]>
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 | ||
70e760e3 LP |
11 | # If mkosi.builddir/ exists mkosi will set $BUILDDIR to it, let's then use it |
12 | # as out-of-tree build dir. Otherwise, let's make up our own builddir. | |
84a4af2c DDM |
13 | [ -z "$BUILDDIR" ] && BUILDDIR="$PWD"/build |
14 | ||
15 | # Let's make sure we're using stuff from the build directory first if available there. | |
16 | PATH="$BUILDDIR:$PATH" | |
17 | export PATH | |
70e760e3 | 18 | |
2ea09665 FB |
19 | # Meson uses Python 3 and requires a locale with an UTF-8 character map. |
20 | # Not running under UTF-8 makes the `ninja test` step break with a CodecError. | |
21 | # So let's ensure we're running under UTF-8. | |
22 | # | |
23 | # If our current locale already is UTF-8, then we don't need to do anything: | |
068d1338 | 24 | if [ "$(locale charmap 2>/dev/null)" != "UTF-8" ] ; then |
2ea09665 FB |
25 | # Try using C.UTF-8 locale, if available. This locale is not shipped |
26 | # by upstream glibc, so it's not available in all distros. | |
27 | # (In particular, it's not available in Arch Linux.) | |
5e577e17 DDM |
28 | if locale -a | grep -q -E "C.UTF-8|C.utf8"; then |
29 | export LC_CTYPE=C.UTF-8 | |
30 | # Finally, try something like en_US.UTF-8, which should be | |
31 | # available in Arch Linux, but is not present in Debian's | |
32 | # minimal image in our mkosi config. | |
33 | elif locale -a | grep -q en_US.utf8; then | |
2ea09665 | 34 | export LC_CTYPE=en_US.UTF-8 |
5e577e17 DDM |
35 | else |
36 | # If nothing works, fail early. | |
37 | echo "*** Could not find a valid locale that supports UTF-8. ***" >&2 | |
38 | exit 1 | |
2ea09665 FB |
39 | fi |
40 | fi | |
9400405b | 41 | |
37d35150 DDM |
42 | # The bpftool script shipped by Ubuntu tries to find the actual program to run via querying `uname -r` and |
43 | # using the current kernel version. This obviously doesn't work in containers. As a workaround, we override | |
44 | # the ubuntu script with a symlink to the first bpftool program we can find. | |
45 | for bpftool in /usr/lib/linux-tools/*/bpftool; do | |
46 | [ -x "$bpftool" ] || continue | |
84a4af2c | 47 | ln -sf "$bpftool" "$BUILDDIR"/bpftool |
37d35150 DDM |
48 | break |
49 | done | |
50 | ||
6afeac1d DDM |
51 | # CentOS Stream 8 includes bpftool 4.18.0 which is lower than what we need. However, they've backported the |
52 | # specific feature we need ("gen skeleton") to this version, so we replace bpftool with a script that reports | |
53 | # version 5.6.0 to satisfy meson which makes bpf work on CentOS Stream 8 as well. | |
54 | if [ "$(grep '^ID=' /etc/os-release)" = "ID=\"centos\"" ] && [ "$(grep '^VERSION=' /etc/os-release)" = "VERSION=\"8\"" ]; then | |
84a4af2c | 55 | cat >"$BUILDDIR"/bpftool <<EOF |
6afeac1d DDM |
56 | #!/bin/sh |
57 | if [ "\$1" = --version ]; then | |
58 | echo 5.6.0 | |
59 | else | |
84a4af2c | 60 | exec /usr/sbin/bpftool \$@ |
6afeac1d DDM |
61 | fi |
62 | EOF | |
84a4af2c | 63 | chmod +x "$BUILDDIR"/bpftool |
6afeac1d DDM |
64 | fi |
65 | ||
c81a2569 | 66 | if [ ! -f "$BUILDDIR"/build.ninja ] ; then |
068d1338 | 67 | sysvinit_path=$(realpath /etc/init.d) |
8da0592c | 68 | |
068d1338 | 69 | init_path=$(realpath /sbin/init 2>/dev/null) |
bac567a5 | 70 | if [ -z "$init_path" ] ; then |
2401c9ac | 71 | rootprefix="" |
bac567a5 | 72 | else |
2401c9ac DDM |
73 | rootprefix=${init_path%/lib/systemd/systemd} |
74 | rootprefix=/${rootprefix#/} | |
bac567a5 MK |
75 | fi |
76 | ||
bbb40c4e LB |
77 | # On debian-like systems the library directory is not /usr/lib64 but /usr/lib/<arch-triplet>/. |
78 | # It is important to use the right one especially for cryptsetup plugins, otherwise they will be | |
79 | # installed in the wrong directory and not be found by cryptsetup. Assume native build. | |
80 | if grep -q -e "ID=debian" -e "ID_LIKE=debian" /etc/os-release && command -v dpkg 2>/dev/null; then | |
81 | LIBDIR="-Drootlibdir=/usr/lib/$(dpkg-architecture -qDEB_HOST_MULTIARCH)" | |
82 | PAMDIR="-Dpamlibdir=/usr/lib/$(dpkg-architecture -qDEB_HOST_MULTIARCH)/security" | |
83 | fi | |
84 | ||
85 | # Cannot quote $LIBDIR and $PAMDIR, because they may be empty, and meson will fail. | |
86 | # shellcheck disable=SC2086 | |
8c21a0c9 | 87 | meson setup "$BUILDDIR" \ |
bbb40c4e LB |
88 | ${LIBDIR:-} \ |
89 | ${PAMDIR:-} \ | |
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 | 177 | if [ "$WITH_TESTS" = 1 ] ; then |
69d638e6 DDM |
178 | if [ -n "$SANITIZERS" ]; then |
179 | export ASAN_OPTIONS="$ASAN_OPTIONS" | |
180 | export UBSAN_OPTIONS="$UBSAN_OPTIONS" | |
181 | TIMEOUT_MULTIPLIER=3 | |
182 | else | |
183 | TIMEOUT_MULTIPLIER=1 | |
184 | fi | |
185 | ||
de9b57a1 | 186 | meson test --print-errorlogs --timeout-multiplier=$TIMEOUT_MULTIPLIER |
ff549982 | 187 | fi |
c3e2dc71 | 188 | cd "$SRCDIR" |
fe2b7631 | 189 | |
fc4b61d0 | 190 | meson install -C "$BUILDDIR" --quiet --no-rebuild --only-changed |
6344a7eb | 191 | |
70e760e3 | 192 | mkdir -p "$DESTDIR"/etc |
6344a7eb | 193 | |
068d1338 | 194 | cat >"$DESTDIR"/etc/issue <<EOF |
6344a7eb LP |
195 | \S (built from systemd tree) |
196 | Kernel \r on an \m (\l) | |
197 | ||
198 | EOF | |
d10ba83a | 199 | |
f533cda5 | 200 | if [ -n "$IMAGE_ID" ] ; then |
2401c9ac DDM |
201 | mkdir -p "$DESTDIR"/usr/lib |
202 | sed -n \ | |
203 | -e '/^IMAGE_ID=/!p' \ | |
204 | -e "\$aIMAGE_ID=$IMAGE_ID" <"/usr/lib/os-release" >"${DESTDIR}/usr/lib/os-release" | |
f533cda5 | 205 | |
2401c9ac | 206 | OSRELEASEFILE="$DESTDIR"/usr/lib/os-release |
f533cda5 | 207 | else |
2401c9ac | 208 | OSRELEASEFILE=/usr/lib/os-release |
f533cda5 LP |
209 | fi |
210 | ||
211 | ||
212 | if [ -n "$IMAGE_VERSION" ] ; then | |
2401c9ac DDM |
213 | mkdir -p "$DESTDIR"/usr/lib |
214 | sed -n \ | |
215 | -e '/^IMAGE_VERSION=/!p' \ | |
216 | -e "\$aIMAGE_VERSION=$IMAGE_VERSION" <$OSRELEASEFILE >"/tmp/os-release.tmp" | |
f533cda5 | 217 | |
f7ad9650 | 218 | cat /tmp/os-release.tmp >"$DESTDIR"/usr/lib/os-release |
2401c9ac | 219 | rm /tmp/os-release.tmp |
f533cda5 | 220 | fi |
24acd406 FS |
221 | |
222 | # If $CI_BUILD is set, copy over the CI service which executes a service check | |
223 | # after boot and then shuts down the machine | |
224 | if [ -n "$CI_BUILD" ]; then | |
2401c9ac DDM |
225 | mkdir -p "$DESTDIR/usr/lib/systemd/system" |
226 | cp -v "$SRCDIR/test/mkosi-check-and-shutdown.service" "$DESTDIR/usr/lib/systemd/system/mkosi-check-and-shutdown.service" | |
227 | cp -v "$SRCDIR/test/mkosi-check-and-shutdown.sh" "$DESTDIR/usr/lib/systemd/mkosi-check-and-shutdown.sh" | |
228 | chmod +x "$DESTDIR/usr/lib/systemd/mkosi-check-and-shutdown.sh" | |
24acd406 | 229 | fi |
69d638e6 DDM |
230 | |
231 | if [ -n "$SANITIZERS" ]; then | |
ac3326df | 232 | LD_PRELOAD=$(ldd "$BUILDDIR"/systemd | grep libasan.so | awk '{print $3}') |
69d638e6 DDM |
233 | |
234 | mkdir -p "$DESTDIR/etc/systemd/system.conf.d" | |
235 | ||
f7ad9650 | 236 | cat >"$DESTDIR/etc/systemd/system.conf.d/10-asan.conf" <<EOF |
69d638e6 DDM |
237 | [Manager] |
238 | ManagerEnvironment=ASAN_OPTIONS=$ASAN_OPTIONS\\ | |
239 | UBSAN_OPTIONS=$UBSAN_OPTIONS\\ | |
240 | LD_PRELOAD=$LD_PRELOAD | |
241 | DefaultEnvironment=ASAN_OPTIONS=$ASAN_OPTIONS\\ | |
242 | UBSAN_OPTIONS=$UBSAN_OPTIONS\\ | |
243 | LD_PRELOAD=$LD_PRELOAD | |
244 | EOF | |
245 | ||
246 | # ASAN logs to stderr by default. However, journald's stderr is connected to /dev/null, so we lose | |
247 | # all the ASAN logs. To rectify that, let's connect journald's stdout to the console so that any | |
248 | # sanitizer failures appear directly on the user's console. | |
249 | mkdir -p "$DESTDIR/etc/systemd/system/systemd-journald.service.d" | |
250 | ||
f7ad9650 | 251 | cat >"$DESTDIR/etc/systemd/system/systemd-journald.service.d/10-stdout-tty.conf" <<EOF |
69d638e6 DDM |
252 | [Service] |
253 | StandardOutput=tty | |
254 | EOF | |
255 | ||
256 | # Both systemd and util-linux's login call vhangup() on /dev/console which disconnects all users. | |
257 | # This means systemd-journald can't log to /dev/console even if we configure `StandardOutput=tty`. As | |
258 | # a workaround, we modify console-getty.service to disable systemd's vhangup() and disallow login | |
259 | # from calling vhangup() so that journald's ASAN logs correctly end up in the console. | |
260 | ||
261 | mkdir -p "$DESTDIR/etc/systemd/system/console-getty.service.d" | |
262 | ||
f7ad9650 | 263 | cat >"$DESTDIR/etc/systemd/system/console-getty.service.d/10-no-vhangup.conf" <<EOF |
69d638e6 DDM |
264 | [Service] |
265 | TTYVHangup=no | |
266 | CapabilityBoundingSet=~CAP_SYS_TTY_CONFIG | |
267 | EOF | |
268 | fi | |
37d35150 DDM |
269 | |
270 | # Make sure services aren't enabled by default on Debian/Ubuntu. | |
271 | mkdir -p "$DESTDIR/etc/systemd/system-preset" | |
f7ad9650 | 272 | echo "disable *" >"$DESTDIR/etc/systemd/system-preset/99-mkosi.preset" |
d12e9bdc DDM |
273 | |
274 | if [ -d mkosi.kernel/ ]; then | |
275 | cd "$SRCDIR/mkosi.kernel" | |
276 | mkdir -p "$BUILDDIR/mkosi.kernel" | |
277 | ||
6c2ff4a0 DDM |
278 | # Ensure fast incremental builds by fixating these values which usually change for each build. |
279 | export KBUILD_BUILD_TIMESTAMP="Fri Jun 5 15:58:00 CEST 2015" | |
280 | export KBUILD_BUILD_HOST="mkosi" | |
281 | ||
37b56a79 DDM |
282 | scripts/kconfig/merge_config.sh -O "$BUILDDIR/mkosi.kernel" \ |
283 | ../mkosi.kernel.config \ | |
284 | tools/testing/selftests/bpf/config.x86_64 \ | |
285 | tools/testing/selftests/bpf/config | |
d12e9bdc DDM |
286 | |
287 | make O="$BUILDDIR/mkosi.kernel" -j "$(nproc)" | |
288 | ||
ac3326df | 289 | KERNEL_RELEASE=$(make O="$BUILDDIR"/mkosi.kernel -s kernelrelease) |
d12e9bdc DDM |
290 | mkdir -p "$DESTDIR/usr/lib/modules/$KERNEL_RELEASE" |
291 | make O="$BUILDDIR/mkosi.kernel" INSTALL_MOD_PATH="$DESTDIR/usr" modules_install | |
292 | make O="$BUILDDIR/mkosi.kernel" INSTALL_PATH="$DESTDIR/usr/lib/modules/$KERNEL_RELEASE" install | |
6c2ff4a0 DDM |
293 | mkdir -p "$DESTDIR/usr/lib/kernel/selftests" |
294 | make -C tools/testing/selftests -j "$(nproc)" O="$BUILDDIR/mkosi.kernel" KSFT_INSTALL_PATH="$DESTDIR/usr/lib/kernel/selftests" SKIP_TARGETS="" install | |
31aba196 DDM |
295 | |
296 | ln -sf /usr/lib/kernel/selftests/bpf/bpftool "$DESTDIR/usr/bin/bpftool" | |
d12e9bdc | 297 | fi |