Extend Red Bear runtime tooling

Red Bear OS Team
This commit is contained in:
2026-04-16 12:44:21 +01:00
parent c290fda6e5
commit 91323523a3
6 changed files with 1417 additions and 27 deletions
@@ -7,3 +7,11 @@ template = "cargo"
[package.files]
"/usr/bin/lspci" = "lspci"
"/usr/bin/lsusb" = "lsusb"
"/usr/bin/redbear-bluetooth-battery-check" = "redbear-bluetooth-battery-check"
"/usr/bin/redbear-phase4-wayland-check" = "redbear-phase4-wayland-check"
"/usr/bin/redbear-phase5-network-check" = "redbear-phase5-network-check"
"/usr/bin/redbear-phase5-wifi-check" = "redbear-phase5-wifi-check"
"/usr/bin/redbear-phase5-wifi-capture" = "redbear-phase5-wifi-capture"
"/usr/bin/redbear-phase5-wifi-run" = "redbear-phase5-wifi-run"
"/usr/bin/redbear-phase5-wifi-analyze" = "redbear-phase5-wifi-analyze"
"/usr/bin/redbear-phase5-wifi-link-check" = "redbear-phase5-wifi-link-check"
@@ -27,10 +27,34 @@ path = "src/bin/redbear-phase3-input-check.rs"
name = "redbear-phase4-wayland-check"
path = "src/bin/redbear-phase4-wayland-check.rs"
[[bin]]
name = "redbear-bluetooth-battery-check"
path = "src/bin/redbear-bluetooth-battery-check.rs"
[[bin]]
name = "redbear-phase5-network-check"
path = "src/bin/redbear-phase5-network-check.rs"
[[bin]]
name = "redbear-phase5-wifi-check"
path = "src/bin/redbear-phase5-wifi-check.rs"
[[bin]]
name = "redbear-phase5-wifi-capture"
path = "src/bin/redbear-phase5-wifi-capture.rs"
[[bin]]
name = "redbear-phase5-wifi-run"
path = "src/bin/redbear-phase5-wifi-run.rs"
[[bin]]
name = "redbear-phase5-wifi-analyze"
path = "src/bin/redbear-phase5-wifi-analyze.rs"
[[bin]]
name = "redbear-phase5-wifi-link-check"
path = "src/bin/redbear-phase5-wifi-link-check.rs"
[[bin]]
name = "redbear-phase6-kde-check"
path = "src/bin/redbear-phase6-kde-check.rs"
@@ -39,7 +63,12 @@ path = "src/bin/redbear-phase6-kde-check.rs"
name = "redbear-phase-iommu-check"
path = "src/bin/redbear-phase-iommu-check.rs"
[[bin]]
name = "redbear-phase-dma-check"
path = "src/bin/redbear-phase-dma-check.rs"
[dependencies]
serde = { version = "1", features = ["derive"] }
serde_json = "1"
orbclient = "0.3"
redox-driver-sys = { path = "../../../drivers/redox-driver-sys/source" }
@@ -15,6 +15,42 @@ fn require_path(path: &str) -> Result<(), String> {
}
}
fn require_wayland_smoke_marker() -> Result<(), String> {
for path in [
"/home/root/.qt6-bootstrap-minimal.ok",
"/home/root/.qt6-plugin-minimal.ok",
"/home/root/.qt6-wayland-smoke-minimal.ok",
"/home/root/.qt6-wayland-smoke-offscreen.ok",
"/home/root/.qt6-wayland-smoke-wayland.ok",
] {
let marker = Path::new(path);
if !marker.exists() {
return Err(format!(
"missing required Qt smoke marker {}",
marker.display()
));
}
println!("{}", marker.display());
}
let ok = Path::new("/home/root/.qt6-wayland-smoke.ok");
if ok.exists() {
println!("{}", ok.display());
println!("qt6-wayland-smoke");
return Ok(());
}
let err = Path::new("/home/root/.qt6-wayland-smoke.err");
if err.exists() {
return Err(format!(
"qt6-wayland-smoke marker missing; failure marker present at {}",
err.display()
));
}
Err("qt6-wayland-smoke did not leave a success marker".to_string())
}
fn run() -> Result<(), String> {
parse_args(PROGRAM, USAGE, std::env::args()).map_err(|err| {
if err.is_empty() {
@@ -27,16 +63,35 @@ fn run() -> Result<(), String> {
require_path("/usr/bin/orbital-wayland")?;
require_path("/usr/bin/wayland-session")?;
require_path("/usr/bin/smallvil")?;
require_path("/usr/bin/qt6-bootstrap-check")?;
require_path("/usr/bin/qt6-plugin-check")?;
require_path("/usr/bin/qt6-wayland-smoke")?;
require_path("/home/root/.wayland-session.started")?;
require_wayland_smoke_marker()?;
let status = Command::new("redbear-info")
.arg("--json")
.status()
.output()
.map_err(|err| format!("failed to run redbear-info --json: {err}"))?;
if status.success() {
Ok(())
return if status.status.success() {
let stdout = String::from_utf8_lossy(&status.stdout);
if stdout.contains("virtio_net_present") {
Ok(())
} else {
Err("redbear-info --json did not report virtio_net_present".to_string())
}
} else {
Err(format!("redbear-info exited with status {status}"))
}
let stderr = String::from_utf8_lossy(&status.stderr);
if stderr.trim().is_empty() {
Err(format!("redbear-info exited with status {}", status.status))
} else {
Err(format!(
"redbear-info exited with status {}: {}",
status.status,
stderr.trim()
))
}
};
}
fn main() {
@@ -2,6 +2,7 @@ use std::path::Path;
use std::process::{self, Command};
use redbear_hwutils::parse_args;
use serde_json::Value;
const PROGRAM: &str = "redbear-phase5-network-check";
const USAGE: &str = "Usage: redbear-phase5-network-check\n\nShow the installed Phase 5 networking/session plumbing surface inside the guest.";
@@ -15,6 +16,21 @@ fn require_path(path: &str) -> Result<(), String> {
}
}
fn require_json_field(value: &Value, field: &str) -> Result<(), String> {
if value.get(field).is_some() {
println!("{field}=present");
Ok(())
} else {
Err(format!("redbear-info --json did not report {field}"))
}
}
fn optional_require_path(path: &str, label: &str) {
if Path::new(path).exists() {
println!("{label}=present");
}
}
fn run() -> Result<(), String> {
parse_args(PROGRAM, USAGE, std::env::args()).map_err(|err| {
if err.is_empty() {
@@ -25,16 +41,108 @@ fn run() -> Result<(), String> {
println!("=== Red Bear OS Phase 5 Networking Check ===");
require_path("/usr/bin/dbus-daemon")?;
require_path("/usr/bin/netctl")?;
require_path("/usr/bin/redbear-wifictl")?;
let info_status = Command::new("redbear-info")
let info_output = Command::new("redbear-info")
.arg("--json")
.status()
.output()
.map_err(|err| format!("failed to run redbear-info --json: {err}"))?;
if !info_status.success() {
return Err(format!("redbear-info exited with status {info_status}"));
if !info_output.status.success() {
let stderr = String::from_utf8_lossy(&info_output.stderr);
if stderr.trim().is_empty() {
return Err(format!(
"redbear-info exited with status {}",
info_output.status
));
}
return Err(format!(
"redbear-info exited with status {}: {}",
info_output.status,
stderr.trim()
));
}
let info_stdout = String::from_utf8_lossy(&info_output.stdout);
let info_json: Value = serde_json::from_str(&info_stdout)
.map_err(|err| format!("failed to parse redbear-info --json output: {err}"))?;
if info_stdout.contains("virtio_net_present") {
println!("virtio_net_present");
} else {
return Err("redbear-info --json did not report virtio_net_present".to_string());
}
let network = info_json
.get("network")
.ok_or_else(|| "redbear-info --json did not include network section".to_string())?;
require_json_field(network, "wifi_control_state")?;
require_json_field(network, "wifi_connect_result")?;
require_json_field(network, "wifi_disconnect_result")?;
let _ = Command::new("netctl").arg("status").status();
let wifictl_output = Command::new("redbear-wifictl")
.arg("--probe")
.output()
.map_err(|err| format!("failed to run redbear-wifictl --probe: {err}"))?;
if !wifictl_output.status.success() {
return Err(format!(
"redbear-wifictl --probe exited with status {}",
wifictl_output.status
));
}
let wifictl_stdout = String::from_utf8_lossy(&wifictl_output.stdout);
if wifictl_stdout.contains("interfaces=") {
println!("WIFICTL_INTERFACES=present");
} else {
return Err("redbear-wifictl --probe did not report interfaces=".to_string());
}
if wifictl_stdout.contains("capabilities=") {
println!("WIFICTL_CAPABILITIES=present");
} else {
return Err("redbear-wifictl --probe did not report capabilities=".to_string());
}
let wifi_check_output = Command::new("redbear-phase5-wifi-check")
.output()
.map_err(|err| format!("failed to run redbear-phase5-wifi-check: {err}"))?;
if !wifi_check_output.status.success() {
let stderr = String::from_utf8_lossy(&wifi_check_output.stderr);
if stderr.trim().is_empty() {
return Err(format!(
"redbear-phase5-wifi-check exited with status {}",
wifi_check_output.status
));
}
return Err(format!(
"redbear-phase5-wifi-check exited with status {}: {}",
wifi_check_output.status,
stderr.trim()
));
}
let wifi_check_stdout = String::from_utf8_lossy(&wifi_check_output.stdout);
if wifi_check_stdout.contains("PASS: bounded Intel Wi-Fi runtime path exercised on target") {
println!("PHASE5_WIFI_CHECK=pass");
} else {
return Err(
"redbear-phase5-wifi-check did not report bounded Wi-Fi runtime success".to_string(),
);
}
if let Ok(ifaces) = std::fs::read_dir("/scheme/wifictl/ifaces") {
for entry in ifaces.flatten() {
let iface = entry.file_name().to_string_lossy().into_owned();
optional_require_path(
&format!("/scheme/wifictl/ifaces/{iface}/connect-result"),
"WIFICTL_CONNECT_RESULT_NODE",
);
optional_require_path(
&format!("/scheme/wifictl/ifaces/{iface}/disconnect-result"),
"WIFICTL_DISCONNECT_RESULT_NODE",
);
}
}
if Path::new("/run/dbus/system_bus_socket").exists() {
println!("DBUS_SYSTEM_BUS=present");
} else {
@@ -49,3 +157,20 @@ fn main() {
process::exit(1);
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn require_json_field_accepts_present_key() {
let value: Value = serde_json::json!({"wifi_connect_result": "unknown"});
assert!(require_json_field(&value, "wifi_connect_result").is_ok());
}
#[test]
fn require_json_field_rejects_missing_key() {
let value: Value = serde_json::json!({"wifi_control_state": "present"});
assert!(require_json_field(&value, "wifi_connect_result").is_err());
}
}
File diff suppressed because it is too large Load Diff
+13 -4
View File
@@ -6,7 +6,10 @@
# - redbear-release: Branding and identity (os-release, hostname, motd)
# - redox-driver-sys: Safe Rust driver infrastructure crate
# - linux-kpi: Linux Kernel Programming Interface compatibility layer
# - firmware-loader: AMD/Intel GPU firmware loading daemon
# - redbear-iwlwifi: bounded Intel Wi-Fi driver-side package
# - redbear-firmware: Linux-firmware-derived firmware bundle
# - firmware-loader: firmware loading daemon used by GPU and Wi-Fi bring-up
# - redbear-wifictl: Wi-Fi control daemon and scheme
# - redox-drm: DRM display driver (AMD + Intel)
# - evdevd: Event device daemon (input translation)
# - udev-shim: udev-compatible device enumeration shim
@@ -27,9 +30,12 @@ This package depends on all core Red Bear OS components.
Installed components:
- redbear-release: OS branding and identity
- redox-driver-sys: Driver infrastructure
- linux-kpi: Linux kernel API compatibility
- firmware-loader: GPU firmware daemon
- redox-driver-sys: Driver infrastructure
- linux-kpi: Linux kernel API compatibility
- redbear-iwlwifi: Intel Wi-Fi driver-side package
- redbear-firmware: Firmware bundle
- firmware-loader: firmware daemon
- redbear-wifictl: Wi-Fi control plane
- redox-drm: DRM display driver (AMD + Intel)
- evdevd: Input event translation
- udev-shim: Device enumeration
@@ -45,8 +51,11 @@ dependencies = [
"redbear-release",
"redox-driver-sys",
"linux-kpi",
"redbear-iwlwifi",
"redbear-firmware",
"redox-drm",
"firmware-loader",
"redbear-wifictl",
"evdevd",
"udev-shim",
]