diff options
741 files changed, 12649 insertions, 8152 deletions
@@ -49,5 +49,5 @@ end desc "Run the unit tests" task :unit do - sh "cd test; rake" + Dir.chdir("test") { sh "rake" } end diff --git a/ext/cert_inspector b/ext/cert_inspector new file mode 100755 index 000000000..1effcaa04 --- /dev/null +++ b/ext/cert_inspector @@ -0,0 +1,140 @@ +#!/usr/bin/env ruby +require 'openssl' + +class X509Collector + include Enumerable + + def initialize + @collected_data = {} + end + + def interpret_contents(contents) + cls = case contents.split("\n")[0] + when /BEGIN X509 CRL/ then OpenSSL::X509::CRL + when /BEGIN CERTIFICATE REQUEST/ then OpenSSL::X509::Request + when /BEGIN CERTIFICATE/ then OpenSSL::X509::Certificate + when /BEGIN RSA (PRIVATE|PUBLIC) KEY/ then OpenSSL::PKey::RSA + else return nil + end + cls.new(contents) + rescue + nil + end + + def expected_non_x509_files + ['inventory.txt', 'ca.pass', 'serial'] + end + + def investigate_path(path) + if File.directory?(path) + Dir.foreach(path) do |x| + next if ['.', '..'].include? x + investigate_path File.join(path, x) + end + else + contents = File.read path + meaning = interpret_contents contents + unless meaning || expected_non_x509_files.include?(File.basename(path)) + puts "WARNING: file #{path.inspect} could not be interpreted" + end + @collected_data[path] = meaning if meaning + end + end + + def each(&block) + @collected_data.each(&block) + end + + def extract_public_key_info(path, meaning) + case meaning + when OpenSSL::PKey::RSA + if meaning.private? + [meaning.public_key, 2, path] + else + [meaning, 3, path] + end + when OpenSSL::X509::Certificate + [meaning.public_key, 0, meaning.subject.to_s] + when OpenSSL::X509::Request + [meaning.public_key, 1, meaning.subject.to_s] + end + end + + def who_signed(meaning, key_names, keys) + signing_key = keys.find { |key| meaning.verify(key) } + if signing_key then "#{key_names[signing_key.to_s]}" else "???" end + end + + def explain(meaning, key_names, keys) + case meaning + when OpenSSL::PKey::RSA + if meaning.private? + "Private key for #{key_names[meaning.public_key.to_s]}" + else + "Public key for #{key_names[meaning.public_key.to_s]}" + end + when OpenSSL::X509::Certificate + signature_desc = who_signed(meaning, key_names, keys) + "Certificate assigning name #{meaning.subject.to_s} to #{key_names[meaning.public_key.to_s]}\n serial number #{meaning.serial}\n issued by #{meaning.issuer.to_s}\n signed by #{signature_desc}" + when OpenSSL::X509::Request + signature_desc = who_signed(meaning, key_names, keys) + "Certificate request for #{meaning.subject.to_s} having key #{key_names[meaning.public_key.to_s]}\n signed by #{signature_desc}" + when OpenSSL::X509::CRL + signature_desc = who_signed(meaning, key_names, keys) + revoked_serial_numbers = meaning.revoked.map { |r| r.serial } + revoked_desc = if revoked_serial_numbers.count > 0 then "serial numbers #{revoked_serial_numbers.inspect}" else "nothing" end + "Certificate revocation list revoking #{revoked_desc}\n issued by #{meaning.issuer.to_s}\n signed by #{signature_desc}" + else + "Unknown" + end + end + + # Yield unique public keys, with a canonical name for each. + def collect_public_keys + key_data = {} # pem => (priority, name, public_key) + @collected_data.collect do |path, meaning| + begin + next unless public_key_info = extract_public_key_info(path, meaning) + public_key, priority, name = public_key_info + pem = public_key.to_s + existing_priority, existing_name, existing_public_key = key_data[pem] + next if existing_priority and existing_priority < priority + key_data[pem] = priority, name, public_key + rescue + puts "exception!" + end + end + name_to_key_hash = {} + key_data.each do |pem, data| + priority, name, public_key = data + if name_to_key_hash[name] + suffix_num = 2 + while name_to_key_hash[name + " (#{suffix_num})"] + suffix_num += 1 + end + name = name + " (#{suffix_num})" + end + name_to_key_hash[name] = public_key + end + key_names = {} + keys = [] + name_to_key_hash.each do |name, public_key| + key_names[public_key.to_s] = "key<#{name}>" + keys << public_key + end + [key_names, keys] + end +end + +collector = X509Collector.new +ARGV.each do |path| + collector.investigate_path(path) +end +key_names, keys = collector.collect_public_keys +collector.map do |path, meaning| + [collector.explain(meaning, key_names, keys), path] +end.sort.each do |description, path| + puts "#{path}:" + puts " #{description}" + puts +end diff --git a/install.rb b/install.rb index 351ba25d2..6bf4f5587 100755 --- a/install.rb +++ b/install.rb @@ -53,18 +53,6 @@ rescue LoadError $haverdoc = false end -begin - if $haverdoc - ronn = %x{which ronn} - $haveman = true - else - $haveman = false - end -rescue - puts "Missing ronn; skipping man page creation" - $haveman = false -end - PREREQS = %w{openssl facter xmlrpc/client xmlrpc/server cgi} MIN_FACTER_VERSION = 1.5 @@ -182,15 +170,6 @@ def prepare_installation end - if $haveman - InstallOptions.man = true - if $operatingsystem == "windows" - InstallOptions.man = false - end - else - InstallOptions.man = false - end - InstallOptions.tests = true ARGV.options do |opts| @@ -202,9 +181,6 @@ def prepare_installation opts.on('--[no-]ri', 'Prevents the creation of RI output.', 'Default off on mswin32.') do |onri| InstallOptions.ri = onri end - opts.on('--[no-]man', 'Prevents the creation of man pages.', 'Default on.') do |onman| - InstallOptions.man = onman - end opts.on('--[no-]tests', 'Prevents the execution of unit tests.', 'Default on.') do |ontest| InstallOptions.tests = ontest end @@ -237,7 +213,6 @@ def prepare_installation end opts.on('--full', 'Performs a full installation. All', 'optional installation steps are run.') do |full| InstallOptions.rdoc = true - InstallOptions.man = true InstallOptions.ri = true InstallOptions.tests = true InstallOptions.configs = true @@ -367,33 +342,6 @@ def build_ri(files) end end -def build_man(bins, sbins) - return unless $haveman - begin - # Locate ronn - ronn = %x{which ronn} - ronn.chomp! - # Create puppet.conf.5 man page - %x{bin/puppetdoc --reference configuration > ./man/man5/puppetconf.5.ronn} - %x{#{ronn} -r ./man/man5/puppetconf.5.ronn} - File.move("./man/man5/puppetconf.5", "./man/man5/puppet.conf.5") - File.unlink("./man/man5/puppetconf.5.ronn") - - # Create binary man pages - binary = bins + sbins - binary.each do |bin| - b = bin.gsub( /(bin|sbin)\//, "") - %x{#{bin} --help > ./man/man8/#{b}.8.ronn} - %x{#{ronn} -r ./man/man8/#{b}.8.ronn} - File.unlink("./man/man8/#{b}.8.ronn") - end - -rescue SystemCallError - $stderr.puts "Couldn't build man pages: " + $ERROR_INFO - $stderr.puts "Continuing with install..." - end -end - def run_tests(test_list) require 'test/unit/ui/console/testrunner' $LOAD_PATH.unshift "lib" @@ -487,7 +435,6 @@ prepare_installation #run_tests(tests) if InstallOptions.tests #build_rdoc(rdoc) if InstallOptions.rdoc #build_ri(ri) if InstallOptions.ri -#build_man(bins, sbins) if InstallOptions.man do_configs(configs, InstallOptions.config_dir) if InstallOptions.configs do_bins(sbins, InstallOptions.sbin_dir) do_bins(bins, InstallOptions.bin_dir) diff --git a/lib/puppet/application.rb b/lib/puppet/application.rb index a028a158f..57bd88877 100644 --- a/lib/puppet/application.rb +++ b/lib/puppet/application.rb @@ -251,7 +251,8 @@ class Application # Every app responds to --help option("--help", "-h") do |v| - help + puts help + exit end def should_parse_config? @@ -386,23 +387,7 @@ class Application end def help - if Puppet.features.usage? - # RH:FIXME: My goodness, this is ugly. - ::RDoc.const_set("PuppetSourceFile", name) - #:stopdoc: # Issue #4161 - def (::RDoc).caller - docfile = `grep -l 'Puppet::Application\\[:#{::RDoc::PuppetSourceFile}\\]' #{DOCPATTERN}`.chomp - super << "#{docfile}:0" - end - #:startdoc: - ::RDoc::usage && exit - else - puts "No help available unless you have RDoc::usage installed" - exit - end - rescue Errno::ENOENT - puts "No help available for puppet #{name}" - exit + "No help available for puppet #{name}" end private diff --git a/lib/puppet/application/agent.rb b/lib/puppet/application/agent.rb index 9f5921de1..2ee40227e 100644 --- a/lib/puppet/application/agent.rb +++ b/lib/puppet/application/agent.rb @@ -83,6 +83,217 @@ class Puppet::Application::Agent < Puppet::Application @args[:Port] = arg end + def help + <<-HELP + +puppet-agent(8) -- The puppet agent daemon +======== + +SYNOPSIS +-------- +Retrieves the client configuration from the puppet master and applies it to +the local host. + +This service may be run as a daemon, run periodically using cron (or something +similar), or run interactively for testing purposes. + + +USAGE +----- +puppet agent [-D|--daemonize|--no-daemonize] [-d|--debug] + [--detailed-exitcodes] [--disable] [--enable] [-h|--help] + [--certname <host name>] [-l|--logdest syslog|<file>|console] + [-o|--onetime] [--serve <handler>] [-t|--test] [--noop] + [--digest <digest>] [--fingerprint] [-V|--version] + [-v|--verbose] [-w|--waitforcert <seconds>] + + +DESCRIPTION +----------- +This is the main puppet client. Its job is to retrieve the local +machine's configuration from a remote server and apply it. In order to +successfully communicate with the remote server, the client must have a +certificate signed by a certificate authority that the server trusts; +the recommended method for this, at the moment, is to run a certificate +authority as part of the puppet server (which is the default). The +client will connect and request a signed certificate, and will continue +connecting until it receives one. + +Once the client has a signed certificate, it will retrieve its +configuration and apply it. + + +USAGE NOTES +----------- +'puppet agent' does its best to find a compromise between interactive +use and daemon use. Run with no arguments and no configuration, it will +go into the background, attempt to get a signed certificate, and retrieve +and apply its configuration every 30 minutes. + +Some flags are meant specifically for interactive use -- in particular, +'test', 'tags' or 'fingerprint' are useful. 'test' enables verbose +logging, causes the daemon to stay in the foreground, exits if the +server's configuration is invalid (this happens if, for instance, you've +left a syntax error on the server), and exits after running the +configuration once (rather than hanging around as a long-running +process). + +'tags' allows you to specify what portions of a configuration you want +to apply. Puppet elements are tagged with all of the class or definition +names that contain them, and you can use the 'tags' flag to specify one +of these names, causing only configuration elements contained within +that class or definition to be applied. This is very useful when you are +testing new configurations -- for instance, if you are just starting to +manage 'ntpd', you would put all of the new elements into an 'ntpd' +class, and call puppet with '--tags ntpd', which would only apply that +small portion of the configuration during your testing, rather than +applying the whole thing. + +'fingerprint' is a one-time flag. In this mode 'puppet agent' will run +once and display on the console (and in the log) the current certificate +(or certificate request) fingerprint. Providing the '--digest' option +allows to use a different digest algorithm to generate the fingerprint. +The main use is to verify that before signing a certificate request on +the master, the certificate request the master received is the same as +the one the client sent (to prevent against man-in-the-middle attacks +when signing certificates). + + +OPTIONS +------- +Note that any configuration parameter that's valid in the configuration +file is also a valid long argument. For example, 'server' is a valid +configuration parameter, so you can specify '--server <servername>' as +an argument. + +See the configuration file documentation at +http://docs.puppetlabs.com/references/stable/configuration.html for the +full list of acceptable parameters. A commented list of all +configuration options can also be generated by running puppet agent with +'--genconfig'. + +* --daemonize: + Send the process into the background. This is the default. + +* --no-daemonize: + Do not send the process into the background. + +* --debug: + Enable full debugging. + +* --digest: + Change the certificate fingerprinting digest algorithm. The default is + MD5. Valid values depends on the version of OpenSSL installed, but + should always at least contain MD5, MD2, SHA1 and SHA256. + +* --detailed-exitcodes: + Provide transaction information via exit codes. If this is enabled, an + exit code of '2' means there were changes, and an exit code of '4' + means that there were failures during the transaction. This option + only makes sense in conjunction with --onetime. + +* --disable: + Disable working on the local system. This puts a lock file in place, + causing 'puppet agent' not to work on the system until the lock file + is removed. This is useful if you are testing a configuration and do + not want the central configuration to override the local state until + everything is tested and committed. + + 'puppet agent' uses the same lock file while it is running, so no more + than one 'puppet agent' process is working at a time. + + 'puppet agent' exits after executing this. + +* --enable: + Enable working on the local system. This removes any lock file, + causing 'puppet agent' to start managing the local system again + (although it will continue to use its normal scheduling, so it might + not start for another half hour). + + 'puppet agent' exits after executing this. + +* --certname: + Set the certname (unique ID) of the client. The master reads this + unique identifying string, which is usually set to the node's + fully-qualified domain name, to determine which configurations the + node will receive. Use this option to debug setup problems or + implement unusual node identification schemes. + +* --help: + Print this help message + +* --logdest: + Where to send messages. Choose between syslog, the console, and a log + file. Defaults to sending messages to syslog, or the console if + debugging or verbosity is enabled. + +* --no-client: + Do not create a config client. This will cause the daemon to run + without ever checking for its configuration automatically, and only + makes sense + +* --onetime: + Run the configuration once. Runs a single (normally daemonized) Puppet + run. Useful for interactively running puppet agent when used in + conjunction with the --no-daemonize option. + +* --fingerprint: + Display the current certificate or certificate signing request + fingerprint and then exit. Use the '--digest' option to change the + digest algorithm used. + +* --serve: + Start another type of server. By default, 'puppet agent' will start a + service handler that allows authenticated and authorized remote nodes + to trigger the configuration to be pulled down and applied. You can + specify any handler here that does not require configuration, e.g., + filebucket, ca, or resource. The handlers are in + 'lib/puppet/network/handler', and the names must match exactly, both + in the call to 'serve' and in 'namespaceauth.conf'. + +* --test: + Enable the most common options used for testing. These are 'onetime', + 'verbose', 'ignorecache', 'no-daemonize', 'no-usecacheonfailure', + 'detailed-exit-codes', 'no-splay', and 'show_diff'. + +* --noop: + Use 'noop' mode where the daemon runs in a no-op or dry-run mode. This + is useful for seeing what changes Puppet will make without actually + executing the changes. + +* --verbose: + Turn on verbose reporting. + +* --version: + Print the puppet version number and exit. + +* --waitforcert: + This option only matters for daemons that do not yet have certificates + and it is enabled by default, with a value of 120 (seconds). This + causes 'puppet agent' to connect to the server every 2 minutes and ask + it to sign a certificate request. This is useful for the initial setup + of a puppet client. You can turn off waiting for certificates by + specifying a time of 0. + + +EXAMPLE +------- + $ puppet agent --server puppet.domain.com + + +AUTHOR +------ +Luke Kanies + + +COPYRIGHT +--------- +Copyright (c) 2005, 2006 Puppet Labs, LLC Licensed under the GNU Public +License + + HELP + end + def run_command return fingerprint if options[:fingerprint] return onetime if Puppet[:onetime] @@ -228,9 +439,9 @@ class Puppet::Application::Agent < Puppet::Application # access to the local files and we don't need a ca. Puppet::SSL::Host.ca_location = options[:fingerprint] ? :none : :remote - Puppet::Transaction::Report.terminus_class = :rest + Puppet::Transaction::Report.indirection.terminus_class = :rest # we want the last report to be persisted locally - Puppet::Transaction::Report.cache_class = :yaml + Puppet::Transaction::Report.indirection.cache_class = :yaml # Override the default; puppetd needs this, usually. # You can still override this on the command-line with, e.g., :compiler. @@ -239,8 +450,7 @@ class Puppet::Application::Agent < Puppet::Application # Override the default. Puppet[:facts_terminus] = :facter - Puppet::Resource::Catalog.cache_class = :yaml - + Puppet::Resource::Catalog.indirection.cache_class = :yaml # We need tomake the client either way, we just don't start it # if --no-client is set. diff --git a/lib/puppet/application/apply.rb b/lib/puppet/application/apply.rb index 7f0b95a89..2b7c9f8fb 100644 --- a/lib/puppet/application/apply.rb +++ b/lib/puppet/application/apply.rb @@ -26,6 +26,103 @@ class Puppet::Application::Apply < Puppet::Application end end + def help + <<-HELP + +puppet-apply(8) -- Apply Puppet manifests locally +======== + +SYNOPSIS +-------- +Applies a standalone Puppet manifest to the local system. + + +USAGE +----- +puppet apply [-h|--help] [-V|--version] [-d|--debug] [-v|--verbose] + [-e|--execute] [--detailed-exitcodes] [-l|--logdest <file>] + [--apply <catalog>] <file> + + +DESCRIPTION +----------- +This is the standalone puppet execution tool; use it to apply +individual manifests. + +When provided with a modulepath, via command line or config file, puppet +apply can effectively mimic the catalog that would be served by puppet +master with access to the same modules, although there are some subtle +differences. When combined with scheduling and an automated system for +pushing manifests, this can be used to implement a serverless Puppet +site. + +Most users should use 'puppet agent' and 'puppet master' for site-wide +manifests. + + +OPTIONS +------- +Note that any configuration parameter that's valid in the configuration +file is also a valid long argument. For example, 'modulepath' is a +valid configuration parameter, so you can specify '--tags <class>,<tag>' +as an argument. + +See the configuration file documentation at +http://docs.puppetlabs.com/references/stable/configuration.html for the +full list of acceptable parameters. A commented list of all +configuration options can also be generated by running puppet with +'--genconfig'. + +* --debug: + Enable full debugging. + +* --detailed-exitcodes: + Provide transaction information via exit codes. If this is enabled, an + exit code of '2' means there were changes, and an exit code of '4' + means that there were failures during the transaction. + +* --help: + Print this help message + +* --loadclasses: + Load any stored classes. 'puppet agent' caches configured classes + (usually at /etc/puppet/classes.txt), and setting this option causes + all of those classes to be set in your puppet manifest. + +* --logdest: + Where to send messages. Choose between syslog, the console, and a log + file. Defaults to sending messages to the console. + +* --execute: + Execute a specific piece of Puppet code + +* --verbose: + Print extra information. + +* --apply: + Apply a JSON catalog (such as one generated with 'puppet master --compile'). You can + either specify a JSON file or pipe in JSON from standard input. + + +EXAMPLE +------- + $ puppet apply -l /tmp/manifest.log manifest.pp + $ puppet apply --modulepath=/root/dev/modules -e "include ntpd::server" + + +AUTHOR +------ +Luke Kanies + + +COPYRIGHT +--------- +Copyright (c) 2005 Puppet Labs, LLC Licensed under the GNU Public +License + + HELP + end + def run_command if options[:catalog] apply @@ -85,12 +182,12 @@ class Puppet::Application::Apply < Puppet::Application end # Collect our facts. - unless facts = Puppet::Node::Facts.find(Puppet[:certname]) + unless facts = Puppet::Node::Facts.indirection.find(Puppet[:certname]) raise "Could not find facts for #{Puppet[:certname]}" end # Find our Node - unless node = Puppet::Node.find(Puppet[:certname]) + unless node = Puppet::Node.indirection.find(Puppet[:certname]) raise "Could not find node #{Puppet[:certname]}" end @@ -112,7 +209,7 @@ class Puppet::Application::Apply < Puppet::Application begin # Compile our catalog starttime = Time.now - catalog = Puppet::Resource::Catalog.find(node.name, :use_node => node) + catalog = Puppet::Resource::Catalog.indirection.find(node.name, :use_node => node) # Translate it to a RAL catalog catalog = catalog.to_ral @@ -149,7 +246,7 @@ class Puppet::Application::Apply < Puppet::Application end # we want the last report to be persisted locally - Puppet::Transaction::Report.cache_class = :yaml + Puppet::Transaction::Report.indirection.cache_class = :yaml if options[:debug] Puppet::Util::Log.level = :debug diff --git a/lib/puppet/application/cert.rb b/lib/puppet/application/cert.rb index ee59b7e56..f02fc893c 100644 --- a/lib/puppet/application/cert.rb +++ b/lib/puppet/application/cert.rb @@ -47,6 +47,129 @@ class Puppet::Application::Cert < Puppet::Application Puppet::Util::Log.level = :info end + def help + puts <<-HELP + +puppet-cert(8) -- Manage certificates and requests +======== + +SYNOPSIS +-------- +Standalone certificate authority. Capable of generating certificates, +but mostly used for signing certificate requests from puppet clients. + + +USAGE +----- +puppet cert [-h|--help] [-V|--version] [-d|--debug] [-v|--verbose] + [-g|--generate] [-l|--list] [-s|--sign] [-r|--revoke] [-p|--print] + [-c|--clean] [--verify] [--digest <digest>] [--fingerprint] [host] + + +DESCRIPTION +----------- +Because the puppet master service defaults to not signing client +certificate requests, this script is available for signing outstanding +requests. It can be used to list outstanding requests and then either +sign them individually or sign all of them. + + +OPTIONS +------- +Note that any configuration parameter that's valid in the configuration +file is also a valid long argument. For example, 'ssldir' is a valid +configuration parameter, so you can specify '--ssldir <directory>' as an +argument. + +See the configuration file documentation at +http://docs.puppetlabs.com/references/stable/configuration.html for the +full list of acceptable parameters. A commented list of all +configuration options can also be generated by running puppet cert with +'--genconfig'. + +* --all: + Operate on all items. Currently only makes sense with '--sign', + '--clean', or '--list'. + +* --digest: + Set the digest for fingerprinting (defaults to md5). Valid values + depends on your openssl and openssl ruby extension version, but should + contain at least md5, sha1, md2, sha256. + +* --clean: + Remove all files related to a host from puppet cert's storage. This is + useful when rebuilding hosts, since new certificate signing requests + will only be honored if puppet cert does not have a copy of a signed + certificate for that host. The certificate of the host is also + revoked. If '--all' is specified then all host certificates, both + signed and unsigned, will be removed. + +* --debug: + Enable full debugging. + +* --generate: + Generate a certificate for a named client. A certificate/keypair will + be generated for each client named on the command line. + +* --help: + Print this help message + +* --list: + List outstanding certificate requests. If '--all' is specified, signed + certificates are also listed, prefixed by '+', and revoked or invalid + certificates are prefixed by '-' (the verification outcome is printed + in parenthesis). + +* --print: + Print the full-text version of a host's certificate. + +* --fingerprint: + Print the DIGEST (defaults to md5) fingerprint of a host's + certificate. + +* --revoke: + Revoke the certificate of a client. The certificate can be specified + either by its serial number, given as a decimal number or a + hexadecimal number prefixed by '0x', or by its hostname. The + certificate is revoked by adding it to the Certificate Revocation List + given by the 'cacrl' config parameter. Note that the puppetmasterd + needs to be restarted after revoking certificates. + +* --sign: + Sign an outstanding certificate request. Unless '--all' is specified, + hosts must be listed after all flags. + +* --verbose: + Enable verbosity. + +* --version: + Print the puppet version number and exit. + +* --verify: + Verify the named certificate against the local CA certificate. + + +EXAMPLE +------- + $ puppet cert -l + culain.madstop.com + $ puppet cert -s culain.madstop.com + + +AUTHOR +------ +Luke Kanies + + +COPYRIGHT +--------- +Copyright (c) 2005 Puppet Labs, LLC Licensed under the GNU Public +License + + HELP + exit + end + def main if @all hosts = :all diff --git a/lib/puppet/application/describe.rb b/lib/puppet/application/describe.rb index e76b347f6..79643159e 100644 --- a/lib/puppet/application/describe.rb +++ b/lib/puppet/application/describe.rb @@ -180,6 +180,60 @@ class Puppet::Application::Describe < Puppet::Application option("--list", "-l") option("--meta","-m") + def help + <<-HELP + +puppet-describe(8) -- Display help about resource types +======== + +SYNOPSIS +-------- +Prints help about Puppet resource types, providers, and metaparameters. + + +USAGE +----- +puppet describe [-h|--help] [-s|--short] [-p|--providers] [-l|--list] [-m|--meta] + + +OPTIONS +------- +* --help: + Print this help text + +* --providers: + Describe providers in detail for each type + +* --list: + List all types + +* --meta: + List all metaparameters + +* --short: + List only parameters without detail + + +EXAMPLE +------- + $ puppet describe --list + $ puppet describe file --providers + $ puppet describe user -s -m + + +AUTHOR +------ +David Lutterkort + + +COPYRIGHT +--------- +Copyright (c) 2005 Puppet Labs, LLC Licensed under the GNU Public +License + + HELP + end + def preinit options[:parameters] = true end diff --git a/lib/puppet/application/doc.rb b/lib/puppet/application/doc.rb index aaefd6e75..74811919e 100644 --- a/lib/puppet/application/doc.rb +++ b/lib/puppet/application/doc.rb @@ -1,7 +1,6 @@ require 'puppet/application' class Puppet::Application::Doc < Puppet::Application - should_not_parse_config run_mode :master @@ -50,6 +49,99 @@ class Puppet::Application::Doc < Puppet::Application options[:references] << arg.intern end + def help + <<-HELP + +puppet-doc(8) -- Generate Puppet documentation and references +======== + +SYNOPSIS +-------- +Generates a reference for all Puppet types. Largely meant for internal +Puppet Labs use. + + +USAGE +----- +puppet doc [-a|--all] [-h|--help] [-o|--outputdir <rdoc-outputdir>] + [-m|--mode text|pdf|rdoc] [-r|--reference <reference-name>] + [--charset <charset>] [<manifest-file>] + + +DESCRIPTION +----------- +If mode is not 'rdoc', then this command generates a Markdown document +describing all installed Puppet types or all allowable arguments to +puppet executables. It is largely meant for internal use and is used to +generate the reference document available on the Puppet Labs web site. + +In 'rdoc' mode, this command generates an html RDoc hierarchy describing +the manifests that are in 'manifestdir' and 'modulepath' configuration +directives. The generated documentation directory is doc by default but +can be changed with the 'outputdir' option. + +If the command is run with the name of a manifest file as an argument, +puppet doc will output a single manifest's documentation on stdout. + + +OPTIONS +------- +* --all: + Output the docs for all of the reference types. In 'rdoc' + modes, this also outputs documentation for all resources + +* --help: + Print this help message + +* --outputdir: + Specifies the directory where to output the rdoc + documentation in 'rdoc' mode. + +* --mode: + Determine the output mode. Valid modes are 'text', 'pdf' and + 'rdoc'. The 'pdf' mode creates PDF formatted files in the + /tmp directory. The default mode is 'text'. In 'rdoc' mode + you must provide 'manifests-path' + +* --reference: + Build a particular reference. Get a list of references by + running 'puppet doc --list'. + +* --charset: + Used only in 'rdoc' mode. It sets the charset used in the + html files produced. + + +EXAMPLE +------- + $ puppet doc -r type > /tmp/type_reference.markdown + +or + + $ puppet doc --outputdir /tmp/rdoc --mode rdoc /path/to/manifests + +or + + $ puppet doc /etc/puppet/manifests/site.pp + +or + + $ puppet doc -m pdf -r configuration + + +AUTHOR +------ +Luke Kanies + + +COPYRIGHT +--------- +Copyright (c) 2005-2007 Puppet Labs, LLC Licensed under the GNU Public +License + +HELP + end + def handle_unknown( opt, arg ) @unknown_args << {:opt => opt, :arg => arg } true @@ -70,11 +162,6 @@ class Puppet::Application::Doc < Puppet::Application files += command_line.args Puppet.info "scanning: #{files.inspect}" - Puppet.settings.setdefaults( - "puppetdoc", - - "document_all" => [false, "Document all resources"] - ) Puppet.settings[:document_all] = options[:all] || false begin require 'puppet/util/rdoc' diff --git a/lib/puppet/application/filebucket.rb b/lib/puppet/application/filebucket.rb index 5c91c4f64..063d97db8 100644 --- a/lib/puppet/application/filebucket.rb +++ b/lib/puppet/application/filebucket.rb @@ -12,6 +12,109 @@ class Puppet::Application::Filebucket < Puppet::Application attr :args + def help + <<-HELP + +puppet-filebucket(8) -- Store and retrieve files in a filebucket +======== + +SYNOPSIS +-------- +A stand-alone Puppet filebucket client. + + +USAGE +----- +puppet filebucket <mode> [-h|--help] [-V|--version] [-d|--debug] + [-v|--verbose] [-l|--local] [-r|--remote] [-s|--server <server>] + [-b|--bucket <directory>] <file> <file> ... + +Puppet filebucket can operate in three modes, with only one mode per call: + +backup: + Send one or more files to the specified file bucket. Each sent file is + printed with its resulting md5 sum. + +get: + Return the text associated with an md5 sum. The text is printed to + stdout, and only one file can be retrieved at a time. + +restore: + Given a file path and an md5 sum, store the content associated with + the sum into the specified file path. You can specify an entirely new + path to this argument; you are not restricted to restoring the content + to its original location. + + +DESCRIPTION +----------- +This is a stand-alone filebucket client for sending files to a local or +central filebucket. + +Note that 'filebucket' defaults to using a network-based filebucket +available on the server named 'puppet'. To use this, you'll have to be +running as a user with valid Puppet certificates. Alternatively, you can +use your local file bucket by specifying '--local'. + + +OPTIONS +------- +Note that any configuration parameter that's valid in the configuration +file is also a valid long argument. For example, 'ssldir' is a valid +configuration parameter, so you can specify '--ssldir <directory>' as an +argument. + +See the configuration file documentation at +http://docs.puppetlabs.com/references/stable/configuration.html for the +full list of acceptable parameters. A commented list of all +configuration options can also be generated by running puppet with +'--genconfig'. + +* --debug: + Enable full debugging. + +* --help: + Print this help message + +* --local: + Use the local filebucket. This will use the default configuration + information. + +* --remote: + Use a remote filebucket. This will use the default configuration + information. + +* --server: + The server to send the file to, instead of locally. + +* --verbose: + Print extra information. + +* --version: + Print version information. + + +EXAMPLE +------- + $ puppet filebucket backup /etc/passwd + /etc/passwd: 429b225650b912a2ee067b0a4cf1e949 + $ puppet filebucket restore /tmp/passwd 429b225650b912a2ee067b0a4cf1e949 + + +AUTHOR +------ +Luke Kanies + + +COPYRIGHT +--------- +Copyright (c) 2005 Puppet Labs, LLC Licensed under the GNU Public +License + + HELP + end + + def run_command @args = command_line.args command = args.shift diff --git a/lib/puppet/application/inspect.rb b/lib/puppet/application/inspect.rb index ce32c661c..e448cb9e8 100644 --- a/lib/puppet/application/inspect.rb +++ b/lib/puppet/application/inspect.rb @@ -20,22 +20,24 @@ class Puppet::Application::Inspect < Puppet::Application end def help - puts <<-HELP ; exit # XXX + <<-HELP -SYNOPSIS +puppet-inspect(8) -- Send an inspection report ======== -Prepare and submit an inspection report to the puppet master. +SYNOPSIS +-------- + +Prepares and submits an inspection report to the puppet master. USAGE -===== - - puppet inspect +----- +puppet inspect DESCRIPTION -=========== +----------- This command uses the cached catalog from the previous run of 'puppet agent' to determine which attributes of which resources have been @@ -44,11 +46,12 @@ the current state of the system, writes the state of the specified resource attributes to a report, and submits the report to the puppet master. -Puppet inspect does not run as a daemon, and must be run manually or from cron. +Puppet inspect does not run as a daemon, and must be run manually or +from cron. OPTIONS -======= +------- Any configuration setting which is valid in the configuration file is also a valid long argument, e.g. '--server=master.domain.com'. See the @@ -58,13 +61,13 @@ the full list of acceptable settings. AUTHOR -====== +------ Puppet Labs COPYRIGHT -========= +--------- Copyright (c) 2011 Puppet Labs, LLC Licensed under the GNU General Public License version 2 @@ -93,15 +96,15 @@ Licensed under the GNU General Public License version 2 Puppet::Util::Log.level = :info end - Puppet::Transaction::Report.terminus_class = :rest - Puppet::Resource::Catalog.terminus_class = :yaml + Puppet::Transaction::Report.indirection.terminus_class = :rest + Puppet::Resource::Catalog.indirection.terminus_class = :yaml end def run_command benchmark(:notice, "Finished inspection") do retrieval_starttime = Time.now - unless catalog = Puppet::Resource::Catalog.find(Puppet[:certname]) + unless catalog = Puppet::Resource::Catalog.indirection.find(Puppet[:certname]) raise "Could not find catalog for #{Puppet[:certname]}" end @@ -168,7 +171,7 @@ Licensed under the GNU General Public License version 2 @report.finalize_report begin - @report.save + Puppet::Transaction::Report.indirection.save(@report) rescue => detail puts detail.backtrace if Puppet[:trace] Puppet.err "Could not send report: #{detail}" diff --git a/lib/puppet/application/kick.rb b/lib/puppet/application/kick.rb index b3c95e21d..da93c0182 100644 --- a/lib/puppet/application/kick.rb +++ b/lib/puppet/application/kick.rb @@ -37,6 +37,147 @@ class Puppet::Application::Kick < Puppet::Application end end + def help + <<-HELP + +puppet-kick(8) -- Remotely control puppet agent +======== + +SYNOPSIS +-------- +Trigger a puppet agent run on a set of hosts. + + +USAGE +----- +puppet kick [-a|--all] [-c|--class <class>] [-d|--debug] [-f|--foreground] + [-h|--help] [--host <host>] [--no-fqdn] [--ignoreschedules] + [-t|--tag <tag>] [--test] [-p|--ping] <host> [<host> [...]] + + +DESCRIPTION +----------- +This script can be used to connect to a set of machines running 'puppet +agent' and trigger them to run their configurations. The most common +usage would be to specify a class of hosts and a set of tags, and +'puppet kick' would look up in LDAP all of the hosts matching that +class, then connect to each host and trigger a run of all of the objects +with the specified tags. + +If you are not storing your host configurations in LDAP, you can specify +hosts manually. + +You will most likely have to run 'puppet kick' as root to get access to +the SSL certificates. + +'puppet kick' reads 'puppet master''s configuration file, so that it can +copy things like LDAP settings. + + +USAGE NOTES +----------- +'puppet kick' is useless unless 'puppet agent' is listening. See its +documentation for more information, but the gist is that you must enable +'listen' on the 'puppet agent' daemon, either using '--listen' on the +command line or adding 'listen = true' in its config file. In addition, +you need to set the daemons up to specifically allow connections by +creating the 'namespaceauth' file, normally at +'/etc/puppet/namespaceauth.conf'. This file specifies who has access to +each namespace; if you create the file you must add every namespace you +want any Puppet daemon to allow -- it is currently global to all Puppet +daemons. + +An example file looks like this: + + [fileserver] + allow *.madstop.com + + [puppetmaster] + allow *.madstop.com + + [puppetrunner] + allow culain.madstop.com + +This is what you would install on your Puppet master; non-master hosts +could leave off the 'fileserver' and 'puppetmaster' namespaces. + + +OPTIONS +------- +Note that any configuration parameter that's valid in the configuration +file is also a valid long argument. For example, 'ssldir' is a valid +configuration parameter, so you can specify '--ssldir <directory>' as an +argument. + +See the configuration file documentation at +http://docs.puppetlabs.com/references/latest/configuration.html for +the full list of acceptable parameters. A commented list of all +configuration options can also be generated by running puppet master +with '--genconfig'. + +* --all: + Connect to all available hosts. Requires LDAP support at this point. + +* --class: + Specify a class of machines to which to connect. This only works if + you have LDAP configured, at the moment. + +* --debug: + Enable full debugging. + +* --foreground: + Run each configuration in the foreground; that is, when connecting to + a host, do not return until the host has finished its run. The default + is false. + +* --help: + Print this help message + +* --host: + A specific host to which to connect. This flag can be specified more + than once. + +* --ignoreschedules: + Whether the client should ignore schedules when running its + configuration. This can be used to force the client to perform work it + would not normally perform so soon. The default is false. + +* --parallel: + How parallel to make the connections. Parallelization is provided by + forking for each client to which to connect. The default is 1, meaning + serial execution. + +* --tag: + Specify a tag for selecting the objects to apply. Does not work with + the --test option. + +* --test: + Print the hosts you would connect to but do not actually connect. This + option requires LDAP support at this point. + +* --ping: + Do a ICMP echo against the target host. Skip hosts that don't respond + to ping. + + +EXAMPLE +------- + $ sudo puppet kick -p 10 -t remotefile -t webserver host1 host2 + + +AUTHOR +------ +Luke Kanies + + +COPYRIGHT +--------- +Copyright (c) 2005 Puppet Labs, LLC Licensed under the GNU Public +License + + HELP + end + def run_command @hosts += command_line.args options[:test] ? test : main @@ -104,7 +245,7 @@ class Puppet::Application::Kick < Puppet::Application out = %x{ping -c 1 #{host}} unless $CHILD_STATUS == 0 $stderr.print "Could not contact #{host}\n" - next + exit($CHILD_STATUS) end end @@ -120,7 +261,7 @@ class Puppet::Application::Kick < Puppet::Application :background => ! options[:foreground], :ignoreschedules => options[:ignoreschedules] } - run = Puppet::Run.new( run_options ).save( url ) + run = Puppet::Run.indirection.save(Puppet::Run.new( run_options ), url) puts "Getting status" result = run.status puts "status is #{result}" @@ -175,12 +316,12 @@ class Puppet::Application::Kick < Puppet::Application if Puppet[:node_terminus] == "ldap" and (options[:all] or @classes) if options[:all] - @hosts = Puppet::Node.search("whatever", :fqdn => options[:fqdn]).collect { |node| node.name } + @hosts = Puppet::Node.indirection.search("whatever", :fqdn => options[:fqdn]).collect { |node| node.name } puts "all: #{@hosts.join(", ")}" else @hosts = [] @classes.each do |klass| - list = Puppet::Node.search("whatever", :fqdn => options[:fqdn], :class => klass).collect { |node| node.name } + list = Puppet::Node.indirection.search("whatever", :fqdn => options[:fqdn], :class => klass).collect { |node| node.name } puts "#{klass}: #{list.join(", ")}" @hosts += list diff --git a/lib/puppet/application/master.rb b/lib/puppet/application/master.rb index c5e9ada54..78499a92a 100644 --- a/lib/puppet/application/master.rb +++ b/lib/puppet/application/master.rb @@ -25,6 +25,92 @@ class Puppet::Application::Master < Puppet::Application end end + def help + <<-HELP + +puppet-master(8) -- The puppet master daemon +======== + +SYNOPSIS +-------- +The central puppet server. Functions as a certificate authority by +default. + + +USAGE +----- +puppet master [-D|--daemonize|--no-daemonize] [-d|--debug] [-h|--help] + [-l|--logdest <file>|console|syslog] [-v|--verbose] [-V|--version] + [--compile <node-name>] + + +DESCRIPTION +----------- +This command starts an instance of puppet master, running as a daemon +and using Ruby's built-in Webrick webserver. Puppet master can also be +managed by other application servers; when this is the case, this +executable is not used. + + +OPTIONS +------- +Note that any configuration parameter that's valid in the configuration +file is also a valid long argument. For example, 'ssldir' is a valid +configuration parameter, so you can specify '--ssldir <directory>' as an +argument. + +See the configuration file documentation at +http://docs.puppetlabs.com/references/stable/configuration.html for the +full list of acceptable parameters. A commented list of all +configuration options can also be generated by running puppet master +with '--genconfig'. + +* --daemonize: + Send the process into the background. This is the default. + +* --no-daemonize: + Do not send the process into the background. + +* --debug: + Enable full debugging. + +* --help: + Print this help message. + +* --logdest: + Where to send messages. Choose between syslog, the console, and a log + file. Defaults to sending messages to syslog, or the console if + debugging or verbosity is enabled. + +* --verbose: + Enable verbosity. + +* --version: + Print the puppet version number and exit. + +* --compile: + Compile a catalogue and output it in JSON from the puppet master. Uses + facts contained in the $vardir/yaml/ directory to compile the catalog. + + +EXAMPLE +------- + puppet master + + +AUTHOR +------ +Luke Kanies + + +COPYRIGHT +--------- +Copyright (c) 2005 Puppet Labs, LLC Licensed under the GNU Public +License + + HELP + end + def preinit Signal.trap(:INT) do $stderr.puts "Cancelling startup" @@ -51,7 +137,7 @@ class Puppet::Application::Master < Puppet::Application Puppet::Util::Log.newdestination :console raise ArgumentError, "Cannot render compiled catalogs without pson support" unless Puppet.features.pson? begin - unless catalog = Puppet::Resource::Catalog.find(options[:node]) + unless catalog = Puppet::Resource::Catalog.indirection.find(options[:node]) raise "Could not compile catalog for #{options[:node]}" end @@ -139,7 +225,7 @@ class Puppet::Application::Master < Puppet::Application Puppet.settings.use :main, :master, :ssl, :metrics # Cache our nodes in yaml. Currently not configurable. - Puppet::Node.cache_class = :yaml + Puppet::Node.indirection.cache_class = :yaml # Configure all of the SSL stuff. if Puppet::SSL::CertificateAuthority.ca? diff --git a/lib/puppet/application/queue.rb b/lib/puppet/application/queue.rb index ede47d0a6..de8aea32a 100644 --- a/lib/puppet/application/queue.rb +++ b/lib/puppet/application/queue.rb @@ -37,16 +37,89 @@ class Puppet::Application::Queue < Puppet::Application option("--debug","-d") option("--verbose","-v") + def help + <<-HELP + +puppet-queue(8) -- Queuing daemon for asynchronous storeconfigs +======== + +SYNOPSIS +-------- +Retrieves serialized storeconfigs records from a queue and processes +them in order. + + +USAGE +----- +puppet queue [-d|--debug] [-v|--verbose] + + +DESCRIPTION +----------- +This application runs as a daemon and processes storeconfigs data, +retrieving the data from a stomp server message queue and writing it to +a database. + +For more information, including instructions for properly setting up +your puppet master and message queue, see the documentation on setting +up asynchronous storeconfigs at: +http://projects.puppetlabs.com/projects/1/wiki/Using_Stored_Configuration + + +OPTIONS +------- +Note that any configuration parameter that's valid in the configuration +file is also a valid long argument. For example, 'server' is a valid +configuration parameter, so you can specify '--server <servername>' as +an argument. + +See the configuration file documentation at +http://docs.puppetlabs.com/references/stable/configuration.html for the +full list of acceptable parameters. A commented list of all +configuration options can also be generated by running puppet queue with +'--genconfig'. + +* --debug: + Enable full debugging. + +* --help: + Print this help message + +* --verbose: + Turn on verbose reporting. + +* --version: + Print the puppet version number and exit. + + +EXAMPLE +------- + $ puppet queue + + +AUTHOR +------ +Luke Kanies + + +COPYRIGHT +--------- +Copyright (c) 2009 Puppet Labs, LLC Licensed under the GNU Public +License + + HELP + end + def main require 'puppet/indirector/catalog/queue' # provides Puppet::Indirector::Queue.subscribe Puppet.notice "Starting puppetqd #{Puppet.version}" Puppet::Resource::Catalog::Queue.subscribe do |catalog| - # Once you have a Puppet::Resource::Catalog instance, calling save on it should suffice + # Once you have a Puppet::Resource::Catalog instance, passing it to save should suffice # to put it through to the database via its active_record indirector (which is determined # by the terminus_class = :active_record setting above) Puppet::Util.benchmark(:notice, "Processing queued catalog for #{catalog.name}") do begin - catalog.save + Puppet::Resource::Catalog.indirection.save(catalog) rescue => detail puts detail.backtrace if Puppet[:trace] Puppet.err "Could not save queued catalog for #{catalog.name}: #{detail}" @@ -79,7 +152,7 @@ class Puppet::Application::Queue < Puppet::Application exit(Puppet.settings.print_configs ? 0 : 1) if Puppet.settings.print_configs? require 'puppet/resource/catalog' - Puppet::Resource::Catalog.terminus_class = :active_record + Puppet::Resource::Catalog.indirection.terminus_class = :active_record daemon.daemonize if Puppet[:daemonize] @@ -87,6 +160,6 @@ class Puppet::Application::Queue < Puppet::Application # class set up, because if storeconfigs is enabled, # we'll get a loop of continually caching the catalog # for storage again. - Puppet::Resource::Catalog.cache_class = nil + Puppet::Resource::Catalog.indirection.cache_class = nil end end diff --git a/lib/puppet/application/resource.rb b/lib/puppet/application/resource.rb index f55caa58a..3995c285b 100644 --- a/lib/puppet/application/resource.rb +++ b/lib/puppet/application/resource.rb @@ -35,6 +35,109 @@ class Puppet::Application::Resource < Puppet::Application @extra_params << arg.to_sym end + def help + <<-HELP + +puppet-resource(8) -- The resource abstraction layer shell +======== + +SYNOPSIS +-------- +Uses the Puppet RAL to directly interact with the system. + + +USAGE +----- +puppet resource [-h|--help] [-d|--debug] [-v|--verbose] [-e|--edit] + [-H|--host <host>] [-p|--param <parameter>] [-t|--types] <type> + [<name>] [<attribute>=<value> ...] + + +DESCRIPTION +----------- +This command provides simple facilities for converting current system +state into Puppet code, along with some ability to modify the current +state using Puppet's RAL. + +By default, you must at least provide a type to list, in which case +puppet resource will tell you everything it knows about all resources of +that type. You can optionally specify an instance name, and puppet +resource will only describe that single instance. + +If given a type, a name, and a series of <attribute>=<value> pairs, +puppet resource will modify the state of the specified resource. +Alternately, if given a type, a name, and the '--edit' flag, puppet +resource will write its output to a file, open that file in an editor, +and then apply the saved file as a Puppet transaction. + + +OPTIONS +------- +Note that any configuration parameter that's valid in the configuration +file is also a valid long argument. For example, 'ssldir' is a valid +configuration parameter, so you can specify '--ssldir <directory>' as an +argument. + +See the configuration file documentation at +http://docs.puppetlabs.com/references/stable/configuration.html for the +full list of acceptable parameters. A commented list of all +configuration options can also be generated by running puppet with +'--genconfig'. + +* --debug: + Enable full debugging. + +* --edit: + Write the results of the query to a file, open the file in an editor, + and read the file back in as an executable Puppet manifest. + +* --host: + When specified, connect to the resource server on the named host + and retrieve the list of resouces of the type specified. + +* --help: + Print this help message. + +* --param: + Add more parameters to be outputted from queries. + +* --types: + List all available types. + +* --verbose: + Print extra information. + + +EXAMPLE +------- +This example uses `puppet resource` to return a Puppet configuration for +the user `luke`: + + $ puppet resource user luke + user { 'luke': + home => '/home/luke', + uid => '100', + ensure => 'present', + comment => 'Luke Kanies,,,', + gid => '1000', + shell => '/bin/bash', + groups => ['sysadmin','audio','video','puppet'] + } + + +AUTHOR +------ +Luke Kanies + + +COPYRIGHT +--------- +Copyright (c) 2005-2007 Puppet Labs, LLC Licensed under the GNU Public +License + + HELP + end + def main args = command_line.args type = args.shift or raise "You must specify the type to display" @@ -76,12 +179,12 @@ class Puppet::Application::Resource < Puppet::Application text = if name if params.empty? - [ Puppet::Resource.find( key ) ] + [ Puppet::Resource.indirection.find( key ) ] else - [ Puppet::Resource.new( type, name, :parameters => params ).save( key ) ] + [ Puppet::Resource.indirection.save(Puppet::Resource.new( type, name, :parameters => params ), key) ] end else - Puppet::Resource.search( key, {} ) + Puppet::Resource.indirection.search( key, {} ) end.map(&format).join("\n") if options[:edit] diff --git a/lib/puppet/configurer.rb b/lib/puppet/configurer.rb index 9f68ca499..cfeb73a1f 100644 --- a/lib/puppet/configurer.rb +++ b/lib/puppet/configurer.rb @@ -173,7 +173,7 @@ class Puppet::Configurer report.finalize_report if trans puts report.summary if Puppet[:summarize] save_last_run_summary(report) - report.save if Puppet[:report] + Puppet::Transaction::Report.indirection.save(report) if Puppet[:report] rescue => detail puts detail.backtrace if Puppet[:trace] Puppet.err "Could not send report: #{detail}" @@ -220,7 +220,7 @@ class Puppet::Configurer def retrieve_catalog_from_cache(fact_options) result = nil @duration = thinmark do - result = Puppet::Resource::Catalog.find(Puppet[:certname], fact_options.merge(:ignore_terminus => true)) + result = Puppet::Resource::Catalog.indirection.find(Puppet[:certname], fact_options.merge(:ignore_terminus => true)) end Puppet.notice "Using cached catalog" result @@ -233,7 +233,7 @@ class Puppet::Configurer def retrieve_new_catalog(fact_options) result = nil @duration = thinmark do - result = Puppet::Resource::Catalog.find(Puppet[:certname], fact_options.merge(:ignore_cache => true)) + result = Puppet::Resource::Catalog.indirection.find(Puppet[:certname], fact_options.merge(:ignore_cache => true)) end result rescue SystemExit,NoMemoryError diff --git a/lib/puppet/configurer/fact_handler.rb b/lib/puppet/configurer/fact_handler.rb index 075a59458..abe032010 100644 --- a/lib/puppet/configurer/fact_handler.rb +++ b/lib/puppet/configurer/fact_handler.rb @@ -16,7 +16,7 @@ module Puppet::Configurer::FactHandler # compile them and then "cache" them on the server. begin reload_facter - Puppet::Node::Facts.find(Puppet[:certname]) + Puppet::Node::Facts.indirection.find(Puppet[:certname]) rescue SystemExit,NoMemoryError raise rescue Exception => detail diff --git a/lib/puppet/defaults.rb b/lib/puppet/defaults.rb index 2a1ded592..989ef3f35 100644 --- a/lib/puppet/defaults.rb +++ b/lib/puppet/defaults.rb @@ -120,12 +120,12 @@ module Puppet :catalog_terminus => ["compiler", "Where to get node catalogs. This is useful to change if, for instance, you'd like to pre-compile catalogs and store them in memcached or some other easily-accessed store."], :facts_terminus => { - :default => Puppet.application_name.to_s == "master" ? 'yaml' : 'facter', + :default => Puppet.application_name.to_s == "master" ? 'yaml' : 'facter', :desc => "The node facts terminus.", :hook => proc do |value| require 'puppet/node/facts' if value.to_s == "rest" - Puppet::Node::Facts.cache_class = :yaml + Puppet::Node::Facts.indirection.cache_class = :yaml end end }, @@ -156,7 +156,7 @@ module Puppet Puppet.settings[:storeconfigs] = true # But then we modify the configuration - Puppet::Resource::Catalog.cache_class = :queue + Puppet::Resource::Catalog.indirection.cache_class = :queue else raise "Cannot disable asynchronous storeconfigs in a running process" end @@ -604,7 +604,7 @@ module Puppet :inventory_port => ["$masterport", "The port to communicate with the inventory_server." ], - :report => [false, + :report => [true, "Whether to send reports after every transaction." ], :lastrunfile => { :default => "$statedir/last_run_summary.yaml", @@ -804,9 +804,9 @@ module Puppet if value require 'puppet/rails' raise "StoreConfigs not supported without ActiveRecord 2.1 or higher" unless Puppet.features.rails? - Puppet::Resource::Catalog.cache_class = :active_record unless Puppet.settings[:async_storeconfigs] - Puppet::Node::Facts.cache_class = :active_record - Puppet::Node.cache_class = :active_record + Puppet::Resource::Catalog.indirection.cache_class = :active_record unless Puppet.settings[:async_storeconfigs] + Puppet::Node::Facts.indirection.cache_class = :active_record + Puppet::Node.indirection.cache_class = :active_record end end } @@ -823,4 +823,8 @@ module Puppet directories." ] ) + setdefaults( + :puppetdoc, + :document_all => [false, "Document all resources"] + ) end diff --git a/lib/puppet/dsl/resource_type_api.rb b/lib/puppet/dsl/resource_type_api.rb index ecb914189..8810d5368 100644 --- a/lib/puppet/dsl/resource_type_api.rb +++ b/lib/puppet/dsl/resource_type_api.rb @@ -1,46 +1,34 @@ require 'puppet/resource/type' +# Type of the objects inside of which pure ruby manifest files are +# executed. Provides methods for creating defines, hostclasses, and +# nodes. class Puppet::DSL::ResourceTypeAPI + def initialize + @__created_ast_objects__ = [] + end + def define(name, *args, &block) - result = __mk_resource_type__(:definition, name, Hash.new, block) - result.set_arguments(__munge_type_arguments__(args)) + args = args.inject([]) do |result, item| + if item.is_a?(Hash) + item.each { |p, v| result << [p, v] } + else + result << item + end + result + end + @__created_ast_objects__.push Puppet::Parser::AST::Definition.new(name, {:arguments => args}, &block) nil end def hostclass(name, options = {}, &block) - __mk_resource_type__(:hostclass, name, options, block) + @__created_ast_objects__.push Puppet::Parser::AST::Hostclass.new(name, options, &block) nil end def node(name, options = {}, &block) - __mk_resource_type__(:node, name, options, block) + name = [name] unless name.is_a?(Array) + @__created_ast_objects__.push Puppet::Parser::AST::Node.new(name, options, &block) nil end - - # Note: we don't want the user to call the following methods - # directly. However, we can't stop them by making the methods - # private because the user's .rb code gets instance_eval'ed on an - # instance of this class. So instead we name the methods using - # double underscores to discourage customers from calling them. - - def __mk_resource_type__(type, name, options, code) - klass = Puppet::Resource::Type.new(type, name, options) - - klass.ruby_code = code if code - - Thread.current[:known_resource_types].add klass - - klass - end - - def __munge_type_arguments__(args) - args.inject([]) do |result, item| - if item.is_a?(Hash) - item.each { |p, v| result << [p, v] } - else - result << item - end - result - end - end end diff --git a/lib/puppet/external/nagios/parser.rb b/lib/puppet/external/nagios/parser.rb index 5504f5818..17db5e307 100644 --- a/lib/puppet/external/nagios/parser.rb +++ b/lib/puppet/external/nagios/parser.rb @@ -753,7 +753,7 @@ module_eval <<'.,.,', 'grammar.ry', 40 module_eval <<'.,.,', 'grammar.ry', 42 def _reduce_10( val, _values, result ) -result = {val[0],val[1]} +result = {val[0] => val[1]} result end .,., diff --git a/lib/puppet/file_bucket/dipper.rb b/lib/puppet/file_bucket/dipper.rb index de4c01b78..d6f6a3747 100644 --- a/lib/puppet/file_bucket/dipper.rb +++ b/lib/puppet/file_bucket/dipper.rb @@ -39,8 +39,8 @@ class Puppet::FileBucket::Dipper # Make a HEAD request for the file so that we don't waste time # uploading it if it already exists in the bucket. - unless Puppet::FileBucket::File.head("#{@rest_path}#{file_bucket_file.checksum_type}/#{file_bucket_file.checksum_data}#{files_original_path}") - file_bucket_file.save(dest_path) + unless Puppet::FileBucket::File.indirection.head("#{@rest_path}#{file_bucket_file.checksum_type}/#{file_bucket_file.checksum_data}#{files_original_path}") + Puppet::FileBucket::File.indirection.save(file_bucket_file, dest_path) end return file_bucket_file.checksum_data @@ -53,7 +53,7 @@ class Puppet::FileBucket::Dipper # Retrieve a file by sum. def getfile(sum) source_path = "#{@rest_path}md5/#{sum}" - file_bucket_file = Puppet::FileBucket::File.find(source_path, :bucket_path => @local_path) + file_bucket_file = Puppet::FileBucket::File.indirection.find(source_path, :bucket_path => @local_path) raise Puppet::Error, "File not found" unless file_bucket_file file_bucket_file.to_s diff --git a/lib/puppet/indirector.rb b/lib/puppet/indirector.rb index e6472f4d9..9effc5cdd 100644 --- a/lib/puppet/indirector.rb +++ b/lib/puppet/indirector.rb @@ -21,7 +21,6 @@ module Puppet::Indirector raise(ArgumentError, "Already handling indirection for #{@indirection.name}; cannot also handle #{indirection}") if @indirection # populate this class with the various new methods extend ClassMethods - include InstanceMethods include Puppet::Indirector::Envelope extend Puppet::Network::FormatHandler @@ -32,40 +31,5 @@ module Puppet::Indirector module ClassMethods attr_reader :indirection - - def cache_class=(klass) - indirection.cache_class = klass - end - - def terminus_class=(klass) - indirection.terminus_class = klass - end - - # Expire any cached instance. - def expire(*args) - indirection.expire(*args) - end - - def find(*args) - indirection.find(*args) - end - - def head(*args) - indirection.head(*args) - end - - def destroy(*args) - indirection.destroy(*args) - end - - def search(*args) - indirection.search(*args) - end - end - - module InstanceMethods - def save(key = nil) - self.class.indirection.save key, self - end end end diff --git a/lib/puppet/indirector/catalog/active_record.rb b/lib/puppet/indirector/catalog/active_record.rb index f814f4aff..365cdfefe 100644 --- a/lib/puppet/indirector/catalog/active_record.rb +++ b/lib/puppet/indirector/catalog/active_record.rb @@ -30,7 +30,7 @@ class Puppet::Resource::Catalog::ActiveRecord < Puppet::Indirector::ActiveRecord host.merge_resources(catalog.vertices) host.last_compile = Time.now - if node = Puppet::Node.find(catalog.name) + if node = Puppet::Node.indirection.find(catalog.name) host.ip = node.parameters["ipaddress"] host.environment = node.environment.to_s end diff --git a/lib/puppet/indirector/catalog/compiler.rb b/lib/puppet/indirector/catalog/compiler.rb index 6375e801f..f4c40812d 100644 --- a/lib/puppet/indirector/catalog/compiler.rb +++ b/lib/puppet/indirector/catalog/compiler.rb @@ -22,7 +22,8 @@ class Puppet::Resource::Catalog::Compiler < Puppet::Indirector::Code else facts = Puppet::Node::Facts.convert_from(format, text_facts) end - facts.save + facts.add_timestamp + Puppet::Node::Facts.indirection.save(facts) end # Compile a node's catalog. @@ -87,7 +88,7 @@ class Puppet::Resource::Catalog::Compiler < Puppet::Indirector::Code # Turn our host name into a node object. def find_node(name) begin - return nil unless node = Puppet::Node.find(name) + return nil unless node = Puppet::Node.indirection.find(name) rescue => detail puts detail.backtrace if Puppet[:trace] raise Puppet::Error, "Failed when searching for node #{name}: #{detail}" diff --git a/lib/puppet/indirector/certificate_status.rb b/lib/puppet/indirector/certificate_status.rb new file mode 100644 index 000000000..47c3adcd4 --- /dev/null +++ b/lib/puppet/indirector/certificate_status.rb @@ -0,0 +1,4 @@ +require 'puppet/indirector' + +class Puppet::Indirector::CertificateStatus +end diff --git a/lib/puppet/indirector/certificate_status/file.rb b/lib/puppet/indirector/certificate_status/file.rb new file mode 100644 index 000000000..9061d9423 --- /dev/null +++ b/lib/puppet/indirector/certificate_status/file.rb @@ -0,0 +1,82 @@ +require 'puppet' +require 'puppet/indirector/certificate_status' +require 'puppet/ssl/certificate' +require 'puppet/ssl/certificate_authority' +require 'puppet/ssl/certificate_request' +require 'puppet/ssl/host' +require 'puppet/ssl/key' + +class Puppet::Indirector::CertificateStatus::File < Puppet::Indirector::Code + def ca + raise ArgumentError, "This process is not configured as a certificate authority" unless Puppet::SSL::CertificateAuthority.ca? + Puppet::SSL::CertificateAuthority.new + end + + def destroy(request) + deleted = [] + [ + Puppet::SSL::Certificate, + Puppet::SSL::CertificateRequest, + Puppet::SSL::Key, + ].collect do |part| + if part.indirection.destroy(request.key) + deleted << "#{part}" + end + end + + return "Nothing was deleted" if deleted.empty? + "Deleted for #{request.key}: #{deleted.join(", ")}" + end + + def save(request) + if request.instance.desired_state == "signed" + certificate_request = Puppet::SSL::CertificateRequest.indirection.find(request.key) + raise Puppet::Error, "Cannot sign for host #{request.key} without a certificate request" unless certificate_request + ca.sign(request.key) + elsif request.instance.desired_state == "revoked" + certificate = Puppet::SSL::Certificate.indirection.find(request.key) + raise Puppet::Error, "Cannot revoke host #{request.key} because has it doesn't have a signed certificate" unless certificate + ca.revoke(request.key) + else + raise Puppet::Error, "State #{request.instance.desired_state} invalid; Must specify desired state of 'signed' or 'revoked' for host #{request.key}" + end + + end + + def search(request) + # Support historic interface wherein users provide classes to filter + # the search. When used via the REST API, the arguments must be + # a Symbol or an Array containing Symbol objects. + klasses = case request.options[:for] + when Class + [request.options[:for]] + when nil + [ + Puppet::SSL::Certificate, + Puppet::SSL::CertificateRequest, + Puppet::SSL::Key, + ] + else + [request.options[:for]].flatten.map do |klassname| + indirection.class.model(klassname.to_sym) + end + end + + klasses.collect do |klass| + klass.indirection.search(request.key, request.options) + end.flatten.collect do |result| + result.name + end.uniq.collect &Puppet::SSL::Host.method(:new) + end + + def find(request) + ssl_host = Puppet::SSL::Host.new(request.key) + public_key = Puppet::SSL::Certificate.indirection.find(request.key) + + if ssl_host.certificate_request || public_key + ssl_host + else + nil + end + end +end diff --git a/lib/puppet/indirector/certificate_status/rest.rb b/lib/puppet/indirector/certificate_status/rest.rb new file mode 100644 index 000000000..c53b663b5 --- /dev/null +++ b/lib/puppet/indirector/certificate_status/rest.rb @@ -0,0 +1,10 @@ +require 'puppet/ssl/host' +require 'puppet/indirector/rest' +require 'puppet/indirector/certificate_status' + +class Puppet::Indirector::CertificateStatus::Rest < Puppet::Indirector::REST + desc "Sign, revoke, search for, or clean certificates & certificate requests over HTTP." + + use_server_setting(:ca_server) + use_port_setting(:ca_port) +end diff --git a/lib/puppet/indirector/indirection.rb b/lib/puppet/indirector/indirection.rb index 3d17e6e47..d958a82ac 100644 --- a/lib/puppet/indirector/indirection.rb +++ b/lib/puppet/indirector/indirection.rb @@ -257,7 +257,7 @@ class Puppet::Indirector::Indirection # Save the instance in the appropriate terminus. This method is # normally an instance method on the indirected class. - def save(key, instance = nil) + def save(instance, key = nil) request = request(:save, key, instance) terminus = prepare(request) diff --git a/lib/puppet/indirector/inventory/yaml.rb b/lib/puppet/indirector/inventory/yaml.rb new file mode 100644 index 000000000..fe3489a95 --- /dev/null +++ b/lib/puppet/indirector/inventory/yaml.rb @@ -0,0 +1,81 @@ +require 'puppet/node/inventory' +require 'puppet/indirector/yaml' + +class Puppet::Node::Inventory::Yaml < Puppet::Indirector::Yaml + desc "Return node names matching the fact query" + + # Return the path to a given node's file. + def yaml_dir_path + base = Puppet.run_mode.master? ? Puppet[:yamldir] : Puppet[:clientyamldir] + File.join(base, 'facts', '*.yaml') + end + + def node_matches?(facts, options) + options.each do |key, value| + type, name, operator = key.to_s.split(".") + operator ||= 'eq' + + return false unless node_matches_option?(type, name, operator, value, facts) + end + return true + end + + def search(request) + node_names = [] + Dir.glob(yaml_dir_path).each do |file| + facts = YAML.load_file(file) + node_names << facts.name if node_matches?(facts, request.options) + end + node_names + end + + private + + def node_matches_option?(type, name, operator, value, facts) + case type + when "meta" + case name + when "timestamp" + compare_timestamp(operator, facts.timestamp, Time.parse(value)) + end + when "facts" + compare_facts(operator, facts.values[name], value) + end + end + + def compare_facts(operator, value1, value2) + return false unless value1 + + case operator + when "eq" + value1.to_s == value2.to_s + when "le" + value1.to_f <= value2.to_f + when "ge" + value1.to_f >= value2.to_f + when "lt" + value1.to_f < value2.to_f + when "gt" + value1.to_f > value2.to_f + when "ne" + value1.to_s != value2.to_s + end + end + + def compare_timestamp(operator, value1, value2) + case operator + when "eq" + value1 == value2 + when "le" + value1 <= value2 + when "ge" + value1 >= value2 + when "lt" + value1 < value2 + when "gt" + value1 > value2 + when "ne" + value1 != value2 + end + end +end diff --git a/lib/puppet/indirector/resource_type/parser.rb b/lib/puppet/indirector/resource_type/parser.rb index 8b1bed0a9..4bcaf3f47 100644 --- a/lib/puppet/indirector/resource_type/parser.rb +++ b/lib/puppet/indirector/resource_type/parser.rb @@ -10,7 +10,10 @@ class Puppet::Indirector::ResourceType::Parser < Puppet::Indirector::Code # This is a bit ugly. [:hostclass, :definition, :node].each do |type| - if r = krt.send(type, request.key) + # We have to us 'find_<type>' here because it will + # load any missing types from disk, whereas the plain + # '<type>' method only returns from memory. + if r = krt.send("find_#{type}", [""], request.key) return r end end @@ -18,9 +21,22 @@ class Puppet::Indirector::ResourceType::Parser < Puppet::Indirector::Code end def search(request) - raise ArgumentError, "Only '*' is acceptable as a search request" unless request.key == "*" krt = request.environment.known_resource_types - result = [krt.hostclasses.values, krt.definitions.values, krt.nodes.values].flatten + # Make sure we've got all of the types loaded. + krt.loader.import_all + result = [krt.hostclasses.values, krt.definitions.values, krt.nodes.values].flatten.reject { |t| t.name == "" } + return nil if result.empty? + return result if request.key == "*" + + # Strip the regex of any wrapping slashes that might exist + key = request.key.sub(/^\//, '').sub(/\/$/, '') + begin + regex = Regexp.new(key) + rescue => detail + raise ArgumentError, "Invalid regex '#{request.key}': #{detail}" + end + + result.reject! { |t| t.name.to_s !~ regex } return nil if result.empty? result end diff --git a/lib/puppet/module.rb b/lib/puppet/module.rb index 43266b2b5..059591ed8 100644 --- a/lib/puppet/module.rb +++ b/lib/puppet/module.rb @@ -138,7 +138,7 @@ class Puppet::Module # Find this module in the modulepath. def path - environment.modulepath.collect { |path| File.join(path, name) }.find { |d| FileTest.exist?(d) } + environment.modulepath.collect { |path| File.join(path, name) }.find { |d| FileTest.directory?(d) } end # Find all plugin directories. This is used by the Plugins fileserving mount. diff --git a/lib/puppet/network/handler/filebucket.rb b/lib/puppet/network/handler/filebucket.rb index 6aaa2df1c..55028ee64 100755 --- a/lib/puppet/network/handler/filebucket.rb +++ b/lib/puppet/network/handler/filebucket.rb @@ -28,12 +28,12 @@ class Puppet::Network::Handler # :nodoc: def addfile(contents, path, client = nil, clientip = nil) contents = Base64.decode64(contents) if client bucket = Puppet::FileBucket::File.new(contents) - bucket.save + Puppet::FileBucket::File.indirection.save(bucket) end # Return the contents associated with a given md5 sum. def getfile(md5, client = nil, clientip = nil) - bucket = Puppet::FileBucket::File.find("md5:#{md5}") + bucket = Puppet::FileBucket::File.indirection.find("md5:#{md5}") contents = bucket.contents if client diff --git a/lib/puppet/network/handler/fileserver.rb b/lib/puppet/network/handler/fileserver.rb index 1531f4f5c..5b4b17a32 100755 --- a/lib/puppet/network/handler/fileserver.rb +++ b/lib/puppet/network/handler/fileserver.rb @@ -4,11 +4,13 @@ require 'webrick/httpstatus' require 'cgi' require 'delegate' require 'sync' +require 'xmlrpc/server' require 'puppet/network/handler' require 'puppet/network/xmlrpc/server' require 'puppet/file_serving' require 'puppet/file_serving/metadata' +require 'puppet/network/handler' class Puppet::Network::Handler AuthStoreError = Puppet::AuthStoreError @@ -234,7 +236,7 @@ class Puppet::Network::Handler unless hostname = (client || Facter.value("hostname")) raise ArgumentError, "Could not find hostname" end - env = (node = Puppet::Node.find(hostname)) ? node.environment : nil + env = (node = Puppet::Node.indirection.find(hostname)) ? node.environment : nil # And use the environment to look up the module. (mod = Puppet::Node::Environment.new(env).module(module_name) and mod.files?) ? @mounts[MODULES].copy(mod.name, mod.file_directory) : nil diff --git a/lib/puppet/network/handler/master.rb b/lib/puppet/network/handler/master.rb index c21aafafc..62aab539e 100644 --- a/lib/puppet/network/handler/master.rb +++ b/lib/puppet/network/handler/master.rb @@ -47,9 +47,9 @@ class Puppet::Network::Handler client ||= facts["hostname"] # Pass the facts to the fact handler - Puppet::Node::Facts.new(client, facts).save unless local? + Puppet::Node::Facts.indirection.save(Puppet::Node::Facts.new(client, facts)) unless local? - catalog = Puppet::Resource::Catalog.find(client) + catalog = Puppet::Resource::Catalog.indirection.find(client) case format when "yaml" diff --git a/lib/puppet/network/http/api/v1.rb b/lib/puppet/network/http/api/v1.rb index 9e51aae36..5fe143979 100644 --- a/lib/puppet/network/http/api/v1.rb +++ b/lib/puppet/network/http/api/v1.rb @@ -33,7 +33,7 @@ module Puppet::Network::HTTP::API::V1 key = URI.unescape(key) - Puppet::Indirector::Request.new(indirection, method, key, params) + [indirection, method, key, params] end def indirection2uri(request) @@ -61,6 +61,7 @@ module Puppet::Network::HTTP::API::V1 # that leads to the fix being too long. return :singular if indirection == "facts" return :singular if indirection == "status" + return :singular if indirection == "certificate_status" return :plural if indirection == "inventory" result = (indirection =~ /s$|_search$/) ? :plural : :singular diff --git a/lib/puppet/network/http/handler.rb b/lib/puppet/network/http/handler.rb index e192613ad..2b9e81b61 100644 --- a/lib/puppet/network/http/handler.rb +++ b/lib/puppet/network/http/handler.rb @@ -61,11 +61,11 @@ module Puppet::Network::HTTP::Handler # handle an HTTP request def process(request, response) - indirection_request = uri2indirection(http_method(request), path(request), params(request)) + indirection, method, key, params = uri2indirection(http_method(request), path(request), params(request)) - check_authorization(indirection_request) + check_authorization(indirection, method, key, params) - send("do_#{indirection_request.method}", indirection_request, request, response) + send("do_#{method}", indirection, key, params, request, response) rescue SystemExit,NoMemoryError raise rescue Exception => e @@ -96,11 +96,16 @@ module Puppet::Network::HTTP::Handler set_response(response, exception.to_s, status) end + def model(indirection_name) + raise ArgumentError, "Could not find indirection '#{indirection_name}'" unless indirection = Puppet::Indirector::Indirection.instance(indirection_name.to_sym) + indirection.model + end + # Execute our find. - def do_find(indirection_request, request, response) - unless result = indirection_request.model.find(indirection_request.key, indirection_request.to_hash) - Puppet.info("Could not find #{indirection_request.indirection_name} for '#{indirection_request.key}'") - return do_exception(response, "Could not find #{indirection_request.indirection_name} #{indirection_request.key}", 404) + def do_find(indirection_name, key, params, request, response) + unless result = model(indirection_name).indirection.find(key, params) + Puppet.info("Could not find #{indirection_name} for '#{key}'") + return do_exception(response, "Could not find #{indirection_name} #{key}", 404) end # The encoding of the result must include the format to use, @@ -128,34 +133,35 @@ module Puppet::Network::HTTP::Handler end # Execute our search. - def do_search(indirection_request, request, response) - result = indirection_request.model.search(indirection_request.key, indirection_request.to_hash) + def do_search(indirection_name, key, params, request, response) + model = self.model(indirection_name) + result = model.indirection.search(key, params) if result.nil? - return do_exception(response, "Could not find instances in #{indirection_request.indirection_name} with '#{indirection_request.key}'", 404) + return do_exception(response, "Could not find instances in #{indirection_name} with '#{key}'", 404) end format = format_to_use(request) set_content_type(response, format) - set_response(response, indirection_request.model.render_multiple(format, result)) + set_response(response, model.render_multiple(format, result)) end # Execute our destroy. - def do_destroy(indirection_request, request, response) - result = indirection_request.model.destroy(indirection_request.key, indirection_request.to_hash) + def do_destroy(indirection_name, key, params, request, response) + result = model(indirection_name).indirection.destroy(key, params) return_yaml_response(response, result) end # Execute our save. - def do_save(indirection_request, request, response) + def do_save(indirection_name, key, params, request, response) data = body(request).to_s raise ArgumentError, "No data to save" if !data or data.empty? format = request_format(request) - obj = indirection_request.model.convert_from(format, data) - result = save_object(indirection_request, obj) + obj = model(indirection_name).convert_from(format, data) + result = model(indirection_name).indirection.save(obj, key) return_yaml_response(response, result) end @@ -177,12 +183,6 @@ module Puppet::Network::HTTP::Handler set_response(response, body.to_yaml) end - # LAK:NOTE This has to be here for testing; it's a stub-point so - # we keep infinite recursion from happening. - def save_object(ind_request, object) - object.save(ind_request.key) - end - def get?(request) http_method(request) == 'GET' end diff --git a/lib/puppet/network/http/webrick.rb b/lib/puppet/network/http/webrick.rb index 8ed0b28ca..54bcf30c2 100644 --- a/lib/puppet/network/http/webrick.rb +++ b/lib/puppet/network/http/webrick.rb @@ -105,7 +105,7 @@ class Puppet::Network::HTTP::WEBrick results[:SSLStartImmediately] = true results[:SSLEnable] = true - raise Puppet::Error, "Could not find CA certificate" unless Puppet::SSL::Certificate.find(Puppet::SSL::CA_NAME) + raise Puppet::Error, "Could not find CA certificate" unless Puppet::SSL::Certificate.indirection.find(Puppet::SSL::CA_NAME) results[:SSLCACertificateFile] = Puppet[:localcacert] results[:SSLVerifyClient] = OpenSSL::SSL::VERIFY_PEER diff --git a/lib/puppet/network/rest_authconfig.rb b/lib/puppet/network/rest_authconfig.rb index e6067612a..cf76978fe 100644 --- a/lib/puppet/network/rest_authconfig.rb +++ b/lib/puppet/network/rest_authconfig.rb @@ -31,14 +31,14 @@ module Puppet # check wether this request is allowed in our ACL # raise an Puppet::Network::AuthorizedError if the request # is denied. - def allowed?(request) + def allowed?(indirection, method, key, params) read # we're splitting the request in part because # fail_on_deny could as well be called in the XMLRPC context # with a ClientRequest. - if authorization_failure_exception = @rights.is_request_forbidden_and_why?(request) + if authorization_failure_exception = @rights.is_request_forbidden_and_why?(indirection, method, key, params) Puppet.warning("Denying access: #{authorization_failure_exception}") raise authorization_failure_exception end diff --git a/lib/puppet/network/rest_authorization.rb b/lib/puppet/network/rest_authorization.rb index e052245eb..50f094e3e 100644 --- a/lib/puppet/network/rest_authorization.rb +++ b/lib/puppet/network/rest_authorization.rb @@ -15,8 +15,8 @@ module Puppet::Network end # Verify that our client has access. - def check_authorization(request) - authconfig.allowed?(request) + def check_authorization(indirection, method, key, params) + authconfig.allowed?(indirection, method, key, params) end end end diff --git a/lib/puppet/network/rights.rb b/lib/puppet/network/rights.rb index b1daef67c..6fde181c9 100755 --- a/lib/puppet/network/rights.rb +++ b/lib/puppet/network/rights.rb @@ -29,20 +29,15 @@ class Rights !is_forbidden_and_why?(name, :node => args[0], :ip => args[1]) end - def is_request_forbidden_and_why?(request) - methods_to_check = if request.method == :head + def is_request_forbidden_and_why?(indirection, method, key, params) + methods_to_check = if method == :head # :head is ok if either :find or :save is ok. [:find, :save] else - [request.method] + [method] end authorization_failure_exceptions = methods_to_check.map do |method| - is_forbidden_and_why?("/#{request.indirection_name}/#{request.key}", - :node => request.node, - :ip => request.ip, - :method => method, - :environment => request.environment, - :authenticated => request.authenticated) + is_forbidden_and_why?("/#{indirection}/#{key}", params.merge({:method => method})) end if authorization_failure_exceptions.include? nil # One of the methods we checked is ok, therefore this request is ok. diff --git a/lib/puppet/node.rb b/lib/puppet/node.rb index 2453cd1d5..5b0a98615 100644 --- a/lib/puppet/node.rb +++ b/lib/puppet/node.rb @@ -3,6 +3,7 @@ require 'puppet/indirector' # A class for managing nodes, including their facts and environment. class Puppet::Node require 'puppet/node/facts' + require 'puppet/node/inventory' require 'puppet/node/environment' # Set up indirection, so that nodes can be looked for in @@ -56,7 +57,7 @@ class Puppet::Node # Merge the node facts with parameters from the node source. def fact_merge - if facts = Puppet::Node::Facts.find(name) + if facts = Puppet::Node::Facts.indirection.find(name) merge(facts.values) end rescue => detail diff --git a/lib/puppet/node/environment.rb b/lib/puppet/node/environment.rb index 807479bc8..dc631979e 100644 --- a/lib/puppet/node/environment.rb +++ b/lib/puppet/node/environment.rb @@ -76,12 +76,12 @@ class Puppet::Node::Environment # per environment semantics with an efficient most common cases; we almost # always just return our thread's known-resource types. Only at the start # of a compilation (after our thread var has been set to nil) or when the - # environment has changed do we delve deeper. + # environment has changed do we delve deeper. Thread.current[:known_resource_types] = nil if (krt = Thread.current[:known_resource_types]) && krt.environment != self Thread.current[:known_resource_types] ||= synchronize { if @known_resource_types.nil? or @known_resource_types.require_reparse? @known_resource_types = Puppet::Resource::TypeCollection.new(self) - @known_resource_types.perform_initial_import + @known_resource_types.import_ast(perform_initial_import, '') end @known_resource_types } @@ -128,7 +128,7 @@ class Puppet::Node::Environment to_s.to_sym end - # The only thing we care about when serializing an environment is its + # The only thing we care about when serializing an environment is its # identity; everything else is ephemeral and should not be stored or # transmitted. def to_zaml(z) @@ -147,5 +147,32 @@ class Puppet::Node::Environment end end + private + + def perform_initial_import + return empty_parse_result if Puppet.settings[:ignoreimport] + parser = Puppet::Parser::Parser.new(self) + if code = Puppet.settings.uninterpolated_value(:code, name.to_s) and code != "" + parser.string = code + else + file = Puppet.settings.value(:manifest, name.to_s) + parser.file = file + end + parser.parse + rescue => detail + known_resource_types.parse_failed = true + + msg = "Could not parse for environment #{self}: #{detail}" + error = Puppet::Error.new(msg) + error.set_backtrace(detail.backtrace) + raise error + end + + def empty_parse_result + # Return an empty toplevel hostclass to use as the result of + # perform_initial_import when no file was actually loaded. + return Puppet::Parser::AST::Hostclass.new('') + end + @root = new(:'*root*') end diff --git a/lib/puppet/node/facts.rb b/lib/puppet/node/facts.rb index 0a96e553b..577b62b62 100755 --- a/lib/puppet/node/facts.rb +++ b/lib/puppet/node/facts.rb @@ -15,8 +15,8 @@ class Puppet::Node::Facts # We want to expire any cached nodes if the facts are saved. module NodeExpirer - def save(key, instance) - Puppet::Node.expire(instance.name) + def save(instance, key = nil) + Puppet::Node.indirection.expire(instance.name) super end end @@ -35,7 +35,7 @@ class Puppet::Node::Facts @name = name @values = values - add_internal + add_timestamp end def downcase_if_necessary @@ -59,14 +59,6 @@ class Puppet::Node::Facts strip_internal == other.send(:strip_internal) end - def timestamp=(time) - self.values[:_timestamp] = time - end - - def timestamp - self.values[:_timestamp] - end - def self.from_pson(data) result = new(data['name'], data['values']) result.timestamp = Time.parse(data['timestamp']) @@ -83,13 +75,21 @@ class Puppet::Node::Facts }.to_pson(*args) end - private - # Add internal data to the facts for storage. - def add_internal - self.values[:_timestamp] = Time.now + def add_timestamp + self.timestamp = Time.now end + def timestamp=(time) + self.values[:_timestamp] = time + end + + def timestamp + self.values[:_timestamp] + end + + private + # Strip out that internal data. def strip_internal newvals = values.dup diff --git a/lib/puppet/node/inventory.rb b/lib/puppet/node/inventory.rb new file mode 100644 index 000000000..fd99163b0 --- /dev/null +++ b/lib/puppet/node/inventory.rb @@ -0,0 +1,7 @@ +require 'puppet/node' +require 'puppet/indirector' + +class Puppet::Node::Inventory + extend Puppet::Indirector + indirects :inventory, :terminus_setting => :inventory_terminus +end diff --git a/lib/puppet/parser/ast.rb b/lib/puppet/parser/ast.rb index a5aaeddc4..122b4dd7a 100644 --- a/lib/puppet/parser/ast.rb +++ b/lib/puppet/parser/ast.rb @@ -111,28 +111,32 @@ end require 'puppet/parser/ast/arithmetic_operator' require 'puppet/parser/ast/astarray' require 'puppet/parser/ast/asthash' -require 'puppet/parser/ast/branch' require 'puppet/parser/ast/boolean_operator' +require 'puppet/parser/ast/branch' require 'puppet/parser/ast/caseopt' require 'puppet/parser/ast/casestatement' require 'puppet/parser/ast/collection' require 'puppet/parser/ast/collexpr' require 'puppet/parser/ast/comparison_operator' +require 'puppet/parser/ast/definition' require 'puppet/parser/ast/else' require 'puppet/parser/ast/function' +require 'puppet/parser/ast/hostclass' require 'puppet/parser/ast/ifstatement' require 'puppet/parser/ast/in_operator' require 'puppet/parser/ast/leaf' require 'puppet/parser/ast/match_operator' require 'puppet/parser/ast/minus' +require 'puppet/parser/ast/node' require 'puppet/parser/ast/nop' require 'puppet/parser/ast/not' +require 'puppet/parser/ast/relationship' require 'puppet/parser/ast/resource' require 'puppet/parser/ast/resource_defaults' +require 'puppet/parser/ast/resource_instance' require 'puppet/parser/ast/resource_override' require 'puppet/parser/ast/resource_reference' require 'puppet/parser/ast/resourceparam' require 'puppet/parser/ast/selector' require 'puppet/parser/ast/tag' require 'puppet/parser/ast/vardef' -require 'puppet/parser/ast/relationship' diff --git a/lib/puppet/parser/ast/astarray.rb b/lib/puppet/parser/ast/astarray.rb index 529998e3c..7283a1f6c 100644 --- a/lib/puppet/parser/ast/astarray.rb +++ b/lib/puppet/parser/ast/astarray.rb @@ -16,25 +16,20 @@ class Puppet::Parser::AST # Evaluate our children. def evaluate(scope) - # Make a new array, so we don't have to deal with the details of - # flattening and such - items = [] - - # First clean out any AST::ASTArrays - @children.each { |child| - if child.instance_of?(AST::ASTArray) - child.each do |ac| - items << ac + result = [] + @children.each do |child| + # Skip things that respond to :instantiate (classes, nodes, + # and definitions), because they have already been + # instantiated. + if !child.respond_to?(:instantiate) + item = child.safeevaluate(scope) + if !item.nil? + # nil values are implicitly removed. + result.push(item) end - else - items << child end - } - - rets = items.flatten.collect { |child| - child.safeevaluate(scope) - } - rets.reject { |o| o.nil? } + end + result end def push(*ary) @@ -52,10 +47,4 @@ class Puppet::Parser::AST "[" + @children.collect { |c| c.to_s }.join(', ') + "]" end end - - # A simple container class, containing the parameters for an object. - # Used for abstracting the grammar declarations. Basically unnecessary - # except that I kept finding bugs because I had too many arrays that - # meant completely different things. - class ResourceInstance < ASTArray; end end diff --git a/lib/puppet/parser/ast/caseopt.rb b/lib/puppet/parser/ast/caseopt.rb index 4e296e82f..db4c2b024 100644 --- a/lib/puppet/parser/ast/caseopt.rb +++ b/lib/puppet/parser/ast/caseopt.rb @@ -18,16 +18,12 @@ class Puppet::Parser::AST # Cache the @default value. return @default if defined?(@default) - if @value.is_a?(AST::ASTArray) - @value.each { |subval| - if subval.is_a?(AST::Default) - @default = true - break - end - } - else - @default = true if @value.is_a?(AST::Default) - end + @value.each { |subval| + if subval.is_a?(AST::Default) + @default = true + break + end + } @default ||= false @@ -36,23 +32,15 @@ class Puppet::Parser::AST # You can specify a list of values; return each in turn. def eachvalue(scope) - if @value.is_a?(AST::ASTArray) - @value.each { |subval| - yield subval.safeevaluate(scope) - } - else - yield @value.safeevaluate(scope) - end + @value.each { |subval| + yield subval.safeevaluate(scope) + } end def eachopt - if @value.is_a?(AST::ASTArray) - @value.each { |subval| - yield subval - } - else - yield @value - end + @value.each { |subval| + yield subval + } end # Evaluate the actual statements; this only gets called if diff --git a/lib/puppet/parser/ast/definition.rb b/lib/puppet/parser/ast/definition.rb new file mode 100644 index 000000000..c43422f82 --- /dev/null +++ b/lib/puppet/parser/ast/definition.rb @@ -0,0 +1,17 @@ +require 'puppet/parser/ast/top_level_construct' + +class Puppet::Parser::AST::Definition < Puppet::Parser::AST::TopLevelConstruct + attr_accessor :context + + def initialize(name, context = {}, &ruby_code) + @name = name + @context = context + @ruby_code = ruby_code + end + + def instantiate(modname) + new_definition = Puppet::Resource::Type.new(:definition, @name, @context.merge(:module_name => modname)) + new_definition.ruby_code = @ruby_code if @ruby_code + [new_definition] + end +end diff --git a/lib/puppet/parser/ast/hostclass.rb b/lib/puppet/parser/ast/hostclass.rb new file mode 100644 index 000000000..cab5e4a24 --- /dev/null +++ b/lib/puppet/parser/ast/hostclass.rb @@ -0,0 +1,29 @@ +require 'puppet/parser/ast/top_level_construct' + +class Puppet::Parser::AST::Hostclass < Puppet::Parser::AST::TopLevelConstruct + attr_accessor :name, :context + + def initialize(name, context = {}, &ruby_code) + @context = context + @name = name + @ruby_code = ruby_code + end + + def instantiate(modname) + new_class = Puppet::Resource::Type.new(:hostclass, @name, @context.merge(:module_name => modname)) + new_class.ruby_code = @ruby_code if @ruby_code + all_types = [new_class] + if code + code.each do |nested_ast_node| + if nested_ast_node.respond_to? :instantiate + all_types += nested_ast_node.instantiate(modname) + end + end + end + return all_types + end + + def code() + @context[:code] + end +end diff --git a/lib/puppet/parser/ast/node.rb b/lib/puppet/parser/ast/node.rb new file mode 100644 index 000000000..b69a5c4e0 --- /dev/null +++ b/lib/puppet/parser/ast/node.rb @@ -0,0 +1,20 @@ +require 'puppet/parser/ast/top_level_construct' + +class Puppet::Parser::AST::Node < Puppet::Parser::AST::TopLevelConstruct + attr_accessor :names, :context + + def initialize(names, context = {}, &ruby_code) + raise ArgumentError, "names should be an array" unless names.is_a? Array + @names = names + @context = context + @ruby_code = ruby_code + end + + def instantiate(modname) + @names.collect do |name| + new_node = Puppet::Resource::Type.new(:node, name, @context.merge(:module_name => modname)) + new_node.ruby_code = @ruby_code if @ruby_code + new_node + end + end +end diff --git a/lib/puppet/parser/ast/resource.rb b/lib/puppet/parser/ast/resource.rb index b019e6aac..ce3c499c5 100644 --- a/lib/puppet/parser/ast/resource.rb +++ b/lib/puppet/parser/ast/resource.rb @@ -3,26 +3,15 @@ require 'puppet/parser/ast/resource_reference' # Any normal puppet resource declaration. Can point to a definition or a # builtin type. class Puppet::Parser::AST -class Resource < AST::ResourceReference +class Resource < AST::Branch associates_doc - attr_accessor :title, :type, :exported, :virtual - attr_reader :parameters + attr_accessor :type, :instances, :exported, :virtual # Does not actually return an object; instead sets an object # in the current scope. def evaluate(scope) - # Evaluate all of the specified params. - paramobjects = parameters.collect { |param| - param.safeevaluate(scope) - } - - resource_titles = @title.safeevaluate(scope) - - # it's easier to always use an array, even for only one name - resource_titles = [resource_titles] unless resource_titles.is_a?(Array) - # We want virtual to be true if exported is true. We can't # just set :virtual => self.virtual in the initialization, # because sometimes the :virtual attribute is set *after* @@ -30,46 +19,49 @@ class Resource < AST::ResourceReference # is true. Argh, this was a very tough one to track down. virt = self.virtual || self.exported - # This is where our implicit iteration takes place; if someone - # passed an array as the name, then we act just like the called us - # many times. - fully_qualified_type, resource_titles = scope.resolve_type_and_titles(type, resource_titles) + # First level of implicit iteration: build a resource for each + # instance. This handles things like: + # file { '/foo': owner => blah; '/bar': owner => blah } + @instances.collect { |instance| - resource_titles.flatten.collect { |resource_title| - exceptwrap :type => Puppet::ParseError do - resource = Puppet::Parser::Resource.new( - fully_qualified_type, resource_title, - :parameters => paramobjects, - :file => self.file, - :line => self.line, - :exported => self.exported, - :virtual => virt, - :source => scope.source, - :scope => scope, - :strict => true - ) + # Evaluate all of the specified params. + paramobjects = instance.parameters.collect { |param| + param.safeevaluate(scope) + } - if resource.resource_type.is_a? Puppet::Resource::Type - resource.resource_type.instantiate_resource(scope, resource) - end - scope.compiler.add_resource(scope, resource) - scope.compiler.evaluate_classes([resource_title],scope,false) if fully_qualified_type == 'class' - resource - end - }.reject { |resource| resource.nil? } - end + resource_titles = instance.title.safeevaluate(scope) - # Set the parameters for our object. - def parameters=(params) - if params.is_a?(AST::ASTArray) - @parameters = params - else - @parameters = AST::ASTArray.new( - :line => params.line, - :file => params.file, - :children => [params] - ) - end + # it's easier to always use an array, even for only one name + resource_titles = [resource_titles] unless resource_titles.is_a?(Array) + + fully_qualified_type, resource_titles = scope.resolve_type_and_titles(type, resource_titles) + + # Second level of implicit iteration; build a resource for each + # title. This handles things like: + # file { ['/foo', '/bar']: owner => blah } + resource_titles.flatten.collect { |resource_title| + exceptwrap :type => Puppet::ParseError do + resource = Puppet::Parser::Resource.new( + fully_qualified_type, resource_title, + :parameters => paramobjects, + :file => self.file, + :line => self.line, + :exported => self.exported, + :virtual => virt, + :source => scope.source, + :scope => scope, + :strict => true + ) + + if resource.resource_type.is_a? Puppet::Resource::Type + resource.resource_type.instantiate_resource(scope, resource) + end + scope.compiler.add_resource(scope, resource) + scope.compiler.evaluate_classes([resource_title],scope,false) if fully_qualified_type == 'class' + resource + end + } + }.flatten.reject { |resource| resource.nil? } end end end diff --git a/lib/puppet/parser/ast/resource_instance.rb b/lib/puppet/parser/ast/resource_instance.rb new file mode 100644 index 000000000..ebfb17bf1 --- /dev/null +++ b/lib/puppet/parser/ast/resource_instance.rb @@ -0,0 +1,9 @@ +require 'puppet/parser/ast/branch' + +class Puppet::Parser::AST + class ResourceInstance < Branch + # A simple container for a parameter for an object. Consists of a + # title and a set of parameters. + attr_accessor :title, :parameters + end +end diff --git a/lib/puppet/parser/ast/resource_override.rb b/lib/puppet/parser/ast/resource_override.rb index e0be889ff..d638202ab 100644 --- a/lib/puppet/parser/ast/resource_override.rb +++ b/lib/puppet/parser/ast/resource_override.rb @@ -3,12 +3,11 @@ require 'puppet/parser/ast/resource' class Puppet::Parser::AST # Set a parameter on a resource specification created somewhere else in the # configuration. The object is responsible for verifying that this is allowed. - class ResourceOverride < Resource + class ResourceOverride < AST::Branch associates_doc - attr_accessor :object - attr_reader :parameters + attr_accessor :object, :parameters # Iterate across all of our children. def each diff --git a/lib/puppet/parser/ast/top_level_construct.rb b/lib/puppet/parser/ast/top_level_construct.rb new file mode 100644 index 000000000..901a939c2 --- /dev/null +++ b/lib/puppet/parser/ast/top_level_construct.rb @@ -0,0 +1,4 @@ +# The base class for AST nodes representing top level things: +# hostclasses, definitions, and nodes. +class Puppet::Parser::AST::TopLevelConstruct < Puppet::Parser::AST +end diff --git a/lib/puppet/parser/compiler.rb b/lib/puppet/parser/compiler.rb index 6e8e3d26b..a891f1a11 100644 --- a/lib/puppet/parser/compiler.rb +++ b/lib/puppet/parser/compiler.rb @@ -20,7 +20,7 @@ class Puppet::Parser::Compiler puts detail.backtrace if Puppet[:trace] raise Puppet::Error, "#{detail} on node #{node.name}" ensure - # We get these from the environment and only cache them in a thread + # We get these from the environment and only cache them in a thread # variable for the duration of the compilation. Thread.current[:known_resource_types] = nil Thread.current[:env_module_directories] = nil @@ -133,12 +133,11 @@ class Puppet::Parser::Compiler end # Evaluate each specified class in turn. If there are any classes we can't - # find, just tag the catalog and move on. This method really just - # creates resource objects that point back to the classes, and then the - # resources are themselves evaluated later in the process. + # find, raise an error. This method really just creates resource objects + # that point back to the classes, and then the resources are themselves + # evaluated later in the process. def evaluate_classes(classes, scope, lazy_evaluate = true) raise Puppet::DevError, "No source for scope passed to evaluate_classes" unless scope.source - found = [] param_classes = nil # if we are a param class, save the classes hash # and transform classes to be the keys @@ -153,20 +152,17 @@ class Puppet::Parser::Compiler if param_classes resource = klass.ensure_in_catalog(scope, param_classes[name] || {}) else - found << name and next if scope.class_scope(klass) + next if scope.class_scope(klass) resource = klass.ensure_in_catalog(scope) end # If they've disabled lazy evaluation (which the :include function does), # then evaluate our resource immediately. resource.evaluate unless lazy_evaluate - found << name else - Puppet.warning "Could not find class #{name} for #{node.name}" - @catalog.tag(name) + raise Puppet::Error, "Could not find class #{name} for #{node.name}" end end - found end def evaluate_relationships diff --git a/lib/puppet/parser/functions/create_resources.rb b/lib/puppet/parser/functions/create_resources.rb new file mode 100644 index 000000000..430f110b4 --- /dev/null +++ b/lib/puppet/parser/functions/create_resources.rb @@ -0,0 +1,47 @@ +Puppet::Parser::Functions::newfunction(:create_resources, :doc => ' +Converts a hash into a set of resources and adds them to the catalog. +Takes two parameters: + create_resource($type, $resources) + Creates resources of type $type from the $resources hash. Assumes that + hash is in the following form: + {title=>{parameters}} + This is currently tested for defined resources, classes, as well as native types +') do |args| + raise ArgumentError, ("create_resources(): wrong number of arguments (#{args.length}; must be 2)") if args.length != 2 + #raise ArgumentError, 'requires resource type and param hash' if args.size < 2 + # figure out what kind of resource we are + type_of_resource = nil + type_name = args[0].downcase + if type_name == 'class' + type_of_resource = :class + else + if resource = Puppet::Type.type(type_name.to_sym) + type_of_resource = :type + elsif resource = find_definition(type_name.downcase) + type_of_resource = :define + else + raise ArgumentError, "could not create resource of unknown type #{type_name}" + end + end + # iterate through the resources to create + args[1].each do |title, params| + raise ArgumentError, 'params should not contain title' if(params['title']) + case type_of_resource + when :type + res = resource.hash2resource(params.merge(:title => title)) + catalog.add_resource(res) + when :define + p_resource = Puppet::Parser::Resource.new(type_name, title, :scope => self, :source => resource) + params.merge(:name => title).each do |k,v| + p_resource.set_parameter(k,v) + end + resource.instantiate_resource(self, p_resource) + compiler.add_resource(self, p_resource) + when :class + klass = find_hostclass(title) + raise ArgumentError, "could not find hostclass #{title}" unless klass + klass.ensure_in_catalog(self, params) + compiler.catalog.add_class([title]) + end + end +end diff --git a/lib/puppet/parser/functions/fqdn_rand.rb b/lib/puppet/parser/functions/fqdn_rand.rb index 52946f2c1..91157a148 100644 --- a/lib/puppet/parser/functions/fqdn_rand.rb +++ b/lib/puppet/parser/functions/fqdn_rand.rb @@ -5,8 +5,8 @@ Puppet::Parser::Functions::newfunction(:fqdn_rand, :type => :rvalue, :doc => $random_number = fqdn_rand(30) $random_number_seed = fqdn_rand(30,30)") do |args| - require 'md5' + require 'digest/md5' max = args.shift - srand MD5.new([lookupvar('fqdn'),args].join(':')).to_s.hex + srand(Digest::MD5.hexdigest([lookupvar('fqdn'),args].join(':')).hex) rand(max).to_s end diff --git a/lib/puppet/parser/grammar.ra b/lib/puppet/parser/grammar.ra index af0ab182b..8339c51b7 100644 --- a/lib/puppet/parser/grammar.ra +++ b/lib/puppet/parser/grammar.ra @@ -28,41 +28,33 @@ prechigh preclow rule -program: statements { - if val[0] - # Make sure we always return an array. - if val[0].is_a?(AST::ASTArray) - if val[0].children.empty? - result = nil - else - result = val[0] - end - else - result = aryfy(val[0]) - end - else - result = nil - end -} +program: statements_and_declarations | nil -statements: statement - | statements statement { - if val[0] and val[1] - if val[0].instance_of?(AST::ASTArray) + statements_and_declarations: statement_or_declaration { + result = ast AST::ASTArray, :children => (val[0] ? [val[0]] : []) + } + | statements_and_declarations statement_or_declaration { + if val[1] val[0].push(val[1]) - result = val[0] - else - result = ast AST::ASTArray, :children => [val[0],val[1]] end - elsif obj = (val[0] || val[1]) - result = obj - else result = nil + result = val[0] + } + +# statements is like statements_and_declarations, but it doesn't allow +# nested definitions, classes, or nodes. +statements: statements_and_declarations { + val[0].each do |stmt| + if stmt.is_a?(AST::TopLevelConstruct) + error "Classes, definitions, and nodes may only appear at toplevel or inside other classes", \ + :line => stmt.context[:line], :file => stmt.context[:file] + end end + result = val[0] } # The main list of valid statements -statement: resource +statement_or_declaration: resource | virtualresource | collection | assignment @@ -89,19 +81,17 @@ relationship_side: resource | resourceref | collection edge: IN_EDGE | OUT_EDGE | IN_EDGE_SUB | OUT_EDGE_SUB fstatement: NAME LPAREN funcvalues RPAREN { - args = aryfy(val[2]) result = ast AST::Function, :name => val[0][:value], :line => val[0][:line], - :arguments => args, + :arguments => val[2], :ftype => :statement } | NAME LPAREN funcvalues COMMA RPAREN { - args = aryfy(val[2]) result = ast AST::Function, :name => val[0][:value], :line => val[0][:line], - :arguments => args, + :arguments => val[2], :ftype => :statement } | NAME LPAREN RPAREN { result = ast AST::Function, @@ -111,29 +101,22 @@ fstatement: NAME LPAREN funcvalues RPAREN { :ftype => :statement } | NAME funcvalues { - args = aryfy(val[1]) result = ast AST::Function, :name => val[0][:value], :line => val[0][:line], - :arguments => args, + :arguments => val[1], :ftype => :statement } -funcvalues: namestring - | resourceref +funcvalues: namestring { result = aryfy(val[0]) } + | resourceref { result = aryfy(val[0]) } | funcvalues COMMA namestring { - result = aryfy(val[0], val[2]) - result.line = @lexer.line - result.file = @lexer.file + val[0].push(val[2]) + result = val[0] } | funcvalues COMMA resourceref { - unless val[0].is_a?(AST::ASTArray) - val[0] = aryfy(val[0]) - end - - val[0].push(val[2]) - - result = val[0] + val[0].push(val[2]) + result = val[0] } # This is *almost* an rvalue, but I couldn't get a full @@ -152,23 +135,7 @@ namestring: name resource: classname LBRACE resourceinstances endsemi RBRACE { @lexer.commentpop - array = val[2] - array = [array] if array.instance_of?(AST::ResourceInstance) - result = ast AST::ASTArray - - # this iterates across each specified resourceinstance - array.each { |instance| - raise Puppet::Dev, "Got something that isn't an instance" unless instance.instance_of?(AST::ResourceInstance) - # now, i need to somehow differentiate between those things with - # arrays in their names, and normal things - - result.push ast( - AST::Resource, - :type => val[0], - :title => instance[0], - - :parameters => instance[1]) - } + result = ast(AST::Resource, :type => val[0], :instances => val[2]) } | classname LBRACE params endcomma RBRACE { # This is a deprecated syntax. error "All resource specifications require names" @@ -197,14 +164,8 @@ virtualresource: at resource { method = type.to_s + "=" - # Just mark our resources as exported and pass them through. - if val[1].instance_of?(AST::ASTArray) - val[1].each do |obj| - obj.send(method, true) - end - else - val[1].send(method, true) - end + # Just mark our resource as exported and pass it through. + val[1].send(method, true) result = val[1] } @@ -303,17 +264,13 @@ colllval: variable | name resourceinst: resourcename COLON params endcomma { - result = ast AST::ResourceInstance, :children => [val[0],val[2]] + result = ast AST::ResourceInstance, :title => val[0], :parameters => val[2] } -resourceinstances: resourceinst +resourceinstances: resourceinst { result = aryfy(val[0]) } | resourceinstances SEMIC resourceinst { - if val[0].instance_of?(AST::ResourceInstance) - result = ast AST::ASTArray, :children => [val[0],val[2]] - else val[0].push val[2] result = val[0] - end } endsemi: # nothing @@ -358,14 +315,10 @@ params: # nothing { result = ast AST::ASTArray } - | param { result = val[0] } + | param { result = aryfy(val[0]) } | params COMMA param { - if val[0].instance_of?(AST::ASTArray) val[0].push(val[2]) result = val[0] - else - result = ast AST::ASTArray, :children => [val[0],val[2]] - end } param: NAME FARROW rvalue { @@ -384,24 +337,14 @@ anyparams: # nothing { result = ast AST::ASTArray } - | anyparam { result = val[0] } + | anyparam { result = aryfy(val[0]) } | anyparams COMMA anyparam { - if val[0].instance_of?(AST::ASTArray) val[0].push(val[2]) result = val[0] - else - result = ast AST::ASTArray, :children => [val[0],val[2]] - end } -rvalues: rvalue - | rvalues comma rvalue { - if val[0].instance_of?(AST::ASTArray) - result = val[0].push(val[2]) - else - result = ast AST::ASTArray, :children => [val[0],val[2]] - end -} +rvalues: rvalue { result = aryfy(val[0]) } + | rvalues comma rvalue { result = val[0].push(val[2]) } simplervalue: quotedtext | name @@ -425,10 +368,9 @@ rvalue: quotedtext # We currently require arguments in these functions. funcrvalue: NAME LPAREN funcvalues RPAREN { - args = aryfy(val[2]) result = ast AST::Function, :name => val[0][:value], :line => val[0][:line], - :arguments => args, + :arguments => val[2], :ftype => :rvalue } | NAME LPAREN RPAREN { result = ast AST::Function, @@ -572,19 +514,13 @@ expression: rvalue casestatement: CASE rvalue LBRACE caseopts RBRACE { @lexer.commentpop - options = val[3] - options = ast AST::ASTArray, :children => [val[3]] unless options.instance_of?(AST::ASTArray) - result = ast AST::CaseStatement, :test => val[1], :options => options + result = ast AST::CaseStatement, :test => val[1], :options => val[3] } -caseopts: caseopt +caseopts: caseopt { result = aryfy(val[0]) } | caseopts caseopt { - if val[0].instance_of?(AST::ASTArray) val[0].push val[1] result = val[0] - else - result = ast AST::ASTArray, :children => [val[0], val[1]] - end } caseopt: casevalues COLON LBRACE statements RBRACE { @@ -601,14 +537,10 @@ caseopt: casevalues COLON LBRACE statements RBRACE { ) } -casevalues: selectlhand +casevalues: selectlhand { result = aryfy(val[0]) } | casevalues COMMA selectlhand { - if val[0].instance_of?(AST::ASTArray) val[0].push(val[2]) result = val[0] - else - result = ast AST::ASTArray, :children => [val[0],val[2]] - end } selector: selectlhand QMARK svalues { @@ -658,48 +590,51 @@ import: IMPORT strings { import(file) end - result = AST::ASTArray.new(:children => []) + result = nil } # Disable definition inheritance for now. 8/27/06, luke #definition: DEFINE NAME argumentlist parent LBRACE statements RBRACE { definition: DEFINE classname argumentlist LBRACE statements RBRACE { @lexer.commentpop - newdefine classname(val[1]), :arguments => val[2], :code => val[4], :line => val[0][:line] + result = Puppet::Parser::AST::Definition.new(classname(val[1]), + ast_context(true).merge(:arguments => val[2], :code => val[4], + :line => val[0][:line])) @lexer.indefine = false - result = nil #} | DEFINE NAME argumentlist parent LBRACE RBRACE { } | DEFINE classname argumentlist LBRACE RBRACE { @lexer.commentpop - newdefine classname(val[1]), :arguments => val[2], :line => val[0][:line] + result = Puppet::Parser::AST::Definition.new(classname(val[1]), + ast_context(true).merge(:arguments => val[2], :line => val[0][:line])) @lexer.indefine = false - result = nil } #hostclass: CLASS NAME argumentlist parent LBRACE statements RBRACE { -hostclass: CLASS classname argumentlist classparent LBRACE statements RBRACE { +hostclass: CLASS classname argumentlist classparent LBRACE statements_and_declarations RBRACE { @lexer.commentpop # Our class gets defined in the parent namespace, not our own. @lexer.namepop - newclass classname(val[1]), :arguments => val[2], :parent => val[3], :code => val[5], :line => val[0][:line] - result = nil + result = Puppet::Parser::AST::Hostclass.new(classname(val[1]), + ast_context(true).merge(:arguments => val[2], :parent => val[3], + :code => val[5], :line => val[0][:line])) } | CLASS classname argumentlist classparent LBRACE RBRACE { @lexer.commentpop # Our class gets defined in the parent namespace, not our own. @lexer.namepop - newclass classname(val[1]), :arguments => val[2], :parent => val[3], :line => val[0][:line] - result = nil + result = Puppet::Parser::AST::Hostclass.new(classname(val[1]), + ast_context(true).merge(:arguments => val[2], :parent => val[3], + :line => val[0][:line])) } nodedef: NODE hostnames nodeparent LBRACE statements RBRACE { @lexer.commentpop - newnode val[1], :parent => val[2], :code => val[4], :line => val[0][:line] - result = nil + result = Puppet::Parser::AST::Node.new(val[1], + ast_context(true).merge(:parent => val[2], :code => val[4], + :line => val[0][:line])) } | NODE hostnames nodeparent LBRACE RBRACE { @lexer.commentpop - newnode val[1], :parent => val[2], :line => val[0][:line] - result = nil + result = Puppet::Parser::AST::Node.new(val[1], ast_context(true).merge(:parent => val[2], :line => val[0][:line])) } classref: CLASSREF { result = val[0][:value] } @@ -710,10 +645,11 @@ classname: NAME { result = val[0][:value] } # Multiple hostnames, as used for node names. These are all literal # strings, not AST objects. -hostnames: nodename +hostnames: nodename { + result = [result] +} | hostnames COMMA nodename { result = val[0] - result = [result] unless result.is_a?(Array) result << val[2] } @@ -779,22 +715,9 @@ variable: VARIABLE { result = ast AST::Variable, :value => val[0][:value], :line => val[0][:line] } -array: LBRACK rvalues RBRACK { - if val[1].instance_of?(AST::ASTArray) - result = val[1] - else - result = ast AST::ASTArray, :children => [val[1]] - end -} - | LBRACK rvalues COMMA RBRACK { - if val[1].instance_of?(AST::ASTArray) - result = val[1] - else - result = ast AST::ASTArray, :children => [val[1]] - end -} | LBRACK RBRACK { - result = ast AST::ASTArray -} +array: LBRACK rvalues RBRACK { result = val[1] } + | LBRACK rvalues COMMA RBRACK { result = val[1] } + | LBRACK RBRACK { result = ast AST::ASTArray } comma: FARROW | COMMA diff --git a/lib/puppet/parser/lexer.rb b/lib/puppet/parser/lexer.rb index 71d9440ff..2f416615e 100644 --- a/lib/puppet/parser/lexer.rb +++ b/lib/puppet/parser/lexer.rb @@ -533,7 +533,7 @@ class Puppet::Parser::Lexer when 'n'; "\n" when 't'; "\t" when 's'; " " - when "\n": '' + when "\n"; '' else ch end else diff --git a/lib/puppet/parser/parser.rb b/lib/puppet/parser/parser.rb index c2fbf976d..300ddddd6 100644 --- a/lib/puppet/parser/parser.rb +++ b/lib/puppet/parser/parser.rb @@ -21,7 +21,7 @@ module Puppet module Parser class Parser < Racc::Parser -module_eval(<<'...end grammar.ra/module_eval...', 'grammar.ra', 866) +module_eval(<<'...end grammar.ra/module_eval...', 'grammar.ra', 789) # It got too annoying having code in a file that needs to be compiled. require 'puppet/parser/parser_support' @@ -30,647 +30,612 @@ require 'puppet/parser/parser_support' # Local Variables: # mode: ruby # End: - -# $Id$ ...end grammar.ra/module_eval... ##### State transition tables begin ### racc_action_table = [ - 256, 257, 228, 63, 327, 64, 156, 54, 82, 356, - -166, 245, 176, 205, 210, 254, 37, 357, 65, 244, - 38, -168, 201, 203, 206, 209, 184, 11, 255, 241, - 242, 158, 54, 251, 72, 75, 72, 75, 102, 117, - 106, -170, 62, 194, 230, 58, 204, 208, 60, 306, - 213, 196, 197, 198, 200, 202, 97, 207, 211, 72, - 75, 241, 242, 102, 199, 106, 163, 71, 59, 307, - 58, 83, 86, 60, 193, 92, 54, 162, 72, 75, - 78, 100, 169, 163, 89, 72, 75, 94, 308, 102, - 163, 106, 71, 59, 162, 59, 83, 86, 59, 169, - 92, 162, 311, 72, 75, 78, 169, 97, 181, 89, - 353, 71, 228, 352, 58, 83, 269, 60, 71, 92, - 59, 345, 83, 86, 137, 184, 92, -171, 89, 72, - 75, 78, 100, 246, 368, 89, 71, 59, 94, 59, - 83, 86, 309, 173, 92, 314, 59, 163, 76, 78, - 72, 75, -167, 89, 102, 310, 106, 37, 162, 173, - 218, 127, 71, 169, 59, 220, 83, 269, 11, 14, - 92, 63, 97, 152, 37, 137, 72, 75, 127, 89, - 102, 319, 106, 71, 218, 11, 14, 83, 86, 220, - 59, 92, 72, 75, 72, 75, 78, 100, 270, 279, - 89, 349, 278, 94, 353, 207, 211, 352, 320, 71, - -169, 59, 199, 83, 86, 197, 198, 92, 72, 75, - 207, 211, 78, -169, 37, 71, 89, 199, 38, 83, - 269, -167, 193, 92, -166, 11, 14, 59, 137, 72, - 75, 272, 89, 102, 182, 106, 37, 207, 211, -186, - 38, 71, 181, 59, 199, 83, 86, 11, 337, 92, - 231, 97, 339, 76, 78, 72, 75, 37, 89, 82, - 48, 38, 71, 48, 323, 176, 83, 86, 11, 59, - 92, 342, 46, 47, 184, 78, 100, 74, -168, 89, - 72, 75, 94, -172, 102, 346, 106, -173, 71, 175, - 59, 59, 83, 86, 240, -171, 92, -170, 241, 242, - 76, 78, 97, 197, 198, 89, 72, 75, 207, 211, - 102, 214, 106, 71, 64, 199, 59, 83, 86, 276, - 215, 92, 217, 246, 275, 173, 78, 100, 97, 82, - 89, 72, 75, 94, 155, 102, 122, 106, 152, 71, - 223, 59, -168, 83, 86, 249, 277, 92, 176, 246, - 247, 122, 78, 100, 225, -166, 89, 72, 75, 94, - 117, 102, 226, 106, 71, -169, 271, 59, 83, 86, - 246, 247, 92, -21, -21, -21, -21, 78, 226, 97, - -167, 89, 72, 75, 52, -168, 102, -166, 106, -169, - 71, -167, 59, -171, 83, 86, 366, 152, 92, -23, - -23, -23, -23, 78, 100, 228, 226, 89, 72, 75, - 94, 50, 102, 373, 106, 71, 49, 375, 59, 83, - 86, 229, -221, 92, 237, 378, 72, 75, 78, 40, - 97, 39, 89, 355, 44, 45, 41, 42, 231, 234, - nil, 71, nil, 59, nil, 83, 86, nil, nil, 92, - 44, 45, 41, 42, 78, 100, 72, 75, 89, 71, - 102, 94, 106, 83, 269, nil, nil, 92, nil, 59, - nil, nil, 137, nil, nil, nil, 89, nil, 97, nil, - nil, nil, 72, 75, nil, nil, 102, 59, 106, 71, - nil, nil, nil, 83, 86, nil, nil, 92, nil, nil, - nil, nil, 78, 100, 97, nil, 89, nil, nil, 94, - nil, nil, 72, 75, nil, 71, 102, 59, 106, 83, - 86, nil, nil, 92, nil, nil, nil, nil, 78, 100, - nil, nil, 89, nil, 97, 94, nil, nil, 72, 75, - nil, nil, 102, 59, 106, 71, nil, nil, nil, 83, - 86, nil, nil, 92, nil, nil, 72, 75, 78, 100, - 97, nil, 89, 72, 75, 94, nil, 102, nil, 106, - nil, 71, nil, 59, nil, 83, 86, 72, 75, 92, - nil, 102, nil, nil, 78, 100, nil, nil, 89, 71, - nil, 94, nil, 83, 269, nil, 71, 92, nil, 59, - 83, 86, 137, nil, 92, nil, 89, nil, nil, 78, - 71, nil, nil, 89, 83, 143, nil, 59, 92, nil, - nil, nil, nil, 137, 59, 72, 75, 89, nil, 102, - nil, 106, 213, 196, 197, 198, 200, 202, 59, 207, - 211, nil, 213, 196, 197, 198, 199, 97, nil, 207, - 211, 72, 75, nil, nil, 102, 199, 106, 71, nil, - nil, nil, 83, 86, nil, nil, 92, nil, nil, nil, - nil, 78, 100, 97, nil, 89, nil, nil, 94, nil, - nil, 72, 75, nil, 71, 102, 59, 106, 83, 86, - nil, nil, 92, nil, nil, nil, nil, 78, 100, nil, - nil, 89, nil, 97, 94, nil, nil, nil, nil, nil, - nil, nil, 59, nil, 71, nil, nil, nil, 83, 86, - 72, 75, 92, nil, 102, 189, 106, 78, 100, nil, - nil, 89, nil, nil, 94, nil, nil, nil, nil, 72, - 75, nil, 59, 102, nil, 106, 72, 75, nil, nil, - 102, nil, 106, 71, nil, nil, nil, 83, 86, nil, - nil, 92, nil, nil, nil, nil, 78, nil, 97, nil, - 89, nil, 71, nil, nil, nil, 83, 86, nil, 71, - 92, 59, nil, 83, 86, 78, nil, 92, nil, 89, - nil, nil, 78, 100, nil, nil, 89, 72, 75, 94, - 59, 102, nil, 106, nil, nil, nil, 59, nil, nil, - nil, nil, nil, nil, nil, nil, 72, 75, nil, 97, - 102, nil, 106, 72, 75, nil, nil, 102, nil, 106, - 71, nil, nil, nil, 83, 86, nil, nil, 92, nil, - nil, nil, nil, 78, 100, 97, nil, 89, nil, 71, - 94, nil, nil, 83, 86, nil, 71, 92, 59, nil, - 83, 86, 78, nil, 92, nil, 89, nil, nil, 78, - 100, nil, nil, 89, 72, 75, 94, 59, 102, nil, - 106, nil, nil, nil, 59, nil, nil, nil, nil, nil, - nil, nil, nil, 72, 75, nil, 97, nil, nil, 72, - 75, nil, nil, nil, nil, nil, nil, 71, nil, nil, - nil, 83, 86, nil, nil, 92, 340, nil, nil, nil, - 78, 100, 177, nil, 89, nil, 71, 94, nil, nil, - 83, 86, 71, nil, 92, 59, 83, 86, 76, 78, - 92, nil, nil, 89, 76, 78, 72, 75, nil, 89, - 102, nil, 106, nil, 59, nil, 213, 196, 197, 198, - 59, nil, nil, 207, 211, 72, 75, nil, 97, 102, - 199, 106, 72, 75, nil, nil, nil, nil, nil, 71, - nil, nil, nil, 83, 86, nil, nil, 92, nil, nil, - 72, 75, 78, 100, nil, nil, 89, nil, 71, 94, - nil, nil, 83, 86, nil, 71, 92, 59, nil, 83, - 269, 78, nil, 92, nil, 89, nil, nil, 137, nil, - nil, nil, 89, 71, nil, nil, 59, 83, 269, nil, - nil, 92, nil, 59, nil, nil, 137, 72, 75, nil, - 89, 102, nil, 106, nil, nil, nil, nil, nil, nil, - nil, 59, nil, nil, nil, nil, 72, 75, nil, 97, - 102, nil, 106, 72, 75, nil, nil, 102, nil, 106, - 71, nil, nil, nil, 83, 86, nil, nil, 92, nil, - nil, nil, nil, 78, 100, 72, 75, 89, nil, 71, - 94, nil, nil, 83, 86, nil, 71, 92, 59, nil, - 83, 86, 78, nil, 92, nil, 89, nil, nil, 78, - 72, 75, nil, 89, 102, nil, 106, 59, 71, nil, - nil, nil, 83, 269, 59, nil, 92, nil, 72, 75, - nil, 137, 102, nil, 106, 89, nil, nil, nil, nil, - nil, nil, nil, 71, nil, nil, 59, 83, 86, nil, - 97, 92, nil, 72, 75, nil, 78, 102, nil, 106, - 89, 71, nil, 72, 75, 83, 86, 102, nil, 92, - nil, 59, nil, nil, 78, 100, nil, nil, 89, nil, - nil, 94, nil, nil, nil, nil, 71, nil, nil, 59, - 83, 86, nil, nil, 92, nil, 71, nil, nil, 78, - 83, 269, nil, 89, 92, nil, 72, 75, nil, 137, - 102, nil, 106, 89, 59, nil, nil, nil, nil, nil, - nil, nil, nil, nil, 59, 72, 75, nil, 97, 102, - nil, 106, 72, 75, nil, nil, 102, nil, 106, 71, - nil, nil, nil, 83, 86, nil, nil, 92, nil, nil, - nil, nil, 78, 100, 97, nil, 89, nil, 71, 94, - nil, nil, 83, 86, nil, 71, 92, 59, nil, 83, - 86, 78, nil, 92, nil, 89, nil, nil, 78, 100, - 212, nil, 89, nil, nil, 94, 59, nil, nil, 205, - 210, nil, nil, 59, nil, nil, nil, nil, 201, 203, - 206, 209, nil, nil, 205, 210, nil, nil, nil, nil, - nil, nil, 274, 201, 203, 206, 209, nil, nil, nil, - nil, nil, 204, 208, nil, nil, 213, 196, 197, 198, - 200, 202, nil, 207, 211, nil, nil, 204, 208, nil, - 199, 213, 196, 197, 198, 200, 202, nil, 207, 211, - 205, 210, nil, nil, nil, 199, nil, nil, nil, 201, - 203, 206, 209, nil, nil, 205, 210, nil, nil, nil, - nil, nil, nil, nil, 201, 203, 206, 209, nil, nil, - nil, nil, nil, nil, 208, nil, nil, 213, 196, 197, - 198, 200, 202, nil, 207, 211, nil, nil, 204, 208, - nil, 199, 213, 196, 197, 198, 200, 202, nil, 207, - 211, 205, 210, nil, nil, nil, 199, nil, nil, nil, - 201, 203, 206, 209, nil, nil, 205, 210, nil, nil, - nil, nil, nil, nil, nil, 201, 203, 206, 209, nil, - nil, nil, nil, nil, 204, 208, nil, nil, 213, 196, - 197, 198, 200, 202, nil, 207, 211, nil, nil, nil, - nil, nil, 199, 213, 196, 197, 198, 200, 202, nil, - 207, 211, 205, 210, nil, nil, nil, 199, nil, nil, - nil, 201, 203, 206, 209, nil, nil, nil, 210, nil, - 213, 196, 197, 198, 200, 202, 201, 207, 211, nil, - nil, nil, nil, nil, 199, 204, 208, 210, nil, 213, - 196, 197, 198, 200, 202, 201, 207, 211, nil, nil, - nil, nil, 210, 199, 213, 196, 197, 198, 200, 202, - 201, 207, 211, nil, nil, nil, nil, nil, 199, nil, - nil, 210, nil, 213, 196, 197, 198, 200, 202, 201, - 207, 211, nil, nil, nil, nil, nil, 199, 213, 196, - 197, 198, 200, 202, nil, 207, 211, nil, nil, 384, - nil, nil, 199, nil, nil, nil, nil, 213, 196, 197, - 198, 200, 202, nil, 207, 211, nil, nil, 297, nil, - 26, 199, 33, 1, nil, 7, 12, nil, 17, nil, - 23, nil, 29, nil, 3, nil, nil, 11, 14, 26, - 305, 33, 1, nil, 7, 12, nil, 17, nil, 23, - nil, 29, nil, 3, nil, nil, 11, 14, nil, 383, - nil, 26, nil, 33, 1, nil, 7, 12, nil, 17, - nil, 23, nil, 29, nil, 3, nil, nil, 11, 14, - 26, 325, 33, 1, nil, 7, 12, nil, 17, nil, - 23, nil, 29, nil, 3, nil, nil, 11, 14, nil, - 382, nil, 26, nil, 33, 1, nil, 7, 12, nil, - 17, nil, 23, nil, 29, nil, 3, nil, nil, 11, - 14, 26, 380, 33, 1, nil, 7, 12, nil, 17, - nil, 23, nil, 29, nil, 3, nil, nil, 11, 14, - nil, 376, nil, 26, nil, 33, 1, nil, 7, 12, - nil, 17, nil, 23, nil, 29, nil, 3, nil, nil, - 11, 14, 26, 350, 33, 1, nil, 7, 12, nil, - 17, nil, 23, nil, 29, nil, 3, nil, nil, 11, - 14, nil, 358, nil, 26, nil, 33, 1, nil, 7, - 12, nil, 17, nil, 23, nil, 29, nil, 3, nil, - nil, 11, 14, 26, 365, 33, 1, nil, 7, 12, - nil, 17, nil, 23, nil, 29, nil, 3, nil, nil, - 11, 14, nil, 364, nil, 26, nil, 33, 1, nil, - 7, 12, nil, 17, nil, 23, nil, 29, nil, 3, - nil, nil, 11, 14, 26, nil, 33, 1, nil, 7, - 12, nil, 17, nil, 23, nil, 29, nil, 3, nil, - nil, 11, 14, 26, nil, 33, 1, nil, 7, 12, - nil, 17, nil, 23, nil, 29, nil, 3, nil, nil, - 11, 14, 26, nil, 33, 1, nil, 7, 12, nil, - 17, nil, 23, nil, 29, nil, 3, nil, nil, 11, - 14 ] + 242, 243, 55, 68, 71, 299, 157, 55, 78, 117, + 199, 68, 71, 181, 186, -169, 36, 112, 341, 113, + 38, 55, 177, 179, 182, 185, 170, 10, 68, 71, + 231, 158, 114, 292, 293, 356, 257, 368, 68, 71, + 59, 198, 100, 61, 103, 59, 180, 184, 61, 198, + 189, 172, 173, 174, 176, 178, 111, 183, 187, 59, + 95, 66, 61, 60, 175, 79, 253, 154, 60, 88, + 345, 66, 233, 229, 139, 79, 81, 231, 84, 88, + 68, 71, 60, 225, 74, 99, 68, 71, 84, 60, + 100, 90, 103, 203, 203, 292, 293, 223, 296, 60, + 203, 117, 231, 78, 202, 202, 295, 240, 95, 209, + 209, 202, 166, 66, 186, 170, 209, 79, 253, 66, + 241, 88, 177, 79, 81, 334, 139, 88, 68, 71, + 84, 310, 74, 99, 68, 71, 84, 357, 100, 90, + 103, 60, 183, 187, 311, 358, 307, 60, 308, 175, + 189, 172, 173, 174, 176, 178, 95, 183, 187, 36, + 309, 66, 288, 38, 175, 79, 253, 66, 218, 88, + 10, 79, 81, 219, 139, 88, 338, 312, 84, 336, + 74, 99, 68, 71, 84, 218, 100, 90, 103, 60, + 219, 173, 174, 217, 285, 60, 183, 187, 257, 284, + 203, 68, 71, 175, 95, 100, 36, 103, 68, 71, + 127, 202, 100, 316, 103, 66, 209, 10, 15, 79, + 81, 173, 174, 88, 183, 187, 183, 187, 74, 99, + 95, 175, 84, 175, 66, 90, 113, 338, 79, 81, + 336, 66, 88, 60, 213, 79, 81, 74, 319, 88, + 216, 84, 68, 71, 74, 99, 213, 49, 84, 68, + 71, 90, 60, 100, 215, 103, 47, 48, 287, 60, + 154, 286, 189, 172, 173, 174, 324, 68, 71, 183, + 187, 100, 213, 103, 36, 66, 175, 327, 38, 79, + 253, 314, 66, 88, 200, 10, 79, 81, 139, 95, + 88, -171, 84, 68, 71, 74, 330, 78, 170, 84, + 66, -172, 259, 60, 79, 81, 257, 258, 88, -173, + 60, -168, -170, 74, 99, 70, 228, 84, 68, 71, + 90, 36, 100, -167, 103, 127, 66, -167, 60, 161, + 79, 81, 10, 15, 88, -169, -171, 297, 72, 74, + 95, 257, 258, 84, 68, 71, 36, -172, 100, -168, + 38, 66, 112, -170, 60, 79, 81, 10, 15, 88, + -22, -22, -22, -22, 74, 99, 68, 71, 84, 290, + 100, 90, 103, 292, 293, -167, 167, 66, 166, 60, + 335, 79, 253, 229, -187, 88, 339, 68, 71, 161, + 139, 100, 49, 103, 84, 43, 44, 40, 41, 66, + 234, -169, -174, 79, 81, 60, 156, 88, 154, 68, + 71, 354, 74, 100, 122, 103, 84, 122, 359, 161, + 66, 60, -170, 53, 79, 81, 229, 60, 88, 366, + 68, 71, 52, 74, 100, -168, 103, 84, 43, 44, + 40, 41, 66, 232, 51, 373, 79, 81, 60, 374, + 88, -169, 95, -167, -170, 74, 68, 71, -168, 84, + 100, -172, 103, 66, 60, 376, 45, 79, 81, -222, + 60, 88, -24, -24, -24, -24, 74, 99, 95, 234, + 84, 379, 238, 90, 39, 384, 68, 71, 385, 66, + 100, 60, 103, 79, 81, nil, nil, 88, nil, nil, + nil, nil, 74, 99, nil, nil, 84, nil, 95, 90, + nil, nil, 68, 71, nil, nil, 100, 60, 103, 66, + nil, nil, nil, 79, 81, nil, nil, 88, nil, nil, + nil, nil, 74, 99, 95, nil, 84, nil, nil, 90, + nil, nil, 68, 71, nil, 66, 100, 60, 103, 79, + 81, nil, nil, 88, nil, nil, nil, nil, 74, 99, + nil, nil, 84, nil, 95, 90, nil, nil, 68, 71, + nil, nil, 100, 60, 103, 66, nil, nil, nil, 79, + 81, nil, nil, 88, nil, nil, nil, nil, 74, 99, + 95, nil, 84, nil, nil, 90, nil, nil, 68, 71, + nil, 66, 100, 60, 103, 79, 81, nil, nil, 88, + nil, nil, nil, nil, 74, 99, nil, nil, 84, nil, + 95, 90, nil, nil, 68, 71, nil, nil, 100, 60, + 103, 66, nil, nil, nil, 79, 81, nil, nil, 88, + 68, 71, nil, nil, 74, 99, 68, 71, 84, nil, + 100, 90, 103, nil, nil, nil, nil, 66, nil, 60, + nil, 79, 81, nil, nil, 88, nil, nil, 95, nil, + 74, 68, 71, 66, 84, 100, nil, 79, 253, 66, + nil, 88, nil, 79, 81, 60, 139, 88, nil, nil, + 84, nil, 74, 99, nil, nil, 84, 68, 71, 90, + nil, 60, nil, nil, 66, nil, nil, 60, 79, 144, + nil, nil, 88, nil, nil, nil, nil, 139, 68, 71, + nil, 84, 100, nil, 103, nil, nil, nil, nil, nil, + 66, nil, 60, nil, 79, 253, 68, 71, 88, nil, + 100, nil, 103, 139, nil, nil, nil, 84, nil, nil, + nil, 66, nil, nil, nil, 79, 81, nil, 60, 88, + nil, 68, 71, nil, 74, nil, nil, nil, 84, 66, + nil, nil, nil, 79, 81, nil, nil, 88, nil, 60, + nil, nil, 74, nil, 261, nil, 84, 68, 71, nil, + nil, 100, nil, 103, 66, nil, nil, 60, 79, 81, + nil, nil, 88, nil, nil, nil, 72, 74, 68, 71, + nil, 84, 100, nil, 103, nil, nil, nil, nil, nil, + 66, nil, 60, nil, 79, 81, nil, nil, 88, nil, + 95, nil, nil, 74, 68, 71, nil, 84, nil, nil, + nil, 66, nil, nil, nil, 79, 81, nil, 60, 88, + nil, nil, nil, nil, 74, 99, nil, 162, 84, 68, + 71, 90, nil, 100, nil, 103, nil, 66, nil, 60, + nil, 79, 81, nil, nil, 88, nil, nil, nil, 72, + 74, 95, nil, nil, 84, 68, 71, nil, nil, 100, + nil, 103, 66, nil, nil, 60, 79, 81, nil, nil, + 88, nil, nil, nil, nil, 74, 99, 95, nil, 84, + 68, 71, 90, nil, 100, nil, 103, nil, 66, nil, + 60, nil, 79, 81, 68, 71, 88, nil, nil, nil, + 255, 74, 99, nil, nil, 84, nil, nil, 90, nil, + nil, nil, nil, 66, nil, nil, 60, 79, 81, 68, + 71, 88, nil, 100, nil, 103, 74, 66, nil, nil, + 84, 79, 253, nil, nil, 88, nil, nil, 68, 71, + 139, 60, nil, nil, 84, nil, nil, nil, nil, nil, + nil, nil, 66, nil, nil, 60, 79, 81, nil, nil, + 88, 328, nil, 68, 71, 74, nil, nil, nil, 84, + nil, 66, nil, nil, nil, 79, 81, nil, nil, 88, + 60, 68, 71, 72, 74, 100, 193, 103, 84, nil, + nil, nil, nil, nil, nil, nil, 66, nil, nil, 60, + 79, 253, 68, 71, 88, nil, 100, nil, 103, 139, + nil, nil, nil, 84, 66, nil, nil, nil, 79, 81, + nil, nil, 88, nil, 60, nil, nil, 74, 68, 71, + nil, 84, 100, nil, 103, 66, nil, nil, nil, 79, + 81, nil, 60, 88, nil, nil, nil, nil, 74, nil, + 95, nil, 84, nil, 68, 71, nil, nil, 100, nil, + 103, 66, nil, 60, nil, 79, 81, nil, nil, 88, + nil, nil, nil, nil, 74, 99, 95, nil, 84, 68, + 71, 90, nil, 100, nil, 103, nil, 66, nil, 60, + nil, 79, 81, 68, 71, 88, nil, nil, nil, nil, + 74, 99, nil, nil, 84, nil, nil, 90, nil, nil, + nil, nil, 66, nil, nil, 60, 79, 81, nil, nil, + 88, nil, nil, nil, nil, 74, 66, nil, nil, 84, + 79, 81, nil, nil, 88, nil, nil, nil, 72, 74, + 60, 68, 71, 84, nil, 100, nil, 103, 189, 172, + 173, 174, 176, 178, 60, 183, 187, nil, 189, 172, + 173, 174, 175, 95, nil, 183, 187, 68, 71, nil, + nil, 100, 175, 103, 66, nil, nil, nil, 79, 81, + nil, nil, 88, nil, nil, nil, nil, 74, 99, 95, + nil, 84, nil, nil, 90, nil, nil, 68, 71, nil, + 66, 100, 60, 103, 79, 81, nil, nil, 88, nil, + nil, nil, nil, 74, 99, nil, nil, 84, nil, 95, + 90, nil, nil, 68, 71, nil, nil, 100, 60, 103, + 66, nil, nil, nil, 79, 81, nil, nil, 88, nil, + nil, nil, nil, 74, 99, 95, nil, 84, nil, nil, + 90, nil, nil, nil, nil, nil, 66, nil, 60, nil, + 79, 81, 188, nil, 88, nil, nil, nil, nil, 74, + 99, 181, 186, 84, nil, nil, 90, nil, nil, nil, + 177, 179, 182, 185, 60, nil, 181, 186, nil, nil, + nil, nil, nil, nil, nil, 177, 179, 182, 185, nil, + nil, nil, nil, nil, 180, 184, nil, nil, 189, 172, + 173, 174, 176, 178, nil, 183, 187, nil, nil, 180, + 184, nil, 175, 189, 172, 173, 174, 176, 178, nil, + 183, 187, 181, 186, nil, nil, nil, 175, nil, nil, + 283, 177, 179, 182, 185, nil, nil, 181, 186, nil, + nil, nil, nil, nil, nil, nil, 177, 179, 182, 185, + nil, nil, nil, nil, nil, 180, 184, nil, nil, 189, + 172, 173, 174, 176, 178, nil, 183, 187, nil, nil, + nil, 184, nil, 175, 189, 172, 173, 174, 176, 178, + nil, 183, 187, 181, 186, nil, nil, nil, 175, nil, + nil, nil, 177, 179, 182, 185, nil, nil, 181, 186, + nil, nil, nil, nil, nil, nil, nil, 177, 179, 182, + 185, nil, nil, nil, nil, nil, 180, 184, nil, nil, + 189, 172, 173, 174, 176, 178, nil, 183, 187, nil, + nil, 180, 184, nil, 175, 189, 172, 173, 174, 176, + 178, nil, 183, 187, 181, 186, nil, nil, nil, 175, + nil, nil, nil, 177, 179, 182, 185, nil, nil, 26, + 186, 32, 1, nil, 8, 11, nil, 18, 177, 23, + nil, 29, nil, 2, nil, nil, 10, 15, nil, 186, + nil, 189, 172, 173, 174, 176, 178, 177, 183, 187, + nil, nil, nil, nil, 186, 175, 189, 172, 173, 174, + 176, 178, 177, 183, 187, nil, nil, nil, nil, nil, + 175, nil, nil, nil, nil, 189, 172, 173, 174, 176, + 178, nil, 183, 187, 281, nil, nil, nil, nil, 175, + 189, 172, 173, 174, 176, 178, nil, 183, 187, nil, + nil, nil, nil, 377, 175, 26, nil, 32, 1, nil, + 8, 11, nil, 18, nil, 23, nil, 29, nil, 2, + nil, nil, 10, 15, 26, 364, 32, 1, nil, 8, + 11, nil, 18, nil, 23, nil, 29, nil, 2, nil, + nil, 10, 15, nil, 383, nil, 26, nil, 32, 1, + nil, 8, 11, nil, 18, nil, 23, nil, 29, nil, + 2, nil, nil, 10, 15, 26, 306, 32, 1, nil, + 8, 11, nil, 18, nil, 23, nil, 29, nil, 2, + nil, nil, 10, 15, nil, 381, nil, 26, nil, 32, + 1, nil, 8, 11, nil, 18, nil, 23, nil, 29, + nil, 2, nil, nil, 10, 15, 26, 326, 32, 1, + nil, 8, 11, nil, 18, nil, 23, nil, 29, nil, + 2, nil, nil, 10, 15, nil, nil, nil, 26, nil, + 32, 1, nil, 8, 11, nil, 18, nil, 23, nil, + 29, nil, 2, nil, nil, 10, 15, 26, nil, 32, + 1, nil, 8, 11, nil, 18, nil, 23, nil, 29, + nil, 2, nil, nil, 10, 15, 26, nil, 32, 1, + nil, 8, 11, nil, 18, nil, 23, nil, 29, nil, + 2, nil, nil, 10, 15, 189, 172, 173, 174, 176, + 178, nil, 183, 187, nil, nil, nil, nil, nil, 175 ] racc_action_check = [ - 180, 180, 152, 22, 243, 22, 55, 17, 86, 301, - 81, 165, 96, 180, 180, 178, 12, 301, 22, 165, - 12, 95, 180, 180, 180, 180, 86, 12, 178, 243, - 243, 55, 156, 174, 208, 208, 106, 106, 208, 215, - 208, 91, 22, 106, 152, 17, 180, 180, 17, 218, - 180, 180, 180, 180, 180, 180, 208, 180, 180, 176, - 176, 174, 174, 176, 180, 176, 62, 208, 17, 219, - 156, 208, 208, 156, 106, 208, 158, 62, 369, 369, - 208, 208, 62, 239, 208, 205, 205, 208, 220, 205, - 65, 205, 176, 156, 239, 208, 176, 176, 211, 239, - 176, 65, 224, 181, 181, 176, 65, 205, 273, 176, - 350, 369, 143, 350, 158, 369, 369, 158, 205, 369, - 176, 273, 205, 205, 369, 143, 205, 90, 369, 356, - 356, 205, 205, 344, 344, 205, 181, 158, 205, 369, - 181, 181, 221, 226, 181, 227, 205, 163, 181, 181, - 352, 352, 87, 181, 352, 221, 352, 120, 163, 229, - 309, 120, 356, 163, 181, 309, 356, 356, 120, 120, - 356, 85, 352, 231, 43, 356, 342, 342, 43, 356, - 342, 232, 342, 352, 122, 43, 43, 352, 352, 122, - 356, 352, 182, 182, 278, 278, 352, 352, 182, 195, - 352, 278, 195, 352, 297, 281, 281, 297, 233, 342, - 103, 352, 281, 342, 342, 280, 280, 342, 184, 184, - 280, 280, 342, 84, 30, 182, 342, 280, 30, 182, - 182, 105, 278, 182, 101, 30, 30, 342, 182, 204, - 204, 184, 182, 204, 80, 204, 1, 282, 282, 78, - 1, 184, 77, 182, 282, 184, 184, 1, 250, 184, - 252, 204, 253, 184, 184, 23, 23, 234, 184, 23, - 71, 234, 204, 7, 234, 70, 204, 204, 234, 184, - 204, 264, 7, 7, 269, 204, 204, 23, 68, 204, - 26, 26, 204, 107, 26, 275, 26, 67, 23, 66, - 204, 207, 23, 23, 160, 108, 23, 109, 160, 160, - 23, 23, 26, 298, 298, 23, 196, 196, 298, 298, - 196, 114, 196, 26, 115, 298, 23, 26, 26, 188, - 119, 26, 121, 188, 188, 64, 26, 26, 196, 127, - 26, 29, 29, 26, 52, 29, 51, 29, 50, 196, - 132, 26, 133, 196, 196, 171, 192, 196, 135, 171, - 171, 36, 196, 196, 136, 138, 196, 213, 213, 196, - 33, 213, 139, 213, 29, 140, 183, 196, 29, 29, - 183, 183, 29, 28, 28, 28, 28, 29, 316, 213, - 142, 29, 306, 306, 16, 328, 306, 329, 306, 331, - 213, 332, 29, 333, 213, 213, 338, 175, 213, 35, - 35, 35, 35, 213, 213, 173, 172, 213, 197, 197, - 213, 9, 197, 353, 197, 306, 8, 357, 213, 306, - 306, 144, 368, 306, 157, 370, 299, 299, 306, 3, - 197, 2, 306, 299, 34, 34, 34, 34, 153, 154, - nil, 197, nil, 306, nil, 197, 197, nil, nil, 197, - 4, 4, 4, 4, 197, 197, 39, 39, 197, 299, - 39, 197, 39, 299, 299, nil, nil, 299, nil, 197, - nil, nil, 299, nil, nil, nil, 299, nil, 39, nil, - nil, nil, 206, 206, nil, nil, 206, 299, 206, 39, - nil, nil, nil, 39, 39, nil, nil, 39, nil, nil, - nil, nil, 39, 39, 206, nil, 39, nil, nil, 39, - nil, nil, 46, 46, nil, 206, 46, 39, 46, 206, - 206, nil, nil, 206, nil, nil, nil, nil, 206, 206, - nil, nil, 206, nil, 46, 206, nil, nil, 47, 47, - nil, nil, 47, 206, 47, 46, nil, nil, nil, 46, - 46, nil, nil, 46, nil, nil, 270, 270, 46, 46, - 47, nil, 46, 48, 48, 46, nil, 48, nil, 48, - nil, 47, nil, 46, nil, 47, 47, 49, 49, 47, - nil, 49, nil, nil, 47, 47, nil, nil, 47, 270, - nil, 47, nil, 270, 270, nil, 48, 270, nil, 47, - 48, 48, 270, nil, 48, nil, 270, nil, nil, 48, - 49, nil, nil, 48, 49, 49, nil, 270, 49, nil, - nil, nil, nil, 49, 48, 203, 203, 49, nil, 203, - nil, 203, 294, 294, 294, 294, 294, 294, 49, 294, - 294, nil, 284, 284, 284, 284, 294, 203, nil, 284, - 284, 209, 209, nil, nil, 209, 284, 209, 203, nil, - nil, nil, 203, 203, nil, nil, 203, nil, nil, nil, - nil, 203, 203, 209, nil, 203, nil, nil, 203, nil, - nil, 210, 210, nil, 209, 210, 203, 210, 209, 209, - nil, nil, 209, nil, nil, nil, nil, 209, 209, nil, - nil, 209, nil, 210, 209, nil, nil, nil, nil, nil, - nil, nil, 209, nil, 210, nil, nil, nil, 210, 210, - 102, 102, 210, nil, 102, 102, 102, 210, 210, nil, - nil, 210, nil, nil, 210, nil, nil, nil, nil, 63, - 63, nil, 210, 63, nil, 63, 202, 202, nil, nil, - 202, nil, 202, 102, nil, nil, nil, 102, 102, nil, - nil, 102, nil, nil, nil, nil, 102, nil, 202, nil, - 102, nil, 63, nil, nil, nil, 63, 63, nil, 202, - 63, 102, nil, 202, 202, 63, nil, 202, nil, 63, - nil, nil, 202, 202, nil, nil, 202, 100, 100, 202, - 63, 100, nil, 100, nil, nil, nil, 202, nil, nil, - nil, nil, nil, nil, nil, nil, 277, 277, nil, 100, - 277, nil, 277, 198, 198, nil, nil, 198, nil, 198, - 100, nil, nil, nil, 100, 100, nil, nil, 100, nil, - nil, nil, nil, 100, 100, 198, nil, 100, nil, 277, - 100, nil, nil, 277, 277, nil, 198, 277, 100, nil, - 198, 198, 277, nil, 198, nil, 277, nil, nil, 198, - 198, nil, nil, 198, 256, 256, 198, 277, 256, nil, - 256, nil, nil, nil, 198, nil, nil, nil, nil, nil, - nil, nil, nil, 254, 254, nil, 256, nil, nil, 74, - 74, nil, nil, nil, nil, nil, nil, 256, nil, nil, - nil, 256, 256, nil, nil, 256, 254, nil, nil, nil, - 256, 256, 74, nil, 256, nil, 254, 256, nil, nil, - 254, 254, 74, nil, 254, 256, 74, 74, 254, 254, - 74, nil, nil, 254, 74, 74, 75, 75, nil, 74, - 75, nil, 75, nil, 254, nil, 286, 286, 286, 286, - 74, nil, nil, 286, 286, 248, 248, nil, 75, 248, - 286, 248, 245, 245, nil, nil, nil, nil, nil, 75, - nil, nil, nil, 75, 75, nil, nil, 75, nil, nil, - 244, 244, 75, 75, nil, nil, 75, nil, 248, 75, - nil, nil, 248, 248, nil, 245, 248, 75, nil, 245, - 245, 248, nil, 245, nil, 248, nil, nil, 245, nil, - nil, nil, 245, 244, nil, nil, 248, 244, 244, nil, - nil, 244, nil, 245, nil, nil, 244, 97, 97, nil, - 244, 97, nil, 97, nil, nil, nil, nil, nil, nil, - nil, 244, nil, nil, nil, nil, 82, 82, nil, 97, - 82, nil, 82, 199, 199, nil, nil, 199, nil, 199, - 97, nil, nil, nil, 97, 97, nil, nil, 97, nil, - nil, nil, nil, 97, 97, 214, 214, 97, nil, 82, - 97, nil, nil, 82, 82, nil, 199, 82, 97, nil, - 199, 199, 82, nil, 199, nil, 82, nil, nil, 199, - 230, 230, nil, 199, 230, nil, 230, 82, 214, nil, - nil, nil, 214, 214, 199, nil, 214, nil, 200, 200, - nil, 214, 200, nil, 200, 214, nil, nil, nil, nil, - nil, nil, nil, 230, nil, nil, 214, 230, 230, nil, - 200, 230, nil, 228, 228, nil, 230, 228, nil, 228, - 230, 200, nil, 225, 225, 200, 200, 225, nil, 200, - nil, 230, nil, nil, 200, 200, nil, nil, 200, nil, - nil, 200, nil, nil, nil, nil, 228, nil, nil, 200, - 228, 228, nil, nil, 228, nil, 225, nil, nil, 228, - 225, 225, nil, 228, 225, nil, 201, 201, nil, 225, - 201, nil, 201, 225, 228, nil, nil, nil, nil, nil, - nil, nil, nil, nil, 225, 308, 308, nil, 201, 308, - nil, 308, 94, 94, nil, nil, 94, nil, 94, 201, - nil, nil, nil, 201, 201, nil, nil, 201, nil, nil, - nil, nil, 201, 201, 94, nil, 201, nil, 308, 201, - nil, nil, 308, 308, nil, 94, 308, 201, nil, 94, - 94, 308, nil, 94, nil, 308, nil, nil, 94, 94, - 111, nil, 94, nil, nil, 94, 308, nil, nil, 111, - 111, nil, nil, 94, nil, nil, nil, nil, 111, 111, - 111, 111, nil, nil, 186, 186, nil, nil, nil, nil, - nil, nil, 186, 186, 186, 186, 186, nil, nil, nil, - nil, nil, 111, 111, nil, nil, 111, 111, 111, 111, - 111, 111, nil, 111, 111, nil, nil, 186, 186, nil, - 111, 186, 186, 186, 186, 186, 186, nil, 186, 186, - 288, 288, nil, nil, nil, 186, nil, nil, nil, 288, - 288, 288, 288, nil, nil, 131, 131, nil, nil, nil, - nil, nil, nil, nil, 131, 131, 131, 131, nil, nil, - nil, nil, nil, nil, 288, nil, nil, 288, 288, 288, - 288, 288, 288, nil, 288, 288, nil, nil, 131, 131, - nil, 288, 131, 131, 131, 131, 131, 131, nil, 131, - 131, 130, 130, nil, nil, nil, 131, nil, nil, nil, - 130, 130, 130, 130, nil, nil, 292, 292, nil, nil, - nil, nil, nil, nil, nil, 292, 292, 292, 292, nil, - nil, nil, nil, nil, 130, 130, nil, nil, 130, 130, - 130, 130, 130, 130, nil, 130, 130, nil, nil, nil, - nil, nil, 130, 292, 292, 292, 292, 292, 292, nil, - 292, 292, 124, 124, nil, nil, nil, 292, nil, nil, - nil, 124, 124, 124, 124, nil, nil, nil, 293, nil, - 285, 285, 285, 285, 285, 285, 293, 285, 285, nil, - nil, nil, nil, nil, 285, 124, 124, 289, nil, 124, - 124, 124, 124, 124, 124, 289, 124, 124, nil, nil, - nil, nil, 287, 124, 293, 293, 293, 293, 293, 293, - 287, 293, 293, nil, nil, nil, nil, nil, 293, nil, - nil, 290, nil, 289, 289, 289, 289, 289, 289, 290, - 289, 289, nil, nil, nil, nil, nil, 289, 287, 287, - 287, 287, 287, 287, nil, 287, 287, nil, nil, 381, - nil, nil, 287, nil, nil, nil, nil, 290, 290, 290, - 290, 290, 290, nil, 290, 290, nil, nil, 212, nil, - 381, 290, 381, 381, nil, 381, 381, nil, 381, nil, - 381, nil, 381, nil, 381, nil, nil, 381, 381, 212, - 217, 212, 212, nil, 212, 212, nil, 212, nil, 212, - nil, 212, nil, 212, nil, nil, 212, 212, nil, 379, - nil, 217, nil, 217, 217, nil, 217, 217, nil, 217, - nil, 217, nil, 217, nil, 217, nil, nil, 217, 217, - 379, 237, 379, 379, nil, 379, 379, nil, 379, nil, - 379, nil, 379, nil, 379, nil, nil, 379, 379, nil, - 375, nil, 237, nil, 237, 237, nil, 237, 237, nil, - 237, nil, 237, nil, 237, nil, 237, nil, nil, 237, - 237, 375, 373, 375, 375, nil, 375, 375, nil, 375, - nil, 375, nil, 375, nil, 375, nil, nil, 375, 375, - nil, 363, nil, 373, nil, 373, 373, nil, 373, 373, - nil, 373, nil, 373, nil, 373, nil, 373, nil, nil, - 373, 373, 363, 296, 363, 363, nil, 363, 363, nil, - 363, nil, 363, nil, 363, nil, 363, nil, nil, 363, - 363, nil, 304, nil, 296, nil, 296, 296, nil, 296, - 296, nil, 296, nil, 296, nil, 296, nil, 296, nil, - nil, 296, 296, 304, 324, 304, 304, nil, 304, 304, - nil, 304, nil, 304, nil, 304, nil, 304, nil, nil, - 304, 304, nil, 320, nil, 324, nil, 324, 324, nil, - 324, 324, nil, 324, nil, 324, nil, 324, nil, 324, - nil, nil, 324, 324, 320, nil, 320, 320, nil, 320, - 320, nil, 320, nil, 320, nil, 320, nil, 320, nil, - nil, 320, 320, 19, nil, 19, 19, nil, 19, 19, - nil, 19, nil, 19, nil, 19, nil, 19, nil, nil, - 19, 19, 0, nil, 0, 0, nil, 0, 0, nil, - 0, nil, 0, nil, 0, nil, 0, nil, nil, 0, - 0 ] + 164, 164, 18, 103, 103, 214, 56, 157, 81, 32, + 103, 286, 286, 164, 164, 136, 11, 27, 286, 27, + 11, 158, 164, 164, 164, 164, 81, 11, 300, 300, + 154, 56, 27, 214, 214, 300, 332, 332, 189, 189, + 18, 103, 189, 18, 189, 157, 164, 164, 157, 286, + 164, 164, 164, 164, 164, 164, 27, 164, 164, 158, + 189, 300, 158, 18, 164, 300, 300, 200, 157, 300, + 294, 189, 154, 212, 300, 189, 189, 213, 300, 189, + 369, 369, 158, 134, 189, 189, 186, 186, 189, 300, + 186, 189, 186, 203, 291, 294, 294, 133, 206, 189, + 111, 216, 144, 127, 203, 291, 206, 163, 186, 203, + 291, 111, 262, 369, 273, 144, 111, 369, 369, 186, + 163, 369, 273, 186, 186, 262, 369, 186, 357, 357, + 369, 221, 186, 186, 185, 185, 186, 302, 185, 186, + 185, 369, 264, 264, 221, 302, 218, 186, 219, 264, + 273, 273, 273, 273, 273, 273, 185, 273, 273, 1, + 220, 357, 197, 1, 273, 357, 357, 185, 122, 357, + 1, 185, 185, 122, 357, 185, 281, 224, 357, 281, + 185, 185, 176, 176, 185, 310, 176, 185, 176, 357, + 310, 282, 282, 121, 192, 185, 282, 282, 192, 192, + 114, 175, 175, 282, 176, 175, 46, 175, 336, 336, + 46, 114, 336, 227, 336, 176, 114, 46, 46, 176, + 176, 263, 263, 176, 265, 265, 263, 263, 176, 176, + 336, 265, 176, 263, 175, 176, 119, 335, 175, 175, + 335, 336, 175, 176, 229, 336, 336, 175, 230, 336, + 116, 175, 215, 215, 336, 336, 232, 8, 336, 330, + 330, 336, 175, 330, 115, 330, 8, 8, 194, 336, + 234, 194, 267, 267, 267, 267, 235, 184, 184, 267, + 267, 184, 113, 184, 225, 215, 267, 239, 225, 215, + 215, 225, 330, 215, 110, 225, 330, 330, 215, 184, + 330, 108, 215, 23, 23, 330, 250, 23, 253, 330, + 184, 107, 169, 215, 184, 184, 169, 169, 184, 106, + 330, 105, 102, 184, 184, 23, 140, 184, 26, 26, + 184, 42, 26, 141, 26, 42, 23, 101, 184, 96, + 23, 23, 42, 42, 23, 94, 89, 211, 23, 23, + 26, 211, 211, 23, 228, 228, 33, 87, 228, 85, + 33, 26, 83, 82, 23, 26, 26, 33, 33, 26, + 31, 31, 31, 31, 26, 26, 29, 29, 26, 201, + 29, 26, 29, 201, 201, 80, 77, 228, 75, 26, + 280, 228, 228, 142, 74, 228, 284, 308, 308, 69, + 228, 308, 66, 308, 228, 6, 6, 6, 6, 29, + 289, 65, 64, 29, 29, 228, 53, 29, 52, 307, + 307, 298, 29, 307, 50, 307, 29, 37, 305, 138, + 308, 187, 143, 17, 308, 308, 321, 29, 308, 325, + 174, 174, 13, 308, 174, 146, 174, 308, 3, 3, + 3, 3, 307, 147, 12, 338, 307, 307, 308, 343, + 307, 347, 174, 348, 350, 307, 179, 179, 351, 307, + 179, 352, 179, 174, 183, 358, 5, 174, 174, 368, + 307, 174, 4, 4, 4, 4, 174, 174, 179, 155, + 174, 370, 159, 174, 2, 380, 173, 173, 382, 179, + 173, 174, 173, 179, 179, nil, nil, 179, nil, nil, + nil, nil, 179, 179, nil, nil, 179, nil, 173, 179, + nil, nil, 45, 45, nil, nil, 45, 179, 45, 173, + nil, nil, nil, 173, 173, nil, nil, 173, nil, nil, + nil, nil, 173, 173, 45, nil, 173, nil, nil, 173, + nil, nil, 172, 172, nil, 45, 172, 173, 172, 45, + 45, nil, nil, 45, nil, nil, nil, nil, 45, 45, + nil, nil, 45, nil, 172, 45, nil, nil, 47, 47, + nil, nil, 47, 45, 47, 172, nil, nil, nil, 172, + 172, nil, nil, 172, nil, nil, nil, nil, 172, 172, + 47, nil, 172, nil, nil, 172, nil, nil, 48, 48, + nil, 47, 48, 172, 48, 47, 47, nil, nil, 47, + nil, nil, nil, nil, 47, 47, nil, nil, 47, nil, + 48, 47, nil, nil, 49, 49, nil, nil, 49, 47, + 49, 48, nil, nil, nil, 48, 48, nil, nil, 48, + 296, 296, nil, nil, 48, 48, 177, 177, 48, nil, + 177, 48, 177, nil, nil, nil, nil, 49, nil, 48, + nil, 49, 49, nil, nil, 49, nil, nil, 177, nil, + 49, 51, 51, 296, 49, 51, nil, 296, 296, 177, + nil, 296, nil, 177, 177, 49, 296, 177, nil, nil, + 296, nil, 177, 177, nil, nil, 177, 295, 295, 177, + nil, 296, nil, nil, 51, nil, nil, 177, 51, 51, + nil, nil, 51, nil, nil, nil, nil, 51, 231, 231, + nil, 51, 231, nil, 231, nil, nil, nil, nil, nil, + 295, nil, 51, nil, 295, 295, 233, 233, 295, nil, + 233, nil, 233, 295, nil, nil, nil, 295, nil, nil, + nil, 231, nil, nil, nil, 231, 231, nil, 295, 231, + nil, 170, 170, nil, 231, nil, nil, nil, 231, 233, + nil, nil, nil, 233, 233, nil, nil, 233, nil, 231, + nil, nil, 233, nil, 170, nil, 233, 288, 288, nil, + nil, 288, nil, 288, 170, nil, nil, 233, 170, 170, + nil, nil, 170, nil, nil, nil, 170, 170, 182, 182, + nil, 170, 182, nil, 182, nil, nil, nil, nil, nil, + 288, nil, 170, nil, 288, 288, nil, nil, 288, nil, + 182, nil, nil, 288, 70, 70, nil, 288, nil, nil, + nil, 182, nil, nil, nil, 182, 182, nil, 288, 182, + nil, nil, nil, nil, 182, 182, nil, 70, 182, 71, + 71, 182, nil, 71, nil, 71, nil, 70, nil, 182, + nil, 70, 70, nil, nil, 70, nil, nil, nil, 70, + 70, 71, nil, nil, 70, 180, 180, nil, nil, 180, + nil, 180, 71, nil, nil, 70, 71, 71, nil, nil, + 71, nil, nil, nil, nil, 71, 71, 180, nil, 71, + 112, 112, 71, nil, 112, nil, 112, nil, 180, nil, + 71, nil, 180, 180, 167, 167, 180, nil, nil, nil, + 167, 180, 180, nil, nil, 180, nil, nil, 180, nil, + nil, nil, nil, 112, nil, nil, 180, 112, 112, 78, + 78, 112, nil, 78, nil, 78, 112, 167, nil, nil, + 112, 167, 167, nil, nil, 167, nil, nil, 240, 240, + 167, 112, nil, nil, 167, nil, nil, nil, nil, nil, + nil, nil, 78, nil, nil, 167, 78, 78, nil, nil, + 78, 240, nil, 255, 255, 78, nil, nil, nil, 78, + nil, 240, nil, nil, nil, 240, 240, nil, nil, 240, + 78, 100, 100, 240, 240, 100, 100, 100, 240, nil, + nil, nil, nil, nil, nil, nil, 255, nil, nil, 240, + 255, 255, 260, 260, 255, nil, 260, nil, 260, 255, + nil, nil, nil, 255, 100, nil, nil, nil, 100, 100, + nil, nil, 100, nil, 255, nil, nil, 100, 181, 181, + nil, 100, 181, nil, 181, 260, nil, nil, nil, 260, + 260, nil, 100, 260, nil, nil, nil, nil, 260, nil, + 181, nil, 260, nil, 90, 90, nil, nil, 90, nil, + 90, 181, nil, 260, nil, 181, 181, nil, nil, 181, + nil, nil, nil, nil, 181, 181, 90, nil, 181, 161, + 161, 181, nil, 161, nil, 161, nil, 90, nil, 181, + nil, 90, 90, 166, 166, 90, nil, nil, nil, nil, + 90, 90, nil, nil, 90, nil, nil, 90, nil, nil, + nil, nil, 161, nil, nil, 90, 161, 161, nil, nil, + 161, nil, nil, nil, nil, 161, 166, nil, nil, 161, + 166, 166, nil, nil, 166, nil, nil, nil, 166, 166, + 161, 95, 95, 166, nil, 95, nil, 95, 277, 277, + 277, 277, 277, 277, 166, 277, 277, nil, 269, 269, + 269, 269, 277, 95, nil, 269, 269, 178, 178, nil, + nil, 178, 269, 178, 95, nil, nil, nil, 95, 95, + nil, nil, 95, nil, nil, nil, nil, 95, 95, 178, + nil, 95, nil, nil, 95, nil, nil, 99, 99, nil, + 178, 99, 95, 99, 178, 178, nil, nil, 178, nil, + nil, nil, nil, 178, 178, nil, nil, 178, nil, 99, + 178, nil, nil, 242, 242, nil, nil, 242, 178, 242, + 99, nil, nil, nil, 99, 99, nil, nil, 99, nil, + nil, nil, nil, 99, 99, 242, nil, 99, nil, nil, + 99, nil, nil, nil, nil, nil, 242, nil, 99, nil, + 242, 242, 91, nil, 242, nil, nil, nil, nil, 242, + 242, 91, 91, 242, nil, nil, 242, nil, nil, nil, + 91, 91, 91, 91, 242, nil, 129, 129, nil, nil, + nil, nil, nil, nil, nil, 129, 129, 129, 129, nil, + nil, nil, nil, nil, 91, 91, nil, nil, 91, 91, + 91, 91, 91, 91, nil, 91, 91, nil, nil, 129, + 129, nil, 91, 129, 129, 129, 129, 129, 129, nil, + 129, 129, 190, 190, nil, nil, nil, 129, nil, nil, + 190, 190, 190, 190, 190, nil, nil, 271, 271, nil, + nil, nil, nil, nil, nil, nil, 271, 271, 271, 271, + nil, nil, nil, nil, nil, 190, 190, nil, nil, 190, + 190, 190, 190, 190, 190, nil, 190, 190, nil, nil, + nil, 271, nil, 190, 271, 271, 271, 271, 271, 271, + nil, 271, 271, 131, 131, nil, nil, nil, 271, nil, + nil, nil, 131, 131, 131, 131, nil, nil, 132, 132, + nil, nil, nil, nil, nil, nil, nil, 132, 132, 132, + 132, nil, nil, nil, nil, nil, 131, 131, nil, nil, + 131, 131, 131, 131, 131, 131, nil, 131, 131, nil, + nil, 132, 132, nil, 131, 132, 132, 132, 132, 132, + 132, nil, 132, 132, 275, 275, nil, nil, nil, 132, + nil, nil, nil, 275, 275, 275, 275, nil, nil, 279, + 276, 279, 279, nil, 279, 279, nil, 279, 276, 279, + nil, 279, nil, 279, nil, nil, 279, 279, nil, 270, + nil, 275, 275, 275, 275, 275, 275, 270, 275, 275, + nil, nil, nil, nil, 272, 275, 276, 276, 276, 276, + 276, 276, 272, 276, 276, nil, nil, nil, nil, nil, + 276, nil, nil, nil, nil, 270, 270, 270, 270, 270, + 270, nil, 270, 270, 188, nil, nil, nil, nil, 270, + 272, 272, 272, 272, 272, 272, nil, 272, 272, nil, + nil, nil, nil, 363, 272, 188, nil, 188, 188, nil, + 188, 188, nil, 188, nil, 188, nil, 188, nil, 188, + nil, nil, 188, 188, 363, 312, 363, 363, nil, 363, + 363, nil, 363, nil, 363, nil, 363, nil, 363, nil, + nil, 363, 363, nil, 376, nil, 312, nil, 312, 312, + nil, 312, 312, nil, 312, nil, 312, nil, 312, nil, + 312, nil, nil, 312, 312, 376, 217, 376, 376, nil, + 376, 376, nil, 376, nil, 376, nil, 376, nil, 376, + nil, nil, 376, 376, nil, 373, nil, 217, nil, 217, + 217, nil, 217, 217, nil, 217, nil, 217, nil, 217, + nil, 217, nil, nil, 217, 217, 373, 238, 373, 373, + nil, 373, 373, nil, 373, nil, 373, nil, 373, nil, + 373, nil, nil, 373, 373, nil, nil, nil, 238, nil, + 238, 238, nil, 238, 238, nil, 238, nil, 238, nil, + 238, nil, 238, nil, nil, 238, 238, 20, nil, 20, + 20, nil, 20, 20, nil, 20, nil, 20, nil, 20, + nil, 20, nil, nil, 20, 20, 0, nil, 0, 0, + nil, 0, 0, nil, 0, nil, 0, nil, 0, nil, + 0, nil, nil, 0, 0, 268, 268, 268, 268, 268, + 268, nil, 268, 268, nil, nil, nil, nil, nil, 268 ] racc_action_pointer = [ - 1832, 210, 426, 395, 396, nil, nil, 267, 418, 413, - nil, nil, -20, nil, nil, nil, 394, 5, nil, 1813, - nil, nil, -3, 263, nil, nil, 288, nil, 319, 339, - 188, nil, nil, 368, 380, 345, 337, nil, nil, 464, - nil, nil, nil, 138, nil, nil, 520, 546, 571, 585, - 308, 322, 344, nil, nil, -6, nil, nil, nil, nil, - nil, nil, 42, 747, 295, 66, 291, 274, 265, nil, - 269, 264, nil, nil, 907, 954, nil, 240, 243, nil, - 221, -13, 1064, nil, 200, 165, 2, 129, nil, nil, - 104, 18, nil, nil, 1240, -2, 6, 1045, nil, nil, - 805, 211, 728, 187, nil, 208, 34, 270, 282, 284, - nil, 1282, nil, nil, 313, 316, nil, nil, nil, 318, - 121, 324, 149, nil, 1465, nil, nil, 333, nil, nil, - 1404, 1358, 343, 329, nil, 352, 323, nil, 342, 360, - 352, nil, 367, 101, 411, nil, nil, nil, nil, nil, - nil, nil, -9, 436, 412, nil, 30, 426, 74, nil, - 258, nil, nil, 123, nil, -7, nil, nil, nil, nil, - nil, 348, 404, 404, 11, 367, 57, nil, 3, nil, - -4, 101, 190, 369, 216, nil, 1297, nil, 322, nil, - nil, nil, 345, nil, nil, 190, 314, 416, 831, 1071, - 1136, 1214, 754, 633, 237, 83, 490, 238, 32, 659, - 689, 35, 1589, 365, 1093, 37, nil, 1611, 34, 44, - 73, 130, nil, nil, 93, 1171, 103, 136, 1161, 119, - 1118, 133, 172, 200, 231, nil, nil, 1652, nil, 59, - nil, nil, nil, -21, 998, 980, nil, nil, 973, nil, - 249, nil, 248, 255, 901, nil, 882, nil, nil, nil, - nil, nil, nil, nil, 270, nil, nil, nil, nil, 260, - 564, nil, nil, 96, nil, 288, nil, 824, 192, nil, - 159, 144, 186, nil, 598, 1446, 912, 1514, 1343, 1499, - 1533, nil, 1419, 1480, 588, nil, 1734, 173, 257, 434, - nil, -3, nil, nil, 1753, nil, 390, nil, 1233, 125, - nil, nil, nil, nil, nil, nil, 376, nil, nil, nil, - 1794, nil, nil, nil, 1775, nil, nil, nil, 372, 374, - nil, 376, 378, 380, nil, nil, nil, nil, 397, nil, - nil, nil, 174, nil, 122, nil, nil, nil, nil, nil, - 79, nil, 148, 415, nil, nil, 127, 419, nil, nil, - nil, nil, nil, 1712, nil, nil, nil, nil, 423, 76, - 426, nil, nil, 1693, nil, 1671, nil, nil, nil, 1630, - nil, 1570, nil, nil, nil ] + 1726, 123, 450, 384, 418, 461, 341, nil, 251, nil, + nil, -20, 446, 434, nil, nil, nil, 433, 0, nil, + 1707, nil, nil, 301, nil, nil, 326, 11, nil, 374, + nil, 306, 7, 320, nil, nil, nil, 403, nil, nil, + nil, nil, 295, nil, nil, 520, 170, 576, 606, 632, + 400, 679, 378, 416, nil, nil, -6, nil, nil, nil, + nil, nil, nil, nil, 389, 388, 396, nil, nil, 393, + 842, 867, nil, nil, 388, 376, nil, 363, 957, nil, + 362, 2, 340, 356, nil, 336, nil, 334, nil, 323, + 1092, 1294, nil, nil, 322, 1179, 333, nil, nil, 1235, + 1019, 314, 299, 1, nil, 298, 296, 288, 278, nil, + 286, 76, 918, 242, 176, 256, 238, nil, nil, 228, + nil, 185, 133, nil, nil, nil, nil, 97, nil, 1309, + nil, 1416, 1431, 90, 46, nil, -8, nil, 423, nil, + 285, 310, 381, 409, 91, nil, 422, 433, nil, nil, + nil, nil, nil, nil, 19, 477, nil, 5, 19, 484, + nil, 1117, nil, 95, -4, nil, 1131, 932, nil, 305, + 769, nil, 550, 494, 438, 199, 180, 654, 1205, 464, + 893, 1066, 816, 411, 275, 132, 84, 368, 1565, 36, + 1355, nil, 187, nil, 259, nil, nil, 151, nil, nil, + 27, 333, nil, 69, nil, nil, 80, nil, nil, nil, + nil, 340, 61, 66, -17, 250, 99, 1647, 131, 133, + 135, 119, nil, nil, 169, 248, nil, 204, 352, 204, + 239, 726, 216, 744, 230, 267, nil, nil, 1688, 280, + 976, nil, 1261, nil, nil, nil, nil, nil, nil, nil, + 295, nil, nil, 284, nil, 1001, nil, nil, nil, nil, + 1040, nil, 100, 165, 81, 163, nil, 218, 1721, 1144, + 1511, 1370, 1526, 96, nil, 1477, 1492, 1134, nil, 1479, + 381, 145, 135, nil, 389, nil, 9, nil, 795, 398, + nil, 70, nil, nil, 45, 705, 648, nil, 412, nil, + 26, nil, 125, nil, nil, 419, nil, 417, 395, nil, + 150, nil, 1606, nil, nil, nil, nil, nil, nil, nil, + nil, 424, nil, nil, nil, 430, nil, nil, nil, nil, + 257, nil, 25, nil, nil, 206, 206, nil, 447, nil, + nil, nil, nil, 450, nil, nil, nil, 438, 440, nil, + 441, 445, 448, nil, nil, nil, nil, 126, 467, nil, + nil, nil, nil, 1584, nil, nil, nil, nil, 470, 78, + 482, nil, nil, 1666, nil, nil, 1625, nil, nil, nil, + 486, nil, 489, nil, nil, nil ] racc_action_default = [ - -197, -234, -234, -50, -234, -8, -9, -234, -234, -22, - -10, -188, -189, -11, -186, -12, -234, -234, -13, -1, - -14, -2, -234, -187, -15, -3, -234, -16, -5, -234, - -234, -17, -6, -234, -18, -7, -197, -189, -187, -234, - -51, -26, -27, -234, -24, -25, -234, -234, -234, -85, - -92, -197, -234, -196, -194, -197, -190, -192, -193, -222, - -195, -4, -197, -234, -85, -197, -53, -232, -42, -175, - -43, -214, -117, -33, -234, -234, -44, -31, -74, -32, - -234, -36, -234, -122, -37, -234, -73, -38, -172, -72, - -39, -40, -174, -41, -234, -103, -111, -234, -132, -112, - -234, -104, -234, -108, -110, -105, -234, -114, -106, -113, - -109, -234, -125, -107, -234, -234, -49, -176, -177, -179, - -234, -234, -198, -199, -83, -19, -22, -187, -21, -23, - -82, -84, -234, -75, -86, -81, -70, -74, -76, -220, - -79, -68, -77, -73, -234, -171, -170, -80, -78, -90, - -91, -93, -234, -220, -197, 385, -234, -234, -234, -208, - -234, -57, -214, -197, -59, -234, -66, -65, -56, -73, - -95, -234, -220, -234, -234, -92, -234, -30, -234, -118, - -234, -234, -234, -234, -234, -142, -234, -149, -234, -217, - -230, -226, -234, -229, -225, -234, -234, -234, -234, -234, - -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, - -234, -234, -234, -234, -234, -234, -20, -234, -207, -234, - -205, -234, -202, -231, -234, -71, -221, -234, -234, -85, - -234, -221, -234, -234, -234, -210, -191, -234, -209, -234, - -54, -62, -61, -234, -234, -234, -218, -219, -234, -124, - -234, -55, -220, -234, -234, -28, -234, -120, -119, -35, - -34, -173, -168, -166, -234, -169, -160, -167, -161, -73, - -234, -123, -116, -234, -152, -219, -215, -234, -234, -223, - -137, -139, -138, -133, -140, -144, -141, -146, -151, -148, - -145, -134, -150, -147, -143, -135, -234, -128, -136, -234, - -154, -234, -158, -178, -234, -181, -234, -200, -234, -234, - -201, -45, -69, -87, -46, -88, -220, -89, -94, -48, - -234, -212, -211, -213, -234, -185, -58, -60, -97, -98, - -63, -102, -99, -100, -101, -64, -96, -47, -234, -233, - -29, -121, -234, -163, -220, -115, -216, -228, -227, -224, - -128, -127, -234, -234, -155, -153, -234, -234, -180, -206, - -204, -203, -67, -234, -183, -184, -52, -165, -219, -234, - -234, -126, -129, -234, -159, -234, -182, -164, -162, -234, - -131, -234, -157, -130, -156 ] + -198, -235, -51, -19, -8, -235, -235, -9, -235, -10, + -189, -190, -235, -23, -11, -187, -12, -235, -235, -13, + -1, -14, -2, -188, -15, -3, -235, -235, -16, -235, + -17, -6, -235, -235, -18, -7, -190, -198, -188, -52, + -27, -28, -235, -25, -26, -235, -235, -235, -235, -235, + -198, -86, -93, -235, -197, -195, -198, -191, -193, -194, + -223, -196, -4, -42, -233, -43, -215, -176, -118, -44, + -235, -235, -45, -34, -75, -32, -33, -235, -235, -123, + -37, -74, -38, -235, -73, -39, -173, -40, -175, -41, + -235, -235, -126, -108, -104, -235, -112, -133, -113, -235, + -235, -105, -109, -235, -111, -106, -115, -107, -114, -110, + -54, -198, -235, -86, -198, -235, -180, -177, -178, -235, + -50, -235, -199, -200, -24, -21, -23, -188, -22, -84, + -20, -83, -85, -235, -198, -79, -76, -87, -82, -75, + -71, -77, -221, -80, -74, -69, -78, -235, -172, -171, + -81, -91, -92, -94, -235, -221, 386, -235, -235, -235, + -209, -235, -31, -235, -235, -119, -235, -235, -96, -235, + -235, -143, -235, -235, -235, -235, -235, -235, -235, -235, + -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, + -235, -150, -235, -218, -235, -231, -227, -235, -230, -226, + -93, -235, -215, -198, -58, -60, -235, -67, -57, -74, + -66, -235, -221, -235, -235, -235, -235, -235, -208, -206, + -235, -235, -203, -232, -235, -235, -211, -235, -72, -222, + -235, -235, -86, -235, -222, -235, -192, -210, -235, -235, + -235, -29, -235, -121, -120, -36, -35, -174, -169, -167, + -235, -170, -161, -74, -168, -235, -162, -219, -220, -124, + -235, -117, -235, -138, -140, -139, -134, -141, -145, -142, + -147, -152, -149, -146, -135, -151, -148, -144, -136, -5, + -235, -129, -137, -153, -220, -216, -235, -224, -235, -221, + -55, -235, -63, -62, -235, -235, -235, -125, -235, -56, + -235, -155, -235, -159, -179, -235, -182, -235, -235, -201, + -235, -202, -235, -213, -214, -212, -46, -70, -88, -47, + -89, -221, -90, -95, -49, -235, -186, -234, -30, -122, + -235, -164, -221, -97, -116, -129, -235, -128, -235, -217, + -228, -225, -229, -235, -59, -61, -102, -98, -99, -64, + -103, -100, -101, -65, -48, -156, -154, -235, -235, -181, + -207, -205, -204, -235, -184, -68, -185, -166, -220, -235, + -235, -127, -130, -235, -53, -160, -235, -183, -165, -163, + -235, -132, -235, -158, -131, -157 ] racc_goto_table = [ - 22, 9, 68, 112, 222, 264, 61, 36, 53, 179, - 268, 141, 70, 19, 2, 77, 191, 118, 51, 22, - 9, 139, 116, 21, 73, 91, 56, 147, 133, 149, - 115, 227, 153, 2, 300, 128, 172, 302, 135, 160, - 125, 129, 174, 22, 126, 232, 351, 43, 171, 299, - 260, 146, 369, 68, 121, 330, 335, 258, 266, 123, - 318, 344, 136, 70, 250, 119, 178, 183, 224, 154, - 233, 55, 157, 66, 123, 73, 91, 120, 159, 238, - 219, 221, 326, 322, 195, 190, 16, 188, nil, nil, - nil, nil, nil, 264, nil, nil, nil, nil, 343, 371, + 27, 13, 20, 222, 89, 92, 115, 37, 62, 5, + 65, 196, 256, 145, 230, 150, 118, 50, 155, 301, + 27, 13, 246, 75, 73, 57, 133, 235, 201, 5, + 250, 214, 149, 119, 337, 165, 121, 344, 136, 69, + 169, 120, 27, 126, 142, 22, 27, 126, 300, 134, + 128, 89, 63, 151, 128, 168, 125, 65, 280, 124, + 130, 42, 192, 124, 46, 349, 353, 138, 244, 87, + 163, 73, 252, 369, 211, 332, 323, 168, 303, 116, + 135, 140, 123, 224, 298, 56, 69, 305, 371, 168, + 195, 159, 227, 237, 220, 123, 246, 148, 221, 63, + 331, 160, 110, 315, 355, 194, 212, 17, 325, nil, + nil, 86, nil, nil, nil, nil, 87, nil, 250, nil, + 294, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 239, 86, + nil, nil, nil, nil, nil, nil, nil, 89, 149, nil, + nil, 89, 266, 65, 248, nil, nil, 65, 86, nil, + nil, 343, nil, 303, 236, nil, 289, 245, nil, nil, + 262, 73, nil, nil, nil, 82, 247, nil, nil, 226, + nil, nil, 69, nil, nil, nil, 69, nil, 27, 13, + 317, 362, 150, 365, 340, 63, 149, 5, nil, 63, + 304, 151, 248, 143, 370, 85, 329, nil, 320, 149, + 322, nil, 87, 148, 378, 136, 87, 27, 13, nil, + 375, 89, 82, nil, 247, 321, 5, 65, nil, 54, + 318, 313, 250, 146, nil, 151, 149, 333, 27, 13, + nil, 245, 248, 380, 138, nil, 382, 5, nil, nil, + nil, nil, 85, nil, 86, 86, 69, 135, 86, nil, + nil, 148, nil, 210, 247, 342, 210, 62, nil, 63, + 80, nil, nil, 195, 148, nil, 149, 149, nil, 27, + 13, 149, 347, 347, 360, 361, 87, 248, 5, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 141, nil, + nil, 148, nil, 86, 247, 247, nil, 367, nil, 247, + nil, nil, 27, 13, 363, 372, 86, 80, 82, 251, + nil, 5, 82, nil, 346, 346, nil, nil, 86, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 149, nil, + nil, 352, 352, 86, 248, nil, 148, nil, 85, 254, + 149, 62, 85, nil, nil, 210, 248, nil, 207, nil, + nil, 207, nil, 27, 13, nil, 247, 251, 54, 54, + nil, nil, 5, 27, 13, nil, 27, 13, 247, nil, + 143, nil, 5, 86, 86, 5, nil, nil, 86, nil, + nil, nil, 82, nil, 274, nil, nil, 254, 278, nil, + nil, nil, nil, 148, nil, nil, nil, 251, nil, nil, + 146, nil, nil, 80, 249, 148, nil, 80, nil, nil, + nil, nil, 85, nil, nil, nil, nil, nil, nil, 129, + nil, 131, 132, nil, nil, nil, nil, 254, nil, nil, + nil, nil, nil, 210, nil, 86, nil, 350, 350, nil, + 207, nil, 251, nil, nil, 164, nil, 86, nil, nil, + nil, nil, 249, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 171, 141, nil, 351, 351, 190, + nil, nil, 254, 191, nil, nil, nil, 80, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, - nil, nil, 128, nil, nil, 88, nil, 216, 129, 354, - 22, 126, 302, 260, nil, nil, nil, nil, nil, nil, + nil, nil, 249, nil, nil, nil, nil, nil, nil, 251, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, - 243, 88, nil, nil, 338, nil, nil, 53, nil, 53, - nil, nil, nil, nil, 149, nil, nil, 252, nil, nil, - 68, 262, nil, 68, nil, 236, 88, nil, nil, nil, - 70, nil, nil, 70, nil, nil, 273, 235, nil, 374, - nil, nil, 259, 91, 146, 73, 91, 312, 348, nil, - 341, 361, 264, 262, 87, nil, 261, 377, 291, 303, - nil, 316, 295, 147, 133, 313, nil, nil, 362, nil, - 149, nil, 22, 9, 135, nil, 146, 22, 9, nil, - 142, nil, nil, 328, 328, 296, 2, 146, 261, nil, - 304, 2, nil, 68, nil, nil, 370, 22, 9, nil, - 321, nil, nil, 70, nil, 87, 146, 146, nil, 262, - 324, 2, nil, nil, nil, 259, 91, 190, 261, 261, - nil, 81, nil, nil, nil, nil, nil, nil, nil, nil, - nil, nil, 146, 88, 88, nil, 88, nil, 262, nil, - nil, nil, nil, 61, 261, nil, nil, 138, 84, nil, - nil, 61, nil, nil, nil, nil, 22, 9, nil, nil, - 166, 146, nil, 166, 22, 9, 88, nil, nil, nil, - 2, 61, 81, 261, 140, nil, nil, 88, 2, nil, - 22, 9, nil, nil, 22, 9, nil, 167, nil, 372, - 167, nil, nil, 363, 2, 262, 88, 88, 2, 84, - nil, 90, nil, nil, nil, nil, 88, nil, 262, nil, - 61, nil, 87, 267, nil, 87, nil, nil, 146, nil, - nil, nil, 88, 22, 9, nil, 61, 145, 61, nil, - 261, 146, nil, 22, 9, 22, 9, 2, 114, 22, - 9, 22, 9, 261, 93, 267, 379, 2, 381, 2, - nil, 88, 90, 2, nil, 2, 142, 132, nil, nil, - nil, 166, nil, nil, nil, nil, nil, nil, nil, nil, - 148, nil, 170, nil, nil, 332, 332, nil, nil, 81, - 263, nil, 81, nil, nil, 87, nil, nil, 167, nil, - nil, 170, nil, nil, nil, 93, nil, nil, nil, nil, - nil, 267, nil, nil, nil, nil, 84, 265, 88, 84, - nil, 170, 263, nil, nil, nil, nil, nil, nil, nil, - nil, 88, nil, 138, nil, nil, nil, nil, nil, nil, - 267, nil, nil, nil, nil, nil, nil, 166, 124, 265, - nil, nil, 329, 329, nil, 130, 131, nil, nil, nil, - 140, nil, 81, nil, nil, nil, nil, nil, nil, 90, - 145, nil, 90, nil, 167, nil, nil, nil, 263, 331, - 331, nil, nil, nil, 180, nil, nil, nil, nil, 84, - nil, nil, nil, nil, nil, 253, nil, 267, nil, nil, - nil, nil, 145, 185, nil, 265, 186, 263, nil, 187, - 267, nil, 93, 145, nil, 93, nil, nil, 283, nil, + nil, 251, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 207, 254, + nil, nil, 348, 348, nil, nil, nil, 249, nil, nil, + nil, 254, nil, nil, nil, nil, 263, 264, 265, nil, + 267, 268, 269, 270, 271, 272, 273, nil, 275, 276, + 277, nil, nil, 282, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, - nil, nil, 333, 333, 265, nil, nil, nil, nil, nil, - nil, nil, 90, nil, nil, nil, nil, 315, nil, 317, - nil, nil, nil, nil, nil, nil, 148, nil, 145, nil, - nil, nil, nil, nil, 263, nil, nil, 336, nil, nil, - nil, nil, nil, nil, nil, 334, 334, 263, nil, nil, - nil, nil, nil, nil, nil, 93, nil, 145, nil, nil, - nil, 265, nil, nil, nil, nil, 347, nil, nil, nil, - nil, nil, nil, nil, 265, 280, 281, 282, nil, 284, - 285, 286, 287, 288, 289, 290, nil, 292, 293, 294, - nil, nil, 298, nil, nil, 359, nil, 360, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, - nil, nil, nil, nil, 145, nil, nil, nil, nil, nil, - nil, nil, nil, nil, nil, nil, nil, 145, nil, nil, - nil, 367, nil, nil, nil, 180 ] + nil, nil, nil, nil, 249, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 249, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 164 ] racc_goto_check = [ - 37, 21, 30, 62, 82, 68, 4, 32, 64, 60, - 70, 47, 31, 2, 52, 22, 85, 72, 32, 37, - 21, 35, 5, 3, 21, 28, 78, 50, 30, 53, - 37, 36, 38, 52, 66, 5, 35, 68, 31, 41, - 19, 7, 41, 37, 21, 36, 63, 20, 57, 65, - 23, 28, 58, 30, 74, 46, 46, 61, 69, 3, - 56, 71, 33, 31, 36, 73, 22, 57, 34, 74, - 75, 76, 77, 40, 3, 21, 28, 20, 3, 79, - 80, 81, 42, 83, 84, 30, 1, 57, nil, nil, - nil, nil, nil, 68, nil, nil, nil, nil, 70, 63, + 38, 22, 2, 83, 29, 63, 55, 33, 4, 53, + 31, 86, 71, 48, 37, 51, 73, 33, 39, 67, + 38, 22, 24, 23, 22, 79, 55, 37, 42, 53, + 69, 42, 29, 38, 64, 61, 75, 43, 31, 32, + 58, 6, 38, 22, 36, 3, 38, 22, 66, 75, + 6, 29, 30, 54, 6, 55, 20, 31, 5, 8, + 20, 21, 58, 8, 21, 47, 47, 32, 62, 28, + 23, 22, 70, 59, 58, 72, 57, 55, 69, 74, + 30, 34, 3, 76, 37, 77, 32, 5, 64, 55, + 31, 78, 35, 80, 81, 3, 24, 28, 82, 30, + 71, 3, 41, 84, 67, 85, 36, 1, 5, nil, + nil, 50, nil, nil, nil, nil, 28, nil, 69, nil, + 42, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 55, 50, + nil, nil, nil, nil, nil, nil, nil, 29, 29, nil, + nil, 29, 55, 31, 31, nil, nil, 31, 50, nil, + nil, 37, nil, 69, 79, nil, 39, 22, nil, nil, + 23, 22, nil, nil, nil, 26, 53, nil, nil, 3, + nil, nil, 32, nil, nil, nil, 32, nil, 38, 22, + 48, 83, 51, 37, 86, 30, 29, 53, nil, 30, + 73, 54, 31, 26, 37, 27, 61, nil, 55, 29, + 55, nil, 28, 28, 71, 31, 28, 38, 22, nil, + 69, 29, 26, nil, 53, 36, 53, 31, nil, 65, + 54, 33, 69, 27, nil, 54, 29, 55, 38, 22, + nil, 22, 31, 5, 32, nil, 5, 53, nil, nil, + nil, nil, 27, nil, 50, 50, 32, 30, 50, nil, + nil, 28, nil, 26, 53, 55, 26, 4, nil, 30, + 25, nil, nil, 31, 28, nil, 29, 29, nil, 38, + 22, 29, 31, 31, 55, 55, 28, 31, 53, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 25, nil, + nil, 28, nil, 50, 53, 53, nil, 55, nil, 53, + nil, nil, 38, 22, 2, 63, 50, 25, 26, 26, + nil, 53, 26, nil, 30, 30, nil, nil, 50, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 29, nil, + nil, 28, 28, 50, 31, nil, 28, nil, 27, 27, + 29, 4, 27, nil, nil, 26, 31, nil, 25, nil, + nil, 25, nil, 38, 22, nil, 53, 26, 65, 65, + nil, nil, 53, 38, 22, nil, 38, 22, 53, nil, + 26, nil, 53, 50, 50, 53, nil, nil, 50, nil, + nil, nil, 26, nil, 65, nil, nil, 27, 65, nil, + nil, nil, nil, 28, nil, nil, nil, 26, nil, nil, + 27, nil, nil, 25, 25, 28, nil, 25, nil, nil, + nil, nil, 27, nil, nil, nil, nil, nil, nil, 52, + nil, 52, 52, nil, nil, nil, nil, 27, nil, nil, + nil, nil, nil, 26, nil, 50, nil, 26, 26, nil, + 25, nil, 26, nil, nil, 52, nil, 50, nil, nil, + nil, nil, 25, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 52, 25, nil, 27, 27, 52, + nil, nil, 27, 52, nil, nil, nil, 25, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, - nil, nil, 5, nil, nil, 49, nil, 19, 7, 66, - 37, 21, 68, 23, nil, nil, nil, nil, nil, nil, + nil, nil, 25, nil, nil, nil, nil, nil, nil, 26, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, - 41, 49, nil, nil, 36, nil, nil, 64, nil, 64, - nil, nil, nil, nil, 53, nil, nil, 38, nil, nil, - 30, 30, nil, 30, nil, 78, 49, nil, nil, nil, - 31, nil, nil, 31, nil, nil, 22, 3, nil, 68, - nil, nil, 21, 28, 28, 21, 28, 47, 85, nil, - 60, 82, 68, 30, 26, nil, 52, 70, 64, 72, - nil, 35, 64, 50, 30, 53, nil, nil, 36, nil, - 53, nil, 37, 21, 31, nil, 28, 37, 21, nil, - 26, nil, nil, 30, 30, 2, 52, 28, 52, nil, - 2, 52, nil, 30, nil, nil, 36, 37, 21, nil, - 32, nil, nil, 31, nil, 26, 28, 28, nil, 30, - 2, 52, nil, nil, nil, 21, 28, 30, 52, 52, - nil, 24, nil, nil, nil, nil, nil, nil, nil, nil, - nil, nil, 28, 49, 49, nil, 49, nil, 30, nil, - nil, nil, nil, 4, 52, nil, nil, 24, 25, nil, - nil, 4, nil, nil, nil, nil, 37, 21, nil, nil, - 24, 28, nil, 24, 37, 21, 49, nil, nil, nil, - 52, 4, 24, 52, 25, nil, nil, 49, 52, nil, - 37, 21, nil, nil, 37, 21, nil, 25, nil, 62, - 25, nil, nil, 2, 52, 30, 49, 49, 52, 25, - nil, 27, nil, nil, nil, nil, 49, nil, 30, nil, - 4, nil, 26, 26, nil, 26, nil, nil, 28, nil, - nil, nil, 49, 37, 21, nil, 4, 27, 4, nil, - 52, 28, nil, 37, 21, 37, 21, 52, 54, 37, - 21, 37, 21, 52, 29, 26, 2, 52, 2, 52, - nil, 49, 27, 52, nil, 52, 26, 54, nil, nil, - nil, 24, nil, nil, nil, nil, nil, nil, nil, nil, - 29, nil, 54, nil, nil, 26, 26, nil, nil, 24, - 24, nil, 24, nil, nil, 26, nil, nil, 25, nil, - nil, 54, nil, nil, nil, 29, nil, nil, nil, nil, - nil, 26, nil, nil, nil, nil, 25, 25, 49, 25, - nil, 54, 24, nil, nil, nil, nil, nil, nil, nil, - nil, 49, nil, 24, nil, nil, nil, nil, nil, nil, - 26, nil, nil, nil, nil, nil, nil, 24, 51, 25, - nil, nil, 24, 24, nil, 51, 51, nil, nil, nil, - 25, nil, 24, nil, nil, nil, nil, nil, nil, 27, - 27, nil, 27, nil, 25, nil, nil, nil, 24, 25, - 25, nil, nil, nil, 51, nil, nil, nil, nil, 25, - nil, nil, nil, nil, nil, 54, nil, 26, nil, nil, - nil, nil, 27, 51, nil, 25, 51, 24, nil, 51, - 26, nil, 29, 27, nil, 29, nil, nil, 54, nil, + nil, 26, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 25, 27, + nil, nil, 25, 25, nil, nil, nil, 25, nil, nil, + nil, 27, nil, nil, nil, nil, 52, 52, 52, nil, + 52, 52, 52, 52, 52, 52, 52, nil, 52, 52, + 52, nil, nil, 52, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, - nil, nil, 27, 27, 25, nil, nil, nil, nil, nil, - nil, nil, 27, nil, nil, nil, nil, 54, nil, 54, - nil, nil, nil, nil, nil, nil, 29, nil, 27, nil, - nil, nil, nil, nil, 24, nil, nil, 54, nil, nil, - nil, nil, nil, nil, nil, 29, 29, 24, nil, nil, - nil, nil, nil, nil, nil, 29, nil, 27, nil, nil, - nil, 25, nil, nil, nil, nil, 54, nil, nil, nil, - nil, nil, nil, nil, 25, 51, 51, 51, nil, 51, - 51, 51, 51, 51, 51, 51, nil, 51, 51, 51, - nil, nil, 51, nil, nil, 54, nil, 54, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, - nil, nil, nil, nil, 27, nil, nil, nil, nil, nil, - nil, nil, nil, nil, nil, nil, nil, 27, nil, nil, - nil, 54, nil, nil, nil, 51 ] + nil, nil, nil, nil, 25, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 25, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 52 ] racc_goto_pointer = [ - nil, 86, 13, 23, -13, -8, nil, -2, nil, nil, - nil, nil, nil, nil, nil, nil, nil, nil, nil, -3, - 43, 1, -8, -131, 238, 265, 171, 318, 2, 361, - -21, -11, 6, 13, -68, -28, -108, 0, -18, nil, - 51, -23, -157, nil, nil, nil, -189, -38, nil, 92, - -22, 439, 14, -21, 349, nil, -171, -15, -292, nil, - -66, -123, -23, -251, -9, -165, -180, nil, -177, -124, - -172, -209, -16, 32, 18, -84, 54, 17, 9, -79, - -42, -41, -118, -151, -22, -90, nil ] + nil, 107, 2, 45, -12, -130, 8, nil, 17, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 14, 58, 1, 0, -144, 247, 152, 182, 46, -19, + 29, -13, 16, 6, 30, -48, -7, -128, 0, -34, + nil, 75, -83, -254, nil, nil, nil, -230, -38, nil, + 88, -36, 384, 9, 1, -23, nil, -158, -38, -259, + nil, -36, -96, -21, -247, 211, -167, -196, nil, -137, + -95, -155, -180, -16, 47, -1, -51, 67, 35, 7, + -65, -28, -24, -119, -122, 2, -92, nil ] racc_goto_default = [ - nil, nil, nil, 168, 25, 28, 32, 35, 5, 6, - 10, 13, 15, 18, 20, 24, 27, 31, 34, 4, - nil, 99, nil, 79, 101, 103, 105, 108, 109, 113, - 95, 96, 8, nil, nil, nil, nil, 85, nil, 30, - nil, nil, 161, 239, 164, 165, nil, nil, 144, 107, - 110, 111, 67, 134, 98, 150, 151, nil, 248, 104, - nil, nil, nil, nil, 69, nil, nil, 301, 80, nil, - nil, nil, nil, nil, nil, nil, nil, nil, nil, 57, - nil, nil, nil, nil, nil, nil, 192 ] + nil, nil, 279, 208, 25, nil, 31, 35, 4, 7, + 9, 14, 16, 19, 21, 24, 28, 30, 34, 3, + 6, nil, 98, nil, 76, 101, 102, 105, 107, 108, + 93, 94, 96, 12, nil, nil, nil, nil, 83, nil, + 33, nil, nil, 204, 291, 205, 206, nil, nil, 147, + 106, 109, 91, 64, 137, 97, 152, 153, nil, 260, + 104, nil, nil, nil, nil, 67, nil, nil, 302, 77, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 58, nil, nil, nil, nil, nil, nil, 197 ] racc_reduce_table = [ 0, 0, :racc_error, - 1, 70, :_reduce_1, 1, 70, :_reduce_none, - 1, 71, :_reduce_none, + 1, 70, :_reduce_none, + 1, 71, :_reduce_3, 2, 71, :_reduce_4, + 1, 74, :_reduce_5, 1, 73, :_reduce_none, 1, 73, :_reduce_none, 1, 73, :_reduce_none, @@ -685,225 +650,225 @@ racc_reduce_table = [ 1, 73, :_reduce_none, 1, 73, :_reduce_none, 1, 73, :_reduce_none, - 3, 87, :_reduce_19, - 3, 87, :_reduce_20, - 1, 88, :_reduce_none, - 1, 88, :_reduce_none, - 1, 88, :_reduce_none, + 3, 88, :_reduce_20, + 3, 88, :_reduce_21, 1, 89, :_reduce_none, 1, 89, :_reduce_none, 1, 89, :_reduce_none, - 1, 89, :_reduce_none, - 4, 81, :_reduce_28, - 5, 81, :_reduce_29, - 3, 81, :_reduce_30, - 2, 81, :_reduce_31, - 1, 91, :_reduce_none, - 1, 91, :_reduce_none, - 3, 91, :_reduce_34, - 3, 91, :_reduce_35, - 1, 92, :_reduce_none, - 1, 92, :_reduce_none, - 1, 92, :_reduce_none, - 1, 92, :_reduce_none, - 1, 92, :_reduce_none, - 1, 92, :_reduce_none, - 1, 92, :_reduce_none, - 1, 92, :_reduce_none, - 1, 92, :_reduce_44, - 5, 74, :_reduce_45, - 5, 74, :_reduce_46, - 5, 74, :_reduce_47, - 5, 85, :_reduce_48, - 2, 75, :_reduce_49, - 1, 108, :_reduce_50, - 2, 108, :_reduce_51, - 6, 76, :_reduce_52, - 2, 76, :_reduce_53, - 3, 109, :_reduce_54, - 3, 109, :_reduce_55, - 1, 110, :_reduce_none, - 1, 110, :_reduce_none, - 3, 110, :_reduce_58, + 1, 90, :_reduce_none, + 1, 90, :_reduce_none, + 1, 90, :_reduce_none, + 1, 90, :_reduce_none, + 4, 82, :_reduce_29, + 5, 82, :_reduce_30, + 3, 82, :_reduce_31, + 2, 82, :_reduce_32, + 1, 92, :_reduce_33, + 1, 92, :_reduce_34, + 3, 92, :_reduce_35, + 3, 92, :_reduce_36, + 1, 93, :_reduce_none, + 1, 93, :_reduce_none, + 1, 93, :_reduce_none, + 1, 93, :_reduce_none, + 1, 93, :_reduce_none, + 1, 93, :_reduce_none, + 1, 93, :_reduce_none, + 1, 93, :_reduce_none, + 1, 93, :_reduce_45, + 5, 75, :_reduce_46, + 5, 75, :_reduce_47, + 5, 75, :_reduce_48, + 5, 86, :_reduce_49, + 2, 76, :_reduce_50, + 1, 109, :_reduce_51, + 2, 109, :_reduce_52, + 6, 77, :_reduce_53, + 2, 77, :_reduce_54, + 3, 110, :_reduce_55, + 3, 110, :_reduce_56, 1, 111, :_reduce_none, - 3, 111, :_reduce_60, - 1, 112, :_reduce_61, - 1, 112, :_reduce_62, - 3, 113, :_reduce_63, - 3, 113, :_reduce_64, - 1, 114, :_reduce_none, - 1, 114, :_reduce_none, - 4, 116, :_reduce_67, - 1, 102, :_reduce_none, - 3, 102, :_reduce_69, - 0, 103, :_reduce_none, - 1, 103, :_reduce_none, - 1, 118, :_reduce_72, - 1, 93, :_reduce_73, - 1, 95, :_reduce_74, - 1, 117, :_reduce_none, - 1, 117, :_reduce_none, - 1, 117, :_reduce_none, - 1, 117, :_reduce_none, - 1, 117, :_reduce_none, - 1, 117, :_reduce_none, - 1, 117, :_reduce_none, - 3, 77, :_reduce_82, - 3, 77, :_reduce_83, - 3, 86, :_reduce_84, - 0, 104, :_reduce_85, - 1, 104, :_reduce_86, - 3, 104, :_reduce_87, - 3, 122, :_reduce_88, - 3, 124, :_reduce_89, - 1, 125, :_reduce_none, - 1, 125, :_reduce_none, - 0, 107, :_reduce_92, - 1, 107, :_reduce_93, - 3, 107, :_reduce_94, - 1, 126, :_reduce_none, - 3, 126, :_reduce_96, - 1, 115, :_reduce_none, - 1, 115, :_reduce_none, - 1, 115, :_reduce_none, - 1, 115, :_reduce_none, + 1, 111, :_reduce_none, + 3, 111, :_reduce_59, + 1, 112, :_reduce_none, + 3, 112, :_reduce_61, + 1, 113, :_reduce_62, + 1, 113, :_reduce_63, + 3, 114, :_reduce_64, + 3, 114, :_reduce_65, 1, 115, :_reduce_none, 1, 115, :_reduce_none, - 1, 123, :_reduce_none, - 1, 123, :_reduce_none, - 1, 123, :_reduce_none, - 1, 123, :_reduce_none, - 1, 123, :_reduce_none, - 1, 123, :_reduce_none, - 1, 123, :_reduce_none, - 1, 123, :_reduce_none, - 1, 123, :_reduce_none, - 1, 123, :_reduce_none, - 1, 123, :_reduce_none, - 1, 123, :_reduce_none, - 4, 97, :_reduce_115, - 3, 97, :_reduce_116, - 1, 99, :_reduce_117, - 2, 99, :_reduce_118, - 2, 129, :_reduce_119, - 1, 130, :_reduce_120, - 2, 130, :_reduce_121, - 1, 96, :_reduce_122, - 4, 90, :_reduce_123, - 4, 90, :_reduce_124, - 2, 79, :_reduce_125, - 5, 131, :_reduce_126, - 4, 131, :_reduce_127, - 0, 132, :_reduce_none, - 2, 132, :_reduce_129, - 4, 132, :_reduce_130, - 3, 132, :_reduce_131, - 1, 120, :_reduce_none, - 3, 120, :_reduce_133, - 3, 120, :_reduce_134, - 3, 120, :_reduce_135, - 3, 120, :_reduce_136, - 3, 120, :_reduce_137, - 3, 120, :_reduce_138, - 3, 120, :_reduce_139, - 3, 120, :_reduce_140, - 3, 120, :_reduce_141, - 2, 120, :_reduce_142, - 3, 120, :_reduce_143, - 3, 120, :_reduce_144, - 3, 120, :_reduce_145, - 3, 120, :_reduce_146, - 3, 120, :_reduce_147, - 3, 120, :_reduce_148, - 2, 120, :_reduce_149, - 3, 120, :_reduce_150, - 3, 120, :_reduce_151, - 3, 120, :_reduce_152, - 5, 78, :_reduce_153, - 1, 134, :_reduce_none, - 2, 134, :_reduce_155, - 5, 135, :_reduce_156, - 4, 135, :_reduce_157, - 1, 136, :_reduce_none, - 3, 136, :_reduce_159, - 3, 98, :_reduce_160, + 4, 117, :_reduce_68, + 1, 103, :_reduce_69, + 3, 103, :_reduce_70, + 0, 104, :_reduce_none, + 1, 104, :_reduce_none, + 1, 119, :_reduce_73, + 1, 94, :_reduce_74, + 1, 96, :_reduce_75, + 1, 118, :_reduce_none, + 1, 118, :_reduce_none, + 1, 118, :_reduce_none, + 1, 118, :_reduce_none, + 1, 118, :_reduce_none, + 1, 118, :_reduce_none, + 1, 118, :_reduce_none, + 3, 78, :_reduce_83, + 3, 78, :_reduce_84, + 3, 87, :_reduce_85, + 0, 105, :_reduce_86, + 1, 105, :_reduce_87, + 3, 105, :_reduce_88, + 3, 123, :_reduce_89, + 3, 125, :_reduce_90, + 1, 126, :_reduce_none, + 1, 126, :_reduce_none, + 0, 108, :_reduce_93, + 1, 108, :_reduce_94, + 3, 108, :_reduce_95, + 1, 127, :_reduce_96, + 3, 127, :_reduce_97, + 1, 116, :_reduce_none, + 1, 116, :_reduce_none, + 1, 116, :_reduce_none, + 1, 116, :_reduce_none, + 1, 116, :_reduce_none, + 1, 116, :_reduce_none, + 1, 124, :_reduce_none, + 1, 124, :_reduce_none, + 1, 124, :_reduce_none, + 1, 124, :_reduce_none, + 1, 124, :_reduce_none, + 1, 124, :_reduce_none, + 1, 124, :_reduce_none, + 1, 124, :_reduce_none, + 1, 124, :_reduce_none, + 1, 124, :_reduce_none, + 1, 124, :_reduce_none, + 1, 124, :_reduce_none, + 4, 98, :_reduce_116, + 3, 98, :_reduce_117, + 1, 100, :_reduce_118, + 2, 100, :_reduce_119, + 2, 130, :_reduce_120, + 1, 131, :_reduce_121, + 2, 131, :_reduce_122, + 1, 97, :_reduce_123, + 4, 91, :_reduce_124, + 4, 91, :_reduce_125, + 2, 80, :_reduce_126, + 5, 132, :_reduce_127, + 4, 132, :_reduce_128, + 0, 133, :_reduce_none, + 2, 133, :_reduce_130, + 4, 133, :_reduce_131, + 3, 133, :_reduce_132, + 1, 121, :_reduce_none, + 3, 121, :_reduce_134, + 3, 121, :_reduce_135, + 3, 121, :_reduce_136, + 3, 121, :_reduce_137, + 3, 121, :_reduce_138, + 3, 121, :_reduce_139, + 3, 121, :_reduce_140, + 3, 121, :_reduce_141, + 3, 121, :_reduce_142, + 2, 121, :_reduce_143, + 3, 121, :_reduce_144, + 3, 121, :_reduce_145, + 3, 121, :_reduce_146, + 3, 121, :_reduce_147, + 3, 121, :_reduce_148, + 3, 121, :_reduce_149, + 2, 121, :_reduce_150, + 3, 121, :_reduce_151, + 3, 121, :_reduce_152, + 3, 121, :_reduce_153, + 5, 79, :_reduce_154, + 1, 135, :_reduce_155, + 2, 135, :_reduce_156, + 5, 136, :_reduce_157, + 4, 136, :_reduce_158, + 1, 137, :_reduce_159, + 3, 137, :_reduce_160, + 3, 99, :_reduce_161, + 1, 139, :_reduce_none, + 4, 139, :_reduce_163, + 1, 141, :_reduce_none, + 3, 141, :_reduce_165, + 3, 140, :_reduce_166, 1, 138, :_reduce_none, - 4, 138, :_reduce_162, - 1, 140, :_reduce_none, - 3, 140, :_reduce_164, - 3, 139, :_reduce_165, - 1, 137, :_reduce_none, - 1, 137, :_reduce_none, - 1, 137, :_reduce_none, - 1, 137, :_reduce_none, - 1, 137, :_reduce_none, - 1, 137, :_reduce_none, - 1, 137, :_reduce_none, - 1, 137, :_reduce_none, - 1, 137, :_reduce_174, - 1, 137, :_reduce_none, - 1, 141, :_reduce_176, - 1, 142, :_reduce_none, - 3, 142, :_reduce_178, - 2, 80, :_reduce_179, - 6, 82, :_reduce_180, - 5, 82, :_reduce_181, - 7, 83, :_reduce_182, - 6, 83, :_reduce_183, + 1, 138, :_reduce_none, + 1, 138, :_reduce_none, + 1, 138, :_reduce_none, + 1, 138, :_reduce_none, + 1, 138, :_reduce_none, + 1, 138, :_reduce_none, + 1, 138, :_reduce_none, + 1, 138, :_reduce_175, + 1, 138, :_reduce_none, + 1, 142, :_reduce_177, + 1, 143, :_reduce_none, + 3, 143, :_reduce_179, + 2, 81, :_reduce_180, + 6, 83, :_reduce_181, + 5, 83, :_reduce_182, + 7, 84, :_reduce_183, 6, 84, :_reduce_184, - 5, 84, :_reduce_185, - 1, 106, :_reduce_186, - 1, 101, :_reduce_187, - 1, 101, :_reduce_188, - 1, 101, :_reduce_189, - 1, 145, :_reduce_none, - 3, 145, :_reduce_191, - 1, 147, :_reduce_192, + 6, 85, :_reduce_185, + 5, 85, :_reduce_186, + 1, 107, :_reduce_187, + 1, 102, :_reduce_188, + 1, 102, :_reduce_189, + 1, 102, :_reduce_190, + 1, 146, :_reduce_191, + 3, 146, :_reduce_192, 1, 148, :_reduce_193, - 1, 148, :_reduce_194, - 1, 148, :_reduce_195, - 1, 148, :_reduce_none, - 0, 72, :_reduce_197, - 0, 149, :_reduce_198, - 1, 143, :_reduce_none, - 3, 143, :_reduce_200, - 3, 143, :_reduce_201, - 1, 150, :_reduce_none, - 3, 150, :_reduce_203, - 3, 151, :_reduce_204, - 1, 151, :_reduce_205, - 3, 151, :_reduce_206, - 1, 151, :_reduce_207, - 1, 146, :_reduce_none, - 2, 146, :_reduce_209, + 1, 149, :_reduce_194, + 1, 149, :_reduce_195, + 1, 149, :_reduce_196, + 1, 149, :_reduce_none, + 0, 72, :_reduce_198, + 0, 150, :_reduce_199, 1, 144, :_reduce_none, - 2, 144, :_reduce_211, - 1, 152, :_reduce_none, - 1, 152, :_reduce_none, - 1, 94, :_reduce_214, - 3, 119, :_reduce_215, - 4, 119, :_reduce_216, - 2, 119, :_reduce_217, - 1, 127, :_reduce_none, - 1, 127, :_reduce_none, - 0, 105, :_reduce_none, - 1, 105, :_reduce_221, - 1, 133, :_reduce_222, - 3, 128, :_reduce_223, - 4, 128, :_reduce_224, - 2, 128, :_reduce_225, + 3, 144, :_reduce_201, + 3, 144, :_reduce_202, + 1, 151, :_reduce_none, + 3, 151, :_reduce_204, + 3, 152, :_reduce_205, + 1, 152, :_reduce_206, + 3, 152, :_reduce_207, + 1, 152, :_reduce_208, + 1, 147, :_reduce_none, + 2, 147, :_reduce_210, + 1, 145, :_reduce_none, + 2, 145, :_reduce_212, 1, 153, :_reduce_none, - 3, 153, :_reduce_227, + 1, 153, :_reduce_none, + 1, 95, :_reduce_215, + 3, 120, :_reduce_216, + 4, 120, :_reduce_217, + 2, 120, :_reduce_218, + 1, 128, :_reduce_none, + 1, 128, :_reduce_none, + 0, 106, :_reduce_none, + 1, 106, :_reduce_222, + 1, 134, :_reduce_223, + 3, 129, :_reduce_224, + 4, 129, :_reduce_225, + 2, 129, :_reduce_226, + 1, 154, :_reduce_none, 3, 154, :_reduce_228, - 1, 155, :_reduce_229, - 1, 155, :_reduce_230, - 4, 121, :_reduce_231, - 1, 100, :_reduce_none, - 4, 100, :_reduce_233 ] + 3, 155, :_reduce_229, + 1, 156, :_reduce_230, + 1, 156, :_reduce_231, + 4, 122, :_reduce_232, + 1, 101, :_reduce_none, + 4, 101, :_reduce_234 ] -racc_reduce_n = 234 +racc_reduce_n = 235 -racc_shift_n = 385 +racc_shift_n = 386 racc_token_table = { false => 0, @@ -1068,9 +1033,10 @@ Racc_token_to_s_table = [ "IN", "$start", "program", - "statements", + "statements_and_declarations", "nil", - "statement", + "statement_or_declaration", + "statements", "resource", "virtualresource", "collection", @@ -1160,51 +1126,43 @@ Racc_debug_parser = false # reduce 0 omitted -module_eval(<<'.,.,', 'grammar.ra', 31) - def _reduce_1(val, _values, result) - if val[0] - # Make sure we always return an array. - if val[0].is_a?(AST::ASTArray) - if val[0].children.empty? - result = nil - else - result = val[0] - end - else - result = aryfy(val[0]) - end - else - result = nil - end +# reduce 1 omitted +# reduce 2 omitted + +module_eval(<<'.,.,', 'grammar.ra', 34) + def _reduce_3(val, _values, result) + result = ast AST::ASTArray, :children => (val[0] ? [val[0]] : []) + result end .,., -# reduce 2 omitted - -# reduce 3 omitted - -module_eval(<<'.,.,', 'grammar.ra', 50) +module_eval(<<'.,.,', 'grammar.ra', 37) def _reduce_4(val, _values, result) - if val[0] and val[1] - if val[0].instance_of?(AST::ASTArray) + if val[1] val[0].push(val[1]) - result = val[0] - else - result = ast AST::ASTArray, :children => [val[0],val[1]] end - elsif obj = (val[0] || val[1]) - result = obj - else result = nil + result = val[0] + + result + end +.,., + +module_eval(<<'.,.,', 'grammar.ra', 46) + def _reduce_5(val, _values, result) + val[0].each do |stmt| + if stmt.is_a?(AST::TopLevelConstruct) + error "Classes, definitions, and nodes may only appear at toplevel or inside other classes", \ + :line => stmt.context[:line], :file => stmt.context[:file] + end end + result = val[0] result end .,., -# reduce 5 omitted - # reduce 6 omitted # reduce 7 omitted @@ -1231,24 +1189,24 @@ module_eval(<<'.,.,', 'grammar.ra', 50) # reduce 18 omitted -module_eval(<<'.,.,', 'grammar.ra', 80) - def _reduce_19(val, _values, result) +# reduce 19 omitted + +module_eval(<<'.,.,', 'grammar.ra', 72) + def _reduce_20(val, _values, result) result = AST::Relationship.new(val[0], val[2], val[1][:value], ast_context) result end .,., -module_eval(<<'.,.,', 'grammar.ra', 83) - def _reduce_20(val, _values, result) +module_eval(<<'.,.,', 'grammar.ra', 75) + def _reduce_21(val, _values, result) result = AST::Relationship.new(val[0], val[2], val[1][:value], ast_context) result end .,., -# reduce 21 omitted - # reduce 22 omitted # reduce 23 omitted @@ -1261,34 +1219,34 @@ module_eval(<<'.,.,', 'grammar.ra', 83) # reduce 27 omitted -module_eval(<<'.,.,', 'grammar.ra', 91) - def _reduce_28(val, _values, result) - args = aryfy(val[2]) - result = ast AST::Function, +# reduce 28 omitted + +module_eval(<<'.,.,', 'grammar.ra', 83) + def _reduce_29(val, _values, result) + result = ast AST::Function, :name => val[0][:value], :line => val[0][:line], - :arguments => args, + :arguments => val[2], :ftype => :statement result end .,., -module_eval(<<'.,.,', 'grammar.ra', 99) - def _reduce_29(val, _values, result) - args = aryfy(val[2]) - result = ast AST::Function, +module_eval(<<'.,.,', 'grammar.ra', 90) + def _reduce_30(val, _values, result) + result = ast AST::Function, :name => val[0][:value], :line => val[0][:line], - :arguments => args, + :arguments => val[2], :ftype => :statement result end .,., -module_eval(<<'.,.,', 'grammar.ra', 106) - def _reduce_30(val, _values, result) +module_eval(<<'.,.,', 'grammar.ra', 96) + def _reduce_31(val, _values, result) result = ast AST::Function, :name => val[0][:value], :line => val[0][:line], @@ -1299,49 +1257,50 @@ module_eval(<<'.,.,', 'grammar.ra', 106) end .,., -module_eval(<<'.,.,', 'grammar.ra', 113) - def _reduce_31(val, _values, result) - args = aryfy(val[1]) - result = ast AST::Function, +module_eval(<<'.,.,', 'grammar.ra', 103) + def _reduce_32(val, _values, result) + result = ast AST::Function, :name => val[0][:value], :line => val[0][:line], - :arguments => args, + :arguments => val[1], :ftype => :statement result end .,., -# reduce 32 omitted - -# reduce 33 omitted +module_eval(<<'.,.,', 'grammar.ra', 110) + def _reduce_33(val, _values, result) + result = aryfy(val[0]) + result + end +.,., -module_eval(<<'.,.,', 'grammar.ra', 124) +module_eval(<<'.,.,', 'grammar.ra', 111) def _reduce_34(val, _values, result) - result = aryfy(val[0], val[2]) - result.line = @lexer.line - result.file = @lexer.file - + result = aryfy(val[0]) result end .,., -module_eval(<<'.,.,', 'grammar.ra', 129) +module_eval(<<'.,.,', 'grammar.ra', 113) def _reduce_35(val, _values, result) - unless val[0].is_a?(AST::ASTArray) - val[0] = aryfy(val[0]) - end + val[0].push(val[2]) + result = val[0] - val[0].push(val[2]) + result + end +.,., - result = val[0] +module_eval(<<'.,.,', 'grammar.ra', 117) + def _reduce_36(val, _values, result) + val[0].push(val[2]) + result = val[0] result end .,., -# reduce 36 omitted - # reduce 37 omitted # reduce 38 omitted @@ -1356,41 +1315,27 @@ module_eval(<<'.,.,', 'grammar.ra', 129) # reduce 43 omitted -module_eval(<<'.,.,', 'grammar.ra', 149) - def _reduce_44(val, _values, result) +# reduce 44 omitted + +module_eval(<<'.,.,', 'grammar.ra', 132) + def _reduce_45(val, _values, result) result = ast AST::Name, :value => val[0][:value] result end .,., -module_eval(<<'.,.,', 'grammar.ra', 153) - def _reduce_45(val, _values, result) +module_eval(<<'.,.,', 'grammar.ra', 136) + def _reduce_46(val, _values, result) @lexer.commentpop - array = val[2] - array = [array] if array.instance_of?(AST::ResourceInstance) - result = ast AST::ASTArray - - # this iterates across each specified resourceinstance - array.each { |instance| - raise Puppet::Dev, "Got something that isn't an instance" unless instance.instance_of?(AST::ResourceInstance) - # now, i need to somehow differentiate between those things with - # arrays in their names, and normal things - - result.push ast( - AST::Resource, - :type => val[0], - :title => instance[0], - - :parameters => instance[1]) - } + result = ast(AST::Resource, :type => val[0], :instances => val[2]) result end .,., -module_eval(<<'.,.,', 'grammar.ra', 172) - def _reduce_46(val, _values, result) +module_eval(<<'.,.,', 'grammar.ra', 139) + def _reduce_47(val, _values, result) # This is a deprecated syntax. error "All resource specifications require names" @@ -1398,8 +1343,8 @@ module_eval(<<'.,.,', 'grammar.ra', 172) end .,., -module_eval(<<'.,.,', 'grammar.ra', 175) - def _reduce_47(val, _values, result) +module_eval(<<'.,.,', 'grammar.ra', 142) + def _reduce_48(val, _values, result) # a defaults setting for a type @lexer.commentpop result = ast(AST::ResourceDefaults, :type => val[0], :parameters => val[2]) @@ -1408,8 +1353,8 @@ module_eval(<<'.,.,', 'grammar.ra', 175) end .,., -module_eval(<<'.,.,', 'grammar.ra', 182) - def _reduce_48(val, _values, result) +module_eval(<<'.,.,', 'grammar.ra', 149) + def _reduce_49(val, _values, result) @lexer.commentpop result = ast AST::ResourceOverride, :object => val[0], :parameters => val[2] @@ -1417,8 +1362,8 @@ module_eval(<<'.,.,', 'grammar.ra', 182) end .,., -module_eval(<<'.,.,', 'grammar.ra', 189) - def _reduce_49(val, _values, result) +module_eval(<<'.,.,', 'grammar.ra', 156) + def _reduce_50(val, _values, result) type = val[0] if (type == :exported and ! Puppet[:storeconfigs]) and ! Puppet[:parseonly] @@ -1429,14 +1374,8 @@ module_eval(<<'.,.,', 'grammar.ra', 189) method = type.to_s + "=" - # Just mark our resources as exported and pass them through. - if val[1].instance_of?(AST::ASTArray) - val[1].each do |obj| - obj.send(method, true) - end - else - val[1].send(method, true) - end + # Just mark our resource as exported and pass it through. + val[1].send(method, true) result = val[1] @@ -1444,22 +1383,22 @@ module_eval(<<'.,.,', 'grammar.ra', 189) end .,., -module_eval(<<'.,.,', 'grammar.ra', 211) - def _reduce_50(val, _values, result) +module_eval(<<'.,.,', 'grammar.ra', 172) + def _reduce_51(val, _values, result) result = :virtual result end .,., -module_eval(<<'.,.,', 'grammar.ra', 212) - def _reduce_51(val, _values, result) +module_eval(<<'.,.,', 'grammar.ra', 173) + def _reduce_52(val, _values, result) result = :exported result end .,., -module_eval(<<'.,.,', 'grammar.ra', 217) - def _reduce_52(val, _values, result) +module_eval(<<'.,.,', 'grammar.ra', 178) + def _reduce_53(val, _values, result) @lexer.commentpop Puppet.warning addcontext("Collection names must now be capitalized") if val[0] =~ /^[a-z]/ type = val[0].downcase @@ -1482,8 +1421,8 @@ module_eval(<<'.,.,', 'grammar.ra', 217) end .,., -module_eval(<<'.,.,', 'grammar.ra', 236) - def _reduce_53(val, _values, result) +module_eval(<<'.,.,', 'grammar.ra', 197) + def _reduce_54(val, _values, result) if val[0] =~ /^[a-z]/ Puppet.warning addcontext("Collection names must now be capitalized") end @@ -1506,8 +1445,8 @@ module_eval(<<'.,.,', 'grammar.ra', 236) end .,., -module_eval(<<'.,.,', 'grammar.ra', 257) - def _reduce_54(val, _values, result) +module_eval(<<'.,.,', 'grammar.ra', 218) + def _reduce_55(val, _values, result) if val[1] result = val[1] result.form = :virtual @@ -1519,8 +1458,8 @@ module_eval(<<'.,.,', 'grammar.ra', 257) end .,., -module_eval(<<'.,.,', 'grammar.ra', 265) - def _reduce_55(val, _values, result) +module_eval(<<'.,.,', 'grammar.ra', 226) + def _reduce_56(val, _values, result) if val[1] result = val[1] result.form = :exported @@ -1532,22 +1471,22 @@ module_eval(<<'.,.,', 'grammar.ra', 265) end .,., -# reduce 56 omitted - # reduce 57 omitted -module_eval(<<'.,.,', 'grammar.ra', 278) - def _reduce_58(val, _values, result) +# reduce 58 omitted + +module_eval(<<'.,.,', 'grammar.ra', 239) + def _reduce_59(val, _values, result) result = ast AST::CollExpr, :test1 => val[0], :oper => val[1], :test2 => val[2] result end .,., -# reduce 59 omitted +# reduce 60 omitted -module_eval(<<'.,.,', 'grammar.ra', 283) - def _reduce_60(val, _values, result) +module_eval(<<'.,.,', 'grammar.ra', 244) + def _reduce_61(val, _values, result) result = val[1] result.parens = true @@ -1555,22 +1494,22 @@ module_eval(<<'.,.,', 'grammar.ra', 283) end .,., -module_eval(<<'.,.,', 'grammar.ra', 287) - def _reduce_61(val, _values, result) +module_eval(<<'.,.,', 'grammar.ra', 248) + def _reduce_62(val, _values, result) result=val[0][:value] result end .,., -module_eval(<<'.,.,', 'grammar.ra', 288) - def _reduce_62(val, _values, result) +module_eval(<<'.,.,', 'grammar.ra', 249) + def _reduce_63(val, _values, result) result=val[0][:value] result end .,., -module_eval(<<'.,.,', 'grammar.ra', 291) - def _reduce_63(val, _values, result) +module_eval(<<'.,.,', 'grammar.ra', 252) + def _reduce_64(val, _values, result) result = ast AST::CollExpr, :test1 => val[0], :oper => val[1][:value], :test2 => val[2] #result = ast AST::CollExpr #result.push *val @@ -1579,8 +1518,8 @@ module_eval(<<'.,.,', 'grammar.ra', 291) end .,., -module_eval(<<'.,.,', 'grammar.ra', 296) - def _reduce_64(val, _values, result) +module_eval(<<'.,.,', 'grammar.ra', 257) + def _reduce_65(val, _values, result) result = ast AST::CollExpr, :test1 => val[0], :oper => val[1][:value], :test2 => val[2] #result = ast AST::CollExpr #result.push *val @@ -1589,63 +1528,62 @@ module_eval(<<'.,.,', 'grammar.ra', 296) end .,., -# reduce 65 omitted - # reduce 66 omitted -module_eval(<<'.,.,', 'grammar.ra', 305) - def _reduce_67(val, _values, result) - result = ast AST::ResourceInstance, :children => [val[0],val[2]] +# reduce 67 omitted + +module_eval(<<'.,.,', 'grammar.ra', 266) + def _reduce_68(val, _values, result) + result = ast AST::ResourceInstance, :title => val[0], :parameters => val[2] result end .,., -# reduce 68 omitted - -module_eval(<<'.,.,', 'grammar.ra', 310) +module_eval(<<'.,.,', 'grammar.ra', 269) def _reduce_69(val, _values, result) - if val[0].instance_of?(AST::ResourceInstance) - result = ast AST::ASTArray, :children => [val[0],val[2]] - else - val[0].push val[2] - result = val[0] + result = aryfy(val[0]) + result end +.,., + +module_eval(<<'.,.,', 'grammar.ra', 271) + def _reduce_70(val, _values, result) + val[0].push val[2] + result = val[0] result end .,., -# reduce 70 omitted - # reduce 71 omitted -module_eval(<<'.,.,', 'grammar.ra', 322) - def _reduce_72(val, _values, result) +# reduce 72 omitted + +module_eval(<<'.,.,', 'grammar.ra', 279) + def _reduce_73(val, _values, result) result = ast AST::Undef, :value => :undef result end .,., -module_eval(<<'.,.,', 'grammar.ra', 326) - def _reduce_73(val, _values, result) +module_eval(<<'.,.,', 'grammar.ra', 283) + def _reduce_74(val, _values, result) result = ast AST::Name, :value => val[0][:value], :line => val[0][:line] result end .,., -module_eval(<<'.,.,', 'grammar.ra', 330) - def _reduce_74(val, _values, result) +module_eval(<<'.,.,', 'grammar.ra', 287) + def _reduce_75(val, _values, result) result = ast AST::Type, :value => val[0][:value], :line => val[0][:line] result end .,., -# reduce 75 omitted - # reduce 76 omitted # reduce 77 omitted @@ -1658,8 +1596,10 @@ module_eval(<<'.,.,', 'grammar.ra', 330) # reduce 81 omitted -module_eval(<<'.,.,', 'grammar.ra', 342) - def _reduce_82(val, _values, result) +# reduce 82 omitted + +module_eval(<<'.,.,', 'grammar.ra', 299) + def _reduce_83(val, _values, result) raise Puppet::ParseError, "Cannot assign to variables in other namespaces" if val[0][:value] =~ /::/ # this is distinct from referencing a variable variable = ast AST::Name, :value => val[0][:value], :line => val[0][:line] @@ -1669,16 +1609,16 @@ module_eval(<<'.,.,', 'grammar.ra', 342) end .,., -module_eval(<<'.,.,', 'grammar.ra', 348) - def _reduce_83(val, _values, result) +module_eval(<<'.,.,', 'grammar.ra', 305) + def _reduce_84(val, _values, result) result = ast AST::VarDef, :name => val[0], :value => val[2] result end .,., -module_eval(<<'.,.,', 'grammar.ra', 352) - def _reduce_84(val, _values, result) +module_eval(<<'.,.,', 'grammar.ra', 309) + def _reduce_85(val, _values, result) variable = ast AST::Name, :value => val[0][:value], :line => val[0][:line] result = ast AST::VarDef, :name => variable, :value => val[2], :append => true, :line => val[0][:line] @@ -1686,44 +1626,40 @@ module_eval(<<'.,.,', 'grammar.ra', 352) end .,., -module_eval(<<'.,.,', 'grammar.ra', 358) - def _reduce_85(val, _values, result) +module_eval(<<'.,.,', 'grammar.ra', 315) + def _reduce_86(val, _values, result) result = ast AST::ASTArray result end .,., -module_eval(<<'.,.,', 'grammar.ra', 360) - def _reduce_86(val, _values, result) - result = val[0] +module_eval(<<'.,.,', 'grammar.ra', 317) + def _reduce_87(val, _values, result) + result = aryfy(val[0]) result end .,., -module_eval(<<'.,.,', 'grammar.ra', 362) - def _reduce_87(val, _values, result) - if val[0].instance_of?(AST::ASTArray) - val[0].push(val[2]) +module_eval(<<'.,.,', 'grammar.ra', 319) + def _reduce_88(val, _values, result) + val[0].push(val[2]) result = val[0] - else - result = ast AST::ASTArray, :children => [val[0],val[2]] - end result end .,., -module_eval(<<'.,.,', 'grammar.ra', 371) - def _reduce_88(val, _values, result) +module_eval(<<'.,.,', 'grammar.ra', 324) + def _reduce_89(val, _values, result) result = ast AST::ResourceParam, :param => val[0][:value], :line => val[0][:line], :value => val[2] result end .,., -module_eval(<<'.,.,', 'grammar.ra', 375) - def _reduce_89(val, _values, result) +module_eval(<<'.,.,', 'grammar.ra', 328) + def _reduce_90(val, _values, result) result = ast AST::ResourceParam, :param => val[0][:value], :line => val[0][:line], :value => val[2], :add => true @@ -1731,54 +1667,48 @@ module_eval(<<'.,.,', 'grammar.ra', 375) end .,., -# reduce 90 omitted - # reduce 91 omitted -module_eval(<<'.,.,', 'grammar.ra', 384) - def _reduce_92(val, _values, result) +# reduce 92 omitted + +module_eval(<<'.,.,', 'grammar.ra', 337) + def _reduce_93(val, _values, result) result = ast AST::ASTArray result end .,., -module_eval(<<'.,.,', 'grammar.ra', 386) - def _reduce_93(val, _values, result) - result = val[0] +module_eval(<<'.,.,', 'grammar.ra', 339) + def _reduce_94(val, _values, result) + result = aryfy(val[0]) result end .,., -module_eval(<<'.,.,', 'grammar.ra', 388) - def _reduce_94(val, _values, result) - if val[0].instance_of?(AST::ASTArray) - val[0].push(val[2]) +module_eval(<<'.,.,', 'grammar.ra', 341) + def _reduce_95(val, _values, result) + val[0].push(val[2]) result = val[0] - else - result = ast AST::ASTArray, :children => [val[0],val[2]] - end result end .,., -# reduce 95 omitted - -module_eval(<<'.,.,', 'grammar.ra', 398) +module_eval(<<'.,.,', 'grammar.ra', 345) def _reduce_96(val, _values, result) - if val[0].instance_of?(AST::ASTArray) - result = val[0].push(val[2]) - else - result = ast AST::ASTArray, :children => [val[0],val[2]] + result = aryfy(val[0]) + result end +.,., +module_eval(<<'.,.,', 'grammar.ra', 346) + def _reduce_97(val, _values, result) + result = val[0].push(val[2]) result end .,., -# reduce 97 omitted - # reduce 98 omitted # reduce 99 omitted @@ -1813,20 +1743,21 @@ module_eval(<<'.,.,', 'grammar.ra', 398) # reduce 114 omitted -module_eval(<<'.,.,', 'grammar.ra', 427) - def _reduce_115(val, _values, result) - args = aryfy(val[2]) - result = ast AST::Function, +# reduce 115 omitted + +module_eval(<<'.,.,', 'grammar.ra', 370) + def _reduce_116(val, _values, result) + result = ast AST::Function, :name => val[0][:value], :line => val[0][:line], - :arguments => args, + :arguments => val[2], :ftype => :rvalue result end .,., -module_eval(<<'.,.,', 'grammar.ra', 433) - def _reduce_116(val, _values, result) +module_eval(<<'.,.,', 'grammar.ra', 375) + def _reduce_117(val, _values, result) result = ast AST::Function, :name => val[0][:value], :line => val[0][:line], :arguments => AST::ASTArray.new({}), @@ -1836,51 +1767,51 @@ module_eval(<<'.,.,', 'grammar.ra', 433) end .,., -module_eval(<<'.,.,', 'grammar.ra', 439) - def _reduce_117(val, _values, result) +module_eval(<<'.,.,', 'grammar.ra', 381) + def _reduce_118(val, _values, result) result = ast AST::String, :value => val[0][:value], :line => val[0][:line] result end .,., -module_eval(<<'.,.,', 'grammar.ra', 440) - def _reduce_118(val, _values, result) +module_eval(<<'.,.,', 'grammar.ra', 382) + def _reduce_119(val, _values, result) result = ast AST::Concat, :value => [ast(AST::String,val[0])]+val[1], :line => val[0][:line] result end .,., -module_eval(<<'.,.,', 'grammar.ra', 442) - def _reduce_119(val, _values, result) +module_eval(<<'.,.,', 'grammar.ra', 384) + def _reduce_120(val, _values, result) result = [val[0]] + val[1] result end .,., -module_eval(<<'.,.,', 'grammar.ra', 444) - def _reduce_120(val, _values, result) +module_eval(<<'.,.,', 'grammar.ra', 386) + def _reduce_121(val, _values, result) result = [ast(AST::String,val[0])] result end .,., -module_eval(<<'.,.,', 'grammar.ra', 445) - def _reduce_121(val, _values, result) +module_eval(<<'.,.,', 'grammar.ra', 387) + def _reduce_122(val, _values, result) result = [ast(AST::String,val[0])] + val[1] result end .,., -module_eval(<<'.,.,', 'grammar.ra', 448) - def _reduce_122(val, _values, result) +module_eval(<<'.,.,', 'grammar.ra', 390) + def _reduce_123(val, _values, result) result = ast AST::Boolean, :value => val[0][:value], :line => val[0][:line] result end .,., -module_eval(<<'.,.,', 'grammar.ra', 452) - def _reduce_123(val, _values, result) +module_eval(<<'.,.,', 'grammar.ra', 394) + def _reduce_124(val, _values, result) Puppet.warning addcontext("Deprecation notice: Resource references should now be capitalized") result = ast AST::ResourceReference, :type => val[0][:value], :line => val[0][:line], :title => val[2] @@ -1888,24 +1819,24 @@ module_eval(<<'.,.,', 'grammar.ra', 452) end .,., -module_eval(<<'.,.,', 'grammar.ra', 455) - def _reduce_124(val, _values, result) +module_eval(<<'.,.,', 'grammar.ra', 397) + def _reduce_125(val, _values, result) result = ast AST::ResourceReference, :type => val[0], :title => val[2] result end .,., -module_eval(<<'.,.,', 'grammar.ra', 459) - def _reduce_125(val, _values, result) +module_eval(<<'.,.,', 'grammar.ra', 401) + def _reduce_126(val, _values, result) result = val[1] result end .,., -module_eval(<<'.,.,', 'grammar.ra', 463) - def _reduce_126(val, _values, result) +module_eval(<<'.,.,', 'grammar.ra', 405) + def _reduce_127(val, _values, result) @lexer.commentpop args = { :test => val[0], @@ -1920,8 +1851,8 @@ module_eval(<<'.,.,', 'grammar.ra', 463) end .,., -module_eval(<<'.,.,', 'grammar.ra', 474) - def _reduce_127(val, _values, result) +module_eval(<<'.,.,', 'grammar.ra', 416) + def _reduce_128(val, _values, result) @lexer.commentpop args = { :test => val[0], @@ -1936,18 +1867,18 @@ module_eval(<<'.,.,', 'grammar.ra', 474) end .,., -# reduce 128 omitted +# reduce 129 omitted -module_eval(<<'.,.,', 'grammar.ra', 487) - def _reduce_129(val, _values, result) +module_eval(<<'.,.,', 'grammar.ra', 429) + def _reduce_130(val, _values, result) result = ast AST::Else, :statements => val[1] result end .,., -module_eval(<<'.,.,', 'grammar.ra', 490) - def _reduce_130(val, _values, result) +module_eval(<<'.,.,', 'grammar.ra', 432) + def _reduce_131(val, _values, result) @lexer.commentpop result = ast AST::Else, :statements => val[2] @@ -1955,8 +1886,8 @@ module_eval(<<'.,.,', 'grammar.ra', 490) end .,., -module_eval(<<'.,.,', 'grammar.ra', 494) - def _reduce_131(val, _values, result) +module_eval(<<'.,.,', 'grammar.ra', 436) + def _reduce_132(val, _values, result) @lexer.commentpop result = ast AST::Else, :statements => ast(AST::Nop) @@ -1964,25 +1895,17 @@ module_eval(<<'.,.,', 'grammar.ra', 494) end .,., -# reduce 132 omitted +# reduce 133 omitted -module_eval(<<'.,.,', 'grammar.ra', 512) - def _reduce_133(val, _values, result) - result = ast AST::InOperator, :lval => val[0], :rval => val[2] - - result - end -.,., - -module_eval(<<'.,.,', 'grammar.ra', 515) +module_eval(<<'.,.,', 'grammar.ra', 454) def _reduce_134(val, _values, result) - result = ast AST::MatchOperator, :operator => val[1][:value], :lval => val[0], :rval => val[2] + result = ast AST::InOperator, :lval => val[0], :rval => val[2] result end .,., -module_eval(<<'.,.,', 'grammar.ra', 518) +module_eval(<<'.,.,', 'grammar.ra', 457) def _reduce_135(val, _values, result) result = ast AST::MatchOperator, :operator => val[1][:value], :lval => val[0], :rval => val[2] @@ -1990,15 +1913,15 @@ module_eval(<<'.,.,', 'grammar.ra', 518) end .,., -module_eval(<<'.,.,', 'grammar.ra', 521) +module_eval(<<'.,.,', 'grammar.ra', 460) def _reduce_136(val, _values, result) - result = ast AST::ArithmeticOperator, :operator => val[1][:value], :lval => val[0], :rval => val[2] + result = ast AST::MatchOperator, :operator => val[1][:value], :lval => val[0], :rval => val[2] result end .,., -module_eval(<<'.,.,', 'grammar.ra', 524) +module_eval(<<'.,.,', 'grammar.ra', 463) def _reduce_137(val, _values, result) result = ast AST::ArithmeticOperator, :operator => val[1][:value], :lval => val[0], :rval => val[2] @@ -2006,7 +1929,7 @@ module_eval(<<'.,.,', 'grammar.ra', 524) end .,., -module_eval(<<'.,.,', 'grammar.ra', 527) +module_eval(<<'.,.,', 'grammar.ra', 466) def _reduce_138(val, _values, result) result = ast AST::ArithmeticOperator, :operator => val[1][:value], :lval => val[0], :rval => val[2] @@ -2014,7 +1937,7 @@ module_eval(<<'.,.,', 'grammar.ra', 527) end .,., -module_eval(<<'.,.,', 'grammar.ra', 530) +module_eval(<<'.,.,', 'grammar.ra', 469) def _reduce_139(val, _values, result) result = ast AST::ArithmeticOperator, :operator => val[1][:value], :lval => val[0], :rval => val[2] @@ -2022,7 +1945,7 @@ module_eval(<<'.,.,', 'grammar.ra', 530) end .,., -module_eval(<<'.,.,', 'grammar.ra', 533) +module_eval(<<'.,.,', 'grammar.ra', 472) def _reduce_140(val, _values, result) result = ast AST::ArithmeticOperator, :operator => val[1][:value], :lval => val[0], :rval => val[2] @@ -2030,7 +1953,7 @@ module_eval(<<'.,.,', 'grammar.ra', 533) end .,., -module_eval(<<'.,.,', 'grammar.ra', 536) +module_eval(<<'.,.,', 'grammar.ra', 475) def _reduce_141(val, _values, result) result = ast AST::ArithmeticOperator, :operator => val[1][:value], :lval => val[0], :rval => val[2] @@ -2038,23 +1961,23 @@ module_eval(<<'.,.,', 'grammar.ra', 536) end .,., -module_eval(<<'.,.,', 'grammar.ra', 539) +module_eval(<<'.,.,', 'grammar.ra', 478) def _reduce_142(val, _values, result) - result = ast AST::Minus, :value => val[1] + result = ast AST::ArithmeticOperator, :operator => val[1][:value], :lval => val[0], :rval => val[2] result end .,., -module_eval(<<'.,.,', 'grammar.ra', 542) +module_eval(<<'.,.,', 'grammar.ra', 481) def _reduce_143(val, _values, result) - result = ast AST::ComparisonOperator, :operator => val[1][:value], :lval => val[0], :rval => val[2] + result = ast AST::Minus, :value => val[1] result end .,., -module_eval(<<'.,.,', 'grammar.ra', 545) +module_eval(<<'.,.,', 'grammar.ra', 484) def _reduce_144(val, _values, result) result = ast AST::ComparisonOperator, :operator => val[1][:value], :lval => val[0], :rval => val[2] @@ -2062,7 +1985,7 @@ module_eval(<<'.,.,', 'grammar.ra', 545) end .,., -module_eval(<<'.,.,', 'grammar.ra', 548) +module_eval(<<'.,.,', 'grammar.ra', 487) def _reduce_145(val, _values, result) result = ast AST::ComparisonOperator, :operator => val[1][:value], :lval => val[0], :rval => val[2] @@ -2070,7 +1993,7 @@ module_eval(<<'.,.,', 'grammar.ra', 548) end .,., -module_eval(<<'.,.,', 'grammar.ra', 551) +module_eval(<<'.,.,', 'grammar.ra', 490) def _reduce_146(val, _values, result) result = ast AST::ComparisonOperator, :operator => val[1][:value], :lval => val[0], :rval => val[2] @@ -2078,7 +2001,7 @@ module_eval(<<'.,.,', 'grammar.ra', 551) end .,., -module_eval(<<'.,.,', 'grammar.ra', 554) +module_eval(<<'.,.,', 'grammar.ra', 493) def _reduce_147(val, _values, result) result = ast AST::ComparisonOperator, :operator => val[1][:value], :lval => val[0], :rval => val[2] @@ -2086,7 +2009,7 @@ module_eval(<<'.,.,', 'grammar.ra', 554) end .,., -module_eval(<<'.,.,', 'grammar.ra', 557) +module_eval(<<'.,.,', 'grammar.ra', 496) def _reduce_148(val, _values, result) result = ast AST::ComparisonOperator, :operator => val[1][:value], :lval => val[0], :rval => val[2] @@ -2094,23 +2017,23 @@ module_eval(<<'.,.,', 'grammar.ra', 557) end .,., -module_eval(<<'.,.,', 'grammar.ra', 560) +module_eval(<<'.,.,', 'grammar.ra', 499) def _reduce_149(val, _values, result) - result = ast AST::Not, :value => val[1] + result = ast AST::ComparisonOperator, :operator => val[1][:value], :lval => val[0], :rval => val[2] result end .,., -module_eval(<<'.,.,', 'grammar.ra', 563) +module_eval(<<'.,.,', 'grammar.ra', 502) def _reduce_150(val, _values, result) - result = ast AST::BooleanOperator, :operator => val[1][:value], :lval => val[0], :rval => val[2] + result = ast AST::Not, :value => val[1] result end .,., -module_eval(<<'.,.,', 'grammar.ra', 566) +module_eval(<<'.,.,', 'grammar.ra', 505) def _reduce_151(val, _values, result) result = ast AST::BooleanOperator, :operator => val[1][:value], :lval => val[0], :rval => val[2] @@ -2118,42 +2041,49 @@ module_eval(<<'.,.,', 'grammar.ra', 566) end .,., -module_eval(<<'.,.,', 'grammar.ra', 569) +module_eval(<<'.,.,', 'grammar.ra', 508) def _reduce_152(val, _values, result) - result = val[1] + result = ast AST::BooleanOperator, :operator => val[1][:value], :lval => val[0], :rval => val[2] result end .,., -module_eval(<<'.,.,', 'grammar.ra', 573) +module_eval(<<'.,.,', 'grammar.ra', 511) def _reduce_153(val, _values, result) - @lexer.commentpop - options = val[3] - options = ast AST::ASTArray, :children => [val[3]] unless options.instance_of?(AST::ASTArray) - result = ast AST::CaseStatement, :test => val[1], :options => options + result = val[1] result end .,., -# reduce 154 omitted +module_eval(<<'.,.,', 'grammar.ra', 515) + def _reduce_154(val, _values, result) + @lexer.commentpop + result = ast AST::CaseStatement, :test => val[1], :options => val[3] -module_eval(<<'.,.,', 'grammar.ra', 581) - def _reduce_155(val, _values, result) - if val[0].instance_of?(AST::ASTArray) - val[0].push val[1] - result = val[0] - else - result = ast AST::ASTArray, :children => [val[0], val[1]] + result end +.,., +module_eval(<<'.,.,', 'grammar.ra', 519) + def _reduce_155(val, _values, result) + result = aryfy(val[0]) result end .,., -module_eval(<<'.,.,', 'grammar.ra', 590) +module_eval(<<'.,.,', 'grammar.ra', 521) def _reduce_156(val, _values, result) + val[0].push val[1] + result = val[0] + + result + end +.,., + +module_eval(<<'.,.,', 'grammar.ra', 526) + def _reduce_157(val, _values, result) @lexer.commentpop result = ast AST::CaseOpt, :value => val[0], :statements => val[3] @@ -2161,8 +2091,8 @@ module_eval(<<'.,.,', 'grammar.ra', 590) end .,., -module_eval(<<'.,.,', 'grammar.ra', 593) - def _reduce_157(val, _values, result) +module_eval(<<'.,.,', 'grammar.ra', 529) + def _reduce_158(val, _values, result) @lexer.commentpop result = ast( @@ -2176,33 +2106,34 @@ module_eval(<<'.,.,', 'grammar.ra', 593) end .,., -# reduce 158 omitted - -module_eval(<<'.,.,', 'grammar.ra', 605) +module_eval(<<'.,.,', 'grammar.ra', 539) def _reduce_159(val, _values, result) - if val[0].instance_of?(AST::ASTArray) - val[0].push(val[2]) - result = val[0] - else - result = ast AST::ASTArray, :children => [val[0],val[2]] + result = aryfy(val[0]) + result end +.,., + +module_eval(<<'.,.,', 'grammar.ra', 541) + def _reduce_160(val, _values, result) + val[0].push(val[2]) + result = val[0] result end .,., -module_eval(<<'.,.,', 'grammar.ra', 614) - def _reduce_160(val, _values, result) +module_eval(<<'.,.,', 'grammar.ra', 546) + def _reduce_161(val, _values, result) result = ast AST::Selector, :param => val[0], :values => val[2] result end .,., -# reduce 161 omitted +# reduce 162 omitted -module_eval(<<'.,.,', 'grammar.ra', 619) - def _reduce_162(val, _values, result) +module_eval(<<'.,.,', 'grammar.ra', 551) + def _reduce_163(val, _values, result) @lexer.commentpop result = val[1] @@ -2210,10 +2141,10 @@ module_eval(<<'.,.,', 'grammar.ra', 619) end .,., -# reduce 163 omitted +# reduce 164 omitted -module_eval(<<'.,.,', 'grammar.ra', 625) - def _reduce_164(val, _values, result) +module_eval(<<'.,.,', 'grammar.ra', 557) + def _reduce_165(val, _values, result) if val[0].instance_of?(AST::ASTArray) val[0].push(val[2]) result = val[0] @@ -2225,16 +2156,14 @@ module_eval(<<'.,.,', 'grammar.ra', 625) end .,., -module_eval(<<'.,.,', 'grammar.ra', 634) - def _reduce_165(val, _values, result) +module_eval(<<'.,.,', 'grammar.ra', 566) + def _reduce_166(val, _values, result) result = ast AST::ResourceParam, :param => val[0], :value => val[2] result end .,., -# reduce 166 omitted - # reduce 167 omitted # reduce 168 omitted @@ -2249,50 +2178,53 @@ module_eval(<<'.,.,', 'grammar.ra', 634) # reduce 173 omitted -module_eval(<<'.,.,', 'grammar.ra', 646) - def _reduce_174(val, _values, result) +# reduce 174 omitted + +module_eval(<<'.,.,', 'grammar.ra', 578) + def _reduce_175(val, _values, result) result = ast AST::Default, :value => val[0][:value], :line => val[0][:line] result end .,., -# reduce 175 omitted +# reduce 176 omitted -module_eval(<<'.,.,', 'grammar.ra', 651) - def _reduce_176(val, _values, result) +module_eval(<<'.,.,', 'grammar.ra', 583) + def _reduce_177(val, _values, result) result = [val[0][:value]] result end .,., -# reduce 177 omitted +# reduce 178 omitted -module_eval(<<'.,.,', 'grammar.ra', 653) - def _reduce_178(val, _values, result) +module_eval(<<'.,.,', 'grammar.ra', 585) + def _reduce_179(val, _values, result) result = val[0] += val[2] result end .,., -module_eval(<<'.,.,', 'grammar.ra', 656) - def _reduce_179(val, _values, result) +module_eval(<<'.,.,', 'grammar.ra', 588) + def _reduce_180(val, _values, result) val[1].each do |file| import(file) end - result = AST::ASTArray.new(:children => []) + result = nil result end .,., -module_eval(<<'.,.,', 'grammar.ra', 666) - def _reduce_180(val, _values, result) +module_eval(<<'.,.,', 'grammar.ra', 598) + def _reduce_181(val, _values, result) @lexer.commentpop - newdefine classname(val[1]), :arguments => val[2], :code => val[4], :line => val[0][:line] + result = Puppet::Parser::AST::Definition.new(classname(val[1]), + ast_context(true).merge(:arguments => val[2], :code => val[4], + :line => val[0][:line])) @lexer.indefine = false - result = nil #} | DEFINE NAME argumentlist parent LBRACE RBRACE { @@ -2300,160 +2232,167 @@ module_eval(<<'.,.,', 'grammar.ra', 666) end .,., -module_eval(<<'.,.,', 'grammar.ra', 673) - def _reduce_181(val, _values, result) +module_eval(<<'.,.,', 'grammar.ra', 606) + def _reduce_182(val, _values, result) @lexer.commentpop - newdefine classname(val[1]), :arguments => val[2], :line => val[0][:line] + result = Puppet::Parser::AST::Definition.new(classname(val[1]), + ast_context(true).merge(:arguments => val[2], :line => val[0][:line])) @lexer.indefine = false - result = nil result end .,., -module_eval(<<'.,.,', 'grammar.ra', 681) - def _reduce_182(val, _values, result) +module_eval(<<'.,.,', 'grammar.ra', 614) + def _reduce_183(val, _values, result) @lexer.commentpop # Our class gets defined in the parent namespace, not our own. @lexer.namepop - newclass classname(val[1]), :arguments => val[2], :parent => val[3], :code => val[5], :line => val[0][:line] - result = nil + result = Puppet::Parser::AST::Hostclass.new(classname(val[1]), + ast_context(true).merge(:arguments => val[2], :parent => val[3], + :code => val[5], :line => val[0][:line])) result end .,., -module_eval(<<'.,.,', 'grammar.ra', 687) - def _reduce_183(val, _values, result) +module_eval(<<'.,.,', 'grammar.ra', 621) + def _reduce_184(val, _values, result) @lexer.commentpop # Our class gets defined in the parent namespace, not our own. @lexer.namepop - newclass classname(val[1]), :arguments => val[2], :parent => val[3], :line => val[0][:line] - result = nil + result = Puppet::Parser::AST::Hostclass.new(classname(val[1]), + ast_context(true).merge(:arguments => val[2], :parent => val[3], + :line => val[0][:line])) result end .,., -module_eval(<<'.,.,', 'grammar.ra', 695) - def _reduce_184(val, _values, result) +module_eval(<<'.,.,', 'grammar.ra', 630) + def _reduce_185(val, _values, result) @lexer.commentpop - newnode val[1], :parent => val[2], :code => val[4], :line => val[0][:line] - result = nil + result = Puppet::Parser::AST::Node.new(val[1], + ast_context(true).merge(:parent => val[2], :code => val[4], + :line => val[0][:line])) result end .,., -module_eval(<<'.,.,', 'grammar.ra', 699) - def _reduce_185(val, _values, result) +module_eval(<<'.,.,', 'grammar.ra', 635) + def _reduce_186(val, _values, result) @lexer.commentpop - newnode val[1], :parent => val[2], :line => val[0][:line] - result = nil + result = Puppet::Parser::AST::Node.new(val[1], ast_context(true).merge(:parent => val[2], :line => val[0][:line])) result end .,., -module_eval(<<'.,.,', 'grammar.ra', 704) - def _reduce_186(val, _values, result) +module_eval(<<'.,.,', 'grammar.ra', 639) + def _reduce_187(val, _values, result) result = val[0][:value] result end .,., -module_eval(<<'.,.,', 'grammar.ra', 706) - def _reduce_187(val, _values, result) +module_eval(<<'.,.,', 'grammar.ra', 641) + def _reduce_188(val, _values, result) result = val[0][:value] result end .,., -module_eval(<<'.,.,', 'grammar.ra', 707) - def _reduce_188(val, _values, result) +module_eval(<<'.,.,', 'grammar.ra', 642) + def _reduce_189(val, _values, result) result = val[0][:value] result end .,., -module_eval(<<'.,.,', 'grammar.ra', 708) - def _reduce_189(val, _values, result) +module_eval(<<'.,.,', 'grammar.ra', 643) + def _reduce_190(val, _values, result) result = "class" result end .,., -# reduce 190 omitted - -module_eval(<<'.,.,', 'grammar.ra', 714) +module_eval(<<'.,.,', 'grammar.ra', 648) def _reduce_191(val, _values, result) - result = val[0] - result = [result] unless result.is_a?(Array) - result << val[2] + result = [result] result end .,., -module_eval(<<'.,.,', 'grammar.ra', 720) +module_eval(<<'.,.,', 'grammar.ra', 651) def _reduce_192(val, _values, result) - result = ast AST::HostName, :value => val[0] + result = val[0] + result << val[2] result end .,., -module_eval(<<'.,.,', 'grammar.ra', 723) +module_eval(<<'.,.,', 'grammar.ra', 656) def _reduce_193(val, _values, result) - result = val[0][:value] + result = ast AST::HostName, :value => val[0] + result end .,., -module_eval(<<'.,.,', 'grammar.ra', 724) +module_eval(<<'.,.,', 'grammar.ra', 659) def _reduce_194(val, _values, result) result = val[0][:value] result end .,., -module_eval(<<'.,.,', 'grammar.ra', 725) +module_eval(<<'.,.,', 'grammar.ra', 660) def _reduce_195(val, _values, result) result = val[0][:value] result end .,., -# reduce 196 omitted +module_eval(<<'.,.,', 'grammar.ra', 661) + def _reduce_196(val, _values, result) + result = val[0][:value] + result + end +.,., + +# reduce 197 omitted -module_eval(<<'.,.,', 'grammar.ra', 729) - def _reduce_197(val, _values, result) +module_eval(<<'.,.,', 'grammar.ra', 665) + def _reduce_198(val, _values, result) result = nil result end .,., -module_eval(<<'.,.,', 'grammar.ra', 733) - def _reduce_198(val, _values, result) +module_eval(<<'.,.,', 'grammar.ra', 669) + def _reduce_199(val, _values, result) result = ast AST::ASTArray, :children => [] result end .,., -# reduce 199 omitted +# reduce 200 omitted -module_eval(<<'.,.,', 'grammar.ra', 738) - def _reduce_200(val, _values, result) +module_eval(<<'.,.,', 'grammar.ra', 674) + def _reduce_201(val, _values, result) result = nil result end .,., -module_eval(<<'.,.,', 'grammar.ra', 741) - def _reduce_201(val, _values, result) +module_eval(<<'.,.,', 'grammar.ra', 677) + def _reduce_202(val, _values, result) result = val[1] result = [result] unless result[0].is_a?(Array) @@ -2461,10 +2400,10 @@ module_eval(<<'.,.,', 'grammar.ra', 741) end .,., -# reduce 202 omitted +# reduce 203 omitted -module_eval(<<'.,.,', 'grammar.ra', 747) - def _reduce_203(val, _values, result) +module_eval(<<'.,.,', 'grammar.ra', 683) + def _reduce_204(val, _values, result) result = val[0] result = [result] unless result[0].is_a?(Array) result << val[2] @@ -2473,8 +2412,8 @@ module_eval(<<'.,.,', 'grammar.ra', 747) end .,., -module_eval(<<'.,.,', 'grammar.ra', 753) - def _reduce_204(val, _values, result) +module_eval(<<'.,.,', 'grammar.ra', 689) + def _reduce_205(val, _values, result) Puppet.warning addcontext("Deprecation notice: must now include '$' in prototype") result = [val[0][:value], val[2]] @@ -2482,8 +2421,8 @@ module_eval(<<'.,.,', 'grammar.ra', 753) end .,., -module_eval(<<'.,.,', 'grammar.ra', 757) - def _reduce_205(val, _values, result) +module_eval(<<'.,.,', 'grammar.ra', 693) + def _reduce_206(val, _values, result) Puppet.warning addcontext("Deprecation notice: must now include '$' in prototype") result = [val[0][:value]] @@ -2491,109 +2430,98 @@ module_eval(<<'.,.,', 'grammar.ra', 757) end .,., -module_eval(<<'.,.,', 'grammar.ra', 760) - def _reduce_206(val, _values, result) +module_eval(<<'.,.,', 'grammar.ra', 696) + def _reduce_207(val, _values, result) result = [val[0][:value], val[2]] result end .,., -module_eval(<<'.,.,', 'grammar.ra', 762) - def _reduce_207(val, _values, result) +module_eval(<<'.,.,', 'grammar.ra', 698) + def _reduce_208(val, _values, result) result = [val[0][:value]] result end .,., -# reduce 208 omitted +# reduce 209 omitted -module_eval(<<'.,.,', 'grammar.ra', 767) - def _reduce_209(val, _values, result) +module_eval(<<'.,.,', 'grammar.ra', 703) + def _reduce_210(val, _values, result) result = val[1] result end .,., -# reduce 210 omitted +# reduce 211 omitted -module_eval(<<'.,.,', 'grammar.ra', 772) - def _reduce_211(val, _values, result) +module_eval(<<'.,.,', 'grammar.ra', 708) + def _reduce_212(val, _values, result) result = val[1] result end .,., -# reduce 212 omitted - # reduce 213 omitted -module_eval(<<'.,.,', 'grammar.ra', 778) - def _reduce_214(val, _values, result) - result = ast AST::Variable, :value => val[0][:value], :line => val[0][:line] +# reduce 214 omitted - result - end -.,., - -module_eval(<<'.,.,', 'grammar.ra', 782) +module_eval(<<'.,.,', 'grammar.ra', 714) def _reduce_215(val, _values, result) - if val[1].instance_of?(AST::ASTArray) - result = val[1] - else - result = ast AST::ASTArray, :children => [val[1]] - end + result = ast AST::Variable, :value => val[0][:value], :line => val[0][:line] result end .,., -module_eval(<<'.,.,', 'grammar.ra', 789) +module_eval(<<'.,.,', 'grammar.ra', 717) def _reduce_216(val, _values, result) - if val[1].instance_of?(AST::ASTArray) - result = val[1] - else - result = ast AST::ASTArray, :children => [val[1]] - end - + result = val[1] result end .,., -module_eval(<<'.,.,', 'grammar.ra', 795) +module_eval(<<'.,.,', 'grammar.ra', 718) def _reduce_217(val, _values, result) - result = ast AST::ASTArray - + result = val[1] result end .,., -# reduce 218 omitted +module_eval(<<'.,.,', 'grammar.ra', 719) + def _reduce_218(val, _values, result) + result = ast AST::ASTArray + result + end +.,., # reduce 219 omitted # reduce 220 omitted -module_eval(<<'.,.,', 'grammar.ra', 802) - def _reduce_221(val, _values, result) +# reduce 221 omitted + +module_eval(<<'.,.,', 'grammar.ra', 725) + def _reduce_222(val, _values, result) result = nil result end .,., -module_eval(<<'.,.,', 'grammar.ra', 805) - def _reduce_222(val, _values, result) +module_eval(<<'.,.,', 'grammar.ra', 728) + def _reduce_223(val, _values, result) result = ast AST::Regex, :value => val[0][:value] result end .,., -module_eval(<<'.,.,', 'grammar.ra', 809) - def _reduce_223(val, _values, result) +module_eval(<<'.,.,', 'grammar.ra', 732) + def _reduce_224(val, _values, result) if val[1].instance_of?(AST::ASTHash) result = val[1] else @@ -2604,8 +2532,8 @@ module_eval(<<'.,.,', 'grammar.ra', 809) end .,., -module_eval(<<'.,.,', 'grammar.ra', 816) - def _reduce_224(val, _values, result) +module_eval(<<'.,.,', 'grammar.ra', 739) + def _reduce_225(val, _values, result) if val[1].instance_of?(AST::ASTHash) result = val[1] else @@ -2616,18 +2544,18 @@ module_eval(<<'.,.,', 'grammar.ra', 816) end .,., -module_eval(<<'.,.,', 'grammar.ra', 822) - def _reduce_225(val, _values, result) +module_eval(<<'.,.,', 'grammar.ra', 745) + def _reduce_226(val, _values, result) result = ast AST::ASTHash result end .,., -# reduce 226 omitted +# reduce 227 omitted -module_eval(<<'.,.,', 'grammar.ra', 827) - def _reduce_227(val, _values, result) +module_eval(<<'.,.,', 'grammar.ra', 750) + def _reduce_228(val, _values, result) if val[0].instance_of?(AST::ASTHash) result = val[0].merge(val[2]) else @@ -2639,40 +2567,40 @@ module_eval(<<'.,.,', 'grammar.ra', 827) end .,., -module_eval(<<'.,.,', 'grammar.ra', 836) - def _reduce_228(val, _values, result) +module_eval(<<'.,.,', 'grammar.ra', 759) + def _reduce_229(val, _values, result) result = ast AST::ASTHash, { :value => { val[0] => val[2] } } result end .,., -module_eval(<<'.,.,', 'grammar.ra', 839) - def _reduce_229(val, _values, result) +module_eval(<<'.,.,', 'grammar.ra', 762) + def _reduce_230(val, _values, result) result = val[0][:value] result end .,., -module_eval(<<'.,.,', 'grammar.ra', 840) - def _reduce_230(val, _values, result) +module_eval(<<'.,.,', 'grammar.ra', 763) + def _reduce_231(val, _values, result) result = val[0] result end .,., -module_eval(<<'.,.,', 'grammar.ra', 843) - def _reduce_231(val, _values, result) +module_eval(<<'.,.,', 'grammar.ra', 766) + def _reduce_232(val, _values, result) result = ast AST::HashOrArrayAccess, :variable => val[0][:value], :key => val[2] result end .,., -# reduce 232 omitted +# reduce 233 omitted -module_eval(<<'.,.,', 'grammar.ra', 848) - def _reduce_233(val, _values, result) +module_eval(<<'.,.,', 'grammar.ra', 771) + def _reduce_234(val, _values, result) result = ast AST::HashOrArrayAccess, :variable => val[0], :key => val[2] result diff --git a/lib/puppet/parser/parser_support.rb b/lib/puppet/parser/parser_support.rb index 9e580efb2..7888fe1dc 100644 --- a/lib/puppet/parser/parser_support.rb +++ b/lib/puppet/parser/parser_support.rb @@ -29,18 +29,9 @@ class Puppet::Parser::Parser message end - # Create an AST array out of all of the args - def aryfy(*args) - if args[0].instance_of?(AST::ASTArray) - result = args.shift - args.each { |arg| - result.push arg - } - else - result = ast AST::ASTArray, :children => args - end - - result + # Create an AST array containing a single element + def aryfy(arg) + ast AST::ASTArray, :children => [arg] end # Create an AST object, and automatically add the file and line information if @@ -68,13 +59,13 @@ class Puppet::Parser::Parser end # Raise a Parse error. - def error(message) + def error(message, options = {}) if brace = @lexer.expected message += "; expected '%s'" end except = Puppet::ParseError.new(message) - except.line = @lexer.line - except.file = @lexer.file if @lexer.file + except.line = options[:line] || @lexer.line + except.file = options[:file] || @lexer.file raise except end @@ -102,11 +93,11 @@ class Puppet::Parser::Parser end def find_hostclass(namespace, name) - known_resource_types.find_or_load(namespace, name, :hostclass) + known_resource_types.find_hostclass(namespace, name) end def find_definition(namespace, name) - known_resource_types.find_or_load(namespace, name, :definition) + known_resource_types.find_definition(namespace, name) end def import(file) @@ -132,26 +123,6 @@ class Puppet::Parser::Parser return ns, n end - # Create a new class, or merge with an existing class. - def newclass(name, options = {}) - known_resource_types.add Puppet::Resource::Type.new(:hostclass, name, ast_context(true, options[:line]).merge(options)) - end - - # Create a new definition. - def newdefine(name, options = {}) - known_resource_types.add Puppet::Resource::Type.new(:definition, name, ast_context(true, options[:line]).merge(options)) - end - - # Create a new node. Nodes are special, because they're stored in a global - # table, not according to namespaces. - def newnode(names, options = {}) - names = [names] unless names.instance_of?(Array) - context = ast_context(true, options[:line]) - names.collect do |name| - known_resource_types.add(Puppet::Resource::Type.new(:node, name, context.merge(options))) - end - end - def on_error(token,value,stack) if token == 0 # denotes end of file value = 'end of file' @@ -173,42 +144,42 @@ class Puppet::Parser::Parser # how should I do error handling here? def parse(string = nil) - return parse_ruby_file if self.file =~ /\.rb$/ - self.string = string if string - begin - @yydebug = false - main = yyparse(@lexer,:scan) - rescue Racc::ParseError => except - error = Puppet::ParseError.new(except) - error.line = @lexer.line - error.file = @lexer.file - error.set_backtrace except.backtrace - raise error - rescue Puppet::ParseError => except - except.line ||= @lexer.line - except.file ||= @lexer.file - raise except - rescue Puppet::Error => except - # and this is a framework error - except.line ||= @lexer.line - except.file ||= @lexer.file - raise except - rescue Puppet::DevError => except - except.line ||= @lexer.line - except.file ||= @lexer.file - raise except - rescue => except - error = Puppet::DevError.new(except.message) - error.line = @lexer.line - error.file = @lexer.file - error.set_backtrace except.backtrace - raise error - end - if main - # Store the results as the top-level class. - newclass("", :code => main) + if self.file =~ /\.rb$/ + main = parse_ruby_file + else + self.string = string if string + begin + @yydebug = false + main = yyparse(@lexer,:scan) + rescue Racc::ParseError => except + error = Puppet::ParseError.new(except) + error.line = @lexer.line + error.file = @lexer.file + error.set_backtrace except.backtrace + raise error + rescue Puppet::ParseError => except + except.line ||= @lexer.line + except.file ||= @lexer.file + raise except + rescue Puppet::Error => except + # and this is a framework error + except.line ||= @lexer.line + except.file ||= @lexer.file + raise except + rescue Puppet::DevError => except + except.line ||= @lexer.line + except.file ||= @lexer.file + raise except + rescue => except + error = Puppet::DevError.new(except.message) + error.line = @lexer.line + error.file = @lexer.file + error.set_backtrace except.backtrace + raise error + end end - return known_resource_types + # Store the results as the top-level class. + return Puppet::Parser::AST::Hostclass.new('', :code => main) ensure @lexer.clear end @@ -216,7 +187,11 @@ class Puppet::Parser::Parser def parse_ruby_file # Execute the contents of the file inside its own "main" object so # that it can call methods in the resource type API. - Puppet::DSL::ResourceTypeAPI.new.instance_eval(File.read(self.file)) + main_object = Puppet::DSL::ResourceTypeAPI.new + main_object.instance_eval(File.read(self.file)) + + # Then extract any types that were created. + Puppet::Parser::AST::ASTArray.new :children => main_object.instance_eval { @__created_ast_objects__ } end def string=(string) diff --git a/lib/puppet/parser/type_loader.rb b/lib/puppet/parser/type_loader.rb index bae560381..1fba73d0b 100644 --- a/lib/puppet/parser/type_loader.rb +++ b/lib/puppet/parser/type_loader.rb @@ -78,16 +78,46 @@ class Puppet::Parser::TypeLoader raise Puppet::ImportError.new("No file(s) found for import of '#{pat}'") end + loaded_asts = [] files.each do |file| unless file =~ /^#{File::SEPARATOR}/ file = File.join(dir, file) end @loading_helper.do_once(file) do - parse_file(file) + loaded_asts << parse_file(file) + end + end + loaded_asts.inject([]) do |loaded_types, ast| + loaded_types + known_resource_types.import_ast(ast, modname) + end + end + + def import_all + require 'find' + + module_names = [] + # Collect the list of all known modules + environment.modulepath.each do |path| + Dir.chdir(path) do + Dir.glob("*").each do |dir| + next unless FileTest.directory?(dir) + module_names << dir + end end end - modname + module_names.uniq! + # And then load all files from each module, but (relying on system + # behavior) only load files from the first module of a given name. E.g., + # given first/foo and second/foo, only files from first/foo will be loaded. + module_names.each do |name| + mod = Puppet::Module.new(name, environment) + Find.find(File.join(mod.path, "manifests")) do |path| + if path =~ /\.pp$/ or path =~ /\.rb$/ + import(path) + end + end + end end def known_resource_types @@ -99,50 +129,45 @@ class Puppet::Parser::TypeLoader @loading_helper = Helper.new end - def load_until(namespaces, name) - return nil if name == "" # special-case main. - name2files(namespaces, name).each do |filename| - modname = begin - import(filename) + # Try to load the object with the given fully qualified name. + def try_load_fqname(type, fqname) + return nil if fqname == "" # special-case main. + name2files(fqname).each do |filename| + begin + imported_types = import(filename) + if result = imported_types.find { |t| t.type == type and t.name == fqname } + Puppet.debug "Automatically imported #{fqname} from #{filename} into #{environment}" + return result + end rescue Puppet::ImportError => detail # We couldn't load the item # I'm not convienced we should just drop these errors, but this # preserves existing behaviours. - nil - end - if result = yield(filename) - Puppet.debug "Automatically imported #{name} from #{filename} into #{environment}" - result.module_name = modname if modname and result.respond_to?(:module_name=) - return result end end - nil - end - - def name2files(namespaces, name) - return [name.sub(/^::/, '').gsub("::", File::SEPARATOR)] if name =~ /^::/ - - result = namespaces.inject([]) do |names_to_try, namespace| - fullname = (namespace + "::#{name}").sub(/^::/, '') - - # Try to load the module init file if we're a qualified name - names_to_try << fullname.split("::")[0] if fullname.include?("::") - - # Then the fully qualified name - names_to_try << fullname - end - - # Otherwise try to load the bare name on its own. This - # is appropriate if the class we're looking for is in a - # module that's different from our namespace. - result << name - result.uniq.collect { |f| f.gsub("::", File::SEPARATOR) } + # Nothing found. + return nil end def parse_file(file) Puppet.debug("importing '#{file}' in environment #{environment}") parser = Puppet::Parser::Parser.new(environment) parser.file = file - parser.parse + return parser.parse + end + + private + + # Return a list of all file basenames that should be tried in order + # to load the object with the given fully qualified name. + def name2files(fqname) + result = [] + ary = fqname.split("::") + while ary.length > 0 + result << ary.join(File::SEPARATOR) + ary.pop + end + return result end + end diff --git a/lib/puppet/provider/aixobject.rb b/lib/puppet/provider/aixobject.rb new file mode 100755 index 000000000..9506c67a2 --- /dev/null +++ b/lib/puppet/provider/aixobject.rb @@ -0,0 +1,393 @@ +# +# Common code for AIX providers. This class implements basic structure for +# AIX resources. +# Author:: Hector Rivas Gandara <keymon@gmail.com> +# +class Puppet::Provider::AixObject < Puppet::Provider + desc "Generic AIX resource provider" + + # The real provider must implement these functions. + def lscmd(value=@resource[:name]) + raise Puppet::Error, "Method not defined #{@resource.class.name} #{@resource.name}: #{detail}" + end + + def lscmd(value=@resource[:name]) + raise Puppet::Error, "Method not defined #{@resource.class.name} #{@resource.name}: #{detail}" + end + + def addcmd(extra_attrs = []) + raise Puppet::Error, "Method not defined #{@resource.class.name} #{@resource.name}: #{detail}" + end + + def modifycmd(attributes_hash) + raise Puppet::Error, "Method not defined #{@resource.class.name} #{@resource.name}: #{detail}" + end + + def deletecmd + raise Puppet::Error, "Method not defined #{@resource.class.name} #{@resource.name}: #{detail}" + end + + # Valid attributes to be managed by this provider. + # It is a list of hashes + # :aix_attr AIX command attribute name + # :puppet_prop Puppet propertie name + # :to Optional. Method name that adapts puppet property to aix command value. + # :from Optional. Method to adapt aix command line value to puppet property. Optional + class << self + attr_accessor :attribute_mapping + end + + # Mapping from Puppet property to AIX attribute. + def self.attribute_mapping_to + if ! @attribute_mapping_to + @attribute_mapping_to = {} + attribute_mapping.each { |elem| + attribute_mapping_to[elem[:puppet_prop]] = { + :key => elem[:aix_attr], + :method => elem[:to] + } + } + end + @attribute_mapping_to + end + + # Mapping from AIX attribute to Puppet property. + def self.attribute_mapping_from + if ! @attribute_mapping_from + @attribute_mapping_from = {} + attribute_mapping.each { |elem| + attribute_mapping_from[elem[:aix_attr]] = { + :key => elem[:puppet_prop], + :method => elem[:from] + } + } + end + @attribute_mapping_from + end + + # This functions translates a key and value using the given mapping. + # Mapping can be nil (no translation) or a hash with this format + # {:key => new_key, :method => translate_method} + # It returns a list with the pair [key, value] + def translate_attr(key, value, mapping) + return [key, value] unless mapping + return nil unless mapping[key] + + if mapping[key][:method] + new_value = method(mapping[key][:method]).call(value) + else + new_value = value + end + [mapping[key][:key], new_value] + end + + # Loads an AIX attribute (key=value) and stores it in the given hash with + # puppet semantics. It translates the pair using the given mapping. + # + # This operation works with each property one by one, + # subclasses must reimplement this if more complex operations are needed + def load_attribute(key, value, mapping, objectinfo) + if mapping.nil? + objectinfo[key] = value + elsif mapping[key].nil? + # is not present in mapping, ignore it. + true + elsif mapping[key][:method].nil? + objectinfo[mapping[key][:key]] = value + elsif + objectinfo[mapping[key][:key]] = method(mapping[key][:method]).call(value) + end + + return objectinfo + end + + # Gets the given command line argument for the given key and value, + # using the given mapping to translate key and value. + # All the objectinfo hash (@resource or @property_hash) is passed. + # + # This operation works with each property one by one, + # and default behaviour is return the arguments as key=value pairs. + # Subclasses must reimplement this if more complex operations/arguments + # are needed + # + def get_arguments(key, value, mapping, objectinfo) + if mapping.nil? + new_key = key + new_value = value + elsif mapping[key].nil? + # is not present in mapping, ignore it. + new_key = nil + new_value = nil + elsif mapping[key][:method].nil? + new_key = mapping[key][:key] + new_value = value + elsif + new_key = mapping[key][:key] + new_value = method(mapping[key][:method]).call(value) + end + + # convert it to string + new_value = Array(new_value).join(',') + + if new_key + return [ "#{new_key}=#{new_value}" ] + else + return [] + end + end + + # Convert the provider properties (hash) to AIX command arguments + # (list of strings) + # This function will translate each value/key and generate the argument using + # the get_arguments function. + def hash2args(hash, mapping=self.class.attribute_mapping_to) + return "" unless hash + arg_list = [] + hash.each {|key, val| + arg_list += self.get_arguments(key, val, mapping, hash) + } + arg_list + end + + # Parse AIX command attributes from the output of an AIX command, that + # which format is a list of space separated of key=value pairs: + # "uid=100 groups=a,b,c". + # It returns an hash. + # + # If a mapping is provided, the keys are translated as defined in the + # mapping hash. And only values included in mapping will be added + # + # NOTE: it will ignore the items not including '=' + def parse_attr_list(str, mapping=self.class.attribute_mapping_from) + properties = {} + attrs = [] + if !str or (attrs = str.split()).empty? + return nil + end + + attrs.each { |i| + if i.include? "=" # Ignore if it does not include '=' + (key_str, val) = i.split('=') + # Check the key + if !key_str or key_str.empty? + info "Empty key in string 'i'?" + continue + end + key = key_str.to_sym + + properties = self.load_attribute(key, val, mapping, properties) + end + } + properties.empty? ? nil : properties + end + + # Parse AIX command output in a colon separated list of attributes, + # This function is useful to parse the output of commands like lsfs -c: + # #MountPoint:Device:Vfs:Nodename:Type:Size:Options:AutoMount:Acct + # /:/dev/hd4:jfs2::bootfs:557056:rw:yes:no + # /home:/dev/hd1:jfs2:::2129920:rw:yes:no + # /usr:/dev/hd2:jfs2::bootfs:9797632:rw:yes:no + # + # If a mapping is provided, the keys are translated as defined in the + # mapping hash. And only values included in mapping will be added + def parse_colon_list(str, key_list, mapping=self.class.attribute_mapping_from) + properties = {} + attrs = [] + if !str or (attrs = str.split(':')).empty? + return nil + end + + attrs.each { |val| + key = key_list.shift.downcase.to_sym + properties = self.load_attribute(key, val, mapping, properties) + } + properties.empty? ? nil : properties + + end + + # Default parsing function for AIX commands. + # It will choose the method depending of the first line. + # For the colon separated list it will: + # 1. Get keys from first line. + # 2. Parse next line. + def parse_command_output(output, mapping=self.class.attribute_mapping_from) + lines = output.split("\n") + # if it begins with #something:... is a colon separated list. + if lines[0] =~ /^#.*:/ + self.parse_colon_list(lines[1], lines[0][1..-1].split(':'), mapping) + else + self.parse_attr_list(lines[0], mapping) + end + end + + # Retrieve all the information of an existing resource. + # It will execute 'lscmd' command and parse the output, using the mapping + # 'attribute_mapping_from' to translate the keys and values. + def getinfo(refresh = false) + if @objectinfo.nil? or refresh == true + # Execute lsuser, split all attributes and add them to a dict. + begin + output = execute(self.lscmd) + @objectinfo = self.parse_command_output(execute(self.lscmd)) + # All attributtes without translation + @objectosinfo = self.parse_command_output(execute(self.lscmd), nil) + rescue Puppet::ExecutionFailure => detail + # Print error if needed. FIXME: Do not check the user here. + Puppet.debug "aix.getinfo(): Could not find #{@resource.class.name} #{@resource.name}: #{detail}" + end + end + @objectinfo + end + + # Like getinfo, but it will not use the mapping to translate the keys and values. + # It might be usefult to retrieve some raw information. + def getosinfo(refresh = false) + if @objectosinfo .nil? or refresh == true + getinfo(refresh) + end + @objectosinfo + end + + + # List all elements of given type. It works for colon separated commands and + # list commands. + # It returns a list of names. + def list_all + names = [] + begin + output = execute(self.lsallcmd()).split('\n') + (output.select{ |l| l != /^#/ }).each { |v| + name = v.split(/[ :]/) + names << name if not name.empty? + } + rescue Puppet::ExecutionFailure => detail + # Print error if needed + Puppet.debug "aix.list_all(): Could not get all resources of type #{@resource.class.name}: #{detail}" + end + names + end + + + #------------- + # Provider API + # ------------ + + # Clear out the cached values. + def flush + @property_hash.clear if @property_hash + @objectinfo.clear if @objectinfo + end + + # Check that the user exists + def exists? + !!getinfo(true) # !! => converts to bool + end + + # Return all existing instances + # The method for returning a list of provider instances. Note that it returns + # providers, preferably with values already filled in, not resources. + def self.instances + objects=[] + self.list_all().each { |entry| + objects << new(:name => entry, :ensure => :present) + } + objects + end + + #- **ensure** + # The basic state that the object should be in. Valid values are + # `present`, `absent`, `role`. + # From ensurable: exists?, create, delete + def ensure + if exists? + :present + else + :absent + end + end + + # Create a new instance of the resource + def create + if exists? + info "already exists" + # The object already exists + return nil + end + + begin + execute(self.addcmd) + rescue Puppet::ExecutionFailure => detail + raise Puppet::Error, "Could not create #{@resource.class.name} #{@resource.name}: #{detail}" + end + end + + # Delete this instance of the resource + def delete + unless exists? + info "already absent" + # the object already doesn't exist + return nil + end + + begin + execute(self.deletecmd) + rescue Puppet::ExecutionFailure => detail + raise Puppet::Error, "Could not delete #{@resource.class.name} #{@resource.name}: #{detail}" + end + end + + #-------------------------------- + # Call this method when the object is initialized. + # It creates getter/setter methods for each property our resource type supports. + # If setter or getter already defined it will not be overwritten + def self.mk_resource_methods + [resource_type.validproperties, resource_type.parameters].flatten.each do |prop| + next if prop == :ensure + define_method(prop) { get(prop) || :absent} unless public_method_defined?(prop) + define_method(prop.to_s + "=") { |*vals| set(prop, *vals) } unless public_method_defined?(prop.to_s + "=") + end + end + + # Define the needed getters and setters as soon as we know the resource type + def self.resource_type=(resource_type) + super + mk_resource_methods + end + + # Retrieve a specific value by name. + def get(param) + (hash = getinfo(false)) ? hash[param] : nil + end + + # Set a property. + def set(param, value) + @property_hash[symbolize(param)] = value + + if getinfo().nil? + # This is weird... + raise Puppet::Error, "Trying to update parameter '#{param}' to '#{value}' for a resource that does not exists #{@resource.class.name} #{@resource.name}: #{detail}" + end + if value == getinfo()[param.to_sym] + return + end + + #self.class.validate(param, value) + if cmd = modifycmd({param =>value}) + begin + execute(cmd) + rescue Puppet::ExecutionFailure => detail + raise Puppet::Error, "Could not set #{param} on #{@resource.class.name}[#{@resource.name}]: #{detail}" + end + end + + # Refresh de info. + hash = getinfo(true) + end + + def initialize(resource) + super + @objectinfo = nil + @objectosinfo = nil + end + +end diff --git a/lib/puppet/provider/augeas/augeas.rb b/lib/puppet/provider/augeas/augeas.rb index 7dbd06240..5488c6674 100644 --- a/lib/puppet/provider/augeas/augeas.rb +++ b/lib/puppet/provider/augeas/augeas.rb @@ -32,10 +32,14 @@ Puppet::Type.type(:augeas).provide(:augeas) do COMMANDS = { "set" => [ :path, :string ], + "setm" => [ :path, :string, :string ], "rm" => [ :path ], "clear" => [ :path ], + "mv" => [ :path, :path ], "insert" => [ :string, :string, :path ], "get" => [ :path, :comparator, :string ], + "defvar" => [ :string, :path ], + "defnode" => [ :string, :path, :string ], "match" => [ :path, :glob ], "size" => [:comparator, :int], "include" => [:string], @@ -46,6 +50,7 @@ Puppet::Type.type(:augeas).provide(:augeas) do COMMANDS["ins"] = COMMANDS["insert"] COMMANDS["remove"] = COMMANDS["rm"] + COMMANDS["move"] = COMMANDS["mv"] attr_accessor :aug @@ -213,7 +218,12 @@ Puppet::Type.type(:augeas).provide(:augeas) do fail("Invalid command: #{cmd_array.join(" ")}") if clause_array.length != 2 comparator = clause_array.shift arg = clause_array.shift - return_value = (result.size.send(comparator, arg)) + case comparator + when "!=" + return_value = !(result.size.send(:==, arg)) + else + return_value = (result.size.send(comparator, arg)) + end when "include" arg = clause_array.shift return_value = result.include?(arg) @@ -329,6 +339,10 @@ Puppet::Type.type(:augeas).provide(:augeas) do debug("sending command '#{command}' with params #{cmd_array.inspect}") rv = aug.set(cmd_array[0], cmd_array[1]) fail("Error sending command '#{command}' with params #{cmd_array.inspect}") if (!rv) + when "setm" + debug("sending command '#{command}' with params #{cmd_array.inspect}") + rv = aug.setm(cmd_array[0], cmd_array[1], cmd_array[2]) + fail("Error sending command '#{command}' with params #{cmd_array.inspect}") if (rv == -1) when "rm", "remove" debug("sending command '#{command}' with params #{cmd_array.inspect}") rv = aug.rm(cmd_array[0]) @@ -349,6 +363,18 @@ Puppet::Type.type(:augeas).provide(:augeas) do debug("sending command '#{command}' with params #{[label, where, path].inspect}") rv = aug.insert(path, label, before) fail("Error sending command '#{command}' with params #{cmd_array.inspect}") if (rv == -1) + when "defvar" + debug("sending command '#{command}' with params #{cmd_array.inspect}") + rv = aug.defvar(cmd_array[0], cmd_array[1]) + fail("Error sending command '#{command}' with params #{cmd_array.inspect}") if (!rv) + when "defnode" + debug("sending command '#{command}' with params #{cmd_array.inspect}") + rv = aug.defnode(cmd_array[0], cmd_array[1], cmd_array[2]) + fail("Error sending command '#{command}' with params #{cmd_array.inspect}") if (!rv) + when "mv", "move" + debug("sending command '#{command}' with params #{cmd_array.inspect}") + rv = aug.mv(cmd_array[0], cmd_array[1]) + fail("Error sending command '#{command}' with params #{cmd_array.inspect}") if (rv == -1) else fail("Command '#{command}' is not supported") end rescue SystemExit,NoMemoryError diff --git a/lib/puppet/provider/file/posix.rb b/lib/puppet/provider/file/posix.rb index f7b8c9797..7b7336b9d 100644 --- a/lib/puppet/provider/file/posix.rb +++ b/lib/puppet/provider/file/posix.rb @@ -54,7 +54,7 @@ Puppet::Type.type(:file).provide :posix do end def retrieve(resource) - unless stat = resource.stat(false) + unless stat = resource.stat return :absent end diff --git a/lib/puppet/provider/file/win32.rb b/lib/puppet/provider/file/win32.rb index 21e7ca974..9423e8f00 100644 --- a/lib/puppet/provider/file/win32.rb +++ b/lib/puppet/provider/file/win32.rb @@ -49,7 +49,7 @@ Puppet::Type.type(:file).provide :microsoft_windows do end def retrieve(resource) - unless stat = resource.stat(false) + unless stat = resource.stat return :absent end diff --git a/lib/puppet/provider/group/aix.rb b/lib/puppet/provider/group/aix.rb new file mode 100755 index 000000000..ecdef6070 --- /dev/null +++ b/lib/puppet/provider/group/aix.rb @@ -0,0 +1,141 @@ +# +# Group Puppet provider for AIX. It uses standard commands to manage groups: +# mkgroup, rmgroup, lsgroup, chgroup +# +# Author:: Hector Rivas Gandara <keymon@gmail.com> +# +require 'puppet/provider/aixobject' + +Puppet::Type.type(:group).provide :aix, :parent => Puppet::Provider::AixObject do + desc "Group management for AIX! Users are managed with mkgroup, rmgroup, lsgroup, chgroup" + + # This will the the default provider for this platform + defaultfor :operatingsystem => :aix + confine :operatingsystem => :aix + + # Provider features + has_features :manages_aix_lam + has_features :manages_members + + # Commands that manage the element + commands :list => "/usr/sbin/lsgroup" + commands :add => "/usr/bin/mkgroup" + commands :delete => "/usr/sbin/rmgroup" + commands :modify => "/usr/bin/chgroup" + + # Group attributes to ignore + def self.attribute_ignore + [] + end + + # AIX attributes to properties mapping. + # + # Valid attributes to be managed by this provider. + # It is a list with of hash + # :aix_attr AIX command attribute name + # :puppet_prop Puppet propertie name + # :to Method to adapt puppet property to aix command value. Optional. + # :from Method to adapt aix command value to puppet property. Optional + self.attribute_mapping = [ + #:name => :name, + {:aix_attr => :id, :puppet_prop => :gid }, + {:aix_attr => :users, :puppet_prop => :members, + :from => :users_from_attr}, + {:aix_attr => :attributes, :puppet_prop => :attributes}, + ] + + #-------------- + # Command definition + + # Return the IA module arguments based on the resource param ia_load_module + def get_ia_module_args + if @resource[:ia_load_module] + ["-R", @resource[:ia_load_module].to_s] + else + [] + end + end + + def lscmd(value=@resource[:name]) + [self.class.command(:list)] + + self.get_ia_module_args + + [ value] + end + + def lsallcmd() + lscmd("ALL") + end + + def addcmd(extra_attrs = []) + # Here we use the @resource.to_hash to get the list of provided parameters + # Puppet does not call to self.<parameter>= method if it does not exists. + # + # It gets an extra list of arguments to add to the user. + [self.class.command(:add) ] + + self.get_ia_module_args + + self.hash2args(@resource.to_hash) + + extra_attrs + [@resource[:name]] + end + + def modifycmd(hash = property_hash) + args = self.hash2args(hash) + return nil if args.empty? + + [self.class.command(:modify)] + + self.get_ia_module_args + + args + [@resource[:name]] + end + + def deletecmd + [self.class.command(:delete)] + + self.get_ia_module_args + + [@resource[:name]] + end + + + #-------------- + # Overwrite get_arguments to add the attributes arguments + def get_arguments(key, value, mapping, objectinfo) + # In the case of attributes, return a list of key=vlaue + if key == :attributes + raise Puppet::Error, "Attributes must be a list of pairs key=value on #{@resource.class.name}[#{@resource.name}]" \ + unless value and value.is_a? Hash + return value.select { |k,v| true }.map { |pair| pair.join("=") } + end + super(key, value, mapping, objectinfo) + end + + def filter_attributes(hash) + # Return only not managed attributtes. + hash.select { + |k,v| !self.class.attribute_mapping_from.include?(k) and + !self.class.attribute_ignore.include?(k) + }.inject({}) { + |hash, array| hash[array[0]] = array[1]; hash + } + end + + def attributes + filter_attributes(getosinfo(refresh = false)) + end + + def attributes=(attr_hash) + #self.class.validate(param, value) + param = :attributes + cmd = modifycmd({param => filter_attributes(attr_hash)}) + if cmd + begin + execute(cmd) + rescue Puppet::ExecutionFailure => detail + raise Puppet::Error, "Could not set #{param} on #{@resource.class.name}[#{@resource.name}]: #{detail}" + end + end + end + + # Force convert users it a list. + def users_from_attr(value) + (value.is_a? String) ? value.split(',') : value + end + + +end diff --git a/lib/puppet/provider/host/parsed.rb b/lib/puppet/provider/host/parsed.rb index 4f15eff3f..2ba01a41c 100644 --- a/lib/puppet/provider/host/parsed.rb +++ b/lib/puppet/provider/host/parsed.rb @@ -8,66 +8,34 @@ else end - Puppet::Type.type(:host).provide( - :parsed, - :parent => Puppet::Provider::ParsedFile, - :default_target => hosts, - - :filetype => :flat -) do +Puppet::Type.type(:host).provide(:parsed,:parent => Puppet::Provider::ParsedFile, + :default_target => hosts,:filetype => :flat) do confine :exists => hosts text_line :comment, :match => /^#/ text_line :blank, :match => /^\s*$/ - record_line :parsed, :fields => %w{ip name host_aliases}, - :optional => %w{host_aliases}, - :rts => true do |line| - hash = {} - if line.sub!(/^(\S+)\s+(\S+)\s*/, '') - hash[:ip] = $1 - hash[:name] = $2 - - if line.empty? - hash[:host_aliases] = [] - else - line.sub!(/\s*/, '') - line.sub!(/^([^#]+)\s*/) do |value| - aliases = $1 - unless aliases =~ /^\s*$/ - hash[:host_aliases] = aliases.split(/\s+/) - end - - "" - end + record_line :parsed, :fields => %w{ip name host_aliases comment}, + :optional => %w{host_aliases comment}, + :match => /^(\S+)\s+(\S+)\s*(.*?)?(?:\s*#\s*(.*))?$/, + :post_parse => proc { |hash| + # An absent comment should match "comment => ''" + hash[:comment] = '' if hash[:comment].nil? or hash[:comment] == :absent + unless hash[:host_aliases].nil? or hash[:host_aliases] == :absent + hash[:host_aliases].gsub!(/\s+/,' ') # Change delimiter end - else - raise Puppet::Error, "Could not match '#{line}'" - end - - hash[:host_aliases] = [] if hash[:host_aliases] == "" - - return hash - end - - # Convert the current object into a host-style string. - def self.to_line(hash) - return super unless hash[:record_type] == :parsed - [:ip, :name].each do |n| - raise ArgumentError, "#{n} is a required attribute for hosts" unless hash[n] and hash[n] != :absent - end - - str = "#{hash[:ip]}\t#{hash[:name]}" - - if hash.include? :host_aliases and !hash[:host_aliases].empty? - if hash[:host_aliases].is_a? Array - str += "\t#{hash[:host_aliases].join("\t")}" - else - raise ArgumentError, "Host aliases must be specified as an array" + }, + :to_line => proc { |hash| + [:ip, :name].each do |n| + raise ArgumentError, "#{n} is a required attribute for hosts" unless hash[n] and hash[n] != :absent end - end - - str - end + str = "#{hash[:ip]}\t#{hash[:name]}" + if hash.include? :host_aliases and !hash[:host_aliases].nil? and hash[:host_aliases] != :absent + str += "\t#{hash[:host_aliases]}" + end + if hash.include? :comment and !hash[:comment].empty? + str += "\t# #{hash[:comment]}" + end + str + } end - diff --git a/lib/puppet/provider/mcx/mcxcontent.rb b/lib/puppet/provider/mcx/mcxcontent.rb index cb5adc698..3ad437b53 100644 --- a/lib/puppet/provider/mcx/mcxcontent.rb +++ b/lib/puppet/provider/mcx/mcxcontent.rb @@ -53,39 +53,31 @@ Puppet::Type.type(:mcx).provide :mcxcontent, :parent => Puppet::Provider do confine :operatingsystem => :darwin defaultfor :operatingsystem => :darwin - # self.instances is all important. - # This is the only class method, it returns - # an array of instances of this class. def self.instances mcx_list = [] - for ds_type in TypeMap.keys + TypeMap.keys.each do |ds_type| ds_path = "/Local/Default/#{TypeMap[ds_type]}" output = dscl 'localhost', '-list', ds_path member_list = output.split - for ds_name in member_list + member_list.each do |ds_name| content = mcxexport(ds_type, ds_name) if content.empty? Puppet.debug "/#{TypeMap[ds_type]}/#{ds_name} has no MCX data." else # This node has MCX data. - rsrc = self.new( - :name => "/#{TypeMap[ds_type]}/#{ds_name}", - :ds_type => ds_type, - :ds_name => ds_name, - - :content => content) - mcx_list << rsrc + mcx_list << self.new( + :name => "/#{TypeMap[ds_type]}/#{ds_name}", + :ds_type => ds_type, + :ds_name => ds_name, + :content => content + ) end end end mcx_list end - private - - # mcxexport is used by instances, and therefore - # a class method. def self.mcxexport(ds_type, ds_name) ds_t = TypeMap[ds_type] ds_n = ds_name.to_s @@ -93,9 +85,49 @@ Puppet::Type.type(:mcx).provide :mcxcontent, :parent => Puppet::Provider do dscl 'localhost', '-mcxexport', ds_path end + + def create + self.content=(resource[:content]) + end + + def destroy + ds_parms = get_dsparams + ds_t = TypeMap[ds_parms[:ds_type]] + ds_n = ds_parms[:ds_name].to_s + ds_path = "/Local/Default/#{ds_t}/#{ds_n}" + + dscl 'localhost', '-mcxdelete', ds_path + end + + def exists? + begin + has_mcx? + rescue Puppet::ExecutionFailure => e + return false + end + end + + def content + ds_parms = get_dsparams + + self.class.mcxexport(ds_parms[:ds_type], ds_parms[:ds_name]) + end + + def content=(value) + # dscl localhost -mcximport + ds_parms = get_dsparams + + mcximport(ds_parms[:ds_type], ds_parms[:ds_name], resource[:content]) + end + + private + + def has_mcx? + !content.empty? + end + def mcximport(ds_type, ds_name, val) ds_t = TypeMap[ds_type] - ds_n = ds_name.to_s ds_path = "/Local/Default/#{ds_t}/#{ds_name}" tmp = Tempfile.new('puppet_mcx') @@ -111,33 +143,31 @@ Puppet::Type.type(:mcx).provide :mcxcontent, :parent => Puppet::Provider do # Given the resource name string, parse ds_type out. def parse_type(name) - tmp = name.split('/')[1] - if ! tmp.is_a? String + ds_type = name.split('/')[1] + unless ds_type raise MCXContentProviderException, "Coult not parse ds_type from resource name '#{name}'. Specify with ds_type parameter." end # De-pluralize and downcase. - tmp = tmp.chop.downcase.to_sym - if not TypeMap.keys.member? tmp + ds_type = ds_type.chop.downcase.to_sym + unless TypeMap.key? ds_type raise MCXContentProviderException, "Coult not parse ds_type from resource name '#{name}'. Specify with ds_type parameter." end - tmp + ds_type end # Given the resource name string, parse ds_name out. def parse_name(name) ds_name = name.split('/')[2] - if ! ds_name.is_a? String + unless ds_name raise MCXContentProviderException, "Could not parse ds_name from resource name '#{name}'. Specify with ds_name parameter." end ds_name end - # Gather ds_type and ds_name from resource or - # parse it out of the name. - # This is a private instance method, not a class method. + # Gather ds_type and ds_name from resource or parse it out of the name. def get_dsparams ds_type = resource[:ds_type] ds_type ||= parse_type(resource[:name]) @@ -146,60 +176,10 @@ Puppet::Type.type(:mcx).provide :mcxcontent, :parent => Puppet::Provider do ds_name = resource[:ds_name] ds_name ||= parse_name(resource[:name]) - rval = { + { :ds_type => ds_type.to_sym, :ds_name => ds_name, } - - return rval - - end - - public - - def create - self.content=(resource[:content]) - end - - def destroy - ds_parms = get_dsparams - ds_t = TypeMap[ds_parms[:ds_type]] - ds_n = ds_parms[:ds_name].to_s - ds_path = "/Local/Default/#{ds_t}/#{ds_n}" - - dscl 'localhost', '-mcxdelete', ds_path - end - - def exists? - # JJM Just re-use the content method and see if it's empty. - begin - mcx = content - rescue Puppet::ExecutionFailure => e - return false - end - has_mcx = ! mcx.empty? - end - - def content - ds_parms = get_dsparams - - mcx = self.class.mcxexport( - ds_parms[:ds_type], - - ds_parms[:ds_name]) - mcx - end - - def content=(value) - # dscl localhost -mcximport - ds_parms = get_dsparams - - mcx = mcximport( - ds_parms[:ds_type], - ds_parms[:ds_name], - - resource[:content]) - mcx end end diff --git a/lib/puppet/provider/nameservice/directoryservice.rb b/lib/puppet/provider/nameservice/directoryservice.rb index b01880360..2e3480985 100644 --- a/lib/puppet/provider/nameservice/directoryservice.rb +++ b/lib/puppet/provider/nameservice/directoryservice.rb @@ -321,6 +321,31 @@ class DirectoryService < Puppet::Provider::NameService password_hash end + # Unlike most other *nixes, OS X doesn't provide built in functionality + # for automatically assigning uids and gids to accounts, so we set up these + # methods for consumption by functionality like --mkusers + # By default we restrict to a reasonably sane range for system accounts + def self.next_system_id(id_type, min_id=20) + dscl_args = ['.', '-list'] + if id_type == 'uid' + dscl_args << '/Users' << 'uid' + elsif id_type == 'gid' + dscl_args << '/Groups' << 'gid' + else + fail("Invalid id_type #{id_type}. Only 'uid' and 'gid' supported") + end + dscl_out = dscl(dscl_args) + # We're ok with throwing away negative uids here. + ids = dscl_out.split.compact.collect { |l| l.to_i if l.match(/^\d+$/) } + ids.compact!.sort! { |a,b| a.to_f <=> b.to_f } + # We're just looking for an unused id in our sorted array. + ids.each_index do |i| + next_id = ids[i] + 1 + return next_id if ids[i+1] != next_id and next_id >= min_id + end + end + + def ensure=(ensure_value) super # We need to loop over all valid properties for the type we're @@ -422,7 +447,14 @@ class DirectoryService < Puppet::Provider::NameService # Now we create all the standard properties Puppet::Type.type(@resource.class.name).validproperties.each do |property| next if property == :ensure - if value = @resource.should(property) and value != "" + value = @resource.should(property) + if property == :gid and value.nil? + value = self.class.next_system_id(id_type='gid') + end + if property == :uid and value.nil? + value = self.class.next_system_id(id_type='uid') + end + if value != "" and not value.nil? if property == :members add_members(nil, value) else diff --git a/lib/puppet/provider/package/pip.rb b/lib/puppet/provider/package/pip.rb new file mode 100644 index 000000000..5abbc135a --- /dev/null +++ b/lib/puppet/provider/package/pip.rb @@ -0,0 +1,109 @@ +# Puppet package provider for Python's `pip` package management frontend. +# <http://pip.openplans.org/> + +require 'puppet/provider/package' +require 'xmlrpc/client' + +Puppet::Type.type(:package).provide :pip, + :parent => ::Puppet::Provider::Package do + + desc "Python packages via `pip`." + + has_feature :installable, :uninstallable, :upgradeable, :versionable + + # Parse lines of output from `pip freeze`, which are structured as + # _package_==_version_. + def self.parse(line) + if line.chomp =~ /^([^=]+)==([^=]+)$/ + {:ensure => $2, :name => $1, :provider => name} + else + nil + end + end + + # Return an array of structured information about every installed package + # that's managed by `pip` or an empty array if `pip` is not available. + def self.instances + packages = [] + pip_cmd = which('pip') or return [] + execpipe "#{pip_cmd} freeze" do |process| + process.collect do |line| + next unless options = parse(line) + packages << new(options) + end + end + packages + end + + # Return structured information about a particular package or `nil` if + # it is not installed or `pip` itself is not available. + def query + self.class.instances.each do |provider_pip| + return provider_pip.properties if @resource[:name] == provider_pip.name + end + return nil + end + + # Ask the PyPI API for the latest version number. There is no local + # cache of PyPI's package list so this operation will always have to + # ask the web service. + def latest + client = XMLRPC::Client.new2("http://pypi.python.org/pypi") + client.http_header_extra = {"Content-Type" => "text/xml"} + result = client.call("package_releases", @resource[:name]) + result.first + end + + # Install a package. The ensure parameter may specify installed, + # latest, a version number, or, in conjunction with the source + # parameter, an SCM revision. In that case, the source parameter + # gives the fully-qualified URL to the repository. + def install + args = %w{install -q} + if @resource[:source] + args << "-e" + if String === @resource[:ensure] + args << "#{@resource[:source]}@#{@resource[:ensure]}#egg=#{ + @resource[:name]}" + else + args << "#{@resource[:source]}#egg=#{@resource[:name]}" + end + else + case @resource[:ensure] + when String + args << "#{@resource[:name]}==#{@resource[:ensure]}" + when :latest + args << "--upgrade" << @resource[:name] + else + args << @resource[:name] + end + end + lazy_pip *args + end + + # Uninstall a package. Uninstall won't work reliably on Debian/Ubuntu + # unless this issue gets fixed. + # <http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=562544> + def uninstall + lazy_pip "uninstall", "-y", "-q", @resource[:name] + end + + def update + install + end + + # Execute a `pip` command. If Puppet doesn't yet know how to do so, + # try to teach it and if even that fails, raise the error. + private + def lazy_pip(*args) + pip *args + rescue NoMethodError => e + if pathname = which('pip') + self.class.commands :pip => pathname + pip *args + else + raise e + end + end + +end diff --git a/lib/puppet/provider/package/yum.rb b/lib/puppet/provider/package/yum.rb index fcda5ba8c..6ed966fbd 100755 --- a/lib/puppet/provider/package/yum.rb +++ b/lib/puppet/provider/package/yum.rb @@ -1,3 +1,4 @@ +require 'puppet/util/package' Puppet::Type.type(:package).provide :yum, :parent => :rpm, :source => :rpm do desc "Support via `yum`." @@ -52,6 +53,7 @@ Puppet::Type.type(:package).provide :yum, :parent => :rpm, :source => :rpm do should = @resource.should(:ensure) self.debug "Ensuring => #{should}" wanted = @resource[:name] + operation = :install # XXX: We don't actually deal with epochs here. case should @@ -61,9 +63,14 @@ Puppet::Type.type(:package).provide :yum, :parent => :rpm, :source => :rpm do else # Add the package version wanted += "-#{should}" + is = self.query + if is && Puppet::Util::Package.versioncmp(should, is[:ensure]) < 0 + self.debug "Downgrading package #{@resource[:name]} from version #{is[:ensure]} to #{should}" + operation = :downgrade + end end - output = yum "-d", "0", "-e", "0", "-y", :install, wanted + output = yum "-d", "0", "-e", "0", "-y", operation, wanted is = self.query raise Puppet::Error, "Could not find package #{self.name}" unless is diff --git a/lib/puppet/provider/service/daemontools.rb b/lib/puppet/provider/service/daemontools.rb index bbb962a71..f5a073329 100644 --- a/lib/puppet/provider/service/daemontools.rb +++ b/lib/puppet/provider/service/daemontools.rb @@ -67,7 +67,7 @@ Puppet::Type.type(:service).provide :daemontools, :parent => :base do path = self.defpath unless FileTest.directory?(path) Puppet.notice "Service path #{path} does not exist" - next + return end # reject entries that aren't either a directory diff --git a/lib/puppet/provider/service/launchd.rb b/lib/puppet/provider/service/launchd.rb index 07c549a8b..9d813bd5a 100644 --- a/lib/puppet/provider/service/launchd.rb +++ b/lib/puppet/provider/service/launchd.rb @@ -211,7 +211,7 @@ Puppet::Type.type(:service).provide :launchd, :parent => :base do job_path, job_plist = plist_from_label(resource[:name]) job_plist_disabled = job_plist["Disabled"] if job_plist.has_key?("Disabled") - if self.class.get_macosx_version_major == "10.6": + if self.class.get_macosx_version_major == "10.6" if FileTest.file?(Launchd_Overrides) and overrides = self.class.read_plist(Launchd_Overrides) if overrides.has_key?(resource[:name]) overrides_disabled = overrides[resource[:name]]["Disabled"] if overrides[resource[:name]].has_key?("Disabled") diff --git a/lib/puppet/provider/service/smf.rb b/lib/puppet/provider/service/smf.rb index 3efb2eb37..f6f221a7c 100755 --- a/lib/puppet/provider/service/smf.rb +++ b/lib/puppet/provider/service/smf.rb @@ -27,7 +27,7 @@ Puppet::Type.type(:service).provide :smf, :parent => :base do end end rescue Puppet::ExecutionFailure => detail - raise Puppet::Error.new( "Cannot config #{self.service} to enable it: #{detail}" ) + raise Puppet::Error.new( "Cannot config #{self.name} to enable it: #{detail}" ) end def enable @@ -54,10 +54,10 @@ Puppet::Type.type(:service).provide :smf, :parent => :base do def startcmd self.setupservice case self.status - when :stopped - [command(:adm), :enable, @resource[:name]] when :maintenance [command(:adm), :clear, @resource[:name]] + else + [command(:adm), :enable, @resource[:name]] end end diff --git a/lib/puppet/provider/service/upstart.rb b/lib/puppet/provider/service/upstart.rb new file mode 100755 index 000000000..54971eeac --- /dev/null +++ b/lib/puppet/provider/service/upstart.rb @@ -0,0 +1,73 @@ +Puppet::Type.type(:service).provide :upstart, :parent => :init do + desc "Ubuntu service manager upstart. + + This provider manages upstart jobs which have replaced initd. + + See: + * http://upstart.ubuntu.com/ + " + # confine to :ubuntu for now because I haven't tested on other platforms + confine :operatingsystem => :ubuntu #[:ubuntu, :fedora, :debian] + + commands :start => "/sbin/start", + :stop => "/sbin/stop", + :restart => "/sbin/restart", + :status_exec => "/sbin/status", + :initctl => "/sbin/initctl" + + # upstart developer haven't implemented initctl enable/disable yet: + # http://www.linuxplanet.com/linuxplanet/tutorials/7033/2/ + # has_feature :enableable + + def self.instances + instances = [] + execpipe("#{command(:initctl)} list") { |process| + process.each { |line| + # needs special handling of services such as network-interface: + # initctl list: + # network-interface (lo) start/running + # network-interface (eth0) start/running + # network-interface-security start/running + name = \ + if matcher = line.match(/^(network-interface)\s\(([^\)]+)\)/) + "#{matcher[1]} INTERFACE=#{matcher[2]}" + else + line.split.first + end + instances << new(:name => name) + } + } + instances + end + + def startcmd + [command(:start), @resource[:name]] + end + + def stopcmd + [command(:stop), @resource[:name]] + end + + def restartcmd + (@resource[:hasrestart] == :true) && [command(:restart), @resource[:name]] + end + + def status + # allows user override of status command + if @resource[:status] + ucommand(:status, false) + if $?.exitstatus == 0 + return :running + else + return :stopped + end + else + output = status_exec(@resource[:name].split) + if (! $?.nil?) && (output =~ /start\//) + return :running + else + return :stopped + end + end + end +end diff --git a/lib/puppet/provider/user/aix.rb b/lib/puppet/provider/user/aix.rb new file mode 100755 index 000000000..032d2b536 --- /dev/null +++ b/lib/puppet/provider/user/aix.rb @@ -0,0 +1,353 @@ +# +# User Puppet provider for AIX. It uses standard commands to manage users: +# mkuser, rmuser, lsuser, chuser +# +# Notes: +# - AIX users can have expiry date defined with minute granularity, +# but puppet does not allow it. There is a ticket open for that (#5431) +# - AIX maximum password age is in WEEKs, not days +# +# See http://projects.puppetlabs.com/projects/puppet/wiki/Development_Provider_Development +# for more information +# +# Author:: Hector Rivas Gandara <keymon@gmail.com> +# +require 'puppet/provider/aixobject' +require 'tempfile' +require 'date' + +Puppet::Type.type(:user).provide :aix, :parent => Puppet::Provider::AixObject do + desc "User management for AIX! Users are managed with mkuser, rmuser, chuser, lsuser" + + # This will the the default provider for this platform + defaultfor :operatingsystem => :aix + confine :operatingsystem => :aix + + # Commands that manage the element + commands :list => "/usr/sbin/lsuser" + commands :add => "/usr/bin/mkuser" + commands :delete => "/usr/sbin/rmuser" + commands :modify => "/usr/bin/chuser" + + commands :lsgroup => "/usr/sbin/lsgroup" + commands :chpasswd => "/bin/chpasswd" + + # Provider features + has_features :manages_aix_lam + has_features :manages_homedir, :manages_passwords + has_features :manages_expiry, :manages_password_age + + # Attribute verification (TODO) + #verify :gid, "GID must be an string or int of a valid group" do |value| + # value.is_a? String || value.is_a? Integer + #end + # + #verify :groups, "Groups must be comma-separated" do |value| + # value !~ /\s/ + #end + + # User attributes to ignore from AIX output. + def self.attribute_ignore + [] + end + + # AIX attributes to properties mapping. + # + # Valid attributes to be managed by this provider. + # It is a list with of hash + # :aix_attr AIX command attribute name + # :puppet_prop Puppet propertie name + # :to Method to adapt puppet property to aix command value. Optional. + # :from Method to adapt aix command value to puppet property. Optional + self.attribute_mapping = [ + #:name => :name, + {:aix_attr => :pgrp, :puppet_prop => :gid, + :to => :gid_to_attr, :from => :gid_from_attr}, + {:aix_attr => :id, :puppet_prop => :uid}, + {:aix_attr => :groups, :puppet_prop => :groups}, + {:aix_attr => :home, :puppet_prop => :home}, + {:aix_attr => :shell, :puppet_prop => :shell}, + {:aix_attr => :expires, :puppet_prop => :expiry, + :to => :expiry_to_attr, :from => :expiry_from_attr}, + {:aix_attr => :maxage, :puppet_prop => :password_max_age}, + {:aix_attr => :minage, :puppet_prop => :password_min_age}, + {:aix_attr => :attributes, :puppet_prop => :attributes}, + ] + + #-------------- + # Command definition + + # Return the IA module arguments based on the resource param ia_load_module + def get_ia_module_args + if @resource[:ia_load_module] + ["-R", @resource[:ia_load_module].to_s] + else + [] + end + end + + # List groups and Ids + def lsgroupscmd(value=@resource[:name]) + [command(:lsgroup)] + + self.get_ia_module_args + + ["-a", "id", value] + end + + def lscmd(value=@resource[:name]) + [self.class.command(:list)] + self.get_ia_module_args + [ value] + end + + def lsallcmd() + lscmd("ALL") + end + + def addcmd(extra_attrs = []) + # Here we use the @resource.to_hash to get the list of provided parameters + # Puppet does not call to self.<parameter>= method if it does not exists. + # + # It gets an extra list of arguments to add to the user. + [self.class.command(:add)] + self.get_ia_module_args + + self.hash2args(@resource.to_hash) + + extra_attrs + [@resource[:name]] + end + + # Get modify command. Set translate=false if no mapping must be used. + # Needed for special properties like "attributes" + def modifycmd(hash = property_hash) + args = self.hash2args(hash) + return nil if args.empty? + + [self.class.command(:modify)] + self.get_ia_module_args + + args + [@resource[:name]] + end + + def deletecmd + [self.class.command(:delete)] + self.get_ia_module_args + [@resource[:name]] + end + + #-------------- + # We overwrite the create function to change the password after creation. + def create + super + # Reset the password if needed + self.password = @resource[:password] if @resource[:password] + end + + + def get_arguments(key, value, mapping, objectinfo) + # In the case of attributes, return a list of key=vlaue + if key == :attributes + raise Puppet::Error, "Attributes must be a list of pairs key=value on #{@resource.class.name}[#{@resource.name}]" \ + unless value and value.is_a? Hash + return value.select { |k,v| true }.map { |pair| pair.join("=") } + end + + super(key, value, mapping, objectinfo) + end + + # Get the groupname from its id + def self.groupname_by_id(gid) + groupname=nil + execute(lsgroupscmd("ALL")).each { |entry| + attrs = self.parse_attr_list(entry, nil) + if attrs and attrs.include? :id and gid == attrs[:id].to_i + groupname = entry.split(" ")[0] + end + } + groupname + end + + # Get the groupname from its id + def groupid_by_name(groupname) + attrs = self.parse_attr_list(execute(lsgroupscmd(groupname)).split("\n")[0], nil) + attrs ? attrs[:id].to_i : nil + end + + # Check that a group exists and is valid + def verify_group(value) + if value.is_a? Integer or value.is_a? Fixnum + groupname = self.groupname_by_id(value) + raise ArgumentError, "AIX group must be a valid existing group" unless groupname + else + raise ArgumentError, "AIX group must be a valid existing group" unless groupid_by_name(value) + groupname = value + end + groupname + end + + # The user's primary group. Can be specified numerically or by name. + def gid_to_attr(value) + verify_group(value) + end + + # Get the group gid from its name + def gid_from_attr(value) + groupid_by_name(value) + end + + # The expiry date for this user. Must be provided in + # a zero padded YYYY-MM-DD HH:MM format + def expiry_to_attr(value) + # For chuser the expires parameter is a 10-character string in the MMDDhhmmyy format + # that is,"%m%d%H%M%y" + newdate = '0' + if value.is_a? String and value!="0000-00-00" + d = DateTime.parse(value, "%Y-%m-%d %H:%M") + newdate = d.strftime("%m%d%H%M%y") + end + newdate + end + + def expiry_from_attr(value) + if value =~ /(..)(..)(..)(..)(..)/ + #d= DateTime.parse("20#{$5}-#{$1}-#{$2} #{$3}:#{$4}") + #expiry_date = d.strftime("%Y-%m-%d %H:%M") + #expiry_date = d.strftime("%Y-%m-%d") + expiry_date = "20#{$5}-#{$1}-#{$2}" + else + Puppet.warn("Could not convert AIX expires date '#{value}' on #{@resource.class.name}[#{@resource.name}]") \ + unless value == '0' + expiry_date = :absent + end + expiry_date + end + + #-------------------------------- + # Getter and Setter + # When the provider is initialized, create getter/setter methods for each + # property our resource type supports. + # If setter or getter already defined it will not be overwritten + + #- **password** + # The user's password, in whatever encrypted format the local machine + # requires. Be sure to enclose any value that includes a dollar sign ($) + # in single quotes ('). Requires features manages_passwords. + # + # Retrieve the password parsing directly the /etc/security/passwd + def password + password = :absent + user = @resource[:name] + f = File.open("/etc/security/passwd", 'r') + # Skip to the user + f.each { |l| break if l =~ /^#{user}:\s*$/ } + if ! f.eof? + f.each { |l| + # If there is a new user stanza, stop + break if l =~ /^\S*:\s*$/ + # If the password= entry is found, return it + if l =~ /^\s*password\s*=\s*(.*)$/ + password = $1; break; + end + } + end + f.close() + return password + end + + def password=(value) + user = @resource[:name] + + # Puppet execute does not support strings as input, only files. + tmpfile = Tempfile.new('puppet_#{user}_pw') + tmpfile << "#{user}:#{value}\n" + tmpfile.close() + + # Options '-e', '-c', use encrypted password and clear flags + # Must receibe "user:enc_password" as input + # command, arguments = {:failonfail => true, :combine => true} + cmd = [self.class.command(:chpasswd),"-R", self.class.ia_module, + '-e', '-c', user] + begin + execute(cmd, {:failonfail => true, :combine => true, :stdinfile => tmpfile.path }) + rescue Puppet::ExecutionFailure => detail + raise Puppet::Error, "Could not set #{param} on #{@resource.class.name}[#{@resource.name}]: #{detail}" + ensure + tmpfile.delete() + end + end + + def filter_attributes(hash) + # Return only not managed attributtes. + hash.select { + |k,v| !self.class.attribute_mapping_from.include?(k) and + !self.class.attribute_ignore.include?(k) + }.inject({}) { + |hash, array| hash[array[0]] = array[1]; hash + } + end + + def attributes + filter_attributes(getosinfo(refresh = false)) + end + + def attributes=(attr_hash) + #self.class.validate(param, value) + param = :attributes + cmd = modifycmd({param => filter_attributes(attr_hash)}) + if cmd + begin + execute(cmd) + rescue Puppet::ExecutionFailure => detail + raise Puppet::Error, "Could not set #{param} on #{@resource.class.name}[#{@resource.name}]: #{detail}" + end + end + end + + #- **comment** + # A description of the user. Generally is a user's full name. + #def comment=(value) + #end + # + #def comment + #end + # UNSUPPORTED + #- **profile_membership** + # Whether specified roles should be treated as the only roles + # of which the user is a member or whether they should merely + # be treated as the minimum membership list. Valid values are + # `inclusive`, `minimum`. + # UNSUPPORTED + #- **profiles** + # The profiles the user has. Multiple profiles should be + # specified as an array. Requires features manages_solaris_rbac. + # UNSUPPORTED + #- **project** + # The name of the project associated with a user Requires features + # manages_solaris_rbac. + # UNSUPPORTED + #- **role_membership** + # Whether specified roles should be treated as the only roles + # of which the user is a member or whether they should merely + # be treated as the minimum membership list. Valid values are + # `inclusive`, `minimum`. + # UNSUPPORTED + #- **roles** + # The roles the user has. Multiple roles should be + # specified as an array. Requires features manages_solaris_rbac. + # UNSUPPORTED + #- **key_membership** + # Whether specified key value pairs should be treated as the only + # attributes + # of the user or whether they should merely + # be treated as the minimum list. Valid values are `inclusive`, + # `minimum`. + # UNSUPPORTED + #- **keys** + # Specify user attributes in an array of keyvalue pairs Requires features + # manages_solaris_rbac. + # UNSUPPORTED + #- **allowdupe** + # Whether to allow duplicate UIDs. Valid values are `true`, `false`. + # UNSUPPORTED + #- **auths** + # The auths the user has. Multiple auths should be + # specified as an array. Requires features manages_solaris_rbac. + # UNSUPPORTED + #- **auth_membership** + # Whether specified auths should be treated as the only auths + # of which the user is a member or whether they should merely + # be treated as the minimum membership list. Valid values are + # `inclusive`, `minimum`. + # UNSUPPORTED + +end diff --git a/lib/puppet/provider/zfs/solaris.rb b/lib/puppet/provider/zfs/solaris.rb index 85d054f86..b783f9e01 100644 --- a/lib/puppet/provider/zfs/solaris.rb +++ b/lib/puppet/provider/zfs/solaris.rb @@ -31,7 +31,7 @@ Puppet::Type.type(:zfs).provide(:solaris) do end end - [:mountpoint, :compression, :copies, :quota, :reservation, :sharenfs, :snapdir].each do |field| + [:aclinherit, :aclmode, :atime, :canmount, :checksum, :compression, :copies, :devices, :exec, :logbias, :mountpoint, :nbmand, :primarycache, :quota, :readonly, :recordsize, :refquota, :refreservation, :reservation, :secondarycache, :setuid, :shareiscsi, :sharenfs, :sharesmb, :snapdir, :version, :volsize, :vscan, :xattr, :zoned, :vscan].each do |field| define_method(field) do zfs(:get, "-H", "-o", "value", field, @resource[:name]).strip end diff --git a/lib/puppet/provider/zone/solaris.rb b/lib/puppet/provider/zone/solaris.rb index f46337b14..194af5049 100644 --- a/lib/puppet/provider/zone/solaris.rb +++ b/lib/puppet/provider/zone/solaris.rb @@ -221,6 +221,9 @@ Puppet::Type.type(:zone).provide(:solaris) do if dir = config["inherit-pkg-dir"] result[:inherit] = dir.collect { |dirs| dirs[:dir] } end + if datasets = config["dataset"] + result[:dataset] = datasets.collect { |dataset| dataset[:name] } + end result[:iptype] = config[:"ip-type"] if net = config["net"] result[:ip] = net.collect do |params| diff --git a/lib/puppet/provider/zpool/solaris.rb b/lib/puppet/provider/zpool/solaris.rb index e597c2ae1..758ea618a 100644 --- a/lib/puppet/provider/zpool/solaris.rb +++ b/lib/puppet/provider/zpool/solaris.rb @@ -19,11 +19,13 @@ Puppet::Type.type(:zpool).provide(:solaris) do pool_array.reverse.each do |value| sym = nil case value - when "spares"; sym = :spare - when "logs"; sym = :log - when "mirror", "raidz1", "raidz2" - sym = value == "mirror" ? :mirror : :raidz - pool[:raid_parity] = "raidz2" if value == "raidz2" + when "spares"; + sym = :spare + when "logs"; + sym = :log + when /^mirror|^raidz1|^raidz2/; + sym = value =~ /^mirror/ ? :mirror : :raidz + pool[:raid_parity] = "raidz2" if value =~ /^raidz2/ else tmp << value sym = :disk if value == pool_array.first diff --git a/lib/puppet/rails.rb b/lib/puppet/rails.rb index 74805bb6f..f74e63f20 100644 --- a/lib/puppet/rails.rb +++ b/lib/puppet/rails.rb @@ -58,7 +58,7 @@ module Puppet::Rails socket = Puppet[:dbsocket] args[:socket] = socket unless socket.to_s.empty? - when "oracle_enhanced": + when "oracle_enhanced" args[:database] = Puppet[:dbname] unless Puppet[:dbname].to_s.empty? args[:username] = Puppet[:dbuser] unless Puppet[:dbuser].to_s.empty? args[:password] = Puppet[:dbpassword] unless Puppet[:dbpassword].to_s.empty? diff --git a/lib/puppet/resource/catalog.rb b/lib/puppet/resource/catalog.rb index a8668d844..98c29657e 100644 --- a/lib/puppet/resource/catalog.rb +++ b/lib/puppet/resource/catalog.rb @@ -61,36 +61,32 @@ class Puppet::Resource::Catalog < Puppet::SimpleGraph [$1, $2] end - # Add one or more resources to our graph and to our resource table. + # Add a resource to our graph and to our resource table. # This is actually a relatively complicated method, because it handles multiple # aspects of Catalog behaviour: # * Add the resource to the resource table # * Add the resource to the resource graph # * Add the resource to the relationship graph # * Add any aliases that make sense for the resource (e.g., name != title) - def add_resource(*resources) - resources.each do |resource| - raise ArgumentError, "Can only add objects that respond to :ref, not instances of #{resource.class}" unless resource.respond_to?(:ref) - end.each { |resource| fail_on_duplicate_type_and_title(resource) }.each do |resource| - title_key = title_key_for_ref(resource.ref) - - @transient_resources << resource if applying? - @resource_table[title_key] = resource - - # If the name and title differ, set up an alias - - if resource.respond_to?(:name) and resource.respond_to?(:title) and resource.respond_to?(:isomorphic?) and resource.name != resource.title - self.alias(resource, resource.uniqueness_key) if resource.isomorphic? - end - - resource.catalog = self if resource.respond_to?(:catalog=) - - add_vertex(resource) - - @relationship_graph.add_vertex(resource) if @relationship_graph - - yield(resource) if block_given? + def add_resource(*resource) + add_resource(*resource[0..-2]) if resource.length > 1 + resource = resource.pop + raise ArgumentError, "Can only add objects that respond to :ref, not instances of #{resource.class}" unless resource.respond_to?(:ref) + fail_on_duplicate_type_and_title(resource) + title_key = title_key_for_ref(resource.ref) + + @transient_resources << resource if applying? + @resource_table[title_key] = resource + + # If the name and title differ, set up an alias + + if resource.respond_to?(:name) and resource.respond_to?(:title) and resource.respond_to?(:isomorphic?) and resource.name != resource.title + self.alias(resource, resource.uniqueness_key) if resource.isomorphic? end + + resource.catalog = self if resource.respond_to?(:catalog=) + add_vertex(resource) + @relationship_graph.add_vertex(resource) if @relationship_graph end # Create an alias for a resource. @@ -335,13 +331,75 @@ class Puppet::Resource::Catalog < Puppet::SimpleGraph @relationship_graph.write_graph(:relationships) if host_config? # Then splice in the container information - @relationship_graph.splice!(self, Puppet::Type::Component) + splice!(@relationship_graph) @relationship_graph.write_graph(:expanded_relationships) if host_config? end @relationship_graph end + # Impose our container information on another graph by using it + # to replace any container vertices X with a pair of verticies + # { admissible_X and completed_X } such that that + # + # 0) completed_X depends on admissible_X + # 1) contents of X each depend on admissible_X + # 2) completed_X depends on each on the contents of X + # 3) everything which depended on X depens on completed_X + # 4) admissible_X depends on everything X depended on + # 5) the containers and their edges must be removed + # + # Note that this requires attention to the possible case of containers + # which contain or depend on other containers, but has the advantage + # that the number of new edges created scales linearly with the number + # of contained verticies regardless of how containers are related; + # alternatives such as replacing container-edges with content-edges + # scale as the product of the number of external dependences, which is + # to say geometrically in the case of nested / chained containers. + # + Default_label = { :callback => :refresh, :event => :ALL_EVENTS } + def splice!(other) + stage_class = Puppet::Type.type(:stage) + whit_class = Puppet::Type.type(:whit) + component_class = Puppet::Type.type(:component) + containers = vertices.find_all { |v| (v.is_a?(component_class) or v.is_a?(stage_class)) and vertex?(v) } + # + # These two hashes comprise the aforementioned attention to the possible + # case of containers that contain / depend on other containers; they map + # containers to their sentinals but pass other verticies through. Thus we + # can "do the right thing" for references to other verticies that may or + # may not be containers. + # + admissible = Hash.new { |h,k| k } + completed = Hash.new { |h,k| k } + containers.each { |x| + admissible[x] = whit_class.new(:name => "admissible_#{x.name}", :catalog => self) + completed[x] = whit_class.new(:name => "completed_#{x.name}", :catalog => self) + } + # + # Implement the six requierments listed above + # + containers.each { |x| + contents = adjacent(x, :direction => :out) + other.add_edge(admissible[x],completed[x]) if contents.empty? # (0) + contents.each { |v| + other.add_edge(admissible[x],admissible[v],Default_label) # (1) + other.add_edge(completed[v], completed[x], Default_label) # (2) + } + # (3) & (5) + other.adjacent(x,:direction => :in,:type => :edges).each { |e| + other.add_edge(completed[e.source],admissible[x],e.label) + other.remove_edge! e + } + # (4) & (5) + other.adjacent(x,:direction => :out,:type => :edges).each { |e| + other.add_edge(completed[x],admissible[e.target],e.label) + other.remove_edge! e + } + } + containers.each { |x| other.remove_vertex! x } # (5) + end + # Remove the resource from our catalog. Notice that we also call # 'remove' on the resource, at least until resource classes no longer maintain # references to the resource instances. diff --git a/lib/puppet/resource/type.rb b/lib/puppet/resource/type.rb index 34fddf135..48d8c1f48 100644 --- a/lib/puppet/resource/type.rb +++ b/lib/puppet/resource/type.rb @@ -13,8 +13,8 @@ class Puppet::Resource::Type RESOURCE_SUPERTYPES = [:hostclass, :node, :definition] - attr_accessor :file, :line, :doc, :code, :ruby_code, :parent, :resource_type_collection, :module_name - attr_reader :type, :namespace, :arguments, :behaves_like + attr_accessor :file, :line, :doc, :code, :ruby_code, :parent, :resource_type_collection + attr_reader :type, :namespace, :arguments, :behaves_like, :module_name RESOURCE_SUPERTYPES.each do |t| define_method("#{t}?") { self.type == t } @@ -34,13 +34,13 @@ class Puppet::Resource::Type end def to_pson_data_hash - data = [:code, :doc, :line, :file, :parent].inject({}) do |hash, param| - next hash unless value = self.send(param) + data = [:doc, :line, :file, :parent].inject({}) do |hash, param| + next hash unless (value = self.send(param)) and (value != "") hash[param.to_s] = value hash end - data['arguments'] = arguments.dup + data['arguments'] = arguments.dup unless arguments.empty? data['name'] = name data['type'] = type @@ -92,6 +92,8 @@ class Puppet::Resource::Type end set_arguments(options[:arguments]) + + @module_name = options[:module_name] end # This is only used for node names, and really only when the node name diff --git a/lib/puppet/resource/type_collection.rb b/lib/puppet/resource/type_collection.rb index 4210475ad..9fe7cdd06 100644 --- a/lib/puppet/resource/type_collection.rb +++ b/lib/puppet/resource/type_collection.rb @@ -1,5 +1,6 @@ class Puppet::Resource::TypeCollection attr_reader :environment + attr_accessor :parse_failed def clear @hostclasses.clear @@ -19,6 +20,12 @@ class Puppet::Resource::TypeCollection @watched_files = {} end + def import_ast(ast, modname) + ast.instantiate(modname).each do |instance| + add(instance) + end + end + def inspect "TypeCollection" + { :hostclasses => @hostclasses.keys, :definitions => @definitions.keys, :nodes => @nodes.keys }.inspect end @@ -96,50 +103,8 @@ class Puppet::Resource::TypeCollection @definitions[munge_name(name)] end - def find(namespaces, name, type) - #Array("") == [] for some reason - namespaces = [namespaces] unless namespaces.is_a?(Array) - - if name =~ /^::/ - return send(type, name.sub(/^::/, '')) - end - - namespaces.each do |namespace| - ary = namespace.split("::") - - while ary.length > 0 - tmp_namespace = ary.join("::") - if r = find_partially_qualified(tmp_namespace, name, type) - return r - end - - # Delete the second to last object, which reduces our namespace by one. - ary.pop - end - - if result = send(type, name) - return result - end - end - nil - end - - def find_or_load(namespaces, name, type) - name = name.downcase - namespaces = [namespaces] unless namespaces.is_a?(Array) - namespaces = namespaces.collect { |ns| ns.downcase } - - # This could be done in the load_until, but the knowledge seems to - # belong here. - if r = find(namespaces, name, type) - return r - end - - loader.load_until(namespaces, name) { find(namespaces, name, type) } - end - def find_node(namespaces, name) - find("", name, :node) + @nodes[munge_name(name)] end def find_hostclass(namespaces, name) @@ -156,24 +121,6 @@ class Puppet::Resource::TypeCollection end end - def perform_initial_import - parser = Puppet::Parser::Parser.new(environment) - if code = Puppet.settings.uninterpolated_value(:code, environment.to_s) and code != "" - parser.string = code - else - file = Puppet.settings.value(:manifest, environment.to_s) - parser.file = file - end - parser.parse - rescue => detail - @parse_failed = true - - msg = "Could not parse for environment #{environment}: #{detail}" - error = Puppet::Error.new(msg) - error.set_backtrace(detail.backtrace) - raise error - end - def require_reparse? @parse_failed || stale? end @@ -206,8 +153,52 @@ class Puppet::Resource::TypeCollection private - def find_partially_qualified(namespace, name, type) - send(type, [namespace, name].join("::")) + # Return a list of all possible fully-qualified names that might be + # meant by the given name, in the context of namespaces. + def resolve_namespaces(namespaces, name) + name = name.downcase + if name =~ /^::/ + # name is explicitly fully qualified, so just return it, sans + # initial "::". + return [name.sub(/^::/, '')] + end + if name == "" + # The name "" has special meaning--it always refers to a "main" + # hostclass which contains all toplevel resources. + return [""] + end + + namespaces = [namespaces] unless namespaces.is_a?(Array) + namespaces = namespaces.collect { |ns| ns.downcase } + + result = [] + namespaces.each do |namespace| + ary = namespace.split("::") + + # Search each namespace nesting in innermost-to-outermost order. + while ary.length > 0 + result << "#{ary.join("::")}::#{name}" + ary.pop + end + + # Finally, search the toplevel namespace. + result << name + end + + return result.uniq + end + + # Resolve namespaces and find the given object. Autoload it if + # necessary. + def find_or_load(namespaces, name, type) + resolve_namespaces(namespaces, name).each do |fqname| + if result = send(type, fqname) || loader.try_load_fqname(type, fqname) + return result + end + end + + # Nothing found. + return nil end def munge_name(name) diff --git a/lib/puppet/simple_graph.rb b/lib/puppet/simple_graph.rb index c658b3b92..671eef150 100644 --- a/lib/puppet/simple_graph.rb +++ b/lib/puppet/simple_graph.rb @@ -1,133 +1,48 @@ -# Created by Luke A. Kanies on 2007-11-07. -# Copyright (c) 2007. All rights reserved. - require 'puppet/external/dot' require 'puppet/relationship' require 'set' # A hopefully-faster graph class to replace the use of GRATR. class Puppet::SimpleGraph - # An internal class for handling a vertex's edges. - class VertexWrapper - attr_accessor :in, :out, :vertex - - # Remove all references to everything. - def clear - @adjacencies[:in].clear - @adjacencies[:out].clear - @vertex = nil - end - - def initialize(vertex) - @vertex = vertex - @adjacencies = {:in => {}, :out => {}} - end - - # Find adjacent vertices or edges. - def adjacent(options) - direction = options[:direction] || :out - options[:type] ||= :vertices - - return send(direction.to_s + "_edges") if options[:type] == :edges - - @adjacencies[direction].keys.reject { |vertex| @adjacencies[direction][vertex].empty? } - end - - # Add an edge to our list. - def add_edge(direction, edge) - opposite_adjacencies(direction, edge) << edge - end - - # Return all known edges. - def edges - in_edges + out_edges - end - - # Test whether we share an edge with a given vertex. - def has_edge?(direction, vertex) - return(vertex_adjacencies(direction, vertex).length > 0 ? true : false) - end - - # Create methods for returning the degree and edges. - [:in, :out].each do |direction| - # LAK:NOTE If you decide to create methods for directly - # testing the degree, you'll have to get the values and flatten - # the results -- you might have duplicate edges, which can give - # a false impression of what the degree is. That's just - # as expensive as just getting the edge list, so I've decided - # to only add this method. - define_method("#{direction}_edges") do - @adjacencies[direction].values.inject([]) { |total, adjacent| total += adjacent.to_a; total } - end - end - - # The other vertex in the edge. - def other_vertex(direction, edge) - case direction - when :in; edge.source - else - edge.target - end - end - - # Remove an edge from our list. Assumes that we've already checked - # that the edge is valid. - def remove_edge(direction, edge) - opposite_adjacencies(direction, edge).delete(edge) - end - - def to_s - vertex.to_s - end - - def inspect - { :@adjacencies => @adjacencies, :@vertex => @vertex.to_s }.inspect - end - - private - - # These methods exist so we don't need a Hash with a default proc. - - # Look up the adjacencies for a vertex at the other end of an - # edge. - def opposite_adjacencies(direction, edge) - opposite_vertex = other_vertex(direction, edge) - vertex_adjacencies(direction, opposite_vertex) - end - - # Look up the adjacencies for a given vertex. - def vertex_adjacencies(direction, vertex) - @adjacencies[direction][vertex] ||= Set.new - @adjacencies[direction][vertex] - end - end - + # + # All public methods of this class must maintain (assume ^ ensure) the following invariants, where "=~=" means + # equiv. up to order: + # + # @in_to.keys =~= @out_to.keys =~= all vertices + # @in_to.values.collect { |x| x.values }.flatten =~= @out_from.values.collect { |x| x.values }.flatten =~= all edges + # @in_to[v1][v2] =~= @out_from[v2][v1] =~= all edges from v1 to v2 + # @in_to [v].keys =~= vertices with edges leading to v + # @out_from[v].keys =~= vertices with edges leading from v + # no operation may shed reference loops (for gc) + # recursive operation must scale with the depth of the spanning trees, or better (e.g. no recursion over the set + # of all vertices, etc.) + # + # This class is intended to be used with DAGs. However, if the + # graph has a cycle, it will not cause non-termination of any of the + # algorithms. + # def initialize - @vertices = {} - @edges = [] + @in_to = {} + @out_from = {} + @upstream_from = {} + @downstream_from = {} end # Clear our graph. def clear - @vertices.each { |vertex, wrapper| wrapper.clear } - @vertices.clear - @edges.clear - end - - # Which resources a given resource depends upon. - def dependents(resource) - tree_from_vertex(resource).keys + @in_to.clear + @out_from.clear + @upstream_from.clear + @downstream_from.clear end # Which resources depend upon the given resource. def dependencies(resource) - # Cache the reversal graph, because it's somewhat expensive - # to create. - @reversal ||= reversal - # Strangely, it's significantly faster to search a reversed - # tree in the :out direction than to search a normal tree - # in the :in direction. - @reversal.tree_from_vertex(resource, :out).keys + vertex?(resource) ? upstream_from_vertex(resource).keys : [] + end + + def dependents(resource) + vertex?(resource) ? downstream_from_vertex(resource).keys : [] end # Whether our graph is directed. Always true. Used to produce dot files. @@ -137,8 +52,7 @@ class Puppet::SimpleGraph # Determine all of the leaf nodes below a given vertex. def leaves(vertex, direction = :out) - tree = tree_from_vertex(vertex, direction) - l = tree.keys.find_all { |c| adjacent(c, :direction => direction).empty? } + tree_from_vertex(vertex, direction).keys.find_all { |c| adjacent(c, :direction => direction).empty? } end # Collect all of the edges that the passed events match. Returns @@ -153,9 +67,7 @@ class Puppet::SimpleGraph # Get all of the edges that this vertex should forward events # to, which is the same thing as saying all edges directly below # This vertex in the graph. - adjacent(source, :direction => :out, :type => :edges).find_all do |edge| - edge.match?(event.name) - end + @out_from[source].values.flatten.find_all { |edge| edge.match?(event.name) } end # Return a reversed version of this graph. @@ -163,197 +75,268 @@ class Puppet::SimpleGraph result = self.class.new vertices.each { |vertex| result.add_vertex(vertex) } edges.each do |edge| - newedge = edge.class.new(edge.target, edge.source, edge.label) - result.add_edge(newedge) + result.add_edge edge.class.new(edge.target, edge.source, edge.label) end result end # Return the size of the graph. def size - @vertices.length + vertices.size end - # Return the graph as an array. def to_a - @vertices.keys + vertices + end + + # This is a simple implementation of Tarjan's algorithm to find strongly + # connected components in the graph; this is a fairly ugly implementation, + # because I can't just decorate the vertices themselves. + # + # This method has an unhealthy relationship with the find_cycles_in_graph + # method below, which contains the knowledge of how the state object is + # maintained. + def tarjan(root, s) + # initialize the recursion stack we use to work around the nasty lack of a + # decent Ruby stack. + recur = [{ :node => root }] + + while not recur.empty? do + frame = recur.last + vertex = frame[:node] + + case frame[:step] + when nil then + s[:index][vertex] = s[:number] + s[:lowlink][vertex] = s[:number] + s[:number] = s[:number] + 1 + + s[:stack].push(vertex) + s[:seen][vertex] = true + + frame[:children] = adjacent(vertex) + frame[:step] = :children + + when :children then + if frame[:children].length > 0 then + child = frame[:children].shift + if ! s[:index][child] then + # Never seen, need to recurse. + frame[:step] = :after_recursion + frame[:child] = child + recur.push({ :node => child }) + elsif s[:seen][child] then + s[:lowlink][vertex] = [s[:lowlink][vertex], s[:index][child]].min + end + else + if s[:lowlink][vertex] == s[:index][vertex] then + this_scc = [] + begin + top = s[:stack].pop + s[:seen][top] = false + this_scc << top + end until top == vertex + # NOTE: if we don't reverse we get the components in the opposite + # order to what a human being would expect; reverse should be an + # O(1) operation, without even copying, because we know the length + # of the source, but I worry that an implementation will get this + # wrong. Still, the worst case is O(n) for n vertices as we can't + # possibly put a vertex into two SCCs. + # + # Also, my feeling is that most implementations are going to do + # better with a reverse operation than a string of 'unshift' + # insertions at the head of the array; if they were going to mess + # up the performance of one, it would be unshift. + s[:scc] << this_scc.reverse + end + recur.pop # done with this node, finally. + end + + when :after_recursion then + s[:lowlink][vertex] = [s[:lowlink][vertex], s[:lowlink][frame[:child]]].min + frame[:step] = :children + + else + fail "#{frame[:step]} is an unknown step" + end + end end - # Provide a topological sort. - def topsort - degree = {} - zeros = [] - result = [] + # Find all cycles in the graph by detecting all the strongly connected + # components, then eliminating everything with a size of one as + # uninteresting - which it is, because it can't be a cycle. :) + # + # This has an unhealthy relationship with the 'tarjan' method above, which + # it uses to implement the detection of strongly connected components. + def find_cycles_in_graph + state = { + :number => 0, :index => {}, :lowlink => {}, :scc => [], + :stack => [], :seen => {} + } + + # we usually have a disconnected graph, must walk all possible roots + vertices.each do |vertex| + if ! state[:index][vertex] then + tarjan vertex, state + end + end + + state[:scc].select { |c| c.length > 1 } + end - # Collect each of our vertices, with the number of in-edges each has. - @vertices.each do |name, wrapper| - edges = wrapper.in_edges - zeros << wrapper if edges.length == 0 - degree[wrapper.vertex] = edges + # Perform a BFS on the sub graph representing the cycle, with a view to + # generating a sufficient set of paths to report the cycle meaningfully, and + # ideally usefully, for the end user. + # + # BFS is preferred because it will generally report the shortest paths + # through the graph first, which are more likely to be interesting to the + # user. I think; it would be interesting to verify that. --daniel 2011-01-23 + def paths_in_cycle(cycle, max_paths = 1) + raise ArgumentError, "negative or zero max_paths" if max_paths < 1 + + # Calculate our filtered outbound vertex lists... + adj = {} + cycle.each do |vertex| + adj[vertex] = adjacent(vertex).select{|s| cycle.member? s} end - # Iterate over each 0-degree vertex, decrementing the degree of - # each of its out-edges. - while wrapper = zeros.pop - result << wrapper.vertex - wrapper.out_edges.each do |edge| - degree[edge.target].delete(edge) - zeros << @vertices[edge.target] if degree[edge.target].length == 0 + found = [] + + # frame struct is vertex, [path] + stack = [[cycle.first, []]] + while frame = stack.shift do + if frame[1].member?(frame[0]) then + found << frame[1] + [frame[0]] + break if found.length >= max_paths + else + adj[frame[0]].each do |to| + stack.push [to, frame[1] + [frame[0]]] + end end end - # If we have any vertices left with non-zero in-degrees, then we've found a cycle. - if cycles = degree.find_all { |vertex, edges| edges.length > 0 } and cycles.length > 0 - message = cycles.collect { |vertex, edges| edges.collect { |e| e.to_s }.join(", ") }.join(", ") - raise Puppet::Error, "Found dependency cycles in the following relationships: #{message}; try using the '--graph' option and open the '.dot' files in OmniGraffle or GraphViz" + return found + end + + def report_cycles_in_graph + cycles = find_cycles_in_graph + n = cycles.length # where is "pluralize"? --daniel 2011-01-22 + return if n == 0 + s = n == 1 ? '' : 's' + + message = "Found #{n} dependency cycle#{s}:\n" + cycles.each do |cycle| + paths = paths_in_cycle(cycle) + message += paths.map{ |path| '(' + path.join(" => ") + ')'}.join("\n") + "\n" end - result + if Puppet[:graph] then + filename = write_cycles_to_graph(cycles) + message += "Cycle graph written to #{filename}." + else + message += "Try the '--graph' option and opening the " + message += "resulting '.dot' file in OmniGraffle or GraphViz" + end + + raise Puppet::Error, message + end + + def write_cycles_to_graph(cycles) + # This does not use the DOT graph library, just writes the content + # directly. Given the complexity of this, there didn't seem much point + # using a heavy library to generate exactly the same content. --daniel 2011-01-27 + Puppet.settings.use(:graphing) + + graph = ["digraph Resource_Cycles {"] + graph << ' label = "Resource Cycles"' + + cycles.each do |cycle| + paths_in_cycle(cycle, 10).each do |path| + graph << path.map { |v| '"' + v.to_s.gsub(/"/, '\\"') + '"' }.join(" -> ") + end + end + + graph << '}' + + filename = File.join(Puppet[:graphdir], "cycles.dot") + File.open(filename, "w") { |f| f.puts graph } + return filename end # Add a new vertex to the graph. def add_vertex(vertex) - @reversal = nil - return false if vertex?(vertex) - setup_vertex(vertex) - true # don't return the VertexWrapper instance. + @in_to[vertex] ||= {} + @out_from[vertex] ||= {} end # Remove a vertex from the graph. - def remove_vertex!(vertex) - return nil unless vertex?(vertex) - @vertices[vertex].edges.each { |edge| remove_edge!(edge) } - @edges -= @vertices[vertex].edges - @vertices[vertex].clear - @vertices.delete(vertex) + def remove_vertex!(v) + return unless vertex?(v) + @upstream_from.clear + @downstream_from.clear + (@in_to[v].values+@out_from[v].values).flatten.each { |e| remove_edge!(e) } + @in_to.delete(v) + @out_from.delete(v) end # Test whether a given vertex is in the graph. - def vertex?(vertex) - @vertices.include?(vertex) + def vertex?(v) + @in_to.include?(v) end # Return a list of all vertices. def vertices - @vertices.keys + @in_to.keys end # Add a new edge. The graph user has to create the edge instance, # since they have to specify what kind of edge it is. - def add_edge(source, target = nil, label = nil) - @reversal = nil - if target - edge = Puppet::Relationship.new(source, target, label) - else - edge = source - end - [edge.source, edge.target].each { |vertex| setup_vertex(vertex) unless vertex?(vertex) } - @vertices[edge.source].add_edge :out, edge - @vertices[edge.target].add_edge :in, edge - @edges << edge - true + def add_edge(e,*a) + return add_relationship(e,*a) unless a.empty? + @upstream_from.clear + @downstream_from.clear + add_vertex(e.source) + add_vertex(e.target) + @in_to[ e.target][e.source] ||= []; @in_to[ e.target][e.source] |= [e] + @out_from[e.source][e.target] ||= []; @out_from[e.source][e.target] |= [e] end - # Find a matching edge. Note that this only finds the first edge, - # not all of them or whatever. - def edge(source, target) - @edges.each_with_index { |test_edge, index| return test_edge if test_edge.source == source and test_edge.target == target } + def add_relationship(source, target, label = nil) + add_edge Puppet::Relationship.new(source, target, label) end - def edge_label(source, target) - return nil unless edge = edge(source, target) - edge.label + # Find all matching edges. + def edges_between(source, target) + (@out_from[source] || {})[target] || [] end # Is there an edge between the two vertices? def edge?(source, target) - return false unless vertex?(source) and vertex?(target) - - @vertices[source].has_edge?(:out, target) + vertex?(source) and vertex?(target) and @out_from[source][target] end def edges - @edges.dup + @in_to.values.collect { |x| x.values }.flatten end - # Remove an edge from our graph. - def remove_edge!(edge) - @vertices[edge.source].remove_edge(:out, edge) - @vertices[edge.target].remove_edge(:in, edge) + def each_edge + @in_to.each { |t,ns| ns.each { |s,es| es.each { |e| yield e }}} + end - @edges.delete(edge) - nil + # Remove an edge from our graph. + def remove_edge!(e) + if edge?(e.source,e.target) + @upstream_from.clear + @downstream_from.clear + @in_to [e.target].delete e.source if (@in_to [e.target][e.source] -= [e]).empty? + @out_from[e.source].delete e.target if (@out_from[e.source][e.target] -= [e]).empty? + end end # Find adjacent edges. - def adjacent(vertex, options = {}) - return [] unless wrapper = @vertices[vertex] - wrapper.adjacent(options) - end - - private - - # An internal method that skips the validation, so we don't have - # duplicate validation calls. - def setup_vertex(vertex) - @vertices[vertex] = VertexWrapper.new(vertex) - end - - public - -# # For some reason, unconnected vertices do not show up in -# # this graph. -# def to_jpg(path, name) -# gv = vertices -# Dir.chdir(path) do -# induced_subgraph(gv).write_to_graphic_file('jpg', name) -# end -# end - - # Take container information from another graph and use it - # to replace any container vertices with their respective leaves. - # This creates direct relationships where there were previously - # indirect relationships through the containers. - def splice!(other, type) - # We have to get the container list via a topological sort on the - # configuration graph, because otherwise containers that contain - # other containers will add those containers back into the - # graph. We could get a similar affect by only setting relationships - # to container leaves, but that would result in many more - # relationships. - stage_class = Puppet::Type.type(:stage) - whit_class = Puppet::Type.type(:whit) - containers = other.topsort.find_all { |v| (v.is_a?(type) or v.is_a?(stage_class)) and vertex?(v) } - containers.each do |container| - # Get the list of children from the other graph. - children = other.adjacent(container, :direction => :out) - - # MQR TODO: Luke suggests that it should be possible to refactor the system so that - # container nodes are retained, thus obviating the need for the whit. - children = [whit_class.new(:name => container.name, :catalog => other)] if children.empty? - - # First create new edges for each of the :in edges - [:in, :out].each do |dir| - edges = adjacent(container, :direction => dir, :type => :edges) - edges.each do |edge| - children.each do |child| - if dir == :in - s = edge.source - t = child - else - s = child - t = edge.target - end - - add_edge(s, t, edge.label) - end - - # Now get rid of the edge, so remove_vertex! works correctly. - remove_edge!(edge) - end - end - remove_vertex!(container) - end + def adjacent(v, options = {}) + return [] unless ns = (options[:direction] == :in) ? @in_to[v] : @out_from[v] + (options[:type] == :edges) ? ns.values.flatten : ns.keys end # Just walk the tree and pass each edge. @@ -385,6 +368,60 @@ class Puppet::SimpleGraph predecessor end + def downstream_from_vertex(v) + return @downstream_from[v] if @downstream_from[v] + result = @downstream_from[v] = {} + @out_from[v].keys.each do |node| + result[node] = 1 + result.update(downstream_from_vertex(node)) + end + result + end + + def direct_dependents_of(v) + (@out_from[v] || {}).keys + end + + def upstream_from_vertex(v) + return @upstream_from[v] if @upstream_from[v] + result = @upstream_from[v] = {} + @in_to[v].keys.each do |node| + result[node] = 1 + result.update(upstream_from_vertex(node)) + end + result + end + + def direct_dependencies_of(v) + (@in_to[v] || {}).keys + end + + # Return an array of the edge-sets between a series of n+1 vertices (f=v0,v1,v2...t=vn) + # connecting the two given verticies. The ith edge set is an array containing all the + # edges between v(i) and v(i+1); these are (by definition) never empty. + # + # * if f == t, the list is empty + # * if they are adjacent the result is an array consisting of + # a single array (the edges from f to t) + # * and so on by induction on a vertex m between them + # * if there is no path from f to t, the result is nil + # + # This implementation is not particularly efficient; it's used in testing where clarity + # is more important than last-mile efficiency. + # + def path_between(f,t) + if f==t + [] + elsif direct_dependents_of(f).include?(t) + [edges_between(f,t)] + elsif dependents(f).include?(t) + m = (dependents(f) & direct_dependencies_of(t)).first + path_between(f,m) + path_between(m,t) + else + nil + end + end + # LAK:FIXME This is just a paste of the GRATR code with slight modifications. # Return a DOT::DOTDigraph for directed graphs or a DOT::DOTSubgraph for an @@ -426,18 +463,6 @@ class Puppet::SimpleGraph system('dotty', dotfile) end - # Use +dot+ to create a graphical representation of the graph. Returns the - # filename of the graphics file. - def write_to_graphic_file (fmt='png', dotfile='graph') - src = dotfile + '.dot' - dot = dotfile + '.' + fmt - - File.open(src, 'w') {|f| f << self.to_dot << "\n"} - - system( "dot -T#{fmt} #{src} -o #{dot}" ) - dot - end - # Produce the graph files if requested. def write_graph(name) return unless Puppet[:graph] @@ -449,4 +474,80 @@ class Puppet::SimpleGraph f.puts to_dot("name" => name.to_s.capitalize) } end + + # This flag may be set to true to use the new YAML serialzation + # format (where @vertices is a simple list of vertices rather than a + # list of VertexWrapper objects). Deserialization supports both + # formats regardless of the setting of this flag. + class << self + attr_accessor :use_new_yaml_format + end + self.use_new_yaml_format = false + + # Stub class to allow graphs to be represented in YAML using the old + # (version 2.6) format. + class VertexWrapper + attr_reader :vertex, :adjacencies + def initialize(vertex, adjacencies) + @vertex = vertex + @adjacencies = adjacencies + end + + def inspect + { :@adjacencies => @adjacencies, :@vertex => @vertex.to_s }.inspect + end + end + + # instance_variable_get is used by Object.to_zaml to get instance + # variables. Override it so that we can simulate the presence of + # instance variables @edges and @vertices for serialization. + def instance_variable_get(v) + case v.to_s + when '@edges' then + edges + when '@vertices' then + if self.class.use_new_yaml_format + vertices + else + result = {} + vertices.each do |vertex| + adjacencies = {} + [:in, :out].each do |direction| + adjacencies[direction] = {} + adjacent(vertex, :direction => direction, :type => :edges).each do |edge| + other_vertex = direction == :in ? edge.source : edge.target + (adjacencies[direction][other_vertex] ||= Set.new).add(edge) + end + end + result[vertex] = Puppet::SimpleGraph::VertexWrapper.new(vertex, adjacencies) + end + result + end + else + super(v) + end + end + + def to_yaml_properties + other_vars = instance_variables. + map {|v| v.to_s}. + reject { |v| %w{@in_to @out_from @upstream_from @downstream_from}.include?(v) } + + (other_vars + %w{@vertices @edges}).sort.uniq + end + + def yaml_initialize(tag, var) + initialize() + vertices = var.delete('vertices') + edges = var.delete('edges') + if vertices.is_a?(Hash) + # Support old (2.6) format + vertices = vertices.keys + end + vertices.each { |v| add_vertex(v) } + edges.each { |e| add_edge(e) } + var.each do |varname, value| + instance_variable_set("@#{varname}", value) + end + end end diff --git a/lib/puppet/ssl/certificate_authority.rb b/lib/puppet/ssl/certificate_authority.rb index 0c226ca6a..d65067c70 100644 --- a/lib/puppet/ssl/certificate_authority.rb +++ b/lib/puppet/ssl/certificate_authority.rb @@ -63,7 +63,7 @@ class Puppet::SSL::CertificateAuthority store = nil store = autosign_store(auto) if auto != true - Puppet::SSL::CertificateRequest.search("*").each do |csr| + Puppet::SSL::CertificateRequest.indirection.search("*").each do |csr| sign(csr.name) if auto == true or store.allowed?(csr.name, "127.1.1.1") end end @@ -93,10 +93,10 @@ class Puppet::SSL::CertificateAuthority # Retrieve (or create, if necessary) the certificate revocation list. def crl unless defined?(@crl) - unless @crl = Puppet::SSL::CertificateRevocationList.find(Puppet::SSL::CA_NAME) + unless @crl = Puppet::SSL::CertificateRevocationList.indirection.find(Puppet::SSL::CA_NAME) @crl = Puppet::SSL::CertificateRevocationList.new(Puppet::SSL::CA_NAME) @crl.generate(host.certificate.content, host.key.content) - @crl.save + Puppet::SSL::CertificateRevocationList.indirection.save(@crl) end end @crl @@ -109,7 +109,7 @@ class Puppet::SSL::CertificateAuthority # Generate a new certificate. def generate(name) - raise ArgumentError, "A Certificate already exists for #{name}" if Puppet::SSL::Certificate.find(name) + raise ArgumentError, "A Certificate already exists for #{name}" if Puppet::SSL::Certificate.indirection.find(name) host = Puppet::SSL::Host.new(name) host.generate_certificate_request @@ -169,7 +169,7 @@ class Puppet::SSL::CertificateAuthority # List all signed certificates. def list - Puppet::SSL::Certificate.search("*").collect { |c| c.name } + Puppet::SSL::Certificate.indirection.search("*").collect { |c| c.name } end # Read the next serial from the serial file, and increment the @@ -199,14 +199,14 @@ class Puppet::SSL::CertificateAuthority # Print a given host's certificate as text. def print(name) - (cert = Puppet::SSL::Certificate.find(name)) ? cert.to_text : nil + (cert = Puppet::SSL::Certificate.indirection.find(name)) ? cert.to_text : nil end # Revoke a given certificate. def revoke(name) raise ArgumentError, "Cannot revoke certificates when the CRL is disabled" unless crl - if cert = Puppet::SSL::Certificate.find(name) + if cert = Puppet::SSL::Certificate.indirection.find(name) serial = cert.content.serial elsif ! serial = inventory.serial(name) raise ArgumentError, "Could not find a serial number for #{name}" @@ -229,7 +229,7 @@ class Puppet::SSL::CertificateAuthority csr = self_signing_csr issuer = csr.content else - unless csr = Puppet::SSL::CertificateRequest.find(hostname) + unless csr = Puppet::SSL::CertificateRequest.indirection.find(hostname) raise ArgumentError, "Could not find certificate request for #{hostname}" end issuer = host.certificate.content @@ -248,17 +248,17 @@ class Puppet::SSL::CertificateAuthority # Save the now-signed cert. This should get routed correctly depending # on the certificate type. - cert.save + Puppet::SSL::Certificate.indirection.save(cert) # And remove the CSR if this wasn't self signed. - Puppet::SSL::CertificateRequest.destroy(csr.name) unless self_signing_csr + Puppet::SSL::CertificateRequest.indirection.destroy(csr.name) unless self_signing_csr cert end # Verify a given host's certificate. def verify(name) - unless cert = Puppet::SSL::Certificate.find(name) + unless cert = Puppet::SSL::Certificate.indirection.find(name) raise ArgumentError, "Could not find a certificate for #{name}" end store = OpenSSL::X509::Store.new @@ -271,7 +271,7 @@ class Puppet::SSL::CertificateAuthority end def fingerprint(name, md = :MD5) - unless cert = Puppet::SSL::Certificate.find(name) || Puppet::SSL::CertificateRequest.find(name) + unless cert = Puppet::SSL::Certificate.indirection.find(name) || Puppet::SSL::CertificateRequest.indirection.find(name) raise ArgumentError, "Could not find a certificate or csr for #{name}" end cert.fingerprint(md) @@ -279,6 +279,6 @@ class Puppet::SSL::CertificateAuthority # List the waiting certificate requests. def waiting? - Puppet::SSL::CertificateRequest.search("*").collect { |r| r.name } + Puppet::SSL::CertificateRequest.indirection.search("*").collect { |r| r.name } end end diff --git a/lib/puppet/ssl/certificate_request.rb b/lib/puppet/ssl/certificate_request.rb index 2f6cae3f5..8c83339a1 100644 --- a/lib/puppet/ssl/certificate_request.rb +++ b/lib/puppet/ssl/certificate_request.rb @@ -5,7 +5,20 @@ class Puppet::SSL::CertificateRequest < Puppet::SSL::Base wraps OpenSSL::X509::Request extend Puppet::Indirector - indirects :certificate_request, :terminus_class => :file + + # If auto-signing is on, sign any certificate requests as they are saved. + module AutoSigner + def save(instance, key = nil) + super + + # Try to autosign the CSR. + if ca = Puppet::SSL::CertificateAuthority.instance + ca.autosign + end + end + end + + indirects :certificate_request, :terminus_class => :file, :extend => AutoSigner # Convert a string into an instance. def self.from_s(string) @@ -46,13 +59,4 @@ class Puppet::SSL::CertificateRequest < Puppet::SSL::Base Puppet.info "Certificate Request fingerprint (md5): #{fingerprint}" @content end - - def save(args = {}) - super() - - # Try to autosign the CSR. - if ca = Puppet::SSL::CertificateAuthority.instance - ca.autosign - end - end end diff --git a/lib/puppet/ssl/certificate_revocation_list.rb b/lib/puppet/ssl/certificate_revocation_list.rb index 44e0a9e22..293f4b8c0 100644 --- a/lib/puppet/ssl/certificate_revocation_list.rb +++ b/lib/puppet/ssl/certificate_revocation_list.rb @@ -79,6 +79,6 @@ class Puppet::SSL::CertificateRevocationList < Puppet::SSL::Base @content.sign(cakey, OpenSSL::Digest::SHA1.new) - save + Puppet::SSL::CertificateRevocationList.indirection.save(self) end end diff --git a/lib/puppet/ssl/host.rb b/lib/puppet/ssl/host.rb index 8a6f0aa6d..b9215effd 100644 --- a/lib/puppet/ssl/host.rb +++ b/lib/puppet/ssl/host.rb @@ -1,3 +1,4 @@ +require 'puppet/indirector' require 'puppet/ssl' require 'puppet/ssl/key' require 'puppet/ssl/certificate' @@ -15,11 +16,17 @@ class Puppet::SSL::Host CertificateRequest = Puppet::SSL::CertificateRequest CertificateRevocationList = Puppet::SSL::CertificateRevocationList + extend Puppet::Indirector + indirects :certificate_status, :terminus_class => :file + attr_reader :name attr_accessor :ca attr_writer :key, :certificate, :certificate_request + # This accessor is used in instances for indirector requests to hold desired state + attr_accessor :desired_state + class << self include Puppet::Util::Cacher @@ -43,31 +50,38 @@ class Puppet::SSL::Host # Configure how our various classes interact with their various terminuses. def self.configure_indirection(terminus, cache = nil) - Certificate.terminus_class = terminus - CertificateRequest.terminus_class = terminus - CertificateRevocationList.terminus_class = terminus + Certificate.indirection.terminus_class = terminus + CertificateRequest.indirection.terminus_class = terminus + CertificateRevocationList.indirection.terminus_class = terminus + + host_map = {:ca => :file, :file => nil, :rest => :rest} + if term = host_map[terminus] + self.indirection.terminus_class = term + else + self.indirection.reset_terminus_class + end if cache # This is weird; we don't actually cache our keys, we # use what would otherwise be the cache as our normal # terminus. - Key.terminus_class = cache + Key.indirection.terminus_class = cache else - Key.terminus_class = terminus + Key.indirection.terminus_class = terminus end if cache - Certificate.cache_class = cache - CertificateRequest.cache_class = cache - CertificateRevocationList.cache_class = cache + Certificate.indirection.cache_class = cache + CertificateRequest.indirection.cache_class = cache + CertificateRevocationList.indirection.cache_class = cache else # Make sure we have no cache configured. puppet master # switches the configurations around a bit, so it's important # that we specify the configs for absolutely everything, every # time. - Certificate.cache_class = nil - CertificateRequest.cache_class = nil - CertificateRevocationList.cache_class = nil + Certificate.indirection.cache_class = nil + CertificateRequest.indirection.cache_class = nil + CertificateRevocationList.indirection.cache_class = nil end end @@ -85,30 +99,34 @@ class Puppet::SSL::Host # Specify how we expect to interact with our certificate authority. def self.ca_location=(mode) - raise ArgumentError, "CA Mode can only be #{CA_MODES.collect { |m| m.to_s }.join(", ")}" unless CA_MODES.include?(mode) + modes = CA_MODES.collect { |m, vals| m.to_s }.join(", ") + raise ArgumentError, "CA Mode can only be one of: #{modes}" unless CA_MODES.include?(mode) @ca_location = mode configure_indirection(*CA_MODES[@ca_location]) end - # Remove all traces of a given host + # Puppet::SSL::Host is actually indirected now so the original implementation + # has been moved into the certificate_status indirector. This method is in-use + # in `puppet cert -c <certname>`. def self.destroy(name) - [Key, Certificate, CertificateRequest].collect { |part| part.destroy(name) }.any? { |x| x } + indirection.destroy(name) end - # Search for more than one host, optionally only specifying - # an interest in hosts with a given file type. - # This just allows our non-indirected class to have one of - # indirection methods. - def self.search(options = {}) - classlist = [options[:for] || [Key, CertificateRequest, Certificate]].flatten - - # Collect the results from each class, flatten them, collect all of the names, make the name list unique, - # then create a Host instance for each one. - classlist.collect { |klass| klass.search }.flatten.collect { |r| r.name }.uniq.collect do |name| - new(name) + def self.from_pson(pson) + instance = new(pson["name"]) + if pson["desired_state"] + instance.desired_state = pson["desired_state"] end + instance + end + + # Puppet::SSL::Host is actually indirected now so the original implementation + # has been moved into the certificate_status indirector. This method does not + # appear to be in use in `puppet cert -l`. + def self.search(options = {}) + indirection.search("*", options) end # Is this a ca host, meaning that all of its files go in the CA location? @@ -117,7 +135,7 @@ class Puppet::SSL::Host end def key - @key ||= Key.find(name) + @key ||= Key.indirection.find(name) end # This is the private key; we can create it from scratch @@ -126,7 +144,7 @@ class Puppet::SSL::Host @key = Key.new(name) @key.generate begin - @key.save + Key.indirection.save(@key) rescue @key = nil raise @@ -135,7 +153,7 @@ class Puppet::SSL::Host end def certificate_request - @certificate_request ||= CertificateRequest.find(name) + @certificate_request ||= CertificateRequest.indirection.find(name) end # Our certificate request requires the key but that's all. @@ -144,7 +162,7 @@ class Puppet::SSL::Host @certificate_request = CertificateRequest.new(name) @certificate_request.generate(key.content) begin - @certificate_request.save + CertificateRequest.indirection.save(@certificate_request) rescue @certificate_request = nil raise @@ -159,8 +177,8 @@ class Puppet::SSL::Host # get the CA cert first, since it's required for the normal cert # to be of any use. - return nil unless Certificate.find("ca") unless ca? - return nil unless @certificate = Certificate.find(name) + return nil unless Certificate.indirection.find("ca") unless ca? + return nil unless @certificate = Certificate.indirection.find(name) unless certificate_matches_key? raise Puppet::Error, "Retrieved certificate does not match private key; please remove certificate from server and regenerate it with the current key" @@ -212,7 +230,7 @@ class Puppet::SSL::Host @ssl_store.add_file(Puppet[:localcacert]) # If there's a CRL, add it to our store. - if crl = Puppet::SSL::CertificateRevocationList.find(CA_NAME) + if crl = Puppet::SSL::CertificateRevocationList.indirection.find(CA_NAME) @ssl_store.flags = OpenSSL::X509::V_FLAG_CRL_CHECK_ALL|OpenSSL::X509::V_FLAG_CRL_CHECK if Puppet.settings[:certificate_revocation] @ssl_store.add_crl(crl.content) end @@ -221,6 +239,24 @@ class Puppet::SSL::Host @ssl_store end + def to_pson(*args) + my_cert = Puppet::SSL::Certificate.indirection.find(name) + pson_hash = { :name => name } + + my_state = state + + pson_hash[:state] = my_state + pson_hash[:desired_state] = desired_state if desired_state + + if my_state == 'requested' + pson_hash[:fingerprint] = certificate_request.fingerprint + else + pson_hash[:fingerprint] = my_cert.fingerprint + end + + pson_hash.to_pson(*args) + end + # Attempt to retrieve a cert, if we don't already have one. def wait_for_cert(time) begin @@ -257,6 +293,20 @@ class Puppet::SSL::Host end end end + + def state + my_cert = Puppet::SSL::Certificate.indirection.find(name) + if certificate_request + return 'requested' + end + + begin + Puppet::SSL::CertificateAuthority.new.verify(my_cert) + return 'signed' + rescue Puppet::SSL::CertificateAuthority::CertificateVerificationError + return 'revoked' + end + end end require 'puppet/ssl/certificate_authority' diff --git a/lib/puppet/ssl/inventory.rb b/lib/puppet/ssl/inventory.rb index b2b402a53..e094da100 100644 --- a/lib/puppet/ssl/inventory.rb +++ b/lib/puppet/ssl/inventory.rb @@ -36,7 +36,7 @@ class Puppet::SSL::Inventory f.print "# Inventory of signed certificates\n# SERIAL NOT_BEFORE NOT_AFTER SUBJECT\n" end - Puppet::SSL::Certificate.search("*").each { |cert| add(cert) } + Puppet::SSL::Certificate.indirection.search("*").each { |cert| add(cert) } end # Find the serial number for a given certificate. diff --git a/lib/puppet/sslcertificates/monkey_patch.rb b/lib/puppet/sslcertificates/monkey_patch.rb deleted file mode 100644 index 663b944c1..000000000 --- a/lib/puppet/sslcertificates/monkey_patch.rb +++ /dev/null @@ -1,6 +0,0 @@ -# This is the file that we use to add indirection to all the SSL Certificate classes. - -require 'puppet/indirector' - -OpenSSL::PKey::RSA.extend Puppet::Indirector -OpenSSL::PKey::RSA.indirects :ssl_rsa, :terminus_class => :file diff --git a/lib/puppet/transaction.rb b/lib/puppet/transaction.rb index 48154ad6f..0533273d9 100644 --- a/lib/puppet/transaction.rb +++ b/lib/puppet/transaction.rb @@ -4,6 +4,7 @@ require 'puppet' require 'puppet/util/tagging' require 'puppet/application' +require 'sha1' class Puppet::Transaction require 'puppet/transaction/event' @@ -12,7 +13,7 @@ class Puppet::Transaction require 'puppet/resource/status' attr_accessor :component, :catalog, :ignoreschedules - attr_accessor :sorted_resources, :configurator + attr_accessor :configurator # The report, once generated. attr_accessor :report @@ -57,68 +58,36 @@ class Puppet::Transaction report.resource_statuses.values.find_all { |status| status.changed }.collect { |status| catalog.resource(status.resource) } end + # Find all of the applied resources (including failed attempts). + def applied_resources + report.resource_statuses.values.collect { |status| catalog.resource(status.resource) } + end + # Copy an important relationships from the parent to the newly-generated # child resource. - def make_parent_child_relationship(resource, children) - depthfirst = resource.depthfirst? - - children.each do |gen_child| - if depthfirst - edge = [gen_child, resource] - else - edge = [resource, gen_child] - end - relationship_graph.add_vertex(gen_child) - - unless relationship_graph.edge?(edge[1], edge[0]) - relationship_graph.add_edge(*edge) - else - resource.debug "Skipping automatic relationship to #{gen_child}" - end + def add_conditional_directed_dependency(parent, child, label=nil) + relationship_graph.add_vertex(child) + edge = parent.depthfirst? ? [child, parent] : [parent, child] + if relationship_graph.edge?(*edge.reverse) + parent.debug "Skipping automatic relationship to #{child}" + else + relationship_graph.add_edge(edge[0],edge[1],label) end end - # See if the resource generates new resources at evaluation time. - def eval_generate(resource) - generate_additional_resources(resource, :eval_generate) - end - # Evaluate a single resource. def eval_resource(resource, ancestor = nil) if skip?(resource) resource_status(resource).skipped = true else - eval_children_and_apply_resource(resource, ancestor) + resource_status(resource).scheduled = true + apply(resource, ancestor) end # Check to see if there are any events queued for this resource event_manager.process_events(resource) end - def eval_children_and_apply_resource(resource, ancestor = nil) - resource_status(resource).scheduled = true - - # We need to generate first regardless, because the recursive - # actions sometimes change how the top resource is applied. - children = eval_generate(resource) - - if ! children.empty? and resource.depthfirst? - children.each do |child| - # The child will never be skipped when the parent isn't - eval_resource(child, ancestor || resource) - end - end - - # Perform the actual changes - apply(resource, ancestor) - - if ! children.empty? and ! resource.depthfirst? - children.each do |child| - eval_resource(child, ancestor || resource) - end - end - end - # This method does all the actual work of running a transaction. It # collects all of the changes, executes them, and responds to any # necessary events. @@ -131,19 +100,13 @@ class Puppet::Transaction Puppet.info "Applying configuration version '#{catalog.version}'" if catalog.version begin - @sorted_resources.each do |resource| - next if stop_processing? + relationship_graph.traverse do |resource| if resource.is_a?(Puppet::Type::Component) Puppet.warning "Somehow left a component in the relationship graph" - next + else + seconds = thinmark { eval_resource(resource) } + resource.info "Evaluated in %0.2f seconds" % seconds if Puppet[:evaltrace] and @catalog.host_config? end - ret = nil - seconds = thinmark do - ret = eval_resource(resource) - end - - resource.info "Evaluated in %0.2f seconds" % seconds if Puppet[:evaltrace] and @catalog.host_config? - ret end ensure # And then close the transaction log. @@ -177,48 +140,66 @@ class Puppet::Transaction found_failed end + def eval_generate(resource) + raise Puppet::DevError,"Depthfirst resources are not supported by eval_generate" if resource.depthfirst? + begin + made = resource.eval_generate.uniq.reverse + rescue => detail + puts detail.backtrace if Puppet[:trace] + resource.err "Failed to generate additional resources using 'eval_generate: #{detail}" + return + end + made.each do |res| + begin + res.tag(*resource.tags) + @catalog.add_resource(res) + res.finish + rescue Puppet::Resource::Catalog::DuplicateResourceError + res.info "Duplicate generated resource; skipping" + end + end + sentinal = Puppet::Type::Whit.new(:name => "completed_#{resource.title}", :catalog => resource.catalog) + relationship_graph.adjacent(resource,:direction => :out,:type => :edges).each { |e| + add_conditional_directed_dependency(sentinal, e.target, e.label) + relationship_graph.remove_edge! e + } + default_label = Puppet::Resource::Catalog::Default_label + made.each do |res| + add_conditional_directed_dependency(made.find { |r| r != res && r.name == res.name[0,r.name.length]} || resource, res) + add_conditional_directed_dependency(res, sentinal, default_label) + end + add_conditional_directed_dependency(resource, sentinal, default_label) + end + # A general method for recursively generating new resources from a # resource. - def generate_additional_resources(resource, method) - return [] unless resource.respond_to?(method) + def generate_additional_resources(resource) + return unless resource.respond_to?(:generate) begin - made = resource.send(method) + made = resource.generate rescue => detail puts detail.backtrace if Puppet[:trace] - resource.err "Failed to generate additional resources using '#{method}': #{detail}" + resource.err "Failed to generate additional resources using 'generate': #{detail}" end - return [] unless made + return unless made made = [made] unless made.is_a?(Array) - made.uniq.find_all do |res| + made.uniq.each do |res| begin res.tag(*resource.tags) - @catalog.add_resource(res) do |r| - r.finish - make_parent_child_relationship(resource, [r]) - - # Call 'generate' recursively - generate_additional_resources(r, method) - end - true + @catalog.add_resource(res) + res.finish + add_conditional_directed_dependency(resource, res) + generate_additional_resources(res) rescue Puppet::Resource::Catalog::DuplicateResourceError res.info "Duplicate generated resource; skipping" - false end end end # Collect any dynamically generated resources. This method is called # before the transaction starts. - def generate - list = @catalog.vertices - newlist = [] - while ! list.empty? - list.each do |resource| - newlist += generate_additional_resources(resource, :generate) - end - list = newlist - newlist = [] - end + def xgenerate + @catalog.vertices.each { |resource| generate_additional_resources(resource) } end # Should we ignore tags? @@ -231,7 +212,7 @@ class Puppet::Transaction def initialize(catalog) @catalog = catalog - @report = Report.new("apply", catalog.version) + @report = Puppet::Transaction::Report.new("apply") @event_manager = Puppet::Transaction::EventManager.new(self) @@ -264,18 +245,75 @@ class Puppet::Transaction # Prepare to evaluate the resources in a transaction. def prepare # Now add any dynamically generated resources - generate + xgenerate # Then prefetch. It's important that we generate and then prefetch, # so that any generated resources also get prefetched. prefetch + end + - # This will throw an error if there are cycles in the graph. - @sorted_resources = relationship_graph.topsort + # We want to monitor changes in the relationship graph of our + # catalog but this is complicated by the fact that the catalog + # both is_a graph and has_a graph, by the fact that changes to + # the structure of the object can have adverse serialization + # effects, by threading issues, by order-of-initialization issues, + # etc. + # + # Since the proper lifetime/scope of the monitoring is a transaction + # and the transaction is already commiting a mild law-of-demeter + # transgression, we cut the Gordian knot here by simply wrapping the + # transaction's view of the resource graph to capture and maintain + # the information we need. Nothing outside the transaction needs + # this information, and nothing outside the transaction can see it + # except via the Transaction#relationship_graph + + class Relationship_graph_wrapper + attr_reader :real_graph,:transaction,:ready,:generated,:done,:unguessable_deterministic_key + def initialize(real_graph,transaction) + @real_graph = real_graph + @transaction = transaction + @ready = {} + @generated = {} + @done = {} + @unguessable_deterministic_key = Hash.new { |h,k| h[k] = Digest::SHA1.hexdigest("NaCl, MgSO4 (salts) and then #{k.title}") } + vertices.each { |v| check_if_now_ready(v) } + end + def method_missing(*args,&block) + real_graph.send(*args,&block) + end + def add_vertex(v) + real_graph.add_vertex(v) + check_if_now_ready(v) # ????????????????????????????????????????? + end + def add_edge(f,t,label=nil) + ready.delete(t) + real_graph.add_edge(f,t,label) + end + def check_if_now_ready(r) + ready[r] = true if direct_dependencies_of(r).all? { |r2| done[r2] } + end + def next_resource + ready.keys.sort_by { |r0| unguessable_deterministic_key[r0] }.first + end + def traverse(&block) + real_graph.report_cycles_in_graph + while (r = next_resource) && !transaction.stop_processing? + if !generated[r] && r.respond_to?(:eval_generate) + transaction.eval_generate(r) + generated[r] = true + else + ready.delete(r) + yield r + done[r] = true + direct_dependents_of(r).each { |v| check_if_now_ready(v) } + end + end + end end def relationship_graph - catalog.relationship_graph + @relationship_graph ||= Relationship_graph_wrapper.new(catalog.relationship_graph,self) end def add_resource_status(status) diff --git a/lib/puppet/transaction/event.rb b/lib/puppet/transaction/event.rb index cd695cff8..d3f25b71c 100644 --- a/lib/puppet/transaction/event.rb +++ b/lib/puppet/transaction/event.rb @@ -48,7 +48,7 @@ class Puppet::Transaction::Event end def to_yaml_properties - (YAML_ATTRIBUTES & instance_variables).sort + (YAML_ATTRIBUTES.map {|ya| ya.to_s} & instance_variables.map{|iv| iv.to_s}).sort end private diff --git a/lib/puppet/transaction/event_manager.rb b/lib/puppet/transaction/event_manager.rb index 3ebb0a9d3..a21bbf892 100644 --- a/lib/puppet/transaction/event_manager.rb +++ b/lib/puppet/transaction/event_manager.rb @@ -31,7 +31,7 @@ class Puppet::Transaction::EventManager # Queue events for other resources to respond to. All of these events have # to be from the same resource. def queue_events(resource, events) - @events += events + #@events += events # Do some basic normalization so we're not doing so many # graph queries for large sets of events. @@ -47,12 +47,15 @@ class Puppet::Transaction::EventManager # Collect the targets of any subscriptions to those events. We pass # the parent resource in so it will override the source in the events, # since eval_generated children can't have direct relationships. + received = (event.name != :restarted) relationship_graph.matching_edges(event, resource).each do |edge| + received ||= true unless edge.target.is_a?(Puppet::Type::Whit) next unless method = edge.callback next unless edge.target.respond_to?(method) queue_events_for_resource(resource, edge.target, method, list) end + @events << event if received queue_events_for_resource(resource, resource, :refresh, [event]) if resource.self_refresh? and ! resource.deleting? end diff --git a/lib/puppet/type.rb b/lib/puppet/type.rb index d24cc8554..5ecc430d4 100644 --- a/lib/puppet/type.rb +++ b/lib/puppet/type.rb @@ -598,14 +598,8 @@ class Type ############################### # Code related to the container behaviour. - # this is a retarded hack method to get around the difference between - # component children and file children - def self.depthfirst? - @depthfirst - end - def depthfirst? - self.class.depthfirst? + false end # Remove an object. The argument determines whether the object's diff --git a/lib/puppet/type/exec.rb b/lib/puppet/type/exec.rb index be0ece023..3ba488f19 100755 --- a/lib/puppet/type/exec.rb +++ b/lib/puppet/type/exec.rb @@ -201,15 +201,6 @@ module Puppet end end - newparam(:env) do - desc "This parameter is deprecated. Use 'environment' instead." - - munge do |value| - warning "'env' is deprecated on exec; use 'environment' instead." - resource[:environment] = value - end - end - newparam(:environment) do desc "Any additional environment variables you want to set for a command. Note that if you use this to set PATH, it will override diff --git a/lib/puppet/type/file.rb b/lib/puppet/type/file.rb index 630ebe5de..715836b22 100644 --- a/lib/puppet/type/file.rb +++ b/lib/puppet/type/file.rb @@ -44,7 +44,7 @@ Puppet::Type.newtype(:file) do # convert the current path in an index into the collection and the last # path name. The aim is to use less storage for all common paths in a hierarchy munge do |value| - path, name = File.split(value.gsub(/\/+/,'/')) + path, name = ::File.split(value.gsub(/\/+/,'/')) { :index => Puppet::FileCollection.collection.index(path), :name => name } end @@ -55,7 +55,7 @@ Puppet::Type.newtype(:file) do if value[:name] == '/' basedir else - File.join( basedir, value[:name] ) + ::File.join( basedir, value[:name] ) end end end @@ -259,7 +259,7 @@ Puppet::Type.newtype(:file) do # Autorequire any parent directories. autorequire(:file) do - basedir = File.dirname(self[:path]) + basedir = ::File.dirname(self[:path]) if basedir != self[:path] basedir else @@ -314,13 +314,11 @@ Puppet::Type.newtype(:file) do return self.new(:name => base, :recurse => true, :recurselimit => 1, :audit => :all).recurse_local.values end - @depthfirst = false - # Determine the user to write files as. def asuser if self.should(:owner) and ! self.should(:owner).is_a?(Symbol) writeable = Puppet::Util::SUIDManager.asuser(self.should(:owner)) { - FileTest.writable?(File.dirname(self[:path])) + FileTest.writable?(::File.dirname(self[:path])) } # If the parent directory is writeable, then we execute @@ -423,7 +421,7 @@ Puppet::Type.newtype(:file) do # Create a new file or directory object as a child to the current # object. def newchild(path) - full_path = File.join(self[:path], path) + full_path = ::File.join(self[:path], path) # Add some new values to our original arguments -- these are the ones # set at initialization. We specifically want to exclude any param @@ -475,8 +473,7 @@ Puppet::Type.newtype(:file) do # be used to copy remote files, manage local files, and/or make links # to map to another directory. def recurse - children = {} - children = recurse_local if self[:recurse] != :remote + children = (self[:recurse] == :remote) ? {} : recurse_local if self[:target] recurse_link(children) @@ -497,27 +494,23 @@ Puppet::Type.newtype(:file) do # not likely to have many actual conflicts, which is good, because # this is a pretty inefficient implementation. def remove_less_specific_files(files) - mypath = self[:path].split(File::Separator) + mypath = self[:path].split(::File::Separator) other_paths = catalog.vertices. select { |r| r.is_a?(self.class) and r[:path] != self[:path] }. - collect { |r| r[:path].split(File::Separator) }. + collect { |r| r[:path].split(::File::Separator) }. select { |p| p[0,mypath.length] == mypath } return files if other_paths.empty? files.reject { |file| - path = file[:path].split(File::Separator) + path = file[:path].split(::File::Separator) other_paths.any? { |p| path[0,p.length] == p } } end # A simple method for determining whether we should be recursing. def recurse? - return false unless @parameters.include?(:recurse) - - val = @parameters[:recurse].value - - !!(val and (val == true or val == :remote)) + self[:recurse] == true or self[:recurse] == :remote end # Recurse the target of the link. @@ -589,13 +582,10 @@ Puppet::Type.newtype(:file) do end def perform_recursion(path) - - Puppet::FileServing::Metadata.search( - + Puppet::FileServing::Metadata.indirection.search( path, :links => self[:links], :recurse => (self[:recurse] == :remote ? true : self[:recurse]), - :recurselimit => self[:recurselimit], :ignore => self[:ignore], :checksum_type => (self[:source] || self[:content]) ? self[:checksum] : :none @@ -623,7 +613,7 @@ Puppet::Type.newtype(:file) do end when "link", "file" debug "Removing existing #{s.ftype} for replacement with #{should}" - File.unlink(self[:path]) + ::File.unlink(self[:path]) else self.fail "Could not back up files of type #{s.ftype}" end @@ -688,7 +678,7 @@ Puppet::Type.newtype(:file) do path = self[:path] begin - File.send(method, self[:path]) + ::File.send(method, self[:path]) rescue Errno::ENOENT => error return nil rescue Errno::EACCES => error @@ -714,7 +704,7 @@ Puppet::Type.newtype(:file) do use_temporary_file = write_temporary_file? if use_temporary_file path = "#{self[:path]}.puppettmp_#{rand(10000)}" - path = "#{self[:path]}.puppettmp_#{rand(10000)}" while File.exists?(path) or File.symlink?(path) + path = "#{self[:path]}.puppettmp_#{rand(10000)}" while ::File.exists?(path) or ::File.symlink?(path) else path = self[:path] end @@ -723,18 +713,18 @@ Puppet::Type.newtype(:file) do umask = mode ? 000 : 022 mode_int = mode ? mode.to_i(8) : nil - content_checksum = Puppet::Util.withumask(umask) { File.open(path, 'w', mode_int ) { |f| write_content(f) } } + content_checksum = Puppet::Util.withumask(umask) { ::File.open(path, 'w', mode_int ) { |f| write_content(f) } } # And put our new file in place if use_temporary_file # This is only not true when our file is empty. begin fail_if_checksum_is_wrong(path, content_checksum) if validate_checksum? - File.rename(path, self[:path]) + ::File.rename(path, self[:path]) rescue => detail fail "Could not rename temporary file #{path} to #{self[:path]}: #{detail}" ensure # Make sure the created file gets removed - File.unlink(path) if FileTest.exists?(path) + ::File.unlink(path) if FileTest.exists?(path) end end diff --git a/lib/puppet/type/file/ctime.rb b/lib/puppet/type/file/ctime.rb index 24b098703..90d95da64 100644 --- a/lib/puppet/type/file/ctime.rb +++ b/lib/puppet/type/file/ctime.rb @@ -4,7 +4,7 @@ module Puppet def retrieve current_value = :absent - if stat = @resource.stat(false) + if stat = @resource.stat current_value = stat.ctime end current_value diff --git a/lib/puppet/type/file/ensure.rb b/lib/puppet/type/file/ensure.rb index 99652ecc6..0f065da14 100755 --- a/lib/puppet/type/file/ensure.rb +++ b/lib/puppet/type/file/ensure.rb @@ -138,7 +138,7 @@ module Puppet end def retrieve - if stat = @resource.stat(false) + if stat = @resource.stat return stat.ftype.intern else if self.should == :false diff --git a/lib/puppet/type/file/group.rb b/lib/puppet/type/file/group.rb index 5ed5166bc..4d1f2f4e6 100755 --- a/lib/puppet/type/file/group.rb +++ b/lib/puppet/type/file/group.rb @@ -62,7 +62,7 @@ module Puppet end def retrieve - return :absent unless stat = resource.stat(false) + return :absent unless stat = resource.stat currentvalue = stat.gid diff --git a/lib/puppet/type/file/mode.rb b/lib/puppet/type/file/mode.rb index 2acd8b359..9f58e6fb0 100755 --- a/lib/puppet/type/file/mode.rb +++ b/lib/puppet/type/file/mode.rb @@ -63,7 +63,7 @@ module Puppet # If we're not following links and we're a link, then we just turn # off mode management entirely. - if stat = @resource.stat(false) + if stat = @resource.stat unless defined?(@fixed) @should &&= @should.collect { |s| self.dirmask(s) } end diff --git a/lib/puppet/type/file/mtime.rb b/lib/puppet/type/file/mtime.rb index 8ca7ed0d6..5952b4b84 100644 --- a/lib/puppet/type/file/mtime.rb +++ b/lib/puppet/type/file/mtime.rb @@ -4,7 +4,7 @@ module Puppet def retrieve current_value = :absent - if stat = @resource.stat(false) + if stat = @resource.stat current_value = stat.mtime end current_value diff --git a/lib/puppet/type/file/selcontext.rb b/lib/puppet/type/file/selcontext.rb index ea385eec0..1b1a77245 100644 --- a/lib/puppet/type/file/selcontext.rb +++ b/lib/puppet/type/file/selcontext.rb @@ -26,7 +26,7 @@ module Puppet include Puppet::Util::SELinux def retrieve - return :absent unless @resource.stat(false) + return :absent unless @resource.stat context = self.get_selinux_current_context(@resource[:path]) parse_selinux_context(name, context) end diff --git a/lib/puppet/type/file/source.rb b/lib/puppet/type/file/source.rb index 6dda7957c..d3b3a48eb 100755 --- a/lib/puppet/type/file/source.rb +++ b/lib/puppet/type/file/source.rb @@ -98,7 +98,7 @@ module Puppet cached_attr(:content) do raise Puppet::DevError, "No source for content was stored with the metadata" unless metadata.source - unless tmp = Puppet::FileServing::Content.find(metadata.source) + unless tmp = Puppet::FileServing::Content.indirection.find(metadata.source) fail "Could not find any content at %s" % metadata.source end tmp.content @@ -144,7 +144,7 @@ module Puppet result = nil value.each do |source| begin - if data = Puppet::FileServing::Metadata.find(source) + if data = Puppet::FileServing::Metadata.indirection.find(source) result = data result.source = source break diff --git a/lib/puppet/type/file/type.rb b/lib/puppet/type/file/type.rb index 4da54e2cb..864d3b1a4 100755 --- a/lib/puppet/type/file/type.rb +++ b/lib/puppet/type/file/type.rb @@ -5,7 +5,7 @@ module Puppet def retrieve current_value = :absent - if stat = @resource.stat(false) + if stat = @resource.stat current_value = stat.ftype end current_value diff --git a/lib/puppet/type/group.rb b/lib/puppet/type/group.rb index cde1cfd65..2573633f9 100755 --- a/lib/puppet/type/group.rb +++ b/lib/puppet/type/group.rb @@ -1,6 +1,7 @@ require 'etc' require 'facter' +require 'puppet/property/keyvalue' module Puppet newtype(:group) do @@ -15,6 +16,9 @@ module Puppet feature :manages_members, "For directories where membership is an attribute of groups not users." + feature :manages_aix_lam, + "The provider can manage AIX Loadable Authentication Module (LAM) system." + ensurable do desc "Create or remove the group." @@ -95,5 +99,38 @@ module Puppet defaultto false end + + newparam(:ia_load_module, :required_features => :manages_aix_lam) do + desc "The name of the I&A module to use to manage this user" + + defaultto "compat" + end + + newproperty(:attributes, :parent => Puppet::Property::KeyValue, :required_features => :manages_aix_lam) do + desc "Specify group AIX attributes in an array of keyvalue pairs" + + def membership + :attribute_membership + end + + def delimiter + " " + end + + validate do |value| + raise ArgumentError, "Attributes value pairs must be seperated by an =" unless value.include?("=") + end + end + + newparam(:attribute_membership) do + desc "Whether specified attribute value pairs should be treated as the only attributes + of the user or whether they should merely + be treated as the minimum list." + + newvalues(:inclusive, :minimum) + + defaultto :minimum + end + end end diff --git a/lib/puppet/type/host.rb b/lib/puppet/type/host.rb index 2666e50ae..a770edab9 100755 --- a/lib/puppet/type/host.rb +++ b/lib/puppet/type/host.rb @@ -1,3 +1,5 @@ +require 'puppet/property/ordered_list' + module Puppet newtype(:host) do ensurable @@ -5,63 +7,36 @@ module Puppet newproperty(:ip) do desc "The host's IP address, IPv4 or IPv6." - validate do |value| - unless value =~ /((([0-9a-fA-F]+:){7}[0-9a-fA-F]+)|(([0-9a-fA-F]+:)*[0-9a-fA-F]+)?::(([0-9a-fA-F]+:)*[0-9a-fA-F]+)?)|((25[0-5]|2[0-4][\d]|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3})/ - raise Puppet::Error, "Invalid IP address" + validate do |value| + unless value =~ /^((([0-9a-fA-F]+:){7}[0-9a-fA-F]+)|(([0-9a-fA-F]+:)*[0-9a-fA-F]+)?::(([0-9a-fA-F]+:)*[0-9a-fA-F]+)?)|((25[0-5]|2[0-4][\d]|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3})$/ + raise Puppet::Error, "Invalid IP address" + end end - end end - newproperty(:host_aliases) do + # for now we use OrderedList to indicate that the order does matter. + newproperty(:host_aliases, :parent => Puppet::Property::OrderedList) do desc "Any aliases the host might have. Multiple values must be specified as an array." - def insync?(is) - is == @should - end - - def is_to_s(currentvalue = @is) - currentvalue = [currentvalue] unless currentvalue.is_a? Array - currentvalue.join(" ") - end - - def retrieve - is = super - case is - when String - is = is.split(/\s*,\s*/) - when Symbol - is = [is] - when Array - # nothing - else - raise Puppet::DevError, "Invalid @is type #{is.class}" - end - is - end - - # We actually want to return the whole array here, not just the first - # value. - def should - if defined?(@should) - if @should == [:absent] - return :absent - else - return @should - end - else - return nil - end + def delimiter + " " end - def should_to_s(newvalue = @should) - newvalue.join(" ") + def inclusive? + true end validate do |value| raise Puppet::Error, "Host aliases cannot include whitespace" if value =~ /\s/ + raise Puppet::Error, "Host alias cannot be an empty string. Use an empty array to delete all host_aliases " if value =~ /^\s*$/ end + + end + + newproperty(:comment) do + desc "A comment that will be attached to the line with a # character" end newproperty(:target) do diff --git a/lib/puppet/type/macauthorization.rb b/lib/puppet/type/macauthorization.rb index e89aa7c89..b16ab6dde 100644 --- a/lib/puppet/type/macauthorization.rb +++ b/lib/puppet/type/macauthorization.rb @@ -2,7 +2,7 @@ Puppet::Type.newtype(:macauthorization) do @doc = "Manage the Mac OS X authorization database. See the [Apple developer site](http://developer.apple.com/documentation/Security/Conceptual/Security_Overview/Security_Services/chapter_4_section_5.html) for more information. - + **Autorequires:** If Puppet is managing the `/etc/authorization` file, each macauthorization resource will autorequire it." @@ -33,8 +33,8 @@ Puppet::Type.newtype(:macauthorization) do desc "The name of the right or rule to be managed. Corresponds to 'key' in Authorization Services. The key is the name of a rule. A key uses the same naming conventions as a right. The - Security Server uses a rule’s key to match the rule with a right. - Wildcard keys end with a ‘.’. The generic rule has an empty key value. + Security Server uses a rule's key to match the rule with a right. + Wildcard keys end with a '.'. The generic rule has an empty key value. Any rights that do not match a specific rule use the generic rule." isnamevar diff --git a/lib/puppet/type/service.rb b/lib/puppet/type/service.rb index 0d09c3d5d..3ef044932 100644 --- a/lib/puppet/type/service.rb +++ b/lib/puppet/type/service.rb @@ -100,6 +100,8 @@ module Puppet looked for in the process table." newvalues(:true, :false) + + defaultto :true end newparam(:name) do desc "The name of the service to run. This name is used to find diff --git a/lib/puppet/type/sshkey.rb b/lib/puppet/type/sshkey.rb index b7a1b8a8d..59a1a12f8 100755 --- a/lib/puppet/type/sshkey.rb +++ b/lib/puppet/type/sshkey.rb @@ -41,7 +41,7 @@ module Puppet raise Puppet::Error, "Aliases cannot include whitespace" end if value =~ /,/ - raise Puppet::Error, "Aliases cannot include whitespace" + raise Puppet::Error, "Aliases must be provided as an array, not a comma-separated list" end end end @@ -50,6 +50,11 @@ module Puppet desc "The host name that the key is associated with." isnamevar + + validate do |value| + raise Puppet::Error, "Resourcename cannot include whitespaces" if value =~ /\s/ + raise Puppet::Error, "No comma in resourcename allowed. If you want to specify aliases use the host_aliases property" if value.include?(',') + end end newproperty(:target) do diff --git a/lib/puppet/type/tidy.rb b/lib/puppet/type/tidy.rb index 65cc077cf..1a308e17d 100755 --- a/lib/puppet/type/tidy.rb +++ b/lib/puppet/type/tidy.rb @@ -141,15 +141,17 @@ Puppet::Type.newtype(:tidy) do newparam(:size) do desc "Tidy files whose size is equal to or greater than the specified size. Unqualified values are in kilobytes, but - *b*, *k*, and *m* can be appended to specify *bytes*, *kilobytes*, - and *megabytes*, respectively. Only the first character is - significant, so the full word can also be used." + *b*, *k*, *m*, *g*, and *t* can be appended to specify *bytes*, + *kilobytes*, *megabytes*, *gigabytes*, and *terabytes*, respectively. + Only the first character is significant, so the full word can also + be used." @@sizeconvertors = { :b => 0, :k => 1, :m => 2, - :g => 3 + :g => 3, + :t => 4 } def convert(unit, multi) @@ -207,7 +209,9 @@ Puppet::Type.newtype(:tidy) do [] end - @depthfirst = true + def depthfirst? + true + end def initialize(hash) super @@ -236,10 +240,6 @@ Puppet::Type.newtype(:tidy) do [] end - def eval_generate - [] - end - def generate return [] unless stat(self[:path]) @@ -252,7 +252,7 @@ Puppet::Type.newtype(:tidy) do if parameter files = Puppet::FileServing::Fileset.new(self[:path], parameter).files.collect do |f| - f == "." ? self[:path] : File.join(self[:path], f) + f == "." ? self[:path] : ::File.join(self[:path], f) end else files = [self[:path]] @@ -268,7 +268,7 @@ Puppet::Type.newtype(:tidy) do files_by_name = result.inject({}) { |hash, file| hash[file[:path]] = file; hash } files_by_name.keys.sort { |a,b| b <=> b }.each do |path| - dir = File.dirname(path) + dir = ::File.dirname(path) next unless resource = files_by_name[dir] if resource[:require] resource[:require] << Puppet::Resource.new(:file, path) @@ -319,7 +319,7 @@ Puppet::Type.newtype(:tidy) do def stat(path) begin - File.lstat(path) + ::File.lstat(path) rescue Errno::ENOENT => error info "File does not exist" return nil diff --git a/lib/puppet/type/user.rb b/lib/puppet/type/user.rb index f74e4266f..767959308 100755 --- a/lib/puppet/type/user.rb +++ b/lib/puppet/type/user.rb @@ -13,7 +13,7 @@ module Puppet This resource type uses the prescribed native tools for creating groups and generally uses POSIX APIs for retrieving information about them. It does not directly modify `/etc/passwd` or anything. - + **Autorequires:** If Puppet is managing the user's primary group (as provided in the `gid` attribute), the user resource will autorequire that group. If Puppet is managing any role accounts corresponding to the user's roles, the user resource will autorequire those role accounts." feature :allows_duplicates, @@ -39,6 +39,9 @@ module Puppet feature :system_users, "The provider allows you to create system users with lower UIDs." + feature :manages_aix_lam, + "The provider can manage AIX Loadable Authentication Module (LAM) system." + newproperty(:ensure, :parent => Puppet::Property::Ensure) do newvalue(:present, :event => :user_created) do provider.create @@ -445,5 +448,39 @@ module Puppet newproperty(:project, :required_features => :manages_solaris_rbac) do desc "The name of the project associated with a user" end + + newparam(:ia_load_module, :required_features => :manages_aix_lam) do + desc "The name of the I&A module to use to manage this user" + + defaultto "compat" + end + + newproperty(:attributes, :parent => Puppet::Property::KeyValue, :required_features => :manages_aix_lam) do + desc "Specify user AIX attributes in an array of keyvalue pairs" + + def membership + :attribute_membership + end + + def delimiter + " " + end + + validate do |value| + raise ArgumentError, "Attributes value pairs must be seperated by an =" unless value.include?("=") + end + end + + newparam(:attribute_membership) do + desc "Whether specified attribute value pairs should be treated as the only attributes + of the user or whether they should merely + be treated as the minimum list." + + newvalues(:inclusive, :minimum) + + defaultto :minimum + end + + end end diff --git a/lib/puppet/type/whit.rb b/lib/puppet/type/whit.rb index 55bfcfb46..55ed0386e 100644 --- a/lib/puppet/type/whit.rb +++ b/lib/puppet/type/whit.rb @@ -6,6 +6,12 @@ Puppet::Type.newtype(:whit) do end def to_s - "Class[#{name}]" + "(#{name})" + end + + def refresh + # We don't do anything with them, but we need this to + # show that we are "refresh aware" and not break the + # chain of propogation. end end diff --git a/lib/puppet/type/zfs.rb b/lib/puppet/type/zfs.rb index 6f04bddd8..75f821787 100755..100644 --- a/lib/puppet/type/zfs.rb +++ b/lib/puppet/type/zfs.rb @@ -10,32 +10,124 @@ module Puppet desc "The full name for this filesystem. (including the zpool)" end - newproperty(:mountpoint) do - desc "The mountpoint property." + newproperty(:aclinherit) do + desc "The aclinherit property. Values: discard | noallow | restricted | passthrough | passthrough-x" + end + + newproperty(:aclmode) do + desc "The aclmode property. Values: discard | groupmask | passthrough" + end + + newproperty(:atime) do + desc "The atime property. Values: on | off" + end + + newproperty(:canmount) do + desc "The canmount property. Values: on | off | noauto" + end + + newproperty(:checksum) do + desc "The checksum property. Values: on | off | fletcher2 | fletcher4 | sha256" end newproperty(:compression) do - desc "The compression property." + desc "The compression property. Values: on | off | lzjb | gzip | gzip-[1-9] | zle" end newproperty(:copies) do - desc "The copies property." + desc "The copies property. Values: 1 | 2 | 3" + end + + newproperty(:devices) do + desc "The devices property. Values: on | off" + end + + newproperty(:exec) do + desc "The exec property. Values: on | off" + end + + newproperty(:logbias) do + desc "The logbias property. Values: latency | throughput" + end + + newproperty(:mountpoint) do + desc "The mountpoint property. Values: <path> | legacy | none" + end + + newproperty(:nbmand) do + desc "The nbmand property. Values: on | off" + end + + newproperty(:primarycache) do + desc "The primarycache property. Values: all | none | metadata" end newproperty(:quota) do - desc "The quota property." + desc "The quota property. Values: <size> | none" + end + + newproperty(:readonly) do + desc "The readonly property. Values: on | off" + end + + newproperty(:recordsize) do + desc "The recordsize property. Values: 512 to 128k, power of 2" + end + + newproperty(:refquota) do + desc "The refquota property. Values: <size> | none" + end + + newproperty(:refreservation) do + desc "The refreservation property. Values: <size> | none" end newproperty(:reservation) do - desc "The reservation property." + desc "The reservation property. Values: <size> | none" + end + + newproperty(:secondarycache) do + desc "The secondarycache property. Values: all | none | metadata" + end + + newproperty(:setuid) do + desc "The setuid property. Values: on | off" + end + + newproperty(:shareiscsi) do + desc "The shareiscsi property. Values: on | off | type=<type>" end newproperty(:sharenfs) do - desc "The sharenfs property." + desc "The sharenfs property. Values: on | off | share(1M) options" + end + + newproperty(:sharesmb) do + desc "The sharesmb property. Values: on | off | sharemgr(1M) options" end newproperty(:snapdir) do - desc "The snapdir property." + desc "The snapdir property. Values: hidden | visible" + end + + newproperty(:version) do + desc "The version property. Values: 1 | 2 | 3 | 4 | current" + end + + newproperty(:volsize) do + desc "The volsize property. Values: <size>" + end + + newproperty(:vscan) do + desc "The vscan property. Values: on | off" + end + + newproperty(:xattr) do + desc "The xattr property. Values: on | off" + end + + newproperty(:zoned) do + desc "The zoned property. Values: on | off" end autorequire(:zpool) do diff --git a/lib/puppet/type/zone.rb b/lib/puppet/type/zone.rb index 471619c98..0fc702ccf 100644 --- a/lib/puppet/type/zone.rb +++ b/lib/puppet/type/zone.rb @@ -284,6 +284,33 @@ Puppet::Type.newtype(:zone) do end end + newproperty(:dataset, :parent => ZoneMultiConfigProperty) do + desc "The list of datasets delegated to the non global zone from the + global zone. All datasets must be zfs filesystem names which is + different than the mountpoint." + + validate do |value| + unless value !~ /^\// + raise ArgumentError, "Datasets must be the name of a zfs filesystem" + end + end + + # Add a zfs filesystem to our list of datasets. + def add(dataset) + "add dataset\nset name=#{dataset}\nend" + end + + # Remove a zfs filesystem from our list of datasets. + def rm(dataset) + "remove dataset name=#{dataset}" + end + + def should + @should + end + end + + newproperty(:inherit, :parent => ZoneMultiConfigProperty) do desc "The list of directories that the zone inherits from the global zone. All directories must be fully qualified." @@ -382,12 +409,29 @@ Puppet::Type.newtype(:zone) do # both as prerequisites. autorequire(:file) do if @parameters.include? :path - [@parameters[:path].value, File.dirname(@parameters[:path].value)] + [@parameters[:path].value, ::File.dirname(@parameters[:path].value)] else nil end end + # If Puppet is also managing the zfs filesystem which is the zone dataset + # then list it as a prerequisite. Zpool's get autorequired by the zfs + # type. We just need to autorequire the dataset zfs itself as the zfs type + # will autorequire all of the zfs parents and zpool. + autorequire(:zfs) do + + # Check if we have datasets in our zone configuration + if @parameters.include? :dataset + reqs = [] + # Autorequire each dataset + self[:dataset].each { |value| + reqs << value + } + reqs + end + end + def validate_ip(ip, name) IPAddr.new(ip) if ip rescue ArgumentError diff --git a/lib/puppet/type/zpool.rb b/lib/puppet/type/zpool.rb index 40ee8f286..2da713c2b 100755 --- a/lib/puppet/type/zpool.rb +++ b/lib/puppet/type/zpool.rb @@ -4,6 +4,7 @@ module Puppet class VDev < Property def flatten_and_sort(array) + array = [array] unless array.is_a? Array array.collect { |a| a.split(' ') }.flatten.sort end diff --git a/lib/puppet/util/classgen.rb b/lib/puppet/util/classgen.rb index ed69c5878..1e99aa873 100644 --- a/lib/puppet/util/classgen.rb +++ b/lib/puppet/util/classgen.rb @@ -124,11 +124,23 @@ module Puppet::Util::ClassGen klass end + # const_defined? in Ruby 1.9 behaves differently in terms + # of which class hierarchy it polls for nested namespaces + # + # See http://redmine.ruby-lang.org/issues/show/1915 + def is_constant_defined?(const) + if ::RUBY_VERSION =~ /1.9/ + const_defined?(const, false) + else + const_defined?(const) + end + end + # Handle the setting and/or removing of the associated constant. def handleclassconst(klass, name, options) const = genconst_string(name, options) - if const_defined?(const) + if is_constant_defined?(const) if options[:overwrite] Puppet.info "Redefining #{name} in #{self}" remove_const(const) diff --git a/lib/puppet/util/command_line/filebucket b/lib/puppet/util/command_line/filebucket deleted file mode 100755 index 34b01508e..000000000 --- a/lib/puppet/util/command_line/filebucket +++ /dev/null @@ -1,97 +0,0 @@ -#!/usr/bin/env ruby - -# -# = Synopsis -# -# A stand-alone Puppet filebucket client. -# -# = Usage -# -# puppet filebucket [-h|--help] [-V|--version] [-d|--debug] [-v|--verbose] -# [-l|--local] [-r|--remote] -# [-s|--server <server>] [-b|--bucket <directory>] <file> <file> ... -# -# = Description -# -# This is a stand-alone filebucket client for sending files to a local -# or central filebucket. -# -# = Usage -# -# This client can operate in three modes, with only one mode per call: -# -# backup:: -# Send one or more files to the specified file bucket. Each sent file -# is printed with its resulting md5 sum. -# -# get:: -# Return the text associated with an md5 sum. The text is printed to -# stdout, and only one file can be retrieved at a time. -# -# restore:: -# Given a file path and an md5 sum, store the content associated with the -# sum into the specified file path. You can specify an entirely new path -# to this argument; you are not restricted to restoring the content to its -# original location. -# -# Note that +filebucket+ defaults to using a network-based filebucket available on -# the server named +puppet+. To use this, you'll have to be running as a user -# with valid Puppet certificates. Alternatively, you can use your local file bucket -# by specifying +--local+. -# -# = Example -# -# $ puppet filebucket backup /etc/passwd -# /etc/passwd: 429b225650b912a2ee067b0a4cf1e949 -# $ puppet filebucket restore /tmp/passwd 429b225650b912a2ee067b0a4cf1e949 -# $ -# -# = Options -# -# Note that any configuration parameter that's valid in the configuration file -# is also a valid long argument. For example, 'ssldir' is a valid configuration -# parameter, so you can specify '--ssldir <directory>' as an argument. -# -# See the configuration file documentation at -# http://docs.puppetlabs.com/references/stable/configuration.html for -# the full list of acceptable parameters. A commented list of all -# configuration options can also be generated by running puppet with -# '--genconfig'. -# -# debug:: -# Enable full debugging. -# -# help:: -# Print this help message -# -# local:: -# Use the local filebucket. This will use the default configuration -# information. -# -# remote:: -# Use a remote filebucket. This will use the default configuration -# information. -# -# server:: -# The server to send the file to, instead of locally. -# -# verbose:: -# Print extra information. -# -# version:: -# Print version information. -# -# = Example -# -# puppet filebucket -b /tmp/filebucket /my/file -# -# = Author -# -# Luke Kanies -# -# = Copyright -# -# Copyright (c) 2005 Puppet Labs, LLC -# Licensed under the GNU Public License - -#Puppet::Application[:filebucket].run diff --git a/lib/puppet/util/command_line/pi b/lib/puppet/util/command_line/pi deleted file mode 100755 index 3d80eea8f..000000000 --- a/lib/puppet/util/command_line/pi +++ /dev/null @@ -1,48 +0,0 @@ -#!/usr/bin/env ruby - -# -# = Synopsis -# -# Print help about puppet types on the console. Run with '-h' to get detailed -# help. -# = Usage -# -# puppet describe [-h|--help] [-s|--short] [-p|--providers] [-l|--list] [-m|--meta] -# -# = Description -# -# Prints details of Puppet types, providers and metaparameters on the console. -# -# = Options -# -# help:: -# Print this help text -# -# providers:: -# Describe providers in detail for each type -# -# list:: -# List all types -# -# meta:: -# List all metaparameters -# -# short:: -# List only parameters without detail -# -# = Example -# -# puppet describe --list -# puppet describe file --providers -# puppet describe user -s -m -# -# = Author -# -# David Lutterkort -# -# = Copyright -# -# Copyright (c) 2005 Puppet Labs, LLC -# Licensed under the GNU Public License - -#Puppet::Application[:describe].run diff --git a/lib/puppet/util/command_line/puppet b/lib/puppet/util/command_line/puppet deleted file mode 100755 index ba3d57c19..000000000 --- a/lib/puppet/util/command_line/puppet +++ /dev/null @@ -1,73 +0,0 @@ - -# -# = Synopsis -# -# Run a stand-alone +puppet+ manifest. -# -# = Usage -# -# puppet apply [-h|--help] [-V|--version] [-d|--debug] [-v|--verbose] [-e|--execute] -# [--detailed-exitcodes] [-l|--logdest <file>] [--apply catalog] <file> -# -# = Description -# -# This is the standalone puppet execution tool; use it to execute -# individual manifests that you write. If you need to execute site-wide -# manifests, use 'puppet agent' and 'puppet master'. -# -# = Options -# -# Note that any configuration parameter that's valid in the configuration file -# is also a valid long argument. For example, 'ssldir' is a valid configuration -# parameter, so you can specify '--ssldir <directory>' as an argument. -# -# See the configuration file documentation at -# http://docs.puppetlabs.com/references/stable/configuration.html for -# the full list of acceptable parameters. A commented list of all -# configuration options can also be generated by running puppet with -# '--genconfig'. -# -# debug:: -# Enable full debugging. -# -# detailed-exitcodes:: -# Provide transaction information via exit codes. If this is enabled, an exit -# code of '2' means there were changes, and an exit code of '4' means that there -# were failures during the transaction. -# -# help:: -# Print this help message -# -# loadclasses:: -# Load any stored classes. 'puppet agent' caches configured classes (usually at -# /etc/puppet/classes.txt), and setting this option causes all of those classes -# to be set in your puppet manifest. -# -# logdest:: -# Where to send messages. Choose between syslog, the console, and a log file. -# Defaults to sending messages to the console. -# -# execute:: -# Execute a specific piece of Puppet code -# -# verbose:: -# Print extra information. -# -# apply:: -# Capability to apply JSON catalog (such as one generated with --compile on the Puppet master). -# You can either specify a JSON catalog file or pipe in JSON from standard input. -# -# = Example -# -# puppet -l /tmp/manifest.log manifest.pp -# -# = Author -# -# Luke Kanies -# -# = Copyright -# -# Copyright (c) 2005 Puppet Labs, LLC -# Licensed under the GNU Public License - -#Puppet::Application[:apply].run diff --git a/lib/puppet/util/command_line/puppetca b/lib/puppet/util/command_line/puppetca deleted file mode 100755 index 317d99881..000000000 --- a/lib/puppet/util/command_line/puppetca +++ /dev/null @@ -1,110 +0,0 @@ -#!/usr/bin/env ruby - -# -# = Synopsis -# -# Stand-alone certificate authority. Capable of generating certificates -# but mostly meant for signing certificate requests from puppet clients. -# -# = Usage -# -# puppet cert [-h|--help] [-V|--version] [-d|--debug] [-v|--verbose] -# [-g|--generate] [-l|--list] [-s|--sign] [-r|--revoke] -# [-p|--print] [-c|--clean] [--verify] [--digest DIGEST] -# [--fingerprint] [host] -# -# = Description -# -# Because the puppetmasterd daemon defaults to not signing client certificate -# requests, this script is available for signing outstanding requests. It -# can be used to list outstanding requests and then either sign them individually -# or sign all of them. -# -# = Options -# -# Note that any configuration parameter that's valid in the configuration file -# is also a valid long argument. For example, 'ssldir' is a valid configuration -# parameter, so you can specify '--ssldir <directory>' as an argument. -# -# See the configuration file documentation at -# http://docs.puppetlabs.com/references/stable/configuration.html for -# the full list of acceptable parameters. A commented list of all -# configuration options can also be generated by running puppet cert with -# '--genconfig'. -# -# all:: -# Operate on all items. Currently only makes sense with '--sign', -# '--clean', or '--list'. -# -# digest:: -# Set the digest for fingerprinting (defaults to md5). Valid values depends -# on your openssl and openssl ruby extension version, but should contain at -# least md5, sha1, md2, sha256. -# -# clean:: -# Remove all files related to a host from puppet cert's storage. This is -# useful when rebuilding hosts, since new certificate signing requests -# will only be honored if puppet cert does not have a copy of a signed -# certificate for that host. The certificate of the host is also revoked. -# If '--all' is specified then all host certificates, both signed and -# unsigned, will be removed. -# -# debug:: -# Enable full debugging. -# -# generate:: -# Generate a certificate for a named client. A certificate/keypair will be -# generated for each client named on the command line. -# -# help:: -# Print this help message -# -# list:: -# List outstanding certificate requests. If '--all' is specified, -# signed certificates are also listed, prefixed by '+', and revoked -# or invalid certificates are prefixed by '-' (the verification outcome -# is printed in parenthesis). -# -# print:: -# Print the full-text version of a host's certificate. -# -# fingerprint:: -# Print the DIGEST (defaults to md5) fingerprint of a host's certificate. -# -# revoke:: -# Revoke the certificate of a client. The certificate can be specified -# either by its serial number, given as a decimal number or a hexadecimal -# number prefixed by '0x', or by its hostname. The certificate is revoked -# by adding it to the Certificate Revocation List given by the 'cacrl' -# config parameter. Note that the puppetmasterd needs to be restarted -# after revoking certificates. -# -# sign:: -# Sign an outstanding certificate request. Unless '--all' is specified, -# hosts must be listed after all flags. -# -# verbose:: -# Enable verbosity. -# -# version:: -# Print the puppet version number and exit. -# -# verify:: -# Verify the named certificate against the local CA certificate. -# -# = Example -# -# $ puppet cert -l -# culain.madstop.com -# $ puppet cert -s culain.madstop.com -# -# = Author -# -# Luke Kanies -# -# = Copyright -# -# Copyright (c) 2005 Puppet Labs, LLC -# Licensed under the GNU Public License - -#Puppet::Application[:cert].run diff --git a/lib/puppet/util/command_line/puppetd b/lib/puppet/util/command_line/puppetd deleted file mode 100755 index b4eafb483..000000000 --- a/lib/puppet/util/command_line/puppetd +++ /dev/null @@ -1,188 +0,0 @@ -#!/usr/bin/env ruby - -# == Synopsis -# -# Retrieve the client configuration from the puppet master and apply -# it to the local host. -# -# Currently must be run out periodically, using cron or something similar. -# -# = Usage -# -# puppet agent [-D|--daemonize|--no-daemonize] [-d|--debug] -# [--detailed-exitcodes] [--disable] [--enable] -# [-h|--help] [--certname <host name>] [-l|--logdest syslog|<file>|console] -# [-o|--onetime] [--serve <handler>] [-t|--test] [--noop] -# [--digest <digest>] [--fingerprint] [-V|--version] -# [-v|--verbose] [-w|--waitforcert <seconds>] -# -# = Description -# -# This is the main puppet client. Its job is to retrieve the local machine's -# configuration from a remote server and apply it. In order to successfully -# communicate with the remote server, the client must have a certificate signed -# by a certificate authority that the server trusts; the recommended method -# for this, at the moment, is to run a certificate authority as part of the -# puppet server (which is the default). The client will connect and request -# a signed certificate, and will continue connecting until it receives one. -# -# Once the client has a signed certificate, it will retrieve its configuration -# and apply it. -# -# = Usage Notes -# -# +puppet agent+ does its best to find a compromise between interactive use and -# daemon use. Run with no arguments and no configuration, it will go into the -# backgroun, attempt to get a signed certificate, and retrieve and apply its -# configuration every 30 minutes. -# -# Some flags are meant specifically for interactive use -- in particular, -# +test+, +tags+ or +fingerprint+ are useful. +test+ enables verbose logging, causes -# the daemon to stay in the foreground, exits if the server's configuration is -# invalid (this happens if, for instance, you've left a syntax error on the -# server), and exits after running the configuration once (rather than hanging -# around as a long-running process). -# -# +tags+ allows you to specify what portions of a configuration you want to apply. -# Puppet elements are tagged with all of the class or definition names that -# contain them, and you can use the +tags+ flag to specify one of these names, -# causing only configuration elements contained within that class or definition -# to be applied. This is very useful when you are testing new configurations -- -# for instance, if you are just starting to manage +ntpd+, you would put all of -# the new elements into an +ntpd+ class, and call puppet with +--tags ntpd+, -# which would only apply that small portion of the configuration during your -# testing, rather than applying the whole thing. -# -# +fingerprint+ is a one-time flag. In this mode +puppet agent+ will run once and -# display on the console (and in the log) the current certificate (or certificate -# request) fingerprint. Providing the +--digest+ option allows to use a different -# digest algorithm to generate the fingerprint. The main use is to verify that -# before signing a certificate request on the master, the certificate request the -# master received is the same as the one the client sent (to prevent against -# man-in-the-middle attacks when signing certificates). -# -# -# = Options -# -# Note that any configuration parameter that's valid in the configuration file -# is also a valid long argument. For example, 'server' is a valid configuration -# parameter, so you can specify '--server <servername>' as an argument. -# -# See the configuration file documentation at -# http://docs.puppetlabs.com/references/stable/configuration.html for -# the full list of acceptable parameters. A commented list of all -# configuration options can also be generated by running puppet agent with -# '--genconfig'. -# -# daemonize:: -# Send the process into the background. This is the default. -# -# no-daemonize:: -# Do not send the process into the background. -# -# debug:: -# Enable full debugging. -# -# digest:: -# Change the certificate fingerprinting digest algorithm. The default is MD5. -# Valid values depends on the version of OpenSSL installed, but should always -# at least contain MD5, MD2, SHA1 and SHA256. -# -# detailed-exitcodes:: -# Provide transaction information via exit codes. If this is enabled, an -# exit code of '2' means there were changes, and an exit code of '4' means -# that there were failures during the transaction. This option only makes -# sense in conjunction with --onetime. -# -# disable:: -# Disable working on the local system. This puts a lock file in place, -# causing +puppet agent+ not to work on the system until the lock file is removed. -# This is useful if you are testing a configuration and do not want the central -# configuration to override the local state until everything is tested and -# committed. -# -# +puppet agent+ uses the same lock file while it is running, so no more than one -# +puppet agent+ process is working at a time. -# -# +puppet agent+ exits after executing this. -# -# enable:: -# Enable working on the local system. This removes any lock file, causing -# +puppet agent+ to start managing the local system again (although it will continue -# to use its normal scheduling, so it might not start for another half hour). -# -# +puppet agent+ exits after executing this. -# -# certname:: -# Set the certname (unique ID) of the client. The master reads this unique -# identifying string, which is usually set to the node's fully-qualified domain -# name, to determine which configurations the node will receive. Use this option -# to debug setup problems or implement unusual node identification schemes. -# -# help:: -# Print this help message -# -# logdest:: -# Where to send messages. Choose between syslog, the console, and a log file. -# Defaults to sending messages to syslog, or the console if debugging or -# verbosity is enabled. -# -# no-client:: -# Do not create a config client. This will cause the daemon to run -# without ever checking for its configuration automatically, and only -# makes sense when used in conjunction with --listen. -# -# onetime:: -# Run the configuration once. Runs a single (normally daemonized) Puppet run. -# Useful for interactively running puppet agent when used in conjunction with -# the --no-daemonize option. -# -# fingerprint:: -# Display the current certificate or certificate signing request fingerprint -# and then exit. Use the +--digest+ option to change the digest algorithm used. -# -# serve:: -# Start another type of server. By default, +puppet agent+ will start -# a service handler that allows authenticated and authorized remote nodes to -# trigger the configuration to be pulled down and applied. You can specify -# any handler here that does not require configuration, e.g., filebucket, ca, -# or resource. The handlers are in +lib/puppet/network/handler+, and the names -# must match exactly, both in the call to +serve+ and in +namespaceauth.conf+. -# -# test:: -# Enable the most common options used for testing. These are +onetime+, -# +verbose+, +ignorecache, +no-daemonize+, +no-usecacheonfailure+, -# +detailed-exit-codes+, +no-splay+, and +show_diff+. -# -# noop:: -# Use +noop+ mode where the daemon runs in a no-op or dry-run mode. This is useful -# for seeing what changes Puppet will make without actually executing the changes. -# -# verbose:: -# Turn on verbose reporting. -# -# version:: -# Print the puppet version number and exit. -# -# waitforcert:: -# This option only matters for daemons that do not yet have certificates -# and it is enabled by default, with a value of 120 (seconds). This causes -# +puppet agent+ to connect to the server every 2 minutes and ask it to sign a -# certificate request. This is useful for the initial setup of a puppet -# client. You can turn off waiting for certificates by specifying a time -# of 0. -# -# = Example -# -# puppet agent --server puppet.domain.com -# -# = Author -# -# Luke Kanies -# -# = Copyright -# -# Copyright (c) 2005, 2006 Puppet Labs, LLC -# Licensed under the GNU Public License - -#Puppet::Application[:agent].run diff --git a/lib/puppet/util/command_line/puppetdoc b/lib/puppet/util/command_line/puppetdoc deleted file mode 100755 index 45a9c6518..000000000 --- a/lib/puppet/util/command_line/puppetdoc +++ /dev/null @@ -1,67 +0,0 @@ -#!/usr/bin/env ruby - -# -# = Synopsis -# -# Generate a reference for all Puppet types. Largely meant for internal Puppet -# Labs use. -# -# = Usage -# -# puppet doc [-a|--all] [-h|--help] [-o|--outputdir <rdoc outputdir>] [-m|--mode <text|pdf|rdoc>] -# [-r|--reference <[type]|configuration|..>] [--charset CHARSET] [manifest-file] -# -# = Description -# -# If mode is not 'rdoc', then this command generates a Markdown document describing all installed -# Puppet types or all allowable arguments to puppet executables. It is largely -# meant for internal use and is used to generate the reference document -# available on the Puppet Labs web site. -# -# In 'rdoc' mode, this command generates an html RDoc hierarchy describing the manifests that -# are in 'manifestdir' and 'modulepath' configuration directives. -# The generated documentation directory is doc by default but can be changed with the 'outputdir' option. -# -# If the command is started with 'manifest-file' command-line arguments, puppet doc generate a single -# manifest documentation that is output on stdout. -# -# = Options -# -# all:: -# Output the docs for all of the reference types. In 'rdoc' modes, this also outputs documentation for all resources -# -# help:: -# Print this help message -# -# outputdir:: -# Specifies the directory where to output the rdoc documentation in 'rdoc' mode. -# -# mode:: -# Determine the output mode. Valid modes are 'text', 'pdf' and 'rdoc'. The 'pdf' mode creates PDF formatted files in the /tmp directory. The default mode is 'text'. In 'rdoc' mode you must provide 'manifests-path' -# -# reference:: -# Build a particular reference. Get a list of references by running +puppet doc --list+. -# -# charset:: -# Used only in 'rdoc' mode. It sets the charset used in the html files produced. -# -# = Example -# -# $ puppet doc -r type > /tmp/type_reference.markdown -# or -# $ puppet doc --outputdir /tmp/rdoc --mode rdoc /path/to/manifests -# or -# $ puppet doc /etc/puppet/manifests/site.pp -# or -# $ puppet doc -m pdf -r configuration -# -# = Author -# -# Luke Kanies -# -# = Copyright -# -# Copyright (c) 2005-2007 Puppet Labs, LLC -# Licensed under the GNU Public License - -#Puppet::Application[:doc].run diff --git a/lib/puppet/util/command_line/puppetmasterd b/lib/puppet/util/command_line/puppetmasterd deleted file mode 100755 index 3b76db82b..000000000 --- a/lib/puppet/util/command_line/puppetmasterd +++ /dev/null @@ -1,70 +0,0 @@ -#!/usr/bin/env ruby - -# -# = Synopsis -# -# The central puppet server. Functions as a certificate authority by default. -# -# = Usage -# -# puppet master [-D|--daemonize|--no-daemonize] [-d|--debug] [-h|--help] -# [-l|--logdest <file>|console|syslog] [-v|--verbose] [-V|--version] -# [--compile <nodename>] -# -# = Description -# -# This is the puppet central daemon. -# -# = Options -# -# Note that any configuration parameter that's valid in the configuration file -# is also a valid long argument. For example, 'ssldir' is a valid configuration -# parameter, so you can specify '--ssldir <directory>' as an argument. -# -# See the configuration file documentation at -# http://docs.puppetlabs.com/references/stable/configuration.html for -# the full list of acceptable parameters. A commented list of all -# configuration options can also be generated by running puppetmasterdd with -# '--genconfig'. -# -# daemonize:: -# Send the process into the background. This is the default. -# -# no-daemonize:: -# Do not send the process into the background. -# -# debug:: -# Enable full debugging. -# -# help:: -# Print this help message. -# -# logdest:: -# Where to send messages. Choose between syslog, the console, and a log file. -# Defaults to sending messages to syslog, or the console -# if debugging or verbosity is enabled. -# -# verbose:: -# Enable verbosity. -# -# version:: -# Print the puppet version number and exit. -# -# compile:: -# Capability to compile a catalogue and output it in JSON from the Puppet master. Uses -# facts contained in the $vardir/yaml/ directory to compile the catalog. -# -# = Example -# -# puppet master -# -# = Author -# -# Luke Kanies -# -# = Copyright -# -# Copyright (c) 2005 Puppet Labs, LLC -# Licensed under the GNU Public License - -#Puppet::Application[:master].run diff --git a/lib/puppet/util/command_line/puppetqd b/lib/puppet/util/command_line/puppetqd deleted file mode 100755 index 81963d537..000000000 --- a/lib/puppet/util/command_line/puppetqd +++ /dev/null @@ -1,53 +0,0 @@ -#!/usr/bin/env ruby - -# == Synopsis -# -# Retrieve serialized records from a queue and process them in order. -# -# = Usage -# -# puppet queue [-d|--debug] [-v|--verbose] -# -# = Description -# -# This is a simple application that just processes entities in a queue as they -# are recieved. -# -# = Options -# -# Note that any configuration parameter that's valid in the configuration file -# is also a valid long argument. For example, 'server' is a valid configuration -# parameter, so you can specify '--server <servername>' as an argument. -# -# See the configuration file documentation at -# http://docs.puppetlabs.com/references/stable/configuration.html for -# the full list of acceptable parameters. A commented list of all -# configuration options can also be generated by running puppetd with -# '--genconfig'. -# -# debug:: -# Enable full debugging. -# -# help:: -# Print this help message -# -# verbose:: -# Turn on verbose reporting. -# -# version:: -# Print the puppet version number and exit. -# -# = Example -# -# puppet queue -# -# = Author -# -# Luke Kanies -# -# = Copyright -# -# Copyright (c) 2009 Puppet Labs, LLC -# Licensed under the GNU Public License - -#Puppet::Application[:queue].run diff --git a/lib/puppet/util/command_line/puppetrun b/lib/puppet/util/command_line/puppetrun deleted file mode 100755 index 3437405b0..000000000 --- a/lib/puppet/util/command_line/puppetrun +++ /dev/null @@ -1,125 +0,0 @@ -#!/usr/bin/env ruby - -# -# = Synopsis -# -# Trigger a puppet agent run on a set of hosts. -# -# = Usage -# -# puppet kick [-a|--all] [-c|--class <class>] [-d|--debug] [-f|--foreground] -# [-h|--help] [--host <host>] [--no-fqdn] [--ignoreschedules] -# [-t|--tag <tag>] [--test] [-p|--ping] <host> [<host> [...]] -# -# = Description -# -# This script can be used to connect to a set of machines running +puppet agent+ -# and trigger them to run their configurations. The most common usage would -# be to specify a class of hosts and a set of tags, and +puppet kick+ would -# look up in LDAP all of the hosts matching that class, then connect to -# each host and trigger a run of all of the objects with the specified tags. -# -# If you are not storing your host configurations in LDAP, you can specify -# hosts manually. -# -# You will most likely have to run +puppet kick+ as root to get access to -# the SSL certificates. -# -# +puppet kick+ reads +puppet master+'s configuration file, so that it can copy -# things like LDAP settings. -# -# = Usage Notes -# -# +puppet kick+ is useless unless +puppet agent+ is listening. See its documentation -# for more information, but the gist is that you must enable +listen+ on the -# +puppet agent+ daemon, either using +--listen+ on the command line or adding -# 'listen: true' in its config file. In addition, you need to set the daemons -# up to specifically allow connections by creating the +namespaceauth+ file, -# normally at '/etc/puppet/namespaceauth.conf'. This file specifies who has -# access to each namespace; if you create the file you must add every namespace -# you want any Puppet daemon to allow -- it is currently global to all Puppet -# daemons. -# -# An example file looks like this:: -# -# [fileserver] -# allow *.madstop.com -# -# [puppetmaster] -# allow *.madstop.com -# -# [puppetrunner] -# allow culain.madstop.com -# -# This is what you would install on your Puppet master; non-master hosts could -# leave off the 'fileserver' and 'puppetmaster' namespaces. -# -# = Options -# -# Note that any configuration parameter that's valid in the configuration file -# is also a valid long argument. For example, 'ssldir' is a valid configuration -# parameter, so you can specify '--ssldir <directory>' as an argument. -# -# See the configuration file documentation at -# http://reductivelabs.com/projects/puppet/reference/configref.html for -# the full list of acceptable parameters. A commented list of all -# configuration options can also be generated by running puppet master with -# '--genconfig'. -# -# -# all:: -# Connect to all available hosts. Requires LDAP support at this point. -# -# class:: -# Specify a class of machines to which to connect. This only works if you -# have LDAP configured, at the moment. -# -# debug:: -# Enable full debugging. -# -# foreground:: -# Run each configuration in the foreground; that is, when connecting to a host, -# do not return until the host has finished its run. The default is false. -# -# help:: -# Print this help message -# -# host:: -# A specific host to which to connect. This flag can be specified more -# than once. -# -# ignoreschedules:: -# Whether the client should ignore schedules when running its configuration. -# This can be used to force the client to perform work it would not normally -# perform so soon. The default is false. -# -# parallel:: -# How parallel to make the connections. Parallelization is provided by forking -# for each client to which to connect. The default is 1, meaning serial execution. -# -# tag:: -# Specify a tag for selecting the objects to apply. Does not work with the -# --test option. -# -# -# test:: -# Print the hosts you would connect to but do not actually connect. This -# option requires LDAP support at this point. -# -# ping:: -# Do a ICMP echo against the target host. Skip hosts that don't respond to ping. -# -# = Example -# -# sudo puppet kick -p 10 -t remotefile -t webserver host1 host2 -# -# = Author -# -# Luke Kanies -# -# = Copyright -# -# Copyright (c) 2005 Puppet Labs, LLC -# Licensed under the GNU Public License - -#Puppet::Application[:kick].run diff --git a/lib/puppet/util/command_line/ralsh b/lib/puppet/util/command_line/ralsh deleted file mode 100755 index 5c1f719e2..000000000 --- a/lib/puppet/util/command_line/ralsh +++ /dev/null @@ -1,89 +0,0 @@ -#!/usr/bin/env ruby - -# -# = Synopsis -# -# Use the Puppet RAL to directly interact with the system. -# -# = Usage -# -# puppet resource [-h|--help] [-d|--debug] [-v|--verbose] [-e|--edit] -# [-H|--host <host>] [-p|--param <param>] [-t|--types] -# type <name> -# -# = Description -# -# This command provides simple facilities for converting current system state -# into Puppet code, along with some ability to use Puppet to affect the current -# state. -# -# By default, you must at least provide a type to list, which case puppet resource -# will tell you everything it knows about all instances of that type. You can -# optionally specify an instance name, and puppet resource will only describe that single -# instance. -# -# You can also add +--edit+ as an argument, and puppet resource will write its output -# to a file, open that file in an editor, and then apply the file as a Puppet -# transaction. You can easily use this to use Puppet to make simple changes to -# a system. -# -# = Options -# -# Note that any configuration parameter that's valid in the configuration file -# is also a valid long argument. For example, 'ssldir' is a valid configuration -# parameter, so you can specify '--ssldir <directory>' as an argument. -# -# See the configuration file documentation at -# http://docs.puppetlabs.com/references/stable/configuration.html for -# the full list of acceptable parameters. A commented list of all -# configuration options can also be generated by running puppet with -# '--genconfig'. -# -# debug:: -# Enable full debugging. -# -# edit: -# Write the results of the query to a file, open the file in an editor, -# and read the file back in as an executable Puppet manifest. -# -# host: -# When specified, connect to the resource server on the named host -# and retrieve the list of resouces of the type specified. -# -# help: -# Print this help message. -# -# param: -# Add more parameters to be outputted from queries. -# -# types: -# List all available types. -# -# verbose: -# Print extra information. -# -# = Example -# -# This example uses `puppet resource` to return Puppet configuration for the user `luke`: -# -# $ puppet resource user luke -# user { 'luke': -# home => '/home/luke', -# uid => '100', -# ensure => 'present', -# comment => 'Luke Kanies,,,', -# gid => '1000', -# shell => '/bin/bash', -# groups => ['sysadmin','audio','video','puppet'] -# } -# -# = Author -# -# Luke Kanies -# -# = Copyright -# -# Copyright (c) 2005-2007 Puppet Labs, LLC -# Licensed under the GNU Public License - -#Puppet::Application[:resource].run diff --git a/lib/puppet/util/log.rb b/lib/puppet/util/log.rb index ba1690078..d34fbaf55 100644 --- a/lib/puppet/util/log.rb +++ b/lib/puppet/util/log.rb @@ -58,6 +58,7 @@ class Puppet::Util::Log destinations.keys.each { |dest| close(dest) } + raise Puppet::DevError.new("Log.close_all failed to close #{@destinations.keys.inspect}") if !@destinations.empty? end # Flush any log destinations that support such operations. diff --git a/lib/puppet/util/log/destinations.rb b/lib/puppet/util/log/destinations.rb index c70edeb02..9550e2c3b 100644 --- a/lib/puppet/util/log/destinations.rb +++ b/lib/puppet/util/log/destinations.rb @@ -96,7 +96,7 @@ Puppet::Util::Log.newdesttype :console do HWHITE = {:console => "[1;37m", :html => "FFFFFF"} RESET = {:console => "[0m", :html => "" } - @@colormap = { + Colormap = { :debug => WHITE, :info => GREEN, :notice => CYAN, @@ -117,11 +117,11 @@ Puppet::Util::Log.newdesttype :console do end def console_color(level, str) - @@colormap[level][:console] + str + RESET[:console] + Colormap[level][:console] + str + RESET[:console] end def html_color(level, str) - %{<span style="color: %s">%s</span>} % [@@colormap[level][:html], str] + %{<span style="color: %s">%s</span>} % [Colormap[level][:html], str] end def initialize @@ -205,8 +205,20 @@ Puppet::Util::Log.newdesttype :report do end # Log to an array, just for testing. +module Puppet::Test + class LogCollector + def initialize(logs) + @logs = logs + end + + def <<(value) + @logs << value + end + end +end + Puppet::Util::Log.newdesttype :array do - match "Array" + match "Puppet::Test::LogCollector" def initialize(messages) @messages = messages diff --git a/lib/puppet/util/monkey_patches.rb b/lib/puppet/util/monkey_patches.rb index 16384855a..a93c66b07 100644 --- a/lib/puppet/util/monkey_patches.rb +++ b/lib/puppet/util/monkey_patches.rb @@ -52,6 +52,13 @@ if RUBY_VERSION == '1.8.7' end class Object + # ActiveSupport 2.3.x mixes in a dangerous method + # that can cause rspec to fork bomb + # and other strange things like that. + def daemonize + raise NotImplementedError, "Kernel.daemonize is too dangerous, please don't try to use it." + end + # The following code allows callers to make assertions that are only # checked when the environment variable PUPPET_ENABLE_ASSERTIONS is # set to a non-empty string. For example: @@ -69,3 +76,17 @@ class Object end end end + +# Workaround for yaml_initialize, which isn't supported before Ruby +# 1.8.3. +if RUBY_VERSION == '1.8.1' || RUBY_VERSION == '1.8.2' + YAML.add_ruby_type( /^object/ ) { |tag, val| + type, obj_class = YAML.read_type_class( tag, Object ) + r = YAML.object_maker( obj_class, val ) + if r.respond_to? :yaml_initialize + r.instance_eval { instance_variables.each { |name| remove_instance_variable name } } + r.yaml_initialize(tag, val) + end + r + } +end diff --git a/lib/puppet/util/rdoc.rb b/lib/puppet/util/rdoc.rb index bdac579d6..c00bc6f85 100644 --- a/lib/puppet/util/rdoc.rb +++ b/lib/puppet/util/rdoc.rb @@ -31,6 +31,7 @@ module Puppet::Util::RDoc options << "--force-update" if Options::OptionList.options.any? { |o| o[0] == "--force-update" } options += [ "--charset", charset] if charset options += files + #TODO dedup file paths (not strict duplication sense, parents, children, etc # launch the documentation process r.document(options) @@ -53,17 +54,10 @@ module Puppet::Util::RDoc # of a manifest def output(file, ast) astobj = [] - ast.nodes.each do |name, k| - astobj << k if k.file == file + ast.instantiate('').each do |resource_type| + astobj << resource_type if resource_type.file == file end - ast.hostclasses.each do |name,k| - astobj << k if k.file == file - end - - ast.definitions.each do |name, k| - astobj << k if k.file == file - end astobj.sort! {|a,b| a.line <=> b.line }.each do |k| output_astnode_doc(k) end @@ -89,4 +83,4 @@ module Puppet::Util::RDoc end end -end
\ No newline at end of file +end diff --git a/lib/puppet/util/rdoc/parser.rb b/lib/puppet/util/rdoc/parser.rb index ea7439ad7..762ce25f0 100644 --- a/lib/puppet/util/rdoc/parser.rb +++ b/lib/puppet/util/rdoc/parser.rb @@ -7,17 +7,23 @@ require "rdoc/code_objects" require "puppet/util/rdoc/code_objects" require "rdoc/tokenstream" -require "rdoc/markup/simple_markup/preprocess" -require "rdoc/parsers/parserfactory" + +if ::RUBY_VERSION =~ /1.9/ + require "rdoc/markup/preprocess" + require "rdoc/parser" +else + require "rdoc/markup/simple_markup/preprocess" + require "rdoc/parsers/parserfactory" +end module RDoc class Parser - extend ParserFactory + extend ParserFactory unless ::RUBY_VERSION =~ /1.9/ SITE = "__site__" - attr_accessor :ast, :input_file_name, :top_level + attr_accessor :input_file_name, :top_level # parser registration into RDoc parse_files_matching(/\.(rb|pp)$/) @@ -33,17 +39,19 @@ class Parser # main entry point def scan - env = Puppet::Node::Environment.new - unless env.known_resource_types.watching_file?(@input_file_name) + environment = Puppet::Node::Environment.new + @known_resource_types = environment.known_resource_types + unless environment.known_resource_types.watching_file?(@input_file_name) Puppet.info "rdoc: scanning #{@input_file_name}" if @input_file_name =~ /\.pp$/ - @parser = Puppet::Parser::Parser.new(env) + @parser = Puppet::Parser::Parser.new(environment) @parser.file = @input_file_name - @ast = @parser.parse + @parser.parse.instantiate('').each do |type| + @known_resource_types.add type + end end - else - @ast = env.known_resource_types end + scan_top_level(@top_level) @top_level end @@ -206,19 +214,21 @@ class Parser if stmt.is_a?(Puppet::Parser::AST::Resource) and !stmt.type.nil? begin type = stmt.type.split("::").collect { |s| s.capitalize }.join("::") - title = stmt.title.is_a?(Puppet::Parser::AST::ASTArray) ? stmt.title.to_s.gsub(/\[(.*)\]/,'\1') : stmt.title.to_s - Puppet.debug "rdoc: found resource: #{type}[#{title}]" + stmt.instances.each do |inst| + title = inst.title.is_a?(Puppet::Parser::AST::ASTArray) ? inst.title.to_s.gsub(/\[(.*)\]/,'\1') : inst.title.to_s + Puppet.debug "rdoc: found resource: #{type}[#{title}]" - param = [] - stmt.parameters.children.each do |p| - res = {} - res["name"] = p.param - res["value"] = "#{p.value.to_s}" unless p.value.nil? + param = [] + inst.parameters.children.each do |p| + res = {} + res["name"] = p.param + res["value"] = "#{p.value.to_s}" unless p.value.nil? - param << res - end + param << res + end - container.add_resource(PuppetResource.new(type, title, stmt.doc, param)) + container.add_resource(PuppetResource.new(type, title, stmt.doc, param)) + end rescue => detail raise Puppet::ParseError, "impossible to parse resource in #{stmt.file} at line #{stmt.line}: #{detail}" end @@ -339,7 +349,8 @@ class Parser # that contains the documentation def parse_elements(container) Puppet.debug "rdoc: scanning manifest" - @ast.hostclasses.values.sort { |a,b| a.name <=> b.name }.each do |klass| + + @known_resource_types.hostclasses.values.sort { |a,b| a.name <=> b.name }.each do |klass| name = klass.name if klass.file == @input_file_name unless name.empty? @@ -352,13 +363,13 @@ class Parser end end - @ast.definitions.each do |name, define| + @known_resource_types.definitions.each do |name, define| if define.file == @input_file_name document_define(name,define,container) end end - @ast.nodes.each do |name, node| + @known_resource_types.nodes.each do |name, node| if node.file == @input_file_name document_node(name.to_s,node,container) end diff --git a/lib/puppet/util/zaml.rb b/lib/puppet/util/zaml.rb index b22dfc199..bbb2af2d2 100644 --- a/lib/puppet/util/zaml.rb +++ b/lib/puppet/util/zaml.rb @@ -20,7 +20,6 @@ class ZAML def self.dump(stuff, where='') z = new stuff.to_zaml(z) - Label.counter_reset where << z.to_s end # @@ -30,7 +29,8 @@ class ZAML @result = [] @indent = nil @structured_key_prefix = nil - Label.counter_reset + @previously_emitted_object = {} + @next_free_label_number = 0 emit('--- ') end def nested(tail=' ') @@ -56,31 +56,30 @@ class ZAML # which we will encounter a reference to the object as we serialize # it can be handled). # - def self.counter_reset - @@previously_emitted_object = {} - @@next_free_label_number = 0 - end - def initialize(obj) + attr_accessor :this_label_number + def initialize(obj,indent) + @indent = indent @this_label_number = nil @obj = obj # prevent garbage collection so that object id isn't reused - @@previously_emitted_object[obj.object_id] = self end def to_s - @this_label_number ? ('&id%03d ' % @this_label_number) : '' + @this_label_number ? ('&id%03d%s' % [@this_label_number, @indent]) : '' end def reference - @this_label_number ||= (@@next_free_label_number += 1) @reference ||= '*id%03d' % @this_label_number end - def self.for(obj) - @@previously_emitted_object[obj.object_id] - end + end + def label_for(obj) + @previously_emitted_object[obj.object_id] end def new_label_for(obj) - Label.new(obj) + label = Label.new(obj,(Hash === obj || Array === obj) ? "#{@indent || "\n"} " : ' ') + @previously_emitted_object[obj.object_id] = label + label end def first_time_only(obj) - if label = Label.for(obj) + if label = label_for(obj) + label.this_label_number ||= (@next_free_label_number += 1) emit(label.reference) else if @structured_key_prefix and not obj.is_a? String @@ -93,7 +92,7 @@ class ZAML end def emit(s) @result << s - @recent_nl = false + @recent_nl = false unless s.kind_of?(Label) end def nl(s='') emit(@indent || "\n") unless @recent_nl @@ -225,30 +224,32 @@ class String gsub( /([\x80-\xFF])/ ) { |x| "\\x#{x.unpack("C")[0].to_s(16)}" } end def to_zaml(z) - num = '[-+]?(0x)?\d+\.?\d*' - case - when self == '' - z.emit('""') - # when self =~ /[\x00-\x08\x0B\x0C\x0E-\x1F\x80-\xFF]/ - # z.emit("!binary |\n") - # z.emit([self].pack("m*")) - when ( - (self =~ /\A(true|false|yes|no|on|null|off|#{num}(:#{num})*|!|=|~)$/i) or - (self =~ /\A\n* /) or - (self =~ /[\s:]$/) or - (self =~ /^[>|][-+\d]*\s/i) or - (self[-1..-1] =~ /\s/) or - (self =~ /[\x00-\x08\x0B\x0C\x0E-\x1F\x80-\xFF]/) or - (self =~ /[,\[\]\{\}\r\t]|:\s|\s#/) or - (self =~ /\A([-:?!#&*'"]|<<|%.+:.)/) - ) - z.emit("\"#{escaped_for_zaml}\"") - when self =~ /\n/ - if self[-1..-1] == "\n" then z.emit('|+') else z.emit('|-') end - z.nested { split("\n",-1).each { |line| z.nl; z.emit(line.chomp("\n")) } } - else - z.emit(self) - end + z.first_time_only(self) { + num = '[-+]?(0x)?\d+\.?\d*' + case + when self == '' + z.emit('""') + # when self =~ /[\x00-\x08\x0B\x0C\x0E-\x1F\x80-\xFF]/ + # z.emit("!binary |\n") + # z.emit([self].pack("m*")) + when ( + (self =~ /\A(true|false|yes|no|on|null|off|#{num}(:#{num})*|!|=|~)$/i) or + (self =~ /\A\n* /) or + (self =~ /[\s:]$/) or + (self =~ /^[>|][-+\d]*\s/i) or + (self[-1..-1] =~ /\s/) or + (self =~ /[\x00-\x08\x0B\x0C\x0E-\x1F\x80-\xFF]/) or + (self =~ /[,\[\]\{\}\r\t]|:\s|\s#/) or + (self =~ /\A([-:?!#&*'"]|<<|%.+:.)/) + ) + z.emit("\"#{escaped_for_zaml}\"") + when self =~ /\n/ + if self[-1..-1] == "\n" then z.emit('|+') else z.emit('|-') end + z.nested { split("\n",-1).each { |line| z.nl; z.emit(line.chomp("\n")) } } + else + z.emit(self) + end + } end end diff --git a/man/man5/puppet.conf.5 b/man/man5/puppet.conf.5 index 210f36786..f6c9926c3 100644 --- a/man/man5/puppet.conf.5 +++ b/man/man5/puppet.conf.5 @@ -1,14 +1,13 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "PUPPETCONF" "5" "August 2010" "" "" -\fBThis page is autogenerated; any changes will get overwritten\fR \fI(last generated on Sat Aug 28 14:00:20 \-0700 2010)\fR -. -.P -{:toc} +.TH "PUPPETCONF" "5" "February 2011" "Puppet Labs, LLC" "Puppet manual" +\fBThis page is autogenerated; any changes will get overwritten\fR \fI(last generated on Thu Feb 17 09:56:34 \-0800 2011)\fR . .SH "Specifying Configuration Parameters" -On The Command\-Line +++++++++++++++++++ Every Puppet executable (with the exception of \fBpuppetdoc\fR) accepts all of the parameters below, but not all of the arguments make sense for every executable\. +. +.SS "On The Command\-Line" +Every Puppet executable (with the exception of \fBpuppetdoc\fR) accepts all of the parameters below, but not all of the arguments make sense for every executable\. . .P I have tried to be as thorough as possible in the descriptions of the arguments, so it should be obvious whether an argument is appropriate or not\. @@ -44,19 +43,13 @@ $ puppet agent \-\-no\-storeconfigs .P The invocations above will enable and disable, respectively, the storage of the client configuration\. . -.P -Configuration Files +++++++++++++++++++ -. -.P +.SS "Configuration Files" As mentioned above, the configuration parameters can also be stored in a configuration file, located in the configuration directory\. As root, the default configuration directory is \fB/etc/puppet\fR, and as a regular user, the default configuration directory is \fB~user/\.puppet\fR\. As of 0\.23\.0, all executables look for \fBpuppet\.conf\fR in their configuration directory (although they previously looked for separate files)\. For example, \fBpuppet\.conf\fR is located at \fB/etc/puppet/puppet\.conf\fR as \fBroot\fR and \fB~user/\.puppet/puppet\.conf\fR as a regular user by default\. . .P All executables will set any parameters set within the \fB[main]\fR section, and each executable will also use one of the \fB[master]\fR, \fB[agent]\fR\. . .P -File Format \'\'\'\'\'\'\'\'\'\'\' -. -.P The file follows INI\-style formatting\. Here is an example of a very simple \fBpuppet\.conf\fR file: . .IP "" 4 @@ -75,14 +68,14 @@ The file follows INI\-style formatting\. Here is an example of a very simple \fB Note that boolean parameters must be explicitly specified as \fBtrue\fR or \fBfalse\fR as seen above\. . .P -If you need to change file parameters (e\.g\., reset the mode or owner), do so within curly braces on the same line: +If you need to change file or directory parameters (e\.g\., reset the mode or owner), do so within curly braces on the same line: . .IP "" 4 . .nf [main] - myfile = /tmp/whatever {owner = root, mode = 644} + vardir = /new/vardir {owner = root, mode = 644} . .fi . @@ -139,21 +132,31 @@ Sending the \fBSIGUSR1\fR signal to an instance of \fBpuppet agent\fR will cause .SH "Configuration Parameter Reference" Below is a list of all documented parameters\. Not all of them are valid with all Puppet executables, but the executables will ignore any inappropriate values\. . -.P -async_storeconfigs ++++++++++++++++++ +.SS "archive_file_server" +During an inspect run, the file bucket server to archive files to if archive_files is set\. . -.P -Whether to use a queueing system to provide asynchronous database integration\. Requires that \fBpuppetqd\fR be running and that \'PSON\' support for ruby be installed\. +.IP "\(bu" 4 +\fIDefault\fR: $server +. +.IP "" 0 +. +.SS "archive_files" +During an inspect run, whether to archive files whose contents are audited to a file bucket\. . .IP "\(bu" 4 \fIDefault\fR: false . .IP "" 0 . -.P -authconfig ++++++++++ +.SS "async_storeconfigs" +Whether to use a queueing system to provide asynchronous database integration\. Requires that \fBpuppetqd\fR be running and that \'PSON\' support for ruby be installed\. . -.P +.IP "\(bu" 4 +\fIDefault\fR: false +. +.IP "" 0 +. +.SS "authconfig" The configuration file that defines the rights to the different namespaces and methods\. This can be used as a coarse\-grained authorization system for both \fBpuppet agent\fR and \fBpuppet master\fR\. . .IP "\(bu" 4 @@ -161,10 +164,7 @@ The configuration file that defines the rights to the different namespaces and m . .IP "" 0 . -.P -autoflush +++++++++ -. -.P +.SS "autoflush" Whether log files should always flush to disk\. . .IP "\(bu" 4 @@ -172,10 +172,7 @@ Whether log files should always flush to disk\. . .IP "" 0 . -.P -autosign ++++++++ -. -.P +.SS "autosign" Whether to enable autosign\. Valid values are true (which autosigns any key request, and is a very bad idea), false (which never autosigns any key request), and the path to a file, which uses that configuration file to determine which keys to sign\. . .IP "\(bu" 4 @@ -183,16 +180,10 @@ Whether to enable autosign\. Valid values are true (which autosigns any key requ . .IP "" 0 . -.P -bindaddress +++++++++++ -. -.P +.SS "bindaddress" The address a listening server should bind to\. Mongrel servers default to 127\.0\.0\.1 and WEBrick defaults to 0\.0\.0\.0\. . -.P -bucketdir +++++++++ -. -.P +.SS "bucketdir" Where FileBucket files are stored\. . .IP "\(bu" 4 @@ -200,10 +191,7 @@ Where FileBucket files are stored\. . .IP "" 0 . -.P -ca ++ -. -.P +.SS "ca" Wether the master should function as a certificate authority\. . .IP "\(bu" 4 @@ -211,16 +199,10 @@ Wether the master should function as a certificate authority\. . .IP "" 0 . -.P -ca_days +++++++ -. -.P +.SS "ca_days" How long a certificate should be valid\. This parameter is deprecated, use ca_ttl instead . -.P -ca_md +++++ -. -.P +.SS "ca_md" The type of hash used in certificates\. . .IP "\(bu" 4 @@ -228,21 +210,15 @@ The type of hash used in certificates\. . .IP "" 0 . -.P -ca_name +++++++ -. -.P +.SS "ca_name" The name to use the Certificate Authority certificate\. . .IP "\(bu" 4 -\fIDefault\fR: $certname +\fIDefault\fR: Puppet CA: $certname . .IP "" 0 . -.P -ca_port +++++++ -. -.P +.SS "ca_port" The port to use for the certificate authority\. . .IP "\(bu" 4 @@ -250,10 +226,7 @@ The port to use for the certificate authority\. . .IP "" 0 . -.P -ca_server +++++++++ -. -.P +.SS "ca_server" The server to use for certificate authority requests\. It\'s a separate server because it cannot and does not need to horizontally scale\. . .IP "\(bu" 4 @@ -261,10 +234,7 @@ The server to use for certificate authority requests\. It\'s a separate server b . .IP "" 0 . -.P -ca_ttl ++++++ -. -.P +.SS "ca_ttl" The default TTL for new certificates; valid values must be an integer, optionally followed by one of the units \'y\' (years of 365 days), \'d\' (days), \'h\' (hours), or \'s\' (seconds)\. The unit defaults to seconds\. If this parameter is set, ca_days is ignored\. Examples are \'3600\' (one hour) and \'1825d\', which is the same as \'5y\' (5 years) . .IP "\(bu" 4 @@ -272,10 +242,7 @@ The default TTL for new certificates; valid values must be an integer, optionall . .IP "" 0 . -.P -cacert ++++++ -. -.P +.SS "cacert" The CA certificate\. . .IP "\(bu" 4 @@ -283,10 +250,7 @@ The CA certificate\. . .IP "" 0 . -.P -cacrl +++++ -. -.P +.SS "cacrl" The certificate revocation list (CRL) for the CA\. Will be used if present but otherwise ignored\. . .IP "\(bu" 4 @@ -294,10 +258,7 @@ The certificate revocation list (CRL) for the CA\. Will be used if present but o . .IP "" 0 . -.P -cadir +++++ -. -.P +.SS "cadir" The root directory for the certificate authority\. . .IP "\(bu" 4 @@ -305,10 +266,7 @@ The root directory for the certificate authority\. . .IP "" 0 . -.P -cakey +++++ -. -.P +.SS "cakey" The CA private key\. . .IP "\(bu" 4 @@ -316,10 +274,7 @@ The CA private key\. . .IP "" 0 . -.P -capass ++++++ -. -.P +.SS "capass" Where the CA stores the password for the private key . .IP "\(bu" 4 @@ -327,10 +282,7 @@ Where the CA stores the password for the private key . .IP "" 0 . -.P -caprivatedir ++++++++++++ -. -.P +.SS "caprivatedir" Where the CA stores private certificate information\. . .IP "\(bu" 4 @@ -338,10 +290,7 @@ Where the CA stores private certificate information\. . .IP "" 0 . -.P -capub +++++ -. -.P +.SS "capub" The CA public key\. . .IP "\(bu" 4 @@ -349,16 +298,10 @@ The CA public key\. . .IP "" 0 . -.P -catalog_format ++++++++++++++ -. -.P +.SS "catalog_format" (Deprecated for \'preferred_serialization_format\') What format to use to dump the catalog\. Only supports \'marshal\' and \'yaml\'\. Only matters on the client, since it asks the server for a specific format\. . -.P -catalog_terminus ++++++++++++++++ -. -.P +.SS "catalog_terminus" Where to get node catalogs\. This is useful to change if, for instance, you\'d like to pre\-compile catalogs and store them in memcached or some other easily\-accessed store\. . .IP "\(bu" 4 @@ -366,10 +309,7 @@ Where to get node catalogs\. This is useful to change if, for instance, you\'d l . .IP "" 0 . -.P -cert_inventory ++++++++++++++ -. -.P +.SS "cert_inventory" A Complete listing of all certificates . .IP "\(bu" 4 @@ -377,10 +317,7 @@ A Complete listing of all certificates . .IP "" 0 . -.P -certdir +++++++ -. -.P +.SS "certdir" The certificate directory\. . .IP "\(bu" 4 @@ -388,16 +325,10 @@ The certificate directory\. . .IP "" 0 . -.P -certdnsnames ++++++++++++ -. -.P +.SS "certdnsnames" The DNS names on the Server certificate as a colon\-separated list\. If it\'s anything other than an empty string, it will be used as an alias in the created certificate\. By default, only the server gets an alias set up, and only for \'puppet\'\. . -.P -certificate_revocation ++++++++++++++++++++++ -. -.P +.SS "certificate_revocation" Whether certificate revocation should be supported by downloading a Certificate Revocation List (CRL) to all clients\. If enabled, CA chaining will almost definitely not work\. . .IP "\(bu" 4 @@ -405,21 +336,15 @@ Whether certificate revocation should be supported by downloading a Certificate . .IP "" 0 . -.P -certname ++++++++ -. -.P +.SS "certname" The name to use when handling certificates\. Defaults to the fully qualified domain name\. . .IP "\(bu" 4 -\fIDefault\fR: pelin\.members\.linode\.com +\fIDefault\fR: magpie\.puppetlabs\.lan . .IP "" 0 . -.P -classfile +++++++++ -. -.P +.SS "classfile" The file in which puppet agent stores a list of the classes associated with the retrieved configuration\. Can be loaded in the separate \fBpuppet\fR executable using the \fB\-\-loadclasses\fR option\. . .IP "\(bu" 4 @@ -427,10 +352,7 @@ The file in which puppet agent stores a list of the classes associated with the . .IP "" 0 . -.P -client_datadir ++++++++++++++ -. -.P +.SS "client_datadir" The directory in which serialized data is stored on the client\. . .IP "\(bu" 4 @@ -438,10 +360,7 @@ The directory in which serialized data is stored on the client\. . .IP "" 0 . -.P -clientbucketdir +++++++++++++++ -. -.P +.SS "clientbucketdir" Where FileBucket files are stored locally\. . .IP "\(bu" 4 @@ -449,10 +368,7 @@ Where FileBucket files are stored locally\. . .IP "" 0 . -.P -clientyamldir +++++++++++++ -. -.P +.SS "clientyamldir" The directory in which client\-side YAML data is stored\. . .IP "\(bu" 4 @@ -460,16 +376,10 @@ The directory in which client\-side YAML data is stored\. . .IP "" 0 . -.P -code ++++ -. -.P +.SS "code" Code to parse directly\. This is essentially only used by \fBpuppet\fR, and should only be set if you\'re writing your own Puppet executable . -.P -color +++++ -. -.P +.SS "color" Whether to use colors when logging to the console\. Valid values are \fBansi\fR (equivalent to \fBtrue\fR), \fBhtml\fR (mostly used during testing with TextMate), and \fBfalse\fR, which produces no color\. . .IP "\(bu" 4 @@ -477,21 +387,15 @@ Whether to use colors when logging to the console\. Valid values are \fBansi\fR . .IP "" 0 . -.P -confdir +++++++ -. -.P -The main Puppet configuration directory\. The default for this parameter is calculated based on the user\. If the process is running as root or the user that \fBpuppet master\fR is supposed to run as, it defaults to a system directory, but if it\'s running as any other user, it defaults to being in \fB~\fR\. +.SS "confdir" +The main Puppet configuration directory\. The default for this parameter is calculated based on the user\. If the process is running as root or the user that Puppet is supposed to run as, it defaults to a system directory, but if it\'s running as any other user, it defaults to being in the user\'s home directory\. . .IP "\(bu" 4 \fIDefault\fR: /etc/puppet . .IP "" 0 . -.P -config ++++++ -. -.P +.SS "config" The configuration file for doc\. . .IP "\(bu" 4 @@ -499,22 +403,13 @@ The configuration file for doc\. . .IP "" 0 . -.P -config_version ++++++++++++++ -. -.P +.SS "config_version" How to determine the configuration version\. By default, it will be the time that the configuration is parsed, but you can provide a shell script to override how the version is determined\. The output of this script will be added to every log message in the reports, allowing you to correlate changes on your hosts to the source version on the server\. . -.P -configprint +++++++++++ -. -.P +.SS "configprint" Print the value of a specific configuration parameter\. If a parameter is provided for this, then the value is printed and puppet exits\. Comma\-separate multiple values\. For a list of all values, specify \'all\'\. This feature is only available in Puppet versions higher than 0\.18\.4\. . -.P -configtimeout +++++++++++++ -. -.P +.SS "configtimeout" How long the client should wait for the configuration to be retrieved before considering it a failure\. This can help reduce flapping if too many clients contact the server at one time\. . .IP "\(bu" 4 @@ -522,10 +417,7 @@ How long the client should wait for the configuration to be retrieved before con . .IP "" 0 . -.P -couchdb_url +++++++++++ -. -.P +.SS "couchdb_url" The url where the puppet couchdb database will be created . .IP "\(bu" 4 @@ -533,10 +425,7 @@ The url where the puppet couchdb database will be created . .IP "" 0 . -.P -csrdir ++++++ -. -.P +.SS "csrdir" Where the CA stores certificate requests . .IP "\(bu" 4 @@ -544,10 +433,7 @@ Where the CA stores certificate requests . .IP "" 0 . -.P -daemonize +++++++++ -. -.P +.SS "daemonize" Send the process into the background\. This is the default\. . .IP "\(bu" 4 @@ -555,10 +441,7 @@ Send the process into the background\. This is the default\. . .IP "" 0 . -.P -dbadapter +++++++++ -. -.P +.SS "dbadapter" The type of database to use\. . .IP "\(bu" 4 @@ -566,21 +449,10 @@ The type of database to use\. . .IP "" 0 . -.P -dbconnections +++++++++++++ -. -.P -The number of database connections\. Only used when networked databases are used\. Will be ignored if the value is an empty string or is less than 1\. -. -.IP "\(bu" 4 -\fIDefault\fR: 0 -. -.IP "" 0 +.SS "dbconnections" +The number of database connections for networked databases\. Will be ignored unless the value is a positive integer\. . -.P -dblocation ++++++++++ -. -.P +.SS "dblocation" The database cache for client configurations\. Used for querying within the language\. . .IP "\(bu" 4 @@ -588,10 +460,7 @@ The database cache for client configurations\. Used for querying within the lang . .IP "" 0 . -.P -dbmigrate +++++++++ -. -.P +.SS "dbmigrate" Whether to automatically migrate the database\. . .IP "\(bu" 4 @@ -599,10 +468,7 @@ Whether to automatically migrate the database\. . .IP "" 0 . -.P -dbname ++++++ -. -.P +.SS "dbname" The name of the database to use\. . .IP "\(bu" 4 @@ -610,10 +476,7 @@ The name of the database to use\. . .IP "" 0 . -.P -dbpassword ++++++++++ -. -.P +.SS "dbpassword" The database password for caching\. Only used when networked databases are used\. . .IP "\(bu" 4 @@ -621,16 +484,10 @@ The database password for caching\. Only used when networked databases are used\ . .IP "" 0 . -.P -dbport ++++++ -. -.P +.SS "dbport" The database password for caching\. Only used when networked databases are used\. . -.P -dbserver ++++++++ -. -.P +.SS "dbserver" The database server for caching\. Only used when networked databases are used\. . .IP "\(bu" 4 @@ -638,16 +495,10 @@ The database server for caching\. Only used when networked databases are used\. . .IP "" 0 . -.P -dbsocket ++++++++ -. -.P +.SS "dbsocket" The database socket location\. Only used when networked databases are used\. Will be ignored if the value is an empty string\. . -.P -dbuser ++++++ -. -.P +.SS "dbuser" The database user for caching\. Only used when networked databases are used\. . .IP "\(bu" 4 @@ -655,10 +506,7 @@ The database user for caching\. Only used when networked databases are used\. . .IP "" 0 . -.P -diff ++++ -. -.P +.SS "diff" Which diff command to use when printing differences between files\. . .IP "\(bu" 4 @@ -666,10 +514,7 @@ Which diff command to use when printing differences between files\. . .IP "" 0 . -.P -diff_args +++++++++ -. -.P +.SS "diff_args" Which arguments to pass to the diff command when printing differences between files\. . .IP "\(bu" 4 @@ -677,10 +522,7 @@ Which arguments to pass to the diff command when printing differences between fi . .IP "" 0 . -.P -downcasefacts +++++++++++++ -. -.P +.SS "downcasefacts" Whether facts should be made all lowercase when sent to the server\. . .IP "\(bu" 4 @@ -688,10 +530,7 @@ Whether facts should be made all lowercase when sent to the server\. . .IP "" 0 . -.P -dynamicfacts ++++++++++++ -. -.P +.SS "dynamicfacts" Facts that are dynamic; these facts will be ignored when deciding whether changed facts should result in a recompile\. Multiple facts should be comma\-separated\. . .IP "\(bu" 4 @@ -699,10 +538,7 @@ Facts that are dynamic; these facts will be ignored when deciding whether change . .IP "" 0 . -.P -environment +++++++++++ -. -.P +.SS "environment" The environment Puppet is running in\. For clients (e\.g\., \fBpuppet agent\fR) this determines the environment itself, which is used to find modules and much more\. For servers (i\.e\., \fBpuppet master\fR) this provides the default environment for nodes we know nothing about\. . .IP "\(bu" 4 @@ -710,10 +546,7 @@ The environment Puppet is running in\. For clients (e\.g\., \fBpuppet agent\fR) . .IP "" 0 . -.P -evaltrace +++++++++ -. -.P +.SS "evaltrace" Whether each resource should log when it is being evaluated\. This allows you to interactively see exactly what is being done\. . .IP "\(bu" 4 @@ -721,10 +554,7 @@ Whether each resource should log when it is being evaluated\. This allows you to . .IP "" 0 . -.P -external_nodes ++++++++++++++ -. -.P +.SS "external_nodes" An external command that can produce node information\. The output must be a YAML dump of a hash, and that hash must have one or both of \fBclasses\fR and \fBparameters\fR, where \fBclasses\fR is an array and \fBparameters\fR is a hash\. For unknown nodes, the commands should exit with a non\-zero exit code\. This command makes it straightforward to store your node mapping information in other data sources like databases\. . .IP "\(bu" 4 @@ -732,10 +562,7 @@ An external command that can produce node information\. The output must be a YAM . .IP "" 0 . -.P -factdest ++++++++ -. -.P +.SS "factdest" Where Puppet should store facts that it pulls down from the central server\. . .IP "\(bu" 4 @@ -743,10 +570,7 @@ Where Puppet should store facts that it pulls down from the central server\. . .IP "" 0 . -.P -factpath ++++++++ -. -.P +.SS "factpath" Where Puppet should look for facts\. Multiple directories should be colon\-separated, like normal PATH variables\. . .IP "\(bu" 4 @@ -754,10 +578,7 @@ Where Puppet should look for facts\. Multiple directories should be colon\-separ . .IP "" 0 . -.P -facts_terminus ++++++++++++++ -. -.P +.SS "facts_terminus" The node facts terminus\. . .IP "\(bu" 4 @@ -765,10 +586,7 @@ The node facts terminus\. . .IP "" 0 . -.P -factsignore +++++++++++ -. -.P +.SS "factsignore" What files to ignore when pulling down facts\. . .IP "\(bu" 4 @@ -776,10 +594,7 @@ What files to ignore when pulling down facts\. . .IP "" 0 . -.P -factsource ++++++++++ -. -.P +.SS "factsource" From where to retrieve facts\. The standard Puppet \fBfile\fR type is used for retrieval, so anything that is a valid file source can be used here\. . .IP "\(bu" 4 @@ -787,10 +602,7 @@ From where to retrieve facts\. The standard Puppet \fBfile\fR type is used for r . .IP "" 0 . -.P -factsync ++++++++ -. -.P +.SS "factsync" Whether facts should be synced with the central server\. . .IP "\(bu" 4 @@ -798,10 +610,7 @@ Whether facts should be synced with the central server\. . .IP "" 0 . -.P -fileserverconfig ++++++++++++++++ -. -.P +.SS "fileserverconfig" Where the fileserver configuration is stored\. . .IP "\(bu" 4 @@ -809,10 +618,7 @@ Where the fileserver configuration is stored\. . .IP "" 0 . -.P -filetimeout +++++++++++ -. -.P +.SS "filetimeout" The minimum time to wait (in seconds) between checking for updates in configuration files\. This timeout determines how quickly Puppet checks whether a file (such as manifests or templates) has changed on disk\. . .IP "\(bu" 4 @@ -820,10 +626,7 @@ The minimum time to wait (in seconds) between checking for updates in configurat . .IP "" 0 . -.P -freeze_main +++++++++++ -. -.P +.SS "freeze_main" Freezes the \'main\' class, disallowing any code to be added to it\. This essentially means that you can\'t have any code outside of a node, class, or definition other than in the site manifest\. . .IP "\(bu" 4 @@ -831,10 +634,7 @@ Freezes the \'main\' class, disallowing any code to be added to it\. This essent . .IP "" 0 . -.P -genconfig +++++++++ -. -.P +.SS "genconfig" Whether to just print a configuration to stdout and exit\. Only makes sense when used interactively\. Takes into account arguments specified on the CLI\. . .IP "\(bu" 4 @@ -842,10 +642,7 @@ Whether to just print a configuration to stdout and exit\. Only makes sense when . .IP "" 0 . -.P -genmanifest +++++++++++ -. -.P +.SS "genmanifest" Whether to just print a manifest to stdout and exit\. Only makes sense when used interactively\. Takes into account arguments specified on the CLI\. . .IP "\(bu" 4 @@ -853,10 +650,7 @@ Whether to just print a manifest to stdout and exit\. Only makes sense when used . .IP "" 0 . -.P -graph +++++ -. -.P +.SS "graph" Whether to create dot graph files for the different configuration graphs\. These dot files can be interpreted by tools like OmniGraffle or dot (which is part of ImageMagick)\. . .IP "\(bu" 4 @@ -864,10 +658,7 @@ Whether to create dot graph files for the different configuration graphs\. These . .IP "" 0 . -.P -graphdir ++++++++ -. -.P +.SS "graphdir" Where to store dot\-outputted graphs\. . .IP "\(bu" 4 @@ -875,10 +666,7 @@ Where to store dot\-outputted graphs\. . .IP "" 0 . -.P -group +++++ -. -.P +.SS "group" The group puppet master should run as\. . .IP "\(bu" 4 @@ -886,10 +674,7 @@ The group puppet master should run as\. . .IP "" 0 . -.P -hostcert ++++++++ -. -.P +.SS "hostcert" Where individual hosts store and look for their certificates\. . .IP "\(bu" 4 @@ -897,10 +682,7 @@ Where individual hosts store and look for their certificates\. . .IP "" 0 . -.P -hostcrl +++++++ -. -.P +.SS "hostcrl" Where the host\'s certificate revocation list can be found\. This is distinct from the certificate authority\'s CRL\. . .IP "\(bu" 4 @@ -908,10 +690,7 @@ Where the host\'s certificate revocation list can be found\. This is distinct fr . .IP "" 0 . -.P -hostcsr +++++++ -. -.P +.SS "hostcsr" Where individual hosts store and look for their certificate requests\. . .IP "\(bu" 4 @@ -919,10 +698,7 @@ Where individual hosts store and look for their certificate requests\. . .IP "" 0 . -.P -hostprivkey +++++++++++ -. -.P +.SS "hostprivkey" Where individual hosts store and look for their private key\. . .IP "\(bu" 4 @@ -930,10 +706,7 @@ Where individual hosts store and look for their private key\. . .IP "" 0 . -.P -hostpubkey ++++++++++ -. -.P +.SS "hostpubkey" Where individual hosts store and look for their public key\. . .IP "\(bu" 4 @@ -941,10 +714,7 @@ Where individual hosts store and look for their public key\. . .IP "" 0 . -.P -http_compression ++++++++++++++++ -. -.P +.SS "http_compression" Allow http compression in REST communication with the master\. This setting might improve performance for agent \-> master communications over slow WANs\. Your puppetmaster needs to support compression (usually by activating some settings in a reverse\-proxy in front of the puppetmaster, which rules out webrick)\. It is harmless to activate this settings if your master doesn\'t support compression, but if it supports it, this setting might reduce performance on high\-speed LANs\. . .IP "\(bu" 4 @@ -952,10 +722,7 @@ Allow http compression in REST communication with the master\. This setting migh . .IP "" 0 . -.P -http_proxy_host +++++++++++++++ -. -.P +.SS "http_proxy_host" The HTTP proxy host to use for outgoing connections\. Note: You may need to use a FQDN for the server hostname when using a proxy\. . .IP "\(bu" 4 @@ -963,10 +730,7 @@ The HTTP proxy host to use for outgoing connections\. Note: You may need to use . .IP "" 0 . -.P -http_proxy_port +++++++++++++++ -. -.P +.SS "http_proxy_port" The HTTP proxy port to use for outgoing connections . .IP "\(bu" 4 @@ -974,10 +738,7 @@ The HTTP proxy port to use for outgoing connections . .IP "" 0 . -.P -httplog +++++++ -. -.P +.SS "httplog" Where the puppet agent web server logs\. . .IP "\(bu" 4 @@ -985,10 +746,7 @@ Where the puppet agent web server logs\. . .IP "" 0 . -.P -ignorecache +++++++++++ -. -.P +.SS "ignorecache" Ignore cache and always recompile the configuration\. This is useful for testing new configurations, where the local cache may in fact be stale even if the timestamps are up to date \- if the facts change or if the server changes\. . .IP "\(bu" 4 @@ -996,10 +754,7 @@ Ignore cache and always recompile the configuration\. This is useful for testing . .IP "" 0 . -.P -ignoreimport ++++++++++++ -. -.P +.SS "ignoreimport" A parameter that can be used in commit hooks, since it enables you to parse\-check a single file rather than requiring that all files exist\. . .IP "\(bu" 4 @@ -1007,10 +762,7 @@ A parameter that can be used in commit hooks, since it enables you to parse\-che . .IP "" 0 . -.P -ignoreschedules +++++++++++++++ -. -.P +.SS "ignoreschedules" Boolean; whether puppet agent should ignore schedules\. This is useful for initial puppet agent runs\. . .IP "\(bu" 4 @@ -1018,10 +770,31 @@ Boolean; whether puppet agent should ignore schedules\. This is useful for initi . .IP "" 0 . -.P -keylength +++++++++ +.SS "inventory_port" +The port to communicate with the inventory_server\. . -.P +.IP "\(bu" 4 +\fIDefault\fR: $masterport +. +.IP "" 0 +. +.SS "inventory_server" +The server to send facts to\. +. +.IP "\(bu" 4 +\fIDefault\fR: $server +. +.IP "" 0 +. +.SS "inventory_terminus" +Should usually be the same as the facts terminus +. +.IP "\(bu" 4 +\fIDefault\fR: $facts_terminus +. +.IP "" 0 +. +.SS "keylength" The bit length of keys\. . .IP "\(bu" 4 @@ -1029,10 +802,23 @@ The bit length of keys\. . .IP "" 0 . -.P -ldapattrs +++++++++ +.SS "lastrunfile" +Where puppet agent stores the last run report summary in yaml format\. . -.P +.IP "\(bu" 4 +\fIDefault\fR: $statedir/last_run_summary\.yaml +. +.IP "" 0 +. +.SS "lastrunreport" +Where puppet agent stores the last run report in yaml format\. +. +.IP "\(bu" 4 +\fIDefault\fR: $statedir/last_run_report\.yaml +. +.IP "" 0 +. +.SS "ldapattrs" The LDAP attributes to include when querying LDAP for nodes\. All returned attributes are set as variables in the top\-level scope\. Multiple values should be comma\-separated\. The value \'all\' returns all attributes\. . .IP "\(bu" 4 @@ -1040,16 +826,10 @@ The LDAP attributes to include when querying LDAP for nodes\. All returned attri . .IP "" 0 . -.P -ldapbase ++++++++ -. -.P +.SS "ldapbase" The search base for LDAP searches\. It\'s impossible to provide a meaningful default here, although the LDAP libraries might have one already set\. Generally, it should be the \'ou=Hosts\' branch under your main directory\. . -.P -ldapclassattrs ++++++++++++++ -. -.P +.SS "ldapclassattrs" The LDAP attributes to use to define Puppet classes\. Values should be comma\-separated\. . .IP "\(bu" 4 @@ -1057,10 +837,7 @@ The LDAP attributes to use to define Puppet classes\. Values should be comma\-se . .IP "" 0 . -.P -ldapnodes +++++++++ -. -.P +.SS "ldapnodes" Whether to search for node configurations in LDAP\. See http://projects\.puppetlabs\.com/projects/puppet/wiki/LDAP_Nodes for more information\. . .IP "\(bu" 4 @@ -1068,10 +845,7 @@ Whether to search for node configurations in LDAP\. See http://projects\.puppetl . .IP "" 0 . -.P -ldapparentattr ++++++++++++++ -. -.P +.SS "ldapparentattr" The attribute to use to define the parent node\. . .IP "\(bu" 4 @@ -1079,16 +853,10 @@ The attribute to use to define the parent node\. . .IP "" 0 . -.P -ldappassword ++++++++++++ -. -.P +.SS "ldappassword" The password to use to connect to LDAP\. . -.P -ldapport ++++++++ -. -.P +.SS "ldapport" The LDAP port\. Only used if \fBldapnodes\fR is enabled\. . .IP "\(bu" 4 @@ -1096,10 +864,7 @@ The LDAP port\. Only used if \fBldapnodes\fR is enabled\. . .IP "" 0 . -.P -ldapserver ++++++++++ -. -.P +.SS "ldapserver" The LDAP server\. Only used if \fBldapnodes\fR is enabled\. . .IP "\(bu" 4 @@ -1107,10 +872,7 @@ The LDAP server\. Only used if \fBldapnodes\fR is enabled\. . .IP "" 0 . -.P -ldapssl +++++++ -. -.P +.SS "ldapssl" Whether SSL should be used when searching for nodes\. Defaults to false because SSL usually requires certificates to be set up on the client side\. . .IP "\(bu" 4 @@ -1118,10 +880,7 @@ Whether SSL should be used when searching for nodes\. Defaults to false because . .IP "" 0 . -.P -ldapstackedattrs ++++++++++++++++ -. -.P +.SS "ldapstackedattrs" The LDAP attributes that should be stacked to arrays by adding the values in all hierarchy elements of the tree\. Values should be comma\-separated\. . .IP "\(bu" 4 @@ -1129,10 +888,7 @@ The LDAP attributes that should be stacked to arrays by adding the values in all . .IP "" 0 . -.P -ldapstring ++++++++++ -. -.P +.SS "ldapstring" The search string used to find an LDAP node\. . .IP "\(bu" 4 @@ -1140,10 +896,7 @@ The search string used to find an LDAP node\. . .IP "" 0 . -.P -ldaptls +++++++ -. -.P +.SS "ldaptls" Whether TLS should be used when searching for nodes\. Defaults to false because TLS usually requires certificates to be set up on the client side\. . .IP "\(bu" 4 @@ -1151,16 +904,10 @@ Whether TLS should be used when searching for nodes\. Defaults to false because . .IP "" 0 . -.P -ldapuser ++++++++ -. -.P +.SS "ldapuser" The user to use to connect to LDAP\. Must be specified as a full DN\. . -.P -lexical +++++++ -. -.P +.SS "lexical" Whether to use lexical scoping (vs\. dynamic)\. . .IP "\(bu" 4 @@ -1168,10 +915,7 @@ Whether to use lexical scoping (vs\. dynamic)\. . .IP "" 0 . -.P -libdir ++++++ -. -.P +.SS "libdir" An extra search path for Puppet\. This is only useful for those files that Puppet will load on demand, and is only guaranteed to work for those cases\. In fact, the autoload mechanism is responsible for making sure this directory is in Ruby\'s search path . .IP "\(bu" 4 @@ -1179,10 +923,7 @@ An extra search path for Puppet\. This is only useful for those files that Puppe . .IP "" 0 . -.P -listen ++++++ -. -.P +.SS "listen" Whether puppet agent should listen for connections\. If this is true, then by default only the \fBrunner\fR server is started, which allows remote authorized and authenticated nodes to connect and trigger \fBpuppet agent\fR runs\. . .IP "\(bu" 4 @@ -1190,10 +931,7 @@ Whether puppet agent should listen for connections\. If this is true, then by de . .IP "" 0 . -.P -localcacert +++++++++++ -. -.P +.SS "localcacert" Where each client stores the CA certificate\. . .IP "\(bu" 4 @@ -1201,10 +939,7 @@ Where each client stores the CA certificate\. . .IP "" 0 . -.P -localconfig +++++++++++ -. -.P +.SS "localconfig" Where puppet agent caches the local configuration\. An extension indicating the cache format is added automatically\. . .IP "\(bu" 4 @@ -1212,10 +947,7 @@ Where puppet agent caches the local configuration\. An extension indicating the . .IP "" 0 . -.P -logdir ++++++ -. -.P +.SS "logdir" The Puppet log directory\. . .IP "\(bu" 4 @@ -1223,10 +955,7 @@ The Puppet log directory\. . .IP "" 0 . -.P -manage_internal_file_permissions ++++++++++++++++++++++++++++++++ -. -.P +.SS "manage_internal_file_permissions" Whether Puppet should manage the owner, group, and mode of files it uses internally . .IP "\(bu" 4 @@ -1234,10 +963,7 @@ Whether Puppet should manage the owner, group, and mode of files it uses interna . .IP "" 0 . -.P -manifest ++++++++ -. -.P +.SS "manifest" The entry\-point manifest for puppet master\. . .IP "\(bu" 4 @@ -1245,10 +971,7 @@ The entry\-point manifest for puppet master\. . .IP "" 0 . -.P -manifestdir +++++++++++ -. -.P +.SS "manifestdir" Where puppet master looks for its manifests\. . .IP "\(bu" 4 @@ -1256,10 +979,7 @@ Where puppet master looks for its manifests\. . .IP "" 0 . -.P -masterhttplog +++++++++++++ -. -.P +.SS "masterhttplog" Where the puppet master web server logs\. . .IP "\(bu" 4 @@ -1267,10 +987,7 @@ Where the puppet master web server logs\. . .IP "" 0 . -.P -masterlog +++++++++ -. -.P +.SS "masterlog" Where puppet master logs\. This is generally not used, since syslog is the default log destination\. . .IP "\(bu" 4 @@ -1278,10 +995,7 @@ Where puppet master logs\. This is generally not used, since syslog is the defau . .IP "" 0 . -.P -masterport ++++++++++ -. -.P +.SS "masterport" Which port puppet master listens on\. . .IP "\(bu" 4 @@ -1289,10 +1003,7 @@ Which port puppet master listens on\. . .IP "" 0 . -.P -maximum_uid +++++++++++ -. -.P +.SS "maximum_uid" The maximum allowed UID\. Some platforms use negative UIDs but then ship with tools that do not know how to handle signed ints, so the UIDs show up as huge numbers that can then not be fed back into the system\. This is a hackish way to fail in a slightly more useful way when that happens\. . .IP "\(bu" 4 @@ -1300,10 +1011,7 @@ The maximum allowed UID\. Some platforms use negative UIDs but then ship with to . .IP "" 0 . -.P -mkusers +++++++ -. -.P +.SS "mkusers" Whether to create the necessary user and group that puppet agent will run as\. . .IP "\(bu" 4 @@ -1311,10 +1019,7 @@ Whether to create the necessary user and group that puppet agent will run as\. . .IP "" 0 . -.P -modulepath ++++++++++ -. -.P +.SS "modulepath" The search path for modules as a colon\-separated list of directories\. . .IP "\(bu" 4 @@ -1322,10 +1027,7 @@ The search path for modules as a colon\-separated list of directories\. . .IP "" 0 . -.P -name ++++ -. -.P +.SS "name" The name of the application, if we are running as one\. The default is essentially $0 without the path or \fB\.rb\fR\. . .IP "\(bu" 4 @@ -1333,10 +1035,7 @@ The name of the application, if we are running as one\. The default is essential . .IP "" 0 . -.P -node_name +++++++++ -. -.P +.SS "node_name" How the puppetmaster determines the client\'s identity and sets the \'hostname\', \'fqdn\' and \'domain\' facts for use in the manifest, in particular for determining which \'node\' statement applies to the client\. Possible values are \'cert\' (use the subject\'s CN in the client\'s certificate) and \'facter\' (use the hostname that the client reported in its facts) . .IP "\(bu" 4 @@ -1344,10 +1043,7 @@ How the puppetmaster determines the client\'s identity and sets the \'hostname\' . .IP "" 0 . -.P -node_terminus +++++++++++++ -. -.P +.SS "node_terminus" Where to find information about nodes\. . .IP "\(bu" 4 @@ -1355,10 +1051,7 @@ Where to find information about nodes\. . .IP "" 0 . -.P -noop ++++ -. -.P +.SS "noop" Whether puppet agent should be run in noop mode\. . .IP "\(bu" 4 @@ -1366,10 +1059,7 @@ Whether puppet agent should be run in noop mode\. . .IP "" 0 . -.P -onetime +++++++ -. -.P +.SS "onetime" Run the configuration once, rather than as a long\-running daemon\. This is useful for interactively running puppetd\. . .IP "\(bu" 4 @@ -1377,10 +1067,7 @@ Run the configuration once, rather than as a long\-running daemon\. This is usef . .IP "" 0 . -.P -parseonly +++++++++ -. -.P +.SS "parseonly" Just check the syntax of the manifests\. . .IP "\(bu" 4 @@ -1388,10 +1075,7 @@ Just check the syntax of the manifests\. . .IP "" 0 . -.P -passfile ++++++++ -. -.P +.SS "passfile" Where puppet agent stores the password for its private key\. Generally unused\. . .IP "\(bu" 4 @@ -1399,10 +1083,7 @@ Where puppet agent stores the password for its private key\. Generally unused\. . .IP "" 0 . -.P -path ++++ -. -.P +.SS "path" The shell search path\. Defaults to whatever is inherited from the parent process\. . .IP "\(bu" 4 @@ -1410,10 +1091,7 @@ The shell search path\. Defaults to whatever is inherited from the parent proces . .IP "" 0 . -.P -pidfile +++++++ -. -.P +.SS "pidfile" The pid file . .IP "\(bu" 4 @@ -1421,10 +1099,7 @@ The pid file . .IP "" 0 . -.P -plugindest ++++++++++ -. -.P +.SS "plugindest" Where Puppet should store plugins that it pulls down from the central server\. . .IP "\(bu" 4 @@ -1432,10 +1107,7 @@ Where Puppet should store plugins that it pulls down from the central server\. . .IP "" 0 . -.P -pluginsignore +++++++++++++ -. -.P +.SS "pluginsignore" What files to ignore when pulling down plugins\. . .IP "\(bu" 4 @@ -1443,10 +1115,7 @@ What files to ignore when pulling down plugins\. . .IP "" 0 . -.P -pluginsource ++++++++++++ -. -.P +.SS "pluginsource" From where to retrieve plugins\. The standard Puppet \fBfile\fR type is used for retrieval, so anything that is a valid file source can be used here\. . .IP "\(bu" 4 @@ -1454,10 +1123,7 @@ From where to retrieve plugins\. The standard Puppet \fBfile\fR type is used for . .IP "" 0 . -.P -pluginsync ++++++++++ -. -.P +.SS "pluginsync" Whether plugins should be synced with the central server\. . .IP "\(bu" 4 @@ -1465,16 +1131,10 @@ Whether plugins should be synced with the central server\. . .IP "" 0 . -.P -postrun_command +++++++++++++++ -. -.P +.SS "postrun_command" A command to run after every agent run\. If this command returns a non\-zero return code, the entire Puppet run will be considered to have failed, even though it might have performed work during the normal run\. . -.P -preferred_serialization_format ++++++++++++++++++++++++++++++ -. -.P +.SS "preferred_serialization_format" The preferred means of serializing ruby instances for passing over the wire\. This won\'t guarantee that all instances will be serialized using this method, since not all classes can be guaranteed to support this format, but it will be used for all classes that support it\. . .IP "\(bu" 4 @@ -1482,16 +1142,10 @@ The preferred means of serializing ruby instances for passing over the wire\. Th . .IP "" 0 . -.P -prerun_command ++++++++++++++ -. -.P +.SS "prerun_command" A command to run before every agent run\. If this command returns a non\-zero return code, the entire Puppet run will fail\. . -.P -privatedir ++++++++++ -. -.P +.SS "privatedir" Where the client stores private certificate information\. . .IP "\(bu" 4 @@ -1499,10 +1153,7 @@ Where the client stores private certificate information\. . .IP "" 0 . -.P -privatekeydir +++++++++++++ -. -.P +.SS "privatekeydir" The private key directory\. . .IP "\(bu" 4 @@ -1510,10 +1161,7 @@ The private key directory\. . .IP "" 0 . -.P -publickeydir ++++++++++++ -. -.P +.SS "publickeydir" The public key directory\. . .IP "\(bu" 4 @@ -1521,10 +1169,7 @@ The public key directory\. . .IP "" 0 . -.P -puppetdlockfile +++++++++++++++ -. -.P +.SS "puppetdlockfile" A lock file to temporarily stop puppet agent from doing anything\. . .IP "\(bu" 4 @@ -1532,10 +1177,7 @@ A lock file to temporarily stop puppet agent from doing anything\. . .IP "" 0 . -.P -puppetdlog ++++++++++ -. -.P +.SS "puppetdlog" The log file for puppet agent\. This is generally not used\. . .IP "\(bu" 4 @@ -1543,10 +1185,7 @@ The log file for puppet agent\. This is generally not used\. . .IP "" 0 . -.P -puppetport ++++++++++ -. -.P +.SS "puppetport" Which port puppet agent listens on\. . .IP "\(bu" 4 @@ -1554,10 +1193,7 @@ Which port puppet agent listens on\. . .IP "" 0 . -.P -queue_source ++++++++++++ -. -.P +.SS "queue_source" Which type of queue to use for asynchronous processing\. If your stomp server requires authentication, you can include it in the URI as long as your stomp client library is at least 1\.1\.1 . .IP "\(bu" 4 @@ -1565,10 +1201,7 @@ Which type of queue to use for asynchronous processing\. If your stomp server re . .IP "" 0 . -.P -queue_type ++++++++++ -. -.P +.SS "queue_type" Which type of queue to use for asynchronous processing\. . .IP "\(bu" 4 @@ -1576,10 +1209,7 @@ Which type of queue to use for asynchronous processing\. . .IP "" 0 . -.P -rails_loglevel ++++++++++++++ -. -.P +.SS "rails_loglevel" The log level for Rails connections\. The value must be a valid log level within Rails\. Production environments normally use \fBinfo\fR and other environments normally use \fBdebug\fR\. . .IP "\(bu" 4 @@ -1587,10 +1217,7 @@ The log level for Rails connections\. The value must be a valid log level within . .IP "" 0 . -.P -railslog ++++++++ -. -.P +.SS "railslog" Where Rails\-specific logs are sent . .IP "\(bu" 4 @@ -1598,21 +1225,15 @@ Where Rails\-specific logs are sent . .IP "" 0 . -.P -report ++++++ -. -.P +.SS "report" Whether to send reports after every transaction\. . .IP "\(bu" 4 -\fIDefault\fR: false +\fIDefault\fR: true . .IP "" 0 . -.P -report_port +++++++++++ -. -.P +.SS "report_port" The port to communicate with the report_server\. . .IP "\(bu" 4 @@ -1620,21 +1241,15 @@ The port to communicate with the report_server\. . .IP "" 0 . -.P -report_server +++++++++++++ -. -.P -The server to which to send transaction reports\. +.SS "report_server" +The server to send transaction reports to\. . .IP "\(bu" 4 \fIDefault\fR: $server . .IP "" 0 . -.P -reportdir +++++++++ -. -.P +.SS "reportdir" The directory in which to store reports received from the client\. Each client gets a separate subdirectory\. . .IP "\(bu" 4 @@ -1642,21 +1257,15 @@ The directory in which to store reports received from the client\. Each client g . .IP "" 0 . -.P -reportfrom ++++++++++ -. -.P +.SS "reportfrom" The \'from\' email address for the reports\. . .IP "\(bu" 4 -\fIDefault\fR: report@pelin\.members\.linode\.com +\fIDefault\fR: report@magpie\.puppetlabs\.lan . .IP "" 0 . -.P -reports +++++++ -. -.P +.SS "reports" The list of reports to generate\. All reports are looked for in \fBpuppet/reports/name\.rb\fR, and multiple report names should be comma\-separated (whitespace is okay)\. . .IP "\(bu" 4 @@ -1664,10 +1273,7 @@ The list of reports to generate\. All reports are looked for in \fBpuppet/report . .IP "" 0 . -.P -reportserver ++++++++++++ -. -.P +.SS "reportserver" (Deprecated for \'report_server\') The server to which to send transaction reports\. . .IP "\(bu" 4 @@ -1675,10 +1281,7 @@ reportserver ++++++++++++ . .IP "" 0 . -.P -reporturl +++++++++ -. -.P +.SS "reporturl" The URL used by the http reports processor to send reports . .IP "\(bu" 4 @@ -1686,10 +1289,7 @@ The URL used by the http reports processor to send reports . .IP "" 0 . -.P -req_bits ++++++++ -. -.P +.SS "req_bits" The bit length of the certificates\. . .IP "\(bu" 4 @@ -1697,10 +1297,7 @@ The bit length of the certificates\. . .IP "" 0 . -.P -requestdir ++++++++++ -. -.P +.SS "requestdir" Where host certificate requests are stored\. . .IP "\(bu" 4 @@ -1708,10 +1305,7 @@ Where host certificate requests are stored\. . .IP "" 0 . -.P -rest_authconfig +++++++++++++++ -. -.P +.SS "rest_authconfig" The configuration file that defines the rights to the different rest indirections\. This can be used as a fine\-grained authorization system for \fBpuppet master\fR\. . .IP "\(bu" 4 @@ -1719,10 +1313,7 @@ The configuration file that defines the rights to the different rest indirection . .IP "" 0 . -.P -rrddir ++++++ -. -.P +.SS "rrddir" The directory where RRD database files are stored\. Directories for each reporting host will be created under this directory\. . .IP "\(bu" 4 @@ -1730,10 +1321,7 @@ The directory where RRD database files are stored\. Directories for each reporti . .IP "" 0 . -.P -rrdinterval +++++++++++ -. -.P +.SS "rrdinterval" How often RRD should expect data\. This should match how often the hosts report back to the server\. . .IP "\(bu" 4 @@ -1741,10 +1329,7 @@ How often RRD should expect data\. This should match how often the hosts report . .IP "" 0 . -.P -run_mode ++++++++ -. -.P +.SS "run_mode" The effective \'run mode\' of the application: master, agent, or user\. . .IP "\(bu" 4 @@ -1752,10 +1337,7 @@ The effective \'run mode\' of the application: master, agent, or user\. . .IP "" 0 . -.P -rundir ++++++ -. -.P +.SS "rundir" Where Puppet PID files are kept\. . .IP "\(bu" 4 @@ -1763,10 +1345,7 @@ Where Puppet PID files are kept\. . .IP "" 0 . -.P -runinterval +++++++++++ -. -.P +.SS "runinterval" How often puppet agent applies the client configuration; in seconds\. . .IP "\(bu" 4 @@ -1774,10 +1353,7 @@ How often puppet agent applies the client configuration; in seconds\. . .IP "" 0 . -.P -sendmail ++++++++ -. -.P +.SS "sendmail" Where to find the sendmail binary with which to send email\. . .IP "\(bu" 4 @@ -1785,10 +1361,7 @@ Where to find the sendmail binary with which to send email\. . .IP "" 0 . -.P -serial ++++++ -. -.P +.SS "serial" Where the serial number for certificates is stored\. . .IP "\(bu" 4 @@ -1796,10 +1369,7 @@ Where the serial number for certificates is stored\. . .IP "" 0 . -.P -server ++++++ -. -.P +.SS "server" The server to which server puppet agent should connect . .IP "\(bu" 4 @@ -1807,10 +1377,7 @@ The server to which server puppet agent should connect . .IP "" 0 . -.P -server_datadir ++++++++++++++ -. -.P +.SS "server_datadir" The directory in which serialized data is stored, usually in a subdirectory\. . .IP "\(bu" 4 @@ -1818,10 +1385,7 @@ The directory in which serialized data is stored, usually in a subdirectory\. . .IP "" 0 . -.P -servertype ++++++++++ -. -.P +.SS "servertype" The type of server to use\. Currently supported options are webrick and mongrel\. If you use mongrel, you will need a proxy in front of the process or processes, since Mongrel cannot speak SSL\. . .IP "\(bu" 4 @@ -1829,10 +1393,7 @@ The type of server to use\. Currently supported options are webrick and mongrel\ . .IP "" 0 . -.P -show_diff +++++++++ -. -.P +.SS "show_diff" Whether to print a contextual diff when files are being replaced\. The diff is printed on stdout, so this option is meaningless unless you are running Puppet interactively\. This feature currently requires the \fBdiff/lcs\fR Ruby library\. . .IP "\(bu" 4 @@ -1840,10 +1401,7 @@ Whether to print a contextual diff when files are being replaced\. The diff is p . .IP "" 0 . -.P -signeddir +++++++++ -. -.P +.SS "signeddir" Where the CA stores signed certificates\. . .IP "\(bu" 4 @@ -1851,10 +1409,7 @@ Where the CA stores signed certificates\. . .IP "" 0 . -.P -smtpserver ++++++++++ -. -.P +.SS "smtpserver" The server through which to send email reports\. . .IP "\(bu" 4 @@ -1862,10 +1417,7 @@ The server through which to send email reports\. . .IP "" 0 . -.P -splay +++++ -. -.P +.SS "splay" Whether to sleep for a pseudo\-random (but consistent) amount of time before a run\. . .IP "\(bu" 4 @@ -1873,10 +1425,7 @@ Whether to sleep for a pseudo\-random (but consistent) amount of time before a r . .IP "" 0 . -.P -splaylimit ++++++++++ -. -.P +.SS "splaylimit" The maximum time to delay before runs\. Defaults to being the same as the run interval\. . .IP "\(bu" 4 @@ -1884,10 +1433,7 @@ The maximum time to delay before runs\. Defaults to being the same as the run in . .IP "" 0 . -.P -ssl_client_header +++++++++++++++++ -. -.P +.SS "ssl_client_header" The header containing an authenticated client\'s SSL DN\. Only used with Mongrel\. This header must be set by the proxy to the authenticated client\'s SSL DN (e\.g\., \fB/CN=puppet\.puppetlabs\.com\fR)\. See http://projects\.puppetlabs\.com/projects/puppet/wiki/Using_Mongrel for more information\. . .IP "\(bu" 4 @@ -1895,10 +1441,7 @@ The header containing an authenticated client\'s SSL DN\. Only used with Mongrel . .IP "" 0 . -.P -ssl_client_verify_header ++++++++++++++++++++++++ -. -.P +.SS "ssl_client_verify_header" The header containing the status message of the client verification\. Only used with Mongrel\. This header must be set by the proxy to \'SUCCESS\' if the client successfully authenticated, and anything else otherwise\. See http://projects\.puppetlabs\.com/projects/puppet/wiki/Using_Mongrel for more information\. . .IP "\(bu" 4 @@ -1906,10 +1449,7 @@ The header containing the status message of the client verification\. Only used . .IP "" 0 . -.P -ssldir ++++++ -. -.P +.SS "ssldir" Where SSL certificates are kept\. . .IP "\(bu" 4 @@ -1917,10 +1457,7 @@ Where SSL certificates are kept\. . .IP "" 0 . -.P -statedir ++++++++ -. -.P +.SS "statedir" The directory where Puppet state is stored\. Generally, this directory can be removed without causing harm (although it might result in spurious service restarts)\. . .IP "\(bu" 4 @@ -1928,10 +1465,7 @@ The directory where Puppet state is stored\. Generally, this directory can be re . .IP "" 0 . -.P -statefile +++++++++ -. -.P +.SS "statefile" Where puppet agent and puppet master store state associated with the running configuration\. In the case of puppet master, this file reflects the state discovered through interacting with clients\. . .IP "\(bu" 4 @@ -1939,10 +1473,7 @@ Where puppet agent and puppet master store state associated with the running con . .IP "" 0 . -.P -storeconfigs ++++++++++++ -. -.P +.SS "storeconfigs" Whether to store each client\'s configuration\. This requires ActiveRecord from Ruby on Rails\. . .IP "\(bu" 4 @@ -1950,10 +1481,7 @@ Whether to store each client\'s configuration\. This requires ActiveRecord from . .IP "" 0 . -.P -strict_hostname_checking ++++++++++++++++++++++++ -. -.P +.SS "strict_hostname_checking" Whether to only search for the complete hostname as it is in the certificate when searching for node information in the catalogs\. . .IP "\(bu" 4 @@ -1961,10 +1489,7 @@ Whether to only search for the complete hostname as it is in the certificate whe . .IP "" 0 . -.P -summarize +++++++++ -. -.P +.SS "summarize" Whether to print a transaction summary\. . .IP "\(bu" 4 @@ -1972,10 +1497,7 @@ Whether to print a transaction summary\. . .IP "" 0 . -.P -syslogfacility ++++++++++++++ -. -.P +.SS "syslogfacility" What syslog facility to use when logging to syslog\. Syslog has a fixed list of valid facilities, and you must choose one of those; you cannot just make one up\. . .IP "\(bu" 4 @@ -1983,10 +1505,7 @@ What syslog facility to use when logging to syslog\. Syslog has a fixed list of . .IP "" 0 . -.P -tagmap ++++++ -. -.P +.SS "tagmap" The mapping between reporting tags and email addresses\. . .IP "\(bu" 4 @@ -1994,16 +1513,10 @@ The mapping between reporting tags and email addresses\. . .IP "" 0 . -.P -tags ++++ -. -.P +.SS "tags" Tags to use to find resources\. If this is set, then only resources tagged with the specified tags will be applied\. Values must be comma\-separated\. . -.P -templatedir +++++++++++ -. -.P +.SS "templatedir" Where Puppet looks for template files\. Can be a list of colon\-seperated directories\. . .IP "\(bu" 4 @@ -2011,10 +1524,7 @@ Where Puppet looks for template files\. Can be a list of colon\-seperated direct . .IP "" 0 . -.P -thin_storeconfigs +++++++++++++++++ -. -.P +.SS "thin_storeconfigs" Boolean; wether storeconfigs store in the database only the facts and exported resources\. If true, then storeconfigs performance will be higher and still allow exported/collected resources, but other usage external to Puppet might not work . .IP "\(bu" 4 @@ -2022,10 +1532,7 @@ Boolean; wether storeconfigs store in the database only the facts and exported r . .IP "" 0 . -.P -trace +++++ -. -.P +.SS "trace" Whether to print stack traces on some errors . .IP "\(bu" 4 @@ -2033,10 +1540,7 @@ Whether to print stack traces on some errors . .IP "" 0 . -.P -use_cached_catalog ++++++++++++++++++ -. -.P +.SS "use_cached_catalog" Whether to only use the cached catalog rather than compiling a new catalog on every run\. Puppet can be run with this enabled by default and then selectively disabled when a recompile is desired\. . .IP "\(bu" 4 @@ -2044,10 +1548,7 @@ Whether to only use the cached catalog rather than compiling a new catalog on ev . .IP "" 0 . -.P -usecacheonfailure +++++++++++++++++ -. -.P +.SS "usecacheonfailure" Whether to use the cached configuration when the remote configuration will not compile\. This option is useful for testing new configurations, where you want to fix the broken configuration rather than reverting to a known\-good one\. . .IP "\(bu" 4 @@ -2055,10 +1556,7 @@ Whether to use the cached configuration when the remote configuration will not c . .IP "" 0 . -.P -user ++++ -. -.P +.SS "user" The user puppet master should run as\. . .IP "\(bu" 4 @@ -2066,10 +1564,7 @@ The user puppet master should run as\. . .IP "" 0 . -.P -vardir ++++++ -. -.P +.SS "vardir" Where Puppet stores dynamic and growing data\. The default for this parameter is calculated specially, like \fBconfdir\fR_\. . .IP "\(bu" 4 @@ -2077,10 +1572,7 @@ Where Puppet stores dynamic and growing data\. The default for this parameter is . .IP "" 0 . -.P -yamldir +++++++ -. -.P +.SS "yamldir" The directory in which YAML data is stored, usually in a subdirectory\. . .IP "\(bu" 4 @@ -2088,10 +1580,7 @@ The directory in which YAML data is stored, usually in a subdirectory\. . .IP "" 0 . -.P -zlib ++++ -. -.P +.SS "zlib" Boolean; whether to use the zlib library . .IP "\(bu" 4 @@ -2100,4 +1589,4 @@ Boolean; whether to use the zlib library .IP "" 0 . .P -\fIThis page autogenerated on Sat Aug 28 14:00:20 \-0700 2010\fR +\fIThis page autogenerated on Thu Feb 17 09:56:34 \-0800 2011\fR diff --git a/man/man8/filebucket.8 b/man/man8/filebucket.8 index 59afc2ed3..7ff0da9af 100644 --- a/man/man8/filebucket.8 +++ b/man/man8/filebucket.8 @@ -1,105 +1,81 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "FILEBUCKET" "8" "August 2010" "" "" -A stand\-alone Puppet filebucket client\.puppet filebucket [\-h|\-\-help] [\-V|\-\-version] [\-d|\-\-debug] [\-v|\-\-verbose] +.TH "PUPPET\-FILEBUCKET" "8" "February 2011" "Puppet Labs, LLC" "Puppet manual" . -.IP "" 4 +.SH "NAME" +\fBpuppet\-filebucket\fR \- Store and retrieve files in a filebucket . -.nf - - [\-l|\-\-local] [\-r|\-\-remote] - [\-s|\-\-server <server>] [\-b|\-\-bucket <directory>] <file> <file> \.\.\. +.SH "SYNOPSIS" +A stand\-alone Puppet filebucket client\. . -.fi -. -.IP "" 0 -This is a stand\-alone filebucket client for sending files to a local or central filebucket\.This client can operate in three modes, with only one mode per call: +.SH "USAGE" +puppet filebucket \fImode\fR [\-h|\-\-help] [\-V|\-\-version] [\-d|\-\-debug] [\-v|\-\-verbose] [\-l|\-\-local] [\-r|\-\-remote] [\-s|\-\-server \fIserver\fR] [\-b|\-\-bucket \fIdirectory\fR] \fIfile\fR \fIfile\fR \.\.\. . .P -backup: Send one or more files to the specified file bucket\. Each sent -. -.IP "" 4 -. -.nf - - file is printed with its resulting md5 sum\. -. -.fi -. -.IP "" 0 +Puppet filebucket can operate in three modes, with only one mode per call: . .P -get: Return the text associated with an md5 sum\. The text is printed -. -.IP "" 4 -. -.nf - - to stdout, and only one file can be retrieved at a time\. -. -.fi -. -.IP "" 0 +backup: Send one or more files to the specified file bucket\. Each sent file is printed with its resulting md5 sum\. . .P -restore: Given a file path and an md5 sum, store the content associated -. -.IP "" 4 +get: Return the text associated with an md5 sum\. The text is printed to stdout, and only one file can be retrieved at a time\. . -.nf - - with the sum into the specified file path\. You can specify an - entirely new path to this argument; you are not restricted to - restoring the content to its original location\. -. -.fi +.P +restore: Given a file path and an md5 sum, store the content associated with the sum into the specified file path\. You can specify an entirely new path to this argument; you are not restricted to restoring the content to its original location\. . -.IP "" 0 +.SH "DESCRIPTION" +This is a stand\-alone filebucket client for sending files to a local or central filebucket\. . .P -Note that +filebucket+ defaults to using a network\-based filebucket available on the server named +puppet+\. To use this, you\'ll have to be running as a user with valid Puppet certificates\. Alternatively, you can use your local file bucket by specifying +\-\-local+\.$ puppet filebucket backup /etc/passwd /etc/passwd: 429b225650b912a2ee067b0a4cf1e949 $ puppet filebucket restore /tmp/passwd 429b225650b912a2ee067b0a4cf1e949 $Note that any configuration parameter that\'s valid in the configuration file is also a valid long argument\. For example, \'ssldir\' is a valid configuration parameter, so you can specify \'\-\-ssldir \fIdirectory\fR\' as an argument\. +Note that \'filebucket\' defaults to using a network\-based filebucket available on the server named \'puppet\'\. To use this, you\'ll have to be running as a user with valid Puppet certificates\. Alternatively, you can use your local file bucket by specifying \'\-\-local\'\. +. +.SH "OPTIONS" +Note that any configuration parameter that\'s valid in the configuration file is also a valid long argument\. For example, \'ssldir\' is a valid configuration parameter, so you can specify \'\-\-ssldir \fIdirectory\fR\' as an argument\. . .P See the configuration file documentation at http://docs\.puppetlabs\.com/references/stable/configuration\.html for the full list of acceptable parameters\. A commented list of all configuration options can also be generated by running puppet with \'\-\-genconfig\'\. . -.P -debug: Enable full debugging\. +.TP +\-\-debug +Enable full debugging\. . -.P -help: Print this help message +.TP +\-\-help +Print this help message . -.P -local: Use the local filebucket\. This will use the default +.TP +\-\-local +Use the local filebucket\. This will use the default configuration information\. . -.IP "" 4 +.TP +\-\-remote +Use a remote filebucket\. This will use the default configuration information\. . -.nf - - configuration information\. +.TP +\-\-server +The server to send the file to, instead of locally\. . -.fi +.TP +\-\-verbose +Print extra information\. . -.IP "" 0 +.TP +\-\-version +Print version information\. . -.P -remote: Use a remote filebucket\. This will use the default -. -.IP "" 4 +.SH "EXAMPLE" . .nf - configuration information\. +$ puppet filebucket backup /etc/passwd +/etc/passwd: 429b225650b912a2ee067b0a4cf1e949 +$ puppet filebucket restore /tmp/passwd 429b225650b912a2ee067b0a4cf1e949 . .fi . -.IP "" 0 +.SH "AUTHOR" +Luke Kanies . -.P -server: The server to send the file to, instead of locally\. -. -.P -verbose: Print extra information\. -. -.P -version: Print version information\.puppet filebucket \-b /tmp/filebucket /my/fileLuke KaniesCopyright (c) 2005 Puppet Labs, LLC Licensed under the GNU Public License +.SH "COPYRIGHT" +Copyright (c) 2005 Puppet Labs, LLC Licensed under the GNU Public License diff --git a/man/man8/pi.8 b/man/man8/pi.8 index b70a128e7..c54a7bec7 100644 --- a/man/man8/pi.8 +++ b/man/man8/pi.8 @@ -1,17 +1,51 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "PI" "8" "August 2010" "" "" -Print help about puppet types on the console\. Run with \'\-h\' to get detailed help\.puppet describe [\-h|\-\-help] [\-s|\-\-short] [\-p|\-\-providers] [\-l|\-\-list] [\-m|\-\-meta]Prints details of Puppet types, providers and metaparameters on the console\.help: Print this help text +.TH "PUPPET\-DESCRIBE" "8" "February 2011" "Puppet Labs, LLC" "Puppet manual" . -.P -providers: Describe providers in detail for each type +.SH "NAME" +\fBpuppet\-describe\fR \- Display help about resource types . -.P -list: List all types +.SH "SYNOPSIS" +Prints help about Puppet resource types, providers, and metaparameters\. . -.P -meta: List all metaparameters +.SH "USAGE" +puppet describe [\-h|\-\-help] [\-s|\-\-short] [\-p|\-\-providers] [\-l|\-\-list] [\-m|\-\-meta] . -.P -short: List only parameters without detailpuppet describe \-\-list puppet describe file \-\-providers puppet describe user \-s \-mDavid LutterkortCopyright (c) 2005 Puppet Labs, LLC Licensed under the GNU Public License +.SH "OPTIONS" +. +.TP +\-\-help +Print this help text +. +.TP +\-\-providers +Describe providers in detail for each type +. +.TP +\-\-list +List all types +. +.TP +\-\-meta +List all metaparameters +. +.TP +\-\-short +List only parameters without detail +. +.SH "EXAMPLE" +. +.nf + +$ puppet describe \-\-list +$ puppet describe file \-\-providers +$ puppet describe user \-s \-m +. +.fi +. +.SH "AUTHOR" +David Lutterkort +. +.SH "COPYRIGHT" +Copyright (c) 2005 Puppet Labs, LLC Licensed under the GNU Public License diff --git a/man/man8/puppet-agent.8 b/man/man8/puppet-agent.8 new file mode 100644 index 000000000..3fadd9df7 --- /dev/null +++ b/man/man8/puppet-agent.8 @@ -0,0 +1,139 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "PUPPET\-AGENT" "8" "February 2011" "Puppet Labs, LLC" "Puppet manual" +. +.SH "NAME" +\fBpuppet\-agent\fR \- The puppet agent daemon +. +.SH "SYNOPSIS" +Retrieves the client configuration from the puppet master and applies it to the local host\. +. +.P +This service may be run as a daemon, run periodically using cron (or something similar), or run interactively for testing purposes\. +. +.SH "USAGE" +puppet agent [\-D|\-\-daemonize|\-\-no\-daemonize] [\-d|\-\-debug] [\-\-detailed\-exitcodes] [\-\-disable] [\-\-enable] [\-h|\-\-help] [\-\-certname \fIhost name\fR] [\-l|\-\-logdest syslog|\fIfile\fR|console] [\-o|\-\-onetime] [\-\-serve \fIhandler\fR] [\-t|\-\-test] [\-\-noop] [\-\-digest \fIdigest\fR] [\-\-fingerprint] [\-V|\-\-version] [\-v|\-\-verbose] [\-w|\-\-waitforcert \fIseconds\fR] +. +.SH "DESCRIPTION" +This is the main puppet client\. Its job is to retrieve the local machine\'s configuration from a remote server and apply it\. In order to successfully communicate with the remote server, the client must have a certificate signed by a certificate authority that the server trusts; the recommended method for this, at the moment, is to run a certificate authority as part of the puppet server (which is the default)\. The client will connect and request a signed certificate, and will continue connecting until it receives one\. +. +.P +Once the client has a signed certificate, it will retrieve its configuration and apply it\. +. +.SH "USAGE NOTES" +\'puppet agent\' does its best to find a compromise between interactive use and daemon use\. Run with no arguments and no configuration, it will go into the background, attempt to get a signed certificate, and retrieve and apply its configuration every 30 minutes\. +. +.P +Some flags are meant specifically for interactive use \-\- in particular, \'test\', \'tags\' or \'fingerprint\' are useful\. \'test\' enables verbose logging, causes the daemon to stay in the foreground, exits if the server\'s configuration is invalid (this happens if, for instance, you\'ve left a syntax error on the server), and exits after running the configuration once (rather than hanging around as a long\-running process)\. +. +.P +\'tags\' allows you to specify what portions of a configuration you want to apply\. Puppet elements are tagged with all of the class or definition names that contain them, and you can use the \'tags\' flag to specify one of these names, causing only configuration elements contained within that class or definition to be applied\. This is very useful when you are testing new configurations \-\- for instance, if you are just starting to manage \'ntpd\', you would put all of the new elements into an \'ntpd\' class, and call puppet with \'\-\-tags ntpd\', which would only apply that small portion of the configuration during your testing, rather than applying the whole thing\. +. +.P +\'fingerprint\' is a one\-time flag\. In this mode \'puppet agent\' will run once and display on the console (and in the log) the current certificate (or certificate request) fingerprint\. Providing the \'\-\-digest\' option allows to use a different digest algorithm to generate the fingerprint\. The main use is to verify that before signing a certificate request on the master, the certificate request the master received is the same as the one the client sent (to prevent against man\-in\-the\-middle attacks when signing certificates)\. +. +.SH "OPTIONS" +Note that any configuration parameter that\'s valid in the configuration file is also a valid long argument\. For example, \'server\' is a valid configuration parameter, so you can specify \'\-\-server \fIservername\fR\' as an argument\. +. +.P +See the configuration file documentation at http://docs\.puppetlabs\.com/references/stable/configuration\.html for the full list of acceptable parameters\. A commented list of all configuration options can also be generated by running puppet agent with \'\-\-genconfig\'\. +. +.TP +\-\-daemonize +Send the process into the background\. This is the default\. +. +.TP +\-\-no\-daemonize +Do not send the process into the background\. +. +.TP +\-\-debug +Enable full debugging\. +. +.TP +\-\-digest +Change the certificate fingerprinting digest algorithm\. The default is MD5\. Valid values depends on the version of OpenSSL installed, but should always at least contain MD5, MD2, SHA1 and SHA256\. +. +.TP +\-\-detailed\-exitcodes +Provide transaction information via exit codes\. If this is enabled, an exit code of \'2\' means there were changes, and an exit code of \'4\' means that there were failures during the transaction\. This option only makes sense in conjunction with \-\-onetime\. +. +.TP +\-\-disable +Disable working on the local system\. This puts a lock file in place, causing \'puppet agent\' not to work on the system until the lock file is removed\. This is useful if you are testing a configuration and do not want the central configuration to override the local state until everything is tested and committed\. +. +.IP +\'puppet agent\' uses the same lock file while it is running, so no more than one \'puppet agent\' process is working at a time\. +. +.IP +\'puppet agent\' exits after executing this\. +. +.TP +\-\-enable +Enable working on the local system\. This removes any lock file, causing \'puppet agent\' to start managing the local system again (although it will continue to use its normal scheduling, so it might not start for another half hour)\. +. +.IP +\'puppet agent\' exits after executing this\. +. +.TP +\-\-certname +Set the certname (unique ID) of the client\. The master reads this unique identifying string, which is usually set to the node\'s fully\-qualified domain name, to determine which configurations the node will receive\. Use this option to debug setup problems or implement unusual node identification schemes\. +. +.TP +\-\-help +Print this help message +. +.TP +\-\-logdest +Where to send messages\. Choose between syslog, the console, and a log file\. Defaults to sending messages to syslog, or the console if debugging or verbosity is enabled\. +. +.TP +\-\-no\-client +Do not create a config client\. This will cause the daemon to run without ever checking for its configuration automatically, and only makes sense +. +.TP +\-\-onetime +Run the configuration once\. Runs a single (normally daemonized) Puppet run\. Useful for interactively running puppet agent when used in conjunction with the \-\-no\-daemonize option\. +. +.TP +\-\-fingerprint +Display the current certificate or certificate signing request fingerprint and then exit\. Use the \'\-\-digest\' option to change the digest algorithm used\. +. +.TP +\-\-serve +Start another type of server\. By default, \'puppet agent\' will start a service handler that allows authenticated and authorized remote nodes to trigger the configuration to be pulled down and applied\. You can specify any handler here that does not require configuration, e\.g\., filebucket, ca, or resource\. The handlers are in \'lib/puppet/network/handler\', and the names must match exactly, both in the call to \'serve\' and in \'namespaceauth\.conf\'\. +. +.TP +\-\-test +Enable the most common options used for testing\. These are \'onetime\', \'verbose\', \'ignorecache\', \'no\-daemonize\', \'no\-usecacheonfailure\', \'detailed\-exit\-codes\', \'no\-splay\', and \'show_diff\'\. +. +.TP +\-\-noop +Use \'noop\' mode where the daemon runs in a no\-op or dry\-run mode\. This is useful for seeing what changes Puppet will make without actually executing the changes\. +. +.TP +\-\-verbose +Turn on verbose reporting\. +. +.TP +\-\-version +Print the puppet version number and exit\. +. +.TP +\-\-waitforcert +This option only matters for daemons that do not yet have certificates and it is enabled by default, with a value of 120 (seconds)\. This causes \'puppet agent\' to connect to the server every 2 minutes and ask it to sign a certificate request\. This is useful for the initial setup of a puppet client\. You can turn off waiting for certificates by specifying a time of 0\. +. +.SH "EXAMPLE" +. +.nf + +$ puppet agent \-\-server puppet\.domain\.com +. +.fi +. +.SH "AUTHOR" +Luke Kanies +. +.SH "COPYRIGHT" +Copyright (c) 2005, 2006 Puppet Labs, LLC Licensed under the GNU Public License diff --git a/man/man8/puppet-apply.8 b/man/man8/puppet-apply.8 new file mode 100644 index 000000000..d8d864b56 --- /dev/null +++ b/man/man8/puppet-apply.8 @@ -0,0 +1,75 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "PUPPET\-APPLY" "8" "February 2011" "Puppet Labs, LLC" "Puppet manual" +. +.SH "NAME" +\fBpuppet\-apply\fR \- Apply Puppet manifests locally +. +.SH "SYNOPSIS" +Applies a standalone Puppet manifest to the local system\. +. +.SH "USAGE" +puppet apply [\-h|\-\-help] [\-V|\-\-version] [\-d|\-\-debug] [\-v|\-\-verbose] [\-e|\-\-execute] [\-\-detailed\-exitcodes] [\-l|\-\-logdest \fIfile\fR] [\-\-apply \fIcatalog\fR] \fIfile\fR +. +.SH "DESCRIPTION" +This is the standalone puppet execution tool; use it to apply individual manifests\. +. +.P +When provided with a modulepath, via command line or config file, puppet apply can effectively mimic the catalog that would be served by puppet master with access to the same modules, although there are some subtle differences\. When combined with scheduling and an automated system for pushing manifests, this can be used to implement a serverless Puppet site\. +. +.P +Most users should use \'puppet agent\' and \'puppet master\' for site\-wide manifests\. +. +.SH "OPTIONS" +Note that any configuration parameter that\'s valid in the configuration file is also a valid long argument\. For example, \'modulepath\' is a valid configuration parameter, so you can specify \'\-\-tags \fIclass\fR,\fItag\fR\' as an argument\. +. +.P +See the configuration file documentation at http://docs\.puppetlabs\.com/references/stable/configuration\.html for the full list of acceptable parameters\. A commented list of all configuration options can also be generated by running puppet with \'\-\-genconfig\'\. +. +.TP +\-\-debug +Enable full debugging\. +. +.TP +\-\-detailed\-exitcodes +Provide transaction information via exit codes\. If this is enabled, an exit code of \'2\' means there were changes, and an exit code of \'4\' means that there were failures during the transaction\. +. +.TP +\-\-help +Print this help message +. +.TP +\-\-loadclasses +Load any stored classes\. \'puppet agent\' caches configured classes (usually at /etc/puppet/classes\.txt), and setting this option causes all of those classes to be set in your puppet manifest\. +. +.TP +\-\-logdest +Where to send messages\. Choose between syslog, the console, and a log file\. Defaults to sending messages to the console\. +. +.TP +\-\-execute +Execute a specific piece of Puppet code +. +.TP +\-\-verbose +Print extra information\. +. +.TP +\-\-apply +Apply a JSON catalog (such as one generated with \'puppet master \-\-compile\')\. You can either specify a JSON file or pipe in JSON from standard input\. +. +.SH "EXAMPLE" +. +.nf + +$ puppet apply \-l /tmp/manifest\.log manifest\.pp +$ puppet apply \-\-modulepath=/root/dev/modules \-e "include ntpd::server" +. +.fi +. +.SH "AUTHOR" +Luke Kanies +. +.SH "COPYRIGHT" +Copyright (c) 2005 Puppet Labs, LLC Licensed under the GNU Public License diff --git a/man/man8/puppet-cert.8 b/man/man8/puppet-cert.8 new file mode 100644 index 000000000..bea7596d4 --- /dev/null +++ b/man/man8/puppet-cert.8 @@ -0,0 +1,94 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "PUPPET\-CERT" "8" "February 2011" "Puppet Labs, LLC" "Puppet manual" +. +.SH "NAME" +\fBpuppet\-cert\fR \- Manage certificates and requests +. +.SH "SYNOPSIS" +Standalone certificate authority\. Capable of generating certificates, but mostly used for signing certificate requests from puppet clients\. +. +.SH "USAGE" +puppet cert [\-h|\-\-help] [\-V|\-\-version] [\-d|\-\-debug] [\-v|\-\-verbose] [\-g|\-\-generate] [\-l|\-\-list] [\-s|\-\-sign] [\-r|\-\-revoke] [\-p|\-\-print] [\-c|\-\-clean] [\-\-verify] [\-\-digest \fIdigest\fR] [\-\-fingerprint] [host] +. +.SH "DESCRIPTION" +Because the puppet master service defaults to not signing client certificate requests, this script is available for signing outstanding requests\. It can be used to list outstanding requests and then either sign them individually or sign all of them\. +. +.SH "OPTIONS" +Note that any configuration parameter that\'s valid in the configuration file is also a valid long argument\. For example, \'ssldir\' is a valid configuration parameter, so you can specify \'\-\-ssldir \fIdirectory\fR\' as an argument\. +. +.P +See the configuration file documentation at http://docs\.puppetlabs\.com/references/stable/configuration\.html for the full list of acceptable parameters\. A commented list of all configuration options can also be generated by running puppet cert with \'\-\-genconfig\'\. +. +.TP +\-\-all +Operate on all items\. Currently only makes sense with \'\-\-sign\', \'\-\-clean\', or \'\-\-list\'\. +. +.TP +\-\-digest +Set the digest for fingerprinting (defaults to md5)\. Valid values depends on your openssl and openssl ruby extension version, but should contain at least md5, sha1, md2, sha256\. +. +.TP +\-\-clean +Remove all files related to a host from puppet cert\'s storage\. This is useful when rebuilding hosts, since new certificate signing requests will only be honored if puppet cert does not have a copy of a signed certificate for that host\. The certificate of the host is also revoked\. If \'\-\-all\' is specified then all host certificates, both signed and unsigned, will be removed\. +. +.TP +\-\-debug +Enable full debugging\. +. +.TP +\-\-generate +Generate a certificate for a named client\. A certificate/keypair will be generated for each client named on the command line\. +. +.TP +\-\-help +Print this help message +. +.TP +\-\-list +List outstanding certificate requests\. If \'\-\-all\' is specified, signed certificates are also listed, prefixed by \'+\', and revoked or invalid certificates are prefixed by \'\-\' (the verification outcome is printed in parenthesis)\. +. +.TP +\-\-print +Print the full\-text version of a host\'s certificate\. +. +.TP +\-\-fingerprint +Print the DIGEST (defaults to md5) fingerprint of a host\'s certificate\. +. +.TP +\-\-revoke +Revoke the certificate of a client\. The certificate can be specified either by its serial number, given as a decimal number or a hexadecimal number prefixed by \'0x\', or by its hostname\. The certificate is revoked by adding it to the Certificate Revocation List given by the \'cacrl\' config parameter\. Note that the puppetmasterd needs to be restarted after revoking certificates\. +. +.TP +\-\-sign +Sign an outstanding certificate request\. Unless \'\-\-all\' is specified, hosts must be listed after all flags\. +. +.TP +\-\-verbose +Enable verbosity\. +. +.TP +\-\-version +Print the puppet version number and exit\. +. +.TP +\-\-verify +Verify the named certificate against the local CA certificate\. +. +.SH "EXAMPLE" +. +.nf + +$ puppet cert \-l +culain\.madstop\.com +$ puppet cert \-s culain\.madstop\.com +. +.fi +. +.SH "AUTHOR" +Luke Kanies +. +.SH "COPYRIGHT" +Copyright (c) 2005 Puppet Labs, LLC Licensed under the GNU Public License diff --git a/man/man8/puppet-describe.8 b/man/man8/puppet-describe.8 new file mode 100644 index 000000000..c54a7bec7 --- /dev/null +++ b/man/man8/puppet-describe.8 @@ -0,0 +1,51 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "PUPPET\-DESCRIBE" "8" "February 2011" "Puppet Labs, LLC" "Puppet manual" +. +.SH "NAME" +\fBpuppet\-describe\fR \- Display help about resource types +. +.SH "SYNOPSIS" +Prints help about Puppet resource types, providers, and metaparameters\. +. +.SH "USAGE" +puppet describe [\-h|\-\-help] [\-s|\-\-short] [\-p|\-\-providers] [\-l|\-\-list] [\-m|\-\-meta] +. +.SH "OPTIONS" +. +.TP +\-\-help +Print this help text +. +.TP +\-\-providers +Describe providers in detail for each type +. +.TP +\-\-list +List all types +. +.TP +\-\-meta +List all metaparameters +. +.TP +\-\-short +List only parameters without detail +. +.SH "EXAMPLE" +. +.nf + +$ puppet describe \-\-list +$ puppet describe file \-\-providers +$ puppet describe user \-s \-m +. +.fi +. +.SH "AUTHOR" +David Lutterkort +. +.SH "COPYRIGHT" +Copyright (c) 2005 Puppet Labs, LLC Licensed under the GNU Public License diff --git a/man/man8/puppet-doc.8 b/man/man8/puppet-doc.8 new file mode 100644 index 000000000..e0cabd5d1 --- /dev/null +++ b/man/man8/puppet-doc.8 @@ -0,0 +1,101 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "PUPPET\-DOC" "8" "February 2011" "Puppet Labs, LLC" "Puppet manual" +. +.SH "NAME" +\fBpuppet\-doc\fR \- Generate Puppet documentation and references +. +.SH "SYNOPSIS" +Generates a reference for all Puppet types\. Largely meant for internal Puppet Labs use\. +. +.SH "USAGE" +puppet doc [\-a|\-\-all] [\-h|\-\-help] [\-o|\-\-outputdir \fIrdoc\-outputdir\fR] [\-m|\-\-mode text|pdf|rdoc] [\-r|\-\-reference \fIreference\-name\fR] [\-\-charset \fIcharset\fR] [\fImanifest\-file\fR] +. +.SH "DESCRIPTION" +If mode is not \'rdoc\', then this command generates a Markdown document describing all installed Puppet types or all allowable arguments to puppet executables\. It is largely meant for internal use and is used to generate the reference document available on the Puppet Labs web site\. +. +.P +In \'rdoc\' mode, this command generates an html RDoc hierarchy describing the manifests that are in \'manifestdir\' and \'modulepath\' configuration directives\. The generated documentation directory is doc by default but can be changed with the \'outputdir\' option\. +. +.P +If the command is run with the name of a manifest file as an argument, puppet doc will output a single manifest\'s documentation on stdout\. +. +.SH "OPTIONS" +. +.TP +\-\-all +Output the docs for all of the reference types\. In \'rdoc\' modes, this also outputs documentation for all resources +. +.TP +\-\-help +Print this help message +. +.TP +\-\-outputdir +Specifies the directory where to output the rdoc documentation in \'rdoc\' mode\. +. +.TP +\-\-mode +Determine the output mode\. Valid modes are \'text\', \'pdf\' and \'rdoc\'\. The \'pdf\' mode creates PDF formatted files in the /tmp directory\. The default mode is \'text\'\. In \'rdoc\' mode you must provide \'manifests\-path\' +. +.TP +\-\-reference +Build a particular reference\. Get a list of references by running \'puppet doc \-\-list\'\. +. +.TP +\-\-charset +Used only in \'rdoc\' mode\. It sets the charset used in the html files produced\. +. +.SH "EXAMPLE" +. +.nf + +$ puppet doc \-r type > /tmp/type_reference\.markdown +. +.fi +. +.P +or +. +.IP "" 4 +. +.nf + +$ puppet doc \-\-outputdir /tmp/rdoc \-\-mode rdoc /path/to/manifests +. +.fi +. +.IP "" 0 +. +.P +or +. +.IP "" 4 +. +.nf + +$ puppet doc /etc/puppet/manifests/site\.pp +. +.fi +. +.IP "" 0 +. +.P +or +. +.IP "" 4 +. +.nf + +$ puppet doc \-m pdf \-r configuration +. +.fi +. +.IP "" 0 +. +.SH "AUTHOR" +Luke Kanies +. +.SH "COPYRIGHT" +Copyright (c) 2005\-2007 Puppet Labs, LLC Licensed under the GNU Public License diff --git a/man/man8/puppet-filebucket.8 b/man/man8/puppet-filebucket.8 new file mode 100644 index 000000000..7ff0da9af --- /dev/null +++ b/man/man8/puppet-filebucket.8 @@ -0,0 +1,81 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "PUPPET\-FILEBUCKET" "8" "February 2011" "Puppet Labs, LLC" "Puppet manual" +. +.SH "NAME" +\fBpuppet\-filebucket\fR \- Store and retrieve files in a filebucket +. +.SH "SYNOPSIS" +A stand\-alone Puppet filebucket client\. +. +.SH "USAGE" +puppet filebucket \fImode\fR [\-h|\-\-help] [\-V|\-\-version] [\-d|\-\-debug] [\-v|\-\-verbose] [\-l|\-\-local] [\-r|\-\-remote] [\-s|\-\-server \fIserver\fR] [\-b|\-\-bucket \fIdirectory\fR] \fIfile\fR \fIfile\fR \.\.\. +. +.P +Puppet filebucket can operate in three modes, with only one mode per call: +. +.P +backup: Send one or more files to the specified file bucket\. Each sent file is printed with its resulting md5 sum\. +. +.P +get: Return the text associated with an md5 sum\. The text is printed to stdout, and only one file can be retrieved at a time\. +. +.P +restore: Given a file path and an md5 sum, store the content associated with the sum into the specified file path\. You can specify an entirely new path to this argument; you are not restricted to restoring the content to its original location\. +. +.SH "DESCRIPTION" +This is a stand\-alone filebucket client for sending files to a local or central filebucket\. +. +.P +Note that \'filebucket\' defaults to using a network\-based filebucket available on the server named \'puppet\'\. To use this, you\'ll have to be running as a user with valid Puppet certificates\. Alternatively, you can use your local file bucket by specifying \'\-\-local\'\. +. +.SH "OPTIONS" +Note that any configuration parameter that\'s valid in the configuration file is also a valid long argument\. For example, \'ssldir\' is a valid configuration parameter, so you can specify \'\-\-ssldir \fIdirectory\fR\' as an argument\. +. +.P +See the configuration file documentation at http://docs\.puppetlabs\.com/references/stable/configuration\.html for the full list of acceptable parameters\. A commented list of all configuration options can also be generated by running puppet with \'\-\-genconfig\'\. +. +.TP +\-\-debug +Enable full debugging\. +. +.TP +\-\-help +Print this help message +. +.TP +\-\-local +Use the local filebucket\. This will use the default configuration information\. +. +.TP +\-\-remote +Use a remote filebucket\. This will use the default configuration information\. +. +.TP +\-\-server +The server to send the file to, instead of locally\. +. +.TP +\-\-verbose +Print extra information\. +. +.TP +\-\-version +Print version information\. +. +.SH "EXAMPLE" +. +.nf + +$ puppet filebucket backup /etc/passwd +/etc/passwd: 429b225650b912a2ee067b0a4cf1e949 +$ puppet filebucket restore /tmp/passwd 429b225650b912a2ee067b0a4cf1e949 +. +.fi +. +.SH "AUTHOR" +Luke Kanies +. +.SH "COPYRIGHT" +Copyright (c) 2005 Puppet Labs, LLC Licensed under the GNU Public License diff --git a/man/man8/puppet-inspect.8 b/man/man8/puppet-inspect.8 new file mode 100644 index 000000000..ae19deede --- /dev/null +++ b/man/man8/puppet-inspect.8 @@ -0,0 +1,28 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "PUPPET\-INSPECT" "8" "February 2011" "Puppet Labs, LLC" "Puppet manual" +. +.SH "NAME" +\fBpuppet\-inspect\fR \- Send an inspection report +. +.SH "SYNOPSIS" +Prepares and submits an inspection report to the puppet master\. +. +.SH "USAGE" +puppet inspect +. +.SH "DESCRIPTION" +This command uses the cached catalog from the previous run of \'puppet agent\' to determine which attributes of which resources have been marked as auditable with the \'audit\' metaparameter\. It then examines the current state of the system, writes the state of the specified resource attributes to a report, and submits the report to the puppet master\. +. +.P +Puppet inspect does not run as a daemon, and must be run manually or from cron\. +. +.SH "OPTIONS" +Any configuration setting which is valid in the configuration file is also a valid long argument, e\.g\. \'\-\-server=master\.domain\.com\'\. See the configuration file documentation at http://docs\.puppetlabs\.com/references/latest/configuration\.html for the full list of acceptable settings\. +. +.SH "AUTHOR" +Puppet Labs +. +.SH "COPYRIGHT" +Copyright (c) 2011 Puppet Labs, LLC Licensed under the GNU General Public License version 2 diff --git a/man/man8/puppet-kick.8 b/man/man8/puppet-kick.8 new file mode 100644 index 000000000..b6a868918 --- /dev/null +++ b/man/man8/puppet-kick.8 @@ -0,0 +1,115 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "PUPPET\-KICK" "8" "February 2011" "Puppet Labs, LLC" "Puppet manual" +. +.SH "NAME" +\fBpuppet\-kick\fR \- Remotely control puppet agent +. +.SH "SYNOPSIS" +Trigger a puppet agent run on a set of hosts\. +. +.SH "USAGE" +puppet kick [\-a|\-\-all] [\-c|\-\-class \fIclass\fR] [\-d|\-\-debug] [\-f|\-\-foreground] [\-h|\-\-help] [\-\-host \fIhost\fR] [\-\-no\-fqdn] [\-\-ignoreschedules] [\-t|\-\-tag \fItag\fR] [\-\-test] [\-p|\-\-ping] \fIhost\fR [\fIhost\fR [\.\.\.]] +. +.SH "DESCRIPTION" +This script can be used to connect to a set of machines running \'puppet agent\' and trigger them to run their configurations\. The most common usage would be to specify a class of hosts and a set of tags, and \'puppet kick\' would look up in LDAP all of the hosts matching that class, then connect to each host and trigger a run of all of the objects with the specified tags\. +. +.P +If you are not storing your host configurations in LDAP, you can specify hosts manually\. +. +.P +You will most likely have to run \'puppet kick\' as root to get access to the SSL certificates\. +. +.P +\'puppet kick\' reads \'puppet master\'\'s configuration file, so that it can copy things like LDAP settings\. +. +.SH "USAGE NOTES" +\'puppet kick\' is useless unless \'puppet agent\' is listening\. See its documentation for more information, but the gist is that you must enable \'listen\' on the \'puppet agent\' daemon, either using \'\-\-listen\' on the command line or adding \'listen = true\' in its config file\. In addition, you need to set the daemons up to specifically allow connections by creating the \'namespaceauth\' file, normally at \'/etc/puppet/namespaceauth\.conf\'\. This file specifies who has access to each namespace; if you create the file you must add every namespace you want any Puppet daemon to allow \-\- it is currently global to all Puppet daemons\. +. +.P +An example file looks like this: +. +.IP "" 4 +. +.nf + +[fileserver] + allow *\.madstop\.com + +[puppetmaster] + allow *\.madstop\.com + +[puppetrunner] + allow culain\.madstop\.com +. +.fi +. +.IP "" 0 +. +.P +This is what you would install on your Puppet master; non\-master hosts could leave off the \'fileserver\' and \'puppetmaster\' namespaces\. +. +.SH "OPTIONS" +Note that any configuration parameter that\'s valid in the configuration file is also a valid long argument\. For example, \'ssldir\' is a valid configuration parameter, so you can specify \'\-\-ssldir \fIdirectory\fR\' as an argument\. +. +.P +See the configuration file documentation at http://docs\.puppetlabs\.com/references/latest/configuration\.html for the full list of acceptable parameters\. A commented list of all configuration options can also be generated by running puppet master with \'\-\-genconfig\'\. +. +.TP +\-\-all +Connect to all available hosts\. Requires LDAP support at this point\. +. +.TP +\-\-class +Specify a class of machines to which to connect\. This only works if you have LDAP configured, at the moment\. +. +.TP +\-\-debug +Enable full debugging\. +. +.TP +\-\-foreground +Run each configuration in the foreground; that is, when connecting to a host, do not return until the host has finished its run\. The default is false\. +. +.TP +\-\-help +Print this help message +. +.TP +\-\-host +A specific host to which to connect\. This flag can be specified more than once\. +. +.TP +\-\-ignoreschedules +Whether the client should ignore schedules when running its configuration\. This can be used to force the client to perform work it would not normally perform so soon\. The default is false\. +. +.TP +\-\-parallel +How parallel to make the connections\. Parallelization is provided by forking for each client to which to connect\. The default is 1, meaning serial execution\. +. +.TP +\-\-tag +Specify a tag for selecting the objects to apply\. Does not work with the \-\-test option\. +. +.TP +\-\-test +Print the hosts you would connect to but do not actually connect\. This option requires LDAP support at this point\. +. +.TP +\-\-ping +Do a ICMP echo against the target host\. Skip hosts that don\'t respond to ping\. +. +.SH "EXAMPLE" +. +.nf + +$ sudo puppet kick \-p 10 \-t remotefile \-t webserver host1 host2 +. +.fi +. +.SH "AUTHOR" +Luke Kanies +. +.SH "COPYRIGHT" +Copyright (c) 2005 Puppet Labs, LLC Licensed under the GNU Public License diff --git a/man/man8/puppet-master.8 b/man/man8/puppet-master.8 new file mode 100644 index 000000000..9ed2a6ad6 --- /dev/null +++ b/man/man8/puppet-master.8 @@ -0,0 +1,63 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "PUPPET\-MASTER" "8" "February 2011" "Puppet Labs, LLC" "Puppet manual" +. +.SH "NAME" +\fBpuppet\-master\fR \- The puppet master daemon +. +.SH "SYNOPSIS" +The central puppet server\. Functions as a certificate authority by default\. +. +.SH "USAGE" +puppet master [\-D|\-\-daemonize|\-\-no\-daemonize] [\-d|\-\-debug] [\-h|\-\-help] [\-l|\-\-logdest \fIfile\fR|console|syslog] [\-v|\-\-verbose] [\-V|\-\-version] [\-\-compile \fInode\-name\fR] +. +.SH "DESCRIPTION" +This command starts an instance of puppet master, running as a daemon and using Ruby\'s built\-in Webrick webserver\. Puppet master can also be managed by other application servers; when this is the case, this executable is not used\. +. +.SH "OPTIONS" +Note that any configuration parameter that\'s valid in the configuration file is also a valid long argument\. For example, \'ssldir\' is a valid configuration parameter, so you can specify \'\-\-ssldir \fIdirectory\fR\' as an argument\. +. +.P +See the configuration file documentation at http://docs\.puppetlabs\.com/references/stable/configuration\.html for the full list of acceptable parameters\. A commented list of all configuration options can also be generated by running puppet master with \'\-\-genconfig\'\. +. +.TP +\-\-daemonize +Send the process into the background\. This is the default\. +. +.TP +\-\-no\-daemonize +Do not send the process into the background\. +. +.TP +\-\-debug +Enable full debugging\. +. +.TP +\-\-help +Print this help message\. +. +.TP +\-\-logdest +Where to send messages\. Choose between syslog, the console, and a log file\. Defaults to sending messages to syslog, or the console if debugging or verbosity is enabled\. +. +.TP +\-\-verbose +Enable verbosity\. +. +.TP +\-\-version +Print the puppet version number and exit\. +. +.TP +\-\-compile +Compile a catalogue and output it in JSON from the puppet master\. Uses facts contained in the $vardir/yaml/ directory to compile the catalog\. +. +.SH "EXAMPLE" +puppet master +. +.SH "AUTHOR" +Luke Kanies +. +.SH "COPYRIGHT" +Copyright (c) 2005 Puppet Labs, LLC Licensed under the GNU Public License diff --git a/man/man8/puppet-queue.8 b/man/man8/puppet-queue.8 new file mode 100644 index 000000000..7dbd683bf --- /dev/null +++ b/man/man8/puppet-queue.8 @@ -0,0 +1,55 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "PUPPET\-QUEUE" "8" "February 2011" "Puppet Labs, LLC" "Puppet manual" +. +.SH "NAME" +\fBpuppet\-queue\fR \- Queuing daemon for asynchronous storeconfigs +. +.SH "SYNOPSIS" +Retrieves serialized storeconfigs records from a queue and processes them in order\. +. +.SH "USAGE" +puppet queue [\-d|\-\-debug] [\-v|\-\-verbose] +. +.SH "DESCRIPTION" +This application runs as a daemon and processes storeconfigs data, retrieving the data from a stomp server message queue and writing it to a database\. +. +.P +For more information, including instructions for properly setting up your puppet master and message queue, see the documentation on setting up asynchronous storeconfigs at: http://projects\.puppetlabs\.com/projects/1/wiki/Using_Stored_Configuration +. +.SH "OPTIONS" +Note that any configuration parameter that\'s valid in the configuration file is also a valid long argument\. For example, \'server\' is a valid configuration parameter, so you can specify \'\-\-server \fIservername\fR\' as an argument\. +. +.P +See the configuration file documentation at http://docs\.puppetlabs\.com/references/stable/configuration\.html for the full list of acceptable parameters\. A commented list of all configuration options can also be generated by running puppet queue with \'\-\-genconfig\'\. +. +.TP +\-\-debug +Enable full debugging\. +. +.TP +\-\-help +Print this help message +. +.TP +\-\-verbose +Turn on verbose reporting\. +. +.TP +\-\-version +Print the puppet version number and exit\. +. +.SH "EXAMPLE" +. +.nf + +$ puppet queue +. +.fi +. +.SH "AUTHOR" +Luke Kanies +. +.SH "COPYRIGHT" +Copyright (c) 2009 Puppet Labs, LLC Licensed under the GNU Public License diff --git a/man/man8/puppet-resource.8 b/man/man8/puppet-resource.8 new file mode 100644 index 000000000..738537e84 --- /dev/null +++ b/man/man8/puppet-resource.8 @@ -0,0 +1,84 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "PUPPET\-RESOURCE" "8" "February 2011" "Puppet Labs, LLC" "Puppet manual" +. +.SH "NAME" +\fBpuppet\-resource\fR \- The resource abstraction layer shell +. +.SH "SYNOPSIS" +Uses the Puppet RAL to directly interact with the system\. +. +.SH "USAGE" +puppet resource [\-h|\-\-help] [\-d|\-\-debug] [\-v|\-\-verbose] [\-e|\-\-edit] [\-H|\-\-host \fIhost\fR] [\-p|\-\-param \fIparameter\fR] [\-t|\-\-types] \fItype\fR [\fIname\fR] [\fIattribute\fR=\fIvalue\fR \.\.\.] +. +.SH "DESCRIPTION" +This command provides simple facilities for converting current system state into Puppet code, along with some ability to modify the current state using Puppet\'s RAL\. +. +.P +By default, you must at least provide a type to list, in which case puppet resource will tell you everything it knows about all resources of that type\. You can optionally specify an instance name, and puppet resource will only describe that single instance\. +. +.P +If given a type, a name, and a series of \fIattribute\fR=\fIvalue\fR pairs, puppet resource will modify the state of the specified resource\. Alternately, if given a type, a name, and the \'\-\-edit\' flag, puppet resource will write its output to a file, open that file in an editor, and then apply the saved file as a Puppet transaction\. +. +.SH "OPTIONS" +Note that any configuration parameter that\'s valid in the configuration file is also a valid long argument\. For example, \'ssldir\' is a valid configuration parameter, so you can specify \'\-\-ssldir \fIdirectory\fR\' as an argument\. +. +.P +See the configuration file documentation at http://docs\.puppetlabs\.com/references/stable/configuration\.html for the full list of acceptable parameters\. A commented list of all configuration options can also be generated by running puppet with \'\-\-genconfig\'\. +. +.TP +\-\-debug +Enable full debugging\. +. +.TP +\-\-edit +Write the results of the query to a file, open the file in an editor, and read the file back in as an executable Puppet manifest\. +. +.TP +\-\-host +When specified, connect to the resource server on the named host and retrieve the list of resouces of the type specified\. +. +.TP +\-\-help +Print this help message\. +. +.TP +\-\-param +Add more parameters to be outputted from queries\. +. +.TP +\-\-types +List all available types\. +. +.TP +\-\-verbose +Print extra information\. +. +.SH "EXAMPLE" +This example uses \fBpuppet resource\fR to return a Puppet configuration for the user \fBluke\fR: +. +.IP "" 4 +. +.nf + +$ puppet resource user luke +user { \'luke\': + home => \'/home/luke\', + uid => \'100\', + ensure => \'present\', + comment => \'Luke Kanies,,,\', + gid => \'1000\', + shell => \'/bin/bash\', + groups => [\'sysadmin\',\'audio\',\'video\',\'puppet\'] +} +. +.fi +. +.IP "" 0 +. +.SH "AUTHOR" +Luke Kanies +. +.SH "COPYRIGHT" +Copyright (c) 2005\-2007 Puppet Labs, LLC Licensed under the GNU Public License diff --git a/man/man8/puppet.8 b/man/man8/puppet.8 index 513d45338..f58a54d41 100644 --- a/man/man8/puppet.8 +++ b/man/man8/puppet.8 @@ -1,10 +1,10 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "PUPPET" "8" "August 2010" "" "" +.TH "PUPPET" "8" "February 2011" "Puppet Labs, LLC" "Puppet manual" . .SH "NAME" \fBpuppet\fR . .P -Usage: puppet command \fIspace separated arguments\fR Available commands are: agent, apply, cert, describe, doc, filebucket, kick, master, queue, resource +Usage: puppet command \fIspace separated arguments\fR Available commands are: agent, apply, cert, describe, doc, filebucket, inspect, kick, master, queue, resource diff --git a/man/man8/puppetca.8 b/man/man8/puppetca.8 index 62fa7a5bf..bea7596d4 100644 --- a/man/man8/puppetca.8 +++ b/man/man8/puppetca.8 @@ -1,169 +1,94 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "PUPPETCA" "8" "August 2010" "" "" -Stand\-alone certificate authority\. Capable of generating certificates but mostly meant for signing certificate requests from puppet clients\.puppet cert [\-h|\-\-help] [\-V|\-\-version] [\-d|\-\-debug] [\-v|\-\-verbose] +.TH "PUPPET\-CERT" "8" "February 2011" "Puppet Labs, LLC" "Puppet manual" . -.IP "" 4 +.SH "NAME" +\fBpuppet\-cert\fR \- Manage certificates and requests . -.nf - - [\-g|\-\-generate] [\-l|\-\-list] [\-s|\-\-sign] [\-r|\-\-revoke] - [\-p|\-\-print] [\-c|\-\-clean] [\-\-verify] [\-\-digest DIGEST] - [\-\-fingerprint] [host] -. -.fi -. -.IP "" 0 -Because the puppetmasterd daemon defaults to not signing client certificate requests, this script is available for signing outstanding requests\. It can be used to list outstanding requests and then either sign them individually or sign all of them\.Note that any configuration parameter that\'s valid in the configuration file is also a valid long argument\. For example, \'ssldir\' is a valid configuration parameter, so you can specify \'\-\-ssldir \fIdirectory\fR\' as an argument\. -. -.P -See the configuration file documentation at http://reductivelabs\.com/projects/puppet/reference/configref\.html for the full list of acceptable parameters\. A commented list of all configuration options can also be generated by running puppet cert with \'\-\-genconfig\'\. -. -.P -all: Operate on all items\. Currently only makes sense with +.SH "SYNOPSIS" +Standalone certificate authority\. Capable of generating certificates, but mostly used for signing certificate requests from puppet clients\. . -.IP "" 4 +.SH "USAGE" +puppet cert [\-h|\-\-help] [\-V|\-\-version] [\-d|\-\-debug] [\-v|\-\-verbose] [\-g|\-\-generate] [\-l|\-\-list] [\-s|\-\-sign] [\-r|\-\-revoke] [\-p|\-\-print] [\-c|\-\-clean] [\-\-verify] [\-\-digest \fIdigest\fR] [\-\-fingerprint] [host] . -.nf - - \'\-\-sign\', \'\-\-clean\', or \'\-\-list\'\. +.SH "DESCRIPTION" +Because the puppet master service defaults to not signing client certificate requests, this script is available for signing outstanding requests\. It can be used to list outstanding requests and then either sign them individually or sign all of them\. . -.fi -. -.IP "" 0 +.SH "OPTIONS" +Note that any configuration parameter that\'s valid in the configuration file is also a valid long argument\. For example, \'ssldir\' is a valid configuration parameter, so you can specify \'\-\-ssldir \fIdirectory\fR\' as an argument\. . .P -digest: Set the digest for fingerprinting (defaults to md5)\. Valid -. -.IP "" 4 -. -.nf - - values depends on your openssl and openssl ruby extension - version, but should contain at least md5, sha1, md2, - sha256\. -. -.fi +See the configuration file documentation at http://docs\.puppetlabs\.com/references/stable/configuration\.html for the full list of acceptable parameters\. A commented list of all configuration options can also be generated by running puppet cert with \'\-\-genconfig\'\. . -.IP "" 0 +.TP +\-\-all +Operate on all items\. Currently only makes sense with \'\-\-sign\', \'\-\-clean\', or \'\-\-list\'\. . -.P -clean: Remove all files related to a host from puppet cert\'s +.TP +\-\-digest +Set the digest for fingerprinting (defaults to md5)\. Valid values depends on your openssl and openssl ruby extension version, but should contain at least md5, sha1, md2, sha256\. . -.IP "" 4 +.TP +\-\-clean +Remove all files related to a host from puppet cert\'s storage\. This is useful when rebuilding hosts, since new certificate signing requests will only be honored if puppet cert does not have a copy of a signed certificate for that host\. The certificate of the host is also revoked\. If \'\-\-all\' is specified then all host certificates, both signed and unsigned, will be removed\. . -.nf - - storage\. This is useful when rebuilding hosts, since new - certificate signing requests will only be honored if puppet - cert does not have a copy of a signed certificate for that - host\. The certificate of the host remains valid\. If \'\-\-all\' - is specified then all host certificates, both signed and - unsigned, will be removed\. +.TP +\-\-debug +Enable full debugging\. . -.fi +.TP +\-\-generate +Generate a certificate for a named client\. A certificate/keypair will be generated for each client named on the command line\. . -.IP "" 0 +.TP +\-\-help +Print this help message . -.P -debug: Enable full debugging\. +.TP +\-\-list +List outstanding certificate requests\. If \'\-\-all\' is specified, signed certificates are also listed, prefixed by \'+\', and revoked or invalid certificates are prefixed by \'\-\' (the verification outcome is printed in parenthesis)\. . -.P -generate: Generate a certificate for a named client\. A +.TP +\-\-print +Print the full\-text version of a host\'s certificate\. . -.IP "" 4 +.TP +\-\-fingerprint +Print the DIGEST (defaults to md5) fingerprint of a host\'s certificate\. . -.nf - - certificate/keypair will be generated for each client named - on the command line\. +.TP +\-\-revoke +Revoke the certificate of a client\. The certificate can be specified either by its serial number, given as a decimal number or a hexadecimal number prefixed by \'0x\', or by its hostname\. The certificate is revoked by adding it to the Certificate Revocation List given by the \'cacrl\' config parameter\. Note that the puppetmasterd needs to be restarted after revoking certificates\. . -.fi +.TP +\-\-sign +Sign an outstanding certificate request\. Unless \'\-\-all\' is specified, hosts must be listed after all flags\. . -.IP "" 0 +.TP +\-\-verbose +Enable verbosity\. . -.P -help: Print this help message +.TP +\-\-version +Print the puppet version number and exit\. . -.P -list: List outstanding certificate requests\. If \'\-\-all\' is +.TP +\-\-verify +Verify the named certificate against the local CA certificate\. . -.IP "" 4 +.SH "EXAMPLE" . .nf - specified, signed certificates are also listed, prefixed by - \'+\', and revoked or invalid certificates are prefixed by - \'\-\' (the verification outcome is printed in parenthesis)\. +$ puppet cert \-l +culain\.madstop\.com +$ puppet cert \-s culain\.madstop\.com . .fi . -.IP "" 0 -. -.P -print: Print the full\-text version of a host\'s certificate\. -. -.P -fingerprint: Print the DIGEST (defaults to md5) fingerprint of a host\'s -. -.IP "" 4 -. -.nf - - certificate\. -. -.fi -. -.IP "" 0 -. -.P -revoke: Revoke the certificate of a client\. The certificate can be -. -.IP "" 4 -. -.nf - - specified either by its serial number, given as a decimal - number or a hexadecimal number prefixed by \'0x\', or by its - hostname\. The certificate is revoked by adding it to the - Certificate Revocation List given by the \'cacrl\' config - parameter\. Note that the puppetmasterd needs to be - restarted after revoking certificates\. -. -.fi -. -.IP "" 0 -. -.P -sign: Sign an outstanding certificate request\. Unless \'\-\-all\' is -. -.IP "" 4 -. -.nf - - specified, hosts must be listed after all flags\. -. -.fi -. -.IP "" 0 -. -.P -verbose: Enable verbosity\. -. -.P -version: Print the puppet version number and exit\. -. -.P -verify: Verify the named certificate against the local CA -. -.IP "" 4 -. -.nf - - certificate\. -. -.fi +.SH "AUTHOR" +Luke Kanies . -.IP "" 0 -$ puppet cert \-l culain\.madstop\.com $ puppet cert \-s culain\.madstop\.comLuke KaniesCopyright (c) 2005 Puppet Labs, LLC Licensed under the GNU Public License +.SH "COPYRIGHT" +Copyright (c) 2005 Puppet Labs, LLC Licensed under the GNU Public License diff --git a/man/man8/puppetd.8 b/man/man8/puppetd.8 index 861137553..3fadd9df7 100644 --- a/man/man8/puppetd.8 +++ b/man/man8/puppetd.8 @@ -1,283 +1,139 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "PUPPETD" "8" "August 2010" "" "" -puppet agent [\-D|\-\-daemonize|\-\-no\-daemonize] [\-d|\-\-debug] +.TH "PUPPET\-AGENT" "8" "February 2011" "Puppet Labs, LLC" "Puppet manual" . -.IP "" 4 +.SH "NAME" +\fBpuppet\-agent\fR \- The puppet agent daemon . -.nf - - [\-\-detailed\-exitcodes] [\-\-disable] [\-\-enable] - [\-h|\-\-help] [\-\-fqdn <host name>] [\-l|\-\-logdest syslog|<file>|console] - [\-o|\-\-onetime] [\-\-serve <handler>] [\-t|\-\-test] [\-\-noop] - [\-\-digest <digest>] [\-\-fingerprint] [\-V|\-\-version] - [\-v|\-\-verbose] [\-w|\-\-waitforcert <seconds>] -. -.fi -. -.IP "" 0 -This is the main puppet client\. Its job is to retrieve the local machine\'s configuration from a remote server and apply it\. In order to successfully communicate with the remote server, the client must have a certificate signed by a certificate authority that the server trusts; the recommended method for this, at the moment, is to run a certificate authority as part of the puppet server (which is the default)\. The client will connect and request a signed certificate, and will continue connecting until it receives one\. -. -.P -Once the client has a signed certificate, it will retrieve its configuration and apply it\.+puppet agent+ does its best to find a compromise between interactive use and daemon use\. Run with no arguments and no configuration, it will go into the backgroun, attempt to get a signed certificate, and retrieve and apply its configuration every 30 minutes\. -. -.P -Some flags are meant specifically for interactive use \-\- in particular, +test+, +tags+ or +fingerprint+ are useful\. +test+ enables verbose logging, causes the daemon to stay in the foreground, exits if the server\'s configuration is invalid (this happens if, for instance, you\'ve left a syntax error on the server), and exits after running the configuration once (rather than hanging around as a long\-running process)\. -. -.P -+tags+ allows you to specify what portions of a configuration you want to apply\. Puppet elements are tagged with all of the class or definition names that contain them, and you can use the +tags+ flag to specify one of these names, causing only configuration elements contained within that class or definition to be applied\. This is very useful when you are testing new configurations \-\- for instance, if you are just starting to manage +ntpd+, you would put all of the new elements into an +ntpd+ class, and call puppet with +\-\-tags ntpd+, which would only apply that small portion of the configuration during your testing, rather than applying the whole thing\. -. -.P -+fingerprint+ is a one\-time flag\. In this mode +puppet agent+ will run once and display on the console (and in the log) the current certificate (or certificate request) fingerprint\. Providing the +\-\-digest+ option allows to use a different digest algorithm to generate the fingerprint\. The main use is to verify that before signing a certificate request on the master, the certificate request the master received is the same as the one the client sent (to prevent against man\-in\-the\-middle attacks when signing certificates)\.Note that any configuration parameter that\'s valid in the configuration file is also a valid long argument\. For example, \'server\' is a valid configuration parameter, so you can specify \'\-\-server \fIservername\fR\' as an argument\. -. -.P -See the configuration file documentation at http://docs\.puppetlabs\.com/references/stable/configuration\.html for the full list of acceptable parameters\. A commented list of all configuration options can also be generated by running puppet agent with \'\-\-genconfig\'\. -. -.P -daemonize: Send the process into the background\. This is the -. -.IP "" 4 -. -.nf - - default\. -. -.fi -. -.IP "" 0 -. -.P -no\-daemonize: Do not send the process into the background\. -. -.P -debug: Enable full debugging\. +.SH "SYNOPSIS" +Retrieves the client configuration from the puppet master and applies it to the local host\. . .P -digest: Change the certificate fingerprinting digest -. -.IP "" 4 -. -.nf - - algorithm\. The default is MD5\. Valid values depends - on the version of OpenSSL installed, but should - always at least contain MD5, MD2, SHA1 and SHA256\. -. -.fi -. -.IP "" 0 +This service may be run as a daemon, run periodically using cron (or something similar), or run interactively for testing purposes\. . -.P -detailed\-exitcodes: Provide transaction information via exit codes\. If -. -.IP "" 4 -. -.nf - - this is enabled, an exit code of \'2\' means there - were changes, and an exit code of \'4\' means that - there were failures during the transaction\. This - option only makes sense in conjunction with - \-\-onetime\. -. -.fi +.SH "USAGE" +puppet agent [\-D|\-\-daemonize|\-\-no\-daemonize] [\-d|\-\-debug] [\-\-detailed\-exitcodes] [\-\-disable] [\-\-enable] [\-h|\-\-help] [\-\-certname \fIhost name\fR] [\-l|\-\-logdest syslog|\fIfile\fR|console] [\-o|\-\-onetime] [\-\-serve \fIhandler\fR] [\-t|\-\-test] [\-\-noop] [\-\-digest \fIdigest\fR] [\-\-fingerprint] [\-V|\-\-version] [\-v|\-\-verbose] [\-w|\-\-waitforcert \fIseconds\fR] . -.IP "" 0 +.SH "DESCRIPTION" +This is the main puppet client\. Its job is to retrieve the local machine\'s configuration from a remote server and apply it\. In order to successfully communicate with the remote server, the client must have a certificate signed by a certificate authority that the server trusts; the recommended method for this, at the moment, is to run a certificate authority as part of the puppet server (which is the default)\. The client will connect and request a signed certificate, and will continue connecting until it receives one\. . .P -disable: Disable working on the local system\. This puts a -. -.IP "" 4 -. -.nf - - lock file in place, causing +puppet agent+ not to - work on the system until the lock file is removed\. - This is useful if you are testing a configuration - and do not want the central configuration to - override the local state until everything is tested - and committed\. -. -.fi +Once the client has a signed certificate, it will retrieve its configuration and apply it\. . -.IP "" 0 +.SH "USAGE NOTES" +\'puppet agent\' does its best to find a compromise between interactive use and daemon use\. Run with no arguments and no configuration, it will go into the background, attempt to get a signed certificate, and retrieve and apply its configuration every 30 minutes\. . .P -+puppet agent+ uses the same lock file while it is running, so no more than one +puppet agent+ process is working at a time\. +Some flags are meant specifically for interactive use \-\- in particular, \'test\', \'tags\' or \'fingerprint\' are useful\. \'test\' enables verbose logging, causes the daemon to stay in the foreground, exits if the server\'s configuration is invalid (this happens if, for instance, you\'ve left a syntax error on the server), and exits after running the configuration once (rather than hanging around as a long\-running process)\. . .P -+puppet agent+ exits after executing this\. +\'tags\' allows you to specify what portions of a configuration you want to apply\. Puppet elements are tagged with all of the class or definition names that contain them, and you can use the \'tags\' flag to specify one of these names, causing only configuration elements contained within that class or definition to be applied\. This is very useful when you are testing new configurations \-\- for instance, if you are just starting to manage \'ntpd\', you would put all of the new elements into an \'ntpd\' class, and call puppet with \'\-\-tags ntpd\', which would only apply that small portion of the configuration during your testing, rather than applying the whole thing\. . .P -enable: Enable working on the local system\. This removes any +\'fingerprint\' is a one\-time flag\. In this mode \'puppet agent\' will run once and display on the console (and in the log) the current certificate (or certificate request) fingerprint\. Providing the \'\-\-digest\' option allows to use a different digest algorithm to generate the fingerprint\. The main use is to verify that before signing a certificate request on the master, the certificate request the master received is the same as the one the client sent (to prevent against man\-in\-the\-middle attacks when signing certificates)\. . -.IP "" 4 -. -.nf - - lock file, causing +puppet agent+ to start managing - the local system again (although it will continue to - use its normal scheduling, so it might not start for - another half hour)\. -. -.fi -. -.IP "" 0 +.SH "OPTIONS" +Note that any configuration parameter that\'s valid in the configuration file is also a valid long argument\. For example, \'server\' is a valid configuration parameter, so you can specify \'\-\-server \fIservername\fR\' as an argument\. . .P -+puppet agent+ exits after executing this\. -. -.P -fqdn: Set the fully\-qualified domain name of the client\. +See the configuration file documentation at http://docs\.puppetlabs\.com/references/stable/configuration\.html for the full list of acceptable parameters\. A commented list of all configuration options can also be generated by running puppet agent with \'\-\-genconfig\'\. . -.IP "" 4 +.TP +\-\-daemonize +Send the process into the background\. This is the default\. . -.nf - - This is only used for certificate purposes, but can - be used to override the discovered hostname\. If you - need to use this flag, it is generally an indication - of a setup problem\. +.TP +\-\-no\-daemonize +Do not send the process into the background\. . -.fi +.TP +\-\-debug +Enable full debugging\. . -.IP "" 0 +.TP +\-\-digest +Change the certificate fingerprinting digest algorithm\. The default is MD5\. Valid values depends on the version of OpenSSL installed, but should always at least contain MD5, MD2, SHA1 and SHA256\. . -.P -help: Print this help message +.TP +\-\-detailed\-exitcodes +Provide transaction information via exit codes\. If this is enabled, an exit code of \'2\' means there were changes, and an exit code of \'4\' means that there were failures during the transaction\. This option only makes sense in conjunction with \-\-onetime\. . -.P -logdest: Where to send messages\. Choose between syslog, the +.TP +\-\-disable +Disable working on the local system\. This puts a lock file in place, causing \'puppet agent\' not to work on the system until the lock file is removed\. This is useful if you are testing a configuration and do not want the central configuration to override the local state until everything is tested and committed\. . -.IP "" 4 +.IP +\'puppet agent\' uses the same lock file while it is running, so no more than one \'puppet agent\' process is working at a time\. . -.nf - - console, and a log file\. Defaults to sending - messages to syslog, or the console if debugging or - verbosity is enabled\. +.IP +\'puppet agent\' exits after executing this\. . -.fi +.TP +\-\-enable +Enable working on the local system\. This removes any lock file, causing \'puppet agent\' to start managing the local system again (although it will continue to use its normal scheduling, so it might not start for another half hour)\. . -.IP "" 0 +.IP +\'puppet agent\' exits after executing this\. . -.P -no\-client: Do not create a config client\. This will cause the +.TP +\-\-certname +Set the certname (unique ID) of the client\. The master reads this unique identifying string, which is usually set to the node\'s fully\-qualified domain name, to determine which configurations the node will receive\. Use this option to debug setup problems or implement unusual node identification schemes\. . -.IP "" 4 +.TP +\-\-help +Print this help message . -.nf - - daemon to run without ever checking for its - configuration automatically, and only makes sense - when used in conjunction with \-\-listen\. +.TP +\-\-logdest +Where to send messages\. Choose between syslog, the console, and a log file\. Defaults to sending messages to syslog, or the console if debugging or verbosity is enabled\. . -.fi +.TP +\-\-no\-client +Do not create a config client\. This will cause the daemon to run without ever checking for its configuration automatically, and only makes sense . -.IP "" 0 +.TP +\-\-onetime +Run the configuration once\. Runs a single (normally daemonized) Puppet run\. Useful for interactively running puppet agent when used in conjunction with the \-\-no\-daemonize option\. . -.P -onetime: Run the configuration once\. Runs a single (normally +.TP +\-\-fingerprint +Display the current certificate or certificate signing request fingerprint and then exit\. Use the \'\-\-digest\' option to change the digest algorithm used\. . -.IP "" 4 +.TP +\-\-serve +Start another type of server\. By default, \'puppet agent\' will start a service handler that allows authenticated and authorized remote nodes to trigger the configuration to be pulled down and applied\. You can specify any handler here that does not require configuration, e\.g\., filebucket, ca, or resource\. The handlers are in \'lib/puppet/network/handler\', and the names must match exactly, both in the call to \'serve\' and in \'namespaceauth\.conf\'\. . -.nf - - daemonized) Puppet run\. Useful for interactively - running puppet agent when used in conjunction with - the \-\-no\-daemonize option\. -. -.fi -. -.IP "" 0 -. -.P -fingerprint: Display the current certificate or certificate +.TP +\-\-test +Enable the most common options used for testing\. These are \'onetime\', \'verbose\', \'ignorecache\', \'no\-daemonize\', \'no\-usecacheonfailure\', \'detailed\-exit\-codes\', \'no\-splay\', and \'show_diff\'\. . -.IP "" 4 +.TP +\-\-noop +Use \'noop\' mode where the daemon runs in a no\-op or dry\-run mode\. This is useful for seeing what changes Puppet will make without actually executing the changes\. . -.nf - - signing request fingerprint and then exit\. Use the - +\-\-digest+ option to change the digest algorithm - used\. +.TP +\-\-verbose +Turn on verbose reporting\. . -.fi +.TP +\-\-version +Print the puppet version number and exit\. . -.IP "" 0 +.TP +\-\-waitforcert +This option only matters for daemons that do not yet have certificates and it is enabled by default, with a value of 120 (seconds)\. This causes \'puppet agent\' to connect to the server every 2 minutes and ask it to sign a certificate request\. This is useful for the initial setup of a puppet client\. You can turn off waiting for certificates by specifying a time of 0\. . -.P -serve: Start another type of server\. By default, +puppet -. -.IP "" 4 +.SH "EXAMPLE" . .nf - agent+ will start a service handler that allows - authenticated and authorized remote nodes to trigger - the configuration to be pulled down and applied\. You - can specify any handler here that does not require - configuration, e\.g\., filebucket, ca, or resource\. - The handlers are in +lib/puppet/network/handler+, - and the names must match exactly, both in the call - to +serve+ and in +namespaceauth\.conf+\. +$ puppet agent \-\-server puppet\.domain\.com . .fi . -.IP "" 0 -. -.P -test: Enable the most common options used for testing\. -. -.IP "" 4 -. -.nf - - These are +onetime+, +verbose+, +ignorecache, - +no\-daemonize+, and +no\-usecacheonfailure+\. -. -.fi -. -.IP "" 0 -. -.P -noop: Use +noop+ mode where the daemon runs in a no\-op or -. -.IP "" 4 -. -.nf - - dry\-run mode\. This is useful for seeing what changes - Puppet will make without actually executing the - changes\. -. -.fi -. -.IP "" 0 -. -.P -verbose: Turn on verbose reporting\. -. -.P -version: Print the puppet version number and exit\. -. -.P -waitforcert: This option only matters for daemons that do not yet -. -.IP "" 4 -. -.nf - - have certificates and it is enabled by default, with - a value of 120 (seconds)\. This causes +puppet agent+ - to connect to the server every 2 minutes and ask it - to sign a certificate request\. This is useful for - the initial setup of a puppet client\. You can turn - off waiting for certificates by specifying a time of - 0\. -. -.fi +.SH "AUTHOR" +Luke Kanies . -.IP "" 0 -puppet agent \-\-server puppet\.domain\.comLuke KaniesCopyright (c) 2005, 2006 Puppet Labs, LLC Licensed under the GNU Public License +.SH "COPYRIGHT" +Copyright (c) 2005, 2006 Puppet Labs, LLC Licensed under the GNU Public License diff --git a/man/man8/puppetdoc.8 b/man/man8/puppetdoc.8 index 47df0e764..e0cabd5d1 100644 --- a/man/man8/puppetdoc.8 +++ b/man/man8/puppetdoc.8 @@ -1,108 +1,101 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "PUPPETDOC" "8" "August 2010" "" "" -Generate a reference for all Puppet types\. Largely meant for internal Puppet Labs use\.puppet doc [\-a|\-\-all] [\-h|\-\-help] [\-o|\-\-outputdir \fIrdoc outputdir\fR] [\-m|\-\-mode \fItext|pdf|rdoc\fR] +.TH "PUPPET\-DOC" "8" "February 2011" "Puppet Labs, LLC" "Puppet manual" . -.IP "" 4 +.SH "NAME" +\fBpuppet\-doc\fR \- Generate Puppet documentation and references . -.nf - - [\-r|\-\-reference <[type]|configuration|\.\.>] [\-\-charset CHARSET] [manifest\-file] +.SH "SYNOPSIS" +Generates a reference for all Puppet types\. Largely meant for internal Puppet Labs use\. . -.fi +.SH "USAGE" +puppet doc [\-a|\-\-all] [\-h|\-\-help] [\-o|\-\-outputdir \fIrdoc\-outputdir\fR] [\-m|\-\-mode text|pdf|rdoc] [\-r|\-\-reference \fIreference\-name\fR] [\-\-charset \fIcharset\fR] [\fImanifest\-file\fR] . -.IP "" 0 +.SH "DESCRIPTION" If mode is not \'rdoc\', then this command generates a Markdown document describing all installed Puppet types or all allowable arguments to puppet executables\. It is largely meant for internal use and is used to generate the reference document available on the Puppet Labs web site\. . .P In \'rdoc\' mode, this command generates an html RDoc hierarchy describing the manifests that are in \'manifestdir\' and \'modulepath\' configuration directives\. The generated documentation directory is doc by default but can be changed with the \'outputdir\' option\. . .P -If the command is started with \'manifest\-file\' command\-line arguments, puppet doc generate a single manifest documentation that is output on stdout\.all: Output the docs for all of the reference types\. In \'rdoc\' +If the command is run with the name of a manifest file as an argument, puppet doc will output a single manifest\'s documentation on stdout\. . -.IP "" 4 +.SH "OPTIONS" . -.nf - - modes, this also outputs documentation for all resources +.TP +\-\-all +Output the docs for all of the reference types\. In \'rdoc\' modes, this also outputs documentation for all resources . -.fi +.TP +\-\-help +Print this help message . -.IP "" 0 +.TP +\-\-outputdir +Specifies the directory where to output the rdoc documentation in \'rdoc\' mode\. . -.P -help: Print this help message +.TP +\-\-mode +Determine the output mode\. Valid modes are \'text\', \'pdf\' and \'rdoc\'\. The \'pdf\' mode creates PDF formatted files in the /tmp directory\. The default mode is \'text\'\. In \'rdoc\' mode you must provide \'manifests\-path\' . -.P -outputdir: Specifies the directory where to output the rdoc +.TP +\-\-reference +Build a particular reference\. Get a list of references by running \'puppet doc \-\-list\'\. . -.IP "" 4 +.TP +\-\-charset +Used only in \'rdoc\' mode\. It sets the charset used in the html files produced\. +. +.SH "EXAMPLE" . .nf - documentation in \'rdoc\' mode\. +$ puppet doc \-r type > /tmp/type_reference\.markdown . .fi . -.IP "" 0 -. .P -mode: Determine the output mode\. Valid modes are \'text\', \'trac\', +or . .IP "" 4 . .nf - \'pdf\' and \'rdoc\'\. The \'pdf\' mode creates PDF formatted files - in the /tmp directory\. The default mode is \'text\'\. In \'rdoc\' - mode you must provide \'manifests\-path\' +$ puppet doc \-\-outputdir /tmp/rdoc \-\-mode rdoc /path/to/manifests . .fi . .IP "" 0 . .P -reference: Build a particular reference\. Get a list of references by +or . .IP "" 4 . .nf - running +puppet doc \-\-list+\. +$ puppet doc /etc/puppet/manifests/site\.pp . .fi . .IP "" 0 . .P -charset: Used only in \'rdoc\' mode\. It sets the charset used in the +or . .IP "" 4 . .nf - html files produced\. +$ puppet doc \-m pdf \-r configuration . .fi . .IP "" 0 -$ puppet doc \-r type > /tmp/type_reference\.rst -. -.P -or -. -.P -$ puppet doc \-\-outputdir /tmp/rdoc \-\-mode rdoc /path/to/manifests . -.P -or -. -.P -$ puppet doc /etc/puppet/manifests/site\.pp +.SH "AUTHOR" +Luke Kanies . -.P -or -. -.P -$ puppet doc \-m pdf \-r configurationLuke KaniesCopyright (c) 2005\-2007 Puppet Labs, LLC Licensed under the GNU Public License +.SH "COPYRIGHT" +Copyright (c) 2005\-2007 Puppet Labs, LLC Licensed under the GNU Public License diff --git a/man/man8/puppetmasterd.8 b/man/man8/puppetmasterd.8 index dde93a3d6..9ed2a6ad6 100644 --- a/man/man8/puppetmasterd.8 +++ b/man/man8/puppetmasterd.8 @@ -1,52 +1,63 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "PUPPETMASTERD" "8" "August 2010" "" "" -The central puppet server\. Functions as a certificate authority by default\.puppet master [\-D|\-\-daemonize|\-\-no\-daemonize] [\-d|\-\-debug] [\-h|\-\-help] +.TH "PUPPET\-MASTER" "8" "February 2011" "Puppet Labs, LLC" "Puppet manual" . -.IP "" 4 +.SH "NAME" +\fBpuppet\-master\fR \- The puppet master daemon . -.nf - - [\-l|\-\-logdest <file>|console|syslog] [\-v|\-\-verbose] [\-V|\-\-version] +.SH "SYNOPSIS" +The central puppet server\. Functions as a certificate authority by default\. . -.fi +.SH "USAGE" +puppet master [\-D|\-\-daemonize|\-\-no\-daemonize] [\-d|\-\-debug] [\-h|\-\-help] [\-l|\-\-logdest \fIfile\fR|console|syslog] [\-v|\-\-verbose] [\-V|\-\-version] [\-\-compile \fInode\-name\fR] . -.IP "" 0 -This is the puppet central daemon\.Note that any configuration parameter that\'s valid in the configuration file is also a valid long argument\. For example, \'ssldir\' is a valid configuration parameter, so you can specify \'\-\-ssldir \fIdirectory\fR\' as an argument\. +.SH "DESCRIPTION" +This command starts an instance of puppet master, running as a daemon and using Ruby\'s built\-in Webrick webserver\. Puppet master can also be managed by other application servers; when this is the case, this executable is not used\. . -.P -See the configuration file documentation at http://docs\.puppetlabs\.com/references/stable/configuration\.html for the full list of acceptable parameters\. A commented list of all configuration options can also be generated by running puppetmasterdd with \'\-\-genconfig\'\. +.SH "OPTIONS" +Note that any configuration parameter that\'s valid in the configuration file is also a valid long argument\. For example, \'ssldir\' is a valid configuration parameter, so you can specify \'\-\-ssldir \fIdirectory\fR\' as an argument\. . .P -daemonize: Send the process into the background\. This is the default\. +See the configuration file documentation at http://docs\.puppetlabs\.com/references/stable/configuration\.html for the full list of acceptable parameters\. A commented list of all configuration options can also be generated by running puppet master with \'\-\-genconfig\'\. . -.P -no\-daemonize: Do not send the process into the background\. +.TP +\-\-daemonize +Send the process into the background\. This is the default\. . -.P -debug: Enable full debugging\. +.TP +\-\-no\-daemonize +Do not send the process into the background\. . -.P -help: Print this help message\. +.TP +\-\-debug +Enable full debugging\. . -.P -logdest: Where to send messages\. Choose between syslog, the +.TP +\-\-help +Print this help message\. . -.IP "" 4 +.TP +\-\-logdest +Where to send messages\. Choose between syslog, the console, and a log file\. Defaults to sending messages to syslog, or the console if debugging or verbosity is enabled\. . -.nf - - console, and a log file\. Defaults to sending messages to - syslog, or the console if debugging or verbosity is - enabled\. +.TP +\-\-verbose +Enable verbosity\. . -.fi +.TP +\-\-version +Print the puppet version number and exit\. . -.IP "" 0 +.TP +\-\-compile +Compile a catalogue and output it in JSON from the puppet master\. Uses facts contained in the $vardir/yaml/ directory to compile the catalog\. . -.P -verbose: Enable verbosity\. +.SH "EXAMPLE" +puppet master . -.P -version: Print the puppet version number and exit\.puppet masterLuke KaniesCopyright (c) 2005 Puppet Labs, LLC Licensed under the GNU Public License +.SH "AUTHOR" +Luke Kanies +. +.SH "COPYRIGHT" +Copyright (c) 2005 Puppet Labs, LLC Licensed under the GNU Public License diff --git a/man/man8/puppetqd.8 b/man/man8/puppetqd.8 index f630c74a5..7dbd683bf 100644 --- a/man/man8/puppetqd.8 +++ b/man/man8/puppetqd.8 @@ -1,20 +1,55 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "PUPPETQD" "8" "August 2010" "" "" -puppet queue [\-d|\-\-debug] [\-v|\-\-verbose]This is a simple application that just processes entities in a queue as they are recieved\.Note that any configuration parameter that\'s valid in the configuration file is also a valid long argument\. For example, \'server\' is a valid configuration parameter, so you can specify \'\-\-server \fIservername\fR\' as an argument\. +.TH "PUPPET\-QUEUE" "8" "February 2011" "Puppet Labs, LLC" "Puppet manual" . -.P -See the configuration file documentation at http://docs\.puppetlabs\.com/references/stable/configuration\.html for the full list of acceptable parameters\. A commented list of all configuration options can also be generated by running puppetd with \'\-\-genconfig\'\. +.SH "NAME" +\fBpuppet\-queue\fR \- Queuing daemon for asynchronous storeconfigs . -.P -debug: Enable full debugging\. +.SH "SYNOPSIS" +Retrieves serialized storeconfigs records from a queue and processes them in order\. . -.P -help: Print this help message +.SH "USAGE" +puppet queue [\-d|\-\-debug] [\-v|\-\-verbose] +. +.SH "DESCRIPTION" +This application runs as a daemon and processes storeconfigs data, retrieving the data from a stomp server message queue and writing it to a database\. . .P -verbose: Turn on verbose reporting\. +For more information, including instructions for properly setting up your puppet master and message queue, see the documentation on setting up asynchronous storeconfigs at: http://projects\.puppetlabs\.com/projects/1/wiki/Using_Stored_Configuration +. +.SH "OPTIONS" +Note that any configuration parameter that\'s valid in the configuration file is also a valid long argument\. For example, \'server\' is a valid configuration parameter, so you can specify \'\-\-server \fIservername\fR\' as an argument\. . .P -version: Print the puppet version number and exit\.puppet queueLuke KaniesCopyright (c) 2009 Puppet Labs, LLC Licensed under the GNU Public License +See the configuration file documentation at http://docs\.puppetlabs\.com/references/stable/configuration\.html for the full list of acceptable parameters\. A commented list of all configuration options can also be generated by running puppet queue with \'\-\-genconfig\'\. +. +.TP +\-\-debug +Enable full debugging\. +. +.TP +\-\-help +Print this help message +. +.TP +\-\-verbose +Turn on verbose reporting\. +. +.TP +\-\-version +Print the puppet version number and exit\. +. +.SH "EXAMPLE" +. +.nf + +$ puppet queue +. +.fi +. +.SH "AUTHOR" +Luke Kanies +. +.SH "COPYRIGHT" +Copyright (c) 2009 Puppet Labs, LLC Licensed under the GNU Public License diff --git a/man/man8/puppetrun.8 b/man/man8/puppetrun.8 index 09fa31b15..b6a868918 100644 --- a/man/man8/puppetrun.8 +++ b/man/man8/puppetrun.8 @@ -1,32 +1,34 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "PUPPETRUN" "8" "August 2010" "" "" -Trigger a puppet agent run on a set of hosts\.puppet kick [\-a|\-\-all] [\-c|\-\-class \fIclass\fR] [\-d|\-\-debug] [\-f|\-\-foreground] +.TH "PUPPET\-KICK" "8" "February 2011" "Puppet Labs, LLC" "Puppet manual" . -.IP "" 4 +.SH "NAME" +\fBpuppet\-kick\fR \- Remotely control puppet agent . -.nf - - [\-h|\-\-help] [\-\-host <host>] [\-\-no\-fqdn] [\-\-ignoreschedules] - [\-t|\-\-tag <tag>] [\-\-test] [\-p|\-\-ping] <host> [<host> [\.\.\.]] +.SH "SYNOPSIS" +Trigger a puppet agent run on a set of hosts\. . -.fi +.SH "USAGE" +puppet kick [\-a|\-\-all] [\-c|\-\-class \fIclass\fR] [\-d|\-\-debug] [\-f|\-\-foreground] [\-h|\-\-help] [\-\-host \fIhost\fR] [\-\-no\-fqdn] [\-\-ignoreschedules] [\-t|\-\-tag \fItag\fR] [\-\-test] [\-p|\-\-ping] \fIhost\fR [\fIhost\fR [\.\.\.]] . -.IP "" 0 -This script can be used to connect to a set of machines running +puppet agent+ and trigger them to run their configurations\. The most common usage would be to specify a class of hosts and a set of tags, and +puppet kick+ would look up in LDAP all of the hosts matching that class, then connect to each host and trigger a run of all of the objects with the specified tags\. +.SH "DESCRIPTION" +This script can be used to connect to a set of machines running \'puppet agent\' and trigger them to run their configurations\. The most common usage would be to specify a class of hosts and a set of tags, and \'puppet kick\' would look up in LDAP all of the hosts matching that class, then connect to each host and trigger a run of all of the objects with the specified tags\. . .P If you are not storing your host configurations in LDAP, you can specify hosts manually\. . .P -You will most likely have to run +puppet kick+ as root to get access to the SSL certificates\. +You will most likely have to run \'puppet kick\' as root to get access to the SSL certificates\. . .P -+puppet kick+ reads +puppet master+\'s configuration file, so that it can copy things like LDAP settings\.+puppet kick+ is useless unless +puppet agent+ is listening\. See its documentation for more information, but the gist is that you must enable +listen+ on the +puppet agent+ daemon, either using +\-\-listen+ on the command line or adding \'listen: true\' in its config file\. In addition, you need to set the daemons up to specifically allow connections by creating the +namespaceauth+ file, normally at \'/etc/puppet/namespaceauth\.conf\'\. This file specifies who has access to each namespace; if you create the file you must add every namespace you want any Puppet daemon to allow \-\- it is currently global to all Puppet daemons\. +\'puppet kick\' reads \'puppet master\'\'s configuration file, so that it can copy things like LDAP settings\. +. +.SH "USAGE NOTES" +\'puppet kick\' is useless unless \'puppet agent\' is listening\. See its documentation for more information, but the gist is that you must enable \'listen\' on the \'puppet agent\' daemon, either using \'\-\-listen\' on the command line or adding \'listen = true\' in its config file\. In addition, you need to set the daemons up to specifically allow connections by creating the \'namespaceauth\' file, normally at \'/etc/puppet/namespaceauth\.conf\'\. This file specifies who has access to each namespace; if you create the file you must add every namespace you want any Puppet daemon to allow \-\- it is currently global to all Puppet daemons\. . .P -An example file looks like this:: +An example file looks like this: . .IP "" 4 . @@ -46,128 +48,68 @@ An example file looks like this:: .IP "" 0 . .P -This is what you would install on your Puppet master; non\-master hosts could leave off the \'fileserver\' and \'puppetmaster\' namespaces\.Note that any configuration parameter that\'s valid in the configuration file is also a valid long argument\. For example, \'ssldir\' is a valid configuration parameter, so you can specify \'\-\-ssldir \fIdirectory\fR\' as an argument\. -. -.P -See the configuration file documentation at http://reductivelabs\.com/projects/puppet/reference/configref\.html for the full list of acceptable parameters\. A commented list of all configuration options can also be generated by running puppet master with \'\-\-genconfig\'\. -. -.P -all: Connect to all available hosts\. Requires LDAP support -. -.IP "" 4 -. -.nf - - at this point\. -. -.fi -. -.IP "" 0 -. -.P -class: Specify a class of machines to which to connect\. This -. -.IP "" 4 -. -.nf - - only works if you have LDAP configured, at the moment\. -. -.fi -. -.IP "" 0 -. -.P -debug: Enable full debugging\. -. -.P -foreground: Run each configuration in the foreground; that is, when -. -.IP "" 4 -. -.nf - - connecting to a host, do not return until the host has - finished its run\. The default is false\. -. -.fi -. -.IP "" 0 -. -.P -help: Print this help message +This is what you would install on your Puppet master; non\-master hosts could leave off the \'fileserver\' and \'puppetmaster\' namespaces\. . -.P -host: A specific host to which to connect\. This flag can be -. -.IP "" 4 -. -.nf - - specified more than once\. -. -.fi -. -.IP "" 0 +.SH "OPTIONS" +Note that any configuration parameter that\'s valid in the configuration file is also a valid long argument\. For example, \'ssldir\' is a valid configuration parameter, so you can specify \'\-\-ssldir \fIdirectory\fR\' as an argument\. . .P -ignoreschedules: Whether the client should ignore schedules when running +See the configuration file documentation at http://docs\.puppetlabs\.com/references/latest/configuration\.html for the full list of acceptable parameters\. A commented list of all configuration options can also be generated by running puppet master with \'\-\-genconfig\'\. . -.IP "" 4 +.TP +\-\-all +Connect to all available hosts\. Requires LDAP support at this point\. . -.nf - - its configuration\. This can be used to force the client - to perform work it would not normally perform so soon\. - The default is false\. +.TP +\-\-class +Specify a class of machines to which to connect\. This only works if you have LDAP configured, at the moment\. . -.fi +.TP +\-\-debug +Enable full debugging\. . -.IP "" 0 +.TP +\-\-foreground +Run each configuration in the foreground; that is, when connecting to a host, do not return until the host has finished its run\. The default is false\. . -.P -parallel: How parallel to make the connections\. Parallelization +.TP +\-\-help +Print this help message . -.IP "" 4 +.TP +\-\-host +A specific host to which to connect\. This flag can be specified more than once\. . -.nf - - is provided by forking for each client to which to - connect\. The default is 1, meaning serial execution\. -. -.fi -. -.IP "" 0 -. -.P -tag: Specify a tag for selecting the objects to apply\. Does -. -.IP "" 4 +.TP +\-\-ignoreschedules +Whether the client should ignore schedules when running its configuration\. This can be used to force the client to perform work it would not normally perform so soon\. The default is false\. . -.nf - - not work with the \-\-test option\. +.TP +\-\-parallel +How parallel to make the connections\. Parallelization is provided by forking for each client to which to connect\. The default is 1, meaning serial execution\. . -.fi +.TP +\-\-tag +Specify a tag for selecting the objects to apply\. Does not work with the \-\-test option\. . -.IP "" 0 +.TP +\-\-test +Print the hosts you would connect to but do not actually connect\. This option requires LDAP support at this point\. . -.P -test: Print the hosts you would connect to but do not +.TP +\-\-ping +Do a ICMP echo against the target host\. Skip hosts that don\'t respond to ping\. . -.IP "" 4 +.SH "EXAMPLE" . .nf - actually connect\. This option requires LDAP support at - this point\. +$ sudo puppet kick \-p 10 \-t remotefile \-t webserver host1 host2 . .fi . -.IP "" 0 +.SH "AUTHOR" +Luke Kanies . -.P -ping:: -. -.P -Do a ICMP echo against the target host\. Skip hosts that don\'t respond to ping\.sudo puppet kick \-p 10 \-t remotefile \-t webserver host1 host2Luke KaniesCopyright (c) 2005 Puppet Labs, LLC Licensed under the GNU Public License +.SH "COPYRIGHT" +Copyright (c) 2005 Puppet Labs, LLC Licensed under the GNU Public License diff --git a/man/man8/ralsh.8 b/man/man8/ralsh.8 index bdc81e90a..738537e84 100644 --- a/man/man8/ralsh.8 +++ b/man/man8/ralsh.8 @@ -1,85 +1,84 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "RALSH" "8" "August 2010" "" "" -Use the Puppet RAL to directly interact with the system\.puppet resource [\-h|\-\-help] [\-d|\-\-debug] [\-v|\-\-verbose] [\-e|\-\-edit] +.TH "PUPPET\-RESOURCE" "8" "February 2011" "Puppet Labs, LLC" "Puppet manual" . -.IP "" 4 +.SH "NAME" +\fBpuppet\-resource\fR \- The resource abstraction layer shell . -.nf - - [\-H|\-\-host <host>] [\-p|\-\-param <param>] [\-t|\-\-types] - type <name> +.SH "SYNOPSIS" +Uses the Puppet RAL to directly interact with the system\. . -.fi +.SH "USAGE" +puppet resource [\-h|\-\-help] [\-d|\-\-debug] [\-v|\-\-verbose] [\-e|\-\-edit] [\-H|\-\-host \fIhost\fR] [\-p|\-\-param \fIparameter\fR] [\-t|\-\-types] \fItype\fR [\fIname\fR] [\fIattribute\fR=\fIvalue\fR \.\.\.] . -.IP "" 0 -This command provides simple facilities for converting current system state into Puppet code, along with some ability to use Puppet to affect the current state\. +.SH "DESCRIPTION" +This command provides simple facilities for converting current system state into Puppet code, along with some ability to modify the current state using Puppet\'s RAL\. . .P -By default, you must at least provide a type to list, which case puppet resource will tell you everything it knows about all instances of that type\. You can optionally specify an instance name, and puppet resource will only describe that single instance\. +By default, you must at least provide a type to list, in which case puppet resource will tell you everything it knows about all resources of that type\. You can optionally specify an instance name, and puppet resource will only describe that single instance\. . .P -You can also add +\-\-edit+ as an argument, and puppet resource will write its output to a file, open that file in an editor, and then apply the file as a Puppet transaction\. You can easily use this to use Puppet to make simple changes to a system\.Note that any configuration parameter that\'s valid in the configuration file is also a valid long argument\. For example, \'ssldir\' is a valid configuration parameter, so you can specify \'\-\-ssldir \fIdirectory\fR\' as an argument\. +If given a type, a name, and a series of \fIattribute\fR=\fIvalue\fR pairs, puppet resource will modify the state of the specified resource\. Alternately, if given a type, a name, and the \'\-\-edit\' flag, puppet resource will write its output to a file, open that file in an editor, and then apply the saved file as a Puppet transaction\. . -.P -See the configuration file documentation at http://docs\.puppetlabs\.com/references/stable/configuration\.html for the full list of acceptable parameters\. A commented list of all configuration options can also be generated by running puppet with \'\-\-genconfig\'\. +.SH "OPTIONS" +Note that any configuration parameter that\'s valid in the configuration file is also a valid long argument\. For example, \'ssldir\' is a valid configuration parameter, so you can specify \'\-\-ssldir \fIdirectory\fR\' as an argument\. . .P -debug: Enable full debugging\. +See the configuration file documentation at http://docs\.puppetlabs\.com/references/stable/configuration\.html for the full list of acceptable parameters\. A commented list of all configuration options can also be generated by running puppet with \'\-\-genconfig\'\. . -.P -edit: +.TP +\-\-debug +Enable full debugging\. . -.P +.TP +\-\-edit Write the results of the query to a file, open the file in an editor, and read the file back in as an executable Puppet manifest\. . -.P -host: -. -.P +.TP +\-\-host When specified, connect to the resource server on the named host and retrieve the list of resouces of the type specified\. . -.P -help: -. -.P +.TP +\-\-help Print this help message\. . -.P -param: -. -.P +.TP +\-\-param Add more parameters to be outputted from queries\. . -.P -types: -. -.P +.TP +\-\-types List all available types\. . -.P -verbose: +.TP +\-\-verbose +Print extra information\. . -.P -Print extra information\.This example uses \fBpuppet resource\fR to return Puppet configuration for the user \fBluke\fR: +.SH "EXAMPLE" +This example uses \fBpuppet resource\fR to return a Puppet configuration for the user \fBluke\fR: . .IP "" 4 . .nf - $ puppet resource user luke - user { \'luke\': - home => \'/home/luke\', - uid => \'100\', - ensure => \'present\', - comment => \'Luke Kanies,,,\', - gid => \'1000\', - shell => \'/bin/bash\', - groups => [\'sysadmin\',\'audio\',\'video\',\'puppet\'] - } +$ puppet resource user luke +user { \'luke\': + home => \'/home/luke\', + uid => \'100\', + ensure => \'present\', + comment => \'Luke Kanies,,,\', + gid => \'1000\', + shell => \'/bin/bash\', + groups => [\'sysadmin\',\'audio\',\'video\',\'puppet\'] +} . .fi . .IP "" 0 -Luke KaniesCopyright (c) 2005\-2007 Puppet Labs, LLC Licensed under the GNU Public License +. +.SH "AUTHOR" +Luke Kanies +. +.SH "COPYRIGHT" +Copyright (c) 2005\-2007 Puppet Labs, LLC Licensed under the GNU Public License diff --git a/spec/fixtures/integration/provider/mailalias/aliases/test1 b/spec/fixtures/integration/provider/mailalias/aliases/test1 new file mode 100644 index 000000000..ecf532213 --- /dev/null +++ b/spec/fixtures/integration/provider/mailalias/aliases/test1 @@ -0,0 +1,28 @@ +# Basic system aliases -- these MUST be present +MAILER-DAEMON: postmaster +postmaster: root + +# General redirections for pseudo accounts +bin: root +daemon: root +named: root +nobody: root +uucp: root +www: root +ftp-bugs: root +postfix: root + +# Put your local aliases here. + +# Well-known aliases +manager: root +dumper: root +operator: root +abuse: postmaster + +# trap decode to catch security attacks +decode: root + +# Other tests +anothertest: "|/path/to/rt-mailgate --queue 'another test' --action correspond --url http://my.com/" +test: "|/path/to/rt-mailgate --queue 'test' --action correspond --url http://my.com/" diff --git a/spec/fixtures/unit/parser/lexer/aliastest.pp b/spec/fixtures/unit/parser/lexer/aliastest.pp new file mode 100644 index 000000000..f2b61592e --- /dev/null +++ b/spec/fixtures/unit/parser/lexer/aliastest.pp @@ -0,0 +1,16 @@ +file { "a file": + path => "/tmp/aliastest", + ensure => file +} + +file { "another": + path => "/tmp/aliastest2", + ensure => file, + require => File["a file"] +} + +file { "a third": + path => "/tmp/aliastest3", + ensure => file, + require => File["/tmp/aliastest"] +} diff --git a/spec/fixtures/unit/parser/lexer/append.pp b/spec/fixtures/unit/parser/lexer/append.pp new file mode 100644 index 000000000..20cbda662 --- /dev/null +++ b/spec/fixtures/unit/parser/lexer/append.pp @@ -0,0 +1,11 @@ +$var=['/tmp/file1','/tmp/file2'] + +class arraytest { + $var += ['/tmp/file3', '/tmp/file4'] + file { + $var: + content => "test" + } +} + +include arraytest diff --git a/spec/fixtures/unit/parser/lexer/argumentdefaults.pp b/spec/fixtures/unit/parser/lexer/argumentdefaults.pp new file mode 100644 index 000000000..eac9dd757 --- /dev/null +++ b/spec/fixtures/unit/parser/lexer/argumentdefaults.pp @@ -0,0 +1,14 @@ +# $Id$ + +define testargs($file, $mode = 755) { + file { $file: ensure => file, mode => $mode } +} + +testargs { "testingname": + file => "/tmp/argumenttest1" +} + +testargs { "testingother": + file => "/tmp/argumenttest2", + mode => 644 +} diff --git a/spec/fixtures/unit/parser/lexer/arithmetic_expression.pp b/spec/fixtures/unit/parser/lexer/arithmetic_expression.pp new file mode 100644 index 000000000..aae98a4db --- /dev/null +++ b/spec/fixtures/unit/parser/lexer/arithmetic_expression.pp @@ -0,0 +1,8 @@ + +$one = 1.30 +$two = 2.034e-2 + +$result = ((( $two + 2) / $one) + 4 * 5.45) - (6 << 7) + (0x800 + -9) + + +notice("result is $result == 1295.87692307692")
\ No newline at end of file diff --git a/spec/fixtures/unit/parser/lexer/arraytrailingcomma.pp b/spec/fixtures/unit/parser/lexer/arraytrailingcomma.pp new file mode 100644 index 000000000..a410f9553 --- /dev/null +++ b/spec/fixtures/unit/parser/lexer/arraytrailingcomma.pp @@ -0,0 +1,3 @@ +file { + ["/tmp/arraytrailingcomma1","/tmp/arraytrailingcomma2", ]: content => "tmp" +} diff --git a/spec/fixtures/unit/parser/lexer/casestatement.pp b/spec/fixtures/unit/parser/lexer/casestatement.pp new file mode 100644 index 000000000..66ecd72b9 --- /dev/null +++ b/spec/fixtures/unit/parser/lexer/casestatement.pp @@ -0,0 +1,65 @@ +# $Id$ + +$var = "value" + +case $var { + "nope": { + file { "/tmp/fakefile": mode => 644, ensure => file } + } + "value": { + file { "/tmp/existsfile": mode => 755, ensure => file } + } +} + +$ovar = "yayness" + +case $ovar { + "fooness": { + file { "/tmp/nostillexistsfile": mode => 644, ensure => file } + } + "booness", "yayness": { + case $var { + "nep": { + file { "/tmp/noexistsfile": mode => 644, ensure => file } + } + "value": { + file { "/tmp/existsfile2": mode => 755, ensure => file } + } + } + } +} + +case $ovar { + "fooness": { + file { "/tmp/nostillexistsfile": mode => 644, ensure => file } + } + default: { + file { "/tmp/existsfile3": mode => 755, ensure => file } + } +} + +$bool = true + +case $bool { + true: { + file { "/tmp/existsfile4": mode => 755, ensure => file } + } +} + +$yay = yay +$a = yay +$b = boo + +case $yay { + $a: { file { "/tmp/existsfile5": mode => 755, ensure => file } } + $b: { file { "/tmp/existsfile5": mode => 644, ensure => file } } + default: { file { "/tmp/existsfile5": mode => 711, ensure => file } } + +} + +$regexvar = "exists regex" +case $regexvar { + "no match": { file { "/tmp/existsfile6": mode => 644, ensure => file } } + /(.*) regex$/: { file { "/tmp/${1}file6": mode => 755, ensure => file } } + default: { file { "/tmp/existsfile6": mode => 711, ensure => file } } +} diff --git a/spec/fixtures/unit/parser/lexer/classheirarchy.pp b/spec/fixtures/unit/parser/lexer/classheirarchy.pp new file mode 100644 index 000000000..36619d8b9 --- /dev/null +++ b/spec/fixtures/unit/parser/lexer/classheirarchy.pp @@ -0,0 +1,15 @@ +# $Id$ + +class base { + file { "/tmp/classheir1": ensure => file, mode => 755 } +} + +class sub1 inherits base { + file { "/tmp/classheir2": ensure => file, mode => 755 } +} + +class sub2 inherits base { + file { "/tmp/classheir3": ensure => file, mode => 755 } +} + +include sub1, sub2 diff --git a/spec/fixtures/unit/parser/lexer/classincludes.pp b/spec/fixtures/unit/parser/lexer/classincludes.pp new file mode 100644 index 000000000..bd5b44ed7 --- /dev/null +++ b/spec/fixtures/unit/parser/lexer/classincludes.pp @@ -0,0 +1,17 @@ +# $Id$ + +class base { + file { "/tmp/classincludes1": ensure => file, mode => 755 } +} + +class sub1 inherits base { + file { "/tmp/classincludes2": ensure => file, mode => 755 } +} + +class sub2 inherits base { + file { "/tmp/classincludes3": ensure => file, mode => 755 } +} + +$sub = "sub2" + +include sub1, $sub diff --git a/spec/fixtures/unit/parser/lexer/classpathtest.pp b/spec/fixtures/unit/parser/lexer/classpathtest.pp new file mode 100644 index 000000000..580333369 --- /dev/null +++ b/spec/fixtures/unit/parser/lexer/classpathtest.pp @@ -0,0 +1,11 @@ +# $Id$ + +define mytype { + file { "/tmp/classtest": ensure => file, mode => 755 } +} + +class testing { + mytype { "componentname": } +} + +include testing diff --git a/spec/fixtures/unit/parser/lexer/collection.pp b/spec/fixtures/unit/parser/lexer/collection.pp new file mode 100644 index 000000000..bc29510a9 --- /dev/null +++ b/spec/fixtures/unit/parser/lexer/collection.pp @@ -0,0 +1,10 @@ +class one { + @file { "/tmp/colltest1": content => "one" } + @file { "/tmp/colltest2": content => "two" } +} + +class two { + File <| content == "one" |> +} + +include one, two diff --git a/spec/fixtures/unit/parser/lexer/collection_override.pp b/spec/fixtures/unit/parser/lexer/collection_override.pp new file mode 100644 index 000000000..b1b39ab16 --- /dev/null +++ b/spec/fixtures/unit/parser/lexer/collection_override.pp @@ -0,0 +1,8 @@ +@file { + "/tmp/collection": + content => "whatever" +} + +File<| |> { + mode => 0600 +} diff --git a/spec/fixtures/unit/parser/lexer/collection_within_virtual_definitions.pp b/spec/fixtures/unit/parser/lexer/collection_within_virtual_definitions.pp new file mode 100644 index 000000000..3c21468b0 --- /dev/null +++ b/spec/fixtures/unit/parser/lexer/collection_within_virtual_definitions.pp @@ -0,0 +1,20 @@ +define test($name) { + file {"/tmp/collection_within_virtual_definitions1_$name.txt": + content => "File name $name\n" + } + Test2 <||> +} + +define test2() { + file {"/tmp/collection_within_virtual_definitions2_$name.txt": + content => "This is a test\n" + } +} + +node default { + @test {"foo": + name => "foo" + } + @test2 {"foo2": } + Test <||> +} diff --git a/spec/fixtures/unit/parser/lexer/componentmetaparams.pp b/spec/fixtures/unit/parser/lexer/componentmetaparams.pp new file mode 100644 index 000000000..7d9f0c2c1 --- /dev/null +++ b/spec/fixtures/unit/parser/lexer/componentmetaparams.pp @@ -0,0 +1,11 @@ +file { "/tmp/component1": + ensure => file +} + +define thing { + file { $name: ensure => file } +} + +thing { "/tmp/component2": + require => File["/tmp/component1"] +} diff --git a/spec/fixtures/unit/parser/lexer/componentrequire.pp b/spec/fixtures/unit/parser/lexer/componentrequire.pp new file mode 100644 index 000000000..a61d2050c --- /dev/null +++ b/spec/fixtures/unit/parser/lexer/componentrequire.pp @@ -0,0 +1,8 @@ +define testfile($mode) { + file { $name: mode => $mode, ensure => present } +} + +testfile { "/tmp/testing_component_requires2": mode => 755 } + +file { "/tmp/testing_component_requires1": mode => 755, ensure => present, + require => Testfile["/tmp/testing_component_requires2"] } diff --git a/spec/fixtures/unit/parser/lexer/deepclassheirarchy.pp b/spec/fixtures/unit/parser/lexer/deepclassheirarchy.pp new file mode 100644 index 000000000..249e6334d --- /dev/null +++ b/spec/fixtures/unit/parser/lexer/deepclassheirarchy.pp @@ -0,0 +1,23 @@ +# $Id$ + +class base { + file { "/tmp/deepclassheir1": ensure => file, mode => 755 } +} + +class sub1 inherits base { + file { "/tmp/deepclassheir2": ensure => file, mode => 755 } +} + +class sub2 inherits sub1 { + file { "/tmp/deepclassheir3": ensure => file, mode => 755 } +} + +class sub3 inherits sub2 { + file { "/tmp/deepclassheir4": ensure => file, mode => 755 } +} + +class sub4 inherits sub3 { + file { "/tmp/deepclassheir5": ensure => file, mode => 755 } +} + +include sub4 diff --git a/spec/fixtures/unit/parser/lexer/defineoverrides.pp b/spec/fixtures/unit/parser/lexer/defineoverrides.pp new file mode 100644 index 000000000..c68b139e3 --- /dev/null +++ b/spec/fixtures/unit/parser/lexer/defineoverrides.pp @@ -0,0 +1,17 @@ +# $Id$ + +$file = "/tmp/defineoverrides1" + +define myfile($mode) { + file { $name: ensure => file, mode => $mode } +} + +class base { + myfile { $file: mode => 644 } +} + +class sub inherits base { + Myfile[$file] { mode => 755, } # test the end-comma +} + +include sub diff --git a/spec/fixtures/unit/parser/lexer/emptyclass.pp b/spec/fixtures/unit/parser/lexer/emptyclass.pp new file mode 100644 index 000000000..48047e748 --- /dev/null +++ b/spec/fixtures/unit/parser/lexer/emptyclass.pp @@ -0,0 +1,9 @@ +# $Id$ + +define component { +} + +class testing { +} + +include testing diff --git a/spec/fixtures/unit/parser/lexer/emptyexec.pp b/spec/fixtures/unit/parser/lexer/emptyexec.pp new file mode 100644 index 000000000..847a30d18 --- /dev/null +++ b/spec/fixtures/unit/parser/lexer/emptyexec.pp @@ -0,0 +1,3 @@ +exec { "touch /tmp/emptyexectest": + path => "/usr/bin:/bin" +} diff --git a/spec/fixtures/unit/parser/lexer/emptyifelse.pp b/spec/fixtures/unit/parser/lexer/emptyifelse.pp new file mode 100644 index 000000000..598b486ac --- /dev/null +++ b/spec/fixtures/unit/parser/lexer/emptyifelse.pp @@ -0,0 +1,9 @@ + +if false { +} else { + # nothing here +} + +if true { + # still nothing +} diff --git a/spec/fixtures/unit/parser/lexer/falsevalues.pp b/spec/fixtures/unit/parser/lexer/falsevalues.pp new file mode 100644 index 000000000..2143b79a7 --- /dev/null +++ b/spec/fixtures/unit/parser/lexer/falsevalues.pp @@ -0,0 +1,3 @@ +$value = false + +file { "/tmp/falsevalues$value": ensure => file } diff --git a/spec/fixtures/unit/parser/lexer/filecreate.pp b/spec/fixtures/unit/parser/lexer/filecreate.pp new file mode 100644 index 000000000..d7972c234 --- /dev/null +++ b/spec/fixtures/unit/parser/lexer/filecreate.pp @@ -0,0 +1,11 @@ +# $Id$ + +file { + "/tmp/createatest": ensure => file, mode => 755; + "/tmp/createbtest": ensure => file, mode => 755 +} + +file { + "/tmp/createctest": ensure => file; + "/tmp/createdtest": ensure => file; +} diff --git a/spec/fixtures/unit/parser/lexer/fqdefinition.pp b/spec/fixtures/unit/parser/lexer/fqdefinition.pp new file mode 100644 index 000000000..ddb0675a9 --- /dev/null +++ b/spec/fixtures/unit/parser/lexer/fqdefinition.pp @@ -0,0 +1,5 @@ +define one::two($ensure) { + file { "/tmp/fqdefinition": ensure => $ensure } +} + +one::two { "/tmp/fqdefinition": ensure => file } diff --git a/spec/fixtures/unit/parser/lexer/fqparents.pp b/spec/fixtures/unit/parser/lexer/fqparents.pp new file mode 100644 index 000000000..ee2f65423 --- /dev/null +++ b/spec/fixtures/unit/parser/lexer/fqparents.pp @@ -0,0 +1,11 @@ +class base { + class one { + file { "/tmp/fqparent1": ensure => file } + } +} + +class two::three inherits base::one { + file { "/tmp/fqparent2": ensure => file } +} + +include two::three diff --git a/spec/fixtures/unit/parser/lexer/funccomma.pp b/spec/fixtures/unit/parser/lexer/funccomma.pp new file mode 100644 index 000000000..32e34f92e --- /dev/null +++ b/spec/fixtures/unit/parser/lexer/funccomma.pp @@ -0,0 +1,5 @@ +@file { + ["/tmp/funccomma1","/tmp/funccomma2"]: content => "1" +} + +realize( File["/tmp/funccomma1"], File["/tmp/funccomma2"] , ) diff --git a/spec/fixtures/unit/parser/lexer/hash.pp b/spec/fixtures/unit/parser/lexer/hash.pp new file mode 100644 index 000000000..d33249872 --- /dev/null +++ b/spec/fixtures/unit/parser/lexer/hash.pp @@ -0,0 +1,33 @@ + +$hash = { "file" => "/tmp/myhashfile1" } + +file { + $hash["file"]: + ensure => file, content => "content"; +} + +$hash2 = { "a" => { key => "/tmp/myhashfile2" }} + +file { + $hash2["a"][key]: + ensure => file, content => "content"; +} + +define test($a = { "b" => "c" }) { + file { + $a["b"]: + ensure => file, content => "content" + } +} + +test { + "test": + a => { "b" => "/tmp/myhashfile3" } +} + +$hash3 = { mykey => "/tmp/myhashfile4" } +$key = "mykey" + +file { + $hash3[$key]: ensure => file, content => "content" +} diff --git a/spec/fixtures/unit/parser/lexer/ifexpression.pp b/spec/fixtures/unit/parser/lexer/ifexpression.pp new file mode 100644 index 000000000..29a637291 --- /dev/null +++ b/spec/fixtures/unit/parser/lexer/ifexpression.pp @@ -0,0 +1,12 @@ +$one = 1 +$two = 2 + +if ($one < $two) and (($two < 3) or ($two == 2)) { + notice("True!") +} + +if "test regex" =~ /(.*) regex/ { + file { + "/tmp/${1}iftest": ensure => file, mode => 0755 + } +} diff --git a/spec/fixtures/unit/parser/lexer/implicititeration.pp b/spec/fixtures/unit/parser/lexer/implicititeration.pp new file mode 100644 index 000000000..6f34cb29c --- /dev/null +++ b/spec/fixtures/unit/parser/lexer/implicititeration.pp @@ -0,0 +1,15 @@ +# $Id$ + +$files = ["/tmp/iterationatest", "/tmp/iterationbtest"] + +file { $files: ensure => file, mode => 755 } + +file { ["/tmp/iterationctest", "/tmp/iterationdtest"]: + ensure => file, + mode => 755 +} + +file { + ["/tmp/iterationetest", "/tmp/iterationftest"]: ensure => file, mode => 755; + ["/tmp/iterationgtest", "/tmp/iterationhtest"]: ensure => file, mode => 755; +} diff --git a/spec/fixtures/unit/parser/lexer/multilinecomments.pp b/spec/fixtures/unit/parser/lexer/multilinecomments.pp new file mode 100644 index 000000000..f9819c020 --- /dev/null +++ b/spec/fixtures/unit/parser/lexer/multilinecomments.pp @@ -0,0 +1,10 @@ + +/* +file { + "/tmp/multilinecomments": content => "pouet" +} +*/ + +/* and another one for #2333, the whitespace after the +end comment is here on purpose */ + diff --git a/spec/fixtures/unit/parser/lexer/multipleclass.pp b/spec/fixtures/unit/parser/lexer/multipleclass.pp new file mode 100644 index 000000000..ae02edc38 --- /dev/null +++ b/spec/fixtures/unit/parser/lexer/multipleclass.pp @@ -0,0 +1,9 @@ +class one { + file { "/tmp/multipleclassone": content => "one" } +} + +class one { + file { "/tmp/multipleclasstwo": content => "two" } +} + +include one diff --git a/spec/fixtures/unit/parser/lexer/multipleinstances.pp b/spec/fixtures/unit/parser/lexer/multipleinstances.pp new file mode 100644 index 000000000..2f9b3c2e8 --- /dev/null +++ b/spec/fixtures/unit/parser/lexer/multipleinstances.pp @@ -0,0 +1,7 @@ +# $Id$ + +file { + "/tmp/multipleinstancesa": ensure => file, mode => 755; + "/tmp/multipleinstancesb": ensure => file, mode => 755; + "/tmp/multipleinstancesc": ensure => file, mode => 755; +} diff --git a/spec/fixtures/unit/parser/lexer/multisubs.pp b/spec/fixtures/unit/parser/lexer/multisubs.pp new file mode 100644 index 000000000..bcec69e2a --- /dev/null +++ b/spec/fixtures/unit/parser/lexer/multisubs.pp @@ -0,0 +1,13 @@ +class base { + file { "/tmp/multisubtest": content => "base", mode => 644 } +} + +class sub1 inherits base { + File["/tmp/multisubtest"] { mode => 755 } +} + +class sub2 inherits base { + File["/tmp/multisubtest"] { content => sub2 } +} + +include sub1, sub2 diff --git a/spec/fixtures/unit/parser/lexer/namevartest.pp b/spec/fixtures/unit/parser/lexer/namevartest.pp new file mode 100644 index 000000000..dbee1c356 --- /dev/null +++ b/spec/fixtures/unit/parser/lexer/namevartest.pp @@ -0,0 +1,9 @@ +define filetest($mode, $ensure = file) { + file { $name: + mode => $mode, + ensure => $ensure + } +} + +filetest { "/tmp/testfiletest": mode => 644} +filetest { "/tmp/testdirtest": mode => 755, ensure => directory} diff --git a/spec/fixtures/unit/parser/lexer/scopetest.pp b/spec/fixtures/unit/parser/lexer/scopetest.pp new file mode 100644 index 000000000..331491766 --- /dev/null +++ b/spec/fixtures/unit/parser/lexer/scopetest.pp @@ -0,0 +1,13 @@ + +$mode = 640 + +define thing { + file { "/tmp/$name": ensure => file, mode => $mode } +} + +class testing { + $mode = 755 + thing {scopetest: } +} + +include testing diff --git a/spec/fixtures/unit/parser/lexer/selectorvalues.pp b/spec/fixtures/unit/parser/lexer/selectorvalues.pp new file mode 100644 index 000000000..d80d26c36 --- /dev/null +++ b/spec/fixtures/unit/parser/lexer/selectorvalues.pp @@ -0,0 +1,49 @@ +$value1 = "" +$value2 = true +$value3 = false +$value4 = yay + +$test = "yay" + +$mode1 = $value1 ? { + "" => 755, + default => 644 +} + +$mode2 = $value2 ? { + true => 755, + default => 644 +} + +$mode3 = $value3 ? { + false => 755, + default => 644 +} + +$mode4 = $value4 ? { + $test => 755, + default => 644 +} + +$mode5 = yay ? { + $test => 755, + default => 644 +} + +$mode6 = $mode5 ? { + 755 => 755 +} + +$mode7 = "test regex" ? { + /regex$/ => 755, + default => 644 +} + + +file { "/tmp/selectorvalues1": ensure => file, mode => $mode1 } +file { "/tmp/selectorvalues2": ensure => file, mode => $mode2 } +file { "/tmp/selectorvalues3": ensure => file, mode => $mode3 } +file { "/tmp/selectorvalues4": ensure => file, mode => $mode4 } +file { "/tmp/selectorvalues5": ensure => file, mode => $mode5 } +file { "/tmp/selectorvalues6": ensure => file, mode => $mode6 } +file { "/tmp/selectorvalues7": ensure => file, mode => $mode7 } diff --git a/spec/fixtures/unit/parser/lexer/simpledefaults.pp b/spec/fixtures/unit/parser/lexer/simpledefaults.pp new file mode 100644 index 000000000..63d199a68 --- /dev/null +++ b/spec/fixtures/unit/parser/lexer/simpledefaults.pp @@ -0,0 +1,5 @@ +# $Id$ + +File { mode => 755 } + +file { "/tmp/defaulttest": ensure => file } diff --git a/spec/fixtures/unit/parser/lexer/simpleselector.pp b/spec/fixtures/unit/parser/lexer/simpleselector.pp new file mode 100644 index 000000000..8b9bc7292 --- /dev/null +++ b/spec/fixtures/unit/parser/lexer/simpleselector.pp @@ -0,0 +1,38 @@ +# $Id$ + +$var = "value" + +file { "/tmp/snippetselectatest": + ensure => file, + mode => $var ? { + nottrue => 641, + value => 755 + } +} + +file { "/tmp/snippetselectbtest": + ensure => file, + mode => $var ? { + nottrue => 644, + default => 755 + } +} + +$othervar = "complex value" + +file { "/tmp/snippetselectctest": + ensure => file, + mode => $othervar ? { + "complex value" => 755, + default => 644 + } +} +$anothervar = Yayness + +file { "/tmp/snippetselectdtest": + ensure => file, + mode => $anothervar ? { + Yayness => 755, + default => 644 + } +} diff --git a/spec/fixtures/unit/parser/lexer/singleary.pp b/spec/fixtures/unit/parser/lexer/singleary.pp new file mode 100644 index 000000000..9ce56dd89 --- /dev/null +++ b/spec/fixtures/unit/parser/lexer/singleary.pp @@ -0,0 +1,19 @@ +# $Id$ + +file { "/tmp/singleary1": + ensure => file +} + +file { "/tmp/singleary2": + ensure => file +} + +file { "/tmp/singleary3": + ensure => file, + require => [File["/tmp/singleary1"], File["/tmp/singleary2"]] +} + +file { "/tmp/singleary4": + ensure => file, + require => [File["/tmp/singleary1"]] +} diff --git a/spec/fixtures/unit/parser/lexer/singlequote.pp b/spec/fixtures/unit/parser/lexer/singlequote.pp new file mode 100644 index 000000000..dc876a2f8 --- /dev/null +++ b/spec/fixtures/unit/parser/lexer/singlequote.pp @@ -0,0 +1,11 @@ +# $Id$ + +file { "/tmp/singlequote1": + ensure => file, + content => 'a $quote' +} + +file { "/tmp/singlequote2": + ensure => file, + content => 'some "\yayness\"' +} diff --git a/spec/fixtures/unit/parser/lexer/singleselector.pp b/spec/fixtures/unit/parser/lexer/singleselector.pp new file mode 100644 index 000000000..520a14017 --- /dev/null +++ b/spec/fixtures/unit/parser/lexer/singleselector.pp @@ -0,0 +1,22 @@ +$value1 = "" +$value2 = true +$value3 = false +$value4 = yay + +$test = "yay" + +$mode1 = $value1 ? { + "" => 755 +} + +$mode2 = $value2 ? { + true => 755 +} + +$mode3 = $value3 ? { + default => 755 +} + +file { "/tmp/singleselector1": ensure => file, mode => $mode1 } +file { "/tmp/singleselector2": ensure => file, mode => $mode2 } +file { "/tmp/singleselector3": ensure => file, mode => $mode3 } diff --git a/spec/fixtures/unit/parser/lexer/subclass_name_duplication.pp b/spec/fixtures/unit/parser/lexer/subclass_name_duplication.pp new file mode 100755 index 000000000..10f1d75ed --- /dev/null +++ b/spec/fixtures/unit/parser/lexer/subclass_name_duplication.pp @@ -0,0 +1,11 @@ +#!/usr/bin/env puppet + +class one::fake { + file { "/tmp/subclass_name_duplication1": ensure => present } +} + +class two::fake { + file { "/tmp/subclass_name_duplication2": ensure => present } +} + +include one::fake, two::fake diff --git a/spec/fixtures/unit/parser/lexer/tag.pp b/spec/fixtures/unit/parser/lexer/tag.pp new file mode 100644 index 000000000..e6e770dd9 --- /dev/null +++ b/spec/fixtures/unit/parser/lexer/tag.pp @@ -0,0 +1,9 @@ +# $Id$ + +$variable = value + +tag yayness, rahness + +tag booness, $variable + +file { "/tmp/settestingness": ensure => file } diff --git a/spec/fixtures/unit/parser/lexer/tagged.pp b/spec/fixtures/unit/parser/lexer/tagged.pp new file mode 100644 index 000000000..7bf90a645 --- /dev/null +++ b/spec/fixtures/unit/parser/lexer/tagged.pp @@ -0,0 +1,35 @@ +# $Id$ + +tag testing +tag(funtest) + +class tagdefine { + $path = tagged(tagdefine) ? { + true => "true", false => "false" + } + + file { "/tmp/taggeddefine$path": ensure => file } +} + +include tagdefine + +$yayness = tagged(yayness) ? { + true => "true", false => "false" +} + +$funtest = tagged(testing) ? { + true => "true", false => "false" +} + +$both = tagged(testing, yayness) ? { + true => "true", false => "false" +} + +$bothtrue = tagged(testing, testing) ? { + true => "true", false => "false" +} + +file { "/tmp/taggedyayness$yayness": ensure => file } +file { "/tmp/taggedtesting$funtest": ensure => file } +file { "/tmp/taggedboth$both": ensure => file } +file { "/tmp/taggedbothtrue$bothtrue": ensure => file } diff --git a/spec/fixtures/unit/parser/lexer/virtualresources.pp b/spec/fixtures/unit/parser/lexer/virtualresources.pp new file mode 100644 index 000000000..a29406b84 --- /dev/null +++ b/spec/fixtures/unit/parser/lexer/virtualresources.pp @@ -0,0 +1,14 @@ +class one { + @file { "/tmp/virtualtest1": content => "one" } + @file { "/tmp/virtualtest2": content => "two" } + @file { "/tmp/virtualtest3": content => "three" } + @file { "/tmp/virtualtest4": content => "four" } +} + +class two { + File <| content == "one" |> + realize File["/tmp/virtualtest2"] + realize(File["/tmp/virtualtest3"], File["/tmp/virtualtest4"]) +} + +include one, two diff --git a/spec/fixtures/unit/provider/host/parsed/valid_hosts b/spec/fixtures/unit/provider/host/parsed/valid_hosts new file mode 100644 index 000000000..24636295d --- /dev/null +++ b/spec/fixtures/unit/provider/host/parsed/valid_hosts @@ -0,0 +1,19 @@ +# Some leading comment, that should be ignored +# The next line is empty so it should be ignored + +::1 localhost + +# We now try another delimiter: Several tabs +127.0.0.1 localhost + +# No test trailing spaces +10.0.0.1 host1 + +# Ok its time to test aliases +2001:252:0:1::2008:8 ipv6host alias1 +192.168.0.1 ipv4host alias2 alias3 + +# Testing inlinecomments now +192.168.0.2 host3 # This is host3 +192.168.0.3 host4 alias10 # This is host4 +192.168.0.4 host5 alias11 alias12 # This is host5 diff --git a/spec/fixtures/unit/provider/mount/parsed/aix.filesystems b/spec/fixtures/unit/provider/mount/parsed/aix.filesystems new file mode 100644 index 000000000..7347f2b8c --- /dev/null +++ b/spec/fixtures/unit/provider/mount/parsed/aix.filesystems @@ -0,0 +1,144 @@ +* IBM_PROLOG_BEGIN_TAG +* This is an automatically generated prolog. +* +* bos61B src/bos/etc/filesystems/filesystems 1.23 +* +* Licensed Materials - Property of IBM +* +* COPYRIGHT International Business Machines Corp. 1985,1993 +* All Rights Reserved +* +* US Government Users Restricted Rights - Use, duplication or +* disclosure restricted by GSA ADP Schedule Contract with IBM Corp. +* +* @(#)filesystems @(#)29 1.23 src/bos/etc/filesystems/filesystems, cmdfs, bos61B, b2007_38A8 8/16/07 17:18:35 +* IBM_PROLOG_END_TAG +* +* COMPONENT_NAME: CMDFS +* +* FUNCTIONS: none +* +* ORIGINS: 27 +* +* (C) COPYRIGHT International Business Machines Corp. 1985, 1993 +* All Rights Reserved +* Licensed Materials - Property of IBM +* +* US Government Users Restricted Rights - Use, duplication or +* disclosure restricted by GSA ADP Schedule Contract with IBM Corp. +* +* +* +* This version of /etc/filesystems assumes that only the root file system +* is created and ready. As new file systems are added, change the check, +* mount, free, log, vol and vfs entries for the appropriate stanza. +* + +/: + dev = /dev/hd4 + vfs = jfs2 + log = /dev/hd8 + mount = automatic + check = false + type = bootfs + vol = root + free = true + quota = no + +/home: + dev = /dev/hd1 + vfs = jfs2 + log = /dev/hd8 + mount = true + check = true + vol = /home + free = false + quota = no + +/usr: + dev = /dev/hd2 + vfs = jfs2 + log = /dev/hd8 + mount = automatic + check = false + type = bootfs + vol = /usr + free = false + quota = no + +/var: + dev = /dev/hd9var + vfs = jfs2 + log = /dev/hd8 + mount = automatic + check = false + type = bootfs + vol = /var + free = false + quota = no + +/tmp: + dev = /dev/hd3 + vfs = jfs2 + log = /dev/hd8 + mount = automatic + check = false + vol = /tmp + free = false + quota = no + +/admin: + dev = /dev/hd11admin + vfs = jfs2 + log = /dev/hd8 + mount = true + check = false + vol = /admin + free = false + quota = no + +/proc: + dev = /proc + vol = "/proc" + mount = true + check = false + free = false + vfs = procfs + +/opt: + dev = /dev/hd10opt + vfs = jfs2 + log = /dev/hd8 + mount = true + check = true + vol = /opt + free = false + quota = no + +/var/adm/ras/livedump: + dev = /dev/livedump + vfs = jfs2 + log = /dev/hd8 + mount = true + account = false + quota = no + + +/stage/middleware: + dev = "/stage/middleware" + vfs = nfs + nodename = 192.168.1.11 + mount = true + type = nfs + options = ro,bg,hard,intr,sec=sys + account = false + +/home/u0010689: + dev = "/userdata/20010689" + vfs = nfs + nodename = 192.168.1.11 + mount = true + type = nfs + options = bg,hard,intr + account = false + diff --git a/spec/fixtures/unit/provider/mount/parsed/aix.mount b/spec/fixtures/unit/provider/mount/parsed/aix.mount new file mode 100644 index 000000000..380dbc5ae --- /dev/null +++ b/spec/fixtures/unit/provider/mount/parsed/aix.mount @@ -0,0 +1,7 @@ +node mounted mounted over vfs date options +---- ------- ------------ --- ------------ ------------------- + /dev/hd0 / jfs Dec 17 08:04 rw, log =/dev/hd8 + /dev/hd3 /tmp jfs Dec 17 08:04 rw, log =/dev/hd8 + /dev/hd1 /home jfs Dec 17 08:06 rw, log =/dev/hd8 + /dev/hd2 /usr jfs Dec 17 08:06 rw, log =/dev/hd8 +sue /home/local/src /usr/code nfs Dec 17 08:06 ro, log =/dev/hd8 diff --git a/spec/fixtures/unit/provider/mount/parsed/darwin.mount b/spec/fixtures/unit/provider/mount/parsed/darwin.mount new file mode 100644 index 000000000..1bdfcf89a --- /dev/null +++ b/spec/fixtures/unit/provider/mount/parsed/darwin.mount @@ -0,0 +1,6 @@ +/dev/disk0s2 on / (hfs, local, journaled) +devfs on /dev (devfs, local, nobrowse) +map -hosts on /net (autofs, nosuid, automounted, nobrowse) +map auto_home on /home (autofs, automounted, nobrowse) +/dev/disk0s3 on /usr (hfs, local, journaled) +/dev/fake on /ghost (hfs, local, journaled) diff --git a/spec/fixtures/unit/provider/mount/parsed/freebsd.fstab b/spec/fixtures/unit/provider/mount/parsed/freebsd.fstab new file mode 100644 index 000000000..41b749bff --- /dev/null +++ b/spec/fixtures/unit/provider/mount/parsed/freebsd.fstab @@ -0,0 +1,8 @@ +# Device Mountpoint FStype Options Dump Pass# +/dev/ad0s1b none swap sw 0 0 +/dev/ad0s1a / ufs rw 1 1 +/dev/ad0s1e /tmp ufs rw 2 2 +/dev/ad0s1f /usr ufs rw 2 2 +/dev/ad0s1d /var ufs rw 2 2 +/dev/ad0s1g /boot ufs rw 2 2 +/dev/acd0 /cdrom cd9660 ro,noauto 0 0 diff --git a/spec/fixtures/unit/provider/mount/parsed/freebsd.mount b/spec/fixtures/unit/provider/mount/parsed/freebsd.mount new file mode 100644 index 000000000..89c518c5d --- /dev/null +++ b/spec/fixtures/unit/provider/mount/parsed/freebsd.mount @@ -0,0 +1,3 @@ +/dev/ad0s1a on / (ufs, local, soft-updates) +/dev/ad0s1d on /ghost (ufs, local, soft-updates) +devfs on /dev (devfs, local, multilabel) diff --git a/spec/fixtures/unit/provider/mount/parsed/hpux.mount b/spec/fixtures/unit/provider/mount/parsed/hpux.mount new file mode 100644 index 000000000..d414fa47a --- /dev/null +++ b/spec/fixtures/unit/provider/mount/parsed/hpux.mount @@ -0,0 +1,17 @@ +/ on rpool/ROOT/opensolaris read/write/setuid/devices/dev=2d90002 on Wed Dec 31 16:00:00 1969 +/devices on /devices read/write/setuid/devices/dev=4a00000 on Thu Feb 17 14:34:02 2011 +/dev on /dev read/write/setuid/devices/dev=4a40000 on Thu Feb 17 14:34:02 2011 +/system/contract on ctfs read/write/setuid/devices/dev=4ac0001 on Thu Feb 17 14:34:02 2011 +/proc on proc read/write/setuid/devices/dev=4b00000 on Thu Feb 17 14:34:02 2011 +/etc/mnttab on mnttab read/write/setuid/devices/dev=4b40001 on Thu Feb 17 14:34:02 2011 +/etc/svc/volatile on swap read/write/setuid/devices/xattr/dev=4b80001 on Thu Feb 17 14:34:02 2011 +/system/object on objfs read/write/setuid/devices/dev=4bc0001 on Thu Feb 17 14:34:02 2011 +/etc/dfs/sharetab on sharefs read/write/setuid/devices/dev=4c00001 on Thu Feb 17 14:34:02 2011 +/lib/libc.so.1 on /usr/lib/libc/libc_hwcap1.so.1 read/write/setuid/devices/dev=2d90002 on Thu Feb 17 14:34:14 2011 +/dev/fd on fd read/write/setuid/devices/dev=4d00001 on Thu Feb 17 14:34:18 2011 +/tmp on swap read/write/setuid/devices/xattr/dev=4b80002 on Thu Feb 17 14:34:19 2011 +/var/run on swap read/write/setuid/devices/xattr/dev=4b80003 on Thu Feb 17 14:34:19 2011 +/export on rpool/export read/write/setuid/devices/nonbmand/exec/xattr/atime/dev=2d90006 on Thu Feb 17 14:37:48 2011 +/export/home on rpool/export/home read/write/setuid/devices/nonbmand/exec/xattr/atime/dev=2d90007 on Thu Feb 17 14:37:48 2011 +/rpool on rpool read/write/setuid/devices/nonbmand/exec/xattr/atime/dev=2d90009 on Thu Feb 17 14:37:48 2011 +/ghost on /dev/fake read/write/setuid/devices/nonbmand/exec/xattr/atime/dev=2d90009 on Thu Feb 17 14:37:48 2011 diff --git a/spec/fixtures/unit/provider/mount/parsed/linux.fstab b/spec/fixtures/unit/provider/mount/parsed/linux.fstab new file mode 100644 index 000000000..b1debff9c --- /dev/null +++ b/spec/fixtures/unit/provider/mount/parsed/linux.fstab @@ -0,0 +1,11 @@ +# A sample fstab, typical for a Fedora system +/dev/vg00/lv00 / ext3 defaults 1 1 +LABEL=/boot /boot ext3 defaults 1 2 +devpts /dev/pts devpts gid=5,mode=620 0 +tmpfs /dev/shm tmpfs defaults 0 +LABEL=/home /home ext3 defaults 1 2 +/home /homes auto bind 0 2 +proc /proc proc defaults 0 0 +/dev/vg00/lv01 /spare ext3 defaults 1 2 +sysfs /sys sysfs defaults 0 0 +LABEL=SWAP-hda6 swap swap defaults 0 0 diff --git a/spec/fixtures/unit/provider/mount/parsed/linux.mount b/spec/fixtures/unit/provider/mount/parsed/linux.mount new file mode 100644 index 000000000..75dd71fd4 --- /dev/null +++ b/spec/fixtures/unit/provider/mount/parsed/linux.mount @@ -0,0 +1,5 @@ +/dev/root on / type jfs (rw,noatime) +rc-svcdir on /lib64/rc/init.d type tmpfs (rw,nosuid,nodev,noexec,relatime,size=1024k,mode=755) +sysfs on /sys type sysfs (rw,nosuid,nodev,noexec,relatime) +/dev/sda9 on /usr/portage type jfs (rw) +/dev/fake on /ghost type jfs (rw) diff --git a/spec/fixtures/unit/provider/mount/parsed/netbsd.fstab b/spec/fixtures/unit/provider/mount/parsed/netbsd.fstab new file mode 100644 index 000000000..ca3ca8450 --- /dev/null +++ b/spec/fixtures/unit/provider/mount/parsed/netbsd.fstab @@ -0,0 +1,9 @@ +# Device Mountpoint FStype Options Dump Pass# +/dev/ad0s1b none swap sw 0 0 +/dev/ad0s1a / ufs rw 1 1 +/dev/ad0s1e /tmp ufs rw 2 2 +/dev/ad0s1f /usr ufs rw 2 2 +/dev/ad0s1d /var ufs rw 2 2 +/dev/ad3s1b none swap sw 0 0 +/dev/ad3s1e /data ufs rw 2 2 +/dev/ad3s1g /boot ufs rw 2 2 diff --git a/spec/fixtures/unit/provider/mount/parsed/netbsd.mount b/spec/fixtures/unit/provider/mount/parsed/netbsd.mount new file mode 100644 index 000000000..dfdc26a34 --- /dev/null +++ b/spec/fixtures/unit/provider/mount/parsed/netbsd.mount @@ -0,0 +1,8 @@ +/dev/ad0s1a on / (ufs, local) +devfs on /dev (devfs, local) +/dev/ad0s1e on /tmp (ufs, local, soft-updates) +/dev/ad0s1f on /usr (ufs, local, soft-updates) +/dev/ad0s1d on /var (ufs, local, soft-updates) +/dev/ad3s1e on /data (ufs, local, soft-updates) +/dev/ad3s1h on /ghost (ufs, local, soft-updates) +devfs on /var/named/dev (devfs, local) diff --git a/spec/fixtures/unit/provider/mount/parsed/openbsd.fstab b/spec/fixtures/unit/provider/mount/parsed/openbsd.fstab new file mode 100644 index 000000000..44c83eed1 --- /dev/null +++ b/spec/fixtures/unit/provider/mount/parsed/openbsd.fstab @@ -0,0 +1,4 @@ +/dev/wd0a / ffs rw 1 1 +/dev/wd0e /home ffs rw,nodev,nosuid 1 2 +/dev/wd0d /usr ffs rw,nodev 1 2 +/dev/wd0f /boot ffs rw,nodev 1 2 diff --git a/spec/fixtures/unit/provider/mount/parsed/openbsd.mount b/spec/fixtures/unit/provider/mount/parsed/openbsd.mount new file mode 100644 index 000000000..367475783 --- /dev/null +++ b/spec/fixtures/unit/provider/mount/parsed/openbsd.mount @@ -0,0 +1,4 @@ +/dev/wd0a on / type ffs (local) +/dev/wd0e on /home type ffs (local, nodev, nosuid) +/dev/wd0d on /usr type ffs (local, nodev) +/dev/wd0g on /ghost type ffs (local, nodev) diff --git a/spec/fixtures/unit/provider/mount/parsed/solaris.fstab b/spec/fixtures/unit/provider/mount/parsed/solaris.fstab new file mode 100644 index 000000000..54afc898c --- /dev/null +++ b/spec/fixtures/unit/provider/mount/parsed/solaris.fstab @@ -0,0 +1,11 @@ +#device device mount FS fsck mount mount +#to mount to fsck point type pass at boot options +# +fd - /dev/fd fd - no - +/proc - /proc proc - no - +/dev/dsk/c0d0s0 /dev/rdsk/c0d0s0 / ufs 1 no - +/dev/dsk/c0d0p0:boot - /boot pcfs - no - +/devices - /devices devfs - no - +ctfs - /system/contract ctfs - no - +objfs - /system/object objfs - no - +#swap - /tmp tmpfs - yes - diff --git a/spec/fixtures/unit/provider/mount/parsed/solaris.mount b/spec/fixtures/unit/provider/mount/parsed/solaris.mount new file mode 100644 index 000000000..26fabc575 --- /dev/null +++ b/spec/fixtures/unit/provider/mount/parsed/solaris.mount @@ -0,0 +1,6 @@ +/ on /dev/dsk/c0t0d0s0 read/write/setuid/intr/largefiles/xattr/onerror=panic/dev=2200000 on Mon Mar 18 08:48:45 2002 +/proc on /proc read/write/setuid/dev=4300000 on Mon Mar 18 08:48:44 2002 +/etc/mnttab on mnttab read/write/setuid/dev=43c0000 on Mon Mar 18 08:48:44 2002 +/tmp on swap read/write/setuid/xattr/dev=2 on Mon Mar 18 08:48:52 2002 +/export/home on /dev/dsk/c0t0d0s7 read/write/setuid/intr/largefiles/xattr/onerror=panic/dev=2200007 on Mon Mar 18 +/ghost on /dev/dsk/c0t1d0s7 read/write/setuid/intr/largefiles/xattr/onerror=panic/dev=2200007 on Mon Mar 18 diff --git a/spec/fixtures/unit/provider/ssh_authorized_key/parsed/authorized_keys b/spec/fixtures/unit/provider/ssh_authorized_key/parsed/authorized_keys new file mode 100644 index 000000000..b22329dca --- /dev/null +++ b/spec/fixtures/unit/provider/ssh_authorized_key/parsed/authorized_keys @@ -0,0 +1,7 @@ +ssh-dss AAAAB3NzaC1kc3MAAACBAJkupmdsJSDXfUy5EU5NTRBDr9Woo3w0YnB8KmnJW9ghU8C7SkWPB1fIHVe+esFfd3qWBseb83PoFX63geZJAg6bjV4/Rdn1zEoa9EO2QyUdYUen4+rpsh3vVKZ6HFNsn3+W5+kPYgE1F/N4INqkbjY3sqCkP/W1BL9+sbVVbuJFAAAAFQCfjWDk5XhvGUkPjNWWVqltBYzHtwAAAIEAg/XL7ky7x9Ad5banzPFAfmM+DGFe0A/JEbLDjKmr5KBM5x4RFohtEvZ8ECuVGUOqBWdgAjyYwsG4oRVjLnKrf/rgmbNRzSFgEWkcAye3BVwk7Dt6hh4knEl+mNfOLq+FH0011UhecOiqTcESMzQDtgQ1vJh2VchElBLjl3x/ZugAAACAAh5jGQC338t5ObP8trSlOefkx0sXmmEzUbo3Mt8mGUuGJPx8m+X0L8Xd+l5rQxytqE3SmV/RD+6REqBuPqHM8RQuqAzfjdOeg/Ajdggx1CRMTVhltZsgQoxO30cz9Qo0SdPoL+Jp1fLuaLZq7m/RmsWYvoLT3jebBlpvvQE8YlI= francois.deppierraz@nimag.net +ssh-dss AAAAB3NzaC1kc3MAAACBAJkupmdsJSDXfUy5EU5NTRBDr9Woo3w0YnB8KmnJW9ghU8C7SkWPB1fIHVe+esFfd3qWBseb83PoFX63geZJAg6bjV4/Rdn1zEoa9EO2QyUdYUen4+rpsh3vVKZ6HFNsn3+W5+kPYgE1F/N4INqkbjY3sqCkP/W1BL9+sbVVbuJFAAAAFQCfjWDk5XhvGUkPjNWWVqltBYzHtwAAAIEAg/XL7ky7x9Ad5banzPFAfmM+DGFe0A/JEbLDjKmr5KBM5x4RFohtEvZ8ECuVGUOqBWdgAjyYwsG4oRVjLnKrf/rgmbNRzSFgEWkcAye3BVwk7Dt6hh4knEl+mNfOLq+FH0011UhecOiqTcESMzQDtgQ1vJh2VchElBLjl3x/ZugAAACAAh5jGQC338t5ObP8trSlOefkx0sXmmEzUbo3Mt8mGUuGJPx8m+X0L8Xd+l5rQxytqE3SmV/RD+6REqBuPqHM8RQuqAzfjdOeg/Ajdggx1CRMTVhltZsgQoxO30cz9Qo0SdPoL+Jp1fLuaLZq7m/RmsWYvoLT3jebBlpvvQE8YlI= Francois Deppierraz <francois@ctrlaltdel.ch> +from="192.168.1.1",command="/bin/false",no-pty,no-port-forwarding ssh-dss AAAAB3NzaC1kc3MAAACBAJkupmdsJSDXfUy5EU5NTRBDr9Woo3w0YnB8KmnJW9ghU8C7SkWPB1fIHVe+esFfd3qWBseb83PoFX63geZJAg6bjV4/Rdn1zEoa9EO2QyUdYUen4+rpsh3vVKZ6HFNsn3+W5+kPYgE1F/N4INqkbjY3sqCkP/W1BL9+sbVVbuJFAAAAFQCfjWDk5XhvGUkPjNWWVqltBYzHtwAAAIEAg/XL7ky7x9Ad5banzPFAfmM+DGFe0A/JEbLDjKmr5KBM5x4RFohtEvZ8ECuVGUOqBWdgAjyYwsG4oRVjLnKrf/rgmbNRzSFgEWkcAye3BVwk7Dt6hh4knEl+mNfOLq+FH0011UhecOiqTcESMzQDtgQ1vJh2VchElBLjl3x/ZugAAACAAh5jGQC338t5ObP8trSlOefkx0sXmmEzUbo3Mt8mGUuGJPx8m+X0L8Xd+l5rQxytqE3SmV/RD+6REqBuPqHM8RQuqAzfjdOeg/Ajdggx1CRMTVhltZsgQoxO30cz9Qo0SdPoL+Jp1fLuaLZq7m/RmsWYvoLT3jebBlpvvQE8YlI= Francois Deppierraz +from="192.168.1.1, www.reductivelabs.com",command="/bin/false",no-pty,no-port-forwarding ssh-dss AAAAB3NzaC1kc3MAAACBAJkupmdsJSDXfUy5EU5NTRBDr9Woo3w0YnB8KmnJW9ghU8C7SkWPB1fIHVe+esFfd3qWBseb83PoFX63geZJAg6bjV4/Rdn1zEoa9EO2QyUdYUen4+rpsh3vVKZ6HFNsn3+W5+kPYgE1F/N4INqkbjY3sqCkP/W1BL9+sbVVbuJFAAAAFQCfjWDk5XhvGUkPjNWWVqltBYzHtwAAAIEAg/XL7ky7x9Ad5banzPFAfmM+DGFe0A/JEbLDjKmr5KBM5x4RFohtEvZ8ECuVGUOqBWdgAjyYwsG4oRVjLnKrf/rgmbNRzSFgEWkcAye3BVwk7Dt6hh4knEl+mNfOLq+FH0011UhecOiqTcESMzQDtgQ1vJh2VchElBLjl3x/ZugAAACAAh5jGQC338t5ObP8trSlOefkx0sXmmEzUbo3Mt8mGUuGJPx8m+X0L8Xd+l5rQxytqE3SmV/RD+6REqBuPqHM8RQuqAzfjdOeg/Ajdggx1CRMTVhltZsgQoxO30cz9Qo0SdPoL+Jp1fLuaLZq7m/RmsWYvoLT3jebBlpvvQE8YlI= Francois Deppierraz +ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA2Vi+TdC3iOGYcIo5vGTvC9P9rjHl9RxCuZmSfn+YDFQ35RXf0waijtjp9I7GYh6R4hBjA5z0u/Pzi95LET5NfRM0Gdc0DJyvBI7K+ALBxIT383Iz6Yz4iKxe1TEJgHGM2he4+7BHkjc3kdIZqIpZjucCk4VsXSxujO4MKKvtaKK2l+kahlLQHHw/vZkDpIgL52iGVsjW9l8RLJaKHZ4mDHJN/Q/Rzn2W4EvcdHUzwhvGMwZlm8clDwITBrSsawYtnivJrQSYcmTRqJuS8wprNDrLIhTGjrwFg5WpruUuMt6fLuCqwe6TeEL+nh3DQ4g554c5aRp3oU6LGBKTvNZGWQ== francois@korn +ssh-dss AAAAB3NzaC1kc3MAAACBAMPpCYnjywOemd8LqbbmC+bePNR3/H1rXsiFwjSLhYE3bbOpvclvOzN1DruFc34m0FopVnMkP+aubjdIYF8pijl+5hg9ggB7Kno2dl0Dd1rGN/swvmhA8OpLAQv7Qt7UnXKVho3as08zYZsrHxYFu0wlnkdbsv4cy4aXyQKd4MPVAAAAFQDSyQFWg8Qt3wU05buhZ10psoR7tQAAAIEAmAhguXwUnI3P2FF5NAW/mpJUmUERdL4pyZARUyAgpf7ezwrh9TJqrvGTQNBF97Xqaivyncm5JWQdMIsTBxEFaXZGkmBta02KnWcn447qvIh7iv8XpNL6M9flCkBEZOJ4t9El0ytTSHHaiCz8A20Et+E8evWyi1kXkFDt8ML2dGgAAACBAK0X4ympbdEjgV/ZyOc+BU22u7vOnfSOUJmyar4Ax1MIDNnoyNWKnGvxRutydQcQOKQHZEU0fE8MhPFn6nLF6CoVfEl/oz0EYz3hjV4WPFpHrF5DY/rhvNj8iuneKJ5P0dy/rG6m5qey25PnHyGFVoIRlkHJvBCJT40dHs40YEjI francois@korn +ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAut8aOSxenjOqF527dlsdHWV4MNoAsX14l9M297+SQXaQ5Z3BedIxZaoQthkDALlV/25A1COELrg9J2MqJNQc8Xe9XQOIkBQWWinUlD/BXwoOTWEy8C8zSZPHZ3getMMNhGTBO+q/O+qiJx3y5cA4MTbw2zSxukfWC87qWwcZ64UUlegIM056vPsdZWFclS9hsROVEa57YUMrehQ1EGxT4Z5j6zIopufGFiAPjZigq/vqgcAqhAKP6yu4/gwO6S9tatBeEjZ8fafvj1pmvvIplZeMr96gHE7xS3pEEQqnB3nd4RY7AF6j9kFixnsytAUO7STPh/M3pLiVQBN89TvWPQ== diff --git a/spec/fixtures/unit/provider/ssh_authorized_key/parsed/authorized_keys1 b/spec/fixtures/unit/provider/ssh_authorized_key/parsed/authorized_keys1 new file mode 100644 index 000000000..7aa0647ca --- /dev/null +++ b/spec/fixtures/unit/provider/ssh_authorized_key/parsed/authorized_keys1 @@ -0,0 +1,3 @@ +1024 35 167576894966720957580065952882142495543043407324667405194097438434880798807651864847570827148390962746149410384891026772700627764845955493549511618975091512997118590589399665757714186775228807376424903966072778732134483862302766419277581465932186641863495699668069439475320990051723279127881281145164415361627 francois@korn +2048 35 27332429396020032283276339339051507284036000350350092862949624519871013308460312287866673933080560923221560798334008554200019645416448528663000202951887890525621015333936122655294782671001073795264378070156670395703161543893088138531854776737799752600933431638059304355933305878665812555436198516842364330938321746086651639330436648850787370397302524667456837036413634152938122227368132322078811602953517461933179827432019932348409533535942749570969101453655028606209719023224268890314608444789012688070463327764203306501923404494017305972543000091038543051645924928018568725584728655193415567703220002707737714942757 francois@korn +from="192.168.1.1",command="/bin/false",no-pty,no-port-forwarding 2048 35 27332429396020032283276339339051507284036000350350092862949624519871013308460312287866673933080560923221560798334008554200019645416448528663000202951887890525621015333936122655294782671001073795264378070156670395703161543893088138531854776737799752600933431638059304355933305878665812555436198516842364330938321746086651639330436648850787370397302524667456837036413634152938122227368132322078811602953517461933179827432019932348409533535942749570969101453655028606209719023224268890314608444789012688070463327764203306501923404494017305972543000091038543051645924928018568725584728655193415567703220002707737714942757 francois@korn diff --git a/spec/fixtures/unit/provider/ssh_authorized_key/parsed/authorized_keys2 b/spec/fixtures/unit/provider/ssh_authorized_key/parsed/authorized_keys2 new file mode 100644 index 000000000..9bf830112 --- /dev/null +++ b/spec/fixtures/unit/provider/ssh_authorized_key/parsed/authorized_keys2 @@ -0,0 +1 @@ +false ssh-dss AAAAB3NzaC1kc3MAAACBAJkupmdsJSDXfUy5EU5NTRBDr9Woo3w0YnB8KmnJW9ghU8C7SkWPB1fIHVe+esFfd3qWBseb83PoFX63geZJAg6bjV4/Rdn1zEoa9EO2QyUdYUen4+rpsh3vVKZ6HFNsn3+W5+kPYgE1F/N4INqkbjY3sqCkP/W1BL9+sbVVbuJFAAAAFQCfjWDk5XhvGUkPjNWWVqltBYzHtwAAAIEAg/XL7ky7x9Ad5banzPFAfmM+DGFe0A/JEbLDjKmr5KBM5x4RFohtEvZ8ECuVGUOqBWdgAjyYwsG4oRVjLnKrf/rgmbNRzSFgEWkcAye3BVwk7Dt6hh4knEl+mNfOLq+FH0011UhecOiqTcESMzQDtgQ1vJh2VchElBLjl3x/ZugAAACAAh5jGQC338t5ObP8trSlOefkx0sXmmEzUbo3Mt8mGUuGJPx8m+X0L8Xd+l5rQxytqE3SmV/RD+6REqBuPqHM8RQuqAzfjdOeg/Ajdggx1CRMTVhltZsgQoxO30cz9Qo0SdPoL+Jp1fLuaLZq7m/RmsWYvoLT3jebBlpvvQE8YlI= Francois Deppierraz diff --git a/spec/fixtures/unit/reports/tagmail/tagmail_failers.conf b/spec/fixtures/unit/reports/tagmail/tagmail_failers.conf new file mode 100644 index 000000000..d116b5fc7 --- /dev/null +++ b/spec/fixtures/unit/reports/tagmail/tagmail_failers.conf @@ -0,0 +1,3 @@ +tag: +: abuse@domain.com +invalid!tag: abuse@domain.com diff --git a/spec/fixtures/unit/reports/tagmail/tagmail_passers.conf b/spec/fixtures/unit/reports/tagmail/tagmail_passers.conf new file mode 100644 index 000000000..ae6d2e7f2 --- /dev/null +++ b/spec/fixtures/unit/reports/tagmail/tagmail_passers.conf @@ -0,0 +1,30 @@ +# A comment +# or maybe two +# plus some blank lines + # with some blanks plus a comment + +# a simple tag report +one: abuse@domain.com + +# with weird spacing + one : abuse@domain.com + +# with multiple tags +one, two: abuse@domain.com + +# again with the weird syntax + one , two : abuse@domain.com + +# Some negations +one, !two: abuse@domain.com + +# some oddly-formatted tags +one, two-three, !four-five, !six: abuse@domain.com + +# multiple addresses +one, two: abuse@domain.com, testing@domain.com + +# and with weird spacing +one, two: abuse@domain.com , testing@domain.com + +# and a trailing comment diff --git a/spec/fixtures/unit/util/rdoc/basic.pp b/spec/fixtures/unit/util/rdoc/basic.pp new file mode 100644 index 000000000..5616503c1 --- /dev/null +++ b/spec/fixtures/unit/util/rdoc/basic.pp @@ -0,0 +1,16 @@ +# im a class +class foo { + file { '/tmp/foo' : + ensure => present, + } +} + +# im a node +node gar { +} + +# im a define +define baz { } + +# im a resource +host { 'cow' : } diff --git a/spec/integration/application/apply_spec.rb b/spec/integration/application/apply_spec.rb index 363aa3469..876f55568 100755 --- a/spec/integration/application/apply_spec.rb +++ b/spec/integration/application/apply_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') require 'puppet_spec/files' diff --git a/spec/integration/application/doc_spec.rb b/spec/integration/application/doc_spec.rb index eaf5442a0..f0b9d7db0 100644 --- a/spec/integration/application/doc_spec.rb +++ b/spec/integration/application/doc_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') require 'puppet_spec/files' describe Puppet::Application::Doc do diff --git a/spec/integration/configurer_spec.rb b/spec/integration/configurer_spec.rb index 780c9bbd0..05b3d6146 100755 --- a/spec/integration/configurer_spec.rb +++ b/spec/integration/configurer_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../spec_helper') require 'puppet/configurer' @@ -34,7 +34,7 @@ describe Puppet::Configurer do it "should send a transaction report with valid data" do @configurer.stubs(:save_last_run_summary) - Puppet::Transaction::Report.indirection.expects(:save).with do |x, report| + Puppet::Transaction::Report.indirection.expects(:save).with do |report, x| report.time.class == Time and report.logs.length > 0 end @@ -45,12 +45,17 @@ describe Puppet::Configurer do it "should save a correct last run summary" do report = Puppet::Transaction::Report.new("apply") - report.stubs(:save) + Puppet::Transaction::Report.indirection.stubs(:save) Puppet[:lastrunfile] = tmpfile("lastrunfile") Puppet[:report] = true + # We only record integer seconds in the timestamp, and truncate + # backwards, so don't use a more accurate timestamp in the test. + # --daniel 2011-03-07 + t1 = Time.now.tv_sec @configurer.run :catalog => @catalog, :report => report + t2 = Time.now.tv_sec summary = nil File.open(Puppet[:lastrunfile], "r") do |fd| @@ -62,7 +67,7 @@ describe Puppet::Configurer do summary.should be_key(key) end summary["time"].should be_key("notify") - summary["time"]["last_run"].should >= Time.now.tv_sec + summary["time"]["last_run"].should be_between(t1, t2) end end end diff --git a/spec/integration/defaults_spec.rb b/spec/integration/defaults_spec.rb index 2f30014e8..ee0a43d07 100755 --- a/spec/integration/defaults_spec.rb +++ b/spec/integration/defaults_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../spec_helper') require 'puppet/defaults' require 'puppet/rails' @@ -116,31 +116,31 @@ describe "Puppet defaults" do describe "when enabling storeconfigs" do before do - Puppet::Resource::Catalog.stubs(:cache_class=) - Puppet::Node::Facts.stubs(:cache_class=) - Puppet::Node.stubs(:cache_class=) + Puppet::Resource::Catalog.indirection.stubs(:cache_class=) + Puppet::Node::Facts.indirection.stubs(:cache_class=) + Puppet::Node.indirection.stubs(:cache_class=) Puppet.features.stubs(:rails?).returns true end it "should set the Catalog cache class to :active_record" do - Puppet::Resource::Catalog.expects(:cache_class=).with(:active_record) + Puppet::Resource::Catalog.indirection.expects(:cache_class=).with(:active_record) Puppet.settings[:storeconfigs] = true end it "should not set the Catalog cache class to :active_record if asynchronous storeconfigs is enabled" do - Puppet::Resource::Catalog.expects(:cache_class=).with(:active_record).never + Puppet::Resource::Catalog.indirection.expects(:cache_class=).with(:active_record).never Puppet.settings.expects(:value).with(:async_storeconfigs).returns true Puppet.settings[:storeconfigs] = true end it "should set the Facts cache class to :active_record" do - Puppet::Node::Facts.expects(:cache_class=).with(:active_record) + Puppet::Node::Facts.indirection.expects(:cache_class=).with(:active_record) Puppet.settings[:storeconfigs] = true end it "should set the Node cache class to :active_record" do - Puppet::Node.expects(:cache_class=).with(:active_record) + Puppet::Node.indirection.expects(:cache_class=).with(:active_record) Puppet.settings[:storeconfigs] = true end @@ -152,9 +152,9 @@ describe "Puppet defaults" do describe "when enabling asynchronous storeconfigs" do before do - Puppet::Resource::Catalog.stubs(:cache_class=) - Puppet::Node::Facts.stubs(:cache_class=) - Puppet::Node.stubs(:cache_class=) + Puppet::Resource::Catalog.indirection.stubs(:cache_class=) + Puppet::Node::Facts.indirection.stubs(:cache_class=) + Puppet::Node.indirection.stubs(:cache_class=) Puppet.features.stubs(:rails?).returns true end @@ -164,26 +164,26 @@ describe "Puppet defaults" do end it "should set the Catalog cache class to :queue" do - Puppet::Resource::Catalog.expects(:cache_class=).with(:queue) + Puppet::Resource::Catalog.indirection.expects(:cache_class=).with(:queue) Puppet.settings[:async_storeconfigs] = true end it "should set the Facts cache class to :active_record" do - Puppet::Node::Facts.expects(:cache_class=).with(:active_record) + Puppet::Node::Facts.indirection.expects(:cache_class=).with(:active_record) Puppet.settings[:storeconfigs] = true end it "should set the Node cache class to :active_record" do - Puppet::Node.expects(:cache_class=).with(:active_record) + Puppet::Node.indirection.expects(:cache_class=).with(:active_record) Puppet.settings[:storeconfigs] = true end end describe "when enabling thin storeconfigs" do before do - Puppet::Resource::Catalog.stubs(:cache_class=) - Puppet::Node::Facts.stubs(:cache_class=) - Puppet::Node.stubs(:cache_class=) + Puppet::Resource::Catalog.indirection.stubs(:cache_class=) + Puppet::Node::Facts.indirection.stubs(:cache_class=) + Puppet::Node.indirection.stubs(:cache_class=) Puppet.features.stubs(:rails?).returns true end diff --git a/spec/integration/file_serving/content_spec.rb b/spec/integration/file_serving/content_spec.rb index 1443b9592..207720d56 100755 --- a/spec/integration/file_serving/content_spec.rb +++ b/spec/integration/file_serving/content_spec.rb @@ -3,7 +3,7 @@ # Created by Luke Kanies on 2007-10-18. # Copyright (c) 2007. All rights reserved. -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') require 'puppet/file_serving/content' require 'shared_behaviours/file_serving' diff --git a/spec/integration/file_serving/fileset_spec.rb b/spec/integration/file_serving/fileset_spec.rb index e5afe8f70..f607aa203 100755 --- a/spec/integration/file_serving/fileset_spec.rb +++ b/spec/integration/file_serving/fileset_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') require 'puppet/file_serving/fileset' diff --git a/spec/integration/file_serving/metadata_spec.rb b/spec/integration/file_serving/metadata_spec.rb index 1e67309e5..627369ff8 100755 --- a/spec/integration/file_serving/metadata_spec.rb +++ b/spec/integration/file_serving/metadata_spec.rb @@ -3,7 +3,7 @@ # Created by Luke Kanies on 2007-10-18. # Copyright (c) 2007. All rights reserved. -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') require 'puppet/file_serving/metadata' require 'shared_behaviours/file_serving' diff --git a/spec/integration/file_serving/terminus_helper_spec.rb b/spec/integration/file_serving/terminus_helper_spec.rb index 5fd47c954..615b24c87 100755 --- a/spec/integration/file_serving/terminus_helper_spec.rb +++ b/spec/integration/file_serving/terminus_helper_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') require 'puppet/file_serving/terminus_helper' diff --git a/spec/integration/indirector/bucket_file/rest_spec.rb b/spec/integration/indirector/bucket_file/rest_spec.rb deleted file mode 100644 index acfc0594b..000000000 --- a/spec/integration/indirector/bucket_file/rest_spec.rb +++ /dev/null @@ -1,77 +0,0 @@ -#!/usr/bin/env ruby - -Dir.chdir(File.dirname(__FILE__)) { (s = lambda { |f| File.exist?(f) ? require(f) : Dir.chdir("..") { s.call(f) } }).call("spec/spec_helper.rb") } - -require 'puppet/file_bucket/file' -require 'puppet/network/server' -require 'puppet/network/http/webrick/rest' - -describe "Filebucket REST Terminus" do - before do - Puppet[:masterport] = 34343 - Puppet[:server] = "localhost" - - # Get a safe temporary file - @tmpfile = Tempfile.new("webrick_integration_testing") - @dir = @tmpfile.path + "_dir" - - Puppet.settings[:confdir] = @dir - Puppet.settings[:vardir] = @dir - Puppet.settings[:group] = Process.gid - Puppet.settings[:server] = "127.0.0.1" - Puppet.settings[:masterport] = "34343" - - Puppet::Util::Cacher.expire - - Puppet[:servertype] = 'webrick' - Puppet[:server] = '127.0.0.1' - Puppet[:certname] = '127.0.0.1' - - # Generate the certificate with a local CA - Puppet::SSL::Host.ca_location = :local - ca = Puppet::SSL::CertificateAuthority.new - ca.generate(Puppet[:certname]) unless Puppet::SSL::Certificate.find(Puppet[:certname]) - ca.generate("foo.madstop.com") unless Puppet::SSL::Certificate.find(Puppet[:certname]) - - @host = Puppet::SSL::Host.new(Puppet[:certname]) - - @params = { :port => 34343, :handlers => [ :file_bucket_file ] } - retries = 0 - begin - @server = Puppet::Network::Server.new(@params) - @server.listen - rescue Errno::EADDRINUSE => e - sleep 0.1 - puts "Port 34343 is in use; waiting for it to be free" if retries == 50 - retry if (retries += 1) < 100 - pending "Can't run too many simultaneous tests" - end - - @old_terminus = Puppet::FileBucket::File.indirection.terminus_class - Puppet::FileBucket::File.terminus_class = :rest - - # LAK:NOTE We need to have a fake model here so that our indirected methods get - # passed through REST; otherwise we'd be stubbing 'find', which would cause an immediate - # return. - @file_bucket_file = stub_everything 'file_bucket_file' - @mock_model = stub('faked model', :name => "file_bucket_file", :convert_from => @file_bucket_file) - Puppet::Indirector::Request.any_instance.stubs(:model).returns(@mock_model) - - Puppet::Network::HTTP::WEBrickREST.any_instance.stubs(:check_authorization) - end - - after do - Puppet::Network::HttpPool.expire - Puppet::SSL::Host.ca_location = :none - Puppet.settings.clear - @server.unlisten - Puppet::FileBucket::File.terminus_class = @old_terminus - end - - it "should be able save a file to the remote filebucket" do - @file_bucket_file.expects(:save) - - file_bucket_file = Puppet::FileBucket::File.new("pouet") - file_bucket_file.save - end -end diff --git a/spec/integration/indirector/catalog/compiler_spec.rb b/spec/integration/indirector/catalog/compiler_spec.rb index ede502e3c..dafa1af7c 100755 --- a/spec/integration/indirector/catalog/compiler_spec.rb +++ b/spec/integration/indirector/catalog/compiler_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -Dir.chdir(File.dirname(__FILE__)) { (s = lambda { |f| File.exist?(f) ? require(f) : Dir.chdir("..") { s.call(f) } }).call("spec/spec_helper.rb") } +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') require 'puppet/resource/catalog' @@ -10,11 +10,8 @@ describe Puppet::Resource::Catalog::Compiler do before do Facter.stubs(:value).returns "something" @catalog = Puppet::Resource::Catalog.new - - @one = Puppet::Resource.new(:file, "/one") - - @two = Puppet::Resource.new(:file, "/two") - @catalog.add_resource(@one, @two) + @catalog.add_resource(@one = Puppet::Resource.new(:file, "/one")) + @catalog.add_resource(@two = Puppet::Resource.new(:file, "/two")) end after { Puppet.settings.clear } @@ -42,7 +39,7 @@ describe Puppet::Resource::Catalog::Compiler do Puppet::Resource::Catalog.indirection.terminus.stubs(:node_from_request) Puppet::Resource::Catalog.indirection.terminus.stubs(:compile).returns(@catalog) - Puppet::Resource::Catalog.find(request).resource_refs.should == [ @two.ref ] + Puppet::Resource::Catalog.indirection.find(request).resource_refs.should == [ @two.ref ] end it "should not filter out exported resources when finding a catalog" do @@ -52,7 +49,7 @@ describe Puppet::Resource::Catalog::Compiler do Puppet::Resource::Catalog.indirection.terminus.stubs(:node_from_request) Puppet::Resource::Catalog.indirection.terminus.stubs(:compile).returns(@catalog) - Puppet::Resource::Catalog.find(request).resource_refs.sort.should == [ @one.ref, @two.ref ] + Puppet::Resource::Catalog.indirection.find(request).resource_refs.sort.should == [ @one.ref, @two.ref ] end it "should filter out virtual exported resources when finding a catalog" do @@ -63,6 +60,6 @@ describe Puppet::Resource::Catalog::Compiler do Puppet::Resource::Catalog.indirection.terminus.stubs(:node_from_request) Puppet::Resource::Catalog.indirection.terminus.stubs(:compile).returns(@catalog) - Puppet::Resource::Catalog.find(request).resource_refs.should == [ @two.ref ] + Puppet::Resource::Catalog.indirection.find(request).resource_refs.should == [ @two.ref ] end end diff --git a/spec/integration/indirector/catalog/queue_spec.rb b/spec/integration/indirector/catalog/queue_spec.rb index 4581e3062..237e489f9 100755 --- a/spec/integration/indirector/catalog/queue_spec.rb +++ b/spec/integration/indirector/catalog/queue_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -Dir.chdir(File.dirname(__FILE__)) { (s = lambda { |f| File.exist?(f) ? require(f) : Dir.chdir("..") { s.call(f) } }).call("spec/spec_helper.rb") } +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') require 'puppet/resource/catalog' diff --git a/spec/integration/indirector/certificate/rest_spec.rb b/spec/integration/indirector/certificate/rest_spec.rb deleted file mode 100755 index 58aa96c48..000000000 --- a/spec/integration/indirector/certificate/rest_spec.rb +++ /dev/null @@ -1,69 +0,0 @@ -#!/usr/bin/env ruby - -Dir.chdir(File.dirname(__FILE__)) { (s = lambda { |f| File.exist?(f) ? require(f) : Dir.chdir("..") { s.call(f) } }).call("spec/spec_helper.rb") } - -require 'puppet/ssl/certificate' -require 'puppet/network/server' -require 'puppet/network/http/webrick/rest' - -describe "Certificate REST Terminus" do - before do - Puppet[:masterport] = 34343 - Puppet[:server] = "localhost" - - # Get a safe temporary file - @tmpfile = Tempfile.new("webrick_integration_testing") - @dir = @tmpfile.path + "_dir" - - Puppet.settings[:confdir] = @dir - Puppet.settings[:vardir] = @dir - Puppet.settings[:group] = Process.gid - Puppet.settings[:server] = "127.0.0.1" - Puppet.settings[:masterport] = "34343" - - Puppet::Util::Cacher.expire - - Puppet[:servertype] = 'webrick' - Puppet[:server] = '127.0.0.1' - Puppet[:certname] = '127.0.0.1' - - # Generate the certificate with a local CA - Puppet::SSL::Host.ca_location = :local - ca = Puppet::SSL::CertificateAuthority.new - ca.generate(Puppet[:certname]) unless Puppet::SSL::Certificate.find(Puppet[:certname]) - ca.generate("foo.madstop.com") unless Puppet::SSL::Certificate.find(Puppet[:certname]) - - @host = Puppet::SSL::Host.new(Puppet[:certname]) - - @params = { :port => 34343, :handlers => [ :certificate ] } - @server = Puppet::Network::Server.new(@params) - @server.listen - - # Then switch to a remote CA, so that we go through REST. - Puppet::SSL::Host.ca_location = :remote - - # LAK:NOTE We need to have a fake model here so that our indirected methods get - # passed through REST; otherwise we'd be stubbing 'find', which would cause an immediate - # return. - @mock_model = stub('faked model', :name => "certificate") - Puppet::Indirector::Request.any_instance.stubs(:model).returns(@mock_model) - - Puppet::Network::HTTP::WEBrickREST.any_instance.stubs(:check_authorization).returns(true) - end - - after do - Puppet::Network::HttpPool.expire - Puppet::SSL::Host.ca_location = :none - Puppet.settings.clear - @server.unlisten - end - - it "should be able to retrieve a remote certificate" do - @mock_model.expects(:find).returns @host.certificate - result = Puppet::SSL::Certificate.find('bar') - - # There's no good '==' method on certs. - result.content.to_s.should == @host.certificate.content.to_s - result.name.should == "bar" - end -end diff --git a/spec/integration/indirector/certificate_request/rest_spec.rb b/spec/integration/indirector/certificate_request/rest_spec.rb deleted file mode 100755 index c718b78ab..000000000 --- a/spec/integration/indirector/certificate_request/rest_spec.rb +++ /dev/null @@ -1,89 +0,0 @@ -#!/usr/bin/env ruby - -Dir.chdir(File.dirname(__FILE__)) { (s = lambda { |f| File.exist?(f) ? require(f) : Dir.chdir("..") { s.call(f) } }).call("spec/spec_helper.rb") } - -require 'puppet/ssl/certificate_request' -require 'puppet/network/server' -require 'puppet/network/http/webrick/rest' - -describe "Certificate Request REST Terminus" do - before do - Puppet::Util::Cacher.expire - - Puppet[:masterport] = 34343 - Puppet[:server] = "localhost" - - # Get a safe temporary file - @tmpfile = Tempfile.new("webrick_integration_testing") - @dir = @tmpfile.path + "_dir" - - Puppet.settings[:confdir] = @dir - Puppet.settings[:vardir] = @dir - Puppet.settings[:group] = Process.gid - Puppet.settings[:server] = "127.0.0.1" - Puppet.settings[:masterport] = "34343" - - Puppet[:servertype] = 'webrick' - Puppet[:server] = '127.0.0.1' - Puppet[:certname] = '127.0.0.1' - - # Generate the certificate with a local CA - Puppet::SSL::Host.ca_location = :local - ca = Puppet::SSL::CertificateAuthority.new - ca.generate(Puppet[:certname]) unless Puppet::SSL::Certificate.find(Puppet[:certname]) - - # Create the CSR and write it to disk - @host = Puppet::SSL::Host.new("foo.madstop.com") - @host.generate_certificate_request - - # Now remove the cached csr - Puppet::SSL::Host.ca_location = :none - Puppet::SSL::Host.destroy("foo.madstop.com") - - @params = { :port => 34343, :handlers => [ :certificate_request ] } - @server = Puppet::Network::Server.new(@params) - @server.listen - - # Then switch to a remote CA, so that we go through REST. - Puppet::SSL::Host.ca_location = :remote - - # LAK:NOTE We need to have a fake model here so that our indirected methods get - # passed through REST; otherwise we'd be stubbing 'find', which would cause an immediate - # return. - @mock_model = stub('faked model', :name => "certificate request") - Puppet::Indirector::Request.any_instance.stubs(:model).returns(@mock_model) - - Puppet::Network::HTTP::WEBrickREST.any_instance.stubs(:check_authorization).returns(true) - end - - after do - Puppet::Network::HttpPool.expire - Puppet::SSL::Host.ca_location = :none - Puppet.settings.clear - @server.unlisten - end - - it "should be able to save a certificate request to the CA" do - key = Puppet::SSL::Key.new("bar.madstop.com") - key.generate - - csr = Puppet::SSL::CertificateRequest.new("bar.madstop.com") - csr.generate(key.content) - - server_csr = mock 'csr' - server_csr.expects(:save) - @mock_model.expects(:convert_from).with("s", csr.content.to_s).returns server_csr - - csr.save - end - - it "should be able to retrieve a remote certificate request" do - # We're finding the cached value :/ - @mock_model.expects(:find).returns @host.certificate_request - result = Puppet::SSL::CertificateRequest.find('foo.madstop.com') - - # There's no good '==' method on certs. - result.content.to_s.should == @host.certificate_request.content.to_s - result.name.should == @host.certificate_request.name - end -end diff --git a/spec/integration/indirector/certificate_revocation_list/rest_spec.rb b/spec/integration/indirector/certificate_revocation_list/rest_spec.rb deleted file mode 100755 index 74e3f90a0..000000000 --- a/spec/integration/indirector/certificate_revocation_list/rest_spec.rb +++ /dev/null @@ -1,85 +0,0 @@ -#!/usr/bin/env ruby - -Dir.chdir(File.dirname(__FILE__)) { (s = lambda { |f| File.exist?(f) ? require(f) : Dir.chdir("..") { s.call(f) } }).call("spec/spec_helper.rb") } - -require 'puppet/ssl/certificate' -require 'puppet/network/server' -require 'puppet/network/http/webrick/rest' - -describe "Certificate REST Terminus" do - before do - Puppet[:masterport] = 34343 - Puppet[:server] = "localhost" - - # Get a safe temporary file - @tmpfile = Tempfile.new("webrick_integration_testing") - @dir = @tmpfile.path + "_dir" - - Puppet.settings[:confdir] = @dir - Puppet.settings[:vardir] = @dir - Puppet.settings[:group] = Process.gid - Puppet.settings[:server] = "127.0.0.1" - Puppet.settings[:masterport] = "34343" - - Puppet::Util::Cacher.expire - - Puppet[:servertype] = 'webrick' - Puppet[:server] = '127.0.0.1' - Puppet[:certname] = '127.0.0.1' - - # Generate the certificate with a local CA - Puppet::SSL::Host.ca_location = :local - ca = Puppet::SSL::CertificateAuthority.new - ca.generate(Puppet[:certname]) unless Puppet::SSL::Certificate.find(Puppet[:certname]) - - @params = { :port => 34343, :handlers => [ :certificate_revocation_list ] } - retries = 0 - begin - @server = Puppet::Network::Server.new(@params) - @server.listen - rescue Errno::EADDRINUSE => e - sleep 0.1 - puts "Port 34343 is in use; waiting for it to be free" if retries == 50 - retry if (retries += 1) < 100 - pending "Can't run too many simultaneous tests" - end - - # And make sure we've generated the CRL - @crl = ca.crl - - # Now remove the cached crl - Puppet::SSL::Host.ca_location = :none - Puppet::SSL::CertificateRevocationList.destroy(Puppet::SSL::CA_NAME) - - # This is necessary so that we create the SSL store before we start - # using REST. This is necessary to prevent an infinite loop, - # which only occurs during testing. - Puppet::Network::HttpPool.ssl_host.ssl_store - - # Then switch to a remote CA, so that we go through REST. - Puppet::SSL::Host.ca_location = :remote - - # LAK:NOTE We need to have a fake model here so that our indirected methods get - # passed through REST; otherwise we'd be stubbing 'find', which would cause an immediate - # return. - @mock_model = stub('faked model', :name => "certificate") - Puppet::Indirector::Request.any_instance.stubs(:model).returns(@mock_model) - - Puppet::Network::HTTP::WEBrickREST.any_instance.stubs(:check_authorization).returns(true) - end - - after do - Puppet::Network::HttpPool.expire - Puppet::SSL::Host.ca_location = :none - Puppet.settings.clear - @server.unlisten - end - - it "should be able to retrieve a remote CRL" do - @mock_model.expects(:find).returns @crl - result = Puppet::SSL::CertificateRevocationList.find('bar') - - # There's no good '==' method on certs. - result.content.to_s.should == @crl.content.to_s - end -end diff --git a/spec/integration/indirector/direct_file_server_spec.rb b/spec/integration/indirector/direct_file_server_spec.rb index 24a55a34f..627733b09 100755 --- a/spec/integration/indirector/direct_file_server_spec.rb +++ b/spec/integration/indirector/direct_file_server_spec.rb @@ -3,7 +3,7 @@ # Created by Luke Kanies on 2007-10-19. # Copyright (c) 2007. All rights reserved. -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') require 'puppet/indirector/file_content/file' diff --git a/spec/integration/indirector/file_content/file_server_spec.rb b/spec/integration/indirector/file_content/file_server_spec.rb index 5de7f1de0..9268ef067 100755 --- a/spec/integration/indirector/file_content/file_server_spec.rb +++ b/spec/integration/indirector/file_content/file_server_spec.rb @@ -3,7 +3,7 @@ # Created by Luke Kanies on 2007-10-18. # Copyright (c) 2007. All rights reserved. -require File.dirname(__FILE__) + '/../../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') require 'puppet/indirector/file_content/file_server' require 'shared_behaviours/file_server_terminus' @@ -34,7 +34,7 @@ describe Puppet::Indirector::FileContent::FileServer, " when finding files" do env = Puppet::Node::Environment.new("foo") env.stubs(:modulepath).returns [path] - result = Puppet::FileServing::Content.search("plugins", :environment => "foo", :recurse => true) + result = Puppet::FileServing::Content.indirection.search("plugins", :environment => "foo", :recurse => true) result.should_not be_nil result.length.should == 2 @@ -54,7 +54,7 @@ describe Puppet::Indirector::FileContent::FileServer, " when finding files" do Puppet.settings[:modulepath] = path - result = Puppet::FileServing::Content.find("modules/mymod/myfile") + result = Puppet::FileServing::Content.indirection.find("modules/mymod/myfile") result.should_not be_nil result.should be_instance_of(Puppet::FileServing::Content) @@ -85,7 +85,7 @@ describe Puppet::Indirector::FileContent::FileServer, " when finding files" do path = File.join(@path, "myfile") - result = Puppet::FileServing::Content.find("one/myfile", :environment => "foo", :node => "mynode") + result = Puppet::FileServing::Content.indirection.find("one/myfile", :environment => "foo", :node => "mynode") result.should_not be_nil result.should be_instance_of(Puppet::FileServing::Content) diff --git a/spec/integration/indirector/file_metadata/file_server_spec.rb b/spec/integration/indirector/file_metadata/file_server_spec.rb index d60012192..069e7af08 100755 --- a/spec/integration/indirector/file_metadata/file_server_spec.rb +++ b/spec/integration/indirector/file_metadata/file_server_spec.rb @@ -3,7 +3,7 @@ # Created by Luke Kanies on 2007-10-18. # Copyright (c) 2007. All rights reserved. -require File.dirname(__FILE__) + '/../../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') require 'puppet/indirector/file_metadata/file_server' require 'shared_behaviours/file_server_terminus' diff --git a/spec/integration/indirector/node/ldap_spec.rb b/spec/integration/indirector/node/ldap_spec.rb index e4c0867ad..3da6d0e73 100755 --- a/spec/integration/indirector/node/ldap_spec.rb +++ b/spec/integration/indirector/node/ldap_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') require 'puppet/indirector/node/ldap' @@ -10,6 +10,6 @@ describe Puppet::Node::Ldap do Puppet::Node.indirection.stubs(:terminus).returns ldap ldap.expects(:ldapsearch).with("(&(objectclass=puppetClient)(puppetclass=foo))") - Puppet::Node.search "eh", :class => "foo" + Puppet::Node.indirection.search "eh", :class => "foo" end end diff --git a/spec/integration/indirector/report/rest_spec.rb b/spec/integration/indirector/report/rest_spec.rb deleted file mode 100644 index 5b5b2ddd8..000000000 --- a/spec/integration/indirector/report/rest_spec.rb +++ /dev/null @@ -1,93 +0,0 @@ -#!/usr/bin/env ruby - -Dir.chdir(File.dirname(__FILE__)) { (s = lambda { |f| File.exist?(f) ? require(f) : Dir.chdir("..") { s.call(f) } }).call("spec/spec_helper.rb") } - -require 'puppet/transaction/report' -require 'puppet/network/server' -require 'puppet/network/http/webrick/rest' - -describe "Report REST Terminus" do - before do - Puppet[:masterport] = 34343 - Puppet[:server] = "localhost" - - # Get a safe temporary file - @tmpfile = Tempfile.new("webrick_integration_testing") - @dir = @tmpfile.path + "_dir" - - Puppet.settings[:confdir] = @dir - Puppet.settings[:vardir] = @dir - Puppet.settings[:group] = Process.gid - Puppet.settings[:server] = "127.0.0.1" - Puppet.settings[:masterport] = "34343" - - Puppet::Util::Cacher.expire - - Puppet[:servertype] = 'webrick' - Puppet[:server] = '127.0.0.1' - Puppet[:certname] = '127.0.0.1' - - # Generate the certificate with a local CA - Puppet::SSL::Host.ca_location = :local - ca = Puppet::SSL::CertificateAuthority.new - ca.generate(Puppet[:certname]) unless Puppet::SSL::Certificate.find(Puppet[:certname]) - ca.generate("foo.madstop.com") unless Puppet::SSL::Certificate.find(Puppet[:certname]) - - @host = Puppet::SSL::Host.new(Puppet[:certname]) - - @params = { :port => 34343, :handlers => [ :report ] } - @server = Puppet::Network::Server.new(@params) - @server.listen - - # Let's use REST for our reports :-) - @old_terminus = Puppet::Transaction::Report.indirection.terminus_class - Puppet::Transaction::Report.terminus_class = :rest - - # LAK:NOTE We need to have a fake model here so that our indirected methods get - # passed through REST; otherwise we'd be stubbing 'save', which would cause an immediate - # return. - @report = stub_everything 'report' - @mock_model = stub_everything 'faked model', :name => "report", :convert_from => @report - Puppet::Indirector::Request.any_instance.stubs(:model).returns(@mock_model) - - Puppet::Network::HTTP::WEBrickREST.any_instance.stubs(:check_authorization) - end - - after do - Puppet::Network::HttpPool.expire - Puppet::SSL::Host.ca_location = :none - Puppet.settings.clear - @server.unlisten - Puppet::Transaction::Report.terminus_class = @old_terminus - end - - it "should be able to send a report to the server" do - @report.expects(:save) - - report = Puppet::Transaction::Report.new("apply") - - resourcemetrics = { - "total" => 12, - "out_of_sync" => 20, - "applied" => 45, - "skipped" => 1, - "restarted" => 23, - "failed_restarts" => 1, - "scheduled" => 10 - } - report.add_metric(:resources, resourcemetrics) - - timemetrics = { - "resource1" => 10, - "resource2" => 50, - "resource3" => 40, - "resource4" => 20, - } - report.add_metric(:times, timemetrics) - - - report.add_metric(:changes, "total" => 20) - - report.save - end -end diff --git a/spec/integration/network/client_spec.rb b/spec/integration/network/client_spec.rb index 4bf3ad82b..07a491b1b 100755 --- a/spec/integration/network/client_spec.rb +++ b/spec/integration/network/client_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') require 'puppet/network/client' diff --git a/spec/integration/network/formats_spec.rb b/spec/integration/network/formats_spec.rb index d141abf00..8eb963e19 100755 --- a/spec/integration/network/formats_spec.rb +++ b/spec/integration/network/formats_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') require 'puppet/network/formats' diff --git a/spec/integration/network/handler_spec.rb b/spec/integration/network/handler_spec.rb index 021f1cedb..a3095c125 100755 --- a/spec/integration/network/handler_spec.rb +++ b/spec/integration/network/handler_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') require 'puppet/network/client' diff --git a/spec/integration/network/server/mongrel_spec.rb b/spec/integration/network/server/mongrel_spec.rb index c2815b565..aeaaad6ae 100755 --- a/spec/integration/network/server/mongrel_spec.rb +++ b/spec/integration/network/server/mongrel_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') require 'puppet/network/server' require 'socket' diff --git a/spec/integration/network/server/webrick_spec.rb b/spec/integration/network/server/webrick_spec.rb index 2b14dfb37..0e1bb4580 100755 --- a/spec/integration/network/server/webrick_spec.rb +++ b/spec/integration/network/server/webrick_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') require 'puppet/network/server' require 'puppet/ssl/certificate_authority' require 'socket' @@ -23,7 +23,7 @@ describe Puppet::Network::Server do Puppet::SSL::Host.ca_location = :local ca = Puppet::SSL::CertificateAuthority.new - ca.generate(Puppet[:certname]) unless Puppet::SSL::Certificate.find(Puppet[:certname]) + ca.generate(Puppet[:certname]) unless Puppet::SSL::Certificate.indirection.find(Puppet[:certname]) end after do @@ -32,6 +32,7 @@ describe Puppet::Network::Server do system("rm -rf #{@dir}") + Puppet::SSL::Host.ca_location = :none Puppet::Util::Cacher.expire end diff --git a/spec/integration/node/environment_spec.rb b/spec/integration/node/environment_spec.rb index 8c5153749..abf0108fa 100755 --- a/spec/integration/node/environment_spec.rb +++ b/spec/integration/node/environment_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') require 'puppet_spec/files' diff --git a/spec/integration/node/facts_spec.rb b/spec/integration/node/facts_spec.rb index 4cc2f4c1f..ee956a6b1 100755 --- a/spec/integration/node/facts_spec.rb +++ b/spec/integration/node/facts_spec.rb @@ -3,7 +3,7 @@ # Created by Luke Kanies on 2008-4-8. # Copyright (c) 2008. All rights reserved. -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') describe Puppet::Node::Facts do describe "when using the indirector" do @@ -16,10 +16,10 @@ describe Puppet::Node::Facts do terminus = Puppet::Node::Facts.indirection.terminus(:yaml) terminus.stubs :save - Puppet::Node.expects(:expire).with("me") + Puppet::Node.indirection.expects(:expire).with("me") facts = Puppet::Node::Facts.new("me") - facts.save + Puppet::Node::Facts.indirection.save(facts) end it "should be able to delegate to the :yaml terminus" do @@ -31,7 +31,7 @@ describe Puppet::Node::Facts do terminus.expects(:path).with("me").returns "/my/yaml/file" FileTest.expects(:exist?).with("/my/yaml/file").returns false - Puppet::Node::Facts.find("me").should be_nil + Puppet::Node::Facts.indirection.find("me").should be_nil end it "should be able to delegate to the :facter terminus" do @@ -41,7 +41,7 @@ describe Puppet::Node::Facts do facts = Puppet::Node::Facts.new("me") Puppet::Node::Facts.expects(:new).with("me", "facter_hash").returns facts - Puppet::Node::Facts.find("me").should equal(facts) + Puppet::Node::Facts.indirection.find("me").should equal(facts) end end end diff --git a/spec/integration/node_spec.rb b/spec/integration/node_spec.rb index c635e7f32..4c8a2c2b1 100755 --- a/spec/integration/node_spec.rb +++ b/spec/integration/node_spec.rb @@ -3,7 +3,7 @@ # Created by Luke Kanies on 2007-9-23. # Copyright (c) 2007. All rights reserved. -require File.dirname(__FILE__) + '/../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../spec_helper') require 'puppet/node' @@ -24,7 +24,7 @@ describe Puppet::Node do terminus.expects(:translate).with(@name, "myresults").returns "translated_results" terminus.expects(:create_node).with(@name, "translated_results").returns @node - Puppet::Node.find(@name).should equal(@node) + Puppet::Node.indirection.find(@name).should equal(@node) end it "should be able to use the yaml terminus" do @@ -36,7 +36,7 @@ describe Puppet::Node do terminus.expects(:path).with(@name).returns "/my/yaml/file" FileTest.expects(:exist?).with("/my/yaml/file").returns false - Puppet::Node.find(@name).should be_nil + Puppet::Node.indirection.find(@name).should be_nil end it "should have an ldap terminus" do @@ -51,7 +51,7 @@ describe Puppet::Node do Puppet::Node.expects(:new).with(@name).returns @node - Puppet::Node.find(@name).should equal(@node) + Puppet::Node.indirection.find(@name).should equal(@node) end describe "and using the memory terminus" do @@ -64,29 +64,29 @@ describe Puppet::Node do end it "should find no nodes by default" do - Puppet::Node.find(@name).should be_nil + Puppet::Node.indirection.find(@name).should be_nil end it "should be able to find nodes that were previously saved" do - @node.save - Puppet::Node.find(@name).should equal(@node) + Puppet::Node.indirection.save(@node) + Puppet::Node.indirection.find(@name).should equal(@node) end it "should replace existing saved nodes when a new node with the same name is saved" do - @node.save + Puppet::Node.indirection.save(@node) two = Puppet::Node.new(@name) - two.save - Puppet::Node.find(@name).should equal(two) + Puppet::Node.indirection.save(two) + Puppet::Node.indirection.find(@name).should equal(two) end it "should be able to remove previously saved nodes" do - @node.save - Puppet::Node.destroy(@node.name) - Puppet::Node.find(@name).should be_nil + Puppet::Node.indirection.save(@node) + Puppet::Node.indirection.destroy(@node.name) + Puppet::Node.indirection.find(@name).should be_nil end it "should fail when asked to destroy a node that does not exist" do - proc { Puppet::Node.destroy(@node) }.should raise_error(ArgumentError) + proc { Puppet::Node.indirection.destroy(@node) }.should raise_error(ArgumentError) end end end diff --git a/spec/integration/parser/collector_spec.rb b/spec/integration/parser/collector_spec.rb index 73273c909..c72e605cf 100755 --- a/spec/integration/parser/collector_spec.rb +++ b/spec/integration/parser/collector_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') require 'puppet/parser/collector' @@ -17,7 +17,7 @@ describe Puppet::Parser::Collector do def query(text) code = "File <| #{text} |>" parser = Puppet::Parser::Parser.new(@scope.compiler) - parser.parse(code).hostclass("").code[0].query + return parser.parse(code).code[0].query end {true => [%{title == "/tmp/testing"}, %{(title == "/tmp/testing")}, %{group == bin}, diff --git a/spec/integration/parser/compiler_spec.rb b/spec/integration/parser/compiler_spec.rb index f80221e3d..097e8b03a 100755 --- a/spec/integration/parser/compiler_spec.rb +++ b/spec/integration/parser/compiler_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') describe Puppet::Parser::Compiler do before :each do @@ -90,4 +90,45 @@ describe Puppet::Parser::Compiler do notify_resource[:require].title.should == "Experiment::Baz" end end + + it "should recompute the version after input files are re-parsed" do + Puppet[:code] = 'class foo { }' + Time.stubs(:now).returns(1) + node = Puppet::Node.new('mynode') + Puppet::Parser::Compiler.compile(node).version.should == 1 + Time.stubs(:now).returns(2) + Puppet::Parser::Compiler.compile(node).version.should == 1 # no change because files didn't change + Puppet::Resource::TypeCollection.any_instance.stubs(:stale?).returns(true).then.returns(false) # pretend change + Puppet::Parser::Compiler.compile(node).version.should == 2 + end + + ['class', 'define', 'node'].each do |thing| + it "should not allow #{thing} inside evaluated conditional constructs" do + Puppet[:code] = <<-PP + if true { + #{thing} foo { + } + notify { decoy: } + } + PP + + begin + Puppet::Parser::Compiler.compile(Puppet::Node.new("mynode")) + raise "compilation should have raised Puppet::Error" + rescue Puppet::Error => e + e.message.should =~ /at line 2/ + end + end + end + + it "should not allow classes inside unevaluated conditional constructs" do + Puppet[:code] = <<-PP + if false { + class foo { + } + } + PP + + lambda { Puppet::Parser::Compiler.compile(Puppet::Node.new("mynode")) }.should raise_error(Puppet::Error) + end end diff --git a/spec/integration/parser/functions/require_spec.rb b/spec/integration/parser/functions/require_spec.rb index 8b3beefe9..737efcce8 100755 --- a/spec/integration/parser/functions/require_spec.rb +++ b/spec/integration/parser/functions/require_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') describe "The require function" do before :each do diff --git a/spec/integration/parser/functions_spec.rb b/spec/integration/parser/functions_spec.rb index cbfb4ac88..504d1fe5e 100644 --- a/spec/integration/parser/functions_spec.rb +++ b/spec/integration/parser/functions_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') describe Puppet::Parser::Functions do before :each do diff --git a/spec/integration/parser/parser_spec.rb b/spec/integration/parser/parser_spec.rb index 20d87c228..b7dfcc3e0 100755 --- a/spec/integration/parser/parser_spec.rb +++ b/spec/integration/parser/parser_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') describe Puppet::Parser::Parser do module ParseMatcher @@ -11,7 +11,7 @@ describe Puppet::Parser::Parser do end def result_instance - @result.hostclass("").code[0] + @result.code[0] end def matches?(string) @@ -44,7 +44,7 @@ describe Puppet::Parser::Parser do end def result_instance - @result.hostclass("").code[0] + @result.code[0] end def matches?(string) @@ -85,7 +85,9 @@ describe Puppet::Parser::Parser do class test {} """) - ast.hostclass("test").doc.should == "comment\n" + ast.code[0].should be_a(Puppet::Parser::AST::Hostclass) + ast.code[0].name.should == 'test' + ast.code[0].instantiate('')[0].doc.should == "comment\n" end end diff --git a/spec/integration/parser/ruby_manifest_spec.rb b/spec/integration/parser/ruby_manifest_spec.rb index de6f4628c..110898206 100644 --- a/spec/integration/parser/ruby_manifest_spec.rb +++ b/spec/integration/parser/ruby_manifest_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') require 'tempfile' require 'puppet_spec/files' diff --git a/spec/integration/provider/mailalias/aliases_spec.rb b/spec/integration/provider/mailalias/aliases_spec.rb index 1bce13f90..19e430ba1 100755 --- a/spec/integration/provider/mailalias/aliases_spec.rb +++ b/spec/integration/provider/mailalias/aliases_spec.rb @@ -1,24 +1,10 @@ #!/usr/bin/env ruby - -require File.dirname(__FILE__) + '/../../../spec_helper' - -require 'puppettest/support/utils' -require 'puppettest/fileparsing' +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') +require 'shared_behaviours/all_parsedfile_providers' provider_class = Puppet::Type.type(:mailalias).provider(:aliases) describe provider_class do - include PuppetTest::FileParsing - include PuppetTest::Support::Utils - - before :each do - @provider = provider_class - end - - # #1560 - it "should be able to parse the mailalias examples" do - fakedata("data/providers/mailalias/aliases").each { |file| - fakedataparse(file) - } - end + # #1560, in which we corrupt the format of complex mail aliases. + it_should_behave_like "all parsedfile providers", provider_class end diff --git a/spec/integration/provider/package_spec.rb b/spec/integration/provider/package_spec.rb index 472662d6b..cc03c57a7 100755 --- a/spec/integration/provider/package_spec.rb +++ b/spec/integration/provider/package_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -Dir.chdir(File.dirname(__FILE__)) { (s = lambda { |f| File.exist?(f) ? require(f) : Dir.chdir("..") { s.call(f) } }).call("spec/spec_helper.rb") } +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') describe "Package Provider" do Puppet::Type.type(:package).providers.each do |name| diff --git a/spec/integration/provider/service/init_spec.rb b/spec/integration/provider/service/init_spec.rb index 2e2505bd4..c74ce29fe 100755 --- a/spec/integration/provider/service/init_spec.rb +++ b/spec/integration/provider/service/init_spec.rb @@ -1,7 +1,6 @@ #!/usr/bin/env ruby -# Find and load the spec file. -Dir.chdir(File.dirname(__FILE__)) { (s = lambda { |f| File.exist?(f) ? require(f) : Dir.chdir("..") { s.call(f) } }).call("spec/spec_helper.rb") } +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') provider = Puppet::Type.type(:service).provider(:init) diff --git a/spec/integration/reference/providers_spec.rb b/spec/integration/reference/providers_spec.rb index c2b1e17c5..d6e19cb59 100755 --- a/spec/integration/reference/providers_spec.rb +++ b/spec/integration/reference/providers_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -Dir.chdir(File.dirname(__FILE__)) { (s = lambda { |f| File.exist?(f) ? require(f) : Dir.chdir("..") { s.call(f) } }).call("spec/spec_helper.rb") } +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') require 'puppet/util/reference' diff --git a/spec/integration/reports_spec.rb b/spec/integration/reports_spec.rb index 40e5284e1..a721d75d8 100755 --- a/spec/integration/reports_spec.rb +++ b/spec/integration/reports_spec.rb @@ -3,7 +3,7 @@ # Created by Luke Kanies on 2007-10-12. # Copyright (c) 2007. All rights reserved. -require File.dirname(__FILE__) + '/../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../spec_helper') require 'puppet/reports' diff --git a/spec/integration/resource/catalog_spec.rb b/spec/integration/resource/catalog_spec.rb index da2b70409..21162655e 100755 --- a/spec/integration/resource/catalog_spec.rb +++ b/spec/integration/resource/catalog_spec.rb @@ -3,7 +3,7 @@ # Created by Luke Kanies on 2007-4-8. # Copyright (c) 2008. All rights reserved. -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') describe Puppet::Resource::Catalog do describe "when pson is available", :if => Puppet.features.pson? do @@ -29,7 +29,7 @@ describe Puppet::Resource::Catalog do terminus.expects(:path).with("me").returns "/my/yaml/file" FileTest.expects(:exist?).with("/my/yaml/file").returns false - Puppet::Resource::Catalog.find("me").should be_nil + Puppet::Resource::Catalog.indirection.find("me").should be_nil end it "should be able to delegate to the :compiler terminus" do @@ -41,10 +41,10 @@ describe Puppet::Resource::Catalog do node = mock 'node' node.stub_everything - Puppet::Node.expects(:find).returns(node) + Puppet::Node.indirection.expects(:find).returns(node) compiler.expects(:compile).with(node).returns nil - Puppet::Resource::Catalog.find("me").should be_nil + Puppet::Resource::Catalog.indirection.find("me").should be_nil end it "should pass provided node information directly to the terminus" do @@ -54,7 +54,7 @@ describe Puppet::Resource::Catalog do node = mock 'node' terminus.expects(:find).with { |request| request.options[:use_node] == node } - Puppet::Resource::Catalog.find("me", :use_node => node) + Puppet::Resource::Catalog.indirection.find("me", :use_node => node) end end end diff --git a/spec/integration/resource/type_collection_spec.rb b/spec/integration/resource/type_collection_spec.rb index 318dd4dd7..f6ba9c7af 100755 --- a/spec/integration/resource/type_collection_spec.rb +++ b/spec/integration/resource/type_collection_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') require 'puppet_spec/files' require 'puppet/resource/type_collection' diff --git a/spec/integration/ssl/certificate_authority_spec.rb b/spec/integration/ssl/certificate_authority_spec.rb index 67ff6f215..17b56ea98 100755 --- a/spec/integration/ssl/certificate_authority_spec.rb +++ b/spec/integration/ssl/certificate_authority_spec.rb @@ -3,7 +3,7 @@ # Created by Luke Kanies on 2008-4-17. # Copyright (c) 2008. All rights reserved. -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') require 'puppet/ssl/certificate_authority' require 'tempfile' @@ -47,7 +47,7 @@ describe Puppet::SSL::CertificateAuthority do it "should be able to generate a new host certificate" do @ca.generate("newhost") - Puppet::SSL::Certificate.find("newhost").should be_instance_of(Puppet::SSL::Certificate) + Puppet::SSL::Certificate.indirection.find("newhost").should be_instance_of(Puppet::SSL::Certificate) end it "should be able to revoke a host certificate" do @@ -94,7 +94,7 @@ describe Puppet::SSL::CertificateAuthority do it "should save the signed certificate" do @ca.sign("luke.madstop.com") - Puppet::SSL::Certificate.find("luke.madstop.com").should be_instance_of(Puppet::SSL::Certificate) + Puppet::SSL::Certificate.indirection.find("luke.madstop.com").should be_instance_of(Puppet::SSL::Certificate) end it "should be able to sign multiple certificates" do @@ -107,15 +107,15 @@ describe Puppet::SSL::CertificateAuthority do @ca.sign("luke.madstop.com") @ca.sign("other.madstop.com") - Puppet::SSL::Certificate.find("other.madstop.com").should be_instance_of(Puppet::SSL::Certificate) - Puppet::SSL::Certificate.find("luke.madstop.com").should be_instance_of(Puppet::SSL::Certificate) + Puppet::SSL::Certificate.indirection.find("other.madstop.com").should be_instance_of(Puppet::SSL::Certificate) + Puppet::SSL::Certificate.indirection.find("luke.madstop.com").should be_instance_of(Puppet::SSL::Certificate) end it "should save the signed certificate to the :signeddir" do @ca.sign("luke.madstop.com") client_cert = File.join(Puppet[:signeddir], "luke.madstop.com.pem") - File.read(client_cert).should == Puppet::SSL::Certificate.find("luke.madstop.com").content.to_s + File.read(client_cert).should == Puppet::SSL::Certificate.indirection.find("luke.madstop.com").content.to_s end it "should save valid certificates" do diff --git a/spec/integration/ssl/certificate_request_spec.rb b/spec/integration/ssl/certificate_request_spec.rb index 8426b9dc5..f1040055b 100755 --- a/spec/integration/ssl/certificate_request_spec.rb +++ b/spec/integration/ssl/certificate_request_spec.rb @@ -3,7 +3,7 @@ # Created by Luke Kanies on 2008-4-17. # Copyright (c) 2008. All rights reserved. -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') require 'puppet/ssl/certificate_request' require 'tempfile' @@ -43,20 +43,20 @@ describe Puppet::SSL::CertificateRequest do end it "should be able to save CSRs" do - @csr.save + Puppet::SSL::CertificateRequest.indirection.save(@csr) end it "should be able to find saved certificate requests via the Indirector" do @csr.generate(@key) - @csr.save + Puppet::SSL::CertificateRequest.indirection.save(@csr) - Puppet::SSL::CertificateRequest.find("luke.madstop.com").should be_instance_of(Puppet::SSL::CertificateRequest) + Puppet::SSL::CertificateRequest.indirection.find("luke.madstop.com").should be_instance_of(Puppet::SSL::CertificateRequest) end it "should save the completely CSR when saving" do @csr.generate(@key) - @csr.save + Puppet::SSL::CertificateRequest.indirection.save(@csr) - Puppet::SSL::CertificateRequest.find("luke.madstop.com").content.to_s.should == @csr.content.to_s + Puppet::SSL::CertificateRequest.indirection.find("luke.madstop.com").content.to_s.should == @csr.content.to_s end end diff --git a/spec/integration/ssl/certificate_revocation_list_spec.rb b/spec/integration/ssl/certificate_revocation_list_spec.rb index 44eee363d..ddf7952f3 100755 --- a/spec/integration/ssl/certificate_revocation_list_spec.rb +++ b/spec/integration/ssl/certificate_revocation_list_spec.rb @@ -3,7 +3,7 @@ # Created by Luke Kanies on 2008-5-5. # Copyright (c) 2008. All rights reserved. -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') require 'puppet/ssl/certificate_revocation_list' require 'tempfile' diff --git a/spec/integration/ssl/host_spec.rb b/spec/integration/ssl/host_spec.rb index 05862dfc4..84160b019 100755 --- a/spec/integration/ssl/host_spec.rb +++ b/spec/integration/ssl/host_spec.rb @@ -3,7 +3,7 @@ # Created by Luke Kanies on 2008-4-17. # Copyright (c) 2008. All rights reserved. -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') require 'puppet/ssl/host' require 'tempfile' @@ -45,7 +45,7 @@ describe Puppet::SSL::Host do it "should save the key such that the Indirector can find it" do @host.generate_key - Puppet::SSL::Key.find(@host.name).content.to_s.should == @host.key.to_s + Puppet::SSL::Key.indirection.find(@host.name).content.to_s.should == @host.key.to_s end it "should save the private key into the :privatekeydir" do @@ -62,7 +62,7 @@ describe Puppet::SSL::Host do it "should save the certificate request such that the Indirector can find it" do @host.generate_certificate_request - Puppet::SSL::CertificateRequest.find(@host.name).content.to_s.should == @host.certificate_request.to_s + Puppet::SSL::CertificateRequest.indirection.find(@host.name).content.to_s.should == @host.certificate_request.to_s end it "should save the private certificate request into the :privatekeydir" do diff --git a/spec/integration/transaction/report_spec.rb b/spec/integration/transaction/report_spec.rb index e7d952eb2..c38f31081 100755 --- a/spec/integration/transaction/report_spec.rb +++ b/spec/integration/transaction/report_spec.rb @@ -3,7 +3,7 @@ # Created by Luke Kanies on 2008-4-8. # Copyright (c) 2008. All rights reserved. -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') describe Puppet::Transaction::Report do describe "when using the indirector" do @@ -23,7 +23,7 @@ describe Puppet::Transaction::Report do terminus.expects(:process).with(report) - report.save + Puppet::Transaction::Report.indirection.save(report) end end end diff --git a/spec/integration/transaction_spec.rb b/spec/integration/transaction_spec.rb index 66a049efe..e608faa27 100755 --- a/spec/integration/transaction_spec.rb +++ b/spec/integration/transaction_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../spec_helper') require 'puppet_spec/files' require 'puppet/transaction' diff --git a/spec/integration/type/file_spec.rb b/spec/integration/type/file_spec.rb index 31f4adee6..513b96e41 100755 --- a/spec/integration/type/file_spec.rb +++ b/spec/integration/type/file_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') require 'puppet_spec/files' @@ -28,7 +28,8 @@ describe Puppet::Type.type(:file) do bucket = Puppet::Type.type(:filebucket).new :path => tmpfile("filebucket"), :name => "mybucket" file = Puppet::Type.type(:file).new :path => tmpfile("bucket_backs"), :backup => "mybucket", :content => "foo" catalog = Puppet::Resource::Catalog.new - catalog.add_resource file, bucket + catalog.add_resource file + catalog.add_resource bucket File.open(file[:path], "w") { |f| f.puts "bar" } @@ -80,7 +81,8 @@ describe Puppet::Type.type(:file) do bucket = Puppet::Type.type(:filebucket).new :path => tmpfile("filebucket"), :name => "mybucket" file = Puppet::Type.type(:file).new :path => link, :target => dest2, :ensure => :link, :backup => "mybucket" catalog = Puppet::Resource::Catalog.new - catalog.add_resource file, bucket + catalog.add_resource file + catalog.add_resource bucket File.open(dest1, "w") { |f| f.puts "whatever" } File.symlink(dest1, link) @@ -113,7 +115,8 @@ describe Puppet::Type.type(:file) do bucket = Puppet::Type.type(:filebucket).new :path => tmpfile("filebucket"), :name => "mybucket" file = Puppet::Type.type(:file).new :path => tmpfile("bucket_backs"), :backup => "mybucket", :content => "foo", :force => true catalog = Puppet::Resource::Catalog.new - catalog.add_resource file, bucket + catalog.add_resource file + catalog.add_resource bucket Dir.mkdir(file[:path]) foofile = File.join(file[:path], "foo") @@ -337,10 +340,10 @@ describe Puppet::Type.type(:file) do it "should have an edge to each resource in the relationship graph" do @catalog.apply do |trans| one = @catalog.resource(:file, File.join(@dest, "one")) - @catalog.relationship_graph.should be_edge(@file, one) + @catalog.relationship_graph.edge?(@file, one).should be two = @catalog.resource(:file, File.join(@dest, "two")) - @catalog.relationship_graph.should be_edge(@file, two) + @catalog.relationship_graph.edge?(@file, two).should be end end end diff --git a/spec/integration/type/package_spec.rb b/spec/integration/type/package_spec.rb index c89c18ba1..8e852f261 100755 --- a/spec/integration/type/package_spec.rb +++ b/spec/integration/type/package_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') describe Puppet::Type.type(:package), "when choosing a default package provider" do before do diff --git a/spec/integration/type/tidy_spec.rb b/spec/integration/type/tidy_spec.rb index 429ba4c57..084ebac6d 100755 --- a/spec/integration/type/tidy_spec.rb +++ b/spec/integration/type/tidy_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') require 'puppet_spec/files' require 'puppet/file_bucket/dipper' diff --git a/spec/integration/type_spec.rb b/spec/integration/type_spec.rb index 957dfe344..62f8fb7d2 100755 --- a/spec/integration/type_spec.rb +++ b/spec/integration/type_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../spec_helper') require 'puppet/type' diff --git a/spec/integration/util/autoload_spec.rb b/spec/integration/util/autoload_spec.rb index 8a5d66232..f9b913502 100755 --- a/spec/integration/util/autoload_spec.rb +++ b/spec/integration/util/autoload_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -Dir.chdir(File.dirname(__FILE__)) { (s = lambda { |f| File.exist?(f) ? require(f) : Dir.chdir("..") { s.call(f) } }).call("spec/spec_helper.rb") } +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') require 'puppet/util/autoload' require 'fileutils' diff --git a/spec/integration/util/feature_spec.rb b/spec/integration/util/feature_spec.rb index f1ada9057..b038cf308 100755 --- a/spec/integration/util/feature_spec.rb +++ b/spec/integration/util/feature_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -Dir.chdir(File.dirname(__FILE__)) { (s = lambda { |f| File.exist?(f) ? require(f) : Dir.chdir("..") { s.call(f) } }).call("spec/spec_helper.rb") } +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') require 'puppet/util/feature' require 'puppet_spec/files' diff --git a/spec/integration/util/file_locking_spec.rb b/spec/integration/util/file_locking_spec.rb index 50613448b..1914fadf7 100755 --- a/spec/integration/util/file_locking_spec.rb +++ b/spec/integration/util/file_locking_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -Dir.chdir(File.dirname(__FILE__)) { (s = lambda { |f| File.exist?(f) ? require(f) : Dir.chdir("..") { s.call(f) } }).call("spec/spec_helper.rb") } +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') require 'puppet/util/file_locking' diff --git a/spec/integration/util/rdoc/parser_spec.rb b/spec/integration/util/rdoc/parser_spec.rb index 7d3b0ec3e..9cb0c9e4a 100755 --- a/spec/integration/util/rdoc/parser_spec.rb +++ b/spec/integration/util/rdoc/parser_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -Dir.chdir(File.dirname(__FILE__)) { (s = lambda { |f| File.exist?(f) ? require(f) : Dir.chdir("..") { s.call(f) } }).call("spec/spec_helper.rb") } +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') require 'puppet/resource/type_collection' require 'puppet/util/rdoc/parser' diff --git a/spec/integration/util/settings_spec.rb b/spec/integration/util/settings_spec.rb index 27acd90ee..d3b5ec594 100755 --- a/spec/integration/util/settings_spec.rb +++ b/spec/integration/util/settings_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') require 'puppet_spec/files' diff --git a/spec/lib/puppet_spec/files.rb b/spec/lib/puppet_spec/files.rb index 52ed903ec..38c51a572 100644 --- a/spec/lib/puppet_spec/files.rb +++ b/spec/lib/puppet_spec/files.rb @@ -3,6 +3,29 @@ require 'tempfile' # A support module for testing files. module PuppetSpec::Files + def self.cleanup + if defined?($tmpfiles) + $tmpfiles.each do |file| + file = File.expand_path(file) + if Puppet.features.posix? and file !~ /^\/tmp/ and file !~ /^\/var\/folders/ + puts "Not deleting tmpfile #{file} outside of /tmp or /var/folders" + next + elsif Puppet.features.microsoft_windows? + tempdir = File.expand_path(File.join(Dir::LOCAL_APPDATA, "Temp")) + if file !~ /^#{tempdir}/ + puts "Not deleting tmpfile #{file} outside of #{tempdir}" + next + end + end + if FileTest.exist?(file) + system("chmod -R 755 '#{file}'") + system("rm -rf '#{file}'") + end + end + $tmpfiles.clear + end + end + def tmpfile(name) source = Tempfile.new(name) path = source.path diff --git a/spec/lib/puppet_spec/fixtures.rb b/spec/lib/puppet_spec/fixtures.rb new file mode 100644 index 000000000..7f6bc2a8f --- /dev/null +++ b/spec/lib/puppet_spec/fixtures.rb @@ -0,0 +1,28 @@ +module PuppetSpec::Fixtures + def fixtures(*rest) + File.join(PuppetSpec::FIXTURE_DIR, *rest) + end + def my_fixture_dir + callers = caller + while line = callers.shift do + next unless found = line.match(%r{/spec/(.*)_spec\.rb:}) + return fixtures(found[1]) + end + fail "sorry, I couldn't work out your path from the caller stack!" + end + def my_fixture(name) + file = File.join(my_fixture_dir, name) + unless File.readable? file then + fail Puppet::DevError, "fixture '#{name}' for #{my_fixture_dir} is not readable" + end + return file + end + def my_fixtures(glob = '*', flags = 0) + files = Dir.glob(File.join(my_fixture_dir, glob), flags) + unless files.length > 0 then + fail Puppet::DevError, "fixture '#{glob}' for #{my_fixture_dir} had no files!" + end + block_given? and files.each do |file| yield file end + files + end +end diff --git a/spec/shared_behaviours/all_parsedfile_providers.rb b/spec/shared_behaviours/all_parsedfile_providers.rb new file mode 100644 index 000000000..9cb199b5f --- /dev/null +++ b/spec/shared_behaviours/all_parsedfile_providers.rb @@ -0,0 +1,21 @@ +shared_examples_for "all parsedfile providers" do |provider, *files| + if files.empty? then + files = my_fixtures + end + + files.flatten.each do |file| + it "should rewrite #{file} reasonably unchanged" do + provider.stubs(:default_target).returns(file) + provider.prefetch + + text = provider.to_file(provider.target_records(file)) + text.gsub!(/^# HEADER.+\n/, '') + + oldlines = File.readlines(file) + newlines = text.chomp.split "\n" + oldlines.zip(newlines).each do |old, new| + new.gsub(/\s+/, '').should == old.chomp.gsub(/\s+/, '') + end + end + end +end diff --git a/spec/shared_behaviours/file_serving.rb b/spec/shared_behaviours/file_serving.rb index 450fff87a..84173448a 100644 --- a/spec/shared_behaviours/file_serving.rb +++ b/spec/shared_behaviours/file_serving.rb @@ -12,7 +12,7 @@ shared_examples_for "Puppet::FileServing::Files" do term = @indirection.terminus(:rest) @indirection.stubs(:terminus).with(:rest).returns term term.expects(:find) - @test_class.find(uri) + @indirection.find(uri) end it "should use the rest terminus when the 'puppet' URI scheme is used, no host name is present, and the process name is not 'puppet' or 'apply'" do @@ -21,7 +21,7 @@ shared_examples_for "Puppet::FileServing::Files" do Puppet.settings.stubs(:value).with(:name).returns("puppetd") Puppet.settings.stubs(:value).with(:modulepath).returns("") @indirection.terminus(:rest).expects(:find) - @test_class.find(uri) + @indirection.find(uri) end it "should use the file_server terminus when the 'puppet' URI scheme is used, no host name is present, and the process name is 'puppet'" do @@ -32,7 +32,7 @@ shared_examples_for "Puppet::FileServing::Files" do Puppet.settings.stubs(:value).with(:fileserverconfig).returns("/whatever") @indirection.terminus(:file_server).expects(:find) @indirection.terminus(:file_server).stubs(:authorized?).returns(true) - @test_class.find(uri) + @indirection.find(uri) end it "should use the file_server terminus when the 'puppet' URI scheme is used, no host name is present, and the process name is 'apply'" do @@ -43,19 +43,19 @@ shared_examples_for "Puppet::FileServing::Files" do Puppet.settings.stubs(:value).with(:fileserverconfig).returns("/whatever") @indirection.terminus(:file_server).expects(:find) @indirection.terminus(:file_server).stubs(:authorized?).returns(true) - @test_class.find(uri) + @indirection.find(uri) end it "should use the file terminus when the 'file' URI scheme is used" do uri = "file:///fakemod/my/file" @indirection.terminus(:file).expects(:find) - @test_class.find(uri) + @indirection.find(uri) end it "should use the file terminus when a fully qualified path is provided" do uri = "/fakemod/my/file" @indirection.terminus(:file).expects(:find) - @test_class.find(uri) + @indirection.find(uri) end it "should use the configuration to test whether the request is allowed" do @@ -66,6 +66,6 @@ shared_examples_for "Puppet::FileServing::Files" do @indirection.terminus(:file_server).expects(:find) mount.expects(:allowed?).returns(true) - @test_class.find(uri, :node => "foo", :ip => "bar") + @indirection.find(uri, :node => "foo", :ip => "bar") end end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 505a8f973..13470428e 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -6,7 +6,6 @@ dir = File.expand_path(File.dirname(__FILE__)) $LOAD_PATH.unshift("#{dir}/") $LOAD_PATH.unshift("#{dir}/lib") # a spec-specific test lib dir $LOAD_PATH.unshift("#{dir}/../lib") -$LOAD_PATH.unshift("#{dir}/../test/lib") # Don't want puppet getting the command line arguments for rake or autotest ARGV.clear @@ -20,12 +19,10 @@ module PuppetSpec FIXTURE_DIR = File.join(dir = File.expand_path(File.dirname(__FILE__)), "fixtures") unless defined?(FIXTURE_DIR) end -module PuppetTest -end - require 'pathname' require 'lib/puppet_spec/verbose' require 'lib/puppet_spec/files' +require 'lib/puppet_spec/fixtures' require 'monkey_patches/alias_should_to_must' require 'monkey_patches/publicize_methods' @@ -34,38 +31,9 @@ Pathname.glob("#{dir}/shared_behaviours/**/*.rb") do |behaviour| end RSpec.configure do |config| - config.mock_with :mocha + include PuppetSpec::Fixtures - config.after :each do - Puppet.settings.clear - Puppet::Node::Environment.clear - Puppet::Util::Storage.clear - Puppet::Util::ExecutionStub.reset - - if defined?($tmpfiles) - $tmpfiles.each do |file| - file = File.expand_path(file) - if Puppet.features.posix? and file !~ /^\/tmp/ and file !~ /^\/var\/folders/ - puts "Not deleting tmpfile #{file} outside of /tmp or /var/folders" - next - elsif Puppet.features.microsoft_windows? - tempdir = File.expand_path(File.join(Dir::LOCAL_APPDATA, "Temp")) - if file !~ /^#{tempdir}/ - puts "Not deleting tmpfile #{file} outside of #{tempdir}" - next - end - end - if FileTest.exist?(file) - system("chmod -R 755 '#{file}'") - system("rm -rf '#{file}'") - end - end - $tmpfiles.clear - end - - @logs.clear - Puppet::Util::Log.close_all - end + config.mock_with :mocha config.before :each do # these globals are set by Application @@ -82,7 +50,19 @@ RSpec.configure do |config| Puppet.settings[:bindaddress] = "127.0.0.1" @logs = [] - Puppet::Util::Log.newdestination(@logs) + Puppet::Util::Log.newdestination(Puppet::Test::LogCollector.new(@logs)) + end + + config.after :each do + Puppet.settings.clear + Puppet::Node::Environment.clear + Puppet::Util::Storage.clear + Puppet::Util::ExecutionStub.reset + + PuppetSpec::Files.cleanup + + @logs.clear + Puppet::Util::Log.close_all end end diff --git a/spec/unit/agent/locker_spec.rb b/spec/unit/agent/locker_spec.rb index ad54c765a..e7c8929c7 100755 --- a/spec/unit/agent/locker_spec.rb +++ b/spec/unit/agent/locker_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') require 'puppet/agent' require 'puppet/agent/locker' diff --git a/spec/unit/agent_spec.rb b/spec/unit/agent_spec.rb index 2b3ee8ca0..a3a54bf7d 100755 --- a/spec/unit/agent_spec.rb +++ b/spec/unit/agent_spec.rb @@ -3,7 +3,7 @@ # Created by Luke Kanies on 2007-11-12. # Copyright (c) 2007. All rights reserved. -require File.dirname(__FILE__) + '/../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../spec_helper') require 'puppet/agent' class AgentTestClient diff --git a/spec/unit/application/agent_spec.rb b/spec/unit/application/agent_spec.rb index c9d9a4509..804057868 100755 --- a/spec/unit/application/agent_spec.rb +++ b/spec/unit/application/agent_spec.rb @@ -1,12 +1,12 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') require 'puppet/agent' require 'puppet/application/agent' require 'puppet/network/server' -require 'puppet/network/handler' require 'puppet/daemon' +require 'puppet/network/handler' describe Puppet::Application::Agent do before :each do @@ -14,15 +14,16 @@ describe Puppet::Application::Agent do @puppetd.stubs(:puts) @daemon = stub_everything 'daemon' Puppet::Daemon.stubs(:new).returns(@daemon) + Puppet[:daemonize] = false @agent = stub_everything 'agent' Puppet::Agent.stubs(:new).returns(@agent) @puppetd.preinit Puppet::Util::Log.stubs(:newdestination) Puppet::Util::Log.stubs(:level=) - Puppet::Node.stubs(:terminus_class=) - Puppet::Node.stubs(:cache_class=) - Puppet::Node::Facts.stubs(:terminus_class=) + Puppet::Node.indirection.stubs(:terminus_class=) + Puppet::Node.indirection.stubs(:cache_class=) + Puppet::Node::Facts.indirection.stubs(:terminus_class=) end it "should operate in agent run_mode" do @@ -172,17 +173,13 @@ describe Puppet::Application::Agent do @puppetd.options.stubs(:[]) Puppet.stubs(:info) FileTest.stubs(:exists?).returns(true) - Puppet.stubs(:[]) - Puppet.stubs(:[]=) - Puppet.stubs(:[]).with(:libdir).returns("/dev/null/lib") - Puppet.settings.stubs(:print_config?) - Puppet.settings.stubs(:print_config) + Puppet[:libdir] = "/dev/null/lib" Puppet::SSL::Host.stubs(:ca_location=) - Puppet::Transaction::Report.stubs(:terminus_class=) - Puppet::Transaction::Report.stubs(:cache_class=) - Puppet::Resource::Catalog.stubs(:terminus_class=) - Puppet::Resource::Catalog.stubs(:cache_class=) - Puppet::Node::Facts.stubs(:terminus_class=) + Puppet::Transaction::Report.indirection.stubs(:terminus_class=) + Puppet::Transaction::Report.indirection.stubs(:cache_class=) + Puppet::Resource::Catalog.indirection.stubs(:terminus_class=) + Puppet::Resource::Catalog.indirection.stubs(:cache_class=) + Puppet::Node::Facts.indirection.stubs(:terminus_class=) @host = stub_everything 'host' Puppet::SSL::Host.stubs(:new).returns(@host) Puppet.stubs(:settraps) @@ -190,7 +187,7 @@ describe Puppet::Application::Agent do describe "with --test" do before :each do - Puppet.settings.stubs(:handlearg) + #Puppet.settings.stubs(:handlearg) @puppetd.options.stubs(:[]=) end @@ -205,8 +202,9 @@ describe Puppet::Application::Agent do @puppetd.setup_test end it "should set options[:onetime] to true" do - Puppet.expects(:[]=).with(:onetime,true) + Puppet[:onetime] = false @puppetd.setup_test + Puppet[:onetime].should == true end it "should set options[:detailed_exitcodes] to true" do @puppetd.options.expects(:[]=).with(:detailed_exitcodes,true) @@ -262,7 +260,7 @@ describe Puppet::Application::Agent do it "should print puppet config if asked to in Puppet config" do @puppetd.stubs(:exit) - Puppet.settings.stubs(:print_configs?).returns(true) + Puppet[:configprint] = "pluginsync" Puppet.settings.expects(:print_configs) @@ -270,14 +268,15 @@ describe Puppet::Application::Agent do end it "should exit after printing puppet config if asked to in Puppet config" do - Puppet.settings.stubs(:print_configs?).returns(true) - + Puppet[:modulepath] = '/my/path' + Puppet[:configprint] = "modulepath" + Puppet::Util::Settings.any_instance.expects(:puts).with('/my/path') lambda { @puppetd.setup }.should raise_error(SystemExit) end it "should set a central log destination with --centrallogs" do @puppetd.options.stubs(:[]).with(:centrallogs).returns(true) - Puppet.stubs(:[]).with(:server).returns("puppet.reductivelabs.com") + Puppet[:server] = "puppet.reductivelabs.com" Puppet::Util::Log.stubs(:newdestination).with(:syslog) Puppet::Util::Log.expects(:newdestination).with("puppet.reductivelabs.com") @@ -305,32 +304,34 @@ describe Puppet::Application::Agent do end it "should tell the report handler to use REST" do - Puppet::Transaction::Report.expects(:terminus_class=).with(:rest) + Puppet::Transaction::Report.indirection.expects(:terminus_class=).with(:rest) @puppetd.setup end it "should tell the report handler to cache locally as yaml" do - Puppet::Transaction::Report.expects(:cache_class=).with(:yaml) + Puppet::Transaction::Report.indirection.expects(:cache_class=).with(:yaml) @puppetd.setup end it "should change the catalog_terminus setting to 'rest'" do - Puppet.expects(:[]=).with(:catalog_terminus, :rest) + Puppet[:catalog_terminus] = :foo @puppetd.setup + Puppet[:catalog_terminus].should == :rest end it "should tell the catalog handler to use cache" do - Puppet::Resource::Catalog.expects(:cache_class=).with(:yaml) + Puppet::Resource::Catalog.indirection.expects(:cache_class=).with(:yaml) @puppetd.setup end it "should change the facts_terminus setting to 'facter'" do - Puppet.expects(:[]=).with(:facts_terminus, :facter) + Puppet[:facts_terminus] = :foo @puppetd.setup + Puppet[:facts_terminus].should == :facter end it "should create an agent" do @@ -378,7 +379,7 @@ describe Puppet::Application::Agent do end it "should daemonize if needed" do - Puppet.stubs(:[]).with(:daemonize).returns(true) + Puppet[:daemonize] = true @daemon.expects(:daemonize) @@ -401,7 +402,7 @@ describe Puppet::Application::Agent do end it "should setup listen if told to and not onetime" do - Puppet.stubs(:[]).with(:listen).returns(true) + Puppet[:listen] = true @puppetd.options.stubs(:[]).with(:onetime).returns(false) @puppetd.expects(:setup_listen) @@ -411,7 +412,7 @@ describe Puppet::Application::Agent do describe "when setting up listen" do before :each do - Puppet.stubs(:[]).with(:authconfig).returns('auth') + Puppet[:authconfig] = 'auth' FileTest.stubs(:exists?).with('auth').returns(true) File.stubs(:exist?).returns(true) @puppetd.options.stubs(:[]).with(:serve).returns([]) @@ -423,7 +424,7 @@ describe Puppet::Application::Agent do it "should exit if no authorization file" do Puppet.stubs(:err) - FileTest.stubs(:exists?).with('auth').returns(false) + FileTest.stubs(:exists?).with(Puppet[:authconfig]).returns(false) @puppetd.expects(:exit) @@ -444,9 +445,9 @@ describe Puppet::Application::Agent do end it "should use puppet default port" do - Puppet.stubs(:[]).with(:puppetport).returns(:port) + Puppet[:puppetport] = 32768 - Puppet::Network::Server.expects(:new).with { |args| args[:port] == :port } + Puppet::Network::Server.expects(:new).with { |args| args[:port] == 32768 } @puppetd.setup_listen end @@ -525,7 +526,7 @@ describe Puppet::Application::Agent do end it "should exit with report's computed exit status" do - Puppet.stubs(:[]).with(:noop).returns(false) + Puppet[:noop] = false report = stub 'report', :exit_status => 666 @agent.stubs(:run).returns(report) @puppetd.expects(:exit).with(666) @@ -534,7 +535,7 @@ describe Puppet::Application::Agent do end it "should exit with the report's computer exit status, even if --noop is set." do - Puppet.stubs(:[]).with(:noop).returns(true) + Puppet[:noop] = true report = stub 'report', :exit_status => 666 @agent.stubs(:run).returns(report) @puppetd.expects(:exit).with(666) diff --git a/spec/unit/application/apply_spec.rb b/spec/unit/application/apply_spec.rb index 67edd4ed7..0c6df2cf8 100755 --- a/spec/unit/application/apply_spec.rb +++ b/spec/unit/application/apply_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') require 'puppet/application/apply' require 'puppet/file_bucket/dipper' @@ -56,7 +56,7 @@ describe Puppet::Application::Apply do Puppet.stubs(:parse_config) Puppet::FileBucket::Dipper.stubs(:new) STDIN.stubs(:read) - Puppet::Transaction::Report.stubs(:cache_class=) + Puppet::Transaction::Report.indirection.stubs(:cache_class=) @apply.options.stubs(:[]).with(any_parameters) end @@ -115,7 +115,7 @@ describe Puppet::Application::Apply do end it "should tell the report handler to cache locally as yaml" do - Puppet::Transaction::Report.expects(:cache_class=).with(:yaml) + Puppet::Transaction::Report.indirection.expects(:cache_class=).with(:yaml) @apply.setup end @@ -148,17 +148,16 @@ describe Puppet::Application::Apply do describe "the parseonly command" do before :each do - Puppet.stubs(:[]).with(:environment) + @environment = Puppet::Node::Environment.new("env") + Puppet.stubs(:[]).with(:environment).returns(@environment) Puppet.stubs(:[]).with(:manifest).returns("site.pp") Puppet.stubs(:err) @apply.stubs(:exit) @apply.options.stubs(:[]).with(:code).returns "some code" - @collection = stub_everything - Puppet::Resource::TypeCollection.stubs(:new).returns(@collection) end - it "should use a Puppet Resource Type Collection to parse the file" do - @collection.expects(:perform_initial_import) + it "should use the environment to parse the file" do + @environment.stubs(:perform_initial_import) @apply.parseonly end @@ -168,14 +167,14 @@ describe Puppet::Application::Apply do end it "should exit with exit code 1 if error" do - @collection.stubs(:perform_initial_import).raises(Puppet::ParseError) + @environment.stubs(:perform_initial_import).raises(Puppet::ParseError) @apply.expects(:exit).with(1) @apply.parseonly end it "should exit with exit code 1 if error, even if --noop is set" do Puppet[:noop] = true - @collection.stubs(:perform_initial_import).raises(Puppet::ParseError) + @environment.stubs(:perform_initial_import).raises(Puppet::ParseError) @apply.expects(:exit).with(1) @apply.parseonly end @@ -192,14 +191,14 @@ describe Puppet::Application::Apply do @apply.options.stubs(:[]) @facts = stub_everything 'facts' - Puppet::Node::Facts.stubs(:find).returns(@facts) + Puppet::Node::Facts.indirection.stubs(:find).returns(@facts) @node = stub_everything 'node' - Puppet::Node.stubs(:find).returns(@node) + Puppet::Node.indirection.stubs(:find).returns(@node) @catalog = stub_everything 'catalog' @catalog.stubs(:to_ral).returns(@catalog) - Puppet::Resource::Catalog.stubs(:find).returns(@catalog) + Puppet::Resource::Catalog.indirection.stubs(:find).returns(@catalog) STDIN.stubs(:read) @@ -255,25 +254,25 @@ describe Puppet::Application::Apply do end it "should collect the node facts" do - Puppet::Node::Facts.expects(:find).returns(@facts) + Puppet::Node::Facts.indirection.expects(:find).returns(@facts) @apply.main end it "should raise an error if we can't find the node" do - Puppet::Node::Facts.expects(:find).returns(nil) + Puppet::Node::Facts.indirection.expects(:find).returns(nil) lambda { @apply.main }.should raise_error end it "should look for the node" do - Puppet::Node.expects(:find).returns(@node) + Puppet::Node.indirection.expects(:find).returns(@node) @apply.main end it "should raise an error if we can't find the node" do - Puppet::Node.expects(:find).returns(nil) + Puppet::Node.indirection.expects(:find).returns(nil) lambda { @apply.main }.should raise_error end @@ -299,7 +298,7 @@ describe Puppet::Application::Apply do end it "should compile the catalog" do - Puppet::Resource::Catalog.expects(:find).returns(@catalog) + Puppet::Resource::Catalog.indirection.expects(:find).returns(@catalog) @apply.main end @@ -330,6 +329,15 @@ describe Puppet::Application::Apply do @apply.main end + it "should save the last run summary" do + Puppet.stubs(:[]).with(:noop).returns(false) + report = Puppet::Transaction::Report.new("apply") + Puppet::Transaction::Report.stubs(:new).returns(report) + + Puppet::Configurer.any_instance.expects(:save_last_run_summary).with(report) + @apply.main + end + describe "with detailed_exitcodes" do it "should exit with report's computed exit status" do Puppet.stubs(:[]).with(:noop).returns(false) diff --git a/spec/unit/application/cert_spec.rb b/spec/unit/application/cert_spec.rb index b3257916b..4315bb8d8 100755 --- a/spec/unit/application/cert_spec.rb +++ b/spec/unit/application/cert_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') require 'puppet/application/cert' @@ -189,7 +189,7 @@ describe Puppet::Application::Cert do @cert_app.ca = @ca end - it "should not fail when no command is given" do + it "should SystemExit after printing help message" do # Make the help method silent for testing; this is a bit nasty, but we # can't identify a cleaner method. Help welcome. --daniel 2011-02-22 Puppet.features.stubs(:usage?).returns(false) diff --git a/spec/unit/application/describe_spec.rb b/spec/unit/application/describe_spec.rb index 7c64ff86d..47b98a17b 100755 --- a/spec/unit/application/describe_spec.rb +++ b/spec/unit/application/describe_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') require 'puppet/application/describe' diff --git a/spec/unit/application/doc_spec.rb b/spec/unit/application/doc_spec.rb index ed723636b..f432184d3 100755 --- a/spec/unit/application/doc_spec.rb +++ b/spec/unit/application/doc_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') require 'puppet/application/doc' require 'puppet/util/reference' diff --git a/spec/unit/application/filebucket_spec.rb b/spec/unit/application/filebucket_spec.rb index 95135c7eb..013e358d8 100644 --- a/spec/unit/application/filebucket_spec.rb +++ b/spec/unit/application/filebucket_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') require 'puppet/application/filebucket' require 'puppet/file_bucket/dipper' diff --git a/spec/unit/application/kick_spec.rb b/spec/unit/application/kick_spec.rb index c18a84de3..ce0e0c7d0 100755 --- a/spec/unit/application/kick_spec.rb +++ b/spec/unit/application/kick_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') require 'puppet/application/kick' @@ -161,7 +161,7 @@ describe Puppet::Application::Kick, :if => Puppet.features.posix? do @kick.options.stubs(:[]).with(:all).returns(true) @kick.stubs(:puts) - Puppet::Node.expects(:search).with("whatever",:fqdn => :something).returns([]) + Puppet::Node.indirection.expects(:search).with("whatever",:fqdn => :something).returns([]) @kick.setup end @@ -170,7 +170,7 @@ describe Puppet::Application::Kick, :if => Puppet.features.posix? do @kick.options.stubs(:[]).with(:all).returns(true) @kick.stubs(:puts) - Puppet::Node.expects(:search).with("whatever",:fqdn => nil).returns([]) + Puppet::Node.indirection.expects(:search).with("whatever",:fqdn => nil).returns([]) @kick.setup end @@ -180,7 +180,7 @@ describe Puppet::Application::Kick, :if => Puppet.features.posix? do @kick.stubs(:puts) @kick.classes = ['class'] - Puppet::Node.expects(:search).with("whatever", :class => "class", :fqdn => nil).returns([]) + Puppet::Node.indirection.expects(:search).with("whatever", :class => "class", :fqdn => nil).returns([]) @kick.setup end @@ -277,7 +277,7 @@ describe Puppet::Application::Kick, :if => Puppet.features.posix? do end it "should call run on a Puppet::Run for the given host" do - @agent_run.expects(:save).with('https://host:8139/production/run/host').returns(@agent_run) + Puppet::Run.indirection.expects(:save).with(@agent_run, 'https://host:8139/production/run/host').returns(@agent_run) @kick.run_for_host('host') end diff --git a/spec/unit/application/master_spec.rb b/spec/unit/application/master_spec.rb index d99b22ded..14478a61a 100644 --- a/spec/unit/application/master_spec.rb +++ b/spec/unit/application/master_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') require 'puppet/application/master' require 'puppet/daemon' @@ -14,12 +14,13 @@ describe Puppet::Application::Master do Puppet::Util::Log.stubs(:newdestination) Puppet::Util::Log.stubs(:level=) - Puppet::Node.stubs(:terminus_class=) - Puppet::Node.stubs(:cache_class=) - Puppet::Node::Facts.stubs(:terminus_class=) - Puppet::Node::Facts.stubs(:cache_class=) - Puppet::Transaction::Report.stubs(:terminus_class=) - Puppet::Resource::Catalog.stubs(:terminus_class=) + Puppet::Node.indirection.stubs(:terminus_class=) + Puppet::Node.indirection.stubs(:cache_class=) + Puppet::Node::Facts.indirection.stubs(:terminus_class=) + Puppet::Node::Facts.indirection.stubs(:cache_class=) + Puppet::Transaction::Report.indirection.stubs(:terminus_class=) + Puppet::Resource::Catalog.indirection.stubs(:terminus_class=) + Puppet::SSL::Host.stubs(:ca_location=) end it "should operate in master run_mode" do @@ -183,7 +184,7 @@ describe Puppet::Application::Master do end it "should cache class in yaml" do - Puppet::Node.expects(:cache_class=).with(:yaml) + Puppet::Node.indirection.expects(:cache_class=).with(:yaml) @master.setup end @@ -257,16 +258,15 @@ describe Puppet::Application::Master do describe "the parseonly command" do before :each do - Puppet.stubs(:[]).with(:environment) + @environment = Puppet::Node::Environment.new("env") + Puppet.stubs(:[]).with(:environment).returns(@environment) Puppet.stubs(:[]).with(:manifest).returns("site.pp") Puppet.stubs(:err) @master.stubs(:exit) - @collection = stub_everything - Puppet::Resource::TypeCollection.stubs(:new).returns(@collection) end it "should use a Puppet Resource Type Collection to parse the file" do - @collection.expects(:perform_initial_import) + @environment.expects(:perform_initial_import) @master.parseonly end @@ -276,7 +276,7 @@ describe Puppet::Application::Master do end it "should exit with exit code 1 if error" do - @collection.stubs(:perform_initial_import).raises(Puppet::ParseError) + @environment.stubs(:perform_initial_import).raises(Puppet::ParseError) @master.expects(:exit).with(1) @master.parseonly end @@ -299,7 +299,7 @@ describe Puppet::Application::Master do it "should compile a catalog for the specified node" do @master.options[:node] = "foo" - Puppet::Resource::Catalog.expects(:find).with("foo").returns Puppet::Resource::Catalog.new + Puppet::Resource::Catalog.indirection.expects(:find).with("foo").returns Puppet::Resource::Catalog.new $stdout.stubs(:puts) @master.compile @@ -307,7 +307,7 @@ describe Puppet::Application::Master do it "should convert the catalog to a pure-resource catalog and use 'jj' to pretty-print the catalog" do catalog = Puppet::Resource::Catalog.new - Puppet::Resource::Catalog.expects(:find).returns catalog + Puppet::Resource::Catalog.indirection.expects(:find).returns catalog catalog.expects(:to_resource).returns("rescat") @@ -319,7 +319,7 @@ describe Puppet::Application::Master do it "should exit with error code 30 if no catalog can be found" do @master.options[:node] = "foo" - Puppet::Resource::Catalog.expects(:find).returns nil + Puppet::Resource::Catalog.indirection.expects(:find).returns nil @master.expects(:exit).with(30) $stderr.expects(:puts) @@ -328,7 +328,7 @@ describe Puppet::Application::Master do it "should exit with error code 30 if there's a failure" do @master.options[:node] = "foo" - Puppet::Resource::Catalog.expects(:find).raises ArgumentError + Puppet::Resource::Catalog.indirection.expects(:find).raises ArgumentError @master.expects(:exit).with(30) $stderr.expects(:puts) diff --git a/spec/unit/application/queue_spec.rb b/spec/unit/application/queue_spec.rb index f8ebbd0b4..bb485ac3c 100755 --- a/spec/unit/application/queue_spec.rb +++ b/spec/unit/application/queue_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') require 'puppet/application/queue' require 'puppet/indirector/catalog/queue' @@ -13,7 +13,7 @@ describe Puppet::Application::Queue do Puppet::Util::Log.stubs(:newdestination) Puppet::Util::Log.stubs(:level=) - Puppet::Resource::Catalog.stubs(:terminus_class=) + Puppet::Resource::Catalog.indirection.stubs(:terminus_class=) end it "should ask Puppet::Application to parse Puppet configuration file" do @@ -76,7 +76,7 @@ describe Puppet::Application::Queue do @queue.daemon.stubs(:daemonize) Puppet.stubs(:info) Puppet.features.stubs(:stomp?).returns true - Puppet::Resource::Catalog.stubs(:terminus_class=) + Puppet::Resource::Catalog.indirection.stubs(:terminus_class=) Puppet.stubs(:settraps) Puppet.settings.stubs(:print_config?) Puppet.settings.stubs(:print_config) @@ -140,7 +140,7 @@ describe Puppet::Application::Queue do end it "should configure the Catalog class to use ActiveRecord" do - Puppet::Resource::Catalog.expects(:terminus_class=).with(:active_record) + Puppet::Resource::Catalog.indirection.expects(:terminus_class=).with(:active_record) @queue.setup end @@ -167,8 +167,8 @@ describe Puppet::Application::Queue do end it "should log and save each catalog passed by the queue" do - catalog = mock 'catalog', :name => 'eh' - catalog.expects(:save) + catalog = Puppet::Resource::Catalog.new('eh') + Puppet::Resource::Catalog.indirection.expects(:save).with(catalog) Puppet::Resource::Catalog::Queue.expects(:subscribe).yields(catalog) Puppet.expects(:notice).times(2) diff --git a/spec/unit/application/resource_spec.rb b/spec/unit/application/resource_spec.rb index b6c52b11e..3e3f8296b 100755 --- a/spec/unit/application/resource_spec.rb +++ b/spec/unit/application/resource_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') require 'puppet/application/resource' @@ -162,21 +162,21 @@ describe Puppet::Application::Resource do @resource.stubs(:puts) @resource.host = 'host' - Puppet::Resource.stubs(:find ).never - Puppet::Resource.stubs(:search).never - Puppet::Resource.stubs(:save ).never + Puppet::Resource.indirection.stubs(:find ).never + Puppet::Resource.indirection.stubs(:search).never + Puppet::Resource.indirection.stubs(:save ).never end it "should search for resources" do @resource.command_line.stubs(:args).returns(['type']) - Puppet::Resource.expects(:search).with('https://host:8139/production/resources/type/', {}).returns([]) + Puppet::Resource.indirection.expects(:search).with('https://host:8139/production/resources/type/', {}).returns([]) @resource.main end it "should describe the given resource" do @resource.command_line.stubs(:args).returns(['type', 'name']) x = stub_everything 'resource' - Puppet::Resource.expects(:find).with('https://host:8139/production/resources/type/name').returns(x) + Puppet::Resource.indirection.expects(:find).with('https://host:8139/production/resources/type/name').returns(x) @resource.main end @@ -184,7 +184,7 @@ describe Puppet::Application::Resource do @resource.command_line.stubs(:args).returns(['type','name','param=temp']) res = stub "resource" - res.expects(:save).with('https://host:8139/production/resources/type/name').returns(res) + Puppet::Resource.indirection.expects(:save).with(res, 'https://host:8139/production/resources/type/name').returns(res) res.expects(:collect) res.expects(:to_manifest) Puppet::Resource.expects(:new).with('type', 'name', :parameters => {'param' => 'temp'}).returns(res) @@ -199,20 +199,20 @@ describe Puppet::Application::Resource do @resource.stubs(:puts) @resource.host = nil - Puppet::Resource.stubs(:find ).never - Puppet::Resource.stubs(:search).never - Puppet::Resource.stubs(:save ).never + Puppet::Resource.indirection.stubs(:find ).never + Puppet::Resource.indirection.stubs(:search).never + Puppet::Resource.indirection.stubs(:save ).never end it "should search for resources" do - Puppet::Resource.expects(:search).with('type/', {}).returns([]) + Puppet::Resource.indirection.expects(:search).with('type/', {}).returns([]) @resource.main end it "should describe the given resource" do @resource.command_line.stubs(:args).returns(['type','name']) x = stub_everything 'resource' - Puppet::Resource.expects(:find).with('type/name').returns(x) + Puppet::Resource.indirection.expects(:find).with('type/name').returns(x) @resource.main end @@ -220,7 +220,7 @@ describe Puppet::Application::Resource do @resource.command_line.stubs(:args).returns(['type','name','param=temp']) res = stub "resource" - res.expects(:save).with('type/name').returns(res) + Puppet::Resource.indirection.expects(:save).with(res, 'type/name').returns(res) res.expects(:collect) res.expects(:to_manifest) Puppet::Resource.expects(:new).with('type', 'name', :parameters => {'param' => 'temp'}).returns(res) diff --git a/spec/unit/application_spec.rb b/spec/unit/application_spec.rb index 5a52c2d54..befc4f510 100755 --- a/spec/unit/application_spec.rb +++ b/spec/unit/application_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../spec_helper') require 'puppet/application' require 'puppet' @@ -283,11 +283,11 @@ describe Puppet::Application do @app.parse_options end - describe "when using --help", :if => Puppet.features.usage? do + describe "when using --help" do - it "should call RDoc::usage and exit" do + it "should call exit" do @app.expects(:exit) - RDoc.expects(:usage).returns(true) + @app.stubs(:puts) @app.handle_help(nil) end diff --git a/spec/unit/configurer/downloader_spec.rb b/spec/unit/configurer/downloader_spec.rb index 4080263e7..266a96b03 100755 --- a/spec/unit/configurer/downloader_spec.rb +++ b/spec/unit/configurer/downloader_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') require 'puppet/configurer/downloader' diff --git a/spec/unit/configurer/fact_handler_spec.rb b/spec/unit/configurer/fact_handler_spec.rb index 051270144..71645225f 100755 --- a/spec/unit/configurer/fact_handler_spec.rb +++ b/spec/unit/configurer/fact_handler_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') require 'puppet/configurer' require 'puppet/configurer/fact_handler' @@ -66,7 +66,7 @@ describe Puppet::Configurer::FactHandler do it "should use the Facts class with the :certname to find the facts" do Puppet.settings.expects(:value).with(:certname).returns "foo" - Puppet::Node::Facts.expects(:find).with("foo").returns "myfacts" + Puppet::Node::Facts.indirection.expects(:find).with("foo").returns "myfacts" @facthandler.stubs(:reload_facter) @facthandler.find_facts.should == "myfacts" end @@ -75,7 +75,7 @@ describe Puppet::Configurer::FactHandler do @facthandler.expects(:reload_facter) Puppet.settings.expects(:value).with(:certname).returns "myhost" - Puppet::Node::Facts.expects(:find).with("myhost") + Puppet::Node::Facts.indirection.expects(:find).with("myhost") @facthandler.find_facts end @@ -85,7 +85,7 @@ describe Puppet::Configurer::FactHandler do Puppet.settings.stubs(:value).with(:trace).returns false Puppet.settings.stubs(:value).with(:certname).returns "myhost" - Puppet::Node::Facts.expects(:find).raises RuntimeError + Puppet::Node::Facts.indirection.expects(:find).raises RuntimeError lambda { @facthandler.find_facts }.should raise_error(Puppet::Error) end diff --git a/spec/unit/configurer/plugin_handler_spec.rb b/spec/unit/configurer/plugin_handler_spec.rb index 30b135e8f..04a479665 100755 --- a/spec/unit/configurer/plugin_handler_spec.rb +++ b/spec/unit/configurer/plugin_handler_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') require 'puppet/configurer' require 'puppet/configurer/plugin_handler' diff --git a/spec/unit/configurer_spec.rb b/spec/unit/configurer_spec.rb index a4b627c08..d21d86ecf 100755 --- a/spec/unit/configurer_spec.rb +++ b/spec/unit/configurer_spec.rb @@ -3,7 +3,7 @@ # Created by Luke Kanies on 2007-11-12. # Copyright (c) 2007. All rights reserved. -require File.dirname(__FILE__) + '/../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../spec_helper') require 'puppet/configurer' describe Puppet::Configurer do @@ -82,9 +82,7 @@ describe Puppet::Configurer, "when executing a catalog run" do @catalog.stubs(:apply) @agent.stubs(:retrieve_catalog).returns @catalog @agent.stubs(:save_last_run_summary) - - Puppet::Util::Log.stubs(:newdestination) - Puppet::Util::Log.stubs(:close) + Puppet::Transaction::Report.indirection.stubs(:save) end it "should prepare for the run" do @@ -95,7 +93,7 @@ describe Puppet::Configurer, "when executing a catalog run" do it "should initialize a transaction report if one is not provided" do report = Puppet::Transaction::Report.new("apply") - Puppet::Transaction::Report.expects(:new).returns report + Puppet::Transaction::Report.expects(:new).at_least_once.returns report @agent.run end @@ -120,6 +118,7 @@ describe Puppet::Configurer, "when executing a catalog run" do report = Puppet::Transaction::Report.new("apply") Puppet::Transaction::Report.expects(:new).returns report + @agent.stubs(:send_report) Puppet::Util::Log.expects(:newdestination).with(report) @agent.run @@ -212,9 +211,10 @@ describe Puppet::Configurer, "when executing a catalog run" do report = Puppet::Transaction::Report.new("apply") Puppet::Transaction::Report.expects(:new).returns(report) - Puppet::Util::Log.expects(:close).with(report) + report.expects(:<<).at_least_once @agent.run + Puppet::Util::Log.destinations.should_not include(report) end it "should return the report as the result of the run" do @@ -261,14 +261,14 @@ describe Puppet::Configurer, "when sending a report" do it "should save the report if reporting is enabled" do Puppet.settings[:report] = true - @report.expects(:save) + Puppet::Transaction::Report.indirection.expects(:save).with(@report) @configurer.send_report(@report, nil) end it "should not save the report if reporting is disabled" do Puppet.settings[:report] = false - @report.expects(:save).never + Puppet::Transaction::Report.indirection.expects(:save).never @configurer.send_report(@report, nil) end @@ -289,7 +289,7 @@ describe Puppet::Configurer, "when sending a report" do it "should log but not fail if saving the report fails" do Puppet.settings[:report] = true - @report.expects(:save).raises "whatever" + Puppet::Transaction::Report.indirection.expects(:save).with(@report).raises "whatever" Puppet.expects(:err) lambda { @configurer.send_report(@report, nil) }.should_not raise_error @@ -346,15 +346,15 @@ describe Puppet::Configurer, "when retrieving a catalog" do end it "should first look in the cache for a catalog" do - Puppet::Resource::Catalog.expects(:find).with { |name, options| options[:ignore_terminus] == true }.returns @catalog - Puppet::Resource::Catalog.expects(:find).with { |name, options| options[:ignore_cache] == true }.never + Puppet::Resource::Catalog.indirection.expects(:find).with { |name, options| options[:ignore_terminus] == true }.returns @catalog + Puppet::Resource::Catalog.indirection.expects(:find).with { |name, options| options[:ignore_cache] == true }.never @agent.retrieve_catalog.should == @catalog end it "should compile a new catalog if none is found in the cache" do - Puppet::Resource::Catalog.expects(:find).with { |name, options| options[:ignore_terminus] == true }.returns nil - Puppet::Resource::Catalog.expects(:find).with { |name, options| options[:ignore_cache] == true }.returns @catalog + Puppet::Resource::Catalog.indirection.expects(:find).with { |name, options| options[:ignore_terminus] == true }.returns nil + Puppet::Resource::Catalog.indirection.expects(:find).with { |name, options| options[:ignore_cache] == true }.returns @catalog @agent.retrieve_catalog.should == @catalog end @@ -363,7 +363,7 @@ describe Puppet::Configurer, "when retrieving a catalog" do describe "when not using a REST terminus for catalogs" do it "should not pass any facts when retrieving the catalog" do @agent.expects(:facts_for_uploading).never - Puppet::Resource::Catalog.expects(:find).with { |name, options| + Puppet::Resource::Catalog.indirection.expects(:find).with { |name, options| options[:facts].nil? }.returns @catalog @@ -374,7 +374,7 @@ describe Puppet::Configurer, "when retrieving a catalog" do describe "when using a REST terminus for catalogs" do it "should pass the prepared facts and the facts format as arguments when retrieving the catalog" do @agent.expects(:facts_for_uploading).returns(:facts => "myfacts", :facts_format => :foo) - Puppet::Resource::Catalog.expects(:find).with { |name, options| + Puppet::Resource::Catalog.indirection.expects(:find).with { |name, options| options[:facts] == "myfacts" and options[:facts_format] == :foo }.returns @catalog @@ -383,7 +383,7 @@ describe Puppet::Configurer, "when retrieving a catalog" do end it "should use the Catalog class to get its catalog" do - Puppet::Resource::Catalog.expects(:find).returns @catalog + Puppet::Resource::Catalog.indirection.expects(:find).returns @catalog @agent.retrieve_catalog end @@ -391,20 +391,20 @@ describe Puppet::Configurer, "when retrieving a catalog" do it "should use its certname to retrieve the catalog" do Facter.stubs(:value).returns "eh" Puppet.settings[:certname] = "myhost.domain.com" - Puppet::Resource::Catalog.expects(:find).with { |name, options| name == "myhost.domain.com" }.returns @catalog + Puppet::Resource::Catalog.indirection.expects(:find).with { |name, options| name == "myhost.domain.com" }.returns @catalog @agent.retrieve_catalog end it "should default to returning a catalog retrieved directly from the server, skipping the cache" do - Puppet::Resource::Catalog.expects(:find).with { |name, options| options[:ignore_cache] == true }.returns @catalog + Puppet::Resource::Catalog.indirection.expects(:find).with { |name, options| options[:ignore_cache] == true }.returns @catalog @agent.retrieve_catalog.should == @catalog end it "should log and return the cached catalog when no catalog can be retrieved from the server" do - Puppet::Resource::Catalog.expects(:find).with { |name, options| options[:ignore_cache] == true }.returns nil - Puppet::Resource::Catalog.expects(:find).with { |name, options| options[:ignore_terminus] == true }.returns @catalog + Puppet::Resource::Catalog.indirection.expects(:find).with { |name, options| options[:ignore_cache] == true }.returns nil + Puppet::Resource::Catalog.indirection.expects(:find).with { |name, options| options[:ignore_terminus] == true }.returns @catalog Puppet.expects(:notice) @@ -412,15 +412,15 @@ describe Puppet::Configurer, "when retrieving a catalog" do end it "should not look in the cache for a catalog if one is returned from the server" do - Puppet::Resource::Catalog.expects(:find).with { |name, options| options[:ignore_cache] == true }.returns @catalog - Puppet::Resource::Catalog.expects(:find).with { |name, options| options[:ignore_terminus] == true }.never + Puppet::Resource::Catalog.indirection.expects(:find).with { |name, options| options[:ignore_cache] == true }.returns @catalog + Puppet::Resource::Catalog.indirection.expects(:find).with { |name, options| options[:ignore_terminus] == true }.never @agent.retrieve_catalog.should == @catalog end it "should return the cached catalog when retrieving the remote catalog throws an exception" do - Puppet::Resource::Catalog.expects(:find).with { |name, options| options[:ignore_cache] == true }.raises "eh" - Puppet::Resource::Catalog.expects(:find).with { |name, options| options[:ignore_terminus] == true }.returns @catalog + Puppet::Resource::Catalog.indirection.expects(:find).with { |name, options| options[:ignore_cache] == true }.raises "eh" + Puppet::Resource::Catalog.indirection.expects(:find).with { |name, options| options[:ignore_terminus] == true }.returns @catalog @agent.retrieve_catalog.should == @catalog end @@ -428,7 +428,7 @@ describe Puppet::Configurer, "when retrieving a catalog" do it "should log and return nil if no catalog can be retrieved from the server and :usecacheonfailure is disabled" do Puppet.stubs(:[]) Puppet.expects(:[]).with(:usecacheonfailure).returns false - Puppet::Resource::Catalog.expects(:find).with { |name, options| options[:ignore_cache] == true }.returns nil + Puppet::Resource::Catalog.indirection.expects(:find).with { |name, options| options[:ignore_cache] == true }.returns nil Puppet.expects(:warning) @@ -436,21 +436,21 @@ describe Puppet::Configurer, "when retrieving a catalog" do end it "should return nil if no cached catalog is available and no catalog can be retrieved from the server" do - Puppet::Resource::Catalog.expects(:find).with { |name, options| options[:ignore_cache] == true }.returns nil - Puppet::Resource::Catalog.expects(:find).with { |name, options| options[:ignore_terminus] == true }.returns nil + Puppet::Resource::Catalog.indirection.expects(:find).with { |name, options| options[:ignore_cache] == true }.returns nil + Puppet::Resource::Catalog.indirection.expects(:find).with { |name, options| options[:ignore_terminus] == true }.returns nil @agent.retrieve_catalog.should be_nil end it "should convert the catalog before returning" do - Puppet::Resource::Catalog.stubs(:find).returns @catalog + Puppet::Resource::Catalog.indirection.stubs(:find).returns @catalog @agent.expects(:convert_catalog).with { |cat, dur| cat == @catalog }.returns "converted catalog" @agent.retrieve_catalog.should == "converted catalog" end it "should return nil if there is an error while retrieving the catalog" do - Puppet::Resource::Catalog.expects(:find).at_least_once.raises "eh" + Puppet::Resource::Catalog.indirection.expects(:find).at_least_once.raises "eh" @agent.retrieve_catalog.should be_nil end diff --git a/spec/unit/daemon_spec.rb b/spec/unit/daemon_spec.rb index 39592b7c9..4de76b728 100755 --- a/spec/unit/daemon_spec.rb +++ b/spec/unit/daemon_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../spec_helper') require 'puppet/daemon' def without_warnings diff --git a/spec/unit/dsl/resource_api_spec.rb b/spec/unit/dsl/resource_api_spec.rb index b36a67f30..13aa6a437 100755 --- a/spec/unit/dsl/resource_api_spec.rb +++ b/spec/unit/dsl/resource_api_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') require 'puppet/dsl/resource_api' diff --git a/spec/unit/dsl/resource_type_api_spec.rb b/spec/unit/dsl/resource_type_api_spec.rb index 4f4eb7e01..795ce2868 100755 --- a/spec/unit/dsl/resource_type_api_spec.rb +++ b/spec/unit/dsl/resource_type_api_spec.rb @@ -1,66 +1,54 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') require 'puppet/dsl/resource_type_api' describe Puppet::DSL::ResourceTypeAPI do - # Run the given block in the context of a new ResourceTypeAPI - # object. + # Verify that the block creates a single AST node through the API, + # instantiate that AST node into a types, and return that type. def test_api_call(&block) - Thread.current[:known_resource_types] = Puppet::Resource::TypeCollection.new(:env) - Puppet::DSL::ResourceTypeAPI.new.instance_eval(&block) + main_object = Puppet::DSL::ResourceTypeAPI.new + main_object.instance_eval(&block) + created_ast_objects = main_object.instance_eval { @__created_ast_objects__ } + created_ast_objects.length.should == 1 + new_types = created_ast_objects[0].instantiate('') + new_types.length.should == 1 + new_types[0] ensure - Thread.current[:known_resource_types] = nil + Thread.current[:ruby_file_parse_result] = nil end [:definition, :node, :hostclass].each do |type| method = type == :definition ? "define" : type it "should be able to create a #{type}" do - newtype = Puppet::Resource::Type.new(:hostclass, "foo") - Puppet::Resource::Type.expects(:new).with { |t, n, args| t == type }.returns newtype - test_api_call { send(method, "myname") } + newtype = test_api_call { send(method, "myname").should == nil } + newtype.should be_a(Puppet::Resource::Type) + newtype.type.should == type end it "should use the provided name when creating a #{type}" do - type = Puppet::Resource::Type.new(:hostclass, "foo") - Puppet::Resource::Type.expects(:new).with { |t, n, args| n == "myname" }.returns type - test_api_call { send(method, "myname") } + newtype = test_api_call { send(method, "myname") } + newtype.name.should == "myname" end unless type == :definition - it "should pass in any provided options" do - type = Puppet::Resource::Type.new(:hostclass, "foo") - Puppet::Resource::Type.expects(:new).with { |t, n, args| args == {:myarg => :myvalue} }.returns type - test_api_call { send(method, "myname", :myarg => :myvalue) } + it "should pass in any provided options when creating a #{type}" do + newtype = test_api_call { send(method, "myname", :line => 200) } + newtype.line.should == 200 end end it "should set any provided block as the type's ruby code" do - Puppet::Resource::Type.any_instance.expects(:ruby_code=).with { |blk| blk.call == 'foo' } - test_api_call { send(method, "myname") { 'foo' } } - end - - it "should add the type to the current environment's known resource types" do - begin - newtype = Puppet::Resource::Type.new(:hostclass, "foo") - Puppet::Resource::Type.expects(:new).returns newtype - known_resource_types = Puppet::Resource::TypeCollection.new(:env) - Thread.current[:known_resource_types] = known_resource_types - known_resource_types.expects(:add).with(newtype) - Puppet::DSL::ResourceTypeAPI.new.instance_eval { hostclass "myname" } - ensure - Thread.current[:known_resource_types] = nil - end + newtype = test_api_call { send(method, "myname") { 'method_result' } } + newtype.ruby_code.call.should == 'method_result' end end describe "when creating a definition" do it "should use the provided options to define valid arguments for the resource type" do - newtype = Puppet::Resource::Type.new(:definition, "foo") - Puppet::Resource::Type.expects(:new).returns newtype - test_api_call { define("myname", :arg1, :arg2) } - newtype.instance_eval { @arguments }.should == { 'arg1' => nil, 'arg2' => nil } + newtype = test_api_call { define("myname", :arg1, :arg2) } + newtype.arguments.should == { 'arg1' => nil, 'arg2' => nil } end end end diff --git a/spec/unit/file_bucket/dipper_spec.rb b/spec/unit/file_bucket/dipper_spec.rb index c40d79589..4dabb722b 100755 --- a/spec/unit/file_bucket/dipper_spec.rb +++ b/spec/unit/file_bucket/dipper_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') require 'pathname' @@ -20,7 +20,7 @@ describe Puppet::FileBucket::Dipper do @dipper = Puppet::FileBucket::Dipper.new(:Path => "/my/bucket") file = make_tmp_file('contents') - Puppet::FileBucket::File.expects(:head).raises ArgumentError + Puppet::FileBucket::File.indirection.expects(:head).raises ArgumentError lambda { @dipper.backup(file) }.should raise_error(Puppet::Error) end @@ -29,8 +29,8 @@ describe Puppet::FileBucket::Dipper do @dipper = Puppet::FileBucket::Dipper.new(:Path => "/my/bucket") file = make_tmp_file('contents') - Puppet::FileBucket::File.expects(:head).returns false - Puppet::FileBucket::File.any_instance.expects(:save).raises ArgumentError + Puppet::FileBucket::File.indirection.expects(:head).returns false + Puppet::FileBucket::File.indirection.expects(:save).raises ArgumentError lambda { @dipper.backup(file) }.should raise_error(Puppet::Error) end @@ -55,8 +55,8 @@ describe Puppet::FileBucket::Dipper do file = make_tmp_file('my contents') checksum = Digest::MD5.hexdigest('my contents') - Puppet::FileBucket::File.expects(:head).returns true - Puppet::FileBucket::File.any_instance.expects(:save).never + Puppet::FileBucket::File.indirection.expects(:head).returns true + Puppet::FileBucket::File.indirection.expects(:save).never @dipper.backup(file).should == checksum end diff --git a/spec/unit/file_bucket/file_spec.rb b/spec/unit/file_bucket/file_spec.rb index f80b16238..d79345736 100644 --- a/spec/unit/file_bucket/file_spec.rb +++ b/spec/unit/file_bucket/file_spec.rb @@ -52,15 +52,7 @@ describe Puppet::FileBucket::File do end it "should have a :save instance method" do - Puppet::FileBucket::File.new("mysum").should respond_to(:save) - end - - it "should respond to :find" do - Puppet::FileBucket::File.should respond_to(:find) - end - - it "should respond to :destroy" do - Puppet::FileBucket::File.should respond_to(:destroy) + Puppet::FileBucket::File.indirection.should respond_to(:save) end end @@ -88,25 +80,25 @@ describe Puppet::FileBucket::File do describe "using the indirector's find method" do it "should return nil if a file doesn't exist" do - bucketfile = Puppet::FileBucket::File.find("md5/#{@digest}") + bucketfile = Puppet::FileBucket::File.indirection.find("md5/#{@digest}") bucketfile.should == nil end it "should find a filebucket if the file exists" do make_bucketed_file - bucketfile = Puppet::FileBucket::File.find("md5/#{@digest}") + bucketfile = Puppet::FileBucket::File.indirection.find("md5/#{@digest}") bucketfile.should_not == nil end describe "using RESTish digest notation" do it "should return nil if a file doesn't exist" do - bucketfile = Puppet::FileBucket::File.find("md5/#{@digest}") + bucketfile = Puppet::FileBucket::File.indirection.find("md5/#{@digest}") bucketfile.should == nil end it "should find a filebucket if the file exists" do make_bucketed_file - bucketfile = Puppet::FileBucket::File.find("md5/#{@digest}") + bucketfile = Puppet::FileBucket::File.indirection.find("md5/#{@digest}") bucketfile.should_not == nil end diff --git a/spec/unit/file_collection/lookup_spec.rb b/spec/unit/file_collection/lookup_spec.rb index 2454cc833..138949a96 100755 --- a/spec/unit/file_collection/lookup_spec.rb +++ b/spec/unit/file_collection/lookup_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') require 'puppet/file_collection/lookup' class LookupTester diff --git a/spec/unit/file_collection_spec.rb b/spec/unit/file_collection_spec.rb index 08621ccac..09888f425 100755 --- a/spec/unit/file_collection_spec.rb +++ b/spec/unit/file_collection_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../spec_helper') require 'puppet/file_collection' diff --git a/spec/unit/file_serving/base_spec.rb b/spec/unit/file_serving/base_spec.rb index b939bcaa3..3449c8d0e 100755 --- a/spec/unit/file_serving/base_spec.rb +++ b/spec/unit/file_serving/base_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') require 'puppet/file_serving/base' diff --git a/spec/unit/file_serving/configuration/parser_spec.rb b/spec/unit/file_serving/configuration/parser_spec.rb index 36e721885..46cdc1c45 100755 --- a/spec/unit/file_serving/configuration/parser_spec.rb +++ b/spec/unit/file_serving/configuration/parser_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') require 'puppet/file_serving/configuration/parser' diff --git a/spec/unit/file_serving/configuration_spec.rb b/spec/unit/file_serving/configuration_spec.rb index 3e11caa08..3c6113165 100755 --- a/spec/unit/file_serving/configuration_spec.rb +++ b/spec/unit/file_serving/configuration_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') require 'puppet/file_serving/configuration' diff --git a/spec/unit/file_serving/content_spec.rb b/spec/unit/file_serving/content_spec.rb index 92b747448..576cbde1f 100755 --- a/spec/unit/file_serving/content_spec.rb +++ b/spec/unit/file_serving/content_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') require 'puppet/file_serving/content' diff --git a/spec/unit/file_serving/fileset_spec.rb b/spec/unit/file_serving/fileset_spec.rb index 149c68c4a..3b12c953e 100755 --- a/spec/unit/file_serving/fileset_spec.rb +++ b/spec/unit/file_serving/fileset_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') require 'puppet/file_serving/fileset' diff --git a/spec/unit/file_serving/indirection_hooks_spec.rb b/spec/unit/file_serving/indirection_hooks_spec.rb index 683efa7c1..1c7f55da8 100755 --- a/spec/unit/file_serving/indirection_hooks_spec.rb +++ b/spec/unit/file_serving/indirection_hooks_spec.rb @@ -3,7 +3,7 @@ # Created by Luke Kanies on 2007-10-18. # Copyright (c) 2007. All rights reserved. -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') require 'puppet/file_serving/indirection_hooks' diff --git a/spec/unit/file_serving/metadata_spec.rb b/spec/unit/file_serving/metadata_spec.rb index dd40324bc..34794cca9 100755 --- a/spec/unit/file_serving/metadata_spec.rb +++ b/spec/unit/file_serving/metadata_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') require 'puppet/file_serving/metadata' diff --git a/spec/unit/file_serving/mount/file_spec.rb b/spec/unit/file_serving/mount/file_spec.rb index 56b4f54f1..792ce951c 100755 --- a/spec/unit/file_serving/mount/file_spec.rb +++ b/spec/unit/file_serving/mount/file_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') require 'puppet/file_serving/mount/file' module FileServingMountTesting diff --git a/spec/unit/file_serving/mount/modules_spec.rb b/spec/unit/file_serving/mount/modules_spec.rb index 5450b85ad..1213f4fa5 100755 --- a/spec/unit/file_serving/mount/modules_spec.rb +++ b/spec/unit/file_serving/mount/modules_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') require 'puppet/file_serving/mount/modules' describe Puppet::FileServing::Mount::Modules do diff --git a/spec/unit/file_serving/mount/plugins_spec.rb b/spec/unit/file_serving/mount/plugins_spec.rb index b48b52509..6aa9ae927 100755 --- a/spec/unit/file_serving/mount/plugins_spec.rb +++ b/spec/unit/file_serving/mount/plugins_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') require 'puppet/file_serving/mount/plugins' describe Puppet::FileServing::Mount::Plugins do diff --git a/spec/unit/file_serving/mount_spec.rb b/spec/unit/file_serving/mount_spec.rb index 6eb0d4d9f..2bfe643f6 100755 --- a/spec/unit/file_serving/mount_spec.rb +++ b/spec/unit/file_serving/mount_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') require 'puppet/file_serving/mount' describe Puppet::FileServing::Mount do diff --git a/spec/unit/file_serving/terminus_helper_spec.rb b/spec/unit/file_serving/terminus_helper_spec.rb index f46da1e1f..36cf0daf3 100755 --- a/spec/unit/file_serving/terminus_helper_spec.rb +++ b/spec/unit/file_serving/terminus_helper_spec.rb @@ -3,7 +3,7 @@ # Created by Luke Kanies on 2007-10-22. # Copyright (c) 2007. All rights reserved. -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') require 'puppet/file_serving/terminus_helper' diff --git a/spec/unit/indirector/active_record_spec.rb b/spec/unit/indirector/active_record_spec.rb index 40af146c8..4fab17da2 100755 --- a/spec/unit/indirector/active_record_spec.rb +++ b/spec/unit/indirector/active_record_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') require 'puppet/rails' require 'puppet/indirector/active_record' @@ -14,10 +14,9 @@ describe Puppet::Indirector::ActiveRecord do @indirection = stub 'indirection', :name => :mystuff, :register_terminus_type => nil, :model => @model Puppet::Indirector::Indirection.stubs(:instance).returns(@indirection) - @active_record_class = Class.new(Puppet::Indirector::ActiveRecord) do - def self.to_s - "Mystuff::Testing" - end + module Testing; end + @active_record_class = class Testing::MyActiveRecord < Puppet::Indirector::ActiveRecord + self end @ar_model = mock 'ar_model' diff --git a/spec/unit/indirector/catalog/active_record_spec.rb b/spec/unit/indirector/catalog/active_record_spec.rb index a368fb3a6..da1d77582 100755 --- a/spec/unit/indirector/catalog/active_record_spec.rb +++ b/spec/unit/indirector/catalog/active_record_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') describe "Puppet::Resource::Catalog::ActiveRecord", :if => Puppet.features.rails? do diff --git a/spec/unit/indirector/catalog/compiler_spec.rb b/spec/unit/indirector/catalog/compiler_spec.rb index 6c950b626..a2ab0c6f4 100755 --- a/spec/unit/indirector/catalog/compiler_spec.rb +++ b/spec/unit/indirector/catalog/compiler_spec.rb @@ -3,13 +3,14 @@ # Created by Luke Kanies on 2007-9-23. # Copyright (c) 2007. All rights reserved. -require File.dirname(__FILE__) + '/../../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') require 'puppet/indirector/catalog/compiler' require 'puppet/rails' describe Puppet::Resource::Catalog::Compiler do before do + require 'puppet/rails' Puppet::Rails.stubs(:init) Facter.stubs(:to_hash).returns({}) Facter.stubs(:value).returns(Facter::Util::Fact.new("something")) @@ -31,8 +32,8 @@ describe Puppet::Resource::Catalog::Compiler do node1 = stub 'node1', :merge => nil node2 = stub 'node2', :merge => nil compiler.stubs(:compile) - Puppet::Node.stubs(:find).with('node1').returns(node1) - Puppet::Node.stubs(:find).with('node2').returns(node2) + Puppet::Node.indirection.stubs(:find).with('node1').returns(node1) + Puppet::Node.indirection.stubs(:find).with('node2').returns(node2) compiler.find(stub('request', :key => 'node1', :node => 'node1', :options => {})) compiler.find(stub('node2request', :key => 'node2', :node => 'node2', :options => {})) @@ -70,12 +71,12 @@ describe Puppet::Resource::Catalog::Compiler do @name = "me" @node = Puppet::Node.new @name @node.stubs(:merge) - Puppet::Node.stubs(:find).returns @node + Puppet::Node.indirection.stubs(:find).returns @node @request = stub 'request', :key => @name, :node => @name, :options => {} end it "should directly use provided nodes" do - Puppet::Node.expects(:find).never + Puppet::Node.indirection.expects(:find).never @compiler.expects(:compile).with(@node) @request.stubs(:options).returns(:use_node => @node) @compiler.find(@request) @@ -83,7 +84,7 @@ describe Puppet::Resource::Catalog::Compiler do it "should use the authenticated node name if no request key is provided" do @request.stubs(:key).returns(nil) - Puppet::Node.expects(:find).with(@name).returns(@node) + Puppet::Node.indirection.expects(:find).with(@name).returns(@node) @compiler.expects(:compile).with(@node) @compiler.find(@request) end @@ -91,37 +92,37 @@ describe Puppet::Resource::Catalog::Compiler do it "should use the provided node name by default" do @request.expects(:key).returns "my_node" - Puppet::Node.expects(:find).with("my_node").returns @node + Puppet::Node.indirection.expects(:find).with("my_node").returns @node @compiler.expects(:compile).with(@node) @compiler.find(@request) end it "should fail if no node is passed and none can be found" do - Puppet::Node.stubs(:find).with(@name).returns(nil) + Puppet::Node.indirection.stubs(:find).with(@name).returns(nil) proc { @compiler.find(@request) }.should raise_error(ArgumentError) end it "should fail intelligently when searching for a node raises an exception" do - Puppet::Node.stubs(:find).with(@name).raises "eh" + Puppet::Node.indirection.stubs(:find).with(@name).raises "eh" proc { @compiler.find(@request) }.should raise_error(Puppet::Error) end it "should pass the found node to the compiler for compiling" do - Puppet::Node.expects(:find).with(@name).returns(@node) + Puppet::Node.indirection.expects(:find).with(@name).returns(@node) config = mock 'config' Puppet::Parser::Compiler.expects(:compile).with(@node) @compiler.find(@request) end it "should extract and save any facts from the request" do - Puppet::Node.expects(:find).with(@name).returns @node + Puppet::Node.indirection.expects(:find).with(@name).returns @node @compiler.expects(:extract_facts_from_request).with(@request) Puppet::Parser::Compiler.stubs(:compile) @compiler.find(@request) end it "should return the results of compiling as the catalog" do - Puppet::Node.stubs(:find).returns(@node) + Puppet::Node.indirection.stubs(:find).returns(@node) config = mock 'config' result = mock 'result' @@ -130,7 +131,7 @@ describe Puppet::Resource::Catalog::Compiler do end it "should benchmark the compile process" do - Puppet::Node.stubs(:find).returns(@node) + Puppet::Node.indirection.stubs(:find).returns(@node) @compiler.stubs(:networked?).returns(true) @compiler.expects(:benchmark).with do |level, message| level == :notice and message =~ /^Compiled catalog/ @@ -140,7 +141,7 @@ describe Puppet::Resource::Catalog::Compiler do end it "should log the benchmark result" do - Puppet::Node.stubs(:find).returns(@node) + Puppet::Node.indirection.stubs(:find).returns(@node) @compiler.stubs(:networked?).returns(true) Puppet::Parser::Compiler.stubs(:compile) @@ -156,22 +157,28 @@ describe Puppet::Resource::Catalog::Compiler do @compiler = Puppet::Resource::Catalog::Compiler.new @request = stub 'request', :options => {} - @facts = stub 'facts', :save => nil + @facts = Puppet::Node::Facts.new('hostname', "fact" => "value", "architecture" => "i386") + Puppet::Node::Facts.indirection.stubs(:save).returns(nil) end it "should do nothing if no facts are provided" do - Puppet::Node::Facts.expects(:convert_from).never + Puppet::Node::Facts.indirection.expects(:convert_from).never @request.options[:facts] = nil @compiler.extract_facts_from_request(@request) end - it "should use the Facts class to deserialize the provided facts" do + it "should use the Facts class to deserialize the provided facts and update the timestamp" do @request.options[:facts_format] = "foo" @request.options[:facts] = "bar" Puppet::Node::Facts.expects(:convert_from).returns @facts + @facts.timestamp = Time.parse('2010-11-01') + @now = Time.parse('2010-11-02') + Time.expects(:now).returns(@now) + @compiler.extract_facts_from_request(@request) + @facts.timestamp.should == @now end it "should use the provided fact format" do @@ -187,7 +194,7 @@ describe Puppet::Resource::Catalog::Compiler do @request.options[:facts] = "bar" Puppet::Node::Facts.expects(:convert_from).returns @facts - @facts.expects(:save) + Puppet::Node::Facts.indirection.expects(:save).with(@facts) @compiler.extract_facts_from_request(@request) end @@ -205,7 +212,7 @@ describe Puppet::Resource::Catalog::Compiler do it "should look node information up via the Node class with the provided key" do @node.stubs :merge - Puppet::Node.expects(:find).with(@name).returns(@node) + Puppet::Node.indirection.expects(:find).with(@name).returns(@node) @compiler.find(@request) end end @@ -220,7 +227,7 @@ describe Puppet::Resource::Catalog::Compiler do @node = mock 'node' @request = stub 'request', :key => @name, :options => {} @compiler.stubs(:compile) - Puppet::Node.stubs(:find).with(@name).returns(@node) + Puppet::Node.indirection.stubs(:find).with(@name).returns(@node) end it "should add the server's Puppet version to the node's parameters as 'serverversion'" do diff --git a/spec/unit/indirector/catalog/queue_spec.rb b/spec/unit/indirector/catalog/queue_spec.rb index 38d40c94a..866113631 100755 --- a/spec/unit/indirector/catalog/queue_spec.rb +++ b/spec/unit/indirector/catalog/queue_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') require 'puppet/indirector/catalog/queue' diff --git a/spec/unit/indirector/catalog/rest_spec.rb b/spec/unit/indirector/catalog/rest_spec.rb index d61054e16..c887504a2 100755 --- a/spec/unit/indirector/catalog/rest_spec.rb +++ b/spec/unit/indirector/catalog/rest_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') require 'puppet/indirector/catalog/rest' diff --git a/spec/unit/indirector/catalog/yaml_spec.rb b/spec/unit/indirector/catalog/yaml_spec.rb index 5a30b8268..3bf5b4640 100755 --- a/spec/unit/indirector/catalog/yaml_spec.rb +++ b/spec/unit/indirector/catalog/yaml_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') require 'puppet/resource/catalog' require 'puppet/indirector/catalog/yaml' diff --git a/spec/unit/indirector/certificate/ca_spec.rb b/spec/unit/indirector/certificate/ca_spec.rb index 6bf3e26ee..77384ddb8 100755 --- a/spec/unit/indirector/certificate/ca_spec.rb +++ b/spec/unit/indirector/certificate/ca_spec.rb @@ -3,7 +3,7 @@ # Created by Luke Kanies on 2008-3-7. # Copyright (c) 2007. All rights reserved. -require File.dirname(__FILE__) + '/../../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') require 'puppet/indirector/certificate/ca' diff --git a/spec/unit/indirector/certificate/file_spec.rb b/spec/unit/indirector/certificate/file_spec.rb index 6a8e7d8f4..45dd95cb5 100755 --- a/spec/unit/indirector/certificate/file_spec.rb +++ b/spec/unit/indirector/certificate/file_spec.rb @@ -3,7 +3,7 @@ # Created by Luke Kanies on 2008-3-7. # Copyright (c) 2007. All rights reserved. -require File.dirname(__FILE__) + '/../../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') require 'puppet/indirector/certificate/file' diff --git a/spec/unit/indirector/certificate/rest_spec.rb b/spec/unit/indirector/certificate/rest_spec.rb index 77b2a67bd..8fd6bff9a 100755 --- a/spec/unit/indirector/certificate/rest_spec.rb +++ b/spec/unit/indirector/certificate/rest_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') require 'puppet/indirector/certificate/rest' diff --git a/spec/unit/indirector/certificate_request/ca_spec.rb b/spec/unit/indirector/certificate_request/ca_spec.rb index 1bcbc46df..8c25e40f7 100755 --- a/spec/unit/indirector/certificate_request/ca_spec.rb +++ b/spec/unit/indirector/certificate_request/ca_spec.rb @@ -3,7 +3,7 @@ # Created by Luke Kanies on 2008-3-7. # Copyright (c) 2007. All rights reserved. -require File.dirname(__FILE__) + '/../../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') require 'puppet/indirector/certificate_request/ca' diff --git a/spec/unit/indirector/certificate_request/file_spec.rb b/spec/unit/indirector/certificate_request/file_spec.rb index f18ba2ca8..465d55d3c 100755 --- a/spec/unit/indirector/certificate_request/file_spec.rb +++ b/spec/unit/indirector/certificate_request/file_spec.rb @@ -3,7 +3,7 @@ # Created by Luke Kanies on 2008-3-7. # Copyright (c) 2007. All rights reserved. -require File.dirname(__FILE__) + '/../../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') require 'puppet/indirector/certificate_request/file' diff --git a/spec/unit/indirector/certificate_request/rest_spec.rb b/spec/unit/indirector/certificate_request/rest_spec.rb index 8b90b46a9..9a8b87439 100755 --- a/spec/unit/indirector/certificate_request/rest_spec.rb +++ b/spec/unit/indirector/certificate_request/rest_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') require 'puppet/indirector/certificate_request/rest' diff --git a/spec/unit/indirector/certificate_revocation_list/ca_spec.rb b/spec/unit/indirector/certificate_revocation_list/ca_spec.rb index 756185da9..d72a3bb10 100755 --- a/spec/unit/indirector/certificate_revocation_list/ca_spec.rb +++ b/spec/unit/indirector/certificate_revocation_list/ca_spec.rb @@ -3,7 +3,7 @@ # Created by Luke Kanies on 2008-3-7. # Copyright (c) 2007. All rights reserved. -require File.dirname(__FILE__) + '/../../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') require 'puppet/indirector/certificate_revocation_list/ca' diff --git a/spec/unit/indirector/certificate_revocation_list/file_spec.rb b/spec/unit/indirector/certificate_revocation_list/file_spec.rb index 507942a6a..3284bee35 100755 --- a/spec/unit/indirector/certificate_revocation_list/file_spec.rb +++ b/spec/unit/indirector/certificate_revocation_list/file_spec.rb @@ -3,7 +3,7 @@ # Created by Luke Kanies on 2008-3-7. # Copyright (c) 2007. All rights reserved. -require File.dirname(__FILE__) + '/../../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') require 'puppet/indirector/certificate_revocation_list/file' diff --git a/spec/unit/indirector/certificate_revocation_list/rest_spec.rb b/spec/unit/indirector/certificate_revocation_list/rest_spec.rb index 8cb32632e..e47a0848c 100755 --- a/spec/unit/indirector/certificate_revocation_list/rest_spec.rb +++ b/spec/unit/indirector/certificate_revocation_list/rest_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') require 'puppet/indirector/certificate_revocation_list/rest' diff --git a/spec/unit/indirector/certificate_status/file_spec.rb b/spec/unit/indirector/certificate_status/file_spec.rb new file mode 100644 index 000000000..6cc0bb547 --- /dev/null +++ b/spec/unit/indirector/certificate_status/file_spec.rb @@ -0,0 +1,188 @@ +#!/usr/bin/env ruby + +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper.rb') +require 'puppet/ssl/host' +require 'puppet/indirector/certificate_status' +require 'tempfile' + +describe "Puppet::Indirector::CertificateStatus::File" do + include PuppetSpec::Files + + before do + Puppet::SSL::CertificateAuthority.stubs(:ca?).returns true + @terminus = Puppet::SSL::Host.indirection.terminus(:file) + + @tmpdir = tmpdir("certificate_status_ca_testing") + Puppet[:confdir] = @tmpdir + Puppet[:vardir] = @tmpdir + + # localcacert is where each client stores the CA certificate + # cacert is where the master stores the CA certificate + # Since we need to play the role of both for testing we need them to be the same and exist + Puppet[:cacert] = Puppet[:localcacert] + end + + def generate_csr(host) + host.generate_key + csr = Puppet::SSL::CertificateRequest.new(host.name) + csr.generate(host.key.content) + Puppet::SSL::CertificateRequest.indirection.save(csr) + end + + def sign_csr(host) + host.desired_state = "signed" + @terminus.save(Puppet::Indirector::Request.new(:certificate_status, :save, host.name, host)) + end + + def generate_signed_cert(host) + generate_csr(host) + sign_csr(host) + + @terminus.find(Puppet::Indirector::Request.new(:certificate_status, :find, host.name, host)) + end + + def generate_revoked_cert(host) + generate_signed_cert(host) + + host.desired_state = "revoked" + + @terminus.save(Puppet::Indirector::Request.new(:certificate_status, :save, host.name, host)) + end + + it "should be a terminus on SSL::Host" do + @terminus.should be_instance_of(Puppet::Indirector::CertificateStatus::File) + end + + it "should create a CA instance if none is present" do + @terminus.ca.should be_instance_of(Puppet::SSL::CertificateAuthority) + end + + describe "when creating the CA" do + it "should fail if it is not a valid CA" do + Puppet::SSL::CertificateAuthority.expects(:ca?).returns false + lambda { @terminus.ca }.should raise_error(ArgumentError, "This process is not configured as a certificate authority") + end + end + + it "should be indirected with the name 'certificate_status'" do + Puppet::SSL::Host.indirection.name.should == :certificate_status + end + + describe "when finding" do + before do + @host = Puppet::SSL::Host.new("foo") + Puppet.settings.use(:main) + end + + it "should return the Puppet::SSL::Host when a CSR exists for the host" do + generate_csr(@host) + request = Puppet::Indirector::Request.new(:certificate_status, :find, "foo", @host) + + retrieved_host = @terminus.find(request) + + retrieved_host.name.should == @host.name + retrieved_host.certificate_request.content.to_s.chomp.should == @host.certificate_request.content.to_s.chomp + end + + it "should return the Puppet::SSL::Host when a public key exist for the host" do + generate_signed_cert(@host) + request = Puppet::Indirector::Request.new(:certificate_status, :find, "foo", @host) + + retrieved_host = @terminus.find(request) + + retrieved_host.name.should == @host.name + retrieved_host.certificate.content.to_s.chomp.should == @host.certificate.content.to_s.chomp + end + + it "should return nil when neither a CSR nor public key exist for the host" do + request = Puppet::Indirector::Request.new(:certificate_status, :find, "foo", @host) + @terminus.find(request).should == nil + end + end + + describe "when saving" do + before do + @host = Puppet::SSL::Host.new("foobar") + Puppet.settings.use(:main) + end + + describe "when signing a cert" do + before do + @host.desired_state = "signed" + @request = Puppet::Indirector::Request.new(:certificate_status, :save, "foobar", @host) + end + + it "should fail if no CSR is on disk" do + lambda { @terminus.save(@request) }.should raise_error(Puppet::Error, /certificate request/) + end + + it "should sign the on-disk CSR when it is present" do + signed_host = generate_signed_cert(@host) + + signed_host.state.should == "signed" + Puppet::SSL::Certificate.indirection.find("foobar").should be_instance_of(Puppet::SSL::Certificate) + end + end + + describe "when revoking a cert" do + before do + @request = Puppet::Indirector::Request.new(:certificate_status, :save, "foobar", @host) + end + + it "should fail if no certificate is on disk" do + @host.desired_state = "revoked" + lambda { @terminus.save(@request) }.should raise_error(Puppet::Error, /Cannot revoke/) + end + + it "should revoke the certificate when it is present" do + generate_revoked_cert(@host) + + @host.state.should == 'revoked' + end + end + end + + describe "when deleting" do + before do + Puppet.settings.use(:main) + end + + it "should not delete anything if no certificate, request, or key is on disk" do + host = Puppet::SSL::Host.new("clean_me") + request = Puppet::Indirector::Request.new(:certificate_status, :delete, "clean_me", host) + @terminus.destroy(request).should == "Nothing was deleted" + end + + it "should clean certs, cert requests, keys" do + signed_host = Puppet::SSL::Host.new("clean_signed_cert") + generate_signed_cert(signed_host) + signed_request = Puppet::Indirector::Request.new(:certificate_status, :delete, "clean_signed_cert", signed_host) + @terminus.destroy(signed_request).should == "Deleted for clean_signed_cert: Puppet::SSL::Certificate, Puppet::SSL::Key" + + requested_host = Puppet::SSL::Host.new("clean_csr") + generate_csr(requested_host) + csr_request = Puppet::Indirector::Request.new(:certificate_status, :delete, "clean_csr", requested_host) + @terminus.destroy(csr_request).should == "Deleted for clean_csr: Puppet::SSL::CertificateRequest, Puppet::SSL::Key" + end + end + + describe "when searching" do + it "should return a list of all hosts with certificate requests, signed certs, or revoked certs" do + Puppet.settings.use(:main) + + signed_host = Puppet::SSL::Host.new("signed_host") + generate_signed_cert(signed_host) + + requested_host = Puppet::SSL::Host.new("requested_host") + generate_csr(requested_host) + + revoked_host = Puppet::SSL::Host.new("revoked_host") + generate_revoked_cert(revoked_host) + + retrieved_hosts = @terminus.search(Puppet::Indirector::Request.new(:certificate_status, :search, "all", signed_host)) + + results = retrieved_hosts.map {|h| [h.name, h.state]}.sort{ |h,i| h[0] <=> i[0] } + results.should == [["ca","signed"],["requested_host","requested"],["revoked_host","revoked"],["signed_host","signed"]] + end + end +end diff --git a/spec/unit/indirector/certificate_status/rest_spec.rb b/spec/unit/indirector/certificate_status/rest_spec.rb new file mode 100644 index 000000000..f44eac671 --- /dev/null +++ b/spec/unit/indirector/certificate_status/rest_spec.rb @@ -0,0 +1,15 @@ +#!/usr/bin/env ruby + +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper.rb') +require 'puppet/ssl/host' +require 'puppet/indirector/certificate_status' + +describe "Puppet::CertificateStatus::Rest" do + before do + @terminus = Puppet::SSL::Host.indirection.terminus(:rest) + end + + it "should be a terminus on Puppet::SSL::Host" do + @terminus.should be_instance_of(Puppet::Indirector::CertificateStatus::Rest) + end +end diff --git a/spec/unit/indirector/code_spec.rb b/spec/unit/indirector/code_spec.rb index 916469a14..1c9e4d2f1 100755 --- a/spec/unit/indirector/code_spec.rb +++ b/spec/unit/indirector/code_spec.rb @@ -1,19 +1,18 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') require 'puppet/indirector/code' describe Puppet::Indirector::Code do - before do + before :all do Puppet::Indirector::Terminus.stubs(:register_terminus_class) @model = mock 'model' @indirection = stub 'indirection', :name => :mystuff, :register_terminus_type => nil, :model => @model Puppet::Indirector::Indirection.stubs(:instance).returns(@indirection) - @code_class = Class.new(Puppet::Indirector::Code) do - def self.to_s - "Mystuff::Testing" - end + module Testing; end + @code_class = class Testing::MyCode < Puppet::Indirector::Code + self end @searcher = @code_class.new diff --git a/spec/unit/indirector/direct_file_server_spec.rb b/spec/unit/indirector/direct_file_server_spec.rb index 0111b5445..5d9af626f 100755 --- a/spec/unit/indirector/direct_file_server_spec.rb +++ b/spec/unit/indirector/direct_file_server_spec.rb @@ -3,21 +3,20 @@ # Created by Luke Kanies on 2007-10-24. # Copyright (c) 2007. All rights reserved. -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') require 'puppet/indirector/direct_file_server' describe Puppet::Indirector::DirectFileServer do - before :each do + before :all do Puppet::Indirector::Terminus.stubs(:register_terminus_class) @model = mock 'model' @indirection = stub 'indirection', :name => :mystuff, :register_terminus_type => nil, :model => @model Puppet::Indirector::Indirection.stubs(:instance).returns(@indirection) - @direct_file_class = Class.new(Puppet::Indirector::DirectFileServer) do - def self.to_s - "Testing::Mytype" - end + module Testing; end + @direct_file_class = class Testing::Mytype < Puppet::Indirector::DirectFileServer + self end @server = @direct_file_class.new diff --git a/spec/unit/indirector/envelope_spec.rb b/spec/unit/indirector/envelope_spec.rb index fb80824c9..2715a2671 100755 --- a/spec/unit/indirector/envelope_spec.rb +++ b/spec/unit/indirector/envelope_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') require 'puppet/indirector/envelope' describe Puppet::Indirector::Envelope do diff --git a/spec/unit/indirector/exec_spec.rb b/spec/unit/indirector/exec_spec.rb index de37f2775..5abb00ae9 100755 --- a/spec/unit/indirector/exec_spec.rb +++ b/spec/unit/indirector/exec_spec.rb @@ -1,21 +1,21 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') require 'puppet/indirector/exec' describe Puppet::Indirector::Exec do - before do + before :all do @indirection = stub 'indirection', :name => :testing Puppet::Indirector::Indirection.expects(:instance).with(:testing).returns(@indirection) - @exec_class = Class.new(Puppet::Indirector::Exec) do - def self.to_s - "Testing::Mytype" - end - + module Testing; end + @exec_class = class Testing::MyTesting < Puppet::Indirector::Exec attr_accessor :command + self end + end + before :each do @searcher = @exec_class.new @searcher.command = ["/echo"] diff --git a/spec/unit/indirector/facts/active_record_spec.rb b/spec/unit/indirector/facts/active_record_spec.rb index e96e01056..71e19e3ca 100755 --- a/spec/unit/indirector/facts/active_record_spec.rb +++ b/spec/unit/indirector/facts/active_record_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') require 'puppet/rails' require 'puppet/node/facts' diff --git a/spec/unit/indirector/facts/couch_spec.rb b/spec/unit/indirector/facts/couch_spec.rb index e3a9d7f14..1f86b56f2 100644 --- a/spec/unit/indirector/facts/couch_spec.rb +++ b/spec/unit/indirector/facts/couch_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') require 'puppet/node/facts' diff --git a/spec/unit/indirector/facts/facter_spec.rb b/spec/unit/indirector/facts/facter_spec.rb index 169440915..3129f5ebf 100755 --- a/spec/unit/indirector/facts/facter_spec.rb +++ b/spec/unit/indirector/facts/facter_spec.rb @@ -3,7 +3,7 @@ # Created by Luke Kanies on 2007-9-23. # Copyright (c) 2007. All rights reserved. -require File.dirname(__FILE__) + '/../../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') require 'puppet/indirector/facts/facter' diff --git a/spec/unit/indirector/facts/inventory_active_record_spec.rb b/spec/unit/indirector/facts/inventory_active_record_spec.rb index 9558abde2..43b9fa397 100644 --- a/spec/unit/indirector/facts/inventory_active_record_spec.rb +++ b/spec/unit/indirector/facts/inventory_active_record_spec.rb @@ -20,7 +20,7 @@ describe "Puppet::Node::Facts::InventoryActiveRecord", :if => (Puppet.features.r end before :each do - Puppet::Node::Facts.terminus_class = :inventory_active_record + Puppet::Node::Facts.indirection.terminus_class = :inventory_active_record Puppet[:dbadapter] = 'sqlite3' Puppet[:dblocation] = @dbfile.path Puppet[:railslog] = "/dev/null" @@ -35,7 +35,8 @@ describe "Puppet::Node::Facts::InventoryActiveRecord", :if => (Puppet.features.r it "should use an existing node if possible" do node = Puppet::Rails::InventoryNode.new(:name => "foo", :timestamp => Time.now) node.save - Puppet::Node::Facts.new("foo", "uptime_days" => "60", "kernel" => "Darwin").save + facts = Puppet::Node::Facts.new("foo", "uptime_days" => "60", "kernel" => "Darwin") + Puppet::Node::Facts.indirection.save(facts) Puppet::Rails::InventoryNode.count.should == 1 Puppet::Rails::InventoryNode.first.should == node @@ -45,27 +46,30 @@ describe "Puppet::Node::Facts::InventoryActiveRecord", :if => (Puppet.features.r # This test isn't valid if there are nodes to begin with Puppet::Rails::InventoryNode.count.should == 0 - Puppet::Node::Facts.new("foo", "uptime_days" => "60", "kernel" => "Darwin").save + facts = Puppet::Node::Facts.new("foo", "uptime_days" => "60", "kernel" => "Darwin") + Puppet::Node::Facts.indirection.save(facts) Puppet::Rails::InventoryNode.count.should == 1 Puppet::Rails::InventoryNode.first.name.should == "foo" end it "should save the facts" do - Puppet::Node::Facts.new("foo", "uptime_days" => "60", "kernel" => "Darwin").save + facts = Puppet::Node::Facts.new("foo", "uptime_days" => "60", "kernel" => "Darwin") + Puppet::Node::Facts.indirection.save(facts) Puppet::Rails::InventoryFact.all.map{|f| [f.name,f.value]}.should =~ [["uptime_days","60"],["kernel","Darwin"]] end it "should remove the previous facts for an existing node" do - Puppet::Node::Facts.new("foo", "uptime_days" => "30", "kernel" => "Darwin").save + facts = Puppet::Node::Facts.new("foo", "uptime_days" => "30", "kernel" => "Darwin") + Puppet::Node::Facts.indirection.save(facts) bar_facts = Puppet::Node::Facts.new("bar", "uptime_days" => "35", "kernel" => "Linux") foo_facts = Puppet::Node::Facts.new("foo", "uptime_days" => "60", "is_virtual" => "false") - bar_facts.save - foo_facts.save + Puppet::Node::Facts.indirection.save(bar_facts) + Puppet::Node::Facts.indirection.save(foo_facts) - Puppet::Node::Facts.find("bar").should == bar_facts - Puppet::Node::Facts.find("foo").should == foo_facts + Puppet::Node::Facts.indirection.find("bar").should == bar_facts + Puppet::Node::Facts.indirection.find("foo").should == foo_facts Puppet::Rails::InventoryFact.all.map{|f| [f.name,f.value]}.should_not include(["uptime_days", "30"], ["kernel", "Darwin"]) end end @@ -74,16 +78,16 @@ describe "Puppet::Node::Facts::InventoryActiveRecord", :if => (Puppet.features.r before do @foo_facts = Puppet::Node::Facts.new("foo", "uptime_days" => "60", "kernel" => "Darwin") @bar_facts = Puppet::Node::Facts.new("bar", "uptime_days" => "30", "kernel" => "Linux") - @foo_facts.save - @bar_facts.save + Puppet::Node::Facts.indirection.save(@foo_facts) + Puppet::Node::Facts.indirection.save(@bar_facts) end it "should identify facts by node name" do - Puppet::Node::Facts.find("foo").should == @foo_facts + Puppet::Node::Facts.indirection.find("foo").should == @foo_facts end it "should return nil if no node instance can be found" do - Puppet::Node::Facts.find("non-existent node").should == nil + Puppet::Node::Facts.indirection.find("non-existent node").should == nil end end @@ -102,10 +106,7 @@ describe "Puppet::Node::Facts::InventoryActiveRecord", :if => (Puppet.features.r @bar.timestamp = @now - 3600*3 @baz.timestamp = @now - 3600*5 @bat.timestamp = @now - 3600*7 - @foo.save - @bar.save - @baz.save - @bat.save + [@foo, @bar, @baz, @bat].each {|facts| Puppet::Node::Facts.indirection.save(facts)} end it "should return node names that match 'equal' constraints" do diff --git a/spec/unit/indirector/facts/rest_spec.rb b/spec/unit/indirector/facts/rest_spec.rb index 19a56921f..03bef4578 100755 --- a/spec/unit/indirector/facts/rest_spec.rb +++ b/spec/unit/indirector/facts/rest_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') require 'puppet/indirector/facts/rest' diff --git a/spec/unit/indirector/facts/yaml_spec.rb b/spec/unit/indirector/facts/yaml_spec.rb index c625c8ee3..c266df18f 100755 --- a/spec/unit/indirector/facts/yaml_spec.rb +++ b/spec/unit/indirector/facts/yaml_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') require 'puppet/node/facts' require 'puppet/indirector/facts/yaml' diff --git a/spec/unit/indirector/file_bucket_file/file_spec.rb b/spec/unit/indirector/file_bucket_file/file_spec.rb index 0c33593d7..1423cb2e3 100755 --- a/spec/unit/indirector/file_bucket_file/file_spec.rb +++ b/spec/unit/indirector/file_bucket_file/file_spec.rb @@ -24,7 +24,7 @@ describe Puppet::FileBucketFile::File do def save_bucket_file(contents, path = "/who_cares") bucket_file = Puppet::FileBucket::File.new(contents) - bucket_file.save("md5/#{Digest::MD5.hexdigest(contents)}#{path}") + Puppet::FileBucket::File.indirection.save(bucket_file, "md5/#{Digest::MD5.hexdigest(contents)}#{path}") bucket_file.checksum_data end @@ -67,21 +67,21 @@ describe Puppet::FileBucketFile::File do describe "when servicing a head/find request" do describe "when supplying a path" do it "should return false/nil if the file isn't bucketed" do - Puppet::FileBucket::File.head("md5/0ae2ec1980410229885fe72f7b44fe55/foo/bar").should == false - Puppet::FileBucket::File.find("md5/0ae2ec1980410229885fe72f7b44fe55/foo/bar").should == nil + Puppet::FileBucket::File.indirection.head("md5/0ae2ec1980410229885fe72f7b44fe55/foo/bar").should == false + Puppet::FileBucket::File.indirection.find("md5/0ae2ec1980410229885fe72f7b44fe55/foo/bar").should == nil end it "should return false/nil if the file is bucketed but with a different path" do checksum = save_bucket_file("I'm the contents of a file", '/foo/bar') - Puppet::FileBucket::File.head("md5/#{checksum}/foo/baz").should == false - Puppet::FileBucket::File.find("md5/#{checksum}/foo/baz").should == nil + Puppet::FileBucket::File.indirection.head("md5/#{checksum}/foo/baz").should == false + Puppet::FileBucket::File.indirection.find("md5/#{checksum}/foo/baz").should == nil end it "should return true/file if the file is already bucketed with the given path" do contents = "I'm the contents of a file" checksum = save_bucket_file(contents, '/foo/bar') - Puppet::FileBucket::File.head("md5/#{checksum}/foo/bar").should == true - find_result = Puppet::FileBucket::File.find("md5/#{checksum}/foo/bar") + Puppet::FileBucket::File.indirection.head("md5/#{checksum}/foo/bar").should == true + find_result = Puppet::FileBucket::File.indirection.find("md5/#{checksum}/foo/bar") find_result.should be_a(Puppet::FileBucket::File) find_result.checksum.should == "{md5}#{checksum}" find_result.to_s.should == contents @@ -94,15 +94,15 @@ describe Puppet::FileBucketFile::File do trailing_string = trailing_slash ? '/' : '' it "should return false/nil if the file isn't bucketed" do - Puppet::FileBucket::File.head("md5/0ae2ec1980410229885fe72f7b44fe55#{trailing_string}").should == false - Puppet::FileBucket::File.find("md5/0ae2ec1980410229885fe72f7b44fe55#{trailing_string}").should == nil + Puppet::FileBucket::File.indirection.head("md5/0ae2ec1980410229885fe72f7b44fe55#{trailing_string}").should == false + Puppet::FileBucket::File.indirection.find("md5/0ae2ec1980410229885fe72f7b44fe55#{trailing_string}").should == nil end it "should return true/file if the file is already bucketed" do contents = "I'm the contents of a file" checksum = save_bucket_file(contents, '/foo/bar') - Puppet::FileBucket::File.head("md5/#{checksum}#{trailing_string}").should == true - find_result = Puppet::FileBucket::File.find("md5/#{checksum}#{trailing_string}") + Puppet::FileBucket::File.indirection.head("md5/#{checksum}#{trailing_string}").should == true + find_result = Puppet::FileBucket::File.indirection.find("md5/#{checksum}#{trailing_string}") find_result.should be_a(Puppet::FileBucket::File) find_result.checksum.should == "{md5}#{checksum}" find_result.to_s.should == contents @@ -115,13 +115,13 @@ describe Puppet::FileBucketFile::File do describe "when diffing files" do it "should generate an empty string if there is no diff" do checksum = save_bucket_file("I'm the contents of a file") - Puppet::FileBucket::File.find("md5/#{checksum}", :diff_with => checksum).should == '' + Puppet::FileBucket::File.indirection.find("md5/#{checksum}", :diff_with => checksum).should == '' end it "should generate a proper diff if there is a diff" do checksum1 = save_bucket_file("foo\nbar\nbaz") checksum2 = save_bucket_file("foo\nbiz\nbaz") - diff = Puppet::FileBucket::File.find("md5/#{checksum1}", :diff_with => checksum2) + diff = Puppet::FileBucket::File.indirection.find("md5/#{checksum1}", :diff_with => checksum2) diff.should == <<HERE 2c2 < bar @@ -133,13 +133,13 @@ HERE it "should raise an exception if the hash to diff against isn't found" do checksum = save_bucket_file("whatever") bogus_checksum = "d1bf072d0e2c6e20e3fbd23f022089a1" - lambda { Puppet::FileBucket::File.find("md5/#{checksum}", :diff_with => bogus_checksum) }.should raise_error "could not find diff_with #{bogus_checksum}" + lambda { Puppet::FileBucket::File.indirection.find("md5/#{checksum}", :diff_with => bogus_checksum) }.should raise_error "could not find diff_with #{bogus_checksum}" end it "should return nil if the hash to diff from isn't found" do checksum = save_bucket_file("whatever") bogus_checksum = "d1bf072d0e2c6e20e3fbd23f022089a1" - Puppet::FileBucket::File.find("md5/#{bogus_checksum}", :diff_with => checksum).should == nil + Puppet::FileBucket::File.indirection.find("md5/#{bogus_checksum}", :diff_with => checksum).should == nil end end end diff --git a/spec/unit/indirector/file_bucket_file/rest_spec.rb b/spec/unit/indirector/file_bucket_file/rest_spec.rb index 960f60ae7..d0f714751 100755 --- a/spec/unit/indirector/file_bucket_file/rest_spec.rb +++ b/spec/unit/indirector/file_bucket_file/rest_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -Dir.chdir(File.dirname(__FILE__)) { (s = lambda { |f| File.exist?(f) ? require(f) : Dir.chdir("..") { s.call(f) } }).call("spec/spec_helper.rb") } +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') require 'puppet/indirector/file_bucket_file/rest' diff --git a/spec/unit/indirector/file_content/file_server_spec.rb b/spec/unit/indirector/file_content/file_server_spec.rb index 326a8c863..5bd88132c 100755 --- a/spec/unit/indirector/file_content/file_server_spec.rb +++ b/spec/unit/indirector/file_content/file_server_spec.rb @@ -3,7 +3,7 @@ # Created by Luke Kanies on 2007-10-18. # Copyright (c) 2007. All rights reserved. -require File.dirname(__FILE__) + '/../../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') require 'puppet/indirector/file_content/file_server' diff --git a/spec/unit/indirector/file_content/file_spec.rb b/spec/unit/indirector/file_content/file_spec.rb index 62c28632e..edead1c70 100755 --- a/spec/unit/indirector/file_content/file_spec.rb +++ b/spec/unit/indirector/file_content/file_spec.rb @@ -3,7 +3,7 @@ # Created by Luke Kanies on 2007-10-18. # Copyright (c) 2007. All rights reserved. -require File.dirname(__FILE__) + '/../../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') require 'puppet/indirector/file_content/file' diff --git a/spec/unit/indirector/file_content/rest_spec.rb b/spec/unit/indirector/file_content/rest_spec.rb index 3b2f43f13..cf94d2ffd 100755 --- a/spec/unit/indirector/file_content/rest_spec.rb +++ b/spec/unit/indirector/file_content/rest_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') require 'puppet/indirector/file_content' diff --git a/spec/unit/indirector/file_metadata/file_server_spec.rb b/spec/unit/indirector/file_metadata/file_server_spec.rb index 98f89c57d..99eb83d7f 100755 --- a/spec/unit/indirector/file_metadata/file_server_spec.rb +++ b/spec/unit/indirector/file_metadata/file_server_spec.rb @@ -3,7 +3,7 @@ # Created by Luke Kanies on 2007-10-18. # Copyright (c) 2007. All rights reserved. -require File.dirname(__FILE__) + '/../../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') require 'puppet/indirector/file_metadata/file_server' diff --git a/spec/unit/indirector/file_metadata/file_spec.rb b/spec/unit/indirector/file_metadata/file_spec.rb index 906b24b3e..74eff5b66 100755 --- a/spec/unit/indirector/file_metadata/file_spec.rb +++ b/spec/unit/indirector/file_metadata/file_spec.rb @@ -3,7 +3,7 @@ # Created by Luke Kanies on 2007-10-18. # Copyright (c) 2007. All rights reserved. -require File.dirname(__FILE__) + '/../../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') require 'puppet/indirector/file_metadata/file' diff --git a/spec/unit/indirector/file_metadata/rest_spec.rb b/spec/unit/indirector/file_metadata/rest_spec.rb index f6e998300..132d90d4f 100755 --- a/spec/unit/indirector/file_metadata/rest_spec.rb +++ b/spec/unit/indirector/file_metadata/rest_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') require 'puppet/indirector/file_metadata' diff --git a/spec/unit/indirector/file_server_spec.rb b/spec/unit/indirector/file_server_spec.rb index eafcf2bb7..079eba0ae 100755 --- a/spec/unit/indirector/file_server_spec.rb +++ b/spec/unit/indirector/file_server_spec.rb @@ -3,25 +3,26 @@ # Created by Luke Kanies on 2007-10-19. # Copyright (c) 2007. All rights reserved. -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') require 'puppet/indirector/file_server' require 'puppet/file_serving/configuration' describe Puppet::Indirector::FileServer do - before :each do + before :all do Puppet::Indirector::Terminus.stubs(:register_terminus_class) @model = mock 'model' @indirection = stub 'indirection', :name => :mystuff, :register_terminus_type => nil, :model => @model Puppet::Indirector::Indirection.stubs(:instance).returns(@indirection) - @file_server_class = Class.new(Puppet::Indirector::FileServer) do - def self.to_s - "Testing::Mytype" - end + module Testing; end + @file_server_class = class Testing::MyFileServer < Puppet::Indirector::FileServer + self end + end + before :each do @file_server = @file_server_class.new @uri = "puppet://host/my/local/file" diff --git a/spec/unit/indirector/file_spec.rb b/spec/unit/indirector/file_spec.rb index 86673f0e2..96d5b2ae7 100755 --- a/spec/unit/indirector/file_spec.rb +++ b/spec/unit/indirector/file_spec.rb @@ -1,20 +1,19 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') require 'puppet/indirector/file' describe Puppet::Indirector::File do - before :each do + before :all do Puppet::Indirector::Terminus.stubs(:register_terminus_class) @model = mock 'model' @indirection = stub 'indirection', :name => :mystuff, :register_terminus_type => nil, :model => @model Puppet::Indirector::Indirection.stubs(:instance).returns(@indirection) - @file_class = Class.new(Puppet::Indirector::File) do - def self.to_s - "Testing::Mytype" - end + module Testing; end + @file_class = class Testing::MyFile < Puppet::Indirector::File + self end @searcher = @file_class.new diff --git a/spec/unit/indirector/indirection_spec.rb b/spec/unit/indirector/indirection_spec.rb index a910cb6f2..8795ae795 100755 --- a/spec/unit/indirector/indirection_spec.rb +++ b/spec/unit/indirector/indirection_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') require 'puppet/indirector/indirection' @@ -455,9 +455,6 @@ describe Puppet::Indirector::Indirection do describe "and storing a model instance" do before { @method = :save } - it_should_behave_like "Indirection Delegator" - it_should_behave_like "Delegation Authorizer" - it "should return the result of the save" do @terminus.stubs(:save).returns "foo" @indirection.save(@instance).should == "foo" diff --git a/spec/unit/indirector/inventory/yaml_spec.rb b/spec/unit/indirector/inventory/yaml_spec.rb new file mode 100644 index 000000000..a4eb2ab7a --- /dev/null +++ b/spec/unit/indirector/inventory/yaml_spec.rb @@ -0,0 +1,221 @@ +#!/usr/bin/env ruby + +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') + +require 'puppet/node/inventory' +require 'puppet/indirector/inventory/yaml' +require 'puppet/indirector/request' + +describe Puppet::Node::Inventory::Yaml do + def assert_search_matches(matching, nonmatching, query) + request = Puppet::Indirector::Request.new(:inventory, :search, nil, query) + + Dir.stubs(:glob).returns(matching.keys + nonmatching.keys) + [matching, nonmatching].each do |examples| + examples.each do |key, value| + YAML.stubs(:load_file).with(key).returns value + end + end + Puppet::Node::Inventory::Yaml.new.search(request).should =~ matching.values.map {|facts| facts.name} + end + + it "should return node names that match the search query options" do + assert_search_matches({ + '/path/to/matching.yaml' => Puppet::Node::Facts.new("matchingnode", "architecture" => "i386", 'processor_count' => '4'), + '/path/to/matching1.yaml' => Puppet::Node::Facts.new("matchingnode1", "architecture" => "i386", 'processor_count' => '4', 'randomfact' => 'foo') + }, + { + "/path/to/nonmatching.yaml" => Puppet::Node::Facts.new("nonmatchingnode", "architecture" => "powerpc", 'processor_count' => '4'), + "/path/to/nonmatching1.yaml" => Puppet::Node::Facts.new("nonmatchingnode1", "architecture" => "powerpc", 'processor_count' => '5'), + "/path/to/nonmatching2.yaml" => Puppet::Node::Facts.new("nonmatchingnode2", "architecture" => "i386", 'processor_count' => '5'), + "/path/to/nonmatching3.yaml" => Puppet::Node::Facts.new("nonmatchingnode3", 'processor_count' => '4'), + }, + {'facts.architecture' => 'i386', 'facts.processor_count' => '4'} + ) + end + + it "should return empty array when no nodes match the search query options" do + assert_search_matches({}, { + "/path/to/nonmatching.yaml" => Puppet::Node::Facts.new("nonmatchingnode", "architecture" => "powerpc", 'processor_count' => '10'), + "/path/to/nonmatching1.yaml" => Puppet::Node::Facts.new("nonmatchingnode1", "architecture" => "powerpc", 'processor_count' => '5'), + "/path/to/nonmatching2.yaml" => Puppet::Node::Facts.new("nonmatchingnode2", "architecture" => "i386", 'processor_count' => '5'), + "/path/to/nonmatching3.yaml" => Puppet::Node::Facts.new("nonmatchingnode3", 'processor_count' => '4'), + }, + {'facts.processor_count.lt' => '4', 'facts.processor_count.gt' => '4'} + ) + end + + + it "should return node names that match the search query options with the greater than operator" do + assert_search_matches({ + '/path/to/matching.yaml' => Puppet::Node::Facts.new("matchingnode", "architecture" => "i386", 'processor_count' => '5'), + '/path/to/matching1.yaml' => Puppet::Node::Facts.new("matchingnode1", "architecture" => "powerpc", 'processor_count' => '10', 'randomfact' => 'foo') + }, + { + "/path/to/nonmatching.yaml" => Puppet::Node::Facts.new("nonmatchingnode", "architecture" => "powerpc", 'processor_count' => '4'), + "/path/to/nonmatching2.yaml" => Puppet::Node::Facts.new("nonmatchingnode2", "architecture" => "i386", 'processor_count' => '3'), + "/path/to/nonmatching3.yaml" => Puppet::Node::Facts.new("nonmatchingnode3" ), + }, + {'facts.processor_count.gt' => '4'} + ) + end + + it "should return node names that match the search query options with the less than operator" do + assert_search_matches({ + '/path/to/matching.yaml' => Puppet::Node::Facts.new("matchingnode", "architecture" => "i386", 'processor_count' => '5'), + '/path/to/matching1.yaml' => Puppet::Node::Facts.new("matchingnode1", "architecture" => "powerpc", 'processor_count' => '30', 'randomfact' => 'foo') + }, + { + "/path/to/nonmatching.yaml" => Puppet::Node::Facts.new("nonmatchingnode", "architecture" => "powerpc", 'processor_count' => '50' ), + "/path/to/nonmatching2.yaml" => Puppet::Node::Facts.new("nonmatchingnode2", "architecture" => "i386", 'processor_count' => '100'), + "/path/to/nonmatching3.yaml" => Puppet::Node::Facts.new("nonmatchingnode3" ), + }, + {'facts.processor_count.lt' => '50'} + ) + end + + it "should return node names that match the search query options with the less than or equal to operator" do + assert_search_matches({ + '/path/to/matching.yaml' => Puppet::Node::Facts.new("matchingnode", "architecture" => "i386", 'processor_count' => '5'), + '/path/to/matching1.yaml' => Puppet::Node::Facts.new("matchingnode1", "architecture" => "powerpc", 'processor_count' => '50', 'randomfact' => 'foo') + }, + { + "/path/to/nonmatching.yaml" => Puppet::Node::Facts.new("nonmatchingnode", "architecture" => "powerpc", 'processor_count' => '100' ), + "/path/to/nonmatching2.yaml" => Puppet::Node::Facts.new("nonmatchingnode2", "architecture" => "i386", 'processor_count' => '5000'), + "/path/to/nonmatching3.yaml" => Puppet::Node::Facts.new("nonmatchingnode3" ), + }, + {'facts.processor_count.le' => '50'} + ) + end + + it "should return node names that match the search query options with the greater than or equal to operator" do + assert_search_matches({ + '/path/to/matching.yaml' => Puppet::Node::Facts.new("matchingnode", "architecture" => "i386", 'processor_count' => '100'), + '/path/to/matching1.yaml' => Puppet::Node::Facts.new("matchingnode1", "architecture" => "powerpc", 'processor_count' => '50', 'randomfact' => 'foo') + }, + { + "/path/to/nonmatching.yaml" => Puppet::Node::Facts.new("nonmatchingnode", "architecture" => "powerpc", 'processor_count' => '40'), + "/path/to/nonmatching2.yaml" => Puppet::Node::Facts.new("nonmatchingnode2", "architecture" => "i386", 'processor_count' => '9' ), + "/path/to/nonmatching3.yaml" => Puppet::Node::Facts.new("nonmatchingnode3" ), + }, + {'facts.processor_count.ge' => '50'} + ) + end + + it "should return node names that match the search query options with the not equal operator" do + assert_search_matches({ + '/path/to/matching.yaml' => Puppet::Node::Facts.new("matchingnode", "architecture" => 'arm' ), + '/path/to/matching1.yaml' => Puppet::Node::Facts.new("matchingnode1", "architecture" => 'powerpc', 'randomfact' => 'foo') + }, + { + "/path/to/nonmatching.yaml" => Puppet::Node::Facts.new("nonmatchingnode", "architecture" => "i386" ), + "/path/to/nonmatching2.yaml" => Puppet::Node::Facts.new("nonmatchingnode2", "architecture" => "i386", 'processor_count' => '9' ), + "/path/to/nonmatching3.yaml" => Puppet::Node::Facts.new("nonmatchingnode3" ), + }, + {'facts.architecture.ne' => 'i386'} + ) + end + + def apply_timestamp(facts, timestamp) + facts.timestamp = timestamp + facts + end + + it "should be able to query based on meta.timestamp.gt" do + assert_search_matches({ + '/path/to/2010-11-01.yaml' => apply_timestamp(Puppet::Node::Facts.new("2010-11-01", {}), Time.parse("2010-11-01")), + '/path/to/2010-11-10.yaml' => apply_timestamp(Puppet::Node::Facts.new("2010-11-10", {}), Time.parse("2010-11-10")), + }, + { + '/path/to/2010-10-01.yaml' => apply_timestamp(Puppet::Node::Facts.new("2010-10-01", {}), Time.parse("2010-10-01")), + '/path/to/2010-10-10.yaml' => apply_timestamp(Puppet::Node::Facts.new("2010-10-10", {}), Time.parse("2010-10-10")), + '/path/to/2010-10-15.yaml' => apply_timestamp(Puppet::Node::Facts.new("2010-10-15", {}), Time.parse("2010-10-15")), + }, + {'meta.timestamp.gt' => '2010-10-15'} + ) + end + + it "should be able to query based on meta.timestamp.le" do + assert_search_matches({ + '/path/to/2010-10-01.yaml' => apply_timestamp(Puppet::Node::Facts.new("2010-10-01", {}), Time.parse("2010-10-01")), + '/path/to/2010-10-10.yaml' => apply_timestamp(Puppet::Node::Facts.new("2010-10-10", {}), Time.parse("2010-10-10")), + '/path/to/2010-10-15.yaml' => apply_timestamp(Puppet::Node::Facts.new("2010-10-15", {}), Time.parse("2010-10-15")), + }, + { + '/path/to/2010-11-01.yaml' => apply_timestamp(Puppet::Node::Facts.new("2010-11-01", {}), Time.parse("2010-11-01")), + '/path/to/2010-11-10.yaml' => apply_timestamp(Puppet::Node::Facts.new("2010-11-10", {}), Time.parse("2010-11-10")), + }, + {'meta.timestamp.le' => '2010-10-15'} + ) + end + + it "should be able to query based on meta.timestamp.lt" do + assert_search_matches({ + '/path/to/2010-10-01.yaml' => apply_timestamp(Puppet::Node::Facts.new("2010-10-01", {}), Time.parse("2010-10-01")), + '/path/to/2010-10-10.yaml' => apply_timestamp(Puppet::Node::Facts.new("2010-10-10", {}), Time.parse("2010-10-10")), + }, + { + '/path/to/2010-11-01.yaml' => apply_timestamp(Puppet::Node::Facts.new("2010-11-01", {}), Time.parse("2010-11-01")), + '/path/to/2010-11-10.yaml' => apply_timestamp(Puppet::Node::Facts.new("2010-11-10", {}), Time.parse("2010-11-10")), + '/path/to/2010-10-15.yaml' => apply_timestamp(Puppet::Node::Facts.new("2010-10-15", {}), Time.parse("2010-10-15")), + }, + {'meta.timestamp.lt' => '2010-10-15'} + ) + end + + it "should be able to query based on meta.timestamp.ge" do + assert_search_matches({ + '/path/to/2010-11-01.yaml' => apply_timestamp(Puppet::Node::Facts.new("2010-11-01", {}), Time.parse("2010-11-01")), + '/path/to/2010-11-10.yaml' => apply_timestamp(Puppet::Node::Facts.new("2010-11-10", {}), Time.parse("2010-11-10")), + '/path/to/2010-10-15.yaml' => apply_timestamp(Puppet::Node::Facts.new("2010-10-15", {}), Time.parse("2010-10-15")), + }, + { + '/path/to/2010-10-01.yaml' => apply_timestamp(Puppet::Node::Facts.new("2010-10-01", {}), Time.parse("2010-10-01")), + '/path/to/2010-10-10.yaml' => apply_timestamp(Puppet::Node::Facts.new("2010-10-10", {}), Time.parse("2010-10-10")), + }, + {'meta.timestamp.ge' => '2010-10-15'} + ) + end + + it "should be able to query based on meta.timestamp.eq" do + assert_search_matches({ + '/path/to/2010-10-15.yaml' => apply_timestamp(Puppet::Node::Facts.new("2010-10-15", {}), Time.parse("2010-10-15")), + }, + { + '/path/to/2010-11-01.yaml' => apply_timestamp(Puppet::Node::Facts.new("2010-11-01", {}), Time.parse("2010-11-01")), + '/path/to/2010-11-10.yaml' => apply_timestamp(Puppet::Node::Facts.new("2010-11-10", {}), Time.parse("2010-11-10")), + '/path/to/2010-10-01.yaml' => apply_timestamp(Puppet::Node::Facts.new("2010-10-01", {}), Time.parse("2010-10-01")), + '/path/to/2010-10-10.yaml' => apply_timestamp(Puppet::Node::Facts.new("2010-10-10", {}), Time.parse("2010-10-10")), + }, + {'meta.timestamp.eq' => '2010-10-15'} + ) + end + + it "should be able to query based on meta.timestamp" do + assert_search_matches({ + '/path/to/2010-10-15.yaml' => apply_timestamp(Puppet::Node::Facts.new("2010-10-15", {}), Time.parse("2010-10-15")), + }, + { + '/path/to/2010-11-01.yaml' => apply_timestamp(Puppet::Node::Facts.new("2010-11-01", {}), Time.parse("2010-11-01")), + '/path/to/2010-11-10.yaml' => apply_timestamp(Puppet::Node::Facts.new("2010-11-10", {}), Time.parse("2010-11-10")), + '/path/to/2010-10-01.yaml' => apply_timestamp(Puppet::Node::Facts.new("2010-10-01", {}), Time.parse("2010-10-01")), + '/path/to/2010-10-10.yaml' => apply_timestamp(Puppet::Node::Facts.new("2010-10-10", {}), Time.parse("2010-10-10")), + }, + {'meta.timestamp' => '2010-10-15'} + ) + end + + it "should be able to query based on meta.timestamp.ne" do + assert_search_matches({ + '/path/to/2010-11-01.yaml' => apply_timestamp(Puppet::Node::Facts.new("2010-11-01", {}), Time.parse("2010-11-01")), + '/path/to/2010-11-10.yaml' => apply_timestamp(Puppet::Node::Facts.new("2010-11-10", {}), Time.parse("2010-11-10")), + '/path/to/2010-10-01.yaml' => apply_timestamp(Puppet::Node::Facts.new("2010-10-01", {}), Time.parse("2010-10-01")), + '/path/to/2010-10-10.yaml' => apply_timestamp(Puppet::Node::Facts.new("2010-10-10", {}), Time.parse("2010-10-10")), + }, + { + '/path/to/2010-10-15.yaml' => apply_timestamp(Puppet::Node::Facts.new("2010-10-15", {}), Time.parse("2010-10-15")), + }, + {'meta.timestamp.ne' => '2010-10-15'} + ) + end +end diff --git a/spec/unit/indirector/key/ca_spec.rb b/spec/unit/indirector/key/ca_spec.rb index 9ed5df67b..53bd380a6 100755 --- a/spec/unit/indirector/key/ca_spec.rb +++ b/spec/unit/indirector/key/ca_spec.rb @@ -3,7 +3,7 @@ # Created by Luke Kanies on 2008-3-7. # Copyright (c) 2007. All rights reserved. -require File.dirname(__FILE__) + '/../../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') require 'puppet/indirector/key/ca' diff --git a/spec/unit/indirector/key/file_spec.rb b/spec/unit/indirector/key/file_spec.rb index 5037c7f0e..715ceacda 100755 --- a/spec/unit/indirector/key/file_spec.rb +++ b/spec/unit/indirector/key/file_spec.rb @@ -3,7 +3,7 @@ # Created by Luke Kanies on 2008-3-7. # Copyright (c) 2007. All rights reserved. -require File.dirname(__FILE__) + '/../../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') require 'puppet/indirector/key/file' diff --git a/spec/unit/indirector/ldap_spec.rb b/spec/unit/indirector/ldap_spec.rb index c071f870e..ab5dab9ce 100755 --- a/spec/unit/indirector/ldap_spec.rb +++ b/spec/unit/indirector/ldap_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') require 'puppet/indirector/ldap' @@ -8,10 +8,9 @@ describe Puppet::Indirector::Ldap do before do @indirection = stub 'indirection', :name => :testing Puppet::Indirector::Indirection.stubs(:instance).returns(@indirection) - @ldap_class = Class.new(Puppet::Indirector::Ldap) do - def self.to_s - "Testing::Mytype" - end + module Testing; end + @ldap_class = class Testing::MyLdap < Puppet::Indirector::Ldap + self end @connection = mock 'ldap' diff --git a/spec/unit/indirector/memory_spec.rb b/spec/unit/indirector/memory_spec.rb index 160b4f91d..751adb1b6 100755 --- a/spec/unit/indirector/memory_spec.rb +++ b/spec/unit/indirector/memory_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') require 'puppet/indirector/memory' require 'shared_behaviours/memory_terminus' @@ -14,10 +14,9 @@ describe Puppet::Indirector::Memory do @indirection = stub 'indirection', :name => :mystuff, :register_terminus_type => nil, :model => @model Puppet::Indirector::Indirection.stubs(:instance).returns(@indirection) - @memory_class = Class.new(Puppet::Indirector::Memory) do - def self.to_s - "Mystuff::Testing" - end + module Testing; end + @memory_class = class Testing::MyMemory < Puppet::Indirector::Memory + self end @searcher = @memory_class.new diff --git a/spec/unit/indirector/node/active_record_spec.rb b/spec/unit/indirector/node/active_record_spec.rb index 69229e144..65b0e1fc9 100755 --- a/spec/unit/indirector/node/active_record_spec.rb +++ b/spec/unit/indirector/node/active_record_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') require 'puppet/node' diff --git a/spec/unit/indirector/node/exec_spec.rb b/spec/unit/indirector/node/exec_spec.rb index d214a5ef6..e6d6ccb93 100755 --- a/spec/unit/indirector/node/exec_spec.rb +++ b/spec/unit/indirector/node/exec_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') require 'puppet/indirector/node/exec' diff --git a/spec/unit/indirector/node/ldap_spec.rb b/spec/unit/indirector/node/ldap_spec.rb index 042e7bd54..5d4086a1a 100755 --- a/spec/unit/indirector/node/ldap_spec.rb +++ b/spec/unit/indirector/node/ldap_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') require 'puppet/indirector/node/ldap' @@ -311,7 +311,7 @@ describe Puppet::Node::Ldap do @options = {} @request = stub 'request', :key => "foo", :options => @options - Puppet::Node::Facts.stubs(:terminus_class).returns :yaml + Puppet::Node::Facts.indirection.stubs(:terminus_class).returns :yaml end it "should find all nodes if no arguments are provided" do diff --git a/spec/unit/indirector/node/memory_spec.rb b/spec/unit/indirector/node/memory_spec.rb index 3f1fdb9f0..904ee1259 100755 --- a/spec/unit/indirector/node/memory_spec.rb +++ b/spec/unit/indirector/node/memory_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') require 'puppet/indirector/node/memory' diff --git a/spec/unit/indirector/node/plain_spec.rb b/spec/unit/indirector/node/plain_spec.rb index 730086296..40d5211db 100755 --- a/spec/unit/indirector/node/plain_spec.rb +++ b/spec/unit/indirector/node/plain_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') require 'puppet/indirector/node/plain' diff --git a/spec/unit/indirector/node/rest_spec.rb b/spec/unit/indirector/node/rest_spec.rb index 0b20752e5..cb3012efa 100755 --- a/spec/unit/indirector/node/rest_spec.rb +++ b/spec/unit/indirector/node/rest_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') require 'puppet/indirector/node/rest' diff --git a/spec/unit/indirector/node/yaml_spec.rb b/spec/unit/indirector/node/yaml_spec.rb index 8e19a1230..649bde06d 100755 --- a/spec/unit/indirector/node/yaml_spec.rb +++ b/spec/unit/indirector/node/yaml_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') require 'puppet/node' require 'puppet/indirector/node/yaml' diff --git a/spec/unit/indirector/plain_spec.rb b/spec/unit/indirector/plain_spec.rb index 2fb9e4dd3..dfaa701bd 100755 --- a/spec/unit/indirector/plain_spec.rb +++ b/spec/unit/indirector/plain_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') require 'puppet/indirector/plain' describe Puppet::Indirector::Plain do @@ -10,10 +10,9 @@ describe Puppet::Indirector::Plain do @indirection = stub 'indirection', :name => :mystuff, :register_terminus_type => nil, :model => @model Puppet::Indirector::Indirection.stubs(:instance).returns(@indirection) - @plain_class = Class.new(Puppet::Indirector::Plain) do - def self.to_s - "Mystuff::Testing" - end + module Testing; end + @plain_class = class Testing::MyPlain < Puppet::Indirector::Plain + self end @searcher = @plain_class.new diff --git a/spec/unit/indirector/queue_spec.rb b/spec/unit/indirector/queue_spec.rb index bbe00c75f..6f5b44b4c 100755 --- a/spec/unit/indirector/queue_spec.rb +++ b/spec/unit/indirector/queue_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') require 'puppet/indirector/queue' class Puppet::Indirector::Queue::TestClient @@ -31,10 +31,9 @@ describe Puppet::Indirector::Queue, :if => Puppet.features.pson? do @model = mock 'model' @indirection = stub 'indirection', :name => :my_queue, :register_terminus_type => nil, :model => @model Puppet::Indirector::Indirection.stubs(:instance).with(:my_queue).returns(@indirection) - @store_class = Class.new(Puppet::Indirector::Queue) do - def self.to_s - 'MyQueue::MyType' - end + module MyQueue; end + @store_class = class MyQueue::MyType < Puppet::Indirector::Queue + self end @store = @store_class.new @@ -42,8 +41,7 @@ describe Puppet::Indirector::Queue, :if => Puppet.features.pson? do @subject = @subject_class.new @subject.name = :me - Puppet.settings.stubs(:value).returns("bogus setting data") - Puppet.settings.stubs(:value).with(:queue_type).returns(:test_client) + Puppet[:queue_type] = :test_client Puppet::Util::Queue.stubs(:queue_type_to_class).with(:test_client).returns(Puppet::Indirector::Queue::TestClient) @request = stub 'request', :key => :me, :instance => @subject @@ -112,12 +110,12 @@ describe Puppet::Indirector::Queue, :if => Puppet.features.pson? do it "should log but not propagate errors" do @store_class.client.expects(:subscribe).yields("foo") - @store_class.expects(:intern).raises ArgumentError - Puppet.expects(:err) - - @store_class.expects(:puts) + @store_class.expects(:intern).raises(ArgumentError) + expect { @store_class.subscribe {|o| o } }.should_not raise_error - @store_class.subscribe {|o| o } + @logs.length.should == 1 + @logs.first.message.should =~ /Error occured with subscription to queue my_queue for indirection my_queue: ArgumentError/ + @logs.first.level.should == :err end end end diff --git a/spec/unit/indirector/report/processor_spec.rb b/spec/unit/indirector/report/processor_spec.rb index 5602a271f..adc2638fc 100755 --- a/spec/unit/indirector/report/processor_spec.rb +++ b/spec/unit/indirector/report/processor_spec.rb @@ -3,7 +3,7 @@ # Created by Luke Kanies on 2007-9-23. # Copyright (c) 2007. All rights reserved. -require File.dirname(__FILE__) + '/../../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') require 'puppet/indirector/report/processor' diff --git a/spec/unit/indirector/report/rest_spec.rb b/spec/unit/indirector/report/rest_spec.rb index d0d29f862..67a98e334 100755 --- a/spec/unit/indirector/report/rest_spec.rb +++ b/spec/unit/indirector/report/rest_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') require 'puppet/indirector/report/rest' diff --git a/spec/unit/indirector/report/yaml_spec.rb b/spec/unit/indirector/report/yaml_spec.rb index 610c9ae43..e75fafe5e 100644 --- a/spec/unit/indirector/report/yaml_spec.rb +++ b/spec/unit/indirector/report/yaml_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') require 'puppet/transaction/report' require 'puppet/indirector/report/yaml' diff --git a/spec/unit/indirector/request_spec.rb b/spec/unit/indirector/request_spec.rb index 0b3c2c266..bef56b1e1 100755 --- a/spec/unit/indirector/request_spec.rb +++ b/spec/unit/indirector/request_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') require 'puppet/indirector/request' describe Puppet::Indirector::Request do diff --git a/spec/unit/indirector/resource/ral_spec.rb b/spec/unit/indirector/resource/ral_spec.rb index a5baef367..43deaa8eb 100644 --- a/spec/unit/indirector/resource/ral_spec.rb +++ b/spec/unit/indirector/resource/ral_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') describe "Puppet::Resource::Ral" do describe "find" do diff --git a/spec/unit/indirector/resource/rest_spec.rb b/spec/unit/indirector/resource/rest_spec.rb index 351aee33b..1285d338a 100755 --- a/spec/unit/indirector/resource/rest_spec.rb +++ b/spec/unit/indirector/resource/rest_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -Dir.chdir(File.dirname(__FILE__)) { (s = lambda { |f| File.exist?(f) ? require(f) : Dir.chdir("..") { s.call(f) } }).call("spec/spec_helper.rb") } +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') require 'puppet/indirector/resource/rest' diff --git a/spec/unit/indirector/resource_type/parser_spec.rb b/spec/unit/indirector/resource_type/parser_spec.rb index 5c0d9e04c..f86b319f9 100755 --- a/spec/unit/indirector/resource_type/parser_spec.rb +++ b/spec/unit/indirector/resource_type/parser_spec.rb @@ -1,15 +1,17 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') require 'puppet/indirector/resource_type/parser' +require 'puppet_spec/files' describe Puppet::Indirector::ResourceType::Parser do + include PuppetSpec::Files + before do @terminus = Puppet::Indirector::ResourceType::Parser.new @request = Puppet::Indirector::Request.new(:resource_type, :find, "foo") - @krt = Puppet::Resource::TypeCollection.new(@request.environment) - @request.environment.stubs(:known_resource_types).returns @krt + @krt = @request.environment.known_resource_types end it "should be registered with the resource_type indirection" do @@ -17,16 +19,29 @@ describe Puppet::Indirector::ResourceType::Parser do end describe "when finding" do - it "should use the request's environment's list of known resource types" do - @request.environment.known_resource_types.expects(:hostclass).returns nil + it "should return any found type from the request's environment" do + type = Puppet::Resource::Type.new(:hostclass, "foo") + @request.environment.known_resource_types.add(type) - @terminus.find(@request) + @terminus.find(@request).should == type end - it "should return any found type" do - type = @krt.add(Puppet::Resource::Type.new(:hostclass, "foo")) + it "should attempt to load the type if none is found in memory" do + dir = tmpdir("find_a_type") + FileUtils.mkdir_p(dir) + Puppet[:modulepath] = dir - @terminus.find(@request).should == type + # Make a new request, since we've reset the env + @request = Puppet::Indirector::Request.new(:resource_type, :find, "foo::bar") + + manifest_path = File.join(dir, "foo", "manifests") + FileUtils.mkdir_p(manifest_path) + + File.open(File.join(manifest_path, "bar.pp"), "w") { |f| f.puts "class foo::bar {}" } + + result = @terminus.find(@request) + result.should be_instance_of(Puppet::Resource::Type) + result.name.should == "foo::bar" end it "should return nil if no type can be found" do @@ -52,8 +67,35 @@ describe Puppet::Indirector::ResourceType::Parser do @terminus.search(@request) end - it "should fail if anyther other than '*' was provided as the search key" do - @request.key = "foo*" + it "should return all results if '*' is provided as the search string" do + @request.key = "*" + type = @krt.add(Puppet::Resource::Type.new(:hostclass, "foo")) + node = @krt.add(Puppet::Resource::Type.new(:node, "bar")) + define = @krt.add(Puppet::Resource::Type.new(:definition, "baz")) + + result = @terminus.search(@request) + result.should be_include(type) + result.should be_include(node) + result.should be_include(define) + end + + it "should treat any search string not '*' as a regex" do + @request.key = "a" + foo = @krt.add(Puppet::Resource::Type.new(:hostclass, "foo")) + bar = @krt.add(Puppet::Resource::Type.new(:hostclass, "bar")) + baz = @krt.add(Puppet::Resource::Type.new(:hostclass, "baz")) + + result = @terminus.search(@request) + result.should be_include(bar) + result.should be_include(baz) + result.should_not be_include(foo) + end + + it "should fail if a provided search string is not '*' and is not a valid regex" do + @request.key = "*foo*" + + # Add one instance so we don't just get an empty array" + @krt.add(Puppet::Resource::Type.new(:hostclass, "foo")) lambda { @terminus.search(@request) }.should raise_error(ArgumentError) end @@ -68,8 +110,41 @@ describe Puppet::Indirector::ResourceType::Parser do result.should be_include(define) end + it "should not return the 'main' class" do + main = @krt.add(Puppet::Resource::Type.new(:hostclass, "")) + + # So there is a return value + foo = @krt.add(Puppet::Resource::Type.new(:hostclass, "foo")) + + @terminus.search(@request).should_not be_include(main) + end + it "should return nil if no types can be found" do @terminus.search(@request).should be_nil end + + it "should load all resource types from all search paths" do + dir = tmpdir("searching_in_all") + first = File.join(dir, "first") + second = File.join(dir, "second") + FileUtils.mkdir_p(first) + FileUtils.mkdir_p(second) + Puppet[:modulepath] = "#{first}:#{second}" + + # Make a new request, since we've reset the env + @request = Puppet::Indirector::Request.new(:resource_type, :search, "*") + + onepath = File.join(first, "one", "manifests") + FileUtils.mkdir_p(onepath) + twopath = File.join(first, "two", "manifests") + FileUtils.mkdir_p(twopath) + + File.open(File.join(onepath, "oneklass.pp"), "w") { |f| f.puts "class one::oneklass {}" } + File.open(File.join(twopath, "twoklass.pp"), "w") { |f| f.puts "class two::twoklass {}" } + + result = @terminus.search(@request) + result.find { |t| t.name == "one::oneklass" }.should be_instance_of(Puppet::Resource::Type) + result.find { |t| t.name == "two::twoklass" }.should be_instance_of(Puppet::Resource::Type) + end end end diff --git a/spec/unit/indirector/resource_type/rest_spec.rb b/spec/unit/indirector/resource_type/rest_spec.rb index 2486502bc..dceb109b2 100755 --- a/spec/unit/indirector/resource_type/rest_spec.rb +++ b/spec/unit/indirector/resource_type/rest_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') require 'puppet/indirector/resource_type/rest' diff --git a/spec/unit/indirector/rest_spec.rb b/spec/unit/indirector/rest_spec.rb index 7bc1cc513..326d85f9d 100755 --- a/spec/unit/indirector/rest_spec.rb +++ b/spec/unit/indirector/rest_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') require 'puppet/indirector/rest' shared_examples_for "a REST http call" do @@ -26,19 +26,27 @@ shared_examples_for "a REST http call" do end describe Puppet::Indirector::REST do - before do + before :all do Puppet::Indirector::Terminus.stubs(:register_terminus_class) @model = stub('model', :supported_formats => %w{}, :convert_from => nil) @instance = stub('model instance', :name= => nil) @indirection = stub('indirection', :name => :mystuff, :register_terminus_type => nil, :model => @model) - Puppet::Indirector::Indirection.stubs(:instance).returns(@indirection) + Puppet::Indirector::Indirection.expects(:instance).returns(@indirection) - @rest_class = Class.new(Puppet::Indirector::REST) do - def self.to_s - "This::Is::A::Test::Class" + module This + module Is + module A + module Test + end + end end end + @rest_class = class This::Is::A::Test::Class < Puppet::Indirector::REST + self + end + end + before :each do @response = stub('mock response', :body => 'result', :code => "200") @response.stubs(:[]).with('content-type').returns "text/plain" @response.stubs(:[]).with('content-encoding').returns nil diff --git a/spec/unit/indirector/run/local_spec.rb b/spec/unit/indirector/run/local_spec.rb index 2684096d5..cb012a0b0 100644 --- a/spec/unit/indirector/run/local_spec.rb +++ b/spec/unit/indirector/run/local_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') require 'puppet/indirector/run/local' diff --git a/spec/unit/indirector/run/rest_spec.rb b/spec/unit/indirector/run/rest_spec.rb index 2b2415ab6..cf90caa5b 100755 --- a/spec/unit/indirector/run/rest_spec.rb +++ b/spec/unit/indirector/run/rest_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') require 'puppet/indirector/run/rest' diff --git a/spec/unit/indirector/ssl_file_spec.rb b/spec/unit/indirector/ssl_file_spec.rb index 37098a7a9..ca97cf49e 100755 --- a/spec/unit/indirector/ssl_file_spec.rb +++ b/spec/unit/indirector/ssl_file_spec.rb @@ -3,20 +3,21 @@ # Created by Luke Kanies on 2008-3-10. # Copyright (c) 2007. All rights reserved. -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') require 'puppet/indirector/ssl_file' describe Puppet::Indirector::SslFile do - before do - @model = mock 'model' + before :all do @indirection = stub 'indirection', :name => :testing, :model => @model Puppet::Indirector::Indirection.expects(:instance).with(:testing).returns(@indirection) - @file_class = Class.new(Puppet::Indirector::SslFile) do - def self.to_s - "Testing::Mytype" - end + module Testing; end + @file_class = class Testing::MyType < Puppet::Indirector::SslFile + self end + end + before :each do + @model = mock 'model' @setting = :certdir @file_class.store_in @setting diff --git a/spec/unit/indirector/status/rest_spec.rb b/spec/unit/indirector/status/rest_spec.rb index 5eed5fc93..436c86881 100755 --- a/spec/unit/indirector/status/rest_spec.rb +++ b/spec/unit/indirector/status/rest_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -Dir.chdir(File.dirname(__FILE__)) { (s = lambda { |f| File.exist?(f) ? require(f) : Dir.chdir("..") { s.call(f) } }).call("spec/spec_helper.rb") } +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') require 'puppet/indirector/status/rest' diff --git a/spec/unit/indirector/terminus_spec.rb b/spec/unit/indirector/terminus_spec.rb index 826b9347a..bc255aa5b 100755 --- a/spec/unit/indirector/terminus_spec.rb +++ b/spec/unit/indirector/terminus_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') require 'puppet/defaults' require 'puppet/indirector' require 'puppet/indirector/file' diff --git a/spec/unit/indirector/yaml_spec.rb b/spec/unit/indirector/yaml_spec.rb index 86c13c5a0..188e300d6 100755 --- a/spec/unit/indirector/yaml_spec.rb +++ b/spec/unit/indirector/yaml_spec.rb @@ -1,18 +1,19 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') require 'puppet/indirector/yaml' describe Puppet::Indirector::Yaml, " when choosing file location" do - before :each do + before :all do @indirection = stub 'indirection', :name => :my_yaml, :register_terminus_type => nil - Puppet::Indirector::Indirection.stubs(:instance).with(:my_yaml).returns(@indirection) - @store_class = Class.new(Puppet::Indirector::Yaml) do - def self.to_s - "MyYaml::MyType" - end + Puppet::Indirector::Indirection.expects(:instance).with(:my_yaml).returns(@indirection) + module MyYaml; end + @store_class = class MyYaml::MyType < Puppet::Indirector::Yaml + self end + end + before :each do @store = @store_class.new @subject = Object.new diff --git a/spec/unit/indirector_spec.rb b/spec/unit/indirector_spec.rb index 6f44764da..7bab426c0 100755 --- a/spec/unit/indirector_spec.rb +++ b/spec/unit/indirector_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../spec_helper') require 'puppet/defaults' require 'puppet/indirector' @@ -64,24 +64,6 @@ describe Puppet::Indirector, "when registering an indirection" do end end -shared_examples_for "Delegated Indirection Method" do - it "should delegate to the indirection" do - @indirection.expects(@method) - @thingie.send(@method, "me") - end - - it "should pass all of the passed arguments directly to the indirection instance" do - @indirection.expects(@method).with("me", :one => :two) - @thingie.send(@method, "me", :one => :two) - end - - it "should return the results of the delegation as its result" do - request = mock 'request' - @indirection.expects(@method).returns "yay" - @thingie.send(@method, "me").should == "yay" - end -end - describe Puppet::Indirector, "when redirecting a model" do before do @thingie = Class.new do @@ -98,64 +80,6 @@ describe Puppet::Indirector, "when redirecting a model" do @thingie.ancestors.should be_include(Puppet::Indirector::Envelope) end - describe "when finding instances via the model" do - before { @method = :find } - it_should_behave_like "Delegated Indirection Method" - end - - describe "when destroying instances via the model" do - before { @method = :destroy } - it_should_behave_like "Delegated Indirection Method" - end - - describe "when searching for instances via the model" do - before { @method = :search } - it_should_behave_like "Delegated Indirection Method" - end - - describe "when expiring instances via the model" do - before { @method = :expire } - it_should_behave_like "Delegated Indirection Method" - end - - describe "when performing a head request" do - before { @method = :head } - it_should_behave_like "Delegated Indirection Method" - end - - # This is an instance method, so it behaves a bit differently. - describe "when saving instances via the model" do - before do - @instance = @thingie.new("me") - end - - it "should delegate to the indirection" do - @indirection.expects(:save) - @instance.save - end - - it "should pass the instance and an optional key to the indirection's :save method" do - @indirection.expects(:save).with("key", @instance) - @instance.save "key" - end - - it "should return the results of the delegation as its result" do - request = mock 'request' - @indirection.expects(:save).returns "yay" - @instance.save.should == "yay" - end - end - - it "should give the model the ability to set the indirection terminus class" do - @indirection.expects(:terminus_class=).with(:myterm) - @thingie.terminus_class = :myterm - end - - it "should give the model the ability to set the indirection cache class" do - @indirection.expects(:cache_class=).with(:mycache) - @thingie.cache_class = :mycache - end - after do @indirection.delete end diff --git a/spec/unit/module_spec.rb b/spec/unit/module_spec.rb index 0b4873f5f..f3120e16b 100755 --- a/spec/unit/module_spec.rb +++ b/spec/unit/module_spec.rb @@ -1,8 +1,11 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../spec_helper') +require 'puppet_spec/files' describe Puppet::Module do + include PuppetSpec::Files + before do # This is necessary because of the extra checks we have for the deprecated # 'plugins' directory @@ -267,17 +270,39 @@ describe Puppet::Module do end it "should return the path to the first found instance in its environment's module paths as its path" do + dir = tmpdir("deep_path") + first = File.join(dir, "first") + second = File.join(dir, "second") + + FileUtils.mkdir_p(first) + FileUtils.mkdir_p(second) + Puppet[:modulepath] = "#{first}:#{second}" + + modpath = File.join(first, "foo") + FileUtils.mkdir_p(modpath) + + # Make a second one, which we shouldn't find + FileUtils.mkdir_p(File.join(second, "foo")) + mod = Puppet::Module.new("foo") - env = mock 'environment' - mod.stubs(:environment).returns env + mod.path.should == modpath + end + + it "should be able to find itself in a directory other than the first directory in the module path" do + dir = tmpdir("deep_path") + first = File.join(dir, "first") + second = File.join(dir, "second") - env.expects(:modulepath).returns %w{/a /b /c} + FileUtils.mkdir_p(first) + FileUtils.mkdir_p(second) + Puppet[:modulepath] = "#{first}:#{second}" - FileTest.expects(:exist?).with("/a/foo").returns false - FileTest.expects(:exist?).with("/b/foo").returns true - FileTest.expects(:exist?).with("/c/foo").never + modpath = File.join(second, "foo") + FileUtils.mkdir_p(modpath) - mod.path.should == "/b/foo" + mod = Puppet::Module.new("foo") + mod.should be_exist + mod.path.should == modpath end it "should be considered existent if it exists in at least one module path" do diff --git a/spec/unit/network/authconfig_spec.rb b/spec/unit/network/authconfig_spec.rb index e10458b1a..9d69e99ac 100755 --- a/spec/unit/network/authconfig_spec.rb +++ b/spec/unit/network/authconfig_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') require 'puppet/network/authconfig' @@ -12,7 +12,7 @@ describe Puppet::Network::AuthConfig do FileTest.stubs(:exists?).returns(true) File.stubs(:stat).returns(stub('stat', :ctime => :now)) - Time.stubs(:now).returns :now + Time.stubs(:now).returns Time.now @authconfig = Puppet::Network::AuthConfig.new("dummy", false) end diff --git a/spec/unit/network/authstore_spec.rb b/spec/unit/network/authstore_spec.rb index 094352c63..d477ee301 100644 --- a/spec/unit/network/authstore_spec.rb +++ b/spec/unit/network/authstore_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') require 'puppet/network/authconfig' @@ -86,7 +86,7 @@ describe Puppet::Network::AuthStore::Declaration do [ "02001:0000:1234:0000:0000:C1C0:ABCD:0876", "2001:0000:1234:0000:00001:C1C0:ABCD:0876", - " 2001:0000:1234:0000:0000:C1C0:ABCD:0876 0", + " 2001:0000:1234:0000:0000:C1C0:ABCD:0876 0", "2001:0000:1234: 0000:0000:C1C0:ABCD:0876", "3ffe:0b00:0000:0001:0000:0000:000a", "FF02:0000:0000:0000:0000:0000:0000:0000:0001", diff --git a/spec/unit/network/client_spec.rb b/spec/unit/network/client_spec.rb index f42bd78b9..820f10f12 100755 --- a/spec/unit/network/client_spec.rb +++ b/spec/unit/network/client_spec.rb @@ -3,7 +3,7 @@ # Created by Luke Kanies on 2008-3-24. # Copyright (c) 2008. All rights reserved. -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') require 'puppet/network/client' diff --git a/spec/unit/network/format_handler_spec.rb b/spec/unit/network/format_handler_spec.rb index 64cca8239..556fada80 100755 --- a/spec/unit/network/format_handler_spec.rb +++ b/spec/unit/network/format_handler_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') require 'puppet/network/format_handler' diff --git a/spec/unit/network/format_spec.rb b/spec/unit/network/format_spec.rb index bcb084156..658729e4c 100755 --- a/spec/unit/network/format_spec.rb +++ b/spec/unit/network/format_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') require 'puppet/network/format' diff --git a/spec/unit/network/formats_spec.rb b/spec/unit/network/formats_spec.rb index 2c58a0534..30e88c578 100755 --- a/spec/unit/network/formats_spec.rb +++ b/spec/unit/network/formats_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') require 'puppet/network/formats' diff --git a/spec/unit/network/handler/fileserver_spec.rb b/spec/unit/network/handler/fileserver_spec.rb index 9d34e9cdd..014b82e69 100644 --- a/spec/unit/network/handler/fileserver_spec.rb +++ b/spec/unit/network/handler/fileserver_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') require 'puppet/network/handler/fileserver' diff --git a/spec/unit/network/http/api/v1_spec.rb b/spec/unit/network/http/api/v1_spec.rb index 9a8780c62..257eec5de 100644 --- a/spec/unit/network/http/api/v1_spec.rb +++ b/spec/unit/network/http/api/v1_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -Dir.chdir(File.dirname(__FILE__)) { (s = lambda { |f| File.exist?(f) ? require(f) : Dir.chdir("..") { s.call(f) } }).call("spec/spec_helper.rb") } +require File.expand_path(File.dirname(__FILE__) + '/../../../../spec_helper') require 'puppet/network/http/api/v1' @@ -32,7 +32,7 @@ describe Puppet::Network::HTTP::API::V1 do end it "should use the first field of the URI as the environment" do - @tester.uri2indirection("GET", "/env/foo/bar", {}).environment.should == Puppet::Node::Environment.new("env") + @tester.uri2indirection("GET", "/env/foo/bar", {})[3][:environment].should == "env" end it "should fail if the environment is not alphanumeric" do @@ -40,11 +40,11 @@ describe Puppet::Network::HTTP::API::V1 do end it "should use the environment from the URI even if one is specified in the parameters" do - @tester.uri2indirection("GET", "/env/foo/bar", {:environment => "otherenv"}).environment.should == Puppet::Node::Environment.new("env") + @tester.uri2indirection("GET", "/env/foo/bar", {:environment => "otherenv"})[3][:environment].should == "env" end it "should use the second field of the URI as the indirection name" do - @tester.uri2indirection("GET", "/env/foo/bar", {}).indirection_name.should == :foo + @tester.uri2indirection("GET", "/env/foo/bar", {})[0].should == "foo" end it "should fail if the indirection name is not alphanumeric" do @@ -52,11 +52,11 @@ describe Puppet::Network::HTTP::API::V1 do end it "should use the remainder of the URI as the indirection key" do - @tester.uri2indirection("GET", "/env/foo/bar", {}).key.should == "bar" + @tester.uri2indirection("GET", "/env/foo/bar", {})[2].should == "bar" end it "should support the indirection key being a /-separated file path" do - @tester.uri2indirection("GET", "/env/foo/bee/baz/bomb", {}).key.should == "bee/baz/bomb" + @tester.uri2indirection("GET", "/env/foo/bee/baz/bomb", {})[2].should == "bee/baz/bomb" end it "should fail if no indirection key is specified" do @@ -65,51 +65,63 @@ describe Puppet::Network::HTTP::API::V1 do end it "should choose 'find' as the indirection method if the http method is a GET and the indirection name is singular" do - @tester.uri2indirection("GET", "/env/foo/bar", {}).method.should == :find + @tester.uri2indirection("GET", "/env/foo/bar", {})[1].should == :find end it "should choose 'head' as the indirection method if the http method is a HEAD and the indirection name is singular" do - @tester.uri2indirection("HEAD", "/env/foo/bar", {}).method.should == :head + @tester.uri2indirection("HEAD", "/env/foo/bar", {})[1].should == :head end it "should choose 'search' as the indirection method if the http method is a GET and the indirection name is plural" do - @tester.uri2indirection("GET", "/env/foos/bar", {}).method.should == :search + @tester.uri2indirection("GET", "/env/foos/bar", {})[1].should == :search end it "should choose 'find' as the indirection method if the http method is a GET and the indirection name is facts" do - @tester.uri2indirection("GET", "/env/facts/bar", {}).method.should == :find + @tester.uri2indirection("GET", "/env/facts/bar", {})[1].should == :find end it "should choose 'save' as the indirection method if the http method is a PUT and the indirection name is facts" do - @tester.uri2indirection("PUT", "/env/facts/bar", {}).method.should == :save + @tester.uri2indirection("PUT", "/env/facts/bar", {})[1].should == :save end it "should choose 'search' as the indirection method if the http method is a GET and the indirection name is inventory" do - @tester.uri2indirection("GET", "/env/inventory/search", {}).method.should == :search + @tester.uri2indirection("GET", "/env/inventory/search", {})[1].should == :search + end + + it "should choose 'find' as the indirection method if the http method is a GET and the indirection name is facts" do + @tester.uri2indirection("GET", "/env/facts/bar", {})[1].should == :find + end + + it "should choose 'save' as the indirection method if the http method is a PUT and the indirection name is facts" do + @tester.uri2indirection("PUT", "/env/facts/bar", {})[1].should == :save + end + + it "should choose 'search' as the indirection method if the http method is a GET and the indirection name is inventory" do + @tester.uri2indirection("GET", "/env/inventory/search", {})[1].should == :search end it "should choose 'search' as the indirection method if the http method is a GET and the indirection name is facts_search" do - @tester.uri2indirection("GET", "/env/facts_search/bar", {}).method.should == :search + @tester.uri2indirection("GET", "/env/facts_search/bar", {})[1].should == :search end it "should change indirection name to 'facts' if the http method is a GET and the indirection name is facts_search" do - @tester.uri2indirection("GET", "/env/facts_search/bar", {}).indirection_name.should == :facts + @tester.uri2indirection("GET", "/env/facts_search/bar", {})[0].should == 'facts' end it "should not change indirection name from 'facts' if the http method is a GET and the indirection name is facts" do - @tester.uri2indirection("GET", "/env/facts/bar", {}).indirection_name.should == :facts + @tester.uri2indirection("GET", "/env/facts/bar", {})[0].should == 'facts' end it "should change indirection name to 'status' if the http method is a GET and the indirection name is statuses" do - @tester.uri2indirection("GET", "/env/statuses/bar", {}).indirection_name.should == :status + @tester.uri2indirection("GET", "/env/statuses/bar", {})[0].should == 'status' end it "should choose 'delete' as the indirection method if the http method is a DELETE and the indirection name is singular" do - @tester.uri2indirection("DELETE", "/env/foo/bar", {}).method.should == :destroy + @tester.uri2indirection("DELETE", "/env/foo/bar", {})[1].should == :destroy end it "should choose 'save' as the indirection method if the http method is a PUT and the indirection name is singular" do - @tester.uri2indirection("PUT", "/env/foo/bar", {}).method.should == :save + @tester.uri2indirection("PUT", "/env/foo/bar", {})[1].should == :save end it "should fail if an indirection method cannot be picked" do @@ -118,7 +130,8 @@ describe Puppet::Network::HTTP::API::V1 do it "should URI unescape the indirection key" do escaped = URI.escape("foo bar") - @tester.uri2indirection("GET", "/env/foo/#{escaped}", {}).key.should == "foo bar" + indirection_name, method, key, params = @tester.uri2indirection("GET", "/env/foo/#{escaped}", {}) + key.should == "foo bar" end end diff --git a/spec/unit/network/http/compression_spec.rb b/spec/unit/network/http/compression_spec.rb index 3828ec59c..85c62f358 100755 --- a/spec/unit/network/http/compression_spec.rb +++ b/spec/unit/network/http/compression_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') describe "http compression" do diff --git a/spec/unit/network/http/handler_spec.rb b/spec/unit/network/http/handler_spec.rb index 68c7b9aa3..97d17fcf8 100755 --- a/spec/unit/network/http/handler_spec.rb +++ b/spec/unit/network/http/handler_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') require 'puppet/network/http/handler' require 'puppet/network/rest_authorization' @@ -46,6 +46,8 @@ describe Puppet::Network::HTTP::Handler do @request.stubs(:[]).returns "foo" @response = stub('http response') @model_class = stub('indirected model class') + @indirection = stub('indirection') + @model_class.stubs(:indirection).returns(@indirection) @result = stub 'result', :render => "mytext" @@ -79,37 +81,22 @@ describe Puppet::Network::HTTP::Handler do @handler.process(@request, @response) end - it "should call the 'do' method associated with the indirection method" do - request = stub 'request' - @handler.expects(:uri2indirection).returns request + it "should call the 'do' method and delegate authorization to the RestAuthorization layer" do + @handler.expects(:uri2indirection).returns(["facts", :mymethod, "key", {:node => "name"}]) - request.expects(:method).returns "mymethod" + @handler.expects(:do_mymethod).with("facts", "key", {:node => "name"}, @request, @response) - @handler.expects(:do_mymethod).with(request, @request, @response) - - @handler.process(@request, @response) - end - - it "should delegate authorization to the RestAuthorization layer" do - request = stub 'request' - @handler.expects(:uri2indirection).returns request - - request.expects(:method).returns "mymethod" - - @handler.expects(:do_mymethod).with(request, @request, @response) - - @handler.expects(:check_authorization).with(request) + @handler.expects(:check_authorization).with("facts", :mymethod, "key", {:node => "name"}) @handler.process(@request, @response) end it "should return 403 if the request is not authorized" do - request = stub 'request' - @handler.expects(:uri2indirection).returns request + @handler.expects(:uri2indirection).returns(["facts", :mymethod, "key", {:node => "name"}]) @handler.expects(:do_mymethod).never - @handler.expects(:check_authorization).with(request).raises(Puppet::Network::AuthorizationError.new("forbindden")) + @handler.expects(:check_authorization).with("facts", :mymethod, "key", {:node => "name"}).raises(Puppet::Network::AuthorizationError.new("forbidden")) @handler.expects(:set_response).with { |response, body, status| status == 403 } @@ -117,7 +104,7 @@ describe Puppet::Network::HTTP::Handler do end it "should serialize a controller exception when an exception is thrown while finding the model instance" do - @handler.expects(:uri2indirection).returns stub("request", :method => :find) + @handler.expects(:uri2indirection).returns(["facts", :find, "key", {:node => "name"}]) @handler.expects(:do_find).raises(ArgumentError, "The exception") @handler.expects(:set_response).with { |response, body, status| body == "The exception" and status == 400 } @@ -141,9 +128,8 @@ describe Puppet::Network::HTTP::Handler do describe "when finding a model instance" do before do - @irequest = stub 'indirection_request', :method => :find, :indirection_name => "my_handler", :to_hash => {}, :key => "my_result", :model => @model_class - - @model_class.stubs(:find).returns @result + @indirection.stubs(:find).returns @result + Puppet::Indirector::Indirection.expects(:instance).with(:my_handler).returns( stub "indirection", :model => @model_class ) @format = stub 'format', :suitable? => true, :mime => "text/format", :name => "format" Puppet::Network::FormatHandler.stubs(:format).returns @format @@ -153,40 +139,37 @@ describe Puppet::Network::HTTP::Handler do end it "should use the indirection request to find the model class" do - @irequest.expects(:model).returns @model_class - - @handler.do_find(@irequest, @request, @response) + @handler.do_find("my_handler", "my_result", {}, @request, @response) end it "should use the escaped request key" do - @model_class.expects(:find).with do |key, args| + @indirection.expects(:find).with do |key, args| key == "my_result" end.returns @result - @handler.do_find(@irequest, @request, @response) + @handler.do_find("my_handler", "my_result", {}, @request, @response) end it "should use a common method for determining the request parameters" do - @irequest.stubs(:to_hash).returns(:foo => :baz, :bar => :xyzzy) - @model_class.expects(:find).with do |key, args| + @indirection.expects(:find).with do |key, args| args[:foo] == :baz and args[:bar] == :xyzzy end.returns @result - @handler.do_find(@irequest, @request, @response) + @handler.do_find("my_handler", "my_result", {:foo => :baz, :bar => :xyzzy}, @request, @response) end it "should set the content type to the first format specified in the accept header" do @handler.expects(:accept_header).with(@request).returns "one,two" @handler.expects(:set_content_type).with(@response, @oneformat) - @handler.do_find(@irequest, @request, @response) + @handler.do_find("my_handler", "my_result", {}, @request, @response) end it "should fail if no accept header is provided" do @handler.expects(:accept_header).with(@request).returns nil - lambda { @handler.do_find(@irequest, @request, @response) }.should raise_error(ArgumentError) + lambda { @handler.do_find("my_handler", "my_result", {}, @request, @response) }.should raise_error(ArgumentError) end it "should fail if the accept header does not contain a valid format" do @handler.expects(:accept_header).with(@request).returns "" - lambda { @handler.do_find(@irequest, @request, @response) }.should raise_error(RuntimeError) + lambda { @handler.do_find("my_handler", "my_result", {}, @request, @response) }.should raise_error(RuntimeError) end it "should not use an unsuitable format" do @@ -198,7 +181,7 @@ describe Puppet::Network::HTTP::Handler do @handler.expects(:set_content_type).with(@response, bar) # the suitable one - @handler.do_find(@irequest, @request, @response) + @handler.do_find("my_handler", "my_result", {}, @request, @response) end it "should render the result using the first format specified in the accept header" do @@ -206,18 +189,18 @@ describe Puppet::Network::HTTP::Handler do @handler.expects(:accept_header).with(@request).returns "one,two" @result.expects(:render).with(@oneformat) - @handler.do_find(@irequest, @request, @response) + @handler.do_find("my_handler", "my_result", {}, @request, @response) end it "should pass the result through without rendering it if the result is a string" do - @model_class.stubs(:find).returns "foo" + @indirection.stubs(:find).returns "foo" @handler.expects(:set_response).with(@response, "foo") - @handler.do_find(@irequest, @request, @response) + @handler.do_find("my_handler", "my_result", {}, @request, @response) end it "should use the default status when a model find call succeeds" do @handler.expects(:set_response).with { |response, body, status| status.nil? } - @handler.do_find(@irequest, @request, @response) + @handler.do_find("my_handler", "my_result", {}, @request, @response) end it "should return a serialized object when a model find call succeeds" do @@ -225,24 +208,24 @@ describe Puppet::Network::HTTP::Handler do @model_instance.expects(:render).returns "my_rendered_object" @handler.expects(:set_response).with { |response, body, status| body == "my_rendered_object" } - @model_class.stubs(:find).returns(@model_instance) - @handler.do_find(@irequest, @request, @response) + @indirection.stubs(:find).returns(@model_instance) + @handler.do_find("my_handler", "my_result", {}, @request, @response) end it "should return a 404 when no model instance can be found" do @model_class.stubs(:name).returns "my name" @handler.expects(:set_response).with { |response, body, status| status == 404 } - @model_class.stubs(:find).returns(nil) - @handler.do_find(@irequest, @request, @response) + @indirection.stubs(:find).returns(nil) + @handler.do_find("my_handler", "my_result", {}, @request, @response) end it "should write a log message when no model instance can be found" do @model_class.stubs(:name).returns "my name" - @model_class.stubs(:find).returns(nil) + @indirection.stubs(:find).returns(nil) Puppet.expects(:info).with("Could not find my_handler for 'my_result'") - @handler.do_find(@irequest, @request, @response) + @handler.do_find("my_handler", "my_result", {}, @request, @response) end @@ -251,8 +234,8 @@ describe Puppet::Network::HTTP::Handler do @handler.expects(:format_to_use).returns(@oneformat) @model_instance.expects(:render).with(@oneformat).returns "my_rendered_object" - @model_class.stubs(:find).returns(@model_instance) - @handler.do_find(@irequest, @request, @response) + @indirection.stubs(:find).returns(@model_instance) + @handler.do_find("my_handler", "my_result", {}, @request, @response) end end @@ -291,14 +274,14 @@ describe Puppet::Network::HTTP::Handler do describe "when searching for model instances" do before do - @irequest = stub 'indirection_request', :method => :find, :indirection_name => "my_handler", :to_hash => {}, :key => "key", :model => @model_class + Puppet::Indirector::Indirection.expects(:instance).with(:my_handler).returns( stub "indirection", :model => @model_class ) @result1 = mock 'result1' @result2 = mock 'results' @result = [@result1, @result2] @model_class.stubs(:render_multiple).returns "my rendered instances" - @model_class.stubs(:search).returns(@result) + @indirection.stubs(:search).returns(@result) @format = stub 'format', :suitable? => true, :mime => "text/format", :name => "format" Puppet::Network::FormatHandler.stubs(:format).returns @format @@ -308,115 +291,109 @@ describe Puppet::Network::HTTP::Handler do end it "should use the indirection request to find the model" do - @irequest.expects(:model).returns @model_class - - @handler.do_search(@irequest, @request, @response) + @handler.do_search("my_handler", "my_result", {}, @request, @response) end it "should use a common method for determining the request parameters" do - @irequest.stubs(:to_hash).returns(:foo => :baz, :bar => :xyzzy) - @model_class.expects(:search).with do |key, args| + @indirection.expects(:search).with do |key, args| args[:foo] == :baz and args[:bar] == :xyzzy end.returns @result - @handler.do_search(@irequest, @request, @response) + @handler.do_search("my_handler", "my_result", {:foo => :baz, :bar => :xyzzy}, @request, @response) end it "should use the default status when a model search call succeeds" do - @model_class.stubs(:search).returns(@result) - @handler.do_search(@irequest, @request, @response) + @indirection.stubs(:search).returns(@result) + @handler.do_search("my_handler", "my_result", {}, @request, @response) end it "should set the content type to the first format returned by the accept header" do @handler.expects(:accept_header).with(@request).returns "one,two" @handler.expects(:set_content_type).with(@response, @oneformat) - @handler.do_search(@irequest, @request, @response) + @handler.do_search("my_handler", "my_result", {}, @request, @response) end it "should return a list of serialized objects when a model search call succeeds" do @handler.expects(:accept_header).with(@request).returns "one,two" - @model_class.stubs(:search).returns(@result) + @indirection.stubs(:search).returns(@result) @model_class.expects(:render_multiple).with(@oneformat, @result).returns "my rendered instances" @handler.expects(:set_response).with { |response, data| data == "my rendered instances" } - @handler.do_search(@irequest, @request, @response) + @handler.do_search("my_handler", "my_result", {}, @request, @response) end it "should return [] when searching returns an empty array" do @handler.expects(:accept_header).with(@request).returns "one,two" - @model_class.stubs(:search).returns([]) + @indirection.stubs(:search).returns([]) @model_class.expects(:render_multiple).with(@oneformat, []).returns "[]" @handler.expects(:set_response).with { |response, data| data == "[]" } - @handler.do_search(@irequest, @request, @response) + @handler.do_search("my_handler", "my_result", {}, @request, @response) end it "should return a 404 when searching returns nil" do @model_class.stubs(:name).returns "my name" @handler.expects(:set_response).with { |response, body, status| status == 404 } - @model_class.stubs(:search).returns(nil) - @handler.do_search(@irequest, @request, @response) + @indirection.stubs(:search).returns(nil) + @handler.do_search("my_handler", "my_result", {}, @request, @response) end end describe "when destroying a model instance" do before do - @irequest = stub 'indirection_request', :method => :destroy, :indirection_name => "my_handler", :to_hash => {}, :key => "key", :model => @model_class + Puppet::Indirector::Indirection.expects(:instance).with(:my_handler).returns( stub "indirection", :model => @model_class ) @result = stub 'result', :render => "the result" - @model_class.stubs(:destroy).returns @result + @indirection.stubs(:destroy).returns @result end it "should use the indirection request to find the model" do - @irequest.expects(:model).returns @model_class - - @handler.do_destroy(@irequest, @request, @response) + @handler.do_destroy("my_handler", "my_result", {}, @request, @response) end it "should use the escaped request key to destroy the instance in the model" do - @irequest.expects(:key).returns "foo bar" - @model_class.expects(:destroy).with do |key, args| + @indirection.expects(:destroy).with do |key, args| key == "foo bar" end - @handler.do_destroy(@irequest, @request, @response) + @handler.do_destroy("my_handler", "foo bar", {}, @request, @response) end it "should use a common method for determining the request parameters" do - @irequest.stubs(:to_hash).returns(:foo => :baz, :bar => :xyzzy) - @model_class.expects(:destroy).with do |key, args| + @indirection.expects(:destroy).with do |key, args| args[:foo] == :baz and args[:bar] == :xyzzy end - @handler.do_destroy(@irequest, @request, @response) + @handler.do_destroy("my_handler", "my_result", {:foo => :baz, :bar => :xyzzy}, @request, @response) end it "should use the default status code a model destroy call succeeds" do @handler.expects(:set_response).with { |response, body, status| status.nil? } - @handler.do_destroy(@irequest, @request, @response) + @handler.do_destroy("my_handler", "my_result", {}, @request, @response) end it "should return a yaml-encoded result when a model destroy call succeeds" do @result = stub 'result', :to_yaml => "the result" - @model_class.expects(:destroy).returns(@result) + @indirection.expects(:destroy).returns(@result) @handler.expects(:set_response).with { |response, body, status| body == "the result" } - @handler.do_destroy(@irequest, @request, @response) + @handler.do_destroy("my_handler", "my_result", {}, @request, @response) end end describe "when saving a model instance" do before do - @irequest = stub 'indirection_request', :method => :save, :indirection_name => "my_handler", :to_hash => {}, :key => "key", :model => @model_class + Puppet::Indirector::Indirection.stubs(:instance).with(:my_handler).returns( stub "indirection", :model => @model_class ) @handler.stubs(:body).returns('my stuff') @handler.stubs(:content_type_header).returns("text/yaml") @result = stub 'result', :render => "the result" - @model_instance = stub('indirected model instance', :save => true) + @model_instance = stub('indirected model instance') @model_class.stubs(:convert_from).returns(@model_instance) + @indirection.stubs(:save) @format = stub 'format', :suitable? => true, :name => "format", :mime => "text/format" Puppet::Network::FormatHandler.stubs(:format).returns @format @@ -425,43 +402,41 @@ describe Puppet::Network::HTTP::Handler do end it "should use the indirection request to find the model" do - @irequest.expects(:model).returns @model_class - - @handler.do_save(@irequest, @request, @response) + @handler.do_save("my_handler", "my_result", {}, @request, @response) end it "should use the 'body' hook to retrieve the body of the request" do @handler.expects(:body).returns "my body" @model_class.expects(:convert_from).with { |format, body| body == "my body" }.returns @model_instance - @handler.do_save(@irequest, @request, @response) + @handler.do_save("my_handler", "my_result", {}, @request, @response) end it "should fail to save model if data is not specified" do @handler.stubs(:body).returns('') - lambda { @handler.do_save(@irequest, @request, @response) }.should raise_error(ArgumentError) + lambda { @handler.do_save("my_handler", "my_result", {}, @request, @response) }.should raise_error(ArgumentError) end it "should use a common method for determining the request parameters" do - @model_instance.expects(:save).with('key').once - @handler.do_save(@irequest, @request, @response) + @indirection.expects(:save).with(@model_instance, 'key').once + @handler.do_save("my_handler", "key", {}, @request, @response) end it "should use the default status when a model save call succeeds" do @handler.expects(:set_response).with { |response, body, status| status.nil? } - @handler.do_save(@irequest, @request, @response) + @handler.do_save("my_handler", "my_result", {}, @request, @response) end it "should return the yaml-serialized result when a model save call succeeds" do - @model_instance.stubs(:save).returns(@model_instance) + @indirection.stubs(:save).returns(@model_instance) @model_instance.expects(:to_yaml).returns('foo') - @handler.do_save(@irequest, @request, @response) + @handler.do_save("my_handler", "my_result", {}, @request, @response) end it "should set the content to yaml" do @handler.expects(:set_content_type).with(@response, @yamlformat) - @handler.do_save(@irequest, @request, @response) + @handler.do_save("my_handler", "my_result", {}, @request, @response) end it "should use the content-type header to know the body format" do @@ -470,7 +445,7 @@ describe Puppet::Network::HTTP::Handler do @model_class.expects(:convert_from).with { |format, body| format == "format" }.returns @model_instance - @handler.do_save(@irequest, @request, @response) + @handler.do_save("my_handler", "my_result", {}, @request, @response) end end end diff --git a/spec/unit/network/http/mongrel/rest_spec.rb b/spec/unit/network/http/mongrel/rest_spec.rb index fb24521d5..086fec522 100755 --- a/spec/unit/network/http/mongrel/rest_spec.rb +++ b/spec/unit/network/http/mongrel/rest_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../../../spec_helper') require 'puppet/network/http' diff --git a/spec/unit/network/http/mongrel_spec.rb b/spec/unit/network/http/mongrel_spec.rb index 1e24be0c6..5a67a3fae 100755 --- a/spec/unit/network/http/mongrel_spec.rb +++ b/spec/unit/network/http/mongrel_spec.rb @@ -3,7 +3,7 @@ # Created by Rick Bradley on 2007-10-15. # Copyright (c) 2007. All rights reserved. -require File.dirname(__FILE__) + '/../../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') require 'puppet/network/http' describe "Puppet::Network::HTTP::Mongrel", "after initializing", :if => Puppet.features.mongrel? do diff --git a/spec/unit/network/http/rack/rest_spec.rb b/spec/unit/network/http/rack/rest_spec.rb index 3eed4a2cb..dd49fa057 100755 --- a/spec/unit/network/http/rack/rest_spec.rb +++ b/spec/unit/network/http/rack/rest_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../../../spec_helper') require 'puppet/network/http/rack' if Puppet.features.rack? require 'puppet/network/http/rack/rest' diff --git a/spec/unit/network/http/rack/xmlrpc_spec.rb b/spec/unit/network/http/rack/xmlrpc_spec.rb index e6411524e..e8ae47bf7 100755 --- a/spec/unit/network/http/rack/xmlrpc_spec.rb +++ b/spec/unit/network/http/rack/xmlrpc_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../../../spec_helper') require 'puppet/network/handler' require 'puppet/network/http/rack' if Puppet.features.rack? require 'puppet/network/http/rack/xmlrpc' if Puppet.features.rack? diff --git a/spec/unit/network/http/rack_spec.rb b/spec/unit/network/http/rack_spec.rb index 434294ce8..75d3fdb90 100755 --- a/spec/unit/network/http/rack_spec.rb +++ b/spec/unit/network/http/rack_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') require 'puppet/network/handler' require 'puppet/network/http/rack' if Puppet.features.rack? diff --git a/spec/unit/network/http/webrick/rest_spec.rb b/spec/unit/network/http/webrick/rest_spec.rb index b00c62dc4..b1491e32e 100755 --- a/spec/unit/network/http/webrick/rest_spec.rb +++ b/spec/unit/network/http/webrick/rest_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../../../spec_helper') require 'puppet/network/http' require 'webrick' require 'puppet/network/http/webrick/rest' diff --git a/spec/unit/network/http/webrick_spec.rb b/spec/unit/network/http/webrick_spec.rb index 8e7c92b71..b27a941ea 100755 --- a/spec/unit/network/http/webrick_spec.rb +++ b/spec/unit/network/http/webrick_spec.rb @@ -3,7 +3,7 @@ # Created by Rick Bradley on 2007-10-15. # Copyright (c) 2007. All rights reserved. -require File.dirname(__FILE__) + '/../../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') require 'puppet/network/handler' require 'puppet/network/http' require 'puppet/network/http/webrick' @@ -282,7 +282,7 @@ describe Puppet::Network::HTTP::WEBrick do @cert = stub 'cert', :content => "mycert" @host = stub 'host', :key => @key, :certificate => @cert, :name => "yay", :ssl_store => "mystore" - Puppet::SSL::Certificate.stubs(:find).with('ca').returns @cert + Puppet::SSL::Certificate.indirection.stubs(:find).with('ca').returns @cert Puppet::SSL::Host.stubs(:localhost).returns @host end @@ -299,7 +299,7 @@ describe Puppet::Network::HTTP::WEBrick do end it "should fail if no CA certificate can be found" do - Puppet::SSL::Certificate.stubs(:find).with('ca').returns nil + Puppet::SSL::Certificate.indirection.stubs(:find).with('ca').returns nil lambda { @server.setup_ssl }.should raise_error(Puppet::Error) end diff --git a/spec/unit/network/http_pool_spec.rb b/spec/unit/network/http_pool_spec.rb index 8fa7de8f9..2cd96cea4 100755 --- a/spec/unit/network/http_pool_spec.rb +++ b/spec/unit/network/http_pool_spec.rb @@ -3,7 +3,7 @@ # Created by Luke Kanies on 2007-11-26. # Copyright (c) 2007. All rights reserved. -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') require 'puppet/network/http_pool' describe Puppet::Network::HttpPool do diff --git a/spec/unit/network/http_spec.rb b/spec/unit/network/http_spec.rb index e1d0d2269..8422e2113 100755 --- a/spec/unit/network/http_spec.rb +++ b/spec/unit/network/http_spec.rb @@ -3,7 +3,7 @@ # Created by Rick Bradley on 2007-10-03. # Copyright (c) 2007. All rights reserved. -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') require 'puppet/network/http' diff --git a/spec/unit/network/rest_authconfig_spec.rb b/spec/unit/network/rest_authconfig_spec.rb index d629f8670..e0bcb5af0 100755 --- a/spec/unit/network/rest_authconfig_spec.rb +++ b/spec/unit/network/rest_authconfig_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') require 'puppet/network/rest_authconfig' @@ -22,16 +22,13 @@ describe Puppet::Network::RestAuthConfig do before :each do FileTest.stubs(:exists?).returns(true) File.stubs(:stat).returns(stub('stat', :ctime => :now)) - Time.stubs(:now).returns :now + Time.stubs(:now).returns Time.now @authconfig = Puppet::Network::RestAuthConfig.new("dummy", false) @authconfig.stubs(:read) @acl = stub_everything 'rights' @authconfig.rights = @acl - - @request = stub 'request', :indirection_name => "path", :key => "to/resource", :ip => "127.0.0.1", - :node => "me", :method => :save, :environment => :env, :authenticated => true end it "should use the puppet default rest authorization file" do @@ -40,16 +37,11 @@ describe Puppet::Network::RestAuthConfig do Puppet::Network::RestAuthConfig.new(nil, false) end - it "should read the config file when needed" do - @authconfig.expects(:read) - - @authconfig.allowed?(@request) - end - it "should ask for authorization to the ACL subsystem" do - @acl.expects(:is_request_forbidden_and_why?).with(@request).returns(nil) + params = {:ip => "127.0.0.1", :node => "me", :environment => :env, :authenticated => true} + @acl.expects(:is_request_forbidden_and_why?).with("path", :save, "to/resource", params).returns(nil) - @authconfig.allowed?(@request) + @authconfig.allowed?("path", :save, "to/resource", params) end describe "when defining an acl with mk_acl" do diff --git a/spec/unit/network/rest_authorization_spec.rb b/spec/unit/network/rest_authorization_spec.rb deleted file mode 100755 index 0cb0bcee9..000000000 --- a/spec/unit/network/rest_authorization_spec.rb +++ /dev/null @@ -1,43 +0,0 @@ -#!/usr/bin/env ruby - -require File.dirname(__FILE__) + '/../../spec_helper' - -require 'puppet/network/rest_authorization' - -class RestAuthorized - include Puppet::Network::RestAuthorization -end - - -describe Puppet::Network::RestAuthorization do - before :each do - @auth = RestAuthorized.new - @authconig = stub 'authconfig' - @auth.stubs(:authconfig).returns(@authconfig) - - @request = stub_everything 'request' - @request.stubs(:method).returns(:find) - @request.stubs(:node).returns("node") - @request.stubs(:ip).returns("ip") - end - - describe "when testing request authorization" do - it "should delegate to the current rest authconfig" do - @authconfig.expects(:allowed?).with(@request).returns(true) - - @auth.check_authorization(@request) - end - - it "should raise an AuthorizationError if authconfig raises an AuthorizationError" do - @authconfig.expects(:allowed?).with(@request).raises(Puppet::Network::AuthorizationError.new("forbidden")) - - lambda { @auth.check_authorization(@request) }.should raise_error(Puppet::Network::AuthorizationError) - end - - it "should not raise an AuthorizationError if request is allowed" do - @authconfig.expects(:allowed?).with(@request).returns(true) - - lambda { @auth.check_authorization(@request) }.should_not raise_error(Puppet::Network::AuthorizationError) - end - end -end diff --git a/spec/unit/network/rights_spec.rb b/spec/unit/network/rights_spec.rb index 3b9e48374..8ae03c56d 100755 --- a/spec/unit/network/rights_spec.rb +++ b/spec/unit/network/rights_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') require 'puppet/network/rights' @@ -17,15 +17,15 @@ describe Puppet::Network::Rights do rights.allow("/", "*") rights.restrict_method("/", allowed_method) rights.restrict_authenticated("/", :any) - request = Puppet::Indirector::Request.new(:indirection_name, :head, "key") - rights.is_request_forbidden_and_why?(request).should == nil + rights.is_request_forbidden_and_why?(:indirection_name, :head, "key", {}).should == nil end end it "should disallow the request if neither :find nor :save is allowed" do rights = Puppet::Network::Rights.new - request = Puppet::Indirector::Request.new(:indirection_name, :head, "key") - rights.is_request_forbidden_and_why?(request).should be_instance_of(Puppet::Network::AuthorizationError) + why_forbidden = rights.is_request_forbidden_and_why?(:indirection_name, :head, "key", {}) + why_forbidden.should be_instance_of(Puppet::Network::AuthorizationError) + why_forbidden.to_s.should == "Forbidden request: access to /indirection_name/key [find]" end end diff --git a/spec/unit/network/server_spec.rb b/spec/unit/network/server_spec.rb index c2496dcca..2a63cd4ec 100755 --- a/spec/unit/network/server_spec.rb +++ b/spec/unit/network/server_spec.rb @@ -3,7 +3,7 @@ # Created by Rick Bradley on 2007-10-03. # Copyright (c) 2007. All rights reserved. -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') require 'puppet/network/server' require 'puppet/network/handler' diff --git a/spec/unit/network/xmlrpc/client_spec.rb b/spec/unit/network/xmlrpc/client_spec.rb index 8440d39fa..7498ca4cf 100755 --- a/spec/unit/network/xmlrpc/client_spec.rb +++ b/spec/unit/network/xmlrpc/client_spec.rb @@ -1,7 +1,7 @@ #!/usr/bin/env ruby require 'puppet/network/client' -Dir.chdir(File.dirname(__FILE__)) { (s = lambda { |f| File.exist?(f) ? require(f) : Dir.chdir("..") { s.call(f) } }).call("spec/spec_helper.rb") } +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') describe Puppet::Network::XMLRPCClient do describe "when performing the rpc call" do diff --git a/spec/unit/node/environment_spec.rb b/spec/unit/node/environment_spec.rb index 6109007b9..d34bdb000 100755 --- a/spec/unit/node/environment_spec.rb +++ b/spec/unit/node/environment_spec.rb @@ -1,11 +1,12 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') require 'puppet/node/environment' require 'puppet/util/execution' describe Puppet::Node::Environment do + include PuppetSpec::Files after do Puppet::Node::Environment.clear end @@ -52,7 +53,7 @@ describe Puppet::Node::Environment do before do @env = Puppet::Node::Environment.new("dev") @collection = Puppet::Resource::TypeCollection.new(@env) - @collection.stubs(:perform_initial_import) + @env.stubs(:perform_initial_import).returns(Puppet::Parser::AST::Hostclass.new('')) Thread.current[:known_resource_types] = nil end @@ -66,9 +67,8 @@ describe Puppet::Node::Environment do end it "should perform the initial import when creating a new collection" do - @collection.expects(:perform_initial_import) - Puppet::Resource::TypeCollection.expects(:new).returns @collection - + @env = Puppet::Node::Environment.new("dev") + @env.expects(:perform_initial_import).returns(Puppet::Parser::AST::Hostclass.new('')) @env.known_resource_types end @@ -275,4 +275,61 @@ describe Puppet::Node::Environment do @helper.environment.name.should == :foo end end + + describe "when performing initial import" do + before do + @parser = Puppet::Parser::Parser.new("test") + Puppet::Parser::Parser.stubs(:new).returns @parser + @env = Puppet::Node::Environment.new("env") + end + + it "should set the parser's string to the 'code' setting and parse if code is available" do + Puppet.settings[:code] = "my code" + @parser.expects(:string=).with "my code" + @parser.expects(:parse) + @env.instance_eval { perform_initial_import } + end + + it "should set the parser's file to the 'manifest' setting and parse if no code is available and the manifest is available" do + filename = tmpfile('myfile') + File.open(filename, 'w'){|f| } + Puppet.settings[:manifest] = filename + @parser.expects(:file=).with filename + @parser.expects(:parse) + @env.instance_eval { perform_initial_import } + end + + it "should pass the manifest file to the parser even if it does not exist on disk" do + filename = tmpfile('myfile') + Puppet.settings[:code] = "" + Puppet.settings[:manifest] = filename + @parser.expects(:file=).with(filename).once + @parser.expects(:parse).once + @env.instance_eval { perform_initial_import } + end + + it "should fail helpfully if there is an error importing" do + File.stubs(:exist?).returns true + @env.stubs(:known_resource_types).returns Puppet::Resource::TypeCollection.new(@env) + @parser.expects(:file=).once + @parser.expects(:parse).raises ArgumentError + lambda { @env.instance_eval { perform_initial_import } }.should raise_error(Puppet::Error) + end + + it "should not do anything if the ignore_import settings is set" do + Puppet.settings[:ignoreimport] = true + @parser.expects(:string=).never + @parser.expects(:file=).never + @parser.expects(:parse).never + @env.instance_eval { perform_initial_import } + end + + it "should mark the type collection as needing a reparse when there is an error parsing" do + @parser.expects(:parse).raises Puppet::ParseError.new("Syntax error at ...") + @env.stubs(:known_resource_types).returns Puppet::Resource::TypeCollection.new(@env) + + lambda { @env.instance_eval { perform_initial_import } }.should raise_error(Puppet::Error, /Syntax error at .../) + @env.known_resource_types.require_reparse?.should be_true + end + end end diff --git a/spec/unit/node/facts_spec.rb b/spec/unit/node/facts_spec.rb index cb2aa3dc7..797009ae4 100755 --- a/spec/unit/node/facts_spec.rb +++ b/spec/unit/node/facts_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') require 'puppet/node/facts' @@ -76,16 +76,10 @@ describe Puppet::Node::Facts, "when indirecting" do @facts = Puppet::Node::Facts.new("me", "one" => "two") end - it "should redirect to the specified fact store for retrieval" do - Puppet::Node::Facts.stubs(:indirection).returns(@indirection) - @indirection.expects(:find) - Puppet::Node::Facts.find(:my_facts) - end - it "should redirect to the specified fact store for storage" do Puppet::Node::Facts.stubs(:indirection).returns(@indirection) @indirection.expects(:save) - @facts.save + Puppet::Node::Facts.indirection.save(@facts) end describe "when the Puppet application is 'master'" do diff --git a/spec/unit/node_spec.rb b/spec/unit/node_spec.rb index 36334ea05..ec1b65ee1 100755 --- a/spec/unit/node_spec.rb +++ b/spec/unit/node_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../spec_helper') describe Puppet::Node do describe "when managing its environment" do @@ -84,11 +84,11 @@ end describe Puppet::Node, "when merging facts" do before do @node = Puppet::Node.new("testnode") - Puppet::Node::Facts.stubs(:find).with(@node.name).returns(Puppet::Node::Facts.new(@node.name, "one" => "c", "two" => "b")) + Puppet::Node::Facts.indirection.stubs(:find).with(@node.name).returns(Puppet::Node::Facts.new(@node.name, "one" => "c", "two" => "b")) end it "should fail intelligently if it cannot find facts" do - Puppet::Node::Facts.expects(:find).with(@node.name).raises "foo" + Puppet::Node::Facts.indirection.expects(:find).with(@node.name).raises "foo" lambda { @node.fact_merge }.should raise_error(Puppet::Error) end @@ -128,13 +128,6 @@ describe Puppet::Node, "when merging facts" do end describe Puppet::Node, "when indirecting" do - it "should redirect to the indirection" do - @indirection = stub 'indirection', :name => :node - Puppet::Node.stubs(:indirection).returns(@indirection) - @indirection.expects(:find) - Puppet::Node.find(:my_node.to_s) - end - it "should default to the 'plain' node terminus" do Puppet::Node.indirection.terminus_class.should == :plain end diff --git a/spec/unit/other/selinux_spec.rb b/spec/unit/other/selinux_spec.rb index 4ec0bba5a..7f908885f 100644 --- a/spec/unit/other/selinux_spec.rb +++ b/spec/unit/other/selinux_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') require 'puppet/type/selboolean' require 'puppet/type/selmodule' diff --git a/spec/unit/other/transbucket_spec.rb b/spec/unit/other/transbucket_spec.rb index a5c4b47a4..6bc257897 100755 --- a/spec/unit/other/transbucket_spec.rb +++ b/spec/unit/other/transbucket_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') describe Puppet::TransBucket do before do diff --git a/spec/unit/other/transobject_spec.rb b/spec/unit/other/transobject_spec.rb index 352af48fd..c2652a386 100755 --- a/spec/unit/other/transobject_spec.rb +++ b/spec/unit/other/transobject_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') require 'puppet/transportable' diff --git a/spec/unit/parameter/value_collection_spec.rb b/spec/unit/parameter/value_collection_spec.rb index cb82d1517..99e4302bc 100755 --- a/spec/unit/parameter/value_collection_spec.rb +++ b/spec/unit/parameter/value_collection_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') require 'puppet/parameter' diff --git a/spec/unit/parameter/value_spec.rb b/spec/unit/parameter/value_spec.rb index 10b24fb4d..cb44770b4 100755 --- a/spec/unit/parameter/value_spec.rb +++ b/spec/unit/parameter/value_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') require 'puppet/parameter' diff --git a/spec/unit/parameter_spec.rb b/spec/unit/parameter_spec.rb index f8ab05d62..c9ef32faf 100755 --- a/spec/unit/parameter_spec.rb +++ b/spec/unit/parameter_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../spec_helper') require 'puppet/parameter' diff --git a/spec/unit/parser/ast/arithmetic_operator_spec.rb b/spec/unit/parser/ast/arithmetic_operator_spec.rb index 093cf94f1..381c5c629 100755 --- a/spec/unit/parser/ast/arithmetic_operator_spec.rb +++ b/spec/unit/parser/ast/arithmetic_operator_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') describe Puppet::Parser::AST::ArithmeticOperator do diff --git a/spec/unit/parser/ast/astarray_spec.rb b/spec/unit/parser/ast/astarray_spec.rb index f79d6c533..01082b3f0 100755 --- a/spec/unit/parser/ast/astarray_spec.rb +++ b/spec/unit/parser/ast/astarray_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') describe Puppet::Parser::AST::ASTArray do before :each do @@ -23,43 +23,26 @@ describe Puppet::Parser::AST::ASTArray do operator.evaluate(@scope) end - it "should evaluate childrens of type ASTArray" do - item1 = stub "item1", :is_a? => true - item2 = stub "item2" - item2.stubs(:is_a?).with(Puppet::Parser::AST).returns(true) - item2.stubs(:instance_of?).with(Puppet::Parser::AST::ASTArray).returns(true) - item2.stubs(:each).yields(item1) - - item1.expects(:safeevaluate).with(@scope).returns(123) - - operator = Puppet::Parser::AST::ASTArray.new :children => [item2] - operator.evaluate(@scope).should == [123] - end - - it "should flatten children coming from children ASTArray" do - item1 = stub "item1", :is_a? => true - item2 = stub "item2" - item2.stubs(:is_a?).with(Puppet::Parser::AST).returns(true) - item2.stubs(:instance_of?).with(Puppet::Parser::AST::ASTArray).returns(true) - item2.stubs(:each).yields([item1]) - - item1.expects(:safeevaluate).with(@scope).returns(123) - - operator = Puppet::Parser::AST::ASTArray.new :children => [item2] - operator.evaluate(@scope).should == [123] + it "should not flatten children coming from children ASTArray" do + item = Puppet::Parser::AST::String.new :value => 'foo' + inner_array = Puppet::Parser::AST::ASTArray.new :children => [item, item] + operator = Puppet::Parser::AST::ASTArray.new :children => [inner_array, inner_array] + operator.evaluate(@scope).should == [['foo', 'foo'], ['foo', 'foo']] end it "should not flatten the results of children evaluation" do - item1 = stub "item1", :is_a? => true - item2 = stub "item2" - item2.stubs(:is_a?).with(Puppet::Parser::AST).returns(true) - item2.stubs(:instance_of?).with(Puppet::Parser::AST::ASTArray).returns(true) - item2.stubs(:each).yields([item1]) - - item1.expects(:safeevaluate).with(@scope).returns([123]) + item = Puppet::Parser::AST::String.new :value => 'foo' + item.stubs(:evaluate).returns(['foo']) + operator = Puppet::Parser::AST::ASTArray.new :children => [item, item] + operator.evaluate(@scope).should == [['foo'], ['foo']] + end - operator = Puppet::Parser::AST::ASTArray.new :children => [item2] - operator.evaluate(@scope).should == [[123]] + it "should discard nil results from children evaluation" do + item1 = Puppet::Parser::AST::String.new :value => 'foo' + item2 = Puppet::Parser::AST::String.new :value => 'foo' + item2.stubs(:evaluate).returns(nil) + operator = Puppet::Parser::AST::ASTArray.new :children => [item1, item2] + operator.evaluate(@scope).should == ['foo'] end it "should return a valid string with to_s" do diff --git a/spec/unit/parser/ast/asthash_spec.rb b/spec/unit/parser/ast/asthash_spec.rb index c70553c56..83f604545 100644 --- a/spec/unit/parser/ast/asthash_spec.rb +++ b/spec/unit/parser/ast/asthash_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') describe Puppet::Parser::AST::ASTHash do before :each do diff --git a/spec/unit/parser/ast/boolean_operator_spec.rb b/spec/unit/parser/ast/boolean_operator_spec.rb index 10e987e31..529946694 100755 --- a/spec/unit/parser/ast/boolean_operator_spec.rb +++ b/spec/unit/parser/ast/boolean_operator_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') describe Puppet::Parser::AST::BooleanOperator do diff --git a/spec/unit/parser/ast/casestatement_spec.rb b/spec/unit/parser/ast/casestatement_spec.rb index 4d79e54cb..bce3ad801 100755 --- a/spec/unit/parser/ast/casestatement_spec.rb +++ b/spec/unit/parser/ast/casestatement_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') describe Puppet::Parser::AST::CaseStatement do before :each do @@ -13,11 +13,14 @@ describe Puppet::Parser::AST::CaseStatement do @test = stub 'test' @test.stubs(:safeevaluate).with(@scope).returns("value") - @option1 = stub 'option1', :eachopt => nil, :default? => false - @option2 = stub 'option2', :eachopt => nil, :default? => false + @option1 = Puppet::Parser::AST::CaseOpt.new({}) + @option1.stubs(:eachopt) + @option1.stubs(:default?).returns false + @option2 = Puppet::Parser::AST::CaseOpt.new({}) + @option2.stubs(:eachopt) + @option2.stubs(:default?).returns false - @options = stub 'options' - @options.stubs(:each).multiple_yields(@option1, @option2) + @options = Puppet::Parser::AST::ASTArray.new(:children => [@option1, @option2]) @casestmt = Puppet::Parser::AST::CaseStatement.new :test => @test, :options => @options end @@ -29,8 +32,6 @@ describe Puppet::Parser::AST::CaseStatement do end it "should scan each option" do - @options.expects(:each).multiple_yields(@option1, @option2) - @casestmt.evaluate(@scope) end @@ -137,12 +138,15 @@ describe Puppet::Parser::AST::CaseStatement do options = tests.collect do |result, values| values = values.collect { |v| AST::Leaf.new :value => v } - AST::CaseOpt.new( - :value => AST::ASTArray.new(:children => values), - - :statements => AST::Leaf.new(:value => result)) + AST::CaseOpt.new( + :value => AST::ASTArray.new(:children => values), + :statements => AST::Leaf.new(:value => result) + ) end - options << AST::CaseOpt.new(:value => AST::Default.new(:value => "default"), :statements => AST::Leaf.new(:value => "default")) + options << AST::CaseOpt.new( + :value => AST::Default.new(:value => "default"), + :statements => AST::Leaf.new(:value => "default") + ) ast = nil param = AST::Variable.new(:value => "testparam") diff --git a/spec/unit/parser/ast/collection_spec.rb b/spec/unit/parser/ast/collection_spec.rb index cc33075b7..99abc998d 100755 --- a/spec/unit/parser/ast/collection_spec.rb +++ b/spec/unit/parser/ast/collection_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') describe Puppet::Parser::AST::Collection do before :each do diff --git a/spec/unit/parser/ast/collexpr_spec.rb b/spec/unit/parser/ast/collexpr_spec.rb index 01276dfb3..04ce69cd3 100755 --- a/spec/unit/parser/ast/collexpr_spec.rb +++ b/spec/unit/parser/ast/collexpr_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') describe Puppet::Parser::AST::CollExpr do diff --git a/spec/unit/parser/ast/comparison_operator_spec.rb b/spec/unit/parser/ast/comparison_operator_spec.rb index 931f936df..03c9069cb 100755 --- a/spec/unit/parser/ast/comparison_operator_spec.rb +++ b/spec/unit/parser/ast/comparison_operator_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') describe Puppet::Parser::AST::ComparisonOperator do before :each do diff --git a/spec/unit/parser/ast/definition_spec.rb b/spec/unit/parser/ast/definition_spec.rb new file mode 100644 index 000000000..e7f55d258 --- /dev/null +++ b/spec/unit/parser/ast/definition_spec.rb @@ -0,0 +1,22 @@ +#!/usr/bin/env ruby + +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') + +describe Puppet::Parser::AST::Definition do + it "should make its context available through an accessor" do + definition = Puppet::Parser::AST::Definition.new('foo', :line => 5) + definition.context.should == {:line => 5} + end + + describe "when instantiated" do + it "should create a definition with the proper type, name, context, and module name" do + definition = Puppet::Parser::AST::Definition.new('foo', :line => 5) + instantiated_definitions = definition.instantiate('modname') + instantiated_definitions.length.should == 1 + instantiated_definitions[0].type.should == :definition + instantiated_definitions[0].name.should == 'foo' + instantiated_definitions[0].line.should == 5 + instantiated_definitions[0].module_name.should == 'modname' + end + end +end diff --git a/spec/unit/parser/ast/function_spec.rb b/spec/unit/parser/ast/function_spec.rb index 38e344157..cd4b0f94e 100644 --- a/spec/unit/parser/ast/function_spec.rb +++ b/spec/unit/parser/ast/function_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') describe Puppet::Parser::AST::Function do before :each do diff --git a/spec/unit/parser/ast/hostclass_spec.rb b/spec/unit/parser/ast/hostclass_spec.rb new file mode 100644 index 000000000..390490788 --- /dev/null +++ b/spec/unit/parser/ast/hostclass_spec.rb @@ -0,0 +1,73 @@ +#!/usr/bin/env ruby + +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') + +describe Puppet::Parser::AST::Hostclass do + def ast + Puppet::Parser::AST + end + + def newarray(*elems) + ast::ASTArray.new({}).push(*elems) + end + + it "should make its name and context available through accessors" do + hostclass = ast::Hostclass.new('foo', :line => 5) + hostclass.name.should == 'foo' + hostclass.context.should == {:line => 5} + end + + it "should make its code available through an accessor" do + code = newarray + hostclass = ast::Hostclass.new('foo', :code => code) + hostclass.code.should be_equal(code) + end + + describe "when instantiated" do + it "should create a class with the proper type, code, name, context, and module name" do + code = newarray + hostclass = ast::Hostclass.new('foo', :code => code, :line => 5) + instantiated_class = hostclass.instantiate('modname')[0] + instantiated_class.type.should == :hostclass + instantiated_class.name.should == 'foo' + instantiated_class.code.should be_equal(code) + instantiated_class.line.should == 5 + instantiated_class.module_name.should == 'modname' + end + + it "should instantiate all nested classes, defines, and nodes with the same module name." do + nested_objects = newarray(ast::Hostclass.new('foo::child1'), + ast::Definition.new('foo::child2'), + ast::Definition.new('child3')) + hostclass = ast::Hostclass.new('foo', :code => nested_objects) + instantiated_classes = hostclass.instantiate('modname') + instantiated_classes.length.should == 4 + instantiated_classes[0].name.should == 'foo' + instantiated_classes[1].name.should == 'foo::child1' + instantiated_classes[2].name.should == 'foo::child2' + instantiated_classes[3].name.should == 'child3' + instantiated_classes.each { |cls| cls.module_name.should == 'modname' } + end + + it "should handle a nested class that contains its own nested classes." do + foo_bar_baz = ast::Hostclass.new('foo::bar::baz') + foo_bar = ast::Hostclass.new('foo::bar', :code => newarray(foo_bar_baz)) + foo = ast::Hostclass.new('foo', :code => newarray(foo_bar)) + instantiated_classes = foo.instantiate('') + instantiated_classes.length.should == 3 + instantiated_classes[0].name.should == 'foo' + instantiated_classes[1].name.should == 'foo::bar' + instantiated_classes[2].name.should == 'foo::bar::baz' + end + + it "should skip nested elements that are not classes, definitions, or nodes." do + func = ast::Function.new(:name => 'biz', :arguments => newarray(ast::Name.new(:value => 'baz'))) + foo = ast::Hostclass.new('foo', :code => newarray(func)) + instantiated_classes = foo.instantiate('') + instantiated_classes.length.should == 1 + instantiated_classes[0].should be_a(Puppet::Resource::Type) + instantiated_classes[0].name.should == 'foo' + end + end +end + diff --git a/spec/unit/parser/ast/ifstatement_spec.rb b/spec/unit/parser/ast/ifstatement_spec.rb index 2a9e1e37b..6a2fed22c 100755 --- a/spec/unit/parser/ast/ifstatement_spec.rb +++ b/spec/unit/parser/ast/ifstatement_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') describe Puppet::Parser::AST::IfStatement do before :each do diff --git a/spec/unit/parser/ast/in_operator_spec.rb b/spec/unit/parser/ast/in_operator_spec.rb index aebe442ab..08c01582e 100644 --- a/spec/unit/parser/ast/in_operator_spec.rb +++ b/spec/unit/parser/ast/in_operator_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') require 'puppet/parser/ast/in_operator' diff --git a/spec/unit/parser/ast/leaf_spec.rb b/spec/unit/parser/ast/leaf_spec.rb index a19c24115..2119a27a8 100755 --- a/spec/unit/parser/ast/leaf_spec.rb +++ b/spec/unit/parser/ast/leaf_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') describe Puppet::Parser::AST::Leaf do before :each do diff --git a/spec/unit/parser/ast/match_operator_spec.rb b/spec/unit/parser/ast/match_operator_spec.rb index d6e998751..f2a68b676 100755 --- a/spec/unit/parser/ast/match_operator_spec.rb +++ b/spec/unit/parser/ast/match_operator_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') describe Puppet::Parser::AST::MatchOperator do before :each do diff --git a/spec/unit/parser/ast/minus_spec.rb b/spec/unit/parser/ast/minus_spec.rb index 108c8812e..339087e80 100755 --- a/spec/unit/parser/ast/minus_spec.rb +++ b/spec/unit/parser/ast/minus_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') describe Puppet::Parser::AST::Minus do before :each do diff --git a/spec/unit/parser/ast/node_spec.rb b/spec/unit/parser/ast/node_spec.rb new file mode 100644 index 000000000..c4e20ca67 --- /dev/null +++ b/spec/unit/parser/ast/node_spec.rb @@ -0,0 +1,31 @@ +#!/usr/bin/env ruby + +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') + +describe Puppet::Parser::AST::Node do + describe "when instantiated" do + it "should make its names and context available through accessors" do + node = Puppet::Parser::AST::Node.new(['foo', 'bar'], :line => 5) + node.names.should == ['foo', 'bar'] + node.context.should == {:line => 5} + end + + it "should create a node with the proper type, name, context, and module name" do + node = Puppet::Parser::AST::Node.new(['foo'], :line => 5) + instantiated_nodes = node.instantiate('modname') + instantiated_nodes.length.should == 1 + instantiated_nodes[0].type.should == :node + instantiated_nodes[0].name.should == 'foo' + instantiated_nodes[0].line.should == 5 + instantiated_nodes[0].module_name.should == 'modname' + end + + it "should handle multiple names" do + node = Puppet::Parser::AST::Node.new(['foo', 'bar']) + instantiated_nodes = node.instantiate('modname') + instantiated_nodes.length.should == 2 + instantiated_nodes[0].name.should == 'foo' + instantiated_nodes[1].name.should == 'bar' + end + end +end diff --git a/spec/unit/parser/ast/nop_spec.rb b/spec/unit/parser/ast/nop_spec.rb index 3e493197a..3fa2fc0ee 100755 --- a/spec/unit/parser/ast/nop_spec.rb +++ b/spec/unit/parser/ast/nop_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') describe Puppet::Parser::AST::Nop do diff --git a/spec/unit/parser/ast/not_spec.rb b/spec/unit/parser/ast/not_spec.rb index 2ef6e0689..31a425132 100755 --- a/spec/unit/parser/ast/not_spec.rb +++ b/spec/unit/parser/ast/not_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') describe Puppet::Parser::AST::Not do before :each do diff --git a/spec/unit/parser/ast/relationship_spec.rb b/spec/unit/parser/ast/relationship_spec.rb index 2a0f658df..d8bc3a535 100644 --- a/spec/unit/parser/ast/relationship_spec.rb +++ b/spec/unit/parser/ast/relationship_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') describe Puppet::Parser::AST::Relationship do before do diff --git a/spec/unit/parser/ast/resource_defaults_spec.rb b/spec/unit/parser/ast/resource_defaults_spec.rb index 7843fd9a9..36eb8df5f 100755 --- a/spec/unit/parser/ast/resource_defaults_spec.rb +++ b/spec/unit/parser/ast/resource_defaults_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') describe Puppet::Parser::AST::ResourceDefaults do diff --git a/spec/unit/parser/ast/resource_override_spec.rb b/spec/unit/parser/ast/resource_override_spec.rb index 637ab41fc..7ca3a7e8c 100755 --- a/spec/unit/parser/ast/resource_override_spec.rb +++ b/spec/unit/parser/ast/resource_override_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') describe Puppet::Parser::AST::ResourceOverride do diff --git a/spec/unit/parser/ast/resource_reference_spec.rb b/spec/unit/parser/ast/resource_reference_spec.rb index 93419d963..492c25490 100755 --- a/spec/unit/parser/ast/resource_reference_spec.rb +++ b/spec/unit/parser/ast/resource_reference_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') describe Puppet::Parser::AST::ResourceReference do diff --git a/spec/unit/parser/ast/resource_spec.rb b/spec/unit/parser/ast/resource_spec.rb index 721c31a8d..b00fee587 100755 --- a/spec/unit/parser/ast/resource_spec.rb +++ b/spec/unit/parser/ast/resource_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') describe Puppet::Parser::AST::Resource do ast = Puppet::Parser::AST @@ -11,14 +11,15 @@ describe Puppet::Parser::AST::Resource do @compiler = Puppet::Parser::Compiler.new(Puppet::Node.new("mynode")) @scope = Puppet::Parser::Scope.new(:compiler => @compiler) @scope.stubs(:resource).returns(stub_everything) - @resource = ast::Resource.new(:title => @title, :type => "file", :parameters => ast::ASTArray.new(:children => []) ) + @instance = ast::ResourceInstance.new(:title => @title, :parameters => ast::ASTArray.new(:children => [])) + @resource = ast::Resource.new(:type => "file", :instances => ast::ASTArray.new(:children => [@instance])) @resource.stubs(:qualified_type).returns("Resource") end it "should evaluate all its parameters" do param = stub 'param' param.expects(:safeevaluate).with(@scope).returns Puppet::Parser::Resource::Param.new(:name => "myparam", :value => "myvalue", :source => stub("source")) - @resource.stubs(:parameters).returns [param] + @instance.stubs(:parameters).returns [param] @resource.evaluate(@scope) end @@ -35,7 +36,7 @@ describe Puppet::Parser::AST::Resource do array = Puppet::Parser::AST::ASTArray.new(:children => titles) - @resource.title = array + @instance.title = array result = @resource.evaluate(@scope).collect { |r| r.title } result.should be_include("one") result.should be_include("two") @@ -49,12 +50,19 @@ describe Puppet::Parser::AST::Resource do array = Puppet::Parser::AST::ASTArray.new(:children => titles) - @resource.title = array + @instance.title = array result = @resource.evaluate(@scope).collect { |r| r.title } result.should be_include("one") result.should be_include("two") end + it "should implicitly iterate over instances" do + new_title = Puppet::Parser::AST::String.new(:value => "other_title") + new_instance = ast::ResourceInstance.new(:title => new_title, :parameters => ast::ASTArray.new(:children => [])) + @resource.instances.push(new_instance) + @resource.evaluate(@scope).collect { |r| r.title }.should == ["mytitle", "other_title"] + end + it "should handover resources to the compiler" do titles = [] %w{one two}.each do |title| @@ -63,7 +71,7 @@ describe Puppet::Parser::AST::Resource do array = Puppet::Parser::AST::ASTArray.new(:children => titles) - @resource.title = array + @instance.title = array result = @resource.evaluate(@scope) result.each do |res| @@ -91,16 +99,19 @@ describe Puppet::Parser::AST::Resource do before do @scope = Puppet::Parser::Scope.new :compiler => Puppet::Parser::Compiler.new(Puppet::Node.new("mynode")) @parser = Puppet::Parser::Parser.new(Puppet::Node::Environment.new) - @parser.newdefine "one" - @parser.newdefine "one::two" - @parser.newdefine "three" + ["one", "one::two", "three"].each do |name| + @parser.environment.known_resource_types.add(Puppet::Resource::Type.new(:definition, name, {})) + end @twoscope = @scope.newscope(:namespace => "one") @twoscope.resource = @scope.resource end def resource(type, params = nil) params ||= Puppet::Parser::AST::ASTArray.new(:children => []) - Puppet::Parser::AST::Resource.new(:type => type, :title => Puppet::Parser::AST::String.new(:value => "myresource"), :parameters => params) + instance = Puppet::Parser::AST::ResourceInstance.new( + :title => Puppet::Parser::AST::String.new(:value => "myresource"), :parameters => params) + Puppet::Parser::AST::Resource.new(:type => type, + :instances => Puppet::Parser::AST::ASTArray.new(:children => [instance])) end it "should be able to generate resources with fully qualified type information" do @@ -141,7 +152,8 @@ describe Puppet::Parser::AST::Resource do @compiler = Puppet::Parser::Compiler.new(Puppet::Node.new("mynode")) @scope = Puppet::Parser::Scope.new(:compiler => @compiler) @scope.stubs(:resource).returns(stub_everything) - @resource = ast::Resource.new(:title => @title, :type => "Class", :parameters => ast::ASTArray.new(:children => []) ) + @instance = ast::ResourceInstance.new(:title => @title, :parameters => ast::ASTArray.new(:children => [])) + @resource = ast::Resource.new(:type => "Class", :instances => ast::ASTArray.new(:children => [@instance])) @resource.stubs(:qualified_type).returns("Resource") @type = Puppet::Resource::Type.new(:hostclass, "classname") @compiler.known_resource_types.add(@type) diff --git a/spec/unit/parser/ast/selector_spec.rb b/spec/unit/parser/ast/selector_spec.rb index 42898475f..4c13aa7ba 100755 --- a/spec/unit/parser/ast/selector_spec.rb +++ b/spec/unit/parser/ast/selector_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') describe Puppet::Parser::AST::Selector do before :each do diff --git a/spec/unit/parser/ast/vardef_spec.rb b/spec/unit/parser/ast/vardef_spec.rb index a90010f5a..9c8b77905 100755 --- a/spec/unit/parser/ast/vardef_spec.rb +++ b/spec/unit/parser/ast/vardef_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') describe Puppet::Parser::AST::VarDef do before :each do diff --git a/spec/unit/parser/ast_spec.rb b/spec/unit/parser/ast_spec.rb index 29dce2b9c..cdfb51869 100644 --- a/spec/unit/parser/ast_spec.rb +++ b/spec/unit/parser/ast_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') require 'puppet/parser/ast' diff --git a/spec/unit/parser/collector_spec.rb b/spec/unit/parser/collector_spec.rb index 4cab26c44..100a04daf 100755 --- a/spec/unit/parser/collector_spec.rb +++ b/spec/unit/parser/collector_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') require 'puppet/rails' require 'puppet/parser/collector' diff --git a/spec/unit/parser/compiler_spec.rb b/spec/unit/parser/compiler_spec.rb index 261cfdec1..e4b18e14b 100755 --- a/spec/unit/parser/compiler_spec.rb +++ b/spec/unit/parser/compiler_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') class CompilerTestResource attr_accessor :builtin, :virtual, :evaluated, :type, :title @@ -576,17 +576,16 @@ describe Puppet::Parser::Compiler do proc { @compiler.evaluate_classes(%w{one two}, scope) }.should raise_error(Puppet::DevError) end - it "should tag the catalog with the name of each not-found class" do - @compiler.catalog.expects(:tag).with("notfound") + it "should raise an error if a class is not found" do @scope.expects(:find_hostclass).with("notfound").returns(nil) - @compiler.evaluate_classes(%w{notfound}, @scope) + lambda{ @compiler.evaluate_classes(%w{notfound}, @scope) }.should raise_error(Puppet::Error, /Could not find class/) end - it "should log when it can't find class" do + + it "should raise an error when it can't find class" do klasses = {'foo'=>nil} @node.classes = klasses @compiler.topscope.stubs(:find_hostclass).with('foo').returns(nil) - Puppet.expects(:warning).with('Could not find class foo for testnode') - @compiler.compile + lambda{ @compiler.compile }.should raise_error(Puppet::Error, /Could not find class foo for testnode/) end end @@ -713,18 +712,6 @@ describe Puppet::Parser::Compiler do Puppet::Parser::Resource.expects(:new).never @compiler.evaluate_classes(%w{MyClass}, @scope, false) end - - it "should return the list of found classes" do - @compiler.catalog.stubs(:tag) - - @compiler.stubs(:add_resource) - @scope.stubs(:find_hostclass).with("notfound").returns(nil) - @scope.stubs(:class_scope).with(@class) - - Puppet::Parser::Resource.stubs(:new).returns(@resource) - @class.stubs :ensure_in_catalog - @compiler.evaluate_classes(%w{myclass notfound}, @scope).should == %w{myclass} - end end describe "when evaluating AST nodes with no AST nodes present" do diff --git a/spec/unit/parser/files_spec.rb b/spec/unit/parser/files_spec.rb index 3eb0db07e..525c83697 100644 --- a/spec/unit/parser/files_spec.rb +++ b/spec/unit/parser/files_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') require 'puppet/parser/files' diff --git a/spec/unit/parser/functions/create_resources_spec.rb b/spec/unit/parser/functions/create_resources_spec.rb new file mode 100755 index 000000000..366fb536c --- /dev/null +++ b/spec/unit/parser/functions/create_resources_spec.rb @@ -0,0 +1,137 @@ +require 'puppet' +require File.dirname(__FILE__) + '/../../../spec_helper' + +describe 'function for dynamically creating resources' do + + def get_scope + @topscope = Puppet::Parser::Scope.new + # This is necessary so we don't try to use the compiler to discover our parent. + @topscope.parent = nil + @scope = Puppet::Parser::Scope.new + @scope.compiler = Puppet::Parser::Compiler.new(Puppet::Node.new("floppy", :environment => 'production')) + @scope.parent = @topscope + @compiler = @scope.compiler + end + before :each do + get_scope + Puppet::Parser::Functions.function(:create_resources) + end + + it "should exist" do + Puppet::Parser::Functions.function(:create_resources).should == "function_create_resources" + end + it 'should require two arguments' do + lambda { @scope.function_create_resources(['foo']) }.should raise_error(ArgumentError, 'create_resources(): wrong number of arguments (1; must be 2)') + end + describe 'when creating native types' do + before :each do + Puppet[:code]='notify{test:}' + get_scope + @scope.resource=Puppet::Parser::Resource.new('class', 't', :scope => @scope) + end + it 'empty hash should not cause resources to be added' do + @scope.function_create_resources(['file', {}]) + @compiler.catalog.resources.size == 1 + end + it 'should be able to add' do + @scope.function_create_resources(['file', {'/etc/foo'=>{'ensure'=>'present'}}]) + @compiler.catalog.resource(:file, "/etc/foo")['ensure'].should == 'present' + end + it 'should accept multiple types' do + type_hash = {} + type_hash['foo'] = {'message' => 'one'} + type_hash['bar'] = {'message' => 'two'} + @scope.function_create_resources(['notify', type_hash]) + @compiler.catalog.resource(:notify, "foo")['message'].should == 'one' + @compiler.catalog.resource(:notify, "bar")['message'].should == 'two' + end + it 'should fail to add non-existing type' do + lambda { @scope.function_create_resources(['foo', {}]) }.should raise_error(ArgumentError, 'could not create resource of unknown type foo') + end + it 'should be able to add edges' do + @scope.function_create_resources(['notify', {'foo'=>{'require' => 'Notify[test]'}}]) + @scope.compiler.compile + rg = @scope.compiler.catalog.to_ral.relationship_graph + test = rg.vertices.find { |v| v.title == 'test' } + foo = rg.vertices.find { |v| v.title == 'foo' } + test.should be + foo.should be + rg.path_between(test,foo).should be + end + end + describe 'when dynamically creating resource types' do + before :each do + Puppet[:code]= +'define foo($one){notify{$name: message => $one}} +notify{test:} +' + get_scope + @scope.resource=Puppet::Parser::Resource.new('class', 't', :scope => @scope) + Puppet::Parser::Functions.function(:create_resources) + end + it 'should be able to create defined resoure types' do + @scope.function_create_resources(['foo', {'blah'=>{'one'=>'two'}}]) + # still have to compile for this to work... + # I am not sure if this constraint ruins the tests + @scope.compiler.compile + @compiler.catalog.resource(:notify, "blah")['message'].should == 'two' + end + it 'should fail if defines are missing params' do + @scope.function_create_resources(['foo', {'blah'=>{}}]) + lambda { @scope.compiler.compile }.should raise_error(Puppet::ParseError, 'Must pass one to Foo[blah] at line 1') + end + it 'should be able to add multiple defines' do + hash = {} + hash['blah'] = {'one' => 'two'} + hash['blaz'] = {'one' => 'three'} + @scope.function_create_resources(['foo', hash]) + # still have to compile for this to work... + # I am not sure if this constraint ruins the tests + @scope.compiler.compile + @compiler.catalog.resource(:notify, "blah")['message'].should == 'two' + @compiler.catalog.resource(:notify, "blaz")['message'].should == 'three' + end + it 'should be able to add edges' do + @scope.function_create_resources(['foo', {'blah'=>{'one'=>'two', 'require' => 'Notify[test]'}}]) + @scope.compiler.compile + rg = @scope.compiler.catalog.to_ral.relationship_graph + test = rg.vertices.find { |v| v.title == 'test' } + blah = rg.vertices.find { |v| v.title == 'blah' } + test.should be + blah.should be + # (Yoda speak like we do) + rg.path_between(test,blah).should be + @compiler.catalog.resource(:notify, "blah")['message'].should == 'two' + end + end + describe 'when creating classes' do + before :each do + Puppet[:code]= +'class bar($one){notify{test: message => $one}} +notify{tester:} +' + get_scope + @scope.resource=Puppet::Parser::Resource.new('class', 't', :scope => @scope) + Puppet::Parser::Functions.function(:create_resources) + end + it 'should be able to create classes' do + @scope.function_create_resources(['class', {'bar'=>{'one'=>'two'}}]) + @scope.compiler.compile + @compiler.catalog.resource(:notify, "test")['message'].should == 'two' + @compiler.catalog.resource(:class, "bar").should_not be_nil#['message'].should == 'two' + end + it 'should fail to create non-existing classes' do + lambda { @scope.function_create_resources(['class', {'blah'=>{'one'=>'two'}}]) }.should raise_error(ArgumentError ,'could not find hostclass blah') + end + it 'should be able to add edges' do + @scope.function_create_resources(['class', {'bar'=>{'one'=>'two', 'require' => 'Notify[tester]'}}]) + @scope.compiler.compile + rg = @scope.compiler.catalog.to_ral.relationship_graph + test = rg.vertices.find { |v| v.title == 'test' } + tester = rg.vertices.find { |v| v.title == 'tester' } + test.should be + tester.should be + rg.path_between(tester,test).should be + end + end +end diff --git a/spec/unit/parser/functions/defined_spec.rb b/spec/unit/parser/functions/defined_spec.rb index cf3f66e17..0113c3233 100755 --- a/spec/unit/parser/functions/defined_spec.rb +++ b/spec/unit/parser/functions/defined_spec.rb @@ -1,8 +1,11 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') describe "the 'defined' function" do + before :all do + Puppet::Parser::Functions.autoloader.loadall + end before :each do Puppet::Node::Environment.stubs(:current).returns(nil) diff --git a/spec/unit/parser/functions/extlookup_spec.rb b/spec/unit/parser/functions/extlookup_spec.rb index a3dcaa742..46cd3cc27 100755 --- a/spec/unit/parser/functions/extlookup_spec.rb +++ b/spec/unit/parser/functions/extlookup_spec.rb @@ -1,15 +1,16 @@ #! /usr/bin/env ruby -require File.dirname(__FILE__) + '/../../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') require 'tempfile' describe "the extlookup function" do + before :all do + Puppet::Parser::Functions.autoloader.loadall + end before :each do @scope = Puppet::Parser::Scope.new - @scope.stubs(:environment).returns(Puppet::Node::Environment.new('production')) - Puppet::Parser::Functions.function("extlookup") end it "should exist" do diff --git a/spec/unit/parser/functions/fqdn_rand_spec.rb b/spec/unit/parser/functions/fqdn_rand_spec.rb index 81c12c6a7..be2e6fa76 100644..100755 --- a/spec/unit/parser/functions/fqdn_rand_spec.rb +++ b/spec/unit/parser/functions/fqdn_rand_spec.rb @@ -1,8 +1,11 @@ #! /usr/bin/env ruby -require File.dirname(__FILE__) + '/../../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') describe "the fqdn_rand function" do + before :all do + Puppet::Parser::Functions.autoloader.loadall + end before :each do @scope = Puppet::Parser::Scope.new diff --git a/spec/unit/parser/functions/generate_spec.rb b/spec/unit/parser/functions/generate_spec.rb index 27aabe261..d25015b56 100755 --- a/spec/unit/parser/functions/generate_spec.rb +++ b/spec/unit/parser/functions/generate_spec.rb @@ -1,8 +1,11 @@ #! /usr/bin/env ruby -require File.dirname(__FILE__) + '/../../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') describe "the generate function" do + before :all do + Puppet::Parser::Functions.autoloader.loadall + end before :each do @scope = Puppet::Parser::Scope.new diff --git a/spec/unit/parser/functions/include_spec.rb b/spec/unit/parser/functions/include_spec.rb index 4f609b055..cfaadfbb6 100644..100755 --- a/spec/unit/parser/functions/include_spec.rb +++ b/spec/unit/parser/functions/include_spec.rb @@ -1,8 +1,11 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') describe "the 'include' function" do + before :all do + Puppet::Parser::Functions.autoloader.loadall + end before :each do Puppet::Node::Environment.stubs(:current).returns(nil) diff --git a/spec/unit/parser/functions/inline_template_spec.rb b/spec/unit/parser/functions/inline_template_spec.rb index 62f389e5d..712c68c69 100755 --- a/spec/unit/parser/functions/inline_template_spec.rb +++ b/spec/unit/parser/functions/inline_template_spec.rb @@ -1,8 +1,11 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') describe "the inline_template function" do + before :all do + Puppet::Parser::Functions.autoloader.loadall + end before :each do @scope = Puppet::Parser::Scope.new @@ -56,4 +59,4 @@ describe "the inline_template function" do lambda { @scope.function_inline_template("1") }.should raise_error(Puppet::ParseError) end -end
\ No newline at end of file +end diff --git a/spec/unit/parser/functions/realize_spec.rb b/spec/unit/parser/functions/realize_spec.rb index 82f4fa251..3106c42b6 100755 --- a/spec/unit/parser/functions/realize_spec.rb +++ b/spec/unit/parser/functions/realize_spec.rb @@ -1,8 +1,11 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') describe "the realize function" do + before :all do + Puppet::Parser::Functions.autoloader.loadall + end before :each do @collector = stub_everything 'collector' diff --git a/spec/unit/parser/functions/regsubst_spec.rb b/spec/unit/parser/functions/regsubst_spec.rb index 47126dd7a..1fb8e410c 100755 --- a/spec/unit/parser/functions/regsubst_spec.rb +++ b/spec/unit/parser/functions/regsubst_spec.rb @@ -1,8 +1,11 @@ #! /usr/bin/env ruby -require File.dirname(__FILE__) + '/../../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') describe "the regsubst function" do + before :all do + Puppet::Parser::Functions.autoloader.loadall + end before :each do @scope = Puppet::Parser::Scope.new diff --git a/spec/unit/parser/functions/require_spec.rb b/spec/unit/parser/functions/require_spec.rb index 49c4bbf74..edcbc4ae6 100755 --- a/spec/unit/parser/functions/require_spec.rb +++ b/spec/unit/parser/functions/require_spec.rb @@ -1,8 +1,11 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') describe "the require function" do + before :all do + Puppet::Parser::Functions.autoloader.loadall + end before :each do @catalog = stub 'catalog' diff --git a/spec/unit/parser/functions/shellquote_spec.rb b/spec/unit/parser/functions/shellquote_spec.rb index 46b9f8d10..55302b97b 100755 --- a/spec/unit/parser/functions/shellquote_spec.rb +++ b/spec/unit/parser/functions/shellquote_spec.rb @@ -1,8 +1,11 @@ #! /usr/bin/env ruby -require File.dirname(__FILE__) + '/../../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') describe "the shellquote function" do + before :all do + Puppet::Parser::Functions.autoloader.loadall + end before :each do @scope = Puppet::Parser::Scope.new diff --git a/spec/unit/parser/functions/split_spec.rb b/spec/unit/parser/functions/split_spec.rb index a1c83bb0f..b892a5c2a 100755 --- a/spec/unit/parser/functions/split_spec.rb +++ b/spec/unit/parser/functions/split_spec.rb @@ -1,8 +1,11 @@ #! /usr/bin/env ruby -require File.dirname(__FILE__) + '/../../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') describe "the split function" do + before :all do + Puppet::Parser::Functions.autoloader.loadall + end before :each do @scope = Puppet::Parser::Scope.new diff --git a/spec/unit/parser/functions/sprintf_spec.rb b/spec/unit/parser/functions/sprintf_spec.rb index 01545a879..69fbb5e97 100755 --- a/spec/unit/parser/functions/sprintf_spec.rb +++ b/spec/unit/parser/functions/sprintf_spec.rb @@ -1,8 +1,11 @@ #! /usr/bin/env ruby -require File.dirname(__FILE__) + '/../../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') describe "the sprintf function" do + before :all do + Puppet::Parser::Functions.autoloader.loadall + end before :each do @scope = Puppet::Parser::Scope.new diff --git a/spec/unit/parser/functions/tag_spec.rb b/spec/unit/parser/functions/tag_spec.rb index dac134134..b6bb45252 100755 --- a/spec/unit/parser/functions/tag_spec.rb +++ b/spec/unit/parser/functions/tag_spec.rb @@ -1,8 +1,11 @@ #! /usr/bin/env ruby -require File.dirname(__FILE__) + '/../../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') describe "the 'tag' function" do + before :all do + Puppet::Parser::Functions.autoloader.loadall + end before :each do @scope = Puppet::Parser::Scope.new diff --git a/spec/unit/parser/functions/template_spec.rb b/spec/unit/parser/functions/template_spec.rb index 096b0598e..7eaf3554d 100755 --- a/spec/unit/parser/functions/template_spec.rb +++ b/spec/unit/parser/functions/template_spec.rb @@ -1,8 +1,11 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') describe "the template function" do + before :all do + Puppet::Parser::Functions.autoloader.loadall + end before :each do @scope = Puppet::Parser::Scope.new @@ -59,4 +62,4 @@ describe "the template function" do lambda { @scope.function_template("1") }.should raise_error(Puppet::ParseError) end -end
\ No newline at end of file +end diff --git a/spec/unit/parser/functions/versioncmp_spec.rb b/spec/unit/parser/functions/versioncmp_spec.rb index 380c6307a..ddc79cd85 100755 --- a/spec/unit/parser/functions/versioncmp_spec.rb +++ b/spec/unit/parser/functions/versioncmp_spec.rb @@ -1,8 +1,11 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') describe "the versioncmp function" do + before :all do + Puppet::Parser::Functions.autoloader.loadall + end before :each do @scope = Puppet::Parser::Scope.new diff --git a/spec/unit/parser/functions_spec.rb b/spec/unit/parser/functions_spec.rb index 18aee4b65..51e52faee 100644 --- a/spec/unit/parser/functions_spec.rb +++ b/spec/unit/parser/functions_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') describe Puppet::Parser::Functions do diff --git a/spec/unit/parser/lexer_spec.rb b/spec/unit/parser/lexer_spec.rb index d144504c5..bc9e22e48 100755 --- a/spec/unit/parser/lexer_spec.rb +++ b/spec/unit/parser/lexer_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') require 'puppet/parser/lexer' @@ -667,11 +667,8 @@ describe "Puppet::Parser::Lexer in the old tests" do end end -require File.dirname(__FILE__) + '/../../../test/lib/puppettest' -require File.dirname(__FILE__) + '/../../../test/lib/puppettest/support/utils' describe "Puppet::Parser::Lexer in the old tests when lexing example files" do - extend PuppetTest::Support::Utils - textfiles do |file| + my_fixtures('*.pp') do |file| it "should correctly lex #{file}" do lexer = Puppet::Parser::Lexer.new lexer.file = file diff --git a/spec/unit/parser/parser_spec.rb b/spec/unit/parser/parser_spec.rb index 2ed279fd9..01cdcb976 100755 --- a/spec/unit/parser/parser_spec.rb +++ b/spec/unit/parser/parser_spec.rb @@ -1,10 +1,10 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') describe Puppet::Parser do - ast = Puppet::Parser::AST + Puppet::Parser::AST before :each do @known_resource_types = Puppet::Resource::TypeCollection.new("development") @@ -64,14 +64,16 @@ describe Puppet::Parser do lambda { @parser.parse("$var += ") }.should raise_error end - it "should call ast::VarDef with append=true" do - ast::VarDef.expects(:new).with { |h| h[:append] == true } - @parser.parse("$var += 2") + it "should create ast::VarDef with append=true" do + vardef = @parser.parse("$var += 2").code[0] + vardef.should be_a(Puppet::Parser::AST::VarDef) + vardef.append.should == true end it "should work with arrays too" do - ast::VarDef.expects(:new).with { |h| h[:append] == true } - @parser.parse("$var += ['test']") + vardef = @parser.parse("$var += ['test']").code[0] + vardef.should be_a(Puppet::Parser::AST::VarDef) + vardef.append.should == true end end @@ -84,21 +86,21 @@ describe Puppet::Parser do describe "when parsing 'if'" do it "not, it should create the correct ast objects" do - ast::Not.expects(:new).with { |h| h[:value].is_a?(ast::Boolean) } + Puppet::Parser::AST::Not.expects(:new).with { |h| h[:value].is_a?(Puppet::Parser::AST::Boolean) } @parser.parse("if ! true { $var = 1 }") end it "boolean operation, it should create the correct ast objects" do - ast::BooleanOperator.expects(:new).with { - |h| h[:rval].is_a?(ast::Boolean) and h[:lval].is_a?(ast::Boolean) and h[:operator]=="or" + Puppet::Parser::AST::BooleanOperator.expects(:new).with { + |h| h[:rval].is_a?(Puppet::Parser::AST::Boolean) and h[:lval].is_a?(Puppet::Parser::AST::Boolean) and h[:operator]=="or" } @parser.parse("if true or true { $var = 1 }") end it "comparison operation, it should create the correct ast objects" do - ast::ComparisonOperator.expects(:new).with { - |h| h[:lval].is_a?(ast::Name) and h[:rval].is_a?(ast::Name) and h[:operator]=="<" + Puppet::Parser::AST::ComparisonOperator.expects(:new).with { + |h| h[:lval].is_a?(Puppet::Parser::AST::Name) and h[:rval].is_a?(Puppet::Parser::AST::Name) and h[:operator]=="<" } @parser.parse("if 1 < 2 { $var = 1 }") @@ -109,13 +111,13 @@ describe Puppet::Parser do describe "when parsing if complex expressions" do it "should create a correct ast tree" do aststub = stub_everything 'ast' - ast::ComparisonOperator.expects(:new).with { - |h| h[:rval].is_a?(ast::Name) and h[:lval].is_a?(ast::Name) and h[:operator]==">" + Puppet::Parser::AST::ComparisonOperator.expects(:new).with { + |h| h[:rval].is_a?(Puppet::Parser::AST::Name) and h[:lval].is_a?(Puppet::Parser::AST::Name) and h[:operator]==">" }.returns(aststub) - ast::ComparisonOperator.expects(:new).with { - |h| h[:rval].is_a?(ast::Name) and h[:lval].is_a?(ast::Name) and h[:operator]=="==" + Puppet::Parser::AST::ComparisonOperator.expects(:new).with { + |h| h[:rval].is_a?(Puppet::Parser::AST::Name) and h[:lval].is_a?(Puppet::Parser::AST::Name) and h[:operator]=="==" }.returns(aststub) - ast::BooleanOperator.expects(:new).with { + Puppet::Parser::AST::BooleanOperator.expects(:new).with { |h| h[:rval]==aststub and h[:lval]==aststub and h[:operator]=="and" } @parser.parse("if (1 > 2) and (1 == 2) { $var = 1 }") @@ -138,9 +140,8 @@ describe Puppet::Parser do end it "should create an ast::ResourceReference" do - ast::Resource.stubs(:new) - ast::ResourceReference.expects(:new).with { |arg| - arg[:line]==1 and arg[:type]=="File" and arg[:title].is_a?(ast::ASTArray) + Puppet::Parser::AST::ResourceReference.expects(:new).with { |arg| + arg[:line]==1 and arg[:type]=="File" and arg[:title].is_a?(Puppet::Parser::AST::ASTArray) } @parser.parse('exec { test: command => File["a","b"] }') end @@ -157,10 +158,14 @@ describe Puppet::Parser do end it "should create an ast::ResourceOverride" do - ast::ResourceOverride.expects(:new).with { |arg| - arg[:line]==1 and arg[:object].is_a?(ast::ResourceReference) and arg[:parameters].is_a?(ast::ResourceParam) - } - @parser.parse('Resource["title1","title2"] { param => value }') + #Puppet::Parser::AST::ResourceOverride.expects(:new).with { |arg| + # arg[:line]==1 and arg[:object].is_a?(Puppet::Parser::AST::ResourceReference) and arg[:parameters].is_a?(Puppet::Parser::AST::ResourceParam) + #} + ro = @parser.parse('Resource["title1","title2"] { param => value }').code[0] + ro.should be_a(Puppet::Parser::AST::ResourceOverride) + ro.line.should == 1 + ro.object.should be_a(Puppet::Parser::AST::ResourceReference) + ro.parameters[0].should be_a(Puppet::Parser::AST::ResourceParam) end end @@ -180,17 +185,17 @@ describe Puppet::Parser do end it "should create a nop node for empty branch" do - ast::Nop.expects(:new) + Puppet::Parser::AST::Nop.expects(:new) @parser.parse("if true { }") end it "should create a nop node for empty else branch" do - ast::Nop.expects(:new) + Puppet::Parser::AST::Nop.expects(:new) @parser.parse("if true { notice('test') } else { }") end it "should build a chain of 'ifs' if there's an 'elsif'" do - ast = @parser.parse(<<-PP) + lambda { @parser.parse(<<-PP) }.should_not raise_error if true { notice('test') } elsif true {} else { } PP end @@ -294,51 +299,6 @@ describe Puppet::Parser do end end - describe "when creating a node" do - before :each do - @lexer = stub 'lexer' - @lexer.stubs(:getcomment) - @parser.stubs(:lexer).returns(@lexer) - @node = stub_everything 'node' - @parser.stubs(:ast_context).returns({}) - @parser.stubs(:node).returns(nil) - - @nodename = stub 'nodename', :is_a? => false, :value => "foo" - @nodename.stubs(:is_a?).with(Puppet::Parser::AST::HostName).returns(true) - end - - it "should return an array of nodes" do - @parser.newnode(@nodename).should be_instance_of(Array) - end - - it "should initialize the ast context with the correct line number" do - @parser.expects(:ast_context).with { |a,b| b == 123 }.returns({}) - @parser.newnode(@nodename, { :line => 123 }) - end - end - - %w{class define}.each do |entity| - describe "when creating a #{entity}" do - before :each do - @parser.stubs(:ast_context).returns({}) - - @name = stub "#{entity}name", :is_a? => false, :value => "foo" - end - - it "should create and add the correct resource type" do - instance = stub 'instance' - Puppet::Resource::Type.expects(:new).returns(instance) - @parser.known_resource_types.expects(:add).with(instance) - @parser.send("new#{entity}", @name) - end - - it "should initialize the ast context with the correct line number" do - @parser.expects(:ast_context).with { |a,b| b == 123 }.returns({}) - @parser.send("new#{entity}", @name, { :line => 123 }) - end - end - end - describe "when retrieving a specific node" do it "should delegate to the known_resource_types node" do @known_resource_types.expects(:node).with("node") @@ -391,30 +351,28 @@ describe Puppet::Parser do @parser.stubs(:known_resource_types).returns @krt end - it "should create new classes" do - @parser.parse("class foobar {}") - @krt.hostclass("foobar").should be_instance_of(Puppet::Resource::Type) + it "should not create new classes" do + @parser.parse("class foobar {}").code[0].should be_a(Puppet::Parser::AST::Hostclass) + @krt.hostclass("foobar").should be_nil end it "should correctly set the parent class when one is provided" do - @parser.parse("class foobar inherits yayness {}") - @krt.hostclass("foobar").parent.should == "yayness" + @parser.parse("class foobar inherits yayness {}").code[0].instantiate('')[0].parent.should == "yayness" end it "should correctly set the parent class for multiple classes at a time" do - @parser.parse("class foobar inherits yayness {}\nclass boo inherits bar {}") - @krt.hostclass("foobar").parent.should == "yayness" - @krt.hostclass("boo").parent.should == "bar" + statements = @parser.parse("class foobar inherits yayness {}\nclass boo inherits bar {}").code + statements[0].instantiate('')[0].parent.should == "yayness" + statements[1].instantiate('')[0].parent.should == "bar" end it "should define the code when some is provided" do - @parser.parse("class foobar { $var = val }") - @krt.hostclass("foobar").code.should_not be_nil + @parser.parse("class foobar { $var = val }").code[0].code.should_not be_nil end it "should define parameters when provided" do - @parser.parse("class foobar($biz,$baz) {}") - @krt.hostclass("foobar").arguments.should == {"biz" => nil, "baz" => nil} + foobar = @parser.parse("class foobar($biz,$baz) {}").code[0].instantiate('')[0] + foobar.arguments.should == {"biz" => nil, "baz" => nil} end end @@ -431,13 +389,37 @@ describe Puppet::Parser do end it "should correctly mark exported resources as exported" do - @parser.parse("@@file { '/file': }") - @krt.hostclass("").code[0].exported.should be_true + @parser.parse("@@file { '/file': }").code[0].exported.should be_true end it "should correctly mark virtual resources as virtual" do - @parser.parse("@file { '/file': }") - @krt.hostclass("").code[0].virtual.should be_true + @parser.parse("@file { '/file': }").code[0].virtual.should be_true + end + end + + describe "when parsing nodes" do + it "should be able to parse a node with a single name" do + node = @parser.parse("node foo { }").code[0] + node.should be_a Puppet::Parser::AST::Node + node.names.length.should == 1 + node.names[0].value.should == "foo" + end + + it "should be able to parse a node with two names" do + node = @parser.parse("node foo, bar { }").code[0] + node.should be_a Puppet::Parser::AST::Node + node.names.length.should == 2 + node.names[0].value.should == "foo" + node.names[1].value.should == "bar" + end + + it "should be able to parse a node with three names" do + node = @parser.parse("node foo, bar, baz { }").code[0] + node.should be_a Puppet::Parser::AST::Node + node.names.length.should == 3 + node.names[0].value.should == "foo" + node.names[1].value.should == "bar" + node.names[2].value.should == "baz" end end end diff --git a/spec/unit/parser/relationship_spec.rb b/spec/unit/parser/relationship_spec.rb index 57f1a772b..883a38d11 100644 --- a/spec/unit/parser/relationship_spec.rb +++ b/spec/unit/parser/relationship_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') require 'puppet/parser/relationship' diff --git a/spec/unit/parser/resource_spec.rb b/spec/unit/parser/resource_spec.rb index dae22fcaa..73c4412dd 100755 --- a/spec/unit/parser/resource_spec.rb +++ b/spec/unit/parser/resource_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') # LAK: FIXME This is just new tests for resources; I have # not moved all tests over yet. diff --git a/spec/unit/parser/scope_spec.rb b/spec/unit/parser/scope_spec.rb index 9895f446b..32a87f1f4 100755 --- a/spec/unit/parser/scope_spec.rb +++ b/spec/unit/parser/scope_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') describe Puppet::Parser::Scope do before :each do @@ -29,8 +29,7 @@ describe Puppet::Parser::Scope do end it "should be able to retrieve its parent module name from the source of its parent type" do - @topscope.source = Puppet::Resource::Type.new(:hostclass, :foo) - @topscope.source.module_name = "foo" + @topscope.source = Puppet::Resource::Type.new(:hostclass, :foo, :module_name => "foo") @scope.parent_module_name.should == "foo" end diff --git a/spec/unit/parser/templatewrapper_spec.rb b/spec/unit/parser/templatewrapper_spec.rb index 68d90a1cc..aab169348 100755 --- a/spec/unit/parser/templatewrapper_spec.rb +++ b/spec/unit/parser/templatewrapper_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') require 'puppet/parser/templatewrapper' describe Puppet::Parser::TemplateWrapper do diff --git a/spec/unit/parser/type_loader_spec.rb b/spec/unit/parser/type_loader_spec.rb index 02d543b02..12bc1ccd6 100644 --- a/spec/unit/parser/type_loader_spec.rb +++ b/spec/unit/parser/type_loader_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') require 'puppet/parser/type_loader' require 'puppet_spec/files' @@ -28,85 +28,20 @@ describe Puppet::Parser::TypeLoader do describe "when loading names from namespaces" do it "should do nothing if the name to import is an empty string" do @loader.expects(:name2files).never - @loader.load_until(["foo"], "") { |f| false }.should be_nil - end - - it "should turn the provided namespaces and name into a list of files" do - @loader.expects(:name2files).with(["foo"], "bar").returns [] - @loader.load_until(["foo"], "bar") { |f| false } + @loader.try_load_fqname(:hostclass, "") { |filename, modname| raise :should_not_occur }.should be_nil end it "should attempt to import each generated name" do - @loader.expects(:name2files).returns %w{foo bar} - @loader.expects(:import).with("foo",nil) - @loader.expects(:import).with("bar",nil) - @loader.load_until(["foo"], "bar") { |f| false } - end - - it "should yield after each import" do - yielded = [] - @loader.expects(:name2files).returns %w{foo bar} - @loader.expects(:import).with("foo",nil) - @loader.expects(:import).with("bar",nil) - @loader.load_until(["foo"], "bar") { |f| yielded << f; false } - yielded.should == %w{foo bar} - end - - it "should stop importing when the yielded block returns true" do - yielded = [] - @loader.expects(:name2files).returns %w{foo bar baz} - @loader.expects(:import).with("foo",nil) - @loader.expects(:import).with("bar",nil) - @loader.expects(:import).with("baz",nil).never - @loader.load_until(["foo"], "bar") { |f| true if f == "bar" } - end - - it "should return the result of the block" do - yielded = [] - @loader.expects(:name2files).returns %w{foo bar baz} - @loader.expects(:import).with("foo",nil) - @loader.expects(:import).with("bar",nil) - @loader.expects(:import).with("baz",nil).never - @loader.load_until(["foo"], "bar") { |f| 10 if f == "bar" }.should == 10 - end - - it "should return nil if the block never returns true" do - @loader.expects(:name2files).returns %w{foo bar} - @loader.expects(:import).with("foo",nil) - @loader.expects(:import).with("bar",nil) - @loader.load_until(["foo"], "bar") { |f| false }.should be_nil - end - - it "should set the module name on any created resource types" do - type = Puppet::Resource::Type.new(:hostclass, "mytype") - - Puppet::Parser::Files.expects(:find_manifests).returns ["modname", %w{one}] - @loader.stubs(:parse_file) - @loader.load_until(["foo"], "one") { |f| type } - - type.module_name.should == "modname" - end - end - - describe "when mapping names to files" do - { - [["foo"], "::bar::baz"] => %w{bar/baz}, - [[""], "foo::bar"] => %w{foo foo/bar}, - [%w{foo}, "bar"] => %w{foo foo/bar bar}, - [%w{a b}, "bar"] => %w{a a/bar b b/bar bar}, - [%w{a::b::c}, "bar"] => %w{a a/b/c/bar bar}, - [%w{a::b}, "foo::bar"] => %w{a a/b/foo/bar foo/bar} - }.each do |inputs, outputs| - it "should produce #{outputs.inspect} from the #{inputs[0].inspect} namespace and #{inputs[1]} name" do - @loader.name2files(*inputs).should == outputs - end + @loader.expects(:import).with("foo/bar",nil).returns([]) + @loader.expects(:import).with("foo",nil).returns([]) + @loader.try_load_fqname(:hostclass, "foo::bar") { |f| false } end end describe "when importing" do before do Puppet::Parser::Files.stubs(:find_manifests).returns ["modname", %w{file}] - Puppet::Parser::Parser.any_instance.stubs(:parse) + Puppet::Parser::Parser.any_instance.stubs(:parse).returns(Puppet::Parser::AST::Hostclass.new('')) Puppet::Parser::Parser.any_instance.stubs(:file=) end @@ -138,19 +73,19 @@ describe Puppet::Parser::TypeLoader do it "should parse each found file" do Puppet::Parser::Files.expects(:find_manifests).returns ["modname", %w{/one}] - @loader.expects(:parse_file).with("/one") + @loader.expects(:parse_file).with("/one").returns(Puppet::Parser::AST::Hostclass.new('')) @loader.import("myfile") end it "should make each file qualified before attempting to parse it" do Puppet::Parser::Files.expects(:find_manifests).returns ["modname", %w{one}] - @loader.expects(:parse_file).with("/current/one") + @loader.expects(:parse_file).with("/current/one").returns(Puppet::Parser::AST::Hostclass.new('')) @loader.import("myfile", "/current/file") end it "should not attempt to import files that have already been imported" do Puppet::Parser::Files.expects(:find_manifests).returns ["modname", %w{/one}] - Puppet::Parser::Parser.any_instance.expects(:parse).once + Puppet::Parser::Parser.any_instance.expects(:parse).once.returns(Puppet::Parser::AST::Hostclass.new('')) @loader.import("myfile") # This will fail if it tries to reimport the file. @@ -158,10 +93,107 @@ describe Puppet::Parser::TypeLoader do end end + describe "when importing all" do + before do + @base = tmpdir("base") + + # Create two module path directories + @modulebase1 = File.join(@base, "first") + FileUtils.mkdir_p(@modulebase1) + @modulebase2 = File.join(@base, "second") + FileUtils.mkdir_p(@modulebase2) + + Puppet[:modulepath] = "#{@modulebase1}:#{@modulebase2}" + end + + def mk_module(basedir, name) + module_dir = File.join(basedir, name) + + # Go ahead and make our manifest directory + FileUtils.mkdir_p(File.join(module_dir, "manifests")) + + return Puppet::Module.new(name) + end + + # We have to pass the base path so that we can + # write to modules that are in the second search path + def mk_manifests(base, mod, type, files) + exts = {"ruby" => ".rb", "puppet" => ".pp"} + files.collect do |file| + name = mod.name + "::" + file.gsub("/", "::") + path = File.join(base, mod.name, "manifests", file + exts[type]) + FileUtils.mkdir_p(File.split(path)[0]) + + # write out the class + if type == "ruby" + File.open(path, "w") { |f| f.print "hostclass '#{name}' do\nend" } + else + File.open(path, "w") { |f| f.print "class #{name} {}" } + end + name + end + end + + it "should load all puppet manifests from all modules in the specified environment" do + @module1 = mk_module(@modulebase1, "one") + @module2 = mk_module(@modulebase2, "two") + + mk_manifests(@modulebase1, @module1, "puppet", %w{a b}) + mk_manifests(@modulebase2, @module2, "puppet", %w{c d}) + + @loader.import_all + + @loader.environment.known_resource_types.hostclass("one::a").should be_instance_of(Puppet::Resource::Type) + @loader.environment.known_resource_types.hostclass("one::b").should be_instance_of(Puppet::Resource::Type) + @loader.environment.known_resource_types.hostclass("two::c").should be_instance_of(Puppet::Resource::Type) + @loader.environment.known_resource_types.hostclass("two::d").should be_instance_of(Puppet::Resource::Type) + end + + it "should load all ruby manifests from all modules in the specified environment" do + @module1 = mk_module(@modulebase1, "one") + @module2 = mk_module(@modulebase2, "two") + + mk_manifests(@modulebase1, @module1, "ruby", %w{a b}) + mk_manifests(@modulebase2, @module2, "ruby", %w{c d}) + + @loader.import_all + + @loader.environment.known_resource_types.hostclass("one::a").should be_instance_of(Puppet::Resource::Type) + @loader.environment.known_resource_types.hostclass("one::b").should be_instance_of(Puppet::Resource::Type) + @loader.environment.known_resource_types.hostclass("two::c").should be_instance_of(Puppet::Resource::Type) + @loader.environment.known_resource_types.hostclass("two::d").should be_instance_of(Puppet::Resource::Type) + end + + it "should not load manifests from duplicate modules later in the module path" do + @module1 = mk_module(@modulebase1, "one") + + # duplicate + @module2 = mk_module(@modulebase2, "one") + + mk_manifests(@modulebase1, @module1, "puppet", %w{a}) + mk_manifests(@modulebase2, @module2, "puppet", %w{c}) + + @loader.import_all + + @loader.environment.known_resource_types.hostclass("one::c").should be_nil + end + + it "should load manifests from subdirectories" do + @module1 = mk_module(@modulebase1, "one") + + mk_manifests(@modulebase1, @module1, "puppet", %w{a a/b a/b/c}) + + @loader.import_all + + @loader.environment.known_resource_types.hostclass("one::a::b").should be_instance_of(Puppet::Resource::Type) + @loader.environment.known_resource_types.hostclass("one::a::b::c").should be_instance_of(Puppet::Resource::Type) + end + end + describe "when parsing a file" do before do @parser = Puppet::Parser::Parser.new(@loader.environment) - @parser.stubs(:parse) + @parser.stubs(:parse).returns(Puppet::Parser::AST::Hostclass.new('')) @parser.stubs(:file=) Puppet::Parser::Parser.stubs(:new).with(@loader.environment).returns @parser end @@ -173,7 +205,7 @@ describe Puppet::Parser::TypeLoader do it "should assign the parser its file and parse" do @parser.expects(:file=).with("/my/file") - @parser.expects(:parse) + @parser.expects(:parse).returns(Puppet::Parser::AST::Hostclass.new('')) @loader.parse_file("/my/file") end end @@ -185,4 +217,15 @@ describe Puppet::Parser::TypeLoader do @loader.known_resource_types.hostclass("foo").should be_instance_of(Puppet::Resource::Type) end + + describe "when deciding where to look for files" do + { 'foo' => ['foo'], + 'foo::bar' => ['foo/bar', 'foo'], + 'foo::bar::baz' => ['foo/bar/baz', 'foo/bar', 'foo'] + }.each do |fqname, expected_paths| + it "should look for #{fqname.inspect} in #{expected_paths.inspect}" do + @loader.instance_eval { name2files(fqname) }.should == expected_paths + end + end + end end diff --git a/spec/unit/property/ensure_spec.rb b/spec/unit/property/ensure_spec.rb index f2722de89..d3029c658 100644 --- a/spec/unit/property/ensure_spec.rb +++ b/spec/unit/property/ensure_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -Dir.chdir(File.dirname(__FILE__)) { (s = lambda { |f| File.exist?(f) ? require(f) : Dir.chdir("..") { s.call(f) } }).call("spec/spec_helper.rb") } +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') require 'puppet/property/ensure' diff --git a/spec/unit/property/keyvalue_spec.rb b/spec/unit/property/keyvalue_spec.rb index a44d891d7..a0175cfa3 100644 --- a/spec/unit/property/keyvalue_spec.rb +++ b/spec/unit/property/keyvalue_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -Dir.chdir(File.dirname(__FILE__)) { (s = lambda { |f| File.exist?(f) ? require(f) : Dir.chdir("..") { s.call(f) } }).call("spec/spec_helper.rb") } +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') require 'puppet/property/keyvalue' diff --git a/spec/unit/property/list_spec.rb b/spec/unit/property/list_spec.rb index c6c5db10e..704fbe3d9 100644 --- a/spec/unit/property/list_spec.rb +++ b/spec/unit/property/list_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -Dir.chdir(File.dirname(__FILE__)) { (s = lambda { |f| File.exist?(f) ? require(f) : Dir.chdir("..") { s.call(f) } }).call("spec/spec_helper.rb") } +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') require 'puppet/property/list' diff --git a/spec/unit/property/ordered_list_spec.rb b/spec/unit/property/ordered_list_spec.rb index 7c8eceb0d..460bec79d 100644 --- a/spec/unit/property/ordered_list_spec.rb +++ b/spec/unit/property/ordered_list_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -Dir.chdir(File.dirname(__FILE__)) { (s = lambda { |f| File.exist?(f) ? require(f) : Dir.chdir("..") { s.call(f) } }).call("spec/spec_helper.rb") } +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') require 'puppet/property/ordered_list' diff --git a/spec/unit/property_spec.rb b/spec/unit/property_spec.rb index 56e643b1a..602d3c66b 100755 --- a/spec/unit/property_spec.rb +++ b/spec/unit/property_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../spec_helper') require 'puppet/property' describe Puppet::Property do diff --git a/spec/unit/provider/augeas/augeas_spec.rb b/spec/unit/provider/augeas/augeas_spec.rb index 07b632083..c65f39097 100644 --- a/spec/unit/provider/augeas/augeas_spec.rb +++ b/spec/unit/provider/augeas/augeas_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') provider_class = Puppet::Type.type(:augeas).provider(:augeas) @@ -316,6 +316,30 @@ describe provider_class do provider.stubs(:get_augeas_version).returns("0.3.5") provider.need_to_run?.should == false end + + #Ticket 5211 testing + it "should return true when a size != the provided value" do + resource = stub("resource") + resource.stubs(:[]).returns(false).then.returns("match path size != 17").then.returns("") + provider = provider_class.new(resource) + augeas_stub = stub("augeas", :match => ["set", "of", "values"]) + augeas_stub.stubs("close") + provider.aug= augeas_stub + provider.stubs(:get_augeas_version).returns("0.3.5") + provider.need_to_run?.should == true + end + + #Ticket 5211 testing + it "should return false when a size doeas equal the provided value" do + resource = stub("resource") + resource.stubs(:[]).returns(false).then.returns("match path size != 3").then.returns("") + provider = provider_class.new(resource) + augeas_stub = stub("augeas", :match => ["set", "of", "values"]) + augeas_stub.stubs("close") + provider.aug= augeas_stub + provider.stubs(:get_augeas_version).returns("0.3.5") + provider.need_to_run?.should == false + end end describe "augeas execution integration" do @@ -409,5 +433,59 @@ describe provider_class do @augeas.expects(:close) @provider.execute_changes.should == :executed end + + it "should handle defvar commands" do + command = "defvar myjar Jar/Jar" + context = "/foo/" + @resource.expects(:[]).times(2).returns(command).then.returns(context) + @augeas.expects(:defvar).with("myjar", "/foo/Jar/Jar").returns(true) + @augeas.expects(:save).returns(true) + @augeas.expects(:close) + @provider.execute_changes.should == :executed + end + + it "should pass through augeas variables without context" do + command = ["defvar myjar Jar/Jar","set $myjar/Binks 1"] + context = "/foo/" + @resource.expects(:[]).times(2).returns(command).then.returns(context) + @augeas.expects(:defvar).with("myjar", "/foo/Jar/Jar").returns(true) + # this is the important bit, shouldn't be /foo/$myjar/Binks + @augeas.expects(:set).with("$myjar/Binks", "1").returns(true) + @augeas.expects(:save).returns(true) + @augeas.expects(:close) + @provider.execute_changes.should == :executed + end + + it "should handle defnode commands" do + command = "defnode newjar Jar/Jar[last()+1] Binks" + context = "/foo/" + @resource.expects(:[]).times(2).returns(command).then.returns(context) + @augeas.expects(:defnode).with("newjar", "/foo/Jar/Jar[last()+1]", "Binks").returns(true) + @augeas.expects(:save).returns(true) + @augeas.expects(:close) + @provider.execute_changes.should == :executed + end + + it "should handle mv commands" do + command = "mv Jar/Jar Binks" + context = "/foo/" + @resource.expects(:[]).times(2).returns(command).then.returns(context) + @augeas.expects(:mv).with("/foo/Jar/Jar", "/foo/Binks").returns(true) + @augeas.expects(:save).returns(true) + @augeas.expects(:close) + @provider.execute_changes.should == :executed + end + + it "should handle setm commands" do + command = ["set test[1]/Jar/Jar Foo","set test[2]/Jar/Jar Bar","setm test Jar/Jar Binks"] + context = "/foo/" + @resource.expects(:[]).times(2).returns(command).then.returns(context) + @augeas.expects(:set).with("/foo/test[1]/Jar/Jar", "Foo").returns(true) + @augeas.expects(:set).with("/foo/test[2]/Jar/Jar", "Bar").returns(true) + @augeas.expects(:setm).with("/foo/test", "Jar/Jar", "Binks").returns(true) + @augeas.expects(:save).returns(true) + @augeas.expects(:close) + @provider.execute_changes.should == :executed + end end end diff --git a/spec/unit/provider/confine/exists_spec.rb b/spec/unit/provider/confine/exists_spec.rb index f039208b8..1dabafb19 100755 --- a/spec/unit/provider/confine/exists_spec.rb +++ b/spec/unit/provider/confine/exists_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') require 'puppet/provider/confine/exists' diff --git a/spec/unit/provider/confine/false_spec.rb b/spec/unit/provider/confine/false_spec.rb index 999fc4714..8ea4bf740 100755 --- a/spec/unit/provider/confine/false_spec.rb +++ b/spec/unit/provider/confine/false_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') require 'puppet/provider/confine/false' diff --git a/spec/unit/provider/confine/feature_spec.rb b/spec/unit/provider/confine/feature_spec.rb index e8368efac..534c8c14a 100755 --- a/spec/unit/provider/confine/feature_spec.rb +++ b/spec/unit/provider/confine/feature_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') require 'puppet/provider/confine/feature' diff --git a/spec/unit/provider/confine/true_spec.rb b/spec/unit/provider/confine/true_spec.rb index 23041e6d5..b23373b87 100755 --- a/spec/unit/provider/confine/true_spec.rb +++ b/spec/unit/provider/confine/true_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') require 'puppet/provider/confine/true' diff --git a/spec/unit/provider/confine/variable_spec.rb b/spec/unit/provider/confine/variable_spec.rb index eda2dd4c5..083573c3a 100755 --- a/spec/unit/provider/confine/variable_spec.rb +++ b/spec/unit/provider/confine/variable_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') require 'puppet/provider/confine/variable' diff --git a/spec/unit/provider/confine_collection_spec.rb b/spec/unit/provider/confine_collection_spec.rb index e5f7f0300..fc68ef7f6 100755 --- a/spec/unit/provider/confine_collection_spec.rb +++ b/spec/unit/provider/confine_collection_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') require 'puppet/provider/confine_collection' diff --git a/spec/unit/provider/confine_spec.rb b/spec/unit/provider/confine_spec.rb index 1fa7f3d11..ce969eded 100755 --- a/spec/unit/provider/confine_spec.rb +++ b/spec/unit/provider/confine_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') require 'puppet/provider/confine' diff --git a/spec/unit/provider/confiner_spec.rb b/spec/unit/provider/confiner_spec.rb index d513c7232..15e2e6129 100755 --- a/spec/unit/provider/confiner_spec.rb +++ b/spec/unit/provider/confiner_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') require 'puppet/provider/confiner' diff --git a/spec/unit/provider/group/groupadd_spec.rb b/spec/unit/provider/group/groupadd_spec.rb index 33d9acd98..41431fb59 100755 --- a/spec/unit/provider/group/groupadd_spec.rb +++ b/spec/unit/provider/group/groupadd_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') provider_class = Puppet::Type.type(:group).provider(:groupadd) diff --git a/spec/unit/provider/group/ldap_spec.rb b/spec/unit/provider/group/ldap_spec.rb index b8c54be94..8454b9604 100755 --- a/spec/unit/provider/group/ldap_spec.rb +++ b/spec/unit/provider/group/ldap_spec.rb @@ -3,7 +3,7 @@ # Created by Luke Kanies on 2008-3-10. # Copyright (c) 2006. All rights reserved. -require File.dirname(__FILE__) + '/../../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') provider_class = Puppet::Type.type(:group).provider(:ldap) diff --git a/spec/unit/provider/host/parsed_spec.rb b/spec/unit/provider/host/parsed_spec.rb new file mode 100755 index 000000000..048d77ba2 --- /dev/null +++ b/spec/unit/provider/host/parsed_spec.rb @@ -0,0 +1,198 @@ +#!/usr/bin/env ruby + +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') +require 'shared_behaviours/all_parsedfile_providers' + +require 'puppet_spec/files' + +provider_class = Puppet::Type.type(:host).provider(:parsed) + +describe provider_class do + include PuppetSpec::Files + + before do + @host_class = Puppet::Type.type(:host) + @provider = @host_class.provider(:parsed) + @hostfile = tmpfile('hosts') + @provider.any_instance.stubs(:target).returns @hostfile + end + + after :each do + @provider.initvars + end + + def mkhost(args) + hostresource = Puppet::Type::Host.new(:name => args[:name]) + hostresource.stubs(:should).with(:target).returns @hostfile + + # Using setters of provider to build our testobject + # Note: We already proved, that in case of host_aliases + # the provider setter "host_aliases=(value)" will be + # called with the joined array, so we just simulate that + host = @provider.new(hostresource) + args.each do |property,value| + value = value.join(" ") if property == :host_aliases and value.is_a?(Array) + host.send("#{property}=", value) + end + host + end + + def genhost(host) + @provider.stubs(:filetype).returns(Puppet::Util::FileType::FileTypeRam) + File.stubs(:chown) + File.stubs(:chmod) + Puppet::Util::SUIDManager.stubs(:asuser).yields + host.flush + @provider.target_object(@hostfile).read + end + + describe "when parsing a line with ip and hostname" do + + it "should parse an ipv4 from the first field" do + @provider.parse_line("127.0.0.1 localhost")[:ip].should == "127.0.0.1" + end + + it "should parse an ipv6 from the first field" do + @provider.parse_line("::1 localhost")[:ip].should == "::1" + end + + it "should parse the name from the second field" do + @provider.parse_line("::1 localhost")[:name].should == "localhost" + end + + it "should set an empty comment" do + @provider.parse_line("::1 localhost")[:comment].should == "" + end + + it "should set host_aliases to :absent" do + @provider.parse_line("::1 localhost")[:host_aliases].should == :absent + end + + end + + describe "when parsing a line with ip, hostname and comment" do + before do + @testline = "127.0.0.1 localhost # A comment with a #-char" + end + + it "should parse the ip from the first field" do + @provider.parse_line(@testline)[:ip].should == "127.0.0.1" + end + + it "should parse the hostname from the second field" do + @provider.parse_line(@testline)[:name].should == "localhost" + end + + it "should parse the comment after the first '#' character" do + @provider.parse_line(@testline)[:comment].should == 'A comment with a #-char' + end + + end + + describe "when parsing a line with ip, hostname and aliases" do + + it "should parse alias from the third field" do + @provider.parse_line("127.0.0.1 localhost localhost.localdomain")[:host_aliases].should == "localhost.localdomain" + end + + it "should parse multiple aliases" do + @provider.parse_line("127.0.0.1 host alias1 alias2")[:host_aliases].should == 'alias1 alias2' + @provider.parse_line("127.0.0.1 host alias1\talias2")[:host_aliases].should == 'alias1 alias2' + @provider.parse_line("127.0.0.1 host alias1\talias2 alias3")[:host_aliases].should == 'alias1 alias2 alias3' + end + + end + + describe "when parsing a line with ip, hostname, aliases and comment" do + + before do + # Just playing with a few different delimiters + @testline = "127.0.0.1\t host alias1\talias2 alias3 # A comment with a #-char" + end + + it "should parse the ip from the first field" do + @provider.parse_line(@testline)[:ip].should == "127.0.0.1" + end + + it "should parse the hostname from the second field" do + @provider.parse_line(@testline)[:name].should == "host" + end + + it "should parse all host_aliases from the third field" do + @provider.parse_line(@testline)[:host_aliases].should == 'alias1 alias2 alias3' + end + + it "should parse the comment after the first '#' character" do + @provider.parse_line(@testline)[:comment].should == 'A comment with a #-char' + end + + end + + describe "when operating on /etc/hosts like files" do + it_should_behave_like "all parsedfile providers", + provider_class, my_fixtures('valid*') + + it "should be able to generate a simple hostfile entry" do + host = mkhost( + :name => 'localhost', + :ip => '127.0.0.1', + :ensure => :present + ) + genhost(host).should == "127.0.0.1\tlocalhost\n" + end + + it "should be able to generate an entry with one alias" do + host = mkhost( + :name => 'localhost.localdomain', + :ip => '127.0.0.1', + :host_aliases => 'localhost', + :ensure => :present + ) + genhost(host).should == "127.0.0.1\tlocalhost.localdomain\tlocalhost\n" + end + + it "should be able to generate an entry with more than one alias" do + host = mkhost( + :name => 'host', + :ip => '192.0.0.1', + :host_aliases => [ 'a1','a2','a3','a4' ], + :ensure => :present + ) + genhost(host).should == "192.0.0.1\thost\ta1 a2 a3 a4\n" + end + + it "should be able to generate a simple hostfile entry with comments" do + host = mkhost( + :name => 'localhost', + :ip => '127.0.0.1', + :comment => 'Bazinga!', + :ensure => :present + ) + genhost(host).should == "127.0.0.1\tlocalhost\t# Bazinga!\n" + end + + it "should be able to generate an entry with one alias and a comment" do + host = mkhost( + :name => 'localhost.localdomain', + :ip => '127.0.0.1', + :host_aliases => 'localhost', + :comment => 'Bazinga!', + :ensure => :present + ) + genhost(host).should == "127.0.0.1\tlocalhost.localdomain\tlocalhost\t# Bazinga!\n" + end + + it "should be able to generate an entry with more than one alias and a comment" do + host = mkhost( + :name => 'host', + :ip => '192.0.0.1', + :host_aliases => [ 'a1','a2','a3','a4' ], + :comment => 'Bazinga!', + :ensure => :present + ) + genhost(host).should == "192.0.0.1\thost\ta1 a2 a3 a4\t# Bazinga!\n" + end + + end + +end diff --git a/spec/unit/provider/ldap_spec.rb b/spec/unit/provider/ldap_spec.rb index 588cafc1f..7ed289c62 100755 --- a/spec/unit/provider/ldap_spec.rb +++ b/spec/unit/provider/ldap_spec.rb @@ -3,7 +3,7 @@ # Created by Luke Kanies on 2008-3-21. # Copyright (c) 2006. All rights reserved. -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') require 'puppet/provider/ldap' diff --git a/spec/unit/provider/macauthorization_spec.rb b/spec/unit/provider/macauthorization_spec.rb index d9e04e957..3c74334ba 100755 --- a/spec/unit/provider/macauthorization_spec.rb +++ b/spec/unit/provider/macauthorization_spec.rb @@ -3,7 +3,7 @@ # Unit testing for the macauthorization provider # -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') require 'puppet' require 'facter/util/plist' diff --git a/spec/unit/provider/mcx/mcxcontent_spec.rb b/spec/unit/provider/mcx/mcxcontent_spec.rb index d3fb043b6..82dbf9ac7 100755 --- a/spec/unit/provider/mcx/mcxcontent_spec.rb +++ b/spec/unit/provider/mcx/mcxcontent_spec.rb @@ -18,7 +18,7 @@ # Author: Jeff McCune <mccune.jeff@gmail.com> -require File.dirname(__FILE__) + '/../../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') provider_class = Puppet::Type.type(:mcx).provider(:mcxcontent) diff --git a/spec/unit/provider/mount/parsed_spec.rb b/spec/unit/provider/mount/parsed_spec.rb index cf29bd358..b63c0751f 100755 --- a/spec/unit/provider/mount/parsed_spec.rb +++ b/spec/unit/provider/mount/parsed_spec.rb @@ -3,48 +3,8 @@ # Created by Luke Kanies on 2007-9-12. # Copyright (c) 2006. All rights reserved. -require File.dirname(__FILE__) + '/../../../spec_helper' - -require 'puppet_spec/files' -require 'puppettest/support/utils' -require 'puppettest/fileparsing' - -module ParsedMountTesting - include PuppetTest::Support::Utils - include PuppetTest::FileParsing - include PuppetSpec::Files - - def fake_fstab - os = Facter.value(:operatingsystem) - if os == "Solaris" - name = "solaris.fstab" - elsif os == "FreeBSD" - name = "freebsd.fstab" - else - # Catchall for other fstabs - name = "linux.fstab" - end - fakefile(File::join("data/types/mount", name)) - end - - def fake_mountoutput - os = Facter.value(:operatingsystem) - if os == "Darwin" - name = "darwin.mount" - elsif os == "HP-UX" - name = "hpux.mount" - elsif os == "Solaris" - name = "solaris.mount" - elsif os == "AIX" - name = "aix.mount" - else - # Catchall for other fstabs - name = "linux.mount" - end - fakefile(File::join("data/providers/mount/parsed", name)) - end - -end +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') +require 'shared_behaviours/all_parsedfile_providers' provider_class = Puppet::Type.type(:mount).provider(:parsed) @@ -76,6 +36,8 @@ FSTAB lambda{ @provider.to_line(parse[0]) }.should_not raise_error end +# it_should_behave_like "all parsedfile providers", +# provider_class, my_fixtures('*.fstab') describe "on Solaris", :if => Facter.value(:operatingsystem) == 'Solaris' do @@ -148,11 +110,9 @@ FSTAB end describe "mountinstances" do - include ParsedMountTesting - it "should get name from mountoutput found on Solaris" do Facter.stubs(:value).with(:operatingsystem).returns 'Solaris' - @provider.stubs(:mountcmd).returns(File.read(fake_mountoutput)) + @provider.stubs(:mountcmd).returns(File.read(my_fixture('solaris.mount'))) mounts = @provider.mountinstances mounts.size.should == 6 mounts[0].should == { :name => '/', :mounted => :yes } @@ -165,7 +125,7 @@ FSTAB it "should get name from mountoutput found on HP-UX" do Facter.stubs(:value).with(:operatingsystem).returns 'HP-UX' - @provider.stubs(:mountcmd).returns(File.read(fake_mountoutput)) + @provider.stubs(:mountcmd).returns(File.read(my_fixture('hpux.mount'))) mounts = @provider.mountinstances mounts.size.should == 17 mounts[0].should == { :name => '/', :mounted => :yes } @@ -189,7 +149,7 @@ FSTAB it "should get name from mountoutput found on Darwin" do Facter.stubs(:value).with(:operatingsystem).returns 'Darwin' - @provider.stubs(:mountcmd).returns(File.read(fake_mountoutput)) + @provider.stubs(:mountcmd).returns(File.read(my_fixture('darwin.mount'))) mounts = @provider.mountinstances mounts.size.should == 6 mounts[0].should == { :name => '/', :mounted => :yes } @@ -202,7 +162,7 @@ FSTAB it "should get name from mountoutput found on Linux" do Facter.stubs(:value).with(:operatingsystem).returns 'Gentoo' - @provider.stubs(:mountcmd).returns(File.read(fake_mountoutput)) + @provider.stubs(:mountcmd).returns(File.read(my_fixture('linux.mount'))) mounts = @provider.mountinstances mounts[0].should == { :name => '/', :mounted => :yes } mounts[1].should == { :name => '/lib64/rc/init.d', :mounted => :yes } @@ -213,7 +173,7 @@ FSTAB it "should get name from mountoutput found on AIX" do Facter.stubs(:value).with(:operatingsystem).returns 'AIX' - @provider.stubs(:mountcmd).returns(File.read(fake_mountoutput)) + @provider.stubs(:mountcmd).returns(File.read(my_fixture('aix.mount'))) mounts = @provider.mountinstances mounts[0].should == { :name => '/', :mounted => :yes } mounts[1].should == { :name => '/tmp', :mounted => :yes } @@ -229,49 +189,64 @@ FSTAB end - describe "when prefetching" do - include ParsedMountTesting + it "should support AIX's paragraph based /etc/filesystems" - before :each do - # Note: we have to stub default_target before creating resources - # because it is used by Puppet::Type::Mount.new to populate the - # :target property. - @provider.stubs(:default_target).returns fake_fstab + my_fixtures('*.fstab').each do |fstab| + platform = File.basename(fstab, '.fstab') + describe "when prefetching on #{platform}" do + before :each do + if Facter[:operatingsystem] == "Solaris" then + platform == 'solaris' or + pending "We need to stub the operatingsystem fact at load time, but can't" + else + platform != 'solaris' or + pending "We need to stub the operatingsystem fact at load time, but can't" + end - @res_ghost = Puppet::Type::Mount.new(:name => '/ghost') # in no fake fstab - @res_mounted = Puppet::Type::Mount.new(:name => '/') # in every fake fstab - @res_unmounted = Puppet::Type::Mount.new(:name => '/boot') # in every fake fstab - @res_absent = Puppet::Type::Mount.new(:name => '/absent') # in no fake fstab + # Stub the mount output to our fixture. + begin + mount = my_fixture(platform + '.mount') + @provider.stubs(:mountcmd).returns File.read(mount) + rescue + pending "is #{platform}.mount missing at this point?" + end - # Simulate transaction.rb:prefetch - @resource_hash = {} - [@res_ghost, @res_mounted, @res_unmounted, @res_absent].each do |resource| - @resource_hash[resource.name] = resource - end + # Note: we have to stub default_target before creating resources + # because it is used by Puppet::Type::Mount.new to populate the + # :target property. + @provider.stubs(:default_target).returns fstab - @provider.stubs(:mountcmd).returns File.read(fake_mountoutput) - end + @res_ghost = Puppet::Type::Mount.new(:name => '/ghost') # in no fake fstab + @res_mounted = Puppet::Type::Mount.new(:name => '/') # in every fake fstab + @res_unmounted = Puppet::Type::Mount.new(:name => '/boot') # in every fake fstab + @res_absent = Puppet::Type::Mount.new(:name => '/absent') # in no fake fstab - it "should set :ensure to :unmounted if found in fstab but not mounted" do - @provider.prefetch(@resource_hash) - @res_unmounted.provider.get(:ensure).should == :unmounted - end + # Simulate transaction.rb:prefetch + @resource_hash = {} + [@res_ghost, @res_mounted, @res_unmounted, @res_absent].each do |resource| + @resource_hash[resource.name] = resource + end + end - it "should set :ensure to :mounted if found in fstab and mounted" do - @provider.prefetch(@resource_hash) - @res_ghost.provider.get(:ensure).should == :ghost - end + it "should set :ensure to :unmounted if found in fstab but not mounted" do + @provider.prefetch(@resource_hash) + @res_unmounted.provider.get(:ensure).should == :unmounted + end - it "should set :ensure to :ghost if not found in fstab but mounted" do - @provider.prefetch(@resource_hash) - @res_mounted.provider.get(:ensure).should == :mounted - end + it "should set :ensure to :ghost if not found in fstab but mounted" do + @provider.prefetch(@resource_hash) + @res_ghost.provider.get(:ensure).should == :ghost + end - it "should set :ensure to :absent if not found in fstab and not mounted" do - @provider.prefetch(@resource_hash) - @res_absent.provider.get(:ensure).should == :absent - end + it "should set :ensure to :mounted if found in fstab and mounted" do + @provider.prefetch(@resource_hash) + @res_mounted.provider.get(:ensure).should == :mounted + end + it "should set :ensure to :absent if not found in fstab and not mounted" do + @provider.prefetch(@resource_hash) + @res_absent.provider.get(:ensure).should == :absent + end + end end - end diff --git a/spec/unit/provider/mount_spec.rb b/spec/unit/provider/mount_spec.rb index 3fc8a8664..9cadfc403 100755 --- a/spec/unit/provider/mount_spec.rb +++ b/spec/unit/provider/mount_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') require 'puppet/provider/mount' diff --git a/spec/unit/provider/naginator_spec.rb b/spec/unit/provider/naginator_spec.rb index 72195756c..8ae1895cc 100755 --- a/spec/unit/provider/naginator_spec.rb +++ b/spec/unit/provider/naginator_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') require 'puppet/provider/naginator' diff --git a/spec/unit/provider/package/aix_spec.rb b/spec/unit/provider/package/aix_spec.rb index 26732a3f0..40e497c27 100755 --- a/spec/unit/provider/package/aix_spec.rb +++ b/spec/unit/provider/package/aix_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') provider_class = Puppet::Type.type(:package).provider(:aix) diff --git a/spec/unit/provider/package/apt_spec.rb b/spec/unit/provider/package/apt_spec.rb index 3c6bf62af..b0ce4f799 100755 --- a/spec/unit/provider/package/apt_spec.rb +++ b/spec/unit/provider/package/apt_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -Dir.chdir(File.dirname(__FILE__)) { (s = lambda { |f| File.exist?(f) ? require(f) : Dir.chdir("..") { s.call(f) } }).call("spec/spec_helper.rb") } +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') provider = Puppet::Type.type(:package).provider(:apt) diff --git a/spec/unit/provider/package/dpkg_spec.rb b/spec/unit/provider/package/dpkg_spec.rb index 47ac9766e..444fb31c1 100755 --- a/spec/unit/provider/package/dpkg_spec.rb +++ b/spec/unit/provider/package/dpkg_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -Dir.chdir(File.dirname(__FILE__)) { (s = lambda { |f| File.exist?(f) ? require(f) : Dir.chdir("..") { s.call(f) } }).call("spec/spec_helper.rb") } +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') provider = Puppet::Type.type(:package).provider(:dpkg) diff --git a/spec/unit/provider/package/gem_spec.rb b/spec/unit/provider/package/gem_spec.rb index 32c067a60..c2bd3cc90 100644 --- a/spec/unit/provider/package/gem_spec.rb +++ b/spec/unit/provider/package/gem_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') provider_class = Puppet::Type.type(:package).provider(:gem) diff --git a/spec/unit/provider/package/hpux_spec.rb b/spec/unit/provider/package/hpux_spec.rb index e4ac22e21..e75ae0822 100644 --- a/spec/unit/provider/package/hpux_spec.rb +++ b/spec/unit/provider/package/hpux_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') provider_class = Puppet::Type.type(:package).provider(:hpux) diff --git a/spec/unit/provider/package/nim_spec.rb b/spec/unit/provider/package/nim_spec.rb index 53a9cc839..74f903813 100755 --- a/spec/unit/provider/package/nim_spec.rb +++ b/spec/unit/provider/package/nim_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') provider_class = Puppet::Type.type(:package).provider(:nim) diff --git a/spec/unit/provider/package/pip_spec.rb b/spec/unit/provider/package/pip_spec.rb new file mode 100644 index 000000000..8953b4b2c --- /dev/null +++ b/spec/unit/provider/package/pip_spec.rb @@ -0,0 +1,177 @@ +#!/usr/bin/env ruby + +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') + +provider_class = Puppet::Type.type(:package).provider(:pip) + +describe provider_class do + + before do + @resource = Puppet::Resource.new(:package, "sdsfdssdhdfyjymdgfcjdfjxdrssf") + @provider = provider_class.new(@resource) + end + + describe "parse" do + + it "should return a hash on valid input" do + provider_class.parse("Django==1.2.5").should == { + :ensure => "1.2.5", + :name => "Django", + :provider => :pip, + } + end + + it "should return nil on invalid input" do + provider_class.parse("foo").should == nil + end + + end + + describe "instances" do + + it "should return an array when pip is present" do + provider_class.expects(:which).with('pip').returns("/fake/bin/pip") + p = stub("process") + p.expects(:collect).yields("Django==1.2.5") + provider_class.expects(:execpipe).with("/fake/bin/pip freeze").yields(p) + provider_class.instances + end + + it "should return an empty array when pip is missing" do + provider_class.expects(:which).with('pip').returns nil + provider_class.instances.should == [] + end + + end + + describe "query" do + + before do + @resource[:name] = "Django" + end + + it "should return a hash when pip and the package are present" do + provider_class.expects(:instances).returns [provider_class.new({ + :ensure => "1.2.5", + :name => "Django", + :provider => :pip, + })] + + @provider.query.should == { + :ensure => "1.2.5", + :name => "Django", + :provider => :pip, + } + end + + it "should return nil when the package is missing" do + provider_class.expects(:instances).returns [] + @provider.query.should == nil + end + + end + + describe "latest" do + + it "should find a version number for Django" do + @resource[:name] = "Django" + @provider.latest.should_not == nil + end + + it "should not find a version number for sdsfdssdhdfyjymdgfcjdfjxdrssf" do + @resource[:name] = "sdsfdssdhdfyjymdgfcjdfjxdrssf" + @provider.latest.should == nil + end + + end + + describe "install" do + + before do + @resource[:name] = "sdsfdssdhdfyjymdgfcjdfjxdrssf" + @url = "git+https://example.com/sdsfdssdhdfyjymdgfcjdfjxdrssf.git" + end + + it "should install" do + @resource[:ensure] = :installed + @resource[:source] = nil + @provider.expects(:lazy_pip). + with("install", '-q', "sdsfdssdhdfyjymdgfcjdfjxdrssf") + @provider.install + end + + it "should install from SCM" do + @resource[:ensure] = :installed + @resource[:source] = @url + @provider.expects(:lazy_pip). + with("install", '-q', '-e', "#{@url}#egg=sdsfdssdhdfyjymdgfcjdfjxdrssf") + @provider.install + end + + it "should install a particular SCM revision" do + @resource[:ensure] = "0123456" + @resource[:source] = @url + @provider.expects(:lazy_pip). + with("install", "-q", "-e", "#{@url}@0123456#egg=sdsfdssdhdfyjymdgfcjdfjxdrssf") + @provider.install + end + + it "should install a particular version" do + @resource[:ensure] = "0.0.0" + @resource[:source] = nil + @provider.expects(:lazy_pip).with("install", "-q", "sdsfdssdhdfyjymdgfcjdfjxdrssf==0.0.0") + @provider.install + end + + it "should upgrade" do + @resource[:ensure] = :latest + @resource[:source] = nil + @provider.expects(:lazy_pip). + with("install", "-q", "--upgrade", "sdsfdssdhdfyjymdgfcjdfjxdrssf") + @provider.install + end + + end + + describe "uninstall" do + + it "should uninstall" do + @resource[:name] = "sdsfdssdhdfyjymdgfcjdfjxdrssf" + @provider.expects(:lazy_pip). + with('uninstall', '-y', '-q', 'sdsfdssdhdfyjymdgfcjdfjxdrssf') + @provider.uninstall + end + + end + + describe "update" do + + it "should just call install" do + @provider.expects(:install).returns(nil) + @provider.update + end + + end + + describe "lazy_pip" do + + it "should succeed if pip is present" do + @provider.stubs(:pip).returns(nil) + @provider.method(:lazy_pip).call "freeze" + end + + it "should retry if pip has not yet been found" do + @provider.expects(:pip).twice.with('freeze').raises(NoMethodError).then.returns(nil) + @provider.expects(:which).with('pip').returns("/fake/bin/pip") + @provider.method(:lazy_pip).call "freeze" + end + + it "should fail if pip is missing" do + @provider.expects(:pip).with('freeze').raises(NoMethodError) + @provider.expects(:which).with('pip').returns(nil) + expect { @provider.method(:lazy_pip).call("freeze") }.to raise_error(NoMethodError) + end + + end + +end diff --git a/spec/unit/provider/package/pkg_spec.rb b/spec/unit/provider/package/pkg_spec.rb index 1544b8b7e..3455c4c40 100644 --- a/spec/unit/provider/package/pkg_spec.rb +++ b/spec/unit/provider/package/pkg_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -Dir.chdir(File.dirname(__FILE__)) { (s = lambda { |f| File.exist?(f) ? require(f) : Dir.chdir("..") { s.call(f) } }).call("spec/spec_helper.rb") } +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') provider = Puppet::Type.type(:package).provider(:pkg) diff --git a/spec/unit/provider/package/pkgdmg_spec.rb b/spec/unit/provider/package/pkgdmg_spec.rb index 1fd5b4ac4..86631e596 100755 --- a/spec/unit/provider/package/pkgdmg_spec.rb +++ b/spec/unit/provider/package/pkgdmg_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -Dir.chdir(File.dirname(__FILE__)) { (s = lambda { |f| File.exist?(f) ? require(f) : Dir.chdir("..") { s.call(f) } }).call("spec/spec_helper.rb") } +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') provider = Puppet::Type.type(:package).provider(:pkgdmg) diff --git a/spec/unit/provider/package/yum_spec.rb b/spec/unit/provider/package/yum_spec.rb new file mode 100644 index 000000000..4e2294a77 --- /dev/null +++ b/spec/unit/provider/package/yum_spec.rb @@ -0,0 +1,67 @@ +#!/usr/bin/env ruby + +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') + +provider = Puppet::Type.type(:package).provider(:yum) + +describe provider do + before do + # Create a mock resource + @resource = stub 'resource' + @resource.stubs(:[]).with(:name).returns 'mypackage' + @provider = provider.new(@resource) + @provider.stubs(:resource).returns @resource + @provider.stubs(:yum).returns 'yum' + @provider.stubs(:rpm).returns 'rpm' + @provider.stubs(:get).with(:name).returns 'mypackage' + @provider.stubs(:get).with(:version).returns '1' + @provider.stubs(:get).with(:release).returns '1' + @provider.stubs(:get).with(:arch).returns 'i386' + end + # provider should repond to the following methods + [:install, :latest, :update, :purge].each do |method| + it "should have a(n) #{method}" do + @provider.should respond_to(method) + end + end + + describe 'when installing' do + it 'should call yum install for :installed' do + @resource.stubs(:should).with(:ensure).returns :installed + @provider.expects(:yum).with('-d', '0', '-e', '0', '-y', :install, 'mypackage') + @provider.install + end + it 'should use :install to update' do + @provider.expects(:install) + @provider.update + end + it 'should be able to set version' do + @resource.stubs(:should).with(:ensure).returns '1.2' + @provider.expects(:yum).with('-d', '0', '-e', '0', '-y', :install, 'mypackage-1.2') + @provider.stubs(:query).returns :ensure => '1.2' + @provider.install + end + it 'should be able to downgrade' do + @resource.stubs(:should).with(:ensure).returns '1.0' + @provider.expects(:yum).with('-d', '0', '-e', '0', '-y', :downgrade, 'mypackage-1.0') + @provider.stubs(:query).returns(:ensure => '1.2').then.returns(:ensure => '1.0') + @provider.install + end + end + + describe 'when uninstalling' do + it 'should use erase to purge' do + @provider.expects(:yum).with('-y', :erase, 'mypackage') + @provider.purge + end + it 'should use rpm to uninstall' do + @provider.expects(:rpm).with('-e', 'mypackage-1-1.i386') + @provider.uninstall + end + end + + it 'should be versionable' do + provider.should be_versionable + end +end + diff --git a/spec/unit/provider/package/zypper_spec.rb b/spec/unit/provider/package/zypper_spec.rb index 5ac13b659..1bf27ad97 100644 --- a/spec/unit/provider/package/zypper_spec.rb +++ b/spec/unit/provider/package/zypper_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') provider_class = Puppet::Type.type(:package).provider(:zypper) diff --git a/spec/unit/provider/parsedfile_spec.rb b/spec/unit/provider/parsedfile_spec.rb index d40f77370..7d95ef1d0 100755 --- a/spec/unit/provider/parsedfile_spec.rb +++ b/spec/unit/provider/parsedfile_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') require 'puppet/provider/parsedfile' diff --git a/spec/unit/provider/selboolean_spec.rb b/spec/unit/provider/selboolean_spec.rb index b37b44b45..02a39f2a7 100755 --- a/spec/unit/provider/selboolean_spec.rb +++ b/spec/unit/provider/selboolean_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -Dir.chdir(File.dirname(__FILE__)) { (s = lambda { |f| File.exist?(f) ? require(f) : Dir.chdir("..") { s.call(f) } }).call("spec/spec_helper.rb") } +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') provider_class = Puppet::Type.type(:selboolean).provider(:getsetsebool) diff --git a/spec/unit/provider/selmodule_spec.rb b/spec/unit/provider/selmodule_spec.rb index fda6d0d78..cb143e993 100755 --- a/spec/unit/provider/selmodule_spec.rb +++ b/spec/unit/provider/selmodule_spec.rb @@ -5,7 +5,7 @@ # with version 1.5.0. The provided selmodule-example.pp is the first # 256 bytes taken from /usr/share/selinux/targeted/nagios.pp on Fedora 9 -Dir.chdir(File.dirname(__FILE__)) { (s = lambda { |f| File.exist?(f) ? require(f) : Dir.chdir("..") { s.call(f) } }).call("spec/spec_helper.rb") } +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') provider_class = Puppet::Type.type(:selmodule).provider(:semodule) diff --git a/spec/unit/provider/service/daemontools_spec.rb b/spec/unit/provider/service/daemontools_spec.rb index 5e8b8d055..0bdb0a85d 100755 --- a/spec/unit/provider/service/daemontools_spec.rb +++ b/spec/unit/provider/service/daemontools_spec.rb @@ -4,7 +4,7 @@ # # author Brice Figureau # -require File.dirname(__FILE__) + '/../../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') provider_class = Puppet::Type.type(:service).provider(:daemontools) diff --git a/spec/unit/provider/service/debian_spec.rb b/spec/unit/provider/service/debian_spec.rb index 440d4491b..b5edf6882 100755 --- a/spec/unit/provider/service/debian_spec.rb +++ b/spec/unit/provider/service/debian_spec.rb @@ -3,7 +3,7 @@ # Unit testing for the debian service provider # -require File.dirname(__FILE__) + '/../../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') provider_class = Puppet::Type.type(:service).provider(:debian) diff --git a/spec/unit/provider/service/freebsd_spec.rb b/spec/unit/provider/service/freebsd_spec.rb index 0330adbed..d8b751108 100644 --- a/spec/unit/provider/service/freebsd_spec.rb +++ b/spec/unit/provider/service/freebsd_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') provider_class = Puppet::Type.type(:service).provider(:freebsd) diff --git a/spec/unit/provider/service/init_spec.rb b/spec/unit/provider/service/init_spec.rb index 856821985..b54c27e8e 100755 --- a/spec/unit/provider/service/init_spec.rb +++ b/spec/unit/provider/service/init_spec.rb @@ -3,7 +3,7 @@ # Unit testing for the Init service Provider # -require File.dirname(__FILE__) + '/../../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') provider_class = Puppet::Type.type(:service).provider(:init) diff --git a/spec/unit/provider/service/launchd_spec.rb b/spec/unit/provider/service/launchd_spec.rb index 43e4cba8e..dfcb58fdc 100755 --- a/spec/unit/provider/service/launchd_spec.rb +++ b/spec/unit/provider/service/launchd_spec.rb @@ -3,7 +3,7 @@ # Unit testing for the launchd service provider # -require File.dirname(__FILE__) + '/../../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') require 'puppet' diff --git a/spec/unit/provider/service/redhat_spec.rb b/spec/unit/provider/service/redhat_spec.rb index fd5822788..a3c6247dd 100755 --- a/spec/unit/provider/service/redhat_spec.rb +++ b/spec/unit/provider/service/redhat_spec.rb @@ -2,7 +2,7 @@ # # Unit testing for the RedHat service Provider # -require File.dirname(__FILE__) + '/../../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') provider_class = Puppet::Type.type(:service).provider(:redhat) diff --git a/spec/unit/provider/service/runit_spec.rb b/spec/unit/provider/service/runit_spec.rb index 80ce456b4..12dfeeb35 100755 --- a/spec/unit/provider/service/runit_spec.rb +++ b/spec/unit/provider/service/runit_spec.rb @@ -4,7 +4,7 @@ # # author Brice Figureau # -require File.dirname(__FILE__) + '/../../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') provider_class = Puppet::Type.type(:service).provider(:runit) diff --git a/spec/unit/provider/service/smf_spec.rb b/spec/unit/provider/service/smf_spec.rb new file mode 100755 index 000000000..40e96ab23 --- /dev/null +++ b/spec/unit/provider/service/smf_spec.rb @@ -0,0 +1,137 @@ +#!/usr/bin/env ruby +# +# Unit testing for the SMF service Provider +# +# author Dominic Cleal +# +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') + +provider_class = Puppet::Type.type(:service).provider(:smf) + +describe provider_class do + + before(:each) do + # Create a mock resource + @resource = Puppet::Type.type(:service).new( + :name => "/system/myservice", :ensure => :running, :enable => :true) + @provider = provider_class.new(@resource) + + FileTest.stubs(:file?).with('/usr/sbin/svcadm').returns true + FileTest.stubs(:executable?).with('/usr/sbin/svcadm').returns true + FileTest.stubs(:file?).with('/usr/bin/svcs').returns true + FileTest.stubs(:executable?).with('/usr/bin/svcs').returns true + end + + it "should have a restart method" do + @provider.should respond_to(:restart) + end + + it "should have a restartcmd method" do + @provider.should respond_to(:restartcmd) + end + + it "should have a start method" do + @provider.should respond_to(:start) + end + + it "should have a stop method" do + @provider.should respond_to(:stop) + end + + it "should have an enabled? method" do + @provider.should respond_to(:enabled?) + end + + it "should have an enable method" do + @provider.should respond_to(:enable) + end + + it "should have a disable method" do + @provider.should respond_to(:disable) + end + + describe "when checking status" do + it "should call the external command 'svcs /system/myservice' once" do + @provider.expects(:svcs).with('-H', '-o', 'state,nstate', "/system/myservice").returns("online\t-") + @provider.status + end + it "should return stopped if svcs can't find the service" do + @provider.stubs(:svcs).raises(Puppet::ExecutionFailure.new("no svc found")) + @provider.status.should == :stopped + end + it "should return running if online in svcs output" do + @provider.stubs(:svcs).returns("online\t-") + @provider.status.should == :running + end + it "should return stopped if disabled in svcs output" do + @provider.stubs(:svcs).returns("disabled\t-") + @provider.status.should == :stopped + end + it "should return maintenance if in maintenance in svcs output" do + @provider.stubs(:svcs).returns("maintenance\t-") + @provider.status.should == :maintenance + end + it "should return target state if transitioning in svcs output" do + @provider.stubs(:svcs).returns("online\tdisabled") + @provider.status.should == :stopped + end + it "should throw error if it's a legacy service in svcs output" do + @provider.stubs(:svcs).returns("legacy_run\t-") + lambda { @provider.status }.should raise_error(Puppet::Error, "Cannot manage legacy services through SMF") + end + end + + describe "when starting" do + it "should enable the service if it is not enabled" do + @provider.expects(:status).returns :stopped + @provider.expects(:texecute) + @provider.start + end + + it "should always execute external command 'svcadm enable /system/myservice'" do + @provider.stubs(:status).returns :running + @provider.expects(:texecute).with(:start, ["/usr/sbin/svcadm", :enable, "/system/myservice"], true) + @provider.start + end + + it "should execute external command 'svcadm clear /system/myservice' if in maintenance" do + @provider.stubs(:status).returns :maintenance + @provider.expects(:texecute).with(:start, ["/usr/sbin/svcadm", :clear, "/system/myservice"], true) + @provider.start + end + end + + describe "when starting a service with a manifest" do + before(:each) do + @resource = Puppet::Type.type(:service).new(:name => "/system/myservice", :ensure => :running, :enable => :true, :manifest => "/tmp/myservice.xml") + @provider = provider_class.new(@resource) + $CHILD_STATUS.stubs(:exitstatus).returns(1) + end + + it "should import the manifest if service is missing" do + @provider.expects(:svccfg).with(:import, "/tmp/myservice.xml") + @provider.expects(:texecute).with(:start, ["/usr/sbin/svcadm", :enable, "/system/myservice"], true) + @provider.start + end + + it "should handle failures if importing a manifest" do + @provider.expects(:svccfg).raises(Puppet::ExecutionFailure.new("can't svccfg import")) + lambda { @provider.start }.should raise_error(Puppet::Error, "Cannot config /system/myservice to enable it: can't svccfg import") + end + end + + describe "when stopping" do + it "should execute external command 'svcadm disable /system/myservice'" do + @provider.expects(:texecute).with(:stop, ["/usr/sbin/svcadm", :disable, "/system/myservice"], true) + @provider.stop + end + end + + describe "when restarting" do + it "should call 'svcadm restart /system/myservice'" do + @provider.expects(:texecute).with(:restart, ["/usr/sbin/svcadm", :restart, "/system/myservice"], true) + @provider.restart + end + end + +end diff --git a/spec/unit/provider/service/src_spec.rb b/spec/unit/provider/service/src_spec.rb index eff98f030..dbe073513 100755 --- a/spec/unit/provider/service/src_spec.rb +++ b/spec/unit/provider/service/src_spec.rb @@ -3,7 +3,7 @@ # Unit testing for the AIX System Resource Controller (src) provider # -require File.dirname(__FILE__) + '/../../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') provider_class = Puppet::Type.type(:service).provider(:src) diff --git a/spec/unit/provider/service/upstart.rb b/spec/unit/provider/service/upstart.rb new file mode 100644 index 000000000..22cf2bdeb --- /dev/null +++ b/spec/unit/provider/service/upstart.rb @@ -0,0 +1,49 @@ +#!/usr/bin/env ruby + +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') + +provider_class = Puppet::Type.type(:service).provider(:upstart) + +describe provider_class do + describe "#instances" do + it "should be able to find all instances" do + processes = ["rc stop/waiting", "ssh start/running, process 712"] + provider_class.stubs(:execpipe).yields(processes) + provider_class.instances.map {|provider| provider.name}.should =~ ["rc","ssh"] + end + + it "should attach the interface name for network interfaces" do + processes = ["network-interface (eth0)"] + provider_class.stubs(:execpipe).yields(processes) + provider_class.instances.first.name.should == "network-interface INTERFACE=eth0" + end + end + + describe "#status" do + it "should allow the user to override the status command" do + resource = Puppet::Type.type(:service).new(:name => "foo", :provider => :upstart, :status => "/bin/foo") + provider = provider_class.new(resource) + + provider.expects(:ucommand).with { `true`; true } + provider.status.should == :running + end + + it "should use the default status command if none is specified" do + resource = Puppet::Type.type(:service).new(:name => "foo", :provider => :upstart) + provider = provider_class.new(resource) + + provider.expects(:status_exec).with(["foo"]).returns("foo start/running, process 1000") + Process::Status.any_instance.stubs(:exitstatus).returns(0) + provider.status.should == :running + end + + it "should properly handle services with 'start' in their name" do + resource = Puppet::Type.type(:service).new(:name => "foostartbar", :provider => :upstart) + provider = provider_class.new(resource) + + provider.expects(:status_exec).with(["foostartbar"]).returns("foostartbar stop/waiting") + Process::Status.any_instance.stubs(:exitstatus).returns(0) + provider.status.should == :stopped + end + end +end diff --git a/spec/unit/provider/ssh_authorized_key/parsed_spec.rb b/spec/unit/provider/ssh_authorized_key/parsed_spec.rb index 2e5be165a..3ac57facc 100755 --- a/spec/unit/provider/ssh_authorized_key/parsed_spec.rb +++ b/spec/unit/provider/ssh_authorized_key/parsed_spec.rb @@ -1,19 +1,13 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../../spec_helper' - +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') +require 'shared_behaviours/all_parsedfile_providers' require 'puppet_spec/files' -require 'puppettest/support/utils' -require 'puppettest/fileparsing' -require 'puppettest/fakes' provider_class = Puppet::Type.type(:ssh_authorized_key).provider(:parsed) describe provider_class do include PuppetSpec::Files - extend PuppetTest::Support::Utils - include PuppetTest - include PuppetTest::FileParsing before :each do @sshauthkey_class = Puppet::Type.type(:ssh_authorized_key) @@ -29,15 +23,13 @@ describe provider_class do end def mkkey(args) - fakeresource = fakeresource(:ssh_authorized_key, args[:name]) - fakeresource.stubs(:should).with(:user).returns @user - fakeresource.stubs(:should).with(:target).returns @keyfile - - key = @provider.new(fakeresource) + args[:target] = @keyfile + args[:user] = @user + resource = Puppet::Type.type(:ssh_authorized_key).new(args) + key = @provider.new(resource) args.each do |p,v| key.send(p.to_s + "=", v) end - key end @@ -50,38 +42,28 @@ describe provider_class do @provider.target_object(@keyfile).read end - fakedata("data/providers/ssh_authorized_key/parsed").each { |file| - it "should be able to parse example data in #{file}" do - fakedataparse(file) - end - } + it_should_behave_like "all parsedfile providers", provider_class it "should be able to generate a basic authorized_keys file" do - key = mkkey( - { - :name => "Just Testing", - :key => "AAAAfsfddsjldjgksdflgkjsfdlgkj", - :type => "ssh-dss", - :ensure => :present, - - :options => [:absent] - }) + key = mkkey(:name => "Just Testing", + :key => "AAAAfsfddsjldjgksdflgkjsfdlgkj", + :type => "ssh-dss", + :ensure => :present, + :options => [:absent] + ) genkey(key).should == "ssh-dss AAAAfsfddsjldjgksdflgkjsfdlgkj Just Testing\n" end it "should be able to generate a authorized_keys file with options" do - key = mkkey( - { - :name => "root@localhost", - :key => "AAAAfsfddsjldjgksdflgkjsfdlgkj", - :type => "ssh-rsa", - :ensure => :present, - - :options => ['from="192.168.1.1"', "no-pty", "no-X11-forwarding"] - }) + key = mkkey(:name => "root@localhost", + :key => "AAAAfsfddsjldjgksdflgkjsfdlgkj", + :type => "ssh-rsa", + :ensure => :present, + :options => ['from="192.168.1.1"', "no-pty", "no-X11-forwarding"] + ) genkey(key).should == "from=\"192.168.1.1\",no-pty,no-X11-forwarding ssh-rsa AAAAfsfddsjldjgksdflgkjsfdlgkj root@localhost\n" end diff --git a/spec/unit/provider/sshkey/parsed_spec.rb b/spec/unit/provider/sshkey/parsed_spec.rb index 1a5470974..7a76b02d6 100755 --- a/spec/unit/provider/sshkey/parsed_spec.rb +++ b/spec/unit/provider/sshkey/parsed_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') provider_class = Puppet::Type.type(:sshkey).provider(:parsed) diff --git a/spec/unit/provider/user/hpux_spec.rb b/spec/unit/provider/user/hpux_spec.rb index f53f6c31e..b10f2847c 100755 --- a/spec/unit/provider/user/hpux_spec.rb +++ b/spec/unit/provider/user/hpux_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') provider_class = Puppet::Type.type(:user).provider(:hpuxuseradd) diff --git a/spec/unit/provider/user/ldap_spec.rb b/spec/unit/provider/user/ldap_spec.rb index b6635705d..5b2dc98b5 100755 --- a/spec/unit/provider/user/ldap_spec.rb +++ b/spec/unit/provider/user/ldap_spec.rb @@ -3,7 +3,7 @@ # Created by Luke Kanies on 2008-3-10. # Copyright (c) 2006. All rights reserved. -require File.dirname(__FILE__) + '/../../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') provider_class = Puppet::Type.type(:user).provider(:ldap) diff --git a/spec/unit/provider/user/user_role_add_spec.rb b/spec/unit/provider/user/user_role_add_spec.rb index f73942389..12a71d25a 100644 --- a/spec/unit/provider/user/user_role_add_spec.rb +++ b/spec/unit/provider/user/user_role_add_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') provider_class = Puppet::Type.type(:user).provider(:user_role_add) diff --git a/spec/unit/provider/user/useradd_spec.rb b/spec/unit/provider/user/useradd_spec.rb index fd75c43f3..b1719eeaf 100755 --- a/spec/unit/provider/user/useradd_spec.rb +++ b/spec/unit/provider/user/useradd_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') provider_class = Puppet::Type.type(:user).provider(:useradd) diff --git a/spec/unit/provider/zfs/solaris_spec.rb b/spec/unit/provider/zfs/solaris_spec.rb index 43a88b1c7..84a2be9f6 100755 --- a/spec/unit/provider/zfs/solaris_spec.rb +++ b/spec/unit/provider/zfs/solaris_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') provider_class = Puppet::Type.type(:zfs).provider(:solaris) @@ -27,6 +27,7 @@ describe provider_class do describe "when calling add_properties" do it "should add -o and the key=value for each properties with a value" do @resource.stubs(:[]).with(:quota).returns "" + @resource.stubs(:[]).with(:refquota).returns "" @resource.stubs(:[]).with(:mountpoint).returns "/foo" properties = @provider.add_properties properties.include?("-o").should == true @@ -75,7 +76,7 @@ describe provider_class do end - [:mountpoint, :compression, :copies, :quota, :reservation, :sharenfs, :snapdir].each do |prop| + [:mountpoint, :recordsize, :aclmode, :aclinherit, :primarycache, :secondarycache, :compression, :copies, :quota, :reservation, :sharenfs, :snapdir].each do |prop| describe "when getting the #{prop} value" do it "should call zfs with :get, #{prop} and this zfs" do @provider.expects(:zfs).with(:get, "-H", "-o", "value", prop, @resource[:name]).returns("value\n") diff --git a/spec/unit/provider/zone/solaris_spec.rb b/spec/unit/provider/zone/solaris_spec.rb index 44416aa61..4a1d03272 100755 --- a/spec/unit/provider/zone/solaris_spec.rb +++ b/spec/unit/provider/zone/solaris_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') provider_class = Puppet::Type.type(:zone).provider(:solaris) diff --git a/spec/unit/provider/zpool/solaris_spec.rb b/spec/unit/provider/zpool/solaris_spec.rb index 99e6997e4..e2a0e16c8 100755 --- a/spec/unit/provider/zpool/solaris_spec.rb +++ b/spec/unit/provider/zpool/solaris_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') provider_class = Puppet::Type.type(:zpool).provider(:solaris) @@ -76,6 +76,13 @@ describe provider_class do end end + describe "when the vdev is a single mirror on solaris 10u9 or later" do + it "should call create_multi_array with mirror" do + @zpool_data = ["mirrorpool", "mirror-0", "disk1", "disk2"] + @provider.process_zpool_data(@zpool_data)[:mirror].should == ["disk1 disk2"] + end + end + describe "when the vdev is a double mirror" do it "should call create_multi_array with mirror" do @zpool_data = ["mirrorpool", "mirror", "disk1", "disk2", "mirror", "disk3", "disk4"] @@ -83,6 +90,13 @@ describe provider_class do end end + describe "when the vdev is a double mirror on solaris 10u9 or later" do + it "should call create_multi_array with mirror" do + @zpool_data = ["mirrorpool", "mirror-0", "disk1", "disk2", "mirror-1", "disk3", "disk4"] + @provider.process_zpool_data(@zpool_data)[:mirror].should == ["disk1 disk2", "disk3 disk4"] + end + end + describe "when the vdev is a raidz1" do it "should call create_multi_array with raidz1" do @zpool_data = ["mirrorpool", "raidz1", "disk1", "disk2"] @@ -90,6 +104,13 @@ describe provider_class do end end + describe "when the vdev is a raidz1 on solaris 10u9 or later" do + it "should call create_multi_array with raidz1" do + @zpool_data = ["mirrorpool", "raidz1-0", "disk1", "disk2"] + @provider.process_zpool_data(@zpool_data)[:raidz].should == ["disk1 disk2"] + end + end + describe "when the vdev is a raidz2" do it "should call create_multi_array with raidz2 and set the raid_parity" do @zpool_data = ["mirrorpool", "raidz2", "disk1", "disk2"] @@ -98,6 +119,15 @@ describe provider_class do pool[:raid_parity].should == "raidz2" end end + + describe "when the vdev is a raidz2 on solaris 10u9 or later" do + it "should call create_multi_array with raidz2 and set the raid_parity" do + @zpool_data = ["mirrorpool", "raidz2-0", "disk1", "disk2"] + pool = @provider.process_zpool_data(@zpool_data) + pool[:raidz].should == ["disk1 disk2"] + pool[:raid_parity].should == "raidz2" + end + end end describe "when calling the getters and setters" do diff --git a/spec/unit/provider_spec.rb b/spec/unit/provider_spec.rb index 629406535..24f5216fe 100755 --- a/spec/unit/provider_spec.rb +++ b/spec/unit/provider_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../spec_helper') describe Puppet::Provider do it "should have a specifity class method" do diff --git a/spec/unit/puppet_spec.rb b/spec/unit/puppet_spec.rb index 60ac9e9d9..28dbd5104 100755 --- a/spec/unit/puppet_spec.rb +++ b/spec/unit/puppet_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby" -require File.dirname(__FILE__) + '/../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../spec_helper') require 'puppet' describe Puppet do diff --git a/spec/unit/rails/host_spec.rb b/spec/unit/rails/host_spec.rb index 4244f117f..e83135c91 100755 --- a/spec/unit/rails/host_spec.rb +++ b/spec/unit/rails/host_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') describe "Puppet::Rails::Host", :if => Puppet.features.rails? do def column(name, type) diff --git a/spec/unit/rails/param_value_spec.rb b/spec/unit/rails/param_value_spec.rb index f67022a14..9a725cfc8 100755 --- a/spec/unit/rails/param_value_spec.rb +++ b/spec/unit/rails/param_value_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') require 'puppet/rails' describe "Puppet::Rails::ParamValue", :if => Puppet.features.rails? do diff --git a/spec/unit/rails/resource_spec.rb b/spec/unit/rails/resource_spec.rb index e5bd8a6c9..3fbbbc7b7 100755 --- a/spec/unit/rails/resource_spec.rb +++ b/spec/unit/rails/resource_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') require 'puppet/rails' describe "Puppet::Rails::Resource", :if => Puppet.features.rails? do diff --git a/spec/unit/rails_spec.rb b/spec/unit/rails_spec.rb index 02b54efef..a08485e4c 100755 --- a/spec/unit/rails_spec.rb +++ b/spec/unit/rails_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../spec_helper') require 'puppet/rails' describe Puppet::Rails, "when initializing any connection", :if => Puppet.features.rails? do diff --git a/spec/unit/relationship_spec.rb b/spec/unit/relationship_spec.rb index 9ce6c56e7..362d74c74 100755 --- a/spec/unit/relationship_spec.rb +++ b/spec/unit/relationship_spec.rb @@ -3,7 +3,7 @@ # Created by Luke Kanies on 2007-11-1. # Copyright (c) 2006. All rights reserved. -require File.dirname(__FILE__) + '/../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../spec_helper') require 'puppet/relationship' describe Puppet::Relationship do diff --git a/spec/unit/reports/http_spec.rb b/spec/unit/reports/http_spec.rb index 70742f7dc..a62793ed5 100644 --- a/spec/unit/reports/http_spec.rb +++ b/spec/unit/reports/http_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -Dir.chdir(File.dirname(__FILE__)) { (s = lambda { |f| File.exist?(f) ? require(f) : Dir.chdir("..") { s.call(f) } }).call("spec/spec_helper.rb") } +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') require 'puppet/reports' diff --git a/spec/unit/reports/rrdgraph_spec.rb b/spec/unit/reports/rrdgraph_spec.rb index ce2cf7905..5215f1dcc 100644 --- a/spec/unit/reports/rrdgraph_spec.rb +++ b/spec/unit/reports/rrdgraph_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -Dir.chdir(File.dirname(__FILE__)) { (s = lambda { |f| File.exist?(f) ? require(f) : Dir.chdir("..") { s.call(f) } }).call("spec/spec_helper.rb") } +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') require 'puppet/reports' diff --git a/spec/unit/reports/store_spec.rb b/spec/unit/reports/store_spec.rb index 9d9042386..d48f6a846 100644 --- a/spec/unit/reports/store_spec.rb +++ b/spec/unit/reports/store_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -Dir.chdir(File.dirname(__FILE__)) { (s = lambda { |f| File.exist?(f) ? require(f) : Dir.chdir("..") { s.call(f) } }).call("spec/spec_helper.rb") } +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') require 'puppet/reports' require 'time' diff --git a/spec/unit/reports/tagmail_spec.rb b/spec/unit/reports/tagmail_spec.rb index 1dadfc7cd..716bcbc04 100755 --- a/spec/unit/reports/tagmail_spec.rb +++ b/spec/unit/reports/tagmail_spec.rb @@ -1,28 +1,25 @@ #!/usr/bin/env ruby -Dir.chdir(File.dirname(__FILE__)) { (s = lambda { |f| File.exist?(f) ? require(f) : Dir.chdir("..") { s.call(f) } }).call("spec/spec_helper.rb") } +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') require 'puppet/reports' -require 'puppettest/support/utils' tagmail = Puppet::Reports.report(:tagmail) describe tagmail do - extend PuppetTest::Support::Utils - before do @processor = Puppet::Transaction::Report.new("apply") @processor.extend(Puppet::Reports.report(:tagmail)) end - passers = File.join(datadir, "reports", "tagmail_passers.conf") + passers = my_fixture "tagmail_passers.conf" File.readlines(passers).each do |line| it "should be able to parse '#{line.inspect}'" do @processor.parse(line) end end - failers = File.join(datadir, "reports", "tagmail_failers.conf") + failers = my_fixture "tagmail_failers.conf" File.readlines(failers).each do |line| it "should not be able to parse '#{line.inspect}'" do lambda { @processor.parse(line) }.should raise_error(ArgumentError) diff --git a/spec/unit/reports_spec.rb b/spec/unit/reports_spec.rb index 57e77a546..a9d10be17 100755 --- a/spec/unit/reports_spec.rb +++ b/spec/unit/reports_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../spec_helper') require 'puppet/reports' diff --git a/spec/unit/resource/catalog_spec.rb b/spec/unit/resource/catalog_spec.rb index 942721464..78d1b3223 100755 --- a/spec/unit/resource/catalog_spec.rb +++ b/spec/unit/resource/catalog_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') describe Puppet::Resource::Catalog, "when compiling" do @@ -374,7 +374,7 @@ describe Puppet::Resource::Catalog, "when compiling" do @original.add_edge(@r1,@r2) @original.filter do |r| r == @r1 - end.edge(@r1,@r2).should be_empty + end.edge?(@r1,@r2).should_not be end end @@ -398,12 +398,6 @@ describe Puppet::Resource::Catalog, "when compiling" do relgraph.should be_vertex(@one) end - it "should yield added resources if a block is provided" do - yielded = [] - @catalog.add_resource(@one, @two) { |r| yielded << r } - yielded.length.should == 2 - end - it "should set itself as the resource's catalog if it is not a relationship graph" do @one.expects(:catalog=).with(@catalog) @catalog.add_resource @one @@ -740,7 +734,7 @@ describe Puppet::Resource::Catalog, "when compiling" do end it "should copy component relationships to all contained resources" do - @relationships.edge?(@one, @two).should be_true + @relationships.path_between(@one, @two).should be end it "should add automatic relationships to the relationship graph" do @@ -818,12 +812,6 @@ describe Puppet::Resource::Catalog, "when compiling" do Puppet::Util::Cacher.expire end - it "should redirect to the indirection for retrieval" do - Puppet::Resource::Catalog.stubs(:indirection).returns(@indirection) - @indirection.expects(:find) - Puppet::Resource::Catalog.find(:myconfig) - end - it "should use the value of the 'catalog_terminus' setting to determine its terminus class" do # Puppet only checks the terminus setting the first time you ask # so this returns the object to the clean state @@ -931,8 +919,8 @@ describe Puppet::Resource::Catalog, "when converting to pson", :if => Puppet.fea @catalog.add_edge(one, two) @catalog.add_edge(two, three) - @catalog.edge(one, two ).expects(:to_pson_data_hash).returns "one_two_pson" - @catalog.edge(two, three).expects(:to_pson_data_hash).returns "two_three_pson" + @catalog.edges_between(one, two )[0].expects(:to_pson_data_hash).returns "one_two_pson" + @catalog.edges_between(two, three)[0].expects(:to_pson_data_hash).returns "two_three_pson" PSON.parse(@catalog.to_pson,:create_additions => false)['data']['edges'].sort.should == %w{one_two_pson two_three_pson}.sort end diff --git a/spec/unit/resource/status_spec.rb b/spec/unit/resource/status_spec.rb index 4e76fa463..343b8d318 100755 --- a/spec/unit/resource/status_spec.rb +++ b/spec/unit/resource/status_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') require 'puppet/resource/status' diff --git a/spec/unit/resource/type_collection_helper_spec.rb b/spec/unit/resource/type_collection_helper_spec.rb index 608b6e61f..442cfd076 100644 --- a/spec/unit/resource/type_collection_helper_spec.rb +++ b/spec/unit/resource/type_collection_helper_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') require 'puppet/resource/type_collection_helper' diff --git a/spec/unit/resource/type_collection_spec.rb b/spec/unit/resource/type_collection_spec.rb index 1576c0615..278e629bd 100644 --- a/spec/unit/resource/type_collection_spec.rb +++ b/spec/unit/resource/type_collection_spec.rb @@ -1,12 +1,11 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') require 'puppet/resource/type_collection' require 'puppet/resource/type' describe Puppet::Resource::TypeCollection do - include PuppetSpec::Files before do @instance = Puppet::Resource::Type.new(:hostclass, "foo") @code = Puppet::Resource::TypeCollection.new("env") @@ -90,6 +89,34 @@ describe Puppet::Resource::TypeCollection do loader.node("node").should be_nil end + describe "when resolving namespaces" do + [ ['', '::foo', ['foo']], + ['a', '::foo', ['foo']], + ['a::b', '::foo', ['foo']], + [['a::b'], '::foo', ['foo']], + [['a::b', 'c'], '::foo', ['foo']], + [['A::B', 'C'], '::Foo', ['foo']], + ['', '', ['']], + ['a', '', ['']], + ['a::b', '', ['']], + [['a::b'], '', ['']], + [['a::b', 'c'], '', ['']], + [['A::B', 'C'], '', ['']], + ['', 'foo', ['foo']], + ['a', 'foo', ['a::foo', 'foo']], + ['a::b', 'foo', ['a::b::foo', 'a::foo', 'foo']], + ['A::B', 'Foo', ['a::b::foo', 'a::foo', 'foo']], + [['a::b'], 'foo', ['a::b::foo', 'a::foo', 'foo']], + [['a', 'b'], 'foo', ['a::foo', 'foo', 'b::foo']], + [['a::b', 'c::d'], 'foo', ['a::b::foo', 'a::foo', 'foo', 'c::d::foo', 'c::foo']], + [['a::b', 'a::c'], 'foo', ['a::b::foo', 'a::foo', 'foo', 'a::c::foo']], + ].each do |namespaces, name, expected_result| + it "should resolve #{name.inspect} in namespaces #{namespaces.inspect} correctly" do + @code.instance_eval { resolve_namespaces(namespaces, name) }.should == expected_result + end + end + end + describe "when looking up names" do before do @type = Puppet::Resource::Type.new(:hostclass, "ns::klass") @@ -108,29 +135,32 @@ describe Puppet::Resource::TypeCollection do describe "that need to be loaded" do it "should use the loader to load the files" do - @code.loader.expects(:load_until).with(["ns"], "klass") - @code.find_or_load(["ns"], "klass", :hostclass) + @code.loader.expects(:try_load_fqname).with(:hostclass, "ns::klass") + @code.loader.expects(:try_load_fqname).with(:hostclass, "klass") + @code.find_hostclass(["ns"], "klass") end it "should downcase the name and downcase and array-fy the namespaces before passing to the loader" do - @code.loader.expects(:load_until).with(["ns"], "klass") - @code.find_or_load("Ns", "Klass", :hostclass) + @code.loader.expects(:try_load_fqname).with(:hostclass, "ns::klass") + @code.loader.expects(:try_load_fqname).with(:hostclass, "klass") + @code.find_hostclass("Ns", "Klass") end - it "should attempt to find the type when the loader yields" do - @code.loader.expects(:load_until).yields - @code.expects(:find).with(["ns"], "klass", :hostclass).times(2).returns(false).then.returns(true) - @code.find_or_load("ns", "klass", :hostclass) + it "should use the class returned by the loader" do + @code.loader.expects(:try_load_fqname).returns(:klass) + @code.expects(:hostclass).with("ns::klass").returns(false) + @code.find_hostclass("ns", "klass").should == :klass end - it "should return the result of 'load_until'" do - @code.loader.expects(:load_until).returns "foo" - @code.find_or_load("Ns", "Klass", :hostclass).should == "foo" + it "should return nil if the name isn't found" do + @code.stubs(:try_load_fqname).returns(nil) + @code.find_hostclass("Ns", "Klass").should be_nil end - it "should return nil if the name isn't found" do - @code.stubs(:load_until).returns(nil) - @code.find_or_load("Ns", "Klass", :hostclass).should be_nil + it "already-loaded names at broader scopes should not shadow autoloaded names" do + @code.add Puppet::Resource::Type.new(:hostclass, "bar") + @code.loader.expects(:try_load_fqname).with(:hostclass, "foo::bar").returns(:foobar) + @code.find_hostclass("foo", "bar").should == :foobar end end end @@ -196,68 +226,68 @@ describe Puppet::Resource::TypeCollection do loader = Puppet::Resource::TypeCollection.new("env") instance = Puppet::Resource::Type.new(:hostclass, "foo::bar") loader.add instance - loader.find("namespace", "::foo::bar", :hostclass).should equal(instance) + loader.find_hostclass("namespace", "::foo::bar").should equal(instance) end it "should return nil if the instance name is fully qualified and no such instance exists" do loader = Puppet::Resource::TypeCollection.new("env") - loader.find("namespace", "::foo::bar", :hostclass).should be_nil + loader.find_hostclass("namespace", "::foo::bar").should be_nil end it "should be able to find classes in the base namespace" do loader = Puppet::Resource::TypeCollection.new("env") instance = Puppet::Resource::Type.new(:hostclass, "foo") loader.add instance - loader.find("", "foo", :hostclass).should equal(instance) + loader.find_hostclass("", "foo").should equal(instance) end it "should return the partially qualified object if it exists in a provided namespace" do loader = Puppet::Resource::TypeCollection.new("env") instance = Puppet::Resource::Type.new(:hostclass, "foo::bar::baz") loader.add instance - loader.find("foo", "bar::baz", :hostclass).should equal(instance) + loader.find_hostclass("foo", "bar::baz").should equal(instance) end it "should be able to find partially qualified objects in any of the provided namespaces" do loader = Puppet::Resource::TypeCollection.new("env") instance = Puppet::Resource::Type.new(:hostclass, "foo::bar::baz") loader.add instance - loader.find(["nons", "foo", "otherns"], "bar::baz", :hostclass).should equal(instance) + loader.find_hostclass(["nons", "foo", "otherns"], "bar::baz").should equal(instance) end it "should return the unqualified object if it exists in a provided namespace" do loader = Puppet::Resource::TypeCollection.new("env") instance = Puppet::Resource::Type.new(:hostclass, "foo::bar") loader.add instance - loader.find("foo", "bar", :hostclass).should equal(instance) + loader.find_hostclass("foo", "bar").should equal(instance) end it "should return the unqualified object if it exists in the parent namespace" do loader = Puppet::Resource::TypeCollection.new("env") instance = Puppet::Resource::Type.new(:hostclass, "foo::bar") loader.add instance - loader.find("foo::bar::baz", "bar", :hostclass).should equal(instance) + loader.find_hostclass("foo::bar::baz", "bar").should equal(instance) end it "should should return the partially qualified object if it exists in the parent namespace" do loader = Puppet::Resource::TypeCollection.new("env") instance = Puppet::Resource::Type.new(:hostclass, "foo::bar::baz") loader.add instance - loader.find("foo::bar", "bar::baz", :hostclass).should equal(instance) + loader.find_hostclass("foo::bar", "bar::baz").should equal(instance) end it "should return the qualified object if it exists in the root namespace" do loader = Puppet::Resource::TypeCollection.new("env") instance = Puppet::Resource::Type.new(:hostclass, "foo::bar::baz") loader.add instance - loader.find("foo::bar", "foo::bar::baz", :hostclass).should equal(instance) + loader.find_hostclass("foo::bar", "foo::bar::baz").should equal(instance) end it "should return nil if the object cannot be found" do loader = Puppet::Resource::TypeCollection.new("env") instance = Puppet::Resource::Type.new(:hostclass, "foo::bar::baz") loader.add instance - loader.find("foo::bar", "eh", :hostclass).should be_nil + loader.find_hostclass("foo::bar", "eh").should be_nil end describe "when topscope has a class that has the same name as a local class" do @@ -269,28 +299,29 @@ describe Puppet::Resource::TypeCollection do end it "should favor the local class, if the name is unqualified" do - @loader.find("foo", "bar", :hostclass).name.should == 'foo::bar' + @loader.find_hostclass("foo", "bar").name.should == 'foo::bar' end it "should only look in the topclass, if the name is qualified" do - @loader.find("foo", "::bar", :hostclass).name.should == 'bar' + @loader.find_hostclass("foo", "::bar").name.should == 'bar' end end - + it "should not look in the local scope for classes when the name is qualified" do @loader = Puppet::Resource::TypeCollection.new("env") @loader.add Puppet::Resource::Type.new(:hostclass, "foo::bar") - @loader.find("foo", "::bar", :hostclass).should == nil + @loader.find_hostclass("foo", "::bar").should == nil end end - it "should use the generic 'find' method with an empty namespace to find nodes" do + it "should be able to find nodes" do + node = Puppet::Resource::Type.new(:node, "bar") loader = Puppet::Resource::TypeCollection.new("env") - loader.expects(:find).with("", "bar", :node) - loader.find_node(stub("ignored"), "bar") + loader.add(node) + loader.find_node(stub("ignored"), "bar").should == node end it "should use the 'find_or_load' method to find hostclasses" do @@ -385,53 +416,6 @@ describe Puppet::Resource::TypeCollection do end end - describe "when performing initial import" do - before do - @parser = Puppet::Parser::Parser.new("test") - Puppet::Parser::Parser.stubs(:new).returns @parser - @code = Puppet::Resource::TypeCollection.new("env") - end - - it "should set the parser's string to the 'code' setting and parse if code is available" do - Puppet.settings[:code] = "my code" - @parser.expects(:string=).with "my code" - @parser.expects(:parse) - @code.perform_initial_import - end - - it "should set the parser's file to the 'manifest' setting and parse if no code is available and the manifest is available" do - filename = tmpfile('myfile') - File.open(filename, 'w'){|f| } - Puppet.settings[:manifest] = filename - @parser.expects(:file=).with filename - @parser.expects(:parse) - @code.perform_initial_import - end - - it "should pass the manifest file to the parser even if it does not exist on disk" do - filename = tmpfile('myfile') - Puppet.settings[:code] = "" - Puppet.settings[:manifest] = filename - @parser.expects(:file=).with(filename).once - @parser.expects(:parse).once - @code.perform_initial_import - end - - it "should fail helpfully if there is an error importing" do - File.stubs(:exist?).returns true - @parser.expects(:parse).raises ArgumentError - @parser.stubs(:file=) - lambda { @code.perform_initial_import }.should raise_error(Puppet::Error) - end - - it "should mark the type collection as needing a reparse when there is an error parsing" do - @parser.expects(:parse).raises Puppet::ParseError.new("Syntax error at ...") - - lambda { @code.perform_initial_import }.should raise_error(Puppet::Error, /Syntax error at .../) - @code.require_reparse?.should be_true - end - end - describe "when determining the configuration version" do before do @code = Puppet::Resource::TypeCollection.new("env") diff --git a/spec/unit/resource/type_spec.rb b/spec/unit/resource/type_spec.rb index 87b4ab420..41b5554d9 100755 --- a/spec/unit/resource/type_spec.rb +++ b/spec/unit/resource/type_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') require 'puppet/resource/type' @@ -55,12 +55,24 @@ describe Puppet::Resource::Type do double_convert.arguments.should == {"one" => nil, "two" => "foo"} end - it "should include any extra attributes" do - @type.file = "/my/file" - @type.line = 50 + it "should not include arguments if none are present" do + @type.to_pson["arguments"].should be_nil + end + + [:line, :doc, :file, :parent].each do |attr| + it "should include #{attr} when set" do + @type.send(attr.to_s + "=", "value") + double_convert.send(attr).should == "value" + end + + it "should not include #{attr} when not set" do + @type.to_pson[attr.to_s].should be_nil + end + end - double_convert.file.should == "/my/file" - double_convert.line.should == 50 + it "should not include docs if they are empty" do + @type.doc = "" + @type.to_pson["doc"].should be_nil end end @@ -263,7 +275,7 @@ describe Puppet::Resource::Type do ['module_name', 'name', 'title'].each do |variable| it "should allow #{variable} to be evaluated as param default" do - @type.module_name = "bar" + @type.instance_eval { @module_name = "bar" } var = Puppet::Parser::AST::Variable.new({'value' => variable}) @type.set_arguments :foo => var @type.set_resource_parameters(@resource, @scope) @@ -344,7 +356,7 @@ describe Puppet::Resource::Type do end it "should set its module name in the scope if available" do - @type.module_name = "mymod" + @type.instance_eval { @module_name = "mymod" } @type.set_resource_parameters(@resource, @scope) @@ -553,8 +565,7 @@ describe Puppet::Resource::Type do @compiler.add_resource @scope, @parent_resource @type.resource_type_collection = @scope.known_resource_types - @type.resource_type_collection.stubs(:node).with("parent").returns(@parent_type) - @type.resource_type_collection.stubs(:node).with("Parent").returns(@parent_type) + @type.resource_type_collection.add(@parent_type) end it "should evaluate the parent's resource" do diff --git a/spec/unit/resource_spec.rb b/spec/unit/resource_spec.rb index 345ccd06e..916741d1a 100755 --- a/spec/unit/resource_spec.rb +++ b/spec/unit/resource_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../spec_helper') require 'puppet/resource' describe Puppet::Resource do diff --git a/spec/unit/run_spec.rb b/spec/unit/run_spec.rb index 58a16d2a6..6c5ecde65 100755 --- a/spec/unit/run_spec.rb +++ b/spec/unit/run_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../spec_helper') require 'puppet/agent' require 'puppet/run' diff --git a/spec/unit/simple_graph_spec.rb b/spec/unit/simple_graph_spec.rb index 2ca8888c5..99db2a55c 100755 --- a/spec/unit/simple_graph_spec.rb +++ b/spec/unit/simple_graph_spec.rb @@ -3,7 +3,7 @@ # Created by Luke Kanies on 2007-11-1. # Copyright (c) 2006. All rights reserved. -require File.dirname(__FILE__) + '/../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../spec_helper') require 'puppet/simple_graph' describe Puppet::SimpleGraph do @@ -31,12 +31,6 @@ describe Puppet::SimpleGraph do proc { @graph.to_dot_graph }.should_not raise_error end - it "should always put its edges first when printing yaml" do - @graph = Puppet::SimpleGraph.new - @graph.add_edge(:one, :two) - @graph.to_yaml_properties[0].should == "@edges" - end - describe "when managing vertices" do before do @graph = Puppet::SimpleGraph.new @@ -117,16 +111,31 @@ describe Puppet::SimpleGraph do @graph.edge?(:one, :two).should be_true end - it "should provide a method for retrieving an edge label" do - edge = Puppet::Relationship.new(:one, :two, :callback => :awesome) - @graph.add_edge(edge) - @graph.edge_label(:one, :two).should == {:callback => :awesome} - end + describe "when retrieving edges between two nodes" do + it "should handle the case of nodes not in the graph" do + @graph.edges_between(:one, :two).should == [] + end - it "should provide a method for retrieving an edge" do - edge = Puppet::Relationship.new(:one, :two) - @graph.add_edge(edge) - @graph.edge(:one, :two).should equal(edge) + it "should handle the case of nodes with no edges between them" do + @graph.add_vertex(:one) + @graph.add_vertex(:two) + @graph.edges_between(:one, :two).should == [] + end + + it "should handle the case of nodes connected by a single edge" do + edge = Puppet::Relationship.new(:one, :two) + @graph.add_edge(edge) + @graph.edges_between(:one, :two).length.should == 1 + @graph.edges_between(:one, :two)[0].should equal(edge) + end + + it "should handle the case of nodes connected by multiple edges" do + edge1 = Puppet::Relationship.new(:one, :two, :callback => :foo) + edge2 = Puppet::Relationship.new(:one, :two, :callback => :bar) + @graph.add_edge(edge1) + @graph.add_edge(edge2) + Set.new(@graph.edges_between(:one, :two)).should == Set.new([edge1, edge2]) + end end it "should add the edge source as a vertex if it is not already" do @@ -253,12 +262,12 @@ describe Puppet::SimpleGraph do it "should retain labels on edges" do @graph.add_edge(:one, :two, :callback => :awesome) - edge = @graph.reversal.edge(:two, :one) + edge = @graph.reversal.edges_between(:two, :one)[0] edge.label.should == {:callback => :awesome} end end - describe "when sorting the graph" do + describe "when reporting cycles in the graph" do before do @graph = Puppet::SimpleGraph.new end @@ -269,40 +278,127 @@ describe Puppet::SimpleGraph do end end - it "should sort the graph topologically" do - add_edges :a => :b, :b => :c - @graph.topsort.should == [:a, :b, :c] - end - it "should fail on two-vertex loops" do add_edges :a => :b, :b => :a - proc { @graph.topsort }.should raise_error(Puppet::Error) + proc { @graph.report_cycles_in_graph }.should raise_error(Puppet::Error) end it "should fail on multi-vertex loops" do add_edges :a => :b, :b => :c, :c => :a - proc { @graph.topsort }.should raise_error(Puppet::Error) + proc { @graph.report_cycles_in_graph }.should raise_error(Puppet::Error) end it "should fail when a larger tree contains a small cycle" do add_edges :a => :b, :b => :a, :c => :a, :d => :c - proc { @graph.topsort }.should raise_error(Puppet::Error) + proc { @graph.report_cycles_in_graph }.should raise_error(Puppet::Error) end it "should succeed on trees with no cycles" do add_edges :a => :b, :b => :e, :c => :a, :d => :c - proc { @graph.topsort }.should_not raise_error + proc { @graph.report_cycles_in_graph }.should_not raise_error end - # Our graph's add_edge method is smart enough not to add - # duplicate edges, so we use the objects, which it doesn't - # check. - it "should be able to sort graphs with duplicate edges" do - one = Puppet::Relationship.new(:a, :b) - @graph.add_edge(one) - two = Puppet::Relationship.new(:a, :b) - @graph.add_edge(two) - proc { @graph.topsort }.should_not raise_error + it "should produce the correct relationship text" do + add_edges :a => :b, :b => :a + # cycle detection starts from a or b randomly + # so we need to check for either ordering in the error message + want = %r{Found 1 dependency cycle:\n\((a => b => a|b => a => b)\)\nTry} + expect { @graph.report_cycles_in_graph }.to raise_error(Puppet::Error, want) + end + + it "cycle discovery should be the minimum cycle for a simple graph" do + add_edges "a" => "b" + add_edges "b" => "a" + add_edges "b" => "c" + + cycles = nil + expect { cycles = @graph.find_cycles_in_graph.sort }.should_not raise_error + cycles.should be == [["a", "b"]] + end + + it "cycle discovery should handle two distinct cycles" do + add_edges "a" => "a1", "a1" => "a" + add_edges "b" => "b1", "b1" => "b" + + cycles = nil + expect { cycles = @graph.find_cycles_in_graph.sort }.should_not raise_error + cycles.should be == [["a", "a1"], ["b", "b1"]] + end + + it "cycle discovery should handle two cycles in a connected graph" do + add_edges "a" => "b", "b" => "c", "c" => "d" + add_edges "a" => "a1", "a1" => "a" + add_edges "c" => "c1", "c1" => "c2", "c2" => "c3", "c3" => "c" + + cycles = nil + expect { cycles = @graph.find_cycles_in_graph.sort }.should_not raise_error + cycles.should be == [%w{a a1}, %w{c c1 c2 c3}] + end + + it "cycle discovery should handle a complicated cycle" do + add_edges "a" => "b", "b" => "c" + add_edges "a" => "c" + add_edges "c" => "c1", "c1" => "a" + add_edges "c" => "c2", "c2" => "b" + + cycles = nil + expect { cycles = @graph.find_cycles_in_graph.sort }.should_not raise_error + cycles.should be == [%w{a b c c1 c2}] + end + + it "cycle discovery should not fail with large data sets" do + limit = 3000 + (1..(limit - 1)).each do |n| add_edges n.to_s => (n+1).to_s end + + cycles = nil + expect { cycles = @graph.find_cycles_in_graph.sort }.should_not raise_error + cycles.should be == [] + end + + it "path finding should work with a simple cycle" do + add_edges "a" => "b", "b" => "c", "c" => "a" + + cycles = @graph.find_cycles_in_graph.sort + paths = @graph.paths_in_cycle(cycles.first, 100) + paths.should be == [%w{a b c a}] + end + + it "path finding should work with two independent cycles" do + add_edges "a" => "b1" + add_edges "a" => "b2" + add_edges "b1" => "a", "b2" => "a" + + cycles = @graph.find_cycles_in_graph.sort + cycles.length.should be == 1 + + paths = @graph.paths_in_cycle(cycles.first, 100) + paths.sort.should be == [%w{a b1 a}, %w{a b2 a}] + end + + it "path finding should prefer shorter paths in cycles" do + add_edges "a" => "b", "b" => "c", "c" => "a" + add_edges "b" => "a" + + cycles = @graph.find_cycles_in_graph.sort + cycles.length.should be == 1 + + paths = @graph.paths_in_cycle(cycles.first, 100) + paths.should be == [%w{a b a}, %w{a b c a}] + end + + it "path finding should respect the max_path value" do + (1..20).each do |n| add_edges "a" => "b#{n}", "b#{n}" => "a" end + + cycles = @graph.find_cycles_in_graph.sort + cycles.length.should be == 1 + + (1..20).each do |n| + paths = @graph.paths_in_cycle(cycles.first, n) + paths.length.should be == n + end + + paths = @graph.paths_in_cycle(cycles.first, 21) + paths.length.should be == 20 end end @@ -409,7 +505,7 @@ describe Puppet::SimpleGraph do require 'puppet/util/graph' - class Container + class Container < Puppet::Type::Component include Puppet::Util::Graph include Enumerable attr_accessor :name @@ -431,6 +527,7 @@ describe Puppet::SimpleGraph do end end + require "puppet/resource/catalog" describe "when splicing the graph" do def container_graph @one = Container.new("one", %w{a b}) @@ -443,13 +540,21 @@ describe Puppet::SimpleGraph do @whit = Puppet::Type.type(:whit) @stage = Puppet::Type.type(:stage).new(:name => "foo") - @contgraph = @top.to_graph + @contgraph = @top.to_graph(Puppet::Resource::Catalog.new) # We have to add the container to the main graph, else it won't # be spliced in the dependency graph. @contgraph.add_vertex(@empty) end + def containers + @contgraph.vertices.select { |x| !x.is_a? String } + end + + def contents_of(x) + @contgraph.direct_dependents_of(x) + end + def dependency_graph @depgraph = Puppet::SimpleGraph.new @contgraph.vertices.each do |v| @@ -458,13 +563,34 @@ describe Puppet::SimpleGraph do # We have to specify a relationship to our empty container, else it # never makes it into the dep graph in the first place. - {@one => @two, "f" => "c", "h" => @middle, "c" => @empty}.each do |source, target| + @explicit_dependencies = {@one => @two, "f" => "c", "h" => @middle, "c" => @empty} + @explicit_dependencies.each do |source, target| @depgraph.add_edge(source, target, :callback => :refresh) end end def splice - @depgraph.splice!(@contgraph, Container) + @contgraph.splice!(@depgraph) + end + + def whit_called(name) + x = @depgraph.vertices.find { |v| v.is_a?(@whit) && v.name =~ /#{name}/ } + x.should_not be_nil + def x.to_s + "Whit[#{name}]" + end + def x.inspect + to_s + end + x + end + + def admissible_sentinal_of(x) + @depgraph.vertex?(x) ? x : whit_called("admissible_#{x.name}") + end + + def completed_sentinal_of(x) + @depgraph.vertex?(x) ? x : whit_called("completed_#{x.name}") end before do @@ -473,63 +599,87 @@ describe Puppet::SimpleGraph do splice end - # This is the real heart of splicing -- replacing all containers in - # our relationship and exploding their relationships so that each - # relationship to a container gets copied to all of its children. + # This is the real heart of splicing -- replacing all containers X in our + # relationship graph with a pair of whits { admissible_X and completed_X } + # such that that + # + # 0) completed_X depends on admissible_X + # 1) contents of X each depend on admissible_X + # 2) completed_X depends on each on the contents of X + # 3) everything which depended on X depends on completed_X + # 4) admissible_X depends on everything X depended on + # 5) the containers and their edges must be removed + # + # Note that this requires attention to the possible case of containers + # which contain or depend on other containers. + # + # Point by point: + + # 0) completed_X depends on admissible_X + # + it "every container's completed sentinal should depend on its admissible sentinal" do + containers.each { |container| + @depgraph.path_between(admissible_sentinal_of(container),completed_sentinal_of(container)).should be + } + end + + # 1) contents of X each depend on admissible_X + # + it "all contained objects should depend on their container's admissible sentinal" do + containers.each { |container| + contents_of(container).each { |leaf| + @depgraph.should be_edge(admissible_sentinal_of(container),admissible_sentinal_of(leaf)) + } + } + end + + # 2) completed_X depends on each on the contents of X + # + it "completed sentinals should depend on their container's contents" do + containers.each { |container| + contents_of(container).each { |leaf| + @depgraph.should be_edge(completed_sentinal_of(leaf),completed_sentinal_of(container)) + } + } + end + + # + # 3) everything which depended on X depends on completed_X + + # + # 4) admissible_X depends on everything X depended on + + # 5) the containers and their edges must be removed + # it "should remove all Container objects from the dependency graph" do @depgraph.vertices.find_all { |v| v.is_a?(Container) }.should be_empty end - # This is a bit hideous, but required to make stages work with relationships - they're - # the top of the graph. it "should remove all Stage resources from the dependency graph" do @depgraph.vertices.find_all { |v| v.is_a?(Puppet::Type.type(:stage)) }.should be_empty end - it "should add container relationships to contained objects" do - @contgraph.leaves(@middle).each do |leaf| - @depgraph.should be_edge("h", leaf) - end - end - - it "should explode container-to-container relationships, making edges between all respective contained objects" do - @one.each do |oobj| - @two.each do |tobj| - @depgraph.should be_edge(oobj, tobj) - end - end - end - - it "should contain a whit-resource to mark the place held by the empty container" do - @depgraph.vertices.find_all { |v| v.is_a?(@whit) }.length.should == 1 - end - - it "should replace edges to empty containers with edges to their residual whit" do - emptys_whit = @depgraph.vertices.find_all { |v| v.is_a?(@whit) }.first - @depgraph.should be_edge("c", emptys_whit) - end - it "should no longer contain anything but the non-container objects" do @depgraph.vertices.find_all { |v| ! v.is_a?(String) and ! v.is_a?(@whit)}.should be_empty end - it "should copy labels" do - @depgraph.edges.each do |edge| - edge.label.should == {:callback => :refresh} - end + it "should retain labels on non-containment edges" do + @explicit_dependencies.each { |f,t| + @depgraph.edges_between(completed_sentinal_of(f),admissible_sentinal_of(t))[0].label.should == {:callback => :refresh} + } end it "should not add labels to edges that have none" do @depgraph.add_edge(@two, @three) splice - @depgraph.edge_label("c", "i").should == {} + @depgraph.path_between("c", "i").any? {|segment| segment.all? {|e| e.label == {} }}.should be end it "should copy labels over edges that have none" do @depgraph.add_edge("c", @three, {:callback => :refresh}) splice # And make sure the label got copied. - @depgraph.edge_label("c", "i").should == {:callback => :refresh} + @depgraph.path_between("c", "i").flatten.select {|e| e.label == {:callback => :refresh} }.should_not be_empty end it "should not replace a label with a nil label" do @@ -537,7 +687,7 @@ describe Puppet::SimpleGraph do @depgraph.add_edge(@middle, @three) @depgraph.add_edge("c", @three, {:callback => :refresh}) splice - @depgraph.edge_label("c", "i").should == {:callback => :refresh} + @depgraph.path_between("c","i").flatten.select {|e| e.label == {:callback => :refresh} }.should_not be_empty end it "should copy labels to all created edges" do @@ -546,9 +696,209 @@ describe Puppet::SimpleGraph do splice @three.each do |child| edge = Puppet::Relationship.new("c", child) - @depgraph.should be_edge(edge.source, edge.target) - @depgraph.edge_label(edge.source, edge.target).should == {:callback => :refresh} + (path = @depgraph.path_between(edge.source, edge.target)).should be + path.should_not be_empty + path.flatten.select {|e| e.label == {:callback => :refresh} }.should_not be_empty + end + end + end + + it "should serialize to YAML using the old format by default" do + Puppet::SimpleGraph.use_new_yaml_format.should == false + end + + describe "(yaml tests)" do + def empty_graph(graph) + end + + def one_vertex_graph(graph) + graph.add_vertex(:a) + end + + def graph_without_edges(graph) + [:a, :b, :c].each { |x| graph.add_vertex(x) } + end + + def one_edge_graph(graph) + graph.add_edge(:a, :b) + end + + def many_edge_graph(graph) + graph.add_edge(:a, :b) + graph.add_edge(:a, :c) + graph.add_edge(:b, :d) + graph.add_edge(:c, :d) + end + + def labeled_edge_graph(graph) + graph.add_edge(:a, :b, :callback => :foo, :event => :bar) + end + + def overlapping_edge_graph(graph) + graph.add_edge(:a, :b, :callback => :foo, :event => :bar) + graph.add_edge(:a, :b, :callback => :biz, :event => :baz) + end + + def self.all_test_graphs + [:empty_graph, :one_vertex_graph, :graph_without_edges, :one_edge_graph, :many_edge_graph, :labeled_edge_graph, + :overlapping_edge_graph] + end + + def object_ids(enumerable) + # Return a sorted list of the object id's of the elements of an + # enumerable. + enumerable.collect { |x| x.object_id }.sort + end + + def graph_to_yaml(graph, which_format) + previous_use_new_yaml_format = Puppet::SimpleGraph.use_new_yaml_format + Puppet::SimpleGraph.use_new_yaml_format = (which_format == :new) + ZAML.dump(graph) + ensure + Puppet::SimpleGraph.use_new_yaml_format = previous_use_new_yaml_format + end + + # Test serialization of graph to YAML. + [:old, :new].each do |which_format| + all_test_graphs.each do |graph_to_test| + it "should be able to serialize #{graph_to_test} to YAML (#{which_format} format)" do + graph = Puppet::SimpleGraph.new + send(graph_to_test, graph) + yaml_form = graph_to_yaml(graph, which_format) + + # Hack the YAML so that objects in the Puppet namespace get + # changed to YAML::DomainType objects. This lets us inspect + # the serialized objects easily without invoking any + # yaml_initialize hooks. + yaml_form.gsub!('!ruby/object:Puppet::', '!hack/object:Puppet::') + serialized_object = YAML.load(yaml_form) + + # Check that the object contains instance variables @edges and + # @vertices only. @reversal is also permitted, but we don't + # check it, because it is going to be phased out. + serialized_object.type_id.should == 'object:Puppet::SimpleGraph' + serialized_object.value.keys.reject { |x| x == 'reversal' }.sort.should == ['edges', 'vertices'] + + # Check edges by forming a set of tuples (source, target, + # callback, event) based on the graph and the YAML and make sure + # they match. + edges = serialized_object.value['edges'] + edges.should be_a(Array) + expected_edge_tuples = graph.edges.collect { |edge| [edge.source, edge.target, edge.callback, edge.event] } + actual_edge_tuples = edges.collect do |edge| + edge.type_id.should == 'object:Puppet::Relationship' + %w{source target}.each { |x| edge.value.keys.should include(x) } + edge.value.keys.each { |x| ['source', 'target', 'callback', 'event'].should include(x) } + %w{source target callback event}.collect { |x| edge.value[x] } + end + Set.new(actual_edge_tuples).should == Set.new(expected_edge_tuples) + actual_edge_tuples.length.should == expected_edge_tuples.length + + # Check vertices one by one. + vertices = serialized_object.value['vertices'] + if which_format == :old + vertices.should be_a(Hash) + Set.new(vertices.keys).should == Set.new(graph.vertices) + vertices.each do |key, value| + value.type_id.should == 'object:Puppet::SimpleGraph::VertexWrapper' + value.value.keys.sort.should == %w{adjacencies vertex} + value.value['vertex'].should equal(key) + adjacencies = value.value['adjacencies'] + adjacencies.should be_a(Hash) + Set.new(adjacencies.keys).should == Set.new([:in, :out]) + [:in, :out].each do |direction| + adjacencies[direction].should be_a(Hash) + expected_adjacent_vertices = Set.new(graph.adjacent(key, :direction => direction, :type => :vertices)) + Set.new(adjacencies[direction].keys).should == expected_adjacent_vertices + adjacencies[direction].each do |adj_key, adj_value| + # Since we already checked edges, just check consistency + # with edges. + desired_source = direction == :in ? adj_key : key + desired_target = direction == :in ? key : adj_key + expected_edges = edges.select do |edge| + edge.value['source'] == desired_source && edge.value['target'] == desired_target + end + adj_value.should be_a(Set) + if object_ids(adj_value) != object_ids(expected_edges) + raise "For vertex #{key.inspect}, direction #{direction.inspect}: expected adjacencies #{expected_edges.inspect} but got #{adj_value.inspect}" + end + end + end + end + else + vertices.should be_a(Array) + Set.new(vertices).should == Set.new(graph.vertices) + vertices.length.should == graph.vertices.length + end + end + end + + # Test deserialization of graph from YAML. This presumes the + # correctness of serialization to YAML, which has already been + # tested. + all_test_graphs.each do |graph_to_test| + it "should be able to deserialize #{graph_to_test} from YAML (#{which_format} format)" do + reference_graph = Puppet::SimpleGraph.new + send(graph_to_test, reference_graph) + yaml_form = graph_to_yaml(reference_graph, which_format) + recovered_graph = YAML.load(yaml_form) + + # Test that the recovered vertices match the vertices in the + # reference graph. + expected_vertices = reference_graph.vertices.to_a + recovered_vertices = recovered_graph.vertices.to_a + Set.new(recovered_vertices).should == Set.new(expected_vertices) + recovered_vertices.length.should == expected_vertices.length + + # Test that the recovered edges match the edges in the + # reference graph. + expected_edge_tuples = reference_graph.edges.collect do |edge| + [edge.source, edge.target, edge.callback, edge.event] + end + recovered_edge_tuples = recovered_graph.edges.collect do |edge| + [edge.source, edge.target, edge.callback, edge.event] + end + Set.new(recovered_edge_tuples).should == Set.new(expected_edge_tuples) + recovered_edge_tuples.length.should == expected_edge_tuples.length + + # We ought to test that the recovered graph is self-consistent + # too. But we're not going to bother with that yet because + # the internal representation of the graph is about to change. + end + end + + it "should be able to serialize a graph where the vertices contain backreferences to the graph (#{which_format} format)" do + reference_graph = Puppet::SimpleGraph.new + vertex = Object.new + vertex.instance_eval { @graph = reference_graph } + reference_graph.add_edge(vertex, :other_vertex) + yaml_form = graph_to_yaml(reference_graph, which_format) + recovered_graph = YAML.load(yaml_form) + + recovered_graph.vertices.length.should == 2 + recovered_vertex = recovered_graph.vertices.reject { |x| x.is_a?(Symbol) }[0] + recovered_vertex.instance_eval { @graph }.should equal(recovered_graph) + recovered_graph.edges.length.should == 1 + recovered_edge = recovered_graph.edges[0] + recovered_edge.source.should equal(recovered_vertex) + recovered_edge.target.should == :other_vertex + end + end + + it "should serialize properly when used as a base class" do + class Puppet::TestDerivedClass < Puppet::SimpleGraph + attr_accessor :foo end + derived = Puppet::TestDerivedClass.new + derived.add_edge(:a, :b) + derived.foo = 1234 + recovered_derived = YAML.load(YAML.dump(derived)) + recovered_derived.class.should equal(Puppet::TestDerivedClass) + recovered_derived.edges.length.should == 1 + recovered_derived.edges[0].source.should == :a + recovered_derived.edges[0].target.should == :b + recovered_derived.vertices.length.should == 2 + recovered_derived.foo.should == 1234 end end end diff --git a/spec/unit/ssl/base_spec.rb b/spec/unit/ssl/base_spec.rb index 47575feab..99038391f 100755 --- a/spec/unit/ssl/base_spec.rb +++ b/spec/unit/ssl/base_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') require 'puppet/ssl/certificate' diff --git a/spec/unit/ssl/certificate_authority/interface_spec.rb b/spec/unit/ssl/certificate_authority/interface_spec.rb index 5cf4073df..2e4a3fc77 100755 --- a/spec/unit/ssl/certificate_authority/interface_spec.rb +++ b/spec/unit/ssl/certificate_authority/interface_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') require 'puppet/ssl/certificate_authority' diff --git a/spec/unit/ssl/certificate_authority_spec.rb b/spec/unit/ssl/certificate_authority_spec.rb index 39fee3f0a..76633b48f 100755 --- a/spec/unit/ssl/certificate_authority_spec.rb +++ b/spec/unit/ssl/certificate_authority_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') require 'puppet/ssl/certificate_authority' @@ -138,18 +138,18 @@ describe Puppet::SSL::CertificateAuthority do it "should return any found CRL instance" do crl = mock 'crl' - Puppet::SSL::CertificateRevocationList.expects(:find).returns crl + Puppet::SSL::CertificateRevocationList.indirection.expects(:find).returns crl @ca.crl.should equal(crl) end it "should create, generate, and save a new CRL instance of no CRL can be found" do - crl = mock 'crl' - Puppet::SSL::CertificateRevocationList.expects(:find).returns nil + crl = Puppet::SSL::CertificateRevocationList.new("fakename") + Puppet::SSL::CertificateRevocationList.indirection.expects(:find).returns nil Puppet::SSL::CertificateRevocationList.expects(:new).returns crl crl.expects(:generate).with(@ca.host.certificate.content, @ca.host.key.content) - crl.expects(:save) + Puppet::SSL::CertificateRevocationList.indirection.expects(:save).with(crl) @ca.crl.should equal(crl) end @@ -235,12 +235,13 @@ describe Puppet::SSL::CertificateAuthority do @name = "myhost" @real_cert = stub 'realcert', :sign => nil - @cert = stub 'certificate', :content => @real_cert + @cert = Puppet::SSL::Certificate.new(@name) + @cert.content = @real_cert Puppet::SSL::Certificate.stubs(:new).returns @cert @cert.stubs(:content=) - @cert.stubs(:save) + Puppet::SSL::Certificate.indirection.stubs(:save) # Stub out the factory @factory = stub 'factory', :result => "my real cert" @@ -252,7 +253,7 @@ describe Puppet::SSL::CertificateAuthority do @inventory = stub 'inventory', :add => nil @ca.stubs(:inventory).returns @inventory - Puppet::SSL::CertificateRequest.stubs(:destroy) + Puppet::SSL::CertificateRequest.indirection.stubs(:destroy) end describe "and calculating the next certificate serial number" do @@ -295,7 +296,7 @@ describe Puppet::SSL::CertificateAuthority do end it "should not look up a certificate request for the host" do - Puppet::SSL::CertificateRequest.expects(:find).never + Puppet::SSL::CertificateRequest.indirection.expects(:find).never @ca.sign(@name, :ca, @request) end @@ -329,7 +330,7 @@ describe Puppet::SSL::CertificateAuthority do end it "should save the resulting certificate" do - @cert.expects(:save) + Puppet::SSL::Certificate.indirection.expects(:save).with(@cert) @ca.sign(@name, :ca, @request) end @@ -340,8 +341,8 @@ describe Puppet::SSL::CertificateAuthority do @serial = 10 @ca.stubs(:next_serial).returns @serial - Puppet::SSL::CertificateRequest.stubs(:find).with(@name).returns @request - @cert.stubs :save + Puppet::SSL::CertificateRequest.indirection.stubs(:find).with(@name).returns @request + Puppet::SSL::CertificateRequest.indirection.stubs :save end it "should use a certificate type of :server" do @@ -353,13 +354,13 @@ describe Puppet::SSL::CertificateAuthority do end it "should use look up a CSR for the host in the :ca_file terminus" do - Puppet::SSL::CertificateRequest.expects(:find).with(@name).returns @request + Puppet::SSL::CertificateRequest.indirection.expects(:find).with(@name).returns @request @ca.sign(@name) end it "should fail if no CSR can be found for the host" do - Puppet::SSL::CertificateRequest.expects(:find).with(@name).returns nil + Puppet::SSL::CertificateRequest.indirection.expects(:find).with(@name).returns nil lambda { @ca.sign(@name) }.should raise_error(ArgumentError) end @@ -390,12 +391,12 @@ describe Puppet::SSL::CertificateAuthority do end it "should save the resulting certificate" do - @cert.expects(:save) + Puppet::SSL::Certificate.indirection.stubs(:save).with(@cert) @ca.sign(@name) end it "should remove the host's certificate request" do - Puppet::SSL::CertificateRequest.expects(:destroy).with(@name) + Puppet::SSL::CertificateRequest.indirection.expects(:destroy).with(@name) @ca.sign(@name) end @@ -405,8 +406,8 @@ describe Puppet::SSL::CertificateAuthority do @serial = 10 @ca.stubs(:next_serial).returns @serial - Puppet::SSL::CertificateRequest.stubs(:find).with(@name).returns @request - @cert.stubs :save + Puppet::SSL::CertificateRequest.indirection.stubs(:find).with(@name).returns @request + Puppet::SSL::Certificate.indirection.stubs :save Puppet::SSL::Certificate.expects(:new).with(@name).returns @cert @ca.sign(@name) @@ -414,8 +415,8 @@ describe Puppet::SSL::CertificateAuthority do it "should return the certificate instance" do @ca.stubs(:next_serial).returns @serial - Puppet::SSL::CertificateRequest.stubs(:find).with(@name).returns @request - @cert.stubs :save + Puppet::SSL::CertificateRequest.indirection.stubs(:find).with(@name).returns @request + Puppet::SSL::Certificate.indirection.stubs :save @ca.sign(@name).should equal(@cert) end @@ -423,8 +424,8 @@ describe Puppet::SSL::CertificateAuthority do @ca.stubs(:next_serial).returns @serial @inventory.expects(:add).with(@cert) - Puppet::SSL::CertificateRequest.stubs(:find).with(@name).returns @request - @cert.stubs :save + Puppet::SSL::CertificateRequest.indirection.stubs(:find).with(@name).returns @request + Puppet::SSL::Certificate.indirection.stubs :save @ca.sign(@name) end @@ -436,7 +437,7 @@ describe Puppet::SSL::CertificateAuthority do it "should do nothing if autosign is disabled" do Puppet.settings.expects(:value).with(:autosign).returns 'false' - Puppet::SSL::CertificateRequest.expects(:search).never + Puppet::SSL::CertificateRequest.indirection.expects(:search).never @ca.autosign end @@ -444,7 +445,7 @@ describe Puppet::SSL::CertificateAuthority do Puppet.settings.expects(:value).with(:autosign).returns '/auto/sign' FileTest.expects(:exist?).with("/auto/sign").returns false - Puppet::SSL::CertificateRequest.expects(:search).never + Puppet::SSL::CertificateRequest.indirection.expects(:search).never @ca.autosign end @@ -454,7 +455,7 @@ describe Puppet::SSL::CertificateAuthority do FileTest.stubs(:exist?).with("/auto/sign").returns true File.stubs(:readlines).with("/auto/sign").returns ["one\n", "two\n"] - Puppet::SSL::CertificateRequest.stubs(:search).returns [] + Puppet::SSL::CertificateRequest.indirection.stubs(:search).returns [] @store = stub 'store', :allow => nil Puppet::Network::AuthStore.stubs(:new).returns @store @@ -495,13 +496,13 @@ describe Puppet::SSL::CertificateAuthority do it "should sign all CSRs whose hostname matches the autosign configuration" do csr1 = mock 'csr1' csr2 = mock 'csr2' - Puppet::SSL::CertificateRequest.stubs(:search).returns [csr1, csr2] + Puppet::SSL::CertificateRequest.indirection.stubs(:search).returns [csr1, csr2] end it "should not sign CSRs whose hostname does not match the autosign configuration" do csr1 = mock 'csr1' csr2 = mock 'csr2' - Puppet::SSL::CertificateRequest.stubs(:search).returns [csr1, csr2] + Puppet::SSL::CertificateRequest.indirection.stubs(:search).returns [csr1, csr2] end end end @@ -548,7 +549,7 @@ describe Puppet::SSL::CertificateAuthority do it "should be able to list waiting certificate requests" do req1 = stub 'req1', :name => "one" req2 = stub 'req2', :name => "two" - Puppet::SSL::CertificateRequest.expects(:search).with("*").returns [req1, req2] + Puppet::SSL::CertificateRequest.indirection.expects(:search).with("*").returns [req1, req2] @ca.waiting?.should == %w{one two} end @@ -566,19 +567,19 @@ describe Puppet::SSL::CertificateAuthority do it "should list certificates as the sorted list of all existing signed certificates" do cert1 = stub 'cert1', :name => "cert1" cert2 = stub 'cert2', :name => "cert2" - Puppet::SSL::Certificate.expects(:search).with("*").returns [cert1, cert2] + Puppet::SSL::Certificate.indirection.expects(:search).with("*").returns [cert1, cert2] @ca.list.should == %w{cert1 cert2} end describe "and printing certificates" do it "should return nil if the certificate cannot be found" do - Puppet::SSL::Certificate.expects(:find).with("myhost").returns nil + Puppet::SSL::Certificate.indirection.expects(:find).with("myhost").returns nil @ca.print("myhost").should be_nil end it "should print certificates by calling :to_text on the host's certificate" do cert1 = stub 'cert1', :name => "cert1", :to_text => "mytext" - Puppet::SSL::Certificate.expects(:find).with("myhost").returns cert1 + Puppet::SSL::Certificate.indirection.expects(:find).with("myhost").returns cert1 @ca.print("myhost").should == "mytext" end end @@ -586,19 +587,19 @@ describe Puppet::SSL::CertificateAuthority do describe "and fingerprinting certificates" do before :each do @cert = stub 'cert', :name => "cert", :fingerprint => "DIGEST" - Puppet::SSL::Certificate.stubs(:find).with("myhost").returns @cert - Puppet::SSL::CertificateRequest.stubs(:find).with("myhost") + Puppet::SSL::Certificate.indirection.stubs(:find).with("myhost").returns @cert + Puppet::SSL::CertificateRequest.indirection.stubs(:find).with("myhost") end it "should raise an error if the certificate or CSR cannot be found" do - Puppet::SSL::Certificate.expects(:find).with("myhost").returns nil - Puppet::SSL::CertificateRequest.expects(:find).with("myhost").returns nil + Puppet::SSL::Certificate.indirection.expects(:find).with("myhost").returns nil + Puppet::SSL::CertificateRequest.indirection.expects(:find).with("myhost").returns nil lambda { @ca.fingerprint("myhost") }.should raise_error end it "should try to find a CSR if no certificate can be found" do - Puppet::SSL::Certificate.expects(:find).with("myhost").returns nil - Puppet::SSL::CertificateRequest.expects(:find).with("myhost").returns @cert + Puppet::SSL::Certificate.indirection.expects(:find).with("myhost").returns nil + Puppet::SSL::CertificateRequest.indirection.expects(:find).with("myhost").returns @cert @cert.expects(:fingerprint) @ca.fingerprint("myhost") end @@ -623,7 +624,7 @@ describe Puppet::SSL::CertificateAuthority do Puppet.settings.stubs(:value).returns "crtstuff" @cert = stub 'cert', :content => "mycert" - Puppet::SSL::Certificate.stubs(:find).returns @cert + Puppet::SSL::Certificate.indirection.stubs(:find).returns @cert @crl = stub('crl', :content => "mycrl") @@ -631,7 +632,7 @@ describe Puppet::SSL::CertificateAuthority do end it "should fail if the host's certificate cannot be found" do - Puppet::SSL::Certificate.expects(:find).with("me").returns(nil) + Puppet::SSL::Certificate.indirection.expects(:find).with("me").returns(nil) lambda { @ca.verify("me") }.should raise_error(ArgumentError) end @@ -694,7 +695,7 @@ describe Puppet::SSL::CertificateAuthority do @real_cert = stub 'real_cert', :serial => 15 @cert = stub 'cert', :content => @real_cert - Puppet::SSL::Certificate.stubs(:find).returns @cert + Puppet::SSL::Certificate.indirection.stubs(:find).returns @cert end @@ -714,7 +715,7 @@ describe Puppet::SSL::CertificateAuthority do it "should get the serial number from the local certificate if it exists" do @ca.crl.expects(:revoke).with { |serial, key| serial == 15 } - Puppet::SSL::Certificate.expects(:find).with("host").returns @cert + Puppet::SSL::Certificate.indirection.expects(:find).with("host").returns @cert @ca.revoke('host') end @@ -722,7 +723,7 @@ describe Puppet::SSL::CertificateAuthority do it "should get the serial number from inventory if no local certificate exists" do real_cert = stub 'real_cert', :serial => 15 cert = stub 'cert', :content => real_cert - Puppet::SSL::Certificate.expects(:find).with("host").returns nil + Puppet::SSL::Certificate.indirection.expects(:find).with("host").returns nil @ca.inventory.expects(:serial).with("host").returns 16 @@ -739,13 +740,13 @@ describe Puppet::SSL::CertificateAuthority do before do @host = stub 'host', :generate_certificate_request => nil Puppet::SSL::Host.stubs(:new).returns @host - Puppet::SSL::Certificate.stubs(:find).returns nil + Puppet::SSL::Certificate.indirection.stubs(:find).returns nil @ca.stubs(:sign) end it "should fail if a certificate already exists for the host" do - Puppet::SSL::Certificate.expects(:find).with("him").returns "something" + Puppet::SSL::Certificate.indirection.expects(:find).with("him").returns "something" lambda { @ca.generate("him") }.should raise_error(ArgumentError) end diff --git a/spec/unit/ssl/certificate_factory_spec.rb b/spec/unit/ssl/certificate_factory_spec.rb index de2093810..c2bcb19ce 100755 --- a/spec/unit/ssl/certificate_factory_spec.rb +++ b/spec/unit/ssl/certificate_factory_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') require 'puppet/ssl/certificate_factory' diff --git a/spec/unit/ssl/certificate_request_spec.rb b/spec/unit/ssl/certificate_request_spec.rb index 437fc0556..32c9cb51d 100755 --- a/spec/unit/ssl/certificate_request_spec.rb +++ b/spec/unit/ssl/certificate_request_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') require 'puppet/ssl/certificate_request' require 'puppet/ssl/key' @@ -187,22 +187,17 @@ describe Puppet::SSL::CertificateRequest do end describe "when a CSR is saved" do - it "should allow arguments" do - csr = Puppet::SSL::CertificateRequest.new("me") - csr.class.indirection.stubs(:save) - - lambda { csr.save :ipaddress => "foo" }.should_not raise_error - end - describe "and a CA is available" do it "should save the CSR and trigger autosigning" do ca = mock 'ca', :autosign Puppet::SSL::CertificateAuthority.expects(:instance).returns ca csr = Puppet::SSL::CertificateRequest.new("me") - Puppet::SSL::CertificateRequest.indirection.expects(:save).with(nil, csr) + terminus = mock 'terminus' + Puppet::SSL::CertificateRequest.indirection.expects(:prepare).returns(terminus) + terminus.expects(:save).with { |request| request.instance == csr && request.key == "me" } - csr.save + Puppet::SSL::CertificateRequest.indirection.save(csr) end end @@ -211,9 +206,11 @@ describe Puppet::SSL::CertificateRequest do Puppet::SSL::CertificateAuthority.expects(:instance).returns nil csr = Puppet::SSL::CertificateRequest.new("me") - Puppet::SSL::CertificateRequest.indirection.expects(:save).with(nil, csr) + terminus = mock 'terminus' + Puppet::SSL::CertificateRequest.indirection.expects(:prepare).returns(terminus) + terminus.expects(:save).with { |request| request.instance == csr && request.key == "me" } - csr.save + Puppet::SSL::CertificateRequest.indirection.save(csr) end end end diff --git a/spec/unit/ssl/certificate_revocation_list_spec.rb b/spec/unit/ssl/certificate_revocation_list_spec.rb index f9993d52e..e83ad9cc5 100755 --- a/spec/unit/ssl/certificate_revocation_list_spec.rb +++ b/spec/unit/ssl/certificate_revocation_list_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') require 'puppet/ssl/certificate_revocation_list' @@ -119,7 +119,7 @@ describe Puppet::SSL::CertificateRevocationList do @crl.generate(@cert, @key) @crl.content.stubs(:sign) - @crl.stubs :save + Puppet::SSL::CertificateRevocationList.indirection.stubs :save @key = mock 'key' end @@ -161,7 +161,7 @@ describe Puppet::SSL::CertificateRevocationList do end it "should save the CRL" do - @crl.expects :save + Puppet::SSL::CertificateRevocationList.indirection.expects(:save).with(@crl, nil) @crl.revoke(1, @key) end end diff --git a/spec/unit/ssl/certificate_spec.rb b/spec/unit/ssl/certificate_spec.rb index 842aa35c5..b3af9f236 100755 --- a/spec/unit/ssl/certificate_spec.rb +++ b/spec/unit/ssl/certificate_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') require 'puppet/ssl/certificate' diff --git a/spec/unit/ssl/host_spec.rb b/spec/unit/ssl/host_spec.rb index b2e43393c..885bd45e2 100755 --- a/spec/unit/ssl/host_spec.rb +++ b/spec/unit/ssl/host_spec.rb @@ -1,18 +1,21 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') require 'puppet/ssl/host' +require 'puppet/sslcertificates' +require 'puppet/sslcertificates/ca' describe Puppet::SSL::Host do before do - @class = Puppet::SSL::Host - @host = @class.new("myname") + Puppet::SSL::Host.indirection.terminus_class = :file + @host = Puppet::SSL::Host.new("myname") end after do # Cleaned out any cached localhost instance. Puppet::Util::Cacher.expire + Puppet::SSL::Host.ca_location = :none end it "should use any provided name as its name" do @@ -22,7 +25,7 @@ describe Puppet::SSL::Host do it "should retrieve its public key from its private key" do realkey = mock 'realkey' key = stub 'key', :content => realkey - Puppet::SSL::Key.stubs(:find).returns(key) + Puppet::SSL::Key.indirection.stubs(:find).returns(key) pubkey = mock 'public_key' realkey.expects(:public_key).returns pubkey @@ -140,13 +143,6 @@ describe Puppet::SSL::Host do end describe "when specifying the CA location" do - before do - [Puppet::SSL::Key, Puppet::SSL::Certificate, Puppet::SSL::CertificateRequest, Puppet::SSL::CertificateRevocationList].each do |klass| - klass.stubs(:terminus_class=) - klass.stubs(:cache_class=) - end - end - it "should support the location ':local'" do lambda { Puppet::SSL::Host.ca_location = :local }.should_not raise_error end @@ -168,80 +164,88 @@ describe Puppet::SSL::Host do end describe "as 'local'" do - it "should set the cache class for Certificate, CertificateRevocationList, and CertificateRequest as :file" do - Puppet::SSL::Certificate.expects(:cache_class=).with :file - Puppet::SSL::CertificateRequest.expects(:cache_class=).with :file - Puppet::SSL::CertificateRevocationList.expects(:cache_class=).with :file - + before do Puppet::SSL::Host.ca_location = :local end - it "should set the terminus class for Key as :file" do - Puppet::SSL::Key.expects(:terminus_class=).with :file + it "should set the cache class for Certificate, CertificateRevocationList, and CertificateRequest as :file" do + Puppet::SSL::Certificate.indirection.cache_class.should == :file + Puppet::SSL::CertificateRequest.indirection.cache_class.should == :file + Puppet::SSL::CertificateRevocationList.indirection.cache_class.should == :file + end - Puppet::SSL::Host.ca_location = :local + it "should set the terminus class for Key and Host as :file" do + Puppet::SSL::Key.indirection.terminus_class.should == :file + Puppet::SSL::Host.indirection.terminus_class.should == :file end it "should set the terminus class for Certificate, CertificateRevocationList, and CertificateRequest as :ca" do - Puppet::SSL::Certificate.expects(:terminus_class=).with :ca - Puppet::SSL::CertificateRequest.expects(:terminus_class=).with :ca - Puppet::SSL::CertificateRevocationList.expects(:terminus_class=).with :ca - - Puppet::SSL::Host.ca_location = :local + Puppet::SSL::Certificate.indirection.terminus_class.should == :ca + Puppet::SSL::CertificateRequest.indirection.terminus_class.should == :ca + Puppet::SSL::CertificateRevocationList.indirection.terminus_class.should == :ca end end describe "as 'remote'" do - it "should set the cache class for Certificate, CertificateRevocationList, and CertificateRequest as :file" do - Puppet::SSL::Certificate.expects(:cache_class=).with :file - Puppet::SSL::CertificateRequest.expects(:cache_class=).with :file - Puppet::SSL::CertificateRevocationList.expects(:cache_class=).with :file - + before do Puppet::SSL::Host.ca_location = :remote end - it "should set the terminus class for Key as :file" do - Puppet::SSL::Key.expects(:terminus_class=).with :file - - Puppet::SSL::Host.ca_location = :remote + it "should set the cache class for Certificate, CertificateRevocationList, and CertificateRequest as :file" do + Puppet::SSL::Certificate.indirection.cache_class.should == :file + Puppet::SSL::CertificateRequest.indirection.cache_class.should == :file + Puppet::SSL::CertificateRevocationList.indirection.cache_class.should == :file end - it "should set the terminus class for Certificate, CertificateRevocationList, and CertificateRequest as :rest" do - Puppet::SSL::Certificate.expects(:terminus_class=).with :rest - Puppet::SSL::CertificateRequest.expects(:terminus_class=).with :rest - Puppet::SSL::CertificateRevocationList.expects(:terminus_class=).with :rest + it "should set the terminus class for Key as :file" do + Puppet::SSL::Key.indirection.terminus_class.should == :file + end - Puppet::SSL::Host.ca_location = :remote + it "should set the terminus class for Host, Certificate, CertificateRevocationList, and CertificateRequest as :rest" do + Puppet::SSL::Host.indirection.terminus_class.should == :rest + Puppet::SSL::Certificate.indirection.terminus_class.should == :rest + Puppet::SSL::CertificateRequest.indirection.terminus_class.should == :rest + Puppet::SSL::CertificateRevocationList.indirection.terminus_class.should == :rest end end describe "as 'only'" do - it "should set the terminus class for Key, Certificate, CertificateRevocationList, and CertificateRequest as :ca" do - Puppet::SSL::Key.expects(:terminus_class=).with :ca - Puppet::SSL::Certificate.expects(:terminus_class=).with :ca - Puppet::SSL::CertificateRequest.expects(:terminus_class=).with :ca - Puppet::SSL::CertificateRevocationList.expects(:terminus_class=).with :ca - + before do Puppet::SSL::Host.ca_location = :only end - it "should reset the cache class for Certificate, CertificateRevocationList, and CertificateRequest to nil" do - Puppet::SSL::Certificate.expects(:cache_class=).with nil - Puppet::SSL::CertificateRequest.expects(:cache_class=).with nil - Puppet::SSL::CertificateRevocationList.expects(:cache_class=).with nil + it "should set the terminus class for Key, Certificate, CertificateRevocationList, and CertificateRequest as :ca" do + Puppet::SSL::Key.indirection.terminus_class.should == :ca + Puppet::SSL::Certificate.indirection.terminus_class.should == :ca + Puppet::SSL::CertificateRequest.indirection.terminus_class.should == :ca + Puppet::SSL::CertificateRevocationList.indirection.terminus_class.should == :ca + end - Puppet::SSL::Host.ca_location = :only + it "should set the cache class for Certificate, CertificateRevocationList, and CertificateRequest to nil" do + Puppet::SSL::Certificate.indirection.cache_class.should be_nil + Puppet::SSL::CertificateRequest.indirection.cache_class.should be_nil + Puppet::SSL::CertificateRevocationList.indirection.cache_class.should be_nil + end + + it "should set the terminus class for Host to :file" do + Puppet::SSL::Host.indirection.terminus_class.should == :file end end describe "as 'none'" do + before do + Puppet::SSL::Host.ca_location = :none + end + it "should set the terminus class for Key, Certificate, CertificateRevocationList, and CertificateRequest as :file" do - Puppet::SSL::Key.expects(:terminus_class=).with :file - Puppet::SSL::Certificate.expects(:terminus_class=).with :file - Puppet::SSL::CertificateRequest.expects(:terminus_class=).with :file - Puppet::SSL::CertificateRevocationList.expects(:terminus_class=).with :file + Puppet::SSL::Key.indirection.terminus_class.should == :file + Puppet::SSL::Certificate.indirection.terminus_class.should == :file + Puppet::SSL::CertificateRequest.indirection.terminus_class.should == :file + Puppet::SSL::CertificateRevocationList.indirection.terminus_class.should == :file + end - Puppet::SSL::Host.ca_location = :none + it "should set the terminus class for Host to 'none'" do + lambda { Puppet::SSL::Host.indirection.terminus_class }.should raise_error(Puppet::DevError) end end end @@ -252,27 +256,27 @@ describe Puppet::SSL::Host do describe "when destroying a host's SSL files" do before do - Puppet::SSL::Key.stubs(:destroy).returns false - Puppet::SSL::Certificate.stubs(:destroy).returns false - Puppet::SSL::CertificateRequest.stubs(:destroy).returns false + Puppet::SSL::Key.indirection.stubs(:destroy).returns false + Puppet::SSL::Certificate.indirection.stubs(:destroy).returns false + Puppet::SSL::CertificateRequest.indirection.stubs(:destroy).returns false end it "should destroy its certificate, certificate request, and key" do - Puppet::SSL::Key.expects(:destroy).with("myhost") - Puppet::SSL::Certificate.expects(:destroy).with("myhost") - Puppet::SSL::CertificateRequest.expects(:destroy).with("myhost") + Puppet::SSL::Key.indirection.expects(:destroy).with("myhost") + Puppet::SSL::Certificate.indirection.expects(:destroy).with("myhost") + Puppet::SSL::CertificateRequest.indirection.expects(:destroy).with("myhost") Puppet::SSL::Host.destroy("myhost") end it "should return true if any of the classes returned true" do - Puppet::SSL::Certificate.expects(:destroy).with("myhost").returns true + Puppet::SSL::Certificate.indirection.expects(:destroy).with("myhost").returns true Puppet::SSL::Host.destroy("myhost").should be_true end - it "should return false if none of the classes returned true" do - Puppet::SSL::Host.destroy("myhost").should be_false + it "should report that nothing was deleted if none of the classes returned true" do + Puppet::SSL::Host.destroy("myhost").should == "Nothing was deleted" end end @@ -301,16 +305,17 @@ describe Puppet::SSL::Host do describe "when managing its private key" do before do @realkey = "mykey" - @key = stub 'key', :content => @realkey + @key = Puppet::SSL::Key.new("mykey") + @key.content = @realkey end it "should return nil if the key is not set and cannot be found" do - Puppet::SSL::Key.expects(:find).with("myname").returns(nil) + Puppet::SSL::Key.indirection.expects(:find).with("myname").returns(nil) @host.key.should be_nil end it "should find the key in the Key class and return the Puppet instance" do - Puppet::SSL::Key.expects(:find).with("myname").returns(@key) + Puppet::SSL::Key.indirection.expects(:find).with("myname").returns(@key) @host.key.should equal(@key) end @@ -318,7 +323,7 @@ describe Puppet::SSL::Host do Puppet::SSL::Key.expects(:new).with("myname").returns(@key) @key.expects(:generate) - @key.expects(:save) + Puppet::SSL::Key.indirection.expects(:save) @host.generate_key.should be_true @host.key.should equal(@key) @@ -328,14 +333,14 @@ describe Puppet::SSL::Host do Puppet::SSL::Key.expects(:new).with("myname").returns(@key) @key.stubs(:generate) - @key.expects(:save).raises "eh" + Puppet::SSL::Key.indirection.expects(:save).raises "eh" lambda { @host.generate_key }.should raise_error @host.key.should be_nil end it "should return any previously found key without requerying" do - Puppet::SSL::Key.expects(:find).with("myname").returns(@key).once + Puppet::SSL::Key.indirection.expects(:find).with("myname").returns(@key).once @host.key.should equal(@key) @host.key.should equal(@key) end @@ -344,16 +349,17 @@ describe Puppet::SSL::Host do describe "when managing its certificate request" do before do @realrequest = "real request" - @request = stub 'request', :content => @realrequest + @request = Puppet::SSL::CertificateRequest.new("myname") + @request.content = @realrequest end it "should return nil if the key is not set and cannot be found" do - Puppet::SSL::CertificateRequest.expects(:find).with("myname").returns(nil) + Puppet::SSL::CertificateRequest.indirection.expects(:find).with("myname").returns(nil) @host.certificate_request.should be_nil end it "should find the request in the Key class and return it and return the Puppet SSL request" do - Puppet::SSL::CertificateRequest.expects(:find).with("myname").returns @request + Puppet::SSL::CertificateRequest.indirection.expects(:find).with("myname").returns @request @host.certificate_request.should equal(@request) end @@ -367,7 +373,7 @@ describe Puppet::SSL::Host do @host.expects(:generate_key).returns(key) @request.stubs(:generate) - @request.stubs(:save) + Puppet::SSL::CertificateRequest.indirection.stubs(:save) @host.generate_certificate_request end @@ -378,14 +384,14 @@ describe Puppet::SSL::Host do key = stub 'key', :public_key => mock("public_key"), :content => "mycontent" @host.stubs(:key).returns(key) @request.expects(:generate).with("mycontent") - @request.expects(:save) + Puppet::SSL::CertificateRequest.indirection.expects(:save).with(@request) @host.generate_certificate_request.should be_true @host.certificate_request.should equal(@request) end it "should return any previously found request without requerying" do - Puppet::SSL::CertificateRequest.expects(:find).with("myname").returns(@request).once + Puppet::SSL::CertificateRequest.indirection.expects(:find).with("myname").returns(@request).once @host.certificate_request.should equal(@request) @host.certificate_request.should equal(@request) @@ -397,11 +403,14 @@ describe Puppet::SSL::Host do key = stub 'key', :public_key => mock("public_key"), :content => "mycontent" @host.stubs(:key).returns(key) @request.stubs(:generate) - @request.expects(:save).raises "eh" + @request.stubs(:name).returns("myname") + terminus = stub 'terminus' + Puppet::SSL::CertificateRequest.indirection.expects(:prepare).returns(terminus) + terminus.expects(:save).with { |req| req.instance == @request && req.key == "myname" }.raises "eh" lambda { @host.generate_certificate_request }.should raise_error - @host.certificate_request.should be_nil + @host.instance_eval { @certificate_request }.should be_nil end end @@ -415,36 +424,36 @@ describe Puppet::SSL::Host do end it "should find the CA certificate if it does not have a certificate" do - Puppet::SSL::Certificate.expects(:find).with(Puppet::SSL::CA_NAME).returns mock("cacert") - Puppet::SSL::Certificate.stubs(:find).with("myname").returns @cert + Puppet::SSL::Certificate.indirection.expects(:find).with(Puppet::SSL::CA_NAME).returns mock("cacert") + Puppet::SSL::Certificate.indirection.stubs(:find).with("myname").returns @cert @host.certificate end it "should not find the CA certificate if it is the CA host" do @host.expects(:ca?).returns true - Puppet::SSL::Certificate.stubs(:find) - Puppet::SSL::Certificate.expects(:find).with(Puppet::SSL::CA_NAME).never + Puppet::SSL::Certificate.indirection.stubs(:find) + Puppet::SSL::Certificate.indirection.expects(:find).with(Puppet::SSL::CA_NAME).never @host.certificate end it "should return nil if it cannot find a CA certificate" do - Puppet::SSL::Certificate.expects(:find).with(Puppet::SSL::CA_NAME).returns nil - Puppet::SSL::Certificate.expects(:find).with("myname").never + Puppet::SSL::Certificate.indirection.expects(:find).with(Puppet::SSL::CA_NAME).returns nil + Puppet::SSL::Certificate.indirection.expects(:find).with("myname").never @host.certificate.should be_nil end it "should find the key if it does not have one" do - Puppet::SSL::Certificate.stubs(:find) + Puppet::SSL::Certificate.indirection.stubs(:find) @host.expects(:key).returns mock("key") @host.certificate end it "should generate the key if one cannot be found" do - Puppet::SSL::Certificate.stubs(:find) + Puppet::SSL::Certificate.indirection.stubs(:find) @host.expects(:key).returns nil @host.expects(:generate_key) @@ -453,8 +462,8 @@ describe Puppet::SSL::Host do end it "should find the certificate in the Certificate class and return the Puppet certificate instance" do - Puppet::SSL::Certificate.expects(:find).with(Puppet::SSL::CA_NAME).returns mock("cacert") - Puppet::SSL::Certificate.expects(:find).with("myname").returns @cert + Puppet::SSL::Certificate.indirection.expects(:find).with(Puppet::SSL::CA_NAME).returns mock("cacert") + Puppet::SSL::Certificate.indirection.expects(:find).with("myname").returns @cert @host.certificate.should equal(@cert) end @@ -462,14 +471,14 @@ describe Puppet::SSL::Host do it "should fail if the found certificate does not match the private key" do @host.expects(:certificate_matches_key?).returns false - Puppet::SSL::Certificate.stubs(:find).returns @cert + Puppet::SSL::Certificate.indirection.stubs(:find).returns @cert lambda { @host.certificate }.should raise_error(Puppet::Error) end it "should return any previously found certificate" do - Puppet::SSL::Certificate.expects(:find).with(Puppet::SSL::CA_NAME).returns mock("cacert") - Puppet::SSL::Certificate.expects(:find).with("myname").returns(@cert).once + Puppet::SSL::Certificate.indirection.expects(:find).with(Puppet::SSL::CA_NAME).returns mock("cacert") + Puppet::SSL::Certificate.indirection.expects(:find).with("myname").returns(@cert).once @host.certificate.should equal(@cert) @host.certificate.should equal(@cert) @@ -482,30 +491,30 @@ describe Puppet::SSL::Host do describe "when listing certificate hosts" do it "should default to listing all clients with any file types" do - Puppet::SSL::Key.expects(:search).returns [] - Puppet::SSL::Certificate.expects(:search).returns [] - Puppet::SSL::CertificateRequest.expects(:search).returns [] + Puppet::SSL::Key.indirection.expects(:search).returns [] + Puppet::SSL::Certificate.indirection.expects(:search).returns [] + Puppet::SSL::CertificateRequest.indirection.expects(:search).returns [] Puppet::SSL::Host.search end it "should be able to list only clients with a key" do - Puppet::SSL::Key.expects(:search).returns [] - Puppet::SSL::Certificate.expects(:search).never - Puppet::SSL::CertificateRequest.expects(:search).never + Puppet::SSL::Key.indirection.expects(:search).returns [] + Puppet::SSL::Certificate.indirection.expects(:search).never + Puppet::SSL::CertificateRequest.indirection.expects(:search).never Puppet::SSL::Host.search :for => Puppet::SSL::Key end it "should be able to list only clients with a certificate" do - Puppet::SSL::Key.expects(:search).never - Puppet::SSL::Certificate.expects(:search).returns [] - Puppet::SSL::CertificateRequest.expects(:search).never + Puppet::SSL::Key.indirection.expects(:search).never + Puppet::SSL::Certificate.indirection.expects(:search).returns [] + Puppet::SSL::CertificateRequest.indirection.expects(:search).never Puppet::SSL::Host.search :for => Puppet::SSL::Certificate end it "should be able to list only clients with a certificate request" do - Puppet::SSL::Key.expects(:search).never - Puppet::SSL::Certificate.expects(:search).never - Puppet::SSL::CertificateRequest.expects(:search).returns [] + Puppet::SSL::Key.indirection.expects(:search).never + Puppet::SSL::Certificate.indirection.expects(:search).never + Puppet::SSL::CertificateRequest.indirection.expects(:search).returns [] Puppet::SSL::Host.search :for => Puppet::SSL::CertificateRequest end @@ -514,9 +523,9 @@ describe Puppet::SSL::Host do cert = stub 'cert', :name => "cert" csr = stub 'csr', :name => "csr" - Puppet::SSL::Key.expects(:search).returns [key] - Puppet::SSL::Certificate.expects(:search).returns [cert] - Puppet::SSL::CertificateRequest.expects(:search).returns [csr] + Puppet::SSL::Key.indirection.expects(:search).returns [key] + Puppet::SSL::Certificate.indirection.expects(:search).returns [cert] + Puppet::SSL::CertificateRequest.indirection.expects(:search).returns [csr] returned = [] %w{key cert csr}.each do |name| @@ -606,7 +615,7 @@ describe Puppet::SSL::Host do Puppet.settings.stubs(:value).with(:localcacert).returns "ssl_host_testing" - Puppet::SSL::CertificateRevocationList.stubs(:find).returns(nil) + Puppet::SSL::CertificateRevocationList.indirection.stubs(:find).returns(nil) end it "should accept a purpose" do @@ -628,7 +637,7 @@ describe Puppet::SSL::Host do describe "and a CRL is available" do before do @crl = stub 'crl', :content => "real_crl" - Puppet::SSL::CertificateRevocationList.stubs(:find).returns @crl + Puppet::SSL::CertificateRevocationList.indirection.stubs(:find).returns @crl Puppet.settings.stubs(:value).with(:certificate_revocation).returns true end @@ -704,4 +713,84 @@ describe Puppet::SSL::Host do @host.wait_for_cert(1) end end + + describe "when handling PSON" do + include PuppetSpec::Files + + before do + Puppet[:vardir] = tmpdir("ssl_test_vardir") + Puppet[:ssldir] = tmpdir("ssl_test_ssldir") + Puppet::SSLCertificates::CA.new.mkrootcert + # localcacert is where each client stores the CA certificate + # cacert is where the master stores the CA certificate + # Since we need to play the role of both for testing we need them to be the same and exist + Puppet[:cacert] = Puppet[:localcacert] + + @ca=Puppet::SSL::CertificateAuthority.new + end + + describe "when converting to PSON" do + it "should be able to identify a host with an unsigned certificate request" do + host = Puppet::SSL::Host.new("bazinga") + host.generate_certificate_request + pson_hash = { + "fingerprint" => host.certificate_request.fingerprint, + "desired_state" => 'requested', + "name" => host.name + } + + result = PSON.parse(Puppet::SSL::Host.new(host.name).to_pson) + result["fingerprint"].should == pson_hash["fingerprint"] + result["name"].should == pson_hash["name"] + result["state"].should == pson_hash["desired_state"] + end + + it "should be able to identify a host with a signed certificate" do + host = Puppet::SSL::Host.new("bazinga") + host.generate_certificate_request + @ca.sign(host.name) + pson_hash = { + "fingerprint" => Puppet::SSL::Certificate.indirection.find(host.name).fingerprint, + "desired_state" => 'signed', + "name" => host.name, + } + + result = PSON.parse(Puppet::SSL::Host.new(host.name).to_pson) + result["fingerprint"].should == pson_hash["fingerprint"] + result["name"].should == pson_hash["name"] + result["state"].should == pson_hash["desired_state"] + end + + it "should be able to identify a host with a revoked certificate" do + host = Puppet::SSL::Host.new("bazinga") + host.generate_certificate_request + @ca.sign(host.name) + @ca.revoke(host.name) + pson_hash = { + "fingerprint" => Puppet::SSL::Certificate.indirection.find(host.name).fingerprint, + "desired_state" => 'revoked', + "name" => host.name, + } + + result = PSON.parse(Puppet::SSL::Host.new(host.name).to_pson) + result["fingerprint"].should == pson_hash["fingerprint"] + result["name"].should == pson_hash["name"] + result["state"].should == pson_hash["desired_state"] + end + end + + describe "when converting from PSON" do + it "should return a Puppet::SSL::Host object with the specified desired state" do + host = Puppet::SSL::Host.new("bazinga") + host.desired_state="signed" + pson_hash = { + "name" => host.name, + "desired_state" => host.desired_state, + } + generated_host = Puppet::SSL::Host.from_pson(pson_hash) + generated_host.desired_state.should == host.desired_state + generated_host.name.should == host.name + end + end + end end diff --git a/spec/unit/ssl/inventory_spec.rb b/spec/unit/ssl/inventory_spec.rb index a57d6fafc..4d47a37c6 100755 --- a/spec/unit/ssl/inventory_spec.rb +++ b/spec/unit/ssl/inventory_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') require 'puppet/ssl/inventory' @@ -40,7 +40,7 @@ describe Puppet::SSL::Inventory do Puppet.settings.stubs(:write) FileTest.stubs(:exist?).with("/inven/tory").returns false - Puppet::SSL::Certificate.stubs(:search).returns [] + Puppet::SSL::Certificate.indirection.stubs(:search).returns [] end it "should log that it is building a new inventory file" do @@ -67,7 +67,7 @@ describe Puppet::SSL::Inventory do cert1 = mock 'cert1' cert2 = mock 'cert2' - Puppet::SSL::Certificate.expects(:search).with("*").returns [cert1, cert2] + Puppet::SSL::Certificate.indirection.expects(:search).with("*").returns [cert1, cert2] @class.any_instance.expects(:add).with(cert1) @class.any_instance.expects(:add).with(cert2) diff --git a/spec/unit/ssl/key_spec.rb b/spec/unit/ssl/key_spec.rb index 58193db28..e0667a5cc 100755 --- a/spec/unit/ssl/key_spec.rb +++ b/spec/unit/ssl/key_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') require 'puppet/ssl/key' diff --git a/spec/unit/sslcertificates/ca_spec.rb b/spec/unit/sslcertificates/ca_spec.rb index b1393b25d..4e44f2d90 100644 --- a/spec/unit/sslcertificates/ca_spec.rb +++ b/spec/unit/sslcertificates/ca_spec.rb @@ -1,5 +1,5 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') require 'puppet' require 'puppet/sslcertificates' diff --git a/spec/unit/status_spec.rb b/spec/unit/status_spec.rb index 71bfa4a44..3a9c805b3 100644 --- a/spec/unit/status_spec.rb +++ b/spec/unit/status_spec.rb @@ -1,11 +1,11 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../spec_helper') describe Puppet::Status do it "should implement find" do - Puppet::Status.find( :default ).should be_is_a(Puppet::Status) - Puppet::Status.find( :default ).status["is_alive"].should == true + Puppet::Status.indirection.find( :default ).should be_is_a(Puppet::Status) + Puppet::Status.indirection.find( :default ).status["is_alive"].should == true end it "should default to is_alive is true" do diff --git a/spec/unit/transaction/event_manager_spec.rb b/spec/unit/transaction/event_manager_spec.rb index eeb3d3389..e45fbdf78 100755 --- a/spec/unit/transaction/event_manager_spec.rb +++ b/spec/unit/transaction/event_manager_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') require 'puppet/transaction/event_manager' diff --git a/spec/unit/transaction/event_spec.rb b/spec/unit/transaction/event_spec.rb index 6ed14722b..c77716cd6 100755 --- a/spec/unit/transaction/event_spec.rb +++ b/spec/unit/transaction/event_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') require 'puppet/transaction/event' diff --git a/spec/unit/transaction/report_spec.rb b/spec/unit/transaction/report_spec.rb index 81efa340e..a3bfe1e82 100755 --- a/spec/unit/transaction/report_spec.rb +++ b/spec/unit/transaction/report_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') require 'puppet/transaction/report' @@ -67,20 +67,13 @@ describe Puppet::Transaction::Report do end describe "when using the indirector" do - it "should redirect :find to the indirection" do - @indirection = stub 'indirection', :name => :report - Puppet::Transaction::Report.stubs(:indirection).returns(@indirection) - @indirection.expects(:find) - Puppet::Transaction::Report.find(:report) - end - it "should redirect :save to the indirection" do Facter.stubs(:value).returns("eh") @indirection = stub 'indirection', :name => :report Puppet::Transaction::Report.stubs(:indirection).returns(@indirection) report = Puppet::Transaction::Report.new("apply") @indirection.expects(:save) - report.save + Puppet::Transaction::Report.indirection.save(report) end it "should default to the 'processor' terminus" do diff --git a/spec/unit/transaction/resource_harness_spec.rb b/spec/unit/transaction/resource_harness_spec.rb index 104c19e85..168b50287 100755 --- a/spec/unit/transaction/resource_harness_spec.rb +++ b/spec/unit/transaction/resource_harness_spec.rb @@ -1,7 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../spec_helper' -require 'puppet_spec/files' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') require 'puppet/transaction/resource_harness' diff --git a/spec/unit/transaction_spec.rb b/spec/unit/transaction_spec.rb index 862413a31..ab76130e3 100755 --- a/spec/unit/transaction_spec.rb +++ b/spec/unit/transaction_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../spec_helper') require 'puppet/transaction' @@ -114,7 +114,6 @@ describe Puppet::Transaction do describe "when evaluating a resource" do before do @transaction = Puppet::Transaction.new(Puppet::Resource::Catalog.new) - @transaction.stubs(:eval_children_and_apply_resource) @transaction.stubs(:skip?).returns false @resource = Puppet::Type.type(:file).new :path => @basepath @@ -126,12 +125,6 @@ describe Puppet::Transaction do @transaction.eval_resource(@resource) end - it "should eval and apply children" do - @transaction.expects(:eval_children_and_apply_resource).with(@resource, nil) - - @transaction.eval_resource(@resource) - end - it "should process events" do @transaction.event_manager.expects(:process_events).with(@resource) @@ -197,7 +190,7 @@ describe Puppet::Transaction do second.expects(:generate).returns [third] third.expects(:generate) - @transaction.generate_additional_resources(first, :generate) + @transaction.generate_additional_resources(first) end it "should finish all resources" do @@ -213,7 +206,7 @@ describe Puppet::Transaction do resource.expects(:finish) - @transaction.generate_additional_resources(generator, :generate) + @transaction.generate_additional_resources(generator) end it "should skip generated resources that conflict with existing resources" do @@ -230,7 +223,7 @@ describe Puppet::Transaction do resource.expects(:finish).never resource.expects(:info) # log that it's skipped - @transaction.generate_additional_resources(generator, :generate).should be_empty + @transaction.generate_additional_resources(generator) end it "should copy all tags to the newly generated resources" do @@ -244,8 +237,10 @@ describe Puppet::Transaction do @catalog.stubs(:add_resource) child.expects(:tag).with("one", "two") + child.expects(:finish) + generator.expects(:depthfirst?) - @transaction.generate_additional_resources(generator, :generate) + @transaction.generate_additional_resources(generator) end end @@ -387,20 +382,19 @@ describe Puppet::Transaction do describe 'within an evaluate call' do before do - @resource = stub 'resource', :ref => 'some_ref' + @resource = Puppet::Type.type(:notify).new :title => "foobar" @catalog.add_resource @resource @transaction.stubs(:prepare) - @transaction.sorted_resources = [@resource] end it 'should stop processing if :stop_processing? is true' do - @transaction.expects(:stop_processing?).returns(true) + @transaction.stubs(:stop_processing?).returns(true) @transaction.expects(:eval_resource).never @transaction.evaluate end it 'should continue processing if :stop_processing? is false' do - @transaction.expects(:stop_processing?).returns(false) + @transaction.stubs(:stop_processing?).returns(false) @transaction.expects(:eval_resource).returns(nil) @transaction.evaluate end diff --git a/spec/unit/type/augeas_spec.rb b/spec/unit/type/augeas_spec.rb index d2e40f0f6..dece395e1 100644 --- a/spec/unit/type/augeas_spec.rb +++ b/spec/unit/type/augeas_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') augeas = Puppet::Type.type(:augeas) diff --git a/spec/unit/type/component_spec.rb b/spec/unit/type/component_spec.rb index f7403e5e3..60abfafbf 100755 --- a/spec/unit/type/component_spec.rb +++ b/spec/unit/type/component_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') component = Puppet::Type.type(:component) diff --git a/spec/unit/type/computer_spec.rb b/spec/unit/type/computer_spec.rb index 1f1c55b2f..3177884f7 100755 --- a/spec/unit/type/computer_spec.rb +++ b/spec/unit/type/computer_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') computer = Puppet::Type.type(:computer) diff --git a/spec/unit/type/cron_spec.rb b/spec/unit/type/cron_spec.rb index f985cdd09..5466b4d58 100755 --- a/spec/unit/type/cron_spec.rb +++ b/spec/unit/type/cron_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -Dir.chdir(File.dirname(__FILE__)) { (s = lambda { |f| File.exist?(f) ? require(f) : Dir.chdir("..") { s.call(f) } }).call("spec/spec_helper.rb") } +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') describe Puppet::Type.type(:cron) do before do diff --git a/spec/unit/type/exec_spec.rb b/spec/unit/type/exec_spec.rb index e155506b0..86b824423 100755 --- a/spec/unit/type/exec_spec.rb +++ b/spec/unit/type/exec_spec.rb @@ -1,5 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../spec_helper' + +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') describe Puppet::Type.type(:exec) do def exec_tester(command, exitstatus = 0, rest = {}) @@ -284,36 +285,6 @@ describe Puppet::Type.type(:exec) do @exec = Puppet::Type.type(:exec).new(:name => '/bin/true') end - describe "when setting env" do - it "should issue a deprecation warning" do - expect { @exec[:env] = 'foo=bar' }.should_not raise_error - @logs.first.message.should =~ /deprecate.*environment/ - end - - it "should update the value of env" do - data = ['foo=bar'] - @exec[:env] = data - @exec[:env].should == data - end - - it "should forward to environment" do - data = ['foo=bar'] - @exec[:env] = data - @exec[:environment].should == data - end - - it "should not override environment if both are set" do - pending "can't fix: too disruptive for 2.6, removed in 2.7" - # ...so this test is here to validate that we know about the problem. - # This ensures correct order of evaluation to trigger the bug; don't - # count on this happening in the constructor. --daniel 2011-03-01 - @exec[:environment] = 'environment=true' - @exec[:env] = 'env=true' - - @exec[:environment].should == "environment=true" - end - end - describe "when setting environment" do { "single values" => "foo=bar", "multiple values" => ["foo=bar", "baz=quux"], diff --git a/spec/unit/type/file/checksum_spec.rb b/spec/unit/type/file/checksum_spec.rb index 8b9138b78..16e8e99e1 100644 --- a/spec/unit/type/file/checksum_spec.rb +++ b/spec/unit/type/file/checksum_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -Dir.chdir(File.dirname(__FILE__)) { (s = lambda { |f| File.exist?(f) ? require(f) : Dir.chdir("..") { s.call(f) } }).call("spec/spec_helper.rb") } +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') checksum = Puppet::Type.type(:file).attrclass(:checksum) describe checksum do diff --git a/spec/unit/type/file/content_spec.rb b/spec/unit/type/file/content_spec.rb index bd2b2adaf..7abc7c433 100755 --- a/spec/unit/type/file/content_spec.rb +++ b/spec/unit/type/file/content_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -Dir.chdir(File.dirname(__FILE__)) { (s = lambda { |f| File.exist?(f) ? require(f) : Dir.chdir("..") { s.call(f) } }).call("spec/spec_helper.rb") } +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') content = Puppet::Type.type(:file).attrclass(:content) describe content do diff --git a/spec/unit/type/file/ctime.rb b/spec/unit/type/file/ctime.rb index 6145cbfdc..9fb892aed 100644 --- a/spec/unit/type/file/ctime.rb +++ b/spec/unit/type/file/ctime.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -Dir.chdir(File.dirname(__FILE__)) { (s = lambda { |f| File.exist?(f) ? require(f) : Dir.chdir("..") { s.call(f) } }).call("spec/spec_helper.rb") } +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') describe Puppet::Type.type(:file).attrclass(:ctime) do require 'puppet_spec/files' diff --git a/spec/unit/type/file/ensure_spec.rb b/spec/unit/type/file/ensure_spec.rb index dbb3a1053..c5351309e 100755 --- a/spec/unit/type/file/ensure_spec.rb +++ b/spec/unit/type/file/ensure_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -Dir.chdir(File.dirname(__FILE__)) { (s = lambda { |f| File.exist?(f) ? require(f) : Dir.chdir("..") { s.call(f) } }).call("spec/spec_helper.rb") } +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') property = Puppet::Type.type(:file).attrclass(:ensure) diff --git a/spec/unit/type/file/group_spec.rb b/spec/unit/type/file/group_spec.rb index 956cd57e7..37a6872bd 100755 --- a/spec/unit/type/file/group_spec.rb +++ b/spec/unit/type/file/group_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -Dir.chdir(File.dirname(__FILE__)) { (s = lambda { |f| File.exist?(f) ? require(f) : Dir.chdir("..") { s.call(f) } }).call("spec/spec_helper.rb") } +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') property = Puppet::Type.type(:file).attrclass(:group) diff --git a/spec/unit/type/file/mtime.rb b/spec/unit/type/file/mtime.rb index 043156ceb..fa61bc343 100644 --- a/spec/unit/type/file/mtime.rb +++ b/spec/unit/type/file/mtime.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -Dir.chdir(File.dirname(__FILE__)) { (s = lambda { |f| File.exist?(f) ? require(f) : Dir.chdir("..") { s.call(f) } }).call("spec/spec_helper.rb") } +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') describe Puppet::Type.type(:file).attrclass(:mtime) do require 'puppet_spec/files' diff --git a/spec/unit/type/file/owner_spec.rb b/spec/unit/type/file/owner_spec.rb index bcb8e07d6..375faa237 100755 --- a/spec/unit/type/file/owner_spec.rb +++ b/spec/unit/type/file/owner_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -Dir.chdir(File.dirname(__FILE__)) { (s = lambda { |f| File.exist?(f) ? require(f) : Dir.chdir("..") { s.call(f) } }).call("spec/spec_helper.rb") } +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') property = Puppet::Type.type(:file).attrclass(:owner) diff --git a/spec/unit/type/file/selinux_spec.rb b/spec/unit/type/file/selinux_spec.rb index a2444acd9..45e8b3b14 100644 --- a/spec/unit/type/file/selinux_spec.rb +++ b/spec/unit/type/file/selinux_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -Dir.chdir(File.dirname(__FILE__)) { (s = lambda { |f| File.exist?(f) ? require(f) : Dir.chdir("..") { s.call(f) } }).call("spec/spec_helper.rb") } +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') [:seluser, :selrole, :seltype, :selrange].each do |param| diff --git a/spec/unit/type/file/source_spec.rb b/spec/unit/type/file/source_spec.rb index 00cc2f235..bb83e7531 100755 --- a/spec/unit/type/file/source_spec.rb +++ b/spec/unit/type/file/source_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -Dir.chdir(File.dirname(__FILE__)) { (s = lambda { |f| File.exist?(f) ? require(f) : Dir.chdir("..") { s.call(f) } }).call("spec/spec_helper.rb") } +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') source = Puppet::Type.type(:file).attrclass(:source) describe Puppet::Type.type(:file).attrclass(:source) do @@ -54,22 +54,22 @@ describe Puppet::Type.type(:file).attrclass(:source) do it "should collect its metadata using the Metadata class if it is not already set" do @source = source.new(:resource => @resource, :value => "/foo/bar") - Puppet::FileServing::Metadata.expects(:find).with("/foo/bar").returns @metadata + Puppet::FileServing::Metadata.indirection.expects(:find).with("/foo/bar").returns @metadata @source.metadata end it "should use the metadata from the first found source" do metadata = stub 'metadata', :source= => nil @source = source.new(:resource => @resource, :value => ["/foo/bar", "/fee/booz"]) - Puppet::FileServing::Metadata.expects(:find).with("/foo/bar").returns nil - Puppet::FileServing::Metadata.expects(:find).with("/fee/booz").returns metadata + Puppet::FileServing::Metadata.indirection.expects(:find).with("/foo/bar").returns nil + Puppet::FileServing::Metadata.indirection.expects(:find).with("/fee/booz").returns metadata @source.metadata.should equal(metadata) end it "should store the found source as the metadata's source" do metadata = mock 'metadata' @source = source.new(:resource => @resource, :value => "/foo/bar") - Puppet::FileServing::Metadata.expects(:find).with("/foo/bar").returns metadata + Puppet::FileServing::Metadata.indirection.expects(:find).with("/foo/bar").returns metadata metadata.expects(:source=).with("/foo/bar") @source.metadata @@ -77,7 +77,7 @@ describe Puppet::Type.type(:file).attrclass(:source) do it "should fail intelligently if an exception is encountered while querying for metadata" do @source = source.new(:resource => @resource, :value => "/foo/bar") - Puppet::FileServing::Metadata.expects(:find).with("/foo/bar").raises RuntimeError + Puppet::FileServing::Metadata.indirection.expects(:find).with("/foo/bar").raises RuntimeError @source.expects(:fail).raises ArgumentError lambda { @source.metadata }.should raise_error(ArgumentError) @@ -85,7 +85,7 @@ describe Puppet::Type.type(:file).attrclass(:source) do it "should fail if no specified sources can be found" do @source = source.new(:resource => @resource, :value => "/foo/bar") - Puppet::FileServing::Metadata.expects(:find).with("/foo/bar").returns nil + Puppet::FileServing::Metadata.indirection.expects(:find).with("/foo/bar").returns nil @source.expects(:fail).raises RuntimeError @@ -96,7 +96,7 @@ describe Puppet::Type.type(:file).attrclass(:source) do expirer = stub 'expired', :dependent_data_expired? => true metadata = stub 'metadata', :source= => nil - Puppet::FileServing::Metadata.expects(:find).with("/fee/booz").returns metadata + Puppet::FileServing::Metadata.indirection.expects(:find).with("/fee/booz").returns metadata @source = source.new(:resource => @resource, :value => ["/fee/booz"]) @source.metadata = "foo" diff --git a/spec/unit/type/file/type.rb b/spec/unit/type/file/type.rb index e46f0e0b0..0d38b64cd 100644 --- a/spec/unit/type/file/type.rb +++ b/spec/unit/type/file/type.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -Dir.chdir(File.dirname(__FILE__)) { (s = lambda { |f| File.exist?(f) ? require(f) : Dir.chdir("..") { s.call(f) } }).call("spec/spec_helper.rb") } +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') describe Puppet::Type.type(:file).attrclass(:type) do require 'puppet_spec/files' diff --git a/spec/unit/type/file_spec.rb b/spec/unit/type/file_spec.rb index 90f3daf09..b15d41d4b 100755 --- a/spec/unit/type/file_spec.rb +++ b/spec/unit/type/file_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') describe Puppet::Type.type(:file) do before do @@ -379,8 +379,6 @@ describe Puppet::Type.type(:file) do end describe "when managing links" do - require 'puppettest/support/assertions' - include PuppetTest require 'tempfile' if @real_posix @@ -394,13 +392,7 @@ describe Puppet::Type.type(:file) do File.open(@file, "w", 0644) { |f| f.puts "yayness"; f.flush } File.symlink(@file, @link) - - @resource = Puppet::Type.type(:file).new( - - :path => @link, - - :mode => "755" - ) + @resource = Puppet::Type.type(:file).new(:path => @link, :mode => "755") @catalog.add_resource @resource end @@ -525,47 +517,47 @@ describe Puppet::Type.type(:file) do describe "when executing a recursive search" do it "should use Metadata to do its recursion" do - Puppet::FileServing::Metadata.expects(:search) + Puppet::FileServing::Metadata.indirection.expects(:search) @file.perform_recursion(@file[:path]) end it "should use the provided path as the key to the search" do - Puppet::FileServing::Metadata.expects(:search).with { |key, options| key == "/foo" } + Puppet::FileServing::Metadata.indirection.expects(:search).with { |key, options| key == "/foo" } @file.perform_recursion("/foo") end it "should return the results of the metadata search" do - Puppet::FileServing::Metadata.expects(:search).returns "foobar" + Puppet::FileServing::Metadata.indirection.expects(:search).returns "foobar" @file.perform_recursion(@file[:path]).should == "foobar" end it "should pass its recursion value to the search" do @file[:recurse] = true - Puppet::FileServing::Metadata.expects(:search).with { |key, options| options[:recurse] == true } + Puppet::FileServing::Metadata.indirection.expects(:search).with { |key, options| options[:recurse] == true } @file.perform_recursion(@file[:path]) end it "should pass true if recursion is remote" do @file[:recurse] = :remote - Puppet::FileServing::Metadata.expects(:search).with { |key, options| options[:recurse] == true } + Puppet::FileServing::Metadata.indirection.expects(:search).with { |key, options| options[:recurse] == true } @file.perform_recursion(@file[:path]) end it "should pass its recursion limit value to the search" do @file[:recurselimit] = 10 - Puppet::FileServing::Metadata.expects(:search).with { |key, options| options[:recurselimit] == 10 } + Puppet::FileServing::Metadata.indirection.expects(:search).with { |key, options| options[:recurselimit] == 10 } @file.perform_recursion(@file[:path]) end it "should configure the search to ignore or manage links" do @file[:links] = :manage - Puppet::FileServing::Metadata.expects(:search).with { |key, options| options[:links] == :manage } + Puppet::FileServing::Metadata.indirection.expects(:search).with { |key, options| options[:links] == :manage } @file.perform_recursion(@file[:path]) end it "should pass its 'ignore' setting to the search if it has one" do @file[:ignore] = %w{.svn CVS} - Puppet::FileServing::Metadata.expects(:search).with { |key, options| options[:ignore] == %w{.svn CVS} } + Puppet::FileServing::Metadata.indirection.expects(:search).with { |key, options| options[:ignore] == %w{.svn CVS} } @file.perform_recursion(@file[:path]) end end @@ -612,7 +604,7 @@ describe Puppet::Type.type(:file) do it "should set checksum_type to none if this file checksum is none" do @file[:checksum] = :none - Puppet::FileServing::Metadata.expects(:search).with { |path,params| params[:checksum_type] == :none }.returns [@metadata] + Puppet::FileServing::Metadata.indirection.expects(:search).with { |path,params| params[:checksum_type] == :none }.returns [@metadata] @file.expects(:newchild).with("my/file").returns "fiebar" @file.recurse_local end diff --git a/spec/unit/type/filebucket_spec.rb b/spec/unit/type/filebucket_spec.rb index 0b8ea50f8..7fcbacc4f 100644 --- a/spec/unit/type/filebucket_spec.rb +++ b/spec/unit/type/filebucket_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') describe Puppet::Type.type(:filebucket) do describe "when validating attributes" do diff --git a/spec/unit/type/group_spec.rb b/spec/unit/type/group_spec.rb index b41ce71a0..43fdfcd4d 100755 --- a/spec/unit/type/group_spec.rb +++ b/spec/unit/type/group_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') describe Puppet::Type.type(:group) do before do diff --git a/spec/unit/type/host_spec.rb b/spec/unit/type/host_spec.rb new file mode 100755 index 000000000..60ce73c6d --- /dev/null +++ b/spec/unit/type/host_spec.rb @@ -0,0 +1,130 @@ +#!/usr/bin/env ruby + +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') + +host = Puppet::Type.type(:host) + +describe host do + before do + @class = host + @catalog = Puppet::Resource::Catalog.new + @provider = stub 'provider' + @resource = stub 'resource', :resource => nil, :provider => @provider + end + + it "should have :name be its namevar" do + @class.key_attributes.should == [:name] + end + + describe "when validating attributes" do + [:name, :provider ].each do |param| + it "should have a #{param} parameter" do + @class.attrtype(param).should == :param + end + end + + [:ip, :target, :host_aliases, :comment, :ensure].each do |property| + it "should have a #{property} property" do + @class.attrtype(property).should == :property + end + end + + it "should have a list host_aliases" do + @class.attrclass(:host_aliases).ancestors.should be_include(Puppet::Property::OrderedList) + end + + end + + describe "when validating values" do + it "should support present as a value for ensure" do + proc { @class.new(:name => "foo", :ensure => :present) }.should_not raise_error + end + + it "should support absent as a value for ensure" do + proc { @class.new(:name => "foo", :ensure => :absent) }.should_not raise_error + end + + it "should accept IPv4 addresses" do + proc { @class.new(:name => "foo", :ip => '10.96.0.1') }.should_not raise_error + end + + it "should accept long IPv6 addresses" do + # Taken from wikipedia article about ipv6 + proc { @class.new(:name => "foo", :ip => '2001:0db8:85a3:08d3:1319:8a2e:0370:7344') }.should_not raise_error + end + + it "should accept one host_alias" do + proc { @class.new(:name => "foo", :host_aliases => 'alias1') }.should_not raise_error + end + + it "should accept multiple host_aliases" do + proc { @class.new(:name => "foo", :host_aliases => [ 'alias1', 'alias2' ]) }.should_not raise_error + end + + it "should accept shortened IPv6 addresses" do + proc { @class.new(:name => "foo", :ip => '2001:db8:0:8d3:0:8a2e:70:7344') }.should_not raise_error + proc { @class.new(:name => "foo", :ip => '::ffff:192.0.2.128') }.should_not raise_error + proc { @class.new(:name => "foo", :ip => '::1') }.should_not raise_error + end + + it "should not accept malformed IPv4 addresses like 192.168.0.300" do + proc { @class.new(:name => "foo", :ip => '192.168.0.300') }.should raise_error + end + + it "should not accept malformed IP addresses like 2001:0dg8:85a3:08d3:1319:8a2e:0370:7344" do + proc { @class.new(:name => "foo", :ip => '2001:0dg8:85a3:08d3:1319:8a2e:0370:7344') }.should raise_error + end + + it "should not accept spaces in resourcename" do + proc { @class.new(:name => "foo bar") }.should raise_error + end + + it "should not accept host_aliases with spaces" do + proc { @class.new(:name => "foo", :host_aliases => [ 'well_formed', 'not wellformed' ]) }.should raise_error + end + + it "should not accept empty host_aliases" do + proc { @class.new(:name => "foo", :host_aliases => ['alias1','']) }.should raise_error + end + end + + describe "when syncing" do + + it "should send the first value to the provider for ip property" do + @ip = @class.attrclass(:ip).new(:resource => @resource, :should => %w{192.168.0.1 192.168.0.2}) + @provider.expects(:ip=).with '192.168.0.1' + @ip.sync + end + + it "should send the first value to the provider for comment property" do + @comment = @class.attrclass(:comment).new(:resource => @resource, :should => %w{Bazinga Notme}) + @provider.expects(:comment=).with 'Bazinga' + @comment.sync + end + + it "should send the joined array to the provider for host_alias" do + @host_aliases = @class.attrclass(:host_aliases).new(:resource => @resource, :should => %w{foo bar}) + @provider.expects(:host_aliases=).with 'foo bar' + @host_aliases.sync + end + + it "should also use the specified delimiter for joining" do + @host_aliases = @class.attrclass(:host_aliases).new(:resource => @resource, :should => %w{foo bar}) + @host_aliases.stubs(:delimiter).returns "\t" + @provider.expects(:host_aliases=).with "foo\tbar" + @host_aliases.sync + end + + it "should care about the order of host_aliases" do + @host_aliases = @class.attrclass(:host_aliases).new(:resource => @resource, :should => %w{foo bar}) + @host_aliases.insync?(%w{foo bar}).should == true + @host_aliases.insync?(%w{bar foo}).should == false + end + + it "should not consider aliases to be in sync if should is a subset of current" do + @host_aliases = @class.attrclass(:host_aliases).new(:resource => @resource, :should => %w{foo bar}) + @host_aliases.insync?(%w{foo bar anotherone}).should == false + end + + end +end diff --git a/spec/unit/type/macauthorization_spec.rb b/spec/unit/type/macauthorization_spec.rb index 544f07f4b..e0d3b9433 100755 --- a/spec/unit/type/macauthorization_spec.rb +++ b/spec/unit/type/macauthorization_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') macauth_type = Puppet::Type.type(:macauthorization) diff --git a/spec/unit/type/maillist_spec.rb b/spec/unit/type/maillist_spec.rb index 04acea7dd..7e96b4760 100755 --- a/spec/unit/type/maillist_spec.rb +++ b/spec/unit/type/maillist_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -Dir.chdir(File.dirname(__FILE__)) { (s = lambda { |f| File.exist?(f) ? require(f) : Dir.chdir("..") { s.call(f) } }).call("spec/spec_helper.rb") } +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') maillist = Puppet::Type.type(:maillist) diff --git a/spec/unit/type/mcx_spec.rb b/spec/unit/type/mcx_spec.rb index 703ecb473..4b60a5c96 100755 --- a/spec/unit/type/mcx_spec.rb +++ b/spec/unit/type/mcx_spec.rb @@ -20,7 +20,7 @@ # Most of this code copied from /spec/type/service.rb -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') require 'puppet/type/mcx' diff --git a/spec/unit/type/mount_spec.rb b/spec/unit/type/mount_spec.rb index fdb67f7d5..4638e9a2e 100755 --- a/spec/unit/type/mount_spec.rb +++ b/spec/unit/type/mount_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') describe Puppet::Type.type(:mount) do it "should have a :refreshable feature that requires the :remount method" do @@ -231,27 +231,51 @@ describe Puppet::Type.type(:mount)::Ensure do end - describe Puppet::Type.type(:mount), "when responding to events" do + describe Puppet::Type.type(:mount), "when responding to refresh" do + pending "2.6.x specifies slightly different behavior and the desired behavior needs to be clarified and revisited. See ticket #4904" do - it "should remount if it is currently mounted" do - @provider.expects(:mounted?).returns(true) - @provider.expects(:remount) + it "should remount if it is supposed to be mounted" do + @mount[:ensure] = "mounted" + @provider.expects(:remount) - @mount.refresh - end + @mount.refresh + end - it "should not remount if it is not currently mounted" do - @provider.expects(:mounted?).returns(false) - @provider.expects(:remount).never + it "should not remount if it is supposed to be present" do + @mount[:ensure] = "present" + @provider.expects(:remount).never - @mount.refresh - end + @mount.refresh + end + + it "should not remount if it is supposed to be absent" do + @mount[:ensure] = "absent" + @provider.expects(:remount).never + + @mount.refresh + end - it "should not remount swap filesystems" do - @mount[:fstype] = "swap" - @provider.expects(:remount).never + it "should not remount if it is supposed to be defined" do + @mount[:ensure] = "defined" + @provider.expects(:remount).never - @mount.refresh + @mount.refresh + end + + it "should not remount if it is supposed to be unmounted" do + @mount[:ensure] = "unmounted" + @provider.expects(:remount).never + + @mount.refresh + end + + it "should not remount swap filesystems" do + @mount[:ensure] = "mounted" + @mount[:fstype] = "swap" + @provider.expects(:remount).never + + @mount.refresh + end end end end diff --git a/spec/unit/type/nagios_spec.rb b/spec/unit/type/nagios_spec.rb index 2acbd392f..1515c2ae9 100755 --- a/spec/unit/type/nagios_spec.rb +++ b/spec/unit/type/nagios_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') require 'puppet/external/nagios' diff --git a/spec/unit/type/noop_metaparam_spec.rb b/spec/unit/type/noop_metaparam_spec.rb index 5ab2d9b7e..6f8f87e6c 100755 --- a/spec/unit/type/noop_metaparam_spec.rb +++ b/spec/unit/type/noop_metaparam_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') require 'puppet/type' diff --git a/spec/unit/type/package_spec.rb b/spec/unit/type/package_spec.rb index 662fe4798..3db9c77be 100755 --- a/spec/unit/type/package_spec.rb +++ b/spec/unit/type/package_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') describe Puppet::Type.type(:package) do before do diff --git a/spec/unit/type/resources_spec.rb b/spec/unit/type/resources_spec.rb index 9d955591c..020ab9b81 100644 --- a/spec/unit/type/resources_spec.rb +++ b/spec/unit/type/resources_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') resources = Puppet::Type.type(:resources) diff --git a/spec/unit/type/schedule_spec.rb b/spec/unit/type/schedule_spec.rb index 8305431a6..59d199812 100755 --- a/spec/unit/type/schedule_spec.rb +++ b/spec/unit/type/schedule_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') module ScheduleTesting diff --git a/spec/unit/type/selboolean_spec.rb b/spec/unit/type/selboolean_spec.rb index 3b31f4306..41b254f25 100755 --- a/spec/unit/type/selboolean_spec.rb +++ b/spec/unit/type/selboolean_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -Dir.chdir(File.dirname(__FILE__)) { (s = lambda { |f| File.exist?(f) ? require(f) : Dir.chdir("..") { s.call(f) } }).call("spec/spec_helper.rb") } +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') describe Puppet::Type.type(:selboolean), "when validating attributes" do [:name, :persistent].each do |param| diff --git a/spec/unit/type/selmodule_spec.rb b/spec/unit/type/selmodule_spec.rb index 3d126256c..37453d8ed 100755 --- a/spec/unit/type/selmodule_spec.rb +++ b/spec/unit/type/selmodule_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -Dir.chdir(File.dirname(__FILE__)) { (s = lambda { |f| File.exist?(f) ? require(f) : Dir.chdir("..") { s.call(f) } }).call("spec/spec_helper.rb") } +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') describe Puppet::Type.type(:selmodule), "when validating attributes" do [:name, :selmoduledir, :selmodulepath].each do |param| diff --git a/spec/unit/type/service_spec.rb b/spec/unit/type/service_spec.rb index 0958a69fa..b11c4d7e7 100755 --- a/spec/unit/type/service_spec.rb +++ b/spec/unit/type/service_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') describe Puppet::Type.type(:service) do it "should have an :enableable feature that requires the :enable, :disable, and :enabled? methods" do @@ -66,6 +66,10 @@ describe Puppet::Type.type(:service), "when validating attribute values" do Puppet::Type.type(:service).new(:name => "yay", :hasstatus => :false) end + it "should specify :true as the default value of hasstatus" do + Puppet::Type.type(:service).new(:name => "yay")[:hasstatus].should == :true + end + it "should support :true as a value to :hasrestart" do Puppet::Type.type(:service).new(:name => "yay", :hasrestart => :true) end diff --git a/spec/unit/type/ssh_authorized_key_spec.rb b/spec/unit/type/ssh_authorized_key_spec.rb index 666616c03..287fca3ab 100755 --- a/spec/unit/type/ssh_authorized_key_spec.rb +++ b/spec/unit/type/ssh_authorized_key_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') ssh_authorized_key = Puppet::Type.type(:ssh_authorized_key) diff --git a/spec/unit/type/sshkey_spec.rb b/spec/unit/type/sshkey_spec.rb new file mode 100644 index 000000000..8315d7ba9 --- /dev/null +++ b/spec/unit/type/sshkey_spec.rb @@ -0,0 +1,71 @@ +#!/usr/bin/env ruby + +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') + +sshkey = Puppet::Type.type(:sshkey) + +describe sshkey do + before do + @class = sshkey + end + + it "should have :name its namevar" do + @class.key_attributes.should == [:name] + end + + describe "when validating attributes" do + [:name, :provider].each do |param| + it "should have a #{param} parameter" do + @class.attrtype(param).should == :param + end + end + + [:host_aliases, :ensure, :key, :type].each do |property| + it "should have a #{property} property" do + @class.attrtype(property).should == :property + end + end + end + + describe "when validating values" do + + it "should support ssh-dss as a type value" do + proc { @class.new(:name => "foo", :type => "ssh-dss") }.should_not raise_error + end + + it "should support ssh-rsa as a type value" do + proc { @class.new(:name => "whev", :type => "ssh-rsa") }.should_not raise_error + end + + it "should alias :dsa to ssh-dss as a value for type" do + key = @class.new(:name => "whev", :type => :dsa) + key.should(:type).should == :'ssh-dss' + end + + it "should alias :rsa to ssh-rsa as a value for type" do + key = @class.new(:name => "whev", :type => :rsa) + key.should(:type).should == :'ssh-rsa' + end + + it "should not support values other than ssh-dss, ssh-rsa, dsa, rsa for type" do + proc { @class.new(:name => "whev", :type => :'ssh-dsa') }.should raise_error(Puppet::Error) + end + + it "should accept one host_alias" do + proc { @class.new(:name => "foo", :host_aliases => 'foo.bar.tld') }.should_not raise_error + end + + it "should accept multiple host_aliases as an array" do + proc { @class.new(:name => "foo", :host_aliases => ['foo.bar.tld','10.0.9.9']) }.should_not raise_error + end + + it "should not accept spaces in any host_alias" do + proc { @class.new(:name => "foo", :host_aliases => ['foo.bar.tld','foo bar']) }.should raise_error(Puppet::Error) + end + + it "should not accept aliases in the resourcename" do + proc { @class.new(:name => 'host,host.domain,ip') }.should raise_error(Puppet::Error) + end + + end +end diff --git a/spec/unit/type/stage_spec.rb b/spec/unit/type/stage_spec.rb index bcde7c4b2..19922f112 100644 --- a/spec/unit/type/stage_spec.rb +++ b/spec/unit/type/stage_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') describe Puppet::Type.type(:stage) do it "should have a 'name' parameter'" do diff --git a/spec/unit/type/tidy_spec.rb b/spec/unit/type/tidy_spec.rb index 11edbfbf3..56bdf6c19 100755 --- a/spec/unit/type/tidy_spec.rb +++ b/spec/unit/type/tidy_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') require 'puppet/file_bucket/dipper' tidy = Puppet::Type.type(:tidy) @@ -110,7 +110,8 @@ describe tidy do :b => 0, :kb => 1, :mb => 2, - :gb => 3 + :gb => 3, + :tb => 4 } convertors.each do |unit, multiple| diff --git a/spec/unit/type/user_spec.rb b/spec/unit/type/user_spec.rb index 5a84af443..6421e6049 100755 --- a/spec/unit/type/user_spec.rb +++ b/spec/unit/type/user_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') user = Puppet::Type.type(:user) diff --git a/spec/unit/type/whit_spec.rb b/spec/unit/type/whit_spec.rb index 998d9df30..0a3324afa 100644 --- a/spec/unit/type/whit_spec.rb +++ b/spec/unit/type/whit_spec.rb @@ -1,11 +1,11 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') whit = Puppet::Type.type(:whit).new(:name => "Foo::Bar") describe whit do - it "should stringify as though it were the class it represents" do - whit.to_s.should == "Class[Foo::Bar]" + it "should stringify in a way that users will regognise" do + whit.to_s.should == "(Foo::Bar)" end end diff --git a/spec/unit/type/zfs_spec.rb b/spec/unit/type/zfs_spec.rb index 6b0b17f3a..88193fca3 100755 --- a/spec/unit/type/zfs_spec.rb +++ b/spec/unit/type/zfs_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -Dir.chdir(File.dirname(__FILE__)) { (s = lambda { |f| File.exist?(f) ? require(f) : Dir.chdir("..") { s.call(f) } }).call("spec/spec_helper.rb") } +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') zfs = Puppet::Type.type(:zfs) diff --git a/spec/unit/type/zone_spec.rb b/spec/unit/type/zone_spec.rb index 726ccc28d..e479fb1e9 100755 --- a/spec/unit/type/zone_spec.rb +++ b/spec/unit/type/zone_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -Dir.chdir(File.dirname(__FILE__)) { (s = lambda { |f| File.exist?(f) ? require(f) : Dir.chdir("..") { s.call(f) } }).call("spec/spec_helper.rb") } +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') zone = Puppet::Type.type(:zone) @@ -57,4 +57,24 @@ describe zone do zone.new(:name => "dummy", :path => "/dummy", :ip => "if", :iptype => :exclusive) end + it "should auto-require :dataset entries" do + fs = 'random-pool/some-zfs' + + # ick + provider = stub 'zfs::provider' + provider.stubs(:name).returns(:solaris) + Puppet::Type.type(:zfs).stubs(:defaultprovider).returns(provider) + + catalog = Puppet::Resource::Catalog.new + zfs_instance = Puppet::Type.type(:zfs).new(:name => fs) + catalog.add_resource zfs_instance + + zone_instance = zone.new(:name => "dummy", + :path => "/foo", + :ip => 'en1:1.0.0.0', + :dataset => fs) + catalog.add_resource zone_instance + + catalog.relationship_graph.dependencies(zone_instance).should == [zfs_instance] + end end diff --git a/spec/unit/type/zpool_spec.rb b/spec/unit/type/zpool_spec.rb index be8cb12ba..96e7d548c 100755 --- a/spec/unit/type/zpool_spec.rb +++ b/spec/unit/type/zpool_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -Dir.chdir(File.dirname(__FILE__)) { (s = lambda { |f| File.exist?(f) ? require(f) : Dir.chdir("..") { s.call(f) } }).call("spec/spec_helper.rb") } +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') zpool = Puppet::Type.type(:zpool) diff --git a/spec/unit/type_spec.rb b/spec/unit/type_spec.rb index 9b1f20500..f9372fced 100755 --- a/spec/unit/type_spec.rb +++ b/spec/unit/type_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.expand_path(File.join(File.dirname(__FILE__), '/../spec_helper')) +require File.expand_path(File.dirname(__FILE__) + '/../spec_helper') describe Puppet::Type do it "should include the Cacher module" do diff --git a/spec/unit/util/autoload/file_cache_spec.rb b/spec/unit/util/autoload/file_cache_spec.rb index c94ec7110..5ad820e4c 100755 --- a/spec/unit/util/autoload/file_cache_spec.rb +++ b/spec/unit/util/autoload/file_cache_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') require 'puppet/util/autoload/file_cache' class FileCacheTester diff --git a/spec/unit/util/autoload_spec.rb b/spec/unit/util/autoload_spec.rb index eb0b705f4..808885dd7 100755 --- a/spec/unit/util/autoload_spec.rb +++ b/spec/unit/util/autoload_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -Dir.chdir(File.dirname(__FILE__)) { (s = lambda { |f| File.exist?(f) ? require(f) : Dir.chdir("..") { s.call(f) } }).call("spec/spec_helper.rb") } +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') require 'puppet/util/autoload' diff --git a/spec/unit/util/backups_spec.rb b/spec/unit/util/backups_spec.rb index 259b18652..3d707a58c 100755 --- a/spec/unit/util/backups_spec.rb +++ b/spec/unit/util/backups_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') require 'puppet/util/backups' diff --git a/spec/unit/util/cache_accumulator_spec.rb b/spec/unit/util/cache_accumulator_spec.rb index 469522ae8..4ed9abf5c 100644 --- a/spec/unit/util/cache_accumulator_spec.rb +++ b/spec/unit/util/cache_accumulator_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') require 'puppet/util/rails/cache_accumulator' describe Puppet::Util::CacheAccumulator do diff --git a/spec/unit/util/cacher_spec.rb b/spec/unit/util/cacher_spec.rb index 89783ed27..125382e84 100755 --- a/spec/unit/util/cacher_spec.rb +++ b/spec/unit/util/cacher_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') require 'puppet/util/cacher' diff --git a/spec/unit/util/checksums_spec.rb b/spec/unit/util/checksums_spec.rb index a8bc12be2..954dc650b 100755 --- a/spec/unit/util/checksums_spec.rb +++ b/spec/unit/util/checksums_spec.rb @@ -3,7 +3,7 @@ # Created by Luke Kanies on 2007-9-22. # Copyright (c) 2007. All rights reserved. -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') require 'puppet/util/checksums' diff --git a/spec/unit/util/command_line_spec.rb b/spec/unit/util/command_line_spec.rb index 98ddb92f6..a7d261dcf 100755 --- a/spec/unit/util/command_line_spec.rb +++ b/spec/unit/util/command_line_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -Dir.chdir(File.dirname(__FILE__)) { (s = lambda { |f| File.exist?(f) ? require(f) : Dir.chdir("..") { s.call(f) } }).call("spec/spec_helper.rb") } +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') require 'puppet/util/command_line' diff --git a/spec/unit/util/constant_inflector_spec.rb b/spec/unit/util/constant_inflector_spec.rb index 423ca8f2e..29574fd5b 100755 --- a/spec/unit/util/constant_inflector_spec.rb +++ b/spec/unit/util/constant_inflector_spec.rb @@ -3,7 +3,7 @@ # Created by Luke Kanies on 2008-02-12. # Copyright (c) 2007. All rights reserved. -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') require 'puppet/util/constant_inflector' diff --git a/spec/unit/util/errors_spec.rb b/spec/unit/util/errors_spec.rb index 2500403d0..da1b8b0bd 100755 --- a/spec/unit/util/errors_spec.rb +++ b/spec/unit/util/errors_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -Dir.chdir(File.dirname(__FILE__)) { (s = lambda { |f| File.exist?(f) ? require(f) : Dir.chdir("..") { s.call(f) } }).call("spec/spec_helper.rb") } +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') require 'puppet/util/errors' diff --git a/spec/unit/util/feature_spec.rb b/spec/unit/util/feature_spec.rb index 8cedade7d..365428752 100755 --- a/spec/unit/util/feature_spec.rb +++ b/spec/unit/util/feature_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -Dir.chdir(File.dirname(__FILE__)) { (s = lambda { |f| File.exist?(f) ? require(f) : Dir.chdir("..") { s.call(f) } }).call("spec/spec_helper.rb") } +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') require 'puppet/util/feature' diff --git a/spec/unit/util/file_locking_spec.rb b/spec/unit/util/file_locking_spec.rb index 8fafb1d52..e9dbe9d7b 100755 --- a/spec/unit/util/file_locking_spec.rb +++ b/spec/unit/util/file_locking_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -Dir.chdir(File.dirname(__FILE__)) { (s = lambda { |f| File.exist?(f) ? require(f) : Dir.chdir("..") { s.call(f) } }).call("spec/spec_helper.rb") } +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') require 'puppet/util/file_locking' diff --git a/spec/unit/util/filetype_spec.rb b/spec/unit/util/filetype_spec.rb index 68ef9d6eb..012631b91 100644 --- a/spec/unit/util/filetype_spec.rb +++ b/spec/unit/util/filetype_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -Dir.chdir(File.dirname(__FILE__)) { (s = lambda { |f| File.exist?(f) ? require(f) : Dir.chdir("..") { s.call(f) } }).call("spec/spec_helper.rb") } +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') require 'puppet/util/filetype' diff --git a/spec/unit/util/inline_docs_spec.rb b/spec/unit/util/inline_docs_spec.rb index edfa405a1..75afb57cb 100755 --- a/spec/unit/util/inline_docs_spec.rb +++ b/spec/unit/util/inline_docs_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -Dir.chdir(File.dirname(__FILE__)) { (s = lambda { |f| File.exist?(f) ? require(f) : Dir.chdir("..") { s.call(f) } }).call("spec/spec_helper.rb") } +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') require 'puppet/util/inline_docs' diff --git a/spec/unit/util/ldap/connection_spec.rb b/spec/unit/util/ldap/connection_spec.rb index 557c42eaa..91f008a2e 100755 --- a/spec/unit/util/ldap/connection_spec.rb +++ b/spec/unit/util/ldap/connection_spec.rb @@ -3,7 +3,7 @@ # Created by Luke Kanies on 2008-3-19. # Copyright (c) 2006. All rights reserved. -require File.dirname(__FILE__) + '/../../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') require 'puppet/util/ldap/connection' diff --git a/spec/unit/util/ldap/generator_spec.rb b/spec/unit/util/ldap/generator_spec.rb index 1630cd183..59c05b7c7 100755 --- a/spec/unit/util/ldap/generator_spec.rb +++ b/spec/unit/util/ldap/generator_spec.rb @@ -3,7 +3,7 @@ # Created by Luke Kanies on 2008-3-28. # Copyright (c) 2008. All rights reserved. -require File.dirname(__FILE__) + '/../../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') require 'puppet/util/ldap/generator' diff --git a/spec/unit/util/ldap/manager_spec.rb b/spec/unit/util/ldap/manager_spec.rb index ba693d562..e91582c8d 100755 --- a/spec/unit/util/ldap/manager_spec.rb +++ b/spec/unit/util/ldap/manager_spec.rb @@ -3,7 +3,7 @@ # Created by Luke Kanies on 2008-3-19. # Copyright (c) 2006. All rights reserved. -require File.dirname(__FILE__) + '/../../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') require 'puppet/util/ldap/manager' diff --git a/spec/unit/util/loadedfile_spec.rb b/spec/unit/util/loadedfile_spec.rb index c6fd625fc..92daeb953 100755 --- a/spec/unit/util/loadedfile_spec.rb +++ b/spec/unit/util/loadedfile_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') require 'tempfile' require 'puppet/util/loadedfile' diff --git a/spec/unit/util/log/destinations_spec.rb b/spec/unit/util/log/destinations_spec.rb index 710a51725..b84c2ab44 100755 --- a/spec/unit/util/log/destinations_spec.rb +++ b/spec/unit/util/log/destinations_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') require 'puppet/util/log' diff --git a/spec/unit/util/log_spec.rb b/spec/unit/util/log_spec.rb index 4a30d5086..3c8577493 100755 --- a/spec/unit/util/log_spec.rb +++ b/spec/unit/util/log_spec.rb @@ -1,13 +1,13 @@ #!/usr/bin/env ruby -Dir.chdir(File.dirname(__FILE__)) { (s = lambda { |f| File.exist?(f) ? require(f) : Dir.chdir("..") { s.call(f) } }).call("spec/spec_helper.rb") } +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') require 'puppet/util/log' describe Puppet::Util::Log do it "should write a given message to the specified destination" do arraydest = [] - Puppet::Util::Log.newdestination(arraydest) + Puppet::Util::Log.newdestination(Puppet::Test::LogCollector.new(arraydest)) Puppet::Util::Log.new(:level => :notice, :message => "foo") message = arraydest.last.message message.should == "foo" @@ -87,7 +87,7 @@ describe Puppet::Util::Log do it "should flush the log queue when the first destination is specified" do Puppet::Util::Log.close_all Puppet::Util::Log.expects(:flushqueue) - Puppet::Util::Log.newdestination([]) + Puppet::Util::Log.newdestination(:console) end it "should convert the level to a symbol if it's passed in as a string" do diff --git a/spec/unit/util/logging_spec.rb b/spec/unit/util/logging_spec.rb index 411cd17a9..97ffc0b25 100755 --- a/spec/unit/util/logging_spec.rb +++ b/spec/unit/util/logging_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -Dir.chdir(File.dirname(__FILE__)) { (s = lambda { |f| File.exist?(f) ? require(f) : Dir.chdir("..") { s.call(f) } }).call("spec/spec_helper.rb") } +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') require 'puppet/util/logging' diff --git a/spec/unit/util/metric_spec.rb b/spec/unit/util/metric_spec.rb index 600b88f85..425812297 100755 --- a/spec/unit/util/metric_spec.rb +++ b/spec/unit/util/metric_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -Dir.chdir(File.dirname(__FILE__)) { (s = lambda { |f| File.exist?(f) ? require(f) : Dir.chdir("..") { s.call(f) } }).call("spec/spec_helper.rb") } +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') require 'puppet/util/metric' diff --git a/spec/unit/util/monkey_patches_spec.rb b/spec/unit/util/monkey_patches_spec.rb index b0f61c808..8bfcd900e 100644 --- a/spec/unit/util/monkey_patches_spec.rb +++ b/spec/unit/util/monkey_patches_spec.rb @@ -1,7 +1,33 @@ #!/usr/bin/env ruby -Dir.chdir(File.dirname(__FILE__)) { (s = lambda { |f| File.exist?(f) ? require(f) : Dir.chdir("..") { s.call(f) } }).call("spec/spec_helper.rb") } +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') require 'puppet/util/monkey_patches' + +describe "yaml deserialization" do + it "should call yaml_initialize when deserializing objects that have that method defined" do + class Puppet::TestYamlInitializeClass + attr_reader :foo + + def yaml_initialize(tag, var) + var.should == {'foo' => 100} + instance_variables.should == [] + @foo = 200 + end + end + + obj = YAML.load("--- !ruby/object:Puppet::TestYamlInitializeClass\n foo: 100") + obj.foo.should == 200 + end + + it "should not call yaml_initialize if not defined" do + class Puppet::TestYamlNonInitializeClass + attr_reader :foo + end + + obj = YAML.load("--- !ruby/object:Puppet::TestYamlNonInitializeClass\n foo: 100") + obj.foo.should == 100 + end +end diff --git a/spec/unit/util/nagios_maker_spec.rb b/spec/unit/util/nagios_maker_spec.rb index 5cda98738..20582525d 100755 --- a/spec/unit/util/nagios_maker_spec.rb +++ b/spec/unit/util/nagios_maker_spec.rb @@ -3,7 +3,7 @@ # Created by Luke Kanies on 2007-11-18. # Copyright (c) 2007. All rights reserved. -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') require 'puppet/util/nagios_maker' diff --git a/spec/unit/util/package_spec.rb b/spec/unit/util/package_spec.rb index 09b222194..e72a7ae91 100644 --- a/spec/unit/util/package_spec.rb +++ b/spec/unit/util/package_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') require 'puppet/util/package' diff --git a/spec/unit/util/posix_spec.rb b/spec/unit/util/posix_spec.rb index dbc90d9d0..6d7351220 100755 --- a/spec/unit/util/posix_spec.rb +++ b/spec/unit/util/posix_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -Dir.chdir(File.dirname(__FILE__)) { (s = lambda { |f| File.exist?(f) ? require(f) : Dir.chdir("..") { s.call(f) } }).call("spec/spec_helper.rb") } +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') require 'puppet/util/posix' diff --git a/spec/unit/util/pson_spec.rb b/spec/unit/util/pson_spec.rb index 474ddafa4..08758ee38 100755 --- a/spec/unit/util/pson_spec.rb +++ b/spec/unit/util/pson_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -Dir.chdir(File.dirname(__FILE__)) { (s = lambda { |f| File.exist?(f) ? require(f) : Dir.chdir("..") { s.call(f) } }).call("spec/spec_helper.rb") } +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') require 'puppet/util/pson' diff --git a/spec/unit/util/queue/stomp_spec.rb b/spec/unit/util/queue/stomp_spec.rb index c33f1a670..a11d5324e 100755 --- a/spec/unit/util/queue/stomp_spec.rb +++ b/spec/unit/util/queue/stomp_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') require 'puppet/util/queue' describe Puppet::Util::Queue, :if => Puppet.features.stomp? do diff --git a/spec/unit/util/queue_spec.rb b/spec/unit/util/queue_spec.rb index 571bddda4..d356fd7bb 100755 --- a/spec/unit/util/queue_spec.rb +++ b/spec/unit/util/queue_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') require 'puppet/util/queue' require 'spec/mocks' diff --git a/spec/unit/util/rdoc/parser_spec.rb b/spec/unit/util/rdoc/parser_spec.rb index 6ae28b40a..f118dc99b 100755 --- a/spec/unit/util/rdoc/parser_spec.rb +++ b/spec/unit/util/rdoc/parser_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -Dir.chdir(File.dirname(__FILE__)) { (s = lambda { |f| File.exist?(f) ? require(f) : Dir.chdir("..") { s.call(f) } }).call("spec/spec_helper.rb") } +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') require 'puppet/resource/type_collection' require 'puppet/util/rdoc/parser' @@ -20,7 +20,7 @@ describe RDoc::Parser do @parser.stubs(:scan_top_level) parser = stub 'parser' Puppet::Parser::Parser.stubs(:new).returns(parser) - parser.expects(:parse).at_least_once + parser.expects(:parse).returns(Puppet::Parser::AST::Hostclass.new('')).at_least_once parser.expects(:file=).with("module/manifests/init.pp") parser.expects(:file=).with("/dev/null/manifests/site.pp") @@ -30,6 +30,7 @@ describe RDoc::Parser do it "should scan the ast for Puppet files" do parser = stub_everything 'parser' Puppet::Parser::Parser.stubs(:new).returns(parser) + parser.expects(:parse).returns(Puppet::Parser::AST::Hostclass.new('')).at_least_once @parser.expects(:scan_top_level) @@ -39,6 +40,7 @@ describe RDoc::Parser do it "should return a PuppetTopLevel to RDoc" do parser = stub_everything 'parser' Puppet::Parser::Parser.stubs(:new).returns(parser) + parser.expects(:parse).returns(Puppet::Parser::AST::Hostclass.new('')).at_least_once @parser.expects(:scan_top_level) @@ -60,8 +62,8 @@ describe RDoc::Parser do describe "when scanning top level entities" do before :each do - @resource_type_collection = stub_everything 'resource_type_collection' - @parser.ast = @resource_type_collection + @resource_type_collection = resource_type_collection = stub_everything('resource_type_collection') + @parser.instance_eval { @known_resource_types = resource_type_collection } @parser.stubs(:split_module).returns("module") @topcontainer = stub_everything 'topcontainer' @@ -154,8 +156,8 @@ describe RDoc::Parser do @definition = stub_everything 'definition', :file => "module/manifests/init.pp", :type => :definition, :name => "mydef" @node = stub_everything 'node', :file => "module/manifests/init.pp", :type => :node, :name => "mynode" - @resource_type_collection = Puppet::Resource::TypeCollection.new("env") - @parser.ast = @resource_type_collection + @resource_type_collection = resource_type_collection = Puppet::Resource::TypeCollection.new("env") + @parser.instance_eval { @known_resource_types = resource_type_collection } @container = stub_everything 'container' end @@ -450,9 +452,13 @@ describe RDoc::Parser do @class = stub_everything 'class' @stmt = Puppet::Parser::AST::Resource.new( :type => "File", - :title => "myfile", - :doc => 'mydoc', - :parameters => Puppet::Parser::AST::ASTArray.new(:children => []) + :instances => Puppet::Parser::AST::ASTArray.new(:children => [ + Puppet::Parser::AST::ResourceInstance.new( + :title => Puppet::Parser::AST::Name.new(:value => "myfile"), + :parameters => Puppet::Parser::AST::ASTArray.new(:children => []) + ) + ]), + :doc => 'mydoc' ) @code = stub_everything 'code' diff --git a/spec/unit/util/rdoc_spec.rb b/spec/unit/util/rdoc_spec.rb index 41d4b9cd0..3b5248528 100755 --- a/spec/unit/util/rdoc_spec.rb +++ b/spec/unit/util/rdoc_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -Dir.chdir(File.dirname(__FILE__)) { (s = lambda { |f| File.exist?(f) ? require(f) : Dir.chdir("..") { s.call(f) } }).call("spec/spec_helper.rb") } +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') require 'puppet/util/rdoc' require 'rdoc/rdoc' @@ -123,63 +123,25 @@ describe Puppet::Util::RDoc do end describe "when outputing documentation" do - before :each do - @node = stub 'node', :file => "file", :line => 1, :doc => "" - @class = stub 'class', :file => "file", :line => 4, :doc => "" - @definition = stub 'definition', :file => "file", :line => 3, :doc => "" - @ast = stub 'ast', :nodes => { :node => @node }, :hostclasses => { :class => @class }, :definitions => { :definition => @definition } - end - - it "should output doc for ast nodes" do - @node.expects(:doc) - - Puppet::Util::RDoc.output("file", @ast) - end - - it "should output doc for ast classes" do - @class.expects(:doc) - - Puppet::Util::RDoc.output("file", @ast) - end - - it "should output doc for ast definitions" do - @definition.expects(:doc) - - Puppet::Util::RDoc.output("file", @ast) - end - - it "should output doc in order of increasing line number" do - byline = sequence('byline') - @node.expects(:doc).in_sequence(byline) - @definition.expects(:doc).in_sequence(byline) - @class.expects(:doc).in_sequence(byline) - - Puppet::Util::RDoc.output("file", @ast) - end - - it "should not output documentation of ast object of another node" do - klass = stub 'otherclass', :file => "otherfile", :line => 12, :doc => "" - @ast.stubs(:hostclasses).returns({ :otherclass => klass }) - - klass.expects(:doc).never - - Puppet::Util::RDoc.output("file", @ast) + it "should output doc for ast classes, nodes and definitions in order of increasing line number" do + byline = sequence('documentation outputs in line order') + Puppet::Util::RDoc.expects(:puts).with("im a class\n").in_sequence(byline) + Puppet::Util::RDoc.expects(:puts).with("im a node\n").in_sequence(byline) + Puppet::Util::RDoc.expects(:puts).with("im a define\n").in_sequence(byline) + # any other output must fail + Puppet::Util::RDoc.manifestdoc([my_fixture('basic.pp')]) end it "should output resource documentation if needed" do - Puppet.settings.stubs(:[]).with(:document_all).returns(true) - [@node,@definition].each do |o| - o.stubs(:code).returns([]) - end - - resource = stub_everything 'resource', :line => 1 - resource.stubs(:is_a?).with(Puppet::Parser::AST::ASTArray).returns(false) - resource.stubs(:is_a?).with(Puppet::Parser::AST::Resource).returns(true) - @class.stubs(:code).returns([resource]) - - resource.expects(:doc) - - Puppet::Util::RDoc.output("file", @ast) + pending "#6634 being fixed" + Puppet.settings[:document_all] = true + byline = sequence('documentation outputs in line order') + Puppet::Util::RDoc.expects(:puts).with("im a class\n").in_sequence(byline) + Puppet::Util::RDoc.expects(:puts).with("im a node\n").in_sequence(byline) + Puppet::Util::RDoc.expects(:puts).with("im a define\n").in_sequence(byline) + Puppet::Util::RDoc.expects(:puts).with("im a resource\n").in_sequence(byline) + # any other output must fail + Puppet::Util::RDoc.manifestdoc([my_fixture('basic.pp')]) end end end diff --git a/spec/unit/util/reference_serializer_spec.rb b/spec/unit/util/reference_serializer_spec.rb index 6e7d8a674..f72715ed6 100644 --- a/spec/unit/util/reference_serializer_spec.rb +++ b/spec/unit/util/reference_serializer_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') require 'puppet/util/rails/reference_serializer' class SerializeTester diff --git a/spec/unit/util/resource_template_spec.rb b/spec/unit/util/resource_template_spec.rb index 2eab2cfcb..e823a9ff4 100755 --- a/spec/unit/util/resource_template_spec.rb +++ b/spec/unit/util/resource_template_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') require 'puppet/util/resource_template' diff --git a/spec/unit/util/run_mode_spec.rb b/spec/unit/util/run_mode_spec.rb index d6ab08a10..1956973ea 100644 --- a/spec/unit/util/run_mode_spec.rb +++ b/spec/unit/util/run_mode_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') describe Puppet::Util::RunMode do before do diff --git a/spec/unit/util/selinux_spec.rb b/spec/unit/util/selinux_spec.rb index e92784386..c18be0c2f 100755 --- a/spec/unit/util/selinux_spec.rb +++ b/spec/unit/util/selinux_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') require 'puppet/util/selinux' include Puppet::Util::SELinux diff --git a/spec/unit/util/settings/file_setting_spec.rb b/spec/unit/util/settings/file_setting_spec.rb index dcfb6e3b1..a2049e2ad 100755 --- a/spec/unit/util/settings/file_setting_spec.rb +++ b/spec/unit/util/settings/file_setting_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') require 'puppet/util/settings' require 'puppet/util/settings/file_setting' diff --git a/spec/unit/util/settings_spec.rb b/spec/unit/util/settings_spec.rb index 07b712c08..2ab31c294 100755 --- a/spec/unit/util/settings_spec.rb +++ b/spec/unit/util/settings_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') describe Puppet::Util::Settings do describe "when specifying defaults" do diff --git a/spec/unit/util/storage_spec.rb b/spec/unit/util/storage_spec.rb index ae3cbc2ae..5359f746f 100755 --- a/spec/unit/util/storage_spec.rb +++ b/spec/unit/util/storage_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') require 'yaml' require 'puppet/util/storage' diff --git a/spec/unit/util/tagging_spec.rb b/spec/unit/util/tagging_spec.rb index 8fd8552b8..5231be2eb 100755 --- a/spec/unit/util/tagging_spec.rb +++ b/spec/unit/util/tagging_spec.rb @@ -3,7 +3,7 @@ # Created by Luke Kanies on 2008-01-19. # Copyright (c) 2007. All rights reserved. -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') require 'puppet/util/tagging' diff --git a/spec/unit/util/user_attr_spec.rb b/spec/unit/util/user_attr_spec.rb index 61312ef19..5acdaee58 100644 --- a/spec/unit/util/user_attr_spec.rb +++ b/spec/unit/util/user_attr_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -Dir.chdir(File.dirname(__FILE__)) { (s = lambda { |f| File.exist?(f) ? require(f) : Dir.chdir("..") { s.call(f) } }).call("spec/spec_helper.rb") } +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') require 'puppet/util/user_attr' diff --git a/spec/unit/util/warnings_spec.rb b/spec/unit/util/warnings_spec.rb index c05c9837b..a3460bccf 100755 --- a/spec/unit/util/warnings_spec.rb +++ b/spec/unit/util/warnings_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') describe Puppet::Util::Warnings do before(:all) do diff --git a/spec/unit/util/zaml_spec.rb b/spec/unit/util/zaml_spec.rb index fd506ea93..804aa8e58 100755 --- a/spec/unit/util/zaml_spec.rb +++ b/spec/unit/util/zaml_spec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -Dir.chdir(File.dirname(__FILE__)) { (s = lambda { |f| File.exist?(f) ? require(f) : Dir.chdir("..") { s.call(f) } }).call("spec/spec_helper.rb") } +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') require 'puppet/util/monkey_patches' @@ -36,55 +36,28 @@ describe "Pure ruby yaml implementation" do end } - def set_of_lines(l) - l.split("\n").sort + it "should emit proper labels and backreferences for common objects" do + # Note: this test makes assumptions about the names ZAML chooses + # for labels. + x = [1, 2] + y = [3, 4] + z = [x, y, x, y] + z.to_yaml.should == "--- \n - &id001\n - 1\n - 2\n - &id002\n - 3\n - 4\n - *id001\n - *id002" + z2 = YAML.load(z.to_yaml) + z2.should == z + z2[0].should equal(z2[2]) + z2[1].should equal(z2[3]) end - it "should handle references to Array in Hash values correctly" do - list = [1] - data = { "one" => list, "two" => list } - data.to_yaml.should == "--- \n two: &id001 \n - 1\n one: *id001" - expect { YAML.load(data.to_yaml).should == data }.should_not raise_error + it "should emit proper labels and backreferences for recursive objects" do + x = [1, 2] + x << x + x.to_yaml.should == "--- &id001\n \n - 1\n - 2\n - *id001" + x2 = YAML.load(x.to_yaml) + x2.should be_a(Array) + x2.length.should == 3 + x2[0].should == 1 + x2[1].should == 2 + x2[2].should equal(x2) end - - it "should handle references to Hash in Hash values correctly" do - hash = { 1 => 1 } - data = { "one" => hash, "two" => hash } - # This could still someday fail because the order change would also change which one got the back ref - set_of_lines(data.to_yaml).should == set_of_lines("--- \n two: &id001 \n 1: 1\n one: *id001") - expect { YAML.load(data.to_yaml).should == data }.should_not raise_error - end - - it "should handle references to Scalar in Hash" do - str = "hello" - data = { "one" => str, "two" => str } - set_of_lines(data.to_yaml).should == set_of_lines("--- \n two: hello\n one: hello") - expect { YAML.load(data.to_yaml).should == data }.should_not raise_error - end - - class Zaml_test_class_A - attr_reader :false,:true - def initialize - @false = @true = 7 - end - end - it "should not blow up when magic strings are used as field names" do - data = Zaml_test_class_A.new - data.to_yaml.should == %Q{--- !ruby/object:Zaml_test_class_A\n \"false\": 7\n \"true\": 7} - expect { - r = YAML.load(data.to_yaml) - r.class.should == data.class - r.true.should == data.true - r.false.should == data.false - }.should_not raise_error - end - - it "should not blow up on back references inside arrays" do - s = [1,2] - data = [s,s] - data.to_yaml.should == %Q{--- \n - &id001 \n - 1\n - 2\n - *id001} - expect { YAML.load(data.to_yaml).should == data }.should_not raise_error - end - end - diff --git a/tasks/rake/gem.rake b/tasks/rake/gem.rake index d654886ae..efea73882 100644 --- a/tasks/rake/gem.rake +++ b/tasks/rake/gem.rake @@ -1,4 +1,4 @@ -require 'ftools' +require 'fileutils' GEM_FILES = FileList[ '[A-Z]*', @@ -44,7 +44,7 @@ end desc "Prepare binaries for gem creation" task :prepare_gem do SBIN.each do |f| - File.copy(f,"bin") + FileUtils.copy(f,"bin") end end @@ -52,8 +52,9 @@ desc "Create the gem" task :create_gem => :prepare_gem do Dir.mkdir("pkg") rescue nil Gem::Builder.new(spec).build - File.move("puppet-#{Puppet::PUPPETVERSION}.gem", "pkg") + FileUtils.move("puppet-#{Puppet::PUPPETVERSION}.gem", "pkg") SBIN.each do |f| - File.unlink("bin/" + f.gsub(/sbin\//, '')) + fn = f.gsub(/sbin\/(.*)/, '\1') + FileUtils.rm_r "bin/" + fn end end diff --git a/tasks/rake/git_workflow.rake b/tasks/rake/git_workflow.rake index f2ae7ee69..56a414568 100644 --- a/tasks/rake/git_workflow.rake +++ b/tasks/rake/git_workflow.rake @@ -5,82 +5,82 @@ def find_start(start) # This is a case statement, as we might want to map certain # git tags to starting points that are not currently in git. - case start - when nil?: - when @next_release: return "master" - else return start - end + case start + when nil?; + when @next_release; return "master" + else return start + end end desc "Set up git for working with Puppet" task :git_setup do - # This should be changed as new versions get released - @next_release = '0.26.x' - @remote = {} - default_remote = {} - default_remote[:url] = 'git://github.com/reductivelabs/puppet' - default_remote[:name] = 'origin' - @remote[:name] = %x{git config puppet.defaultremote}.chomp - @remote[:name] = @remote[:name].empty? ? default_remote[:name] : @remote[:name] - @remote[:url] = default_remote[:url] if @remote[:name] == default_remote[:name] - default_fetch = '+refs/heads/*:refs/remotes/puppet/*' - @remote[:fetch] = %x{git config puppet.#{@remote[:name]}.fetch}.chomp - @remote[:fetch] = @remote[:fetch].empty? ? default_fetch : @remote[:fetch] + # This should be changed as new versions get released + @next_release = '0.26.x' + @remote = {} + default_remote = {} + default_remote[:url] = 'git://github.com/reductivelabs/puppet' + default_remote[:name] = 'origin' + @remote[:name] = %x{git config puppet.defaultremote}.chomp + @remote[:name] = @remote[:name].empty? ? default_remote[:name] : @remote[:name] + @remote[:url] = default_remote[:url] if @remote[:name] == default_remote[:name] + default_fetch = '+refs/heads/*:refs/remotes/puppet/*' + @remote[:fetch] = %x{git config puppet.#{@remote[:name]}.fetch}.chomp + @remote[:fetch] = @remote[:fetch].empty? ? default_fetch : @remote[:fetch] end desc "Start work on a feature" task :start_feature, [:feature,:remote,:branch] => :git_setup do |t, args| - args.with_defaults(:remote => @remote[:name]) - args.with_defaults(:branch => @next_release) - start_at = find_start(args.branch) - branch = "feature/#{start_at}/#{args.feature}" - sh "git checkout -b #{branch} #{start_at}" do |ok, res| - if ! ok - raise <<EOS + args.with_defaults(:remote => @remote[:name]) + args.with_defaults(:branch => @next_release) + start_at = find_start(args.branch) + branch = "feature/#{start_at}/#{args.feature}" + sh "git checkout -b #{branch} #{start_at}" do |ok, res| + if ! ok + raise <<EOS Was not able to create branch for #{args.feature} on branch #{args.branch}, starting at #{start_at}: error code was: #{res.exitstatus} EOS - end - end - sh "git config branch.#{branch}.remote #{args.remote}" do |ok, res| - raise "Could not set remote: #{$?}" unless ok - end - - sh "git config branch.#{branch}.merge refs/heads/#{branch}" do |ok, res| - raise "Could not configure merge: #{$?}" unless ok - end + end + end + sh "git config branch.#{branch}.remote #{args.remote}" do |ok, res| + raise "Could not set remote: #{$?}" unless ok + end + + sh "git config branch.#{branch}.merge refs/heads/#{branch}" do |ok, res| + raise "Could not configure merge: #{$?}" unless ok + end end desc "Do git prep to start work on a Redmine ticket" task :start_ticket, [:ticket, :remote, :branch] => :git_setup do |t, args| - args.with_defaults(:remote => @remote[:name]) - args.with_defaults(:branch => @next_release) - start_at = find_start(args.branch) - branch = "tickets/#{start_at}/#{args.ticket}" - sh "git checkout -b #{branch} #{start_at}" do |ok, res| - unless ok - raise <<EOS + args.with_defaults(:remote => @remote[:name]) + args.with_defaults(:branch => @next_release) + start_at = find_start(args.branch) + branch = "tickets/#{start_at}/#{args.ticket}" + sh "git checkout -b #{branch} #{start_at}" do |ok, res| + unless ok + raise <<EOS Was not able to create branch for ticket #{args.ticket} on branch #{args.branch}, starting at #{start_at}: error code was: #{$?} Git command used was: #{command} EOS - end - end + end + end sh "git config branch.#{branch}.remote #{args.remote}" do |ok, res| - raise "Could not set remote: #{$?}" unless ok - end + raise "Could not set remote: #{$?}" unless ok + end sh "git config branch.#{branch}.merge refs/heads/#{branch}" do |ok, res| - raise "Could not configure merge: #{$?}" unless ok - end + raise "Could not configure merge: #{$?}" unless ok + end end # This isn't very useful by itself, but we might enhance it later, or use it # in a dependency for a more complex task. desc "Push out changes" task :push_changes, [:remote] do |t, arg| - branch = %x{git branch | grep "^" | awk '{print $2}'} - sh "git push #{arg.remote} #{branch}" do |ok, res| - raise "Unable to push to #{arg.remote}" unless ok - end + branch = %x{git branch | grep "^" | awk '{print $2}'} + sh "git push #{arg.remote} #{branch}" do |ok, res| + raise "Unable to push to #{arg.remote}" unless ok + end end desc "Send patch information to the puppet-dev list" @@ -103,10 +103,21 @@ task :mail_patches do # Create all of the patches sh "git format-patch -C -M -s -n --subject-prefix='PATCH/puppet' #{parent}..HEAD" + # Add info to the patches + additional_info = "Local-branch: #{branch}\n" + files = Dir.glob("00*.patch") + files.each do |file| + contents = File.read(file) + contents.sub!(/^---\n/, "---\n#{additional_info}") + File.open(file, 'w') do |file_handle| + file_handle.print contents + end + end + # And then mail them out. # If we've got more than one patch, add --compose - if Dir.glob("00*.patch").length > 1 + if files.length > 1 compose = "--compose" subject = "--subject \"#{type} #{name} against #{parent}\"" else diff --git a/tasks/rake/manpages.rake b/tasks/rake/manpages.rake new file mode 100644 index 000000000..f7275e4c3 --- /dev/null +++ b/tasks/rake/manpages.rake @@ -0,0 +1,37 @@ +# require 'fileutils' + +desc "Build Puppet manpages" +task :gen_manpages do + + sbins = Dir.glob(%w{sbin/*}) + bins = Dir.glob(%w{bin/*}) + applications = Dir.glob(%w{lib/puppet/application/*}) + # Locate ronn + ronn = %x{which ronn}.chomp + unless File.executable?(ronn) then fail("Ronn does not appear to be installed.") end + + # Create puppet.conf.5 man page + %x{RUBYLIB=./lib:$RUBYLIB bin/puppetdoc --reference configuration > ./man/man5/puppetconf.5.ronn} + %x{#{ronn} --manual="Puppet manual" --organization="Puppet Labs, LLC" -r ./man/man5/puppetconf.5.ronn} + File.move("./man/man5/puppetconf.5", "./man/man5/puppet.conf.5") + File.unlink("./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} --manual="Puppet manual" --organization="Puppet Labs, LLC" -r ./man/man8/#{b}.8.ronn} + File.unlink("./man/man8/#{b}.8.ronn") + end + + # Create modern binary man pages + applications.each do |app| + app.gsub!( /^lib\/puppet\/application\/(.*?)\.rb/, '\1') + %x{RUBYLIB=./lib:$RUBYLIB bin/puppet #{app} --help > ./man/man8/puppet-#{app}.8.ronn} + %x{#{ronn} --manual="Puppet manual" --organization="Puppet Labs, LLC" -r ./man/man8/puppet-#{app}.8.ronn} + File.unlink("./man/man8/puppet-#{app}.8.ronn") + end + + +end
\ No newline at end of file diff --git a/test/certmgr/certmgr.rb b/test/certmgr/certmgr.rb index b78a138b7..11ecd6307 100755 --- a/test/certmgr/certmgr.rb +++ b/test/certmgr/certmgr.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../lib/puppettest' +require File.expand_path(File.dirname(__FILE__) + '/../lib/puppettest') require 'puppet' require 'puppet/sslcertificates.rb' diff --git a/test/certmgr/inventory.rb b/test/certmgr/inventory.rb index d1ba4c879..fa612b2c1 100755 --- a/test/certmgr/inventory.rb +++ b/test/certmgr/inventory.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../lib/puppettest' +require File.expand_path(File.dirname(__FILE__) + '/../lib/puppettest') require 'puppet' require 'puppettest/certificates' diff --git a/test/certmgr/support.rb b/test/certmgr/support.rb index 060c458d8..f85d54a8a 100755 --- a/test/certmgr/support.rb +++ b/test/certmgr/support.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../lib/puppettest' +require File.expand_path(File.dirname(__FILE__) + '/../lib/puppettest') require 'puppettest' require 'puppet/sslcertificates/support' diff --git a/test/data/providers/host/parsed/valid_hosts b/test/data/providers/host/parsed/valid_hosts new file mode 100644 index 000000000..24636295d --- /dev/null +++ b/test/data/providers/host/parsed/valid_hosts @@ -0,0 +1,19 @@ +# Some leading comment, that should be ignored +# The next line is empty so it should be ignored + +::1 localhost + +# We now try another delimiter: Several tabs +127.0.0.1 localhost + +# No test trailing spaces +10.0.0.1 host1 + +# Ok its time to test aliases +2001:252:0:1::2008:8 ipv6host alias1 +192.168.0.1 ipv4host alias2 alias3 + +# Testing inlinecomments now +192.168.0.2 host3 # This is host3 +192.168.0.3 host4 alias10 # This is host4 +192.168.0.4 host5 alias11 alias12 # This is host5 diff --git a/test/language/ast.rb b/test/language/ast.rb index 10b9fa361..ec20cdb99 100755 --- a/test/language/ast.rb +++ b/test/language/ast.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../lib/puppettest' +require File.expand_path(File.dirname(__FILE__) + '/../lib/puppettest') require 'puppettest' require 'puppet/parser/parser' diff --git a/test/language/ast/variable.rb b/test/language/ast/variable.rb index 8a7738b23..968d1b7c3 100755 --- a/test/language/ast/variable.rb +++ b/test/language/ast/variable.rb @@ -3,7 +3,7 @@ # Created by Luke A. Kanies on 2007-0419. # Copyright (c) 2006. All rights reserved. -require File.dirname(__FILE__) + '/../../lib/puppettest' +require File.expand_path(File.dirname(__FILE__) + '/../../lib/puppettest') require 'puppettest' require 'puppettest/parsertesting' diff --git a/test/language/functions.rb b/test/language/functions.rb index 1d4ed8241..e882b68f3 100755 --- a/test/language/functions.rb +++ b/test/language/functions.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../lib/puppettest' +require File.expand_path(File.dirname(__FILE__) + '/../lib/puppettest') require 'puppet' require 'puppet/parser/parser' @@ -447,11 +447,11 @@ class TestLangFunctions < Test::Unit::TestCase include = Puppet::Parser::Functions.function(:include) - assert_raise(Puppet::ParseError, "did not throw error on missing class") do + assert_raise(Puppet::Error, "did not throw error on missing class") do scope.function_include("nosuchclass") end - parser.newclass("myclass") + scope.known_resource_types.add Puppet::Resource::Type.new(:hostclass, "myclass", {}) scope.compiler.expects(:evaluate_classes).with(%w{myclass otherclass}, scope, false).returns(%w{myclass otherclass}) diff --git a/test/language/parser.rb b/test/language/parser.rb index 8cda8eeb2..36a9c4787 100755 --- a/test/language/parser.rb +++ b/test/language/parser.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../lib/puppettest' +require File.expand_path(File.dirname(__FILE__) + '/../lib/puppettest') require 'mocha' require 'puppet' @@ -39,9 +39,8 @@ class TestParser < Test::Unit::TestCase failers { |file| parser = mkparser Puppet.debug("parsing failer #{file}") if __FILE__ == $0 - assert_raise(Puppet::ParseError, "Did not fail while parsing #{file}") { - parser.file = file - ast = parser.parse + assert_raise(Puppet::ParseError, Puppet::Error, "Did not fail while parsing #{file}") { + Puppet[:manifest] = file config = mkcompiler(parser) config.compile #ast.hostclass("").evaluate config.topscope @@ -288,7 +287,7 @@ class TestParser < Test::Unit::TestCase ret = parser.parse } - ret.hostclass("").code.each do |obj| + ret.code.each do |obj| assert_instance_of(AST::Collection, obj) end end @@ -362,12 +361,12 @@ file { "/tmp/yayness": assert_raise(Puppet::ParseError) { - parser.parse %{define mydef($schedule) {}} + parser.known_resource_types.import_ast(parser.parse(%{define mydef($schedule) {}}), '') } assert_nothing_raised { - parser.parse %{define adef($schedule = false) {}} - parser.parse %{define mydef($schedule = daily) {}} + parser.known_resource_types.import_ast(parser.parse(%{define adef($schedule = false) {}}), '') + parser.known_resource_types.import_ast(parser.parse(%{define mydef($schedule = daily) {}}), '') } end @@ -379,12 +378,12 @@ file { "/tmp/yayness": str1 = %{if true { #{exec.call("true")} }} ret = nil assert_nothing_raised { - ret = parser.parse(str1).hostclass("").code[0] + ret = parser.parse(str1).code[0] } assert_instance_of(Puppet::Parser::AST::IfStatement, ret) parser = mkparser str2 = %{if true { #{exec.call("true")} } else { #{exec.call("false")} }} - ret = parser.parse(str2).hostclass("").code[0] + ret = parser.parse(str2).code[0] assert_instance_of(Puppet::Parser::AST::IfStatement, ret) assert_instance_of(Puppet::Parser::AST::Else, ret.else) end @@ -393,23 +392,23 @@ file { "/tmp/yayness": parser = mkparser assert_nothing_raised { - parser.parse %{class myclass { class other {} }} + parser.known_resource_types.import_ast(parser.parse(%{class myclass { class other {} }}), '') } assert(parser.hostclass("myclass"), "Could not find myclass") assert(parser.hostclass("myclass::other"), "Could not find myclass::other") assert_nothing_raised { - parser.parse "class base {} + parser.known_resource_types.import_ast(parser.parse("class base {} class container { class deep::sub inherits base {} - }" + }"), '') } sub = parser.hostclass("container::deep::sub") assert(sub, "Could not find sub") # Now try it with a parent class being a fq class assert_nothing_raised { - parser.parse "class container::one inherits container::deep::sub {}" + parser.known_resource_types.import_ast(parser.parse("class container::one inherits container::deep::sub {}"), '') } sub = parser.hostclass("container::one") assert(sub, "Could not find one") @@ -417,7 +416,7 @@ file { "/tmp/yayness": # Finally, try including a qualified class assert_nothing_raised("Could not include fully qualified class") { - parser.parse "include container::deep::sub" + parser.known_resource_types.import_ast(parser.parse("include container::deep::sub"), '') } end @@ -426,20 +425,11 @@ file { "/tmp/yayness": # Make sure we put the top-level code into a class called "" in # the "" namespace - assert_nothing_raised do - out = parser.parse "" - - assert_instance_of(Puppet::Resource::TypeCollection, out) - assert_nil(parser.hostclass(""), "Got a 'main' class when we had no code") - end - - # Now try something a touch more complicated parser.initvars assert_nothing_raised do - out = parser.parse "Exec { path => '/usr/bin:/usr/sbin' }" - assert_instance_of(Puppet::Resource::TypeCollection, out) - assert_equal("", parser.hostclass("").name) - assert_equal("", parser.hostclass("").namespace) + parser.known_resource_types.import_ast(parser.parse("Exec { path => '/usr/bin:/usr/sbin' }"), '') + assert_equal("", parser.known_resource_types.hostclass("").name) + assert_equal("", parser.known_resource_types.hostclass("").namespace) end end @@ -482,22 +472,26 @@ file { "/tmp/yayness": ret = nil assert_nothing_raised do - ret = parser.parse("#{at}file { '/tmp/testing': owner => root }") + parser.known_resource_types.import_ast(parser.parse("#{at}file { '/tmp/testing': owner => root }"), '') + ret = parser.known_resource_types end assert_instance_of(AST::ASTArray, ret.hostclass("").code) resdef = ret.hostclass("").code[0] assert_instance_of(AST::Resource, resdef) - assert_equal("/tmp/testing", resdef.title.value) + assert_instance_of(AST::ASTArray, resdef.instances) + assert_equal(1, resdef.instances.children.length) + assert_equal("/tmp/testing", resdef.instances[0].title.value) # We always get an astarray back, so... check.call(resdef, "simple resource") # Now let's try it with multiple resources in the same spec assert_nothing_raised do - ret = parser.parse("#{at}file { ['/tmp/1', '/tmp/2']: owner => root }") + parser.known_resource_types.import_ast(parser.parse("#{at}file { ['/tmp/1', '/tmp/2']: owner => root }"), '') + ret = parser.known_resource_types end - ret.hostclass("").code.each do |res| + ret.hostclass("").code[0].each do |res| assert_instance_of(AST::Resource, res) check.call(res, "multiresource") end @@ -506,9 +500,9 @@ file { "/tmp/yayness": ensure if Puppet.features.rails? Puppet[:storeconfigs] = false - Puppet::Resource::Catalog.cache_class = catalog_cache_class - Puppet::Node::Facts.cache_class = facts_cache_class - Puppet::Node.cache_class = node_cache_class + Puppet::Resource::Catalog.indirection.cache_class = catalog_cache_class + Puppet::Node::Facts.indirection.cache_class = facts_cache_class + Puppet::Node.indirection.cache_class = node_cache_class end end @@ -537,7 +531,7 @@ file { "/tmp/yayness": ret = parser.parse("File #{arrow}") end - coll = ret.hostclass("").code[0] + coll = ret.code[0] assert_instance_of(AST::Collection, coll) assert_equal(form, coll.form) end @@ -545,9 +539,9 @@ file { "/tmp/yayness": ensure if Puppet.features.rails? Puppet[:storeconfigs] = false - Puppet::Resource::Catalog.cache_class = catalog_cache_class - Puppet::Node::Facts.cache_class = facts_cache_class - Puppet::Node.cache_class = node_cache_class + Puppet::Resource::Catalog.indirection.cache_class = catalog_cache_class + Puppet::Node::Facts.indirection.cache_class = facts_cache_class + Puppet::Node.indirection.cache_class = node_cache_class end end @@ -560,7 +554,7 @@ file { "/tmp/yayness": res = nil assert_nothing_raised do - res = parser.parse(str).hostclass("").code[0] + res = parser.parse(str).code[0] end assert_instance_of(AST::Collection, res) @@ -583,7 +577,7 @@ file { "/tmp/yayness": res = nil assert_nothing_raised do - res = parser.parse(str).hostclass("").code[0] + res = parser.parse(str).code[0] end assert_instance_of(AST::Collection, res) @@ -607,7 +601,7 @@ file { "/tmp/yayness": res = nil assert_nothing_raised("Could not parse '#{test}'") do - res = parser.parse(str).hostclass("").code[0] + res = parser.parse(str).code[0] end assert_instance_of(AST::Collection, res) @@ -624,15 +618,11 @@ file { "/tmp/yayness": def test_fully_qualified_definitions parser = mkparser + types = parser.known_resource_types assert_nothing_raised("Could not parse fully-qualified definition") { - parser.parse %{define one::two { }} + types.import_ast(parser.parse(%{define one::two { }}), '') } assert(parser.definition("one::two"), "Could not find one::two with no namespace") - - # Now try using the definition - assert_nothing_raised("Could not parse fully-qualified definition usage") { - parser.parse %{one::two { yayness: }} - } end # #524 @@ -691,7 +681,7 @@ file { "/tmp/yayness": result = parser.parse %{$variable = undef} } - main = result.hostclass("").code + main = result.code children = main.children assert_instance_of(AST::VarDef, main.children[0]) assert_instance_of(AST::Undef, main.children[0].value) @@ -704,7 +694,8 @@ file { "/tmp/yayness": str = "file { '/tmp/yay': ensure => file }\nclass yay {}\nnode foo {}\ndefine bar {}\n" result = nil assert_nothing_raised("Could not parse") do - result = parser.parse(str) + parser.known_resource_types.import_ast(parser.parse(str), '') + result = parser.known_resource_types end assert_instance_of(Puppet::Resource::TypeCollection, result, "Did not get a ASTSet back from parsing") @@ -734,12 +725,14 @@ file { "/tmp/yayness": result = nil assert_nothing_raised do - result = parser.newclass "Yayness" + parser.known_resource_types.import_ast(parser.parse("class yayness { }"), '') + result = parser.known_resource_types.hostclass('yayness') end assert_equal(result, parser.find_hostclass("", "yayNess")) assert_nothing_raised do - result = parser.newdefine "FunTest" + parser.known_resource_types.import_ast(parser.parse("define funtest { }"), '') + result = parser.known_resource_types.definition('funtest') end assert_equal(result, parser.find_definition("", "fUntEst"), "#{"fUntEst"} was not matched") end diff --git a/test/language/scope.rb b/test/language/scope.rb index cb5558aec..c4154dc27 100755 --- a/test/language/scope.rb +++ b/test/language/scope.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../lib/puppettest' +require File.expand_path(File.dirname(__FILE__) + '/../lib/puppettest') require 'mocha' require 'puppettest' @@ -163,7 +163,7 @@ class TestScope < Test::Unit::TestCase config = mkcompiler # Create a default source - parser.newclass("") + parser.known_resource_types.add Puppet::Resource::Type.new(:hostclass, "") config.topscope.source = parser.known_resource_types.hostclass("") # And a scope resource @@ -175,12 +175,12 @@ class TestScope < Test::Unit::TestCase ) # Create a top-level define - parser.newdefine "one", :arguments => [%w{arg}], + parser.known_resource_types.add Puppet::Resource::Type.new(:definition, "one", :arguments => [%w{arg}], :code => AST::ASTArray.new( :children => [ resourcedef("file", "/tmp", {"owner" => varref("arg")}) ] - ) + )) # create a resource that calls our third define obj = resourcedef("one", "boo", {"arg" => "parentfoo"}) @@ -233,9 +233,9 @@ Host <<||>>" } ensure Puppet[:storeconfigs] = false - Puppet::Resource::Catalog.cache_class = catalog_cache_class - Puppet::Node::Facts.cache_class = facts_cache_class - Puppet::Node.cache_class = node_cache_class + Puppet::Resource::Catalog.indirection.cache_class = catalog_cache_class + Puppet::Node::Facts.indirection.cache_class = facts_cache_class + Puppet::Node.indirection.cache_class = node_cache_class end else $stderr.puts "No ActiveRecord -- skipping collection tests" diff --git a/test/language/snippets.rb b/test/language/snippets.rb index a10e8e870..bfc14fa2d 100755 --- a/test/language/snippets.rb +++ b/test/language/snippets.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../lib/puppettest' +require File.expand_path(File.dirname(__FILE__) + '/../lib/puppettest') require 'puppet' require 'puppet/parser/parser' @@ -504,7 +504,7 @@ class TestSnippets < Test::Unit::TestCase catalog = nil assert_nothing_raised("Could not compile catalog") { - catalog = Puppet::Resource::Catalog.find(node) + catalog = Puppet::Resource::Catalog.indirection.find(node) } assert_nothing_raised("Could not convert catalog") { diff --git a/test/language/transportable.rb b/test/language/transportable.rb index 1e9ae930e..d8b5c10e1 100755 --- a/test/language/transportable.rb +++ b/test/language/transportable.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../lib/puppettest' +require File.expand_path(File.dirname(__FILE__) + '/../lib/puppettest') require 'puppet' require 'puppet/transportable' diff --git a/test/lib/puppettest.rb b/test/lib/puppettest.rb index 0b3a89a72..a60092cf7 100755 --- a/test/lib/puppettest.rb +++ b/test/lib/puppettest.rb @@ -185,7 +185,7 @@ module PuppetTest #if rake? or ! Puppet[:debug] #if defined?($puppet_debug) or ! rake? Puppet[:color] = false if textmate? - Puppet::Util::Log.newdestination(@logs) + Puppet::Util::Log.newdestination(Puppet::Test::LogCollector.new(@logs)) if defined? $console Puppet.info @method_name Puppet::Util::Log.newdestination(:console) @@ -305,7 +305,7 @@ module PuppetTest def logstore @logs = [] - Puppet::Util::Log.newdestination(@logs) + Puppet::Util::Log.newdestination(Puppet::Test::LogCollector.new(@logs)) end end diff --git a/test/lib/puppettest/parsertesting.rb b/test/lib/puppettest/parsertesting.rb index bd04c1ec5..411bad37a 100644 --- a/test/lib/puppettest/parsertesting.rb +++ b/test/lib/puppettest/parsertesting.rb @@ -94,16 +94,15 @@ module PuppetTest::ParserTesting def resourcedef(type, title, params) title = stringobj(title) unless title.is_a?(AST) + instance = AST::ResourceInstance.new(:title => title, :parameters => resourceparams(params)) assert_nothing_raised("Could not create #{type} #{title}") { return AST::Resource.new( :file => __FILE__, :line => __LINE__, - :title => title, :type => type, - - :parameters => resourceinst(params) + :instances => AST::ASTArray.new(:children => [instance]) ) } end @@ -122,9 +121,7 @@ module PuppetTest::ParserTesting :file => __FILE__, :line => __LINE__, :object => resourceref(type, title), - - :type => type, - :parameters => resourceinst(params) + :parameters => resourceparams(params) ) } end @@ -197,13 +194,13 @@ module PuppetTest::ParserTesting } end - def resourceinst(hash) + def resourceparams(hash) assert_nothing_raised("Could not create resource instance") { params = hash.collect { |param, value| resourceparam(param, value) } - return AST::ResourceInstance.new( + return AST::ASTArray.new( :file => tempfile, diff --git a/test/lib/puppettest/support/assertions.rb b/test/lib/puppettest/support/assertions.rb index 31fa3f1da..758c126ce 100644 --- a/test/lib/puppettest/support/assertions.rb +++ b/test/lib/puppettest/support/assertions.rb @@ -46,7 +46,12 @@ module PuppetTest config = resources2catalog(*resources) transaction = Puppet::Transaction.new(config) - run_events(:evaluate, transaction, events, msg) + transaction.evaluate + newevents = transaction.events. + reject { |e| ['failure', 'audit'].include? e.status }. + collect { |e| e.name } + + assert_equal(events, newevents, "Incorrect evaluate #{msg} events") transaction end diff --git a/test/lib/puppettest/support/utils.rb b/test/lib/puppettest/support/utils.rb index bca5d9634..4ecc3819e 100644 --- a/test/lib/puppettest/support/utils.rb +++ b/test/lib/puppettest/support/utils.rb @@ -82,25 +82,6 @@ module PuppetTest::Support::Utils @mygroup = group end - def run_events(type, trans, events, msg) - case type - when :evaluate, :rollback # things are hunky-dory - else - raise Puppet::DevError, "Incorrect run_events type" - end - - method = type - - trans.send(method) - newevents = trans.events.reject { |e| ['failure', 'audit'].include? e.status }.collect { |e| - e.name - } - - assert_equal(events, newevents, "Incorrect #{type} #{msg} events") - - trans - end - def fakefile(name) ary = [basedir, "test"] ary += name.split("/") diff --git a/test/network/authconfig.rb b/test/network/authconfig.rb index f53238d0b..3a4f18838 100755 --- a/test/network/authconfig.rb +++ b/test/network/authconfig.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../lib/puppettest' +require File.expand_path(File.dirname(__FILE__) + '/../lib/puppettest') require 'puppettest' diff --git a/test/network/authorization.rb b/test/network/authorization.rb index f29fe2554..5a1254a84 100755 --- a/test/network/authorization.rb +++ b/test/network/authorization.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../lib/puppettest' +require File.expand_path(File.dirname(__FILE__) + '/../lib/puppettest') require 'puppettest' require 'puppet/network/authorization' diff --git a/test/network/authstore.rb b/test/network/authstore.rb index e608423bf..e3c185302 100755 --- a/test/network/authstore.rb +++ b/test/network/authstore.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../lib/puppettest' +require File.expand_path(File.dirname(__FILE__) + '/../lib/puppettest') require 'puppettest' require 'mocha' diff --git a/test/network/client/ca.rb b/test/network/client/ca.rb index 5037fe48d..fcb950174 100755 --- a/test/network/client/ca.rb +++ b/test/network/client/ca.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../lib/puppettest' +require File.expand_path(File.dirname(__FILE__) + '/../../lib/puppettest') require 'mocha' require 'puppettest' diff --git a/test/network/client/dipper.rb b/test/network/client/dipper.rb index d4f784628..45f3a7a5c 100755 --- a/test/network/client/dipper.rb +++ b/test/network/client/dipper.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../lib/puppettest' +require File.expand_path(File.dirname(__FILE__) + '/../../lib/puppettest') require 'puppettest' require 'puppet/file_bucket/dipper' diff --git a/test/network/client_request.rb b/test/network/client_request.rb index 25fc57ff4..96b9d3e4f 100755 --- a/test/network/client_request.rb +++ b/test/network/client_request.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../lib/puppettest' +require File.expand_path(File.dirname(__FILE__) + '/../lib/puppettest') require 'puppettest' diff --git a/test/network/handler/ca.rb b/test/network/handler/ca.rb index 79a1b15dc..e27e9c29b 100755 --- a/test/network/handler/ca.rb +++ b/test/network/handler/ca.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../lib/puppettest' +require File.expand_path(File.dirname(__FILE__) + '/../../lib/puppettest') require 'puppettest' require 'puppet/network/handler/ca' diff --git a/test/network/handler/fileserver.rb b/test/network/handler/fileserver.rb index d979821bb..b76f8e199 100755 --- a/test/network/handler/fileserver.rb +++ b/test/network/handler/fileserver.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../lib/puppettest' +require File.expand_path(File.dirname(__FILE__) + '/../../lib/puppettest') require 'puppettest' require 'puppet/network/handler/fileserver' diff --git a/test/network/handler/master.rb b/test/network/handler/master.rb index 81869ac06..4c0374a76 100755 --- a/test/network/handler/master.rb +++ b/test/network/handler/master.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../lib/puppettest' +require File.expand_path(File.dirname(__FILE__) + '/../../lib/puppettest') require 'puppettest' require 'puppet/network/handler/master' @@ -13,7 +13,7 @@ class TestMaster < Test::Unit::TestCase @master = Puppet::Network::Handler.master.new(:Manifest => tempfile) @catalog = stub 'catalog', :extract => "" - Puppet::Resource::Catalog.stubs(:find).returns(@catalog) + Puppet::Resource::Catalog.indirection.stubs(:find).returns(@catalog) end def teardown @@ -32,15 +32,17 @@ class TestMaster < Test::Unit::TestCase def test_hostname_is_used_if_client_is_missing @master.expects(:decode_facts).returns("hostname" => "yay") - Puppet::Node::Facts.expects(:new).with { |name, facts| name == "yay" }.returns(stub('facts', :save => nil)) + facts = Puppet::Node::Facts.new("the_facts") + Puppet::Node::Facts.indirection.stubs(:save).with(facts) + Puppet::Node::Facts.expects(:new).with { |name, facts| name == "yay" }.returns(facts) @master.getconfig("facts") end def test_facts_are_saved - facts = mock('facts') + facts = Puppet::Node::Facts.new("the_facts") Puppet::Node::Facts.expects(:new).returns(facts) - facts.expects(:save) + Puppet::Node::Facts.indirection.expects(:save).with(facts) @master.stubs(:decode_facts) @@ -48,12 +50,13 @@ class TestMaster < Test::Unit::TestCase end def test_catalog_is_used_for_compiling - facts = stub('facts', :save => nil) + facts = Puppet::Node::Facts.new("the_facts") + Puppet::Node::Facts.indirection.stubs(:save).with(facts) Puppet::Node::Facts.stubs(:new).returns(facts) @master.stubs(:decode_facts) - Puppet::Resource::Catalog.expects(:find).with("foo.com").returns(@catalog) + Puppet::Resource::Catalog.indirection.expects(:find).with("foo.com").returns(@catalog) @master.getconfig("facts", "yaml", "foo.com") end @@ -61,14 +64,15 @@ end class TestMasterFormats < Test::Unit::TestCase def setup - @facts = stub('facts', :save => nil) + @facts = Puppet::Node::Facts.new("the_facts") Puppet::Node::Facts.stubs(:new).returns(@facts) + Puppet::Node::Facts.indirection.stubs(:save) @master = Puppet::Network::Handler.master.new(:Code => "") @master.stubs(:decode_facts) @catalog = stub 'catalog', :extract => "" - Puppet::Resource::Catalog.stubs(:find).returns(@catalog) + Puppet::Resource::Catalog.indirection.stubs(:find).returns(@catalog) end def test_marshal_can_be_used diff --git a/test/network/handler/report.rb b/test/network/handler/report.rb index 590dcdb13..d0c223878 100755 --- a/test/network/handler/report.rb +++ b/test/network/handler/report.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../lib/puppettest' +require File.expand_path(File.dirname(__FILE__) + '/../../lib/puppettest') require 'puppettest' require 'puppet/network/handler/report' diff --git a/test/network/handler/runner.rb b/test/network/handler/runner.rb index 396568b29..d03fb2c89 100755 --- a/test/network/handler/runner.rb +++ b/test/network/handler/runner.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../lib/puppettest' +require File.expand_path(File.dirname(__FILE__) + '/../../lib/puppettest') require 'puppettest' require 'puppet/network/handler/runner' diff --git a/test/network/rights.rb b/test/network/rights.rb index df032b5a9..0167a98f1 100755 --- a/test/network/rights.rb +++ b/test/network/rights.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../lib/puppettest' +require File.expand_path(File.dirname(__FILE__) + '/../lib/puppettest') require 'puppettest' require 'puppet/network/rights' diff --git a/test/network/server/mongrel_test.rb b/test/network/server/mongrel_test.rb index d675b42f7..ca215ee25 100755 --- a/test/network/server/mongrel_test.rb +++ b/test/network/server/mongrel_test.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../lib/puppettest' +require File.expand_path(File.dirname(__FILE__) + '/../../lib/puppettest') require 'puppettest' require 'mocha' diff --git a/test/network/server/webrick.rb b/test/network/server/webrick.rb index e203894d9..624147b6c 100755 --- a/test/network/server/webrick.rb +++ b/test/network/server/webrick.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../lib/puppettest' +require File.expand_path(File.dirname(__FILE__) + '/../../lib/puppettest') require 'puppettest' require 'puppet/network/http_server/webrick' diff --git a/test/network/xmlrpc/client.rb b/test/network/xmlrpc/client.rb index 7e7f36944..73159a994 100755 --- a/test/network/xmlrpc/client.rb +++ b/test/network/xmlrpc/client.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../lib/puppettest' +require File.expand_path(File.dirname(__FILE__) + '/../../lib/puppettest') require 'puppettest' require 'puppet/network/xmlrpc/client' diff --git a/test/network/xmlrpc/processor.rb b/test/network/xmlrpc/processor.rb index 0c990c9e8..379b34a85 100755 --- a/test/network/xmlrpc/processor.rb +++ b/test/network/xmlrpc/processor.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../lib/puppettest' +require File.expand_path(File.dirname(__FILE__) + '/../../lib/puppettest') require 'puppettest' require 'puppet/network/xmlrpc/processor' diff --git a/test/network/xmlrpc/server.rb b/test/network/xmlrpc/server.rb index a5474b08c..0653f009e 100755 --- a/test/network/xmlrpc/server.rb +++ b/test/network/xmlrpc/server.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../lib/puppettest' +require File.expand_path(File.dirname(__FILE__) + '/../../lib/puppettest') require 'puppettest' require 'puppet/network/xmlrpc/server' diff --git a/test/network/xmlrpc/webrick_servlet.rb b/test/network/xmlrpc/webrick_servlet.rb index 47bad27c2..f2faf09ec 100755 --- a/test/network/xmlrpc/webrick_servlet.rb +++ b/test/network/xmlrpc/webrick_servlet.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../lib/puppettest' +require File.expand_path(File.dirname(__FILE__) + '/../../lib/puppettest') require 'puppettest' require 'puppettest/support/utils' diff --git a/test/other/provider.rb b/test/other/provider.rb index a539ee5a7..c31c6bfb9 100755 --- a/test/other/provider.rb +++ b/test/other/provider.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../lib/puppettest' +require File.expand_path(File.dirname(__FILE__) + '/../lib/puppettest') require 'puppet' require 'puppet/provider' diff --git a/test/other/puppet.rb b/test/other/puppet.rb index 657bdefca..9fb53ddba 100755 --- a/test/other/puppet.rb +++ b/test/other/puppet.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../lib/puppettest' +require File.expand_path(File.dirname(__FILE__) + '/../lib/puppettest') require 'puppet' require 'puppettest' diff --git a/test/other/relationships.rb b/test/other/relationships.rb index df4d3a96e..e36dcda71 100755 --- a/test/other/relationships.rb +++ b/test/other/relationships.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../lib/puppettest' +require File.expand_path(File.dirname(__FILE__) + '/../lib/puppettest') require 'puppet' require 'puppettest' @@ -14,11 +14,8 @@ class TestRelationships < Test::Unit::TestCase def newfile assert_nothing_raised { - - return Puppet::Type.type(:file).new( - + return Puppet::Type.type(:file).new( :path => tempfile, - :check => [:mode, :owner, :group] ) } @@ -58,18 +55,14 @@ class TestRelationships < Test::Unit::TestCase def test_autorequire # We know that execs autorequire their cwd, so we'll use that path = tempfile - - - file = Puppet::Type.type(:file).new( - :title => "myfile", :path => path, - - :ensure => :directory) - - exec = Puppet::Type.newexec( - :title => "myexec", :cwd => path, - - :command => "/bin/echo") - + file = Puppet::Type.type(:file).new( + :title => "myfile", :path => path, + :ensure => :directory + ) + exec = Puppet::Type.newexec( + :title => "myexec", :cwd => path, + :command => "/bin/echo" + ) catalog = mk_catalog(file, exec) reqs = nil assert_nothing_raised do @@ -82,7 +75,7 @@ class TestRelationships < Test::Unit::TestCase # Now make sure that these relationships are added to the # relationship graph catalog.apply do |trans| - assert(catalog.relationship_graph.edge?(file, exec), "autorequire edge was not created") + assert(catalog.relationship_graph.path_between(file, exec), "autorequire edge was not created") end end diff --git a/test/other/report.rb b/test/other/report.rb index eacf1632b..fb206470a 100755 --- a/test/other/report.rb +++ b/test/other/report.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../lib/puppettest' +require File.expand_path(File.dirname(__FILE__) + '/../lib/puppettest') require 'puppet' require 'puppet/reports' diff --git a/test/other/transactions.rb b/test/other/transactions.rb index 6655d8645..812e519ab 100755 --- a/test/other/transactions.rb +++ b/test/other/transactions.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../lib/puppettest' +require File.expand_path(File.dirname(__FILE__) + '/../lib/puppettest') require 'mocha' require 'puppet' @@ -114,39 +114,6 @@ class TestTransactions < Test::Unit::TestCase assert_equal({inst.title => inst}, $prefetched, "evaluate did not call prefetch") end - # We need to generate resources before we prefetch them, else generated - # resources that require prefetching don't work. - def test_generate_before_prefetch - config = mk_catalog - trans = Puppet::Transaction.new(config) - - generate = nil - prefetch = nil - trans.expects(:generate).with { |*args| generate = Time.now; true } - trans.expects(:prefetch).with { |*args| ! generate.nil? } - trans.prepare - return - - resource = Puppet::Type.type(:file).new :ensure => :present, :path => tempfile - other_resource = mock 'generated' - def resource.generate - [other_resource] - end - - - config = mk_catalog(yay, rah) - trans = Puppet::Transaction.new(config) - - assert_nothing_raised do - trans.generate - end - - %w{ya ra y r}.each do |name| - assert(trans.catalog.vertex?(Puppet::Type.type(:generator)[name]), "Generated #{name} was not a vertex") - assert($finished.include?(name), "#{name} was not finished") - end - end - def test_ignore_tags? config = Puppet::Resource::Catalog.new config.host_config = true @@ -235,7 +202,7 @@ class TestTransactions < Test::Unit::TestCase config = mk_catalog(one, two) trans = Puppet::Transaction.new(config) assert_raise(Puppet::Error) do - trans.prepare + trans.evaluate end end diff --git a/test/puppet/defaults.rb b/test/puppet/defaults.rb index d290cef1f..18c74bf49 100755 --- a/test/puppet/defaults.rb +++ b/test/puppet/defaults.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../lib/puppettest' +require File.expand_path(File.dirname(__FILE__) + '/../lib/puppettest') require 'puppet' require 'puppettest' diff --git a/test/puppet/errortest.rb b/test/puppet/errortest.rb index bb81b0d3f..35f2ed39e 100755 --- a/test/puppet/errortest.rb +++ b/test/puppet/errortest.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../lib/puppettest' +require File.expand_path(File.dirname(__FILE__) + '/../lib/puppettest') require 'puppet' require 'puppettest' diff --git a/test/puppet/tc_suidmanager.rb b/test/puppet/tc_suidmanager.rb index eeb56f2c9..2f4cb40da 100755 --- a/test/puppet/tc_suidmanager.rb +++ b/test/puppet/tc_suidmanager.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../lib/puppettest' +require File.expand_path(File.dirname(__FILE__) + '/../lib/puppettest') require 'puppet' require 'puppettest' diff --git a/test/rails/rails.rb b/test/rails/rails.rb index 6a5bd7b17..75987b95e 100755 --- a/test/rails/rails.rb +++ b/test/rails/rails.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../lib/puppettest' +require File.expand_path(File.dirname(__FILE__) + '/../lib/puppettest') require 'puppet' require 'puppet/rails' diff --git a/test/rails/railsparameter.rb b/test/rails/railsparameter.rb index 9f6fc1c1e..fafa2b7e7 100755 --- a/test/rails/railsparameter.rb +++ b/test/rails/railsparameter.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../lib/puppettest' +require File.expand_path(File.dirname(__FILE__) + '/../lib/puppettest') require 'puppet' require 'puppet/rails' @@ -22,7 +22,7 @@ class TestRailsParameter < Test::Unit::TestCase # Now create a source parser = mkparser - source = parser.newclass "myclass" + source = parser.known_resource_types.add Puppet::Resource::Type.new(:hostclass, "myclass") host = Puppet::Rails::Host.new(:name => "myhost") diff --git a/test/ral/manager/attributes.rb b/test/ral/manager/attributes.rb index 6d0284d9e..030f38c50 100755 --- a/test/ral/manager/attributes.rb +++ b/test/ral/manager/attributes.rb @@ -3,7 +3,7 @@ # Created by Luke A. Kanies on 2007-02-05. # Copyright (c) 2007. All rights reserved. -require File.dirname(__FILE__) + '/../../lib/puppettest' +require File.expand_path(File.dirname(__FILE__) + '/../../lib/puppettest') require 'puppettest' require 'mocha' diff --git a/test/ral/manager/instances.rb b/test/ral/manager/instances.rb index dd1cf054e..f1731ac64 100755 --- a/test/ral/manager/instances.rb +++ b/test/ral/manager/instances.rb @@ -3,7 +3,7 @@ # Created by Luke A. Kanies on 2007-06-10. # Copyright (c) 2007. All rights reserved. -require File.dirname(__FILE__) + '/../../lib/puppettest' +require File.expand_path(File.dirname(__FILE__) + '/../../lib/puppettest') require 'puppettest' diff --git a/test/ral/manager/manager.rb b/test/ral/manager/manager.rb index 76b1d97fe..9c9449a45 100755 --- a/test/ral/manager/manager.rb +++ b/test/ral/manager/manager.rb @@ -3,7 +3,7 @@ # Created by Luke A. Kanies on 2006-11-29. # Copyright (c) 2006. All rights reserved. -require File.dirname(__FILE__) + '/../../lib/puppettest' +require File.expand_path(File.dirname(__FILE__) + '/../../lib/puppettest') require 'puppettest' diff --git a/test/ral/manager/provider.rb b/test/ral/manager/provider.rb index d4c8a3407..1d7265b7c 100755 --- a/test/ral/manager/provider.rb +++ b/test/ral/manager/provider.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../lib/puppettest' +require File.expand_path(File.dirname(__FILE__) + '/../../lib/puppettest') require 'puppettest' require 'mocha' diff --git a/test/ral/manager/type.rb b/test/ral/manager/type.rb index 145877722..c2e6a0c1e 100755 --- a/test/ral/manager/type.rb +++ b/test/ral/manager/type.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../lib/puppettest' +require File.expand_path(File.dirname(__FILE__) + '/../../lib/puppettest') require 'mocha' require 'puppettest' diff --git a/test/ral/providers/cron/crontab.rb b/test/ral/providers/cron/crontab.rb index be2af1e16..3475cf6f1 100755 --- a/test/ral/providers/cron/crontab.rb +++ b/test/ral/providers/cron/crontab.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../../lib/puppettest' +require File.expand_path(File.dirname(__FILE__) + '/../../../lib/puppettest') require 'puppettest' require 'mocha' diff --git a/test/ral/providers/group.rb b/test/ral/providers/group.rb index 8a0860551..4259be355 100755 --- a/test/ral/providers/group.rb +++ b/test/ral/providers/group.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../lib/puppettest' +require File.expand_path(File.dirname(__FILE__) + '/../../lib/puppettest') require 'puppettest' require 'etc' diff --git a/test/ral/providers/host/parsed.rb b/test/ral/providers/host/parsed.rb index c2367d566..521654d53 100755 --- a/test/ral/providers/host/parsed.rb +++ b/test/ral/providers/host/parsed.rb @@ -1,8 +1,7 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../../lib/puppettest' +require File.expand_path(File.dirname(__FILE__) + '/../../../lib/puppettest') -require 'etc' require 'puppettest' require 'puppettest/fileparsing' require 'test/unit' @@ -25,210 +24,9 @@ class TestParsedHostProvider < Test::Unit::TestCase super end - def test_provider_existence - assert(@provider, "Could not retrieve provider") - end - - # Here we just create a fake host type that answers to all of the methods - # but does not modify our actual system. - def mkfaketype - @provider.filetype = Puppet::Util::FileType.filetype(:ram) - end - - def mkhosthash - if defined?(@hcount) - @hcount += 1 - else - @hcount = 1 - end - - return { - :name => "fakehost#{@hcount}", - :ip => "192.168.27.#{@hcount}", - :host_aliases => ["alias#{@hcount}"], - :ensure => :present - } - end - - def mkhost - hash = mkhosthash - - fakeresource = fakeresource(:host, hash[:name]) - - host = @provider.new(fakeresource) - - assert(host, "Could not create provider host") - hash.each do |name, val| - host.send(name.to_s + "=", val) - end - - host - end - - # Make sure we convert both directlys correctly using a simple host. - def test_basic_isomorphism - hash = {:record_type => :parsed, :name => "myhost", :ip => "192.168.43.56", :host_aliases => %w{another host}} - - str = nil - assert_nothing_raised do - str = @provider.to_line(hash) - end - - assert_equal("192.168.43.56\tmyhost\tanother\thost", str) - - newhash = nil - assert_nothing_raised do - newhash = @provider.parse(str).shift - end - - assert_equal(hash, newhash) - end - - # Make sure parsing gets comments, blanks, and hosts - def test_blanks_and_comments - mkfaketype - text = %{# comment one - -192.168.43.56\tmyhost\tanother\thost - -# another comment -192.168.43.57\tanotherhost -} - - instances = nil - assert_nothing_raised do - instances = @provider.parse(text) - end - - - assert_equal( - [ - {:record_type => :comment, :line => "# comment one"}, - {:record_type => :blank, :line => ""}, - {:record_type => :parsed, :name => "myhost", :ip => "192.168.43.56", :host_aliases => %w{another host}}, - {:record_type => :blank, :line => " "}, - {:record_type => :comment, :line => "# another comment"}, - - {:record_type => :parsed, :name => "anotherhost", :ip => "192.168.43.57", :host_aliases => []} - ], instances) - - newtext = nil - assert_nothing_raised do - newtext = @provider.to_file(instances).gsub(/^# HEADER.+\n/, '') - end - - assert_equal(text, newtext) - end - - def test_simplehost - mkfaketype - @provider.default_target = :yayness - file = @provider.target_object(:yayness) - - # Start out with no content. - assert_nothing_raised { - assert_equal([], @provider.parse(file.read)) - } - - # Now create a provider - host = nil - assert_nothing_raised { - host = mkhost - } - - # Make sure we're still empty - assert_nothing_raised { - assert_equal([], @provider.parse(file.read)) - } - - # Try storing it - assert_nothing_raised do - host.flush - end - - # Make sure we get the host back - assert_nothing_raised { - - assert( - file.read.include?(host.name), - - "Did not flush host to disk") - } - - # Remove a single field and make sure it gets tossed - name = host.host_aliases - host.host_aliases = [:absent] - - assert_nothing_raised { - host.flush - - assert( - ! file.read.include?(name[0]), - - "Did not remove host_aliases from disk") - } - - # Make sure it throws up if we remove a required field - host.ip = :absent - - assert_raise(ArgumentError) { - host.flush - } - - # Now remove the whole object - host.ensure = :absent - assert_nothing_raised { - host.flush - assert_equal([], @provider.parse(file.read)) - } - end - # Parse our sample data and make sure we regenerate it correctly. def test_hostsparse fakedata("data/types/hosts").each do |file| fakedataparse(file) end end - - # Make sure we can modify the file elsewhere and those modifications will - # get taken into account. - def test_modifyingfile - hostfile = tempfile - @provider.default_target = hostfile - - file = @provider.target_object(hostfile) - - hosts = [] - 3.times { - h = mkhost - hosts << h - } - - hosts.each do |host| - host.flush - end - - newhost = mkhost - hosts << newhost - - # Now store our new host - newhost.flush - - # Verify we can retrieve that info - assert_nothing_raised("Could not retrieve after second write") { - @provider.prefetch - } - - text = file.read - - instances = @provider.parse(text) - - # And verify that we have data for everything - hosts.each { |host| - name = host.resource[:name] - assert(text.include?(name), "Host #{name} is not in file") - hash = host.property_hash - assert(! hash.empty?, "Could not find host #{name}") - assert(hash[:ip], "Could not find ip for host #{name}") - } - end end diff --git a/test/ral/providers/mailalias/aliases.rb b/test/ral/providers/mailalias/aliases.rb index 0497528c3..9cd2fc354 100755 --- a/test/ral/providers/mailalias/aliases.rb +++ b/test/ral/providers/mailalias/aliases.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../../lib/puppettest' +require File.expand_path(File.dirname(__FILE__) + '/../../../lib/puppettest') require 'puppettest' require 'puppettest/fileparsing' diff --git a/test/ral/providers/nameservice.rb b/test/ral/providers/nameservice.rb index 967c59f92..a04b45b1f 100755 --- a/test/ral/providers/nameservice.rb +++ b/test/ral/providers/nameservice.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../lib/puppettest' +require File.expand_path(File.dirname(__FILE__) + '/../../lib/puppettest') require 'puppettest' require 'puppet/provider/nameservice' diff --git a/test/ral/providers/package.rb b/test/ral/providers/package.rb index 9c5e0dfa6..5264443bc 100755 --- a/test/ral/providers/package.rb +++ b/test/ral/providers/package.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../lib/puppettest' +require File.expand_path(File.dirname(__FILE__) + '/../../lib/puppettest') require 'puppettest' require 'etc' diff --git a/test/ral/providers/package/aptitude.rb b/test/ral/providers/package/aptitude.rb index 34eba10bf..871de9ded 100755 --- a/test/ral/providers/package/aptitude.rb +++ b/test/ral/providers/package/aptitude.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../../lib/puppettest' +require File.expand_path(File.dirname(__FILE__) + '/../../../lib/puppettest') require 'mocha' diff --git a/test/ral/providers/package/aptrpm.rb b/test/ral/providers/package/aptrpm.rb index 5f2a0d274..a9646696a 100755 --- a/test/ral/providers/package/aptrpm.rb +++ b/test/ral/providers/package/aptrpm.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../../lib/puppettest' +require File.expand_path(File.dirname(__FILE__) + '/../../../lib/puppettest') require 'mocha' diff --git a/test/ral/providers/parsedfile.rb b/test/ral/providers/parsedfile.rb index c7e5d9b04..b9e33e56c 100755 --- a/test/ral/providers/parsedfile.rb +++ b/test/ral/providers/parsedfile.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../lib/puppettest' +require File.expand_path(File.dirname(__FILE__) + '/../../lib/puppettest') require 'puppettest' require 'mocha' diff --git a/test/ral/providers/port/parsed.rb b/test/ral/providers/port/parsed.rb index 13cc87d2c..062044796 100755 --- a/test/ral/providers/port/parsed.rb +++ b/test/ral/providers/port/parsed.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../../lib/puppettest' +require File.expand_path(File.dirname(__FILE__) + '/../../../lib/puppettest') require 'puppettest' #require 'puppettest/fileparsing' diff --git a/test/ral/providers/provider.rb b/test/ral/providers/provider.rb index f46e03f82..a9f5ad21c 100755 --- a/test/ral/providers/provider.rb +++ b/test/ral/providers/provider.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../lib/puppettest' +require File.expand_path(File.dirname(__FILE__) + '/../../lib/puppettest') require 'puppettest' require 'facter' diff --git a/test/ral/providers/service/base.rb b/test/ral/providers/service/base.rb index 82d36ab98..112246b12 100755 --- a/test/ral/providers/service/base.rb +++ b/test/ral/providers/service/base.rb @@ -3,7 +3,7 @@ # Created by Luke A. Kanies on 2007-01-28. # Copyright (c) 2007. All rights reserved. -require File.dirname(__FILE__) + '/../../../lib/puppettest' +require File.expand_path(File.dirname(__FILE__) + '/../../../lib/puppettest') require 'puppettest' diff --git a/test/ral/providers/sshkey/parsed.rb b/test/ral/providers/sshkey/parsed.rb index f21158fed..2a6041406 100755 --- a/test/ral/providers/sshkey/parsed.rb +++ b/test/ral/providers/sshkey/parsed.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../../lib/puppettest' +require File.expand_path(File.dirname(__FILE__) + '/../../../lib/puppettest') require 'puppettest' require 'puppettest/fileparsing' diff --git a/test/ral/providers/user.rb b/test/ral/providers/user.rb index 64f833f6a..ebf2ab700 100755 --- a/test/ral/providers/user.rb +++ b/test/ral/providers/user.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../lib/puppettest' +require File.expand_path(File.dirname(__FILE__) + '/../../lib/puppettest') require 'puppettest' require 'puppettest/support/utils' diff --git a/test/ral/providers/user/useradd.rb b/test/ral/providers/user/useradd.rb index 12e1f7ffc..6350ec6dc 100755 --- a/test/ral/providers/user/useradd.rb +++ b/test/ral/providers/user/useradd.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../../lib/puppettest' +require File.expand_path(File.dirname(__FILE__) + '/../../../lib/puppettest') require 'mocha' diff --git a/test/ral/type/cron.rb b/test/ral/type/cron.rb index a941caec8..ae280e04f 100755 --- a/test/ral/type/cron.rb +++ b/test/ral/type/cron.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../lib/puppettest' +require File.expand_path(File.dirname(__FILE__) + '/../../lib/puppettest') require 'puppettest' diff --git a/test/ral/type/exec.rb b/test/ral/type/exec.rb index dd42ae61f..0831d466d 100755 --- a/test/ral/type/exec.rb +++ b/test/ral/type/exec.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../lib/puppettest' +require File.expand_path(File.dirname(__FILE__) + '/../../lib/puppettest') require 'puppettest' @@ -547,47 +547,6 @@ class TestExec < Test::Unit::TestCase } end - def test_envparam - - exec = Puppet::Type.newexec( - :command => "echo $envtest", - :path => ENV["PATH"], - :env => "envtest=yayness" - ) - - assert(exec, "Could not make exec") - - output = status = nil - assert_nothing_raised { - output, status = exec.provider.run("echo $envtest") - } - - assert_equal("yayness\n", output) - - # Now check whether we can do multiline settings - assert_nothing_raised do - exec[:env] = "envtest=a list of things -and stuff" - end - - output = status = nil - assert_nothing_raised { - output, status = exec.provider.run('echo "$envtest"') - } - assert_equal("a list of things\nand stuff\n", output) - - # Now test arrays - assert_nothing_raised do - exec[:env] = ["funtest=A", "yaytest=B"] - end - - output = status = nil - assert_nothing_raised { - output, status = exec.provider.run('echo "$funtest" "$yaytest"') - } - assert_equal("A B\n", output) - end - def test_environmentparam exec = Puppet::Type.newexec( diff --git a/test/ral/type/file.rb b/test/ral/type/file.rb index 386c3ca1b..2285e72c8 100755 --- a/test/ral/type/file.rb +++ b/test/ral/type/file.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../lib/puppettest' +require File.expand_path(File.dirname(__FILE__) + '/../../lib/puppettest') require 'puppettest' require 'puppettest/support/utils' diff --git a/test/ral/type/file/target.rb b/test/ral/type/file/target.rb index 339e47dcc..d778f2891 100755 --- a/test/ral/type/file/target.rb +++ b/test/ral/type/file/target.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../../lib/puppettest' +require File.expand_path(File.dirname(__FILE__) + '/../../../lib/puppettest') require 'puppettest' require 'puppettest/support/utils' @@ -24,12 +24,9 @@ class TestFileTarget < Test::Unit::TestCase file = nil assert_nothing_raised { - - file = Puppet::Type.type(:file).new( - + file = Puppet::Type.type(:file).new( :title => "somethingelse", :ensure => path, - :path => link ) } @@ -102,12 +99,9 @@ class TestFileTarget < Test::Unit::TestCase link = nil assert_nothing_raised { - - link = Puppet::Type.type(:file).new( - + link = Puppet::Type.type(:file).new( :ensure => source, :path => dest, - :recurse => true ) } @@ -140,11 +134,8 @@ class TestFileTarget < Test::Unit::TestCase link = nil assert_nothing_raised { - - link = Puppet::Type.type(:file).new( - + link = Puppet::Type.type(:file).new( :path => dest, - :ensure => "source" ) } @@ -161,20 +152,16 @@ class TestFileTarget < Test::Unit::TestCase resources = [] - resources << Puppet::Type.type(:exec).new( - + resources << Puppet::Type.type(:exec).new( :command => "mkdir #{source}; touch #{source}/file", :title => "yay", - :path => ENV["PATH"] ) - resources << Puppet::Type.type(:file).new( - + resources << Puppet::Type.type(:file).new( :ensure => source, :path => dest, :recurse => true, - :require => resources[0] ) diff --git a/test/ral/type/fileignoresource.rb b/test/ral/type/fileignoresource.rb index 3254fe293..593fcf7a7 100755 --- a/test/ral/type/fileignoresource.rb +++ b/test/ral/type/fileignoresource.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../lib/puppettest' +require File.expand_path(File.dirname(__FILE__) + '/../../lib/puppettest') require 'puppettest' require 'puppettest/support/utils' diff --git a/test/ral/type/filesources.rb b/test/ral/type/filesources.rb index 242a82e83..3363aafb3 100755 --- a/test/ral/type/filesources.rb +++ b/test/ral/type/filesources.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../lib/puppettest' +require File.expand_path(File.dirname(__FILE__) + '/../../lib/puppettest') require 'puppettest' require 'puppettest/support/utils' diff --git a/test/ral/type/host.rb b/test/ral/type/host.rb index 1b5bb01c9..00e1d9ef6 100755 --- a/test/ral/type/host.rb +++ b/test/ral/type/host.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../lib/puppettest' +require File.expand_path(File.dirname(__FILE__) + '/../../lib/puppettest') require 'puppettest' require 'test/unit' diff --git a/test/ral/type/mailalias.rb b/test/ral/type/mailalias.rb index 634ff2a31..1c867ef1b 100755 --- a/test/ral/type/mailalias.rb +++ b/test/ral/type/mailalias.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../lib/puppettest' +require File.expand_path(File.dirname(__FILE__) + '/../../lib/puppettest') require 'puppettest' require 'mocha' diff --git a/test/ral/type/port.rb b/test/ral/type/port.rb index 85592d14a..1daee1474 100755 --- a/test/ral/type/port.rb +++ b/test/ral/type/port.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../lib/puppettest' +require File.expand_path(File.dirname(__FILE__) + '/../../lib/puppettest') require 'puppettest' diff --git a/test/ral/type/resources.rb b/test/ral/type/resources.rb index f36df7f1d..fcfeebe10 100755 --- a/test/ral/type/resources.rb +++ b/test/ral/type/resources.rb @@ -3,7 +3,7 @@ # Created by Luke Kanies on 2006-12-12. # Copyright (c) 2006. All rights reserved. -require File.dirname(__FILE__) + '/../../lib/puppettest' +require File.expand_path(File.dirname(__FILE__) + '/../../lib/puppettest') require 'puppettest' diff --git a/test/ral/type/service.rb b/test/ral/type/service.rb index 9e6469088..b7ae8dfd6 100755 --- a/test/ral/type/service.rb +++ b/test/ral/type/service.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../lib/puppettest' +require File.expand_path(File.dirname(__FILE__) + '/../../lib/puppettest') require 'puppettest' require 'mocha' diff --git a/test/ral/type/sshkey.rb b/test/ral/type/sshkey.rb index 725f188ca..2bdc00877 100755 --- a/test/ral/type/sshkey.rb +++ b/test/ral/type/sshkey.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../lib/puppettest' +require File.expand_path(File.dirname(__FILE__) + '/../../lib/puppettest') require 'puppettest' require 'facter' diff --git a/test/ral/type/user.rb b/test/ral/type/user.rb index dee6a9176..404d84f4e 100755 --- a/test/ral/type/user.rb +++ b/test/ral/type/user.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../lib/puppettest' +require File.expand_path(File.dirname(__FILE__) + '/../../lib/puppettest') require 'puppettest' require 'etc' diff --git a/test/ral/type/yumrepo.rb b/test/ral/type/yumrepo.rb index bbc1562db..086615097 100755 --- a/test/ral/type/yumrepo.rb +++ b/test/ral/type/yumrepo.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../lib/puppettest' +require File.expand_path(File.dirname(__FILE__) + '/../../lib/puppettest') require 'puppettest' require 'fileutils' diff --git a/test/ral/type/zone.rb b/test/ral/type/zone.rb index 59de99075..c93cc68bc 100755 --- a/test/ral/type/zone.rb +++ b/test/ral/type/zone.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../lib/puppettest' +require File.expand_path(File.dirname(__FILE__) + '/../../lib/puppettest') require 'puppettest' require 'puppet/type/zone' diff --git a/test/util/classgen.rb b/test/util/classgen.rb index 5560764d5..aa9bdbed7 100755 --- a/test/util/classgen.rb +++ b/test/util/classgen.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../lib/puppettest' +require File.expand_path(File.dirname(__FILE__) + '/../lib/puppettest') require 'puppet' require 'puppettest' diff --git a/test/util/execution.rb b/test/util/execution.rb index e6509582e..316231b66 100755 --- a/test/util/execution.rb +++ b/test/util/execution.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../lib/puppettest' +require File.expand_path(File.dirname(__FILE__) + '/../lib/puppettest') require 'puppet' require 'puppettest' diff --git a/test/util/fileparsing.rb b/test/util/fileparsing.rb index 05ed80a79..831f19bdb 100755 --- a/test/util/fileparsing.rb +++ b/test/util/fileparsing.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../lib/puppettest' +require File.expand_path(File.dirname(__FILE__) + '/../lib/puppettest') require 'puppettest' require 'puppettest/fileparsing' diff --git a/test/util/inifile.rb b/test/util/inifile.rb index 78831ca2f..e3ce20823 100755 --- a/test/util/inifile.rb +++ b/test/util/inifile.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../lib/puppettest' +require File.expand_path(File.dirname(__FILE__) + '/../lib/puppettest') require 'puppet' require 'puppet/util/inifile' diff --git a/test/util/instance_loader.rb b/test/util/instance_loader.rb index 2e3dcb3d6..61ca4e3c8 100755 --- a/test/util/instance_loader.rb +++ b/test/util/instance_loader.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../lib/puppettest' +require File.expand_path(File.dirname(__FILE__) + '/../lib/puppettest') require 'puppet' require 'puppet/util/instance_loader' diff --git a/test/util/log.rb b/test/util/log.rb index 4dbd3c6d1..908347a50 100755 --- a/test/util/log.rb +++ b/test/util/log.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../lib/puppettest' +require File.expand_path(File.dirname(__FILE__) + '/../lib/puppettest') require 'puppet' require 'puppet/util/log' diff --git a/test/util/metrics.rb b/test/util/metrics.rb index 82e792d0b..d1a052293 100755 --- a/test/util/metrics.rb +++ b/test/util/metrics.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../lib/puppettest' +require File.expand_path(File.dirname(__FILE__) + '/../lib/puppettest') require 'puppet' require 'puppet/util/metric' diff --git a/test/util/package.rb b/test/util/package.rb index b2bb6dfcc..cd6a9d01d 100755 --- a/test/util/package.rb +++ b/test/util/package.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../lib/puppettest' +require File.expand_path(File.dirname(__FILE__) + '/../lib/puppettest') require 'puppet' require 'puppet/util/package' diff --git a/test/util/pidlock.rb b/test/util/pidlock.rb index 764c7436d..beaff1089 100755 --- a/test/util/pidlock.rb +++ b/test/util/pidlock.rb @@ -1,4 +1,4 @@ -require File.dirname(__FILE__) + '/../lib/puppettest' +require File.expand_path(File.dirname(__FILE__) + '/../lib/puppettest') require 'puppet/util/pidlock' require 'fileutils' diff --git a/test/util/settings.rb b/test/util/settings.rb index ffcfbbfc2..7a7150983 100755 --- a/test/util/settings.rb +++ b/test/util/settings.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../lib/puppettest' +require File.expand_path(File.dirname(__FILE__) + '/../lib/puppettest') require 'mocha' require 'puppettest' diff --git a/test/util/storage.rb b/test/util/storage.rb index f4836ce78..26bf70952 100755 --- a/test/util/storage.rb +++ b/test/util/storage.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../lib/puppettest' +require File.expand_path(File.dirname(__FILE__) + '/../lib/puppettest') require 'puppet' require 'puppettest' diff --git a/test/util/subclass_loader.rb b/test/util/subclass_loader.rb index 957b6cc6c..c3453157e 100755 --- a/test/util/subclass_loader.rb +++ b/test/util/subclass_loader.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../lib/puppettest' +require File.expand_path(File.dirname(__FILE__) + '/../lib/puppettest') require 'puppettest' require 'puppet/util/subclass_loader' diff --git a/test/util/utiltest.rb b/test/util/utiltest.rb index 0e55e1dde..1c934d612 100755 --- a/test/util/utiltest.rb +++ b/test/util/utiltest.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../lib/puppettest' +require File.expand_path(File.dirname(__FILE__) + '/../lib/puppettest') require 'puppettest' require 'mocha' |