script generazioni vm su proxmox

This commit is contained in:
2025-11-29 18:14:49 +01:00
parent 17fa8eb056
commit c688eefe0b

341
scripts/create-vm.sh Executable file
View File

@@ -0,0 +1,341 @@
#!/bin/bash
# create-vm.sh
# Script per creare singole VM su Proxmox con parametri personalizzabili
# Uso: ./create-vm.sh <vm_id> <vm_name> [cores] [memory_mb] [disk_size]
# Esempio: ./create-vm.sh 203 web-server 4 8192 50G
set -e
# ==================== CONFIGURAZIONE ====================
# Parametri da riga di comando
if [ "$#" -lt 2 ]; then
echo "Uso: $0 <vm_id> <vm_name> [cores] [memory_mb] [disk_size]"
echo ""
echo "Parametri obbligatori:"
echo " vm_id - ID della VM Proxmox (es: 203)"
echo " vm_name - Nome della VM (es: web-server)"
echo ""
echo "Parametri opzionali (valori di default):"
echo " cores - Numero di CPU cores (default: 4)"
echo " memory_mb - RAM in MB (default: 8192)"
echo " disk_size - Dimensione disco con unità (default: 50G)"
echo ""
echo "Esempi:"
echo " $0 203 web-server # VM con valori default"
echo " $0 203 web-server 2 4096 30G # VM con 2 cores, 4GB RAM, 30GB disco"
echo ""
echo "Nota: L'IP sarà automaticamente 192.168.1.<vm_id>"
exit 1
fi
VM_ID=$1
VM_NAME=$2
VM_IP="192.168.1.${VM_ID}"
# Parametri opzionali con valori di default
CORES=${3:-2}
MEMORY=${4:-4096}
DISK_SIZE=${5:-20G}
# Configurazione Proxmox
PVE_NODE="server"
STORAGE="sddmirror" # Storage principale per i dischi VM (supporta Images)
BRIDGE="vmbr0"
# FIX: Due variabili per lo storage
CLOUDINIT_VOL_STORAGE="$STORAGE" # sddmirror: Useremo lo storage principale che supporta i volumi disco Cloud-Init (Images)
SNIPPET_STORAGE="local" # local: Manteniamo 'local' per i file snippet YAML
# Configurazione di rete
GATEWAY="192.168.1.1"
NETMASK="24"
DNS="8.8.8.8"
# Template
TEMPLATE_ID=9000
UBUNTU_IMAGE_URL="https://cloud-images.ubuntu.com/noble/current/noble-server-cloudimg-amd64.img"
UBUNTU_IMAGE_NAME="ubuntu-24.04-cloudimg.img"
# Credenziali
SSH_PUBLIC_KEY="ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOyva+cul3WOW3ct53a0QMRTkhtKvA2QpJI0p8bv48tH alex@alex-XPS-15-9570"
ROOT_PASSWORD="TempProxmox123!"
# Directory applicazioni
APP_DIR="/opt/myapp"
# Directory per gli snippet
SNIPPETS_DIR="/var/lib/vz/snippets"
# Colors
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'
# ==================== FUNZIONI ====================
print_header() {
echo -e "${BLUE}================================================${NC}"
echo -e "${BLUE}$1${NC}"
echo -e "${BLUE}================================================${NC}"
}
print_success() { echo -e "${GREEN}$1${NC}"; }
print_warning() { echo -e "${YELLOW}$1${NC}"; }
print_error() { echo -e "${RED}$1${NC}"; }
print_info() { echo -e "${BLUE} $1${NC}"; }
check_command() {
if ! command -v $1 &> /dev/null; then
print_error "$1 non trovato. Installalo: apt install $1"
exit 1
fi
}
# Funzione per generare il file user-data YAML personalizzato (come snippet)
create_custom_user_data() {
local vm_name=$1
local output_file="/tmp/${vm_name}-user-data.yaml"
# Crea user-data YAML
cat > "$output_file" << EOF
#cloud-config
hostname: $vm_name
fqdn: ${vm_name}.local
manage_etc_hosts: true
users:
- name: root
ssh_authorized_keys:
- $SSH_PUBLIC_KEY
lock_passwd: false
shell: /bin/bash
chpasswd:
list: |
root:$ROOT_PASSWORD
expire: false
ssh_pwauth: true
disable_root: false
packages:
- curl
- wget
- git
- htop
- net-tools
- qemu-guest-agent
runcmd:
# Install Docker
- mkdir -p /etc/apt/keyrings
- curl -fsSL https://download.docker.com/linux/ubuntu/gpg | gpg --dearmor -o /etc/apt/keyrings/docker.gpg
- echo "deb [arch=\$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \$(lsb_release -cs) stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null
- apt-get update
- apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
- systemctl enable docker
- systemctl start docker
- systemctl enable qemu-guest-agent
- systemctl start qemu-guest-agent
# Configure sysctl
- echo "net.ipv4.ip_nonlocal_bind=1" >> /etc/sysctl.conf
- echo "net.ipv4.ip_forward=1" >> /etc/sysctl.conf
- sysctl -p
# Create app directory
- mkdir -p $APP_DIR
- chown -R root:root $APP_DIR
# Ensure SSH is properly configured
- sed -i 's/#*PermitRootLogin.*/PermitRootLogin yes/' /etc/ssh/sshd_config
- sed -i 's/#*PubkeyAuthentication.*/PubkeyAuthentication yes/' /etc/ssh/sshd_config
- systemctl restart sshd
power_state:
mode: reboot
timeout: 300
condition: true
EOF
echo "$output_file"
}
# ==================== SCRIPT PRINCIPALE ====================
print_header "CREAZIONE VM SU PROXMOX"
# Check prerequisites
print_info "Verifica prerequisiti..."
check_command "qm"
print_success "Prerequisiti OK"
# Validazione parametri
if ! [[ "$VM_ID" =~ ^[0-9]+$ ]]; then
print_error "VM_ID deve essere un numero valido"
exit 1
fi
if [ "$VM_ID" -eq "$TEMPLATE_ID" ]; then
print_error "VM_ID $VM_ID è riservato per il template"
exit 1
fi
if ! [[ "$CORES" =~ ^[0-9]+$ ]] || [ "$CORES" -lt 1 ]; then
print_error "CORES deve essere un numero positivo (valore fornito: $CORES)"
exit 1
fi
if ! [[ "$MEMORY" =~ ^[0-9]+$ ]] || [ "$MEMORY" -lt 512 ]; then
print_error "MEMORY deve essere almeno 512 MB (valore fornito: $MEMORY)"
exit 1
fi
if ! [[ "$DISK_SIZE" =~ ^[0-9]+[GMK]$ ]]; then
print_error "DISK_SIZE deve essere nel formato numero+unità (es: 50G, 500M) (valore fornito: $DISK_SIZE)"
exit 1
fi
print_info "Configurazione VM:"
print_info " ID: $VM_ID"
print_info " Nome: $VM_NAME"
print_info " IP: $VM_IP"
print_info " CPU Cores: $CORES"
print_info " RAM: ${MEMORY}MB"
print_info " Disco: $DISK_SIZE"
# Crea la directory snippet se non esiste
mkdir -p "$SNIPPETS_DIR"
# Verifica se la VM esiste già
if qm status $VM_ID &>/dev/null; then
print_warning "VM $VM_ID già esistente!"
read -p "Vuoi eliminarlo e ricrearlo? (y/N) " -n 1 -r
echo
if [[ $REPLY =~ ^[Yy]$ ]]; then
print_info "Arresto VM $VM_ID..."
qm stop $VM_ID || true
sleep 3
print_info "Eliminazione VM $VM_ID..."
qm destroy $VM_ID
# Pulizia dei file custom
rm -f "${SNIPPETS_DIR}/${VM_ID}-user-data.yaml"
print_success "VM $VM_ID eliminata"
else
print_error "Operazione annullata"
exit 1
fi
fi
# ==================== VERIFICA/CREA TEMPLATE ====================
print_header "STEP 1: Verifica Template Cloud-Init"
if ! qm status $TEMPLATE_ID &>/dev/null; then
print_info "Template non trovato. Creazione in corso..."
cd /tmp
if [ ! -f "$UBUNTU_IMAGE_NAME" ]; then
print_info "Download Ubuntu Cloud Image..."
wget -q --show-progress $UBUNTU_IMAGE_URL -O $UBUNTU_IMAGE_NAME
fi
print_info "Creazione template VM..."
qm create $TEMPLATE_ID --name ubuntu-cloud-template --memory $MEMORY --net0 virtio,bridge=$BRIDGE --cores $CORES
# Importa il disco
qm importdisk $TEMPLATE_ID $UBUNTU_IMAGE_NAME $STORAGE &>/dev/null
qm set $TEMPLATE_ID --scsihw virtio-scsi-single --scsi0 ${STORAGE}:vm-${TEMPLATE_ID}-disk-0
# Configurazione Cloud-Init
qm set $TEMPLATE_ID --delete ide0 2>/dev/null || true
qm set $TEMPLATE_ID --delete ide2 2>/dev/null || true
# Aggiungi il drive per cloud-init
qm set $TEMPLATE_ID --ide2 ${CLOUDINIT_VOL_STORAGE}:cloudinit,format=raw
# Imposta configurazioni essenziali
qm set $TEMPLATE_ID --cpu x86-64-v2-AES
qm set $TEMPLATE_ID --agent enabled=1
qm set $TEMPLATE_ID --boot c --bootdisk scsi0
# Resize del disco del template
qm resize $TEMPLATE_ID scsi0 $DISK_SIZE &>/dev/null || true
qm template $TEMPLATE_ID
print_success "Template creato con successo"
else
print_success "Template già esistente"
fi
# ==================== CREA VM ====================
print_header "STEP 2: Creazione VM $VM_NAME (ID: $VM_ID, IP: $VM_IP)"
print_info "Clonazione template..."
qm clone $TEMPLATE_ID $VM_ID --name $VM_NAME --full
# 1. Crea il file user-data personalizzato
USER_DATA_FILE=$(create_custom_user_data $VM_NAME)
# 2. Crea il file SSH temporaneo
SSH_KEY_FILE="/tmp/${VM_NAME}_id_rsa.pub"
echo "$SSH_PUBLIC_KEY" > "$SSH_KEY_FILE"
print_info "Chiave SSH salvata in $SSH_KEY_FILE per l'iniezione."
# 3. Allega il file user-data personalizzato come snippet (cicustom)
SNIPPET_FILENAME="${VM_ID}-user-data.yaml"
# 4. Configura VM con tutti i dati di Cloud-Init
print_info "Iniezione configurazione Cloud-Init..."
qm set $VM_ID \
--ciuser root \
--sshkeys "$SSH_KEY_FILE" \
--ipconfig0 "ip=${VM_IP}/${NETMASK},gw=${GATEWAY}" \
--nameserver "${DNS}" \
--cicustom "user=${SNIPPET_STORAGE}:snippets/${SNIPPET_FILENAME}"
# 5. Sposta il file user-data nella directory snippets di Proxmox
mv "$USER_DATA_FILE" "${SNIPPETS_DIR}/${SNIPPET_FILENAME}"
# 6. PULIZIA: Rimuovi il file temporaneo della chiave SSH
rm "$SSH_KEY_FILE"
print_success "VM configurata e dati cloud-init iniettati"
# ==================== AVVIA VM ====================
print_header "STEP 3: Avvio della VM"
print_info "Avvio VM $VM_NAME ($VM_IP)..."
qm start $VM_ID
sleep 5
print_info "Attendo cloud-init (2-3 minuti). Il primo avvio può richiedere tempo per il resize e le installazioni."
sleep 180
# ==================== RIEPILOGO ====================
print_header "CREAZIONE VM COMPLETATA! 🎉"
print_info ""
print_info "Dettagli VM:"
print_info " Nome: $VM_NAME"
print_info " ID: $VM_ID"
print_info " IP: ${GREEN}$VM_IP${NC}"
print_info " Cores: $CORES"
print_info " Memory: ${MEMORY}MB"
print_info " Disk: $DISK_SIZE"
print_info ""
print_info "Credenziali:"
print_info " User: root"
print_info " Password: $ROOT_PASSWORD"
print_info " SSH Key: configurata"
print_info ""
print_info "Test connessione (attendere il riavvio causato da cloud-init se non funziona subito):"
print_info " ssh root@$VM_IP"
print_info ""
print_success "Setup completato! La VM ora ha IP statico $VM_IP, Docker installato e chiave SSH configurata."