chef 0.9.8 → 0.9.10.rc.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (98) hide show
  1. data/README.rdoc +1 -1
  2. data/distro/common/man/man8/knife.8 +89 -79
  3. data/distro/common/markdown/knife.mkd +7 -0
  4. data/distro/debian/etc/default/chef-server +3 -0
  5. data/distro/debian/etc/default/chef-server-webui +3 -0
  6. data/distro/debian/etc/default/chef-solr +3 -0
  7. data/distro/debian/etc/default/chef-solr-indexer +3 -0
  8. data/distro/debian/etc/init.d/chef-server +3 -1
  9. data/distro/debian/etc/init.d/chef-server-webui +3 -1
  10. data/distro/redhat/etc/init.d/chef-client +1 -1
  11. data/lib/chef/application.rb +2 -0
  12. data/lib/chef/application/client.rb +5 -3
  13. data/lib/chef/application/knife.rb +16 -5
  14. data/lib/chef/application/solo.rb +0 -1
  15. data/lib/chef/checksum.rb +65 -1
  16. data/lib/chef/checksum_cache.rb +173 -0
  17. data/lib/chef/client.rb +84 -121
  18. data/lib/chef/cookbook/remote_file_vendor.rb +10 -3
  19. data/lib/chef/cookbook/syntax_check.rb +2 -2
  20. data/lib/chef/cookbook_loader.rb +2 -0
  21. data/lib/chef/cookbook_site_streaming_uploader.rb +29 -0
  22. data/lib/chef/cookbook_uploader.rb +8 -7
  23. data/lib/chef/cookbook_version.rb +155 -114
  24. data/lib/chef/exceptions.rb +5 -0
  25. data/lib/chef/handler.rb +43 -0
  26. data/lib/chef/index_queue/consumer.rb +1 -1
  27. data/lib/chef/index_queue/indexable.rb +1 -1
  28. data/lib/chef/knife.rb +18 -5
  29. data/lib/chef/knife/bootstrap.rb +2 -2
  30. data/lib/chef/knife/bootstrap/archlinux-gems.erb +44 -0
  31. data/lib/chef/knife/bootstrap/client-install.vbs +80 -0
  32. data/lib/chef/knife/bootstrap/ubuntu10.04-apt.erb +2 -2
  33. data/lib/chef/knife/bootstrap/ubuntu10.04-gems.erb +6 -7
  34. data/lib/chef/knife/bootstrap/windows-gems.erb +34 -0
  35. data/lib/chef/knife/configure_client.rb +4 -2
  36. data/lib/chef/knife/cookbook_metadata.rb +1 -1
  37. data/lib/chef/knife/cookbook_site_share.rb +2 -1
  38. data/lib/chef/knife/cookbook_site_vendor.rb +6 -0
  39. data/lib/chef/knife/cookbook_test.rb +1 -1
  40. data/lib/chef/knife/ec2_server_create.rb +51 -26
  41. data/lib/chef/knife/exec.rb +52 -0
  42. data/lib/chef/knife/ssh.rb +27 -15
  43. data/lib/chef/knife/status.rb +27 -10
  44. data/lib/chef/knife/windows_bootstrap.rb +154 -0
  45. data/lib/chef/mixin/checksum.rb +2 -2
  46. data/lib/chef/mixin/xml_escape.rb +75 -49
  47. data/lib/chef/node.rb +54 -58
  48. data/lib/chef/node/attribute.rb +61 -53
  49. data/lib/chef/platform.rb +19 -2
  50. data/lib/chef/provider/breakpoint.rb +1 -1
  51. data/lib/chef/provider/cookbook_file.rb +3 -3
  52. data/lib/chef/provider/cron.rb +3 -3
  53. data/lib/chef/provider/cron/solaris.rb +195 -0
  54. data/lib/chef/provider/deploy.rb +3 -3
  55. data/lib/chef/provider/directory.rb +2 -2
  56. data/lib/chef/provider/env.rb +5 -5
  57. data/lib/chef/provider/execute.rb +1 -1
  58. data/lib/chef/provider/file.rb +10 -9
  59. data/lib/chef/provider/git.rb +12 -4
  60. data/lib/chef/provider/group.rb +5 -5
  61. data/lib/chef/provider/http_request.rb +25 -9
  62. data/lib/chef/provider/ifconfig.rb +2 -2
  63. data/lib/chef/provider/link.rb +11 -6
  64. data/lib/chef/provider/log.rb +1 -0
  65. data/lib/chef/provider/mdadm.rb +3 -3
  66. data/lib/chef/provider/mount.rb +5 -5
  67. data/lib/chef/provider/mount/mount.rb +1 -1
  68. data/lib/chef/provider/ohai.rb +41 -0
  69. data/lib/chef/provider/package.rb +5 -5
  70. data/lib/chef/provider/package/yum-dump.py +5 -2
  71. data/lib/chef/provider/remote_directory.rb +11 -5
  72. data/lib/chef/provider/remote_file.rb +2 -2
  73. data/lib/chef/provider/route.rb +154 -133
  74. data/lib/chef/provider/ruby_block.rb +1 -1
  75. data/lib/chef/provider/service.rb +6 -6
  76. data/lib/chef/provider/subversion.rb +12 -9
  77. data/lib/chef/provider/template.rb +2 -2
  78. data/lib/chef/provider/user.rb +7 -7
  79. data/lib/chef/provider/user/useradd.rb +15 -1
  80. data/lib/chef/providers.rb +2 -0
  81. data/lib/chef/resource.rb +164 -58
  82. data/lib/chef/resource/http_request.rb +9 -0
  83. data/lib/chef/resource/ohai.rb +40 -0
  84. data/lib/chef/resource/remote_directory.rb +10 -1
  85. data/lib/chef/resource/rpm_package.rb +34 -0
  86. data/lib/chef/resource_collection.rb +3 -2
  87. data/lib/chef/resources.rb +2 -0
  88. data/lib/chef/rest.rb +13 -7
  89. data/lib/chef/rest/auth_credentials.rb +1 -1
  90. data/lib/chef/rest/rest_request.rb +3 -1
  91. data/lib/chef/runner.rb +31 -55
  92. data/lib/chef/shef/shef_session.rb +1 -1
  93. data/lib/chef/util/windows/net_use.rb +1 -1
  94. data/lib/chef/version.rb +1 -1
  95. data/lib/chef/webui_user.rb +0 -1
  96. metadata +38 -19
  97. data/lib/chef/cache.rb +0 -61
  98. data/lib/chef/cache/checksum.rb +0 -91
@@ -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(&notification_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(&notification_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(&notification_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
- run_status = Chef::RunStatus.new(node)
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, valid_cache_entries) }
100
- cookbook_hash = sync_cookbooks(valid_cache_entries)
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
- run_report_handlers(run_status)
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
- run_exception_handlers(run_status)
121
- Chef::Log.error("Re-raising exception: #{e.class} - #{e.message}\n#{e.backtrace.join("\n ")}")
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
- @node.process_external_attrs(ohai.data, @json_attribs)
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(valid_cache_entries)
249
+ def sync_cookbooks
200
250
  Chef::Log.debug("Synchronizing cookbooks")
201
251
  cookbook_hash = rest.get_rest("nodes/#{node_name}/cookbooks")
202
- Chef::Log.debug("Cookbooks to load: #{cookbook_hash.inspect}")
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 cookboook_path is set correctly."
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, valid_cache_entries)
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
- @valid_cache_entries[cache_filename] = true
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/cache/checksum'
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::Cache::Checksum.instance
50
+ Chef::ChecksumCache.instance
51
51
  end
52
52
 
53
53
  def ruby_files
@@ -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/cache/checksum'
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("/sandboxes", { :checksums => checksums })
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::Request.execute(:method => :put, :url => info['url'], :headers => headers, :payload => file_contents)
52
- rescue RestClient::RequestFailed => e
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