Implementazione sistema backup CRI Catania#1
Open
ico88 wants to merge 65 commits into
Open
Conversation
- FastAPI + SQLite/SQLAlchemy: modelli Server, VMwareHost, BackupDestination, BackupJob, BackupRun, BackupLog - Engine backup: ESXi snapshot+OVF (pyvmomi), dati Windows via WinRM/PowerShell, dati Linux via SSH/rsync - Trasferimento QNAP: rsync-over-SSH e API QTS, con gestione retention automatica - Scheduler APScheduler con espressioni cron configurabili - UI Bootstrap 5: dashboard con statistiche live, wizard guidato (server/QNAP/job), storico esecuzioni, viewer log real-time - Cifratura credenziali nel DB tramite Fernet https://claude.ai/code/session_01AfKVb7RehwV197JyXeeqab
…che email, UI NAKIVO-style - Autenticazione: login con bcrypt, sessione cookie (SessionMiddleware), primo avvio crea admin/changeme, wizard setup iniziale - Sicurezza: tutte le route UI/API protette da sessione, cambio password, gestione utenti (solo admin) - Verifica integrità: SHA-256 locale pre-trasferimento e remoto post-trasferimento via SSH, risultato salvato su BackupRun - Retention per copie: sostituisce quella a giorni, mantiene al massimo N backup per job (ls + rm via SSH) - Notifiche email: SMTP configurabile da UI, invio automatico a fine job con log dettagliato e stato integrità - UI dark NAKIVO-style: sidebar, topbar con user menu, stat cards, badge status colorati, login page - Nuovi campi Job: verify_integrity, notify_on_success, notify_on_failure - Pagina Impostazioni: SMTP con test, gestione utenti, info sistema https://claude.ai/code/session_01AfKVb7RehwV197JyXeeqab
- Endpoint /api/stats/summary: KPI globali (successi, falliti, tasso, dimensione totale/media, durata media, integrità) - Endpoint /api/stats/by-job: statistiche per singolo job nel periodo selezionato - Endpoint /api/stats/trend: serie temporale giornaliera successi/fallimenti - Endpoint /api/stats/export-csv: esportazione esecuzioni in CSV scaricabile - Pagina /reports: grafico barre trend giornaliero (Chart.js), donut distribuzione stato, tabella dettagliata per job con tasso di successo colorato, dimensione media, durata media - Filtro periodo: 7/30/90/365 giorni - Voce "Report & Statistiche" aggiunta alla sidebar https://claude.ai/code/session_01AfKVb7RehwV197JyXeeqab
- Chiede porta personalizzata (1024–65535) con verifica che non sia già in uso - Chiede directory di installazione (default /opt/backup-all) - Installa dipendenze di sistema (python3, git, rsync, sshpass, curl) - Auto-installa Python 3.11 via deadsnakes PPA se la versione è < 3.11 - Crea utente di sistema dedicato senza shell (backupall) - Clone repo, virtualenv, pip install con fallback senza pyvmomi - Crea unit file systemd con hardening (NoNewPrivileges, PrivateTmp, ProtectSystem) - Abilita e avvia il servizio automaticamente - Apre la porta su UFW se attivo (con conferma) - Riepilogo finale con URL, credenziali e comandi utili https://claude.ai/code/session_01AfKVb7RehwV197JyXeeqab
- Remove all placeholder app names (gamma, abulafia, TeamSystem) from
templates and backend comments; use generic terms
- wizard_server + wizard_destination: list with colored badges at top,
click row to edit via modal (PUT endpoint), test button in modal
- PUT /api/servers/{id} and PUT /api/destinations/{id} update endpoints
- POST /api/servers/{id}/test: SSH (Linux) / TCP port check (Windows)
- POST /api/destinations/{id}/test: improved SSH test with readable errors
- crypto.py: validate key on load, regenerate if corrupted, decrypt()
returns "" instead of crashing on bad key
- install.sh: generate valid Fernet key into .env at install time
- update.sh: rsync code-only update script (skips .venv/.db/.env)
- base.html badges: solid opaque backgrounds for high contrast
https://claude.ai/code/session_01AfKVb7RehwV197JyXeeqab
- base.html: title tag and topbar subtitle - login.html: title, brand subtitle, footer - setup_wizard.html: subtitle - settings.html: organisation field - wizard_job.html: email placeholder - main.py: FastAPI title - api/settings.py: SMTP test subject - notifications.py: email body header https://claude.ai/code/session_01AfKVb7RehwV197JyXeeqab
- Nuovo campo smb_share su BackupDestination (modello + migrazione automatica al boot) - backup_system_wbadmin() in windows.py: esegue wbadmin direttamente su UNC path QNAP - engine.py: job FULL su Windows con smb_share usa wbadmin (bypass trasferimento locale) - destinations.py: smb_share in create/update/serialize + test SSH migliorato - wizard_destination.html: lista + click-to-edit modal + campo smb_share - database.py: _migrate() aggiunge colonne mancanti su DB esistente - Ripristino update.sh https://claude.ai/code/session_01AfKVb7RehwV197JyXeeqab
- servers.py: aggiunto PUT /{server_id} (update), POST /{server_id}/test (SSH/WinRM),
username/ssh_port/winrm_port ora inclusi in _serialize()
- crypto.py: ripristino _is_valid_fernet_key(), lettura .secret_key da disco,
decrypt() con try/except per non crashare su chiave cambiata
- wizard_server.html: riscrittura completa con lista server, click-to-edit modal,
testa connessione, form aggiunta collassabile
https://claude.ai/code/session_01AfKVb7RehwV197JyXeeqab
…enti a CRI Catania - Nuovo endpoint GET/PUT /api/settings/general per il campo organizzazione - Topbar mostra il nome organizzazione caricato dinamicamente via JS - Notifiche email e subject test SMTP usano il nome organizzazione dal DB - settings.html: nuova card Generale con campo Nome organizzazione editabile - Rimossi tutti i riferimenti hardcoded a CRI Catania da template e codice Python https://claude.ai/code/session_01AfKVb7RehwV197JyXeeqab
- ServerType: aggiunto VMWARE come terzo tipo (retrocompatibile su SQLite) - wizard_server.html: tre tab dedicate (Linux / Windows / VMware) con form specifici per tipo; gestione host ESXi integrata nella tab VMware; lista sorgenti con badge colorati e click-to-edit per tipo - engine.py: sorgente VMWARE esegue solo snapshot+OVF; Linux/Windows mantengono il flusso esistente con snapshot VMware opzionale se configurato - servers.py: test endpoint gestisce il tipo VMWARE (verifica connessione ESXi e presenza della VM); _serialize espone vmware_host_name - wizard_job.html: tipi di backup filtrati dinamicamente in base al tipo di sorgente selezionata (VMware=solo OVF, Windows=wbadmin+app, Linux=app+vm) https://claude.ai/code/session_01AfKVb7RehwV197JyXeeqab
…ioni - Nuova pagina /docs: guida completa alla configurazione (requisiti, passo per passo per Linux/Windows/VMware, destinazioni, job, replica VM, FAQ) - Sostituisce il link "API Docs" con "Guida" nella sidebar - Aggiunta endpoint POST /api/servers/test-inline: testa la connessione SSH/WinRM/ESXi senza salvare prima la sorgente nel database - Aggiunta endpoint POST /api/destinations/test-inline: testa SSH/TCP verso il NAS senza salvare la destinazione - Pulsante "Testa connessione" nei form di aggiunta (Linux, Windows, VMware) nel wizard sorgenti — risultato mostrato inline sopra il pulsante Salva - Wizard destinazioni: il test usa ora l'endpoint inline invece di creare temporaneamente il record e poi testarlo https://claude.ai/code/session_01AfKVb7RehwV197JyXeeqab
La pagina /docs ora è una guida nativa all'app: - Checklist interattiva a 5 step che legge lo stato reale via API (sorgenti, destinazioni, job, replica VM, SMTP) - Ogni step mostra: quanti elementi configurati, verde/rosso basato sui dati reali, lista inline degli elementi già presenti - Step espandibili con spiegazioni visive e consigli contestuali - Diagramma flow replica VM con componenti HTML dello stesso stile - FAQ con blocchi comando copiabili con un click - Nessuna lista statica di API — tutto vive con i dati del sistema https://claude.ai/code/session_01AfKVb7RehwV197JyXeeqab
- qnap.py: rimosso --mkpath (non supportato su rsync < 3.2.3 del QNAP); sostituito con mkdir -p via SSH prima del trasferimento - engine.py: snapshot VMware ora gestisce RestrictedVersion (ESXi Free License) come warning anziché errore bloccante — l'export OVF prosegue direttamente senza snapshot https://claude.ai/code/session_01AfKVb7RehwV197JyXeeqab
- vmware.py: aggiunta export_vm_ovf_ovftool() che usa ovftool invece delle API NFC (compatibile con ESXi Free che blocca ExportVm()) - engine.py: nuova funzione _export_vm() prova prima pyvmomi, se riceve RestrictedVersion/Current license passa automaticamente a ovftool senza interrompere il backup https://claude.ai/code/session_01AfKVb7RehwV197JyXeeqab
ESXi Free blocca sia CreateSnapshot che ExportVm (RestrictedVersion). La lettura file dal datastore via HTTPS è invece sempre consentita. - vmware.py: aggiunta export_vm_datastore() che usa pyvmomi solo per leggere il percorso VM e lista file (operazioni read-only, consentite su Free), poi scarica i file via HTTPS /folder/ con cookie di sessione - engine.py: _export_vm() ora prova in ordine: 1. pyvmomi ExportVm (licenza standard) 2. download datastore HTTPS (ESXi Free — nessuna dipendenza esterna) 3. ovftool (se installato) https://claude.ai/code/session_01AfKVb7RehwV197JyXeeqab
Il download temporaneo in /tmp falliva con ENOSPC su VM grandi. - vmware.py: aggiunta stream_vm_to_remote() — ottiene lista file via pyvmomi read-only (permesso su Free), poi pipe curl→ssh per ogni file (curl scarica da ESXi HTTPS, ssh scrive sul QNAP) senza toccare il disco locale del server Backup-All - engine.py: backup VMware ora usa stream_vm_to_remote() e ritorna subito dopo, saltando il passaggio rsync locale→QNAP https://claude.ai/code/session_01AfKVb7RehwV197JyXeeqab
- SSH: aggiunto LogLevel=ERROR e BatchMode=yes per sopprimere il warning post-quantum che oscurava il messaggio di errore reale - mkdir remota ora controlla il return code e lancia eccezione chiara se la directory non può essere creata sul QNAP - Curl e SSH ora catturano stderr separatamente per mostrare l'errore preciso (curl vs ssh) in caso di fallimento - Aggiunto -o flag a curl per output esplicito su stdout https://claude.ai/code/session_01AfKVb7RehwV197JyXeeqab
- models.py: add XCPNG to ServerType enum, new XCPHost model, xcp_host_id FK and relationship on Server
- database.py: migration to add xcp_host_id column on servers table
- app/backup/xcpng.py: new module — XAPI session/login, list_vms, stream_vm_to_remote (snapshot → XVA export → pipe SSH to QNAP, zero local disk)
- app/api/servers.py: XCPHostCreate model, GET/POST /xcp-hosts, GET /xcp-hosts/{id}/vms, xcp_host_id in ServerCreate/update, XCPNG handling in test-inline and test endpoints, xcp_host_id/xcp_host_name in _serialize
- app/backup/engine.py: XCPNG branch in run_job (streaming direct to QNAP, retention)
- templates/wizard_server.html: XCP-ng tab, panel with host selector/VM selector, host management section, loadXCPHosts/loadXCPVMs/saveXCPHost/testInlineXCP JS, typeBadge/openEdit/saveEdit/switchTab updated for xcpng
https://claude.ai/code/session_01AfKVb7RehwV197JyXeeqab
- DELETE /api/servers/vmware-hosts/{id} con controllo sorgenti in uso
- DELETE /api/servers/xcp-hosts/{id} con controllo sorgenti in uso
- Pulsante cestino nella lista host ESXi e XCP-ng in wizard_server.html
- Funzioni deleteEsxiHost() e deleteXCPHost() con conferma
https://claude.ai/code/session_01AfKVb7RehwV197JyXeeqab
- history.html: pulsante Riprova (arrow-clockwise) sui run con status failed, chiama POST /api/jobs/{id}/run e ricarica lo storico dopo 3s
- docs.html: aggiunta card XCP-ng nella sezione Sorgenti con dettagli XAPI/XVA
- docs.html: nuova FAQ "Un backup è fallito — ricomincia da capo o riprende?" con spiegazione per tipo (rsync incrementale vs streaming da capo)
- docs.html: aggiornato ripristino con istruzione xe vm-import per XCP-ng
- docs.html: badge xcpng nella tabella sorgenti, colonna host/VM per xcpng
https://claude.ai/code/session_01AfKVb7RehwV197JyXeeqab
- base.html: api() ora gestisce risposta 204 No Content senza tentare r.json() (causava "string did not match expected pattern") - main.py: FastAPI Swagger spostato su /api/swagger per liberare /docs alla pagina Guida utente https://claude.ai/code/session_01AfKVb7RehwV197JyXeeqab
Cancellare una sorgente ora elimina automaticamente tutti i job, run e log collegati. Stesso cascade aggiunto su BackupDestination → BackupJob. https://claude.ai/code/session_01AfKVb7RehwV197JyXeeqab
Invece di cadere silenziosamente su 'Backup dati Windows' e fallire con 'nessun percorso configurato', ora mostra subito: "Backup Windows FULL richiede una Share SMB — vai su Destinazioni e compila il campo Share SMB" https://claude.ai/code/session_01AfKVb7RehwV197JyXeeqab
net use con credenziali inline fallisce su password con caratteri speciali. PSCredential è il metodo corretto in PowerShell e gestisce correttamente tutti i caratteri. https://claude.ai/code/session_01AfKVb7RehwV197JyXeeqab
- Destinazione rsync: cosa abilitare su QNAP (SSH, permessi utente, percorso share) - Destinazione API QTS: File Station e porta HTTP - Destinazione SMB: Win/Mac/NFS e permessi share per wbadmin - Sorgente Linux: SSH, utente, mysqldump/pg_dump - Sorgente Windows: comandi WinRM quickconfig, nota su SMB per backup FULL - Sorgente VMware: vSphere API, licenza Free, ruolo minimo - Sorgente XCP-ng: XAPI, ruolo Pool Admin, formato XVA https://claude.ai/code/session_01AfKVb7RehwV197JyXeeqab
…Windows - Tab rinominati con sottotitolo che spiega cosa fa ciascun tipo - Linux Server / Windows Server / VM su ESXi / VM su XCP-ng - Rimossi campi vmware_host_id e vm_name dal form Windows (confondevano) - Per backuppare una VM Windows usare il tab "VM su ESXi"
L'agente aveva lasciato tag </div> orfani dopo il box alert, causando la rottura della struttura HTML e la visualizzazione sovrapposta dei form. https://claude.ai/code/session_01AfKVb7RehwV197JyXeeqab
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
https://claude.ai/code/session_01AfKVb7RehwV197JyXeeqab