summaryrefslogtreecommitdiffstats
path: root/lib/puppet/daemon.rb
diff options
context:
space:
mode:
Diffstat (limited to 'lib/puppet/daemon.rb')
-rwxr-xr-xlib/puppet/daemon.rb102
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