mirror of
https://github.com/containers/bootc.git
synced 2026-02-05 06:45:13 +01:00
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: https://github.com/bootc-dev/bootc/pull/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 <walters@verbum.org>
This commit is contained in:
7
Cargo.lock
generated
7
Cargo.lock
generated
@@ -185,6 +185,13 @@ dependencies = [
|
||||
"tracing",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bootc-initramfs-setup"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bootc-internal-blockdev"
|
||||
version = "0.0.0"
|
||||
|
||||
16
Dockerfile
16
Dockerfile
@@ -39,6 +39,8 @@ EORUN
|
||||
# bootc binaries in /out. The intention is that the target rootfs is extracted from /out
|
||||
# back into a final stae (without the build deps etc) below.
|
||||
FROM base as build
|
||||
# Flip this on to enable initramfs code
|
||||
ARG initramfs=0
|
||||
# This installs our package dependencies, and we want to cache it independently of the rest.
|
||||
# Basically we don't want changing a .rs file to blow out the cache of packages. So we only
|
||||
# copy files necessary
|
||||
@@ -59,8 +61,14 @@ COPY --from=src /src /src
|
||||
WORKDIR /src
|
||||
# See https://www.reddit.com/r/rust/comments/126xeyx/exploring_the_problem_of_faster_cargo_docker/
|
||||
# We aren't using the full recommendations there, just the simple bits.
|
||||
RUN --mount=type=cache,target=/build/target --mount=type=cache,target=/var/roothome \
|
||||
make && make install-all DESTDIR=/out
|
||||
RUN --mount=type=cache,target=/build/target --mount=type=cache,target=/var/roothome <<EORUN
|
||||
set -xeuo pipefail
|
||||
make
|
||||
make install-all DESTDIR=/out
|
||||
if test "${initramfs:-}" = 1; then
|
||||
make install-initramfs-dracut DESTDIR=/out
|
||||
fi
|
||||
EORUN
|
||||
|
||||
# This "build" just runs our unit tests
|
||||
FROM build as units
|
||||
@@ -74,6 +82,10 @@ FROM base
|
||||
COPY --from=build /out/ /
|
||||
RUN <<EORUN
|
||||
set -xeuo pipefail
|
||||
if test -x /usr/lib/bootc/initramfs-setup; then
|
||||
kver=$(cd /usr/lib/modules && echo *);
|
||||
env DRACUT_NO_XATTR=1 dracut -vf /usr/lib/modules/$kver/initramfs.img $kver
|
||||
fi
|
||||
# Only in this containerfile, inject a file which signifies
|
||||
# this comes from this development image. This can be used in
|
||||
# tests to know we're doing upstream CI.
|
||||
|
||||
10
Makefile
10
Makefile
@@ -53,6 +53,16 @@ install-ostree-hooks:
|
||||
ln -sf ../../../bin/bootc $(DESTDIR)$(prefix)/libexec/libostree/ext/$$x; \
|
||||
done
|
||||
|
||||
# Install code in the initramfs, off by default except in builds from git main right now
|
||||
# Also the systemd unit hardcodes /usr so we give up the farce of supporting $(prefix)
|
||||
install-initramfs:
|
||||
install -D -m 0644 -t $(DESTDIR)/usr/lib/systemd/system crates/initramfs/*.service
|
||||
install -D -m 0755 target/release/bootc-initramfs-setup $(DESTDIR)/usr/lib/bootc/initramfs-setup
|
||||
|
||||
# Install initramfs files, including dracut module
|
||||
install-initramfs-dracut: install-initramfs
|
||||
install -D -m 0755 -t $(DESTDIR)/usr/lib/dracut/modules.d/51bootc crates/initramfs/dracut/module-setup.sh
|
||||
|
||||
# Install the main binary, the ostree hooks, and the integration test suite.
|
||||
install-all: install install-ostree-hooks
|
||||
install -D -m 0755 target/release/tests-integration $(DESTDIR)$(prefix)/bin/bootc-integration-tests
|
||||
|
||||
12
crates/initramfs/Cargo.toml
Normal file
12
crates/initramfs/Cargo.toml
Normal file
@@ -0,0 +1,12 @@
|
||||
[package]
|
||||
name = "bootc-initramfs-setup"
|
||||
version = "0.1.0"
|
||||
license = "MIT OR Apache-2.0"
|
||||
edition = "2021"
|
||||
publish = false
|
||||
|
||||
[dependencies]
|
||||
anyhow.workspace = true
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
22
crates/initramfs/bootc-root-setup.service
Normal file
22
crates/initramfs/bootc-root-setup.service
Normal file
@@ -0,0 +1,22 @@
|
||||
[Unit]
|
||||
Description=bootc setup root
|
||||
Documentation=man:bootc(1)
|
||||
DefaultDependencies=no
|
||||
# For now
|
||||
ConditionKernelCommandLine=ostree
|
||||
ConditionPathExists=/etc/initrd-release
|
||||
After=sysroot.mount
|
||||
After=ostree-prepare-root.service
|
||||
Requires=sysroot.mount
|
||||
Before=initrd-root-fs.target
|
||||
|
||||
OnFailure=emergency.target
|
||||
OnFailureJobMode=isolate
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
ExecStart=/usr/lib/bootc/initramfs-setup setup-root
|
||||
StandardInput=null
|
||||
StandardOutput=journal
|
||||
StandardError=journal+console
|
||||
RemainAfterExit=yes
|
||||
18
crates/initramfs/dracut/module-setup.sh
Executable file
18
crates/initramfs/dracut/module-setup.sh
Executable file
@@ -0,0 +1,18 @@
|
||||
#!/bin/bash
|
||||
installkernel() {
|
||||
instmods erofs overlay
|
||||
}
|
||||
check() {
|
||||
require_binaries /usr/lib/bootc/initramfs-setup || return 1
|
||||
}
|
||||
depends() {
|
||||
return 0
|
||||
}
|
||||
install() {
|
||||
local service=bootc-root-setup.service
|
||||
dracut_install /usr/lib/bootc/initramfs-setup
|
||||
inst_simple "${systemdsystemunitdir}/${service}"
|
||||
mkdir -p "${initdir}${systemdsystemconfdir}/initrd-root-fs.target.wants"
|
||||
ln_r "${systemdsystemunitdir}/${service}" \
|
||||
"${systemdsystemconfdir}/initrd-root-fs.target.wants/${service}"
|
||||
}
|
||||
24
crates/initramfs/src/main.rs
Normal file
24
crates/initramfs/src/main.rs
Normal file
@@ -0,0 +1,24 @@
|
||||
//! Code for bootc that goes into the initramfs.
|
||||
//! At the current time, this is mostly just a no-op.
|
||||
// SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
|
||||
use anyhow::Result;
|
||||
|
||||
fn setup_root() -> Result<()> {
|
||||
let _ = std::fs::metadata("/sysroot/usr")?;
|
||||
println!("setup OK");
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn main() -> Result<()> {
|
||||
let v = std::env::args().collect::<Vec<_>>();
|
||||
let args = match v.as_slice() {
|
||||
[] => anyhow::bail!("Missing argument".to_string()),
|
||||
[_, rest @ ..] => rest,
|
||||
};
|
||||
match args {
|
||||
[] => anyhow::bail!("Missing argument".to_string()),
|
||||
[s] if s == "setup-root" => setup_root(),
|
||||
[o, ..] => anyhow::bail!(format!("Unknown command {o}")),
|
||||
}
|
||||
}
|
||||
13
tmt/tests/booted/readonly/051-test-initramfs.nu
Normal file
13
tmt/tests/booted/readonly/051-test-initramfs.nu
Normal file
@@ -0,0 +1,13 @@
|
||||
use std assert
|
||||
use tap.nu
|
||||
|
||||
tap begin "initramfs"
|
||||
|
||||
if (not ("/usr/lib/bootc/initramfs-setup" | path exists)) {
|
||||
print "No initramfs support"
|
||||
exit 0
|
||||
}
|
||||
|
||||
journalctl -b -t bootc-root-setup.service --grep=OK
|
||||
|
||||
tap ok
|
||||
Reference in New Issue
Block a user