358356a1b1
A second Conjurer bot alongside the test one, sharing librarian/musician/ radio and the API key, differing only in: * Discord token from the deploy-conjurer-netrc secret, * distinct names/labels (deploy-bot) and NodePort 32443, * /data on an NFS export (RWX) instead of a block PVC - so config/state can be uploaded while it runs (copy onto the share) and backed up concurrently. deploy-bot-backup: a daily CronJob that mirrors /data and keeps 30 days of dated snapshots of the critical small state (both memories, settings, accident log, transcripts) on NFS. Production only - the test bot's amnesia is fine. DEPLOY-BOT.md documents seeding, backup/restore, and the librarian/musician callback routing (they push to one bot; repoint CONJURER_MAIN_BOT to :32443 to feed this one). kubectl kustomize builds cleanly (10 objects). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
66 lines
2.7 KiB
YAML
66 lines
2.7 KiB
YAML
# Daily backup of the PRODUCTION ("deploy") bot's /data.
|
|
#
|
|
# Only production is backed up - the test bot's amnesia is fine, this bot's is
|
|
# not (pamiec.json / pamiec_muzyki.json are the conversation & music memory).
|
|
# Both volumes are NFS (RWX), so this runs while the bot is live - no RWO clash.
|
|
#
|
|
# Two-part backup:
|
|
# * a full, space-efficient MIRROR (rsync --delete) of everything, incl. music
|
|
# and graphics - always the current state,
|
|
# * dated SNAPSHOTS of just the small critical state (the memories, settings,
|
|
# accident log, transcripts) so you can roll back to a point in time.
|
|
# Snapshots older than RETENTION_DAYS are pruned.
|
|
apiVersion: batch/v1
|
|
kind: CronJob
|
|
metadata:
|
|
name: deploy-bot-backup
|
|
namespace: conjurer
|
|
spec:
|
|
schedule: "17 4 * * *" # every day at 04:17
|
|
concurrencyPolicy: Forbid
|
|
successfulJobsHistoryLimit: 3
|
|
failedJobsHistoryLimit: 3
|
|
jobTemplate:
|
|
spec:
|
|
backoffLimit: 2
|
|
template:
|
|
spec:
|
|
restartPolicy: Never
|
|
containers:
|
|
- name: backup
|
|
image: alpine:3.20
|
|
command: ["/bin/sh", "-c"]
|
|
args:
|
|
- |
|
|
set -eu
|
|
apk add --no-cache rsync >/dev/null
|
|
STAMP="$(date +%F-%H%M)"
|
|
mkdir -p /backup/current /backup/snapshots
|
|
echo "[$STAMP] mirroring /data -> /backup/current"
|
|
rsync -a --delete /data/ /backup/current/
|
|
echo "[$STAMP] snapshotting critical state"
|
|
tar czf "/backup/snapshots/deploy-state-$STAMP.tgz" -C /data \
|
|
accident_log.json pamiec.json pamiec_muzyki.json \
|
|
settings.json system_gpt_settings.json transcripts \
|
|
2>/dev/null || echo " (some files absent - skipped)"
|
|
echo "[$STAMP] pruning snapshots older than ${RETENTION_DAYS}d"
|
|
find /backup/snapshots -name 'deploy-state-*.tgz' -type f \
|
|
-mtime +"${RETENTION_DAYS}" -delete
|
|
echo "[$STAMP] backup done"
|
|
env:
|
|
- { name: RETENTION_DAYS, value: "30" }
|
|
volumeMounts:
|
|
- { name: data, mountPath: /data, readOnly: true }
|
|
- { name: backup, mountPath: /backup }
|
|
volumes:
|
|
# Same export the bot mounts (read-only here).
|
|
- name: data
|
|
nfs:
|
|
server: 192.168.1.34
|
|
path: /mnt/Tank1/conjurer_swap/deploy-bot/data
|
|
# Backup target - ADJUST to your export.
|
|
- name: backup
|
|
nfs:
|
|
server: 192.168.1.34
|
|
path: /mnt/Tank1/conjurer_swap/deploy-bot/backups
|