chef-metal 0.4 → 0.5

Sign up to get free protection for your applications and to get access to all the features.
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