bin/puppetd in puppet-0.16.0 vs bin/puppetd in puppet-0.18.4

- old
+ new

@@ -1,19 +1,19 @@ -#!/usr/bin/ruby +#!/usr/bin/env ruby # == Synopsis # # Retrieve the client configuration from the central puppet server and apply # it to the local host. # # Currently must be run out periodically, using cron or something similar. # # = Usage # -# puppetd [-h|--help] [-V|--version] [-d|--debug] [-v|--verbose] -# [-l|--logdest <syslog|<file>|console>] [--fqdn <host name>] -# [-o|--onetime] [-w|--waitforcert <seconds>] [-t|--test] -# [--disable] [--enable] +# puppetd [-D|--daemonize] [-d|--debug] [--disable] [--enable] +# [-h|--help] [--fqdn <host name>] [-l|--logdest syslog|<file>|console] +# [-o|--onetime] [--serve <handler>] [-t|--test] +# [-V|--version] [-v|--verbose] [-w|--waitforcert <seconds>] # # = Description # # This is the main puppet client. Its job is to retrieve the local machine's # configuration from a remote server and apply it. In order to successfully @@ -24,22 +24,51 @@ # a signed certificate, and will continue connecting until it receives one. # # Once the client has a signed certificate, it will retrieve its configuration # and apply it. # -# The vast majority of options are shared between all Puppet executables and -# are documented completely at -# http://reductivelabs.com/projects/puppet/documentation. +# = Usage Notes # +# +puppetd+ does its best to find a compromise between interactive use and +# daemon use. Run with no arguments and no configuration, it will go into the +# backgroun, attempt to get a signed certificate, and retrieve and apply its +# configuration every 30 minutes. +# +# Some flags are meant specifically for interactive use -- in particular, +# +test+ and +tag+ are useful. +test+ enables verobse logging, causes +# the daemon to stay in the foreground, exits if the server's configuration is +# invalid (this happens if, for instance, you've left a syntax error on the +# server), and exits after running the configuration once (rather than hanging +# around as a long-running process). +# +# +tag+ allows you to specify what portions of a configuration you want to apply. +# Puppet elements are tagged with all of the class or definition names that +# contain them, and you can use the +tag+ flag to specify one of these names, +# causing only configuration elements contained within that class or definition +# to be applied. This is very useful when you are testing new configurations -- +# for instance, if you are just starting to manage +ntpd+, you would put all of +# the new elements into an +ntpd+ class, and call puppet with +--tag ntpd+, +# which would only apply that small portion of the configuration during your +# testing, rather than applying the whole thing. +# # = Options # # Note that any configuration parameter that's valid in the configuration file # is also a valid long argument. For example, 'server' is a valid configuration # parameter, so you can specify '--server <servername>' as an argument. # -# See the configuration file for the full list of acceptable parameters. +# See the configuration file documentation at +# http://reductivelabs.com/projects/puppet/documentation/puppet-executable-reference +# for the full list of acceptable parameters. # +# daemonize:: +# Send the process into the background. This is the default unless +# +verbose+ or +debug+ is enabled. +# +# debug:: +# Enable full debugging. +# # disable:: # Disable working on the local system. This puts a lock file in place, # causing +puppetd+ not to work on the system until the lock file is removed. # This is useful if you are testing a configuration and do not want the central # configuration to override the local state until everything is tested and @@ -48,13 +77,10 @@ # +puppetd+ uses the same lock file while it is running, so no more than one # +puppetd+ process is working at a time. # # +puppetd+ exits after executing this. # -# debug:: -# Enable full debugging. -# # enable:: # Enable working on the local system. This removes any lock file, causing # +puppetd+ to start managing the local system again (although it will continue # to use its normal scheduling, so it might not start for another half hour). # @@ -75,10 +101,17 @@ # # onetime:: # Run the configuration once, rather than as a long-running daemon. This is # useful for interactively running puppetd. # +# serve:: +# Start another type of server. By default default, +puppetd+ will start +# a server that allows authenticated and authorized remote nodes to trigger +# the configuration to be pulled down and applied. You can specify +# any other type of service here that does not require configuration, +# e.g., filebucket, ca, or pelement. +# # test:: # Enable the most common options used for testing. These are +onetime+, # +verbose+, and +no-usecacheonfailure+. # # verbose:: @@ -86,12 +119,16 @@ # # version:: # Print the puppet version number and exit. # # waitforcert:: -# Have the process wait around, continuously retrying for the certificate -# each <argument> seconds. +# This option only matters for daemons that do not yet have certificates +# and it is enabled by default, with a value of 120 (seconds). This causes +# +puppetd+ to connect to the server every 2 minutes and ask it to sign a +# certificate request. This is useful for the initial setup of a puppet +# client. You can turn off waiting for certificates by specifying a time +# of 0. # # = Example # # puppetd --server puppet.domain.com # @@ -102,10 +139,15 @@ # = Copyright # # Copyright (c) 2005, 2006 Reductive Labs, LLC # Licensed under the GNU Public License +# Do an initial trap, so that cancels don't get a stack trace. +trap(:INT) do + $stderr.puts "Cancelling startup" + exit(0) +end require 'puppet' require 'puppet/server' require 'puppet/client' require 'getoptlong' @@ -117,62 +159,69 @@ $haveusage = false end options = [ [ "--centrallogging", GetoptLong::NO_ARGUMENT ], + [ "--daemonize", "-D", GetoptLong::NO_ARGUMENT ], [ "--disable", GetoptLong::NO_ARGUMENT ], [ "--debug", "-d", GetoptLong::NO_ARGUMENT ], [ "--enable", GetoptLong::NO_ARGUMENT ], [ "--fqdn", "-f", GetoptLong::REQUIRED_ARGUMENT ], [ "--help", "-h", GetoptLong::NO_ARGUMENT ], [ "--logdest", "-l", GetoptLong::REQUIRED_ARGUMENT ], [ "--onetime", "-o", GetoptLong::NO_ARGUMENT ], [ "--test", "-t", GetoptLong::NO_ARGUMENT ], + [ "--no-client", GetoptLong::NO_ARGUMENT ], [ "--verbose", "-v", GetoptLong::NO_ARGUMENT ], [ "--version", "-V", GetoptLong::NO_ARGUMENT ], [ "--waitforcert", "-w", GetoptLong::REQUIRED_ARGUMENT ] ] # Add all of the config parameters as valid options. Puppet.config.addargs(options) result = GetoptLong.new(*options) -server = "puppet" -fqdn = nil args = {} -waitforcert = false +options = { + :waitforcert => 120, # Default to checking for certs every 5 minutes + :onetime => false, + :centrallogs => false, + :setdest => false, + :enable => false, + :disable => false, + :client => true, + :fqdn => nil, + :serve => {} +} -onetime = false - -centrallogs = false - -setdest = false - -enable = false -disable = false - begin result.each { |opt,arg| case opt # First check to see if the argument is a valid configuration parameter; # if so, set it. + when "--daemonize" + options[:daemonize] = true when "--disable" - disable = true + options[:disable] = true + when "--serve" + if klass = Puppet::Server::Handler.handler(arg) + options[:serve][klass.name] = klass + end when "--enable" - enable = true + options[:enable] = true when "--test" # Enable all of the most common test options. Puppet.config.handlearg("--no-usecacheonfailure") - onetime = true + options[:onetime] = true unless Puppet::Log.level == :debug Puppet::Log.level = :info end Puppet::Log.newdestination(:console) when "--centrallogging" - centrallogs = true + options[:centrallogs] = true when "--help" if $haveusage RDoc::usage && exit else puts "No help available unless you have RDoc::usage installed" @@ -186,24 +235,26 @@ Puppet::Log.newdestination(:console) when "--debug" Puppet::Log.level = :debug Puppet::Log.newdestination(:console) when "--fqdn" - fqdn = arg + options[:fqdn] = arg + when "--no-client" + options[:client] = false when "--onetime" - onetime = true + options[:onetime] = true when "--port" args[:Port] = arg when "--logdest" begin Puppet::Log.newdestination(arg) - setdest = true + options[:setdest] = true rescue => detail $stderr.puts detail.to_s end when "--waitforcert" - waitforcert = arg.to_i + options[:waitforcert] = arg.to_i else Puppet.config.handlearg(opt, arg) end } rescue GetoptLong::InvalidOption => detail @@ -222,101 +273,173 @@ # Now parse the config if Puppet[:config] and File.exists? Puppet[:config] Puppet.config.parse(Puppet[:config]) end -if Puppet::Log.level == :debug or Puppet::Log.level == :info - args[:Daemonize] = false -else - args[:Daemonize] = true +# Default to daemonizing, but if verbose or debug is specified, +# default to staying in the foreground. +unless options.include?(:daemonize) + if Puppet::Log.level == :debug or Puppet::Log.level == :info + options[:daemonize] = false + else + options[:daemonize] = true + end end -unless setdest +unless options[:setdest] Puppet::Log.newdestination(:syslog) end args[:Server] = Puppet[:server] -if fqdn +if options[:fqdn] args[:FQDN] = fqdn end -if centrallogs +if options[:centrallogs] logdest = args[:Server] if args.include?(:Port) logdest += ":" + args[:Port] end Puppet::Log.newdestination(logdest) end -Puppet.notice "Starting Puppet client version %s" % [Puppet.version] -client = Puppet::Client::MasterClient.new(args) +if options[:onetime] + Puppet[:setpidfile] = false +end -if enable +# We need tomake the client either way, we just don't start it +# if --no-client is set. +client = Puppet::Client::MasterClient.new(args) +if options[:enable] client.enable -elsif disable +elsif options[:disable] client.disable end -if enable or disable +if options[:enable] or options[:disable] exit(0) end +server = nil + +# It'd be nice to daemonize later, but we have to daemonize before the +# waitforcert happens. +if options[:daemonize] + client.daemonize +end + unless client.readcert - if waitforcert + # If we don't already have the certificate, then create a client to + # request one. + caclient = Puppet::Client::CA.new(args) + if options[:waitforcert] > 0 begin - while ! client.requestcert do + while ! caclient.requestcert do Puppet.notice "Did not receive certificate" - sleep waitforcert + sleep options[:waitforcert] end rescue => detail Puppet.err "Could not request certificate: %s" % detail.to_s exit(23) end else - unless client.requestcert + unless caclient.requestcert Puppet.notice "No certificates; exiting" exit(1) end end - # Now, because the Net::HTTP object cannot be modified once we've connected, - # we need to recreate the client with the certs intact - client = Puppet::Client::MasterClient.new(args) + # Now read the new cert in. unless client.readcert - PUppet.err "Could not read certificates after retrieving them" + Puppet.err "Could not read certificates after retrieving them" exit(34) end end -if args[:Daemonize] - #exit(13) - client.daemonize +objects = [] + +# This has to go after the certs are dealt with. +if Puppet[:listen] + unless FileTest.exists?(Puppet[:authconfig]) + $stderr.puts "Will not start without authorization file %s" % + Puppet[:authconfig] + exit(14) + end + + handlers = nil + + if options[:serve].empty? + handlers = {:Runner => {}} + else + handlers = options[:serve].inject({}) do |hash, name, klass| + hash[name] = {} + end + end + + handlers.each do |name, hash| + Puppet.info "Starting handler for %s" % name + end + + args[:Handlers] = handlers + args[:Port] = Puppet[:puppetport] + + begin + server = Puppet::Server.new(args) + rescue => detail + $stderr.puts detail + puts detail.backtrace + exit(1) + end + + objects << server end # now set up the network client with the certs, now that we have them client.setcerts -[:INT, :TERM].each do |signal| - trap(signal) do - Puppet.notice "Caught #{signal}; shutting down" - client.shutdown - end +if options[:client] + objects << client end -if onetime +# Set traps for INT and TERM +Puppet.settraps + +if options[:onetime] + unless options[:client] + $stderr.puts "onetime is specified but there is no client" + exit(43) + end + + if server + Puppet.notice "Ignoring --listen on onetime run" + end + + # Add the service, so the traps work correctly. + Puppet.newservice(client) + begin client.run rescue => detail Puppet.err detail.to_s if Puppet[:debug] puts detail.backtrace end end + exit(0) else - client.start + if server + Puppet.newservice(server) + end - # Mmm, hackish + if options[:client] + Puppet.notice "Starting Puppet client version %s" % [Puppet.version] + Puppet.newservice(client) + end + + Puppet.settraps + Puppet.start end -# $Id: puppetd 1108 2006-04-11 23:08:48Z luke $ + +# $Id: puppetd 1415 2006-07-21 15:37:15Z luke $