fix(release): daily backups no longer replace the recovery point
Product chose to keep the scheduled backup, but the current recovery point must stay the one created by hand. Daily runs still encrypt and restore-verify, then record a separate latest-backup note. Co-Authored-By: Grok (agent loop)
This commit is contained in:
co-authored by
Grok (agent loop)
parent
6ba63470a9
commit
5c0d895391
+2
-1
@@ -401,7 +401,8 @@ report list / detail / create smoke”): `GET /api/reports` 200, owned
|
||||
### 备份
|
||||
|
||||
- 工作流:`.gitea/workflows/backup-production-daily.yml`。北京时间每天 04:00,也可手动触发。只从 `main` 运行,调用 `deploy/run-production-recovery.sh`,不另写一套导出。
|
||||
- 每日文件前缀是 `production-daily-`。手动恢复点仍是 `production-pre-migration-`。清理脚本 `deploy/prune-production-daily-backups.sh` 只删超过 7 天的每日文件和对应的校验文件。
|
||||
- 每日文件前缀是 `production-daily-`。手动恢复点仍是 `production-pre-migration-`。清理脚本 `deploy/prune-production-daily-backups.sh` 只删超过 7 天的每日文件和对应的校验文件,不会删 `production-pre-migration-` 手动恢复点。
|
||||
- 每日备份只做存档和还原核对,不是发布用的恢复点。它不改 `/opt/jyotisha-production/.state/recovery-baseline.env`。核对结果另写在同目录的 `daily-backup-latest.env`,只有文件名、sha256、核对时间和格式版本,没有数据和密钥。发布、迁移、回退都不读这个文件。上线前仍要手动点 Create production recovery。
|
||||
- Gitea 产物默认保留 14 天。手动恢复点工作流仍是 30 天,没有改。
|
||||
- 还原步骤:`docs/operations/production-restore-drill-20261014.md`。
|
||||
|
||||
|
||||
@@ -6,10 +6,26 @@ umask 077
|
||||
: "${DEPLOY_PATH:?DEPLOY_PATH is required}"
|
||||
: "${RECOVERY_RUN_ID:?RECOVERY_RUN_ID is required}"
|
||||
|
||||
[ "$DEPLOY_PATH" = "/opt/jyotisha-production" ] || {
|
||||
echo "unexpected production path" >&2
|
||||
exit 1
|
||||
}
|
||||
# Tests set JYOTISHA_RECOVERY_FIXTURE=1 and point DEPLOY_PATH at a temp directory.
|
||||
# Production workflows never set it, so the live path check stays closed.
|
||||
if [ "${JYOTISHA_RECOVERY_FIXTURE:-}" = "1" ]; then
|
||||
[ -d "$DEPLOY_PATH" ] && [ ! -L "$DEPLOY_PATH" ] || {
|
||||
echo "unexpected production path" >&2
|
||||
exit 1
|
||||
}
|
||||
case "$DEPLOY_PATH" in
|
||||
/*) ;;
|
||||
*)
|
||||
echo "unexpected production path" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
else
|
||||
[ "$DEPLOY_PATH" = "/opt/jyotisha-production" ] || {
|
||||
echo "unexpected production path" >&2
|
||||
exit 1
|
||||
}
|
||||
fi
|
||||
[[ "$RECOVERY_RUN_ID" =~ ^[0-9]+$ ]] || {
|
||||
echo "recovery run id must be numeric" >&2
|
||||
exit 1
|
||||
@@ -140,6 +156,8 @@ created_compact="$(date -u +%Y%m%dT%H%M%SZ)"
|
||||
created_at="$(date -u +%Y-%m-%dT%H:%M:%SZ)"
|
||||
# Daily backups set RECOVERY_BASENAME_PREFIX=production-daily so retention can
|
||||
# tell them from manual recovery points. Unset keeps the original name.
|
||||
# That same prefix is the switch that skips recovery-baseline.env. Daily runs
|
||||
# still export, encrypt, and restore-verify, then record daily-backup-latest.env.
|
||||
backup_prefix="production-pre-migration"
|
||||
if [ -n "${RECOVERY_BASENAME_PREFIX:-}" ]; then
|
||||
case "$RECOVERY_BASENAME_PREFIX" in
|
||||
@@ -226,11 +244,21 @@ printf '{\n "mode": "restore_verify",\n "ok": true,\n "backup": "%s",\n "sha
|
||||
chmod 600 "$verify_file"
|
||||
|
||||
recovery_reference="gitea-actions-run-${RECOVERY_RUN_ID}/${backup_basename}"
|
||||
state_tmp="$state_directory/recovery-baseline.env.tmp.$$"
|
||||
printf 'RECOVERY_REFERENCE=%s\nRECOVERY_CREATED_AT=%s\nRECOVERY_SHA256=%s\nRESTORE_VERIFIED=true\nRECOVERY_FORMAT=2\nVERIFY_FILE=%s\n' \
|
||||
"$recovery_reference" "$created_at" "$backup_sha256" "$verify_basename" >"$state_tmp"
|
||||
chmod 600 "$state_tmp"
|
||||
mv "$state_tmp" "$state_directory/recovery-baseline.env"
|
||||
if [ "$backup_prefix" = "production-daily" ]; then
|
||||
daily_tmp="$state_directory/daily-backup-latest.env.tmp.$$"
|
||||
printf 'BACKUP_BASENAME=%s\nBACKUP_SHA256=%s\nVERIFIED_AT=%s\nBACKUP_FORMAT=2\n' \
|
||||
"$backup_basename" "$backup_sha256" "$verified_at" >"$daily_tmp"
|
||||
chmod 600 "$daily_tmp"
|
||||
mv "$daily_tmp" "$state_directory/daily-backup-latest.env"
|
||||
echo "baseline_updated=false" >&2
|
||||
else
|
||||
state_tmp="$state_directory/recovery-baseline.env.tmp.$$"
|
||||
printf 'RECOVERY_REFERENCE=%s\nRECOVERY_CREATED_AT=%s\nRECOVERY_SHA256=%s\nRESTORE_VERIFIED=true\nRECOVERY_FORMAT=2\nVERIFY_FILE=%s\n' \
|
||||
"$recovery_reference" "$created_at" "$backup_sha256" "$verify_basename" >"$state_tmp"
|
||||
chmod 600 "$state_tmp"
|
||||
mv "$state_tmp" "$state_directory/recovery-baseline.env"
|
||||
echo "baseline_updated=true" >&2
|
||||
fi
|
||||
|
||||
printf 'RECOVERY_REFERENCE=%s\nRECOVERY_CREATED_AT=%s\nRECOVERY_VERIFIED_AT=%s\nRECOVERY_SHA256=%s\nRESTORE_VERIFIED=true\nBACKUP_BASENAME=%s\nVERIFY_BASENAME=%s\n' \
|
||||
"$recovery_reference" "$created_at" "$verified_at" "$backup_sha256" \
|
||||
|
||||
Reference in New Issue
Block a user