repair typo bug in reloading for systemd-filter;

JailThread get method `join` for safe usage of it, also for not started threads (test-cases or in case of error), that will be used for cleanup resp. wait purposes also (see join of pyinotify-filter);
pull/1557/head
sebres 2016-09-22 18:56:21 +02:00
parent d153555a07
commit c0373a7158
8 changed files with 47 additions and 23 deletions

View File

@ -100,6 +100,10 @@ class Filter(JailThread):
def __repr__(self): def __repr__(self):
return "%s(%r)" % (self.__class__.__name__, self.jail) return "%s(%r)" % (self.__class__.__name__, self.jail)
@property
def jailName(self):
return (self.jail is not None and self.jail.name or "~jailless~")
def clearAllParams(self): def clearAllParams(self):
""" Clear all lists/dicts parameters (used by reloading) """ Clear all lists/dicts parameters (used by reloading)
""" """
@ -135,7 +139,7 @@ class Filter(JailThread):
if "\n" in regex.getRegex() and not self.getMaxLines() > 1: if "\n" in regex.getRegex() and not self.getMaxLines() > 1:
logSys.warning( logSys.warning(
"Mutliline regex set for jail %r " "Mutliline regex set for jail %r "
"but maxlines not greater than 1", self.jail.name) "but maxlines not greater than 1", self.jailName)
except RegexException as e: except RegexException as e:
logSys.error(e) logSys.error(e)
raise e raise e
@ -420,7 +424,7 @@ class Filter(JailThread):
def logIgnoreIp(self, ip, log_ignore, ignore_source="unknown source"): def logIgnoreIp(self, ip, log_ignore, ignore_source="unknown source"):
if log_ignore: if log_ignore:
logSys.info("[%s] Ignore %s by %s" % (self.jail.name, ip, ignore_source)) logSys.info("[%s] Ignore %s by %s" % (self.jailName, ip, ignore_source))
def getIgnoreIP(self): def getIgnoreIP(self):
return self.__ignoreIpList return self.__ignoreIpList
@ -491,7 +495,7 @@ class Filter(JailThread):
if self.inIgnoreIPList(ip, log_ignore=True): if self.inIgnoreIPList(ip, log_ignore=True):
continue continue
logSys.info( logSys.info(
"[%s] Found %s - %s", self.jail.name, ip, datetime.datetime.fromtimestamp(unixTime).strftime("%Y-%m-%d %H:%M:%S") "[%s] Found %s - %s", self.jailName, ip, datetime.datetime.fromtimestamp(unixTime).strftime("%Y-%m-%d %H:%M:%S")
) )
tick = FailTicket(ip, unixTime, lines, data=fail) tick = FailTicket(ip, unixTime, lines, data=fail)
self.failManager.addFailure(tick) self.failManager.addFailure(tick)

View File

@ -132,7 +132,7 @@ class FilterGamin(FileFilter):
Utils.wait_for(lambda: not self.active or self._handleEvents(), Utils.wait_for(lambda: not self.active or self._handleEvents(),
self.sleeptime) self.sleeptime)
self.ticks += 1 self.ticks += 1
logSys.debug(self.jail.name + ": filter terminated") logSys.debug("[%s] filter terminated", self.jailName)
return True return True
def stop(self): def stop(self):

View File

@ -123,9 +123,7 @@ class FilterPoll(FileFilter):
except FailManagerEmpty: except FailManagerEmpty:
self.failManager.cleanup(MyTime.time()) self.failManager.cleanup(MyTime.time())
self.__modified = False self.__modified = False
logSys.debug( logSys.debug("[%s] filter terminated", self.jailName)
(self.jail is not None and self.jail.name or "jailless") +
" filter terminated")
return True return True
## ##

View File

@ -198,7 +198,7 @@ class FilterPyinotify(FileFilter):
prcevent, timeout=self.sleeptime) prcevent, timeout=self.sleeptime)
self.__notifier.check_events = self.__check_events self.__notifier.check_events = self.__check_events
self.__notifier.start() self.__notifier.start()
logSys.debug("pyinotifier started for %s.", self.jail.name) logSys.debug("[%s] filter started (pyinotifier)", self.jailName)
return True return True
## ##
@ -206,15 +206,22 @@ class FilterPyinotify(FileFilter):
def stop(self): def stop(self):
super(FilterPyinotify, self).stop() super(FilterPyinotify, self).stop()
# Stop the notifier thread # Stop the notifier thread
self.__notifier.stop() self.__notifier.stop()
self.__notifier.join() # to not exit before notifier does
self.__cleanup() # for pedantic ones ##
# Wait for exit with cleanup.
def join(self):
self.__cleanup()
super(FilterPyinotify, self).join()
logSys.debug("[%s] filter terminated (pyinotifier)", self.jailName)
## ##
# Deallocates the resources used by pyinotify. # Deallocates the resources used by pyinotify.
def __cleanup(self): def __cleanup(self):
self.__notifier = None if self.__notifier:
self.__notifier.join() # to not exit before notifier does
self.__notifier = None
self.__monitor = None self.__monitor = None

View File

@ -130,7 +130,8 @@ class FilterSystemd(JournalFilter): # pragma: systemd no cover
self.resetJournalMatches() self.resetJournalMatches()
raise raise
else: else:
logSys.info("Added journal match for: %r", " ".join(match)) logSys.info("[%s] Added journal match for: %r", self.jailName,
" ".join(match))
## ##
# Reset a journal match filter called on removal or failure # Reset a journal match filter called on removal or failure
# #
@ -138,7 +139,7 @@ class FilterSystemd(JournalFilter): # pragma: systemd no cover
def resetJournalMatches(self): def resetJournalMatches(self):
self.__journal.flush_matches() self.__journal.flush_matches()
logSys.debug("Flushed all journal matches") logSys.debug("[%s] Flushed all journal matches", self.jailName)
match_copy = self.__matches[:] match_copy = self.__matches[:]
self.__matches = [] self.__matches = []
try: try:
@ -157,14 +158,17 @@ class FilterSystemd(JournalFilter): # pragma: systemd no cover
def delJournalMatch(self, match=None): def delJournalMatch(self, match=None):
# clear all: # clear all:
if match is None: if match is None:
if not self.__matches:
return
del self.__matches[:] del self.__matches[:]
# delete by index: # delete by index:
elif match in self.__matches: elif match in self.__matches:
del self.__matches[self.__matches.index(match)] del self.__matches[self.__matches.index(match)]
else: else:
raise ValueError("Match not found") raise ValueError("Match %r not found" % match)
self.resetJournalMatches() self.resetJournalMatches()
logSys.info("Removed journal match for: %r" % " ".join(match)) logSys.info("[%s] Removed journal match for: %r", self.jailName,
match if match else '*')
## ##
# Get current journal match filter # Get current journal match filter
@ -214,8 +218,8 @@ class FilterSystemd(JournalFilter): # pragma: systemd no cover
date = logentry.get('_SOURCE_REALTIME_TIMESTAMP', date = logentry.get('_SOURCE_REALTIME_TIMESTAMP',
logentry.get('__REALTIME_TIMESTAMP')) logentry.get('__REALTIME_TIMESTAMP'))
logSys.debug("Read systemd journal entry: %r" % logSys.debug("[%s] Read systemd journal entry: %s %s", self.jailName,
"".join([date.isoformat(), logline])) date.isoformat(), logline)
## use the same type for 1st argument: ## use the same type for 1st argument:
return ((logline[:0], date.isoformat(), logline), return ((logline[:0], date.isoformat(), logline),
time.mktime(date.timetuple()) + date.microsecond/1.0E6) time.mktime(date.timetuple()) + date.microsecond/1.0E6)
@ -302,6 +306,7 @@ class FilterSystemd(JournalFilter): # pragma: systemd no cover
# incr common error counter: # incr common error counter:
self.commonError() self.commonError()
logSys.debug("[%s] filter terminated", self.jailName)
# close journal: # close journal:
try: try:
if self.__journal: if self.__journal:

View File

@ -257,8 +257,7 @@ class Jail(object):
obj.stop() obj.stop()
## wait for end of threads: ## wait for end of threads:
if join: if join:
if obj.isAlive(): obj.join()
obj.join()
except Exception as e: except Exception as e:
logSys.error("Stop %r of jail %r failed: %s", obj, self.name, e, logSys.error("Stop %r of jail %r failed: %s", obj, self.name, e,
exc_info=logSys.getEffectiveLevel()<=logging.DEBUG) exc_info=logSys.getEffectiveLevel()<=logging.DEBUG)

View File

@ -53,8 +53,8 @@ class JailThread(Thread):
super(JailThread, self).__init__(name=name) super(JailThread, self).__init__(name=name)
## Should going with main thread also: ## Should going with main thread also:
self.daemon = True self.daemon = True
## Control the state of the thread. ## Control the state of the thread (None - was not started, True - active, False - stopped).
self.active = False self.active = None
## Control the idle state of the thread. ## Control the idle state of the thread.
self.idle = False self.idle = False
## The time the thread sleeps in the loop. ## The time the thread sleeps in the loop.
@ -93,3 +93,14 @@ class JailThread(Thread):
"""Abstract - Called when thread starts, thread stops when returns. """Abstract - Called when thread starts, thread stops when returns.
""" """
pass pass
def join(self):
""" Safer join, that could be called also for not started (or ended) threads (used for cleanup).
"""
## if cleanup needed - create derivate and call it before join...
## if was really started - should call join:
if self.active is not None:
super(JailThread, self).join()

View File

@ -102,7 +102,7 @@ class Transmitter:
self.__commandHandler(cmd) self.__commandHandler(cmd)
finally: finally:
self.__server.reloadJails(*opts, begin=False) self.__server.reloadJails(*opts, begin=False)
return None return 'OK'
elif len(command) >= 2 and command[0] == "unban": elif len(command) >= 2 and command[0] == "unban":
# unban in all jails: # unban in all jails:
value = command[1:] value = command[1:]