Add an rpmostree-client sub-crate
This is intended to be published to https://crates.io/crates/rpmostree-client
Part of https://github.com/coreos/rpm-ostree/issues/2389
This directly imports the code from
5551c54c6e/tests/inst/src/rpmostree.rs
Once merged and released I'll try converting the ostree test suite
over as well as Zincati.
Internally add a testutils helper to validate it works.
This commit is contained in:
parent
7bf885ecf7
commit
e6c045cada
11
Cargo.lock
generated
11
Cargo.lock
generated
@ -1197,6 +1197,16 @@ dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rpmostree-client"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"serde",
|
||||
"serde_derive",
|
||||
"serde_json",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rpmostree-rust"
|
||||
version = "0.1.0"
|
||||
@ -1228,6 +1238,7 @@ dependencies = [
|
||||
"phf",
|
||||
"rand 0.8.3",
|
||||
"rayon",
|
||||
"rpmostree-client",
|
||||
"rust-ini",
|
||||
"serde",
|
||||
"serde_derive",
|
||||
|
@ -60,6 +60,7 @@ libdnf-sys = { path = "rust/libdnf-sys", version = "0.1.0" }
|
||||
memfd = "0.3.0"
|
||||
rust-ini = "0.16.1"
|
||||
os-release = "0.1.0"
|
||||
rpmostree-client = { path = "rust/rpmostree-client", version = "0.1.0" }
|
||||
|
||||
[build-dependencies]
|
||||
cbindgen = "0.16.0"
|
||||
|
16
rust/rpmostree-client/Cargo.toml
Normal file
16
rust/rpmostree-client/Cargo.toml
Normal file
@ -0,0 +1,16 @@
|
||||
[package]
|
||||
name = "rpmostree-client"
|
||||
description = "Client side bindings for rpm-ostree"
|
||||
version = "0.1.0"
|
||||
edition = "2018"
|
||||
license = "Apache-2.0"
|
||||
keywords = ["ostree", "rpm-ostree"]
|
||||
documentation = "http://docs.rs/rpmostree-client"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
anyhow = "1.0.38"
|
||||
serde = { version = "1.0.123", features = ["derive"] }
|
||||
serde_derive = "1.0.118"
|
||||
serde_json = "1.0.62"
|
64
rust/rpmostree-client/src/lib.rs
Normal file
64
rust/rpmostree-client/src/lib.rs
Normal file
@ -0,0 +1,64 @@
|
||||
//! APIs for interacting with rpm-ostree client side.
|
||||
|
||||
use anyhow::Context;
|
||||
use serde_derive::Deserialize;
|
||||
use std::process::Command;
|
||||
|
||||
/// Our generic catchall fatal error, expected to be converted
|
||||
/// to a string to output to a terminal or logs.
|
||||
type Result<T> = std::result::Result<T, Box<dyn std::error::Error + Send + Sync + 'static>>;
|
||||
|
||||
/// Representation of the rpm-ostree client-side state; this
|
||||
/// can be parsed directly from the output of `rpm-ostree status --json`.
|
||||
/// Currently not all fields are here, but that is a bug.
|
||||
#[derive(Deserialize)]
|
||||
#[serde(rename_all = "kebab-case")]
|
||||
pub struct Status {
|
||||
pub deployments: Vec<Deployment>,
|
||||
}
|
||||
|
||||
/// A single deployment, i.e. a bootable ostree commit
|
||||
#[derive(Deserialize)]
|
||||
#[serde(rename_all = "kebab-case")]
|
||||
pub struct Deployment {
|
||||
pub unlocked: Option<String>,
|
||||
pub osname: String,
|
||||
pub pinned: bool,
|
||||
pub checksum: String,
|
||||
pub staged: Option<bool>,
|
||||
pub booted: bool,
|
||||
pub serial: u32,
|
||||
pub origin: String,
|
||||
}
|
||||
|
||||
/// Gather a snapshot of the system status.
|
||||
pub fn query_status() -> Result<Status> {
|
||||
// Retry on temporary activation failures, see
|
||||
// https://github.com/coreos/rpm-ostree/issues/2531
|
||||
let pause = std::time::Duration::from_secs(1);
|
||||
let max_retries = 10;
|
||||
let mut retries = 0;
|
||||
let cmd_res = loop {
|
||||
retries += 1;
|
||||
let res = Command::new("rpm-ostree")
|
||||
.args(&["status", "--json"])
|
||||
.output()
|
||||
.context("failed to spawn 'rpm-ostree status'")?;
|
||||
|
||||
if res.status.success() || retries >= max_retries {
|
||||
break res;
|
||||
}
|
||||
std::thread::sleep(pause);
|
||||
};
|
||||
|
||||
if !cmd_res.status.success() {
|
||||
return Err(format!(
|
||||
"running 'rpm-ostree status' failed: {}",
|
||||
String::from_utf8_lossy(&cmd_res.stderr)
|
||||
)
|
||||
.into());
|
||||
}
|
||||
|
||||
Ok(serde_json::from_slice(&cmd_res.stdout)
|
||||
.context("failed to parse 'rpm-ostree status' output")?)
|
||||
}
|
417
rust/rpmostree-client/tests/fixtures/workstation-status.json
vendored
Normal file
417
rust/rpmostree-client/tests/fixtures/workstation-status.json
vendored
Normal file
@ -0,0 +1,417 @@
|
||||
{
|
||||
"deployments": [
|
||||
{
|
||||
"unlocked": "none",
|
||||
"base-commit-meta": {
|
||||
"coreos-assembler.config-gitrev": "80966f951c766846da070b4c168b9170c61513e2",
|
||||
"coreos-assembler.config-dirty": "false",
|
||||
"rpmostree.inputhash": "06539cc4a4265eec2045a349fe80de451a61628c1b117e171d80663d3e3f42eb",
|
||||
"coreos-assembler.basearch": "x86_64",
|
||||
"version": "33.21",
|
||||
"rpmostree.initramfs-args": [
|
||||
"--add=ignition",
|
||||
"--no-hostonly",
|
||||
"--omit=nfs",
|
||||
"--omit=lvm",
|
||||
"--omit=iscsi"
|
||||
],
|
||||
"rpmostree.rpmmd-repos": [
|
||||
{
|
||||
"id": "fedora-coreos-pool",
|
||||
"timestamp": 1053029086517002240
|
||||
},
|
||||
{
|
||||
"id": "fedora",
|
||||
"timestamp": -2945197617627267072
|
||||
},
|
||||
{
|
||||
"id": "fedora-updates",
|
||||
"timestamp": -389530169125109760
|
||||
}
|
||||
]
|
||||
},
|
||||
"requested-local-packages": [],
|
||||
"base-removals": [],
|
||||
"gpg-enabled": false,
|
||||
"origin": "fedora/33/x86_64/silverblue",
|
||||
"osname": "fedora-silverblue",
|
||||
"pinned": false,
|
||||
"requested-base-local-replacements": [
|
||||
"rpm-ostree-2021.1-2.fc33.x86_64",
|
||||
"rpm-ostree-libs-2021.1-2.fc33.x86_64"
|
||||
],
|
||||
"checksum": "63335a77f9853618ba1a5f139c5805e82176a2a040ef5e34d7402e12263af5bb",
|
||||
"regenerate-initramfs": false,
|
||||
"id": "fedora-silverblue-63335a77f9853618ba1a5f139c5805e82176a2a040ef5e34d7402e12263af5bb.0",
|
||||
"version": "33.21",
|
||||
"base-version": "33.21",
|
||||
"requested-base-removals": [],
|
||||
"base-checksum": "229387d3c0bb8ad698228ca5702eca72aed8b298a7c800be1dc72bab160a9f7f",
|
||||
"requested-packages": [
|
||||
"xsel",
|
||||
"gdb",
|
||||
"ykclient",
|
||||
"krb5-workstation",
|
||||
"ykpers",
|
||||
"git-evtag",
|
||||
"fish",
|
||||
"qemu-system-aarch64",
|
||||
"strace",
|
||||
"qemu-kvm",
|
||||
"virt-manager",
|
||||
"opensc",
|
||||
"tmux",
|
||||
"pcsc-lite-ccid",
|
||||
"tilix",
|
||||
"libvirt"
|
||||
],
|
||||
"base-timestamp": 1612554510,
|
||||
"serial": 0,
|
||||
"layered-commit-meta": {
|
||||
"rpmostree.clientlayer": true,
|
||||
"rpmostree.removed-base-packages": [],
|
||||
"version": "33.21",
|
||||
"rpmostree.packages": [
|
||||
"fish",
|
||||
"gdb",
|
||||
"git-evtag",
|
||||
"krb5-workstation",
|
||||
"libvirt",
|
||||
"opensc",
|
||||
"pcsc-lite-ccid",
|
||||
"qemu-kvm",
|
||||
"qemu-system-aarch64",
|
||||
"strace",
|
||||
"tilix",
|
||||
"tmux",
|
||||
"virt-manager",
|
||||
"xsel",
|
||||
"ykclient",
|
||||
"ykpers"
|
||||
],
|
||||
"rpmostree.clientlayer_version": 4,
|
||||
"rpmostree.replaced-base-packages": [
|
||||
[
|
||||
[
|
||||
"rpm-ostree-2021.1-2.fc33.x86_64",
|
||||
"rpm-ostree",
|
||||
0,
|
||||
"2021.1",
|
||||
"2.fc33",
|
||||
"x86_64"
|
||||
],
|
||||
[
|
||||
"rpm-ostree-2021.1-3.fc33.x86_64",
|
||||
"rpm-ostree",
|
||||
0,
|
||||
"2021.1",
|
||||
"3.fc33",
|
||||
"x86_64"
|
||||
]
|
||||
],
|
||||
[
|
||||
[
|
||||
"rpm-ostree-libs-2021.1-2.fc33.x86_64",
|
||||
"rpm-ostree-libs",
|
||||
0,
|
||||
"2021.1",
|
||||
"2.fc33",
|
||||
"x86_64"
|
||||
],
|
||||
[
|
||||
"rpm-ostree-libs-2021.1-3.fc33.x86_64",
|
||||
"rpm-ostree-libs",
|
||||
0,
|
||||
"2021.1",
|
||||
"3.fc33",
|
||||
"x86_64"
|
||||
]
|
||||
]
|
||||
],
|
||||
"rpmostree.state-sha512": "8b037fba282e3773ef17d4c396ee958765c01e85c7a6a29ec9df1bb2213022cf599da15ec4df982c4f0904012b165c4370a9f14b12c48d0684a66928c4f34b34",
|
||||
"rpmostree.rpmmd-repos": [
|
||||
{
|
||||
"id": "fedora-cisco-openh264",
|
||||
"timestamp": 1598382634
|
||||
},
|
||||
{
|
||||
"id": "updates",
|
||||
"timestamp": 1612486906
|
||||
},
|
||||
{
|
||||
"id": "fedora",
|
||||
"timestamp": 1603150039
|
||||
}
|
||||
]
|
||||
},
|
||||
"base-local-replacements": [
|
||||
[
|
||||
[
|
||||
"rpm-ostree-2021.1-2.fc33.x86_64",
|
||||
"rpm-ostree",
|
||||
0,
|
||||
"2021.1",
|
||||
"2.fc33",
|
||||
"x86_64"
|
||||
],
|
||||
[
|
||||
"rpm-ostree-2021.1-3.fc33.x86_64",
|
||||
"rpm-ostree",
|
||||
0,
|
||||
"2021.1",
|
||||
"3.fc33",
|
||||
"x86_64"
|
||||
]
|
||||
],
|
||||
[
|
||||
[
|
||||
"rpm-ostree-libs-2021.1-2.fc33.x86_64",
|
||||
"rpm-ostree-libs",
|
||||
0,
|
||||
"2021.1",
|
||||
"2.fc33",
|
||||
"x86_64"
|
||||
],
|
||||
[
|
||||
"rpm-ostree-libs-2021.1-3.fc33.x86_64",
|
||||
"rpm-ostree-libs",
|
||||
0,
|
||||
"2021.1",
|
||||
"3.fc33",
|
||||
"x86_64"
|
||||
]
|
||||
]
|
||||
],
|
||||
"timestamp": 1612555369,
|
||||
"packages": [
|
||||
"fish",
|
||||
"gdb",
|
||||
"git-evtag",
|
||||
"krb5-workstation",
|
||||
"libvirt",
|
||||
"opensc",
|
||||
"pcsc-lite-ccid",
|
||||
"qemu-kvm",
|
||||
"qemu-system-aarch64",
|
||||
"strace",
|
||||
"tilix",
|
||||
"tmux",
|
||||
"virt-manager",
|
||||
"xsel",
|
||||
"ykclient",
|
||||
"ykpers"
|
||||
],
|
||||
"booted": true,
|
||||
"initramfs-etc": []
|
||||
},
|
||||
{
|
||||
"unlocked": "none",
|
||||
"pending-base-version": "33.21",
|
||||
"base-commit-meta": {
|
||||
"coreos-assembler.config-gitrev": "bbd5282b507c5b29e3a5f12e9da21f3aaa0f0e00",
|
||||
"coreos-assembler.config-dirty": "false",
|
||||
"rpmostree.inputhash": "f33469d0f6c5d5ce5e30345fa5b002a8e4ebf5ea397caad000bdc32cd74897a6",
|
||||
"coreos-assembler.basearch": "x86_64",
|
||||
"version": "33.17",
|
||||
"rpmostree.initramfs-args": [
|
||||
"--add=ignition",
|
||||
"--no-hostonly",
|
||||
"--omit=nfs",
|
||||
"--omit=lvm",
|
||||
"--omit=iscsi"
|
||||
],
|
||||
"rpmostree.rpmmd-repos": [
|
||||
{
|
||||
"id": "fedora-coreos-pool",
|
||||
"timestamp": 7926905303512121344
|
||||
},
|
||||
{
|
||||
"id": "fedora",
|
||||
"timestamp": -2945197617627267072
|
||||
},
|
||||
{
|
||||
"id": "fedora-updates",
|
||||
"timestamp": -6611277243593261056
|
||||
}
|
||||
]
|
||||
},
|
||||
"requested-local-packages": [],
|
||||
"base-removals": [],
|
||||
"gpg-enabled": false,
|
||||
"osname": "fedora-silverblue",
|
||||
"origin": "fedora/33/x86_64/silverblue",
|
||||
"packages": [
|
||||
"fish",
|
||||
"gdb",
|
||||
"git-evtag",
|
||||
"krb5-workstation",
|
||||
"libvirt",
|
||||
"opensc",
|
||||
"pcsc-lite-ccid",
|
||||
"qemu-kvm",
|
||||
"qemu-system-aarch64",
|
||||
"strace",
|
||||
"tilix",
|
||||
"tmux",
|
||||
"virt-manager",
|
||||
"xsel",
|
||||
"ykclient",
|
||||
"ykpers"
|
||||
],
|
||||
"pinned": false,
|
||||
"requested-base-local-replacements": [
|
||||
"rpm-ostree-2021.1-2.fc33.x86_64",
|
||||
"rpm-ostree-libs-2021.1-2.fc33.x86_64"
|
||||
],
|
||||
"checksum": "775d54e89bc74731ec27db04f12510c0269c8cbab3ad5e39e0a4d693231ef072",
|
||||
"regenerate-initramfs": false,
|
||||
"id": "fedora-silverblue-775d54e89bc74731ec27db04f12510c0269c8cbab3ad5e39e0a4d693231ef072.0",
|
||||
"version": "33.17",
|
||||
"base-version": "33.17",
|
||||
"base-checksum": "deea0555cb7d3eb042df9a85d4efcbb9f70d778a9a9557715c0e398978233cd7",
|
||||
"requested-base-removals": [],
|
||||
"requested-packages": [
|
||||
"xsel",
|
||||
"gdb",
|
||||
"ykclient",
|
||||
"krb5-workstation",
|
||||
"ykpers",
|
||||
"git-evtag",
|
||||
"fish",
|
||||
"qemu-system-aarch64",
|
||||
"strace",
|
||||
"qemu-kvm",
|
||||
"virt-manager",
|
||||
"opensc",
|
||||
"tmux",
|
||||
"pcsc-lite-ccid",
|
||||
"tilix",
|
||||
"libvirt"
|
||||
],
|
||||
"base-timestamp": 1611079148,
|
||||
"serial": 0,
|
||||
"layered-commit-meta": {
|
||||
"rpmostree.clientlayer": true,
|
||||
"rpmostree.removed-base-packages": [],
|
||||
"version": "33.17",
|
||||
"rpmostree.packages": [
|
||||
"fish",
|
||||
"gdb",
|
||||
"git-evtag",
|
||||
"krb5-workstation",
|
||||
"libvirt",
|
||||
"opensc",
|
||||
"pcsc-lite-ccid",
|
||||
"qemu-kvm",
|
||||
"qemu-system-aarch64",
|
||||
"strace",
|
||||
"tilix",
|
||||
"tmux",
|
||||
"virt-manager",
|
||||
"xsel",
|
||||
"ykclient",
|
||||
"ykpers"
|
||||
],
|
||||
"rpmostree.clientlayer_version": 4,
|
||||
"rpmostree.replaced-base-packages": [
|
||||
[
|
||||
[
|
||||
"rpm-ostree-2021.1-2.fc33.x86_64",
|
||||
"rpm-ostree",
|
||||
0,
|
||||
"2021.1",
|
||||
"2.fc33",
|
||||
"x86_64"
|
||||
],
|
||||
[
|
||||
"rpm-ostree-2020.10-1.fc33.x86_64",
|
||||
"rpm-ostree",
|
||||
0,
|
||||
"2020.10",
|
||||
"1.fc33",
|
||||
"x86_64"
|
||||
]
|
||||
],
|
||||
[
|
||||
[
|
||||
"rpm-ostree-libs-2021.1-2.fc33.x86_64",
|
||||
"rpm-ostree-libs",
|
||||
0,
|
||||
"2021.1",
|
||||
"2.fc33",
|
||||
"x86_64"
|
||||
],
|
||||
[
|
||||
"rpm-ostree-libs-2020.10-1.fc33.x86_64",
|
||||
"rpm-ostree-libs",
|
||||
0,
|
||||
"2020.10",
|
||||
"1.fc33",
|
||||
"x86_64"
|
||||
]
|
||||
]
|
||||
],
|
||||
"rpmostree.state-sha512": "684f72c2b63379ee17a8f3055ccdfb3d54d255ed5bf1965788be21e804a0aff9e08620519dacaa34cc8cbad038474e8b0abbc68ee98988c547ad599f93ddcfa1",
|
||||
"rpmostree.rpmmd-repos": [
|
||||
{
|
||||
"id": "fedora-cisco-openh264",
|
||||
"timestamp": 1598382634
|
||||
},
|
||||
{
|
||||
"id": "updates",
|
||||
"timestamp": 1611022500
|
||||
},
|
||||
{
|
||||
"id": "fedora",
|
||||
"timestamp": 1603150039
|
||||
}
|
||||
]
|
||||
},
|
||||
"base-local-replacements": [
|
||||
[
|
||||
[
|
||||
"rpm-ostree-2021.1-2.fc33.x86_64",
|
||||
"rpm-ostree",
|
||||
0,
|
||||
"2021.1",
|
||||
"2.fc33",
|
||||
"x86_64"
|
||||
],
|
||||
[
|
||||
"rpm-ostree-2020.10-1.fc33.x86_64",
|
||||
"rpm-ostree",
|
||||
0,
|
||||
"2020.10",
|
||||
"1.fc33",
|
||||
"x86_64"
|
||||
]
|
||||
],
|
||||
[
|
||||
[
|
||||
"rpm-ostree-libs-2021.1-2.fc33.x86_64",
|
||||
"rpm-ostree-libs",
|
||||
0,
|
||||
"2021.1",
|
||||
"2.fc33",
|
||||
"x86_64"
|
||||
],
|
||||
[
|
||||
"rpm-ostree-libs-2020.10-1.fc33.x86_64",
|
||||
"rpm-ostree-libs",
|
||||
0,
|
||||
"2020.10",
|
||||
"1.fc33",
|
||||
"x86_64"
|
||||
]
|
||||
]
|
||||
],
|
||||
"timestamp": 1611081986,
|
||||
"pending-base-timestamp": 1612554510,
|
||||
"booted": false,
|
||||
"pending-base-checksum": "229387d3c0bb8ad698228ca5702eca72aed8b298a7c800be1dc72bab160a9f7f",
|
||||
"initramfs-etc": []
|
||||
}
|
||||
],
|
||||
"transaction": null,
|
||||
"cached-update": null
|
||||
}
|
10
rust/rpmostree-client/tests/parse.rs
Normal file
10
rust/rpmostree-client/tests/parse.rs
Normal file
@ -0,0 +1,10 @@
|
||||
use anyhow::Result;
|
||||
use rpmostree_client;
|
||||
|
||||
#[test]
|
||||
fn parse_workstation() -> Result<()> {
|
||||
let data = include_str!("fixtures/workstation-status.json");
|
||||
let state: rpmostree_client::Status = serde_json::from_str(data)?;
|
||||
assert_eq!(state.deployments.len(), 2);
|
||||
Ok(())
|
||||
}
|
@ -45,6 +45,8 @@ struct SyntheticUpgradeOpts {
|
||||
enum Opt {
|
||||
/// Generate an OS update by changing ELF files
|
||||
GenerateSyntheticUpgrade(SyntheticUpgradeOpts),
|
||||
/// Validate that we can parse the output of `rpm-ostree status --json`.
|
||||
ValidateParseStatus,
|
||||
}
|
||||
|
||||
/// Returns `true` if a file is ELF; see https://en.wikipedia.org/wiki/Executable_and_Linkable_Format
|
||||
@ -211,10 +213,24 @@ fn update_os_tree(opts: &SyntheticUpgradeOpts) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
// We always expect to be in a booted deployment. The real goal here
|
||||
// is to ensure that everything output from status --json in our
|
||||
// test suite can be parsed by our client side bindings.
|
||||
//
|
||||
// In the future we'll switch the client API to have like
|
||||
// query_status_deny_unknown_fields() which will force us
|
||||
// to update the client bindings when adding new fields.
|
||||
fn validate_parse_status() -> Result<()> {
|
||||
let s = rpmostree_client::query_status().map_err(anyhow::Error::msg)?;
|
||||
assert_ne!(s.deployments.len(), 0);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) fn testutils_entrypoint(args: Vec<String>) -> CxxResult<()> {
|
||||
let opt = Opt::from_iter(args.iter());
|
||||
match opt {
|
||||
Opt::GenerateSyntheticUpgrade(ref opts) => update_os_tree(opts)?,
|
||||
Opt::ValidateParseStatus => validate_parse_status()?,
|
||||
};
|
||||
Ok(())
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
set -xeuo pipefail
|
||||
|
||||
. ${KOLA_EXT_DATA}/libtest.sh
|
||||
cd $(mktemp -d)
|
||||
@ -15,6 +15,7 @@ assert_jq status.json \
|
||||
'.deployments[0]["requested-base-removals"]' \
|
||||
'.deployments[0]["layered-commit-meta"]|not'
|
||||
rm status.json
|
||||
rpm-ostree testutils validate-parse-status
|
||||
echo "ok empty pkg arrays, and commit meta correct in status json"
|
||||
|
||||
# Ensure we return an error when passing a wrong option.
|
||||
|
Loading…
Reference in New Issue
Block a user