fix(openwrt): detect opkg silent failure and show disk space error

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>
This commit is contained in:
ssmithx 2026-06-29 01:41:36 +00:00
parent f69fac627a
commit 4c56e1bb96
2 changed files with 23 additions and 1 deletions

View File

@ -66,6 +66,9 @@ pub(super) fn sanitize_error_message(msg: &str) -> String {
"Bitcoin address",
"No router",
"No OpenWrt",
"No space left",
"TollGate installation failed",
"No pre-built TollGate",
];
for prefix in &user_facing_prefixes {
if msg.starts_with(prefix) {

View File

@ -48,8 +48,27 @@ pub fn install_tollgate(router: &Router) -> Result<()> {
info!("[{}] Downloading TollGate for {} from GitHub releases", router.host, arch);
router.run_ok(&format!("wget -O /tmp/tollgate.ipk '{}'", url))?;
router.run_ok("opkg install --force-depends /tmp/tollgate.ipk")?;
// 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(())
}