Speed up Rudder new node's detection

By default, a new node sending its inventory to the Rudder server, won't appear in the "Accept new nodes" menu before the next cf-agent run on the server.
In the worst case scenario, you'll have to wait 5 minutes for the node to appear. My issue was that i needed this process to be as quick as possible as i'm deploying rudder-agent through a kickstart post-install script, and i whished for the deployed node to have all the rudder rules applied before reboot.

As the inventory creation can be tracked in /var/rudder/inventories/incoming, a small python script using pyinotify to the rescue.

import os, datetime, subprocess, re, thread
import pyinotify

command = "/opt/rudder/bin/cf-agent -K -b sendInventoryToCmdb -f /var/rudder/cfengine-community/inputs/promises.cf"
report_re = re.compile('R:.*')

wm = pyinotify.WatchManager() # Watch Manager
mask = pyinotify.IN_DELETE | pyinotify.IN_CREATE # watched events

def exec_proc(file, dummy1):
    process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=None, shell=True)
    output = process.communicate()
    date = datetime.datetime.now()
    report_line = report_re.search(output[0])
    print "%s: %s - %s" % (date, file, report_line.group())

class EventHandler(pyinotify.ProcessEvent):
    def process_IN_CREATE(self, event):
        date = datetime.datetime.now()
        print "%s: %s - %s created" % (date, event.path, event.name)

        if "incoming" in event.path:
            dummy_tup = event.name, 'null'
            thread.start_new_thread(exec_proc, dummy_tup)

    def process_IN_DELETE(self, event):
        date = datetime.datetime.now()
        print "%s: %s - %s deleted" % (date, event.path, event.name)

handler = EventHandler()
notifier = pyinotify.Notifier(wm, handler)
wdd = wm.add_watch('/var/rudder/inventories/', mask, rec=True)


So what performance gain do we have ?

# python bin/rudder_inv_notify.py 
2013-08-27 17:26:51.051183: /var/rudder/inventories/incoming - itclient-01-2013-09-04-17-26-46.ocs created
2013-08-27 17:26:54.616183: p4itclient-01-2013-09-04-17-26-46.ocs - R: @@DistributePolicy@@result_success@@root-DP@@root-distributePolicy@@20@@Send inventories to CMDB@@None@@2013-09-04 17:26:54+02:00##root@#Incoming inventories were successfully added to Rudder
2013-08-27 17:26:54.932790: /var/rudder/inventories/historical - 9530ce39-6699-49bc-819e-d8b72ae35a55 created

Around 3 seconds to have the node available in pending list. This let us use API to accept it ... I'll detail this further in another post.