~ubuntu-branches/ubuntu/lucid/puppet/lucid-security

« back to all changes in this revision

Viewing changes to bin/puppetd

  • Committer: Bazaar Package Importer
  • Author(s): Chuck Short
  • Date: 2009-12-23 00:48:10 UTC
  • mfrom: (1.1.10 upstream) (3.1.7 squeeze)
  • Revision ID: james.westby@ubuntu.com-20091223004810-3i4oryds922g5n59
Tags: 0.25.1-3ubuntu1
* Merge from debian testing.  Remaining changes:
  - debian/rules:
    + Don't start puppet when first installing puppet.
  - debian/puppet.conf, lib/puppet/defaults.rb:
    + Move templates to /etc/puppet
  - lib/puppet/defaults.rb:
    + Fix /var/lib/puppet/state ownership.
  - man/man8/puppet.conf.8: 
    + Fix broken URL in manpage.
  - debian/control:
    + Update maintainer accordint to spec.
    + Puppetmaster Recommends -> Suggests
    + Created puppet-testsuite as a seperate. Allow the users to run puppet's 
      testsuite.
  - tests/Rakefile: Fix rakefile so that the testsuite can acutally be ran.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
#!/usr/bin/env ruby
2
 
# == Synopsis 
3
 
#
4
 
# Retrieve the client configuration from the central puppet server and apply
5
 
# it to the local host.
6
 
#
7
 
# Currently must be run out periodically, using cron or something similar.
8
 
#
9
 
# = Usage
10
 
#
11
 
#   puppetd  [-D|--daemonize|--no-daemonize] [-d|--debug] [--disable] [--enable]
12
 
#       [-h|--help] [--fqdn <host name>] [-l|--logdest syslog|<file>|console]
13
 
#       [-o|--onetime] [--serve <handler>] [-t|--test] [--noop]
14
 
#       [-V|--version] [-v|--verbose] [-w|--waitforcert <seconds>]
15
 
#
16
 
# = Description
17
 
#
18
 
# This is the main puppet client.  Its job is to retrieve the local machine's
19
 
# configuration from a remote server and apply it.  In order to successfully
20
 
# communicate with the remote server, the client must have a certificate signed
21
 
# by a certificate authority that the server trusts; the recommended method
22
 
# for this, at the moment, is to run a certificate authority as part of the
23
 
# puppet server (which is the default).  The client will connect and request
24
 
# a signed certificate, and will continue connecting until it receives one.
25
 
#
26
 
# Once the client has a signed certificate, it will retrieve its configuration
27
 
# and apply it.
28
 
#
29
 
# = Usage Notes
30
 
#
31
 
# +puppetd+ does its best to find a compromise between interactive use and
32
 
# daemon use.  Run with no arguments and no configuration, it will go into the
33
 
# backgroun, attempt to get a signed certificate, and retrieve and apply its
34
 
# configuration every 30 minutes.
35
 
#
36
 
# Some flags are meant specifically for interactive use -- in particular,
37
 
# +test+ and +tags+ are useful.  +test+ enables verbose logging, causes
38
 
# the daemon to stay in the foreground, exits if the server's configuration is
39
 
# invalid (this happens if, for instance, you've left a syntax error on the
40
 
# server), and exits after running the configuration once (rather than hanging
41
 
# around as a long-running process).
42
 
#
43
 
# +tags+ allows you to specify what portions of a configuration you want to apply.
44
 
# Puppet elements are tagged with all of the class or definition names that
45
 
# contain them, and you can use the +tags+ flag to specify one of these names,
46
 
# causing only configuration elements contained within that class or definition
47
 
# to be applied.  This is very useful when you are testing new configurations --
48
 
# for instance, if you are just starting to manage +ntpd+, you would put all of
49
 
# the new elements into an +ntpd+ class, and call puppet with +--tags ntpd+,
50
 
# which would only apply that small portion of the configuration during your
51
 
# testing, rather than applying the whole thing.
52
 
#
53
 
# = Options
54
 
#
55
 
# Note that any configuration parameter that's valid in the configuration file
56
 
# is also a valid long argument.  For example, 'server' is a valid configuration
57
 
# parameter, so you can specify '--server <servername>' as an argument.
58
 
#
59
 
# See the configuration file documentation at
60
 
# http://reductivelabs.com/trac/puppet/wiki/ConfigurationReference for
61
 
# the full list of acceptable parameters. A commented list of all
62
 
# configuration options can also be generated by running puppetd with
63
 
# '--genconfig'.
64
 
#
65
 
# daemonize::
66
 
#   Send the process into the background.  This is the default.
67
 
#
68
 
# no-daemonize::
69
 
#   Do not send the process into the background.
70
 
#
71
 
# debug::
72
 
#   Enable full debugging.
73
 
#
74
 
# disable::
75
 
#   Disable working on the local system.  This puts a lock file in place,
76
 
#   causing +puppetd+ not to work on the system until the lock file is removed.
77
 
#   This is useful if you are testing a configuration and do not want the central
78
 
#   configuration to override the local state until everything is tested and
79
 
#   committed.
80
 
#
81
 
#   +puppetd+ uses the same lock file while it is running, so no more than one
82
 
#   +puppetd+ process is working at a time.
83
 
#
84
 
#   +puppetd+ exits after executing this.
85
 
#
86
 
# enable::
87
 
#   Enable working on the local system.  This removes any lock file, causing
88
 
#   +puppetd+ to start managing the local system again (although it will continue
89
 
#   to use its normal scheduling, so it might not start for another half hour).
90
 
#
91
 
#   +puppetd+ exits after executing this.
92
 
#
93
 
# fqdn::
94
 
#   Set the fully-qualified domain name of the client.  This is only used for
95
 
#   certificate purposes, but can be used to override the discovered hostname.
96
 
#   If you need to use this flag, it is generally an indication of a setup problem.
97
 
#
98
 
# help::
99
 
#   Print this help message
100
 
#
101
 
# logdest::
102
 
#   Where to send messages.  Choose between syslog, the console, and a log file.
103
 
#   Defaults to sending messages to syslog, or the console if debugging or
104
 
#   verbosity is enabled.
105
 
#
106
 
# no-client::
107
 
#   Do not create a config client.  This will cause the daemon to run
108
 
#   without ever checking for its configuration automatically, and only
109
 
#   makes sense when used in conjunction with --listen.
110
 
#
111
 
# onetime::
112
 
#   Run the configuration once, rather than as a long-running daemon.  This is
113
 
#   useful for interactively running puppetd.
114
 
#
115
 
# serve::
116
 
#   Start another type of server.  By default, +puppetd+ will start
117
 
#   a service handler that allows authenticated and authorized remote nodes to
118
 
#   trigger the configuration to be pulled down and applied.  You can specify
119
 
#   any handler here that does not require configuration, e.g., filebucket, ca,
120
 
#   or resource.  The handlers are in +lib/puppet/network/handler+, and the names
121
 
#   must match exactly, both in the call to +serve+ and in +namespaceauth.conf+.
122
 
#
123
 
# test::
124
 
#   Enable the most common options used for testing.  These are +onetime+,
125
 
#   +verbose+, +ignorecache, and +no-usecacheonfailure+.
126
 
#
127
 
# noop::
128
 
#   Use +noop+ mode where the daemon runs in a no-op or dry-run mode.  This is useful
129
 
#   for seeing what changes Puppet will make without actually executing the changes.
130
 
#
131
 
# verbose::
132
 
#   Turn on verbose reporting.
133
 
#
134
 
# version::
135
 
#   Print the puppet version number and exit.
136
 
#
137
 
# waitforcert::
138
 
#   This option only matters for daemons that do not yet have certificates
139
 
#   and it is enabled by default, with a value of 120 (seconds).  This causes
140
 
#   +puppetd+ to connect to the server every 2 minutes and ask it to sign a
141
 
#   certificate request.  This is useful for the initial setup of a puppet
142
 
#   client.  You can turn off waiting for certificates by specifying a time
143
 
#   of 0.
144
 
#
145
 
# = Example
146
 
#
147
 
#   puppetd --server puppet.domain.com
148
 
#
149
 
# = Author
150
 
#
151
 
# Luke Kanies
152
 
#
153
 
# = Copyright
154
 
#
155
 
# Copyright (c) 2005, 2006 Reductive Labs, LLC
156
 
# Licensed under the GNU Public License
157
 
 
158
 
# Do an initial trap, so that cancels don't get a stack trace.
159
 
trap(:INT) do
160
 
    $stderr.puts "Cancelling startup"
161
 
    exit(0)
162
 
end
163
 
 
164
 
require 'puppet'
165
 
require 'puppet/executables/client/certhandler'
166
 
require 'puppet/network/client'
167
 
require 'getoptlong'
168
 
 
169
 
options = [
170
 
        [ "--centrallogging",                   GetoptLong::NO_ARGUMENT ],
171
 
        [ "--disable",                          GetoptLong::NO_ARGUMENT ],
172
 
        [ "--debug",    "-d",                   GetoptLong::NO_ARGUMENT ],
173
 
        [ "--enable",                           GetoptLong::NO_ARGUMENT ],
174
 
        [ "--fqdn",     "-f",                   GetoptLong::REQUIRED_ARGUMENT ],
175
 
        [ "--help",             "-h",                   GetoptLong::NO_ARGUMENT ],
176
 
        [ "--logdest",  "-l",                   GetoptLong::REQUIRED_ARGUMENT ],
177
 
        [ "--onetime",  "-o",                   GetoptLong::NO_ARGUMENT ],
178
 
        [ "--test",         "-t",                       GetoptLong::NO_ARGUMENT ],
179
 
        [ "--serve",    "-s",                   GetoptLong::REQUIRED_ARGUMENT ],
180
 
        [ "--no-client",                        GetoptLong::NO_ARGUMENT ],
181
 
        [ "--verbose",  "-v",                   GetoptLong::NO_ARGUMENT ],
182
 
        [ "--version",  "-V",                   GetoptLong::NO_ARGUMENT ],
183
 
        [ "--waitforcert",      "-w",           GetoptLong::REQUIRED_ARGUMENT ]
184
 
]
185
 
 
186
 
# Add all of the config parameters as valid options.
187
 
Puppet.settings.addargs(options)
188
 
 
189
 
result = GetoptLong.new(*options)
190
 
 
191
 
args = {}
192
 
 
193
 
options = {
194
 
    :waitforcert => 120,  # Default to checking for certs every 5 minutes
195
 
    :onetime => false,
196
 
    :verbose => false,
197
 
    :debug => false,
198
 
    :centrallogs => false,
199
 
    :setdest => false,
200
 
    :enable => false,
201
 
    :disable => false,
202
 
    :client => true,
203
 
    :fqdn => nil,
204
 
    :serve => {}
205
 
}
206
 
 
207
 
begin
208
 
    explicit_waitforcert = false
209
 
    result.each { |opt,arg|
210
 
        case opt
211
 
            # First check to see if the argument is a valid configuration parameter;
212
 
            # if so, set it. NOTE: there is a catch-all at the bottom for defaults.rb
213
 
            when "--disable"
214
 
                options[:disable] = true
215
 
            when "--serve"
216
 
                if Puppet::Network::Handler.handler(arg)
217
 
                    options[:serve][arg.to_sym] = {}
218
 
                else
219
 
                    raise "Could not find handler for %s" % arg
220
 
                end
221
 
            when "--enable"
222
 
                options[:enable] = true
223
 
            when "--test"
224
 
                options[:test] = true
225
 
            when "--centrallogging"
226
 
                options[:centrallogs] = true
227
 
            when "--help"
228
 
                if Puppet.features.usage?
229
 
                    RDoc::usage && exit
230
 
                else
231
 
                    puts "No help available unless you have RDoc::usage installed"
232
 
                    exit
233
 
                end
234
 
            when "--version"
235
 
                puts "%s" % Puppet.version
236
 
                exit
237
 
            when "--verbose"
238
 
                options[:verbose] = true
239
 
            when "--debug"
240
 
                options[:debug] = true
241
 
            when "--fqdn"
242
 
                options[:fqdn] = arg
243
 
            when "--no-client"
244
 
                options[:client] = false
245
 
            when "--onetime"
246
 
                options[:onetime] = true
247
 
                options[:waitforcert] = 0 unless explicit_waitforcert
248
 
            when "--port"
249
 
                args[:Port] = arg
250
 
            when "--logdest"
251
 
                begin
252
 
                    Puppet::Util::Log.newdestination(arg)
253
 
                    options[:setdest] = true
254
 
                rescue => detail
255
 
                    if Puppet[:debug]
256
 
                        puts detail.backtrace
257
 
                    end
258
 
                    $stderr.puts detail.to_s
259
 
                end
260
 
            when "--waitforcert"
261
 
                options[:waitforcert] = arg.to_i
262
 
                explicit_waitforcert = true
263
 
            else
264
 
                Puppet.settings.handlearg(opt, arg)
265
 
        end
266
 
    }
267
 
rescue GetoptLong::InvalidOption => detail
268
 
    $stderr.puts detail
269
 
    $stderr.puts "Try '#{$0} --help'"
270
 
    exit(1)
271
 
end
272
 
 
273
 
# Now parse the config
274
 
Puppet.parse_config
275
 
 
276
 
if options[:test]
277
 
    # Enable all of the most common test options.
278
 
    Puppet.settings.handlearg("--ignorecache")
279
 
    Puppet.settings.handlearg("--no-usecacheonfailure")
280
 
    Puppet.settings.handlearg("--no-splay")
281
 
    Puppet.settings.handlearg("--show_diff")
282
 
    Puppet.settings.handlearg("--no-daemonize")
283
 
    options[:verbose] = true
284
 
    options[:onetime] = true
285
 
    options[:waitforcert] = 0
286
 
end
287
 
 
288
 
# Handle the logging settings.
289
 
if options[:debug] or options[:verbose]
290
 
    Puppet::Util::Log.newdestination(:console)
291
 
    if options[:debug]
292
 
        Puppet::Util::Log.level = :debug
293
 
    else
294
 
        Puppet::Util::Log.level = :info
295
 
    end
296
 
end
297
 
 
298
 
unless options[:setdest]
299
 
    Puppet::Util::Log.newdestination(:syslog)
300
 
end
301
 
 
302
 
if Puppet.settings.print_configs?
303
 
    exit(Puppet.settings.print_configs ? 0 : 1)
304
 
end
305
 
 
306
 
# If noop is set, then also enable diffs
307
 
if Puppet[:noop]
308
 
    Puppet[:show_diff] = true
309
 
end
310
 
 
311
 
args[:Server] = Puppet[:server]
312
 
if options[:fqdn]
313
 
    args[:FQDN] = options[:fqdn]
314
 
    Puppet[:certname] = options[:fqdn] 
315
 
end
316
 
 
317
 
if options[:centrallogs]
318
 
    logdest = args[:Server]
319
 
 
320
 
    if args.include?(:Port)
321
 
        logdest += ":" + args[:Port]
322
 
    end
323
 
    Puppet::Util::Log.newdestination(logdest)
324
 
end
325
 
 
326
 
# We need tomake the client either way, we just don't start it
327
 
# if --no-client is set.
328
 
client = Puppet::Network::Client.master.new(args)
329
 
if options[:enable]
330
 
    client.enable
331
 
elsif options[:disable]
332
 
    client.disable
333
 
end
334
 
 
335
 
if options[:enable] or options[:disable]
336
 
    exit(0)
337
 
end
338
 
 
339
 
server = nil
340
 
 
341
 
# It'd be nice to daemonize later, but we have to daemonize before the
342
 
# waitforcert happens.
343
 
if Puppet[:daemonize]
344
 
    client.daemonize
345
 
end
346
 
 
347
 
unless Puppet::Executables::Client::CertHandler.new(options[:waitforcert], options[:onetime]).read_retrieve
348
 
    client.recycle_connection
349
 
end
350
 
 
351
 
objects = []
352
 
 
353
 
# This has to go after the certs are dealt with.
354
 
if Puppet[:listen] and ! options[:onetime]
355
 
    unless FileTest.exists?(Puppet[:authconfig])
356
 
        Puppet.err "Will not start without authorization file %s" %
357
 
            Puppet[:authconfig]
358
 
        exit(14)
359
 
    end
360
 
 
361
 
    # FIXME: we should really figure out how to distribute the CRL
362
 
    # to clients. In the meantime, we just disable CRL checking if
363
 
    # the CRL file doesn't exist
364
 
    unless File::exist?(Puppet[:cacrl])
365
 
        Puppet[:cacrl] = 'false' 
366
 
    end
367
 
 
368
 
    handlers = nil
369
 
 
370
 
    if options[:serve].empty?
371
 
        handlers = {:Runner => {}}
372
 
    else
373
 
        handlers = options[:serve]
374
 
    end
375
 
 
376
 
    handlers.each do |name, hash|
377
 
        Puppet.info "Starting handler for %s" % name
378
 
    end
379
 
 
380
 
    args[:Handlers] = handlers
381
 
    args[:Port] = Puppet[:puppetport]
382
 
 
383
 
    require 'puppet/network/http_server/webrick'
384
 
 
385
 
    begin
386
 
        server = Puppet::Network::HTTPServer::WEBrick.new(args)
387
 
    rescue => detail
388
 
        $stderr.puts detail
389
 
        puts detail.backtrace
390
 
        exit(1)
391
 
    end
392
 
 
393
 
    objects << server
394
 
elsif options[:onetime] and Puppet[:listen]
395
 
    Puppet.notice "Ignoring --listen on onetime run"
396
 
end
397
 
 
398
 
if options[:client]
399
 
    objects << client
400
 
end
401
 
 
402
 
# Set traps for INT and TERM
403
 
Puppet.settraps
404
 
 
405
 
# If --onetime is specified, we don't run 'start', which means we don't
406
 
# create a pidfile.
407
 
if options[:onetime]
408
 
    unless options[:client]
409
 
        $stderr.puts "onetime is specified but there is no client"
410
 
        exit(43)
411
 
    end
412
 
 
413
 
    # Add the service, so the traps work correctly.
414
 
    Puppet.newservice(client)
415
 
 
416
 
    begin
417
 
        client.run
418
 
    rescue => detail
419
 
        if Puppet[:trace]
420
 
            puts detail.backtrace
421
 
        end
422
 
        Puppet.err detail.to_s
423
 
    end
424
 
    exit(0)
425
 
else
426
 
    if server
427
 
        Puppet.newservice(server)
428
 
    end
429
 
 
430
 
    if options[:client]
431
 
        Puppet.notice "Starting Puppet client version %s" % [Puppet.version]
432
 
        Puppet.newservice(client)
433
 
    end
434
 
 
435
 
    Puppet.settraps
436
 
 
437
 
    Puppet.start
438
 
end
439