chef-metal 0.4 → 0.5

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 93940616771e3e091f441bce2587a1383f7859ef
4
- data.tar.gz: 8e49d7a64afdc1fe06c82b99056accc1b4ae587c
3
+ metadata.gz: ae7198497aa5a5f38de02410732e0a1aab44e63a
4
+ data.tar.gz: bebf3d3226651b34c9bf334ac427c85d4ec6d6af
5
5
  SHA512:
6
- metadata.gz: 1815d8c7b09c9fdb5fa68bcea2282abe2253bb71e4d3345c12b75774e545dea7532ddb45772f428b4c65b4361fb9006b45e633d12c80cdd780860f89b9b06886
7
- data.tar.gz: 5bf3f00b97b72d98a9fcbf962c99bcb201afc696ae7ed25f9ef023234442e16cfab6e1a5e0d4256554a4ad3769f881b986be6593ebfb637624361708c2cd77e8
6
+ metadata.gz: b3f43cbc60deb6bf72f4aec3dabfcb16689896f74ab3b58abcd61cf6b97801402c903f75701837d015f7aa990f470c580367782f2ba9749d3cb69d7a931d5f69
7
+ data.tar.gz: 4cc81e32caf611a3f518b440ea8d2c4ef7a3b9be34f04993ab59f85f68750ede2e9cfc2f0220b2675a8aaf12e13f975b9801889d54a5a33c59cea681b33e11cf
@@ -1,7 +1,10 @@
1
1
  require 'chef/provider/lwrp_base'
2
+ require 'chef_metal/provider_action_handler'
2
3
 
3
4
  class Chef::Provider::FogKeyPair < Chef::Provider::LWRPBase
4
5
 
6
+ include ChefMetal::ProviderActionHandler
7
+
5
8
  use_inline_resources
6
9
 
7
10
  def whyrun_supported?
@@ -1,9 +1,12 @@
1
1
  require 'chef/provider/lwrp_base'
2
2
  require 'chef/provider/chef_node'
3
3
  require 'openssl'
4
+ require 'chef_metal/provider_action_handler'
4
5
 
5
6
  class Chef::Provider::Machine < Chef::Provider::LWRPBase
6
7
 
8
+ include ChefMetal::ProviderActionHandler
9
+
7
10
  use_inline_resources
8
11
 
9
12
  def whyrun_supported?
@@ -27,10 +27,17 @@ class Chef::Provider::MachineFile < Chef::Provider::LWRPBase
27
27
  else
28
28
  machine.upload_file(self, new_resource.local_path, new_resource.path)
29
29
  end
30
+
31
+ attributes = {}
32
+ attributes[:group] = new_resource.group if new_resource.group
33
+ attributes[:owner] = new_resource.owner if new_resource.owner
34
+ attributes[:mode] = new_resource.mode if new_resource.mode
35
+
36
+ machine.set_attributes(self, new_resource.path, attributes)
30
37
  end
31
38
 
32
39
  action :download do
33
- machine.download_file(provider, new_resource.path, new_resource.local_path)
40
+ machine.download_file(self, new_resource.path, new_resource.local_path)
34
41
  end
35
42
 
36
43
  action :delete do
@@ -1,7 +1,10 @@
1
1
  require 'chef/provider/lwrp_base'
2
+ require 'chef_metal/provider_action_handler'
2
3
 
3
4
  class Chef::Provider::VagrantCluster < Chef::Provider::LWRPBase
4
5
 
6
+ include ChefMetal::ProviderActionHandler
7
+
5
8
  use_inline_resources
6
9
 
7
10
  def whyrun_supported?
@@ -20,6 +20,10 @@ class Chef::Resource::MachineFile < Chef::Resource::LWRPBase
20
20
  attribute :local_path, :kind_of => String
21
21
  attribute :content
22
22
 
23
+ attribute :owner, :kind_of => String
24
+ attribute :group, :kind_of => String
25
+ attribute :mode, :kind_of => String
26
+
23
27
  attribute :chef_server, :kind_of => Hash
24
28
  attribute :provisioner, :kind_of => ChefMetal::Provisioner
25
29
  end
@@ -32,8 +32,8 @@ module ChefMetal
32
32
  end
33
33
  end
34
34
 
35
- def self.inline_resource(provider, &block)
36
- InlineResource.new(provider).instance_eval(&block)
35
+ def self.inline_resource(action_handler, &block)
36
+ InlineResource.new(action_handler).instance_eval(&block)
37
37
  end
38
38
 
39
39
  @@enclosing_provisioner = nil
@@ -48,7 +48,21 @@ module ChefMetal
48
48
  def self.enclosing_provisioner_options
49
49
  @@enclosing_provisioner_options
50
50
  end
51
+
51
52
  def self.enclosing_provisioner_options=(provisioner_options)
52
53
  @@enclosing_provisioner_options = provisioner_options
53
54
  end
55
+
56
+ @@registered_provisioner_classes = {}
57
+ def self.add_registered_provisioner_class(name, provisioner)
58
+ @@registered_provisioner_classes[name] = provisioner
59
+ end
60
+
61
+ def self.provisioner_for_node(node)
62
+ provisioner_url = node['normal']['provisioner_output']['provisioner_url']
63
+ cluster_type = provisioner_url.split(':', 2)[0]
64
+ require "chef_metal/provisioner_init/#{cluster_type}_init"
65
+ provisioner_class = @@registered_provisioner_classes[cluster_type]
66
+ provisioner_class.inflate(node)
67
+ end
54
68
  end
@@ -0,0 +1,49 @@
1
+ # -*- encoding: utf-8 -*-
2
+ #
3
+ # Author:: Douglas Triggs (<doug@getchef.com>)
4
+ #
5
+ # Copyright (C) 2014, Chef, Inc.
6
+ #
7
+ # Licensed under the Apache License, Version 2.0 (the "License");
8
+ # you may not use this file except in compliance with the License.
9
+ # You may obtain a copy of the License at
10
+ #
11
+ # http://www.apache.org/licenses/LICENSE-2.0
12
+ #
13
+ # Unless required by applicable law or agreed to in writing, software
14
+ # distributed under the License is distributed on an "AS IS" BASIS,
15
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
+ # See the License for the specific language governing permissions and
17
+ # limitations under the License.
18
+
19
+ # This is the generic action handler
20
+ module ChefMetal
21
+ class ActionHandler
22
+
23
+ # This should be the run context
24
+ def recipe_context
25
+ raise ActionFailed, "ActionHandler behavior requires a recipe_context"
26
+ end
27
+
28
+ # This should be repaced with whatever records the update; by default it
29
+ # essentially does nothing here.
30
+ def updated!
31
+ @updated = true
32
+ end
33
+
34
+ # This should perform the actual action (e.g., converge) if there is an
35
+ # action that needs to be done.
36
+ #
37
+ # By default, it will simply execute the block as so:
38
+ def perform_action(description, &block)
39
+ puts description
40
+ block.call
41
+ end
42
+
43
+ # This is the name that will show up in the output, so should be something
44
+ # like a cookbook or driver name
45
+ def debug_name
46
+ raise ActionFailed, "ActionHandler behavior requires a debug_name"
47
+ end
48
+ end
49
+ end
@@ -1,15 +1,15 @@
1
1
  module ChefMetal
2
2
  class ConvergenceStrategy
3
- def setup_convergence(provider, machine, machine_resource)
3
+ def setup_convergence(action_handler, machine, machine_resource)
4
4
  raise "setup_convergence not overridden on #{self.class}"
5
5
  end
6
6
 
7
- def converge(provider, machine)
7
+ def converge(action_handler, machine)
8
8
  raise "converge not overridden on #{self.class}"
9
9
  end
10
10
 
11
- def delete_chef_objects(provider, node)
12
- raise "delete_chef_objects not overridden on #{self.class}"
11
+ def cleanup_convergence(action_handler, node)
12
+ raise "cleanup_convergence not overridden on #{self.class}"
13
13
  end
14
14
  end
15
- end
15
+ end
@@ -19,26 +19,26 @@ module ChefMetal
19
19
  @package_cache_lock = Mutex.new
20
20
  end
21
21
 
22
- def setup_convergence(provider, machine, machine_resource)
22
+ def setup_convergence(action_handler, machine, machine_resource)
23
23
  super
24
24
 
25
25
  # Install chef-client. TODO check and update version if not latest / not desired
26
26
  if machine.execute_always('chef-client -v').exitstatus != 0
27
- platform, platform_version, machine_architecture = machine.detect_os(provider)
28
- package_file = download_package_for_platform(provider, machine, platform, platform_version, machine_architecture)
27
+ platform, platform_version, machine_architecture = machine.detect_os(action_handler)
28
+ package_file = download_package_for_platform(action_handler, machine, platform, platform_version, machine_architecture)
29
29
  remote_package_file = "#{@tmp_dir}/#{File.basename(package_file)}"
30
- machine.upload_file(provider, package_file, remote_package_file)
31
- install_package(provider, machine, remote_package_file)
30
+ machine.upload_file(action_handler, package_file, remote_package_file)
31
+ install_package(action_handler, machine, remote_package_file)
32
32
  end
33
33
  end
34
34
 
35
- def converge(provider, machine)
36
- machine.execute(provider, 'chef-client')
35
+ def converge(action_handler, machine)
36
+ machine.execute(action_handler, 'chef-client')
37
37
  end
38
38
 
39
39
  private
40
40
 
41
- def download_package_for_platform(provider, machine, platform, platform_version, machine_architecture)
41
+ def download_package_for_platform(action_handler, machine, platform, platform_version, machine_architecture)
42
42
  @package_cache_lock.synchronize do
43
43
  @package_cache ||= {}
44
44
  @package_cache[platform] ||= {}
@@ -55,7 +55,7 @@ module ChefMetal
55
55
  # Download actual package desired by metadata
56
56
  package_file = "#{@package_cache_path}/#{URI(metadata['url']).path.split('/')[-1]}"
57
57
 
58
- ChefMetal.inline_resource(provider) do
58
+ ChefMetal.inline_resource(action_handler) do
59
59
  remote_file package_file do
60
60
  source metadata['url']
61
61
  checksum metadata['sha256']
@@ -75,9 +75,9 @@ module ChefMetal
75
75
  metadata_url="https://www.opscode.com/chef/metadata"
76
76
  metadata_url << "?v=#{@chef_version}"
77
77
  metadata_url << "&prerelease=#{@prerelease ? 'true' : 'false'}"
78
- metadata_url << "&p=#{platform}"
79
- metadata_url << "&pv=#{platform_version}"
80
- metadata_url << "&m=#{machine_architecture}"
78
+ metadata_url << "&p=#{platform.strip}"
79
+ metadata_url << "&pv=#{platform_version.strip}"
80
+ metadata_url << "&m=#{machine_architecture.strip}"
81
81
  use_ssl = true
82
82
 
83
83
  # solaris 9 lacks openssl, solaris 10 lacks recent enough credentials - your base O/S is completely insecure, please upgrade
@@ -102,23 +102,23 @@ module ChefMetal
102
102
  metadata
103
103
  end
104
104
 
105
- def install_package(provider, machine, remote_package_file)
105
+ def install_package(action_handler, machine, remote_package_file)
106
106
  extension = File.extname(remote_package_file)
107
107
  result = case extension
108
108
  when '.rpm'
109
- machine.execute(provider, "rpm -Uvh --oldpackage --replacepkgs \"#{remote_package_file}\"")
109
+ machine.execute(action_handler, "rpm -Uvh --oldpackage --replacepkgs \"#{remote_package_file}\"")
110
110
  when '.deb'
111
- machine.execute(provider, "dpkg -i \"#{remote_package_file}\"")
111
+ machine.execute(action_handler, "dpkg -i \"#{remote_package_file}\"")
112
112
  when '.solaris'
113
- machine.write_file(provider, "#{@tmp_dir}/nocheck", <<EOM)
113
+ machine.write_file(action_handler, "#{@tmp_dir}/nocheck", <<EOM)
114
114
  conflict=nocheck
115
115
  action=nocheck
116
116
  mail=
117
117
  EOM
118
- machine.execute(provider, "pkgrm -a \"#{@tmp_dir}/nocheck\" -n chef")
119
- machine.execute(provider, "pkgadd -n -d \"#{remote_package_file}\" -a \"#{@tmp_dir}/nocheck\" chef")
118
+ machine.execute(action_handler, "pkgrm -a \"#{@tmp_dir}/nocheck\" -n chef")
119
+ machine.execute(action_handler, "pkgadd -n -d \"#{remote_package_file}\" -a \"#{@tmp_dir}/nocheck\" chef")
120
120
  when '.sh'
121
- machine.execute(provider, "sh \"#{remote_package_file}\"")
121
+ machine.execute(action_handler, "sh \"#{remote_package_file}\"")
122
122
  else
123
123
  raise "Unknown package extension '#{extension}' for file #{remote_package_file}"
124
124
  end
@@ -14,7 +14,7 @@ module ChefMetal
14
14
  attr_reader :install_msi_url
15
15
  attr_reader :install_msi_path
16
16
 
17
- def setup_convergence(provider, machine, machine_resource)
17
+ def setup_convergence(action_handler, machine, machine_resource)
18
18
  system_drive = machine.execute_always('$env:SystemDrive').stdout.strip
19
19
  @client_rb_path ||= "#{system_drive}\\chef\\client.rb"
20
20
  @client_pem_path ||= "#{system_drive}\\chef\\client.pem"
@@ -27,12 +27,12 @@ module ChefMetal
27
27
  # TODO find a way to cache this on the host like with the Unix stuff.
28
28
  # Limiter is we don't know how to efficiently upload large files to
29
29
  # the remote machine with WMI.
30
- machine.execute(provider, "(New-Object System.Net.WebClient).DownloadFile(#{machine.escape(install_msi_url)}, #{machine.escape(install_msi_path)})")
31
- machine.execute(provider, "msiexec /qn /i #{machine.escape(install_msi_path)}")
30
+ machine.execute(action_handler, "(New-Object System.Net.WebClient).DownloadFile(#{machine.escape(install_msi_url)}, #{machine.escape(install_msi_path)})")
31
+ machine.execute(action_handler, "msiexec /qn /i #{machine.escape(install_msi_path)}")
32
32
  end
33
33
  end
34
34
 
35
- def converge(provider, machine)
35
+ def converge(action_handler, machine)
36
36
  # TODO For some reason I get a 500 back if I don't do -l debug
37
37
  machine.transport.execute("chef-client -l debug")
38
38
  end
@@ -16,20 +16,20 @@ module ChefMetal
16
16
  attr_reader :install_sh_url
17
17
  attr_reader :install_sh_path
18
18
 
19
- def setup_convergence(provider, machine, machine_resource)
19
+ def setup_convergence(action_handler, machine, machine_resource)
20
20
  super
21
21
 
22
22
  # Install chef-client. TODO check and update version if not latest / not desired
23
23
  if machine.execute_always('chef-client -v').exitstatus != 0
24
24
  # TODO ssh verification of install.sh before running arbtrary code would be nice?
25
25
  @@install_sh_cache[install_sh_url] ||= Net::HTTP.get(URI(install_sh_url))
26
- machine.write_file(provider, install_sh_path, @@install_sh_cache[install_sh_url], :ensure_dir => true)
27
- machine.execute(provider, "bash #{install_sh_path}")
26
+ machine.write_file(action_handler, install_sh_path, @@install_sh_cache[install_sh_url], :ensure_dir => true)
27
+ machine.execute(action_handler, "bash #{install_sh_path}")
28
28
  end
29
29
  end
30
30
 
31
- def converge(provider, machine)
32
- machine.execute(provider, 'chef-client')
31
+ def converge(action_handler, machine)
32
+ machine.execute(action_handler, 'chef-client')
33
33
  end
34
34
  end
35
35
  end
@@ -0,0 +1,34 @@
1
+ require 'chef_metal/convergence_strategy'
2
+ require 'pathname'
3
+ require 'cheffish'
4
+
5
+ module ChefMetal
6
+ class ConvergenceStrategy
7
+ class NoConverge < ConvergenceStrategy
8
+ attr_reader :client_rb_path
9
+ attr_reader :client_pem_path
10
+
11
+ def setup_convergence(action_handler, machine, machine_resource)
12
+ # Save the node
13
+ ChefMetal.inline_resource(action_handler) do
14
+ # TODO strip automatic attributes first so we don't race with "current state"
15
+ chef_node machine.node['name'] do
16
+ chef_server machine_resource.chef_server
17
+ raw_json machine.node
18
+ end
19
+ end
20
+ end
21
+
22
+ def converge(action_handler, machine)
23
+ end
24
+
25
+ def cleanup_convergence(action_handler, node)
26
+ ChefMetal.inline_resource(action_handler) do
27
+ chef_node node['name'] do
28
+ action :delete
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -1,5 +1,6 @@
1
1
  require 'chef_metal/convergence_strategy'
2
2
  require 'pathname'
3
+ require 'cheffish'
3
4
 
4
5
  module ChefMetal
5
6
  class ConvergenceStrategy
@@ -13,11 +14,11 @@ module ChefMetal
13
14
  attr_reader :client_rb_path
14
15
  attr_reader :client_pem_path
15
16
 
16
- def setup_convergence(provider, machine, machine_resource)
17
+ def setup_convergence(action_handler, machine, machine_resource)
17
18
  # Create keys on machine
18
- public_key = create_keys(provider, machine, machine_resource)
19
+ public_key = create_keys(action_handler, machine, machine_resource)
19
20
  # Create node and client on chef server
20
- create_chef_objects(provider, machine, machine_resource, public_key)
21
+ create_chef_objects(action_handler, machine, machine_resource, public_key)
21
22
 
22
23
  # If the chef server lives on localhost, tunnel the port through to the guest
23
24
  chef_server_url = machine_resource.chef_server[:chef_server_url]
@@ -29,11 +30,11 @@ module ChefMetal
29
30
 
30
31
  # Create client.rb and client.pem on machine
31
32
  content = client_rb_content(chef_server_url, machine.node['name'])
32
- machine.write_file(provider, client_rb_path, content, :ensure_dir => true)
33
+ machine.write_file(action_handler, client_rb_path, content, :ensure_dir => true)
33
34
  end
34
35
 
35
- def delete_chef_objects(provider, node)
36
- ChefMetal.inline_resource(provider) do
36
+ def cleanup_convergence(action_handler, node)
37
+ ChefMetal.inline_resource(action_handler) do
37
38
  chef_node node['name'] do
38
39
  action :delete
39
40
  end
@@ -45,7 +46,7 @@ module ChefMetal
45
46
 
46
47
  protected
47
48
 
48
- def create_keys(provider, machine, machine_resource)
49
+ def create_keys(action_handler, machine, machine_resource)
49
50
  server_private_key = machine.read_file(client_pem_path)
50
51
  if server_private_key
51
52
  begin
@@ -61,7 +62,7 @@ module ChefMetal
61
62
  # If the server private key does not match our source key, overwrite it
62
63
  server_private_key = source_key
63
64
  if machine_resource.allow_overwrite_keys
64
- machine.write_file(provider, client_pem_path, server_private_key.to_pem, :ensure_dir => true)
65
+ machine.write_file(action_handler, client_pem_path, server_private_key.to_pem, :ensure_dir => true)
65
66
  else
66
67
  raise "Private key on machine #{machine_resource.name} does not match desired input key."
67
68
  end
@@ -70,7 +71,7 @@ module ChefMetal
70
71
  else
71
72
 
72
73
  # If the server does not already have keys, create them and upload
73
- Cheffish.inline_resource(provider) do
74
+ Cheffish.inline_resource(action_handler) do
74
75
  private_key 'in_memory' do
75
76
  path :none
76
77
  if machine_resource.private_key_options
@@ -82,7 +83,7 @@ module ChefMetal
82
83
  end
83
84
  end
84
85
 
85
- machine.write_file(provider, client_pem_path, server_private_key.to_pem, :ensure_dir => true)
86
+ machine.write_file(action_handler, client_pem_path, server_private_key.to_pem, :ensure_dir => true)
86
87
  end
87
88
 
88
89
  server_private_key.public_key
@@ -106,9 +107,9 @@ module ChefMetal
106
107
  end
107
108
  end
108
109
 
109
- def create_chef_objects(provider, machine, machine_resource, public_key)
110
+ def create_chef_objects(action_handler, machine, machine_resource, public_key)
110
111
  # Save the node and create the client keys and client.
111
- ChefMetal.inline_resource(provider) do
112
+ ChefMetal.inline_resource(action_handler) do
112
113
  # Create client
113
114
  chef_client machine.node['name'] do
114
115
  chef_server machine_resource.chef_server
@@ -1,13 +1,13 @@
1
1
  module ChefMetal
2
2
  class InlineResource
3
- def initialize(provider)
4
- @provider = provider
3
+ def initialize(action_handler)
4
+ @action_handler = action_handler
5
5
  end
6
6
 
7
- attr_reader :provider
7
+ attr_reader :action_handler
8
8
 
9
- def run_context
10
- provider.run_context
9
+ def recipe_context
10
+ action_handler.recipe_context
11
11
  end
12
12
 
13
13
  def method_missing(method_symbol, *args, &block)
@@ -16,21 +16,24 @@ module ChefMetal
16
16
  # Checks the new platform => short_name => resource mapping initially
17
17
  # then fall back to the older approach (Chef::Resource.const_get) for
18
18
  # backward compatibility
19
- resource_class = Chef::Resource.resource_for_node(method_symbol, provider.run_context.node)
19
+ resource_class = Chef::Resource.resource_for_node(method_symbol,
20
+ action_handler.recipe_context.node)
20
21
 
21
22
  super unless resource_class
22
23
  raise ArgumentError, "You must supply a name when declaring a #{method_symbol} resource" unless args.size > 0
23
24
 
24
25
  # If we have a resource like this one, we want to steal its state
25
- args << run_context
26
+ args << recipe_context
26
27
  resource = resource_class.new(*args)
27
28
  resource.source_line = caller[0]
28
29
  resource.load_prior_resource
29
- resource.cookbook_name = provider.cookbook_name
30
+ resource.cookbook_name = action_handler.debug_name
30
31
  resource.recipe_name = @recipe_name
31
32
  resource.params = @params
32
- # Determine whether this resource is being created in the context of an enclosing Provider
33
- resource.enclosing_provider = provider.is_a?(Chef::Provider) ? provider : nil
33
+ # Determine whether this resource is being created in the context of an
34
+ # enclosing Provider
35
+ resource.enclosing_provider =
36
+ action_handler.is_a?(Chef::Provider) ? action_handler : nil
34
37
  # Evaluate resource attribute DSL
35
38
  resource.instance_eval(&block) if block
36
39
 
@@ -38,13 +41,13 @@ module ChefMetal
38
41
  resource.after_created
39
42
 
40
43
  # Do NOT put this in the resource collection.
41
- #run_context.resource_collection.insert(resource)
44
+ #recipe_context.resource_collection.insert(resource)
42
45
 
43
46
  # Instead, run the action directly.
44
47
  Array(resource.action).each do |action|
45
48
  resource.updated_by_last_action(false)
46
49
  run_provider_action(resource.provider_for_action(action))
47
- provider.new_resource.updated_by_last_action(true) if resource.updated_by_last_action?
50
+ action_handler.updated! if resource.updated_by_last_action?
48
51
  end
49
52
  resource
50
53
  end
@@ -85,4 +88,4 @@ module ChefMetal
85
88
  inline_provider.cleanup_after_converge
86
89
  end
87
90
  end
88
- end
91
+ end