import contextlib
import logging
import os
+import sys
import os.path
import shutil
import subprocess
"""No service file"""
pass
+class MountErrorException(Exception):
+ pass
+
+class UncleanExitException(Exception):
+ pass
+
+class ISUPkgCreateErrorException(Exception):
+ pass
+
+class NoISUConfigDirException(Exception):
+ pass
class Config:
def __init__(self):
logger.info(f"SUCCESS: ISU Package {pkg_result_name} created.")
except FileExistsError as e:
logger.error(f"ISU package \"{self._ctx.cfg.name}\" prepare error: {e}")
+ raise ISUPkgCreateErrorException()
def _clear(self):
logger.info(f"Remove {self._ctx.work_dir}")
return cfg
- def run(self):
- try:
- with Extractor(self._ctx) as extractor:
- with contextlib.ExitStack() as stack:
- mounts = {img_name: stack.enter_context(Mounter(img_path, self._ctx.tmp_dir))
- for (img_name, img_path) in extractor.images().items()}
-
- if any(m.failed() for m in mounts.values()):
- logger.error("Some error during mounts")
- return
-
- isu_on_rootfs = mounts['rootfs.img'].mnt_dir() / 'etc/isu'
- logger.info(f"Processing configs in {isu_on_rootfs}")
- for isudir in os.listdir(isu_on_rootfs):
- try:
- isudir_path = isu_on_rootfs / isudir
- isucfg_path = isudir_path / ISUSinglePkgMaker.ISU_CFG_FILE
- if isudir_path.is_dir() and isucfg_path.is_file():
- logger.info(f"\n=========\nProcess dir: {isudir}\n=========")
- cfg = self.load_config(isucfg_path)
- try:
- with ISUSinglePkgMaker(isudir_path, cfg, mounts, self._ctx) as isu_maker:
- isu_maker.make_pkg()
- except ISUNoServiceException as error:
- logger.warning(f"No service file ({error}) found for {cfg.name} package. Perhaps the file was deleted by security-config tests.")
- except InvalidConfigException as error:
- logger.error(f"Load isu.cfg error: {error}")
- logger.info(f"End of processing")
- except Exception as err:
- logger.error(f"Run error: {err}")
- traceback.print_exc()
+ def run(self, exit_on_any_error=False):
+ some_errors = False
+ with Extractor(self._ctx) as extractor:
+ with contextlib.ExitStack() as stack:
+ mounts = {img_name: stack.enter_context(Mounter(img_path, self._ctx.tmp_dir))
+ for (img_name, img_path) in extractor.images().items()}
+
+ if any(m.failed() for m in mounts.values()):
+ logger.error("Some error during mounts")
+ raise MountErrorException()
+
+ isu_on_rootfs = mounts['rootfs.img'].mnt_dir() / 'etc/isu'
+ logger.info(f"Processing configs in {isu_on_rootfs}")
+ if not isu_on_rootfs.is_dir():
+ logger.warning("No ISU config dir on the image.")
+ raise NoISUConfigDirException()
+ for isudir in os.listdir(isu_on_rootfs):
+ try:
+ isudir_path = isu_on_rootfs / isudir
+ isucfg_path = isudir_path / ISUSinglePkgMaker.ISU_CFG_FILE
+ if isudir_path.is_dir() and isucfg_path.is_file():
+ logger.info(f"\n=========\nProcess dir: {isudir}\n=========")
+ cfg = self.load_config(isucfg_path)
+ try:
+ with ISUSinglePkgMaker(isudir_path, cfg, mounts, self._ctx) as isu_maker:
+ isu_maker.make_pkg()
+ except ISUPkgCreateErrorException:
+ some_errors = True
+ if exit_on_any_error:
+ break
+ except ISUNoServiceException as error:
+ logger.warning(f"No service file ({error}) found for {cfg.name} package. Perhaps the file was deleted by security-config tests.")
+ some_errors = True
+ if exit_on_any_error:
+ break
+ except InvalidConfigException as error:
+ logger.error(f"Load isu.cfg error: {error}")
+ some_errors = True
+ if exit_on_any_error:
+ break
+ logger.info(f"End of processing")
+ if some_errors:
+ raise UncleanExitException()
def load_map(map_path: Path) -> FileMapper:
return FileMapper(map)
-def main():
+def main() -> int:
logger.info("Start")
try:
os.seteuid(getpwnam("nobody").pw_uid)
except PermissionError as error:
logger.error(f"seteuid() error: {error}")
- return
+ return os.EX_NOPERM
parser = argparse.ArgumentParser(description="ISU Pkgs maker")
parser.add_argument('--src', '-s', type=str, required=True,
help="Directory with images archive")
help="File with image<->path mapping")
parser.add_argument('--key', '-k', type=str, required=True,
help="Signing key")
+ parser.add_argument('--exit_on_any_error', '-e', action='store_true',
+ required=False, help="Terminate after any error")
args = parser.parse_args()
map = load_map(args.map)
- with TemporaryDirectory() as tmp_dir:
- with ISUPkgsMaker(Path(args.src), Path(tmp_dir), Path(args.out), Path(args.key), map) as isu_pkgs_maker:
- isu_pkgs_maker.run()
+ try:
+ with TemporaryDirectory() as tmp_dir:
+ with ISUPkgsMaker(Path(args.src),
+ Path(tmp_dir),
+ Path(args.out),
+ Path(args.key),
+ map) as isu_pkgs_maker:
+ isu_pkgs_maker.run(args.exit_on_any_error)
+ except NoISUConfigDirException:
+ return os.EX_OK
+ except MountErrorException:
+ return os.EX_IOERR
+ except UncleanExitException:
+ return os.EX_SOFTWARE
+ except Exception as err:
+ logger.error(f"Run error: {err}")
+ traceback.print_exc()
+ return os.EX_SOFTWARE
+
+ return os.EX_OK
if __name__ == '__main__':
- main()
+ code = main()
+ sys.exit(code)