2
require 'puppet/external/event-loop'
3
require 'puppet/application'
5
# A general class for triggering a run of another
8
require 'puppet/agent/locker'
9
include Puppet::Agent::Locker
11
require 'puppet/agent/disabler'
12
include Puppet::Agent::Disabler
14
attr_reader :client_class, :client, :splayed
16
# Just so we can specify that we are "the" instance.
17
def initialize(client_class)
20
@client_class = client_class
24
client_class.lockfile_path
28
Puppet::Application.restart_requested?
31
# Perform a run with our client.
34
Puppet.notice "Run of #{client_class} already in progress; skipping"
38
Puppet.notice "Skipping run of #{client_class}; administratively disabled: #{disable_message}"
42
block_run = Puppet::Application.controlled_run do
44
with_client do |client|
46
sync.synchronize { lock { result = client.run(*args) } }
47
rescue SystemExit,NoMemoryError
49
rescue Exception => detail
50
puts detail.backtrace if Puppet[:trace]
51
Puppet.err "Could not run #{client_class}: #{detail}"
56
Puppet.notice "Shutdown/restart in progress; skipping run" unless block_run
61
Puppet::Application.stop_requested?
64
# Have we splayed already?
69
# Sleep when splay is enabled; else just return.
71
return unless Puppet[:splay]
74
time = rand(Integer(Puppet[:splaylimit]) + 1)
75
Puppet.info "Sleeping for #{time} seconds (splay is enabled)"
80
# Start listening for events. We're pretty much just listening for
83
# Create our timer. Puppet will handle observing it and such.
84
timer = EventLoop::Timer.new(:interval => Puppet[:runinterval], :tolerance => 1, :start? => true) do
88
# Run once before we start following the timer
98
# Create and yield a client instance, keeping a reference
99
# to it during the yield.
102
@client = client_class.new
103
rescue SystemExit,NoMemoryError
105
rescue Exception => detail
106
puts detail.backtrace if Puppet[:trace]
107
Puppet.err "Could not create instance of #{client_class}: #{detail}"