Skip to content

Commit ac5ce03

Browse files
committed
install/aleph: include the image labels in aleph
Include the container labels in the aleph file, since they often contain useful information about the image provenance, such as the source commit the image was build from. Also we skip serializing the source image reference if it start with `/tmp` since this is a good signal it was source from a local copy of an image, e.g. in an osbuild environnement. Whith this, a build of Fedora CoreOS through osbuild goes from: ``` { "image": "/tmp/tmpb29j6pi3/image", "kernel": "6.18.12-200.fc43.x86_64", "selinux": "disabled", "timestamp": null, "version": "43.20260301.20.dev1" } ``` to ``` { "digest": "sha256:07bf537cc4e4d208eb0b978f76e5046e55529ce6192b982d8c1a41fa1d61b95a", "kernel": "6.18.13-200.fc43.x86_64", "labels": { "com.coreos.inputhash": "fe9883169714c593d98058606e886b9747710ed15ab1b9cdbd7fa538fb435b3c", "com.coreos.osname": "fedora-coreos", "com.coreos.stream": "testing-devel", "containers.bootc": "1", "io.buildah.version": "1.42.2", "org.opencontainers.image.description": "Fedora CoreOS testing-devel", "org.opencontainers.image.revision": "233fe18749c7d2749581e4307c4cac60967acde4", "org.opencontainers.image.source": "git@github.com:jbtrystram/fedora-coreos-config.git", "org.opencontainers.image.title": "Fedora CoreOS testing-devel", "org.opencontainers.image.version": "43.20260301.20.dev1", "ostree.bootable": "1", "ostree.commit": "89635f7cba9de932fc60d71a6bded65ad0db06a35c9d016da03ca7ade9ba4736", "ostree.final-diffid": "sha256:12787d84fa137cd5649a9005efe98ec9d05ea46245fdc50aecb7dd007f2035b1" }, "selinux": "disabled", "target-image": "ostree-image-signed:docker://quay.io/fedora/fedora-coreos:testing-devel", "timestamp": null, "version": "43.20260301.20.dev1" } ``` which is way more useful. See #2038 Assisted-by: OpenCode(Opus 4.6)
1 parent c3c1602 commit ac5ce03

3 files changed

Lines changed: 38 additions & 5 deletions

File tree

crates/lib/src/install.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1209,7 +1209,12 @@ async fn install_container(
12091209
osconfig::inject_root_ssh_authorized_keys(&root, sepolicy, contents)?;
12101210
}
12111211

1212-
let aleph = InstallAleph::new(&src_imageref, &imgstate, &state.selinux_state)?;
1212+
let aleph = InstallAleph::new(
1213+
&src_imageref,
1214+
&state.target_imgref,
1215+
&imgstate,
1216+
&state.selinux_state,
1217+
)?;
12131218
Ok((deployment, aleph))
12141219
}
12151220

crates/lib/src/install/aleph.rs

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
use std::collections::BTreeMap;
2+
13
use anyhow::{Context as _, Result};
24
use canon_json::CanonJsonSerialize as _;
35
use cap_std_ext::{cap_std::fs::Dir, dirext::CapStdExtDirExt as _};
@@ -17,7 +19,16 @@ pub(crate) const BOOTC_ALEPH_PATH: &str = ".bootc-aleph.json";
1719
#[derive(Debug, Serialize)]
1820
pub(crate) struct InstallAleph {
1921
/// Digested pull spec for installed image
20-
pub(crate) image: String,
22+
#[serde(skip_serializing_if = "Option::is_none")]
23+
pub(crate) image: Option<String>,
24+
/// The manifest digest of the installed image
25+
pub(crate) digest: String,
26+
/// The target image reference, used for subsequent updates
27+
#[serde(rename = "target-image")]
28+
pub(crate) target_image: String,
29+
/// The OCI image labels from the installed image
30+
#[serde(skip_serializing_if = "BTreeMap::is_empty")]
31+
pub(crate) labels: BTreeMap<String, String>,
2132
/// The version number
2233
pub(crate) version: Option<String>,
2334
/// The timestamp
@@ -32,19 +43,34 @@ impl InstallAleph {
3243
#[context("Creating aleph data")]
3344
pub(crate) fn new(
3445
src_imageref: &ostree_container::OstreeImageReference,
46+
target_imgref: &ostree_container::OstreeImageReference,
3547
imgstate: &ostree_container::store::LayeredImageState,
3648
selinux_state: &SELinuxFinalState,
3749
) -> Result<Self> {
3850
let uname = rustix::system::uname();
39-
let labels = crate::status::labels_of_config(&imgstate.configuration);
40-
let timestamp = labels
51+
let oci_labels = crate::status::labels_of_config(&imgstate.configuration);
52+
let timestamp = oci_labels
4153
.and_then(|l| {
4254
l.get(oci_spec::image::ANNOTATION_CREATED)
4355
.map(|s| s.as_str())
4456
})
4557
.and_then(bootc_utils::try_deserialize_timestamp);
58+
let labels: BTreeMap<String, String> = oci_labels
59+
.map(|l| l.iter().map(|(k, v)| (k.clone(), v.clone())).collect())
60+
.unwrap_or_default();
61+
// When installing via osbuild, the source image is usually a
62+
// temporary local container storage path (e.g. `/tmp/...`) which is not useful.
63+
let image = if src_imageref.imgref.name.starts_with("/tmp") {
64+
tracing::debug!("Not serializing the source imageref as it's a local temporary image.");
65+
None
66+
} else {
67+
Some(src_imageref.imgref.name.clone())
68+
};
4669
let r = InstallAleph {
47-
image: src_imageref.imgref.name.clone(),
70+
image,
71+
target_image: target_imgref.imgref.name.clone(),
72+
digest: imgstate.manifest_digest.to_string(),
73+
labels,
4874
version: imgstate.version().as_ref().map(|s| s.to_string()),
4975
timestamp,
5076
kernel: uname.release().to_str()?.to_string(),

docs/src/bootc-install.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -535,6 +535,8 @@ After installation, bootc writes a JSON file at the root of the physical
535535
filesystem (`.bootc-aleph.json`) containing installation provenance information:
536536

537537
- The source image reference and digest
538+
- The target image reference (if provided)
539+
- The OCI image labels from the installed image
538540
- Installation timestamp
539541
- bootc version
540542
- Kernel version

0 commit comments

Comments
 (0)