Skip to content

Commit

Permalink
identity: introspect basearch
Browse files Browse the repository at this point in the history
This introspects node basearch from rpm-ostree, instead of using
build-time configuration and the internal mapping table.
  • Loading branch information
lucab committed Jul 4, 2019
1 parent 0fa2daf commit fbee2cf
Show file tree
Hide file tree
Showing 5 changed files with 129 additions and 55 deletions.
38 changes: 0 additions & 38 deletions src/identity/basearch.rs

This file was deleted.

3 changes: 1 addition & 2 deletions src/identity/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
mod basearch;
mod platform;

use crate::config::inputs;
Expand Down Expand Up @@ -58,7 +57,7 @@ impl Identity {

/// Try to build default agent identity.
pub fn try_default() -> Fallible<Self> {
let basearch = basearch::read_basearch()?;
let basearch = rpm_ostree::basearch()?;
let current_os = rpm_ostree::booted().context("failed to introspect booted OS image")?;
let node_uuid = {
let app_id = id128::Id128::try_from_slice(APP_ID)
Expand Down
81 changes: 67 additions & 14 deletions src/rpm_ostree/cli_status.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,19 @@ pub struct DeploymentJSON {
booted: bool,
#[serde(rename = "base-checksum")]
base_checksum: Option<String>,
#[serde(rename = "base-commit-meta")]
base_metadata: BaseCommitMetaJSON,
checksum: String,
version: String,
}

/// Metadata from base commit (only fields relevant to zincati).
#[derive(Debug, Deserialize)]
struct BaseCommitMetaJSON {
#[serde(rename = "coreos-assembler.basearch")]
basearch: String,
}

impl DeploymentJSON {
/// Convert into `Release`.
pub fn into_release(self) -> Release {
Expand All @@ -39,30 +48,74 @@ impl DeploymentJSON {
}
}

/// Return base architecture for booted deployment.
pub fn basearch() -> Fallible<String> {
let status = status_json(true)?;
let json = booted_json(status)?;
Ok(json.base_metadata.basearch)
}

/// Find the booted deployment.
pub fn booted() -> Fallible<Release> {
let cmd = std::process::Command::new("rpm-ostree")
.arg("status")
let status = status_json(true)?;
let json = booted_json(status)?;
Ok(json.into_release())
}

/// Return JSON object for booted deployment.
fn booted_json(status: StatusJSON) -> Fallible<DeploymentJSON> {
let booted = status
.deployments
.into_iter()
.find(|d| d.booted)
.ok_or_else(|| format_err!("no booted deployment found"))?;

ensure!(!booted.base_revision().is_empty(), "empty base revision");
ensure!(!booted.version.is_empty(), "empty version");
ensure!(!booted.base_metadata.basearch.is_empty(), "empty basearch");
Ok(booted)
}

/// Introspect deployments (rpm-ostree status).
fn status_json(booted_only: bool) -> Fallible<StatusJSON> {
let mut cmd = std::process::Command::new("rpm-ostree");
cmd.arg("status");

// Try to request the minimum scope we need.
if booted_only {
cmd.arg("--booted");
}

let cmdrun = cmd
.arg("--json")
.arg("--booted")
.output()
.with_context(|e| format_err!("failed to run rpm-ostree: {}", e))?;

if !cmd.status.success() {
if !cmdrun.status.success() {
bail!(
"rpm-ostree status failed:\n{}",
String::from_utf8_lossy(&cmd.stderr)
String::from_utf8_lossy(&cmdrun.stderr)
);
}
let status: StatusJSON = serde_json::from_slice(&cmd.stdout)?;
let status: StatusJSON = serde_json::from_slice(&cmdrun.stdout)?;
Ok(status)
}

let booted = status
.deployments
.into_iter()
.find(|d| d.booted)
.ok_or_else(|| format_err!("no booted deployment found"))?;
#[cfg(test)]
mod tests {
use super::*;

ensure!(!booted.base_revision().is_empty(), "empty base revision");
ensure!(!booted.version.is_empty(), "empty version");
Ok(booted.into_release())
fn mock_status() -> Fallible<StatusJSON> {
let fp = std::fs::File::open("tests/fixtures/rpm-ostree-status.json").unwrap();
let mut bufrd = std::io::BufReader::new(fp);
let status: StatusJSON = serde_json::from_reader(bufrd)?;
Ok(status)
}

#[test]
fn mock_booted_basearch() {
let status = mock_status().unwrap();
let booted = booted_json(status).unwrap();
assert_eq!(booted.base_metadata.basearch, "x86_64");
}
}
2 changes: 1 addition & 1 deletion src/rpm_ostree/mod.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
mod cli_deploy;
mod cli_finalize;
mod cli_status;
pub use cli_status::booted;
pub use cli_status::{basearch, booted};

mod actor;
pub use actor::{FinalizeDeployment, RpmOstreeClient, StageDeployment};
Expand Down
60 changes: 60 additions & 0 deletions tests/fixtures/rpm-ostree-status.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
{
"deployments" : [
{
"unlocked" : "none",
"requested-local-packages" : [
],
"base-commit-meta" : {
"coreos-assembler.config-dirty" : "true",
"coreos-assembler.config-gitrev" : "e5ffda727170e124c7f7d8782e256b0462bf9869",
"coreos-assembler.basearch" : "x86_64",
"rpmostree.inputhash" : "0e2ba98bac847c8a8cc5ffd42822a41d53ef6719ccaf6a0094559768aa24da33",
"version" : "30.1",
"rpmostree.rpmmd-repos" : [
{
"id" : "fedora-coreos-pool",
"timestamp" : 7435743550895030272
},
{
"id" : "fedora",
"timestamp" : -7689964138319052800
},
{
"id" : "fedora-updates",
"timestamp" : -1292510703390818304
},
{
"id" : "coreos-assembler-local-overrides",
"timestamp" : 1402332922660257792
}
]
},
"base-removals" : [
],
"gpg-enabled" : false,
"origin" : "fedora/x86_64/coreos/testing-devel",
"osname" : "fedora-coreos",
"pinned" : false,
"requested-base-local-replacements" : [
],
"checksum" : "ce718b90ce19c2cac07fa45efdce91aad208a508c98e9f7f572f5aaba76f569a",
"regenerate-initramfs" : false,
"id" : "fedora-coreos-ce718b90ce19c2cac07fa45efdce91aad208a508c98e9f7f572f5aaba76f569a.0",
"version" : "30.1",
"requested-packages" : [
],
"requested-base-removals" : [
],
"serial" : 0,
"base-local-replacements" : [
],
"timestamp" : 1561753297,
"booted" : true,
"packages" : [
]
}
],
"transaction" : null,
"cached-update" : null
}

0 comments on commit fbee2cf

Please sign in to comment.