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
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:
@@ -33,7 +33,7 @@ main() {
|
|||||||
|
|
||||||
# Step 2: SSH 到 188 將 Redis volume 打包傳回
|
# Step 2: SSH 到 188 將 Redis volume 打包傳回
|
||||||
log_info "從 192.168.0.188 拉取 clawbot-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)
|
local size=$(du -h "${DUMP_DIR}/clawbot-redis_${timestamp}.tar.gz" | cut -f1)
|
||||||
log_success "ClawBot Redis volume 拉取完成 (${size})"
|
log_success "ClawBot Redis volume 拉取完成 (${size})"
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -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_WEEKLY=12 # 2026-04-05 Claude Code: 延長保留 (原4→12)
|
||||||
export KEEP_MONTHLY=24 # 2026-04-05 Claude Code: 延長保留 (原6→24)
|
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}"
|
||||||
|
|
||||||
# -----------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------
|
||||||
# 日誌函式
|
# 日誌函式
|
||||||
# -----------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------
|
||||||
|
|||||||
@@ -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
|
||||||
Reference in New Issue
Block a user