[elbe-devel] [PATCH 07/11] elbepack: migrate command_out_stderr to subprocess package
Thomas Weißschuh
thomas.weissschuh at linutronix.de
Wed Mar 13 16:54:56 CET 2024
The subprocess APIs are more powerful, better documented and
standardized.
Signed-off-by: Thomas Weißschuh <thomas.weissschuh at linutronix.de>
---
elbepack/initvmaction.py | 27 +++++++++++++--------------
elbepack/pbuilderaction.py | 32 ++++++++++++++++----------------
elbepack/shellhelper.py | 42 ------------------------------------------
elbepack/xmlpreprocess.py | 18 ++++++++----------
4 files changed, 37 insertions(+), 82 deletions(-)
diff --git a/elbepack/initvmaction.py b/elbepack/initvmaction.py
index bd56682da991..7f5b871e3403 100644
--- a/elbepack/initvmaction.py
+++ b/elbepack/initvmaction.py
@@ -12,11 +12,11 @@ import time
import elbepack
from elbepack.config import cfg
-from elbepack.directories import elbe_exe
+from elbepack.directories import elbe_exe, run_elbe
from elbepack.elbexml import ElbeXML, ValidationError, ValidationMode
from elbepack.filesystem import TmpdirFilesystem
from elbepack.repodir import Repodir, RepodirError
-from elbepack.shellhelper import command_out_stderr, system
+from elbepack.shellhelper import system
from elbepack.treeutils import etree
from elbepack.xmlpreprocess import PreprocessWrapper
@@ -215,11 +215,11 @@ class EnsureAction(InitVMAction):
elif self.initvm_state() == libvirt.VIR_DOMAIN_RUNNING:
stop = time.time() + 300
while True:
- cmd = command_out_stderr(f'{sys.executable} {elbe_exe} control list_projects')
- if cmd[0] == 0:
+ ps = run_elbe(['control', 'list_projects'], capture_output=True)
+ if ps.returncode == 0:
break
if time.time() > stop:
- print(f'Waited for 5 minutes and the daemon is still not active: {cmd[2]}',
+ print(f'Waited for 5 minutes and the daemon is still not active: {ps.stderr}',
file=sys.stderr)
sys.exit(123)
time.sleep(10)
@@ -300,21 +300,20 @@ def submit_and_dl_result(xmlfile, cdrom, opt):
with PreprocessWrapper(xmlfile, opt) as ppw:
xmlfile = ppw.preproc
- ret, prjdir, err = command_out_stderr(
- f'{sys.executable} {elbe_exe} control create_project')
- if ret != 0:
+ ps = run_elbe(['control', 'create_project'], capture_output=True, encoding='utf-8')
+ if ps.returncode != 0:
print('elbe control create_project failed.', file=sys.stderr)
- print(err, file=sys.stderr)
+ print(ps.stderr, file=sys.stderr)
print('Giving up', file=sys.stderr)
sys.exit(128)
- prjdir = prjdir.strip()
+ prjdir = ps.stdout.strip()
- cmd = f'{sys.executable} {elbe_exe} control set_xml {prjdir} {xmlfile}'
- ret, _, err = command_out_stderr(cmd)
- if ret != 0:
+ ps = run_elbe(['control', 'set_xml', prjdir, xmlfile],
+ capture_output=True, encoding='utf-8')
+ if ps.returncode != 0:
print('elbe control set_xml failed2', file=sys.stderr)
- print(err, file=sys.stderr)
+ print(ps.stderr, file=sys.stderr)
print('Giving up', file=sys.stderr)
sys.exit(129)
except subprocess.CalledProcessError:
diff --git a/elbepack/pbuilderaction.py b/elbepack/pbuilderaction.py
index 908db86fbd64..35f0220095c4 100644
--- a/elbepack/pbuilderaction.py
+++ b/elbepack/pbuilderaction.py
@@ -6,9 +6,9 @@ import os
import subprocess
import sys
-from elbepack.directories import elbe_exe
+from elbepack.directories import elbe_exe, run_elbe
from elbepack.filesystem import TmpdirFilesystem
-from elbepack.shellhelper import command_out_stderr, system
+from elbepack.shellhelper import system
from elbepack.xmlpreprocess import PreprocessWrapper
@@ -77,22 +77,22 @@ class CreateAction(PBuilderAction):
if opt.xmlfile:
try:
with PreprocessWrapper(opt.xmlfile, opt) as ppw:
- ret, prjdir, err = command_out_stderr(
- f'{sys.executable} {elbe_exe} control create_project')
- if ret != 0:
+ ps = run_elbe(['control', 'create_project'],
+ capture_output=True, encoding='utf-8')
+ if ps.returncode != 0:
print('elbe control create_project failed.',
file=sys.stderr)
- print(err, file=sys.stderr)
+ print(ps.stderr, file=sys.stderr)
print('Giving up', file=sys.stderr)
sys.exit(152)
- prjdir = prjdir.strip()
- ret, _, err = command_out_stderr(
- f'{sys.executable} {elbe_exe} control set_xml "{prjdir}" "{ppw.preproc}"')
+ prjdir = ps.stdout.strip()
+ ps = run_elbe(['control', 'set_xml', prjdir, ppw.preproc],
+ capture_output=True, encoding='utf-8')
- if ret != 0:
+ if ps.returncode != 0:
print('elbe control set_xml failed.', file=sys.stderr)
- print(err, file=sys.stderr)
+ print(ps.stderr, file=sys.stderr)
print('Giving up', file=sys.stderr)
sys.exit(153)
except subprocess.CalledProcessError:
@@ -185,15 +185,15 @@ class BuildAction(PBuilderAction):
tmp = TmpdirFilesystem()
if opt.xmlfile:
- ret, prjdir, err = command_out_stderr(
- f'{sys.executable} {elbe_exe} control create_project --retries 60 "{opt.xmlfile}"')
- if ret != 0:
+ ps = run_elbe(['control', 'create_project', '--retries', '60', opt.xmlfile],
+ capture_output=True, encoding='utf-8')
+ if ps.returncode != 0:
print('elbe control create_project failed.', file=sys.stderr)
- print(err, file=sys.stderr)
+ print(ps.stderr, file=sys.stderr)
print('Giving up', file=sys.stderr)
sys.exit(160)
- prjdir = prjdir.strip()
+ prjdir = ps.stdout.strip()
try:
system(f'{sys.executable} {elbe_exe} control build_pbuilder "{prjdir}"')
diff --git a/elbepack/shellhelper.py b/elbepack/shellhelper.py
index 483e6eacaebc..5449b8bea243 100644
--- a/elbepack/shellhelper.py
+++ b/elbepack/shellhelper.py
@@ -86,48 +86,6 @@ def command_out(cmd, stdin=None, output=PIPE, env_add=None):
return p.returncode, out
-def command_out_stderr(cmd, stdin=None, env_add=None):
- """command_out_stderr() - Execute cmd in a shell.
-
- Returns a tuple of the exitcode, stdout and stderr of cmd.
-
- --
-
- >>> command_out_stderr("$TRUE && cat -", stdin=b"ELBE", env_add={"TRUE":"true"})
- (0, 'ELBE', '')
-
- >>> command_out_stderr("1>&2 cat - && false", stdin=b"ELBE")
- (1, '', 'ELBE')
-
- >>> command_out_stderr("1>&2 cat - && false", stdin="ELBE")
- (1, '', 'ELBE')
-
- >>> command_out_stderr("true")
- (0, '', '')
-
- """
- new_env = os.environ.copy()
- if env_add:
- new_env.update(env_add)
-
- if isinstance(stdin, str):
- stdin = stdin.encode()
-
- if stdin is None:
- p = Popen(cmd, shell=True,
- stdout=PIPE, stderr=PIPE, env=new_env)
- output, stderr = p.communicate()
- else:
- p = Popen(cmd, shell=True,
- stdout=PIPE, stderr=PIPE, stdin=PIPE, env=new_env)
- output, stderr = p.communicate(input=stdin)
-
- output = TextIOWrapper(BytesIO(output), encoding='utf-8', errors='replace').read()
- stderr = TextIOWrapper(BytesIO(stderr), encoding='utf-8', errors='replace').read()
-
- return p.returncode, output, stderr
-
-
def do(cmd, allow_fail=False, stdin=None, env_add=None, log_cmd=None):
"""do() - Execute cmd in a shell and redirect outputs to logging.
diff --git a/elbepack/xmlpreprocess.py b/elbepack/xmlpreprocess.py
index 02d33383e82d..46bd8f157ee5 100644
--- a/elbepack/xmlpreprocess.py
+++ b/elbepack/xmlpreprocess.py
@@ -16,10 +16,9 @@ from urllib.request import urlopen
from elbepack.archivedir import ArchivedirError, combinearchivedir
from elbepack.config import cfg
-from elbepack.directories import elbe_exe
+from elbepack.directories import run_elbe
from elbepack.isooptions import iso_option_valid
from elbepack.schema import xml_schema_file
-from elbepack.shellhelper import command_out_stderr
from elbepack.validate import error_log_to_strings
from lxml import etree
@@ -421,22 +420,21 @@ class PreprocessWrapper:
def __init__(self, xmlfile, opt):
self.xmlfile = xmlfile
self.outxml = None
- self.options = ''
+ self.options = []
if opt.variant:
- self.options += f' --variants "{opt.variant}"'
+ self.options.extend(['--variants', opt.variant])
def __enter__(self):
fname = f'elbe-{time.time_ns()}.xml'
self.outxml = os.path.join(tempfile.gettempdir(), fname)
- cmd = (f'{sys.executable} {elbe_exe} preprocess {self.options} '
- f'-o {self.outxml} {self.xmlfile}')
- ret, _, err = command_out_stderr(cmd)
- if ret != 0:
+ ps = run_elbe(['preprocess', *self.options, '-o', self.outxml, self.xmlfile],
+ capture_output=True, encoding='utf-8')
+ if ps.returncode != 0:
print('elbe preprocess failed.', file=sys.stderr)
- print(err, file=sys.stderr)
- raise subprocess.CalledProcessError(ret, cmd)
+ print(ps.stderr, file=sys.stderr)
+ raise subprocess.CalledProcessError(ps.returncode, ps.args)
return self
--
2.44.0
More information about the elbe-devel
mailing list