summaryrefslogtreecommitdiffstats
path: root/src/lib/Bcfg2/Server/FileMonitor
diff options
context:
space:
mode:
authorChris St. Pierre <chris.a.st.pierre@gmail.com>2012-09-25 11:49:15 -0400
committerChris St. Pierre <chris.a.st.pierre@gmail.com>2012-09-25 11:58:48 -0400
commiteac71fc1109f2edc6b71e62a6cff38d762bebe63 (patch)
tree203cf372e31b92dfc0cf7ea57c451c44e5e1e54b /src/lib/Bcfg2/Server/FileMonitor
parent3f16355e18cdceb37828a00a8181d9cc60815cd0 (diff)
downloadbcfg2-eac71fc1109f2edc6b71e62a6cff38d762bebe63.tar.gz
bcfg2-eac71fc1109f2edc6b71e62a6cff38d762bebe63.tar.bz2
bcfg2-eac71fc1109f2edc6b71e62a6cff38d762bebe63.zip
expanded pylint coverage
Diffstat (limited to 'src/lib/Bcfg2/Server/FileMonitor')
-rw-r--r--src/lib/Bcfg2/Server/FileMonitor/Fam.py31
-rw-r--r--src/lib/Bcfg2/Server/FileMonitor/Gamin.py4
-rw-r--r--src/lib/Bcfg2/Server/FileMonitor/Inotify.py39
-rw-r--r--src/lib/Bcfg2/Server/FileMonitor/Pseudo.py11
-rw-r--r--src/lib/Bcfg2/Server/FileMonitor/__init__.py45
5 files changed, 73 insertions, 57 deletions
diff --git a/src/lib/Bcfg2/Server/FileMonitor/Fam.py b/src/lib/Bcfg2/Server/FileMonitor/Fam.py
index aef74add4..9c6031be9 100644
--- a/src/lib/Bcfg2/Server/FileMonitor/Fam.py
+++ b/src/lib/Bcfg2/Server/FileMonitor/Fam.py
@@ -7,21 +7,24 @@ import logging
from time import time
from Bcfg2.Server.FileMonitor import FileMonitor
-logger = logging.getLogger(__name__)
+LOGGER = logging.getLogger(__name__)
+
class Fam(FileMonitor):
+ """ file monitor with support for FAM """
+
__priority__ = 90
def __init__(self, ignore=None, debug=False):
FileMonitor.__init__(self, ignore=ignore, debug=debug)
- self.fm = _fam.open()
+ self.filemonitor = _fam.open()
self.users = {}
def fileno(self):
"""Return fam file handle number."""
- return self.fm.fileno()
+ return self.filemonitor.fileno()
- def handle_event_set(self, _):
+ def handle_event_set(self, _=None):
self.Service()
def handle_events_in_interval(self, interval):
@@ -30,13 +33,13 @@ class Fam(FileMonitor):
if self.Service():
now = time()
- def AddMonitor(self, path, obj):
+ def AddMonitor(self, path, obj, _=None):
"""Add a monitor to path, installing a callback to obj.HandleEvent."""
mode = os.stat(path)[stat.ST_MODE]
if stat.S_ISDIR(mode):
- handle = self.fm.monitorDirectory(path, None)
+ handle = self.filemonitor.monitorDirectory(path, None)
else:
- handle = self.fm.monitorFile(path, None)
+ handle = self.filemonitor.monitorFile(path, None)
self.handles[handle.requestID()] = handle
if obj != None:
self.users[handle.requestID()] = obj
@@ -50,10 +53,10 @@ class Fam(FileMonitor):
start = time()
now = time()
while (time() - now) < interval:
- if self.fm.pending():
- while self.fm.pending():
+ if self.filemonitor.pending():
+ while self.filemonitor.pending():
count += 1
- rawevents.append(self.fm.nextEvent())
+ rawevents.append(self.filemonitor.nextEvent())
now = time()
unique = []
bookkeeping = []
@@ -73,10 +76,10 @@ class Fam(FileMonitor):
if event.requestID in self.users:
try:
self.users[event.requestID].HandleEvent(event)
- except:
- logger.error("Handling event for file %s" % event.filename,
+ except: # pylint: disable=W0702
+ LOGGER.error("Handling event for file %s" % event.filename,
exc_info=1)
end = time()
- logger.info("Processed %s fam events in %03.03f seconds. %s coalesced" %
- (count, (end - start), collapsed))
+ LOGGER.info("Processed %s fam events in %03.03f seconds. "
+ "%s coalesced" % (count, (end - start), collapsed))
return count
diff --git a/src/lib/Bcfg2/Server/FileMonitor/Gamin.py b/src/lib/Bcfg2/Server/FileMonitor/Gamin.py
index 9d4330e89..d0ba59cd8 100644
--- a/src/lib/Bcfg2/Server/FileMonitor/Gamin.py
+++ b/src/lib/Bcfg2/Server/FileMonitor/Gamin.py
@@ -2,15 +2,12 @@
import os
import stat
-import logging
# pylint: disable=F0401
from gamin import WatchMonitor, GAMCreated, GAMExists, GAMEndExist, \
GAMChanged, GAMDeleted
# pylint: enable=F0401
from Bcfg2.Server.FileMonitor import Event, FileMonitor
-logger = logging.getLogger(__name__)
-
class GaminEvent(Event):
"""
@@ -28,6 +25,7 @@ class GaminEvent(Event):
class Gamin(FileMonitor):
+ """ file monitor with gamin support """
__priority__ = 10
def __init__(self, ignore=None, debug=False):
diff --git a/src/lib/Bcfg2/Server/FileMonitor/Inotify.py b/src/lib/Bcfg2/Server/FileMonitor/Inotify.py
index 75eff3bc5..5a8a1e1c6 100644
--- a/src/lib/Bcfg2/Server/FileMonitor/Inotify.py
+++ b/src/lib/Bcfg2/Server/FileMonitor/Inotify.py
@@ -1,17 +1,18 @@
""" Inotify driver for file alteration events """
import os
-import sys
import logging
import pyinotify # pylint: disable=F0401
-from Bcfg2.Compat import reduce
+from Bcfg2.Compat import reduce # pylint: disable=W0622
from Bcfg2.Server.FileMonitor import Event
from Bcfg2.Server.FileMonitor.Pseudo import Pseudo
-logger = logging.getLogger(__name__)
+LOGGER = logging.getLogger(__name__)
class Inotify(Pseudo, pyinotify.ProcessEvent):
+ """ file monitor with inotify support """
+
__priority__ = 1
# pylint: disable=E1101
action_map = {pyinotify.IN_CREATE: 'created',
@@ -24,18 +25,18 @@ class Inotify(Pseudo, pyinotify.ProcessEvent):
def __init__(self, ignore=None, debug=False):
Pseudo.__init__(self, ignore=ignore, debug=debug)
- pyinotify.ProcessEvent(self)
+ pyinotify.ProcessEvent.__init__(self)
self.event_filter = dict()
self.watches_by_path = dict()
# these are created in start() after the server is done forking
self.notifier = None
- self.wm = None
+ self.watchmgr = None
self.add_q = []
def start(self):
Pseudo.start(self)
- self.wm = pyinotify.WatchManager()
- self.notifier = pyinotify.ThreadedNotifier(self.wm, self)
+ self.watchmgr = pyinotify.WatchManager()
+ self.notifier = pyinotify.ThreadedNotifier(self.watchmgr, self)
self.notifier.start()
for monitor in self.add_q:
self.AddMonitor(*monitor)
@@ -43,7 +44,7 @@ class Inotify(Pseudo, pyinotify.ProcessEvent):
def fileno(self):
if self.started:
- return self.wm.get_fd()
+ return self.watchmgr.get_fd()
else:
return None
@@ -54,9 +55,9 @@ class Inotify(Pseudo, pyinotify.ProcessEvent):
action = aname
break
try:
- watch = self.wm.watches[ievent.wd]
+ watch = self.watchmgr.watches[ievent.wd]
except KeyError:
- logger.error("Error handling event for %s: Watch %s not found" %
+ LOGGER.error("Error handling event for %s: Watch %s not found" %
(ievent.pathname, ievent.wd))
return
# FAM-style file monitors return the full path to the parent
@@ -87,7 +88,7 @@ class Inotify(Pseudo, pyinotify.ProcessEvent):
ievent.pathname in self.event_filter[ievent.wd]):
self.events.append(evt)
- def AddMonitor(self, path, obj):
+ def AddMonitor(self, path, obj, handleID=None):
# strip trailing slashes
path = path.rstrip("/")
@@ -116,18 +117,18 @@ class Inotify(Pseudo, pyinotify.ProcessEvent):
# see if this path is already being watched
try:
- wd = self.watches_by_path[watch_path]
+ watchdir = self.watches_by_path[watch_path]
except KeyError:
- wd = self.wm.add_watch(watch_path, self.mask,
- quiet=False)[watch_path]
- self.watches_by_path[watch_path] = wd
+ watchdir = self.watchmgr.add_watch(watch_path, self.mask,
+ quiet=False)[watch_path]
+ self.watches_by_path[watch_path] = watchdir
produce_exists = True
if not is_dir:
- if wd not in self.event_filter:
- self.event_filter[wd] = [path]
- elif path not in self.event_filter[wd]:
- self.event_filter[wd].append(path)
+ if watchdir not in self.event_filter:
+ self.event_filter[watchdir] = [path]
+ elif path not in self.event_filter[watchdir]:
+ self.event_filter[watchdir].append(path)
else:
# we've been asked to watch a file that we're already
# watching, so we don't need to produce 'exists'
diff --git a/src/lib/Bcfg2/Server/FileMonitor/Pseudo.py b/src/lib/Bcfg2/Server/FileMonitor/Pseudo.py
index 089d4cf0f..9062cbfd8 100644
--- a/src/lib/Bcfg2/Server/FileMonitor/Pseudo.py
+++ b/src/lib/Bcfg2/Server/FileMonitor/Pseudo.py
@@ -1,12 +1,13 @@
""" Pseudo provides static monitor support for file alteration events """
import os
-import logging
from Bcfg2.Server.FileMonitor import FileMonitor, Event
-logger = logging.getLogger(__name__)
class Pseudo(FileMonitor):
+ """ file monitor that only produces events on server startup and
+ doesn't actually monitor at all """
+
__priority__ = 99
def AddMonitor(self, path, obj, handleID=None):
@@ -15,9 +16,9 @@ class Pseudo(FileMonitor):
handleID = len(list(self.handles.keys()))
self.events.append(Event(handleID, path, 'exists'))
if os.path.isdir(path):
- dirList = os.listdir(path)
- for includedFile in dirList:
- self.events.append(Event(handleID, includedFile, 'exists'))
+ dirlist = os.listdir(path)
+ for fname in dirlist:
+ self.events.append(Event(handleID, fname, 'exists'))
self.events.append(Event(handleID, path, 'endExist'))
if obj != None:
diff --git a/src/lib/Bcfg2/Server/FileMonitor/__init__.py b/src/lib/Bcfg2/Server/FileMonitor/__init__.py
index fd0cb66f1..1b12ab703 100644
--- a/src/lib/Bcfg2/Server/FileMonitor/__init__.py
+++ b/src/lib/Bcfg2/Server/FileMonitor/__init__.py
@@ -4,12 +4,13 @@ import os
import sys
import fnmatch
import logging
-import pkgutil
from time import sleep, time
-logger = logging.getLogger(__name__)
+LOGGER = logging.getLogger(__name__)
+
class Event(object):
+ """ Base class for all FAM events """
def __init__(self, request_id, filename, code):
self.requestID = request_id
self.filename = filename
@@ -53,33 +54,40 @@ class FileMonitor(object):
self.started = True
def debug_log(self, msg):
+ """ log a debug message """
if self.debug:
- logger.info(msg)
+ LOGGER.info(msg)
def should_ignore(self, event):
+ """ returns true if an event should be ignored """
for pattern in self.ignore:
- if (fnmatch.fnmatch(event.filename, pattern) or
+ if (fnmatch.fnmatch(event.filename, pattern) or
fnmatch.fnmatch(os.path.split(event.filename)[-1], pattern)):
self.debug_log("Ignoring %s" % event)
return True
return False
def pending(self):
+ """ returns True if there are pending events """
return bool(self.events)
def get_event(self):
+ """ get the oldest pending event """
return self.events.pop(0)
def fileno(self):
+ """ get the file descriptor of the file monitor thread """
return 0
def handle_one_event(self, event):
+ """ handle the given event by dispatching it to the object
+ that handles events for the path """
if not self.started:
self.start()
if self.should_ignore(event):
return
if event.requestID not in self.handles:
- logger.info("Got event for unexpected id %s, file %s" %
+ LOGGER.info("Got event for unexpected id %s, file %s" %
(event.requestID, event.filename))
return
self.debug_log("Dispatching event %s %s to obj %s" %
@@ -87,12 +95,13 @@ class FileMonitor(object):
self.handles[event.requestID]))
try:
self.handles[event.requestID].HandleEvent(event)
- except:
+ except: # pylint: disable=W0702
err = sys.exc_info()[1]
- logger.error("Error in handling of event %s for %s: %s" %
+ LOGGER.error("Error in handling of event %s for %s: %s" %
(event.code2str(), event.filename, err))
def handle_event_set(self, lock=None):
+ """ Handle all pending events """
if not self.started:
self.start()
count = 1
@@ -100,19 +109,18 @@ class FileMonitor(object):
start = time()
if lock:
lock.acquire()
- try:
- self.handle_one_event(event)
- while self.pending():
- self.handle_one_event(self.get_event())
- count += 1
- except:
- pass
+ self.handle_one_event(event)
+ while self.pending():
+ self.handle_one_event(self.get_event())
+ count += 1
if lock:
lock.release()
end = time()
- logger.info("Handled %d events in %.03fs" % (count, (end - start)))
+ LOGGER.info("Handled %d events in %.03fs" % (count, (end - start)))
def handle_events_in_interval(self, interval):
+ """ handle events for the specified period of time (in
+ seconds) """
if not self.started:
self.start()
end = time() + interval
@@ -124,10 +132,15 @@ class FileMonitor(object):
sleep(0.5)
def shutdown(self):
+ """ shutdown the monitor """
self.started = False
+ def AddMonitor(self, path, obj, handleID=None):
+ """ watch the specified path, alerting obj to events """
+ raise NotImplementedError
+
-available = dict()
+available = dict() # pylint: disable=C0103
# todo: loading the monitor drivers should be automatic
from Bcfg2.Server.FileMonitor.Pseudo import Pseudo