Class MCollective::Agents
In: lib/mcollective/agents.rb
Parent: Object

A collection of agents, loads them, reloads them and dispatches messages to them. It uses the PluginManager to store, load and manage instances of plugins.

Methods

Public Class methods

Get a list of agents that we have

[Source]

     # File lib/mcollective/agents.rb, line 156
156:     def self.agentlist
157:       @@agents.keys
158:     end

[Source]

    # File lib/mcollective/agents.rb, line 5
 5:     def initialize(agents = {})
 6:       @config = Config.instance
 7:       raise ("Configuration has not been loaded, can't load agents") unless @config.configured
 8: 
 9:       @@agents = agents
10: 
11:       loadagents
12:     end

Public Instance methods

Checks if a plugin should be activated by calling activate? on it if it responds to that method else always activate it

[Source]

    # File lib/mcollective/agents.rb, line 80
80:     def activate_agent?(agent)
81:       klass = Kernel.const_get("MCollective").const_get("Agent").const_get(agent.capitalize)
82: 
83:       if klass.respond_to?("activate?")
84:         return klass.activate?
85:       else
86:         Log.debug("#{klass} does not have an activate? method, activating as default")
87:         return true
88:       end
89:     rescue Exception => e
90:       Log.warn("Agent activation check for #{agent} failed: #{e.class}: #{e}")
91:       return false
92:     end

Builds a class name string given a Agent name

[Source]

    # File lib/mcollective/agents.rb, line 73
73:     def class_for_agent(agent)
74:       "MCollective::Agent::#{agent.capitalize}"
75:     end

Deletes all agents

[Source]

    # File lib/mcollective/agents.rb, line 15
15:     def clear!
16:       @@agents.each_key do |agent|
17:         PluginManager.delete "#{agent}_agent"
18:         Util.unsubscribe(Util.make_subscriptions(agent, :broadcast))
19:       end
20: 
21:       @@agents = {}
22:     end

Dispatches a message to an agent, accepts a block that will get run if there are any replies to process from the agent

[Source]

     # File lib/mcollective/agents.rb, line 129
129:     def dispatch(request, connection)
130:       Log.debug("Dispatching a message to agent #{request.agent}")
131: 
132:       Thread.new do
133:         begin
134:           agent = PluginManager["#{request.agent}_agent"]
135: 
136:           Timeout::timeout(agent.timeout) do
137:             replies = agent.handlemsg(request.payload, connection)
138: 
139:             # Agents can decide if they wish to reply or not,
140:             # returning nil will mean nothing goes back to the
141:             # requestor
142:             unless replies == nil
143:               yield(replies)
144:             end
145:           end
146:         rescue Timeout::Error => e
147:           Log.warn("Timeout while handling message for #{request.agent}")
148:         rescue Exception => e
149:           Log.error("Execution of #{request.agent} failed: #{e}")
150:           Log.error(e.backtrace.join("\n\t\t"))
151:         end
152:       end
153:     end

searches the libdirs for agents

[Source]

     # File lib/mcollective/agents.rb, line 95
 95:     def findagentfile(agentname)
 96:       @config.libdir.each do |libdir|
 97:         agentfile = File.join([libdir, "mcollective", "agent", "#{agentname}.rb"])
 98:         if File.exist?(agentfile)
 99:           Log.debug("Found #{agentname} at #{agentfile}")
100:           return agentfile
101:         end
102:       end
103:       return false
104:     end

Returns the help for an agent after first trying to get rid of some indentation infront

[Source]

     # File lib/mcollective/agents.rb, line 113
113:     def help(agentname)
114:       raise("No such agent") unless include?(agentname)
115: 
116:       body = PluginManager["#{agentname}_agent"].help.split("\n")
117: 
118:       if body.first =~ /^(\s+)\S/
119:         indent = $1
120: 
121:         body = body.map {|b| b.gsub(/^#{indent}/, "")}
122:       end
123: 
124:       body.join("\n")
125:     end

Determines if we have an agent with a certain name

[Source]

     # File lib/mcollective/agents.rb, line 107
107:     def include?(agentname)
108:       PluginManager.include?("#{agentname}_agent")
109:     end

Loads a specified agent from disk if available

[Source]

    # File lib/mcollective/agents.rb, line 42
42:     def loadagent(agentname)
43:       agentfile = findagentfile(agentname)
44:       return false unless agentfile
45:       classname = class_for_agent(agentname)
46: 
47:       PluginManager.delete("#{agentname}_agent")
48: 
49:       begin
50:         single_instance = ["registration", "discovery"].include?(agentname)
51: 
52:         PluginManager.loadclass(classname)
53: 
54:         if activate_agent?(agentname)
55:           PluginManager << {:type => "#{agentname}_agent", :class => classname, :single_instance => single_instance}
56: 
57:           Util.subscribe(Util.make_subscriptions(agentname, :broadcast)) unless @@agents.include?(agentname)
58: 
59:           @@agents[agentname] = {:file => agentfile}
60:           return true
61:         else
62:           Log.debug("Not activating agent #{agentname} due to agent policy in activate? method")
63:           return false
64:         end
65:       rescue Exception => e
66:         Log.error("Loading agent #{agentname} failed: #{e}")
67:         PluginManager.delete("#{agentname}_agent")
68:         return false
69:       end
70:     end

Loads all agents from disk

[Source]

    # File lib/mcollective/agents.rb, line 25
25:     def loadagents
26:       Log.debug("Reloading all agents from disk")
27: 
28:       clear!
29: 
30:       @config.libdir.each do |libdir|
31:         agentdir = "#{libdir}/mcollective/agent"
32:         next unless File.directory?(agentdir)
33: 
34:         Dir.new(agentdir).grep(/\.rb$/).each do |agent|
35:           agentname = File.basename(agent, ".rb")
36:           loadagent(agentname) unless PluginManager.include?("#{agentname}_agent")
37:         end
38:       end
39:     end

[Validate]