fix(backup): bound cron backup containers
Some checks failed
CD Pipeline / workflow-shape (push) Successful in 0s
CD Pipeline / cancel-stale-cd (push) Has been skipped
CD Pipeline / tests (push) Successful in 2m33s
CD Pipeline / build-and-deploy (push) Failing after 15m14s
AWOOOI Harbor 110 Local Repair / workflow-shape (push) Successful in 1s
CD Pipeline / post-deploy-checks (push) Has been skipped
AWOOOI Harbor 110 Local Repair / harbor-110-local-repair (push) Successful in 23s

This commit is contained in:
Your Name
2026-07-18 17:23:50 +08:00
parent f493fe8dcb
commit efe1ba0505
3 changed files with 41 additions and 1 deletions

View File

@@ -33,7 +33,7 @@ main() {
# Step 2: SSH 到 188 將 Redis volume 打包傳回
log_info "從 192.168.0.188 拉取 clawbot-redis volume..."
if ssh "${REMOTE_HOST}" "docker run --rm -v clawbot-v5_clawbot-redis-data:/data alpine tar czf - /data 2>/dev/null" > "${DUMP_DIR}/clawbot-redis_${timestamp}.tar.gz"; then
if ssh "${REMOTE_HOST}" "docker run --rm --cpus=$(printf '%q' "${BACKUP_DOCKER_CPUS}") --memory=$(printf '%q' "${BACKUP_DOCKER_MEMORY}") --memory-swap=$(printf '%q' "${BACKUP_DOCKER_MEMORY_SWAP}") -v clawbot-v5_clawbot-redis-data:/data:ro alpine tar czf - /data 2>/dev/null" > "${DUMP_DIR}/clawbot-redis_${timestamp}.tar.gz"; then
local size=$(du -h "${DUMP_DIR}/clawbot-redis_${timestamp}.tar.gz" | cut -f1)
log_success "ClawBot Redis volume 拉取完成 (${size})"
else

View File

@@ -25,6 +25,11 @@ export KEEP_DAILY=30 # 2026-04-05 Claude Code: 延長保留 (原7→30)
export KEEP_WEEKLY=12 # 2026-04-05 Claude Code: 延長保留 (原4→12)
export KEEP_MONTHLY=24 # 2026-04-05 Claude Code: 延長保留 (原6→24)
# Ephemeral backup containers must remain bounded even when cron has no env file.
export BACKUP_DOCKER_CPUS="${BACKUP_DOCKER_CPUS:-1.0}"
export BACKUP_DOCKER_MEMORY="${BACKUP_DOCKER_MEMORY:-1g}"
export BACKUP_DOCKER_MEMORY_SWAP="${BACKUP_DOCKER_MEMORY_SWAP:-1g}"
# -----------------------------------------------------------------------------
# 日誌函式
# -----------------------------------------------------------------------------

View File

@@ -0,0 +1,35 @@
from __future__ import annotations
from pathlib import Path
ROOT = Path(__file__).resolve().parents[3]
COMMON = ROOT / "scripts" / "backup" / "common.sh"
CLAWBOT = ROOT / "scripts" / "backup" / "backup-clawbot.sh"
SENTRY = ROOT / "scripts" / "backup" / "backup-sentry.sh"
def test_common_defines_bounded_container_defaults_for_cron() -> None:
source = COMMON.read_text(encoding="utf-8")
assert 'BACKUP_DOCKER_CPUS="${BACKUP_DOCKER_CPUS:-1.0}"' in source
assert 'BACKUP_DOCKER_MEMORY="${BACKUP_DOCKER_MEMORY:-1g}"' in source
assert 'BACKUP_DOCKER_MEMORY_SWAP="${BACKUP_DOCKER_MEMORY_SWAP:-1g}"' in source
def test_sentry_and_clawbot_backup_containers_use_the_bounded_contract() -> None:
common = COMMON.read_text(encoding="utf-8")
for script in (CLAWBOT, SENTRY):
source = script.read_text(encoding="utf-8")
assert 'source "$(dirname "$0")/common.sh"' in source
for variable in (
"BACKUP_DOCKER_CPUS",
"BACKUP_DOCKER_MEMORY",
"BACKUP_DOCKER_MEMORY_SWAP",
):
assert variable in common
assert variable in source
clawbot = CLAWBOT.read_text(encoding="utf-8")
assert "clawbot-v5_clawbot-redis-data:/data:ro" in clawbot