comms: make room reset a suspended cronjob

This commit is contained in:
Brad Stein 2026-01-08 06:09:34 -03:00
parent d870e97b38
commit ffddd71116
2 changed files with 235 additions and 209 deletions

View File

@ -17,13 +17,12 @@ Operational jobs
- synapse-user-seed-job: seeds atlasbot + othrys-seeder users/passwords. - synapse-user-seed-job: seeds atlasbot + othrys-seeder users/passwords.
- mas-local-users-ensure-job: ensures MAS local users exist (seeder/bot). - mas-local-users-ensure-job: ensures MAS local users exist (seeder/bot).
- seed-othrys-room: (suspended) creates Othrys + joins locals. - seed-othrys-room: (suspended) creates Othrys + joins locals.
- reset-othrys-room: one-off room reset + pin invite. - reset-othrys-room: suspended CronJob for a manual room reset + pin invite.
- pin-othrys-invite: (suspended) pin invite message if missing. - pin-othrys-invite: (suspended) pin invite message if missing.
- guest-name-randomizer: renames numeric/guest users to adj-noun names. - guest-name-randomizer: renames numeric/guest users to adj-noun names.
- bstein-force-leave: one-off room leave cleanup. - bstein-force-leave: one-off room leave cleanup.
Manual re-runs Manual re-runs
- Bump the job name suffix (e.g., reset-othrys-room-9) to re-run a one-off job.
- Unsuspend a CronJob only when needed; re-suspend after completion. - Unsuspend a CronJob only when needed; re-suspend after completion.
Ports Ports

View File

@ -1,9 +1,16 @@
# services/comms/reset-othrys-room-job.yaml # services/comms/reset-othrys-room-job.yaml
apiVersion: batch/v1 apiVersion: batch/v1
kind: Job kind: CronJob
metadata: metadata:
name: othrys-room-reset-8 name: othrys-room-reset
namespace: comms namespace: comms
spec:
schedule: "0 0 1 1 *"
suspend: true
concurrencyPolicy: Forbid
successfulJobsHistoryLimit: 1
failedJobsHistoryLimit: 1
jobTemplate:
spec: spec:
backoffLimit: 0 backoffLimit: 0
template: template:
@ -14,7 +21,7 @@ spec:
image: python:3.11-slim image: python:3.11-slim
env: env:
- name: SYNAPSE_BASE - name: SYNAPSE_BASE
value: http://matrix-authentication-service:8080 value: http://othrys-synapse-matrix-synapse:8008
- name: AUTH_BASE - name: AUTH_BASE
value: http://matrix-authentication-service:8080 value: http://matrix-authentication-service:8080
- name: SERVER_NAME - name: SERVER_NAME
@ -41,7 +48,10 @@ spec:
set -euo pipefail set -euo pipefail
pip install --no-cache-dir requests >/dev/null pip install --no-cache-dir requests >/dev/null
python - <<'PY' python - <<'PY'
import os, sys, time, urllib.parse, requests import os
import time
import urllib.parse
import requests
BASE = os.environ["SYNAPSE_BASE"] BASE = os.environ["SYNAPSE_BASE"]
AUTH_BASE = os.environ.get("AUTH_BASE", BASE) AUTH_BASE = os.environ.get("AUTH_BASE", BASE)
@ -76,7 +86,8 @@ spec:
"users_default": 0, "users_default": 0,
} }
def auth(token): return {"Authorization": f"Bearer {token}"} def auth(token):
return {"Authorization": f"Bearer {token}"}
def canon_user(user): def canon_user(user):
u = (user or "").strip() u = (user or "").strip()
@ -85,14 +96,17 @@ spec:
u = u.lstrip("@") u = u.lstrip("@")
if ":" in u: if ":" in u:
return f"@{u}" return f"@{u}"
return f"@{u}:live.bstein.dev" return f"@{u}:{SERVER_NAME}"
def login(user, password): def login(user, password):
r = requests.post(f"{AUTH_BASE}/_matrix/client/v3/login", json={ r = requests.post(
f"{AUTH_BASE}/_matrix/client/v3/login",
json={
"type": "m.login.password", "type": "m.login.password",
"identifier": {"type": "m.id.user", "user": canon_user(user)}, "identifier": {"type": "m.id.user", "user": canon_user(user)},
"password": password, "password": password,
}) },
)
if r.status_code != 200: if r.status_code != 200:
raise SystemExit(f"login failed: {r.status_code} {r.text}") raise SystemExit(f"login failed: {r.status_code} {r.text}")
return r.json()["access_token"] return r.json()["access_token"]
@ -106,11 +120,15 @@ spec:
return r.json()["room_id"] return r.json()["room_id"]
def create_room(token): def create_room(token):
r = requests.post(f"{BASE}/_matrix/client/v3/createRoom", headers=auth(token), json={ r = requests.post(
f"{BASE}/_matrix/client/v3/createRoom",
headers=auth(token),
json={
"preset": "public_chat", "preset": "public_chat",
"name": ROOM_NAME, "name": ROOM_NAME,
"room_version": "11", "room_version": "11",
}) },
)
r.raise_for_status() r.raise_for_status()
return r.json()["room_id"] return r.json()["room_id"]
@ -231,8 +249,17 @@ spec:
set_directory_visibility(token, old_room_id, "private") set_directory_visibility(token, old_room_id, "private")
put_state(token, old_room_id, "m.room.join_rules", {"join_rule": "invite"}) put_state(token, old_room_id, "m.room.join_rules", {"join_rule": "invite"})
put_state(token, old_room_id, "m.room.guest_access", {"guest_access": "forbidden"}) put_state(token, old_room_id, "m.room.guest_access", {"guest_access": "forbidden"})
put_state(token, old_room_id, "m.room.tombstone", {"body": "Othrys has been reset. Please join the new room.", "replacement_room": new_room_id}) put_state(
send_message(token, old_room_id, "Othrys was reset. Join the new room at https://live.bstein.dev/#/room/#othrys:live.bstein.dev?action=join") token,
old_room_id,
"m.room.tombstone",
{"body": "Othrys has been reset. Please join the new room.", "replacement_room": new_room_id},
)
send_message(
token,
old_room_id,
"Othrys was reset. Join the new room at https://live.bstein.dev/#/room/#othrys:live.bstein.dev?action=join",
)
print(f"old_room_id={old_room_id}") print(f"old_room_id={old_room_id}")
print(f"new_room_id={new_room_id}") print(f"new_room_id={new_room_id}")