Repository: systemd/mkosi

Issue:
Cannot build a Debian image on Arch Linux because of `DPkg::Path`
Building a simple Debian image on Arch Linux currently fails (with `apt` 2.6.0 packaged and installed from the AUR):

<details>
<summary><code>mkosi --cache-dir ~/.cache/mkosi/ -d debian -r bullseye</code></summary>

```
‣ Removing output files…
‣ Building image
‣  Mounting image…
‣   Installing Debian
Get:1 http://deb.debian.org/debian bullseye InRelease [116 kB]
Get:2 http://security.debian.org/debian-security bullseye-security InRelease [48.4 kB]
Get:3 http://deb.debian.org/debian bullseye-updates InRelease [44.1 kB]
Get:4 http://security.debian.org/debian-security bullseye-security/main amd64 Packages [237 kB]
Get:5 http://security.debian.org/debian-security bullseye-security/main Translation-en [156 kB]
Get:6 http://deb.debian.org/debian bullseye/main amd64 Packages [8183 kB]
Get:7 http://deb.debian.org/debian bullseye/main Translation-en [6240 kB]
Get:8 http://deb.debian.org/debian bullseye-updates/main amd64 Packages [14.6 kB]
Get:9 http://deb.debian.org/debian bullseye-updates/main Translation-en [7929 B]
Fetched 15.0 MB in 3s (4623 kB/s)                                    
Reading package lists... Done
Reading package lists... Done
Building dependency tree... Done
The following additional packages will be installed:
  debconf gcc-10-base libacl1 libattr1 libaudit-common libaudit1 libblkid1 libbz2-1.0 libc6 libcap-ng0 libcom-err2 libcrypt1 libdb5.3 libdebconfclient0 libgcc-s1 libgcrypt20 libgmp10 libgpg-error0
  libgssapi-krb5-2 libk5crypto3 libkeyutils1 libkrb5-3 libkrb5support0 liblz4-1 liblzma5 libmount1 libnsl2 libpam-modules libpam-modules-bin libpam-runtime libpam0g libpcre2-8-0 libpcre3 libselinux1 libsmartcols1
  libssl1.1 libsystemd0 libtinfo6 libtirpc-common libtirpc3 libudev1 libuuid1 libzstd1 lsb-base mawk zlib1g
Suggested packages:
  bash-doc debconf-doc debconf-utils whiptail | dialog libterm-readline-gnu-perl libgtk3-perl libnet-ldap-perl perl debconf-kde-helper diffutils-doc wdiff apt debsig-verify mlocate | locate less glibc-doc
  libc-l10n locales rng-tools krb5-doc krb5-user libpam-doc sensible-utils bzip2 ncompress xz-utils tar-scripts tar-doc dosfstools kbd util-linux-locales
Recommended packages:
  bash-completion bsdextrautils apt-utils debconf-i18n manpages libidn2-0 libnss-nis libnss-nisplus libgpg-error-l10n krb5-locales uuid-runtime
The following NEW packages will be installed:
  base-files base-passwd bash bsdutils coreutils dash debconf debianutils diffutils dpkg findutils gcc-10-base grep gzip hostname init-system-helpers libacl1 libattr1 libaudit-common libaudit1 libblkid1
  libbz2-1.0 libc-bin libc6 libcap-ng0 libcom-err2 libcrypt1 libdb5.3 libdebconfclient0 libgcc-s1 libgcrypt20 libgmp10 libgpg-error0 libgssapi-krb5-2 libk5crypto3 libkeyutils1 libkrb5-3 libkrb5support0 liblz4-1
  liblzma5 libmount1 libnsl2 libpam-modules libpam-modules-bin libpam-runtime libpam0g libpcre2-8-0 libpcre3 libselinux1 libsmartcols1 libssl1.1 libsystemd0 libtinfo6 libtirpc-common libtirpc3 libudev1 libuuid1
  libzstd1 login lsb-base mawk ncurses-base ncurses-bin perl-base sed sysvinit-utils tar util-linux zlib1g
0 upgraded, 69 newly installed, 0 to remove and 0 not upgraded.
Need to get 0 B/26.8 MB of archives.
After this operation, 97.5 MB of additional disk space will be used.
Download complete and in download only mode
Hit:1 http://deb.debian.org/debian bullseye InRelease
Hit:2 http://security.debian.org/debian-security bullseye-security InRelease
Hit:3 http://deb.debian.org/debian bullseye-updates InRelease
Reading package lists... Done
Reading package lists... Done
Building dependency tree... Done
Suggested packages:
  bash-doc debconf-doc debconf-utils whiptail | dialog libterm-readline-gnu-perl libgtk3-perl libnet-ldap-perl perl debconf-kde-helper diffutils-doc wdiff apt debsig-verify mlocate | locate less glibc-doc
  libc-l10n locales rng-tools krb5-doc krb5-user libpam-doc sensible-utils bzip2 ncompress xz-utils tar-scripts tar-doc dosfstools kbd util-linux-locales
Recommended packages:
  bash-completion bsdextrautils apt-utils debconf-i18n manpages libidn2-0 libnss-nis libnss-nisplus libgpg-error-l10n krb5-locales uuid-runtime
The following NEW packages will be installed:
  base-files base-passwd bash bsdutils coreutils dash debconf debianutils diffutils dpkg findutils gcc-10-base grep gzip hostname init-system-helpers libacl1 libattr1 libaudit-common libaudit1 libblkid1
  libbz2-1.0 libc-bin libc6 libcap-ng0 libcom-err2 libcrypt1 libdb5.3 libdebconfclient0 libgcc-s1 libgcrypt20 libgmp10 libgpg-error0 libgssapi-krb5-2 libk5crypto3 libkeyutils1 libkrb5-3 libkrb5support0 liblz4-1
  liblzma5 libmount1 libnsl2 libpam-modules libpam-modules-bin libpam-runtime libpam0g libpcre2-8-0 libpcre3 libselinux1 libsmartcols1 libssl1.1 libsystemd0 libtinfo6 libtirpc-common libtirpc3 libudev1 libuuid1
  libzstd1 login lsb-base mawk ncurses-base ncurses-bin perl-base sed sysvinit-utils tar util-linux zlib1g
0 upgraded, 69 newly installed, 0 to remove and 0 not upgraded.
Need to get 0 B/26.8 MB of archives.
After this operation, 97.5 MB of additional disk space will be used.
Selecting previously unselected package gcc-10-base:amd64.
(Reading database ... 0 files and directories currently installed.)
Preparing to unpack .../gcc-10-base_10.2.1-6_amd64.deb ...
Unpacking gcc-10-base:amd64 (10.2.1-6) ...
Selecting previously unselected package libgcc-s1:amd64.
Preparing to unpack .../libgcc-s1_10.2.1-6_amd64.deb ...
Unpacking libgcc-s1:amd64 (10.2.1-6) ...
Selecting previously unselected package libcrypt1:amd64.
Preparing to unpack .../libcrypt1_1%3a4.4.18-4_amd64.deb ...
Unpacking libcrypt1:amd64 (1:4.4.18-4) ...
Selecting previously unselected package libc6:amd64.
Preparing to unpack .../libc6_2.31-13+deb11u5_amd64.deb ...
Use of uninitialized value in concatenation (.) or string at /usr/share/perl5/Debconf/Config.pm line 22.
Unpacking libc6:amd64 (2.31-13+deb11u5) ...
Selecting previously unselected package mawk.
Preparing to unpack .../mawk_1.3.4.20200120-2_amd64.deb ...
Unpacking mawk (1.3.4.20200120-2) ...
Setting up gcc-10-base:amd64 (10.2.1-6) ...
Setting up libgcc-s1:amd64 (10.2.1-6) ...
Setting up libcrypt1:amd64 (1:4.4.18-4) ...
Setting up libc6:amd64 (2.31-13+deb11u5) ...
Use of uninitialized value in concatenation (.) or string at /usr/share/perl5/Debconf/Config.pm line 22.
Setting up mawk (1.3.4.20200120-2) ...
Selecting previously unselected package base-files.
(Reading database ... 355 files and directories currently installed.)
Preparing to unpack .../base-files_11.1+deb11u6_amd64.deb ...
Unpacking base-files (11.1+deb11u6) ...
Selecting previously unselected package libtinfo6:amd64.
Preparing to unpack .../libtinfo6_6.2+20201114-2_amd64.deb ...
Unpacking libtinfo6:amd64 (6.2+20201114-2) ...
Selecting previously unselected package debianutils.
Preparing to unpack .../debianutils_4.11.2_amd64.deb ...
Unpacking debianutils (4.11.2) ...
Setting up libtinfo6:amd64 (6.2+20201114-2) ...
Selecting previously unselected package bash.
(Reading database ... 535 files and directories currently installed.)
Preparing to unpack .../bash_5.1-2+deb11u1_amd64.deb ...
Unpacking bash (5.1-2+deb11u1) ...
Selecting previously unselected package libgpg-error0:amd64.
Preparing to unpack .../libgpg-error0_1.38-2_amd64.deb ...
Unpacking libgpg-error0:amd64 (1.38-2) ...
Selecting previously unselected package libgcrypt20:amd64.
Preparing to unpack .../libgcrypt20_1.8.7-6_amd64.deb ...
Unpacking libgcrypt20:amd64 (1.8.7-6) ...
Selecting previously unselected package liblz4-1:amd64.
Preparing to unpack .../liblz4-1_1.9.3-2_amd64.deb ...
Unpacking liblz4-1:amd64 (1.9.3-2) ...
Selecting previously unselected package liblzma5:amd64.
Preparing to unpack .../liblzma5_5.2.5-2.1~deb11u1_amd64.deb ...
Unpacking liblzma5:amd64 (5.2.5-2.1~deb11u1) ...
Selecting previously unselected package libzstd1:amd64.
Preparing to unpack .../libzstd1_1.4.8+dfsg-2.1_amd64.deb ...
Unpacking libzstd1:amd64 (1.4.8+dfsg-2.1) ...
Setting up libgpg-error0:amd64 (1.38-2) ...
Setting up libgcrypt20:amd64 (1.8.7-6) ...
Setting up liblz4-1:amd64 (1.9.3-2) ...
Setting up liblzma5:amd64 (5.2.5-2.1~deb11u1) ...
Setting up libzstd1:amd64 (1.4.8+dfsg-2.1) ...
Selecting previously unselected package libsystemd0:amd64.
(Reading database ... 722 files and directories currently installed.)
Preparing to unpack .../libsystemd0_247.3-7+deb11u1_amd64.deb ...
Unpacking libsystemd0:amd64 (247.3-7+deb11u1) ...
Setting up libsystemd0:amd64 (247.3-7+deb11u1) ...
Selecting previously unselected package bsdutils.
(Reading database ... 727 files and directories currently installed.)
Preparing to unpack .../bsdutils_1%3a2.36.1-8+deb11u1_amd64.deb ...
Unpacking bsdutils (1:2.36.1-8+deb11u1) ...
Selecting previously unselected package libacl1:amd64.
Preparing to unpack .../libacl1_2.2.53-10_amd64.deb ...
Unpacking libacl1:amd64 (2.2.53-10) ...
Selecting previously unselected package libattr1:amd64.
Preparing to unpack .../libattr1_1%3a2.4.48-6_amd64.deb ...
Unpacking libattr1:amd64 (1:2.4.48-6) ...
Selecting previously unselected package libgmp10:amd64.
Preparing to unpack .../libgmp10_2%3a6.2.1+dfsg-1+deb11u1_amd64.deb ...
Unpacking libgmp10:amd64 (2:6.2.1+dfsg-1+deb11u1) ...
Selecting previously unselected package libpcre2-8-0:amd64.
Preparing to unpack .../libpcre2-8-0_10.36-2+deb11u1_amd64.deb ...
Unpacking libpcre2-8-0:amd64 (10.36-2+deb11u1) ...
Selecting previously unselected package libselinux1:amd64.
Preparing to unpack .../libselinux1_3.1-3_amd64.deb ...
Unpacking libselinux1:amd64 (3.1-3) ...
Setting up libacl1:amd64 (2.2.53-10) ...
Setting up libattr1:amd64 (1:2.4.48-6) ...
Setting up libgmp10:amd64 (2:6.2.1+dfsg-1+deb11u1) ...
Setting up libpcre2-8-0:amd64 (10.36-2+deb11u1) ...
Setting up libselinux1:amd64 (3.1-3) ...
Selecting previously unselected package coreutils.
(Reading database ... 783 files and directories currently installed.)
Preparing to unpack .../coreutils_8.32-4+b1_amd64.deb ...
Unpacking coreutils (8.32-4+b1) ...
Selecting previously unselected package libbz2-1.0:amd64.
Preparing to unpack .../libbz2-1.0_1.0.8-4_amd64.deb ...
Unpacking libbz2-1.0:amd64 (1.0.8-4) ...
Selecting previously unselected package zlib1g:amd64.
Preparing to unpack .../zlib1g_1%3a1.2.11.dfsg-2+deb11u2_amd64.deb ...
Unpacking zlib1g:amd64 (1:1.2.11.dfsg-2+deb11u2) ...
Selecting previously unselected package tar.
Preparing to unpack .../tar_1.34+dfsg-1_amd64.deb ...
Unpacking tar (1.34+dfsg-1) ...
Setting up libbz2-1.0:amd64 (1.0.8-4) ...
Setting up zlib1g:amd64 (1:1.2.11.dfsg-2+deb11u2) ...
Selecting previously unselected package dpkg.
(Reading database ... 1224 files and directories currently installed.)
Preparing to unpack .../dpkg_1.20.12_amd64.deb ...
Unpacking dpkg (1.20.12) ...
Setting up tar (1.34+dfsg-1) ...
update-alternatives: using /usr/sbin/rmt-tar to provide /usr/sbin/rmt (rmt) in auto mode
Setting up dpkg (1.20.12) ...
Selecting previously unselected package perl-base.
(Reading database ... 1447 files and directories currently installed.)
Preparing to unpack .../perl-base_5.32.1-4+deb11u2_amd64.deb ...
Unpacking perl-base (5.32.1-4+deb11u2) ...
Setting up perl-base (5.32.1-4+deb11u2) ...
Selecting previously unselected package debconf.
(Reading database ... 2172 files and directories currently installed.)
Preparing to unpack .../debconf_1.5.77_all.deb ...
Unpacking debconf (1.5.77) ...
Selecting previously unselected package dash.
Preparing to unpack .../dash_0.5.11+git20200708+dd9ef66-5_amd64.deb ...
Unpacking dash (0.5.11+git20200708+dd9ef66-5) ...
Selecting previously unselected package diffutils.
Preparing to unpack .../diffutils_1%3a3.7-5_amd64.deb ...
Unpacking diffutils (1:3.7-5) ...
Selecting previously unselected package findutils.
Preparing to unpack .../findutils_4.8.0-1_amd64.deb ...
Unpacking findutils (4.8.0-1) ...
Selecting previously unselected package libpcre3:amd64.
Preparing to unpack .../libpcre3_2%3a8.39-13_amd64.deb ...
Unpacking libpcre3:amd64 (2:8.39-13) ...
Setting up libpcre3:amd64 (2:8.39-13) ...
Selecting previously unselected package grep.
(Reading database ... 2467 files and directories currently installed.)
Preparing to unpack .../archives/grep_3.6-1_amd64.deb ...
Unpacking grep (3.6-1) ...
Selecting previously unselected package gzip.
Preparing to unpack .../gzip_1.10-4+deb11u1_amd64.deb ...
Unpacking gzip (1.10-4+deb11u1) ...
Selecting previously unselected package hostname.
Preparing to unpack .../hostname_3.23_amd64.deb ...
Unpacking hostname (3.23) ...
Selecting previously unselected package libaudit-common.
Preparing to unpack .../libaudit-common_1%3a3.0-2_all.deb ...
Unpacking libaudit-common (1:3.0-2) ...
Selecting previously unselected package libcap-ng0:amd64.
Preparing to unpack .../libcap-ng0_0.7.9-2.2+b1_amd64.deb ...
Unpacking libcap-ng0:amd64 (0.7.9-2.2+b1) ...
Selecting previously unselected package libaudit1:amd64.
Preparing to unpack .../libaudit1_1%3a3.0-2_amd64.deb ...
Unpacking libaudit1:amd64 (1:3.0-2) ...
Selecting previously unselected package libpam0g:amd64.
Preparing to unpack .../libpam0g_1.4.0-9+deb11u1_amd64.deb ...
Unpacking libpam0g:amd64 (1.4.0-9+deb11u1) ...
Selecting previously unselected package libdb5.3:amd64.
Preparing to unpack .../libdb5.3_5.3.28+dfsg1-0.8_amd64.deb ...
Unpacking libdb5.3:amd64 (5.3.28+dfsg1-0.8) ...
Selecting previously unselected package libcom-err2:amd64.
Preparing to unpack .../libcom-err2_1.46.2-2_amd64.deb ...
Unpacking libcom-err2:amd64 (1.46.2-2) ...
Selecting previously unselected package libkrb5support0:amd64.
Preparing to unpack .../libkrb5support0_1.18.3-6+deb11u3_amd64.deb ...
Unpacking libkrb5support0:amd64 (1.18.3-6+deb11u3) ...
Selecting previously unselected package libk5crypto3:amd64.
Preparing to unpack .../libk5crypto3_1.18.3-6+deb11u3_amd64.deb ...
Unpacking libk5crypto3:amd64 (1.18.3-6+deb11u3) ...
Selecting previously unselected package libkeyutils1:amd64.
Preparing to unpack .../libkeyutils1_1.6.1-2_amd64.deb ...
Unpacking libkeyutils1:amd64 (1.6.1-2) ...
Selecting previously unselected package libssl1.1:amd64.
Preparing to unpack .../libssl1.1_1.1.1n-0+deb11u4_amd64.deb ...
Unpacking libssl1.1:amd64 (1.1.1n-0+deb11u4) ...
Selecting previously unselected package libkrb5-3:amd64.
Preparing to unpack .../libkrb5-3_1.18.3-6+deb11u3_amd64.deb ...
Unpacking libkrb5-3:amd64 (1.18.3-6+deb11u3) ...
Selecting previously unselected package libgssapi-krb5-2:amd64.
Preparing to unpack .../libgssapi-krb5-2_1.18.3-6+deb11u3_amd64.deb ...
Unpacking libgssapi-krb5-2:amd64 (1.18.3-6+deb11u3) ...
Selecting previously unselected package libtirpc-common.
Preparing to unpack .../libtirpc-common_1.3.1-1+deb11u1_all.deb ...
Unpacking libtirpc-common (1.3.1-1+deb11u1) ...
Selecting previously unselected package libtirpc3:amd64.
Preparing to unpack .../libtirpc3_1.3.1-1+deb11u1_amd64.deb ...
Unpacking libtirpc3:amd64 (1.3.1-1+deb11u1) ...
Selecting previously unselected package libnsl2:amd64.
Preparing to unpack .../libnsl2_1.3.0-2_amd64.deb ...
Unpacking libnsl2:amd64 (1.3.0-2) ...
Selecting previously unselected package libpam-modules-bin.
Preparing to unpack .../libpam-modules-bin_1.4.0-9+deb11u1_amd64.deb ...
Unpacking libpam-modules-bin (1.4.0-9+deb11u1) ...
Setting up libaudit-common (1:3.0-2) ...
Setting up libcap-ng0:amd64 (0.7.9-2.2+b1) ...
Setting up libaudit1:amd64 (1:3.0-2) ...
Setting up libdb5.3:amd64 (5.3.28+dfsg1-0.8) ...
Setting up libcom-err2:amd64 (1.46.2-2) ...
Setting up libkrb5support0:amd64 (1.18.3-6+deb11u3) ...
Setting up libk5crypto3:amd64 (1.18.3-6+deb11u3) ...
Setting up libkeyutils1:amd64 (1.6.1-2) ...
Setting up debconf (1.5.77) ...
Use of uninitialized value in concatenation (.) or string at /usr/share/perl5/Debconf/Config.pm line 22.
Setting up libssl1.1:amd64 (1.1.1n-0+deb11u4) ...
Use of uninitialized value in concatenation (.) or string at /usr/share/perl5/Debconf/Config.pm line 22.
Setting up libkrb5-3:amd64 (1.18.3-6+deb11u3) ...
Setting up libgssapi-krb5-2:amd64 (1.18.3-6+deb11u3) ...
Setting up libtirpc-common (1.3.1-1+deb11u1) ...
Setting up libtirpc3:amd64 (1.3.1-1+deb11u1) ...
Setting up libnsl2:amd64 (1.3.0-2) ...
Setting up libpam0g:amd64 (1.4.0-9+deb11u1) ...
Use of uninitialized value in concatenation (.) or string at /usr/share/perl5/Debconf/Config.pm line 22.
Setting up libpam-modules-bin (1.4.0-9+deb11u1) ...
Selecting previously unselected package libpam-modules:amd64.
(Reading database ... 2704 files and directories currently installed.)
Preparing to unpack .../libpam-modules_1.4.0-9+deb11u1_amd64.deb ...
Use of uninitialized value in concatenation (.) or string at /usr/share/perl5/Debconf/Config.pm line 22.
Unpacking libpam-modules:amd64 (1.4.0-9+deb11u1) ...
Selecting previously unselected package libpam-runtime.
Preparing to unpack .../libpam-runtime_1.4.0-9+deb11u1_all.deb ...
Unpacking libpam-runtime (1.4.0-9+deb11u1) ...
Setting up libpam-modules:amd64 (1.4.0-9+deb11u1) ...
Setting up libpam-runtime (1.4.0-9+deb11u1) ...
Use of uninitialized value in concatenation (.) or string at /usr/share/perl5/Debconf/Config.pm line 22.
/var/lib/dpkg/info/libpam-runtime.postinst: 32: pam-auth-update: not found
dpkg: error processing package libpam-runtime (--configure):
 installed libpam-runtime package post-installation script subprocess returned error exit status 127
Errors were encountered while processing:
 libpam-runtime
E: Sub-process dpkg returned an error code (1)
‣ Error: "apt-get install gcc-10-base libgcc-s1 libcrypt1 libc6 mawk base-files libtinfo6 debianutils bash libgpg-error0 libgcrypt20 liblz4-1 liblzma5 libzstd1 libsystemd0 bsdutils libacl1 libattr1 libgmp10 libpcre2-8-0 libselinux1 coreutils libbz2-1.0 zlib1g tar dpkg perl-base debconf dash diffutils findutils libpcre3 grep gzip hostname libaudit-common libcap-ng0 libaudit1 libpam0g libdb5.3 libcom-err2 libkrb5support0 libk5crypto3 libkeyutils1 libssl1.1 libkrb5-3 libgssapi-krb5-2 libtirpc-common libtirpc3 libnsl2 libpam-modules-bin libpam-modules libpam-runtime login ncurses-bin sed libblkid1 libmount1 libsmartcols1 libudev1 libuuid1 util-linux libdebconfclient0 base-passwd init-system-helpers libc-bin ncurses-base lsb-base sysvinit-utils" returned non-zero exit code 100.
```

</details>

However, it works if I remove the line that injects the current `$PATH` in apt.conf: https://github.com/systemd/mkosi/blob/ec097ee1ba6a33e632e6f8446ae1605c1e064740/mkosi/distributions/debian.py#L206

By calling `apt-config dump` at the end of `setup_apt` with the same `env` parameter as `invoke_apt`, I find that the default configuration is `DPkg::Path "/usr/sbin:/usr/bin:/sbin:/bin";`. My guess is that the lookup for `pam-auth-update` fails as it's in `/usr/sbin` and the default `$PATH` for Arch Linux is `/usr/local/sbin:/usr/local/bin:/usr/bin`.

However, I do not understand the point of overriding `DPkg::Path` with the current `$PATH`. `pam-auth-update` is Debian specific and does not exist on Arch Linux. Therefore, `DPkg::Path` is already relative to the chroot or it wouldn't work with the default configuration.




Discussion:

Resolving patch:
diff --git a/mkosi/distributions/debian.py b/mkosi/distributions/debian.py
--- a/mkosi/distributions/debian.py
+++ b/mkosi/distributions/debian.py
@@ -1,7 +1,7 @@
 # SPDX-License-Identifier: LGPL-2.1+
 
 import os
-import subprocess
+import shutil
 import tempfile
 from collections.abc import Sequence
 from pathlib import Path
@@ -10,7 +10,7 @@
 from mkosi.backend import MkosiState
 from mkosi.distributions import DistributionInstaller
 from mkosi.run import run, run_with_apivfs
-from mkosi.types import _FILE, CompletedProcess, PathString
+from mkosi.types import CompletedProcess, PathString
 
 
 class DebianInstaller(DistributionInstaller):
@@ -80,35 +80,20 @@ def install(cls, state: MkosiState) -> None:
             state.root.joinpath(d).symlink_to(f"usr/{d}")
             state.root.joinpath(f"usr/{d}").mkdir(mode=0o755)
 
-        # Next, we download the essential debs. We add usr-is-merged to assert the system is usr-merged
-        # already and to prevent usrmerge from being installed and pulling in all its dependencies.
-        setup_apt(state, cls.repositories(state))
-        invoke_apt(state, "update")
-        invoke_apt(state, "install", ["--download-only", "?essential", "?name(usr-is-merged)"])
-
-        # Next, invoke apt install with an info fd to which it writes the debs it's operating on. However, by
+        # Next, we invoke apt install with an info fd to which it writes the debs it's operating on. When
         # passing "-oDebug::pkgDpkgPm=1", apt will not actually execute any dpkg commands, which turns the
-        # install command into a noop that tells us the full paths to the essential debs and any dependencies
-        # that apt would install in the apt cache.
+        # install command into a command that downloads the debs and tells us the full paths to the essential
+        # debs and any dependencies that apt would install in the apt cache.
         with tempfile.TemporaryFile(dir=state.workspace, mode="w+") as f:
             os.set_inheritable(f.fileno(), True)
 
-            options = [
+            cls.install_packages(state, [
                 "-oDebug::pkgDpkgPm=1",
                 f"-oAPT::Keep-Fds::={f.fileno()}",
-                f"-oDPkg::Tools::options::'cat >&$fd'::InfoFD={f.fileno()}",
+                f"-oDPkg::Tools::options::'cat >&{f.fileno()}'::InfoFD={f.fileno()}",
                 f"-oDpkg::Pre-Install-Pkgs::=cat >&{f.fileno()}",
                 "?essential", "?name(usr-is-merged)",
-            ]
-
-            try:
-                invoke_apt(state, "install", options, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
-            except subprocess.CalledProcessError:
-                # By default, we run the command with stdout/stderr redirected to /dev/null because it
-                # produces a lot of useless output. If it fails, let's rerun it with regular stdout/stderr so
-                # we can debug the error.
-                invoke_apt(state, "install", options)
-                raise
+            ])
 
             f.seek(0)
             essential = f.read().strip().splitlines()
@@ -202,8 +187,7 @@ def setup_apt(state: MkosiState, repos: Sequence[str]) -> None:
             Dir::Etc::trusted "/usr/share/keyrings/{state.config.release}-archive-keyring";
             Dir::Etc::trustedparts "/usr/share/keyrings";
             Dir::Log "{state.workspace / "apt/log"}";
-            Dir::Bin::dpkg "dpkg";
-            DPkg::Path "{os.environ["PATH"]}";
+            Dir::Bin::dpkg "{shutil.which("dpkg")}";
             DPkg::Options:: "--root={state.root}";
             DPkg::Options:: "--log={state.workspace / "apt/dpkg.log"}";
             DPkg::Options:: "--force-unsafe-io";
@@ -223,8 +207,6 @@ def invoke_apt(
     state: MkosiState,
     operation: str,
     extra: Sequence[str] = tuple(),
-    stdout: _FILE = None,
-    stderr: _FILE = None,
 ) -> CompletedProcess:
     env: dict[str, PathString] = dict(
         APT_CONFIG=state.workspace / "apt/apt.conf",
@@ -234,4 +216,4 @@ def invoke_apt(
         INITRD="No",
     )
 
-    return run_with_apivfs(state, ["apt-get", operation, *extra], env=env, stdout=stdout, stderr=stderr)
+    return run_with_apivfs(state, ["apt-get", operation, *extra], env=env)
diff --git a/mkosi/run.py b/mkosi/run.py
--- a/mkosi/run.py
+++ b/mkosi/run.py
@@ -267,7 +267,6 @@ def run_with_apivfs(
     cmd: Sequence[PathString],
     bwrap_params: Sequence[PathString] = tuple(),
     stdout: _FILE = None,
-    stderr: _FILE = None,
     env: Mapping[str, PathString] = {},
 ) -> CompletedProcess:
     cmdline: list[PathString] = [
@@ -306,7 +305,7 @@ def run_with_apivfs(
 
     try:
         return _run([*cmdline, template.format(shlex.join(str(s) for s in cmd))],
-                   text=True, stdout=stdout, stderr=stderr, env=env)
+                   text=True, stdout=stdout, env=env)
     except subprocess.CalledProcessError as e:
         if "run" in ARG_DEBUG:
             _run([*cmdline, template.format("sh")], check=False, env=env)


Test patch: