Class: Chef::Provider::MachineBatch

Inherits:
LWRPBase
  • Object
show all
Includes:
ChefMetal::ProviderActionHandler
Defined in:
lib/chef/provider/machine_batch.rb

Instance Method Summary collapse

Methods included from ChefMetal::ProviderActionHandler

#debug_name, #open_stream, #perform_action, #performed_action, #should_perform_actions, #updated!

Instance Method Details

#load_current_resourceObject



95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
# File 'lib/chef/provider/machine_batch.rb', line 95

def load_current_resource
  # Figure out which machines are in the batch, remove duplicates, and retrieve
  # the nodes from the Chef server if they exist.
  @by_provisioner = {}
  @by_node = {}
  new_resource.machines.each do |machine_resource|
    next if @by_node.has_key?(node_url(machine_resource))
    next unless Array(machine_resource.action).include?(:create)
    @by_node[node_url(machine_resource)] = {
      :resource => machine_resource,
      :provider => Chef::Provider::Machine.new(machine_resource, run_context)
    }
    @by_provisioner[machine_resource.provisioner] ||= []
    @by_provisioner[machine_resource.provisioner] << node_url(machine_resource)
  end
  # Load nodes in parallel
  parallel_do(@by_node.values) do |machine|
    machine[:provider].load_current_resource
  end
end

#node_url(machine_resource) ⇒ Object



91
92
93
# File 'lib/chef/provider/machine_batch.rb', line 91

def node_url(machine_resource)
  "#{machine_resource.chef_server[:chef_server_url]}/nodes/#{machine_resource.name}"
end

#parallel_do(enum, options = {}, &block) ⇒ Object

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.



87
88
89
# File 'lib/chef/provider/machine_batch.rb', line 87

def parallel_do(enum, options = {}, &block)
  parallelizer.parallelize(enum, options, &block).to_a
end

#parallelizerObject



17
18
19
# File 'lib/chef/provider/machine_batch.rb', line 17

def parallelizer
  @parallelizer ||= Chef::ChefFS::Parallelizer.new(new_resource.max_simultaneous || 100)
end

#whyrun_supported?Boolean

Returns:

  • (Boolean)


13
14
15
# File 'lib/chef/provider/machine_batch.rb', line 13

def whyrun_supported?
  true
end

#with_booted_machinesObject



54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
# File 'lib/chef/provider/machine_batch.rb', line 54

def with_booted_machines
  parallel_do(@by_provisioner) do |provisioner, node_urls|
    machines = node_urls.map do |node_url|
      # Fill in the provisioner options and output in case they got overwritten
      machine = @by_node[node_url]
      machine[:node] = machine[:provider].node_provider.new_json
      machine[:node]['normal']['provisioner_options'] = machine[:resource].provisioner_options
      machine[:node]['normal']['provisioner_output'] = machine[:provider].node_provider.current_json['normal']['provisioner_output']
      machine
    end

    # TODO I don't understand why the object_id hack was necessary.  Using the
    # node as a key didn't work. If we could pass node_urls through acquire_machines,
    # that would solve the problem in a bestest way (nodes themselves are not
    # necessarily unique without knowing the chef_server with which they are
    # associated)
    by_node_json = machines.inject({}) { |result, machine| result[machine[:node].object_id] = machine; result }
    provisioner.acquire_machines(self, by_node_json.values.map { |m| m[:node] }, parallelizer) do |node_json, machine_obj|
      machine = by_node_json[node_json.object_id]

      machine[:machine] = machine_obj
      begin
        yield machine if block_given?
      ensure
        machine_obj.disconnect
      end
    end
  end
end