puppet 0.16.0 → 0.18.4
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of puppet might be problematic. Click here for more details.
- data/CHANGELOG +98 -0
- data/Rakefile +5 -1
- data/bin/puppet +1 -1
- data/bin/puppetca +25 -11
- data/bin/puppetd +189 -66
- data/bin/puppetdoc +79 -62
- data/bin/puppetmasterd +93 -49
- data/bin/puppetrun +385 -0
- data/conf/redhat/client.init +5 -2
- data/conf/redhat/fileserver.conf +1 -1
- data/conf/redhat/lsb-config.patch +51 -0
- data/conf/redhat/puppet.spec +45 -18
- data/conf/redhat/puppetd.conf +32 -4
- data/conf/redhat/server.init +5 -2
- data/conf/solaris/pkginfo +7 -0
- data/conf/solaris/smf/puppetd.xml +77 -0
- data/conf/solaris/smf/puppetmasterd.xml +77 -0
- data/conf/solaris/smf/svc-puppetd +66 -0
- data/conf/solaris/smf/svc-puppetmasterd +62 -0
- data/examples/code/failers/noobjectrvalue +1 -0
- data/examples/code/snippets/deepclassheirarchy.pp +23 -0
- data/examples/code/snippets/defineoverrides.pp +17 -0
- data/examples/code/snippets/emptyexec.pp +3 -0
- data/examples/code/snippets/selectorvalues.pp +6 -1
- data/examples/code/snippets/tagged.pp +35 -0
- data/ext/ldap/puppet.schema +2 -2
- data/install.rb +4 -2
- data/lib/puppet.rb +206 -15
- data/lib/puppet/client.rb +30 -20
- data/lib/puppet/client/ca.rb +2 -2
- data/lib/puppet/client/dipper.rb +5 -9
- data/lib/puppet/client/master.rb +224 -44
- data/lib/puppet/client/pelement.rb +54 -9
- data/lib/puppet/client/proxy.rb +3 -2
- data/lib/puppet/client/reporter.rb +34 -0
- data/lib/puppet/client/runner.rb +17 -0
- data/lib/puppet/config.rb +136 -55
- data/lib/puppet/daemon.rb +59 -37
- data/lib/puppet/element.rb +2 -1
- data/lib/puppet/event.rb +14 -3
- data/lib/puppet/filetype.rb +28 -19
- data/lib/puppet/log.rb +297 -132
- data/lib/puppet/metric.rb +31 -131
- data/lib/puppet/networkclient.rb +73 -46
- data/lib/puppet/parameter.rb +49 -1
- data/lib/puppet/parsedfile.rb +32 -12
- data/lib/puppet/parser/ast.rb +6 -1
- data/lib/puppet/parser/ast/astarray.rb +32 -6
- data/lib/puppet/parser/ast/collection.rb +91 -0
- data/lib/puppet/parser/ast/compdef.rb +2 -2
- data/lib/puppet/parser/ast/component.rb +24 -11
- data/lib/puppet/parser/ast/function.rb +50 -0
- data/lib/puppet/parser/ast/hostclass.rb +70 -22
- data/lib/puppet/parser/ast/node.rb +17 -8
- data/lib/puppet/parser/ast/nodedef.rb +1 -1
- data/lib/puppet/parser/ast/objectdef.rb +28 -10
- data/lib/puppet/parser/ast/selector.rb +4 -1
- data/lib/puppet/parser/functions.rb +145 -0
- data/lib/puppet/parser/interpreter.rb +243 -86
- data/lib/puppet/parser/lexer.rb +5 -4
- data/lib/puppet/parser/parser.rb +586 -505
- data/lib/puppet/parser/scope.rb +337 -187
- data/lib/puppet/rails.rb +115 -0
- data/lib/puppet/rails/database.rb +40 -0
- data/lib/puppet/rails/host.rb +83 -0
- data/lib/puppet/rails/rails_object.rb +42 -0
- data/lib/puppet/rails/rails_parameter.rb +5 -0
- data/lib/puppet/reports/rrdgraph.rb +20 -0
- data/lib/puppet/reports/tagmail.rb +94 -0
- data/lib/puppet/server.rb +20 -4
- data/lib/puppet/server/authconfig.rb +14 -3
- data/lib/puppet/server/authstore.rb +2 -2
- data/lib/puppet/server/ca.rb +23 -11
- data/lib/puppet/server/filebucket.rb +10 -10
- data/lib/puppet/server/fileserver.rb +4 -8
- data/lib/puppet/server/master.rb +19 -22
- data/lib/puppet/server/pelement.rb +28 -16
- data/lib/puppet/server/report.rb +184 -0
- data/lib/puppet/server/runner.rb +62 -0
- data/lib/puppet/server/servlet.rb +23 -9
- data/lib/puppet/sslcertificates/ca.rb +25 -1
- data/lib/puppet/statechange.rb +34 -53
- data/lib/puppet/storage.rb +1 -2
- data/lib/puppet/transaction.rb +305 -133
- data/lib/puppet/transaction/report.rb +42 -0
- data/lib/puppet/transportable.rb +57 -33
- data/lib/puppet/type.rb +260 -127
- data/lib/puppet/type/component.rb +9 -21
- data/lib/puppet/type/cron.rb +367 -116
- data/lib/puppet/type/exec.rb +15 -16
- data/lib/puppet/type/group.rb +9 -1
- data/lib/puppet/type/nameservice.rb +2 -5
- data/lib/puppet/type/nameservice/netinfo.rb +3 -0
- data/lib/puppet/type/nameservice/objectadd.rb +23 -10
- data/lib/puppet/type/nameservice/pw.rb +16 -3
- data/lib/puppet/type/package.rb +25 -75
- data/lib/puppet/type/package/apple.rb +15 -1
- data/lib/puppet/type/package/apt.rb +37 -2
- data/lib/puppet/type/package/blastwave.rb +136 -0
- data/lib/puppet/type/package/dpkg.rb +4 -4
- data/lib/puppet/type/package/gem.rb +119 -0
- data/lib/puppet/type/package/openbsd.rb +7 -6
- data/lib/puppet/type/package/ports.rb +7 -2
- data/lib/puppet/type/package/rpm.rb +1 -1
- data/lib/puppet/type/package/sun.rb +23 -9
- data/lib/puppet/type/package/sunfreeware.rb +7 -0
- data/lib/puppet/type/package/yum.rb +16 -9
- data/lib/puppet/type/parsedtype.rb +7 -5
- data/lib/puppet/type/parsedtype/mount.rb +55 -34
- data/lib/puppet/type/parsedtype/port.rb +7 -1
- data/lib/puppet/type/parsedtype/sshkey.rb +6 -16
- data/lib/puppet/type/pfile.rb +115 -23
- data/lib/puppet/type/pfile/checksum.rb +18 -5
- data/lib/puppet/type/pfile/content.rb +2 -2
- data/lib/puppet/type/pfile/ensure.rb +3 -3
- data/lib/puppet/type/pfile/group.rb +2 -2
- data/lib/puppet/type/pfile/source.rb +28 -17
- data/lib/puppet/type/pfile/target.rb +25 -17
- data/lib/puppet/type/pfilebucket.rb +25 -6
- data/lib/puppet/type/schedule.rb +6 -6
- data/lib/puppet/type/service.rb +24 -14
- data/lib/puppet/type/service/debian.rb +1 -1
- data/lib/puppet/type/service/redhat.rb +13 -10
- data/lib/puppet/type/service/smf.rb +3 -3
- data/lib/puppet/type/state.rb +1 -2
- data/lib/puppet/type/symlink.rb +3 -4
- data/lib/puppet/type/user.rb +22 -10
- data/lib/puppet/type/yumrepo.rb +6 -1
- data/lib/puppet/type/zone.rb +595 -0
- data/lib/puppet/util.rb +58 -12
- data/test/client/client.rb +2 -2
- data/test/client/master.rb +92 -3
- data/test/client/pelement.rb +99 -0
- data/test/executables/puppetbin.rb +3 -4
- data/test/executables/puppetca.rb +3 -3
- data/test/executables/puppetd.rb +3 -3
- data/test/executables/puppetmasterd.rb +1 -5
- data/test/executables/puppetmodule.rb +2 -2
- data/test/language/ast.rb +200 -11
- data/test/language/functions.rb +245 -0
- data/test/language/interpreter.rb +155 -6
- data/test/language/lexer.rb +35 -2
- data/test/language/node.rb +48 -1
- data/test/language/parser.rb +250 -1
- data/test/language/rails.rb +105 -0
- data/test/language/scope.rb +304 -10
- data/test/language/snippets.rb +54 -5
- data/test/language/transportable.rb +60 -28
- data/test/other/config.rb +214 -1
- data/test/other/events.rb +67 -9
- data/test/other/log.rb +31 -5
- data/test/other/metrics.rb +23 -21
- data/test/other/parsedfile.rb +29 -2
- data/test/other/puppet.rb +79 -0
- data/test/other/report.rb +106 -0
- data/test/other/storage.rb +2 -2
- data/test/other/transactions.rb +128 -2
- data/test/puppet/utiltest.rb +10 -5
- data/test/puppettest.rb +193 -21
- data/test/server/authstore.rb +13 -4
- data/test/server/bucket.rb +33 -8
- data/test/server/ca.rb +44 -6
- data/test/server/master.rb +6 -7
- data/test/server/pelement.rb +15 -5
- data/test/server/report.rb +93 -0
- data/test/server/runner.rb +107 -0
- data/test/server/server.rb +28 -1
- data/test/types/cron.rb +339 -31
- data/test/types/file.rb +256 -24
- data/test/types/filebucket.rb +6 -2
- data/test/types/filesources.rb +41 -92
- data/test/types/group.rb +31 -1
- data/test/types/host.rb +2 -1
- data/test/types/mount.rb +18 -1
- data/test/types/package.rb +200 -18
- data/test/types/service.rb +5 -1
- data/test/types/sshkey.rb +2 -1
- data/test/types/symlink.rb +3 -2
- data/test/types/type.rb +180 -1
- data/test/types/user.rb +65 -27
- data/test/types/yumrepo.rb +15 -0
- data/test/types/zone.rb +437 -0
- metadata +43 -4
- data/bin/cf2puppet +0 -186
- data/conf/redhat/puppetmasterd.conf +0 -5
data/lib/puppet/daemon.rb
CHANGED
@@ -6,8 +6,13 @@ module Puppet
|
|
6
6
|
# A module that handles operations common to all daemons. This is included
|
7
7
|
# into the Server and Client base classes.
|
8
8
|
module Daemon
|
9
|
+
include Puppet::Util
|
10
|
+
|
11
|
+
Puppet.config.setdefaults(:puppet, :setpidfile => [true,
|
12
|
+
"Whether to store a PID file for the daemon."])
|
9
13
|
def daemonname
|
10
|
-
|
14
|
+
#$0.sub(/.+#{File::SEPARATOR}/,'')
|
15
|
+
Puppet.name
|
11
16
|
end
|
12
17
|
|
13
18
|
# The path to the pid file for this server
|
@@ -22,8 +27,6 @@ module Puppet
|
|
22
27
|
exit(0)
|
23
28
|
end
|
24
29
|
|
25
|
-
setpidfile()
|
26
|
-
|
27
30
|
# Get rid of console logging
|
28
31
|
Puppet::Log.close(:console)
|
29
32
|
|
@@ -36,9 +39,9 @@ module Puppet
|
|
36
39
|
Puppet::Log.reopen
|
37
40
|
rescue => detail
|
38
41
|
File.open("/tmp/daemonout", "w") { |f|
|
39
|
-
f.puts "Could not start %s: %s" % [
|
42
|
+
f.puts "Could not start %s: %s" % [Puppet.name, detail]
|
40
43
|
}
|
41
|
-
Puppet.err "Could not start %s: %s" % [
|
44
|
+
Puppet.err "Could not start %s: %s" % [Puppet.name, detail]
|
42
45
|
exit(12)
|
43
46
|
end
|
44
47
|
end
|
@@ -89,6 +92,10 @@ module Puppet
|
|
89
92
|
return true
|
90
93
|
end
|
91
94
|
|
95
|
+
unless defined? @fqdn
|
96
|
+
self.fqdn
|
97
|
+
end
|
98
|
+
|
92
99
|
# we are not going to encrypt our key, but we need at a minimum
|
93
100
|
# a keyfile and a certfile
|
94
101
|
@certfile = File.join(Puppet[:certdir], [@fqdn, "pem"].join("."))
|
@@ -120,6 +127,10 @@ module Puppet
|
|
120
127
|
# of creating the cert request, contacting the remote system, and
|
121
128
|
# storing the cert locally.
|
122
129
|
def requestcert
|
130
|
+
unless @secureinit
|
131
|
+
raise Puppet::DevError,
|
132
|
+
"Tried to request cert without initialized security"
|
133
|
+
end
|
123
134
|
retrieved = false
|
124
135
|
Puppet.config.use(:puppet, :certificates)
|
125
136
|
# create the directories involved
|
@@ -193,53 +204,64 @@ module Puppet
|
|
193
204
|
return retrieved
|
194
205
|
end
|
195
206
|
|
196
|
-
#
|
197
|
-
def
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
return
|
207
|
+
# Remove the pid file
|
208
|
+
def rmpidfile
|
209
|
+
threadlock(:pidfile) do
|
210
|
+
if defined? @pidfile and @pidfile and FileTest.exists?(@pidfile)
|
211
|
+
begin
|
212
|
+
File.unlink(@pidfile)
|
213
|
+
rescue => detail
|
214
|
+
Puppet.err "Could not remove PID file %s: %s" %
|
215
|
+
[@pidfile, detail]
|
216
|
+
end
|
207
217
|
end
|
208
218
|
end
|
219
|
+
end
|
209
220
|
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
221
|
+
# Create the pid file.
|
222
|
+
def setpidfile
|
223
|
+
return unless Puppet[:setpidfile]
|
224
|
+
threadlock(:pidfile) do
|
225
|
+
Puppet.config.use(:puppet)
|
226
|
+
@pidfile = self.pidfile
|
227
|
+
if FileTest.exists?(@pidfile)
|
228
|
+
if defined? $setpidfile
|
229
|
+
return
|
230
|
+
else
|
231
|
+
raise Puppet::Error, "A PID file already exists for #{Puppet.name}
|
232
|
+
at #{@pidfile}. Not starting."
|
233
|
+
end
|
234
|
+
end
|
214
235
|
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
236
|
+
Puppet.info "Creating PID file to %s" % @pidfile
|
237
|
+
begin
|
238
|
+
File.open(@pidfile, "w") { |f| f.puts $$ }
|
239
|
+
rescue => detail
|
240
|
+
Puppet.err "Could not create PID file: %s" % detail
|
241
|
+
exit(74)
|
242
|
+
end
|
243
|
+
$setpidfile = true
|
221
244
|
end
|
222
|
-
Puppet.info "pid file is %s" % @pidfile
|
223
245
|
end
|
224
246
|
|
225
247
|
# Shut down our server
|
226
248
|
def shutdown
|
227
249
|
# Remove our pid file
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
[@pidfile, detail]
|
234
|
-
end
|
250
|
+
rmpidfile()
|
251
|
+
|
252
|
+
# And close all logs except the console.
|
253
|
+
Puppet::Log.destinations.reject { |d| d == :console }.each do |dest|
|
254
|
+
Puppet::Log.close(dest)
|
235
255
|
end
|
236
256
|
|
237
|
-
|
238
|
-
|
257
|
+
super
|
258
|
+
end
|
239
259
|
|
260
|
+
def start
|
261
|
+
setpidfile()
|
240
262
|
super
|
241
263
|
end
|
242
264
|
end
|
243
265
|
end
|
244
266
|
|
245
|
-
# $Id: daemon.rb
|
267
|
+
# $Id: daemon.rb 1315 2006-06-27 05:15:51Z luke $
|
data/lib/puppet/element.rb
CHANGED
@@ -6,6 +6,7 @@ require 'puppet'
|
|
6
6
|
# and provides a few simple across-the-board functions like 'noop'
|
7
7
|
class Puppet::Element
|
8
8
|
include Puppet
|
9
|
+
include Puppet::Util
|
9
10
|
attr_writer :noop
|
10
11
|
|
11
12
|
class << self
|
@@ -66,4 +67,4 @@ class Puppet::Element
|
|
66
67
|
|
67
68
|
end
|
68
69
|
|
69
|
-
# $Id: element.rb
|
70
|
+
# $Id: element.rb 1227 2006-05-28 22:13:46Z luke $
|
data/lib/puppet/event.rb
CHANGED
@@ -75,6 +75,17 @@ module Puppet
|
|
75
75
|
@subscriptions[stype][sname] << sub
|
76
76
|
end
|
77
77
|
|
78
|
+
# Collect all of the subscriptions that target a specific event.
|
79
|
+
def self.targets_of(event, source)
|
80
|
+
type, name = self.split(source)
|
81
|
+
|
82
|
+
@subscriptions[type][name].each { |sub|
|
83
|
+
if sub.match?(event)
|
84
|
+
yield sub
|
85
|
+
end
|
86
|
+
}
|
87
|
+
end
|
88
|
+
|
78
89
|
# Trigger the subscriptions related to an event, and then pass it up
|
79
90
|
# as appropriate
|
80
91
|
def self.trigger(source, event)
|
@@ -195,7 +206,7 @@ module Puppet
|
|
195
206
|
end
|
196
207
|
|
197
208
|
# Trigger a subscription, which basically calls the associated method
|
198
|
-
# on the target object.
|
209
|
+
# on the target object. XXX This is currently unused.
|
199
210
|
def trigger(transaction)
|
200
211
|
event = nil
|
201
212
|
|
@@ -245,9 +256,9 @@ module Puppet
|
|
245
256
|
end
|
246
257
|
|
247
258
|
def to_s
|
248
|
-
self.event.to_s
|
259
|
+
@source.to_s + " -> " + self.event.to_s
|
249
260
|
end
|
250
261
|
end
|
251
262
|
end
|
252
263
|
|
253
|
-
# $Id: event.rb
|
264
|
+
# $Id: event.rb 1178 2006-05-05 19:43:23Z luke $
|
data/lib/puppet/filetype.rb
CHANGED
@@ -112,43 +112,38 @@ module Puppet
|
|
112
112
|
|
113
113
|
# Operate on plain files.
|
114
114
|
newfiletype(:ram) do
|
115
|
+
@@tabs = {}
|
116
|
+
|
117
|
+
def self.clear
|
118
|
+
@@tabs.clear
|
119
|
+
end
|
120
|
+
|
115
121
|
def initialize(path)
|
116
122
|
super
|
117
|
-
@
|
123
|
+
@@tabs[@path] ||= ""
|
118
124
|
end
|
119
125
|
|
120
126
|
# Read the file.
|
121
127
|
def read
|
122
128
|
Puppet.info "Reading %s from RAM" % @path
|
123
|
-
@
|
129
|
+
@@tabs[@path]
|
124
130
|
end
|
125
131
|
|
126
132
|
# Remove the file.
|
127
133
|
def remove
|
128
134
|
Puppet.info "Removing %s from RAM" % @path
|
129
|
-
@
|
135
|
+
@@tabs[@path] = ""
|
130
136
|
end
|
131
137
|
|
132
138
|
# Overwrite the file.
|
133
139
|
def write(text)
|
134
140
|
Puppet.info "Writing %s to RAM" % @path
|
135
|
-
@
|
141
|
+
@@tabs[@path] = text
|
136
142
|
end
|
137
143
|
end
|
138
144
|
|
139
145
|
# Handle Linux-style cron tabs.
|
140
146
|
newfiletype(:crontab) do
|
141
|
-
# Only add the -u flag when the @path is different. Fedora apparently
|
142
|
-
# does not think I should be allowed to set the @path to my
|
143
|
-
def cmdbase
|
144
|
-
cmd = nil
|
145
|
-
if @path == Process.uid
|
146
|
-
return "crontab"
|
147
|
-
else
|
148
|
-
return "crontab -u #{@path}"
|
149
|
-
end
|
150
|
-
end
|
151
|
-
|
152
147
|
def initialize(user)
|
153
148
|
begin
|
154
149
|
uid = Puppet::Util.uid(user)
|
@@ -178,6 +173,19 @@ module Puppet
|
|
178
173
|
p.print text
|
179
174
|
}
|
180
175
|
end
|
176
|
+
|
177
|
+
private
|
178
|
+
|
179
|
+
# Only add the -u flag when the @path is different. Fedora apparently
|
180
|
+
# does not think I should be allowed to set the @path to my
|
181
|
+
def cmdbase
|
182
|
+
cmd = nil
|
183
|
+
if @path == Process.uid
|
184
|
+
return "crontab"
|
185
|
+
else
|
186
|
+
return "crontab -u #{@path}"
|
187
|
+
end
|
188
|
+
end
|
181
189
|
end
|
182
190
|
|
183
191
|
# SunOS has completely different cron commands; this class implements
|
@@ -208,7 +216,8 @@ module Puppet
|
|
208
216
|
end
|
209
217
|
end
|
210
218
|
|
211
|
-
# Treat netinfo tables as a single file, just for simplicity of certain
|
219
|
+
# Treat netinfo tables as a single file, just for simplicity of certain
|
220
|
+
# types
|
212
221
|
newfiletype(:netinfo) do
|
213
222
|
class << self
|
214
223
|
attr_accessor :format
|
@@ -230,8 +239,8 @@ module Puppet
|
|
230
239
|
end
|
231
240
|
end
|
232
241
|
|
233
|
-
# Convert our table to an array of hashes. This only works for
|
234
|
-
# table at a time.
|
242
|
+
# Convert our table to an array of hashes. This only works for
|
243
|
+
# handling one table at a time.
|
235
244
|
def to_array(text = nil)
|
236
245
|
unless text
|
237
246
|
text = read
|
@@ -296,4 +305,4 @@ module Puppet
|
|
296
305
|
end
|
297
306
|
end
|
298
307
|
|
299
|
-
# $Id: filetype.rb
|
308
|
+
# $Id: filetype.rb 1402 2006-07-18 15:35:15Z luke $
|
data/lib/puppet/log.rb
CHANGED
@@ -16,21 +16,83 @@ module Puppet
|
|
16
16
|
@levels = [:debug,:info,:notice,:warning,:err,:alert,:emerg,:crit]
|
17
17
|
@loglevel = 2
|
18
18
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
19
|
+
@desttypes = {}
|
20
|
+
|
21
|
+
# A type of log destination.
|
22
|
+
class Destination
|
23
|
+
class << self
|
24
|
+
attr_accessor :name
|
25
|
+
end
|
26
|
+
|
27
|
+
# Mark the things we're supposed to match.
|
28
|
+
def self.match(obj)
|
29
|
+
@matches ||= []
|
30
|
+
@matches << obj
|
31
|
+
end
|
32
|
+
|
33
|
+
# See whether we match a given thing.
|
34
|
+
def self.match?(obj)
|
35
|
+
# Convert single-word strings into symbols like :console and :syslog
|
36
|
+
if obj.is_a? String and obj =~ /^\w+$/
|
37
|
+
obj = obj.downcase.intern
|
38
|
+
end
|
39
|
+
|
40
|
+
@matches.each do |thing|
|
41
|
+
# Search for direct matches or class matches
|
42
|
+
return true if thing === obj or thing == obj.class.to_s
|
43
|
+
end
|
44
|
+
return false
|
45
|
+
end
|
46
|
+
|
47
|
+
def name
|
48
|
+
if defined? @name
|
49
|
+
return @name
|
50
|
+
else
|
51
|
+
return self.class.name
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
# Set how to handle a message.
|
56
|
+
def self.sethandler(&block)
|
57
|
+
define_method(:handle, &block)
|
58
|
+
end
|
59
|
+
|
60
|
+
# Mark how to initialize our object.
|
61
|
+
def self.setinit(&block)
|
62
|
+
define_method(:initialize, &block)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
# Create a new destination type.
|
67
|
+
def self.newdesttype(name, options = {}, &block)
|
68
|
+
dest = Class.new(Destination)
|
69
|
+
name = name.to_s.downcase.intern
|
70
|
+
dest.name = name
|
71
|
+
dest.match(dest.name)
|
72
|
+
|
73
|
+
const_set("Dest" + name.to_s.capitalize, dest)
|
74
|
+
|
75
|
+
@desttypes[dest.name] = dest
|
76
|
+
|
77
|
+
options.each do |option, value|
|
78
|
+
begin
|
79
|
+
dest.send(option.to_s + "=", value)
|
80
|
+
rescue NoMethodError
|
81
|
+
raise "%s is an invalid option for log destinations" % option
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
dest.class_eval(&block)
|
86
|
+
|
87
|
+
return dest
|
88
|
+
end
|
89
|
+
|
32
90
|
@destinations = {}
|
33
91
|
|
92
|
+
class << self
|
93
|
+
include Puppet::Util
|
94
|
+
end
|
95
|
+
|
34
96
|
# Reset all logs to basics. Basically just closes all files and undefs
|
35
97
|
# all of the other objects.
|
36
98
|
def Log.close(dest = nil)
|
@@ -42,7 +104,7 @@ module Puppet
|
|
42
104
|
@destinations.delete(dest)
|
43
105
|
end
|
44
106
|
else
|
45
|
-
@destinations.each { |
|
107
|
+
@destinations.each { |name, dest|
|
46
108
|
if dest.respond_to?(:flush)
|
47
109
|
dest.flush
|
48
110
|
end
|
@@ -52,8 +114,6 @@ module Puppet
|
|
52
114
|
}
|
53
115
|
@destinations = {}
|
54
116
|
end
|
55
|
-
|
56
|
-
Puppet.info "closed"
|
57
117
|
end
|
58
118
|
|
59
119
|
# Flush any log destinations that support such operations.
|
@@ -112,63 +172,220 @@ module Puppet
|
|
112
172
|
@levels.dup
|
113
173
|
end
|
114
174
|
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
if @destinations.include?(dest)
|
119
|
-
return
|
175
|
+
newdesttype :syslog do
|
176
|
+
def close
|
177
|
+
Syslog.close
|
120
178
|
end
|
121
179
|
|
122
|
-
|
123
|
-
when "syslog", :syslog
|
180
|
+
def initialize
|
124
181
|
if Syslog.opened?
|
125
182
|
Syslog.close
|
126
183
|
end
|
127
184
|
name = Puppet.name
|
128
185
|
name = "puppet-#{name}" unless name =~ /puppet/
|
129
|
-
|
130
|
-
|
131
|
-
|
186
|
+
|
187
|
+
options = Syslog::LOG_PID | Syslog::LOG_NDELAY
|
188
|
+
|
189
|
+
# XXX This should really be configurable.
|
190
|
+
facility = Syslog::LOG_DAEMON
|
191
|
+
|
192
|
+
@syslog = Syslog.open(name, options, facility)
|
193
|
+
end
|
194
|
+
|
195
|
+
def handle(msg)
|
196
|
+
# XXX Syslog currently has a bug that makes it so you
|
197
|
+
# cannot log a message with a '%' in it. So, we get rid
|
198
|
+
# of them.
|
199
|
+
if msg.source == "Puppet"
|
200
|
+
@syslog.send(msg.level, msg.to_s.gsub("%", '%%'))
|
201
|
+
else
|
202
|
+
@syslog.send(msg.level, "(%s) %s" %
|
203
|
+
[msg.source.to_s.gsub("%", ""),
|
204
|
+
msg.to_s.gsub("%", '%%')
|
205
|
+
]
|
206
|
+
)
|
207
|
+
end
|
208
|
+
end
|
209
|
+
end
|
210
|
+
|
211
|
+
newdesttype :file do
|
212
|
+
match(/^\//)
|
213
|
+
|
214
|
+
def close
|
215
|
+
if defined? @file
|
216
|
+
@file.close
|
217
|
+
@file = nil
|
218
|
+
end
|
219
|
+
end
|
220
|
+
|
221
|
+
def flush
|
222
|
+
if defined? @file
|
223
|
+
@file.flush
|
224
|
+
end
|
225
|
+
end
|
226
|
+
|
227
|
+
def initialize(path)
|
228
|
+
@name = path
|
132
229
|
# first make sure the directory exists
|
133
230
|
# We can't just use 'Config.use' here, because they've
|
134
231
|
# specified a "special" destination.
|
135
|
-
unless FileTest.exist?(File.dirname(
|
232
|
+
unless FileTest.exist?(File.dirname(path))
|
233
|
+
Puppet.recmkdir(File.dirname(path))
|
234
|
+
Puppet.info "Creating log directory %s" % File.dirname(path)
|
235
|
+
end
|
236
|
+
|
237
|
+
# create the log file, if it doesn't already exist
|
238
|
+
file = File.open(path, File::WRONLY|File::CREAT|File::APPEND)
|
239
|
+
|
240
|
+
@file = file
|
241
|
+
end
|
242
|
+
|
243
|
+
def handle(msg)
|
244
|
+
@file.puts("%s %s (%s): %s" %
|
245
|
+
[msg.time, msg.source, msg.level, msg.to_s])
|
246
|
+
end
|
247
|
+
end
|
248
|
+
|
249
|
+
newdesttype :console do
|
250
|
+
@@colors = {
|
251
|
+
:debug => SLATE,
|
252
|
+
:info => GREEN,
|
253
|
+
:notice => PINK,
|
254
|
+
:warning => ORANGE,
|
255
|
+
:err => YELLOW,
|
256
|
+
:alert => BLUE,
|
257
|
+
:emerg => RESET,
|
258
|
+
:crit => RESET
|
259
|
+
}
|
260
|
+
|
261
|
+
def initialize
|
262
|
+
# Flush output immediately.
|
263
|
+
$stdout.sync = true
|
264
|
+
end
|
265
|
+
|
266
|
+
def handle(msg)
|
267
|
+
color = ""
|
268
|
+
reset = ""
|
269
|
+
if Puppet[:color]
|
270
|
+
color = @@colors[msg.level]
|
271
|
+
reset = RESET
|
272
|
+
end
|
273
|
+
if msg.source == "Puppet"
|
274
|
+
puts color + "%s: %s" % [
|
275
|
+
msg.level, msg.to_s
|
276
|
+
] + reset
|
277
|
+
else
|
278
|
+
puts color + "%s: %s: %s" % [
|
279
|
+
msg.level, msg.source, msg.to_s
|
280
|
+
] + reset
|
281
|
+
end
|
282
|
+
end
|
283
|
+
end
|
284
|
+
|
285
|
+
newdesttype :host do
|
286
|
+
def initialize(host)
|
287
|
+
Puppet.info "Treating %s as a hostname" % host
|
288
|
+
args = {}
|
289
|
+
if host =~ /:(\d+)/
|
290
|
+
args[:Port] = $1
|
291
|
+
args[:Server] = host.sub(/:\d+/, '')
|
292
|
+
else
|
293
|
+
args[:Server] = host
|
294
|
+
end
|
295
|
+
|
296
|
+
@name = host
|
297
|
+
|
298
|
+
@driver = Puppet::Client::LogClient.new(args)
|
299
|
+
end
|
300
|
+
|
301
|
+
def handle(msg)
|
302
|
+
unless msg.is_a?(String) or msg.remote
|
303
|
+
unless defined? @hostname
|
304
|
+
@hostname = Facter["hostname"].value
|
305
|
+
end
|
306
|
+
unless defined? @domain
|
307
|
+
@domain = Facter["domain"].value
|
308
|
+
if @domain
|
309
|
+
@hostname += "." + @domain
|
310
|
+
end
|
311
|
+
end
|
312
|
+
if msg.source =~ /^\//
|
313
|
+
msg.source = @hostname + ":" + msg.source
|
314
|
+
elsif msg.source == "Puppet"
|
315
|
+
msg.source = @hostname + " " + msg.source
|
316
|
+
else
|
317
|
+
msg.source = @hostname + " " + msg.source
|
318
|
+
end
|
136
319
|
begin
|
137
|
-
|
138
|
-
|
139
|
-
|
320
|
+
#puts "would have sent %s" % msg
|
321
|
+
#puts "would have sent %s" %
|
322
|
+
# CGI.escape(YAML.dump(msg))
|
323
|
+
begin
|
324
|
+
tmp = CGI.escape(YAML.dump(msg))
|
325
|
+
rescue => detail
|
326
|
+
puts "Could not dump: %s" % detail.to_s
|
327
|
+
return
|
328
|
+
end
|
329
|
+
# Add the hostname to the source
|
330
|
+
@driver.addlog(tmp)
|
140
331
|
rescue => detail
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
332
|
+
if Puppet[:debug]
|
333
|
+
puts detail.backtrace
|
334
|
+
end
|
335
|
+
Puppet.err detail
|
336
|
+
Puppet::Log.close(self)
|
145
337
|
end
|
146
338
|
end
|
339
|
+
end
|
340
|
+
end
|
147
341
|
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
342
|
+
# Log to a transaction report.
|
343
|
+
newdesttype :report do
|
344
|
+
match "Puppet::Transaction::Report"
|
345
|
+
|
346
|
+
def initialize(report)
|
347
|
+
@report = report
|
348
|
+
end
|
349
|
+
|
350
|
+
def handle(msg)
|
351
|
+
# Only add messages from objects, since anything else is
|
352
|
+
# probably unrelated to this run.
|
353
|
+
if msg.objectsource?
|
354
|
+
@report.newlog(msg)
|
156
355
|
end
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
356
|
+
end
|
357
|
+
end
|
358
|
+
|
359
|
+
# Create a new log destination.
|
360
|
+
def Log.newdestination(dest)
|
361
|
+
# Each destination can only occur once.
|
362
|
+
if @destinations.find { |name, obj| obj.name == dest }
|
363
|
+
return
|
364
|
+
end
|
365
|
+
|
366
|
+
name, type = @desttypes.find do |name, klass|
|
367
|
+
klass.match?(dest)
|
368
|
+
end
|
369
|
+
|
370
|
+
unless type
|
371
|
+
raise Puppet::DevError, "Unknown destination type %s" % dest
|
372
|
+
end
|
373
|
+
|
374
|
+
begin
|
375
|
+
if type.instance_method(:initialize).arity == 1
|
376
|
+
@destinations[dest] = type.new(dest)
|
168
377
|
else
|
169
|
-
|
378
|
+
@destinations[dest] = type.new()
|
379
|
+
end
|
380
|
+
rescue => detail
|
381
|
+
if Puppet[:debug]
|
382
|
+
puts detail.backtrace
|
383
|
+
end
|
384
|
+
|
385
|
+
# If this was our only destination, then add the console back in.
|
386
|
+
if @destinations.empty? and (dest != :console and dest != "console")
|
387
|
+
newdestination(:console)
|
170
388
|
end
|
171
|
-
@destinations[dest] = Puppet::Client::LogClient.new(args)
|
172
389
|
end
|
173
390
|
end
|
174
391
|
|
@@ -181,83 +398,12 @@ module Puppet
|
|
181
398
|
if @levels.index(msg.level) < @loglevel
|
182
399
|
return
|
183
400
|
end
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
# XXX Syslog currently has a bug that makes it so you
|
189
|
-
# cannot log a message with a '%' in it. So, we get rid
|
190
|
-
# of them.
|
191
|
-
if msg.source == "Puppet"
|
192
|
-
dest.send(msg.level, msg.to_s.gsub("%", '%%'))
|
193
|
-
else
|
194
|
-
dest.send(msg.level, "(%s) %s" %
|
195
|
-
[msg.source.to_s.gsub("%", ""),
|
196
|
-
msg.to_s.gsub("%", '%%')
|
197
|
-
]
|
198
|
-
)
|
199
|
-
end
|
200
|
-
when File:
|
201
|
-
dest.puts("%s %s (%s): %s" %
|
202
|
-
[msg.time, msg.source, msg.level, msg.to_s])
|
203
|
-
when :console
|
204
|
-
color = ""
|
205
|
-
reset = ""
|
206
|
-
if Puppet[:color]
|
207
|
-
color = @colors[msg.level]
|
208
|
-
reset = RESET
|
209
|
-
end
|
210
|
-
if msg.source == "Puppet"
|
211
|
-
puts color + "%s: %s" % [
|
212
|
-
msg.level, msg.to_s
|
213
|
-
] + reset
|
214
|
-
else
|
215
|
-
puts color + "%s: %s: %s" % [
|
216
|
-
msg.level, msg.source, msg.to_s
|
217
|
-
] + reset
|
218
|
-
end
|
219
|
-
when Puppet::Client::LogClient
|
220
|
-
unless msg.is_a?(String) or msg.remote
|
221
|
-
unless defined? @hostname
|
222
|
-
@hostname = Facter["hostname"].value
|
223
|
-
end
|
224
|
-
unless defined? @domain
|
225
|
-
@domain = Facter["domain"].value
|
226
|
-
if @domain
|
227
|
-
@hostname += "." + @domain
|
228
|
-
end
|
229
|
-
end
|
230
|
-
if msg.source =~ /^\//
|
231
|
-
msg.source = @hostname + ":" + msg.source
|
232
|
-
elsif msg.source == "Puppet"
|
233
|
-
msg.source = @hostname + " " + msg.source
|
234
|
-
else
|
235
|
-
msg.source = @hostname + " " + msg.source
|
236
|
-
end
|
237
|
-
begin
|
238
|
-
#puts "would have sent %s" % msg
|
239
|
-
#puts "would have sent %s" %
|
240
|
-
# CGI.escape(YAML.dump(msg))
|
241
|
-
begin
|
242
|
-
tmp = CGI.escape(YAML.dump(msg))
|
243
|
-
rescue => detail
|
244
|
-
puts "Could not dump: %s" % detail.to_s
|
245
|
-
return
|
246
|
-
end
|
247
|
-
# Add the hostname to the source
|
248
|
-
dest.addlog(tmp)
|
249
|
-
#dest.addlog(msg.to_s)
|
250
|
-
sleep(0.5)
|
251
|
-
rescue => detail
|
252
|
-
Puppet.err detail
|
253
|
-
@destinations.delete(type)
|
254
|
-
end
|
255
|
-
end
|
256
|
-
else
|
257
|
-
raise Puppet::Error, "Invalid log destination %s" % dest
|
258
|
-
#puts "Invalid log destination %s" % dest.inspect
|
401
|
+
|
402
|
+
@destinations.each do |name, dest|
|
403
|
+
threadlock(dest) do
|
404
|
+
dest.handle(msg)
|
259
405
|
end
|
260
|
-
|
406
|
+
end
|
261
407
|
end
|
262
408
|
|
263
409
|
def Log.sendlevel?(level)
|
@@ -332,6 +478,15 @@ module Puppet
|
|
332
478
|
Log.newmessage(self)
|
333
479
|
end
|
334
480
|
|
481
|
+
# Was the source of this log an object?
|
482
|
+
def objectsource?
|
483
|
+
if defined? @objectsource and @objectsource
|
484
|
+
@objectsource
|
485
|
+
else
|
486
|
+
false
|
487
|
+
end
|
488
|
+
end
|
489
|
+
|
335
490
|
# If they pass a source in to us, we make sure it is a string, and
|
336
491
|
# we retrieve any tags we can.
|
337
492
|
def source=(source)
|
@@ -339,8 +494,10 @@ module Puppet
|
|
339
494
|
# is a bit of a stupid hack, specifically testing for elements, but
|
340
495
|
# eh.
|
341
496
|
if source.is_a?(Puppet::Element) and source.respond_to?(:path)
|
497
|
+
@objectsource = true
|
342
498
|
@source = source.path
|
343
499
|
else
|
500
|
+
@objectsource = false
|
344
501
|
@source = source.to_s
|
345
502
|
end
|
346
503
|
unless defined? @tags and @tags
|
@@ -350,10 +507,18 @@ module Puppet
|
|
350
507
|
end
|
351
508
|
end
|
352
509
|
|
510
|
+
def tagged?(tag)
|
511
|
+
@tags.include?(tag)
|
512
|
+
end
|
513
|
+
|
514
|
+
def to_report
|
515
|
+
"%s %s (%s): %s" % [self.time, self.source, self.level, self.to_s]
|
516
|
+
end
|
517
|
+
|
353
518
|
def to_s
|
354
519
|
return @message
|
355
520
|
end
|
356
521
|
end
|
357
522
|
end
|
358
523
|
|
359
|
-
# $Id: log.rb
|
524
|
+
# $Id: log.rb 1422 2006-07-22 03:32:56Z luke $
|