diff --git a/pkgs/tools/virtualization/mkosi/0001-Use-wrapped-binaries-instead-of-Python-interpreter.patch b/pkgs/tools/virtualization/mkosi/0001-Use-wrapped-binaries-instead-of-Python-interpreter.patch new file mode 100644 index 000000000000..30a107be5dd0 --- /dev/null +++ b/pkgs/tools/virtualization/mkosi/0001-Use-wrapped-binaries-instead-of-Python-interpreter.patch @@ -0,0 +1,116 @@ +From eb36791f873dd645b1cbfa693b9c246943647190 Mon Sep 17 00:00:00 2001 +From: Moritz Sanft <58110325+msanft@users.noreply.github.com> +Date: Tue, 3 Sep 2024 08:57:26 +0200 +Subject: [PATCH 1/3] Use wrapped binaries instead of Python interpreter + +Rather than calling ukify and mkosi with sys.executable, which doesn't use the Python wrappers for PATH and PYTHONPATH, we call the wrapped binaries directly. + +Signed-off-by: Moritz Sanft <58110325+msanft@users.noreply.github.com> +--- + mkosi/__init__.py | 19 ++++--------------- + mkosi/run.py | 8 ++++---- + 2 files changed, 8 insertions(+), 19 deletions(-) + +diff --git a/mkosi/__init__.py b/mkosi/__init__.py +index cc8482c4..ba44ad31 100644 +--- a/mkosi/__init__.py ++++ b/mkosi/__init__.py +@@ -2059,16 +2059,7 @@ def join_initrds(initrds: Sequence[Path], output: Path) -> Path: + + + def python_binary(config: Config, *, binary: Optional[PathString]) -> PathString: +- tools = ( +- not binary or +- not (path := config.find_binary(binary)) or +- not any(path.is_relative_to(d) for d in config.extra_search_paths) +- ) +- +- # If there's no tools tree, prefer the interpreter from MKOSI_INTERPRETER. If there is a tools +- # tree, just use the default python3 interpreter. +- exe = Path(sys.executable) +- return "python3" if (tools and config.tools_tree) or not exe.is_relative_to("/usr") else exe ++ return "@PYTHON_PEFILE@" + + + def extract_pe_section(context: Context, binary: Path, section: str, output: Path) -> Path: +@@ -2135,11 +2126,10 @@ def build_uki( + if not (arch := context.config.architecture.to_efi()): + die(f"Architecture {context.config.architecture} does not support UEFI") + +- if not (ukify := context.config.find_binary("ukify", "/usr/lib/systemd/ukify")): ++ if not (ukify := context.config.find_binary("ukify", "@UKIFY@")): + die("Could not find ukify") + + cmd: list[PathString] = [ +- python_binary(context.config, binary=ukify), + ukify, + *(["--cmdline", f"@{context.workspace / 'cmdline'}"] if cmdline else []), + "--os-release", f"@{context.root / 'usr/lib/os-release'}", +@@ -2213,7 +2203,6 @@ def build_uki( + # new .ucode section support? + if ( + systemd_tool_version( +- python_binary(context.config, binary=ukify), + ukify, + sandbox=context.sandbox, + ) >= "256" and +@@ -2303,7 +2292,7 @@ def want_uki(context: Context) -> bool: + context.config.unified_kernel_images == ConfigFeature.enabled or ( + context.config.unified_kernel_images == ConfigFeature.auto and + systemd_stub_binary(context).exists() and +- context.config.find_binary("ukify", "/usr/lib/systemd/ukify") is not None ++ context.config.find_binary("ukify", "@UKIFY@") is not None + ) + ) + +@@ -2914,7 +2903,7 @@ def check_ukify( + reason: str, + hint: Optional[str] = None, + ) -> None: +- ukify = check_tool(config, "ukify", "/usr/lib/systemd/ukify", reason=reason, hint=hint) ++ ukify = check_tool(config, "ukify", "@UKIFY@", reason=reason, hint=hint) + + v = systemd_tool_version(python_binary(config, binary=ukify), ukify, sandbox=config.sandbox) + if v < version: +diff --git a/mkosi/run.py b/mkosi/run.py +index fd3bc98e..de47349a 100644 +--- a/mkosi/run.py ++++ b/mkosi/run.py +@@ -450,7 +450,7 @@ def sandbox_cmd( + ) -> Iterator[list[PathString]]: + cmdline: list[PathString] = [ + *setup, +- sys.executable, "-SI", mkosi.sandbox.__file__, ++ @MKOSI_SANDBOX@, + "--proc", "/proc", + # We mounted a subdirectory of TMPDIR to /var/tmp so we unset TMPDIR so that /tmp or /var/tmp are used instead. + "--unsetenv", "TMPDIR", +@@ -563,7 +563,7 @@ def apivfs_options(*, root: Path = Path("/buildroot")) -> list[PathString]: + def apivfs_script_cmd(*, tools: bool, options: Sequence[PathString] = ()) -> list[PathString]: + exe = Path(sys.executable) + return [ +- "python3" if tools or not exe.is_relative_to("/usr") else exe, "-SI", "/sandbox.py", ++ @MKOSI_SANDBOX@, + "--bind", "/", "/", + "--same-dir", + "--bind", "/var/tmp", "/buildroot/var/tmp", +@@ -597,7 +597,7 @@ def chroot_cmd( + options: Sequence[PathString] = (), + ) -> Iterator[list[PathString]]: + cmdline: list[PathString] = [ +- sys.executable, "-SI", mkosi.sandbox.__file__, ++ @MKOSI_SANDBOX@, + "--bind", root, "/", + # We mounted a subdirectory of TMPDIR to /var/tmp so we unset TMPDIR so that /tmp or /var/tmp are used instead. + "--unsetenv", "TMPDIR", +@@ -619,7 +619,7 @@ def chroot_cmd( + def chroot_script_cmd(*, tools: bool, network: bool = False, work: bool = False) -> list[PathString]: + exe = Path(sys.executable) + return [ +- "python3" if tools or not exe.is_relative_to("/usr") else exe, "-SI", "/sandbox.py", ++ @MKOSI_SANDBOX@, + "--bind", "/buildroot", "/", + "--bind", "/var/tmp", "/var/tmp", + *apivfs_options(root=Path("/")), +-- +2.45.2 diff --git a/pkgs/tools/virtualization/mkosi/0002-Fix-library-resolving.patch b/pkgs/tools/virtualization/mkosi/0002-Fix-library-resolving.patch new file mode 100644 index 000000000000..8f4f3110d7ea --- /dev/null +++ b/pkgs/tools/virtualization/mkosi/0002-Fix-library-resolving.patch @@ -0,0 +1,36 @@ +From a1e6ccfeaf8ef10361280b9ecad958e9d556005b Mon Sep 17 00:00:00 2001 +From: Moritz Sanft <58110325+msanft@users.noreply.github.com> +Date: Tue, 3 Sep 2024 09:00:34 +0200 +Subject: [PATCH 2/3] Fix library resolving + +As ctypes doesn't do lookups in the Nix store for libraries, we supply the exact paths. + +Signed-off-by: Moritz Sanft <58110325+msanft@users.noreply.github.com> +--- + mkosi/sandbox/__init__.py | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/mkosi/sandbox/__init__.py b/mkosi/sandbox/__init__.py +index 7db340c5..3d0a0e56 100644 +--- a/mkosi/sandbox/__init__.py ++++ b/mkosi/sandbox/__init__.py +@@ -78,7 +78,7 @@ class cap_user_data_t(ctypes.Structure): + ] + + +-libc = ctypes.CDLL(None, use_errno=True) ++libc = ctypes.CDLL("@LIBC@", use_errno=True) + + libc.syscall.restype = ctypes.c_long + libc.unshare.argtypes = (ctypes.c_int,) +@@ -175,7 +175,7 @@ def seccomp_suppress_chown() -> None: + Unfortunately, non-root users can only create files owned by their own uid. To still allow non-root users to build + images, if requested we install a seccomp filter that makes calls to chown() and friends a noop. + """ +- libseccomp = ctypes.CDLL("libseccomp.so.2") ++ libseccomp = ctypes.CDLL("@LIBSECCOMP@") + if libseccomp is None: + raise FileNotFoundError("libseccomp.so.2") + +-- +2.45.2 diff --git a/pkgs/tools/virtualization/mkosi/0003-Fix-QEMU-firmware-path.patch b/pkgs/tools/virtualization/mkosi/0003-Fix-QEMU-firmware-path.patch new file mode 100644 index 000000000000..028a581a9b7d --- /dev/null +++ b/pkgs/tools/virtualization/mkosi/0003-Fix-QEMU-firmware-path.patch @@ -0,0 +1,25 @@ +From e834d51aa2542b141ceafdd42285ded6a9997c90 Mon Sep 17 00:00:00 2001 +From: Moritz Sanft <58110325+msanft@users.noreply.github.com> +Date: Tue, 3 Sep 2024 09:09:19 +0200 +Subject: [PATCH 3/3] Fix QEMU firmware path + +Signed-off-by: Moritz Sanft <58110325+msanft@users.noreply.github.com> +--- + mkosi/qemu.py | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/mkosi/qemu.py b/mkosi/qemu.py +index b98bec65..886598aa 100644 +--- a/mkosi/qemu.py ++++ b/mkosi/qemu.py +@@ -182,7 +182,7 @@ def find_ovmf_firmware(config: Config, qemu: Path, firmware: QemuFirmware) -> Op + + tools = Path("/") if any(qemu.is_relative_to(d) for d in config.extra_search_paths) else config.tools() + +- desc = list((tools / "usr/share/qemu/firmware").glob("*")) ++ desc = list((tools / "@QEMU_FIRMWARE@").glob("*")) + if tools == Path("/"): + desc += list((tools / "etc/qemu/firmware").glob("*")) + +-- +2.45.2 diff --git a/pkgs/tools/virtualization/mkosi/default.nix b/pkgs/tools/virtualization/mkosi/default.nix index a9262ff056be..2f5dea5481fb 100644 --- a/pkgs/tools/virtualization/mkosi/default.nix +++ b/pkgs/tools/virtualization/mkosi/default.nix @@ -1,29 +1,31 @@ -{ lib -, fetchFromGitHub -, stdenv -, python3 -, bubblewrap -, systemd -, pandoc -, kmod -, gnutar -, util-linux -, cpio -, bash -, coreutils -, btrfs-progs +{ + lib, + fetchFromGitHub, + stdenv, + python3, + systemd, + pandoc, + kmod, + gnutar, + util-linux, + cpio, + bash, + coreutils, + btrfs-progs, + libseccomp, + replaceVars, # Python packages -, setuptools -, setuptools-scm -, wheel -, buildPythonApplication -, pytestCheckHook -, pefile + setuptools, + setuptools-scm, + wheel, + buildPythonApplication, + pytestCheckHook, + pefile, # Optional dependencies -, withQemu ? false -, qemu + withQemu ? false, + qemu, }: let # For systemd features used by mkosi, see @@ -38,34 +40,51 @@ let withKernelInstall = true; }; - python3pefile = python3.withPackages (ps: with ps; [ - pefile - ]); + python3pefile = python3.withPackages ( + ps: with ps; [ + pefile + ] + ); in buildPythonApplication rec { pname = "mkosi"; - version = "22"; + version = "24.3-unstable-2024-08-28"; format = "pyproject"; - outputs = [ "out" "man" ]; + outputs = [ + "out" + "man" + ]; src = fetchFromGitHub { owner = "systemd"; repo = "mkosi"; - rev = "v${version}"; - hash = "sha256-Zom1GlyhqgpTKfjcBOUEJMlubSn+TQsk97js1/UfDHY="; + rev = "8c2f828701a1bdb3dc9b80d6f2ab979f0430a6b8"; + hash = "sha256-rO/4ki2nAJQN2slmYuHKESGBBDMXC/ikGf6dMDcKFr4="; }; - # Fix ctypes finding library - # https://github.com/NixOS/nixpkgs/issues/7307 - postPatch = lib.optionalString stdenv.isLinux '' - substituteInPlace mkosi/user.py \ - --replace-fail 'ctypes.util.find_library("c")' "'${stdenv.cc.libc}/lib/libc.so.6'" - substituteInPlace mkosi/__init__.py \ - --replace-fail '/usr/lib/systemd/ukify' "${systemdForMkosi}/lib/systemd/ukify" - '' + lib.optionalString withQemu '' - substituteInPlace mkosi/qemu.py \ - --replace-fail "usr/share/qemu/firmware" "${qemu}/share/qemu/firmware" + patches = + [ + (replaceVars ./0001-Use-wrapped-binaries-instead-of-Python-interpreter.patch { + UKIFY = "${systemdForMkosi}/lib/systemd/ukify"; + PYTHON_PEFILE = "${python3pefile}/bin/python3.12"; + MKOSI_SANDBOX = "~MKOSI_SANDBOX~"; # to satisfy replaceVars, will be replaced in postPatch + }) + (replaceVars ./0002-Fix-library-resolving.patch { + LIBC = "${stdenv.cc.libc}/lib/libc.so.6"; + LIBSECCOMP = "${libseccomp.lib}/lib/libseccomp.so.2"; + }) + ] + ++ lib.optional withQemu ( + replaceVars ./0003-Fix-QEMU-firmware-path.patch { + QEMU_FIRMWARE = "${qemu}/share/qemu/firmware"; + } + ); + + postPatch = '' + # As we need the $out reference, we can't use `replaceVars` here. + substituteInPlace mkosi/run.py \ + --replace-fail '~MKOSI_SANDBOX~' "\"$out/bin/mkosi-sandbox\"" ''; nativeBuildInputs = [ @@ -75,19 +94,20 @@ buildPythonApplication rec { wheel ]; - propagatedBuildInputs = [ - bash - btrfs-progs - bubblewrap - coreutils - cpio - gnutar - kmod - systemdForMkosi - util-linux - ] ++ lib.optional withQemu [ - qemu - ]; + propagatedBuildInputs = + [ + bash + btrfs-progs + coreutils + cpio + gnutar + kmod + systemdForMkosi + util-linux + ] + ++ lib.optional withQemu [ + qemu + ]; postBuild = '' ./tools/make-man-page.sh @@ -97,27 +117,21 @@ buildPythonApplication rec { pytestCheckHook ]; - pythonImportsCheck = [ - "mkosi" - ]; - postInstall = '' mkdir -p $out/share/man/man1 mv mkosi/resources/mkosi.1 $out/share/man/man1/ ''; - makeWrapperArgs = [ - "--set MKOSI_INTERPRETER ${python3pefile}/bin/python3" - "--prefix PYTHONPATH : \"$PYTHONPATH\"" - ]; - meta = with lib; { description = "Build legacy-free OS images"; homepage = "https://github.com/systemd/mkosi"; changelog = "https://github.com/systemd/mkosi/releases/tag/v${version}"; license = licenses.lgpl21Only; mainProgram = "mkosi"; - maintainers = with maintainers; [ malt3 ]; + maintainers = with maintainers; [ + malt3 + msanft + ]; platforms = platforms.linux; # `mkosi qemu` boot fails in the uefi shell, image isn't found. broken = withQemu;