WIP many change in logic for simplify

This commit is contained in:
Nicolas Duhamel 2025-06-26 17:54:08 +02:00
parent b0b9712b52
commit de21cbd4d2
7 changed files with 237 additions and 188 deletions

118
README.md
View File

@ -1,118 +0,0 @@
# Citadel Backup System
Système de sauvegarde automatisé basé sur Restic avec intégration systemd pour services containerisés.
## Structure du Projet
```
citadel/
├── backup.env # Configuration centralisée
├── manage # Interface principale de gestion
├── install # Script d'installation et configuration
├── config/
│ └── restic.conf # Configuration Restic (générée)
└── backup/
├── install-service # Installation timers systemd
├── list-snapshots # Liste des snapshots
├── restore # Restauration
├── service-backup@.service # Template service systemd
└── service-backup@.timer # Template timer systemd
```
## Installation
1. **Configuration initiale**
```bash
# Copier et adapter la configuration
cp backup.env.sample backup.env
# Éditer backup.env selon votre environnement
```
2. **Installation complète**
```bash
# Installation automatique (configuration + repository)
./install
# Ou étape par étape
./install config # Génération configuration Restic
./install repo # Initialisation repository
```
3. **Installation d'un service**
```bash
sudo ./manage install <nom_service>
```
## Configuration
### Variables principales (backup.env)
- `BACKUP_USER` : Utilisateur système (défaut: citadel)
- `PROJECT_ROOT` : Racine du projet
- `SERVICES_BASE_DIR` : Répertoire des services à sauvegarder
- `BACKUP_REPOSITORY` : Chemin du repository Restic
- `DEFAULT_BACKUP_SCHEDULE` : Planning par défaut (défaut: *-*-* 03:00:00)
### Personnalisation
```bash
# Exemple pour un autre utilisateur
export BACKUP_USER="myuser"
export BACKUP_HOME="/home/myuser"
source backup.env
# Puis utiliser normalement
./manage list
```
## Utilisation
### Gestion des sauvegardes
```bash
# Lister les timers (configuration auto-sourcée)
./manage list
# Statut d'un service
./manage status paperless
# Lancer une sauvegarde manuelle
./manage run paperless
# Voir les logs
./manage logs paperless
# Services disponibles
./manage available
```
### Restauration
```bash
# Lister les snapshots
./manage snapshots paperless
# Restaurer en mode test
./manage restore paperless
# Restaurer en production
./manage restore-prod paperless
```
## Architecture
### Principes de conception
- **Interface unifiée** : Toutes les opérations via `./manage` et `./install`
- **Configuration auto-sourcée** : Plus besoin de sourcer manuellement
- **Scripts protégés** : Scripts dans `backup/` non exécutables directement
- **Sécurité** : Mots de passe générés automatiquement, permissions restreintes
### Composants
- **`./manage`** : Interface principale pour toutes les opérations de sauvegarde
- **`./install`** : Script d'installation consolidé (config + repository)
- **`backup.env`** : Configuration centralisée avec variables d'environnement
- **`backup/`** : Scripts internes appelés via `./manage` uniquement
### Développement
Les scripts dans `backup/` utilisent la variable `CALLED_FROM_MANAGE` pour empêcher l'exécution directe et garantir l'utilisation de l'interface unifiée.

View File

@ -4,36 +4,26 @@
# 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
# Auto-configure via backup.env from standard location
CONFIG_DIR="$HOME/.config/citadel"
CONFIG_FILE="$CONFIG_DIR/backup.env"
# Source centralized configuration
if [ -f "$PROJECT_ROOT/backup.env" ]; then
source "$PROJECT_ROOT/backup.env"
if [ -f "$CONFIG_FILE" ]; then
source "$CONFIG_FILE"
else
echo "ERROR: Configuration file backup.env not found in $PROJECT_ROOT" >&2
echo "Please ensure backup.env exists in project root directory" >&2
echo "ERROR: Configuration not found at $CONFIG_FILE" >&2
echo "Please run './install setup' to initialize configuration" >&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
# Use service name if set explicitly, otherwise detect from calling script
if [ -z "$SERVICE_NAME" ]; then
# BASH_SOURCE[1] is the script that sourced this template
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"
RESTIC_CONFIG_FILE="$CONFIG_DIR/restic.conf"
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"
@ -96,7 +86,7 @@ cleanup_on_exit() {
# Export commonly used variables
export SERVICE_NAME
export SERVICE_DIR
export CONFIG_FILE
export RESTIC_CONFIG_FILE
export LOG_FILE
export DATA_DIR
export TEMP_BACKUP_DIR

View File

@ -1,12 +1,35 @@
#My name is Nicolas
# Claude Code Guidance - Citadel Project
This file provides guidance to Claude Code when working with this repository.
**Maintainer:** Nicolas
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.
## Project Overview
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
Citadel is a collection of shell scripts for managing a self-hosted server for personal usage. It provides automated backup management using Restic with systemd integration for containerized services.
## Deployment Structure
- **Development:** `/home/nicolas/dev/citadel`
- **Production:** `$HOME/citadel` (default user: "citadel")
- **Configuration:** `$HOME/.config/citadel`
## Development Guidelines
### Core Principles
- **Simplicity first:** Keep solutions minimal and focused
- **No unsolicited features:** Only implement specifically requested functionality
- **Ask before enhancing:** If a feature seems beneficial, ask before implementing
- **Shell scripts only:** Use bash/shell scripting as the primary technology
- **No migration scripts:** Unless explicitly requested
### Code Standards
- **Comments & Documentation:** English only
- **Error handling:** Use consistent patterns across scripts
- **Security:** Follow secure coding practices, especially for password/secret handling
- **Integration:** Prefer using the centralized template system for new services
### File Exclusions
- **Do not analyze:** Files listed in `.gitignore`
## Communication
- **Interaction language:** French (Nicolas preference)
- **Code language:** English (comments, documentation, variable names)

87
install
View File

@ -8,13 +8,15 @@ set -e
# Get the directory where this script is located (project root)
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# Auto-source configuration
if [ -f "$SCRIPT_DIR/backup.env" ]; then
source "$SCRIPT_DIR/backup.env"
# Auto-source configuration from standard location
CONFIG_DIR="$HOME/.config/citadel"
CONFIG_FILE="$CONFIG_DIR/backup.env"
if [ -f "$CONFIG_FILE" ]; then
source "$CONFIG_FILE"
else
echo "ERROR: Configuration file backup.env not found in $SCRIPT_DIR"
echo "Please ensure backup.env exists in project root directory"
exit 1
echo "Configuration not found at $CONFIG_FILE"
echo "Will create configuration during setup..."
fi
show_help() {
@ -33,14 +35,34 @@ show_help() {
}
generate_config() {
local CONFIG_FILE="$RESTIC_CONFIG_FILE"
local RESTIC_CONFIG_FILE="$CONFIG_DIR/restic.conf"
local BACKUP_ENV_FILE="$CONFIG_DIR/backup.env"
echo "=== Generating Citadel Configuration ==="
# Create config directory
mkdir -p "$CONFIG_DIR"
# Copy backup.env.sample if backup.env doesn't exist
if [ ! -f "$BACKUP_ENV_FILE" ]; then
if [ -f "$SCRIPT_DIR/backup.env.sample" ]; then
echo "Creating configuration from sample..."
cp "$SCRIPT_DIR/backup.env.sample" "$BACKUP_ENV_FILE"
echo "✅ Configuration created at $BACKUP_ENV_FILE"
echo "Please edit this file to match your environment"
else
echo "ERROR: backup.env.sample not found in $SCRIPT_DIR"
return 1
fi
fi
# Source the configuration to get variables
source "$BACKUP_ENV_FILE"
local REPO_PATH="$BACKUP_REPOSITORY"
echo "=== Generating Restic Configuration ==="
# Check if config already exists
if [ -f "$CONFIG_FILE" ]; then
echo "Configuration file already exists at $CONFIG_FILE"
# Check if restic config already exists
if [ -f "$RESTIC_CONFIG_FILE" ]; then
echo "Restic configuration already exists at $RESTIC_CONFIG_FILE"
read -p "Do you want to overwrite it? (y/N): " -n 1 -r
echo
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
@ -49,16 +71,13 @@ generate_config() {
fi
fi
# Ensure config directory exists
mkdir -p "$(dirname "$CONFIG_FILE")"
# Generate secure password (32 characters)
echo "Generating secure password..."
local RESTIC_PASSWORD=$(openssl rand -base64 32)
# Create configuration file
echo "Creating configuration file..."
cat > "$CONFIG_FILE" << EOF
# Create restic configuration file
echo "Creating restic configuration file..."
cat > "$RESTIC_CONFIG_FILE" << EOF
# Restic configuration for citadel backups
# Generated on $(date)
@ -73,24 +92,34 @@ export RESTIC_CACHE_DIR="$RESTIC_CACHE_DIR"
EOF
# Set secure permissions
chmod 600 "$CONFIG_FILE"
chmod 600 "$RESTIC_CONFIG_FILE"
echo "✅ Configuration file created at $CONFIG_FILE"
echo "✅ Restic configuration file created at $RESTIC_CONFIG_FILE"
echo "🔒 Password generated and saved securely"
echo ""
echo "⚠️ IMPORTANT: Save this password somewhere safe!"
echo " If you lose it, you won't be able to restore your backups!"
echo ""
echo "📁 Password saved in: $CONFIG_FILE"
echo " Use 'cat $CONFIG_FILE' to view the password if needed"
echo "📁 Password saved in: $RESTIC_CONFIG_FILE"
echo " Use 'cat $RESTIC_CONFIG_FILE' to view the password if needed"
echo ""
return 0
}
initialize_repository() {
local RESTIC_CONFIG_FILE="$CONFIG_DIR/restic.conf"
# Source backup.env to get repository path
if [ -f "$CONFIG_DIR/backup.env" ]; then
source "$CONFIG_DIR/backup.env"
else
echo "Error: backup.env not found at $CONFIG_DIR/backup.env"
echo "Please run '$0 config' first to create the configuration."
return 1
fi
local REPO_PATH="$BACKUP_REPOSITORY"
local CONFIG_FILE="$RESTIC_CONFIG_FILE"
echo "=== Initializing Restic Repository ==="
@ -101,15 +130,15 @@ initialize_repository() {
sudo chown $(whoami):$(whoami) "$(dirname "$REPO_PATH")"
fi
# Check if config file exists
if [ ! -f "$CONFIG_FILE" ]; then
echo "Error: Configuration file $CONFIG_FILE not found!"
# Check if restic config file exists
if [ ! -f "$RESTIC_CONFIG_FILE" ]; then
echo "Error: Restic configuration file $RESTIC_CONFIG_FILE not found!"
echo "Please run '$0 config' first to create the configuration."
return 1
fi
# Source the configuration
source "$CONFIG_FILE"
# Source the restic configuration
source "$RESTIC_CONFIG_FILE"
# Check if repository is already initialized
if restic -r "$REPO_PATH" cat config &>/dev/null; then
@ -125,7 +154,7 @@ initialize_repository() {
if [ $? -eq 0 ]; then
echo "✅ Repository successfully initialized!"
echo "Repository path: $REPO_PATH"
echo "Configuration: $CONFIG_FILE"
echo "Configuration: $RESTIC_CONFIG_FILE"
echo ""
echo "=== Repository Information ==="
restic -r "$REPO_PATH" stats

13
manage
View File

@ -8,12 +8,15 @@ set -e
# Get the directory where this script is located (project root)
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# Auto-source configuration
if [ -f "$SCRIPT_DIR/backup.env" ]; then
source "$SCRIPT_DIR/backup.env"
# Auto-source configuration from standard location
CONFIG_DIR="$HOME/.config/citadel"
CONFIG_FILE="$CONFIG_DIR/backup.env"
if [ -f "$CONFIG_FILE" ]; then
source "$CONFIG_FILE"
else
echo "ERROR: Configuration file backup.env not found in $SCRIPT_DIR"
echo "Please ensure backup.env exists in project root directory"
echo "ERROR: Configuration not found at $CONFIG_FILE"
echo "Please run './install setup' to initialize configuration"
exit 1
fi

View File

@ -6,7 +6,12 @@
set -e
# Load template configuration
source "$(dirname "$(dirname "$(dirname "$0")")")/backup/service-script-template.sh"
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
# Set service name explicitly for template
export SERVICE_NAME="paperless"
source "$PROJECT_ROOT/backup/service-script-template.sh"
# Setup logging and cleanup
setup_logging
@ -17,14 +22,14 @@ COMPOSE_FILE="$SERVICE_DIR/docker-compose.yml"
log "=== Starting $SERVICE_NAME Backup ==="
# Check if configuration exists
if [ ! -f "$CONFIG_FILE" ]; then
error "Configuration file $CONFIG_FILE not found!"
# Check if restic configuration exists
if [ ! -f "$RESTIC_CONFIG_FILE" ]; then
error "Restic configuration file $RESTIC_CONFIG_FILE not found!"
exit 1
fi
# Source Restic configuration
source "$CONFIG_FILE"
source "$RESTIC_CONFIG_FILE"
# Create temporary backup directory
log "Creating temporary backup directory: $TEMP_BACKUP_DIR"

117
todo.md Normal file
View File

@ -0,0 +1,117 @@
# Plan de Migration vers $HOME/.config/citadel
## Objectif
Migrer la configuration du projet vers `$HOME/.config/citadel` pour respecter les standards de configuration système et séparer clairement le code de la configuration en production.
## Architecture Cible
### Structure de configuration
```
$HOME/.config/citadel/
├── backup.env # Configuration principale (était à la racine)
├── restic.conf # Configuration Restic générée (était dans config/)
└── services/ # Configurations spécifiques par service (futures extensions)
```
### Fichiers sample conservés dans le projet
```
backup.env.sample # Guide d'installation (reste à la racine)
config/restic.conf # Devient un exemple/template
```
## Plan d'action détaillé
### Phase 1 : Modification du système de sourcing
#### 1.1 Modifier `manage`
- **Fichier** : `manage` (lignes 12-18)
- **Action** : Remplacer le sourcing conditionnel par un chemin fixe
- **Nouveau code** :
```bash
CONFIG_DIR="$HOME/.config/citadel"
CONFIG_FILE="$CONFIG_DIR/backup.env"
if [ -f "$CONFIG_FILE" ]; then
source "$CONFIG_FILE"
else
echo "ERROR: Configuration not found at $CONFIG_FILE"
echo "Please run './install setup' to initialize configuration"
exit 1
fi
```
#### 1.2 Modifier `install`
- **Fichier** : `install` (lignes 12-18)
- **Action** : Même modification que `manage` + création du répertoire config
- **Ajout** : Fonction de création/migration de la configuration
- **Nouveau comportement** :
- Créer `$HOME/.config/citadel/` si inexistant
- Copier `backup.env.sample` vers `$HOME/.config/citadel/backup.env` si absent
- Générer `restic.conf` dans le nouveau répertoire
#### 1.3 Modifier `service-script-template.sh`
- **Fichier** : `backup/service-script-template.sh` (lignes 8-26)
- **Action** : Supprimer la détection automatique de PROJECT_ROOT
- **Nouveau code** :
```bash
CONFIG_DIR="$HOME/.config/citadel"
CONFIG_FILE="$CONFIG_DIR/backup.env"
if [ -f "$CONFIG_FILE" ]; then
source "$CONFIG_FILE"
else
echo "ERROR: Configuration not found at $CONFIG_FILE" >&2
exit 1
fi
```
### Phase 2 : Adaptation des variables de configuration
#### 2.1 Modifier `backup.env.sample`
- **Action** : Mettre à jour les chemins par défaut
- **Variables à modifier** :
```bash
# Nouveau chemin de configuration
RESTIC_CONFIG_FILE="${RESTIC_CONFIG_FILE:-$HOME/.config/citadel/restic.conf}"
# PROJECT_ROOT devient optionnel (pour les templates systemd seulement)
PROJECT_ROOT="${PROJECT_ROOT:-/home/nicolas/dev/citadel}"
```
#### 2.2 Modifier la génération de `restic.conf`
- **Fichier** : `install` (fonction `generate_config`)
- **Action** : Générer le fichier dans `$HOME/.config/citadel/restic.conf`
- **Chemin cible** : `$CONFIG_DIR/restic.conf`
### Phase 3 : Tests et validation
#### 3.1 Tests de non-régression
- `./manage list` fonctionne
- `./manage install <service>` fonctionne
- Scripts de backup sourcent correctement la configuration
- Installation initiale crée la structure correcte
### Phase 4 : Documentation
#### 4.1 Mettre à jour README.md
- Documenter le nouveau chemin de configuration
- Ajouter la procédure de setup initial
#### 4.2 Messages d'erreur informatifs
- Guider l'utilisateur vers la bonne commande d'installation
- Indiquer clairement les chemins de configuration
## Avantages de cette migration
1. **Standard système** : Respect de la convention `$HOME/.config/`
2. **Séparation claire** : Code et configuration indépendants
3. **Sécurité** : Configuration hors du répertoire de développement
4. **Simplicité** : Plus de détection automatique hasardeuse
5. **Maintenance** : Configuration centralisée et prévisible
## Risques identifiés et mitigations
- **Risque** : Scripts cassés après migration
- **Mitigation** : Tests de non-régression complets
- **Risque** : Confusion utilisateur
- **Mitigation** : Messages d'erreur explicites et documentation claire