pmb.helpers.run_core: move flat_cmd here

Move pmb.helpers.run.flat_cmd to run_core, as it will be used by
pmb.helpers.run_core.core in the next patch.

Link: https://lists.sr.ht/~postmarketos/pmbootstrap-devel/%3C20230713182337.6185-2-ollieparanoid@postmarketos.org%3E
This commit is contained in:
Oliver Smith 2023-07-13 20:19:47 +02:00
parent 46789ccee8
commit 20a0ccf36f
No known key found for this signature in database
GPG key ID: 5AE7F5513E0885CB
8 changed files with 54 additions and 48 deletions

View file

@ -71,10 +71,10 @@ def root(args, cmd, suffix="native", working_dir="/", output="log",
# cmd_sudo: ["sudo", "env", "-i", "sh", "-c", "PATH=... /sbin/chroot ..."] # cmd_sudo: ["sudo", "env", "-i", "sh", "-c", "PATH=... /sbin/chroot ..."]
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_core.flat_cmd(cmd, working_dir)]
cmd_sudo = pmb.config.sudo([ cmd_sudo = pmb.config.sudo([
"env", "-i", executables["sh"], "-c", "env", "-i", executables["sh"], "-c",
pmb.helpers.run.flat_cmd(cmd_chroot, env=env_all)] pmb.helpers.run_core.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,

View file

@ -2,6 +2,7 @@
# SPDX-License-Identifier: GPL-3.0-or-later # SPDX-License-Identifier: GPL-3.0-or-later
import pmb.chroot.root import pmb.chroot.root
import pmb.helpers.run import pmb.helpers.run
import pmb.helpers.run_core
def user(args, cmd, suffix="native", working_dir="/", output="log", def user(args, cmd, suffix="native", working_dir="/", output="log",
@ -21,7 +22,7 @@ def user(args, cmd, suffix="native", working_dir="/", output="log",
if "HOME" not in env: if "HOME" not in env:
env["HOME"] = "/home/pmos" env["HOME"] = "/home/pmos"
flat_cmd = pmb.helpers.run.flat_cmd(cmd, env=env) flat_cmd = pmb.helpers.run_core.flat_cmd(cmd, env=env)
cmd = ["busybox", "su", "pmos", "-c", flat_cmd] cmd = ["busybox", "su", "pmos", "-c", flat_cmd]
return pmb.chroot.root(args, cmd, suffix, working_dir, output, return pmb.chroot.root(args, cmd, suffix, working_dir, output,
output_return, check, {}, auto_init) output_return, check, {}, auto_init)

View file

@ -6,6 +6,7 @@ import pmb.chroot.root
import pmb.config.pmaports import pmb.config.pmaports
import pmb.helpers.cli import pmb.helpers.cli
import pmb.helpers.run import pmb.helpers.run
import pmb.helpers.run_core
import pmb.parse.version import pmb.parse.version
@ -62,7 +63,7 @@ def _create_command_with_progress(command, fifo):
""" """
flags = ["--no-progress", "--progress-fd", "3"] flags = ["--no-progress", "--progress-fd", "3"]
command_full = [command[0]] + flags + command[1:] command_full = [command[0]] + flags + command[1:]
command_flat = pmb.helpers.run.flat_cmd(command_full) command_flat = pmb.helpers.run_core.flat_cmd(command_full)
command_flat = f"exec 3>{fifo}; {command_flat}" command_flat = f"exec 3>{fifo}; {command_flat}"
return ["sh", "-c", command_flat] return ["sh", "-c", command_flat]

View file

@ -4,35 +4,6 @@ import shlex
import pmb.helpers.run_core import pmb.helpers.run_core
def flat_cmd(cmd, working_dir=None, env={}):
"""
Convert a shell command passed as list into a flat shell string with
proper escaping.
:param cmd: command as list, e.g. ["echo", "string with spaces"]
:param working_dir: when set, prepend "cd ...;" to execute the command
in the given working directory
:param env: dict of environment variables to be passed to the command, e.g.
{"JOBS": "5"}
:returns: the flat string, e.g.
echo 'string with spaces'
cd /home/pmos;echo 'string with spaces'
"""
# Merge env and cmd into escaped list
escaped = []
for key, value in env.items():
escaped.append(key + "=" + shlex.quote(value))
for i in range(len(cmd)):
escaped.append(shlex.quote(cmd[i]))
# Prepend working dir
ret = " ".join(escaped)
if working_dir:
ret = "cd " + shlex.quote(working_dir) + ";" + ret
return ret
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={}, sudo=False): check=None, env={}, sudo=False):
""" """
@ -54,7 +25,7 @@ def user(args, cmd, working_dir=None, output="log", output_return=False,
# Add environment variables and run # Add environment variables and run
if env: if env:
cmd = ["sh", "-c", flat_cmd(cmd, env=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, return pmb.helpers.run_core.core(args, msg, cmd, working_dir, output,
output_return, check, sudo) output_return, check, sudo)
@ -71,7 +42,7 @@ def root(args, cmd, working_dir=None, output="log", output_return=False,
arguments and the return value. arguments and the return value.
""" """
if env: if env:
cmd = ["sh", "-c", flat_cmd(cmd, env=env)] cmd = ["sh", "-c", pmb.helpers.run_core.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,

View file

@ -2,12 +2,13 @@
# SPDX-License-Identifier: GPL-3.0-or-later # SPDX-License-Identifier: GPL-3.0-or-later
import fcntl import fcntl
import logging import logging
import os
import selectors import selectors
import shlex
import subprocess import subprocess
import sys import sys
import threading import threading
import time import time
import os
import pmb.helpers.run import pmb.helpers.run
""" For a detailed description of all output modes, read the description of """ For a detailed description of all output modes, read the description of
@ -15,6 +16,35 @@ import pmb.helpers.run
called by core(). """ called by core(). """
def flat_cmd(cmd, working_dir=None, env={}):
"""
Convert a shell command passed as list into a flat shell string with
proper escaping.
:param cmd: command as list, e.g. ["echo", "string with spaces"]
:param working_dir: when set, prepend "cd ...;" to execute the command
in the given working directory
:param env: dict of environment variables to be passed to the command, e.g.
{"JOBS": "5"}
:returns: the flat string, e.g.
echo 'string with spaces'
cd /home/pmos;echo 'string with spaces'
"""
# Merge env and cmd into escaped list
escaped = []
for key, value in env.items():
escaped.append(key + "=" + shlex.quote(value))
for i in range(len(cmd)):
escaped.append(shlex.quote(cmd[i]))
# Prepend working dir
ret = " ".join(escaped)
if working_dir:
ret = "cd " + shlex.quote(working_dir) + ";" + ret
return ret
def sanity_checks(output="log", output_return=False, check=None): def sanity_checks(output="log", output_return=False, check=None):
""" """
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

View file

@ -5,6 +5,7 @@ import os
import logging import logging
import pmb.helpers.run import pmb.helpers.run
import pmb.helpers.run_core
import pmb.parse.apkindex import pmb.parse.apkindex
import pmb.config.pmaports import pmb.config.pmaports
import pmb.build import pmb.build
@ -29,7 +30,7 @@ def scp_abuild_key(args, user, host, port):
keyname = os.path.join("/tmp", os.path.basename(key)) keyname = os.path.join("/tmp", os.path.basename(key))
remote_cmd = ['sudo', '-p', pmb.config.sideload_sudo_prompt, remote_cmd = ['sudo', '-p', pmb.config.sideload_sudo_prompt,
'-S', 'mv', '-n', keyname, "/etc/apk/keys/"] '-S', 'mv', '-n', keyname, "/etc/apk/keys/"]
remote_cmd = pmb.helpers.run.flat_cmd(remote_cmd) remote_cmd = pmb.helpers.run_core.flat_cmd(remote_cmd)
command = ['ssh', '-t', '-p', port, f'{user}@{host}', remote_cmd] command = ['ssh', '-t', '-p', port, f'{user}@{host}', remote_cmd]
pmb.helpers.run.user(args, command, output="tui") pmb.helpers.run.user(args, command, output="tui")
@ -53,8 +54,8 @@ def ssh_install_apks(args, user, host, port, paths):
logging.info(f"Installing packages at {user}@{host}") logging.info(f"Installing packages at {user}@{host}")
add_cmd = ['sudo', '-p', pmb.config.sideload_sudo_prompt, add_cmd = ['sudo', '-p', pmb.config.sideload_sudo_prompt,
'-S', 'apk', '--wait', '30', 'add'] + remote_paths '-S', 'apk', '--wait', '30', 'add'] + remote_paths
add_cmd = pmb.helpers.run.flat_cmd(add_cmd) add_cmd = pmb.helpers.run_core.flat_cmd(add_cmd)
clean_cmd = pmb.helpers.run.flat_cmd(['rm'] + remote_paths) clean_cmd = pmb.helpers.run_core.flat_cmd(['rm'] + remote_paths)
command = ['ssh', '-t', '-p', port, f'{user}@{host}', command = ['ssh', '-t', '-p', port, f'{user}@{host}',
f'{add_cmd}; rc=$?; {clean_cmd}; exit $rc'] f'{add_cmd}; rc=$?; {clean_cmd}; exit $rc']
pmb.helpers.run.user(args, command, output="tui") pmb.helpers.run.user(args, command, output="tui")

View file

@ -9,6 +9,7 @@ import pmb.config
import pmb.helpers.frontend import pmb.helpers.frontend
import pmb.helpers.logging import pmb.helpers.logging
import pmb.helpers.run import pmb.helpers.run
import pmb.helpers.run_core
@pytest.fixture @pytest.fixture
@ -40,11 +41,11 @@ def test_config_user(args, tmpdir, monkeypatch):
path_config = tmpdir + "/pmbootstrap.cfg" path_config = tmpdir + "/pmbootstrap.cfg"
# Generate default config (only uses tmpdir) # Generate default config (only uses tmpdir)
cmd = pmb.helpers.run.flat_cmd(["./pmbootstrap.py", cmd = pmb.helpers.run_core.flat_cmd(["./pmbootstrap.py",
"-c", path_config, "-c", path_config,
"-w", path_work, "-w", path_work,
"--aports", args.aports, "--aports", args.aports,
"init"]) "init"])
pmb.helpers.run.user(args, ["sh", "-c", "yes '' | " + cmd], pmb.helpers.run.user(args, ["sh", "-c", "yes '' | " + cmd],
pmb.config.pmb_src) pmb.config.pmb_src)

View file

@ -7,6 +7,7 @@ import pmb_test # noqa
import pmb.chroot.root import pmb.chroot.root
import pmb.chroot.user import pmb.chroot.user
import pmb.helpers.run import pmb.helpers.run
import pmb.helpers.run_core
import pmb.helpers.logging import pmb.helpers.logging
@ -79,7 +80,7 @@ def test_shell_escape_env(args):
def test_flat_cmd_simple(): def test_flat_cmd_simple():
func = pmb.helpers.run.flat_cmd func = pmb.helpers.run_core.flat_cmd
cmd = ["echo", "test"] cmd = ["echo", "test"]
working_dir = None working_dir = None
ret = "echo test" ret = "echo test"
@ -88,7 +89,7 @@ def test_flat_cmd_simple():
def test_flat_cmd_wrap_shell_string_with_spaces(): def test_flat_cmd_wrap_shell_string_with_spaces():
func = pmb.helpers.run.flat_cmd func = pmb.helpers.run_core.flat_cmd
cmd = ["echo", "string with spaces"] cmd = ["echo", "string with spaces"]
working_dir = None working_dir = None
ret = "echo 'string with spaces'" ret = "echo 'string with spaces'"
@ -97,7 +98,7 @@ def test_flat_cmd_wrap_shell_string_with_spaces():
def test_flat_cmd_wrap_env_simple(): def test_flat_cmd_wrap_env_simple():
func = pmb.helpers.run.flat_cmd func = pmb.helpers.run_core.flat_cmd
cmd = ["echo", "test"] cmd = ["echo", "test"]
working_dir = None working_dir = None
ret = "JOBS=5 echo test" ret = "JOBS=5 echo test"
@ -106,7 +107,7 @@ def test_flat_cmd_wrap_env_simple():
def test_flat_cmd_wrap_env_spaces(): def test_flat_cmd_wrap_env_spaces():
func = pmb.helpers.run.flat_cmd func = pmb.helpers.run_core.flat_cmd
cmd = ["echo", "test"] cmd = ["echo", "test"]
working_dir = None working_dir = None
ret = "JOBS=5 TEST='spaces string' echo test" ret = "JOBS=5 TEST='spaces string' echo test"