Skip to content

Commit f61ba60

Browse files
committed
Add initramfs infrastructure
This adds scaffolding to install a stub binary which can optionally be added into the initramfs; prep for us doing real work during setup as we aim to move to the native composefs backend. The binary is *built* but is only installed by a new `Makefile` target, so existing build system users won't pick it up. Our development-only `Dockerfile` gains a build option to use it (and also ensures the initramfs is regenerated). However previously we also discussed moving the fstab logic into the initramfs: #1113 I might try doing that once this lands. One notable thing is that even this trivial nearly-no-op binary is still 4MB which I think is mostly due to linking in a whole copy of prebuilt rust `std`. In theory we could try going to `#[no_std]` but I don't think it'll be viable once we start doing more here. Probably most practical thing re size is `-Z build-std` + LTO. Signed-off-by: Colin Walters <[email protected]>
1 parent acba07b commit f61ba60

File tree

8 files changed

+121
-3
lines changed

8 files changed

+121
-3
lines changed

Cargo.lock

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Dockerfile

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ EORUN
3939
# bootc binaries in /out. The intention is that the target rootfs is extracted from /out
4040
# back into a final stae (without the build deps etc) below.
4141
FROM base as build
42+
# Flip this on to enable initramfs code
43+
ARG initramfs=0
4244
# This installs our package dependencies, and we want to cache it independently of the rest.
4345
# Basically we don't want changing a .rs file to blow out the cache of packages. So we only
4446
# copy files necessary
@@ -59,8 +61,14 @@ COPY --from=src /src /src
5961
WORKDIR /src
6062
# See https://www.reddit.com/r/rust/comments/126xeyx/exploring_the_problem_of_faster_cargo_docker/
6163
# We aren't using the full recommendations there, just the simple bits.
62-
RUN --mount=type=cache,target=/build/target --mount=type=cache,target=/var/roothome \
63-
make && make install-all DESTDIR=/out
64+
RUN --mount=type=cache,target=/build/target --mount=type=cache,target=/var/roothome <<EORUN
65+
set -xeuo pipefail
66+
make
67+
make install-all DESTDIR=/out
68+
if test "${initramfs:-}" = 1; then
69+
make install-initramfs-dracut DESTDIR=/out
70+
fi
71+
EORUN
6472

6573
# This "build" just runs our unit tests
6674
FROM build as units
@@ -74,6 +82,10 @@ FROM base
7482
COPY --from=build /out/ /
7583
RUN <<EORUN
7684
set -xeuo pipefail
85+
if test -x /usr/lib/bootc/initramfs-setup; then
86+
kver=$(cd /usr/lib/modules && echo *);
87+
env DRACUT_NO_XATTR=1 dracut -vf /usr/lib/modules/$kver/initramfs.img $kver
88+
fi
7789
# Only in this containerfile, inject a file which signifies
7890
# this comes from this development image. This can be used in
7991
# tests to know we're doing upstream CI.

Makefile

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,9 +53,19 @@ install-ostree-hooks:
5353
ln -sf ../../../bin/bootc $(DESTDIR)$(prefix)/libexec/libostree/ext/$$x; \
5454
done
5555

56+
# Install code in the initramfs, off by default except in builds from git main right now
57+
# Also the systemd unit hardcodes /usr so we give up the farce of supporting $(prefix)
58+
install-initramfs:
59+
install -D -m 0644 -t $(DESTDIR)/usr/lib/systemd/system crates/initramfs/*.service
60+
install -D -m 0755 target/release/bootc-initramfs-setup $(DESTDIR)/usr/lib/bootc/initramfs-setup
61+
62+
# Install initramfs files, including dracut module
63+
install-initramfs-dracut: install-initramfs
64+
install -D -m 0755 -t $(DESTDIR)/usr/lib/dracut/modules.d/51bootc crates/initramfs/dracut/module-setup.sh
65+
5666
# Install the main binary, the ostree hooks, and the integration test suite.
5767
install-all: install install-ostree-hooks
58-
install -D -m 0755 target/release/tests-integration $(DESTDIR)$(prefix)/bin/bootc-integration-tests
68+
install -D -m 0755 target/release/tests-integration $(DESTDIR)$(prefix)/bin/bootc-integration-tests
5969

6070
bin-archive: all
6171
$(MAKE) install DESTDIR=tmp-install && $(TAR_REPRODUCIBLE) --zstd -C tmp-install -cf target/bootc.tar.zst . && rm tmp-install -rf

crates/initramfs/Cargo.toml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
[package]
2+
name = "bootc-initramfs-setup"
3+
version = "0.1.0"
4+
license = "MIT OR Apache-2.0"
5+
edition = "2021"
6+
publish = false
7+
8+
[dependencies]
9+
anyhow.workspace = true
10+
11+
[lints]
12+
workspace = true
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
[Unit]
2+
Description=bootc setup root
3+
Documentation=man:bootc(1)
4+
DefaultDependencies=no
5+
# For now
6+
ConditionKernelCommandLine=ostree
7+
ConditionPathExists=/etc/initrd-release
8+
After=sysroot.mount
9+
After=ostree-prepare-root.service
10+
Requires=sysroot.mount
11+
Before=initrd-root-fs.target
12+
13+
OnFailure=emergency.target
14+
OnFailureJobMode=isolate
15+
16+
[Service]
17+
Type=oneshot
18+
ExecStart=/usr/lib/bootc/initramfs-setup setup-root
19+
StandardInput=null
20+
StandardOutput=journal
21+
StandardError=journal+console
22+
RemainAfterExit=yes
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
#!/bin/bash
2+
installkernel() {
3+
instmods erofs overlay
4+
}
5+
check() {
6+
require_binaries /usr/lib/bootc/initramfs-setup || return 1
7+
}
8+
depends() {
9+
return 0
10+
}
11+
install() {
12+
local service=bootc-root-setup.service
13+
dracut_install /usr/lib/bootc/initramfs-setup
14+
inst_simple "${systemdsystemunitdir}/${service}"
15+
mkdir -p "${initdir}${systemdsystemconfdir}/initrd-root-fs.target.wants"
16+
ln_r "${systemdsystemunitdir}/${service}" \
17+
"${systemdsystemconfdir}/initrd-root-fs.target.wants/${service}"
18+
}

crates/initramfs/src/main.rs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
//! Code for bootc that goes into the initramfs.
2+
//! At the current time, this is mostly just a no-op.
3+
// SPDX-License-Identifier: Apache-2.0 OR MIT
4+
5+
use anyhow::Result;
6+
7+
fn setup_root() -> Result<()> {
8+
let _ = std::fs::metadata("/sysroot/usr")?;
9+
println!("setup OK");
10+
Ok(())
11+
}
12+
13+
fn main() -> Result<()> {
14+
let v = std::env::args().collect::<Vec<_>>();
15+
let args = match v.as_slice() {
16+
[] => anyhow::bail!("Missing argument".to_string()),
17+
[_, rest @ ..] => rest,
18+
};
19+
match args {
20+
[] => anyhow::bail!("Missing argument".to_string()),
21+
[s] if s == "setup-root" => setup_root(),
22+
[o, ..] => anyhow::bail!(format!("Unknown command {o}")),
23+
}
24+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
use std assert
2+
use tap.nu
3+
4+
tap begin "initramfs"
5+
6+
if (not ("/usr/lib/bootc/initramfs-setup" | path exists)) {
7+
print "No initramfs support"
8+
exit 0
9+
}
10+
11+
journalctl -b -t bootc-root-setup.service --grep=OK
12+
13+
tap ok

0 commit comments

Comments
 (0)