1
0
mirror of https://github.com/systemd/systemd.git synced 2024-10-30 14:55:37 +03:00
systemd/mkosi.build
Daan De Meyer 37d35150cb mkosi: Ensure we build all features/components in mkosi
Explicitly enable all features/components in the mkosi build to
ensure they all get built and we get an error if they can't be built.

We also rework the packages sections of all mkosi configs to reduce
duplication and cover all the dependencies necessary to build/use all
systemd features.

Note that for the final image, since systemd is installed by default
in base images, we rely on that to install the base library dependencies
and we only list extra optional dependencies and tools that aren't already
installed by default into the base image.

We also drop the centos stream 8 mkosi build as dependencies on that
distro are too out-of-date to be able to build all systemd features.
Since centos stream 9 has been out for a while, let's focus on that
and leave it to downstream to keep systemd building on centos stream 8.

Finally, there's a few additions to the mkosi scripts to make sure
services don't start by default on boot.
2022-08-23 15:19:26 +02:00

262 lines
9.7 KiB
Bash
Executable File

#!/bin/sh
# SPDX-License-Identifier: LGPL-2.1-or-later
set -e
# This is a build script for OS image generation using mkosi (https://github.com/systemd/mkosi).
# Simply invoke "mkosi" in the project directory to build an OS image.
ASAN_OPTIONS=strict_string_checks=1:detect_stack_use_after_return=1:check_initialization_order=1:strict_init_order=1:disable_coredump=0:use_madv_dontdump=1
UBSAN_OPTIONS=print_stacktrace=1:print_summary=1:halt_on_error=1
# On Fedora "ld" is (unfortunately — if you ask me) managed via
# "alternatives". Since we'd like to support building images in environments
# with only /usr/ around (e.g. mkosi's UsrOnly=1 option), we have the problem
# that /usr/bin/ld is a symlink that points to a non-existing file in
# /etc/alternative/ in this mode. Let's work around this for now by manually
# redirect "ld" to "ld.bfd", i.e. circumventing the /usr/bin/ld symlink.
if [ ! -x /usr/bin/ld ] && [ -x /usr/bin/ld.bfd ]; then
mkdir -p "$HOME"/bin
ln -s /usr/bin/ld.bfd "$HOME"/bin/ld
PATH="$HOME/bin:$PATH"
fi
# If mkosi.builddir/ exists mkosi will set $BUILDDIR to it, let's then use it
# as out-of-tree build dir. Otherwise, let's make up our own builddir.
[ -z "$BUILDDIR" ] && BUILDDIR=build
# Meson uses Python 3 and requires a locale with an UTF-8 character map.
# Not running under UTF-8 makes the `ninja test` step break with a CodecError.
# So let's ensure we're running under UTF-8.
#
# If our current locale already is UTF-8, then we don't need to do anything:
if [ "$(locale charmap 2>/dev/null)" != "UTF-8" ] ; then
# Try using C.UTF-8 locale, if available. This locale is not shipped
# by upstream glibc, so it's not available in all distros.
# (In particular, it's not available in Arch Linux.)
if locale -a | grep -q -E "C.UTF-8|C.utf8"; then
export LC_CTYPE=C.UTF-8
# Finally, try something like en_US.UTF-8, which should be
# available in Arch Linux, but is not present in Debian's
# minimal image in our mkosi config.
elif locale -a | grep -q en_US.utf8; then
export LC_CTYPE=en_US.UTF-8
else
# If nothing works, fail early.
echo "*** Could not find a valid locale that supports UTF-8. ***" >&2
exit 1
fi
fi
# The bpftool script shipped by Ubuntu tries to find the actual program to run via querying `uname -r` and
# using the current kernel version. This obviously doesn't work in containers. As a workaround, we override
# the ubuntu script with a symlink to the first bpftool program we can find.
for bpftool in /usr/lib/linux-tools/*/bpftool; do
[ -x "$bpftool" ] || continue
ln -sf "$bpftool" /usr/sbin/bpftool
break
done
if [ ! -f "$BUILDDIR"/build.ninja ] ; then
sysvinit_path=$(realpath /etc/init.d)
init_path=$(realpath /sbin/init 2>/dev/null)
if [ -z "$init_path" ] ; then
rootprefix=""
else
rootprefix=${init_path%/lib/systemd/systemd}
rootprefix=/${rootprefix#/}
fi
meson "$BUILDDIR" \
-D "sysvinit-path=$sysvinit_path" \
-D "rootprefix=$rootprefix" \
-D man=false \
-D translations=false \
-D version-tag="${VERSION_TAG}" \
-D mode=developer \
-D b_sanitize="${SANITIZERS:-none}" \
-D install-tests=true \
-D tests=unsafe \
-D slow-tests=true \
-D utmp=true \
-D hibernate=true \
-D ldconfig=true \
-D resolve=true \
-D efi=true \
-D tpm=true \
-D environment-d=true \
-D binfmt=true \
-D repart=true \
-D sysupdate=true \
-D coredump=true \
-D pstore=true \
-D oomd=true \
-D logind=true \
-D hostnamed=true \
-D localed=true \
-D machined=true \
-D portabled=true \
-D sysext=true \
-D userdb=true \
-D homed=true \
-D networkd=true \
-D timedated=true \
-D timesyncd=true \
-D remote=true \
-D nss-myhostname=true \
-D nss-mymachines=true \
-D nss-resolve=true \
-D nss-systemd=true \
-D firstboot=true \
-D randomseed=true \
-D backlight=true \
-D vconsole=true \
-D quotacheck=true \
-D sysusers=true \
-D tmpfiles=true \
-D importd=true \
-D hwdb=true \
-D rfkill=true \
-D xdg-autostart=true \
-D translations=true \
-D polkit=true \
-D acl=true \
-D audit=true \
-D blkid=true \
-D fdisk=true \
-D kmod=true \
-D pam=true \
-D pwquality=true \
-D microhttpd=true \
-D libcryptsetup=true \
-D libcurl=true \
-D idn=true \
-D libidn2=true \
-D qrencode=true \
-D gcrypt=true \
-D gnutls=true \
-D openssl=true \
-D cryptolib=openssl \
-D p11kit=true \
-D libfido2=true \
-D tpm2=true \
-D elfutils=true \
-D zstd=true \
-D xkbcommon=true \
-D pcre2=true \
-D glib=true \
-D dbus=true \
-D gnu-efi=true \
-D kernel-install=true \
-D analyze=true \
-D bpf-framework=true
fi
cd "$BUILDDIR"
ninja "$@"
if [ "$WITH_TESTS" = 1 ] ; then
for id in 1 2 3; do
getent group $id >/dev/null || groupadd -g $id testgroup$id
done
if [ -n "$SANITIZERS" ]; then
export ASAN_OPTIONS="$ASAN_OPTIONS"
export UBSAN_OPTIONS="$UBSAN_OPTIONS"
TIMEOUT_MULTIPLIER=3
else
TIMEOUT_MULTIPLIER=1
fi
meson test --timeout-multiplier=$TIMEOUT_MULTIPLIER
fi
cd "$SRCDIR"
# Ubuntu Focal is stuck with meson 0.53.0.
if [ "$(meson -v | cut -d . -f 2)" -gt 53 ] ; then
meson install -C "$BUILDDIR" --quiet --no-rebuild --only-changed
else
meson install -C "$BUILDDIR" --no-rebuild --only-changed
fi
mkdir -p "$DESTDIR"/etc
cat >"$DESTDIR"/etc/issue <<EOF
\S (built from systemd tree)
Kernel \r on an \m (\l)
EOF
if [ -n "$IMAGE_ID" ] ; then
mkdir -p "$DESTDIR"/usr/lib
sed -n \
-e '/^IMAGE_ID=/!p' \
-e "\$aIMAGE_ID=$IMAGE_ID" <"/usr/lib/os-release" >"${DESTDIR}/usr/lib/os-release"
OSRELEASEFILE="$DESTDIR"/usr/lib/os-release
else
OSRELEASEFILE=/usr/lib/os-release
fi
if [ -n "$IMAGE_VERSION" ] ; then
mkdir -p "$DESTDIR"/usr/lib
sed -n \
-e '/^IMAGE_VERSION=/!p' \
-e "\$aIMAGE_VERSION=$IMAGE_VERSION" <$OSRELEASEFILE >"/tmp/os-release.tmp"
cat /tmp/os-release.tmp > "$DESTDIR"/usr/lib/os-release
rm /tmp/os-release.tmp
fi
# If $CI_BUILD is set, copy over the CI service which executes a service check
# after boot and then shuts down the machine
if [ -n "$CI_BUILD" ]; then
mkdir -p "$DESTDIR/usr/lib/systemd/system"
cp -v "$SRCDIR/test/mkosi-check-and-shutdown.service" "$DESTDIR/usr/lib/systemd/system/mkosi-check-and-shutdown.service"
cp -v "$SRCDIR/test/mkosi-check-and-shutdown.sh" "$DESTDIR/usr/lib/systemd/mkosi-check-and-shutdown.sh"
chmod +x "$DESTDIR/usr/lib/systemd/mkosi-check-and-shutdown.sh"
fi
if [ -n "$SANITIZERS" ]; then
LD_PRELOAD=$(ldd $BUILDDIR/systemd | grep libasan.so | awk '{print $3}')
mkdir -p "$DESTDIR/etc/systemd/system.conf.d"
cat > "$DESTDIR/etc/systemd/system.conf.d/10-asan.conf" <<EOF
[Manager]
ManagerEnvironment=ASAN_OPTIONS=$ASAN_OPTIONS\\
UBSAN_OPTIONS=$UBSAN_OPTIONS\\
LD_PRELOAD=$LD_PRELOAD
DefaultEnvironment=ASAN_OPTIONS=$ASAN_OPTIONS\\
UBSAN_OPTIONS=$UBSAN_OPTIONS\\
LD_PRELOAD=$LD_PRELOAD
EOF
# ASAN logs to stderr by default. However, journald's stderr is connected to /dev/null, so we lose
# all the ASAN logs. To rectify that, let's connect journald's stdout to the console so that any
# sanitizer failures appear directly on the user's console.
mkdir -p "$DESTDIR/etc/systemd/system/systemd-journald.service.d"
cat > "$DESTDIR/etc/systemd/system/systemd-journald.service.d/10-stdout-tty.conf" <<EOF
[Service]
StandardOutput=tty
EOF
# Both systemd and util-linux's login call vhangup() on /dev/console which disconnects all users.
# This means systemd-journald can't log to /dev/console even if we configure `StandardOutput=tty`. As
# a workaround, we modify console-getty.service to disable systemd's vhangup() and disallow login
# from calling vhangup() so that journald's ASAN logs correctly end up in the console.
mkdir -p "$DESTDIR/etc/systemd/system/console-getty.service.d"
cat > "$DESTDIR/etc/systemd/system/console-getty.service.d/10-no-vhangup.conf" <<EOF
[Service]
TTYVHangup=no
CapabilityBoundingSet=~CAP_SYS_TTY_CONFIG
EOF
fi
# Make sure services aren't enabled by default on Debian/Ubuntu.
mkdir -p "$DESTDIR/etc/systemd/system-preset"
echo "disable *" > "$DESTDIR/etc/systemd/system-preset/99-mkosi.preset"