Class | MCollective::Application |
In: |
lib/mcollective/application.rb
|
Parent: | Object |
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 28: def description(descr) 29: self[:description] = descr 30: 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[:foo]
# File lib/mcollective/application.rb, line 54 54: def option(name, arguments) 55: opt = {:name => name, 56: :description => nil, 57: :arguments => [], 58: :type => String, 59: :required => false, 60: :validate => Proc.new { true }} 61: 62: arguments.each_pair{|k,v| opt[k] = v} 63: 64: self[:cli_arguments] << opt 65: end
Returns an array of all the arguments built using calls to optin
# File lib/mcollective/application.rb, line 202 202: def application_cli_arguments 203: self.class.application_options[:cli_arguments] 204: end
Retrieve the current application description
# File lib/mcollective/application.rb, line 189 189: def application_description 190: self.class.application_options[:description] 191: 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 208: def application_failure(e) 209: STDERR.puts "#{$0} failed to run: #{e} (#{e.class})" 210: 211: if options 212: e.backtrace.each{|l| STDERR.puts "\tfrom #{l}"} if options[:verbose] 213: else 214: e.backtrace.each{|l| STDERR.puts "\tfrom #{l}"} 215: end 216: 217: MCollective::PluginManager["connector_plugin"].disconnect rescue true 218: 219: exit 1 220: end
Builds an ObjectParser config, parse the CLI options and validates based on the option config
# File lib/mcollective/application.rb, line 99 99: def application_parse_options 100: @options = rpcoptions do |parser, options| 101: parser.define_head application_description if application_description 102: parser.banner = "" 103: 104: if application_usage 105: parser.separator "" 106: 107: application_usage.each do |u| 108: parser.separator "Usage: #{u}" 109: end 110: 111: parser.separator "" 112: end 113: 114: parser.define_tail "" 115: parser.define_tail "The Marionette Collective #{MCollective.version}" 116: 117: 118: application_cli_arguments.each do |carg| 119: opts_array = [] 120: 121: opts_array << :on 122: 123: # if a default is set from the application set it up front 124: if carg.include?(:default) 125: configuration[carg[:name]] = carg[:default] 126: end 127: 128: # :arguments are multiple possible ones 129: if carg[:arguments].is_a?(Array) 130: carg[:arguments].each {|a| opts_array << a} 131: else 132: opts_array << carg[:arguments] 133: end 134: 135: # type was given and its not one of our special types, just pass it onto optparse 136: opts_array << carg[:type] if carg[:type] and ! [:bool, :array].include?(carg[:type]) 137: 138: opts_array << carg[:description] 139: 140: # Handle our special types else just rely on the optparser to handle the types 141: if carg[:type] == :bool 142: parser.send(*opts_array) do |v| 143: validate_option(carg[:validate], carg[:name], v) 144: 145: configuration[carg[:name]] = true 146: end 147: 148: elsif carg[:type] == :array 149: parser.send(*opts_array) do |v| 150: validate_option(carg[:validate], carg[:name], v) 151: 152: configuration[carg[:name]] = [] unless configuration.include?(carg[:name]) 153: configuration[carg[:name]] << v 154: end 155: 156: else 157: parser.send(*opts_array) do |v| 158: validate_option(carg[:validate], carg[:name], v) 159: 160: configuration[carg[:name]] = v 161: end 162: end 163: end 164: end 165: 166: # Check all required parameters were set 167: validation_passed = true 168: application_cli_arguments.each do |carg| 169: # Check for required arguments 170: if carg[:required] 171: unless configuration[ carg[:name] ] 172: validation_passed = false 173: STDERR.puts "The #{carg[:name]} option is mandatory" 174: end 175: end 176: end 177: 178: unless validation_passed 179: STDERR.puts "\nPlease run with --help for detailed help" 180: exit 1 181: end 182: 183: post_option_parser(configuration) if respond_to?(:post_option_parser) 184: rescue Exception => e 185: application_failure(e) 186: end
The application configuration built from CLI arguments
# File lib/mcollective/application.rb, line 76 76: def configuration 77: @application_configuration ||= {} 78: @application_configuration 79: end
The active options hash used for MC::Client and other configuration
# File lib/mcollective/application.rb, line 82 82: def options 83: @options 84: 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 250: def rpcclient(agent, flags = {}) 251: flags[:options] = options unless flags.include?(:options) 252: 253: super 254: 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 225: def run 226: application_parse_options 227: 228: validate_configuration(configuration) if respond_to?(:validate_configuration) 229: 230: main 231: 232: MCollective::PluginManager["connector_plugin"].disconnect rescue true 233: 234: rescue SystemExit 235: raise 236: rescue Exception => e 237: application_failure(e) 238: 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 88: def validate_option(blk, name, value) 89: validation_result = blk.call(value) 90: 91: unless validation_result == true 92: STDERR.puts "Validation of #{name} failed: #{validation_result}" 93: exit 1 94: end 95: end