]>
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. | |
84a4af2c DDM |
25 | [ -z "$BUILDDIR" ] && BUILDDIR="$PWD"/build |
26 | ||
27 | # Let's make sure we're using stuff from the build directory first if available there. | |
28 | PATH="$BUILDDIR:$PATH" | |
29 | export PATH | |
70e760e3 | 30 | |
2ea09665 FB |
31 | # Meson uses Python 3 and requires a locale with an UTF-8 character map. |
32 | # Not running under UTF-8 makes the `ninja test` step break with a CodecError. | |
33 | # So let's ensure we're running under UTF-8. | |
34 | # | |
35 | # If our current locale already is UTF-8, then we don't need to do anything: | |
068d1338 | 36 | if [ "$(locale charmap 2>/dev/null)" != "UTF-8" ] ; then |
2ea09665 FB |
37 | # Try using C.UTF-8 locale, if available. This locale is not shipped |
38 | # by upstream glibc, so it's not available in all distros. | |
39 | # (In particular, it's not available in Arch Linux.) | |
5e577e17 DDM |
40 | if locale -a | grep -q -E "C.UTF-8|C.utf8"; then |
41 | export LC_CTYPE=C.UTF-8 | |
42 | # Finally, try something like en_US.UTF-8, which should be | |
43 | # available in Arch Linux, but is not present in Debian's | |
44 | # minimal image in our mkosi config. | |
45 | elif locale -a | grep -q en_US.utf8; then | |
2ea09665 | 46 | export LC_CTYPE=en_US.UTF-8 |
5e577e17 DDM |
47 | else |
48 | # If nothing works, fail early. | |
49 | echo "*** Could not find a valid locale that supports UTF-8. ***" >&2 | |
50 | exit 1 | |
2ea09665 FB |
51 | fi |
52 | fi | |
9400405b | 53 | |
37d35150 DDM |
54 | # The bpftool script shipped by Ubuntu tries to find the actual program to run via querying `uname -r` and |
55 | # using the current kernel version. This obviously doesn't work in containers. As a workaround, we override | |
56 | # the ubuntu script with a symlink to the first bpftool program we can find. | |
57 | for bpftool in /usr/lib/linux-tools/*/bpftool; do | |
58 | [ -x "$bpftool" ] || continue | |
84a4af2c | 59 | ln -sf "$bpftool" "$BUILDDIR"/bpftool |
37d35150 DDM |
60 | break |
61 | done | |
62 | ||
6afeac1d DDM |
63 | # CentOS Stream 8 includes bpftool 4.18.0 which is lower than what we need. However, they've backported the |
64 | # specific feature we need ("gen skeleton") to this version, so we replace bpftool with a script that reports | |
65 | # version 5.6.0 to satisfy meson which makes bpf work on CentOS Stream 8 as well. | |
66 | if [ "$(grep '^ID=' /etc/os-release)" = "ID=\"centos\"" ] && [ "$(grep '^VERSION=' /etc/os-release)" = "VERSION=\"8\"" ]; then | |
84a4af2c | 67 | cat >"$BUILDDIR"/bpftool <<EOF |
6afeac1d DDM |
68 | #!/bin/sh |
69 | if [ "\$1" = --version ]; then | |
70 | echo 5.6.0 | |
71 | else | |
84a4af2c | 72 | exec /usr/sbin/bpftool \$@ |
6afeac1d DDM |
73 | fi |
74 | EOF | |
84a4af2c | 75 | chmod +x "$BUILDDIR"/bpftool |
6afeac1d DDM |
76 | fi |
77 | ||
c81a2569 | 78 | if [ ! -f "$BUILDDIR"/build.ninja ] ; then |
068d1338 | 79 | sysvinit_path=$(realpath /etc/init.d) |
8da0592c | 80 | |
068d1338 | 81 | init_path=$(realpath /sbin/init 2>/dev/null) |
bac567a5 | 82 | if [ -z "$init_path" ] ; then |
2401c9ac | 83 | rootprefix="" |
bac567a5 | 84 | else |
2401c9ac DDM |
85 | rootprefix=${init_path%/lib/systemd/systemd} |
86 | rootprefix=/${rootprefix#/} | |
bac567a5 MK |
87 | fi |
88 | ||
8c21a0c9 | 89 | meson setup "$BUILDDIR" \ |
db52af5a DDM |
90 | -D "sysvinit-path=$sysvinit_path" \ |
91 | -D "rootprefix=$rootprefix" \ | |
92 | -D man=false \ | |
ef1bd234 | 93 | -D translations=false \ |
c0daae3a | 94 | -D version-tag="${VERSION_TAG}" \ |
69d638e6 | 95 | -D mode=developer \ |
819a2502 | 96 | -D b_sanitize="${SANITIZERS:-none}" \ |
37d35150 DDM |
97 | -D install-tests=true \ |
98 | -D tests=unsafe \ | |
99 | -D slow-tests=true \ | |
100 | -D utmp=true \ | |
101 | -D hibernate=true \ | |
102 | -D ldconfig=true \ | |
103 | -D resolve=true \ | |
104 | -D efi=true \ | |
105 | -D tpm=true \ | |
106 | -D environment-d=true \ | |
107 | -D binfmt=true \ | |
108 | -D repart=true \ | |
109 | -D sysupdate=true \ | |
110 | -D coredump=true \ | |
111 | -D pstore=true \ | |
112 | -D oomd=true \ | |
113 | -D logind=true \ | |
114 | -D hostnamed=true \ | |
115 | -D localed=true \ | |
116 | -D machined=true \ | |
117 | -D portabled=true \ | |
118 | -D sysext=true \ | |
119 | -D userdb=true \ | |
120 | -D homed=true \ | |
121 | -D networkd=true \ | |
122 | -D timedated=true \ | |
123 | -D timesyncd=true \ | |
124 | -D remote=true \ | |
125 | -D nss-myhostname=true \ | |
126 | -D nss-mymachines=true \ | |
127 | -D nss-resolve=true \ | |
128 | -D nss-systemd=true \ | |
129 | -D firstboot=true \ | |
130 | -D randomseed=true \ | |
131 | -D backlight=true \ | |
132 | -D vconsole=true \ | |
133 | -D quotacheck=true \ | |
134 | -D sysusers=true \ | |
135 | -D tmpfiles=true \ | |
136 | -D importd=true \ | |
137 | -D hwdb=true \ | |
138 | -D rfkill=true \ | |
139 | -D xdg-autostart=true \ | |
140 | -D translations=true \ | |
141 | -D polkit=true \ | |
142 | -D acl=true \ | |
143 | -D audit=true \ | |
144 | -D blkid=true \ | |
145 | -D fdisk=true \ | |
146 | -D kmod=true \ | |
147 | -D pam=true \ | |
148 | -D pwquality=true \ | |
149 | -D microhttpd=true \ | |
150 | -D libcryptsetup=true \ | |
151 | -D libcurl=true \ | |
152 | -D idn=true \ | |
153 | -D libidn2=true \ | |
154 | -D qrencode=true \ | |
155 | -D gcrypt=true \ | |
156 | -D gnutls=true \ | |
157 | -D openssl=true \ | |
158 | -D cryptolib=openssl \ | |
159 | -D p11kit=true \ | |
160 | -D libfido2=true \ | |
161 | -D tpm2=true \ | |
162 | -D elfutils=true \ | |
163 | -D zstd=true \ | |
164 | -D xkbcommon=true \ | |
165 | -D pcre2=true \ | |
166 | -D glib=true \ | |
167 | -D dbus=true \ | |
168 | -D gnu-efi=true \ | |
169 | -D kernel-install=true \ | |
170 | -D analyze=true \ | |
c8943ce8 DDM |
171 | -D bpf-framework=true \ |
172 | -D ukify=true | |
c82ce4f2 LP |
173 | fi |
174 | ||
c3e2dc71 | 175 | cd "$BUILDDIR" |
44bc7f4f | 176 | ninja "$@" |
ff549982 MK |
177 | if [ "$WITH_TESTS" = 1 ] ; then |
178 | for id in 1 2 3; do | |
80c2f3e4 | 179 | getent group $id >/dev/null || echo "g testgroup$id $id -" | ./systemd-sysusers - |
ff549982 MK |
180 | done |
181 | ||
69d638e6 DDM |
182 | if [ -n "$SANITIZERS" ]; then |
183 | export ASAN_OPTIONS="$ASAN_OPTIONS" | |
184 | export UBSAN_OPTIONS="$UBSAN_OPTIONS" | |
185 | TIMEOUT_MULTIPLIER=3 | |
186 | else | |
187 | TIMEOUT_MULTIPLIER=1 | |
188 | fi | |
189 | ||
de9b57a1 | 190 | meson test --print-errorlogs --timeout-multiplier=$TIMEOUT_MULTIPLIER |
ff549982 | 191 | fi |
c3e2dc71 | 192 | cd "$SRCDIR" |
fe2b7631 | 193 | |
fc4b61d0 | 194 | meson install -C "$BUILDDIR" --quiet --no-rebuild --only-changed |
6344a7eb | 195 | |
70e760e3 | 196 | mkdir -p "$DESTDIR"/etc |
6344a7eb | 197 | |
068d1338 | 198 | cat >"$DESTDIR"/etc/issue <<EOF |
6344a7eb LP |
199 | \S (built from systemd tree) |
200 | Kernel \r on an \m (\l) | |
201 | ||
202 | EOF | |
d10ba83a | 203 | |
f533cda5 | 204 | if [ -n "$IMAGE_ID" ] ; then |
2401c9ac DDM |
205 | mkdir -p "$DESTDIR"/usr/lib |
206 | sed -n \ | |
207 | -e '/^IMAGE_ID=/!p' \ | |
208 | -e "\$aIMAGE_ID=$IMAGE_ID" <"/usr/lib/os-release" >"${DESTDIR}/usr/lib/os-release" | |
f533cda5 | 209 | |
2401c9ac | 210 | OSRELEASEFILE="$DESTDIR"/usr/lib/os-release |
f533cda5 | 211 | else |
2401c9ac | 212 | OSRELEASEFILE=/usr/lib/os-release |
f533cda5 LP |
213 | fi |
214 | ||
215 | ||
216 | if [ -n "$IMAGE_VERSION" ] ; then | |
2401c9ac DDM |
217 | mkdir -p "$DESTDIR"/usr/lib |
218 | sed -n \ | |
219 | -e '/^IMAGE_VERSION=/!p' \ | |
220 | -e "\$aIMAGE_VERSION=$IMAGE_VERSION" <$OSRELEASEFILE >"/tmp/os-release.tmp" | |
f533cda5 | 221 | |
f7ad9650 | 222 | cat /tmp/os-release.tmp >"$DESTDIR"/usr/lib/os-release |
2401c9ac | 223 | rm /tmp/os-release.tmp |
f533cda5 | 224 | fi |
24acd406 FS |
225 | |
226 | # If $CI_BUILD is set, copy over the CI service which executes a service check | |
227 | # after boot and then shuts down the machine | |
228 | if [ -n "$CI_BUILD" ]; then | |
2401c9ac DDM |
229 | mkdir -p "$DESTDIR/usr/lib/systemd/system" |
230 | cp -v "$SRCDIR/test/mkosi-check-and-shutdown.service" "$DESTDIR/usr/lib/systemd/system/mkosi-check-and-shutdown.service" | |
231 | cp -v "$SRCDIR/test/mkosi-check-and-shutdown.sh" "$DESTDIR/usr/lib/systemd/mkosi-check-and-shutdown.sh" | |
232 | chmod +x "$DESTDIR/usr/lib/systemd/mkosi-check-and-shutdown.sh" | |
24acd406 | 233 | fi |
69d638e6 DDM |
234 | |
235 | if [ -n "$SANITIZERS" ]; then | |
ac3326df | 236 | LD_PRELOAD=$(ldd "$BUILDDIR"/systemd | grep libasan.so | awk '{print $3}') |
69d638e6 DDM |
237 | |
238 | mkdir -p "$DESTDIR/etc/systemd/system.conf.d" | |
239 | ||
f7ad9650 | 240 | cat >"$DESTDIR/etc/systemd/system.conf.d/10-asan.conf" <<EOF |
69d638e6 DDM |
241 | [Manager] |
242 | ManagerEnvironment=ASAN_OPTIONS=$ASAN_OPTIONS\\ | |
243 | UBSAN_OPTIONS=$UBSAN_OPTIONS\\ | |
244 | LD_PRELOAD=$LD_PRELOAD | |
245 | DefaultEnvironment=ASAN_OPTIONS=$ASAN_OPTIONS\\ | |
246 | UBSAN_OPTIONS=$UBSAN_OPTIONS\\ | |
247 | LD_PRELOAD=$LD_PRELOAD | |
248 | EOF | |
249 | ||
250 | # ASAN logs to stderr by default. However, journald's stderr is connected to /dev/null, so we lose | |
251 | # all the ASAN logs. To rectify that, let's connect journald's stdout to the console so that any | |
252 | # sanitizer failures appear directly on the user's console. | |
253 | mkdir -p "$DESTDIR/etc/systemd/system/systemd-journald.service.d" | |
254 | ||
f7ad9650 | 255 | cat >"$DESTDIR/etc/systemd/system/systemd-journald.service.d/10-stdout-tty.conf" <<EOF |
69d638e6 DDM |
256 | [Service] |
257 | StandardOutput=tty | |
258 | EOF | |
259 | ||
260 | # Both systemd and util-linux's login call vhangup() on /dev/console which disconnects all users. | |
261 | # This means systemd-journald can't log to /dev/console even if we configure `StandardOutput=tty`. As | |
262 | # a workaround, we modify console-getty.service to disable systemd's vhangup() and disallow login | |
263 | # from calling vhangup() so that journald's ASAN logs correctly end up in the console. | |
264 | ||
265 | mkdir -p "$DESTDIR/etc/systemd/system/console-getty.service.d" | |
266 | ||
f7ad9650 | 267 | cat >"$DESTDIR/etc/systemd/system/console-getty.service.d/10-no-vhangup.conf" <<EOF |
69d638e6 DDM |
268 | [Service] |
269 | TTYVHangup=no | |
270 | CapabilityBoundingSet=~CAP_SYS_TTY_CONFIG | |
271 | EOF | |
272 | fi | |
37d35150 DDM |
273 | |
274 | # Make sure services aren't enabled by default on Debian/Ubuntu. | |
275 | mkdir -p "$DESTDIR/etc/systemd/system-preset" | |
f7ad9650 | 276 | echo "disable *" >"$DESTDIR/etc/systemd/system-preset/99-mkosi.preset" |
d12e9bdc DDM |
277 | |
278 | if [ -d mkosi.kernel/ ]; then | |
279 | cd "$SRCDIR/mkosi.kernel" | |
280 | mkdir -p "$BUILDDIR/mkosi.kernel" | |
281 | ||
6c2ff4a0 DDM |
282 | # Ensure fast incremental builds by fixating these values which usually change for each build. |
283 | export KBUILD_BUILD_TIMESTAMP="Fri Jun 5 15:58:00 CEST 2015" | |
284 | export KBUILD_BUILD_HOST="mkosi" | |
285 | ||
37b56a79 DDM |
286 | scripts/kconfig/merge_config.sh -O "$BUILDDIR/mkosi.kernel" \ |
287 | ../mkosi.kernel.config \ | |
288 | tools/testing/selftests/bpf/config.x86_64 \ | |
289 | tools/testing/selftests/bpf/config | |
d12e9bdc DDM |
290 | |
291 | make O="$BUILDDIR/mkosi.kernel" -j "$(nproc)" | |
292 | ||
ac3326df | 293 | KERNEL_RELEASE=$(make O="$BUILDDIR"/mkosi.kernel -s kernelrelease) |
d12e9bdc | 294 | mkdir -p "$DESTDIR/usr/lib/modules/$KERNEL_RELEASE" |
6c2ff4a0 | 295 | make O="$BUILDDIR/mkosi.kernel" INSTALL_HDR_PATH=/usr headers_install |
d12e9bdc DDM |
296 | make O="$BUILDDIR/mkosi.kernel" INSTALL_MOD_PATH="$DESTDIR/usr" modules_install |
297 | make O="$BUILDDIR/mkosi.kernel" INSTALL_PATH="$DESTDIR/usr/lib/modules/$KERNEL_RELEASE" install | |
6c2ff4a0 DDM |
298 | mkdir -p "$DESTDIR/usr/lib/kernel/selftests" |
299 | make -C tools/testing/selftests -j "$(nproc)" O="$BUILDDIR/mkosi.kernel" KSFT_INSTALL_PATH="$DESTDIR/usr/lib/kernel/selftests" SKIP_TARGETS="" install | |
31aba196 DDM |
300 | |
301 | ln -sf /usr/lib/kernel/selftests/bpf/bpftool "$DESTDIR/usr/bin/bpftool" | |
d12e9bdc | 302 | fi |