4
# Retrieve the client configuration from the central puppet server and apply
5
# it to the local host.
7
# Currently must be run out periodically, using cron or something similar.
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>]
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.
26
# Once the client has a signed certificate, it will retrieve its configuration
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.
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).
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.
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.
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
66
# Send the process into the background. This is the default.
69
# Do not send the process into the background.
72
# Enable full debugging.
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
81
# +puppetd+ uses the same lock file while it is running, so no more than one
82
# +puppetd+ process is working at a time.
84
# +puppetd+ exits after executing this.
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).
91
# +puppetd+ exits after executing this.
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.
99
# Print this help message
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.
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.
112
# Run the configuration once, rather than as a long-running daemon. This is
113
# useful for interactively running puppetd.
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+.
124
# Enable the most common options used for testing. These are +onetime+,
125
# +verbose+, +ignorecache, and +no-usecacheonfailure+.
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.
132
# Turn on verbose reporting.
135
# Print the puppet version number and exit.
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
147
# puppetd --server puppet.domain.com
155
# Copyright (c) 2005, 2006 Reductive Labs, LLC
156
# Licensed under the GNU Public License
158
# Do an initial trap, so that cancels don't get a stack trace.
160
$stderr.puts "Cancelling startup"
165
require 'puppet/executables/client/certhandler'
166
require 'puppet/network/client'
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 ]
186
# Add all of the config parameters as valid options.
187
Puppet.settings.addargs(options)
189
result = GetoptLong.new(*options)
194
:waitforcert => 120, # Default to checking for certs every 5 minutes
198
:centrallogs => false,
208
explicit_waitforcert = false
209
result.each { |opt,arg|
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
214
options[:disable] = true
216
if Puppet::Network::Handler.handler(arg)
217
options[:serve][arg.to_sym] = {}
219
raise "Could not find handler for %s" % arg
222
options[:enable] = true
224
options[:test] = true
225
when "--centrallogging"
226
options[:centrallogs] = true
228
if Puppet.features.usage?
231
puts "No help available unless you have RDoc::usage installed"
235
puts "%s" % Puppet.version
238
options[:verbose] = true
240
options[:debug] = true
244
options[:client] = false
246
options[:onetime] = true
247
options[:waitforcert] = 0 unless explicit_waitforcert
252
Puppet::Util::Log.newdestination(arg)
253
options[:setdest] = true
256
puts detail.backtrace
258
$stderr.puts detail.to_s
261
options[:waitforcert] = arg.to_i
262
explicit_waitforcert = true
264
Puppet.settings.handlearg(opt, arg)
267
rescue GetoptLong::InvalidOption => detail
269
$stderr.puts "Try '#{$0} --help'"
273
# Now parse the config
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
288
# Handle the logging settings.
289
if options[:debug] or options[:verbose]
290
Puppet::Util::Log.newdestination(:console)
292
Puppet::Util::Log.level = :debug
294
Puppet::Util::Log.level = :info
298
unless options[:setdest]
299
Puppet::Util::Log.newdestination(:syslog)
302
if Puppet.settings.print_configs?
303
exit(Puppet.settings.print_configs ? 0 : 1)
306
# If noop is set, then also enable diffs
308
Puppet[:show_diff] = true
311
args[:Server] = Puppet[:server]
313
args[:FQDN] = options[:fqdn]
314
Puppet[:certname] = options[:fqdn]
317
if options[:centrallogs]
318
logdest = args[:Server]
320
if args.include?(:Port)
321
logdest += ":" + args[:Port]
323
Puppet::Util::Log.newdestination(logdest)
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)
331
elsif options[:disable]
335
if options[:enable] or options[:disable]
341
# It'd be nice to daemonize later, but we have to daemonize before the
342
# waitforcert happens.
343
if Puppet[:daemonize]
347
unless Puppet::Executables::Client::CertHandler.new(options[:waitforcert], options[:onetime]).read_retrieve
348
client.recycle_connection
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" %
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'
370
if options[:serve].empty?
371
handlers = {:Runner => {}}
373
handlers = options[:serve]
376
handlers.each do |name, hash|
377
Puppet.info "Starting handler for %s" % name
380
args[:Handlers] = handlers
381
args[:Port] = Puppet[:puppetport]
383
require 'puppet/network/http_server/webrick'
386
server = Puppet::Network::HTTPServer::WEBrick.new(args)
389
puts detail.backtrace
394
elsif options[:onetime] and Puppet[:listen]
395
Puppet.notice "Ignoring --listen on onetime run"
402
# Set traps for INT and TERM
405
# If --onetime is specified, we don't run 'start', which means we don't
408
unless options[:client]
409
$stderr.puts "onetime is specified but there is no client"
413
# Add the service, so the traps work correctly.
414
Puppet.newservice(client)
420
puts detail.backtrace
422
Puppet.err detail.to_s
427
Puppet.newservice(server)
431
Puppet.notice "Starting Puppet client version %s" % [Puppet.version]
432
Puppet.newservice(client)