Source code for benchbuild.utils.uchroot

import enum
import logging

from plumbum.commands import ProcessExecutionError
from plumbum import local, FG

from benchbuild.settings import CFG
from benchbuild.utils import path, run

LOG = logging.getLogger(__name__)


[docs]def uchroot(*args, **kwargs): """ Return a customizable uchroot command. Args: args: List of additional arguments for uchroot (typical: mounts) Return: chroot_cmd """ uchroot_cmd = with_mounts(*args, uchroot_cmd_fn=no_llvm, **kwargs) return uchroot_cmd["--"]
def __default_opts__(uid=0, gid=0): return [ "-C", "-w", "/", "-r", local.cwd, "-u", str(uid), "-g", str(gid), "-E", "-A" ]
[docs]def no_llvm(*args, uid=0, gid=0, **kwargs): """ Return a customizable uchroot command. The command will be executed inside a uchroot environment. Args: args: List of additional arguments for uchroot (typical: mounts) Return: chroot_cmd """ uchroot_cmd = no_args() uchroot_cmd = uchroot_cmd[__default_opts__(uid, gid)] return uchroot_cmd[args]
[docs]def no_args(**kwargs): """Return the uchroot command without any customizations.""" from benchbuild.utils.cmd import uchroot as uchrt prefixes = CFG["container"]["prefixes"].value p_paths, p_libs = env(prefixes) uchrt = run.with_env_recursive( uchrt, LD_LIBRARY_PATH=path.list_to_path(p_libs), PATH=path.list_to_path(p_paths)) return uchrt
[docs]def with_mounts(*args, uchroot_cmd_fn=no_args, **kwargs): """Return a uchroot command with all mounts enabled.""" mounts = CFG["container"]["mounts"].value prefixes = CFG["container"]["prefixes"].value uchroot_opts, mounts = __mounts__("mnt", mounts) uchroot_cmd = uchroot_cmd_fn(**kwargs) uchroot_cmd = uchroot_cmd[uchroot_opts] uchroot_cmd = uchroot_cmd[args] paths, libs = env(mounts) prefix_paths, prefix_libs = env(prefixes) uchroot_cmd = run.with_env_recursive( uchroot_cmd, LD_LIBRARY_PATH=path.list_to_path(libs + prefix_libs), PATH=path.list_to_path(paths + prefix_paths)) return uchroot_cmd
[docs]class UchrootEC(enum.Enum): MNT_FAILED = 255 MNT_PROC_FAILED = 254 MNT_DEV_FAILED = 253 MNT_SYS_FAILED = 252 MNT_PTS_FAILED = 251
[docs]def retry(pb_cmd, retries=0, max_retries=10, retcode=0, retry_retcodes=None): try: pb_cmd & FG(retcode=retcode) except ProcessExecutionError as proc_ex: new_retcode = proc_ex.retcode if retries > max_retries: LOG.error("Retried %d times. No change. Abort", retries) raise if new_retcode in retry_retcodes: retry( pb_cmd, retries=retries + 1, max_retries=max_retries, retcode=retcode, retry_retcodes=retry_retcodes) else: raise
[docs]def uretry(cmd, retcode=0): retry( cmd, retcode=retcode, retry_retcodes=[ UchrootEC.MNT_PROC_FAILED.value, UchrootEC.MNT_DEV_FAILED.value, UchrootEC.MNT_SYS_FAILED.value, UchrootEC.MNT_PTS_FAILED.value ])
[docs]def clean_env(uchroot_cmd, varnames): """Returns a uchroot cmd that runs inside a filtered environment.""" env = uchroot_cmd["/usr/bin/env"] __clean_env = env["-u", ",".join(varnames)] return __clean_env
[docs]def mounts(prefix, __mounts): """ Compute the mountpoints of the current user. Args: prefix: Define where the job was running if it ran on a cluster. mounts: All mounts the user currently uses in his file system. Return: mntpoints """ i = 0 mntpoints = [] for mount in __mounts: if not isinstance(mount, dict): mntpoint = "{0}/{1}".format(prefix, str(i)) mntpoints.append(mntpoint) i = i + 1 return mntpoints
def __mounts__(prefix, _mounts): i = 0 mntpoints = [] uchroot_opts = [] for mount in _mounts: if isinstance(mount, dict): src_mount = mount["src"] tgt_mount = mount["tgt"] else: src_mount = mount tgt_mount = "{0}/{1}".format(prefix, str(i)) i = i + 1 path.mkdir_uchroot(tgt_mount) uchroot_opts.extend(["-M", "{0}:{1}".format(src_mount, tgt_mount)]) mntpoints.append(tgt_mount) return uchroot_opts, mntpoints
[docs]def env(mounts): """ Compute the environment of the change root for the user. Args: mounts: The mountpoints of the current user. Return: paths ld_libs """ f_mounts = [m.strip("/") for m in mounts] root = local.path("/") ld_libs = [root / m / "lib" for m in f_mounts] ld_libs.extend([root / m / "lib64" for m in f_mounts]) paths = [root / m / "bin" for m in f_mounts] paths.extend([root / m / "sbin" for m in f_mounts]) paths.extend([root / m for m in f_mounts]) return paths, ld_libs