From 5d82e6ff8d592ee1748e2511baf2c9b0e2daf771 Mon Sep 17 00:00:00 2001 From: ssmithx Date: Mon, 29 Jun 2026 14:02:53 +0000 Subject: [PATCH] fix(openwrt): bootstrap opkg via apk on OpenWrt 25.x routers OpenWrt 25.x switched from opkg to apk as the default package manager, so devices like the Cudy TR1200 on 25.12.4 don't have /usr/bin/opkg. When opkg is missing but apk is present, install opkg through apk first so the rest of the provisioning flow can proceed unchanged. Co-Authored-By: Claude Sonnet 4.6 --- core/openwrt/src/opkg.rs | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/core/openwrt/src/opkg.rs b/core/openwrt/src/opkg.rs index 6f66e0a7..c7865dee 100644 --- a/core/openwrt/src/opkg.rs +++ b/core/openwrt/src/opkg.rs @@ -4,16 +4,24 @@ use tracing::info; use crate::Router; impl Router { - /// Verify opkg is available, returning a clear error if not. + /// Verify opkg is available. On OpenWrt 25.x+ which ships apk instead of + /// opkg, bootstraps opkg via `apk add opkg` before returning. pub fn opkg_check(&self) -> Result<()> { let (_, code) = self.run("test -x /usr/bin/opkg")?; - if code != 0 { - anyhow::bail!( - "opkg not found at /usr/bin/opkg — this router's firmware may not \ - support package management (TollGate requires a standard OpenWrt build)" - ); + if code == 0 { + return Ok(()); } - Ok(()) + // OpenWrt 25.x switched to apk as default — install opkg through it. + let (_, apk_code) = self.run("test -x /usr/bin/apk")?; + if apk_code == 0 { + info!("[{}] opkg not found, bootstrapping via apk", self.host); + self.run_ok("/usr/bin/apk add opkg")?; + return Ok(()); + } + anyhow::bail!( + "opkg not found at /usr/bin/opkg — this router's firmware may not \ + support package management (TollGate requires a standard OpenWrt build)" + ); } /// `opkg update` — refresh package lists.