]>
Commit | Line | Data |
---|---|---|
7629744a | 1 | #!/bin/sh |
8f5bcd61 | 2 | # SPDX-License-Identifier: LGPL-2.1-or-later |
1394a3ec | 3 | set -e |
1b0ff615 | 4 | |
1b0ff615 LP |
5 | # This is a build script for OS image generation using mkosi (https://github.com/systemd/mkosi). |
6 | # Simply invoke "mkosi" in the project directory to build an OS image. | |
7 | ||
69d638e6 DDM |
8 | 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 |
9 | UBSAN_OPTIONS=print_stacktrace=1:print_summary=1:halt_on_error=1 | |
10 | ||
7211773a LP |
11 | # On Fedora "ld" is (unfortunately — if you ask me) managed via |
12 | # "alternatives". Since we'd like to support building images in environments | |
13 | # with only /usr/ around (e.g. mkosi's UsrOnly=1 option), we have the problem | |
14 | # that /usr/bin/ld is a symlink that points to a non-existing file in | |
15 | # /etc/alternative/ in this mode. Let's work around this for now by manually | |
16 | # redirect "ld" to "ld.bfd", i.e. circumventing the /usr/bin/ld symlink. | |
068d1338 | 17 | if [ ! -x /usr/bin/ld ] && [ -x /usr/bin/ld.bfd ]; then |
7211773a LP |
18 | mkdir -p "$HOME"/bin |
19 | ln -s /usr/bin/ld.bfd "$HOME"/bin/ld | |
20 | PATH="$HOME/bin:$PATH" | |
21 | fi | |
22 | ||
70e760e3 LP |
23 | # If mkosi.builddir/ exists mkosi will set $BUILDDIR to it, let's then use it |
24 | # as out-of-tree build dir. Otherwise, let's make up our own builddir. | |
25 | [ -z "$BUILDDIR" ] && BUILDDIR=build | |
26 | ||
2ea09665 FB |
27 | # Meson uses Python 3 and requires a locale with an UTF-8 character map. |
28 | # Not running under UTF-8 makes the `ninja test` step break with a CodecError. | |
29 | # So let's ensure we're running under UTF-8. | |
30 | # | |
31 | # If our current locale already is UTF-8, then we don't need to do anything: | |
068d1338 | 32 | if [ "$(locale charmap 2>/dev/null)" != "UTF-8" ] ; then |
2ea09665 FB |
33 | # Try using C.UTF-8 locale, if available. This locale is not shipped |
34 | # by upstream glibc, so it's not available in all distros. | |
35 | # (In particular, it's not available in Arch Linux.) | |
5e577e17 DDM |
36 | if locale -a | grep -q -E "C.UTF-8|C.utf8"; then |
37 | export LC_CTYPE=C.UTF-8 | |
38 | # Finally, try something like en_US.UTF-8, which should be | |
39 | # available in Arch Linux, but is not present in Debian's | |
40 | # minimal image in our mkosi config. | |
41 | elif locale -a | grep -q en_US.utf8; then | |
2ea09665 | 42 | export LC_CTYPE=en_US.UTF-8 |
5e577e17 DDM |
43 | else |
44 | # If nothing works, fail early. | |
45 | echo "*** Could not find a valid locale that supports UTF-8. ***" >&2 | |
46 | exit 1 | |
2ea09665 FB |
47 | fi |
48 | fi | |
9400405b | 49 | |
c81a2569 | 50 | if [ ! -f "$BUILDDIR"/build.ninja ] ; then |
068d1338 | 51 | sysvinit_path=$(realpath /etc/init.d) |
8da0592c | 52 | |
068d1338 | 53 | init_path=$(realpath /sbin/init 2>/dev/null) |
bac567a5 | 54 | if [ -z "$init_path" ] ; then |
2401c9ac | 55 | rootprefix="" |
bac567a5 | 56 | else |
2401c9ac DDM |
57 | rootprefix=${init_path%/lib/systemd/systemd} |
58 | rootprefix=/${rootprefix#/} | |
bac567a5 MK |
59 | fi |
60 | ||
db52af5a DDM |
61 | meson "$BUILDDIR" \ |
62 | -D "sysvinit-path=$sysvinit_path" \ | |
63 | -D "rootprefix=$rootprefix" \ | |
64 | -D man=false \ | |
ef1bd234 | 65 | -D translations=false \ |
c0daae3a | 66 | -D version-tag="${VERSION_TAG}" \ |
69d638e6 DDM |
67 | -D mode=developer \ |
68 | -D b_sanitize="${SANITIZERS:-none}" | |
c82ce4f2 LP |
69 | fi |
70 | ||
c3e2dc71 | 71 | cd "$BUILDDIR" |
44bc7f4f | 72 | ninja "$@" |
ff549982 MK |
73 | if [ "$WITH_TESTS" = 1 ] ; then |
74 | for id in 1 2 3; do | |
068d1338 | 75 | getent group $id >/dev/null || groupadd -g $id testgroup$id |
ff549982 MK |
76 | done |
77 | ||
69d638e6 DDM |
78 | if [ -n "$SANITIZERS" ]; then |
79 | export ASAN_OPTIONS="$ASAN_OPTIONS" | |
80 | export UBSAN_OPTIONS="$UBSAN_OPTIONS" | |
81 | TIMEOUT_MULTIPLIER=3 | |
82 | else | |
83 | TIMEOUT_MULTIPLIER=1 | |
84 | fi | |
85 | ||
86 | meson test --timeout-multiplier=$TIMEOUT_MULTIPLIER | |
ff549982 | 87 | fi |
c3e2dc71 | 88 | cd "$SRCDIR" |
fe2b7631 DDM |
89 | |
90 | # Ubuntu Focal is stuck with meson 0.53.0. | |
91 | if [ "$(meson -v | cut -d . -f 2)" -gt 53 ] ; then | |
2234c6a0 | 92 | meson install -C "$BUILDDIR" --quiet --no-rebuild --only-changed |
fe2b7631 | 93 | else |
2234c6a0 | 94 | meson install -C "$BUILDDIR" --no-rebuild --only-changed |
fe2b7631 | 95 | fi |
6344a7eb | 96 | |
70e760e3 | 97 | mkdir -p "$DESTDIR"/etc |
6344a7eb | 98 | |
068d1338 | 99 | cat >"$DESTDIR"/etc/issue <<EOF |
6344a7eb LP |
100 | \S (built from systemd tree) |
101 | Kernel \r on an \m (\l) | |
102 | ||
103 | EOF | |
d10ba83a | 104 | |
f533cda5 | 105 | if [ -n "$IMAGE_ID" ] ; then |
2401c9ac DDM |
106 | mkdir -p "$DESTDIR"/usr/lib |
107 | sed -n \ | |
108 | -e '/^IMAGE_ID=/!p' \ | |
109 | -e "\$aIMAGE_ID=$IMAGE_ID" <"/usr/lib/os-release" >"${DESTDIR}/usr/lib/os-release" | |
f533cda5 | 110 | |
2401c9ac | 111 | OSRELEASEFILE="$DESTDIR"/usr/lib/os-release |
f533cda5 | 112 | else |
2401c9ac | 113 | OSRELEASEFILE=/usr/lib/os-release |
f533cda5 LP |
114 | fi |
115 | ||
116 | ||
117 | if [ -n "$IMAGE_VERSION" ] ; then | |
2401c9ac DDM |
118 | mkdir -p "$DESTDIR"/usr/lib |
119 | sed -n \ | |
120 | -e '/^IMAGE_VERSION=/!p' \ | |
121 | -e "\$aIMAGE_VERSION=$IMAGE_VERSION" <$OSRELEASEFILE >"/tmp/os-release.tmp" | |
f533cda5 | 122 | |
2401c9ac DDM |
123 | cat /tmp/os-release.tmp > "$DESTDIR"/usr/lib/os-release |
124 | rm /tmp/os-release.tmp | |
f533cda5 | 125 | fi |
24acd406 FS |
126 | |
127 | # If $CI_BUILD is set, copy over the CI service which executes a service check | |
128 | # after boot and then shuts down the machine | |
129 | if [ -n "$CI_BUILD" ]; then | |
2401c9ac DDM |
130 | mkdir -p "$DESTDIR/usr/lib/systemd/system" |
131 | cp -v "$SRCDIR/test/mkosi-check-and-shutdown.service" "$DESTDIR/usr/lib/systemd/system/mkosi-check-and-shutdown.service" | |
132 | cp -v "$SRCDIR/test/mkosi-check-and-shutdown.sh" "$DESTDIR/usr/lib/systemd/mkosi-check-and-shutdown.sh" | |
133 | chmod +x "$DESTDIR/usr/lib/systemd/mkosi-check-and-shutdown.sh" | |
24acd406 | 134 | fi |
69d638e6 DDM |
135 | |
136 | if [ -n "$SANITIZERS" ]; then | |
137 | LD_PRELOAD=$(ldd $BUILDDIR/systemd | grep libasan.so | awk '{print $3}') | |
138 | ||
139 | mkdir -p "$DESTDIR/etc/systemd/system.conf.d" | |
140 | ||
141 | cat > "$DESTDIR/etc/systemd/system.conf.d/10-asan.conf" <<EOF | |
142 | [Manager] | |
143 | ManagerEnvironment=ASAN_OPTIONS=$ASAN_OPTIONS\\ | |
144 | UBSAN_OPTIONS=$UBSAN_OPTIONS\\ | |
145 | LD_PRELOAD=$LD_PRELOAD | |
146 | DefaultEnvironment=ASAN_OPTIONS=$ASAN_OPTIONS\\ | |
147 | UBSAN_OPTIONS=$UBSAN_OPTIONS\\ | |
148 | LD_PRELOAD=$LD_PRELOAD | |
149 | EOF | |
150 | ||
151 | # ASAN logs to stderr by default. However, journald's stderr is connected to /dev/null, so we lose | |
152 | # all the ASAN logs. To rectify that, let's connect journald's stdout to the console so that any | |
153 | # sanitizer failures appear directly on the user's console. | |
154 | mkdir -p "$DESTDIR/etc/systemd/system/systemd-journald.service.d" | |
155 | ||
156 | cat > "$DESTDIR/etc/systemd/system/systemd-journald.service.d/10-stdout-tty.conf" <<EOF | |
157 | [Service] | |
158 | StandardOutput=tty | |
159 | EOF | |
160 | ||
161 | # Both systemd and util-linux's login call vhangup() on /dev/console which disconnects all users. | |
162 | # This means systemd-journald can't log to /dev/console even if we configure `StandardOutput=tty`. As | |
163 | # a workaround, we modify console-getty.service to disable systemd's vhangup() and disallow login | |
164 | # from calling vhangup() so that journald's ASAN logs correctly end up in the console. | |
165 | ||
166 | mkdir -p "$DESTDIR/etc/systemd/system/console-getty.service.d" | |
167 | ||
168 | cat > "$DESTDIR/etc/systemd/system/console-getty.service.d/10-no-vhangup.conf" <<EOF | |
169 | [Service] | |
170 | TTYVHangup=no | |
171 | CapabilityBoundingSet=~CAP_SYS_TTY_CONFIG | |
172 | EOF | |
173 | fi |