Class: MotherBrain::Provisioner::Manager

Inherits:
Object
  • Object
show all
Includes:
Celluloid, MB::Mixin::Locks, MB::Mixin::Services, Logging
Defined in:
lib/mb/provisioner/manager.rb

Overview

Handles provisioning of nodes and joining them to a Chef Server. Requests are delegated to a provisioner of the desired type or ‘Environment Factory’ by default.

Constant Summary collapse

WORKER_OPTS =
[
  :component_versions,
  :cookbook_versions,
  :environment_attributes,
  :environment_attributes_file,
  :skip_bootstrap,
  :force
]

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Logging

add_argument_header, dev, filename, #log_exception, logger, #logger, reset, set_logger, setup

Constructor Details

#initializeManager

Returns a new instance of Manager.



36
37
38
39
40
41
42
43
# File 'lib/mb/provisioner/manager.rb', line 36

def initialize
  log.debug { "Provision Manager starting..." }
  @provisioner_registry   = Celluloid::Registry.new
  @provisioner_supervisor = ProvisionerSupervisor.new_link(@provisioner_registry)
  Provisioner.all.each do |provisioner|
    @provisioner_supervisor.supervise_as(provisioner.provisioner_id, provisioner)
  end
end

Instance Attribute Details

#provisioner_registryObject (readonly)

Returns the value of attribute provisioner_registry.



34
35
36
# File 'lib/mb/provisioner/manager.rb', line 34

def provisioner_registry
  @provisioner_registry
end

Class Method Details

.instanceCelluloid::Actor(Provisioner::Manager)

Returns:

Raises:

  • (Celluloid::DeadActorError)

    if Provisioner Manager has not been started



13
14
15
# File 'lib/mb/provisioner/manager.rb', line 13

def instance
  MB::Application[:provisioner_manager] or raise Celluloid::DeadActorError, "provisioner manager not running"
end

Instance Method Details

#async_destroy(environment, options = {}) ⇒ Object

Asynchronously destroy an environment that was created with motherbrain

Parameters:

  • environment (String)

    name of the environment to destroy

  • options (Hash) (defaults to: {})

    a customizable set of options

Options Hash (options):

  • :with (#to_sym)

    id of provisioner to use



52
53
54
55
56
57
# File 'lib/mb/provisioner/manager.rb', line 52

def async_destroy(environment, options = {})
  job = Job.new(:destroy)
  async(:destroy, job, environment, options)

  job.ticket
end

#async_provision(environment, manifest, plugin, options = {}) ⇒ MB::JobRecord

Asynchronously create a new environment

Parameters:

  • environment (#to_s)

    name of the environment to create or append to

  • manifest (MB::Provisioner::Manifest)

    manifest of nodes to create

  • plugin (MB::Plugin)

    the plugin we are creating these nodes for

Returns:

See Also:

  • for options


72
73
74
75
76
77
78
79
80
81
# File 'lib/mb/provisioner/manager.rb', line 72

def async_provision(environment, manifest, plugin, options = {})
  options = options.reverse_merge(skip_bootstrap: false)

  job_type = options[:skip_bootstrap] ? :provision : :provision_and_bootstrap
  job      = Job.new(job_type)

  async(:provision, job, environment, manifest, plugin, options)

  job.ticket
end

#choose_provisioner(id) ⇒ MB::Provisioner::Base

Retrieve the running provisioner for the given ID. The default provisioner will be returned if nil is provided.

Parameters:

Returns:

  • (MB::Provisioner::Base)

Raises:



92
93
94
95
96
97
98
99
100
# File 'lib/mb/provisioner/manager.rb', line 92

def choose_provisioner(id)
  id ||= Provisioner.default_id

  unless provisioner = @provisioner_registry[id.to_sym]
    abort ProvisionerNotStarted.new(id)
  end

  provisioner
end

#destroy(job, environment, options = {}) ⇒ Object

Destroy an environment that was created with motherbrain

Parameters:

  • job (MB::Job)

    a job to update with progress

  • environment (String)

    name of the environment to destroy

  • options (Hash) (defaults to: {})

    a customizable set of options

Options Hash (options):

  • :with (#to_sym)

    id of provisioner to use



111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
# File 'lib/mb/provisioner/manager.rb', line 111

def destroy(job, environment, options = {})
  job.report_running
  options = options.dup

  chef_synchronize(chef_environment: environment, force: options[:force]) do
    provision_data = ProvisionData.new(environment)

    provision_data.provisioners.each do |provisioner_name|
      provisioner = choose_provisioner(provisioner_name)
      job.set_status "Destroying nodes provisioned with #{provisioner_name.upcase}"
      provisioner.down job, environment, options
    end

    job.set_status "Removing nodes and clients from Chef"
    environment_manager.purge_nodes(environment)

    job.set_status "Destroying Chef environment #{environment}"
    environment_manager.destroy(environment)

    job.set_status "Destroying provision data"
    provision_data.destroy
  end

  job.report_success("Environment #{environment} destroyed")
rescue => ex
  job.report_failure(ex)
ensure
  job.terminate if job && job.alive?
end

#provision(job, environment, manifest, plugin, options = {}) ⇒ Object

Create a new environment

Parameters:

  • job (MB::Job)

    a job to update with progress

  • environment (String)

    name of the environment to create or append to

  • manifest (MB::Provisioner::Manifest)

    manifest of nodes to create

  • plugin (MB::Plugin)

    the plugin we are creating these nodes for

  • options (Hash) (defaults to: {})

    a customizable set of options

Options Hash (options):

  • :chef_version (String)

    version of Chef to install on the node

  • :component_versions (Hash) — default: Hash.new

    Hash of components and the versions to set them to

  • :cookbook_versions (Hash) — default: Hash.new

    Hash of cookbooks and the versions to set them to

  • :environment_attributes (Hash) — default: Hash.new

    Hash of additional attributes to set on the environment

  • :skip_bootstrap (Boolean) — default: false

    skip automatic bootstrapping of the created environment

  • :force (Boolean) — default: false

    force provisioning nodes to the environment even if the environment is locked



164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
# File 'lib/mb/provisioner/manager.rb', line 164

def provision(job, environment, manifest, plugin, options = {})
  job.report_running("preparing to provision")

  options = options.reverse_merge(
    component_versions: Hash.new,
    cookbook_versions: Hash.new,
    environment_attributes: Hash.new,
    skip_bootstrap: false,
    force: false
  )

  manifest.validate!(plugin)
  response = choose_provisioner(manifest.provisioner).up(job, environment, manifest, plugin, options)

  unless options[:skip_bootstrap]
    bootstrap_manifest = Bootstrap::Manifest.from_provisioner(response, manifest)
    write_bootstrap_manifest(job, environment, bootstrap_manifest, plugin)
    bootstrapper.bootstrap(job, environment, bootstrap_manifest, plugin, options)
  end

  job.report_success unless job.completed?
rescue => ex
  job.report_failure(ex)
ensure
  job.terminate if job && job.alive?
end