chef 0.9.18 → 0.10.0.beta.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 (177) hide show
  1. data/README.rdoc +0 -3
  2. data/distro/arch/etc/rc.d/chef-server +0 -4
  3. data/distro/arch/etc/rc.d/chef-server-webui +0 -4
  4. data/distro/arch/etc/rc.d/chef-solr +0 -4
  5. data/distro/arch/etc/rc.d/chef-solr-indexer +0 -4
  6. data/lib/chef.rb +3 -3
  7. data/lib/chef/api_client.rb +1 -1
  8. data/lib/chef/application.rb +11 -1
  9. data/lib/chef/application/client.rb +18 -22
  10. data/lib/chef/application/knife.rb +28 -29
  11. data/lib/chef/application/solo.rb +14 -12
  12. data/lib/chef/client.rb +112 -54
  13. data/lib/chef/config.rb +4 -0
  14. data/lib/chef/cookbook/chefignore.rb +66 -0
  15. data/lib/chef/cookbook/cookbook_collection.rb +6 -5
  16. data/lib/chef/cookbook/cookbook_version_loader.rb +151 -0
  17. data/lib/chef/cookbook/file_system_file_vendor.rb +10 -8
  18. data/lib/chef/cookbook/metadata.rb +200 -108
  19. data/lib/chef/cookbook_loader.rb +39 -163
  20. data/lib/chef/cookbook_uploader.rb +100 -78
  21. data/lib/chef/cookbook_version.rb +92 -47
  22. data/lib/chef/cookbook_version_selector.rb +163 -0
  23. data/lib/chef/couchdb.rb +9 -1
  24. data/lib/chef/data_bag.rb +1 -1
  25. data/lib/chef/data_bag_item.rb +1 -1
  26. data/lib/chef/encrypted_data_bag_item.rb +126 -0
  27. data/lib/chef/environment.rb +386 -0
  28. data/lib/chef/exceptions.rb +82 -1
  29. data/lib/chef/index_queue/amqp_client.rb +15 -12
  30. data/lib/chef/index_queue/indexable.rb +38 -4
  31. data/lib/chef/json_compat.rb +3 -3
  32. data/lib/chef/knife.rb +97 -202
  33. data/lib/chef/knife/bootstrap.rb +27 -61
  34. data/lib/chef/knife/bootstrap/archlinux-gems.erb +4 -2
  35. data/lib/chef/knife/bootstrap/centos5-gems.erb +6 -15
  36. data/lib/chef/knife/bootstrap/fedora13-gems.erb +3 -4
  37. data/lib/chef/knife/bootstrap/ubuntu10.04-apt.erb +2 -2
  38. data/lib/chef/knife/bootstrap/ubuntu10.04-gems.erb +6 -5
  39. data/lib/chef/knife/client_bulk_delete.rb +6 -3
  40. data/lib/chef/knife/client_create.rb +13 -10
  41. data/lib/chef/knife/client_delete.rb +10 -7
  42. data/lib/chef/knife/client_edit.rb +9 -6
  43. data/lib/chef/knife/client_list.rb +8 -5
  44. data/lib/chef/knife/client_reregister.rb +9 -6
  45. data/lib/chef/knife/client_show.rb +9 -6
  46. data/lib/chef/knife/configure.rb +15 -19
  47. data/lib/chef/knife/configure_client.rb +4 -4
  48. data/lib/chef/knife/cookbook_bulk_delete.rb +11 -8
  49. data/lib/chef/knife/cookbook_create.rb +120 -55
  50. data/lib/chef/knife/cookbook_delete.rb +18 -12
  51. data/lib/chef/knife/cookbook_download.rb +10 -6
  52. data/lib/chef/knife/cookbook_list.rb +15 -6
  53. data/lib/chef/knife/cookbook_metadata.rb +41 -21
  54. data/lib/chef/knife/cookbook_metadata_from_file.rb +4 -0
  55. data/lib/chef/knife/cookbook_show.rb +16 -5
  56. data/lib/chef/knife/cookbook_site_download.rb +2 -2
  57. data/lib/chef/knife/cookbook_site_share.rb +18 -13
  58. data/lib/chef/knife/cookbook_site_unshare.rb +7 -4
  59. data/lib/chef/knife/cookbook_site_vendor.rb +21 -18
  60. data/lib/chef/knife/cookbook_test.rb +14 -14
  61. data/lib/chef/knife/cookbook_upload.rb +91 -40
  62. data/lib/chef/knife/data_bag_create.rb +41 -6
  63. data/lib/chef/knife/data_bag_delete.rb +5 -3
  64. data/lib/chef/knife/data_bag_edit.rb +55 -11
  65. data/lib/chef/knife/data_bag_from_file.rb +47 -7
  66. data/lib/chef/knife/data_bag_list.rb +4 -1
  67. data/lib/chef/knife/data_bag_show.rb +44 -4
  68. data/lib/chef/knife/environment_create.rb +53 -0
  69. data/lib/chef/knife/environment_delete.rb +45 -0
  70. data/lib/chef/knife/environment_edit.rb +45 -0
  71. data/lib/chef/knife/environment_from_file.rb +39 -0
  72. data/lib/chef/knife/environment_list.rb +42 -0
  73. data/lib/chef/knife/environment_show.rb +46 -0
  74. data/lib/chef/knife/exec.rb +1 -1
  75. data/lib/chef/knife/index_rebuild.rb +8 -9
  76. data/lib/chef/knife/node_bulk_delete.rb +9 -6
  77. data/lib/chef/knife/node_create.rb +9 -6
  78. data/lib/chef/knife/node_delete.rb +10 -7
  79. data/lib/chef/knife/node_edit.rb +129 -10
  80. data/lib/chef/knife/node_from_file.rb +10 -7
  81. data/lib/chef/knife/node_list.rb +11 -6
  82. data/lib/chef/knife/node_run_list_add.rb +10 -7
  83. data/lib/chef/knife/node_run_list_remove.rb +9 -6
  84. data/lib/chef/knife/node_show.rb +15 -7
  85. data/lib/chef/knife/recipe_list.rb +4 -3
  86. data/lib/chef/knife/role_bulk_delete.rb +9 -6
  87. data/lib/chef/knife/role_create.rb +9 -6
  88. data/lib/chef/knife/role_delete.rb +10 -7
  89. data/lib/chef/knife/role_edit.rb +11 -8
  90. data/lib/chef/knife/role_from_file.rb +10 -7
  91. data/lib/chef/knife/role_list.rb +8 -5
  92. data/lib/chef/knife/role_show.rb +11 -8
  93. data/lib/chef/knife/search.rb +33 -10
  94. data/lib/chef/knife/ssh.rb +33 -61
  95. data/lib/chef/knife/status.rb +7 -4
  96. data/lib/chef/knife/subcommand_loader.rb +101 -0
  97. data/lib/chef/knife/tag_create.rb +31 -0
  98. data/lib/chef/knife/tag_delete.rb +31 -0
  99. data/lib/chef/knife/tag_list.rb +29 -0
  100. data/lib/chef/knife/ui.rb +229 -0
  101. data/lib/chef/knife/windows_bootstrap.rb +8 -5
  102. data/lib/chef/log.rb +5 -59
  103. data/lib/chef/mash.rb +211 -0
  104. data/lib/chef/mixins.rb +1 -2
  105. data/lib/chef/nil_argument.rb +3 -0
  106. data/lib/chef/node.rb +96 -34
  107. data/lib/chef/platform.rb +27 -0
  108. data/lib/chef/provider/cookbook_file.rb +21 -20
  109. data/lib/chef/provider/deploy/revision.rb +3 -0
  110. data/lib/chef/provider/file.rb +20 -11
  111. data/lib/chef/provider/git.rb +26 -26
  112. data/lib/chef/provider/group/aix.rb +70 -0
  113. data/lib/chef/provider/group/groupadd.rb +7 -4
  114. data/lib/chef/provider/group/usermod.rb +1 -1
  115. data/lib/chef/provider/package.rb +28 -28
  116. data/lib/chef/provider/package/dpkg.rb +1 -1
  117. data/lib/chef/provider/package/portage.rb +50 -39
  118. data/lib/chef/provider/package/rubygems.rb +1 -1
  119. data/lib/chef/provider/package/zypper.rb +3 -20
  120. data/lib/chef/provider/remote_directory.rb +0 -2
  121. data/lib/chef/provider/remote_file.rb +2 -3
  122. data/lib/chef/provider/service/arch.rb +28 -35
  123. data/lib/chef/provider/service/simple.rb +1 -1
  124. data/lib/chef/provider/subversion.rb +22 -22
  125. data/lib/chef/providers.rb +1 -0
  126. data/lib/chef/recipe.rb +10 -12
  127. data/lib/chef/resource.rb +49 -42
  128. data/lib/chef/resource/gem_package.rb +7 -3
  129. data/lib/chef/resource/git.rb +5 -5
  130. data/lib/chef/resource/package.rb +7 -7
  131. data/lib/chef/resource/scm.rb +2 -1
  132. data/lib/chef/resource/solaris_package.rb +0 -1
  133. data/lib/chef/resource/yum_package.rb +0 -1
  134. data/lib/chef/rest.rb +7 -16
  135. data/lib/chef/rest/rest_request.rb +0 -16
  136. data/lib/chef/role.rb +67 -13
  137. data/lib/chef/run_context.rb +37 -21
  138. data/lib/chef/run_list.rb +30 -15
  139. data/lib/chef/run_list/run_list_expansion.rb +41 -20
  140. data/lib/chef/run_list/run_list_item.rb +20 -6
  141. data/lib/chef/run_list/versioned_recipe_list.rb +68 -0
  142. data/lib/chef/runner.rb +7 -15
  143. data/lib/chef/search/query.rb +12 -7
  144. data/lib/chef/shef.rb +6 -7
  145. data/lib/chef/shef/shef_session.rb +40 -35
  146. data/lib/chef/shell_out.rb +22 -201
  147. data/lib/chef/shell_out/unix.rb +224 -0
  148. data/lib/chef/shell_out/windows.rb +95 -0
  149. data/lib/chef/solr_query.rb +187 -0
  150. data/lib/chef/solr_query/lucene.treetop +145 -0
  151. data/lib/chef/solr_query/lucene_nodes.rb +285 -0
  152. data/lib/chef/solr_query/query_transform.rb +65 -0
  153. data/lib/chef/solr_query/solr_http_request.rb +118 -0
  154. data/lib/chef/version.rb +4 -2
  155. data/lib/chef/version_class.rb +70 -0
  156. data/lib/chef/version_constraint.rb +116 -0
  157. metadata +68 -37
  158. data/lib/chef/cookbook/metadata/version.rb +0 -87
  159. data/lib/chef/knife/bluebox_images_list.rb +0 -54
  160. data/lib/chef/knife/bluebox_server_create.rb +0 -157
  161. data/lib/chef/knife/bluebox_server_delete.rb +0 -63
  162. data/lib/chef/knife/bluebox_server_list.rb +0 -59
  163. data/lib/chef/knife/ec2_instance_data.rb +0 -46
  164. data/lib/chef/knife/ec2_server_create.rb +0 -218
  165. data/lib/chef/knife/ec2_server_delete.rb +0 -87
  166. data/lib/chef/knife/ec2_server_list.rb +0 -89
  167. data/lib/chef/knife/rackspace_server_create.rb +0 -184
  168. data/lib/chef/knife/rackspace_server_delete.rb +0 -57
  169. data/lib/chef/knife/rackspace_server_list.rb +0 -59
  170. data/lib/chef/knife/slicehost_images_list.rb +0 -53
  171. data/lib/chef/knife/slicehost_server_create.rb +0 -103
  172. data/lib/chef/knife/slicehost_server_delete.rb +0 -61
  173. data/lib/chef/knife/slicehost_server_list.rb +0 -64
  174. data/lib/chef/knife/terremark_server_create.rb +0 -152
  175. data/lib/chef/knife/terremark_server_delete.rb +0 -87
  176. data/lib/chef/knife/terremark_server_list.rb +0 -77
  177. data/lib/chef/mixin/find_preferred_file.rb +0 -92
@@ -9,9 +9,9 @@
9
9
  # Licensed under the Apache License, Version 2.0 (the "License");
10
10
  # you may not use this file except in compliance with the License.
11
11
  # You may obtain a copy of the License at
12
- #
12
+ #
13
13
  # http://www.apache.org/licenses/LICENSE-2.0
14
- #
14
+ #
15
15
  # Unless required by applicable law or agreed to in writing, software
16
16
  # distributed under the License is distributed on an "AS IS" BASIS,
17
17
  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -19,144 +19,71 @@
19
19
  # limitations under the License.
20
20
 
21
21
  require 'chef/config'
22
+ require 'chef/exceptions'
23
+ require 'chef/cookbook/cookbook_version_loader'
22
24
  require 'chef/cookbook_version'
25
+ require 'chef/cookbook/chefignore'
23
26
  require 'chef/cookbook/metadata'
24
27
 
25
28
  class Chef
26
29
  class CookbookLoader
27
-
28
- attr_accessor :cookbook, :metadata
29
-
30
+
31
+ attr_accessor :metadata
32
+ attr_reader :cookbooks_by_name
33
+
30
34
  include Enumerable
31
-
32
- def initialize()
35
+
36
+ def initialize(*repo_paths)
37
+ @repo_paths = repo_paths.flatten
38
+ raise ArgumentError, "You must specify at least one cookbook repo path" if @repo_paths.empty?
33
39
  @cookbooks_by_name = Mash.new
34
- @metadata = Hash.new
35
- @ignore_regexes = Hash.new { |hsh, key| hsh[key] = Array.new }
40
+ @loaded_cookbooks = {}
41
+ @metadata = Mash.new
36
42
  load_cookbooks
37
43
  end
38
-
44
+
39
45
  def load_cookbooks
40
46
  cookbook_settings = Hash.new
41
- [Chef::Config.cookbook_path].flatten.each do |cb_path|
42
- cb_path = File.expand_path(cb_path)
43
- Dir[File.join(cb_path, "*")].each do |cookbook|
44
- next unless File.directory?(cookbook)
45
- cookbook_name = File.basename(cookbook).to_sym
46
- unless cookbook_settings.has_key?(cookbook_name)
47
- cookbook_settings[cookbook_name] = {
48
- :attribute_filenames => Hash.new,
49
- :definition_filenames => Hash.new,
50
- :recipe_filenames => Hash.new,
51
- :template_filenames => Hash.new,
52
- :file_filenames => Hash.new,
53
- :library_filenames => Hash.new,
54
- :resource_filenames => Hash.new,
55
- :provider_filenames => Hash.new,
56
- :root_filenames => Hash.new,
57
- :metadata_filenames => Array.new
58
- }
59
- end
60
- ignore_regexes = load_ignore_file(File.join(cookbook, "ignore"))
61
- @ignore_regexes[cookbook_name].concat(ignore_regexes)
62
-
63
- load_files_unless_basename(
64
- File.join(cookbook, "attributes", "*.rb"),
65
- cookbook_settings[cookbook_name][:attribute_filenames]
66
- )
67
- load_files_unless_basename(
68
- File.join(cookbook, "definitions", "*.rb"),
69
- cookbook_settings[cookbook_name][:definition_filenames]
70
- )
71
- load_files_unless_basename(
72
- File.join(cookbook, "recipes", "*.rb"),
73
- cookbook_settings[cookbook_name][:recipe_filenames]
74
- )
75
- load_files_unless_basename(
76
- File.join(cookbook, "libraries", "*.rb"),
77
- cookbook_settings[cookbook_name][:library_filenames]
78
- )
79
- load_cascading_files(
80
- "*",
81
- File.join(cookbook, "templates"),
82
- cookbook_settings[cookbook_name][:template_filenames]
83
- )
84
- load_cascading_files(
85
- "*",
86
- File.join(cookbook, "files"),
87
- cookbook_settings[cookbook_name][:file_filenames]
88
- )
89
- load_cascading_files(
90
- "*.rb",
91
- File.join(cookbook, "resources"),
92
- cookbook_settings[cookbook_name][:resource_filenames]
93
- )
94
- load_cascading_files(
95
- "*.rb",
96
- File.join(cookbook, "providers"),
97
- cookbook_settings[cookbook_name][:provider_filenames]
98
- )
99
- load_files(
100
- "*",
101
- cookbook,
102
- cookbook_settings[cookbook_name][:root_filenames]
103
- )
104
- cookbook_settings[cookbook_name][:root_dir] = cookbook
105
- if File.exists?(File.join(cookbook, "metadata.json"))
106
- cookbook_settings[cookbook_name][:metadata_filenames] << File.join(cookbook, "metadata.json")
107
- end
108
-
109
- empty = cookbook_settings[cookbook_name].inject(true) do |all_empty, files|
110
- all_empty && files.last.empty?
111
- end
112
-
113
- if empty
114
- Chef::Log.warn "found a directory #{cookbook_name} in the cookbook path, but it contains no cookbook files. skipping."
115
- cookbook_settings.delete(cookbook_name)
47
+ @repo_paths.each do |repo_path|
48
+ repo_path = File.expand_path(repo_path)
49
+ chefignore = Cookbook::Chefignore.new(repo_path)
50
+ Dir[File.join(repo_path, "*")].each do |cookbook_path|
51
+ next unless File.directory?(cookbook_path)
52
+ loader = Cookbook::CookbookVersionLoader.new(cookbook_path, chefignore)
53
+ loader.load_cookbooks
54
+ next if loader.empty?
55
+ if @loaded_cookbooks.key?(loader.cookbook_name)
56
+ @loaded_cookbooks[loader.cookbook_name].merge!(loader)
57
+ else
58
+ @loaded_cookbooks[loader.cookbook_name] = loader
116
59
  end
117
60
  end
118
61
  end
119
- remove_ignored_files_from(cookbook_settings)
120
62
 
121
- cookbook_settings.each_key do |cookbook|
122
- @cookbooks_by_name[cookbook] = Chef::CookbookVersion.new(cookbook)
123
- @cookbooks_by_name[cookbook].root_dir = cookbook_settings[cookbook][:root_dir]
124
- @cookbooks_by_name[cookbook].attribute_filenames = cookbook_settings[cookbook][:attribute_filenames].values
125
- @cookbooks_by_name[cookbook].definition_filenames = cookbook_settings[cookbook][:definition_filenames].values
126
- @cookbooks_by_name[cookbook].recipe_filenames = cookbook_settings[cookbook][:recipe_filenames].values
127
- @cookbooks_by_name[cookbook].template_filenames = cookbook_settings[cookbook][:template_filenames].values
128
- @cookbooks_by_name[cookbook].file_filenames = cookbook_settings[cookbook][:file_filenames].values
129
- @cookbooks_by_name[cookbook].library_filenames = cookbook_settings[cookbook][:library_filenames].values
130
- @cookbooks_by_name[cookbook].resource_filenames = cookbook_settings[cookbook][:resource_filenames].values
131
- @cookbooks_by_name[cookbook].provider_filenames = cookbook_settings[cookbook][:provider_filenames].values
132
- @cookbooks_by_name[cookbook].root_filenames = cookbook_settings[cookbook][:root_filenames].values
133
- @cookbooks_by_name[cookbook].metadata_filenames = cookbook_settings[cookbook][:metadata_filenames]
134
- @metadata[cookbook] = Chef::Cookbook::Metadata.new(@cookbooks_by_name[cookbook])
135
- cookbook_settings[cookbook][:metadata_filenames].each do |meta_json|
136
- begin
137
- @metadata[cookbook].from_json(IO.read(meta_json))
138
- rescue JSON::ParserError
139
- Chef::Log.fatal("Couldn't parse JSON in " + meta_json)
140
- raise
141
- end
142
- end
143
- @cookbooks_by_name[cookbook].metadata = @metadata[cookbook]
63
+ @loaded_cookbooks.each do |cookbook, loader|
64
+ cookbook_version = loader.cookbook_version
65
+ @cookbooks_by_name[cookbook] = cookbook_version
66
+ @metadata[cookbook] = cookbook_version.metadata
144
67
  end
68
+ @cookbooks_by_name
145
69
  end
146
-
70
+
147
71
  def [](cookbook)
148
72
  if @cookbooks_by_name.has_key?(cookbook.to_sym)
149
73
  @cookbooks_by_name[cookbook.to_sym]
150
74
  else
151
- raise ArgumentError, "Cannot find a cookbook named #{cookbook.to_s}; did you forget to add metadata to a cookbook? (http://wiki.opscode.com/display/chef/Metadata)"
75
+ raise Exceptions::CookbookNotFoundInRepo, "Cannot find a cookbook named #{cookbook.to_s}; did you forget to add metadata to a cookbook? (http://wiki.opscode.com/display/chef/Metadata)"
152
76
  end
153
77
  end
154
78
 
79
+ alias :fetch :[]
80
+
155
81
  def has_key?(cookbook_name)
156
82
  @cookbooks_by_name.has_key?(cookbook_name)
157
83
  end
158
84
  alias :cookbook_exists? :has_key?
159
-
85
+ alias :key? :has_key?
86
+
160
87
  def each
161
88
  @cookbooks_by_name.keys.sort { |a,b| a.to_s <=> b.to_s }.each do |cname|
162
89
  yield(cname, @cookbooks_by_name[cname])
@@ -172,56 +99,5 @@ class Chef
172
99
  end
173
100
  alias :cookbooks :values
174
101
 
175
- private
176
-
177
- def load_ignore_file(ignore_file)
178
- results = Array.new
179
- if File.exists?(ignore_file) && File.readable?(ignore_file)
180
- IO.foreach(ignore_file) do |line|
181
- next if line =~ /^#/
182
- next if line =~ /^\w*$/
183
- line.chomp!
184
- results << Regexp.new(line)
185
- end
186
- end
187
- results
188
- end
189
-
190
- def remove_ignored_files_from(cookbook_settings)
191
- file_types_to_inspect = [ :attribute_filenames, :definition_filenames, :recipe_filenames, :template_filenames,
192
- :file_filenames, :library_filenames, :resource_filenames, :provider_filenames]
193
-
194
- @ignore_regexes.each do |cookbook_name, regexes|
195
- regexes.each do |regex|
196
- settings = cookbook_settings[cookbook_name]
197
- file_types_to_inspect.each do |file_type|
198
- settings[file_type].delete_if { |uniqname, fullpath| fullpath.match(regex) }
199
- end
200
- end
201
- end
202
- end
203
-
204
- def load_files(file_glob, base_path, result_hash, recursive=false)
205
- rm_base_path = /^#{Regexp.escape(base_path)}\/(.+)$/
206
- file_spec = [base_path]
207
- file_spec << "**" if recursive
208
- file_spec << file_glob
209
- # To handle dotfiles like .ssh
210
- Dir.glob(File.join(file_spec), File::FNM_DOTMATCH).each do |file|
211
- next if File.directory?(file)
212
- result_hash[rm_base_path.match(file)[1]] = file
213
- end
214
- end
215
-
216
- def load_cascading_files(file_glob, base_path, result_hash)
217
- load_files(file_glob, base_path, result_hash, true)
218
- end
219
-
220
- def load_files_unless_basename(file_glob, result_hash)
221
- Dir[file_glob].each do |file|
222
- result_hash[File.basename(file)] = file
223
- end
224
- end
225
-
226
102
  end
227
103
  end
@@ -1,5 +1,6 @@
1
1
  require 'rest_client'
2
- require 'chef/cookbook_loader'
2
+ require 'chef/exceptions'
3
+ require 'chef/knife/cookbook_metadata'
3
4
  require 'chef/checksum_cache'
4
5
  require 'chef/sandbox'
5
6
  require 'chef/cookbook_version'
@@ -8,96 +9,117 @@ require 'chef/cookbook/file_system_file_vendor'
8
9
 
9
10
  class Chef
10
11
  class CookbookUploader
11
- class << self
12
12
 
13
- def upload_cookbook(cookbook)
14
- Chef::Log.info("Saving #{cookbook.name}")
13
+ attr_reader :cookbook
14
+ attr_reader :path
15
+ attr_reader :opts
16
+ attr_reader :rest
15
17
 
16
- rest = Chef::REST.new(Chef::Config[:chef_server_url])
18
+ # Creates a new CookbookUploader.
19
+ # ===Arguments:
20
+ # * cookbook::: A Chef::CookbookVersion describing the cookbook to be uploaded
21
+ # * path::: A String or Array of Strings representing the base paths to the
22
+ # cookbook repositories.
23
+ # * opts::: (optional) An options Hash
24
+ # ===Options:
25
+ # * :force indicates that the uploader should set the force option when
26
+ # uploading the cookbook. This allows frozen CookbookVersion
27
+ # documents on the server to be overwritten (otherwise a 409 is
28
+ # returned by the server)
29
+ # * :rest A Chef::REST object that you have configured the way you like it.
30
+ # If you don't provide this, one will be created using the values
31
+ # in Chef::Config.
32
+ def initialize(cookbook, path, opts={})
33
+ @cookbook, @path, @opts = cookbook, path, opts
34
+ @rest = opts[:rest] || Chef::REST.new(Chef::Config[:chef_server_url])
35
+ end
17
36
 
18
- # Syntax Check
19
- validate_cookbook(cookbook)
20
- # Generate metadata.json from metadata.rb
21
- build_metadata(cookbook)
37
+ def upload_cookbook
38
+ Chef::Log.info("Saving #{cookbook.name}")
22
39
 
23
- # generate checksums of cookbook files and create a sandbox
24
- checksum_files = cookbook.checksums
25
- checksums = checksum_files.inject({}){|memo,elt| memo[elt.first]=nil ; memo}
26
- new_sandbox = rest.post_rest("sandboxes", { :checksums => checksums })
40
+ # Syntax Check
41
+ validate_cookbook
42
+ # Generate metadata.json from metadata.rb
43
+ build_metadata
27
44
 
28
- Chef::Log.info("Uploading files")
29
- # upload the new checksums and commit the sandbox
30
- new_sandbox['checksums'].each do |checksum, info|
31
- if info['needs_upload'] == true
32
- Chef::Log.info("Uploading #{checksum_files[checksum]} (checksum hex = #{checksum}) to #{info['url']}")
45
+ # generate checksums of cookbook files and create a sandbox
46
+ checksum_files = cookbook.checksums
47
+ checksums = checksum_files.inject({}){|memo,elt| memo[elt.first]=nil ; memo}
48
+ new_sandbox = rest.post_rest("sandboxes", { :checksums => checksums })
33
49
 
34
- # Checksum is the hexadecimal representation of the md5,
35
- # but we need the base64 encoding for the content-md5
36
- # header
37
- checksum64 = Base64.encode64([checksum].pack("H*")).strip
38
- timestamp = Time.now.utc.iso8601
39
- file_contents = File.read(checksum_files[checksum])
40
- # TODO - 5/28/2010, cw: make signing and sending the request streaming
41
- sign_obj = Mixlib::Authentication::SignedHeaderAuth.signing_object(
42
- :http_method => :put,
43
- :path => URI.parse(info['url']).path,
44
- :body => file_contents,
45
- :timestamp => timestamp,
46
- :user_id => rest.client_name
47
- )
48
- headers = { 'content-type' => 'application/x-binary', 'content-md5' => checksum64, :accept => 'application/json' }
49
- headers.merge!(sign_obj.sign(OpenSSL::PKey::RSA.new(rest.signing_key)))
50
- begin
51
- RestClient::Resource.new(info['url'], :headers=>headers, :timeout=>1800, :open_timeout=>1800).put(file_contents)
52
- rescue RestClient::Exception => e
53
- Chef::Log.error("Upload failed: #{e.message}\n#{e.response.body}")
54
- raise
55
- end
56
- else
57
- Chef::Log.debug("#{checksum_files[checksum]} has not changed")
58
- end
59
- end
60
- sandbox_url = new_sandbox['uri']
61
- Chef::Log.debug("Committing sandbox")
62
- # Retry if S3 is claims a checksum doesn't exist (the eventual
63
- # in eventual consistency)
64
- retries = 0
65
- begin
66
- rest.put_rest(sandbox_url, {:is_completed => true})
67
- rescue Net::HTTPServerException => e
68
- if e.message =~ /^400/ && (retries += 1) <= 5
69
- sleep 2
70
- retry
71
- else
50
+ Chef::Log.info("Uploading files")
51
+ # upload the new checksums and commit the sandbox
52
+ new_sandbox['checksums'].each do |checksum, info|
53
+ if info['needs_upload'] == true
54
+ Chef::Log.info("Uploading #{checksum_files[checksum]} (checksum hex = #{checksum}) to #{info['url']}")
55
+
56
+ # Checksum is the hexadecimal representation of the md5,
57
+ # but we need the base64 encoding for the content-md5
58
+ # header
59
+ checksum64 = Base64.encode64([checksum].pack("H*")).strip
60
+ timestamp = Time.now.utc.iso8601
61
+ file_contents = File.read(checksum_files[checksum])
62
+ # TODO - 5/28/2010, cw: make signing and sending the request streaming
63
+ sign_obj = Mixlib::Authentication::SignedHeaderAuth.signing_object(
64
+ :http_method => :put,
65
+ :path => URI.parse(info['url']).path,
66
+ :body => file_contents,
67
+ :timestamp => timestamp,
68
+ :user_id => rest.client_name
69
+ )
70
+ headers = { 'content-type' => 'application/x-binary', 'content-md5' => checksum64, :accept => 'application/json' }
71
+ headers.merge!(sign_obj.sign(OpenSSL::PKey::RSA.new(rest.signing_key)))
72
+
73
+ begin
74
+ RestClient::Resource.new(info['url'], :headers=>headers, :timeout=>1800, :open_timeout=>1800).put(file_contents)
75
+ rescue RestClient::Exception => e
76
+ Chef::Log.error("Upload failed: #{e.message}\n#{e.response.body}")
72
77
  raise
73
78
  end
79
+ else
80
+ Chef::Log.debug("#{checksum_files[checksum]} has not changed")
74
81
  end
75
- # files are uploaded, so save the manifest
76
- cookbook.save
77
- Chef::Log.info("Upload complete!")
78
82
  end
79
-
80
- def build_metadata(cookbook)
81
- Chef::Log.debug("Generating metadata")
82
- # FIXME: This knife command should be factored out into a
83
- # library for use here
84
- kcm = Chef::Knife::CookbookMetadata.new
85
- kcm.config[:cookbook_path] = Chef::Config[:cookbook_path]
86
- kcm.name_args = [ cookbook.name.to_s ]
87
- kcm.run
88
- cookbook.reload_metadata!
83
+ sandbox_url = new_sandbox['uri']
84
+ Chef::Log.debug("Committing sandbox")
85
+ # Retry if S3 is claims a checksum doesn't exist (the eventual
86
+ # in eventual consistency)
87
+ retries = 0
88
+ begin
89
+ rest.put_rest(sandbox_url, {:is_completed => true})
90
+ rescue Net::HTTPServerException => e
91
+ if e.message =~ /^400/ && (retries += 1) <= 5
92
+ sleep 2
93
+ retry
94
+ else
95
+ raise
96
+ end
89
97
  end
98
+ # files are uploaded, so save the manifest
99
+ opts[:force] ? cookbook.force_save : cookbook.save
100
+ Chef::Log.info("Upload complete!")
101
+ end
90
102
 
91
- def validate_cookbook(cookbook)
92
- syntax_checker = Chef::Cookbook::SyntaxCheck.for_cookbook(cookbook.name, @user_cookbook_path)
93
- Chef::Log.info("Validating ruby files")
94
- exit(1) unless syntax_checker.validate_ruby_files
95
- Chef::Log.info("Validating templates")
96
- exit(1) unless syntax_checker.validate_templates
97
- Chef::Log.info("Syntax OK")
98
- true
99
- end
103
+ def build_metadata
104
+ Chef::Log.debug("Generating metadata")
105
+ # FIXME: This knife command should be factored out into a
106
+ # library for use here
107
+ kcm = Chef::Knife::CookbookMetadata.new
108
+ kcm.config[:cookbook_path] = path
109
+ kcm.name_args = [ cookbook.name.to_s ]
110
+ kcm.run
111
+ cookbook.reload_metadata!
112
+ end
100
113
 
114
+ def validate_cookbook
115
+ syntax_checker = Chef::Cookbook::SyntaxCheck.for_cookbook(cookbook.name, @user_cookbook_path)
116
+ Chef::Log.info("Validating ruby files")
117
+ exit(1) unless syntax_checker.validate_ruby_files
118
+ Chef::Log.info("Validating templates")
119
+ exit(1) unless syntax_checker.validate_templates
120
+ Chef::Log.info("Syntax OK")
121
+ true
101
122
  end
123
+
102
124
  end
103
125
  end