From 82f8284a947ed520bc3f4a364d9a0cfb9e59e259 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Fri, 7 Nov 2025 16:23:22 -0500 Subject: [PATCH] libvirt-run: Add --update-from-host This streamlines the UX of upgrading from a local build; it's part of the idea of https://github.com/bootc-dev/bcvk/pull/86 but this is a lot smaller than that. Signed-off-by: Colin Walters --- crates/kit/src/cache_metadata.rs | 12 ++++++++++++ crates/kit/src/install_options.rs | 9 +++++++++ crates/kit/src/libvirt/run.rs | 15 ++++++++++++++- docs/src/man/bcvk-libvirt-run.md | 8 ++++++++ docs/src/man/bcvk-libvirt-upload.md | 4 ++++ docs/src/man/bcvk-to-disk.md | 4 ++++ 6 files changed, 51 insertions(+), 1 deletion(-) diff --git a/crates/kit/src/cache_metadata.rs b/crates/kit/src/cache_metadata.rs index d2377f9..cd52bb3 100644 --- a/crates/kit/src/cache_metadata.rs +++ b/crates/kit/src/cache_metadata.rs @@ -34,10 +34,16 @@ struct CacheInputs { /// This is crucial because it determines the upgrade source for the installed system source_imgref: String, + /// Target transport + #[serde(skip_serializing_if = "Option::is_none")] + target_transport: Option, + /// Filesystem type used for installation (e.g., "ext4", "xfs", "btrfs") + #[serde(skip_serializing_if = "Option::is_none")] filesystem: Option, /// Root filesystem size if specified + #[serde(skip_serializing_if = "Option::is_none")] root_size: Option, /// Whether to use composefs-native storage @@ -60,6 +66,9 @@ pub struct DiskImageMetadata { /// This is crucial because it determines the upgrade source for the installed system pub source_imgref: String, + /// Target transport + pub target_transport: Option, + /// Filesystem type used for installation (e.g., "ext4", "xfs", "btrfs") pub filesystem: Option, @@ -82,6 +91,7 @@ impl DiskImageMetadata { let inputs = CacheInputs { image_digest: self.digest.clone(), source_imgref: self.source_imgref.clone(), + target_transport: self.target_transport.clone(), filesystem: self.filesystem.clone(), root_size: self.root_size.clone(), composefs_backend: self.composefs_backend, @@ -169,6 +179,7 @@ impl DiskImageMetadata { version: 1, digest: image_digest.to_owned(), source_imgref: source_imgref.to_owned(), + target_transport: options.target_transport.clone(), filesystem: options.filesystem.clone(), root_size: options.root_size.clone(), kernel_args: options.karg.clone(), @@ -326,6 +337,7 @@ mod tests { let inputs = CacheInputs { image_digest: "sha256:abc123".to_string(), source_imgref: "quay.io/test/image:v1".to_string(), + target_transport: None, filesystem: Some("ext4".to_string()), root_size: Some("20G".to_string()), kernel_args: vec!["console=ttyS0".to_string()], diff --git a/crates/kit/src/install_options.rs b/crates/kit/src/install_options.rs index db0eaca..ce06f58 100644 --- a/crates/kit/src/install_options.rs +++ b/crates/kit/src/install_options.rs @@ -29,6 +29,10 @@ pub struct InstallOptions { )] pub storage_path: Option, + /// The transport; e.g. oci, oci-archive, containers-storage. Defaults to `registry` + #[clap(long)] + pub target_transport: Option, + #[clap(long)] /// Set a kernel argument pub karg: Vec, @@ -57,6 +61,11 @@ impl InstallOptions { args.push(format!("--karg={k}")); } + if let Some(ref t) = self.target_transport { + args.push("--target-transport".to_string()); + args.push(t.clone()); + } + if self.composefs_backend { args.push("--composefs-backend".to_owned()); } diff --git a/crates/kit/src/libvirt/run.rs b/crates/kit/src/libvirt/run.rs index 3f878f2..b6ee8fd 100644 --- a/crates/kit/src/libvirt/run.rs +++ b/crates/kit/src/libvirt/run.rs @@ -22,6 +22,9 @@ use crate::xml_utils; /// SSH wait timeout in seconds const SSH_WAIT_TIMEOUT_SECONDS: u64 = 180; +/// Transport type for updating from host container storage +const UPDATE_FROM_HOST_TRANSPORT: &str = "containers-storage"; + /// Create a virsh command with optional connection URI pub(super) fn virsh_command(connect_uri: Option<&str>) -> Result { let mut cmd = std::process::Command::new("virsh"); @@ -264,6 +267,11 @@ pub struct LibvirtRunOpts { #[clap(long = "bind-storage-ro")] pub bind_storage_ro: bool, + /// Implies --bind-storage-ro, but also configure to update from the host + /// container storage by default. + #[clap(long, conflicts_with = "target_transport")] + pub update_from_host: bool, + /// Firmware type for the VM (defaults to uefi-secure) #[clap(long, default_value = "uefi-secure")] pub firmware: FirmwareType, @@ -381,7 +389,7 @@ fn wait_for_ssh_ready( } /// Execute the libvirt run command -pub fn run(global_opts: &crate::libvirt::LibvirtOptions, opts: LibvirtRunOpts) -> Result<()> { +pub fn run(global_opts: &crate::libvirt::LibvirtOptions, mut opts: LibvirtRunOpts) -> Result<()> { use crate::images; // Validate labels don't contain commas @@ -417,6 +425,11 @@ pub fn run(global_opts: &crate::libvirt::LibvirtOptions, opts: LibvirtRunOpts) - let image_digest = inspect.digest.to_string(); debug!("Image digest: {}", image_digest); + if opts.update_from_host { + opts.bind_storage_ro = true; + opts.install.target_transport = Some(UPDATE_FROM_HOST_TRANSPORT.to_owned()); + } + // Phase 1: Find or create a base disk image let base_disk_path = crate::libvirt::base_disks::find_or_create_base_disk( &opts.image, diff --git a/docs/src/man/bcvk-libvirt-run.md b/docs/src/man/bcvk-libvirt-run.md index 41e36f0..511266e 100644 --- a/docs/src/man/bcvk-libvirt-run.md +++ b/docs/src/man/bcvk-libvirt-run.md @@ -57,6 +57,10 @@ Run a bootable container as a persistent VM Path to host container storage (auto-detected if not specified) +**--target-transport**=*TARGET_TRANSPORT* + + The transport; e.g. oci, oci-archive, containers-storage. Defaults to `registry` + **--karg**=*KARG* Set a kernel argument @@ -103,6 +107,10 @@ Run a bootable container as a persistent VM Mount host container storage (RO) at /run/host-container-storage +**--update-from-host** + + Implies --bind-storage-ro, but also configure to update from the host container storage by default + **--firmware**=*FIRMWARE* Firmware type for the VM (defaults to uefi-secure) diff --git a/docs/src/man/bcvk-libvirt-upload.md b/docs/src/man/bcvk-libvirt-upload.md index c7ab10a..328721a 100644 --- a/docs/src/man/bcvk-libvirt-upload.md +++ b/docs/src/man/bcvk-libvirt-upload.md @@ -45,6 +45,10 @@ Upload bootc disk images to libvirt with metadata annotations Path to host container storage (auto-detected if not specified) +**--target-transport**=*TARGET_TRANSPORT* + + The transport; e.g. oci, oci-archive, containers-storage. Defaults to `registry` + **--karg**=*KARG* Set a kernel argument diff --git a/docs/src/man/bcvk-to-disk.md b/docs/src/man/bcvk-to-disk.md index c082e83..e73fd05 100644 --- a/docs/src/man/bcvk-to-disk.md +++ b/docs/src/man/bcvk-to-disk.md @@ -47,6 +47,10 @@ The installation process: Path to host container storage (auto-detected if not specified) +**--target-transport**=*TARGET_TRANSPORT* + + The transport; e.g. oci, oci-archive, containers-storage. Defaults to `registry` + **--karg**=*KARG* Set a kernel argument