source: Klonkt/scripts/klonkt-refresh-updater.sh@ 952baf3

main
Last change on this file since 952baf3 was 952baf3, checked in by Robin <roboburr@…>, 5 weeks ago

Merge GitHub-main (1.7.0) met de VPS-lijn

De twee mains waren een dag gedivergeerd en bevatten elk echt werk. GitHub had 66
commits die nooit langs prutfolio.git zijn gekomen, omdat een parallelle sessie
rechtstreeks naar GitHub pushte vanaf een kloon in /tmp op de VPS. De VPS had twee
commits die GitHub niet had. Geen van beide bevatte de ander, en stable had geen van
de twee.

Bewust een merge en geen rebase: dan blijft beide historie intact en wordt er niets
herschreven waar iemand anders al op voortbouwt.

Drie bestanden raakten beide kanten. Alle drie zijn nagekeken, want dat een merge
automatisch slaagt zegt niets over of hij inhoudelijk klopt:

src/services/ActivityPubService.js

  • de sleutelbinding staat nu boven de nieuwe asSlug-aanroep van 1.7.0, dus de controle komt nog steeds voor de handtekeningcontrole

scripts/klonkt-refresh-updater.sh

  • alleen de opzij-aanpak overleefde; systemctl mask staat nergens meer als code

deploy/MULTI-INSTANCE.md

  • spreekt zichzelf niet tegen: beschrijft opzij zetten, met de reden waarom mask weigert

remarks: het gat dat in de review naar boven kwam staat hiermee ook op de 1.7.0-lijn.
De andere bevindingen uit die review staan nog open en zijn niet in deze merge
opgelost; die horen als beads. Ook nog te doen: dezelfde sleutelbinding op stable
als 1.6.1, want daar is het gat nog open bij self-hosters.

-robo
Co-Authored-By: Claude Opus 4.8 <noreply@…>

  • Property mode set to 100755
File size: 5.3 KB
Line 
1#!/usr/bin/env bash
2#
3# (Re)write /usr/local/bin/klonkt-update so it matches how this server runs.
4#
5# Why this exists: the updater is generated once at install time. A server
6# that later migrated to the split layout (klonkt@<slug> units) kept its old
7# updater, which still restarts the retired klonkt.service. Result: the code
8# on disk updates, the restart quietly fails, and the old process keeps
9# serving — half old routes, half new templates, which is how you get a 500
10# on one page and nothing in the logs that says why.
11#
12# Idempotent; safe to run any time:
13#
14# sudo bash /opt/klonkt/scripts/klonkt-refresh-updater.sh
15#
16set -euo pipefail
17
18KLONKT_DIR="${KLONKT_DIR:-/opt/klonkt}"
19KLONKT_USER="${KLONKT_USER:-klonkt}"
20DATA_ROOT="${KLONKT_DATA_ROOT:-/var/lib/klonkt}"
21# Follow whatever branch the checkout is on (stable for most self-hosters).
22BRANCH="${KLONKT_BRANCH:-$(git -C "$KLONKT_DIR" rev-parse --abbrev-ref HEAD 2>/dev/null || echo stable)}"
23
24[ "$(id -u)" = 0 ] || { echo "run this as root (sudo)." >&2; exit 1; }
25[ -d "$KLONKT_DIR/.git" ] || { echo "no git checkout at $KLONKT_DIR" >&2; exit 1; }
26
27cat > /usr/local/bin/klonkt-update <<EOF
28#!/usr/bin/env bash
29set -euo pipefail
30D="${KLONKT_DIR}"
31B=\$(runuser -u ${KLONKT_USER} -- git -C "\$D" rev-parse HEAD 2>/dev/null || true)
32# Deepen a shallow checkout ONCE. \`fetch --depth 1\` keeps only the newest commit
33# and \`checkout -f\` throws away the tree that was there, so after an update the
34# previous version existed nowhere on the machine: a bad release could not be
35# undone without the network, and only if you knew which commit to ask for.
36# One deepening buys back the history; every later fetch keeps it.
37if [ "\$(runuser -u ${KLONKT_USER} -- git -C "\$D" rev-parse --is-shallow-repository 2>/dev/null)" = "true" ]; then
38 echo "deepening the checkout once so updates can be rolled back..."
39 runuser -u ${KLONKT_USER} -- git -C "\$D" fetch --unshallow origin ${BRANCH} || true
40fi
41runuser -u ${KLONKT_USER} -- git -C "\$D" fetch origin ${BRANCH}
42runuser -u ${KLONKT_USER} -- git -C "\$D" checkout -qf -B ${BRANCH} FETCH_HEAD
43A=\$(runuser -u ${KLONKT_USER} -- git -C "\$D" rev-parse HEAD)
44if [ "\$B" = "\$A" ]; then
45 echo "Klonkt is already up to date (\$A) — nothing to do."
46 exit 0
47fi
48if ! runuser -u ${KLONKT_USER} -- git -C "\$D" diff --quiet "\$B" "\$A" -- package-lock.json 2>/dev/null; then
49 runuser -u ${KLONKT_USER} -- env HOME="\$D" bash -c "cd '\$D' && npm ci --omit=dev"
50fi
51# Restart every instance sharing this checkout: one directory with an .env
52# under the data root per instance. No instances there = the pre-split
53# single-service layout, which still runs plain klonkt.service.
54N=0
55for d in ${DATA_ROOT}/*/; do
56 [ -f "\$d/.env" ] || continue
57 s=\$(basename "\$d")
58 systemctl restart "klonkt@\$s" && N=\$((N+1))
59done
60if [ "\$N" = 0 ]; then
61 systemctl restart klonkt
62 echo "Klonkt updated (\$A) + restarted."
63else
64 echo "Klonkt updated (\$A) + restarted \$N instance(s)."
65fi
66# History alone is not a rollback; at three in the morning you also need the
67# command. Print it while the previous commit is still known.
68if [ -n "\$B" ]; then
69 echo
70 echo "Previous version: \$B"
71 echo "To go back:"
72 echo " runuser -u ${KLONKT_USER} -- git -C \$D checkout -qf -B ${BRANCH} \$B"
73 echo " then restart the instances (systemctl restart 'klonkt@*')"
74fi
75EOF
76chmod +x /usr/local/bin/klonkt-update
77echo "klonkt-update rewritten: branch ${BRANCH}, code ${KLONKT_DIR}, instances under ${DATA_ROOT}"
78
79# On a split install the old single unit must not be startable at all.
80# `disable` is not enough (restart starts a disabled unit anyway) and `mask`
81# refuses while the real file sits in /etc/systemd/system, the highest-priority
82# directory. Moving the file aside is what actually works: systemd stops
83# knowing the unit, so any restart fails loudly instead of quietly starting a
84# second process that writes an empty database into the checkout.
85SPLIT=0
86for d in "${DATA_ROOT}"/*/; do [ -f "$d/.env" ] && SPLIT=1 && break; done
87if [ "$SPLIT" = 1 ] && [ -f /etc/systemd/system/klonkt.service ]; then
88 systemctl stop klonkt.service 2>/dev/null || true
89 systemctl disable klonkt.service 2>/dev/null || true
90 RETIRED="/etc/systemd/system/klonkt.service.retired-$(date +%Y%m%d%H%M%S)"
91 if mv /etc/systemd/system/klonkt.service "$RETIRED"; then
92 systemctl daemon-reload
93 echo "retired klonkt.service → $RETIRED (move it back + daemon-reload to roll back)"
94 else
95 echo "WARNING: could not move /etc/systemd/system/klonkt.service aside."
96 echo " Until you do, any 'systemctl restart klonkt' starts a second"
97 echo " process that writes an empty database into ${KLONKT_DIR}."
98 fi
99fi
100
101# A leftover storage/ in the checkout means something ran without the instance
102# config. Report it; never delete it unattended — only its owner can tell
103# whether it holds anything.
104if [ "$SPLIT" = 1 ] && [ -e "${KLONKT_DIR}/storage" ]; then
105 echo
106 echo "WARNING: ${KLONKT_DIR}/storage exists while instance data lives in ${DATA_ROOT}."
107 echo " Something ran without the instance .env and wrote here. Check with:"
108 echo " sqlite3 ${KLONKT_DIR}/storage/database.sqlite 'select count(*) from posts;'"
109 echo " If it is empty, it is a stray from a resurrected klonkt.service and"
110 echo " can be removed. If it is NOT empty, do not delete it: ask first."
111fi
Note: See TracBrowser for help on using the repository browser.