pmbootstrap-meow/pmb/helpers/run.py
Oliver Smith 37a7f3924d
Fix preserving proxy variables (MR 2237)
Fix "pmbootstrap chroot" and others not passing the proxy environment
variables correctly. Thanks to notfound405 for pointing this out!

Instead of only preserving proxy environment variables in
pmb.helpers.run_core, which should never be called directly, do it in
the calling functions:

* pmb.helpers.run.user
* pmb.helpers.run.root
* pmb.chroot.root
* pmb.chroot.user

This fixes that the environment variables were only really passed by
pmb.helpers.run.user, because the other functions would result in
something like:
  HTTP_PROXY=mytestproxy sudo env -i /usr/bin/sh -c '…'
This is needed to either elevate to root, or to elevate to root first
and then enter the chroot as root or user. Due to the "env -i", the
environment intentionally gets cleaned, but unintentionally also removes
the proxy environment variables that were explicitly set.

By adjusting the functions, they now run a variant of:
  sudo env -i /usr/bin/sh -c 'HTTP_PROXY=mytestproxy …'

The escaping is simplified in this example, run "pmbootstrap -v" to see
the not very readable, but proper escaping with shutil.quote().

Remove the previous test for preserving the environment variables in
pmb.helpers.run_core (as it should never be called directly), and test
instead the new behavior.

Fixes: issue 2299
Fixes: 13c4ac42 ("pmb.helpers.run_core: fix proxy env var logic")
2024-01-25 20:12:53 +00:00

53 lines
1.7 KiB
Python

# Copyright 2023 Oliver Smith
# SPDX-License-Identifier: GPL-3.0-or-later
import pmb.helpers.run_core
def user(args, cmd, working_dir=None, output="log", output_return=False,
check=None, env={}, sudo=False):
"""
Run a command on the host system as user.
:param env: dict of environment variables to be passed to the command, e.g.
{"JOBS": "5"}
See pmb.helpers.run_core.core() for a detailed description of all other
arguments and the return value.
"""
# Readable log message (without all the escaping)
msg = "% "
for key, value in env.items():
msg += key + "=" + value + " "
if working_dir:
msg += "cd " + working_dir + "; "
msg += " ".join(cmd)
# Add environment variables and run
env = env.copy()
pmb.helpers.run_core.add_proxy_env_vars(env)
if env:
cmd = ["sh", "-c", pmb.helpers.run_core.flat_cmd(cmd, env=env)]
return pmb.helpers.run_core.core(args, msg, cmd, working_dir, output,
output_return, check, sudo)
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 or doas.
:param env: dict of environment variables to be passed to the command, e.g.
{"JOBS": "5"}
See pmb.helpers.run_core.core() for a detailed description of all other
arguments and the return value.
"""
env = env.copy()
pmb.helpers.run_core.add_proxy_env_vars(env)
if env:
cmd = ["sh", "-c", pmb.helpers.run_core.flat_cmd(cmd, env=env)]
cmd = pmb.config.sudo(cmd)
return user(args, cmd, working_dir, output, output_return, check, env,
True)