eeff744dfc
Priority 1: Daily backup automation via Dagu DAG (~/dagu/dags/fn_backup.yaml, schedule "0 3 * * *"). Backs up registry.db, each operations.db, and vaults via rsync --link-dest. Fixes set -e arithmetic bugs in rotate_backups.sh and backup_all.sh ((var++) returns 1 when var=0). Fixes && chain set -e bug in vault rotation. Priority 2: Pre-commit hook v2 chains scan_secrets + uses_functions audit. New function git_hook_audit_app_drift_bash_infra blocks commits that touch app code when that app has uses_functions drift. Allows corrective app.md-only edits. Installed on fn_registry + 32 sub-repos. Priority 3: Synced uses_functions in 6 sub-repo apps (commits in their own repos): dag_engine, script_navegador, deploy_server, docker_tui, auto_metabase, metabase_registry. Drift went from 7/12 to 4/12 apps. Remaining drift = audit heuristic limitations (Python nested imports, Go symbol name detection). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
107 lines
3.6 KiB
Bash
107 lines
3.6 KiB
Bash
#!/usr/bin/env bash
|
|
# rotate_backups — retention policy estilo rsnapshot (daily/weekly/monthly)
|
|
|
|
rotate_backups() {
|
|
local dir="$1"
|
|
local new_file="$2"
|
|
local daily=7
|
|
local weekly=4
|
|
local monthly=12
|
|
|
|
# Parsear args posicionales o key=value
|
|
local i=3
|
|
for arg in "${@:3}"; do
|
|
case "$arg" in
|
|
daily=*) daily="${arg#daily=}" ;;
|
|
weekly=*) weekly="${arg#weekly=}" ;;
|
|
monthly=*) monthly="${arg#monthly=}" ;;
|
|
*)
|
|
case $i in
|
|
3) daily="$arg" ;;
|
|
4) weekly="$arg" ;;
|
|
5) monthly="$arg" ;;
|
|
esac
|
|
;;
|
|
esac
|
|
i=$((i + 1))
|
|
done
|
|
|
|
# Validar numericos
|
|
if ! [[ "$daily" =~ ^[0-9]+$ ]] || ! [[ "$weekly" =~ ^[0-9]+$ ]] || ! [[ "$monthly" =~ ^[0-9]+$ ]]; then
|
|
echo "ERROR: daily, weekly y monthly deben ser enteros positivos" >&2
|
|
return 3
|
|
fi
|
|
|
|
# Validar new_file
|
|
if [[ ! -e "$new_file" ]]; then
|
|
echo "ERROR: new_file no existe: $new_file" >&2
|
|
return 1
|
|
fi
|
|
|
|
# Crear directorio si no existe
|
|
if ! mkdir -p "$dir" 2>/dev/null; then
|
|
echo "ERROR: no se pudo crear el directorio: $dir" >&2
|
|
return 2
|
|
fi
|
|
|
|
local dow
|
|
dow=$(date +%w) # 0=domingo
|
|
local dom
|
|
dom=$(date +%d) # 01-31
|
|
|
|
local rotated_daily=0
|
|
local rotated_weekly=0
|
|
local rotated_monthly=0
|
|
|
|
# --- Monthly: si dia 1, rotar desde weekly.<weekly-1> ANTES de borrar ---
|
|
if [[ "$dom" == "01" ]] && (( monthly > 0 )); then
|
|
local weekly_src="$dir/weekly.$((weekly - 1))"
|
|
if [[ -e "$weekly_src" ]]; then
|
|
# Borrar monthly mas viejo
|
|
local oldest_monthly="$dir/monthly.$((monthly - 1))"
|
|
[[ -e "$oldest_monthly" ]] && rm -rf "$oldest_monthly"
|
|
# Desplazar monthly.<i> → monthly.<i+1>
|
|
for (( j = monthly - 2; j >= 0; j-- )); do
|
|
[[ -e "$dir/monthly.$j" ]] && mv "$dir/monthly.$j" "$dir/monthly.$((j+1))"
|
|
done
|
|
cp -a "$weekly_src" "$dir/monthly.0"
|
|
rotated_monthly=1
|
|
fi
|
|
fi
|
|
|
|
# --- Weekly: si domingo, rotar desde daily.<daily-1> ANTES de borrarlo ---
|
|
if [[ "$dow" == "0" ]] && (( weekly > 0 )); then
|
|
local daily_src="$dir/daily.$((daily - 1))"
|
|
if [[ -e "$daily_src" ]]; then
|
|
# Borrar weekly mas viejo
|
|
local oldest_weekly="$dir/weekly.$((weekly - 1))"
|
|
[[ -e "$oldest_weekly" ]] && rm -rf "$oldest_weekly"
|
|
# Desplazar weekly.<i> → weekly.<i+1>
|
|
for (( j = weekly - 2; j >= 0; j-- )); do
|
|
[[ -e "$dir/weekly.$j" ]] && mv "$dir/weekly.$j" "$dir/weekly.$((j+1))"
|
|
done
|
|
cp -a "$daily_src" "$dir/weekly.0"
|
|
rotated_weekly=1
|
|
fi
|
|
fi
|
|
|
|
# --- Daily: borrar el mas viejo, desplazar, mover new_file a daily.0 ---
|
|
local oldest_daily="$dir/daily.$((daily - 1))"
|
|
[[ -e "$oldest_daily" ]] && rm -rf "$oldest_daily"
|
|
|
|
for (( j = daily - 2; j >= 0; j-- )); do
|
|
[[ -e "$dir/daily.$j" ]] && mv "$dir/daily.$j" "$dir/daily.$((j+1))"
|
|
done
|
|
|
|
mv "$new_file" "$dir/daily.0"
|
|
rotated_daily=1
|
|
|
|
# Contar slots ocupados para el reporte
|
|
local cnt_daily=0 cnt_weekly=0 cnt_monthly=0
|
|
for (( j = 0; j < daily; j++ )); do [[ -e "$dir/daily.$j" ]] && cnt_daily=$((cnt_daily + 1)); done
|
|
for (( j = 0; j < weekly; j++ )); do [[ -e "$dir/weekly.$j" ]] && cnt_weekly=$((cnt_weekly + 1)); done
|
|
for (( j = 0; j < monthly; j++ )); do [[ -e "$dir/monthly.$j" ]] && cnt_monthly=$((cnt_monthly + 1)); done
|
|
|
|
echo "ROTATED daily=$cnt_daily weekly=$cnt_weekly monthly=$cnt_monthly dir=$dir"
|
|
}
|