chef 10.14.0.beta.2 → 10.14.0.beta.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (100) hide show
  1. data/distro/common/html/chef-client.8.html +3 -3
  2. data/distro/common/html/chef-expander.8.html +3 -3
  3. data/distro/common/html/chef-expanderctl.8.html +3 -3
  4. data/distro/common/html/chef-server-webui.8.html +3 -3
  5. data/distro/common/html/chef-server.8.html +3 -3
  6. data/distro/common/html/chef-solo.8.html +3 -3
  7. data/distro/common/html/chef-solr.8.html +3 -3
  8. data/distro/common/html/knife-bootstrap.1.html +3 -3
  9. data/distro/common/html/knife-client.1.html +3 -3
  10. data/distro/common/html/knife-configure.1.html +4 -4
  11. data/distro/common/html/knife-cookbook-site.1.html +6 -6
  12. data/distro/common/html/knife-cookbook.1.html +3 -3
  13. data/distro/common/html/knife-data-bag.1.html +3 -3
  14. data/distro/common/html/knife-environment.1.html +6 -6
  15. data/distro/common/html/knife-exec.1.html +4 -4
  16. data/distro/common/html/knife-index.1.html +3 -3
  17. data/distro/common/html/knife-node.1.html +3 -3
  18. data/distro/common/html/knife-role.1.html +3 -3
  19. data/distro/common/html/knife-search.1.html +3 -3
  20. data/distro/common/html/knife-ssh.1.html +4 -4
  21. data/distro/common/html/knife-status.1.html +4 -4
  22. data/distro/common/html/knife-tag.1.html +4 -4
  23. data/distro/common/html/knife.1.html +3 -3
  24. data/distro/common/html/shef.1.html +7 -7
  25. data/distro/common/man/man1/knife-bootstrap.1 +1 -1
  26. data/distro/common/man/man1/knife-client.1 +1 -1
  27. data/distro/common/man/man1/knife-configure.1 +1 -1
  28. data/distro/common/man/man1/knife-cookbook-site.1 +1 -1
  29. data/distro/common/man/man1/knife-cookbook.1 +1 -1
  30. data/distro/common/man/man1/knife-data-bag.1 +1 -1
  31. data/distro/common/man/man1/knife-environment.1 +1 -1
  32. data/distro/common/man/man1/knife-exec.1 +1 -1
  33. data/distro/common/man/man1/knife-index.1 +1 -1
  34. data/distro/common/man/man1/knife-node.1 +1 -1
  35. data/distro/common/man/man1/knife-role.1 +1 -1
  36. data/distro/common/man/man1/knife-search.1 +1 -1
  37. data/distro/common/man/man1/knife-ssh.1 +1 -1
  38. data/distro/common/man/man1/knife-status.1 +1 -1
  39. data/distro/common/man/man1/knife-tag.1 +1 -1
  40. data/distro/common/man/man1/knife.1 +1 -1
  41. data/distro/common/man/man1/shef.1 +1 -1
  42. data/distro/common/man/man8/chef-client.8 +1 -1
  43. data/distro/common/man/man8/chef-expander.8 +1 -1
  44. data/distro/common/man/man8/chef-expanderctl.8 +1 -1
  45. data/distro/common/man/man8/chef-server-webui.8 +1 -1
  46. data/distro/common/man/man8/chef-server.8 +1 -1
  47. data/distro/common/man/man8/chef-solo.8 +1 -1
  48. data/distro/common/man/man8/chef-solr.8 +1 -1
  49. data/lib/chef/application/client.rb +6 -2
  50. data/lib/chef/application/solo.rb +7 -3
  51. data/lib/chef/application/windows_service.rb +1 -2
  52. data/lib/chef/client.rb +72 -47
  53. data/lib/chef/config.rb +3 -1
  54. data/lib/chef/cookbook_uploader.rb +28 -18
  55. data/lib/chef/cookbook_version.rb +2 -2
  56. data/lib/chef/event_dispatch/base.rb +4 -0
  57. data/lib/chef/exceptions.rb +1 -0
  58. data/lib/chef/formatters/base.rb +13 -9
  59. data/lib/chef/formatters/error_inspectors/compile_error_inspector.rb +12 -6
  60. data/lib/chef/formatters/error_inspectors/resource_failure_inspector.rb +1 -2
  61. data/lib/chef/formatters/error_mapper.rb +13 -6
  62. data/lib/chef/knife/bootstrap.rb +4 -4
  63. data/lib/chef/knife/bootstrap/ubuntu12.04-gems.erb +2 -2
  64. data/lib/chef/knife/client_create.rb +1 -0
  65. data/lib/chef/knife/cookbook_upload.rb +60 -33
  66. data/lib/chef/knife/core/node_presenter.rb +1 -0
  67. data/lib/chef/knife/tag_delete.rb +1 -1
  68. data/lib/chef/mixin/file_class.rb +46 -0
  69. data/lib/chef/provider/cron.rb +1 -1
  70. data/lib/chef/provider/deploy.rb +1 -1
  71. data/lib/chef/provider/link.rb +2 -18
  72. data/lib/chef/provider/package/apt.rb +7 -4
  73. data/lib/chef/provider/remote_directory.rb +17 -5
  74. data/lib/chef/provider/user/useradd.rb +1 -0
  75. data/lib/chef/resource_reporter.rb +4 -4
  76. data/lib/chef/rest.rb +8 -0
  77. data/lib/chef/run_context.rb +4 -1
  78. data/lib/chef/solr_query/lucene.treetop +2 -2
  79. data/lib/chef/version.rb +1 -1
  80. data/spec/support/shared/functional/file_resource.rb +2 -1
  81. data/spec/support/shared/functional/securable_resource.rb +28 -12
  82. data/spec/unit/client_spec.rb +49 -13
  83. data/spec/unit/formatters/error_inspectors/resource_failure_inspector_spec.rb +21 -1
  84. data/spec/unit/knife/config_file_selection_spec.rb +5 -4
  85. data/spec/unit/knife/cookbook_upload_spec.rb +4 -3
  86. data/spec/unit/mixin/enforce_ownership_and_permissions_spec.rb +21 -0
  87. data/spec/unit/provider/cookbook_file_spec.rb +2 -0
  88. data/spec/unit/provider/cron_spec.rb +46 -0
  89. data/spec/unit/provider/deploy_spec.rb +12 -0
  90. data/spec/unit/provider/execute_spec.rb +3 -0
  91. data/spec/unit/provider/file_spec.rb +9 -6
  92. data/spec/unit/provider/package/apt_spec.rb +13 -0
  93. data/spec/unit/provider/remote_directory_spec.rb +16 -5
  94. data/spec/unit/provider/template_spec.rb +10 -0
  95. data/spec/unit/provider/user/useradd_spec.rb +2 -2
  96. data/spec/unit/provider/user_spec.rb +28 -17
  97. data/spec/unit/resource/file_spec.rb +14 -7
  98. data/spec/unit/resource/template_spec.rb +13 -6
  99. data/spec/unit/solr_query/query_transform_spec.rb +4 -0
  100. metadata +5 -4
@@ -53,7 +53,8 @@ class Chef
53
53
 
54
54
  if RUBY_PLATFORM =~ /mswin|mingw|windows/
55
55
  # turns /etc/chef/client.rb into C:/chef/client.rb
56
- path = File.join(ENV['SYSTEMDRIVE'], path.split('/')[2..-1])
56
+ system_drive = ENV['SYSTEMDRIVE'] ? ENV['SYSTEMDRIVE'] : ""
57
+ path = File.join(system_drive, path.split('/')[2..-1])
57
58
  # ensure all forward slashes are backslashes
58
59
  path.gsub!(File::SEPARATOR, (File::ALT_SEPARATOR || '\\'))
59
60
  end
@@ -195,6 +196,7 @@ class Chef
195
196
  splay nil
196
197
  why_run false
197
198
  color false
199
+ client_fork false
198
200
 
199
201
  # Set these to enable SSL authentication / mutual-authentication
200
202
  # with the server
@@ -29,14 +29,15 @@ class Chef
29
29
  end
30
30
  end
31
31
 
32
- attr_reader :cookbook
32
+ attr_reader :cookbooks
33
33
  attr_reader :path
34
34
  attr_reader :opts
35
35
  attr_reader :rest
36
36
 
37
37
  # Creates a new CookbookUploader.
38
38
  # ===Arguments:
39
- # * cookbook::: A Chef::CookbookVersion describing the cookbook to be uploaded
39
+ # * cookbooks::: A Chef::CookbookVersion or array of them describing the
40
+ # cookbook(s) to be uploaded
40
41
  # * path::: A String or Array of Strings representing the base paths to the
41
42
  # cookbook repositories.
42
43
  # * opts::: (optional) An options Hash
@@ -48,19 +49,24 @@ class Chef
48
49
  # * :rest A Chef::REST object that you have configured the way you like it.
49
50
  # If you don't provide this, one will be created using the values
50
51
  # in Chef::Config.
51
- def initialize(cookbook, path, opts={})
52
- @cookbook, @path, @opts = cookbook, path, opts
52
+ def initialize(cookbooks, path, opts={})
53
+ @path, @opts = path, opts
54
+ @cookbooks = Array(cookbooks)
53
55
  @rest = opts[:rest] || Chef::REST.new(Chef::Config[:chef_server_url])
54
56
  end
55
57
 
56
- def upload_cookbook
58
+ def upload_cookbooks
57
59
  Thread.abort_on_exception = true
58
- Chef::Log.info("Saving #{cookbook.name}")
59
60
 
60
61
  # Syntax Check
61
- validate_cookbook
62
+ validate_cookbooks
62
63
  # generate checksums of cookbook files and create a sandbox
63
- checksum_files = cookbook.checksums
64
+ checksum_files = {}
65
+ cookbooks.each do |cb|
66
+ Chef::Log.info("Saving #{cb.name}")
67
+ checksum_files.merge!(cb.checksums)
68
+ end
69
+
64
70
  checksums = checksum_files.inject({}){|memo,elt| memo[elt.first]=nil ; memo}
65
71
  new_sandbox = rest.post_rest("sandboxes", { :checksums => checksums })
66
72
 
@@ -102,8 +108,10 @@ class Chef
102
108
  end
103
109
 
104
110
  # files are uploaded, so save the manifest
105
- save_url = opts[:force] ? cookbook.force_save_url : cookbook.save_url
106
- rest.put_rest(save_url, cookbook)
111
+ cookbooks.each do |cb|
112
+ save_url = opts[:force] ? cb.force_save_url : cb.save_url
113
+ rest.put_rest(save_url, cb)
114
+ end
107
115
 
108
116
  Chef::Log.info("Upload complete!")
109
117
  end
@@ -140,14 +148,16 @@ class Chef
140
148
  end
141
149
  end
142
150
 
143
- def validate_cookbook
144
- syntax_checker = Chef::Cookbook::SyntaxCheck.for_cookbook(cookbook.name, @user_cookbook_path)
145
- Chef::Log.info("Validating ruby files")
146
- exit(1) unless syntax_checker.validate_ruby_files
147
- Chef::Log.info("Validating templates")
148
- exit(1) unless syntax_checker.validate_templates
149
- Chef::Log.info("Syntax OK")
150
- true
151
+ def validate_cookbooks
152
+ cookbooks.each do |cb|
153
+ syntax_checker = Chef::Cookbook::SyntaxCheck.for_cookbook(cb.name, @user_cookbook_path)
154
+ Chef::Log.info("Validating ruby files")
155
+ exit(1) unless syntax_checker.validate_ruby_files
156
+ Chef::Log.info("Validating templates")
157
+ exit(1) unless syntax_checker.validate_templates
158
+ Chef::Log.info("Syntax OK")
159
+ true
160
+ end
151
161
  end
152
162
 
153
163
  end
@@ -544,7 +544,7 @@ class Chef
544
544
  # called from DSL
545
545
  def load_recipe(recipe_name, run_context)
546
546
  unless recipe_filenames_by_name.has_key?(recipe_name)
547
- raise ArgumentError, "Cannot find a recipe matching #{recipe_name} in cookbook #{name}"
547
+ raise Chef::Exceptions::RecipeNotFound, "could not find recipe #{recipe_name} for cookbook #{name}"
548
548
  end
549
549
 
550
550
  Chef::Log.debug("Found recipe #{recipe_name} in cookbook #{name}")
@@ -552,7 +552,7 @@ class Chef
552
552
  recipe_filename = recipe_filenames_by_name[recipe_name]
553
553
 
554
554
  unless recipe_filename
555
- raise Chef::Exceptions::RecipeNotFound, "could not find recipe #{recipe_name} for cookbook #{name}"
555
+ raise Chef::Exceptions::RecipeNotFound, "could not find #{recipe_name} files for cookbook #{name}"
556
556
  end
557
557
 
558
558
  recipe.from_file(recipe_filename)
@@ -206,6 +206,10 @@ class Chef
206
206
  def recipe_file_load_failed(path, exception)
207
207
  end
208
208
 
209
+ # Called when a recipe cannot be resolved
210
+ def recipe_not_found(exception)
211
+ end
212
+
209
213
  # Called when recipes have been loaded.
210
214
  def recipe_load_complete
211
215
  end
@@ -53,6 +53,7 @@ class Chef
53
53
  # Cookbook loader used to raise an argument error when cookbook not found.
54
54
  # for back compat, need to raise an error that inherits from ArgumentError
55
55
  class CookbookNotFoundInRepo < ArgumentError; end
56
+ class RecipeNotFound < ArgumentError; end
56
57
  class AttributeNotFound < RuntimeError; end
57
58
  class InvalidCommandOption < RuntimeError; end
58
59
  class CommandTimeout < RuntimeError; end
@@ -129,32 +129,32 @@ class Chef
129
129
 
130
130
  def registration_failed(node_name, exception, config)
131
131
  #A Formatters::ErrorDescription object
132
- description = ErrorMapper.registration_failed_helper(node_name, exception, config)
132
+ description = ErrorMapper.registration_failed(node_name, exception, config)
133
133
  display_error(description)
134
134
  end
135
135
 
136
136
  def node_load_failed(node_name, exception, config)
137
- description = ErrorMapper.node_load_failed_helper(node_name, exception, config)
137
+ description = ErrorMapper.node_load_failed(node_name, exception, config)
138
138
  display_error(description)
139
139
  end
140
140
 
141
141
  def run_list_expand_failed(node, exception)
142
- description = ErrorMapper.run_list_expand_failed_helper(node, exception)
142
+ description = ErrorMapper.run_list_expand_failed(node, exception)
143
143
  display_error(description)
144
144
  end
145
145
 
146
146
  def cookbook_resolution_failed(expanded_run_list, exception)
147
- description = ErrorMapper.cookbook_resolution_failed_helper(expanded_run_list, exception)
147
+ description = ErrorMapper.cookbook_resolution_failed(expanded_run_list, exception)
148
148
  display_error(description)
149
149
  end
150
150
 
151
151
  def cookbook_sync_failed(cookbooks, exception)
152
- description = ErrorMapper.cookbook_sync_failed_helper(cookbooks, exception)
152
+ description = ErrorMapper.cookbook_sync_failed(cookbooks, exception)
153
153
  display_error(description)
154
154
  end
155
155
 
156
156
  def resource_failed(resource, action, exception)
157
- description = ErrorMapper.resource_failed_helper(resource, action, exception)
157
+ description = ErrorMapper.resource_failed(resource, action, exception)
158
158
  display_error(description)
159
159
  end
160
160
 
@@ -171,9 +171,13 @@ class Chef
171
171
  # exception when loaded. Default behavior is to use CompileErrorInspector
172
172
  # to print contextual info about the failure.
173
173
  def file_load_failed(path, exception)
174
- error_inspector = ErrorInspectors::CompileErrorInspector.new(path, exception)
175
- headline = "Error compiling #{path}"
176
- describe_error(headline, error_inspector)
174
+ description = ErrorMapper.file_load_failed(path, exception)
175
+ display_error(description)
176
+ end
177
+
178
+ def recipe_not_found(exception)
179
+ description = ErrorMapper.file_load_failed(nil, exception)
180
+ display_error(description)
177
181
  end
178
182
 
179
183
  # Delegates to #file_loaded
@@ -33,11 +33,16 @@ class Chef
33
33
  end
34
34
 
35
35
  def add_explanation(error_description)
36
- error_description.section(exception.class.name, exception.message)
37
-
38
- traceback = filtered_bt.map {|line| " #{line}"}.join("\n")
39
- error_description.section("Cookbook Trace:", traceback)
40
- error_description.section("Relevant File Content:", context)
36
+ case exception
37
+ when Chef::Exceptions::RecipeNotFound
38
+ error_description.section(exception.class.name, exception.message)
39
+ else
40
+ error_description.section(exception.class.name, exception.message)
41
+
42
+ traceback = filtered_bt.map {|line| " #{line}"}.join("\n")
43
+ error_description.section("Cookbook Trace:", traceback)
44
+ error_description.section("Relevant File Content:", context)
45
+ end
41
46
  end
42
47
 
43
48
  def context
@@ -80,7 +85,8 @@ class Chef
80
85
  end
81
86
 
82
87
  def filtered_bt
83
- exception.backtrace.select {|l| l =~ /^#{Chef::Config.file_cache_path}/ }
88
+ r = exception.backtrace.select {|l| l =~ /^#{Chef::Config.file_cache_path}/ }
89
+ return r.count > 0 ? r : exception.backtrace
84
90
  end
85
91
 
86
92
  end
@@ -49,7 +49,7 @@ class Chef
49
49
  def recipe_snippet
50
50
  return nil if dynamic_resource?
51
51
  @snippet ||= begin
52
- if file = resource.source_line[/^([^:]+):[\d]+/,1] and line = resource.source_line[/^#{file}:([\d]+)/,1].to_i
52
+ if file = resource.source_line[/^(([\w]:)?[^:]+):([\d]+)/,1] and line = resource.source_line[/^#{file}:([\d]+)/,1].to_i
53
53
  lines = IO.readlines(file)
54
54
 
55
55
  relevant_lines = ["# In #{file}\n\n"]
@@ -74,7 +74,6 @@ class Chef
74
74
  break if nesting <= 0
75
75
  end
76
76
  relevant_lines << format_line(current_line + 1, lines[current_line + 1]) if lines[current_line + 1]
77
-
78
77
  relevant_lines.join("")
79
78
  end
80
79
  end
@@ -25,7 +25,7 @@ class Chef
25
25
  module ErrorMapper
26
26
 
27
27
  # Failed to register this client with the server.
28
- def self.registration_failed_helper(node_name, exception, config)
28
+ def self.registration_failed(node_name, exception, config)
29
29
  error_inspector = ErrorInspectors::RegistrationErrorInspector.new(node_name, exception, config)
30
30
  headline = "Chef encountered an error attempting to create the client \"#{node_name}\""
31
31
  description = ErrorDescription.new(headline)
@@ -33,7 +33,7 @@ class Chef
33
33
  return description
34
34
  end
35
35
 
36
- def self.node_load_failed_helper(node_name, exception, config)
36
+ def self.node_load_failed(node_name, exception, config)
37
37
  error_inspector = ErrorInspectors::NodeLoadErrorInspector.new(node_name, exception, config)
38
38
  headline = "Chef encountered an error attempting to load the node data for \"#{node_name}\""
39
39
  description = ErrorDescription.new(headline)
@@ -41,7 +41,7 @@ class Chef
41
41
  return description
42
42
  end
43
43
 
44
- def self.run_list_expand_failed_helper(node, exception)
44
+ def self.run_list_expand_failed(node, exception)
45
45
  error_inspector = ErrorInspectors::RunListExpansionErrorInspector.new(node, exception)
46
46
  headline = "Error expanding the run_list:"
47
47
  description = ErrorDescription.new(headline)
@@ -49,7 +49,7 @@ class Chef
49
49
  return description
50
50
  end
51
51
 
52
- def self.cookbook_resolution_failed_helper(expanded_run_list, exception)
52
+ def self.cookbook_resolution_failed(expanded_run_list, exception)
53
53
  error_inspector = ErrorInspectors::CookbookResolveErrorInspector.new(expanded_run_list, exception)
54
54
  headline = "Error Resolving Cookbooks for Run List:"
55
55
  description = ErrorDescription.new(headline)
@@ -57,7 +57,7 @@ class Chef
57
57
  return description
58
58
  end
59
59
 
60
- def self.cookbook_sync_failed_helper(cookbooks, exception)
60
+ def self.cookbook_sync_failed(cookbooks, exception)
61
61
  error_inspector = ErrorInspectors::CookbookSyncErrorInspector.new(cookbooks, exception)
62
62
  headline = "Error Syncing Cookbooks:"
63
63
  description = ErrorDescription.new(headline)
@@ -65,7 +65,7 @@ class Chef
65
65
  return description
66
66
  end
67
67
 
68
- def self.resource_failed_helper(resource, action, exception)
68
+ def self.resource_failed(resource, action, exception)
69
69
  error_inspector = ErrorInspectors::ResourceFailureInspector.new(resource, action, exception)
70
70
  headline = "Error executing action `#{action}` on resource '#{resource}'"
71
71
  description = ErrorDescription.new(headline)
@@ -73,6 +73,13 @@ class Chef
73
73
  return description
74
74
  end
75
75
 
76
+ def self.file_load_failed(path, exception)
77
+ error_inspector = ErrorInspectors::CompileErrorInspector.new(path, exception)
78
+ headline = "Recipe Compile Error" + ( path ? " in #{path}" : "" )
79
+ description = ErrorDescription.new(headline)
80
+ error_inspector.add_explanation(description)
81
+ description
82
+ end
76
83
  end
77
84
  end
78
85
  end
@@ -120,13 +120,13 @@ class Chef
120
120
  :boolean => true,
121
121
  :default => true
122
122
 
123
- Chef::Config[:knife][:hints] ||= Hash.new
124
123
  option :hint,
125
124
  :long => "--hint HINT_NAME[=HINT_FILE]",
126
125
  :description => "Specify Ohai Hint to be set on the bootstrap target. Use multiple --hint options to specify multiple hints.",
127
126
  :proc => Proc.new { |h|
128
- name, path = h.split("=")
129
- Chef::Config[:knife][:hints][name] = path ? JSON.parse(::File.read(path)) : Hash.new }
127
+ Chef::Config[:knife][:hints] ||= Hash.new
128
+ name, path = h.split("=")
129
+ Chef::Config[:knife][:hints][name] = path ? JSON.parse(::File.read(path)) : Hash.new }
130
130
 
131
131
  def load_template(template=nil)
132
132
  # Are we bootstrapping using an already shipped template?
@@ -176,7 +176,7 @@ class Chef
176
176
  knife_ssh.run
177
177
  rescue Net::SSH::AuthenticationFailed
178
178
  unless config[:ssh_password]
179
- puts "Failed to authenticate #{config[:ssh_user]} - trying password auth"
179
+ ui.info("Failed to authenticate #{config[:ssh_user]} - trying password auth")
180
180
  knife_ssh_with_password_auth.run
181
181
  end
182
182
  end
@@ -51,8 +51,8 @@ EOP
51
51
 
52
52
  (
53
53
  cat <<'EOP'
54
- <%= { "run_list" => @run_list }.to_json %>
54
+ <%= first_boot.to_json %>
55
55
  EOP
56
56
  ) > /etc/chef/first-boot.json
57
57
 
58
- <%= start_chef %>'
58
+ <%= start_chef %>'
@@ -71,6 +71,7 @@ class Chef
71
71
  end
72
72
  else
73
73
  ui.error "Client '#{client['name']}' already exists"
74
+ exit 1
74
75
  end
75
76
  end
76
77
  end
@@ -94,31 +94,56 @@ class Chef
94
94
  # Get a list of cookbooks and their versions from the server
95
95
  # to check for the existence of a cookbook's dependencies.
96
96
  @server_side_cookbooks = Chef::CookbookVersion.list_all_versions
97
+ justify_width = @server_side_cookbooks.map {|name| name.size}.max.to_i + 2
98
+ if config[:all]
97
99
 
98
- justify_width = cookbooks_to_upload.map {|name, cookbook| name.size}.max.to_i + 2
99
-
100
- cookbooks_to_upload.each do |cookbook_name, cookbook|
101
- cookbook.freeze_version if config[:freeze]
102
- begin
103
- upload(cookbook, justify_width)
104
- upload_ok += 1
100
+ cbs = []
101
+ cookbook_repo.each do |cookbook_name, cookbook|
102
+ cbs << cookbook
103
+ cookbook.freeze_version if config[:freeze]
105
104
  version_constraints_to_update[cookbook_name] = cookbook.version
105
+ end
106
+ begin
107
+ upload(cbs, justify_width)
106
108
  rescue Exceptions::CookbookFrozen
107
- upload_failures += 1
108
- ui.warn("Not updating version constraints for #{cookbook_name} in the environment as the cookbook is frozen.") if config[:environment]
109
+ ui.warn("Not updating version constraints for some cookbooks in the environment as the cookbook is frozen.")
110
+ end
111
+ ui.info("Uploaded all cookbooks.")
112
+ else
113
+ if @name_args.empty?
114
+ show_usage
115
+ ui.error("You must specify the --all flag or at least one cookbook name")
116
+ exit 1
117
+ end
118
+
119
+ cookbooks_to_upload.each do |cookbook_name, cookbook|
120
+ cookbook.freeze_version if config[:freeze]
121
+ begin
122
+ upload([cookbook], justify_width)
123
+ upload_ok += 1
124
+ version_constraints_to_update[cookbook_name] = cookbook.version
125
+ rescue Exceptions::CookbookNotFoundInRepo => e
126
+ upload_failures += 1
127
+ ui.error("Could not find cookbook #{cookbook_name} in your cookbook path, skipping it")
128
+ Log.debug(e)
129
+ upload_failures += 1
130
+ rescue Exceptions::CookbookFrozen
131
+ ui.warn("Not updating version constraints for #{cookbook_name} in the environment as the cookbook is frozen.")
132
+ upload_failures += 1
133
+ end
109
134
  end
110
- end
111
135
 
112
- upload_failures += config[:all] ? 0 : @name_args.length - @cookbooks_to_upload.length
136
+ upload_failures += @name_args.length - @cookbooks_to_upload.length
113
137
 
114
- if upload_failures == 0
115
- ui.info "Uploaded #{upload_ok} cookbook#{upload_ok > 1 ? "s" : ""}."
116
- elsif upload_failures > 0 && upload_ok > 0
117
- ui.warn "Uploaded #{upload_ok} cookbook#{upload_ok > 1 ? "s" : ""} ok but #{upload_failures} " +
118
- "cookbook#{upload_failures > 1 ? "s" : ""} upload failed."
119
- elsif upload_failures > 0 && upload_ok == 0
120
- ui.error "Failed to upload #{upload_failures} cookbook#{upload_failures > 1 ? "s" : ""}."
121
- exit 1
138
+ if upload_failures == 0
139
+ ui.info "Uploaded #{upload_ok} cookbook#{upload_ok > 1 ? "s" : ""}."
140
+ elsif upload_failures > 0 && upload_ok > 0
141
+ ui.warn "Uploaded #{upload_ok} cookbook#{upload_ok > 1 ? "s" : ""} ok but #{upload_failures} " +
142
+ "cookbook#{upload_failures > 1 ? "s" : ""} upload failed."
143
+ elsif upload_failures > 0 && upload_ok == 0
144
+ ui.error "Failed to upload #{upload_failures} cookbook#{upload_failures > 1 ? "s" : ""}."
145
+ exit 1
146
+ end
122
147
  end
123
148
 
124
149
  unless version_constraints_to_update.empty?
@@ -133,18 +158,18 @@ class Chef
133
158
  else
134
159
  upload_set = {}
135
160
  @name_args.each do |cookbook_name|
136
- begin
137
- if ! upload_set.has_key?(cookbook_name)
138
- upload_set[cookbook_name] = cookbook_repo[cookbook_name]
139
- if config[:depends]
140
- upload_set[cookbook_name].metadata.dependencies.each { |dep, ver| @name_args << dep }
161
+ begin
162
+ if ! upload_set.has_key?(cookbook_name)
163
+ upload_set[cookbook_name] = cookbook_repo[cookbook_name]
164
+ if config[:depends]
165
+ upload_set[cookbook_name].metadata.dependencies.each { |dep, ver| @name_args << dep }
166
+ end
141
167
  end
168
+ rescue Exceptions::CookbookNotFoundInRepo => e
169
+ ui.error("Could not find cookbook #{cookbook_name} in your cookbook path, skipping it")
170
+ Log.debug(e)
142
171
  end
143
- rescue Exceptions::CookbookNotFoundInRepo => e
144
- ui.error("Could not find cookbook #{cookbook_name} in your cookbook path, skipping it")
145
- Log.debug(e)
146
172
  end
147
- end
148
173
  upload_set
149
174
  end
150
175
  end
@@ -197,11 +222,13 @@ WARNING
197
222
  end
198
223
  end
199
224
 
200
- def upload(cookbook, justify_width)
201
- ui.info("Uploading #{cookbook.name.to_s.ljust(justify_width + 10)} [#{cookbook.version}]")
202
- check_for_broken_links!(cookbook)
203
- check_for_dependencies!(cookbook)
204
- Chef::CookbookUploader.new(cookbook, config[:cookbook_path], :force => config[:force]).upload_cookbook
225
+ def upload(cookbooks, justify_width)
226
+ cookbooks.each do |cb|
227
+ ui.info("Uploading #{cb.name.to_s.ljust(justify_width + 10)} [#{cb.version}]")
228
+ check_for_broken_links!(cb)
229
+ check_for_dependencies!(cb)
230
+ end
231
+ Chef::CookbookUploader.new(cookbooks, config[:cookbook_path], :force => config[:force]).upload_cookbooks
205
232
  rescue Net::HTTPServerException => e
206
233
  case e.response.code
207
234
  when "409"