def __init__(self, paths, white_list, black_list, delay): """Creates a new file change monitor.""" # Events of interest. self.WATCH_EVENTS = inotifyx.IN_CREATE | inotifyx.IN_MODIFY | inotifyx.IN_DELETE | inotifyx.IN_DELETE_SELF | inotifyx.IN_MOVE # Remember params. self.white_list = white_list self.black_list = black_list self.delay = delay # Init inotify. self.fd = inotifyx.init() # Watch specified paths. self.watches = {} self.watches.update( (inotifyx.add_watch(self.fd, path, self.WATCH_EVENTS), path) for path in paths) # Watch sub dirs of specified paths. Ensure we modify dirs # variable in place so that os.walk only traverses white # listed dirs. for path in paths: for root, dirs, files in os.walk(path): dirs[:] = [dir for dir in dirs if self.is_white_listed(dir)] self.watches.update((inotifyx.add_watch( self.fd, os.path.join(root, dir), self.WATCH_EVENTS), os.path.join(root, dir)) for dir in dirs)
def __init__(self, paths, white_list, black_list, delay): """Creates a new file change monitor.""" # Events of interest. self.WATCH_EVENTS = inotifyx.IN_CREATE | inotifyx.IN_MODIFY | inotifyx.IN_MOVE# | inotifyx.IN_DELETE_SELF | inotifyx.IN_DELETE # Remember params. self.white_list = white_list self.black_list = black_list self.delay = delay # Init inotify. self.fd = inotifyx.init() # Watch specified paths. self.watches = {} self.watches.update((inotifyx.add_watch(self.fd, path, self.WATCH_EVENTS), path) for path in paths) # Watch sub dirs of specified paths. Ensure we modify dirs # variable in place so that os.walk only traverses white # listed dirs. for path in paths: for root, dirs, files in os.walk(path): dirs[:] = [dir for dir in dirs if self.is_white_listed(dir)] self.watches.update((inotifyx.add_watch(self.fd, os.path.join(root, dir), self.WATCH_EVENTS), os.path.join(root, dir)) for dir in dirs)
def start ( self ): if self._run: return self._run = True self._id = inotifyx.init() self._wd = inotifyx.add_watch(self._id, self._conf['dev_path'], inotifyx.IN_CREATE | inotifyx.IN_DELETE) threading.Thread.start(self)
def start(self): if self._run: return self._run = True self._id = inotifyx.init() self._wd = inotifyx.add_watch(self._id, self._conf['dev_path'], inotifyx.IN_CREATE | inotifyx.IN_DELETE) threading.Thread.start(self)
def _observe_inotify(self, watch_dir): self.msg.info(self.name, 'Using inotify.') timeout = -1 fd = inotifyx.init() try: self._inotify_watch_recursive(fd, watch_dir) while True: events = inotifyx.get_events(fd, timeout) if events: for event in events: if not event.mask & inotifyx.IN_ISDIR: (state, show_tuple) = self._get_playing_show() self.update_show_if_needed(state, show_tuple) if self.last_state == STATE_NOVIDEO: # Make get_events block indifinitely timeout = -1 else: timeout = 1 else: self.update_show_if_needed(self.last_state, self.last_show_tuple) except IOError: self.msg.warn(self.name, 'Watch directory not found! Tracker will stop.') finally: os.close(fd)
def run(self): # watch intel vbtn for event to know when to parse dmesg for what it was self.log.info("StanceWatcher started") vbtnWatchFd = inotifyx.init() try: self.log.debug("Add Watch for Intel Virtual Button input...") vbtnWatch = inotifyx.add_watch(vbtnWatchFd, Config['intelVbtnInput'], inotifyx.IN_ACCESS) lastEventTime = 0.0 while not self.stopEv.is_set(): vbtnEvent = inotifyx.get_events(vbtnWatchFd,0.8) if len(vbtnEvent) > 0: now = time.time(); # vbtn event file is modified multiple times on a lid rotation, a quick solution to fire stance change only once # assuming the user won't rotate the lid very frequently (like under a second...) if now - lastEventTime > 0.8: self.log.debug("lid rotate event occurred, parse syslog...") time.sleep(0.2) #give time for event to appear in syslog readStance = self.parseStanceFromSyslog() if readStance: self.stance = readStance self.log.debug("Stance updated to %s", self.stance) self.changeEvent.set() else: self.log.warning("Got None, stance NOT updated.") else: self.log.debug("event discarded, too soon") lastEventTime = now inotifyx.rm_watch(vbtnWatchFd, vbtnWatch) self.log.debug("Removed watch for Intel Virtual Button input") finally: os.close(vbtnWatchFd)
def setUp(self): self.workdir = os.path.abspath(os.getcwd()) self.testdir = os.path.abspath( os.path.join(os.path.dirname(__file__), 'test')) os.mkdir(self.testdir) os.chdir(self.testdir) self.fd = inotifyx.init()
def __init__(self, watch_dir, n_files): super().__init__(watch_dir, n_files) self.wd_to_path = {} self.inotify_binding = inotifyx.init() wd = inotifyx.add_watch(self.inotify_binding, self.watch_dir) self.wd_to_path[wd] = self.watch_dir
def livepdf(): import inotifyx, sys, os, time, subprocess sys.path.insert(0, sourcedir) from conf import basic_filename subprocess.call( ['xdg-open', builddir + 'latex/' + basic_filename + '.pdf']) fd = inotifyx.init() try: wd = inotifyx.add_watch(fd, sourcedir, inotifyx.IN_CLOSE_WRITE) try: while True: events = [] events += inotifyx.get_events(fd, 0) time.sleep(1) events += inotifyx.get_events(fd, 0) names = set() for event in events: if event.name and event.name[-3:-1] != 'sw' and event.name[ -1] != '!': names.add(sourcedir + event.name) if len(names) > 0: print('%s modified' % ','.join(names)) subprocess.call(['make', 'latexpdf']) except KeyboardInterrupt: pass finally: os.close(fd)
class Observer(base.Observer): _fd = inotifyx.init() _wd = dict() @classmethod def add_observer(self, observer): self._observers.append(observer) observer._wd = inotifyx.add_watch( self._fd, observer.dir, inotifyx.IN_CREATE | inotifyx.IN_MOVE | inotifyx.IN_DELETE | inotifyx.IN_ATTRIB, ) self._wd[observer._wd] = observer @classmethod def remove_observer(self, observer): inotifyx.rm_watch(self._fd, observer._wd) self._observers.remove(observer) del self._wd[observer._wd] @classmethod def check(self): for event in inotifyx.get_events(self._fd): self.log.debug('%s %r [%s]', event, event.name, event.cookie) if event.wd in self._wd: self._wd[event.wd].dispatch() @classmethod def close(self): os.close(self._fd)
def _observe_inotify(self, watch_dir): self.msg.info(self.name, 'Using inotify.') timeout = -1 fd = inotifyx.init() try: self._inotify_watch_recursive(fd, watch_dir) while True: events = inotifyx.get_events(fd, timeout) if events: for event in events: if not event.mask & inotifyx.IN_ISDIR: filename = self._get_playing_file_lsof(self.process_name) (state, show_tuple) = self._get_playing_show(filename) self.update_show_if_needed(state, show_tuple) if self.last_state == STATE_NOVIDEO: # Make get_events block indifinitely timeout = -1 else: timeout = 1 else: self.update_show_if_needed(self.last_state, self.last_show_tuple) except IOError: self.msg.warn(self.name, 'Watch directory not found! Tracker will stop.') finally: os.close(fd)
def __init__(self): super(IOWatcher, self).__init__() self.daemon = True self.last_update = datetime.datetime(1970,1,1) self.callbacks = [] self.fd = inotifyx.init() self.wd = inotifyx.add_watch(self.fd, FILE_DIR) self.NOTABLE = inotifyx.IN_CLOSE_WRITE | inotifyx.IN_MOVE
def install_watcher(self): self.watch_fd = inotifyx.init() for d in self.base_dirs: if os.path.isdir(d): logging.info('adding watch for {0}'.format(d)) self.watches[inotifyx.add_watch(self.watch_fd, d, inotifyx.IN_MODIFY | inotifyx.IN_CREATE)] = d glib.timeout_add_seconds(3, self.do_watch)
def waitDeletion(self): inotify_fd = inotifyx.init() try: inotifyx.add_watch(inotify_fd, self.filename, inotifyx.IN_DELETE) inotifyx.get_events(inotify_fd) except IOError: # add_watch failed pass finally: os.close(inotify_fd) self.__enter__()
def parse_args(self): # Fails if path is not a directory. if not os.path.isdir(self.params.path): raise gc3libs.exceptions.InvalidUsage("%s is not a directory", self.params.path) # We start the inotify as soon as possible, so that if a new # file is created between the execution of this function and # the every_main_loop() call (which is called *after* the main # loop), we don't lose the newly created file. self.ifd = inotifyx.init() self.iwatch = inotifyx.add_watch(self.ifd, self.params.path, inotifyx.IN_CLOSE_WRITE)
def ivisit(self): try: fd = inotifyx.init() wd = inotifyx.add_watch(fd, self.items[0], inotifyx.IN_CLOSE) self.urlvisit() inotifyx.get_events(fd, self.keep) inotifyx.rm_watch(fd, wd) os.close(fd) except IOError: hint = "consider increasing " "/proc/sys/fs/inotify/max_user_watches" raise util.DeadMan("failed to enable inotify", hint=hint)
def run(self): logging.debug('starting watcher thread') mask = inotifyx.IN_MODIFY | inotifyx.IN_CLOSE_WRITE in_fd = inotifyx.init() for f in self.watch_files: inotifyx.add_watch(in_fd, f, mask) logging.debug('watching ' + f) while True: logging.debug('watcher waiting for events') inotifyx.get_events(in_fd) logging.debug('watcher got change event') self.mapfuse.read_list()
def ivisit(self): try: fd = inotifyx.init() wd = inotifyx.add_watch(fd, self.items[0], inotifyx.IN_CLOSE) self.urlvisit() inotifyx.get_events(fd, self.keep) inotifyx.rm_watch(fd, wd) os.close(fd) except IOError: hint = ('consider increasing ' '/proc/sys/fs/inotify/max_user_watches') raise util.DeadMan('failed to enable inotify', hint=hint)
def _main(): watch_dir = "/tmp/watch_tree" create_thread = threading.Thread(target=create_test_files, args=(watch_dir, )) try: os.mkdir(watch_dir) except OSError: pass fd = inotifyx.init() wd_to_path = {} try: wd = inotifyx.add_watch(fd, watch_dir) wd_to_path[wd] = watch_dir print("wd_to_path: ", wd_to_path) except Exception: print("stopped") os.close(fd) sys.exit(1) create_thread.start() try: while True: events = inotifyx.get_events(fd) for event in events: path = wd_to_path[event.wd] event_type = event.get_mask_description() event_type_array = event_type.split("|") # remember dir name if "IN_ISDIR" in event_type_array and "IN_CREATE" in event_type: new_dir = os.path.join(path, event.name) wd = inotifyx.add_watch(fd, new_dir) wd_to_path[wd] = new_dir print("PATH=[{}] FILENAME=[{}] EVENT_TYPES={}".format( path, event.name, event_type_array)) except KeyboardInterrupt: pass finally: os.close(fd)
def tail(self): fd = inotifyx.init() try: wd = inotifyx.add_watch(fd, '/var/log/emerge.log', inotifyx.IN_MODIFY) self.log_currentcompile(1) # only wait for a second for the sandbox while True: self.log_heartbeat() events = inotifyx.get_events(fd, float(self.nap)) if len(events) != 0: # not timeout self.log_currentcompile(self.sandboxwait) inotifyx.rm_watch(fd, wd) finally: os.close(fd)
def main_linux(data_dir): """Notify about events triggered base on inotify. Args: data_dir: The directory to watch. """ from inotifyx import init, add_watch, get_events inotify_fd = init() wd_to_path = {} try: # get all subdirs # do not register right away because it will trigger events dirs = [] for root, _, _ in os.walk(data_dir): dirs.append(root) for i in dirs: wd_to_path[add_watch(inotify_fd, i)] = i try: while True: events = get_events(inotify_fd) for event in events: path = wd_to_path[event.wd] parts = event.get_mask_description() logging.info("%s: %s/%s", parts, path, event.name) # is_created = ("IN_CREATE" in parts) # is_dir = ("IN_ISDIR" in parts) # is_closed = ("IN_CLOSE" in a_array # or "IN_CLOSE_WRITE" in a_array) # if a new directory is created inside the monitored one, # this one has to be monitored as well # if is_created and is_dir and event.name: if ("IN_CREATE" in parts and "IN_ISDIR" in parts and event.name): dirname = path + os.sep + event.name wd_to_path[add_watch(inotify_fd, dirname)] = dirname except KeyboardInterrupt: pass finally: os.close(inotify_fd)
def start ( self ): self.notify('Started', 'BrytonSync started') if self._run: return # Create dirs tdir = os.path.expanduser(self._conf['track_dir']) if not os.path.exists(tdir): os.makedirs(tdir) # Setup inotify self._run = True self._id = inotifyx.init() self._wd = inotifyx.add_watch(self._id, tdir) # Start device monitor self._devmon.start() if not self._conf['nosync']: threading.Thread.start(self)
def watch(self): fd = inotifyx.init() wd = inotifyx.add_watch(fd, self.pickup_dir, inotifyx.constants["IN_CLOSE_WRITE"]) keep_running = True while keep_running: try: events = inotifyx.get_events(fd, 1.0) for event in events: self.pickup_event_processor.process(event) sleep(0.1) except KeyboardInterrupt: keep_running = False os.close(fd)
def _main(): watch_dir = "/tmp/watch_tree" try: for path in watch_dir: os.mkdir(path) except OSError: pass fd = inotifyx.init() wd_to_path = {} try: wd = inotifyx.add_watch(fd, watch_dir) wd_to_path[wd] = watch_dir print("wd_to_path: ", wd_to_path) except Exception as excp: print("stopped") print("Exception was", excp) os.close(fd) sys.exit(1) with open(os.path.join(watch_dir, "test_file"), "w"): pass try: while True: events = inotifyx.get_events(fd) for event in events: path = wd_to_path[event.wd] event_type = event.get_mask_description() event_type_array = event_type.split("|") print("PATH=[{}] FILENAME=[{}] EVENT_TYPES={}".format( path, event.name, event_type_array)) except KeyboardInterrupt: pass finally: os.close(fd)
def __init__(self, directory): gobject.GObject.__init__(self) self.directory = gio.File(directory) self.objects = {} if not self.directory.query_exists(None): raise RuntimeError("%s does not exist!" % directory) self.monitor_fd = None ## inotify file monitor if inotifyx: fd = inotifyx.init() ix = inotifyx wd = inotifyx.add_watch(fd, self.directory.get_path(), ix.IN_CLOSE_WRITE | ix.IN_DELETE | ix.IN_MODIFY) glib.io_add_watch(fd, glib.IO_IN, self.on_inotifyx, fd) self.monitor_fd = fd self.monitor = self.directory.monitor_directory() if self.monitor is not None: self.monitor.connect("changed", self.on_file_monitor_changed)
def watchFiles(queue): mediaFound = False fd = inotifyx.init() wd = inotifyx.add_watch(fd, watchPath, inotifyx.IN_CLOSE) while (1): # Wait for an event with timeout. event = inotifyx.get_events(fd, eventTimeout) print("Event caught, or timed-out.") # Wait before reading files time.sleep(readDelay) for fname in os.listdir(watchPath): fpath = os.path.join(watchPath, fname) if (os.path.isfile(fpath) and fname.startswith(watchFilePrefix) and fname.endswith(watchFileSuffix)): mediaFound = False print ("Processing file: " + fpath) f = open(fpath, "r") for line in f: pieces = shlex.split(line.strip()) for p in pieces: queue.put(p) print ("Found: " + p) mediaFound = True f.close() # Only remove the file if we found something in it if(mediaFound): os.remove(fpath) print("Deleting file.") # Drain events from file operations. e = inotifyx.get_events(fd, 0) while e: e = inotifyx.get_events(fd, 0) inotifyx.rm_watch(fd, wd) os.close(fd)
def ssh(self, cmd, output_catcher=ForwardToStd(), remotes_stdin=None): if not cmd: # XXX: Where do these empty commands come from? return def assert_master_openssh_running(): if self.master_openssh.poll() == 255: raise Offline(self) ssh_master_socket = self.ssh_master_socket if not ssh_master_socket: ssh_master_socket_dir = on_exit_vanishing_dtemp() ssh_master_socket = join(ssh_master_socket_dir, 'socket') self.ssh_master_socket = ssh_master_socket fd = inotifyx.init() try: inotifyx.add_watch(fd, ssh_master_socket_dir) self.master_openssh = master_openssh = self.openssh( ['-M', '-N'] + remote_authorized_key_env(), [], stderr=PIPE) filter_masters_stderr_thread = threading.Thread( target=self.filter_masters_stderr, args=(master_openssh.stderr,) ) filter_masters_stderr_thread.daemon = True filter_masters_stderr_thread.start() # Wait for termination in the case the target is # not available: while True: if inotifyx.get_events(fd, 0.1): register(master_openssh.kill) break assert_master_openssh_running() finally: os.close(fd) cmd_openssh = self.openssh(output_catcher.allocate_tty, [cmd], remotes_stdin, output_catcher.remotes_stdout, output_catcher.remotes_stdout) communicate_with_child(cmd_openssh, output_catcher, assert_master_openssh_running, cmd)
def __init__(self, url, mask=events['IN_ALL_EVENTS'], recurse=False, **kw): super(INotifyPoller, self).__init__(url, mask, **kw) self._recurse = recurse self._ifd = inotifyx.init() self._watched = set() # Ensure inbox directory exists if not os.path.exists(self.url.path): gc3libs.log.info( "Inbox directory `%s` does not exist," " creating it ...", self.url.path) os.makedirs(self.url.path) self.watch(self.url.path) if self._recurse: for dirpath, dirnames, filenames in os.walk(self.url.path): self.watch(dirpath) for name in filenames: path = os.path.join(self.url.path, dirpath, name) self.watch(path)
def subfiles(directory): """Return the list of subfiles of a directory, and wait for the newly created ones. CAUTION : *DONT TRY TO CONVERT THE RESULT OF THIS FUNCTION INTO A LIST ! ALWAYS ITERATE OVER IT !!!*""" watchfd = inotifyx.init() inotifyx.add_watch(watchfd, directory, inotifyx.IN_CREATE) try: subfiles = set(os.listdir(directory)) subfiles |= set([file_.name for file_ in inotifyx.get_events(watchfd, 0)]) while True: for file_ in subfiles: yield os.path.join(directory, file_) subfiles = [file_.name for file_ in inotifyx.get_events(watchfd)] finally: os.close(watchfd)
def subfiles(directory): """Return the list of subfiles of a directory, and wait for the newly created ones. CAUTION : *DONT TRY TO CONVERT THE RESULT OF THIS FUNCTION INTO A LIST ! ALWAYS ITERATE OVER IT !!!*""" watchfd = inotifyx.init() inotifyx.add_watch(watchfd, directory, inotifyx.IN_CREATE) try: subfiles = set(os.listdir(directory)) subfiles |= set( [file_.name for file_ in inotifyx.get_events(watchfd, 0)]) while True: for file_ in subfiles: yield os.path.join(directory, file_) subfiles = [file_.name for file_ in inotifyx.get_events(watchfd)] finally: os.close(watchfd)
def __init__(self, url, mask, recurse=False, **kw): Poller.__init__(self, url, mask, **kw) self._recurse = recurse self._ifds = {} # Ensure inbox directory exists if not os.path.exists(self.url.path): log.warning("Inbox directory `%s` does not exist," " creating it.", self.url.path) os.makedirs(self.url.path) ifd = inotifyx.init() inotifyx.add_watch(ifd, self.url.path, self.mask) log.debug("Adding watch for path %s" % self.url.path) self._ifds[self.url.path] = ifd if self._recurse: for dirpath, dirnames, filename in os.walk(self.url.path): for dirname in dirnames: abspath = os.path.join(self.url.path, dirpath, dirname) log.debug("Adding watch for path %s" % abspath) self._add_watch(abspath)
def ino_watch(file_to_watch, action, *action_args): ''' ``inotify``-based watcher, applying function upon *write-and-close* events ''' watcher = inotifyx.init() #TODO: implement check like "it's a directory and you don't run a cmd!" if not os.path.isdir(file_to_watch): dirname = os.path.dirname(file_to_watch) or '.' basename = os.path.basename(file_to_watch) else: dirname = file_to_watch basename = None # we watch for CLOSE_WRITE events in directory and filter them by file name # because editors like vim do save&rename instead of simple modification inotifyx.add_watch(watcher, dirname, inotifyx.IN_CLOSE_WRITE) # wrap action to avoid code duplication action_lambda = lambda: action(file_to_watch, *action_args) # run the first time action_lambda() while True: events = inotifyx.get_events(watcher) if (basename is None) or (basename in (ev.name for ev in events)): action_lambda()
def scan(topdir): ''' print filesystem events for tree of files ''' fd = inotifyx.init() mask = inotifyx.IN_MODIFY | inotifyx.IN_CLOSE_WRITE if 0: mask = inotifyx.IN_ALL_EVENTS wd_to_path = add_watch_dirs( topdir=topdir, fd=fd, mask=mask, ) try: oldpath = None while True: for event in inotifyx.get_events(fd): path = os.path.join( wd_to_path[event.wd], event.name if event.name else '', ) parts = [ event.get_mask_description() ] parts = [ word.replace('IN_ALL_EVENTS|', '') for word in parts ] if path != oldpath: print path oldpath = path print '\t', ' '.join(parts) except KeyboardInterrupt: pass finally: os.close(fd)
def _wait_files_creation(file_list): # Etablish a list of directory and subfiles directories = dict() for dirname, filename in [os.path.split(f) for f in file_list]: directories.setdefault(dirname, dict()) directories[dirname][filename] = False def all_files_exists(): return all([all(files.values()) for files in directories.values()]) fd = inotifyx.init() try: # Watch every directories where the file are watchdescriptors = dict() for dirname in directories.keys(): wd = inotifyx.add_watch(fd, dirname, inotifyx.IN_CREATE | inotifyx.IN_DELETE) watchdescriptors[wd] = dirname # Set to True the file wich exists for dirname, filename in [os.path.split(f) for f in file_list]: directories[dirname][filename] = os.path.exists(os.path.join(dirname, filename)) # Let's wait for every file creation while not all_files_exists(): events_list = inotifyx.get_events(fd) for event in events_list: dirname = watchdescriptors[event.wd] if event.name in directories[dirname]: # One of watched file was created or deleted if event.mask & inotifyx.IN_DELETE: directories[dirname][event.name] = False else: directories[dirname][event.name] = True finally: os.close(fd)
def _wait_files_creation(file_list): # Etablish a list of directory and subfiles directories = dict() for dirname, filename in [os.path.split(f) for f in file_list]: directories.setdefault(dirname, dict()) directories[dirname][filename] = False def all_files_exists(): return all([all(files.values()) for files in directories.values()]) fd = inotifyx.init() try: # Watch every directories where the file are watchdescriptors = dict() for dirname in directories.keys(): wd = inotifyx.add_watch(fd, dirname, inotifyx.IN_CREATE | inotifyx.IN_DELETE) watchdescriptors[wd] = dirname # Set to True the file wich exists for dirname, filename in [os.path.split(f) for f in file_list]: directories[dirname][filename] = os.path.exists( os.path.join(dirname, filename)) # Let's wait for every file creation while not all_files_exists(): events_list = inotifyx.get_events(fd) for event in events_list: dirname = watchdescriptors[event.wd] if event.name in directories[dirname]: # One of watched file was created or deleted if event.mask & inotifyx.IN_DELETE: directories[dirname][event.name] = False else: directories[dirname][event.name] = True finally: os.close(fd)
import time import RPi.GPIO as GPIO from pulsatingLED import PulsatingLED from tardisButton import TardisButton from indicators import Indicators from volume import Volume import subprocess import sys import os import glob import inspect import inotifyx import json # Setup a watch fd = inotifyx.init() # Where are we? dir = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe()))) # Initial volume (from file if exists, else 80) vol = Volume(dir) # RGB display and music player m = SonicRGB(red=7, green=24, blue=26, pwmFrequency=500, cutoffs=[50, 500, 2000, 15000]) # The 5 music selection buttons b1 = TardisButton(11, m) b2 = TardisButton(13, m) b3 = TardisButton(12, m)
def setUp(self): os.mkdir(self.test_dir) os.chdir(self.test_dir) self.fd = inotifyx.init()
def watch_dhcp_leases(path): """ This is a generator for events that happen to the file at the given path. It assumes ISC DHCPD -like behavior; that is, ISC dhcpd man page dhcpd.leases(5) promises that the leases file is only updated in exactly two ways: 1. new entries are appended 2. a new (pruned) lease file is renamed to the monitored filename (the old file is first moved out of the way, but that's not relevant here) So we trigger events on appends and lease file replacement, and start monitoring the new file on the latter. Example:: for _ in watch('/var/lib/dhcp/dhcpd.leases'): print "Stuff happened!" """ fd = inotifyx.init() parent = os.path.dirname(path) if parent == '': # this happens if path had no slashes in it; mostly when # testing manually parent = '.' try: wd_new = inotifyx.add_watch( fd, parent, inotifyx.IN_MOVED_TO | inotifyx.IN_ONLYDIR, ) while True: # the only real reason for `path` not to exist here is on # first loop (assuming dhcpd behavior); `replaced` only # becomes True after a file is renamed to this name, so # there's no race there (barring un-dhcpd like behavior # like deleting the file) wd_journal = inotifyx.add_watch( fd, path, inotifyx.IN_MODIFY, ) # yield once in order to 1) make caller read the existing # content of the file and 2) make writing unit tests # easier; now we already have an open inotify fd with the # right watches yield None replaced = False while not replaced: for e in inotifyx.get_events(fd): if e.mask & inotifyx.IN_Q_OVERFLOW: yield e # we could have lost an IN_MOVED_TO event, # do this just in case replaced = True elif e.wd == wd_journal: yield e elif (e.wd == wd_new and e.mask & inotifyx.IN_MOVED_TO and e.name == os.path.basename(path)): # the old watch is implicitly removed as the # file is deleted, no need to clean that up; # not 100% sure if this will leak wds or not replaced = True finally: os.close(fd)
#!/usr/bin/python import inotifyx, re, syslog, os """ TODO: Deal with log rotation, 9-5 no sleep schedule, xbmc/vlc(via psutil?) no sleep """ LOG = "/var/log/auth.log" ifd = inotifyx.init() log = inotifyx.add_watch( ifd, LOG, inotifyx.IN_MODIFY | inotifyx.IN_ATTRIB | inotifyx.IN_DELETE_SELF | inotifyx.IN_MOVE_SELF) f = open(LOG) sessions = set() while True: line = f.readline() if line == '': # we've reached end of log, inotify avoids polling for growth # suspend if after 60seconds after activity in auth log stopped, there are still 0 ssh sessions ls = [] while len(ls) == 0: ls = inotifyx.get_events(ifd, 60) # sometimes the log is missing an entry # make sure that we only wait for live processes for pid in list(sessions): if not os.path.exists("/proc/%s" % pid): print "Removing stale pid %s" % pid sessions.remove(pid) if len(ls) + len(sessions) == 0: syslog.syslog("No more ssh sessions, going to sleep") os.system("/home/taras/work/sleepyscripts/suspend.sh") for e in ls: print e.get_mask_description()
def _add_watch(self, path): if path not in self._ifds: log.debug("Adding watch for path %s" % path) ifd = inotifyx.init() inotifyx.add_watch(ifd, path, self.mask) self._ifds[path] = ifd
def __init__(self): super(Monitor, self).__init__() self.fd = inotifyx.init() self.dirs = {} self.wds = {} self.queue = []
def getFd(self): if not hasattr(self, '_fd'): self._fd = init() return self._fd
def _setup(self): """Initiate class variables and environment. Sets static configuration parameters creates ring buffer and starts cleanup thread. """ try: self.timeout = self.config["event_timeout"] except KeyError: # when using old config file type self.timeout = 1 self.file_descriptor = inotifyx.init() # TODO why is this necessary self.paths = [self.config["monitored_dir"]] self.mon_subdirs = self.config["fix_subdirs"] self.mon_regex_per_event = self.config["monitored_events"] self.log.debug("monitored_events=%s", self.config["monitored_events"]) regexes = [] for key, value in iteritems(self.config["monitored_events"]): self.mon_regex_per_event[key] = (convert_suffix_list_to_regex( value, compile_regex=False, log=self.log)) regexes.append(self.mon_regex_per_event[key]) # cannot be compiled before because regexes needs to be a list # of string try: self.mon_regex_per_event[key] = (re.compile( self.mon_regex_per_event[key])) except Exception: self.log.error("Could not compile regex '%s'", self.mon_regex_per_event[key], exc_info=True) raise self.log.debug("regexes=%s", regexes) self.mon_regex = convert_suffix_list_to_regex(regexes, suffix=False, compile_regex=True, log=self.log) self.history = collections.deque(maxlen=self.config["history_size"]) self.lock = threading.Lock() self._add_watch() if self.config["use_cleanup"]: self.cleanup_time = self.config["time_till_closed"] self.action_time = self.config["action_time"] self.get_remaining_events = self._get_events_from_cleanup self.cleanup_thread = CleanUp(paths=self.paths, mon_subdirs=self.mon_subdirs, mon_regex=self.mon_regex, cleanup_time=self.cleanup_time, action_time=self.action_time, lock=self.lock, log_queue=self.log_queue) self.cleanup_thread.start() else: self.get_remaining_events = self._get_no_events
def main(): ''' The main function ''' try: if len(sys.argv) < 2: print_help() else: command = sys.argv[1] # Start the system if command == "start": # Set keyboard to use steelsquid_utils.execute_system_command_blind(["/usr/bin/termfix", steelsquid_utils.get_parameter("keyboard")], wait_for_finish=True) # Redirect sys.stdout to shout sys.stdout = Logger() # Create the task event dir steelsquid_utils.make_dirs(system_event_dir) # Print welcome message steelsquid_utils.shout("Steelsquid Kiss OS "+steelsquid_utils.steelsquid_kiss_os_version()[1], to_lcd=False, wait_for_finish=False) # Use locking on the I2C bus if steelsquid_utils.get_flag("i2c_lock"): steelsquid_i2c.enable_locking(True) else: steelsquid_i2c.enable_locking(False) # Disable the monitor if steelsquid_utils.get_flag("disable_monitor"): steelsquid_utils.execute_system_command_blind(["/opt/vc/bin/tvservice", "-o"], wait_for_finish=False) # Listen for shutdown on GPIO if steelsquid_utils.has_parameter("power_gpio"): gpio = steelsquid_utils.get_parameter("power_gpio") steelsquid_utils.shout("Listen for clean shutdown on GPIO " + gpio) steelsquid_pi.gpio_click(gpio, poweroff, steelsquid_pi.PULL_DOWN) # Load all modules pkgpath = os.path.dirname(modules.__file__) for name in pkgutil.iter_modules([pkgpath]): if steelsquid_utils.get_flag("module_"+name[1]): steelsquid_utils.shout("Load module: " +name[1], debug=True) n = name[1] steelsquid_kiss_global.loaded_modules[n]=import_module('modules.'+n) # Enable the download manager if steelsquid_utils.get_flag("download"): if steelsquid_utils.get_parameter("download_dir") == "": steelsquid_utils.set_parameter("download_dir", "/root") steelsquid_utils.execute_system_command_blind(['steelsquid', 'download-on'], wait_for_finish=False) # Enable NRF24L01+ as server if steelsquid_utils.get_flag("nrf24_server"): steelsquid_utils.shout("Enable NRF24L01+ server") steelsquid_nrf24.server() thread.start_new_thread(nrf24_server_thread, ()) # Enable NRF24L01+ as client elif steelsquid_utils.get_flag("nrf24_client"): steelsquid_utils.shout("Enable NRF24L01+ client") steelsquid_nrf24.client() # Enable NRF24L01+ as master if steelsquid_utils.get_flag("nrf24_master"): steelsquid_utils.shout("Enable NRF24L01+ master") steelsquid_nrf24.master(nrf24_callback) # Enable NRF24L01+ as slave elif steelsquid_utils.get_flag("nrf24_slave"): steelsquid_utils.shout("Enable NRF24L01+ slave") steelsquid_nrf24.slave() thread.start_new_thread(nrf24_slave_thread, ()) # Enable HM-TRLR-S as server if steelsquid_utils.get_flag("hmtrlrs_server"): config_gpio = int(steelsquid_utils.get_parameter("hmtrlrs_config_gpio", "25")) reset_gpio = int(steelsquid_utils.get_parameter("hmtrlrs_reset_gpio", "23")) steelsquid_utils.shout("Enable HM-TRLR-S server") steelsquid_hmtrlrs.setup(config_gpio=config_gpio, reset_gpio=reset_gpio) thread.start_new_thread(hmtrlrs_server_thread, ()) # Enable HM-TRLR-S as client elif steelsquid_utils.get_flag("hmtrlrs_client"): config_gpio = int(steelsquid_utils.get_parameter("hmtrlrs_config_gpio", "25")) reset_gpio = int(steelsquid_utils.get_parameter("hmtrlrs_reset_gpio", "23")) steelsquid_utils.shout("Enable HM-TRLR-S client") steelsquid_hmtrlrs.setup(config_gpio=config_gpio, reset_gpio=reset_gpio) thread.start_new_thread(hmtrlrs_client_thread, ()) # Start the modules for obj in steelsquid_kiss_global.loaded_modules.itervalues(): thread.start_new_thread(import_file_dyn, (obj,)) # Enable the webserver if steelsquid_utils.get_flag("web"): port = None if steelsquid_utils.has_parameter("web_port"): port = steelsquid_utils.get_parameter("web_port") steelsquid_kiss_global.http_server = steelsquid_kiss_http_server.SteelsquidKissHttpServer(port, steelsquid_utils.STEELSQUID_FOLDER+"/web/", steelsquid_utils.get_flag("web_authentication"), steelsquid_utils.get_flag("web_local"), steelsquid_utils.get_flag("web_authentication"), steelsquid_utils.get_flag("web_https")) for obj in steelsquid_kiss_global.loaded_modules.itervalues(): if hasattr(obj, "WEB"): steelsquid_kiss_global.http_server.external_objects.append(getattr(obj, "WEB")) steelsquid_kiss_global.http_server.start_server() # Enable the socket server as server if steelsquid_utils.get_flag("socket_server"): steelsquid_kiss_global.socket_connection = steelsquid_kiss_socket_connection.SteelsquidKissSocketConnection(True) for obj in steelsquid_kiss_global.loaded_modules.itervalues(): if hasattr(obj, "SOCKET"): steelsquid_kiss_global.socket_connection.external_objects.append(getattr(obj, "SOCKET")) steelsquid_kiss_global.socket_connection.start() # Enable the socket server as client elif steelsquid_utils.has_parameter("socket_client"): steelsquid_kiss_global.socket_connection = steelsquid_kiss_socket_connection.SteelsquidKissSocketConnection(False, steelsquid_utils.get_parameter("socket_client")) for obj in steelsquid_kiss_global.loaded_modules.itervalues(): if hasattr(obj, "SOCKET"): steelsquid_kiss_global.socket_connection.external_objects.append(getattr(obj, "SOCKET")) steelsquid_kiss_global.socket_connection.start() # Enable the bluetooth if steelsquid_utils.get_flag("bluetooth_pairing"): if not steelsquid_utils.has_parameter("bluetooth_pin"): steelsquid_utils.set_parameter("bluetooth_pin", "1234") thread.start_new_thread(bluetooth_agent, ()) fd = inotifyx.init() inotifyx.add_watch(fd, system_event_dir, inotifyx.IN_CLOSE_WRITE) # Execute a network event so the IP is shown execute_task_event("network") # Delete old stop eventa and execute others... for f in os.listdir(system_event_dir): if f=="stop" or f=="shutdown": steelsquid_utils.deleteFileOrFolder(system_event_dir+"/"+f) else: read_task_event(f) # Listen for events try: while running: events = inotifyx.get_events(fd) for event in events: read_task_event(event.name) except KeyboardInterrupt: pass os.close(fd) _cleanup() # Delete old eventa for f in os.listdir(system_event_dir): steelsquid_utils.deleteFileOrFolder(system_event_dir+"/"+f) # Broadcast the event else: if len(sys.argv)>2: broadcast_task_event(command, sys.argv[2:]) else: broadcast_task_event(command) except: steelsquid_utils.shout("Fatal error when on boot steelsquid service", is_error=True) os._exit(0)
def __init__ (self): self.fd = inotifyx.init() self.wd = self._add (vmbase) self.paths = {}
def watch_dhcp_leases(path): """ This is a generator for events that happen to the file at the given path. It assumes ISC DHCPD -like behavior; that is, ISC dhcpd man page dhcpd.leases(5) promises that the leases file is only updated in exactly two ways: 1. new entries are appended 2. a new (pruned) lease file is renamed to the monitored filename (the old file is first moved out of the way, but that's not relevant here) So we trigger events on appends and lease file replacement, and start monitoring the new file on the latter. Example:: for _ in watch('/var/lib/dhcp/dhcpd.leases'): print "Stuff happened!" """ fd = inotifyx.init() parent = os.path.dirname(path) if parent == "": # this happens if path had no slashes in it; mostly when # testing manually parent = "." try: wd_new = inotifyx.add_watch(fd, parent, inotifyx.IN_MOVED_TO | inotifyx.IN_ONLYDIR) while True: # the only real reason for `path` not to exist here is on # first loop (assuming dhcpd behavior); `replaced` only # becomes True after a file is renamed to this name, so # there's no race there (barring un-dhcpd like behavior # like deleting the file) wd_journal = inotifyx.add_watch(fd, path, inotifyx.IN_MODIFY) # yield once in order to 1) make caller read the existing # content of the file and 2) make writing unit tests # easier; now we already have an open inotify fd with the # right watches yield None replaced = False while not replaced: for e in inotifyx.get_events(fd): if e.mask & inotifyx.IN_Q_OVERFLOW: yield e # we could have lost an IN_MOVED_TO event, # do this just in case replaced = True elif e.wd == wd_journal: yield e elif e.wd == wd_new and e.mask & inotifyx.IN_MOVED_TO and e.name == os.path.basename(path): # the old watch is implicitly removed as the # file is deleted, no need to clean that up; # not 100% sure if this will leak wds or not replaced = True finally: os.close(fd)
def xzCompress(inputFile, outputFile): # Compresses a file, that may be actively written to, with xz. # Returns the file name on success, or None on failure # command uses custom streaming build of xz xzCommand = "export LD_LIBRARY_PATH=/usr/local/lib; /usr/local/bin/xz2 -z1 > %s" % (outputFile) # xzCommand = "/usr/local/bin/xz -z1 | pv -B 1024 -L 100 > %s" % (outputFile) IN_WATCH_EVENTS = inotifyx.IN_MODIFY try: # Sets up the main inotify watcher fd = inotifyx.init() watcher = inotifyx.add_watch(fd, inputFile, IN_WATCH_EVENTS) with io.open(inputFile, mode='r+b') as fileStream: # Loop until no more data try: xzp = subprocess.Popen( xzCommand, stdin=subprocess.PIPE, shell=True, close_fds=False, preexec_fn=subprocessSetup) # Counter for retrys trycount = 0 while 1: # Main loop which reads the file and writes to xz stdin data = fileStream.read(1024000) current = False # Assume reading a normal file until we get to the end if len(data) == 0: current = currentFile(inputFile, fd) if not current: # Reached EOF, check next file exists sleep(0.1) # Prevent race condition if nextFile(inputFile) is not None: logger.debug("Breaking, next file exists!") break trycount += 1 logger.debug("Waiting for next file or more data.." + str(trycount)) sleep(1) logger.debug("Writing %s" % len(data)) xzp.stdin.write(data) if current: # Reduce looping, wait a bit for more data sleep(0.5) except(KeyboardInterrupt, SystemExit): raise finally: xzp.stdin.flush() xzp.stdin.close() position = fileStream.tell() inotifyx.rm_watch(fd, watcher) finally: os.close(fd) # Get return code xzp.wait() if xzp.returncode is not 0: logger.error("xz gave non-zero exit status") return None # logger.debug("xz return code: %s" % (returnCode)) # Check new compressed file exists (before this we don't *actually* know # it does because it's a shell redirect) try: with open(outputFile): pass except IOError: logger.error("Failed to create xz file") return None return (outputFile, position)
def __init__(self, polling=False, **params): self._params = params self._mode_map = dict((val, nam) for nam, val in globals().items() if nam.startswith('WF_')) # Set up the access mode. If select.kqueue() is callable, WF_KQUEUE # mode will be used, otherwise polling will be used. The get_mode() # method supplies read-only access to th attribute. The value is not # settable after the class is instantiated. # if polling: self._mode = WF_POLLING elif wf_inotifyx_available: self._mode = WF_INOTIFYX elif 'kqueue' in dir(select) and callable(select.kqueue): self._mode = WF_KQUEUE else: self._mode = WF_POLLING # Holds all paths that have been added, whether actually being watched or not. self.paths = {} # Holds paths that have been opened and are being watched # self.paths_open = {} # Holds paths where "missing" was True and the path could not be opened. # self.paths_pending = {} # Associates all open file descriptors and the opened path # self.fds_open = {} # Provided to caller to observe the last set of changes. The # value of the dict is the time the change was noted. # self.last_changes = {} self._discard = logging.getLogger(__name__) self._discard.addHandler(logging.NullHandler()) self.unprocessed_event = None if self._mode == WF_KQUEUE: # Immediately create a kernel event queue so that an immediate # call to fileno() will return the correct controlling fd. # self._kq = select.kqueue() elif self._mode == WF_INOTIFYX: # Immediately create an inotifyx channel identified by a # file descriptor. # self._inx_fd = inotifyx.init() # This is the standard mask used for watches. It is setup # to only trigger events when somethingn changes. # self._inx_mask = inotifyx.IN_ALL_EVENTS & ~(inotifyx.IN_ACCESS | inotifyx.IN_CLOSE | inotifyx.IN_OPEN) # Record inode of watched paths to work around simfs bug # self._inx_inode = {} elif self._mode == WF_POLLING: self._self_pipe() self._poll_stat = {} # Holds paths that were removed or renamed until get() is # called. # self._poll_pending = {}
def __init__(self): self._fd = inotifyx.init() self._watches = {} self._starts = {} syslog.openlog(b"InotifyWatcher")