Skip to content

Commit

Permalink
Remove unreferenced container images in cleanup, not rebase
Browse files Browse the repository at this point in the history
This allows users to pin a deployment and have the container
image be retained.

Closes: coreos#4391
  • Loading branch information
cgwalters committed Sep 1, 2023
1 parent 600fc98 commit 2ed82ee
Show file tree
Hide file tree
Showing 6 changed files with 26 additions and 36 deletions.
10 changes: 4 additions & 6 deletions rpmostree-cxxrs.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -2063,9 +2063,8 @@ extern "C"
::rpmostreecxx::OstreeRepo const &repo, ::rpmostreecxx::GCancellable const &cancellable,
::rust::Str imgref, ::rust::Box< ::rpmostreecxx::ContainerImageState> *return$) noexcept;

::rust::repr::PtrLen rpmostreecxx$cxxbridge1$container_prune (
::rpmostreecxx::OstreeRepo const &repo,
::rpmostreecxx::GCancellable const &cancellable) noexcept;
::rust::repr::PtrLen
rpmostreecxx$cxxbridge1$container_prune (::rpmostreecxx::OstreeSysroot const &sysroot) noexcept;

::rust::repr::PtrLen rpmostreecxx$cxxbridge1$query_container_image_commit (
::rpmostreecxx::OstreeRepo const &repo, ::rust::Str c,
Expand Down Expand Up @@ -3659,10 +3658,9 @@ pull_container (::rpmostreecxx::OstreeRepo const &repo,
}

void
container_prune (::rpmostreecxx::OstreeRepo const &repo,
::rpmostreecxx::GCancellable const &cancellable)
container_prune (::rpmostreecxx::OstreeSysroot const &sysroot)
{
::rust::repr::PtrLen error$ = rpmostreecxx$cxxbridge1$container_prune (repo, cancellable);
::rust::repr::PtrLen error$ = rpmostreecxx$cxxbridge1$container_prune (sysroot);
if (error$.ptr)
{
throw ::rust::impl< ::rust::Error>::error (error$);
Expand Down
3 changes: 1 addition & 2 deletions rpmostree-cxxrs.h
Original file line number Diff line number Diff line change
Expand Up @@ -1767,8 +1767,7 @@ ::rust::Box< ::rpmostreecxx::ContainerImageState>
pull_container (::rpmostreecxx::OstreeRepo const &repo,
::rpmostreecxx::GCancellable const &cancellable, ::rust::Str imgref);

void container_prune (::rpmostreecxx::OstreeRepo const &repo,
::rpmostreecxx::GCancellable const &cancellable);
void container_prune (::rpmostreecxx::OstreeSysroot const &sysroot);

::rust::Box< ::rpmostreecxx::ContainerImageState>
query_container_image_commit (::rpmostreecxx::OstreeRepo const &repo, ::rust::Str c);
Expand Down
2 changes: 1 addition & 1 deletion rust/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,7 @@ pub mod ffi {
cancellable: &GCancellable,
imgref: &str,
) -> Result<Box<ContainerImageState>>;
fn container_prune(repo: &OstreeRepo, cancellable: &GCancellable) -> Result<()>;
fn container_prune(sysroot: &OstreeSysroot) -> Result<()>;
fn query_container_image_commit(
repo: &OstreeRepo,
c: &str,
Expand Down
37 changes: 12 additions & 25 deletions rust/src/sysroot_upgrade.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,8 @@

use crate::cxxrsutil::*;
use crate::ffi::{output_message, ContainerImageState};
use anyhow::Result;
use anyhow::{Context, Result};
use ostree::glib;
use ostree::prelude::*;
use ostree_container::store::{
ImageImporter, ImageProxyConfig, ImportProgress, ManifestLayerState, PrepareResult,
};
Expand Down Expand Up @@ -140,28 +139,16 @@ pub(crate) fn pull_container(
Ok(Box::new(r))
}

pub(crate) fn layer_prune(
repo: &ostree::Repo,
cancellable: Option<&ostree::gio::Cancellable>,
) -> Result<()> {
if let Some(c) = cancellable {
c.set_error_if_cancelled()?;
}
tracing::debug!("pruning image layers");
crate::try_fail_point!("sysroot-upgrade::layer-prune");
let n_pruned = ostree_ext::container::store::gc_image_layers(repo)?;
systemd::journal::print(6, &format!("Pruned container image layers: {n_pruned}"));
/// Run a prune of container images that are not referenced by a deployment.
pub(crate) fn container_prune(sysroot: &crate::FFIOstreeSysroot) -> CxxResult<()> {
let sysroot = &sysroot.glib_reborrow();
tracing::debug!("Pruning container images");
crate::try_fail_point!("sysroot-upgrade::container-prune");
let sysroot = &ostree_ext::sysroot::SysrootLock::from_assumed_locked(sysroot);
ostree_container::deploy::remove_undeployed_images(sysroot).context("Pruning images")?;
Ok(())
}

/// Run a prune of container image layers.
pub(crate) fn container_prune(
repo: &crate::FFIOstreeRepo,
cancellable: &crate::FFIGCancellable,
) -> CxxResult<()> {
layer_prune(&repo.glib_reborrow(), Some(&cancellable.glib_reborrow())).map_err(Into::into)
}

/// C++ wrapper for querying image state; requires a pulled image
pub(crate) fn query_container_image_commit(
repo: &crate::FFIOstreeRepo,
Expand All @@ -176,10 +163,10 @@ pub(crate) fn query_container_image_commit(
pub(crate) fn purge_refspec(repo: &crate::FFIOstreeRepo, imgref: &str) -> CxxResult<()> {
let repo = &repo.glib_reborrow();
tracing::debug!("Purging {imgref}");
if let Ok(cref) = OstreeImageReference::try_from(imgref) {
// It's a container, use the ostree-ext APIs to prune it.
ostree_container::store::remove_image(repo, &cref.imgref)?;
layer_prune(repo, None)?;
if OstreeImageReference::try_from(imgref).is_ok() {
// It's a container, so we will defer to the new model of pruning
// container images that have no deployments in cleanup.
tracing::debug!("No action needed");
} else if ostree::validate_checksum_string(imgref).is_ok() {
// Nothing to do here
} else {
Expand Down
2 changes: 1 addition & 1 deletion src/daemon/rpmostree-sysroot-core.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@ rpmostree_syscore_cleanup (OstreeSysroot *sysroot, OstreeRepo *repo, GCancellabl
/* Refs for the live state */
ROSCXX_TRY (applylive_sync_ref (*sysroot), error);

CXX_TRY (rpmostreecxx::container_prune (*repo, *cancellable), error);
CXX_TRY (rpmostreecxx::container_prune (*sysroot), error);

/* And do a prune */
guint64 freed_space;
Expand Down
8 changes: 7 additions & 1 deletion tests/kolainst/destructive/container-image
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,8 @@ EOF
fi
rpm-ostree rebase ostree-unverified-image:containers-storage:localhost/fcos-derived
ostree container image list --repo=/ostree/repo | tee imglist.txt
assert_streq "$(wc -l < imglist.txt)" 1
# We now only prune when the deployment is removed
assert_streq "$(wc -l < imglist.txt)" 2
rm $image_dir -rf
/tmp/autopkgtest-reboot 3
;;
Expand All @@ -187,6 +188,11 @@ EOF
echo -e "[Daemon]\nAutomaticUpdatePolicy=apply" > /etc/rpm-ostreed.conf
rpm-ostree reload

# This should now prune the previous image
rpm-ostree cleanup -pr
ostree container image list --repo=/ostree/repo | tee imglist.txt
assert_streq "$(wc -l < imglist.txt)" 1

# Now revert back to the base image, but keep our layered package foo
rpm-ostree rebase ostree-unverified-image:containers-storage:localhost/fcos
/tmp/autopkgtest-reboot 4
Expand Down

0 comments on commit 2ed82ee

Please sign in to comment.