class Puppet::Application::Apply
Public Instance Methods
app_defaults()
click to toggle source
Calls superclass method
Puppet::Application#app_defaults
# File lib/puppet/application/apply.rb 172 def app_defaults 173 super.merge({ 174 :default_file_terminus => :file_server, 175 :write_catalog_summary => false 176 }) 177 end
apply()
click to toggle source
# File lib/puppet/application/apply.rb 192 def apply 193 if options[:catalog] == "-" 194 text = $stdin.read 195 else 196 text = Puppet::FileSystem.read(options[:catalog], :encoding => 'utf-8') 197 end 198 env = Puppet.lookup(:environments).get(Puppet[:environment]) 199 Puppet.override(:current_environment => env, :loaders => create_loaders(env)) do 200 catalog = read_catalog(text) 201 apply_catalog(catalog) 202 end 203 end
help()
click to toggle source
# File lib/puppet/application/apply.rb 41 def help 42 <<-HELP 43 44 puppet-apply(8) -- #{summary} 45 ======== 46 47 SYNOPSIS 48 -------- 49 Applies a standalone Puppet manifest to the local system. 50 51 52 USAGE 53 ----- 54 puppet apply [-h|--help] [-V|--version] [-d|--debug] [-v|--verbose] 55 [-e|--execute] [--detailed-exitcodes] [-L|--loadclasses] 56 [-l|--logdest syslog|eventlog|<ABS FILEPATH>|console] [--noop] 57 [--catalog <catalog>] [--write-catalog-summary] <file> 58 59 60 DESCRIPTION 61 ----------- 62 This is the standalone puppet execution tool; use it to apply 63 individual manifests. 64 65 When provided with a modulepath, via command line or config file, puppet 66 apply can effectively mimic the catalog that would be served by puppet 67 master with access to the same modules, although there are some subtle 68 differences. When combined with scheduling and an automated system for 69 pushing manifests, this can be used to implement a serverless Puppet 70 site. 71 72 Most users should use 'puppet agent' and 'puppet master' for site-wide 73 manifests. 74 75 76 OPTIONS 77 ------- 78 Any setting that's valid in the configuration 79 file is a valid long argument for puppet apply. For example, 'tags' is a 80 valid setting, so you can specify '--tags <class>,<tag>' 81 as an argument. 82 83 See the configuration file documentation at 84 https://puppet.com/docs/puppet/latest/configuration.html for the 85 full list of acceptable parameters. You can generate a commented list of all 86 configuration options by running puppet with 87 '--genconfig'. 88 89 * --debug: 90 Enable full debugging. 91 92 * --detailed-exitcodes: 93 Provide extra information about the run via exit codes. If enabled, 'puppet 94 apply' will use the following exit codes: 95 96 0: The run succeeded with no changes or failures; the system was already in 97 the desired state. 98 99 1: The run failed. 100 101 2: The run succeeded, and some resources were changed. 102 103 4: The run succeeded, and some resources failed. 104 105 6: The run succeeded, and included both changes and failures. 106 107 * --help: 108 Print this help message 109 110 * --loadclasses: 111 Load any stored classes. 'puppet agent' caches configured classes 112 (usually at /etc/puppetlabs/puppet/classes.txt), and setting this option causes 113 all of those classes to be set in your puppet manifest. 114 115 * --logdest: 116 Where to send log messages. Choose between 'syslog' (the POSIX syslog 117 service), 'eventlog' (the Windows Event Log), 'console', or the path to a log 118 file. Defaults to 'console'. 119 Multiple destinations can be set using a comma separated list 120 (eg: `/path/file1,console,/path/file2`)" 121 122 A path ending with '.json' will receive structured output in JSON format. The 123 log file will not have an ending ']' automatically written to it due to the 124 appending nature of logging. It must be appended manually to make the content 125 valid JSON. 126 127 A path ending with '.jsonl' will receive structured output in JSON Lines 128 format. 129 130 * --noop: 131 Use 'noop' mode where Puppet runs in a no-op or dry-run mode. This 132 is useful for seeing what changes Puppet will make without actually 133 executing the changes. 134 135 * --execute: 136 Execute a specific piece of Puppet code 137 138 * --test: 139 Enable the most common options used for testing. These are 'verbose', 140 'detailed-exitcodes' and 'show_diff'. 141 142 * --verbose: 143 Print extra information. 144 145 * --catalog: 146 Apply a JSON catalog (such as one generated with 'puppet master --compile'). You can 147 either specify a JSON file or pipe in JSON from standard input. 148 149 * --write-catalog-summary 150 After compiling the catalog saves the resource list and classes list to the node 151 in the state directory named classes.txt and resources.txt 152 153 EXAMPLE 154 ------- 155 $ puppet apply -l /tmp/manifest.log manifest.pp 156 $ puppet apply --modulepath=/root/dev/modules -e "include ntpd::server" 157 $ puppet apply --catalog catalog.json 158 159 160 AUTHOR 161 ------ 162 Luke Kanies 163 164 165 COPYRIGHT 166 --------- 167 Copyright (c) 2011 Puppet Inc., LLC Licensed under the Apache 2.0 License 168 169 HELP 170 end
main()
click to toggle source
# File lib/puppet/application/apply.rb 205 def main 206 manifest = get_manifest() # Get either a manifest or nil if apply should use content of Puppet[:code] 207 splay # splay if needed 208 facts = get_facts() # facts or nil 209 node = get_node() # node or error 210 apply_environment = get_configured_environment(node, manifest) 211 212 # TRANSLATORS "puppet apply" is a program command and should not be translated 213 Puppet.override({:current_environment => apply_environment, :loaders => create_loaders(apply_environment)}, _("For puppet apply")) do 214 configure_node_facts(node, facts) 215 216 # Allow users to load the classes that puppet agent creates. 217 if options[:loadclasses] 218 file = Puppet[:classfile] 219 if Puppet::FileSystem.exist?(file) 220 unless FileTest.readable?(file) 221 $stderr.puts _("%{file} is not readable") % { file: file } 222 exit(63) 223 end 224 node.classes = Puppet::FileSystem.read(file, :encoding => 'utf-8').split(/[\s]+/) 225 end 226 end 227 228 begin 229 # Compile the catalog 230 starttime = Time.now 231 232 # When compiling, the compiler traps and logs certain errors 233 # Those that do not lead to an immediate exit are caught by the general 234 # rule and gets logged. 235 # 236 catalog = 237 begin 238 Puppet::Resource::Catalog.indirection.find(node.name, :use_node => node) 239 rescue Puppet::Error 240 # already logged and handled by the compiler, including Puppet::ParseErrorWithIssue 241 exit(1) 242 end 243 244 # Resolve all deferred values and replace them / mutate the catalog 245 Puppet::Pops::Evaluator::DeferredResolver.resolve_and_replace(node.facts, catalog, apply_environment, Puppet[:preprocess_deferred]) 246 247 # Translate it to a RAL catalog 248 catalog = catalog.to_ral 249 250 catalog.finalize 251 252 catalog.retrieval_duration = Time.now - starttime 253 254 # We accept either the global option `--write_catalog_summary` 255 # corresponding to the new setting, or the application option 256 # `--write-catalog-summary`. The latter is needed to maintain backwards 257 # compatibility. 258 # 259 # Puppet settings parse global options using PuppetOptionParser, but it 260 # only recognizes underscores, not dashes. 261 # The base application parses app specific options using ruby's builtin 262 # OptionParser. As of ruby 2.4, it will accept either underscores or 263 # dashes, but prefer dashes. 264 # 265 # So if underscores are used, the PuppetOptionParser will parse it and 266 # store that in Puppet[:write_catalog_summary]. If dashes are used, 267 # OptionParser will parse it, and set Puppet[:write_catalog_summary]. In 268 # either case, settings will contain the correct value. 269 if Puppet[:write_catalog_summary] 270 catalog.write_class_file 271 catalog.write_resource_file 272 end 273 274 exit_status = apply_catalog(catalog) 275 276 if not exit_status 277 exit(1) 278 elsif options[:detailed_exitcodes] then 279 exit(exit_status) 280 else 281 exit(0) 282 end 283 rescue => detail 284 Puppet.log_exception(detail) 285 exit(1) 286 end 287 end 288 end
run_command()
click to toggle source
# File lib/puppet/application/apply.rb 179 def run_command 180 if options[:catalog] 181 apply 182 else 183 main 184 end 185 ensure 186 if @profiler 187 Puppet::Util::Profiler.remove_profiler(@profiler) 188 @profiler.shutdown 189 end 190 end
setup()
click to toggle source
# File lib/puppet/application/apply.rb 298 def setup 299 setup_test if options[:test] 300 301 exit(Puppet.settings.print_configs ? 0 : 1) if Puppet.settings.print_configs? 302 303 handle_logdest_arg(Puppet[:logdest]) 304 Puppet::Util::Log.newdestination(:console) unless options[:setdest] 305 306 Signal.trap(:INT) do 307 $stderr.puts _("Exiting") 308 exit(1) 309 end 310 311 Puppet.settings.use :main, :agent, :ssl 312 313 314 if Puppet[:catalog_cache_terminus] 315 Puppet::Resource::Catalog.indirection.cache_class = Puppet[:catalog_cache_terminus] 316 end 317 318 # we want the last report to be persisted locally 319 Puppet::Transaction::Report.indirection.cache_class = :yaml 320 321 set_log_level 322 323 if Puppet[:profile] 324 @profiler = Puppet::Util::Profiler.add_profiler(Puppet::Util::Profiler::Aggregate.new(Puppet.method(:info), "apply")) 325 end 326 end
setup_test()
click to toggle source
Enable all of the most common test options.
# File lib/puppet/application/apply.rb 291 def setup_test 292 Puppet.settings.handlearg("--no-splay") 293 Puppet.settings.handlearg("--show_diff") 294 options[:verbose] = true 295 options[:detailed_exitcodes] = true 296 end
summary()
click to toggle source
# File lib/puppet/application/apply.rb 37 def summary 38 _("Apply Puppet manifests locally") 39 end
Private Instance Methods
apply_catalog(catalog)
click to toggle source
# File lib/puppet/application/apply.rb 360 def apply_catalog(catalog) 361 configurer = Puppet::Configurer.new 362 configurer.run(:catalog => catalog, :pluginsync => false) 363 end
configure_node_facts(node, facts)
click to toggle source
Mixes the facts into the node, and mixes in server facts
# File lib/puppet/application/apply.rb 424 def configure_node_facts(node, facts) 425 node.merge(facts.values) if facts 426 # Add server facts so $server_facts[environment] exists when doing a puppet apply 427 node.add_server_facts({}) 428 end
create_loaders(env)
click to toggle source
# File lib/puppet/application/apply.rb 330 def create_loaders(env) 331 # Ignore both 'cached_puppet_lib' and pcore resource type loaders 332 Puppet::Pops::Loaders.new(env, false, false) 333 end
get_configured_environment(node, manifest = nil)
click to toggle source
Returns a configured environment, if a manifest is given it overrides what is configured for the environment specified by the node (or the current_environment found in the Puppet context). The node's resolved environment is modified if needed.
# File lib/puppet/application/apply.rb 407 def get_configured_environment(node, manifest = nil) 408 configured_environment = node.environment || Puppet.lookup(:current_environment) 409 410 apply_environment = manifest ? 411 configured_environment.override_with(:manifest => manifest) : 412 configured_environment 413 414 # Modify the node descriptor to use the special apply_environment. 415 # It is based on the actual environment from the node, or the locally 416 # configured environment if the node does not specify one. 417 # If a manifest file is passed on the command line, it overrides 418 # the :manifest setting of the apply_environment. 419 node.environment = apply_environment 420 apply_environment 421 end
get_facts()
click to toggle source
Returns facts or nil
# File lib/puppet/application/apply.rb 367 def get_facts() 368 facts = nil 369 unless Puppet[:node_name_fact].empty? 370 # Collect our facts. 371 facts = Puppet::Node::Facts.indirection.find(Puppet[:node_name_value]) 372 raise _("Could not find facts for %{node}") % { node: Puppet[:node_name_value] } unless facts 373 374 Puppet[:node_name_value] = facts.values[Puppet[:node_name_fact]] 375 facts.name = Puppet[:node_name_value] 376 end 377 facts 378 end
get_manifest()
click to toggle source
Returns either a manifest (filename) or nil if apply should use content of Puppet
# File lib/puppet/application/apply.rb 390 def get_manifest() 391 manifest = nil 392 # Set our code or file to use. 393 if options[:code] or command_line.args.length == 0 394 Puppet[:code] = options[:code] || STDIN.read 395 else 396 manifest = command_line.args.shift 397 raise _("Could not find file %{manifest}") % { manifest: manifest } unless Puppet::FileSystem.exist?(manifest) 398 Puppet.warning(_("Only one file can be applied per run. Skipping %{files}") % { files: command_line.args.join(', ') }) if command_line.args.size > 0 399 end 400 manifest 401 end
get_node()
click to toggle source
Returns the node or raises and error if node not found.
# File lib/puppet/application/apply.rb 382 def get_node() 383 node = Puppet::Node.indirection.find(Puppet[:node_name_value]) 384 raise _("Could not find node %{node}") % { node: Puppet[:node_name_value] } unless node 385 node 386 end
read_catalog(text)
click to toggle source
# File lib/puppet/application/apply.rb 335 def read_catalog(text) 336 facts = get_facts() 337 node = get_node() 338 configured_environment = get_configured_environment(node) 339 340 # TRANSLATORS "puppet apply" is a program command and should not be translated 341 Puppet.override({:current_environment => configured_environment}, _("For puppet apply")) do 342 configure_node_facts(node, facts) 343 344 # NOTE: Does not set rich_data = true automatically (which would ensure always reading catalog with rich data 345 # on (seemingly the right thing to do)), but that would remove the ability to test what happens when a 346 # rich catalog is processed without rich_data being turned on. 347 format = Puppet::Resource::Catalog.default_format 348 begin 349 catalog = Puppet::Resource::Catalog.convert_from(format, text) 350 rescue => detail 351 raise Puppet::Error, _("Could not deserialize catalog from %{format}: %{detail}") % { format: format, detail: detail }, detail.backtrace 352 end 353 # Resolve all deferred values and replace them / mutate the catalog 354 Puppet::Pops::Evaluator::DeferredResolver.resolve_and_replace(node.facts, catalog, configured_environment, Puppet[:preprocess_deferred]) 355 356 catalog.to_ral 357 end 358 end