]> gitweb.maison.local Git - horusd.git/commitdiff
Added : inotify survey of /tmp (only remove working ...)
authorlionel <lionel@stargate.enneade.fdn.org>
Fri, 22 Jan 2016 12:50:20 +0000 (13:50 +0100)
committerlionel <lionel@stargate.enneade.fdn.org>
Fri, 22 Jan 2016 12:50:20 +0000 (13:50 +0100)
horusd.py
test.py [new file with mode: 0755]

index 56e7e44c4ab314e63e3fe98980c21079851bb39f..8f794bd6da9a10798749c251c6049b5dc51a649d 100755 (executable)
--- a/horusd.py
+++ b/horusd.py
@@ -4,11 +4,14 @@
 import logging                  # Logs
 import time                     # sleep
 import string                   # split strings
-#import python-daemon
+import os,select
 
 from daemon import runner      # daemonization
 
-#from multiprocessing import Process
+from inotifyx import binding
+from inotifyx.distinfo import version as __version__
+
+from multiprocessing import Process
 #import subprocess
 #import shlex
 
@@ -21,36 +24,146 @@ class App():
 
   def __init__(self):
     self.stdin_path = "/dev/null"
-    self.stdout_path = "/home/lionel/work/python/horusd/stdout.log"
-    self.stderr_path = "/home/lionel/work/python/horusd/stderr.log"
-    self.pidfile_path = "/home/lionel/work/python/horusd/horusd.pid"
+    self.stdout_path = "/home/lionel/work/python/horusd/log/stdout.log"
+    self.stderr_path = "/home/lionel/work/python/horusd/log/stderr.log"
+    self.pidfile_path = "/home/lionel/work/python/horusd/pid/horusd.pid"
     self.pidfile_timeout = 5
 
   def run(self):
-    if __name__ == '__main__':
-# All functions definitions took place above
+# We must put all functions before the 'if __name__ blabla'
 
-      logger.info("horusd started")
+# The inotify class :
+    class InotifyEvent(object):
+      '''
+      InotifyEvent(wd, mask, cookie, name)
+      A representation of the inotify_event structure.  See the inotify
+      documentation for a description of these fields.
+      '''
+
+      wd = None
+      mask = None
+      cookie = None
+      name = None
+
+      def __init__(self, wd, mask, cookie, name):
+        self.wd = wd
+        self.mask = mask
+        self.cookie = cookie
+        self.name = name
+
+      def __str__(self):
+        return '%s: %s' % (self.wd, self.get_mask_description())
+
+      def __repr__(self):
+        return '%s(%s, %s, %s, %s)' % (
+          self.__class__.__name__,
+          repr(self.wd),
+          repr(self.mask),
+          repr(self.cookie),
+          repr(self.name),
+          )
+
+      def get_mask_description(self):
+        '''
+        Return an ASCII string describing the mask field in terms of
+        bitwise-or'd IN_* constants, or 0.  The result is valid Python code
+        that could be eval'd to get the value of the mask field.  In other
+        words, for a given event:
+
+        >>> from inotifyx import *
+        >>> assert (event.mask == eval(event.get_mask_description()))
+        '''
+
+        parts = []
+        for name, value in constants.items():
+          if self.mask & value:
+            parts.append(name)
+          if parts:
+            return '|'.join(parts)
+          return '0'
+
+    def get_events(fd, *args):
+      '''
+      get_events(fd[, timeout])
+
+      Return a list of InotifyEvent instances representing events read from
+      inotify.  If timeout is None, this will block forever until at least one
+      event can be read.  Otherwise, timeout should be an integer or float
+      specifying a timeout in seconds.  If get_events times out waiting for
+      events, an empty list will be returned.  If timeout is zero, get_events
+      will not block.
+      '''
+      return [
+        InotifyEvent(wd, mask, cookie, name)
+        for wd, mask, cookie, name in binding.get_events(fd, *args)
+      ]
 
-## Begin the infinit loop by polling signals values
-      loop_counter = 0
+    def heartbeat(min):
+      seconds = int(min) * 60
       while True:
-        time.sleep(2)
-        loop_counter=loop_counter+1
-# Every 300 loops (around 600s/10min on normal conditions),
-# we write informations to the log file and verify power unit keep alive.
-        if (loop_counter) == 3:
-          logger.info("Still Alive.")
-          loop_counter = 0
+        logger.info("HB : alive")
+        time.sleep(seconds)
+      return False
 
 
+# All functions definitions took place above
+    if __name__ == '__main__':
+      logger.info("horusd started")
+
+      '''
+      Launching the heartbeat function
+      '''
+      p = Process(target=heartbeat, args=(2,))
+      p.start()
+      heartbeat_pid = p.pid
+      logger.info("heartbeat loop launched (pid " + str(heartbeat_pid) + ")")
+
+      '''
+      Preparing main loop
+      '''
+      constants = {}
+
+      for name in dir(binding):
+        if name.startswith('IN_CREATE') or name.startswith('IN_DELETE'):
+          globals()[name] = constants[name] = getattr(binding, name)
+
+      init = binding.init
+      rm_watch = binding.rm_watch
+      add_watch = binding.add_watch
+
+      '''
+      Entering infinite loop
+      '''
+
+      path = "/tmp"
+      fd = init()
+      wd_to_path = {}
+
+      wd = add_watch(fd, path)
+      wd_to_path[wd] = path
+
+      try:
+        while True:
+          events = get_events(fd)
+          for event in events:
+            path = wd_to_path[event.wd]
+            parts = [event.get_mask_description()]
+            if event.name:
+              parts.append(event.name)
+            logger.debug("parts[] == " + str(parts))
+            if parts[0][0:3] == "IN_":
+              logger.info('%s: %s' % (path, ' '.join(parts)))
+      except:
+        logger.error("While loop interrupted : aborting")
+        os.close(fd)
+        # Faut arrêter les Process ...
+
 # Invocation of the daemon part
 # Means : if it's working : DON'T TOUCH ANYTHING
 if __name__ == "__main__":
-
   app = App()
   logger = logging.getLogger("horusd")
-  loglevel = "info"
+  loglevel = "debug"
   if (loglevel=="DEBUG") or (loglevel=="debug"):
     logger.setLevel(logging.DEBUG)
   elif (loglevel=="INFO") or (loglevel=="info"):
@@ -62,7 +175,7 @@ if __name__ == "__main__":
   else:
     logger.setLevel(logging.DEBUG)
   formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s")
-  handler = logging.FileHandler("horusd.log")
+  handler = logging.FileHandler("log/horusd.log")
   handler.setFormatter(formatter)
   logger.addHandler(handler)
 
diff --git a/test.py b/test.py
new file mode 100755 (executable)
index 0000000..0a2006f
--- /dev/null
+++ b/test.py
@@ -0,0 +1,112 @@
+#!/usr/bin/python2.7
+# -*- coding:Utf-8 -*-
+import os, select
+
+from inotifyx import binding
+from inotifyx.distinfo import version as __version__
+
+
+constants = {}
+
+for name in dir(binding):
+    if name.startswith('IN_CREATE') or name.startswith('IN_DELETE'):
+        globals()[name] = constants[name] = getattr(binding, name)
+
+
+init = binding.init
+rm_watch = binding.rm_watch
+add_watch = binding.add_watch
+
+
+class InotifyEvent(object):
+  '''
+    InotifyEvent(wd, mask, cookie, name)
+
+    A representation of the inotify_event structure.  See the inotify
+    documentation for a description of these fields.
+  '''
+
+  wd = None
+  mask = None
+  cookie = None
+  name = None
+
+  def __init__(self, wd, mask, cookie, name):
+    self.wd = wd
+    self.mask = mask
+    self.cookie = cookie
+    self.name = name
+
+  def __str__(self):
+    return '%s: %s' % (self.wd, self.get_mask_description())
+
+  def __repr__(self):
+    return '%s(%s, %s, %s, %s)' % (
+      self.__class__.__name__,
+      repr(self.wd),
+      repr(self.mask),
+      repr(self.cookie),
+      repr(self.name),
+      )
+
+  def get_mask_description(self):
+    '''
+        Return an ASCII string describing the mask field in terms of
+        bitwise-or'd IN_* constants, or 0.  The result is valid Python code
+        that could be eval'd to get the value of the mask field.  In other
+        words, for a given event:
+
+        >>> from inotifyx import *
+        >>> assert (event.mask == eval(event.get_mask_description()))
+    '''
+    parts = []
+    for name, value in constants.items():
+      if self.mask & value:
+        parts.append(name)
+        if parts:
+          return '|'.join(parts)
+    return '0'
+
+
+def get_events(fd, *args):
+  '''
+    get_events(fd[, timeout])
+
+    Return a list of InotifyEvent instances representing events read from
+    inotify.  If timeout is None, this will block forever until at least one
+    event can be read.  Otherwise, timeout should be an integer or float
+    specifying a timeout in seconds.  If get_events times out waiting for
+    events, an empty list will be returned.  If timeout is zero, get_events
+    will not block.
+  '''
+  return [
+    InotifyEvent(wd, mask, cookie, name)
+    for wd, mask, cookie, name in binding.get_events(fd, *args)
+  ]
+
+
+if __name__ == '__main__':
+    import sys
+
+    path = "/tmp"
+    fd = init()
+    wd_to_path = {}
+
+    wd = add_watch(fd, path)
+    wd_to_path[wd] = path
+
+    try:
+        while True:
+            events = get_events(fd)
+            for event in events:
+                path = wd_to_path[event.wd]
+                parts = [event.get_mask_description()]
+                if event.name:
+                    parts.append(event.name)
+                if parts[0][0:3] == "IN_":
+                    print '%s: %s' % (path, ' '.join(parts))
+    except KeyboardInterrupt:
+        pass
+
+    finally:
+        os.close(fd)