Zum Inhalt

Migration auf calServer 6.0

6.0 ist ein Versions- und Konsolidierungsschnitt: die Versionsnummer holt den Namen ein, den die Doku laengst benutzt, und die Versionsraeume ueber alle Ebenen ziehen auf eine Quelle. Funktional wird nichts entfernt. Der Legacy-Abbau ist markiert und terminiert, siehe Deprecations.

Hintergrund und Begruendungen: ADR-012.


Vorher: Backup

Pflicht, nicht Formsache. Ein Rollback ueber /admin/updates stellt die Container wieder her, nicht das Datenbankschema. Wer ohne Backup ueber eine Major-Grenze geht, hat im Fehlerfall keinen Rueckweg fuer die Daten.

# PostgreSQL (V2-Standard)
docker exec calserver-postgres \
  pg_dump -U calserver calserver_v2 > backup-vor-6.0.sql

# MySQL (V1 und Uebergangsinstallationen)
export MYSQL_PWD="$(sed -n 's/^DB_ROOT_PASSWORD=//p' /var/calserver/.env | head -1)"
docker exec -e MYSQL_PWD mysql_db \
  mysqldump --single-transaction --routines --triggers \
  -u root calserver > backup-v1-vor-6.0.sql
unset MYSQL_PWD

Datenbanknamen und Benutzer stehen in der Host-.env: PG_DATABASE / PG_USERNAME fuer V2 (ohne Eintrag gelten calserver_v2 und calserver), DB_DATABASE fuer V1. Der MySQL-Container heisst mysql_db.

Beim mysqldump nicht auf -p ausweichen

docker exec haengt ohne -i kein stdin an. Der Passwort-Prompt von -p bekommt dann nichts, mysqldump verbindet sich mit leerem Passwort und meldet Access denied ... (using password: NO). -it ist der falsche Ausweg: Das Pseudo-Terminal legt CRLF-Zeilenenden in die Umleitung, und der Dump sieht richtig aus, ist beim Einspielen aber kaputt.

Deshalb -e MYSQL_PWD ohne =wert — Docker nimmt den Wert aus der aufrufenden Umgebung, so steht das Passwort nicht in der Prozessliste des Hosts. --single-transaction liefert einen konsistenten Stand, ohne die laufende V1 zu sperren (alle Tabellen sind InnoDB); es ist derselbe Flag-Satz, den V2s eigener Sicherungslauf benutzt (app/Services/Backup/DatabaseDumper.php).

Danach die letzte Zeile ansehen:

tail -1 backup-v1-vor-6.0.sql   # muss "-- Dump completed on ..." sein

Laeuft die Platte waehrend des Dumps voll, liegt trotzdem eine plausibel grosse Datei da, nur ohne Ende. Und Backup zurueckspielen koennen, nicht nur anlegen: einmal in einer Testumgebung einspielen, bevor es ernst wird.


Reihenfolge

  1. V2 zuerst, ueber /admin/updates. Der Updater erneuert calserver-api-v2 und calserver-frontend; Migrationen laufen beim Container-Start automatisch.
  2. V1 danach, ueber deploy.sh auf dem Host. Der Updater fasst die V1-Container bewusst nicht an — nach Schritt 1 gibt es also einen Versionsversatz. Die Admin-UI zeigt den laufenden V1-Tag an.
cd /var/calserver
./update.sh          # V1-Image ziehen
./deploy.sh          # V1-Container neu erstellen

Das Major-Gate

Ab 6.0 laeuft ein Sprung ueber die Major-Grenze nicht mehr als gewoehnliches Update durch. Auf /admin/updates erscheint statt „Aktualisieren" der Knopf „Major-Update vorbereiten", und es folgen zwei Schritte:

  1. Migrationshinweise und die Releases zwischen laufender und Zielversion lesen, dazu die Hinweise zu V1-Versatz und Rollback-Grenze.
  2. Backup bestaetigen und die Zielversion eintippen. Erst dann laesst sich das Update starten.

Technisch verlangen beide Seiten die Bestaetigung unabhaengig voneinander: der Updater-Sidecar antwortet ohne confirm_major mit 409, die V2-API mit 422.

Flottenweiter Schalter

ALLOW_MAJOR_UPDATE in der Host-.env Wirkung
nicht gesetzt (Default) Major-Update braucht die Bestaetigung in der UI
true Major-Update laeuft ohne Rueckfrage (unbeaufsichtigte Flotten)
false Major-Updates sind gesperrt, auch mit Bestaetigung

false ist der Not-Aus fuer verwaltete Flotten: damit sieht ein Kunde die 6.0 zwar, kann sie aber nicht einspielen, bis der Betreiber freigibt.


Beta-Kanal

Releases gehen ab sofort zuerst ueber den Beta-Kanal. Wer 6.0 vor dem stabilen Release testen will, setzt in der Host-.env:

UPDATE_CHANNEL=beta

Der Kanal beta akzeptiert Tags mit -beta- und -rc-Suffix zusaetzlich zu den stabilen. Ein Beta-System sollte einen echten Semver-Tag als V2_IMAGE_TAG fahren (v5.64.922), nicht develop-latest — sonst ist die laufende Version nicht bestimmbar und die UI weist den Versionsvergleich ausdruecklich als unpraezise aus.

ALLOWED_TAG_PATTERNS auf Bestandssystemen nachziehen

Wer ALLOWED_TAG_PATTERNS in der Host-.env selbst gesetzt hat, muss das Muster um das Pre-Release-Suffix erweitern, sonst findet die Pruefung ein Beta-Tag und das Anwenden scheitert mit 403:

ALLOWED_TAG_PATTERNS=^v\d+\.\d+\.\d+(-[0-9A-Za-z.-]+)?$|^(develop|release|master|beta)-latest$|^latest$

Ohne eigenen Eintrag greift der neue Default, dann ist nichts zu tun.


Verhaltensaenderungen

Klein, aber sichtbar fuer API-Clients:

Was Vorher Ab 6.0
meta.api_version an 17 Endpunkten "2.0" "2.0.0" (aus config/api.php, wie ueberall sonst schon)
GET /admin/information/version → app_version "2.0.0" (aus composer.json) Produktversion, z.B. "6.0.0"
GET /app/version → app_version Produktversion unveraendert
dcc:release im DCC-XML-Export immer "1.0.0" Produktversion
Versionslog update_logs — neues Feld is_major

Der API-Contract bleibt unveraendert. Der Route-Prefix /api/v2 wandert nicht mit dem Produkt-Major mit, und meta.api_version steigt nur, wenn sich der Contract selbst aendert. Bestehende Integrationen brauchen keine Anpassung.


Was 6.0 nicht tut

  • Nichts wird entfernt. V1CompatResponse, die X-REST-Header-Auth, der MD5-Passwortpfad und HasFieldMapping sind als veraltet markiert und fuer 7.0 vorgesehen — siehe Deprecations.
  • V1 (Yii) wird nicht abgeschaltet. Der Sunset vor dem Yii-1-EOL am 31.12.2026 ist ein eigener Schritt.
  • Es gibt keinen Datenbankwechsel als Teil des Updates.

Wenn etwas schiefgeht

  1. Rollback ueber /admin/updates: jeder abgeschlossene oder fehlgeschlagene Eintrag im Verlauf bietet den Rueckweg auf den zuvor laufenden Tag. Der Rueckweg ueber die Major-Grenze ist bewusst nicht gesperrt.
  2. Schema zurueckspielen: der Rollback holt die Container zurueck, nicht das Schema. Dafuer ist das Backup da.
  3. Bleibt das Update im Zustand „wird angewendet" haengen, auf dem Host pruefen:

    docker compose ps calserver-updater
    docker compose logs --tail=100 calserver-updater
    

Details zum Update-System: Update-Anleitung.