Files
noroot bab82f8d5b feat(update): Testing/Stable-Update-Kanäle wie enconf (Suite=trixie, Komponente=Kanal)
Installer (EDGEGUARD_CHANNEL), Kanal-Lesen/-Schreiben ohne DB-State
(sources.list ist Quelle der Wahrheit), Cluster-Endpoints für Kanalwechsel
mit mTLS-Peer-Propagation + Drift-Erkennung, --allow-downgrades für
testing→stable-Downgrades über den bestehenden sicheren Rolling-Update-
Flow, Settings-UI mit Bestätigung, neues scripts/release.sh (Testing-Push
datumsbasiert YYYY.MM.DD.NN, Stable-Promotion mit Verify-Gate + Git-Tag),
publish.sh/cleanup-old.sh kanalfähig mit Stable-Tag-Schutz.

Migriert Bestandsnodes automatisch von der alten "main"-Komponente auf
"stable" (postinst, idempotent) — ohne das würden vor diesem Release
installierte Nodes stillschweigend keine Updates mehr sehen, sobald
main nicht mehr bespielt wird.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-02 16:31:52 +02:00

98 lines
3.2 KiB
Bash
Executable File

#!/bin/bash
# Publish EdgeGuard deb packages to the Gitea Package Registry in
# the correct dependency order, with fail-fast on partial failure.
#
# Wichtig: das Meta-Paket `edgeguard` deklariert harte Versions-
# Dependencies auf `edgeguard-api (= X.Y.Z)` und `edgeguard-ui (= X.Y.Z)`.
# Wenn beim Upload die api/ui-Pakete fehlschlagen, darf das Meta NICHT
# hochgeladen werden — sonst sieht apt eine inkonsistente Lage:
# "edgeguard X.Y.Z available, depends api X.Y.Z, but api only Y.Z-1 in
# Packages" → "no choices are installable" → Self-Service-Update broken.
# Befund 2026-05-17 nach Gitea-Disk-Full-Vorfall.
#
# Aufruf:
# ./publish.sh <version> <arch> [channel]
# arch = amd64 | arm64. arm64 publiziert NUR edgeguard-api (das einzige
# arch-spezifische Paket); amd64 publiziert alle drei.
# channel = stable | testing (Default stable). Kanal-Modell wie enconf:
# Suite=trixie fest, Komponente=Kanal. Wird von scripts/release.sh
# gesetzt — direkter Aufruf (z.B. aus altem `make publish`) bleibt
# ohne 3. Arg unverändert auf stable.
set -euo pipefail
VERSION="${1:?usage: publish.sh <version> <arch> [channel]}"
ARCH="${2:?usage: publish.sh <version> <arch> [channel]}"
CHANNEL="${3:-stable}"
case "$CHANNEL" in stable|testing) ;; *) echo "publish: unknown channel '$CHANNEL' (expected stable or testing)" >&2; exit 2 ;; esac
BASE="https://git.netcell-it.de/api/packages/projekte/debian/pool/trixie/${CHANNEL}/upload"
if [ -z "${GITEA_TOKEN:-}" ]; then
if [ -r "$HOME/.gitea-token" ]; then
GITEA_TOKEN="$(tr -d '\n' < "$HOME/.gitea-token")"
else
echo "publish: missing ~/.gitea-token and GITEA_TOKEN env" >&2
exit 1
fi
fi
TOK="$GITEA_TOKEN"
# upload_one <local-deb-path>
# 201 → OK, frisch hochgeladen
# 409 → bereits vorhanden (idempotent, OK)
# alles andere → harter Fehler, abort
upload_one() {
local file="$1"
if [ ! -f "$file" ]; then
echo "$file: not found" >&2
return 1
fi
local name
name="$(basename "$file")"
echo " -> publish $name"
# curl -w schreibt HTTP-Code in stdout-tail, body in /tmp.
local body http
body="$(mktemp)"
http="$(curl -sS -o "$body" -w '%{http_code}' \
-H "Authorization: token $TOK" \
--upload-file "$file" "$BASE")"
case "$http" in
201)
rm -f "$body"
;;
409)
echo " (already exists in registry — OK, idempotent skip)"
rm -f "$body"
;;
*)
echo " ✗ HTTP $http"
cat "$body" >&2
rm -f "$body"
return 1
;;
esac
}
# Upload order: api zuerst, dann ui, dann zuletzt das Meta-Paket.
# Diese Reihenfolge garantiert: wenn ein Schritt failt, ist das Meta
# NICHT im Registry (die strikte Dep-Constraint bleibt erfüllbar).
case "$ARCH" in
amd64)
upload_one "build/deb/edgeguard-api_${VERSION}_amd64.deb"
upload_one "build/deb/edgeguard-ui_${VERSION}_all.deb"
upload_one "build/deb/edgeguard_${VERSION}_all.deb"
;;
arm64)
upload_one "build/deb/edgeguard-api_${VERSION}_arm64.deb"
# Meta + UI sind arch=all → werden vom amd64-Publish abgedeckt.
# arm64-Publish lädt NUR das api-Binary.
;;
*)
echo "publish: unknown arch '$ARCH' (expected amd64 or arm64)" >&2
exit 2
;;
esac
echo "publish: ok ($VERSION/$ARCH/$CHANNEL)"