diff --git a/dist/polkit-1/rules.d/zincati.rules b/dist/polkit-1/rules.d/zincati.rules index 71b64d36..12d32964 100644 --- a/dist/polkit-1/rules.d/zincati.rules +++ b/dist/polkit-1/rules.d/zincati.rules @@ -2,7 +2,8 @@ polkit.addRule(function(action, subject) { if ((action.id == "org.projectatomic.rpmostree1.deploy" || action.id == "org.projectatomic.rpmostree1.finalize-deployment") || - action.id == "org.projectatomic.rpmostree1.cleanup" && + action.id == "org.projectatomic.rpmostree1.cleanup" || + action.id == "org.projectatomic.rpmostree1.rebase" && subject.user == "zincati") { return polkit.Result.YES; } diff --git a/src/cincinnati/client.rs b/src/cincinnati/client.rs index b16c77e0..a99eb977 100644 --- a/src/cincinnati/client.rs +++ b/src/cincinnati/client.rs @@ -210,10 +210,7 @@ impl ClientBuilder { .timeout(DEFAULT_HTTP_COMPLETION_TIMEOUT) .build()?, }; - let query_params = match self.query_params { - Some(params) => params, - None => HashMap::new(), - }; + let query_params = self.query_params.unwrap_or_default(); let api_base = reqwest::Url::parse(&self.api_base) .context(format!("failed to parse '{}'", &self.api_base))?; diff --git a/src/cincinnati/mod.rs b/src/cincinnati/mod.rs index ee8ff65f..fd8a52e6 100644 --- a/src/cincinnati/mod.rs +++ b/src/cincinnati/mod.rs @@ -35,6 +35,9 @@ pub static DEADEND_REASON_KEY: &str = "org.fedoraproject.coreos.updates.deadend_ /// Metadata value for "checksum" payload scheme. pub static CHECKSUM_SCHEME: &str = "checksum"; +/// Metadata value for "oci" payload scheme. +pub static OCI_SCHEME: &str = "oci"; + lazy_static::lazy_static! { static ref GRAPH_NODES: IntGauge = register_int_gauge!(opts!( "zincati_cincinnati_graph_nodes_count", @@ -232,7 +235,13 @@ fn find_update( .find(|(_, node)| is_same_checksum(node, &booted_depl.checksum)) { Some(current) => current, - None => return Ok(None), + None => { + log::warn!( + "booted deployment {} not found in the update graph", + &booted_depl.checksum + ); + return Ok(None); + } }; drop(booted_depl); let cur_release = Release::from_cincinnati(cur_node.clone()) @@ -330,12 +339,28 @@ fn find_denylisted_releases(graph: &client::Graph, depls: BTreeSet) -> /// Check whether input node matches current checksum. fn is_same_checksum(node: &Node, checksum: &str) -> bool { + //let payload_type = node.metadata.get(SCHEME_KEY); + + //if let Some(schema) = payload_type { + // if schema.as_str() == OCI_SCHEME { + // // This unwrap is safe since we get the OCI graph only if we're + // // booted on OCI already. + // //let local_checksum = deploy.get_pullspec_hash().unwrap_or_default(); + // node.payload == local_checksum + // //node.version == deploy.version + // } else if schema.as_str() == CHECKSUM_SCHEME { + // return node.payload == deploy.checksum; + // } else { + // return false; + // } + // } else { + // false + // } let payload_is_checksum = node .metadata .get(SCHEME_KEY) - .map(|v| v == CHECKSUM_SCHEME) + .map(|v| v == CHECKSUM_SCHEME || v == OCI_SCHEME) .unwrap_or(false); - payload_is_checksum && node.payload == checksum } diff --git a/src/identity/mod.rs b/src/identity/mod.rs index 5b359750..6959afa5 100644 --- a/src/identity/mod.rs +++ b/src/identity/mod.rs @@ -49,6 +49,8 @@ pub(crate) struct Identity { pub(crate) rollout_wariness: Option>, /// Stream label. pub(crate) stream: String, + /// Wether the current deployment is from an OCI container or an ostree reference. + pub(crate) oci: bool, } impl Identity { @@ -104,6 +106,9 @@ impl Identity { let platform = platform::read_id("/proc/cmdline")?; let stream = rpm_ostree::parse_booted_updates_stream(&status) .context("failed to introspect OS updates stream")?; + let oci = rpm_ostree::get_booted_oci_reference(&status) + .context("failed to introspect booted OCI reference")? + .is_some(); let id = Self { basearch, @@ -113,6 +118,7 @@ impl Identity { group: DEFAULT_GROUP.to_string(), node_uuid, rollout_wariness: None, + oci, }; Ok(id) } @@ -139,6 +145,9 @@ impl Identity { vars.insert("node_uuid".to_string(), self.node_uuid.lower_hex()); vars.insert("platform".to_string(), self.platform.clone()); vars.insert("stream".to_string(), self.stream.clone()); + if self.oci { + vars.insert("oci".to_string(), "true".to_string()); + } if let Some(rw) = self.rollout_wariness { vars.insert("rollout_wariness".to_string(), format!("{:.06}", rw)); } @@ -153,12 +162,14 @@ impl Identity { version: "0.0.0-mock".to_string(), checksum: "sha-mock".to_string(), age_index: None, + is_oci: false, }, group: "mock-workers".to_string(), node_uuid: id128::Id128::parse_str("e0f3745b108f471cbd4883c6fbed8cdd").unwrap(), platform: "mock-azure".to_string(), rollout_wariness: Some(NotNan::new(0.5).unwrap()), stream: "mock-stable".to_string(), + oci: false, } } diff --git a/src/rpm_ostree/actor.rs b/src/rpm_ostree/actor.rs index 261776c8..89ed795f 100644 --- a/src/rpm_ostree/actor.rs +++ b/src/rpm_ostree/actor.rs @@ -52,8 +52,52 @@ impl Handler for RpmOstreeClient { type Result = Result; fn handle(&mut self, msg: StageDeployment, _ctx: &mut Self::Context) -> Self::Result { - trace!("request to stage release: {:?}", msg.release); - let release = super::cli_deploy::deploy_locked(msg.release, msg.allow_downgrade); + let booted = super::cli_status::invoke_cli_status(true)?; + let local_deploy = super::cli_status::booted_status(&booted)?; + + let custom_origin = local_deploy.custom_origin(); + let release = if msg.release.is_oci { + if let Some(custom_origin) = custom_origin { + // make sure the update comes from the same origin + let release_pullspec_split: Vec<&str> = + msg.release.checksum.split("@sha256:").collect(); + if !custom_origin[0].contains(release_pullspec_split[0]) { + anyhow::bail!( + "The update pullspec provided does not match local custom-origin-url", + ); + } + + // remove the tag from the custom origin + // as it's a moving tag and we want to pin versions + let origin_prefix = custom_origin[0] + .rsplit_once(':') + .map(|(origin, _)| origin) + .ok_or(anyhow::anyhow!("Invalid custom-origin-url format"))?; + + // append the release digest to the custom origin url + let release_sha_digest = release_pullspec_split[1]; + let full_rebase_spec = format!("{origin_prefix}@sha256:{release_sha_digest}"); + + // re-craft a release object with the pullspec + let oci_release = Release { + version: msg.release.version.clone(), + checksum: full_rebase_spec, + age_index: msg.release.age_index, + is_oci: true, + }; + trace!("request to stage release: {:?}", oci_release); + super::cli_deploy::deploy_locked( + oci_release, + msg.allow_downgrade, + Some(custom_origin), + ) + } else { + anyhow::bail!("Zincati does not support OCI updates if rpm-ostree custom origin is not set on local deployement."); + } + } else { + trace!("request to stage release: {:?}", msg.release); + super::cli_deploy::deploy_locked(msg.release, msg.allow_downgrade, None) + }; trace!("rpm-ostree CLI returned: {:?}", release); release } diff --git a/src/rpm_ostree/cli_deploy.rs b/src/rpm_ostree/cli_deploy.rs index 665ef9ca..a5eb4006 100644 --- a/src/rpm_ostree/cli_deploy.rs +++ b/src/rpm_ostree/cli_deploy.rs @@ -32,10 +32,14 @@ static REGISTER_DRIVER_FAILURES: Lazy = Lazy::new(|| { }); /// Deploy an upgrade (by checksum) and leave the new deployment locked. -pub fn deploy_locked(release: Release, allow_downgrade: bool) -> Result { +pub fn deploy_locked( + release: Release, + allow_downgrade: bool, + origin: Option>, +) -> Result { DEPLOY_ATTEMPTS.inc(); - let result = invoke_cli_deploy(release, allow_downgrade); + let result = invoke_cli_deploy(release, allow_downgrade, origin); if result.is_err() { DEPLOY_FAILURES.inc(); } @@ -94,16 +98,32 @@ fn invoke_cli_register() -> Result<()> { } /// CLI executor for deploying upgrades. -fn invoke_cli_deploy(release: Release, allow_downgrade: bool) -> Result { +fn invoke_cli_deploy( + release: Release, + allow_downgrade: bool, + custom_origin: Option>, +) -> Result { fail_point!("deploy_locked_err", |_| bail!("deploy_locked_err")); fail_point!("deploy_locked_ok", |_| Ok(release.clone())); let mut cmd = std::process::Command::new("rpm-ostree"); - cmd.arg("deploy") - .arg("--lock-finalization") - .arg("--skip-branch-check") - .arg(format!("revision={}", release.checksum)) - .env("RPMOSTREE_CLIENT_ID", "zincati"); + if release.is_oci { + if let Some(origin) = custom_origin { + cmd.arg("rebase") + .arg(&release.checksum) + .arg("--lock-finalization") + .arg("--custom-origin-url") + .arg(origin[0].clone()) + .arg("--custom-origin-description") + .arg(origin[1].clone()); + } + } else { + cmd.arg("deploy") + .arg("--lock-finalization") + .arg("--skip-branch-check") + .arg(format!("revision={}", release.checksum)); + } + cmd.env("RPMOSTREE_CLIENT_ID", "zincati"); if !allow_downgrade { cmd.arg("--disallow-downgrade"); } @@ -148,8 +168,9 @@ mod tests { version: "foo".to_string(), checksum: "bar".to_string(), age_index: None, + is_oci: false, }; - let result = deploy_locked(release, true); + let result = deploy_locked(release, true, None); assert!(result.is_err()); assert!(DEPLOY_ATTEMPTS.get() >= 1); assert!(DEPLOY_FAILURES.get() >= 1); @@ -165,8 +186,9 @@ mod tests { version: "foo".to_string(), checksum: "bar".to_string(), age_index: None, + is_oci: false, }; - let result = deploy_locked(release.clone(), true).unwrap(); + let result = deploy_locked(release.clone(), true, None).unwrap(); assert_eq!(result, release); assert!(DEPLOY_ATTEMPTS.get() >= 1); } diff --git a/src/rpm_ostree/cli_finalize.rs b/src/rpm_ostree/cli_finalize.rs index ef731f8f..8cf8383f 100644 --- a/src/rpm_ostree/cli_finalize.rs +++ b/src/rpm_ostree/cli_finalize.rs @@ -18,18 +18,27 @@ lazy_static::lazy_static! { /// Unlock and finalize the new deployment. pub fn finalize_deployment(release: Release) -> Result { FINALIZE_ATTEMPTS.inc(); - let cmd = std::process::Command::new("rpm-ostree") - .arg("finalize-deployment") - .arg(&release.checksum) - .env("RPMOSTREE_CLIENT_ID", "zincati") - .output() - .context("failed to run 'rpm-ostree' binary")?; + let mut cmd = std::process::Command::new("rpm-ostree"); + cmd.env("RPMOSTREE_CLIENT_ID", "zincati") + .arg("finalize-deployment"); - if !cmd.status.success() { + // XXX for OCI image, we don't know the checksum until we deployed it. + // Currently, rpm-ostree do not return the resulting ostree commit + // when rebasing to an OCI image. We could query the deployements and + // get the latest commit but that would be racy, so let's finalize the latest + // commit. + if release.is_oci { + cmd.arg("--allow-missing-checksum") + } else { + cmd.arg(&release.checksum) + }; + + let cmd_result = cmd.output().context("failed to run 'rpm-ostree' binary")?; + if !cmd_result.status.success() { FINALIZE_FAILURES.inc(); anyhow::bail!( "rpm-ostree finalize-deployment failed:\n{}", - String::from_utf8_lossy(&cmd.stderr) + String::from_utf8_lossy(&cmd_result.stderr) ); } diff --git a/src/rpm_ostree/cli_status.rs b/src/rpm_ostree/cli_status.rs index 1be93e37..c071125b 100644 --- a/src/rpm_ostree/cli_status.rs +++ b/src/rpm_ostree/cli_status.rs @@ -61,6 +61,7 @@ pub struct Status { pub struct Deployment { booted: bool, container_image_reference: Option, + custom_origin: Option>, base_checksum: Option, #[serde(rename = "base-commit-meta")] base_metadata: BaseCommitMeta, @@ -85,37 +86,52 @@ impl Deployment { checksum: self.base_revision(), version: self.version, age_index: None, + is_oci: self.container_image_reference.is_some(), } } /// Return the deployment base revision. pub fn base_revision(&self) -> String { - self.base_checksum + self.container_image_reference .clone() + .or(self.base_checksum.clone()) .unwrap_or_else(|| self.checksum.clone()) } + + /// return the custom origin fields + pub fn custom_origin(&self) -> Option> { + self.custom_origin.clone() + } } /// Parse the booted deployment from status object. pub fn parse_booted(status: &Status) -> Result { let status = booted_status(status)?; - if let Some(img) = status.container_image_reference.as_ref() { - let msg = format!("Automatic updates disabled; booted into container image {img}"); - crate::utils::notify_ready(); - crate::utils::update_unit_status(&msg); - return Err(anyhow::Error::new(SystemInoperable(msg))); - } Ok(status.into_release()) } fn fedora_coreos_stream_from_deployment(deploy: &Deployment) -> Result { - let stream = deploy - .base_metadata - .stream - .as_ref() - .ok_or_else(|| anyhow!("Missing `fedora-coreos.stream` in commit metadata"))?; - ensure!(!stream.is_empty(), "empty stream value"); - Ok(stream.to_string()) + if let Some(origin) = deploy.custom_origin.clone() { + fedora_coreos_stream_from_custom_origin(&origin[0]) + } else { + let stream = deploy + .base_metadata + .stream + .as_ref() + .ok_or_else(|| anyhow!("Missing `fedora-coreos.stream` in commit metadata"))?; + ensure!(!stream.is_empty(), "empty stream value"); + Ok(stream.to_string()) + } +} + +fn fedora_coreos_stream_from_custom_origin(origin: &String) -> Result { + //ostree-remote-image:fedora:registry:quay.io/fedora/fedora-coreos:testing + let origin_split: Vec<&str> = origin.split(':').collect(); + if origin_split.len() != 5 { + Err(anyhow!("{origin} is not a valid custom URL")) + } else { + Ok(origin_split[4].to_string()) + } } /// Parse updates stream for booted deployment from status object. @@ -124,6 +140,11 @@ pub fn parse_booted_updates_stream(status: &Status) -> Result { fedora_coreos_stream_from_deployment(&json) } +/// Parse oci image reference for booted deployment from status object. +pub fn get_booted_oci_reference(status: &Status) -> Result> { + booted_status(status).map(|s| s.container_image_reference) +} + /// Parse pending deployment from status object. pub fn parse_pending_deployment(status: &Status) -> Result> { // There can be at most one staged/pending rpm-ostree deployment, @@ -166,7 +187,7 @@ pub fn local_deployments( } /// Return JSON object for booted deployment. -fn booted_status(status: &Status) -> Result { +pub fn booted_status(status: &Status) -> Result { let booted = status .clone() .deployments @@ -258,6 +279,14 @@ mod tests { let deployments = parse_local_deployments(&status, true); assert_eq!(deployments.len(), 1); } + { + let status = mock_status("tests/fixtures/rpm-ostree-oci-status.json").unwrap(); + let deployments = parse_local_deployments(&status, false); + assert_eq!(deployments.len(), 1); + assert!(get_booted_oci_reference(&status).unwrap().is_some()); + assert_eq!(get_booted_oci_reference(&status).unwrap().unwrap(), + "ostree-remote-image:fedora:registry:quay.io/fedora/fedora-coreos@sha256:c4a15145a232d882ccf2ed32d22c06c01a7cf62317eb966a98340ae4bd56dfa6") + } } #[test] @@ -267,4 +296,24 @@ mod tests { let stream = fedora_coreos_stream_from_deployment(&booted).unwrap(); assert_eq!(stream, "testing-devel"); } + + #[test] + fn mock_booted_oci_deployment() { + let status = mock_status("tests/fixtures/rpm-ostree-oci-status.json").unwrap(); + let booted = booted_status(&status).unwrap(); + let stream = fedora_coreos_stream_from_deployment(&booted).unwrap(); + assert_eq!(stream, "testing"); + let custom_origin = booted.custom_origin(); + assert!(custom_origin.is_some()); + let custom_origin = custom_origin.unwrap(); + assert_eq!(custom_origin.len(), 2); + assert_eq!( + custom_origin[0], + "ostree-remote-image:fedora:registry:quay.io/fedora/fedora-coreos:testing" + ); + assert_eq!( + custom_origin[1], + "Fedora CoreOS Testing stream through OCI images" + ); + } } diff --git a/src/rpm_ostree/mod.rs b/src/rpm_ostree/mod.rs index f2c4e48c..783a8662 100644 --- a/src/rpm_ostree/mod.rs +++ b/src/rpm_ostree/mod.rs @@ -2,7 +2,8 @@ mod cli_deploy; mod cli_finalize; mod cli_status; pub use cli_status::{ - invoke_cli_status, parse_booted, parse_booted_updates_stream, SystemInoperable, + get_booted_oci_reference, invoke_cli_status, parse_booted, parse_booted_updates_stream, + SystemInoperable, }; mod actor; @@ -14,8 +15,8 @@ pub use actor::{ #[cfg(test)] mod mock_tests; -use crate::cincinnati::{Node, AGE_INDEX_KEY, CHECKSUM_SCHEME, SCHEME_KEY}; -use anyhow::{anyhow, ensure, Context, Result}; +use crate::cincinnati::{Node, AGE_INDEX_KEY, CHECKSUM_SCHEME, OCI_SCHEME, SCHEME_KEY}; +use anyhow::{anyhow, bail, ensure, Context, Result}; use serde::Serialize; use std::cmp::Ordering; @@ -28,6 +29,8 @@ pub struct Release { pub checksum: String, /// Release age (Cincinnati `age_index`). pub age_index: Option, + /// If the release is shipped within an OCI image + pub is_oci: bool, } impl std::cmp::Ord for Release { @@ -70,7 +73,7 @@ impl Release { .ok_or_else(|| anyhow!("missing metadata key: {}", SCHEME_KEY))?; ensure!( - scheme == CHECKSUM_SCHEME, + scheme == CHECKSUM_SCHEME || scheme == OCI_SCHEME, "unexpected payload scheme: {}", scheme ); @@ -89,9 +92,20 @@ impl Release { version: node.version, checksum: node.payload, age_index: Some(age), + is_oci: { scheme == OCI_SCHEME }, }; Ok(rel) } + pub fn get_pullspec_hash(&self) -> Result { + let split: Vec<&str> = self.checksum.split(":registry:").collect(); + if split.len() != 2 { + bail!( + "Unexpected image reference {0}. Unable to handle.", + self.checksum + ); + } + Ok(split[1].to_string()) + } } #[cfg(test)] @@ -157,11 +171,13 @@ mod tests { version: "v0".to_string(), checksum: "p0".to_string(), age_index: Some(0), + is_oci: false, }; let n1 = Release { version: "v1".to_string(), checksum: "p1".to_string(), age_index: Some(1), + is_oci: false, }; assert!(n0 < n1); assert!(n0 == n0); @@ -173,11 +189,13 @@ mod tests { version: "v0".to_string(), checksum: "p0".to_string(), age_index: Some(0), + is_oci: false, }; let n1 = Release { version: "v1".to_string(), checksum: "p1".to_string(), age_index: Some(0), + is_oci: false, }; assert!(n0 < n1); assert!(!(n0 < n0)); @@ -188,11 +206,13 @@ mod tests { version: "v0".to_string(), checksum: "p0".to_string(), age_index: Some(0), + is_oci: false, }; let n1 = Release { version: "v0".to_string(), checksum: "p1".to_string(), age_index: Some(0), + is_oci: false, }; assert!(n0 < n1); assert!(!(n0 < n0)); diff --git a/src/update_agent/actor.rs b/src/update_agent/actor.rs index 67cc6439..502455e9 100644 --- a/src/update_agent/actor.rs +++ b/src/update_agent/actor.rs @@ -4,7 +4,7 @@ use super::{UpdateAgent, UpdateAgentInfo, UpdateAgentMachineState, UpdateAgentSt use crate::rpm_ostree::{self, Release}; use crate::utils; use actix::prelude::*; -use anyhow::{bail, format_err, Error, Result}; +use anyhow::{format_err, Error, Result}; use fn_error_context::context; use futures::prelude::*; use log::trace; @@ -478,18 +478,21 @@ impl UpdateAgentInfo { })?; if pending.version != release.version { - bail!( + log::error!( "expected pending deployment '{}', but found '{}' instead", release.version, pending.version ); + return Ok(false); } + if pending.checksum != release.checksum { - bail!( + log::error!( "detected checksum mismatch for pending deployment '{}', got unexpected value '{}'", release.version, release.checksum, ); + return Ok(false); } if self.identity.stream != stream { @@ -596,6 +599,7 @@ mod tests { version: "v1".to_string(), checksum: "ostree-checksum".to_string(), age_index: None, + is_oci: false, }; // Transition between states with different discriminants. diff --git a/src/update_agent/mod.rs b/src/update_agent/mod.rs index a4111d75..08495f41 100644 --- a/src/update_agent/mod.rs +++ b/src/update_agent/mod.rs @@ -620,6 +620,7 @@ mod tests { version: "v1".to_string(), checksum: "ostree-checksum".to_string(), age_index: None, + is_oci: false, }; machine.update_available(update.clone()); assert_eq!( @@ -656,6 +657,7 @@ mod tests { version: "v1".to_string(), checksum: "ostree-checksum".to_string(), age_index: None, + is_oci: false, }; let mut machine = UpdateAgentMachineState::NoNewUpdate; @@ -690,6 +692,7 @@ mod tests { version: "v1".to_string(), checksum: "ostree-checksum".to_string(), age_index: None, + is_oci: false, }; let mut machine = UpdateAgentMachineState::UpdateAvailable((update.clone(), 0)); let (delay, should_jitter) = machine.get_refresh_delay(steady_interval); diff --git a/tests/fixtures/00-config-sample.toml b/tests/fixtures/00-config-sample.toml index af71c07d..47786bef 100644 --- a/tests/fixtures/00-config-sample.toml +++ b/tests/fixtures/00-config-sample.toml @@ -28,4 +28,4 @@ length_minutes = 120 [[updates.periodic.window]] days = [ "Wed" ] start_time = "23:30" -length_minutes = 25 \ No newline at end of file +length_minutes = 25 diff --git a/tests/fixtures/rpm-ostree-oci-status.json b/tests/fixtures/rpm-ostree-oci-status.json new file mode 100644 index 00000000..75dcafca --- /dev/null +++ b/tests/fixtures/rpm-ostree-oci-status.json @@ -0,0 +1,42 @@ +{ + "deployments" : [ + { + "unlocked" : "none", + "requested-local-packages" : [], + "base-commit-meta" : { + "ostree.importer.version" : "0.15.3", + "ostree.tar-filtered" : { }, + "ostree.manifest" : "{\"schemaVersion\":2,\"config\":{\"mediaType\":\"application/vnd.oci.image.config.v1+json\",\"digest\":\"sha256:4863073af59a028054731969d5fba6ab1d27c4a8b9d1dabb51bd4421e3c35996\",\"size\":8812},\"layers\":[{\"mediaType\":\"application/vnd.oci.image.layer.v1.tar+gzip\",\"digest\":\"sha256:466cd9c8c01b308ab3ba61343af6e46a5b898713b08d71415899d6f533903492\",\"size\":1541370},{\"mediaType\":\"application/vnd.oci.image.layer.v1.tar+gzip\",\"digest\":\"sha256:9e9d4c4cc91e472a458e049c26eeed8771c9f621a22977c6254f3c216a95894a\",\"size\":54196970,\"annotations\":{\"ostree.components\":\"containerd\"}},{\"mediaType\":\"application/vnd.oci.image.layer.v1.tar+gzip\",\"digest\":\"sha256:981a071da17cf24618ee64219bbd9e8825108fc1bade2dc633b84828ba2db476\",\"size\":40754337,\"annotations\":{\"ostree.components\":\"llvm18-libs\"}},{\"mediaType\":\"application/vnd.oci.image.layer.v1.tar+gzip\",\"digest\":\"sha256:7b283136d6c1b3e2deac25e9d772db4f17e73e8a86f25068ae507561d76f6390\",\"size\":33851011,\"annotations\":{\"ostree.components\":\"moby-engine\"}},{\"mediaType\":\"application/vnd.oci.image.layer.v1.tar+gzip\",\"digest\":\"sha256:34605c4d33fb9f76c221713266de6718d4b0539199f834a722c3a3bd8e5529ab\",\"size\":66136828,\"annotations\":{\"ostree.components\":\"kernel-modules\"}},{\"mediaType\":\"application/vnd.oci.image.layer.v1.tar+gzip\",\"digest\":\"sha256:ec37ae0cf72911d288a34cc279689e00849f0bb5cc791e8fdc331d180c42a2af\",\"size\":19908622,\"annotations\":{\"ostree.components\":\"podman\"}},{\"mediaType\":\"application/vnd.oci.image.layer.v1.tar+gzip\",\"digest\":\"sha256:d1918c425a40ef45b6341d4c10a995f02d208bdf1805c5ef275fdd749640154d\",\"size\":40123366,\"annotations\":{\"ostree.components\":\"kernel-modules-core\"}},{\"mediaType\":\"application/vnd.oci.image.layer.v1.tar+gzip\",\"digest\":\"sha256:11581772b3aaf319ec55a255a868668ee575d1f7647ec2c7d46bba74ab7f36ad\",\"size\":41343078,\"annotations\":{\"ostree.components\":\"linux-firmware\"}},{\"mediaType\":\"application/vnd.oci.image.layer.v1.tar+gzip\",\"digest\":\"sha256:be7b499d203798de8b25193dfcb0fa4d1b6e5ab6a2c4e87fec2e9553dd2752bf\",\"size\":39813516,\"annotations\":{\"ostree.components\":\"nvidia-gpu-firmware\"}},{\"mediaType\":\"application/vnd.oci.image.layer.v1.tar+gzip\",\"digest\":\"sha256:10d062e6c4069170d3465c7314a1c17de9729ab5bd4fbb37dceac7d8b2989604\",\"size\":15215097,\"annotations\":{\"ostree.components\":\"libicu\"}},{\"mediaType\":\"application/vnd.oci.image.layer.v1.tar+gzip\",\"digest\":\"sha256:4681ba5da8eb1fb163f8cb58c7f2cd7b38da34f0681fae5cfe2bc7b52a7649f6\",\"size\":9615176,\"annotations\":{\"ostree.components\":\"rpm\"}},{\"mediaType\":\"application/vnd.oci.image.layer.v1.tar+gzip\",\"digest\":\"sha256:3e16f16c1f868d1f0ce2fcf77a0d1878c48aadb7c21b25839fd404c47a987c5f\",\"size\":18443148,\"annotations\":{\"ostree.components\":\"kernel-core\"}},{\"mediaType\":\"application/vnd.oci.image.layer.v1.tar+gzip\",\"digest\":\"sha256:2fedcee3c17093ba94899083d1b43f69c117615ae37fbaca8a63bbbc25027958\",\"size\":11019215,\"annotations\":{\"ostree.components\":\"skopeo\"}},{\"mediaType\":\"application/vnd.oci.image.layer.v1.tar+gzip\",\"digest\":\"sha256:a99f70cd5870b25d34dbcd63371770dd2e81a4ad2114620397c1f9dcd9624cbc\",\"size\":9866444,\"annotations\":{\"ostree.components\":\"docker-cli\"}},{\"mediaType\":\"application/vnd.oci.image.layer.v1.tar+gzip\",\"digest\":\"sha256:c2b4d238e054df8bef6c326b32076929230a407e2cb802bfb584019e20415dc1\",\"size\":8486116,\"annotations\":{\"ostree.components\":\"ignition\"}},{\"mediaType\":\"application/vnd.oci.image.layer.v1.tar+gzip\",\"digest\":\"sha256:c6b543b5bd072118399a12f281ce0cc61238d93b31721d9ad0a210e96af35f64\",\"size\":25194750,\"annotations\":{\"ostree.components\":\"amd-gpu-firmware\"}},{\"mediaType\":\"application/vnd.oci.image.layer.v1.tar+gzip\",\"digest\":\"sha256:bee67bcc7f7e7caea514ade9ae026fa23ee8abe041511000a45a5604f2e80fdd\",\"size\":9860213,\"annotations\":{\"ostree.components\":\"git-core\"}},{\"mediaType\":\"application/vnd.oci.image.layer.v1.tar+gzip\",\"digest\":\"sha256:8e9b61c66198d266e92abb150268b3178d921d471e2cbaee77a0010a37f0e800\",\"size\":7404318,\"annotations\":{\"ostree.components\":\"samba-client-libs\"}},{\"mediaType\":\"application/vnd.oci.image.layer.v1.tar+gzip\",\"digest\":\"sha256:b7b14f7672a7872589a73420e11b2401eaf04f93aa9200f800861629fc5bee9c\",\"size\":5933793,\"annotations\":{\"ostree.components\":\"systemd\"}},{\"mediaType\":\"application/vnd.oci.image.layer.v1.tar+gzip\",\"digest\":\"sha256:3e034a46b70ead2b0fd8a6237ccccee79277f774702ba77de5e87e08f4b11767\",\"size\":6376749,\"annotations\":{\"ostree.components\":\"rpm-ostree\"}},{\"mediaType\":\"application/vnd.oci.image.layer.v1.tar+gzip\",\"digest\":\"sha256:1d882695d0bb059113b73e482c783ff30c7424a5dbc93ebe108b2d13fb18a4bf\",\"size\":6198878,\"annotations\":{\"ostree.components\":\"bootc\"}},{\"mediaType\":\"application/vnd.oci.image.layer.v1.tar+gzip\",\"digest\":\"sha256:42a2f0607bdceff8aa49da4d9e35014a8153d2834c0ada82ecdf26cac5c8493d\",\"size\":5000388,\"annotations\":{\"ostree.components\":\"glib2\"}},{\"mediaType\":\"application/vnd.oci.image.layer.v1.tar+gzip\",\"digest\":\"sha256:b2d293a51f8ed7e787aa5881e7aa31662c717a7e1667294817d1cefc45b0f652\",\"size\":2745167,\"annotations\":{\"ostree.components\":\"systemd-udev\"}},{\"mediaType\":\"application/vnd.oci.image.layer.v1.tar+gzip\",\"digest\":\"sha256:4d2e00ce2c308667cbb90a7e458737dc13759d15c71e9a396a6ca8cc7f4f94af\",\"size\":4498173,\"annotations\":{\"ostree.components\":\"coreos-installer\"}},{\"mediaType\":\"application/vnd.oci.image.layer.v1.tar+gzip\",\"digest\":\"sha256:2a33a781ebf3d7e8cfbc249f671c9e6b50e8ab620911aa588ff32754eff35838\",\"size\":4170832,\"annotations\":{\"ostree.components\":\"runc\"}},{\"mediaType\":\"application/vnd.oci.image.layer.v1.tar+gzip\",\"digest\":\"sha256:423d272a819dfbc982094df00f7be8b75b8ac62279715502b7ea9bcf503881d8\",\"size\":4212878,\"annotations\":{\"ostree.components\":\"toolbox\"}},{\"mediaType\":\"application/vnd.oci.image.layer.v1.tar+gzip\",\"digest\":\"sha256:41573c7486d4f68eaf4a565ac0a94636e540e0391cfd7bc17276f63e78e74eec\",\"size\":4672868,\"annotations\":{\"ostree.components\":\"netavark\"}},{\"mediaType\":\"application/vnd.oci.image.layer.v1.tar+gzip\",\"digest\":\"sha256:2398fec23e673bd68ea9c9b228c0a929c62e6668bda52986fb7196dfdaee8925\",\"size\":3574574,\"annotations\":{\"ostree.components\":\"coreutils-common\"}},{\"mediaType\":\"application/vnd.oci.image.layer.v1.tar+gzip\",\"digest\":\"sha256:0da29f758dcf5f845a47ab5dc63f3923561af7cb529ce4ac786cf5971a062c1a\",\"size\":4505981,\"annotations\":{\"ostree.components\":\"nmstate\"}},{\"mediaType\":\"application/vnd.oci.image.layer.v1.tar+gzip\",\"digest\":\"sha256:b399f7bc70195362f8e2ce2096a57bde305cc03df014716bfb19e88b0c2f3ebe\",\"size\":2782331,\"annotations\":{\"ostree.components\":\"NetworkManager-team,WALinuxAgent-udev,afterburn-dracut,alternatives,audit-rules,authselect,bsdtar,bzip2,bzip2-libs,clevis,clevis-dracut,clevis-luks,clevis-systemd,cloud-utils-growpart,composefs-libs,console-login-helper-messages,console-login-helper-messages-issuegen,console-login-helper-messages-motdgen,console-login-helper-messages-profile,container-selinux,containers-common,criu-libs,crun-wasm,cyrus-sasl-gssapi,dbus-common,device-mapper-event,device-mapper-event-libs,dracut-squash,efibootmgr,elfutils-default-yama-scope,fedora-gpg-keys,fedora-release-common,fedora-release-identity-coreos,file,filesystem,flatpak-session-helper,fstrm,fuse-sshfs,fuse3,gettext-envsubst,google-compute-engine-guest-configs-udev,hostname,inih,ipcalc,iptables-legacy,iptables-legacy-libs,iptables-services,iptables-utils,irqbalance,jansson,jose,json-c,keyutils-libs,kpartx,libacl,libaio,libassuan,libattr,libbasicobjects,libbsd,libcap-ng,libcbor,libcollection,libcom_err,libdaemon,libdhash,libeconf,libffi,libgudev,libipa_hbac,libkcapi,libkcapi-hasher,libkcapi-hmaccalc,libluksmeta,libmaxminddb,libmd,libmnl,libndp,libnet,libnfnetlink,libnsl2,libpath_utils,libpkgconf,libpsl,libref_array,libss,libsss_certmap,libsss_idmap,libsss_nss_idmap,libsss_sudo,libtalloc,libtasn1,libtdb,libteam,libtevent,libtool-ltdl,libutempter,libuuid,libverto,libwbclient,lmdb-libs,logrotate,luksmeta,mokutil,nano-default-editor,npth,nss-altfiles,numactl-libs,os-prober,passim-libs,pciutils-libs,pcre2-syntax,pkgconf,pkgconf-m4,pkgconf-pkg-config,protobuf-c,publicsuffix-list-dafsa,rpcbind,rpm-ostree-libs,rpm-plugin-selinux,samba-common,selinux-policy,selinux-policy-targeted,setup,shadow-utils-subid,slirp4netns,snappy,sssd-krb5,sssd-ldap,sssd-nfs-idmap,stalld,vim-data,which,xxhash-libs,yajl,zchunk-libs\"}},{\"mediaType\":\"application/vnd.oci.image.layer.v1.tar+gzip\",\"digest\":\"sha256:a3bdedd9a2af04e7a90ccd94701b0bf33cd43c67fecc74301b57a6c06bf5b01d\",\"size\":6259428,\"annotations\":{\"ostree.components\":\"glibc,glibc-gconv-extra\"}},{\"mediaType\":\"application/vnd.oci.image.layer.v1.tar+gzip\",\"digest\":\"sha256:b70c8c0e583280696cddfc2a971ffec48f107c2da60ceb6b58048971e6897857\",\"size\":1560116,\"annotations\":{\"ostree.components\":\"glibc-common,libldb,libsmbclient,samba-common-libs,systemd-pam,systemd-resolved\"}},{\"mediaType\":\"application/vnd.oci.image.layer.v1.tar+gzip\",\"digest\":\"sha256:ca0fc061134500bda387cc52b1c3795add53c550848ddb48ee82e1e108da6538\",\"size\":1550452,\"annotations\":{\"ostree.components\":\"systemd-container,systemd-libs\"}},{\"mediaType\":\"application/vnd.oci.image.layer.v1.tar+gzip\",\"digest\":\"sha256:e8d74030a3f265fa5d4f95599ffc64d0c3e03f66fc845c10efbb7d2db671ee8e\",\"size\":52412299,\"annotations\":{\"ostree.components\":\"NetworkManager-libnm,afterburn,btrfs-progs,coreutils,fwupd,grub2-tools,hwdata,intel-gpu-firmware,microcode_ctl,openssl-libs,qed-firmware\"}},{\"mediaType\":\"application/vnd.oci.image.layer.v1.tar+gzip\",\"digest\":\"sha256:3ee5a16b03e5a52bf6251b40813de03f0083aff4b779dfcebc73f087bf72b02a\",\"size\":2790214,\"annotations\":{\"ostree.components\":\"authselect-libs,composefs,expat,iproute-tc,iputils,jq,libibverbs,libmodulemd,policycoreutils,polkit,polkit-libs,teamd,xz\"}},{\"mediaType\":\"application/vnd.oci.image.layer.v1.tar+gzip\",\"digest\":\"sha256:d80a2624f5543aa59e56b7a1a66ead7a605b925ed5c823479ed1ed7d75d38836\",\"size\":1544708,\"annotations\":{\"ostree.components\":\"cryptsetup,e2fsprogs-libs,fmt,gettext-runtime,libnghttp2,librepo,libselinux,libselinux-utils,libtextstyle,libxcrypt,openldap,xz-libs,zlib-ng-compat\"}},{\"mediaType\":\"application/vnd.oci.image.layer.v1.tar+gzip\",\"digest\":\"sha256:94a1381dff949ae7e4221711fbdd5d81a674975335a94b916e1880a34137afe2\",\"size\":1924569,\"annotations\":{\"ostree.components\":\"NetworkManager-cloud-setup,NetworkManager-tui,audit,audit-libs,c-ares,iptables-nft,libcap,libnvme,libsolv,libtirpc,libxmlb,pam-libs,pciutils\"}},{\"mediaType\":\"application/vnd.oci.image.layer.v1.tar+gzip\",\"digest\":\"sha256:a13108d05edf3c0bec53130a67f0c2b873e8adbd3ad94f1763fa2e3c664d9830\",\"size\":3349687,\"annotations\":{\"ostree.components\":\"bind-utils,crun,curl,dracut,dracut-network,libblkid,libcurl-minimal,libfdisk,libmount,libnfsidmap,nfs-utils-coreos,tzdata,util-linux-core\"}},{\"mediaType\":\"application/vnd.oci.image.layer.v1.tar+gzip\",\"digest\":\"sha256:e66da556a497b6aaa05eb8bc86d3b2c760c518db9d6ec0e191606205ac064cc2\",\"size\":2129771,\"annotations\":{\"ostree.components\":\"amd-ucode-firmware,crypto-policies,elfutils-libelf,elfutils-libs,kexec-tools,libsmartcols,linux-firmware-whence,openssh,sssd-ad,sssd-client,sssd-common-pac,sssd-ipa,sssd-krb5-common\"}},{\"mediaType\":\"application/vnd.oci.image.layer.v1.tar+gzip\",\"digest\":\"sha256:682e793282ff665c5645e727c43a8e89159ba0479b72fb8513d5b8d3cbcc2010\",\"size\":2435991,\"annotations\":{\"ostree.components\":\"libdnf5-cli,libgcc,openssl,ostree,ostree-libs,passt,passt-selinux,rpm-libs\"}},{\"mediaType\":\"application/vnd.oci.image.layer.v1.tar+gzip\",\"digest\":\"sha256:c9380ad83ff4542903ddbb11ae007e377c66ec69942d92045b33e29662dbbcd7\",\"size\":13969532,\"annotations\":{\"ostree.components\":\"NetworkManager,coreos-installer-bootinfra,cryptsetup-libs,device-mapper-persistent-data,e2fsprogs,gettext-libs,iproute,iptables-libs,libxml2,nvme-cli,pam,sqlite-libs,xfsprogs\"}},{\"mediaType\":\"application/vnd.oci.image.layer.v1.tar+gzip\",\"digest\":\"sha256:b3aaa205f4c5833bdefec16533c3adf0d1b3bd6f729f1adfc30b08d12968ce68\",\"size\":13788767,\"annotations\":{\"ostree.components\":\"clevis-pin-tpm2,diffutils,findutils,kbd-misc,libunistring,nano,rpm-sequoia,sg3_utils,shared-mime-info,sudo,tar,tpm2-tss,zstd\"}},{\"mediaType\":\"application/vnd.oci.image.layer.v1.tar+gzip\",\"digest\":\"sha256:9d3e586bb34de324909e806d2fc99a85bff30a19f5fa735681208261def04813\",\"size\":22299971,\"annotations\":{\"ostree.components\":\"aardvark-dns,bind-libs,cyrus-sasl-lib,dnf5,gnutls,grub2-common,grub2-pc-modules,grub2-tools-minimal,libdnf5,libstdc++,lld18-libs,openssh-clients,openssh-server,shadow-utils,sssd-common,util-linux,vim-minimal\"}},{\"mediaType\":\"application/vnd.oci.image.layer.v1.tar+gzip\",\"digest\":\"sha256:c39284b11b6ace91c78e441366079beba97af8176756ead16be2d5a350ba7c0f\",\"size\":14644512,\"annotations\":{\"ostree.components\":\"bash,duktape,file-libs,gnupg2,jemalloc,kbd,kbd-legacy,libzstd,lzo,procps-ng,slang,squashfs-tools,tini-static,tpm2-tools,userspace-rcu,wireguard-tools,zincati\"}},{\"mediaType\":\"application/vnd.oci.image.layer.v1.tar+gzip\",\"digest\":\"sha256:71edf1664c3fe458133c0385dcb1bdaf10fdc99d1a671b03173419867944b3e6\",\"size\":5383085,\"annotations\":{\"ostree.components\":\"adcli,cpio,cracklib,dbus-libs,fuse3-libs,gawk,gdbm,gdbm-libs,gmp,gpgme,grep,isns-utils-libs,keyutils,libini_config,libnetfilter_conntrack,libsepol,libyaml,lsof,lua-libs,makedumpfile,mpfr,net-tools,pigz,popt,sed,zram-generator\"}},{\"mediaType\":\"application/vnd.oci.image.layer.v1.tar+gzip\",\"digest\":\"sha256:331c479ffa32bb37168326a0c2035f6f9a4dae7049643b2a19a0fc221f774048\",\"size\":4758892,\"annotations\":{\"ostree.components\":\"acl,attr,avahi-libs,catatonit,gdisk,gzip,iscsi-initiator-utils,json-glib,libevent,libgusb,libjcat,libpcap,libpwquality,libseccomp,libslirp,lz4-libs,nettle,newt,oniguruma,psmisc,readline,rsync,sdbus-cpp,sg3_utils-libs,socat,spdlog\"}},{\"mediaType\":\"application/vnd.oci.image.layer.v1.tar+gzip\",\"digest\":\"sha256:69c27174fb85112f448d1b9ad9894249e671a4d5044eaf27e28666a8b19d33fc\",\"size\":5134611,\"annotations\":{\"ostree.components\":\"bash-completion,bubblewrap,chrony,conmon,dnsmasq,dosfstools,fuse-overlayfs,iscsi-initiator-utils-iscsiuio,kmod,kmod-libs,less,libedit,libfido2,libgpg-error,libidn2,libksba,libnl3,libnl3-cli,libsemanage,libusb1,ncurses,ncurses-base,ncurses-libs,nftables,ssh-key-dir,tpm2-tss-fapi\"}},{\"mediaType\":\"application/vnd.oci.image.layer.v1.tar+gzip\",\"digest\":\"sha256:96eb1ef6910d4b16326488cbcd4a899d12364c323e12eb4f9c35adc690fd7426\",\"size\":3248217,\"annotations\":{\"ostree.components\":\"cifs-utils,dbus-broker,device-mapper,device-mapper-libs,device-mapper-multipath,device-mapper-multipath-libs,efivar-libs,ethtool,kdump-utils,libarchive,libbpf,libjose,libnftnl,libuv,mdadm,p11-kit-trust,pcre2\"}},{\"mediaType\":\"application/vnd.oci.image.layer.v1.tar+gzip\",\"digest\":\"sha256:772387a49542b44a43e86e19caf5a8c2f2629160b9067ce35e09a3de2afc4715\",\"size\":8650636,\"annotations\":{\"ostree.components\":\"bootupd,ca-certificates,criu,krb5-libs,libgcrypt,lvm2,lvm2-libs,p11-kit,wasmedge-rt\"}},{\"mediaType\":\"application/vnd.oci.image.layer.v1.tar+gzip\",\"digest\":\"sha256:bff92eb69522296adc98872683a33fb8934b5ced11d7a34cc285ca582a9348f7\",\"size\":111067947,\"annotations\":{\"ostree.components\":\"initramfs,rpmostree-unpackaged-content\"}},{\"mediaType\":\"application/vnd.oci.image.layer.v1.tar+gzip\",\"digest\":\"sha256:9dad063a624b62064bf25dbbc2e802e472d636056f661f2a0be73efd8a4da98b\",\"size\":2341,\"annotations\":{\"ostree.components\":\"\"}}],\"annotations\":{\"org.opencontainers.image.revision\":\"2c413b560b1ca85a445cbe1933c25b060cf6c1d6\",\"org.opencontainers.image.version\":\"41.20250105.2.0\",\"ostree.commit\":\"059032a82cb2d0b9455b43ce5dfdc2ae62cbda96ec2cbc99416617a0d0241b8a\",\"rpmostree.inputhash\":\"0f8ffe578d91082e8b539775df61a179a2c0143e7a325969bd65529e617cc627\",\"coreos-assembler.image-config-checksum\":\"7785d2c62ec40bdf6ca4f25477f4ca121f98482efb0846ee1980f74d4c741663\",\"ostree.bootable\":\"true\",\"org.opencontainers.image.source\":\"https://github.com/coreos/fedora-coreos-config\",\"ostree.final-diffid\":\"sha256:12787d84fa137cd5649a9005efe98ec9d05ea46245fdc50aecb7dd007f2035b1\",\"ostree.linux\":\"6.12.7-200.fc41.x86_64\",\"fedora-coreos.stream\":\"testing\",\"coreos-assembler.image-input-checksum\":\"6f7d94de4393d0e07a5a69397b9da913c449fb827cbd64a3388abb159fd12dc5\",\"containers.bootc\":\"1\"}}", + "ostree.manifest-digest" : "sha256:c4a15145a232d882ccf2ed32d22c06c01a7cf62317eb966a98340ae4bd56dfa6", + "ostree.container.image-config" : "{\"created\":\"2025-01-06T19:46:25Z\",\"architecture\":\"amd64\",\"os\":\"linux\",\"config\":{\"Cmd\":[\"/usr/bin/bash\"],\"Labels\":{\"ostree.linux\":\"6.12.7-200.fc41.x86_64\",\"org.opencontainers.image.version\":\"41.20250105.2.0\",\"coreos-assembler.image-config-checksum\":\"7785d2c62ec40bdf6ca4f25477f4ca121f98482efb0846ee1980f74d4c741663\",\"fedora-coreos.stream\":\"testing\",\"ostree.final-diffid\":\"sha256:12787d84fa137cd5649a9005efe98ec9d05ea46245fdc50aecb7dd007f2035b1\",\"coreos-assembler.image-input-checksum\":\"6f7d94de4393d0e07a5a69397b9da913c449fb827cbd64a3388abb159fd12dc5\",\"rpmostree.inputhash\":\"0f8ffe578d91082e8b539775df61a179a2c0143e7a325969bd65529e617cc627\",\"ostree.commit\":\"059032a82cb2d0b9455b43ce5dfdc2ae62cbda96ec2cbc99416617a0d0241b8a\",\"ostree.bootable\":\"true\",\"containers.bootc\":\"1\",\"org.opencontainers.image.revision\":\"2c413b560b1ca85a445cbe1933c25b060cf6c1d6\",\"org.opencontainers.image.source\":\"https://github.com/coreos/fedora-coreos-config\"}},\"rootfs\":{\"type\":\"layers\",\"diff_ids\":[\"sha256:03ea77a0f2304bba48fe869bcc4f06629fbe2d735ea1ad5b420ccdc0a98fd026\",\"sha256:00c4a94561293758d3efd2b5e7f99c71114c02841adee74ce750f7b7a83ee2f4\",\"sha256:89082379ef521d2221c394c676241826f7057da258a3d37a22634bdeb7bb91ff\",\"sha256:11b17813bc4e2409edff9098aba0b2b3e0326ea65cba2921e145de2e03262f47\",\"sha256:9a83e8fb8d324d2c0ffaed9f1a3efaf3330ccdd8cc42788660be6b70a58c377e\",\"sha256:7f2a1ecab41a3d1bf460012ef1cfcfcee2305dce4039089b99b41aba9506ed51\",\"sha256:cd9b5d28f5caebaebff0c5a13824dc13eecbc227fed57210d8114ddd101801da\",\"sha256:7f9cb74d8a70652febfac627c51c74dadd1fbcd0e6dfd82ed98368a6804121b9\",\"sha256:221a17e21dd9925fa3199df00a1bbf065f7f71e6f25a556a9a6ad5cca6fec50b\",\"sha256:4acad7694e32ac27526ca49fff3a1f15eb8d890fadfec17090fd777a3b23e3d7\",\"sha256:647223531f6c844a881ac77aa8f9010609c20247ea021ff115dd78fb8db8597e\",\"sha256:3b409c71d2e3bd86f816afcd2f04bb2b1873f8d60e4f6e281bb2f45f00705f95\",\"sha256:6a4b5a21b1244f1067f97bd5f3fe988e90542216aafd5a67c8e97266d3e4b4fa\",\"sha256:d756b2dd286af080fd4c46e47c02f31c23b1d6c9080452b3742a28fd6034cdfc\",\"sha256:43726de68aebe2ff965f4f698c213da14d1ee9af085cb61fccd37aca68547b54\",\"sha256:38b3799ba2c17460bd38dd4774f2c063070b0adb36d8be19a055364b051be27b\",\"sha256:6fbf0ef01289c9bf9d5ce420c69efef03c97085eae10364c679aeed50c46bd8e\",\"sha256:c14c12b76f004e700d7a87ca935f6bc979bd9aa7e4d0a012fb9be42a4cc104c1\",\"sha256:711261988a219915086a34fc75a8705858047705a7283d587f69469afc8acd03\",\"sha256:4e0c3b4f05f1169634e9bbd8b77dde22478ad7ffd3f983c5be266983910814eb\",\"sha256:1a6db3e7cf65215e3ca15572d5cc007b172f2befb07c50d9ec03481be86ba284\",\"sha256:4af78e5998add29f0e94555144560fb6d596edb9041dc665a9c0ce524169982e\",\"sha256:de63ee0b345b77f4addd9fda0eedb65dd0c8f2170aa437d39f42e36a7216e457\",\"sha256:9c56b6b0332280c881f79205515d1d28b18610be79f74994a384ab4e76e9c15f\",\"sha256:9bae1fdf5409c2f94208328b6cad802827591b0a262f4fb8282beb9f4197f865\",\"sha256:8b5fb0ddb1863145f6d459bf7e9d291e54e59e493bcbc8053491cada985892fd\",\"sha256:7fddfc1148c63f36d8bb57fd4d1241a2c505cfc9ce6290b14fc2fb68cbbff52e\",\"sha256:5744bd1355ae2855b0eb92013d259943d5f42c8c0113dbc8b75d0bbf0f98b71c\",\"sha256:785fa3b07125801eb2f6ee2b9ae8b9229357073b49d49010edf994832043a843\",\"sha256:49c72662eb696f9394f45173d344e7d0d4ae54b8e4b7a68bbc0350beaa2afec7\",\"sha256:a91d941a95462e194046aa4b9dffc4a685e5d24b918df7ff791bc02a4d316687\",\"sha256:6192f9387c8eab3a0f92010bfd1f5dbb606e4b24b6df430624a3b8023f089847\",\"sha256:bc0e302a71bda9bdd8f38e33b8425c0c236ab8c82d916a3ead16dfc7f84c88ef\",\"sha256:da812c8ff846365fa1eb0047c1cf9aeb7eaf6080e794148a1138fb3a235bf7d1\",\"sha256:048c2c275a6b9a67f1730fee3382902cf7fd42f472720671e0deda95a18ba616\",\"sha256:04903e262958313a28264a61798fd6cee8e3fa211b607dd0c9040a6b7fd06d28\",\"sha256:0cc82553bd0a446c12cbb724cce5080770156a5493fe918702b74454183f01b5\",\"sha256:9a78976c993dcd964d4a740476bf5372989bd8f10be9b64338a88083b117fd7f\",\"sha256:648a4efb2418fc5f2af0e79f3871e1df9de9418501a3b87859da081fbc0d620e\",\"sha256:deab50d8d3488fe152d4e93063426beb6815fd2f550f9684473f2e4b7ebfdf4f\",\"sha256:3ebbb21c2dcdc53472ed2d061bcbc70c9425abd62d09f37a0153e4d8857bdacc\",\"sha256:4469a84828ae49c373c898bc4a764fddd149ae47757ea94e4f3de863acfe78b5\",\"sha256:2a80c41c3f71db4fedee8cafaa0401cbde497c33512b99446328f58fb6afa5ac\",\"sha256:a8d3b696bc84582e4f97f5411452d3add83500586adc81bff38bc3facad0da1d\",\"sha256:ec8433d1403864caf20b813cb85fc9d06667b31cdf2e9dd67f927c208be3f602\",\"sha256:66619a1c05b0f8766600a6d31ca91f770a5c062c8a6e326d54b0aea4f9e12f56\",\"sha256:64a2000a2e2cafef15c5480172148144343fd977f7d1de39108c839f41e083cb\",\"sha256:dc3e00b8dbe8fa1139fed7ef9c94b190be95ac9f8bd4e61e4e250f2f50cfbef5\",\"sha256:a3adebd0b592957c1a6105c8880b66fcea5e742509eefe72e2f8610681d0e09f\",\"sha256:9abe75d0a85b75adab306d65e0cc66ae94bc8bbf107b56a737467f3405bdfe86\",\"sha256:12787d84fa137cd5649a9005efe98ec9d05ea46245fdc50aecb7dd007f2035b1\"]},\"history\":[{\"created\":\"2025-01-06T19:47:49Z\",\"created_by\":\"ostree export of commit 059032a82cb2d0b9455b43ce5dfdc2ae62cbda96ec2cbc99416617a0d0241b8a\"},{\"created\":\"2025-01-06T19:47:49Z\",\"created_by\":\"containerd-1.7.24-3.fc41.x86_64\"},{\"created\":\"2025-01-06T19:47:49Z\",\"created_by\":\"llvm18-libs-18.1.8-4.fc41.x86_64\"},{\"created\":\"2025-01-06T19:47:49Z\",\"created_by\":\"moby-engine-27.3.1-2.fc41.x86_64\"},{\"created\":\"2025-01-06T19:47:49Z\",\"created_by\":\"kernel-modules-6.12.7-200.fc41.x86_64\"},{\"created\":\"2025-01-06T19:47:49Z\",\"created_by\":\"podman-5:5.3.1-1.fc41.x86_64\"},{\"created\":\"2025-01-06T19:47:49Z\",\"created_by\":\"kernel-modules-core-6.12.7-200.fc41.x86_64\"},{\"created\":\"2025-01-06T19:47:49Z\",\"created_by\":\"linux-firmware-20241210-1.fc41.noarch\"},{\"created\":\"2025-01-06T19:47:49Z\",\"created_by\":\"nvidia-gpu-firmware-20241210-1.fc41.noarch\"},{\"created\":\"2025-01-06T19:47:49Z\",\"created_by\":\"libicu-74.2-2.fc41.x86_64\"},{\"created\":\"2025-01-06T19:47:49Z\",\"created_by\":\"rpm-4.20.0-1.fc41.x86_64\"},{\"created\":\"2025-01-06T19:47:49Z\",\"created_by\":\"kernel-core-6.12.7-200.fc41.x86_64\"},{\"created\":\"2025-01-06T19:47:49Z\",\"created_by\":\"skopeo-1:1.17.0-1.fc41.x86_64\"},{\"created\":\"2025-01-06T19:47:49Z\",\"created_by\":\"docker-cli-27.3.1-2.fc41.x86_64\"},{\"created\":\"2025-01-06T19:47:49Z\",\"created_by\":\"ignition-2.20.0-2.fc41.x86_64\"},{\"created\":\"2025-01-06T19:47:49Z\",\"created_by\":\"amd-gpu-firmware-20241210-1.fc41.noarch\"},{\"created\":\"2025-01-06T19:47:49Z\",\"created_by\":\"git-core-2.47.1-1.fc41.x86_64\"},{\"created\":\"2025-01-06T19:47:49Z\",\"created_by\":\"samba-client-libs-2:4.21.2-1.fc41.x86_64\"},{\"created\":\"2025-01-06T19:47:49Z\",\"created_by\":\"systemd-256.10-1.fc41.x86_64\"},{\"created\":\"2025-01-06T19:47:49Z\",\"created_by\":\"rpm-ostree-2024.9-1.fc41.x86_64\"},{\"created\":\"2025-01-06T19:47:49Z\",\"created_by\":\"bootc-1.1.2-2.fc41.x86_64\"},{\"created\":\"2025-01-06T19:47:49Z\",\"created_by\":\"glib2-2.82.2-1.fc41.x86_64\"},{\"created\":\"2025-01-06T19:47:49Z\",\"created_by\":\"systemd-udev-256.10-1.fc41.x86_64\"},{\"created\":\"2025-01-06T19:47:49Z\",\"created_by\":\"coreos-installer-0.23.0-1.fc41.x86_64\"},{\"created\":\"2025-01-06T19:47:49Z\",\"created_by\":\"runc-2:1.2.3-1.fc41.x86_64\"},{\"created\":\"2025-01-06T19:47:49Z\",\"created_by\":\"toolbox-0.1.1-1.fc41.x86_64\"},{\"created\":\"2025-01-06T19:47:49Z\",\"created_by\":\"netavark-2:1.13.1-1.fc41.x86_64\"},{\"created\":\"2025-01-06T19:47:49Z\",\"created_by\":\"coreutils-common-9.5-11.fc41.x86_64\"},{\"created\":\"2025-01-06T19:47:49Z\",\"created_by\":\"nmstate-2.2.39-1.fc41.x86_64\"},{\"created\":\"2025-01-06T19:47:49Z\",\"created_by\":\"136 components\"},{\"created\":\"2025-01-06T19:47:49Z\",\"created_by\":\"glibc-gconv-extra-2.40-17.fc41.x86_64 and glibc-2.40-17.fc41.x86_64\"},{\"created\":\"2025-01-06T19:47:49Z\",\"created_by\":\"6 components\"},{\"created\":\"2025-01-06T19:47:49Z\",\"created_by\":\"systemd-libs-256.10-1.fc41.x86_64 and systemd-container-256.10-1.fc41.x86_64\"},{\"created\":\"2025-01-06T19:47:49Z\",\"created_by\":\"11 components\"},{\"created\":\"2025-01-06T19:47:49Z\",\"created_by\":\"13 components\"},{\"created\":\"2025-01-06T19:47:49Z\",\"created_by\":\"13 components\"},{\"created\":\"2025-01-06T19:47:49Z\",\"created_by\":\"13 components\"},{\"created\":\"2025-01-06T19:47:49Z\",\"created_by\":\"13 components\"},{\"created\":\"2025-01-06T19:47:49Z\",\"created_by\":\"13 components\"},{\"created\":\"2025-01-06T19:47:49Z\",\"created_by\":\"8 components\"},{\"created\":\"2025-01-06T19:47:49Z\",\"created_by\":\"13 components\"},{\"created\":\"2025-01-06T19:47:49Z\",\"created_by\":\"13 components\"},{\"created\":\"2025-01-06T19:47:49Z\",\"created_by\":\"17 components\"},{\"created\":\"2025-01-06T19:47:49Z\",\"created_by\":\"17 components\"},{\"created\":\"2025-01-06T19:47:49Z\",\"created_by\":\"26 components\"},{\"created\":\"2025-01-06T19:47:49Z\",\"created_by\":\"26 components\"},{\"created\":\"2025-01-06T19:47:49Z\",\"created_by\":\"26 components\"},{\"created\":\"2025-01-06T19:47:49Z\",\"created_by\":\"17 components\"},{\"created\":\"2025-01-06T19:47:49Z\",\"created_by\":\"9 components\"},{\"created\":\"2025-01-06T19:47:49Z\",\"created_by\":\"initramfs (kernel 6.12.7-200.fc41.x86_64) and rpmostree-unpackaged-content\"},{\"created\":\"2025-01-06T19:47:49Z\",\"created_by\":\"Reserved for new packages\"}]}" + }, + "base-removals" : [], + "custom-origin" : [ + "ostree-remote-image:fedora:registry:quay.io/fedora/fedora-coreos:testing", + "Fedora CoreOS Testing stream through OCI images" + ], + "pinned" : false, + "osname" : "fedora-coreos", + "base-remote-replacements" : { }, + "regenerate-initramfs" : false, + "checksum" : "93d0341726aec2fc96b2a956ee1486105f959305507b80e38c689e2abeb7a7e6", + "container-image-reference-digest" : "sha256:c4a15145a232d882ccf2ed32d22c06c01a7cf62317eb966a98340ae4bd56dfa6", + "requested-base-local-replacements" : [], + "id" : "fedora-coreos-93d0341726aec2fc96b2a956ee1486105f959305507b80e38c689e2abeb7a7e6.0", + "version" : "41.20250105.2.0", + "requested-local-fileoverride-packages" : [], + "requested-base-removals" : [], + "requested-packages" : [], + "serial" : 0, + "timestamp" : 1736192785, + "staged" : false, + "booted" : true, + "container-image-reference" : "ostree-remote-image:fedora:registry:quay.io/fedora/fedora-coreos@sha256:c4a15145a232d882ccf2ed32d22c06c01a7cf62317eb966a98340ae4bd56dfa6", + "packages" : [], + "base-local-replacements" : [] + } + ], + "transaction" : null, + "cached-update" : null, + "update-driver" : null +} \ No newline at end of file