++ Primo Caricamento

This commit is contained in:
2026-02-03 10:17:18 +01:00
commit 06c3e06c50
3 changed files with 754 additions and 0 deletions

532
README.md Normal file
View File

@@ -0,0 +1,532 @@
# VM Disk Export Script
Script bash per l'esportazione automatica di dischi da VM Linux verso server remoto tramite SSH, con compressione in tempo reale. Progettato per la migrazione da Tim Cloud Flex a ESXi.
## 📋 Indice
- [Caratteristiche](#caratteristiche)
- [Requisiti](#requisiti)
- [Installazione](#installazione)
- [Configurazione](#configurazione)
- [Utilizzo](#utilizzo)
- [Esempi](#esempi)
- [Opzioni Avanzate](#opzioni-avanzate)
- [Troubleshooting](#troubleshooting)
- [Note di Sicurezza](#note-di-sicurezza)
- [FAQ](#faq)
---
## ✨ Caratteristiche
- **Rilevamento automatico dischi**: Identifica automaticamente tutti i dischi fisici del sistema
- **Configurazione esterna**: Credenziali e parametri in file separato
- **Compressione in tempo reale**: Utilizza gzip per ridurre dimensioni e tempo di trasferimento
- **Progress bar**: Monitoraggio avanzamento con `pv` (Pipe Viewer)
- **Verifiche di sicurezza**: Controllo spazio, connettività SSH, permessi
- **Filtri intelligenti**: Esclude automaticamente dispositivi virtuali, USB, CD-ROM
- **Export multiplo**: Gestisce qualsiasi numero di dischi in una sola esecuzione
- **Output colorato**: Interfaccia user-friendly con codici colore
---
## 📦 Requisiti
### Sistema Operativo
- Linux (testato su Debian/Ubuntu e CentOS/RHEL)
- Accesso root o sudo
### Software Necessario
Lo script installerà automaticamente le dipendenze mancanti:
- `pv` (Pipe Viewer) - per progress bar
- `bc` - per calcoli matematici
- `ssh` - per trasferimento remoto
- `gzip` - per compressione (solitamente preinstallato)
### Server Remoto
- Server SSH accessibile
- Spazio disco sufficiente per i backup
- Autenticazione SSH configurata (chiave pubblica raccomandata)
---
## 🚀 Installazione
### 1. Download dei file
Copia i seguenti file sulla VM da cui vuoi esportare i dischi:
```bash
exportdisk.sh
exportdisk.conf
```
### 2. Imposta i permessi
```bash
# Rendi eseguibile lo script
chmod +x exportdisk.sh
# Proteggi il file di configurazione (contiene credenziali)
chmod 600 exportdisk.conf
```
### 3. Configura l'autenticazione SSH
Per evitare di inserire la password ad ogni trasferimento:
```bash
# Genera chiave SSH (se non esiste)
ssh-keygen -t rsa -b 4096
# Copia la chiave sul server remoto
ssh-copy-id setapps@172.16.0.5
# Verifica la connessione
ssh setapps@172.16.0.5 "echo 'Connessione OK'"
```
---
## ⚙️ Configurazione
Modifica il file `exportdisk.conf` con i tuoi parametri:
```bash
# Configurazione Export Disk Script
# Tutti i campi sono obbligatori
# Credenziali SSH
REMOTE_USER="setapps" # Username SSH sul server remoto
REMOTE_HOST="172.16.0.5" # IP o hostname del server remoto
REMOTE_PATH="/home/setapps/backups" # Directory di destinazione
# Filtri per il rilevamento automatico dischi
# Dispositivi da escludere (separati da |)
EXCLUDE_DEVICES="loop|sr|dm-" # loop=loopback, sr=CD/DVD, dm=device mapper
# Dimensione minima disco in GB (per escludere dispositivi piccoli)
MIN_DISK_SIZE_GB=1 # Dischi sotto 1GB vengono ignorati
```
### Parametri di Configurazione
| Parametro | Descrizione | Esempio |
|-----------|-------------|---------|
| `REMOTE_USER` | Username per connessione SSH | `setapps` |
| `REMOTE_HOST` | IP o hostname del server | `172.16.0.5` |
| `REMOTE_PATH` | Directory remota per i backup | `/home/setapps/backups` |
| `EXCLUDE_DEVICES` | Pattern regex per escludere dispositivi | `loop\|sr\|dm-` |
| `MIN_DISK_SIZE_GB` | Dimensione minima disco in GB | `1` |
---
## 🎯 Utilizzo
### Utilizzo Base
```bash
# Esegui con file di configurazione nella stessa directory
sudo ./exportdisk.sh
```
### Utilizzo con Configurazione Personalizzata
```bash
# Specifica un file di configurazione diverso
sudo ./exportdisk.sh /percorso/al/mio/config.conf
```
### Processo di Esecuzione
Lo script esegue i seguenti passaggi:
1. **Caricamento configurazione**: Legge parametri da file .conf
2. **Rilevamento dischi**: Identifica automaticamente i dischi da esportare
3. **Verifica dipendenze**: Controlla e installa pv e bc se necessario
4. **Test connettività**: Verifica connessione SSH al server remoto
5. **Controllo spazio**: Verifica spazio disponibile su destinazione
6. **Preparazione directory**: Crea directory backup se non esiste
7. **Export dischi**: Esporta ogni disco con compressione e progress bar
---
## 📚 Esempi
### Esempio 1: Export Standard
```bash
$ sudo ./exportdisk.sh
========================================
VM Disk Export Script
========================================
Caricamento configurazione da: ./exportdisk.conf
[1/6] Rilevamento dischi automatico...
✓ Rilevato: /dev/sda (50.00 GB)
✓ Rilevato: /dev/sdb (100.00 GB)
Dischi da esportare: 2
[2/6] Verifica dipendenze...
✓ Dipendenze OK
[3/6] Verifica connettività verso 172.16.0.5...
✓ Connessione SSH OK
[4/6] Verifica spazio disponibile su 172.16.0.5...
Spazio disponibile: 500 GB
✓ Spazio OK
[5/6] Preparazione directory remota...
✓ Directory pronta
[6/6] Esportazione dischi...
[1/2] Esportazione /dev/sda ...
sda: 12.5GiB 0:05:23 [39.6MiB/s] [=============>] 100%
✓ /dev/sda esportato con successo
[2/2] Esportazione /dev/sdb ...
sdb: 25.3GiB 0:10:47 [40.1MiB/s] [=============>] 100%
✓ /dev/sdb esportato con successo
========================================
Esportazione completata!
========================================
File creati su 172.16.0.5:
-rw-r--r-- 1 setapps setapps 13G Feb 3 10:30 sda_20260203_103045.img.gz
-rw-r--r-- 1 setapps setapps 26G Feb 3 10:41 sdb_20260203_103045.img.gz
Prossimi passi:
1. Decomprimere i file sul server remoto:
gunzip /home/setapps/backups/sda_20260203_103045.img.gz
gunzip /home/setapps/backups/sdb_20260203_103045.img.gz
2. Convertire in VMDK:
qemu-img convert -O vmdk sda_20260203_103045.img sda.vmdk -p
qemu-img convert -O vmdk sdb_20260203_103045.img sdb.vmdk -p
3. Trasferire su ESXi e importare la VM
```
### Esempio 2: Configurazione per Ambiente Multiplo
Puoi creare configurazioni diverse per ambienti diversi:
```bash
# Produzione
sudo ./exportdisk.sh /etc/exportdisk/prod.conf
# Staging
sudo ./exportdisk.sh /etc/exportdisk/staging.conf
# Test
sudo ./exportdisk.sh /etc/exportdisk/test.conf
```
### Esempio 3: Post-Processing sul Server Remoto
Dopo l'export, sul server remoto:
```bash
# Accedi al server
ssh setapps@172.16.0.5
# Vai nella directory backup
cd /home/setapps/backups
# Decomprimi i file
gunzip sda_20260203_103045.img.gz
gunzip sdb_20260203_103045.img.gz
# Converti in formato VMDK per ESXi
qemu-img convert -O vmdk sda_20260203_103045.img sda.vmdk -p
qemu-img convert -O vmdk sdb_20260203_103045.img sdb.vmdk -p
# Crea il descriptor VMDK (opzionale, per compatibilità)
cat > sda.vmdk << 'EOF'
# Disk DescriptorFile
version=1
CID=fffffffe
parentCID=ffffffff
createType="monolithicSparse"
EOF
```
---
## 🔧 Opzioni Avanzate
### Modifica Filtri Dispositivi
Per includere/escludere dispositivi specifici, modifica `EXCLUDE_DEVICES`:
```bash
# Esclude solo loop e sr
EXCLUDE_DEVICES="loop|sr"
# Esclude anche nvme
EXCLUDE_DEVICES="loop|sr|dm-|nvme"
# Non esclude nulla (attenzione!)
EXCLUDE_DEVICES=""
```
### Modifica Dimensione Minima Disco
```bash
# Considera solo dischi > 10GB
MIN_DISK_SIZE_GB=10
# Considera tutti i dischi
MIN_DISK_SIZE_GB=0
```
### Modifica Livello di Compressione
Nel file `exportdisk.sh`, puoi modificare il livello di compressione gzip:
```bash
# Compressione veloce (livello 1 - default)
gzip -1
# Compressione bilanciata (livello 6)
gzip -6
# Compressione massima (livello 9 - più lento)
gzip -9
```
### Modifica Block Size
Per dischi molto grandi, puoi aumentare il block size:
```bash
# Default
dd if="$disk" bs=16M ...
# Per performance migliori su dischi grandi
dd if="$disk" bs=32M ...
dd if="$disk" bs=64M ...
```
---
## 🐛 Troubleshooting
### Problema: "File di configurazione non trovato"
**Soluzione:**
```bash
# Verifica che il file esista
ls -la exportdisk.conf
# Specifica il percorso completo
sudo ./exportdisk.sh /percorso/completo/exportdisk.conf
```
### Problema: "Impossibile connettersi via SSH"
**Causa:** Chiave SSH non configurata o firewall
**Soluzione:**
```bash
# Verifica connettività
ping -c 3 172.16.0.5
# Verifica SSH
ssh -v setapps@172.16.0.5
# Configura chiave SSH
ssh-copy-id setapps@172.16.0.5
```
### Problema: "Nessun disco rilevato"
**Causa:** Filtri troppo restrittivi o MIN_DISK_SIZE_GB troppo alto
**Soluzione:**
```bash
# Verifica dischi disponibili manualmente
lsblk -d -o NAME,SIZE,TYPE
# Modifica configurazione
MIN_DISK_SIZE_GB=0
EXCLUDE_DEVICES="loop|sr"
```
### Problema: "Spazio insufficiente"
**Soluzione:**
```bash
# Sul server remoto, libera spazio
ssh setapps@172.16.0.5 "df -h"
ssh setapps@172.16.0.5 "du -sh /home/setapps/backups/*"
# Elimina backup vecchi
ssh setapps@172.16.0.5 "rm /home/setapps/backups/old_backup_*"
```
### Problema: "Permission denied"
**Soluzione:**
```bash
# Assicurati di eseguire come root
sudo ./exportdisk.sh
# Verifica permessi file
ls -la exportdisk.sh
chmod +x exportdisk.sh
```
### Problema: Export si interrompe
**Causa:** Disco con settori danneggiati
**Soluzione:**
Lo script usa `conv=sync,noerror` in dd che continua anche con errori. Controlla i log del sistema:
```bash
dmesg | grep -i error
journalctl -xe | grep -i disk
```
---
## 🔒 Note di Sicurezza
### Protezione File di Configurazione
Il file `exportdisk.conf` contiene credenziali sensibili:
```bash
# Imposta permessi restrittivi (solo root può leggere)
chmod 600 exportdisk.conf
chown root:root exportdisk.conf
```
### Autenticazione SSH
**Raccomandato:** Usa chiavi SSH invece di password
```bash
# Genera chiave con passphrase
ssh-keygen -t rsa -b 4096 -f ~/.ssh/id_rsa_backup
# Specifica la chiave nel file config SSH
cat >> ~/.ssh/config << 'EOF'
Host backup-server
HostName 172.16.0.5
User setapps
IdentityFile ~/.ssh/id_rsa_backup
EOF
```
### Crittografia Aggiuntiva
Per dati sensibili, aggiungi crittografia oltre a gzip:
```bash
# Modifica lo script per usare gpg
gzip -1 | gpg --symmetric --cipher-algo AES256 | ssh ...
```
### Logging
Salva un log delle operazioni:
```bash
sudo ./exportdisk.sh 2>&1 | tee export_$(date +%Y%m%d_%H%M%S).log
```
### Network Security
- Usa VPN o rete privata per i trasferimenti
- Considera l'uso di SSH su porta non standard
- Implementa fail2ban sul server remoto
---
## ❓ FAQ
### D: Quanto tempo impiega l'export?
**R:** Dipende da:
- Dimensione dischi
- Velocità rete
- Carico I/O del sistema
- Livello compressione
Stima approssimativa: 40-50 MB/s → ~30 minuti per 100GB
### D: Posso eseguire lo script senza essere root?
**R:** No, serve accesso root per leggere i dispositivi `/dev/sdX`
### D: Lo script funziona con NVMe?
**R:** Sì, ma assicurati che `EXCLUDE_DEVICES` non contenga "nvme"
### D: Posso exportare su disco locale invece che remoto?
**R:** Sì, modifica la parte SSH dello script:
```bash
# Invece di SSH, usa redirect locale
gzip -1 > /percorso/locale/disk_${TIMESTAMP}.img.gz
```
### D: Come verifico l'integrità dei file esportati?
**R:** Usa checksum:
```bash
# Prima dell'export (sulla VM)
md5sum /dev/sda > sda.md5
# Dopo l'import (sul server)
gunzip -c sda_20260203_103045.img.gz | md5sum
```
### D: Posso fare export incrementali?
**R:** Questo script fa export completo. Per incrementali considera:
- rsync per filesystem montati
- Strumenti di backup dedicati (Bacula, Amanda, etc.)
### D: Supporta dischi > 2TB?
**R:** Sì, `dd` e `blockdev` supportano dischi di qualsiasi dimensione
---
## 📄 License
Script fornito "as-is" per scopi di migrazione VM.
## 🤝 Supporto
Per problemi o suggerimenti, verifica:
1. Questo README
2. Log di sistema (`journalctl`, `dmesg`)
3. Output verbose SSH (`ssh -vvv`)
---
## 📝 Changelog
### Versione 2.0 (Corrente)
- ✨ Rilevamento automatico dischi
- ✨ File di configurazione esterno
- ✨ Supporto multi-disco
- 🐛 Fix gestione errori
- 📚 Documentazione completa
### Versione 1.0
- Export manuale sda/sdb
- Configurazione hardcoded
---
**Nota:** Questo script è progettato per migrazioni one-time. Per backup regolari, considera soluzioni dedicate come Veeam, Bacula, o snapshot a livello hypervisor.

14
exportdisk.conf Normal file
View File

@@ -0,0 +1,14 @@
# Configurazione Export Disk Script
# Tutti i campi sono obbligatori
# Credenziali SSH
REMOTE_USER="setapps"
REMOTE_HOST="172.16.0.5"
REMOTE_PATH="/home/setapps/backups"
# Filtri per il rilevamento automatico dischi
# Dispositivi da escludere (separati da |)
EXCLUDE_DEVICES="loop|sr|dm-"
# Dimensione minima disco in GB (per escludere dispositivi piccoli)
MIN_DISK_SIZE_GB=1

208
exportdisk.sh Normal file
View File

@@ -0,0 +1,208 @@
#!/bin/bash
#
# VM Export Script - Tim Cloud Flex to ESXi Migration
# Rileva automaticamente i dischi e li esporta verso server remoto
#
set -e # Exit on error
# File di configurazione
CONFIG_FILE="${1:-./exportdisk.conf}"
# Verifica esistenza file di configurazione
if [[ ! -f "$CONFIG_FILE" ]]; then
echo "Errore: File di configurazione non trovato: $CONFIG_FILE"
echo "Uso: $0 [percorso-config-file]"
echo "Se non specificato, cerca ./exportdisk.conf"
exit 1
fi
# Carica configurazione
echo "Caricamento configurazione da: $CONFIG_FILE"
source "$CONFIG_FILE"
# Verifica parametri obbligatori
if [[ -z "$REMOTE_USER" ]] || [[ -z "$REMOTE_HOST" ]] || [[ -z "$REMOTE_PATH" ]]; then
echo "Errore: Parametri obbligatori mancanti nel file di configurazione"
echo "Richiesti: REMOTE_USER, REMOTE_HOST, REMOTE_PATH"
exit 1
fi
# Imposta valori di default se non specificati
EXCLUDE_DEVICES="${EXCLUDE_DEVICES:-loop|sr|dm-}"
MIN_DISK_SIZE_GB="${MIN_DISK_SIZE_GB:-1}"
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
# Colori per output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
echo -e "${GREEN}========================================${NC}"
echo -e "${GREEN}VM Disk Export Script${NC}"
echo -e "${GREEN}========================================${NC}"
echo ""
# Verifica se eseguito come root
if [[ $EUID -ne 0 ]]; then
echo -e "${RED}Questo script deve essere eseguito come root${NC}"
exit 1
fi
# Rileva i dischi
DISKS=($(detect_disks | grep "^/dev/" || echo ""))
# Verifica se pv è installato
echo -e "${YELLOW}[2/6] Verifica dipendenze...${NC}"
if ! command -v pv &> /dev/null; then
echo -e "${YELLOW}pv (Pipe Viewer) non è installato. Installazione in corso...${NC}"
apt-get update -qq && apt-get install -y pv || yum install -y pv || {
echo -e "${RED}Impossibile installare pv. Installa manualmente: apt-get install pv${NC}"
exit 1
}
fi
# Verifica bc per i calcoli
if ! command -v bc &> /dev/null; then
echo -e "${YELLOW}bc non è installato. Installazione in corso...${NC}"
apt-get update -qq && apt-get install -y bc || yum install -y bc || {
echo -e "${RED}Impossibile installare bc. Installa manualmente: apt-get install bc${NC}"
exit 1
}
fi
echo -e "${GREEN}✓ Dipendenze OK${NC}"
echo ""
# Verifica connettività SSH
echo -e "${YELLOW}[3/6_name" | grep -qE "$EXCLUDE_DEVICES"; then
continue
fi
# Verifica se il disco è removibile (esclude USB, ecc.)
if [[ -f "$device/removable" ]] && [[ $(cat "$device/removable") -eq 1 ]]; then
continue
fi
# Ottieni dimensione del disco
if [[ -f "$device/size" ]]; then
sectors=$(cat "$device/size")
# Calcola dimensione in GB (settori * 512 byte / 1024^3)
size_gb=$(awk "BEGIN {printf \"%.2f\", $sectors * 512 / 1024 / 1024 / 1024}")
# Verifica dimensione minima
if (( $(echo "$size_gb >= $MIN_DISK_SIZE_GB" | bc -l) )); then
disks+=("/dev/$disk_name:$size_gb")
echo -e " ${GREEN}${NC} Rilevato: /dev/$disk_name (${size_gb} GB)"
fi
fi
done
if [[ ${#disks[@]} -eq 0 ]]; then
echo -e "${RED}Errore: Nessun disco rilevato${NC}"
exit 1
fi
echo ""
echo -e "${BLUE}Dischi da esportare: ${#disks[@]}${NC}"
echo "${disks[@]}"
}
# Verifica se pv è installato
if ! command -v pv &> /dev/null; then
echo -e "${YELLOW}pv (Pipe Viewer) non è installato. Installazione in corso...${NC}"
apt-get update -qq && apt-get install -y pv || yum install -y pv || {
echo -e "${RED}Impossibile installare pv. Installa manualmente: apt-get install pv${NC}"
exit 14/6
}
fi
# Verifica connettività SSH
echo -e "${YELLOW}[1/5] Verifica connettività verso ${REMOTE_HOST}...${NC}"
if ! ssh -o ConnectTimeout=5 ${REMOTE_USER}@${REMOTE_HOST} "echo 'OK'" &> /dev/null; then
echo -e "${RED}Errore: Impossibile connettersi a ${REMOTE_USER}@${REMOTE_HOST}${NC}"
echo "Assicurati che SSH sia configurato e che la chiave pubblica sia installata."
exit 1
fi
echo -e "${GREEN}✓ Connessione SSH OK${NC}"
echo ""
# Verifica spazio su destinazione
echo -e "${YELLOW}[2/5] Verifica spazio disponibile su ${REMOTE_HOST}...${NC}"
REMOTE_SPACE=$(ssh ${REMOTE_USER}@${REMOTE_HOST} "df -BG ${REMOTE_PATH} | tail -1 | awk '{print \$4}' | sed 's/G//'")
echo -e "Spazio disponibile: ${REMOTE_SPACE} GB"
if [[ $REMOTE_SPACE -lt 30 ]]; then
echo -e "${RED}Attenzione: Spazio insufficiente (minimo 30GB consigliato)${NC}"
read -p "Continuare comunque? (y/N): " -n 1 -r
echo
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
exit 1
fi
fi
echo -e "${GREEN}✓ Spazio OK${NC}"
echo ""
# Crea directory backup se non esiste
echo -e "${YELLOW}[5/6] Preparazione directory remota...${NC}"
ssh ${REMOTE_USER}@${REMOTE_HOST} "mkdir -p ${REMOTE_PATH}"
echo -e "${GREEN}✓ Directory pronta${NC}"
echo ""
# Export di tutti i dischi rilevati
echo -e "${YELLOW}[6/6] Esportazione dischi...${NC}"
echo ""
disk_counter=1
total_disks=${#DISKS[@]}
for disk_info in "${DISKS[@]}"; do
disk=$(echo "$disk_info" | cut -d':' -f1)
disk_name=$(basename "$disk")
echo -e "${BLUE}[$disk_counter/$total_disks] Esportazione $disk ...${NC}"
echo -e "Destinazione: ${REMOTE_USER}@${REMOTE_HOST}:${REMOTE_PATH}/${disk_name}_${TIMESTAMP}.img.gz"
echo ""
# Ottieni dimensione del disco
DISK_SIZE=$(blockdev --getsize64 "$disk")
# Esegui export
dd if="$disk" bs=16M conv=sync,noerror 2>/dev/null | \
pv -s ${DISK_SIZE} -N "$disk_name" -p -t -e -r -b | \
gzip -1 | \
ssh ${REMOTE_USER}@${REMOTE_HOST} "cat > ${REMOTE_PATH}/${disk_name}_${TIMESTAMP}.img.gz"
echo -e "\n${GREEN}$disk esportato con successo${NC}"
echo ""
((disk_counter++))
done
# Summary
echo -e "${GREEN}========================================${NC}"
echo -e "${GREEN}Esportazione completata!${NC}"
echo -e "${GREEN}========================================${NC}"
echo ""
echo "File creati su ${REMOTE_HOST}:"
ssh ${REMOTE_USER}@${REMOTE_HOST} "ls -lh ${REMOTE_PATH}/*${TIMESTAMP}*.gz"
echo ""
echo -e "${YELLOW}Prossimi passi:${NC}"
echo "1. Decomprimere i file sul server remoto:"
for disk_info in "${DISKS[@]}"; do
disk_name=$(basename $(echo "$disk_info" | cut -d':' -f1))
echo " gunzip ${REMOTE_PATH}/${disk_name}_${TIMESTAMP}.img.gz"
done
echo ""
echo "2. Convertire in VMDK:"
for disk_info in "${DISKS[@]}"; do
disk_name=$(basename $(echo "$disk_info" | cut -d':' -f1))
echo " qemu-img convert -O vmdk ${disk_name}_${TIMESTAMP}.img ${disk_name}.vmdk -p"
done
echo ""
echo "3. Trasferire su ESXi e importare la VM"
echo ""
exit 0