Skip to content

Commit eb585e0

Browse files
authored
Merge pull request #1157 from cgwalters/install-finalize
install: Add a generic `install finalize`
2 parents 859bf9e + 112e36d commit eb585e0

File tree

5 files changed

+68
-4
lines changed

5 files changed

+68
-4
lines changed

Makefile

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -59,15 +59,22 @@ test-bin-archive: all
5959
test-tmt:
6060
cargo xtask test-tmt
6161

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

7279
validate: validate-rust
7380
ruff check

docs/src/bootc-install.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,26 @@ storage or filesystem setups, but reuses the "top half" of the logic.
161161
For example, a goal is to change [Anaconda](https://github.com/rhinstaller/anaconda/)
162162
to use this.
163163

164+
#### Postprocessing after to-filesystem
165+
166+
Some installation tools may want to inject additional data, such as adding
167+
an `/etc/hostname` into the target root. At the current time, bootc does
168+
not offer a direct API to do this. However, the backend for bootc is
169+
ostree, and it is possible to enumerate the deployments via ostree APIs.
170+
171+
We hope to provide a bootc-supported method to find the deployment in
172+
the future.
173+
174+
However, for tools that do perform any changes, there is a new
175+
`bootc install finalize` command which is optional, but recommended
176+
to run as the penultimate step before unmounting the target filesystem.
177+
178+
This command will perform some basic sanity checks and may also
179+
perform fixups on the target root. For example, a direction
180+
currently for bootc is to stop using `/etc/fstab`. While `install finalize`
181+
does not do this today, in the future it may automatically migrate
182+
`etc/fstab` to `rootflags` kernel arguments.
183+
164184
### Using `bootc install to-disk --via-loopback`
165185

166186
Because every `bootc` system comes with an opinionated default installation

lib/src/cli.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,12 @@ pub(crate) enum InstallOpts {
209209
/// will be wiped, but the content of the existing root will otherwise be retained, and will
210210
/// need to be cleaned up if desired when rebooted into the new root.
211211
ToExistingRoot(crate::install::InstallToExistingRootOpts),
212+
/// Execute this as the penultimate step of an installation using `install to-filesystem`.
213+
///
214+
Finalize {
215+
/// Path to the mounted root filesystem.
216+
root_path: Utf8PathBuf,
217+
},
212218
/// Intended for use in environments that are performing an ostree-based installation, not bootc.
213219
///
214220
/// In this scenario the installation may be missing bootc specific features such as
@@ -1121,6 +1127,9 @@ async fn run_from_opt(opt: Opt) -> Result<()> {
11211127
let rootfs = &Dir::open_ambient_dir("/", cap_std::ambient_authority())?;
11221128
crate::install::completion::run_from_anaconda(rootfs).await
11231129
}
1130+
InstallOpts::Finalize { root_path } => {
1131+
crate::install::install_finalize(&root_path).await
1132+
}
11241133
},
11251134
Opt::ExecInHostMountNamespace { args } => {
11261135
crate::install::exec_in_host_mountns(args.as_slice())

lib/src/install.rs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1452,6 +1452,9 @@ async fn install_to_filesystem_impl(state: &State, rootfs: &mut RootSetup) -> Re
14521452
// descriptors.
14531453
}
14541454

1455+
// Run this on every install as the penultimate step
1456+
install_finalize(&rootfs.physical_root_path).await?;
1457+
14551458
// Finalize mounted filesystems
14561459
if !rootfs.skip_finalize {
14571460
let bootfs = rootfs.boot.as_ref().map(|_| ("boot", "boot"));
@@ -1909,6 +1912,24 @@ pub(crate) async fn install_to_existing_root(opts: InstallToExistingRootOpts) ->
19091912

19101913
install_to_filesystem(opts, true).await
19111914
}
1915+
1916+
/// Implementation of `bootc install finalize`.
1917+
pub(crate) async fn install_finalize(target: &Utf8Path) -> Result<()> {
1918+
crate::cli::require_root(false)?;
1919+
let sysroot = ostree::Sysroot::new(Some(&gio::File::for_path(target)));
1920+
sysroot.load(gio::Cancellable::NONE)?;
1921+
let deployments = sysroot.deployments();
1922+
// Verify we find a deployment
1923+
if deployments.is_empty() {
1924+
anyhow::bail!("Failed to find deployment in {target}");
1925+
}
1926+
1927+
// For now that's it! We expect to add more validation/postprocessing
1928+
// later, such as munging `etc/fstab` if needed. See
1929+
1930+
Ok(())
1931+
}
1932+
19121933
#[cfg(test)]
19131934
mod tests {
19141935
use super::*;

tests-integration/src/install.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,13 @@ pub(crate) fn run_alongside(image: &str, mut testargs: libtest_mimic::Arguments)
104104
std::fs::write(&tmp_keys, b"ssh-ed25519 ABC0123 [email protected]")?;
105105
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()?;
106106

107+
// Also test install finalize here
108+
cmd!(
109+
sh,
110+
"sudo {BASE_ARGS...} {target_args...} {image} bootc install finalize /target"
111+
)
112+
.run()?;
113+
107114
generic_post_install_verification()?;
108115

109116
// Test kargs injected via CLI

0 commit comments

Comments
 (0)