Skip to content

Commit 7810219

Browse files
committed
deploy: short-circuit pull if digest pullspec already exists
If we're pulling by digest and the pullspec already exists, then there's no need to reach out to the registry or even spawn skopeo. Detect this case and exit early in the pull code. This allows RHCOS to conform better to the PinnedImageSet API[1], where the expectation is that once an image is pulled, the registry will not be contacted again. In a future with unified storage, the MCO's pre-pull would work just the same for the RHCOS image as any other. Framing this more generally: this patch allows one to pre-pull an image into the store, and making the later deployment operation be fully offline. E.g. this could be used to implement a `bootc switch --download-only` option. [1] https://github.com/openshift/enhancements/blob/26ce3cd8a0c7ce650e73bc5393a3605022cb6847/enhancements/machine-config/pin-and-pre-load-images.md
1 parent ba65dd2 commit 7810219

File tree

1 file changed

+16
-0
lines changed

1 file changed

+16
-0
lines changed

lib/src/deploy.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
55
use std::collections::HashSet;
66
use std::io::{BufRead, Write};
7+
use std::str::FromStr;
78

89
use anyhow::Ok;
910
use anyhow::{anyhow, Context, Result};
@@ -15,6 +16,7 @@ use ostree::{gio, glib};
1516
use ostree_container::OstreeImageReference;
1617
use ostree_ext::container as ostree_container;
1718
use ostree_ext::container::store::{ImageImporter, ImportProgress, PrepareResult, PreparedImport};
19+
use ostree_ext::oci_spec::distribution::Reference as OciReference;
1820
use ostree_ext::oci_spec::image::{Descriptor, Digest};
1921
use ostree_ext::ostree::Deployment;
2022
use ostree_ext::ostree::{self, Sysroot};
@@ -343,6 +345,20 @@ pub(crate) async fn prepare_for_pull(
343345
let imgref_canonicalized = imgref.clone().canonicalize()?;
344346
tracing::debug!("Canonicalized image reference: {imgref_canonicalized:#}");
345347
let ostree_imgref = &OstreeImageReference::from(imgref_canonicalized);
348+
349+
let maybe_oci_ref = ostree_imgref.imgref.name.parse::<OciReference>().ok();
350+
if let Some(digest) = maybe_oci_ref.as_ref().and_then(|oci_ref| oci_ref.digest()) {
351+
// This is a digested pull. If that digested image already exists in
352+
// the store, we can short-circuit a lot here and e.g. not spawn skopeo
353+
// at all.
354+
if let Some(c) = ostree_container::store::query_image(repo, &ostree_imgref.imgref)? {
355+
let digest = Digest::from_str(digest)?;
356+
assert_eq!(digest, c.manifest_digest);
357+
println!("Digest-based pullspec {imgref:#} already present");
358+
return Ok(PreparedPullResult::AlreadyPresent(Box::new((*c).into())));
359+
}
360+
}
361+
346362
let mut imp = new_importer(repo, ostree_imgref).await?;
347363
if let Some(target) = target_imgref {
348364
imp.set_target(target);

0 commit comments

Comments
 (0)