chef-metal 0.10.1 → 0.10.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 75907d8e5aa3714df11b2d37090fb42babe16499
4
- data.tar.gz: 61cadff437fe83b341b74da8d41d9d0164c670c7
3
+ metadata.gz: af79447510d93b295a7d77a3223d670bdc569415
4
+ data.tar.gz: ac28faf8d8afa3026960b9997de94d9c4fc77369
5
5
  SHA512:
6
- metadata.gz: 6b46ef77e100475dd856861eb9db77202919dd28150b7606b9deddd8658c7594c2922755aaae0b2c9af71f71905f8b33b9a31dcb15e79dc9fffaba338d5981a2
7
- data.tar.gz: 4fd6d879cb7d174f5ef65b7af723f4079e017f04975f42e4c6f9346e2888485aec7b3b3b70a1ca56d74e6678ee0a3b6483c54ef05f5b3c80c57ffb4f6d76bbde
6
+ metadata.gz: 49762ba3a7f0f71677b85d6f9657cdb05174c1d389ba96825bb218f9af7dd557f35ab515dd391865caba7dc20a6a3ddfbd12b1a3c566219bab1e6cda7d8248fa
7
+ data.tar.gz: 5412dfb1f503aa30259bf37c16a7f8e46dffc98c7434375fefaf208a3745af25208052d60a4982a6a809444eaaeb82211e6490fa5a9c52cced6a7347cf70c0a0
data/CHANGELOG.md CHANGED
@@ -1,5 +1,9 @@
1
1
  # Chef Metal Changelog
2
2
 
3
+ ## 0.10.2 (5/2/2014)
4
+
5
+ - Fix crash with add_provisioner_options when provisioner_options is not yet set
6
+
3
7
  ## 0.10.1 (5/2/2014)
4
8
 
5
9
  - Fix a crash when uploading files in a machine batch
@@ -9,7 +9,11 @@ module ChefMetal
9
9
  with :machine_batch
10
10
 
11
11
  def add_provisioner_options(options, &block)
12
- with_provisioner_options(Chef::Mixin::DeepMerge.hash_only_merge(current_provisioner_options, options), &block)
12
+ if current_provisioner_options
13
+ with_provisioner_options(Chef::Mixin::DeepMerge.hash_only_merge(current_provisioner_options, options), &block)
14
+ else
15
+ with_provisioner_options(options)
16
+ end
13
17
  end
14
18
  end
15
19
  end
@@ -0,0 +1,81 @@
1
+ require 'cheffish'
2
+ require 'cheffish/cheffish_server_api'
3
+
4
+ module ChefMetal
5
+ #
6
+ # Specification for a machine. Sufficient information to find and contact it
7
+ # after it has been set up.
8
+ #
9
+ class MachineSpec
10
+ def initialize(node, chef_server)
11
+ @node = node
12
+ @chef_server = chef_server
13
+ end
14
+
15
+ def self.get(name, chef_server)
16
+ rest = Cheffish::CheffishServerAPI.new(chef_server || Cheffish.current_chef_server)
17
+ MachineSpec.new(rest.get("/nodes/#{name}"), chef_server)
18
+ end
19
+
20
+ #
21
+ # Globally unique identifier for this machine. Does not depend on the machine's
22
+ # location or existence.
23
+ #
24
+ def id
25
+ "#{@chef_server[:chef_server_url]}/nodes/#{name}"
26
+ end
27
+
28
+ #
29
+ # Name of the machine. Corresponds to the name in "machine 'name' do" ...
30
+ #
31
+ def name
32
+ @node['name']
33
+ end
34
+
35
+ #
36
+ # Location of this machine. This should be a freeform hash, with enough
37
+ # information for the provider to look it up and create a Machine object to
38
+ # access it.
39
+ #
40
+ # This MUST include a 'provider_url' attribute with the provider's URL in it.
41
+ #
42
+ # chef-metal will do its darnedest to not lose this information.
43
+ #
44
+ def location
45
+ metal_attr('location')
46
+ end
47
+
48
+ #
49
+ # Set the location for this machine.
50
+ #
51
+ def location=(value)
52
+ @node['normal']['metal'] ||= {}
53
+ @node['normal']['metal']['spec'] = value
54
+ end
55
+
56
+ #
57
+ # Save this node to the server. If you have significant information that
58
+ # could be lost, you should do this as quickly as possible. Data will be
59
+ # saved automatically for you after allocate_machine and ready_machine.
60
+ #
61
+ def save(action_handler)
62
+ # Save the node to the server.
63
+ ChefMetal.inline_resource(action_handler) do
64
+ chef_node node['name'] do
65
+ chef_server @chef_server
66
+ raw_json node
67
+ end
68
+ end
69
+ end
70
+
71
+ private
72
+
73
+ def metal_attr(attr)
74
+ if @node['normal'] && @node['normal']['metal']
75
+ @node['normal']['metal'][attr]
76
+ else
77
+ nil
78
+ end
79
+ end
80
+ end
81
+ end
@@ -0,0 +1,239 @@
1
+ module ChefMetal
2
+ #
3
+ # A Provider instance represents a place where machines can be created and found,
4
+ # and contains methods to create, delete, start, stop, and find them.
5
+ #
6
+ # For AWS, a Provider instance corresponds to a single account.
7
+ # For Vagrant, it is a directory where VM files are found.
8
+ #
9
+ # == How to Make a Provider
10
+ #
11
+ # To implement a Provider, you must implement the following methods:
12
+ #
13
+ # - initialize(driver_url) - create a new driver with the given URL
14
+ # - driver_url - a URL representing everything unique about your provider.
15
+ # But 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
18
+ # accessible (for example, accessible via SSH transport).
19
+ # - stop_machine - stop the machine.
20
+ # - delete_machine - delete the machine.
21
+ # - connect_to_machine - connect to the given machine.
22
+ #
23
+ # Optionally, you can also implement:
24
+ # - allocate_machines - allocate an entire group of machines.
25
+ # - resource_created - a hook to tell you when a resource associated with your
26
+ # provider has been created.
27
+ #
28
+ # Additionally, you must create a file named `chef_metal/provider_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
31
+ #
32
+ # All of these methods must be idempotent - if the work is already done, they
33
+ # just don't do anything.
34
+ #
35
+ class Provider
36
+ #
37
+ # Inflate a driver from node information; we don't want to force the
38
+ # driver to figure out what the driver really needs, since it varies
39
+ # from driver to driver.
40
+ #
41
+ # ## Parameters
42
+ # driver_url - the URL to inflate the driver
43
+ #
44
+ # ## Returns
45
+ # A Provider representing the given driver_url.
46
+ def initialize(driver_url)
47
+ # We do not save it ... it's up to the driver to extract whatever information
48
+ # it wants.
49
+ end
50
+
51
+ #
52
+ # A URL representing the driver and the place where machines come from.
53
+ # This will be stuffed in attributes in the node so that the node can be
54
+ # reinflated. URLs must have a unique scheme identifying the driver
55
+ # class, and enough information to identify the place where created machines
56
+ # can be found. For AWS, this is the account number; for lxc and vagrant,
57
+ # it is the directory in which VMs and containers are.
58
+ #
59
+ # For example:
60
+ # - fog:AWS:123456789012
61
+ # - vagrant:/var/vms
62
+ # - lxc:
63
+ # - docker:
64
+ #
65
+ def driver_url
66
+ raise "#{self.class} does not implement driver_url"
67
+ end
68
+
69
+ #
70
+ # Allocate a machine from the PXE/cloud/VM/container provider. This method
71
+ # does not need to wait for the machine to boot or have an IP, but it must
72
+ # store enough information in node['normal']['driver_output'] to find
73
+ # the machine later in ready_machine.
74
+ #
75
+ # If a machine is powered off or otherwise unusable, this method may start
76
+ # it, but does not need to wait until it is started. The idea is to get the
77
+ # gears moving, but the job doesn't need to be done :)
78
+ #
79
+ # ## Parameters
80
+ # action_handler - the action_handler object that is calling this method; this
81
+ # is generally a provider, but could be anything that can support the
82
+ # interface (i.e., in the case of the test kitchen metal driver for
83
+ # acquiring and destroying VMs).
84
+ #
85
+ # existing_machine - a MachineSpec representing the existing machine (if any).
86
+ #
87
+ # machine_options - a set of options representing the desired provisioning
88
+ # state of the machine (image name, bootstrap ssh credentials,
89
+ # etc.). This will NOT be stored in the node, and is
90
+ # ephemeral.
91
+ #
92
+ # ## Returns
93
+ #
94
+ # Modifies the passed-in machine_spec. Anything in here will be saved
95
+ # back to the node.
96
+ #
97
+ def allocate_machine(action_handler, machine_spec, machine_options)
98
+ raise "#{self.class} does not implement allocate_machine"
99
+ end
100
+
101
+ #
102
+ # Ready a machine, to the point where it is running and accessible via a
103
+ # transport. This will NOT allocate a machine, but may kick it if it is down.
104
+ # This method waits for the machine to be usable, returning a Machine object
105
+ # pointing at the machine, allowing useful actions like setup, converge,
106
+ # execute, file and directory.
107
+ #
108
+ # ## Parameters
109
+ # action_handler - the action_handler object that is calling this method; this
110
+ # is generally a provider, but could be anything that can support the
111
+ # interface (i.e., in the case of the test kitchen metal driver for
112
+ # acquiring and destroying VMs).
113
+ # machine_spec - MachineSpec representing this machine.
114
+ #
115
+ # ## Returns
116
+ #
117
+ # Machine object pointing at the machine, allowing useful actions like setup,
118
+ # converge, execute, file and directory.
119
+ #
120
+ def ready_machine(action_handler, machine_spec)
121
+ raise "#{self.class} does not implement ready_machine"
122
+ end
123
+
124
+ #
125
+ # Connect to a machine without allocating or readying it. This method will
126
+ # NOT make any changes to anything, or attempt to wait.
127
+ #
128
+ # ## Parameters
129
+ # machine_spec - MachineSpec representing this machine.
130
+ #
131
+ # ## Returns
132
+ #
133
+ # Machine object pointing at the machine, allowing useful actions like setup,
134
+ # converge, execute, file and directory.
135
+ #
136
+ def connect_to_machine(machine_spec)
137
+ raise "#{self.class} does not implement connect_to_machine"
138
+ end
139
+
140
+ #
141
+ # Delete the given machine (idempotent). Should destroy the machine,
142
+ # returning things to the state before allocate_machine was called.
143
+ #
144
+ def delete_machine(action_handler, machine_spec)
145
+ raise "#{self.class} does not implement delete_machine"
146
+ end
147
+
148
+ #
149
+ # Stop the given machine.
150
+ #
151
+ def stop_machine(action_handler, machine_spec)
152
+ raise "#{self.class} does not implement stop_machine"
153
+ end
154
+
155
+ #
156
+ # Optional interface methods
157
+ #
158
+
159
+ #
160
+ # Allocate a set of machines. This should have the same effect as running
161
+ # allocate_machine on all nodes.
162
+ #
163
+ # Providers do not need to implement this; the default implementation
164
+ # calls acquire_machine in parallel.
165
+ #
166
+ # ## Parameter
167
+ # action_handler - the action_handler object that is calling this method; this
168
+ # is generally a provider, but could be anything that can support the
169
+ # interface (i.e., in the case of the test kitchen metal driver for
170
+ # acquiring and destroying VMs).
171
+ # nodes - a list of nodes representing the nodes to acquire.
172
+ # parallelizer - an object with a parallelize() method that works like this:
173
+ #
174
+ # parallelizer.parallelize(nodes) do |node|
175
+ # allocate_machine(action_handler, node)
176
+ # end.to_a
177
+ # # The to_a at the end causes you to wait until the parallelization is done
178
+ #
179
+ # This object is shared among other chef-metal actions, ensuring that you do
180
+ # not go over parallelization limits set by the user. Use of the parallelizer
181
+ # to parallelizer machines is not required.
182
+ #
183
+ def allocate_machines(action_handler, machine_specs, parallelizer)
184
+ parallelizer.parallelize(machine_specs) do |machine_spec|
185
+ allocate_machine(add_prefix(machine_spec, action_handler), machine_spec)
186
+ yield machine_spec if block_given?
187
+ machine
188
+ end.to_a
189
+ end
190
+
191
+ # Acquire machines in batch, in parallel if possible.
192
+ def acquire_machines(action_handler, machine_specs, parallelizer)
193
+ parallelizer.parallelize(machine_specs) do |machine_spec|
194
+ machine = acquire_machine(add_prefix(machine_spec, action_handler), machine_spec)
195
+ yield machine_spec, machine if block_given?
196
+ machine
197
+ end.to_a
198
+ end
199
+
200
+ # Stop machines in batch, in parallel if possible.
201
+ def stop_machines(action_handler, nodes_json, parallelizer)
202
+ parallelizer.parallelize(machine_specs) do |machine_spec|
203
+ stop_machine(add_prefix(machine_spec, action_handler), machine_spec)
204
+ yield machine_spec if block_given?
205
+ end.to_a
206
+ end
207
+
208
+ # Delete machines in batch, in parallel if possible.
209
+ def delete_machines(action_handler, machine_specs, parallelizer)
210
+ parallelizer.parallelize(machine_specs) do |machine_spec|
211
+ delete_machine(add_prefix(machine_spec, action_handler), machine_spec)
212
+ yield machine_spec if block_given?
213
+ end.to_a
214
+ end
215
+
216
+ #
217
+ # Provider notification that happens at the point a machine resource is declared
218
+ # (after all properties have been set on it)
219
+ #
220
+ def resource_created(machine)
221
+ end
222
+
223
+ protected
224
+
225
+ def save_node(provider, node, chef_server)
226
+ # Save the node and create the client. TODO strip automatic attributes first so we don't race with "current state"
227
+ ChefMetal.inline_resource(provider) do
228
+ chef_node node['name'] do
229
+ chef_server chef_server
230
+ raw_json node
231
+ end
232
+ end
233
+ end
234
+
235
+ def add_prefix(node_json, action_handler)
236
+ AddPrefixActionHandler.new(action_handler, "[#{node_json['name']}] ")
237
+ end
238
+ end
239
+ end
@@ -1,3 +1,3 @@
1
1
  module ChefMetal
2
- VERSION = '0.10.1'
2
+ VERSION = '0.10.2'
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: chef-metal
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.10.1
4
+ version: 0.10.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - John Keiser
@@ -172,7 +172,9 @@ files:
172
172
  - lib/chef_metal/machine/unix_machine.rb
173
173
  - lib/chef_metal/machine/windows_machine.rb
174
174
  - lib/chef_metal/machine.rb
175
+ - lib/chef_metal/machine_spec.rb
175
176
  - lib/chef_metal/openstack_credentials.rb
177
+ - lib/chef_metal/provider.rb
176
178
  - lib/chef_metal/provider_action_handler.rb
177
179
  - lib/chef_metal/provisioner.rb
178
180
  - lib/chef_metal/recipe_dsl.rb