补强生产数据路径与备份来源护栏(07-26-internal-ops-recovery-baseline)
这个提交包含在:
+25
-3
@@ -4,12 +4,32 @@ set -euo pipefail
|
||||
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||
BACKUP_DIR="${BACKUP_DIR:-$ROOT_DIR/deploy/trialrun/backups}"
|
||||
BACKUP_RUN_ID="${BACKUP_RUN_ID:-$(date -u +%Y%m%dT%H%M%SZ)}"
|
||||
BUILD_SHA="${BUILD_SHA:-}"
|
||||
SOURCE_IMAGE_DIGEST="${SOURCE_IMAGE_DIGEST:-}"
|
||||
|
||||
if [[ ! "$BACKUP_RUN_ID" =~ ^[A-Za-z0-9][A-Za-z0-9._-]{0,79}$ ]]; then
|
||||
echo "[ERR] BACKUP_RUN_ID must use 1-80 safe characters" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ -z "$BUILD_SHA" ]]; then
|
||||
BUILD_SHA="$(git -C "$ROOT_DIR" rev-parse --short=12 HEAD 2>/dev/null || true)"
|
||||
fi
|
||||
if [[ -n "$BUILD_SHA" && ! "$BUILD_SHA" =~ ^[0-9a-fA-F]{7,64}$ ]]; then
|
||||
echo "[ERR] BUILD_SHA must be a 7-64 character hexadecimal commit id" >&2
|
||||
exit 1
|
||||
fi
|
||||
if [[ -n "$SOURCE_IMAGE_DIGEST" && ! "$SOURCE_IMAGE_DIGEST" =~ ^sha256:[0-9a-fA-F]{64}$ ]]; then
|
||||
echo "[ERR] SOURCE_IMAGE_DIGEST must use sha256:<64 hexadecimal characters>" >&2
|
||||
exit 1
|
||||
fi
|
||||
if [[ -z "$BUILD_SHA" && -z "$SOURCE_IMAGE_DIGEST" ]]; then
|
||||
echo "[ERR] BUILD_SHA or SOURCE_IMAGE_DIGEST is required to identify the backup source" >&2
|
||||
exit 1
|
||||
fi
|
||||
BUILD_SHA="${BUILD_SHA,,}"
|
||||
SOURCE_IMAGE_DIGEST="${SOURCE_IMAGE_DIGEST,,}"
|
||||
|
||||
mkdir -p "$BACKUP_DIR"
|
||||
FINAL_DIR="$BACKUP_DIR/hyb-oa-backup-$BACKUP_RUN_ID"
|
||||
if [[ -e "$FINAL_DIR" ]]; then
|
||||
@@ -64,23 +84,23 @@ DB_SHA256="$(sha256sum "$DB_FILE" | awk '{print $1}')"
|
||||
STORAGE_SHA256="$(sha256sum "$STORAGE_FILE" | awk '{print $1}')"
|
||||
DB_BYTES="$(wc -c <"$DB_FILE" | tr -d ' ')"
|
||||
STORAGE_BYTES="$(wc -c <"$STORAGE_FILE" | tr -d ' ')"
|
||||
BUILD_SHA="$(git -C "$ROOT_DIR" rev-parse --short=12 HEAD 2>/dev/null || true)"
|
||||
CREATED_AT="$(date -u +%Y-%m-%dT%H:%M:%SZ)"
|
||||
|
||||
MANIFEST_ARGS=(
|
||||
"$TEMP_DIR/$MANIFEST_NAME" "$BACKUP_RUN_ID" "$CREATED_AT" "$BUILD_SHA"
|
||||
"$TEMP_DIR/$MANIFEST_NAME" "$BACKUP_RUN_ID" "$CREATED_AT" "$BUILD_SHA" "$SOURCE_IMAGE_DIGEST"
|
||||
"$DB_NAME" "$DB_BYTES" "$DB_SHA256" "$STORAGE_NAME" "$STORAGE_BYTES" "$STORAGE_SHA256"
|
||||
)
|
||||
|
||||
if command -v node >/dev/null 2>&1; then
|
||||
node - "${MANIFEST_ARGS[@]}" <<'NODE'
|
||||
const fs = require("node:fs");
|
||||
const [manifestPath, runId, createdAt, buildSha, dbFile, dbBytes, dbSha256, storageFile, storageBytes, storageSha256] = process.argv.slice(2);
|
||||
const [manifestPath, runId, createdAt, buildSha, sourceImageDigest, dbFile, dbBytes, dbSha256, storageFile, storageBytes, storageSha256] = process.argv.slice(2);
|
||||
const manifest = {
|
||||
schemaVersion: 1,
|
||||
runId,
|
||||
createdAt,
|
||||
buildSha: buildSha || null,
|
||||
sourceImageDigest: sourceImageDigest || null,
|
||||
status: "complete",
|
||||
artifacts: {
|
||||
database: { file: dbFile, bytes: Number(dbBytes), sha256: dbSha256 },
|
||||
@@ -99,6 +119,7 @@ import sys
|
||||
run_id,
|
||||
created_at,
|
||||
build_sha,
|
||||
source_image_digest,
|
||||
db_file,
|
||||
db_bytes,
|
||||
db_sha256,
|
||||
@@ -112,6 +133,7 @@ manifest = {
|
||||
"runId": run_id,
|
||||
"createdAt": created_at,
|
||||
"buildSha": build_sha or None,
|
||||
"sourceImageDigest": source_image_digest or None,
|
||||
"status": "complete",
|
||||
"artifacts": {
|
||||
"database": {"file": db_file, "bytes": int(db_bytes), "sha256": db_sha256},
|
||||
|
||||
在新工单中引用
屏蔽一个用户