chef-metal 0.10.2 → 0.11.beta
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +9 -5
- data/README.md +3 -3
- data/bin/metal +5 -9
- data/lib/chef/provider/machine.rb +81 -32
- data/lib/chef/provider/machine_batch.rb +67 -58
- data/lib/chef/provider/machine_execute.rb +7 -7
- data/lib/chef/provider/machine_file.rb +11 -11
- data/lib/chef/resource/machine.rb +11 -15
- data/lib/chef/resource/machine_batch.rb +1 -1
- data/lib/chef/resource/machine_execute.rb +3 -4
- data/lib/chef/resource/machine_file.rb +3 -4
- data/lib/chef_metal.rb +26 -28
- data/lib/chef_metal/action_handler.rb +9 -7
- data/lib/chef_metal/add_prefix_action_handler.rb +7 -5
- data/lib/chef_metal/chef_machine_spec.rb +64 -0
- data/lib/chef_metal/{provider_action_handler.rb → chef_provider_action_handler.rb} +27 -14
- data/lib/chef_metal/chef_run_data.rb +68 -7
- data/lib/chef_metal/convergence_strategy.rb +14 -3
- data/lib/chef_metal/convergence_strategy/install_cached.rb +24 -10
- data/lib/chef_metal/convergence_strategy/install_msi.rb +17 -10
- data/lib/chef_metal/convergence_strategy/install_sh.rb +20 -10
- data/lib/chef_metal/convergence_strategy/no_converge.rb +20 -13
- data/lib/chef_metal/convergence_strategy/precreate_chef_objects.rb +51 -47
- data/lib/chef_metal/{provider.rb → driver.rb} +103 -79
- data/lib/chef_metal/machine.rb +13 -5
- data/lib/chef_metal/machine/basic_machine.rb +11 -11
- data/lib/chef_metal/machine/unix_machine.rb +6 -6
- data/lib/chef_metal/machine/windows_machine.rb +3 -3
- data/lib/chef_metal/machine_spec.rb +22 -25
- data/lib/chef_metal/recipe_dsl.rb +34 -9
- data/lib/chef_metal/transport.rb +7 -2
- data/lib/chef_metal/transport/ssh.rb +42 -9
- data/lib/chef_metal/transport/winrm.rb +8 -5
- data/lib/chef_metal/version.rb +1 -1
- data/spec/integration/machine.rb +29 -0
- metadata +21 -9
- data/lib/chef_metal/aws_credentials.rb +0 -58
- data/lib/chef_metal/openstack_credentials.rb +0 -44
- data/lib/chef_metal/provisioner.rb +0 -121
@@ -1,10 +1,12 @@
|
|
1
1
|
require 'chef/provider/lwrp_base'
|
2
|
-
require '
|
3
|
-
require 'chef_metal/
|
2
|
+
require 'chef_metal/chef_provider_action_handler'
|
3
|
+
require 'chef_metal/machine'
|
4
4
|
|
5
5
|
class Chef::Provider::MachineFile < Chef::Provider::LWRPBase
|
6
6
|
|
7
|
-
|
7
|
+
def action_handler
|
8
|
+
@action_handler ||= ChefMetal::ChefProviderActionHandler.new(self)
|
9
|
+
end
|
8
10
|
|
9
11
|
use_inline_resources
|
10
12
|
|
@@ -17,18 +19,16 @@ class Chef::Provider::MachineFile < Chef::Provider::LWRPBase
|
|
17
19
|
if new_resource.machine.kind_of?(ChefMetal::Machine)
|
18
20
|
new_resource.machine
|
19
21
|
else
|
20
|
-
|
21
|
-
node = Cheffish::CheffishServerAPI.new(new_resource.chef_server).get("/nodes/#{new_resource.machine}")
|
22
|
-
new_resource.provisioner.connect_to_machine(node)
|
22
|
+
run_context.chef_metal.connect_to_machine(new_resource.machine, new_resource.chef_server)
|
23
23
|
end
|
24
24
|
end
|
25
25
|
end
|
26
26
|
|
27
27
|
action :upload do
|
28
28
|
if new_resource.content
|
29
|
-
machine.write_file(
|
29
|
+
machine.write_file(action_handler, new_resource.path, new_resource.content)
|
30
30
|
else
|
31
|
-
machine.upload_file(
|
31
|
+
machine.upload_file(action_handler, new_resource.local_path, new_resource.path)
|
32
32
|
end
|
33
33
|
|
34
34
|
attributes = {}
|
@@ -36,14 +36,14 @@ class Chef::Provider::MachineFile < Chef::Provider::LWRPBase
|
|
36
36
|
attributes[:owner] = new_resource.owner if new_resource.owner
|
37
37
|
attributes[:mode] = new_resource.mode if new_resource.mode
|
38
38
|
|
39
|
-
machine.set_attributes(
|
39
|
+
machine.set_attributes(action_handler, new_resource.path, attributes)
|
40
40
|
end
|
41
41
|
|
42
42
|
action :download do
|
43
|
-
machine.download_file(
|
43
|
+
machine.download_file(action_handler, new_resource.path, new_resource.local_path)
|
44
44
|
end
|
45
45
|
|
46
46
|
action :delete do
|
47
|
-
machine.delete_file(
|
47
|
+
machine.delete_file(action_handler, new_resource.path)
|
48
48
|
end
|
49
49
|
end
|
@@ -9,31 +9,27 @@ class Chef::Resource::Machine < Chef::Resource::LWRPBase
|
|
9
9
|
super
|
10
10
|
@chef_environment = run_context.cheffish.current_environment
|
11
11
|
@chef_server = run_context.cheffish.current_chef_server
|
12
|
-
@
|
13
|
-
@
|
12
|
+
@driver = run_context.chef_metal.current_driver
|
13
|
+
@machine_options = run_context.chef_metal.current_machine_options
|
14
14
|
if run_context.chef_metal.current_machine_batch
|
15
15
|
run_context.chef_metal.current_machine_batch.machines << self
|
16
16
|
end
|
17
17
|
end
|
18
18
|
|
19
|
-
|
20
|
-
|
21
|
-
@provisioner.resource_created(self)
|
22
|
-
end
|
23
|
-
|
24
|
-
actions :create, :delete, :stop, :converge, :nothing
|
25
|
-
default_action :create
|
19
|
+
actions :allocate, :ready, :setup, :converge, :converge_only, :destroy, :stop
|
20
|
+
default_action :converge
|
26
21
|
|
27
|
-
#
|
28
|
-
attribute :
|
29
|
-
attribute :
|
22
|
+
# Driver attributes
|
23
|
+
attribute :driver
|
24
|
+
attribute :machine_options
|
30
25
|
|
31
26
|
# Node attributes
|
32
27
|
Cheffish.node_attributes(self)
|
33
28
|
|
34
29
|
# Client keys
|
35
30
|
# Options to generate private key (size, type, etc.) when the server doesn't have it
|
36
|
-
attribute :private_key_options, :kind_of =>
|
31
|
+
attribute :private_key_options, :kind_of => Hash
|
32
|
+
attribute :allow_overwrite_keys, :kind_of => [TrueClass, FalseClass]
|
37
33
|
|
38
34
|
# Optionally pull the public key out to a file
|
39
35
|
attribute :public_key_path, :kind_of => String
|
@@ -88,8 +84,8 @@ class Chef::Resource::Machine < Chef::Resource::LWRPBase
|
|
88
84
|
end
|
89
85
|
end
|
90
86
|
|
91
|
-
def
|
92
|
-
@
|
87
|
+
def add_machine_options(options)
|
88
|
+
@machine_options = Chef::Mixin::DeepMerge.hash_only_merge(@machine_options, options)
|
93
89
|
end
|
94
90
|
|
95
91
|
# chef client version and omnibus
|
@@ -11,7 +11,7 @@ class Chef::Resource::MachineBatch < Chef::Resource::LWRPBase
|
|
11
11
|
|
12
12
|
# TODO there is a useful action sequence where one does an ohai on all machines,
|
13
13
|
# waits for that to complete, save the nodes, and THEN converges.
|
14
|
-
actions :acquire, :setup, :converge, :stop, :
|
14
|
+
actions :acquire, :setup, :converge, :stop, :destroy
|
15
15
|
default_action :converge
|
16
16
|
|
17
17
|
attribute :machines, :kind_of => [ Array ]
|
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'chef/resource/lwrp_base'
|
2
2
|
require 'chef_metal'
|
3
3
|
require 'chef_metal/machine'
|
4
|
-
require 'chef_metal/
|
4
|
+
require 'chef_metal/driver'
|
5
5
|
|
6
6
|
class Chef::Resource::MachineExecute < Chef::Resource::LWRPBase
|
7
7
|
self.resource_name = 'machine_execute'
|
@@ -9,15 +9,14 @@ class Chef::Resource::MachineExecute < Chef::Resource::LWRPBase
|
|
9
9
|
def initialize(*args)
|
10
10
|
super
|
11
11
|
@chef_server = run_context.cheffish.current_chef_server
|
12
|
-
@provisioner = run_context.chef_metal.current_provisioner
|
13
12
|
end
|
14
13
|
|
15
14
|
actions :run
|
16
15
|
default_action :run
|
17
16
|
|
18
17
|
attribute :command, :kind_of => String, :name_attribute => true
|
19
|
-
attribute :machine, :kind_of =>
|
18
|
+
attribute :machine, :kind_of => String
|
20
19
|
|
21
20
|
attribute :chef_server, :kind_of => Hash
|
22
|
-
attribute :
|
21
|
+
attribute :driver, :kind_of => ChefMetal::Driver
|
23
22
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'chef/resource/lwrp_base'
|
2
2
|
require 'chef_metal'
|
3
3
|
require 'chef_metal/machine'
|
4
|
-
require 'chef_metal/
|
4
|
+
require 'chef_metal/driver'
|
5
5
|
|
6
6
|
class Chef::Resource::MachineFile < Chef::Resource::LWRPBase
|
7
7
|
self.resource_name = 'machine_file'
|
@@ -9,14 +9,13 @@ class Chef::Resource::MachineFile < Chef::Resource::LWRPBase
|
|
9
9
|
def initialize(*args)
|
10
10
|
super
|
11
11
|
@chef_server = run_context.cheffish.current_chef_server
|
12
|
-
@provisioner = run_context.chef_metal.current_provisioner
|
13
12
|
end
|
14
13
|
|
15
14
|
actions :upload, :download, :delete, :nothing
|
16
15
|
default_action :upload
|
17
16
|
|
18
17
|
attribute :path, :kind_of => String, :name_attribute => true
|
19
|
-
attribute :machine, :kind_of =>
|
18
|
+
attribute :machine, :kind_of => String
|
20
19
|
attribute :local_path, :kind_of => String
|
21
20
|
attribute :content
|
22
21
|
|
@@ -25,5 +24,5 @@ class Chef::Resource::MachineFile < Chef::Resource::LWRPBase
|
|
25
24
|
attribute :mode, :kind_of => String
|
26
25
|
|
27
26
|
attribute :chef_server, :kind_of => Hash
|
28
|
-
attribute :
|
27
|
+
attribute :driver, :kind_of => ChefMetal::Driver
|
29
28
|
end
|
data/lib/chef_metal.rb
CHANGED
@@ -1,15 +1,8 @@
|
|
1
1
|
# Include recipe basics so require 'chef_metal' will load everything
|
2
2
|
require 'chef_metal/recipe_dsl'
|
3
|
-
require 'chef/resource/machine'
|
4
|
-
require 'chef/provider/machine'
|
5
|
-
require 'chef/resource/machine_batch'
|
6
|
-
require 'chef/provider/machine_batch'
|
7
|
-
require 'chef/resource/machine_file'
|
8
|
-
require 'chef/provider/machine_file'
|
9
|
-
require 'chef/resource/machine_execute'
|
10
|
-
require 'chef/provider/machine_execute'
|
11
3
|
require 'chef/server_api'
|
12
4
|
require 'cheffish/basic_chef_client'
|
5
|
+
require 'cheffish/merged_config'
|
13
6
|
|
14
7
|
module ChefMetal
|
15
8
|
def self.inline_resource(action_handler, &block)
|
@@ -26,35 +19,40 @@ module ChefMetal
|
|
26
19
|
|
27
20
|
def resource_update_applied(resource, action, update)
|
28
21
|
prefix = action_handler.should_perform_actions ? "" : "Would "
|
29
|
-
update = Array(update).map { |u| "#{prefix}#{u}"}
|
22
|
+
update = Array(update).flatten.map { |u| "#{prefix}#{u}"}
|
30
23
|
action_handler.performed_action(update)
|
31
24
|
end
|
32
25
|
end
|
33
26
|
|
27
|
+
# Helpers for driver inflation
|
28
|
+
@@registered_driver_classes = {}
|
29
|
+
def self.register_driver_class(name, driver)
|
30
|
+
@@registered_driver_classes[name] = driver
|
31
|
+
end
|
34
32
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
33
|
+
def self.config_for_url(driver_url, config = Chef::Config)
|
34
|
+
if config && config[:drivers] && config[:drivers][driver_url]
|
35
|
+
config = Cheffish::MergedConfig.new(config[:drivers][driver_url], config)
|
36
|
+
end
|
37
|
+
config || {}
|
39
38
|
end
|
40
39
|
|
41
|
-
def self.
|
42
|
-
|
43
|
-
cluster_type
|
44
|
-
|
45
|
-
|
46
|
-
|
40
|
+
def self.driver_for_url(driver_url, config = Chef::Config)
|
41
|
+
cluster_type = driver_url.split(':', 2)[0]
|
42
|
+
require "chef_metal/driver_init/#{cluster_type}"
|
43
|
+
driver_class = @@registered_driver_classes[cluster_type]
|
44
|
+
config = config_for_url(driver_url, config)
|
45
|
+
driver_class.from_url(driver_url, config || {})
|
47
46
|
end
|
48
47
|
|
49
|
-
def self.connect_to_machine(
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
48
|
+
def self.connect_to_machine(machine_spec, config = Chef::Config)
|
49
|
+
driver = driver_for_url(machine_spec.driver_url, config)
|
50
|
+
if driver
|
51
|
+
machine_options = { :convergence_options => { :chef_server => Cheffish.default_chef_server(config) } }
|
52
|
+
machine_options = Cheffish::MergedConfig.new(config[:machine_options], machine_options) if config[:machine_options]
|
53
|
+
driver.connect_to_machine(machine_spec, machine_options)
|
54
|
+
else
|
55
|
+
nil
|
55
56
|
end
|
56
|
-
provisioner = provisioner_for_node(node)
|
57
|
-
machine = provisioner.connect_to_machine(node)
|
58
|
-
[ machine, provisioner ]
|
59
57
|
end
|
60
58
|
end
|
@@ -30,8 +30,12 @@ module ChefMetal
|
|
30
30
|
true
|
31
31
|
end
|
32
32
|
|
33
|
+
def report_progress(description)
|
34
|
+
Array(description).each { |d| puts d }
|
35
|
+
end
|
36
|
+
|
33
37
|
def performed_action(description)
|
34
|
-
puts
|
38
|
+
Array(description).each { |d| puts d }
|
35
39
|
end
|
36
40
|
|
37
41
|
# This should perform the actual action (e.g., converge) if there is an
|
@@ -43,12 +47,6 @@ module ChefMetal
|
|
43
47
|
performed_action(description)
|
44
48
|
end
|
45
49
|
|
46
|
-
# This is the name that will show up in the output, so should be something
|
47
|
-
# like a cookbook or driver name
|
48
|
-
def debug_name
|
49
|
-
raise ActionFailed, "ActionHandler behavior requires a debug_name"
|
50
|
-
end
|
51
|
-
|
52
50
|
# Open a stream which can be printed to and closed
|
53
51
|
def open_stream(name)
|
54
52
|
if block_given?
|
@@ -57,5 +55,9 @@ module ChefMetal
|
|
57
55
|
STDOUT
|
58
56
|
end
|
59
57
|
end
|
58
|
+
|
59
|
+
# A URL identifying the host node. nil if no such node.
|
60
|
+
def host_node
|
61
|
+
end
|
60
62
|
end
|
61
63
|
end
|
@@ -12,16 +12,18 @@ module ChefMetal
|
|
12
12
|
attr_reader :action_handler
|
13
13
|
attr_reader :prefix
|
14
14
|
|
15
|
-
def_delegators :@action_handler, :should_perform_actions, :updated!, :
|
16
|
-
|
17
|
-
|
15
|
+
def_delegators :@action_handler, :should_perform_actions, :updated!, :open_stream, :host_node
|
16
|
+
|
17
|
+
def report_progress(description)
|
18
|
+
action_handler.report_progress(Array(description).flatten.map { |d| "#{prefix}#{d}" })
|
19
|
+
end
|
18
20
|
|
19
21
|
def performed_action(description)
|
20
|
-
action_handler.performed_action(Array(description).map { |d| "#{prefix}#{d}" })
|
22
|
+
action_handler.performed_action(Array(description).flatten.map { |d| "#{prefix}#{d}" })
|
21
23
|
end
|
22
24
|
|
23
25
|
def perform_action(description, &block)
|
24
|
-
action_handler.perform_action(Array(description).map { |d| "#{prefix}#{d}" }, &block)
|
26
|
+
action_handler.perform_action(Array(description).flatten.map { |d| "#{prefix}#{d}" }, &block)
|
25
27
|
end
|
26
28
|
end
|
27
29
|
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
require 'chef_metal'
|
2
|
+
require 'cheffish'
|
3
|
+
require 'chef_metal/machine_spec'
|
4
|
+
|
5
|
+
module ChefMetal
|
6
|
+
#
|
7
|
+
# Specification for a machine. Sufficient information to find and contact it
|
8
|
+
# after it has been set up.
|
9
|
+
#
|
10
|
+
class ChefMachineSpec < MachineSpec
|
11
|
+
def initialize(node, chef_server)
|
12
|
+
super(node)
|
13
|
+
@chef_server = chef_server
|
14
|
+
end
|
15
|
+
|
16
|
+
#
|
17
|
+
# Get a MachineSpec from the chef server.
|
18
|
+
#
|
19
|
+
def self.get(name, chef_server = Cheffish.default_chef_server)
|
20
|
+
chef_api = Cheffish.chef_server_api(chef_server)
|
21
|
+
ChefMachineSpec.new(chef_api.get("/nodes/#{name}"), chef_server)
|
22
|
+
end
|
23
|
+
|
24
|
+
#
|
25
|
+
# Globally unique identifier for this machine. Does not depend on the machine's
|
26
|
+
# location or existence.
|
27
|
+
#
|
28
|
+
def id
|
29
|
+
ChefMachineSpec.id_from(chef_server, name)
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.id_from(chef_server, name)
|
33
|
+
"#{chef_server[:chef_server_url]}/nodes/#{name}"
|
34
|
+
end
|
35
|
+
|
36
|
+
#
|
37
|
+
# Save this node to the server. If you have significant information that
|
38
|
+
# could be lost, you should do this as quickly as possible. Data will be
|
39
|
+
# saved automatically for you after allocate_machine and ready_machine.
|
40
|
+
#
|
41
|
+
def save(action_handler)
|
42
|
+
# Save the node to the server.
|
43
|
+
_self = self
|
44
|
+
_chef_server = _self.chef_server
|
45
|
+
ChefMetal.inline_resource(action_handler) do
|
46
|
+
chef_node _self.name do
|
47
|
+
chef_server _chef_server
|
48
|
+
raw_json _self.node
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
protected
|
54
|
+
|
55
|
+
attr_reader :chef_server
|
56
|
+
|
57
|
+
#
|
58
|
+
# Chef API object for the given Chef server
|
59
|
+
#
|
60
|
+
def chef_api
|
61
|
+
Cheffish.server_api_for(chef_server)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -16,37 +16,46 @@
|
|
16
16
|
# See the License for the specific language governing permissions and
|
17
17
|
# limitations under the License.
|
18
18
|
|
19
|
-
|
20
|
-
|
19
|
+
require 'chef_metal/action_handler'
|
20
|
+
|
21
|
+
# This is included in the metal drivers to proxy from generic requests needed
|
22
|
+
# to specific driver actions
|
21
23
|
module ChefMetal
|
22
|
-
|
23
|
-
|
24
|
+
class ChefProviderActionHandler < ActionHandler
|
25
|
+
def initialize(provider)
|
26
|
+
@provider = provider
|
27
|
+
end
|
28
|
+
|
29
|
+
attr_reader :provider
|
24
30
|
|
25
31
|
def updated!
|
26
|
-
|
32
|
+
provider.new_resource.updated_by_last_action(true)
|
27
33
|
end
|
28
34
|
|
29
35
|
def should_perform_actions
|
30
|
-
!
|
36
|
+
!provider.run_context.config.why_run
|
31
37
|
end
|
32
38
|
|
33
|
-
def
|
34
|
-
|
39
|
+
def report_progress(description)
|
40
|
+
# TODO this seems wrong but Chef doesn't have another thing
|
41
|
+
provider.converge_by description do
|
35
42
|
# We already did the action, but we trust whoever told us that they did it.
|
36
43
|
end
|
37
44
|
end
|
38
45
|
|
39
|
-
def
|
40
|
-
|
46
|
+
def performed_action(description)
|
47
|
+
provider.converge_by description do
|
48
|
+
# We already did the action, but we trust whoever told us that they did it.
|
49
|
+
end
|
41
50
|
end
|
42
51
|
|
43
|
-
def
|
44
|
-
|
52
|
+
def perform_action(description, &block)
|
53
|
+
provider.converge_by(description, &block)
|
45
54
|
end
|
46
55
|
|
47
56
|
def open_stream(name, &block)
|
48
|
-
if
|
49
|
-
|
57
|
+
if provider.run_context.respond_to?(:open_stream)
|
58
|
+
provider.run_context.open_stream({ :name => name }, &block)
|
50
59
|
else
|
51
60
|
if block_given?
|
52
61
|
yield STDOUT
|
@@ -55,5 +64,9 @@ module ChefMetal
|
|
55
64
|
end
|
56
65
|
end
|
57
66
|
end
|
67
|
+
|
68
|
+
def host_node
|
69
|
+
"#{provider.run_context.config[:chef_server_url]}/nodes/#{provider.run_context.node['name']}"
|
70
|
+
end
|
58
71
|
end
|
59
72
|
end
|