diff --git a/fail2ban/server/observer.py b/fail2ban/server/observer.py index 443c6ac6..14233c55 100644 --- a/fail2ban/server/observer.py +++ b/fail2ban/server/observer.py @@ -413,7 +413,7 @@ class ObserverThread(JailThread): """ # check jail active : if not jail.isAlive() or not jail.database: - return + return banTime be = jail.getBanTimeExtra() ip = ticket.getIP() orgBanTime = banTime diff --git a/fail2ban/server/server.py b/fail2ban/server/server.py index c77246d2..3654ea6e 100644 --- a/fail2ban/server/server.py +++ b/fail2ban/server/server.py @@ -172,6 +172,10 @@ class Server: logSys.info("Exiting Fail2ban") def quit(self): + # Give observer a small chance to complete its work before exit + if Observers.Main is not None: + Observers.Main.stop() + # Stop communication first because if jail's unban action # tries to communicate via fail2ban-client we get a lockup # among threads. So the simplest resolution is to stop all diff --git a/fail2ban/tests/fail2banclienttestcase.py b/fail2ban/tests/fail2banclienttestcase.py index b8417be5..c31269bb 100644 --- a/fail2ban/tests/fail2banclienttestcase.py +++ b/fail2ban/tests/fail2banclienttestcase.py @@ -81,6 +81,14 @@ fail2banserver.output = \ protocol.output = _test_output +Observers = server.Observers + +def _observer_wait_idle(): + """Helper to wait observer becomes idle""" + if Observers.Main is not None: + Observers.Main.wait_empty(MID_WAITTIME) + Observers.Main.wait_idle(MID_WAITTIME / 5) + # # Mocking .exit so we could test its correct operation. # Two custom exceptions will be assessed to be raised in the tests @@ -934,6 +942,8 @@ class Fail2banServerTest(Fail2banClientServerBase): "[test-jail2] Found 192.0.2.3", "[test-jail2] Ban 192.0.2.3", all=True) + # if observer available wait for it becomes idle (write all tickets to db): + _observer_wait_idle() # rotate logs: _write_file(test1log, "w+")