Skip to content

Commit

Permalink
Add container upgrade --check function
Browse files Browse the repository at this point in the history
Previously, OS based on native containers could not retrieve the
manifest difference between the current system container image and its
corresponding remote container image without performing an actual
upgrade. This PR solves this issue by allowing the manifest difference
to be outputted when using the `rpm-ostree upgrade --check` command.

A `ManifestDiff` struct needed to be retrieved using `ostree-rs-ext`,
requring several new functions in both Rust and C that were bridged
through CXX Bridge.

The `cached_update` object also needed to be modifed and updated with
the `ManifestDiff` in order to extend compatibility with other products
using rpm-ostree. However, a notable difference between how the
`--upgrade --check` function works for ostree based system and a native
container based system is that native containers skip over the use of
`checksums`. This is because rebasing to locally stored container images
(as opposed to a remote repository) does not create a valid ostree
refspec.

A Rust unit test was implemented to confirm that a difference between
two manifests (stored locally in the rust/test folder) can be
successfully retrieved. A `kola` test was also implemented to confirm
that running `rpm-ostree upgrade --check` returns the correct manifest
difference for a potential upgrade.
  • Loading branch information
lukewarmtemp committed Aug 9, 2023
1 parent 6bca8f4 commit 4c1675c
Show file tree
Hide file tree
Showing 11 changed files with 479 additions and 18 deletions.
62 changes: 62 additions & 0 deletions rpmostree-cxxrs.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -1293,6 +1293,7 @@ enum class SystemHostType : ::std::uint8_t;
enum class BubblewrapMutability : ::std::uint8_t;
struct Bubblewrap;
struct ContainerImageState;
struct ExportedManifestDiff;
enum class RefspecType : ::std::uint8_t;
struct TempEtcGuard;
struct FilesystemScriptPrep;
Expand Down Expand Up @@ -1413,6 +1414,22 @@ struct ContainerImageState final
};
#endif // CXXBRIDGE1_STRUCT_rpmostreecxx$ContainerImageState

#ifndef CXXBRIDGE1_STRUCT_rpmostreecxx$ExportedManifestDiff
#define CXXBRIDGE1_STRUCT_rpmostreecxx$ExportedManifestDiff
struct ExportedManifestDiff final
{
bool initialized;
::rust::u64 total;
::rust::u64 total_size;
::rust::u64 n_removed;
::rust::u64 removed_size;
::rust::u64 n_added;
::rust::u64 added_size;

using IsRelocatable = ::std::true_type;
};
#endif // CXXBRIDGE1_STRUCT_rpmostreecxx$ExportedManifestDiff

#ifndef CXXBRIDGE1_ENUM_rpmostreecxx$RefspecType
#define CXXBRIDGE1_ENUM_rpmostreecxx$RefspecType
enum class RefspecType : ::std::uint8_t
Expand Down Expand Up @@ -2064,6 +2081,10 @@ extern "C"
const ::rpmostreecxx::OstreeRepo &repo,
const ::rpmostreecxx::GCancellable &cancellable) noexcept;

::rust::repr::PtrLen rpmostreecxx$cxxbridge1$compare_local_to_remote_container (
const ::rpmostreecxx::OstreeRepo &repo, const ::rpmostreecxx::GCancellable &cancellable,
::rust::Str imgref, ::rust::Box< ::rpmostreecxx::ExportedManifestDiff> *return$) noexcept;

::rust::repr::PtrLen rpmostreecxx$cxxbridge1$query_container_image_commit (
const ::rpmostreecxx::OstreeRepo &repo, ::rust::Str c,
::rust::Box< ::rpmostreecxx::ContainerImageState> *return$) noexcept;
Expand Down Expand Up @@ -3656,6 +3677,21 @@ container_prune (const ::rpmostreecxx::OstreeRepo &repo,
}
}

::rust::Box< ::rpmostreecxx::ExportedManifestDiff>
compare_local_to_remote_container (const ::rpmostreecxx::OstreeRepo &repo,
const ::rpmostreecxx::GCancellable &cancellable,
::rust::Str imgref)
{
::rust::MaybeUninit< ::rust::Box< ::rpmostreecxx::ExportedManifestDiff> > return$;
::rust::repr::PtrLen error$ = rpmostreecxx$cxxbridge1$compare_local_to_remote_container (
repo, cancellable, imgref, &return$.value);
if (error$.ptr)
{
throw ::rust::impl< ::rust::Error>::error (error$);
}
return ::std::move (return$.value);
}

::rust::Box< ::rpmostreecxx::ContainerImageState>
query_container_image_commit (const ::rpmostreecxx::OstreeRepo &repo, ::rust::Str c)
{
Expand Down Expand Up @@ -5995,6 +6031,13 @@ extern "C"
void cxxbridge1$box$rpmostreecxx$ContainerImageState$drop (
::rust::Box< ::rpmostreecxx::ContainerImageState> *ptr) noexcept;

::rpmostreecxx::ExportedManifestDiff *
cxxbridge1$box$rpmostreecxx$ExportedManifestDiff$alloc () noexcept;
void cxxbridge1$box$rpmostreecxx$ExportedManifestDiff$dealloc (
::rpmostreecxx::ExportedManifestDiff *) noexcept;
void cxxbridge1$box$rpmostreecxx$ExportedManifestDiff$drop (
::rust::Box< ::rpmostreecxx::ExportedManifestDiff> *ptr) noexcept;

::rpmostreecxx::TempEtcGuard *cxxbridge1$box$rpmostreecxx$TempEtcGuard$alloc () noexcept;
void cxxbridge1$box$rpmostreecxx$TempEtcGuard$dealloc (::rpmostreecxx::TempEtcGuard *) noexcept;
void cxxbridge1$box$rpmostreecxx$TempEtcGuard$drop (
Expand Down Expand Up @@ -6335,6 +6378,25 @@ Box< ::rpmostreecxx::ContainerImageState>::drop () noexcept
cxxbridge1$box$rpmostreecxx$ContainerImageState$drop (this);
}
template <>
::rpmostreecxx::ExportedManifestDiff *
Box< ::rpmostreecxx::ExportedManifestDiff>::allocation::alloc () noexcept
{
return cxxbridge1$box$rpmostreecxx$ExportedManifestDiff$alloc ();
}
template <>
void
Box< ::rpmostreecxx::ExportedManifestDiff>::allocation::dealloc (
::rpmostreecxx::ExportedManifestDiff *ptr) noexcept
{
cxxbridge1$box$rpmostreecxx$ExportedManifestDiff$dealloc (ptr);
}
template <>
void
Box< ::rpmostreecxx::ExportedManifestDiff>::drop () noexcept
{
cxxbridge1$box$rpmostreecxx$ExportedManifestDiff$drop (this);
}
template <>
::rpmostreecxx::TempEtcGuard *
Box< ::rpmostreecxx::TempEtcGuard>::allocation::alloc () noexcept
{
Expand Down
22 changes: 22 additions & 0 deletions rpmostree-cxxrs.h
Original file line number Diff line number Diff line change
Expand Up @@ -1075,6 +1075,7 @@ enum class SystemHostType : ::std::uint8_t;
enum class BubblewrapMutability : ::std::uint8_t;
struct Bubblewrap;
struct ContainerImageState;
struct ExportedManifestDiff;
enum class RefspecType : ::std::uint8_t;
struct TempEtcGuard;
struct FilesystemScriptPrep;
Expand Down Expand Up @@ -1195,6 +1196,22 @@ struct ContainerImageState final
};
#endif // CXXBRIDGE1_STRUCT_rpmostreecxx$ContainerImageState

#ifndef CXXBRIDGE1_STRUCT_rpmostreecxx$ExportedManifestDiff
#define CXXBRIDGE1_STRUCT_rpmostreecxx$ExportedManifestDiff
struct ExportedManifestDiff final
{
bool initialized;
::rust::u64 total;
::rust::u64 total_size;
::rust::u64 n_removed;
::rust::u64 removed_size;
::rust::u64 n_added;
::rust::u64 added_size;

using IsRelocatable = ::std::true_type;
};
#endif // CXXBRIDGE1_STRUCT_rpmostreecxx$ExportedManifestDiff

#ifndef CXXBRIDGE1_ENUM_rpmostreecxx$RefspecType
#define CXXBRIDGE1_ENUM_rpmostreecxx$RefspecType
enum class RefspecType : ::std::uint8_t
Expand Down Expand Up @@ -1768,6 +1785,11 @@ pull_container (const ::rpmostreecxx::OstreeRepo &repo,
void container_prune (const ::rpmostreecxx::OstreeRepo &repo,
const ::rpmostreecxx::GCancellable &cancellable);

::rust::Box< ::rpmostreecxx::ExportedManifestDiff>
compare_local_to_remote_container (const ::rpmostreecxx::OstreeRepo &repo,
const ::rpmostreecxx::GCancellable &cancellable,
::rust::Str imgref);

::rust::Box< ::rpmostreecxx::ContainerImageState>
query_container_image_commit (const ::rpmostreecxx::OstreeRepo &repo, ::rust::Str c);

Expand Down
23 changes: 23 additions & 0 deletions rust/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,24 @@ pub mod ffi {
pub version: String,
}

#[derive(Debug, Default)]
pub(crate) struct ExportedManifestDiff {
/// Check if the struct is initialized
pub initialized: bool,
/// The total number of packages in the next upgrade
pub total: u64,
/// The size of the total number of packages in the next upgrade
pub total_size: u64,
/// The total number of removed packages in the next upgrade
pub n_removed: u64,
/// The size of total number of removed packages in the next upgrade
pub removed_size: u64,
/// The total number of added packages in the next upgrade
pub n_added: u64,
/// The size of total number of added packages in the next upgrade
pub added_size: u64,
}

// sysroot_upgrade.rs
extern "Rust" {
fn pull_container(
Expand All @@ -201,6 +219,11 @@ pub mod ffi {
c: &str,
) -> Result<Box<ContainerImageState>>;
fn purge_refspec(repo: &OstreeRepo, refspec: &str) -> Result<()>;
fn compare_local_to_remote_container(
repo: &OstreeRepo,
cancellable: &GCancellable,
imgref: &str,
) -> Result<Box<ExportedManifestDiff>>;
}

// core.rs
Expand Down
72 changes: 72 additions & 0 deletions rust/src/sysroot_upgrade.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
// SPDX-License-Identifier: Apache-2.0 OR MIT

use crate::cxxrsutil::*;
use crate::ffi::ExportedManifestDiff;
use crate::ffi::{output_message, ContainerImageState};
use anyhow::Result;
use ostree::glib;
Expand Down Expand Up @@ -199,3 +200,74 @@ pub(crate) fn purge_refspec(repo: &crate::FFIOstreeRepo, imgref: &str) -> CxxRes
}
Ok(())
}

pub(crate) fn compare_local_to_remote_container(
repo: &crate::FFIOstreeRepo,
cancellable: &crate::FFIGCancellable,
imgref: &str,
) -> CxxResult<Box<ExportedManifestDiff>> {
let repo = &repo.glib_reborrow();
let cancellable = cancellable.glib_reborrow();
let imgref = &OstreeImageReference::try_from(imgref)?;
let r = Handle::current().block_on(async {
crate::utils::run_with_cancellable(
async { get_container_manifest_diff(repo, imgref).await },
&cancellable,
)
.await
})?;
Ok(Box::new(r))
}

pub async fn get_container_manifest_diff(
repo: &ostree::Repo,
imgref: &OstreeImageReference,
) -> Result<ExportedManifestDiff> {
use ostree_ext::container::ManifestDiff;
let previous_state =
if let Some(r) = ostree_ext::container::store::query_image_ref(&repo, &imgref.imgref)? {
r
} else {
return Ok(ExportedManifestDiff::default());
};

let (manifest, _) = ostree_ext::container::fetch_manifest(&imgref).await?;
let diff = ManifestDiff::new(&previous_state.manifest, &manifest);

let manifest_diff = ExportedManifestDiff {
initialized: true,
total: diff.total,
total_size: diff.total_size,
n_removed: diff.n_removed,
removed_size: diff.removed_size,
n_added: diff.n_added,
added_size: diff.added_size,
};

Ok(manifest_diff)
}

#[test]
fn test_container_manifest_diff() -> Result<()> {
use ostree_ext::container::ManifestDiff;
use ostree_ext::oci_spec::image::ImageManifest;
let a: ImageManifest = serde_json::from_str(include_str!("../test/manifest1.json")).unwrap();
let b: ImageManifest = serde_json::from_str(include_str!("../test/manifest2.json")).unwrap();
let diff = ManifestDiff::new(&a, &b);

let cmp_total = diff.total;
let cmp_total_size = diff.total_size;
let cmp_removed = diff.n_removed;
let cmp_removed_size = diff.removed_size;
let cmp_added = diff.n_added;
let cmp_added_size = diff.added_size;

assert_eq!(cmp_total, 51 as u64);
assert_eq!(cmp_total_size, 697035490 as u64);
assert_eq!(cmp_removed, 4 as u64);
assert_eq!(cmp_removed_size, 170473141 as u64);
assert_eq!(cmp_added, 4 as u64);
assert_eq!(cmp_added_size, 170472856 as u64);

Ok(())
}
1 change: 1 addition & 0 deletions rust/test/manifest1.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"schemaVersion":2,"config":{"mediaType":"application/vnd.oci.image.config.v1+json","digest":"sha256:f3b50d0849a19894aa27ca2346a78efdacf2c56bdc2a3493672d2a819990fedf","size":9301},"layers":[{"mediaType":"application/vnd.oci.image.layer.v1.tar+gzip","digest":"sha256:75f4abe8518ec55cb8bf0d358a737084f38e2c030a28651d698c0b7569d680a6","size":1387849},{"mediaType":"application/vnd.oci.image.layer.v1.tar+gzip","digest":"sha256:777cb841d2803f775a36fba62bcbfe84b2a1e0abc27cf995961b63c3d218a410","size":48676116},{"mediaType":"application/vnd.oci.image.layer.v1.tar+gzip","digest":"sha256:1179dc1e2994ec0466787ec43967db9016b4b93c602bb9675d7fe4c0993366ba","size":124705297},{"mediaType":"application/vnd.oci.image.layer.v1.tar+gzip","digest":"sha256:74555b3730c4c0f77529ead433db58e038070666b93a5cc0da262d7b8debff0e","size":38743650},{"mediaType":"application/vnd.oci.image.layer.v1.tar+gzip","digest":"sha256:0ff8b1fdd38e5cfb6390024de23ba4b947cd872055f62e70f2c21dad5c928925","size":77161948},{"mediaType":"application/vnd.oci.image.layer.v1.tar+gzip","digest":"sha256:76b83eea62b7b93200a056b5e0201ef486c67f1eeebcf2c7678ced4d614cece2","size":21970157},{"mediaType":"application/vnd.oci.image.layer.v1.tar+gzip","digest":"sha256:d85c742f69904cb8dbf98abca4724d364d91792fcf8b5f5634ab36dda162bfc4","size":59797135},{"mediaType":"application/vnd.oci.image.layer.v1.tar+gzip","digest":"sha256:167e5df36d0fcbed876ca90c1ed1e6c79b5e2bdaba5eae74ab86444654b19eff","size":49410348},{"mediaType":"application/vnd.oci.image.layer.v1.tar+gzip","digest":"sha256:b34384ba76fa1e335cc8d75522508d977854f2b423f8aceb50ca6dfc2f609a99","size":21714783},{"mediaType":"application/vnd.oci.image.layer.v1.tar+gzip","digest":"sha256:7bf2d65ebf222ee10115284abf6909b1a3da0f3bd6d8d849e30723636b7145cb","size":15264848},{"mediaType":"application/vnd.oci.image.layer.v1.tar+gzip","digest":"sha256:a75bbf55d8de4dbd54e429e16fbd46688717faf4ea823c94676529cc2525fd5f","size":14373701},{"mediaType":"application/vnd.oci.image.layer.v1.tar+gzip","digest":"sha256:cf728677fa8c84bfcfd71e17953062421538d492d7fbfdd0dbce8eb1e5f6eec3","size":8400473},{"mediaType":"application/vnd.oci.image.layer.v1.tar+gzip","digest":"sha256:caff60c1ef085fb500c94230ccab9338e531578635070230b1413b439fd53f8f","size":6914489},{"mediaType":"application/vnd.oci.image.layer.v1.tar+gzip","digest":"sha256:65ca8f9bddaa720b74c5a7401bf273e93eba6b3b855a62422a8258373e0b1ae0","size":8294965},{"mediaType":"application/vnd.oci.image.layer.v1.tar+gzip","digest":"sha256:387bab4fcb713e9691617a645b6af2b7ad29fe5e009b0b0d3215645ef315481c","size":6600369},{"mediaType":"application/vnd.oci.image.layer.v1.tar+gzip","digest":"sha256:f63dcde5a664dad3eb3321bbcf2913d9644d16561a67c86ab61d814c1462583d","size":16869027},{"mediaType":"application/vnd.oci.image.layer.v1.tar+gzip","digest":"sha256:8bcd90242651342fbd2ed5ca3e60d03de90fdd28c3a9f634329f6e1c21c79718","size":5735283},{"mediaType":"application/vnd.oci.image.layer.v1.tar+gzip","digest":"sha256:cb65c21a0659b5b826881280556995a7ca4818c2b9b7a89e31d816a996fa8640","size":4528663},{"mediaType":"application/vnd.oci.image.layer.v1.tar+gzip","digest":"sha256:5187f51b62f4a2e82198a75afcc623a0323d4804fa7848e2e0acb30d77b8d9ab","size":5266030},{"mediaType":"application/vnd.oci.image.layer.v1.tar+gzip","digest":"sha256:bfef79d6d35378fba9093083ff6bd7b5ed9f443f87517785e6ff134dc8d08c6a","size":4316135},{"mediaType":"application/vnd.oci.image.layer.v1.tar+gzip","digest":"sha256:1cf332fd50b382af7941d6416994f270c894e9d60fb5c6cecf25de887673bbcb","size":3914655},{"mediaType":"application/vnd.oci.image.layer.v1.tar+gzip","digest":"sha256:e0d80be6e71bfae398f06f7a7e3b224290f3dde7544c8413f922934abeb1f599","size":2441858},{"mediaType":"application/vnd.oci.image.layer.v1.tar+gzip","digest":"sha256:48ff87e7a7af41d7139c5230e2e939aa97cafb1f62a114825bda5f5904e04a0e","size":3818782},{"mediaType":"application/vnd.oci.image.layer.v1.tar+gzip","digest":"sha256:8bcc652ccaa27638bd5bd2d7188053f1736586afbae87b3952e9211c773e3563","size":3885971},{"mediaType":"application/vnd.oci.image.layer.v1.tar+gzip","digest":"sha256:d83d9388b8c8c1e7c97b6b18f5107b74354700ebce9da161ccb73156a2c54a2e","size":3442642},{"mediaType":"application/vnd.oci.image.layer.v1.tar+gzip","digest":"sha256:efc465ae44a18ee395e542eb97c8d1fc21bf9d5fb49244ba4738e9bf48bfd3dc","size":3066348},{"mediaType":"application/vnd.oci.image.layer.v1.tar+gzip","digest":"sha256:c5c471cce08aa9cc7d96884a9e1981b7bb67ee43524af47533f50a8ddde7a83d","size":909923},{"mediaType":"application/vnd.oci.image.layer.v1.tar+gzip","digest":"sha256:8956cd951abc481ba364cf8ef5deca7cc9185b59ed95ae40b52e42afdc271d8e","size":3553645},{"mediaType":"application/vnd.oci.image.layer.v1.tar+gzip","digest":"sha256:5b0963a6c89d595b5c4786e2f3ce0bc168a262efab74dfce3d7c8d1063482c60","size":1495301},{"mediaType":"application/vnd.oci.image.layer.v1.tar+gzip","digest":"sha256:bf2df295da2716291f9dd4707158bca218b4a7920965955a4808b824c1bee2b6","size":3063142},{"mediaType":"application/vnd.oci.image.layer.v1.tar+gzip","digest":"sha256:19b2ea8d63794b8249960d581216ae1ccb80f8cfe518ff8dd1f12d65d19527a5","size":8109718},{"mediaType":"application/vnd.oci.image.layer.v1.tar+gzip","digest":"sha256:420636df561ccc835ef9665f41d4bc91c5f00614a61dca266af2bcd7bee2cc25","size":3003935},{"mediaType":"application/vnd.oci.image.layer.v1.tar+gzip","digest":"sha256:5ae67caf0978d82848d47ff932eee83a1e5d2581382c9c47335f69c9d7acc180","size":2468557},{"mediaType":"application/vnd.oci.image.layer.v1.tar+gzip","digest":"sha256:4f4b8bb8463dc74bb7f32eee78d02b71f61a322967b6d6cbb29829d262376f74","size":2427605},{"mediaType":"application/vnd.oci.image.layer.v1.tar+gzip","digest":"sha256:69373f86b83e6e5a962de07f40ff780a031b42d2568ffbb8b3c36de42cc90dec","size":2991782},{"mediaType":"application/vnd.oci.image.layer.v1.tar+gzip","digest":"sha256:2d05c2f993f9761946701da37f45fc573a2db8467f92b3f0d356f5f7adaf229e","size":3085765},{"mediaType":"application/vnd.oci.image.layer.v1.tar+gzip","digest":"sha256:41925843e5c965165bedc9c8124b96038f08a89c95ba94603a5f782dc813f0a8","size":2724309},{"mediaType":"application/vnd.oci.image.layer.v1.tar+gzip","digest":"sha256:a8c39f2998073e0e8b55fb88ccd68d2621a0fb6e31a528fd4790a1c90f8508a9","size":2512079},{"mediaType":"application/vnd.oci.image.layer.v1.tar+gzip","digest":"sha256:b905f801d092faba0c155597dd1303fa8c0540116af59c111ed7744e486ed63b","size":2341122},{"mediaType":"application/vnd.oci.image.layer.v1.tar+gzip","digest":"sha256:4f46b58b37828fa71fa5d7417a8ca7a62761cc6a72eb1592943572fc2446b054","size":2759344},{"mediaType":"application/vnd.oci.image.layer.v1.tar+gzip","digest":"sha256:3fbae92ecc64cf253b643a0e75b56514dc694451f163b47fb4e15af373238e10","size":2539288},{"mediaType":"application/vnd.oci.image.layer.v1.tar+gzip","digest":"sha256:744dd4a3ec521668942661cf1f184eb8f07f44025ce1aa35d5072ad9d72946fe","size":2415870},{"mediaType":"application/vnd.oci.image.layer.v1.tar+gzip","digest":"sha256:6c74c0a05a36bddabef1fdfae365ff87a9c5dd1ec7345d9e20f7f8ab04b39fc6","size":2145078},{"mediaType":"application/vnd.oci.image.layer.v1.tar+gzip","digest":"sha256:910ff6f93303ebedde3459f599b06d7b70d8f0674e3fe1d6623e3af809245cc4","size":5098511},{"mediaType":"application/vnd.oci.image.layer.v1.tar+gzip","digest":"sha256:2752e2f62f38fea3a390f111d673d2529dbf929f6c67ec7ef4359731d1a7edd8","size":1051999},{"mediaType":"application/vnd.oci.image.layer.v1.tar+gzip","digest":"sha256:5065c3aac5fcc3c1bde50a19d776974353301f269a936dd2933a67711af3b703","size":2713694},{"mediaType":"application/vnd.oci.image.layer.v1.tar+gzip","digest":"sha256:8bf6993eea50bbd8b448e6fd719f83c82d1d40b623f2c415f7727e766587ea83","size":1686714},{"mediaType":"application/vnd.oci.image.layer.v1.tar+gzip","digest":"sha256:630221744f0f9632f4f34f74241e65f79e78f938100266a119113af1ce10a1c5","size":2061581},{"mediaType":"application/vnd.oci.image.layer.v1.tar+gzip","digest":"sha256:e7e2eae322bca0ffa01bb2cae72288507bef1a11ad51f99d0a4faba1b1e000b9","size":2079706},{"mediaType":"application/vnd.oci.image.layer.v1.tar+gzip","digest":"sha256:bb6374635385b0c2539c284b137d831bd45fbe64b5e49aee8ad92d14c156a41b","size":3142398},{"mediaType":"application/vnd.oci.image.layer.v1.tar+gzip","digest":"sha256:40493ecd0f9ab499a2bec715415c3a98774ea6d1c9c01eb30a6b56793204a02d","size":69953187}]}
Loading

0 comments on commit 4c1675c

Please sign in to comment.