Files
sld-filebackups-py/README_IT.md

11 KiB

sld-filebackups-py

Utility di backup in Python, leggera e senza dipendenze esterne, che archivia file e cartelle dichiarati in un file JSON con rotazione automatica dei backup più vecchi. Pensata per girare come cron job giornaliero su server Linux.


Indice


Funzionalità

  • Backup selettivo — definisci i percorsi da salvare in un file JSON, con un flag di abilitazione per ogni voce; non è necessario toccare il codice per aggiungere o rimuovere entry
  • Backup di cartelle — le directory vengono archiviate come .tar.gz (solo il nome della cartella viene preservato come radice dell'archivio, nessun percorso assoluto esposto)
  • Backup di file singoli — i file vengono compressi come .gz
  • Skip automatico se già esiste — se un backup per la data odierna è già presente, viene saltato; il script può essere lanciato più volte al giorno senza duplicati
  • Rotazione automatica — dopo ogni esecuzione, gli archivi più vecchi oltre una soglia configurabile vengono eliminati per ogni sottocartella
  • Modalità dry-run — anteprima precisa di cosa verrebbe eliminato dalla rotazione, senza cancellare nulla
  • Logging strutturato — output sempre presente su console (utile per leggere l'output di cron); opzionalmente scrive su file di log persistente
  • Supporto multi-ambiente — switch tra configurazioni local, local2 e prod in un unico file
  • Gestione degli errori robusta — entry JSON malformate, percorsi mancanti, cartelle vuote ed errori di permessi vengono catturati e loggati senza interrompere l'intera esecuzione

Struttura del progetto

backups_script/
├── script.py           # Punto di ingresso e parser degli argomenti CLI
├── functions.py        # Logica principale: backup, rotazione, controlli
├── constants.py        # Stato condiviso: percorsi, config caricata, timestamp
├── logger.py           # Setup del logging (console + file handler opzionale)
├── init.py             # Selettore di ambiente (local / prod)
├── config.json         # Configurazione runtime
├── dir_backups.json    # Lista dichiarativa dei percorsi da salvare
└── LICENSE             # GNU GPL v3

Responsabilità dei moduli

File Ruolo
init.py Definisce ROOT_DIR_APP e ROOT_DIR_BACKUPS in base all'ambiente selezionato. Importato per primo da tutto il resto.
constants.py Costruisce tutti i percorsi derivati (cartella backup, percorsi config), carica config.json e dir_backups.json in memoria, cattura la data odierna e l'ora corrente.
logger.py Legge config.json direttamente e configura il logger root di Python con uno StreamHandler (sempre attivo) e un FileHandler opzionale.
functions.py Contiene tutta la logica di business: default_backup_dir(), check_existing_folders(), backups_now(), autorotate_backups(), show_enabled().
script.py Inizializza il logging, poi analizza gli argomenti CLI e chiama la funzione appropriata. Senza flag, esegue backup completo + rotazione.

Come funziona

  1. script.py chiama setup_logger(), che legge config.json e configura il logging.
  2. default_backup_dir() verifica che la cartella di backup root e la sottocartella con il nome host esistano, creandole se necessario.
  3. check_existing_folders() legge dir_backups.json, filtra le entry abilitate (flag == 1), verifica che ogni percorso esista su disco e lo classifica come "folder" o "file". Le directory vuote o non leggibili vengono escluse.
  4. backups_now() itera i percorsi verificati:
    • Per le cartelle: crea un archivio <nome>_YYYY-MM-DD.tar.gz tramite il modulo tarfile.
    • Per i file singoli: crea una copia compressa <nome>_YYYY-MM-DD.gz tramite gzip + shutil.copyfileobj.
    • Se l'archivio di oggi esiste già, l'entry viene saltata.
  5. autorotate_backups() scansiona ogni sottocartella diretta della directory di backup dell'host, ordina i file .gz per data di modifica (più recenti prima) ed elimina quelli oltre la soglia keep_backups.

Installazione

Nessun pacchetto da installare. Il script usa solo la libreria standard di Python.

git clone https://gitea.sld-server.org/sld-admin/sld-filebackups-py.git
cd sld-filebackups-py

Poi imposta il tuo ambiente e i percorsi in init.py e dir_backups.json.


Configurazione

config.json

{
    "keep_backups": 7,
    "logs": false,
    "logs_path": "/home/backups/logs"
}
Chiave Tipo Default Descrizione
keep_backups intero 7 Quanti archivi recenti conservare per sottocartella. I più vecchi vengono eliminati dalla rotazione.
logs booleano false Se true, viene scritto un file backup.log in logs_path oltre all'output su console.
logs_path stringa ~/backups/logs Cartella dove verrà creato backup.log. Viene creata automaticamente se non esiste.

Nota: Anche quando logs è false, tutto l'output viene comunque stampato su stdout/stderr, quindi cron lo cattura normalmente tramite mail o redirezione.


dir_backups.json

È la lista dichiarativa di tutto ciò che deve essere salvato. Ogni entry è un array JSON di esattamente tre valori:

[
    [ "/percorso/assoluto/cartella",  1, "NomeBackup"       ],
    [ "/percorso/assoluto/file",      1, "BackupConfig"     ],
    [ "/percorso/disabilitato",       0, "VecchiaEntry"     ]
]
Posizione Campo Descrizione
0 percorso Percorso assoluto del file o della cartella da salvare.
1 abilitato 1 = includi nelle esecuzioni di backup. 0 = salta completamente (la entry viene letta ma mai elaborata).
2 nome Identificativo breve usato come nome della sottocartella nella destinazione del backup e come prefisso del nome dell'archivio. Deve essere unico tra le entry.

Suggerimenti:

  • Per disabilitare temporaneamente una entry senza eliminarla, imposta il flag a 0.
  • Il campo nome diventa una directory dentro <ROOT_DIR_BACKUPS>/<hostname>/, quindi evita spazi e caratteri speciali.
  • Le cartelle vengono salvate solo se non sono vuote e sono leggibili.

Ambiente (init.py)

env = "local"   # Valori disponibili: "local", "local2", "prod"
Ambiente ROOT_DIR_APP ROOT_DIR_BACKUPS
local /home/sld-admin/Scrivania/backups_script/ <ROOT_DIR_APP>/backups/Daily_File_Backups/
local2 /home/simo-positive/Desktop/backups_script/ <ROOT_DIR_APP>/backups/Daily_File_Backups/
prod /opt/sld-backups/ /home/backups/backups_root/Daily_File_Backups/

Se viene impostato un valore sconosciuto, il script termina immediatamente con un errore.


Utilizzo

# Backup completo + rotazione automatica (comportamento di default, nessun flag richiesto)
python3 script.py

# Mostra quali percorsi sono abilitati e quali disabilitati
python3 script.py --show

# Verifica se i percorsi dichiarati esistono su disco e stampa un report
python3 script.py --check

# Esegui il backup con output di debug verboso
python3 script.py --debug

# Esegui solo la rotazione (nessun nuovo backup creato)
python3 script.py --rotate

# Anteprima di cosa verrebbe eliminato dalla rotazione, senza cancellare nulla
python3 script.py --rotate --dry

Riferimento flag CLI

Flag Forma lunga Descrizione
-s --show Stampa i percorsi abilitati e disabilitati da dir_backups.json.
-d --debug Esegue il backup con debug="on", abilitando output verboso sul controllo dei percorsi.
-c --check Esegue check_existing_folders() e stampa lo stato dettagliato per ogni percorso dichiarato.
-r --rotate Esegue solo autorotate_backups(). Può essere combinato con --dry.
--dry Modalità dry-run per --rotate: logga i candidati all'eliminazione ma non cancella nulla.

Struttura dei backup

I backup vengono scritti sotto:

<ROOT_DIR_BACKUPS>/
└── <hostname>/
    ├── Documenti/
    │   ├── Documenti_2026-03-10.tar.gz
    │   ├── Documenti_2026-03-11.tar.gz
    │   └── Documenti_2026-03-12.tar.gz
    └── BackupConfig/
        ├── BackupConfig_2026-03-10.gz
        └── BackupConfig_2026-03-11.gz
  • Ogni entry in dir_backups.json ottiene la propria sottocartella con il nome del campo nome.
  • Gli archivi seguono il pattern <nome>_YYYY-MM-DD.tar.gz (cartelle) o <nome>_YYYY-MM-DD.gz (file).
  • Il nome host della macchina viene usato come cartella di primo livello, rendendo semplice raccogliere backup di più macchine sotto la stessa root.

Rotazione automatica

La rotazione (autorotate_backups) viene eseguita automaticamente dopo ogni backup, oppure può essere avviata manualmente con --rotate.

Logica:

  1. Scansiona ogni sottocartella diretta di <ROOT_DIR_BACKUPS>/<hostname>/.
  2. Trova tutti i file *.gz (copre sia .gz che .tar.gz).
  3. Li ordina per data di modifica, dal più recente al più vecchio.
  4. Conserva i primi keep_backups (default: 7) ed elimina i restanti.

Dry-run (--rotate --dry) logga esattamente quali file verrebbero eliminati, senza nessuna modifica al filesystem. Utile per verificare l'impostazione di retention prima di applicarla.


Logging

Tutte le funzioni usano il modulo standard logging di Python tramite un logger con nome (__name__). Il logger root viene configurato da logger.py all'avvio.

  • Output su console sempre attivo (via StreamHandler), indipendentemente dall'impostazione logs.
  • Output su file aggiunto quando "logs": true è impostato in config.json. Il file di log è <logs_path>/backup.log e viene aggiunto ad ogni esecuzione.
  • Formato log: YYYY-MM-DD HH:MM:SS [LIVELLO] messaggio

Esecuzione come cron job

Per eseguire un backup completo ogni giorno alle 2:00:

crontab -e
0 2 * * * /usr/bin/python3 /opt/sld-backups/script.py >> /home/backups/logs/cron.log 2>&1

Poiché il script scrive sempre su stdout, la redirezione dell'output di cron cattura il log completo dell'esecuzione anche se il log su file è disabilitato in config.json.


Requisiti

  • Python 3.6+
  • Nessun pacchetto di terze parti — usa solo la libreria standard:
    • tarfile, gzip, shutil — archiviazione e compressione
    • logging — output strutturato
    • argparse — parsing degli argomenti CLI
    • pathlib — gestione dei percorsi
    • socket — rilevamento del nome host
    • json — caricamento della configurazione

Licenza

GNU General Public License v3.0 — vedi LICENSE per i termini completi.