chef 0.9.8 → 0.9.10.rc.0
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.rdoc +1 -1
- data/distro/common/man/man8/knife.8 +89 -79
- data/distro/common/markdown/knife.mkd +7 -0
- data/distro/debian/etc/default/chef-server +3 -0
- data/distro/debian/etc/default/chef-server-webui +3 -0
- data/distro/debian/etc/default/chef-solr +3 -0
- data/distro/debian/etc/default/chef-solr-indexer +3 -0
- data/distro/debian/etc/init.d/chef-server +3 -1
- data/distro/debian/etc/init.d/chef-server-webui +3 -1
- data/distro/redhat/etc/init.d/chef-client +1 -1
- data/lib/chef/application.rb +2 -0
- data/lib/chef/application/client.rb +5 -3
- data/lib/chef/application/knife.rb +16 -5
- data/lib/chef/application/solo.rb +0 -1
- data/lib/chef/checksum.rb +65 -1
- data/lib/chef/checksum_cache.rb +173 -0
- data/lib/chef/client.rb +84 -121
- data/lib/chef/cookbook/remote_file_vendor.rb +10 -3
- data/lib/chef/cookbook/syntax_check.rb +2 -2
- data/lib/chef/cookbook_loader.rb +2 -0
- data/lib/chef/cookbook_site_streaming_uploader.rb +29 -0
- data/lib/chef/cookbook_uploader.rb +8 -7
- data/lib/chef/cookbook_version.rb +155 -114
- data/lib/chef/exceptions.rb +5 -0
- data/lib/chef/handler.rb +43 -0
- data/lib/chef/index_queue/consumer.rb +1 -1
- data/lib/chef/index_queue/indexable.rb +1 -1
- data/lib/chef/knife.rb +18 -5
- data/lib/chef/knife/bootstrap.rb +2 -2
- data/lib/chef/knife/bootstrap/archlinux-gems.erb +44 -0
- data/lib/chef/knife/bootstrap/client-install.vbs +80 -0
- data/lib/chef/knife/bootstrap/ubuntu10.04-apt.erb +2 -2
- data/lib/chef/knife/bootstrap/ubuntu10.04-gems.erb +6 -7
- data/lib/chef/knife/bootstrap/windows-gems.erb +34 -0
- data/lib/chef/knife/configure_client.rb +4 -2
- data/lib/chef/knife/cookbook_metadata.rb +1 -1
- data/lib/chef/knife/cookbook_site_share.rb +2 -1
- data/lib/chef/knife/cookbook_site_vendor.rb +6 -0
- data/lib/chef/knife/cookbook_test.rb +1 -1
- data/lib/chef/knife/ec2_server_create.rb +51 -26
- data/lib/chef/knife/exec.rb +52 -0
- data/lib/chef/knife/ssh.rb +27 -15
- data/lib/chef/knife/status.rb +27 -10
- data/lib/chef/knife/windows_bootstrap.rb +154 -0
- data/lib/chef/mixin/checksum.rb +2 -2
- data/lib/chef/mixin/xml_escape.rb +75 -49
- data/lib/chef/node.rb +54 -58
- data/lib/chef/node/attribute.rb +61 -53
- data/lib/chef/platform.rb +19 -2
- data/lib/chef/provider/breakpoint.rb +1 -1
- data/lib/chef/provider/cookbook_file.rb +3 -3
- data/lib/chef/provider/cron.rb +3 -3
- data/lib/chef/provider/cron/solaris.rb +195 -0
- data/lib/chef/provider/deploy.rb +3 -3
- data/lib/chef/provider/directory.rb +2 -2
- data/lib/chef/provider/env.rb +5 -5
- data/lib/chef/provider/execute.rb +1 -1
- data/lib/chef/provider/file.rb +10 -9
- data/lib/chef/provider/git.rb +12 -4
- data/lib/chef/provider/group.rb +5 -5
- data/lib/chef/provider/http_request.rb +25 -9
- data/lib/chef/provider/ifconfig.rb +2 -2
- data/lib/chef/provider/link.rb +11 -6
- data/lib/chef/provider/log.rb +1 -0
- data/lib/chef/provider/mdadm.rb +3 -3
- data/lib/chef/provider/mount.rb +5 -5
- data/lib/chef/provider/mount/mount.rb +1 -1
- data/lib/chef/provider/ohai.rb +41 -0
- data/lib/chef/provider/package.rb +5 -5
- data/lib/chef/provider/package/yum-dump.py +5 -2
- data/lib/chef/provider/remote_directory.rb +11 -5
- data/lib/chef/provider/remote_file.rb +2 -2
- data/lib/chef/provider/route.rb +154 -133
- data/lib/chef/provider/ruby_block.rb +1 -1
- data/lib/chef/provider/service.rb +6 -6
- data/lib/chef/provider/subversion.rb +12 -9
- data/lib/chef/provider/template.rb +2 -2
- data/lib/chef/provider/user.rb +7 -7
- data/lib/chef/provider/user/useradd.rb +15 -1
- data/lib/chef/providers.rb +2 -0
- data/lib/chef/resource.rb +164 -58
- data/lib/chef/resource/http_request.rb +9 -0
- data/lib/chef/resource/ohai.rb +40 -0
- data/lib/chef/resource/remote_directory.rb +10 -1
- data/lib/chef/resource/rpm_package.rb +34 -0
- data/lib/chef/resource_collection.rb +3 -2
- data/lib/chef/resources.rb +2 -0
- data/lib/chef/rest.rb +13 -7
- data/lib/chef/rest/auth_credentials.rb +1 -1
- data/lib/chef/rest/rest_request.rb +3 -1
- data/lib/chef/runner.rb +31 -55
- data/lib/chef/shef/shef_session.rb +1 -1
- data/lib/chef/util/windows/net_use.rb +1 -1
- data/lib/chef/version.rb +1 -1
- data/lib/chef/webui_user.rb +0 -1
- metadata +38 -19
- data/lib/chef/cache.rb +0 -61
- data/lib/chef/cache/checksum.rb +0 -91
data/lib/chef/client.rb
CHANGED
@@ -40,6 +40,73 @@ class Chef
|
|
40
40
|
# The main object in a Chef run. Preps a Chef::Node and Chef::RunContext,
|
41
41
|
# syncs cookbooks if necessary, and triggers convergence.
|
42
42
|
class Client
|
43
|
+
|
44
|
+
# Clears all notifications for client run status events.
|
45
|
+
# Primarily for testing purposes.
|
46
|
+
def self.clear_notifications
|
47
|
+
@run_start_notifications = nil
|
48
|
+
@run_completed_successfully_notifications = nil
|
49
|
+
@run_failed_notifications = nil
|
50
|
+
end
|
51
|
+
|
52
|
+
# The list of notifications to be run when the client run starts.
|
53
|
+
def self.run_start_notifications
|
54
|
+
@run_start_notifications ||= []
|
55
|
+
end
|
56
|
+
|
57
|
+
# The list of notifications to be run when the client run completes
|
58
|
+
# successfully.
|
59
|
+
def self.run_completed_successfully_notifications
|
60
|
+
@run_completed_successfully_notifications ||= []
|
61
|
+
end
|
62
|
+
|
63
|
+
# The list of notifications to be run when the client run fails.
|
64
|
+
def self.run_failed_notifications
|
65
|
+
@run_failed_notifications ||= []
|
66
|
+
end
|
67
|
+
|
68
|
+
# Add a notification for the 'client run started' event. The notification
|
69
|
+
# is provided as a block. The current Chef::RunStatus object will be passed
|
70
|
+
# to the notification_block when the event is triggered.
|
71
|
+
def self.when_run_starts(¬ification_block)
|
72
|
+
run_start_notifications << notification_block
|
73
|
+
end
|
74
|
+
|
75
|
+
# Add a notification for the 'client run success' event. The notification
|
76
|
+
# is provided as a block. The current Chef::RunStatus object will be passed
|
77
|
+
# to the notification_block when the event is triggered.
|
78
|
+
def self.when_run_completes_successfully(¬ification_block)
|
79
|
+
run_completed_successfully_notifications << notification_block
|
80
|
+
end
|
81
|
+
|
82
|
+
# Add a notification for the 'client run failed' event. The notification
|
83
|
+
# is provided as a block. The current Chef::RunStatus is passed to the
|
84
|
+
# notification_block when the event is triggered.
|
85
|
+
def self.when_run_fails(¬ification_block)
|
86
|
+
run_failed_notifications << notification_block
|
87
|
+
end
|
88
|
+
|
89
|
+
# Callback to fire notifications that the Chef run is starting
|
90
|
+
def run_started
|
91
|
+
self.class.run_start_notifications.each do |notification|
|
92
|
+
notification.call(run_status)
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
# Callback to fire notifications that the run completed successfully
|
97
|
+
def run_completed_successfully
|
98
|
+
self.class.run_completed_successfully_notifications.each do |notification|
|
99
|
+
notification.call(run_status)
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
# Callback to fire notifications that the Chef run failed
|
104
|
+
def run_failed
|
105
|
+
self.class.run_failed_notifications.each do |notification|
|
106
|
+
notification.call(run_status)
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
43
110
|
attr_accessor :node
|
44
111
|
attr_accessor :ohai
|
45
112
|
attr_accessor :rest
|
@@ -49,10 +116,13 @@ class Chef
|
|
49
116
|
# TODO: timh/cw: 5-19-2010: json_attribs should be moved to RunContext?
|
50
117
|
attr_reader :json_attribs
|
51
118
|
|
119
|
+
attr_reader :run_status
|
120
|
+
|
52
121
|
# Creates a new Chef::Client.
|
53
122
|
def initialize(json_attribs=nil)
|
54
123
|
@json_attribs = json_attribs
|
55
124
|
@node = nil
|
125
|
+
@run_status = nil
|
56
126
|
@runner = nil
|
57
127
|
@ohai = Ohai::System.new
|
58
128
|
end
|
@@ -75,9 +145,10 @@ class Chef
|
|
75
145
|
build_node
|
76
146
|
|
77
147
|
begin
|
78
|
-
|
148
|
+
|
79
149
|
run_status.start_clock
|
80
150
|
Chef::Log.info("Starting Chef Run (Version #{Chef::VERSION})")
|
151
|
+
run_started
|
81
152
|
|
82
153
|
if Chef::Config[:solo]
|
83
154
|
Chef::Cookbook::FileVendor.on_create { |manifest| Chef::Cookbook::FileSystemFileVendor.new(manifest) }
|
@@ -86,18 +157,12 @@ class Chef
|
|
86
157
|
assert_cookbook_path_not_empty(run_context)
|
87
158
|
converge(run_context)
|
88
159
|
else
|
89
|
-
# Keep track of the filenames that we use in both eager cookbook
|
90
|
-
# downloading (during sync_cookbooks) and lazy (during the run
|
91
|
-
# itself, through FileVendor). After the run is over, clean up the
|
92
|
-
# cache.
|
93
|
-
valid_cache_entries = Hash.new
|
94
|
-
|
95
160
|
# Sync_cookbooks eagerly loads all files except files and templates.
|
96
161
|
# It returns the cookbook_hash -- the return result from
|
97
162
|
# /nodes/#{nodename}/cookbooks -- which we will use for our
|
98
163
|
# run_context.
|
99
|
-
Chef::Cookbook::FileVendor.on_create { |manifest| Chef::Cookbook::RemoteFileVendor.new(manifest, rest
|
100
|
-
cookbook_hash = sync_cookbooks
|
164
|
+
Chef::Cookbook::FileVendor.on_create { |manifest| Chef::Cookbook::RemoteFileVendor.new(manifest, rest) }
|
165
|
+
cookbook_hash = sync_cookbooks
|
101
166
|
run_context = Chef::RunContext.new(node, Chef::CookbookCollection.new(cookbook_hash))
|
102
167
|
run_status.run_context = run_context
|
103
168
|
|
@@ -106,41 +171,23 @@ class Chef
|
|
106
171
|
converge(run_context)
|
107
172
|
Chef::Log.debug("Saving the current state of node #{node_name}")
|
108
173
|
@node.save
|
109
|
-
|
110
|
-
cleanup_file_cache(valid_cache_entries)
|
111
174
|
end
|
112
175
|
|
113
176
|
run_status.stop_clock
|
114
177
|
Chef::Log.info("Chef Run complete in #{run_status.elapsed_time} seconds")
|
115
|
-
|
178
|
+
run_completed_successfully
|
116
179
|
true
|
117
180
|
rescue Exception => e
|
118
181
|
run_status.stop_clock
|
119
182
|
run_status.exception = e
|
120
|
-
|
121
|
-
Chef::Log.
|
183
|
+
run_failed
|
184
|
+
Chef::Log.debug("Re-raising exception: #{e.class} - #{e.message}\n#{e.backtrace.join("\n ")}")
|
122
185
|
raise
|
123
186
|
ensure
|
124
187
|
run_status = nil
|
125
188
|
end
|
126
189
|
end
|
127
190
|
|
128
|
-
def run_report_handlers(run_status)
|
129
|
-
Chef::Log.info("Running report handlers")
|
130
|
-
Array(Chef::Config[:report_handlers]).each do |handler|
|
131
|
-
handler.run_report_safely(run_status)
|
132
|
-
end
|
133
|
-
Chef::Log.info("Report handlers complete")
|
134
|
-
end
|
135
|
-
|
136
|
-
def run_exception_handlers(run_status)
|
137
|
-
Chef::Log.error("Running exception handlers")
|
138
|
-
Array(Chef::Config[:exception_handlers]).each do |handler|
|
139
|
-
handler.run_report_safely(run_status)
|
140
|
-
end
|
141
|
-
Chef::Log.error("Exception handlers complete")
|
142
|
-
end
|
143
|
-
|
144
191
|
def run_ohai
|
145
192
|
ohai.all_plugins
|
146
193
|
end
|
@@ -171,10 +218,13 @@ class Chef
|
|
171
218
|
@node = Chef::Node.find_or_create(node_name)
|
172
219
|
end
|
173
220
|
|
174
|
-
|
221
|
+
|
222
|
+
@node.consume_external_attrs(ohai.data, @json_attribs)
|
175
223
|
@node.save unless Chef::Config[:solo]
|
176
224
|
@node.reset_defaults_and_overrides
|
177
225
|
|
226
|
+
@run_status = Chef::RunStatus.new(@node)
|
227
|
+
|
178
228
|
@node
|
179
229
|
end
|
180
230
|
|
@@ -196,25 +246,10 @@ class Chef
|
|
196
246
|
#
|
197
247
|
# === Returns
|
198
248
|
# true:: Always returns true
|
199
|
-
def sync_cookbooks
|
249
|
+
def sync_cookbooks
|
200
250
|
Chef::Log.debug("Synchronizing cookbooks")
|
201
251
|
cookbook_hash = rest.get_rest("nodes/#{node_name}/cookbooks")
|
202
|
-
Chef::
|
203
|
-
|
204
|
-
# Remove all cookbooks no longer relevant to this node
|
205
|
-
Chef::FileCache.find(File.join(%w{cookbooks ** *})).each do |cache_file|
|
206
|
-
cache_file =~ /^cookbooks\/([^\/]+)\//
|
207
|
-
unless cookbook_hash.has_key?($1)
|
208
|
-
Chef::Log.info("Removing #{cache_file} from the cache; its cookbook is no longer needed on this client.")
|
209
|
-
Chef::FileCache.delete(cache_file)
|
210
|
-
end
|
211
|
-
end
|
212
|
-
|
213
|
-
# Synchronize each of the node's cookbooks, and add to the
|
214
|
-
# valid_cache_entries hash.
|
215
|
-
cookbook_hash.values.each do |cookbook|
|
216
|
-
sync_cookbook_file_cache(cookbook, valid_cache_entries)
|
217
|
-
end
|
252
|
+
Chef::CookbookVersion.sync_cookbooks(cookbook_hash)
|
218
253
|
|
219
254
|
# register the file cache path in the cookbook path so that CookbookLoader actually picks up the synced cookbooks
|
220
255
|
Chef::Config[:cookbook_path] = File.join(Chef::Config[:file_cache_path], "cookbooks")
|
@@ -222,78 +257,6 @@ class Chef
|
|
222
257
|
cookbook_hash
|
223
258
|
end
|
224
259
|
|
225
|
-
# Update the file caches for a given cache segment. Takes a segment name
|
226
|
-
# and a hash that matches one of the cookbooks/_attribute_files style
|
227
|
-
# remote file listings.
|
228
|
-
#
|
229
|
-
# === Parameters
|
230
|
-
# cookbook<Chef::Cookbook>:: The cookbook to update
|
231
|
-
# valid_cache_entries<Hash>:: Out-param; Added to this hash are the files that
|
232
|
-
# were referred to by this cookbook
|
233
|
-
def sync_cookbook_file_cache(cookbook, valid_cache_entries)
|
234
|
-
Chef::Log.debug("Synchronizing cookbook #{cookbook.name}")
|
235
|
-
|
236
|
-
# files and templates are lazily loaded, and will be done later.
|
237
|
-
eager_segments = Chef::CookbookVersion::COOKBOOK_SEGMENTS.dup
|
238
|
-
eager_segments.delete(:files)
|
239
|
-
eager_segments.delete(:templates)
|
240
|
-
|
241
|
-
eager_segments.each do |segment|
|
242
|
-
segment_filenames = Array.new
|
243
|
-
cookbook.manifest[segment].each do |manifest_record|
|
244
|
-
# segment = cookbook segment
|
245
|
-
# remote_list = list of file hashes
|
246
|
-
#
|
247
|
-
# We need the list of known good attribute files, so we can delete any that are
|
248
|
-
# just laying about.
|
249
|
-
|
250
|
-
cache_filename = File.join("cookbooks", cookbook.name, manifest_record['path'])
|
251
|
-
valid_cache_entries[cache_filename] = true
|
252
|
-
|
253
|
-
current_checksum = nil
|
254
|
-
if Chef::FileCache.has_key?(cache_filename)
|
255
|
-
current_checksum = Chef::CookbookVersion.checksum_cookbook_file(Chef::FileCache.load(cache_filename, false))
|
256
|
-
end
|
257
|
-
|
258
|
-
# If the checksums are different between on-disk (current) and on-server
|
259
|
-
# (remote, per manifest), do the update. This will also execute if there
|
260
|
-
# is no current checksum.
|
261
|
-
if current_checksum != manifest_record['checksum']
|
262
|
-
raw_file = rest.get_rest(manifest_record[:url], true)
|
263
|
-
|
264
|
-
Chef::Log.info("Storing updated #{cache_filename} in the cache.")
|
265
|
-
Chef::FileCache.move_to(raw_file.path, cache_filename)
|
266
|
-
else
|
267
|
-
Chef::Log.debug("Not storing #{cache_filename}, as the cache is up to date.")
|
268
|
-
end
|
269
|
-
|
270
|
-
# make the segment filenames a full path.
|
271
|
-
full_path_cache_filename = Chef::FileCache.load(cache_filename, false)
|
272
|
-
segment_filenames << full_path_cache_filename
|
273
|
-
end
|
274
|
-
|
275
|
-
# replace segment filenames with a full-path one.
|
276
|
-
if segment.to_sym == :recipes
|
277
|
-
cookbook.recipe_filenames = segment_filenames
|
278
|
-
elsif segment.to_sym == :attributes
|
279
|
-
cookbook.attribute_filenames = segment_filenames
|
280
|
-
else
|
281
|
-
cookbook.segment_filenames(segment).replace(segment_filenames)
|
282
|
-
end
|
283
|
-
end
|
284
|
-
end
|
285
|
-
|
286
|
-
def cleanup_file_cache(valid_cache_entries)
|
287
|
-
# Delete each file in the cache that we didn't encounter in the
|
288
|
-
# manifest.
|
289
|
-
Chef::FileCache.find(File.join(%w{cookbooks ** *})).each do |cache_filename|
|
290
|
-
unless valid_cache_entries[cache_filename]
|
291
|
-
Chef::Log.info("Removing #{cache_filename} from the cache; it is no longer on the server.")
|
292
|
-
Chef::FileCache.delete(cache_filename)
|
293
|
-
end
|
294
|
-
end
|
295
|
-
end
|
296
|
-
|
297
260
|
# Converges the node.
|
298
261
|
#
|
299
262
|
# === Returns
|
@@ -325,7 +288,7 @@ class Chef
|
|
325
288
|
if directory_not_empty?(cookbook_path)
|
326
289
|
break
|
327
290
|
else
|
328
|
-
msg = "No cookbook found in #{Chef::Config[:cookbook_path].inspect}, make sure
|
291
|
+
msg = "No cookbook found in #{Chef::Config[:cookbook_path].inspect}, make sure cookbook_path is set correctly."
|
329
292
|
Chef::Log.fatal(msg)
|
330
293
|
raise Chef::Exceptions::CookbookNotFound, msg if is_last_element?(index, Chef::Config[:cookbook_path])
|
331
294
|
end
|
@@ -25,11 +25,10 @@ class Chef
|
|
25
25
|
# if not available, loading them from the remote server.
|
26
26
|
class RemoteFileVendor < FileVendor
|
27
27
|
|
28
|
-
def initialize(manifest, rest
|
28
|
+
def initialize(manifest, rest)
|
29
29
|
@manifest = manifest
|
30
30
|
@cookbook_name = @manifest[:cookbook_name]
|
31
31
|
@rest = rest
|
32
|
-
@valid_cache_entries = valid_cache_entries
|
33
32
|
end
|
34
33
|
|
35
34
|
# Implements abstract base's requirement. It looks in the
|
@@ -50,7 +49,7 @@ class Chef
|
|
50
49
|
|
51
50
|
# update valid_cache_entries so the upstream cache cleaner knows what
|
52
51
|
# we've used.
|
53
|
-
|
52
|
+
validate_cached_copy(cache_filename)
|
54
53
|
|
55
54
|
current_checksum = nil
|
56
55
|
if Chef::FileCache.has_key?(cache_filename)
|
@@ -74,6 +73,14 @@ class Chef
|
|
74
73
|
# return the filename, not the contents (second argument= false)
|
75
74
|
full_path_cache_filename
|
76
75
|
end
|
76
|
+
|
77
|
+
def validate_cached_copy(cache_filename)
|
78
|
+
valid_cache_entries[cache_filename] = true
|
79
|
+
end
|
80
|
+
|
81
|
+
def valid_cache_entries
|
82
|
+
Chef::CookbookVersion.valid_cache_entries
|
83
|
+
end
|
77
84
|
|
78
85
|
end
|
79
86
|
end
|
@@ -16,7 +16,7 @@
|
|
16
16
|
# limitations under the License.
|
17
17
|
#
|
18
18
|
|
19
|
-
require 'chef/
|
19
|
+
require 'chef/checksum_cache'
|
20
20
|
require 'chef/mixin/shell_out'
|
21
21
|
|
22
22
|
class Chef
|
@@ -47,7 +47,7 @@ class Chef
|
|
47
47
|
end
|
48
48
|
|
49
49
|
def cache
|
50
|
-
Chef::
|
50
|
+
Chef::ChecksumCache.instance
|
51
51
|
end
|
52
52
|
|
53
53
|
def ruby_files
|
data/lib/chef/cookbook_loader.rb
CHANGED
@@ -101,6 +101,7 @@ class Chef
|
|
101
101
|
cookbook,
|
102
102
|
cookbook_settings[cookbook_name][:root_filenames]
|
103
103
|
)
|
104
|
+
cookbook_settings[cookbook_name][:root_dir] = cookbook
|
104
105
|
if File.exists?(File.join(cookbook, "metadata.json"))
|
105
106
|
cookbook_settings[cookbook_name][:metadata_filenames] << File.join(cookbook, "metadata.json")
|
106
107
|
end
|
@@ -119,6 +120,7 @@ class Chef
|
|
119
120
|
|
120
121
|
cookbook_settings.each_key do |cookbook|
|
121
122
|
@cookbooks_by_name[cookbook] = Chef::CookbookVersion.new(cookbook)
|
123
|
+
@cookbooks_by_name[cookbook].root_dir = cookbook_settings[cookbook][:root_dir]
|
122
124
|
@cookbooks_by_name[cookbook].attribute_filenames = cookbook_settings[cookbook][:attribute_filenames].values
|
123
125
|
@cookbooks_by_name[cookbook].definition_filenames = cookbook_settings[cookbook][:definition_filenames].values
|
124
126
|
@cookbooks_by_name[cookbook].recipe_filenames = cookbook_settings[cookbook][:recipe_filenames].values
|
@@ -34,6 +34,35 @@ class Chef
|
|
34
34
|
|
35
35
|
class << self
|
36
36
|
|
37
|
+
def create_build_dir(cookbook)
|
38
|
+
tmp_cookbook_path = Tempfile.new("chef-#{cookbook.name}-build")
|
39
|
+
tmp_cookbook_path.close
|
40
|
+
tmp_cookbook_dir = tmp_cookbook_path.path
|
41
|
+
File.unlink(tmp_cookbook_dir)
|
42
|
+
FileUtils.mkdir_p(tmp_cookbook_dir)
|
43
|
+
Chef::Log.debug("Staging at #{tmp_cookbook_dir}")
|
44
|
+
checksums_to_on_disk_paths = cookbook.checksums
|
45
|
+
Chef::CookbookVersion::COOKBOOK_SEGMENTS.each do |segment|
|
46
|
+
cookbook.manifest[segment].each do |manifest_record|
|
47
|
+
path_in_cookbook = manifest_record[:path]
|
48
|
+
on_disk_path = checksums_to_on_disk_paths[manifest_record[:checksum]]
|
49
|
+
dest = File.join(tmp_cookbook_dir, cookbook.name.to_s, path_in_cookbook)
|
50
|
+
FileUtils.mkdir_p(File.dirname(dest))
|
51
|
+
Chef::Log.debug("Staging #{on_disk_path} to #{dest}")
|
52
|
+
FileUtils.cp(on_disk_path, dest)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
# First, generate metadata
|
57
|
+
Chef::Log.debug("Generating metadata")
|
58
|
+
kcm = Chef::Knife::CookbookMetadata.new
|
59
|
+
kcm.config[:cookbook_path] = [ tmp_cookbook_dir ]
|
60
|
+
kcm.name_args = [ cookbook.name.to_s ]
|
61
|
+
kcm.run
|
62
|
+
|
63
|
+
tmp_cookbook_dir
|
64
|
+
end
|
65
|
+
|
37
66
|
def post(to_url, user_id, secret_key_filename, params = {}, headers = {})
|
38
67
|
make_request(:post, to_url, user_id, secret_key_filename, params, headers)
|
39
68
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'rest_client'
|
2
2
|
require 'chef/cookbook_loader'
|
3
|
-
require 'chef/
|
3
|
+
require 'chef/checksum_cache'
|
4
4
|
require 'chef/sandbox'
|
5
5
|
require 'chef/cookbook_version'
|
6
6
|
require 'chef/cookbook/syntax_check'
|
@@ -23,7 +23,7 @@ class Chef
|
|
23
23
|
# generate checksums of cookbook files and create a sandbox
|
24
24
|
checksum_files = cookbook.checksums
|
25
25
|
checksums = checksum_files.inject({}){|memo,elt| memo[elt.first]=nil ; memo}
|
26
|
-
new_sandbox = rest.post_rest("
|
26
|
+
new_sandbox = rest.post_rest("sandboxes", { :checksums => checksums })
|
27
27
|
|
28
28
|
Chef::Log.info("Uploading files")
|
29
29
|
# upload the new checksums and commit the sandbox
|
@@ -48,8 +48,8 @@ class Chef
|
|
48
48
|
headers = { 'content-type' => 'application/x-binary', 'content-md5' => checksum64, :accept => 'application/json' }
|
49
49
|
headers.merge!(sign_obj.sign(OpenSSL::PKey::RSA.new(rest.signing_key)))
|
50
50
|
begin
|
51
|
-
RestClient::
|
52
|
-
rescue RestClient::
|
51
|
+
RestClient::Resource.new(info['url'], :headers=>headers, :timeout=>1800, :open_timeout=>1800).put(file_contents)
|
52
|
+
rescue RestClient::Exception => e
|
53
53
|
Chef::Log.error("Upload failed: #{e.message}\n#{e.response.body}")
|
54
54
|
raise
|
55
55
|
end
|
@@ -72,19 +72,20 @@ class Chef
|
|
72
72
|
raise
|
73
73
|
end
|
74
74
|
end
|
75
|
-
|
76
75
|
# files are uploaded, so save the manifest
|
77
76
|
cookbook.save
|
78
|
-
|
79
77
|
Chef::Log.info("Upload complete!")
|
80
78
|
end
|
81
79
|
|
82
80
|
def build_metadata(cookbook)
|
83
81
|
Chef::Log.debug("Generating metadata")
|
82
|
+
# FIXME: This knife command should be factored out into a
|
83
|
+
# library for use here
|
84
84
|
kcm = Chef::Knife::CookbookMetadata.new
|
85
85
|
kcm.config[:cookbook_path] = Chef::Config[:cookbook_path]
|
86
86
|
kcm.name_args = [ cookbook.name.to_s ]
|
87
87
|
kcm.run
|
88
|
+
cookbook.reload_metadata!
|
88
89
|
end
|
89
90
|
|
90
91
|
def validate_cookbook(cookbook)
|
@@ -99,4 +100,4 @@ class Chef
|
|
99
100
|
|
100
101
|
end
|
101
102
|
end
|
102
|
-
end
|
103
|
+
end
|