From 4aef0ba7cfda4b2dc53bc8e379694d9735b401a4 Mon Sep 17 00:00:00 2001 From: luke Date: Sun, 20 May 2007 16:35:14 +0000 Subject: Fixing #323 -- puppetd and puppetmasterd are now in sbin; packages still need to be fixed git-svn-id: https://reductivelabs.com/svn/puppet/trunk@2529 980ebf18-57e1-0310-9a29-db15c13687c0 --- CHANGELOG | 3 + bin/puppetd | 449 ----------------------------------------- bin/puppetmasterd | 302 --------------------------- install.rb | 65 +++--- sbin/puppetd | 449 +++++++++++++++++++++++++++++++++++++++++ sbin/puppetmasterd | 302 +++++++++++++++++++++++++++ test/lib/puppettest/exetest.rb | 7 + 7 files changed, 798 insertions(+), 779 deletions(-) delete mode 100755 bin/puppetd delete mode 100755 bin/puppetmasterd create mode 100755 sbin/puppetd create mode 100755 sbin/puppetmasterd diff --git a/CHANGELOG b/CHANGELOG index e6d0b0292..b97acb323 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,6 @@ + Moved puppetd and puppetmasterd to sbin in svn and fixed install.rb + to copy them into sbin on the local system appropriately. (#323) + Added a splay option (#501). It's disabled when running under --test in puppetd. The value is random but cached. It defaults to the runinterval but can be tuned with --splaylimit diff --git a/bin/puppetd b/bin/puppetd deleted file mode 100755 index e9380adb9..000000000 --- a/bin/puppetd +++ /dev/null @@ -1,449 +0,0 @@ -#!/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 [-D|--daemonize] [-d|--debug] [--disable] [--enable] -# [-h|--help] [--fqdn ] [-l|--logdest syslog||console] -# [-o|--onetime] [--serve ] [-t|--test] -# [-V|--version] [-v|--verbose] [-w|--waitforcert ] -# -# = 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 -# communicate with the remote server, the client must have a certificate signed -# by a certificate authority that the server trusts; the recommended method -# for this, at the moment, is to run a certificate authority as part of the -# puppet server (which is the default). The client will connect and request -# 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. -# -# = 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 +tags+ 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). -# -# +tags+ 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 +tags+ 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 +--tags 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 ' as an argument. -# -# See the configuration file documentation at -# http://reductivelabs.com/projects/puppet/reference/configref.html for -# the full list of acceptable parameters. A commented list of all -# configuration options can also be generated by running puppetd with -# '--genconfig'. -# -# 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 -# committed. -# -# +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. -# -# 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). -# -# +puppetd+ exits after executing this. -# -# fqdn:: -# Set the fully-qualified domain name of the client. This is only used for -# certificate purposes, but can be used to override the discovered hostname. -# If you need to use this flag, it is generally an indication of a setup problem. -# -# help:: -# Print this help message -# -# logdest:: -# Where to send messages. Choose between syslog, the console, and a log file. -# Defaults to sending messages to syslog, or the console if debugging or -# verbosity is enabled. -# -# no-client:: -# Do not create a config client. This will cause the daemon to run -# without ever checking for its configuration automatically, and only -# makes sense when used in conjunction with --listen. -# -# 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, +puppetd+ will start -# a service handler that allows authenticated and authorized remote nodes to -# trigger the configuration to be pulled down and applied. You can specify -# any handler here that does not require configuration, e.g., filebucket, ca, -# or resource. The handlers are in +lib/puppet/network/handler+, and the names -# must match exactly, both in the call to +serve+ and in +namespaceauth.conf+. -# -# test:: -# Enable the most common options used for testing. These are +onetime+, -# +verbose+, +ignorecache, and +no-usecacheonfailure+. -# -# verbose:: -# Turn on verbose reporting. -# -# version:: -# Print the puppet version number and exit. -# -# waitforcert:: -# 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 -# -# = Author -# -# Luke Kanies -# -# = 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/network/client' -require 'getoptlong' - -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 ], - [ "--serve", "-s", GetoptLong::REQUIRED_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) - -args = {} - -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 => {} -} - -begin - explicit_waitforcert = false - 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" - options[:disable] = true - when "--serve" - if Puppet::Network::Handler.handler(arg) - options[:serve][arg.to_sym] = {} - else - raise "Could not find handler for %s" % arg - end - when "--enable" - options[:enable] = true - when "--test" - # Enable all of the most common test options. - Puppet.config.handlearg("--ignorecache") - Puppet.config.handlearg("--no-usecacheonfailure") - Puppet.config.handlearg("--no-splay") - options[:onetime] = true - options[:waitforcert] = 0 - unless Puppet::Util::Log.level == :debug - Puppet::Util::Log.level = :info - end - Puppet::Util::Log.newdestination(:console) - when "--centrallogging" - options[:centrallogs] = true - when "--help" - if Puppet.features.usage? - RDoc::usage && exit - else - puts "No help available unless you have RDoc::usage installed" - exit - end - when "--version" - puts "%s" % Puppet.version - exit - when "--verbose" - Puppet::Util::Log.level = :info - Puppet::Util::Log.newdestination(:console) - when "--debug" - Puppet::Util::Log.level = :debug - Puppet::Util::Log.newdestination(:console) - when "--fqdn" - options[:fqdn] = arg - when "--no-client" - options[:client] = false - when "--onetime" - options[:onetime] = true - options[:waitforcert] = 0 unless explicit_waitforcert - when "--port" - args[:Port] = arg - when "--logdest" - begin - Puppet::Util::Log.newdestination(arg) - options[:setdest] = true - rescue => detail - $stderr.puts detail.to_s - end - when "--waitforcert" - options[:waitforcert] = arg.to_i - explicit_waitforcert = true - else - Puppet.config.handlearg(opt, arg) - end - } -rescue GetoptLong::InvalidOption => detail - $stderr.puts detail - $stderr.puts "Try '#{$0} --help'" - exit(1) -end - -# Now parse the config -Puppet.parse_config - -Puppet.genconfig -Puppet.genmanifest - -# Default to daemonizing, but if verbose or debug is specified, -# default to staying in the foreground. -unless options.include?(:daemonize) - if Puppet::Util::Log.level == :debug or Puppet::Util::Log.level == :info - options[:daemonize] = false - else - options[:daemonize] = true - end -end - -unless options[:setdest] - Puppet::Util::Log.newdestination(:syslog) -end - -args[:Server] = Puppet[:server] -if options[:fqdn] - args[:FQDN] = options[:fqdn] -end - -if options[:centrallogs] - logdest = args[:Server] - - if args.include?(:Port) - logdest += ":" + args[:Port] - end - Puppet::Util::Log.newdestination(logdest) -end - -# We need tomake the client either way, we just don't start it -# if --no-client is set. -client = Puppet::Network::Client.master.new(args) -if options[:enable] - client.enable -elsif options[:disable] - client.disable -end - -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.read_cert - # If we don't already have the certificate, then create a client to - # request one. Use the special ca stuff, don't use the normal server and port. - caclient = Puppet::Network::Client.ca.new() - if options[:waitforcert] > 0 - begin - while ! caclient.request_cert do - Puppet.notice "Did not receive certificate" - sleep options[:waitforcert] - end - rescue => detail - Puppet.err "Could not request certificate: %s" % detail.to_s - exit(23) - end - else - unless caclient.request_cert - Puppet.notice "No certificates; exiting" - exit(1) - end - end - - # Now read the new cert in. - if client.read_cert - Puppet.notice "Got signed certificate" - else - Puppet.err "Could not read certificates after retrieving them" - exit(34) - end -end - -objects = [] - -# This has to go after the certs are dealt with. -if Puppet[:listen] and ! options[:onetime] - unless FileTest.exists?(Puppet[:authconfig]) - Puppet.err "Will not start without authorization file %s" % - Puppet[:authconfig] - exit(14) - end - - # FIXME: we should really figure out how to distribute the CRL - # to clients. In the meantime, we just disable CRL checking if - # the CRL file doesn't exist - unless File::exist?(Puppet[:cacrl]) - Puppet[:cacrl] = 'none' - end - - handlers = nil - - if options[:serve].empty? - handlers = {:Runner => {}} - else - handlers = options[:serve] - end - - handlers.each do |name, hash| - Puppet.info "Starting handler for %s" % name - end - - args[:Handlers] = handlers - args[:Port] = Puppet[:puppetport] - - require 'puppet/network/server/webrick' - - begin - server = Puppet::Network::Server::WEBrick.new(args) - rescue => detail - $stderr.puts detail - puts detail.backtrace - exit(1) - end - - objects << server -elsif options[:onetime] and Puppet[:listen] - Puppet.notice "Ignoring --listen on onetime run" -end - -if options[:client] - objects << client -end - -# Set traps for INT and TERM -Puppet.settraps - -# If --onetime is specified, we don't run 'start', which means we don't -# create a pidfile. -if options[:onetime] - unless options[:client] - $stderr.puts "onetime is specified but there is no client" - exit(43) - end - - # Add the service, so the traps work correctly. - Puppet.newservice(client) - - begin - client.run - rescue => detail - if Puppet[:trace] - puts detail.backtrace - end - Puppet.err detail.to_s - end - exit(0) -else - if server - Puppet.newservice(server) - end - - if options[:client] - Puppet.notice "Starting Puppet client version %s" % [Puppet.version] - Puppet.newservice(client) - end - - Puppet.settraps - - Puppet.start -end - -# $Id$ diff --git a/bin/puppetmasterd b/bin/puppetmasterd deleted file mode 100755 index f290d6f1f..000000000 --- a/bin/puppetmasterd +++ /dev/null @@ -1,302 +0,0 @@ -#!/usr/bin/env ruby - -# -# = Synopsis -# -# The central puppet server. Functions as a certificate authority by default. -# -# = Usage -# -# puppetmasterd [-D|--daemonize] [-d|--debug] [-h|--help] -# [-l|--logdest |console|syslog] [--nobucket] [--nonodes] -# [-v|--verbose] [-V|--version] -# -# = Description -# -# This is the puppet central daemon. -# -# = Options -# -# Note that any configuration parameter that's valid in the configuration file -# is also a valid long argument. For example, 'ssldir' is a valid configuration -# parameter, so you can specify '--ssldir ' as an argument. -# -# See the configuration file documentation at -# http://reductivelabs.com/projects/puppet/reference/configref.html for -# the full list of acceptable parameters. A commented list of all -# configuration options can also be generated by running puppetmasterdd with -# '--genconfig'. -# -# daemonize:: -# Send the process into the background. This is the default unless -# +verbose+ or +debug+ is enabled. -# -# debug:: -# Enable full debugging. Causes the daemon not to go into the background. -# -# help:: -# Print this help message. -# -# logdest:: -# Where to send messages. Choose between syslog, the console, and a log file. -# Defaults to sending messages to syslog, or the console -# if debugging or verbosity is enabled. -# -# nobucket:: -# Do not function as a file bucket. -# -# nonodes:: -# Do not use individual node designations; each node will receive the result -# of evaluating the entire configuration. -# -# noreports:: -# Do not start the reports server. -# -# verbose:: -# Enable verbosity. Causes the daemon not to go into the background. -# -# version:: -# Print the puppet version number and exit. -# -# = Example -# -# puppetmasterd -# -# = Author -# -# Luke Kanies -# -# = Copyright -# -# Copyright (c) 2005 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 'getoptlong' -require 'puppet' -require 'puppet/sslcertificates' - -options = [ - [ "--daemonize", "-D", GetoptLong::NO_ARGUMENT ], - [ "--debug", "-d", GetoptLong::NO_ARGUMENT ], - [ "--help", "-h", GetoptLong::NO_ARGUMENT ], - [ "--logdest", "-l", GetoptLong::REQUIRED_ARGUMENT ], - [ "--noca", GetoptLong::NO_ARGUMENT ], - [ "--nobucket", GetoptLong::NO_ARGUMENT ], - [ "--noreports", GetoptLong::NO_ARGUMENT ], - [ "--nonodes", GetoptLong::NO_ARGUMENT ], - [ "--verbose", "-v", GetoptLong::NO_ARGUMENT ], - [ "--version", "-V", GetoptLong::NO_ARGUMENT ] -] - -# Add all of the config parameters as valid options. -Puppet.config.addargs(options) - -result = GetoptLong.new(*options) - -master = {} -ca = {} -report = {} -fs = {} -bucket = {} - -options = { - :havereport => true, - :havebucket => true, - :havemaster => true, - :setdest => false, - :verbose => false, - :debug => false -} - -begin - result.each { |opt,arg| - case opt - when "--daemonize" - options[:daemonize] = true - when "--debug" - options[:debug] = true - when "--help" - if Puppet.features.usage? - RDoc::usage && exit - else - puts "No help available unless you have RDoc::usage installed" - exit - end - when "--noreports" - options[:havereport] = false - when "--nomaster" - options[:havemaster] = false - when "--nobucket" - options[:havebucket] = false - when "--nonodes" - master[:UseNodes] = false - when "--logdest" - begin - Puppet::Util::Log.newdestination(arg) - options[:setdest] = true - rescue => detail - if Puppet[:debug] - puts detail.backtrace - end - $stderr.puts detail.to_s - end - when "--version" - puts "%s" % Puppet.version - exit - when "--verbose" - options[:verbose] = true - else - Puppet.config.handlearg(opt, arg) - end - } -rescue GetoptLong::InvalidOption => detail - $stderr.puts "Try '#{$0} --help'" - #$stderr.puts detail - exit(1) -end - -# Handle the logging settings. -if options[:debug] or options[:verbose] - if options[:debug] - Puppet::Util::Log.level = :debug - else - Puppet::Util::Log.level = :info - end - - unless options[:daemonize] - Puppet::Util::Log.newdestination(:console) - options[:setdest] = true - end -end - -unless options[:setdest] - Puppet::Util::Log.newdestination(:syslog) -end - -# Now parse the config -Puppet.parse_config - -Puppet.genconfig -Puppet.genmanifest - -require 'etc' - -# Default to daemonizing, but if verbose or debug is specified, -# default to staying in the foreground. -unless options.include?(:daemonize) - if Puppet::Util::Log.level == :debug or Puppet::Util::Log.level == :info - options[:daemonize] = false - else - options[:daemonize] = true - end -end - -handlers = { - :Status => {}, -} - -if options[:havemaster] - handlers[:Master] = master -end - -if options[:havereport] - handlers[:Report] = report -end - -if Puppet[:ca] - handlers[:CA] = ca -end - -if options[:havebucket] - handlers[:FileBucket] = bucket -end - -if Puppet[:parseonly] - begin - Puppet::Network::Handler.master.new(master) - rescue => detail - if Puppet[:trace] - puts detail.backtrace - end - $stderr.puts detail - exit(32) - end - # we would have already exited if the file weren't syntactically correct - exit(0) -end - -if File.exists?(Puppet[:fileserverconfig]) - fs[:Config] = Puppet[:fileserverconfig] -#else -# Puppet.notice "File server config %s does not exist; skipping file serving" % -# Puppet[:fileserverconfig] -end - -if fs.include?(:Config) - handlers[:FileServer] = fs -end - -begin - case Puppet[:servertype] - when "webrick" - # use the default, um, everything - require 'puppet/network/server/webrick' - server = Puppet::Network::Server::WEBrick.new(:Handlers => handlers) - when "mongrel": - require 'puppet/network/server/mongrel' - handler = Puppet::Network::Server::MongrelHandler.new(handlers) - addr = Puppet[:bindaddress] - if addr == "" - addr = "127.0.0.1" - end - server = Mongrel::HttpServer.new(addr, Puppet[:masterport]) - server.register("/", handler) - else - Puppet.err "Invalid server type %s" % Puppet[:servertype] - exit(45) - end -rescue => detail - if Puppet[:trace] - puts detail.backtrace - end - $stderr.puts detail - exit(1) -end - -if Process.uid == 0 - begin - Puppet::Util.chuser - rescue => detail - if Puppet[:debug] - puts detail.backtrace - end - $stderr.puts "Could not change user to %s: %s" % [Puppet[:user], detail] - exit(39) - end -end - -# Mongrel doesn't shut down like webrick; we really need to write plugins for it. -if Puppet[:servertype] == "webrick" - Puppet.newservice(server) -end -Puppet.settraps - -if options[:daemonize] - server.daemonize -end - -Puppet.notice "Starting Puppet server version %s" % [Puppet.version] -case Puppet[:servertype] -when "webrick" - Puppet.start -when "mongrel": - server.run.join -end - -# $Id$ diff --git a/install.rb b/install.rb index b89f68fe1..0bfb706f4 100755 --- a/install.rb +++ b/install.rb @@ -61,13 +61,14 @@ def glob(list) end # Set these values to what you want installed. -bins = glob(%w{bin/**/*}) -rdoc = glob(%w{bin/**/* lib/**/*.rb README README-library CHANGELOG TODO Install}).reject { |e| e=~ /\.(bat|cmd)$/ } -ri = glob(%w(bin/**/*.rb lib/**/*.rb)).reject { |e| e=~ /\.(bat|cmd)$/ } +sbins = glob(%w{sbin/*}) +bins = glob(%w{bin/*}) +rdoc = glob(%w{bin/* sbin/* lib/**/*.rb README README-library CHANGELOG TODO Install}).reject { |e| e=~ /\.(bat|cmd)$/ } +ri = glob(%w(bin/*.rb sbin/* lib/**/*.rb)).reject { |e| e=~ /\.(bat|cmd)$/ } libs = glob(%w{lib/**/*.rb}) tests = glob(%w{tests/**/*.rb}) -def do_bins(bins, target, strip = 'bin/') +def do_bins(bins, target, strip = 's?bin/') bins.each do |bf| obf = bf.gsub(/#{strip}/, '') install_binfile(bf, obf, target) @@ -145,37 +146,40 @@ def prepare_installation opts.parse! end - bds = [".", ENV['TMP'], ENV['TEMP']] + tmpdirs = [".", ENV['TMP'], ENV['TEMP'], "/tmp", "/var/tmp"] version = [Config::CONFIG["MAJOR"], Config::CONFIG["MINOR"]].join(".") - ld = File.join(Config::CONFIG["libdir"], "ruby", version) - - sd = Config::CONFIG["sitelibdir"] - if sd.nil? - sd = $:.find { |x| x =~ /site_ruby/ } - if sd.nil? - sd = File.join(ld, "site_ruby") - elsif sd !~ Regexp.quote(version) - sd = File.join(sd, version) + libdir = File.join(Config::CONFIG["libdir"], "ruby", version) + + sitelibdir = Config::CONFIG["sitelibdir"] + if sitelibdir.nil? + sitelibdir = $:.find { |x| x =~ /site_ruby/ } + if sitelibdir.nil? + sitelibdir = File.join(libdir, "site_ruby") + elsif sitelibdir !~ Regexp.quote(version) + sitelibdir = File.join(sitelibdir, version) end end if (destdir = ENV['DESTDIR']) - bd = "#{destdir}#{Config::CONFIG['bindir']}" - sd = "#{destdir}#{sd}" - bds << bd - - FileUtils.makedirs(bd) - FileUtils.makedirs(sd) + bindir = "#{destdir}#{Config::CONFIG['bindir']}" + sbindir = "#{destdir}#{Config::CONFIG['sbindir']}" + sitelibdir = "#{destdir}#{sitelibdir}" + tmpdirs << bindir + + FileUtils.makedirs(bindir) + FileUtils.makedirs(sbindir) + FileUtils.makedirs(sitelibdir) else - bd = Config::CONFIG['bindir'] - bds << Config::CONFIG['bindir'] + bindir = Config::CONFIG['bindir'] + tmpdirs << Config::CONFIG['bindir'] end - InstallOptions.bin_dirs = bds.compact - InstallOptions.site_dir = sd - InstallOptions.bin_dir = bd - InstallOptions.lib_dir = ld + InstallOptions.tmp_dirs = tmpdirs.compact + InstallOptions.site_dir = sitelibdir + InstallOptions.bin_dir = bindir + InstallOptions.sbin_dir = sbindir + InstallOptions.lib_dir = libdir end ## @@ -236,7 +240,7 @@ end # windows, we add an '.rb' extension and let file associations do their stuff. def install_binfile(from, op_file, target) tmp_dir = nil - InstallOptions.bin_dirs.each do |t| + InstallOptions.tmp_dirs.each do |t| if File.directory?(t) and File.writable?(t) tmp_dir = t break @@ -251,7 +255,11 @@ def install_binfile(from, op_file, target) File.open(tmp_file, "w") do |op| ruby = File.join(Config::CONFIG['bindir'], Config::CONFIG['ruby_install_name']) op.puts "#!#{ruby}" - op.write ip.read + contents = ip.readlines + if contents[0] =~ /^#!/ + contents.shift + end + op.write contents.join() end end @@ -302,5 +310,6 @@ prepare_installation run_tests(tests) if InstallOptions.tests #build_rdoc(rdoc) if InstallOptions.rdoc #build_ri(ri) if InstallOptions.ri +do_bins(sbins, InstallOptions.sbin_dir) do_bins(bins, InstallOptions.bin_dir) do_libs(libs) diff --git a/sbin/puppetd b/sbin/puppetd new file mode 100755 index 000000000..e9380adb9 --- /dev/null +++ b/sbin/puppetd @@ -0,0 +1,449 @@ +#!/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 [-D|--daemonize] [-d|--debug] [--disable] [--enable] +# [-h|--help] [--fqdn ] [-l|--logdest syslog||console] +# [-o|--onetime] [--serve ] [-t|--test] +# [-V|--version] [-v|--verbose] [-w|--waitforcert ] +# +# = 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 +# communicate with the remote server, the client must have a certificate signed +# by a certificate authority that the server trusts; the recommended method +# for this, at the moment, is to run a certificate authority as part of the +# puppet server (which is the default). The client will connect and request +# 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. +# +# = 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 +tags+ 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). +# +# +tags+ 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 +tags+ 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 +--tags 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 ' as an argument. +# +# See the configuration file documentation at +# http://reductivelabs.com/projects/puppet/reference/configref.html for +# the full list of acceptable parameters. A commented list of all +# configuration options can also be generated by running puppetd with +# '--genconfig'. +# +# 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 +# committed. +# +# +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. +# +# 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). +# +# +puppetd+ exits after executing this. +# +# fqdn:: +# Set the fully-qualified domain name of the client. This is only used for +# certificate purposes, but can be used to override the discovered hostname. +# If you need to use this flag, it is generally an indication of a setup problem. +# +# help:: +# Print this help message +# +# logdest:: +# Where to send messages. Choose between syslog, the console, and a log file. +# Defaults to sending messages to syslog, or the console if debugging or +# verbosity is enabled. +# +# no-client:: +# Do not create a config client. This will cause the daemon to run +# without ever checking for its configuration automatically, and only +# makes sense when used in conjunction with --listen. +# +# 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, +puppetd+ will start +# a service handler that allows authenticated and authorized remote nodes to +# trigger the configuration to be pulled down and applied. You can specify +# any handler here that does not require configuration, e.g., filebucket, ca, +# or resource. The handlers are in +lib/puppet/network/handler+, and the names +# must match exactly, both in the call to +serve+ and in +namespaceauth.conf+. +# +# test:: +# Enable the most common options used for testing. These are +onetime+, +# +verbose+, +ignorecache, and +no-usecacheonfailure+. +# +# verbose:: +# Turn on verbose reporting. +# +# version:: +# Print the puppet version number and exit. +# +# waitforcert:: +# 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 +# +# = Author +# +# Luke Kanies +# +# = 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/network/client' +require 'getoptlong' + +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 ], + [ "--serve", "-s", GetoptLong::REQUIRED_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) + +args = {} + +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 => {} +} + +begin + explicit_waitforcert = false + 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" + options[:disable] = true + when "--serve" + if Puppet::Network::Handler.handler(arg) + options[:serve][arg.to_sym] = {} + else + raise "Could not find handler for %s" % arg + end + when "--enable" + options[:enable] = true + when "--test" + # Enable all of the most common test options. + Puppet.config.handlearg("--ignorecache") + Puppet.config.handlearg("--no-usecacheonfailure") + Puppet.config.handlearg("--no-splay") + options[:onetime] = true + options[:waitforcert] = 0 + unless Puppet::Util::Log.level == :debug + Puppet::Util::Log.level = :info + end + Puppet::Util::Log.newdestination(:console) + when "--centrallogging" + options[:centrallogs] = true + when "--help" + if Puppet.features.usage? + RDoc::usage && exit + else + puts "No help available unless you have RDoc::usage installed" + exit + end + when "--version" + puts "%s" % Puppet.version + exit + when "--verbose" + Puppet::Util::Log.level = :info + Puppet::Util::Log.newdestination(:console) + when "--debug" + Puppet::Util::Log.level = :debug + Puppet::Util::Log.newdestination(:console) + when "--fqdn" + options[:fqdn] = arg + when "--no-client" + options[:client] = false + when "--onetime" + options[:onetime] = true + options[:waitforcert] = 0 unless explicit_waitforcert + when "--port" + args[:Port] = arg + when "--logdest" + begin + Puppet::Util::Log.newdestination(arg) + options[:setdest] = true + rescue => detail + $stderr.puts detail.to_s + end + when "--waitforcert" + options[:waitforcert] = arg.to_i + explicit_waitforcert = true + else + Puppet.config.handlearg(opt, arg) + end + } +rescue GetoptLong::InvalidOption => detail + $stderr.puts detail + $stderr.puts "Try '#{$0} --help'" + exit(1) +end + +# Now parse the config +Puppet.parse_config + +Puppet.genconfig +Puppet.genmanifest + +# Default to daemonizing, but if verbose or debug is specified, +# default to staying in the foreground. +unless options.include?(:daemonize) + if Puppet::Util::Log.level == :debug or Puppet::Util::Log.level == :info + options[:daemonize] = false + else + options[:daemonize] = true + end +end + +unless options[:setdest] + Puppet::Util::Log.newdestination(:syslog) +end + +args[:Server] = Puppet[:server] +if options[:fqdn] + args[:FQDN] = options[:fqdn] +end + +if options[:centrallogs] + logdest = args[:Server] + + if args.include?(:Port) + logdest += ":" + args[:Port] + end + Puppet::Util::Log.newdestination(logdest) +end + +# We need tomake the client either way, we just don't start it +# if --no-client is set. +client = Puppet::Network::Client.master.new(args) +if options[:enable] + client.enable +elsif options[:disable] + client.disable +end + +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.read_cert + # If we don't already have the certificate, then create a client to + # request one. Use the special ca stuff, don't use the normal server and port. + caclient = Puppet::Network::Client.ca.new() + if options[:waitforcert] > 0 + begin + while ! caclient.request_cert do + Puppet.notice "Did not receive certificate" + sleep options[:waitforcert] + end + rescue => detail + Puppet.err "Could not request certificate: %s" % detail.to_s + exit(23) + end + else + unless caclient.request_cert + Puppet.notice "No certificates; exiting" + exit(1) + end + end + + # Now read the new cert in. + if client.read_cert + Puppet.notice "Got signed certificate" + else + Puppet.err "Could not read certificates after retrieving them" + exit(34) + end +end + +objects = [] + +# This has to go after the certs are dealt with. +if Puppet[:listen] and ! options[:onetime] + unless FileTest.exists?(Puppet[:authconfig]) + Puppet.err "Will not start without authorization file %s" % + Puppet[:authconfig] + exit(14) + end + + # FIXME: we should really figure out how to distribute the CRL + # to clients. In the meantime, we just disable CRL checking if + # the CRL file doesn't exist + unless File::exist?(Puppet[:cacrl]) + Puppet[:cacrl] = 'none' + end + + handlers = nil + + if options[:serve].empty? + handlers = {:Runner => {}} + else + handlers = options[:serve] + end + + handlers.each do |name, hash| + Puppet.info "Starting handler for %s" % name + end + + args[:Handlers] = handlers + args[:Port] = Puppet[:puppetport] + + require 'puppet/network/server/webrick' + + begin + server = Puppet::Network::Server::WEBrick.new(args) + rescue => detail + $stderr.puts detail + puts detail.backtrace + exit(1) + end + + objects << server +elsif options[:onetime] and Puppet[:listen] + Puppet.notice "Ignoring --listen on onetime run" +end + +if options[:client] + objects << client +end + +# Set traps for INT and TERM +Puppet.settraps + +# If --onetime is specified, we don't run 'start', which means we don't +# create a pidfile. +if options[:onetime] + unless options[:client] + $stderr.puts "onetime is specified but there is no client" + exit(43) + end + + # Add the service, so the traps work correctly. + Puppet.newservice(client) + + begin + client.run + rescue => detail + if Puppet[:trace] + puts detail.backtrace + end + Puppet.err detail.to_s + end + exit(0) +else + if server + Puppet.newservice(server) + end + + if options[:client] + Puppet.notice "Starting Puppet client version %s" % [Puppet.version] + Puppet.newservice(client) + end + + Puppet.settraps + + Puppet.start +end + +# $Id$ diff --git a/sbin/puppetmasterd b/sbin/puppetmasterd new file mode 100755 index 000000000..f290d6f1f --- /dev/null +++ b/sbin/puppetmasterd @@ -0,0 +1,302 @@ +#!/usr/bin/env ruby + +# +# = Synopsis +# +# The central puppet server. Functions as a certificate authority by default. +# +# = Usage +# +# puppetmasterd [-D|--daemonize] [-d|--debug] [-h|--help] +# [-l|--logdest |console|syslog] [--nobucket] [--nonodes] +# [-v|--verbose] [-V|--version] +# +# = Description +# +# This is the puppet central daemon. +# +# = Options +# +# Note that any configuration parameter that's valid in the configuration file +# is also a valid long argument. For example, 'ssldir' is a valid configuration +# parameter, so you can specify '--ssldir ' as an argument. +# +# See the configuration file documentation at +# http://reductivelabs.com/projects/puppet/reference/configref.html for +# the full list of acceptable parameters. A commented list of all +# configuration options can also be generated by running puppetmasterdd with +# '--genconfig'. +# +# daemonize:: +# Send the process into the background. This is the default unless +# +verbose+ or +debug+ is enabled. +# +# debug:: +# Enable full debugging. Causes the daemon not to go into the background. +# +# help:: +# Print this help message. +# +# logdest:: +# Where to send messages. Choose between syslog, the console, and a log file. +# Defaults to sending messages to syslog, or the console +# if debugging or verbosity is enabled. +# +# nobucket:: +# Do not function as a file bucket. +# +# nonodes:: +# Do not use individual node designations; each node will receive the result +# of evaluating the entire configuration. +# +# noreports:: +# Do not start the reports server. +# +# verbose:: +# Enable verbosity. Causes the daemon not to go into the background. +# +# version:: +# Print the puppet version number and exit. +# +# = Example +# +# puppetmasterd +# +# = Author +# +# Luke Kanies +# +# = Copyright +# +# Copyright (c) 2005 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 'getoptlong' +require 'puppet' +require 'puppet/sslcertificates' + +options = [ + [ "--daemonize", "-D", GetoptLong::NO_ARGUMENT ], + [ "--debug", "-d", GetoptLong::NO_ARGUMENT ], + [ "--help", "-h", GetoptLong::NO_ARGUMENT ], + [ "--logdest", "-l", GetoptLong::REQUIRED_ARGUMENT ], + [ "--noca", GetoptLong::NO_ARGUMENT ], + [ "--nobucket", GetoptLong::NO_ARGUMENT ], + [ "--noreports", GetoptLong::NO_ARGUMENT ], + [ "--nonodes", GetoptLong::NO_ARGUMENT ], + [ "--verbose", "-v", GetoptLong::NO_ARGUMENT ], + [ "--version", "-V", GetoptLong::NO_ARGUMENT ] +] + +# Add all of the config parameters as valid options. +Puppet.config.addargs(options) + +result = GetoptLong.new(*options) + +master = {} +ca = {} +report = {} +fs = {} +bucket = {} + +options = { + :havereport => true, + :havebucket => true, + :havemaster => true, + :setdest => false, + :verbose => false, + :debug => false +} + +begin + result.each { |opt,arg| + case opt + when "--daemonize" + options[:daemonize] = true + when "--debug" + options[:debug] = true + when "--help" + if Puppet.features.usage? + RDoc::usage && exit + else + puts "No help available unless you have RDoc::usage installed" + exit + end + when "--noreports" + options[:havereport] = false + when "--nomaster" + options[:havemaster] = false + when "--nobucket" + options[:havebucket] = false + when "--nonodes" + master[:UseNodes] = false + when "--logdest" + begin + Puppet::Util::Log.newdestination(arg) + options[:setdest] = true + rescue => detail + if Puppet[:debug] + puts detail.backtrace + end + $stderr.puts detail.to_s + end + when "--version" + puts "%s" % Puppet.version + exit + when "--verbose" + options[:verbose] = true + else + Puppet.config.handlearg(opt, arg) + end + } +rescue GetoptLong::InvalidOption => detail + $stderr.puts "Try '#{$0} --help'" + #$stderr.puts detail + exit(1) +end + +# Handle the logging settings. +if options[:debug] or options[:verbose] + if options[:debug] + Puppet::Util::Log.level = :debug + else + Puppet::Util::Log.level = :info + end + + unless options[:daemonize] + Puppet::Util::Log.newdestination(:console) + options[:setdest] = true + end +end + +unless options[:setdest] + Puppet::Util::Log.newdestination(:syslog) +end + +# Now parse the config +Puppet.parse_config + +Puppet.genconfig +Puppet.genmanifest + +require 'etc' + +# Default to daemonizing, but if verbose or debug is specified, +# default to staying in the foreground. +unless options.include?(:daemonize) + if Puppet::Util::Log.level == :debug or Puppet::Util::Log.level == :info + options[:daemonize] = false + else + options[:daemonize] = true + end +end + +handlers = { + :Status => {}, +} + +if options[:havemaster] + handlers[:Master] = master +end + +if options[:havereport] + handlers[:Report] = report +end + +if Puppet[:ca] + handlers[:CA] = ca +end + +if options[:havebucket] + handlers[:FileBucket] = bucket +end + +if Puppet[:parseonly] + begin + Puppet::Network::Handler.master.new(master) + rescue => detail + if Puppet[:trace] + puts detail.backtrace + end + $stderr.puts detail + exit(32) + end + # we would have already exited if the file weren't syntactically correct + exit(0) +end + +if File.exists?(Puppet[:fileserverconfig]) + fs[:Config] = Puppet[:fileserverconfig] +#else +# Puppet.notice "File server config %s does not exist; skipping file serving" % +# Puppet[:fileserverconfig] +end + +if fs.include?(:Config) + handlers[:FileServer] = fs +end + +begin + case Puppet[:servertype] + when "webrick" + # use the default, um, everything + require 'puppet/network/server/webrick' + server = Puppet::Network::Server::WEBrick.new(:Handlers => handlers) + when "mongrel": + require 'puppet/network/server/mongrel' + handler = Puppet::Network::Server::MongrelHandler.new(handlers) + addr = Puppet[:bindaddress] + if addr == "" + addr = "127.0.0.1" + end + server = Mongrel::HttpServer.new(addr, Puppet[:masterport]) + server.register("/", handler) + else + Puppet.err "Invalid server type %s" % Puppet[:servertype] + exit(45) + end +rescue => detail + if Puppet[:trace] + puts detail.backtrace + end + $stderr.puts detail + exit(1) +end + +if Process.uid == 0 + begin + Puppet::Util.chuser + rescue => detail + if Puppet[:debug] + puts detail.backtrace + end + $stderr.puts "Could not change user to %s: %s" % [Puppet[:user], detail] + exit(39) + end +end + +# Mongrel doesn't shut down like webrick; we really need to write plugins for it. +if Puppet[:servertype] == "webrick" + Puppet.newservice(server) +end +Puppet.settraps + +if options[:daemonize] + server.daemonize +end + +Puppet.notice "Starting Puppet server version %s" % [Puppet.version] +case Puppet[:servertype] +when "webrick" + Puppet.start +when "mongrel": + server.run.join +end + +# $Id$ diff --git a/test/lib/puppettest/exetest.rb b/test/lib/puppettest/exetest.rb index d0a85956a..8d91b88cc 100644 --- a/test/lib/puppettest/exetest.rb +++ b/test/lib/puppettest/exetest.rb @@ -13,10 +13,17 @@ module PuppetTest::ExeTest File.join(basedir, "bin") end + def sbindir + File.join(basedir, "sbin") + end + def setbindir unless ENV["PATH"].split(":").include?(bindir) ENV["PATH"] = [bindir, ENV["PATH"]].join(":") end + unless ENV["PATH"].split(":").include?(sbindir) + ENV["PATH"] = [sbindir, ENV["PATH"]].join(":") + end end def setlibdir -- cgit