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

Sign up to get free protection for your applications and to get access to all the features.
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