summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTim Hinderliter <tim@opscode.com>2010-10-29 15:11:07 -0700
committerTim Hinderliter <tim@opscode.com>2010-10-29 15:11:07 -0700
commit9f582d3851a6c76669424e947d38a4bd6df7c0b4 (patch)
treedde893f8e018c8e44340a2415e9d3a2bfe63a173
parentfd10a6dfe5f22f3b65b6fce72c44288f7efd17ba (diff)
downloadchef-9f582d3851a6c76669424e947d38a4bd6df7c0b4.tar.gz
Fix CHEF-1835 -- child chef-chef now spawned using
fork/exec instead of popen4, so we don't use grep shenanigans to determine its pid.
-rw-r--r--features/data/cookbooks/run_interval/recipes/default.rb11
-rw-r--r--features/steps/run_client_steps.rb72
2 files changed, 55 insertions, 28 deletions
diff --git a/features/data/cookbooks/run_interval/recipes/default.rb b/features/data/cookbooks/run_interval/recipes/default.rb
index 4b7f432de2..d0e6c30d15 100644
--- a/features/data/cookbooks/run_interval/recipes/default.rb
+++ b/features/data/cookbooks/run_interval/recipes/default.rb
@@ -2,7 +2,7 @@
# Cookbook Name:: run_interval
# Recipe:: default
#
-# Copyright 2009, Opscode
+# Copyright 2009, 2010, Opscode
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -16,3 +16,12 @@
# See the License for the specific language governing permissions and
# limitations under the License.
#
+
+# Force chef-client to exit once this cookbook has been applied twice.
+# The test depends on chef having run twice, so this number is tied to
+# run_interval.feature!
+
+$run_interval_global ||= 2
+
+$run_interval_global -= 1
+exit(2) if $run_interval_global == 0
diff --git a/features/steps/run_client_steps.rb b/features/steps/run_client_steps.rb
index 34e6ce2180..c8361ba773 100644
--- a/features/steps/run_client_steps.rb
+++ b/features/steps/run_client_steps.rb
@@ -23,16 +23,19 @@ include Chef::Mixin::ShellOut
CHEF_CLIENT = File.join(CHEF_PROJECT_ROOT, "chef", "bin", "chef-client")
+def chef_client_command_string
+ @log_level ||= ENV["LOG_LEVEL"] ? ENV["LOG_LEVEL"] : "error"
+ @chef_args ||= ""
+ @config_file ||= File.expand_path(File.join(configdir, 'client.rb'))
+
+ "#{File.join(File.dirname(__FILE__), "..", "..", "chef", "bin", "chef-client")} -l #{@log_level} -c #{@config_file} #{@chef_args}"
+end
###
# When
###
When /^I run the chef\-client$/ do
- @log_level ||= ENV["LOG_LEVEL"] ? ENV["LOG_LEVEL"] : "error"
- @chef_args ||= ""
- @config_file ||= File.expand_path(File.join(configdir, 'client.rb'))
- status = Chef::Mixin::Command.popen4(
- "#{File.join(File.dirname(__FILE__), "..", "..", "chef", "bin", "chef-client")} -l #{@log_level} -c #{@config_file} #{@chef_args}") do |p, i, o, e|
+ status = Chef::Mixin::Command.popen4(chef_client_command_string()) do |p, i, o, e|
@stdout = o.gets(nil)
@stderr = e.gets(nil)
end
@@ -65,29 +68,44 @@ When /^I run the chef\-client with '(.+)' for '(.+)' seconds$/ do |args, run_for
end
When /^I run the chef\-client for '(.+)' seconds$/ do |run_for|
- cid = Process.fork {
- sleep run_for.to_i
-
- client_pid = `ps ax | grep chef-client | grep -v grep | grep -v rake | grep -v cucumber | awk '{ print $1 }'`.to_i
-
- # Send a SIGINT to the child process so it has a chance to cleanly exit,
- # including flushing its stdout.
- Process.kill("INT", client_pid)
-
- sleep 1
-
- # Send KILL to the child chef-client. Due to OHAI-223, where ohai sometimes
- # ignores/doesn't exit correctly on receipt of SIGINT, brutally kill the
- # subprocess.
- begin
- Process.kill("KILL", client_pid)
- rescue Errno::ESRCH
- # SIGINT worked above, so the KILL failed. Ignore it as this means things
- # are working the way they're supposed to.
+ # Normal behavior depends on the run_interval/recipes/default.rb to count down
+ # and exit subordinate chef-client after two runs. However, we will forcably
+ # kill the client if that didn't work.
+ begin
+ stdout_filename = "/tmp/chef.run_interval.stdout.#{$$}.txt"
+ stderr_filename = "/tmp/chef.run_interval.stderr.#{$$}.txt"
+ client_pid = Process.fork do
+ STDOUT.reopen(File.open(stdout_filename, "w"))
+ STDERR.reopen(File.open(stderr_filename, "w"))
+ exec "#{chef_client_command_string}"
+ exit 2
end
- }
- When 'I run the chef-client'
- Process.waitpid2(cid)
+
+ killer_pid = Process.fork {
+ sleep run_for.to_i
+
+ # Send KILL to the child chef-client. Due to OHAI-223, where ohai sometimes
+ # ignores/doesn't exit correctly on receipt of SIGINT, brutally kill the
+ # subprocess.
+ begin
+ Process.kill("KILL", client_pid)
+ rescue Errno::ESRCH
+ # Kill didn't work; the process exited while we were waiting, like
+ # it's supposed to.
+ end
+ }
+
+ Process.waitpid2(killer_pid)
+ @status = Process.waitpid2(client_pid).last
+
+ # Read these in so they can be used in later steps.
+ @stdout = IO.read(stdout_filename)
+ @stderr = IO.read(stderr_filename)
+ ensure
+ # clean up after ourselves.
+ File.delete(stdout_filename)
+ File.delete(stderr_filename)
+ end
end
When /^I run the chef\-client at log level '(.+)'$/ do |log_level|