Class MCollective::Applications
In: lib/mcollective/applications.rb
Parent: Object

Methods

Public Class methods

[Source]

   # File lib/mcollective/applications.rb, line 3
3:         def self.[](appname)
4:             load_application(appname)
5:             PluginManager["#{appname}_application"]
6:         end

Filters a string of opts out using Shellwords keeping only things related to —config and -c

[Source]

    # File lib/mcollective/applications.rb, line 46
46:         def self.filter_extra_options(opts)
47:             res = ""
48:             words = Shellwords.shellwords(opts)
49:             words.each_with_index do |word,idx|
50:                 if word == "-c"
51:                     return "--config=#{words[idx + 1]}"
52:                 elsif word == "--config"
53:                     return "--config=#{words[idx + 1]}"
54:                 elsif word =~ /\-c=/
55:                     return word
56:                 elsif word =~ /\-\-config=/
57:                     return word
58:                 end
59:             end
60: 
61:             return ""
62:         end

Returns an array of applications found in the lib dirs

[Source]

    # File lib/mcollective/applications.rb, line 25
25:         def self.list
26:             load_config
27: 
28:             applist = []
29: 
30:             Config.instance.libdir.each do |libdir|
31:                 applicationdir = "#{libdir}/mcollective/application"
32:                 next unless File.directory?(applicationdir)
33: 
34:                 Dir.entries(applicationdir).grep(/\.rb$/).each do |application|
35:                     applist << File.basename(application, ".rb")
36:                 end
37:             end
38: 
39:             applist
40:         rescue
41:             return []
42:         end

[Source]

    # File lib/mcollective/applications.rb, line 15
15:         def self.load_application(appname)
16:             return if PluginManager.include?("#{appname}_application")
17: 
18:             load_config
19: 
20:             PluginManager.loadclass "MCollective::Application::#{appname.capitalize}"
21:             PluginManager << {:type => "#{appname}_application", :class => "MCollective::Application::#{appname.capitalize}"}
22:         end

We need to know the config file in order to know the libdir so that we can find applications.

The problem is the CLI might be stuffed with options only the app in the libdir might understand so we have a chicken and egg situation.

We‘re parsing and filtering MCOLLECTIVE_EXTRA_OPTS removing all but config related options and parsing the options looking just for the config file.

We‘re handling failures gracefully and finally restoring the ARG and MCOLLECTIVE_EXTRA_OPTS to the state they were before we started parsing.

This is mostly a hack, when we‘re redoing how config works this stuff should be made less sucky

[Source]

     # File lib/mcollective/applications.rb, line 81
 81:         def self.load_config
 82:             return if Config.instance.configured
 83: 
 84:             original_argv = ARGV.clone
 85:             original_extra_opts = ENV["MCOLLECTIVE_EXTRA_OPTS"].clone rescue nil
 86:             configfile = nil
 87: 
 88:             parser = OptionParser.new
 89:             parser.on("--config CONFIG", "-c", "Config file") do |f|
 90:                 configfile = f
 91:             end
 92: 
 93:             parser.program_name = $0
 94: 
 95:             parser.on("--help")
 96: 
 97:             # avoid option parsers own internal version handling that sux
 98:             parser.on("-v", "--verbose")
 99: 
100:             if original_extra_opts
101:                 begin
102:                     # optparse will parse the whole ENV in one go and refuse
103:                     # to play along with the retry trick I do below so in
104:                     # order to handle unknown options properly I parse out
105:                     # only -c and --config deleting everything else and
106:                     # then restore the environment variable later when I
107:                     # am done with it
108:                     ENV["MCOLLECTIVE_EXTRA_OPTS"] = filter_extra_options(ENV["MCOLLECTIVE_EXTRA_OPTS"].clone)
109:                     parser.environment("MCOLLECTIVE_EXTRA_OPTS")
110:                 rescue Exception => e
111:                     Log.error("Failed to parse MCOLLECTIVE_EXTRA_OPTS: #{e}")
112:                 end
113: 
114:                 ENV["MCOLLECTIVE_EXTRA_OPTS"] = original_extra_opts.clone
115:             end
116: 
117:             begin
118:                 parser.parse!
119:             rescue OptionParser::InvalidOption => e
120:                 retry
121:             end
122: 
123:             ARGV.clear
124:             original_argv.each {|a| ARGV << a}
125: 
126:             configfile = Util.config_file_for_user unless configfile
127: 
128:             Config.instance.loadconfig(configfile)
129:         end

[Source]

    # File lib/mcollective/applications.rb, line 8
 8:         def self.run(appname)
 9:             load_config
10: 
11:             load_application(appname)
12:             PluginManager["#{appname}_application"].run
13:         end

[Validate]