Class: Puppet::Application

Inherits:
Object show all
Extended by:
Util
Includes:
Util
Defined in:
lib/puppet/application.rb

Direct Known Subclasses

Agent, Apply, Cert, Describe, Doc, Filebucket, Inspect, Master, Queue, Resource

Defined Under Namespace

Classes: Agent, Apply, Cert, Describe, Doc, Filebucket, Inspect, Master, Queue, Resource

Constant Summary collapse

DOCPATTERN =
File.expand_path(File.dirname(__FILE__) + "/util/command_line/*" )

Class Attribute Summary collapse

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Util

activerecord_version, benchmark, chuser, classproxy, execfail, execpipe, execute, logmethods, memory, proxy, recmkdir, secure_open, symbolize, symbolizehash, symbolizehash!, synchronize_on, thinmark, threadlock, which, withumask

Methods included from Util::POSIX

#get_posix_field, #gid, #idfield, #methodbyid, #methodbyname, #search_posix_field, #uid

Constructor Details

#initialize(command_line = nil) ⇒ Application

Returns a new instance of Application.



265
266
267
268
269
270
271
272
# File 'lib/puppet/application.rb', line 265

def initialize(command_line = nil)
  require 'puppet/util/command_line'
  @command_line = command_line || Puppet::Util::CommandLine.new
  set_run_mode self.class.run_mode
  @options = {}

  require 'puppet'
end

Class Attribute Details

.run_statusObject

Returns the value of attribute run_status.



127
128
129
# File 'lib/puppet/application.rb', line 127

def run_status
  @run_status
end

Instance Attribute Details

#command_lineObject (readonly)

Returns the value of attribute command_line.



244
245
246
# File 'lib/puppet/application.rb', line 244

def command_line
  @command_line
end

#optionsObject (readonly)

Returns the value of attribute options.



244
245
246
# File 'lib/puppet/application.rb', line 244

def options
  @options
end

Class Method Details

.[](name) ⇒ Object



229
230
231
# File 'lib/puppet/application.rb', line 229

def [](name)
  find(name).new
end


204
205
206
# File 'lib/puppet/application.rb', line 204

def banner(banner = nil)
  @banner ||= banner
end

.clear!Object



129
130
131
# File 'lib/puppet/application.rb', line 129

def clear!
  self.run_status = nil
end

.clear?Boolean

Indicates that Puppet::Application believes that it’s in usual running run_mode (no stop/restart request currently active).

Returns:

  • (Boolean)


161
162
163
# File 'lib/puppet/application.rb', line 161

def clear?
  run_status.nil?
end

.controlled_run(&block) ⇒ Object

Only executes the given block if the run status of Puppet::Application is clear (no restarts, stops, etc. requested). Upon block execution, checks the run status again; if a restart has been requested during the block’s execution, then controlled_run will send a new HUP signal to the current process. Thus, long-running background processes can potentially finish their work before a restart.



170
171
172
173
174
175
# File 'lib/puppet/application.rb', line 170

def controlled_run(&block)
  return unless clear?
  result = block.call
  Process.kill(:HUP, $PID) if restart_requested?
  result
end

.exit(code) ⇒ Object

this is used for testing



380
381
382
# File 'lib/puppet/application.rb', line 380

def self.exit(code)
  exit(code)
end

.find(name) ⇒ Object



215
216
217
218
219
220
221
222
223
224
225
226
227
# File 'lib/puppet/application.rb', line 215

def find(name)
  klass = name.to_s.capitalize

  # const_defined? is used before const_get since const_defined? will only
  # check within our namespace, whereas const_get will check ancestor
  # trees as well, resulting in unexpected behaviour.
  if !self.const_defined?(klass)
    puts "Unable to find application '#{name.to_s}'."
    Kernel::exit(1)
  end

  self.const_get(klass)
end

.interrupted?Boolean

Indicates that one of stop! or start! was invoked on Puppet::Application, and some kind of process shutdown/short-circuit may be necessary.

Returns:

  • (Boolean)


155
156
157
# File 'lib/puppet/application.rb', line 155

def interrupted?
  [:restart_requested, :stop_requested].include? run_status
end

.option(*options, &block) ⇒ Object

used to declare code that handle an option



191
192
193
194
195
196
197
198
199
200
201
202
# File 'lib/puppet/application.rb', line 191

def option(*options, &block)
  long = options.find { |opt| opt =~ /^--/ }.gsub(/^--(?:\[no-\])?([^ =]+).*$/, '\1' ).gsub('-','_')
  fname = symbolize("handle_#{long}")
  if (block_given?)
    define_method(fname, &block)
  else
    define_method(fname) do |value|
      self.options["#{long}".to_sym] = value
    end
  end
  self.option_parser_commands << [options, fname]
end

.option_parser_commandsObject



208
209
210
211
212
213
# File 'lib/puppet/application.rb', line 208

def option_parser_commands
  @option_parser_commands ||= (
    superclass.respond_to?(:option_parser_commands) ? superclass.option_parser_commands.dup : []
  )
  @option_parser_commands
end

.restart!Object



137
138
139
# File 'lib/puppet/application.rb', line 137

def restart!
  self.run_status = :restart_requested
end

.restart_requested?Boolean

Indicates that Puppet::Application.restart! has been invoked and components should do what is necessary to facilitate a restart.

Returns:

  • (Boolean)


143
144
145
# File 'lib/puppet/application.rb', line 143

def restart_requested?
  :restart_requested == run_status
end

.run_mode(mode_name = nil) ⇒ Object

Sets or gets the run_mode name. Sets the run_mode name if a mode_name is passed. Otherwise, gets the run_mode or a default run_mode



236
237
238
239
240
241
# File 'lib/puppet/application.rb', line 236

def run_mode( mode_name = nil)
  return @run_mode if @run_mode and not mode_name

  require 'puppet/util/run_mode'
  @run_mode = Puppet::Util::RunMode[ mode_name || :user ]
end

.should_not_parse_configObject



181
182
183
# File 'lib/puppet/application.rb', line 181

def should_not_parse_config
  @parse_config = false
end

.should_parse_configObject



177
178
179
# File 'lib/puppet/application.rb', line 177

def should_parse_config
  @parse_config = true
end

.should_parse_config?Boolean

Returns:

  • (Boolean)


185
186
187
188
# File 'lib/puppet/application.rb', line 185

def should_parse_config?
  @parse_config = true if ! defined?(@parse_config)
  @parse_config
end

.stop!Object



133
134
135
# File 'lib/puppet/application.rb', line 133

def stop!
  self.run_status = :stop_requested
end

.stop_requested?Boolean

Indicates that Puppet::Application.stop! has been invoked and components should do what is necessary for a clean stop.

Returns:

  • (Boolean)


149
150
151
# File 'lib/puppet/application.rb', line 149

def stop_requested?
  :stop_requested == run_status
end

Instance Method Details

#handlearg(opt, arg) ⇒ Object



361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
# File 'lib/puppet/application.rb', line 361

def handlearg(opt, arg)
  # rewrite --[no-]option to --no-option if that's what was given
  if opt =~ /\[no-\]/ and !arg
    opt = opt.gsub(/\[no-\]/,'no-')
  end
  # otherwise remove the [no-] prefix to not confuse everybody
  opt = opt.gsub(/\[no-\]/, '')
  unless respond_to?(:handle_unknown) and send(:handle_unknown, opt, arg)
    # Puppet.settings.handlearg doesn't handle direct true/false :-)
    if arg.is_a?(FalseClass)
      arg = "false"
    elsif arg.is_a?(TrueClass)
      arg = "true"
    end
    Puppet.settings.handlearg(opt, arg)
  end
end

#helpObject



388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
# File 'lib/puppet/application.rb', line 388

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
end

#mainObject

Raises:

  • (NotImplementedError)


308
309
310
# File 'lib/puppet/application.rb', line 308

def main
  raise NotImplementedError, "No valid command or main"
end

#nameObject



384
385
386
# File 'lib/puppet/application.rb', line 384

def name
  self.class.to_s.sub(/.*::/,"").downcase.to_sym
end

#parse_optionsObject



330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
# File 'lib/puppet/application.rb', line 330

def parse_options
  # Create an option parser
  option_parser = OptionParser.new(self.class.banner)

  # Add all global options to it.
  Puppet.settings.optparse_addargs([]).each do |option|
    option_parser.on(*option) do |arg|
      handlearg(option[0], arg)
    end
  end

  # Add options that are local to this application, which were
  # created using the "option()" metaprogramming method.  If there
  # are any conflicts, this application's options will be favored.
  self.class.option_parser_commands.each do |options, fname|
    option_parser.on(*options) do |value|
      # Call the method that "option()" created.
      self.send(fname, value)
    end
  end

  # scan command line.
  begin
    option_parser.parse!(self.command_line.args)
  rescue OptionParser::ParseError => detail
    $stderr.puts detail
    $stderr.puts "Try 'puppet #{command_line.subcommand_name} --help'"
    exit(1)
  end
end

#preinitObject

override to execute code before running anything else



262
263
# File 'lib/puppet/application.rb', line 262

def preinit
end

#runObject

This is the main application entry point



300
301
302
303
304
305
306
# File 'lib/puppet/application.rb', line 300

def run
  exit_on_fail("initialize")               { hook('preinit')       { preinit } }
  exit_on_fail("parse options")            { hook('parse_options') { parse_options } }
  exit_on_fail("parse configuration file") { Puppet.settings.parse } if should_parse_config?
  exit_on_fail("prepare for execution")    { hook('setup')         { setup } }
  exit_on_fail("run")                      { hook('run_command')   { run_command } }
end

#run_commandObject



312
313
314
# File 'lib/puppet/application.rb', line 312

def run_command
  main
end

#set_run_mode(mode) ⇒ Object

WARNING: This is a totally scary, frightening, and nasty internal API. We strongly advise that you do not use this, and if you insist, we will politely allow you to keep both pieces of your broken code.

We plan to provide a supported, long-term API to deliver this in a way that you can use. Please make sure that you let us know if you do require this, and this message is still present in the code. –daniel 2011-02-03



281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
# File 'lib/puppet/application.rb', line 281

def set_run_mode(mode)
  @run_mode = mode
  $puppet_application_mode = @run_mode
  $puppet_application_name = name

  if Puppet.respond_to? :settings
    # This is to reduce the amount of confusion in rspec
    # because it might have loaded defaults.rb before the globals were set
    # and thus have the wrong defaults for the current application
    Puppet.settings.set_value(:confdir, Puppet.run_mode.conf_dir, :mutable_defaults)
    Puppet.settings.set_value(:vardir, Puppet.run_mode.var_dir, :mutable_defaults)
    Puppet.settings.set_value(:name, Puppet.application_name.to_s, :mutable_defaults)
    Puppet.settings.set_value(:logdir, Puppet.run_mode.logopts, :mutable_defaults)
    Puppet.settings.set_value(:rundir, Puppet.run_mode.run_dir, :mutable_defaults)
    Puppet.settings.set_value(:run_mode, Puppet.run_mode.name.to_s, :mutable_defaults)
  end
end

#setupObject



316
317
318
319
320
321
322
323
324
325
326
327
328
# File 'lib/puppet/application.rb', line 316

def setup
  # Handle the logging settings
  if options[:debug] or options[:verbose]
    Puppet::Util::Log.newdestination(:console)
    if options[:debug]
      Puppet::Util::Log.level = :debug
    else
      Puppet::Util::Log.level = :info
    end
  end

  Puppet::Util::Log.newdestination(:syslog) unless options[:setdest]
end

#should_parse_config?Boolean

Returns:

  • (Boolean)


257
258
259
# File 'lib/puppet/application.rb', line 257

def should_parse_config?
  self.class.should_parse_config?
end