Pass Nextcloud backup restore drill for Forgejo (T09)
Decrypt production forgejo-dump artifact, restore 14 repos in isolated namespace, and harden restore script for large chunked copy and drill mailer stub.
This commit is contained in:
parent
8ea13a065b
commit
1da9c3269b
3 changed files with 74 additions and 15 deletions
|
|
@ -14,6 +14,26 @@ PROD_POD="${PROD_POD:-$(kubectl get pods -n forgejo -l app.kubernetes.io/instanc
|
|||
|
||||
step() { echo "==> $*"; }
|
||||
|
||||
# kubectl cp drops large archives (~686M) via websocket EOF; split and reassemble.
|
||||
copy_backup_to_pod() {
|
||||
local src="$1" dest_ns="$2" dest_pod="$3" dest_path="$4" container="$5"
|
||||
local size chunk_dir
|
||||
size="$(stat -c%s "${src}")"
|
||||
if [[ "${size}" -lt 104857600 ]]; then
|
||||
kubectl cp "${src}" "${dest_ns}/${dest_pod}:${dest_path}" -c "${container}"
|
||||
return
|
||||
fi
|
||||
step "Chunked copy (${size} bytes) to pod"
|
||||
chunk_dir="$(mktemp -d)"
|
||||
trap 'rm -rf "${chunk_dir}"' RETURN
|
||||
split -b 48m -a 3 "${src}" "${chunk_dir}/part-"
|
||||
for part in "${chunk_dir}"/part-*; do
|
||||
kubectl cp "${part}" "${dest_ns}/${dest_pod}:/backup/$(basename "${part}")" -c "${container}"
|
||||
done
|
||||
kubectl exec -n "${dest_ns}" "${dest_pod}" -c "${container}" -- \
|
||||
sh -c "cat /backup/part-* > '${dest_path}' && rm -f /backup/part-*"
|
||||
}
|
||||
|
||||
if [[ "${DRILL_CLEAN}" == "1" ]]; then
|
||||
step "Clean prior drill namespace ${NS}"
|
||||
kubectl delete namespace "${NS}" --wait=true --timeout=5m || true
|
||||
|
|
@ -69,7 +89,8 @@ spec:
|
|||
emptyDir: {}
|
||||
EOF
|
||||
kubectl wait --for=condition=Ready pod/forgejo-restore-import -n "${NS}" --timeout=3m
|
||||
kubectl cp "${BACKUP_LOCAL}" "${NS}/forgejo-restore-import:/backup/forgejo-drill-backup.zip" -c restore
|
||||
copy_backup_to_pod "${BACKUP_LOCAL}" "${NS}" forgejo-restore-import \
|
||||
/backup/forgejo-drill-backup.zip restore
|
||||
DB_PASS="$(kubectl get secret forgejo-db-credentials -n "${NS}" -o jsonpath='{.data.password}' | base64 -d)"
|
||||
kubectl exec -n "${NS}" forgejo-restore-import -c restore -- env POSTGRES_PASSWORD="${DB_PASS}" sh -c '
|
||||
set -eu
|
||||
|
|
@ -89,19 +110,25 @@ kubectl delete pod forgejo-restore-import -n "${NS}" --wait=true
|
|||
step "Deploy isolated Forgejo release"
|
||||
cd "${HOME}/railiance-apps"
|
||||
DB_PASS="$(kubectl get secret forgejo-db-credentials -n "${NS}" -o jsonpath='{.data.password}' | base64 -d)"
|
||||
# Restore namespace has no OpenBao/ESO mailer secret — stub for chart init.
|
||||
kubectl create secret generic forgejo-mailer -n "${NS}" \
|
||||
--from-literal=MAILER_PASSWD=restore-drill-local-only \
|
||||
--dry-run=client -o yaml | kubectl apply -f -
|
||||
helm upgrade --install forgejo-restore gitea-charts/gitea --version 12.5.0 \
|
||||
--namespace "${NS}" --create-namespace \
|
||||
-f helm/forgejo-values.yaml \
|
||||
-f helm/forgejo-registry-values.yaml \
|
||||
--set strategy.type=Recreate \
|
||||
--set persistence.enabled=true \
|
||||
--set persistence.existingClaim=forgejo-restore-data \
|
||||
--set gitea.config.database.HOST=forgejo-db-restore-rw.${NS}.svc.cluster.local:5432 \
|
||||
--set gitea.config.database.PASSWD="${DB_PASS}" \
|
||||
--set gitea.config.server.DOMAIN=forgejo-restore.local \
|
||||
--set gitea.config.server.ROOT_URL=http://forgejo-restore.local:3000/ \
|
||||
--set gitea.config.mailer.ENABLED=false \
|
||||
--set gitea.admin.password=restore-drill-local-only \
|
||||
--set ingress.enabled=false \
|
||||
--wait --timeout=10m
|
||||
--wait --timeout=20m
|
||||
unset DB_PASS
|
||||
|
||||
step "Post-restore checks via port-forward"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue