From 1cf5696bf99c2acf0120620ff6bba1330d0b7ee3 Mon Sep 17 00:00:00 2001 From: Andrew Lukoshko Date: Wed, 8 Apr 2026 14:20:41 +0000 Subject: [PATCH] Add OCI platform support for x86_64 sub-architecture containers Add cache_key option to yum_cache plugin for shared package cache across configs --- ...platform-support-for-x86_64-sub-arch.patch | 234 +++++++++++++++ ...d-cache-key-for-shared-package-cache.patch | 267 ++++++++++++++++++ SPECS/mock.spec | 13 +- 3 files changed, 512 insertions(+), 2 deletions(-) create mode 100644 SOURCES/1000-add-oci-platform-support-for-x86_64-sub-arch.patch create mode 100644 SOURCES/1001-yum-cache-add-cache-key-for-shared-package-cache.patch diff --git a/SOURCES/1000-add-oci-platform-support-for-x86_64-sub-arch.patch b/SOURCES/1000-add-oci-platform-support-for-x86_64-sub-arch.patch new file mode 100644 index 0000000..1778ac3 --- /dev/null +++ b/SOURCES/1000-add-oci-platform-support-for-x86_64-sub-arch.patch @@ -0,0 +1,234 @@ +From f18ddbae4f900b54b3e2c3abe8270cf37f889e33 Mon Sep 17 00:00:00 2001 +From: Andrew Lukoshko +Date: Mon, 6 Apr 2026 19:12:45 +0200 +Subject: [PATCH 1/2] feat: add OCI platform support for x86_64 + sub-architecture containers + +Add oci_platform_map config dict mapping x86_64_v2/v3/v4 to OCI +platform strings (linux/amd64/v2, v3, v4). + +When target_arch has a mapping, podman pull receives --platform so +the correct image variant is fetched from multi-arch manifests. + +Preserve target repo_arch for bootstrap chroot when target_arch has +an oci_platform_map entry, so the bootstrap uses the correct +sub-architecture repos instead of falling back to the base arch. + +Includes 7 unit tests covering platform injection, architecture +check, and error paths. + +Fixes: #1732 +--- + py/mock.py | 8 +- + py/mockbuild/config.py | 7 + + py/mockbuild/podman.py | 7 +- + tests/test_podman.py | 130 ++++++++++++++++++ + .../oci-platform-sub-arch.feature.md | 5 + + 5 files changed, 155 insertions(+), 2 deletions(-) + create mode 100644 tests/test_podman.py + create mode 100644 releng/release-notes-next/oci-platform-sub-arch.feature.md + +diff --git a/py/mock.py b/py/mock.py +index 270043611..0ed4b746a 100755 +--- a/py/mock.py ++++ b/py/mock.py +@@ -773,8 +773,14 @@ def main(): + # Enforce host-native repo architecture for bootstrap chroot (unless + # bootstrap_forcearch=True, which should never be the case). This + # decision affects condPersonality() for DNF calls! ++ # ++ # Exception: sub-architecture variants (e.g. x86_64_v2) listed in ++ # oci_platform_map run natively on the host — keep the target's ++ # repo_arch so the bootstrap uses the correct sub-arch repos. + host_arch = config_opts["host_arch"] +- if config_opts["use_bootstrap_image"]: ++ target_arch = config_opts["target_arch"] ++ if config_opts["use_bootstrap_image"] \ ++ and target_arch not in config_opts.get('oci_platform_map', {}): + # with bootstrap image, bootstrap is always native + bootstrap_buildroot_config['repo_arch'] = config_opts['repo_arch_map'].get(host_arch, host_arch) + elif host_arch not in config_opts.get("legal_host_arches", []) \ +diff --git a/py/mockbuild/config.py b/py/mockbuild/config.py +index 34244fa45..cc80cec84 100644 +--- a/py/mockbuild/config.py ++++ b/py/mockbuild/config.py +@@ -429,6 +429,13 @@ def setup_default_config_opts(): + 'i686': 'i386', + } + ++ # mapping from target_arch to OCI --platform string for podman pull ++ config_opts['oci_platform_map'] = { ++ 'x86_64_v2': 'linux/amd64/v2', ++ 'x86_64_v3': 'linux/amd64/v3', ++ 'x86_64_v4': 'linux/amd64/v4', ++ } ++ + config_opts["recursion_limit"] = 5000 + + config_opts["calculatedeps"] = None +diff --git a/py/mockbuild/podman.py b/py/mockbuild/podman.py +index 286d5fae3..67369534a 100644 +--- a/py/mockbuild/podman.py ++++ b/py/mockbuild/podman.py +@@ -117,7 +117,12 @@ def pull_image(self): + """ pull the latest image, return True if successful """ + logger = getLog() + logger.info("Pulling image: %s", self.image) +- cmd = [self.podman_binary, "pull", self.image] ++ cmd = [self.podman_binary, "pull"] ++ target_arch = self.buildroot.config.get('target_arch', '') ++ oci_platform = self.buildroot.config.get('oci_platform_map', {}).get(target_arch) ++ if oci_platform: ++ cmd += ["--platform", oci_platform] ++ cmd.append(self.image) + + res = subprocess.run(cmd, env=self.buildroot.env, + stdout=subprocess.PIPE, stderr=subprocess.PIPE, +diff --git a/tests/test_podman.py b/tests/test_podman.py +new file mode 100644 +index 000000000..ec2187cc8 +--- /dev/null ++++ b/tests/test_podman.py +@@ -0,0 +1,130 @@ ++# -*- coding: utf-8 -*- ++"""Unit tests for mockbuild.podman — OCI platform pull and architecture check.""" ++ ++import subprocess ++from unittest.mock import MagicMock, patch ++ ++from mockbuild.podman import ( ++ Podman, ++ podman_check_native_image_architecture, ++) ++ ++ ++# --------------------------------------------------------------------------- ++# Helpers ++# --------------------------------------------------------------------------- ++ ++def _make_buildroot(target_arch, oci_platform_map=None): ++ """Return a minimal mock buildroot with the given config values.""" ++ config = {"target_arch": target_arch} ++ if oci_platform_map is not None: ++ config["oci_platform_map"] = oci_platform_map ++ br = MagicMock() ++ br.config = config ++ br.env = {} ++ return br ++ ++ ++def _make_podman(buildroot, image="registry.example.com/image:latest"): ++ """Instantiate Podman while bypassing the os.path.exists check.""" ++ with patch("os.path.exists", return_value=True): ++ return Podman(buildroot, image) ++ ++ ++# =================================================================== ++# R002 — pull_image injects --platform when mapping matches ++# =================================================================== ++ ++class TestPullImagePlatform: ++ """pull_image() must inject --platform from oci_platform_map.""" ++ ++ @patch("mockbuild.podman.subprocess.run") ++ def test_platform_injected_when_mapped(self, mock_run): ++ """--platform linux/amd64/v2 appears when target_arch is x86_64_v2.""" ++ mock_run.return_value = MagicMock(returncode=0, stdout=b"sha256:abc") ++ br = _make_buildroot( ++ "x86_64_v2", ++ oci_platform_map={"x86_64_v2": "linux/amd64/v2"}, ++ ) ++ pod = _make_podman(br) ++ assert pod.pull_image() is True ++ ++ cmd = mock_run.call_args[0][0] ++ assert "--platform" in cmd ++ plat_idx = cmd.index("--platform") ++ assert cmd[plat_idx + 1] == "linux/amd64/v2" ++ # --platform must precede image name ++ assert plat_idx < cmd.index("registry.example.com/image:latest") ++ ++ @patch("mockbuild.podman.subprocess.run") ++ def test_no_platform_when_arch_not_in_map(self, mock_run): ++ """--platform absent when target_arch has no mapping entry.""" ++ mock_run.return_value = MagicMock(returncode=0, stdout=b"sha256:abc") ++ br = _make_buildroot( ++ "x86_64", ++ oci_platform_map={"x86_64_v2": "linux/amd64/v2"}, ++ ) ++ pod = _make_podman(br) ++ assert pod.pull_image() is True ++ ++ cmd = mock_run.call_args[0][0] ++ assert "--platform" not in cmd ++ ++ @patch("mockbuild.podman.subprocess.run") ++ def test_no_platform_when_map_missing(self, mock_run): ++ """--platform absent when oci_platform_map key is missing entirely.""" ++ mock_run.return_value = MagicMock(returncode=0, stdout=b"sha256:def") ++ br = _make_buildroot("x86_64") # no oci_platform_map ++ pod = _make_podman(br) ++ assert pod.pull_image() is True ++ ++ cmd = mock_run.call_args[0][0] ++ assert "--platform" not in cmd ++ ++ @patch("mockbuild.podman.subprocess.run") ++ def test_empty_target_arch(self, mock_run): ++ """Empty target_arch string never produces --platform.""" ++ mock_run.return_value = MagicMock(returncode=0, stdout=b"sha256:ghi") ++ br = _make_buildroot( ++ "", ++ oci_platform_map={"x86_64_v2": "linux/amd64/v2"}, ++ ) ++ pod = _make_podman(br) ++ assert pod.pull_image() is True ++ ++ cmd = mock_run.call_args[0][0] ++ assert "--platform" not in cmd ++ ++ ++# =================================================================== ++# R003 — podman_check_native_image_architecture ++# =================================================================== ++ ++class TestArchCheck: ++ """Architecture check compares system vs image os/arch.""" ++ ++ @patch("mockbuild.podman.subprocess.check_output") ++ def test_matching_arch_returns_true(self, mock_co): ++ """Matching system and image arch returns True.""" ++ mock_co.side_effect = ["linux/amd64", "linux/amd64"] ++ assert podman_check_native_image_architecture("img:latest") is True ++ ++ @patch("mockbuild.podman.subprocess.check_output") ++ def test_mismatched_arch_returns_false(self, mock_co): ++ """Mismatched system and image arch returns False.""" ++ mock_co.side_effect = ["linux/amd64", "linux/arm64"] ++ assert podman_check_native_image_architecture("img:latest") is False ++ ++ ++# =================================================================== ++# Negative / boundary tests ++# =================================================================== ++ ++class TestArchCheckErrorPaths: ++ """Error handling in architecture check.""" ++ ++ @patch("mockbuild.podman.subprocess.check_output") ++ def test_subprocess_error_returns_false(self, mock_co): ++ """SubprocessError during check returns False (existing behavior).""" ++ mock_co.side_effect = subprocess.SubprocessError("fail") ++ assert podman_check_native_image_architecture("img:latest") is False +diff --git a/releng/release-notes-next/oci-platform-sub-arch.feature.md b/releng/release-notes-next/oci-platform-sub-arch.feature.md +new file mode 100644 +index 000000000..0dc976c3a +--- /dev/null ++++ b/releng/release-notes-next/oci-platform-sub-arch.feature.md +@@ -0,0 +1,5 @@ ++Podman container image pulls now pass `--platform` for x86_64 ++sub-architecture variants (x86_64_v2, x86_64_v3, x86_64_v4). A new ++`oci_platform_map` config option maps target architectures to OCI platform ++strings (e.g. `linux/amd64/v2`), and the architecture check accepts ++variant images on a matching base host. + diff --git a/SOURCES/1001-yum-cache-add-cache-key-for-shared-package-cache.patch b/SOURCES/1001-yum-cache-add-cache-key-for-shared-package-cache.patch new file mode 100644 index 0000000..9fbf116 --- /dev/null +++ b/SOURCES/1001-yum-cache-add-cache-key-for-shared-package-cache.patch @@ -0,0 +1,267 @@ +From 38842ed9678d974309d879907d1f05fe211e539b Mon Sep 17 00:00:00 2001 +From: Andrew Lukoshko +Date: Wed, 8 Apr 2026 01:49:00 +0200 +Subject: [PATCH] yum_cache: add cache_key option for shared package cache + across configs + +When cache_key is set in yum_cache_opts, the plugin redirects the +dnf/yum cache bind mounts and lock file to a shared directory at +/yum_cache// instead of the per-config +buildroot.cachedir. This allows multiple mock configs with different +root names but the same cache_key to share cached RPM packages and +repo metadata, avoiding redundant downloads. + +Without cache_key the behavior is identical to the original plugin. + +Usage in mock config: + config_opts['plugin_conf']['yum_cache_opts']['cache_key'] = 'almalinux-kitten-10-x86_64' + +The shared cache directory is not removed by --scrub=all (which only +cleans per-root caches), matching the design intent that shared caches +are host-level resources. +--- + py/mockbuild/plugins/yum_cache.py | 25 +++- + tests/plugins/test_yum_cache.py | 181 +++++++++++++++++++++++++ + 2 files changed, 200 insertions(+), 6 deletions(-) + create mode 100644 tests/plugins/test_yum_cache.py + +diff --git a/py/mockbuild/plugins/yum_cache.py b/py/mockbuild/plugins/yum_cache.py +index c732b439f..1e8aec494 100644 +--- a/py/mockbuild/plugins/yum_cache.py ++++ b/py/mockbuild/plugins/yum_cache.py +@@ -26,11 +26,12 @@ def init(plugins, conf, buildroot): + + + class CacheDir: +- def __init__(self, buildroot, pkg_manager): ++ def __init__(self, buildroot, pkg_manager, cache_dir=None): + self.buildroot = buildroot + self.cache_path = os.path.join('/var/cache', pkg_manager) +- self.host_cache_path = os.path.join(self.buildroot.cachedir, +- pkg_manager + '_cache') ++ self.host_cache_path = os.path.join( ++ cache_dir if cache_dir else self.buildroot.cachedir, ++ pkg_manager + '_cache') + self.mount_path = self.buildroot.make_chroot_path(self.cache_path) + self.buildroot.mounts.add(BindMountPoint( + srcpath=self.host_cache_path, +@@ -56,9 +57,21 @@ def __init__(self, plugins, conf, buildroot): + self.config = buildroot.config + self.state = buildroot.state + self.yum_cache_opts = conf ++ ++ cache_key = conf.get('cache_key') ++ if cache_key: ++ cache_topdir = self.config['cache_topdir'] ++ cache_dir = os.path.join(cache_topdir, 'yum_cache', cache_key) ++ mockbuild.file_util.mkdirIfAbsent(cache_dir) ++ lock_dir = cache_dir ++ getLog().info("enabled package manager cache (shared, key=%s)", cache_key) ++ else: ++ cache_dir = None ++ lock_dir = buildroot.cachedir ++ + self.cache_dirs = [ +- CacheDir(buildroot, 'yum'), +- CacheDir(buildroot, 'dnf'), ++ CacheDir(buildroot, 'yum', cache_dir), ++ CacheDir(buildroot, 'dnf', cache_dir), + ] + self.yumSharedCachePath = self.cache_dirs[0].host_cache_path + self.online = self.config['online'] +@@ -66,7 +79,7 @@ def __init__(self, plugins, conf, buildroot): + plugins.add_hook("postyum", self._yumCachePostYumHook) + plugins.add_hook("preinit", self._yumCachePreInitHook) + +- self.yumCacheLock = open(os.path.join(buildroot.cachedir, "yumcache.lock"), "a+") ++ self.yumCacheLock = open(os.path.join(lock_dir, "yumcache.lock"), "a+") + + + # ============= +diff --git a/tests/plugins/test_yum_cache.py b/tests/plugins/test_yum_cache.py +new file mode 100644 +index 000000000..a6aba45d0 +--- /dev/null ++++ b/tests/plugins/test_yum_cache.py +@@ -0,0 +1,181 @@ ++"""Unit tests for the yum_cache plugin cache_key shared-cache feature.""" ++ ++from copy import deepcopy ++from unittest import mock ++from unittest.mock import MagicMock, patch ++ ++from mockbuild.plugins import yum_cache ++ ++ ++# --------------------------------------------------------------------------- ++# Helpers ++# --------------------------------------------------------------------------- ++ ++DEFAULT_CONF = { ++ 'max_age_days': 30, ++ 'max_metadata_age_days': 0.5, ++} ++ ++ ++def make_buildroot(extra_config=None): ++ br = MagicMock() ++ br.config = { ++ 'cache_topdir': '/var/cache/mock', ++ 'online': False, ++ 'target_arch': 'x86_64', ++ } ++ if extra_config: ++ br.config.update(extra_config) ++ br.make_chroot_path.side_effect = lambda p: '/chroot' + p ++ return br ++ ++ ++# --------------------------------------------------------------------------- ++# init() entry point ++# --------------------------------------------------------------------------- ++ ++@patch('mockbuild.plugins.yum_cache.YumCache') ++def test_init(MockYumCache): ++ plugins, conf, buildroot = object(), object(), object() ++ yum_cache.init(plugins, conf, buildroot) ++ MockYumCache.assert_called_once_with(plugins, conf, buildroot) ++ ++ ++# --------------------------------------------------------------------------- ++# Without cache_key — legacy behaviour unchanged ++# --------------------------------------------------------------------------- ++ ++@patch('mockbuild.plugins.yum_cache.mockbuild.file_util') ++def test_no_cache_key_uses_buildroot_cachedir(mock_file_util): ++ """Without cache_key, host_cache_path must be buildroot.cachedir/dnf_cache.""" ++ br = make_buildroot() ++ br.cachedir = '/var/cache/mock/my-root' ++ conf = deepcopy(DEFAULT_CONF) ++ ++ with patch('builtins.open', mock.mock_open()): ++ plugin = yum_cache.YumCache(MagicMock(), conf, br) ++ ++ dnf_dir = next(d for d in plugin.cache_dirs if d.host_cache_path.endswith('dnf_cache')) ++ assert dnf_dir.host_cache_path == '/var/cache/mock/my-root/dnf_cache' ++ ++ ++@patch('mockbuild.plugins.yum_cache.mockbuild.file_util') ++def test_no_cache_key_lock_in_buildroot_cachedir(mock_file_util): ++ """Without cache_key, lock file must be in buildroot.cachedir.""" ++ br = make_buildroot() ++ br.cachedir = '/var/cache/mock/my-root' ++ conf = deepcopy(DEFAULT_CONF) ++ ++ mock_open = mock.mock_open() ++ with patch('builtins.open', mock_open): ++ yum_cache.YumCache(MagicMock(), conf, br) ++ ++ opened_paths = [c.args[0] for c in mock_open.call_args_list] ++ assert any('my-root/yumcache.lock' in p for p in opened_paths), \ ++ f"lock not in cachedir; opened: {opened_paths}" ++ ++ ++# --------------------------------------------------------------------------- ++# With cache_key — shared cache behaviour ++# --------------------------------------------------------------------------- ++ ++@patch('mockbuild.plugins.yum_cache.mockbuild.file_util') ++def test_cache_key_uses_shared_dir(mock_file_util): ++ """With cache_key, host_cache_path must be cache_topdir/yum_cache/{key}/dnf_cache.""" ++ br = make_buildroot({'cache_topdir': '/var/cache/mock'}) ++ conf = {**DEFAULT_CONF, 'cache_key': 'centos-stream-10-x86_64'} ++ ++ with patch('builtins.open', mock.mock_open()): ++ plugin = yum_cache.YumCache(MagicMock(), conf, br) ++ ++ dnf_dir = next(d for d in plugin.cache_dirs if d.host_cache_path.endswith('dnf_cache')) ++ assert dnf_dir.host_cache_path == \ ++ '/var/cache/mock/yum_cache/centos-stream-10-x86_64/dnf_cache' ++ ++ ++@patch('mockbuild.plugins.yum_cache.mockbuild.file_util') ++def test_cache_key_lock_in_shared_dir(mock_file_util): ++ """With cache_key, lock file must be in the shared cache dir, not buildroot.cachedir.""" ++ br = make_buildroot({'cache_topdir': '/var/cache/mock'}) ++ br.cachedir = '/var/cache/mock/my-root' ++ conf = {**DEFAULT_CONF, 'cache_key': 'centos-stream-10-x86_64'} ++ ++ mock_open = mock.mock_open() ++ with patch('builtins.open', mock_open): ++ yum_cache.YumCache(MagicMock(), conf, br) ++ ++ opened_paths = [c.args[0] for c in mock_open.call_args_list] ++ assert any('yum_cache/centos-stream-10-x86_64/yumcache.lock' in p ++ for p in opened_paths), f"shared lock not found; opened: {opened_paths}" ++ assert not any('my-root/yumcache.lock' in p ++ for p in opened_paths), "lock must not be in buildroot.cachedir" ++ ++ ++@patch('mockbuild.plugins.yum_cache.mockbuild.file_util') ++def test_cache_key_shared_dir_created(mock_file_util): ++ """With cache_key, the shared directory must be created via mkdirIfAbsent.""" ++ br = make_buildroot({'cache_topdir': '/var/cache/mock'}) ++ conf = {**DEFAULT_CONF, 'cache_key': 'centos-stream-10-x86_64'} ++ ++ with patch('builtins.open', mock.mock_open()): ++ yum_cache.YumCache(MagicMock(), conf, br) ++ ++ created_dirs = [c.args[0] for c in mock_file_util.mkdirIfAbsent.call_args_list] ++ assert any('yum_cache/centos-stream-10-x86_64' in d for d in created_dirs), \ ++ f"shared dir not created; mkdirIfAbsent called with: {created_dirs}" ++ ++ ++@patch('mockbuild.plugins.yum_cache.mockbuild.file_util') ++def test_both_dnf_and_yum_cache_dirs_registered(mock_file_util): ++ """Both /var/cache/dnf and /var/cache/yum bind mounts must be added.""" ++ br = make_buildroot() ++ conf = {**DEFAULT_CONF, 'cache_key': 'centos-stream-10-x86_64'} ++ ++ with patch('builtins.open', mock.mock_open()): ++ yum_cache.YumCache(MagicMock(), conf, br) ++ ++ added_srcs = [c.args[0].srcpath for c in br.mounts.add.call_args_list] ++ assert any('dnf_cache' in p for p in added_srcs), f"dnf_cache not mounted: {added_srcs}" ++ assert any('yum_cache' in p for p in added_srcs), f"yum_cache not mounted: {added_srcs}" ++ ++ ++# --------------------------------------------------------------------------- ++# Hook registration (both modes) ++# --------------------------------------------------------------------------- ++ ++@patch('mockbuild.plugins.yum_cache.mockbuild.file_util') ++def test_hooks_registered(mock_file_util): ++ """Plugin must always register preyum, postyum, preinit hooks.""" ++ for conf in [deepcopy(DEFAULT_CONF), {**DEFAULT_CONF, 'cache_key': 'my-key'}]: ++ plugins = MagicMock() ++ br = make_buildroot() ++ br.cachedir = '/var/cache/mock/root' ++ with patch('builtins.open', mock.mock_open()): ++ yum_cache.YumCache(plugins, conf, br) ++ hook_names = [c.args[0] for c in plugins.add_hook.call_args_list] ++ assert 'preyum' in hook_names ++ assert 'postyum' in hook_names ++ assert 'preinit' in hook_names ++ ++ ++# --------------------------------------------------------------------------- ++# Two configs, same cache_key — both resolve to same path ++# --------------------------------------------------------------------------- ++ ++@patch('mockbuild.plugins.yum_cache.mockbuild.file_util') ++def test_two_roots_same_cache_key_share_path(mock_file_util): ++ """Two buildroots with different cachedir but same cache_key must resolve identical paths.""" ++ conf = {**DEFAULT_CONF, 'cache_key': 'centos-stream-10-x86_64'} ++ ++ br1 = make_buildroot({'cache_topdir': '/var/cache/mock'}) ++ br1.cachedir = '/var/cache/mock/build-root-1' ++ br2 = make_buildroot({'cache_topdir': '/var/cache/mock'}) ++ br2.cachedir = '/var/cache/mock/build-root-2' ++ ++ with patch('builtins.open', mock.mock_open()): ++ p1 = yum_cache.YumCache(MagicMock(), deepcopy(conf), br1) ++ p2 = yum_cache.YumCache(MagicMock(), deepcopy(conf), br2) ++ ++ dnf1 = next(d.host_cache_path for d in p1.cache_dirs if d.host_cache_path.endswith('dnf_cache')) ++ dnf2 = next(d.host_cache_path for d in p2.cache_dirs if d.host_cache_path.endswith('dnf_cache')) ++ assert dnf1 == dnf2, f"paths differ: {dnf1} != {dnf2}" diff --git a/SPECS/mock.spec b/SPECS/mock.spec index 41ca3f2..4f1d224 100644 --- a/SPECS/mock.spec +++ b/SPECS/mock.spec @@ -19,7 +19,7 @@ Summary: Builds packages inside chroots Name: mock Version: 6.7 -Release: 1%{?dist} +Release: 1%{?dist}.alma.1 License: GPL-2.0-or-later # Source is created by # git clone https://github.com/rpm-software-management/mock.git @@ -27,6 +27,10 @@ License: GPL-2.0-or-later # git reset --hard %%{name}-%%{version} # tito build --tgz Source: https://github.com/rpm-software-management/%{name}/releases/download/%{name}-%{version}-1/%{name}-%{version}.tar.gz + +# AlmaLinux Patch +Patch: 1000-add-oci-platform-support-for-x86_64-sub-arch.patch +Patch: 1001-yum-cache-add-cache-key-for-shared-package-cache.patch URL: https://github.com/rpm-software-management/mock/ BuildArch: noarch Requires: tar @@ -169,7 +173,7 @@ Requires(pre): shadow-utils Filesystem layout and group for Mock. %prep -%setup -q +%autosetup -p1 for file in py/mock.py py/mock-parse-buildlog.py; do sed -i 1"s|#!/usr/bin/python3 |#!%{__python} |" $file done @@ -330,6 +334,11 @@ pylint-3 py/mockbuild/ py/*.py py/mockbuild/plugins/* || : %changelog +* Wed Apr 08 2026 Andrew Lukoshko - 6.7-1.alma.1 +- Add OCI platform support for x86_64 sub-architecture containers +- Add cache_key option to yum_cache plugin for shared package cache across + configs + * Tue Mar 03 2026 Pavel Raiskup 6.7-1 - mock: Use umask 0022 instead of 0002 to avoid strange permissions (ngompa@velocitylimitless.com) - expand_spec plugin: generating expanded-spec.txt in postdeps hook (yzhu@redhat.com)