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