chef-provisioning 2.0.1 → 2.0.2

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 +906 -899
  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 -36
  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 -144
  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 -30
  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 +10 -4
@@ -1,144 +1,144 @@
1
- require 'chef/provisioning/transport'
2
- require 'base64'
3
- require 'timeout'
4
-
5
- class Chef
6
- module Provisioning
7
- class Transport
8
- # Transport to handle the WinRM connection protocol.
9
- class WinRM < Chef::Provisioning::Transport
10
- #
11
- # Create a new WinRM transport.
12
- #
13
- # == Arguments
14
- # - endpoint: the WinRM endpoint, e.g. http://145.14.51.45:5985/wsman.
15
- # - type: the connection type, e.g. :plaintext.
16
- # - options: options hash, including both WinRM options and transport options.
17
- # For transport options, see the Transport.options definition. WinRM
18
- # options include :user, :pass, :disable_sspi => true, among others.
19
- # - global_config: an options hash that looks suspiciously similar to
20
- # Chef::Config, containing at least the key :log_level.
21
- #
22
- # The actual connection is made as ::WinRM::WinRMWebService.new(endpoint, type, options)
23
- #
24
- def initialize(endpoint, type, options, global_config)
25
- @options = options
26
- @options[:endpoint] = endpoint
27
- @options[:transport] = type
28
-
29
- # WinRM v2 switched from :pass to :password
30
- # we accept either to avoid having to update every driver
31
- @options[:password] = @options[:password] || @options[:pass]
32
-
33
- @config = global_config
34
- end
35
-
36
- attr_reader :options
37
- attr_reader :config
38
-
39
- def execute(command, execute_options = {})
40
- output = with_execute_timeout(execute_options) do
41
- block = Proc.new { |stdout, stderr| stream_chunk(execute_options, stdout, stderr) }
42
- session.run(command, &block)
43
- end
44
- WinRMResult.new(command, execute_options, config, output)
45
- end
46
-
47
- def read_file(path)
48
- result = execute("[Convert]::ToBase64String((Get-Content #{escape(path)} -Encoding byte -ReadCount 0))")
49
- if result.exitstatus == 0
50
- Base64.decode64(result.stdout)
51
- else
52
- nil
53
- end
54
- end
55
-
56
- def write_file(path, content)
57
- file = Tempfile.new('provisioning-upload')
58
- begin
59
- file.write(content)
60
- file.close
61
- file_transporter.upload(file.path, path)
62
- ensure
63
- file.unlink
64
- end
65
- end
66
-
67
- def disconnect
68
- #
69
- end
70
-
71
- def escape(string)
72
- "\"#{string.gsub("\"", "`\"")}\""
73
- end
74
-
75
- def available?
76
- # If you can't pwd within 10 seconds, you can't pwd
77
- execute('pwd', :timeout => 10)
78
- true
79
- rescue ::WinRM::WinRMAuthorizationError
80
- Chef::Log.debug("unavailable: winrm authentication error: #{$!.inspect} ")
81
- disconnect
82
- false
83
- rescue Timeout::Error, Errno::EHOSTUNREACH, Errno::ETIMEDOUT, Errno::ECONNREFUSED, Errno::ECONNRESET, ::WinRM::WinRMError
84
- Chef::Log.debug("unavailable: network connection failed or broke: #{$!.inspect}")
85
- disconnect
86
- false
87
- end
88
-
89
- def make_url_available_to_remote(local_url)
90
- uri = URI(local_url)
91
- uri.scheme = 'http' if uri.scheme == 'chefzero' && uri.host == 'localhost'
92
- host = Socket.getaddrinfo(uri.host, uri.scheme, nil, :STREAM)[0][3]
93
- if host == '127.0.0.1' || host == '::1'
94
- raise 'Unable to converge locally via winrm. Local converge is currently only supported with SSH. You may only converge with winrm against a chef-server.'
95
- end
96
- local_url
97
- end
98
-
99
- protected
100
-
101
- def session
102
- @session ||= begin
103
- require 'winrm'
104
- ::WinRM::Connection.new(options).shell(:powershell)
105
- end
106
- end
107
-
108
- def file_transporter
109
- @file_transporter ||= begin
110
- require 'winrm-fs'
111
- ::WinRM::FS::Core::FileTransporter.new(session)
112
- end
113
- end
114
-
115
- class WinRMResult
116
- def initialize(command, options, config, output)
117
- @command = command
118
- @options = options
119
- @config = config
120
- @exitstatus = output.exitcode
121
- @stdout = output.stdout
122
- @stderr = output.stderr
123
- end
124
-
125
- attr_reader :stdout
126
- attr_reader :stderr
127
- attr_reader :exitstatus
128
- attr_reader :command
129
- attr_reader :options
130
- attr_reader :config
131
-
132
- def error!
133
- if exitstatus != 0
134
- msg = "Error: command '#{command}' exited with code #{exitstatus}.\n"
135
- msg << "STDOUT: #{stdout}" if !options[:stream] && !options[:stream_stdout] && config[:log_level] != :debug
136
- msg << "STDERR: #{stderr}" if !options[:stream] && !options[:stream_stderr] && config[:log_level] != :debug
137
- raise msg
138
- end
139
- end
140
- end
141
- end
142
- end
143
- end
144
- end
1
+ require 'chef/provisioning/transport'
2
+ require 'base64'
3
+ require 'timeout'
4
+
5
+ class Chef
6
+ module Provisioning
7
+ class Transport
8
+ # Transport to handle the WinRM connection protocol.
9
+ class WinRM < Chef::Provisioning::Transport
10
+ #
11
+ # Create a new WinRM transport.
12
+ #
13
+ # == Arguments
14
+ # - endpoint: the WinRM endpoint, e.g. http://145.14.51.45:5985/wsman.
15
+ # - type: the connection type, e.g. :plaintext.
16
+ # - options: options hash, including both WinRM options and transport options.
17
+ # For transport options, see the Transport.options definition. WinRM
18
+ # options include :user, :pass, :disable_sspi => true, among others.
19
+ # - global_config: an options hash that looks suspiciously similar to
20
+ # Chef::Config, containing at least the key :log_level.
21
+ #
22
+ # The actual connection is made as ::WinRM::WinRMWebService.new(endpoint, type, options)
23
+ #
24
+ def initialize(endpoint, type, options, global_config)
25
+ @options = options
26
+ @options[:endpoint] = endpoint
27
+ @options[:transport] = type
28
+
29
+ # WinRM v2 switched from :pass to :password
30
+ # we accept either to avoid having to update every driver
31
+ @options[:password] = @options[:password] || @options[:pass]
32
+
33
+ @config = global_config
34
+ end
35
+
36
+ attr_reader :options
37
+ attr_reader :config
38
+
39
+ def execute(command, execute_options = {})
40
+ output = with_execute_timeout(execute_options) do
41
+ block = Proc.new { |stdout, stderr| stream_chunk(execute_options, stdout, stderr) }
42
+ session.run(command, &block)
43
+ end
44
+ WinRMResult.new(command, execute_options, config, output)
45
+ end
46
+
47
+ def read_file(path)
48
+ result = execute("[Convert]::ToBase64String((Get-Content #{escape(path)} -Encoding byte -ReadCount 0))")
49
+ if result.exitstatus == 0
50
+ Base64.decode64(result.stdout)
51
+ else
52
+ nil
53
+ end
54
+ end
55
+
56
+ def write_file(path, content)
57
+ file = Tempfile.new('provisioning-upload')
58
+ begin
59
+ file.write(content)
60
+ file.close
61
+ file_transporter.upload(file.path, path)
62
+ ensure
63
+ file.unlink
64
+ end
65
+ end
66
+
67
+ def disconnect
68
+ #
69
+ end
70
+
71
+ def escape(string)
72
+ "\"#{string.gsub("\"", "`\"")}\""
73
+ end
74
+
75
+ def available?
76
+ # If you can't pwd within 10 seconds, you can't pwd
77
+ execute('pwd', :timeout => 10)
78
+ true
79
+ rescue ::WinRM::WinRMAuthorizationError
80
+ Chef::Log.debug("unavailable: winrm authentication error: #{$!.inspect} ")
81
+ disconnect
82
+ false
83
+ rescue Timeout::Error, Errno::EHOSTUNREACH, Errno::ETIMEDOUT, Errno::ECONNREFUSED, Errno::ECONNRESET, ::WinRM::WinRMError
84
+ Chef::Log.debug("unavailable: network connection failed or broke: #{$!.inspect}")
85
+ disconnect
86
+ false
87
+ end
88
+
89
+ def make_url_available_to_remote(local_url)
90
+ uri = URI(local_url)
91
+ uri.scheme = 'http' if uri.scheme == 'chefzero' && uri.host == 'localhost'
92
+ host = Socket.getaddrinfo(uri.host, uri.scheme, nil, :STREAM)[0][3]
93
+ if host == '127.0.0.1' || host == '::1'
94
+ raise 'Unable to converge locally via winrm. Local converge is currently only supported with SSH. You may only converge with winrm against a chef-server.'
95
+ end
96
+ local_url
97
+ end
98
+
99
+ protected
100
+
101
+ def session
102
+ @session ||= begin
103
+ require 'winrm'
104
+ ::WinRM::Connection.new(options).shell(:powershell)
105
+ end
106
+ end
107
+
108
+ def file_transporter
109
+ @file_transporter ||= begin
110
+ require 'winrm-fs'
111
+ ::WinRM::FS::Core::FileTransporter.new(session)
112
+ end
113
+ end
114
+
115
+ class WinRMResult
116
+ def initialize(command, options, config, output)
117
+ @command = command
118
+ @options = options
119
+ @config = config
120
+ @exitstatus = output.exitcode
121
+ @stdout = output.stdout
122
+ @stderr = output.stderr
123
+ end
124
+
125
+ attr_reader :stdout
126
+ attr_reader :stderr
127
+ attr_reader :exitstatus
128
+ attr_reader :command
129
+ attr_reader :options
130
+ attr_reader :config
131
+
132
+ def error!
133
+ if exitstatus != 0
134
+ msg = "Error: command '#{command}' exited with code #{exitstatus}.\n"
135
+ msg << "STDOUT: #{stdout}" if !options[:stream] && !options[:stream_stdout] && config[:log_level] != :debug
136
+ msg << "STDERR: #{stderr}" if !options[:stream] && !options[:stream_stderr] && config[:log_level] != :debug
137
+ raise msg
138
+ end
139
+ end
140
+ end
141
+ end
142
+ end
143
+ end
144
+ end
@@ -1,5 +1,5 @@
1
- class Chef
2
- module Provisioning
3
- VERSION = '2.0.1'
4
- end
5
- end
1
+ class Chef
2
+ module Provisioning
3
+ VERSION = '2.0.2'
4
+ end
5
+ end
@@ -1,146 +1,146 @@
1
- require 'chef/resource/lwrp_base'
2
- require 'cheffish'
3
-
4
- # A resource that is backed by a data bag in a Chef server somewhere
5
- class Chef::Resource::ChefDataBagResource < Chef::Resource::LWRPBase
6
-
7
- # The key to store this thing under (/data/bag/<<name>>).
8
- attr_reader :name
9
-
10
- class << self
11
- # The name of the databag to store the item in.
12
- attr_reader :databag_name
13
- end
14
-
15
- def initialize(name, run_context=nil)
16
- super
17
- Chef::Log.debug("Re-hydrating #{name} from #{self.class.databag_name}...")
18
- self.hydrate
19
- end
20
-
21
- # A list of attributes to be persisted into the databag.
22
- # @return [Array] List of attributes that are stored in the databag
23
- def self.stored_attributes
24
- @stored_attributes || []
25
- end
26
-
27
- # Set databag name
28
- # @return [Void]
29
- def self.databag_name= name
30
- Chef::Log.debug("Setting databag name to #{name}")
31
- @databag_name = name
32
- end
33
-
34
- # Mark an attribute as stored by adding it to the internal tracking list {stored_attributes}
35
- # and then delegating to {Chef::Resource::LWRPBase#attribute}
36
- # @param attr_name [Symbol] Name of the attribute as a symbol
37
- # @return [Void]
38
- def self.stored_attribute(attr_name, *args)
39
- @stored_attributes ||= []
40
- @stored_attributes << attr_name
41
- self.attribute attr_name, *args
42
- end
43
-
44
- # Load persisted data from the server's databag. If the databag does not exist on the
45
- # server, returns nil.
46
- #
47
- # @param chef_server [Hash] A hash representing which Chef server to talk to
48
- # @option chef_server [String] :chef_server_url URL to the Chef server
49
- # @option chef_server [Hash] :options Options for when talking to the Chef server
50
- # @option options [String] :client_name The node name making the call
51
- # @option options [String] :signing_key_filename Path to the signing key
52
- # @return [Object] an instance of this class re-hydrated from the data hash stored in the
53
- # databag.
54
- def hydrate(chef_server = Cheffish.default_chef_server)
55
- chef_api = Cheffish.chef_server_api(chef_server)
56
- begin
57
- data = chef_api.get("/data/#{self.class.databag_name}/#{name}")
58
- load_from_hash(data)
59
- Chef::Log.debug("Rehydrating resource from #{self.class.databag_name}/#{name}: #{data}")
60
- rescue Net::HTTPServerException => e
61
- if e.response.code == '404'
62
- nil
63
- else
64
- raise
65
- end
66
- end
67
- end
68
-
69
- # Load instance variable data from a hash. For each key,value pair, set @<key> to value
70
- # @param hash [Hash] Hash containing the instance variable data
71
- # @return [Object] self after having been populated with data.
72
- def load_from_hash hash
73
- hash.each do |k,v|
74
- self.instance_variable_set("@#{k}", v)
75
- end
76
- self
77
- end
78
-
79
- # Convert the values in {stored_attributes} to a hash for storing in a databag
80
- # @return [Hash] a hash of (k,v) pairs where k is each record in {stored_attributes}
81
- def storage_hash
82
- ignored = []
83
-
84
- hash = {}
85
- (self.class.stored_attributes - ignored).each do |attr_name|
86
- varname = "@#{attr_name.to_s.gsub('@', '')}"
87
- key = varname.gsub('@', '')
88
- hash[key] = self.instance_variable_get varname
89
- end
90
-
91
- hash
92
- end
93
-
94
-
95
- # Save this entity to the server. If you have significant information that
96
- # could be lost, you should do this as quickly as possible.
97
- # @return [Void]
98
- def save
99
-
100
- create_databag_if_needed self.class.databag_name
101
-
102
- # Clone for inline_resource
103
- _databag_name = self.class.databag_name
104
- _hash = self.storage_hash
105
- _name = self.name
106
-
107
- Cheffish.inline_resource(self, @action) do
108
- chef_data_bag_item _name do
109
- data_bag _databag_name
110
- raw_data _hash
111
- action :create
112
- end
113
- end
114
- end
115
-
116
- # Delete this entity from the server
117
- # @return [Void]
118
- def delete
119
- # Clone for inline_resource
120
- _name = self.name
121
- _databag_name = self.class.databag_name
122
-
123
- Cheffish.inline_resource(self, @action) do
124
- chef_data_bag_item _name do
125
- data_bag _databag_name
126
- action :delete
127
- end
128
- end
129
- end
130
-
131
- def new_resource
132
- self
133
- end
134
-
135
- private
136
- # Create the databag with Cheffish if required
137
- # @return [Void]
138
- def create_databag_if_needed databag_name
139
- _databag_name = databag_name
140
- Cheffish.inline_resource(self, @action) do
141
- chef_data_bag _databag_name do
142
- action :create
143
- end
144
- end
145
- end
146
- end
1
+ require 'chef/resource/lwrp_base'
2
+ require 'cheffish'
3
+
4
+ # A resource that is backed by a data bag in a Chef server somewhere
5
+ class Chef::Resource::ChefDataBagResource < Chef::Resource::LWRPBase
6
+
7
+ # The key to store this thing under (/data/bag/<<name>>).
8
+ attr_reader :name
9
+
10
+ class << self
11
+ # The name of the databag to store the item in.
12
+ attr_reader :databag_name
13
+ end
14
+
15
+ def initialize(name, run_context=nil)
16
+ super
17
+ Chef::Log.debug("Re-hydrating #{name} from #{self.class.databag_name}...")
18
+ self.hydrate
19
+ end
20
+
21
+ # A list of attributes to be persisted into the databag.
22
+ # @return [Array] List of attributes that are stored in the databag
23
+ def self.stored_attributes
24
+ @stored_attributes || []
25
+ end
26
+
27
+ # Set databag name
28
+ # @return [Void]
29
+ def self.databag_name= name
30
+ Chef::Log.debug("Setting databag name to #{name}")
31
+ @databag_name = name
32
+ end
33
+
34
+ # Mark an attribute as stored by adding it to the internal tracking list {stored_attributes}
35
+ # and then delegating to {Chef::Resource::LWRPBase#attribute}
36
+ # @param attr_name [Symbol] Name of the attribute as a symbol
37
+ # @return [Void]
38
+ def self.stored_attribute(attr_name, *args)
39
+ @stored_attributes ||= []
40
+ @stored_attributes << attr_name
41
+ self.attribute attr_name, *args
42
+ end
43
+
44
+ # Load persisted data from the server's databag. If the databag does not exist on the
45
+ # server, returns nil.
46
+ #
47
+ # @param chef_server [Hash] A hash representing which Chef server to talk to
48
+ # @option chef_server [String] :chef_server_url URL to the Chef server
49
+ # @option chef_server [Hash] :options Options for when talking to the Chef server
50
+ # @option options [String] :client_name The node name making the call
51
+ # @option options [String] :signing_key_filename Path to the signing key
52
+ # @return [Object] an instance of this class re-hydrated from the data hash stored in the
53
+ # databag.
54
+ def hydrate(chef_server = Cheffish.default_chef_server)
55
+ chef_api = Cheffish.chef_server_api(chef_server)
56
+ begin
57
+ data = chef_api.get("/data/#{self.class.databag_name}/#{name}")
58
+ load_from_hash(data)
59
+ Chef::Log.debug("Rehydrating resource from #{self.class.databag_name}/#{name}: #{data}")
60
+ rescue Net::HTTPServerException => e
61
+ if e.response.code == '404'
62
+ nil
63
+ else
64
+ raise
65
+ end
66
+ end
67
+ end
68
+
69
+ # Load instance variable data from a hash. For each key,value pair, set @<key> to value
70
+ # @param hash [Hash] Hash containing the instance variable data
71
+ # @return [Object] self after having been populated with data.
72
+ def load_from_hash hash
73
+ hash.each do |k,v|
74
+ self.instance_variable_set("@#{k}", v)
75
+ end
76
+ self
77
+ end
78
+
79
+ # Convert the values in {stored_attributes} to a hash for storing in a databag
80
+ # @return [Hash] a hash of (k,v) pairs where k is each record in {stored_attributes}
81
+ def storage_hash
82
+ ignored = []
83
+
84
+ hash = {}
85
+ (self.class.stored_attributes - ignored).each do |attr_name|
86
+ varname = "@#{attr_name.to_s.gsub('@', '')}"
87
+ key = varname.gsub('@', '')
88
+ hash[key] = self.instance_variable_get varname
89
+ end
90
+
91
+ hash
92
+ end
93
+
94
+
95
+ # Save this entity to the server. If you have significant information that
96
+ # could be lost, you should do this as quickly as possible.
97
+ # @return [Void]
98
+ def save
99
+
100
+ create_databag_if_needed self.class.databag_name
101
+
102
+ # Clone for inline_resource
103
+ _databag_name = self.class.databag_name
104
+ _hash = self.storage_hash
105
+ _name = self.name
106
+
107
+ Cheffish.inline_resource(self, @action) do
108
+ chef_data_bag_item _name do
109
+ data_bag _databag_name
110
+ raw_data _hash
111
+ action :create
112
+ end
113
+ end
114
+ end
115
+
116
+ # Delete this entity from the server
117
+ # @return [Void]
118
+ def delete
119
+ # Clone for inline_resource
120
+ _name = self.name
121
+ _databag_name = self.class.databag_name
122
+
123
+ Cheffish.inline_resource(self, @action) do
124
+ chef_data_bag_item _name do
125
+ data_bag _databag_name
126
+ action :delete
127
+ end
128
+ end
129
+ end
130
+
131
+ def new_resource
132
+ self
133
+ end
134
+
135
+ private
136
+ # Create the databag with Cheffish if required
137
+ # @return [Void]
138
+ def create_databag_if_needed databag_name
139
+ _databag_name = databag_name
140
+ Cheffish.inline_resource(self, @action) do
141
+ chef_data_bag _databag_name do
142
+ action :create
143
+ end
144
+ end
145
+ end
146
+ end