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