diff options
author | Lamont Granquist <lamont@scriptkiddie.org> | 2014-09-26 15:08:09 -0700 |
---|---|---|
committer | Lamont Granquist <lamont@scriptkiddie.org> | 2014-09-26 15:08:09 -0700 |
commit | 718d032e973f50856e08838c8b7e79f1df341bab (patch) | |
tree | bb1b9972ed3ad8909a22fd9dcb1fff2ca379e5b6 | |
parent | 791232c8e08743447fd2a1bf4eb69b87e5d24c00 (diff) | |
download | chef-lcg/signal-nightmare.tar.gz |
possible solution to sig handlinglcg/signal-nightmare
-rw-r--r-- | lib/chef/application/client.rb | 41 | ||||
-rw-r--r-- | spec/unit/application/client_spec.rb | 7 |
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 |