summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorNarayan Desai <desai@mcs.anl.gov>2005-10-18 04:55:48 +0000
committerNarayan Desai <desai@mcs.anl.gov>2005-10-18 04:55:48 +0000
commit33e7dd47f7975eaa0433a53efc75d27e40820d46 (patch)
treee9059fc4e0e34297c015a528730d3683e0048367 /src
parent9f9262ac2ec4e854f3638efb61adadf6c9c2531e (diff)
downloadbcfg2-33e7dd47f7975eaa0433a53efc75d27e40820d46.tar.gz
bcfg2-33e7dd47f7975eaa0433a53efc75d27e40820d46.tar.bz2
bcfg2-33e7dd47f7975eaa0433a53efc75d27e40820d46.zip
add in Gamin support
Change around fam API so that monitor specific junk is abstracted (Logical change 1.337) git-svn-id: https://svn.mcs.anl.gov/repos/bcfg/trunk/bcfg2@1386 ce84e21b-d406-0410-9b95-82705330c041
Diffstat (limited to 'src')
-rw-r--r--src/lib/Server/Core.py84
1 files changed, 79 insertions, 5 deletions
diff --git a/src/lib/Server/Core.py b/src/lib/Server/Core.py
index 8940b798c..82bc07117 100644
--- a/src/lib/Server/Core.py
+++ b/src/lib/Server/Core.py
@@ -9,7 +9,6 @@ from traceback import extract_tb
from time import time
from ConfigParser import ConfigParser
from elementtree.ElementTree import Element
-import _fam
from Bcfg2.Server.Plugin import PluginInitError, PluginExecutionError
from Bcfg2.Server.Metadata import MetadataStore, MetadataConsistencyError
@@ -19,8 +18,8 @@ class CoreInitError(Exception):
'''This error is raised when the core cannot be initialized'''
pass
-class Fam(object):
- '''The fam object is a set of callbacks for file alteration events'''
+class FamFam(object):
+ '''The fam object is a set of callbacks for file alteration events (FAM support)'''
def __init__(self):
object.__init__(self)
@@ -32,7 +31,7 @@ class Fam(object):
'''return fam file handle number'''
return self.fm.fileno()
- def AddMonitor(self, path, obj=None):
+ def AddMonitor(self, path, obj):
'''add a monitor to path, installing a callback to obj.HandleEvent'''
mode = stat(path)[ST_MODE]
if S_ISDIR(mode):
@@ -53,6 +52,81 @@ class Fam(object):
#print "dispatching event %s %s to obj %s handle :%s:" % (event.code2str(), event.filename, self.users[reqid], event.requestID)
self.users[reqid].HandleEvent(event)
+ def Service(self):
+ '''Handle all fam work'''
+ while self.fm.pending():
+ self.HandleEvent()
+
+class GaminEvent(object):
+ '''This class provides an event analogous to python-fam events based on gamin sources'''
+ def __init__(self, request_id, filename, code):
+ action_map = {GAMCreated: 'created', GAMExists: 'exists', GAMChanged: 'changed',
+ GAMDeleted: 'deleted', GAMEndExist: 'EndExist'}
+ self.requestID = request_id
+ self.filename = filename
+ if action_map.has_key(code):
+ self.action = action_map[code]
+
+ def code2str(self):
+ '''return static code for event'''
+ return self.action
+
+class GaminFam(object):
+ '''The fam object is a set of callbacks for file alteration events (Gamin support)'''
+ def __init__(self):
+ object.__init__(self)
+ self.mon = WatchMonitor()
+ self.handles = {}
+ self.counter = 0
+
+ def fileno(self):
+ '''return fam file handle number'''
+ return self.mon.get_fd()
+
+ def dispatch(self, path, action, request_id):
+ '''find the right object to dispatch to'''
+ if self.handles.has_key(request_id):
+ evt = GaminEvent(request_id, path, action)
+ #print "e %s %s to obj %s handle :%s:" % (evt.code2str(), evt.filename,
+ # self.handles[request_id], evt.requestID)
+ self.handles[request_id].HandleEvent(evt)
+ else:
+ print "got crazy event for nonexistant handle %s" % request_id
+
+ def AddMonitor(self, path, obj):
+ '''add a monitor to path, installing a callback to obj.HandleEvent'''
+ handle = self.counter
+ self.counter += 1
+ mode = stat(path)[ST_MODE]
+ if S_ISDIR(mode):
+ self.mon.watch_directory(path, self.dispatch, handle)
+ #print "adding callback for directory %s to %s, handle :%s:" % ( path, obj, handle.requestID())
+ else:
+ self.mon.watch_file(path, self.dispatch, handle)
+ self.handles[handle] = obj
+ return handle
+
+ def HandleEvent(self):
+ '''Call Gamin, which will call the callback'''
+ self.mon.handle_one_event()
+
+ def Service(self):
+ '''Handle any pending Gamin work'''
+ while self.mon.event_pending():
+ self.mon.handle_one_event()
+
+try:
+ from gamin import WatchMonitor, GAMCreated, GAMExists, GAMEndExist, GAMChanged, GAMDeleted
+ monitor = GaminFam
+except ImportError:
+ # fall back to _fam
+ try:
+ import _fam
+ monitor = FamFam
+ except ImportError:
+ print "Couldn't locate Fam module, exiting"
+ raise SystemExit, 1
+
class Core(object):
'''The Core object is the container for all Bcfg2 Server logic, and modules'''
def __init__(self, setup, configfile):
@@ -61,7 +135,7 @@ class Core(object):
cfile.read([configfile])
self.datastore = cfile.get('server','repository')
try:
- self.fam = Fam()
+ self.fam = monitor()
except IOError:
raise CoreInitError, "failed to connect to fam"
self.pubspace = {}