diff --git a/LICENSE b/LICENSE index 57d96f83e..a43a24352 100644 --- a/LICENSE +++ b/LICENSE @@ -1,17 +1,17 @@ -Puppet - Automating Configuration Management. Copyright (C) 2005 Reductive Labs LLC +Puppet - Automating Configuration Management. Copyright (C) 2005 Puppet Labs LLC -Reductive Labs can be contacted at: info@reductivelabs.com +Puppet Labs can be contacted at: info@puppetlabs.com This program and entire repository is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA diff --git a/README b/README index 7b6a3afe8..8b1684497 100644 --- a/README +++ b/README @@ -1,27 +1,27 @@ Documentation (and detailed install instructions) can be found -online at http://reductivelabs.com/trac/puppet/wiki/DocumentationStart . +online at http://puppetlabs.com/trac/puppet/wiki/DocumentationStart . Generally, you need the following things installed: * Ruby >= 1.8.1 (earlier releases might work but probably not) * The Ruby OpenSSL library. For some reason, this often isn't included in the main ruby distributions. You can test for it by running 'ruby -ropenssl -e "puts :yep"'. If that errors out, you're missing the library. If your distribution doesn't come with the necessary library (e.g., on Debian and Ubuntu you need to install libopenssl-ruby), then you'll probably have to compile Ruby yourself, since it's part of the standard library and not available separately. You could probably just compile and install that one library, though. * The Ruby XMLRPC client and server libraries. For some reason, this often isn't included in the main ruby distributions. You can test for it by running 'ruby -rxmlrpc/client -e "puts :yep"'. If that errors out, you're missing the library. * Facter => 1.5.1 - You can get this from < http://reductivelabs.com/projects/facter > + You can get this from < http://puppetlabs.com/projects/facter > $Id$ diff --git a/README.queueing b/README.queueing index 8c4a18029..e8be38a80 100644 --- a/README.queueing +++ b/README.queueing @@ -1,126 +1,126 @@ *PUPPET QUEUEING Puppet Queueing is a feature which is designed to take some load off of the PuppetMaster by transferring the task of updating the database to a separate program which is named puppetqd (Puppet Queue Daemon). Currently this is only supported for "Storeconfigs" which is documented at: -http://reductivelabs.com/trac/puppet/wiki/UsingStoredConfiguration +http://puppetlabs.com/trac/puppet/wiki/UsingStoredConfiguration In the future this feature can be extended to any new puppet data which involves storage in a database. *OPERATION In a nutshell: puppetmasterd -> stomp -> service -> stomp -> puppetqd -> database At the moment the only messaging protocol supported is "stomp". Although others could be implemented, stomp is considered by many as the default queueing mechanism for Ruby and Rails applications. It is distributed as a Ruby gem and is easily installed. (The queueing code inside Puppet has been written so that when other interfaces and protocols are implemented they will be easy to use by changing settings in puppet.conf). The "service" in the diagram above is any queueing service that supports the Stomp API. For details refer to: http://xircles.codehaus.org/projects/stomp Both puppetmasterd and puppetqd subscribe to the same queueing service using the stomp interface. As puppetmasterd posts data to the queue, puppetqd receives it and stores it. The details of how to connect to the service and the name of the queue to use are set in puppet.conf: [main] queue_type = stomp queue_source = stomp://localhost:61613 [puppetmasterd] async_storeconfigs = true Note: since puppetmasterd needs to recover the data being stored at a later time, both puppetmasterd and puppetqd need to work with the same database as defined in the STORECONFIGS setup. *QUEUEING SERVICES As mentioned previously any queueing service that supports the Stomp protocol can be used. Which one you use depends on your needs. We have tested with two of the most popular services - StompServer and ActiveMQ. + StompServer http://rubyforge.org/projects/stompserver/ StompServer is a lightweight queueing service written in Ruby which is suitable for testing or low volume puppet usage. Works well when both puppetmasterd and puppetd are running on the same machine that it's running on but we encountered some problems when using it from multiple machines. Just install the stompserver gem and run 'stompserver'. + Apache ActiveMQ http://activemq.apache.org Considered by many to be the most popular message service in use today, ActiveMQ has hundreds of features for scaling, persistence and so on. Although installation is fairly simple, the configuration can seem quite intimidating, but for our use a one line change to the standard configuration is all that is required and is explained at: http://activemq.apache.org/stomp.html Other customization of the internal workings of ActiveMQ, if any, will depend on your needs and deployment. A quick skimming of the ActiveMQ documentation will give you enough info to decide. Others We have looked at but not tried some other queuing services which are compatible with the Stomp API: + POE Component Message Queue + JBoss Messaging (with 3rd party support for Stomp) *SCALING For StoreConfigs you basically need to have the catalog for a node stored in the database before the next time the node connects and asks for a new catalog. If the puppetd on your nodes is set to check every 30 minutes, then it would seem that there is no problem. However if you have 3000 nodes you have a LOT of catalogs to store and it is possible you will not get a catalog saved in time. Running puppetmaster, your queueing service and puppetqd on the same machine means that they are all competing for the same CPU cycles. Bumping up the power of the server they are running on may be enough to handle even fairly large deployments. However since most queueing services (even StompServer) are designed to deliver messages from a "queue" to whoever asks for the next message you can split things up between machines: puppetmaster1 --\ /-- puppetqd1 -\ puppetmaster2 ----> ActiveMQ ---> puppetqd2 ---> database puppetmaster3 --/ \-- puppetqd33 -/ \- puppetqd4-/ This is, of course a totally contrived example, but it gets the point across. As long as the data gets to the database, it doesn't matter which machines or services it goes through. Although for StoreConfigs absolute reliability is not a requirement as a new catalog will be sent the next time a node connects, some amount of persistence should some process crash may be desirable. Both ActiveMQ and MySQL (and other databases) have these kind of features built in which can be activated as needed. diff --git a/README.rst b/README.rst index 7e34d0d2a..f03621be0 100644 --- a/README.rst +++ b/README.rst @@ -1,38 +1,38 @@ Puppet ====== Puppet, an automated administrative engine for your Linux and Unix systems, performs administrative tasks (such as adding users, installing packages, and updating server configurations) based on a centralized specification. Documentation (and detailed install instructions) can be found online at the `Puppet Wiki`_. Installation ------------ Generally, you need the following things installed: * Ruby >= 1.8.1 (earlier releases might work but probably not) * The Ruby OpenSSL library. For some reason, this often isn't included in the main ruby distributions. You can test for it by running 'ruby -ropenssl -e "puts :yep"'. If that errors out, you're missing the library. If your distribution doesn't come with the necessary library (e.g., on Debian and Ubuntu you need to install libopenssl-ruby), then you'll probably have to compile Ruby yourself, since it's part of the standard library and not available separately. You could probably just compile and install that one library, though. * The Ruby XMLRPC client and server libraries. For some reason, this often isn't included in the main ruby distributions. You can test for it by running 'ruby -rxmlrpc/client -e "puts :yep"'. If that errors out, you're missing the library. * Facter => 1.1.1 You can get this from your package management system or the `Facter site`_ -.. _Puppet Wiki: http://reductivelabs.com/trac/puppet/wiki/DocumentationStart -.. _Facter site: http://reductivelabs.com/projects/facter +.. _Puppet Wiki: http://puppetlabs.com/trac/puppet/wiki/DocumentationStart +.. _Facter site: http://puppetlabs.com/projects/facter diff --git a/bin/filebucket b/bin/filebucket index 1c5daa4e3..2aa02ff2d 100755 --- a/bin/filebucket +++ b/bin/filebucket @@ -1,101 +1,101 @@ #!/usr/bin/env ruby # # = Synopsis # # A stand-alone Puppet filebucket client. # # = Usage # # filebucket [-h|--help] [-V|--version] [-d|--debug] [-v|--verbose] # [-l|--local] [-r|--remote] # [-s|--server ] [-b|--bucket ] ... # # = Description # # This is a stand-alone filebucket client for sending files to a local # or central filebucket. # # = Usage # # This client can operate in three modes, with only one mode per call: # # backup:: # Send one or more files to the specified file bucket. Each sent file # is printed with its resulting md5 sum. # # get:: # Return the text associated with an md5 sum. The text is printed to # stdout, and only one file can be retrieved at a time. # # restore:: # Given a file path and an md5 sum, store the content associated with the # sum into the specified file path. You can specify an entirely new path # to this argument; you are not restricted to restoring the content to its # original location. # # Note that +filebucket+ defaults to using a network-based filebucket available on # the server named +puppet+. To use this, you'll have to be running as a user # with valid Puppet certificates. Alternatively, you can use your local file bucket # by specifying +--local+. # # = Example # # $ filebucket backup /etc/passwd # /etc/passwd: 429b225650b912a2ee067b0a4cf1e949 # $ filebucket restore /tmp/passwd 429b225650b912a2ee067b0a4cf1e949 # $ # # = 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/trac/puppet/wiki/ConfigurationReference for +# http://puppetlabs.com/trac/puppet/wiki/ConfigurationReference for # the full list of acceptable parameters. A commented list of all # configuration options can also be generated by running puppet with # '--genconfig'. # # debug:: # Enable full debugging. # # help:: # Print this help message # # local:: # Use the local filebucket. This will use the default configuration # information. # # remote:: # Use a remote filebucket. This will use the default configuration # information. # # server:: # The server to send the file to, instead of locally. # # verbose:: # Print extra information. # # version:: # Print version information. # # = Example # # filebucket -b /tmp/filebucket /my/file # # = Author # # Luke Kanies # # = Copyright # -# Copyright (c) 2005 Reductive Labs, LLC +# Copyright (c) 2005 Puppet Labs, LLC # Licensed under the GNU Public License require 'puppet/application' require 'puppet/application/filebucket' # launch the filebucket Puppet::Application[:filebucket].run diff --git a/bin/pi b/bin/pi index c1a59631e..4f29a2905 100755 --- a/bin/pi +++ b/bin/pi @@ -1,50 +1,50 @@ #!/usr/bin/env ruby # # = Synopsis # # Print help about puppet types on the console. Run with '-h' to get detailed # help. # = Usage # # pi [-h|--help] [-s|--short] [-p|--providers] [-l|--list] [-m|--meta] # # = Description # # Prints details of Puppet types, providers and metaparameters on the console. # # = Options # # help:: # Print this help text # # providers:: # Describe providers in detail for each type # # list:: # List all types # # meta:: # List all metaparameters # # short:: # List only parameters without detail # # = Example # # pi --list # pi file --providers # pi user -s -m # # = Author # # David Lutterkort # # = Copyright # -# Copyright (c) 2005 Reductive Labs, LLC +# Copyright (c) 2005 Puppet Labs, LLC # Licensed under the GNU Public License require 'puppet/application/pi' Puppet::Application[:pi].run diff --git a/bin/puppet b/bin/puppet index 931e3a993..426d647b6 100755 --- a/bin/puppet +++ b/bin/puppet @@ -1,71 +1,71 @@ #!/usr/bin/env ruby # # = Synopsis # # Run a stand-alone +puppet+ manifest. # # = Usage # # puppet [-h|--help] [-V|--version] [-d|--debug] [-v|--verbose] [-e|--execute] # [--detailed-exitcodes] [-l|--logdest ] # # = Description # # This is the standalone puppet execution tool; use it to execute # individual manifests that you write. If you need to execute site-wide # manifests, use +puppetd+ and +puppetmasterd+. # # = 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/trac/puppet/wiki/ConfigurationReference for +# http://puppetlabs.com/trac/puppet/wiki/ConfigurationReference for # the full list of acceptable parameters. A commented list of all # configuration options can also be generated by running puppet with # '--genconfig'. # # debug:: # Enable full debugging. # # detailed-exitcodes:: # Provide transaction information via exit codes. If this is enabled, an exit # code of '2' means there were changes, and an exit code of '4' means that there # were failures during the transaction. # # help:: # Print this help message # # loadclasses:: # Load any stored classes. +puppetd+ caches configured classes (usually at # /etc/puppet/classes.txt), and setting this option causes all of those classes # to be set in your +puppet+ manifest. # # logdest:: # Where to send messages. Choose between syslog, the console, and a log file. # Defaults to sending messages to the console. # # execute:: # Execute a specific piece of Puppet code # # verbose:: # Print extra information. # # = Example # # puppet -l /tmp/manifest.log manifest.pp # # = Author # # Luke Kanies # # = Copyright # -# Copyright (c) 2005 Reductive Labs, LLC +# Copyright (c) 2005 Puppet Labs, LLC # Licensed under the GNU Public License require 'puppet/application/puppet' Puppet::Application[:puppet].run diff --git a/bin/puppetdoc b/bin/puppetdoc index a69d169c9..a20417e64 100755 --- a/bin/puppetdoc +++ b/bin/puppetdoc @@ -1,65 +1,65 @@ #!/usr/bin/env ruby # # = Synopsis # -# Generate a reference for all Puppet types. Largely meant for internal Reductive +# Generate a reference for all Puppet types. Largely meant for internal Puppet # Labs use. # # = Usage # # puppetdoc [-a|--all] [-h|--help] [-o|--outputdir ] [-m|--mode ] # [-r|--reference <[type]|configuration|..>] [manifest-file] # # = Description # # If mode is not 'rdoc', then this command generates a restructured-text document describing all installed # Puppet types or all allowable arguments to puppet executables. It is largely # meant for internal use and is used to generate the reference document -# available on the Reductive Labs web site. +# available on the Puppet Labs web site. # # In 'rdoc' mode, this command generates an html RDoc hierarchy describing the manifests that # are in 'manifestdir' and 'modulepath' configuration directives. # The generated documentation directory is doc by default but can be changed with the 'outputdir' option. # # If the command is started with 'manifest-file' command-line arguments, puppetdoc generate a single # manifest documentation that is output on stdout. # # = Options # # all:: # Output the docs for all of the reference types. In 'rdoc' modes, this also outputs documentation for all resources # # help:: # Print this help message # # outputdir:: # Specifies the directory where to output the rdoc documentation in 'rdoc' mode. # # mode:: -# Determine the output mode. Valid modes are 'text', 'trac', 'pdf', 'markdown' and 'rdoc'. The 'pdf' and 'markdown' modes create PDF or Markdown formatted files in the /tmp directory. Note that 'trac' mode only works on Reductive Labs servers. The default mode is 'text'. In 'rdoc' mode you must provide 'manifests-path' +# Determine the output mode. Valid modes are 'text', 'trac', 'pdf', 'markdown' and 'rdoc'. The 'pdf' and 'markdown' modes create PDF or Markdown formatted files in the /tmp directory. Note that 'trac' mode only works on Puppet Labs servers. The default mode is 'text'. In 'rdoc' mode you must provide 'manifests-path' # # reference:: # Build a particular reference. Get a list of references by running +puppetdoc --list+. # # = Example # # $ puppetdoc -r type > /tmp/type_reference.rst # or # $ puppetdoc --outputdir /tmp/rdoc --mode rdoc /path/to/manifests # or # $ puppetdoc /etc/puppet/manifests/site.pp # or # $ puppetdoc -m markdown -r configuration # # = Author # # Luke Kanies # # = Copyright # -# Copyright (c) 2005-2007 Reductive Labs, LLC +# Copyright (c) 2005-2007 Puppet Labs, LLC # Licensed under the GNU Public License require 'puppet/application/puppetdoc' Puppet::Application[:puppetdoc].run diff --git a/bin/ralsh b/bin/ralsh index ca20c4c2f..409d3dc69 100755 --- a/bin/ralsh +++ b/bin/ralsh @@ -1,89 +1,89 @@ #!/usr/bin/env ruby # vim: softtabstop=4 shiftwidth=4 expandtab # # = Synopsis # # Use the Puppet RAL to directly interact with the system. # # = Usage # # ralsh [-h|--help] [-d|--debug] [-v|--verbose] [-e|--edit] [-H|--host ] # [-p|--param ] [-t|--types] type # # = Description # # This command provides simple facilities for converting current system state # into Puppet code, along with some ability to use Puppet to affect the current # state. # # By default, you must at least provide a type to list, which case ralsh # will tell you everything it knows about all instances of that type. You can # optionally specify an instance name, and ralsh will only describe that single # instance. # # You can also add +--edit+ as an argument, and ralsh will write its output # to a file, open that file in an editor, and then apply the file as a Puppet # transaction. You can easily use this to use Puppet to make simple changes to # a system. # # = 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/trac/puppet/wiki/ConfigurationReference for +# http://puppetlabs.com/trac/puppet/wiki/ConfigurationReference for # the full list of acceptable parameters. A commented list of all # configuration options can also be generated by running puppet with # '--genconfig'. # # debug:: # Enable full debugging. # # edit: # Write the results of the query to a file, open the file in an editor, # and read the file back in as an executable Puppet manifest. # # host: # When specified, connect to the resource server on the named host # and retrieve the list of resouces of the type specified. # # help: # Print this help message. # # param: # Add more parameters to be outputted from queries. # # types: # List all available types. # # verbose:: # Print extra information. # # = Example # # This example uses ``ralsh`` to return Puppet configuration for the user ``luke``:: # # $ ralsh user luke # user { 'luke': # home => '/home/luke', # uid => '100', # ensure => 'present', # comment => 'Luke Kanies,,,', # gid => '1000', # shell => '/bin/bash', # groups => ['sysadmin','audio','video','puppet'] # } # # = Author # # Luke Kanies # # = Copyright # -# Copyright (c) 2005-2007 Reductive Labs, LLC +# Copyright (c) 2005-2007 Puppet Labs, LLC # Licensed under the GNU Public License require 'puppet/application/ralsh' Puppet::Application[:ralsh].run diff --git a/conf/epm.list b/conf/epm.list index d7d7b40e5..efb740774 100644 --- a/conf/epm.list +++ b/conf/epm.list @@ -1,8 +1,8 @@ %product Puppet -%copyright 2004-2005 by Reductive Labs, All Rights Reserved -%vendor Reductive Labs +%copyright 2004-2005 by Puppet Labs, All Rights Reserved +%vendor Puppet Labs %license COPYING %readme README %description System Automation and Configuration Management Software %version 0.15.0 %requires facter 1.1 diff --git a/conf/osx/PackageInfo.plist b/conf/osx/PackageInfo.plist index 08930e1ab..947aabb4c 100644 --- a/conf/osx/PackageInfo.plist +++ b/conf/osx/PackageInfo.plist @@ -1,36 +1,36 @@ CFBundleIdentifier - com.reductivelabs.puppet + com.puppetlabs.puppet CFBundleShortVersionString {SHORTVERSION} IFMajorVersion {MAJORVERSION} IFMinorVersion {MINORVERSION} IFPkgFlagAllowBackRev IFPkgFlagAuthorizationAction RootAuthorization IFPkgFlagDefaultLocation / IFPkgFlagFollowLinks IFPkgFlagInstallFat IFPkgFlagIsRequired IFPkgFlagOverwritePermissions IFPkgFlagRelocatable IFPkgFlagRestartAction None IFPkgFlagRootVolumeOnly IFPkgFlagUpdateInstalledLanguages diff --git a/conf/redhat/puppet.spec b/conf/redhat/puppet.spec index aaebd5188..3c22e8abe 100644 --- a/conf/redhat/puppet.spec +++ b/conf/redhat/puppet.spec @@ -1,442 +1,442 @@ # Augeas and SELinux requirements may be disabled at build time by passing # --without augeas and/or --without selinux to rpmbuild or mock %{!?ruby_sitelibdir: %define ruby_sitelibdir %(ruby -rrbconfig -e 'puts Config::CONFIG["sitelibdir"]')} %define confdir conf/redhat Name: puppet Version: 0.25.2 Release: 1%{?dist} Summary: A network tool for managing many disparate systems License: GPLv2+ -URL: http://puppet.reductivelabs.com/ -Source0: http://reductivelabs.com/downloads/puppet/%{name}-%{version}.tar.gz +URL: http://puppet.puppetlabs.com/ +Source0: http://puppetlabs.com/downloads/puppet/%{name}-%{version}.tar.gz Patch0: rundir-perms.patch Group: System Environment/Base BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) BuildRequires: facter >= 1.5 BuildRequires: ruby >= 1.8.1 %if 0%{?fedora} || 0%{?rhel} >= 5 BuildArch: noarch Requires: ruby(abi) = 1.8 Requires: ruby-shadow %endif # Pull in ruby selinux bindings where available %if 0%{?fedora} %if 0%{?fedora} >= 12 %{!?_without_selinux:Requires: ruby(selinux)} %else %{!?_without_selinux:Requires: libselinux-ruby} %endif %endif Requires: facter >= 1.5 Requires: ruby >= 1.8.1 %{!?_without_augeas:Requires: ruby-augeas} Requires(pre): shadow-utils Requires(post): chkconfig Requires(preun): chkconfig Requires(preun): initscripts Requires(postun): initscripts %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} Requires(post): chkconfig Requires(preun): chkconfig Requires(preun): initscripts Requires(postun): initscripts %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 %patch0 -p1 %build # Fix some rpmlint complaints for f in mac_dscl.pp mac_dscl_revert.pp \ mac_pkgdmg.pp ; do sed -i -e'1d' examples/$f chmod a-x examples/$f done for f in external/nagios.rb network/http_server/mongrel.rb relationship.rb; do sed -i -e '1d' lib/puppet/$f done chmod +x ext/puppetstoredconfigclean.rb find examples/ -type f -empty | xargs rm find examples/ -type f | xargs chmod a-x # puppet-queue.conf is more of an example, used for stompserver mv conf/puppet-queue.conf examples/etc/puppet/ %install rm -rf %{buildroot} ruby install.rb --destdir=%{buildroot} --quick --no-rdoc install -d -m0755 %{buildroot}%{_sysconfdir}/puppet/manifests install -d -m0755 %{buildroot}%{_localstatedir}/lib/puppet install -d -m0755 %{buildroot}%{_localstatedir}/run/puppet install -d -m0750 %{buildroot}%{_localstatedir}/log/puppet 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}/puppet.conf %{buildroot}%{_sysconfdir}/puppet/puppet.conf install -Dp -m0644 conf/auth.conf %{buildroot}%{_sysconfdir}/puppet/auth.conf install -Dp -m0644 %{confdir}/logrotate %{buildroot}%{_sysconfdir}/logrotate.d/puppet # We need something for these ghosted files, otherwise rpmbuild # will complain loudly. They won't be included in the binary packages touch %{buildroot}%{_sysconfdir}/puppet/puppetmasterd.conf touch %{buildroot}%{_sysconfdir}/puppet/puppetca.conf touch %{buildroot}%{_sysconfdir}/puppet/puppetd.conf # Install the ext/ directory to %{_datadir}/%{name} install -d %{buildroot}%{_datadir}/%{name} cp -a ext/ %{buildroot}%{_datadir}/%{name} # emacs and vim bits are installed elsewhere rm -rf %{buildroot}%{_datadir}/%{name}/ext/{emacs,vim} # Install emacs mode files emacsdir=%{buildroot}%{_datadir}/emacs/site-lisp install -Dp -m0644 ext/emacs/puppet-mode.el $emacsdir/puppet-mode.el install -Dp -m0644 ext/emacs/puppet-mode-init.el \ $emacsdir/site-start.d/puppet-mode-init.el # Install vim syntax files vimdir=%{buildroot}%{_datadir}/vim/vimfiles install -Dp -m0644 ext/vim/ftdetect/puppet.vim $vimdir/ftdetect/puppet.vim install -Dp -m0644 ext/vim/syntax/puppet.vim $vimdir/syntax/puppet.vim %files %defattr(-, root, root, 0755) %doc CHANGELOG COPYING LICENSE README README.queueing examples %{_bindir}/pi %{_bindir}/puppet %{_bindir}/ralsh %{_bindir}/filebucket %{_bindir}/puppetdoc %{_sbindir}/puppetca %{_sbindir}/puppetd %{ruby_sitelibdir}/* %{_initrddir}/puppet %dir %{_sysconfdir}/puppet %config(noreplace) %{_sysconfdir}/sysconfig/puppet %config(noreplace) %{_sysconfdir}/puppet/puppet.conf %config(noreplace) %{_sysconfdir}/puppet/auth.conf %ghost %config(noreplace,missingok) %{_sysconfdir}/puppet/puppetca.conf %ghost %config(noreplace,missingok) %{_sysconfdir}/puppet/puppetd.conf %config(noreplace) %{_sysconfdir}/logrotate.d/puppet # We don't want to require emacs or vim, so we need to own these dirs %{_datadir}/emacs %{_datadir}/vim %{_datadir}/%{name} # 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 %{_mandir}/man8/pi.8.gz %{_mandir}/man8/puppet.8.gz %{_mandir}/man8/puppet.conf.8.gz %{_mandir}/man8/puppetca.8.gz %{_mandir}/man8/puppetd.8.gz %{_mandir}/man8/ralsh.8.gz %{_mandir}/man8/puppetdoc.8.gz %files server %defattr(-, root, root, 0755) %{_sbindir}/puppetmasterd %{_sbindir}/puppetrun %{_sbindir}/puppetqd %{_initrddir}/puppetmaster %config(noreplace) %{_sysconfdir}/puppet/fileserver.conf %dir %{_sysconfdir}/puppet/manifests %config(noreplace) %{_sysconfdir}/sysconfig/puppetmaster %ghost %config(noreplace,missingok) %{_sysconfdir}/puppet/puppetmasterd.conf %{_mandir}/man8/filebucket.8.gz %{_mandir}/man8/puppetmasterd.8.gz %{_mandir}/man8/puppetrun.8.gz %{_mandir}/man8/puppetqd.8.gz # Fixed uid/gid were assigned in bz 472073 (Fedora), 471918 (RHEL-5), # and 471919 (RHEL-4) %pre getent group puppet &>/dev/null || groupadd -r puppet -g 52 &>/dev/null getent passwd puppet &>/dev/null || \ useradd -r -u 52 -g puppet -d %{_localstatedir}/lib/puppet -s /sbin/nologin \ -c "Puppet" puppet &>/dev/null || : # ensure that old setups have the right puppet home dir if [ $1 -gt 1 ] ; then usermod -d %{_localstatedir}/lib/puppet puppet &>/dev/null || : fi %post /sbin/chkconfig --add puppet || : %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 if [ "$1" -ge 1 ]; then /sbin/service puppet condrestart >/dev/null 2>&1 || : fi %postun server if [ "$1" -ge 1 ]; then /sbin/service puppetmaster condrestart > /dev/null 2>&1 || : fi %clean rm -rf %{buildroot} %changelog * Fri Jan 01 2010 Todd Zullinger - 0.25.2-1 - Update to 0.25.2 - Install auth.conf, puppetqd manpage, and queuing examples/docs * Tue Oct 20 2009 Todd Zullinger - 0.25.1-1 - Update to 0.25.1 - Include the pi program and man page (R.I.Pienaar) * Sat Oct 17 2009 Todd Zullinger - 0.25.1-0.2.rc2 - Update to 0.25.1rc2 * Tue Sep 22 2009 Todd Zullinger - 0.25.1-0.1.rc1 - Update to 0.25.1rc1 - Move puppetca to puppet package, it has uses on client systems - Drop redundant %%doc from manpage %%file listings * Fri Sep 04 2009 Todd Zullinger - 0.25.0-1 - Update to 0.25.0 - Fix permissions on /var/log/puppet (#495096) - Install emacs mode and vim syntax files (#491437) - Install ext/ directory in %%{_datadir}/%{name} (/usr/share/puppet) * Mon May 04 2009 Todd Zullinger - 0.25.0-0.1.beta1 - Update to 0.25.0beta1 - Make Augeas and SELinux requirements build time options * Mon Mar 23 2009 Todd Zullinger - 0.24.8-1 - Update to 0.24.8 - Quiet output from %%pre - Use upstream install script - Increase required facter version to >= 1.5 * Tue Dec 16 2008 Todd Zullinger - 0.24.7-4 - Remove redundant useradd from %%pre * Tue Dec 16 2008 Jeroen van Meeuwen - 0.24.7-3 - New upstream version - Set a static uid and gid (#472073, #471918, #471919) - Add a conditional requirement on libselinux-ruby for Fedora >= 9 - Add a dependency on ruby-augeas * Wed Oct 22 2008 Todd Zullinger - 0.24.6-1 - Update to 0.24.6 - Require ruby-shadow on Fedora and RHEL >= 5 - Simplify Fedora/RHEL version checks for ruby(abi) and BuildArch - Require chkconfig and initstripts for preun, post, and postun scripts - Conditionally restart puppet in %%postun - Ensure %%preun, %%post, and %%postun scripts exit cleanly - Create puppet user/group according to Fedora packaging guidelines - Quiet a few rpmlint complaints - Remove useless %%pbuild macro - Make specfile more like the Fedora/EPEL template * Mon Jul 28 2008 David Lutterkort - 0.24.5-1 - Add /usr/bin/puppetdoc * Thu Jul 24 2008 Brenton Leanhardt - New version - man pages now ship with tarball - examples/code moved to root examples dir in upstream tarball * Tue Mar 25 2008 David Lutterkort - 0.24.4-1 - Add man pages (from separate tarball, upstream will fix to include in main tarball) * Mon Mar 24 2008 David Lutterkort - 0.24.3-1 - New version * Wed Mar 5 2008 David Lutterkort - 0.24.2-1 - New version * Sat Dec 22 2007 David Lutterkort - 0.24.1-1 - New version * Mon Dec 17 2007 David Lutterkort - 0.24.0-2 - Use updated upstream tarball that contains yumhelper.py * Fri Dec 14 2007 David Lutterkort - 0.24.0-1 - Fixed license - Munge examples/ to make rpmlint happier * Wed Aug 22 2007 David Lutterkort - 0.23.2-1 - New version * Thu Jul 26 2007 David Lutterkort - 0.23.1-1 - Remove old config files * Wed Jun 20 2007 David Lutterkort - 0.23.0-1 - Install one puppet.conf instead of old config files, keep old configs around to ease update - Use plain shell commands in install instead of macros * Wed May 2 2007 David Lutterkort - 0.22.4-1 - New version * Thu Mar 29 2007 David Lutterkort - 0.22.3-1 - Claim ownership of _sysconfdir/puppet (bz 233908) * Mon Mar 19 2007 David Lutterkort - 0.22.2-1 - Set puppet's homedir to /var/lib/puppet, not /var/puppet - Remove no-lockdir patch, not needed anymore * Mon Feb 12 2007 David Lutterkort - 0.22.1-2 - Fix bogus config parameter in puppetd.conf * Sat Feb 3 2007 David Lutterkort - 0.22.1-1 - New version * Fri Jan 5 2007 David Lutterkort - 0.22.0-1 - New version * Mon Nov 20 2006 David Lutterkort - 0.20.1-2 - Make require ruby(abi) and buildarch: noarch conditional for fedora 5 or later to allow building on older fedora releases * Mon Nov 13 2006 David Lutterkort - 0.20.1-1 - New version * Mon Oct 23 2006 David Lutterkort - 0.20.0-1 - New version * Tue Sep 26 2006 David Lutterkort - 0.19.3-1 - New version * Mon Sep 18 2006 David Lutterkort - 0.19.1-1 - New version * 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 7f7bb9736..d3762ba5d 100644 --- a/conf/solaris/pkginfo +++ b/conf/solaris/pkginfo @@ -1,7 +1,7 @@ PKG=CSWpuppet NAME=puppet - System Automation Framework VERSION=0.23.0 CATEGORY=application -VENDOR=http://reductivelabs.com/projects/puppet -HOTLINE=http://reductivelabs.com/cgi-bin/puppet.cgi +VENDOR=http://puppetlabs.com/projects/puppet +HOTLINE=http://puppetlabs.com/cgi-bin/puppet.cgi EMAIL=luke@madstop.com diff --git a/conf/solaris/smf/puppetd.xml b/conf/solaris/smf/puppetd.xml index 84ee0087d..dc4ac2ec0 100644 --- a/conf/solaris/smf/puppetd.xml +++ b/conf/solaris/smf/puppetd.xml @@ -1,77 +1,77 @@ - + diff --git a/conf/solaris/smf/puppetmasterd.xml b/conf/solaris/smf/puppetmasterd.xml index e7b0113bd..c0a82f3a3 100644 --- a/conf/solaris/smf/puppetmasterd.xml +++ b/conf/solaris/smf/puppetmasterd.xml @@ -1,77 +1,77 @@ - + diff --git a/conf/suse/puppet.spec b/conf/suse/puppet.spec index 15a9b9e5b..9b2f7a34a 100644 --- a/conf/suse/puppet.spec +++ b/conf/suse/puppet.spec @@ -1,225 +1,225 @@ %{!?ruby_sitelibdir: %define ruby_sitelibdir %(ruby -rrbconfig -e 'puts Config::CONFIG["sitelibdir"]')} %define pbuild %{_builddir}/%{name}-%{version} %define suseconfdir conf/suse %define confdir conf/redhat Summary: A network tool for managing many disparate systems Name: puppet Version: 0.25.4 Release: 1%{?dist} License: GPL Group: System Environment/Base -URL: http://reductivelabs.com/projects/puppet/ -Source: http://reductivelabs.com/downloads/puppet/%{name}-%{version}.tar.gz +URL: http://puppetlabs.com/projects/puppet/ +Source: http://puppetlabs.com/downloads/puppet/%{name}-%{version}.tar.gz Patch0: puppet.suse.patch Requires: ruby >= 1.8.2 Requires: facter >= 1.3.7 BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) BuildRequires: ruby >= 1.8.2 %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 %patch0 -p0 %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/* %{pbuild}/sbin/* %{buildroot}%{_sbindir} %{__mv} %{buildroot}%{_sbindir}/puppet %{buildroot}%{_bindir}/puppet %{__mv} %{buildroot}%{_sbindir}/puppetrun %{buildroot}%{_bindir}/puppetrun %{__mv} %{buildroot}%{_sbindir}/pi %{buildroot}%{_bindir}/pi %{__mv} %{buildroot}%{_sbindir}/filebucket %{buildroot}%{_bindir}/filebucket %{__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 %{suseconfdir}/client.init %{buildroot}%{_initrddir}/puppet %{__install} -Dp -m0644 %{confdir}/server.sysconfig %{buildroot}%{_sysconfdir}/sysconfig/puppetmaster %{__install} -Dp -m0755 %{suseconfdir}/server.init %{buildroot}%{_initrddir}/puppetmaster %{__install} -Dp -m0644 %{confdir}/fileserver.conf %{buildroot}%{_sysconfdir}/puppet/fileserver.conf %{__install} -Dp -m0644 %{confdir}/puppet.conf %{buildroot}%{_sysconfdir}/puppet/puppet.conf %{__install} -Dp -m0644 %{confdir}/logrotate %{buildroot}%{_sysconfdir}/logrotate.d/puppet %files %defattr(-, root, root, 0755) %{_bindir}/puppet %{_bindir}/pi %{_bindir}/filebucket %{_sbindir}/ralsh %{_sbindir}/puppetd %{ruby_sitelibdir}/* %{_initrddir}/puppet %config(noreplace) %{_sysconfdir}/sysconfig/puppet %config(noreplace) %{_sysconfdir}/puppet/puppet.conf %doc CHANGELOG COPYING LICENSE README 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 %{_sbindir}/puppetqd %{_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/lib/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 try-restart > /dev/null 2>&1 fi %clean %{__rm} -rf %{buildroot} %changelog * Sat Feb 16 2008 James Turnbull - 0.24.1-1 - Fixed puppet configuation file references to match single puppet.conf file - Update versions for 0.24.1 release * Tue Aug 3 2006 Martin Vuk - 0.18.4-3 - Replaced puppet-bin.patch with %build section from David's spec * Tue Aug 1 2006 Martin Vuk - 0.18.4-2 - Added supprot for enabling services in SuSE * Tue Aug 1 2006 Martin Vuk - 0.18.4-1 - New version and support for SuSE * 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/examples/modules/sample-module/README.txt b/examples/modules/sample-module/README.txt index ee4b8201a..579fe60f9 100644 --- a/examples/modules/sample-module/README.txt +++ b/examples/modules/sample-module/README.txt @@ -1,17 +1,17 @@ Jeff McCune 2007-08-14 This small, sample module demonstrates how to extend the puppet language with a new parser function. See: manifests/init.pp lib/puppet/parser/functions/hostname_to_dn.rb templates/sample.erb Note the consistent naming of files for Puppet::Util::Autoload Reference Documents: -http://reductivelabs.com/trac/puppet/wiki/ModuleOrganisation -http://reductivelabs.com/trac/puppet/wiki/WritingYourOwnFunctions -http://reductivelabs.com/trac/puppet/wiki/FunctionReference +http://puppetlabs.com/trac/puppet/wiki/ModuleOrganisation +http://puppetlabs.com/trac/puppet/wiki/WritingYourOwnFunctions +http://puppetlabs.com/trac/puppet/wiki/FunctionReference diff --git a/examples/modules/sample-module/lib/puppet/parser/functions/hostname_to_dn.rb b/examples/modules/sample-module/lib/puppet/parser/functions/hostname_to_dn.rb index d7ad7d22e..e507462c6 100644 --- a/examples/modules/sample-module/lib/puppet/parser/functions/hostname_to_dn.rb +++ b/examples/modules/sample-module/lib/puppet/parser/functions/hostname_to_dn.rb @@ -1,36 +1,36 @@ # Copyright (C) David Schmitt # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # 1. Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # 2. Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # 3. Neither the name of the Author nor the names of its contributors # may be used to endorse or promote products derived from this software # without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF # SUCH DAMAGE. # Jeff McCune # 2007-08-14 -# See: http://reductivelabs.com/trac/puppet/wiki/WritingYourOwnFunctions +# See: http://puppetlabs.com/trac/puppet/wiki/WritingYourOwnFunctions module Puppet::Parser::Functions newfunction(:hostname_to_dn, :type => :rvalue, :doc => "Given 'foo.bar.com', return 'dc=foo,dc=bar,dc=com'.") do |args| args[0].split(/\./).map do |s| "dc=%s"%[s] end.join(",") end end diff --git a/ext/extlookup.rb b/ext/extlookup.rb index b0978ef12..4793cba7d 100644 --- a/ext/extlookup.rb +++ b/ext/extlookup.rb @@ -1,183 +1,183 @@ # Puppet External Data Sources # # This is a parser function to read data from external files, this version # uses CSV files but the concept can easily be adjust for databases, yaml # or any other queryable data source. # # The object of this is to make it obvious when it's being used, rather than # magically loading data in when an module is loaded I prefer to look at the code # and see statements like: # # $snmp_contact = extlookup("snmp_contact") # # The above snippet will load the snmp_contact value from CSV files, this in its # own is useful but a common construct in puppet manifests is something like this: # # case $domain { # "myclient.com": { $snmp_contact = "John Doe " } # default: { $snmp_contact = "My Support " } # } # # Over time there will be a lot of this kind of thing spread all over your manifests # and adding an additional client involves grepping through manifests to find all the # places where you have constructs like this. # # This is a data problem and shouldn't be handled in code, a using this function you # can do just that. # # First you configure it in site.pp: # $extlookup_datadir = "/etc/puppet/manifests/extdata" # $extlookup_precedence = ["%{fqdn}", "domain_%{domain}", "common"] # # The array tells the code how to resolve values, first it will try to find it in # web1.myclient.com.csv then in domain_myclient.com.csv and finally in common.csv # # Now create the following data files in /etc/puppet/manifests/extdata # # domain_myclient.com.csv: # snmp_contact,John Doe # root_contact,support@%{domain} # client_trusted_ips,192.168.1.130,192.168.10.0/24 # # common.csv: # snmp_contact,My Support # root_contact,support@my.com # # Now you can replace the case statement with the simple single line to achieve # the exact same outcome: # # $snmp_contact = extlookup("snmp_contact") # # The obove code shows some other features, you can use any fact or variable that # is in scope by simply using %{varname} in your data files, you can return arrays # by just having multiple values in the csv after the initial variable name. # # In the event that a variable is nowhere to be found a critical error will be raised # that will prevent your manifest from compiling, this is to avoid accidentally putting # in empty values etc. You can however specify a default value: # # $ntp_servers = extlookup("ntp_servers", "1.${country}.pool.ntp.org") # # In this case it will default to "1.${country}.pool.ntp.org" if nothing is defined in # any data file. # # You can also specify an additional data file to search first before any others at use # time, for example: # # $version = extlookup("rsyslog_version", "present", "packages") # # package{"rsyslog": ensure => $version } # # This will look for a version configured in packages.csv and then in the rest as configured # by $extlookup_precedence if it's not found anywhere it will default to "present", this kind # of use case makes puppet a lot nicer for managing large amounts of packages since you do not # need to edit a load of manifests to do simple things like adjust a desired version number. # # For more information on installing and writing your own custom functions see: -# http://reductivelabs.com/trac/puppet/wiki/WritingYourOwnFunctions +# http://puppetlabs.com/trac/puppet/wiki/WritingYourOwnFunctions # # For further help contact Volcane on #puppet require 'csv' module Puppet::Parser::Functions newfunction(:extlookup, :type => :rvalue) do |args| key = args[0] default = "_ExtUNSET_" datafile = "_ExtUNSET_" default = args[1] if args[1] datafile = args[2] if args[2] extlookup_datadir = lookupvar('extlookup_datadir') extlookup_precedence = Array.new # precedence values can have variables embedded in them # in the form %{fqdn}, you could for example do # # $extlookup_precedence = ["hosts/%{fqdn}", "common"] # # this will result in /path/to/extdata/hosts/your.box.com.csv # being searched. # # we parse the precedence here because the best place to specify # it would be in site.pp but site.pp is only evaluated at startup # so $fqdn etc would have no meaning there, this way it gets evaluated # each run and has access to the right variables for that run lookupvar('extlookup_precedence').each do |prec| while prec =~ /%\{(.+?)\}/ prec.gsub!(/%\{#{$1}\}/, lookupvar($1)) end extlookup_precedence << prec end datafiles = Array.new # if we got a custom data file, put it first in the array of search files if datafile != "" if File.exists?(extlookup_datadir + "/#{datafile}.csv") datafiles << extlookup_datadir + "/#{datafile}.csv" end end extlookup_precedence.each do |d| datafiles << extlookup_datadir + "/#{d}.csv" end desired = "_ExtUNSET_" datafiles.each do |file| parser.watch_file(file) if File.exists?(file) if desired == "_ExtUNSET_" if File.exists?(file) result = CSV.read(file).find_all do |r| r[0] == key end # return just the single result if theres just one, # else take all the fields in the csv and build an array if result.length > 0 if result[0].length == 2 val = result[0][1].to_s # parse %{}'s in the CSV into local variables using lookupvar() while val =~ /%\{(.+?)\}/ val.gsub!(/%\{#{$1}\}/, lookupvar($1)) end desired = val elsif result[0].length > 1 length = result[0].length cells = result[0][1,length] # Individual cells in a CSV result are a weird data type and throws # puppets yaml parsing, so just map it all to plain old strings desired = cells.map do |c| # parse %{}'s in the CSV into local variables using lookupvar() while c =~ /%\{(.+?)\}/ c.gsub!(/%\{#{$1}\}/, lookupvar($1)) end c.to_s end end end end end end # don't accidently return nil's and such rather throw a parse error if desired == "_ExtUNSET_" && default == "_ExtUNSET_" raise Puppet::ParseError, "No match found for '#{key}' in any data file during extlookup()" else desired = default if desired == "_ExtUNSET_" end desired end end # vi:tabstop=4:expandtab:ai diff --git a/ext/nagios/naggen b/ext/nagios/naggen index 6ff09e260..2b8480eca 100755 --- a/ext/nagios/naggen +++ b/ext/nagios/naggen @@ -1,302 +1,302 @@ #!/usr/bin/env ruby # # = Synopsis # # Generate Nagios configurations from Puppet Resources in an ActiveRecord database # # = Usage # # naggen [-h|--help] [-d|--debug] [-v|--verbose] [--compare] # # = Description # # This executable is a means of short-circuiting the process of generating nagios # configurations on your server using Puppet Exported Resources. It skips any possible # naming conflicts resulting from Puppet's resource uniqueness requirements, and it # also skips the inefficiencies involved in converting and transporting large numbers # of Puppet resources. # # At the least, the machine that runs this will need ActiveRecord (2.0.2) installed, # along with any database libraries you use. # # = 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. # # You can add naggen-specific settings to your puppet.conf in a '[naggen]' section, # just like any other executable. # # See the configuration file documentation at -# http://reductivelabs.com/projects/puppet/reference/configref.html for +# http://puppetlabs.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 puppet with # '--genconfig'. # # compare:: # Compare new and old files and only backup and write if the files are different. # Potentially expensive computationally, but idempotent. Will exit with 0 if # no changes were made and 1 if there were. # # debug:: # Enable full debugging. # # detailed-exitcodes:: # Provide transaction information via exit codes. If this is enabled, an exit # code of '2' means there were changes, and an exit code of '4' means that there # were failures during the transaction. # # help:: # Print this help message # # verbose:: # Print extra information. # # = Example # # naggen --storeconfigs --confdir /foo --compare # # = Author # # Luke Kanies # # = Copyright # -# Copyright (c) 2009 Reductive Labs, LLC +# Copyright (c) 2009 Puppet Labs, LLC # Licensed under the GPL 2 require 'puppet' require 'puppet/rails' require 'puppet/rails/resource' require 'puppet/rails/param_value' require 'puppet/network/client' require 'puppet/parser/collector' require 'puppet/provider/naginator' require 'getoptlong' # Monkey-patch the rails resources so we can # easily convert them to nagios instances. class Puppet::Rails::Resource def to_param_hash values = @params_hash || Puppet::Rails::ParamValue.find_all_params_from_resource(self) if values.size == 0 return {} end values.inject({}) do |hash, value| hash[value['name']] ||= [] hash[value['name']] << value["value"] hash end end def to_nagios unless nagios_type = Nagios::Base.type(restype.sub("Nagios_", '').to_sym) raise Puppet::DevError, "Could not find nagios type '%s'" % restype end result = nagios_type.new to_param_hash.each do |param, value| next unless nagios_type.parameter?(param) result[param] = value end result[:name] = self.title result end end class NagiosWriter class FakeScope def debug(string) Puppet.debug string end def host "this host doesn't exist" end end attr_accessor :nagios_type, :bucket def backup(target) return unless FileTest.exist?(target) and File.stat(target).size > 0 Puppet.info "Backing up %s" % target bucket.backup(target) end def collector collector = Puppet::Parser::Collector.new(FakeScope.new, "nagios_" + @nagios_type.to_s, nil, nil, :exported) # We don't have a scope, so we're stubbing everything out that would interact # with the scope. class << collector def collect_virtual(*args) [] end def exported_resource(res) res end end collector end def default_target "/etc/nagios/nagios_#{nagios_type.to_s}.cfg" end def evaluate return unless resources = rails_resources() resources_by_target = resources.inject({}) do |hash, resource| target = resource["target"] || default_target hash[target] ||= [] hash[target] << resource hash end changed = false resources_by_target.each do |target, resources| begin result = write(target, resources) rescue => detail $stderr.puts detail.backtrace Puppet.err "Could not write to %s: %s" % [target, detail] end changed = true if result end changed end def initialize(nagios_type) @nagios_type = nagios_type @bucket = Puppet::Network::Client.client(:Dipper).new(:Path => Puppet[:clientbucketdir]) end def rails_resources collector.send(:collect_exported) end def write(target, resources) # Skip the nagios type when we have no resources and no existing # file. return if resources.empty? and ! FileTest.exist?(target) dir = File.dirname(target) unless FileTest.exist?(dir) FileUtils.mkdir_p(dir) end count = 0 tempfile = target + ".tmp" File.open(tempfile, "w") do |file| resources.each do |resource| count += 1 file.puts resource.to_nagios.to_s.gsub("_naginator_name", Puppet::Provider::Naginator::NAME_STRING) end end if $options[:compare] if FileTest.exist?(target) and File.read(tempfile) == File.read(target) return false end end backup(target) # Atomic rename File.rename(tempfile, target) Puppet.notice "Wrote %s resources to %s" % [count, target] return true ensure File.unlink(tempfile) if tempfile and FileTest.exist?(tempfile) end end arguments = [ [ "--compare", "-c", GetoptLong::NO_ARGUMENT ], [ "--debug", "-d", GetoptLong::NO_ARGUMENT ], [ "--verbose", "-v", GetoptLong::NO_ARGUMENT ], [ "--help", "-h", GetoptLong::NO_ARGUMENT ] ] Puppet.settings.addargs(arguments) result = GetoptLong.new(*arguments) $options = {} result.each { |opt,arg| case opt when "--help" begin require 'rdoc/usage' RDoc::usage && exit rescue LoadError docs = [] File.readlines(__FILE__).each do |line| next if line =~ /^#\!/ unless line =~ /^#/ next if docs.length == 0 # skip the first line or so break # else, we've passed the docs, so just break end docs << line.sub(/^# ?/, '') end print docs exit end when "--compare" $options[:compare] = true when "--verbose" $options[:verbose] = true when "--debug" $options[:debug] = true when "--debug" $options[:debug] = true else Puppet.settings.handlearg(opt, arg) end } # Read in Puppet settings, so we know how Puppet's configured. Puppet.parse_config Puppet::Util::Log.newdestination(:console) if $options[:debug] Puppet::Util::Log.level = :debug elsif $options[:verbose] Puppet::Util::Log.level = :info end # See if Naginator is installed directly, else load Puppet's version. begin require 'nagios' rescue LoadError require 'puppet/external/nagios' end changed = false Nagios::Base.eachtype do |name, type| writer = NagiosWriter.new(name) changed = true if writer.evaluate end if $options[:compare] and changed exit(1) else exit(0) end diff --git a/ext/puppet-test b/ext/puppet-test index dbbde40c6..d1f49d6d8 100755 --- a/ext/puppet-test +++ b/ext/puppet-test @@ -1,536 +1,536 @@ #!/usr/bin/env ruby # == Synopsis # # Test individual client performance. Can compile configurations, describe # files, or retrieve files. # # = Usage # # puppet-test [-c|--compile] [-D|--describe ] [-d|--debug] # [--fork ] [-h|--help] [-H|--hostname ] [-l|--list] [-r|--repeat ] # [-R|--retrieve ] [-t|--test ] [-V|--version] [-v|--verbose] # # = Description # # This is a simple script meant for doing performance tests with Puppet. By # default it pulls down a compiled configuration, but it supports multiple # other tests. # # = 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 +# http://puppetlabs.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'. # # compile:: # Compile the client's configuration. The default. # # debug:: # Enable full debugging. # # describe:: # Describe the file being tested. This is a query to get information about # the file from the server, to determine if it should be copied, and is the # first half of every file transfer. # # fork:: # Fork the specified number of times, thus acting as multiple clients. # # 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 # # list:: # List all available tests. # # node:: # Specify the node to use. This is useful for looking up cached yaml data # in your :clientyaml directory, and forcing a specific host's configuration to # get compiled. # # pause:: # Pause before starting test (useful for testing with dtrace). # # repeat:: # How many times to perform the test. # # retrieve:: # Test file retrieval performance. Retrieves the specified file from the # remote system. Note that the server should be specified via --server, # so the argument to this option is just the remote module name and path, # e.g., "/dist/apps/myapp/myfile", where "dist" is the module and # "apps/myapp/myfile" is the path to the file relative to the module. # # test:: # Specify the test to run. You can see the list of tests by running this command with --list. # # verbose:: # Turn on verbose reporting. # # version:: # Print the puppet version number and exit. # # = Example # # puppet-test --retrieve /module/path/to/file # # = Author # # Luke Kanies # # = Copyright # -# Copyright (c) 2005, 2006 Reductive Labs, LLC +# Copyright (c) 2005, 2006 Puppet 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(1) end require 'puppet' require 'puppet/network/client' require 'getoptlong' class Suite attr_reader :name, :doc @@suites = {} @@tests = {} def self.[](name) @@suites[name] end # Run a test by first finding the suite then running the appropriate test. def self.run(test) unless suite_name = @@tests[test] raise "Unknown test %s" % test end unless suite = @@suites[suite_name] raise "Unknown test suite %s from test %s" % [suite_name, test] end suite.run(test) end # What suites are available? def self.suites @@suites.keys end def forked? defined? @forking end # Create a new test suite. def initialize(name, doc, &block) @name = name @doc = doc @tests = {} @@suites[name] = self raise "You must pass a block to the Test" unless block_given? instance_eval(&block) end # Define a new type of test on this suite. def newtest(name, doc, &block) @tests[name] = doc if @@tests[name] raise "Test names must be unique; cannot redefine %s" % name end @@tests[name] = @name meta_def(name, &block) end # Run the actual test. def run(test) unless doc = @tests[test] raise "Suite %s only supports tests %s; not %s" % [@name, @tests.keys.collect { |k| k.to_s }.join(","), test] end puts "Running %s %s test" % [@name, test] prepare() if respond_to?(:prepare) if $options[:pause] puts "Hit any key to continue" $stdin.readline puts "Continuing with test" end if $options[:fork] > 0 @forking = true $options[:fork].times { if pid = fork $pids << pid else break end } end $options[:repeat].times do |i| @count = i if forked? msg = doc + " in PID %s" % Process.pid else msg = doc end Puppet::Util.benchmark(:notice, msg) do begin send(test) rescue => detail puts detail.backtrace if Puppet[:trace] Puppet.err "%s failed: %s" % [@name, detail.to_s] end end end end # What tests are available on this suite? def tests @tests.keys end end Suite.new :parser, "Manifest parsing" do newtest :parse, "Parsed files" do @parser = Puppet::Parser::Parser.new(:environment => Puppet[:environment]) @parser.file = Puppet[:manifest] @parser.parse end end Suite.new :local_catalog, "Local catalog handling" do def prepare @node = Puppet::Node.find($options[:nodes][0]) end newtest :compile, "Compiled catalog" do Puppet::Resource::Catalog.find(@node) end end Suite.new :remote_catalog, "Remote catalog handling" do def prepare $args[:cache] = false # Create a config client and pull the config down @client = Puppet::Network::Client.master.new($args) unless @client.read_cert fail "Could not read client certificate" end if tmp = Puppet::Node::Facts.find($options[:nodes][0]) @facts = tmp.values else raise "Could not find facts for %s" % $optins[:nodes][0] end if host = $options[:fqdn] @facts["fqdn"] = host @facts["hostname"] = host.sub(/\..+/, '') @facts["domain"] = host.sub(/^[^.]+\./, '') end @facts = YAML.dump(@facts) end newtest :getconfig, "Compiled catalog" do @client.driver.getconfig(@facts, "yaml") end # This test will always force a false answer. newtest :fresh, "Checked freshness" do @client.driver.freshness end end Suite.new :file, "File interactions" do def prepare unless $options[:file] fail "You must specify a file (using --file ) to interact with on the server" end @client = Puppet::Network::Client.file.new($args) unless @client.read_cert fail "Could not read client certificate" end end newtest :describe, "Described file" do @client.describe($options[:file], :ignore) end newtest :retrieve, "Retrieved file" do @client.retrieve($options[:file], :ignore) end end Suite.new :filebucket, "Filebucket interactions" do def prepare require 'tempfile' @client = Puppet::Network::Client.dipper.new($args) end newtest :backup, "Backed up file" do Tempfile.open("bucket_testing") do |f| f.print rand(1024) f.close @client.backup(f.path) end end end # Note that this uses an env variable to determine how many resources per # host to create (with a default of 10). 'repeat' determines how # many hosts to create. You probably will get mad failures if you # use forking and sqlite. # Here's an example run of this test, using sqlite: # RESOURCE_COUNT=50 ext/puppet-test --suite rails --test storage --confdir /tmp/storagetesting --vardir /tmp/storagetesting --repeat 10 Suite.new :rails, "Rails Interactions" do def prepare Puppet::Rails.init @facts = Facter.to_hash if num = ENV["RESOURCECOUNT"] @resources = Integer(num) else @resources = 10 end end Resource = Puppet::Parser::Resource def execute(test, msg) begin send(test) rescue => detail puts detail.backtrace if Puppet[:trace] Puppet.err "%s failed: %s" % [@name, detail.to_s] end end def mkresource(type, title, parameters) source = "fakesource" res = Resource.new(:type => type, :title => title, :source => source, :scope => "fakescope") parameters.each do |param, value| res.set(param, value, source) end res end def ref(type, title) Resource::Reference.new(:type => type, :title => title) end newtest :storage, "Stored resources" do hostname = "host%s" % @count @facts["hostname"] = hostname args = {:facts => @facts, :name => hostname} # Make all of the resources we want. Make them at least slightly complex, # so we model real resources as close as we can. resources = [] args[:resources] = resources @resources.times do |resnum| exec = mkresource("exec", "exec%s" % resnum, :command => "/bin/echo do something %s" % resnum) exec.tags = %w{exec one} << "exec%s" % resnum user = mkresource("user", "user%s" % resnum, :uid => resnum.to_s, :require => ref("exec", "exec%s" % resnum)) user.tags = %w{user one two} << "user%s" % resnum file = mkresource("file", "/tmp/file%s" % resnum, :owner => resnum.to_s, :require => [ref("exec", "exec%s" % resnum), ref("user", "user%s" % resnum)]) file.tags = %w{file one three} << "file%s" % resnum file.exported = true resources << exec << user << file end Puppet::Rails::Host.store(args) end end Suite.new :report, "Reports interactions" do def prepare Puppet::Transaction::Report.terminus_class = :rest end newtest :empty, "send empty report" do report = Puppet::Transaction::Report.new report.time = Time.now report.save end newtest :fake, "send fake report" do report = Puppet::Transaction::Report.new resourcemetrics = { :total => 12, :out_of_sync => 20, :applied => 45, :skipped => 1, :restarted => 23, :failed_restarts => 1, :scheduled => 10 } report.newmetric(:resources, resourcemetrics) timemetrics = { :resource1 => 10, :resource2 => 50, :resource3 => 40, :resource4 => 20, } report.newmetric(:times, timemetrics) report.newmetric(:changes, :total => 20 ) report.time = Time.now report.save end end $cmdargs = [ [ "--compile", "-c", GetoptLong::NO_ARGUMENT ], [ "--describe", GetoptLong::REQUIRED_ARGUMENT ], [ "--retrieve", "-R", GetoptLong::REQUIRED_ARGUMENT ], [ "--fork", GetoptLong::REQUIRED_ARGUMENT ], [ "--fqdn", "-F", GetoptLong::REQUIRED_ARGUMENT ], [ "--suite", "-s", GetoptLong::REQUIRED_ARGUMENT ], [ "--test", "-t", GetoptLong::REQUIRED_ARGUMENT ], [ "--pause", "-p", GetoptLong::NO_ARGUMENT ], [ "--repeat", "-r", GetoptLong::REQUIRED_ARGUMENT ], [ "--node", "-n", GetoptLong::REQUIRED_ARGUMENT ], [ "--debug", "-d", GetoptLong::NO_ARGUMENT ], [ "--help", "-h", GetoptLong::NO_ARGUMENT ], [ "--list", "-l", 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($cmdargs) Puppet::Util::Log.newdestination(:console) Puppet::Node.terminus_class = :plain Puppet::Node.cache_class = :yaml Puppet::Node::Facts.terminus_class = :facter Puppet::Node::Facts.cache_class = :yaml result = GetoptLong.new(*$cmdargs) $args = {} $options = {:repeat => 1, :fork => 0, :pause => false, :nodes => []} 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 "--compile" $options[:suite] = :configuration $options[:test] = :compile when "--retrieve" $options[:suite] = :file $options[:test] = :retrieve $options[:file] = arg when "--fork" begin $options[:fork] = Integer(arg) rescue => detail $stderr.puts "The argument to 'fork' must be an integer" exit(14) end when "--describe" $options[:suite] = :file $options[:test] = :describe $options[:file] = arg when "--fqdn" $options[:fqdn] = arg when "--repeat" $options[:repeat] = Integer(arg) 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 "--suite" $options[:suite] = arg.intern when "--test" $options[:test] = arg.intern when "--file" $options[:file] = arg when "--pause" $options[:pause] = true when "--node" $options[:nodes] << arg when "--list" Suite.suites.sort { |a,b| a.to_s <=> b.to_s }.each do |suite_name| suite = Suite[suite_name] tests = suite.tests.sort { |a,b| a.to_s <=> b.to_s }.join(", ") puts "%20s: %s" % [suite_name, tests] end exit(0) else Puppet.settings.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 $options[:nodes] << Puppet.settings[:certname] if $options[:nodes].empty? $args[:Server] = Puppet[:server] unless $options[:test] $options[:suite] = :remote_catalog $options[:test] = :getconfig end unless $options[:test] raise "A suite was specified without a test" end $pids = [] Suite.run($options[:test]) if $options[:fork] > 0 Process.waitall end diff --git a/ext/puppetstoredconfigclean.rb b/ext/puppetstoredconfigclean.rb index 439d74376..6538192dd 100644 --- a/ext/puppetstoredconfigclean.rb +++ b/ext/puppetstoredconfigclean.rb @@ -1,87 +1,87 @@ #!/usr/bin/env ruby # Script to clean up stored configs for (a) given host(s) # # Credits: -# Script was taken from http://reductivelabs.com/trac/puppet/attachment/wiki/UsingStoredConfiguration/kill_node_in_storedconfigs_db.rb +# Script was taken from http://puppetlabs.com/trac/puppet/attachment/wiki/UsingStoredConfiguration/kill_node_in_storedconfigs_db.rb # which haven been initially posted by James Turnbull # duritong adapted and improved the script a bit. require 'getoptlong' config = '/etc/puppet/puppet.conf' def printusage(error_code) puts "Usage: #{$0} [ list of hostnames as stored in hosts table ]" puts "\n Options:" puts "--config " exit(error_code) end opts = GetoptLong.new( [ "--config", "-c", GetoptLong::REQUIRED_ARGUMENT ], [ "--help", "-h", GetoptLong::NO_ARGUMENT ], [ "--usage", "-u", GetoptLong::NO_ARGUMENT ], [ "--version", "-v", GetoptLong::NO_ARGUMENT ] ) begin opts.each do |opt, arg| case opt when "--config" config = arg when "--help" printusage(0) when "--usage" printusage(0) when "--version" puts "%s" % Puppet.version exit end end rescue GetoptLong::InvalidOption => detail $stderr.puts "Try '#{$0} --help'" exit(1) end printusage(1) unless ARGV.size > 0 require 'puppet/rails' Puppet[:config] = config Puppet.parse_config pm_conf = Puppet.settings.instance_variable_get(:@values)[:puppetmasterd] adapter = pm_conf[:dbadapter] args = {:adapter => adapter, :log_level => pm_conf[:rails_loglevel]} case adapter when "sqlite3" args[:dbfile] = pm_conf[:dblocation] when "mysql", "postgresql" args[:host] = pm_conf[:dbserver] unless pm_conf[:dbserver].to_s.empty? args[:username] = pm_conf[:dbuser] unless pm_conf[:dbuser].to_s.empty? args[:password] = pm_conf[:dbpassword] unless pm_conf[:dbpassword].to_s.empty? args[:database] = pm_conf[:dbname] unless pm_conf[:dbname].to_s.empty? socket = pm_conf[:dbsocket] args[:socket] = socket unless socket.to_s.empty? else raise ArgumentError, "Invalid db adapter %s" % adapter end args[:database] = "puppet" unless not args[:database].to_s.empty? ActiveRecord::Base.establish_connection(args) ARGV.each { |hostname| if @host = Puppet::Rails::Host.find_by_name(hostname.strip) print "Killing #{hostname}..." $stdout.flush @host.destroy puts "done." else puts "Can't find host #{hostname}." end } exit 0 diff --git a/ext/regexp_nodes/regexp_nodes.rb b/ext/regexp_nodes/regexp_nodes.rb index a9e7ed6a9..78e4357d6 100644 --- a/ext/regexp_nodes/regexp_nodes.rb +++ b/ext/regexp_nodes/regexp_nodes.rb @@ -1,215 +1,215 @@ #!/usr/bin/env ruby # = Synopsis # This is an external node classifier script, after -# http://reductivelabs.com/trac/puppet/wiki/ExternalNodes +# http://puppetlabs.com/trac/puppet/wiki/ExternalNodes # # = Usage # regexp_nodes.rb # # = Description # This classifier implements filesystem autoloading: It looks through classes # and parameters subdirectories, looping through each file it finds there - the # contents are a regexp-per-line which, if they match the hostname passed us as # ARGV[0], will cause a class or parameter named the same thing as the file to # be set. # # = Examples # In the distribution there are two subdirectories test_classes/ and # test_parameters, which are passed as parameters to MyExternalNode.new. # test_classes/database will set the 'database' class for any hostnames # matching %r{db\d{2}} (that is, 'db' followed by two digits) or with 'mysql' # anywhere in the hostname. Similarly, hosts beginning with 'www' or 'web' # or the hostname 'leterel' (my workstation) will be assigned the 'webserver' # class. # # Under test_parameters/ there is one subdirectory 'environment' which # sets the a parameter called 'environment' to the value 'prod' for production # hosts (whose hostnames always end with three numbers for us), 'qa' for # anything that starts with 'qa-' 'qa2-' or 'qa3-', and 'sandbox' for any # development machines which are, naturally, named after Autechre songs. # # # = Author # Eric Sorenson # we need yaml or there's not much point in going on require 'yaml' # Sets are like arrays but automatically de-duplicate elements require 'set' # set up some nice logging require 'logger' # XXX flip this for production vs local sandbox # $LOG = Logger.new("/var/lib/puppet/log/extnodes.log") # $LOG.level = Logger::FATAL $LOG = Logger.new($stderr) $LOG.level = Logger::DEBUG # paths for files we use will be relative to this directory # XXX flip this for production vs local sandbox # WORKINGDIR = "/var/lib/puppet/bin" WORKINGDIR = Dir.pwd # This class holds all the methods for creating and accessing the properties # of an external node. There are really only two public methods: initialize() # and a special version of to_yaml() class ExternalNode # Make these instance variables get/set-able with eponymous methods attr_accessor :classes, :parameters, :hostname # initialize() takes three arguments: # hostname:: usually passed in via ARGV[0] but it could be anything # classdir:: directory under WORKINGDIR to look for files named after # classes # parameterdir:: directory under WORKINGDIR to look for directories to set # parameters def initialize(hostname, classdir = 'classes/', parameterdir = 'parameters/') # instance variables that contain the lists of classes and parameters @hostname @classes = Set.new ["baseclass"] @parameters = Hash.new("unknown") # sets a default value of "unknown" self.parse_argv(hostname) self.match_classes(WORKINGDIR + "/" + classdir) self.match_parameters(WORKINGDIR + "/" + parameterdir) end # private method called by initialize() which sanity-checks our hostname. # good candidate for overriding in a subclass if you need different checks def parse_argv(hostname) if hostname =~ /^([-\w]+?)\.([-\w\.]+)/ # non-greedy up to the first . is hostname @hostname = $1 elsif hostname =~ /^([-\w]+)$/ # sometimes puppet's @name is just a name @hostname = hostname else $LOG.fatal("didn't receive parsable hostname, got: [#{hostname}]") exit(1) end end # to_yaml massages a copy of the object and outputs clean yaml so we don't # feed weird things back to puppet []< def to_yaml classes = self.classes.to_a if self.parameters.empty? # otherwise to_yaml prints "parameters: {}" parameters = nil else parameters = self.parameters end ({ 'classes' => classes, 'parameters' => parameters}).to_yaml end # Private method that expects an absolute path to a file and a string to # match - it returns true if the string was matched by any of the lines in # the file def matched_in_patternfile?(filepath, matchthis) patternlist = [] begin open(filepath).each { |l| pattern = %r{#{l.chomp!}} patternlist << pattern $LOG.debug("appending [#{pattern}] to patternlist for [#{filepath}]") } rescue Exception $LOG.fatal("Problem reading #{filepath}: #{$!}") exit(1) end $LOG.debug("list of patterns for #{filepath}: #{patternlist}") if matchthis =~ Regexp.union(patternlist) $LOG.debug("matched #{$~.to_s} in #{matchthis}, returning true") return true else # hostname didn't match anything in patternlist $LOG.debug("#{matchthis} unmatched, returning false") return nil end end # def # private method - takes a path to look for files, iterates through all # readable, regular files it finds, and matches this instance's @hostname # against each line; if any match, the class will be set for this node. def match_classes(fullpath) Dir.foreach(fullpath) do |patternfile| filepath = "#{fullpath}/#{patternfile}" next unless File.file?(filepath) and File.readable?(filepath) $LOG.debug("Attempting to match [#{@hostname}] in [#{filepath}]") if matched_in_patternfile?(filepath,@hostname) @classes << patternfile.to_s $LOG.debug("Appended #{patternfile.to_s} to classes instance variable") end # if end # Dir.foreach end # def # Parameters are handled slightly differently; we make another level of # directories to get the parameter name, then use the names of the files # contained in there for the values of those parameters. # # ex: cat /var/lib/puppet/bin/parameters/environment/production # ^prodweb # would set parameters["environment"] = "production" for prodweb001 def match_parameters(fullpath) Dir.foreach(fullpath) do |parametername| filepath = "#{fullpath}/#{parametername}" next if File.basename(filepath) =~ /^\./ # skip over dotfiles next unless File.directory?(filepath) and File.readable?(filepath) # skip over non-directories $LOG.debug "Considering contents of #{filepath}" Dir.foreach("#{filepath}") do |patternfile| secondlevel = "#{filepath}/#{patternfile}" $LOG.debug "Found parameters patternfile at #{secondlevel}" next unless File.file?(secondlevel) and File.readable?(secondlevel) $LOG.debug("Attempting to match [#{@hostname}] in [#{secondlevel}]") if matched_in_patternfile?(secondlevel, @hostname) @parameters[ parametername.to_s ] = patternfile.to_s $LOG.debug("Set @parameters[#{parametername.to_s}] = #{patternfile.to_s}") end # if end # Dir.foreach #{filepath} end # Dir.foreach #{fullpath} end # def end # Class # Logic for local hacks that don't fit neatly into the autoloading model can # happen as we initialize a subclass class MyExternalNode < ExternalNode def initialize(hostname, classdir = 'classes/', parameterdir = 'parameters/') super # Set "hostclass" parameter based on hostname, # stripped of leading environment prefix and numeric suffix if @hostname =~ /^(\w*?)-?(\D+)(\d{2,3})$/ match = Regexp.last_match hostclass = match[2] $LOG.debug("matched hostclass #{hostclass}") @parameters[ "hostclass" ] = hostclass else $LOG.debug("hostclass couldn't figure out class from #{@hostname}") end # if end # def end # Class # Here we begin actual execution by calling methods defined above mynode = MyExternalNode.new(ARGV[0], classes = 'test_classes', parameters = 'test_parameters') puts mynode.to_yaml diff --git a/lib/puppet/defaults.rb b/lib/puppet/defaults.rb index e78b20fe2..d33353585 100644 --- a/lib/puppet/defaults.rb +++ b/lib/puppet/defaults.rb @@ -1,797 +1,797 @@ # The majority of the system configuration parameters are set in this file. module Puppet # 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 name = $0.gsub(/.+#{File::SEPARATOR}/,'').sub(/\.rb$/, '') # Make File.expand_path happy require 'etc' ENV["HOME"] ||= Etc.getpwuid(Process.uid).dir if name != "puppetmasterd" and Puppet::Util::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/lib/puppet" end self.setdefaults(:main, :confdir => [conf, "The main Puppet configuration directory. The default for this parameter is calculated based on the user. If the process is runnig as root or the user that ``puppetmasterd`` is supposed to run as, it defaults to a system directory, but if it's running as any other user, it defaults to being in ``~``."], :vardir => [var, "Where Puppet stores dynamic and growing data. The default for this parameter is calculated specially, like `confdir`_."], :name => [name, "The name of the service, if we are running as one. The default is essentially $0 without the path or ``.rb``."] ) if name == "puppetmasterd" logopts = {:default => "$vardir/log", :mode => 0750, :owner => "service", :group => "service", :desc => "The Puppet log directory." } else logopts = ["$vardir/log", "The Puppet log directory."] end setdefaults(:main, :logdir => logopts) # This name hackery is necessary so that the rundir is set reasonably during # unit tests. if Process.uid == 0 and %w{puppetd puppetmasterd}.include?(self.name) rundir = "/var/run/puppet" else rundir = "$vardir/run" end self.setdefaults(:main, :trace => [false, "Whether to print stack traces on some errors"], :autoflush => [false, "Whether log files should always flush to disk."], :syslogfacility => ["daemon", "What syslog facility to use when logging to syslog. Syslog has a fixed list of valid facilities, and you must choose one of those; you cannot just make one up."], :statedir => { :default => "$vardir/state", :mode => 01755, :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 => rundir, :mode => 01777, :desc => "Where Puppet PID files 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 => ["ansi", "Whether to use colors when logging to the console. Valid values are ``ansi`` (equivalent to ``true``), ``html`` (mostly used during testing with TextMate), and ``false``, which produces no color."], :mkusers => [false, "Whether to create the necessary user and group that puppetd will run as."], :manage_internal_file_permissions => [true, "Whether Puppet should manage the owner, group, and mode of files it uses internally" ], :path => {:default => "none", :desc => "The shell search path. Defaults to whatever is inherited from the parent process.", :call_on_define => true, # Call our hook with the default value, so we always get the libdir set. :hook => proc do |value| ENV["PATH"] = "" if ENV["PATH"].nil? ENV["PATH"] = value unless value == "none" paths = ENV["PATH"].split(File::PATH_SEPARATOR) %w{/usr/sbin /sbin}.each do |path| unless paths.include?(path) ENV["PATH"] += File::PATH_SEPARATOR + path end end value end }, :libdir => {:default => "$vardir/lib", :desc => "An extra search path for Puppet. This is only useful for those files that Puppet will load on demand, and is only guaranteed to work for those cases. In fact, the autoload mechanism is responsible for making sure this directory is in Ruby's search path", :call_on_define => true, # Call our hook with the default value, so we always get the libdir set. :hook => proc do |value| if defined? @oldlibdir and $:.include?(@oldlibdir) $:.delete(@oldlibdir) end @oldlibdir = value $: << value end }, :ignoreimport => [false, "A parameter that can be used in commit hooks, since it enables you to parse-check a single file rather than requiring that all files exist."], :authconfig => [ "$confdir/namespaceauth.conf", "The configuration file that defines the rights to the different namespaces and methods. This can be used as a coarse-grained authorization system for both ``puppetd`` and ``puppetmasterd``." ], :environment => {:default => "production", :desc => "The environment Puppet is running in. For clients (e.g., ``puppetd``) this determines the environment itself, which is used to find modules and much more. For servers (i.e., ``puppetmasterd``) this provides the default environment for nodes we know nothing about." }, :diff_args => ["-u", "Which arguments to pass to the diff command when printing differences between files."], :diff => ["diff", "Which diff command to use when printing differences between files."], :show_diff => [false, "Whether to print a contextual diff when files are being replaced. The diff is printed on stdout, so this option is meaningless unless you are running Puppet interactively. This feature currently requires the ``diff/lcs`` Ruby library."], :daemonize => { :default => true, :desc => "Send the process into the background. This is the default.", :short => "D" }, :maximum_uid => [4294967290, "The maximum allowed UID. Some platforms use negative UIDs but then ship with tools that do not know how to handle signed ints, so the UIDs show up as huge numbers that can then not be fed back into the system. This is a hackish way to fail in a slightly more useful way when that happens."], :node_terminus => ["plain", "Where to find information about nodes."], :catalog_terminus => ["compiler", "Where to get node catalogs. This is useful to change if, for instance, you'd like to pre-compile catalogs and store them in memcached or some other easily-accessed store."], :httplog => { :default => "$logdir/http.log", :owner => "root", :mode => 0640, :desc => "Where the puppetd web server logs." }, :http_proxy_host => ["none", "The HTTP proxy host to use for outgoing connections. Note: You may need to use a FQDN for the server hostname when using a proxy."], :http_proxy_port => [3128, "The HTTP proxy port to use for outgoing connections"], :filetimeout => [ 15, "The minimum time to wait (in seconds) between checking for updates in configuration files. This timeout determines how quickly Puppet checks whether a file (such as manifests or templates) has changed on disk." ], :queue_type => ["stomp", "Which type of queue to use for asynchronous processing."], :queue_type => ["stomp", "Which type of queue to use for asynchronous processing."], :queue_source => ["stomp://localhost:61613/", "Which type of queue to use for asynchronous processing. If your stomp server requires authentication, you can include it in the URI as long as your stomp client library is at least 1.1.1"], :async_storeconfigs => {:default => false, :desc => "Whether to use a queueing system to provide asynchronous database integration. Requires that ``puppetqd`` be running and that 'PSON' support for ruby be installed.", :hook => proc do |value| if value # This reconfigures the terminii for Node, Facts, and Catalog Puppet.settings[:storeconfigs] = true # But then we modify the configuration Puppet::Resource::Catalog.cache_class = :queue else raise "Cannot disable asynchronous storeconfigs in a running process" end end }, :thin_storeconfigs => {:default => false, :desc => "Boolean; wether storeconfigs store in the database only the facts and exported resources. If true, then storeconfigs performance will be higher and still allow exported/collected resources, but other usage external to Puppet might not work", :hook => proc do |value| Puppet.settings[:storeconfigs] = true if value end }, :config_version => ["", "How to determine the configuration version. By default, it will be the time that the configuration is parsed, but you can provide a shell script to override how the version is determined. The output of this script will be added to every log message in the reports, allowing you to correlate changes on your hosts to the source version on the server."], :zlib => [true, "Boolean; whether to use the zlib library", ], :prerun_command => ["", "A command to run before every agent run. If this command returns a non-zero return code, the entire Puppet run will fail."], :postrun_command => ["", "A command to run after every agent run. If this command returns a non-zero return code, the entire Puppet run will be considered to have failed, even though it might have performed work during the normal run."] ) hostname = Facter["hostname"].value domain = Facter["domain"].value if domain and domain != "" fqdn = [hostname, domain].join(".") else fqdn = hostname end Puppet.setdefaults(:main, # We have to downcase the fqdn, because the current ssl stuff (as oppsed to in master) doesn't have good facilities for # manipulating naming. :certname => {:default => fqdn.downcase, :desc => "The name to use when handling certificates. Defaults to the fully qualified domain name.", :call_on_define => true, # Call our hook with the default value, so we're always downcased :hook => proc { |value| raise(ArgumentError, "Certificate names must be lower case; see #1168") unless value == value.downcase }}, :certdnsnames => ['', "The DNS names on the Server certificate as a colon-separated list. If it's anything other than an empty string, it will be used as an alias in the created certificate. By default, only the server gets an alias set up, and only for 'puppet'."], :certdir => { :default => "$ssldir/certs", :owner => "service", :desc => "The certificate directory." }, :ssldir => { :default => "$confdir/ssl", :mode => 0771, :owner => "service", :desc => "Where SSL certificates are kept." }, :publickeydir => { :default => "$ssldir/public_keys", :owner => "service", :desc => "The public key directory." }, :requestdir => { :default => "$ssldir/certificate_requests", :owner => "service", :desc => "Where host certificate requests are stored." }, :privatekeydir => { :default => "$ssldir/private_keys", :mode => 0750, :owner => "service", :desc => "The private key directory." }, :privatedir => { :default => "$ssldir/private", :mode => 0750, :owner => "service", :desc => "Where the client stores private certificate information." }, :passfile => { :default => "$privatedir/password", :mode => 0640, :owner => "service", :desc => "Where puppetd stores the password for its private key. Generally unused." }, :hostcsr => { :default => "$ssldir/csr_$certname.pem", :mode => 0644, :owner => "service", :desc => "Where individual hosts store and look for their certificate requests." }, :hostcert => { :default => "$certdir/$certname.pem", :mode => 0644, :owner => "service", :desc => "Where individual hosts store and look for their certificates." }, :hostprivkey => { :default => "$privatekeydir/$certname.pem", :mode => 0600, :owner => "service", :desc => "Where individual hosts store and look for their private key." }, :hostpubkey => { :default => "$publickeydir/$certname.pem", :mode => 0644, :owner => "service", :desc => "Where individual hosts store and look for their public key." }, :localcacert => { :default => "$certdir/ca.pem", :mode => 0644, :owner => "service", :desc => "Where each client stores the CA certificate." }, :hostcrl => { :default => "$ssldir/crl.pem", :mode => 0644, :owner => "service", :desc => "Where the host's certificate revocation list can be found. This is distinct from the certificate authority's CRL." } ) setdefaults(:ca, :cadir => { :default => "$ssldir/ca", :owner => "service", :group => "service", :mode => 0770, :desc => "The root directory for the certificate authority." }, :cacert => { :default => "$cadir/ca_crt.pem", :owner => "service", :group => "service", :mode => 0660, :desc => "The CA certificate." }, :cakey => { :default => "$cadir/ca_key.pem", :owner => "service", :group => "service", :mode => 0660, :desc => "The CA private key." }, :capub => { :default => "$cadir/ca_pub.pem", :owner => "service", :group => "service", :desc => "The CA public key." }, :cacrl => { :default => "$cadir/ca_crl.pem", :owner => "service", :group => "service", :mode => 0664, :desc => "The certificate revocation list (CRL) for the CA. Will be used if present but otherwise ignored.", :hook => proc do |value| if value == 'false' Puppet.warning "Setting the :cacrl to 'false' is deprecated; Puppet will just ignore the crl if yours is missing" end end }, :caprivatedir => { :default => "$cadir/private", :owner => "service", :group => "service", :mode => 0770, :desc => "Where the CA stores private certificate information." }, :csrdir => { :default => "$cadir/requests", :owner => "service", :group => "service", :desc => "Where the CA stores certificate requests" }, :signeddir => { :default => "$cadir/signed", :owner => "service", :group => "service", :mode => 0770, :desc => "Where the CA stores signed certificates." }, :capass => { :default => "$caprivatedir/ca.pass", :owner => "service", :group => "service", :mode => 0660, :desc => "Where the CA stores the password for the private key" }, :serial => { :default => "$cadir/serial", :owner => "service", :group => "service", :mode => 0644, :desc => "Where the serial number for certificates is stored." }, :autosign => { :default => "$confdir/autosign.conf", :mode => 0644, :desc => "Whether to enable autosign. Valid values are true (which autosigns any key request, and is a very bad idea), false (which never autosigns any key request), and the path to a file, which uses that configuration file to determine which keys to sign."}, :ca_days => ["", "How long a certificate should be valid. This parameter is deprecated, use ca_ttl instead"], :ca_ttl => ["5y", "The default TTL for new certificates; valid values must be an integer, optionally followed by one of the units 'y' (years of 365 days), 'd' (days), 'h' (hours), or 's' (seconds). The unit defaults to seconds. If this parameter is set, ca_days is ignored. Examples are '3600' (one hour) and '1825d', which is the same as '5y' (5 years) "], :ca_md => ["md5", "The type of hash used in certificates."], :req_bits => [2048, "The bit length of the certificates."], :keylength => [1024, "The bit length of keys."], :cert_inventory => { :default => "$cadir/inventory.txt", :mode => 0644, :owner => "service", :group => "service", :desc => "A Complete listing of all certificates" } ) # Define the config default. self.setdefaults(self.settings[:name], :config => ["$confdir/puppet.conf", "The configuration file for #{Puppet[:name]}."], :pidfile => ["$rundir/$name.pid", "The pid file"], :bindaddress => ["", "The address a listening server should bind to. Mongrel servers default to 127.0.0.1 and WEBrick defaults to 0.0.0.0."], :servertype => {:default => "webrick", :desc => "The type of server to use. Currently supported options are webrick and mongrel. If you use mongrel, you will need a proxy in front of the process or processes, since Mongrel cannot speak SSL.", :call_on_define => true, # Call our hook with the default value, so we always get the correct bind address set. :hook => proc { |value| value == "webrick" ? Puppet.settings[:bindaddress] = "0.0.0.0" : Puppet.settings[:bindaddress] = "127.0.0.1" if Puppet.settings[:bindaddress] == "" } } ) 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."], :code => ["", "Code to parse directly. This is essentially only used by ``puppet``, and should only be set if you're writing your own Puppet executable"], :masterlog => { :default => "$logdir/puppetmaster.log", :owner => "service", :group => "service", :mode => 0660, :desc => "Where puppetmasterd logs. This is generally not used, since syslog is the default log destination." }, :masterhttplog => { :default => "$logdir/masterhttp.log", :owner => "service", :group => "service", :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', 'fqdn' and 'domain' facts 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)"], :bucketdir => { :default => "$vardir/bucket", :mode => 0750, :owner => "service", :group => "service", :desc => "Where FileBucket files are stored." }, :rest_authconfig => [ "$confdir/auth.conf", "The configuration file that defines the rights to the different rest indirections. This can be used as a fine-grained authorization system for ``puppetmasterd``." ], :ca => [true, "Wether the master should function as a certificate authority."], :modulepath => {:default => "$confdir/modules:/usr/share/puppet/modules", :desc => "The search path for modules as a colon-separated list of directories.", :type => :setting }, # We don't want this to be considered a file, since it's multiple files. :ssl_client_header => ["HTTP_X_CLIENT_DN", "The header containing an authenticated client's SSL DN. Only used with Mongrel. This header must be set by the proxy - to the authenticated client's SSL DN (e.g., ``/CN=puppet.reductivelabs.com``). - See http://reductivelabs.com/puppet/trac/wiki/UsingMongrel for more information."], + to the authenticated client's SSL DN (e.g., ``/CN=puppet.puppetlabs.com``). + See http://puppetlabs.com/puppet/trac/wiki/UsingMongrel for more information."], :ssl_client_verify_header => ["HTTP_X_CLIENT_VERIFY", "The header containing the status message of the client verification. Only used with Mongrel. This header must be set by the proxy to 'SUCCESS' if the client successfully authenticated, and anything else otherwise. - See http://reductivelabs.com/puppet/trac/wiki/UsingMongrel for more information."], + See http://puppetlabs.com/puppet/trac/wiki/UsingMongrel for more information."], # To make sure this directory is created before we try to use it on the server, we need # it to be in the server section (#1138). :yamldir => {:default => "$vardir/yaml", :owner => "service", :group => "service", :mode => "750", :desc => "The directory in which YAML data is stored, usually in a subdirectory."}, :reports => ["store", "The list of reports to generate. All reports are looked for in puppet/reports/.rb, and multiple report names should be comma-separated (whitespace is okay)." ], :reportdir => {:default => "$vardir/reports", :mode => 0750, :owner => "service", :group => "service", :desc => "The directory in which to store reports received from the client. Each client gets a separate subdirectory."}, :fileserverconfig => ["$confdir/fileserver.conf", "Where the fileserver configuration is stored."], :rrddir => {:default => "$vardir/rrd", :owner => "service", :group => "service", :desc => "The directory where RRD database files are stored. Directories for each reporting host will be created under this directory." }, :rrdinterval => ["$runinterval", "How often RRD should expect data. This should match how often the hosts report back to the server."], :strict_hostname_checking => [false, "Whether to only search for the complete hostname as it is in the certificate when searching for node information in the catalogs."] ) self.setdefaults(:puppetd, :localconfig => { :default => "$statedir/localconfig", :owner => "root", :mode => 0660, :desc => "Where puppetd caches the local configuration. An extension indicating the cache format is added automatically."}, :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." }, :clientyamldir => {:default => "$vardir/client_yaml", :mode => "750", :desc => "The directory in which client-side YAML data is stored."}, :classfile => { :default => "$statedir/classes.txt", :owner => "root", :mode => 0644, :desc => "The file in which puppetd stores a list of the classes associated with the retrieved configuration. 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." }, :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."], :listen => [false, "Whether puppetd should listen for connections. If this is true, then by default only the ``runner`` server is started, which allows remote authorized and authenticated nodes to connect and trigger ``puppetd`` runs."], :ca_server => ["$server", "The server to use for certificate authority requests. It's a separate server because it cannot and does not need to horizontally scale."], :ca_port => ["$masterport", "The port to use for the certificate authority."], :catalog_format => { :default => "", :desc => "(Deprecated for 'preferred_serialization_format') What format to use to dump the catalog. Only supports 'marshal' and 'yaml'. Only matters on the client, since it asks the server for a specific format.", :hook => proc { |value| if value Puppet.warning "Setting 'catalog_format' is deprecated; use 'preferred_serialization_format' instead." Puppet.settings[:preferred_serialization_format] = value end } }, :preferred_serialization_format => ["pson", "The preferred means of serializing ruby instances for passing over the wire. This won't guarantee that all instances will be serialized using this method, since not all classes can be guaranteed to support this format, but it will be used for all classes that support it."], :puppetdlockfile => [ "$statedir/puppetdlock", "A lock file to temporarily stop puppetd from doing anything."], :usecacheonfailure => [true, "Whether to use the cached configuration when the remote configuration will not compile. This option is useful for testing new configurations, where you want to fix the broken configuration rather than reverting to a known-good one." ], :use_cached_catalog => [false, "Whether to only use the cached catalog rather than compiling a new catalog on every run. Puppet can be run with this enabled by default and then selectively disabled when a recompile is desired."], :ignorecache => [false, "Ignore cache and always recompile the configuration. This is useful for testing new configurations, where the local cache may in fact be stale even if the timestamps are up to date - if the facts change or if the server changes." ], :downcasefacts => [false, "Whether facts should be made all lowercase when sent to the server."], :dynamicfacts => ["memorysize,memoryfree,swapsize,swapfree", "Facts that are dynamic; these facts will be ignored when deciding whether changed facts should result in a recompile. Multiple facts should be comma-separated."], :splaylimit => ["$runinterval", "The maximum time to delay before runs. Defaults to being the same as the run interval."], :splay => [false, "Whether to sleep for a pseudo-random (but consistent) amount of time before a run."], :clientbucketdir => { :default => "$vardir/clientbucket", :mode => 0750, :desc => "Where FileBucket files are stored locally." }, :configtimeout => [120, "How long the client should wait for the configuration to be retrieved before considering it a failure. This can help reduce flapping if too many clients contact the server at one time." ], :reportserver => { :default => "$server", :call_on_define => false, :desc => "(Deprecated for 'report_server') The server to which to send transaction reports.", :hook => proc do |value| if value Puppet.settings[:report_server] = value end end }, :report_server => ["$server", "The server to which to send transaction reports." ], :report_port => ["$masterport", "The port to communicate with the report_server." ], :report => [false, "Whether to send reports after every transaction." ], :graph => [false, "Whether to create dot graph files for the different configuration graphs. These dot files can be interpreted by tools like OmniGraffle or dot (which is part of ImageMagick)."], :graphdir => ["$statedir/graphs", "Where to store dot-outputted graphs."] ) # Plugin information. self.setdefaults(:main, :plugindest => ["$libdir", "Where Puppet should store plugins that it pulls down from the central server."], :pluginsource => ["puppet://$server/plugins", "From where to retrieve plugins. The standard Puppet ``file`` type is used for retrieval, so anything that is a valid file source can be used here."], :pluginsync => [false, "Whether plugins should be synced with the central server."], :pluginsignore => [".svn CVS .git", "What files to ignore when pulling down plugins."] ) # Central fact information. self.setdefaults(:main, :factpath => {:default => "$vardir/facts/", :desc => "Where Puppet should look for facts. Multiple directories should be colon-separated, like normal PATH variables.", :call_on_define => true, # Call our hook with the default value, so we always get the value added to facter. :type => :setting, # Don't consider it a file, because it could be multiple colon-separated files :hook => proc { |value| Facter.search(value) if Facter.respond_to?(:search) }}, :factdest => ["$vardir/facts/", "Where Puppet should store facts that it pulls down from the central server."], :factsource => ["puppet://$server/facts/", "From where to retrieve facts. The standard Puppet ``file`` type is used for retrieval, so anything that is a valid file source can be used here."], :factsync => [false, "Whether facts should be synced with the central server."], :factsignore => [".svn CVS", "What files to ignore when pulling down facts."] ) self.setdefaults(:tagmail, :tagmap => ["$confdir/tagmail.conf", "The mapping between reporting tags and email addresses."], :sendmail => [%x{which sendmail 2>/dev/null}.chomp, "Where to find the sendmail binary with which to send email."], :reportfrom => ["report@" + [Facter["hostname"].value, Facter["domain"].value].join("."), "The 'from' email address for the reports."], :smtpserver => ["none", "The server through which to send email reports."] ) self.setdefaults(:rails, :dblocation => { :default => "$statedir/clientconfigs.sqlite3", :mode => 0660, :owner => "service", :group => "service", :desc => "The database cache for client configurations. Used for querying within the language." }, :dbadapter => [ "sqlite3", "The type of database to use." ], :dbmigrate => [ false, "Whether to automatically migrate the database." ], :dbname => [ "puppet", "The name of the database to use." ], :dbserver => [ "localhost", "The database server for Client caching. Only used when networked databases are used."], :dbuser => [ "puppet", "The database user for Client caching. Only used when networked databases are used."], :dbpassword => [ "puppet", "The database password for Client caching. Only used when networked databases are used."], :dbsocket => [ "", "The database socket location. Only used when networked databases are used. Will be ignored if the value is an empty string."], :railslog => {:default => "$logdir/rails.log", :mode => 0600, :owner => "service", :group => "service", :desc => "Where Rails-specific logs are sent" }, :rails_loglevel => ["info", "The log level for Rails connections. The value must be a valid log level within Rails. Production environments normally use ``info`` and other environments normally use ``debug``."] ) setdefaults(:transaction, :tags => ["", "Tags to use to find resources. If this is set, then only resources tagged with the specified tags will be applied. Values must be comma-separated."], :evaltrace => [false, "Whether each resource should log when it is being evaluated. This allows you to interactively see exactly what is being done."], :summarize => [false, "Whether to print a transaction summary." ] ) setdefaults(:parser, :typecheck => [true, "Whether to validate types during parsing."], :paramcheck => [true, "Whether to validate parameters during parsing."] ) setdefaults(:main, :casesensitive => [false, "Whether matching in case statements and selectors should be case-sensitive. Case insensitivity is handled by downcasing all values before comparison."], :external_nodes => ["none", "An external command that can produce node information. The output must be a YAML dump of a hash, and that hash must have one or both of ``classes`` and ``parameters``, where ``classes`` is an array and ``parameters`` is a hash. For unknown nodes, the commands should exit with a non-zero exit code. This command makes it straightforward to store your node mapping information in other data sources like databases."]) setdefaults(:ldap, :ldapnodes => [false, "Whether to search for node configurations in LDAP. See - http://reductivelabs.com/trac/puppet/wiki/LDAPNodes for more information."], + http://puppetlabs.com/trac/puppet/wiki/LDAPNodes for more information."], :ldapssl => [false, "Whether SSL should be used when searching for nodes. Defaults to false because SSL usually requires certificates to be set up on the client side."], :ldaptls => [false, "Whether TLS should be used when searching for nodes. Defaults to false because TLS usually requires certificates to be set up on the client side."], :ldapserver => ["ldap", "The LDAP server. Only used if ``ldapnodes`` is enabled."], :ldapport => [389, "The LDAP port. Only used if ``ldapnodes`` is enabled."], :ldapstring => ["(&(objectclass=puppetClient)(cn=%s))", "The search string used to find an LDAP node."], :ldapclassattrs => ["puppetclass", "The LDAP attributes to use to define Puppet classes. Values should be comma-separated."], :ldapstackedattrs => ["puppetvar", "The LDAP attributes that should be stacked to arrays by adding the values in all hierarchy elements of the tree. Values should be comma-separated."], :ldapattrs => ["all", "The LDAP attributes to include when querying LDAP for nodes. All returned attributes are set as variables in the top-level scope. Multiple values should be comma-separated. The value 'all' returns all attributes."], :ldapparentattr => ["parentnode", "The attribute to use to define the parent node."], :ldapuser => ["", "The user to use to connect to LDAP. Must be specified as a full DN."], :ldappassword => ["", "The password to use to connect to LDAP."], :ldapbase => ["", "The search base for LDAP searches. It's impossible to provide a meaningful default here, although the LDAP libraries might have one already set. Generally, it should be the 'ou=Hosts' branch under your main directory."] ) setdefaults(:puppetmasterd, :storeconfigs => {:default => false, :desc => "Whether to store each client's configuration. This requires ActiveRecord from Ruby on Rails.", :call_on_define => true, # Call our hook with the default value, so we always get the libdir set. :hook => proc do |value| require 'puppet/node' require 'puppet/node/facts' require 'puppet/resource/catalog' if value raise "StoreConfigs not supported without ActiveRecord 2.1 or higher" unless Puppet.features.rails? Puppet::Resource::Catalog.cache_class = :active_record unless Puppet.settings[:async_storeconfigs] Puppet::Node::Facts.cache_class = :active_record Puppet::Node.cache_class = :active_record end end } ) # This doesn't actually work right now. setdefaults(:parser, :lexical => [false, "Whether to use lexical scoping (vs. dynamic)."], :templatedir => ["$vardir/templates", "Where Puppet looks for template files. Can be a list of colon-seperated directories." ] ) end diff --git a/lib/puppet/network/authstore.rb b/lib/puppet/network/authstore.rb index a7029a0a0..d5ba3ef78 100755 --- a/lib/puppet/network/authstore.rb +++ b/lib/puppet/network/authstore.rb @@ -1,256 +1,256 @@ # standard module for determining whether a given hostname or IP has access to # the requested resource require 'ipaddr' require 'puppet/util/logging' module Puppet class AuthStoreError < Puppet::Error; end class AuthorizationError < Puppet::Error; end class Network::AuthStore include Puppet::Util::Logging # Mark a given pattern as allowed. def allow(pattern) # a simple way to allow anyone at all to connect if pattern == "*" @globalallow = true else store(:allow, pattern) end return nil end # Is a given combination of name and ip address allowed? If either input # is non-nil, then both inputs must be provided. If neither input # is provided, then the authstore is considered local and defaults to "true". def allowed?(name, ip) if name or ip # This is probably unnecessary, and can cause some weirdnesses in # cases where we're operating over localhost but don't have a real # IP defined. unless name and ip raise Puppet::DevError, "Name and IP must be passed to 'allowed?'" end # else, we're networked and such else # we're local return true end # yay insecure overrides if globalallow? return true end if decl = declarations.find { |d| d.match?(name, ip) } return decl.result end info "defaulting to no access for %s" % name return false end # Deny a given pattern. def deny(pattern) store(:deny, pattern) end # Is global allow enabled? def globalallow? @globalallow end # does this auth store has any rules? def empty? @globalallow.nil? && @declarations.size == 0 end def initialize @globalallow = nil @declarations = [] end def to_s "authstore" end def interpolate(match) Thread.current[:declarations] = @declarations.collect { |ace| ace.interpolate(match) }.sort end def reset_interpolation Thread.current[:declarations] = nil end private # returns our ACEs list, but if we have a modification of it # in our current thread, let's return it # this is used if we want to override the this purely immutable list # by a modified version in a multithread safe way. def declarations Thread.current[:declarations] || @declarations end # Store the results of a pattern into our hash. Basically just # converts the pattern and sticks it into the hash. def store(type, pattern) @declarations << Declaration.new(type, pattern) @declarations.sort! return nil end # A single declaration. Stores the info for a given declaration, # provides the methods for determining whether a declaration matches, # and handles sorting the declarations appropriately. class Declaration include Puppet::Util include Comparable # The type of declaration: either :allow or :deny attr_reader :type # The name: :ip or :domain attr_accessor :name # The pattern we're matching against. Can be an IPAddr instance, # or an array of strings, resulting from reversing a hostname # or domain name. attr_reader :pattern # The length. Only used for iprange and domain. attr_accessor :length # Sort the declarations most specific first. def <=>(other) compare(exact?, other.exact?) || compare(ip?, other.ip?) || ((length != other.length) && (other.length <=> length)) || compare(deny?, other.deny?) || ( ip? ? pattern.to_s <=> other.pattern.to_s : pattern <=> other.pattern) end def deny? type == :deny end def exact? @exact == :exact end def initialize(type, pattern) self.type = type self.pattern = pattern end # Are we an IP type? def ip? name == :ip end # Does this declaration match the name/ip combo? def match?(name, ip) ip? ? pattern.include?(IPAddr.new(ip)) : matchname?(name) end # Set the pattern appropriately. Also sets the name and length. def pattern=(pattern) parse(pattern) @orig = pattern end # Mapping a type of statement into a return value. def result type == :allow end def to_s "#{type}: #{pattern}" end # Set the declaration type. Either :allow or :deny. def type=(type) type = symbolize(type) unless [:allow, :deny].include?(type) raise ArgumentError, "Invalid declaration type %s" % type end @type = type end # interpolate a pattern to replace any # backreferences by the given match - # for instance if our pattern is $1.reductivelabs.com + # for instance if our pattern is $1.puppetlabs.com # and we're called with a MatchData whose capture 1 is puppet - # we'll return a pattern of puppet.reductivelabs.com + # we'll return a pattern of puppet.puppetlabs.com def interpolate(match) clone = dup clone.pattern = clone.pattern.reverse.collect do |p| p.gsub(/\$(\d)/) { |m| match[$1.to_i] } end.join(".") clone end private # Returns nil if both values are true or both are false, returns # -1 if the first is true, and 1 if the second is true. Used # in the <=> operator. def compare(me, them) (me and them) ? nil : me ? -1 : them ? 1 : nil end # Does the name match our pattern? def matchname?(name) name = munge_name(name) (pattern == name) or (not exact? and pattern.zip(name).all? { |p,n| p == n }) end # Convert the name to a common pattern. def munge_name(name) # LAK:NOTE http://snurl.com/21zf8 [groups_google_com] # Change to name.downcase.split(".",-1).reverse for FQDN support name.downcase.split(".").reverse end # Parse our input pattern and figure out what kind of allowal # statement it is. The output of this is used for later matching. Octet = '(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])' IPv4 = "#{Octet}\.#{Octet}\.#{Octet}\.#{Octet}" IPv6_full = "_:_:_:_:_:_:_:_|_:_:_:_:_:_::_?|_:_:_:_:_::((_:)?_)?|_:_:_:_::((_:){0,2}_)?|_:_:_::((_:){0,3}_)?|_:_::((_:){0,4}_)?|_::((_:){0,5}_)?|::((_:){0,6}_)?" IPv6_partial = "_:_:_:_:_:_:|_:_:_:_::(_:)?|_:_::(_:){0,2}|_::(_:){0,3}" # It should be: # IP = "#{IPv4}|#{IPv6_full}|(#{IPv6_partial}#{IPv4})".gsub(/_/,'([0-9a-fA-F]{1,4})').gsub(/\(/,'(?:') # but ruby's ipaddr lib doesn't support the hybrid format IP = "#{IPv4}|#{IPv6_full}".gsub(/_/,'([0-9a-fA-F]{1,4})').gsub(/\(/,'(?:') def parse(value) @name,@exact,@length,@pattern = *case value when /^(?:#{IP})\/(\d+)$/ # 12.34.56.78/24, a001:b002::efff/120, c444:1000:2000::9:192.168.0.1/112 [:ip,:inexact,$1.to_i,IPAddr.new(value)] when /^(#{IP})$/ # 10.20.30.40, [:ip,:exact,nil,IPAddr.new(value)] when /^(#{Octet}\.){1,3}\*$/ # an ip address with a '*' at the end segments = value.split(".")[0..-2] bits = 8*segments.length [:ip,:inexact,bits,IPAddr.new((segments+[0,0,0])[0,4].join(".") + "/#{bits}")] when /^(\w[-\w]*\.)+[-\w]+$/ # a full hostname # Change to /^(\w[-\w]*\.)+[-\w]+\.?$/ for FQDN support [:domain,:exact,nil,munge_name(value)] when /^\*(\.(\w[-\w]*)){1,}$/ # *.domain.com host_sans_star = munge_name(value)[0..-2] [:domain,:inexact,host_sans_star.length,host_sans_star] - when /\$\d+/ # a backreference pattern ala $1.reductivelabs.com or 192.168.0.$1 or $1.$2 + when /\$\d+/ # a backreference pattern ala $1.puppetlabs.com or 192.168.0.$1 or $1.$2 [:dynamic,:exact,nil,munge_name(value)] when /^\w[-.@\w]*$/ # ? Just like a host name but allow '@'s and ending '.'s [:opaque,:exact,nil,[value]] else raise AuthStoreError, "Invalid pattern %s" % value end end end end end diff --git a/lib/puppet/provider/macauthorization/macauthorization.rb b/lib/puppet/provider/macauthorization/macauthorization.rb index d1e2b229f..bc2dfb176 100644 --- a/lib/puppet/provider/macauthorization/macauthorization.rb +++ b/lib/puppet/provider/macauthorization/macauthorization.rb @@ -1,322 +1,322 @@ require 'facter' require 'facter/util/plist' require 'puppet' require 'tempfile' Puppet::Type.type(:macauthorization).provide :macauthorization, :parent => Puppet::Provider do desc "Manage Mac OS X authorization database rules and rights. " commands :security => "/usr/bin/security" commands :sw_vers => "/usr/bin/sw_vers" confine :operatingsystem => :darwin # This should be confined based on macosx_productversion once - # http://projects.reductivelabs.com/issues/show/1796 + # http://projects.puppetlabs.com/issues/show/1796 # is resolved. if FileTest.exists?("/usr/bin/sw_vers") product_version = sw_vers "-productVersion" confine :true => if /^10.5/.match(product_version) or /^10.6/.match(product_version) true end end defaultfor :operatingsystem => :darwin AuthDB = "/etc/authorization" @rights = {} @rules = {} @parsed_auth_db = {} @comment = "" # Not implemented yet. Is there any real need to? # This map exists due to the use of hyphens and reserved words in # the authorization schema. PuppetToNativeAttributeMap = { :allow_root => "allow-root", :authenticate_user => "authenticate-user", :auth_class => "class", :k_of_n => "k-of-n", :session_owner => "session-owner", } class << self attr_accessor :parsed_auth_db attr_accessor :rights attr_accessor :rules attr_accessor :comments # Not implemented yet. def prefetch(resources) self.populate_rules_rights end def instances if self.parsed_auth_db == {} self.prefetch(nil) end self.parsed_auth_db.collect do |k,v| new(:name => k) end end def populate_rules_rights auth_plist = Plist::parse_xml(AuthDB) if not auth_plist raise Puppet::Error.new("Cannot parse: #{AuthDB}") end self.rights = auth_plist["rights"].dup self.rules = auth_plist["rules"].dup self.parsed_auth_db = self.rights.dup self.parsed_auth_db.merge!(self.rules.dup) end end # standard required provider instance methods def initialize(resource) if self.class.parsed_auth_db == {} self.class.prefetch(resource) end super end def create # we just fill the @property_hash in here and let the flush method # deal with it rather than repeating code. new_values = {} validprops = Puppet::Type.type(resource.class.name).validproperties validprops.each do |prop| next if prop == :ensure if value = resource.should(prop) and value != "" new_values[prop] = value end end @property_hash = new_values.dup end def destroy # We explicitly delete here rather than in the flush method. case resource[:auth_type] when :right destroy_right when :rule destroy_rule else raise Puppet::Error.new("Must specify auth_type when destroying.") end end def exists? if self.class.parsed_auth_db.has_key?(resource[:name]) return true else return false end end def flush # deletion happens in the destroy methods if resource[:ensure] != :absent case resource[:auth_type] when :right flush_right when :rule flush_rule else raise Puppet::Error.new("flush requested for unknown type.") end @property_hash.clear end end # utility methods below def destroy_right security "authorizationdb", :remove, resource[:name] end def destroy_rule authdb = Plist::parse_xml(AuthDB) authdb_rules = authdb["rules"].dup if authdb_rules[resource[:name]] begin authdb["rules"].delete(resource[:name]) Plist::Emit.save_plist(authdb, AuthDB) rescue Errno::EACCES => e raise Puppet::Error.new("Error saving #{AuthDB}: #{e}") end end end def flush_right # first we re-read the right just to make sure we're in sync for # values that weren't specified in the manifest. As we're supplying # the whole plist when specifying the right it seems safest to be # paranoid given the low cost of quering the db once more. cmds = [] cmds << :security << "authorizationdb" << "read" << resource[:name] output = execute(cmds, :combine => false) current_values = Plist::parse_xml(output) if current_values.nil? current_values = {} end specified_values = convert_plist_to_native_attributes(@property_hash) # take the current values, merge the specified values to obtain a # complete description of the new values. new_values = current_values.merge(specified_values) set_right(resource[:name], new_values) end def flush_rule authdb = Plist::parse_xml(AuthDB) authdb_rules = authdb["rules"].dup current_values = {} if authdb_rules[resource[:name]] current_values = authdb_rules[resource[:name]] end specified_values = convert_plist_to_native_attributes(@property_hash) new_values = current_values.merge(specified_values) set_rule(resource[:name], new_values) end def set_right(name, values) # Both creates and modifies rights as it simply overwrites them. # The security binary only allows for writes using stdin, so we # dump the values to a tempfile. values = convert_plist_to_native_attributes(values) tmp = Tempfile.new('puppet_macauthorization') begin Plist::Emit.save_plist(values, tmp.path) cmds = [] cmds << :security << "authorizationdb" << "write" << name output = execute(cmds, :combine => false, :stdinfile => tmp.path.to_s) rescue Errno::EACCES => e raise Puppet::Error.new("Cannot save right to #{tmp.path}: #{e}") ensure tmp.close tmp.unlink end end def set_rule(name, values) # Both creates and modifies rules as it overwrites the entry in the # rules dictionary. Unfortunately the security binary doesn't # support modifying rules at all so we have to twiddle the whole # plist... :( See Apple Bug #6386000 values = convert_plist_to_native_attributes(values) authdb = Plist::parse_xml(AuthDB) authdb["rules"][name] = values begin Plist::Emit.save_plist(authdb, AuthDB) rescue raise Puppet::Error.new("Error writing to: #{AuthDB}") end end def convert_plist_to_native_attributes(propertylist) # This mainly converts the keys from the puppet attributes to the # 'native' ones, but also enforces that the keys are all Strings # rather than Symbols so that any merges of the resultant Hash are # sane. The exception is booleans, where we coerce to a proper bool # if they come in as a symbol. newplist = {} propertylist.each_pair do |key, value| next if key == :ensure # not part of the auth db schema. next if key == :auth_type # not part of the auth db schema. case value when true, :true value = true when false, :false value = false end new_key = key if PuppetToNativeAttributeMap.has_key?(key) new_key = PuppetToNativeAttributeMap[key].to_s elsif not key.is_a?(String) new_key = key.to_s end newplist[new_key] = value end newplist end def retrieve_value(resource_name, attribute) # We set boolean values to symbols when retrieving values if not self.class.parsed_auth_db.has_key?(resource_name) raise Puppet::Error.new("Cannot find #{resource_name} in auth db") end if PuppetToNativeAttributeMap.has_key?(attribute) native_attribute = PuppetToNativeAttributeMap[attribute] else native_attribute = attribute.to_s end if self.class.parsed_auth_db[resource_name].has_key?(native_attribute) value = self.class.parsed_auth_db[resource_name][native_attribute] case value when true, :true value = :true when false, :false value = :false end @property_hash[attribute] = value return value else @property_hash.delete(attribute) return "" # so ralsh doesn't display it. end end # property methods below # # We define them all dynamically apart from auth_type which is a special # case due to not being in the actual authorization db schema. properties = [ :allow_root, :authenticate_user, :auth_class, :comment, :group, :k_of_n, :mechanisms, :rule, :session_owner, :shared, :timeout, :tries ] properties.each do |field| define_method(field.to_s) do retrieve_value(resource[:name], field) end define_method(field.to_s + "=") do |value| @property_hash[field] = value end end def auth_type if resource.should(:auth_type) != nil return resource.should(:auth_type) elsif self.exists? # this is here just for ralsh, so it can work out what type it is. if self.class.rights.has_key?(resource[:name]) return :right elsif self.class.rules.has_key?(resource[:name]) return :rule else raise Puppet::Error.new("#{resource[:name]} is unknown type.") end else raise Puppet::Error.new("auth_type required for new resources.") end end def auth_type=(value) @property_hash[:auth_type] = value end end diff --git a/lib/puppet/provider/service/debian.rb b/lib/puppet/provider/service/debian.rb index 51fb7a22b..1f9dc5ab6 100755 --- a/lib/puppet/provider/service/debian.rb +++ b/lib/puppet/provider/service/debian.rb @@ -1,48 +1,48 @@ # Manage debian services. Start/stop is the same as InitSvc, but enable/disable # is special. Puppet::Type.type(:service).provide :debian, :parent => :init do desc "Debian's form of ``init``-style management. The only difference is that this supports service enabling and disabling via ``update-rc.d`` and determines enabled status via ``invoke-rc.d``. " commands :update_rc => "/usr/sbin/update-rc.d" # note this isn't being used as a command until - # http://projects.reductivelabs.com/issues/2538 + # http://projects.puppetlabs.com/issues/2538 # is resolved. commands :invoke_rc => "/usr/sbin/invoke-rc.d" defaultfor :operatingsystem => [:debian, :ubuntu] def self.defpath superclass.defpath end # Remove the symlinks def disable update_rc "-f", @resource[:name], "remove" update_rc @resource[:name], "stop", "00", "1", "2", "3", "4", "5", "6", "." end def enabled? # TODO: Replace system() call when Puppet::Util.execute gives us a way - # to determine exit status. http://projects.reductivelabs.com/issues/2538 + # to determine exit status. http://projects.puppetlabs.com/issues/2538 system("/usr/sbin/invoke-rc.d", "--quiet", "--query", @resource[:name], "start") # 104 is the exit status when you query start an enabled service. # 106 is the exit status when the policy layer supplies a fallback action # See x-man-page://invoke-rc.d if [104, 106].include?($?.exitstatus) return :true else return :false end end def enable update_rc "-f", @resource[:name], "remove" update_rc @resource[:name], "defaults" end end diff --git a/lib/puppet/reference/providers.rb b/lib/puppet/reference/providers.rb index d425d803e..884e34f7e 100644 --- a/lib/puppet/reference/providers.rb +++ b/lib/puppet/reference/providers.rb @@ -1,124 +1,124 @@ # This doesn't get stored in trac, since it changes every time. providers = Puppet::Util::Reference.newreference :providers, :title => "Provider Suitability Report", :depth => 1, :dynamic => true, :doc => "Which providers are valid for this machine" do types = [] Puppet::Type.loadall Puppet::Type.eachtype do |klass| next unless klass.providers.length > 0 types << klass end types.sort! { |a,b| a.name.to_s <=> b.name.to_s } unless ARGV.empty? types.reject! { |type| ! ARGV.include?(type.name.to_s) } end ret = "Details about this host:\n\n" # Throw some facts in there, so we know where the report is from. ["Ruby Version", "Puppet Version", "Operating System", "Operating System Release"].each do |label| name = label.gsub(/\s+/, '') value = Facter.value(name) ret += option(label, value) end ret += "\n" count = 1 # Produce output for each type. types.each do |type| features = type.features ret += "\n" # add a trailing newline # Now build up a table of provider suitability. headers = %w{Provider Suitable?} + features.collect { |f| f.to_s }.sort table_data = {} functional = false notes = [] begin default = type.defaultprovider.name rescue Puppet::DevError default = "none" end type.providers.sort { |a,b| a.to_s <=> b.to_s }.each do |pname| data = [] table_data[pname] = data provider = type.provider(pname) # Add the suitability note if missing = provider.suitable?(false) and missing.empty? data << "**X**" suit = true functional = true else data << "[%s]_" % [count] # A pointer to the appropriate footnote suit = false end # Add a footnote with the details about why this provider is unsuitable, if that's the case unless suit details = ".. [%s]\n" % count missing.each do |test, values| case test when :exists details += " - Missing files %s\n" % values.join(", ") when :variable values.each do |name, facts| if Puppet.settings.valid?(name) details += " - Setting %s (currently %s) not in list %s\n" % [name, Puppet.settings.value(name).inspect, facts.join(", ")] else details += " - Fact %s (currently %s) not in list %s\n" % [name, Facter.value(name).inspect, facts.join(", ")] end end when :true details += " - Got %s true tests that should have been false\n" % values when :false details += " - Got %s false tests that should have been true\n" % values when :feature details += " - Missing features %s\n" % values.collect { |f| f.to_s }.join(",") end end notes << details count += 1 end # Add a note for every feature features.each do |feature| if provider.features.include?(feature) data << "**X**" else data << "" end end end ret += h(type.name.to_s + "_", 2) - ret += ".. _%s: %s\n\n" % [type.name, "http://reductivelabs.com/trac/puppet/wiki/TypeReference#%s" % type.name] + ret += ".. _%s: %s\n\n" % [type.name, "http://puppetlabs.com/trac/puppet/wiki/TypeReference#%s" % type.name] ret += option("Default provider", default) ret += doctable(headers, table_data) notes.each do |note| ret += note + "\n" end ret += "\n" end ret += "\n" ret end providers.header = " Puppet resource types are usually backed by multiple implementations called ``providers``, which handle variance between platforms and tools. Different providers are suitable or unsuitable on different platforms based on things like the presence of a given tool. Here are all of the provider-backed types and their different providers. Any unmentioned types do not use providers yet. " diff --git a/lib/puppet/type/exec.rb b/lib/puppet/type/exec.rb index a68bfb189..64b6f2d39 100755 --- a/lib/puppet/type/exec.rb +++ b/lib/puppet/type/exec.rb @@ -1,624 +1,624 @@ module Puppet newtype(:exec) do include Puppet::Util::Execution require 'timeout' @doc = "Executes external commands. It is critical that all commands executed using this mechanism can be run multiple times without harm, i.e., they are *idempotent*. One useful way to create idempotent commands is to use the checks like ``creates`` to avoid running the command unless some condition is met. Note also that you can restrict an ``exec`` to only run when it receives events by using the ``refreshonly`` parameter; this is a useful way to have your configuration respond to events with arbitrary commands. It is worth noting that ``exec`` is special, in that it is not currently considered an error to have multiple ``exec`` instances with the same name. This was done purely because it had to be this way in order to get certain functionality, but it complicates things. In particular, you will not be able to use ``exec`` instances that share their commands with other instances as a dependency, since Puppet has no way of knowing which instance you mean. For example:: # defined in the production class exec { \"make\": cwd => \"/prod/build/dir\", path => \"/usr/bin:/usr/sbin:/bin\" } . etc. . # defined in the test class exec { \"make\": cwd => \"/test/build/dir\", path => \"/usr/bin:/usr/sbin:/bin\" } Any other type would throw an error, complaining that you had the same instance being managed in multiple places, but these are obviously different images, so ``exec`` had to be treated specially. It is recommended to avoid duplicate names whenever possible. Note that if an ``exec`` receives an event from another resource, it will get executed again (or execute the command specified in ``refresh``, if there is one). There is a strong tendency to use ``exec`` to do whatever work Puppet can't already do; while this is obviously acceptable (and unavoidable) in the short term, it is highly recommended to migrate work from ``exec`` to native Puppet types as quickly as possible. If you find that you are doing a lot of work with ``exec``, please at least notify - us at Reductive Labs what you are doing, and hopefully we can work with + us at Puppet Labs what you are doing, and hopefully we can work with you to get a native resource type for the work you are doing." require 'open3' # Create a new check mechanism. It's basically just a parameter that # provides one extra 'check' method. def self.newcheck(name, &block) @checks ||= {} check = newparam(name, &block) @checks[name] = check end def self.checks @checks.keys end newproperty(:returns, :array_matching => :all) do |property| include Puppet::Util::Execution munge do |value| value.to_s end defaultto "0" attr_reader :output desc "The expected return code(s). An error will be returned if the executed command returns something else. Defaults to 0. Can be specified as an array of acceptable return codes or a single value." # Make output a bit prettier def change_to_s(currentvalue, newvalue) return "executed successfully" end # First verify that all of our checks pass. def retrieve # Default to somethinng if @resource.check return :notrun else return self.should end end # Actually execute the command. def sync olddir = nil # We need a dir to change to, even if it's just the cwd dir = self.resource[:cwd] || Dir.pwd event = :executed_command begin @output, status = @resource.run(self.resource[:command]) rescue Timeout::Error self.fail "Command exceeded timeout" % value.inspect end if log = @resource[:logoutput] case log when :true log = @resource[:loglevel] when :on_failure if status.exitstatus.to_s != self.should.to_s log = @resource[:loglevel] else log = :false end end unless log == :false @output.split(/\n/).each { |line| self.send(log, line) } end end unless self.should.include?(status.exitstatus.to_s) self.fail("%s returned %s instead of one of [%s]" % [self.resource[:command], status.exitstatus, self.should.join(",")]) end return event end end newparam(:command) do isnamevar desc "The actual command to execute. Must either be fully qualified or a search path for the command must be provided. If the command succeeds, any output produced will be logged at the instance's normal log level (usually ``notice``), but if the command fails (meaning its return code does not match the specified code) then any output is logged at the ``err`` log level." end newparam(:path) do desc "The search path used for command execution. Commands must be fully qualified if no path is specified. Paths can be specified as an array or as a colon-separated list." # Support both arrays and colon-separated fields. def value=(*values) @value = values.flatten.collect { |val| val.split(":") }.flatten end end newparam(:user) do desc "The user to run the command as. Note that if you use this then any error output is not currently captured. This is because of a bug within Ruby. If you are using Puppet to create this user, the exec will automatically require the user, as long as it is specified by name." # Most validation is handled by the SUIDManager class. validate do |user| unless Puppet.features.root? self.fail "Only root can execute commands as other users" end end end newparam(:group) do desc "The group to run the command as. This seems to work quite haphazardly on different platforms -- it is a platform issue not a Ruby or Puppet one, since the same variety exists when running commnands as different users in the shell." # Validation is handled by the SUIDManager class. end newparam(:cwd) do desc "The directory from which to run the command. If this directory does not exist, the command will fail." validate do |dir| unless dir =~ /^#{File::SEPARATOR}/ self.fail("CWD must be a fully qualified path") end end munge do |dir| if dir.is_a?(Array) dir = dir[0] end dir end end newparam(:logoutput) do desc "Whether to log output. Defaults to logging output at the loglevel for the ``exec`` resource. Use *on_failure* to only log the output when the command reports an error. Values are **true**, *false*, *on_failure*, and any legal log level." newvalues(:true, :false, :on_failure) end newparam(:refresh) do desc "How to refresh this command. By default, the exec is just called again when it receives an event from another resource, but this parameter allows you to define a different command for refreshing." validate do |command| @resource.validatecmd(command) end end newparam(:env) do desc "This parameter is deprecated. Use 'environment' instead." munge do |value| warning "'env' is deprecated on exec; use 'environment' instead." resource[:environment] = value end end newparam(:environment) do desc "Any additional environment variables you want to set for a command. Note that if you use this to set PATH, it will override the ``path`` attribute. Multiple environment variables should be specified as an array." validate do |values| values = [values] unless values.is_a? Array values.each do |value| unless value =~ /\w+=/ raise ArgumentError, "Invalid environment setting '%s'" % value end end end end newparam(:timeout) do desc "The maximum time the command should take. If the command takes longer than the timeout, the command is considered to have failed and will be stopped. Use any negative number to disable the timeout. The time is specified in seconds." munge do |value| value = value.shift if value.is_a?(Array) if value.is_a?(String) unless value =~ /^[-\d.]+$/ raise ArgumentError, "The timeout must be a number." end Float(value) else value end end defaultto 300 end newcheck(:refreshonly) do desc "The command should only be run as a refresh mechanism for when a dependent object is changed. It only makes sense to use this option when this command depends on some other object; it is useful for triggering an action:: # Pull down the main aliases file file { \"/etc/aliases\": source => \"puppet://server/module/aliases\" } # Rebuild the database, but only when the file changes exec { newaliases: path => [\"/usr/bin\", \"/usr/sbin\"], subscribe => File[\"/etc/aliases\"], refreshonly => true } Note that only ``subscribe`` and ``notify`` can trigger actions, not ``require``, so it only makes sense to use ``refreshonly`` with ``subscribe`` or ``notify``." newvalues(:true, :false) # We always fail this test, because we're only supposed to run # on refresh. def check(value) # We have to invert the values. if value == :true false else true end end end newcheck(:creates) do desc "A file that this command creates. If this parameter is provided, then the command will only be run if the specified file does not exist:: exec { \"tar xf /my/tar/file.tar\": cwd => \"/var/tmp\", creates => \"/var/tmp/myfile\", path => [\"/usr/bin\", \"/usr/sbin\"] } " # FIXME if they try to set this and fail, then we should probably # fail the entire exec, right? validate do |files| files = [files] unless files.is_a? Array files.each do |file| self.fail("'creates' must be set to a fully qualified path") unless file unless file =~ %r{^#{File::SEPARATOR}} self.fail "'creates' files must be fully qualified." end end end # If the file exists, return false (i.e., don't run the command), # else return true def check(value) return ! FileTest.exists?(value) end end newcheck(:unless) do desc "If this parameter is set, then this ``exec`` will run unless the command returns 0. For example:: exec { \"/bin/echo root >> /usr/lib/cron/cron.allow\": path => \"/usr/bin:/usr/sbin:/bin\", unless => \"grep root /usr/lib/cron/cron.allow 2>/dev/null\" } This would add ``root`` to the cron.allow file (on Solaris) unless ``grep`` determines it's already there. Note that this command follows the same rules as the main command, which is to say that it must be fully qualified if the path is not set. " validate do |cmds| cmds = [cmds] unless cmds.is_a? Array cmds.each do |cmd| @resource.validatecmd(cmd) end end # Return true if the command does not return 0. def check(value) begin output, status = @resource.run(value, true) rescue Timeout::Error err "Check %s exceeded timeout" % value.inspect return false end return status.exitstatus != 0 end end newcheck(:onlyif) do desc "If this parameter is set, then this ``exec`` will only run if the command returns 0. For example:: exec { \"logrotate\": path => \"/usr/bin:/usr/sbin:/bin\", onlyif => \"test `du /var/log/messages | cut -f1` -gt 100000\" } This would run ``logrotate`` only if that test returned true. Note that this command follows the same rules as the main command, which is to say that it must be fully qualified if the path is not set. Also note that onlyif can take an array as its value, eg:: onlyif => [\"test -f /tmp/file1\", \"test -f /tmp/file2\"] This will only run the exec if /all/ conditions in the array return true. " validate do |cmds| cmds = [cmds] unless cmds.is_a? Array cmds.each do |cmd| @resource.validatecmd(cmd) end end # Return true if the command returns 0. def check(value) begin output, status = @resource.run(value, true) rescue Timeout::Error err "Check %s exceeded timeout" % value.inspect return false end return status.exitstatus == 0 end end # Exec names are not isomorphic with the objects. @isomorphic = false validate do validatecmd(self[:command]) end # FIXME exec should autorequire any exec that 'creates' our cwd autorequire(:file) do reqs = [] # Stick the cwd in there if we have it if self[:cwd] reqs << self[:cwd] end self[:command].scan(/^(#{File::SEPARATOR}\S+)/) { |str| reqs << str } [:onlyif, :unless].each { |param| next unless tmp = self[param] tmp = [tmp] unless tmp.is_a? Array tmp.each do |line| # And search the command line for files, adding any we # find. This will also catch the command itself if it's # fully qualified. It might not be a bad idea to add # unqualified files, but, well, that's a bit more annoying # to do. reqs += line.scan(%r{(#{File::SEPARATOR}\S+)}) end } # For some reason, the += isn't causing a flattening reqs.flatten! reqs end autorequire(:user) do # Autorequire users if they are specified by name if user = self[:user] and user !~ /^\d+$/ user end end def self.instances [] end # Verify that we pass all of the checks. The argument determines whether # we skip the :refreshonly check, which is necessary because we now check # within refresh() def check(refreshing = false) self.class.checks.each { |check| next if refreshing and check == :refreshonly if @parameters.include?(check) val = @parameters[check].value val = [val] unless val.is_a? Array val.each do |value| unless @parameters[check].check(value) return false end end end } return true end # Verify that we have the executable def checkexe(cmd) if cmd =~ /^\// exe = cmd.split(/ /)[0] unless FileTest.exists?(exe) raise ArgumentError, "Could not find executable %s" % exe end unless FileTest.executable?(exe) raise ArgumentError, "%s is not executable" % exe end elsif path = self[:path] exe = cmd.split(/ /)[0] withenv :PATH => self[:path].join(":") do path = %{which #{exe}}.chomp if path == "" raise ArgumentError, "Could not find command '%s'" % exe end end else raise ArgumentError, "%s is somehow not qualified with no search path" % self[:command] end end def output if self.property(:returns).nil? return nil else return self.property(:returns).output end end # Run the command, or optionally run a separately-specified command. def refresh if self.check(true) if cmd = self[:refresh] self.run(cmd) else self.property(:returns).sync end end end # Run a command. def run(command, check = false) output = nil status = nil dir = nil checkexe(command) if dir = self[:cwd] unless File.directory?(dir) if check dir = nil else self.fail "Working directory '%s' does not exist" % dir end end end dir ||= Dir.pwd if check debug "Executing check '#{command}'" else debug "Executing '#{command}'" end begin # Do our chdir Dir.chdir(dir) do environment = {} if self[:path] environment[:PATH] = self[:path].join(":") end if envlist = self[:environment] envlist = [envlist] unless envlist.is_a? Array envlist.each do |setting| if setting =~ /^(\w+)=((.|\n)+)$/ name = $1 value = $2 if environment.include? name warning( "Overriding environment setting '%s' with '%s'" % [name, value] ) end environment[name] = value else warning "Cannot understand environment setting %s" % setting.inspect end end end withenv environment do Timeout::timeout(self[:timeout]) do output, status = Puppet::Util::SUIDManager.run_and_capture( [command], self[:user], self[:group] ) end # The shell returns 127 if the command is missing. if status.exitstatus == 127 raise ArgumentError, output end end end rescue Errno::ENOENT => detail self.fail detail.to_s end return output, status end def validatecmd(cmd) # if we're not fully qualified, require a path if cmd !~ /^\// if self[:path].nil? self.fail "'%s' is both unqualifed and specified no search path" % cmd end end end end end diff --git a/lib/puppet/type/file.rb b/lib/puppet/type/file.rb index fdb5a3578..0aaad3e97 100644 --- a/lib/puppet/type/file.rb +++ b/lib/puppet/type/file.rb @@ -1,835 +1,835 @@ require 'digest/md5' require 'cgi' require 'etc' require 'uri' require 'fileutils' require 'puppet/network/handler' require 'puppet/util/diff' require 'puppet/util/checksums' require 'puppet/network/client' require 'puppet/util/backups' module Puppet newtype(:file) do include Puppet::Util::MethodHelper include Puppet::Util::Checksums include Puppet::Util::Backups @doc = "Manages local files, including setting ownership and permissions, creation of both files and directories, and retrieving entire files from remote servers. As Puppet matures, it expected that the ``file`` resource will be used less and less to manage content, and instead native resources will be used to do so. If you find that you are often copying files in from a central location, rather than using native resources, please contact - Reductive Labs and we can hopefully work with you to develop a + Puppet Labs and we can hopefully work with you to develop a native resource to support what you are doing." newparam(:path) do desc "The path to the file to manage. Must be fully qualified." isnamevar validate do |value| unless value =~ /^#{File::SEPARATOR}/ fail Puppet::Error,"File paths must be fully qualified, not '#{value}'" end end # convert the current path in an index into the collection and the last # path name. The aim is to use less storage for all common paths in a hierarchy munge do |value| path, name = File.split(value) { :index => Puppet::FileCollection.collection.index(path), :name => name } end # and the reverse unmunge do |value| File.join( Puppet::FileCollection.collection.path(value[:index]), value[:name] ) end to_canonicalize do |s| # Get rid of any duplicate slashes, and remove any trailing slashes unless # the title is just a slash, in which case leave it. s.gsub(/\/+/, "/").sub(/(.)\/$/,'\1') end end newparam(:backup) do desc "Whether files should be backed up before being replaced. The preferred method of backing files up is via a ``filebucket``, which stores files by their MD5 sums and allows easy retrieval without littering directories with backups. You can specify a local filebucket or a network-accessible server-based filebucket by setting ``backup => bucket-name``. Alternatively, if you specify any value that begins with a ``.`` (e.g., ``.puppet-bak``), then Puppet will use copy the file in the same directory with that value as the extension of the backup. Setting ``backup => false`` disables all backups of the file in question. Puppet automatically creates a local filebucket named ``puppet`` and defaults to backing up there. To use a server-based filebucket, you must specify one in your configuration:: filebucket { main: server => puppet } The ``puppetmasterd`` daemon creates a filebucket by default, so you can usually back up to your main server with this configuration. Once you've described the bucket in your configuration, you can use it in any file:: file { \"/my/file\": source => \"/path/in/nfs/or/something\", backup => main } This will back the file up to the central server. At this point, the benefits of using a filebucket are that you do not have backup files lying around on each of your machines, a given version of a file is only backed up once, and you can restore any given file manually, no matter how old. Eventually, transactional support will be able to automatically restore filebucketed files. " defaultto "puppet" munge do |value| # I don't really know how this is happening. value = value.shift if value.is_a?(Array) case value when false, "false", :false false when true, "true", ".puppet-bak", :true ".puppet-bak" when String value else self.fail "Invalid backup type %s" % value.inspect end end end newparam(:recurse) do desc "Whether and how deeply to do recursive management." newvalues(:true, :false, :inf, :remote, /^[0-9]+$/) # Replace the validation so that we allow numbers in # addition to string representations of them. validate { |arg| } munge do |value| newval = super(value) case newval when :true, :inf; true when :false; false when :remote; :remote when Integer, Fixnum, Bignum self.warning "Setting recursion depth with the recurse parameter is now deprecated, please use recurselimit" # recurse == 0 means no recursion return false if value == 0 resource[:recurselimit] = value true when /^\d+$/ self.warning "Setting recursion depth with the recurse parameter is now deprecated, please use recurselimit" value = Integer(value) # recurse == 0 means no recursion return false if value == 0 resource[:recurselimit] = value true else self.fail "Invalid recurse value #{value.inspect}" end end end newparam(:recurselimit) do desc "How deeply to do recursive management." newvalues(/^[0-9]+$/) munge do |value| newval = super(value) case newval when Integer, Fixnum, Bignum; value when /^\d+$/; Integer(value) else self.fail "Invalid recurselimit value #{value.inspect}" end end end newparam(:replace, :boolean => true) do desc "Whether or not to replace a file that is sourced but exists. This is useful for using file sources purely for initialization." newvalues(:true, :false) aliasvalue(:yes, :true) aliasvalue(:no, :false) defaultto :true end newparam(:force, :boolean => true) do desc "Force the file operation. Currently only used when replacing directories with links." newvalues(:true, :false) defaultto false end newparam(:ignore) do desc "A parameter which omits action on files matching specified patterns during recursion. Uses Ruby's builtin globbing engine, so shell metacharacters are fully supported, e.g. ``[a-z]*``. Matches that would descend into the directory structure are ignored, e.g., ``*/*``." validate do |value| unless value.is_a?(Array) or value.is_a?(String) or value == false self.devfail "Ignore must be a string or an Array" end end end newparam(:links) do desc "How to handle links during file actions. During file copying, ``follow`` will copy the target file instead of the link, ``manage`` will copy the link itself, and ``ignore`` will just pass it by. When not copying, ``manage`` and ``ignore`` behave equivalently (because you cannot really ignore links entirely during local recursion), and ``follow`` will manage the file to which the link points." newvalues(:follow, :manage) defaultto :manage end newparam(:purge, :boolean => true) do desc "Whether unmanaged files should be purged. If you have a filebucket configured the purged files will be uploaded, but if you do not, this will destroy data. Only use this option for generated files unless you really know what you are doing. This option only makes sense when recursively managing directories. Note that when using ``purge`` with ``source``, Puppet will purge any files that are not on the remote system." defaultto :false newvalues(:true, :false) end newparam(:sourceselect) do desc "Whether to copy all valid sources, or just the first one. This parameter is only used in recursive copies; by default, the first valid source is the only one used as a recursive source, but if this parameter is set to ``all``, then all valid sources will have all of their contents copied to the local host, and for sources that have the same file, the source earlier in the list will be used." defaultto :first newvalues(:first, :all) end # Autorequire any parent directories. autorequire(:file) do basedir = File.dirname(self[:path]) if basedir != self[:path] basedir else nil end end # Autorequire the owner and group of the file. {:user => :owner, :group => :group}.each do |type, property| autorequire(type) do if @parameters.include?(property) # The user/group property automatically converts to IDs next unless should = @parameters[property].shouldorig val = should[0] if val.is_a?(Integer) or val =~ /^\d+$/ nil else val end end end end CREATORS = [:content, :source, :target] validate do count = 0 CREATORS.each do |param| count += 1 if self.should(param) end if @parameters.include?(:source) count += 1 end if count > 1 self.fail "You cannot specify more than one of %s" % CREATORS.collect { |p| p.to_s}.join(", ") end if !self[:source] and self[:recurse] == :remote self.fail "You cannot specify a remote recursion without a source" end if !self[:recurse] and self[:recurselimit] self.warning "Possible error: recurselimit is set but not recurse, no recursion will happen" end end def self.[](path) return nil unless path super(path.gsub(/\/+/, '/').sub(/\/$/, '')) end # List files, but only one level deep. def self.instances(base = "/") unless FileTest.directory?(base) return [] end files = [] Dir.entries(base).reject { |e| e == "." or e == ".." }.each do |name| path = File.join(base, name) if obj = self[path] obj[:check] = :all files << obj else files << self.new( :name => path, :check => :all ) end end files end @depthfirst = false # Determine the user to write files as. def asuser if self.should(:owner) and ! self.should(:owner).is_a?(Symbol) writeable = Puppet::Util::SUIDManager.asuser(self.should(:owner)) { FileTest.writable?(File.dirname(self[:path])) } # If the parent directory is writeable, then we execute # as the user in question. Otherwise we'll rely on # the 'owner' property to do things. if writeable asuser = self.should(:owner) end end return asuser end def bucket return @bucket if defined?(@bucket) and @bucket backup = self[:backup] return nil unless backup return nil if backup =~ /^\./ unless catalog or backup == "puppet" fail "Can not find filebucket for backups without a catalog" end unless catalog and filebucket = catalog.resource(:filebucket, backup) or backup == "puppet" fail "Could not find filebucket %s specified in backup" % backup end return default_bucket unless filebucket @bucket = filebucket.bucket return @bucket end def default_bucket Puppet::Type.type(:filebucket).mkdefaultbucket.bucket end # Does the file currently exist? Just checks for whether # we have a stat def exist? stat ? true : false end # We have to do some extra finishing, to retrieve our bucket if # there is one. def finish # Look up our bucket, if there is one bucket() super end # Create any children via recursion or whatever. def eval_generate return [] unless self.recurse? recurse #recurse.reject do |resource| # catalog.resource(:file, resource[:path]) #end.each do |child| # catalog.add_resource child # catalog.relationship_graph.add_edge self, child #end end def flush # We want to make sure we retrieve metadata anew on each transaction. @parameters.each do |name, param| param.flush if param.respond_to?(:flush) end @stat = nil end def initialize(hash) # Used for caching clients @clients = {} super @title = self.class.canonicalize_ref(@title) @stat = nil end # Configure discovered resources to be purged. def mark_children_for_purging(children) children.each do |name, child| next if child[:source] child[:ensure] = :absent end end # Create a new file or directory object as a child to the current # object. def newchild(path) full_path = File.join(self[:path], path) # Add some new values to our original arguments -- these are the ones # set at initialization. We specifically want to exclude any param # values set by the :source property or any default values. # LAK:NOTE This is kind of silly, because the whole point here is that # the values set at initialization should live as long as the resource # but values set by default or by :source should only live for the transaction # or so. Unfortunately, we don't have a straightforward way to manage # the different lifetimes of this data, so we kludge it like this. # The right-side hash wins in the merge. options = @original_parameters.merge(:path => full_path).reject { |param, value| value.nil? } # These should never be passed to our children. [:parent, :ensure, :recurse, :recurselimit, :target, :alias, :source].each do |param| options.delete(param) if options.include?(param) end return self.class.new(options) end # Files handle paths specially, because they just lengthen their # path names, rather than including the full parent's title each # time. def pathbuilder # We specifically need to call the method here, so it looks # up our parent in the catalog graph. if parent = parent() # We only need to behave specially when our parent is also # a file if parent.is_a?(self.class) # Remove the parent file name list = parent.pathbuilder list.pop # remove the parent's path info return list << self.ref else return super end else return [self.ref] end end # Should we be purging? def purge? @parameters.include?(:purge) and (self[:purge] == :true or self[:purge] == "true") end # Recursively generate a list of file resources, which will # be used to copy remote files, manage local files, and/or make links # to map to another directory. def recurse children = {} if self[:recurse] != :remote children = recurse_local end if self[:target] recurse_link(children) elsif self[:source] recurse_remote(children) end # If we're purging resources, then delete any resource that isn't on the # remote system. mark_children_for_purging(children) if self.purge? result = children.values.sort { |a, b| a[:path] <=> b[:path] } remove_less_specific_files(result) end # This is to fix bug #2296, where two files recurse over the same # set of files. It's a rare case, and when it does happen you're # not likely to have many actual conflicts, which is good, because # this is a pretty inefficient implementation. def remove_less_specific_files(files) mypath = self[:path].split(File::Separator) other_paths = catalog.vertices. select { |r| r.is_a?(self.class) and r[:path] != self[:path] }. collect { |r| r[:path].split(File::Separator) }. select { |p| p[0,mypath.length] == mypath } return files if other_paths.empty? files.reject { |file| path = file[:path].split(File::Separator) other_paths.any? { |p| path[0,p.length] == p } } end # A simple method for determining whether we should be recursing. def recurse? return false unless @parameters.include?(:recurse) val = @parameters[:recurse].value if val and (val == true or val == :remote) return true else return false end end # Recurse the target of the link. def recurse_link(children) perform_recursion(self[:target]).each do |meta| if meta.relative_path == "." self[:ensure] = :directory next end children[meta.relative_path] ||= newchild(meta.relative_path) if meta.ftype == "directory" children[meta.relative_path][:ensure] = :directory else children[meta.relative_path][:ensure] = :link children[meta.relative_path][:target] = meta.full_path end end children end # Recurse the file itself, returning a Metadata instance for every found file. def recurse_local result = perform_recursion(self[:path]) return {} unless result result.inject({}) do |hash, meta| next hash if meta.relative_path == "." hash[meta.relative_path] = newchild(meta.relative_path) hash end end # Recurse against our remote file. def recurse_remote(children) sourceselect = self[:sourceselect] total = self[:source].collect do |source| next unless result = perform_recursion(source) return if top = result.find { |r| r.relative_path == "." } and top.ftype != "directory" result.each { |data| data.source = "%s/%s" % [source, data.relative_path] } break result if result and ! result.empty? and sourceselect == :first result end.flatten # This only happens if we have sourceselect == :all unless sourceselect == :first found = [] total.reject! do |data| result = found.include?(data.relative_path) found << data.relative_path unless found.include?(data.relative_path) result end end total.each do |meta| if meta.relative_path == "." parameter(:source).metadata = meta next end children[meta.relative_path] ||= newchild(meta.relative_path) children[meta.relative_path][:source] = meta.source children[meta.relative_path][:checksum] = :md5 if meta.ftype == "file" children[meta.relative_path].parameter(:source).metadata = meta end children end def perform_recursion(path) params = { :links => self[:links], :recurse => (self[:recurse] == :remote ? true : self[:recurse]), :recurselimit => self[:recurselimit], :ignore => self[:ignore] } params[:checksum_type] = self[:checksum] if self[:checksum] == :none Puppet::FileServing::Metadata.search(path, params) end # Remove any existing data. This is only used when dealing with # links or directories. def remove_existing(should) return unless s = stat self.fail "Could not back up; will not replace" unless perform_backup unless should.to_s == "link" return if s.ftype.to_s == should.to_s end case s.ftype when "directory" if self[:force] == :true debug "Removing existing directory for replacement with %s" % should FileUtils.rmtree(self[:path]) else notice "Not removing directory; use 'force' to override" end when "link", "file" debug "Removing existing %s for replacement with %s" % [s.ftype, should] File.unlink(self[:path]) else self.fail "Could not back up files of type %s" % s.ftype end expire end # a wrapper method to make sure the file exists before doing anything def retrieve if source = parameter(:source) source.copy_source_values end super end # Set the checksum, from another property. There are multiple # properties that modify the contents of a file, and they need the # ability to make sure that the checksum value is in sync. def setchecksum(sum = nil) if @parameters.include? :checksum if sum @parameters[:checksum].checksum = sum else # If they didn't pass in a sum, then tell checksum to # figure it out. currentvalue = @parameters[:checksum].retrieve @parameters[:checksum].checksum = currentvalue end end end # Should this thing be a normal file? This is a relatively complex # way of determining whether we're trying to create a normal file, # and it's here so that the logic isn't visible in the content property. def should_be_file? return true if self[:ensure] == :file # I.e., it's set to something like "directory" return false if e = self[:ensure] and e != :present # The user doesn't really care, apparently if self[:ensure] == :present return true unless s = stat return true if s.ftype == "file" return false end # If we've gotten here, then :ensure isn't set return true if self[:content] return true if stat and stat.ftype == "file" return false end # Stat our file. Depending on the value of the 'links' attribute, we # use either 'stat' or 'lstat', and we expect the properties to use the # resulting stat object accordingly (mostly by testing the 'ftype' # value). cached_attr(:stat) do method = :stat # Files are the only types that support links if (self.class.name == :file and self[:links] != :follow) or self.class.name == :tidy method = :lstat end path = self[:path] begin File.send(method, self[:path]) rescue Errno::ENOENT => error return nil rescue Errno::EACCES => error warning "Could not stat; permission denied" return nil end end # We have to hack this just a little bit, because otherwise we'll get # an error when the target and the contents are created as properties on # the far side. def to_trans(retrieve = true) obj = super if obj[:target] == :notlink obj.delete(:target) end obj end # Write out the file. Requires the content to be written, # the property name for logging, and the checksum for validation. def write(content, property, checksum = nil) if validate = validate_checksum? # Use the appropriate checksum type -- md5, md5lite, etc. sumtype = property(:checksum).checktype checksum ||= "{#{sumtype}}" + property(:checksum).send(sumtype, content) end remove_existing(:file) use_temporary_file = (content.length != 0) if use_temporary_file path = "#{self[:path]}.puppettmp_#{rand(10000)}" while File.exists?(path) or File.symlink?(path) path = "#{self[:path]}.puppettmp_#{rand(10000)}" end else path = self[:path] end mode = self.should(:mode) # might be nil umask = mode ? 000 : 022 Puppet::Util.withumask(umask) do File.open(path, File::CREAT|File::WRONLY|File::TRUNC, mode) { |f| f.print content } end # And put our new file in place if use_temporary_file # This is only not true when our file is empty. begin fail_if_checksum_is_wrong(path, checksum) if validate File.rename(path, self[:path]) rescue => detail fail "Could not rename temporary file %s to %s : %s" % [path, self[:path], detail] ensure # Make sure the created file gets removed File.unlink(path) if FileTest.exists?(path) end end # make sure all of the modes are actually correct property_fix # And then update our checksum, so the next run doesn't find it. self.setchecksum(checksum) end # Should we validate the checksum of the file we're writing? def validate_checksum? if sumparam = @parameters[:checksum] return sumparam.checktype.to_s !~ /time/ else return false end end private # Make sure the file we wrote out is what we think it is. def fail_if_checksum_is_wrong(path, checksum) if checksum =~ /^\{(\w+)\}.+/ sumtype = $1 else # This shouldn't happen, but if it happens to, it's nicer # to just use a default sumtype than fail. sumtype = "md5" end newsum = property(:checksum).getsum(sumtype, path) return if newsum == checksum self.fail "File written to disk did not match checksum; discarding changes (%s vs %s)" % [checksum, newsum] end # Override the parent method, because we don't want to generate changes # when the file is missing and there is no 'ensure' state. def propertychanges(currentvalues) unless self.stat found = false ([:ensure] + CREATORS).each do |prop| if @parameters.include?(prop) found = true break end end unless found return [] end end super end # There are some cases where all of the work does not get done on # file creation/modification, so we have to do some extra checking. def property_fix properties.each do |thing| next unless [:mode, :owner, :group, :seluser, :selrole, :seltype, :selrange].include?(thing.name) # Make sure we get a new stat objct expire currentvalue = thing.retrieve unless thing.insync?(currentvalue) thing.sync end end end end # Puppet::Type.type(:pfile) # We put all of the properties in separate files, because there are so many # of them. The order these are loaded is important, because it determines # the order they are in the property lit. require 'puppet/type/file/checksum' require 'puppet/type/file/content' # can create the file require 'puppet/type/file/source' # can create the file require 'puppet/type/file/target' # creates a different type of file require 'puppet/type/file/ensure' # can create the file require 'puppet/type/file/owner' require 'puppet/type/file/group' require 'puppet/type/file/mode' require 'puppet/type/file/type' require 'puppet/type/file/selcontext' # SELinux file context end diff --git a/lib/puppet/util/nagios_maker.rb b/lib/puppet/util/nagios_maker.rb index 339d2d1a2..d7044f2c8 100644 --- a/lib/puppet/util/nagios_maker.rb +++ b/lib/puppet/util/nagios_maker.rb @@ -1,61 +1,61 @@ require 'puppet/external/nagios' require 'puppet/external/nagios/base' require 'puppet/provider/naginator' module Puppet::Util::NagiosMaker # Create a new nagios type, using all of the parameters # from the parser. def self.create_nagios_type(name) name = name.to_sym full_name = ("nagios_" + name.to_s).to_sym raise(Puppet::DevError, "No nagios type for %s" % name) unless nagtype = Nagios::Base.type(name) type = Puppet::Type.newtype(full_name) {} type.ensurable type.newparam(nagtype.namevar, :namevar => true) do desc "The name parameter for Nagios type %s" % nagtype.name end # We deduplicate the parameters because it makes sense to allow Naginator to have dupes. nagtype.parameters.uniq.each do |param| next if param == nagtype.namevar # We can't turn these parameter names into constants, so at least for now they aren't # supported. next if param.to_s =~ /^[0-9]/ type.newproperty(param) do desc "Nagios configuration file parameter." end end type.newproperty(:target) do desc 'target' defaultto do resource.class.defaultprovider.default_target end end target = "/etc/nagios/#{full_name.to_s}.cfg" provider = type.provide(:naginator, :parent => Puppet::Provider::Naginator, :default_target => target) {} provider.nagios_type type.desc "The Nagios type #{name.to_s}. This resource type is autogenerated using the model developed in Naginator_, and all of the Nagios types are generated using the same code and the same library. This type generates Nagios configuration statements in Nagios-parseable configuration files. By default, the statements will be added to ``#{target}``, but you can send them to a different file by setting their ``target`` attribute. You can purge Nagios resources using the ``resources`` type, but *only* in the default file locations. This is an architectural limitation. - .. _naginator: http://projects.reductivelabs.com/projects/naginator + .. _naginator: http://projects.puppetlabs.com/projects/naginator " end end diff --git a/man/man5/puppet.conf.5 b/man/man5/puppet.conf.5 index 6bff15afc..ff9b88953 100644 --- a/man/man5/puppet.conf.5 +++ b/man/man5/puppet.conf.5 @@ -1,1485 +1,1485 @@ .TH CONFIGURATION REFERENCE "" "" "" .SH NAME Configuration Reference \- .\" Man page generated from reStructeredText. . .sp \fBThis page is autogenerated; any changes will get overwritten\fP \fI(last generated on Sun Apr 11 17:57:48 \-0400 2010)\fP .SS Contents .INDENT 0.0 .IP \(bu 2 . \fI\%Specifying Configuration Parameters\fP .IP \(bu 2 . \fI\%Signals\fP .IP \(bu 2 . \fI\%Configuration Parameter Reference\fP .UNINDENT .SH SPECIFYING CONFIGURATION PARAMETERS .SS On The Command\-Line .sp Every Puppet executable (with the exception of \fBpuppetdoc\fP) accepts all of the parameters below, but not all of the arguments make sense for every executable. .sp I have tried to be as thorough as possible in the descriptions of the arguments, so it should be obvious whether an argument is appropriate or not. .sp These parameters can be supplied to the executables either as command\-line options or in the configuration file. For instance, the command\-line invocation below would set the configuration directory to \fB/private/puppet\fP: .sp .nf .ft C $ puppetd \-\-confdir=/private/puppet .ft P .fi .sp Note that boolean options are turned on and off with a slightly different syntax on the command line: .sp .nf .ft C $ puppetd \-\-storeconfigs $ puppetd \-\-no\-storeconfigs .ft P .fi .sp The invocations above will enable and disable, respectively, the storage of the client configuration. .SS Configuration Files .sp As mentioned above, the configuration parameters can also be stored in a configuration file, located in the configuration directory. As root, the default configuration directory is \fB/etc/puppet\fP, and as a regular user, the default configuration directory is \fB~user/.puppet\fP. As of 0.23.0, all executables look for \fBpuppet.conf\fP in their configuration directory (although they previously looked for separate files). For example, \fBpuppet.conf\fP is located at \fB/etc/puppet/puppet.conf\fP as root and \fB~user/.puppet/puppet.conf\fP as a regular user by default. .sp All executables will set any parameters set within the \fBmain\fP section, while each executable will also look for a section named for the executable and load those parameters. For example, \fBpuppetd\fP will look for a section named \fBpuppetd\fP, and \fBpuppetmasterd\fP looks for a section named \fBpuppetmasterd\fP. This allows you to use a single configuration file to customize the settings for all of your executables. .SS File Format .sp The file follows INI\-style formatting. Here is an example of a very simple \fBpuppet.conf\fP file: .sp .nf .ft C [main] confdir = /private/puppet storeconfigs = true .ft P .fi .sp Note that boolean parameters must be explicitly specified as \fItrue\fP or \fIfalse\fP as seen above. .sp If you need to change file parameters (e.g., reset the mode or owner), do so within curly braces on the same line: .sp .nf .ft C [main] myfile = /tmp/whatever {owner = root, mode = 644} .ft P .fi .sp If you\(aqre starting out with a fresh configuration, you may wish to let the executable generate a template configuration file for you by invoking the executable in question with the \fI\-\-genconfig\fP command. The executable will print a template configuration to standard output, which can be redirected to a file like so: .sp .nf .ft C $ puppetd \-\-genconfig > /etc/puppet/puppet.conf .ft P .fi .sp Note that this invocation will replace the contents of any pre\-existing \fIpuppet.conf\fP file, so make a backup of your present config if it contains valuable information. .sp Like the \fI\-\-genconfig\fP argument, the executables also accept a \fI\-\-genmanifest\fP argument, which will generate a manifest that can be used to manage all of Puppet\(aqs directories and files and prints it to standard output. This can likewise be redirected to a file: .sp .nf .ft C $ puppetd \-\-genmanifest > /etc/puppet/manifests/site.pp .ft P .fi .sp Puppet can also create user and group accounts for itself (one \fIpuppet\fP group and one \fIpuppet\fP user) if it is invoked as \fIroot\fP with the \fI\-\-mkusers\fP argument: .sp .nf .ft C $ puppetd \-\-mkusers .ft P .fi .SH SIGNALS .sp The \fBpuppetd\fP and \fBpuppetmasterd\fP executables catch some signals for special handling. Both daemons catch (\fBSIGHUP\fP), which forces the server to restart tself. Predictably, interrupt and terminate (\fBSIGINT\fP and \fBSIGTERM\fP) will shut down the server, whether it be an instance of \fBpuppetd\fP or \fBpuppetmasterd\fP. .sp Sending the \fBSIGUSR1\fP signal to an instance of \fBpuppetd\fP will cause it to immediately begin a new configuration transaction with the server. This signal has no effect on \fBpuppetmasterd\fP. .SH CONFIGURATION PARAMETER REFERENCE .sp Below is a list of all documented parameters. Not all of them are valid with all Puppet executables, but the executables will ignore any inappropriate values. .SS async_storeconfigs .sp Whether to use a queueing system to provide asynchronous database integration. Requires that \fBpuppetqd\fP be running and that \(aqPSON\(aq support for ruby be installed. .INDENT 0.0 .IP \(bu 2 . \fBDefault\fP: false .UNINDENT .SS authconfig .sp The configuration file that defines the rights to the different namespaces and methods. This can be used as a coarse\-grained authorization system for both \fBpuppetd\fP and \fBpuppetmasterd\fP. .INDENT 0.0 .IP \(bu 2 . \fBDefault\fP: $confdir/namespaceauth.conf .UNINDENT .SS autoflush .sp Whether log files should always flush to disk. .INDENT 0.0 .IP \(bu 2 . \fBDefault\fP: false .UNINDENT .SS autosign .sp Whether to enable autosign. Valid values are true (which autosigns any key request, and is a very bad idea), false (which never autosigns any key request), and the path to a file, which uses that configuration file to determine which keys to sign. .INDENT 0.0 .IP \(bu 2 . \fBDefault\fP: $confdir/autosign.conf .UNINDENT .SS bindaddress .sp The address a listening server should bind to. Mongrel servers default to 127.0.0.1 and WEBrick defaults to 0.0.0.0. .SS bucketdir .sp Where FileBucket files are stored. .INDENT 0.0 .IP \(bu 2 . \fBDefault\fP: $vardir/bucket .UNINDENT .SS ca .sp Wether the master should function as a certificate authority. .INDENT 0.0 .IP \(bu 2 . \fBDefault\fP: true .UNINDENT .SS ca_days .sp How long a certificate should be valid. This parameter is deprecated, use ca_ttl instead .SS ca_md .sp The type of hash used in certificates. .INDENT 0.0 .IP \(bu 2 . \fBDefault\fP: md5 .UNINDENT .SS ca_port .sp The port to use for the certificate authority. .INDENT 0.0 .IP \(bu 2 . \fBDefault\fP: $masterport .UNINDENT .SS ca_server .sp The server to use for certificate authority requests. It\(aqs a separate server because it cannot and does not need to horizontally scale. .INDENT 0.0 .IP \(bu 2 . \fBDefault\fP: $server .UNINDENT .SS ca_ttl .sp The default TTL for new certificates; valid values must be an integer, optionally followed by one of the units \(aqy\(aq (years of 365 days), \(aqd\(aq (days), \(aqh\(aq (hours), or \(aqs\(aq (seconds). The unit defaults to seconds. If this parameter is set, ca_days is ignored. Examples are \(aq3600\(aq (one hour) and \(aq1825d\(aq, which is the same as \(aq5y\(aq (5 years) .INDENT 0.0 .IP \(bu 2 . \fBDefault\fP: 5y .UNINDENT .SS cacert .sp The CA certificate. .INDENT 0.0 .IP \(bu 2 . \fBDefault\fP: $cadir/ca_crt.pem .UNINDENT .SS cacrl .sp The certificate revocation list (CRL) for the CA. Will be used if present but otherwise ignored. .INDENT 0.0 .IP \(bu 2 . \fBDefault\fP: $cadir/ca_crl.pem .UNINDENT .SS cadir .sp The root directory for the certificate authority. .INDENT 0.0 .IP \(bu 2 . \fBDefault\fP: $ssldir/ca .UNINDENT .SS cakey .sp The CA private key. .INDENT 0.0 .IP \(bu 2 . \fBDefault\fP: $cadir/ca_key.pem .UNINDENT .SS capass .sp Where the CA stores the password for the private key .INDENT 0.0 .IP \(bu 2 . \fBDefault\fP: $caprivatedir/ca.pass .UNINDENT .SS caprivatedir .sp Where the CA stores private certificate information. .INDENT 0.0 .IP \(bu 2 . \fBDefault\fP: $cadir/private .UNINDENT .SS capub .sp The CA public key. .INDENT 0.0 .IP \(bu 2 . \fBDefault\fP: $cadir/ca_pub.pem .UNINDENT .SS casesensitive .sp Whether matching in case statements and selectors should be case\-sensitive. Case insensitivity is handled by downcasing all values before comparison. .INDENT 0.0 .IP \(bu 2 . \fBDefault\fP: false .UNINDENT .SS catalog_format .sp (Deprecated for \(aqpreferred_serialization_format\(aq) What format to use to dump the catalog. Only supports \(aqmarshal\(aq and \(aqyaml\(aq. Only matters on the client, since it asks the server for a specific format. .SS catalog_terminus .sp Where to get node catalogs. This is useful to change if, for instance, you\(aqd like to pre\-compile catalogs and store them in memcached or some other easily\-accessed store. .INDENT 0.0 .IP \(bu 2 . \fBDefault\fP: compiler .UNINDENT .SS cert_inventory .sp A Complete listing of all certificates .INDENT 0.0 .IP \(bu 2 . \fBDefault\fP: $cadir/inventory.txt .UNINDENT .SS certdir .sp The certificate directory. .INDENT 0.0 .IP \(bu 2 . \fBDefault\fP: $ssldir/certs .UNINDENT .SS certdnsnames .sp The DNS names on the Server certificate as a colon\-separated list. If it\(aqs anything other than an empty string, it will be used as an alias in the created certificate. By default, only the server gets an alias set up, and only for \(aqpuppet\(aq. .SS certname .sp The name to use when handling certificates. Defaults to the fully qualified domain name. .INDENT 0.0 .IP \(bu 2 . \fBDefault\fP: pelin.lovedthanlost.net .UNINDENT .SS classfile .sp The file in which puppetd stores a list of the classes associated with the retrieved configuration. Can be loaded in the separate \fBpuppet\fP executable using the \fB\-\-loadclasses\fP option. .INDENT 0.0 .IP \(bu 2 . \fBDefault\fP: $statedir/classes.txt .UNINDENT .SS clientbucketdir .sp Where FileBucket files are stored locally. .INDENT 0.0 .IP \(bu 2 . \fBDefault\fP: $vardir/clientbucket .UNINDENT .SS clientyamldir .sp The directory in which client\-side YAML data is stored. .INDENT 0.0 .IP \(bu 2 . \fBDefault\fP: $vardir/client_yaml .UNINDENT .SS code .sp Code to parse directly. This is essentially only used by \fBpuppet\fP, and should only be set if you\(aqre writing your own Puppet executable .SS color .sp Whether to use colors when logging to the console. Valid values are \fBansi\fP (equivalent to \fBtrue\fP), \fBhtml\fP (mostly used during testing with TextMate), and \fBfalse\fP, which produces no color. .INDENT 0.0 .IP \(bu 2 . \fBDefault\fP: ansi .UNINDENT .SS confdir .sp The main Puppet configuration directory. The default for this parameter is calculated based on the user. If the process is runnig as root or the user that \fBpuppetmasterd\fP is supposed to run as, it defaults to a system directory, but if it\(aqs running as any other user, it defaults to being in \fB~\fP. .INDENT 0.0 .IP \(bu 2 . \fBDefault\fP: /etc/puppet .UNINDENT .SS config .sp The configuration file for puppetdoc. .INDENT 0.0 .IP \(bu 2 . \fBDefault\fP: $confdir/puppet.conf .UNINDENT .SS config_version .sp How to determine the configuration version. By default, it will be the time that the configuration is parsed, but you can provide a shell script to override how the version is determined. The output of this script will be added to every log message in the reports, allowing you to correlate changes on your hosts to the source version on the server. .SS configprint .sp 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 \(aqall\(aq. This feature is only available in Puppet versions higher than 0.18.4. .SS configtimeout .sp How long the client should wait for the configuration to be retrieved before considering it a failure. This can help reduce flapping if too many clients contact the server at one time. .INDENT 0.0 .IP \(bu 2 . \fBDefault\fP: 120 .UNINDENT .SS csrdir .sp Where the CA stores certificate requests .INDENT 0.0 .IP \(bu 2 . \fBDefault\fP: $cadir/requests .UNINDENT .SS daemonize .sp Send the process into the background. This is the default. .INDENT 0.0 .IP \(bu 2 . \fBDefault\fP: true .UNINDENT .SS dbadapter .sp The type of database to use. .INDENT 0.0 .IP \(bu 2 . \fBDefault\fP: sqlite3 .UNINDENT .SS dblocation .sp The database cache for client configurations. Used for querying within the language. .INDENT 0.0 .IP \(bu 2 . \fBDefault\fP: $statedir/clientconfigs.sqlite3 .UNINDENT .SS dbmigrate .sp Whether to automatically migrate the database. .INDENT 0.0 .IP \(bu 2 . \fBDefault\fP: false .UNINDENT .SS dbname .sp The name of the database to use. .INDENT 0.0 .IP \(bu 2 . \fBDefault\fP: puppet .UNINDENT .SS dbpassword .sp The database password for Client caching. Only used when networked databases are used. .INDENT 0.0 .IP \(bu 2 . \fBDefault\fP: puppet .UNINDENT .SS dbserver .sp The database server for Client caching. Only used when networked databases are used. .INDENT 0.0 .IP \(bu 2 . \fBDefault\fP: localhost .UNINDENT .SS dbsocket .sp The database socket location. Only used when networked databases are used. Will be ignored if the value is an empty string. .SS dbuser .sp The database user for Client caching. Only used when networked databases are used. .INDENT 0.0 .IP \(bu 2 . \fBDefault\fP: puppet .UNINDENT .SS diff .sp Which diff command to use when printing differences between files. .INDENT 0.0 .IP \(bu 2 . \fBDefault\fP: diff .UNINDENT .SS diff_args .sp Which arguments to pass to the diff command when printing differences between files. .INDENT 0.0 .IP \(bu 2 . \fBDefault\fP: \-u .UNINDENT .SS downcasefacts .sp Whether facts should be made all lowercase when sent to the server. .INDENT 0.0 .IP \(bu 2 . \fBDefault\fP: false .UNINDENT .SS dynamicfacts .sp Facts that are dynamic; these facts will be ignored when deciding whether changed facts should result in a recompile. Multiple facts should be comma\-separated. .INDENT 0.0 .IP \(bu 2 . \fBDefault\fP: memorysize,memoryfree,swapsize,swapfree .UNINDENT .SS environment .sp The environment Puppet is running in. For clients (e.g., \fBpuppetd\fP) this determines the environment itself, which is used to find modules and much more. For servers (i.e., \fBpuppetmasterd\fP) this provides the default environment for nodes we know nothing about. .INDENT 0.0 .IP \(bu 2 . \fBDefault\fP: production .UNINDENT .SS evaltrace .sp Whether each resource should log when it is being evaluated. This allows you to interactively see exactly what is being done. .INDENT 0.0 .IP \(bu 2 . \fBDefault\fP: false .UNINDENT .SS external_nodes .sp An external command that can produce node information. The output must be a YAML dump of a hash, and that hash must have one or both of \fBclasses\fP and \fBparameters\fP, where \fBclasses\fP is an array and \fBparameters\fP is a hash. For unknown nodes, the commands should exit with a non\-zero exit code. This command makes it straightforward to store your node mapping information in other data sources like databases. .INDENT 0.0 .IP \(bu 2 . \fBDefault\fP: none .UNINDENT .SS factdest .sp Where Puppet should store facts that it pulls down from the central server. .INDENT 0.0 .IP \(bu 2 . \fBDefault\fP: $vardir/facts/ .UNINDENT .SS factpath .sp Where Puppet should look for facts. Multiple directories should be colon\-separated, like normal PATH variables. .INDENT 0.0 .IP \(bu 2 . \fBDefault\fP: $vardir/facts/ .UNINDENT .SS factsignore .sp What files to ignore when pulling down facts. .INDENT 0.0 .IP \(bu 2 . \fBDefault\fP: .svn CVS .UNINDENT .SS factsource .sp From where to retrieve facts. The standard Puppet \fBfile\fP type is used for retrieval, so anything that is a valid file source can be used here. .INDENT 0.0 .IP \(bu 2 . \fBDefault\fP: puppet://$server/facts/ .UNINDENT .SS factsync .sp Whether facts should be synced with the central server. .INDENT 0.0 .IP \(bu 2 . \fBDefault\fP: false .UNINDENT .SS fileserverconfig .sp Where the fileserver configuration is stored. .INDENT 0.0 .IP \(bu 2 . \fBDefault\fP: $confdir/fileserver.conf .UNINDENT .SS filetimeout .sp The minimum time to wait (in seconds) between checking for updates in configuration files. This timeout determines how quickly Puppet checks whether a file (such as manifests or templates) has changed on disk. .INDENT 0.0 .IP \(bu 2 . \fBDefault\fP: 15 .UNINDENT .SS genconfig .sp Whether to just print a configuration to stdout and exit. Only makes sense when used interactively. Takes into account arguments specified on the CLI. .INDENT 0.0 .IP \(bu 2 . \fBDefault\fP: false .UNINDENT .SS genmanifest .sp Whether to just print a manifest to stdout and exit. Only makes sense when used interactively. Takes into account arguments specified on the CLI. .INDENT 0.0 .IP \(bu 2 . \fBDefault\fP: false .UNINDENT .SS graph .sp Whether to create dot graph files for the different configuration graphs. These dot files can be interpreted by tools like OmniGraffle or dot (which is part of ImageMagick). .INDENT 0.0 .IP \(bu 2 . \fBDefault\fP: false .UNINDENT .SS graphdir .sp Where to store dot\-outputted graphs. .INDENT 0.0 .IP \(bu 2 . \fBDefault\fP: $statedir/graphs .UNINDENT .SS group .sp The group puppetmasterd should run as. .INDENT 0.0 .IP \(bu 2 . \fBDefault\fP: puppet .UNINDENT .SS hostcert .sp Where individual hosts store and look for their certificates. .INDENT 0.0 .IP \(bu 2 . \fBDefault\fP: $certdir/$certname.pem .UNINDENT .SS hostcrl .sp Where the host\(aqs certificate revocation list can be found. This is distinct from the certificate authority\(aqs CRL. .INDENT 0.0 .IP \(bu 2 . \fBDefault\fP: $ssldir/crl.pem .UNINDENT .SS hostcsr .sp Where individual hosts store and look for their certificate requests. .INDENT 0.0 .IP \(bu 2 . \fBDefault\fP: $ssldir/csr_$certname.pem .UNINDENT .SS hostprivkey .sp Where individual hosts store and look for their private key. .INDENT 0.0 .IP \(bu 2 . \fBDefault\fP: $privatekeydir/$certname.pem .UNINDENT .SS hostpubkey .sp Where individual hosts store and look for their public key. .INDENT 0.0 .IP \(bu 2 . \fBDefault\fP: $publickeydir/$certname.pem .UNINDENT .SS http_proxy_host .sp The HTTP proxy host to use for outgoing connections. Note: You may need to use a FQDN for the server hostname when using a proxy. .INDENT 0.0 .IP \(bu 2 . \fBDefault\fP: none .UNINDENT .SS http_proxy_port .sp The HTTP proxy port to use for outgoing connections .INDENT 0.0 .IP \(bu 2 . \fBDefault\fP: 3128 .UNINDENT .SS httplog .sp Where the puppetd web server logs. .INDENT 0.0 .IP \(bu 2 . \fBDefault\fP: $logdir/http.log .UNINDENT .SS ignorecache .sp Ignore cache and always recompile the configuration. This is useful for testing new configurations, where the local cache may in fact be stale even if the timestamps are up to date \- if the facts change or if the server changes. .INDENT 0.0 .IP \(bu 2 . \fBDefault\fP: false .UNINDENT .SS ignoreimport .sp A parameter that can be used in commit hooks, since it enables you to parse\-check a single file rather than requiring that all files exist. .INDENT 0.0 .IP \(bu 2 . \fBDefault\fP: false .UNINDENT .SS ignoreschedules .sp Boolean; whether puppetd should ignore schedules. This is useful for initial puppetd runs. .INDENT 0.0 .IP \(bu 2 . \fBDefault\fP: false .UNINDENT .SS keylength .sp The bit length of keys. .INDENT 0.0 .IP \(bu 2 . \fBDefault\fP: 1024 .UNINDENT .SS ldapattrs .sp The LDAP attributes to include when querying LDAP for nodes. All returned attributes are set as variables in the top\-level scope. Multiple values should be comma\-separated. The value \(aqall\(aq returns all attributes. .INDENT 0.0 .IP \(bu 2 . \fBDefault\fP: all .UNINDENT .SS ldapbase .sp The search base for LDAP searches. It\(aqs impossible to provide a meaningful default here, although the LDAP libraries might have one already set. Generally, it should be the \(aqou=Hosts\(aq branch under your main directory. .SS ldapclassattrs .sp The LDAP attributes to use to define Puppet classes. Values should be comma\-separated. .INDENT 0.0 .IP \(bu 2 . \fBDefault\fP: puppetclass .UNINDENT .SS ldapnodes .sp -Whether to search for node configurations in LDAP. See \fI\%http://reductivelabs.com/trac/puppet/wiki/LDAPNodes\fP for more information. +Whether to search for node configurations in LDAP. See \fI\%http://puppetlabs.com/trac/puppet/wiki/LDAPNodes\fP for more information. .INDENT 0.0 .IP \(bu 2 . \fBDefault\fP: false .UNINDENT .SS ldapparentattr .sp The attribute to use to define the parent node. .INDENT 0.0 .IP \(bu 2 . \fBDefault\fP: parentnode .UNINDENT .SS ldappassword .sp The password to use to connect to LDAP. .SS ldapport .sp The LDAP port. Only used if \fBldapnodes\fP is enabled. .INDENT 0.0 .IP \(bu 2 . \fBDefault\fP: 389 .UNINDENT .SS ldapserver .sp The LDAP server. Only used if \fBldapnodes\fP is enabled. .INDENT 0.0 .IP \(bu 2 . \fBDefault\fP: ldap .UNINDENT .SS ldapssl .sp Whether SSL should be used when searching for nodes. Defaults to false because SSL usually requires certificates to be set up on the client side. .INDENT 0.0 .IP \(bu 2 . \fBDefault\fP: false .UNINDENT .SS ldapstackedattrs .sp The LDAP attributes that should be stacked to arrays by adding the values in all hierarchy elements of the tree. Values should be comma\-separated. .INDENT 0.0 .IP \(bu 2 . \fBDefault\fP: puppetvar .UNINDENT .SS ldapstring .sp The search string used to find an LDAP node. .INDENT 0.0 .IP \(bu 2 . \fBDefault\fP: (&(objectclass=puppetClient)(cn=%s)) .UNINDENT .SS ldaptls .sp Whether TLS should be used when searching for nodes. Defaults to false because TLS usually requires certificates to be set up on the client side. .INDENT 0.0 .IP \(bu 2 . \fBDefault\fP: false .UNINDENT .SS ldapuser .sp The user to use to connect to LDAP. Must be specified as a full DN. .SS lexical .sp Whether to use lexical scoping (vs. dynamic). .INDENT 0.0 .IP \(bu 2 . \fBDefault\fP: false .UNINDENT .SS libdir .sp An extra search path for Puppet. This is only useful for those files that Puppet will load on demand, and is only guaranteed to work for those cases. In fact, the autoload mechanism is responsible for making sure this directory is in Ruby\(aqs search path .INDENT 0.0 .IP \(bu 2 . \fBDefault\fP: $vardir/lib .UNINDENT .SS listen .sp Whether puppetd should listen for connections. If this is true, then by default only the \fBrunner\fP server is started, which allows remote authorized and authenticated nodes to connect and trigger \fBpuppetd\fP runs. .INDENT 0.0 .IP \(bu 2 . \fBDefault\fP: false .UNINDENT .SS localcacert .sp Where each client stores the CA certificate. .INDENT 0.0 .IP \(bu 2 . \fBDefault\fP: $certdir/ca.pem .UNINDENT .SS localconfig .sp Where puppetd caches the local configuration. An extension indicating the cache format is added automatically. .INDENT 0.0 .IP \(bu 2 . \fBDefault\fP: $statedir/localconfig .UNINDENT .SS logdir .sp The Puppet log directory. .INDENT 0.0 .IP \(bu 2 . \fBDefault\fP: $vardir/log .UNINDENT .SS manage_internal_file_permissions .sp Whether Puppet should manage the owner, group, and mode of files it uses internally .INDENT 0.0 .IP \(bu 2 . \fBDefault\fP: true .UNINDENT .SS manifest .sp The entry\-point manifest for puppetmasterd. .INDENT 0.0 .IP \(bu 2 . \fBDefault\fP: $manifestdir/site.pp .UNINDENT .SS manifestdir .sp Where puppetmasterd looks for its manifests. .INDENT 0.0 .IP \(bu 2 . \fBDefault\fP: $confdir/manifests .UNINDENT .SS masterhttplog .sp Where the puppetmasterd web server logs. .INDENT 0.0 .IP \(bu 2 . \fBDefault\fP: $logdir/masterhttp.log .UNINDENT .SS masterlog .sp Where puppetmasterd logs. This is generally not used, since syslog is the default log destination. .INDENT 0.0 .IP \(bu 2 . \fBDefault\fP: $logdir/puppetmaster.log .UNINDENT .SS masterport .sp Which port puppetmasterd listens on. .INDENT 0.0 .IP \(bu 2 . \fBDefault\fP: 8140 .UNINDENT .SS maximum_uid .sp The maximum allowed UID. Some platforms use negative UIDs but then ship with tools that do not know how to handle signed ints, so the UIDs show up as huge numbers that can then not be fed back into the system. This is a hackish way to fail in a slightly more useful way when that happens. .INDENT 0.0 .IP \(bu 2 . \fBDefault\fP: 4294967290 .UNINDENT .SS mkusers .sp Whether to create the necessary user and group that puppetd will run as. .INDENT 0.0 .IP \(bu 2 . \fBDefault\fP: false .UNINDENT .SS modulepath .sp The search path for modules as a colon\-separated list of directories. .INDENT 0.0 .IP \(bu 2 . \fBDefault\fP: $confdir/modules:/usr/share/puppet/modules .UNINDENT .SS name .sp The name of the service, if we are running as one. The default is essentially $0 without the path or \fB.rb\fP. .INDENT 0.0 .IP \(bu 2 . \fBDefault\fP: puppetdoc .UNINDENT .SS node_name .sp How the puppetmaster determines the client\(aqs identity and sets the \(aqhostname\(aq, \(aqfqdn\(aq and \(aqdomain\(aq facts for use in the manifest, in particular for determining which \(aqnode\(aq statement applies to the client. Possible values are \(aqcert\(aq (use the subject\(aqs CN in the client\(aqs certificate) and \(aqfacter\(aq (use the hostname that the client reported in its facts) .INDENT 0.0 .IP \(bu 2 . \fBDefault\fP: cert .UNINDENT .SS node_terminus .sp Where to find information about nodes. .INDENT 0.0 .IP \(bu 2 . \fBDefault\fP: plain .UNINDENT .SS noop .sp Whether puppetd should be run in noop mode. .INDENT 0.0 .IP \(bu 2 . \fBDefault\fP: false .UNINDENT .SS paramcheck .sp Whether to validate parameters during parsing. .INDENT 0.0 .IP \(bu 2 . \fBDefault\fP: true .UNINDENT .SS parseonly .sp Just check the syntax of the manifests. .INDENT 0.0 .IP \(bu 2 . \fBDefault\fP: false .UNINDENT .SS passfile .sp Where puppetd stores the password for its private key. Generally unused. .INDENT 0.0 .IP \(bu 2 . \fBDefault\fP: $privatedir/password .UNINDENT .SS path .sp The shell search path. Defaults to whatever is inherited from the parent process. .INDENT 0.0 .IP \(bu 2 . \fBDefault\fP: none .UNINDENT .SS pidfile .sp The pid file .INDENT 0.0 .IP \(bu 2 . \fBDefault\fP: $rundir/$name.pid .UNINDENT .SS plugindest .sp Where Puppet should store plugins that it pulls down from the central server. .INDENT 0.0 .IP \(bu 2 . \fBDefault\fP: $libdir .UNINDENT .SS pluginsignore .sp What files to ignore when pulling down plugins. .INDENT 0.0 .IP \(bu 2 . \fBDefault\fP: .svn CVS .git .UNINDENT .SS pluginsource .sp From where to retrieve plugins. The standard Puppet \fBfile\fP type is used for retrieval, so anything that is a valid file source can be used here. .INDENT 0.0 .IP \(bu 2 . \fBDefault\fP: puppet://$server/plugins .UNINDENT .SS pluginsync .sp Whether plugins should be synced with the central server. .INDENT 0.0 .IP \(bu 2 . \fBDefault\fP: false .UNINDENT .SS postrun_command .sp A command to run after every agent run. If this command returns a non\-zero return code, the entire Puppet run will be considered to have failed, even though it might have performed work during the normal run. .SS preferred_serialization_format .sp The preferred means of serializing ruby instances for passing over the wire. This won\(aqt guarantee that all instances will be serialized using this method, since not all classes can be guaranteed to support this format, but it will be used for all classes that support it. .INDENT 0.0 .IP \(bu 2 . \fBDefault\fP: pson .UNINDENT .SS prerun_command .sp A command to run before every agent run. If this command returns a non\-zero return code, the entire Puppet run will fail. .SS privatedir .sp Where the client stores private certificate information. .INDENT 0.0 .IP \(bu 2 . \fBDefault\fP: $ssldir/private .UNINDENT .SS privatekeydir .sp The private key directory. .INDENT 0.0 .IP \(bu 2 . \fBDefault\fP: $ssldir/private_keys .UNINDENT .SS publickeydir .sp The public key directory. .INDENT 0.0 .IP \(bu 2 . \fBDefault\fP: $ssldir/public_keys .UNINDENT .SS puppetdlockfile .sp A lock file to temporarily stop puppetd from doing anything. .INDENT 0.0 .IP \(bu 2 . \fBDefault\fP: $statedir/puppetdlock .UNINDENT .SS puppetdlog .sp The log file for puppetd. This is generally not used. .INDENT 0.0 .IP \(bu 2 . \fBDefault\fP: $logdir/puppetd.log .UNINDENT .SS puppetport .sp Which port puppetd listens on. .INDENT 0.0 .IP \(bu 2 . \fBDefault\fP: 8139 .UNINDENT .SS queue_source .sp Which type of queue to use for asynchronous processing. If your stomp server requires authentication, you can include it in the URI as long as your stomp client library is at least 1.1.1 .INDENT 0.0 .IP \(bu 2 . \fBDefault\fP: stomp://localhost:61613/ .UNINDENT .SS queue_type .sp Which type of queue to use for asynchronous processing. .INDENT 0.0 .IP \(bu 2 . \fBDefault\fP: stomp .UNINDENT .SS rails_loglevel .sp The log level for Rails connections. The value must be a valid log level within Rails. Production environments normally use \fBinfo\fP and other environments normally use \fBdebug\fP. .INDENT 0.0 .IP \(bu 2 . \fBDefault\fP: info .UNINDENT .SS railslog .sp Where Rails\-specific logs are sent .INDENT 0.0 .IP \(bu 2 . \fBDefault\fP: $logdir/rails.log .UNINDENT .SS report .sp Whether to send reports after every transaction. .INDENT 0.0 .IP \(bu 2 . \fBDefault\fP: false .UNINDENT .SS report_port .sp The port to communicate with the report_server. .INDENT 0.0 .IP \(bu 2 . \fBDefault\fP: $masterport .UNINDENT .SS report_server .sp The server to which to send transaction reports. .INDENT 0.0 .IP \(bu 2 . \fBDefault\fP: $server .UNINDENT .SS reportdir .sp The directory in which to store reports received from the client. Each client gets a separate subdirectory. .INDENT 0.0 .IP \(bu 2 . \fBDefault\fP: $vardir/reports .UNINDENT .SS reportfrom .sp The \(aqfrom\(aq email address for the reports. .INDENT 0.0 .IP \(bu 2 . \fBDefault\fP: \fI\%report@pelin.lovedthanlost.net\fP .UNINDENT .SS reports .sp The list of reports to generate. All reports are looked for in puppet/reports/.rb, and multiple report names should be comma\-separated (whitespace is okay). .INDENT 0.0 .IP \(bu 2 . \fBDefault\fP: store .UNINDENT .SS reportserver .sp (Deprecated for \(aqreport_server\(aq) The server to which to send transaction reports. .INDENT 0.0 .IP \(bu 2 . \fBDefault\fP: $server .UNINDENT .SS req_bits .sp The bit length of the certificates. .INDENT 0.0 .IP \(bu 2 . \fBDefault\fP: 2048 .UNINDENT .SS requestdir .sp Where host certificate requests are stored. .INDENT 0.0 .IP \(bu 2 . \fBDefault\fP: $ssldir/certificate_requests .UNINDENT .SS rest_authconfig .sp The configuration file that defines the rights to the different rest indirections. This can be used as a fine\-grained authorization system for \fBpuppetmasterd\fP. .INDENT 0.0 .IP \(bu 2 . \fBDefault\fP: $confdir/auth.conf .UNINDENT .SS rrddir .sp The directory where RRD database files are stored. Directories for each reporting host will be created under this directory. .INDENT 0.0 .IP \(bu 2 . \fBDefault\fP: $vardir/rrd .UNINDENT .SS rrdinterval .sp How often RRD should expect data. This should match how often the hosts report back to the server. .INDENT 0.0 .IP \(bu 2 . \fBDefault\fP: $runinterval .UNINDENT .SS rundir .sp Where Puppet PID files are kept. .INDENT 0.0 .IP \(bu 2 . \fBDefault\fP: $vardir/run .UNINDENT .SS runinterval .sp How often puppetd applies the client configuration; in seconds. .INDENT 0.0 .IP \(bu 2 . \fBDefault\fP: 1800 .UNINDENT .SS sendmail .sp Where to find the sendmail binary with which to send email. .INDENT 0.0 .IP \(bu 2 . \fBDefault\fP: /usr/sbin/sendmail .UNINDENT .SS serial .sp Where the serial number for certificates is stored. .INDENT 0.0 .IP \(bu 2 . \fBDefault\fP: $cadir/serial .UNINDENT .SS server .sp The server to which server puppetd should connect .INDENT 0.0 .IP \(bu 2 . \fBDefault\fP: puppet .UNINDENT .SS servertype .sp The type of server to use. Currently supported options are webrick and mongrel. If you use mongrel, you will need a proxy in front of the process or processes, since Mongrel cannot speak SSL. .INDENT 0.0 .IP \(bu 2 . \fBDefault\fP: webrick .UNINDENT .SS show_diff .sp Whether to print a contextual diff when files are being replaced. The diff is printed on stdout, so this option is meaningless unless you are running Puppet interactively. This feature currently requires the \fBdiff/lcs\fP Ruby library. .INDENT 0.0 .IP \(bu 2 . \fBDefault\fP: false .UNINDENT .SS signeddir .sp Where the CA stores signed certificates. .INDENT 0.0 .IP \(bu 2 . \fBDefault\fP: $cadir/signed .UNINDENT .SS smtpserver .sp The server through which to send email reports. .INDENT 0.0 .IP \(bu 2 . \fBDefault\fP: none .UNINDENT .SS splay .sp Whether to sleep for a pseudo\-random (but consistent) amount of time before a run. .INDENT 0.0 .IP \(bu 2 . \fBDefault\fP: false .UNINDENT .SS splaylimit .sp The maximum time to delay before runs. Defaults to being the same as the run interval. .INDENT 0.0 .IP \(bu 2 . \fBDefault\fP: $runinterval .UNINDENT .SS ssl_client_header .sp -The header containing an authenticated client\(aqs SSL DN. Only used with Mongrel. This header must be set by the proxy to the authenticated client\(aqs SSL DN (e.g., \fB/CN=puppet.reductivelabs.com\fP). See \fI\%http://reductivelabs.com/puppet/trac/wiki/UsingMongrel\fP for more information. +The header containing an authenticated client\(aqs SSL DN. Only used with Mongrel. This header must be set by the proxy to the authenticated client\(aqs SSL DN (e.g., \fB/CN=puppet.puppetlabs.com\fP). See \fI\%http://puppetlabs.com/puppet/trac/wiki/UsingMongrel\fP for more information. .INDENT 0.0 .IP \(bu 2 . \fBDefault\fP: HTTP_X_CLIENT_DN .UNINDENT .SS ssl_client_verify_header .sp -The header containing the status message of the client verification. Only used with Mongrel. This header must be set by the proxy to \(aqSUCCESS\(aq if the client successfully authenticated, and anything else otherwise. See \fI\%http://reductivelabs.com/puppet/trac/wiki/UsingMongrel\fP for more information. +The header containing the status message of the client verification. Only used with Mongrel. This header must be set by the proxy to \(aqSUCCESS\(aq if the client successfully authenticated, and anything else otherwise. See \fI\%http://puppetlabs.com/puppet/trac/wiki/UsingMongrel\fP for more information. .INDENT 0.0 .IP \(bu 2 . \fBDefault\fP: HTTP_X_CLIENT_VERIFY .UNINDENT .SS ssldir .sp Where SSL certificates are kept. .INDENT 0.0 .IP \(bu 2 . \fBDefault\fP: $confdir/ssl .UNINDENT .SS statedir .sp The directory where Puppet state is stored. Generally, this directory can be removed without causing harm (although it might result in spurious service restarts). .INDENT 0.0 .IP \(bu 2 . \fBDefault\fP: $vardir/state .UNINDENT .SS statefile .sp 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. .INDENT 0.0 .IP \(bu 2 . \fBDefault\fP: $statedir/state.yaml .UNINDENT .SS storeconfigs .sp Whether to store each client\(aqs configuration. This requires ActiveRecord from Ruby on Rails. .INDENT 0.0 .IP \(bu 2 . \fBDefault\fP: false .UNINDENT .SS strict_hostname_checking .sp Whether to only search for the complete hostname as it is in the certificate when searching for node information in the catalogs. .INDENT 0.0 .IP \(bu 2 . \fBDefault\fP: false .UNINDENT .SS summarize .sp Whether to print a transaction summary. .INDENT 0.0 .IP \(bu 2 . \fBDefault\fP: false .UNINDENT .SS syslogfacility .sp What syslog facility to use when logging to syslog. Syslog has a fixed list of valid facilities, and you must choose one of those; you cannot just make one up. .INDENT 0.0 .IP \(bu 2 . \fBDefault\fP: daemon .UNINDENT .SS tagmap .sp The mapping between reporting tags and email addresses. .INDENT 0.0 .IP \(bu 2 . \fBDefault\fP: $confdir/tagmail.conf .UNINDENT .SS tags .sp Tags to use to find resources. If this is set, then only resources tagged with the specified tags will be applied. Values must be comma\-separated. .SS templatedir .sp Where Puppet looks for template files. Can be a list of colon\-seperated directories. .INDENT 0.0 .IP \(bu 2 . \fBDefault\fP: $vardir/templates .UNINDENT .SS thin_storeconfigs .sp Boolean; wether storeconfigs store in the database only the facts and exported resources. If true, then storeconfigs performance will be higher and still allow exported/collected resources, but other usage external to Puppet might not work .INDENT 0.0 .IP \(bu 2 . \fBDefault\fP: false .UNINDENT .SS trace .sp Whether to print stack traces on some errors .INDENT 0.0 .IP \(bu 2 . \fBDefault\fP: false .UNINDENT .SS typecheck .sp Whether to validate types during parsing. .INDENT 0.0 .IP \(bu 2 . \fBDefault\fP: true .UNINDENT .SS use_cached_catalog .sp Whether to only use the cached catalog rather than compiling a new catalog on every run. Puppet can be run with this enabled by default and then selectively disabled when a recompile is desired. .INDENT 0.0 .IP \(bu 2 . \fBDefault\fP: false .UNINDENT .SS usecacheonfailure .sp Whether to use the cached configuration when the remote configuration will not compile. This option is useful for testing new configurations, where you want to fix the broken configuration rather than reverting to a known\-good one. .INDENT 0.0 .IP \(bu 2 . \fBDefault\fP: true .UNINDENT .SS user .sp The user puppetmasterd should run as. .INDENT 0.0 .IP \(bu 2 . \fBDefault\fP: puppet .UNINDENT .SS vardir .sp Where Puppet stores dynamic and growing data. The default for this parameter is calculated specially, like \fI\%confdir\fP. .INDENT 0.0 .IP \(bu 2 . \fBDefault\fP: /var/lib/puppet .UNINDENT .SS yamldir .sp The directory in which YAML data is stored, usually in a subdirectory. .INDENT 0.0 .IP \(bu 2 . \fBDefault\fP: $vardir/yaml .UNINDENT .SS zlib .sp Boolean; whether to use the zlib library .INDENT 0.0 .IP \(bu 2 . \fBDefault\fP: true .UNINDENT .sp .ce ---- .ce 0 .sp .sp \fIThis page autogenerated on Sun Apr 11 17:57:48 \-0400 2010\fP .\" Generated by docutils manpage writer. .\" . diff --git a/man/man8/filebucket.8 b/man/man8/filebucket.8 index de2dee733..4421ad137 100644 --- a/man/man8/filebucket.8 +++ b/man/man8/filebucket.8 @@ -1,107 +1,107 @@ .TH "" "" "" .SH NAME \- .\" Man page generated from reStructeredText. . .SH SYNOPSIS .sp A stand\-alone Puppet filebucket client. .SH USAGE .INDENT 0.0 .INDENT 3.5 .INDENT 0.0 .TP .B filebucket [\-h|\-\-help] [\-V|\-\-version] [\-d|\-\-debug] [\-v|\-\-verbose] . [\-l|\-\-local] [\-r|\-\-remote] [\-s|\-\-server ] [\-b|\-\-bucket ] ... .UNINDENT .UNINDENT .UNINDENT .SH DESCRIPTION .sp This is a stand\-alone filebucket client for sending files to a local or central filebucket. .SH USAGE .sp This client can operate in three modes, with only one mode per call: .INDENT 0.0 .TP .B backup: Send one or more files to the specified file bucket. Each sent . file is printed with its resulting md5 sum. .TP .B get: Return the text associated with an md5 sum. The text is printed . to stdout, and only one file can be retrieved at a time. .TP .B restore: Given a file path and an md5 sum, store the content associated . with the sum into the specified file path. You can specify an entirely new path to this argument; you are not restricted to restoring the content to its original location. .UNINDENT .sp Note that +filebucket+ defaults to using a network\-based filebucket available on the server named +puppet+. To use this, you\(aqll have to be running as a user with valid Puppet certificates. Alternatively, you can use your local file bucket by specifying +\-\-local+. .SH EXAMPLE .INDENT 0.0 .INDENT 3.5 .sp $ filebucket backup /etc/passwd /etc/passwd: 429b225650b912a2ee067b0a4cf1e949 $ filebucket restore /tmp/passwd 429b225650b912a2ee067b0a4cf1e949 $ .UNINDENT .UNINDENT .SH OPTIONS .sp Note that any configuration parameter that\(aqs valid in the configuration file is also a valid long argument. For example, \(aqssldir\(aq is a valid configuration parameter, so you can specify \(aq\-\-ssldir \(aq as an argument. .sp See the configuration file documentation at -\fI\%http://reductivelabs.com/trac/puppet/wiki/ConfigurationReference\fP for the +\fI\%http://puppetlabs.com/trac/puppet/wiki/ConfigurationReference\fP for the full list of acceptable parameters. A commented list of all configuration options can also be generated by running puppet with \(aq\-\-genconfig\(aq. .sp debug: Enable full debugging. .sp help: Print this help message .INDENT 0.0 .TP .B local: Use the local filebucket. This will use the default . configuration information. .TP .B remote: Use a remote filebucket. This will use the default . configuration information. .UNINDENT .sp server: The server to send the file to, instead of locally. .sp verbose: Print extra information. .sp version: Print version information. .SH EXAMPLE .INDENT 0.0 .INDENT 3.5 .sp filebucket \-b /tmp/filebucket /my/file .UNINDENT .UNINDENT .SH AUTHOR .sp Luke Kanies .SH COPYRIGHT .sp -Copyright (c) 2005 Reductive Labs, LLC Licensed under the GNU Public +Copyright (c) 2005 Puppet Labs, LLC Licensed under the GNU Public License .\" Generated by docutils manpage writer. .\" . diff --git a/man/man8/pi.8 b/man/man8/pi.8 index 519be2ca9..cb57dc389 100644 --- a/man/man8/pi.8 +++ b/man/man8/pi.8 @@ -1,50 +1,50 @@ .TH "" "" "" .SH NAME \- .\" Man page generated from reStructeredText. . .SH SYNOPSIS .sp Print help about puppet types on the console. Run with \(aq\-h\(aq to get detailed help. .SH USAGE .INDENT 0.0 .INDENT 3.5 .sp pi [\-h|\-\-help] [\-s|\-\-short] [\-p|\-\-providers] [\-l|\-\-list] [\-m|\-\-meta] .UNINDENT .UNINDENT .SH DESCRIPTION .sp Prints details of Puppet types, providers and metaparameters on the console. .SH OPTIONS .sp help: Print this help text .sp providers: Describe providers in detail for each type .sp list: List all types .sp meta: List all metaparameters .sp short: List only parameters without detail .SH EXAMPLE .INDENT 0.0 .INDENT 3.5 .sp pi \-\-list pi file \-\-providers pi user \-s \-m .UNINDENT .UNINDENT .SH AUTHOR .sp David Lutterkort .SH COPYRIGHT .sp -Copyright (c) 2005 Reductive Labs, LLC Licensed under the GNU Public +Copyright (c) 2005 Puppet Labs, LLC Licensed under the GNU Public License .\" Generated by docutils manpage writer. .\" . diff --git a/man/man8/puppet.8 b/man/man8/puppet.8 index 02176ce81..ede96be20 100644 --- a/man/man8/puppet.8 +++ b/man/man8/puppet.8 @@ -1,82 +1,82 @@ .TH "" "" "" .SH NAME \- .\" Man page generated from reStructeredText. . .SH SYNOPSIS .sp Run a stand\-alone +puppet+ manifest. .SH USAGE .INDENT 0.0 .INDENT 3.5 .INDENT 0.0 .TP .B puppet [\-h|\-\-help] [\-V|\-\-version] [\-d|\-\-debug] [\-v|\-\-verbose] [\-e|\-\-execute] . [\-\-detailed\-exitcodes] [\-l|\-\-logdest ] .UNINDENT .UNINDENT .UNINDENT .SH DESCRIPTION .sp This is the standalone puppet execution tool; use it to execute individual manifests that you write. If you need to execute site\-wide manifests, use +puppetd+ and +puppetmasterd+. .SH OPTIONS .sp Note that any configuration parameter that\(aqs valid in the configuration file is also a valid long argument. For example, \(aqssldir\(aq is a valid configuration parameter, so you can specify \(aq\-\-ssldir \(aq as an argument. .sp See the configuration file documentation at -\fI\%http://reductivelabs.com/trac/puppet/wiki/ConfigurationReference\fP for the +\fI\%http://puppetlabs.com/trac/puppet/wiki/ConfigurationReference\fP for the full list of acceptable parameters. A commented list of all configuration options can also be generated by running puppet with \(aq\-\-genconfig\(aq. .sp debug: Enable full debugging. .INDENT 0.0 .TP .B detailed\-exitcodes: Provide transaction information via exit codes. If . this is enabled, an exit code of \(aq2\(aq means there were changes, and an exit code of \(aq4\(aq means that there were failures during the transaction. .UNINDENT .sp help: Print this help message .INDENT 0.0 .TP .B loadclasses: Load any stored classes. +puppetd+ caches configured . classes (usually at /etc/puppet/classes.txt), and setting this option causes all of those classes to be set in your +puppet+ manifest. .TP .B logdest: Where to send messages. Choose between syslog, the . console, and a log file. Defaults to sending messages to the console. .UNINDENT .sp execute: Execute a specific piece of Puppet code .sp verbose: Print extra information. .SH EXAMPLE .INDENT 0.0 .INDENT 3.5 .sp puppet \-l /tmp/manifest.log manifest.pp .UNINDENT .UNINDENT .SH AUTHOR .sp Luke Kanies .SH COPYRIGHT .sp -Copyright (c) 2005 Reductive Labs, LLC Licensed under the GNU Public +Copyright (c) 2005 Puppet Labs, LLC Licensed under the GNU Public License .\" Generated by docutils manpage writer. .\" . diff --git a/man/man8/puppetca.8 b/man/man8/puppetca.8 index 92e9de1b1..a94ea03a1 100644 --- a/man/man8/puppetca.8 +++ b/man/man8/puppetca.8 @@ -1,115 +1,115 @@ .TH "" "" "" .SH NAME \- .\" Man page generated from reStructeredText. . .SH SYNOPSIS .sp Stand\-alone certificate authority. Capable of generating certificates but mostly meant for signing certificate requests from puppet clients. .SH USAGE .INDENT 0.0 .INDENT 3.5 .INDENT 0.0 .TP .B puppetca [\-h|\-\-help] [\-V|\-\-version] [\-d|\-\-debug] [\-v|\-\-verbose] . [\-g|\-\-generate] [\-l|\-\-list] [\-s|\-\-sign] [\-r|\-\-revoke] [\-p|\-\-print] [\-c|\-\-clean] [\-\-verify] [host] .UNINDENT .UNINDENT .UNINDENT .SH DESCRIPTION .sp Because the puppetmasterd daemon defaults to not signing client certificate requests, this script is available for signing outstanding requests. It can be used to list outstanding requests and then either sign them individually or sign all of them. .SH OPTIONS .sp Note that any configuration parameter that\(aqs valid in the configuration file is also a valid long argument. For example, \(aqssldir\(aq is a valid configuration parameter, so you can specify \(aq\-\-ssldir \(aq as an argument. .sp See the configuration file documentation at -\fI\%http://reductivelabs.com/projects/puppet/reference/configref.html\fP for +\fI\%http://puppetlabs.com/projects/puppet/reference/configref.html\fP for the full list of acceptable parameters. A commented list of all configuration options can also be generated by running puppetca with \(aq\-\-genconfig\(aq. .INDENT 0.0 .TP .B all: Operate on all items. Currently only makes sense with . \(aq\-\-sign\(aq, \(aq\-\-clean\(aq, or \(aq\-\-list\(aq. .TP .B clean: Remove all files related to a host from puppetca\(aqs storage. . This is useful when rebuilding hosts, since new certificate signing requests will only be honored if puppetca does not have a copy of a signed certificate for that host. The certificate of the host remains valid. If \(aq\-\-all\(aq is specified then all host certificates, both signed and unsigned, will be removed. .UNINDENT .sp debug: Enable full debugging. .INDENT 0.0 .TP .B generate: Generate a certificate for a named client. A . certificate/keypair will be generated for each client named on the command line. .UNINDENT .sp help: Print this help message .INDENT 0.0 .TP .B list: List outstanding certificate requests. If \(aq\-\-all\(aq is . specified, signed certificates are also listed, prefixed by \(aq+\(aq, and revoked or invalid certificates are prefixed by \(aq\-\(aq (the verification outcome is printed in parenthesis). .UNINDENT .sp print: Print the full\-text version of a host\(aqs certificate. .INDENT 0.0 .TP .B revoke: Revoke the certificate of a client. The certificate can be . specified either by its serial number, given as a decimal number or a hexadecimal number prefixed by \(aq0x\(aq, or by its hostname. The certificate is revoked by adding it to the Certificate Revocation List given by the \(aqcacrl\(aq config parameter. Note that the puppetmasterd needs to be restarted after revoking certificates. .TP .B sign: Sign an outstanding certificate request. Unless \(aq\-\-all\(aq is . specified, hosts must be listed after all flags. .UNINDENT .sp verbose: Enable verbosity. .sp version: Print the puppet version number and exit. .sp verify: Verify the named certificate against the local CA certificate. .SH EXAMPLE .INDENT 0.0 .INDENT 3.5 .sp $ puppetca \-l culain.madstop.com $ puppetca \-s culain.madstop.com .UNINDENT .UNINDENT .SH AUTHOR .sp Luke Kanies .SH COPYRIGHT .sp -Copyright (c) 2005 Reductive Labs, LLC Licensed under the GNU Public +Copyright (c) 2005 Puppet Labs, LLC Licensed under the GNU Public License .\" Generated by docutils manpage writer. .\" . diff --git a/man/man8/puppetd.8 b/man/man8/puppetd.8 index c2d5cb530..ed40fff78 100644 --- a/man/man8/puppetd.8 +++ b/man/man8/puppetd.8 @@ -1,185 +1,185 @@ .TH SYNOPSIS "" "" "" .SH NAME Synopsis \- .\" Man page generated from reStructeredText. . .sp Retrieve the client configuration from the central puppet server and apply it to the local host. .sp Currently must be run out periodically, using cron or something similar. .SH USAGE .INDENT 0.0 .INDENT 3.5 .INDENT 0.0 .TP .B puppetd [\-D|\-\-daemonize|\-\-no\-daemonize] [\-d|\-\-debug] [\-\-disable] [\-\-enable] . [\-h|\-\-help] [\-\-fqdn ] [\-l|\-\-logdest syslog||console] [\-o|\-\-onetime] [\-\-serve ] [\-t|\-\-test] [\-\-noop] [\-V|\-\-version] [\-v|\-\-verbose] [\-w|\-\-waitforcert ] .UNINDENT .UNINDENT .UNINDENT .SH DESCRIPTION .sp This is the main puppet client. Its job is to retrieve the local machine\(aqs 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. .sp Once the client has a signed certificate, it will retrieve its configuration and apply it. .SH USAGE NOTES .sp +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. .sp Some flags are meant specifically for interactive use \-\- in particular, +test+ and +tags+ are useful. +test+ enables verbose logging, causes the daemon to stay in the foreground, exits if the server\(aqs configuration is invalid (this happens if, for instance, you\(aqve left a syntax error on the server), and exits after running the configuration once (rather than hanging around as a long\-running process). .sp +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. .SH OPTIONS .sp Note that any configuration parameter that\(aqs valid in the configuration file is also a valid long argument. For example, \(aqserver\(aq is a valid configuration parameter, so you can specify \(aq\-\-server \(aq as an argument. .sp See the configuration file documentation at -\fI\%http://reductivelabs.com/trac/puppet/wiki/ConfigurationReference\fP for the +\fI\%http://puppetlabs.com/trac/puppet/wiki/ConfigurationReference\fP for the full list of acceptable parameters. A commented list of all configuration options can also be generated by running puppetd with \(aq\-\-genconfig\(aq. .sp daemonize: Send the process into the background. This is the default. .sp no\-daemonize: Do not send the process into the background. .sp debug: Enable full debugging. .INDENT 0.0 .TP .B 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. .UNINDENT .sp +puppetd+ uses the same lock file while it is running, so no more than one +puppetd+ process is working at a time. .sp +puppetd+ exits after executing this. .INDENT 0.0 .TP .B 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). .UNINDENT .sp +puppetd+ exits after executing this. .INDENT 0.0 .TP .B 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. .UNINDENT .sp help: Print this help message .INDENT 0.0 .TP .B 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. .TP .B 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. .TP .B onetime: Run the configuration once. Runs a single daemonized . Puppet run. Useful for interactively running puppetd and hence used in conjunction with the \-\-no\-daemonize option. .TP .B 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+. .TP .B test: Enable the most common options used for testing. These are . +onetime+, +verbose+, +ignorecache, +no\-daemonize+, and +no\-usecacheonfailure+. .TP .B noop: Use +noop+ mode where the daemon runs in a no\-op or . dry\-run mode. This is useful for seeing what changes Puppet will make without actually executing the changes. .UNINDENT .sp verbose: Turn on verbose reporting. .sp version: Print the puppet version number and exit. .INDENT 0.0 .TP .B 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. .UNINDENT .SH EXAMPLE .INDENT 0.0 .INDENT 3.5 .sp puppetd \-\-server puppet.domain.com .UNINDENT .UNINDENT .SH AUTHOR .sp Luke Kanies .SH COPYRIGHT .sp -Copyright (c) 2005, 2006 Reductive Labs, LLC Licensed under the GNU +Copyright (c) 2005, 2006 Puppet Labs, LLC Licensed under the GNU Public License .\" Generated by docutils manpage writer. .\" . diff --git a/man/man8/puppetdoc.8 b/man/man8/puppetdoc.8 index 5cf7269f0..cf64a7bff 100644 --- a/man/man8/puppetdoc.8 +++ b/man/man8/puppetdoc.8 @@ -1,104 +1,104 @@ .TH "" "" "" .SH NAME \- .\" Man page generated from reStructeredText. . .SH SYNOPSIS .sp Generate a reference for all Puppet types. Largely meant for internal -Reductive Labs use. +Puppet Labs use. .SH USAGE .INDENT 0.0 .INDENT 3.5 .INDENT 0.0 .TP .B puppetdoc [\-a|\-\-all] [\-h|\-\-help] [\-o|\-\-outputdir ] [\-m|\-\-mode ] . [\-r|\-\-reference <[type]|configuration|..>] [manifest\-file] .UNINDENT .UNINDENT .UNINDENT .SH DESCRIPTION .sp If mode is not \(aqrdoc\(aq, then this command generates a restructured\-text document describing all installed Puppet types or all allowable arguments to puppet executables. It is largely meant for internal use and is used to generate the reference document available on the -Reductive Labs web site. +Puppet Labs web site. .sp In \(aqrdoc\(aq mode, this command generates an html RDoc hierarchy describing the manifests that are in \(aqmanifestdir\(aq and \(aqmodulepath\(aq configuration directives. The generated documentation directory is doc by default but can be changed with the \(aqoutputdir\(aq option. .sp If the command is started with \(aqmanifest\-file\(aq command\-line arguments, puppetdoc generate a single manifest documentation that is output on stdout. .SH OPTIONS .INDENT 0.0 .TP .B all: Output the docs for all of the reference types. In \(aqrdoc\(aq . modes, this also outputs documentation for all resources .UNINDENT .sp help: Print this help message .INDENT 0.0 .TP .B outputdir: Specifies the directory where to output the rdoc . documentation in \(aqrdoc\(aq mode. .TP .B mode: Determine the output mode. Valid modes are \(aqtext\(aq, \(aqtrac\(aq, . \(aqpdf\(aq, \(aqmarkdown\(aq and \(aqrdoc\(aq. The \(aqpdf\(aq and \(aqmarkdown\(aq modes create PDF or Markdown formatted files in the /tmp directory. -Note that \(aqtrac\(aq mode only works on Reductive Labs servers. +Note that \(aqtrac\(aq mode only works on Puppet Labs servers. The default mode is \(aqtext\(aq. In \(aqrdoc\(aq mode you must provide \(aqmanifests\-path\(aq .TP .B reference: Build a particular reference. Get a list of references by . running +puppetdoc \-\-list+. .UNINDENT .SH EXAMPLE .INDENT 0.0 .INDENT 3.5 .sp $ puppetdoc \-r type > /tmp/type_reference.rst .UNINDENT .UNINDENT .sp or .INDENT 0.0 .INDENT 3.5 .sp $ puppetdoc \-\-outputdir /tmp/rdoc \-\-mode rdoc /path/to/manifests .UNINDENT .UNINDENT .sp or .INDENT 0.0 .INDENT 3.5 .sp $ puppetdoc /etc/puppet/manifests/site.pp .UNINDENT .UNINDENT .sp or .INDENT 0.0 .INDENT 3.5 .sp $ puppetdoc \-m markdown \-r configuration .UNINDENT .UNINDENT .SH AUTHOR .sp Luke Kanies .SH COPYRIGHT .sp -Copyright (c) 2005\-2007 Reductive Labs, LLC Licensed under the GNU +Copyright (c) 2005\-2007 Puppet Labs, LLC Licensed under the GNU Public License .\" Generated by docutils manpage writer. .\" . diff --git a/man/man8/puppetmasterd.8 b/man/man8/puppetmasterd.8 index 5bfea2ef2..17652fbd3 100644 --- a/man/man8/puppetmasterd.8 +++ b/man/man8/puppetmasterd.8 @@ -1,72 +1,72 @@ .TH "" "" "" .SH NAME \- .\" Man page generated from reStructeredText. . .SH SYNOPSIS .sp The central puppet server. Functions as a certificate authority by default. .SH USAGE .INDENT 0.0 .INDENT 3.5 .INDENT 0.0 .TP .B puppetmasterd [\-D|\-\-daemonize|\-\-no\-daemonize] [\-d|\-\-debug] [\-h|\-\-help] . [\-l|\-\-logdest |console|syslog] [\-v|\-\-verbose] [\-V|\-\-version] .UNINDENT .UNINDENT .UNINDENT .SH DESCRIPTION .sp This is the puppet central daemon. .SH OPTIONS .sp Note that any configuration parameter that\(aqs valid in the configuration file is also a valid long argument. For example, \(aqssldir\(aq is a valid configuration parameter, so you can specify \(aq\-\-ssldir \(aq as an argument. .sp See the configuration file documentation at -\fI\%http://reductivelabs.com/trac/puppet/wiki/ConfigurationReference\fP for the +\fI\%http://puppetlabs.com/trac/puppet/wiki/ConfigurationReference\fP for the full list of acceptable parameters. A commented list of all configuration options can also be generated by running puppetmasterdd with \(aq\-\-genconfig\(aq. .sp daemonize: Send the process into the background. This is the default. .sp no\-daemonize: Do not send the process into the background. .sp debug: Enable full debugging. .sp help: Print this help message. .INDENT 0.0 .TP .B 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. .UNINDENT .sp verbose: Enable verbosity. .sp version: Print the puppet version number and exit. .SH EXAMPLE .INDENT 0.0 .INDENT 3.5 .sp puppetmasterd .UNINDENT .UNINDENT .SH AUTHOR .sp Luke Kanies .SH COPYRIGHT .sp -Copyright (c) 2005 Reductive Labs, LLC Licensed under the GNU Public +Copyright (c) 2005 Puppet Labs, LLC Licensed under the GNU Public License .\" Generated by docutils manpage writer. .\" . diff --git a/man/man8/puppetqd.8 b/man/man8/puppetqd.8 index bf08f2bb2..14e9915ef 100644 --- a/man/man8/puppetqd.8 +++ b/man/man8/puppetqd.8 @@ -1,55 +1,55 @@ .TH SYNOPSIS "" "" "" .SH NAME Synopsis \- .\" Man page generated from reStructeredText. . .sp Retrieve serialized records from a queue and process them in order. .SH USAGE .INDENT 0.0 .INDENT 3.5 .sp puppetqd [\-d|\-\-debug] [\-v|\-\-verbose] .UNINDENT .UNINDENT .SH DESCRIPTION .sp This is a simple application that just processes entities in a queue as they are recieved. .SH OPTIONS .sp Note that any configuration parameter that\(aqs valid in the configuration file is also a valid long argument. For example, \(aqserver\(aq is a valid configuration parameter, so you can specify \(aq\-\-server \(aq as an argument. .sp See the configuration file documentation at -\fI\%http://reductivelabs.com/trac/puppet/wiki/ConfigurationReference\fP for the +\fI\%http://puppetlabs.com/trac/puppet/wiki/ConfigurationReference\fP for the full list of acceptable parameters. A commented list of all configuration options can also be generated by running puppetd with \(aq\-\-genconfig\(aq. .sp debug: Enable full debugging. .sp help: Print this help message .sp verbose: Turn on verbose reporting. .sp version: Print the puppet version number and exit. .SH EXAMPLE .INDENT 0.0 .INDENT 3.5 .sp puppetqd .UNINDENT .UNINDENT .SH AUTHOR .sp Luke Kanies .SH COPYRIGHT .sp -Copyright (c) 2009 Reductive Labs, LLC Licensed under the GNU Public +Copyright (c) 2009 Puppet Labs, LLC Licensed under the GNU Public License .\" Generated by docutils manpage writer. .\" . diff --git a/man/man8/puppetrun.8 b/man/man8/puppetrun.8 index 73a4ba3f2..c0116fdf7 100644 --- a/man/man8/puppetrun.8 +++ b/man/man8/puppetrun.8 @@ -1,152 +1,152 @@ .TH "" "" "" .SH NAME \- .\" Man page generated from reStructeredText. . .SH SYNOPSIS .sp Trigger a puppetd run on a set of hosts. .SH USAGE .INDENT 0.0 .INDENT 3.5 .INDENT 0.0 .TP .B puppetrun [\-a|\-\-all] [\-c|\-\-class ] [\-d|\-\-debug] [\-f|\-\-foreground] . [\-h|\-\-help] [\-\-host ] [\-\-no\-fqdn] [\-\-ignoreschedules] [\-t|\-\-tag ] [\-\-test] [\-p|\-\-ping] .UNINDENT .UNINDENT .UNINDENT .SH DESCRIPTION .sp This script can be used to connect to a set of machines running +puppetd+ and trigger them to run their configurations. The most common usage would be to specify a class of hosts and a set of tags, and +puppetrun+ would look up in LDAP all of the hosts matching that class, then connect to each host and trigger a run of all of the objects with the specified tags. .sp If you are not storing your host configurations in LDAP, you can specify hosts manually. .sp You will most likely have to run +puppetrun+ as root to get access to the SSL certificates. .sp +puppetrun+ reads +puppetmaster+\(aqs configuration file, so that it can copy things like LDAP settings. .SH USAGE NOTES .sp +puppetrun+ is useless unless +puppetd+ is listening. See its documentation for more information, but the gist is that you must enable +listen+ on the +puppetd+ daemon, either using +\-\-listen+ on the command line or adding \(aqlisten: true\(aq in its config file. In addition, you need to set the daemons up to specifically allow connections by creating the +namespaceauth+ file, normally at \(aq/etc/puppet/namespaceauth.conf\(aq. This file specifies who has access to each namespace; if you create the file you must add every namespace you want any Puppet daemon to allow \-\- it is currently global to all Puppet daemons. .sp An example file looks like this: .sp .nf .ft C [fileserver] allow *.madstop.com [puppetmaster] allow *.madstop.com [puppetrunner] allow culain.madstop.com .ft P .fi .sp This is what you would install on your Puppet master; non\-master hosts could leave off the \(aqfileserver\(aq and \(aqpuppetmaster\(aq namespaces. .sp Expect more documentation on this eventually. .SH OPTIONS .sp Note that any configuration parameter that\(aqs valid in the configuration file is also a valid long argument. For example, \(aqssldir\(aq is a valid configuration parameter, so you can specify \(aq\-\-ssldir \(aq as an argument. .sp See the configuration file documentation at -\fI\%http://reductivelabs.com/projects/puppet/reference/configref.html\fP for +\fI\%http://puppetlabs.com/projects/puppet/reference/configref.html\fP for the full list of acceptable parameters. A commented list of all configuration options can also be generated by running puppetmasterdd with \(aq\-\-genconfig\(aq. .INDENT 0.0 .TP .B all: Connect to all available hosts. Requires LDAP support . at this point. .TP .B class: Specify a class of machines to which to connect. This . only works if you have LDAP configured, at the moment. .UNINDENT .sp debug: Enable full debugging. .INDENT 0.0 .TP .B foreground: Run each configuration in the foreground; that is, when . connecting to a host, do not return until the host has finished its run. The default is false. .UNINDENT .sp help: Print this help message .INDENT 0.0 .TP .B host: A specific host to which to connect. This flag can be . specified more than once. .TP .B ignoreschedules: Whether the client should ignore schedules when running . its configuration. This can be used to force the client to perform work it would not normally perform so soon. The default is false. .TP .B parallel: How parallel to make the connections. Parallelization . is provided by forking for each client to which to connect. The default is 1, meaning serial execution. .TP .B tag: Specify a tag for selecting the objects to apply. Does . not work with the \-\-test option. .TP .B test: Print the hosts you would connect to but do not . actually connect. This option requires LDAP support at this point. .UNINDENT .sp ping: .sp .nf .ft C Do a ICMP echo against the target host. Skip hosts that don\(aqt respond to ping. .ft P .fi .SH EXAMPLE .INDENT 0.0 .INDENT 3.5 .sp sudo puppetrun \-p 10 \-\-host host1 \-\-host host2 \-t remotefile \-t webserver .UNINDENT .UNINDENT .SH AUTHOR .sp Luke Kanies .SH COPYRIGHT .sp -Copyright (c) 2005 Reductive Labs, LLC Licensed under the GNU Public +Copyright (c) 2005 Puppet Labs, LLC Licensed under the GNU Public License .\" Generated by docutils manpage writer. .\" . diff --git a/man/man8/ralsh.8 b/man/man8/ralsh.8 index 98892e0c9..c2c5c85e9 100644 --- a/man/man8/ralsh.8 +++ b/man/man8/ralsh.8 @@ -1,123 +1,123 @@ .TH "" "" "" .SH NAME \- .\" Man page generated from reStructeredText. . .sp vim: softtabstop=4 shiftwidth=4 expandtab .SH SYNOPSIS .sp Use the Puppet RAL to directly interact with the system. .SH USAGE .INDENT 0.0 .INDENT 3.5 .INDENT 0.0 .TP .B ralsh [\-h|\-\-help] [\-d|\-\-debug] [\-v|\-\-verbose] [\-e|\-\-edit] [\-H|\-\-host ] . [\-p|\-\-param ] [\-t|\-\-types] type .UNINDENT .UNINDENT .UNINDENT .SH DESCRIPTION .sp This command provides simple facilities for converting current system state into Puppet code, along with some ability to use Puppet to affect the current state. .sp By default, you must at least provide a type to list, which case ralsh will tell you everything it knows about all instances of that type. You can optionally specify an instance name, and ralsh will only describe that single instance. .sp You can also add +\-\-edit+ as an argument, and ralsh will write its output to a file, open that file in an editor, and then apply the file as a Puppet transaction. You can easily use this to use Puppet to make simple changes to a system. .SH OPTIONS .sp Note that any configuration parameter that\(aqs valid in the configuration file is also a valid long argument. For example, \(aqssldir\(aq is a valid configuration parameter, so you can specify \(aq\-\-ssldir \(aq as an argument. .sp See the configuration file documentation at -\fI\%http://reductivelabs.com/trac/puppet/wiki/ConfigurationReference\fP for the +\fI\%http://puppetlabs.com/trac/puppet/wiki/ConfigurationReference\fP for the full list of acceptable parameters. A commented list of all configuration options can also be generated by running puppet with \(aq\-\-genconfig\(aq. .sp debug: Enable full debugging. .sp edit: .INDENT 0.0 .INDENT 3.5 .sp Write the results of the query to a file, open the file in an editor, and read the file back in as an executable Puppet manifest. .UNINDENT .UNINDENT .sp host: .INDENT 0.0 .INDENT 3.5 .sp When specified, connect to the resource server on the named host and retrieve the list of resouces of the type specified. .UNINDENT .UNINDENT .sp help: .INDENT 0.0 .INDENT 3.5 .sp Print this help message. .UNINDENT .UNINDENT .sp param: .INDENT 0.0 .INDENT 3.5 .sp Add more parameters to be outputted from queries. .UNINDENT .UNINDENT .sp types: .INDENT 0.0 .INDENT 3.5 .sp List all available types. .UNINDENT .UNINDENT .sp verbose: Print extra information. .SH EXAMPLE .sp This example uses \fBralsh\fP to return Puppet configuration for the user \fBluke\fP: .sp .nf .ft C $ ralsh user luke user { \(aqluke\(aq: home => \(aq/home/luke\(aq, uid => \(aq100\(aq, ensure => \(aqpresent\(aq, comment => \(aqLuke Kanies,,,\(aq, gid => \(aq1000\(aq, shell => \(aq/bin/bash\(aq, groups => [\(aqsysadmin\(aq,\(aqaudio\(aq,\(aqvideo\(aq,\(aqpuppet\(aq] } .ft P .fi .SH AUTHOR .sp Luke Kanies .SH COPYRIGHT .sp -Copyright (c) 2005\-2007 Reductive Labs, LLC Licensed under the GNU +Copyright (c) 2005\-2007 Puppet Labs, LLC Licensed under the GNU Public License .\" Generated by docutils manpage writer. .\" . diff --git a/sbin/puppetca b/sbin/puppetca index 27ba916b5..87e83fc67 100755 --- a/sbin/puppetca +++ b/sbin/puppetca @@ -1,102 +1,102 @@ #!/usr/bin/env ruby # # = Synopsis # # Stand-alone certificate authority. Capable of generating certificates # but mostly meant for signing certificate requests from puppet clients. # # = Usage # # puppetca [-h|--help] [-V|--version] [-d|--debug] [-v|--verbose] # [-g|--generate] [-l|--list] [-s|--sign] [-r|--revoke] # [-p|--print] [-c|--clean] [--verify] [host] # # = Description # # Because the puppetmasterd daemon defaults to not signing client certificate # requests, this script is available for signing outstanding requests. It # can be used to list outstanding requests and then either sign them individually # or sign all of them. # # = 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 +# http://puppetlabs.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 puppetca with # '--genconfig'. # # all:: # Operate on all items. Currently only makes sense with '--sign', # '--clean', or '--list'. # # clean:: # Remove all files related to a host from puppetca's storage. This is # useful when rebuilding hosts, since new certificate signing requests # will only be honored if puppetca does not have a copy of a signed # certificate for that host. The certificate of the host remains valid. # If '--all' is specified then all host certificates, both signed and # unsigned, will be removed. # # debug:: # Enable full debugging. # # generate:: # Generate a certificate for a named client. A certificate/keypair will be # generated for each client named on the command line. # # help:: # Print this help message # # list:: # List outstanding certificate requests. If '--all' is specified, # signed certificates are also listed, prefixed by '+', and revoked # or invalid certificates are prefixed by '-' (the verification outcome # is printed in parenthesis). # # print:: # Print the full-text version of a host's certificate. # # revoke:: # Revoke the certificate of a client. The certificate can be specified # either by its serial number, given as a decimal number or a hexadecimal # number prefixed by '0x', or by its hostname. The certificate is revoked # by adding it to the Certificate Revocation List given by the 'cacrl' # config parameter. Note that the puppetmasterd needs to be restarted # after revoking certificates. # # sign:: # Sign an outstanding certificate request. Unless '--all' is specified, # hosts must be listed after all flags. # # verbose:: # Enable verbosity. # # version:: # Print the puppet version number and exit. # # verify:: # Verify the named certificate against the local CA certificate. # # = Example # # $ puppetca -l # culain.madstop.com # $ puppetca -s culain.madstop.com # # = Author # # Luke Kanies # # = Copyright # -# Copyright (c) 2005 Reductive Labs, LLC +# Copyright (c) 2005 Puppet Labs, LLC # Licensed under the GNU Public License require 'puppet/application/puppetca' Puppet::Application[:puppetca].run diff --git a/sbin/puppetd b/sbin/puppetd index 873d32813..6be19c7af 100755 --- a/sbin/puppetd +++ b/sbin/puppetd @@ -1,160 +1,160 @@ #!/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|--no-daemonize] [-d|--debug] [--disable] [--enable] # [-h|--help] [--fqdn ] [-l|--logdest syslog||console] # [-o|--onetime] [--serve ] [-t|--test] [--noop] # [-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 verbose 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/trac/puppet/wiki/ConfigurationReference for +# http://puppetlabs.com/trac/puppet/wiki/ConfigurationReference 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. # # no-daemonize:: # Do not send the process into the background. # # 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. Runs a single daemonized Puppet run. Useful for # interactively running puppetd and hence used in conjunction with the --no-daemonize # option. # # 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, +no-daemonize+, and +no-usecacheonfailure+. # # noop:: # Use +noop+ mode where the daemon runs in a no-op or dry-run mode. This is useful # for seeing what changes Puppet will make without actually executing the changes. # # 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 +# Copyright (c) 2005, 2006 Puppet Labs, LLC # Licensed under the GNU Public License require 'puppet/application/puppetd' Puppet::Application[:puppetd].run diff --git a/sbin/puppetmasterd b/sbin/puppetmasterd index 9f12f678c..bc7d42471 100755 --- a/sbin/puppetmasterd +++ b/sbin/puppetmasterd @@ -1,66 +1,66 @@ #!/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] [-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/trac/puppet/wiki/ConfigurationReference for +# http://puppetlabs.com/trac/puppet/wiki/ConfigurationReference 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. # # verbose:: # Enable verbosity. # # version:: # Print the puppet version number and exit. # # = Example # # puppetmasterd # # = Author # # Luke Kanies # # = Copyright # -# Copyright (c) 2005 Reductive Labs, LLC +# Copyright (c) 2005 Puppet Labs, LLC # Licensed under the GNU Public License require 'puppet/application/puppetmasterd' Puppet::Application[:puppetmasterd].run diff --git a/sbin/puppetqd b/sbin/puppetqd index 5487a324f..234572f9f 100755 --- a/sbin/puppetqd +++ b/sbin/puppetqd @@ -1,53 +1,53 @@ #!/usr/bin/env ruby # == Synopsis # # Retrieve serialized records from a queue and process them in order. # # = Usage # # puppetqd [-d|--debug] [-v|--verbose] # # = Description # # This is a simple application that just processes entities in a queue as they # are recieved. # # = 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/trac/puppet/wiki/ConfigurationReference for +# http://puppetlabs.com/trac/puppet/wiki/ConfigurationReference for # the full list of acceptable parameters. A commented list of all # configuration options can also be generated by running puppetd with # '--genconfig'. # # debug:: # Enable full debugging. # # help:: # Print this help message # # verbose:: # Turn on verbose reporting. # # version:: # Print the puppet version number and exit. # # = Example # # puppetqd # # = Author # # Luke Kanies # # = Copyright # -# Copyright (c) 2009 Reductive Labs, LLC +# Copyright (c) 2009 Puppet Labs, LLC # Licensed under the GNU Public License require 'puppet/application/puppetqd' Puppet::Application[:puppetqd].run diff --git a/sbin/puppetrun b/sbin/puppetrun index d3b2630af..e629f1ca8 100755 --- a/sbin/puppetrun +++ b/sbin/puppetrun @@ -1,130 +1,130 @@ #!/usr/bin/env ruby # # = Synopsis # # Trigger a puppetd run on a set of hosts. # # = Usage # # puppetrun [-a|--all] [-c|--class ] [-d|--debug] [-f|--foreground] # [-h|--help] [--host ] [--no-fqdn] [--ignoreschedules] # [-t|--tag ] [--test] [-p|--ping] # # = Description # # This script can be used to connect to a set of machines running +puppetd+ # and trigger them to run their configurations. The most common usage would # be to specify a class of hosts and a set of tags, and +puppetrun+ would # look up in LDAP all of the hosts matching that class, then connect to # each host and trigger a run of all of the objects with the specified tags. # # If you are not storing your host configurations in LDAP, you can specify # hosts manually. # # You will most likely have to run +puppetrun+ as root to get access to # the SSL certificates. # # +puppetrun+ reads +puppetmaster+'s configuration file, so that it can copy # things like LDAP settings. # # = Usage Notes # # +puppetrun+ is useless unless +puppetd+ is listening. See its documentation # for more information, but the gist is that you must enable +listen+ on the # +puppetd+ daemon, either using +--listen+ on the command line or adding # 'listen: true' in its config file. In addition, you need to set the daemons # up to specifically allow connections by creating the +namespaceauth+ file, # normally at '/etc/puppet/namespaceauth.conf'. This file specifies who has # access to each namespace; if you create the file you must add every namespace # you want any Puppet daemon to allow -- it is currently global to all Puppet # daemons. # # An example file looks like this:: # # [fileserver] # allow *.madstop.com # # [puppetmaster] # allow *.madstop.com # # [puppetrunner] # allow culain.madstop.com # # This is what you would install on your Puppet master; non-master hosts could # leave off the 'fileserver' and 'puppetmaster' namespaces. # # Expect more documentation on this eventually. # # = 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 +# http://puppetlabs.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'. # # # all:: # Connect to all available hosts. Requires LDAP support at this point. # # class:: # Specify a class of machines to which to connect. This only works if you # have LDAP configured, at the moment. # # debug:: # Enable full debugging. # # foreground:: # Run each configuration in the foreground; that is, when connecting to a host, # do not return until the host has finished its run. The default is false. # # help:: # Print this help message # # host:: # A specific host to which to connect. This flag can be specified more # than once. # # ignoreschedules:: # Whether the client should ignore schedules when running its configuration. # This can be used to force the client to perform work it would not normally # perform so soon. The default is false. # # parallel:: # How parallel to make the connections. Parallelization is provided by forking # for each client to which to connect. The default is 1, meaning serial execution. # # tag:: # Specify a tag for selecting the objects to apply. Does not work with the # --test option. # # # test:: # Print the hosts you would connect to but do not actually connect. This # option requires LDAP support at this point. # # ping:: # # Do a ICMP echo against the target host. Skip hosts that don't respond to ping. # # = Example # # sudo puppetrun -p 10 --host host1 --host host2 -t remotefile -t webserver # # = Author # # Luke Kanies # # = Copyright # -# Copyright (c) 2005 Reductive Labs, LLC +# Copyright (c) 2005 Puppet Labs, LLC # Licensed under the GNU Public License require 'puppet/application/puppetrun' Puppet::Application[:puppetrun].run diff --git a/spec/unit/application/filebucket.rb b/spec/unit/application/filebucket.rb index e87bab402..c0a6dcc7f 100644 --- a/spec/unit/application/filebucket.rb +++ b/spec/unit/application/filebucket.rb @@ -1,220 +1,220 @@ #!/usr/bin/env ruby require File.dirname(__FILE__) + '/../../spec_helper' require 'puppet/application/filebucket' describe "Filebucket" do before :each do @filebucket = Puppet::Application[:filebucket] end it "should ask Puppet::Application to not parse Puppet configuration file" do @filebucket.should_parse_config?.should be_false end it "should declare a get command" do @filebucket.should respond_to(:get) end it "should declare a backup command" do @filebucket.should respond_to(:backup) end it "should declare a restore command" do @filebucket.should respond_to(:restore) end [:bucket, :debug, :local, :remote, :verbose].each do |option| it "should declare handle_#{option} method" do @filebucket.should respond_to("handle_#{option}".to_sym) end it "should store argument value when calling handle_#{option}" do @filebucket.options.expects(:[]=).with("#{option}".to_sym, 'arg') @filebucket.send("handle_#{option}".to_sym, 'arg') end end describe "during setup" do before :each do Puppet::Log.stubs(:newdestination) Puppet.stubs(:settraps) Puppet::Log.stubs(:level=) Puppet.stubs(:parse_config) Puppet::Network::Client.dipper.stubs(:new) @filebucket.options.stubs(:[]).with(any_parameters) end it "should set console as the log destination" do Puppet::Log.expects(:newdestination).with(:console) @filebucket.run_setup end it "should trap INT" do @filebucket.expects(:trap).with(:INT) @filebucket.run_setup end it "should set log level to debug if --debug was passed" do @filebucket.options.stubs(:[]).with(:debug).returns(true) Puppet::Log.expects(:level=).with(:debug) @filebucket.run_setup end it "should set log level to info if --verbose was passed" do @filebucket.options.stubs(:[]).with(:verbose).returns(true) Puppet::Log.expects(:level=).with(:info) @filebucket.run_setup end it "should Parse puppet config" do Puppet.expects(:parse_config) @filebucket.run_setup end it "should print puppet config if asked to in Puppet config" do @filebucket.stubs(:exit) Puppet.settings.stubs(:print_configs?).returns(true) Puppet.settings.expects(:print_configs) @filebucket.run_setup end it "should exit after printing puppet config if asked to in Puppet config" do Puppet.settings.stubs(:print_configs?).returns(true) lambda { @filebucket.run_setup }.should raise_error(SystemExit) end describe "with local bucket" do before :each do @filebucket.options.stubs(:[]).with(:local).returns(true) end it "should create a client with the default bucket if none passed" do Puppet.stubs(:[]).with(:bucketdir).returns("path") Puppet::Network::Client::Dipper.expects(:new).with { |h| h[:Path] == "path" } @filebucket.run_setup end it "should create a local Client dipper with the given bucket" do @filebucket.options.stubs(:[]).with(:bucket).returns("path") Puppet::Network::Client::Dipper.expects(:new).with { |h| h[:Path] == "path" } @filebucket.run_setup end end describe "with remote bucket" do it "should create a remote Client to the configured server" do - Puppet.stubs(:[]).with(:server).returns("puppet.reductivelabs.com") + Puppet.stubs(:[]).with(:server).returns("puppet.puppetlabs.com") - Puppet::Network::Client::Dipper.expects(:new).with { |h| h[:Server] == "puppet.reductivelabs.com" } + Puppet::Network::Client::Dipper.expects(:new).with { |h| h[:Server] == "puppet.puppetlabs.com" } @filebucket.run_setup end end end describe "when running" do before :each do Puppet::Log.stubs(:newdestination) Puppet.stubs(:settraps) Puppet::Log.stubs(:level=) Puppet.stubs(:parse_config) Puppet::Network::Client.dipper.stubs(:new) @filebucket.options.stubs(:[]).with(any_parameters) @client = stub 'client' Puppet::Network::Client::Dipper.stubs(:new).returns(@client) @filebucket.run_setup end it "should use the first non-option parameter as the dispatch" do ARGV.stubs(:shift).returns(:get) @filebucket.get_command.should == :get end describe "the command get" do before :each do @filebucket.stubs(:print) end it "should call the client getfile method" do @client.expects(:getfile) @filebucket.get end it "should call the client getfile method with the given md5" do md5="DEADBEEF" ARGV.stubs(:shift).returns(md5) @client.expects(:getfile).with(md5) @filebucket.get end it "should print the file content" do @client.stubs(:getfile).returns("content") @filebucket.expects(:print).returns("content") @filebucket.get end end describe "the command backup" do it "should call the client backup method for each given parameter" do @filebucket.stubs(:puts) FileTest.stubs(:exists?).returns(true) FileTest.stubs(:readable?).returns(true) ARGV.stubs(:each).multiple_yields("file1","file2") @client.expects(:backup).with("file1") @client.expects(:backup).with("file2") @filebucket.backup end end describe "the command restore" do it "should call the client getfile method with the given md5" do md5="DEADBEEF" file="testfile" ARGV.stubs(:shift).returns(file,md5) @client.expects(:restore).with(file,md5) @filebucket.restore end end end end diff --git a/spec/unit/application/puppetd.rb b/spec/unit/application/puppetd.rb index 0f7257e59..88772b2f1 100755 --- a/spec/unit/application/puppetd.rb +++ b/spec/unit/application/puppetd.rb @@ -1,502 +1,502 @@ #!/usr/bin/env ruby require File.dirname(__FILE__) + '/../../spec_helper' require 'puppet/application/puppetd' require 'puppet/network/server' describe "puppetd" do before :each do @puppetd = Puppet::Application[:puppetd] @puppetd.stubs(:puts) @daemon = stub_everything 'daemon' Puppet::Daemon.stubs(:new).returns(@daemon) @agent = stub_everything 'agent' Puppet::Agent.stubs(:new).returns(@agent) @puppetd.run_preinit Puppet::Util::Log.stubs(:newdestination) Puppet::Util::Log.stubs(:level=) Puppet::Node.stubs(:terminus_class=) Puppet::Node.stubs(:cache_class=) Puppet::Node::Facts.stubs(:terminus_class=) end it "should ask Puppet::Application to parse Puppet configuration file" do @puppetd.should_parse_config?.should be_true end it "should declare a main command" do @puppetd.should respond_to(:main) end it "should declare a onetime command" do @puppetd.should respond_to(:onetime) end it "should declare a preinit block" do @puppetd.should respond_to(:run_preinit) end describe "in preinit" do before :each do @puppetd.stubs(:trap) end it "should catch INT" do @puppetd.expects(:trap).with { |arg,block| arg == :INT } @puppetd.run_preinit end it "should set waitforcert to 120" do @puppetd.run_preinit @puppetd.options[:waitforcert].should == 120 end it "should init client to true" do @puppetd.run_preinit @puppetd.options[:client].should be_true end it "should init fqdn to nil" do @puppetd.run_preinit @puppetd.options[:fqdn].should be_nil end it "should init serve to []" do @puppetd.run_preinit @puppetd.options[:serve].should == [] end end describe "when handling options" do before do @old_argv = ARGV.dup ARGV.clear end after do ARGV.clear @old_argv.each { |a| ARGV << a } end [:centrallogging, :disable, :enable, :debug, :fqdn, :test, :verbose].each do |option| it "should declare handle_#{option} method" do @puppetd.should respond_to("handle_#{option}".to_sym) end it "should store argument value when calling handle_#{option}" do @puppetd.options.expects(:[]=).with(option, 'arg') @puppetd.send("handle_#{option}".to_sym, 'arg') end end it "should set an existing handler on server" do Puppet::Network::Handler.stubs(:handler).with("handler").returns(true) @puppetd.handle_serve("handler") @puppetd.options[:serve].should == [ :handler ] end it "should set client to false with --no-client" do @puppetd.handle_no_client(nil) @puppetd.options[:client].should be_false end it "should set onetime to ture with --onetime" do @puppetd.handle_onetime(nil) @puppetd.options[:onetime].should be_true end it "should set waitforcert to 0 with --onetime and if --waitforcert wasn't given" do @puppetd.explicit_waitforcert = false @puppetd.handle_onetime(nil) @puppetd.options[:waitforcert].should == 0 end it "should not reset waitforcert with --onetime when --waitforcert is used" do @puppetd.explicit_waitforcert = true @puppetd.handle_onetime(nil) @puppetd.options[:waitforcert].should_not == 0 end it "should set the log destination with --logdest" do @puppetd.options.stubs(:[]=).with { |opt,val| opt == :setdest } Puppet::Log.expects(:newdestination).with("console") @puppetd.handle_logdest("console") end it "should put the setdest options to true" do @puppetd.options.expects(:[]=).with(:setdest,true) @puppetd.handle_logdest("console") end it "should parse the log destination from ARGV" do ARGV << "--logdest" << "/my/file" Puppet::Util::Log.expects(:newdestination).with("/my/file") @puppetd.parse_options end it "should store the waitforcert options with --waitforcert" do @puppetd.options.expects(:[]=).with(:waitforcert,42) @puppetd.handle_waitforcert("42") end it "should mark explicit_waitforcert to true with --waitforcert" do @puppetd.options.stubs(:[]=) @puppetd.handle_waitforcert("42") @puppetd.explicit_waitforcert.should be_true end it "should set args[:Port] with --port" do @puppetd.handle_port("42") @puppetd.args[:Port].should == "42" end end describe "during setup" do before :each do @puppetd.options.stubs(:[]) Puppet.stubs(:info) FileTest.stubs(:exists?).returns(true) Puppet.stubs(:[]) Puppet.stubs(:[]).with(:libdir).returns("/dev/null/lib") Puppet.settings.stubs(:print_config?) Puppet.settings.stubs(:print_config) Puppet::SSL::Host.stubs(:ca_location=) Puppet::Transaction::Report.stubs(:terminus_class=) Puppet::Resource::Catalog.stubs(:terminus_class=) Puppet::Resource::Catalog.stubs(:cache_class=) Puppet::Node::Facts.stubs(:terminus_class=) @host = stub_everything 'host' Puppet::SSL::Host.stubs(:new).returns(@host) Puppet.stubs(:settraps) end describe "with --test" do before :each do Puppet.settings.stubs(:handlearg) @puppetd.options.stubs(:[]=) end it "should call setup_test" do @puppetd.options.stubs(:[]).with(:test).returns(true) @puppetd.expects(:setup_test) @puppetd.run_setup end it "should set options[:verbose] to true" do @puppetd.options.expects(:[]=).with(:verbose,true) @puppetd.setup_test end it "should set options[:onetime] to true" do @puppetd.options.expects(:[]=).with(:onetime,true) @puppetd.setup_test end it "should set waitforcert to 0" do @puppetd.options.expects(:[]=).with(:waitforcert,0) @puppetd.setup_test end end it "should call setup_logs" do @puppetd.expects(:setup_logs) @puppetd.run_setup end describe "when setting up logs" do before :each do Puppet::Util::Log.stubs(:newdestination) end it "should set log level to debug if --debug was passed" do @puppetd.options.stubs(:[]).with(:debug).returns(true) Puppet::Util::Log.expects(:level=).with(:debug) @puppetd.setup_logs end it "should set log level to info if --verbose was passed" do @puppetd.options.stubs(:[]).with(:verbose).returns(true) Puppet::Util::Log.expects(:level=).with(:info) @puppetd.setup_logs end [:verbose, :debug].each do |level| it "should set console as the log destination with level #{level}" do @puppetd.options.stubs(:[]).with(level).returns(true) Puppet::Util::Log.expects(:newdestination).with(:console) @puppetd.setup_logs end end it "should set syslog as the log destination if no --logdest" do @puppetd.options.stubs(:[]).with(:setdest).returns(false) Puppet::Util::Log.expects(:newdestination).with(:syslog) @puppetd.setup_logs end end it "should print puppet config if asked to in Puppet config" do @puppetd.stubs(:exit) Puppet.settings.stubs(:print_configs?).returns(true) Puppet.settings.expects(:print_configs) @puppetd.run_setup end it "should exit after printing puppet config if asked to in Puppet config" do Puppet.settings.stubs(:print_configs?).returns(true) lambda { @puppetd.run_setup }.should raise_error(SystemExit) end it "should set a central log destination with --centrallogs" do @puppetd.options.stubs(:[]).with(:centrallogs).returns(true) - Puppet.stubs(:[]).with(:server).returns("puppet.reductivelabs.com") + Puppet.stubs(:[]).with(:server).returns("puppet.puppetlabs.com") Puppet::Util::Log.stubs(:newdestination).with(:syslog) - Puppet::Util::Log.expects(:newdestination).with("puppet.reductivelabs.com") + Puppet::Util::Log.expects(:newdestination).with("puppet.puppetlabs.com") @puppetd.run_setup end it "should use :main, :puppetd, and :ssl" do Puppet.settings.expects(:use).with(:main, :puppetd, :ssl) @puppetd.run_setup end it "should install a remote ca location" do Puppet::SSL::Host.expects(:ca_location=).with(:remote) @puppetd.run_setup end it "should tell the report handler to use REST" do Puppet::Transaction::Report.expects(:terminus_class=).with(:rest) @puppetd.run_setup end it "should change the catalog_terminus setting to 'rest'" do Puppet.expects(:[]=).with(:catalog_terminus, :rest) @puppetd.run_setup end it "should tell the catalog handler to use cache" do Puppet::Resource::Catalog.expects(:cache_class=).with(:yaml) @puppetd.run_setup end it "should tell the facts to use facter" do Puppet::Node::Facts.expects(:terminus_class=).with(:facter) @puppetd.run_setup end it "should create an agent" do Puppet::Agent.stubs(:new).with(Puppet::Configurer) @puppetd.run_setup end [:enable, :disable].each do |action| it "should delegate to enable_disable_client if we #{action} the agent" do @puppetd.options.stubs(:[]).with(action).returns(true) @puppetd.expects(:enable_disable_client).with(@agent) @puppetd.run_setup end end describe "when enabling or disabling agent" do [:enable, :disable].each do |action| it "should call client.#{action}" do @puppetd.stubs(:exit) @puppetd.options.stubs(:[]).with(action).returns(true) @agent.expects(action) @puppetd.enable_disable_client(@agent) end end it "should finally exit" do lambda { @puppetd.enable_disable_client(@agent) }.should raise_error(SystemExit) end end it "should inform the daemon about our agent if :client is set to 'true'" do @puppetd.options.expects(:[]).with(:client).returns true @daemon.expects(:agent=).with(@agent) @puppetd.run_setup end it "should not inform the daemon about our agent if :client is set to 'false'" do @puppetd.options[:client] = false @daemon.expects(:agent=).never @puppetd.run_setup end it "should daemonize if needed" do Puppet.stubs(:[]).with(:daemonize).returns(true) @daemon.expects(:daemonize) @puppetd.run_setup end it "should wait for a certificate" do @puppetd.options.stubs(:[]).with(:waitforcert).returns(123) @host.expects(:wait_for_cert).with(123) @puppetd.run_setup end it "should setup listen if told to and not onetime" do Puppet.stubs(:[]).with(:listen).returns(true) @puppetd.options.stubs(:[]).with(:onetime).returns(false) @puppetd.expects(:setup_listen) @puppetd.run_setup end describe "when setting up listen" do before :each do Puppet.stubs(:[]).with(:authconfig).returns('auth') FileTest.stubs(:exists?).with('auth').returns(true) File.stubs(:exist?).returns(true) @puppetd.options.stubs(:[]).with(:serve).returns([]) @puppetd.stubs(:exit) @server = stub_everything 'server' Puppet::Network::Server.stubs(:new).returns(@server) end it "should exit if no authorization file" do Puppet.stubs(:err) FileTest.stubs(:exists?).with('auth').returns(false) @puppetd.expects(:exit) @puppetd.setup_listen end it "should create a server to listen on at least the Runner handler" do Puppet::Network::Server.expects(:new).with { |args| args[:xmlrpc_handlers] == [:Runner] } @puppetd.setup_listen end it "should create a server to listen for specific handlers" do @puppetd.options.stubs(:[]).with(:serve).returns([:handler]) Puppet::Network::Server.expects(:new).with { |args| args[:xmlrpc_handlers] == [:handler] } @puppetd.setup_listen end it "should use puppet default port" do Puppet.stubs(:[]).with(:puppetport).returns(:port) Puppet::Network::Server.expects(:new).with { |args| args[:port] == :port } @puppetd.setup_listen end end end describe "when running" do before :each do @puppetd.agent = @agent @puppetd.daemon = @daemon end it "should dispatch to onetime if --onetime is used" do @puppetd.options.stubs(:[]).with(:onetime).returns(true) @puppetd.get_command.should == :onetime end it "should dispatch to main if --onetime is not used" do @puppetd.options.stubs(:[]).with(:onetime).returns(false) @puppetd.get_command.should == :main end describe "with --onetime" do before :each do @puppetd.options.stubs(:[]).with(:client).returns(:client) @puppetd.stubs(:exit).with(0) Puppet.stubs(:newservice) end it "should exit if no defined --client" do $stderr.stubs(:puts) @puppetd.options.stubs(:[]).with(:client).returns(nil) @puppetd.expects(:exit).with(43) @puppetd.onetime end it "should setup traps" do @daemon.expects(:set_signal_traps) @puppetd.onetime end it "should let the agent run" do @agent.expects(:run) @puppetd.onetime end it "should finish by exiting with 0 error code" do @puppetd.expects(:exit).with(0) @puppetd.onetime end end describe "without --onetime" do before :each do Puppet.stubs(:notice) @puppetd.options.stubs(:[]).with(:client) end it "should start our daemon" do @daemon.expects(:start) @puppetd.main end end end end diff --git a/spec/unit/parser/ast/leaf.rb b/spec/unit/parser/ast/leaf.rb index 62ebc2ab1..5e7516b1d 100755 --- a/spec/unit/parser/ast/leaf.rb +++ b/spec/unit/parser/ast/leaf.rb @@ -1,298 +1,298 @@ #!/usr/bin/env ruby require File.dirname(__FILE__) + '/../../../spec_helper' describe Puppet::Parser::AST::Leaf do before :each do @scope = stub 'scope' @value = stub 'value' @leaf = Puppet::Parser::AST::Leaf.new(:value => @value) end it "should have a evaluate_match method" do Puppet::Parser::AST::Leaf.new(:value => "value").should respond_to(:evaluate_match) end describe "when evaluate_match is called" do it "should evaluate itself" do @leaf.expects(:safeevaluate).with(@scope) @leaf.evaluate_match("value", @scope) end it "should match values by equality" do @leaf.stubs(:safeevaluate).with(@scope).returns(@value) @value.expects(:==).with("value") @leaf.evaluate_match("value", @scope) end it "should downcase the evaluated value if wanted" do @leaf.stubs(:safeevaluate).with(@scope).returns(@value) @value.expects(:downcase).returns("value") @leaf.evaluate_match("value", @scope, :insensitive => true) end it "should downcase the parameter value if wanted" do parameter = stub 'parameter' parameter.expects(:downcase).returns("value") @leaf.evaluate_match(parameter, @scope, :insensitive => true) end end describe "when converting to string" do it "should transform its value to string" do value = stub 'value', :is_a? => true value.expects(:to_s) Puppet::Parser::AST::Leaf.new( :value => value ).to_s end end it "should have a match method" do @leaf.should respond_to(:match) end it "should delegate match to ==" do @value.expects(:==).with("value") @leaf.match("value") end end describe Puppet::Parser::AST::FlatString do describe "when converting to string" do it "should transform its value to a quoted string" do value = stub 'value', :is_a? => true, :to_s => "ab" Puppet::Parser::AST::FlatString.new( :value => value ).to_s.should == "\"ab\"" end end end describe Puppet::Parser::AST::String do describe "when converting to string" do it "should transform its value to a quoted string" do value = stub 'value', :is_a? => true, :to_s => "ab" Puppet::Parser::AST::String.new( :value => value ).to_s.should == "\"ab\"" end end end describe Puppet::Parser::AST::Variable do describe "when converting to string" do it "should transform its value to a variable" do value = stub 'value', :is_a? => true, :to_s => "myvar" Puppet::Parser::AST::Variable.new( :value => value ).to_s.should == "\$myvar" end end end describe Puppet::Parser::AST::Regex do before :each do @scope = stub 'scope' end describe "when initializing" do it "should create a Regexp with its content when value is not a Regexp" do Regexp.expects(:new).with("/ab/") Puppet::Parser::AST::Regex.new :value => "/ab/" end it "should not create a Regexp with its content when value is a Regexp" do value = Regexp.new("/ab/") Regexp.expects(:new).with("/ab/").never Puppet::Parser::AST::Regex.new :value => value end end describe "when evaluating" do it "should return self" do val = Puppet::Parser::AST::Regex.new :value => "/ab/" val.evaluate(@scope).should === val end end describe "when evaluate_match" do before :each do @value = stub 'regex' @value.stubs(:match).with("value").returns(true) Regexp.stubs(:new).returns(@value) @regex = Puppet::Parser::AST::Regex.new :value => "/ab/" end it "should issue the regexp match" do @value.expects(:match).with("value") @regex.evaluate_match("value", @scope) end it "should not downcase the paramater value" do @value.expects(:match).with("VaLuE") @regex.evaluate_match("VaLuE", @scope) end it "should set ephemeral scope vars if there is a match" do @scope.expects(:ephemeral_from).with(true, nil, nil) @regex.evaluate_match("value", @scope) end it "should return the match to the caller" do @value.stubs(:match).with("value").returns(:match) @scope.stubs(:ephemeral_from) @regex.evaluate_match("value", @scope) end end it "should return the regex source with to_s" do regex = stub 'regex' Regexp.stubs(:new).returns(regex) val = Puppet::Parser::AST::Regex.new :value => "/ab/" regex.expects(:source) val.to_s end it "should delegate match to the underlying regexp match method" do regex = Regexp.new("/ab/") val = Puppet::Parser::AST::Regex.new :value => regex regex.expects(:match).with("value") val.match("value") end end describe Puppet::Parser::AST::HostName do before :each do @scope = stub 'scope' @value = stub 'value', :=~ => false @value.stubs(:to_s).returns(@value) @value.stubs(:downcase).returns(@value) @host = Puppet::Parser::AST::HostName.new( :value => @value) end it "should raise an error if hostname is not valid" do lambda { Puppet::Parser::AST::HostName.new( :value => "not an hostname!" ) }.should raise_error end it "should not raise an error if hostname is a regex" do lambda { Puppet::Parser::AST::HostName.new( :value => Puppet::Parser::AST::Regex.new(:value => "/test/") ) }.should_not raise_error end it "should stringify the value" do value = stub 'value', :=~ => false value.expects(:to_s).returns("test") Puppet::Parser::AST::HostName.new(:value => value) end it "should downcase the value" do value = stub 'value', :=~ => false value.stubs(:to_s).returns("UPCASED") host = Puppet::Parser::AST::HostName.new(:value => value) host.value == "upcased" end it "should evaluate to its value" do @host.evaluate(@scope).should == @value end it "should implement to_classname" do @host.should respond_to(:to_classname) end it "should return the downcased nodename as classname" do host = Puppet::Parser::AST::HostName.new( :value => "KLASSNAME" ) host.to_classname.should == "klassname" end it "should preserve '_' in to_classname with a string nodename" do host = Puppet::Parser::AST::HostName.new( :value => "node_with_underscore") host.to_classname.should == "node_with_underscore" end it "should preserve '_' in to_classname with a regex nodename" do host = Puppet::Parser::AST::HostName.new( :value => Puppet::Parser::AST::Regex.new(:value => "/\dnode_with_underscore\.+/") ) host.to_classname.should == "dnode_with_underscore." end it "should return a string usable as classname when calling to_classname" do host = Puppet::Parser::AST::HostName.new( :value => Puppet::Parser::AST::Regex.new(:value => "/^this-is not@a classname$/") ) host.to_classname.should == "this-isnotaclassname" end it "should return a string usable as a tag when calling to_classname" do - host = Puppet::Parser::AST::HostName.new( :value => Puppet::Parser::AST::Regex.new(:value => "/.+.reductivelabs\.com/") ) - host.to_classname.should == "reductivelabs.com" + host = Puppet::Parser::AST::HostName.new( :value => Puppet::Parser::AST::Regex.new(:value => "/.+.puppetlabs\.com/") ) + host.to_classname.should == "puppetlabs.com" end it "should delegate 'match' to the underlying value if it is an HostName" do @value.expects(:match).with("value") @host.match("value") end it "should delegate eql? to the underlying value if it is an HostName" do @value.expects(:eql?).with("value") @host.eql?("value") end it "should delegate eql? to the underlying value if it is not an HostName" do value = stub 'compared', :is_a? => true, :value => "value" @value.expects(:eql?).with("value") @host.eql?(value) end it "should delegate hash to the underlying value" do @value.expects(:hash) @host.hash end it "should return true when regex? is called and value is a Regex" do @value.expects(:is_a?).with(Puppet::Parser::AST::Regex).returns(true) @host.regex?.should be_true end it "should return the results of comparing the regexes if asked whether a regex matches another regex" do hosts = [1,2].collect do |num| vreg = /vreg#{num}/ value = Puppet::Parser::AST::Regex.new(:value => vreg) Puppet::Parser::AST::HostName.new(:value => value) end hosts[0].match(hosts[1]).should be_false hosts[0].match(hosts[0]).should be_true end it "should return false when comparing a non-regex to a regex" do vreg = /vreg/ value = Puppet::Parser::AST::Regex.new(:value => vreg) regex = Puppet::Parser::AST::HostName.new(:value => value) value = Puppet::Parser::AST::Regex.new(:value => "foo") normal = Puppet::Parser::AST::HostName.new(:value => value) normal.match(regex).should be_false end it "should true when a provided string matches a regex" do vreg = /r/ value = Puppet::Parser::AST::Regex.new(:value => vreg) regex = Puppet::Parser::AST::HostName.new(:value => value) value = Puppet::Parser::AST::Leaf.new(:value => "bar") normal = Puppet::Parser::AST::HostName.new(:value => value) regex.match(normal).should be_true end end diff --git a/spec/unit/provider/ssh_authorized_key/parsed.rb b/spec/unit/provider/ssh_authorized_key/parsed.rb index 9abcda54f..d5c66d7b0 100755 --- a/spec/unit/provider/ssh_authorized_key/parsed.rb +++ b/spec/unit/provider/ssh_authorized_key/parsed.rb @@ -1,195 +1,195 @@ #!/usr/bin/env ruby require File.dirname(__FILE__) + '/../../../spec_helper' require 'puppettest' require 'puppettest/support/utils' require 'puppettest/fileparsing' provider_class = Puppet::Type.type(:ssh_authorized_key).provider(:parsed) describe provider_class do include PuppetTest include PuppetTest::FileParsing before :each do @sshauthkey_class = Puppet::Type.type(:ssh_authorized_key) @provider = @sshauthkey_class.provider(:parsed) end after :each do @provider.initvars end def mkkey(args) fakeresource = fakeresource(:ssh_authorized_key, args[:name]) key = @provider.new(fakeresource) args.each do |p,v| key.send(p.to_s + "=", v) end return key end def genkey(key) @provider.stubs(:filetype).returns(Puppet::Util::FileType::FileTypeRam) file = @provider.default_target key.flush text = @provider.target_object(file).read return text end PuppetTest.fakedata("data/providers/ssh_authorized_key/parsed").each { |file| it "should be able to parse example data in #{file}" do puts "Parsing %s" % file fakedataparse(file) end } it "should be able to generate a basic authorized_keys file" do key = mkkey({ :name => "Just Testing", :key => "AAAAfsfddsjldjgksdflgkjsfdlgkj", :type => "ssh-dss", :ensure => :present, :options => [:absent] }) genkey(key).should == "ssh-dss AAAAfsfddsjldjgksdflgkjsfdlgkj Just Testing\n" end it "should be able to generate a authorized_keys file with options" do key = mkkey({ :name => "root@localhost", :key => "AAAAfsfddsjldjgksdflgkjsfdlgkj", :type => "ssh-rsa", :ensure => :present, :options => ['from="192.168.1.1"', "no-pty", "no-X11-forwarding"] }) genkey(key).should == "from=\"192.168.1.1\",no-pty,no-X11-forwarding ssh-rsa AAAAfsfddsjldjgksdflgkjsfdlgkj root@localhost\n" end it "'s parse_options method should be able to parse options containing commas" do - options = %w{from="host1.reductlivelabs.com,host.reductivelabs.com" command="/usr/local/bin/run" ssh-pty} + options = %w{from="host1.reductlivelabs.com,host.puppetlabs.com" command="/usr/local/bin/run" ssh-pty} optionstr = options.join(", ") @provider.parse_options(optionstr).should == options end it "should use '' as name for entries that lack a comment" do line = "ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAut8aOSxenjOqF527dlsdHWV4MNoAsX14l9M297+SQXaQ5Z3BedIxZaoQthkDALlV/25A1COELrg9J2MqJNQc8Xe9XQOIkBQWWinUlD/BXwoOTWEy8C8zSZPHZ3getMMNhGTBO+q/O+qiJx3y5cA4MTbw2zSxukfWC87qWwcZ64UUlegIM056vPsdZWFclS9hsROVEa57YUMrehQ1EGxT4Z5j6zIopufGFiAPjZigq/vqgcAqhAKP6yu4/gwO6S9tatBeEjZ8fafvj1pmvvIplZeMr96gHE7xS3pEEQqnB3nd4RY7AF6j9kFixnsytAUO7STPh/M3pLiVQBN89TvWPQ==" @provider.parse(line)[0][:name].should == "" end end describe provider_class do before :each do @resource = stub("resource", :name => "foo") @resource.stubs(:[]).returns "foo" @provider = provider_class.new(@resource) provider_class.stubs(:filetype).returns(Puppet::Util::FileType::FileTypeRam) end describe "when flushing" do before :each do # Stub file and directory operations Dir.stubs(:mkdir) File.stubs(:chmod) File.stubs(:chown) end describe "and both a user and a target have been specified" do before :each do Puppet::Util.stubs(:uid).with("random_bob").returns 12345 @resource.stubs(:should).with(:user).returns "random_bob" target = "/tmp/.ssh_dir/place_to_put_authorized_keys" @resource.stubs(:should).with(:target).returns target end it "should create the directory" do File.stubs(:exist?).with("/tmp/.ssh_dir").returns false Dir.expects(:mkdir).with("/tmp/.ssh_dir", 0700) @provider.flush end it "should chown the directory to the user" do uid = Puppet::Util.uid("random_bob") File.expects(:chown).with(uid, nil, "/tmp/.ssh_dir") @provider.flush end it "should chown the key file to the user" do uid = Puppet::Util.uid("random_bob") File.expects(:chown).with(uid, nil, "/tmp/.ssh_dir/place_to_put_authorized_keys") @provider.flush end it "should chmod the key file to 0600" do File.expects(:chmod).with(0600, "/tmp/.ssh_dir/place_to_put_authorized_keys") @provider.flush end end describe "and a user has been specified with no target" do before :each do @resource.stubs(:should).with(:user).returns "nobody" @resource.stubs(:should).with(:target).returns nil # # I'd like to use random_bob here and something like # # File.stubs(:expand_path).with("~random_bob/.ssh").returns "/users/r/random_bob/.ssh" # # but mocha objects strenuously to stubbing File.expand_path # so I'm left with using nobody. @dir = File.expand_path("~nobody/.ssh") end it "should create the directory" do File.stubs(:exist?).with(@dir).returns false Dir.expects(:mkdir).with(@dir,0700) @provider.flush end it "should chown the directory to the user" do uid = Puppet::Util.uid("nobody") File.expects(:chown).with(uid, nil, @dir) @provider.flush end it "should chown the key file to the user" do uid = Puppet::Util.uid("nobody") File.expects(:chown).with(uid, nil, File.expand_path("~nobody/.ssh/authorized_keys")) @provider.flush end it "should chmod the key file to 0600" do File.expects(:chmod).with(0600, File.expand_path("~nobody/.ssh/authorized_keys")) @provider.flush end end describe "and a target has been specified with no user" do before :each do @resource.stubs(:should).with(:user).returns nil @resource.stubs(:should).with(:target).returns("/tmp/.ssh_dir/place_to_put_authorized_keys") end it "should make the directory" do File.stubs(:exist?).with("/tmp/.ssh_dir").returns false Dir.expects(:mkdir).with("/tmp/.ssh_dir", 0755) @provider.flush end it "should chmod the key file to 0644" do File.expects(:chmod).with(0644, "/tmp/.ssh_dir/place_to_put_authorized_keys") @provider.flush end end end end diff --git a/tasks/rake/git_workflow.rake b/tasks/rake/git_workflow.rake index b2f96c603..5ef568c7b 100644 --- a/tasks/rake/git_workflow.rake +++ b/tasks/rake/git_workflow.rake @@ -1,121 +1,121 @@ # This set of tasks helps automate the workflow as described on -# http://reductivelabs.com/trac/puppet/wiki/Development/DevelopmentLifecycle +# http://puppetlabs.com/trac/puppet/wiki/Development/DevelopmentLifecycle def find_start(start) # This is a case statement, as we might want to map certain # git tags to starting points that are not currently in git. case start when nil?: when @next_release: return "master" else return start end end desc "Set up git for working with Puppet" task :git_setup do # This should be changed as new versions get released @next_release = '0.26.x' @remote = {} default_remote = {} default_remote[:url] = 'git://github.com/reductivelabs/puppet' default_remote[:name] = 'origin' @remote[:name] = %x{git config puppet.defaultremote}.chomp @remote[:name] = @remote[:name].empty? ? default_remote[:name] : @remote[:name] @remote[:url] = default_remote[:url] if @remote[:name] == default_remote[:name] default_fetch = '+refs/heads/*:refs/remotes/puppet/*' @remote[:fetch] = %x{git config puppet.#{@remote[:name]}.fetch}.chomp @remote[:fetch] = @remote[:fetch].empty? ? default_fetch : @remote[:fetch] end desc "Start work on a feature" task :start_feature, [:feature,:remote,:branch] => :git_setup do |t, args| args.with_defaults(:remote => @remote[:name]) args.with_defaults(:branch => @next_release) start_at = find_start(args.branch) branch = "feature/#{start_at}/#{args.feature}" sh "git checkout -b #{branch} #{start_at}" do |ok, res| if ! ok raise < :git_setup do |t, args| args.with_defaults(:remote => @remote[:name]) args.with_defaults(:branch => @next_release) start_at = find_start(args.branch) branch = "tickets/#{start_at}/#{args.ticket}" sh "git checkout -b #{branch} #{start_at}" do |ok, res| unless ok raise < 0 raise "Patches already exist matching '00*.patch'; clean up first" end unless %x{git status} =~ /On branch (.+)/ raise "Could not get branch from 'git status'" end branch = $1 unless branch =~ %r{^([^\/]+)/([^\/]+)/([^\/]+)$} raise "Branch name does not follow // model; cannot autodetect parent branch" end type, parent, name = $1, $2, $3 # Create all of the patches sh "git format-patch -C -M -s -n --subject-prefix='PATCH/puppet' #{parent}..HEAD" # And then mail them out. # If we've got more than one patch, add --compose if Dir.glob("00*.patch").length > 1 compose = "--compose" else compose = "" end # Now send the mail. sh "git send-email #{compose} --no-signed-off-by-cc --suppress-from --to puppet-dev@googlegroups.com 00*.patch" # Finally, clean up the patches sh "rm 00*.patch" end diff --git a/tasks/rake/sign.rake b/tasks/rake/sign.rake index 2eed60df0..d5d393575 100644 --- a/tasks/rake/sign.rake +++ b/tasks/rake/sign.rake @@ -1,14 +1,14 @@ -desc "Sign to the package with the Reductive Labs release key" +desc "Sign to the package with the Puppet Labs release key" task :sign_packages do version = Puppet::PUPPETVERSION # Sign package sh "gpg --homedir $HOME/release_key --detach-sign --output pkg/puppet-#{version}.tar.gz.sign --armor pkg/puppet-#{version}.tar.gz" # Sign gem sh "gpg --homedir $HOME/release_key --detach-sign --output pkg/puppet-#{version}.gem.sign --armor pkg/puppet-#{version}.gem" end diff --git a/test/certmgr/certmgr.rb b/test/certmgr/certmgr.rb index 2c4605f03..de63fc399 100755 --- a/test/certmgr/certmgr.rb +++ b/test/certmgr/certmgr.rb @@ -1,299 +1,299 @@ #!/usr/bin/env ruby require File.dirname(__FILE__) + '/../lib/puppettest' require 'puppet' require 'puppet/sslcertificates.rb' require 'puppettest' require 'puppettest/certificates' require 'mocha' class TestCertMgr < Test::Unit::TestCase include PuppetTest::Certificates def setup super #@dir = File.join(Puppet[:certdir], "testing") @dir = File.join(@configpath, "certest") system("mkdir -p %s" % @dir) Puppet::Util::SUIDManager.stubs(:asuser).yields end def testCreateSelfSignedCertificate cert = nil name = "testing" newcert = proc { Puppet::SSLCertificates::Certificate.new( :name => name, :selfsign => true ) } assert_nothing_raised { cert = newcert.call() } assert_nothing_raised { cert.mkselfsigned } assert_raise(Puppet::Error) { cert.mkselfsigned } assert_nothing_raised { cert.write } assert(FileTest.exists?(cert.certfile)) assert_nothing_raised { cert.delete } assert_nothing_raised { cert = newcert.call() } assert_nothing_raised { cert.mkselfsigned } assert_nothing_raised { cert.delete } end def disabled_testCreateEncryptedSelfSignedCertificate cert = nil name = "testing" keyfile = mkPassFile assert_nothing_raised { cert = Puppet::SSLCertificates::Certificate.new( :name => name, :selfsign => true, :capass => keyfile ) } assert_nothing_raised { cert.mkselfsigned } assert_nothing_raised { cert.mkhash } assert_raise(Puppet::Error) { cert.mkselfsigned } assert(FileTest.exists?(cert.certfile)) assert(FileTest.exists?(cert.hash)) assert_nothing_raised { cert.delete } assert_nothing_raised { cert.mkselfsigned } assert_nothing_raised { cert.delete } end def testCreateCA ca = nil assert_nothing_raised { ca = Puppet::SSLCertificates::CA.new() } # make the CA again and verify it doesn't fail because everything # still exists assert_nothing_raised { ca = Puppet::SSLCertificates::CA.new() } end def testSignCert ca = mkCA() cert = nil assert_nothing_raised { cert = Puppet::SSLCertificates::Certificate.new( :name => "signedcertest", :property => "TN", :city => "Nashville", :country => "US", :email => "luke@madstop.com", - :org => "Reductive", + :org => "Puppet", :ou => "Development", :encrypt => mkPassFile() ) } assert_nothing_raised { cert.mkcsr } signedcert = nil cacert = nil assert_nothing_raised { signedcert, cacert = ca.sign(cert.csr) } assert_instance_of(OpenSSL::X509::Certificate, signedcert) assert_instance_of(OpenSSL::X509::Certificate, cacert) assert_nothing_raised { cert.cert = signedcert cert.cacert = cacert cert.write } #system("find %s" % Puppet[:ssldir]) #system("cp -R %s /tmp/ssltesting" % Puppet[:ssldir]) output = nil assert_nothing_raised { output = %x{openssl verify -CAfile #{Puppet[:cacert]} -purpose sslserver #{cert.certfile}} #output = %x{openssl verify -CApath #{Puppet[:certdir]} -purpose sslserver #{cert.certfile}} } assert_equal($?,0) assert_equal(File.join(Puppet[:certdir], "signedcertest.pem: OK\n"), output) end def test_interactiveca ca = nil assert_nothing_raised { ca = Puppet::SSLCertificates::CA.new } # basic initialization hostname = "test.hostname.com" cert = mkcert(hostname) # create the csr csr = nil assert_nothing_raised { csr = cert.mkcsr } assert_nothing_raised { ca.storeclientcsr(csr) } # store it pulledcsr = nil assert_nothing_raised { pulledcsr = ca.getclientcsr(hostname) } assert_equal(csr.to_pem, pulledcsr.to_pem) signedcert = nil assert_nothing_raised { signedcert, cacert = ca.sign(csr) } assert_instance_of(OpenSSL::X509::Certificate, signedcert) newsignedcert = nil assert_nothing_raised { newsignedcert, cacert = ca.getclientcert(hostname) } assert(newsignedcert) assert_equal(signedcert.to_pem, newsignedcert.to_pem) end def test_cafailures ca = mkCA() cert = cacert = nil assert_nothing_raised { cert, cacert = ca.getclientcert("nohost") } assert_nil(cert) end def test_crl ca = mkCA() h1 = mksignedcert(ca, "host1.example.com") h2 = mksignedcert(ca, "host2.example.com") assert(ca.cert.verify(ca.cert.public_key)) assert(h1.verify(ca.cert.public_key)) assert(h2.verify(ca.cert.public_key)) crl = ca.crl assert_not_nil(crl) store = mkStore(ca) assert( store.verify(ca.cert)) assert( store.verify(h1, [ca.cert])) assert( store.verify(h2, [ca.cert])) ca.revoke(h1.serial) oldcert = File.read(Puppet.settings[:cacert]) oldserial = File.read(Puppet.settings[:serial]) # Recreate the CA from disk ca = mkCA() newcert = File.read(Puppet.settings[:cacert]) newserial = File.read(Puppet.settings[:serial]) assert_equal(oldcert, newcert, "The certs are not equal after making a new CA.") assert_equal(oldserial, newserial, "The serials are not equal after making a new CA.") store = mkStore(ca) assert( store.verify(ca.cert), "Could not verify CA certs after reloading certs.") assert(!store.verify(h1, [ca.cert]), "Incorrectly verified revoked cert.") assert( store.verify(h2, [ca.cert]), "Could not verify certs with reloaded CA.") ca.revoke(h2.serial) assert_equal(1, ca.crl.extensions.size) # Recreate the CA from disk ca = mkCA() store = mkStore(ca) assert( store.verify(ca.cert)) assert(!store.verify(h1, [ca.cert]), "first revoked cert passed") assert(!store.verify(h2, [ca.cert]), "second revoked cert passed") end def test_ttl cert = mksignedcert assert_equal(5 * 365 * 24 * 60 * 60, cert.not_after - cert.not_before) Puppet[:ca_ttl] = 7 * 24 * 60 * 60 cert = mksignedcert assert_equal(7 * 24 * 60 * 60, cert.not_after - cert.not_before) Puppet[:ca_ttl] = "2y" cert = mksignedcert assert_equal(2 * 365 * 24 * 60 * 60, cert.not_after - cert.not_before) Puppet[:ca_ttl] = "2y" cert = mksignedcert assert_equal(2 * 365 * 24 * 60 * 60, cert.not_after - cert.not_before) Puppet[:ca_ttl] = "1h" cert = mksignedcert assert_equal(60 * 60, cert.not_after - cert.not_before) Puppet[:ca_ttl] = "900s" cert = mksignedcert assert_equal(900, cert.not_after - cert.not_before) # This needs to be last, to make sure that setting ca_days # overrides setting ca_ttl Puppet[:ca_days] = 3 cert = mksignedcert assert_equal(3 * 24 * 60 * 60, cert.not_after - cert.not_before) end end diff --git a/test/data/providers/ssh_authorized_key/parsed/authorized_keys b/test/data/providers/ssh_authorized_key/parsed/authorized_keys index b22329dca..e99e07998 100644 --- a/test/data/providers/ssh_authorized_key/parsed/authorized_keys +++ b/test/data/providers/ssh_authorized_key/parsed/authorized_keys @@ -1,7 +1,7 @@ ssh-dss AAAAB3NzaC1kc3MAAACBAJkupmdsJSDXfUy5EU5NTRBDr9Woo3w0YnB8KmnJW9ghU8C7SkWPB1fIHVe+esFfd3qWBseb83PoFX63geZJAg6bjV4/Rdn1zEoa9EO2QyUdYUen4+rpsh3vVKZ6HFNsn3+W5+kPYgE1F/N4INqkbjY3sqCkP/W1BL9+sbVVbuJFAAAAFQCfjWDk5XhvGUkPjNWWVqltBYzHtwAAAIEAg/XL7ky7x9Ad5banzPFAfmM+DGFe0A/JEbLDjKmr5KBM5x4RFohtEvZ8ECuVGUOqBWdgAjyYwsG4oRVjLnKrf/rgmbNRzSFgEWkcAye3BVwk7Dt6hh4knEl+mNfOLq+FH0011UhecOiqTcESMzQDtgQ1vJh2VchElBLjl3x/ZugAAACAAh5jGQC338t5ObP8trSlOefkx0sXmmEzUbo3Mt8mGUuGJPx8m+X0L8Xd+l5rQxytqE3SmV/RD+6REqBuPqHM8RQuqAzfjdOeg/Ajdggx1CRMTVhltZsgQoxO30cz9Qo0SdPoL+Jp1fLuaLZq7m/RmsWYvoLT3jebBlpvvQE8YlI= francois.deppierraz@nimag.net ssh-dss AAAAB3NzaC1kc3MAAACBAJkupmdsJSDXfUy5EU5NTRBDr9Woo3w0YnB8KmnJW9ghU8C7SkWPB1fIHVe+esFfd3qWBseb83PoFX63geZJAg6bjV4/Rdn1zEoa9EO2QyUdYUen4+rpsh3vVKZ6HFNsn3+W5+kPYgE1F/N4INqkbjY3sqCkP/W1BL9+sbVVbuJFAAAAFQCfjWDk5XhvGUkPjNWWVqltBYzHtwAAAIEAg/XL7ky7x9Ad5banzPFAfmM+DGFe0A/JEbLDjKmr5KBM5x4RFohtEvZ8ECuVGUOqBWdgAjyYwsG4oRVjLnKrf/rgmbNRzSFgEWkcAye3BVwk7Dt6hh4knEl+mNfOLq+FH0011UhecOiqTcESMzQDtgQ1vJh2VchElBLjl3x/ZugAAACAAh5jGQC338t5ObP8trSlOefkx0sXmmEzUbo3Mt8mGUuGJPx8m+X0L8Xd+l5rQxytqE3SmV/RD+6REqBuPqHM8RQuqAzfjdOeg/Ajdggx1CRMTVhltZsgQoxO30cz9Qo0SdPoL+Jp1fLuaLZq7m/RmsWYvoLT3jebBlpvvQE8YlI= Francois Deppierraz from="192.168.1.1",command="/bin/false",no-pty,no-port-forwarding ssh-dss AAAAB3NzaC1kc3MAAACBAJkupmdsJSDXfUy5EU5NTRBDr9Woo3w0YnB8KmnJW9ghU8C7SkWPB1fIHVe+esFfd3qWBseb83PoFX63geZJAg6bjV4/Rdn1zEoa9EO2QyUdYUen4+rpsh3vVKZ6HFNsn3+W5+kPYgE1F/N4INqkbjY3sqCkP/W1BL9+sbVVbuJFAAAAFQCfjWDk5XhvGUkPjNWWVqltBYzHtwAAAIEAg/XL7ky7x9Ad5banzPFAfmM+DGFe0A/JEbLDjKmr5KBM5x4RFohtEvZ8ECuVGUOqBWdgAjyYwsG4oRVjLnKrf/rgmbNRzSFgEWkcAye3BVwk7Dt6hh4knEl+mNfOLq+FH0011UhecOiqTcESMzQDtgQ1vJh2VchElBLjl3x/ZugAAACAAh5jGQC338t5ObP8trSlOefkx0sXmmEzUbo3Mt8mGUuGJPx8m+X0L8Xd+l5rQxytqE3SmV/RD+6REqBuPqHM8RQuqAzfjdOeg/Ajdggx1CRMTVhltZsgQoxO30cz9Qo0SdPoL+Jp1fLuaLZq7m/RmsWYvoLT3jebBlpvvQE8YlI= Francois Deppierraz -from="192.168.1.1, www.reductivelabs.com",command="/bin/false",no-pty,no-port-forwarding ssh-dss AAAAB3NzaC1kc3MAAACBAJkupmdsJSDXfUy5EU5NTRBDr9Woo3w0YnB8KmnJW9ghU8C7SkWPB1fIHVe+esFfd3qWBseb83PoFX63geZJAg6bjV4/Rdn1zEoa9EO2QyUdYUen4+rpsh3vVKZ6HFNsn3+W5+kPYgE1F/N4INqkbjY3sqCkP/W1BL9+sbVVbuJFAAAAFQCfjWDk5XhvGUkPjNWWVqltBYzHtwAAAIEAg/XL7ky7x9Ad5banzPFAfmM+DGFe0A/JEbLDjKmr5KBM5x4RFohtEvZ8ECuVGUOqBWdgAjyYwsG4oRVjLnKrf/rgmbNRzSFgEWkcAye3BVwk7Dt6hh4knEl+mNfOLq+FH0011UhecOiqTcESMzQDtgQ1vJh2VchElBLjl3x/ZugAAACAAh5jGQC338t5ObP8trSlOefkx0sXmmEzUbo3Mt8mGUuGJPx8m+X0L8Xd+l5rQxytqE3SmV/RD+6REqBuPqHM8RQuqAzfjdOeg/Ajdggx1CRMTVhltZsgQoxO30cz9Qo0SdPoL+Jp1fLuaLZq7m/RmsWYvoLT3jebBlpvvQE8YlI= Francois Deppierraz +from="192.168.1.1, www.puppetlabs.com",command="/bin/false",no-pty,no-port-forwarding ssh-dss AAAAB3NzaC1kc3MAAACBAJkupmdsJSDXfUy5EU5NTRBDr9Woo3w0YnB8KmnJW9ghU8C7SkWPB1fIHVe+esFfd3qWBseb83PoFX63geZJAg6bjV4/Rdn1zEoa9EO2QyUdYUen4+rpsh3vVKZ6HFNsn3+W5+kPYgE1F/N4INqkbjY3sqCkP/W1BL9+sbVVbuJFAAAAFQCfjWDk5XhvGUkPjNWWVqltBYzHtwAAAIEAg/XL7ky7x9Ad5banzPFAfmM+DGFe0A/JEbLDjKmr5KBM5x4RFohtEvZ8ECuVGUOqBWdgAjyYwsG4oRVjLnKrf/rgmbNRzSFgEWkcAye3BVwk7Dt6hh4knEl+mNfOLq+FH0011UhecOiqTcESMzQDtgQ1vJh2VchElBLjl3x/ZugAAACAAh5jGQC338t5ObP8trSlOefkx0sXmmEzUbo3Mt8mGUuGJPx8m+X0L8Xd+l5rQxytqE3SmV/RD+6REqBuPqHM8RQuqAzfjdOeg/Ajdggx1CRMTVhltZsgQoxO30cz9Qo0SdPoL+Jp1fLuaLZq7m/RmsWYvoLT3jebBlpvvQE8YlI= Francois Deppierraz ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA2Vi+TdC3iOGYcIo5vGTvC9P9rjHl9RxCuZmSfn+YDFQ35RXf0waijtjp9I7GYh6R4hBjA5z0u/Pzi95LET5NfRM0Gdc0DJyvBI7K+ALBxIT383Iz6Yz4iKxe1TEJgHGM2he4+7BHkjc3kdIZqIpZjucCk4VsXSxujO4MKKvtaKK2l+kahlLQHHw/vZkDpIgL52iGVsjW9l8RLJaKHZ4mDHJN/Q/Rzn2W4EvcdHUzwhvGMwZlm8clDwITBrSsawYtnivJrQSYcmTRqJuS8wprNDrLIhTGjrwFg5WpruUuMt6fLuCqwe6TeEL+nh3DQ4g554c5aRp3oU6LGBKTvNZGWQ== francois@korn ssh-dss AAAAB3NzaC1kc3MAAACBAMPpCYnjywOemd8LqbbmC+bePNR3/H1rXsiFwjSLhYE3bbOpvclvOzN1DruFc34m0FopVnMkP+aubjdIYF8pijl+5hg9ggB7Kno2dl0Dd1rGN/swvmhA8OpLAQv7Qt7UnXKVho3as08zYZsrHxYFu0wlnkdbsv4cy4aXyQKd4MPVAAAAFQDSyQFWg8Qt3wU05buhZ10psoR7tQAAAIEAmAhguXwUnI3P2FF5NAW/mpJUmUERdL4pyZARUyAgpf7ezwrh9TJqrvGTQNBF97Xqaivyncm5JWQdMIsTBxEFaXZGkmBta02KnWcn447qvIh7iv8XpNL6M9flCkBEZOJ4t9El0ytTSHHaiCz8A20Et+E8evWyi1kXkFDt8ML2dGgAAACBAK0X4ympbdEjgV/ZyOc+BU22u7vOnfSOUJmyar4Ax1MIDNnoyNWKnGvxRutydQcQOKQHZEU0fE8MhPFn6nLF6CoVfEl/oz0EYz3hjV4WPFpHrF5DY/rhvNj8iuneKJ5P0dy/rG6m5qey25PnHyGFVoIRlkHJvBCJT40dHs40YEjI francois@korn ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAut8aOSxenjOqF527dlsdHWV4MNoAsX14l9M297+SQXaQ5Z3BedIxZaoQthkDALlV/25A1COELrg9J2MqJNQc8Xe9XQOIkBQWWinUlD/BXwoOTWEy8C8zSZPHZ3getMMNhGTBO+q/O+qiJx3y5cA4MTbw2zSxukfWC87qWwcZ64UUlegIM056vPsdZWFclS9hsROVEa57YUMrehQ1EGxT4Z5j6zIopufGFiAPjZigq/vqgcAqhAKP6yu4/gwO6S9tatBeEjZ8fafvj1pmvvIplZeMr96gHE7xS3pEEQqnB3nd4RY7AF6j9kFixnsytAUO7STPh/M3pLiVQBN89TvWPQ== diff --git a/test/network/handler/ca.rb b/test/network/handler/ca.rb index 16782bb18..f528c7bc0 100755 --- a/test/network/handler/ca.rb +++ b/test/network/handler/ca.rb @@ -1,274 +1,274 @@ #!/usr/bin/env ruby require File.dirname(__FILE__) + '/../../lib/puppettest' require 'puppettest' require 'puppet/network/handler/ca' require 'mocha' if ARGV.length > 0 and ARGV[0] == "short" $short = true else $short = false end class TestCA < Test::Unit::TestCase include PuppetTest::ServerTest def setup Puppet::Util::SUIDManager.stubs(:asuser).yields super end # Verify that we're autosigning. We have to autosign a "different" machine, # since we always autosign the CA server's certificate. def test_autocertgeneration ca = nil # create our ca assert_nothing_raised { ca = Puppet::Network::Handler.ca.new(:autosign => true) } # create a cert with a fake name key = nil csr = nil cert = nil hostname = "test.domain.com" assert_nothing_raised { cert = Puppet::SSLCertificates::Certificate.new( :name => "test.domain.com" ) } # make the request assert_nothing_raised { cert.mkcsr } # and get it signed certtext = nil cacerttext = nil assert_nothing_raised { certtext, cacerttext = ca.getcert(cert.csr.to_s) } # they should both be strings assert_instance_of(String, certtext) assert_instance_of(String, cacerttext) # and they should both be valid certs assert_nothing_raised { OpenSSL::X509::Certificate.new(certtext) } assert_nothing_raised { OpenSSL::X509::Certificate.new(cacerttext) } # and pull it again, just to make sure we're getting the same thing newtext = nil assert_nothing_raised { newtext, cacerttext = ca.getcert( - cert.csr.to_s, "test.reductivelabs.com", "127.0.0.1" + cert.csr.to_s, "test.puppetlabs.com", "127.0.0.1" ) } assert_equal(certtext,newtext) end # this time don't use autosign def test_storeAndSign ca = nil caserv = nil # make our CA server assert_nothing_raised { caserv = Puppet::Network::Handler.ca.new(:autosign => false) } # retrieve the actual ca object assert_nothing_raised { ca = caserv.ca } # make our test cert again key = nil csr = nil cert = nil hostname = "test.domain.com" assert_nothing_raised { cert = Puppet::SSLCertificates::Certificate.new( :name => "anothertest.domain.com" ) } # and the CSR assert_nothing_raised { cert.mkcsr } # retrieve them certtext = nil assert_nothing_raised { certtext, cacerttext = caserv.getcert( - cert.csr.to_s, "test.reductivelabs.com", "127.0.0.1" + cert.csr.to_s, "test.puppetlabs.com", "127.0.0.1" ) } # verify we got nothing back, since autosign is off assert_equal("", certtext) # now sign it manually, with the CA object x509 = nil assert_nothing_raised { x509, cacert = ca.sign(cert.csr) } # and write it out cert.cert = x509 assert_nothing_raised { cert.write } assert(File.exists?(cert.certfile)) # now get them again, and verify that we actually get them newtext = nil assert_nothing_raised { newtext, cacerttext = caserv.getcert(cert.csr.to_s) } assert(newtext) assert_nothing_raised { OpenSSL::X509::Certificate.new(newtext) } # Now verify that we can clean a given host's certs assert_nothing_raised { ca.clean("anothertest.domain.com") } assert(!File.exists?(cert.certfile), "Cert still exists after clean") end # and now test the autosign file def test_autosign autosign = File.join(tmpdir, "autosigntesting") @@tmpfiles << autosign File.open(autosign, "w") { |f| f.puts "hostmatch.domain.com" f.puts "*.other.com" } caserv = nil assert_nothing_raised { caserv = Puppet::Network::Handler.ca.new(:autosign => autosign) } # make sure we know what's going on assert(caserv.autosign?("hostmatch.domain.com")) assert(caserv.autosign?("fakehost.other.com")) - assert(!caserv.autosign?("kirby.reductivelabs.com")) + assert(!caserv.autosign?("kirby.puppetlabs.com")) assert(!caserv.autosign?("culain.domain.com")) end # verify that things aren't autosigned by default def test_nodefaultautosign caserv = nil assert_nothing_raised { caserv = Puppet::Network::Handler.ca.new() } # make sure we know what's going on assert(!caserv.autosign?("hostmatch.domain.com")) assert(!caserv.autosign?("fakehost.other.com")) - assert(!caserv.autosign?("kirby.reductivelabs.com")) + assert(!caserv.autosign?("kirby.puppetlabs.com")) assert(!caserv.autosign?("culain.domain.com")) end # We want the CA to autosign its own certificate, because otherwise # the puppetmasterd CA does not autostart. def test_caautosign server = nil Puppet[:name] = "puppetmasterd" assert_nothing_raised { server = Puppet::Network::HTTPServer::WEBrick.new( :Port => @@port, :Handlers => { :CA => {}, # so that certs autogenerate :Status => nil } ) } end # Make sure true/false causes the file to be ignored. def test_autosign_true_beats_file caserv = nil assert_nothing_raised { caserv = Puppet::Network::Handler.ca.new() } host = "hostname.domain.com" # Create an autosign file file = tempfile() Puppet[:autosign] = file File.open(file, "w") { |f| f.puts host } # Start with "false" Puppet[:autosign] = false assert(! caserv.autosign?(host), "Host was incorrectly autosigned") # Then set it to true Puppet[:autosign] = true assert(caserv.autosign?(host), "Host was not autosigned") # And try a different host assert(caserv.autosign?("other.yay.com"), "Host was not autosigned") # And lastly the file Puppet[:autosign] = file assert(caserv.autosign?(host), "Host was not autosigned") # And try a different host assert(! caserv.autosign?("other.yay.com"), "Host was autosigned") end # Make sure that a CSR created with keys that don't match the existing # cert throws an exception on the server. def test_mismatched_public_keys_throws_exception ca = Puppet::Network::Handler.ca.new() # First initialize the server client = Puppet::Network::Client.ca.new :CA => ca client.request_cert File.unlink(Puppet[:hostcsr]) # Now use a different cert name Puppet[:certname] = "my.host.com" client = Puppet::Network::Client.ca.new :CA => ca firstcsr = client.csr File.unlink(Puppet[:hostcsr]) if FileTest.exists?(Puppet[:hostcsr]) assert_nothing_raised("Could not get cert") do ca.getcert(firstcsr.to_s) end # Now get rid of the public key, forcing a new csr File.unlink(Puppet[:hostprivkey]) client = Puppet::Network::Client.ca.new :CA => ca second_csr = client.csr assert(firstcsr.to_s != second_csr.to_s, "CSR did not change") assert_raise(Puppet::Error, "CA allowed mismatched keys") do ca.getcert(second_csr.to_s) end end end diff --git a/test/test b/test/test index 097885751..c8b9b08ef 100755 --- a/test/test +++ b/test/test @@ -1,241 +1,241 @@ #!/usr/bin/env ruby # # = Synopsis # # Run unit tests, usually with the goal of resolving some conflict # between tests. # # = Usage # # test [-d|--debug] [-f|--files] [-h|--help] [-n method] [-v|--verbose] [file] ... # # = Description # # This script is useful for running a specific subset of unit tests, especially # when attempting to find a conflict between tests. By default, it will take # the first argument you pass it and run that test or test directory with each # test directory in turn, looking for a failure. If any tests fail, then # the script will drill into that test directory, looking for the specific conflict. # # In this way, when you have deduced you have two conflicting unit tests (tests which # pass in isolation but fail when run together), you can tell this script where # the failure is and leave it alone to find the conflict. # # This script is different from the Rakefile because it will run all tests in # a single process, whereas if you ask the Rakefile to run multiple tests, it will # run them in separate processes thus making it impossible to find conflicts. # # = Examples # # Attempt to resolve a conflict between a single test suite that could be anywhere: # # ./test ral/providers/user.rb # # Determine whether two individual files conflict: # # ./test --files language/functions.rb ral/providers/provider.rb # # Run the same test, but only run a specific unit test: # # ./test -d -n test_search --files language/functions.rb ral/providers/provider.rb # # = Options # # debug:: # Enable full debugging. # # files:: # Specify exactly which files to test. # # help:: # Print this help message # # n:: # Specify a single unit test to run. You can still specify as many files # as you want. # # verbose:: # Print extra information. # # = Example # # puppet -l /tmp/script.log script.pp # # = Author # # Luke Kanies # # = Copyright # -# Copyright (c) 2005 Reductive Labs, LLC +# Copyright (c) 2005 Puppet Labs, LLC # Licensed under the GNU Public License require 'find' require 'getoptlong' include Find result = GetoptLong.new( [ "--debug", "-d", GetoptLong::NO_ARGUMENT ], [ "--verbose", "-v", GetoptLong::NO_ARGUMENT ], [ "-n", GetoptLong::REQUIRED_ARGUMENT ], [ "--files", "-f", GetoptLong::NO_ARGUMENT ], [ "--help", "-h", GetoptLong::NO_ARGUMENT ] ) usage = "USAGE: %s [--help] suite" % $0 $options = {} keep = [] result.each { |opt,arg| case opt when "--verbose" $options[:verbose] = true when "--files" $options[:files] = true when "--debug" $options[:debug] = true $options[:verbose] = true when "--help" puts usage exit else keep << opt keep << arg if arg end } def dirs Dir.glob("*").find_all { |d| FileTest.directory?(d) }.reject { |d| ["lib", "data"].include?(d) } end def rake(*args) print "trying %s..." % args.join(" ") output = %x{rake %s} % args.join(" ") if $?.exitstatus == 0 puts "succeeded" return true else puts "failed" return false end end def resolve(dir) dirs = dirs() # If the passed dir is a subdir or file, put the basedir last if dir.include?(File::SEPARATOR) basedir = dir.split(File::SEPARATOR)[0] if dirs.include?(basedir) dirs.delete(basedir) dirs << basedir end end failed = nil dirs.each do |d| next if d == dir unless run([d, dir]) failed = d break end end puts "%s failed" % failed files = ruby_files(failed) files.each do |file| unless run([file, dir]) puts file exit(0) end end exit(1) end def ruby_files(dir) files = [] # First collect the entire file list. begin find(dir) { |f| files << f if f =~ /\.rb$/ } rescue => detail puts "could not find on %s: %s" % [dir.inspect, detail] end files end def run(files, flags = nil) args = %w{ruby} args << "-Ilib:../lib" args << "lib/rake/puppet_test_loader.rb" if flags args += flags end args += ARGV print files.join(" ") + "... " $stdout.flush files.each do |file| case File.stat(file).ftype when "file"; args << file when "directory"; args += ruby_files(file) else $stderr.puts "Skipping %s; can't handle %s" % [file, File.stat(file).ftype] end end args = args.join(" ") if $options[:verbose] p args end output = %x{#{args} 2>&1} if $options[:debug] print output end if $?.exitstatus == 0 puts "succeeded" return true else puts "failed" puts output return false end end if $options[:files] run(ARGV, keep) else dir = ARGV.shift unless dir $stderr.puts usage exit(1) end resolve(dir) end # # #files = [] # #args.each do |test| # if FileTest.directory?(test) # files += ruby_files(test) # end #end ## Now load all of our files. #files.each do |file| # load file unless file =~ /^-/ #end # #runner = Test::Unit::AutoRunner.new(false) #runner.process_args #runner.run