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.
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