- Pin vendor/core submodule to 26.1.5 tag (matches running firewall)
- Regenerate dnsmasq from model v1.0.9 (migrated during firmware upgrade)
- Handle array-style select widgets in enum deserialization: OPNsense
sometimes returns [{value, selected}, ...] instead of {key: {value, selected}}
- Add firmware_upgrade and reboot examples for managing OPNsense updates
- All 7 modules validated against live OPNsense 26.1.5:
dnsmasq, haproxy, caddy, vlan, lagg, wireguard, firewall
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
58 lines
1.5 KiB
Rust
58 lines
1.5 KiB
Rust
//! Example: reboot OPNsense and wait for it to come back.
|
|
//!
|
|
//! ```text
|
|
//! cargo run --example reboot
|
|
//! ```
|
|
|
|
mod common;
|
|
|
|
use serde::Deserialize;
|
|
|
|
#[derive(Debug, Deserialize)]
|
|
struct RebootResponse {
|
|
#[serde(default)]
|
|
status: String,
|
|
}
|
|
|
|
#[tokio::main]
|
|
async fn main() {
|
|
let client = common::client_from_env();
|
|
|
|
println!("Triggering reboot...");
|
|
let resp: RebootResponse = client
|
|
.post_typed("core", "firmware", "reboot", None::<&()>)
|
|
.await
|
|
.expect("reboot call failed");
|
|
println!("Reboot triggered: {resp:?}");
|
|
|
|
println!("Waiting for firewall to go down...");
|
|
tokio::time::sleep(std::time::Duration::from_secs(10)).await;
|
|
|
|
// Poll until the firewall comes back
|
|
println!("Polling until firewall is back...");
|
|
for i in 0..120 {
|
|
tokio::time::sleep(std::time::Duration::from_secs(5)).await;
|
|
|
|
let result = client
|
|
.get_typed::<serde_json::Value>("core", "firmware", "status")
|
|
.await;
|
|
|
|
match result {
|
|
Ok(resp) => {
|
|
let version = resp["product"]["CORE_PKGVERSION"]
|
|
.as_str()
|
|
.unwrap_or("unknown");
|
|
println!("[{i:3}] Firewall is back! Version: {version}");
|
|
return;
|
|
}
|
|
Err(_) => {
|
|
if i % 6 == 0 {
|
|
println!("[{i:3}] Still waiting...");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
println!("Timed out waiting for firewall to come back.");
|
|
}
|