chef 0.10.0.beta.6 → 0.10.0.beta.7

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 (90) hide show
  1. data/lib/chef/application.rb +3 -0
  2. data/lib/chef/application/client.rb +34 -2
  3. data/lib/chef/checksum.rb +2 -2
  4. data/lib/chef/checksum_cache.rb +2 -2
  5. data/lib/chef/client.rb +7 -5
  6. data/lib/chef/cookbook/remote_file_vendor.rb +1 -1
  7. data/lib/chef/cookbook/syntax_check.rb +2 -2
  8. data/lib/chef/cookbook_version.rb +5 -0
  9. data/lib/chef/data_bag_item.rb +1 -1
  10. data/lib/chef/environment.rb +31 -9
  11. data/lib/chef/file_access_control.rb +7 -3
  12. data/lib/chef/index_queue/indexable.rb +2 -2
  13. data/lib/chef/knife.rb +1 -1
  14. data/lib/chef/knife/bootstrap.rb +1 -1
  15. data/lib/chef/knife/cookbook_site_install.rb +1 -1
  16. data/lib/chef/knife/cookbook_site_share.rb +2 -2
  17. data/lib/chef/knife/cookbook_upload.rb +32 -11
  18. data/lib/chef/knife/core/subcommand_loader.rb +24 -13
  19. data/lib/chef/knife/core/text_formatter.rb +2 -2
  20. data/lib/chef/knife/core/ui.rb +1 -1
  21. data/lib/chef/knife/search.rb +1 -1
  22. data/lib/chef/knife/ssh.rb +1 -0
  23. data/lib/chef/mixin/shell_out.rb +2 -2
  24. data/lib/chef/node.rb +7 -4
  25. data/lib/chef/provider/cookbook_file.rb +4 -5
  26. data/lib/chef/provider/cron.rb +3 -3
  27. data/lib/chef/provider/cron/solaris.rb +7 -7
  28. data/lib/chef/provider/deploy.rb +52 -29
  29. data/lib/chef/provider/directory.rb +8 -8
  30. data/lib/chef/provider/env.rb +8 -8
  31. data/lib/chef/provider/erl_call.rb +7 -6
  32. data/lib/chef/provider/execute.rb +7 -2
  33. data/lib/chef/provider/file.rb +9 -9
  34. data/lib/chef/provider/git.rb +17 -8
  35. data/lib/chef/provider/group.rb +6 -6
  36. data/lib/chef/provider/group/aix.rb +1 -1
  37. data/lib/chef/provider/group/dscl.rb +2 -2
  38. data/lib/chef/provider/group/gpasswd.rb +3 -3
  39. data/lib/chef/provider/group/groupadd.rb +1 -1
  40. data/lib/chef/provider/group/pw.rb +3 -3
  41. data/lib/chef/provider/group/usermod.rb +2 -2
  42. data/lib/chef/provider/group/windows.rb +1 -1
  43. data/lib/chef/provider/ifconfig.rb +9 -7
  44. data/lib/chef/provider/link.rb +27 -24
  45. data/lib/chef/provider/mdadm.rb +10 -10
  46. data/lib/chef/provider/mount.rb +10 -13
  47. data/lib/chef/provider/mount/mount.rb +10 -10
  48. data/lib/chef/provider/mount/windows.rb +4 -3
  49. data/lib/chef/provider/ohai.rb +2 -1
  50. data/lib/chef/provider/package.rb +10 -6
  51. data/lib/chef/provider/package/apt.rb +18 -18
  52. data/lib/chef/provider/package/dpkg.rb +3 -3
  53. data/lib/chef/provider/package/easy_install.rb +2 -2
  54. data/lib/chef/provider/package/freebsd.rb +4 -5
  55. data/lib/chef/provider/package/macports.rb +2 -2
  56. data/lib/chef/provider/package/pacman.rb +2 -2
  57. data/lib/chef/provider/package/portage.rb +1 -1
  58. data/lib/chef/provider/package/rpm.rb +3 -3
  59. data/lib/chef/provider/package/rubygems.rb +7 -7
  60. data/lib/chef/provider/package/solaris.rb +9 -9
  61. data/lib/chef/provider/package/yum.rb +4 -4
  62. data/lib/chef/provider/package/zypper.rb +5 -11
  63. data/lib/chef/provider/remote_directory.rb +15 -14
  64. data/lib/chef/provider/remote_file.rb +11 -12
  65. data/lib/chef/provider/route.rb +8 -10
  66. data/lib/chef/provider/ruby_block.rb +1 -0
  67. data/lib/chef/provider/service.rb +10 -16
  68. data/lib/chef/provider/service/debian.rb +1 -1
  69. data/lib/chef/provider/service/freebsd.rb +16 -18
  70. data/lib/chef/provider/service/gentoo.rb +2 -3
  71. data/lib/chef/provider/service/simple.rb +7 -5
  72. data/lib/chef/provider/service/upstart.rb +8 -8
  73. data/lib/chef/provider/service/windows.rb +3 -3
  74. data/lib/chef/provider/subversion.rb +12 -9
  75. data/lib/chef/provider/template.rb +2 -3
  76. data/lib/chef/provider/user.rb +13 -14
  77. data/lib/chef/provider/user/dscl.rb +2 -2
  78. data/lib/chef/provider/user/pw.rb +4 -4
  79. data/lib/chef/provider/user/useradd.rb +3 -3
  80. data/lib/chef/provider/user/windows.rb +3 -3
  81. data/lib/chef/resource.rb +4 -3
  82. data/lib/chef/resource/deploy.rb +1 -1
  83. data/lib/chef/rest/rest_request.rb +2 -2
  84. data/lib/chef/run_context.rb +1 -1
  85. data/lib/chef/shell_out.rb +13 -1
  86. data/lib/chef/solr_query.rb +1 -1
  87. data/lib/chef/solr_query/solr_http_request.rb +1 -1
  88. data/lib/chef/tasks/chef_repo.rake +74 -0
  89. data/lib/chef/version.rb +1 -1
  90. metadata +2 -2
@@ -24,6 +24,9 @@ require 'tmpdir'
24
24
  class Chef::Application
25
25
  include Mixlib::CLI
26
26
 
27
+ class Wakeup < Exception
28
+ end
29
+
27
30
  def initialize
28
31
  super
29
32
 
@@ -26,6 +26,9 @@ require 'chef/rest'
26
26
 
27
27
  class Chef::Application::Client < Chef::Application
28
28
 
29
+ # Mimic self_pipe sleep from Unicorn to capture signals safely
30
+ SELF_PIPE = []
31
+
29
32
  option :config_file,
30
33
  :short => "-c CONFIG",
31
34
  :long => "--config CONFIG",
@@ -197,6 +200,15 @@ class Chef::Application::Client < Chef::Application
197
200
 
198
201
  # Run the chef client, optionally daemonizing or looping at intervals.
199
202
  def run_application
203
+ unless RUBY_PLATFORM =~ /mswin|mingw32|windows/
204
+ SELF_PIPE.replace IO.pipe
205
+
206
+ trap("USR1") do
207
+ Chef::Log.info("SIGUSR1 received, waking up")
208
+ SELF_PIPE[1].putc('.') # wakeup master process from select
209
+ end
210
+ end
211
+
200
212
  if Chef::Config[:version]
201
213
  puts "Chef version: #{::Chef::VERSION}"
202
214
  end
@@ -219,10 +231,18 @@ class Chef::Application::Client < Chef::Application
219
231
  @chef_client = nil
220
232
  if Chef::Config[:interval]
221
233
  Chef::Log.debug("Sleeping for #{Chef::Config[:interval]} seconds")
222
- sleep Chef::Config[:interval]
234
+ unless SELF_PIPE.empty?
235
+ client_sleep Chef::Config[:interval]
236
+ else
237
+ # Windows
238
+ sleep Chef::Config[:interval]
239
+ end
223
240
  else
224
241
  Chef::Application.exit! "Exiting", 0
225
242
  end
243
+ rescue Chef::Application::Wakeup => e
244
+ Chef::Log.debug("Received Wakeup signal. Starting run.")
245
+ next
226
246
  rescue SystemExit => e
227
247
  raise
228
248
  rescue Exception => e
@@ -230,7 +250,12 @@ class Chef::Application::Client < Chef::Application
230
250
  Chef::Log.error("#{e.class}: #{e}")
231
251
  Chef::Application.debug_stacktrace(e)
232
252
  Chef::Log.error("Sleeping for #{Chef::Config[:interval]} seconds before trying again")
233
- sleep Chef::Config[:interval]
253
+ unless SELF_PIPE.empty?
254
+ client_sleep Chef::Config[:interval]
255
+ else
256
+ # Windows
257
+ sleep Chef::Config[:interval]
258
+ end
234
259
  retry
235
260
  else
236
261
  Chef::Application.debug_stacktrace(e)
@@ -241,4 +266,11 @@ class Chef::Application::Client < Chef::Application
241
266
  end
242
267
  end
243
268
  end
269
+
270
+ private
271
+
272
+ def client_sleep(sec)
273
+ IO.select([ SELF_PIPE[0] ], nil, nil, sec) or return
274
+ SELF_PIPE[0].getc
275
+ end
244
276
  end
@@ -106,7 +106,7 @@ class Chef
106
106
  # given by +file_location+ and saves the Checksum to the database
107
107
  def commit_sandbox_file(sandbox_file)
108
108
  @original_committed_file_location = sandbox_file
109
- Chef::Log.info("commiting sandbox file: move #{sandbox_file} to #{file_location}")
109
+ Chef::Log.info("Commiting sandbox file: move #{sandbox_file} to #{file_location}")
110
110
  FileUtils.mkdir_p(checksum_repo_directory)
111
111
  File.rename(sandbox_file, file_location)
112
112
  cdb_save
@@ -122,7 +122,7 @@ class Chef
122
122
  raise Chef::Exceptions::IllegalChecksumRevert, "Checksum #{self.inspect} cannot be reverted because the original sandbox file location is not known"
123
123
  end
124
124
 
125
- Chef::Log.warn("reverting sandbox file commit: moving #{file_location} back to #{original_committed_file_location}")
125
+ Chef::Log.warn("Reverting sandbox file commit: moving #{file_location} back to #{original_committed_file_location}")
126
126
  File.rename(file_location, original_committed_file_location)
127
127
  cdb_destroy
128
128
  end
@@ -78,7 +78,7 @@ class Chef
78
78
  end
79
79
 
80
80
  def self.cleanup_checksum_cache
81
- Chef::Log.info("cleaning the checksum cache")
81
+ Chef::Log.debug("Cleaning the checksum cache")
82
82
  if (Chef::Config[:cache_type].to_s == "BasicFile")
83
83
  all_cached_checksums.each do |cache_key, cksum_cache_file|
84
84
  unless valid_cached_checksums.include?(cache_key)
@@ -93,7 +93,7 @@ class Chef
93
93
  end
94
94
 
95
95
  def self.remove_unused_checksum(checksum_file)
96
- Chef::Log.debug("removing unused checksum cache file #{checksum_file}")
96
+ Chef::Log.debug("Removing unused checksum cache file #{checksum_file}")
97
97
  FileUtils.rm(checksum_file)
98
98
  end
99
99
 
@@ -152,7 +152,7 @@ class Chef
152
152
  begin
153
153
 
154
154
  run_status.start_clock
155
- Chef::Log.info("Starting Run for #{node.name}")
155
+ Chef::Log.info("Starting Chef Run for #{node.name}")
156
156
  run_started
157
157
 
158
158
  run_context = setup_run_context
@@ -261,7 +261,7 @@ class Chef
261
261
  @expanded_run_list_with_versions = @run_list_expansion.recipes.with_version_constraints_strings
262
262
 
263
263
  Chef::Log.info("Run List is [#{@node.run_list}]")
264
- Chef::Log.info("Run List expands (with versions) to [#{@expanded_run_list_with_versions.join(', ')}]")
264
+ Chef::Log.info("Run List expands to [#{@expanded_run_list_with_versions.join(', ')}]")
265
265
 
266
266
  @run_status = Chef::RunStatus.new(@node)
267
267
 
@@ -317,8 +317,10 @@ class Chef
317
317
  existing_paths = env["PATH"].split(':')
318
318
  SANE_PATHS.each do |sane_path|
319
319
  unless existing_paths.include?(sane_path)
320
- env["PATH"] << ':' unless env["PATH"].empty?
321
- env["PATH"] << sane_path
320
+ env_path = env["PATH"].dup
321
+ env_path << ':' unless env["PATH"].empty?
322
+ env_path << sane_path
323
+ env["PATH"] = env_path
322
324
  end
323
325
  end
324
326
  end
@@ -339,7 +341,7 @@ class Chef
339
341
  # Check for cookbooks in the path given
340
342
  # Chef::Config[:cookbook_path] can be a string or an array
341
343
  # if it's an array, go through it and check each one, raise error at the last one if no files are found
342
- Chef::Log.debug "loading from cookbook_path: #{Array(Chef::Config[:cookbook_path]).map { |path| File.expand_path(path) }.join(', ')}"
344
+ Chef::Log.debug "Loading from cookbook_path: #{Array(Chef::Config[:cookbook_path]).map { |path| File.expand_path(path) }.join(', ')}"
343
345
  Array(Chef::Config[:cookbook_path]).each_with_index do |cookbook_path, index|
344
346
  if directory_not_empty?(cookbook_path)
345
347
  break
@@ -62,7 +62,7 @@ class Chef
62
62
  if current_checksum != found_manifest_record['checksum']
63
63
  raw_file = @rest.get_rest(found_manifest_record[:url], true)
64
64
 
65
- Chef::Log.info("Storing updated #{cache_filename} in the cache.")
65
+ Chef::Log.debug("Storing updated #{cache_filename} in the cache.")
66
66
  Chef::FileCache.move_to(raw_file.path, cache_filename)
67
67
  else
68
68
  Chef::Log.debug("Not storing #{cache_filename}, as the cache is up to date.")
@@ -57,7 +57,7 @@ class Chef
57
57
  def untested_ruby_files
58
58
  ruby_files.reject do |file|
59
59
  if validated?(file)
60
- Chef::Log.debug("ruby file #{file} is unchanged, skipping syntax check")
60
+ Chef::Log.debug("Ruby file #{file} is unchanged, skipping syntax check")
61
61
  true
62
62
  else
63
63
  false
@@ -72,7 +72,7 @@ class Chef
72
72
  def untested_template_files
73
73
  template_files.reject do |file|
74
74
  if validated?(file)
75
- Chef::Log.debug("template #{file} is unchanged, skipping syntax check")
75
+ Chef::Log.debug("Template #{file} is unchanged, skipping syntax check")
76
76
  true
77
77
  else
78
78
  false
@@ -439,6 +439,11 @@ class Chef
439
439
  @checksums
440
440
  end
441
441
 
442
+ def manifest_records_by_path
443
+ @manifest_records_by_path || generate_manifest
444
+ @manifest_records_by_path
445
+ end
446
+
442
447
  def full_name
443
448
  "#{name}-#{version}"
444
449
  end
@@ -201,7 +201,7 @@ class Chef
201
201
 
202
202
  # Remove this Data Bag Item from CouchDB
203
203
  def cdb_destroy
204
- Chef::Log.debug "destroying data bag item: #{self.inspect}"
204
+ Chef::Log.debug "Destroying data bag item: #{self.inspect}"
205
205
  @couchdb.delete("data_bag_item", object_name, @couchdb_rev)
206
206
  end
207
207
 
@@ -18,7 +18,9 @@
18
18
  #
19
19
 
20
20
  require 'chef/config'
21
+ require 'chef/mash'
21
22
  require 'chef/mixin/params_validate'
23
+ require 'chef/mixin/from_file'
22
24
  require 'chef/couchdb'
23
25
  require 'chef/index_queue'
24
26
  require 'chef/version_constraint'
@@ -65,7 +67,8 @@ class Chef
65
67
  def initialize(couchdb=nil)
66
68
  @name = ''
67
69
  @description = ''
68
- @attributes = Mash.new
70
+ @default_attributes = Mash.new
71
+ @override_attributes = Mash.new
69
72
  @cookbook_versions = Hash.new
70
73
  @couchdb_rev = nil
71
74
  @couchdb_id = nil
@@ -101,9 +104,17 @@ class Chef
101
104
  )
102
105
  end
103
106
 
104
- def attributes(arg=nil)
107
+ def default_attributes(arg=nil)
105
108
  set_or_return(
106
- :attributes,
109
+ :default_attributes,
110
+ arg,
111
+ :kind_of => Hash
112
+ )
113
+ end
114
+
115
+ def override_attributes(arg=nil)
116
+ set_or_return(
117
+ :override_attributes,
107
118
  arg,
108
119
  :kind_of => Hash
109
120
  )
@@ -140,7 +151,8 @@ class Chef
140
151
  "cookbook_versions" => @cookbook_versions,
141
152
  "json_class" => self.class.name,
142
153
  "chef_type" => "environment",
143
- "attributes" => @attributes
154
+ "default_attributes" => @default_attributes,
155
+ "override_attributes" => @override_attributes
144
156
  }
145
157
  result["_rev"] = couchdb_rev if couchdb_rev
146
158
  result
@@ -153,10 +165,21 @@ class Chef
153
165
  def update_from!(o)
154
166
  description(o.description)
155
167
  cookbook_versions(o.cookbook_versions)
156
- attributes(o.attributes)
168
+ default_attributes(o.default_attributes)
169
+ override_attributes(o.override_attributes)
157
170
  self
158
171
  end
159
172
 
173
+
174
+ def update_attributes_from_params(params)
175
+ unless params[:default_attributes].nil? || params[:default_attributes].size == 0
176
+ default_attributes(Chef::JSONCompat.from_json(params[:default_attributes]))
177
+ end
178
+ unless params[:override_attributes].nil? || params[:override_attributes].size == 0
179
+ override_attributes(Chef::JSONCompat.from_json(params[:override_attributes]))
180
+ end
181
+ end
182
+
160
183
  def update_from_params(params)
161
184
  # reset because everything we need will be in the params, this is necessary because certain constraints
162
185
  # may have been removed in the params and need to be removed from cookbook_versions as well.
@@ -180,9 +203,7 @@ class Chef
180
203
  end
181
204
  end
182
205
 
183
- unless params[:attributes].nil? || params[:attributes].size == 0
184
- attributes(Chef::JSONCompat.from_json(params[:attributes]))
185
- end
206
+ update_attributes_from_params(params)
186
207
 
187
208
  valid = validate_required_attrs_present && valid
188
209
  cookbook_versions(bkup_cb_versions) unless valid # restore the old cookbook_versions if valid is false
@@ -228,7 +249,8 @@ class Chef
228
249
  environment.name(o["name"])
229
250
  environment.description(o["description"])
230
251
  environment.cookbook_versions(o["cookbook_versions"])
231
- environment.attributes(o["attributes"])
252
+ environment.default_attributes(o["default_attributes"])
253
+ environment.override_attributes(o["override_attributes"])
232
254
  environment.couchdb_rev = o["_rev"] if o.has_key?("_rev")
233
255
  environment.couchdb_id = o["_id"] if o.has_key?("_id")
234
256
  environment
@@ -84,8 +84,8 @@ class Chef
84
84
 
85
85
  def set_owner
86
86
  if (uid = target_uid) && (uid != stat.uid)
87
- Chef::Log.debug("setting owner on #{file} to #{uid}")
88
87
  File.chown(uid, nil, file)
88
+ Chef::Log.info("#{log_string} owner changed to #{uid}")
89
89
  modified
90
90
  end
91
91
  end
@@ -106,8 +106,8 @@ class Chef
106
106
 
107
107
  def set_group
108
108
  if (gid = target_gid) && (gid != stat.gid)
109
- Chef::Log.debug("setting group on #{file} to #{gid}")
110
109
  File.chown(nil, gid, file)
110
+ Chef::Log.info("#{log_string} owner changed to #{gid}")
111
111
  modified
112
112
  end
113
113
  end
@@ -119,8 +119,8 @@ class Chef
119
119
 
120
120
  def set_mode
121
121
  if (mode = target_mode) && (mode != (stat.mode & 007777))
122
- Chef::Log.debug("setting mode on #{file} to #{mode.to_s(8)}")
123
122
  File.chmod(target_mode, file)
123
+ Chef::Log.info("#{log_string} mode changed to #{mode.to_s(8)}")
124
124
  modified
125
125
  end
126
126
  end
@@ -135,6 +135,10 @@ class Chef
135
135
  def modified
136
136
  @modified = true
137
137
  end
138
+
139
+ def log_string
140
+ @resource || @file
141
+ end
138
142
 
139
143
  end
140
144
  end
@@ -66,7 +66,7 @@ class Chef
66
66
  end
67
67
 
68
68
  def add_to_index(metadata={})
69
- Chef::Log.debug("pushing item to index queue for addition: #{self.with_indexer_metadata(metadata)}")
69
+ Chef::Log.debug("Pushing item to index queue for addition: #{self.with_indexer_metadata(metadata)}")
70
70
  object_with_metadata = with_indexer_metadata(metadata)
71
71
  obj_id = object_with_metadata["id"]
72
72
  obj = {:action => :add, :payload => self.with_indexer_metadata(metadata)}
@@ -75,7 +75,7 @@ class Chef
75
75
  end
76
76
 
77
77
  def delete_from_index(metadata={})
78
- Chef::Log.debug("pushing item to index queue for deletion: #{self.with_indexer_metadata(metadata)}")
78
+ Chef::Log.debug("Pushing item to index queue for deletion: #{self.with_indexer_metadata(metadata)}")
79
79
  object_with_metadata = with_indexer_metadata(metadata)
80
80
  obj_id = object_with_metadata["id"]
81
81
  obj = {:action => :delete, :payload => self.with_indexer_metadata(metadata)}
@@ -291,7 +291,7 @@ class Chef
291
291
  self.msg("No knife configuration file found")
292
292
  end
293
293
 
294
- config[:color] = config[:color] && !config[:no_color]
294
+ Chef::Config[:color] = config[:color] && !config[:no_color]
295
295
 
296
296
  case config[:verbosity]
297
297
  when 0
@@ -31,7 +31,7 @@ class Chef
31
31
  require 'net/ssh/multi'
32
32
  end
33
33
 
34
- banner "knife bootstrap FQDN [RUN LIST...] (options)"
34
+ banner "knife bootstrap FQDN (options)"
35
35
 
36
36
  option :ssh_user,
37
37
  :short => "-x USERNAME",
@@ -95,7 +95,7 @@ class Chef
95
95
 
96
96
  if config[:deps]
97
97
  md = Chef::Cookbook::Metadata.new
98
- md.from_file(File.join(cookbook_path, "metadata.rb"))
98
+ md.from_file(File.join(@install_path, @cookbook_name, "metadata.rb"))
99
99
  md.dependencies.each do |cookbook, version_list|
100
100
  # Doesn't do versions.. yet
101
101
  nv = Chef::Knife::CookbookSiteVendor.new
@@ -50,10 +50,10 @@ class Chef
50
50
  cl = Chef::CookbookLoader.new(config[:cookbook_path])
51
51
  if cl.cookbook_exists?(cookbook_name)
52
52
  cookbook = cl[cookbook_name]
53
- Chef::CookbookUploader.validate_cookbook(cookbook)
53
+ Chef::CookbookUploader.new(cookbook,config[:cookbook_path]).validate_cookbook
54
54
  tmp_cookbook_dir = Chef::CookbookSiteStreamingUploader.create_build_dir(cookbook)
55
55
  begin
56
- Chef::Log.debug("temp cookbook directory is #{tmp_cookbook_dir.inspect}")
56
+ Chef::Log.debug("Temp cookbook directory is #{tmp_cookbook_dir.inspect}")
57
57
  ui.info("Making tarball #{cookbook_name}.tgz")
58
58
  Chef::Mixin::Command.run_command(:command => "tar -czf #{cookbook_name}.tgz #{cookbook_name}", :cwd => tmp_cookbook_dir)
59
59
  rescue => e
@@ -23,6 +23,9 @@ class Chef
23
23
  class Knife
24
24
  class CookbookUpload < Knife
25
25
 
26
+ CHECKSUM = "checksum"
27
+ MATCH_CHECKSUM = /[0-9a-f]{32,}/
28
+
26
29
  deps do
27
30
  require 'chef/exceptions'
28
31
  require 'chef/cookbook_loader'
@@ -55,7 +58,8 @@ class Chef
55
58
  option :environment,
56
59
  :short => '-E',
57
60
  :long => '--environment ENVIRONMENT',
58
- :description => "Set ENVIRONMENT's version dependency match the version you're uploading."
61
+ :description => "Set ENVIRONMENT's version dependency match the version you're uploading.",
62
+ :default => nil
59
63
 
60
64
  def run
61
65
  config[:cookbook_path] ||= Chef::Config[:cookbook_path]
@@ -72,7 +76,7 @@ class Chef
72
76
  else
73
77
  if @name_args.empty?
74
78
  show_usage
75
- Chef::Log.fatal("You must specify the --all flag or at least one cookbook name")
79
+ ui.error("You must specify the --all flag or at least one cookbook name")
76
80
  exit 1
77
81
  end
78
82
  @name_args.each do |cookbook_name|
@@ -82,12 +86,13 @@ class Chef
82
86
  upload(cookbook)
83
87
  version_constraints_to_update[cookbook_name] = cookbook.version
84
88
  rescue Exceptions::CookbookNotFoundInRepo => e
85
- Log.error("Could not find cookbook #{cookbook_name} in your cookbook path, skipping it")
89
+ ui.error("Could not find cookbook #{cookbook_name} in your cookbook path, skipping it")
86
90
  Log.debug(e)
87
91
  end
88
92
  end
89
93
  end
90
94
 
95
+ ui.info "upload complete"
91
96
  update_version_constraints(version_constraints_to_update) if config[:environment]
92
97
  end
93
98
 
@@ -107,7 +112,7 @@ class Chef
107
112
 
108
113
 
109
114
  def environment
110
- @environment ||= Environment.load(config[:environment])
115
+ @environment ||= config[:environment] ? Environment.load(config[:environment]) : nil
111
116
  end
112
117
 
113
118
  private
@@ -116,7 +121,7 @@ class Chef
116
121
  environment
117
122
  rescue Net::HTTPServerException => e
118
123
  if e.response.code.to_s == "404"
119
- Log.error "The environment #{config[:environment]} does not exist on the server"
124
+ ui.error "The environment #{config[:environment]} does not exist on the server, aborting."
120
125
  Log.debug(e)
121
126
  exit 1
122
127
  else
@@ -125,22 +130,38 @@ class Chef
125
130
  end
126
131
 
127
132
  def upload(cookbook)
128
- Chef::Log.info("** #{cookbook.name} **")
133
+ if config[:all]
134
+ ui.info("** #{cookbook.name} **")
135
+ else
136
+ ui.info "Uploading #{cookbook.name}..."
137
+ end
138
+ check_for_broken_links(cookbook)
129
139
  Chef::CookbookUploader.new(cookbook, config[:cookbook_path], :force => config[:force]).upload_cookbook
130
140
  rescue Net::HTTPServerException => e
131
141
  case e.response.code
132
- when "401"
133
- Log.error "Request failed due to authentication (#{e}), check your client configuration (username, key)"
134
- Log.debug(e)
135
- exit 18
136
142
  when "409"
137
- Log.error "Version #{cookbook.version} of cookbook #{cookbook.name} is frozen. Use --force to override."
143
+ ui.error "Version #{cookbook.version} of cookbook #{cookbook.name} is frozen. Use --force to override."
138
144
  Log.debug(e)
139
145
  else
140
146
  raise
141
147
  end
142
148
  end
143
149
 
150
+ # if only you people wouldn't put broken symlinks in your cookbooks in
151
+ # the first place. ;)
152
+ def check_for_broken_links(cookbook)
153
+ broken_files = cookbook.manifest_records_by_path.select do |path, info|
154
+ info[CHECKSUM].nil? || info[CHECKSUM] !~ MATCH_CHECKSUM
155
+ end
156
+ unless broken_files.empty?
157
+ broken_filenames = Array(broken_files).map {|path, info| path}
158
+ ui.error "The cookbook #{cookbook.name} has one or more broken files"
159
+ ui.info "This is probably caused by broken symlinks in the cookbook directory"
160
+ ui.info "The broken file(s) are: #{broken_filenames.join(' ')}"
161
+ exit 1
162
+ end
163
+ end
164
+
144
165
  end
145
166
  end
146
167
  end