EdgeRouter X: unattended von 2023.2 auf 2025.1, im Autoupdater, ohne(!) Config-Verlust

Für EdgeRouter X und X-SFP auf das 6-MB-Kernel-Layout für Gluon 2025.1.x: das Paket neanderfunk-erx-migrate (AGPL-3.0, Feed-Zweig v2023.2.x).
Hier die Kernpunkte, alles Weitere steht im README.

Ausgangslage

  • Kernel 6.6 aus OpenWrt 24.10: 3.173.564 Bytes, die beiden alten Slots haben je 3 MB, es fehlen 27 KB. Im aktuellen 26101610sta sind es 3.175.938 Bytes (ERX) und 3.176.094 Bytes (SFP), rund 30 KB über dem Slot.
  • Die Release Notes zu Gluon v2025.1 nennen manuelle Schritte und verweisen auf darkxst/erx-migration. Dabei geht die Config verloren.
  • compat_version 1.x -> 2.0 failt erst in sysupgrade --test, also nach Download und Signaturprüfung. --ignore-minor-compat-version hilft nicht, der Major-Branch von fwtool_check_image() wertet das Flag nicht aus.
  • Folge bei zwei Mirrors und 24 Cron-Runs: rund unnütze 345 MB am Tag je Knoten.

Ablauf

  • Stage 1: 2023.2-Intermediate-Image mit dem Paket, kommt über den normalen Autoupdater (compat 1.x -> 1.x)
  • Trigger: nur micron.d, stündlich zur Minute 37, ab einer Stunde Uptime, der ganze Run unter /var/lock/autoupdater.lock
  • Target: steht nicht im Image. erx-migrate-run liest Branch, Mirrors, Keys und good_signatures aus uci, holt das Manifest, prüft es mit ecdsaverify und nimmt Dateiname, Größe und SHA256 aus der Zeile des Zielmodells. Der Threshold ist auf 2 gedeckelt (ZIEL_SIGNATUREN).
  • Download: macht das Paket selbst, weil --no-action des Autoupdaters erst nach sysupgrade --test greift
  • Stage 2 im RAM-Root: Kernel über kernel1 und kernel2 schreiben, per Readback vergleichen, erst dann Boot-Index auf 0, UBI-Volumes neu aufbauen, Config zurück. Reihenfolge und Writes stammen aus darkxst/erx-migration.
  • Release-Kopplung: Jedes neue Release im Branch ist ohne weiteren Schritt das Target. Solange unmigrierte ERX im Feld stehen, gehört eine Migration vor jedes Release.

Config

  • sysupgrade -b nach /tmp vor dem Teardown, nand_restore_config nach dem Neuaufbau der UBI-Volumes. Der Preinit findet das Archiv wie bei einem normalen Sysupgrade.
  • compat_version wird im Archiv auf den Wert aus dem Image gehoben (fwtool -q -i). Sonst steht der Knoten nach dem Restore wieder auf 1.1 und nimmt später Images für das alte Layout an.

Imagename -ka

  • Auf 2025.1 heißen die Images ubiquiti-edgerouter-x-ka und ubiquiti-edgerouter-x-sfp-ka
  • Ein unmigrierter Knoten findet so seine Manifest-Zeile nicht, der Autoupdater bricht bei model_ok ab, vor dem Download
  • Unter dem alten Namen kann im selben Manifest das Intermediate-Image stehen
  • compatible bleibt, fwtool_check_image() und Sysupgrade merken nichts davon
  • Sichtbar: Das Model heißt danach Ubiquiti EdgeRouter X KA. Ein ERX ohne -ka in image_name ist auf der Karte ein unmigrierter Knoten.
  • Patch: devices/erx-ka-imagename.sh, dort steht auch, wie der Name wieder entfällt

Fehlerverhalten

  • Deferred (Log AUFSCHUB): kein Uplink, zu wenig Signaturen, Mirror noch nicht aktuell, Image fehlt oder ist corrupt. Retry nach einer Stunde.
  • Aborted (Log ABBRUCH): Pre-Check failed, Migration nicht durchgeführt. Marker in /tmp, kein Retry bis zum nächsten Boot.
  • Kein Flash-Write, solange die Migration nicht wirklich losläuft. Log und Image liegen in /tmp, State über Reboots gibt es nicht.
  • Startet Stage 2 nicht, baut erx-migrate.sh nach fünf Minuten zurück und startet micrond wieder, der Knoten läuft normal weiter
  • Log: http://[<knoten>]/cgi-bin/erx-migrate-log, offen wie die Statusseite, nur im RAM

Stand 01.11.2026

  • Testknoten: zwei Läufe am 31.10., Intermediate-Image per Autoupdater, Target aus dem echten stable-Manifest, Knoten rund zwei Minuten weg. Im ersten Lauf blieben Hostname, Kontakt, Standort, SSH-Keys, Port-Rollen und Adressen erhalten. Im zweiten lief auch der Start zur Minute 37 ohne manuellen Eingriff.
  • Feld: 14 ERX und 4 ERX SFP in 11 Domains. Intermediate-Image und Start hier von Hand, ohne Uptime-Grenze. Boot-Index vorher siebenmal 1 und elfmal 0. Alle 18 kamen beim ersten Handover durch.

Grenzen

  • Ausgangsstand war immer 26091920sta (2023.2.6). Ab Gluon 2022.1 sollte das Intermediate-Image (compat_version 1.1) per --ignore-minor-compat-version durchgehen, am ERX ungetestet. Bis 2021.1 (OpenWrt 19.07) eher nicht, auch das ungetestet.
  • Der Download läuft per uclient-fetch ohne gluon-wan, wie beim Autoupdater. Bei mindestens sieben der 18 Feldknoten lag der Gateway-Weg über br-mesh_other. Alle unsere ERX haben aber einen eigenen VPN-Link, ein ERX ganz ohne ist nicht geprüft.
  • Kein Remote-Rückweg nach dem Kernel-Write. Neuer Kernel auf altem Rootfs würde bedeuten: keine Module und kein Netz, erx-migrate-run sieht dann kernel in /proc/mtd und endet, es gibt keinen automatischen Retry. Rettung dann nur über die serielle Konsole. Am Testgerät reichte dabei jedes Mal eine Adresse von Hand, danach ließ sich der Lauf fortsetzen, erx-migrate.sh kennt beide Layouts.
  • Bad Blocks: mtd write überspringt sie (sollte also safe sein), die Markierung lässt sich im Image aber nicht abfragen. Der Readback fängt die Folge ab. Nach dem zweiten Fehlversuch bricht Stage 2 ab, das Gerät startet dann laut Code nicht mehr und braucht die Konsole. Ein falscher Readback ist am Gerät bisher nie aufgetreten.
  • Reboot-Pfade: Das Skript hält micrond und unsere eigenen Watchdogs an. Andere Pakete, die rebooten, wenn sysupgrade beim Teardown TERM und KILL schickt, muss man selbst prüfen.

Einbinden

  • Abhängigkeiten: gluon-core, micrond, ecdsautils
  • ziel.conf: nennt die Zielmodelle, ohne Eintrag tut das Paket nichts
  • Paket: neanderfunk-erx-migrate

2 „Gefällt mir“