blob: f07305559994ff72007a3a4c68ca06d7319e0a8b (
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
|
require 'sync'
require 'puppet/external/event-loop'
require 'puppet/application'
# 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, :splayed
# 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?
Puppet::Application.restart_requested?
end
# Perform a run with our client.
def run(*args)
if running?
Puppet.notice "Run of %s already in progress; skipping" % client_class
return
end
result = nil
block_run = Puppet::Application.controlled_run do
splay
with_client do |client|
begin
sync.synchronize { lock { result = client.run(*args) } }
rescue => detail
puts detail.backtrace if Puppet[:trace]
Puppet.err "Could not run %s: %s" % [client_class, detail]
end
end
true
end
Puppet.notice "Shutdown/restart in progress; skipping run" unless block_run
result
end
def stopping?
Puppet::Application.stop_requested?
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 SystemExit,NoMemoryError
raise
rescue Exception => detail
puts detail.backtrace if Puppet[:trace]
Puppet.err "Could not create instance of %s: %s" % [client_class, detail]
return
end
yield @client
ensure
@client = nil
end
end
|