1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
|
""" Inotify driver for file alteration events """
import os
import stat
import logging
import operator
import pyinotify
from Bcfg2.Server.FileMonitor import FileMonitor, Event
logger = logging.getLogger(__name__)
class InotifyEvent(Event):
action_map = {pyinotify.IN_CREATE: 'created',
pyinotify.IN_DELETE: 'deleted',
pyinotify.IN_MODIFY: 'changed'}
def __init__(self, event):
Event.__init__(self, event.wd, event.pathname, event.mask)
if event.mask in self.action_map:
self.action = self.action_map[event.mask]
class Inotify(FileMonitor, pyinotify.ProcessEvent):
__priority__ = 1
mask = pyinotify.IN_CREATE | pyinotify.IN_DELETE | pyinotify.IN_MODIFY
def __init__(self, ignore=None, debug=False):
FileMonitor.__init__(self, ignore=ignore, debug=debug)
self.wm = pyinotify.WatchManager()
self.notifier = pyinotify.ThreadedNotifier(self.wm, self)
self.notifier.start()
def fileno(self):
return self.wm.get_fd()
def process_default(self, event):
self.events.append(InotifyEvent(event))
def AddMonitor(self, path, obj):
res = self.wm.add_watch(path, self.mask, quiet=False)
if not res:
# if we didn't get a return, but we also didn't get an
# exception, we're already watching this directory, so we
# need to find the watch descriptor for it
for wd, watch in self.wm.watches.items():
if watch.path == path:
wd = watch.wd
else:
wd = res[path]
self.handles[wd] = obj
self.events.append(Event(wd, path, "exists"))
mode = os.stat(path)[stat.ST_MODE]
if stat.S_ISDIR(mode):
for wname in os.listdir(path):
self.events.append(Event(wd, wname, "exists"))
return wd
def shutdown(self):
self.notifier.stop()
|