BF+RF: only return bool status on failed commands execution + mitigate different exit codes between bash/dash

Closes #1155
pull/1187/head
Yaroslav Halchenko 2015-09-12 19:39:44 -04:00
parent 85b298e49c
commit 7cbb3980eb
2 changed files with 13 additions and 13 deletions

View File

@ -561,6 +561,7 @@ class CommandAction(ActionBase):
_cmd_lock.acquire() _cmd_lock.acquire()
try: try:
retcode = None # to guarantee being defined upon early except
stdout = tempfile.TemporaryFile(suffix=".stdout", prefix="fai2ban_") stdout = tempfile.TemporaryFile(suffix=".stdout", prefix="fai2ban_")
stderr = tempfile.TemporaryFile(suffix=".stderr", prefix="fai2ban_") stderr = tempfile.TemporaryFile(suffix=".stderr", prefix="fai2ban_")
@ -603,15 +604,16 @@ class CommandAction(ActionBase):
return True return True
elif retcode is None: elif retcode is None:
logSys.error("%s -- unable to kill PID %i" % (realCmd, popen.pid)) logSys.error("%s -- unable to kill PID %i" % (realCmd, popen.pid))
elif retcode < 0: elif retcode < 0 or retcode > 128:
logSys.error("%s -- killed with %s" % # dash would return negative while bash 128 + n
(realCmd, signame.get(-retcode, "signal %i" % -retcode))) sigcode = -retcode if retcode < 0 else retcode - 128
logSys.error("%s -- killed with %s (return code: %s)" %
(realCmd, signame.get(sigcode, "signal %i" % sigcode), retcode))
else: else:
msg = _RETCODE_HINTS.get(retcode, None) msg = _RETCODE_HINTS.get(retcode, None)
logSys.error("%s -- returned %i" % (realCmd, retcode)) logSys.error("%s -- returned %i" % (realCmd, retcode))
if msg: if msg:
logSys.info("HINT on %i: %s" logSys.info("HINT on %i: %s"
% (retcode, msg % locals())) % (retcode, msg % locals()))
return False return False
raise RuntimeError("Command execution failed: %s" % realCmd)

View File

@ -196,8 +196,7 @@ class CommandActionTest(LogCaptureTestCase):
def testExecuteTimeout(self): def testExecuteTimeout(self):
stime = time.time() stime = time.time()
# Should take a minute # Should take a minute
self.assertRaises( self.assertFalse(CommandAction.executeCmd('sleep 60', timeout=2))
RuntimeError, CommandAction.executeCmd, 'sleep 60', timeout=2)
# give a test still 1 second, because system could be too busy # give a test still 1 second, because system could be too busy
self.assertTrue(time.time() >= stime + 2 and time.time() <= stime + 3) self.assertTrue(time.time() >= stime + 2 and time.time() <= stime + 3)
self.assertTrue(self._is_logged('sleep 60 -- timed out after 2 seconds') self.assertTrue(self._is_logged('sleep 60 -- timed out after 2 seconds')
@ -222,17 +221,16 @@ class CommandActionTest(LogCaptureTestCase):
return int(f.read()) return int(f.read())
# First test if can kill the bastard # First test if can kill the bastard
self.assertRaises( self.assertFalse(CommandAction.executeCmd(
RuntimeError, CommandAction.executeCmd, 'bash %s' % tmpFilename, timeout=.1) 'bash %s' % tmpFilename, timeout=.1))
# Verify that the proccess itself got killed # Verify that the proccess itself got killed
self.assertFalse(pid_exists(getnastypid())) # process should have been killed self.assertFalse(pid_exists(getnastypid())) # process should have been killed
self.assertTrue(self._is_logged('timed out')) self.assertTrue(self._is_logged('timed out'))
self.assertTrue(self._is_logged('killed with SIGTERM')) self.assertTrue(self._is_logged('killed with SIGTERM'))
# A bit evolved case even though, previous test already tests killing children processes # A bit evolved case even though, previous test already tests killing children processes
self.assertRaises( self.assertFalse(CommandAction.executeCmd(
RuntimeError, CommandAction.executeCmd, 'out=`bash %s`; echo ALRIGHT' % tmpFilename, 'out=`bash %s`; echo ALRIGHT' % tmpFilename, timeout=.2))
timeout=.2)
# Verify that the proccess itself got killed # Verify that the proccess itself got killed
self.assertFalse(pid_exists(getnastypid())) self.assertFalse(pid_exists(getnastypid()))
self.assertTrue(self._is_logged('timed out')) self.assertTrue(self._is_logged('timed out'))