Skip to content

Commit

Permalink
WIP async propagation for podman image inspection
Browse files Browse the repository at this point in the history
  • Loading branch information
jeckersb committed Jun 5, 2024
1 parent 0ff0acb commit 37b35d5
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 27 deletions.
6 changes: 3 additions & 3 deletions lib/src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -396,7 +396,7 @@ async fn upgrade(opts: UpgradeOpts) -> Result<()> {
let sysroot = &get_locked_sysroot().await?;
let repo = &sysroot.repo();
let (booted_deployment, _deployments, host) =
crate::status::get_status_require_booted(sysroot)?;
crate::status::get_status_require_booted(sysroot).await?;
let imgref = host.spec.image.as_ref();
// If there's no specified image, let's be nice and check if the booted system is using rpm-ostree
if imgref.is_none()
Expand Down Expand Up @@ -525,7 +525,7 @@ async fn switch(opts: SwitchOpts) -> Result<()> {
let sysroot = &get_locked_sysroot().await?;
let repo = &sysroot.repo();
let (booted_deployment, _deployments, host) =
crate::status::get_status_require_booted(sysroot)?;
crate::status::get_status_require_booted(sysroot).await?;

let new_spec = {
let mut new_spec = host.spec.clone();
Expand Down Expand Up @@ -573,7 +573,7 @@ async fn edit(opts: EditOpts) -> Result<()> {
prepare_for_write().await?;
let sysroot = &get_locked_sysroot().await?;
let (booted_deployment, _deployments, host) =
crate::status::get_status_require_booted(sysroot)?;
crate::status::get_status_require_booted(sysroot).await?;
let new_host: Host = if let Some(filename) = opts.filename {
let mut r = std::io::BufReader::new(std::fs::File::open(filename)?);
serde_yaml::from_reader(&mut r)?
Expand Down
18 changes: 17 additions & 1 deletion lib/src/deploy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,21 @@ impl From<ostree_container::store::LayeredImageState> for ImageState {
}
}

impl From<crate::podman::PodmanInspect> for ImageState {
fn from(value: crate::podman::PodmanInspect) -> Self {
let version = None;
let ostree_commit = "".to_owned();
let created = value.created;
Self {
backend: Backend::Container,
manifest_digest: value.digest,
created,
version,
ostree_commit,
}
}
}

impl ImageState {
/// Fetch the manifest corresponding to this image. May not be available in all backends.
pub(crate) fn get_manifest(
Expand Down Expand Up @@ -385,7 +400,8 @@ pub(crate) async fn stage(
pub(crate) async fn rollback(sysroot: &SysrootLock) -> Result<()> {
const ROLLBACK_JOURNAL_ID: &str = "26f3b1eb24464d12aa5e7b544a6b5468";
let repo = &sysroot.repo();
let (booted_deployment, deployments, host) = crate::status::get_status_require_booted(sysroot)?;
let (booted_deployment, deployments, host) =
crate::status::get_status_require_booted(sysroot).await?;

let new_spec = {
let mut new_spec = host.spec.clone();
Expand Down
64 changes: 41 additions & 23 deletions lib/src/status.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use std::collections::VecDeque;

use crate::deploy::ImageState;
use crate::podman;
use crate::spec::{
Backend, BootEntry, BootOrder, Host, HostSpec, HostStatus, HostType, ImageStatus,
};
Expand Down Expand Up @@ -152,7 +153,7 @@ pub(crate) fn create_imagestatus(

/// Given an OSTree deployment, parse out metadata into our spec.
#[context("Reading deployment metadata")]
fn boot_entry_from_deployment(
async fn boot_entry_from_deployment(
sysroot: &SysrootLock,
deployment: &ostree::Deployment,
) -> Result<BootEntry> {
Expand All @@ -169,7 +170,11 @@ fn boot_entry_from_deployment(
let csum = deployment.csum();
let imgstate = match backend {
Backend::Container => {
todo!()
// TODO: encapsulate this better
let rootfs = &cap_std_ext::cap_std::fs::Dir::reopen_dir(
&crate::utils::sysroot_fd_borrowed(sysroot),
)?;
ImageState::from(podman::podman_inspect(rootfs, &image.image).await?)
}
Backend::OstreeContainer => {
ImageState::from(*ostree_container::store::query_image_commit(repo, &csum)?)
Expand Down Expand Up @@ -231,18 +236,18 @@ impl BootEntry {
}

/// A variant of [`get_status`] that requires a booted deployment.
pub(crate) fn get_status_require_booted(
pub(crate) async fn get_status_require_booted(
sysroot: &SysrootLock,
) -> Result<(ostree::Deployment, Deployments, Host)> {
let booted_deployment = sysroot.require_booted_deployment()?;
let (deployments, host) = get_status(sysroot, Some(&booted_deployment))?;
let (deployments, host) = get_status(sysroot, Some(&booted_deployment)).await?;
Ok((booted_deployment, deployments, host))
}

/// Gather the ostree deployment objects, but also extract metadata from them into
/// a more native Rust structure.
#[context("Computing status")]
pub(crate) fn get_status(
pub(crate) async fn get_status(
sysroot: &SysrootLock,
booted_deployment: Option<&ostree::Deployment>,
) -> Result<(Deployments, Host)> {
Expand Down Expand Up @@ -281,23 +286,36 @@ pub(crate) fn get_status(
other,
};

let staged = deployments
.staged
.as_ref()
.map(|d| boot_entry_from_deployment(sysroot, d))
.transpose()
.context("Staged deployment")?;
let booted = booted_deployment
.as_ref()
.map(|d| boot_entry_from_deployment(sysroot, d))
.transpose()
.context("Booted deployment")?;
let rollback = deployments
.rollback
.as_ref()
.map(|d| boot_entry_from_deployment(sysroot, d))
.transpose()
.context("Rollback deployment")?;
let staged = if let Some(d) = deployments.staged.as_ref() {
Some(
boot_entry_from_deployment(sysroot, d)
.await
.context("Staged deployment")?,
)
} else {
None
};

let booted = if let Some(d) = booted_deployment {
Some(
boot_entry_from_deployment(sysroot, d)
.await
.context("Booted deployment")?,
)
} else {
None
};

let rollback = if let Some(d) = deployments.rollback.as_ref() {
Some(
boot_entry_from_deployment(sysroot, d)
.await
.context("Rollback deployment")?,
)
} else {
None
};

let spec = staged
.as_ref()
.or(booted.as_ref())
Expand Down Expand Up @@ -346,7 +364,7 @@ pub(crate) async fn status(opts: super::cli::StatusOpts) -> Result<()> {
crate::cli::require_root()?;
let sysroot = super::cli::get_locked_sysroot().await?;
let booted_deployment = sysroot.booted_deployment();
let (_deployments, host) = get_status(&sysroot, booted_deployment.as_ref())?;
let (_deployments, host) = get_status(&sysroot, booted_deployment.as_ref()).await?;
host
};

Expand Down

0 comments on commit 37b35d5

Please sign in to comment.