forked from Mirror/pmbootstrap
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:
parent
27127f1cae
commit
8842a7d5c0
5 changed files with 23 additions and 43 deletions
|
@ -71,6 +71,5 @@ def root(args, cmd, suffix="native", working_dir="/", output="log",
|
||||||
pmb.helpers.run.flat_cmd(cmd, working_dir)]
|
pmb.helpers.run.flat_cmd(cmd, working_dir)]
|
||||||
cmd_sudo = ["sudo", "env", "-i", executables["sh"], "-c",
|
cmd_sudo = ["sudo", "env", "-i", executables["sh"], "-c",
|
||||||
pmb.helpers.run.flat_cmd(cmd_chroot, env=env_all)]
|
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,
|
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)
|
||||||
|
|
|
@ -107,12 +107,6 @@ is_interactive = sys.stdout.isatty() and \
|
||||||
sys.stdin.isatty()
|
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
|
# CHROOT
|
||||||
#
|
#
|
||||||
|
|
|
@ -34,7 +34,7 @@ def flat_cmd(cmd, working_dir=None, env={}):
|
||||||
|
|
||||||
|
|
||||||
def user(args, cmd, working_dir=None, output="log", output_return=False,
|
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.
|
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:
|
if env:
|
||||||
cmd = ["sh", "-c", flat_cmd(cmd, env=env)]
|
cmd = ["sh", "-c", flat_cmd(cmd, env=env)]
|
||||||
return pmb.helpers.run_core.core(args, msg, cmd, working_dir, output,
|
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,
|
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 = ["sh", "-c", flat_cmd(cmd, env=env)]
|
||||||
cmd = ["sudo"] + cmd
|
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,
|
return user(args, cmd, working_dir, output, output_return, check, env,
|
||||||
kill_as_root)
|
True)
|
||||||
|
|
|
@ -14,8 +14,7 @@ import pmb.helpers.run
|
||||||
called by core(). """
|
called by core(). """
|
||||||
|
|
||||||
|
|
||||||
def sanity_checks(output="log", output_return=False, check=None,
|
def sanity_checks(output="log", output_return=False, check=None):
|
||||||
kill_as_root=False):
|
|
||||||
"""
|
"""
|
||||||
Raise an exception if the parameters passed to core() don't make sense
|
Raise an exception if the parameters passed to core() don't make sense
|
||||||
(all parameters are described in core() below).
|
(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"]:
|
if output_return and output in ["tui", "background"]:
|
||||||
raise RuntimeError("Can't use output_return with output: " + output)
|
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):
|
def background(args, cmd, working_dir=None):
|
||||||
""" Run a subprocess in background and redirect its output to the log. """
|
""" 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
|
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
|
Recursively kill a pid and its child processes
|
||||||
|
|
||||||
:param pid: process id that will be killed
|
:param pid: process id that will be killed
|
||||||
:param ppids: list of process id and parent process id tuples (pid, ppid)
|
: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)],
|
pmb.helpers.run.root(args, ["kill", "-9", str(pid)],
|
||||||
check=False)
|
check=False)
|
||||||
else:
|
else:
|
||||||
|
@ -102,15 +98,15 @@ def kill_process_tree(args, pid, ppids, kill_as_root):
|
||||||
|
|
||||||
for (child_pid, child_ppid) in ppids:
|
for (child_pid, child_ppid) in ppids:
|
||||||
if child_ppid == str(pid):
|
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
|
Kill a command process and recursively kill its child processes
|
||||||
|
|
||||||
:param pid: process id that will be killed
|
: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"]
|
cmd = ["ps", "-e", "-o", "pid=,ppid=", "--noheaders"]
|
||||||
ret = subprocess.run(cmd, check=True, stdout=subprocess.PIPE)
|
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)
|
raise RuntimeError("Unexpected ps output: " + row)
|
||||||
ppids.append(items)
|
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,
|
def foreground_pipe(args, cmd, working_dir=None, output_to_stdout=False,
|
||||||
output_return=False, output_timeout=True,
|
output_return=False, output_timeout=True,
|
||||||
kill_as_root=False):
|
sudo=False):
|
||||||
"""
|
"""
|
||||||
Run a subprocess in foreground with redirected output and optionally kill
|
Run a subprocess in foreground with redirected output and optionally kill
|
||||||
it after being silent for too long.
|
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
|
:param output_timeout: kill the process when it doesn't print any output
|
||||||
after a certain time (configured with --timeout)
|
after a certain time (configured with --timeout)
|
||||||
and raise a RuntimeError exception
|
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)
|
:returns: (code, output)
|
||||||
* code: return code of the program
|
* code: return code of the program
|
||||||
* output: ""
|
* output: ""
|
||||||
|
@ -173,7 +169,7 @@ def foreground_pipe(args, cmd, working_dir=None, output_to_stdout=False,
|
||||||
str(args.timeout) + " seconds. Killing it.")
|
str(args.timeout) + " seconds. Killing it.")
|
||||||
logging.info("NOTE: The timeout can be increased with"
|
logging.info("NOTE: The timeout can be increased with"
|
||||||
" 'pmbootstrap -t'.")
|
" 'pmbootstrap -t'.")
|
||||||
kill_command(args, process.pid, kill_as_root)
|
kill_command(args, process.pid, sudo)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# Read all currently available output
|
# 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",
|
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.
|
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
|
is not 0. Set this to False to disable the check. This
|
||||||
parameter can not be used when the output is "background" or
|
parameter can not be used when the output is "background" or
|
||||||
"pipe".
|
"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)
|
:returns: * program's return code (default)
|
||||||
* subprocess.Popen instance (output is "background" or "pipe")
|
* subprocess.Popen instance (output is "background" or "pipe")
|
||||||
* the program's entire output (output_return is True)
|
* 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)
|
# Log simplified and full command (pmbootstrap -v)
|
||||||
logging.debug(log_message)
|
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"]:
|
if not args.details_to_stdout and output in ["stdout", "interactive"]:
|
||||||
output_to_stdout = True
|
output_to_stdout = True
|
||||||
|
|
||||||
output_timeout = output in pmb.config.run_outputs_with_timeout \
|
output_timeout = output in ["log", "stdout"] and not disable_timeout
|
||||||
and not disable_timeout
|
|
||||||
(code, output_after_run) = foreground_pipe(args, cmd, working_dir,
|
(code, output_after_run) = foreground_pipe(args, cmd, working_dir,
|
||||||
output_to_stdout,
|
output_to_stdout,
|
||||||
output_return,
|
output_return,
|
||||||
output_timeout,
|
output_timeout,
|
||||||
kill_as_root)
|
sudo)
|
||||||
|
|
||||||
# Check the return code
|
# Check the return code
|
||||||
if check is not False:
|
if check is not False:
|
||||||
|
|
|
@ -41,12 +41,6 @@ def test_sanity_checks():
|
||||||
func("tui", output_return=True)
|
func("tui", output_return=True)
|
||||||
assert str(e.value).startswith("Can't use output_return with")
|
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):
|
def test_background(args):
|
||||||
# Sleep in background
|
# Sleep in background
|
||||||
|
@ -90,7 +84,7 @@ def test_foreground_pipe(args):
|
||||||
cmd = ["sudo", "sh", "-c", "printf first; sleep 2; printf second"]
|
cmd = ["sudo", "sh", "-c", "printf first; sleep 2; printf second"]
|
||||||
args.timeout = 0.3
|
args.timeout = 0.3
|
||||||
ret = func(args, cmd, output_return=True, output_timeout=True,
|
ret = func(args, cmd, output_return=True, output_timeout=True,
|
||||||
kill_as_root=True)
|
sudo=True)
|
||||||
assert ret == (-9, "first")
|
assert ret == (-9, "first")
|
||||||
|
|
||||||
# Finish before timeout
|
# Finish before timeout
|
||||||
|
@ -108,7 +102,7 @@ def test_foreground_pipe(args):
|
||||||
"sleep 10 | sleep 20 | sleep 30"]
|
"sleep 10 | sleep 20 | sleep 30"]
|
||||||
args.timeout = 0.3
|
args.timeout = 0.3
|
||||||
ret = func(args, cmd, output_return=True, output_timeout=True,
|
ret = func(args, cmd, output_return=True, output_timeout=True,
|
||||||
kill_as_root=True)
|
sudo=True)
|
||||||
pgid = str(ret[1])
|
pgid = str(ret[1])
|
||||||
|
|
||||||
cmd = ["ps", "-e", "-o", "pgid=,comm=", "--noheaders"]
|
cmd = ["ps", "-e", "-o", "pgid=,comm=", "--noheaders"]
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue