Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ostree-ext: Add image clear-cached-update #1071

Merged
merged 1 commit into from
Feb 3, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions ostree-ext/src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,17 @@ pub(crate) enum ContainerImageOpts {
config: bool,
},

/// Remove metadata for a cached update.
ClearCachedUpdate {
/// Path to the repository
#[clap(long, value_parser)]
repo: Utf8PathBuf,

/// Container image reference, e.g. registry:quay.io/exampleos/exampleos:latest
#[clap(value_parser = parse_base_imgref)]
imgref: ImageReference,
},

/// Copy a pulled container image from one repo to another.
Copy {
/// Path to the source repository
Expand Down Expand Up @@ -1132,6 +1143,11 @@ async fn run_from_opt(opt: Opt) -> Result<()> {
stdout.flush()?;
Ok(())
}
ContainerImageOpts::ClearCachedUpdate { repo, imgref } => {
let repo = parse_repo(&repo)?;
crate::container::store::clear_cached_update(&repo, &imgref)?;
Ok(())
}
ContainerImageOpts::Remove {
repo,
imgrefs,
Expand Down
34 changes: 33 additions & 1 deletion ostree-ext/src/container/store.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,10 @@ use futures_util::TryFutureExt;
use oci_spec::image::{
self as oci_image, Arch, Descriptor, Digest, History, ImageConfiguration, ImageManifest,
};
use ostree::glib::FromVariant;
use ostree::prelude::{Cast, FileEnumeratorExt, FileExt, ToVariant};
use ostree::{gio, glib};
use std::collections::{BTreeSet, HashMap};
use std::collections::{BTreeMap, BTreeSet, HashMap};
use std::iter::FromIterator;
use tokio::sync::mpsc::{Receiver, Sender};

Expand Down Expand Up @@ -1196,6 +1197,37 @@ fn parse_cached_update(meta: &glib::VariantDict) -> Result<Option<CachedImageUpd
}))
}

/// Remove any cached
#[context("Clearing cached update {imgref}")]
pub fn clear_cached_update(repo: &ostree::Repo, imgref: &ImageReference) -> Result<()> {
let cancellable = gio::Cancellable::NONE;
let ostree_ref = ref_for_image(imgref)?;
let rev = repo.require_rev(&ostree_ref)?;
let Some(commitmeta) = repo.read_commit_detached_metadata(&rev, cancellable)? else {
return Ok(());
};

// SAFETY: We know this is an a{sv}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have no idea what a{sv} means here, not a blocker but please enlighten me 😃

Copy link
Collaborator Author

@cgwalters cgwalters Feb 3, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

gvariant is a bit like a binary JSON, although also with a richer type system (e.g. 32 and 64 bit signed/unsigned integers, not just "number" etc.).

See https://docs.gtk.org/glib/gvariant-format-strings.html - specifically a{sv} is a lot like a default json dictionary (string keys, heterogeneous values).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks for the lesson 🎓

let mut commitmeta: BTreeMap<String, glib::Variant> =
BTreeMap::from_variant(&commitmeta).unwrap();
let mut changed = false;
for key in [
ImageImporter::CACHED_KEY_CONFIG,
ImageImporter::CACHED_KEY_MANIFEST,
ImageImporter::CACHED_KEY_MANIFEST_DIGEST,
] {
if commitmeta.remove(key).is_some() {
changed = true;
}
}
if !changed {
return Ok(());
}
let commitmeta = glib::Variant::from(commitmeta);
repo.write_commit_detached_metadata(&rev, Some(&commitmeta), cancellable)?;
Ok(())
}

/// Query metadata for a pulled image via an OSTree commit digest.
/// The digest must refer to a pulled container image's merge commit.
pub fn query_image_commit(repo: &ostree::Repo, commit: &str) -> Result<Box<LayeredImageState>> {
Expand Down