diff --git a/bin/puppetmasterd b/bin/puppetmasterd index bae11c831..a00186b68 100755 --- a/bin/puppetmasterd +++ b/bin/puppetmasterd @@ -1,285 +1,284 @@ #!/usr/bin/env ruby # # = Synopsis # # The central puppet server. Functions as a certificate authority by default. # # = Usage # # puppetmasterd [-D|--daemonize|--no-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. # # no-daemonize:: # Do not send the process into the background. # # debug:: # Enable full debugging. # # 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. # # 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 = [ [ "--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.settings.addargs(options) result = GetoptLong.new(*options) master = {} ca = {} report = {} bucket = {} options = { :havereport => true, :havebucket => true, :havemaster => true, :setdest => false, :verbose => false, :debug => false } begin result.each { |opt,arg| case opt # First check to see if the argument is a valid configuration parameter; # if so, set it. NOTE: there is a catch-all at the bottom for defaults.rb 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.settings.handlearg(opt, arg) end } rescue GetoptLong::InvalidOption => detail $stderr.puts "Try '#{$0} --help'" #$stderr.puts detail exit(1) end # Now parse the config Puppet.parse_config # 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 Puppet[:daemonize] Puppet::Util::Log.newdestination(:console) options[:setdest] = true end end unless options[:setdest] Puppet::Util::Log.newdestination(:syslog) end Puppet.genconfig Puppet.genmanifest # A temporary solution, to at least make the master work for now. Puppet::Node::Facts.terminus_class = :yaml require 'etc' handlers = { :Status => {}, :FileServer => {} } 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 webserver = server = nil begin case Puppet[:servertype] when "webrick" # use the default, um, everything require 'puppet/network/http_server/webrick' webserver = server = Puppet::Network::HTTPServer::WEBrick.new(:Handlers => handlers) when "mongrel": require 'puppet/network/http_server/mongrel' server = Puppet::Network::HTTPServer::Mongrel.new(handlers) addr = Puppet[:bindaddress] if addr == "" addr = "127.0.0.1" end webserver = Mongrel::HttpServer.new(addr, Puppet[:masterport]) webserver.register("/", server) 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 Puppet[:daemonize] server.daemonize end Puppet.notice "Starting Puppet server version %s" % [Puppet.version] case Puppet[:servertype] when "webrick" Puppet.start when "mongrel": webserver.run.join end diff --git a/lib/puppet/util/autoload.rb b/lib/puppet/util/autoload.rb index 4b77fa3eb..5f13d936b 100644 --- a/lib/puppet/util/autoload.rb +++ b/lib/puppet/util/autoload.rb @@ -1,151 +1,147 @@ require 'puppet/util/warnings' # Autoload paths, either based on names or all at once. class Puppet::Util::Autoload include Puppet::Util include Puppet::Util::Warnings @autoloaders = {} @loaded = [] class << self attr_reader :autoloaders private :autoloaders end # Send [], []=, and :clear to the @autloaders hash Puppet::Util.classproxy self, :autoloaders, "[]", "[]=" # List all loaded files. def self.list_loaded @loaded.sort { |a,b| a[0] <=> b[0] }.collect do |path, hash| "%s: %s" % [path, hash[:file]] end end # Has a given path been loaded? This is used for testing whether a # changed file should be loaded or just ignored. This is only # used in network/client/master, when downloading plugins, to # see if a given plugin is currently loaded and thus should be # reloaded. def self.loaded?(path) path = path.to_s.sub(/\.rb$/, '') @loaded.include?(path) end # Save the fact that a given path has been loaded. This is so # we can load downloaded plugins if they've already been loaded # into memory. def self.loaded(file) @loaded << file unless @loaded.include?(file) end attr_accessor :object, :path, :objwarn, :wrap def initialize(obj, path, options = {}) @path = path.to_s if @path !~ /^\w/ raise ArgumentError, "Autoload paths cannot be fully qualified" end @object = obj self.class[obj] = self options.each do |opt, value| opt = opt.intern if opt.is_a? String begin self.send(opt.to_s + "=", value) rescue NoMethodError raise ArgumentError, "%s is not a valid option" % opt end end unless defined? @wrap @wrap = true end end # Load a single plugin by name. We use 'load' here so we can reload a # given plugin. def load(name) path = name.to_s + ".rb" eachdir do |dir| file = File.join(dir, path) next unless FileTest.exists?(file) begin Kernel.load file, @wrap name = symbolize(name) loaded name, file return true rescue LoadError => detail # I have no idea what's going on here, but different versions # of ruby are raising different errors on missing files. unless detail.to_s =~ /^no such file/i warn "Could not autoload %s: %s" % [name, detail] if Puppet[:trace] puts detail.backtrace end end return false end end return false end # Mark the named object as loaded. Note that this supports unqualified # queries, while we store the result as a qualified query in the class. def loaded(name, file) self.class.loaded(File.join(@path, name.to_s)) end # Indicate whether the specfied plugin has been loaded. def loaded?(name) self.class.loaded?(File.join(@path, name.to_s)) end # Load all instances that we can. This uses require, rather than load, # so that already-loaded files don't get reloaded unnecessarily. def loadall # Load every instance of everything we can find. eachdir do |dir| Dir.glob("#{dir}/*.rb").each do |file| name = File.basename(file).sub(".rb", '').intern next if loaded?(name) rubypath = File.join(@path, name.to_s) begin Kernel.require rubypath loaded(name, file) rescue => detail if Puppet[:trace] puts detail.backtrace end warn "Could not autoload %s: %s" % [file.inspect, detail] end end end end # Yield each subdir in turn. def eachdir searchpath.each do |dir| subdir = File.join(dir, @path) yield subdir if FileTest.directory?(subdir) end end # The list of directories to search through for loadable plugins. def searchpath # JJM: Search for optional lib directories in each module bundle. module_lib_dirs = Puppet[:modulepath].split(":").collect do |d| Dir.glob("%s/*/{plugins,lib}" % d).select do |f| - if f =~ /lib$/ - # LAK: Deprecated on 2/14/08 - warnonce "Using 'lib' in modules is deprecated; switch %s to 'plugins'" % f - end FileTest.directory?(f) end end.flatten [module_lib_dirs, Puppet[:libdir], $:].flatten end end