-
Notifications
You must be signed in to change notification settings - Fork 86
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add "rhsm" feature for integration with Red Hat Subscription Manager
This adds a new subcommand `bootc internals publish-rhsm-facts` which writes out facts data to /etc/rhsm/facts/bootc.json Signed-off-by: John Eckersberg <[email protected]>
- Loading branch information
Showing
4 changed files
with
139 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -42,3 +42,6 @@ mod install; | |
mod kernel; | ||
#[cfg(feature = "install")] | ||
pub(crate) mod mount; | ||
|
||
#[cfg(feature = "rhsm")] | ||
mod rhsm; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,128 @@ | ||
//! Integration with Red Hat Subscription Manager | ||
use anyhow::Result; | ||
use cap_std::fs::{Dir, OpenOptions}; | ||
use cap_std_ext::cap_std; | ||
use fn_error_context::context; | ||
use serde::Serialize; | ||
|
||
const FACTS_PATH: &str = "etc/rhsm/facts/bootc.json"; | ||
|
||
#[derive(Serialize)] | ||
struct RhsmFacts { | ||
#[serde(rename = "bootc.booted.image")] | ||
booted_image: String, | ||
#[serde(rename = "bootc.booted.version")] | ||
booted_version: String, | ||
#[serde(rename = "bootc.booted.digest")] | ||
booted_digest: String, | ||
#[serde(rename = "bootc.staged.image")] | ||
staged_image: String, | ||
#[serde(rename = "bootc.staged.version")] | ||
staged_version: String, | ||
#[serde(rename = "bootc.staged.digest")] | ||
staged_digest: String, | ||
#[serde(rename = "bootc.rollback.image")] | ||
rollback_image: String, | ||
#[serde(rename = "bootc.rollback.version")] | ||
rollback_version: String, | ||
#[serde(rename = "bootc.rollback.digest")] | ||
rollback_digest: String, | ||
#[serde(rename = "bootc.available.image")] | ||
available_image: String, | ||
#[serde(rename = "bootc.available.version")] | ||
available_version: String, | ||
#[serde(rename = "bootc.available.digest")] | ||
available_digest: String, | ||
} | ||
|
||
impl From<crate::spec::HostStatus> for RhsmFacts { | ||
fn from(hoststatus: crate::spec::HostStatus) -> Self { | ||
let (booted_image, booted_version, booted_digest) = hoststatus | ||
.booted | ||
.as_ref() | ||
.and_then(|boot_entry| { | ||
boot_entry.image.as_ref().map(|imagestatus| { | ||
let image = imagestatus.image.image.clone(); | ||
let version = imagestatus.version.as_ref().cloned().unwrap_or_default(); | ||
let digest = imagestatus.image_digest.clone(); | ||
|
||
(image, digest, version) | ||
}) | ||
}) | ||
.unwrap_or_default(); | ||
|
||
let (staged_image, staged_version, staged_digest) = hoststatus | ||
.staged | ||
.as_ref() | ||
.and_then(|boot_entry| { | ||
boot_entry.image.as_ref().map(|imagestatus| { | ||
let image = imagestatus.image.image.clone(); | ||
let version = imagestatus.version.as_ref().cloned().unwrap_or_default(); | ||
let digest = imagestatus.image_digest.clone(); | ||
|
||
(image, digest, version) | ||
}) | ||
}) | ||
.unwrap_or_default(); | ||
|
||
let (rollback_image, rollback_version, rollback_digest) = hoststatus | ||
.rollback | ||
.as_ref() | ||
.and_then(|boot_entry| { | ||
boot_entry.image.as_ref().map(|imagestatus| { | ||
let image = imagestatus.image.image.clone(); | ||
let version = imagestatus.version.as_ref().cloned().unwrap_or_default(); | ||
let digest = imagestatus.image_digest.clone(); | ||
|
||
(image, digest, version) | ||
}) | ||
}) | ||
.unwrap_or_default(); | ||
|
||
let (available_image, available_version, available_digest) = hoststatus | ||
.booted | ||
.as_ref() | ||
.and_then(|boot_entry| { | ||
boot_entry.cached_update.as_ref().map(|imagestatus| { | ||
let image = imagestatus.image.image.clone(); | ||
let version = imagestatus.version.as_ref().cloned().unwrap_or_default(); | ||
let digest = imagestatus.image_digest.clone(); | ||
|
||
(image, digest, version) | ||
}) | ||
}) | ||
.unwrap_or_default(); | ||
|
||
Self { | ||
booted_image, | ||
booted_version, | ||
booted_digest, | ||
staged_image, | ||
staged_version, | ||
staged_digest, | ||
rollback_image, | ||
rollback_version, | ||
rollback_digest, | ||
available_image, | ||
available_version, | ||
available_digest, | ||
} | ||
} | ||
} | ||
|
||
/// Publish facts for subscription-manager consumption | ||
#[context("Publishing facts")] | ||
pub(crate) async fn publish_facts(root: &Dir) -> Result<()> { | ||
let sysroot = super::cli::get_storage().await?; | ||
let booted_deployment = sysroot.booted_deployment(); | ||
let (_deployments, host) = crate::status::get_status(&sysroot, booted_deployment.as_ref())?; | ||
|
||
let facts = RhsmFacts::from(host.status); | ||
let mut bootc_facts_file = root.open_with( | ||
FACTS_PATH, | ||
OpenOptions::new().write(true).create(true).truncate(true), | ||
)?; | ||
serde_json::to_writer_pretty(&mut bootc_facts_file, &facts)?; | ||
Ok(()) | ||
} |