| #!/usr/bin/env bash |
| |
| |
| |
| |
|
|
| set -euo pipefail |
|
|
| BACKUP_ENV_FILE_PATH="${OPENCLAW_BACKUP_ENV_FILE_PATH:-/root/.env.d/openclaw-backup.env}" |
| BACKUP_LOG_DIR="${OPENCLAW_BACKUP_LOG_DIR:-/var/log/openclaw}" |
| BACKUP_LOG_FILE="${BACKUP_LOG_DIR}/backup.log" |
| HEALTH_CHECK_ENABLED="${OPENCLAW_BACKUP_HEALTH_CHECK_ENABLED:-false}" |
| HEALTH_CHECK_BEFORE="${OPENCLAW_BACKUP_HEALTH_CHECK_BEFORE:-false}" |
| HEALTH_CHECK_AFTER="${OPENCLAW_BACKUP_HEALTH_CHECK_AFTER:-false}" |
|
|
| |
| timestamp() { |
| date '+%Y-%m-%dT%H:%M:%S' |
| } |
|
|
| |
| log() { |
| echo "[$(timestamp)] $*" >> "$BACKUP_LOG_FILE" |
| } |
|
|
| is_true() { |
| local value |
| value="$(printf '%s' "${1:-}" | tr '[:upper:]' '[:lower:]')" |
| [[ "$value" == "1" || "$value" == "true" || "$value" == "yes" || "$value" == "on" ]] |
| } |
|
|
| |
| load_env() { |
| if [[ -f "$BACKUP_ENV_FILE_PATH" ]]; then |
| |
| if ! source "$BACKUP_ENV_FILE_PATH"; then |
| log "ERROR: Failed to source $BACKUP_ENV_FILE_PATH" |
| return 1 |
| fi |
| log "INFO: Loaded environment from $BACKUP_ENV_FILE_PATH" |
| else |
| log "WARN: Environment file not found: $BACKUP_ENV_FILE_PATH" |
| fi |
| } |
|
|
| |
| run_health_check() { |
| if [[ "$HEALTH_CHECK_ENABLED" != "true" ]]; then |
| log "INFO: Health check is disabled" |
| return 0 |
| fi |
| |
| log "INFO: Running pre-backup health check..." |
| |
| if /usr/local/bin/openclaw-backup-health.sh --check >> "$BACKUP_LOG_FILE" 2>&1; then |
| log "INFO: Health check passed" |
| return 0 |
| else |
| log "WARN: Health check failed, attempting repair..." |
| |
| |
| if /usr/local/bin/openclaw-backup-health.sh --repair >> "$BACKUP_LOG_FILE" 2>&1; then |
| log "INFO: Repair successful, retrying health check..." |
| |
| |
| if /usr/local/bin/openclaw-backup-health.sh --check >> "$BACKUP_LOG_FILE" 2>&1; then |
| log "INFO: Health check passed after repair" |
| return 0 |
| else |
| log "ERROR: Health check still failing after repair" |
| return 1 |
| fi |
| else |
| log "ERROR: Repair failed" |
| return 1 |
| fi |
| fi |
| } |
|
|
| |
| run_backup_with_retry() { |
| local max_retries="${OPENCLAW_BACKUP_MAX_RETRIES:-3}" |
| local retry_count=0 |
| local backup_success=false |
| |
| while [[ $retry_count -lt $max_retries ]]; do |
| ((retry_count++)) |
| log "INFO: Backup attempt $retry_count/$max_retries" |
| |
| local exit_code=0 |
| python3 /opt/openclaw-hf/openclaw_hf/backup.py backup >> "$BACKUP_LOG_FILE" 2>&1 || exit_code=$? |
| if [[ $exit_code -eq 0 ]]; then |
| log "INFO: Backup completed successfully on attempt $retry_count" |
| backup_success=true |
| break |
| else |
| log "ERROR: Backup failed on attempt $retry_count (exit code: $exit_code)" |
|
|
| if [[ $retry_count -lt $max_retries ]]; then |
| local retry_delay=$((retry_count * 10)) |
| log "INFO: Waiting ${retry_delay}s before retry..." |
| sleep $retry_delay |
|
|
| |
| log "INFO: Attempting repair before retry..." |
| /usr/local/bin/openclaw-backup-health.sh --repair >> "$BACKUP_LOG_FILE" 2>&1 || true |
| fi |
| fi |
| done |
| |
| if [[ "$backup_success" == "true" ]]; then |
| return 0 |
| else |
| log "ERROR: Backup failed after $max_retries attempts" |
| return 1 |
| fi |
| } |
|
|
| |
| post_backup_check() { |
| if [[ "$HEALTH_CHECK_AFTER" != "true" ]]; then |
| return 0 |
| fi |
| |
| log "INFO: Running post-backup health check..." |
| |
| |
| if [[ -f "$BACKUP_LOG_FILE" ]]; then |
| local last_backup |
| last_backup=$(grep -i "backup complete" "$BACKUP_LOG_FILE" | tail -1) |
| |
| if [[ -n "$last_backup" ]]; then |
| log "INFO: Post-backup check: Backup log shows completion" |
| return 0 |
| else |
| log "WARN: Post-backup check: No completion found in logs" |
| return 1 |
| fi |
| fi |
| |
| return 0 |
| } |
|
|
| |
| main() { |
| |
| mkdir -p "$BACKUP_LOG_DIR" |
|
|
| log "========================================" |
| log "OpenClaw Backup Starting" |
| log "========================================" |
|
|
| |
| load_env |
|
|
| |
| if ! is_true "${OPENCLAW_BACKUP_ENABLED:-false}"; then |
| log "INFO: Backup is disabled (OPENCLAW_BACKUP_ENABLED=false), skipping" |
| exit 0 |
| fi |
|
|
| |
| if [[ "$HEALTH_CHECK_BEFORE" == "true" ]]; then |
| if ! run_health_check; then |
| log "ERROR: Pre-backup health check failed, aborting backup" |
| exit 1 |
| fi |
| fi |
| |
| |
| if run_backup_with_retry; then |
| log "INFO: Backup process completed successfully" |
| |
| |
| post_backup_check |
| |
| log "========================================" |
| log "OpenClaw Backup Finished Successfully" |
| log "========================================" |
| exit 0 |
| else |
| log "ERROR: Backup process failed" |
| |
| |
| log "INFO: Running emergency repair..." |
| /usr/local/bin/openclaw-backup-health.sh --emergency >> "$BACKUP_LOG_FILE" 2>&1 || true |
| |
| log "========================================" |
| log "OpenClaw Backup Failed" |
| log "========================================" |
| exit 1 |
| fi |
| } |
|
|
| |
| main "$@" |
|
|