Fix exit of subprocess in case it was terminated by signal
If child process of rootwrap is terminated by signal, exit code should be 128 + N, where N is number of signal. According [1] subprocess.Popen.returncode returns -N. sys.exit interprets negative signed byte as unsigned thus original exit code is 256 - N instead of 128 + N. [1] https://docs.python.org/2/library/subprocess.html#subprocess.Popen.returncode Change-Id: I43b4c959a98f8f620466c77de4cd5b724b09e5a8 Closes-Bug: #1364822
This commit is contained in:
parent
aaf1869cc4
commit
56e9cb5b07
@ -44,6 +44,7 @@ RC_UNAUTHORIZED = 99
|
||||
RC_NOCOMMAND = 98
|
||||
RC_BADCONFIG = 97
|
||||
RC_NOEXECFOUND = 96
|
||||
SIGNAL_BASE = 128
|
||||
|
||||
|
||||
def _exit_error(execname, message, errorcode, log=True):
|
||||
@ -106,8 +107,11 @@ def run_one_command(execname, config, filters, userargs):
|
||||
stdin=sys.stdin,
|
||||
stdout=sys.stdout,
|
||||
stderr=sys.stderr)
|
||||
obj.wait()
|
||||
sys.exit(obj.returncode)
|
||||
returncode = obj.wait()
|
||||
# Fix returncode of Popen
|
||||
if returncode < 0:
|
||||
returncode = SIGNAL_BASE - returncode
|
||||
sys.exit(returncode)
|
||||
|
||||
except wrapper.FilterMatchNotExecutable as exc:
|
||||
msg = ("Executable not found: %s (filter match = %s)"
|
||||
|
@ -23,6 +23,7 @@ import mock
|
||||
from six import moves
|
||||
import testtools
|
||||
|
||||
from oslo.rootwrap import cmd
|
||||
from oslo.rootwrap import filters
|
||||
from oslo.rootwrap import wrapper
|
||||
|
||||
@ -567,3 +568,18 @@ class PathFilterTestCase(testtools.TestCase):
|
||||
os.path.realpath(self.TRAVERSAL_SYMLINK_WITHIN_DIR)]
|
||||
|
||||
self.assertEqual(expected, self.f.get_command(args))
|
||||
|
||||
|
||||
class RunOneCommandTestCase(testtools.TestCase):
|
||||
def _test_returncode_helper(self, returncode, expected):
|
||||
with mock.patch.object(wrapper, 'start_subprocess') as mock_start:
|
||||
with mock.patch('sys.exit') as mock_exit:
|
||||
mock_start.return_value.wait.return_value = returncode
|
||||
cmd.run_one_command(None, mock.Mock(), None, None)
|
||||
mock_exit.assert_called_once_with(expected)
|
||||
|
||||
def test_positive_returncode(self):
|
||||
self._test_returncode_helper(1, 1)
|
||||
|
||||
def test_negative_returncode(self):
|
||||
self._test_returncode_helper(-1, 129)
|
||||
|
Loading…
x
Reference in New Issue
Block a user