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
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
|
# the available clients
require 'puppet'
require 'puppet/networkclient'
module Puppet
# FIXME this still isn't a good design, because none of the handlers overlap
# so i could just as easily include them all in the main module
# but at least it's better organized for now
class Client
include Puppet
include SignalObserver
include Puppet::Util
# FIXME The cert stuff should only come up with networking, so it
# should be in the network client, not the normal client. But if i do
# that, it's hard to tell whether the certs have been initialized.
include Puppet::Daemon
attr_reader :secureinit
attr_accessor :schedule, :lastrun, :local, :stopping
class << self
attr_reader :drivername
end
def initcerts
unless self.readcert
unless self.requestcert
return nil
end
end
# unless we have a driver, we're a local client and we can't add
# certs anyway, so it doesn't matter
unless @driver
return true
end
self.setcerts
end
def initialize(hash)
# to whom do we connect?
@server = nil
@nil = nil
@secureinit = hash[:NoSecureInit] || true
if hash.include?(:FQDN)
@fqdn = hash[:FQDN]
else
self.fqdn
end
if hash.include?(:Cache)
@cache = hash[:Cache]
else
@cache = true
end
driverparam = self.class.drivername
if hash.include?(:Server)
if $noclientnetworking
raise NetworkClientError.new("Networking not available: %s" %
$nonetworking)
end
args = {:Server => hash[:Server]}
args[:Port] = hash[:Port] || Puppet[:masterport]
if self.readcert
args[:Certificate] = @cert
args[:Key] = @key
args[:CAFile] = @cacertfile
end
@driver = Puppet::NetworkClient.new(args)
@local = false
elsif hash.include?(driverparam)
@driver = hash[driverparam]
@local = true
else
raise ClientError, "%s must be passed a Server or %s" %
[self.class, driverparam]
end
end
# A wrapper method to run and then store the last run time
def runnow
if self.stopping
Puppet.notice "In shutdown progress; skipping run"
return
end
begin
self.run
self.lastrun = Time.now.to_i
rescue => detail
Puppet.err "Could not run %s: %s" % [self.class, detail]
end
end
def run
raise Puppet::DevError, "Client type %s did not override run" %
self.class
end
def scheduled?
if sched = self.schedule
return sched.match?(self.lastrun)
else
return true
end
end
def setcerts
@driver.cert = @cert
@driver.key = @key
@driver.ca_file = @cacertfile
end
# FIXME this should probably not store every single time.
def shutdown
if self.stopping
Puppet.notice "Already in shutdown"
else
self.stopping = true
Puppet::Storage.store
exit
end
end
# Start listening for events. We're pretty much just listening for
# timer events here.
def start
# Create our timer
timer = EventLoop::Timer.new(
:interval => Puppet[:runinterval],
:tolerance => 1,
:start? => true
)
# Stick it in the loop
EventLoop.current.monitor_timer timer
# Run once before we start following the timer
self.runnow
# And run indefinitely
observe_signal timer, :alarm do
if self.scheduled?
self.runnow
end
end
end
require 'puppet/client/proxy'
require 'puppet/client/ca'
require 'puppet/client/dipper'
require 'puppet/client/file'
require 'puppet/client/log'
require 'puppet/client/master'
require 'puppet/client/status'
end
end
# $Id$
|