mkosi: Introduce build image

We want the exitrd image to be built with the latest systemd as well.
As the exitrd image is built as part of mkosi.images, and all subimages
are built before the main image, this implies the packages must be built
as a subimage in mkosi.images/ as well. So we introduce the build image and
move all logic related to building distribution packages there.

This also has the nice side effect of slimming down the main image as the
build dependencies are not installed into the main image anymore. It also
makes sure the packages are built in a "clean" chroot without any of the
other packages which we install in the main image available.
This commit is contained in:
Daan De Meyer 2024-07-12 15:33:49 +02:00
parent 72a8f508e5
commit 7205fc7dc3
51 changed files with 487 additions and 300 deletions

View File

@ -3,6 +3,24 @@
[Config]
MinimumVersion=23~devel
InitrdInclude=mkosi.initrd/
Dependencies=
exitrd
minimal-base
minimal-0
minimal-1
PassEnvironment=
NO_BUILD
NO_SYNC
WIPE
SANITIZERS
CFLAGS
LDFLAGS
LLVM
MESON_VERBOSE
MESON_OPTIONS
SYSEXT
WITH_DEBUG
[Output]
RepartDirectories=mkosi.repart
@ -14,11 +32,18 @@ CacheDirectory=build/mkosi.cache
BuildSourcesEphemeral=yes
Autologin=yes
PostInstallationScripts=mkosi.sanitizers.chroot
ExtraTrees=
mkosi.crt:/usr/lib/verity.d/mkosi.crt # sysext verification key
mkosi.leak-sanitizer-suppressions:/usr/lib/systemd/leak-sanitizer-suppressions
mkosi.coredump-journal-storage.conf:/usr/lib/systemd/coredump.conf.d/10-coredump-journal-storage.conf
%O/minimal-0.root-%a.raw:/usr/share/minimal_0.raw
%O/minimal-0.root-%a-verity.raw:/usr/share/minimal_0.verity
%O/minimal-0.root-%a-verity-sig.raw:/usr/share/minimal_0.verity.sig
%O/minimal-1.root-%a.raw:/usr/share/minimal_1.raw
%O/minimal-1.root-%a-verity.raw:/usr/share/minimal_1.verity
%O/minimal-1.root-%a-verity-sig.raw:/usr/share/minimal_1.verity.sig
%O/minimal-base:/usr/share/TEST-13-NSPAWN-container-template
%O/exitrd:/exitrd
Environment=
SYSTEMD_REPART_OVERRIDE_FSTYPE_ROOT=%F
@ -57,16 +82,6 @@ KernelCommandLine=systemd.crash_shell
KernelModulesInitrdExclude=.*
KernelModulesInitrdInclude=default
ExtraTrees=
%O/minimal-0.root-%a.raw:/usr/share/minimal_0.raw
%O/minimal-0.root-%a-verity.raw:/usr/share/minimal_0.verity
%O/minimal-0.root-%a-verity-sig.raw:/usr/share/minimal_0.verity.sig
%O/minimal-1.root-%a.raw:/usr/share/minimal_1.raw
%O/minimal-1.root-%a-verity.raw:/usr/share/minimal_1.verity
%O/minimal-1.root-%a-verity-sig.raw:/usr/share/minimal_1.verity.sig
%O/minimal-base:/usr/share/TEST-13-NSPAWN-container-template
%O/exitrd:/exitrd
InitrdPackages=
btrfs-progs
findutils
@ -79,7 +94,6 @@ Packages=
bash-completion
bpftrace
btrfs-progs
clang
coreutils
curl
diffutils
@ -97,8 +111,6 @@ Packages=
kmod
knot
less
lld
llvm
lvm2
man
mdadm
@ -117,7 +129,6 @@ Packages=
sed
socat
strace
systemd
tar
tmux
tree

View File

@ -4,11 +4,6 @@
Distribution=arch
[Content]
Environment=
GIT_URL=https://gitlab.archlinux.org/archlinux/packaging/packages/systemd.git
GIT_BRANCH=main
GIT_COMMIT=d74b24c7c6077740c35a876445febe6d26bf013c
VolatilePackages=
systemd
systemd-libs
@ -20,18 +15,14 @@ VolatilePackages=
Packages=
bind
bpf
compiler-rt
compsize
cryptsetup
dbus-broker
dbus-broker-units
debugedit
dhcp
f2fs-tools
fakeroot
git
gnutls
gnutls
iproute
iputils
linux
@ -43,7 +34,6 @@ Packages=
openssl
pacman
perf
pkgconf
polkit
procps-ng
psmisc
@ -57,11 +47,9 @@ Packages=
stress-ng
tgt
tpm2-tools
tpm2-tss
vim
InitrdPackages=
compiler-rt
tpm2-tools
InitrdVolatilePackages=

View File

@ -2,28 +2,32 @@
# SPDX-License-Identifier: LGPL-2.1-or-later
set -e
if [ "$1" = "build" ] || ((NO_BUILD)); then
if [[ "$1" == "build" ]]; then
exit 0
fi
# shellcheck source=/dev/null
. "$BUILDROOT/usr/lib/os-release"
DEPS=""
if [ ! -f "pkg/$ID/PKGBUILD" ]; then
echo "PKGBUILD not found at pkg/$ID/PKGBUILD, run mkosi once with -ff to make sure the PKGBUILD is cloned" >&2
exit 1
fi
while read -r PACKAGE; do
DEPS="$DEPS $(
pacman --sync --info "$PACKAGE" |
sed '1,/^$/d' | # Only keep result from first repository (delete everything after first blank line).
sed --quiet 's/^Depends On *: //p' # Filter out everything except "Depends On:" line and fetch dependencies from it.
)"
# We get depends and optdepends from .SRCINFO as getting them from the PKGBUILD is rather complex.
sed --expression 's/^[ \t]*//' "pkg/$ID/.SRCINFO" |
grep --regexp '^depends =' --regexp '^optdepends =' |
sed --expression 's/^depends = //' --expression 's/^optdepends = //' --expression 's/:.*//' --expression 's/=.*//' |
xargs --delimiter '\n' mkosi-install
DEPS="$DEPS $(
pacman --sync --info "$PACKAGE" |
sed '1,/^$/d' | # Only keep result from first repository (delete everything after first blank line).
sed --quiet '/Optional Deps/,/Conflicts With/{/Conflicts With/!p}' | # Get every line from "Optional Deps" (inclusive) until "Conflicts With" (exclusive).
sed 's/Optional Deps *: //' | # Drop "Optional Deps :" from first line.
sed 's/ *\(.*\):.*/\1/' | # Drop descriptions (everything after first colon for all lines).
tr '\n' ' ' # Transform newlines to whitespace.
)"
done < <(jq --raw-output .VolatilePackages[] <"$MKOSI_CONFIG")
# We get makedepends from the PKGBUILD as .SRCINFO can't encode conditional dependencies depending on
# whether some environment variable is set or not.
# shellcheck source=/dev/null
_systemd_UPSTREAM=1 . "pkg/$ID/PKGBUILD"
# shellcheck disable=SC2154
mkosi-install "${makedepends[@]}"
echo "$DEPS" |
xargs | # Remove extra whitespace.
tr ' ' '\n' |
grep --invert-match --regexp systemd --regexp None | # systemd packages will be installed later on.
sort --unique |
xargs --delimiter '\n' --no-run-if-empty mkosi-install

View File

@ -11,6 +11,7 @@ VolatilePackages=
systemd-container
systemd-devel
systemd-journal-remote
systemd-libs
systemd-networkd
systemd-networkd-defaults
systemd-oomd-defaults
@ -23,7 +24,6 @@ VolatilePackages=
Packages=
bind-utils
bpftool
compiler-rt
cryptsetup
device-mapper-event
device-mapper-multipath
@ -33,7 +33,6 @@ Packages=
git-core
glibc-langpack-de
glibc-langpack-en
gnutls
gnutls-utils
integritysetup
iproute
@ -41,9 +40,7 @@ Packages=
iputils
iscsi-initiator-utils
kernel-core
libasan
libcap-ng-utils
libubsan
man-db
nmap-ncat
openssh-clients
@ -57,8 +54,6 @@ Packages=
python3-pexpect
quota
rpm
rpm-build
rpmautospec
sbsigntools
softhsm
squashfs-tools

View File

@ -2,64 +2,18 @@
# SPDX-License-Identifier: LGPL-2.1-or-later
set -e
if [ "$1" = "build" ] || ((NO_BUILD)); then
if [[ "$1" == "build" ]]; then
exit 0
fi
# shellcheck source=/dev/null
. "$BUILDROOT/usr/lib/os-release"
mapfile -t PACKAGES < <(jq --raw-output .VolatilePackages[] <"$MKOSI_CONFIG")
if [ ! -f "pkg/$ID/systemd.spec" ]; then
echo "spec not found at pkg/$ID/systemd.spec, run mkosi with -ff to make sure the spec is cloned" >&2
exit 1
fi
for DEPS in --requires --buildrequires; do
mkosi-chroot \
rpmspec \
--with upstream \
--query \
"$DEPS" \
--define "_topdir /var/tmp" \
--define "_sourcedir pkg/$ID" \
"pkg/$ID/systemd.spec" |
grep --invert-match --regexp systemd --regexp /bin/sh --regexp "rpmlib(" --regexp udev --regexp grubby --regexp sdubby |
sort --unique |
tee /tmp/buildrequires |
xargs --delimiter '\n' mkosi-install
done
# rpmbuild -br tries to build a source package which means all source files have to exist which isn't the
# case when using --build-in-place so we get rid of the source file that doesn't exist to make it happy.
# TODO: Use -bd instead of -br and get rid of this once we don't need to build on CentOS Stream 9 anymore.
sed '/Source0/d' --in-place "pkg/$ID/systemd.spec"
until mkosi-chroot \
rpmbuild \
-br \
--build-in-place \
--with upstream \
--define "_topdir /var/tmp" \
--define "_sourcedir pkg/$ID" \
--define "_build_name_fmt %%{NAME}-%%{VERSION}-%%{RELEASE}.%%{ARCH}.rpm" \
"pkg/$ID/systemd.spec"
do
EXIT_STATUS=$?
if [ $EXIT_STATUS -ne 11 ]; then
exit $EXIT_STATUS
fi
mkosi-chroot \
rpm \
--query \
--package \
--requires \
/var/tmp/SRPMS/systemd-*.buildreqs.nosrc.rpm |
grep --invert-match '^rpmlib(' |
sort --unique >/tmp/dynamic-buildrequires
sort /tmp/buildrequires /tmp/dynamic-buildrequires |
uniq --unique |
tee --append /tmp/buildrequires |
xargs --delimiter '\n' mkosi-install
for DEPS in --requires --recommends --suggests; do
# We need --latest-limit=1 to only consider the newest version of the packages.
# --latest-limit=1 is per <name>.<arch> so we have to pass --arch= explicitly to make sure i686 packages
# are not considerd on x86-64.
dnf repoquery --arch="$DISTRIBUTION_ARCHITECTURE" --latest-limit=1 --quiet "$DEPS" "${PACKAGES[@]}" |
grep --invert-match --regexp systemd --regexp udev --regexp /bin/sh --regexp grubby --regexp sdubby --regexp libcurl-minimal |
sort --unique |
xargs --delimiter '\n' --no-run-if-empty mkosi-install
done

View File

@ -20,10 +20,5 @@ Environment=
# mkfs.ext4 enabled it by default, so we disable it explicitly.
SYSTEMD_REPART_MKFS_OPTIONS_EXT4="-O ^orphan_file"
GIT_URL=https://git.centos.org/rpms/systemd.git
GIT_BRANCH=c9s-sig-hyperscale
GIT_COMMIT=8cf2aed0181920611421384f7374720db269d6c7
Packages=
kernel-modules # For squashfs
rpmautospec-rpm-macros

View File

@ -8,12 +8,6 @@ Distribution=|ubuntu
PackageManagerTrees=mkosi-pinning.pref:/etc/apt/preferences.d/mkosi-pinning.pref
[Content]
Environment=
GIT_URL=https://salsa.debian.org/systemd-team/systemd.git
GIT_SUBDIR=debian
GIT_BRANCH=debian/master
GIT_COMMIT=abf24e775c67cf054f474526dd5d9d952a00228b
VolatilePackages=
libnss-myhostname
libnss-mymachines
@ -21,6 +15,8 @@ VolatilePackages=
libnss-systemd
libpam-systemd
libsystemd-dev
libsystemd-shared
libsystemd0
libudev-dev
systemd
systemd-container
@ -40,17 +36,12 @@ VolatilePackages=
udev
Packages=
^libasan[0-9]+$
^libtss2-esys-[0-9.]+-0$
^libtss2-mu-[0-9.]+-0$
^libubsan[0-9]+$
apt
bind9-dnsutils
cryptsetup-bin
dbus-broker
dbus-user-session
dmsetup
dpkg-dev
f2fs-tools
fdisk
git-core
@ -59,9 +50,6 @@ Packages=
iputils-ping
isc-dhcp-server
libcap-ng-utils
libclang-rt-dev
libtss2-rc0
libtss2-tcti-device0
locales
man-db
multipath-tools
@ -85,7 +73,6 @@ Packages=
xxd
InitrdPackages=
libclang-rt-dev
tpm2-tools
InitrdVolatilePackages=

View File

@ -1,29 +0,0 @@
#!/bin/bash
# SPDX-License-Identifier: LGPL-2.1-or-later
set -e
# By default Suggests are not installed (and often Recommends are disabled too), which means we will miss
# the dlopen optional dependencies, but the tests need them, so parse them from the package metadata and
# install them. This is not an issue when building locally, as the build and runtime images are the same,
# so they would get installed as build dependencies anyway.
if [ "$1" = "build" ] || ! ((NO_BUILD)); then
exit 0
fi
# Query the Recommends and Suggests of all systemd packages, by matching on the version
systemd_version="$(dpkg-query --showformat '${Version}' --show systemd)"
mapfile -t systemd_packages < <( dpkg --list | grep '^ii' | grep "$systemd_version" | awk '{print $2}' | tr '\n' ' ' )
extra_packages=()
# shellcheck disable=SC2068
for package in ${systemd_packages[@]}; do
# We are looking for dlopens, so filter for libraries
mapfile -t -O "${#extra_packages[@]}" extra_packages < <(dpkg-query --showformat '${Suggests}' --show "$package" | sed -e "s/, /\n/g" -e "s/|.*//" | grep "lib")
mapfile -t -O "${#extra_packages[@]}" extra_packages < <(dpkg-query --showformat '${Recommends}' --show "$package" | sed -e "s/, /\n/g" -e "s/|.*//" | grep "lib")
done
if [ "${#extra_packages[@]}" -eq 0 ]; then
exit 0
fi
apt install "${extra_packages[@]}"

View File

@ -2,17 +2,15 @@
# SPDX-License-Identifier: LGPL-2.1-or-later
set -e
if [ "$1" = "build" ] || ((NO_BUILD)); then
if [[ "$1" == "build" ]]; then
exit 0
fi
# shellcheck source=/dev/null
. "$BUILDROOT/usr/lib/os-release"
mapfile -t PACKAGES < <(jq --raw-output .VolatilePackages[] <"$MKOSI_CONFIG")
if [ ! -d "pkg/$ID/debian" ]; then
echo "deb rules not found at pkg/$ID/debian, run mkosi once with -ff to make sure the rules are cloned" >&2
exit 1
fi
cd "pkg/$ID"
DEB_BUILD_PROFILES="pkg.systemd.upstream" apt-get build-dep .
apt-cache depends "${PACKAGES[@]}" |
grep --invert-match --regexp "<" --regexp "|" --regexp systemd | # Remove e.g. <python3:any> and |dbus-broker like results
grep --extended-regexp "Depends|Suggests|Recommends" |
sed --quiet 's/.*: //p' | # Get every line with ": " in it and strip it at the same time.
sort --unique |
xargs --delimiter '\n' --no-run-if-empty mkosi-install

View File

@ -7,11 +7,6 @@ Distribution=fedora
Release=rawhide
[Content]
Environment=
GIT_URL=https://src.fedoraproject.org/rpms/systemd.git
GIT_BRANCH=rawhide
GIT_COMMIT=a3524fc837f5e7b68f86b3e0a9d470a94a04c4c8
Packages=
compsize
dnf5

View File

@ -12,12 +12,9 @@ Repositories=non-oss
PackageManagerTrees=macros.db_backend:/etc/rpm/macros.db_backend
[Content]
Environment=
GIT_URL=https://code.opensuse.org/package/systemd
GIT_BRANCH=master
GIT_COMMIT=6812406e52a474568744c267e7bade1496bb26a5
VolatilePackages=
libsystemd0
libudev1
systemd
systemd-boot
systemd-container
@ -43,23 +40,14 @@ Packages=
docbook-xsl-stylesheets
f2fs-tools
gawk
gcc-c++
git-core
glibc-locale-base
gnutls
grep
group(bin)
group(daemon)
group(games)
group(nobody)
group(root)
gzip
iputils
kernel-default
kmod
libasan8
libkmod2
libubsan1
multipath-tools
ncat
open-iscsi
@ -74,7 +62,6 @@ Packages=
python3-pexpect
python3-psutil
quota
rpm-build
rsync
sbsigntools
sed
@ -85,20 +72,13 @@ Packages=
tgt
timezone
tpm2.0-tools
user(bin)
user(daemon)
user(games)
user(nobody)
user(root)
veritysetup
vim
xz
zypper
InitrdPackages=
clang
kmod
libkmod2
tpm2.0-tools
InitrdVolatilePackages=

View File

@ -2,63 +2,22 @@
# SPDX-License-Identifier: LGPL-2.1-or-later
set -e
if [ "$1" = "build" ] || ((NO_BUILD)); then
if [[ "$1" == "build" ]]; then
exit 0
fi
# shellcheck source=/dev/null
. "$BUILDROOT/usr/lib/os-release"
ID="${ID%-*}"
DEPS=""
if [ ! -f "pkg/$ID/systemd.spec" ]; then
echo "spec not found at pkg/$ID/systemd.spec, run mkosi once with -ff to make sure the spec is cloned" >&2
exit 1
fi
while read -r PACKAGE; do
# zypper's output is not machine readable so we make do with sed instead.
DEPS="$DEPS\n$(
zypper info --requires --recommends --suggests "$PACKAGE" |
sed '/Requires/,$!d' | # Remove everything before Requires line
sed --quiet 's/^ //p' # All indented lines have dependencies
)"
done < <(jq --raw-output .VolatilePackages[] <"$MKOSI_CONFIG")
# TODO: Drop when the spec is fixed (either the patch is adapted or not applied when building for upstream).
sed --in-place '/0009-pid1-handle-console-specificities-weirdness-for-s390.patch/d' "pkg/$ID/systemd.spec"
for DEPS in --requires --buildrequires; do
mkosi-chroot \
rpmspec \
--with upstream \
--query \
"$DEPS" \
--define "_topdir /var/tmp" \
--define "_sourcedir pkg/$ID" \
"pkg/$ID/systemd.spec" |
grep --invert-match --regexp systemd --regexp /bin/sh --regexp "rpmlib(" --regexp udev |
sort --unique |
tee /tmp/buildrequires |
xargs --delimiter '\n' mkosi-install
done
until mkosi-chroot \
rpmbuild \
-bd \
--build-in-place \
--with upstream \
--define "_topdir /var/tmp" \
--define "_sourcedir pkg/$ID" \
--define "_build_name_fmt %%{NAME}-%%{VERSION}-%%{RELEASE}.%%{ARCH}.rpm" \
"pkg/$ID/systemd.spec"
do
EXIT_STATUS=$?
if [ $EXIT_STATUS -ne 11 ]; then
exit $EXIT_STATUS
fi
mkosi-chroot \
rpm \
--query \
--package \
--requires \
/var/tmp/SRPMS/systemd-*.buildreqs.nosrc.rpm |
grep --invert-match '^rpmlib(' |
sort --unique >/tmp/dynamic-buildrequires
sort /tmp/buildrequires /tmp/dynamic-buildrequires |
uniq --unique |
tee --append /tmp/buildrequires |
xargs --delimiter '\n' mkosi-install
done
echo -e "$DEPS" |
grep --invert-match --regexp systemd --regexp udev --regexp qemu |
sort --unique |
xargs --delimiter '\n' --no-run-if-empty mkosi-install

View File

@ -0,0 +1,9 @@
# SPDX-License-Identifier: LGPL-2.1-or-later
# Add a dependency on the build image unless NO_BUILD=1.
[Match]
Environment=!NO_BUILD=1
[Config]
Dependencies=build

View File

@ -1,9 +1,11 @@
# SPDX-License-Identifier: LGPL-2.1-or-later
# If we're only rerunning the build script, remove all subimage dependencies to speed up builds.
# If we're only rerunning the build script, remove all subimage dependencies except the build image to speed
# up builds.
[Match]
Format=none
[Config]
Dependencies=
Dependencies=build

View File

@ -2,6 +2,7 @@
[Match]
Environment=SANITIZERS
Environment=!SANITIZERS=
[Content]
# Set verify_asan_link_order=0 to prevent ASAN warnings when building the image and make sure the real ASAN
@ -17,3 +18,6 @@ KernelCommandLine=
systemd.setenv=UBSAN_OPTIONS=print_stacktrace=1:print_summary=1:halt_on_error=1
LSAN_OPTIONS=suppressions=/usr/lib/systemd/leak-sanitizer-suppressions
systemd.setenv=LSAN_OPTIONS=suppressions=/usr/lib/systemd/leak-sanitizer-suppressions
[Config]
Include=%D/mkosi.sanitizers

View File

@ -0,0 +1,11 @@
# SPDX-License-Identifier: LGPL-2.1-or-later
[Content]
Packages=
clang
erofs-utils
lld
llvm
[Output]
Format=none

View File

@ -2,14 +2,10 @@
# SPDX-License-Identifier: LGPL-2.1-or-later
set -e
if ((NO_BUILD)); then
exit 0
fi
# shellcheck source=/dev/null
. /usr/lib/os-release
if [ ! -f "pkg/$ID/PKGBUILD" ]; then
if [[ ! -f "pkg/$ID/PKGBUILD" ]]; then
echo "PKGBUILD not found at pkg/$ID/PKGBUILD, run mkosi once with -ff to make sure the PKGBUILD is cloned" >&2
exit 1
fi
@ -65,7 +61,7 @@ EOF
# Linting the PKGBUILD takes multiple seconds every build so avoid that by nuking all the linting functions.
rm /usr/share/makepkg/lint_pkgbuild/*
if [ -d .git/ ] && [ -z "$(git status --porcelain)" ]; then
if [[ -d .git/ ]] && [[ -z "$(git status --porcelain)" ]]; then
TS="$(git show --no-patch --format=%ct HEAD)"
else
TS="${SOURCE_DATE_EPOCH:-$(date +%s)}"

View File

@ -0,0 +1,16 @@
# SPDX-License-Identifier: LGPL-2.1-or-later
[Match]
Distribution=arch
[Content]
Environment=
GIT_URL=https://gitlab.archlinux.org/archlinux/packaging/packages/systemd.git
GIT_BRANCH=main
GIT_COMMIT=d74b24c7c6077740c35a876445febe6d26bf013c
Packages=
base
base-devel
diffutils
git

View File

@ -0,0 +1,21 @@
#!/bin/bash
# SPDX-License-Identifier: LGPL-2.1-or-later
set -e
if [[ "$1" == "build" ]]; then
exit 0
fi
# shellcheck source=/dev/null
. "$BUILDROOT/usr/lib/os-release"
if [[ ! -f "pkg/$ID/PKGBUILD" ]]; then
echo "PKGBUILD not found at pkg/$ID/PKGBUILD, run mkosi once with -ff to make sure the PKGBUILD is cloned" >&2
exit 1
fi
# shellcheck source=/dev/null
_systemd_UPSTREAM=1 . "pkg/$ID/PKGBUILD"
# shellcheck disable=SC2154
mkosi-install "${makedepends[@]}"

View File

@ -4,25 +4,21 @@ set -e
. mkosi.functions
if ((NO_BUILD)); then
exit 0
fi
# shellcheck source=/dev/null
. /usr/lib/os-release
if [ ! -f "pkg/$ID/systemd.spec" ]; then
if [[ ! -f "pkg/$ID/systemd.spec" ]]; then
echo "spec not found at pkg/$ID/systemd.spec, run mkosi once with -ff to make sure the spec is cloned" >&2
exit 1
fi
if [ -d .git/ ] && [ -z "$(git status --porcelain)" ]; then
if [[ -d .git/ ]] && [[ -z "$(git status --porcelain)" ]]; then
TS="$(git show --no-patch --format=%ct HEAD)"
else
TS="${SOURCE_DATE_EPOCH:-$(date +%s)}"
fi
if systemd-analyze compare-versions "$(rpm --version | cut -d ' ' -f3)" lt "4.19.91"; then
if [[ "$(rpm --eval "%{lua:print(rpm.vercmp('$(rpm --version | cut -d ' ' -f3)', '4.19.91'))}")" == "-1" ]]; then
# Fix the %install override so debuginfo packages are generated even when --build-in-place is used.
# See https://github.com/rpm-software-management/rpm/issues/3042.
tee --append /usr/lib/rpm/redhat/macros <<'EOF'

View File

@ -0,0 +1,14 @@
# SPDX-License-Identifier: LGPL-2.1-or-later
[Match]
Distribution=|centos
Distribution=|fedora
[Content]
Packages=
compiler-rt
git-core
libasan
libubsan
rpm-build
rpmautospec

View File

@ -0,0 +1,63 @@
#!/bin/bash
# SPDX-License-Identifier: LGPL-2.1-or-later
set -e
if [[ "$1" == "build" ]]; then
exit 0
fi
# shellcheck source=/dev/null
. "$BUILDROOT/usr/lib/os-release"
if [[ ! -f "pkg/$ID/systemd.spec" ]]; then
echo "spec not found at pkg/$ID/systemd.spec, run mkosi with -ff to make sure the spec is cloned" >&2
exit 1
fi
mkosi-chroot \
rpmspec \
--with upstream \
--query \
--buildrequires \
--define "_topdir /var/tmp" \
--define "_sourcedir pkg/$ID" \
"pkg/$ID/systemd.spec" |
grep --invert-match --regexp systemd --regexp /bin/sh --regexp "rpmlib(" --regexp udev --regexp grubby --regexp sdubby |
sort --unique |
tee /tmp/buildrequires |
xargs --delimiter '\n' mkosi-install
# rpmbuild -br tries to build a source package which means all source files have to exist which isn't the
# case when using --build-in-place so we get rid of the source file that doesn't exist to make it happy.
# TODO: Use -bd instead of -br and get rid of this once we don't need to build on CentOS Stream 9 anymore.
sed '/Source0/d' --in-place "pkg/$ID/systemd.spec"
until mkosi-chroot \
rpmbuild \
-br \
--build-in-place \
--with upstream \
--define "_topdir /var/tmp" \
--define "_sourcedir pkg/$ID" \
--define "_build_name_fmt %%{NAME}-%%{VERSION}-%%{RELEASE}.%%{ARCH}.rpm" \
"pkg/$ID/systemd.spec"
do
EXIT_STATUS=$?
if [[ $EXIT_STATUS -ne 11 ]]; then
exit $EXIT_STATUS
fi
mkosi-chroot \
rpm \
--query \
--package \
--requires \
/var/tmp/SRPMS/systemd-*.buildreqs.nosrc.rpm |
grep --invert-match '^rpmlib(' |
sort --unique >/tmp/dynamic-buildrequires
sort /tmp/buildrequires /tmp/dynamic-buildrequires |
uniq --unique |
tee --append /tmp/buildrequires |
xargs --delimiter '\n' mkosi-install
done

View File

@ -0,0 +1,14 @@
# SPDX-License-Identifier: LGPL-2.1-or-later
[Match]
Distribution=centos
[Content]
Packages=
rsync # TODO: Drop when CentOS Stream 9 CI is removed.
rpmautospec-rpm-macros
Environment=
GIT_URL=https://git.centos.org/rpms/systemd.git
GIT_BRANCH=c9s-sig-hyperscale
GIT_COMMIT=46480aaa9e0ea63a85b6ca676554ce2aae10ce36

View File

@ -2,14 +2,10 @@
# SPDX-License-Identifier: LGPL-2.1-or-later
set -e
if ((NO_BUILD)); then
exit 0
fi
# shellcheck source=/dev/null
. /usr/lib/os-release
if [ ! -d "pkg/$ID/debian" ]; then
if [[ ! -d "pkg/$ID/debian" ]]; then
echo "deb rules not found at pkg/$ID/debian, run mkosi once with -ff to make sure the rules are cloned" >&2
exit 1
fi
@ -25,7 +21,7 @@ rm -rf "$SRCDIR"/debian/patches/*
DEB_HOST_GNU_TYPE="$(dpkg-architecture --query DEB_HOST_GNU_TYPE)"
mount --mkdir --bind "$BUILDDIR" "$SRCDIR/obj-$DEB_HOST_GNU_TYPE"
if [ -d .git/ ] && [ -z "$(git status --porcelain)" ]; then
if [[ -d .git/ ]] && [[ -z "$(git status --porcelain)" ]]; then
TS="$(git show --no-patch --format=%ct HEAD)"
else
TS="${SOURCE_DATE_EPOCH:-$(date +%s)}"
@ -116,7 +112,7 @@ if ! build; then
# by meson install.
(cd debian/tmp/ && find . ! -type d ! -path "*dh-exec*" -printf '%P\n') >/tmp/installed-files
if [ -f debian/not-installed ]; then
if [[ -f debian/not-installed ]]; then
grep --invert-match "^#" debian/not-installed >>/tmp/installed-files
fi
@ -126,7 +122,7 @@ if ! build; then
# not in the packaged file.
comm -23 /tmp/installed-files /tmp/packaged-files > /tmp/unpackaged-files
# If there are no unpackaged files something else went wrong.
if [ ! -s /tmp/unpackaged-files ]; then
if [[ ! -s /tmp/unpackaged-files ]]; then
exit 1
fi

View File

@ -0,0 +1,18 @@
# SPDX-License-Identifier: LGPL-2.1-or-later
[Match]
Distribution=|debian
Distribution=|ubuntu
[Content]
Environment=
GIT_URL=https://salsa.debian.org/systemd-team/systemd.git
GIT_SUBDIR=debian
GIT_BRANCH=debian/master
GIT_COMMIT=abf24e775c67cf054f474526dd5d9d952a00228b
Packages=
apt
git-core
libclang-rt-dev
dpkg-dev

View File

@ -0,0 +1,18 @@
#!/bin/bash
# SPDX-License-Identifier: LGPL-2.1-or-later
set -e
if [[ "$1" == "build" ]]; then
exit 0
fi
# shellcheck source=/dev/null
. "$BUILDROOT/usr/lib/os-release"
if [[ ! -d "pkg/$ID/debian" ]]; then
echo "deb rules not found at pkg/$ID/debian, run mkosi once with -ff to make sure the rules are cloned" >&2
exit 1
fi
cd "pkg/$ID"
DEB_BUILD_PROFILES="pkg.systemd.upstream" apt-get build-dep .

View File

@ -0,0 +1,10 @@
# SPDX-License-Identifier: LGPL-2.1-or-later
[Match]
Distribution=fedora
[Content]
Environment=
GIT_URL=https://src.fedoraproject.org/rpms/systemd.git
GIT_BRANCH=rawhide
GIT_COMMIT=a3524fc837f5e7b68f86b3e0a9d470a94a04c4c8

View File

@ -4,20 +4,16 @@ set -e
. mkosi.functions
if ((NO_BUILD)); then
exit 0
fi
# shellcheck source=/dev/null
. /usr/lib/os-release
ID="${ID%-*}"
if [ ! -f "pkg/$ID/systemd.spec" ]; then
if [[ ! -f "pkg/$ID/systemd.spec" ]]; then
echo "spec not found at pkg/$ID/systemd.spec, run mkosi once with -ff to make sure the spec is cloned" >&2
exit 1
fi
if [ -d .git/ ] && [ -z "$(git status --porcelain)" ]; then
if [[ -d .git/ ]] && [[ -z "$(git status --porcelain)" ]]; then
TS="$(git show --no-patch --format=%ct HEAD)"
else
TS="${SOURCE_DATE_EPOCH:-$(date +%s)}"
@ -28,7 +24,7 @@ fi
# extension.
find "pkg/$ID" -name "files.*" -exec sed --in-place 's/\.gz$//' {} \;
if systemd-analyze compare-versions "$(rpm --version | cut -d ' ' -f3)" lt "4.20"; then
if [[ "$(rpm --eval "%{lua:print(rpm.vercmp('$(rpm --version | cut -d ' ' -f3)', '4.20'))}")" == "-1" ]]; then
# Fix the %install override so debuginfo packages are generated.
tee --append /usr/lib/rpm/suse/macros <<'EOF'
%install %{debug_package}\
@ -122,7 +118,7 @@ build() {
}
if ! build; then
if [ ! -s /tmp/unpackaged-files ]; then
if [[ ! -s /tmp/unpackaged-files ]]; then
exit 1
fi

View File

@ -0,0 +1,16 @@
# SPDX-License-Identifier: LGPL-2.1-or-later
[Match]
Distribution=opensuse
[Content]
Environment=
GIT_URL=https://code.opensuse.org/package/systemd
GIT_BRANCH=master
GIT_COMMIT=6812406e52a474568744c267e7bade1496bb26a5
Packages=
gcc-c++
git-core
patterns-base-minimal_base
rpm-build

View File

@ -0,0 +1,62 @@
#!/bin/bash
# SPDX-License-Identifier: LGPL-2.1-or-later
set -e
if [[ "$1" == "build" ]]; then
exit 0
fi
# shellcheck source=/dev/null
. "$BUILDROOT/usr/lib/os-release"
ID="${ID%-*}"
if [[ ! -f "pkg/$ID/systemd.spec" ]]; then
echo "spec not found at pkg/$ID/systemd.spec, run mkosi once with -ff to make sure the spec is cloned" >&2
exit 1
fi
# TODO: Drop when the spec is fixed (either the patch is adapted or not applied when building for upstream).
sed --in-place '/0009-pid1-handle-console-specificities-weirdness-for-s390.patch/d' "pkg/$ID/systemd.spec"
mkosi-chroot \
rpmspec \
--with upstream \
--query \
--buildrequires \
--define "_topdir /var/tmp" \
--define "_sourcedir pkg/$ID" \
"pkg/$ID/systemd.spec" |
grep --invert-match --regexp systemd --regexp /bin/sh --regexp "rpmlib(" --regexp udev |
sort --unique |
tee /tmp/buildrequires |
xargs --delimiter '\n' mkosi-install
until mkosi-chroot \
rpmbuild \
-bd \
--build-in-place \
--with upstream \
--define "_topdir /var/tmp" \
--define "_sourcedir pkg/$ID" \
--define "_build_name_fmt %%{NAME}-%%{VERSION}-%%{RELEASE}.%%{ARCH}.rpm" \
"pkg/$ID/systemd.spec"
do
EXIT_STATUS=$?
if [[ $EXIT_STATUS -ne 11 ]]; then
exit $EXIT_STATUS
fi
mkosi-chroot \
rpm \
--query \
--package \
--requires \
/var/tmp/SRPMS/systemd-*.buildreqs.nosrc.rpm |
grep --invert-match '^rpmlib(' |
sort --unique >/tmp/dynamic-buildrequires
sort /tmp/buildrequires /tmp/dynamic-buildrequires |
uniq --unique |
tee --append /tmp/buildrequires |
xargs --delimiter '\n' mkosi-install
done

View File

@ -14,6 +14,11 @@ if [[ -d "$PKG_SUBDIR/.git" ]]; then
exit 0
fi
if ! git -C "$PKG_SUBDIR" show-ref --quiet "origin/$GIT_BRANCH"; then
git -C "$PKG_SUBDIR" remote set-url origin "$GIT_URL"
git -C "$PKG_SUBDIR" fetch origin "$GIT_BRANCH"
fi
# If work is being done on the packaging rules in a separate branch, don't touch the checkout.
if ! git -C "$PKG_SUBDIR" merge-base --is-ancestor HEAD "origin/$GIT_BRANCH"; then
EXIT_STATUS=$?

View File

@ -12,3 +12,6 @@ MakeInitrd=yes
Packages=
bash
[Config]
Include=%D/mkosi.sanitizers

View File

@ -4,7 +4,7 @@
Distribution=arch
[Content]
Packages=
VolatilePackages=
systemd
RemoveFiles=

View File

@ -5,5 +5,5 @@ Distribution=|centos
Distribution=|fedora
[Content]
Packages=
VolatilePackages=
systemd-standalone-shutdown

View File

@ -4,5 +4,5 @@
Distribution=debian
[Content]
Packages=
VolatilePackages=
systemd-standalone-shutdown

View File

@ -5,4 +5,7 @@ Distribution=opensuse
[Content]
Packages=
patterns-base-minimal_base
VolatilePackages=
systemd

View File

@ -4,5 +4,5 @@
Distribution=ubuntu
[Content]
Packages=
VolatilePackages=
systemd

View File

@ -0,0 +1,9 @@
# SPDX-License-Identifier: LGPL-2.1-or-later
# Add a dependency on the build image unless NO_BUILD=1.
[Match]
Environment=!NO_BUILD=1
[Config]
Dependencies=build

View File

@ -14,3 +14,6 @@ Packages=
coreutils
grep
util-linux
[Config]
Include=%D/mkosi.sanitizers

View File

@ -9,6 +9,9 @@ Packages=
iproute
nmap
VolatilePackages=
systemd-libs
RemoveFiles=
# Arch Linux doesn't split their gcc-libs package so we manually remove
# unneeded stuff here to make sure it doesn't end up in the image.

View File

@ -10,3 +10,6 @@ Packages=
iproute
iproute-tc
nmap-ncat
VolatilePackages=
systemd-libs

View File

@ -10,3 +10,7 @@ Packages=
iproute2
mount
ncat
VolatilePackages=
libsystemd0
libudev1

View File

@ -9,3 +9,7 @@ Packages=
iproute2
ncat
patterns-base-minimal_base
VolatilePackages=
libsystemd0
libudev1

View File

@ -0,0 +1,9 @@
# SPDX-License-Identifier: LGPL-2.1-or-later
# Add a dependency on the build image unless NO_BUILD=1.
[Match]
Environment=!NO_BUILD=1
[Config]
Dependencies=build

View File

@ -1,7 +1,9 @@
# SPDX-License-Identifier: LGPL-2.1-or-later
[Content]
PostInstallationScripts=../mkosi.sanitizers.chroot
ExtraTrees=
../mkosi.leak-sanitizer-suppressions:/usr/lib/systemd/leak-sanitizer-suppressions
../mkosi.coredump-journal-storage.conf:/usr/lib/systemd/coredump.conf.d/10-coredump-journal-storage.conf
[Config]
Include=../mkosi.sanitizers

View File

@ -0,0 +1,5 @@
# SPDX-License-Identifier: LGPL-2.1-or-later
[Match]
Environment=SANITIZERS
Environment=!SANITIZERS=

View File

@ -0,0 +1,9 @@
# SPDX-License-Identifier: LGPL-2.1-or-later
[Match]
Distribution=arch
Environment=LLVM=1
[Content]
Packages=
compiler-rt

View File

@ -0,0 +1,11 @@
# SPDX-License-Identifier: LGPL-2.1-or-later
# TODO: Drop when https://bugzilla.suse.com/show_bug.cgi?id=1225784 is fixed.
[Match]
Distribution=|debian
Distribution=|ubuntu
Environment=LLVM=1
[Content]
Packages=
libclang-rt-dev

View File

@ -0,0 +1,10 @@
# SPDX-License-Identifier: LGPL-2.1-or-later
# TODO: Drop when https://bugzilla.suse.com/show_bug.cgi?id=1225784 is fixed.
[Match]
Distribution=opensuse
Environment=LLVM=1
[Content]
Packages=
clang

View File

@ -3,31 +3,35 @@
set -e
set -o nounset
if [[ -z "${SANITIZERS:-}" ]]; then
LIBSYSTEMD="$(mkosi-chroot ldconfig -p | grep libsystemd.so.0 | sed 's/[^/]*\//\//')"
if [[ ! -f "$BUILDROOT/$LIBSYSTEMD" ]]; then
exit 0
fi
# Sanitizers log to stderr by default. However, journald's stderr is connected to /dev/null, so we lose
# all the sanitizer logs. To rectify that, let's connect journald's stdout to kmsg so that the sanitizer
# failures end up in the journal.
mkdir -p /etc/systemd/system/systemd-journald.service.d
cat >/etc/systemd/system/systemd-journald.service.d/10-stdout-tty.conf <<EOF
if [[ -f "$BUILDROOT"/usr/lib/systemd/system/systemd-journald.service ]]; then
mkdir -p "$BUILDROOT"/etc/systemd/system/systemd-journald.service.d
cat >"$BUILDROOT"/etc/systemd/system/systemd-journald.service.d/10-stdout-tty.conf <<EOF
[Service]
StandardOutput=kmsg
EOF
fi
# ASAN and syscall filters aren't compatible with each other.
find /usr /etc -name '*.service' -type f -exec sed -i 's/^\(MemoryDeny\|SystemCall\)/# \1/' {} +
find "$BUILDROOT"/usr "$BUILDROOT"/etc -name '*.service' -type f -exec sed -i 's/^\(MemoryDeny\|SystemCall\)/# \1/' {} +
# 'systemd-hwdb update' takes > 50s when built with sanitizers so let's not run it by default.
systemctl mask systemd-hwdb-update.service
systemctl --root="$BUILDROOT" mask systemd-hwdb-update.service
ASAN_RT_PATH="$(grep libasan.so < <(ldd /usr/lib/systemd/systemd) | cut -d ' ' -f 3)"
ASAN_RT_PATH="$(grep libasan.so < <(mkosi-chroot ldd "$LIBSYSTEMD") | cut -d ' ' -f 3)"
if [[ -z "$ASAN_RT_PATH" ]]; then
ASAN_RT_PATH="$(grep libclang_rt.asan < <(ldd /usr/lib/systemd/systemd) | cut -d ' ' -f 3)"
ASAN_RT_PATH="$(grep libclang_rt.asan < <(mkosi-chroot ldd "$LIBSYSTEMD") | cut -d ' ' -f 3)"
# As clang's ASan DSO is usually in a non-standard path, let's check if the RUNPATH is set accordingly.
if ldd /usr/lib/systemd/systemd | grep -q "libclang_rt.asan.*not found"; then
if mkosi-chroot ldd "$LIBSYSTEMD" | grep -q "libclang_rt.asan.*not found"; then
echo >&2 "clang's ASan DSO libclang_rt.asan is not present in the runtime library path"
exit 1
fi
@ -94,7 +98,7 @@ wrap=(
)
for bin in "${wrap[@]}"; do
if ! command -v "$bin" >/dev/null; then
if ! mkosi-chroot command -v "$bin" >/dev/null; then
continue
fi
@ -104,11 +108,11 @@ for bin in "${wrap[@]}"; do
enable_lsan=0
fi
target="$(command -v "$bin")"
target="$(mkosi-chroot command -v "$bin")"
mv "$target" "$target.orig"
mv "$BUILDROOT/$target" "$BUILDROOT/$target.orig"
cat >"$target" <<EOF
cat >"$BUILDROOT/$target" <<EOF
#!/bin/bash
# Preload the ASan runtime DSO, otherwise ASAn will complain
export LD_PRELOAD="$ASAN_RT_PATH"
@ -118,10 +122,10 @@ export ASAN_OPTIONS=detect_leaks=$enable_lsan
# Set argv[0] to the original binary name without the ".orig" suffix
exec -a "\$0" -- "${target}.orig" "\$@"
EOF
chmod +x "$target"
chmod +x "$BUILDROOT/$target"
done
cat >/usr/lib/systemd/systemd-asan-env <<EOF
cat >"$BUILDROOT"/usr/lib/systemd/systemd-asan-env <<EOF
LD_PRELOAD=$ASAN_RT_PATH
LSAN_OPTIONS=detect_leaks=0
EOF

View File

@ -33,7 +33,8 @@ def read_config(distro: str):
text = subprocess.check_output(cmd, text=True)
data = json.loads(text)
return data['Images'][-1]
images = {image["Image"]: image for image in data["Images"]}
return images["build"]
def commit_file(distro: str, file: Path, commit: str, changes: str):
message = '\n'.join((
@ -69,7 +70,7 @@ def update_distro(args, distro: str):
print(f"+ {shlex.join(cmd)}")
changes = subprocess.check_output(cmd, text=True).strip()
conf_dir = Path('mkosi.conf.d')
conf_dir = Path('mkosi.images/build/mkosi.conf.d')
files = conf_dir.glob('*/*.conf')
for file in files:
s = file.read_text()