Don't use 'sudo' when running as root

This cancels the need to install and configure `sudo` or `doas` on
single-user installations (e.g.: a VM dedicated to running pmbootstrap).

Fixes: https://gitlab.com/postmarketOS/pmbootstrap/-/issues/2224
Reviewed-by: Oliver Smith <ollieparanoid@postmarketos.org>
Link: https://lists.sr.ht/~postmarketos/pmbootstrap-devel/%3C20230529203922.22161-1-hugo@whynothugo.nl%3E
This commit is contained in:
Hugo Osvaldo Barrera 2023-05-29 22:39:23 +02:00 committed by Oliver Smith
parent 27618d5ffd
commit d31313f7dc
No known key found for this signature in database
GPG Key ID: 5AE7F5513E0885CB
5 changed files with 30 additions and 10 deletions

View File

@ -78,8 +78,10 @@ def root(args, cmd, suffix="native", working_dir="/", output="log",
executables = executables_absolute_path() executables = executables_absolute_path()
cmd_chroot = [executables["chroot"], chroot, "/bin/sh", "-c", cmd_chroot = [executables["chroot"], chroot, "/bin/sh", "-c",
pmb.helpers.run.flat_cmd(cmd, working_dir)] pmb.helpers.run.flat_cmd(cmd, working_dir)]
cmd_sudo = [pmb.config.sudo, "env", "-i", executables["sh"], "-c", cmd_sudo = pmb.config.sudo([
pmb.helpers.run.flat_cmd(cmd_chroot, env=env_all)] "env", "-i", executables["sh"], "-c",
pmb.helpers.run.flat_cmd(cmd_chroot, env=env_all)]
)
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, True, output_return, check, True,
disable_timeout) disable_timeout)

View File

@ -58,7 +58,16 @@ required_programs = [
"ps", "ps",
"tar", "tar",
] ]
sudo = which_sudo()
def sudo(cmd: list[str]) -> list[str]:
"""Adapt a command to run as root."""
sudo = which_sudo()
if sudo:
return [sudo, *cmd]
else:
return cmd
# Keys saved in the config file (mostly what we ask in 'pmbootstrap init') # Keys saved in the config file (mostly what we ask in 'pmbootstrap init')
config_keys = [ config_keys = [

View File

@ -2,13 +2,20 @@
# SPDX-License-Identifier: GPL-3.0-or-later # SPDX-License-Identifier: GPL-3.0-or-later
import os import os
import shutil import shutil
from functools import lru_cache
def which_sudo(): @lru_cache()
""" def which_sudo() -> str | None:
"""Returns a command required to run commands as root, if any.
Find whether sudo or doas is installed for commands that require root. Find whether sudo or doas is installed for commands that require root.
Allows user to override preferred sudo with PMB_SUDO env variable. Allows user to override preferred sudo with PMB_SUDO env variable.
""" """
if os.getuid() == 0:
return None
supported_sudos = ['doas', 'sudo'] supported_sudos = ['doas', 'sudo']
user_set_sudo = os.getenv("PMB_SUDO") user_set_sudo = os.getenv("PMB_SUDO")

View File

@ -72,7 +72,7 @@ def root(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)]
cmd = [pmb.config.sudo] + cmd cmd = pmb.config.sudo(cmd)
return user(args, cmd, working_dir, output, output_return, check, env, return user(args, cmd, working_dir, output, output_return, check, env,
True) True)

View File

@ -83,7 +83,7 @@ def test_foreground_pipe(args):
assert ret == (-9, "first\n") assert ret == (-9, "first\n")
# Kill with output timeout as root # Kill with output timeout as root
cmd = [pmb.config.sudo, "sh", "-c", "printf first; sleep 2; printf second"] cmd = pmb.config.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,
sudo=True) sudo=True)
@ -99,9 +99,11 @@ def test_foreground_pipe(args):
# Check if all child processes are killed after timeout. # Check if all child processes are killed after timeout.
# The first command uses ps to get its process group id (pgid) and echo it # The first command uses ps to get its process group id (pgid) and echo it
# to stdout. All of the test commands will be running under that pgid. # to stdout. All of the test commands will be running under that pgid.
cmd = [pmb.config.sudo, "sh", "-c", cmd = pmb.config.sudo([
"pgid=$(ps -o pgid= | grep ^${1:-$$});echo $pgid | tr -d '\n';" + "sh", "-c",
"sleep 10 | sleep 20 | sleep 30"] "pgid=$(ps -o pgid= | grep ^${1:-$$});echo $pgid | tr -d '\n';"
"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,
sudo=True) sudo=True)