Changeset 12bed59 in Klonkt for scripts


Ignore:
Timestamp:
08/07/2026 04:14:49 PM (5 weeks ago)
Author:
Robin <roboburr@…>
Branches:
main
Children:
f85b2c3
Parents:
fa33214
git-author:
Robin <roboburr@…> (07/31/2026 02:52:19 PM)
git-committer:
Robin <roboburr@…> (08/07/2026 04:14:49 PM)
Message:

Zet de oude klonkt.service opzij; maskeren werkte niet

Correctie op f434294. Daar maskeerde ik de oude unit om te voorkomen dat een
systemctl restart klonkt hem uit de dood liet opstaan. Getest met een
user-unit blijkt dat niet te werken:

Failed to mask unit: File '.../masktest.service' already exists

systemctl mask legt een symlink naar /dev/null op het pad van de unit, maar
install.sh schrijft klonkt.service in /etc/systemd/system, de map met de
hoogste prioriteit. Er is dan geen plek meer om de mask neer te zetten en
systemd weigert. Na de mislukte mask start restart de unit gewoon nog
(exitcode 0), dus de fix deed niets.

Erger: die mask stond zonder vangnet onder set -euo pipefail. In het
migratiescript zou hij de migratie afbreken NADAT de data al verplaatst was.
De fix was dus niet alleen nutteloos maar ook gevaarlijk.

Wat wel werkt, en nu getest is in beide richtingen: het unit-bestand opzij
zetten met een tijdstempel en daemon-reload. systemd kent de unit dan niet
meer, en een restart faalt hard met "Unit klonkt.service not found"
(exitcode 5) in plaats van stilletjes een tweede proces te starten dat een
lege database in de checkout schrijft. Terugzetten plus daemon-reload maakt
hem weer gewoon startbaar, dus de rollback blijft intact.

Changed files:
scripts/klonkt-migrate-data.sh

  • eigen stap 'Retiring klonkt.service': stop, disable, bestand naar klonkt.service.retired-<tijdstempel>, daemon-reload
  • stop en disable krijgen een vangnet zodat een al gestopte unit de migratie niet afbreekt
  • waarom maskeren hier niet kan, staat erbij; dat is niet vanzelfsprekend

scripts/klonkt-refresh-updater.sh

  • zelfde aanpak voor al gemigreerde servers, met een expliciete waarschuwing als het verplaatsen niet lukt

deploy/MULTI-INSTANCE.md

  • rollback bijgewerkt naar het terugzetten van het bestand

-robo
Co-Authored-By: Claude Fable 5 <noreply@…>

Location:
scripts
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • scripts/klonkt-migrate-data.sh

    rfa33214 r12bed59  
    128128run "systemctl daemon-reload"
    129129
     130step "Retiring $OLD_UNIT"
     131# Stopping and disabling is NOT enough: `systemctl restart klonkt` starts a
     132# disabled unit anyway, and that is exactly what an updater generated before
     133# the split does. A resurrected klonkt.service no longer finds its .env (that
     134# moved with the data), falls back to the built-in defaults, and writes a
     135# FRESH EMPTY database into the checkout.
     136#
     137# Masking does not help either: the unit file lives in /etc/systemd/system,
     138# the highest-priority directory, and `systemctl mask` refuses when a real
     139# file is already there ("File ... already exists"). Verified, not assumed.
     140#
     141# So the file is moved aside. systemd then no longer knows the unit at all and
     142# any restart fails loudly with "Unit klonkt.service not found". The file is
     143# kept next to its old place, timestamped, so a rollback is a move back.
     144if [ -f "/etc/systemd/system/$OLD_UNIT" ]; then
     145  run "systemctl stop $OLD_UNIT 2>/dev/null || true"
     146  run "systemctl disable $OLD_UNIT 2>/dev/null || true"
     147  RETIRED="/etc/systemd/system/${OLD_UNIT}.retired-$(date +%Y%m%d%H%M%S)"
     148  run "mv '/etc/systemd/system/$OLD_UNIT' '$RETIRED'"
     149  run "systemctl daemon-reload"
     150  say "stopped, disabled and moved aside → $RETIRED"
     151  say "roll back by moving that file back and running: systemctl daemon-reload"
     152else
     153  say "no $OLD_UNIT unit file to retire"
     154fi
     155
    130156step "Switching to klonkt@$SLUG"
    131 if systemctl list-unit-files "$OLD_UNIT" >/dev/null 2>&1; then
    132   run "systemctl disable --now $OLD_UNIT"
    133   # Disable only removes the autostart link: `systemctl restart klonkt` would
    134   # still START it. That is not theoretical — an updater generated before the
    135   # split does exactly that, and the resurrected unit finds no .env (it moved
    136   # with the data), falls back to the built-in defaults and creates a FRESH
    137   # EMPTY database in the checkout. Masking makes any such call fail loudly.
    138   # Reversible: systemctl unmask klonkt.
    139   run "systemctl mask $OLD_UNIT"
    140   say "disabled and masked $OLD_UNIT (unmask to roll back)"
    141 fi
    142157run "systemctl enable --now 'klonkt@$SLUG'"
    143158
  • scripts/klonkt-refresh-updater.sh

    rfa33214 r12bed59  
    5959echo "klonkt-update rewritten: branch ${BRANCH}, code ${KLONKT_DIR}, instances under ${DATA_ROOT}"
    6060
    61 # On a split install the old single unit must not be startable. `disable` alone
    62 # does not stop `systemctl restart klonkt` from starting it, and a resurrected
    63 # klonkt.service has no .env (it moved with the data): it falls back to the
    64 # defaults and writes a fresh empty database into the checkout.
     61# On a split install the old single unit must not be startable at all.
     62# `disable` is not enough (restart starts a disabled unit anyway) and `mask`
     63# refuses while the real file sits in /etc/systemd/system, the highest-priority
     64# directory. Moving the file aside is what actually works: systemd stops
     65# knowing the unit, so any restart fails loudly instead of quietly starting a
     66# second process that writes an empty database into the checkout.
    6567SPLIT=0
    6668for d in "${DATA_ROOT}"/*/; do [ -f "$d/.env" ] && SPLIT=1 && break; done
    67 if [ "$SPLIT" = 1 ] && systemctl list-unit-files klonkt.service >/dev/null 2>&1; then
    68   if ! systemctl is-enabled klonkt.service 2>/dev/null | grep -q masked; then
    69     systemctl stop klonkt.service 2>/dev/null || true
    70     systemctl disable klonkt.service 2>/dev/null || true
    71     systemctl mask klonkt.service
    72     echo "retired klonkt.service: stopped, disabled and masked (unmask to roll back)"
     69if [ "$SPLIT" = 1 ] && [ -f /etc/systemd/system/klonkt.service ]; then
     70  systemctl stop klonkt.service 2>/dev/null || true
     71  systemctl disable klonkt.service 2>/dev/null || true
     72  RETIRED="/etc/systemd/system/klonkt.service.retired-$(date +%Y%m%d%H%M%S)"
     73  if mv /etc/systemd/system/klonkt.service "$RETIRED"; then
     74    systemctl daemon-reload
     75    echo "retired klonkt.service → $RETIRED (move it back + daemon-reload to roll back)"
     76  else
     77    echo "WARNING: could not move /etc/systemd/system/klonkt.service aside."
     78    echo "         Until you do, any 'systemctl restart klonkt' starts a second"
     79    echo "         process that writes an empty database into ${KLONKT_DIR}."
    7380  fi
    7481fi
Note: See TracChangeset for help on using the changeset viewer.