Source code for benchbuild.utils.container

"""
Container utilites.
"""
import os
import logging
from benchbuild.settings import CFG
from benchbuild.utils.cmd import cp, mkdir, bash, rm, curl, tail, cut
from benchbuild.utils.downloader import Wget
from plumbum import local, TF

LOG = logging.getLogger(__name__)


[docs]def cached(func): ret = None def call_or_cache(*args, **kwargs): nonlocal ret if ret is None: ret = func(*args, **kwargs) return ret return call_or_cache
[docs]def is_valid_container(container, path): """ Checks if a container exists and is unpacked. Args: path: The location where the container is expected. Returns: True if the container is valid, False if the container needs to unpacked or if the path does not exist yet. """ try: tmp_hash_path = container.filename + ".hash" with open(tmp_hash_path, 'r') as tmp_file: tmp_hash = tmp_file.readline() except IOError: LOG.info("No .hash-file in the tmp-directory.") container_hash_path = os.path.abspath(os.path.join(path, "gentoo.tar.bz2.hash")) if not os.path.exists(container_hash_path): return False else: with open(container_hash_path, 'r') as hash_file: container_hash = hash_file.readline() return container_hash == tmp_hash
[docs]def unpack_container(container, path): """ Unpack a container usable by uchroot. Method that checks if a directory for the container exists, checks if erlent support is needed and then unpacks the container accordingly. Args: path: The location where the container is, that needs to be unpacked. """ from benchbuild.utils.run import run, uchroot_no_args path = os.path.abspath(path) name = os.path.basename(os.path.abspath(container.filename)) if not os.path.exists(path): mkdir("-p", path) with local.cwd(path): Wget(container.remote, name) uchroot = uchroot_no_args() uchroot = uchroot["-E", "-A", "-C", "-r", "/", "-w", os.path.abspath("."), "--"] # Check, if we need erlent support for this archive. has_erlent = bash[ "-c", "tar --list -f './{0}' | grep --silent '.erlent'".format( name)] has_erlent = (has_erlent & TF) cmd = local["/bin/tar"]["xf"] if not has_erlent: cmd = uchroot[cmd["./" + name]] else: cmd = cmd[name] run(cmd["--exclude=dev/*"]) if not os.path.samefile(name, container.filename): rm(name) else: LOG.warning("File contents do not match: %s != %s", name, container.filename) cp(container.filename + ".hash", path)
[docs]class Container(object): name = "container" @property def remote(self): pass @property def filename(self): image_cfg = CFG["container"]["images"].value() image_cfg = image_cfg[self.name] if os.path.isabs(image_cfg): return image_cfg else: return os.path.join(CFG["tmp_dir"].value(), image_cfg) @property def local(self): """ Finds the current location of a container. Also unpacks the project if necessary. Returns: target: The path, where the container lies in the end. """ from benchbuild.settings import CFG assert self.name in CFG["container"]["images"].value() target = os.path.join(CFG["tmp_dir"].value(), self.name) if not os.path.exists(target) or not is_valid_container(self, target): unpack_container(self, target) return target
[docs]class Gentoo(Container): name = "gentoo"
[docs] @cached def latest_src_uri(self): """ Get the latest src_uri for a stage 3 tarball. Returns (str): Latest src_uri from gentoo's distfiles mirror. """ from plumbum import ProcessExecutionError latest_txt = "http://distfiles.gentoo.org/releases/amd64/autobuilds/"\ "latest-stage3-amd64.txt" try: src_uri = (curl[latest_txt] | tail["-n", "+3"] | cut["-f1", "-d "])().strip() except ProcessExecutionError as proc_ex: src_uri = "NOT-FOUND" LOG.error( "Could not determine latest stage3 src uri: %s", str(proc_ex)) return src_uri
@property def remote(self): """Get a remote URL of the requested container.""" return "http://distfiles.gentoo.org/releases/amd64/autobuilds/{0}" \ .format(self.latest_src_uri())
[docs]class Ubuntu(Container): name = "ubuntu" @property def remote(self): """Get a remote URL of the requested container.""" pass