diff --git a/crates/lib/src/bootc_composefs/boot.rs b/crates/lib/src/bootc_composefs/boot.rs index 81a6dfa21..49890aa37 100644 --- a/crates/lib/src/bootc_composefs/boot.rs +++ b/crates/lib/src/bootc_composefs/boot.rs @@ -1405,7 +1405,7 @@ pub(crate) async fn setup_composefs_boot( write_composefs_state( &root_setup.physical_root_path, &id, - &crate::spec::ImageReference::from(state.target_imgref.clone()), + &crate::spec::ImageReferenceSig::from(state.target_imgref.clone()), None, boot_type, boot_digest, diff --git a/crates/lib/src/bootc_composefs/repo.rs b/crates/lib/src/bootc_composefs/repo.rs index 1f59fb8d7..d5e696d5d 100644 --- a/crates/lib/src/bootc_composefs/repo.rs +++ b/crates/lib/src/bootc_composefs/repo.rs @@ -237,7 +237,7 @@ async fn pull_composefs_unified( /// Checks for boot entries in the image and returns them. #[context("Pulling composefs repository")] pub(crate) async fn pull_composefs_repo( - spec_imgref: &crate::spec::ImageReference, + spec_imgref: &crate::spec::ImageReferenceSig, allow_missing_fsverity: bool, use_unified: bool, ) -> Result { diff --git a/crates/lib/src/bootc_composefs/state.rs b/crates/lib/src/bootc_composefs/state.rs index 6c14f954b..a4a8a0a37 100644 --- a/crates/lib/src/bootc_composefs/state.rs +++ b/crates/lib/src/bootc_composefs/state.rs @@ -38,7 +38,7 @@ use crate::{ SHARED_VAR_PATH, STATE_DIR_RELATIVE, }, parsers::bls_config::BLSConfig, - spec::ImageReference, + spec::ImageReferenceSig, spec::{FilesystemOverlay, FilesystemOverlayAccessMode, FilesystemOverlayPersistence}, utils::path_relative_to, }; @@ -230,7 +230,7 @@ pub(crate) fn update_boot_digest_in_origin( pub(crate) async fn write_composefs_state( root_path: &Utf8PathBuf, deployment_id: &Sha512HashValue, - target_imgref: &ImageReference, + target_imgref: &ImageReferenceSig, staged: Option, boot_type: BootType, boot_digest: String, diff --git a/crates/lib/src/bootc_composefs/status.rs b/crates/lib/src/bootc_composefs/status.rs index 7e08fa115..5d982f229 100644 --- a/crates/lib/src/bootc_composefs/status.rs +++ b/crates/lib/src/bootc_composefs/status.rs @@ -25,7 +25,7 @@ use crate::{ bls_config::{BLSConfig, BLSConfigType, parse_bls_config}, grub_menuconfig::{MenuEntry, parse_grub_menuentry_file}, }, - spec::{BootEntry, BootOrder, Host, HostSpec, ImageReference, ImageStatus}, + spec::{BootEntry, BootOrder, Host, HostSpec, ImageStatus}, store::Storage, utils::{EfiError, read_uefi_var}, }; @@ -468,7 +468,7 @@ fn boot_entry_from_composefs_deployment( let image = match origin.get::("origin", ORIGIN_CONTAINER) { Some(img_name_from_config) => { let ostree_img_ref = OstreeImageReference::from_str(&img_name_from_config)?; - let img_ref = ImageReference::from(ostree_img_ref); + let img_ref = crate::spec::ImageReferenceSig::from(ostree_img_ref); let img_conf = get_imginfo(storage, &verity)?; diff --git a/crates/lib/src/bootc_composefs/update.rs b/crates/lib/src/bootc_composefs/update.rs index 0be2e430d..ce2f42f68 100644 --- a/crates/lib/src/bootc_composefs/update.rs +++ b/crates/lib/src/bootc_composefs/update.rs @@ -29,7 +29,7 @@ use crate::{ COMPOSEFS_STAGED_DEPLOYMENT_FNAME, COMPOSEFS_TRANSIENT_STATE_DIR, STATE_DIR_RELATIVE, TYPE1_ENT_PATH_STAGED, USER_CFG_STAGED, }, - spec::{Bootloader, Host, ImageReference}, + spec::{Bootloader, Host, ImageReferenceSig}, store::{BootedComposefs, ComposefsRepository, Storage}, }; @@ -54,7 +54,7 @@ use crate::{ #[context("Checking if image {} is pulled", imgref.image)] pub(crate) async fn is_image_pulled( repo: &ComposefsRepository, - imgref: &ImageReference, + imgref: &ImageReferenceSig, ) -> Result<(Option, ImgConfigManifest)> { let imgref_repr = imgref.to_image_proxy_ref()?; let img_config_manifest = get_container_manifest_and_config(&imgref_repr.to_string()).await?; @@ -242,7 +242,7 @@ pub(crate) async fn do_upgrade( storage: &Storage, booted_cfs: &BootedComposefs, host: &Host, - imgref: &ImageReference, + imgref: &ImageReferenceSig, opts: &DoUpgradeOpts, manifest: &ostree_ext::oci_spec::image::ImageManifest, ) -> Result<()> { diff --git a/crates/lib/src/cli.rs b/crates/lib/src/cli.rs index 48559f34d..15c304a66 100644 --- a/crates/lib/src/cli.rs +++ b/crates/lib/src/cli.rs @@ -53,7 +53,7 @@ use crate::podstorage::set_additional_image_store; use crate::progress_jsonl::{ProgressWriter, RawProgressFd}; use crate::spec::FilesystemOverlayAccessMode; use crate::spec::Host; -use crate::spec::ImageReference; +use crate::spec::ImageReferenceSig; use crate::status::get_host; use crate::store::{BootedOstree, Storage}; use crate::store::{BootedStorage, BootedStorageKind}; @@ -1347,7 +1347,7 @@ async fn upgrade( Ok(()) } -pub(crate) fn imgref_for_switch(opts: &SwitchOpts) -> Result { +pub(crate) fn imgref_for_switch(opts: &SwitchOpts) -> Result { let transport = ostree_container::Transport::try_from(opts.transport.as_str())?; let imgref = ostree_container::ImageReference { transport, @@ -1355,7 +1355,7 @@ pub(crate) fn imgref_for_switch(opts: &SwitchOpts) -> Result { }; let sigverify = sigpolicy_from_opt(opts.enforce_container_sigpolicy); let target = ostree_container::OstreeImageReference { sigverify, imgref }; - let target = ImageReference::from(target); + let target = ImageReferenceSig::from(target); return Ok(target); } @@ -2482,7 +2482,7 @@ mod tests { #[test] fn test_image_reference_with_tag() { // Test basic tag replacement for registry transport - let current = ImageReference { + let current = ImageReferenceSig { image: "quay.io/example/myapp:v1.0".to_string(), transport: "registry".to_string(), signature: None, @@ -2492,7 +2492,7 @@ mod tests { assert_eq!(result.transport, "registry"); // Test tag replacement with digest (digest should be stripped for registry) - let current_with_digest = ImageReference { + let current_with_digest = ImageReferenceSig { image: "quay.io/example/myapp:v1.0@sha256:abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890".to_string(), transport: "registry".to_string(), signature: None, @@ -2501,7 +2501,7 @@ mod tests { assert_eq!(result.image, "quay.io/example/myapp:v2.0"); // Test that non-registry transport works (containers-storage) - let containers_storage = ImageReference { + let containers_storage = ImageReferenceSig { image: "localhost/myapp:v1.0".to_string(), transport: "containers-storage".to_string(), signature: None, @@ -2511,7 +2511,7 @@ mod tests { assert_eq!(result.transport, "containers-storage"); // Test digest stripping for non-registry transport - let containers_storage_with_digest = ImageReference { + let containers_storage_with_digest = ImageReferenceSig { image: "localhost/myapp:v1.0@sha256:abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890" .to_string(), @@ -2523,7 +2523,7 @@ mod tests { assert_eq!(result.transport, "containers-storage"); // Test image without tag (edge case) - let no_tag = ImageReference { + let no_tag = ImageReferenceSig { image: "localhost/myapp".to_string(), transport: "containers-storage".to_string(), signature: None, diff --git a/crates/lib/src/deploy.rs b/crates/lib/src/deploy.rs index c4c686eca..3f5ca4346 100644 --- a/crates/lib/src/deploy.rs +++ b/crates/lib/src/deploy.rs @@ -24,7 +24,7 @@ use ostree_ext::sysroot::SysrootLock; use ostree_ext::tokio_util::spawn_blocking_cancellable_flatten; use crate::progress_jsonl::{Event, ProgressWriter, SubTaskBytes, SubTaskStep}; -use crate::spec::ImageReference; +use crate::spec::ImageReferenceSig; use crate::spec::{BootOrder, HostSpec}; use crate::status::labels_of_config; use crate::store::Storage; @@ -48,7 +48,7 @@ const BOOTC_DERIVED_KEY: &str = "bootc.derived"; /// Variant of HostSpec but required to be filled out pub(crate) struct RequiredHostSpec<'a> { - pub(crate) image: &'a ImageReference, + pub(crate) image: &'a ImageReferenceSig, } /// State of a locally fetched image @@ -388,7 +388,7 @@ fn check_disk_space_inner( fd: impl AsFd, bytes_to_fetch: u64, min_free: u64, - imgref: &ImageReference, + imgref: &ImageReferenceSig, ) -> Result<()> { let stat = rustix::fs::fstatvfs(fd)?; let bytes_avail = stat.f_bsize.checked_mul(stat.f_bavail).unwrap_or(u64::MAX); @@ -411,7 +411,7 @@ fn check_disk_space_inner( pub(crate) fn check_disk_space_ostree( repo: &ostree::Repo, image_meta: &PreparedImportMeta, - imgref: &ImageReference, + imgref: &ImageReferenceSig, ) -> Result<()> { let min_free = repo.min_free_space_bytes().unwrap_or(0); check_disk_space_inner( @@ -427,7 +427,7 @@ pub(crate) fn check_disk_space_ostree( pub(crate) fn check_disk_space_unified( cfs: &crate::store::ComposefsRepository, image_meta: &PreparedImportMeta, - imgref: &ImageReference, + imgref: &ImageReferenceSig, ) -> Result<()> { check_disk_space_inner(cfs.objects_dir()?, image_meta.bytes_to_fetch, 0, imgref) } @@ -437,7 +437,7 @@ pub(crate) fn check_disk_space_unified( pub(crate) fn check_disk_space_composefs( cfs: &crate::store::ComposefsRepository, manifest: &ostree_ext::oci_spec::image::ImageManifest, - imgref: &ImageReference, + imgref: &ImageReferenceSig, ) -> Result<()> { let bytes_to_fetch: u64 = manifest .layers() @@ -464,7 +464,7 @@ pub(crate) enum PreparedPullResult { pub(crate) async fn prepare_for_pull( repo: &ostree::Repo, - imgref: &ImageReference, + imgref: &ImageReferenceSig, target_imgref: Option<&OstreeImageReference>, booted_deployment: Option<&ostree::Deployment>, ) -> Result { @@ -511,7 +511,7 @@ pub(crate) async fn prepare_for_pull( /// Returns true if the image exists in bootc storage. pub(crate) async fn image_exists_in_unified_storage( store: &Storage, - imgref: &ImageReference, + imgref: &ImageReferenceSig, ) -> Result { let imgstore = store.get_ensure_imgstore()?; let image_ref_str = imgref.to_transport_image()?; @@ -522,7 +522,7 @@ pub(crate) async fn image_exists_in_unified_storage( /// This reuses the same infrastructure as LBIs. pub(crate) async fn prepare_for_pull_unified( repo: &ostree::Repo, - imgref: &ImageReference, + imgref: &ImageReferenceSig, target_imgref: Option<&OstreeImageReference>, store: &Storage, booted_deployment: Option<&ostree::Deployment>, @@ -548,7 +548,7 @@ pub(crate) async fn prepare_for_pull_unified( // Now create a containers-storage reference to read from bootc storage tracing::info!("Unified pull: now importing from containers-storage transport"); - let containers_storage_imgref = ImageReference { + let containers_storage_imgref = ImageReferenceSig { transport: "containers-storage".to_string(), image: imgref.image.clone(), signature: imgref.signature.clone(), @@ -614,7 +614,7 @@ pub(crate) async fn prepare_for_pull_unified( /// Unified pull: Use podman to pull to containers-storage, then read from there pub(crate) async fn pull_unified( repo: &ostree::Repo, - imgref: &ImageReference, + imgref: &ImageReferenceSig, target_imgref: Option<&OstreeImageReference>, quiet: bool, prog: ProgressWriter, @@ -642,7 +642,7 @@ pub(crate) async fn pull_unified( imgref, )?; // To avoid duplicate success logs, pass a containers-storage imgref to the importer - let cs_imgref = ImageReference { + let cs_imgref = ImageReferenceSig { transport: "containers-storage".to_string(), image: imgref.image.clone(), signature: imgref.signature.clone(), @@ -654,7 +654,7 @@ pub(crate) async fn pull_unified( #[context("Pulling")] pub(crate) async fn pull_from_prepared( - imgref: &ImageReference, + imgref: &ImageReferenceSig, quiet: bool, prog: ProgressWriter, mut prepared_image: PreparedImportMeta, @@ -729,7 +729,7 @@ pub(crate) async fn pull_from_prepared( /// Wrapper for pulling a container image, wiring up status output. pub(crate) async fn pull( repo: &ostree::Repo, - imgref: &ImageReference, + imgref: &ImageReferenceSig, target_imgref: Option<&OstreeImageReference>, quiet: bool, prog: ProgressWriter, @@ -922,7 +922,7 @@ async fn deploy( } #[context("Generating origin")] -fn origin_from_imageref(imgref: &ImageReference) -> Result { +fn origin_from_imageref(imgref: &ImageReferenceSig) -> Result { let origin = glib::KeyFile::new(); let imgref = OstreeImageReference::from(imgref.clone()); origin.set_string( @@ -1215,7 +1215,7 @@ fn find_newest_deployment_name(deploysdir: &Dir) -> Result { } // Implementation of `bootc switch --in-place` -pub(crate) fn switch_origin_inplace(root: &Dir, imgref: &ImageReference) -> Result { +pub(crate) fn switch_origin_inplace(root: &Dir, imgref: &ImageReferenceSig) -> Result { // Log the in-place switch operation to systemd journal const SWITCH_INPLACE_JOURNAL_ID: &str = "3e2f1a0b9c8d7e6f5a4b3c2d1e0f9a8b7"; @@ -1385,7 +1385,7 @@ mod tests { builder, )?; let deploydir = &td.open_dir(deploydir)?; - let orig_imgref = ImageReference { + let orig_imgref = ImageReferenceSig { image: "quay.io/exampleos/original:sometag".into(), transport: "registry".into(), signature: None, @@ -1398,7 +1398,7 @@ mod tests { )?; } - let target_imgref = ImageReference { + let target_imgref = ImageReferenceSig { image: "quay.io/someother/otherimage:latest".into(), transport: "registry".into(), signature: None, @@ -1465,7 +1465,7 @@ UUID=6907-17CA /boot/efi vfat umask=0077,shortname=win #[test] fn test_check_disk_space_inner() -> Result<()> { let td = cap_std_ext::cap_tempfile::TempDir::new(cap_std::ambient_authority())?; - let imgref = ImageReference { + let imgref = ImageReferenceSig { image: "quay.io/exampleos/exampleos:latest".into(), transport: "registry".into(), signature: None, diff --git a/crates/lib/src/image.rs b/crates/lib/src/image.rs index 6cfd76109..0672ddfb6 100644 --- a/crates/lib/src/image.rs +++ b/crates/lib/src/image.rs @@ -506,7 +506,7 @@ pub(crate) async fn set_unified(sysroot: &crate::store::Storage) -> Result<()> { // Optionally verify we can import from containers-storage by preparing in a temp importer // without actually importing into the main repo; this is a lightweight validation. - let containers_storage_imgref = crate::spec::ImageReference { + let containers_storage_imgref = crate::spec::ImageReferenceSig { transport: "containers-storage".to_string(), image: imgref.image.clone(), signature: imgref.signature.clone(), diff --git a/crates/lib/src/install.rs b/crates/lib/src/install.rs index c9fcaf88c..e8e214d44 100644 --- a/crates/lib/src/install.rs +++ b/crates/lib/src/install.rs @@ -198,7 +198,7 @@ use crate::deploy::{MergeState, PreparedPullResult, prepare_for_pull, pull_from_ use crate::install::config::Filesystem as FilesystemEnum; use crate::lsm; use crate::progress_jsonl::ProgressWriter; -use crate::spec::{Bootloader, ImageReference}; +use crate::spec::{Bootloader, ImageReferenceSig}; use crate::store::Storage; use crate::task::Task; use crate::utils::sigpolicy_from_opt; @@ -1061,7 +1061,7 @@ async fn install_container( // Pull the container image into the target root filesystem. Since this is // an install path, we don't need to fsync() individual layers. - let spec_imgref = ImageReference::from(src_imageref.clone()); + let spec_imgref = ImageReferenceSig::from(src_imageref.clone()); let repo = &sysroot.repo(); repo.set_disable_fsync(true); @@ -2030,7 +2030,7 @@ async fn install_to_filesystem_impl( crate::deploy::check_disk_space_composefs( &cfs_repo, &img_manifest_config.manifest, - &crate::spec::ImageReference { + &crate::spec::ImageReferenceSig { image: imgref.name.clone(), transport: imgref.transport.to_string(), signature: None, diff --git a/crates/lib/src/spec.rs b/crates/lib/src/spec.rs index 4cc3e234e..7106f40a0 100644 --- a/crates/lib/src/spec.rs +++ b/crates/lib/src/spec.rs @@ -64,7 +64,7 @@ pub enum Store { /// The host specification pub struct HostSpec { /// The host image - pub image: Option, + pub image: Option, /// If set, and there is a rollback deployment, it will be set for the next boot. #[serde(default)] pub boot_order: BootOrder, @@ -85,7 +85,7 @@ pub enum ImageSignature { /// A container image reference with attached transport and signature verification #[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, JsonSchema)] #[serde(rename_all = "camelCase")] -pub struct ImageReference { +pub struct ImageReferenceSig { /// The container image reference pub image: String, /// The container image transport @@ -106,7 +106,7 @@ fn canonicalize_reference(reference: Reference) -> Option { Some(reference.clone_with_digest(digest.to_owned())) } -impl ImageReference { +impl ImageReferenceSig { /// Returns a canonicalized version of this image reference, preferring the digest over the tag if both are present. pub fn canonicalize(self) -> Result { // TODO maintain a proper transport enum in the spec here @@ -120,7 +120,7 @@ impl ImageReference { return Ok(self); }; - let r = ImageReference { + let r = ImageReferenceSig { image: reference.to_string(), transport: self.transport.clone(), signature: self.signature.clone(), @@ -192,7 +192,7 @@ impl ImageReference { format!("{}:{}", image_part, new_tag) }; - Ok(ImageReference { + Ok(ImageReferenceSig { image: new_image, transport: self.transport.clone(), signature: self.signature.clone(), @@ -205,7 +205,7 @@ impl ImageReference { #[serde(rename_all = "camelCase")] pub struct ImageStatus { /// The currently booted image - pub image: ImageReference, + pub image: ImageReferenceSig, /// The version string, if any pub version: Option, /// The build timestamp, if any @@ -573,7 +573,7 @@ impl BootOrder { } } -impl Display for ImageReference { +impl Display for ImageReferenceSig { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { // For the default of fetching from a remote registry, just output the image name if f.alternate() && self.signature.is_none() && self.transport == "registry" { @@ -696,7 +696,7 @@ mod tests { ]; for (initial, expected, transport) in test_cases { - let imgref = ImageReference { + let imgref = ImageReferenceSig { image: initial.to_string(), transport: transport.to_string(), signature: None, @@ -748,7 +748,7 @@ mod tests { ]; for (transport, image, expected_transport, expected_name) in cases { - let imgref = ImageReference { + let imgref = ImageReferenceSig { transport: transport.to_string(), image: image.to_string(), signature: None, @@ -767,7 +767,7 @@ mod tests { #[test] fn test_unimplemented_oci_tagged_digested() { - let imgref = ImageReference { + let imgref = ImageReferenceSig { image: "path/to/image:sometag@sha256:5db6d8b5f34d3cbdaa1e82ed0152a5ac980076d19317d4269db149cbde057bb2".to_string(), transport: "oci".to_string(), signature: None @@ -819,7 +819,7 @@ mod tests { fn test_display_imgref() { let src = "ostree-unverified-registry:quay.io/example/foo:sometag"; let s = OstreeImageReference::from_str(src).unwrap(); - let s = ImageReference::from(s); + let s = ImageReferenceSig::from(s); let displayed = format!("{s}"); assert_eq!(displayed.as_str(), src); // Alternative display should be short form @@ -827,7 +827,7 @@ mod tests { let src = "ostree-remote-image:fedora:docker://quay.io/example/foo:sometag"; let s = OstreeImageReference::from_str(src).unwrap(); - let s = ImageReference::from(s); + let s = ImageReferenceSig::from(s); let displayed = format!("{s}"); assert_eq!(displayed.as_str(), src); assert_eq!(format!("{s:#}"), src); @@ -894,7 +894,7 @@ mod tests { #[test] fn test_to_transport_image() { // Test registry transport (should return only the image name) - let registry_ref = ImageReference { + let registry_ref = ImageReferenceSig { transport: "registry".to_string(), image: "quay.io/example/foo:latest".to_string(), signature: None, @@ -905,7 +905,7 @@ mod tests { ); // Test containers-storage transport - let storage_ref = ImageReference { + let storage_ref = ImageReferenceSig { transport: "containers-storage".to_string(), image: "localhost/bootc".to_string(), signature: None, @@ -916,7 +916,7 @@ mod tests { ); // Test oci transport - let oci_ref = ImageReference { + let oci_ref = ImageReferenceSig { transport: "oci".to_string(), image: "/path/to/image".to_string(), signature: None, diff --git a/crates/lib/src/status.rs b/crates/lib/src/status.rs index c6c3e8232..012a4f286 100644 --- a/crates/lib/src/status.rs +++ b/crates/lib/src/status.rs @@ -23,7 +23,7 @@ use crate::cli::OutputFormat; use crate::spec::BootEntryComposefs; use crate::spec::ImageStatus; use crate::spec::{BootEntry, BootOrder, Host, HostSpec, HostStatus, HostType}; -use crate::spec::{ImageReference, ImageSignature}; +use crate::spec::{ImageReferenceSig, ImageSignature}; use crate::store::BootedStorage; use crate::store::BootedStorageKind; use crate::store::CachedImageStatus; @@ -63,7 +63,7 @@ fn transport_to_string(transport: ostree_container::Transport) -> String { } } -impl From for ImageReference { +impl From for ImageReferenceSig { fn from(imgref: OstreeImageReference) -> Self { let signature = match imgref.sigverify { ostree_container::SignatureSource::ContainerPolicyAllowInsecure => None, @@ -77,8 +77,8 @@ impl From for ImageReference { } } -impl From for OstreeImageReference { - fn from(img: ImageReference) -> Self { +impl From for OstreeImageReference { + fn from(img: ImageReferenceSig) -> Self { let sigverify = match img.signature { Some(v) => v.into(), None => ostree_container::SignatureSource::ContainerPolicyAllowInsecure, @@ -195,7 +195,7 @@ pub(crate) fn labels_of_config( /// Convert between a subset of ostree-ext metadata and the exposed spec API. fn create_imagestatus( - image: ImageReference, + image: ImageReferenceSig, manifest_digest: &Digest, config: &ImageConfiguration, ) -> ImageStatus { @@ -226,7 +226,7 @@ fn imagestatus( ) -> Result { let repo = &sysroot.repo(); let imgstate = ostree_container::store::query_image_commit(repo, &deployment.csum())?; - let image = ImageReference::from(image); + let image = ImageReferenceSig::from(image); let cached = imgstate .cached_update .map(|cached| create_imagestatus(image.clone(), &cached.manifest_digest, &cached.config)); @@ -1152,11 +1152,11 @@ mod tests { ) .unwrap(); - let ir = ImageReference::from(ir_unverified.clone()); + let ir = ImageReferenceSig::from(ir_unverified.clone()); assert_eq!(ir.image, "quay.io/someexample/foo:latest"); assert_eq!(ir.signature, None); - let ir = ImageReference::from(ir_ostree.clone()); + let ir = ImageReferenceSig::from(ir_ostree.clone()); assert_eq!(ir.image, "quay.io/fedora/fedora-coreos:stable"); assert_eq!( ir.signature, diff --git a/crates/ostree-ext/src/cli.rs b/crates/ostree-ext/src/cli.rs index b386c09b9..7c3f9995f 100644 --- a/crates/ostree-ext/src/cli.rs +++ b/crates/ostree-ext/src/cli.rs @@ -43,7 +43,7 @@ pub fn parse_imgref(s: &str) -> Result { /// Parse a base [`ImageReference`] from a CLI argument. pub fn parse_base_imgref(s: &str) -> Result { - ImageReference::try_from(s) + Ok(ImageReference::try_from(s)?) } /// Parse an [`ostree::Repo`] from a CLI argument. diff --git a/crates/ostree-ext/src/container/mod.rs b/crates/ostree-ext/src/container/mod.rs index 4b521690c..d7992da4d 100644 --- a/crates/ostree-ext/src/container/mod.rs +++ b/crates/ostree-ext/src/container/mod.rs @@ -187,34 +187,12 @@ pub(crate) const COMPONENT_SEPARATOR: char = ','; type Result = anyhow::Result; /// A backend/transport for OCI/Docker images. -#[derive(Copy, Clone, Hash, Debug, PartialEq, Eq)] -pub enum Transport { - /// A remote Docker/OCI registry (`registry:` or `docker://`) - Registry, - /// A local OCI directory (`oci:`) - OciDir, - /// A local OCI archive tarball (`oci-archive:`) - OciArchive, - /// A local Docker archive tarball (`docker-archive:`) - DockerArchive, - /// Local container storage (`containers-storage:`) - ContainerStorage, - /// Local directory (`dir:`) - Dir, - /// Local Docker daemon (`docker-daemon:`) - DockerDaemon, -} +pub type Transport = containers_image_proxy::transport::Transport; /// Combination of a remote image reference and transport. /// /// For example, -#[derive(Debug, Clone, Hash, PartialEq, Eq)] -pub struct ImageReference { - /// The storage and transport for the image - pub transport: Transport, - /// The image name (e.g. `quay.io/somerepo/someimage:latest`) - pub name: String, -} +pub type ImageReference = containers_image_proxy::ImageReference; /// Policy for signature verification. #[derive(Debug, Clone, PartialEq, Eq, Hash)] @@ -240,77 +218,6 @@ pub struct OstreeImageReference { pub imgref: ImageReference, } -impl TryFrom<&str> for Transport { - type Error = anyhow::Error; - - fn try_from(value: &str) -> Result { - Ok(match value { - Self::REGISTRY_STR | "docker" => Self::Registry, - Self::OCI_STR => Self::OciDir, - Self::OCI_ARCHIVE_STR => Self::OciArchive, - Self::DOCKER_ARCHIVE_STR => Self::DockerArchive, - Self::CONTAINERS_STORAGE_STR => Self::ContainerStorage, - Self::LOCAL_DIRECTORY_STR => Self::Dir, - Self::DOCKER_DAEMON_STR => Self::DockerDaemon, - o => return Err(anyhow!("Unknown transport '{}'", o)), - }) - } -} - -impl Transport { - const OCI_STR: &'static str = "oci"; - const OCI_ARCHIVE_STR: &'static str = "oci-archive"; - const DOCKER_ARCHIVE_STR: &'static str = "docker-archive"; - const CONTAINERS_STORAGE_STR: &'static str = "containers-storage"; - const LOCAL_DIRECTORY_STR: &'static str = "dir"; - const REGISTRY_STR: &'static str = "registry"; - const DOCKER_DAEMON_STR: &'static str = "docker-daemon"; - - /// Retrieve an identifier that can then be re-parsed from [`Transport::try_from::<&str>`]. - pub fn serializable_name(&self) -> &'static str { - match self { - Transport::Registry => Self::REGISTRY_STR, - Transport::OciDir => Self::OCI_STR, - Transport::OciArchive => Self::OCI_ARCHIVE_STR, - Transport::DockerArchive => Self::DOCKER_ARCHIVE_STR, - Transport::ContainerStorage => Self::CONTAINERS_STORAGE_STR, - Transport::Dir => Self::LOCAL_DIRECTORY_STR, - Transport::DockerDaemon => Self::DOCKER_DAEMON_STR, - } - } -} - -impl TryFrom<&str> for ImageReference { - type Error = anyhow::Error; - - fn try_from(value: &str) -> Result { - let (transport_name, mut name) = value - .split_once(':') - .ok_or_else(|| anyhow!("Missing ':' in {}", value))?; - let transport: Transport = transport_name.try_into()?; - if name.is_empty() { - return Err(anyhow!("Invalid empty name in {}", value)); - } - if transport_name == "docker" { - name = name - .strip_prefix("//") - .ok_or_else(|| anyhow!("Missing // in docker:// in {}", value))?; - } - Ok(Self { - transport, - name: name.to_string(), - }) - } -} - -impl FromStr for ImageReference { - type Err = anyhow::Error; - - fn from_str(s: &str) -> Result { - Self::try_from(s) - } -} - impl TryFrom<&str> for SignatureSource { type Error = anyhow::Error; @@ -388,28 +295,6 @@ impl FromStr for OstreeImageReference { } } -impl std::fmt::Display for Transport { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - let s = match self { - // TODO once skopeo supports this, canonicalize as registry: - Self::Registry => "docker://", - Self::OciArchive => "oci-archive:", - Self::DockerArchive => "docker-archive:", - Self::OciDir => "oci:", - Self::ContainerStorage => "containers-storage:", - Self::Dir => "dir:", - Self::DockerDaemon => "docker-daemon:", - }; - f.write_str(s) - } -} - -impl std::fmt::Display for ImageReference { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "{}{}", self.transport, self.name) - } -} - impl std::fmt::Display for SignatureSource { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { diff --git a/crates/ostree-ext/src/container/store.rs b/crates/ostree-ext/src/container/store.rs index ea0665d40..b1a845844 100644 --- a/crates/ostree-ext/src/container/store.rs +++ b/crates/ostree-ext/src/container/store.rs @@ -2096,11 +2096,12 @@ fn gc_image_layers_impl( let deployment_commits = list_container_deployment_manifests(repo, cancellable)?; let all_manifests = all_images .into_iter() - .map(|img| { - ImageReference::try_from(img.as_str()).and_then(|ir| manifest_for_image(repo, &ir)) + .map(|img| -> anyhow::Result<_> { + let ir = ImageReference::try_from(img.as_str())?; + manifest_for_image(repo, &ir) }) .chain(deployment_commits.into_iter().map(Ok)) - .collect::>>()?; + .collect::>>()?; tracing::debug!("Images found: {}", all_manifests.len()); let mut referenced_layers = BTreeSet::new(); for m in all_manifests.iter() { diff --git a/crates/ostree-ext/src/repair.rs b/crates/ostree-ext/src/repair.rs index b46408cba..b481f0b42 100644 --- a/crates/ostree-ext/src/repair.rs +++ b/crates/ostree-ext/src/repair.rs @@ -183,7 +183,7 @@ pub fn analyze_for_repair(sysroot: &SysrootLock, verbose: bool) -> Result Result<_> { Ok(crate::container::ImageReference::try_from(img.as_str())?) }) .collect::>>()?; println!("Verifying ostree-container images: {}", all_images.len()); let mut likely_corrupted_container_image_merges = Vec::new();