[elbe-devel] [PATCH 04/11] elbepack: replace custom CommandError with subprocess.CalledProcessError

Thomas Weißschuh thomas.weissschuh at linutronix.de
Wed Mar 13 16:54:53 CET 2024


The stdlib already has an equivalent of our custom error class.
This replacement also makes it possible to replace the custom execution helpers
with the suprocess module while preserving exception compatibility.

Signed-off-by: Thomas Weißschuh <thomas.weissschuh at linutronix.de>
---
 elbepack/cdroms.py                     |  5 ++--
 elbepack/commands/buildchroot.py       |  4 ++--
 elbepack/commands/check-build.py       |  7 +++---
 elbepack/commands/chroot.py            |  7 +++---
 elbepack/commands/fetch_initvm_pkgs.py |  7 +++---
 elbepack/debinstaller.py               |  7 +++---
 elbepack/efilesystem.py                | 10 ++++----
 elbepack/egpg.py                       |  5 ++--
 elbepack/elbeproject.py                |  5 ++--
 elbepack/finetuning.py                 |  7 +++---
 elbepack/fstab.py                      |  5 ++--
 elbepack/hashes.py                     |  7 +++---
 elbepack/hdimg.py                      | 11 +++++----
 elbepack/initvmaction.py               | 39 ++++++++++++++++---------------
 elbepack/packers.py                    |  7 +++---
 elbepack/pbuilderaction.py             | 31 +++++++++++++------------
 elbepack/repomanager.py                |  7 +++---
 elbepack/rfs.py                        | 11 +++++----
 elbepack/shellhelper.py                | 42 ++++++++++++----------------------
 elbepack/updated.py                    | 10 ++++----
 elbepack/xmlpreprocess.py              |  5 ++--
 21 files changed, 121 insertions(+), 118 deletions(-)

diff --git a/elbepack/cdroms.py b/elbepack/cdroms.py
index 6f225a35d732..7e318188b522 100644
--- a/elbepack/cdroms.py
+++ b/elbepack/cdroms.py
@@ -4,6 +4,7 @@
 
 import logging
 import os
+import subprocess
 from shutil import copyfile
 
 from apt.package import FetchError
@@ -14,7 +15,7 @@ from elbepack.filesystem import Filesystem, hostfs
 from elbepack.isooptions import get_iso_options
 from elbepack.repomanager import CdromBinRepo, CdromInitRepo, CdromSrcRepo
 from elbepack.rpcaptcache import get_rpcaptcache
-from elbepack.shellhelper import CommandError, do
+from elbepack.shellhelper import do
 
 CDROM_SIZE = 640 * 1000 * 1000
 
@@ -130,7 +131,7 @@ def mk_binary_cdrom(rfs, arch, codename, init_codename, xml, target):
     # not touch the repo config, nor generate a new key.
     try:
         do(f'cp -av /var/cache/elbe/initvm-bin-repo "{repo_path}"')
-    except CommandError:
+    except subprocess.CalledProcessError:
         # When /var/cache/elbe/initvm-bin-repo has not been created
         # (because the initvm install was an old version or somthing,
         #  log an error, and continue with an empty directory.
diff --git a/elbepack/commands/buildchroot.py b/elbepack/commands/buildchroot.py
index 98a7715e17db..45d0316294c4 100644
--- a/elbepack/commands/buildchroot.py
+++ b/elbepack/commands/buildchroot.py
@@ -4,6 +4,7 @@
 # SPDX-FileCopyrightText: 2015 Matthias Buehler <Matthias.Buehler at de.trumpf.com>
 
 import logging
+import subprocess
 import sys
 from optparse import OptionParser
 
@@ -12,7 +13,6 @@ from elbepack.db import ElbeDB
 from elbepack.elbeproject import ElbeProject
 from elbepack.elbexml import ValidationError
 from elbepack.log import elbe_logging
-from elbepack.shellhelper import CommandError
 
 from sqlalchemy.exc import OperationalError
 
@@ -97,7 +97,7 @@ def run_command(argv):
                 opt.cdrom_size,
                 opt.skip_pkglist,
                 opt.skip_pbuild)
-        except CommandError as ce:
+        except subprocess.CalledProcessError as ce:
             logging.error('Command in project build failed: %s', ce.cmd)
             sys.exit(29)
 
diff --git a/elbepack/commands/check-build.py b/elbepack/commands/check-build.py
index e17090ddbb28..39417f5bb91e 100644
--- a/elbepack/commands/check-build.py
+++ b/elbepack/commands/check-build.py
@@ -7,6 +7,7 @@ import logging
 import optparse
 import os
 import shutil
+import subprocess
 import sys
 import tempfile
 import traceback
@@ -15,7 +16,7 @@ from elbepack import qemu_firmware
 from elbepack.directories import elbe_exe
 from elbepack.filesystem import TmpdirFilesystem
 from elbepack.log import elbe_logging
-from elbepack.shellhelper import CommandError, command_out, do, get_command_out
+from elbepack.shellhelper import command_out, do, get_command_out
 from elbepack.treeutils import etree
 
 import pexpect
@@ -112,7 +113,7 @@ class CheckCdroms(CheckBase):
     def extract_cdrom(self, tgt, cdrom):
         try:
             do(f'7z x -o"{tgt}" "{cdrom}"')
-        except CommandError as E:
+        except subprocess.CalledProcessError as E:
             self.fail(f'Failed to extract cdrom {cdrom}:\n{E}')
 
     def dpkg_get_infos(self, path, fmt):
@@ -123,7 +124,7 @@ class CheckCdroms(CheckBase):
             elif path.endswith('.dsc'):
                 cmd = f'grep -E "^({"|".join(fmt)}):" {path}'
             return get_command_out(cmd).decode('utf-8')
-        except CommandError as E:
+        except subprocess.CalledProcessError as E:
             self.fail(
                 f"Failed to get debian infos ({'|'.join(fmt)}) "
                 f'for {path}:\n{E}')
diff --git a/elbepack/commands/chroot.py b/elbepack/commands/chroot.py
index 6fa9bc8a7a37..d16bd2d76fd3 100644
--- a/elbepack/commands/chroot.py
+++ b/elbepack/commands/chroot.py
@@ -4,13 +4,14 @@
 
 import logging
 import os
+import subprocess
 import sys
 from optparse import OptionParser
 
 from elbepack.elbeproject import ElbeProject
 from elbepack.elbexml import ValidationError, ValidationMode
 from elbepack.log import elbe_logging
-from elbepack.shellhelper import CommandError, system
+from elbepack.shellhelper import system
 
 
 def run_command(argv):
@@ -60,11 +61,11 @@ def run_command(argv):
             try:
                 with project.targetfs:
                     system(f'/usr/sbin/chroot {project.targetpath} {cmd}')
-            except CommandError as e:
+            except subprocess.CalledProcessError as e:
                 print(repr(e))
         else:
             try:
                 with project.buildenv:
                     system(f'/usr/sbin/chroot {project.chrootpath} {cmd}')
-            except CommandError as e:
+            except subprocess.CalledProcessError as e:
                 print(repr(e))
diff --git a/elbepack/commands/fetch_initvm_pkgs.py b/elbepack/commands/fetch_initvm_pkgs.py
index 6a67c04e9e3c..f9c874b177d0 100644
--- a/elbepack/commands/fetch_initvm_pkgs.py
+++ b/elbepack/commands/fetch_initvm_pkgs.py
@@ -3,6 +3,7 @@
 # SPDX-FileCopyrightText: 2018 Linutronix GmbH
 
 import logging
+import subprocess
 import sys
 from optparse import OptionParser
 
@@ -16,7 +17,7 @@ from elbepack.elbexml import ElbeXML, ValidationError
 from elbepack.filesystem import hostfs
 from elbepack.log import elbe_logging
 from elbepack.repomanager import CdromInitRepo, CdromSrcRepo
-from elbepack.shellhelper import CommandError, do
+from elbepack.shellhelper import do
 
 
 def run_command(argv):
@@ -125,7 +126,7 @@ def run_command(argv):
                         logging.exception('Package "%s" missing name or version',
                                           pkg_id)
                         retry = 3
-                    except CommandError:
+                    except subprocess.CalledProcessError:
                         logging.exception('Package "%s-%s" could not be added to repo.',
                                           pkg.name, pkgver.version)
                         retry += 1
@@ -169,7 +170,7 @@ def run_command(argv):
                         logging.exception('Package "%s" missing name or version',
                                           pkg_id)
                         retry = 3
-                    except CommandError:
+                    except subprocess.CalledProcessError:
                         logging.exception('Package "%s" could not be added to repo.',
                                           pkg_id)
                         retry += 1
diff --git a/elbepack/debinstaller.py b/elbepack/debinstaller.py
index 513a028d10bd..4e7493421e3e 100644
--- a/elbepack/debinstaller.py
+++ b/elbepack/debinstaller.py
@@ -4,6 +4,7 @@
 
 import os
 import re
+import subprocess
 import sys
 from shutil import copyfile
 from urllib.request import urlopen
@@ -11,7 +12,7 @@ from urllib.request import urlopen
 from elbepack.egpg import OverallStatus, check_signature
 from elbepack.filesystem import TmpdirFilesystem
 from elbepack.hashes import HashValidationFailed, HashValidator
-from elbepack.shellhelper import CommandError, system
+from elbepack.shellhelper import system
 
 from gpg import core
 from gpg.constants import PROTOCOL_OpenPGP
@@ -95,14 +96,14 @@ def setup_apt_keyring(gpg_home, keyring_fname):
             system(
                 f'gpg {gpg_options} '
                 f'--import "{os.path.join("/etc/apt/trusted.gpg.d", key)}"')
-        except CommandError:
+        except subprocess.CalledProcessError:
             print(f'adding keyring "{key}" to keyring "{ring_path}" failed')
 
 
 def download(url, local_fname):
     try:
         system(f'wget -O "{local_fname}" "{url}"')
-    except CommandError:
+    except subprocess.CalledProcessError:
         raise NoKinitrdException(f'Failed to download {url}')
 
 
diff --git a/elbepack/efilesystem.py b/elbepack/efilesystem.py
index 798316c60d8f..b97b36c8845a 100644
--- a/elbepack/efilesystem.py
+++ b/elbepack/efilesystem.py
@@ -15,7 +15,7 @@ from elbepack.fstab import fstabentry
 from elbepack.hdimg import do_hdimg
 from elbepack.licencexml import copyright_xml
 from elbepack.packers import default_packer
-from elbepack.shellhelper import CommandError, chroot, do, get_command_out, system
+from elbepack.shellhelper import chroot, do, get_command_out, system
 from elbepack.version import elbe_version
 
 
@@ -78,7 +78,7 @@ def copy_filelist(src, file_lst, dst):
                 system(
                     'cp -a --reflink=auto '
                     f'"{src.realpath(f)}" "{dst.realpath(f)}"')
-            except CommandError as E:
+            except subprocess.CalledProcessError as E:
                 logging.warning('Error while copying from %s to %s of file %s - %s',
                                 src.path, dst.path, f, E)
 
@@ -435,7 +435,7 @@ class TargetFs(ChRootFilesystem):
                 do(cmd % args)
                 # only append filename if creating tarball was successful
                 self.images.append(targz_name)
-            except CommandError:
+            except subprocess.CalledProcessError:
                 # error was logged; continue creating cpio image
                 pass
 
@@ -449,7 +449,7 @@ class TargetFs(ChRootFilesystem):
                     f'{os.path.join(targetdir, cpio_name)}')
                 # only append filename if creating cpio was successful
                 self.images.append(cpio_name)
-            except CommandError:
+            except subprocess.CalledProcessError:
                 # error was logged; continue
                 pass
             os.chdir(oldwd)
@@ -468,7 +468,7 @@ class TargetFs(ChRootFilesystem):
                     f'-noappend -no-progress {options}')
                 # only append filename if creating mksquashfs was successful
                 self.images.append(sfs_name)
-            except CommandError:
+            except subprocess.CalledProcessError:
                 # error was logged; continue
                 pass
             os.chdir(oldwd)
diff --git a/elbepack/egpg.py b/elbepack/egpg.py
index 31a234d1efef..1a8a01f06c34 100644
--- a/elbepack/egpg.py
+++ b/elbepack/egpg.py
@@ -4,9 +4,10 @@
 
 import logging
 import os
+import subprocess
 
 from elbepack.filesystem import hostfs
-from elbepack.shellhelper import CommandError, get_command_out, system
+from elbepack.shellhelper import get_command_out, system
 
 from gpg import core
 from gpg.constants import PROTOCOL_OpenPGP, sig, sigsum
@@ -288,7 +289,7 @@ def unarmor_openpgp_keyring(armored):
     """
     try:
         conv_cmd = get_command_out('/usr/bin/gpg --no-options --dearmor', stdin=armored)
-    except CommandError as e:
+    except subprocess.CalledProcessError as e:
         logging.error(e)
         return b''
 
diff --git a/elbepack/elbeproject.py b/elbepack/elbeproject.py
index b54971786205..e073c5b44dab 100644
--- a/elbepack/elbeproject.py
+++ b/elbepack/elbeproject.py
@@ -8,6 +8,7 @@ import glob
 import io
 import logging
 import os
+import subprocess
 import sys
 
 from elbepack.aptpkgutils import XMLPackage
@@ -33,7 +34,7 @@ from elbepack.pbuilder import (
 from elbepack.repomanager import ProjectRepo
 from elbepack.rfs import BuildEnv
 from elbepack.rpcaptcache import get_rpcaptcache
-from elbepack.shellhelper import CommandError, chroot, do, system
+from elbepack.shellhelper import chroot, do, system
 from elbepack.templates import write_pack_template
 
 validation = logging.getLogger('validation')
@@ -812,7 +813,7 @@ class ElbeProject:
                                            pbuilderdir,
                                            'result',
                                            '*.changes'))
-        except CommandError:
+        except subprocess.CalledProcessError:
             logging.exception('Package fails to build.\n'
                               'Please make sure, that the submitted package '
                               'builds in pbuilder')
diff --git a/elbepack/finetuning.py b/elbepack/finetuning.py
index ff54dd17633d..ddb67a37c681 100644
--- a/elbepack/finetuning.py
+++ b/elbepack/finetuning.py
@@ -6,6 +6,7 @@ import base64
 import errno
 import logging
 import os
+import subprocess
 from shutil import rmtree
 
 from apt.package import FetchError
@@ -15,7 +16,7 @@ from elbepack.filesystem import ImgMountFilesystem
 from elbepack.packers import default_packer, packers
 from elbepack.repomanager import UpdateRepo
 from elbepack.rpcaptcache import get_rpcaptcache
-from elbepack.shellhelper import CommandError, chroot, do, get_command_out
+from elbepack.shellhelper import chroot, do, get_command_out
 
 from gpg import core
 from gpg.constants import PROTOCOL_OpenPGP
@@ -736,7 +737,7 @@ def do_finetuning(xml, buildenv, target):
             logging.exception("Unimplemented finetuning action '%s'",
                               i.et.tag)
             raise
-        except CommandError as e:
+        except subprocess.CalledProcessError as e:
             logging.exception('Finetuning Error: %s', e)
             raise
         except FinetuningException as e:
@@ -756,7 +757,7 @@ def do_prj_finetuning(xml, buildenv, target, builddir):
         except KeyError:
             logging.exception("Unimplemented Project Finetuning action '%s'",
                               i.et.tag)
-        except CommandError as e:
+        except subprocess.CalledProcessError as e:
             logging.exception('Project Finetuning Error: %s', e)
             raise
         except FinetuningException as e:
diff --git a/elbepack/fstab.py b/elbepack/fstab.py
index 6d45be62a0ef..c3f181c5bc34 100644
--- a/elbepack/fstab.py
+++ b/elbepack/fstab.py
@@ -4,9 +4,10 @@
 # SPDX-FileCopyrightText: 2015 Matthias Buehler <matthias.buehler at de.trumpf.com>
 
 import os
+import subprocess
 import time
 
-from elbepack.shellhelper import CommandError, do, get_command_out
+from elbepack.shellhelper import do, get_command_out
 
 
 def get_mtdnum(xml, label):
@@ -96,7 +97,7 @@ class hdpart:
 
             try:
                 loopdev = get_command_out(cmd)
-            except CommandError as e:
+            except subprocess.CalledProcessError as e:
                 if e.returncode != 1:
                     raise
                 do('sync')
diff --git a/elbepack/hashes.py b/elbepack/hashes.py
index c7db890782d1..a1b5c1b9dc58 100644
--- a/elbepack/hashes.py
+++ b/elbepack/hashes.py
@@ -3,8 +3,9 @@
 # SPDX-FileCopyrightText: 2018 Linutronix GmbH
 
 import hashlib
+import subprocess
 
-from elbepack.shellhelper import CommandError, system
+from elbepack.shellhelper import system
 
 
 class HashValidationFailed(Exception):
@@ -45,7 +46,7 @@ class HashValidator:
         url = self.base_url + upstream_fname
         try:
             system(f'wget -O "{local_fname}" "{url}"')
-        except CommandError:
-            raise HashValidationFailed(f'Failed to download {url}')
+        except subprocess.CalledProcessError as e:
+            raise HashValidationFailed(f'Failed to download {url}') from e
 
         self.validate_file(upstream_fname, local_fname)
diff --git a/elbepack/hdimg.py b/elbepack/hdimg.py
index 5c976b2c8bee..1f1e93577d69 100644
--- a/elbepack/hdimg.py
+++ b/elbepack/hdimg.py
@@ -4,11 +4,12 @@
 
 import logging
 import os
+import subprocess
 from pathlib import Path
 
 from elbepack.filesystem import Filesystem, size_to_int
 from elbepack.fstab import fstabentry, hdpart, mountpoint_dict
-from elbepack.shellhelper import CommandError, chroot, do, get_command_out
+from elbepack.shellhelper import chroot, do, get_command_out
 
 import parted
 
@@ -46,7 +47,7 @@ def mkfs_mtd(mtd, fslabel, target):
                f'{fslabel[label].mkfsopt}')
             # only append the ubifs file if creation didn't fail
             img_files.append(f'{label}.ubifs')
-        except CommandError:
+        except subprocess.CalledProcessError:
             # continue creating further ubifs filesystems
             pass
 
@@ -117,7 +118,7 @@ def build_image_mtd(mtd, target):
         # only add file to list if ubinize command was successful
         img_files.append(mtd.text('name'))
 
-    except CommandError:
+    except subprocess.CalledProcessError:
         # continue with generating further images
         pass
 
@@ -197,7 +198,7 @@ class grubinstaller202(grubinstaller_base):
                     f'grub-install {user_args} --target=i386-pc '
                     f'--no-floppy {poopdev}')
 
-        except CommandError as E:
+        except subprocess.CalledProcessError as E:
             logging.error('Fail installing grub device: %s', E)
 
         finally:
@@ -271,7 +272,7 @@ class grubinstaller97(grubinstaller_base):
                 f'chroot {imagemnt} '
                 f'grub-install {user_args} --no-floppy {poopdev}')
 
-        except CommandError as E:
+        except subprocess.CalledProcessError as E:
             logging.error('Fail installing grub device: %s', E)
 
         finally:
diff --git a/elbepack/initvmaction.py b/elbepack/initvmaction.py
index 44fc3752783a..bd56682da991 100644
--- a/elbepack/initvmaction.py
+++ b/elbepack/initvmaction.py
@@ -6,6 +6,7 @@
 import datetime
 import io
 import os
+import subprocess
 import sys
 import time
 
@@ -15,7 +16,7 @@ from elbepack.directories import elbe_exe
 from elbepack.elbexml import ElbeXML, ValidationError, ValidationMode
 from elbepack.filesystem import TmpdirFilesystem
 from elbepack.repodir import Repodir, RepodirError
-from elbepack.shellhelper import CommandError, command_out_stderr, system
+from elbepack.shellhelper import command_out_stderr, system
 from elbepack.treeutils import etree
 from elbepack.xmlpreprocess import PreprocessWrapper
 
@@ -316,7 +317,7 @@ def submit_and_dl_result(xmlfile, cdrom, opt):
                 print(err, file=sys.stderr)
                 print('Giving up', file=sys.stderr)
                 sys.exit(129)
-    except CommandError:
+    except subprocess.CalledProcessError:
         # this is the failure from PreprocessWrapper
         # it already printed the error message from
         # elbe preprocess
@@ -331,7 +332,7 @@ def submit_and_dl_result(xmlfile, cdrom, opt):
         print('Uploading CDROM. This might take a while')
         try:
             system(f'{sys.executable} {elbe_exe} control set_cdrom "{prjdir}" "{cdrom}"')
-        except CommandError:
+        except subprocess.CalledProcessError:
             print('elbe control set_cdrom Failed', file=sys.stderr)
             print('Giving up', file=sys.stderr)
             sys.exit(131)
@@ -348,7 +349,7 @@ def submit_and_dl_result(xmlfile, cdrom, opt):
 
     try:
         system(f'{sys.executable} {elbe_exe} control build "{prjdir}" {build_opts}')
-    except CommandError:
+    except subprocess.CalledProcessError:
         print('elbe control build Failed', file=sys.stderr)
         print('Giving up', file=sys.stderr)
         sys.exit(132)
@@ -357,7 +358,7 @@ def submit_and_dl_result(xmlfile, cdrom, opt):
 
     try:
         system(f'{sys.executable} {elbe_exe} control wait_busy "{prjdir}"')
-    except CommandError:
+    except subprocess.CalledProcessError:
         print('elbe control wait_busy Failed', file=sys.stderr)
         print('', file=sys.stderr)
         print('The project will not be deleted from the initvm.',
@@ -382,7 +383,7 @@ def submit_and_dl_result(xmlfile, cdrom, opt):
     if opt.build_sdk:
         try:
             system(f'{sys.executable} {elbe_exe} control build_sdk "{prjdir}" {build_opts}')
-        except CommandError:
+        except subprocess.CalledProcessError:
             print('elbe control build_sdk Failed', file=sys.stderr)
             print('Giving up', file=sys.stderr)
             sys.exit(134)
@@ -391,7 +392,7 @@ def submit_and_dl_result(xmlfile, cdrom, opt):
 
         try:
             system(f'{sys.executable} {elbe_exe} control wait_busy "{prjdir}"')
-        except CommandError:
+        except subprocess.CalledProcessError:
             print('elbe control wait_busy Failed, while waiting for the SDK',
                   file=sys.stderr)
             print('', file=sys.stderr)
@@ -417,14 +418,14 @@ def submit_and_dl_result(xmlfile, cdrom, opt):
 
     try:
         system(f'{sys.executable} {elbe_exe} control dump_file "{prjdir}" validation.txt')
-    except CommandError:
+    except subprocess.CalledProcessError:
         print(
             'Project failed to generate validation.txt',
             file=sys.stderr)
         print('Getting log.txt', file=sys.stderr)
         try:
             system(f'{sys.executable} {elbe_exe} control dump_file "{prjdir}" log.txt')
-        except CommandError:
+        except subprocess.CalledProcessError:
 
             print('Failed to dump log.txt', file=sys.stderr)
             print('Giving up', file=sys.stderr)
@@ -436,7 +437,7 @@ def submit_and_dl_result(xmlfile, cdrom, opt):
         print('')
         try:
             system(f'{sys.executable} {elbe_exe} control get_files "{prjdir}"')
-        except CommandError:
+        except subprocess.CalledProcessError:
             print('elbe control get_files Failed', file=sys.stderr)
             print('Giving up', file=sys.stderr)
             sys.exit(137)
@@ -454,7 +455,7 @@ def submit_and_dl_result(xmlfile, cdrom, opt):
             system(
                 f'{sys.executable} {elbe_exe} control get_files --output "{opt.outdir}" '
                 f'"{prjdir}"')
-        except CommandError:
+        except subprocess.CalledProcessError:
             print('elbe control get_files Failed', file=sys.stderr)
             print('Giving up', file=sys.stderr)
             sys.exit(138)
@@ -462,7 +463,7 @@ def submit_and_dl_result(xmlfile, cdrom, opt):
         if not opt.keep_files:
             try:
                 system(f'{sys.executable} {elbe_exe} control del_project "{prjdir}"')
-            except CommandError:
+            except subprocess.CalledProcessError:
                 print('remove project from initvm failed',
                       file=sys.stderr)
                 sys.exit(139)
@@ -551,7 +552,7 @@ class CreateAction(InitVMAction):
                   'It may belong to an old elbe version. '
                   'Please stop it to prevent interfering with this version.', file=sys.stderr)
             sys.exit(143)
-        except CommandError:
+        except subprocess.CalledProcessError:
             pass
 
         # Init cdrom to None, if we detect it, we set it
@@ -612,7 +613,7 @@ class CreateAction(InitVMAction):
                         f'{sys.executable} {elbe_exe} init {init_opts} '
                         f'--directory "{initvmdir}" "{ppw.preproc}"')
 
-        except CommandError:
+        except subprocess.CalledProcessError:
             print("'elbe init' Failed", file=sys.stderr)
             print('Giving up', file=sys.stderr)
             sys.exit(145)
@@ -624,7 +625,7 @@ class CreateAction(InitVMAction):
         # Register initvm in libvirt
         try:
             self.conn.defineXML(xml)
-        except CommandError:
+        except subprocess.CalledProcessError:
             print('Registering initvm in libvirt failed', file=sys.stderr)
             print(f"Try `virsh --connect qemu:///system undefine {cfg['initvm_domain']}`"
                   'to delete existing initvm',
@@ -634,14 +635,14 @@ class CreateAction(InitVMAction):
         # Build initvm
         try:
             system(f'cd "{initvmdir}"; make')
-        except CommandError:
+        except subprocess.CalledProcessError:
             print('Building the initvm Failed', file=sys.stderr)
             print('Giving up', file=sys.stderr)
             sys.exit(147)
 
         try:
             system(f'{sys.executable} {elbe_exe} initvm start')
-        except CommandError:
+        except subprocess.CalledProcessError:
             print('Starting the initvm Failed', file=sys.stderr)
             print('Giving up', file=sys.stderr)
             sys.exit(148)
@@ -677,7 +678,7 @@ class SubmitAction(InitVMAction):
     def execute(self, _initvmdir, opt, args):
         try:
             system(f'{sys.executable} {elbe_exe} initvm ensure')
-        except CommandError:
+        except subprocess.CalledProcessError:
             print('Starting the initvm Failed', file=sys.stderr)
             print('Giving up', file=sys.stderr)
             sys.exit(150)
@@ -719,5 +720,5 @@ class SyncAction(InitVMAction):
                    "--exclude='examples' "
                    f"--rsh='ssh -p {cfg['sshport']}' --chown=root:root "
                    f'{top_dir}/ root at localhost:/var/cache/elbe/devel')
-        except CommandError as E:
+        except subprocess.CalledProcessError as E:
             print(E)
diff --git a/elbepack/packers.py b/elbepack/packers.py
index 308074bb52bf..8b56ede7db31 100644
--- a/elbepack/packers.py
+++ b/elbepack/packers.py
@@ -3,8 +3,9 @@
 # SPDX-FileCopyrightText: 2019 Linutronix GmbH
 
 import os
+import subprocess
 
-from elbepack.shellhelper import CommandError, do
+from elbepack.shellhelper import do
 
 
 class Packer:
@@ -30,7 +31,7 @@ class InPlacePacker(Packer):
         try:
             fpath = os.path.join(builddir, fname)
             do(f'{self.cmd} "{fpath}"')
-        except CommandError:
+        except subprocess.CalledProcessError:
             # in case of an error, we just return None
             # which means, that the orig file does not
             # exist anymore
@@ -55,7 +56,7 @@ class TarArchiver(Packer):
                 f'tar --create --verbose --sparse {self.flag} '
                 f'--file "{archname}" --directory "{dirname}" "{basename}"')
             do(f'rm -f "{fpath}"')
-        except CommandError:
+        except subprocess.CalledProcessError:
             # in case of an error, we just return None
             # which means, that the orig file does not
             # exist anymore.
diff --git a/elbepack/pbuilderaction.py b/elbepack/pbuilderaction.py
index 73fef07870a9..908db86fbd64 100644
--- a/elbepack/pbuilderaction.py
+++ b/elbepack/pbuilderaction.py
@@ -3,11 +3,12 @@
 # SPDX-FileCopyrightText: 2015-2017 Linutronix GmbH
 
 import os
+import subprocess
 import sys
 
 from elbepack.directories import elbe_exe
 from elbepack.filesystem import TmpdirFilesystem
-from elbepack.shellhelper import CommandError, command_out_stderr, system
+from elbepack.shellhelper import command_out_stderr, system
 from elbepack.xmlpreprocess import PreprocessWrapper
 
 
@@ -94,7 +95,7 @@ class CreateAction(PBuilderAction):
                         print(err, file=sys.stderr)
                         print('Giving up', file=sys.stderr)
                         sys.exit(153)
-            except CommandError:
+            except subprocess.CalledProcessError:
                 # this is the failure from PreprocessWrapper
                 # it already printed the error message from
                 # elbe preprocess
@@ -117,14 +118,14 @@ class CreateAction(PBuilderAction):
         try:
             system(f'{sys.executable} {elbe_exe} control '
                    f'build_pbuilder "{prjdir}" {crossopt} {ccacheopt} {ccachesize}')
-        except CommandError:
+        except subprocess.CalledProcessError:
             print('elbe control build_pbuilder Failed', file=sys.stderr)
             print('Giving up', file=sys.stderr)
             sys.exit(156)
 
         try:
             system(f'{sys.executable} {elbe_exe} control wait_busy "{prjdir}"')
-        except CommandError:
+        except subprocess.CalledProcessError:
             print('elbe control wait_busy Failed', file=sys.stderr)
             print('Giving up', file=sys.stderr)
             sys.exit(157)
@@ -156,7 +157,7 @@ class UpdateAction(PBuilderAction):
 
         try:
             system(f'{sys.executable} {elbe_exe} control update_pbuilder "{prjdir}"')
-        except CommandError:
+        except subprocess.CalledProcessError:
             print('elbe control update_pbuilder Failed', file=sys.stderr)
             print('Giving up', file=sys.stderr)
             sys.exit(159)
@@ -196,14 +197,14 @@ class BuildAction(PBuilderAction):
 
             try:
                 system(f'{sys.executable} {elbe_exe} control build_pbuilder "{prjdir}"')
-            except CommandError:
+            except subprocess.CalledProcessError:
                 print('elbe control build_pbuilder Failed', file=sys.stderr)
                 print('Giving up', file=sys.stderr)
                 sys.exit(161)
 
             try:
                 system(f'{sys.executable} {elbe_exe} control wait_busy "{prjdir}"')
-            except CommandError:
+            except subprocess.CalledProcessError:
                 print('elbe control wait_busy Failed', file=sys.stderr)
                 print('Giving up', file=sys.stderr)
                 sys.exit(162)
@@ -225,7 +226,7 @@ class BuildAction(PBuilderAction):
         print('')
         try:
             system(f'tar cfz "{tmp.fname("pdebuild.tar.gz")}" .')
-        except CommandError:
+        except subprocess.CalledProcessError:
             print('tar Failed', file=sys.stderr)
             print('Giving up', file=sys.stderr)
             sys.exit(164)
@@ -237,7 +238,7 @@ class BuildAction(PBuilderAction):
             try:
                 system(
                     f'{sys.executable} {elbe_exe} control set_orig "{prjdir}" "{of}"')
-            except CommandError:
+            except subprocess.CalledProcessError:
                 print('elbe control set_orig Failed', file=sys.stderr)
                 print('Giving up', file=sys.stderr)
                 sys.exit(165)
@@ -251,13 +252,13 @@ class BuildAction(PBuilderAction):
                 f'{sys.executable} {elbe_exe} control set_pdebuild --cpuset "{opt.cpuset}" '
                 f'--profile "{opt.profile}" {crossopt} '
                 f'"{prjdir}" "{tmp.fname("pdebuild.tar.gz")}"')
-        except CommandError:
+        except subprocess.CalledProcessError:
             print('elbe control set_pdebuild Failed', file=sys.stderr)
             print('Giving up', file=sys.stderr)
             sys.exit(166)
         try:
             system(f'{sys.executable} {elbe_exe} control wait_busy "{prjdir}"')
-        except CommandError:
+        except subprocess.CalledProcessError:
             print('elbe control wait_busy Failed', file=sys.stderr)
             print('Giving up', file=sys.stderr)
             sys.exit(167)
@@ -272,14 +273,14 @@ class BuildAction(PBuilderAction):
             try:
                 system(
                     f'{sys.executable} {elbe_exe} control --pbuilder-only get_files "{prjdir}"')
-            except CommandError:
+            except subprocess.CalledProcessError:
                 print('elbe control get_files Failed', file=sys.stderr)
                 print('', file=sys.stderr)
                 print('dumping logfile', file=sys.stderr)
 
                 try:
                     system(f'{sys.executable} {elbe_exe} control dump_file "{prjdir}" log.txt')
-                except CommandError:
+                except subprocess.CalledProcessError:
                     print('elbe control dump_file Failed', file=sys.stderr)
                     print('', file=sys.stderr)
                     print('Giving up', file=sys.stderr)
@@ -299,14 +300,14 @@ class BuildAction(PBuilderAction):
                 system(
                     f'{sys.executable} {elbe_exe} control --pbuilder-only get_files '
                     f'--output "{opt.outdir}" "{prjdir}"')
-            except CommandError:
+            except subprocess.CalledProcessError:
                 print('elbe control get_files Failed', file=sys.stderr)
                 print('', file=sys.stderr)
                 print('dumping logfile', file=sys.stderr)
 
                 try:
                     system(f'{sys.executable} {elbe_exe} control dump_file "{prjdir}" log.txt')
-                except CommandError:
+                except subprocess.CalledProcessError:
                     print('elbe control dump_file Failed', file=sys.stderr)
                     print('', file=sys.stderr)
                     print('Giving up', file=sys.stderr)
diff --git a/elbepack/repomanager.py b/elbepack/repomanager.py
index a1604f03e627..9e617374dd0e 100644
--- a/elbepack/repomanager.py
+++ b/elbepack/repomanager.py
@@ -3,13 +3,14 @@
 # SPDX-FileCopyrightText: 2014-2017 Linutronix GmbH
 
 import os
+import subprocess
 
 from debian.deb822 import Deb822
 
 from elbepack.egpg import export_key, generate_elbe_internal_key, unlock_key
 from elbepack.filesystem import Filesystem
 from elbepack.pkgutils import get_dsc_size
-from elbepack.shellhelper import CommandError, do
+from elbepack.shellhelper import do
 
 
 class RepoAttributes:
@@ -195,7 +196,7 @@ class RepoBase:
             self._includedeb(path, self.repo_attr.codename,
                              components=components,
                              prio=prio)
-        except CommandError as ce:
+        except subprocess.CalledProcessError as ce:
             if force and pkgname is not None:
                 # Including deb did not work.
                 # Maybe we have the same Version with a
@@ -310,7 +311,7 @@ class RepoBase:
     def includedsc(self, path, components=None, force=False):
         try:
             self._includedsc(path, self.repo_attr.codename, components)
-        except CommandError as ce:
+        except subprocess.CalledProcessError as ce:
             if force:
                 # Including dsc did not work.
                 # Maybe we have the same Version with a
diff --git a/elbepack/rfs.py b/elbepack/rfs.py
index 3485e21d2049..b3476f965639 100644
--- a/elbepack/rfs.py
+++ b/elbepack/rfs.py
@@ -5,11 +5,12 @@
 
 import logging
 import os
+import subprocess
 from urllib.parse import urlsplit
 
 from elbepack.efilesystem import BuildImgFs
 from elbepack.egpg import unarmor_openpgp_keyring
-from elbepack.shellhelper import CommandError, chroot, do, get_command_out
+from elbepack.shellhelper import chroot, do, get_command_out
 from elbepack.templates import get_preseed, preseed_to_text, write_pack_template
 
 
@@ -203,9 +204,9 @@ class BuildEnv:
                 if keyring:
                     self.convert_asc_to_gpg('/cdrom/targetrepo/repo.pub', '/elbe.keyring')
                 do(cmd)
-            except CommandError:
+            except subprocess.CalledProcessError as e:
                 cleanup = True
-                raise DebootstrapException()
+                raise DebootstrapException() from e
             finally:
                 self.cdrom_umount()
                 if cleanup:
@@ -245,9 +246,9 @@ class BuildEnv:
 
             chroot(self.rfs.path, 'dpkg --configure -a')
 
-        except CommandError:
+        except subprocess.CalledProcessError as e:
             cleanup = True
-            raise DebootstrapException()
+            raise DebootstrapException() from e
         finally:
             self.cdrom_umount()
             if cleanup:
diff --git a/elbepack/shellhelper.py b/elbepack/shellhelper.py
index 5abd3c078fa3..02d8fdae220d 100644
--- a/elbepack/shellhelper.py
+++ b/elbepack/shellhelper.py
@@ -5,8 +5,9 @@
 
 import logging
 import os
+import subprocess
 from io import BytesIO, TextIOWrapper
-from subprocess import PIPE, Popen, STDOUT, call
+from subprocess import PIPE, Popen, STDOUT
 
 from elbepack.log import async_logging_ctx
 
@@ -14,21 +15,10 @@ log = logging.getLogger('log')
 soap = logging.getLogger('soap')
 
 
-class CommandError(Exception):
-
-    def __init__(self, cmd, returncode):
-        super(CommandError, self).__init__(cmd, returncode)
-        self.returncode = returncode
-        self.cmd = cmd
-
-    def __str__(self):
-        return f'Error: {self.returncode} returned from Command {self.cmd}'
-
-
 def system(cmd, allow_fail=False, env_add=None):
     """system() - Execute cmd in a shell.
 
-    Throws a CommandError if cmd returns none-zero and allow_fail=False
+    Throws a subprocess.CalledProcessError if cmd returns none-zero and allow_fail=False
 
     --
 
@@ -39,18 +29,14 @@ def system(cmd, allow_fail=False, env_add=None):
     >>> system("$FALSE", env_add={"FALSE":"false"}) # doctest: +ELLIPSIS
     Traceback (most recent call last):
     ...
-    elbepack.shellhelper.CommandError: ...
+    subprocess.CalledProcessError: ...
 
     """
     new_env = os.environ.copy()
     if env_add:
         new_env.update(env_add)
 
-    ret = call(cmd, shell=True, env=new_env)
-
-    if ret != 0:
-        if not allow_fail:
-            raise CommandError(cmd, ret)
+    subprocess.run(cmd, shell=True, env=new_env, check=not allow_fail)
 
 
 def command_out(cmd, stdin=None, output=PIPE, env_add=None):
@@ -111,7 +97,7 @@ def system_out(cmd, stdin=None, allow_fail=False, env_add=None):
     >>> system_out("false") # doctest: +ELLIPSIS
     Traceback (most recent call last):
     ...
-    elbepack.shellhelper.CommandError: ...
+    subprocess.CalledProcessError: ...
 
     >>> system_out("false", allow_fail=True)
     ''
@@ -121,7 +107,7 @@ def system_out(cmd, stdin=None, allow_fail=False, env_add=None):
 
     if code != 0:
         if not allow_fail:
-            raise CommandError(cmd, code)
+            raise subprocess.CalledProcessError(code, cmd)
 
     return out
 
@@ -171,7 +157,7 @@ def command_out_stderr(cmd, stdin=None, env_add=None):
 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.
 
-    Throws a CommandError if cmd failed with allow_Fail=False.
+    Throws a subprocess.CalledProcessError if cmd returns none-zero and allow_fail=False
 
     --
 
@@ -192,12 +178,12 @@ def do(cmd, allow_fail=False, stdin=None, env_add=None, log_cmd=None):
     >>> do("cat - && false", stdin=b"ELBE") # doctest: +ELLIPSIS
     Traceback (most recent call last):
     ...
-    elbepack.shellhelper.CommandError: ...
+    subprocess.CalledProcessError: ...
 
     >>> do("false") # doctest: +ELLIPSIS
     Traceback (most recent call last):
     ...
-    elbepack.shellhelper.CommandError: ...
+    subprocess.CalledProcessError: ...
     """
 
     new_env = os.environ.copy()
@@ -220,7 +206,7 @@ def do(cmd, allow_fail=False, stdin=None, env_add=None, log_cmd=None):
         p.communicate(input=stdin)
 
     if p.returncode and not allow_fail:
-        raise CommandError(cmd, p.returncode)
+        raise subprocess.CalledProcessError(p.returncode, cmd)
 
 
 def chroot(directory, cmd, env_add=None, **kwargs):
@@ -237,7 +223,7 @@ def chroot(directory, cmd, env_add=None, **kwargs):
     >>> chroot("/", "true") # doctest: +ELLIPSIS
     Traceback (most recent call last):
     ...
-    elbepack.shellhelper.CommandError: ...
+    subprocess.CalledProcessError: ...
     """
 
     new_env = {'LANG': 'C',
@@ -265,7 +251,7 @@ def get_command_out(cmd, stdin=None, allow_fail=False, env_add=None):
     >>> get_command_out("false") # doctest: +ELLIPSIS
     Traceback (most recent call last):
     ...
-    elbepack.shellhelper.CommandError: ...
+    subprocess.CalledProcessError: ...
 
     >>> get_command_out("false", allow_fail=True)
     b''
@@ -298,6 +284,6 @@ def get_command_out(cmd, stdin=None, allow_fail=False, env_add=None):
         stdout, _ = p.communicate(input=stdin)
 
     if p.returncode and not allow_fail:
-        raise CommandError(cmd, p.returncode)
+        raise subprocess.CalledProcessError(p.returncode, cmd)
 
     return stdout
diff --git a/elbepack/updated.py b/elbepack/updated.py
index c0a32a5c2f71..203b5831ca83 100644
--- a/elbepack/updated.py
+++ b/elbepack/updated.py
@@ -24,7 +24,7 @@ from elbepack.aptprogress import (
 )
 from elbepack.config import cfg
 from elbepack.egpg import unsign_file
-from elbepack.shellhelper import CommandError, system
+from elbepack.shellhelper import system
 from elbepack.treeutils import etree
 
 from packaging import version
@@ -173,7 +173,7 @@ class rw_access:
             self.status.log(f'remount {self.mount} read/writeable')
             try:
                 system(f'mount -o remount,rw {self.mount}')
-            except CommandError as e:
+            except subprocess.CalledProcessError as e:
                 self.status.log(repr(e))
 
     def __exit__(self, _typ, _value, _traceback):
@@ -181,11 +181,11 @@ class rw_access:
             self.status.log(f'remount {self.mount} readonly')
             try:
                 system('sync')
-            except CommandError as e:
+            except subprocess.CalledProcessError as e:
                 self.status.log(repr(e))
             try:
                 system(f'mount -o remount,ro {self.mount}')
-            except CommandError as e:
+            except subprocess.CalledProcessError as e:
                 self.status.log(repr(e))
 
     def get_mount_status(self):
@@ -429,7 +429,7 @@ def apply_update(fname, status):
         # is locked. We currently don't understand this behaviour :(
         try:
             system('apt-get clean')
-        except CommandError as e:
+        except subprocess.CalledProcessError as e:
             status.log(repr(e))
         if p.exitcode != 0:
             raise Exception(
diff --git a/elbepack/xmlpreprocess.py b/elbepack/xmlpreprocess.py
index 8f25fc384a89..02d33383e82d 100644
--- a/elbepack/xmlpreprocess.py
+++ b/elbepack/xmlpreprocess.py
@@ -5,6 +5,7 @@
 import logging
 import os
 import re
+import subprocess
 import sys
 import tempfile
 import time
@@ -18,7 +19,7 @@ from elbepack.config import cfg
 from elbepack.directories import elbe_exe
 from elbepack.isooptions import iso_option_valid
 from elbepack.schema import xml_schema_file
-from elbepack.shellhelper import CommandError, command_out_stderr
+from elbepack.shellhelper import command_out_stderr
 from elbepack.validate import error_log_to_strings
 
 from lxml import etree
@@ -435,7 +436,7 @@ class PreprocessWrapper:
         if ret != 0:
             print('elbe preprocess failed.', file=sys.stderr)
             print(err, file=sys.stderr)
-            raise CommandError(cmd, ret)
+            raise subprocess.CalledProcessError(ret, cmd)
 
         return self
 

-- 
2.44.0



More information about the elbe-devel mailing list