f116d93
# -*- coding: utf-8 -*-
f116d93
f116d93
f116d93
# This program is free software; you can redistribute it and/or modify
f116d93
# it under the terms of the GNU General Public License as published by
f116d93
# the Free Software Foundation; version 2 of the License.
f116d93
#
f116d93
# This program is distributed in the hope that it will be useful,
f116d93
# but WITHOUT ANY WARRANTY; without even the implied warranty of
f116d93
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
f116d93
# GNU Library General Public License for more details.
f116d93
#
f116d93
# You should have received a copy of the GNU General Public License
f116d93
# along with this program; if not, write to the Free Software
f116d93
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
f116d93
f116d93
f116d93
import os
f116d93
import tempfile
f116d93
f116d93
from kobo.shortcuts import run
f116d93
07e90f0
from pungi.util import rmtree
07e90f0
from pungi.wrappers.pungi import PungiWrapper
f116d93
07e90f0
from pungi.arch import tree_arch_to_yum_arch
07e90f0
import pungi.phases.gather
f116d93
f116d93
07e90f0
import pungi.phases.gather.method
f116d93
f116d93
07e90f0
class GatherMethodDeps(pungi.phases.gather.method.GatherMethodBase):
f116d93
    enabled = True
f116d93
    config_options = (
f116d93
        {
f116d93
            "name": "gather_method",
f116d93
            "expected_types": [str],
f116d93
            "expected_values": ["deps"],
f116d93
        },
f116d93
        {
f116d93
            "name": "check_deps",
f116d93
            "expected_types": [bool],
f116d93
        },
f116d93
        {
f116d93
            "name": "gather_fulltree",
f116d93
            "expected_types": [bool],
f116d93
            "optional": True,
f116d93
        },
f116d93
        {
f116d93
            "name": "gather_selfhosting",
f116d93
            "expected_types": [bool],
f116d93
            "optional": True,
f116d93
        },
f116d93
    )
f116d93
f116d93
    def __call__(self, arch, variant, packages, groups, filter_packages, multilib_whitelist, multilib_blacklist, package_sets, path_prefix=None, fulltree_excludes=None, prepopulate=None):
f116d93
        # result = {
f116d93
        #     "rpm": [],
f116d93
        #     "srpm": [],
f116d93
        #     "debuginfo": [],
f116d93
        # }
f116d93
f116d93
        write_pungi_config(self.compose, arch, variant, packages, groups, filter_packages, multilib_whitelist, multilib_blacklist, package_set=package_sets[arch], fulltree_excludes=fulltree_excludes, prepopulate=prepopulate)
f116d93
        result = resolve_deps(self.compose, arch, variant)
f116d93
        check_deps(self.compose, arch, variant)
f116d93
        return result
f116d93
f116d93
f116d93
def write_pungi_config(compose, arch, variant, packages, groups, filter_packages, multilib_whitelist, multilib_blacklist, repos=None, comps_repo=None, package_set=None, fulltree_excludes=None, prepopulate=None):
f116d93
    """write pungi config (kickstart) for arch/variant"""
Adam Miller dc9cfff
    pungi_wrapper = PungiWrapper()
f116d93
    pungi_cfg = compose.paths.work.pungi_conf(variant=variant, arch=arch)
f116d93
    msg = "Writing pungi config (arch: %s, variant: %s): %s" % (arch, variant, pungi_cfg)
f116d93
f116d93
    if compose.DEBUG and os.path.isfile(pungi_cfg):
f116d93
        compose.log_warning("[SKIP ] %s" % msg)
f116d93
        return
f116d93
f116d93
    compose.log_info(msg)
f116d93
f116d93
    if not repos:
f116d93
        repo_path = compose.paths.work.arch_repo(arch=arch)
f116d93
        repos = {"pungi-repo": repo_path}
f116d93
f116d93
    lookaside_repos = {}
07e90f0
    for i, repo_url in enumerate(pungi.phases.gather.get_lookaside_repos(compose, arch, variant)):
f116d93
        lookaside_repos["lookaside-repo-%s" % i] = repo_url
f116d93
f116d93
    packages_str = []
f116d93
    for pkg_name, pkg_arch in sorted(packages):
f116d93
        if pkg_arch:
f116d93
            packages_str.append("%s.%s" % (pkg_name, pkg_arch))
f116d93
        else:
f116d93
            packages_str.append(pkg_name)
f116d93
f116d93
    filter_packages_str = []
f116d93
    for pkg_name, pkg_arch in sorted(filter_packages):
f116d93
        if pkg_arch:
f116d93
            filter_packages_str.append("%s.%s" % (pkg_name, pkg_arch))
f116d93
        else:
f116d93
            filter_packages_str.append(pkg_name)
f116d93
Adam Miller dc9cfff
    pungi_wrapper.write_kickstart(ks_path=pungi_cfg, repos=repos, groups=groups, packages=packages_str, exclude_packages=filter_packages_str, comps_repo=comps_repo, lookaside_repos=lookaside_repos, fulltree_excludes=fulltree_excludes, multilib_whitelist=multilib_whitelist, multilib_blacklist=multilib_blacklist, prepopulate=prepopulate)
f116d93
f116d93
f116d93
def resolve_deps(compose, arch, variant):
Adam Miller dc9cfff
    pungi_wrapper = PungiWrapper()
f116d93
    pungi_log = compose.paths.work.pungi_log(arch, variant)
f116d93
f116d93
    msg = "Running pungi (arch: %s, variant: %s)" % (arch, variant)
f116d93
    if compose.DEBUG and os.path.exists(pungi_log):
f116d93
        compose.log_warning("[SKIP ] %s" % msg)
Adam Miller dc9cfff
        return pungi_wrapper.get_packages(open(pungi_log, "r").read())
f116d93
f116d93
    compose.log_info("[BEGIN] %s" % msg)
f116d93
    pungi_conf = compose.paths.work.pungi_conf(arch, variant)
f116d93
f116d93
    multilib_methods = compose.conf.get("multilib_methods", None)
f116d93
    multilib_methods = compose.conf.get("multilib_methods", None)
f116d93
    is_multilib = arch in compose.conf["multilib_arches"]
f116d93
    if not is_multilib:
f116d93
        multilib_methods = None
f116d93
f116d93
    greedy_method = compose.conf.get("greedy_method", "none")
f116d93
f116d93
    # variant
f116d93
    fulltree = compose.conf.get("gather_fulltree", False)
f116d93
    selfhosting = compose.conf.get("gather_selfhosting", False)
f116d93
f116d93
    # optional
f116d93
    if variant.type == "optional":
f116d93
        fulltree = True
f116d93
        selfhosting = True
f116d93
f116d93
    # addon
f116d93
    if variant.type in ["addon", "layered-product"]:
f116d93
        # packages having SRPM in parent variant are excluded from fulltree (via %fulltree-excludes)
f116d93
        fulltree = True
f116d93
        selfhosting = False
f116d93
f116d93
    lookaside_repos = {}
07e90f0
    for i, repo_url in enumerate(pungi.phases.gather.get_lookaside_repos(compose, arch, variant)):
f116d93
        lookaside_repos["lookaside-repo-%s" % i] = repo_url
f116d93
f116d93
    yum_arch = tree_arch_to_yum_arch(arch)
f116d93
    tmp_dir = compose.paths.work.tmp_dir(arch, variant)
f116d93
    cache_dir = compose.paths.work.pungi_cache_dir(arch, variant)
Adam Miller dc9cfff
    cmd = pungi_wrapper.get_pungi_cmd(pungi_conf, destdir=tmp_dir, name=variant.uid, selfhosting=selfhosting, fulltree=fulltree, arch=yum_arch, full_archlist=True, greedy=greedy_method, cache_dir=cache_dir, lookaside_repos=lookaside_repos, multilib_methods=multilib_methods)
f116d93
    # Use temp working directory directory as workaround for
f116d93
    # https://bugzilla.redhat.com/show_bug.cgi?id=795137
f116d93
    tmp_dir = tempfile.mkdtemp(prefix="pungi_")
f116d93
    try:
f116d93
        run(cmd, logfile=pungi_log, show_cmd=True, workdir=tmp_dir)
f116d93
    finally:
f116d93
        rmtree(tmp_dir)
Adam Miller dc9cfff
    result = pungi_wrapper.get_packages(open(pungi_log, "r").read())
f116d93
f116d93
    compose.log_info("[DONE ] %s" % msg)
f116d93
    return result
f116d93
f116d93
f116d93
def check_deps(compose, arch, variant):
f116d93
    check_deps = compose.conf.get("check_deps", True)
f116d93
    if not check_deps:
f116d93
        return
f116d93
Adam Miller dc9cfff
    pungi_wrapper = PungiWrapper()
f116d93
    pungi_log = compose.paths.work.pungi_log(arch, variant)
Adam Miller dc9cfff
    missing_deps = pungi_wrapper.get_missing_deps(open(pungi_log, "r").read())
f116d93
    if missing_deps:
f116d93
        for pkg in sorted(missing_deps):
f116d93
            compose.log_error("Unresolved dependencies in package %s: %s" % (pkg, sorted(missing_deps[pkg])))
f116d93
        raise RuntimeError("Unresolved dependencies detected")