~postmarketos/pmbootstrap-devel

This thread contains a patchset. You're looking at the original emails, but you may wish to use the patch review UI. Review patch
3 2

[PATCH pmbootstrap v4] Don't use 'sudo' when running as root

Details
Message ID
<20230529203922.22161-1-hugo@whynothugo.nl>
DKIM signature
missing
Download raw message
Patch: +30 -10
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
---
Appologies for the noise with this patch.

This fourth version addresses all previous comments and passes all CI checks.
 pmb/chroot/root.py     |  6 ++++--
 pmb/config/__init__.py | 11 ++++++++++-
 pmb/config/sudo.py     | 11 +++++++++--
 pmb/helpers/run.py     |  2 +-
 test/test_run_core.py  | 10 ++++++----
 5 files changed, 30 insertions(+), 10 deletions(-)

diff --git a/pmb/chroot/root.py b/pmb/chroot/root.py
index a14177ad..4e5fc586 100644
--- a/pmb/chroot/root.py
+++ b/pmb/chroot/root.py
@@ -78,8 +78,10 @@ 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 = [pmb.config.sudo, "env", "-i", executables["sh"], "-c",
                pmb.helpers.run.flat_cmd(cmd_chroot, env=env_all)]
    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,
                                     disable_timeout)
diff --git a/pmb/config/__init__.py b/pmb/config/__init__.py
index fae75b17..59af6f76 100644
--- a/pmb/config/__init__.py
+++ b/pmb/config/__init__.py
@@ -58,7 +58,16 @@ required_programs = [
    "ps",
    "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')
config_keys = [
diff --git a/pmb/config/sudo.py b/pmb/config/sudo.py
index fe876987..1e227534 100644
--- a/pmb/config/sudo.py
+++ b/pmb/config/sudo.py
@@ -2,13 +2,20 @@
# SPDX-License-Identifier: GPL-3.0-or-later
import os
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.
    Allows user to override preferred sudo with PMB_SUDO env variable.
    """

    if os.getuid() == 0:
        return None

    supported_sudos = ['doas', 'sudo']

    user_set_sudo = os.getenv("PMB_SUDO")
diff --git a/pmb/helpers/run.py b/pmb/helpers/run.py
index b172b356..9835434a 100644
--- a/pmb/helpers/run.py
+++ b/pmb/helpers/run.py
@@ -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 = [pmb.config.sudo] + cmd
    cmd = pmb.config.sudo(cmd)

    return user(args, cmd, working_dir, output, output_return, check, env,
                True)
diff --git a/test/test_run_core.py b/test/test_run_core.py
index a4600fb8..aa2aaf65 100644
--- a/test/test_run_core.py
+++ b/test/test_run_core.py
@@ -83,7 +83,7 @@ def test_foreground_pipe(args):
    assert ret == (-9, "first\n")

    # 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
    ret = func(args, cmd, output_return=True, output_timeout=True,
               sudo=True)
@@ -99,9 +99,11 @@ 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 = [pmb.config.sudo, "sh", "-c",
           "pgid=$(ps -o pgid= | grep ^${1:-$$});echo $pgid | tr -d '\n';" +
           "sleep 10 | sleep 20 | sleep 30"]
    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
    ret = func(args, cmd, output_return=True, output_timeout=True,
               sudo=True)
-- 
2.40.1

[pmbootstrap/patches/.build.yml] build success

builds.sr.ht <builds@sr.ht>
Details
Message ID
<CSZ2P24KK2G5.15MJPXA8QL8JN@cirno2>
In-Reply-To
<20230529203922.22161-1-hugo@whynothugo.nl> (view parent)
DKIM signature
missing
Download raw message
pmbootstrap/patches/.build.yml: SUCCESS in 21m12s

[Don't use 'sudo' when running as root][0] v4 from [Hugo Osvaldo Barrera][1]

[0]: https://lists.sr.ht/~postmarketos/pmbootstrap-devel/patches/41488
[1]: hugo@whynothugo.nl

✓ #998177 SUCCESS pmbootstrap/patches/.build.yml https://builds.sr.ht/~postmarketos/job/998177
Details
Message ID
<CT3RGVEDXEHE.1QQB8G4USSDY5@pm-mail-aerc>
In-Reply-To
<20230529203922.22161-1-hugo@whynothugo.nl> (view parent)
DKIM signature
missing
Download raw message
On Mon May 29, 2023 at 10:39 PM CEST, Hugo Osvaldo Barrera wrote:
> 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

Looks good now, thanks a lot!

Reviewed-by: Oliver Smith <ollieparanoid@postmarketos.org>

> ---
> Appologies for the noise with this patch.
>
> This fourth version addresses all previous comments and passes all CI checks.
>  pmb/chroot/root.py     |  6 ++++--
>  pmb/config/__init__.py | 11 ++++++++++-
>  pmb/config/sudo.py     | 11 +++++++++--
>  pmb/helpers/run.py     |  2 +-
>  test/test_run_core.py  | 10 ++++++----
>  5 files changed, 30 insertions(+), 10 deletions(-)
>
> diff --git a/pmb/chroot/root.py b/pmb/chroot/root.py
> index a14177ad..4e5fc586 100644
> --- a/pmb/chroot/root.py
> +++ b/pmb/chroot/root.py
> @@ -78,8 +78,10 @@ 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 = [pmb.config.sudo, "env", "-i", executables["sh"], "-c",
> -                pmb.helpers.run.flat_cmd(cmd_chroot, env=env_all)]
> +    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,
>                                       disable_timeout)
> diff --git a/pmb/config/__init__.py b/pmb/config/__init__.py
> index fae75b17..59af6f76 100644
> --- a/pmb/config/__init__.py
> +++ b/pmb/config/__init__.py
> @@ -58,7 +58,16 @@ required_programs = [
>      "ps",
>      "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')
>  config_keys = [
> diff --git a/pmb/config/sudo.py b/pmb/config/sudo.py
> index fe876987..1e227534 100644
> --- a/pmb/config/sudo.py
> +++ b/pmb/config/sudo.py
> @@ -2,13 +2,20 @@
>  # SPDX-License-Identifier: GPL-3.0-or-later
>  import os
>  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.
>      Allows user to override preferred sudo with PMB_SUDO env variable.
>      """
> +
> +    if os.getuid() == 0:
> +        return None
> +
>      supported_sudos = ['doas', 'sudo']
>  
>      user_set_sudo = os.getenv("PMB_SUDO")
> diff --git a/pmb/helpers/run.py b/pmb/helpers/run.py
> index b172b356..9835434a 100644
> --- a/pmb/helpers/run.py
> +++ b/pmb/helpers/run.py
> @@ -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 = [pmb.config.sudo] + cmd
> +    cmd = pmb.config.sudo(cmd)
>  
>      return user(args, cmd, working_dir, output, output_return, check, env,
>                  True)
> diff --git a/test/test_run_core.py b/test/test_run_core.py
> index a4600fb8..aa2aaf65 100644
> --- a/test/test_run_core.py
> +++ b/test/test_run_core.py
> @@ -83,7 +83,7 @@ def test_foreground_pipe(args):
>      assert ret == (-9, "first\n")
>  
>      # 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
>      ret = func(args, cmd, output_return=True, output_timeout=True,
>                 sudo=True)
> @@ -99,9 +99,11 @@ 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 = [pmb.config.sudo, "sh", "-c",
> -           "pgid=$(ps -o pgid= | grep ^${1:-$$});echo $pgid | tr -d '\n';" +
> -           "sleep 10 | sleep 20 | sleep 30"]
> +    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
>      ret = func(args, cmd, output_return=True, output_timeout=True,
>                 sudo=True)
> -- 
> 2.40.1
Details
Message ID
<168587141559.2597.4098596091517159632.b4-ty@postmarketos.org>
In-Reply-To
<20230529203922.22161-1-hugo@whynothugo.nl> (view parent)
DKIM signature
missing
Download raw message
On Mon, 29 May 2023 22:39:23 +0200, Hugo Osvaldo Barrera wrote:
> This cancels the need to install and configure `sudo` or `doas` on
> single-user installations (e.g.: a VM dedicated to running pmbootstrap).
> 
> 

Applied, thanks!

[1/1] Don't use 'sudo' when running as root
      commit: d31313f7dc8018aeb92eeb8caf2dccf71a443a43

Best regards,
-- 
Oliver Smith <ollieparanoid@postmarketos.org>
Reply to thread Export thread (mbox)