Skip to main content

bootc_lib/
ukify.rs

1//! Build Unified Kernel Images (UKI) using ukify.
2//!
3//! This module provides functionality to build UKIs by computing the necessary
4//! arguments from a container image and invoking the ukify tool. Default V1
5//! UKIs also carry the legacy V2 digest for older bootc clients.
6
7use std::ffi::OsString;
8use std::process::Command;
9
10use anyhow::{Context, Result};
11use bootc_utils::CommandRunExt;
12use camino::Utf8Path;
13use fn_error_context::context;
14
15use crate::boot_artifact::prepare_boot_artifact;
16use crate::cli::BootArtifactErofsVersionArg;
17
18/// Build a UKI from the given rootfs.
19///
20/// Finds the kernel, computes the composefs digest, reads kernel arguments from
21/// kargs.d, then invokes ukify with any additional pass-through arguments.
22#[context("Building UKI")]
23pub(crate) async fn build_ukify(
24    rootfs: &Utf8Path,
25    extra_kargs: &[String],
26    args: &[OsString],
27    kernel_dir: Option<&Utf8Path>,
28    allow_missing_fsverity: bool,
29    erofs_version: Option<BootArtifactErofsVersionArg>,
30    write_dumpfile_to: Option<&Utf8Path>,
31) -> Result<()> {
32    if !extra_kargs.is_empty() {
33        tracing::warn!(
34            "The --karg flag is temporary and will be removed as soon as possible \
35            (https://github.com/bootc-dev/bootc/issues/1826)"
36        );
37    }
38
39    if !crate::utils::have_executable("ukify")? {
40        anyhow::bail!(
41            "ukify executable not found in PATH. Please install systemd-ukify or equivalent."
42        );
43    }
44
45    let inputs = prepare_boot_artifact(
46        rootfs,
47        kernel_dir,
48        extra_kargs,
49        allow_missing_fsverity,
50        erofs_version,
51        write_dumpfile_to,
52    )
53    .await?;
54
55    let mut cmd = Command::new("ukify");
56    cmd.current_dir(rootfs);
57    cmd.arg("build")
58        .arg("--linux")
59        .arg(&inputs.vmlinuz)
60        .arg("--initrd")
61        .arg(&inputs.initramfs)
62        .arg("--uname")
63        .arg(&inputs.kernel_version)
64        .arg("--cmdline")
65        .arg(&inputs.cmdline)
66        .arg("--os-release")
67        .arg("@usr/lib/os-release");
68    cmd.args(args);
69
70    tracing::debug!("Executing ukify: {:?}", cmd);
71    cmd.run_inherited().context("Running ukify")?;
72
73    Ok(())
74}