class Chef::Provider::MachineBatch

Public Instance Methods

action_handler() click to toggle source
# File lib/chef/provider/machine_batch.rb, line 13
def action_handler
  @action_handler ||= Provisioning::ChefProviderActionHandler.new(self)
end
by_current_driver() click to toggle source
# File lib/chef/provider/machine_batch.rb, line 178
def by_current_driver
  result = {}
  drivers = {}
  @machines.each do |m|
    if m[:spec].driver_url
      drivers[m[:spec].driver_url] ||= run_context.chef_provisioning.driver_for(m[:spec].driver_url)
      driver = drivers[m[:spec].driver_url]
      result[driver] ||= {}
      result[driver][m[:spec]] = m[:machine_options].call(driver)
    end
  end
  result
end
by_id() click to toggle source
# File lib/chef/provider/machine_batch.rb, line 142
def by_id
  @by_id ||= @machines.inject({}) { |hash,m| hash[m[:spec].id] = m; hash }
end
by_new_driver() click to toggle source
# File lib/chef/provider/machine_batch.rb, line 153
def by_new_driver
  result = {}
  drivers = {}
  @machines.each do |m|
    if m[:desired_driver]
      drivers[m[:desired_driver]] ||= run_context.chef_provisioning.driver_for(m[:desired_driver])
      driver = drivers[m[:desired_driver]]
      # Check whether the current driver is same or different; we disallow
      # moving a machine from one place to another.
      if m[:spec].driver_url
        drivers[m[:spec].driver_url] ||= run_context.chef_provisioning.driver_for(m[:spec].driver_url)
        current_driver = drivers[m[:spec].driver_url]
        if driver.driver_url != current_driver.driver_url
          raise "Cannot move '#{m[:spec].name}' from #{current_driver.driver_url} to #{driver.driver_url}: machine moving is not supported.  Destroy and recreate."
        end
      end
      result[driver] ||= {}
      result[driver][m[:spec]] = m[:machine_options].call(driver)
    else
      raise "No driver specified for #{m[:spec].name}"
    end
  end
  result
end
chef_managed_entry_store() click to toggle source
# File lib/chef/provider/machine_batch.rb, line 230
def chef_managed_entry_store
  @chef_managed_entry_store ||= Provisioning.chef_managed_entry_store(new_resource.chef_server)
end
load_current_resource() click to toggle source
# File lib/chef/provider/machine_batch.rb, line 192
def load_current_resource
  # Load nodes in parallel
  @machines = parallel_do(new_resource.machines) do |machine|
    if machine.is_a?(Chef::Resource::Machine)
      machine_resource = machine
      provider = Chef::Provider::Machine.new(machine_resource, machine_resource.run_context)
      provider.load_current_resource
      {
        :resource => machine_resource,
        :spec => provider.machine_spec,
        :desired_driver => machine_resource.driver,
        :files => machine_resource.files,
        :machine_options => proc { |driver| provider.machine_options(driver) },
        :action_handler => Provisioning::AddPrefixActionHandler.new(action_handler, "[#{machine_resource.name}] ")
      }
    elsif machine.is_a?(Provisioning::ManagedEntry)
      machine_spec = machine
      {
        :spec => machine_spec,
        :desired_driver => new_resource.driver,
        :files => new_resource.files,
        :machine_options => proc { |driver| machine_options(driver) },
        :action_handler => Provisioning::AddPrefixActionHandler.new(action_handler, "[#{machine_spec.name}] ")
      }
    else
      name = machine
      machine_spec = chef_managed_entry_store.get_or_new(:machine, name)
      {
        :spec => machine_spec,
        :desired_driver => new_resource.driver,
        :files => new_resource.files,
        :machine_options => proc { |driver| machine_options(driver) },
        :action_handler => Provisioning::AddPrefixActionHandler.new(action_handler, "[#{name}] ")
      }
    end
  end.to_a
end
machine_options(driver) click to toggle source
# File lib/chef/provider/machine_batch.rb, line 234
def machine_options(driver)
  result = { :convergence_options => { :chef_server => new_resource.chef_server } }
  result = Chef::Mixin::DeepMerge.hash_only_merge(result, run_context.chef_provisioning.config[:machine_options]) if run_context.chef_provisioning.config[:machine_options]
  result = Chef::Mixin::DeepMerge.hash_only_merge(result, driver.config[:machine_options]) if driver.config && driver.config[:machine_options]
  result = Chef::Mixin::DeepMerge.hash_only_merge(result, new_resource.machine_options)
  result
end
parallel_do(enum, options = {}, &block) click to toggle source

TODO in many of these cases, the order of the results only matters because you want to match it up with the input. Make a parallelize method that doesn't care about order and spits back results as quickly as possible.

# File lib/chef/provider/machine_batch.rb, line 149
def parallel_do(enum, options = {}, &block)
  parallelizer.parallelize(enum, options, &block).to_a
end
parallelizer() click to toggle source
# File lib/chef/provider/machine_batch.rb, line 23
def parallelizer
  @parallelizer ||= Chef::ChefFS::Parallelizer.new(new_resource.max_simultaneous || 100)
end
whyrun_supported?() click to toggle source
# File lib/chef/provider/machine_batch.rb, line 19
def whyrun_supported?
  true
end
with_ready_machines(ready_only: false) { |m| ... } click to toggle source
# File lib/chef/provider/machine_batch.rb, line 117
def with_ready_machines(ready_only: false)
  action_allocate unless ready_only
  parallel_do(by_new_driver) do |driver, specs_and_options|
    driver.ready_machines(action_handler, specs_and_options, parallelizer) do |machine|
      machine.machine_spec.save(action_handler)

      m = by_id[machine.machine_spec.id]

      m[:machine] = machine
      begin
        yield m if block_given?
      rescue StandardError => error
        Chef::Log.debug("Chef provisioning failed on machine #{machine.name}")
        raise MachineBatchError.new(machine, error.message)
      ensure
        machine.disconnect
      end
    end
  end
end
with_ready_machines_only() click to toggle source
# File lib/chef/provider/machine_batch.rb, line 138
def with_ready_machines_only
  with_ready_machines(ready_only: true)
end