From d354d989e748b1972734ede5d4cba42931e3e944 Mon Sep 17 00:00:00 2001 From: oliver Date: Tue, 21 Apr 2026 12:03:46 -0300 Subject: [PATCH] Backup 17, 18 changed --- app/sbin/backup/ODOO_17 | 80 +++++++++++++++++++++++++++++------------ app/sbin/backup/ODOO_18 | 80 +++++++++++++++++++++++++++++------------ app/sbin/backup/ODOO_19 | 2 +- 3 files changed, 115 insertions(+), 47 deletions(-) diff --git a/app/sbin/backup/ODOO_17 b/app/sbin/backup/ODOO_17 index 1e2dd70..7a90bb2 100755 --- a/app/sbin/backup/ODOO_17 +++ b/app/sbin/backup/ODOO_17 @@ -1,46 +1,80 @@ #!/bin/bash -# Backup Odoo database script -# Author: Your Name -# Description: Dumps Odoo DB, manages backups, and sets permissions +# Backup Odoo 19 database script +# Description: Dumps Odoo DB, manages backup rotation, and maintains a current.zip symlink set -euo pipefail # Fail on error, undefined variables, and pipe errors +log() { echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*"; } + # Load helper functions source /4server/sbin/helpers -# Get contract info +# Get contract info (also exports ODOO_DB_PASSWORD via helpers) get_contract_info -# Export Odoo database password -export ODOO_DB_PASSWORD -#ODOO_DB_PASSWORD=$(echo "$SECRET" | jq -r '.psql') +log "UUID: $UUID" +log "Backup slots: $BACKUP_SLOTS" +log "DB host: $POSTGRES_HOST" -# Display basic info -echo "UUID: $UUID" -echo "Backup slots: $BACKUP_SLOTS" - -# Create backup filename +# Build paths FILENAME="$(date +"%Y%m%d_%H%M").zip" BACKUP_DIR="/BACKUP/$UUID" +BB_DIR="$BACKUP_DIR/bb" -# Ensure backup directory exists -mkdir -p "$BACKUP_DIR" +# Ensure backup directories exist (requires elevated permissions like other ops) +doas mkdir -p "$BACKUP_DIR" +doas mkdir -p "$BB_DIR" -# Perform database dump using docker +# Perform database dump inside the container +log "Starting dump -> $BACKUP_DIR/$FILENAME" doas docker exec "$UUID" odoo db \ - --db_host beedb \ + --db_host "$POSTGRES_HOST" \ -r "$UUID" \ -w "$ODOO_DB_PASSWORD" \ --data-dir /home/odoo/.local/share/Odoo/ \ dump "$UUID" "/mnt/backup/$FILENAME" -# Set permissions for backup files -doas chmod 600 "$BACKUP_DIR"/* +log "Dump complete: $(doas du -sh "$BACKUP_DIR/$FILENAME" | cut -f1)" + +# Secure timestamped backups (scoped glob — leaves current.zip symlink untouched) +doas chmod 600 "$BACKUP_DIR"/[0-9]*.zip + +# Hand ownership back to odoo inside the container doas docker exec "$UUID" chown odoo:odoo -R /mnt/backup +# Update the current.zip symlink inside bb/ pointing at the backup just created. +# Target is relative (../$FILENAME) because the symlink lives one level deeper +# than the actual .zip files, so it stays valid if the directory is moved. +doas ln -sf "../$FILENAME" "$BB_DIR/current.zip" +log "bb/current.zip -> ../$FILENAME" -# Remove old backups beyond the configured slots -ls -t "$BACKUP_DIR"/[0-9]*.zip 2>/dev/null | tail -n +$((BACKUP_SLOTS + 1)) | while read -r file; do - echo "Deleting old backup: $file" - doas rm -f "$file" -done +# Remove old backups beyond the configured slot count +# Process substitution (< <(...)) keeps the loop in the main shell so +# set -e / exit codes propagate correctly — unlike a pipe subshell. +while IFS= read -r old_file; do + log "Deleting old backup: $old_file" + doas rm -f "$old_file" +done < <(ls -t "$BACKUP_DIR"/[0-9]*.zip 2>/dev/null | tail -n +$((BACKUP_SLOTS + 1))) + +log "Backup finished successfully." + +# --- Custom modules snapshot --- +# Archive /4server/data/$UUID/git-server/repos/local/custom/ into .current.tar.gz. +# Rebuilt only when at least one file inside is newer than the existing archive, +# so borg backup dedup sees an identical blob on unchanged runs. +CUSTOM_SRC="/4server/data/$UUID/git-server/repos/local/custom" +CUSTOM_ARCHIVE="$BB_DIR/current_modules.tar.gz" + +if [ ! -d "$CUSTOM_SRC" ]; then + log "Custom modules directory not found, skipping: $CUSTOM_SRC" +elif [ ! -f "$CUSTOM_ARCHIVE" ] || \ + doas find "$CUSTOM_SRC" -newer "$CUSTOM_ARCHIVE" -print -quit | grep -q .; then + log "Changes detected in custom modules — rebuilding current.tar.gz" + # Write to a temp file first; mv is atomic, so borg never sees a partial archive + doas tar -czf "${CUSTOM_ARCHIVE}.tmp" \ + -C "/4server/data/$UUID/git-server/repos/local" custom + doas mv "${CUSTOM_ARCHIVE}.tmp" "$CUSTOM_ARCHIVE" + log ".current.tar.gz updated: $(doas du -sh "$CUSTOM_ARCHIVE" | cut -f1)" +else + log "No changes in custom modules — current.tar.gz is up to date" +fi diff --git a/app/sbin/backup/ODOO_18 b/app/sbin/backup/ODOO_18 index 1e2dd70..7a90bb2 100755 --- a/app/sbin/backup/ODOO_18 +++ b/app/sbin/backup/ODOO_18 @@ -1,46 +1,80 @@ #!/bin/bash -# Backup Odoo database script -# Author: Your Name -# Description: Dumps Odoo DB, manages backups, and sets permissions +# Backup Odoo 19 database script +# Description: Dumps Odoo DB, manages backup rotation, and maintains a current.zip symlink set -euo pipefail # Fail on error, undefined variables, and pipe errors +log() { echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*"; } + # Load helper functions source /4server/sbin/helpers -# Get contract info +# Get contract info (also exports ODOO_DB_PASSWORD via helpers) get_contract_info -# Export Odoo database password -export ODOO_DB_PASSWORD -#ODOO_DB_PASSWORD=$(echo "$SECRET" | jq -r '.psql') +log "UUID: $UUID" +log "Backup slots: $BACKUP_SLOTS" +log "DB host: $POSTGRES_HOST" -# Display basic info -echo "UUID: $UUID" -echo "Backup slots: $BACKUP_SLOTS" - -# Create backup filename +# Build paths FILENAME="$(date +"%Y%m%d_%H%M").zip" BACKUP_DIR="/BACKUP/$UUID" +BB_DIR="$BACKUP_DIR/bb" -# Ensure backup directory exists -mkdir -p "$BACKUP_DIR" +# Ensure backup directories exist (requires elevated permissions like other ops) +doas mkdir -p "$BACKUP_DIR" +doas mkdir -p "$BB_DIR" -# Perform database dump using docker +# Perform database dump inside the container +log "Starting dump -> $BACKUP_DIR/$FILENAME" doas docker exec "$UUID" odoo db \ - --db_host beedb \ + --db_host "$POSTGRES_HOST" \ -r "$UUID" \ -w "$ODOO_DB_PASSWORD" \ --data-dir /home/odoo/.local/share/Odoo/ \ dump "$UUID" "/mnt/backup/$FILENAME" -# Set permissions for backup files -doas chmod 600 "$BACKUP_DIR"/* +log "Dump complete: $(doas du -sh "$BACKUP_DIR/$FILENAME" | cut -f1)" + +# Secure timestamped backups (scoped glob — leaves current.zip symlink untouched) +doas chmod 600 "$BACKUP_DIR"/[0-9]*.zip + +# Hand ownership back to odoo inside the container doas docker exec "$UUID" chown odoo:odoo -R /mnt/backup +# Update the current.zip symlink inside bb/ pointing at the backup just created. +# Target is relative (../$FILENAME) because the symlink lives one level deeper +# than the actual .zip files, so it stays valid if the directory is moved. +doas ln -sf "../$FILENAME" "$BB_DIR/current.zip" +log "bb/current.zip -> ../$FILENAME" -# Remove old backups beyond the configured slots -ls -t "$BACKUP_DIR"/[0-9]*.zip 2>/dev/null | tail -n +$((BACKUP_SLOTS + 1)) | while read -r file; do - echo "Deleting old backup: $file" - doas rm -f "$file" -done +# Remove old backups beyond the configured slot count +# Process substitution (< <(...)) keeps the loop in the main shell so +# set -e / exit codes propagate correctly — unlike a pipe subshell. +while IFS= read -r old_file; do + log "Deleting old backup: $old_file" + doas rm -f "$old_file" +done < <(ls -t "$BACKUP_DIR"/[0-9]*.zip 2>/dev/null | tail -n +$((BACKUP_SLOTS + 1))) + +log "Backup finished successfully." + +# --- Custom modules snapshot --- +# Archive /4server/data/$UUID/git-server/repos/local/custom/ into .current.tar.gz. +# Rebuilt only when at least one file inside is newer than the existing archive, +# so borg backup dedup sees an identical blob on unchanged runs. +CUSTOM_SRC="/4server/data/$UUID/git-server/repos/local/custom" +CUSTOM_ARCHIVE="$BB_DIR/current_modules.tar.gz" + +if [ ! -d "$CUSTOM_SRC" ]; then + log "Custom modules directory not found, skipping: $CUSTOM_SRC" +elif [ ! -f "$CUSTOM_ARCHIVE" ] || \ + doas find "$CUSTOM_SRC" -newer "$CUSTOM_ARCHIVE" -print -quit | grep -q .; then + log "Changes detected in custom modules — rebuilding current.tar.gz" + # Write to a temp file first; mv is atomic, so borg never sees a partial archive + doas tar -czf "${CUSTOM_ARCHIVE}.tmp" \ + -C "/4server/data/$UUID/git-server/repos/local" custom + doas mv "${CUSTOM_ARCHIVE}.tmp" "$CUSTOM_ARCHIVE" + log ".current.tar.gz updated: $(doas du -sh "$CUSTOM_ARCHIVE" | cut -f1)" +else + log "No changes in custom modules — current.tar.gz is up to date" +fi diff --git a/app/sbin/backup/ODOO_19 b/app/sbin/backup/ODOO_19 index 82b7c34..7a90bb2 100755 --- a/app/sbin/backup/ODOO_19 +++ b/app/sbin/backup/ODOO_19 @@ -76,5 +76,5 @@ elif [ ! -f "$CUSTOM_ARCHIVE" ] || \ doas mv "${CUSTOM_ARCHIVE}.tmp" "$CUSTOM_ARCHIVE" log ".current.tar.gz updated: $(doas du -sh "$CUSTOM_ARCHIVE" | cut -f1)" else - log "No changes in custom modules — .current.tar.gz is up to date" + log "No changes in custom modules — current.tar.gz is up to date" fi