Refactor: Rename project from QuantumRick to Citadel

- Update README.md title and project structure references
- Update script headers in install and manage scripts
- Update configuration comments in backup.env.sample
- Update Restic configuration comment in install script
- Maintain consistency across all project documentation

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Nicolas Duhamel 2025-06-26 17:04:18 +02:00
parent 9bb47abc95
commit f314fd06d3
9 changed files with 185 additions and 135 deletions

View File

@ -1,11 +1,11 @@
# QuantumRick Backup System # Citadel Backup System
Système de sauvegarde automatisé basé sur Restic avec intégration systemd pour services containerisés. Système de sauvegarde automatisé basé sur Restic avec intégration systemd pour services containerisés.
## Structure du Projet ## Structure du Projet
``` ```
quantumrick/ citadel/
├── backup.env # Configuration centralisée ├── backup.env # Configuration centralisée
├── manage # Interface principale de gestion ├── manage # Interface principale de gestion
├── install # Script d'installation et configuration ├── install # Script d'installation et configuration

View File

@ -1,78 +1,55 @@
#!/bin/bash #!/bin/bash
# Configuration centralisée pour le système de backup quantumrick # Configuration centralisée pour le système de backup citadel
# Copiez ce fichier vers backup.env et adaptez les valeurs selon votre environnement # Copiez ce fichier vers backup.env et adaptez les valeurs selon votre environnement
# === Configuration Utilisateur === # === Configuration Essentielle ===
# Utilisateur système qui exécutera les backups # Utilisateur système qui exécutera les backups
BACKUP_USER="${BACKUP_USER:-citadel}" CITADEL_USER="${CITADEL_USER:-citadel}"
BACKUP_HOME="${BACKUP_HOME:-/home/$BACKUP_USER}" # Racine du projet citadel
PROJECT_ROOT="${PROJECT_ROOT:-/home/nicolas/dev/citadel}"
# === Répertoires Principaux ===
# Racine du projet quantumrick
PROJECT_ROOT="${PROJECT_ROOT:-/home/nicolas/dev/quantumrick}"
# Répertoire où les scripts de backup sont installés
BACKUP_BASE_DIR="${BACKUP_BASE_DIR:-$BACKUP_HOME/backup}"
# Répertoire contenant les services à sauvegarder # Répertoire contenant les services à sauvegarder
SERVICES_BASE_DIR="${SERVICES_BASE_DIR:-$BACKUP_HOME/services}" SERVICES_BASE_DIR="${SERVICES_BASE_DIR:-/home/$CITADEL_USER/services}"
# Répertoire de configuration du projet
CONFIG_DIR="${CONFIG_DIR:-$PROJECT_ROOT/config}"
# === Stockage des Sauvegardes === # === Stockage Restic ===
# Chemin de base pour le stockage des backups # Chemin de base pour le stockage des backups
BACKUP_STORAGE_PATH="${BACKUP_STORAGE_PATH:-/mnt/data/backup}" RESTIC_STORAGE="${RESTIC_STORAGE:-/mnt/data/backup}"
# Nom du repository Restic # Nom du repository Restic
BACKUP_REPO_NAME="${BACKUP_REPO_NAME:-quantumrick}" RESTIC_REPO="${RESTIC_REPO:-citadel}"
# Chemin complet du repository Restic
BACKUP_REPOSITORY="${BACKUP_REPOSITORY:-$BACKUP_STORAGE_PATH/$BACKUP_REPO_NAME}"
# === Système === # === Système ===
# Répertoire des services systemd # Planning de sauvegarde par défaut (format systemd)
SYSTEMD_DIR="${SYSTEMD_DIR:-/etc/systemd/system}" # Exemples: "*-*-* 03:00:00" (quotidien 3h), "Mon *-*-* 04:00:00" (lundi 4h)
DEFAULT_BACKUP_SCHEDULE="${DEFAULT_BACKUP_SCHEDULE:-*-*-* 03:00:00}"
# Répertoire des logs système # Répertoire des logs système
LOG_DIR="${LOG_DIR:-/var/log}" LOG_DIR="${LOG_DIR:-/var/log}"
# Répertoire temporaire # Répertoire temporaire
TEMP_DIR="${TEMP_DIR:-/tmp}" TEMP_DIR="${TEMP_DIR:-/tmp}"
# === Restic Configuration ===
# Cache Restic
RESTIC_CACHE_DIR="${RESTIC_CACHE_DIR:-$TEMP_DIR/restic-cache}"
# Fichier de configuration Restic (généré automatiquement) # Fichier de configuration Restic (généré automatiquement)
RESTIC_CONFIG_FILE="${RESTIC_CONFIG_FILE:-$CONFIG_DIR/restic.conf}" RESTIC_CONFIG_FILE="${RESTIC_CONFIG_FILE:-$PROJECT_ROOT/config/restic.conf}"
# === Templates systemd === # === Politique de Rétention ===
# Nom des fichiers templates # Nombre de sauvegardes quotidiennes à conserver
RETENTION_DAILY="${RETENTION_DAILY:-7}"
# Nombre de sauvegardes hebdomadaires à conserver
RETENTION_WEEKLY="${RETENTION_WEEKLY:-4}"
# Nombre de sauvegardes mensuelles à conserver
RETENTION_MONTHLY="${RETENTION_MONTHLY:-12}"
# Nombre de sauvegardes annuelles à conserver
RETENTION_YEARLY="${RETENTION_YEARLY:-3}"
# === Variables Dérivées (automatiquement calculées) ===
BACKUP_USER="$CITADEL_USER"
BACKUP_HOME="${BACKUP_HOME:-/home/$CITADEL_USER}"
BACKUP_BASE_DIR="${BACKUP_BASE_DIR:-$BACKUP_HOME/backup}"
BACKUP_STORAGE_PATH="$RESTIC_STORAGE"
BACKUP_REPO_NAME="$RESTIC_REPO"
BACKUP_REPOSITORY="${BACKUP_REPOSITORY:-$RESTIC_STORAGE/$RESTIC_REPO}"
RESTIC_CACHE_DIR="${RESTIC_CACHE_DIR:-$TEMP_DIR/restic-cache}"
CONFIG_DIR="${CONFIG_DIR:-$PROJECT_ROOT/config}"
SYSTEMD_DIR="${SYSTEMD_DIR:-/etc/systemd/system}"
SERVICE_TEMPLATE="${SERVICE_TEMPLATE:-service-backup@.service}" SERVICE_TEMPLATE="${SERVICE_TEMPLATE:-service-backup@.service}"
TIMER_TEMPLATE="${TIMER_TEMPLATE:-service-backup@.timer}" TIMER_TEMPLATE="${TIMER_TEMPLATE:-service-backup@.timer}"
# === Planning par défaut ===
# Planning de sauvegarde par défaut (format systemd)
# Exemples: "*-*-* 03:00:00" (quotidien 3h), "Mon *-*-* 04:00:00" (lundi 4h)
DEFAULT_BACKUP_SCHEDULE="${DEFAULT_BACKUP_SCHEDULE:-*-*-* 03:00:00}"
# === Variables d'export pour Restic === # === Variables d'export pour Restic ===
export RESTIC_REPOSITORY="$BACKUP_REPOSITORY" export RESTIC_REPOSITORY="$BACKUP_REPOSITORY"
export RESTIC_CACHE_DIR export RESTIC_CACHE_DIR
# Fonction utilitaire pour valider les chemins
validate_paths() {
local paths=("$BACKUP_HOME" "$SERVICES_BASE_DIR" "$(dirname "$BACKUP_STORAGE_PATH")")
for path in "${paths[@]}"; do
if [[ ! -d "$path" ]]; then
echo "WARN: Directory $path does not exist" >&2
fi
done
}
# Fonction pour afficher la configuration courante
show_config() {
echo "=== Configuration Backup ==="
echo "BACKUP_USER: $BACKUP_USER"
echo "BACKUP_HOME: $BACKUP_HOME"
echo "BACKUP_BASE_DIR: $BACKUP_BASE_DIR"
echo "SERVICES_BASE_DIR: $SERVICES_BASE_DIR"
echo "BACKUP_REPOSITORY: $BACKUP_REPOSITORY"
echo "RESTIC_CONFIG_FILE: $RESTIC_CONFIG_FILE"
echo "SYSTEMD_DIR: $SYSTEMD_DIR"
echo "LOG_DIR: $LOG_DIR"
echo "DEFAULT_BACKUP_SCHEDULE: $DEFAULT_BACKUP_SCHEDULE"
}

View File

@ -36,9 +36,9 @@ BACKUP_SCRIPT="$SERVICE_DIR/backup.sh"
BACKUP_DIR="$BACKUP_BASE_DIR" BACKUP_DIR="$BACKUP_BASE_DIR"
# Systemd template files # Systemd template files
SERVICE_TEMPLATE="$SERVICE_TEMPLATE" SERVICE_TEMPLATE="service-backup@.service"
TIMER_TEMPLATE="$TIMER_TEMPLATE" TIMER_TEMPLATE="service-backup@.timer"
SYSTEMD_DIR="$SYSTEMD_DIR" SYSTEMD_DIR="/etc/systemd/system"
# Instance names # Instance names
SERVICE_INSTANCE="service-backup@$SERVICE_NAME.service" SERVICE_INSTANCE="service-backup@$SERVICE_NAME.service"
@ -70,13 +70,13 @@ fi
chmod +x "$BACKUP_SCRIPT" chmod +x "$BACKUP_SCRIPT"
# Check if template files exist # Check if template files exist
if [ ! -f "$BACKUP_DIR/$SERVICE_TEMPLATE" ]; then if [ ! -f "$BACKUP_DIR/service-backup@.service" ]; then
echo "ERROR: Service template not found: $BACKUP_DIR/$SERVICE_TEMPLATE" echo "ERROR: Service template not found: $BACKUP_DIR/service-backup@.service"
exit 1 exit 1
fi fi
if [ ! -f "$BACKUP_DIR/$TIMER_TEMPLATE" ]; then if [ ! -f "$BACKUP_DIR/service-backup@.timer" ]; then
echo "ERROR: Timer template not found: $BACKUP_DIR/$TIMER_TEMPLATE" echo "ERROR: Timer template not found: $BACKUP_DIR/service-backup@.timer"
exit 1 exit 1
fi fi
@ -95,20 +95,20 @@ fi
echo "Generating service file with current configuration..." echo "Generating service file with current configuration..."
sed -e "s|\${BACKUP_USER}|$BACKUP_USER|g" \ sed -e "s|\${BACKUP_USER}|$BACKUP_USER|g" \
-e "s|\${SERVICES_BASE_DIR}|$SERVICES_BASE_DIR|g" \ -e "s|\${SERVICES_BASE_DIR}|$SERVICES_BASE_DIR|g" \
"$BACKUP_DIR/$SERVICE_TEMPLATE" > "$SYSTEMD_DIR/$SERVICE_TEMPLATE" "$BACKUP_DIR/service-backup@.service" > "/etc/systemd/system/service-backup@.service"
chmod 644 "$SYSTEMD_DIR/$SERVICE_TEMPLATE" chmod 644 "/etc/systemd/system/service-backup@.service"
echo "Generating timer file with current configuration..." echo "Generating timer file with current configuration..."
sed -e "s|\${DEFAULT_BACKUP_SCHEDULE}|$DEFAULT_BACKUP_SCHEDULE|g" \ sed -e "s|\${DEFAULT_BACKUP_SCHEDULE}|$DEFAULT_BACKUP_SCHEDULE|g" \
"$BACKUP_DIR/$TIMER_TEMPLATE" > "$SYSTEMD_DIR/$TIMER_TEMPLATE" "$BACKUP_DIR/service-backup@.timer" > "/etc/systemd/system/service-backup@.timer"
chmod 644 "$SYSTEMD_DIR/$TIMER_TEMPLATE" chmod 644 "/etc/systemd/system/service-backup@.timer"
# Create custom timer with specific schedule if different from default # Create custom timer with specific schedule if different from default
if [ "$SCHEDULE" != "$DEFAULT_BACKUP_SCHEDULE" ]; then if [ "$SCHEDULE" != "$DEFAULT_BACKUP_SCHEDULE" ]; then
echo "Creating custom timer with schedule: $SCHEDULE" echo "Creating custom timer with schedule: $SCHEDULE"
sed "s|OnCalendar=\*-\*-\* 03:00:00|OnCalendar=$SCHEDULE|" \ sed "s|OnCalendar=\*-\*-\* 03:00:00|OnCalendar=$SCHEDULE|" \
"$BACKUP_DIR/$TIMER_TEMPLATE" > "$SYSTEMD_DIR/$TIMER_INSTANCE" "$BACKUP_DIR/service-backup@.timer" > "/etc/systemd/system/$TIMER_INSTANCE"
chmod 644 "$SYSTEMD_DIR/$TIMER_INSTANCE" chmod 644 "/etc/systemd/system/$TIMER_INSTANCE"
fi fi
# Reload systemd # Reload systemd

View File

@ -0,0 +1,102 @@
#!/bin/bash
# Generic Service Script Template for Citadel Backup System
# This template provides standardized configuration for all service scripts
# Usage: Source this template at the beginning of service backup/restore scripts
# Auto-configure via backup.env
# Calculate PROJECT_ROOT based on where template is sourced from
# Template is in backup/, so from services/service_name/ we need to go ../../
if [[ "${BASH_SOURCE[1]}" == */services/* ]]; then
# Sourced from a service script
PROJECT_ROOT="$(cd "$(dirname "${BASH_SOURCE[1]}")/../.." && pwd)"
else
# Sourced from backup/ directory or elsewhere
SCRIPT_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(cd "$SCRIPT_ROOT/.." && pwd)"
fi
# Source centralized configuration
if [ -f "$PROJECT_ROOT/backup.env" ]; then
source "$PROJECT_ROOT/backup.env"
else
echo "ERROR: Configuration file backup.env not found in $PROJECT_ROOT" >&2
echo "Please ensure backup.env exists in project root directory" >&2
exit 1
fi
# Variables universelles pour tout service (auto-dérivées)
# Detect service name from the script that sources this template
if [[ "${BASH_SOURCE[1]}" == */services/* ]]; then
SERVICE_NAME="$(basename "$(dirname "${BASH_SOURCE[1]}")")"
else
SERVICE_NAME="$(basename "$(dirname "$0")")"
fi
SERVICE_DIR="$SERVICES_BASE_DIR/$SERVICE_NAME"
CONFIG_FILE="$RESTIC_CONFIG_FILE"
LOG_FILE="$LOG_DIR/$SERVICE_NAME-backup.log"
DATA_DIR="${DATA_DIR:-$(dirname "$SERVICES_BASE_DIR")/data/$SERVICE_NAME}"
TEMP_BACKUP_DIR="$TEMP_DIR/$SERVICE_NAME-backup"
# Logging functions
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1"
}
error() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] ERROR: $1" >&2
}
success() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] SUCCESS: $1"
}
# Function to apply retention policy
apply_retention() {
local service_tag="$1"
log "Applying retention policy for $service_tag"
restic forget --tag "$service_tag" \
--keep-daily "$RETENTION_DAILY" \
--keep-weekly "$RETENTION_WEEKLY" \
--keep-monthly "$RETENTION_MONTHLY" \
--keep-yearly "$RETENTION_YEARLY" \
--prune
if [ $? -eq 0 ]; then
success "Retention policy applied successfully"
else
error "Failed to apply retention policy"
return 1
fi
}
# Function to setup logging
setup_logging() {
# Redirect stdout and stderr to log file while keeping console output
exec 1> >(tee -a "$LOG_FILE")
exec 2> >(tee -a "$LOG_FILE" >&2)
}
# Function to cleanup on exit
cleanup_on_exit() {
log "Cleaning up temporary files..."
[ -d "$TEMP_BACKUP_DIR" ] && rm -rf "$TEMP_BACKUP_DIR"
# Ensure containers are running in case of error
if [ -f "$SERVICE_DIR/docker-compose.yml" ]; then
if docker compose -f "$SERVICE_DIR/docker-compose.yml" ps --services --filter "status=exited" | grep -q .; then
log "Some containers are stopped, restarting..."
cd "$SERVICE_DIR"
docker compose up -d
fi
fi
}
# Export commonly used variables
export SERVICE_NAME
export SERVICE_DIR
export CONFIG_FILE
export LOG_FILE
export DATA_DIR
export TEMP_BACKUP_DIR

View File

@ -2,11 +2,11 @@
This file provides guidance to Claude Code when working with this repository. This file provides guidance to Claude Code when working with this repository.
This is a pack of script for manage a self hosted server. This is a pack of script named citadel for manage a self hosted server, for personnal usage.
IMPORTANT Keep things simple. Ne rajoute pas de fonctionnalitée non spécifiquement souhaité. Si tu penses qu'une nouvelle fonctionnalitée est fortement souhaitable demande moi avant.
Use shell script.
Ne prévoit pas de script ou documentation de migration sauf si demandé explicitement.
I interact with you in french, you can anwser in french I interact with you in french, you can anwser in french
IMPORTANT all code comment and documentation must be write in english IMPORTANT all code comment and documentation must be write in english
IMPORTANT do not analyse file mentioned in .gitignore IMPORTANT do not analyse file mentioned in .gitignore
Keep things simple
Use shell script

View File

@ -1,6 +1,6 @@
#!/bin/bash #!/bin/bash
# QuantumRick Installation Script # Citadel Installation Script
# Consolidates configuration generation and repository initialization # Consolidates configuration generation and repository initialization
set -e set -e
@ -59,7 +59,7 @@ generate_config() {
# Create configuration file # Create configuration file
echo "Creating configuration file..." echo "Creating configuration file..."
cat > "$CONFIG_FILE" << EOF cat > "$CONFIG_FILE" << EOF
# Restic configuration for quantumrick backups # Restic configuration for citadel backups
# Generated on $(date) # Generated on $(date)
# Repository path # Repository path
@ -137,7 +137,7 @@ initialize_repository() {
} }
complete_setup() { complete_setup() {
echo "=== QuantumRick Complete Setup ===" echo "=== Citadel Complete Setup ==="
echo "" echo ""
# Step 1: Generate configuration # Step 1: Generate configuration
@ -155,7 +155,7 @@ complete_setup() {
fi fi
echo "" echo ""
echo "🎉 QuantumRick setup completed successfully!" echo "🎉 Citadel setup completed successfully!"
echo "" echo ""
echo "Next steps:" echo "Next steps:"
echo "1. Install a service timer: ./manage install <service_name>" echo "1. Install a service timer: ./manage install <service_name>"

2
manage
View File

@ -1,6 +1,6 @@
#!/bin/bash #!/bin/bash
# QuantumRick Backup Management Interface # Citadel Backup Management Interface
# Automatically sources configuration from project root # Automatically sources configuration from project root
set -e set -e

View File

@ -1,48 +1,25 @@
#!/bin/bash #!/bin/bash
# Generic Service Backup Script for Docker Compose services # Paperless Service Backup Script
# Location: /home/citadel/services/paperless/backup.sh # Uses centralized configuration via backup.env
# Runs daily at 3 AM via systemd timer
set -e set -e
# Service Configuration # Load template configuration
SERVICE_NAME="paperless" source "$(dirname "$(dirname "$(dirname "$0")")")/backup/service-script-template.sh"
SERVICE_DIR="/home/citadel/services/$SERVICE_NAME"
DATA_DIR="/home/citadel/data/$SERVICE_NAME" # Setup logging and cleanup
TEMP_BACKUP_DIR="/tmp/$SERVICE_NAME" setup_logging
CONFIG_FILE="/home/citadel/backup/restic.conf" trap cleanup_on_exit EXIT
# Service-specific configuration
COMPOSE_FILE="$SERVICE_DIR/docker-compose.yml" COMPOSE_FILE="$SERVICE_DIR/docker-compose.yml"
# Logging
LOG_FILE="/var/log/$SERVICE_NAME-backup.log"
exec 1> >(tee -a "$LOG_FILE")
exec 2> >(tee -a "$LOG_FILE" >&2)
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1"
}
cleanup() {
log "Cleaning up temporary files..."
rm -rf "$TEMP_BACKUP_DIR"
# Ensure containers are running in case of error
if docker compose -f "$COMPOSE_FILE" ps --services --filter "status=exited" | grep -q .; then
log "Some containers are stopped, restarting..."
cd "$SERVICE_DIR"
docker compose up -d
fi
}
# Set up cleanup on exit
trap cleanup EXIT
log "=== Starting $SERVICE_NAME Backup ===" log "=== Starting $SERVICE_NAME Backup ==="
# Check if configuration exists # Check if configuration exists
if [ ! -f "$CONFIG_FILE" ]; then if [ ! -f "$CONFIG_FILE" ]; then
log "ERROR: Configuration file $CONFIG_FILE not found!" error "Configuration file $CONFIG_FILE not found!"
exit 1 exit 1
fi fi
@ -58,7 +35,7 @@ cd "$SERVICE_DIR"
# Check if compose file exists # Check if compose file exists
if [ ! -f "$COMPOSE_FILE" ]; then if [ ! -f "$COMPOSE_FILE" ]; then
log "ERROR: Docker compose file $COMPOSE_FILE not found!" error "Docker compose file $COMPOSE_FILE not found!"
exit 1 exit 1
fi fi
@ -79,7 +56,7 @@ sleep 10
if [ -f "$SERVICE_DIR/.env" ]; then if [ -f "$SERVICE_DIR/.env" ]; then
source "$SERVICE_DIR/.env" source "$SERVICE_DIR/.env"
else else
log "ERROR: .env file not found!" error ".env file not found!"
exit 1 exit 1
fi fi
@ -90,9 +67,9 @@ log "Creating database dump: $DUMP_FILE"
docker compose exec -T db pg_dump -U "$POSTGRES_USER" -d "$POSTGRES_DB" > "$DUMP_FILE" docker compose exec -T db pg_dump -U "$POSTGRES_USER" -d "$POSTGRES_DB" > "$DUMP_FILE"
if [ $? -eq 0 ]; then if [ $? -eq 0 ]; then
log "✅ Database dump created successfully" success "Database dump created successfully"
else else
log "❌ Database dump failed!" error "Database dump failed!"
exit 1 exit 1
fi fi
@ -113,9 +90,9 @@ restic backup "$TEMP_BACKUP_DIR" \
--tag "daily" --tag "daily"
if [ $? -eq 0 ]; then if [ $? -eq 0 ]; then
log "Restic backup completed successfully with tag: $SERVICE_NAME" success "Restic backup completed successfully with tag: $SERVICE_NAME"
else else
log "❌ Restic backup failed!" error "Restic backup failed!"
exit 1 exit 1
fi fi
@ -127,20 +104,14 @@ sleep 15
# Check if services are running # Check if services are running
if docker compose ps --services --filter "status=running" | grep -q "webserver"; then if docker compose ps --services --filter "status=running" | grep -q "webserver"; then
log "$SERVICE_NAME containers restarted successfully" success "$SERVICE_NAME containers restarted successfully"
else else
log "⚠️ Warning: Some containers may not be running properly" log "Warning: Some containers may not be running properly"
fi fi
log "Running Restic maintenance (forget old snapshots)..." log "Running Restic maintenance (forget old snapshots)..."
# Keep: 7 daily, 4 weekly, 12 monthly, 2 yearly # Apply retention policy using template function
restic forget \ apply_retention "$SERVICE_NAME"
--tag "$SERVICE_NAME" \
--keep-daily 7 \
--keep-weekly 4 \
--keep-monthly 12 \
--keep-yearly 2 \
--prune
log "=== Backup completed successfully ===" log "=== Backup completed successfully ==="

View File

@ -8,11 +8,11 @@
set -euo pipefail set -euo pipefail
# Load template configuration
source "$(dirname "$(dirname "$(dirname "$0")")")/backup/service-script-template.sh"
# Configuration # Configuration
readonly SERVICE_NAME="paperless"
readonly SERVICE_DIR="/home/citadel/services/$SERVICE_NAME"
readonly TEST_DIR="$SERVICE_DIR/test-restore" readonly TEST_DIR="$SERVICE_DIR/test-restore"
readonly CONFIG_FILE="/home/citadel/backup/restic.conf"
readonly SCRIPT_NAME=$(basename "$0") readonly SCRIPT_NAME=$(basename "$0")
# Colors # Colors