build: split current and legacy OpenWrt packages
This commit is contained in:
@@ -0,0 +1,256 @@
|
||||
name: Build legacy OpenWrt packages
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
agent_tag:
|
||||
description: Existing agent release tag to extend (for example agent-v0.6.6)
|
||||
required: true
|
||||
type: string
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
concurrency:
|
||||
group: legacy-packages-${{ inputs.agent_tag }}
|
||||
cancel-in-progress: false
|
||||
|
||||
jobs:
|
||||
validate:
|
||||
name: Validate agent release
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
ref: ${{ inputs.agent_tag }}
|
||||
- name: Validate tag and package version
|
||||
env:
|
||||
AGENT_TAG: ${{ inputs.agent_tag }}
|
||||
GH_TOKEN: ${{ github.token }}
|
||||
shell: bash
|
||||
run: |
|
||||
set -euo pipefail
|
||||
if [[ ! "$AGENT_TAG" =~ ^agent-v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
|
||||
echo "agent_tag must look like agent-vMAJOR.MINOR.PATCH" >&2
|
||||
exit 1
|
||||
fi
|
||||
agent_version="${AGENT_TAG#agent-v}"
|
||||
source_version="$(sed -n 's/^const agentVersion = "\([^"]*\)"/\1/p' agent/go/cmd/rmm-agent/main.go)"
|
||||
package_version="$(sed -n 's/^PKG_VERSION:=//p' agent/package/rmm-agent-go-production/Makefile)"
|
||||
test "$source_version" = "$agent_version"
|
||||
test "$package_version" = "$agent_version"
|
||||
gh release view "$AGENT_TAG" --repo "$GITHUB_REPOSITORY" >/dev/null
|
||||
latest_agent_tag="$(gh api \
|
||||
"repos/${GITHUB_REPOSITORY}/releases?per_page=100" \
|
||||
--jq '[.[] | select(.draft == false and .prerelease == false and (.tag_name | startswith("agent-v")))] | first | .tag_name')"
|
||||
if [ "$AGENT_TAG" != "$latest_agent_tag" ]; then
|
||||
echo "legacy packages may extend only the latest agent release: ${latest_agent_tag}" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
legacy-packages:
|
||||
name: OpenWrt ${{ matrix.release }} · ${{ matrix.label }}
|
||||
needs: validate
|
||||
runs-on: ubuntu-24.04
|
||||
timeout-minutes: 90
|
||||
strategy:
|
||||
fail-fast: false
|
||||
max-parallel: 4
|
||||
matrix:
|
||||
include:
|
||||
# Legacy support intentionally excludes bcm27xx/bcm2711. It can be
|
||||
# restored as an on-demand row when a real supported device needs it.
|
||||
- { release: "21.02.7", target: x86, subtarget: "64", label: x86-64, goarch: amd64 }
|
||||
- { release: "21.02.7", target: ramips, subtarget: mt7621, label: ramips-mt7621, goarch: mipsle, gomips: softfloat }
|
||||
- { release: "21.02.7", target: ath79, subtarget: generic, label: ath79-generic, goarch: mips, gomips: softfloat }
|
||||
- { release: "21.02.7", target: ipq40xx, subtarget: generic, label: ipq40xx-generic, goarch: arm, goarm: "7" }
|
||||
|
||||
- { release: "22.03.7", target: x86, subtarget: "64", label: x86-64, goarch: amd64 }
|
||||
- { release: "22.03.7", target: ramips, subtarget: mt7621, label: ramips-mt7621, goarch: mipsle, gomips: softfloat }
|
||||
- { release: "22.03.7", target: ath79, subtarget: generic, label: ath79-generic, goarch: mips, gomips: softfloat }
|
||||
- { release: "22.03.7", target: ipq40xx, subtarget: generic, label: ipq40xx-generic, goarch: arm, goarm: "7" }
|
||||
|
||||
- { release: "23.05.5", target: x86, subtarget: "64", label: x86-64, goarch: amd64 }
|
||||
- { release: "23.05.5", target: ramips, subtarget: mt7621, label: ramips-mt7621, goarch: mipsle, gomips: softfloat }
|
||||
- { release: "23.05.5", target: ath79, subtarget: generic, label: ath79-generic, goarch: mips, gomips: softfloat }
|
||||
- { release: "23.05.5", target: ipq40xx, subtarget: generic, label: ipq40xx-generic, goarch: arm, goarm: "7" }
|
||||
- { release: "23.05.5", target: mediatek, subtarget: filogic, label: mediatek-filogic, goarch: arm64 }
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
ref: ${{ inputs.agent_tag }}
|
||||
|
||||
- name: Resolve official OpenWrt SDK
|
||||
id: sdk
|
||||
shell: bash
|
||||
env:
|
||||
RELEASE: ${{ matrix.release }}
|
||||
TARGET: ${{ matrix.target }}
|
||||
SUBTARGET: ${{ matrix.subtarget }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
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 locked SDK found for OpenWrt ${RELEASE} ${TARGET}/${SUBTARGET}" >&2
|
||||
exit 1
|
||||
fi
|
||||
read -r sha256 url <<<"$record"
|
||||
echo "url=${url}" >> "$GITHUB_OUTPUT"
|
||||
echo "sha256=${sha256}" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- uses: docker/setup-buildx-action@v3
|
||||
|
||||
- name: Build signed agent and LuCI packages
|
||||
uses: docker/build-push-action@v6
|
||||
env:
|
||||
OPENWRT_USIGN_SECRET_B64: ${{ secrets.OPENWRT_USIGN_SECRET_B64 }}
|
||||
with:
|
||||
context: .
|
||||
file: deploy/luci-builder/Dockerfile
|
||||
target: artifacts
|
||||
push: false
|
||||
outputs: type=local,dest=artifacts
|
||||
build-args: |
|
||||
OPENWRT_SDK_URL=${{ steps.sdk.outputs.url }}
|
||||
OPENWRT_SDK_SHA256=${{ steps.sdk.outputs.sha256 }}
|
||||
RMM_GOARCH=${{ matrix.goarch }}
|
||||
RMM_GOARM=${{ matrix.goarm || '7' }}
|
||||
RMM_GOMIPS=${{ matrix.gomips || 'softfloat' }}
|
||||
RMM_GOAMD64=v1
|
||||
REQUIRE_NATIVE_SIGNATURE=true
|
||||
REPOSITORY_INDEX_REVISION=${{ github.run_id }}
|
||||
secret-envs: |
|
||||
openwrt_usign_secret_b64=OPENWRT_USIGN_SECRET_B64
|
||||
cache-from: type=gha,scope=openwrt-${{ matrix.release }}-${{ matrix.label }}
|
||||
cache-to: type=gha,mode=max,scope=openwrt-${{ matrix.release }}-${{ matrix.label }}
|
||||
|
||||
- name: Verify package artifacts
|
||||
shell: bash
|
||||
run: |
|
||||
set -euo pipefail
|
||||
find artifacts -maxdepth 1 -type f -print
|
||||
test -f artifacts/SHA256SUMS
|
||||
(cd artifacts && sha256sum --check SHA256SUMS)
|
||||
find artifacts -maxdepth 1 -type f -name '*.ipk' -print -quit | grep -q .
|
||||
test -f artifacts/Packages
|
||||
test -f artifacts/Packages.gz
|
||||
test -f artifacts/Packages.sig
|
||||
public_key="$(find artifacts -maxdepth 1 -type f -regextype posix-extended \
|
||||
-regex '.*/[0-9a-f]{16}' -print -quit)"
|
||||
test -n "$public_key"
|
||||
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: openwrt-${{ matrix.release }}-${{ matrix.label }}
|
||||
path: artifacts/*
|
||||
if-no-files-found: error
|
||||
retention-days: 30
|
||||
|
||||
publish:
|
||||
name: Extend release and signed package repository
|
||||
needs: [validate, legacy-packages]
|
||||
runs-on: ubuntu-24.04
|
||||
permissions:
|
||||
contents: write
|
||||
id-token: write
|
||||
attestations: write
|
||||
pages: write
|
||||
environment:
|
||||
name: github-pages
|
||||
url: ${{ steps.deployment.outputs.page_url }}
|
||||
steps:
|
||||
# Repository tooling comes from the default branch so an existing
|
||||
# agent tag can be extended after this workflow itself was introduced.
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
ref: ${{ github.event.repository.default_branch }}
|
||||
|
||||
- uses: actions/download-artifact@v4
|
||||
with:
|
||||
pattern: openwrt-*
|
||||
path: legacy-artifacts
|
||||
|
||||
- name: Prepare legacy release assets
|
||||
shell: bash
|
||||
run: |
|
||||
set -euo pipefail
|
||||
mkdir legacy-publish
|
||||
while IFS= read -r file; do
|
||||
artifact="$(basename "$(dirname "$file")")"
|
||||
cp "$file" "legacy-publish/${artifact}-$(basename "$file")"
|
||||
done < <(find legacy-artifacts -type f ! -name 'SHA256SUMS' -print | sort)
|
||||
|
||||
- name: Attest legacy release assets
|
||||
uses: actions/attest-build-provenance@v2
|
||||
with:
|
||||
subject-path: legacy-publish/*
|
||||
|
||||
- name: Combine and reconstruct all release package artifacts
|
||||
env:
|
||||
AGENT_TAG: ${{ inputs.agent_tag }}
|
||||
GH_TOKEN: ${{ github.token }}
|
||||
shell: bash
|
||||
run: |
|
||||
set -euo pipefail
|
||||
mkdir release-assets
|
||||
gh release download "$AGENT_TAG" \
|
||||
--repo "$GITHUB_REPOSITORY" \
|
||||
--pattern 'openwrt-*' \
|
||||
--dir release-assets
|
||||
cp legacy-publish/* release-assets/
|
||||
bash scripts/unpack-release-package-assets.sh \
|
||||
release-assets \
|
||||
.github/openwrt-sdk-lock.tsv \
|
||||
combined-artifacts
|
||||
bash scripts/prepare-package-repository.sh \
|
||||
combined-artifacts \
|
||||
package-repository \
|
||||
"${AGENT_TAG#agent-v}"
|
||||
|
||||
- uses: sigstore/cosign-installer@v3
|
||||
|
||||
- name: Prepare combined release checksums
|
||||
shell: bash
|
||||
run: |
|
||||
set -euo pipefail
|
||||
(
|
||||
cd release-assets
|
||||
sha256sum ./openwrt-* > SHA256SUMS
|
||||
)
|
||||
|
||||
- name: Attest combined release checksums
|
||||
uses: actions/attest-build-provenance@v2
|
||||
with:
|
||||
subject-path: release-assets/SHA256SUMS
|
||||
|
||||
- name: Sign and upload combined release checksums
|
||||
env:
|
||||
AGENT_TAG: ${{ inputs.agent_tag }}
|
||||
GH_TOKEN: ${{ github.token }}
|
||||
shell: bash
|
||||
run: |
|
||||
set -euo pipefail
|
||||
cosign sign-blob --yes \
|
||||
--bundle release-assets/SHA256SUMS.sigstore.json \
|
||||
release-assets/SHA256SUMS
|
||||
mapfile -t legacy_files < <(find legacy-publish -type f -print | sort)
|
||||
gh release upload "$AGENT_TAG" \
|
||||
"${legacy_files[@]}" \
|
||||
release-assets/SHA256SUMS \
|
||||
release-assets/SHA256SUMS.sigstore.json \
|
||||
--repo "$GITHUB_REPOSITORY" \
|
||||
--clobber
|
||||
|
||||
- uses: actions/upload-pages-artifact@v3
|
||||
with:
|
||||
path: package-repository
|
||||
|
||||
- name: Deploy complete package repository to GitHub Pages
|
||||
id: deployment
|
||||
uses: actions/deploy-pages@v4
|
||||
+35
-24
@@ -55,6 +55,38 @@ jobs:
|
||||
grep -Eq '^[[:space:]]*DEPENDS:=.*[[:space:]]\+ip([[:space:]]|$)' "$file"
|
||||
! grep -Eq '\+ip-(tiny|full)' "$file"
|
||||
done
|
||||
- name: Verify package release support tiers
|
||||
shell: bash
|
||||
run: |
|
||||
set -euo pipefail
|
||||
bash -n \
|
||||
scripts/prepare-package-repository.sh \
|
||||
scripts/unpack-release-package-assets.sh
|
||||
|
||||
current_matrix="$(awk '
|
||||
/Tagged releases cover the current OpenWrt lines/ { in_matrix = 1 }
|
||||
in_matrix && /^[[:space:]]*- \{ release:/ { count++ }
|
||||
in_matrix && /^[[:space:]]*steps:/ { print count; exit }
|
||||
' .github/workflows/build.yml)"
|
||||
legacy_matrix="$(awk '
|
||||
/Legacy support intentionally excludes/ { in_matrix = 1 }
|
||||
in_matrix && /^[[:space:]]*- \{ release:/ { count++ }
|
||||
in_matrix && /^[[:space:]]*steps:/ { print count; exit }
|
||||
' .github/workflows/build-legacy.yml)"
|
||||
test "$current_matrix" = 10
|
||||
test "$legacy_matrix" = 13
|
||||
|
||||
fixture="$(mktemp -d)"
|
||||
trap 'rm -rf "$fixture"' EXIT
|
||||
mkdir -p "$fixture/assets"
|
||||
touch "$fixture/assets/openwrt-24.10.7-ramips-mt7621-Packages"
|
||||
touch "$fixture/assets/openwrt-21.02.7-x86-64-rmm-agent.ipk"
|
||||
bash scripts/unpack-release-package-assets.sh \
|
||||
"$fixture/assets" \
|
||||
.github/openwrt-sdk-lock.tsv \
|
||||
"$fixture/output"
|
||||
test -f "$fixture/output/openwrt-24.10.7-ramips-mt7621/Packages"
|
||||
test -f "$fixture/output/openwrt-21.02.7-x86-64/rmm-agent.ipk"
|
||||
|
||||
openwrt-packages:
|
||||
name: OpenWrt ${{ matrix.release }} · ${{ matrix.label }}
|
||||
@@ -67,40 +99,19 @@ jobs:
|
||||
max-parallel: 4
|
||||
matrix:
|
||||
include:
|
||||
# The matrix covers the common CPU families: amd64, mipsel, mips,
|
||||
# ARMv7 and ARM64. Add a target/subtarget row when another device
|
||||
# family needs an architecture-specific package.
|
||||
- { release: "21.02.7", target: x86, subtarget: "64", label: x86-64, goarch: amd64 }
|
||||
- { release: "21.02.7", target: ramips, subtarget: mt7621, label: ramips-mt7621, goarch: mipsle, gomips: softfloat }
|
||||
- { release: "21.02.7", target: ath79, subtarget: generic, label: ath79-generic, goarch: mips, gomips: softfloat }
|
||||
- { release: "21.02.7", target: ipq40xx, subtarget: generic, label: ipq40xx-generic, goarch: arm, goarm: "7" }
|
||||
- { release: "21.02.7", target: bcm27xx, subtarget: bcm2711, label: bcm27xx-bcm2711, goarch: arm64 }
|
||||
|
||||
- { release: "22.03.7", target: x86, subtarget: "64", label: x86-64, goarch: amd64 }
|
||||
- { release: "22.03.7", target: ramips, subtarget: mt7621, label: ramips-mt7621, goarch: mipsle, gomips: softfloat }
|
||||
- { release: "22.03.7", target: ath79, subtarget: generic, label: ath79-generic, goarch: mips, gomips: softfloat }
|
||||
- { release: "22.03.7", target: ipq40xx, subtarget: generic, label: ipq40xx-generic, goarch: arm, goarm: "7" }
|
||||
- { release: "22.03.7", target: bcm27xx, subtarget: bcm2711, label: bcm27xx-bcm2711, goarch: arm64 }
|
||||
|
||||
- { release: "23.05.5", target: x86, subtarget: "64", label: x86-64, goarch: amd64 }
|
||||
- { release: "23.05.5", target: ramips, subtarget: mt7621, label: ramips-mt7621, goarch: mipsle, gomips: softfloat }
|
||||
- { release: "23.05.5", target: ath79, subtarget: generic, label: ath79-generic, goarch: mips, gomips: softfloat }
|
||||
- { release: "23.05.5", target: ipq40xx, subtarget: generic, label: ipq40xx-generic, goarch: arm, goarm: "7" }
|
||||
- { release: "23.05.5", target: bcm27xx, subtarget: bcm2711, label: bcm27xx-bcm2711, goarch: arm64 }
|
||||
- { release: "23.05.5", target: mediatek, subtarget: filogic, label: mediatek-filogic, goarch: arm64 }
|
||||
|
||||
# Tagged releases cover the current OpenWrt lines and the common
|
||||
# router CPU families. OpenWrt 21.02-23.05 are built on demand by
|
||||
# build-legacy.yml so a legacy SDK cannot block the main release.
|
||||
- { release: "24.10.7", target: x86, subtarget: "64", label: x86-64, goarch: amd64 }
|
||||
- { release: "24.10.7", target: ramips, subtarget: mt7621, label: ramips-mt7621, goarch: mipsle, gomips: softfloat }
|
||||
- { release: "24.10.7", target: ath79, subtarget: generic, label: ath79-generic, goarch: mips, gomips: softfloat }
|
||||
- { release: "24.10.7", target: ipq40xx, subtarget: generic, label: ipq40xx-generic, goarch: arm, goarm: "7" }
|
||||
- { release: "24.10.7", target: bcm27xx, subtarget: bcm2711, label: bcm27xx-bcm2711, goarch: arm64 }
|
||||
- { release: "24.10.7", target: mediatek, subtarget: filogic, label: mediatek-filogic, goarch: arm64 }
|
||||
|
||||
- { release: "25.12.4", target: x86, subtarget: "64", label: x86-64, goarch: amd64 }
|
||||
- { release: "25.12.4", target: ramips, subtarget: mt7621, label: ramips-mt7621, goarch: mipsle, gomips: softfloat }
|
||||
- { release: "25.12.4", target: ath79, subtarget: generic, label: ath79-generic, goarch: mips, gomips: softfloat }
|
||||
- { release: "25.12.4", target: ipq40xx, subtarget: generic, label: ipq40xx-generic, goarch: arm, goarm: "7" }
|
||||
- { release: "25.12.4", target: bcm27xx, subtarget: bcm2711, label: bcm27xx-bcm2711, goarch: arm64 }
|
||||
- { release: "25.12.4", target: mediatek, subtarget: filogic, label: mediatek-filogic, goarch: arm64 }
|
||||
|
||||
steps:
|
||||
|
||||
+6
-4
@@ -1,12 +1,13 @@
|
||||
# Актуальный инженерный checklist
|
||||
|
||||
Синхронизировано с кодом 2026-07-23. Источник продуктового порядка — `ROADMAP.md`.
|
||||
Синхронизировано с кодом 2026-07-30. Источник продуктового порядка — `ROADMAP.md`.
|
||||
|
||||
## Работает сейчас
|
||||
|
||||
- [x] Go server, SQLite/WAL, Docker/Compose и `/healthz`.
|
||||
- [x] Go agent 0.6.5, heartbeat, команды, backoff и OpenWrt init integration.
|
||||
- [x] APK/IPK и LuCI-пакет.
|
||||
- [x] Go agent 0.6.6, heartbeat, команды, backoff и OpenWrt init integration.
|
||||
- [x] APK/IPK и LuCI-пакет: OpenWrt 24.10/25.12 в основном релизе,
|
||||
OpenWrt 21.02/22.03/23.05 в ручном legacy workflow.
|
||||
- [x] Multi-user, роли admin/user, владение и передача роутеров.
|
||||
- [x] Профиль, e-mail, смена/сброс пароля и управление сессиями.
|
||||
- [x] Одноразовый secure enrollment; reusable token secrets хранятся как hash.
|
||||
@@ -43,7 +44,8 @@
|
||||
- [ ] Подписанный webhook channel.
|
||||
- [ ] Quiet hours/timezone и per-device notification overrides.
|
||||
- [ ] Конфигурационные backup artifacts и retention.
|
||||
- [x] CI для тестов, Docker, multi-version APK/IPK и release artifacts.
|
||||
- [x] CI для тестов, Docker, текущей multi-architecture APK/IPK-матрицы и отдельной
|
||||
legacy-сборки без блокировки основного релиза.
|
||||
- [x] Keyless Cosign, provenance/SBOM контейнеров и подписанные checksum релизов.
|
||||
- [x] Нативные подписанные `Packages.sig`/`packages.adb` и публикация package feed.
|
||||
- [ ] Signed update manifest и безопасное обновление агента из кабинета.
|
||||
|
||||
+13
-5
@@ -5,16 +5,16 @@ Versioning.
|
||||
|
||||
## Server releases
|
||||
|
||||
Tags use `server-vMAJOR.MINOR.PATCH`, for example `server-v0.8.0`.
|
||||
Tags use `server-vMAJOR.MINOR.PATCH`, for example `server-v0.8.1`.
|
||||
|
||||
A server release contains the Go API, web interface, database migrations and the coupled
|
||||
SSH reverse-tunnel service. The GitHub Actions server workflow tests the server and
|
||||
publishes two images with the same version:
|
||||
|
||||
```text
|
||||
ghcr.io/benya9669/openwrt-rmm-server:0.8.0
|
||||
ghcr.io/benya9669/openwrt-rmm-server:0.8.1
|
||||
ghcr.io/benya9669/openwrt-rmm-server:latest
|
||||
ghcr.io/benya9669/openwrt-rmm-tunnel:0.8.0
|
||||
ghcr.io/benya9669/openwrt-rmm-tunnel:0.8.1
|
||||
ghcr.io/benya9669/openwrt-rmm-tunnel:latest
|
||||
```
|
||||
|
||||
@@ -35,6 +35,14 @@ An agent release contains the Go runtime, LuCI application and OpenWrt IPK/APK p
|
||||
Before tagging, the tag version must match `agentVersion` in the Go source and
|
||||
`PKG_VERSION` in the production Go package. CI rejects a mismatched release tag.
|
||||
|
||||
Tagged releases automatically build the current OpenWrt 24.10 and 25.12 package matrix.
|
||||
OpenWrt 21.02, 22.03 and 23.05 are a manual legacy tier that extends an existing agent
|
||||
release without blocking current packages. Run it after the tagged workflow completes:
|
||||
|
||||
```sh
|
||||
gh workflow run build-legacy.yml -f agent_tag=agent-v0.6.6
|
||||
```
|
||||
|
||||
The LuCI application is shipped as part of the router bundle. It can retain its own package
|
||||
version for package-manager upgrades, but it does not require a separate GitHub release
|
||||
line unless it later becomes an independent product.
|
||||
@@ -55,8 +63,8 @@ transition period; it should not silently reuse `v1`.
|
||||
## Release commands
|
||||
|
||||
```sh
|
||||
git tag -a server-v0.8.0 -m "OpenWrt RMM Server 0.8.0"
|
||||
git push origin server-v0.8.0
|
||||
git tag -a server-v0.8.1 -m "OpenWrt RMM Server 0.8.1"
|
||||
git push origin server-v0.8.1
|
||||
|
||||
git tag -a agent-v0.6.6 -m "OpenWrt RMM Agent 0.6.6"
|
||||
git push origin agent-v0.6.6
|
||||
|
||||
+7
-3
@@ -1,6 +1,6 @@
|
||||
# OpenWrt RMM — актуальный roadmap
|
||||
|
||||
Актуализировано: 2026-07-23. Текущая стабильная линия агента: `0.6.5`.
|
||||
Актуализировано: 2026-07-30. Текущая стабильная линия агента: `0.6.6`.
|
||||
|
||||
## Цель продукта
|
||||
|
||||
@@ -49,6 +49,8 @@ OpenWrt через исходящее соединение агента. Пол
|
||||
- [x] SMTP STARTTLS/TLS и Telegram bot configuration через environment.
|
||||
- [x] Версионированные server/tunnel images в GHCR и production Compose overlay.
|
||||
- [x] SBOM/provenance, keyless Cosign и подписанный APK/IPK package repository.
|
||||
- [x] Быстрая матрица текущих OpenWrt 24.10/25.12 и отдельная ручная legacy-сборка
|
||||
OpenWrt 21.02/22.03/23.05 без блокировки основного релиза.
|
||||
|
||||
## Следующие этапы
|
||||
|
||||
@@ -110,6 +112,8 @@ OpenWrt через исходящее соединение агента. Пол
|
||||
|
||||
## Ближайший приоритет
|
||||
|
||||
1. Создать и сохранить ключи package feed, включить GitHub Pages и проверить первый подписанный agent/server release.
|
||||
1. Завершить и проверить `agent-v0.6.6`, при необходимости добавить legacy-пакеты,
|
||||
развернуть server `0.8.1` и проверить свежие SSH/LuCI-сессии.
|
||||
2. Развернуть и проверить notification release на production.
|
||||
3. Добавить webhook и quiet hours, затем начать конфигурационные backup/restore.
|
||||
3. Добавить активное подтверждение проводных клиентов, webhook и quiet hours, затем
|
||||
начать конфигурационные backup/restore.
|
||||
|
||||
@@ -1,7 +1,13 @@
|
||||
# Signed OpenWrt package repository
|
||||
|
||||
Agent release tags publish a repository for every supported OpenWrt release and target.
|
||||
The default public base URL is:
|
||||
Agent release tags automatically publish the current OpenWrt support tier:
|
||||
|
||||
- OpenWrt 24.10 and 25.12;
|
||||
- `x86/64`, `ramips/mt7621`, `ath79/generic`, `ipq40xx/generic` and
|
||||
`mediatek/filogic`.
|
||||
|
||||
OpenWrt 21.02, 22.03 and 23.05 packages are added to an existing agent release by the
|
||||
manual legacy workflow described below. The default public base URL is:
|
||||
|
||||
```text
|
||||
https://benya9669.github.io/openwrt-rmm/feeds/stable/openwrt
|
||||
@@ -55,11 +61,43 @@ The public keys are committed under `keys/openwrt/`. Their expected identifiers
|
||||
The release build verifies that each private key matches the committed public key before
|
||||
publishing a signed feed.
|
||||
|
||||
An `agent-v*` release fails closed when the key required by an OpenWrt generation is
|
||||
missing. Manual workflow runs may still create unsigned test artifacts. BuildKit secret
|
||||
An `agent-v*` release and the legacy publication workflow fail closed when a required
|
||||
native signing key is missing. A manual run of the general **Build and test** workflow
|
||||
may still create unsigned test artifacts, but it does not publish them. BuildKit secret
|
||||
mounts expose private keys only to the repository-index build step; private keys are not
|
||||
copied into images, artifacts or build cache.
|
||||
|
||||
## Support tiers and legacy packages
|
||||
|
||||
The normal `agent-v*` workflow builds ten current package targets. This keeps the release
|
||||
gate fast and prevents an obsolete SDK from blocking packages for supported OpenWrt
|
||||
versions.
|
||||
|
||||
To extend the latest agent release with signed OpenWrt 21.02, 22.03 and 23.05 packages,
|
||||
run **Actions → Build legacy OpenWrt packages → Run workflow** from the default branch
|
||||
and enter its existing tag, for example `agent-v0.6.6`. The same operation is available
|
||||
through GitHub CLI:
|
||||
|
||||
```sh
|
||||
gh workflow run build-legacy.yml -f agent_tag=agent-v0.6.6
|
||||
```
|
||||
|
||||
Run it only after the main agent release has completed. The legacy workflow:
|
||||
|
||||
1. checks out and builds the exact agent tag;
|
||||
2. signs the IPK repositories with the configured `usign` key;
|
||||
3. combines them with the current release and reconstructs the complete repository;
|
||||
4. refreshes signed checksums and uploads the legacy files to the existing GitHub Release;
|
||||
5. redeploys the complete current plus legacy repository to GitHub Pages.
|
||||
|
||||
The workflow refuses an older agent tag because publishing it would roll the `stable`
|
||||
feed back from the latest agent version.
|
||||
|
||||
The legacy matrix contains `x86/64`, `ramips/mt7621`, `ath79/generic` and
|
||||
`ipq40xx/generic`; OpenWrt 23.05 also contains `mediatek/filogic`.
|
||||
`bcm27xx/bcm2711` is intentionally on-demand and should be added only when a supported
|
||||
Raspberry Pi 4 installation needs a package.
|
||||
|
||||
## OpenWrt 24.10 and older: IPK/opkg
|
||||
|
||||
Choose the directory matching the firmware release and target. For example MT7621 on
|
||||
@@ -106,7 +144,7 @@ Release assets also include a keyless Sigstore bundle for the combined checksums
|
||||
cosign verify-blob \
|
||||
--bundle SHA256SUMS.sigstore.json \
|
||||
--certificate-identity-regexp \
|
||||
'^https://github.com/Benya9669/openwrt-rmm/.github/workflows/build.yml@refs/tags/agent-v.*$' \
|
||||
'^https://github.com/Benya9669/openwrt-rmm/.github/workflows/(build\.yml@refs/tags/agent-v.*|build-legacy\.yml@refs/heads/main)$' \
|
||||
--certificate-oidc-issuer https://token.actions.githubusercontent.com \
|
||||
SHA256SUMS
|
||||
sha256sum --check SHA256SUMS
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
if [ "$#" -ne 3 ]; then
|
||||
echo "usage: $0 <release-assets-dir> <sdk-lock-file> <output-dir>" >&2
|
||||
exit 2
|
||||
fi
|
||||
|
||||
source_dir="$1"
|
||||
lock_file="$2"
|
||||
output_dir="$3"
|
||||
|
||||
if [ ! -d "$source_dir" ]; then
|
||||
echo "release assets directory does not exist: $source_dir" >&2
|
||||
exit 1
|
||||
fi
|
||||
if [ ! -f "$lock_file" ]; then
|
||||
echo "SDK lock file does not exist: $lock_file" >&2
|
||||
exit 1
|
||||
fi
|
||||
if [ -e "$output_dir" ] && [ -n "$(find "$output_dir" -mindepth 1 -maxdepth 1 -print -quit 2>/dev/null)" ]; then
|
||||
echo "output directory must be empty: $output_dir" >&2
|
||||
exit 1
|
||||
fi
|
||||
mkdir -p "$output_dir"
|
||||
|
||||
artifact_count=0
|
||||
while IFS=$'\t' read -r release target subtarget _sha256 _url; do
|
||||
[ -n "$release" ] || continue
|
||||
case "$release" in
|
||||
\#*) continue ;;
|
||||
esac
|
||||
|
||||
case "$target/$subtarget" in
|
||||
x86/64) label="x86-64" ;;
|
||||
*) label="${target}-${subtarget}" ;;
|
||||
esac
|
||||
|
||||
artifact_name="openwrt-${release}-${label}"
|
||||
destination="$output_dir/$artifact_name"
|
||||
matched=0
|
||||
for asset in "$source_dir/$artifact_name"-*; do
|
||||
[ -f "$asset" ] || continue
|
||||
mkdir -p "$destination"
|
||||
basename="${asset##*/}"
|
||||
cp "$asset" "$destination/${basename#"$artifact_name"-}"
|
||||
matched=1
|
||||
done
|
||||
if [ "$matched" -eq 1 ]; then
|
||||
artifact_count=$((artifact_count + 1))
|
||||
fi
|
||||
done < "$lock_file"
|
||||
|
||||
if [ "$artifact_count" -eq 0 ]; then
|
||||
echo "no prefixed OpenWrt package assets found in $source_dir" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "reconstructed ${artifact_count} OpenWrt package artifact directories"
|
||||
Reference in New Issue
Block a user