From 42b7d6b5b8d1328295e1b1fb2a810fb84d116f40 Mon Sep 17 00:00:00 2001 From: jbtrystram Date: Fri, 7 Feb 2025 11:02:53 +0100 Subject: [PATCH] update_agent: support updating with OCI graph Local deployements are now unserialized with a enum being either `Checksum` or `Pullspec`. This will cue the cincinnati client to request the OCI graph in the pullspec case. [1] The custom-origin-description, if set, is passed along the rebase call, and the custom-url is updated to match the new pullspec. [2] Finally, update the polkit policy to allow Zincati to do a rebase operation. [1] Requires https://github.com/coreos/fedora-coreos-cincinnati/pull/99 and https://github.com/coreos/rpm-ostree/pull/5120 --- dist/polkit-1/rules.d/zincati.rules | 3 +- src/cincinnati/mod.rs | 74 ++++++++++++++++++++-------- src/identity/mod.rs | 14 ++++-- src/rpm_ostree/actor.rs | 54 ++++++++++++++++++-- src/rpm_ostree/cli_deploy.rs | 49 ++++++++++++++----- src/rpm_ostree/cli_finalize.rs | 24 ++++++--- src/rpm_ostree/cli_status.rs | 65 ++++++++++++------------ src/rpm_ostree/mod.rs | 76 +++++++++++++++++++++-------- src/update_agent/actor.rs | 8 +-- src/update_agent/mod.rs | 8 +-- 10 files changed, 267 insertions(+), 108 deletions(-) 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/mod.rs b/src/cincinnati/mod.rs index ee8ff65f..c1497ad3 100644 --- a/src/cincinnati/mod.rs +++ b/src/cincinnati/mod.rs @@ -9,11 +9,12 @@ mod mock_tests; use crate::config::inputs; use crate::identity::Identity; -use crate::rpm_ostree::Release; +use crate::rpm_ostree::{Payload, Release}; use anyhow::{Context, Result}; use fn_error_context::context; use futures::prelude::*; use futures::TryFutureExt; +use ostree_ext::container::OstreeImageReference; use prometheus::{IntCounter, IntCounterVec, IntGauge}; use serde::Serialize; use std::collections::BTreeSet; @@ -33,7 +34,10 @@ pub static DEADEND_KEY: &str = "org.fedoraproject.coreos.updates.deadend"; pub static DEADEND_REASON_KEY: &str = "org.fedoraproject.coreos.updates.deadend_reason"; /// Metadata value for "checksum" payload scheme. -pub static CHECKSUM_SCHEME: &str = "checksum"; +pub const CHECKSUM_SCHEME: &str = "checksum"; + +/// Metadata value for "oci" payload scheme. +pub const OCI_SCHEME: &str = "oci"; lazy_static::lazy_static! { static ref GRAPH_NODES: IntGauge = register_int_gauge!(opts!( @@ -229,7 +233,7 @@ fn find_update( .nodes .iter() .enumerate() - .find(|(_, node)| is_same_checksum(node, &booted_depl.checksum)) + .find(|(_, node)| is_same_checksum(node, &booted_depl)) { Some(current) => current, None => return Ok(None), @@ -313,15 +317,29 @@ fn find_denylisted_releases(graph: &client::Graph, depls: BTreeSet) -> use std::collections::HashSet; let mut local_releases = BTreeSet::new(); - let checksums: HashSet = depls.into_iter().map(|rel| rel.checksum).collect(); + let payloads: HashSet = depls + .into_iter() + // in the OCI case, the local deployment payload is a full OSTree image reference + // while the cincinnati payload only contains the OCI pullspec + // Extract the local image reference before comparing + .map(|rel| match rel.payload { + Payload::Checksum(_) => rel.payload, + Payload::Pullspec(imgref) => { + let ostree_imgref: Result = imgref.as_str().try_into(); + // ostree_imgref here is `ostree-remote-image:fedora:docker://quay.io.....` + // while the cincinnati payload only contains `quay.io:///....` + Payload::Pullspec( + ostree_imgref.map_or(imgref, |ostree_imgref| ostree_imgref.imgref.name), + ) + } + }) + .collect(); for entry in &graph.nodes { - if !checksums.contains(&entry.payload) { - continue; - } - if let Ok(release) = Release::from_cincinnati(entry.clone()) { - local_releases.insert(release); + if payloads.contains(&release.payload) { + local_releases.insert(release); + } } } @@ -329,14 +347,24 @@ 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_is_checksum = node - .metadata - .get(SCHEME_KEY) - .map(|v| v == CHECKSUM_SCHEME) - .unwrap_or(false); - - payload_is_checksum && node.payload == checksum +fn is_same_checksum(node: &Node, deploy: &Release) -> bool { + match node.metadata.get(SCHEME_KEY) { + Some(scheme) if scheme == OCI_SCHEME => { + if let Ok(Some(local_digest)) = deploy.get_image_reference() { + local_digest == node.payload + } else { + false + } + } + Some(scheme) if scheme == CHECKSUM_SCHEME => { + if let Payload::Checksum(checksum) = &deploy.payload { + checksum == &node.payload + } else { + false + } + } + _ => false, + } } /// Check whether input node is a dead-end; if so, return the reason. @@ -373,23 +401,27 @@ mod tests { #[test] fn source_node_comparison() { - let current = "current-sha"; + let current = Release { + version: String::new(), + payload: Payload::Checksum("current-sha".to_string()), + age_index: None, + }; let mut metadata = HashMap::new(); metadata.insert(SCHEME_KEY.to_string(), CHECKSUM_SCHEME.to_string()); let matching = Node { version: "v0".to_string(), - payload: current.to_string(), + payload: "current-sha".to_string(), metadata, }; - assert!(is_same_checksum(&matching, current)); + assert!(is_same_checksum(&matching, ¤t)); let mismatch = Node { version: "v0".to_string(), payload: "mismatch".to_string(), metadata: HashMap::new(), }; - assert!(!is_same_checksum(&mismatch, current)); + assert!(!is_same_checksum(&mismatch, ¤t)); } #[test] diff --git a/src/identity/mod.rs b/src/identity/mod.rs index 5b359750..1ad1894d 100644 --- a/src/identity/mod.rs +++ b/src/identity/mod.rs @@ -1,7 +1,7 @@ mod platform; -use crate::config::inputs; use crate::rpm_ostree; +use crate::{config::inputs, rpm_ostree::Payload}; use anyhow::{anyhow, ensure, Context, Result}; use fn_error_context::context; use lazy_static::lazy_static; @@ -133,12 +133,20 @@ impl Identity { pub fn cincinnati_params(&self) -> HashMap { let mut vars = HashMap::new(); vars.insert("basearch".to_string(), self.basearch.clone()); - vars.insert("os_checksum".to_string(), self.current_os.checksum.clone()); vars.insert("os_version".to_string(), self.current_os.version.clone()); vars.insert("group".to_string(), self.group.clone()); 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()); + match &self.current_os.payload { + Payload::Checksum(checksum) => { + vars.insert("os_checksum".to_string(), checksum.clone()); + } + Payload::Pullspec(image) => { + vars.insert("os_checksum".to_string(), image.clone()); + vars.insert("oci".to_string(), "true".to_string()); + } + } if let Some(rw) = self.rollout_wariness { vars.insert("rollout_wariness".to_string(), format!("{:.06}", rw)); } @@ -151,7 +159,7 @@ impl Identity { basearch: "mock-amd64".to_string(), current_os: rpm_ostree::Release { version: "0.0.0-mock".to_string(), - checksum: "sha-mock".to_string(), + payload: Payload::Checksum("sha-mock".to_string()), age_index: None, }, group: "mock-workers".to_string(), diff --git a/src/rpm_ostree/actor.rs b/src/rpm_ostree/actor.rs index 261776c8..145e1333 100644 --- a/src/rpm_ostree/actor.rs +++ b/src/rpm_ostree/actor.rs @@ -1,11 +1,12 @@ //! rpm-ostree client actor. use super::cli_status::Status; -use super::Release; +use super::{Payload, Release}; use actix::prelude::*; use anyhow::{Context, Result}; use filetime::FileTime; use log::trace; +use ostree_ext::container::OstreeImageReference; use std::collections::BTreeSet; use std::rc::Rc; @@ -52,8 +53,55 @@ 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 release = if let Payload::Pullspec(release_payload) = msg.release.payload { + if let Some(local_imgref) = local_deploy.container_image_reference() { + // re-use the custom origin info to the new deployment + // while updating custom-url to match the new image digest + // XXX: when moving to update graph V2 we want to remove this and + // have custom-url pointing to the OCI artifact containing the graph + // See https://github.com/coreos/fedora-coreos-tracker/issues/1872 + let custom_origin = if let Some(mut custom_origin) = local_deploy.custom_origin() { + custom_origin.url = release_payload.clone(); + Some(custom_origin) + } else { + log::warn!("Missing custom origin information for local OCI deployment."); + None + }; + + // Cinncinati payload contains the container image pullspec, but we need + // to prepend the OSTree signature source so rpm-ostree will verify the signature of + // the OSTree commit wrapped inside the container. + + // let's craft a propper ostree imgref object + let rebase_target = OstreeImageReference { + sigverify: local_imgref.sigverify, + imgref: ostree_ext::container::ImageReference { + transport: ostree_ext::container::Transport::Registry, + name: release_payload, + }, + }; + + // re-craft a release object with the pullspec + let oci_release = Release { + version: msg.release.version.clone(), + payload: Payload::Pullspec(rebase_target.to_string()), + age_index: msg.release.age_index, + }; + + trace!("request to stage release: {:?}", oci_release); + super::cli_deploy::deploy_locked(oci_release, msg.allow_downgrade, custom_origin) + } else { + // This should never happen as requesting the OCI graph only happens after we detected the local deployment is OCI. + // But let's fail gracefuly just in case. + anyhow::bail!("Zincati does not support OCI updates if the current deployment is not already an OCI image reference.") + } + } 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..73abd779 100644 --- a/src/rpm_ostree/cli_deploy.rs +++ b/src/rpm_ostree/cli_deploy.rs @@ -1,7 +1,7 @@ //! Interface to `rpm-ostree deploy --lock-finalization` and //! `rpm-ostree deploy --register-driver`. -use super::Release; +use crate::rpm_ostree::{CustomOrigin, Payload, Release}; use anyhow::{bail, Context, Result}; use once_cell::sync::Lazy; use prometheus::IntCounter; @@ -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, + custom_origin: Option, +) -> Result { DEPLOY_ATTEMPTS.inc(); - let result = invoke_cli_deploy(release, allow_downgrade); + let result = invoke_cli_deploy(release, allow_downgrade, custom_origin); if result.is_err() { DEPLOY_FAILURES.inc(); } @@ -94,16 +98,35 @@ 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"); + match &release.payload { + Payload::Pullspec(image) => { + cmd.arg("rebase").arg(image).arg("--lock-finalization"); + if let Some(origin) = custom_origin { + cmd.arg("--custom-origin-url") + .arg(origin.url.clone()) + .arg("--custom-origin-description") + .arg(origin.description.clone()); + } else { + log::warn!("No custom-origin information to attach to deployment.") + } + } + Payload::Checksum(checksum) => { + cmd.arg("deploy") + .arg("--lock-finalization") + .arg("--skip-branch-check") + .arg(format!("revision={}", checksum)); + } + } + cmd.env("RPMOSTREE_CLIENT_ID", "zincati"); if !allow_downgrade { cmd.arg("--disallow-downgrade"); } @@ -146,10 +169,10 @@ mod tests { let release = Release { version: "foo".to_string(), - checksum: "bar".to_string(), + payload: Payload::Checksum("bar".to_string()), age_index: None, }; - 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); @@ -163,10 +186,10 @@ mod tests { let release = Release { version: "foo".to_string(), - checksum: "bar".to_string(), + payload: Payload::Checksum("bar".to_string()), age_index: None, }; - 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..4f2844e7 100644 --- a/src/rpm_ostree/cli_finalize.rs +++ b/src/rpm_ostree/cli_finalize.rs @@ -18,18 +18,26 @@ 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. + match &release.payload { + super::Payload::Pullspec(_) => cmd.arg("--allow-missing-checksum"), + super::Payload::Checksum(checksum) => cmd.arg(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 e6320d50..e1fa6718 100644 --- a/src/rpm_ostree/cli_status.rs +++ b/src/rpm_ostree/cli_status.rs @@ -1,14 +1,14 @@ //! Interface to `rpm-ostree status --json`. use super::actor::{RpmOstreeClient, StatusCache}; -use super::Release; +use super::{Payload, Release}; use anyhow::{anyhow, bail, ensure, Context, Result}; use filetime::FileTime; use log::trace; use ostree_ext::container::OstreeImageReference; use prometheus::IntCounter; use serde::Deserialize; -use std::collections::{BTreeSet, HashMap}; +use std::collections::BTreeSet; use std::fs; use std::rc::Rc; @@ -64,7 +64,7 @@ pub struct Deployment { container_image_reference: Option, custom_origin: Option, base_checksum: Option, - base_commit_meta: HashMap, + base_commit_meta: BaseCommitMeta, checksum: String, // NOTE(lucab): missing field means "not staged". #[serde(default)] @@ -79,11 +79,24 @@ pub struct CustomOrigin { pub description: String, } +#[derive(Clone, Debug, Deserialize)] +struct BaseCommitMeta { + #[serde(rename = "fedora-coreos.stream")] + stream: Option, + #[serde(rename = "ostree.manifest")] + oci_manifest: Option, +} + impl Deployment { /// Convert into `Release`. pub fn into_release(self) -> Release { + let payload = if let Some(image) = self.container_image_reference { + Payload::Pullspec(image) + } else { + Payload::Checksum(self.base_revision()) + }; Release { - checksum: self.base_revision(), + payload, version: self.version, age_index: None, } @@ -117,39 +130,27 @@ pub fn parse_booted(status: &Status) -> Result { } fn fedora_coreos_stream_from_deployment(deploy: &Deployment) -> Result { - let stream = if deploy.container_image_reference.is_some() { - // This is the edge case where we spoofed the origin file to make it looks like a container - // native deployment but it's still pure ostree. - // here, the base commit meta deserialize nicely and we don't need the "unstringify" operation. - if let Some(stream) = deploy.base_commit_meta.get("fedora-coreos.stream") { - serde_json::from_value(stream.clone())? - - // in the OCI case, base commit meta is an escaped JSON string of + let stream = match ( + deploy.base_commit_meta.stream.clone(), + deploy.base_commit_meta.oci_manifest.clone(), + ) { + (Some(stream), _) => stream.clone(), // in the OCI case, base commit meta is an escaped JSON string of // an OCI ImageManifest. Deserialize it properly. - } else if let Some(serde_json::Value::String(inner)) = - deploy.base_commit_meta.get("ostree.manifest") - { - let manifest: oci_spec::image::ImageManifest = serde_json::from_str(inner)?; - let stream = manifest + (_, Some(oci_manifest)) => { + let manifest: oci_spec::image::ImageManifest = + serde_json::from_str(oci_manifest.as_str())?; + manifest .annotations() .clone() - .and_then(|a| a.get("fedora-coreos.stream").cloned()); - stream.ok_or_else(|| { - anyhow!("Missing `fedora-coreos.stream` in base image manifest annotations") - })? - } else { - bail!("Cannot deserialize ostree base image manifest") + .and_then(|a| a.get("fedora-coreos.stream").cloned()) + .ok_or_else(|| { + anyhow!("Missing `fedora-coreos.stream` in base image manifest annotations") + })? } - } else { - // In the regular OSTree case, just fetch "fedora-coreos.stream" - let stream = deploy - .base_commit_meta - .get("fedora-coreos.stream") - .ok_or_else(|| anyhow!("Missing `fedora-coreos.stream` in commit metadata"))?; - serde_json::from_value(stream.clone())? + (None, None) => bail!("Cannot deserialize ostree base image manifest"), }; ensure!(!stream.is_empty(), "empty stream value"); - Ok(stream.to_string()) + Ok(stream) } /// Parse updates stream for booted deployment from status object. @@ -200,7 +201,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 diff --git a/src/rpm_ostree/mod.rs b/src/rpm_ostree/mod.rs index f2c4e48c..a6aa74f8 100644 --- a/src/rpm_ostree/mod.rs +++ b/src/rpm_ostree/mod.rs @@ -2,7 +2,7 @@ mod cli_deploy; mod cli_finalize; mod cli_status; pub use cli_status::{ - invoke_cli_status, parse_booted, parse_booted_updates_stream, SystemInoperable, + invoke_cli_status, parse_booted, parse_booted_updates_stream, CustomOrigin, SystemInoperable, }; mod actor; @@ -14,8 +14,9 @@ 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 core::fmt; use serde::Serialize; use std::cmp::Ordering; @@ -24,12 +25,30 @@ use std::cmp::Ordering; pub struct Release { /// OS version. pub version: String, - /// Image base checksum. - pub checksum: String, + /// Image base checksum or OCI pullspec. + pub payload: Payload, /// Release age (Cincinnati `age_index`). pub age_index: Option, } +/// payload unique identifier can either be an ostree checksum or an OCI pullspec +#[derive(Clone, Debug, Hash, PartialEq, Eq, Serialize)] +pub enum Payload { + /// Represent a pure OSTree checksum + Checksum(String), + /// an OCI image name + Pullspec(String), +} + +impl std::fmt::Display for Payload { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + Payload::Checksum(checksum) => write!(f, "{checksum}"), + Payload::Pullspec(image) => write!(f, "{image}"), + } + } +} + impl std::cmp::Ord for Release { fn cmp(&self, other: &Self) -> Ordering { // Order is primarily based on age-index coming from Cincinnati. @@ -45,8 +64,17 @@ impl std::cmp::Ord for Release { return self.version.cmp(&other.version); } - if self.checksum != other.checksum { - return self.checksum.cmp(&other.checksum); + if self.payload != other.payload { + let self_payload = match &self.payload { + Payload::Checksum(str) => str, + Payload::Pullspec(str) => str, + }; + let other_payload = match &other.payload { + Payload::Checksum(str) => str, + Payload::Pullspec(str) => str, + }; + + return self_payload.cmp(other_payload); } Ordering::Equal @@ -69,11 +97,11 @@ impl Release { .get(SCHEME_KEY) .ok_or_else(|| anyhow!("missing metadata key: {}", SCHEME_KEY))?; - ensure!( - scheme == CHECKSUM_SCHEME, - "unexpected payload scheme: {}", - scheme - ); + let payload = match scheme.as_str() { + CHECKSUM_SCHEME => Payload::Checksum(node.payload), + OCI_SCHEME => Payload::Pullspec(node.payload), + _ => bail!("unexpected payload scheme: {}", scheme), + }; let age = { let val = node @@ -87,11 +115,21 @@ impl Release { let rel = Self { version: node.version, - checksum: node.payload, + payload, age_index: Some(age), }; Ok(rel) } + pub fn get_image_reference(&self) -> Result> { + match &self.payload { + Payload::Checksum(_) => Ok(None), + Payload::Pullspec(imgref) => { + let ostree_imgref: ostree_ext::container::OstreeImageReference = + imgref.as_str().try_into()?; + Ok(Some(ostree_imgref.imgref.name)) + } + } + } } #[cfg(test)] @@ -155,12 +193,12 @@ mod tests { { let n0 = Release { version: "v0".to_string(), - checksum: "p0".to_string(), + payload: Payload::Checksum("p0".to_string()), age_index: Some(0), }; let n1 = Release { version: "v1".to_string(), - checksum: "p1".to_string(), + payload: Payload::Checksum("p1".to_string()), age_index: Some(1), }; assert!(n0 < n1); @@ -171,12 +209,12 @@ mod tests { { let n0 = Release { version: "v0".to_string(), - checksum: "p0".to_string(), + payload: Payload::Checksum("p0".to_string()), age_index: Some(0), }; let n1 = Release { version: "v1".to_string(), - checksum: "p1".to_string(), + payload: Payload::Checksum("p1".to_string()), age_index: Some(0), }; assert!(n0 < n1); @@ -186,12 +224,12 @@ mod tests { { let n0 = Release { version: "v0".to_string(), - checksum: "p0".to_string(), + payload: Payload::Checksum("p0".to_string()), age_index: Some(0), }; let n1 = Release { version: "v0".to_string(), - checksum: "p1".to_string(), + payload: Payload::Checksum("p1".to_string()), age_index: Some(0), }; assert!(n0 < n1); diff --git a/src/update_agent/actor.rs b/src/update_agent/actor.rs index 8271bb28..a762dd50 100644 --- a/src/update_agent/actor.rs +++ b/src/update_agent/actor.rs @@ -253,7 +253,7 @@ impl UpdateAgent { log::info!( "deployment {} ({}) will be excluded from being a future update target", release.version, - release.checksum + release.payload ); } } else { @@ -484,11 +484,11 @@ impl UpdateAgentInfo { pending.version ); } - if pending.checksum != release.checksum { + if pending.payload != release.payload { bail!( "detected checksum mismatch for pending deployment '{}', got unexpected value '{}'", release.version, - release.checksum, + release.payload, ); } @@ -594,7 +594,7 @@ mod tests { // Dummy `Release`. let update = Release { version: "v1".to_string(), - checksum: "ostree-checksum".to_string(), + payload: rpm_ostree::Payload::Checksum("ostree-checksum".to_string()), age_index: None, }; diff --git a/src/update_agent/mod.rs b/src/update_agent/mod.rs index a4111d75..3b046148 100644 --- a/src/update_agent/mod.rs +++ b/src/update_agent/mod.rs @@ -573,7 +573,7 @@ fn format_seconds(seconds: u64) -> String { #[cfg(test)] mod tests { use super::*; - use crate::rpm_ostree::Release; + use crate::rpm_ostree::{Payload, Release}; use std::{thread, time}; #[test] @@ -618,7 +618,7 @@ mod tests { let update = Release { version: "v1".to_string(), - checksum: "ostree-checksum".to_string(), + payload: Payload::Checksum("ostree-checksum".to_string()), age_index: None, }; machine.update_available(update.clone()); @@ -654,7 +654,7 @@ mod tests { fn test_fsm_abandon_update() { let update = Release { version: "v1".to_string(), - checksum: "ostree-checksum".to_string(), + payload: Payload::Checksum("ostree-checksum".to_string()), age_index: None, }; let mut machine = UpdateAgentMachineState::NoNewUpdate; @@ -688,7 +688,7 @@ mod tests { let postponement_interval = Duration::from_secs(DEFAULT_POSTPONEMENT_TIME_SECS); let update = Release { version: "v1".to_string(), - checksum: "ostree-checksum".to_string(), + payload: Payload::Checksum("ostree-checksum".to_string()), age_index: None, }; let mut machine = UpdateAgentMachineState::UpdateAvailable((update.clone(), 0));