class MCollective::Runner

The main runner for the daemon, supports running in the foreground and the background, keeps detailed stats and provides hooks to access all this information

Public Class Methods

daemonize() { || ... } click to toggle source

Daemonize the current process

# File lib/mcollective/runner.rb, line 32
def self.daemonize
    fork do
        Process.setsid
        exit if fork
        Dir.chdir('/tmp')
        STDIN.reopen('/dev/null')
        STDOUT.reopen('/dev/null', 'a')
        STDERR.reopen('/dev/null', 'a')

        yield
    end
end
new(configfile) click to toggle source
# File lib/mcollective/runner.rb, line 6
def initialize(configfile)
    @config = Config.instance
    @config.loadconfig(configfile) unless @config.configured

    @stats = PluginManager["global_stats"]

    @security = PluginManager["security_plugin"]
    @security.initiated_by = :node

    @connection = PluginManager["connector_plugin"]
    @connection.connect

    @agents = Agents.new

    Signal.trap("USR1") do
        Log.info("Reloading all agents after receiving USR1 signal")
        @agents.loadagents
    end

    Signal.trap("USR2") do
        Log.info("Cycling logging level due to USR2 signal")
        Log.cycle_level
    end
end

Public Instance Methods

run() click to toggle source

Starts the main loop, before calling this you should initialize the MCollective::Config singleton.

# File lib/mcollective/runner.rb, line 46
def run
    controltopics = Util.make_target("mcollective", :command)
    Util.subscribe(controltopics)

    # Start the registration plugin if interval isn't 0
    begin
        PluginManager["registration_plugin"].run(@connection) unless @config.registerinterval == 0
    rescue Exception => e
        Log.error("Failed to start registration plugin: #{e}")
    end

    loop do
        begin
            msg = receive

            collective = msg[:collective]
            agent = msg[:agent]

            # requests from older clients would not include the
            # :collective and :agent this parses the target in
            # a backward compat way for them
            unless collective && agent
                parsed_dest = Util.parse_msgtarget(msg[:msgtarget])
                collective = parsed_dest[:collective]
                agent = parsed_dest[:agent]
            end

            if agent == "mcollective"
                Log.debug("Handling message for mcollectived controller")

                controlmsg(msg, collective)
            else
                Log.debug("Handling message for agent '#{agent}' on collective '#{collective}'")

                agentmsg(msg, agent, collective)
            end
        rescue Interrupt
            Log.warn("Exiting after interrupt signal")
            @connection.disconnect
            exit!

        rescue NotTargettedAtUs => e
            Log.debug("Message does not pass filters, ignoring")

        rescue Exception => e
            Log.warn("Failed to handle message: #{e} - #{e.class}\n")
            Log.warn(e.backtrace.join("\n\t"))
        end
    end
end