Skip to content
This repository has been archived by the owner on Nov 7, 2024. It is now read-only.

Commit

Permalink
Merge pull request #401 from cgwalters/gc-image-layers-default
Browse files Browse the repository at this point in the history
container: Prune image layers by default
  • Loading branch information
jmarrero authored Nov 10, 2022
2 parents aabd86b + 97d8d3d commit c0359aa
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 5 deletions.
42 changes: 39 additions & 3 deletions lib/src/container/store.rs
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,8 @@ pub struct ImageImporter {
pub(crate) proxy: ImageProxy,
imgref: OstreeImageReference,
target_imgref: Option<OstreeImageReference>,
no_imgref: bool, // If true, do not write final image ref
no_imgref: bool, // If true, do not write final image ref
disable_gc: bool, // If true, don't prune unused image layers
pub(crate) proxy_img: OpenedImage,

layer_progress: Option<Sender<ImportProgress>>,
Expand Down Expand Up @@ -447,6 +448,7 @@ impl ImageImporter {
proxy_img,
target_imgref: None,
no_imgref: false,
disable_gc: false,
imgref: imgref.clone(),
layer_progress: None,
layer_byte_progress: None,
Expand All @@ -465,6 +467,11 @@ impl ImageImporter {
self.no_imgref = true;
}

/// Do not prune image layers.
pub fn disable_gc(&mut self) {
self.disable_gc = true;
}

/// Determine if there is a new manifest, and if so return its digest.
#[context("Preparing import")]
pub async fn prepare(&mut self) -> Result<PrepareResult> {
Expand Down Expand Up @@ -691,7 +698,9 @@ impl ImageImporter {
})
}

/// Import a layered container image
/// Import a layered container image.
///
/// If enabled, this will also prune unused container image layers.
#[context("Importing")]
pub async fn import(
mut self,
Expand Down Expand Up @@ -847,6 +856,12 @@ impl ImageImporter {
repo.transaction_set_ref(None, &ostree_ref, Some(merged_commit.as_str()));
}
txn.commit(cancellable)?;

if !self.disable_gc {
let n: u32 = gc_image_layers_impl(repo, cancellable)?;
tracing::debug!("pruned {n} layers");
}

// Here we re-query state just to run through the same code path,
// though it'd be cheaper to synthesize it from the data we already have.
let state = query_image(repo, &imgref)?.unwrap();
Expand Down Expand Up @@ -970,7 +985,14 @@ pub async fn copy(
/// The underlying objects are *not* pruned; that requires a separate invocation
/// of [`ostree::Repo::prune`].
pub fn gc_image_layers(repo: &ostree::Repo) -> Result<u32> {
let cancellable = gio::NONE_CANCELLABLE;
gc_image_layers_impl(repo, gio::NONE_CANCELLABLE)
}

#[context("Pruning image layers")]
fn gc_image_layers_impl(
repo: &ostree::Repo,
cancellable: Option<&gio::Cancellable>,
) -> Result<u32> {
let all_images = list_images(repo)?;
let all_manifests = all_images
.into_iter()
Expand Down Expand Up @@ -1005,6 +1027,20 @@ pub fn gc_image_layers(repo: &ostree::Repo) -> Result<u32> {
Ok(pruned)
}

#[cfg(feature = "internal-testing-api")]
/// Return how many container blobs (layers) are stored
pub fn count_layer_references(repo: &ostree::Repo) -> Result<u32> {
let cancellable = gio::NONE_CANCELLABLE;
let n = repo
.list_refs_ext(
Some(LAYER_PREFIX),
ostree::RepoListRefsExtFlags::empty(),
cancellable,
)?
.len();
Ok(n as u32)
}

#[context("Pruning {}", image)]
fn prune_image(repo: &ostree::Repo, image: &ImageReference) -> Result<()> {
let ostree_ref = &ref_for_image(image)?;
Expand Down
9 changes: 7 additions & 2 deletions lib/tests/it/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -800,12 +800,14 @@ r usr/bin/bash bash-v0
}
}

assert_eq!(store::list_images(fixture.destrepo()).unwrap().len(), 1);
let n = store::count_layer_references(fixture.destrepo())? as i64;
let _import = imp.import(prep).await.unwrap();

assert_eq!(store::list_images(fixture.destrepo()).unwrap().len(), 1);

let n_removed = store::gc_image_layers(fixture.destrepo())?;
assert_eq!(n_removed, 2);
let n2 = store::count_layer_references(fixture.destrepo())? as i64;
assert_eq!(n, n2);
fixture
.destrepo()
.prune(ostree::RepoPruneFlags::REFS_ONLY, 0, gio::NONE_CANCELLABLE)?;
Expand Down Expand Up @@ -846,6 +848,8 @@ r usr/bin/bash bash-v0
assert!(prep.ostree_commit_layer.commit.is_some());
assert_eq!(prep.ostree_layers.len(), nlayers as usize);

// We want to test explicit layer pruning
imp.disable_gc();
let _import = imp.import(prep).await.unwrap();
assert_eq!(store::list_images(fixture.destrepo()).unwrap().len(), 2);

Expand All @@ -869,6 +873,7 @@ r usr/bin/bash bash-v0
assert_eq!(n_removed, (*CONTENTS_V0_LEN + 1) as u32);

// Repo should be clean now
assert_eq!(store::count_layer_references(fixture.destrepo())?, 0);
assert_eq!(
fixture
.destrepo()
Expand Down

0 comments on commit c0359aa

Please sign in to comment.