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.
## Structure du Projet
```
quantumrick/
citadel/
├── backup.env # Configuration centralisée
├── manage # Interface principale de gestion
├── install # Script d'installation et configuration

View File

@ -1,78 +1,55 @@
#!/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
# === Configuration Utilisateur ===
# === Configuration Essentielle ===
# Utilisateur système qui exécutera les backups
BACKUP_USER="${BACKUP_USER:-citadel}"
BACKUP_HOME="${BACKUP_HOME:-/home/$BACKUP_USER}"
# === 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}"
CITADEL_USER="${CITADEL_USER:-citadel}"
# Racine du projet citadel
PROJECT_ROOT="${PROJECT_ROOT:-/home/nicolas/dev/citadel}"
# Répertoire contenant les services à sauvegarder
SERVICES_BASE_DIR="${SERVICES_BASE_DIR:-$BACKUP_HOME/services}"
# Répertoire de configuration du projet
CONFIG_DIR="${CONFIG_DIR:-$PROJECT_ROOT/config}"
SERVICES_BASE_DIR="${SERVICES_BASE_DIR:-/home/$CITADEL_USER/services}"
# === Stockage des Sauvegardes ===
# === Stockage Restic ===
# 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
BACKUP_REPO_NAME="${BACKUP_REPO_NAME:-quantumrick}"
# Chemin complet du repository Restic
BACKUP_REPOSITORY="${BACKUP_REPOSITORY:-$BACKUP_STORAGE_PATH/$BACKUP_REPO_NAME}"
RESTIC_REPO="${RESTIC_REPO:-citadel}"
# === Système ===
# Répertoire des services systemd
SYSTEMD_DIR="${SYSTEMD_DIR:-/etc/systemd/system}"
# 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}"
# Répertoire des logs système
LOG_DIR="${LOG_DIR:-/var/log}"
# Répertoire temporaire
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)
RESTIC_CONFIG_FILE="${RESTIC_CONFIG_FILE:-$CONFIG_DIR/restic.conf}"
RESTIC_CONFIG_FILE="${RESTIC_CONFIG_FILE:-$PROJECT_ROOT/config/restic.conf}"
# === Templates systemd ===
# Nom des fichiers templates
# === Politique de Rétention ===
# 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}"
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 ===
export RESTIC_REPOSITORY="$BACKUP_REPOSITORY"
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"
# Systemd template files
SERVICE_TEMPLATE="$SERVICE_TEMPLATE"
TIMER_TEMPLATE="$TIMER_TEMPLATE"
SYSTEMD_DIR="$SYSTEMD_DIR"
SERVICE_TEMPLATE="service-backup@.service"
TIMER_TEMPLATE="service-backup@.timer"
SYSTEMD_DIR="/etc/systemd/system"
# Instance names
SERVICE_INSTANCE="service-backup@$SERVICE_NAME.service"
@ -70,13 +70,13 @@ fi
chmod +x "$BACKUP_SCRIPT"
# Check if template files exist
if [ ! -f "$BACKUP_DIR/$SERVICE_TEMPLATE" ]; then
echo "ERROR: Service template not found: $BACKUP_DIR/$SERVICE_TEMPLATE"
if [ ! -f "$BACKUP_DIR/service-backup@.service" ]; then
echo "ERROR: Service template not found: $BACKUP_DIR/service-backup@.service"
exit 1
fi
if [ ! -f "$BACKUP_DIR/$TIMER_TEMPLATE" ]; then
echo "ERROR: Timer template not found: $BACKUP_DIR/$TIMER_TEMPLATE"
if [ ! -f "$BACKUP_DIR/service-backup@.timer" ]; then
echo "ERROR: Timer template not found: $BACKUP_DIR/service-backup@.timer"
exit 1
fi
@ -95,20 +95,20 @@ fi
echo "Generating service file with current configuration..."
sed -e "s|\${BACKUP_USER}|$BACKUP_USER|g" \
-e "s|\${SERVICES_BASE_DIR}|$SERVICES_BASE_DIR|g" \
"$BACKUP_DIR/$SERVICE_TEMPLATE" > "$SYSTEMD_DIR/$SERVICE_TEMPLATE"
chmod 644 "$SYSTEMD_DIR/$SERVICE_TEMPLATE"
"$BACKUP_DIR/service-backup@.service" > "/etc/systemd/system/service-backup@.service"
chmod 644 "/etc/systemd/system/service-backup@.service"
echo "Generating timer file with current configuration..."
sed -e "s|\${DEFAULT_BACKUP_SCHEDULE}|$DEFAULT_BACKUP_SCHEDULE|g" \
"$BACKUP_DIR/$TIMER_TEMPLATE" > "$SYSTEMD_DIR/$TIMER_TEMPLATE"
chmod 644 "$SYSTEMD_DIR/$TIMER_TEMPLATE"
"$BACKUP_DIR/service-backup@.timer" > "/etc/systemd/system/service-backup@.timer"
chmod 644 "/etc/systemd/system/service-backup@.timer"
# Create custom timer with specific schedule if different from default
if [ "$SCHEDULE" != "$DEFAULT_BACKUP_SCHEDULE" ]; then
echo "Creating custom timer with schedule: $SCHEDULE"
sed "s|OnCalendar=\*-\*-\* 03:00:00|OnCalendar=$SCHEDULE|" \
"$BACKUP_DIR/$TIMER_TEMPLATE" > "$SYSTEMD_DIR/$TIMER_INSTANCE"
chmod 644 "$SYSTEMD_DIR/$TIMER_INSTANCE"
"$BACKUP_DIR/service-backup@.timer" > "/etc/systemd/system/$TIMER_INSTANCE"
chmod 644 "/etc/systemd/system/$TIMER_INSTANCE"
fi
# 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 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
IMPORTANT all code comment and documentation must be write in english
IMPORTANT do not analyse file mentioned in .gitignore
Keep things simple
Use shell script

View File

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

2
manage
View File

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

View File

@ -1,48 +1,25 @@
#!/bin/bash
# Generic Service Backup Script for Docker Compose services
# Location: /home/citadel/services/paperless/backup.sh
# Runs daily at 3 AM via systemd timer
# Paperless Service Backup Script
# Uses centralized configuration via backup.env
set -e
# Service Configuration
SERVICE_NAME="paperless"
SERVICE_DIR="/home/citadel/services/$SERVICE_NAME"
DATA_DIR="/home/citadel/data/$SERVICE_NAME"
TEMP_BACKUP_DIR="/tmp/$SERVICE_NAME"
CONFIG_FILE="/home/citadel/backup/restic.conf"
# Load template configuration
source "$(dirname "$(dirname "$(dirname "$0")")")/backup/service-script-template.sh"
# Setup logging and cleanup
setup_logging
trap cleanup_on_exit EXIT
# Service-specific configuration
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 ==="
# Check if configuration exists
if [ ! -f "$CONFIG_FILE" ]; then
log "ERROR: Configuration file $CONFIG_FILE not found!"
error "Configuration file $CONFIG_FILE not found!"
exit 1
fi
@ -58,7 +35,7 @@ cd "$SERVICE_DIR"
# Check if compose file exists
if [ ! -f "$COMPOSE_FILE" ]; then
log "ERROR: Docker compose file $COMPOSE_FILE not found!"
error "Docker compose file $COMPOSE_FILE not found!"
exit 1
fi
@ -79,7 +56,7 @@ sleep 10
if [ -f "$SERVICE_DIR/.env" ]; then
source "$SERVICE_DIR/.env"
else
log "ERROR: .env file not found!"
error ".env file not found!"
exit 1
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"
if [ $? -eq 0 ]; then
log "✅ Database dump created successfully"
success "Database dump created successfully"
else
log "❌ Database dump failed!"
error "Database dump failed!"
exit 1
fi
@ -113,9 +90,9 @@ restic backup "$TEMP_BACKUP_DIR" \
--tag "daily"
if [ $? -eq 0 ]; then
log "Restic backup completed successfully with tag: $SERVICE_NAME"
success "Restic backup completed successfully with tag: $SERVICE_NAME"
else
log "❌ Restic backup failed!"
error "Restic backup failed!"
exit 1
fi
@ -127,20 +104,14 @@ sleep 15
# Check if services are running
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
log "⚠️ Warning: Some containers may not be running properly"
log "Warning: Some containers may not be running properly"
fi
log "Running Restic maintenance (forget old snapshots)..."
# Keep: 7 daily, 4 weekly, 12 monthly, 2 yearly
restic forget \
--tag "$SERVICE_NAME" \
--keep-daily 7 \
--keep-weekly 4 \
--keep-monthly 12 \
--keep-yearly 2 \
--prune
# Apply retention policy using template function
apply_retention "$SERVICE_NAME"
log "=== Backup completed successfully ==="

View File

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