Skip to content

Commit

Permalink
Merge pull request #1157 from cgwalters/install-finalize
Browse files Browse the repository at this point in the history
install: Add a generic `install finalize`
  • Loading branch information
cgwalters authored Mar 1, 2025
2 parents 859bf9e + 112e36d commit eb585e0
Show file tree
Hide file tree
Showing 5 changed files with 68 additions and 4 deletions.
15 changes: 11 additions & 4 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -59,15 +59,22 @@ test-bin-archive: all
test-tmt:
cargo xtask test-tmt

# Checks extra rust things (formatting, a few extra rust warnings, and select clippy lints)
# This gates CI by default. Note that for clippy, we gate on
# only the clippy correctness and suspicious lints, plus a select
# set of default rustc warnings.
# We intentionally don't gate on this for local builds in cargo.toml
# because it impedes iteration speed.
CLIPPY_CONFIG = -A clippy::all -D clippy::correctness -D clippy::suspicious -Dunused_imports -Ddead_code
validate-rust:
cargo fmt -- --check -l
cargo check
(cd lib && cargo check --no-default-features)
cargo test --no-run
cargo clippy -- -D clippy::correctness -D clippy::suspicious
(cd lib && cargo check --no-default-features)
cargo clippy -- $(CLIPPY_CONFIG)
env RUSTDOCFLAGS='-D warnings' cargo doc --lib
.PHONY: validate-rust
fix-rust:
cargo clippy --fix --allow-dirty -- $(CLIPPY_CONFIG)
.PHONY: fix-rust

validate: validate-rust
ruff check
Expand Down
20 changes: 20 additions & 0 deletions docs/src/bootc-install.md
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,26 @@ storage or filesystem setups, but reuses the "top half" of the logic.
For example, a goal is to change [Anaconda](https://github.com/rhinstaller/anaconda/)
to use this.

#### Postprocessing after to-filesystem

Some installation tools may want to inject additional data, such as adding
an `/etc/hostname` into the target root. At the current time, bootc does
not offer a direct API to do this. However, the backend for bootc is
ostree, and it is possible to enumerate the deployments via ostree APIs.

We hope to provide a bootc-supported method to find the deployment in
the future.

However, for tools that do perform any changes, there is a new
`bootc install finalize` command which is optional, but recommended
to run as the penultimate step before unmounting the target filesystem.

This command will perform some basic sanity checks and may also
perform fixups on the target root. For example, a direction
currently for bootc is to stop using `/etc/fstab`. While `install finalize`
does not do this today, in the future it may automatically migrate
`etc/fstab` to `rootflags` kernel arguments.

### Using `bootc install to-disk --via-loopback`

Because every `bootc` system comes with an opinionated default installation
Expand Down
9 changes: 9 additions & 0 deletions lib/src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,12 @@ pub(crate) enum InstallOpts {
/// will be wiped, but the content of the existing root will otherwise be retained, and will
/// need to be cleaned up if desired when rebooted into the new root.
ToExistingRoot(crate::install::InstallToExistingRootOpts),
/// Execute this as the penultimate step of an installation using `install to-filesystem`.
///
Finalize {
/// Path to the mounted root filesystem.
root_path: Utf8PathBuf,
},
/// Intended for use in environments that are performing an ostree-based installation, not bootc.
///
/// In this scenario the installation may be missing bootc specific features such as
Expand Down Expand Up @@ -1121,6 +1127,9 @@ async fn run_from_opt(opt: Opt) -> Result<()> {
let rootfs = &Dir::open_ambient_dir("/", cap_std::ambient_authority())?;
crate::install::completion::run_from_anaconda(rootfs).await
}
InstallOpts::Finalize { root_path } => {
crate::install::install_finalize(&root_path).await
}
},
Opt::ExecInHostMountNamespace { args } => {
crate::install::exec_in_host_mountns(args.as_slice())
Expand Down
21 changes: 21 additions & 0 deletions lib/src/install.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1452,6 +1452,9 @@ async fn install_to_filesystem_impl(state: &State, rootfs: &mut RootSetup) -> Re
// descriptors.
}

// Run this on every install as the penultimate step
install_finalize(&rootfs.physical_root_path).await?;

// Finalize mounted filesystems
if !rootfs.skip_finalize {
let bootfs = rootfs.boot.as_ref().map(|_| ("boot", "boot"));
Expand Down Expand Up @@ -1909,6 +1912,24 @@ pub(crate) async fn install_to_existing_root(opts: InstallToExistingRootOpts) ->

install_to_filesystem(opts, true).await
}

/// Implementation of `bootc install finalize`.
pub(crate) async fn install_finalize(target: &Utf8Path) -> Result<()> {
crate::cli::require_root(false)?;
let sysroot = ostree::Sysroot::new(Some(&gio::File::for_path(target)));
sysroot.load(gio::Cancellable::NONE)?;
let deployments = sysroot.deployments();
// Verify we find a deployment
if deployments.is_empty() {
anyhow::bail!("Failed to find deployment in {target}");
}

// For now that's it! We expect to add more validation/postprocessing
// later, such as munging `etc/fstab` if needed. See

Ok(())
}

#[cfg(test)]
mod tests {
use super::*;
Expand Down
7 changes: 7 additions & 0 deletions tests-integration/src/install.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,13 @@ pub(crate) fn run_alongside(image: &str, mut testargs: libtest_mimic::Arguments)
std::fs::write(&tmp_keys, b"ssh-ed25519 ABC0123 [email protected]")?;
cmd!(sh, "sudo {BASE_ARGS...} {target_args...} -v {tmp_keys}:/test_authorized_keys {image} bootc install to-filesystem {generic_inst_args...} --acknowledge-destructive --karg=foo=bar --replace=alongside --root-ssh-authorized-keys=/test_authorized_keys /target").run()?;

// Also test install finalize here
cmd!(
sh,
"sudo {BASE_ARGS...} {target_args...} {image} bootc install finalize /target"
)
.run()?;

generic_post_install_verification()?;

// Test kargs injected via CLI
Expand Down

0 comments on commit eb585e0

Please sign in to comment.