Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package mkosi for openSUSE:Factory checked 
in at 2026-10-07 19:34:58
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/mkosi (Old)
 and      /work/SRC/openSUSE:Factory/.mkosi.new.3698736 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "mkosi"

Wed Oct  7 19:34:58 2026 rev:35 rq:1382954 version:27.1

Changes:
--------
--- /work/SRC/openSUSE:Factory/mkosi/mkosi.changes      2026-09-10 
11:52:21.816037286 +0200
+++ /work/SRC/openSUSE:Factory/.mkosi.new.3698736/mkosi.changes 2026-10-07 
19:35:50.204766747 +0200
@@ -1,0 +2,29 @@
+Mon Oct  5 14:46:35 UTC 2026 - Antonio Feijoo <[email protected]>
+
+- Update to 27.1:
+  * Fix tests failing in restricted build environments.
+  * SignInitrdPCRs= can be used with SplitArtifacts=pcrs, fixing 
initrd-specific
+    PCR policies with systemd v262.
+  * Don't fail creating initrds when there are directories mixed in with
+    microcode files.
+  * Fix builds when using unsigned local repositories with opensuse.
+  * Only use repositories and variables from the sandbox tree when using DNF.
+  * The mkosi-obs no longer sets MakeScriptsExecutable=, except for the main
+    image, so it can be included again.
+  * The security and debug repositories are switched back to deb.debian.org and
+    are no longer set by the Repositories= setting.
+  * Add an environment variable MKOSI_FORCE_USERNS_FALLBACK that when set to a
+    value that parses as a truthy bool, skips using systemd-nsresourced.
+  * A new setting DelegateRanges= is added that defaults to 0 when mkosi is run
+    as the root user. This fixes builds run as the root user.
+
+- Remove 0003-mkosi-obs-Only-configure-MakeScriptsExecutable-in-th.patch, 
merged
+  in version 27.1.
+
+- Remove 0002-opensuse-tolerate-missing-RPM-keyring.patch, merged
+  in version 27.1.
+
+- Remove 0001-tests-skip-test_fork_and_wait-if-on-rc-1.patch, merged
+  in version 27.1.
+
+-------------------------------------------------------------------

Old:
----
  0001-tests-skip-test_fork_and_wait-if-on-rc-1.patch
  0002-opensuse-tolerate-missing-RPM-keyring.patch
  0003-mkosi-obs-Only-configure-MakeScriptsExecutable-in-th.patch
  mkosi-27.tar.gz

New:
----
  mkosi-27.1.tar.gz

----------(Old B)----------
  Old:
- Remove 0001-tests-skip-test_fork_and_wait-if-on-rc-1.patch, merged
  in version 27.1.
  Old:
- Remove 0002-opensuse-tolerate-missing-RPM-keyring.patch, merged
  in version 27.1.
  Old:
- Remove 0003-mkosi-obs-Only-configure-MakeScriptsExecutable-in-th.patch, merged
  in version 27.1.
----------(Old E)----------

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ mkosi.spec ++++++
--- /var/tmp/diff_new_pack.gG87Fx/_old  2026-10-07 19:35:51.012800529 +0200
+++ /var/tmp/diff_new_pack.gG87Fx/_new  2026-10-07 19:35:51.018800780 +0200
@@ -28,7 +28,7 @@
 %endif
 
 Name:           mkosi
-Version:        27
+Version:        27.1
 Release:        0
 Summary:        Build bespoke OS Images
 License:        LGPL-2.1-or-later
@@ -36,12 +36,6 @@
 URL:            https://github.com/systemd/mkosi
 Source0:        
https://github.com/systemd/mkosi/archive/v%{version}.tar.gz#/%{name}-%{version}.tar.gz
 Source1:        mkosi-initrd.conf
-# PATCH-FIX-UPSTREAM https://github.com/systemd/mkosi/pull/4432
-Patch0:         0001-tests-skip-test_fork_and_wait-if-on-rc-1.patch
-# PATCH-FIX-UPSTREAM https://github.com/systemd/mkosi/pull/4442
-Patch1:         0002-opensuse-tolerate-missing-RPM-keyring.patch
-# PATCH-FIX-UPSTREAM https://github.com/systemd/mkosi/pull/4453
-Patch2:         0003-mkosi-obs-Only-configure-MakeScriptsExecutable-in-th.patch
 BuildRequires:  %{python_module pip}
 BuildRequires:  %{python_module pytest}
 BuildRequires:  %{python_module wheel}

++++++ mkosi-27.tar.gz -> mkosi-27.1.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mkosi-27/action.yaml new/mkosi-27.1/action.yaml
--- old/mkosi-27/action.yaml    2026-08-27 16:30:58.000000000 +0200
+++ new/mkosi-27.1/action.yaml  2026-09-28 15:32:03.000000000 +0200
@@ -118,8 +118,8 @@
       run: |
         set +e
         APK_TOOLS_API="https://gitlab.alpinelinux.org/api/v4/projects/5";
-        APK_FALLBACK_VERSION='v3.0.7'
-        
APK_FALLBACK_SHA256='c07bf5356eacc9dd7a8c56bc537f46702f007170287403299d52a04264e74b3c'
+        APK_FALLBACK_VERSION='v3.0.8'
+        
APK_FALLBACK_SHA256='11758d76de3699c7606152357f415f55879743ccf0e3d8942d5ba98cf29a3c86'
 
         APK_VERSION=$(curl -fsSL --retry 5 --retry-all-errors --retry-max-time 
30 "${APK_TOOLS_API}/repository/tags" | jq -r '.[].name' | grep -v '_rc' | sort 
-V | tail -1)
         if [[ -n "$APK_VERSION" && "$APK_VERSION" != "$APK_FALLBACK_VERSION" ]]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mkosi-27/docs/root-verity.md 
new/mkosi-27.1/docs/root-verity.md
--- old/mkosi-27/docs/root-verity.md    2026-08-27 16:30:58.000000000 +0200
+++ new/mkosi-27.1/docs/root-verity.md  2026-09-28 15:32:03.000000000 +0200
@@ -144,7 +144,7 @@
 whose contents will depend on how updates are deployed:
 
 ```ini
-# /usr/lib/sysupdate.d/10-root-verity-sig.conf
+# /usr/lib/sysupdate.d/10-root-verity-sig.transfer
 [Transfer]
 ProtectVersion=%A
 
@@ -156,7 +156,7 @@
 PartitionFlags=0
 ReadOnly=1
 
-# /usr/lib/sysupdate.d/11-root-verity.conf
+# /usr/lib/sysupdate.d/11-root-verity.transfer
 [Transfer]
 ProtectVersion=%A
 
@@ -168,7 +168,7 @@
 PartitionFlags=0
 ReadOnly=1
 
-# /usr/lib/sysupdate.d/12-root.conf
+# /usr/lib/sysupdate.d/12-root.transfer
 [Transfer]
 ProtectVersion=%A
 
@@ -180,7 +180,7 @@
 PartitionFlags=0
 ReadOnly=1
 
-# /usr/lib/sysupdate.d/20-uki.conf
+# /usr/lib/sysupdate.d/20-uki.transfer
 [Transfer]
 ProtectVersion=%A
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mkosi-27/mkosi/__init__.py 
new/mkosi-27.1/mkosi/__init__.py
--- old/mkosi-27/mkosi/__init__.py      2026-08-27 16:30:58.000000000 +0200
+++ new/mkosi-27.1/mkosi/__init__.py    2026-09-28 15:32:03.000000000 +0200
@@ -1504,11 +1504,18 @@
             if amd.exists():
                 with (destdir / "AuthenticAMD.bin").open("wb") as f:
                     for p in amd.iterdir():
+                        if not p.is_file():
+                            continue
                         f.write(p.read_bytes())
 
             if intel.exists():
                 with (destdir / "GenuineIntel.bin").open("wb") as f:
                     for p in intel.iterdir():
+                        # On some distributions the Intel ucode directory may 
contain directories like
+                        # intel-ucode-with-caveats, that contain microcode 
that needs special patches in the
+                        # kernel or other manual interventions, so we ignore 
these.
+                        if not p.is_file():
+                            continue
                         f.write(p.read_bytes())
 
         # Normalize timestamps for reproducible builds before creating cpio
@@ -1721,6 +1728,7 @@
         die("Could not find ukify")
 
     json_out = False
+    ukify_version = systemd_tool_version(python_binary(context.config), ukify, 
sandbox=context.sandbox)
 
     arguments: list[PathString] = [
         "--os-release", f"@{workdir(context.root / 'usr/lib/os-release')}",
@@ -1776,15 +1784,13 @@
             "--pcr-banks", "sha256",
         ]  # fmt: skip
 
-        ukify_version = systemd_tool_version(python_binary(context.config), 
ukify, sandbox=context.sandbox)
-
         if ukify_version >= "258":
             cert_parameter = "--pcr-certificate"
         else:
             cert_parameter = "--pcr-public-key"
 
         if context.config.sign_initrd_pcrs == ConfigFeature.enabled or (
-            context.config.sign_initrd_pcrs == ConfigFeature.auto and 
ukify_version >= "261.999"
+            context.config.sign_initrd_pcrs == ConfigFeature.auto and 
ukify_version >= "262~"
         ):
             arguments += ["--sign-initrd-pcrs"]
 
@@ -1830,6 +1836,10 @@
             "--pcr-banks", "sha256",
             "--pcr-certificate", 
workdir(context.config.sign_expected_pcr_certificate),
         ]  # fmt: skip
+        if context.config.sign_initrd_pcrs == ConfigFeature.enabled or (
+            context.config.sign_initrd_pcrs == ConfigFeature.auto and 
ukify_version >= "262~"
+        ):
+            arguments += ["--sign-initrd-pcrs"]
         options += [
             "--ro-bind", context.config.sign_expected_pcr_certificate, 
workdir(context.config.sign_expected_pcr_certificate),  # noqa: E501
         ]  # fmt: skip
@@ -2754,8 +2764,10 @@
             hint="Run mkosi genkey to generate a key/certificate pair",
         )
 
-    if config.sign_initrd_pcrs == ConfigFeature.enabled and not 
want_signed_pcrs(config):
-        die("SignInitrdPCRs= is enabled but PCR signing is not enabled")
+    if config.sign_initrd_pcrs == ConfigFeature.enabled and not (
+        want_signed_pcrs(config) or ArtifactOutput.pcrs in 
config.split_artifacts
+    ):
+        die("SignInitrdPCRs= is enabled but neither PCR signing nor 
SplitArtifacts=pcrs are enabled")
 
     if config.secure_boot_key_source != config.sign_expected_pcr_key_source:
         die("Secure boot key source and expected PCR signatures key source 
have to be the same")
@@ -2909,7 +2921,7 @@
         if config.sign_initrd_pcrs == ConfigFeature.enabled and 
want_signed_pcrs(config):
             check_ukify(
                 config,
-                version="261.999",
+                version="262~",
                 reason="sign a PCR policy for the initrd",
             )
 
@@ -5097,9 +5109,17 @@
         return
 
     try:
+        if parse_boolean(os.getenv("MKOSI_FORCE_USERNS_FALLBACK") or "0"):
+            raise ConnectionRefusedError("Forced fallback to unpriv userns.")
+
         # Try to get a user namespace with some delegated ranges and the 
foreign UID range via
-        # systemd-nsresourced if we can.
-        acquire_privileges(foreign=True, delegate=3)
+        # systemd-nsresourced if we can, unless we're running as root, then
+        # - Only use the foreign UID range if it was explicitly requested
+        # - Only use delegated ranges if they were requested
+        acquire_privileges(
+            foreign=last.foreign_uid_range if (os.getuid() == 0 and 
os.getgid() == 0) else True,
+            delegate_ranges=last.delegate_ranges,
+        )
     # Don't fail if systemd-nsresourced is too old, not installed or refuses 
to provision a user namespace
     # for us unless the foreign UID range was explicitly requested, use a 
regular unpriv user namespace
     # instead.
@@ -5114,7 +5134,7 @@
         if last.foreign_uid_range:
             die(f"Could not provision user namespace via systemd-nsresourced 
({e})")
 
-        logging.debug(
+        logging.info(
             f"Could not provision user namespace via systemd-nsresourced 
({e}), falling back to "
             "unprivileged user namespace via unshare(CLONE_NEWUSER) and 
writing /proc/self/uid_map directly",
         )
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mkosi-27/mkosi/config.py 
new/mkosi-27.1/mkosi/config.py
--- old/mkosi-27/mkosi/config.py        2026-08-27 16:30:58.000000000 +0200
+++ new/mkosi-27.1/mkosi/config.py      2026-09-28 15:32:03.000000000 +0200
@@ -908,6 +908,18 @@
     return parse_boolean(value)
 
 
+def config_parse_int(value: Optional[str], old: Optional[int]) -> 
Optional[int]:
+    if value is None:
+        return None
+
+    try:
+        num = int(value)
+    except ValueError:
+        die(f"{value!r} is not a valid integer")
+
+    return num
+
+
 def parse_feature(value: str) -> ConfigFeature:
     try:
         return ConfigFeature(value)
@@ -2245,6 +2257,7 @@
     proxy_client_key: Optional[Path]
     make_scripts_executable: bool
     foreign_uid_range: bool
+    delegate_ranges: int
 
     nspawn_settings: Optional[Path]
     ephemeral: bool
@@ -4194,6 +4207,15 @@
         help="Use the foreign UID range",
         scope=SettingScope.main,
     ),
+    ConfigSetting(
+        dest="delegate_ranges",
+        name="DelegateRanges",
+        section="Build",
+        default=0 if (os.getuid() == 0 and os.getgid() == 0) else 3,
+        parse=config_parse_int,
+        help="Delegate this number of UID ranges in the foreign UID range",
+        scope=SettingScope.main,
+    ),
     # Runtime section
     ConfigSetting(
         dest="nspawn_settings",
@@ -6011,6 +6033,9 @@
                          Tools Tree: {config.tools_tree}
             Tools Tree Certificates: {yes_no(config.tools_tree_certificates)}
 
+          Use the Foreign UID Range: {yes_no(config.foreign_uid_range)}
+         Number of Delegated Ranges: {config.delegate_ranges}
+
                  Extra Search Paths: 
{line_join_list(config.extra_search_paths)}
                         Incremental: {config.incremental}
              Use Only Package Cache: {config.cacheonly}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mkosi-27/mkosi/distribution/debian.py 
new/mkosi-27.1/mkosi/distribution/debian.py
--- old/mkosi-27/mkosi/distribution/debian.py   2026-08-27 16:30:58.000000000 
+0200
+++ new/mkosi-27.1/mkosi/distribution/debian.py 2026-09-28 15:32:03.000000000 
+0200
@@ -81,7 +81,7 @@
         if snapshot:
             url = join_mirror(mirror, f"archive/debian-debug/{snapshot}")
         else:
-            url = join_mirror(mirror, "debian-debug")
+            url = "http://deb.debian.org/debian-debug";
 
         yield AptRepository(
             types=types,
@@ -107,7 +107,7 @@
         if snapshot:
             url = join_mirror(mirror, f"archive/debian-security/{snapshot}")
         else:
-            url = join_mirror(mirror, "debian-security")
+            url = "http://deb.debian.org/debian-security";
 
         yield AptRepository(
             types=types,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mkosi-27/mkosi/distribution/opensuse.py 
new/mkosi-27.1/mkosi/distribution/opensuse.py
--- old/mkosi-27/mkosi/distribution/opensuse.py 2026-08-27 16:30:58.000000000 
+0200
+++ new/mkosi-27.1/mkosi/distribution/opensuse.py       2026-09-28 
15:32:03.000000000 +0200
@@ -1,6 +1,7 @@
 # SPDX-License-Identifier: LGPL-2.1-or-later
 
 import os
+import subprocess
 import tempfile
 from collections.abc import Iterable, Sequence
 from pathlib import Path
@@ -57,7 +58,7 @@
             options = context.rootoptions()
 
             gpgkeys: Sequence[PathString] = []
-            if (p := context.keyring_dir / "opensuse.gpg").exists():
+            if (p := context.keyring_dir / "opensuse.gpg").exists() and 
p.stat().st_size > 0:
                 gpgkeys = [workdir(p)]
                 options += ["--bind", os.fspath(p), workdir(p)]
             else:
@@ -76,14 +77,29 @@
             return
 
         context.keyring_dir.mkdir(parents=True, exist_ok=True)
+        keyring = context.keyring_dir / "opensuse.gpg"
 
-        with (context.keyring_dir / "opensuse.gpg").open("wb") as f:
-            run(
-                # TODO: Switch to rpmkeys --export once we can rely on rpm 
6.0.0 or newer.
-                ["rpm", "--root=/buildroot", "-q", "gpg-pubkey", "--qf", 
"%{PUBKEYS:armor}\n"],
-                stdout=f,
-                sandbox=context.sandbox(options=context.rootoptions()),
-            )
+        result = run(
+            # TODO: Switch to rpmkeys --export once we can rely on rpm 6.0.0 
or newer.
+            ["rpm", "--root=/buildroot", "-q", "gpg-pubkey", "--qf", 
"%{PUBKEYS:armor}\n"],
+            stdout=subprocess.PIPE,
+            stderr=subprocess.PIPE,
+            sandbox=context.sandbox(options=context.rootoptions()),
+            success_exit_status=(0, 1),
+        )
+
+        if result.returncode == 1:
+            expected = "package gpg-pubkey is not installed"
+            if expected not in result.stdout and expected not in result.stderr:
+                raise subprocess.CalledProcessError(
+                    result.returncode,
+                    result.args,
+                    output=result.stdout,
+                    stderr=result.stderr,
+                )
+            keyring.unlink(missing_ok=True)
+        else:
+            keyring.write_text(result.stdout)
 
     @classmethod
     def install(cls, context: Context) -> None:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mkosi-27/mkosi/installer/dnf.py 
new/mkosi-27.1/mkosi/installer/dnf.py
--- old/mkosi-27/mkosi/installer/dnf.py 2026-08-27 16:30:58.000000000 +0200
+++ new/mkosi-27.1/mkosi/installer/dnf.py       2026-09-28 15:32:03.000000000 
+0200
@@ -217,11 +217,15 @@
         if dnf == "dnf5":
             cmdline += ["--use-host-config"]
         else:
-            cmdline += [
-                "--config=/etc/dnf/dnf.conf",
-                "--setopt=reposdir=/etc/yum.repos.d",
-                "--setopt=varsdir=/etc/dnf/vars",
-            ]
+            cmdline += ["--config=/etc/dnf/dnf.conf"]
+
+        # By default, dnf5 also reads repository definitions and variables 
from /usr/share/dnf5 which comes
+        # from the tools tree when using one (e.g. Fedora rawhide's 
fedora-repos ships its repositories there
+        # now), so make sure we only ever use the ones from the sandbox tree.
+        cmdline += [
+            "--setopt=reposdir=/etc/yum.repos.d",
+            "--setopt=varsdir=/etc/dnf/vars",
+        ]
 
         if context.config.proxy_url:
             cmdline += [f"--setopt=proxy={context.config.proxy_url}"]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mkosi-27/mkosi/resources/man/mkosi.1.md 
new/mkosi-27.1/mkosi/resources/man/mkosi.1.md
--- old/mkosi-27/mkosi/resources/man/mkosi.1.md 2026-08-27 16:30:58.000000000 
+0200
+++ new/mkosi-27.1/mkosi/resources/man/mkosi.1.md       2026-09-28 
15:32:03.000000000 +0200
@@ -1458,11 +1458,18 @@
 :   Path to the X.509 file containing the certificate for signing the expected 
PCR signatures.
 
 `SignInitrdPCRs=`, `--sign-initrd-pcrs=`
-:   Whether to generate signed PCR policies that can only be satisfied from the
-    initrd. This is required for initialization of NvPCRs. This takes a 
boolean value
-    or the special value `auto`, which is the default and is equivalent to a 
true value
-    if PCR signing is enabled (see `SignExpectedPcr=`) and the version of 
**ukify** is
-    at least v262. Signing is performed with the key that is supplied to 
`SignExpectedPcrKey=`.
+:   Whether to generate PCR policies that can only be satisfied from the 
initrd.
+    This is required for initialization of NvPCRs. This takes a boolean value 
or
+    the special value `auto`, which is the default and is equivalent to a true
+    value if the version of **ukify** is at least v262 and either PCR signing 
is
+    enabled (see `SignExpectedPcr=`) or `pcrs` is selected in 
`SplitArtifacts=`.
+    If enabled explicitly, either PCR signing or `SplitArtifacts=pcrs` must be
+    enabled as well.
+
+    When PCR signing is enabled, the policies are signed with the key supplied 
to
+    `SignExpectedPcrKey=` and embedded in the UKI. If `SplitArtifacts=pcrs` is
+    enabled and PCR signing is disabled, the policy digests are written 
unsigned to
+    the split PCR JSON artifact for offline signing.
 
 `SecureBootKeySource=`, `--secure-boot-key-source=`, `VerityKeySource=`, 
`--verity-key-source=`, `SignExpectedPcrKeySource=`, 
`--sign-expected-key-source=`
 :   The source of the corresponding private key, to support OpenSSL engines 
and providers,
@@ -1636,7 +1643,8 @@
     it will use the configuration files from their canonical locations
     in `/usr` or `/etc` in the sandbox trees. For example, it  will look
     for `/etc/dnf/dnf.conf` in the sandbox trees  if **dnf** is used to
-    install packages.
+    install packages. See **PACKAGE MANAGER-SPECIFIC BEHAVIOUR** for
+    further details.
 
 `WorkspaceDirectory=`, `--workspace-directory=`
 :   Path to a directory where to store data required temporarily while
@@ -1853,6 +1861,10 @@
     systemd-nsresourced and systemd-mountfsd v260 or newer are required on the 
host
     to make use of this option.
 
+`DelegateRanges=`, `--delegate-ranges=`
+:   Set the number of delegated ranges in the foreign UID range. Defaults to 3 
for regular users and 0 for
+    root.
+
 ### [Runtime] Section (previously known as the [Host] section)
 
 `NSpawnSettings=`, `--settings=`
@@ -2504,8 +2516,9 @@
 1. Parse CLI options
 1. Parse configuration files
 1. Run configure scripts (`mkosi.configure`)
-1. If we're not running as root, unshare the user namespace and map the
-   subuid range configured in `/etc/subuid` and `/etc/subgid` into it.
+1. If we're not running as root, unshare the user namespace and map the the 
current user to root in it.  If
+   available this uses systemd-nsresourced to acquire a delegated range in the 
foreign UID range, otherwise
+   an unprivileged user namespace is set up by mkosi.
 1. Unshare the mount namespace
 1. Remount the following directories read-only if they exist:
    - `/usr`
@@ -3115,6 +3128,28 @@
 | `zstd`                  | ✓      | ✓      | ✓      | ✓    | ✓      | ✓    | 
✓        | ✓            |
 | `zypper`                | ✓      |        | ✓      | ✓    | ✓      | ✓    | 
✓        |              |
 
+# PACKAGE MANAGER-SPECIFC BEHAVIOUR
+
+## Arch and other pacman-based distributions
+
+mkosi generates a `pacman.conf` in the sanbox tree if one doesn't exist. If 
one exists, a `DownloadUser`
+setting is always removed. The generated config will always include all files 
with the `.conf` extension from
+`/etc/pacman.d` in the sandbox tree.
+
+## Debian and other deb-based distributions
+
+mkosi generates `/etc/apt/sources.list.d/mkosi.sources` in the sandbox tree if 
it does not exist.
+The configured `Mirror=` is used for everything except for the security and 
debug repositories, which always
+use http://deb.debian.org.
+
+## Fedora and other distributions using DNF
+
+mkosi generates `/etc/yum.repos.d/mkosi.repo` in the sandbox tree if it does 
not exist.
+
+## Opensuse and other distributions using Zypper
+
+mkosi generates `/etc/zypp/repos.d/mkosi.repo` in the sandbox tree if it does 
not exist.
+
 # BUILDING MULTIPLE IMAGES
 
 If the `mkosi.images/` directory exists, **mkosi** will load individual
@@ -3492,6 +3527,11 @@
 
   You can set `PORTABLE_PREFIXES=` by setting 
`Environment=PORTABLE_PREFIXES=XXX` in your mkosi config.
 
+- `BaseTrees=`/`Overlay=` do not work with nsresourced?
+
+  This is expected and need upstream kernel changes expected to land in Linux 
7.3. You can skip the usage of
+  nsresourced by setting the environment variable 
`MKOSI_FORCE_USERNS_FALLBACK` to a true value.
+
 # REFERENCES
 * [Primary mkosi git repository on GitHub](https://github.com/systemd/mkosi/)
 * [mkosi — A Tool for Generating OS 
Images](https://0pointer.net/blog/mkosi-a-tool-for-generating-os-images.html) 
introductory blog post by Lennart Poettering
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mkosi-27/mkosi/resources/man/mkosi.news.7.md 
new/mkosi-27.1/mkosi/resources/man/mkosi.news.7.md
--- old/mkosi-27/mkosi/resources/man/mkosi.news.7.md    2026-08-27 
16:30:58.000000000 +0200
+++ new/mkosi-27.1/mkosi/resources/man/mkosi.news.7.md  2026-09-28 
15:32:03.000000000 +0200
@@ -4,6 +4,23 @@
 
 # mkosi Changelog
 
+## v27.1
+
+- Fix tests failing in restricted build environments
+- `SignInitrdPCRs=` can be used with `SplitArtifacts=pcrs`, fixing 
initrd-specific PCR policies with systemd
+  v262.
+- Don't fail creating initrds when there are directories mixed in with 
microcode files.
+- Fix builds when using unsigned local repositories with opensuse.
+- Only use repositories and variables from the sandbox tree when using DNF.
+- The mkosi-obs no longer sets `MakeScriptsExecutable=`, except for the main 
image, so it can be included
+  again.
+- The security and debug repositories are switched back to deb.debian.org and 
are no longer set by the
+  `Repositories=` setting.
+- Add an environment variable `MKOSI_FORCE_USERNS_FALLBACK` that when set to a 
value that parses as a truthy
+  bool, skips using systemd-nsresourced.
+- A new setting `DelegateRanges=` is added that defaults to 0 when mkosi is 
run as the root user. This fixes
+  builds run as the root user.
+
 ## v27
 
 - Debug output (with `--debug`) will now show the duration of all steps.
@@ -29,7 +46,7 @@
   images unprivileged without a sufficiently new systemd-nsresourced is still 
supported.
 - If a `mkosi/` directory exists and no output location is configured, the 
`.mkosi-private` will be put there.
 - `LocalMirror=` can now be set for tools trees.
-- A new setting `DriveType=` has been added to configures the disk type to use 
for the root disk when booting
+- A new setting `DiskType=` has been added to configures the disk type to use 
for the root disk when booting
   a virtual machine.
 - Four new settings `ElTorito=`, `ElToritoSystem=`, `ElToritoVolume=`, and 
`ElToritoPublisher=` for use with
   systemd-repart's El Torito support have been added.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mkosi-27/mkosi/resources/mkosi-obs/mkosi.build 
new/mkosi-27.1/mkosi/resources/mkosi-obs/mkosi.build
--- old/mkosi-27/mkosi/resources/mkosi-obs/mkosi.build  2026-08-27 
16:30:58.000000000 +0200
+++ new/mkosi-27.1/mkosi/resources/mkosi-obs/mkosi.build        2026-09-28 
15:32:03.000000000 +0200
@@ -140,14 +140,14 @@
 while read -r SIG; do
     uki="$OUTPUTDIR/$(basename "$(dirname "${SIG%.sig}")")"
     pcrs="${uki%.efi}.pcrs"
-    pol="$(basename "${SIG%.sig}")"
+    tbs="$(basename "${SIG%.sig}")"
 
     test -f "${pcrs}"
 
-    jq -c --arg pol "$pol" --arg sig "$(base64 -w0 <"$SIG")" '
+    jq -c --arg tbs "$tbs" --arg sig "$(base64 -w0 <"$SIG")" '
         to_entries | map(
             .value |= map(
-                if .pol == $pol then
+                if (.tbs // .pol) == $tbs then
                     .sig = $sig
                 else
                     .
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mkosi-27/mkosi/resources/mkosi-obs/mkosi.conf 
new/mkosi-27.1/mkosi/resources/mkosi-obs/mkosi.conf
--- old/mkosi-27/mkosi/resources/mkosi-obs/mkosi.conf   2026-08-27 
16:30:58.000000000 +0200
+++ new/mkosi-27.1/mkosi/resources/mkosi-obs/mkosi.conf 2026-09-28 
15:32:03.000000000 +0200
@@ -8,6 +8,3 @@
 SignExpectedPcr=no
 Verity=defer
 Checksum=yes
-
-[Build]
-MakeScriptsExecutable=yes
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/mkosi-27/mkosi/resources/mkosi-obs/mkosi.conf.d/main.conf 
new/mkosi-27.1/mkosi/resources/mkosi-obs/mkosi.conf.d/main.conf
--- old/mkosi-27/mkosi/resources/mkosi-obs/mkosi.conf.d/main.conf       
2026-08-27 16:30:58.000000000 +0200
+++ new/mkosi-27.1/mkosi/resources/mkosi-obs/mkosi.conf.d/main.conf     
2026-09-28 15:32:03.000000000 +0200
@@ -11,6 +11,7 @@
 CacheDirectory=
 Incremental=no
 WithNetwork=never
+MakeScriptsExecutable=yes
 
 [Distribution]
 RepositoryKeyCheck=no
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mkosi-27/mkosi/resources/mkosi-obs/mkosi.postoutput 
new/mkosi-27.1/mkosi/resources/mkosi-obs/mkosi.postoutput
--- old/mkosi-27/mkosi/resources/mkosi-obs/mkosi.postoutput     2026-08-27 
16:30:58.000000000 +0200
+++ new/mkosi-27.1/mkosi/resources/mkosi-obs/mkosi.postoutput   2026-09-28 
15:32:03.000000000 +0200
@@ -41,9 +41,9 @@
     test -f "${OUTPUTDIR}/${f}" || continue
     if [ -f "${OUTPUTDIR}/${f%.efi}.pcrs" ]; then
         mkdir -p "hashes/pcrs/$f"
-        while read -r pol; do
-            echo -n "$pol" | tr '[:lower:]' '[:upper:]' | basenc --base16 
--decode >"hashes/pcrs/${f}/${pol}"
-        done < <(jq -r 'to_entries[] | .value[].pol' 
<"${OUTPUTDIR}/${f%.efi}.pcrs")
+        while read -r tbs; do
+            echo -n "$tbs" | tr '[:lower:]' '[:upper:]' | basenc --base16 
--decode >"hashes/pcrs/${f}/${tbs}"
+        done < <(jq -r 'to_entries[] | .value[] | .tbs // .pol' 
<"${OUTPUTDIR}/${f%.efi}.pcrs")
     else
         mkdir -p "$(dirname "hashes/ukis/$f")"
         pesign --force -n sql:"$nss_db" -i "${OUTPUTDIR}/${f}" -E 
"hashes/ukis/$f"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mkosi-27/mkosi/sandbox.py 
new/mkosi-27.1/mkosi/sandbox.py
--- old/mkosi-27/mkosi/sandbox.py       2026-08-27 16:30:58.000000000 +0200
+++ new/mkosi-27.1/mkosi/sandbox.py     2026-09-28 15:32:03.000000000 +0200
@@ -13,7 +13,7 @@
 import sys
 import warnings  # noqa: F401 (loaded lazily by os.execvp() which happens too 
late)
 
-__version__ = "27"
+__version__ = "27.1"
 
 # The following constants are taken from the Linux kernel headers.
 AT_EMPTY_PATH = 0x1000
@@ -745,7 +745,7 @@
     userns: FD,
     type: str = "managed",
     foreign: bool = False,
-    delegate: int = 0,
+    delegate_ranges: int = 0,
     become_root: bool = False,
 ) -> None:
     import uuid
@@ -760,7 +760,7 @@
             "type": type,
             **({"target": 0} if become_root or type != "self" else {}),
             "mapForeign": foreign,
-            "delegateContainerRanges": delegate,
+            "delegateContainerRanges": delegate_ranges,
         },
         fds=(userns,),
     )
@@ -857,7 +857,7 @@
     *,
     identity: bool = True,
     foreign: bool = False,
-    delegate: int = 0,
+    delegate_ranges: int = 0,
     become_root: bool = False,
     network: bool = False,
 ) -> bool:
@@ -865,12 +865,12 @@
         have_effective_cap(CAP_SYS_ADMIN)
         and identity
         and (not foreign or have_effective_cap(CAP_CHOWN))
-        and not delegate
+        and (delegate_ranges == 0)
         and (not become_root or (os.getuid() == 0 and os.getgid() == 0))
     ):
         return False
 
-    if not identity or (foreign and not have_effective_cap(CAP_CHOWN)) or 
delegate:
+    if not identity or (foreign and not have_effective_cap(CAP_CHOWN)) or 
delegate_ranges:
         # nsresource_allocate_user_range() might fail for various reasons and 
we don't want to leave
         # the process in an empty user namespace if that's the case. Hence we 
don't unshare our own
         # user namespace but get ourselves a child user namespace which we 
pass to nsresourced. We only
@@ -880,7 +880,7 @@
                 userns_fd,
                 "self" if identity else "managed",
                 foreign,
-                delegate,
+                delegate_ranges,
                 become_root,
             )
             setns(userns_fd, CLONE_NEWUSER)
@@ -1595,7 +1595,7 @@
     userns = acquire_privileges(
         identity=True,
         foreign=map_foreign,
-        delegate=(map_delegate + int(foreign)),
+        delegate_ranges=(map_delegate + int(foreign)),
         become_root=(not foreign and become_root),
         network=unshare_net,
     )
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mkosi-27/mkosi/user.py new/mkosi-27.1/mkosi/user.py
--- old/mkosi-27/mkosi/user.py  2026-08-27 16:30:58.000000000 +0200
+++ new/mkosi-27.1/mkosi/user.py        2026-09-28 15:32:03.000000000 +0200
@@ -5,8 +5,6 @@
 from mkosi.run import find_binary
 from mkosi.util import parents_below
 
-SUBRANGE = 65536
-
 
 class INVOKING_USER:
     @classmethod
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mkosi-27/pyproject.toml new/mkosi-27.1/pyproject.toml
--- old/mkosi-27/pyproject.toml 2026-08-27 16:30:58.000000000 +0200
+++ new/mkosi-27.1/pyproject.toml       2026-09-28 15:32:03.000000000 +0200
@@ -7,7 +7,7 @@
 authors = [
     {name = "mkosi contributors", email = 
"[email protected]"},
 ]
-version = "27"
+version = "27.1"
 description = "Build Bespoke OS Images"
 readme = "README.md"
 requires-python = ">=3.9"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mkosi-27/tests/test_json.py 
new/mkosi-27.1/tests/test_json.py
--- old/mkosi-27/tests/test_json.py     2026-08-27 16:30:58.000000000 +0200
+++ new/mkosi-27.1/tests/test_json.py   2026-09-28 15:32:03.000000000 +0200
@@ -161,6 +161,7 @@
                     "Value": null
                 }
             ],
+            "DelegateRanges": 3,
             "Dependencies": [
                 "dep1"
             ],
@@ -487,6 +488,7 @@
             Credential(name="credkey", value="credval"),
             Credential(name="pathcred", path=Path("/secret/file")),
         ],
+        delegate_ranges=3,
         dependencies=["dep1"],
         distribution=Distribution.fedora,
         disk_type=QemuDiskType.virtio_blk,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mkosi-27/tests/test_run.py 
new/mkosi-27.1/tests/test_run.py
--- old/mkosi-27/tests/test_run.py      2026-08-27 16:30:58.000000000 +0200
+++ new/mkosi-27.1/tests/test_run.py    2026-09-28 15:32:03.000000000 +0200
@@ -8,6 +8,7 @@
 import pytest
 
 from mkosi.run import fork_and_wait
+from mkosi.sandbox import EPERM
 
 
 def test_fork_and_wait_returns_value() -> None:
@@ -60,5 +61,10 @@
     def exists() -> bool:
         return Path("/abc").exists()
 
-    result = fork_and_wait(exists, sandbox=contextlib.nullcontext(["--bind", 
os.fspath(tmp_path), "/"]))
+    try:
+        result = fork_and_wait(exists, 
sandbox=contextlib.nullcontext(["--bind", os.fspath(tmp_path), "/"]))
+    except subprocess.CalledProcessError as e:
+        if e.returncode == EPERM or e.returncode == 28:
+            pytest.skip("CLONE_NEWUSER is not allowed in the test environment")
+        raise
     assert result

Reply via email to