summaryrefslogtreecommitdiffstats
path: root/src/lib/Bcfg2/Server/FileMonitor
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/Bcfg2/Server/FileMonitor')
-rw-r--r--src/lib/Bcfg2/Server/FileMonitor/Inotify.py23
-rw-r--r--src/lib/Bcfg2/Server/FileMonitor/__init__.py14
2 files changed, 37 insertions, 0 deletions
diff --git a/src/lib/Bcfg2/Server/FileMonitor/Inotify.py b/src/lib/Bcfg2/Server/FileMonitor/Inotify.py
index 178a47b1a..cdd52dbb9 100644
--- a/src/lib/Bcfg2/Server/FileMonitor/Inotify.py
+++ b/src/lib/Bcfg2/Server/FileMonitor/Inotify.py
@@ -2,6 +2,7 @@
support. """
import os
+import errno
import logging
import pyinotify
from Bcfg2.Compat import reduce # pylint: disable=W0622
@@ -15,6 +16,8 @@ class Inotify(Pseudo, pyinotify.ProcessEvent):
""" File monitor backend with `inotify
<http://inotify.aiken.cz/>`_ support. """
+ __rmi__ = Pseudo.__rmi__ + ["list_watches", "list_paths"]
+
#: Inotify is the best FAM backend, so it gets a very high
#: priority
__priority__ = 99
@@ -182,6 +185,9 @@ class Inotify(Pseudo, pyinotify.ProcessEvent):
try:
watchdir = self.watches_by_path[watch_path]
except KeyError:
+ if not os.path.exists(watch_path):
+ raise OSError(errno.ENOENT,
+ "No such file or directory: '%s'" % path)
watchdir = self.watchmgr.add_watch(watch_path, self.mask,
quiet=False)[watch_path]
self.watches_by_path[watch_path] = watchdir
@@ -211,3 +217,20 @@ class Inotify(Pseudo, pyinotify.ProcessEvent):
if self.notifier:
self.notifier.stop()
shutdown.__doc__ = Pseudo.shutdown.__doc__
+
+ def list_watches(self):
+ """ XML-RPC that returns a list of current inotify watches for
+ debugging purposes. """
+ return list(self.watches_by_path.keys())
+
+ def list_paths(self):
+ """ XML-RPC that returns a list of paths that are handled for
+ debugging purposes. Because inotify doesn't like watching
+ files, but prefers to watch directories, this will be
+ different from
+ :func:`Bcfg2.Server.FileMonitor.Inotify.Inotify.ListWatches`. For
+ instance, if a plugin adds a monitor to
+ ``/var/lib/bcfg2/Plugin/foo.xml``, :func:`ListPaths` will
+ return ``/var/lib/bcfg2/Plugin/foo.xml``, while
+ :func:`ListWatches` will return ``/var/lib/bcfg2/Plugin``. """
+ return list(self.handles.keys())
diff --git a/src/lib/Bcfg2/Server/FileMonitor/__init__.py b/src/lib/Bcfg2/Server/FileMonitor/__init__.py
index d77f21b93..522ddb705 100644
--- a/src/lib/Bcfg2/Server/FileMonitor/__init__.py
+++ b/src/lib/Bcfg2/Server/FileMonitor/__init__.py
@@ -116,6 +116,9 @@ class FileMonitor(Debuggable):
#: should have higher priorities.
__priority__ = -1
+ #: List of names of methods to be exposed as XML-RPC functions
+ __rmi__ = Debuggable.__rmi__ + ["list_event_handlers"]
+
def __init__(self, ignore=None, debug=False):
"""
:param ignore: A list of filename globs describing events that
@@ -288,6 +291,8 @@ class FileMonitor(Debuggable):
def shutdown(self):
""" Handle any tasks required to shut down the monitor. """
+ self.debug_log("Shutting down %s file monitor" %
+ self.__class__.__name__)
self.started = False
def AddMonitor(self, path, obj, handleID=None):
@@ -310,6 +315,15 @@ class FileMonitor(Debuggable):
"""
raise NotImplementedError
+ def list_event_handlers(self):
+ """ XML-RPC that returns
+ :attr:`Bcfg2.Server.FileMonitor.FileMonitor.handles` for
+ debugging purposes. """
+ rv = dict()
+ for watch, handler in self.handles.items():
+ rv[watch] = getattr(handler, "name", handler.__class__.__name__)
+ return rv
+
#: A module-level FAM object that all plugins, etc., can use. This
#: should not be used directly, but retrieved via :func:`get_fam`.