chef-provisioning 2.0.0 → 2.0.1

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.
Files changed (53) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +899 -885
  3. data/Gemfile +17 -17
  4. data/LICENSE +201 -201
  5. data/README.md +312 -312
  6. data/Rakefile +55 -55
  7. data/chef-provisioning.gemspec +38 -38
  8. data/lib/chef/provider/load_balancer.rb +75 -75
  9. data/lib/chef/provider/machine.rb +219 -219
  10. data/lib/chef/provider/machine_batch.rb +224 -224
  11. data/lib/chef/provider/machine_execute.rb +36 -35
  12. data/lib/chef/provider/machine_file.rb +55 -55
  13. data/lib/chef/provider/machine_image.rb +105 -105
  14. data/lib/chef/provisioning.rb +110 -110
  15. data/lib/chef/provisioning/action_handler.rb +68 -68
  16. data/lib/chef/provisioning/add_prefix_action_handler.rb +35 -35
  17. data/lib/chef/provisioning/chef_managed_entry_store.rb +128 -128
  18. data/lib/chef/provisioning/chef_provider_action_handler.rb +74 -74
  19. data/lib/chef/provisioning/chef_run_data.rb +132 -132
  20. data/lib/chef/provisioning/convergence_strategy.rb +28 -28
  21. data/lib/chef/provisioning/convergence_strategy/ignore_convergence_failure.rb +54 -54
  22. data/lib/chef/provisioning/convergence_strategy/install_cached.rb +188 -188
  23. data/lib/chef/provisioning/convergence_strategy/install_msi.rb +71 -71
  24. data/lib/chef/provisioning/convergence_strategy/install_sh.rb +71 -71
  25. data/lib/chef/provisioning/convergence_strategy/no_converge.rb +35 -35
  26. data/lib/chef/provisioning/convergence_strategy/precreate_chef_objects.rb +255 -255
  27. data/lib/chef/provisioning/driver.rb +323 -323
  28. data/lib/chef/provisioning/load_balancer_spec.rb +14 -14
  29. data/lib/chef/provisioning/machine.rb +112 -112
  30. data/lib/chef/provisioning/machine/basic_machine.rb +84 -84
  31. data/lib/chef/provisioning/machine/unix_machine.rb +288 -288
  32. data/lib/chef/provisioning/machine/windows_machine.rb +108 -108
  33. data/lib/chef/provisioning/machine_image_spec.rb +34 -34
  34. data/lib/chef/provisioning/machine_spec.rb +58 -58
  35. data/lib/chef/provisioning/managed_entry.rb +121 -121
  36. data/lib/chef/provisioning/managed_entry_store.rb +136 -136
  37. data/lib/chef/provisioning/recipe_dsl.rb +99 -99
  38. data/lib/chef/provisioning/rspec.rb +27 -27
  39. data/lib/chef/provisioning/transport.rb +100 -100
  40. data/lib/chef/provisioning/transport/ssh.rb +403 -403
  41. data/lib/chef/provisioning/transport/winrm.rb +144 -156
  42. data/lib/chef/provisioning/version.rb +5 -5
  43. data/lib/chef/resource/chef_data_bag_resource.rb +146 -146
  44. data/lib/chef/resource/load_balancer.rb +57 -57
  45. data/lib/chef/resource/machine.rb +128 -128
  46. data/lib/chef/resource/machine_batch.rb +78 -78
  47. data/lib/chef/resource/machine_execute.rb +30 -29
  48. data/lib/chef/resource/machine_file.rb +34 -34
  49. data/lib/chef/resource/machine_image.rb +35 -35
  50. data/lib/chef_metal.rb +1 -1
  51. data/spec/chef/provisioning/convergence_strategy/ignore_convergence_failure_spec.rb +86 -86
  52. data/spec/spec_helper.rb +27 -27
  53. metadata +5 -5
@@ -1,54 +1,54 @@
1
- class Chef
2
- module Provisioning
3
- class ConvergenceStrategy
4
-
5
- # The purpose of this class is to decore the `converge` method with logic to catch any
6
- # convergence failure exceptions, log them and then squelch them. The reason we
7
- # need this is to prevent 1 provisioned node's converge failing an entire provisioning
8
- # recipe.
9
- module IgnoreConvergenceFailure
10
-
11
- attr_accessor :ignore_failures_array, :ignore_exit_values
12
-
13
- # This module is only meant to be extended into instances, not classes or modules.
14
- # Different machines may have different settings so we don't want to extend
15
- # every `install_sh` strategy with this logic.
16
- def self.extended(instance)
17
- opts = instance.convergence_options[:ignore_failure]
18
- instance.ignore_failures_array = []
19
- instance.ignore_exit_values = []
20
- if opts == true
21
- instance.ignore_failures_array << RuntimeError
22
- else
23
- # We assume it is integers or errors
24
- opts = [opts].flatten
25
- opts.each do |o|
26
- case
27
- when o.is_a?(Fixnum)
28
- instance.ignore_exit_values << o
29
- when o.is_a?(Range)
30
- instance.ignore_exit_values += o.to_a
31
- when o <= Exception
32
- instance.ignore_failures_array << o
33
- end
34
- end
35
- end
36
- end
37
-
38
- def converge(action_handler, machine)
39
- super
40
- rescue SystemExit => e
41
- if ignore_exit_values.include? e.status
42
- action_handler.performed_action("Caught SystemExit error #{e.status} from converging node but ignoring it")
43
- else
44
- raise
45
- end
46
- rescue *ignore_failures_array
47
- action_handler.performed_action("Caught error '#{$!.inspect.gsub(/\n/,'\\n')}' from converging node but ignoring it")
48
- end
49
-
50
- end
51
-
52
- end
53
- end
54
- end
1
+ class Chef
2
+ module Provisioning
3
+ class ConvergenceStrategy
4
+
5
+ # The purpose of this class is to decore the `converge` method with logic to catch any
6
+ # convergence failure exceptions, log them and then squelch them. The reason we
7
+ # need this is to prevent 1 provisioned node's converge failing an entire provisioning
8
+ # recipe.
9
+ module IgnoreConvergenceFailure
10
+
11
+ attr_accessor :ignore_failures_array, :ignore_exit_values
12
+
13
+ # This module is only meant to be extended into instances, not classes or modules.
14
+ # Different machines may have different settings so we don't want to extend
15
+ # every `install_sh` strategy with this logic.
16
+ def self.extended(instance)
17
+ opts = instance.convergence_options[:ignore_failure]
18
+ instance.ignore_failures_array = []
19
+ instance.ignore_exit_values = []
20
+ if opts == true
21
+ instance.ignore_failures_array << RuntimeError
22
+ else
23
+ # We assume it is integers or errors
24
+ opts = [opts].flatten
25
+ opts.each do |o|
26
+ case
27
+ when o.is_a?(Fixnum)
28
+ instance.ignore_exit_values << o
29
+ when o.is_a?(Range)
30
+ instance.ignore_exit_values += o.to_a
31
+ when o <= Exception
32
+ instance.ignore_failures_array << o
33
+ end
34
+ end
35
+ end
36
+ end
37
+
38
+ def converge(action_handler, machine)
39
+ super
40
+ rescue SystemExit => e
41
+ if ignore_exit_values.include? e.status
42
+ action_handler.performed_action("Caught SystemExit error #{e.status} from converging node but ignoring it")
43
+ else
44
+ raise
45
+ end
46
+ rescue *ignore_failures_array
47
+ action_handler.performed_action("Caught error '#{$!.inspect.gsub(/\n/,'\\n')}' from converging node but ignoring it")
48
+ end
49
+
50
+ end
51
+
52
+ end
53
+ end
54
+ end
@@ -1,188 +1,188 @@
1
- require 'chef/provisioning/convergence_strategy/precreate_chef_objects'
2
- require 'pathname'
3
- require 'fileutils'
4
- require 'digest/md5'
5
- require 'thread'
6
- require 'chef/http/simple'
7
-
8
- class Chef
9
- module Provisioning
10
- class ConvergenceStrategy
11
- class InstallCached < PrecreateChefObjects
12
- # convergence_options is a hash of setup convergence_options, including:
13
- # - :chef_server
14
- # - :allow_overwrite_keys
15
- # - :source_key, :source_key_path, :source_key_pass_phrase
16
- # - :private_key_options
17
- # - :ohai_hints
18
- # - :public_key_path, :public_key_format
19
- # - :admin, :validator
20
- # - :chef_client_timeout
21
- # - :client_rb_path, :client_pem_path
22
- # - :chef_version, :prerelease, :package_cache_path
23
- # - :package_metadata
24
- def initialize(convergence_options, config)
25
- convergence_options = Cheffish::MergedConfig.new(convergence_options, {
26
- :client_rb_path => '/etc/chef/client.rb',
27
- :client_pem_path => '/etc/chef/client.pem'
28
- })
29
- super(convergence_options, config)
30
- @client_rb_path ||= convergence_options[:client_rb_path]
31
- @chef_version ||= convergence_options[:chef_version]
32
- @prerelease ||= convergence_options[:prerelease]
33
- @package_cache_path ||= convergence_options[:package_cache_path] || "#{ENV['HOME']}/.chef/package_cache"
34
- @package_cache = {}
35
- @tmp_dir = '/tmp'
36
- @chef_client_timeout = convergence_options.has_key?(:chef_client_timeout) ? convergence_options[:chef_client_timeout] : 120*60 # Default: 2 hours
37
- FileUtils.mkdir_p(@package_cache_path)
38
- @package_cache_lock = Mutex.new
39
- @package_metadata ||= convergence_options[:package_metadata]
40
- end
41
-
42
- attr_reader :client_rb_path
43
- attr_reader :client_pem_path
44
- attr_reader :chef_version
45
- attr_reader :prerelease
46
-
47
- def setup_convergence(action_handler, machine)
48
- super
49
-
50
- # Check for existing chef client.
51
- version = machine.execute_always('chef-client -v')
52
-
53
- # Don't do install/upgrade if a chef client exists and
54
- # no chef version is defined by user configs or
55
- # the chef client's version already matches user config
56
- if version.exitstatus == 0
57
- version = version.stdout.strip
58
- if !chef_version
59
- return
60
- elsif version =~ /Chef: #{chef_version}$/
61
- Chef::Log.debug "Already installed chef version #{version}"
62
- return
63
- elsif version.include?(chef_version)
64
- Chef::Log.warn "Installed chef version #{version} contains desired version #{chef_version}. " +
65
- "If you see this message on consecutive chef runs tighten your desired version constraint to prevent " +
66
- "multiple convergence."
67
- end
68
- end
69
-
70
- # Install chef client
71
- platform, platform_version, machine_architecture = machine.detect_os(action_handler)
72
- package_file = download_package_for_platform(action_handler, machine, platform, platform_version, machine_architecture)
73
- remote_package_file = "#{@tmp_dir}/#{File.basename(package_file)}"
74
- machine.upload_file(action_handler, package_file, remote_package_file)
75
- install_package(action_handler, machine, platform, remote_package_file)
76
- end
77
-
78
- def converge(action_handler, machine)
79
- super
80
-
81
- action_handler.open_stream(machine.node['name']) do |stdout|
82
- action_handler.open_stream(machine.node['name']) do |stderr|
83
- command_line = "chef-client"
84
- command_line << " -c #{@client_rb_path} -l #{config[:log_level].to_s}" if config[:log_level]
85
- machine.execute(action_handler, command_line,
86
- :stream_stdout => stdout,
87
- :stream_stderr => stderr,
88
- :timeout => @chef_client_timeout)
89
- end
90
- end
91
- end
92
-
93
- private
94
-
95
- def download_package_for_platform(action_handler, machine, platform, platform_version, machine_architecture)
96
- @package_cache_lock.synchronize do
97
- @package_cache ||= {}
98
- @package_cache[platform] ||= {}
99
- @package_cache[platform][platform_version] ||= {}
100
- @package_cache[platform][platform_version][machine_architecture] ||= { :lock => Mutex.new }
101
- end
102
- @package_cache[platform][platform_version][machine_architecture][:lock].synchronize do
103
- if !@package_cache[platform][platform_version][machine_architecture][:file]
104
- #
105
- # Grab metadata
106
- #
107
- metadata = @package_metadata
108
- if !metadata
109
- Chef::Log.info("No metadata supplied, downloading it...")
110
- metadata = download_metadata_for_platform(machine, platform, platform_version, machine_architecture)
111
- end
112
-
113
- # Download actual package desired by metadata
114
- package_file = "#{@package_cache_path}/#{URI(metadata[:url]).path.split('/')[-1]}"
115
-
116
- Chef::Log.debug("Package metadata: #{metadata}")
117
- Chef::Provisioning.inline_resource(action_handler) do
118
- remote_file package_file do
119
- source metadata[:url]
120
- checksum metadata[:sha256]
121
- end
122
- end
123
-
124
- @package_cache[platform][platform_version][machine_architecture][:file] = package_file
125
- end
126
- end
127
- @package_cache[platform][platform_version][machine_architecture][:file]
128
- end
129
-
130
- def download_metadata_for_platform(machine, platform, platform_version, machine_architecture)
131
- #
132
- # Figure out the URL to the metadata
133
- #
134
- metadata_url="https://www.chef.io/chef/metadata"
135
- metadata_url << "?v=#{@chef_version}"
136
- metadata_url << "&prerelease=#{@prerelease ? 'true' : 'false'}"
137
- metadata_url << "&p=#{platform.strip}"
138
- metadata_url << "&pv=#{platform_version.strip}"
139
- metadata_url << "&m=#{machine_architecture.strip}"
140
- use_ssl = true
141
-
142
- # solaris 9 lacks openssl, solaris 10 lacks recent enough credentials - your base O/S is completely insecure, please upgrade
143
- if platform == 'solaris2' && (platform_version == '5.9' || platform_version == '5.10')
144
- metadata_url.sub(/^https/, 'http')
145
- use_ssl = false
146
- end
147
-
148
- # Download and parse the metadata
149
- Chef::Log.debug("Getting metadata for machine #{machine.node['name']}: #{metadata_url}")
150
- uri = URI(metadata_url)
151
- metadata_str = Chef::HTTP::Simple.new(uri).get(uri)
152
- metadata = {}
153
- metadata_str.each_line do |line|
154
- key, value = line.split("\t", 2)
155
- metadata[key.to_sym] = value.chomp
156
- end
157
- metadata
158
- end
159
-
160
- def install_package(action_handler, machine, platform, remote_package_file)
161
- extension = File.extname(remote_package_file)
162
- result = case extension
163
- when '.rpm'
164
- if platform == "wrlinux"
165
- machine.execute(action_handler, "yum install -yv \"#{remote_package_file}\"")
166
- else
167
- machine.execute(action_handler, "rpm -Uvh --oldpackage --replacepkgs \"#{remote_package_file}\"")
168
- end
169
- when '.deb'
170
- machine.execute(action_handler, "dpkg -i \"#{remote_package_file}\"")
171
- when '.solaris'
172
- machine.write_file(action_handler, "#{@tmp_dir}/nocheck", <<EOM)
173
- conflict=nocheck
174
- action=nocheck
175
- mail=
176
- EOM
177
- machine.execute(action_handler, "pkgrm -a \"#{@tmp_dir}/nocheck\" -n chef")
178
- machine.execute(action_handler, "pkgadd -n -d \"#{remote_package_file}\" -a \"#{@tmp_dir}/nocheck\" chef")
179
- when '.sh'
180
- machine.execute(action_handler, "sh \"#{remote_package_file}\"")
181
- else
182
- raise "Unknown package extension '#{extension}' for file #{remote_package_file}"
183
- end
184
- end
185
- end
186
- end
187
- end
188
- end
1
+ require 'chef/provisioning/convergence_strategy/precreate_chef_objects'
2
+ require 'pathname'
3
+ require 'fileutils'
4
+ require 'digest/md5'
5
+ require 'thread'
6
+ require 'chef/http/simple'
7
+
8
+ class Chef
9
+ module Provisioning
10
+ class ConvergenceStrategy
11
+ class InstallCached < PrecreateChefObjects
12
+ # convergence_options is a hash of setup convergence_options, including:
13
+ # - :chef_server
14
+ # - :allow_overwrite_keys
15
+ # - :source_key, :source_key_path, :source_key_pass_phrase
16
+ # - :private_key_options
17
+ # - :ohai_hints
18
+ # - :public_key_path, :public_key_format
19
+ # - :admin, :validator
20
+ # - :chef_client_timeout
21
+ # - :client_rb_path, :client_pem_path
22
+ # - :chef_version, :prerelease, :package_cache_path
23
+ # - :package_metadata
24
+ def initialize(convergence_options, config)
25
+ convergence_options = Cheffish::MergedConfig.new(convergence_options, {
26
+ :client_rb_path => '/etc/chef/client.rb',
27
+ :client_pem_path => '/etc/chef/client.pem'
28
+ })
29
+ super(convergence_options, config)
30
+ @client_rb_path ||= convergence_options[:client_rb_path]
31
+ @chef_version ||= convergence_options[:chef_version]
32
+ @prerelease ||= convergence_options[:prerelease]
33
+ @package_cache_path ||= convergence_options[:package_cache_path] || "#{ENV['HOME']}/.chef/package_cache"
34
+ @package_cache = {}
35
+ @tmp_dir = '/tmp'
36
+ @chef_client_timeout = convergence_options.has_key?(:chef_client_timeout) ? convergence_options[:chef_client_timeout] : 120*60 # Default: 2 hours
37
+ FileUtils.mkdir_p(@package_cache_path)
38
+ @package_cache_lock = Mutex.new
39
+ @package_metadata ||= convergence_options[:package_metadata]
40
+ end
41
+
42
+ attr_reader :client_rb_path
43
+ attr_reader :client_pem_path
44
+ attr_reader :chef_version
45
+ attr_reader :prerelease
46
+
47
+ def setup_convergence(action_handler, machine)
48
+ super
49
+
50
+ # Check for existing chef client.
51
+ version = machine.execute_always('chef-client -v')
52
+
53
+ # Don't do install/upgrade if a chef client exists and
54
+ # no chef version is defined by user configs or
55
+ # the chef client's version already matches user config
56
+ if version.exitstatus == 0
57
+ version = version.stdout.strip
58
+ if !chef_version
59
+ return
60
+ elsif version =~ /Chef: #{chef_version}$/
61
+ Chef::Log.debug "Already installed chef version #{version}"
62
+ return
63
+ elsif version.include?(chef_version)
64
+ Chef::Log.warn "Installed chef version #{version} contains desired version #{chef_version}. " +
65
+ "If you see this message on consecutive chef runs tighten your desired version constraint to prevent " +
66
+ "multiple convergence."
67
+ end
68
+ end
69
+
70
+ # Install chef client
71
+ platform, platform_version, machine_architecture = machine.detect_os(action_handler)
72
+ package_file = download_package_for_platform(action_handler, machine, platform, platform_version, machine_architecture)
73
+ remote_package_file = "#{@tmp_dir}/#{File.basename(package_file)}"
74
+ machine.upload_file(action_handler, package_file, remote_package_file)
75
+ install_package(action_handler, machine, platform, remote_package_file)
76
+ end
77
+
78
+ def converge(action_handler, machine)
79
+ super
80
+
81
+ action_handler.open_stream(machine.node['name']) do |stdout|
82
+ action_handler.open_stream(machine.node['name']) do |stderr|
83
+ command_line = "chef-client"
84
+ command_line << " -c #{@client_rb_path} -l #{config[:log_level].to_s}" if config[:log_level]
85
+ machine.execute(action_handler, command_line,
86
+ :stream_stdout => stdout,
87
+ :stream_stderr => stderr,
88
+ :timeout => @chef_client_timeout)
89
+ end
90
+ end
91
+ end
92
+
93
+ private
94
+
95
+ def download_package_for_platform(action_handler, machine, platform, platform_version, machine_architecture)
96
+ @package_cache_lock.synchronize do
97
+ @package_cache ||= {}
98
+ @package_cache[platform] ||= {}
99
+ @package_cache[platform][platform_version] ||= {}
100
+ @package_cache[platform][platform_version][machine_architecture] ||= { :lock => Mutex.new }
101
+ end
102
+ @package_cache[platform][platform_version][machine_architecture][:lock].synchronize do
103
+ if !@package_cache[platform][platform_version][machine_architecture][:file]
104
+ #
105
+ # Grab metadata
106
+ #
107
+ metadata = @package_metadata
108
+ if !metadata
109
+ Chef::Log.info("No metadata supplied, downloading it...")
110
+ metadata = download_metadata_for_platform(machine, platform, platform_version, machine_architecture)
111
+ end
112
+
113
+ # Download actual package desired by metadata
114
+ package_file = "#{@package_cache_path}/#{URI(metadata[:url]).path.split('/')[-1]}"
115
+
116
+ Chef::Log.debug("Package metadata: #{metadata}")
117
+ Chef::Provisioning.inline_resource(action_handler) do
118
+ remote_file package_file do
119
+ source metadata[:url]
120
+ checksum metadata[:sha256]
121
+ end
122
+ end
123
+
124
+ @package_cache[platform][platform_version][machine_architecture][:file] = package_file
125
+ end
126
+ end
127
+ @package_cache[platform][platform_version][machine_architecture][:file]
128
+ end
129
+
130
+ def download_metadata_for_platform(machine, platform, platform_version, machine_architecture)
131
+ #
132
+ # Figure out the URL to the metadata
133
+ #
134
+ metadata_url="https://www.chef.io/chef/metadata"
135
+ metadata_url << "?v=#{@chef_version}"
136
+ metadata_url << "&prerelease=#{@prerelease ? 'true' : 'false'}"
137
+ metadata_url << "&p=#{platform.strip}"
138
+ metadata_url << "&pv=#{platform_version.strip}"
139
+ metadata_url << "&m=#{machine_architecture.strip}"
140
+ use_ssl = true
141
+
142
+ # solaris 9 lacks openssl, solaris 10 lacks recent enough credentials - your base O/S is completely insecure, please upgrade
143
+ if platform == 'solaris2' && (platform_version == '5.9' || platform_version == '5.10')
144
+ metadata_url.sub(/^https/, 'http')
145
+ use_ssl = false
146
+ end
147
+
148
+ # Download and parse the metadata
149
+ Chef::Log.debug("Getting metadata for machine #{machine.node['name']}: #{metadata_url}")
150
+ uri = URI(metadata_url)
151
+ metadata_str = Chef::HTTP::Simple.new(uri).get(uri)
152
+ metadata = {}
153
+ metadata_str.each_line do |line|
154
+ key, value = line.split("\t", 2)
155
+ metadata[key.to_sym] = value.chomp
156
+ end
157
+ metadata
158
+ end
159
+
160
+ def install_package(action_handler, machine, platform, remote_package_file)
161
+ extension = File.extname(remote_package_file)
162
+ result = case extension
163
+ when '.rpm'
164
+ if platform == "wrlinux"
165
+ machine.execute(action_handler, "yum install -yv \"#{remote_package_file}\"")
166
+ else
167
+ machine.execute(action_handler, "rpm -Uvh --oldpackage --replacepkgs \"#{remote_package_file}\"")
168
+ end
169
+ when '.deb'
170
+ machine.execute(action_handler, "dpkg -i \"#{remote_package_file}\"")
171
+ when '.solaris'
172
+ machine.write_file(action_handler, "#{@tmp_dir}/nocheck", <<EOM)
173
+ conflict=nocheck
174
+ action=nocheck
175
+ mail=
176
+ EOM
177
+ machine.execute(action_handler, "pkgrm -a \"#{@tmp_dir}/nocheck\" -n chef")
178
+ machine.execute(action_handler, "pkgadd -n -d \"#{remote_package_file}\" -a \"#{@tmp_dir}/nocheck\" chef")
179
+ when '.sh'
180
+ machine.execute(action_handler, "sh \"#{remote_package_file}\"")
181
+ else
182
+ raise "Unknown package extension '#{extension}' for file #{remote_package_file}"
183
+ end
184
+ end
185
+ end
186
+ end
187
+ end
188
+ end