diff --git a/lib/puppet/application/apply.rb b/lib/puppet/application/apply.rb index 1a5ab2c0c..37029cfb5 100644 --- a/lib/puppet/application/apply.rb +++ b/lib/puppet/application/apply.rb @@ -1,236 +1,252 @@ require 'puppet/application' class Puppet::Application::Apply < Puppet::Application should_parse_config option("--debug","-d") option("--execute EXECUTE","-e") do |arg| options[:code] = arg end option("--loadclasses","-L") option("--verbose","-v") option("--use-nodes") option("--detailed-exitcodes") option("--apply catalog", "-a catalog") do |arg| options[:catalog] = arg end option("--logdest LOGDEST", "-l") do |arg| begin Puppet::Util::Log.newdestination(arg) options[:logset] = true rescue => detail $stderr.puts detail.to_s end end def help <<-HELP -SYNOPSIS +puppet-apply(8) -- Apply Puppet manifests locally ======== -Run a stand-alone 'puppet' manifest. + +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 ] +----- +puppet apply [-h|--help] [-V|--version] [-d|--debug] [-v|--verbose] + [-e|--execute] [--detailed-exitcodes] [-l|--logdest ] DESCRIPTION -=========== -This is the standalone puppet execution tool; use it to execute -individual manifests that you write. If you need to execute site-wide -manifests, use 'puppet agent' and 'puppet master'. +----------- +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, 'ssldir' is a valid -configuration parameter, so you can specify '--ssldir ' as an -argument. +file is also a valid long argument. For example, 'modulepath' is a +valid configuration parameter, so you can specify '--tags ,' +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. +* --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. +* --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 +* --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. +* --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. +* --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 +* --execute: + Execute a specific piece of Puppet code -verbose: Print extra information. +* --verbose: + Print extra information. EXAMPLE -======= - puppet -l /tmp/manifest.log manifest.pp +------- + $ 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 elsif Puppet[:parseonly] parseonly else main end end def apply if options[:catalog] == "-" text = $stdin.read else text = File.read(options[:catalog]) end begin catalog = Puppet::Resource::Catalog.convert_from(Puppet::Resource::Catalog.default_format,text) catalog = Puppet::Resource::Catalog.pson_create(catalog) unless catalog.is_a?(Puppet::Resource::Catalog) rescue => detail raise Puppet::Error, "Could not deserialize catalog from pson: #{detail}" end catalog = catalog.to_ral require 'puppet/configurer' configurer = Puppet::Configurer.new configurer.run :catalog => catalog end def parseonly # Set our code or file to use. if options[:code] or command_line.args.length == 0 Puppet[:code] = options[:code] || STDIN.read else Puppet[:manifest] = command_line.args.shift end begin Puppet::Node::Environment.new(Puppet[:environment]).known_resource_types rescue => detail Puppet.err detail exit 1 end exit 0 end def main # Set our code or file to use. if options[:code] or command_line.args.length == 0 Puppet[:code] = options[:code] || STDIN.read else manifest = command_line.args.shift raise "Could not find file #{manifest}" unless File.exist?(manifest) Puppet.warning("Only one file can be applied per run. Skipping #{command_line.args.join(', ')}") if command_line.args.size > 0 Puppet[:manifest] = manifest end # Collect our facts. 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.indirection.find(Puppet[:certname]) raise "Could not find node #{Puppet[:certname]}" end # Merge in the facts. node.merge(facts.values) # Allow users to load the classes that puppet agent creates. if options[:loadclasses] file = Puppet[:classfile] if FileTest.exists?(file) unless FileTest.readable?(file) $stderr.puts "#{file} is not readable" exit(63) end node.classes = File.read(file).split(/[\s\n]+/) end end begin # Compile our catalog starttime = Time.now catalog = Puppet::Resource::Catalog.indirection.find(node.name, :use_node => node) # Translate it to a RAL catalog catalog = catalog.to_ral catalog.finalize catalog.retrieval_duration = Time.now - starttime require 'puppet/configurer' configurer = Puppet::Configurer.new report = configurer.run(:skip_plugin_download => true, :catalog => catalog) exit( Puppet[:noop] ? 0 : options[:detailed_exitcodes] ? report.exit_status : 0 ) rescue => detail puts detail.backtrace if Puppet[:trace] $stderr.puts detail.message exit(1) end end def setup exit(Puppet.settings.print_configs ? 0 : 1) if Puppet.settings.print_configs? # If noop is set, then also enable diffs Puppet[:show_diff] = true if Puppet[:noop] Puppet::Util::Log.newdestination(:console) unless options[:logset] client = nil server = nil trap(:INT) do $stderr.puts "Exiting" exit(1) end # we want the last report to be persisted locally Puppet::Transaction::Report.indirection.cache_class = :yaml if options[:debug] Puppet::Util::Log.level = :debug elsif options[:verbose] Puppet::Util::Log.level = :info end end end