75 lines
3.3 KiB
Rust
Raw Normal View History

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(())
}