diff --git a/ext/debian/puppet-common.manpages b/ext/debian/puppet-common.manpages index d034f863a..6ebb5e296 100644 --- a/ext/debian/puppet-common.manpages +++ b/ext/debian/puppet-common.manpages @@ -1,35 +1,32 @@ man/man5/puppet.conf.5 man/man8/extlookup2hiera.8 man/man8/puppet.8 man/man8/puppet-agent.8 man/man8/puppet-apply.8 man/man8/puppet-catalog.8 man/man8/puppet-cert.8 man/man8/puppet-certificate.8 man/man8/puppet-certificate_request.8 man/man8/puppet-certificate_revocation_list.8 man/man8/puppet-config.8 man/man8/puppet-describe.8 man/man8/puppet-device.8 man/man8/puppet-doc.8 man/man8/puppet-facts.8 man/man8/puppet-file.8 man/man8/puppet-filebucket.8 man/man8/puppet-help.8 man/man8/puppet-inspect.8 -man/man8/puppet-instrumentation_data.8 -man/man8/puppet-instrumentation_listener.8 -man/man8/puppet-instrumentation_probe.8 man/man8/puppet-key.8 man/man8/puppet-kick.8 man/man8/puppet-man.8 man/man8/puppet-module.8 man/man8/puppet-node.8 man/man8/puppet-parser.8 man/man8/puppet-plugin.8 man/man8/puppet-queue.8 man/man8/puppet-report.8 man/man8/puppet-resource.8 man/man8/puppet-resource_type.8 man/man8/puppet-secret_agent.8 man/man8/puppet-status.8 diff --git a/ext/redhat/puppet.spec.erb b/ext/redhat/puppet.spec.erb index 6b8b3f9f5..8dc2c5734 100644 --- a/ext/redhat/puppet.spec.erb +++ b/ext/redhat/puppet.spec.erb @@ -1,860 +1,857 @@ # Augeas and SELinux requirements may be disabled at build time by passing # --without augeas and/or --without selinux to rpmbuild or mock # Fedora 17 ships with ruby 1.9, RHEL 7 with ruby 2.0, which use vendorlibdir instead # of sitelibdir. Adjust our target if installing on f17 or rhel7. %if 0%{?fedora} >= 17 || 0%{?rhel} >= 7 || 0%{?amzn} >= 1 %global puppet_libdir %(ruby -rrbconfig -e 'puts RbConfig::CONFIG["vendorlibdir"]') %else %global puppet_libdir %(ruby -rrbconfig -e 'puts RbConfig::CONFIG["sitelibdir"]') %endif %if 0%{?fedora} >= 17 || 0%{?rhel} >= 7 %global _with_systemd 1 %else %global _with_systemd 0 %endif # VERSION is subbed out during rake srpm process %global realversion <%= @version %> %global rpmversion <%= @rpmversion %> %global confdir ext/redhat %global pending_upgrade_path %{_localstatedir}/lib/rpm-state/puppet %global pending_upgrade_file %{pending_upgrade_path}/upgrade_pending Name: puppet Version: %{rpmversion} Release: <%= @rpmrelease -%>%{?dist} Vendor: %{?_host_vendor} Summary: A network tool for managing many disparate systems License: ASL 2.0 URL: http://puppetlabs.com Source0: http://puppetlabs.com/downloads/%{name}/%{name}-%{realversion}.tar.gz Group: System Environment/Base BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) BuildRequires: facter >= 1:1.7.0 # Puppet 3.x drops ruby 1.8.5 support and adds ruby 1.9 support BuildRequires: ruby >= 1.8.7 BuildRequires: hiera >= 1.0.0 BuildArch: noarch Requires: ruby >= 1.8 Requires: ruby-shadow Requires: rubygem-json # Pull in ruby selinux bindings where available %if 0%{?fedora} || 0%{?rhel} >= 6 %{!?_without_selinux:Requires: ruby(selinux), libselinux-utils} %else %if ( 0%{?rhel} && 0%{?rhel} == 5 ) || 0%{?amzn} >= 1 %{!?_without_selinux:Requires: libselinux-ruby, libselinux-utils} %endif %endif Requires: facter >= 1:1.7.0 # Puppet 3.x drops ruby 1.8.5 support and adds ruby 1.9 support # Ruby 1.8.7 available for el5 at: yum.puppetlabs.com/el/5/devel/$ARCH Requires: ruby >= 1.8.7 Requires: hiera >= 1.0.0 Obsoletes: hiera-puppet < 1.0.0 Provides: hiera-puppet >= 1.0.0 %{!?_without_augeas:Requires: ruby-augeas} # Required for %%pre Requires: shadow-utils %if 0%{?_with_systemd} # Required for %%post, %%preun, %%postun Requires: systemd %if 0%{?fedora} >= 18 || 0%{?rhel} >= 7 BuildRequires: systemd %else BuildRequires: systemd-units %endif %else # Required for %%post and %%preun Requires: chkconfig # Required for %%preun and %%postun Requires: initscripts %endif %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} # chkconfig (%%post, %%preun) and initscripts (%%preun %%postun) are required for non systemd # and systemd (%%post, %%preun, and %%postun) are required for systems with systemd as default # They come along transitively with 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 -n %{name}-%{realversion} %build for f in external/nagios.rb relationship.rb; do sed -i -e '1d' lib/puppet/$f done find examples/ -type f | xargs --no-run-if-empty chmod a-x %install rm -rf %{buildroot} ruby install.rb --destdir=%{buildroot} --quick --no-rdoc --sitelibdir=%{puppet_libdir} install -d -m0755 %{buildroot}%{_sysconfdir}/puppet/environments/example_env/manifests install -d -m0755 %{buildroot}%{_sysconfdir}/puppet/environments/example_env/modules install -d -m0755 %{buildroot}%{_sysconfdir}/puppet/manifests install -d -m0755 %{buildroot}%{_datadir}/%{name}/modules install -d -m0755 %{buildroot}%{_localstatedir}/lib/puppet install -d -m0755 %{buildroot}%{_localstatedir}/lib/puppet/state install -d -m0755 %{buildroot}%{_localstatedir}/lib/puppet/reports install -d -m0755 %{buildroot}%{_localstatedir}/run/puppet # As per redhat bz #495096 install -d -m0750 %{buildroot}%{_localstatedir}/log/puppet %if 0%{?_with_systemd} # Systemd for fedora >= 17 or el 7 %{__install} -d -m0755 %{buildroot}%{_unitdir} install -Dp -m0644 ext/systemd/puppet.service %{buildroot}%{_unitdir}/puppet.service ln -s %{_unitdir}/puppet.service %{buildroot}%{_unitdir}/puppetagent.service install -Dp -m0644 ext/systemd/puppetmaster.service %{buildroot}%{_unitdir}/puppetmaster.service %else # Otherwise init.d for fedora < 17 or el 5, 6 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 -m0755 %{confdir}/queue.init %{buildroot}%{_initrddir}/puppetqueue %endif 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 install -Dp -m0644 ext/README.environment %{buildroot}%{_sysconfdir}/puppet/environments/example_env/README.environment # 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} # remove misc packaging artifacts not applicable to rpms rm -rf %{buildroot}%{_datadir}/%{name}/ext/{gentoo,freebsd,solaris,suse,windows,osx,ips,debian} rm -f %{buildroot}%{_datadir}/%{name}/ext/redhat/*.init rm -f %{buildroot}%{_datadir}/%{name}/ext/{build_defaults.yaml,project_data.yaml} # Rpmlint fixup chmod 755 %{buildroot}%{_datadir}/%{name}/ext/regexp_nodes/regexp_nodes.rb chmod 755 %{buildroot}%{_datadir}/%{name}/ext/puppet-load.rb # 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 %if 0%{?fedora} >= 15 || 0%{?rhel} >= 7 # Setup tmpfiles.d config mkdir -p %{buildroot}%{_sysconfdir}/tmpfiles.d echo "D /var/run/%{name} 0755 %{name} %{name} -" > \ %{buildroot}%{_sysconfdir}/tmpfiles.d/%{name}.conf %endif # Create puppet modules directory for puppet module tool mkdir -p %{buildroot}%{_sysconfdir}/%{name}/modules # Install a NetworkManager dispatcher script to pickup changes to # # /etc/resolv.conf and such (https://bugzilla.redhat.com/532085). mkdir -p %{buildroot}%{_sysconfdir}/NetworkManager/dispatcher.d cp -pr ext/puppet-nm-dispatcher \ %{buildroot}%{_sysconfdir}/NetworkManager/dispatcher.d/98-%{name} %files %defattr(-, root, root, 0755) %doc LICENSE README.md examples %{_bindir}/puppet %{_bindir}/extlookup2hiera %{puppet_libdir}/* %dir %{_sysconfdir}/NetworkManager %dir %{_sysconfdir}/NetworkManager/dispatcher.d %{_sysconfdir}/NetworkManager/dispatcher.d/98-puppet %if 0%{?_with_systemd} %{_unitdir}/puppet.service %{_unitdir}/puppetagent.service %else %{_initrddir}/puppet %config(noreplace) %{_sysconfdir}/sysconfig/puppet %endif %dir %{_sysconfdir}/puppet %dir %{_sysconfdir}/%{name}/modules %if 0%{?fedora} >= 15 || 0%{?rhel} >= 7 %config(noreplace) %{_sysconfdir}/tmpfiles.d/%{name}.conf %endif %config(noreplace) %{_sysconfdir}/puppet/puppet.conf %config(noreplace) %{_sysconfdir}/puppet/auth.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} # man pages %{_mandir}/man5/puppet.conf.5.gz %{_mandir}/man8/puppet.8.gz %{_mandir}/man8/puppet-agent.8.gz %{_mandir}/man8/puppet-apply.8.gz %{_mandir}/man8/puppet-catalog.8.gz %{_mandir}/man8/puppet-describe.8.gz %{_mandir}/man8/puppet-ca.8.gz %{_mandir}/man8/puppet-cert.8.gz %{_mandir}/man8/puppet-certificate.8.gz %{_mandir}/man8/puppet-certificate_request.8.gz %{_mandir}/man8/puppet-certificate_revocation_list.8.gz %{_mandir}/man8/puppet-config.8.gz %{_mandir}/man8/puppet-device.8.gz %{_mandir}/man8/puppet-doc.8.gz %{_mandir}/man8/puppet-facts.8.gz %{_mandir}/man8/puppet-file.8.gz %{_mandir}/man8/puppet-filebucket.8.gz %{_mandir}/man8/puppet-help.8.gz %{_mandir}/man8/puppet-inspect.8.gz -%{_mandir}/man8/puppet-instrumentation_data.8.gz -%{_mandir}/man8/puppet-instrumentation_listener.8.gz -%{_mandir}/man8/puppet-instrumentation_probe.8.gz %{_mandir}/man8/puppet-key.8.gz %{_mandir}/man8/puppet-kick.8.gz %{_mandir}/man8/puppet-man.8.gz %{_mandir}/man8/puppet-module.8.gz %{_mandir}/man8/puppet-node.8.gz %{_mandir}/man8/puppet-parser.8.gz %{_mandir}/man8/puppet-plugin.8.gz %{_mandir}/man8/puppet-queue.8.gz %{_mandir}/man8/puppet-report.8.gz %{_mandir}/man8/puppet-resource.8.gz %{_mandir}/man8/puppet-resource_type.8.gz %{_mandir}/man8/puppet-secret_agent.8.gz %{_mandir}/man8/puppet-status.8.gz %{_mandir}/man8/extlookup2hiera.8.gz # These need to be owned by puppet so the server can # write to them. The separate %defattr's are required # to work around RH Bugzilla 681540 %defattr(-, puppet, puppet, 0755) %{_localstatedir}/run/puppet %defattr(-, puppet, puppet, 0750) %{_localstatedir}/log/puppet %{_localstatedir}/lib/puppet %{_localstatedir}/lib/puppet/state %{_localstatedir}/lib/puppet/reports # Return the default attributes to 0755 to # prevent incorrect permission assignment on EL6 %defattr(-, root, root, 0755) %files server %defattr(-, root, root, 0755) %if 0%{?_with_systemd} %{_unitdir}/puppetmaster.service %else %{_initrddir}/puppetmaster %{_initrddir}/puppetqueue %config(noreplace) %{_sysconfdir}/sysconfig/puppetmaster %endif %config(noreplace) %{_sysconfdir}/puppet/fileserver.conf %dir %{_sysconfdir}/puppet/manifests %dir %{_sysconfdir}/puppet/environments %dir %{_sysconfdir}/puppet/environments/example_env %dir %{_sysconfdir}/puppet/environments/example_env/manifests %dir %{_sysconfdir}/puppet/environments/example_env/modules %{_sysconfdir}/puppet/environments/example_env/README.environment %{_mandir}/man8/puppet-ca.8.gz %{_mandir}/man8/puppet-master.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 exit 0 %post %if 0%{?_with_systemd} /bin/systemctl daemon-reload >/dev/null 2>&1 || : if [ "$1" -ge 1 ]; then # The pidfile changed from 0.25.x to 2.6.x, handle upgrades without leaving # the old process running. oldpid="%{_localstatedir}/run/puppet/puppetd.pid" newpid="%{_localstatedir}/run/puppet/agent.pid" if [ -s "$oldpid" -a ! -s "$newpid" ]; then (kill $(< "$oldpid") && rm -f "$oldpid" && \ /bin/systemctl start puppet.service) >/dev/null 2>&1 || : fi fi %else /sbin/chkconfig --add puppet || : if [ "$1" -ge 1 ]; then # The pidfile changed from 0.25.x to 2.6.x, handle upgrades without leaving # the old process running. oldpid="%{_localstatedir}/run/puppet/puppetd.pid" newpid="%{_localstatedir}/run/puppet/agent.pid" if [ -s "$oldpid" -a ! -s "$newpid" ]; then (kill $(< "$oldpid") && rm -f "$oldpid" && \ /sbin/service puppet start) >/dev/null 2>&1 || : fi # If an old puppet process (one whose binary is located in /sbin) is running, # kill it and then start up a fresh with the new binary. if [ -e "$newpid" ]; then if ps aux | grep `cat "$newpid"` | grep -v grep | awk '{ print $12 }' | grep -q sbin; then (kill $(< "$newpid") && rm -f "$newpid" && \ /sbin/service puppet start) >/dev/null 2>&1 || : fi fi fi %endif %post server %if 0%{?_with_systemd} /bin/systemctl daemon-reload >/dev/null 2>&1 || : if [ "$1" -ge 1 ]; then # The pidfile changed from 0.25.x to 2.6.x, handle upgrades without leaving # the old process running. oldpid="%{_localstatedir}/run/puppet/puppetmasterd.pid" newpid="%{_localstatedir}/run/puppet/master.pid" if [ -s "$oldpid" -a ! -s "$newpid" ]; then (kill $(< "$oldpid") && rm -f "$oldpid" && \ /bin/systemctl start puppetmaster.service) > /dev/null 2>&1 || : fi fi %else /sbin/chkconfig --add puppetmaster || : if [ "$1" -ge 1 ]; then # The pidfile changed from 0.25.x to 2.6.x, handle upgrades without leaving # the old process running. oldpid="%{_localstatedir}/run/puppet/puppetmasterd.pid" newpid="%{_localstatedir}/run/puppet/master.pid" if [ -s "$oldpid" -a ! -s "$newpid" ]; then (kill $(< "$oldpid") && rm -f "$oldpid" && \ /sbin/service puppetmaster start) >/dev/null 2>&1 || : fi fi %endif %preun %if 0%{?_with_systemd} if [ "$1" -eq 0 ] ; then # Package removal, not upgrade /bin/systemctl --no-reload disable puppetagent.service > /dev/null 2>&1 || : /bin/systemctl --no-reload disable puppet.service > /dev/null 2>&1 || : /bin/systemctl stop puppetagent.service > /dev/null 2>&1 || : /bin/systemctl stop puppet.service > /dev/null 2>&1 || : /bin/systemctl daemon-reload >/dev/null 2>&1 || : fi if [ "$1" == "1" ]; then /bin/systemctl is-enabled puppetagent.service > /dev/null 2>&1 if [ "$?" == "0" ]; then /bin/systemctl --no-reload disable puppetagent.service > /dev/null 2>&1 ||: /bin/systemctl stop puppetagent.service > /dev/null 2>&1 ||: /bin/systemctl daemon-reload >/dev/null 2>&1 ||: if [ ! -d %{pending_upgrade_path} ]; then mkdir -p %{pending_upgrade_path} fi if [ ! -e %{pending_upgrade_file} ]; then touch %{pending_upgrade_file} fi fi fi %else if [ "$1" = 0 ] ; then /sbin/service puppet stop > /dev/null 2>&1 /sbin/chkconfig --del puppet || : fi %endif %preun server %if 0%{?_with_systemd} if [ $1 -eq 0 ] ; then # Package removal, not upgrade /bin/systemctl --no-reload disable puppetmaster.service > /dev/null 2>&1 || : /bin/systemctl stop puppetmaster.service > /dev/null 2>&1 || : /bin/systemctl daemon-reload >/dev/null 2>&1 || : fi %else if [ "$1" = 0 ] ; then /sbin/service puppetmaster stop > /dev/null 2>&1 /sbin/chkconfig --del puppetmaster || : fi %endif %postun %if 0%{?_with_systemd} if [ $1 -ge 1 ] ; then if [ -e %{pending_upgrade_file} ]; then /bin/systemctl --no-reload enable puppet.service > /dev/null 2>&1 ||: /bin/systemctl start puppet.service > /dev/null 2>&1 ||: /bin/systemctl daemon-reload >/dev/null 2>&1 ||: rm %{pending_upgrade_file} fi # Package upgrade, not uninstall /bin/systemctl try-restart puppetagent.service >/dev/null 2>&1 || : fi %else if [ "$1" -ge 1 ]; then /sbin/service puppet condrestart >/dev/null 2>&1 || : fi %endif %postun server %if 0%{?_with_systemd} if [ $1 -ge 1 ] ; then # Package upgrade, not uninstall /bin/systemctl try-restart puppetmaster.service >/dev/null 2>&1 || : fi %else if [ "$1" -ge 1 ]; then /sbin/service puppetmaster condrestart >/dev/null 2>&1 || : fi %endif %clean rm -rf %{buildroot} %changelog * <%= Time.now.strftime("%a %b %d %Y") %> Puppet Labs Release - <%= @rpmversion %>-<%= @rpmrelease %> - Build for <%= @version %> * Wed Oct 2 2013 Jason Antman - Move systemd service and unit file names back to "puppet" from erroneous "puppetagent" - Add symlink to puppetagent unit file for compatibility with current bug - Alter package removal actions to deactivate and stop both service names * Thu Jun 27 2013 Matthaus Owens - 3.2.3-0.1rc0 - Bump requires on ruby-rgen to 0.6.5 * Fri Apr 12 2013 Matthaus Owens - 3.2.0-0.1rc0 - Add requires on ruby-rgen for new parser in Puppet 3.2 * Fri Jan 25 2013 Matthaus Owens - 3.1.0-0.1rc1 - Add extlookup2hiera.8.gz to the files list * Wed Jan 9 2013 Ryan Uber - 3.1.0-0.1rc1 - Work-around for RH Bugzilla 681540 * Fri Dec 28 2012 Michael Stahnke - 3.0.2-2 - Added a script for Network Manager for bug https://bugzilla.redhat.com/532085 * Tue Dec 18 2012 Matthaus Owens - Remove for loop on examples/ code which no longer exists. Add --no-run-if-empty to xargs invocations. * Sat Dec 1 2012 Ryan Uber - Fix for logdir perms regression (#17866) * Wed Aug 29 2012 Moses Mendoza - 3.0.0-0.1rc5 - Update for 3.0.0 rc5 * Fri Aug 24 2012 Eric Sorenson - 3.0.0-0.1rc4 - Facter requirement is 1.6.11, not 2.0 - Update for 3.0.0 rc4 * Tue Aug 21 2012 Moses Mendoza - 2.7.19-1 - Update for 2.7.19 * Tue Aug 14 2012 Moses Mendoza - 2.7.19-0.1rc3 - Update for 2.7.19rc3 * Tue Aug 7 2012 Moses Mendoza - 2.7.19-0.1rc2 - Update for 2.7.19rc2 * Wed Aug 1 2012 Moses Mendoza - 2.7.19-0.1rc1 - Update for 2.7.19rc1 * Wed Jul 11 2012 William Hopper - 2.7.18-2 - (#15221) Create /etc/puppet/modules for puppet module tool * Mon Jul 9 2012 Moses Mendoza - 2.7.18-1 - Update for 2.7.18 * Tue Jun 19 2012 Matthaus Litteken - 2.7.17-1 - Update for 2.7.17 * Wed Jun 13 2012 Matthaus Litteken - 2.7.16-1 - Update for 2.7.16 * Fri Jun 08 2012 Moses Mendoza - 2.7.16-0.1rc1.2 - Updated facter 2.0 dep to include epoch 1 * Wed Jun 06 2012 Matthaus Litteken - 2.7.16-0.1rc1 - Update for 2.7.16rc1, added generated manpages * Fri Jun 01 2012 Matthaus Litteken - 3.0.0-0.1rc3 - Puppet 3.0.0rc3 Release * Fri Jun 01 2012 Matthaus Litteken - 2.7.15-0.1rc4 - Update for 2.7.15rc4 * Tue May 29 2012 Moses Mendoza - 2.7.15-0.1rc3 - Update for 2.7.15rc3 * Tue May 22 2012 Matthaus Litteken - 3.0.0-0.1rc2 - Puppet 3.0.0rc2 Release * Thu May 17 2012 Matthaus Litteken - 3.0.0-0.1rc1 - Puppet 3.0.0rc1 Release * Wed May 16 2012 Moses Mendoza - 2.7.15-0.1rc2 - Update for 2.7.15rc2 * Tue May 15 2012 Moses Mendoza - 2.7.15-0.1rc1 - Update for 2.7.15rc1 * Wed May 02 2012 Moses Mendoza - 2.7.14-1 - Update for 2.7.14 * Tue Apr 10 2012 Matthaus Litteken - 2.7.13-1 - Update for 2.7.13 * Mon Mar 12 2012 Michael Stahnke - 2.7.12-1 - Update for 2.7.12 * Fri Feb 24 2012 Matthaus Litteken - 2.7.11-2 - Update 2.7.11 from proper tag, including #12572 * Wed Feb 22 2012 Michael Stahnke - 2.7.11-1 - Update for 2.7.11 * Wed Jan 25 2012 Michael Stahnke - 2.7.10-1 - Update for 2.7.10 * Fri Dec 9 2011 Matthaus Litteken - 2.7.9-1 - Update for 2.7.9 * Thu Dec 8 2011 Matthaus Litteken - 2.7.8-1 - Update for 2.7.8 * Wed Nov 30 2011 Michael Stahnke - 2.7.8-0.1rc1 - Update for 2.7.8rc1 * Mon Nov 21 2011 Michael Stahnke - 2.7.7-1 - Relaese 2.7.7 * Tue Nov 01 2011 Michael Stahnke - 2.7.7-0.1rc1 - Update for 2.7.7rc1 * Fri Oct 21 2011 Michael Stahnke - 2.7.6-1 - 2.7.6 final * Thu Oct 13 2011 Michael Stahnke - 2.7.6-.1rc3 - New RC * Fri Oct 07 2011 Michael Stahnke - 2.7.6-0.1rc2 - New RC * Mon Oct 03 2011 Michael Stahnke - 2.7.6-0.1rc1 - New RC * Fri Sep 30 2011 Michael Stahnke - 2.7.5-1 - Fixes for CVE-2011-3869, 3870, 3871 * Wed Sep 28 2011 Michael Stahnke - 2.7.4-1 - Fix for CVE-2011-3484 * Wed Jul 06 2011 Michael Stahnke - 2.7.2-0.2.rc1 - Clean up rpmlint errors - Put man pages in correct package * Wed Jul 06 2011 Michael Stahnke - 2.7.2-0.1.rc1 - Update to 2.7.2rc1 * Wed Jun 15 2011 Todd Zullinger - 2.6.9-0.1.rc1 - Update rc versioning to ensure 2.6.9 final is newer to rpm - sync changes with Fedora/EPEL * Tue Jun 14 2011 Michael Stahnke - 2.6.9rc1-1 - Update to 2.6.9rc1 * Thu Apr 14 2011 Todd Zullinger - 2.6.8-1 - Update to 2.6.8 * Thu Mar 24 2011 Todd Zullinger - 2.6.7-1 - Update to 2.6.7 * Wed Mar 16 2011 Todd Zullinger - 2.6.6-1 - Update to 2.6.6 - Ensure %%pre exits cleanly - Fix License tag, puppet is now GPLv2 only - Create and own /usr/share/puppet/modules (#615432) - Properly restart puppet agent/master daemons on upgrades from 0.25.x - Require libselinux-utils when selinux support is enabled - Support tmpfiles.d for Fedora >= 15 (#656677) * Wed Feb 09 2011 Fedora Release Engineering - 0.25.5-2 - Rebuilt for https://fedoraproject.org/wiki/Fedora_15_Mass_Rebuild * Mon May 17 2010 Todd Zullinger - 0.25.5-1 - Update to 0.25.5 - Adjust selinux conditional for EL-6 - Apply rundir-perms patch from tarball rather than including it separately - Update URL's to reflect the new puppetlabs.com domain * Fri Jan 29 2010 Todd Zullinger - 0.25.4-1 - Update to 0.25.4 * Tue Jan 19 2010 Todd Zullinger - 0.25.3-2 - Apply upstream patch to fix cron resources (upstream #2845) * Mon Jan 11 2010 Todd Zullinger - 0.25.3-1 - Update to 0.25.3 * Tue Jan 05 2010 Todd Zullinger - 0.25.2-1.1 - Replace %%define with %%global for macros * Tue Jan 05 2010 Todd Zullinger - 0.25.2-1 - Update to 0.25.2 - Fixes CVE-2010-0156, tmpfile security issue (#502881) - Install auth.conf, puppetqd manpage, and queuing examples/docs * Wed Nov 25 2009 Jeroen van Meeuwen - 0.25.1-1 - New upstream version * Tue Oct 27 2009 Todd Zullinger - 0.25.1-0.3 - 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/lib/puppet/application.rb b/lib/puppet/application.rb index 1d9611093..791a8e415 100644 --- a/lib/puppet/application.rb +++ b/lib/puppet/application.rb @@ -1,516 +1,513 @@ require 'optparse' require 'puppet/util/command_line' require 'puppet/util/plugins' require 'puppet/util/constant_inflector' require 'puppet/error' module Puppet # This class handles all the aspects of a Puppet application/executable # * setting up options # * setting up logs # * choosing what to run # * representing execution status # # === Usage # An application is a subclass of Puppet::Application. # # For legacy compatibility, # Puppet::Application[:example].run # is equivalent to # Puppet::Application::Example.new.run # # # class Puppet::Application::Example < Puppet::Application # # def preinit # # perform some pre initialization # @all = false # end # # # run_command is called to actually run the specified command # def run_command # send Puppet::Util::CommandLine.new.args.shift # end # # # option uses metaprogramming to create a method # # and also tells the option parser how to invoke that method # option("--arg ARGUMENT") do |v| # @args << v # end # # option("--debug", "-d") do |v| # @debug = v # end # # option("--all", "-a:) do |v| # @all = v # end # # def handle_unknown(opt,arg) # # last chance to manage an option # ... # # let's say to the framework we finally handle this option # true # end # # def read # # read action # end # # def write # # writeaction # end # # end # # === Preinit # The preinit block is the first code to be called in your application, before option parsing, # setup or command execution. # # === Options # Puppet::Application uses +OptionParser+ to manage the application options. # Options are defined with the +option+ method to which are passed various # arguments, including the long option, the short option, a description... # Refer to +OptionParser+ documentation for the exact format. # * If the option method is given a block, this one will be called whenever # the option is encountered in the command-line argument. # * If the option method has no block, a default functionnality will be used, that # stores the argument (or true/false if the option doesn't require an argument) in # the global (to the application) options array. # * If a given option was not defined by a the +option+ method, but it exists as a Puppet settings: # * if +unknown+ was used with a block, it will be called with the option name and argument # * if +unknown+ wasn't used, then the option/argument is handed to Puppet.settings.handlearg for # a default behavior # # --help is managed directly by the Puppet::Application class, but can be overriden. # # === Setup # Applications can use the setup block to perform any initialization. # The default +setup+ behaviour is to: read Puppet configuration and manage log level and destination # # === What and how to run # If the +dispatch+ block is defined it is called. This block should return the name of the registered command # to be run. # If it doesn't exist, it defaults to execute the +main+ command if defined. # # === Execution state # The class attributes/methods of Puppet::Application serve as a global place to set and query the execution # status of the application: stopping, restarting, etc. The setting of the application status does not directly # affect its running status; it's assumed that the various components within the application will consult these # settings appropriately and affect their own processing accordingly. Control operations (signal handlers and # the like) should set the status appropriately to indicate to the overall system that it's the process of # stopping or restarting (or just running as usual). # # So, if something in your application needs to stop the process, for some reason, you might consider: # # def stop_me! # # indicate that we're stopping # Puppet::Application.stop! # # ...do stuff... # end # # And, if you have some component that involves a long-running process, you might want to consider: # # def my_long_process(giant_list_to_munge) # giant_list_to_munge.collect do |member| # # bail if we're stopping # return if Puppet::Application.stop_requested? # process_member(member) # end # end class Application require 'puppet/util' include Puppet::Util DOCPATTERN = ::File.expand_path(::File.dirname(__FILE__) + "/util/command_line/*" ) CommandLineArgs = Struct.new(:subcommand_name, :args) @loader = Puppet::Util::Autoload.new(self, 'puppet/application') class << self include Puppet::Util attr_accessor :run_status def clear! self.run_status = nil end def stop! self.run_status = :stop_requested end def restart! self.run_status = :restart_requested end # Indicates that Puppet::Application.restart! has been invoked and components should # do what is necessary to facilitate a restart. def restart_requested? :restart_requested == run_status end # Indicates that Puppet::Application.stop! has been invoked and components should do what is necessary # for a clean stop. def stop_requested? :stop_requested == run_status end # Indicates that one of stop! or start! was invoked on Puppet::Application, and some kind of process # shutdown/short-circuit may be necessary. def interrupted? [:restart_requested, :stop_requested].include? run_status end # Indicates that Puppet::Application believes that it's in usual running run_mode (no stop/restart request # currently active). def clear? run_status.nil? end # Only executes the given block if the run status of Puppet::Application is clear (no restarts, stops, # etc. requested). # Upon block execution, checks the run status again; if a restart has been requested during the block's # execution, then controlled_run will send a new HUP signal to the current process. # Thus, long-running background processes can potentially finish their work before a restart. def controlled_run(&block) return unless clear? result = block.call Process.kill(:HUP, $PID) if restart_requested? result end SHOULD_PARSE_CONFIG_DEPRECATION_MSG = "is no longer supported; config file parsing " + "is now controlled by the puppet engine, rather than by individual applications. This " + "method will be removed in a future version of puppet." def should_parse_config Puppet.deprecation_warning("should_parse_config " + SHOULD_PARSE_CONFIG_DEPRECATION_MSG) end def should_not_parse_config Puppet.deprecation_warning("should_not_parse_config " + SHOULD_PARSE_CONFIG_DEPRECATION_MSG) end def should_parse_config? Puppet.deprecation_warning("should_parse_config? " + SHOULD_PARSE_CONFIG_DEPRECATION_MSG) true end # used to declare code that handle an option def option(*options, &block) long = options.find { |opt| opt =~ /^--/ }.gsub(/^--(?:\[no-\])?([^ =]+).*$/, '\1' ).gsub('-','_') fname = "handle_#{long}".intern if (block_given?) define_method(fname, &block) else define_method(fname) do |value| self.options["#{long}".to_sym] = value end end self.option_parser_commands << [options, fname] end def banner(banner = nil) @banner ||= banner end def option_parser_commands @option_parser_commands ||= ( superclass.respond_to?(:option_parser_commands) ? superclass.option_parser_commands.dup : [] ) @option_parser_commands end # @return [Array] the names of available applications # @api public def available_application_names @loader.files_to_load.map do |fn| ::File.basename(fn, '.rb') end.uniq end # Finds the class for a given application and loads the class. This does # not create an instance of the application, it only gets a handle to the # class. The code for the application is expected to live in a ruby file # `puppet/application/#{name}.rb` that is available on the `$LOAD_PATH`. # # @param application_name [String] the name of the application to find (eg. "apply"). # @return [Class] the Class instance of the application that was found. # @raise [Puppet::Error] if the application class was not found. # @raise [LoadError] if there was a problem loading the application file. # @api public def find(application_name) begin require @loader.expand(application_name.to_s.downcase) rescue LoadError => e Puppet.log_and_raise(e, "Unable to find application '#{application_name}'. #{e}") end class_name = Puppet::Util::ConstantInflector.file2constant(application_name.to_s) clazz = try_load_class(class_name) ################################################################ #### Begin 2.7.x backward compatibility hack; #### eventually we need to issue a deprecation warning here, #### and then get rid of this stanza in a subsequent release. ################################################################ if (clazz.nil?) class_name = application_name.capitalize clazz = try_load_class(class_name) end ################################################################ #### End 2.7.x backward compatibility hack ################################################################ if clazz.nil? raise Puppet::Error.new("Unable to load application class '#{class_name}' from file 'puppet/application/#{application_name}.rb'") end return clazz end # Given the fully qualified name of a class, attempt to get the class instance. # @param [String] class_name the fully qualified name of the class to try to load # @return [Class] the Class instance, or nil? if it could not be loaded. def try_load_class(class_name) return self.const_defined?(class_name) ? const_get(class_name) : nil end private :try_load_class def [](name) find(name).new end # Sets or gets the run_mode name. Sets the run_mode name if a mode_name is # passed. Otherwise, gets the run_mode or a default run_mode # def run_mode( mode_name = nil) if mode_name Puppet.settings.preferred_run_mode = mode_name end return @run_mode if @run_mode and not mode_name require 'puppet/util/run_mode' @run_mode = Puppet::Util::RunMode[ mode_name || Puppet.settings.preferred_run_mode ] end # This is for testing only def clear_everything_for_tests @run_mode = @banner = @run_status = @option_parser_commands = nil end end attr_reader :options, :command_line # Every app responds to --version # See also `lib/puppet/util/command_line.rb` for some special case early # handling of this. option("--version", "-V") do |arg| puts "#{Puppet.version}" exit end # Every app responds to --help option("--help", "-h") do |v| puts help exit end def app_defaults() Puppet::Settings.app_defaults_for_run_mode(self.class.run_mode).merge( :name => name ) end def initialize_app_defaults() Puppet.settings.initialize_app_defaults(app_defaults) end # override to execute code before running anything else def preinit end def initialize(command_line = Puppet::Util::CommandLine.new) @command_line = CommandLineArgs.new(command_line.subcommand_name, command_line.args.dup) @options = {} end # Execute the application. # @api public # @return [void] def run # I don't really like the names of these lifecycle phases. It would be nice to change them to some more meaningful # names, and make deprecated aliases. Also, Daniel suggests that we can probably get rid of this "plugin_hook" # pattern, but we need to check with PE and the community first. --cprice 2012-03-16 # exit_on_fail("get application-specific default settings") do plugin_hook('initialize_app_defaults') { initialize_app_defaults } end Puppet.push_context(Puppet.base_context(Puppet.settings), "Update for application settings (#{self.class.run_mode})") # This use of configured environment is correct, this is used to establish # the defaults for an application that does not override, or where an override # has not been made from the command line. # configured_environment_name = Puppet[:environment] if self.class.run_mode.name != :agent configured_environment = Puppet.lookup(:environments).get(configured_environment_name) if configured_environment.nil? fail(Puppet::Environments::EnvironmentNotFound, configured_environment_name) end else configured_environment = Puppet::Node::Environment.remote(configured_environment_name) end configured_environment = configured_environment.override_from_commandline(Puppet.settings) # Setup a new context using the app's configuration Puppet.push_context({ :current_environment => configured_environment }, "Update current environment from application's configuration") - require 'puppet/util/instrumentation' - Puppet::Util::Instrumentation.init - exit_on_fail("initialize") { plugin_hook('preinit') { preinit } } exit_on_fail("parse application options") { plugin_hook('parse_options') { parse_options } } exit_on_fail("prepare for execution") { plugin_hook('setup') { setup } } exit_on_fail("configure routes from #{Puppet[:route_file]}") { configure_indirector_routes } exit_on_fail("log runtime debug info") { log_runtime_environment } exit_on_fail("run") { plugin_hook('run_command') { run_command } } end def main raise NotImplementedError, "No valid command or main" end def run_command main end def setup setup_logs end def setup_logs if options[:debug] || options[:verbose] Puppet::Util::Log.newdestination(:console) end set_log_level Puppet::Util::Log.setup_default unless options[:setdest] end def set_log_level if options[:debug] Puppet::Util::Log.level = :debug elsif options[:verbose] Puppet::Util::Log.level = :info end end def handle_logdest_arg(arg) begin Puppet::Util::Log.newdestination(arg) options[:setdest] = true rescue => detail Puppet.log_exception(detail) end end def configure_indirector_routes route_file = Puppet[:route_file] if Puppet::FileSystem.exist?(route_file) routes = YAML.load_file(route_file) application_routes = routes[name.to_s] Puppet::Indirector.configure_routes(application_routes) if application_routes end end # Output basic information about the runtime environment for debugging # purposes. # # @api public # # @param extra_info [Hash{String => #to_s}] a flat hash of extra information # to log. Intended to be passed to super by subclasses. # @return [void] def log_runtime_environment(extra_info=nil) runtime_info = { 'puppet_version' => Puppet.version, 'ruby_version' => RUBY_VERSION, 'run_mode' => self.class.run_mode.name, } runtime_info['default_encoding'] = Encoding.default_external if RUBY_VERSION >= '1.9.3' runtime_info.merge!(extra_info) unless extra_info.nil? Puppet.debug 'Runtime environment: ' + runtime_info.map{|k,v| k + '=' + v.to_s}.join(', ') end def parse_options # Create an option parser option_parser = OptionParser.new(self.class.banner) # Here we're building up all of the options that the application may need to handle. The main # puppet settings defined in "defaults.rb" have already been parsed once (in command_line.rb) by # the time we get here; however, our app may wish to handle some of them specially, so we need to # make the parser aware of them again. We might be able to make this a bit more efficient by # re-using the parser object that gets built up in command_line.rb. --cprice 2012-03-16 # Add all global options to it. Puppet.settings.optparse_addargs([]).each do |option| option_parser.on(*option) do |arg| handlearg(option[0], arg) end end # Add options that are local to this application, which were # created using the "option()" metaprogramming method. If there # are any conflicts, this application's options will be favored. self.class.option_parser_commands.each do |options, fname| option_parser.on(*options) do |value| # Call the method that "option()" created. self.send(fname, value) end end # Scan command line. We just hand any exceptions to our upper levels, # rather than printing help and exiting, so that we can meaningfully # respond with context-sensitive help if we want to. --daniel 2011-04-12 option_parser.parse!(self.command_line.args) end def handlearg(opt, val) opt, val = Puppet::Settings.clean_opt(opt, val) send(:handle_unknown, opt, val) if respond_to?(:handle_unknown) end # this is used for testing def self.exit(code) exit(code) end def name self.class.to_s.sub(/.*::/,"").downcase.to_sym end def help "No help available for puppet #{name}" end def plugin_hook(step,&block) Puppet::Plugins.send("before_application_#{step}",:application_object => self) x = yield Puppet::Plugins.send("after_application_#{step}",:application_object => self, :return_value => x) x end private :plugin_hook end end diff --git a/lib/puppet/application/instrumentation_data.rb b/lib/puppet/application/instrumentation_data.rb deleted file mode 100644 index ab431c3e5..000000000 --- a/lib/puppet/application/instrumentation_data.rb +++ /dev/null @@ -1,7 +0,0 @@ -require 'puppet/application/indirection_base' - -# NOTE: this is using an "old" naming convention (underscores instead of camel-case), for backwards -# compatibility with 2.7.x. When the old naming convention is officially and publicly deprecated, -# this should be changed to camel-case. -class Puppet::Application::Instrumentation_data < Puppet::Application::IndirectionBase -end diff --git a/lib/puppet/application/instrumentation_listener.rb b/lib/puppet/application/instrumentation_listener.rb deleted file mode 100644 index 10e289374..000000000 --- a/lib/puppet/application/instrumentation_listener.rb +++ /dev/null @@ -1,7 +0,0 @@ -require 'puppet/application/indirection_base' - -# NOTE: this is using an "old" naming convention (underscores instead of camel-case), for backwards -# compatibility with 2.7.x. When the old naming convention is officially and publicly deprecated, -# this should be changed to camel-case. -class Puppet::Application::Instrumentation_listener < Puppet::Application::IndirectionBase -end diff --git a/lib/puppet/application/instrumentation_probe.rb b/lib/puppet/application/instrumentation_probe.rb deleted file mode 100644 index d6d364438..000000000 --- a/lib/puppet/application/instrumentation_probe.rb +++ /dev/null @@ -1,7 +0,0 @@ -require 'puppet/application/indirection_base' - -# NOTE: this is using an "old" naming convention (underscores instead of camel-case), for backwards -# compatibility with 2.7.x. When the old naming convention is officially and publicly deprecated, -# this should be changed to camel-case. -class Puppet::Application::Instrumentation_probe < Puppet::Application::IndirectionBase -end diff --git a/lib/puppet/face/instrumentation_data.rb b/lib/puppet/face/instrumentation_data.rb deleted file mode 100644 index 05eb4fdb6..000000000 --- a/lib/puppet/face/instrumentation_data.rb +++ /dev/null @@ -1,30 +0,0 @@ -require 'puppet/indirector/face' -require 'puppet/util/instrumentation/data' - -Puppet::Indirector::Face.define(:instrumentation_data, '0.0.1') do - copyright "Puppet Labs", 2011 - license "Apache 2 license; see COPYING" - - summary "Manage instrumentation listener accumulated data. DEPRECATED." - description <<-EOT - This subcommand allows to retrieve the various listener data. - (DEPRECATED) This subcommand will be removed in Puppet 4.0. - EOT - - get_action(:destroy).summary "Invalid for this subcommand." - get_action(:save).summary "Invalid for this subcommand." - get_action(:search).summary "Invalid for this subcommand." - - find = get_action(:find) - find.summary "Retrieve listener data." - find.render_as = :pson - find.returns <<-EOT - The data of an instrumentation listener - EOT - find.examples <<-EOT - Retrieve listener data: - - $ puppet instrumentation_data find performance --terminus rest - EOT - -end diff --git a/lib/puppet/face/instrumentation_listener.rb b/lib/puppet/face/instrumentation_listener.rb deleted file mode 100644 index e11ef407f..000000000 --- a/lib/puppet/face/instrumentation_listener.rb +++ /dev/null @@ -1,98 +0,0 @@ -require 'puppet/indirector/face' -require 'puppet/util/instrumentation/listener' - -Puppet::Indirector::Face.define(:instrumentation_listener, '0.0.1') do - copyright "Puppet Labs", 2011 - license "Apache 2 license; see COPYING" - - summary "Manage instrumentation listeners. DEPRECATED." - description <<-EOT - This subcommand enables/disables or list instrumentation listeners. - (DEPRECATED) This subcommand will be removed in Puppet 4.0. - EOT - - get_action(:destroy).summary "Invalid for this subcommand." - - find = get_action(:find) - find.summary "Retrieve a single listener." - find.render_as = :pson - find.returns <<-EOT - The status of an instrumentation listener - EOT - find.examples <<-EOT - Retrieve a given listener: - - $ puppet instrumentation_listener find performance --terminus rest - EOT - - search = get_action(:search) - search.summary "Retrieve all instrumentation listeners statuses." - search.arguments "" - search.render_as = :pson - search.returns <<-EOT - The statuses of all instrumentation listeners - EOT - search.short_description <<-EOT - This retrieves all instrumentation listeners - EOT - search.notes <<-EOT - Although this action always returns all instrumentation listeners, it requires a dummy search - key; this is a known bug. - EOT - search.examples <<-EOT - Retrieve the state of the listeners running in the remote puppet master: - - $ puppet instrumentation_listener search x --terminus rest - EOT - - def manage(name, activate) - Puppet::Util::Instrumentation::Listener.indirection.terminus_class = :rest - listener = Puppet::Face[:instrumentation_listener, '0.0.1'].find(name) - if listener - listener.enabled = activate - Puppet::Face[:instrumentation_listener, '0.0.1'].save(listener) - end - end - - action :enable do - summary "Enable a given instrumentation listener." - arguments "" - returns "Nothing." - description <<-EOT - Enable a given instrumentation listener. After being enabled the listener - will start receiving instrumentation notifications from the probes if those - are enabled. - EOT - examples <<-EOT - Enable the "performance" listener in the running master: - - $ puppet instrumentation_listener enable performance --terminus rest - EOT - - when_invoked do |name, options| - manage(name, true) - end - end - - action :disable do - summary "Disable a given instrumentation listener." - arguments "" - returns "Nothing." - description <<-EOT - Disable a given instrumentation listener. After being disabled the listener - will stop receiving instrumentation notifications from the probes. - EOT - examples <<-EOT - Disable the "performance" listener in the running master: - - $ puppet instrumentation_listener disable performance --terminus rest - EOT - - when_invoked do |name, options| - manage(name, false) - end - end - - get_action(:save).summary "API only: modify an instrumentation listener status." - get_action(:save).arguments "" -end diff --git a/lib/puppet/face/instrumentation_probe.rb b/lib/puppet/face/instrumentation_probe.rb deleted file mode 100644 index b77f5e977..000000000 --- a/lib/puppet/face/instrumentation_probe.rb +++ /dev/null @@ -1,79 +0,0 @@ -require 'puppet/indirector/face' -require 'puppet/util/instrumentation/indirection_probe' - -Puppet::Indirector::Face.define(:instrumentation_probe, '0.0.1') do - copyright "Puppet Labs", 2011 - license "Apache 2 license; see COPYING" - - summary "Manage instrumentation probes. Deprecated" - description <<-EOT - This subcommand enables/disables or list instrumentation listeners. - (DEPRECATED) This subcommand will be removed in Puppet 4.0. - EOT - - get_action(:find).summary "Invalid for this subcommand." - - search = get_action(:search) - search.summary "Retrieve all probe statuses." - search.arguments "" - search.render_as = :pson - search.returns <<-EOT - The statuses of all instrumentation probes - EOT - search.short_description <<-EOT - This retrieves all instrumentation probes - EOT - search.notes <<-EOT - Although this action always returns all instrumentation probes, it requires a dummy search - key; this is a known bug. - EOT - search.examples <<-EOT - Retrieve the state of the probes running in the remote puppet master: - - $ puppet instrumentation_probe search x --terminus rest - EOT - - action :enable do - summary "Enable all instrumentation probes." - arguments "" - returns "Nothing." - description <<-EOT - Enable all instrumentation probes. After being enabled, all enabled listeners - will start receiving instrumentation notifications from the probes. - EOT - examples <<-EOT - Enable the probes for the running master: - - $ puppet instrumentation_probe enable x --terminus rest - EOT - - when_invoked do |name, options| - Puppet::Face[:instrumentation_probe, '0.0.1'].save(nil) - end - end - - action :disable do - summary "Disable all instrumentation probes." - arguments "" - returns "Nothing." - description <<-EOT - Disable all instrumentation probes. After being disabled, no listeners - will receive instrumentation notifications. - EOT - examples <<-EOT - Disable the probes for the running master: - - $ puppet instrumentation_probe disable x --terminus rest - EOT - - when_invoked do |name, options| - Puppet::Face[:instrumentation_probe, '0.0.1'].destroy(nil) - end - end - - get_action(:save).summary "API only: enable all instrumentation probes." - get_action(:save).arguments "" - - get_action(:destroy).summary "API only: disable all instrumentation probes." - get_action(:destroy).arguments "" -end diff --git a/lib/puppet/indirector/indirection.rb b/lib/puppet/indirector/indirection.rb index 26a33543c..102b34bd7 100644 --- a/lib/puppet/indirector/indirection.rb +++ b/lib/puppet/indirector/indirection.rb @@ -1,336 +1,329 @@ require 'puppet/util/docs' require 'puppet/util/profiler' require 'puppet/util/methodhelper' require 'puppet/indirector/envelope' require 'puppet/indirector/request' -require 'puppet/util/instrumentation/instrumentable' # The class that connects functional classes with their different collection # back-ends. Each indirection has a set of associated terminus classes, # each of which is a subclass of Puppet::Indirector::Terminus. class Puppet::Indirector::Indirection include Puppet::Util::MethodHelper include Puppet::Util::Docs - extend Puppet::Util::Instrumentation::Instrumentable attr_accessor :name, :model attr_reader :termini - probe :find, :label => Proc.new { |parent, key, *args| "find_#{parent.name}_#{parent.terminus_class}" }, :data => Proc.new { |parent, key, *args| { :key => key }} - probe :save, :label => Proc.new { |parent, key, *args| "save_#{parent.name}_#{parent.terminus_class}" }, :data => Proc.new { |parent, key, *args| { :key => key }} - probe :search, :label => Proc.new { |parent, key, *args| "search_#{parent.name}_#{parent.terminus_class}" }, :data => Proc.new { |parent, key, *args| { :key => key }} - probe :destroy, :label => Proc.new { |parent, key, *args| "destroy_#{parent.name}_#{parent.terminus_class}" }, :data => Proc.new { |parent, key, *args| { :key => key }} - @@indirections = [] # Find an indirection by name. This is provided so that Terminus classes # can specifically hook up with the indirections they are associated with. def self.instance(name) @@indirections.find { |i| i.name == name } end # Return a list of all known indirections. Used to generate the # reference. def self.instances @@indirections.collect { |i| i.name } end # Find an indirected model by name. This is provided so that Terminus classes # can specifically hook up with the indirections they are associated with. def self.model(name) return nil unless match = @@indirections.find { |i| i.name == name } match.model end # Create and return our cache terminus. def cache raise(Puppet::DevError, "Tried to cache when no cache class was set") unless cache_class terminus(cache_class) end # Should we use a cache? def cache? cache_class ? true : false end attr_reader :cache_class # Define a terminus class to be used for caching. def cache_class=(class_name) validate_terminus_class(class_name) if class_name @cache_class = class_name end # This is only used for testing. def delete @@indirections.delete(self) if @@indirections.include?(self) end # Set the time-to-live for instances created through this indirection. def ttl=(value) raise ArgumentError, "Indirection TTL must be an integer" unless value.is_a?(Fixnum) @ttl = value end # Default to the runinterval for the ttl. def ttl @ttl ||= Puppet[:runinterval] end # Calculate the expiration date for a returned instance. def expiration Time.now + ttl end # Generate the full doc string. def doc text = "" text << scrub(@doc) << "\n\n" if @doc text << "* **Indirected Class**: `#{@indirected_class}`\n"; if terminus_setting text << "* **Terminus Setting**: #{terminus_setting}\n" end text end def initialize(model, name, options = {}) @model = model @name = name @termini = {} @cache_class = nil @terminus_class = nil raise(ArgumentError, "Indirection #{@name} is already defined") if @@indirections.find { |i| i.name == @name } @@indirections << self @indirected_class = options.delete(:indirected_class) if mod = options[:extend] extend(mod) options.delete(:extend) end # This is currently only used for cache_class and terminus_class. set_options(options) end # Set up our request object. def request(*args) Puppet::Indirector::Request.new(self.name, *args) end # Return the singleton terminus for this indirection. def terminus(terminus_name = nil) # Get the name of the terminus. raise Puppet::DevError, "No terminus specified for #{self.name}; cannot redirect" unless terminus_name ||= terminus_class termini[terminus_name] ||= make_terminus(terminus_name) end # This can be used to select the terminus class. attr_accessor :terminus_setting # Determine the terminus class. def terminus_class unless @terminus_class if setting = self.terminus_setting self.terminus_class = Puppet.settings[setting] else raise Puppet::DevError, "No terminus class nor terminus setting was provided for indirection #{self.name}" end end @terminus_class end def reset_terminus_class @terminus_class = nil end # Specify the terminus class to use. def terminus_class=(klass) validate_terminus_class(klass) @terminus_class = klass end # This is used by terminus_class= and cache=. def validate_terminus_class(terminus_class) raise ArgumentError, "Invalid terminus name #{terminus_class.inspect}" unless terminus_class and terminus_class.to_s != "" unless Puppet::Indirector::Terminus.terminus_class(self.name, terminus_class) raise ArgumentError, "Could not find terminus #{terminus_class} for indirection #{self.name}" end end # Expire a cached object, if one is cached. Note that we don't actually # remove it, we expire it and write it back out to disk. This way people # can still use the expired object if they want. def expire(key, options={}) request = request(:expire, key, nil, options) return nil unless cache? return nil unless instance = cache.find(request(:find, key, nil, options)) Puppet.info "Expiring the #{self.name} cache of #{instance.name}" # Set an expiration date in the past instance.expiration = Time.now - 60 cache.save(request(:save, nil, instance, options)) end def allow_remote_requests? terminus.allow_remote_requests? end # Search for an instance in the appropriate terminus, caching the # results if caching is configured.. def find(key, options={}) request = request(:find, key, nil, options) terminus = prepare(request) result = find_in_cache(request) if not result.nil? result elsif request.ignore_terminus? nil else # Otherwise, return the result from the terminus, caching if # appropriate. result = terminus.find(request) if not result.nil? result.expiration ||= self.expiration if result.respond_to?(:expiration) if cache? Puppet.info "Caching #{self.name} for #{request.key}" cache.save request(:save, key, result, options) end filtered = result if terminus.respond_to?(:filter) Puppet::Util::Profiler.profile("Filtered result for #{self.name} #{request.key}", [:indirector, :filter, self.name, request.key]) do filtered = terminus.filter(result) end end filtered end end end # Search for an instance in the appropriate terminus, and return a # boolean indicating whether the instance was found. def head(key, options={}) request = request(:head, key, nil, options) terminus = prepare(request) # Look in the cache first, then in the terminus. Force the result # to be a boolean. !!(find_in_cache(request) || terminus.head(request)) end def find_in_cache(request) # See if our instance is in the cache and up to date. return nil unless cache? and ! request.ignore_cache? and cached = cache.find(request) if cached.expired? Puppet.info "Not using expired #{self.name} for #{request.key} from cache; expired at #{cached.expiration}" return nil end Puppet.debug "Using cached #{self.name} for #{request.key}" cached rescue => detail Puppet.log_exception(detail, "Cached #{self.name} for #{request.key} failed: #{detail}") nil end # Remove something via the terminus. def destroy(key, options={}) request = request(:destroy, key, nil, options) terminus = prepare(request) result = terminus.destroy(request) if cache? and cache.find(request(:find, key, nil, options)) # Reuse the existing request, since it's equivalent. cache.destroy(request) end result end # Search for more than one instance. Should always return an array. def search(key, options={}) request = request(:search, key, nil, options) terminus = prepare(request) if result = terminus.search(request) raise Puppet::DevError, "Search results from terminus #{terminus.name} are not an array" unless result.is_a?(Array) result.each do |instance| next unless instance.respond_to? :expiration instance.expiration ||= self.expiration end return result end end # Save the instance in the appropriate terminus. This method is # normally an instance method on the indirected class. def save(instance, key = nil, options={}) request = request(:save, key, instance, options) terminus = prepare(request) result = terminus.save(request) # If caching is enabled, save our document there cache.save(request) if cache? result end private # Check authorization if there's a hook available; fail if there is one # and it returns false. def check_authorization(request, terminus) # At this point, we're assuming authorization makes no sense without # client information. return unless request.node # This is only to authorize via a terminus-specific authorization hook. return unless terminus.respond_to?(:authorized?) unless terminus.authorized?(request) msg = "Not authorized to call #{request.method} on #{request}" msg += " with #{request.options.inspect}" unless request.options.empty? raise ArgumentError, msg end end # Setup a request, pick the appropriate terminus, check the request's authorization, and return it. def prepare(request) # Pick our terminus. if respond_to?(:select_terminus) unless terminus_name = select_terminus(request) raise ArgumentError, "Could not determine appropriate terminus for #{request}" end else terminus_name = terminus_class end dest_terminus = terminus(terminus_name) check_authorization(request, dest_terminus) dest_terminus.validate(request) dest_terminus end # Create a new terminus instance. def make_terminus(terminus_class) # Load our terminus class. unless klass = Puppet::Indirector::Terminus.terminus_class(self.name, terminus_class) raise ArgumentError, "Could not find terminus #{terminus_class} for indirection #{self.name}" end klass.new end end diff --git a/lib/puppet/indirector/instrumentation_data.rb b/lib/puppet/indirector/instrumentation_data.rb deleted file mode 100644 index f1bea330d..000000000 --- a/lib/puppet/indirector/instrumentation_data.rb +++ /dev/null @@ -1,3 +0,0 @@ -# A stub class, so our constants work. -class Puppet::Indirector::InstrumentationData -end diff --git a/lib/puppet/indirector/instrumentation_data/local.rb b/lib/puppet/indirector/instrumentation_data/local.rb deleted file mode 100644 index 7504a7d57..000000000 --- a/lib/puppet/indirector/instrumentation_data/local.rb +++ /dev/null @@ -1,22 +0,0 @@ -require 'puppet/indirector/instrumentation_data' - -class Puppet::Indirector::InstrumentationData::Local < Puppet::Indirector::Code - - desc "Undocumented." - - def find(request) - model.new(request.key) - end - - def search(request) - raise Puppet::DevError, "You cannot search for instrumentation data" - end - - def save(request) - raise Puppet::DevError, "You cannot save instrumentation data" - end - - def destroy(request) - raise Puppet::DevError, "You cannot remove instrumentation data" - end -end diff --git a/lib/puppet/indirector/instrumentation_data/rest.rb b/lib/puppet/indirector/instrumentation_data/rest.rb deleted file mode 100644 index f926d7ddf..000000000 --- a/lib/puppet/indirector/instrumentation_data/rest.rb +++ /dev/null @@ -1,8 +0,0 @@ -require 'puppet/indirector/rest' -require 'puppet/indirector/instrumentation_data' - -class Puppet::Indirector::InstrumentationData::Rest < Puppet::Indirector::REST - - desc "Undocumented." - -end diff --git a/lib/puppet/indirector/instrumentation_listener.rb b/lib/puppet/indirector/instrumentation_listener.rb deleted file mode 100644 index 6aaa71ce6..000000000 --- a/lib/puppet/indirector/instrumentation_listener.rb +++ /dev/null @@ -1,3 +0,0 @@ -# A stub class, so our constants work. -class Puppet::Indirector::InstrumentationListener -end diff --git a/lib/puppet/indirector/instrumentation_listener/local.rb b/lib/puppet/indirector/instrumentation_listener/local.rb deleted file mode 100644 index 947d62717..000000000 --- a/lib/puppet/indirector/instrumentation_listener/local.rb +++ /dev/null @@ -1,26 +0,0 @@ -require 'puppet/indirector/instrumentation_listener' - -class Puppet::Indirector::InstrumentationListener::Local < Puppet::Indirector::Code - - desc "Undocumented." - - def find(request) - Puppet::Util::Instrumentation[request.key] - end - - def search(request) - Puppet::Util::Instrumentation.listeners - end - - def save(request) - res = request.instance - Puppet::Util::Instrumentation[res.name] = res - nil # don't leak the listener - end - - def destroy(request) - listener = Puppet::Util::Instrumentation[request.key] - raise "Listener #{request.key} hasn't been subscribed" unless listener - Puppet::Util::Instrumentation.unsubscribe(listener) - end -end diff --git a/lib/puppet/indirector/instrumentation_listener/rest.rb b/lib/puppet/indirector/instrumentation_listener/rest.rb deleted file mode 100644 index c99ec9803..000000000 --- a/lib/puppet/indirector/instrumentation_listener/rest.rb +++ /dev/null @@ -1,8 +0,0 @@ -require 'puppet/indirector/instrumentation_listener' -require 'puppet/indirector/rest' - -class Puppet::Indirector::InstrumentationListener::Rest < Puppet::Indirector::REST - - desc "Undocumented." - -end diff --git a/lib/puppet/indirector/instrumentation_probe.rb b/lib/puppet/indirector/instrumentation_probe.rb deleted file mode 100644 index 3e514447a..000000000 --- a/lib/puppet/indirector/instrumentation_probe.rb +++ /dev/null @@ -1,3 +0,0 @@ -# A stub class, so our constants work. -class Puppet::Indirector::InstrumentationProbe -end diff --git a/lib/puppet/indirector/instrumentation_probe/local.rb b/lib/puppet/indirector/instrumentation_probe/local.rb deleted file mode 100644 index 8f6711555..000000000 --- a/lib/puppet/indirector/instrumentation_probe/local.rb +++ /dev/null @@ -1,27 +0,0 @@ -require 'puppet/indirector/instrumentation_probe' -require 'puppet/indirector/code' -require 'puppet/util/instrumentation/indirection_probe' - -class Puppet::Indirector::InstrumentationProbe::Local < Puppet::Indirector::Code - - desc "Undocumented." - - def find(request) - end - - def search(request) - probes = [] - Puppet::Util::Instrumentation::Instrumentable.each_probe do |probe| - probes << Puppet::Util::Instrumentation::IndirectionProbe.new("#{probe.klass}.#{probe.method}") - end - probes - end - - def save(request) - Puppet::Util::Instrumentation::Instrumentable.enable_probes - end - - def destroy(request) - Puppet::Util::Instrumentation::Instrumentable.disable_probes - end -end diff --git a/lib/puppet/indirector/instrumentation_probe/rest.rb b/lib/puppet/indirector/instrumentation_probe/rest.rb deleted file mode 100644 index ba5d5e437..000000000 --- a/lib/puppet/indirector/instrumentation_probe/rest.rb +++ /dev/null @@ -1,8 +0,0 @@ -require 'puppet/indirector/rest' -require 'puppet/indirector/instrumentation_probe' - -class Puppet::Indirector::InstrumentationProbe::Rest < Puppet::Indirector::REST - - desc "Undocumented." - -end diff --git a/lib/puppet/util/instrumentation.rb b/lib/puppet/util/instrumentation.rb deleted file mode 100644 index 94a75ac03..000000000 --- a/lib/puppet/util/instrumentation.rb +++ /dev/null @@ -1,152 +0,0 @@ -require 'puppet' -require 'puppet/util/classgen' -require 'puppet/util/instance_loader' - -class Puppet::Util::Instrumentation - extend Puppet::Util::ClassGen - extend Puppet::Util::InstanceLoader - - # we're using a ruby lazy autoloader to prevent a loop when requiring listeners - # since this class sets up an indirection which is also used in Puppet::Indirector::Indirection - # which is used to setup indirections... - autoload :Listener, 'puppet/util/instrumentation/listener' - autoload :Data, 'puppet/util/instrumentation/data' - - # Set up autoloading and retrieving of instrumentation listeners. - instance_load :listener, 'puppet/util/instrumentation/listeners' - - class << self - attr_accessor :listeners, :listeners_of - end - - # instrumentation layer - - # Triggers an instrumentation - # - # Call this method around the instrumentation point - # Puppet::Util::Instrumentation.instrument(:my_long_computation) do - # ... a long computation - # end - # - # This will send an event to all the listeners of "my_long_computation". - # Note: this method uses ruby yield directive to call the instrumented code. - # It is usually way slower than calling start and stop directly around the instrumented code. - # For high traffic code path, it is thus advisable to not use this method. - def self.instrument(label, data = {}) - id = self.start(label, data) - yield - ensure - self.stop(label, id, data) - end - - # Triggers a "start" instrumentation event - # - # Important note: - # For proper use, the data hash instance used for start should also - # be used when calling stop. The idea is to use the current scope - # where start is called to retain a reference to 'data' so that it is possible - # to send it back to stop. - # This way listeners can match start and stop events more easily. - def self.start(label, data) - data[:started] = Time.now - publish(label, :start, data) - data[:id] = next_id - end - - # Triggers a "stop" instrumentation event - def self.stop(label, id, data) - data[:finished] = Time.now - publish(label, :stop, data) - end - - def self.publish(label, event, data) - each_listener(label) do |k,l| - l.notify(label, event, data) - end - end - - def self.listeners - @listeners.values - end - - def self.each_listener(label) - @listeners_of[label] ||= @listeners.select do |k,l| - l.listen_to?(label) - end.each do |l| - yield l - end - end - - # Adds a new listener - # - # Usage: - # Puppet::Util::Instrumentation.new_listener(:my_instrumentation, pattern) do - # - # def notify(label, data) - # ... do something for data... - # end - # end - # - # It is possible to use a "pattern". The listener will be notified only - # if the pattern match the label of the event. - # The pattern can be a symbol, a string or a regex. - # If no pattern is provided, then the listener will be called for every events - def self.new_listener(name, options = {}, &block) - Puppet.debug "new listener called #{name}" - name = name.intern - listener = genclass(name, :hash => instance_hash(:listener), :block => block) - listener.send(:define_method, :name) do - name - end - subscribe(listener.new, options[:label_pattern], options[:event]) - end - - def self.subscribe(listener, label_pattern, event) - raise "Listener #{listener.name} is already subscribed" if @listeners.include?(listener.name) - Puppet.debug "registering instrumentation listener #{listener.name}" - @listeners[listener.name] = Listener.new(listener, label_pattern, event) - listener.subscribed if listener.respond_to?(:subscribed) - rehash - end - - def self.unsubscribe(listener) - Puppet.warning("#{listener.name} hasn't been registered but asked to be unregistered") unless @listeners.include?(listener.name) - Puppet.info "unregistering instrumentation listener #{listener.name}" - @listeners.delete(listener.name) - listener.unsubscribed if listener.respond_to?(:unsubscribed) - rehash - end - - def self.init - # let's init our probe indirection - require 'puppet/util/instrumentation/indirection_probe' - @listeners ||= {} - @listeners_of ||= {} - instance_loader(:listener).loadall - end - - def self.clear - @listeners = {} - @listeners_of = {} - @id = 0 - end - - def self.[](key) - @listeners[key.intern] - end - - def self.[]=(key, value) - @listeners[key.intern] = value - rehash - end - - private - - def self.rehash - @listeners_of = {} - end - - def self.next_id - @id = (@id || 0) + 1 - end -end diff --git a/lib/puppet/util/instrumentation/data.rb b/lib/puppet/util/instrumentation/data.rb deleted file mode 100644 index 34d978cec..000000000 --- a/lib/puppet/util/instrumentation/data.rb +++ /dev/null @@ -1,46 +0,0 @@ -require 'puppet/indirector' -require 'puppet/util/instrumentation' - -# This is just a transport class to be used through the instrumentation_data -# indirection. All the data resides in the real underlying listeners which this -# class delegates to. -class Puppet::Util::Instrumentation::Data - extend Puppet::Indirector - - indirects :instrumentation_data, :terminus_class => :local - - attr_reader :listener - - def initialize(listener_name) - @listener = Puppet::Util::Instrumentation[listener_name] - raise "Listener #{listener_name} wasn't registered" unless @listener - end - - def name - @listener.name - end - - def to_data_hash - { :name => name }.merge(@listener.respond_to?(:data) ? @listener.data : {}) - end - - def to_pson_data_hash - { - 'document_type' => "Puppet::Util::Instrumentation::Data", - 'data' => to_data_hash, - } - end - - def to_pson(*args) - to_pson_data_hash.to_pson(*args) - end - - def self.from_data_hash(data) - data - end - - def self.from_pson(data) - Puppet.deprecation_warning("from_pson is being removed in favour of from_data_hash.") - data - end -end diff --git a/lib/puppet/util/instrumentation/indirection_probe.rb b/lib/puppet/util/instrumentation/indirection_probe.rb deleted file mode 100644 index afaccd303..000000000 --- a/lib/puppet/util/instrumentation/indirection_probe.rb +++ /dev/null @@ -1,41 +0,0 @@ -require 'puppet/indirector' -require 'puppet/util/instrumentation' - -# We need to use a class other than Probe for the indirector because -# the Indirection class might declare some probes, and this would be a huge unbreakable -# dependency cycle. -class Puppet::Util::Instrumentation::IndirectionProbe - extend Puppet::Indirector - - indirects :instrumentation_probe, :terminus_class => :local - - attr_reader :probe_name - - def initialize(probe_name) - @probe_name = probe_name - end - - def to_data_hash - { :name => probe_name } - end - - def to_pson_data_hash - { - :document_type => "Puppet::Util::Instrumentation::IndirectionProbe", - :data => to_data_hash, - } - end - - def to_pson(*args) - to_pson_data_hash.to_pson(*args) - end - - def self.from_data_hash(data) - self.new(data["name"]) - end - - def self.from_pson(data) - Puppet.deprecation_warning("from_pson is being removed in favour of from_data_hash.") - self.from_data_hash(data) - end -end diff --git a/lib/puppet/util/instrumentation/instrumentable.rb b/lib/puppet/util/instrumentation/instrumentable.rb deleted file mode 100644 index 01c75ff77..000000000 --- a/lib/puppet/util/instrumentation/instrumentable.rb +++ /dev/null @@ -1,136 +0,0 @@ -require 'puppet/util/instrumentation' - -# This is the central point of all declared probes. -# Every class needed to declare probes should include this module -# and declare the methods that are subject to instrumentation: -# -# class MyClass -# extend Puppet::Util::Instrumentation::Instrumentable -# -# probe :mymethod -# -# def mymethod -# ... this is code to be instrumented ... -# end -# end -module Puppet::Util::Instrumentation::Instrumentable - INSTRUMENTED_CLASSES = {} - - attr_reader :probes - - class Probe - attr_reader :klass, :method, :label, :data - - def initialize(method, klass, options = {}) - @method = method - @klass = klass - - @label = options[:label] || method - @data = options[:data] || {} - end - - def enable - raise "Probe already enabled" if enabled? - - # We're forced to perform this copy because in the class_eval'uated - # block below @method would be evaluated in the class context. It's better - # to close on locally-scoped variables than to resort to complex namespacing - # to get access to the probe instance variables. - method = @method; label = @label; data = @data - klass.class_eval { - alias_method("instrumented_#{method}", method) - define_method(method) do |*args| - id = nil - instrumentation_data = nil - begin - instrumentation_label = label.respond_to?(:call) ? label.call(self, args) : label - instrumentation_data = data.respond_to?(:call) ? data.call(self, args) : data - id = Puppet::Util::Instrumentation.start(instrumentation_label, instrumentation_data) - send("instrumented_#{method}".to_sym, *args) - ensure - Puppet::Util::Instrumentation.stop(instrumentation_label, id, instrumentation_data || {}) - end - end - } - @enabled = true - end - - def disable - raise "Probe is not enabled" unless enabled? - - # For the same reason as in #enable, we're forced to do a local - # copy - method = @method - klass.class_eval do - alias_method(method, "instrumented_#{method}") - remove_method("instrumented_#{method}".to_sym) - end - @enabled = false - end - - def enabled? - !!@enabled - end - end - - # Declares a new probe - # - # It is possible to pass several options that will be later on evaluated - # and sent to the instrumentation layer. - # - # label:: - # this can either be a static symbol/string or a block. If it's a block - # this one will be evaluated on every call of the instrumented method and - # should return a string or a symbol - # - # data:: - # this can be a hash or a block. If it's a block this one will be evaluated - # on every call of the instrumented method and should return a hash. - # - #Example: - # - # class MyClass - # extend Instrumentable - # - # probe :mymethod, :data => Proc.new { |args| { :data => args[1] } }, :label => Proc.new { |args| args[0] } - # - # def mymethod(name, options) - # end - # - # end - # - def probe(method, options = {}) - (@probes ||= []) << Probe.new(method, self, options) - INSTRUMENTED_CLASSES[self] = @probes - end - - def self.probes - @probes - end - - def self.probe_names - probe_names = [] - each_probe { |probe| probe_names << "#{probe.klass}.#{probe.method}" } - probe_names - end - - def self.enable_probes - each_probe { |probe| probe.enable } - end - - def self.disable_probes - each_probe { |probe| probe.disable } - end - - def self.clear_probes - INSTRUMENTED_CLASSES.clear - nil # do not leak our probes to the exterior world - end - - def self.each_probe - INSTRUMENTED_CLASSES.each_key do |klass| - klass.probes.each { |probe| yield probe } - end - nil # do not leak our probes to the exterior world - end -end diff --git a/lib/puppet/util/instrumentation/listener.rb b/lib/puppet/util/instrumentation/listener.rb deleted file mode 100644 index cb25b2925..000000000 --- a/lib/puppet/util/instrumentation/listener.rb +++ /dev/null @@ -1,72 +0,0 @@ -require 'puppet/indirector' -require 'puppet/util/instrumentation' -require 'puppet/util/instrumentation/data' - -class Puppet::Util::Instrumentation::Listener - include Puppet::Util - include Puppet::Util::Warnings - extend Puppet::Indirector - - indirects :instrumentation_listener, :terminus_class => :local - - attr_reader :pattern, :listener - attr_accessor :enabled - - def initialize(listener, pattern = nil, enabled = false) - @pattern = pattern.is_a?(Symbol) ? pattern.to_s : pattern - raise "Listener isn't a correct listener (it doesn't provide the notify method)" unless listener.respond_to?(:notify) - @listener = listener - @enabled = enabled - end - - def notify(label, event, data) - listener.notify(label, event, data) - rescue => e - warnonce("Error during instrumentation notification: #{e}") - end - - def listen_to?(label) - enabled? and (!@pattern || @pattern === label.to_s) - end - - def enabled? - !!@enabled - end - - def name - @listener.name.to_s - end - - def data - { :data => @listener.data } - end - - def to_data_hash - { - :name => name, - :pattern => pattern, - :enabled => enabled? - } - end - - def to_pson_data_hash - { - :document_type => "Puppet::Util::Instrumentation::Listener", - :data => to_data_hash, - } - end - - def to_pson(*args) - to_pson_data_hash.to_pson(*args) - end - - def self.from_data_hash(data) - result = Puppet::Util::Instrumentation[data["name"]] - self.new(result.listener, result.pattern, data["enabled"]) - end - - def self.from_pson(data) - Puppet.deprecation_warning("from_pson is being removed in favour of from_data_hash.") - self.from_data_hash(data) - end -end diff --git a/lib/puppet/util/instrumentation/listeners/log.rb b/lib/puppet/util/instrumentation/listeners/log.rb deleted file mode 100644 index 72797d628..000000000 --- a/lib/puppet/util/instrumentation/listeners/log.rb +++ /dev/null @@ -1,23 +0,0 @@ -# This is an example instrumentation listener that stores the last -# 20 instrumented probe run time. -Puppet::Util::Instrumentation.new_listener(:log) do - - SIZE = 20 - - attr_accessor :last_logs - - def initialize - @last_logs = {} - end - - def notify(label, event, data) - return if event == :start - log_line = "#{label} took #{data[:finished] - data[:started]}" - (@last_logs[label] ||= []) << log_line - @last_logs[label].shift if @last_logs[label].length > SIZE - end - - def data - @last_logs.dup - end -end diff --git a/lib/puppet/util/instrumentation/listeners/performance.rb b/lib/puppet/util/instrumentation/listeners/performance.rb deleted file mode 100644 index 5bf3e2c5b..000000000 --- a/lib/puppet/util/instrumentation/listeners/performance.rb +++ /dev/null @@ -1,24 +0,0 @@ -Puppet::Util::Instrumentation.new_listener(:performance) do - - attr_reader :samples - - def initialize - @samples = {} - end - - def notify(label, event, data) - return if event == :start - - duration = data[:finished] - data[:started] - @samples[label] ||= { :count => 0, :max => 0, :min => nil, :sum => 0, :average => 0 } - @samples[label][:count] += 1 - @samples[label][:sum] += duration - @samples[label][:max] = [ @samples[label][:max], duration ].max - @samples[label][:min] = [ @samples[label][:min], duration ].reject { |val| val.nil? }.min - @samples[label][:average] = @samples[label][:sum] / @samples[label][:count] - end - - def data - @samples.dup - end -end diff --git a/man/man8/puppet-instrumentation_data.8 b/man/man8/puppet-instrumentation_data.8 deleted file mode 100644 index 2110dbca5..000000000 --- a/man/man8/puppet-instrumentation_data.8 +++ /dev/null @@ -1,141 +0,0 @@ -.\" generated with Ronn/v0.7.3 -.\" http://github.com/rtomayko/ronn/tree/0.7.3 -. -.TH "PUPPET\-INSTRUMENTATION_DATA" "8" "January 2013" "Puppet Labs, LLC" "Puppet manual" -. -.SH "NAME" -\fBpuppet\-instrumentation_data\fR \- Manage instrumentation listener accumulated data\. -. -.SH "SYNOPSIS" -puppet instrumentation_data \fIaction\fR [\-\-terminus TERMINUS] [\-\-extra HASH] -. -.SH "DESCRIPTION" -This subcommand allows to retrieve the various listener data\. -. -.SH "OPTIONS" -Note that any configuration parameter that\'s valid in the configuration file is also a valid long argument, although it may or may not be relevant to the present action\. For example, \fBserver\fR and \fBrun_mode\fR are valid configuration parameters, so you can specify \fB\-\-server \fR, or \fB\-\-run_mode \fR as an argument\. -. -.P -See the configuration file documentation at \fIhttp://docs\.puppetlabs\.com/references/stable/configuration\.html\fR for the full list of acceptable parameters\. A commented list of all configuration options can also be generated by running puppet with \fB\-\-genconfig\fR\. -. -.TP -\-\-render\-as FORMAT -The format in which to render output\. The most common formats are \fBjson\fR, \fBs\fR (string), \fByaml\fR, and \fBconsole\fR, but other options such as \fBdot\fR are sometimes available\. -. -.TP -\-\-verbose -Whether to log verbosely\. -. -.TP -\-\-debug -Whether to log debug information\. -. -.TP -\-\-extra HASH -A terminus can take additional arguments to refine the operation, which are passed as an arbitrary hash to the back\-end\. Anything passed as the extra value is just send direct to the back\-end\. -. -.TP -\-\-terminus TERMINUS -Indirector faces expose indirected subsystems of Puppet\. These subsystems are each able to retrieve and alter a specific type of data (with the familiar actions of \fBfind\fR, \fBsearch\fR, \fBsave\fR, and \fBdestroy\fR) from an arbitrary number of pluggable backends\. In Puppet parlance, these backends are called terminuses\. -. -.IP -Almost all indirected subsystems have a \fBrest\fR terminus that interacts with the puppet master\'s data\. Most of them have additional terminuses for various local data models, which are in turn used by the indirected subsystem on the puppet master whenever it receives a remote request\. -. -.IP -The terminus for an action is often determined by context, but occasionally needs to be set explicitly\. See the "Notes" section of this face\'s manpage for more details\. -. -.SH "ACTIONS" -. -.TP -\fBdestroy\fR \- Invalid for this subcommand\. -\fBSYNOPSIS\fR -. -.IP -puppet instrumentation_data destroy [\-\-terminus TERMINUS] [\-\-extra HASH] \fIkey\fR -. -.IP -\fBDESCRIPTION\fR -. -.IP -Invalid for this subcommand\. -. -.TP -\fBfind\fR \- Retrieve listener data\. -\fBSYNOPSIS\fR -. -.IP -puppet instrumentation_data find [\-\-terminus TERMINUS] [\-\-extra HASH] \fIkey\fR -. -.IP -\fBDESCRIPTION\fR -. -.IP -Retrieve listener data\. -. -.IP -\fBRETURNS\fR -. -.IP -The data of an instrumentation listener -. -.TP -\fBinfo\fR \- Print the default terminus class for this face\. -\fBSYNOPSIS\fR -. -.IP -puppet instrumentation_data info [\-\-terminus TERMINUS] [\-\-extra HASH] -. -.IP -\fBDESCRIPTION\fR -. -.IP -Prints the default terminus class for this subcommand\. Note that different run modes may have different default termini; when in doubt, specify the run mode with the \'\-\-run_mode\' option\. -. -.TP -\fBsave\fR \- Invalid for this subcommand\. -\fBSYNOPSIS\fR -. -.IP -puppet instrumentation_data save [\-\-terminus TERMINUS] [\-\-extra HASH] \fIkey\fR -. -.IP -\fBDESCRIPTION\fR -. -.IP -API only: create or overwrite an object\. As the Faces framework does not currently accept data from STDIN, save actions cannot currently be invoked from the command line\. -. -.TP -\fBsearch\fR \- Invalid for this subcommand\. -\fBSYNOPSIS\fR -. -.IP -puppet instrumentation_data search [\-\-terminus TERMINUS] [\-\-extra HASH] \fIquery\fR -. -.IP -\fBDESCRIPTION\fR -. -.IP -Invalid for this subcommand\. -. -.SH "EXAMPLES" -\fBfind\fR -. -.P -Retrieve listener data: -. -.P -$ puppet instrumentation_data find performance \-\-terminus rest -. -.SH "NOTES" -This subcommand is an indirector face, which exposes \fBfind\fR, \fBsearch\fR, \fBsave\fR, and \fBdestroy\fR actions for an indirected subsystem of Puppet\. Valid termini for this face include: -. -.IP "\(bu" 4 -\fBlocal\fR -. -.IP "\(bu" 4 -\fBrest\fR -. -.IP "" 0 -. -.SH "COPYRIGHT AND LICENSE" -Copyright 2011 by Puppet Labs Apache 2 license; see COPYING diff --git a/man/man8/puppet-instrumentation_listener.8 b/man/man8/puppet-instrumentation_listener.8 deleted file mode 100644 index 35ce84f78..000000000 --- a/man/man8/puppet-instrumentation_listener.8 +++ /dev/null @@ -1,218 +0,0 @@ -.\" generated with Ronn/v0.7.3 -.\" http://github.com/rtomayko/ronn/tree/0.7.3 -. -.TH "PUPPET\-INSTRUMENTATION_LISTENER" "8" "January 2013" "Puppet Labs, LLC" "Puppet manual" -. -.SH "NAME" -\fBpuppet\-instrumentation_listener\fR \- Manage instrumentation listeners\. -. -.SH "SYNOPSIS" -puppet instrumentation_listener \fIaction\fR [\-\-terminus TERMINUS] [\-\-extra HASH] -. -.SH "DESCRIPTION" -This subcommand enables/disables or list instrumentation listeners\. -. -.SH "OPTIONS" -Note that any configuration parameter that\'s valid in the configuration file is also a valid long argument, although it may or may not be relevant to the present action\. For example, \fBserver\fR and \fBrun_mode\fR are valid configuration parameters, so you can specify \fB\-\-server \fR, or \fB\-\-run_mode \fR as an argument\. -. -.P -See the configuration file documentation at \fIhttp://docs\.puppetlabs\.com/references/stable/configuration\.html\fR for the full list of acceptable parameters\. A commented list of all configuration options can also be generated by running puppet with \fB\-\-genconfig\fR\. -. -.TP -\-\-render\-as FORMAT -The format in which to render output\. The most common formats are \fBjson\fR, \fBs\fR (string), \fByaml\fR, and \fBconsole\fR, but other options such as \fBdot\fR are sometimes available\. -. -.TP -\-\-verbose -Whether to log verbosely\. -. -.TP -\-\-debug -Whether to log debug information\. -. -.TP -\-\-extra HASH -A terminus can take additional arguments to refine the operation, which are passed as an arbitrary hash to the back\-end\. Anything passed as the extra value is just send direct to the back\-end\. -. -.TP -\-\-terminus TERMINUS -Indirector faces expose indirected subsystems of Puppet\. These subsystems are each able to retrieve and alter a specific type of data (with the familiar actions of \fBfind\fR, \fBsearch\fR, \fBsave\fR, and \fBdestroy\fR) from an arbitrary number of pluggable backends\. In Puppet parlance, these backends are called terminuses\. -. -.IP -Almost all indirected subsystems have a \fBrest\fR terminus that interacts with the puppet master\'s data\. Most of them have additional terminuses for various local data models, which are in turn used by the indirected subsystem on the puppet master whenever it receives a remote request\. -. -.IP -The terminus for an action is often determined by context, but occasionally needs to be set explicitly\. See the "Notes" section of this face\'s manpage for more details\. -. -.SH "ACTIONS" -. -.TP -\fBdestroy\fR \- Invalid for this subcommand\. -\fBSYNOPSIS\fR -. -.IP -puppet instrumentation_listener destroy [\-\-terminus TERMINUS] [\-\-extra HASH] \fIkey\fR -. -.IP -\fBDESCRIPTION\fR -. -.IP -Invalid for this subcommand\. -. -.TP -\fBdisable\fR \- Disable a given instrumentation listener\. -\fBSYNOPSIS\fR -. -.IP -puppet instrumentation_listener disable [\-\-terminus TERMINUS] [\-\-extra HASH] \fIlistener\fR -. -.IP -\fBDESCRIPTION\fR -. -.IP -Disable a given instrumentation listener\. After being disabled the listener will stop receiving instrumentation notifications from the probes\. -. -.IP -\fBRETURNS\fR -. -.IP -Nothing\. -. -.TP -\fBenable\fR \- Enable a given instrumentation listener\. -\fBSYNOPSIS\fR -. -.IP -puppet instrumentation_listener enable [\-\-terminus TERMINUS] [\-\-extra HASH] \fIlistener\fR -. -.IP -\fBDESCRIPTION\fR -. -.IP -Enable a given instrumentation listener\. After being enabled the listener will start receiving instrumentation notifications from the probes if those are enabled\. -. -.IP -\fBRETURNS\fR -. -.IP -Nothing\. -. -.TP -\fBfind\fR \- Retrieve a single listener\. -\fBSYNOPSIS\fR -. -.IP -puppet instrumentation_listener find [\-\-terminus TERMINUS] [\-\-extra HASH] \fIkey\fR -. -.IP -\fBDESCRIPTION\fR -. -.IP -Retrieve a single listener\. -. -.IP -\fBRETURNS\fR -. -.IP -The status of an instrumentation listener -. -.TP -\fBinfo\fR \- Print the default terminus class for this face\. -\fBSYNOPSIS\fR -. -.IP -puppet instrumentation_listener info [\-\-terminus TERMINUS] [\-\-extra HASH] -. -.IP -\fBDESCRIPTION\fR -. -.IP -Prints the default terminus class for this subcommand\. Note that different run modes may have different default termini; when in doubt, specify the run mode with the \'\-\-run_mode\' option\. -. -.TP -\fBsave\fR \- API only: modify an instrumentation listener status\. -\fBSYNOPSIS\fR -. -.IP -puppet instrumentation_listener save [\-\-terminus TERMINUS] [\-\-extra HASH] \fIlistener\fR -. -.IP -\fBDESCRIPTION\fR -. -.IP -API only: create or overwrite an object\. As the Faces framework does not currently accept data from STDIN, save actions cannot currently be invoked from the command line\. -. -.TP -\fBsearch\fR \- Retrieve all instrumentation listeners statuses\. -\fBSYNOPSIS\fR -. -.IP -puppet instrumentation_listener search [\-\-terminus TERMINUS] [\-\-extra HASH] \fIdummy_text\fR -. -.IP -\fBDESCRIPTION\fR -. -.IP -Retrieve all instrumentation listeners statuses\. -. -.IP -\fBRETURNS\fR -. -.IP -The statuses of all instrumentation listeners -. -.IP -\fBNOTES\fR -. -.IP -Although this action always returns all instrumentation listeners, it requires a dummy search key; this is a known bug\. -. -.SH "EXAMPLES" -\fBdisable\fR -. -.P -Disable the "performance" listener in the running master: -. -.P -$ puppet instrumentation_listener disable performance \-\-terminus rest -. -.P -\fBenable\fR -. -.P -Enable the "performance" listener in the running master: -. -.P -$ puppet instrumentation_listener enable performance \-\-terminus rest -. -.P -\fBfind\fR -. -.P -Retrieve a given listener: -. -.P -$ puppet instrumentation_listener find performance \-\-terminus rest -. -.P -\fBsearch\fR -. -.P -Retrieve the state of the listeners running in the remote puppet master: -. -.P -$ puppet instrumentation_listener search x \-\-terminus rest -. -.SH "NOTES" -This subcommand is an indirector face, which exposes \fBfind\fR, \fBsearch\fR, \fBsave\fR, and \fBdestroy\fR actions for an indirected subsystem of Puppet\. Valid termini for this face include: -. -.IP "\(bu" 4 -\fBlocal\fR -. -.IP "\(bu" 4 -\fBrest\fR -. -.IP "" 0 -. -.SH "COPYRIGHT AND LICENSE" -Copyright 2011 by Puppet Labs Apache 2 license; see COPYING diff --git a/man/man8/puppet-instrumentation_probe.8 b/man/man8/puppet-instrumentation_probe.8 deleted file mode 100644 index a883c7cbb..000000000 --- a/man/man8/puppet-instrumentation_probe.8 +++ /dev/null @@ -1,203 +0,0 @@ -.\" generated with Ronn/v0.7.3 -.\" http://github.com/rtomayko/ronn/tree/0.7.3 -. -.TH "PUPPET\-INSTRUMENTATION_PROBE" "8" "January 2013" "Puppet Labs, LLC" "Puppet manual" -. -.SH "NAME" -\fBpuppet\-instrumentation_probe\fR \- Manage instrumentation probes\. -. -.SH "SYNOPSIS" -puppet instrumentation_probe \fIaction\fR [\-\-terminus TERMINUS] [\-\-extra HASH] -. -.SH "DESCRIPTION" -This subcommand enables/disables or list instrumentation listeners\. -. -.SH "OPTIONS" -Note that any configuration parameter that\'s valid in the configuration file is also a valid long argument, although it may or may not be relevant to the present action\. For example, \fBserver\fR and \fBrun_mode\fR are valid configuration parameters, so you can specify \fB\-\-server \fR, or \fB\-\-run_mode \fR as an argument\. -. -.P -See the configuration file documentation at \fIhttp://docs\.puppetlabs\.com/references/stable/configuration\.html\fR for the full list of acceptable parameters\. A commented list of all configuration options can also be generated by running puppet with \fB\-\-genconfig\fR\. -. -.TP -\-\-render\-as FORMAT -The format in which to render output\. The most common formats are \fBjson\fR, \fBs\fR (string), \fByaml\fR, and \fBconsole\fR, but other options such as \fBdot\fR are sometimes available\. -. -.TP -\-\-verbose -Whether to log verbosely\. -. -.TP -\-\-debug -Whether to log debug information\. -. -.TP -\-\-extra HASH -A terminus can take additional arguments to refine the operation, which are passed as an arbitrary hash to the back\-end\. Anything passed as the extra value is just send direct to the back\-end\. -. -.TP -\-\-terminus TERMINUS -Indirector faces expose indirected subsystems of Puppet\. These subsystems are each able to retrieve and alter a specific type of data (with the familiar actions of \fBfind\fR, \fBsearch\fR, \fBsave\fR, and \fBdestroy\fR) from an arbitrary number of pluggable backends\. In Puppet parlance, these backends are called terminuses\. -. -.IP -Almost all indirected subsystems have a \fBrest\fR terminus that interacts with the puppet master\'s data\. Most of them have additional terminuses for various local data models, which are in turn used by the indirected subsystem on the puppet master whenever it receives a remote request\. -. -.IP -The terminus for an action is often determined by context, but occasionally needs to be set explicitly\. See the "Notes" section of this face\'s manpage for more details\. -. -.SH "ACTIONS" -. -.TP -\fBdestroy\fR \- API only: disable all instrumentation probes\. -\fBSYNOPSIS\fR -. -.IP -puppet instrumentation_probe destroy [\-\-terminus TERMINUS] [\-\-extra HASH] \fIdummy\fR -. -.IP -\fBDESCRIPTION\fR -. -.IP -API only: disable all instrumentation probes\. -. -.TP -\fBdisable\fR \- Disable all instrumentation probes\. -\fBSYNOPSIS\fR -. -.IP -puppet instrumentation_probe disable [\-\-terminus TERMINUS] [\-\-extra HASH] \fIdummy\fR -. -.IP -\fBDESCRIPTION\fR -. -.IP -Disable all instrumentation probes\. After being disabled, no listeners will receive instrumentation notifications\. -. -.IP -\fBRETURNS\fR -. -.IP -Nothing\. -. -.TP -\fBenable\fR \- Enable all instrumentation probes\. -\fBSYNOPSIS\fR -. -.IP -puppet instrumentation_probe enable [\-\-terminus TERMINUS] [\-\-extra HASH] \fIdummy\fR -. -.IP -\fBDESCRIPTION\fR -. -.IP -Enable all instrumentation probes\. After being enabled, all enabled listeners will start receiving instrumentation notifications from the probes\. -. -.IP -\fBRETURNS\fR -. -.IP -Nothing\. -. -.TP -\fBfind\fR \- Invalid for this subcommand\. -\fBSYNOPSIS\fR -. -.IP -puppet instrumentation_probe find [\-\-terminus TERMINUS] [\-\-extra HASH] \fIkey\fR -. -.IP -\fBDESCRIPTION\fR -. -.IP -Invalid for this subcommand\. -. -.TP -\fBinfo\fR \- Print the default terminus class for this face\. -\fBSYNOPSIS\fR -. -.IP -puppet instrumentation_probe info [\-\-terminus TERMINUS] [\-\-extra HASH] -. -.IP -\fBDESCRIPTION\fR -. -.IP -Prints the default terminus class for this subcommand\. Note that different run modes may have different default termini; when in doubt, specify the run mode with the \'\-\-run_mode\' option\. -. -.TP -\fBsave\fR \- API only: enable all instrumentation probes\. -\fBSYNOPSIS\fR -. -.IP -puppet instrumentation_probe save [\-\-terminus TERMINUS] [\-\-extra HASH] \fIdummy\fR -. -.IP -\fBDESCRIPTION\fR -. -.IP -API only: create or overwrite an object\. As the Faces framework does not currently accept data from STDIN, save actions cannot currently be invoked from the command line\. -. -.TP -\fBsearch\fR \- Retrieve all probe statuses\. -\fBSYNOPSIS\fR -. -.IP -puppet instrumentation_probe search [\-\-terminus TERMINUS] [\-\-extra HASH] \fIdummy_text\fR -. -.IP -\fBDESCRIPTION\fR -. -.IP -Retrieve all probe statuses\. -. -.IP -\fBRETURNS\fR -. -.IP -The statuses of all instrumentation probes -. -.IP -\fBNOTES\fR -. -.IP -Although this action always returns all instrumentation probes, it requires a dummy search key; this is a known bug\. -. -.SH "EXAMPLES" -\fBdisable\fR -. -.P -Disable the probes for the running master: -. -.P -$ puppet instrumentation_probe disable x \-\-terminus rest -. -.P -\fBenable\fR -. -.P -Enable the probes for the running master: -. -.P -$ puppet instrumentation_probe enable x \-\-terminus rest -. -.P -\fBsearch\fR -. -.P -Retrieve the state of the probes running in the remote puppet master: -. -.P -$ puppet instrumentation_probe search x \-\-terminus rest -. -.SH "NOTES" -This subcommand is an indirector face, which exposes \fBfind\fR, \fBsearch\fR, \fBsave\fR, and \fBdestroy\fR actions for an indirected subsystem of Puppet\. Valid termini for this face include: -. -.IP "\(bu" 4 -\fBlocal\fR -. -.IP "\(bu" 4 -\fBrest\fR -. -.IP "" 0 -. -.SH "COPYRIGHT AND LICENSE" -Copyright 2011 by Puppet Labs Apache 2 license; see COPYING diff --git a/spec/unit/application/indirection_base_spec.rb b/spec/unit/application/indirection_base_spec.rb index a8c8142da..fc31b1521 100755 --- a/spec/unit/application/indirection_base_spec.rb +++ b/spec/unit/application/indirection_base_spec.rb @@ -1,52 +1,48 @@ #! /usr/bin/env ruby require 'spec_helper' require 'puppet/util/command_line' require 'puppet/application/indirection_base' require 'puppet/indirector/face' ######################################################################## # Stub for testing; the names are critical, sadly. --daniel 2011-03-30 class Puppet::Application::TestIndirection < Puppet::Application::IndirectionBase end ######################################################################## describe Puppet::Application::IndirectionBase do before :all do @face = Puppet::Indirector::Face.define(:test_indirection, '0.0.1') do summary "fake summary" copyright "Puppet Labs", 2011 license "Apache 2 license; see COPYING" end # REVISIT: This horror is required because we don't allow anything to be # :current except for if it lives on, and is loaded from, disk. --daniel 2011-03-29 @face.instance_variable_set('@version', :current) Puppet::Face.register(@face) end after :all do # Delete the face so that it doesn't interfere with other specs Puppet::Interface::FaceCollection.instance_variable_get(:@faces).delete Puppet::Interface::FaceCollection.underscorize(@face.name) end it "should accept a terminus command line option" do # It would be nice not to have to stub this, but whatever... writing an # entire indirection stack would cause us more grief. --daniel 2011-03-31 terminus = stub_everything("test indirection terminus") terminus.stubs(:name).returns(:test_indirection) - # This is necessary because Instrumentation tickles indirection, which - # messes up our expectations. - Puppet::Util::Instrumentation.stubs(:init) - Puppet::Indirector::Indirection.expects(:instance). with(:test_indirection).returns(terminus) command_line = Puppet::Util::CommandLine.new("puppet", %w{test_indirection --terminus foo save bar}) application = Puppet::Application::TestIndirection.new(command_line) expect { application.run }.to exit_with 0 end end diff --git a/spec/unit/application_spec.rb b/spec/unit/application_spec.rb index b96f829d9..4b214d5da 100755 --- a/spec/unit/application_spec.rb +++ b/spec/unit/application_spec.rb @@ -1,645 +1,628 @@ #! /usr/bin/env ruby require 'spec_helper' require 'puppet/application' require 'puppet' require 'getoptlong' require 'timeout' describe Puppet::Application do before(:each) do - Puppet::Util::Instrumentation.stubs(:init) @app = Class.new(Puppet::Application).new @appclass = @app.class @app.stubs(:name).returns("test_app") end describe "application commandline" do it "should not pick up changes to the array of arguments" do args = %w{subcommand --arg} command_line = Puppet::Util::CommandLine.new('puppet', args) app = Puppet::Application.new(command_line) args[0] = 'different_subcommand' args[1] = '--other-arg' app.command_line.subcommand_name.should == 'subcommand' app.command_line.args.should == ['--arg'] end end describe "application defaults" do it "should fail if required app default values are missing" do @app.stubs(:app_defaults).returns({ :foo => 'bar' }) Puppet.expects(:err).with(regexp_matches(/missing required app default setting/)) expect { @app.run }.to exit_with 1 end end describe "finding" do before do @klass = Puppet::Application @klass.stubs(:puts) end it "should find classes in the namespace" do @klass.find("Agent").should == @klass::Agent end it "should not find classes outside the namespace" do expect { @klass.find("String") }.to raise_error(LoadError) end it "should error if it can't find a class" do Puppet.expects(:err).with do |value| value =~ /Unable to find application 'ThisShallNeverEverEverExist'/ and value =~ /puppet\/application\/thisshallneverevereverexist/ and value =~ /no such file to load|cannot load such file/ end expect { @klass.find("ThisShallNeverEverEverExist") }.to raise_error(LoadError) end it "#12114: should prevent File namespace collisions" do # have to require the file face once, then the second time around it would fail @klass.find("File").should == Puppet::Application::File @klass.find("File").should == Puppet::Application::File end end describe "#available_application_names" do it 'should be able to find available application names' do apps = %w{describe filebucket kick queue resource agent cert apply doc master} Puppet::Util::Autoload.expects(:files_to_load).returns(apps) Puppet::Application.available_application_names.should =~ apps end it 'should find applications from multiple paths' do Puppet::Util::Autoload.expects(:files_to_load).with('puppet/application').returns(%w{ /a/foo.rb /b/bar.rb }) Puppet::Application.available_application_names.should =~ %w{ foo bar } end it 'should return unique application names' do Puppet::Util::Autoload.expects(:files_to_load).with('puppet/application').returns(%w{ /a/foo.rb /b/foo.rb }) Puppet::Application.available_application_names.should == %w{ foo } end end describe ".run_mode" do it "should default to user" do @appclass.run_mode.name.should == :user end it "should set and get a value" do @appclass.run_mode :agent @appclass.run_mode.name.should == :agent end end # These tests may look a little weird and repetative in its current state; # it used to illustrate several ways that the run_mode could be changed # at run time; there are fewer ways now, but it would still be nice to # get to a point where it was entirely impossible. describe "when dealing with run_mode" do class TestApp < Puppet::Application run_mode :master def run_command # no-op end end it "should sadly and frighteningly allow run_mode to change at runtime via #initialize_app_defaults" do Puppet.features.stubs(:syslog?).returns(true) app = TestApp.new app.initialize_app_defaults Puppet.run_mode.should be_master end it "should sadly and frighteningly allow run_mode to change at runtime via #run" do app = TestApp.new app.run app.class.run_mode.name.should == :master Puppet.run_mode.should be_master end end it "should explode when an invalid run mode is set at runtime, for great victory" do expect { class InvalidRunModeTestApp < Puppet::Application run_mode :abracadabra def run_command # no-op end end }.to raise_error end it "should have a run entry-point" do @app.should respond_to(:run) end it "should have a read accessor to options" do @app.should respond_to(:options) end it "should include a default setup method" do @app.should respond_to(:setup) end it "should include a default preinit method" do @app.should respond_to(:preinit) end it "should include a default run_command method" do @app.should respond_to(:run_command) end it "should invoke main as the default" do @app.expects( :main ) @app.run_command end - it "should initialize the Puppet Instrumentation layer early in the life cycle" do - # Not proud of this, but the fact that we are stubbing init_app_defaults - # below means that we will get errors if anyone tries to access any - # settings that depend on app_defaults. In general this whole test - # seems to be testing too many implementation details rather than - # functionality, but, hey. - Puppet[:route_file] = "/dev/null" - - startup_sequence = sequence('startup') - @app.expects(:initialize_app_defaults).in_sequence(startup_sequence) - Puppet::Util::Instrumentation.expects(:init).in_sequence(startup_sequence) - @app.expects(:preinit).in_sequence(startup_sequence) - - expect { @app.run }.to exit_with(1) - end - describe 'when invoking clear!' do before :each do Puppet::Application.run_status = :stop_requested Puppet::Application.clear! end it 'should have nil run_status' do Puppet::Application.run_status.should be_nil end it 'should return false for restart_requested?' do Puppet::Application.restart_requested?.should be_false end it 'should return false for stop_requested?' do Puppet::Application.stop_requested?.should be_false end it 'should return false for interrupted?' do Puppet::Application.interrupted?.should be_false end it 'should return true for clear?' do Puppet::Application.clear?.should be_true end end describe 'after invoking stop!' do before :each do Puppet::Application.run_status = nil Puppet::Application.stop! end after :each do Puppet::Application.run_status = nil end it 'should have run_status of :stop_requested' do Puppet::Application.run_status.should == :stop_requested end it 'should return true for stop_requested?' do Puppet::Application.stop_requested?.should be_true end it 'should return false for restart_requested?' do Puppet::Application.restart_requested?.should be_false end it 'should return true for interrupted?' do Puppet::Application.interrupted?.should be_true end it 'should return false for clear?' do Puppet::Application.clear?.should be_false end end describe 'when invoking restart!' do before :each do Puppet::Application.run_status = nil Puppet::Application.restart! end after :each do Puppet::Application.run_status = nil end it 'should have run_status of :restart_requested' do Puppet::Application.run_status.should == :restart_requested end it 'should return true for restart_requested?' do Puppet::Application.restart_requested?.should be_true end it 'should return false for stop_requested?' do Puppet::Application.stop_requested?.should be_false end it 'should return true for interrupted?' do Puppet::Application.interrupted?.should be_true end it 'should return false for clear?' do Puppet::Application.clear?.should be_false end end describe 'when performing a controlled_run' do it 'should not execute block if not :clear?' do Puppet::Application.run_status = :stop_requested target = mock 'target' target.expects(:some_method).never Puppet::Application.controlled_run do target.some_method end end it 'should execute block if :clear?' do Puppet::Application.run_status = nil target = mock 'target' target.expects(:some_method).once Puppet::Application.controlled_run do target.some_method end end describe 'on POSIX systems', :if => Puppet.features.posix? do it 'should signal process with HUP after block if restart requested during block execution' do Timeout::timeout(3) do # if the signal doesn't fire, this causes failure. has_run = false old_handler = trap('HUP') { has_run = true } begin Puppet::Application.controlled_run do Puppet::Application.run_status = :restart_requested end # Ruby 1.9 uses a separate OS level thread to run the signal # handler, so we have to poll - ideally, in a way that will kick # the OS into running other threads - for a while. # # You can't just use the Ruby Thread yield thing either, because # that is just an OS hint, and Linux ... doesn't take that # seriously. --daniel 2012-03-22 sleep 0.001 while not has_run ensure trap('HUP', old_handler) end end end end after :each do Puppet::Application.run_status = nil end end describe "when parsing command-line options" do before :each do @app.command_line.stubs(:args).returns([]) Puppet.settings.stubs(:optparse_addargs).returns([]) end it "should pass the banner to the option parser" do option_parser = stub "option parser" option_parser.stubs(:on) option_parser.stubs(:parse!) @app.class.instance_eval do banner "banner" end OptionParser.expects(:new).with("banner").returns(option_parser) @app.parse_options end it "should ask OptionParser to parse the command-line argument" do @app.command_line.stubs(:args).returns(%w{ fake args }) OptionParser.any_instance.expects(:parse!).with(%w{ fake args }) @app.parse_options end describe "when using --help" do it "should call exit" do @app.stubs(:puts) expect { @app.handle_help(nil) }.to exit_with 0 end end describe "when using --version" do it "should declare a version option" do @app.should respond_to(:handle_version) end it "should exit after printing the version" do @app.stubs(:puts) expect { @app.handle_version(nil) }.to exit_with 0 end end describe "when dealing with an argument not declared directly by the application" do it "should pass it to handle_unknown if this method exists" do Puppet.settings.stubs(:optparse_addargs).returns([["--not-handled", :REQUIRED]]) @app.expects(:handle_unknown).with("--not-handled", "value").returns(true) @app.command_line.stubs(:args).returns(["--not-handled", "value"]) @app.parse_options end it "should transform boolean option to normal form for Puppet.settings" do @app.expects(:handle_unknown).with("--option", true) @app.send(:handlearg, "--[no-]option", true) end it "should transform boolean option to no- form for Puppet.settings" do @app.expects(:handle_unknown).with("--no-option", false) @app.send(:handlearg, "--[no-]option", false) end end end describe "when calling default setup" do before :each do @app.options.stubs(:[]) end [ :debug, :verbose ].each do |level| it "should honor option #{level}" do @app.options.stubs(:[]).with(level).returns(true) Puppet::Util::Log.stubs(:newdestination) @app.setup Puppet::Util::Log.level.should == (level == :verbose ? :info : :debug) end end it "should honor setdest option" do @app.options.stubs(:[]).with(:setdest).returns(false) Puppet::Util::Log.expects(:setup_default) @app.setup end end describe "when configuring routes" do include PuppetSpec::Files before :each do Puppet::Node.indirection.reset_terminus_class end after :each do Puppet::Node.indirection.reset_terminus_class end it "should use the routes specified for only the active application" do Puppet[:route_file] = tmpfile('routes') File.open(Puppet[:route_file], 'w') do |f| f.print <<-ROUTES test_app: node: terminus: exec other_app: node: terminus: plain catalog: terminus: invalid ROUTES end @app.configure_indirector_routes Puppet::Node.indirection.terminus_class.should == 'exec' end it "should not fail if the route file doesn't exist" do Puppet[:route_file] = "/dev/null/non-existent" expect { @app.configure_indirector_routes }.to_not raise_error end it "should raise an error if the routes file is invalid" do Puppet[:route_file] = tmpfile('routes') File.open(Puppet[:route_file], 'w') do |f| f.print <<-ROUTES invalid : : yaml ROUTES end expect { @app.configure_indirector_routes }.to raise_error end end describe "when running" do before :each do @app.stubs(:preinit) @app.stubs(:setup) @app.stubs(:parse_options) end it "should call preinit" do @app.stubs(:run_command) @app.expects(:preinit) @app.run end it "should call parse_options" do @app.stubs(:run_command) @app.expects(:parse_options) @app.run end it "should call run_command" do @app.expects(:run_command) @app.run end it "should call run_command" do @app.expects(:run_command) @app.run end it "should call main as the default command" do @app.expects(:main) @app.run end it "should warn and exit if no command can be called" do Puppet.expects(:err) expect { @app.run }.to exit_with 1 end it "should raise an error if dispatch returns no command" do @app.stubs(:get_command).returns(nil) Puppet.expects(:err) expect { @app.run }.to exit_with 1 end it "should raise an error if dispatch returns an invalid command" do @app.stubs(:get_command).returns(:this_function_doesnt_exist) Puppet.expects(:err) expect { @app.run }.to exit_with 1 end end describe "when metaprogramming" do describe "when calling option" do it "should create a new method named after the option" do @app.class.option("--test1","-t") do end @app.should respond_to(:handle_test1) end it "should transpose in option name any '-' into '_'" do @app.class.option("--test-dashes-again","-t") do end @app.should respond_to(:handle_test_dashes_again) end it "should create a new method called handle_test2 with option(\"--[no-]test2\")" do @app.class.option("--[no-]test2","-t") do end @app.should respond_to(:handle_test2) end describe "when a block is passed" do it "should create a new method with it" do @app.class.option("--[no-]test2","-t") do raise "I can't believe it, it works!" end expect { @app.handle_test2 }.to raise_error end it "should declare the option to OptionParser" do OptionParser.any_instance.stubs(:on) OptionParser.any_instance.expects(:on).with { |*arg| arg[0] == "--[no-]test3" } @app.class.option("--[no-]test3","-t") do end @app.parse_options end it "should pass a block that calls our defined method" do OptionParser.any_instance.stubs(:on) OptionParser.any_instance.stubs(:on).with('--test4','-t').yields(nil) @app.expects(:send).with(:handle_test4, nil) @app.class.option("--test4","-t") do end @app.parse_options end end describe "when no block is given" do it "should declare the option to OptionParser" do OptionParser.any_instance.stubs(:on) OptionParser.any_instance.expects(:on).with("--test4","-t") @app.class.option("--test4","-t") @app.parse_options end it "should give to OptionParser a block that adds the value to the options array" do OptionParser.any_instance.stubs(:on) OptionParser.any_instance.stubs(:on).with("--test4","-t").yields(nil) @app.options.expects(:[]=).with(:test4,nil) @app.class.option("--test4","-t") @app.parse_options end end end end describe "#handle_logdest_arg" do let(:test_arg) { "arg_test_logdest" } it "should log an exception that is raised" do our_exception = Puppet::DevError.new("test exception") Puppet::Util::Log.expects(:newdestination).with(test_arg).raises(our_exception) Puppet.expects(:log_exception).with(our_exception) @app.handle_logdest_arg(test_arg) end it "should set the new log destination" do Puppet::Util::Log.expects(:newdestination).with(test_arg) @app.handle_logdest_arg(test_arg) end it "should set the flag that a destination is set in the options hash" do Puppet::Util::Log.stubs(:newdestination).with(test_arg) @app.handle_logdest_arg(test_arg) @app.options[:setdest].should be_true end end end diff --git a/spec/unit/face/instrumentation_data_spec.rb b/spec/unit/face/instrumentation_data_spec.rb deleted file mode 100644 index cad084065..000000000 --- a/spec/unit/face/instrumentation_data_spec.rb +++ /dev/null @@ -1,7 +0,0 @@ -#! /usr/bin/env ruby -require 'spec_helper' -require 'puppet/face' - -describe Puppet::Face[:instrumentation_data, '0.0.1'] do - it_should_behave_like "an indirector face" -end diff --git a/spec/unit/face/instrumentation_listener_spec.rb b/spec/unit/face/instrumentation_listener_spec.rb deleted file mode 100644 index a402ce7f2..000000000 --- a/spec/unit/face/instrumentation_listener_spec.rb +++ /dev/null @@ -1,38 +0,0 @@ -#! /usr/bin/env ruby -require 'spec_helper' -require 'puppet/face' - -describe Puppet::Face[:instrumentation_listener, '0.0.1'] do - it_should_behave_like "an indirector face" - - [:enable, :disable].each do |m| - describe "when running ##{m}" do - before(:each) do - @listener = stub_everything 'listener' - Puppet::Face[:instrumentation_listener, '0.0.1'].stubs(:find).returns(@listener) - Puppet::Face[:instrumentation_listener, '0.0.1'].stubs(:save) - Puppet::Util::Instrumentation::Listener.indirection.stubs(:terminus_class=) - end - - it "should force the REST terminus" do - Puppet::Util::Instrumentation::Listener.indirection.expects(:terminus_class=).with(:rest) - subject.send(m, "dummy") - end - - it "should find the named listener" do - Puppet::Face[:instrumentation_listener, '0.0.1'].expects(:find).with("dummy").returns(@listener) - subject.send(m, "dummy") - end - - it "should #{m} the named listener" do - @listener.expects(:enabled=).with( m == :enable ) - subject.send(m, "dummy") - end - - it "should save finally the listener" do - Puppet::Face[:instrumentation_listener, '0.0.1'].expects(:save).with(@listener) - subject.send(m, "dummy") - end - end - end -end diff --git a/spec/unit/face/instrumentation_probe_spec.rb b/spec/unit/face/instrumentation_probe_spec.rb deleted file mode 100644 index 78c806bba..000000000 --- a/spec/unit/face/instrumentation_probe_spec.rb +++ /dev/null @@ -1,21 +0,0 @@ -#! /usr/bin/env ruby -require 'spec_helper' -require 'puppet/face' - -describe Puppet::Face[:instrumentation_probe, '0.0.1'] do - it_should_behave_like "an indirector face" - - describe 'when running #enable' do - it 'should invoke #save' do - subject.expects(:save).with(nil) - subject.enable('hostname') - end - end - - describe 'when running #disable' do - it 'should invoke #destroy' do - subject.expects(:destroy).with(nil) - subject.disable('hostname') - end - end -end diff --git a/spec/unit/indirector/instrumentation_data/local_spec.rb b/spec/unit/indirector/instrumentation_data/local_spec.rb deleted file mode 100644 index 062e5cf67..000000000 --- a/spec/unit/indirector/instrumentation_data/local_spec.rb +++ /dev/null @@ -1,52 +0,0 @@ -#! /usr/bin/env ruby -require 'spec_helper' - -require 'puppet/util/instrumentation/listener' -require 'puppet/indirector/instrumentation_data/local' - -describe Puppet::Indirector::InstrumentationData::Local do - it "should be a subclass of the Code terminus" do - Puppet::Indirector::InstrumentationData::Local.superclass.should equal(Puppet::Indirector::Code) - end - - it "should be registered with the configuration store indirection" do - indirection = Puppet::Indirector::Indirection.instance(:instrumentation_data) - Puppet::Indirector::InstrumentationData::Local.indirection.should equal(indirection) - end - - it "should have its name set to :local" do - Puppet::Indirector::InstrumentationData::Local.name.should == :local - end -end - -describe Puppet::Indirector::InstrumentationData::Local do - before :each do - Puppet::Util::Instrumentation.stubs(:listener) - @data = Puppet::Indirector::InstrumentationData::Local.new - @name = "me" - @request = stub 'request', :key => @name - end - - describe "when finding instrumentation data" do - it "should return an Instrumentation Data instance matching the key" do - end - end - - describe "when searching listeners" do - it "should raise an error" do - lambda { @data.search(@request) }.should raise_error(Puppet::DevError) - end - end - - describe "when saving listeners" do - it "should raise an error" do - lambda { @data.save(@request) }.should raise_error(Puppet::DevError) - end - end - - describe "when destroying listeners" do - it "should raise an error" do - lambda { @data.destroy(@reques) }.should raise_error(Puppet::DevError) - end - end -end diff --git a/spec/unit/indirector/instrumentation_data/rest_spec.rb b/spec/unit/indirector/instrumentation_data/rest_spec.rb deleted file mode 100644 index 295928f91..000000000 --- a/spec/unit/indirector/instrumentation_data/rest_spec.rb +++ /dev/null @@ -1,11 +0,0 @@ -#! /usr/bin/env ruby -require 'spec_helper' - -require 'puppet/util/instrumentation/data' -require 'puppet/indirector/instrumentation_data/rest' - -describe Puppet::Indirector::InstrumentationData::Rest do - it "should be a subclass of Puppet::Indirector::REST" do - Puppet::Indirector::InstrumentationData::Rest.superclass.should equal(Puppet::Indirector::REST) - end -end diff --git a/spec/unit/indirector/instrumentation_listener/local_spec.rb b/spec/unit/indirector/instrumentation_listener/local_spec.rb deleted file mode 100644 index 195528167..000000000 --- a/spec/unit/indirector/instrumentation_listener/local_spec.rb +++ /dev/null @@ -1,65 +0,0 @@ -#! /usr/bin/env ruby -require 'spec_helper' - -require 'puppet/util/instrumentation/listener' -require 'puppet/indirector/instrumentation_listener/local' - -describe Puppet::Indirector::InstrumentationListener::Local do - it "should be a subclass of the Code terminus" do - Puppet::Indirector::InstrumentationListener::Local.superclass.should equal(Puppet::Indirector::Code) - end - - it "should be registered with the configuration store indirection" do - indirection = Puppet::Indirector::Indirection.instance(:instrumentation_listener) - Puppet::Indirector::InstrumentationListener::Local.indirection.should equal(indirection) - end - - it "should have its name set to :local" do - Puppet::Indirector::InstrumentationListener::Local.name.should == :local - end -end - -describe Puppet::Indirector::InstrumentationListener::Local do - before :each do - Puppet::Util::Instrumentation.stubs(:listener) - @listener = Puppet::Indirector::InstrumentationListener::Local.new - @name = "me" - @request = stub 'request', :key => @name - end - - describe "when finding listeners" do - it "should return an Instrumentation Listener instance matching the key" do - Puppet::Util::Instrumentation.expects(:[]).with("me").returns(:instance) - @listener.find(@request).should == :instance - end - end - - describe "when searching listeners" do - it "should return a list of all loaded Instrumentation Listenesrs irregardless of the given key" do - Puppet::Util::Instrumentation.expects(:listeners).returns([:instance1, :instance2]) - @listener.search(@request).should == [:instance1, :instance2] - end - end - - describe "when saving listeners" do - it "should set the new listener to the global listener list" do - newlistener = stub 'listener', :name => @name - @request.stubs(:instance).returns(newlistener) - Puppet::Util::Instrumentation.expects(:[]=).with("me", newlistener) - @listener.save(@request) - end - end - - describe "when destroying listeners" do - it "should raise an error if listener wasn't subscribed" do - Puppet::Util::Instrumentation.expects(:[]).with("me").returns(nil) - lambda { @listener.destroy(@request) }.should raise_error - end - - it "should unsubscribe the listener" do - Puppet::Util::Instrumentation.expects(:[]).with("me").returns(:instancce) - Puppet::Util::Instrumentation.expects(:unsubscribe).with(:instancce) - @listener.destroy(@request) - end - end -end diff --git a/spec/unit/indirector/instrumentation_listener/rest_spec.rb b/spec/unit/indirector/instrumentation_listener/rest_spec.rb deleted file mode 100644 index 56ac9ab76..000000000 --- a/spec/unit/indirector/instrumentation_listener/rest_spec.rb +++ /dev/null @@ -1,11 +0,0 @@ -#! /usr/bin/env ruby -require 'spec_helper' - -require 'puppet/util/instrumentation/listener' -require 'puppet/indirector/instrumentation_listener/rest' - -describe Puppet::Indirector::InstrumentationListener::Rest do - it "should be a subclass of Puppet::Indirector::REST" do - Puppet::Indirector::InstrumentationListener::Rest.superclass.should equal(Puppet::Indirector::REST) - end -end diff --git a/spec/unit/indirector/instrumentation_probe/local_spec.rb b/spec/unit/indirector/instrumentation_probe/local_spec.rb deleted file mode 100644 index c930098bf..000000000 --- a/spec/unit/indirector/instrumentation_probe/local_spec.rb +++ /dev/null @@ -1,65 +0,0 @@ -#! /usr/bin/env ruby -require 'spec_helper' - -require 'puppet/util/instrumentation/indirection_probe' -require 'puppet/indirector/instrumentation_probe/local' -require 'puppet/util/instrumentation/instrumentable' - -describe Puppet::Indirector::InstrumentationProbe::Local do - it "should be a subclass of the Code terminus" do - Puppet::Indirector::InstrumentationProbe::Local.superclass.should equal(Puppet::Indirector::Code) - end - - it "should be registered with the configuration store indirection" do - indirection = Puppet::Indirector::Indirection.instance(:instrumentation_probe) - Puppet::Indirector::InstrumentationProbe::Local.indirection.should equal(indirection) - end - - it "should have its name set to :local" do - Puppet::Indirector::InstrumentationProbe::Local.name.should == :local - end -end - -describe Puppet::Indirector::InstrumentationProbe::Local do - before :each do - Puppet::Util::Instrumentation.stubs(:listener) - @probe = Puppet::Indirector::InstrumentationProbe::Local.new - @name = "me" - @request = stub 'request', :key => @name - end - - describe "when finding probes" do - it "should do nothing" do - @probe.find(@request).should be_nil - end - end - - describe "when searching probes" do - it "should return a list of all loaded probes irregardless of the given key" do - instance1 = stub 'instance1', :method => "probe1", :klass => "Klass1" - instance2 = stub 'instance2', :method => "probe2", :klass => "Klass2" - Puppet::Util::Instrumentation::IndirectionProbe.expects(:new).with("Klass1.probe1").returns(:instance1) - Puppet::Util::Instrumentation::IndirectionProbe.expects(:new).with("Klass2.probe2").returns(:instance2) - Puppet::Util::Instrumentation::Instrumentable.expects(:each_probe).multiple_yields([instance1], [instance2]) - @probe.search(@request).should == [ :instance1, :instance2 ] - end - end - - describe "when saving probes" do - it "should enable probes" do - newprobe = stub 'probe', :name => @name - @request.stubs(:instance).returns(newprobe) - Puppet::Util::Instrumentation::Instrumentable.expects(:enable_probes) - @probe.save(@request) - end - end - - describe "when destroying probes" do - it "should disable probes" do - newprobe = stub 'probe', :name => @name - @request.stubs(:instance).returns(newprobe) - Puppet::Util::Instrumentation::Instrumentable.expects(:disable_probes) - @probe.destroy(@request) - end - end -end diff --git a/spec/unit/indirector/instrumentation_probe/rest_spec.rb b/spec/unit/indirector/instrumentation_probe/rest_spec.rb deleted file mode 100644 index 7c278779d..000000000 --- a/spec/unit/indirector/instrumentation_probe/rest_spec.rb +++ /dev/null @@ -1,11 +0,0 @@ -#! /usr/bin/env ruby -require 'spec_helper' - -require 'puppet/util/instrumentation/indirection_probe' -require 'puppet/indirector/instrumentation_probe/rest' - -describe Puppet::Indirector::InstrumentationProbe::Rest do - it "should be a subclass of Puppet::Indirector::REST" do - Puppet::Indirector::InstrumentationProbe::Rest.superclass.should equal(Puppet::Indirector::REST) - end -end diff --git a/spec/unit/util/instrumentation/data_spec.rb b/spec/unit/util/instrumentation/data_spec.rb deleted file mode 100755 index 418d89724..000000000 --- a/spec/unit/util/instrumentation/data_spec.rb +++ /dev/null @@ -1,46 +0,0 @@ -#! /usr/bin/env ruby - -require 'spec_helper' -require 'matchers/json' -require 'puppet/util/instrumentation' -require 'puppet/util/instrumentation/data' - -describe Puppet::Util::Instrumentation::Data do - include JSONMatchers - - Puppet::Util::Instrumentation::Data - - before(:each) do - @listener = stub 'listener', :name => "name" - Puppet::Util::Instrumentation.stubs(:[]).with("name").returns(@listener) - end - - it "should indirect instrumentation_data" do - Puppet::Util::Instrumentation::Data.indirection.name.should == :instrumentation_data - end - - it "should lookup the corresponding listener" do - Puppet::Util::Instrumentation.expects(:[]).with("name").returns(@listener) - Puppet::Util::Instrumentation::Data.new("name") - end - - it "should error if the listener can not be found" do - Puppet::Util::Instrumentation.expects(:[]).with("name").returns(nil) - expect { Puppet::Util::Instrumentation::Data.new("name") }.to raise_error - end - - it "should return pson data" do - data = Puppet::Util::Instrumentation::Data.new("name") - @listener.stubs(:data).returns({ :this_is_data => "here also" }) - data.should set_json_attribute('name').to("name") - data.should set_json_attribute('this_is_data').to("here also") - end - - it "should not error if the underlying listener doesn't have data" do - lambda { Puppet::Util::Instrumentation::Data.new("name").to_pson }.should_not raise_error - end - - it "should return a hash containing data when unserializing from pson" do - Puppet::Util::Instrumentation::Data.from_data_hash({:name => "name"}).should == {:name => "name"} - end -end diff --git a/spec/unit/util/instrumentation/indirection_probe_spec.rb b/spec/unit/util/instrumentation/indirection_probe_spec.rb deleted file mode 100644 index d06849e5e..000000000 --- a/spec/unit/util/instrumentation/indirection_probe_spec.rb +++ /dev/null @@ -1,21 +0,0 @@ -#! /usr/bin/env ruby - -require 'spec_helper' -require 'matchers/json' -require 'puppet/util/instrumentation' -require 'puppet/util/instrumentation/indirection_probe' - -describe Puppet::Util::Instrumentation::IndirectionProbe do - include JSONMatchers - - Puppet::Util::Instrumentation::IndirectionProbe - - it "should indirect instrumentation_probe" do - Puppet::Util::Instrumentation::IndirectionProbe.indirection.name.should == :instrumentation_probe - end - - it "should return pson data" do - probe = Puppet::Util::Instrumentation::IndirectionProbe.new("probe") - probe.should set_json_attribute('name').to("probe") - end -end diff --git a/spec/unit/util/instrumentation/instrumentable_spec.rb b/spec/unit/util/instrumentation/instrumentable_spec.rb deleted file mode 100755 index 344f8f44d..000000000 --- a/spec/unit/util/instrumentation/instrumentable_spec.rb +++ /dev/null @@ -1,186 +0,0 @@ -#! /usr/bin/env ruby - -require 'spec_helper' - -require 'puppet/util/instrumentation' -require 'puppet/util/instrumentation/instrumentable' - -describe Puppet::Util::Instrumentation::Instrumentable::Probe do - - before(:each) do - Puppet::Util::Instrumentation.stubs(:start) - Puppet::Util::Instrumentation.stubs(:stop) - - class ProbeTest - def mymethod(arg1, arg2, arg3) - :it_worked - end - end - end - - after(:each) do - if ProbeTest.method_defined?(:instrumented_mymethod) - ProbeTest.class_eval { - remove_method(:mymethod) - alias_method(:mymethod, :instrumented_mymethod) - } - end - Puppet::Util::Instrumentation::Instrumentable.clear_probes - end - - describe "when enabling a probe" do - it "should raise an error if the probe is already enabled" do - probe = Puppet::Util::Instrumentation::Instrumentable::Probe.new(:mymethod, ProbeTest) - probe.enable - lambda { probe.enable }.should raise_error - end - - it "should rename the original method name" do - probe = Puppet::Util::Instrumentation::Instrumentable::Probe.new(:mymethod, ProbeTest) - probe.enable - ProbeTest.new.should respond_to(:instrumented_mymethod) - end - - it "should create a new method of the original name" do - probe = Puppet::Util::Instrumentation::Instrumentable::Probe.new(:mymethod, ProbeTest) - probe.enable - ProbeTest.new.should respond_to(:mymethod) - end - end - - describe "when disabling a probe" do - it "should raise an error if the probe is already enabled" do - probe = Puppet::Util::Instrumentation::Instrumentable::Probe.new(:mymethod, ProbeTest) - lambda { probe.disable }.should raise_error - end - - it "should rename the original method name" do - probe = Puppet::Util::Instrumentation::Instrumentable::Probe.new(:mymethod, ProbeTest) - probe.enable - probe.disable - - Puppet::Util::Instrumentation.expects(:start).never - Puppet::Util::Instrumentation.expects(:stop).never - ProbeTest.new.mymethod(1,2,3).should == :it_worked - end - - it "should remove the created method" do - probe = Puppet::Util::Instrumentation::Instrumentable::Probe.new(:mymethod, ProbeTest) - probe.enable - probe.disable - ProbeTest.new.should_not respond_to(:instrumented_mymethod) - end - end - - describe "when a probe is called" do - it "should call the original method" do - probe = Puppet::Util::Instrumentation::Instrumentable::Probe.new(:mymethod, ProbeTest) - probe.enable - test = ProbeTest.new - test.expects(:instrumented_mymethod).with(1,2,3) - test.mymethod(1,2,3) - end - - it "should start the instrumentation" do - Puppet::Util::Instrumentation.expects(:start) - probe = Puppet::Util::Instrumentation::Instrumentable::Probe.new(:mymethod, ProbeTest) - probe.enable - test = ProbeTest.new - test.mymethod(1,2,3) - end - - it "should stop the instrumentation" do - Puppet::Util::Instrumentation.expects(:stop) - probe = Puppet::Util::Instrumentation::Instrumentable::Probe.new(:mymethod, ProbeTest) - probe.enable - test = ProbeTest.new - test.mymethod(1,2,3) - end - - describe "and the original method raises an exception" do - it "should propagate the exception" do - probe = Puppet::Util::Instrumentation::Instrumentable::Probe.new(:mymethod, ProbeTest) - probe.enable - test = ProbeTest.new - test.expects(:instrumented_mymethod).with(1,2,3).raises - lambda { test.mymethod(1,2,3) }.should raise_error - end - - it "should stop the instrumentation" do - Puppet::Util::Instrumentation.expects(:stop) - probe = Puppet::Util::Instrumentation::Instrumentable::Probe.new(:mymethod, ProbeTest) - probe.enable - test = ProbeTest.new - test.expects(:instrumented_mymethod).with(1,2,3).raises - lambda { test.mymethod(1,2,3) }.should raise_error - end - end - - describe "with a static label" do - it "should send the label to the instrumentation layer" do - probe = Puppet::Util::Instrumentation::Instrumentable::Probe.new(:mymethod, ProbeTest, :label => :mylabel) - probe.enable - test = ProbeTest.new - Puppet::Util::Instrumentation.expects(:start).with { |label,data| label == :mylabel }.returns(42) - Puppet::Util::Instrumentation.expects(:stop).with(:mylabel, 42, {}) - test.mymethod(1,2,3) - end - end - - describe "with a dynamic label" do - it "should send the evaluated label to the instrumentation layer" do - probe = Puppet::Util::Instrumentation::Instrumentable::Probe.new(:mymethod, ProbeTest, :label => Proc.new { |parent,args| "dynamic#{args[0]}" } ) - probe.enable - test = ProbeTest.new - Puppet::Util::Instrumentation.expects(:start).with { |label,data| label == "dynamic1" }.returns(42) - Puppet::Util::Instrumentation.expects(:stop).with("dynamic1",42,{}) - test.mymethod(1,2,3) - end - end - - describe "with static data" do - it "should send the data to the instrumentation layer" do - probe = Puppet::Util::Instrumentation::Instrumentable::Probe.new(:mymethod, ProbeTest, :data => { :static_data => "nothing" }) - probe.enable - test = ProbeTest.new - Puppet::Util::Instrumentation.expects(:start).with { |label,data| data == { :static_data => "nothing" }} - test.mymethod(1,2,3) - end - end - - describe "with dynamic data" do - it "should send the evaluated label to the instrumentation layer" do - probe = Puppet::Util::Instrumentation::Instrumentable::Probe.new(:mymethod, ProbeTest, :data => Proc.new { |parent, args| { :key => args[0] } } ) - probe.enable - test = ProbeTest.new - Puppet::Util::Instrumentation.expects(:start).with { |label,data| data == { :key => 1 } } - Puppet::Util::Instrumentation.expects(:stop) - test.mymethod(1,2,3) - end - end - end -end - -describe Puppet::Util::Instrumentation::Instrumentable do - before(:each) do - class ProbeTest2 - extend Puppet::Util::Instrumentation::Instrumentable - probe :mymethod - def mymethod(arg1,arg2,arg3) - end - end - end - - after do - Puppet::Util::Instrumentation::Instrumentable.clear_probes - end - - it "should allow probe definition" do - Puppet::Util::Instrumentation::Instrumentable.probe_names.should be_include("ProbeTest2.mymethod") - end - - it "should be able to enable all probes" do - Puppet::Util::Instrumentation::Instrumentable.enable_probes - ProbeTest2.new.should respond_to(:instrumented_mymethod) - end -end diff --git a/spec/unit/util/instrumentation/listener_spec.rb b/spec/unit/util/instrumentation/listener_spec.rb deleted file mode 100755 index 344934908..000000000 --- a/spec/unit/util/instrumentation/listener_spec.rb +++ /dev/null @@ -1,101 +0,0 @@ -#! /usr/bin/env ruby - -require 'spec_helper' -require 'matchers/json' - -require 'puppet/util/instrumentation' -require 'puppet/util/instrumentation/listener' - -describe Puppet::Util::Instrumentation::Listener do - include JSONMatchers - - Listener = Puppet::Util::Instrumentation::Listener - - before(:each) do - @delegate = stub 'listener', :notify => nil, :name => 'listener' - @listener = Listener.new(@delegate) - @listener.enabled = true - end - - it "should indirect instrumentation_listener" do - Listener.indirection.name.should == :instrumentation_listener - end - - it "should raise an error if delegate doesn't support notify" do - lambda { Listener.new(Object.new) }.should raise_error - end - - it "should not be enabled by default" do - Listener.new(@delegate).should_not be_enabled - end - - it "should delegate notification" do - @delegate.expects(:notify).with(:event, :start, {}) - listener = Listener.new(@delegate) - listener.notify(:event, :start, {}) - end - - it "should not listen is not enabled" do - @listener.enabled = false - @listener.should_not be_listen_to(:label) - end - - it "should listen to all label if created without pattern" do - @listener.should be_listen_to(:improbable_label) - end - - it "should listen to specific string pattern" do - listener = Listener.new(@delegate, "specific") - listener.enabled = true - listener.should be_listen_to(:specific) - end - - it "should not listen to non-matching string pattern" do - listener = Listener.new(@delegate, "specific") - listener.enabled = true - listener.should_not be_listen_to(:unspecific) - end - - it "should listen to specific regex pattern" do - listener = Listener.new(@delegate, /spe.*/) - listener.enabled = true - listener.should be_listen_to(:specific_pattern) - end - - it "should not listen to non matching regex pattern" do - listener = Listener.new(@delegate, /^match.*/) - listener.enabled = true - listener.should_not be_listen_to(:not_matching) - end - - it "should delegate its name to the underlying listener" do - @delegate.expects(:name).returns("myname") - @listener.name.should == "myname" - end - - it "should delegate data fetching to the underlying listener" do - @delegate.expects(:data).returns(:data) - @listener.data.should == {:data => :data } - end - - describe "when serializing to pson" do - it "should return a pson object containing pattern, name and status" do - @listener.should set_json_attribute('enabled').to(true) - @listener.should set_json_attribute('name').to("listener") - end - end - - describe "when deserializing from pson" do - it "should lookup the archetype listener from the instrumentation layer" do - Puppet::Util::Instrumentation.expects(:[]).with("listener").returns(@listener) - Puppet::Util::Instrumentation::Listener.from_data_hash({"name" => "listener"}) - end - - it "should create a new listener shell instance delegating to the archetypal listener" do - Puppet::Util::Instrumentation.expects(:[]).with("listener").returns(@listener) - @listener.stubs(:listener).returns(@delegate) - Puppet::Util::Instrumentation::Listener.expects(:new).with(@delegate, nil, true) - Puppet::Util::Instrumentation::Listener.from_data_hash({"name" => "listener", "enabled" => true}) - end - end -end diff --git a/spec/unit/util/instrumentation/listeners/log_spec.rb b/spec/unit/util/instrumentation/listeners/log_spec.rb deleted file mode 100755 index 1274acd1d..000000000 --- a/spec/unit/util/instrumentation/listeners/log_spec.rb +++ /dev/null @@ -1,34 +0,0 @@ -require 'spec_helper' -require 'puppet/util/instrumentation' - -Puppet::Util::Instrumentation.init -log = Puppet::Util::Instrumentation.listener(:log) - -describe log do - before(:each) do - @log = log.new - end - - it "should have a notify method" do - @log.should respond_to(:notify) - end - - it "should have a data method" do - @log.should respond_to(:data) - end - - it "should keep data for stop event" do - @log.notify(:test, :stop, { :started => Time.at(123456789), :finished => Time.at(123456790)}) - @log.data.should == {:test=>["test took 1.0"]} - end - - it "should not keep data for start event" do - @log.notify(:test, :start, { :started => Time.at(123456789)}) - @log.data.should be_empty - end - - it "should not keep more than 20 events per label" do - 25.times { @log.notify(:test, :stop, { :started => Time.at(123456789), :finished => Time.at(123456790)}) } - @log.data[:test].size.should == 20 - end -end diff --git a/spec/unit/util/instrumentation/listeners/performance_spec.rb b/spec/unit/util/instrumentation/listeners/performance_spec.rb deleted file mode 100755 index 519de5e90..000000000 --- a/spec/unit/util/instrumentation/listeners/performance_spec.rb +++ /dev/null @@ -1,36 +0,0 @@ -require 'spec_helper' -require 'puppet/util/instrumentation' - -Puppet::Util::Instrumentation.init -performance = Puppet::Util::Instrumentation.listener(:performance) - -describe performance do - before(:each) do - @performance = performance.new - end - - it "should have a notify method" do - @performance.should respond_to(:notify) - end - - it "should have a data method" do - @performance.should respond_to(:data) - end - - it "should keep data for stop event" do - @performance.notify(:test, :stop, { :started => Time.at(123456789), :finished => Time.at(123456790)}) - @performance.data.should == {:test=>{:average=>1.0, :count=>1, :min=>1.0, :max=>1.0, :sum=>1.0}} - end - - it "should accumulate performance statistics" do - @performance.notify(:test, :stop, { :started => Time.at(123456789), :finished => Time.at(123456790)}) - @performance.notify(:test, :stop, { :started => Time.at(123456789), :finished => Time.at(123456791)}) - - @performance.data.should == {:test=>{:average=>1.5, :count=>2, :min=>1.0, :max=>2.0, :sum=>3.0}} - end - - it "should not keep data for start event" do - @performance.notify(:test, :start, { :started => Time.at(123456789)}) - @performance.data.should be_empty - end -end diff --git a/spec/unit/util/instrumentation_spec.rb b/spec/unit/util/instrumentation_spec.rb deleted file mode 100755 index 978ef7735..000000000 --- a/spec/unit/util/instrumentation_spec.rb +++ /dev/null @@ -1,181 +0,0 @@ -#! /usr/bin/env ruby - -require 'spec_helper' - -require 'puppet/util/instrumentation' - -describe Puppet::Util::Instrumentation do - - Instrumentation = Puppet::Util::Instrumentation - - after(:each) do - Instrumentation.clear - end - - it "should instance-load instrumentation listeners" do - Instrumentation.instance_loader(:listener).should be_instance_of(Puppet::Util::Autoload) - end - - it "should have a method for registering instrumentation listeners" do - Instrumentation.should respond_to(:new_listener) - end - - it "should have a method for retrieving instrumentation listener by name" do - Instrumentation.should respond_to(:listener) - end - - describe "when registering listeners" do - it "should evaluate the supplied block as code for a class" do - Instrumentation.expects(:genclass).returns(Class.new { def notify(label, event, data) ; end }) - Instrumentation.new_listener(:testing, :label_pattern => :for_this_label, :event => :all) { } - end - - it "should subscribe a new listener instance" do - Instrumentation.expects(:genclass).returns(Class.new { def notify(label, event, data) ; end }) - Instrumentation.new_listener(:testing, :label_pattern => :for_this_label, :event => :all) { } - Instrumentation.listeners.size.should == 1 - Instrumentation.listeners[0].pattern.should == "for_this_label" - end - - it "should be possible to access listeners by name" do - Instrumentation.expects(:genclass).returns(Class.new { def notify(label, event, data) ; end }) - Instrumentation.new_listener(:testing, :label_pattern => :for_this_label, :event => :all) { } - Instrumentation["testing"].should_not be_nil - end - - it "should be possible to store a new listener by name" do - listener = stub 'listener' - Instrumentation["testing"] = listener - Instrumentation["testing"].should == listener - end - - it "should fail if listener is already subscribed" do - listener = stub 'listener', :notify => nil, :name => "mylistener" - Instrumentation.subscribe(listener, :for_this_label, :all) - expect { Instrumentation.subscribe(listener, :for_this_label, :all) }.to raise_error - end - - it 'should call #unsubscribed' do - listener = stub 'listener', :notify => nil, :name => "mylistener" - - listener.expects(:subscribed) - - Instrumentation.subscribe(listener, :for_this_label, :all) - end - end - - describe "when unsubscribing listener" do - it "should remove it from the listeners" do - listener = stub 'listener', :notify => nil, :name => "mylistener" - Instrumentation.subscribe(listener, :for_this_label, :all) - Instrumentation.unsubscribe(listener) - Instrumentation.listeners.size.should == 0 - end - - it "should warn if the listener wasn't subscribed" do - listener = stub 'listener', :notify => nil, :name => "mylistener" - Puppet.expects(:warning) - Instrumentation.unsubscribe(listener) - end - - it 'should call #unsubscribed' do - listener = stub 'listener', :notify => nil, :name => "mylistener" - Instrumentation.subscribe(listener, :for_this_label, :all) - - listener.expects(:unsubscribed) - - Instrumentation.unsubscribe(listener) - end - end - - describe "when firing events" do - it "should be able to find all listeners matching a label" do - listener = stub 'listener', :notify => nil, :name => "mylistener" - Instrumentation.subscribe(listener, :for_this_label, :all) - Instrumentation.listeners[0].enabled = true - - count = 0 - Instrumentation.each_listener(:for_this_label) { |l| count += 1 } - count.should == 1 - end - - it "should fire events to matching listeners" do - listener = stub 'listener', :notify => nil, :name => "mylistener" - Instrumentation.subscribe(listener, :for_this_label, :all) - Instrumentation.listeners[0].enabled = true - - listener.expects(:notify).with(:for_this_label, :start, {}) - - Instrumentation.publish(:for_this_label, :start, {}) - end - - it "should not fire events to non-matching listeners" do - listener1 = stub 'listener1', :notify => nil, :name => "mylistener1" - listener2 = stub 'listener2', :notify => nil, :name => "mylistener2" - Instrumentation.subscribe(listener1, :for_this_label, :all) - Instrumentation.listeners[0].enabled = true - Instrumentation.subscribe(listener2, :for_this_other_label, :all) - Instrumentation.listeners[1].enabled = true - - listener1.expects(:notify).never - listener2.expects(:notify).with(:for_this_other_label, :start, {}) - - Instrumentation.publish(:for_this_other_label, :start, {}) - end - end - - describe "when instrumenting code" do - before(:each) do - Instrumentation.stubs(:publish) - end - describe "with a block" do - it "should execute it" do - executed = false - Instrumentation.instrument(:event) do - executed = true - end - executed.should be_true - end - - it "should publish an event before execution" do - Instrumentation.expects(:publish).with { |label,event,data| label == :event && event == :start } - Instrumentation.instrument(:event) {} - end - - it "should publish an event after execution" do - Instrumentation.expects(:publish).with { |label,event,data| label == :event && event == :stop } - Instrumentation.instrument(:event) {} - end - - it "should publish the event even when block raised an exception" do - Instrumentation.expects(:publish).with { |label,event,data| label == :event } - lambda { Instrumentation.instrument(:event) { raise "not working" } }.should raise_error - end - - it "should retain start end finish time of the event" do - Instrumentation.expects(:publish).with { |label,event,data| data.include?(:started) and data.include?(:finished) } - Instrumentation.instrument(:event) {} - end - end - - describe "without a block" do - it "should raise an error if stop is called with no matching start" do - lambda{ Instrumentation.stop(:event) }.should raise_error - end - - it "should publish an event on stop" do - Instrumentation.expects(:publish).with { |label,event,data| event == :start } - Instrumentation.expects(:publish).with { |label,event,data| event == :stop and data.include?(:started) and data.include?(:finished) } - data = {} - Instrumentation.start(:event, data) - Instrumentation.stop(:event, 1, data) - end - - it "should return a different id per event" do - data = {} - Instrumentation.start(:event, data).should == 1 - Instrumentation.start(:event, data).should == 2 - end - end - end -end diff --git a/tasks/manpages.rake b/tasks/manpages.rake index f0aa673e2..f3a927596 100644 --- a/tasks/manpages.rake +++ b/tasks/manpages.rake @@ -1,84 +1,75 @@ # require 'fileutils' desc "Build Puppet manpages" task :gen_manpages do require 'puppet/face' require 'fileutils' # TODO: this line is unfortunate. In an ideal world, faces would serve # as a clear, well-defined entry-point into the code and could be # responsible for state management all on their own; this really should # not be necessary. When we can, we should get rid of it. # --cprice 2012-05-16 Puppet.initialize_settings() helpface = Puppet::Face[:help, '0.0.1'] manface = Puppet::Face[:man, '0.0.1'] - # TODO: This line is terrible. The reason we need this here is because we - # handle state initialization differently when we run via command line - # (application.rb) than we do when we try to use Faces as library code. - # This is bad, we need to come up with an official stance on what our - # API is and what the entry points, so that we can make sure that - # state initialization is consistent. See: - # http://projects.puppetlabs.com/issues/14441 - Puppet::Util::Instrumentation.init() - sbins = Dir.glob(%w{sbin/*}) bins = Dir.glob(%w{bin/*}) non_face_applications = helpface.legacy_applications faces = Puppet::Face.faces ronn_args = '--manual="Puppet manual" --organization="Puppet Labs, LLC" -r' # Locate ronn ronn = %x{which ronn}.chomp unless File.executable?(ronn) then fail("Ronn does not appear to be installed.") end # def write_manpage(text, filename) # IO.popen("#{ronn} #{ronn_args} -r > #{filename}") do |fh| fh.write text end # end # Create puppet.conf.5 man page # IO.popen("#{ronn} #{ronn_args} > ./man/man5/puppet.conf.5", 'w') do |fh| # fh.write %x{RUBYLIB=./lib:$RUBYLIB bin/puppetdoc --reference configuration} # end %x{RUBYLIB=./lib:$RUBYLIB bin/puppet doc --reference configuration > ./man/man5/puppetconf.5.ronn} %x{#{ronn} #{ronn_args} ./man/man5/puppetconf.5.ronn} FileUtils.mv("./man/man5/puppetconf.5", "./man/man5/puppet.conf.5") FileUtils.rm("./man/man5/puppetconf.5.ronn") # Create LEGACY binary man pages (i.e. delete me for 2.8.0) binary = bins + sbins binary.each do |bin| b = bin.gsub( /^s?bin\//, "") %x{RUBYLIB=./lib:$RUBYLIB #{bin} --help > ./man/man8/#{b}.8.ronn} %x{#{ronn} #{ronn_args} ./man/man8/#{b}.8.ronn} FileUtils.rm("./man/man8/#{b}.8.ronn") end # Create regular non-face man pages non_face_applications.each do |app| %x{RUBYLIB=./lib:$RUBYLIB bin/puppet #{app} --help > ./man/man8/puppet-#{app}.8.ronn} %x{#{ronn} #{ronn_args} ./man/man8/puppet-#{app}.8.ronn} FileUtils.rm("./man/man8/puppet-#{app}.8.ronn") end # Create face man pages faces.each do |face| File.open("./man/man8/puppet-#{face}.8.ronn", 'w') do |fh| fh.write manface.man("#{face}") end %x{#{ronn} #{ronn_args} ./man/man8/puppet-#{face}.8.ronn} FileUtils.rm("./man/man8/puppet-#{face}.8.ronn") end # Vile hack: create puppet resource man page # Currently, the useless resource face wins against puppet resource in puppet # man. (And actually, it even gets removed from the list of legacy # applications.) So we overwrite it with the correct man page at the end. %x{RUBYLIB=./lib:$RUBYLIB bin/puppet resource --help > ./man/man8/puppet-resource.8.ronn} %x{#{ronn} #{ronn_args} ./man/man8/puppet-resource.8.ronn} FileUtils.rm("./man/man8/puppet-resource.8.ronn") end