chef-metal 0.10.2 → 0.11.beta
Sign up to get free protection for your applications and to get access to all the features.
- 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
|