# File lib/mcollective/application.rb, line 242 def main STDERR.puts "Applications need to supply a 'main' method" exit 1 end
retrieves a specific option
# File lib/mcollective/application.rb, line 20 def [](option) intialize_application_options unless @application_options @application_options[option] end
set an option in the options hash
# File lib/mcollective/application.rb, line 14 def []=(option, value) intialize_application_options unless @application_options @application_options[option] = value end
Intialize a blank set of options if its the first time used else returns active options
# File lib/mcollective/application.rb, line 8 def application_options intialize_application_options unless @application_options @application_options end
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, line 28 def description(descr) self[:description] = descr end
Creates an empty set of options
# File lib/mcollective/application.rb, line 68 def intialize_application_options @application_options = {:description => nil, :usage => [], :cli_arguments => []} end
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, line 54 def option(name, arguments) opt = {:name => name, :description => nil, :arguments => [], :type => String, :required => false, :validate => Proc.new { true }} arguments.each_pair{|k,v| opt[k] = v} self[:cli_arguments] << opt end
Supplies usage information, calling multiple times will create multiple usage lines in –help output
# File lib/mcollective/application.rb, line 34 def usage(usage) self[:usage] << usage end
Returns an array of all the arguments built using calls to optin
# File lib/mcollective/application.rb, line 202 def application_cli_arguments self.class.application_options[:cli_arguments] end
Retrieve the current application description
# File lib/mcollective/application.rb, line 189 def application_description self.class.application_options[:description] end
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, line 208 def application_failure(e) STDERR.puts "#{$0} failed to run: #{e} (#{e.class})" if options e.backtrace.each{|l| STDERR.puts "\tfrom #{l}"} if options[:verbose] else e.backtrace.each{|l| STDERR.puts "\tfrom #{l}"} end MCollective::PluginManager["connector_plugin"].disconnect rescue true exit 1 end
Builds an ObjectParser config, parse the CLI options and validates based on the option config
# File lib/mcollective/application.rb, line 99 def application_parse_options @options = rpcoptions do |parser, options| parser.define_head application_description if application_description parser.banner = "" if application_usage parser.separator "" application_usage.each do |u| parser.separator "Usage: #{u}" end parser.separator "" end parser.define_tail "" parser.define_tail "The Marionette Collective #{MCollective.version}" application_cli_arguments.each do |carg| opts_array = [] opts_array << :on # if a default is set from the application set it up front if carg.include?(:default) configuration[carg[:name]] = carg[:default] end # :arguments are multiple possible ones if carg[:arguments].is_a?(Array) carg[:arguments].each {|a| opts_array << a} else opts_array << carg[:arguments] end # type was given and its not one of our special types, just pass it onto optparse opts_array << carg[:type] if carg[:type] and ! [:bool, :array].include?(carg[:type]) opts_array << carg[:description] # Handle our special types else just rely on the optparser to handle the types if carg[:type] == :bool parser.send(*opts_array) do |v| validate_option(carg[:validate], carg[:name], v) configuration[carg[:name]] = true end elsif carg[:type] == :array parser.send(*opts_array) do |v| validate_option(carg[:validate], carg[:name], v) configuration[carg[:name]] = [] unless configuration.include?(carg[:name]) configuration[carg[:name]] << v end else parser.send(*opts_array) do |v| validate_option(carg[:validate], carg[:name], v) configuration[carg[:name]] = v end end end end # Check all required parameters were set validation_passed = true application_cli_arguments.each do |carg| # Check for required arguments if carg[:required] unless configuration[ carg[:name] ] validation_passed = false STDERR.puts "The #{carg[:name]} option is mandatory" end end end unless validation_passed STDERR.puts "\nPlease run with --help for detailed help" exit 1 end post_option_parser(configuration) if respond_to?(:post_option_parser) rescue Exception => e application_failure(e) end
Return the current usage text false if nothing is set
# File lib/mcollective/application.rb, line 194 def application_usage usage = self.class.application_options[:usage] usage.empty? ? false : usage end
The application configuration built from CLI arguments
# File lib/mcollective/application.rb, line 76 def configuration @application_configuration ||= {} @application_configuration end
Fake abstract class that logs if the user tries to use an application without supplying a main override method.
# File lib/mcollective/application.rb, line 242 def main STDERR.puts "Applications need to supply a 'main' method" exit 1 end
The active options hash used for MC::Client and other configuration
# File lib/mcollective/application.rb, line 82 def options @options end
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
# File lib/mcollective/application.rb, line 250 def rpcclient(agent, flags = {}) flags[:options] = options unless flags.include?(:options) super end
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, line 225 def run application_parse_options validate_configuration(configuration) if respond_to?(:validate_configuration) main MCollective::PluginManager["connector_plugin"].disconnect rescue true rescue SystemExit raise rescue Exception => e application_failure(e) end
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, line 88 def validate_option(blk, name, value) validation_result = blk.call(value) unless validation_result == true STDERR.puts "Validation of #{name} failed: #{validation_result}" exit 1 end end