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.
- data/README.rdoc +0 -3
- data/distro/arch/etc/rc.d/chef-server +0 -4
- data/distro/arch/etc/rc.d/chef-server-webui +0 -4
- data/distro/arch/etc/rc.d/chef-solr +0 -4
- data/distro/arch/etc/rc.d/chef-solr-indexer +0 -4
- data/lib/chef.rb +3 -3
- data/lib/chef/api_client.rb +1 -1
- data/lib/chef/application.rb +11 -1
- data/lib/chef/application/client.rb +18 -22
- data/lib/chef/application/knife.rb +28 -29
- data/lib/chef/application/solo.rb +14 -12
- data/lib/chef/client.rb +112 -54
- data/lib/chef/config.rb +4 -0
- data/lib/chef/cookbook/chefignore.rb +66 -0
- data/lib/chef/cookbook/cookbook_collection.rb +6 -5
- data/lib/chef/cookbook/cookbook_version_loader.rb +151 -0
- data/lib/chef/cookbook/file_system_file_vendor.rb +10 -8
- data/lib/chef/cookbook/metadata.rb +200 -108
- data/lib/chef/cookbook_loader.rb +39 -163
- data/lib/chef/cookbook_uploader.rb +100 -78
- data/lib/chef/cookbook_version.rb +92 -47
- data/lib/chef/cookbook_version_selector.rb +163 -0
- data/lib/chef/couchdb.rb +9 -1
- data/lib/chef/data_bag.rb +1 -1
- data/lib/chef/data_bag_item.rb +1 -1
- data/lib/chef/encrypted_data_bag_item.rb +126 -0
- data/lib/chef/environment.rb +386 -0
- data/lib/chef/exceptions.rb +82 -1
- data/lib/chef/index_queue/amqp_client.rb +15 -12
- data/lib/chef/index_queue/indexable.rb +38 -4
- data/lib/chef/json_compat.rb +3 -3
- data/lib/chef/knife.rb +97 -202
- data/lib/chef/knife/bootstrap.rb +27 -61
- data/lib/chef/knife/bootstrap/archlinux-gems.erb +4 -2
- data/lib/chef/knife/bootstrap/centos5-gems.erb +6 -15
- data/lib/chef/knife/bootstrap/fedora13-gems.erb +3 -4
- data/lib/chef/knife/bootstrap/ubuntu10.04-apt.erb +2 -2
- data/lib/chef/knife/bootstrap/ubuntu10.04-gems.erb +6 -5
- data/lib/chef/knife/client_bulk_delete.rb +6 -3
- data/lib/chef/knife/client_create.rb +13 -10
- data/lib/chef/knife/client_delete.rb +10 -7
- data/lib/chef/knife/client_edit.rb +9 -6
- data/lib/chef/knife/client_list.rb +8 -5
- data/lib/chef/knife/client_reregister.rb +9 -6
- data/lib/chef/knife/client_show.rb +9 -6
- data/lib/chef/knife/configure.rb +15 -19
- data/lib/chef/knife/configure_client.rb +4 -4
- data/lib/chef/knife/cookbook_bulk_delete.rb +11 -8
- data/lib/chef/knife/cookbook_create.rb +120 -55
- data/lib/chef/knife/cookbook_delete.rb +18 -12
- data/lib/chef/knife/cookbook_download.rb +10 -6
- data/lib/chef/knife/cookbook_list.rb +15 -6
- data/lib/chef/knife/cookbook_metadata.rb +41 -21
- data/lib/chef/knife/cookbook_metadata_from_file.rb +4 -0
- data/lib/chef/knife/cookbook_show.rb +16 -5
- data/lib/chef/knife/cookbook_site_download.rb +2 -2
- data/lib/chef/knife/cookbook_site_share.rb +18 -13
- data/lib/chef/knife/cookbook_site_unshare.rb +7 -4
- data/lib/chef/knife/cookbook_site_vendor.rb +21 -18
- data/lib/chef/knife/cookbook_test.rb +14 -14
- data/lib/chef/knife/cookbook_upload.rb +91 -40
- data/lib/chef/knife/data_bag_create.rb +41 -6
- data/lib/chef/knife/data_bag_delete.rb +5 -3
- data/lib/chef/knife/data_bag_edit.rb +55 -11
- data/lib/chef/knife/data_bag_from_file.rb +47 -7
- data/lib/chef/knife/data_bag_list.rb +4 -1
- data/lib/chef/knife/data_bag_show.rb +44 -4
- data/lib/chef/knife/environment_create.rb +53 -0
- data/lib/chef/knife/environment_delete.rb +45 -0
- data/lib/chef/knife/environment_edit.rb +45 -0
- data/lib/chef/knife/environment_from_file.rb +39 -0
- data/lib/chef/knife/environment_list.rb +42 -0
- data/lib/chef/knife/environment_show.rb +46 -0
- data/lib/chef/knife/exec.rb +1 -1
- data/lib/chef/knife/index_rebuild.rb +8 -9
- data/lib/chef/knife/node_bulk_delete.rb +9 -6
- data/lib/chef/knife/node_create.rb +9 -6
- data/lib/chef/knife/node_delete.rb +10 -7
- data/lib/chef/knife/node_edit.rb +129 -10
- data/lib/chef/knife/node_from_file.rb +10 -7
- data/lib/chef/knife/node_list.rb +11 -6
- data/lib/chef/knife/node_run_list_add.rb +10 -7
- data/lib/chef/knife/node_run_list_remove.rb +9 -6
- data/lib/chef/knife/node_show.rb +15 -7
- data/lib/chef/knife/recipe_list.rb +4 -3
- data/lib/chef/knife/role_bulk_delete.rb +9 -6
- data/lib/chef/knife/role_create.rb +9 -6
- data/lib/chef/knife/role_delete.rb +10 -7
- data/lib/chef/knife/role_edit.rb +11 -8
- data/lib/chef/knife/role_from_file.rb +10 -7
- data/lib/chef/knife/role_list.rb +8 -5
- data/lib/chef/knife/role_show.rb +11 -8
- data/lib/chef/knife/search.rb +33 -10
- data/lib/chef/knife/ssh.rb +33 -61
- data/lib/chef/knife/status.rb +7 -4
- data/lib/chef/knife/subcommand_loader.rb +101 -0
- data/lib/chef/knife/tag_create.rb +31 -0
- data/lib/chef/knife/tag_delete.rb +31 -0
- data/lib/chef/knife/tag_list.rb +29 -0
- data/lib/chef/knife/ui.rb +229 -0
- data/lib/chef/knife/windows_bootstrap.rb +8 -5
- data/lib/chef/log.rb +5 -59
- data/lib/chef/mash.rb +211 -0
- data/lib/chef/mixins.rb +1 -2
- data/lib/chef/nil_argument.rb +3 -0
- data/lib/chef/node.rb +96 -34
- data/lib/chef/platform.rb +27 -0
- data/lib/chef/provider/cookbook_file.rb +21 -20
- data/lib/chef/provider/deploy/revision.rb +3 -0
- data/lib/chef/provider/file.rb +20 -11
- data/lib/chef/provider/git.rb +26 -26
- data/lib/chef/provider/group/aix.rb +70 -0
- data/lib/chef/provider/group/groupadd.rb +7 -4
- data/lib/chef/provider/group/usermod.rb +1 -1
- data/lib/chef/provider/package.rb +28 -28
- data/lib/chef/provider/package/dpkg.rb +1 -1
- data/lib/chef/provider/package/portage.rb +50 -39
- data/lib/chef/provider/package/rubygems.rb +1 -1
- data/lib/chef/provider/package/zypper.rb +3 -20
- data/lib/chef/provider/remote_directory.rb +0 -2
- data/lib/chef/provider/remote_file.rb +2 -3
- data/lib/chef/provider/service/arch.rb +28 -35
- data/lib/chef/provider/service/simple.rb +1 -1
- data/lib/chef/provider/subversion.rb +22 -22
- data/lib/chef/providers.rb +1 -0
- data/lib/chef/recipe.rb +10 -12
- data/lib/chef/resource.rb +49 -42
- data/lib/chef/resource/gem_package.rb +7 -3
- data/lib/chef/resource/git.rb +5 -5
- data/lib/chef/resource/package.rb +7 -7
- data/lib/chef/resource/scm.rb +2 -1
- data/lib/chef/resource/solaris_package.rb +0 -1
- data/lib/chef/resource/yum_package.rb +0 -1
- data/lib/chef/rest.rb +7 -16
- data/lib/chef/rest/rest_request.rb +0 -16
- data/lib/chef/role.rb +67 -13
- data/lib/chef/run_context.rb +37 -21
- data/lib/chef/run_list.rb +30 -15
- data/lib/chef/run_list/run_list_expansion.rb +41 -20
- data/lib/chef/run_list/run_list_item.rb +20 -6
- data/lib/chef/run_list/versioned_recipe_list.rb +68 -0
- data/lib/chef/runner.rb +7 -15
- data/lib/chef/search/query.rb +12 -7
- data/lib/chef/shef.rb +6 -7
- data/lib/chef/shef/shef_session.rb +40 -35
- data/lib/chef/shell_out.rb +22 -201
- data/lib/chef/shell_out/unix.rb +224 -0
- data/lib/chef/shell_out/windows.rb +95 -0
- data/lib/chef/solr_query.rb +187 -0
- data/lib/chef/solr_query/lucene.treetop +145 -0
- data/lib/chef/solr_query/lucene_nodes.rb +285 -0
- data/lib/chef/solr_query/query_transform.rb +65 -0
- data/lib/chef/solr_query/solr_http_request.rb +118 -0
- data/lib/chef/version.rb +4 -2
- data/lib/chef/version_class.rb +70 -0
- data/lib/chef/version_constraint.rb +116 -0
- metadata +68 -37
- data/lib/chef/cookbook/metadata/version.rb +0 -87
- data/lib/chef/knife/bluebox_images_list.rb +0 -54
- data/lib/chef/knife/bluebox_server_create.rb +0 -157
- data/lib/chef/knife/bluebox_server_delete.rb +0 -63
- data/lib/chef/knife/bluebox_server_list.rb +0 -59
- data/lib/chef/knife/ec2_instance_data.rb +0 -46
- data/lib/chef/knife/ec2_server_create.rb +0 -218
- data/lib/chef/knife/ec2_server_delete.rb +0 -87
- data/lib/chef/knife/ec2_server_list.rb +0 -89
- data/lib/chef/knife/rackspace_server_create.rb +0 -184
- data/lib/chef/knife/rackspace_server_delete.rb +0 -57
- data/lib/chef/knife/rackspace_server_list.rb +0 -59
- data/lib/chef/knife/slicehost_images_list.rb +0 -53
- data/lib/chef/knife/slicehost_server_create.rb +0 -103
- data/lib/chef/knife/slicehost_server_delete.rb +0 -61
- data/lib/chef/knife/slicehost_server_list.rb +0 -64
- data/lib/chef/knife/terremark_server_create.rb +0 -152
- data/lib/chef/knife/terremark_server_delete.rb +0 -87
- data/lib/chef/knife/terremark_server_list.rb +0 -77
- data/lib/chef/mixin/find_preferred_file.rb +0 -92
data/lib/chef/cookbook_loader.rb
CHANGED
|
@@ -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 :
|
|
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
|
-
@
|
|
35
|
-
@
|
|
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
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
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
|
-
|
|
122
|
-
|
|
123
|
-
@cookbooks_by_name[cookbook]
|
|
124
|
-
@
|
|
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
|
|
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/
|
|
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
|
-
|
|
14
|
-
|
|
13
|
+
attr_reader :cookbook
|
|
14
|
+
attr_reader :path
|
|
15
|
+
attr_reader :opts
|
|
16
|
+
attr_reader :rest
|
|
15
17
|
|
|
16
|
-
|
|
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
|
-
|
|
19
|
-
|
|
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
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
40
|
+
# Syntax Check
|
|
41
|
+
validate_cookbook
|
|
42
|
+
# Generate metadata.json from metadata.rb
|
|
43
|
+
build_metadata
|
|
27
44
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
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
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
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
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
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
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
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
|