bootc_lib/install/
aleph.rs1use anyhow::{Context as _, Result};
2use canon_json::CanonJsonSerialize as _;
3use cap_std_ext::{cap_std::fs::Dir, dirext::CapStdExtDirExt as _};
4use fn_error_context::context;
5use ostree_ext::{container as ostree_container, oci_spec};
6use serde::Serialize;
7
8use super::SELinuxFinalState;
9
10pub(crate) const BOOTC_ALEPH_PATH: &str = ".bootc-aleph.json";
12
13#[derive(Debug, Serialize)]
18pub(crate) struct InstallAleph {
19 pub(crate) image: String,
21 pub(crate) version: Option<String>,
23 pub(crate) timestamp: Option<chrono::DateTime<chrono::Utc>>,
25 pub(crate) kernel: String,
27 pub(crate) selinux: String,
29}
30
31impl InstallAleph {
32 #[context("Creating aleph data")]
33 pub(crate) fn new(
34 src_imageref: &ostree_container::OstreeImageReference,
35 imgstate: &ostree_container::store::LayeredImageState,
36 selinux_state: &SELinuxFinalState,
37 ) -> Result<Self> {
38 let uname = rustix::system::uname();
39 let labels = crate::status::labels_of_config(&imgstate.configuration);
40 let timestamp = labels
41 .and_then(|l| {
42 l.get(oci_spec::image::ANNOTATION_CREATED)
43 .map(|s| s.as_str())
44 })
45 .and_then(bootc_utils::try_deserialize_timestamp);
46 let r = InstallAleph {
47 image: src_imageref.imgref.name.clone(),
48 version: imgstate.version().as_ref().map(|s| s.to_string()),
49 timestamp,
50 kernel: uname.release().to_str()?.to_string(),
51 selinux: selinux_state.to_aleph().to_string(),
52 };
53 Ok(r)
54 }
55
56 pub(crate) fn write_to(&self, root: &Dir) -> Result<()> {
58 root.atomic_replace_with(BOOTC_ALEPH_PATH, |f| {
59 anyhow::Ok(self.to_canon_json_writer(f)?)
60 })
61 .context("Writing aleph version")
62 }
63}