Skip to content

Commit

Permalink
Add previous container state manifest
Browse files Browse the repository at this point in the history
This commit is a prerequisite to issue #4176 in the rpm-ostree repo,
implementing the `rpm-ostree upgrade --check` feature for ostree native
containers.

A previous_state `LayeredImageState` object is added to the
`PreparedImport` object, used to store the previous container state when
importing a container image.

A `export_as_string()` function is added to the `ManifestDiff` object to
allow rpm-ostree to print the manifest diff on the client side. The code
is exactly the same as the existing `print()` function for
`ManifestDiff`, except it returns a string instead of printing out the
diff in the terminal.
  • Loading branch information
lukewarmtemp committed Jul 11, 2023
1 parent 060a3a4 commit 4bb8261
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 6 deletions.
6 changes: 5 additions & 1 deletion lib/src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use tokio::sync::mpsc::Receiver;

use crate::commit::container_commit;
use crate::container::store::{ImportProgress, LayerProgress, PreparedImport};
use crate::container::{self as ostree_container};
use crate::container::{self as ostree_container, ManifestDiff};
use crate::container::{Config, ImageReference, OstreeImageReference};
use ostree_container::store::{ImageImporter, PrepareResult};

Expand Down Expand Up @@ -613,6 +613,10 @@ async fn container_store(
if let Some(warning) = prep.deprecated_warning() {
print_deprecated_warning(warning).await;
}
if let Some(previous_state) = prep.previous_state.as_ref() {
let diff = ManifestDiff::new(&previous_state.manifest, &prep.manifest);
diff.print();
}
print_layer_status(&prep);
let printer = (!quiet).then(|| {
let layer_progress = imp.request_progress();
Expand Down
17 changes: 17 additions & 0 deletions lib/src/container/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -324,6 +324,23 @@ impl<'a> ManifestDiff<'a> {
println!("Removed layers: {n_removed:<4} Size: {removed_size_str}");
println!("Added layers: {n_added:<4} Size: {added_size_str}");
}

/// Exports the total, removed and added content between two OCI images as a string
pub fn export_as_string(&self) -> String {
fn layersum<'a, I: Iterator<Item = &'a oci_spec::image::Descriptor>>(layers: I) -> u64 {
layers.map(|layer| layer.size() as u64).sum()
}
let new_total = self.to.layers().len();
let new_total_size = glib::format_size(layersum(self.to.layers().iter()));
let n_removed = self.removed.len();
let n_added = self.added.len();
let removed_size = layersum(self.removed.iter().copied());
let removed_size_str = glib::format_size(removed_size);
let added_size = layersum(self.added.iter().copied());
let added_size_str = glib::format_size(added_size);
let result = format!("Total new layers: {new_total:<4} Size: {new_total_size}\nRemoved layers: {n_removed:<4} Size: {removed_size_str}\nAdded layers: {n_added:<4} Size: {added_size_str}");
return result
}
}

/// Apply default configuration for container image pulls to an existing configuration.
Expand Down
12 changes: 7 additions & 5 deletions lib/src/container/store.rs
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,8 @@ pub struct PreparedImport {
pub manifest: oci_image::ImageManifest,
/// The deserialized configuration.
pub config: oci_image::ImageConfiguration,
/// The previous manifest
pub previous_state: Option<Box<LayeredImageState>>,
/// The previously stored manifest digest.
pub previous_manifest_digest: Option<String>,
/// The previously stored image ID.
Expand Down Expand Up @@ -532,7 +534,7 @@ impl ImageImporter {

// Query for previous stored state

let (previous_manifest_digest, previous_imageid) =
let (previous_state, previous_imageid) =
if let Some(previous_state) = try_query_image_ref(&self.repo, &self.imgref.imgref)? {
// If the manifest digests match, we're done.
if previous_state.manifest_digest == manifest_digest {
Expand All @@ -543,10 +545,8 @@ impl ImageImporter {
if previous_imageid == new_imageid {
return Ok(PrepareResult::AlreadyPresent(previous_state));
}
(
Some(previous_state.manifest_digest),
Some(previous_imageid.to_string()),
)
let previous_imageid = previous_imageid.to_string();
(Some(previous_state), Some(previous_imageid))
} else {
(None, None)
};
Expand All @@ -567,10 +567,12 @@ impl ImageImporter {
.map(query)
.collect::<Result<Vec<_>>>()?;

let previous_manifest_digest = previous_state.as_ref().map(|s| s.manifest_digest.clone());
let imp = PreparedImport {
manifest,
manifest_digest,
config,
previous_state,
previous_manifest_digest,
previous_imageid,
ostree_layers: component_layers,
Expand Down

0 comments on commit 4bb8261

Please sign in to comment.