Skip to content
This repository was archived by the owner on Jan 15, 2025. It is now read-only.

Commit ac6acf2

Browse files
committed
container: Support JSON out for ManifestDiff
This will let higher level tools (Plasma Discover for example) more easily read the output of `bootc update --check --json`.
1 parent 3d686ab commit ac6acf2

File tree

2 files changed

+44
-14
lines changed

2 files changed

+44
-14
lines changed

lib/src/cli.rs

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use camino::{Utf8Path, Utf8PathBuf};
1010
use cap_std::fs::Dir;
1111
use cap_std_ext::cap_std;
1212
use cap_std_ext::prelude::CapStdExtDirExt;
13-
use clap::{Parser, Subcommand};
13+
use clap::{builder::ArgPredicate, Parser, Subcommand};
1414
use fn_error_context::context;
1515
use io_lifetimes::AsFd;
1616
use ostree::{gio, glib};
@@ -178,6 +178,10 @@ pub(crate) enum ContainerOpts {
178178
/// Image reference, e.g. ostree-remote-image:someremote:registry:quay.io/exampleos/exampleos:latest
179179
#[clap(value_parser = parse_imgref)]
180180
imgref_new: OstreeImageReference,
181+
182+
/// Use JSON as output format.
183+
#[clap(long)]
184+
json: bool,
181185
},
182186
}
183187

@@ -234,6 +238,10 @@ pub(crate) enum ContainerImageOpts {
234238
/// the new manifest.
235239
#[clap(long)]
236240
check: Option<Utf8PathBuf>,
241+
242+
/// Use JSON as output format. Only applies to the --check option.
243+
#[clap(long, requires_if(ArgPredicate::IsPresent, "check"))]
244+
json: bool,
237245
},
238246

239247
/// Output metadata about an already stored container image.
@@ -717,6 +725,7 @@ async fn container_store(
717725
proxyopts: ContainerProxyOpts,
718726
quiet: bool,
719727
check: Option<Utf8PathBuf>,
728+
json: bool,
720729
) -> Result<()> {
721730
let mut imp = ImageImporter::new(repo, imgref, proxyopts.into()).await?;
722731
let prep = match imp.prepare().await? {
@@ -739,7 +748,7 @@ async fn container_store(
739748
}
740749
if let Some(previous_state) = prep.previous_state.as_ref() {
741750
let diff = ManifestDiff::new(&previous_state.manifest, &prep.manifest);
742-
diff.print();
751+
diff.print(json);
743752
}
744753
print_layer_status(&prep);
745754
let printer = (!quiet).then(|| {
@@ -965,9 +974,10 @@ async fn run_from_opt(opt: Opt) -> Result<()> {
965974
proxyopts,
966975
quiet,
967976
check,
977+
json,
968978
} => {
969979
let repo = parse_repo(&repo)?;
970-
container_store(&repo, &imgref, proxyopts, quiet, check).await
980+
container_store(&repo, &imgref, proxyopts, quiet, check, json).await
971981
}
972982
ContainerImageOpts::History { repo, imgref } => {
973983
let repo = parse_repo(&repo)?;
@@ -1177,12 +1187,13 @@ async fn run_from_opt(opt: Opt) -> Result<()> {
11771187
ContainerOpts::Compare {
11781188
imgref_old,
11791189
imgref_new,
1190+
json,
11801191
} => {
11811192
let (manifest_old, _) = crate::container::fetch_manifest(&imgref_old).await?;
11821193
let (manifest_new, _) = crate::container::fetch_manifest(&imgref_new).await?;
11831194
let manifest_diff =
11841195
crate::container::ManifestDiff::new(&manifest_old, &manifest_new);
1185-
manifest_diff.print();
1196+
manifest_diff.print(json);
11861197
Ok(())
11871198
}
11881199
},

lib/src/container/mod.rs

Lines changed: 29 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
use anyhow::anyhow;
2929
use containers_image_proxy::oci_spec;
3030
use ostree::glib;
31+
use serde_json::json;
3132

3233
use std::borrow::Cow;
3334
use std::collections::HashMap;
@@ -376,16 +377,34 @@ impl<'a> ManifestDiff<'a> {
376377

377378
impl<'a> ManifestDiff<'a> {
378379
/// Prints the total, removed and added content between two OCI images
379-
pub fn print(&self) {
380-
let print_total = self.total;
381-
let print_total_size = glib::format_size(self.total_size);
382-
let print_n_removed = self.n_removed;
383-
let print_removed_size = glib::format_size(self.removed_size);
384-
let print_n_added = self.n_added;
385-
let print_added_size = glib::format_size(self.added_size);
386-
println!("Total new layers: {print_total:<4} Size: {print_total_size}");
387-
println!("Removed layers: {print_n_removed:<4} Size: {print_removed_size}");
388-
println!("Added layers: {print_n_added:<4} Size: {print_added_size}");
380+
pub fn print(&self, json: bool) {
381+
if json {
382+
let out = json!({
383+
"total": {
384+
"count": self.total,
385+
"size": self.total_size
386+
},
387+
"removed": {
388+
"count": self.n_removed,
389+
"size": self.removed_size
390+
},
391+
"added": {
392+
"count": self.n_added,
393+
"size": self.added_size
394+
}
395+
});
396+
println!("{}", out.to_string());
397+
} else {
398+
let print_total = self.total;
399+
let print_total_size = glib::format_size(self.total_size);
400+
let print_n_removed = self.n_removed;
401+
let print_removed_size = glib::format_size(self.removed_size);
402+
let print_n_added = self.n_added;
403+
let print_added_size = glib::format_size(self.added_size);
404+
println!("Total new layers: {print_total:<4} Size: {print_total_size}");
405+
println!("Removed layers: {print_n_removed:<4} Size: {print_removed_size}");
406+
println!("Added layers: {print_n_added:<4} Size: {print_added_size}");
407+
}
389408
}
390409
}
391410

0 commit comments

Comments
 (0)