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,323 +1,323 @@
1
- class Chef
2
- module Provisioning
3
- #
4
- # A Driver instance represents a place where machines can be created and found,
5
- # and contains methods to create, delete, start, stop, and find them.
6
- #
7
- # For AWS, a Driver instance corresponds to a single account.
8
- # For Vagrant, it is a directory where VM files are found.
9
- #
10
- # = How to Make a Driver
11
- #
12
- # To implement a Driver, you must implement the following methods:
13
- #
14
- # * initialize(driver_url) - create a new driver with the given URL
15
- # * driver_url - a URL representing everything unique about your driver. (NOT credentials)
16
- # * allocate_machine - ask the driver to allocate a machine to you.
17
- # * ready_machine - get the machine "ready" - wait for it to be booted and accessible (for example, accessible via SSH transport).
18
- # * stop_machine - stop the machine.
19
- # * destroy_machine - delete the machine.
20
- # * connect_to_machine - connect to the given machine.
21
- #
22
- # Optionally, you can also implement:
23
- # * allocate_machines - allocate an entire group of machines.
24
- # * ready_machines - get a group of machines warm and booted.
25
- # * stop_machines - stop a group of machines.
26
- # * destroy_machines - delete a group of machines.
27
- #
28
- # Additionally, you must create a file named `chef/provisioning/driver_init/<scheme>.rb`,
29
- # where <scheme> is the name of the scheme you chose for your driver_url. This
30
- # file, when required, must call Chef::Provisioning.add_registered_driver(<scheme>, <class>).
31
- # The given <class>.from_url(url, config) will be called with a driver_url and
32
- # configuration.
33
- #
34
- # All of these methods must be idempotent - if the work is already done, they
35
- # just don't do anything.
36
- #
37
- class Driver
38
- #
39
- # Inflate a driver from a driver URL.
40
- #
41
- #
42
- # @param [String] driver_url the URL to inflate the driver
43
- # config - a configuration hash. See "config" for a list of known keys.
44
- #
45
- # == Returns
46
- # A Driver representing the given driver_url.
47
- #
48
- def initialize(driver_url, config)
49
- @driver_url = driver_url
50
- @config = config
51
- end
52
-
53
- #
54
- # Override this on specific driver classes
55
- #
56
- def self.from_url(driver_url, config)
57
- Chef::Provisioning.from_url(driver_url, config)
58
- end
59
-
60
- #
61
- # A URL representing the driver and the place where machines come from.
62
- # This will be stuffed in machine_spec.reference['driver_url'] so that the
63
- # machine can be re-inflated. URLs must have a unique scheme identifying the
64
- # driver class, and enough information to identify the place where created
65
- # machines can be found. For AWS, this is the account number; for lxc and
66
- # vagrant, it is the directory in which VMs and containers are.
67
- #
68
- # For example:
69
- # - fog:AWS:123456789012
70
- # - vagrant:/var/vms
71
- # - lxc:
72
- # - docker:
73
- #
74
- attr_reader :driver_url
75
-
76
- # A configuration hash. These keys may be present:
77
- # - :driver_options: a driver-defined object containing driver config.
78
- # - :private_keys: a hash of private keys, with a "name" and a "value". Values are either strings (paths) or PrivateKey objects.
79
- # - :private_key_paths: a list of paths to directories containing private keys.
80
- # - :write_private_key_path: the path to which we write new keys by default.
81
- # - :log_level: :debug/:info/:warn/:error/:fatal
82
- # - :chef_server_url: url to chef server
83
- # - :node_name: username to talk to chef server
84
- # - :client_key: path to key used to talk to chef server
85
- attr_reader :config
86
-
87
- #
88
- # Driver configuration. Equivalent to config[:driver_options] || {}
89
- #
90
- def driver_options
91
- config[:driver_options] || {}
92
- end
93
-
94
-
95
- # Allocate a machine from the underlying service. This method
96
- # does not need to wait for the machine to boot or have an IP, but it must
97
- # store enough information in machine_spec.reference to find the machine
98
- # later in ready_machine.
99
- #
100
- # If a machine is powered off or otherwise unusable, this method may start
101
- # it, but does not need to wait until it is started. The idea is to get the
102
- # gears moving, but the job doesn't need to be done :)
103
- #
104
- # @param [Chef::Provisioning::ActionHandler] action_handler The action_handler object that is calling this method
105
- # @param [Chef::Provisioning::ManagedEntry] machine_spec A machine specification representing this machine.
106
- # @param [Hash] machine_options A set of options representing the desired options when
107
- # constructing the machine
108
- #
109
- # @return [Chef::Provisioning::ManagedEntry] Modifies the passed-in machine_spec. Anything in here will be saved
110
- # back after allocate_machine completes.
111
- #
112
- def allocate_machine(action_handler, machine_spec, machine_options)
113
- raise "#{self.class} does not implement allocate_machine"
114
- end
115
-
116
- # Ready a machine, to the point where it is running and accessible via a
117
- # transport. This will NOT allocate a machine, but may kick it if it is down.
118
- # This method waits for the machine to be usable, returning a Machine object
119
- # pointing at the machine, allowing useful actions like setup, converge,
120
- # execute, file and directory.
121
- #
122
- #
123
- # @param [Chef::Provisioning::ActionHandler] action_handler The action_handler object that is calling this method
124
- # @param [Chef::Provisioning::ManagedEntry] machine_spec A machine specification representing this machine.
125
- # @param [Hash] machine_options A set of options representing the desired state of the machine
126
- #
127
- # @return [Machine] A machine object pointing at the machine, allowing useful actions like setup,
128
- # converge, execute, file and directory.
129
- #
130
- def ready_machine(action_handler, machine_spec, machine_options)
131
- raise "#{self.class} does not implement ready_machine"
132
- end
133
-
134
- # Connect to a machine without allocating or readying it. This method will
135
- # NOT make any changes to anything, or attempt to wait.
136
- #
137
- # @param [Chef::Provisioning::ManagedEntry] machine_spec ManagedEntry representing this machine.
138
- # @param [Hash] machine_options
139
- # @return [Machine] A machine object pointing at the machine, allowing useful actions like setup,
140
- # converge, execute, file and directory.
141
- #
142
- def connect_to_machine(machine_spec, machine_options)
143
- raise "#{self.class} does not implement connect_to_machine"
144
- end
145
-
146
-
147
- # Delete the given machine -- destroy the machine,
148
- # returning things to the state before allocate_machine was called.
149
- #
150
- # @param [Chef::Provisioning::ActionHandler] action_handler The action_handler object that is calling this method
151
- # @param [Chef::Provisioning::ManagedEntry] machine_spec A machine specification representing this machine.
152
- # @param [Hash] machine_options A set of options representing the desired state of the machine
153
- def destroy_machine(action_handler, machine_spec, machine_options)
154
- raise "#{self.class} does not implement destroy_machine"
155
- end
156
-
157
- # Stop the given machine.
158
- #
159
- # @param [Chef::Provisioning::ActionHandler] action_handler The action_handler object that is calling this method
160
- # @param [Chef::Provisioning::ManagedEntry] machine_spec A machine specification representing this machine.
161
- # @param [Hash] machine_options A set of options representing the desired state of the machine
162
- def stop_machine(action_handler, machine_spec, machine_options)
163
- raise "#{self.class} does not implement stop_machine"
164
- end
165
-
166
- # Allocate an image. Returns quickly with an ID that tracks the image.
167
- #
168
- # @param [Chef::Provisioning::ActionHandler] action_handler The action_handler object that is calling this method
169
- # @param [Chef::Provisioning::ManagedEntry] image_spec An image specification representing this image.
170
- # @param [Hash] image_options A set of options representing the desired state of the image
171
- # @param [Chef::Provisioning::ManagedEntry] machine_spec A machine specification representing this machine.
172
- # @param [Hash] machine_options A set of options representing the desired state of the machine used to create the image
173
- def allocate_image(action_handler, image_spec, image_options, machine_spec, machine_options)
174
- raise "#{self.class} does not implement create_image"
175
- end
176
-
177
- # Ready an image, waiting till the point where it is ready to be used.
178
- #
179
- # @param [Chef::Provisioning::ActionHandler] action_handler The action_handler object that is calling this method
180
- # @param [Chef::Provisioning::ManagedEntry] image_spec An image specification representing this image.
181
- # @param [Hash] image_options A set of options representing the desired state of the image
182
- def ready_image(action_handler, image_spec, image_options)
183
- raise "#{self.class} does not implement ready_image"
184
- end
185
-
186
- # Destroy an image using this service.
187
- #
188
- # @param [Chef::Provisioning::ActionHandler] action_handler The action_handler object that is calling this method
189
- # @param [Chef::Provisioning::ManagedEntry] image_spec An image specification representing this image.
190
- # @param [Hash] image_options A set of options representing the desired state of the image
191
- # @param [Hash] machine_options A set of options representing the desired state of the machine used to create the image
192
- def destroy_image(action_handler, image_spec, image_options, machine_options={})
193
- raise "#{self.class} does not implement destroy_image"
194
- end
195
-
196
- #
197
- # Optional interface methods
198
- #
199
-
200
- #
201
- # Allocate a set of machines. This should have the same effect as running
202
- # allocate_machine on all machine_specs.
203
- #
204
- # Drivers do not need to implement this; the default implementation
205
- # calls acquire_machine in parallel.
206
- #
207
- # == Parallelizing
208
- #
209
- # The parallelizer must implement #parallelize
210
- # @example Example parallelizer
211
- # parallelizer.parallelize(specs_and_options) do |machine_spec|
212
- # allocate_machine(action_handler, machine_spec)
213
- # end.to_a
214
- # # The to_a at the end causes you to wait until the parallelization is done
215
- #
216
- # This object is shared among other chef-provisioning actions, ensuring that you do
217
- # not go over parallelization limits set by the user. Use of the parallelizer
218
- # to parallelizer machines is not required.
219
- #
220
- # == Passing a block
221
- #
222
- # If you pass a block to this function, each machine will be yielded to you
223
- # as it completes, and then the function will return when all machines are
224
- # yielded.
225
- #
226
- # @example Passing a block
227
- # allocate_machines(action_handler, specs_and_options, parallelizer) do |machine_spec|
228
- # ...
229
- # end
230
- #
231
- # @param [Chef::Provisioning::ActionHandler] action_handler The action_handler object that is calling this method; this
232
- # is generally a driver, but could be anything that can support the
233
- # interface (i.e., in the case of the test kitchen provisioning driver for
234
- # acquiring and destroying VMs).
235
- # @param [Hash] specs_and_options A hash of machine_spec -> machine_options representing the
236
- # machines to allocate.
237
- # @param [Parallelizer] parallelizer an object with a parallelize() method that works like this:
238
- # @return [Array<Machine>] An array of machine objects created
239
- def allocate_machines(action_handler, specs_and_options, parallelizer)
240
- parallelizer.parallelize(specs_and_options) do |machine_spec, machine_options|
241
- allocate_machine(add_prefix(machine_spec, action_handler), machine_spec, machine_options)
242
- yield machine_spec if block_given?
243
- machine_spec
244
- end.to_a
245
- end
246
-
247
- # Ready machines in batch, in parallel if possible.
248
- def ready_machines(action_handler, specs_and_options, parallelizer)
249
- parallelizer.parallelize(specs_and_options) do |machine_spec, machine_options|
250
- machine = ready_machine(add_prefix(machine_spec, action_handler), machine_spec, machine_options)
251
- yield machine if block_given?
252
- machine
253
- end.to_a
254
- end
255
-
256
- # Stop machines in batch, in parallel if possible.
257
- def stop_machines(action_handler, specs_and_options, parallelizer)
258
- parallelizer.parallelize(specs_and_options) do |machine_spec, machine_options|
259
- stop_machine(add_prefix(machine_spec, action_handler), machine_spec, machine_options)
260
- yield machine_spec if block_given?
261
- end.to_a
262
- end
263
-
264
- # Delete machines in batch, in parallel if possible.
265
- def destroy_machines(action_handler, specs_and_options, parallelizer)
266
- parallelizer.parallelize(specs_and_options) do |machine_spec, machine_options|
267
- destroy_machine(add_prefix(machine_spec, action_handler), machine_spec, machine_options)
268
- yield machine_spec if block_given?
269
- end.to_a
270
- end
271
-
272
- # Allocate a load balancer
273
- # @param [Chef::Provisioning::ActionHandler] action_handler The action handler
274
- # @param [Chef::Provisioning::ManagedEntry] lb_spec Frozen LB specification
275
- # @param [Hash] lb_options A hash of options to pass the LB
276
- # @param [Array[ChefMetal::MachineSpec]] machine_specs An array of machine specs
277
- # the load balancer should have. `nil` indicates "leave the set of machines
278
- # alone," or for new LBs, it means "no machines."
279
- def allocate_load_balancer(action_handler, lb_spec, lb_options, machine_specs)
280
- end
281
-
282
- # Make the load balancer ready
283
- # @param [Chef::Provisioning::ActionHandler] action_handler The action handler
284
- # @param [Chef::Provisioning::ManagedEntry] lb_spec Frozen LB specification
285
- # @param [Hash] lb_options A hash of options to pass the LB
286
- # @param [Array[ChefMetal::MachineSpec]] machine_specs An array of machine specs
287
- # the load balancer should have. `nil` indicates "leave the set of machines
288
- # alone," or for new LBs, it means "no machines."
289
- def ready_load_balancer(action_handler, lb_spec, lb_options, machine_specs)
290
- end
291
-
292
- # Destroy the load balancer
293
- # @param [ChefMetal::ActionHandler] action_handler The action handler
294
- # @param [ChefMetal::LoadBalancerSpec] lb_spec Frozen LB specification
295
- # @param [Hash] lb_options A hash of options to pass the LB
296
- def destroy_load_balancer(action_handler, lb_spec, lb_options)
297
- end
298
-
299
- protected
300
-
301
- def add_prefix(machine_spec, action_handler)
302
- AddPrefixActionHandler.new(action_handler, "[#{machine_spec.name}] ")
303
- end
304
-
305
- def get_private_key(name)
306
- Cheffish.get_private_key(name, config)
307
- end
308
- end
309
- end
310
- end
311
-
312
- # In chef-provisioning we don't perform resource cloning
313
- # This fixes resource cloning when the ResourceBuilder is present
314
- require 'chef/resource_builder' unless defined?(Chef::ResourceBuilder)
315
- class Chef
316
- class ResourceBuilder
317
- if defined?(:prior_resource)
318
- def prior_resource
319
- nil
320
- end
321
- end
322
- end
323
- end
1
+ class Chef
2
+ module Provisioning
3
+ #
4
+ # A Driver instance represents a place where machines can be created and found,
5
+ # and contains methods to create, delete, start, stop, and find them.
6
+ #
7
+ # For AWS, a Driver instance corresponds to a single account.
8
+ # For Vagrant, it is a directory where VM files are found.
9
+ #
10
+ # = How to Make a Driver
11
+ #
12
+ # To implement a Driver, you must implement the following methods:
13
+ #
14
+ # * initialize(driver_url) - create a new driver with the given URL
15
+ # * driver_url - a URL representing everything unique about your driver. (NOT credentials)
16
+ # * allocate_machine - ask the driver to allocate a machine to you.
17
+ # * ready_machine - get the machine "ready" - wait for it to be booted and accessible (for example, accessible via SSH transport).
18
+ # * stop_machine - stop the machine.
19
+ # * destroy_machine - delete the machine.
20
+ # * connect_to_machine - connect to the given machine.
21
+ #
22
+ # Optionally, you can also implement:
23
+ # * allocate_machines - allocate an entire group of machines.
24
+ # * ready_machines - get a group of machines warm and booted.
25
+ # * stop_machines - stop a group of machines.
26
+ # * destroy_machines - delete a group of machines.
27
+ #
28
+ # Additionally, you must create a file named `chef/provisioning/driver_init/<scheme>.rb`,
29
+ # where <scheme> is the name of the scheme you chose for your driver_url. This
30
+ # file, when required, must call Chef::Provisioning.add_registered_driver(<scheme>, <class>).
31
+ # The given <class>.from_url(url, config) will be called with a driver_url and
32
+ # configuration.
33
+ #
34
+ # All of these methods must be idempotent - if the work is already done, they
35
+ # just don't do anything.
36
+ #
37
+ class Driver
38
+ #
39
+ # Inflate a driver from a driver URL.
40
+ #
41
+ #
42
+ # @param [String] driver_url the URL to inflate the driver
43
+ # config - a configuration hash. See "config" for a list of known keys.
44
+ #
45
+ # == Returns
46
+ # A Driver representing the given driver_url.
47
+ #
48
+ def initialize(driver_url, config)
49
+ @driver_url = driver_url
50
+ @config = config
51
+ end
52
+
53
+ #
54
+ # Override this on specific driver classes
55
+ #
56
+ def self.from_url(driver_url, config)
57
+ Chef::Provisioning.from_url(driver_url, config)
58
+ end
59
+
60
+ #
61
+ # A URL representing the driver and the place where machines come from.
62
+ # This will be stuffed in machine_spec.reference['driver_url'] so that the
63
+ # machine can be re-inflated. URLs must have a unique scheme identifying the
64
+ # driver class, and enough information to identify the place where created
65
+ # machines can be found. For AWS, this is the account number; for lxc and
66
+ # vagrant, it is the directory in which VMs and containers are.
67
+ #
68
+ # For example:
69
+ # - fog:AWS:123456789012
70
+ # - vagrant:/var/vms
71
+ # - lxc:
72
+ # - docker:
73
+ #
74
+ attr_reader :driver_url
75
+
76
+ # A configuration hash. These keys may be present:
77
+ # - :driver_options: a driver-defined object containing driver config.
78
+ # - :private_keys: a hash of private keys, with a "name" and a "value". Values are either strings (paths) or PrivateKey objects.
79
+ # - :private_key_paths: a list of paths to directories containing private keys.
80
+ # - :write_private_key_path: the path to which we write new keys by default.
81
+ # - :log_level: :debug/:info/:warn/:error/:fatal
82
+ # - :chef_server_url: url to chef server
83
+ # - :node_name: username to talk to chef server
84
+ # - :client_key: path to key used to talk to chef server
85
+ attr_reader :config
86
+
87
+ #
88
+ # Driver configuration. Equivalent to config[:driver_options] || {}
89
+ #
90
+ def driver_options
91
+ config[:driver_options] || {}
92
+ end
93
+
94
+
95
+ # Allocate a machine from the underlying service. This method
96
+ # does not need to wait for the machine to boot or have an IP, but it must
97
+ # store enough information in machine_spec.reference to find the machine
98
+ # later in ready_machine.
99
+ #
100
+ # If a machine is powered off or otherwise unusable, this method may start
101
+ # it, but does not need to wait until it is started. The idea is to get the
102
+ # gears moving, but the job doesn't need to be done :)
103
+ #
104
+ # @param [Chef::Provisioning::ActionHandler] action_handler The action_handler object that is calling this method
105
+ # @param [Chef::Provisioning::ManagedEntry] machine_spec A machine specification representing this machine.
106
+ # @param [Hash] machine_options A set of options representing the desired options when
107
+ # constructing the machine
108
+ #
109
+ # @return [Chef::Provisioning::ManagedEntry] Modifies the passed-in machine_spec. Anything in here will be saved
110
+ # back after allocate_machine completes.
111
+ #
112
+ def allocate_machine(action_handler, machine_spec, machine_options)
113
+ raise "#{self.class} does not implement allocate_machine"
114
+ end
115
+
116
+ # Ready a machine, to the point where it is running and accessible via a
117
+ # transport. This will NOT allocate a machine, but may kick it if it is down.
118
+ # This method waits for the machine to be usable, returning a Machine object
119
+ # pointing at the machine, allowing useful actions like setup, converge,
120
+ # execute, file and directory.
121
+ #
122
+ #
123
+ # @param [Chef::Provisioning::ActionHandler] action_handler The action_handler object that is calling this method
124
+ # @param [Chef::Provisioning::ManagedEntry] machine_spec A machine specification representing this machine.
125
+ # @param [Hash] machine_options A set of options representing the desired state of the machine
126
+ #
127
+ # @return [Machine] A machine object pointing at the machine, allowing useful actions like setup,
128
+ # converge, execute, file and directory.
129
+ #
130
+ def ready_machine(action_handler, machine_spec, machine_options)
131
+ raise "#{self.class} does not implement ready_machine"
132
+ end
133
+
134
+ # Connect to a machine without allocating or readying it. This method will
135
+ # NOT make any changes to anything, or attempt to wait.
136
+ #
137
+ # @param [Chef::Provisioning::ManagedEntry] machine_spec ManagedEntry representing this machine.
138
+ # @param [Hash] machine_options
139
+ # @return [Machine] A machine object pointing at the machine, allowing useful actions like setup,
140
+ # converge, execute, file and directory.
141
+ #
142
+ def connect_to_machine(machine_spec, machine_options)
143
+ raise "#{self.class} does not implement connect_to_machine"
144
+ end
145
+
146
+
147
+ # Delete the given machine -- destroy the machine,
148
+ # returning things to the state before allocate_machine was called.
149
+ #
150
+ # @param [Chef::Provisioning::ActionHandler] action_handler The action_handler object that is calling this method
151
+ # @param [Chef::Provisioning::ManagedEntry] machine_spec A machine specification representing this machine.
152
+ # @param [Hash] machine_options A set of options representing the desired state of the machine
153
+ def destroy_machine(action_handler, machine_spec, machine_options)
154
+ raise "#{self.class} does not implement destroy_machine"
155
+ end
156
+
157
+ # Stop the given machine.
158
+ #
159
+ # @param [Chef::Provisioning::ActionHandler] action_handler The action_handler object that is calling this method
160
+ # @param [Chef::Provisioning::ManagedEntry] machine_spec A machine specification representing this machine.
161
+ # @param [Hash] machine_options A set of options representing the desired state of the machine
162
+ def stop_machine(action_handler, machine_spec, machine_options)
163
+ raise "#{self.class} does not implement stop_machine"
164
+ end
165
+
166
+ # Allocate an image. Returns quickly with an ID that tracks the image.
167
+ #
168
+ # @param [Chef::Provisioning::ActionHandler] action_handler The action_handler object that is calling this method
169
+ # @param [Chef::Provisioning::ManagedEntry] image_spec An image specification representing this image.
170
+ # @param [Hash] image_options A set of options representing the desired state of the image
171
+ # @param [Chef::Provisioning::ManagedEntry] machine_spec A machine specification representing this machine.
172
+ # @param [Hash] machine_options A set of options representing the desired state of the machine used to create the image
173
+ def allocate_image(action_handler, image_spec, image_options, machine_spec, machine_options)
174
+ raise "#{self.class} does not implement create_image"
175
+ end
176
+
177
+ # Ready an image, waiting till the point where it is ready to be used.
178
+ #
179
+ # @param [Chef::Provisioning::ActionHandler] action_handler The action_handler object that is calling this method
180
+ # @param [Chef::Provisioning::ManagedEntry] image_spec An image specification representing this image.
181
+ # @param [Hash] image_options A set of options representing the desired state of the image
182
+ def ready_image(action_handler, image_spec, image_options)
183
+ raise "#{self.class} does not implement ready_image"
184
+ end
185
+
186
+ # Destroy an image using this service.
187
+ #
188
+ # @param [Chef::Provisioning::ActionHandler] action_handler The action_handler object that is calling this method
189
+ # @param [Chef::Provisioning::ManagedEntry] image_spec An image specification representing this image.
190
+ # @param [Hash] image_options A set of options representing the desired state of the image
191
+ # @param [Hash] machine_options A set of options representing the desired state of the machine used to create the image
192
+ def destroy_image(action_handler, image_spec, image_options, machine_options={})
193
+ raise "#{self.class} does not implement destroy_image"
194
+ end
195
+
196
+ #
197
+ # Optional interface methods
198
+ #
199
+
200
+ #
201
+ # Allocate a set of machines. This should have the same effect as running
202
+ # allocate_machine on all machine_specs.
203
+ #
204
+ # Drivers do not need to implement this; the default implementation
205
+ # calls acquire_machine in parallel.
206
+ #
207
+ # == Parallelizing
208
+ #
209
+ # The parallelizer must implement #parallelize
210
+ # @example Example parallelizer
211
+ # parallelizer.parallelize(specs_and_options) do |machine_spec|
212
+ # allocate_machine(action_handler, machine_spec)
213
+ # end.to_a
214
+ # # The to_a at the end causes you to wait until the parallelization is done
215
+ #
216
+ # This object is shared among other chef-provisioning actions, ensuring that you do
217
+ # not go over parallelization limits set by the user. Use of the parallelizer
218
+ # to parallelizer machines is not required.
219
+ #
220
+ # == Passing a block
221
+ #
222
+ # If you pass a block to this function, each machine will be yielded to you
223
+ # as it completes, and then the function will return when all machines are
224
+ # yielded.
225
+ #
226
+ # @example Passing a block
227
+ # allocate_machines(action_handler, specs_and_options, parallelizer) do |machine_spec|
228
+ # ...
229
+ # end
230
+ #
231
+ # @param [Chef::Provisioning::ActionHandler] action_handler The action_handler object that is calling this method; this
232
+ # is generally a driver, but could be anything that can support the
233
+ # interface (i.e., in the case of the test kitchen provisioning driver for
234
+ # acquiring and destroying VMs).
235
+ # @param [Hash] specs_and_options A hash of machine_spec -> machine_options representing the
236
+ # machines to allocate.
237
+ # @param [Parallelizer] parallelizer an object with a parallelize() method that works like this:
238
+ # @return [Array<Machine>] An array of machine objects created
239
+ def allocate_machines(action_handler, specs_and_options, parallelizer)
240
+ parallelizer.parallelize(specs_and_options) do |machine_spec, machine_options|
241
+ allocate_machine(add_prefix(machine_spec, action_handler), machine_spec, machine_options)
242
+ yield machine_spec if block_given?
243
+ machine_spec
244
+ end.to_a
245
+ end
246
+
247
+ # Ready machines in batch, in parallel if possible.
248
+ def ready_machines(action_handler, specs_and_options, parallelizer)
249
+ parallelizer.parallelize(specs_and_options) do |machine_spec, machine_options|
250
+ machine = ready_machine(add_prefix(machine_spec, action_handler), machine_spec, machine_options)
251
+ yield machine if block_given?
252
+ machine
253
+ end.to_a
254
+ end
255
+
256
+ # Stop machines in batch, in parallel if possible.
257
+ def stop_machines(action_handler, specs_and_options, parallelizer)
258
+ parallelizer.parallelize(specs_and_options) do |machine_spec, machine_options|
259
+ stop_machine(add_prefix(machine_spec, action_handler), machine_spec, machine_options)
260
+ yield machine_spec if block_given?
261
+ end.to_a
262
+ end
263
+
264
+ # Delete machines in batch, in parallel if possible.
265
+ def destroy_machines(action_handler, specs_and_options, parallelizer)
266
+ parallelizer.parallelize(specs_and_options) do |machine_spec, machine_options|
267
+ destroy_machine(add_prefix(machine_spec, action_handler), machine_spec, machine_options)
268
+ yield machine_spec if block_given?
269
+ end.to_a
270
+ end
271
+
272
+ # Allocate a load balancer
273
+ # @param [Chef::Provisioning::ActionHandler] action_handler The action handler
274
+ # @param [Chef::Provisioning::ManagedEntry] lb_spec Frozen LB specification
275
+ # @param [Hash] lb_options A hash of options to pass the LB
276
+ # @param [Array[ChefMetal::MachineSpec]] machine_specs An array of machine specs
277
+ # the load balancer should have. `nil` indicates "leave the set of machines
278
+ # alone," or for new LBs, it means "no machines."
279
+ def allocate_load_balancer(action_handler, lb_spec, lb_options, machine_specs)
280
+ end
281
+
282
+ # Make the load balancer ready
283
+ # @param [Chef::Provisioning::ActionHandler] action_handler The action handler
284
+ # @param [Chef::Provisioning::ManagedEntry] lb_spec Frozen LB specification
285
+ # @param [Hash] lb_options A hash of options to pass the LB
286
+ # @param [Array[ChefMetal::MachineSpec]] machine_specs An array of machine specs
287
+ # the load balancer should have. `nil` indicates "leave the set of machines
288
+ # alone," or for new LBs, it means "no machines."
289
+ def ready_load_balancer(action_handler, lb_spec, lb_options, machine_specs)
290
+ end
291
+
292
+ # Destroy the load balancer
293
+ # @param [ChefMetal::ActionHandler] action_handler The action handler
294
+ # @param [ChefMetal::LoadBalancerSpec] lb_spec Frozen LB specification
295
+ # @param [Hash] lb_options A hash of options to pass the LB
296
+ def destroy_load_balancer(action_handler, lb_spec, lb_options)
297
+ end
298
+
299
+ protected
300
+
301
+ def add_prefix(machine_spec, action_handler)
302
+ AddPrefixActionHandler.new(action_handler, "[#{machine_spec.name}] ")
303
+ end
304
+
305
+ def get_private_key(name)
306
+ Cheffish.get_private_key(name, config)
307
+ end
308
+ end
309
+ end
310
+ end
311
+
312
+ # In chef-provisioning we don't perform resource cloning
313
+ # This fixes resource cloning when the ResourceBuilder is present
314
+ require 'chef/resource_builder' unless defined?(Chef::ResourceBuilder)
315
+ class Chef
316
+ class ResourceBuilder
317
+ if defined?(:prior_resource)
318
+ def prior_resource
319
+ nil
320
+ end
321
+ end
322
+ end
323
+ end