chef 0.7.16 → 0.8.2
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of chef might be problematic. Click here for more details.
- data/README.rdoc +11 -10
- data/bin/chef-client +2 -2
- data/bin/chef-solo +1 -1
- data/bin/knife +27 -0
- data/bin/shef +49 -0
- data/distro/README +2 -0
- data/distro/{debian → common}/man/man1/chef-indexer.1 +0 -0
- data/distro/{debian → common}/man/man1/chef-server.1 +0 -0
- data/distro/{debian → common}/man/man8/chef-client.8 +0 -0
- data/distro/{debian → common}/man/man8/chef-solo.8 +0 -0
- data/distro/common/man/man8/knife.8 +375 -0
- data/distro/redhat/etc/init.d/chef-client +8 -4
- data/distro/redhat/etc/init.d/chef-server +16 -15
- data/distro/redhat/etc/init.d/chef-server-webui +78 -0
- data/distro/redhat/etc/init.d/chef-solr +76 -0
- data/distro/redhat/etc/init.d/chef-solr-indexer +75 -0
- data/distro/redhat/etc/sysconfig/chef-client +10 -0
- data/distro/redhat/etc/sysconfig/chef-server +10 -0
- data/distro/redhat/etc/sysconfig/chef-server-webui +10 -0
- data/distro/redhat/etc/sysconfig/chef-solr +9 -0
- data/distro/redhat/etc/sysconfig/chef-solr-indexer +7 -0
- data/distro/suse/etc/init.d/chef-client +121 -0
- data/lib/chef.rb +1 -1
- data/lib/chef/api_client.rb +263 -0
- data/lib/chef/application.rb +1 -1
- data/lib/chef/application/client.rb +21 -3
- data/lib/chef/application/knife.rb +144 -0
- data/lib/chef/application/server.rb +2 -1
- data/lib/chef/application/solo.rb +9 -2
- data/lib/chef/cache.rb +61 -0
- data/lib/chef/cache/checksum.rb +70 -0
- data/lib/chef/certificate.rb +154 -0
- data/lib/chef/client.rb +123 -220
- data/lib/chef/compile.rb +9 -21
- data/lib/chef/config.rb +67 -10
- data/lib/chef/cookbook.rb +49 -22
- data/lib/chef/cookbook/metadata.rb +85 -5
- data/lib/chef/cookbook_loader.rb +4 -4
- data/lib/chef/couchdb.rb +99 -30
- data/lib/chef/daemon.rb +1 -1
- data/lib/chef/data_bag.rb +215 -0
- data/lib/chef/data_bag_item.rb +219 -0
- data/lib/chef/exceptions.rb +3 -0
- data/lib/chef/index_queue.rb +29 -0
- data/lib/chef/index_queue/amqp_client.rb +106 -0
- data/lib/chef/index_queue/consumer.rb +76 -0
- data/lib/chef/index_queue/indexable.rb +74 -0
- data/lib/chef/knife.rb +309 -0
- data/lib/chef/knife/client_bulk_delete.rb +40 -0
- data/lib/chef/knife/client_create.rb +62 -0
- data/lib/chef/knife/client_delete.rb +37 -0
- data/lib/chef/knife/client_edit.rb +37 -0
- data/lib/chef/knife/client_list.rb +40 -0
- data/lib/chef/knife/client_reregister.rb +48 -0
- data/lib/chef/knife/client_show.rb +42 -0
- data/lib/chef/knife/configure.rb +123 -0
- data/lib/chef/knife/cookbook_bulk_delete.rb +46 -0
- data/lib/chef/knife/cookbook_delete.rb +41 -0
- data/lib/chef/knife/cookbook_download.rb +57 -0
- data/lib/chef/knife/cookbook_list.rb +41 -0
- data/lib/chef/knife/cookbook_metadata.rb +87 -0
- data/lib/chef/knife/cookbook_show.rb +75 -0
- data/lib/chef/knife/cookbook_upload.rb +179 -0
- data/lib/chef/knife/data_bag_create.rb +43 -0
- data/lib/chef/knife/data_bag_delete.rb +43 -0
- data/lib/chef/knife/data_bag_edit.rb +49 -0
- data/lib/chef/knife/data_bag_list.rb +42 -0
- data/lib/chef/knife/data_bag_show.rb +40 -0
- data/lib/chef/knife/ec2_instance_data.rb +46 -0
- data/lib/chef/knife/index_rebuild.rb +51 -0
- data/lib/chef/knife/node_bulk_delete.rb +43 -0
- data/lib/chef/knife/node_create.rb +39 -0
- data/lib/chef/knife/node_delete.rb +36 -0
- data/lib/chef/knife/node_edit.rb +36 -0
- data/lib/chef/knife/node_from_file.rb +42 -0
- data/lib/chef/knife/node_list.rb +41 -0
- data/lib/chef/knife/node_run_list_add.rb +64 -0
- data/lib/chef/knife/node_run_list_remove.rb +45 -0
- data/lib/chef/knife/node_show.rb +46 -0
- data/lib/chef/knife/role_bulk_delete.rb +44 -0
- data/lib/chef/knife/role_create.rb +44 -0
- data/lib/chef/knife/role_delete.rb +36 -0
- data/lib/chef/knife/role_edit.rb +37 -0
- data/lib/chef/knife/role_from_file.rb +46 -0
- data/lib/chef/knife/role_list.rb +40 -0
- data/lib/chef/knife/role_show.rb +43 -0
- data/lib/chef/knife/search.rb +94 -0
- data/lib/chef/knife/ssh.rb +170 -0
- data/lib/chef/log.rb +30 -8
- data/lib/chef/mixin/checksum.rb +2 -7
- data/lib/chef/mixin/command.rb +32 -13
- data/lib/chef/mixin/convert_to_class_name.rb +15 -0
- data/lib/chef/mixin/deep_merge.rb +199 -11
- data/lib/chef/mixin/generate_url.rb +18 -9
- data/lib/chef/mixin/language.rb +29 -1
- data/lib/chef/mixin/language_include_attribute.rb +56 -0
- data/lib/chef/mixin/language_include_recipe.rb +53 -0
- data/lib/chef/mixin/params_validate.rb +25 -12
- data/lib/chef/mixin/recipe_definition_dsl_core.rb +2 -0
- data/lib/chef/mixin/template.rb +11 -1
- data/lib/chef/mixin/xml_escape.rb +87 -0
- data/lib/chef/node.rb +144 -122
- data/lib/chef/openid_registration.rb +12 -5
- data/lib/chef/platform.rb +89 -47
- data/lib/chef/provider/breakpoint.rb +36 -0
- data/lib/chef/provider/cron.rb +5 -6
- data/lib/chef/provider/deploy.rb +43 -10
- data/lib/chef/provider/deploy/revision.rb +2 -3
- data/lib/chef/provider/erl_call.rb +72 -0
- data/lib/chef/provider/file.rb +8 -4
- data/lib/chef/provider/git.rb +10 -5
- data/lib/chef/provider/group/dscl.rb +128 -0
- data/lib/chef/provider/http_request.rb +6 -2
- data/lib/chef/provider/ifconfig.rb +1 -0
- data/lib/chef/provider/link.rb +1 -1
- data/lib/chef/provider/log.rb +53 -0
- data/lib/chef/provider/mdadm.rb +88 -0
- data/lib/chef/provider/mount/mount.rb +1 -1
- data/lib/chef/provider/package.rb +1 -1
- data/lib/chef/provider/package/easy_install.rb +106 -0
- data/lib/chef/provider/package/pacman.rb +101 -0
- data/lib/chef/provider/package/portage.rb +1 -1
- data/lib/chef/provider/package/rpm.rb +10 -8
- data/lib/chef/provider/package/yum-dump.py +22 -3
- data/lib/chef/provider/package/yum.rb +32 -8
- data/lib/chef/provider/package/zypper.rb +132 -0
- data/lib/chef/provider/remote_directory.rb +58 -49
- data/lib/chef/provider/remote_file.rb +1 -1
- data/lib/chef/provider/route.rb +136 -80
- data/lib/chef/provider/ruby_block.rb +18 -1
- data/lib/chef/provider/service/arch.rb +109 -0
- data/lib/chef/provider/service/freebsd.rb +0 -1
- data/lib/chef/provider/service/simple.rb +2 -3
- data/lib/chef/provider/service/upstart.rb +191 -0
- data/lib/chef/provider/subversion.rb +12 -4
- data/lib/chef/provider/template.rb +85 -53
- data/lib/chef/provider/user.rb +1 -1
- data/lib/chef/provider/user/dscl.rb +277 -0
- data/lib/chef/provider/user/useradd.rb +1 -0
- data/lib/chef/recipe.rb +2 -41
- data/lib/chef/resource.rb +9 -3
- data/lib/chef/resource/breakpoint.rb +35 -0
- data/lib/chef/resource/deploy.rb +16 -2
- data/lib/chef/resource/easy_install_package.rb +41 -0
- data/lib/chef/resource/erl_call.rb +83 -0
- data/lib/chef/resource/freebsd_package.rb +35 -0
- data/lib/chef/resource/log.rb +62 -0
- data/lib/chef/resource/mdadm.rb +82 -0
- data/lib/chef/resource/pacman_package.rb +33 -0
- data/lib/chef/resource/ruby_block.rb +21 -2
- data/lib/chef/resource/scm.rb +8 -0
- data/lib/chef/resource/subversion.rb +1 -0
- data/lib/chef/resource/user.rb +5 -2
- data/lib/chef/resource/yum_package.rb +36 -0
- data/lib/chef/resource_collection.rb +17 -9
- data/lib/chef/resource_collection/stepable_iterator.rb +124 -0
- data/lib/chef/rest.rb +166 -81
- data/lib/chef/role.rb +114 -38
- data/lib/chef/run_list.rb +15 -6
- data/lib/chef/runner.rb +13 -11
- data/lib/chef/search/query.rb +60 -0
- data/lib/chef/shef.rb +220 -0
- data/lib/chef/shef/ext.rb +297 -0
- data/lib/chef/shef/shef_session.rb +175 -0
- data/lib/chef/streaming_cookbook_uploader.rb +187 -0
- data/lib/chef/tasks/chef_repo.rake +53 -155
- data/lib/chef/util/file_edit.rb +94 -96
- data/lib/chef/webui_user.rb +233 -0
- metadata +219 -63
- data/distro/debian/etc/init.d/chef-indexer +0 -175
- data/distro/redhat/etc/chef/client.rb +0 -16
- data/distro/redhat/etc/chef/indexer.rb +0 -10
- data/distro/redhat/etc/chef/server.rb +0 -22
- data/distro/redhat/etc/init.d/chef-indexer +0 -76
- data/lib/chef/application/indexer.rb +0 -141
- data/lib/chef/queue.rb +0 -145
- data/lib/chef/search.rb +0 -88
- data/lib/chef/search/result.rb +0 -64
- data/lib/chef/search_index.rb +0 -77
- data/lib/chef/util/fileedit.rb +0 -121
@@ -0,0 +1,187 @@
|
|
1
|
+
require 'net/http'
|
2
|
+
require 'mixlib/authentication/signedheaderauth'
|
3
|
+
require 'openssl'
|
4
|
+
|
5
|
+
# inspired by/cargo-culted from http://stanislavvitvitskiy.blogspot.com/2008/12/multipart-post-in-ruby.html
|
6
|
+
# TODO: confirm that code is public domain
|
7
|
+
class Chef
|
8
|
+
class StreamingCookbookUploader
|
9
|
+
|
10
|
+
DefaultHeaders = { 'accept' => 'application/json' }
|
11
|
+
|
12
|
+
class << self
|
13
|
+
|
14
|
+
def post(to_url, user_id, secret_key_filename, params = {}, headers = {})
|
15
|
+
make_request(:post, to_url, user_id, secret_key_filename, params, headers)
|
16
|
+
end
|
17
|
+
|
18
|
+
def put(to_url, user_id, secret_key_filename, params = {}, headers = {})
|
19
|
+
make_request(:put, to_url, user_id, secret_key_filename, params, headers)
|
20
|
+
end
|
21
|
+
|
22
|
+
def make_request(http_verb, to_url, user_id, secret_key_filename, params = {}, headers = {})
|
23
|
+
boundary = '----RubyMultipartClient' + rand(1000000).to_s + 'ZZZZZ'
|
24
|
+
parts = []
|
25
|
+
content_file = nil
|
26
|
+
content_body = nil
|
27
|
+
|
28
|
+
timestamp = Time.now.utc.iso8601
|
29
|
+
secret_key = OpenSSL::PKey::RSA.new(File.read(secret_key_filename))
|
30
|
+
|
31
|
+
unless params.nil? || params.empty?
|
32
|
+
params.each do |key, value|
|
33
|
+
if value.kind_of?(File)
|
34
|
+
content_file = value
|
35
|
+
filepath = value.path
|
36
|
+
filename = File.basename(filepath)
|
37
|
+
parts << StringPart.new( "--" + boundary + "\r\n" +
|
38
|
+
"Content-Disposition: form-data; name=\"" + key.to_s + "\"; filename=\"" + filename + "\"\r\n" +
|
39
|
+
"Content-Type: application/octet-stream\r\n\r\n")
|
40
|
+
parts << StreamPart.new(value, File.size(filepath))
|
41
|
+
parts << StringPart.new("\r\n")
|
42
|
+
else
|
43
|
+
content_body = value.to_s
|
44
|
+
parts << StringPart.new( "--" + boundary + "\r\n" +
|
45
|
+
"Content-Disposition: form-data; name=\"" + key.to_s + "\"\r\n\r\n")
|
46
|
+
parts << StringPart.new(content_body + "\r\n")
|
47
|
+
end
|
48
|
+
end
|
49
|
+
parts << StringPart.new("--" + boundary + "--\r\n")
|
50
|
+
end
|
51
|
+
|
52
|
+
body_stream = MultipartStream.new(parts)
|
53
|
+
|
54
|
+
timestamp = Time.now.utc.iso8601
|
55
|
+
|
56
|
+
url = URI.parse(to_url)
|
57
|
+
|
58
|
+
Chef::Log.logger.debug("Signing: method: #{http_verb}, path: #{url.path}, file: #{content_file}, User-id: #{user_id}, Timestamp: #{timestamp}")
|
59
|
+
|
60
|
+
signing_options = {
|
61
|
+
:http_method=>http_verb,
|
62
|
+
:path=>url.path,
|
63
|
+
:user_id=>user_id,
|
64
|
+
:timestamp=>timestamp}
|
65
|
+
(content_file && signing_options[:file] = content_file) || (signing_options[:body] = (content_body || ""))
|
66
|
+
|
67
|
+
headers.merge!(Mixlib::Authentication::SignedHeaderAuth.signing_object(signing_options).sign(secret_key))
|
68
|
+
|
69
|
+
content_file.rewind if content_file
|
70
|
+
|
71
|
+
# net/http doesn't like symbols for header keys, so we'll to_s each one just in case
|
72
|
+
headers = DefaultHeaders.merge(Hash[*headers.map{ |k,v| [k.to_s, v] }.flatten])
|
73
|
+
|
74
|
+
req = case http_verb
|
75
|
+
when :put
|
76
|
+
Net::HTTP::Put.new(url.path, headers)
|
77
|
+
when :post
|
78
|
+
Net::HTTP::Post.new(url.path, headers)
|
79
|
+
end
|
80
|
+
req.content_length = body_stream.size
|
81
|
+
req.content_type = 'multipart/form-data; boundary=' + boundary unless parts.empty?
|
82
|
+
req.body_stream = body_stream
|
83
|
+
|
84
|
+
http = Net::HTTP.new(url.host, url.port)
|
85
|
+
if url.scheme == "https"
|
86
|
+
http.use_ssl = true
|
87
|
+
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
88
|
+
end
|
89
|
+
res = http.request(req)
|
90
|
+
#res = http.start {|http_proc| http_proc.request(req) }
|
91
|
+
|
92
|
+
# alias status to code and to_s to body for test purposes
|
93
|
+
# TODO: stop the following madness!
|
94
|
+
class << res
|
95
|
+
alias :to_s :body
|
96
|
+
|
97
|
+
# BUGBUG this makes the response compatible with what respsonse_steps expects to test headers (response.headers[] -> response[])
|
98
|
+
def headers
|
99
|
+
self
|
100
|
+
end
|
101
|
+
|
102
|
+
def status
|
103
|
+
code.to_i
|
104
|
+
end
|
105
|
+
end
|
106
|
+
res
|
107
|
+
end
|
108
|
+
|
109
|
+
end
|
110
|
+
|
111
|
+
class StreamPart
|
112
|
+
def initialize(stream, size)
|
113
|
+
@stream, @size = stream, size
|
114
|
+
end
|
115
|
+
|
116
|
+
def size
|
117
|
+
@size
|
118
|
+
end
|
119
|
+
|
120
|
+
# read the specified amount from the stream
|
121
|
+
def read(offset, how_much)
|
122
|
+
@stream.read(how_much)
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
class StringPart
|
127
|
+
def initialize(str)
|
128
|
+
@str = str
|
129
|
+
end
|
130
|
+
|
131
|
+
def size
|
132
|
+
@str.length
|
133
|
+
end
|
134
|
+
|
135
|
+
# read the specified amount from the string startiung at the offset
|
136
|
+
def read(offset, how_much)
|
137
|
+
@str[offset, how_much]
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
class MultipartStream
|
142
|
+
def initialize(parts)
|
143
|
+
@parts = parts
|
144
|
+
@part_no = 0
|
145
|
+
@part_offset = 0
|
146
|
+
end
|
147
|
+
|
148
|
+
def size
|
149
|
+
@parts.inject(0) {|size, part| size + part.size}
|
150
|
+
end
|
151
|
+
|
152
|
+
def read(how_much)
|
153
|
+
return nil if @part_no >= @parts.size
|
154
|
+
|
155
|
+
how_much_current_part = @parts[@part_no].size - @part_offset
|
156
|
+
|
157
|
+
how_much_current_part = if how_much_current_part > how_much
|
158
|
+
how_much
|
159
|
+
else
|
160
|
+
how_much_current_part
|
161
|
+
end
|
162
|
+
|
163
|
+
how_much_next_part = how_much - how_much_current_part
|
164
|
+
|
165
|
+
current_part = @parts[@part_no].read(@part_offset, how_much_current_part)
|
166
|
+
|
167
|
+
# recurse into the next part if the current one was not large enough
|
168
|
+
if how_much_next_part > 0
|
169
|
+
@part_no += 1
|
170
|
+
@part_offset = 0
|
171
|
+
next_part = read(how_much_next_part)
|
172
|
+
current_part + if next_part
|
173
|
+
next_part
|
174
|
+
else
|
175
|
+
''
|
176
|
+
end
|
177
|
+
else
|
178
|
+
@part_offset += how_much_current_part
|
179
|
+
current_part
|
180
|
+
end
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
end
|
185
|
+
|
186
|
+
|
187
|
+
end
|
@@ -24,6 +24,20 @@ require 'chef/cookbook/metadata'
|
|
24
24
|
require 'tempfile'
|
25
25
|
require 'rake'
|
26
26
|
|
27
|
+
# Allow REMOTE options to be overridden on the command line
|
28
|
+
REMOTE_HOST = ENV["REMOTE_HOST"] if ENV["REMOTE_HOST"] != nil
|
29
|
+
REMOTE_SUDO = ENV["REMOTE_SUDO"] if ENV["REMOTE_SUDO"] != nil
|
30
|
+
if defined? REMOTE_HOST
|
31
|
+
REMOTE_PATH_PREFIX = "#{REMOTE_HOST}:"
|
32
|
+
REMOTE_EXEC_PREFIX = "ssh #{REMOTE_HOST}"
|
33
|
+
REMOTE_EXEC_PREFIX += " sudo" if defined? REMOTE_SUDO
|
34
|
+
LOCAL_EXEC_PREFIX = ""
|
35
|
+
else
|
36
|
+
REMOTE_PATH_PREFIX = ""
|
37
|
+
REMOTE_EXEC_PREFIX = ""
|
38
|
+
LOCAL_EXEC_PREFIX = "sudo"
|
39
|
+
end
|
40
|
+
|
27
41
|
desc "Update your repository from source control"
|
28
42
|
task :update do
|
29
43
|
puts "** Updating your repository"
|
@@ -33,7 +47,6 @@ task :update do
|
|
33
47
|
sh %{svn up}
|
34
48
|
when :git
|
35
49
|
pull = false
|
36
|
-
pull = true if File.join(TOPDIR, ".git", "remotes", "origin")
|
37
50
|
IO.foreach(File.join(TOPDIR, ".git", "config")) do |line|
|
38
51
|
pull = true if line =~ /\[remote "origin"\]/
|
39
52
|
end
|
@@ -47,124 +60,15 @@ task :update do
|
|
47
60
|
end
|
48
61
|
end
|
49
62
|
|
50
|
-
desc "Test your cookbooks for syntax errors"
|
51
|
-
task :test_recipes do
|
52
|
-
puts "** Testing your cookbooks for syntax errors"
|
53
|
-
|
54
|
-
if File.exists?(TEST_CACHE)
|
55
|
-
cache = JSON.load(open(TEST_CACHE).read)
|
56
|
-
trap("INT") { puts "INT received, flushing test cache"; write_cache(cache) }
|
57
|
-
else
|
58
|
-
cache = {}
|
59
|
-
end
|
60
|
-
|
61
|
-
recipes = ["*cookbooks"].map { |folder|
|
62
|
-
Dir[File.join(TOPDIR, folder, "**", "*.rb")]
|
63
|
-
}.flatten
|
64
|
-
|
65
|
-
recipes.each do |recipe|
|
66
|
-
print "Testing recipe #{recipe}: "
|
67
|
-
|
68
|
-
recipe_mtime = File.stat(recipe).mtime.to_s
|
69
|
-
if cache.has_key?(recipe)
|
70
|
-
if cache[recipe]["mtime"] == recipe_mtime
|
71
|
-
puts "No modification since last test."
|
72
|
-
next
|
73
|
-
end
|
74
|
-
else
|
75
|
-
cache[recipe] = {}
|
76
|
-
end
|
77
|
-
|
78
|
-
|
79
|
-
sh %{ruby -c #{recipe}} do |ok, res|
|
80
|
-
if ok
|
81
|
-
cache[recipe]["mtime"] = recipe_mtime
|
82
|
-
else
|
83
|
-
write_cache(cache)
|
84
|
-
raise "Syntax error in #{recipe}"
|
85
|
-
end
|
86
|
-
end
|
87
|
-
end
|
88
|
-
|
89
|
-
write_cache(cache)
|
90
|
-
end
|
91
|
-
|
92
|
-
desc "Test your templates for syntax errors"
|
93
|
-
task :test_templates do
|
94
|
-
puts "** Testing your cookbooks for syntax errors"
|
95
|
-
|
96
|
-
if File.exists?(TEST_CACHE)
|
97
|
-
cache = JSON.load(open(TEST_CACHE).read)
|
98
|
-
trap("INT") { puts "INT received, flushing test cache"; write_cache(cache) }
|
99
|
-
else
|
100
|
-
cache = {}
|
101
|
-
end
|
102
|
-
|
103
|
-
templates = ["*cookbooks"].map { |folder|
|
104
|
-
Dir[File.join(TOPDIR, folder, "**", "*.erb")]
|
105
|
-
}.flatten
|
106
|
-
|
107
|
-
templates.each do |template|
|
108
|
-
print "Testing template #{template}: "
|
109
|
-
|
110
|
-
template_mtime = File.stat(template).mtime.to_s
|
111
|
-
if cache.has_key?(template)
|
112
|
-
if cache[template]["mtime"] == template_mtime
|
113
|
-
puts "No change since last test."
|
114
|
-
next
|
115
|
-
end
|
116
|
-
else
|
117
|
-
cache[template] = {}
|
118
|
-
end
|
119
|
-
|
120
|
-
sh %{erubis -x #{template} | ruby -c} do |ok, res|
|
121
|
-
if ok
|
122
|
-
cache[template]["mtime"] = template_mtime
|
123
|
-
else
|
124
|
-
write_cache(cache)
|
125
|
-
raise "Syntax error in #{template}"
|
126
|
-
end
|
127
|
-
end
|
128
|
-
|
129
|
-
end
|
130
|
-
|
131
|
-
write_cache(cache)
|
132
|
-
end
|
133
|
-
|
134
|
-
desc "Test your cookbooks for syntax errors"
|
135
|
-
task :test => [ :test_recipes , :test_templates ]
|
136
|
-
|
137
|
-
def write_cache(cache)
|
138
|
-
File.open(TEST_CACHE, "w") { |f| JSON.dump(cache, f) }
|
139
|
-
end
|
140
|
-
|
141
63
|
desc "Install the latest copy of the repository on this Chef Server"
|
142
|
-
task :install => [ :update, :
|
143
|
-
|
144
|
-
directories = [
|
145
|
-
COOKBOOK_PATH,
|
146
|
-
SITE_COOKBOOK_PATH,
|
147
|
-
CHEF_CONFIG_PATH
|
148
|
-
]
|
149
|
-
puts "* Creating Directories"
|
150
|
-
directories.each do |dir|
|
151
|
-
sh "sudo mkdir -p #{dir}"
|
152
|
-
sh "sudo chown root #{dir}"
|
153
|
-
end
|
154
|
-
puts "* Installing new Cookbooks"
|
155
|
-
sh "sudo rsync -rlP --delete --exclude '.svn' --exclude '.git*' cookbooks/ #{COOKBOOK_PATH}"
|
156
|
-
puts "* Installing new Site Cookbooks"
|
157
|
-
sh "sudo rsync -rlP --delete --exclude '.svn' --exclude '.git*' site-cookbooks/ #{SITE_COOKBOOK_PATH}"
|
158
|
-
puts "* Installing new Node Roles"
|
159
|
-
sh "sudo rsync -rlP --delete --exclude '.svn' --exclude '.git*' roles/ #{ROLE_PATH}"
|
160
|
-
|
161
|
-
if File.exists?(File.join(File.dirname(__FILE__), "config", "server.rb"))
|
64
|
+
task :install => [ :update, :roles, :upload_cookbooks ] do
|
65
|
+
if File.exists?(File.join(TOPDIR, "config", "server.rb"))
|
162
66
|
puts "* Installing new Chef Server Config"
|
163
|
-
sh "
|
67
|
+
sh "#{LOCAL_EXEC_PREFIX} rsync -rlt --delete --exclude '.svn' --exclude '.git*' config/server.rb #{REMOTE_PATH_PREFIX}#{CHEF_SERVER_CONFIG}"
|
164
68
|
end
|
165
|
-
if File.exists?(File.join(
|
69
|
+
if File.exists?(File.join(TOPDIR, "config", "client.rb"))
|
166
70
|
puts "* Installing new Chef Client Config"
|
167
|
-
sh "
|
71
|
+
sh "#{LOCAL_EXEC_PREFIX} rsync -rlt --delete --exclude '.svn' --exclude '.git*' config/client.rb #{REMOTE_PATH_PREFIX}#{CHEF_CLIENT_CONFIG}"
|
168
72
|
end
|
169
73
|
end
|
170
74
|
|
@@ -279,12 +183,13 @@ task :ssl_cert do
|
|
279
183
|
fqdn =~ /^(.+?)\.(.+)$/
|
280
184
|
hostname = $1
|
281
185
|
domain = $2
|
186
|
+
keyfile = fqdn.gsub("*", "wildcard")
|
282
187
|
raise "Must provide FQDN!" unless fqdn && hostname && domain
|
283
188
|
puts "** Creating self signed SSL Certificate for #{fqdn}"
|
284
|
-
sh("(cd #{CADIR} && openssl genrsa 2048 > #{
|
285
|
-
sh("(cd #{CADIR} && chmod 644 #{
|
189
|
+
sh("(cd #{CADIR} && openssl genrsa 2048 > #{keyfile}.key)")
|
190
|
+
sh("(cd #{CADIR} && chmod 644 #{keyfile}.key)")
|
286
191
|
puts "* Generating Self Signed Certificate Request"
|
287
|
-
tf = Tempfile.new("#{
|
192
|
+
tf = Tempfile.new("#{keyfile}.ssl-conf")
|
288
193
|
ssl_config = <<EOH
|
289
194
|
[ req ]
|
290
195
|
distinguished_name = req_distinguished_name
|
@@ -301,47 +206,40 @@ emailAddress = #{SSL_EMAIL_ADDRESS}
|
|
301
206
|
EOH
|
302
207
|
tf.puts(ssl_config)
|
303
208
|
tf.close
|
304
|
-
sh("(cd #{CADIR} && openssl req -config '#{tf.path}' -new -x509 -nodes -sha1 -days 3650 -key #{
|
305
|
-
sh("(cd #{CADIR} && openssl x509 -noout -fingerprint -text < #{
|
306
|
-
sh("(cd #{CADIR} && cat #{
|
307
|
-
sh("(cd #{CADIR} && chmod 644 #{
|
209
|
+
sh("(cd #{CADIR} && openssl req -config '#{tf.path}' -new -x509 -nodes -sha1 -days 3650 -key #{keyfile}.key > #{keyfile}.crt)")
|
210
|
+
sh("(cd #{CADIR} && openssl x509 -noout -fingerprint -text < #{keyfile}.crt > #{keyfile}.info)")
|
211
|
+
sh("(cd #{CADIR} && cat #{keyfile}.crt #{keyfile}.key > #{keyfile}.pem)")
|
212
|
+
sh("(cd #{CADIR} && chmod 644 #{keyfile}.pem)")
|
213
|
+
end
|
214
|
+
|
215
|
+
rule(%r{\b(?:site-)?cookbooks/[^/]+/metadata\.json\Z} => [ proc { |task_name| task_name.sub(/\.[^.]+$/, '.rb') } ]) do |t|
|
216
|
+
system("knife cookbook metadata #{t.source}")
|
308
217
|
end
|
309
218
|
|
310
219
|
desc "Build cookbook metadata.json from metadata.rb"
|
311
|
-
task :metadata
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
if ENV['COOKBOOK']
|
316
|
-
next unless cookbook.name.to_s == ENV['COOKBOOK']
|
317
|
-
end
|
318
|
-
cook_meta = Chef::Cookbook::Metadata.new(cookbook)
|
319
|
-
Chef::Config.cookbook_path.each do |cdir|
|
320
|
-
metadata_rb_file = File.join(cdir, cookbook.name.to_s, 'metadata.rb')
|
321
|
-
metadata_json_file = File.join(cdir, cookbook.name.to_s, 'metadata.json')
|
322
|
-
if File.exists?(metadata_rb_file)
|
323
|
-
puts "Generating metadata for #{cookbook.name}"
|
324
|
-
cook_meta.from_file(metadata_rb_file)
|
325
|
-
File.open(metadata_json_file, "w") do |f|
|
326
|
-
f.write(JSON.pretty_generate(cook_meta))
|
327
|
-
end
|
328
|
-
end
|
329
|
-
end
|
330
|
-
end
|
220
|
+
task :metadata => FileList[File.join(TOPDIR, '*cookbooks', ENV['COOKBOOK'] || '*', 'metadata.rb')].pathmap('%X.json')
|
221
|
+
|
222
|
+
rule(%r{\broles/\S+\.json\Z} => [ proc { |task_name| task_name.sub(/\.[^.]+$/, '.rb') } ]) do |t|
|
223
|
+
system("knife role from file #{t.source}")
|
331
224
|
end
|
332
225
|
|
333
|
-
desc "
|
334
|
-
task :roles
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
226
|
+
desc "Update roles"
|
227
|
+
task :roles => FileList[File.join(TOPDIR, 'roles', '**', '*.rb')].pathmap('%X.json')
|
228
|
+
|
229
|
+
desc "Update a specific role"
|
230
|
+
task :role, :role_name do |t, args|
|
231
|
+
system("knife role from file #{args.cookbook}")
|
232
|
+
end
|
233
|
+
|
234
|
+
desc "Upload all cookbooks"
|
235
|
+
task :upload_cookbooks => [ :metadata ]
|
236
|
+
task :upload_cookbooks do
|
237
|
+
system("knife cookbook upload --all")
|
238
|
+
end
|
239
|
+
|
240
|
+
desc "Upload a single cookbook"
|
241
|
+
task :upload_cookbook => [ :metadata ]
|
242
|
+
task :upload_cookbook, :cookbook do |t, args|
|
243
|
+
system("knife cookbook upload #{args.cookbook}")
|
346
244
|
end
|
347
245
|
|
data/lib/chef/util/file_edit.rb
CHANGED
@@ -20,106 +20,104 @@ require 'fileutils'
|
|
20
20
|
require 'tempfile'
|
21
21
|
|
22
22
|
class Chef
|
23
|
-
|
24
|
-
|
23
|
+
class Util
|
24
|
+
class FileEdit
|
25
25
|
|
26
|
-
|
27
|
-
|
28
|
-
|
26
|
+
private
|
27
|
+
|
28
|
+
attr_accessor :original_pathname, :contents, :file_edited
|
29
29
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
30
|
+
public
|
31
|
+
|
32
|
+
def initialize(filepath)
|
33
|
+
@original_pathname = filepath
|
34
|
+
@file_edited = false
|
35
|
+
|
36
|
+
raise ArgumentError, "File doesn't exist" unless File.exist? @original_pathname
|
37
|
+
raise ArgumentError, "File is blank" unless (@contents = File.new(@original_pathname).readlines).length > 0
|
38
|
+
end
|
39
|
+
|
40
|
+
#search the file line by line and match each line with the given regex
|
41
|
+
#if matched, replace the whole line with newline.
|
42
|
+
def search_file_replace_line(regex, newline)
|
43
|
+
search_match(regex, newline, 'r', 1)
|
44
|
+
end
|
45
45
|
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
46
|
+
#search the file line by line and match each line with the given regex
|
47
|
+
#if matched, replace the match (all occurances) with the replace parameter
|
48
|
+
def search_file_replace(regex, replace)
|
49
|
+
search_match(regex, replace, 'r', 2)
|
50
|
+
end
|
51
|
+
|
52
|
+
#search the file line by line and match each line with the given regex
|
53
|
+
#if matched, delete the line
|
54
|
+
def search_file_delete_line(regex)
|
55
|
+
search_match(regex, " ", 'd', 1)
|
56
|
+
end
|
57
|
+
|
58
|
+
#search the file line by line and match each line with the given regex
|
59
|
+
#if matched, delete the match (all occurances) from the line
|
60
|
+
def search_file_delete(regex)
|
61
|
+
search_match(regex, " ", 'd', 2)
|
62
|
+
end
|
63
63
|
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
64
|
+
#search the file line by line and match each line with the given regex
|
65
|
+
#if matched, insert newline after each matching line
|
66
|
+
def insert_line_after_match(regex, newline)
|
67
|
+
search_match(regex, newline, 'i', 0)
|
68
|
+
end
|
69
|
+
|
70
|
+
#Make a copy of old_file and write new file out (only if file changed)
|
71
|
+
def write_file
|
72
|
+
|
73
|
+
# file_edited is false when there was no match in the whole file and thus no contents have changed.
|
74
|
+
if file_edited
|
75
|
+
backup_pathname = original_pathname + ".old"
|
76
|
+
FileUtils.cp(original_pathname, backup_pathname, :preserve => true)
|
77
|
+
File.open(original_pathname, "w") do |newfile|
|
78
|
+
contents.each do |line|
|
79
|
+
newfile.puts(line)
|
80
|
+
end
|
81
|
+
newfile.flush
|
82
|
+
end
|
83
|
+
end
|
84
|
+
self.file_edited = false
|
85
|
+
end
|
86
|
+
|
87
|
+
private
|
88
|
+
|
89
|
+
#helper method to do the match, replace, delete, and insert operations
|
90
|
+
#command is the switch of delete, replace, and insert ('d', 'r', 'i')
|
91
|
+
#method is to control operation on whole line or only the match (1 for line, 2 for match)
|
92
|
+
def search_match(regex, replace, command, method)
|
93
|
+
|
94
|
+
#convert regex to a Regexp object (if not already is one) and store it in exp.
|
95
|
+
exp = Regexp.new(regex)
|
86
96
|
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
97
|
+
#loop through contents and do the appropriate operation depending on 'command' and 'method'
|
98
|
+
new_contents = []
|
99
|
+
|
100
|
+
contents.each do |line|
|
101
|
+
if line.match(exp)
|
102
|
+
self.file_edited = true
|
103
|
+
case
|
104
|
+
when command == 'r'
|
105
|
+
new_contents << ((method == 1) ? replace : line.gsub!(exp, replace))
|
106
|
+
when command == 'd'
|
107
|
+
if method == 2
|
108
|
+
new_contents << line.gsub!(exp, "")
|
109
|
+
end
|
110
|
+
when command == 'i'
|
111
|
+
new_contents << line
|
112
|
+
new_contents << replace
|
113
|
+
end
|
114
|
+
else
|
115
|
+
new_contents << line
|
116
|
+
end
|
117
|
+
end
|
98
118
|
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
if line.match(exp)
|
104
|
-
self.file_edited = true
|
105
|
-
case
|
106
|
-
when command == 'r'
|
107
|
-
new_contents << ((method == 1) ? replace : line.gsub!(exp, replace))
|
108
|
-
when command == 'd'
|
109
|
-
if method == 2
|
110
|
-
new_contents << line.gsub!(exp, "")
|
111
|
-
end
|
112
|
-
when command == 'i'
|
113
|
-
new_contents << line
|
114
|
-
new_contents << replace
|
115
|
-
end
|
116
|
-
else
|
117
|
-
new_contents << line
|
118
|
-
end
|
119
|
-
end
|
120
|
-
|
121
|
-
self.contents = new_contents
|
122
|
-
end
|
123
|
-
end
|
124
|
-
end
|
119
|
+
self.contents = new_contents
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
125
123
|
end
|