Use doas instead of sudo if installed (MR 2091)
Prefer using doas over sudo if both are installed. Let the user override the sudo tool with PMB_SUDO.
This commit is contained in:
parent
2801b5d687
commit
c1407f921b
|
@ -195,6 +195,12 @@ $ pmbootstrap stats --arch=armhf
|
|||
$ pmbootstrap log_distccd
|
||||
```
|
||||
|
||||
### Use alternative sudo
|
||||
|
||||
pmbootstrap supports `doas` and `sudo`.
|
||||
If multiple sudo implementations are installed, pmbootstrap will use `doas`.
|
||||
You can set the `PMB_SUDO` environmental variable to define the sudo implementation you want to use.
|
||||
|
||||
## Development
|
||||
### Requirements for running tests
|
||||
* [Shellcheck](https://shellcheck.net/)
|
||||
|
|
|
@ -71,7 +71,7 @@ def root(args, cmd, suffix="native", working_dir="/", output="log",
|
|||
executables = executables_absolute_path()
|
||||
cmd_chroot = [executables["chroot"], chroot, "/bin/sh", "-c",
|
||||
pmb.helpers.run.flat_cmd(cmd, working_dir)]
|
||||
cmd_sudo = ["sudo", "env", "-i", executables["sh"], "-c",
|
||||
cmd_sudo = [pmb.config.sudo, "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,
|
||||
output_return, check, True,
|
||||
|
|
|
@ -11,6 +11,7 @@ import sys
|
|||
from pmb.config.load import load
|
||||
from pmb.config.save import save
|
||||
from pmb.config.merge_with_args import merge_with_args
|
||||
from pmb.config.sudo import which_sudo
|
||||
|
||||
|
||||
#
|
||||
|
@ -50,6 +51,7 @@ ondev_min_version = "0.2.0"
|
|||
# in sync with README.md, and try to keep the list as small as possible. The
|
||||
# idea is to run almost everything in Alpine chroots.
|
||||
required_programs = ["git", "openssl", "ps"]
|
||||
sudo = which_sudo()
|
||||
|
||||
# Keys saved in the config file (mostly what we ask in 'pmbootstrap init')
|
||||
config_keys = ["aports",
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
# Copyright 2021 Anjandev Momi
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
import os
|
||||
import shutil
|
||||
|
||||
|
||||
def which_sudo():
|
||||
"""
|
||||
Find whether sudo or doas is installed for commands that require root.
|
||||
Allows user to override preferred sudo with PMB_SUDO env variable.
|
||||
"""
|
||||
supported_sudos = ['doas', 'sudo']
|
||||
|
||||
user_set_sudo = os.getenv("PMB_SUDO")
|
||||
if user_set_sudo is not None:
|
||||
if shutil.which(user_set_sudo) is None:
|
||||
raise RuntimeError("PMB_SUDO environmental variable is set to"
|
||||
f" {user_set_sudo} but pmbootstrap cannot find"
|
||||
" this command on your system.")
|
||||
return user_set_sudo
|
||||
|
||||
for sudo in supported_sudos:
|
||||
if shutil.which(sudo) is not None:
|
||||
return sudo
|
||||
|
||||
raise RuntimeError("Can't find sudo or doas required to run pmbootstrap."
|
||||
" Please install sudo, doas, or specify your own sudo"
|
||||
" with the PMB_SUDO environmental variable.")
|
|
@ -62,7 +62,7 @@ def user(args, cmd, working_dir=None, output="log", output_return=False,
|
|||
def root(args, cmd, working_dir=None, output="log", output_return=False,
|
||||
check=None, env={}):
|
||||
"""
|
||||
Run a command on the host system as root, with sudo.
|
||||
Run a command on the host system as root, with sudo or doas.
|
||||
|
||||
:param env: dict of environment variables to be passed to the command, e.g.
|
||||
{"JOBS": "5"}
|
||||
|
@ -72,7 +72,7 @@ def root(args, cmd, working_dir=None, output="log", output_return=False,
|
|||
"""
|
||||
if env:
|
||||
cmd = ["sh", "-c", flat_cmd(cmd, env=env)]
|
||||
cmd = ["sudo"] + cmd
|
||||
cmd = [pmb.config.sudo] + cmd
|
||||
|
||||
return user(args, cmd, working_dir, output, output_return, check, env,
|
||||
True)
|
||||
|
|
|
@ -224,7 +224,10 @@ def sudo_timer_iterate():
|
|||
Run sudo -v and schedule a new timer to repeat the same.
|
||||
"""
|
||||
|
||||
subprocess.Popen(["sudo", "-v"]).wait()
|
||||
if pmb.config.sudo == "sudo":
|
||||
subprocess.Popen(["sudo", "-v"]).wait()
|
||||
else:
|
||||
subprocess.Popen([pmb.config.sudo, "true"]).wait()
|
||||
|
||||
timer = threading.Timer(interval=60, function=sudo_timer_iterate)
|
||||
timer.daemon = True
|
||||
|
|
|
@ -79,8 +79,9 @@ def bootimg(args, path):
|
|||
if not os.path.exists(path):
|
||||
raise RuntimeError("Could not find file '" + path + "'")
|
||||
|
||||
logging.info("NOTE: You will be prompted for your sudo password, so we can"
|
||||
" set up a chroot to extract and analyze your boot.img file")
|
||||
logging.info("NOTE: You will be prompted for your sudo/doas password, so"
|
||||
" we can set up a chroot to extract and analyze your"
|
||||
" boot.img file")
|
||||
pmb.chroot.apk.install(args, ["file", "unpackbootimg"])
|
||||
|
||||
temp_path = pmb.chroot.other.tempfolder(args, "/tmp/bootimg_parser")
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
import sys
|
||||
import subprocess
|
||||
import pytest
|
||||
import time
|
||||
|
||||
import pmb_test # noqa
|
||||
import pmb.helpers.run_core
|
||||
|
@ -81,7 +82,7 @@ def test_foreground_pipe(args):
|
|||
assert ret == (-9, "first\n")
|
||||
|
||||
# Kill with output timeout as root
|
||||
cmd = ["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
|
||||
ret = func(args, cmd, output_return=True, output_timeout=True,
|
||||
sudo=True)
|
||||
|
@ -97,7 +98,7 @@ def test_foreground_pipe(args):
|
|||
# Check if all child processes are killed after timeout.
|
||||
# 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.
|
||||
cmd = ["sudo", "sh", "-c",
|
||||
cmd = [pmb.config.sudo, "sh", "-c",
|
||||
"pgid=$(ps -o pgid= | grep ^${1:-$$});echo $pgid | tr -d '\n';" +
|
||||
"sleep 10 | sleep 20 | sleep 30"]
|
||||
args.timeout = 0.3
|
||||
|
@ -152,3 +153,14 @@ def test_core(args):
|
|||
with pytest.raises(RuntimeError) as e:
|
||||
func(args, msg, ["sleep", "1"], output="log")
|
||||
assert str(e.value).startswith("Command failed:")
|
||||
|
||||
|
||||
@pytest.mark.skip_ci
|
||||
def test_sudo_timer(args):
|
||||
pmb.helpers.run.root(args, ["whoami"])
|
||||
|
||||
time.sleep(300)
|
||||
|
||||
out = pmb.helpers.run.root(args, ["whoami"])
|
||||
|
||||
assert out == 0
|
||||
|
|
Loading…
Reference in New Issue