pmb.helpers.run_core: change kill_as_root to sudo (MR 1997)

Replace the "kill_as_root" argument with a much simpler "sudo" argument
and remove the now obsolete check for the output mode of "kill_as_root".

"kill_as_root" would only get set to True if both conditions are met:
a) command is running with sudo
b) command is running with an output mode ("log" or "stdout") where
   pmb.helpers.run_core would kill it if it does not output anything
   before a timeout is reached

The new "sudo" argument just indicates if the command is running with
sudo (a), regardless of the output mode (b).
This commit is contained in:
Johannes Marbach 2020-12-09 19:41:12 +01:00
parent 27127f1cae
commit 8842a7d5c0
No known key found for this signature in database
GPG key ID: 5AE7F5513E0885CB
5 changed files with 23 additions and 43 deletions

View file

@ -71,6 +71,5 @@ def root(args, cmd, suffix="native", working_dir="/", output="log",
pmb.helpers.run.flat_cmd(cmd, working_dir)]
cmd_sudo = ["sudo", "env", "-i", executables["sh"], "-c",
pmb.helpers.run.flat_cmd(cmd_chroot, env=env_all)]
kill_as_root = output in ["log", "stdout"]
return pmb.helpers.run_core.core(args, msg, cmd_sudo, None, output,
output_return, check, kill_as_root, disable_timeout)
output_return, check, True, disable_timeout)

View file

@ -107,12 +107,6 @@ is_interactive = sys.stdout.isatty() and \
sys.stdin.isatty()
# pmbootstrap will kill programs which do not output anything for several
# minutes and have one of the following output types. See
# pmb.helpers.run_core.core() for more information.
run_outputs_with_timeout = ["log", "stdout"]
#
# CHROOT
#

View file

@ -34,7 +34,7 @@ def flat_cmd(cmd, working_dir=None, env={}):
def user(args, cmd, working_dir=None, output="log", output_return=False,
check=None, env={}, kill_as_root=False):
check=None, env={}, sudo=False):
"""
Run a command on the host system as user.
@ -56,7 +56,7 @@ def user(args, cmd, working_dir=None, output="log", output_return=False,
if env:
cmd = ["sh", "-c", flat_cmd(cmd, env=env)]
return pmb.helpers.run_core.core(args, msg, cmd, working_dir, output,
output_return, check, kill_as_root)
output_return, check, sudo)
def root(args, cmd, working_dir=None, output="log", output_return=False,
@ -74,8 +74,5 @@ def root(args, cmd, working_dir=None, output="log", output_return=False,
cmd = ["sh", "-c", flat_cmd(cmd, env=env)]
cmd = ["sudo"] + cmd
# pmbootstrap shall use 'sudo kill' to get rid of timed out programs
kill_as_root = output in pmb.config.run_outputs_with_timeout or None
return user(args, cmd, working_dir, output, output_return, check, env,
kill_as_root)
True)

View file

@ -14,8 +14,7 @@ import pmb.helpers.run
called by core(). """
def sanity_checks(output="log", output_return=False, check=None,
kill_as_root=False):
def sanity_checks(output="log", output_return=False, check=None):
"""
Raise an exception if the parameters passed to core() don't make sense
(all parameters are described in core() below).
@ -33,9 +32,6 @@ def sanity_checks(output="log", output_return=False, check=None,
if output_return and output in ["tui", "background"]:
raise RuntimeError("Can't use output_return with output: " + output)
if kill_as_root and output not in pmb.config.run_outputs_with_timeout:
raise RuntimeError("Can't use kill_as_root with output: " + output)
def background(args, cmd, working_dir=None):
""" Run a subprocess in background and redirect its output to the log. """
@ -85,15 +81,15 @@ def pipe_read(args, process, output_to_stdout=False, output_return=False,
return
def kill_process_tree(args, pid, ppids, kill_as_root):
def kill_process_tree(args, pid, ppids, sudo):
"""
Recursively kill a pid and its child processes
:param pid: process id that will be killed
:param ppids: list of process id and parent process id tuples (pid, ppid)
:param kill_as_root: use sudo to kill the process
:param sudo: use sudo to kill the process
"""
if kill_as_root:
if sudo:
pmb.helpers.run.root(args, ["kill", "-9", str(pid)],
check=False)
else:
@ -102,15 +98,15 @@ def kill_process_tree(args, pid, ppids, kill_as_root):
for (child_pid, child_ppid) in ppids:
if child_ppid == str(pid):
kill_process_tree(args, child_pid, ppids, kill_as_root)
kill_process_tree(args, child_pid, ppids, sudo)
def kill_command(args, pid, kill_as_root):
def kill_command(args, pid, sudo):
"""
Kill a command process and recursively kill its child processes
:param pid: process id that will be killed
:param kill_as_root: use sudo to kill the process
:param sudo: use sudo to kill the process
"""
cmd = ["ps", "-e", "-o", "pid=,ppid=", "--noheaders"]
ret = subprocess.run(cmd, check=True, stdout=subprocess.PIPE)
@ -122,12 +118,12 @@ def kill_command(args, pid, kill_as_root):
raise RuntimeError("Unexpected ps output: " + row)
ppids.append(items)
kill_process_tree(args, pid, ppids, kill_as_root)
kill_process_tree(args, pid, ppids, sudo)
def foreground_pipe(args, cmd, working_dir=None, output_to_stdout=False,
output_return=False, output_timeout=True,
kill_as_root=False):
sudo=False):
"""
Run a subprocess in foreground with redirected output and optionally kill
it after being silent for too long.
@ -139,7 +135,7 @@ def foreground_pipe(args, cmd, working_dir=None, output_to_stdout=False,
:param output_timeout: kill the process when it doesn't print any output
after a certain time (configured with --timeout)
and raise a RuntimeError exception
:param kill_as_root: use sudo to kill the process when it hits the timeout
:param sudo: use sudo to kill the process when it hits the timeout
:returns: (code, output)
* code: return code of the program
* output: ""
@ -173,7 +169,7 @@ def foreground_pipe(args, cmd, working_dir=None, output_to_stdout=False,
str(args.timeout) + " seconds. Killing it.")
logging.info("NOTE: The timeout can be increased with"
" 'pmbootstrap -t'.")
kill_command(args, process.pid, kill_as_root)
kill_command(args, process.pid, sudo)
continue
# Read all currently available output
@ -222,7 +218,7 @@ def check_return_code(args, code, log_message):
def core(args, log_message, cmd, working_dir=None, output="log",
output_return=False, check=None, kill_as_root=False, disable_timeout=False):
output_return=False, check=None, sudo=False, disable_timeout=False):
"""
Run a command and create a log entry.
@ -274,12 +270,12 @@ def core(args, log_message, cmd, working_dir=None, output="log",
is not 0. Set this to False to disable the check. This
parameter can not be used when the output is "background" or
"pipe".
:param kill_as_root: use sudo to kill the process when it hits the timeout.
:param sudo: use sudo to kill the process when it hits the timeout.
:returns: * program's return code (default)
* subprocess.Popen instance (output is "background" or "pipe")
* the program's entire output (output_return is True)
"""
sanity_checks(output, output_return, check, kill_as_root)
sanity_checks(output, output_return, check)
# Log simplified and full command (pmbootstrap -v)
logging.debug(log_message)
@ -304,13 +300,13 @@ def core(args, log_message, cmd, working_dir=None, output="log",
if not args.details_to_stdout and output in ["stdout", "interactive"]:
output_to_stdout = True
output_timeout = output in pmb.config.run_outputs_with_timeout \
and not disable_timeout
output_timeout = output in ["log", "stdout"] and not disable_timeout
(code, output_after_run) = foreground_pipe(args, cmd, working_dir,
output_to_stdout,
output_return,
output_timeout,
kill_as_root)
sudo)
# Check the return code
if check is not False:

View file

@ -41,12 +41,6 @@ def test_sanity_checks():
func("tui", output_return=True)
assert str(e.value).startswith("Can't use output_return with")
# kill_as_root
func("log", kill_as_root=True)
with pytest.raises(RuntimeError) as e:
func("tui", kill_as_root=True)
assert str(e.value).startswith("Can't use kill_as_root with")
def test_background(args):
# Sleep in background
@ -90,7 +84,7 @@ def test_foreground_pipe(args):
cmd = ["sudo", "sh", "-c", "printf first; sleep 2; printf second"]
args.timeout = 0.3
ret = func(args, cmd, output_return=True, output_timeout=True,
kill_as_root=True)
sudo=True)
assert ret == (-9, "first")
# Finish before timeout
@ -108,7 +102,7 @@ def test_foreground_pipe(args):
"sleep 10 | sleep 20 | sleep 30"]
args.timeout = 0.3
ret = func(args, cmd, output_return=True, output_timeout=True,
kill_as_root=True)
sudo=True)
pgid = str(ret[1])
cmd = ["ps", "-e", "-o", "pgid=,comm=", "--noheaders"]