diff options
Diffstat (limited to 'lib/puppet/daemon.rb')
-rwxr-xr-x | lib/puppet/daemon.rb | 102 |
1 files changed, 77 insertions, 25 deletions
diff --git a/lib/puppet/daemon.rb b/lib/puppet/daemon.rb index b0576124e..5f811d897 100755 --- a/lib/puppet/daemon.rb +++ b/lib/puppet/daemon.rb @@ -1,10 +1,11 @@ require 'puppet' require 'puppet/util/pidlock' +require 'puppet/external/event-loop' # A module that handles operations common to all daemons. This is included # into the Server and Client base classes. -module Puppet::Daemon - include Puppet::Util +class Puppet::Daemon + attr_accessor :agent, :server, :argv def daemonname Puppet[:name] @@ -17,7 +18,7 @@ module Puppet::Daemon exit(0) end - setpidfile() + create_pidfile() # Get rid of console logging Puppet::Util::Log.close(:console) @@ -38,18 +39,42 @@ module Puppet::Daemon end end - # The path to the pid file for this server + # Create a pidfile for our daemon, so we can be stopped and others + # don't try to start. + def create_pidfile + Puppet::Util.sync(Puppet[:name]).synchronize(Sync::EX) do + unless Puppet::Util::Pidlock.new(pidfile).lock + raise "Could not create PID file: %s" % [pidfile] + end + end + end + + # Provide the path to our pidfile. def pidfile - if Puppet[:pidfile] != "" - Puppet[:pidfile] - else - File.join(Puppet[:rundir], daemonname() + ".pid") + Puppet[:pidfile] + end + + def reexec + raise Puppet::DevError, "Cannot reexec unless ARGV arguments are set" unless argv + command = $0 + " " + argv.join(" ") + Puppet.notice "Restarting with '%s'" % command + stop(:exit => false) + exec(command) + end + + def reload + return unless agent + if agent.running? + Puppet.notice "Not triggering already-running agent" + return end + + agent.run end - # Remove the pid file - def rmpidfile - threadlock(:pidfile) do + # Remove the pid file for our daemon. + def remove_pidfile + Puppet::Util.sync(Puppet[:name]).synchronize(Sync::EX) do locker = Puppet::Util::Pidlock.new(pidfile) if locker.locked? locker.unlock or Puppet.err "Could not remove PID file %s" % [pidfile] @@ -57,25 +82,52 @@ module Puppet::Daemon end end - # Create the pid file. - def setpidfile - threadlock(:pidfile) do - unless Puppet::Util::Pidlock.new(pidfile).lock - Puppet.err("Could not create PID file: %s" % [pidfile]) - exit(74) - end + def restart + if agent and agent.running? + agent.configure_delayed_restart + else + reexec end end - # Shut down our server - def shutdown - # Remove our pid file - rmpidfile() + def reopen_logs + Puppet::Util::Log.reopen + end - # And close all logs except the console. - Puppet::Util::Log.destinations.reject { |d| d == :console }.each do |dest| - Puppet::Util::Log.close(dest) + # Trap a couple of the main signals. This should probably be handled + # in a way that anyone else can register callbacks for traps, but, eh. + def set_signal_traps + {:INT => :stop, :TERM => :stop, :HUP => :restart, :USR1 => :reload, :USR2 => :reopen_logs}.each do |signal, method| + trap(signal) do + Puppet.notice "Caught #{signal}; calling #{method}" + send(method) + end end end + + # Stop everything + def stop(args = {:exit => true}) + server.stop if server + + agent.stop if agent + + remove_pidfile() + + Puppet::Util::Log.close_all + + exit if args[:exit] + end + + def start + set_signal_traps + + create_pidfile + + raise Puppet::DevError, "Daemons must have an agent, server, or both" unless agent or server + agent.start if agent + server.start if server + + EventLoop.current.run + end end |