chef 0.9.14.rc.1 → 0.9.14
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/lib/chef/provider/deploy.rb +48 -47
- data/lib/chef/provider/deploy/revision.rb +12 -12
- data/lib/chef/provider/package/yum.rb +15 -2
- data/lib/chef/shef/shef_session.rb +1 -1
- data/lib/chef/shell_out.rb +48 -48
- data/lib/chef/version.rb +1 -1
- metadata +8 -12
data/lib/chef/provider/deploy.rb
CHANGED
@@ -6,9 +6,9 @@
|
|
6
6
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
7
7
|
# you may not use this file except in compliance with the License.
|
8
8
|
# You may obtain a copy of the License at
|
9
|
-
#
|
9
|
+
#
|
10
10
|
# http://www.apache.org/licenses/LICENSE-2.0
|
11
|
-
#
|
11
|
+
#
|
12
12
|
# Unless required by applicable law or agreed to in writing, software
|
13
13
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
14
14
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
@@ -24,40 +24,40 @@ require "chef/provider/subversion"
|
|
24
24
|
class Chef
|
25
25
|
class Provider
|
26
26
|
class Deploy < Chef::Provider
|
27
|
-
|
27
|
+
|
28
28
|
include Chef::Mixin::FromFile
|
29
29
|
include Chef::Mixin::Command
|
30
|
-
|
30
|
+
|
31
31
|
attr_reader :scm_provider, :release_path
|
32
|
-
|
32
|
+
|
33
33
|
def initialize(new_resource, run_context)
|
34
34
|
super(new_resource, run_context)
|
35
|
-
|
35
|
+
|
36
36
|
@scm_provider = new_resource.scm_provider.new(new_resource, run_context)
|
37
|
-
|
37
|
+
|
38
38
|
# @configuration is not used by Deploy, it is only for backwards compat with
|
39
39
|
# chef-deploy or capistrano hooks that might use it to get environment information
|
40
40
|
@configuration = @new_resource.to_hash
|
41
41
|
@configuration[:environment] = @configuration[:environment] && @configuration[:environment]["RAILS_ENV"]
|
42
42
|
end
|
43
|
-
|
43
|
+
|
44
44
|
def load_current_resource
|
45
45
|
@release_path = @new_resource.deploy_to + "/releases/#{release_slug}"
|
46
46
|
end
|
47
|
-
|
47
|
+
|
48
48
|
def sudo(command,&block)
|
49
49
|
execute(command, &block)
|
50
50
|
end
|
51
|
-
|
51
|
+
|
52
52
|
def run(command, &block)
|
53
53
|
exec = execute(command, &block)
|
54
54
|
exec.user(@new_resource.user) if @new_resource.user
|
55
55
|
exec.group(@new_resource.group) if @new_resource.group
|
56
56
|
exec.cwd(release_path) unless exec.cwd
|
57
|
-
exec.environment(@new_resource.environment) unless exec.environment
|
57
|
+
exec.environment(@new_resource.environment) unless exec.environment
|
58
58
|
exec
|
59
59
|
end
|
60
|
-
|
60
|
+
|
61
61
|
def action_deploy
|
62
62
|
if all_releases.include?(release_path)
|
63
63
|
if all_releases[-1] == release_path
|
@@ -71,7 +71,7 @@ class Chef
|
|
71
71
|
@new_resource.updated_by_last_action(true)
|
72
72
|
end
|
73
73
|
end
|
74
|
-
|
74
|
+
|
75
75
|
def action_force_deploy
|
76
76
|
if all_releases.include?(release_path)
|
77
77
|
Chef::Log.info("Already deployed app at #{release_path}, forcing.")
|
@@ -80,7 +80,7 @@ class Chef
|
|
80
80
|
deploy
|
81
81
|
@new_resource.updated_by_last_action(true)
|
82
82
|
end
|
83
|
-
|
83
|
+
|
84
84
|
def action_rollback
|
85
85
|
if release_path
|
86
86
|
rp_index = all_releases.index(release_path)
|
@@ -88,7 +88,7 @@ class Chef
|
|
88
88
|
rp_index += 1
|
89
89
|
releases_to_nuke = all_releases[rp_index..-1]
|
90
90
|
else
|
91
|
-
@release_path = all_releases[-2]
|
91
|
+
@release_path = all_releases[-2]
|
92
92
|
raise RuntimeError, "There is no release to rollback to!" unless @release_path
|
93
93
|
releases_to_nuke = [ all_releases.last ]
|
94
94
|
end
|
@@ -99,12 +99,12 @@ class Chef
|
|
99
99
|
restart
|
100
100
|
releases_to_nuke.each do |i|
|
101
101
|
Chef::Log.info "Removing release: #{i}"
|
102
|
-
FileUtils.rm_rf i
|
102
|
+
FileUtils.rm_rf i
|
103
103
|
release_deleted(i)
|
104
104
|
end
|
105
105
|
@new_resource.updated_by_last_action(true)
|
106
106
|
end
|
107
|
-
|
107
|
+
|
108
108
|
def deploy
|
109
109
|
Chef::Log.info "deploying branch: #{@new_resource.branch}"
|
110
110
|
enforce_ownership
|
@@ -121,7 +121,7 @@ class Chef
|
|
121
121
|
callback(:after_restart, @new_resource.after_restart)
|
122
122
|
cleanup!
|
123
123
|
end
|
124
|
-
|
124
|
+
|
125
125
|
def callback(what, callback_code=nil)
|
126
126
|
@collection = Chef::ResourceCollection.new
|
127
127
|
case callback_code
|
@@ -140,31 +140,31 @@ class Chef
|
|
140
140
|
raise RuntimeError, "You gave me a callback I don't know what to do with: #{callback_code.inspect}"
|
141
141
|
end
|
142
142
|
end
|
143
|
-
|
143
|
+
|
144
144
|
def migrate
|
145
145
|
run_symlinks_before_migrate
|
146
|
-
|
146
|
+
|
147
147
|
if @new_resource.migrate
|
148
148
|
enforce_ownership
|
149
|
-
|
149
|
+
|
150
150
|
environment = @new_resource.environment
|
151
|
-
env_info = environment && environment.map do |key_and_val|
|
151
|
+
env_info = environment && environment.map do |key_and_val|
|
152
152
|
"#{key_and_val.first}='#{key_and_val.last}'"
|
153
153
|
end.join(" ")
|
154
|
-
|
154
|
+
|
155
155
|
Chef::Log.info "Migrating: running #{@new_resource.migration_command} as #{@new_resource.user} " +
|
156
156
|
"with environment #{env_info}"
|
157
157
|
run_command(run_options(:command => @new_resource.migration_command, :cwd=>release_path))
|
158
158
|
end
|
159
159
|
end
|
160
|
-
|
160
|
+
|
161
161
|
def symlink
|
162
162
|
Chef::Log.info "Symlinking"
|
163
163
|
purge_tempfiles_from_current_release
|
164
164
|
link_tempfiles_to_current_release
|
165
165
|
link_current_release_to_production
|
166
166
|
end
|
167
|
-
|
167
|
+
|
168
168
|
def restart
|
169
169
|
if restart_cmd = @new_resource.restart_command
|
170
170
|
if restart_cmd.kind_of?(Proc)
|
@@ -176,7 +176,7 @@ class Chef
|
|
176
176
|
end
|
177
177
|
end
|
178
178
|
end
|
179
|
-
|
179
|
+
|
180
180
|
def cleanup!
|
181
181
|
all_releases[0..-6].each do |old_release|
|
182
182
|
Chef::Log.info "Removing old release #{old_release}"
|
@@ -184,48 +184,49 @@ class Chef
|
|
184
184
|
release_deleted(old_release)
|
185
185
|
end
|
186
186
|
end
|
187
|
-
|
187
|
+
|
188
188
|
def all_releases
|
189
189
|
Dir.glob(@new_resource.deploy_to + "/releases/*").sort
|
190
190
|
end
|
191
|
-
|
191
|
+
|
192
192
|
def update_cached_repo
|
193
|
+
@scm_provider.load_current_resource
|
193
194
|
if @new_resource.svn_force_export
|
194
195
|
svn_force_export
|
195
196
|
else
|
196
197
|
run_scm_sync
|
197
198
|
end
|
198
199
|
end
|
199
|
-
|
200
|
+
|
200
201
|
def run_scm_sync
|
201
202
|
Chef::Log.info "updating the cached checkout"
|
202
203
|
@scm_provider.action_sync
|
203
204
|
end
|
204
|
-
|
205
|
+
|
205
206
|
def svn_force_export
|
206
207
|
Chef::Log.info "exporting source repository to #{@new_resource.destination}"
|
207
208
|
@scm_provider.action_force_export
|
208
209
|
end
|
209
|
-
|
210
|
+
|
210
211
|
def copy_cached_repo
|
211
212
|
Chef::Log.info "copying the cached checkout to #{release_path}"
|
212
213
|
FileUtils.mkdir_p(@new_resource.deploy_to + "/releases")
|
213
214
|
run_command(:command => "cp -RPp #{::File.join(@new_resource.destination, ".")} #{release_path}")
|
214
215
|
release_created(release_path)
|
215
216
|
end
|
216
|
-
|
217
|
+
|
217
218
|
def enforce_ownership
|
218
219
|
Chef::Log.info "ensuring proper ownership"
|
219
220
|
FileUtils.chown_R(@new_resource.user, @new_resource.group, @new_resource.deploy_to)
|
220
221
|
end
|
221
|
-
|
222
|
+
|
222
223
|
def link_current_release_to_production
|
223
224
|
Chef::Log.info "Linking release #{release_path} into production at #{@new_resource.current_path}"
|
224
225
|
FileUtils.rm_f(@new_resource.current_path)
|
225
226
|
FileUtils.ln_sf(release_path, @new_resource.current_path)
|
226
227
|
enforce_ownership
|
227
228
|
end
|
228
|
-
|
229
|
+
|
229
230
|
def run_symlinks_before_migrate
|
230
231
|
links_info = @new_resource.symlink_before_migrate.map { |src, dst| "#{src} => #{dst}" }.join(", ")
|
231
232
|
Chef::Log.info "Making pre-migration symlinks: #{links_info}"
|
@@ -233,12 +234,12 @@ class Chef
|
|
233
234
|
FileUtils.ln_sf(@new_resource.shared_path + "/#{src}", release_path + "/#{dest}")
|
234
235
|
end
|
235
236
|
end
|
236
|
-
|
237
|
+
|
237
238
|
def link_tempfiles_to_current_release
|
238
239
|
dirs_info = @new_resource.create_dirs_before_symlink.join(",")
|
239
240
|
Chef::Log.info("creating directories before symlink: #{dirs_info}")
|
240
241
|
@new_resource.create_dirs_before_symlink.each { |dir| FileUtils.mkdir_p(release_path + "/#{dir}") }
|
241
|
-
|
242
|
+
|
242
243
|
links_info = @new_resource.symlinks.map { |src, dst| "#{src} => #{dst}" }.join(", ")
|
243
244
|
Chef::Log.info("Linking shared paths into current release: #{links_info}")
|
244
245
|
@new_resource.symlinks.each do |src, dest|
|
@@ -247,32 +248,32 @@ class Chef
|
|
247
248
|
run_symlinks_before_migrate
|
248
249
|
enforce_ownership
|
249
250
|
end
|
250
|
-
|
251
|
+
|
251
252
|
def create_dirs_before_symlink
|
252
253
|
end
|
253
|
-
|
254
|
+
|
254
255
|
def purge_tempfiles_from_current_release
|
255
256
|
log_info = @new_resource.purge_before_symlink.join(", ")
|
256
257
|
Chef::Log.info("Purging directories in checkout #{log_info}")
|
257
258
|
@new_resource.purge_before_symlink.each { |dir| FileUtils.rm_rf(release_path + "/#{dir}") }
|
258
259
|
end
|
259
|
-
|
260
|
+
|
260
261
|
protected
|
261
|
-
|
262
|
+
|
262
263
|
# Internal callback, called after copy_cached_repo.
|
263
264
|
# Override if you need to keep state externally.
|
264
265
|
def release_created(release_path)
|
265
266
|
end
|
266
|
-
|
267
|
+
|
267
268
|
# Internal callback, called during cleanup! for each old release removed.
|
268
269
|
# Override if you need to keep state externally.
|
269
270
|
def release_deleted(release_path)
|
270
271
|
end
|
271
|
-
|
272
|
+
|
272
273
|
def release_slug
|
273
274
|
raise Chef::Exceptions::Override, "You must override release_slug in #{self.to_s}"
|
274
275
|
end
|
275
|
-
|
276
|
+
|
276
277
|
def install_gems
|
277
278
|
gem_resource_collection_runner.converge
|
278
279
|
end
|
@@ -288,7 +289,7 @@ class Chef
|
|
288
289
|
def gem_packages
|
289
290
|
return [] unless ::File.exist?("#{release_path}/gems.yml")
|
290
291
|
gems = YAML.load(IO.read("#{release_path}/gems.yml"))
|
291
|
-
|
292
|
+
|
292
293
|
gems.map do |g|
|
293
294
|
r = Chef::Resource::GemPackage.new(g[:name])
|
294
295
|
r.version g[:version]
|
@@ -297,14 +298,14 @@ class Chef
|
|
297
298
|
r
|
298
299
|
end
|
299
300
|
end
|
300
|
-
|
301
|
+
|
301
302
|
def run_options(run_opts={})
|
302
303
|
run_opts[:user] = @new_resource.user if @new_resource.user
|
303
304
|
run_opts[:group] = @new_resource.group if @new_resource.group
|
304
305
|
run_opts[:environment] = @new_resource.environment if @new_resource.environment
|
305
306
|
run_opts
|
306
307
|
end
|
307
|
-
|
308
|
+
|
308
309
|
def run_callback_from_file(callback_file)
|
309
310
|
if ::File.exist?(callback_file)
|
310
311
|
Dir.chdir(release_path) do
|
@@ -313,7 +314,7 @@ class Chef
|
|
313
314
|
end
|
314
315
|
end
|
315
316
|
end
|
316
|
-
|
317
|
+
|
317
318
|
end
|
318
319
|
end
|
319
320
|
end
|
@@ -6,9 +6,9 @@
|
|
6
6
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
7
7
|
# you may not use this file except in compliance with the License.
|
8
8
|
# You may obtain a copy of the License at
|
9
|
-
#
|
9
|
+
#
|
10
10
|
# http://www.apache.org/licenses/LICENSE-2.0
|
11
|
-
#
|
11
|
+
#
|
12
12
|
# Unless required by applicable law or agreed to in writing, software
|
13
13
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
14
14
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
@@ -24,27 +24,27 @@ class Chef
|
|
24
24
|
class Provider
|
25
25
|
class Deploy
|
26
26
|
class Revision < Chef::Provider::Deploy
|
27
|
-
|
27
|
+
|
28
28
|
def all_releases
|
29
29
|
sorted_releases
|
30
30
|
end
|
31
|
-
|
31
|
+
|
32
32
|
protected
|
33
|
-
|
33
|
+
|
34
34
|
def release_created(release)
|
35
35
|
sorted_releases {|r| r.delete(release); r << release }
|
36
36
|
end
|
37
|
-
|
37
|
+
|
38
38
|
def release_deleted(release)
|
39
39
|
sorted_releases { |r| r.delete(release)}
|
40
40
|
end
|
41
|
-
|
41
|
+
|
42
42
|
def release_slug
|
43
43
|
scm_provider.revision_slug
|
44
44
|
end
|
45
|
-
|
45
|
+
|
46
46
|
private
|
47
|
-
|
47
|
+
|
48
48
|
def sorted_releases
|
49
49
|
cache = load_cache
|
50
50
|
if block_given?
|
@@ -53,7 +53,7 @@ class Chef
|
|
53
53
|
end
|
54
54
|
cache
|
55
55
|
end
|
56
|
-
|
56
|
+
|
57
57
|
def sorted_releases_from_filesystem
|
58
58
|
Dir.glob(new_resource.deploy_to + "/releases/*").sort_by { |d| ::File.ctime(d) }
|
59
59
|
end
|
@@ -65,12 +65,12 @@ class Chef
|
|
65
65
|
sorted_releases_from_filesystem
|
66
66
|
end
|
67
67
|
end
|
68
|
-
|
68
|
+
|
69
69
|
def save_cache(cache)
|
70
70
|
Chef::FileCache.store("revision-deploys/#{new_resource.name}", cache.to_json)
|
71
71
|
cache
|
72
72
|
end
|
73
|
-
|
73
|
+
|
74
74
|
end
|
75
75
|
end
|
76
76
|
end
|
@@ -108,12 +108,25 @@ class Chef
|
|
108
108
|
if (package_data = @data[package_name])
|
109
109
|
if (available_versions = package_data[:available])
|
110
110
|
if arch
|
111
|
-
|
111
|
+
# arch gets passed like ".x86_64"
|
112
|
+
matching_versions = [ available_versions[arch.sub(/^./, '')]]
|
112
113
|
else
|
113
114
|
matching_versions = available_versions.values
|
114
115
|
end
|
115
116
|
|
117
|
+
if matching_versions.nil?
|
118
|
+
if arch.empty?
|
119
|
+
arch_msg = ""
|
120
|
+
else
|
121
|
+
arch_msg = "with arch #{arch.sub(/^./, '')} "
|
122
|
+
end
|
123
|
+
|
124
|
+
raise ArgumentError, "#{package_name}: Found no available versions #{arch_msg}to match"
|
125
|
+
end
|
126
|
+
|
127
|
+
# Expect [ { :version => "ver", :release => "rel" }, { :version => "ver", :release => "rel" }, { :version => "ver", :release => "rel" } ] ???
|
116
128
|
matching_versions.each do |ver|
|
129
|
+
Chef::Log.debug("#{package_name}: trying to match #{desired_version} to version #{ver[:version]} and release #{ver[:release]}")
|
117
130
|
if (desired_version == "#{ver[:version]}-#{ver[:release]}")
|
118
131
|
return true
|
119
132
|
end
|
@@ -205,7 +218,7 @@ class Chef
|
|
205
218
|
:command => "yum -d0 -e0 -y #{@new_resource.options} install #{name}-#{version}#{yum_arch}"
|
206
219
|
)
|
207
220
|
else
|
208
|
-
raise ArgumentError, "#{new_resource.name}: Version #{version} of #{name} not found. Did you specify both version and release? (version-release, e.g. 1.84-10.fc6)"
|
221
|
+
raise ArgumentError, "#{@new_resource.name}: Version #{version} of #{name} not found. Did you specify both version and release? (version-release, e.g. 1.84-10.fc6)"
|
209
222
|
end
|
210
223
|
end
|
211
224
|
@yum.flush
|
@@ -186,7 +186,7 @@ module Shef
|
|
186
186
|
@run_status = Chef::RunStatus.new(@node)
|
187
187
|
Chef::Cookbook::FileVendor.on_create { |manifest| Chef::Cookbook::RemoteFileVendor.new(manifest, Chef::REST.new(Chef::Config[:server_url])) }
|
188
188
|
cookbook_hash = @client.sync_cookbooks
|
189
|
-
run_context = Chef::RunContext.new(node, Chef::CookbookCollection.new(cookbook_hash))
|
189
|
+
@run_context = Chef::RunContext.new(node, Chef::CookbookCollection.new(cookbook_hash))
|
190
190
|
@run_status.run_context = run_context
|
191
191
|
end
|
192
192
|
|
data/lib/chef/shell_out.rb
CHANGED
@@ -6,9 +6,9 @@
|
|
6
6
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
7
7
|
# you may not use this file except in compliance with the License.
|
8
8
|
# You may obtain a copy of the License at
|
9
|
-
#
|
9
|
+
#
|
10
10
|
# http://www.apache.org/licenses/LICENSE-2.0
|
11
|
-
#
|
11
|
+
#
|
12
12
|
# Unless required by applicable law or agreed to in writing, software
|
13
13
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
14
14
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
@@ -28,9 +28,9 @@ class Chef
|
|
28
28
|
# Provides a simplified interface to shelling out yet still collecting both
|
29
29
|
# standard out and standard error and providing full control over environment,
|
30
30
|
# working directory, uid, gid, etc.
|
31
|
-
#
|
31
|
+
#
|
32
32
|
# No means for passing input to the subprocess is provided, nor is there any
|
33
|
-
# way to inspect the output of the command as it is being read. If you need
|
33
|
+
# way to inspect the output of the command as it is being read. If you need
|
34
34
|
# to do that, you have to use popen4 (in Chef::Mixin::Command)
|
35
35
|
#
|
36
36
|
# === Platform Support
|
@@ -41,16 +41,16 @@ class Chef
|
|
41
41
|
READ_SIZE = 4096
|
42
42
|
DEFAULT_READ_TIMEOUT = 60
|
43
43
|
DEFAULT_ENVIRONMENT = {'LC_ALL' => 'C'}
|
44
|
-
|
44
|
+
|
45
45
|
attr_accessor :user, :group, :cwd, :valid_exit_codes
|
46
46
|
attr_reader :command, :umask, :environment
|
47
47
|
attr_writer :timeout
|
48
48
|
attr_reader :execution_time
|
49
|
-
|
49
|
+
|
50
50
|
attr_reader :stdout, :stderr, :status
|
51
|
-
|
51
|
+
|
52
52
|
attr_reader :stdin_pipe, :stdout_pipe, :stderr_pipe, :process_status_pipe
|
53
|
-
|
53
|
+
|
54
54
|
# === Arguments:
|
55
55
|
# Takes a single command, or a list of command fragments. These are used
|
56
56
|
# as arguments to Kernel.exec. See the Kernel.exec documentation for more
|
@@ -97,34 +97,34 @@ class Chef
|
|
97
97
|
def initialize(*command_args)
|
98
98
|
@stdout, @stderr = '', ''
|
99
99
|
@environment = DEFAULT_ENVIRONMENT
|
100
|
-
@cwd =
|
100
|
+
@cwd = nil
|
101
101
|
@valid_exit_codes = [0]
|
102
102
|
|
103
103
|
if command_args.last.is_a?(Hash)
|
104
104
|
parse_options(command_args.pop)
|
105
105
|
end
|
106
|
-
|
106
|
+
|
107
107
|
@command = command_args.size == 1 ? command_args.first : command_args
|
108
108
|
end
|
109
|
-
|
109
|
+
|
110
110
|
def umask=(new_umask)
|
111
111
|
@umask = (new_umask.respond_to?(:oct) ? new_umask.oct : new_umask.to_i) & 007777
|
112
112
|
end
|
113
|
-
|
113
|
+
|
114
114
|
def uid
|
115
115
|
return nil unless user
|
116
116
|
user.kind_of?(Integer) ? user : Etc.getpwnam(user.to_s).uid
|
117
117
|
end
|
118
|
-
|
118
|
+
|
119
119
|
def gid
|
120
120
|
return nil unless group
|
121
121
|
group.kind_of?(Integer) ? group : Etc.getgrnam(group.to_s).gid
|
122
122
|
end
|
123
|
-
|
123
|
+
|
124
124
|
def timeout
|
125
125
|
@timeout || DEFAULT_READ_TIMEOUT
|
126
126
|
end
|
127
|
-
|
127
|
+
|
128
128
|
# Creates a String showing the output of the command, including a banner
|
129
129
|
# showing the exact command executed. Used by +invalid!+ to show command
|
130
130
|
# results when the command exited with an unexpected status.
|
@@ -137,11 +137,11 @@ class Chef
|
|
137
137
|
msg << "Ran #{command} returned #{status.exitstatus}" if status
|
138
138
|
msg
|
139
139
|
end
|
140
|
-
|
140
|
+
|
141
141
|
def exitstatus
|
142
142
|
@status && @status.exitstatus
|
143
143
|
end
|
144
|
-
|
144
|
+
|
145
145
|
# Run the command, writing the command's standard out and standard error
|
146
146
|
# to +stdout+ and +stderr+, and saving its exit status object to +status+
|
147
147
|
# === Returns
|
@@ -156,13 +156,13 @@ class Chef
|
|
156
156
|
def run_command
|
157
157
|
Chef::Log.debug("sh(#{@command})")
|
158
158
|
@child_pid = fork_subprocess
|
159
|
-
|
159
|
+
|
160
160
|
configure_parent_process_file_descriptors
|
161
161
|
propagate_pre_exec_failure
|
162
|
-
|
162
|
+
|
163
163
|
@result = nil
|
164
164
|
@execution_time = 0
|
165
|
-
|
165
|
+
|
166
166
|
# Ruby 1.8.7 and 1.8.6 from mid 2009 try to allocate objects during GC
|
167
167
|
# when calling IO.select and IO#read. Some OS Vendors are not interested
|
168
168
|
# in updating their ruby packages (Apple, *cough*) and we *have to*
|
@@ -176,14 +176,14 @@ class Chef
|
|
176
176
|
raise Chef::Exceptions::CommandTimeout, "command timed out:\n#{format_for_exception}"
|
177
177
|
end
|
178
178
|
end
|
179
|
-
|
179
|
+
|
180
180
|
if ready && ready.first.include?(child_stdout)
|
181
181
|
read_stdout_to_buffer
|
182
182
|
end
|
183
183
|
if ready && ready.first.include?(child_stderr)
|
184
184
|
read_stderr_to_buffer
|
185
185
|
end
|
186
|
-
|
186
|
+
|
187
187
|
unless @status
|
188
188
|
# make one more pass to get the last of the output after the
|
189
189
|
# child process dies
|
@@ -205,8 +205,8 @@ class Chef
|
|
205
205
|
GC.enable
|
206
206
|
close_all_pipes
|
207
207
|
end
|
208
|
-
|
209
|
-
# Checks the +exitstatus+ against the set of +valid_exit_codes+. If
|
208
|
+
|
209
|
+
# Checks the +exitstatus+ against the set of +valid_exit_codes+. If
|
210
210
|
# +exitstatus+ is not in the list of +valid_exit_codes+, calls +invalid!+,
|
211
211
|
# which raises an Exception.
|
212
212
|
# === Returns
|
@@ -231,15 +231,15 @@ class Chef
|
|
231
231
|
msg ||= "Command produced unexpected results"
|
232
232
|
raise Chef::Exceptions::ShellCommandFailed, msg + "\n" + format_for_exception
|
233
233
|
end
|
234
|
-
|
234
|
+
|
235
235
|
def inspect
|
236
236
|
"<#{self.class.name}##{object_id}: command: '#@command' process_status: #{@status.inspect} " +
|
237
|
-
"stdout: '#{stdout.strip}' stderr: '#{stderr.strip}' child_pid: #{@child_pid.inspect} " +
|
237
|
+
"stdout: '#{stdout.strip}' stderr: '#{stderr.strip}' child_pid: #{@child_pid.inspect} " +
|
238
238
|
"environment: #{@environment.inspect} timeout: #{timeout} user: #@user group: #@group working_dir: #@cwd >"
|
239
239
|
end
|
240
240
|
|
241
241
|
private
|
242
|
-
|
242
|
+
|
243
243
|
def parse_options(opts)
|
244
244
|
opts.each do |option, setting|
|
245
245
|
case option.to_s
|
@@ -263,31 +263,31 @@ class Chef
|
|
263
263
|
end
|
264
264
|
end
|
265
265
|
end
|
266
|
-
|
266
|
+
|
267
267
|
def set_user
|
268
268
|
if user
|
269
269
|
Process.euid = uid
|
270
270
|
Process.uid = uid
|
271
271
|
end
|
272
|
-
end
|
273
|
-
|
272
|
+
end
|
273
|
+
|
274
274
|
def set_group
|
275
275
|
if group
|
276
276
|
Process.egid = gid
|
277
277
|
Process.gid = gid
|
278
278
|
end
|
279
279
|
end
|
280
|
-
|
280
|
+
|
281
281
|
def set_environment
|
282
282
|
environment.each do |env_var,value|
|
283
283
|
ENV[env_var] = value
|
284
284
|
end
|
285
285
|
end
|
286
|
-
|
286
|
+
|
287
287
|
def set_umask
|
288
288
|
File.umask(umask) if umask
|
289
289
|
end
|
290
|
-
|
290
|
+
|
291
291
|
def set_cwd
|
292
292
|
Dir.chdir(cwd) if cwd
|
293
293
|
end
|
@@ -296,31 +296,31 @@ class Chef
|
|
296
296
|
@stdout_pipe, @stderr_pipe, @process_status_pipe = IO.pipe, IO.pipe, IO.pipe
|
297
297
|
@process_status_pipe.last.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC)
|
298
298
|
end
|
299
|
-
|
299
|
+
|
300
300
|
def child_stdout
|
301
301
|
@stdout_pipe[0]
|
302
302
|
end
|
303
|
-
|
303
|
+
|
304
304
|
def child_stderr
|
305
305
|
@stderr_pipe[0]
|
306
306
|
end
|
307
|
-
|
307
|
+
|
308
308
|
def child_process_status
|
309
309
|
@process_status_pipe[0]
|
310
310
|
end
|
311
|
-
|
311
|
+
|
312
312
|
def close_all_pipes
|
313
313
|
child_stdout.close unless child_stdout.closed?
|
314
314
|
child_stderr.close unless child_stderr.closed?
|
315
315
|
child_process_status.close unless child_process_status.closed?
|
316
316
|
end
|
317
|
-
|
317
|
+
|
318
318
|
# replace stdout, and stderr with pipes to the parent, and close the
|
319
319
|
# reader side of the error marshaling side channel. Close STDIN so when we
|
320
320
|
# exec, the new program will know it's never getting input ever.
|
321
321
|
def configure_subprocess_file_descriptors
|
322
322
|
process_status_pipe.first.close
|
323
|
-
|
323
|
+
|
324
324
|
# HACK: for some reason, just STDIN.close isn't good enough when running
|
325
325
|
# under ruby 1.9.2, so make it good enough:
|
326
326
|
stdin_reader, stdin_writer = IO.pipe
|
@@ -338,7 +338,7 @@ class Chef
|
|
338
338
|
|
339
339
|
STDOUT.sync = STDERR.sync = true
|
340
340
|
end
|
341
|
-
|
341
|
+
|
342
342
|
def configure_parent_process_file_descriptors
|
343
343
|
# Close the sides of the pipes we don't care about
|
344
344
|
stdout_pipe.last.close
|
@@ -350,7 +350,7 @@ class Chef
|
|
350
350
|
|
351
351
|
true
|
352
352
|
end
|
353
|
-
|
353
|
+
|
354
354
|
# Some patch levels of ruby in wide use (in particular the ruby 1.8.6 on OSX)
|
355
355
|
# segfault when you IO.select a pipe that's reached eof. Weak sauce.
|
356
356
|
def open_pipes
|
@@ -365,7 +365,7 @@ class Chef
|
|
365
365
|
rescue EOFError
|
366
366
|
open_pipes.delete_at(0)
|
367
367
|
end
|
368
|
-
|
368
|
+
|
369
369
|
def read_stderr_to_buffer
|
370
370
|
while chunk = child_stderr.read_nonblock(READ_SIZE)
|
371
371
|
@stderr << chunk
|
@@ -374,13 +374,13 @@ class Chef
|
|
374
374
|
rescue EOFError
|
375
375
|
open_pipes.delete_at(1)
|
376
376
|
end
|
377
|
-
|
377
|
+
|
378
378
|
def fork_subprocess
|
379
379
|
initialize_ipc
|
380
|
-
|
380
|
+
|
381
381
|
fork do
|
382
382
|
configure_subprocess_file_descriptors
|
383
|
-
|
383
|
+
|
384
384
|
set_user
|
385
385
|
set_group
|
386
386
|
set_environment
|
@@ -389,7 +389,7 @@ class Chef
|
|
389
389
|
|
390
390
|
begin
|
391
391
|
command.kind_of?(Array) ? exec(*command) : exec(command)
|
392
|
-
|
392
|
+
|
393
393
|
raise 'forty-two' # Should never get here
|
394
394
|
rescue Exception => e
|
395
395
|
Marshal.dump(e, process_status_pipe.last)
|
@@ -399,7 +399,7 @@ class Chef
|
|
399
399
|
exit!
|
400
400
|
end
|
401
401
|
end
|
402
|
-
|
402
|
+
|
403
403
|
# Attempt to get a Marshaled error from the side-channel.
|
404
404
|
# If it's there, un-marshal it and raise. If it's not there,
|
405
405
|
# assume everything went well.
|
@@ -413,6 +413,6 @@ class Chef
|
|
413
413
|
child_process_status.close
|
414
414
|
end
|
415
415
|
end
|
416
|
-
|
416
|
+
|
417
417
|
end
|
418
418
|
end
|
data/lib/chef/version.rb
CHANGED
metadata
CHANGED
@@ -1,15 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: chef
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
5
|
-
prerelease:
|
4
|
+
hash: 39
|
5
|
+
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 9
|
9
9
|
- 14
|
10
|
-
|
11
|
-
- 1
|
12
|
-
version: 0.9.14.rc.1
|
10
|
+
version: 0.9.14
|
13
11
|
platform: ruby
|
14
12
|
authors:
|
15
13
|
- Adam Jacob
|
@@ -17,7 +15,7 @@ autorequire:
|
|
17
15
|
bindir: bin
|
18
16
|
cert_chain: []
|
19
17
|
|
20
|
-
date: 2011-
|
18
|
+
date: 2011-03-04 00:00:00 -08:00
|
21
19
|
default_executable:
|
22
20
|
dependencies:
|
23
21
|
- !ruby/object:Gem::Dependency
|
@@ -630,14 +628,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
630
628
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
631
629
|
none: false
|
632
630
|
requirements:
|
633
|
-
- - "
|
631
|
+
- - ">="
|
634
632
|
- !ruby/object:Gem::Version
|
635
|
-
hash:
|
633
|
+
hash: 3
|
636
634
|
segments:
|
637
|
-
-
|
638
|
-
|
639
|
-
- 1
|
640
|
-
version: 1.3.1
|
635
|
+
- 0
|
636
|
+
version: "0"
|
641
637
|
requirements: []
|
642
638
|
|
643
639
|
rubyforge_project:
|