chef-provisioning 2.0.1 → 2.0.2

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