blob: 3add43ec1ea25f7da006668759c9fd15c1a7967b (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
|
require 'sync'
require 'puppet/external/event-loop'
# A general class for triggering a run of another
# class.
class Puppet::Agent
require 'puppet/agent/locker'
include Puppet::Agent::Locker
require 'puppet/agent/runner'
attr_reader :client_class, :client, :needing_restart, :splayed
attr_accessor :stopping
def configure_delayed_restart
@needing_restart = true
end
# Just so we can specify that we are "the" instance.
def initialize(client_class)
@splayed = false
@client_class = client_class
end
def lockfile_path
client_class.lockfile_path
end
def needing_restart?
@needing_restart
end
def restart
configure_delayed_restart and return if running?
Process.kill(:HUP, $$)
@needing_restart = false
end
# Perform a run with our client.
def run
if running?
Puppet.notice "Run of %s already in progress; skipping" % client_class
return
end
if stopping?
Puppet.notice "In shutdown progress; skipping run"
return
end
splay
with_client do |client|
begin
sync.synchronize { lock { client.run } }
rescue => detail
puts detail.backtrace if Puppet[:trace]
Puppet.err "Could not run %s: %s" % [client_class, detail]
end
end
end
def stop
if self.stopping?
Puppet.notice "Already in shutdown"
return
end
self.stopping = true
if client and client.respond_to?(:stop)
begin
client.stop
rescue
puts detail.backtrace if Puppet[:trace]
Puppet.err "Could not stop %s: %s" % [client_class, detail]
end
end
ensure
self.stopping = false
end
def stopping?
stopping
end
# Have we splayed already?
def splayed?
splayed
end
# Sleep when splay is enabled; else just return.
def splay
return unless Puppet[:splay]
return if splayed?
time = rand(Integer(Puppet[:splaylimit]) + 1)
Puppet.info "Sleeping for %s seconds (splay is enabled)" % time
sleep(time)
@splayed = true
end
# Start listening for events. We're pretty much just listening for
# timer events here.
def start
# Create our timer. Puppet will handle observing it and such.
timer = EventLoop::Timer.new(:interval => Puppet[:runinterval], :tolerance => 1, :start? => true) do
run()
end
# Run once before we start following the timer
timer.sound_alarm
end
def sync
unless defined?(@sync) and @sync
@sync = Sync.new
end
@sync
end
private
# Create and yield a client instance, keeping a reference
# to it during the yield.
def with_client
begin
@client = client_class.new
rescue => details
puts detail.backtrace if Puppet[:trace]
Puppet.err "Could not create instance of %s: %s" % [client_class, details]
return
end
yield @client
ensure
@client = nil
end
end
|