BusyBox opkg exits 0 even when 'Cannot install' due to insufficient space, causing the fallback to silently report success. Now captures stderr and checks for the failure string explicitly. Adds user-visible error for the common case where the router flash is too small for the TollGate package (~19 MB needed vs ~9 MB available on typical budget routers). Adds error prefixes to the RPC sanitizer allowlist so the message reaches the UI instead of showing 'Check server logs'. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
75 lines
3.3 KiB
Rust
75 lines
3.3 KiB
Rust
use anyhow::Result;
|
|
use tracing::info;
|
|
|
|
use crate::Router;
|
|
|
|
/// The OpenWrt package name for the TollGate reference implementation.
|
|
const TOLLGATE_PACKAGE: &str = "tollgate-module-basic-go";
|
|
|
|
/// Direct-download fallback URLs by opkg architecture string.
|
|
/// Used when the package is not in any configured feed.
|
|
/// Source: https://github.com/OpenTollGate/tollgate-module-basic-go/releases/tag/v0.2.0
|
|
fn ipk_url(arch: &str) -> Option<&'static str> {
|
|
match arch {
|
|
"mips_24kc" => Some("https://github.com/OpenTollGate/tollgate-module-basic-go/releases/download/v0.2.0/mips_24kc.ipk"),
|
|
"mipsel_24kc" => Some("https://github.com/OpenTollGate/tollgate-module-basic-go/releases/download/v0.2.0/mipsel_24kc.ipk"),
|
|
"aarch64_cortex-a53" => Some("https://github.com/OpenTollGate/tollgate-module-basic-go/releases/download/v0.2.0/aarch64_cortex-a53.ipk"),
|
|
"aarch64_cortex-a72" => Some("https://github.com/OpenTollGate/tollgate-module-basic-go/releases/download/v0.2.0/aarch64_cortex-a72.ipk"),
|
|
"arm_cortex-a7" => Some("https://github.com/OpenTollGate/tollgate-module-basic-go/releases/download/v0.2.0/arm_cortex-a7.ipk"),
|
|
_ => None,
|
|
}
|
|
}
|
|
|
|
/// Install tollgate-module-basic-go.
|
|
///
|
|
/// Tries opkg first (works if a custom feed is configured). Falls back to
|
|
/// downloading the .ipk directly from GitHub releases if opkg can't find it.
|
|
/// Caller is responsible for running `opkg_update` first.
|
|
pub fn install_tollgate(router: &Router) -> Result<()> {
|
|
info!("[{}] Installing {}", router.host, TOLLGATE_PACKAGE);
|
|
|
|
// Fast path: standard opkg install (or already installed).
|
|
if router.opkg_install(TOLLGATE_PACKAGE).is_ok() {
|
|
return Ok(());
|
|
}
|
|
|
|
// Package not in any feed — download the .ipk directly.
|
|
let arch = router
|
|
.run_ok("opkg print-architecture | grep -v 'all\\|noarch' | tail -1 | awk '{print $2}'")?;
|
|
let arch = arch.trim();
|
|
|
|
let url = ipk_url(arch).ok_or_else(|| {
|
|
anyhow::anyhow!(
|
|
"No pre-built TollGate package for architecture '{}'. \
|
|
Add a custom opkg feed or build from source.",
|
|
arch
|
|
)
|
|
})?;
|
|
|
|
info!("[{}] Downloading TollGate for {} from GitHub releases", router.host, arch);
|
|
router.run_ok(&format!("wget -O /tmp/tollgate.ipk '{}'", url))?;
|
|
|
|
// Capture stderr too — BusyBox opkg exits 0 even on "Cannot install" failures.
|
|
let (out, _code) = router.run("opkg install --force-depends /tmp/tollgate.ipk 2>&1")?;
|
|
router.run_ok("rm -f /tmp/tollgate.ipk")?;
|
|
|
|
if out.contains("Cannot install") || out.contains("errors encountered") {
|
|
if out.contains("Only have") && out.contains("available on filesystem") {
|
|
// Extract the sizes from the error for a user-readable message.
|
|
// Example: "Only have 8884kb available on filesystem /overlay, pkg tollgate-wrt needs 18750"
|
|
anyhow::bail!(
|
|
"No space left on router for TollGate ({}). \
|
|
This router has insufficient flash storage. \
|
|
Consider a router with ≥32 MB flash or add an extroot USB drive.",
|
|
out.lines()
|
|
.find(|l| l.contains("Only have"))
|
|
.unwrap_or("check router disk space")
|
|
.trim()
|
|
);
|
|
}
|
|
anyhow::bail!("TollGate installation failed: {}", out.trim());
|
|
}
|
|
|
|
Ok(())
|
|
}
|