ridley 0.10.2 → 0.11.0.rc1
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.
- data/README.md +147 -216
- data/lib/ridley.rb +2 -0
- data/lib/ridley/bootstrap_bindings/unix_template_binding.rb +21 -25
- data/lib/ridley/bootstrap_bindings/windows_template_binding.rb +29 -34
- data/lib/ridley/bootstrapper.rb +2 -2
- data/lib/ridley/bootstrapper/context.rb +5 -5
- data/lib/ridley/chef.rb +0 -1
- data/lib/ridley/chef/cookbook.rb +0 -9
- data/lib/ridley/chef_object.rb +128 -0
- data/lib/ridley/chef_objects.rb +3 -0
- data/lib/ridley/chef_objects/client_object.rb +55 -0
- data/lib/ridley/chef_objects/cookbook_object.rb +190 -0
- data/lib/ridley/chef_objects/data_bag_item_obect.rb +104 -0
- data/lib/ridley/chef_objects/data_bag_object.rb +31 -0
- data/lib/ridley/chef_objects/environment_object.rb +59 -0
- data/lib/ridley/chef_objects/node_object.rb +161 -0
- data/lib/ridley/chef_objects/role_object.rb +62 -0
- data/lib/ridley/chef_objects/sandbox_object.rb +58 -0
- data/lib/ridley/client.rb +76 -45
- data/lib/ridley/connection.rb +1 -1
- data/lib/ridley/errors.rb +8 -1
- data/lib/ridley/host_connector.rb +26 -6
- data/lib/ridley/host_connector/ssh.rb +3 -3
- data/lib/ridley/host_connector/ssh/worker.rb +7 -9
- data/lib/ridley/host_connector/winrm/worker.rb +4 -5
- data/lib/ridley/mixin/bootstrap_binding.rb +1 -12
- data/lib/ridley/resource.rb +51 -171
- data/lib/ridley/resources/client_resource.rb +18 -68
- data/lib/ridley/resources/cookbook_resource.rb +181 -381
- data/lib/ridley/resources/data_bag_item_resource.rb +55 -161
- data/lib/ridley/resources/data_bag_resource.rb +20 -61
- data/lib/ridley/resources/environment_resource.rb +9 -64
- data/lib/ridley/resources/node_resource.rb +135 -311
- data/lib/ridley/resources/role_resource.rb +1 -57
- data/lib/ridley/resources/sandbox_resource.rb +80 -65
- data/lib/ridley/resources/search_resource.rb +99 -0
- data/lib/ridley/sandbox_uploader.rb +12 -52
- data/lib/ridley/version.rb +1 -1
- data/spec/acceptance/bootstrapping_spec.rb +1 -1
- data/spec/acceptance/client_resource_spec.rb +15 -37
- data/spec/acceptance/data_bag_item_resource_spec.rb +8 -14
- data/spec/acceptance/data_bag_resource_spec.rb +1 -1
- data/spec/acceptance/environment_resource_spec.rb +13 -22
- data/spec/acceptance/node_resource_spec.rb +10 -29
- data/spec/acceptance/role_resource_spec.rb +14 -13
- data/spec/acceptance/sandbox_resource_spec.rb +2 -2
- data/spec/support/shared_examples/ridley_resource.rb +2 -23
- data/spec/unit/ridley/bootstrap_bindings/unix_template_binding_spec.rb +3 -4
- data/spec/unit/ridley/bootstrap_bindings/windows_template_binding_spec.rb +3 -5
- data/spec/unit/ridley/bootstrapper/context_spec.rb +2 -3
- data/spec/unit/ridley/bootstrapper_spec.rb +1 -1
- data/spec/unit/ridley/chef_object_spec.rb +240 -0
- data/spec/unit/ridley/chef_objects/client_object_spec.rb +11 -0
- data/spec/unit/ridley/chef_objects/cookbook_object_spec.rb +93 -0
- data/spec/unit/ridley/chef_objects/data_bag_item_object_spec.rb +74 -0
- data/spec/unit/ridley/chef_objects/data_bag_object_spec.rb +9 -0
- data/spec/unit/ridley/chef_objects/environment_object_spec.rb +57 -0
- data/spec/unit/ridley/chef_objects/node_object_spec.rb +252 -0
- data/spec/unit/ridley/chef_objects/role_object_spec.rb +57 -0
- data/spec/unit/ridley/chef_objects/sandbox_object_spec.rb +66 -0
- data/spec/unit/ridley/client_spec.rb +51 -51
- data/spec/unit/ridley/host_connector/ssh/worker_spec.rb +4 -4
- data/spec/unit/ridley/host_connector/ssh_spec.rb +26 -24
- data/spec/unit/ridley/host_connector/winrm/worker_spec.rb +3 -4
- data/spec/unit/ridley/host_connector/winrm_spec.rb +4 -4
- data/spec/unit/ridley/host_connector_spec.rb +40 -3
- data/spec/unit/ridley/mixin/bootstrap_binding_spec.rb +1 -1
- data/spec/unit/ridley/resource_spec.rb +81 -109
- data/spec/unit/ridley/resources/client_resource_spec.rb +18 -33
- data/spec/unit/ridley/resources/cookbook_resource_spec.rb +56 -230
- data/spec/unit/ridley/resources/data_bag_item_resource_spec.rb +2 -57
- data/spec/unit/ridley/resources/data_bag_resource_spec.rb +12 -7
- data/spec/unit/ridley/resources/environment_resource_spec.rb +10 -118
- data/spec/unit/ridley/resources/node_resource_spec.rb +83 -394
- data/spec/unit/ridley/resources/role_resource_spec.rb +2 -56
- data/spec/unit/ridley/resources/sandbox_resource_spec.rb +139 -136
- data/spec/unit/ridley/resources/search_resource_spec.rb +234 -0
- data/spec/unit/ridley/sandbox_uploader_spec.rb +13 -58
- metadata +36 -17
- data/lib/ridley/chef/chefignore.rb +0 -76
- data/lib/ridley/resources/encrypted_data_bag_item_resource.rb +0 -55
- data/lib/ridley/resources/search.rb +0 -101
- data/spec/fixtures/chefignore +0 -8
- data/spec/unit/ridley/chef/chefignore_spec.rb +0 -40
- data/spec/unit/ridley/resources/search_spec.rb +0 -221
@@ -1,422 +1,222 @@
|
|
1
1
|
module Ridley
|
2
2
|
# @author Jamie Winsor <reset@riotgames.com>
|
3
3
|
class CookbookResource < Ridley::Resource
|
4
|
-
|
5
|
-
|
6
|
-
#
|
7
|
-
# @example return value
|
8
|
-
# {
|
9
|
-
# "ant" => [
|
10
|
-
# "0.10.1"
|
11
|
-
# ],
|
12
|
-
# "apache2" => [
|
13
|
-
# "1.4.0"
|
14
|
-
# ]
|
15
|
-
# }
|
16
|
-
#
|
17
|
-
# @param [Ridley::Client] client
|
18
|
-
#
|
19
|
-
# @return [Hash]
|
20
|
-
# a hash containing keys which represent cookbook names and values which contain
|
21
|
-
# an array of strings representing the available versions
|
22
|
-
def all(client)
|
23
|
-
response = client.connection.get(self.resource_path).body
|
24
|
-
|
25
|
-
{}.tap do |cookbooks|
|
26
|
-
response.each do |name, details|
|
27
|
-
cookbooks[name] = details["versions"].collect { |version| version["version"] }
|
28
|
-
end
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
# Delete a cookbook of the given name and version on the remote Chef server
|
33
|
-
#
|
34
|
-
# @param [Ridley::Client] client
|
35
|
-
# @param [String] name
|
36
|
-
# @param [String] version
|
37
|
-
#
|
38
|
-
# @option options [Boolean] purge (false)
|
39
|
-
#
|
40
|
-
# @return [Boolean]
|
41
|
-
def delete(client, name, version, options = {})
|
42
|
-
options = options.reverse_merge(purge: false)
|
43
|
-
url = "#{self.resource_path}/#{name}/#{version}"
|
44
|
-
url += "?purge=true" if options[:purge]
|
45
|
-
|
46
|
-
client.connection.delete(url).body
|
47
|
-
true
|
48
|
-
rescue Errors::HTTPNotFound
|
49
|
-
true
|
50
|
-
end
|
51
|
-
|
52
|
-
# Delete all of the versions of a given cookbook on the remote Chef server
|
53
|
-
#
|
54
|
-
# @param [Ridley::Client] client
|
55
|
-
# @param [String] name
|
56
|
-
# name of the cookbook to delete
|
57
|
-
#
|
58
|
-
# @option options [Boolean] purge (false)
|
59
|
-
def delete_all(client, name, options = {})
|
60
|
-
versions(client, name).each do |version|
|
61
|
-
delete(client, name, version, options)
|
62
|
-
end
|
63
|
-
end
|
64
|
-
|
65
|
-
# Download the entire cookbook
|
66
|
-
#
|
67
|
-
# @param [Ridley::Client] client
|
68
|
-
# @param [String] name
|
69
|
-
# @param [String] version
|
70
|
-
# @param [String] destination (Dir.mktmpdir)
|
71
|
-
# the place to download the cookbook too. If no value is provided the cookbook
|
72
|
-
# will be downloaded to a temporary location
|
73
|
-
#
|
74
|
-
# @return [String]
|
75
|
-
# the path to the directory the cookbook was downloaded to
|
76
|
-
def download(client, name, version, destination = Dir.mktmpdir)
|
77
|
-
cookbook = find(client, name, version)
|
78
|
-
|
79
|
-
unless cookbook.nil?
|
80
|
-
cookbook.download(destination)
|
81
|
-
end
|
82
|
-
end
|
83
|
-
|
84
|
-
# @param [Ridley::Client] client
|
85
|
-
# @param [String, #chef_id] object
|
86
|
-
# @param [String] version
|
87
|
-
#
|
88
|
-
# @return [nil, CookbookResource]
|
89
|
-
def find(client, object, version)
|
90
|
-
find!(client, object, version)
|
91
|
-
rescue Errors::HTTPNotFound
|
92
|
-
nil
|
93
|
-
end
|
94
|
-
|
95
|
-
# @param [Ridley::Client] client
|
96
|
-
# @param [String, #chef_id] object
|
97
|
-
# @param [String] version
|
98
|
-
#
|
99
|
-
# @raise [Errors::HTTPNotFound]
|
100
|
-
# if a resource with the given chef_id is not found
|
101
|
-
#
|
102
|
-
# @return [CookbookResource]
|
103
|
-
def find!(client, object, version)
|
104
|
-
chef_id = object.respond_to?(:chef_id) ? object.chef_id : object
|
105
|
-
new(client, client.connection.get("#{self.resource_path}/#{chef_id}/#{version}").body)
|
106
|
-
end
|
107
|
-
|
108
|
-
# Return the latest version of the given cookbook found on the remote Chef server
|
109
|
-
#
|
110
|
-
# @param [Ridley::Client] client
|
111
|
-
# @param [String] name
|
112
|
-
#
|
113
|
-
# @return [String, nil]
|
114
|
-
def latest_version(client, name)
|
115
|
-
ver = versions(client, name).collect do |version|
|
116
|
-
Solve::Version.new(version)
|
117
|
-
end.sort.last
|
118
|
-
|
119
|
-
ver.nil? ? nil : ver.to_s
|
120
|
-
end
|
121
|
-
|
122
|
-
# Return the version of the given cookbook which best stasifies the given constraint
|
123
|
-
#
|
124
|
-
# @param [Ridley::Client] client
|
125
|
-
# @param [String] name
|
126
|
-
# name of the cookbook
|
127
|
-
# @param [String, Solve::Constraint] constraint
|
128
|
-
# constraint to solve for
|
129
|
-
#
|
130
|
-
# @return [CookbookResource, nil]
|
131
|
-
# returns the cookbook resource for the best solution or nil if no solution exists
|
132
|
-
def satisfy(client, name, constraint)
|
133
|
-
version = Solve::Solver.satisfy_best(constraint, versions(client, name)).to_s
|
134
|
-
find(client, name, version)
|
135
|
-
rescue Solve::Errors::NoSolutionError
|
136
|
-
nil
|
137
|
-
end
|
138
|
-
|
139
|
-
# Update or create a new Cookbook Version of the given name, version with the
|
140
|
-
# given manifest of files and checksums.
|
141
|
-
#
|
142
|
-
# @param [Ridley::Client] client
|
143
|
-
# @param [Ridley::Chef::Cookbook] cookbook
|
144
|
-
# the cookbook to save
|
145
|
-
#
|
146
|
-
# @option options [Boolean] :force
|
147
|
-
# Upload the Cookbook even if the version already exists and is frozen on
|
148
|
-
# the target Chef Server
|
149
|
-
# @option options [Boolean] :freeze
|
150
|
-
# Freeze the uploaded Cookbook on the Chef Server so that it cannot be
|
151
|
-
# overwritten
|
152
|
-
#
|
153
|
-
# @raise [Ridley::Errors::FrozenCookbook]
|
154
|
-
# if a cookbook of the same name and version already exists on the remote Chef server
|
155
|
-
# and is frozen. If the :force option is provided the given cookbook will be saved
|
156
|
-
# regardless.
|
157
|
-
#
|
158
|
-
# @return [Hash]
|
159
|
-
def update(client, cookbook, options = {})
|
160
|
-
options.reverse_merge(force: false, freeze: false)
|
161
|
-
|
162
|
-
cookbook.frozen = options[:freeze]
|
163
|
-
|
164
|
-
url = "cookbooks/#{cookbook.cookbook_name}/#{cookbook.version}"
|
165
|
-
url << "?force=true" if options[:force]
|
166
|
-
|
167
|
-
client.connection.put(url, cookbook.to_json)
|
168
|
-
rescue Ridley::Errors::HTTPConflict => ex
|
169
|
-
raise Ridley::Errors::FrozenCookbook, ex
|
170
|
-
end
|
171
|
-
alias_method :create, :update
|
172
|
-
|
173
|
-
# Uploads a cookbook to the remote Chef server from the contents of a filepath
|
174
|
-
#
|
175
|
-
# @param [Ridley::Client] client
|
176
|
-
# @param [String] path
|
177
|
-
# path to a cookbook on local disk
|
178
|
-
#
|
179
|
-
# @option options [String] :name
|
180
|
-
# automatically populated by the metadata of the cookbook at the given path, but
|
181
|
-
# in the event that the metadata does not contain a name it can be specified with
|
182
|
-
# this option
|
183
|
-
# @option options [Boolean] :force (false)
|
184
|
-
# Upload the Cookbook even if the version already exists and is frozen on
|
185
|
-
# the target Chef Server
|
186
|
-
# @option options [Boolean] :freeze (false)
|
187
|
-
# Freeze the uploaded Cookbook on the Chef Server so that it cannot be
|
188
|
-
# overwritten
|
189
|
-
# @option options [Boolean] :validate (true)
|
190
|
-
# Validate the contents of the cookbook before uploading
|
191
|
-
#
|
192
|
-
# @return [Hash]
|
193
|
-
def upload(client, path, options = {})
|
194
|
-
options = options.reverse_merge(validate: true, force: false, freeze: false)
|
195
|
-
cookbook = Ridley::Chef::Cookbook.from_path(path, options.slice(:name))
|
196
|
-
|
197
|
-
unless (existing = find(client, cookbook.cookbook_name, cookbook.version)).nil?
|
198
|
-
if existing.frozen? && options[:force] == false
|
199
|
-
msg = "The cookbook #{cookbook.cookbook_name} (#{cookbook.version}) already exists and is"
|
200
|
-
msg << " frozen on the Chef server. Use the 'force' option to override."
|
201
|
-
raise Ridley::Errors::FrozenCookbook, msg
|
202
|
-
end
|
203
|
-
end
|
204
|
-
|
205
|
-
if options[:validate]
|
206
|
-
cookbook.validate
|
207
|
-
end
|
208
|
-
|
209
|
-
checksums = cookbook.checksums.dup
|
210
|
-
sandbox = client.sandbox.create(checksums.keys)
|
211
|
-
|
212
|
-
sandbox.upload(checksums)
|
213
|
-
sandbox.commit
|
214
|
-
update(client, cookbook, options.slice(:force, :freeze))
|
215
|
-
end
|
4
|
+
set_resource_path "cookbooks"
|
5
|
+
represented_by Ridley::CookbookObject
|
216
6
|
|
217
|
-
|
218
|
-
|
219
|
-
# @
|
220
|
-
|
221
|
-
#
|
222
|
-
# @example
|
223
|
-
# versions(client, "nginx") => [ "1.0.0", "1.2.0" ]
|
224
|
-
#
|
225
|
-
# @return [Array<String>]
|
226
|
-
def versions(client, name)
|
227
|
-
response = client.connection.get("#{self.resource_path}/#{name}").body
|
7
|
+
def initialize(connection_registry, client_name, client_key, options = {})
|
8
|
+
super(connection_registry)
|
9
|
+
# @sandbox_resource = SandboxResource.new_link(connection_registry, client_name, client_key, options)
|
10
|
+
end
|
228
11
|
|
229
|
-
|
230
|
-
|
12
|
+
# List all of the cookbooks and their versions present on the remote
|
13
|
+
#
|
14
|
+
# @example return value
|
15
|
+
# {
|
16
|
+
# "ant" => [
|
17
|
+
# "0.10.1"
|
18
|
+
# ],
|
19
|
+
# "apache2" => [
|
20
|
+
# "1.4.0"
|
21
|
+
# ]
|
22
|
+
# }
|
23
|
+
#
|
24
|
+
# @return [Hash]
|
25
|
+
# a hash containing keys which represent cookbook names and values which contain
|
26
|
+
# an array of strings representing the available versions
|
27
|
+
def all
|
28
|
+
response = connection.get(self.class.resource_path).body
|
29
|
+
|
30
|
+
{}.tap do |cookbooks|
|
31
|
+
response.each do |name, details|
|
32
|
+
cookbooks[name] = details["versions"].collect { |version| version["version"] }
|
231
33
|
end
|
232
34
|
end
|
233
35
|
end
|
234
36
|
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
:
|
245
|
-
|
246
|
-
:
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
attribute :name,
|
255
|
-
required: true
|
256
|
-
|
257
|
-
attribute :attributes,
|
258
|
-
type: Array,
|
259
|
-
default: Array.new
|
260
|
-
|
261
|
-
attribute :cookbook_name,
|
262
|
-
type: String
|
263
|
-
|
264
|
-
attribute :definitions,
|
265
|
-
type: Array,
|
266
|
-
default: Array.new
|
267
|
-
|
268
|
-
attribute :files,
|
269
|
-
type: Array,
|
270
|
-
default: Array.new
|
271
|
-
|
272
|
-
attribute :libraries,
|
273
|
-
type: Array,
|
274
|
-
default: Array.new
|
275
|
-
|
276
|
-
attribute :metadata,
|
277
|
-
type: Hashie::Mash
|
278
|
-
|
279
|
-
attribute :providers,
|
280
|
-
type: Array,
|
281
|
-
default: Array.new
|
282
|
-
|
283
|
-
attribute :recipes,
|
284
|
-
type: Array,
|
285
|
-
default: Array.new
|
286
|
-
|
287
|
-
attribute :resources,
|
288
|
-
type: Array,
|
289
|
-
default: Array.new
|
290
|
-
|
291
|
-
attribute :root_files,
|
292
|
-
type: Array,
|
293
|
-
default: Array.new
|
294
|
-
|
295
|
-
attribute :templates,
|
296
|
-
type: Array,
|
297
|
-
default: Array.new
|
298
|
-
|
299
|
-
attribute :version,
|
300
|
-
type: String
|
37
|
+
# Delete a cookbook of the given name and version on the remote Chef server
|
38
|
+
#
|
39
|
+
# @param [String] name
|
40
|
+
# @param [String] version
|
41
|
+
#
|
42
|
+
# @option options [Boolean] purge (false)
|
43
|
+
#
|
44
|
+
# @return [Boolean]
|
45
|
+
def delete(name, version, options = {})
|
46
|
+
options = options.reverse_merge(purge: false)
|
47
|
+
url = "#{self.class.resource_path}/#{name}/#{version}"
|
48
|
+
url += "?purge=true" if options[:purge]
|
49
|
+
|
50
|
+
connection.delete(url).body
|
51
|
+
true
|
52
|
+
rescue Errors::HTTPNotFound
|
53
|
+
true
|
54
|
+
end
|
301
55
|
|
302
|
-
|
303
|
-
|
56
|
+
# Delete all of the versions of a given cookbook on the remote Chef server
|
57
|
+
#
|
58
|
+
# @param [String] name
|
59
|
+
# name of the cookbook to delete
|
60
|
+
#
|
61
|
+
# @option options [Boolean] purge (false)
|
62
|
+
def delete_all(name, options = {})
|
63
|
+
versions(name).each do |version|
|
64
|
+
future(:delete, name, version, options)
|
65
|
+
end.map(&:value)
|
66
|
+
end
|
304
67
|
|
305
68
|
# Download the entire cookbook
|
306
69
|
#
|
70
|
+
# @param [String] name
|
71
|
+
# @param [String] version
|
307
72
|
# @param [String] destination (Dir.mktmpdir)
|
308
73
|
# the place to download the cookbook too. If no value is provided the cookbook
|
309
74
|
# will be downloaded to a temporary location
|
310
75
|
#
|
311
76
|
# @return [String]
|
312
77
|
# the path to the directory the cookbook was downloaded to
|
313
|
-
def download(destination = Dir.mktmpdir)
|
314
|
-
|
315
|
-
log.debug { "downloading cookbook: '#{name}'" }
|
316
|
-
|
317
|
-
FILE_TYPES.each do |filetype|
|
318
|
-
next unless manifest.has_key?(filetype)
|
78
|
+
def download(name, version, destination = Dir.mktmpdir)
|
79
|
+
cookbook = find(name, version)
|
319
80
|
|
320
|
-
|
321
|
-
|
322
|
-
FileUtils.mkdir_p(File.dirname(file_destination))
|
323
|
-
download_file(filetype, file[:path], file_destination)
|
324
|
-
end
|
81
|
+
unless cookbook.nil?
|
82
|
+
cookbook.download(destination)
|
325
83
|
end
|
84
|
+
end
|
326
85
|
|
327
|
-
|
86
|
+
# @param [String, #chef_id] object
|
87
|
+
# @param [String] version
|
88
|
+
#
|
89
|
+
# @return [nil, CookbookResource]
|
90
|
+
def find(object, version)
|
91
|
+
chef_id = object.respond_to?(:chef_id) ? object.chef_id : object
|
92
|
+
new(connection.get("#{self.class.resource_path}/#{chef_id}/#{version}").body)
|
93
|
+
rescue Errors::HTTPNotFound
|
94
|
+
nil
|
328
95
|
end
|
329
96
|
|
330
|
-
#
|
97
|
+
# Return the latest version of the given cookbook found on the remote Chef server
|
331
98
|
#
|
332
|
-
# @param [
|
333
|
-
# the type of file to download. These are broken up into the following types in Chef:
|
334
|
-
# - attribute (unsupported until resolved https://github.com/reset/chozo/issues/17)
|
335
|
-
# - definition
|
336
|
-
# - file
|
337
|
-
# - library
|
338
|
-
# - provider
|
339
|
-
# - recipe
|
340
|
-
# - resource
|
341
|
-
# - root_file
|
342
|
-
# - template
|
343
|
-
# these types are where the files are stored in your cookbook's structure. For example, a
|
344
|
-
# recipe would be stored in the recipes directory while a root_file is stored at the root
|
345
|
-
# of your cookbook
|
346
|
-
# @param [String] path
|
347
|
-
# path of the file to download
|
348
|
-
# @param [String] destination
|
349
|
-
# where to download the file to
|
99
|
+
# @param [String] name
|
350
100
|
#
|
351
|
-
# @return [nil]
|
352
|
-
def
|
353
|
-
|
101
|
+
# @return [String, nil]
|
102
|
+
def latest_version(name)
|
103
|
+
ver = versions(name).collect do |version|
|
104
|
+
Solve::Version.new(version)
|
105
|
+
end.sort.last
|
106
|
+
|
107
|
+
ver.nil? ? nil : ver.to_s
|
354
108
|
end
|
355
109
|
|
356
|
-
#
|
357
|
-
# representing each file of that type this cookbook contains
|
110
|
+
# Return the version of the given cookbook which best stasifies the given constraint
|
358
111
|
#
|
359
|
-
# @
|
360
|
-
#
|
361
|
-
#
|
362
|
-
#
|
363
|
-
# :name => "afile.rb",
|
364
|
-
# :path => "files/ubuntu-9.10/afile.rb",
|
365
|
-
# :checksum => "2222",
|
366
|
-
# :specificity => "ubuntu-9.10"
|
367
|
-
# },
|
368
|
-
# ],
|
369
|
-
# templates: [ manifest_record1, ... ],
|
370
|
-
# ...
|
371
|
-
# }
|
112
|
+
# @param [String] name
|
113
|
+
# name of the cookbook
|
114
|
+
# @param [String, Solve::Constraint] constraint
|
115
|
+
# constraint to solve for
|
372
116
|
#
|
373
|
-
# @return [
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
|
117
|
+
# @return [CookbookResource, nil]
|
118
|
+
# returns the cookbook resource for the best solution or nil if no solution exists
|
119
|
+
def satisfy(name, constraint)
|
120
|
+
version = Solve::Solver.satisfy_best(constraint, versions(name)).to_s
|
121
|
+
find(name, version)
|
122
|
+
rescue Solve::Errors::NoSolutionError
|
123
|
+
nil
|
380
124
|
end
|
381
125
|
|
382
|
-
|
383
|
-
|
384
|
-
|
126
|
+
# Update or create a new Cookbook Version of the given name, version with the
|
127
|
+
# given manifest of files and checksums.
|
128
|
+
#
|
129
|
+
# @param [Ridley::Chef::Cookbook] cookbook
|
130
|
+
# the cookbook to save
|
131
|
+
#
|
132
|
+
# @option options [Boolean] :force
|
133
|
+
# Upload the Cookbook even if the version already exists and is frozen on
|
134
|
+
# the target Chef Server
|
135
|
+
# @option options [Boolean] :freeze
|
136
|
+
# Freeze the uploaded Cookbook on the Chef Server so that it cannot be
|
137
|
+
# overwritten
|
138
|
+
#
|
139
|
+
# @raise [Ridley::Errors::FrozenCookbook]
|
140
|
+
# if a cookbook of the same name and version already exists on the remote Chef server
|
141
|
+
# and is frozen. If the :force option is provided the given cookbook will be saved
|
142
|
+
# regardless.
|
143
|
+
#
|
144
|
+
# @return [Hash]
|
145
|
+
def update(cookbook, options = {})
|
146
|
+
options.reverse_merge(force: false, freeze: false)
|
385
147
|
|
386
|
-
|
148
|
+
cookbook.frozen = options[:freeze]
|
149
|
+
|
150
|
+
url = "cookbooks/#{cookbook.cookbook_name}/#{cookbook.version}"
|
151
|
+
url << "?force=true" if options[:force]
|
387
152
|
|
388
|
-
|
389
|
-
|
390
|
-
|
391
|
-
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
|
398
|
-
|
399
|
-
|
400
|
-
|
401
|
-
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
-
|
406
|
-
|
407
|
-
|
153
|
+
connection.put(url, cookbook.to_json)
|
154
|
+
rescue Ridley::Errors::HTTPConflict => ex
|
155
|
+
abort Ridley::Errors::FrozenCookbook.new(ex)
|
156
|
+
end
|
157
|
+
alias_method :create, :update
|
158
|
+
|
159
|
+
# Uploads a cookbook to the remote Chef server from the contents of a filepath
|
160
|
+
#
|
161
|
+
# @param [String] path
|
162
|
+
# path to a cookbook on local disk
|
163
|
+
#
|
164
|
+
# @option options [String] :name
|
165
|
+
# automatically populated by the metadata of the cookbook at the given path, but
|
166
|
+
# in the event that the metadata does not contain a name it can be specified with
|
167
|
+
# this option
|
168
|
+
# @option options [Boolean] :force (false)
|
169
|
+
# Upload the Cookbook even if the version already exists and is frozen on
|
170
|
+
# the target Chef Server
|
171
|
+
# @option options [Boolean] :freeze (false)
|
172
|
+
# Freeze the uploaded Cookbook on the Chef Server so that it cannot be
|
173
|
+
# overwritten
|
174
|
+
# @option options [Boolean] :validate (true)
|
175
|
+
# Validate the contents of the cookbook before uploading
|
176
|
+
#
|
177
|
+
# @return [Hash]
|
178
|
+
def upload(path, options = {})
|
179
|
+
options = options.reverse_merge(validate: true, force: false, freeze: false)
|
180
|
+
cookbook = Ridley::Chef::Cookbook.from_path(path, options.slice(:name))
|
181
|
+
|
182
|
+
unless (existing = find(cookbook.cookbook_name, cookbook.version)).nil?
|
183
|
+
if existing.frozen? && options[:force] == false
|
184
|
+
msg = "The cookbook #{cookbook.cookbook_name} (#{cookbook.version}) already exists and is"
|
185
|
+
msg << " frozen on the Chef server. Use the 'force' option to override."
|
186
|
+
abort Ridley::Errors::FrozenCookbook.new(msg)
|
408
187
|
end
|
188
|
+
end
|
189
|
+
|
190
|
+
if options[:validate]
|
191
|
+
cookbook.validate
|
192
|
+
end
|
409
193
|
|
410
|
-
|
411
|
-
|
412
|
-
file = files.find { |f| f[:path] == target }
|
413
|
-
return nil if file.nil?
|
194
|
+
checksums = cookbook.checksums.dup
|
195
|
+
sandbox = sandbox_resource.create(checksums.keys)
|
414
196
|
|
415
|
-
|
416
|
-
|
197
|
+
sandbox.upload(checksums)
|
198
|
+
sandbox.commit
|
199
|
+
update(cookbook, options.slice(:force, :freeze))
|
200
|
+
end
|
417
201
|
|
418
|
-
|
419
|
-
|
202
|
+
# Return a list of versions for the given cookbook present on the remote Chef server
|
203
|
+
#
|
204
|
+
# @param [String] name
|
205
|
+
#
|
206
|
+
# @example
|
207
|
+
# versions("nginx") => [ "1.0.0", "1.2.0" ]
|
208
|
+
#
|
209
|
+
# @return [Array<String>]
|
210
|
+
def versions(name)
|
211
|
+
response = connection.get("#{self.class.resource_path}/#{name}").body
|
212
|
+
|
213
|
+
response[name]["versions"].collect do |cb_ver|
|
214
|
+
cb_ver["version"]
|
420
215
|
end
|
216
|
+
end
|
217
|
+
|
218
|
+
private
|
219
|
+
|
220
|
+
attr_reader :sandbox_resource
|
421
221
|
end
|
422
222
|
end
|