Some checks failed
Run Check Script / check (pull_request) Failing after 19s
94 lines
2.4 KiB
Rust
94 lines
2.4 KiB
Rust
//! Example: install an OPNsense package and poll until completion.
|
|
//!
|
|
//! ```text
|
|
//! cargo run --example install_and_wait -- os-haproxy
|
|
//! ```
|
|
//!
|
|
//! The firmware install endpoint is async — it returns a `msg_uuid` that
|
|
//! must be polled via `GET /api/core/firmware/upgradestatus`.
|
|
|
|
mod common;
|
|
|
|
use serde::Deserialize;
|
|
use std::env;
|
|
|
|
#[derive(Debug, Deserialize)]
|
|
struct InstallResponse {
|
|
status: String,
|
|
#[serde(default)]
|
|
msg_uuid: String,
|
|
}
|
|
|
|
#[derive(Debug, Deserialize)]
|
|
struct UpgradeStatus {
|
|
#[serde(default)]
|
|
status: String,
|
|
#[serde(default)]
|
|
log: String,
|
|
}
|
|
|
|
#[tokio::main]
|
|
async fn main() {
|
|
let client = common::client_from_env();
|
|
|
|
let pkg_name = env::args().nth(1).unwrap_or_else(|| {
|
|
eprintln!("Usage: cargo run --example install_and_wait -- <package_name>");
|
|
std::process::exit(1);
|
|
});
|
|
|
|
println!("Installing {pkg_name}...");
|
|
|
|
let resp: InstallResponse = client
|
|
.post_typed(
|
|
"core",
|
|
"firmware",
|
|
&format!("install/{pkg_name}"),
|
|
None::<&()>,
|
|
)
|
|
.await
|
|
.expect("install API call failed");
|
|
|
|
println!(
|
|
"Install triggered: status={}, msg_uuid={}",
|
|
resp.status, resp.msg_uuid
|
|
);
|
|
|
|
if resp.status != "ok" {
|
|
eprintln!("Install did not return 'ok'. Response: {resp:?}");
|
|
std::process::exit(1);
|
|
}
|
|
|
|
// Poll for completion
|
|
loop {
|
|
tokio::time::sleep(std::time::Duration::from_secs(3)).await;
|
|
|
|
let status: UpgradeStatus = client
|
|
.get_typed("core", "firmware", "upgradestatus")
|
|
.await
|
|
.expect("upgradestatus API call failed");
|
|
|
|
let last_line = status.log.lines().last().unwrap_or("");
|
|
println!(" status={}, last_log={}", status.status, last_line);
|
|
|
|
if status.status == "done" {
|
|
println!("Installation complete.");
|
|
break;
|
|
}
|
|
}
|
|
|
|
// Verify
|
|
let info: serde_json::Value = client
|
|
.get_typed("core", "firmware", "info")
|
|
.await
|
|
.expect("info API call failed");
|
|
|
|
if let Some(pkgs) = info["package"].as_array() {
|
|
if let Some(pkg) = pkgs.iter().find(|p| p["name"].as_str() == Some(&pkg_name)) {
|
|
println!(
|
|
"Package {} version={} installed={}",
|
|
pkg["name"], pkg["version"], pkg["installed"]
|
|
);
|
|
}
|
|
}
|
|
}
|