#!/usr/bin/env ruby

require "puppet"
require "syslog"
require "socket"

Syslog.open(File.basename(__FILE__), Syslog::LOG_PID | Syslog::LOG_NDELAY,
            Syslog::LOG_DAEMON)

Puppet.parse_config

if Puppet.version[/\d+/].to_i >= 2
    puppetd = "puppet agent"
    pidname = "agent.pid"
else
    puppetd = "puppetd"
    pidname = "puppetd.pid"
end

# get pid number for puppet or warn if not found
pidfile = File.join(Puppet.settings.value("rundir"), pidname)
begin
    pid = File.new(pidfile, "r").read.to_i
rescue Errno::ENOENT
    err = sprintf("puppetd not running on host '%s'\n", Socket.gethostname)
    Syslog.info sprintf(err)
    print err
    Syslog.close
    exit
end

# check that process is still alive
begin
    Process.kill(0, pid)

    # check memory usage and restart if over 256M
    rss = `ps -o rss -p '#{pid}'`.to_a.last.to_i / 1024
    if rss > 128
        err = sprintf("puppetd memory usage too high (%d MB), on host '%s' sending HUP\n",
                      rss, Socket.gethostname)
        Syslog.warning err
        print err
        Process.kill("HUP", pid)
    end

    # check if deadlock file is too old
    dlock = Puppet.settings.value("puppetdlockfile")
    if File.exists?(dlock) and Time.new - File.new(dlock).mtime > 43200
        err = "puppetd deadlock file is over 12 hours old, removing it and sending HUP to daemon\n"
        Syslog.warning err
        print err
        File.unlink(dlock)
        Process.kill("HUP", pid)
    end

    exit
rescue Errno::ESRCH
    nil
end

# restart
err = sprintf("puppetd dead but pid file exists on host '%s', restarting\n",
              Socket.gethostname)
Syslog.warning err
system("service puppet start > /dev/null")
system(puppetd) if $?.exitstatus == 127
Syslog.close

