diff --git a/CHANGELOG b/CHANGELOG index 23bcc0d96..c3a1e5e24 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,263 +1,267 @@ +0.19.3 + Fixing a bug in server/master.rb that causes the hostname + not to be available in locally-executed manifests. + 0.19.2 Fixing a few smaller bugs, notably in the reports system. Refreshed objects now generate an event, which can result in further refreshes of other objects. 0.19.1 Fixing two critical bugs: User management works again and cron jobs are no longer added to all user accounts. 0.19.0 Added provider support. Added support for %h, %H, and %d expansion in fileserver.conf. Added Certificate Revocation support. Made dynamic loading pervasive -- nearly every aspect of Puppet will now automatically load new instances (e.g., types, providers, and reports). Added support for automatic distribution of facts and plugins (custom types). 0.18.4 Another bug-fix release. The most import bug fixed is that cronjobs again work even with initially empty crontabs. 0.18.3 Mostly a bug-fix release; fixed small bugs in the functionality added in 0.18.2. 0.18.2 Added templating support. Added reporting. Added gem and blastwave packaging support. 0.18.1 Added signal handlers for HUP, so both client and server deal correctly with it. Added signal handler for USR1, which triggers a run on the client. As usual, fixed many bugs. Significant fixes to puppetrun -- it should behave much more correctly now. Added "fail" function which throws a syntax error if it's encountered. Added plugin downloading from the central server to the client. It must be enabled with --pluginsync. Added support for FreeBSD's special "@daily" cron schedules. Correctly handling spaces in file sources. Moved documentation into svn tree. 0.18.0 Added support for a "default" node. When multiple nodes are specified, they must now be comma-separated (this introduces a language incompatibility). Failed dependencies cause dependent objects within the same transaction not to run. Many updates to puppetrun Many bug fixes Function names are no longer reserved words. Links can now replace files. 0.17.2 Added "puppetrun" application and associated runner server and client classes. Fixed cron support so it better supports valid values and environment settings. 0.17.1 Fixing a bug requiring rails on all Debian boxes Fixing a couple of other small bugs 0.17.0 Adding ActiveRecord integration on the server Adding export/collect functionality Fixing many bugs 0.16.5 Fixing a critical bug in importing classes from other files Fixing nodename handling to actually allow dashes 0.16.4 Fixing a critical bug in puppetd when acquiring a certificate for the first time 0.16.3 Some significant bug fixes Modified puppetd so that it can now function as an agent independent of a puppetmasterd process, e.g., using the PuppetShow web application. 0.16.2 Modified some of the AST classes so that class names, definition names, and node names are all set within the code being evaluated, so 'tagged(name)' returns true while evaluating 'name', for instance. Added '--clean' argument to puppetca to remove all traces of a given client. 0.16.1 Added 'tagged' and 'defined' functions. Moved all functions to a general framework that makes it very easy to add new functions. 0.16.0 Added 'tag' keyword/function. Added FreeBSD Ports support Added 'pelement' server for sending or receiving Puppet objects, although none of the executables use it yet. 0.15.3 Fixed many bugs in :exec, including adding support for arrays of checks Added autoloading for types and service variants (e.g., you can now just create a new type in the appropriate location and use it in Puppet, without modifying the core Puppet libs). 0.15.2 Added darwinport, Apple .pkg, and freebsd package types Added 'mount type Host facts are now set at the top scope (Bug #103) Added -e (inline exection) flag to 'puppet' executable Many small bug fixes 0.15.1 Fixed 'yum' installs so that they successfully upgrade packages. Fixed puppetmasterd.conf file so group settings take. 0.15.0 Upped the minor release because the File server is incompatible with 0.14, because it now handles links. The 'symlink' type is deprecated (but still present), in favor of using files with the 'target' parameter. Unset variables no longer throw an error, they just return an empty string You can now specify tags to restrict which objects run during a given run. You can also specify to skip running against the cached copy when there's a failure, which is useful for testing new configurations. RPMs and Sun packages can now install, as long as they specify a package location, and they'll automatically upgrade if you point them to a new file with an upgrade. Multiple bug fixes. 0.14.1 Fixed a couple of small logging bugs Fixed a bug with handling group ownership of links 0.14.0 Added some ability to selectively manage symlinks when doing file management Many bug fixes Variables can now be used as the test values in case statements and selectors Bumping a minor release number because 0.13.4 introduced a protocol incompatibility and should have had a minor rev bump 0.13.6 Many, many small bug fixes FreeBSD user/group support has been added The configuration system has been rewritten so that daemons can now generate and repair the files and directories they need. (Fixed bug #68.) Fixed the element override issues; now only subclasses can override values. 0.13.5 Fixed packages so types can be specified Added 'enable' state to services, although it does not work everywhere yet 0.13.4 A few important bug fixes, mostly in the parser. 0.13.3 Changed transactions to be one-stage instead of two Changed all types to use self[:name] instead of self.name, to support the symbolic naming implemented in 0.13.1 0.13.2 Changed package[answerfile] to package[adminfile], and added package[responsefile] Fixed a bunch of internal functions to behave more consistently and usefully 0.13.1 Fixed RPM spec files to create puppet user and group (lutter) Fixed crontab reading and writing (luke) Added symbolic naming in the language (luke) 0.13.0 Added support for configuration files. Even more bug fixes, including the infamous 'frozen object' bug, which was a problem with 'waitforcert'. David Lutterkort got RPM into good shape. 0.12.0 Added Scheduling, and many bug fixes, of course. 0.11.2 Fixed bugs related to specifying arrays of requirements Fixed a key bug in retrieving checksums Fixed lots of usability bugs Added 'fail' methods that automatically add file and line info when possible, and converted many errors to use that method 0.11.1 Fixed bug with recursive copying with 'ignore' set. Added OpenBSD package support. 0.11.0 Added 'ensure' state to many elements. Modified puppetdoc to correctly handle indentation and such. Significantly rewrote much of the builtin documentation to take advantage of the new features in puppetdoc, including many examples. 0.10.2 Added SMF support Added autorequire functionality, with specific support for exec and file Exec elements autorequire any mentioned files, including the scripts, along with their CWDs. Files autorequire any parent directories. Added 'alias' metaparam. Fixed dependencies so they don't depend on file order. 0.10.1 Added Solaris package support and changed puppetmasterd to run as a non-root user. 0.10.0 Significant refactoring of how types, states, and parameters work, including breaking out parameters into a separate class. This refactoring did not introduce much new functionality, but made extension of Puppet significantly easier Also, fixed the bug with 'waitforcert' in puppetd. 0.9.4 Small fix to wrap the StatusServer class in the checks for required classes. 0.9.3 Fixed some significant bugs in cron job management. 0.9.2 Second Public Beta 0.9.0 First Public Beta diff --git a/conf/redhat/puppet.spec b/conf/redhat/puppet.spec index 67a2d2b4c..4c332b571 100644 --- a/conf/redhat/puppet.spec +++ b/conf/redhat/puppet.spec @@ -1,222 +1,222 @@ %{!?ruby_sitelibdir: %define ruby_sitelibdir %(ruby -rrbconfig -e 'puts Config::CONFIG["sitelibdir"]')} %define pbuild %{_builddir}/%{name}-%{version} %define confdir conf/redhat Summary: A network tool for managing many disparate systems Name: puppet -Version: 0.19.2 +Version: 0.19.3 Release: 1%{?dist} License: GPL Group: System Environment/Base URL: http://reductivelabs.com/projects/puppet/ Source: http://reductivelabs.com/downloads/puppet/%{name}-%{version}.tgz Requires: ruby >= 1.8.1 Requires: ruby(abi) = 1.8 Requires: facter >= 1.1.4 BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) BuildArchitectures: noarch BuildRequires: ruby >= 1.8.1 %description Puppet lets you centrally manage every important aspect of your system using a cross-platform specification language that manages all the separate elements normally aggregated in different files, like users, cron jobs, and hosts, along with obviously discrete elements like packages, services, and files. %package server Group: System Environment/Base Summary: Server for the puppet system management tool Requires: puppet = %{version}-%{release} %description server Provides the central puppet server daemon which provides manifests to clients. The server can also function as a certificate authority and file server. %prep %setup -q %build for f in bin/* ; do sed -i -e '1c#!/usr/bin/ruby' $f done %install %{__rm} -rf %{buildroot} %{__install} -d -m0755 %{buildroot}%{_sbindir} %{__install} -d -m0755 %{buildroot}%{_bindir} %{__install} -d -m0755 %{buildroot}%{ruby_sitelibdir} %{__install} -d -m0755 %{buildroot}%{_sysconfdir}/puppet/manifests %{__install} -d -m0755 %{buildroot}%{_docdir}/%{name}-%{version} %{__install} -d -m0755 %{buildroot}%{_localstatedir}/lib/puppet %{__install} -d -m0755 %{buildroot}%{_localstatedir}/run/puppet %{__install} -d -m0755 %{buildroot}%{_localstatedir}/log/puppet %{__install} -Dp -m0755 %{pbuild}/bin/* %{buildroot}%{_sbindir} %{__mv} %{buildroot}%{_sbindir}/puppet %{buildroot}%{_bindir}/puppet %{__mv} %{buildroot}%{_sbindir}/puppetrun %{buildroot}%{_bindir}/puppetrun %{__install} -Dp -m0644 %{pbuild}/lib/puppet.rb %{buildroot}%{ruby_sitelibdir}/puppet.rb %{__cp} -a %{pbuild}/lib/puppet %{buildroot}%{ruby_sitelibdir} find %{buildroot}%{ruby_sitelibdir} -type f -perm +ugo+x -print0 | xargs -0 -r %{__chmod} a-x %{__install} -Dp -m0644 %{confdir}/client.sysconfig %{buildroot}%{_sysconfdir}/sysconfig/puppet %{__install} -Dp -m0755 %{confdir}/client.init %{buildroot}%{_initrddir}/puppet %{__install} -Dp -m0644 %{confdir}/server.sysconfig %{buildroot}%{_sysconfdir}/sysconfig/puppetmaster %{__install} -Dp -m0755 %{confdir}/server.init %{buildroot}%{_initrddir}/puppetmaster %{__install} -Dp -m0644 %{confdir}/fileserver.conf %{buildroot}%{_sysconfdir}/puppet/fileserver.conf %{__install} -Dp -m0644 %{confdir}/puppetd.conf %{buildroot}%{_sysconfdir}/puppet/puppetd.conf %{__ln_s} puppetd.conf %{buildroot}%{_sysconfdir}/puppet/puppetmasterd.conf %{__ln_s} puppetd.conf %{buildroot}%{_sysconfdir}/puppet/puppetca.conf %{__install} -Dp -m0644 %{confdir}/logrotate %{buildroot}%{_sysconfdir}/logrotate.d/puppet %files %defattr(-, root, root, 0755) %{_bindir}/puppet %{_sbindir}/puppetd %{ruby_sitelibdir}/* %{_initrddir}/puppet %config(noreplace) %{_sysconfdir}/sysconfig/puppet %config(noreplace) %{_sysconfdir}/puppet/puppetd.conf %doc CHANGELOG COPYING LICENSE README TODO examples %exclude %{_sbindir}/puppetdoc %config(noreplace) %{_sysconfdir}/logrotate.d/puppet # These need to be owned by puppet so the server can # write to them %attr(-, puppet, puppet) %{_localstatedir}/run/puppet %attr(-, puppet, puppet) %{_localstatedir}/log/puppet %attr(-, puppet, puppet) %{_localstatedir}/lib/puppet %files server %defattr(-, root, root, 0755) %{_sbindir}/puppetmasterd %{_bindir}/puppetrun %{_initrddir}/puppetmaster %config(noreplace) %{_sysconfdir}/puppet/* %config(noreplace) %{_sysconfdir}/sysconfig/puppetmaster %{_sbindir}/puppetca %pre /usr/sbin/groupadd -r puppet 2>/dev/null || : /usr/sbin/useradd -g puppet -c "Puppet" \ -s /sbin/nologin -r -d /var/puppet puppet 2> /dev/null || : %post /sbin/chkconfig --add puppet exit 0 %post server /sbin/chkconfig --add puppetmaster %preun if [ "$1" = 0 ] ; then /sbin/service puppet stop > /dev/null 2>&1 /sbin/chkconfig --del puppet fi %preun server if [ "$1" = 0 ] ; then /sbin/service puppetmaster stop > /dev/null 2>&1 /sbin/chkconfig --del puppetmaster fi %postun server if [ "$1" -ge 1 ]; then /sbin/service puppetmaster condrestart > /dev/null 2>&1 fi %clean %{__rm} -rf %{buildroot} %changelog * Thu Sep 7 2006 David Lutterkort - 0.19.0-1 - New version * Tue Aug 1 2006 David Lutterkort - 0.18.4-2 - Use /usr/bin/ruby directly instead of /usr/bin/env ruby in executables. Otherwise, initscripts break since pidof can't find the right process * Tue Aug 1 2006 David Lutterkort - 0.18.4-1 - New version * Fri Jul 14 2006 David Lutterkort - 0.18.3-1 - New version * Wed Jul 5 2006 David Lutterkort - 0.18.2-1 - New version * Wed Jun 28 2006 David Lutterkort - 0.18.1-1 - Removed lsb-config.patch and yumrepo.patch since they are upstream now * Mon Jun 19 2006 David Lutterkort - 0.18.0-1 - Patch config for LSB compliance (lsb-config.patch) - Changed config moves /var/puppet to /var/lib/puppet, /etc/puppet/ssl to /var/lib/puppet, /etc/puppet/clases.txt to /var/lib/puppet/classes.txt, /etc/puppet/localconfig.yaml to /var/lib/puppet/localconfig.yaml * Fri May 19 2006 David Lutterkort - 0.17.2-1 - Added /usr/bin/puppetrun to server subpackage - Backported patch for yumrepo type (yumrepo.patch) * Wed May 3 2006 David Lutterkort - 0.16.4-1 - Rebuilt * Fri Apr 21 2006 David Lutterkort - 0.16.0-1 - Fix default file permissions in server subpackage - Run puppetmaster as user puppet - rebuilt for 0.16.0 * Mon Apr 17 2006 David Lutterkort - 0.15.3-2 - Don't create empty log files in post-install scriptlet * Fri Apr 7 2006 David Lutterkort - 0.15.3-1 - Rebuilt for new version * Wed Mar 22 2006 David Lutterkort - 0.15.1-1 - Patch0: Run puppetmaster as root; running as puppet is not ready for primetime * Mon Mar 13 2006 David Lutterkort - 0.15.0-1 - Commented out noarch; requires fix for bz184199 * Mon Mar 6 2006 David Lutterkort - 0.14.0-1 - Added BuildRequires for ruby * Wed Mar 1 2006 David Lutterkort - 0.13.5-1 - Removed use of fedora-usermgmt. It is not required for Fedora Extras and makes it unnecessarily hard to use this rpm outside of Fedora. Just allocate the puppet uid/gid dynamically * Sun Feb 19 2006 David Lutterkort - 0.13.0-4 - Use fedora-usermgmt to create puppet user/group. Use uid/gid 24. Fixed problem with listing fileserver.conf and puppetmaster.conf twice * Wed Feb 8 2006 David Lutterkort - 0.13.0-3 - Fix puppetd.conf * Wed Feb 8 2006 David Lutterkort - 0.13.0-2 - Changes to run puppetmaster as user puppet * Mon Feb 6 2006 David Lutterkort - 0.13.0-1 - Don't mark initscripts as config files * Mon Feb 6 2006 David Lutterkort - 0.12.0-2 - Fix BuildRoot. Add dist to release * Tue Jan 17 2006 David Lutterkort - 0.11.0-1 - Rebuild * Thu Jan 12 2006 David Lutterkort - 0.10.2-1 - Updated for 0.10.2 Fixed minor kink in how Source is given * Wed Jan 11 2006 David Lutterkort - 0.10.1-3 - Added basic fileserver.conf * Wed Jan 11 2006 David Lutterkort - 0.10.1-1 - Updated. Moved installation of library files to sitelibdir. Pulled initscripts into separate files. Folded tools rpm into server * Thu Nov 24 2005 Duane Griffin - Added init scripts for the client * Wed Nov 23 2005 Duane Griffin - First packaging diff --git a/conf/solaris/pkginfo b/conf/solaris/pkginfo index cd0e676be..e4e2f1153 100644 --- a/conf/solaris/pkginfo +++ b/conf/solaris/pkginfo @@ -1,7 +1,7 @@ PKG=CSWpuppet NAME=puppet - System Automation Framework -VERSION=0.19.2 +VERSION=0.19.3 CATEGORY=application VENDOR=http://reductivelabs.com/projects/puppet HOTLINE=http://reductivelabs.com/cgi-bin/puppet.cgi EMAIL=luke@madstop.com diff --git a/lib/puppet.rb b/lib/puppet.rb index e0d8a8e6c..b4376108c 100644 --- a/lib/puppet.rb +++ b/lib/puppet.rb @@ -1,532 +1,532 @@ # see the bottom of the file for further inclusions require 'singleton' require 'puppet/error' require 'puppet/event-loop' require 'puppet/util' require 'puppet/log' require 'puppet/config' require 'puppet/suidmanager' #------------------------------------------------------------ # the top-level module # # all this really does is dictate how the whole system behaves, through # preferences for things like debugging # # it's also a place to find top-level commands like 'debug' module Puppet - PUPPETVERSION = '0.19.2' + PUPPETVERSION = '0.19.3' def Puppet.version return PUPPETVERSION end class << self # So we can monitor signals and such. include SignalObserver include Puppet::Util # To keep a copy of arguments. Set within Config#addargs, because I'm # lazy. attr_accessor :args end def self.name unless defined? @name @name = $0.gsub(/.+#{File::SEPARATOR}/,'').sub(/\.rb$/, '') end return @name end # the hash that determines how our system behaves @@config = Puppet::Config.new # The services running in this process. @services ||= [] # define helper messages for each of the message levels Puppet::Log.eachlevel { |level| define_method(level,proc { |args| if args.is_a?(Array) args = args.join(" ") end Puppet::Log.create( :level => level, :message => args ) }) module_function level } # I keep wanting to use Puppet.error # XXX this isn't actually working right now alias :error :err # Store a new default value. def self.setdefaults(section, hash) @@config.setdefaults(section, hash) end # If we're running the standalone puppet process as a non-root user, # use basedirs that are in the user's home directory. conf = nil var = nil if self.name == "puppet" and Puppet::SUIDManager.uid != 0 conf = File.expand_path("~/.puppet") var = File.expand_path("~/.puppet/var") else # Else, use system-wide directories. conf = "/etc/puppet" var = "/var/puppet" end self.setdefaults(:puppet, :confdir => [conf, "The main Puppet configuration directory."], :vardir => [var, "Where Puppet stores dynamic and growing data."] ) if self.name == "puppetmasterd" self.setdefaults(:puppetmasterd, :logdir => {:default => "$vardir/log", :mode => 0750, :owner => "$user", :group => "$group", :desc => "The Puppet log directory." } ) else self.setdefaults(:puppet, :logdir => ["$vardir/log", "The Puppet log directory."] ) end self.setdefaults(:puppet, :trace => [false, "Whether to print stack traces on some errors"], :statedir => { :default => "$vardir/state", :mode => 01777, :desc => "The directory where Puppet state is stored. Generally, this directory can be removed without causing harm (although it might result in spurious service restarts)." }, :rundir => { :default => "$vardir/run", :mode => 01777, :desc => "Where Puppet PID files are kept." }, :lockdir => { :default => "$vardir/locks", :mode => 01777, :desc => "Where lock files are kept." }, :statefile => { :default => "$statedir/state.yaml", :mode => 0660, :desc => "Where puppetd and puppetmasterd store state associated with the running configuration. In the case of puppetmasterd, this file reflects the state discovered through interacting with clients." }, :ssldir => { :default => "$confdir/ssl", :mode => 0771, :owner => "root", :desc => "Where SSL certificates are kept." }, :genconfig => [false, "Whether to just print a configuration to stdout and exit. Only makes sense when used interactively. Takes into account arguments specified on the CLI."], :genmanifest => [false, "Whether to just print a manifest to stdout and exit. Only makes sense when used interactively. Takes into account arguments specified on the CLI."], :configprint => ["", "Print the value of a specific configuration parameter. If a parameter is provided for this, then the value is printed and puppet exits. Comma-separate multiple values. For a list of all values, specify 'all'. This feature is only available in Puppet versions higher than 0.18.4."], :color => [true, "Whether to use ANSI colors when logging to the console."], :mkusers => [false, "Whether to create the necessary user and group that puppetd will run as."] ) # Define the config default. self.setdefaults(self.name, :config => ["$confdir/#{self.name}.conf", "The configuration file for #{self.name}."] ) self.setdefaults("puppetmasterd", :user => ["puppet", "The user puppetmasterd should run as."], :group => ["puppet", "The group puppetmasterd should run as."], :manifestdir => ["$confdir/manifests", "Where puppetmasterd looks for its manifests."], :manifest => ["$manifestdir/site.pp", "The entry-point manifest for puppetmasterd."], :masterlog => { :default => "$logdir/puppetmaster.log", :owner => "$user", :group => "$group", :mode => 0660, :desc => "Where puppetmasterd logs. This is generally not used, since syslog is the default log destination." }, :masterhttplog => { :default => "$logdir/masterhttp.log", :owner => "$user", :group => "$group", :mode => 0660, :create => true, :desc => "Where the puppetmasterd web server logs." }, :masterport => [8140, "Which port puppetmasterd listens on."], :parseonly => [false, "Just check the syntax of the manifests."], :node_name => ["cert", "How the puppetmaster determines the client's identity and sets the 'hostname' fact for use in the manifest, in particular for determining which 'node' statement applies to the client. Possible values are 'cert' (use the subject's CN in the client's certificate) and 'facter' (use the hostname that the client reported in its facts)"] ) self.setdefaults("puppetd", :localconfig => { :default => "$confdir/localconfig", :owner => "root", :mode => 0660, :desc => "Where puppetd caches the local configuration. An extension indicating the cache format is added automatically."}, :classfile => { :default => "$confdir/classes.txt", :owner => "root", :mode => 0644, :desc => "The file in which puppetd stores a list of the classes associated with the retrieved configuratiion. Can be loaded in the separate ``puppet`` executable using the ``--loadclasses`` option."}, :puppetdlog => { :default => "$logdir/puppetd.log", :owner => "root", :mode => 0640, :desc => "The log file for puppetd. This is generally not used." }, :httplog => { :default => "$logdir/http.log", :owner => "root", :mode => 0640, :desc => "Where the puppetd web server logs." }, :server => ["puppet", "The server to which server puppetd should connect"], :ignoreschedules => [false, "Boolean; whether puppetd should ignore schedules. This is useful for initial puppetd runs."], :puppetport => [8139, "Which port puppetd listens on."], :noop => [false, "Whether puppetd should be run in noop mode."], :runinterval => [1800, # 30 minutes "How often puppetd applies the client configuration; in seconds"] ) # configuration parameter access and stuff def self.[](param) case param when :debug: if Puppet::Log.level == :debug return true else return false end else return @@config[param] end end # configuration parameter access and stuff def self.[]=(param,value) @@config[param] = value end def self.clear @@config.clear end def self.debug=(value) if value Puppet::Log.level=(:debug) else Puppet::Log.level=(:notice) end end def self.config @@config end def self.genconfig if Puppet[:configprint] != "" val = Puppet[:configprint] if val == "all" hash = {} Puppet.config.each do |name, obj| val = obj.value case val when true, false, "": val = val.inspect end hash[name] = val end hash.sort { |a,b| a[0].to_s <=> b[0].to_s }.each do |name, val| puts "%s = %s" % [name, val] end elsif val =~ /,/ val.split(/\s*,\s*/).sort.each do |v| puts "%s = %s" % [v, Puppet[v]] end else puts Puppet[val] end exit(0) end if Puppet[:genconfig] puts Puppet.config.to_config exit(0) end end def self.genmanifest if Puppet[:genmanifest] puts Puppet.config.to_manifest exit(0) end end # Run all threads to their ends def self.join defined? @threads and @threads.each do |t| t.join end end # Create a new service that we're supposed to run def self.newservice(service) @services ||= [] @services << service end def self.newthread(&block) @threads ||= [] @threads << Thread.new do yield end end def self.newtimer(hash, &block) timer = nil threadlock(:timers) do @timers ||= [] timer = EventLoop::Timer.new(hash) @timers << timer if block_given? observe_signal(timer, :alarm, &block) end end # In case they need it for something else. timer end # Relaunch the executable. def self.restart command = $0 + " " + self.args.join(" ") Puppet.notice "Restarting with '%s'" % command Puppet.shutdown(false) exec(command) end # Trap a couple of the main signals. This should probably be handled # in a way that anyone else can register callbacks for traps, but, eh. def self.settraps [:INT, :TERM].each do |signal| trap(signal) do Puppet.notice "Caught #{signal}; shutting down" Puppet.shutdown end end # Handle restarting. trap(:HUP) do if client = @services.find { |s| s.is_a? Puppet::Client::MasterClient } and client.running? client.restart else Puppet.restart end end # Provide a hook for running clients where appropriate trap(:USR1) do done = 0 Puppet.notice "Caught USR1; triggering client run" @services.find_all { |s| s.is_a? Puppet::Client }.each do |client| if client.respond_to? :running? if client.running? Puppet.info "Ignoring running %s" % client.class else done += 1 begin client.runnow rescue => detail Puppet.err "Could not run client: %s" % detail end end else Puppet.info "Ignoring %s; cannot test whether it is running" % client.class end end unless done > 0 Puppet.notice "No clients were run" end end end # Shutdown our server process, meaning stop all services and all threads. # Optionally, exit. def self.shutdown(leave = true) Puppet.notice "Shutting down" # Unmonitor our timers defined? @timers and @timers.each do |timer| EventLoop.current.ignore_timer timer end # This seems to exit the process, although I can't find where it does # so. Leaving it out doesn't seem to hurt anything. #if EventLoop.current.running? # EventLoop.current.quit #end # Stop our services defined? @services and @services.each do |svc| begin timeout(20) do svc.shutdown end rescue TimeoutError Puppet.err "%s could not shut down within 20 seconds" % svc.class end end # And wait for them all to die, giving a decent amount of time defined? @threads and @threads.each do |thr| begin timeout(20) do thr.join end rescue TimeoutError # Just ignore this, since we can't intelligently provide a warning end end if leave exit(0) end end # Start all of our services and optionally our event loop, which blocks, # waiting for someone, somewhere, to generate events of some kind. def self.start(block = true) # Starting everything in its own thread, fwiw defined? @services and @services.each do |svc| newthread do begin svc.start rescue => detail if Puppet[:debug] puts detail.backtrace end @services.delete svc Puppet.err "Could not start %s: %s" % [svc.class, detail] end end end unless @services.length > 0 Puppet.notice "No remaining services; exiting" exit(1) end # We need to give the services a chance to register their timers before # we try to start monitoring them. sleep 0.5 if defined? @timers and ! @timers.empty? @timers.each do |timer| EventLoop.current.monitor_timer timer end end if block EventLoop.current.run end end # Create the timer that our different objects (uh, mostly the client) # check. def self.timer unless defined? @timer #Puppet.info "Interval is %s" % Puppet[:runinterval] #@timer = EventLoop::Timer.new(:interval => Puppet[:runinterval]) @timer = EventLoop::Timer.new( :interval => Puppet[:runinterval], :tolerance => 1, :start? => true ) EventLoop.current.monitor_timer @timer end @timer end # XXX this should all be done using puppet objects, not using # normal mkdir def self.recmkdir(dir,mode = 0755) if FileTest.exist?(dir) return false else tmp = dir.sub(/^\//,'') path = [File::SEPARATOR] tmp.split(File::SEPARATOR).each { |dir| path.push dir if ! FileTest.exist?(File.join(path)) begin Dir.mkdir(File.join(path), mode) rescue Errno::EACCES => detail Puppet.err detail.to_s return false rescue => detail Puppet.err "Could not create %s: %s" % [path, detail.to_s] return false end elsif FileTest.directory?(File.join(path)) next else FileTest.exist?(File.join(path)) raise Puppet::Error, "Cannot create %s: basedir %s is a file" % [dir, File.join(path)] end } return true end end # Create a new type. Just proxy to the Type class. def self.newtype(name, parent = nil, &block) Puppet::Type.newtype(name, parent, &block) end # Retrieve a type by name. Just proxy to the Type class. def self.type(name) Puppet::Type.type(name) end end require 'puppet/server' require 'puppet/type' require 'puppet/storage' # $Id$