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 Jul 2, 2024
1 parent fe098b3 commit 331a0b5
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 28 deletions.
6 changes: 3 additions & 3 deletions lib/src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -497,7 +497,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 @@ -638,7 +638,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 @@ -688,7 +688,7 @@ async fn rollback(_opts: RollbackOpts) -> Result<()> {
async fn edit(opts: EditOpts) -> Result<()> {
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 @@ -81,6 +81,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 @@ -388,7 +403,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
2 changes: 1 addition & 1 deletion lib/src/image.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ pub(crate) async fn push_entrypoint(source: Option<&str>, target: Option<&str>)
let source = if let Some(source) = source {
ImageReference::try_from(source).context("Parsing source image")?
} else {
let status = crate::status::get_status_require_booted(&sysroot)?;
let status = crate::status::get_status_require_booted(&sysroot).await?;
// SAFETY: We know it's booted
let booted = status.2.status.booted.unwrap();
let booted_image = booted.image.unwrap().image;
Expand Down
64 changes: 41 additions & 23 deletions lib/src/status.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ use ostree_ext::sysroot::SysrootLock;

use crate::cli::OutputFormat;
use crate::deploy::ImageState;
use crate::podman;
use crate::spec::{
Backend, BootEntry, BootOrder, Host, HostSpec, HostStatus, HostType, ImageStatus,
};
Expand Down Expand Up @@ -154,7 +155,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 @@ -171,7 +172,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 @@ -233,18 +238,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 @@ -283,23 +288,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 @@ -347,7 +365,7 @@ pub(crate) async fn status(opts: super::cli::StatusOpts) -> Result<()> {
} else {
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 331a0b5

Please sign in to comment.