Skip to content

Commit

Permalink
deploy: Pass around subset of ostree-container image state
Browse files Browse the repository at this point in the history
Prep for a podman backend.

Signed-off-by: Colin Walters <[email protected]>
  • Loading branch information
cgwalters committed Dec 3, 2023
1 parent 6956054 commit fde6bdd
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 15 deletions.
7 changes: 5 additions & 2 deletions lib/src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -315,8 +315,11 @@ async fn upgrade(opts: UpgradeOpts) -> Result<()> {
crate::deploy::stage(sysroot, &osname, &fetched, &spec).await?;
changed = true;
if let Some(prev) = booted_image.as_ref() {
let diff = ostree_container::ManifestDiff::new(&prev.manifest, &fetched.manifest);
diff.print();
if let Some(fetched_manifest) = fetched.get_manifest(repo)? {
let diff =
ostree_container::ManifestDiff::new(&prev.manifest, &fetched_manifest);
diff.print();
}
}
}
}
Expand Down
50 changes: 37 additions & 13 deletions lib/src/deploy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ use anyhow::{Context, Result};

use fn_error_context::context;
use ostree::{gio, glib};
use ostree_container::store::LayeredImageState;
use ostree_container::OstreeImageReference;
use ostree_ext::container as ostree_container;
use ostree_ext::container::store::PrepareResult;
Expand All @@ -28,6 +27,13 @@ pub(crate) struct RequiredHostSpec<'a> {
pub(crate) image: &'a ImageReference,
}

/// State of a locally fetched image
pub(crate) struct ImageState {
pub(crate) manifest_digest: String,
pub(crate) version: Option<String>,
pub(crate) ostree_commit: String,
}

impl<'a> RequiredHostSpec<'a> {
/// Given a (borrowed) host specification, "unwrap" its internal
/// options, giving a spec that is required to have a base container image.
Expand All @@ -40,6 +46,29 @@ impl<'a> RequiredHostSpec<'a> {
}
}

impl From<ostree_container::store::LayeredImageState> for ImageState {
fn from(value: ostree_container::store::LayeredImageState) -> Self {
let version = value.version().map(|v| v.to_owned());
let ostree_commit = value.get_commit().to_owned();
Self {
manifest_digest: value.manifest_digest,
version,
ostree_commit,
}
}
}

impl ImageState {
/// Fetch the manifest corresponding to this image. May not be available in all backends.
pub(crate) fn get_manifest(
&self,
repo: &ostree::Repo,
) -> Result<Option<ostree_ext::oci_spec::image::ImageManifest>> {
ostree_container::store::query_image_commit(repo, &self.ostree_commit)
.map(|v| Some(v.manifest))
}
}

/// Wrapper for pulling a container image, wiring up status output.
pub(crate) async fn new_importer(
repo: &ostree::Repo,
Expand All @@ -57,14 +86,14 @@ pub(crate) async fn pull(
sysroot: &SysrootLock,
imgref: &ImageReference,
quiet: bool,
) -> Result<Box<LayeredImageState>> {
) -> Result<Box<ImageState>> {
let repo = &sysroot.repo();
let imgref = &OstreeImageReference::from(imgref.clone());
let mut imp = new_importer(repo, imgref).await?;
let prep = match imp.prepare().await? {
PrepareResult::AlreadyPresent(c) => {
println!("No changes in {} => {}", imgref, c.manifest_digest);
return Ok(c);
return Ok(Box::new((*c).into()));
}
PrepareResult::Ready(p) => p,
};
Expand All @@ -89,7 +118,7 @@ pub(crate) async fn pull(
{
eprintln!("{msg}")
}
Ok(import)
Ok(Box::new((*import).into()))
}

pub(crate) async fn cleanup(sysroot: &SysrootLock) -> Result<()> {
Expand Down Expand Up @@ -143,16 +172,15 @@ async fn deploy(
sysroot: &SysrootLock,
merge_deployment: Option<&Deployment>,
stateroot: &str,
image: &LayeredImageState,
image: &ImageState,
origin: &glib::KeyFile,
) -> Result<()> {
let stateroot = Some(stateroot);
// Copy to move into thread
let base_commit = image.get_commit().to_owned();
let cancellable = gio::Cancellable::NONE;
let _new_deployment = sysroot.stage_tree_with_options(
stateroot,
&base_commit,
image.ostree_commit.as_str(),
Some(origin),
merge_deployment,
&Default::default(),
Expand All @@ -166,7 +194,7 @@ async fn deploy(
pub(crate) async fn stage(
sysroot: &SysrootLock,
stateroot: &str,
image: &LayeredImageState,
image: &ImageState,
spec: &RequiredHostSpec<'_>,
) -> Result<()> {
let merge_deployment = sysroot.merge_deployment(Some(stateroot));
Expand All @@ -187,11 +215,7 @@ pub(crate) async fn stage(
.await?;
crate::deploy::cleanup(sysroot).await?;
println!("Queued for next boot: {imgref}");
if let Some(version) = image
.configuration
.as_ref()
.and_then(ostree_container::version_for_config)
{
if let Some(version) = image.version.as_deref() {
println!(" Version: {version}");
}
println!(" Digest: {}", image.manifest_digest);
Expand Down

0 comments on commit fde6bdd

Please sign in to comment.