class MCollective::Application - mcollective version 2.12.5

# class MCollective::Application

### Public Class Methods

[](option) click to toggle source

retrieves a specific option

       # File lib/mcollective/application.rb
    22 def [](option)
    23   intialize_application_options unless @application_options
    24   @application_options[option]
    25 end

[]=(option, value) click to toggle source

set an option in the options hash

       # File lib/mcollective/application.rb
    16 def []=(option, value)
    17   intialize_application_options unless @application_options
    18   @application_options[option] = value
    19 end

application_options() click to toggle source

Intialize a blank set of options if its the first time used else returns active options

       # File lib/mcollective/application.rb
    10 def application_options
    11   intialize_application_options unless @application_options
    12   @application_options
    13 end

description(descr) click to toggle source

Sets the application description, there can be only one description per application so multiple calls will just change the description

       # File lib/mcollective/application.rb
    30 def description(descr)
    31   self[:description] = descr
    32 end

exclude_argument_sections(*sections) click to toggle source

       # File lib/mcollective/application.rb
    40 def exclude_argument_sections(*sections)
    41   sections = [sections].flatten
    42
    43   sections.each do |s|
    44     raise "Unknown CLI argument section #{s}" unless ["rpc", "common", "filter"].include?(s)
    45   end
    46
    47   intialize_application_options unless @application_options
    48   self[:exclude_arg_sections] = sections
    49 end

intialize_application_options() click to toggle source

Creates an empty set of options

       # File lib/mcollective/application.rb
    81 def intialize_application_options
    82   @application_options = {:description          => nil,
    83                           :usage                => [],
    84                           :cli_arguments        => [],
    85                           :exclude_arg_sections => []}
    86 end

option(name, arguments) click to toggle source

Wrapper to create command line options

    - name: varaible name that will be used to access the option value
    - description: textual info shown in --help
    - arguments: a list of possible arguments that can be used
      to activate this option
    - type: a data type that ObjectParser understand of :bool or :array
    - required: true or false if this option has to be supplied
    - validate: a proc that will be called with the value used to validate
      the supplied value

     option :foo,
            :description => "The foo option"
            :arguments   => ["--foo ARG"]

after this the value supplied will be in configuration

       # File lib/mcollective/application.rb
    67 def option(name, arguments)
    68   opt = {:name => name,
    69          :description => nil,
    70          :arguments => [],
    71          :type => String,
    72          :required => false,
    73          :validate => Proc.new { true }}
    74
    75   arguments.each_pair{|k,v| opt[k] = v}
    76
    77   self[:cli_arguments] << opt
    78 end

usage(usage) click to toggle source

Supplies usage information, calling multiple times will create multiple usage lines in –help output

       # File lib/mcollective/application.rb
    36 def usage(usage)
    37   self[:usage] << usage
    38 end

### Public Instance Methods

application_cli_arguments() click to toggle source

Returns an array of all the arguments built using calls to optin

        # File lib/mcollective/application.rb
    249 def application_cli_arguments
    250   application_options[:cli_arguments]
    251 end

application_description() click to toggle source

Retrieve the current application description

        # File lib/mcollective/application.rb
    236 def application_description
    237   application_options[:description]
    238 end

application_failure(e, err_dest=STDERR) click to toggle source

Handles failure, if we're far enough in the initialization phase it will log backtraces if its in verbose mode only

        # File lib/mcollective/application.rb
    255 def application_failure(e, err_dest=STDERR)
    256   # peole can use exit() anywhere and not get nasty backtraces as a result
    257   if e.is_a?(SystemExit)
    258     disconnect
    259     raise(e)
    260   end
    261
    262   if options[:verbose]
    263     err_dest.puts "\nThe %s application failed to run: %s\n" % [ Util.colorize(:bold, $0), Util.colorize(:red, e.to_s)]
    264   else
    265     err_dest.puts "\nThe %s application failed to run, use -v for full error backtrace details: %s\n" % [ Util.colorize(:bold, $0), Util.colorize(:red, e.to_s)]
    266   end
    267
    268   if options.nil? || options[:verbose]
    269     e.backtrace.first << Util.colorize(:red, "  <----")
    270     err_dest.puts "\n%s %s" % [ Util.colorize(:red, e.to_s), Util.colorize(:bold, "(#{e.class.to_s})")]
    271     e.backtrace.each{|l| err_dest.puts "\tfrom #{l}"}
    272   end
    273
    274   disconnect
    275
    276   exit 1
    277 end

application_options() click to toggle source

Retrieves the full hash of application options

        # File lib/mcollective/application.rb
    231 def application_options
    232   self.class.application_options
    233 end

application_parse_options(help=false) click to toggle source

Builds an ObjectParser config, parse the CLI options and validates based on the option config

        # File lib/mcollective/application.rb
    137 def application_parse_options(help=false)
    138   @options ||= {:verbose => false}
    139
    140   @options = clioptions(help) do |parser, options|
    141     parser.define_head application_description if application_description
    142     parser.banner = ""
    143
    144     if application_usage
    145       parser.separator ""
    146
    147       application_usage.each do |u|
    148         parser.separator "Usage: #{u}"
    149       end
    150
    151       parser.separator ""
    152     end
    153
    154     parser.separator "Application Options" unless application_cli_arguments.empty?
    155
    156     parser.define_tail ""
    157     parser.define_tail "The Marionette Collective #{MCollective.version}"
    158
    159
    160     application_cli_arguments.each do |carg|
    161       opts_array = []
    162
    163       opts_array << :on
    164
    165       # if a default is set from the application set it up front
    166       if carg.include?(:default)
    167         configuration[carg[:name]] = carg[:default]
    168       end
    169
    170       # :arguments are multiple possible ones
    171       if carg[:arguments].is_a?(Array)
    172         carg[:arguments].each {|a| opts_array << a}
    173       else
    174         opts_array << carg[:arguments]
    175       end
    176
    177       # type was given and its not one of our special types, just pass it onto optparse
    178       opts_array << carg[:type] if carg[:type] && ![:boolean, :bool, :array].include?(carg[:type])
    179
    180       opts_array << carg[:description]
    181
    182       # Handle our special types else just rely on the optparser to handle the types
    183       if [:bool, :boolean].include?(carg[:type])
    184         parser.send(*opts_array) do |v|
    185           validate_option(carg[:validate], carg[:name], v)
    186
    187           configuration[carg[:name]] = v
    188         end
    189
    190       elsif carg[:type] == :array
    191         parser.send(*opts_array) do |v|
    192           validate_option(carg[:validate], carg[:name], v)
    193
    194           configuration[carg[:name]] = [] unless configuration.include?(carg[:name])
    195           configuration[carg[:name]] << v
    196         end
    197
    198       else
    199         parser.send(*opts_array) do |v|
    200           validate_option(carg[:validate], carg[:name], v)
    201
    202           configuration[carg[:name]] = v
    203         end
    204       end
    205     end
    206   end
    207 end

application_usage() click to toggle source

Return the current usage text false if nothing is set

        # File lib/mcollective/application.rb
    241 def application_usage
    242   usage = application_options[:usage]
    243
    244   usage.empty? ? false : usage
    245 end

clioptions(help) { |parser, options| ... } click to toggle source

Creates a standard options hash, pass in a block to add extra headings etc see `Optionparser`

        # File lib/mcollective/application.rb
    113 def clioptions(help)
    114   oparser = Optionparser.new({:verbose => false, :progress_bar => true}, "filter", application_options[:exclude_arg_sections])
    115
    116   options = oparser.parse do |parser, options|
    117     if block_given?
    118       yield(parser, options)
    119     end
    120
    121     RPC::Helpers.add_simplerpc_options(parser, options) unless application_options[:exclude_arg_sections].include?("rpc")
    122   end
    123
    124   return oparser.parser.help if help
    125
    126   validate_cli_options
    127
    128   post_option_parser(configuration) if respond_to?(:post_option_parser)
    129
    130   return options
    131 rescue Exception => e
    132   application_failure(e)
    133 end

configuration() click to toggle source

The application configuration built from CLI arguments

       # File lib/mcollective/application.rb
    90 def configuration
    91   @application_configuration ||= {}
    92   @application_configuration
    93 end

disconnect() click to toggle source

        # File lib/mcollective/application.rb
    301 def disconnect
    302   MCollective::PluginManager["connector_plugin"].disconnect
    303 rescue
    304 end

halt(stats) click to toggle source

A helper that creates a consistent exit code for applications by looking at an instance of `MCollective::RPC::Stats`

Exit with 0 if nodes were discovered and all passed Exit with 0 if no discovery were done and > 0 responses were received, all ok Exit with 1 if no nodes were discovered Exit with 2 if nodes were discovered but some `RPC` requests failed Exit with 3 if nodes were discovered, but no responses received Exit with 4 if no discovery were done and no responses were received

        # File lib/mcollective/application.rb
    351 def halt(stats)
    352   exit(halt_code(stats))
    353 end

halt_code(stats) click to toggle source

        # File lib/mcollective/application.rb
    313 def halt_code(stats)
    314   request_stats = {:discoverytime => 0,
    315                    :discovered => 0,
    316                    :okcount => 0,
    317                    :failcount => 0}.merge(stats.to_hash)
    318
    319   if (request_stats[:discoverytime] == 0 && request_stats[:responses] == 0)
    320     return 4
    321   end
    322
    323   if (request_stats[:discovered] > 0)
    324     if (request_stats[:responses] == 0)
    325       return 3
    326     elsif (request_stats[:failcount] > 0)
    327       return 2
    328     end
    329   end
    330
    331   if (request_stats[:discovered] == 0)
    332     if (request_stats[:responses] && request_stats[:responses] > 0)
    333       return 0
    334     else
    335       return 1
    336     end
    337   end
    338
    339   return 0
    340 end

help() click to toggle source

        # File lib/mcollective/application.rb
    279 def help
    280   application_parse_options(true)
    281 end

main() click to toggle source

Fake abstract class that logs if the user tries to use an application without supplying a main override method.

        # File lib/mcollective/application.rb
    308 def main
    309   STDERR.puts "Applications need to supply a 'main' method"
    310   exit 1
    311 end

options() click to toggle source

The active options hash used for MC::Client and other configuration

       # File lib/mcollective/application.rb
    96 def options
    97   @options
    98 end

rpcclient(agent, flags = {}) click to toggle source

Wrapper around MC::RPC#rpcclient that forcably supplies our options hash if someone forgets to pass in options in an application the filters and other cli options wouldnt take effect which could have a disasterous outcome

Calls superclass method `MCollective::RPC#rpcclient`

        # File lib/mcollective/application.rb
    358 def rpcclient(agent, flags = {})
    359   flags[:options] = options unless flags.include?(:options)
    360   flags[:exit_on_failure] = false
    361
    362   super
    363 end

run() click to toggle source

The main logic loop, builds up the options, validate configuration and calls the main as supplied by the user. Disconnects when done and pass any exception onto the `application_failure` helper

        # File lib/mcollective/application.rb
    286 def run
    287   application_parse_options
    288
    289   validate_configuration(configuration) if respond_to?(:validate_configuration)
    290
    291   Util.setup_windows_sleeper if Util.windows?
    292
    293   main
    294
    295   disconnect
    296
    297 rescue Exception => e
    298   application_failure(e)
    299 end

validate_cli_options() click to toggle source

        # File lib/mcollective/application.rb
    209 def validate_cli_options
    210   # Check all required parameters were set
    211   validation_passed = true
    212   application_cli_arguments.each do |carg|
    213     # Check for required arguments
    214     if carg[:required]
    215       unless configuration[ carg[:name] ]
    216         validation_passed = false
    217         STDERR.puts "The #{carg[:name]} option is mandatory"
    218       end
    219     end
    220   end
    221
    222   unless validation_passed
    223     STDERR.puts "\nPlease run with --help for detailed help"
    224     exit 1
    225   end
    226
    227
    228 end

validate_option(blk, name, value) click to toggle source

Calls the supplied block in an option for validation, an error raised will log to STDERR and exit the application

        # File lib/mcollective/application.rb
    102 def validate_option(blk, name, value)
    103   validation_result = blk.call(value)
    104
    105   unless validation_result == true
    106     STDERR.puts "Validation of #{name} failed: #{validation_result}"
    107     exit 1
    108   end
    109 end