summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLamont Granquist <lamont@scriptkiddie.org>2014-09-26 15:08:09 -0700
committerLamont Granquist <lamont@scriptkiddie.org>2014-09-26 15:08:09 -0700
commit718d032e973f50856e08838c8b7e79f1df341bab (patch)
treebb1b9972ed3ad8909a22fd9dcb1fff2ca379e5b6
parent791232c8e08743447fd2a1bf4eb69b87e5d24c00 (diff)
downloadchef-lcg/signal-nightmare.tar.gz
possible solution to sig handlinglcg/signal-nightmare
-rw-r--r--lib/chef/application/client.rb41
-rw-r--r--spec/unit/application/client_spec.rb7
2 files changed, 26 insertions, 22 deletions
diff --git a/lib/chef/application/client.rb b/lib/chef/application/client.rb
index 6c06ad656d..8e8954c832 100644
--- a/lib/chef/application/client.rb
+++ b/lib/chef/application/client.rb
@@ -301,6 +301,7 @@ class Chef::Application::Client < Chef::Application
SELF_PIPE.replace IO.pipe
trap("USR1") do
+ puts "USR1 CAUGHT!"
Chef::Log.info("SIGUSR1 received, waking up")
SELF_PIPE[1].putc(IMMEDIATE_RUN_SIGNAL) # wakeup master process from select
end
@@ -322,25 +323,22 @@ class Chef::Application::Client < Chef::Application
Chef::Daemon.daemonize("chef-client")
end
- signal = nil
-
loop do
begin
- Chef::Application.exit!("Exiting", 0) if signal == GRACEFUL_EXIT_SIGNAL
+ @signal = get_signal
- if Chef::Config[:splay] and signal != IMMEDIATE_RUN_SIGNAL
- splay = rand Chef::Config[:splay]
- Chef::Log.debug("Splay sleep #{splay} seconds")
- sleep splay
+ if ( Chef::Config[:splay] || Chef::Config[:interval] ) && !@signal
+ puts "THE FUCK?!?!?"
+ splay = ( rand Chef::Config[:splay] ) + Chef::Config[:interval] # FIXME: nil handling?
+ Chef::Log.debug("sleeping #{splay} seconds")
+ interval_sleep splay
end
- signal = nil
+ Chef::Application.exit!("Exiting", 0) if @signal == GRACEFUL_EXIT_SIGNAL
+
run_chef_client(Chef::Config[:specific_recipes])
- if Chef::Config[:interval]
- Chef::Log.debug("Sleeping for #{Chef::Config[:interval]} seconds")
- signal = interval_sleep
- else
+ unless Chef::Config[:interval]
Chef::Application.exit! "Exiting", 0
end
rescue SystemExit => e
@@ -348,8 +346,7 @@ class Chef::Application::Client < Chef::Application
rescue Exception => e
if Chef::Config[:interval]
Chef::Log.error("#{e.class}: #{e}")
- Chef::Log.error("Sleeping for #{Chef::Config[:interval]} seconds before trying again")
- signal = interval_sleep
+ Chef::Log.error("Retrying...")
retry
else
Chef::Application.fatal!("#{e.class}: #{e.message}", 1)
@@ -360,17 +357,21 @@ class Chef::Application::Client < Chef::Application
private
- def interval_sleep
+ def interval_sleep(secs)
unless SELF_PIPE.empty?
- client_sleep Chef::Config[:interval]
+ client_sleep secs
else
# Windows
- sleep Chef::Config[:interval]
+ sleep secs
end
end
- def client_sleep(sec)
- IO.select([ SELF_PIPE[0] ], nil, nil, sec) or return
- SELF_PIPE[0].getc.chr
+ def client_sleep(secs)
+ IO.select([ SELF_PIPE[0] ], nil, nil, secs) or return
+ @signal = SELF_PIPE[0].getc.chr
+ end
+
+ def get_signal
+ client_sleep(0)
end
end
diff --git a/spec/unit/application/client_spec.rb b/spec/unit/application/client_spec.rb
index 3bc6b97d3d..24ce755bf5 100644
--- a/spec/unit/application/client_spec.rb
+++ b/spec/unit/application/client_spec.rb
@@ -176,6 +176,7 @@ describe Chef::Application::Client, "run_application", :unix_only do
# If everything is fine, sending USR1 to self should prevent
# app to go into splay sleep forever.
Process.kill("USR1", Process.pid)
+ puts "FUCK YOU, KILLED MYSELF!!!"
end
number_of_sleep_calls = 0
@@ -185,10 +186,12 @@ describe Chef::Application::Client, "run_application", :unix_only do
# We have to do it this way because the main loop of
# Chef::Application::Client swallows most exceptions, and we need to be
# able to expose our expectation failures to the parent process in the test.
- @app.stub(:sleep) do |arg|
+ expect(@app).to_not receive(:sleep)
+ @app.stub(:interval_sleep) do |arg|
number_of_sleep_calls += 1
if number_of_sleep_calls > 1
- exit 127
+ puts number_of_sleep_calls
+ #exit 127
end
end
end