From bfc568121812c193c882ac0ece6c4bafc41c13f7 Mon Sep 17 00:00:00 2001 From: Nils Philippsen Date: Mar 06 2019 16:34:05 +0000 Subject: cope with non-x86_64 multilib The new util.arch package contains a function to emulate rpm.archscore, but for any machine architecture, not just the real one of the system being run on. This uses information extracted from /usr/lib/rpmrc etc. which is stored in config/arch-compat.yaml. --- diff --git a/_fedmod/_depchase.py b/_fedmod/_depchase.py index dd86929..daeac3b 100644 --- a/_fedmod/_depchase.py +++ b/_fedmod/_depchase.py @@ -11,7 +11,7 @@ import smartcols import solv from . import _repodata -from .util import parse_dataset_name +from .util import arch_score, parse_dataset_name log = logging.getLogger(__name__) @@ -295,14 +295,17 @@ def _get_rpm(pool, pkg): raise RuntimeError("Couldn't find package {}".format(pkg)) found = sel.solvables() - # Handle x86 32-bit vs 64-bit multilib packages - have_x86_64 = any(x.arch == "x86_64" for x in found) - have_i686 = any(x.arch == "i686" for x in found) - if have_x86_64 and have_i686: - found = [x for x in found if x.arch == "x86_64"] + # determine latest EVR in the found packages + found = sorted(found, key=functools.cmp_to_key(lambda a, b: b.evrcmp(a))) + latest_evr = found[0].evr - found = sorted(found, key=functools.cmp_to_key(lambda a, b: a.evrcmp(b))) - return found[0] + # filter for latest and arch-compatible + found = [f for f in found if f.evr == latest_evr and arch_score(f.arch)] + + # return the one package with the best matching architecture for multilib + return functools.reduce(lambda x, y: + x if arch_score(x.arch) < arch_score(y.arch) else y, + found) def get_srpm_for_rpm(pool, pkg): diff --git a/_fedmod/util/__init__.py b/_fedmod/util/__init__.py index d891ca0..1cb7f10 100644 --- a/_fedmod/util/__init__.py +++ b/_fedmod/util/__init__.py @@ -1,3 +1,4 @@ +from .arch import score as arch_score # noqa: F401 from .click import ChoiceGlob # noqa: F401 from .dataset import display_dataset_name, get_default_dataset # noqa: F401 from .dataset import parse_dataset_name # noqa: F401 diff --git a/_fedmod/util/arch.py b/_fedmod/util/arch.py new file mode 100644 index 0000000..2298dc3 --- /dev/null +++ b/_fedmod/util/arch.py @@ -0,0 +1,68 @@ +# -*- coding: utf-8 -*- +# +# util.arch - helper functionality for handling architectures +# +# Copyright © 2019 Red Hat, Inc. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# +# Author: +# Nils Philippsen + +from typing import Optional + +from .dataset import parse_dataset_name + + +config = None + + +def __score(arch, basearch, __seen): + if arch == basearch: + return 1 + + compat_arches = config.get('arch-compat', {}).get(basearch, []) + + # breadth-first + if arch in compat_arches: + return 2 + + # recurse + for compat_arch in compat_arches: + if compat_arch in __seen: + continue + + cscore = __score(arch, compat_arch, __seen=__seen) + if cscore: + return cscore + 1 + + +def score(arch: str, basearch: Optional[str] = None) -> Optional[int]: + """Compute a score how well an architecure fits on a base architecture. + + :param arch: name of the architecture + :param basearch: name of the base architecture or None (defaults to + architecture of the dataset) + + :returns: a score, the lower, the better, or None if it doesn't + match at all + """ + global config + if not config: + from ..config import config + + if not basearch: + release_name, basearch = parse_dataset_name() + + return __score(arch, basearch, {basearch}) diff --git a/config/arch-compat.yaml b/config/arch-compat.yaml new file mode 100644 index 0000000..fa0c6a8 --- /dev/null +++ b/config/arch-compat.yaml @@ -0,0 +1,94 @@ +document: fedmod-configuration +version: 1 +data: + arch-compat: + aarch64: [noarch] + alpha: [axp, noarch] + alphaev5: [alpha] + alphaev56: [alphaev5] + alphaev6: [alphapca56] + alphaev67: [alphaev6] + alphapca56: [alphaev56] + amd64: [x86_64, em64t, athlon, noarch] + armv3l: [noarch] + armv4b: [noarch] + armv4l: [armv3l] + armv4tl: [armv4l] + armv5tejl: [armv5tel] + armv5tel: [armv5tl] + armv5tl: [armv4tl] + armv6hl: [noarch] + armv6l: [armv5tejl] + armv7hl: [armv6hl] + armv7hnl: [armv7hl] + armv7l: [armv6l] + atariclone: [m68kmint, noarch] + atarist: [m68kmint, noarch] + atariste: [m68kmint, noarch] + ataritt: [m68kmint, noarch] + athlon: [i686] + falcon: [m68kmint, noarch] + geode: [i686] + hades: [m68kmint, noarch] + hppa1.0: [parisc] + hppa1.1: [hppa1.0] + hppa1.2: [hppa1.1] + hppa2.0: [hppa1.2] + i370: [noarch] + i386: [noarch, fat] + i486: [i386] + i586: [i486] + i686: [i586] + ia32e: [x86_64, em64t, athlon, noarch] + ia64: [noarch] + m68k: [noarch] + milan: [m68kmint, noarch] + mips: [noarch] + mips64: [mips] + mips64el: [mipsel] + mips64r6: [mipsr6] + mips64r6el: [mipsr6el] + mipsel: [noarch] + mipsr6: [noarch] + mipsr6el: [noarch] + osfmach3_i386: [i486] + osfmach3_i486: [i486, osfmach3_i386] + osfmach3_i586: [i586, osfmach3_i486] + osfmach3_i686: [i686, osfmach3_i586] + osfmach3_ppc: [ppc] + parisc: [noarch] + pentium3: [i686] + pentium4: [pentium3] + powerpc: [ppc] + powerppc: [ppc] + ppc: [rs6000] + ppc32dy4: [ppc] + ppc64: [ppc] + ppc64iseries: [ppc64] + ppc64le: [noarch, fat] + ppc64p7: [ppc64] + ppc64pseries: [ppc64] + ppc8260: [ppc] + ppc8560: [ppc] + ppciseries: [ppc] + ppcpseries: [ppc] + riscv: [noarch] + riscv64: [noarch] + rs6000: [noarch, fat] + s390: [noarch] + s390x: [s390, noarch] + sh3: [noarch] + sh4: [noarch] + sh4a: [sh4] + sparc: [noarch] + sparc64: [sparcv9] + sparc64v: [sparc64] + sparcv8: [sparc] + sparcv9: [sparcv8] + sparcv9v: [sparcv9] + sun4c: [sparc] + sun4d: [sparc] + sun4m: [sparc] + sun4u: [sparc64] + x86_64: [amd64, em64t, athlon, noarch] +