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 60
60:     def self.filter_extra_options(opts)
61:       res = ""
62:       words = Shellwords.shellwords(opts)
63:       words.each_with_index do |word,idx|
64:         if word == "-c"
65:           return "--config=#{words[idx + 1]}"
66:         elsif word == "--config"
67:           return "--config=#{words[idx + 1]}"
68:         elsif word =~ /\-c=/
69:           return word
70:         elsif word =~ /\-\-config=/
71:           return word
72:         end
73:       end
74: 
75:       return ""
76:     end

Returns an array of applications found in the lib dirs

[Source]

    # File lib/mcollective/applications.rb, line 36
36:     def self.list
37:       load_config
38: 
39:       applist = []
40: 
41:       Config.instance.libdir.each do |libdir|
42:         applicationdir = "#{libdir}/mcollective/application"
43:         next unless File.directory?(applicationdir)
44: 
45:         Dir.entries(applicationdir).grep(/\.rb$/).each do |application|
46:           applist << File.basename(application, ".rb")
47:         end
48:       end
49: 
50:       applist
51:     rescue SystemExit
52:       exit 1
53:     rescue Exception => e
54:       STDERR.puts "Failed to generate application list: #{e.class}: #{e}"
55:       exit 1
56:     end

[Source]

    # File lib/mcollective/applications.rb, line 26
26:     def self.load_application(appname)
27:       return if PluginManager.include?("#{appname}_application")
28: 
29:       load_config
30: 
31:       PluginManager.loadclass "MCollective::Application::#{appname.capitalize}"
32:       PluginManager << {:type => "#{appname}_application", :class => "MCollective::Application::#{appname.capitalize}"}
33:     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 95
 95:     def self.load_config
 96:       return if Config.instance.configured
 97: 
 98:       original_argv = ARGV.clone
 99:       original_extra_opts = ENV["MCOLLECTIVE_EXTRA_OPTS"].clone rescue nil
100:       configfile = nil
101: 
102:       parser = OptionParser.new
103:       parser.on("--config CONFIG", "-c", "Config file") do |f|
104:         configfile = f
105:       end
106: 
107:       parser.program_name = $0
108: 
109:       parser.on("--help")
110: 
111:       # avoid option parsers own internal version handling that sux
112:       parser.on("-v", "--verbose")
113: 
114:       if original_extra_opts
115:         begin
116:           # optparse will parse the whole ENV in one go and refuse
117:           # to play along with the retry trick I do below so in
118:           # order to handle unknown options properly I parse out
119:           # only -c and --config deleting everything else and
120:           # then restore the environment variable later when I
121:           # am done with it
122:           ENV["MCOLLECTIVE_EXTRA_OPTS"] = filter_extra_options(ENV["MCOLLECTIVE_EXTRA_OPTS"].clone)
123:           parser.environment("MCOLLECTIVE_EXTRA_OPTS")
124:         rescue Exception => e
125:           Log.error("Failed to parse MCOLLECTIVE_EXTRA_OPTS: #{e}")
126:         end
127: 
128:         ENV["MCOLLECTIVE_EXTRA_OPTS"] = original_extra_opts.clone
129:       end
130: 
131:       begin
132:         parser.parse!
133:       rescue OptionParser::InvalidOption => e
134:         retry
135:       end
136: 
137:       ARGV.clear
138:       original_argv.each {|a| ARGV << a}
139: 
140:       configfile = Util.config_file_for_user unless configfile
141: 
142:       Config.instance.loadconfig(configfile)
143:     end

[Source]

    # File lib/mcollective/applications.rb, line 8
 8:     def self.run(appname)
 9:       load_config
10: 
11:       begin
12:         load_application(appname)
13:       rescue Exception => e
14:         e.backtrace.first << RPC::Helpers.colorize(:red, "  <----")
15:         STDERR.puts "Application '#{appname}' failed to load:"
16:         STDERR.puts
17:         STDERR.puts RPC::Helpers.colorize(:red, "   #{e} (#{e.class})")
18:         STDERR.puts
19:         STDERR.puts "       %s" % [e.backtrace.join("\n       ")]
20:         exit 1
21:       end
22: 
23:       PluginManager["#{appname}_application"].run
24:     end

[Validate]