diff --git a/.gitattributes b/.gitattributes index c650d67..50e2ebb 100644 --- a/.gitattributes +++ b/.gitattributes @@ -3,6 +3,7 @@ *.sh text eol=lf *.yaml text eol=lf *.yml text eol=lf +*.tsv text eol=lf Dockerfile text eol=lf Caddyfile text eol=lf Makefile text eol=lf diff --git a/.github/openwrt-sdk-lock.tsv b/.github/openwrt-sdk-lock.tsv new file mode 100644 index 0000000..0f9f8d1 --- /dev/null +++ b/.github/openwrt-sdk-lock.tsv @@ -0,0 +1,29 @@ +# release target subtarget sha256 url +21.02.7 x86 64 21c75e4c5a429da487f8a885555cb49eee80cfc355d5dbe35d2b3ae05324a09d https://downloads.openwrt.org/releases/21.02.7/targets/x86/64/openwrt-sdk-21.02.7-x86-64_gcc-8.4.0_musl.Linux-x86_64.tar.xz +21.02.7 ramips mt7621 ceed7c1869a373b23ff2826ccce587723b0a0bcf8ce9bfa377557c705a41638a https://downloads.openwrt.org/releases/21.02.7/targets/ramips/mt7621/openwrt-sdk-21.02.7-ramips-mt7621_gcc-8.4.0_musl.Linux-x86_64.tar.xz +21.02.7 ath79 generic 71408b147f020dc6d9229f79e9d53219a3c9351034b0e07f073b2c5b22c4dd31 https://downloads.openwrt.org/releases/21.02.7/targets/ath79/generic/openwrt-sdk-21.02.7-ath79-generic_gcc-8.4.0_musl.Linux-x86_64.tar.xz +21.02.7 ipq40xx generic df6510f055ab90635aa0d80e6974df38f36c76a75dfa2aba027854a9a126002c https://downloads.openwrt.org/releases/21.02.7/targets/ipq40xx/generic/openwrt-sdk-21.02.7-ipq40xx-generic_gcc-8.4.0_musl_eabi.Linux-x86_64.tar.xz +21.02.7 bcm27xx bcm2711 267dd814860b0928429592dd1568fde6194ef44c80c16c384e4e8719859d9660 https://downloads.openwrt.org/releases/21.02.7/targets/bcm27xx/bcm2711/openwrt-sdk-21.02.7-bcm27xx-bcm2711_gcc-8.4.0_musl.Linux-x86_64.tar.xz +22.03.7 x86 64 a49b1269a4869eadafbd1a95c3822bbc3f968e9a6a6207deee68f117982e5630 https://downloads.openwrt.org/releases/22.03.7/targets/x86/64/openwrt-sdk-22.03.7-x86-64_gcc-11.2.0_musl.Linux-x86_64.tar.xz +22.03.7 ramips mt7621 f00548715d7ca6a461f6d62589ca5a12a628bbe8ca2102ef574438c2fd738e1b https://downloads.openwrt.org/releases/22.03.7/targets/ramips/mt7621/openwrt-sdk-22.03.7-ramips-mt7621_gcc-11.2.0_musl.Linux-x86_64.tar.xz +22.03.7 ath79 generic e57b3d029f6d75bc4535b820947e40c119231d7b4e03f0c0dc1901ac02ba39f3 https://downloads.openwrt.org/releases/22.03.7/targets/ath79/generic/openwrt-sdk-22.03.7-ath79-generic_gcc-11.2.0_musl.Linux-x86_64.tar.xz +22.03.7 ipq40xx generic 86c2ecf230a117cf80e378669e18c77e7a1188570d7ab365c545da5097101a88 https://downloads.openwrt.org/releases/22.03.7/targets/ipq40xx/generic/openwrt-sdk-22.03.7-ipq40xx-generic_gcc-11.2.0_musl_eabi.Linux-x86_64.tar.xz +22.03.7 bcm27xx bcm2711 1247676e8bb1852ef393785251a300ba4a40adb3a895dedbc0d6f6df2657a3d3 https://downloads.openwrt.org/releases/22.03.7/targets/bcm27xx/bcm2711/openwrt-sdk-22.03.7-bcm27xx-bcm2711_gcc-11.2.0_musl.Linux-x86_64.tar.xz +23.05.5 x86 64 9e5b6813a3f810123391f5f3ea10dfd1c14be1a880f410c70ec4424bbd1573d2 https://downloads.openwrt.org/releases/23.05.5/targets/x86/64/openwrt-sdk-23.05.5-x86-64_gcc-12.3.0_musl.Linux-x86_64.tar.xz +23.05.5 ramips mt7621 97ac89bcd590cf882bad8e027d893ab073959628b69e9e43829a2ccfb1e11e29 https://downloads.openwrt.org/releases/23.05.5/targets/ramips/mt7621/openwrt-sdk-23.05.5-ramips-mt7621_gcc-12.3.0_musl.Linux-x86_64.tar.xz +23.05.5 ath79 generic dc2ffaf036929630e3de601be2006829d57ed30d018ed4e9e71496bd75d9cbb6 https://downloads.openwrt.org/releases/23.05.5/targets/ath79/generic/openwrt-sdk-23.05.5-ath79-generic_gcc-12.3.0_musl.Linux-x86_64.tar.xz +23.05.5 ipq40xx generic 3c8140b6f6d6c8a6379872a1bdf0ea11ca3f37fc8fbb08ec7c1750efe6d58268 https://downloads.openwrt.org/releases/23.05.5/targets/ipq40xx/generic/openwrt-sdk-23.05.5-ipq40xx-generic_gcc-12.3.0_musl_eabi.Linux-x86_64.tar.xz +23.05.5 bcm27xx bcm2711 c766e01a31720e6428c0d4a47ddacf5057f97dfca583cfb49ce0563e33bc9dcf https://downloads.openwrt.org/releases/23.05.5/targets/bcm27xx/bcm2711/openwrt-sdk-23.05.5-bcm27xx-bcm2711_gcc-12.3.0_musl.Linux-x86_64.tar.xz +23.05.5 mediatek filogic dd55d11661a149bccd75383ba9e5632e3ab23b44912a7cf5c3b59d42c9352f8c https://downloads.openwrt.org/releases/23.05.5/targets/mediatek/filogic/openwrt-sdk-23.05.5-mediatek-filogic_gcc-12.3.0_musl.Linux-x86_64.tar.xz +24.10.7 x86 64 996d71f9eab7df2e8acb0bb2c9726426f05c10d419e5f9600d59b14d871f2acb https://downloads.openwrt.org/releases/24.10.7/targets/x86/64/openwrt-sdk-24.10.7-x86-64_gcc-13.3.0_musl.Linux-x86_64.tar.zst +24.10.7 ramips mt7621 014cd0f69b2b28088fd89e5b00e4f4d5087e2fe6da52cbaa48cd521087ebf10d https://downloads.openwrt.org/releases/24.10.7/targets/ramips/mt7621/openwrt-sdk-24.10.7-ramips-mt7621_gcc-13.3.0_musl.Linux-x86_64.tar.zst +24.10.7 ath79 generic 17e88fafcfb422d7cfbf3c0fa5a4daae984b7c0af80121a9ecd5bdd96c475383 https://downloads.openwrt.org/releases/24.10.7/targets/ath79/generic/openwrt-sdk-24.10.7-ath79-generic_gcc-13.3.0_musl.Linux-x86_64.tar.zst +24.10.7 ipq40xx generic d59c8d85f72541303e5e18eda353233abfdf6db1ba90f28c2514d7cacb58a265 https://downloads.openwrt.org/releases/24.10.7/targets/ipq40xx/generic/openwrt-sdk-24.10.7-ipq40xx-generic_gcc-13.3.0_musl_eabi.Linux-x86_64.tar.zst +24.10.7 bcm27xx bcm2711 c85ee387af7ed0505e7bb79aab3582b9c404d9e24b0e886b74219af84e8bc739 https://downloads.openwrt.org/releases/24.10.7/targets/bcm27xx/bcm2711/openwrt-sdk-24.10.7-bcm27xx-bcm2711_gcc-13.3.0_musl.Linux-x86_64.tar.zst +24.10.7 mediatek filogic 8d8fd6dd96458f6f397b069e3212c6dc365c306b0be32c95c9497b52d80b13df https://downloads.openwrt.org/releases/24.10.7/targets/mediatek/filogic/openwrt-sdk-24.10.7-mediatek-filogic_gcc-13.3.0_musl.Linux-x86_64.tar.zst +25.12.4 x86 64 28e004c1be4d215d19c1f12a6aa4c8d8f80689549eb707d0ff5a71f16fa8d05f https://downloads.openwrt.org/releases/25.12.4/targets/x86/64/openwrt-sdk-25.12.4-x86-64_gcc-14.3.0_musl.Linux-x86_64.tar.zst +25.12.4 ramips mt7621 03f4766fcfbae86a814cbbf194226fa7e9ec66be2d4273bc1a0927a72a43a333 https://downloads.openwrt.org/releases/25.12.4/targets/ramips/mt7621/openwrt-sdk-25.12.4-ramips-mt7621_gcc-14.3.0_musl.Linux-x86_64.tar.zst +25.12.4 ath79 generic 001468f22df86efd13344863b6fcd705e99e92a7c402ddaf69d82f1648c74850 https://downloads.openwrt.org/releases/25.12.4/targets/ath79/generic/openwrt-sdk-25.12.4-ath79-generic_gcc-14.3.0_musl.Linux-x86_64.tar.zst +25.12.4 ipq40xx generic 070e15aee4b7856bdb909a6092c99cf3a93d8657f93e2c9b3a08eb8dcbdddc08 https://downloads.openwrt.org/releases/25.12.4/targets/ipq40xx/generic/openwrt-sdk-25.12.4-ipq40xx-generic_gcc-14.3.0_musl_eabi.Linux-x86_64.tar.zst +25.12.4 bcm27xx bcm2711 7819901b8840899691cae27565999828a34069bc8c7efdfe4c263727bfd6e3d1 https://downloads.openwrt.org/releases/25.12.4/targets/bcm27xx/bcm2711/openwrt-sdk-25.12.4-bcm27xx-bcm2711_gcc-14.3.0_musl.Linux-x86_64.tar.zst +25.12.4 mediatek filogic 411a2277ca10f909c30275a506aab4dc28a4f1281d7fda4f19faaa2ded6630bb https://downloads.openwrt.org/releases/25.12.4/targets/mediatek/filogic/openwrt-sdk-25.12.4-mediatek-filogic_gcc-14.3.0_musl.Linux-x86_64.tar.zst diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index d8efb89..d24054b 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -119,30 +119,20 @@ jobs: SUBTARGET: ${{ matrix.subtarget }} run: | set -euo pipefail - relative="releases/${RELEASE}/targets/${TARGET}/${SUBTARGET}" - record="" - base_url="" - for mirror in https://downloads.openwrt.org https://archive.openwrt.org; do - candidate="${mirror}/${relative}" - if sums="$(curl --fail --location --silent --show-error "${candidate}/sha256sums" 2>/dev/null)"; then - record="$(printf '%s\n' "$sums" | awk ' - $2 ~ /^\*?openwrt-sdk-.*\.Linux-x86_64\.tar\.(xz|zst)$/ { - sub(/^\*/, "", $2); print $1 " " $2; exit - }')" - if [ -n "$record" ]; then - base_url="$candidate" - break - fi - fi - done + record="$(awk -F '\t' \ + -v release="$RELEASE" \ + -v target="$TARGET" \ + -v subtarget="$SUBTARGET" \ + '$1 == release && $2 == target && $3 == subtarget { print $4 " " $5; exit }' \ + .github/openwrt-sdk-lock.tsv)" if [ -z "$record" ]; then - echo "No SDK found for OpenWrt ${RELEASE} ${TARGET}/${SUBTARGET}" >&2 + echo "No locked SDK found for OpenWrt ${RELEASE} ${TARGET}/${SUBTARGET}" >&2 exit 1 fi - read -r sha256 filename <<<"$record" - echo "url=${base_url}/${filename}" >> "$GITHUB_OUTPUT" + read -r sha256 url <<<"$record" + echo "url=${url}" >> "$GITHUB_OUTPUT" echo "sha256=${sha256}" >> "$GITHUB_OUTPUT" - echo "Using ${base_url}/${filename}" + echo "Using locked SDK ${url}" - uses: docker/setup-buildx-action@v3 diff --git a/CHECKLIST.md b/CHECKLIST.md index 137c745..b1e7533 100644 --- a/CHECKLIST.md +++ b/CHECKLIST.md @@ -5,7 +5,7 @@ ## Работает сейчас - [x] Go server, SQLite/WAL, Docker/Compose и `/healthz`. -- [x] Go agent 0.6.1, heartbeat, команды, backoff и OpenWrt init integration. +- [x] Go agent 0.6.2, heartbeat, команды, backoff и OpenWrt init integration. - [x] APK/IPK и LuCI-пакет. - [x] Multi-user, роли admin/user, владение и передача роутеров. - [x] Профиль, e-mail, смена/сброс пароля и управление сессиями. diff --git a/ROADMAP.md b/ROADMAP.md index 88640dd..2084e8a 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -1,6 +1,6 @@ # OpenWrt RMM — актуальный roadmap -Актуализировано: 2026-07-23. Текущая стабильная линия агента: `0.6.1`. +Актуализировано: 2026-07-23. Текущая стабильная линия агента: `0.6.2`. ## Цель продукта diff --git a/agent/README.md b/agent/README.md index cd2b4da..8f63c9d 100644 --- a/agent/README.md +++ b/agent/README.md @@ -1,6 +1,6 @@ # OpenWrt RMM Agent -Current stable Go agent: `0.6.1`. It reports runtime health, pending command results, +Current stable Go agent: `0.6.2`. It reports runtime health, pending command results, and the last heartbeat transport error after connectivity is restored. Production Go agent for OpenWrt, with the shell implementation retained as a fallback runtime. diff --git a/agent/go/cmd/rmm-agent/main.go b/agent/go/cmd/rmm-agent/main.go index 18e4d3b..164040c 100644 --- a/agent/go/cmd/rmm-agent/main.go +++ b/agent/go/cmd/rmm-agent/main.go @@ -23,7 +23,7 @@ import ( "time" ) -const agentVersion = "0.6.1" +const agentVersion = "0.6.2" type agentRuntimeHealth struct { StartedAt time.Time diff --git a/agent/go/cmd/rmm-agent/main_test.go b/agent/go/cmd/rmm-agent/main_test.go index 75eec0d..09b0ef0 100644 --- a/agent/go/cmd/rmm-agent/main_test.go +++ b/agent/go/cmd/rmm-agent/main_test.go @@ -9,7 +9,7 @@ import ( ) func TestAgentVersionIsStable(t *testing.T) { - if agentVersion != "0.6.1" { + if agentVersion != "0.6.2" { t.Fatalf("unexpected agent version %q", agentVersion) } } diff --git a/agent/package/luci-app-rmm-agent/README.md b/agent/package/luci-app-rmm-agent/README.md index dce041c..30c0d99 100644 --- a/agent/package/luci-app-rmm-agent/README.md +++ b/agent/package/luci-app-rmm-agent/README.md @@ -67,7 +67,7 @@ application to the router. Do not copy or install the shell runtime at the same cd dist/rmm-openwrt-25.12.4-ramips-mt7621 sha256sum -c SHA256SUMS scp \ - rmm-agent-go-production-0.6.1-r2.apk \ + rmm-agent-go-production-0.6.2-r1.apk \ luci-app-rmm-agent-0.2.1-r2.apk \ root@ROUTER_IP:/tmp/ ``` @@ -76,7 +76,7 @@ Then install the locally built, unsigned packages over SSH: ```sh apk add --allow-untrusted \ - /tmp/rmm-agent-go-production-0.6.1-r2.apk \ + /tmp/rmm-agent-go-production-0.6.2-r1.apk \ /tmp/luci-app-rmm-agent-0.2.1-r2.apk /etc/init.d/rpcd restart /etc/init.d/uhttpd restart diff --git a/agent/package/rmm-agent-go-production/Makefile b/agent/package/rmm-agent-go-production/Makefile index 4a5cff9..c6f5da4 100644 --- a/agent/package/rmm-agent-go-production/Makefile +++ b/agent/package/rmm-agent-go-production/Makefile @@ -2,8 +2,8 @@ include $(TOPDIR)/rules.mk PKG_NAME:=rmm-agent-go-production -PKG_VERSION:=0.6.1 -PKG_RELEASE:=2 +PKG_VERSION:=0.6.2 +PKG_RELEASE:=1 PKG_MAINTAINER:=RMM OpenWrt PKG_LICENSE:=MIT diff --git a/agent/package/rmm-agent-go-production/README.md b/agent/package/rmm-agent-go-production/README.md index 7c3939e..1348543 100644 --- a/agent/package/rmm-agent-go-production/README.md +++ b/agent/package/rmm-agent-go-production/README.md @@ -34,5 +34,5 @@ opkg install /tmp/rmm-agent-go-production_*.ipk This package is intended for the final shell-to-Go migration when the router should keep the same RMM object identity. -Version `0.6.1` uses the cloud tunnel exclusively and no longer discovers or publishes the +Version `0.6.2` uses the cloud tunnel exclusively and no longer discovers or publishes the router's public WAN addresses. diff --git a/agent/package/rmm-agent-go/Makefile b/agent/package/rmm-agent-go/Makefile index 74d9c70..ca39cb4 100644 --- a/agent/package/rmm-agent-go/Makefile +++ b/agent/package/rmm-agent-go/Makefile @@ -2,8 +2,8 @@ include $(TOPDIR)/rules.mk PKG_NAME:=rmm-agent-go -PKG_VERSION:=0.6.1 -PKG_RELEASE:=2 +PKG_VERSION:=0.6.2 +PKG_RELEASE:=1 PKG_MAINTAINER:=RMM OpenWrt PKG_LICENSE:=MIT diff --git a/deploy/luci-builder/Dockerfile b/deploy/luci-builder/Dockerfile index 85d8b84..01911d5 100644 --- a/deploy/luci-builder/Dockerfile +++ b/deploy/luci-builder/Dockerfile @@ -57,6 +57,7 @@ RUN case "${OPENWRT_SDK_URL}" in \ *) echo "unsupported OpenWrt SDK URL: ${OPENWRT_SDK_URL}" >&2; exit 1 ;; \ esac \ && curl --fail --location --show-error --silent \ + --retry 5 --retry-all-errors --retry-delay 2 \ --output "${sdk_archive}" "${OPENWRT_SDK_URL}" \ && echo "${OPENWRT_SDK_SHA256} ${sdk_archive}" | sha256sum --check --strict \ && mkdir sdk \ diff --git a/docs/openwrt.md b/docs/openwrt.md index 2d05100..1417eed 100644 --- a/docs/openwrt.md +++ b/docs/openwrt.md @@ -143,8 +143,10 @@ The release matrix covers OpenWrt `21.02.7`, `22.03.7`, `23.05.5`, `24.10.7` and - Raspberry Pi 4 (`bcm27xx/bcm2711`, ARM64); - MediaTek Filogic (`mediatek/filogic`, ARM64) on supported releases. -The workflow resolves each SDK filename and SHA256 from the official OpenWrt mirror, -falling back to the OpenWrt archive for end-of-life branches. Releases through `24.10` +The workflow reads each official SDK URL and SHA256 from the reviewed +`.github/openwrt-sdk-lock.tsv` lock file. Updating an OpenWrt patch release requires +refreshing that file from the official `sha256sums`; Docker still verifies every SDK +archive before extraction and retries transient downloads. Releases through `24.10` produce `.ipk`; `25.12` produces `.apk`. Manual runs retain each target as a workflow artifact for 30 days. An `agent-v*` tag also creates a GitHub Release containing all packages and a combined `SHA256SUMS`, a Sigstore signature bundle and native signed package feeds. diff --git a/web/app.js b/web/app.js index 6d2476c..f9e226a 100644 --- a/web/app.js +++ b/web/app.js @@ -38,7 +38,7 @@ const state = { let eventSource = null; let liveRefreshTimer = null; -const EXPECTED_AGENT_VERSION = "0.6.1"; +const EXPECTED_AGENT_VERSION = "0.6.2"; const els = { loginView: document.querySelector("#loginView"),