def archive_tmpfile(arch_elem):
    fp = NamedTemporaryFile()
    fp.write(standard_b64decode(arch_elem))
    fp.file.flush()
    return fp def get_rpcaptcache(rfs, arch,
                    notifier=None, norecommend=False, noauth=True):

    # pylint: disable=too-many-arguments

    mm = MyMan()
    mm.start()

    # Disable false positive, because pylint can not
    # see the creation of MyMan.RPCAPTCache by
    # MyMan.register()
    #
    # pylint: disable=no-member
    return mm.RPCAPTCache(rfs, arch, notifier, norecommend, noauth) class CdromSrcRepo(RepoBase):
    def __init__(self, codename, init_codename, path, maxsize,
                 mirror='http://ftp.debian.org/debian'):

        # pylint: disable=too-many-arguments

        repo_attrs = RepoAttributes(codename,
                                    "source",
                                    ["main",
                                     "added",
                                     "target",
                                     "chroot",
                                     "sysroot-host"],
                                    mirror)

        if init_codename is not None:
            init_attrs = RepoAttributes(init_codename,
                                        "source",
                                        ["initvm"],
                                        mirror)
        else:
            init_attrs = None

        RepoBase.__init__(self,
                          path,
                          init_attrs,
                          repo_attrs,
                          "Elbe",
                          "Elbe Source Cdrom Repo",
                          maxsize) class CdromBinRepo(RepoBase):
    def __init__(
            self,
            arch,
            codename,
            init_codename,
            path,
            mirror='http://ftp.debian.org/debian'):

        # pylint: disable=too-many-arguments

        repo_attrs = RepoAttributes(codename, arch, ["main", "added"], mirror)
        if init_codename is not None:
            init_attrs = RepoAttributes(
                init_codename, "amd64", [
                    "main", "main/debian-installer"], mirror)
        else:
            init_attrs = None

        RepoBase.__init__(self,
                          path,
                          init_attrs,
                          repo_attrs,
                          "Elbe",
                          "Elbe Binary Cdrom Repo") class CdromInitRepo(RepoBase):
    def __init__(self, init_codename, path,
                 mirror='http://ftp.de.debian.org/debian'):

        # pylint: disable=too-many-arguments

        init_attrs = RepoAttributes(
            init_codename, "amd64", [
                "main", "main/debian-installer"], mirror)

        RepoBase.__init__(self,
                          path,
                          None,
                          init_attrs,
                          "Elbe",
                          "Elbe InitVM Cdrom Repo") class XMLPackage(PackageBase):
    def __init__(self, node, arch):
        PackageBase.__init__(self, node.et.text,
                             node.et.get('version'), None,
                             node.et.get('md5'), None,
                             node.et.get('prio'), None,
                             INSTALLED, node.et.get('auto') == 'true',
                             None, arch) def size_to_int(size):
    def __init__(self, path, clean=False):
    def fname(self, path):
    def open(self, path, mode="r"):
    def open_gz(self, path, mode="r"):
    def isdir(self, path):
    def islink(self, path):
    def isfile(self, path):
    def exists(self, path):
    def lexists(self, path):
    def mkdir(self, path):
    def readlink(self, path):
    def realpath(self, path):
    def symlink(self, src, path, allow_exists=False):
    def stat(self, path):
    def chown(self, path, uid, gid):
    def chmod(self, path, mode):
    def utime(self, path, times=None):
    def cat_file(self, inf):
    def remove(self, path, noerr=False):
    def rmtree(self, path):
    def listdir(self, path='', ignore=None, skiplinks=False):
    def glob(self, path):
    def _write_file(path, f, cont, mode):
    def write_file(self, path, mode, cont):
    def append_file(self, path, cont, mode=None):
    def read_file(self, path, gz=False):
    def mkdir_p(self, newdir, mode=0o755):
    def touch_file(self, fname):
    def walk_files(self, directory='', exclude_dirs=None):
    def mtime_snap(self, dirname='', exclude_dirs=None):
    def __disk_usage(self, directory):
    def disk_usage(self, dirname=''):
    def __init__(self, debug=False):
    def __del__(self):
    def delete(self):
    def __enter__(self):
    def __exit__(self, exec_type, exec_value, tb):
    def __init__(self, mntpoint, dev):
    def __enter__(self):
    def __exit__(self, typ, value, traceback):
class Filesystem:
class TmpdirFilesystem (Filesystem):
class ImgMountFilesystem(Filesystem): class CommandError(Exception):

    def __init__(self, cmd, returncode):
        super(CommandError, self).__init__(cmd, returncode)
        self.returncode = returncode
        self.cmd = cmd

    def __str__(self):
        return "Error: %d returned from Command %s" % (
            self.returncode, self.cmd) def do(cmd, allow_fail=False, stdin=None, env_add=None):
    """do() - Execute cmd in a shell and redirect outputs to logging.

    Throws a CommandError if cmd failed with allow_Fail=False.

    --

    Let's redirect the loggers to current stdout
    >>> import sys
    >>> from elbepack.log import open_logging
    >>> open_logging({"streams":sys.stdout})

    >>> do("true")
    [CMD] true

    >>> do("false", allow_fail=True)
    [CMD] false

    >>> do("cat -", stdin=b"ELBE")
    [CMD] cat -

    >>> do("cat - && false", stdin=b"ELBE") # doctest: +ELLIPSIS
    Traceback (most recent call last):
    ...
    elbepack.shellhelper.CommandError: ...

    >>> do("false") # doctest: +ELLIPSIS
    Traceback (most recent call last):
    ...
    elbepack.shellhelper.CommandError: ...
    """

    new_env = os.environ.copy()
    if env_add:
        new_env.update(env_add)

    if isinstance(stdin, str):
        stdin = stdin.encode()

    logging.info(cmd, extra={"context":"[CMD] "})

    r, w = os.pipe()

    if stdin is None:
        p = Popen(cmd, shell=True, stdout=w, stderr=STDOUT, env=new_env)
    else:
        p = Popen(cmd, shell=True, stdin=PIPE, stdout=w, stderr=STDOUT, env=new_env)

    async_logging(r, w, soap, log)
    p.communicate(input=stdin)

    if p.returncode and not allow_fail:
        raise CommandError(cmd, p.returncode) def get_iso_options(xml):
    options = []
    src_opts = xml.node("src-cdrom/src-opts")
    if src_opts is None:
        return ""
    for node in src_opts:
        if node.tag not in iso_options:
            continue
        option = iso_options[node.tag]
        logging.info("Adding option %s\n%s", node.tag, option[2])
        text = node.et.text[:option[1]]
        options.append('%s "%s"' % (option[0], text.replace('"', '\\"')))
    return " ".join(options)
import os
import logging
from shutil import copyfile
from apt.package import FetchError
from elbepack.archivedir import archive_tmpfile
from elbepack.rpcaptcache import get_rpcaptcache
from elbepack.repomanager import CdromSrcRepo
from elbepack.repomanager import CdromBinRepo
from elbepack.repomanager import CdromInitRepo
from elbepack.aptpkgutils import XMLPackage
from elbepack.filesystem import Filesystem, hostfs
from elbepack.shellhelper import CommandError, do
from elbepack.isooptions import get_iso_options
# ELBE - Debian Based Embedded Rootfilesystem Builder
# Copyright (c) 2014-2016 Torben Hohn <torben.hohn@linutronix.de>
# Copyright (c) 2014-2015, 2017 Manuel Traut <manut@linutronix.de>
# Copyright (c) 2016 John Ogness <john.ogness@linutronix.de>
# Copyright (c) 2017 Philipp Arras <philipp.arras@linutronix.de>
#
# SPDX-License-Identifier: GPL-3.0-or-later





CDROM_SIZE = 640 * 1000 * 1000

# pylint: disable=too-many-arguments
def add_source_pkg(repo, component, cache, pkg, version, forbid):
    if pkg in forbid:
        return
    pkg_id = "%s-%s" % (pkg, version)
    try:
        dsc = cache.download_source(pkg,
                                    version,
                                    '/var/cache/elbe/sources')
        repo.includedsc(dsc, components=component, force=True)
    except ValueError as e:
        logging.error("No sources for package '%s': %s", pkg_id, str(e))
    except FetchError as e:
        logging.error("Source for package '%s' could not be downloaded: %s", pkg_id, str(e))

def mk_source_cdrom(components, codename,
                    init_codename, target,
                    cdrom_size=CDROM_SIZE, xml=None,
                    mirror='http://ftp.de.debian.org/debian'):

    # pylint: disable=too-many-arguments
    # pylint: disable=too-many-locals
    # pylint: disable=too-many-branches

    hostfs.mkdir_p('/var/cache/elbe/sources')

    forbiddenPackages = []
    if xml is not None and xml.has('target/pkg-list'):
        for i in xml.node('target/pkg-list'):
            try:
                if i.tag == 'pkg' and i.et.attrib['on_src_cd'] == 'False':
                    forbiddenPackages.append(i.text('.').strip())
            except KeyError:
                pass

    repos = {}

    for component in components.keys():
        rfs, cache, pkg_lst = components[component]
        logging.info("Adding %s component", component)
        rfs.mkdir_p("/var/cache/elbe/sources")

        repo = CdromSrcRepo(codename, init_codename,