Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Status tweaks #798

Merged
merged 3 commits into from
Sep 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions lib/src/fixtures/spec-via-local-oci.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
apiVersion: org.containers.bootc/v1alpha1
kind: BootcHost
metadata:
name: host
spec:
image:
image: /var/mnt/osupdate:latest
transport: oci
bootOrder: default
status:
staged: null
booted:
image:
image:
image: /var/mnt/osupdate
transport: oci
version: stream9.20240807.0
timestamp: null
imageDigest: sha256:47e5ed613a970b6574bfa954ab25bb6e85656552899aa518b5961d9645102b38
cachedUpdate: null
incompatible: false
pinned: false
ostree:
checksum: 439f6bd2e2361bee292c1f31840d798c5ac5ba76483b8021dc9f7b0164ac0f48
deploySerial: 0
rollback: null
rollbackQueued: false
type: bootcHost
91 changes: 61 additions & 30 deletions lib/src/status.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use std::borrow::Cow;
use std::collections::VecDeque;
use std::io::IsTerminal;
use std::io::Write;
Expand Down Expand Up @@ -324,40 +325,62 @@ pub(crate) async fn status(opts: super::cli::StatusOpts) -> Result<()> {
Ok(())
}

/// Write the data for a container image based status.
fn human_render_imagestatus(
mut out: impl Write,
slot_name: &str,
image: &crate::spec::ImageStatus,
) -> Result<()> {
let transport = &image.image.transport;
let imagename = &image.image.image;
// Registry is the default, so don't show that
let imageref = if transport == "registry" {
Cow::Borrowed(imagename)
} else {
// But for non-registry we include the transport
Cow::Owned(format!("{transport}:{imagename}"))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I need to read about how Cow works but I like this implementation. It does make a lot more sense.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cow basically abstracts over borrowed/owned data here, it's honestly a pointless micro-optimization but it's not hard to do either.

};
writeln!(out, "Current {slot_name} image: {imageref}")?;

let version = image
.version
.as_deref()
.unwrap_or("No image version defined");
let timestamp = image
.timestamp
.as_ref()
.map(|t| t.to_string())
.unwrap_or_else(|| "No timestamp present".to_owned());
let digest = &image.image_digest;

writeln!(out, " Image version: {version} ({timestamp})")?;
writeln!(out, " Image digest: {digest}")?;
Ok(())
}

fn human_render_ostree(mut out: impl Write, slot_name: &str, _ostree_commit: &str) -> Result<()> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this where we'd implement the documentation for additional deployments like rpm-ostree status?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep

// TODO consider rendering more ostree stuff here like rpm-ostree status does
writeln!(out, "Current {slot_name} state is native ostree")?;
Ok(())
}

/// Implementation of rendering our host structure in a "human readable" way.
fn human_readable_output(mut out: impl Write, host: &Host) -> Result<()> {
for (status_string, status) in [
for (slot_name, status) in [
("staged", &host.status.staged),
("booted", &host.status.booted),
("rollback", &host.status.rollback),
] {
if let Some(host_status) = status {
if let Some(image) = &host_status.image {
writeln!(
out,
"Current {} image: {}",
status_string, image.image.image
)?;

let version = image
.version
.as_deref()
.unwrap_or("No image version defined");
let timestamp = image
.timestamp
.as_ref()
.map(|t| t.to_string())
.unwrap_or_else(|| "No timestamp present".to_owned());
let transport = &image.image.transport;
let digest = &image.image_digest;

writeln!(out, " Image version: {version} ({timestamp})")?;
writeln!(out, " Image transport: {transport}")?;
writeln!(out, " Image digest: {digest}")?;
human_render_imagestatus(&mut out, slot_name, image)?;
} else if let Some(ostree) = host_status.ostree.as_ref() {
human_render_ostree(&mut out, slot_name, &ostree.checksum)?;
} else {
writeln!(out, "Current {status_string} state is native ostree")?;
writeln!(out, "Current {slot_name} state is unknown")?;
}
} else {
writeln!(out, "No {status_string} image present")?;
writeln!(out, "No {slot_name} image present")?;
}
}
Ok(())
Expand All @@ -383,11 +406,9 @@ mod tests {
let expected = indoc::indoc! { r"
Current staged image: quay.io/example/someimage:latest
Image version: nightly (2023-10-14 19:22:15 UTC)
Image transport: registry
Image digest: sha256:16dc2b6256b4ff0d2ec18d2dbfb06d117904010c8cf9732cdb022818cf7a7566
Current booted image: quay.io/example/someimage:latest
Image version: nightly (2023-09-30 19:22:16 UTC)
Image transport: registry
Image digest: sha256:736b359467c9437c1ac915acaae952aad854e07eb4a16a94999a48af08c83c34
No rollback image present
"};
Expand Down Expand Up @@ -417,7 +438,6 @@ mod tests {
let expected = indoc::indoc! { r"
Current staged image: quay.io/centos-bootc/centos-bootc:stream9
Image version: stream9.20240807.0 (No timestamp present)
Image transport: registry
Image digest: sha256:47e5ed613a970b6574bfa954ab25bb6e85656552899aa518b5961d9645102b38
Current booted state is native ostree
No rollback image present
Expand All @@ -434,7 +454,6 @@ mod tests {
No staged image present
Current booted image: quay.io/centos-bootc/centos-bootc:stream9
Image version: stream9.20240807.0 (No timestamp present)
Image transport: registry
Image digest: sha256:47e5ed613a970b6574bfa954ab25bb6e85656552899aa518b5961d9645102b38
No rollback image present
"};
Expand All @@ -449,17 +468,29 @@ mod tests {
let expected = indoc::indoc! { r"
Current staged image: quay.io/example/someimage:latest
Image version: nightly (2023-10-14 19:22:15 UTC)
Image transport: registry
Image digest: sha256:16dc2b6256b4ff0d2ec18d2dbfb06d117904010c8cf9732cdb022818cf7a7566
No booted image present
Current rollback image: quay.io/example/someimage:latest
Image version: nightly (2023-09-30 19:22:16 UTC)
Image transport: registry
Image digest: sha256:736b359467c9437c1ac915acaae952aad854e07eb4a16a94999a48af08c83c34
"};
similar_asserts::assert_eq!(w, expected);
}

#[test]
fn test_via_oci() {
let w = human_status_from_spec_fixture(include_str!("fixtures/spec-via-local-oci.yaml"))
.unwrap();
let expected = indoc::indoc! { r"
No staged image present
Current booted image: oci:/var/mnt/osupdate
Image version: stream9.20240807.0 (No timestamp present)
Image digest: sha256:47e5ed613a970b6574bfa954ab25bb6e85656552899aa518b5961d9645102b38
No rollback image present
"};
similar_asserts::assert_eq!(w, expected);
}

#[test]
fn test_convert_signatures() {
use std::str::FromStr;
Expand Down