Actualiser lxc_manager.sh

This commit is contained in:
2025-12-18 08:27:56 +00:00
parent 99a9f79d31
commit 1707e2d26e

View File

@@ -2,16 +2,62 @@
############################################# #############################################
# Script de Gestion LXC pour Proxmox VE # Script de Gestion LXC pour Proxmox VE
# Date: 16/12/2025 # Date: 18/12/2025
# Description: Gestion complète des conteneurs LXC # Description: Gestion complète des conteneurs LXC
############################################# #############################################
# Sécurité stricte
set -euo pipefail
# Couleurs pour l'affichage # Couleurs pour l'affichage
RED='\033[0;31m' readonly RED='\033[0;31m'
GREEN='\033[0;32m' readonly GREEN='\033[0;32m'
YELLOW='\033[1;33m' readonly YELLOW='\033[1;33m'
BLUE='\033[0;34m' readonly BLUE='\033[0;34m'
NC='\033[0m' # No Color readonly NC='\033[0m' # No Color
# Fonction pour gérer les erreurs
error_exit() {
echo -e "${RED}Erreur: $1${NC}" >&2
read -p "Appuyez sur Entrée pour continuer..."
return 1
}
# Fonction pour valider un VMID
validate_vmid() {
local vmid="$1"
if [[ ! "$vmid" =~ ^[1-9][0-9]{2,8}$ ]]; then
return 1
fi
return 0
}
# Fonction pour valider un nom d'hôte
validate_hostname() {
local hostname="$1"
if [[ ! "$hostname" =~ ^[a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?$ ]]; then
return 1
fi
return 0
}
# Fonction pour valider une adresse IP
validate_ip() {
local ip="$1"
if [[ ! "$ip" =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}/[0-9]{1,2}$ ]]; then
return 1
fi
return 0
}
# Fonction pour valider un nombre positif
validate_positive_number() {
local num="$1"
if [[ ! "$num" =~ ^[1-9][0-9]*$ ]]; then
return 1
fi
return 0
}
# Fonction pour afficher le logo # Fonction pour afficher le logo
show_logo() { show_logo() {
@@ -19,7 +65,7 @@ show_logo() {
echo -e "${BLUE}" echo -e "${BLUE}"
echo "╔═══════════════════════════════════════════════╗" echo "╔═══════════════════════════════════════════════╗"
echo "║ GESTIONNAIRE LXC PROXMOX VE ║" echo "║ GESTIONNAIRE LXC PROXMOX VE ║"
echo "║ Version 1.0 ║" echo "║ Version 2.0 - Sécurisé ║"
echo "╚═══════════════════════════════════════════════╝" echo "╚═══════════════════════════════════════════════╝"
echo -e "${NC}" echo -e "${NC}"
} }
@@ -30,6 +76,11 @@ check_proxmox() {
echo -e "${RED}Erreur: Ce script doit être exécuté sur un serveur Proxmox VE${NC}" echo -e "${RED}Erreur: Ce script doit être exécuté sur un serveur Proxmox VE${NC}"
exit 1 exit 1
fi fi
if [[ $EUID -ne 0 ]]; then
echo -e "${RED}Erreur: Ce script doit être exécuté en tant que root${NC}"
exit 1
fi
} }
# Fonction pour lister les conteneurs # Fonction pour lister les conteneurs
@@ -37,10 +88,16 @@ list_containers() {
echo -e "${BLUE}═══════════════════════════════════════════════${NC}" echo -e "${BLUE}═══════════════════════════════════════════════${NC}"
echo -e "${GREEN}Liste des conteneurs LXC:${NC}" echo -e "${GREEN}Liste des conteneurs LXC:${NC}"
echo -e "${BLUE}═══════════════════════════════════════════════${NC}" echo -e "${BLUE}═══════════════════════════════════════════════${NC}"
pct list pct list || error_exit "Impossible de lister les conteneurs"
echo "" echo ""
} }
# Fonction pour vérifier l'existence d'un conteneur
container_exists() {
local vmid="$1"
pct status "$vmid" &>/dev/null
}
# Fonction pour créer un conteneur # Fonction pour créer un conteneur
create_container() { create_container() {
show_logo show_logo
@@ -49,279 +106,429 @@ create_container() {
# Liste des conteneurs existants # Liste des conteneurs existants
list_containers list_containers
# Demande du VMID # Demande et validation du VMID
local vmid
while true; do while true; do
read -p "Entrez le numéro du conteneur (VMID, ex: 100): " vmid read -rp "Entrez le numéro du conteneur (VMID, 100-999999999): " vmid
if [[ ! "$vmid" =~ ^[0-9]+$ ]]; then
echo -e "${RED}Erreur: Veuillez entrer un numéro valide${NC}" if ! validate_vmid "$vmid"; then
echo -e "${RED}Erreur: VMID invalide (doit être entre 100 et 999999999)${NC}"
continue continue
fi fi
if pct status $vmid &>/dev/null; then
if container_exists "$vmid"; then
echo -e "${RED}Erreur: Le VMID $vmid existe déjà${NC}" echo -e "${RED}Erreur: Le VMID $vmid existe déjà${NC}"
continue continue
fi fi
break break
done done
# Nom du conteneur # Nom du conteneur avec validation
read -p "Nom du conteneur: " hostname local hostname
while true; do
read -rp "Nom du conteneur (ex: web-server): " hostname
# Mot de passe root if [[ -z "$hostname" ]]; then
read -sp "Mot de passe root: " password echo -e "${RED}Erreur: Le nom ne peut pas être vide${NC}"
continue
fi
if ! validate_hostname "$hostname"; then
echo -e "${RED}Erreur: Nom invalide (lettres, chiffres, tirets uniquement)${NC}"
continue
fi
break
done
# Mot de passe root avec validation
local password password_confirm
while true; do
read -rsp "Mot de passe root (min 8 caractères): " password
echo "" echo ""
if [[ ${#password} -lt 8 ]]; then
echo -e "${RED}Erreur: Le mot de passe doit contenir au moins 8 caractères${NC}"
continue
fi
read -rsp "Confirmez le mot de passe: " password_confirm
echo ""
if [[ "$password" != "$password_confirm" ]]; then
echo -e "${RED}Erreur: Les mots de passe ne correspondent pas${NC}"
continue
fi
break
done
# Stockage disponible # Stockage disponible
echo -e "\n${BLUE}Stockages disponibles:${NC}" echo -e "\n${BLUE}Stockages disponibles:${NC}"
pvesm status | grep -E "^(local|local-lvm)" || pvesm status pvesm status | grep -E "^(local|local-lvm)" || pvesm status
echo "" echo ""
read -p "Stockage pour le conteneur (ex: local-lvm): " storage
local storage
read -rp "Stockage pour le conteneur (ex: local-lvm): " storage
if [[ -z "$storage" ]]; then
error_exit "Le stockage ne peut pas être vide"
return 1
fi
# Vérifier que le stockage existe
if ! pvesm status | grep -q "^${storage}"; then
error_exit "Le stockage '$storage' n'existe pas"
return 1
fi
# Template disponible # Template disponible
echo -e "\n${BLUE}Templates disponibles:${NC}" echo -e "\n${BLUE}Templates disponibles:${NC}"
pveam available | grep -i "system" | head -10 pveam available | grep -i "system" | head -10
echo "" echo ""
read -p "Template à utiliser (ex: debian-12-standard): " template
# Si le template n'est pas téléchargé local template
if ! pveam list $storage | grep -q "$template"; then read -rp "Template à utiliser (ex: debian-12-standard): " template
echo -e "${YELLOW}Téléchargement du template...${NC}"
pveam download $storage $template if [[ -z "$template" ]]; then
error_exit "Le template ne peut pas être vide"
return 1
fi fi
# Ressources # Si le template n'est pas téléchargé
read -p "RAM en MB (défaut: 512): " memory if ! pveam list "$storage" | grep -q "$template"; then
echo -e "${YELLOW}Téléchargement du template...${NC}"
pveam download "$storage" "$template" || {
error_exit "Échec du téléchargement du template"
return 1
}
fi
# Ressources avec validation
local memory
while true; do
read -rp "RAM en MB (défaut: 512): " memory
memory=${memory:-512} memory=${memory:-512}
read -p "Swap en MB (défaut: 512): " swap if validate_positive_number "$memory"; then
break
fi
echo -e "${RED}Erreur: Valeur invalide${NC}"
done
local swap
while true; do
read -rp "Swap en MB (défaut: 512): " swap
swap=${swap:-512} swap=${swap:-512}
read -p "Espace disque en GB (défaut: 8): " disk if validate_positive_number "$swap"; then
break
fi
echo -e "${RED}Erreur: Valeur invalide${NC}"
done
local disk
while true; do
read -rp "Espace disque en GB (défaut: 8): " disk
disk=${disk:-8} disk=${disk:-8}
read -p "Nombre de CPU cores (défaut: 1): " cores if validate_positive_number "$disk"; then
break
fi
echo -e "${RED}Erreur: Valeur invalide${NC}"
done
local cores
while true; do
read -rp "Nombre de CPU cores (défaut: 1): " cores
cores=${cores:-1} cores=${cores:-1}
# Bridge réseau if validate_positive_number "$cores"; then
read -p "Bridge réseau (défaut: vmbr0): " bridge break
fi
echo -e "${RED}Erreur: Valeur invalide${NC}"
done
# Bridge réseau avec validation
local bridge
read -rp "Bridge réseau (défaut: vmbr0): " bridge
bridge=${bridge:-vmbr0} bridge=${bridge:-vmbr0}
if [[ ! "$bridge" =~ ^vmbr[0-9]+$ ]]; then
error_exit "Bridge invalide (format: vmbr0, vmbr1, etc.)"
return 1
fi
# Configuration IP # Configuration IP
echo -e "\n${BLUE}Configuration réseau:${NC}" echo -e "\n${BLUE}Configuration réseau:${NC}"
echo "1) DHCP" echo "1) DHCP"
echo "2) IP statique" echo "2) IP statique"
read -p "Choix: " net_choice
if [ "$net_choice" = "2" ]; then local net_choice
read -p "Adresse IP/CIDR (ex: 192.168.1.100/24): " ip read -rp "Choix: " net_choice
read -p "Passerelle: " gateway
net_config="name=eth0,bridge=$bridge,ip=$ip,gw=$gateway" local net_config
if [[ "$net_choice" == "2" ]]; then
local ip gateway
while true; do
read -rp "Adresse IP/CIDR (ex: 192.168.1.100/24): " ip
if validate_ip "$ip"; then
break
fi
echo -e "${RED}Erreur: Format IP invalide${NC}"
done
read -rp "Passerelle: " gateway
net_config="name=eth0,bridge=${bridge},ip=${ip},gw=${gateway}"
else else
net_config="name=eth0,bridge=$bridge,ip=dhcp" net_config="name=eth0,bridge=${bridge},ip=dhcp"
fi fi
# Démarrage automatique # Démarrage automatique
read -p "Démarrage automatique? (o/n, défaut: n): " autostart local autostart onboot
read -rp "Démarrage automatique? (o/n, défaut: n): " autostart
onboot="0" onboot="0"
[ "$autostart" = "o" ] && onboot="1" [[ "$autostart" == "o" ]] && onboot="1"
# Création du conteneur # Création du conteneur
echo -e "\n${YELLOW}Création du conteneur en cours...${NC}" echo -e "\n${YELLOW}Création du conteneur en cours...${NC}"
pct create $vmid $storage:vztmpl/$template \ if pct create "$vmid" "${storage}:vztmpl/${template}" \
--hostname $hostname \ --hostname "$hostname" \
--password "$password" \ --password "$password" \
--memory $memory \ --memory "$memory" \
--swap $swap \ --swap "$swap" \
--rootfs $storage:$disk \ --rootfs "${storage}:${disk}" \
--cores $cores \ --cores "$cores" \
--net0 $net_config \ --net0 "$net_config" \
--onboot $onboot \ --onboot "$onboot" \
--unprivileged 1 --unprivileged 1; then
if [ $? -eq 0 ]; then
echo -e "${GREEN}✓ Conteneur $vmid créé avec succès!${NC}" echo -e "${GREEN}✓ Conteneur $vmid créé avec succès!${NC}"
read -p "Démarrer le conteneur maintenant? (o/n): " start
if [ "$start" = "o" ]; then local start
pct start $vmid read -rp "Démarrer le conteneur maintenant? (o/n): " start
echo -e "${GREEN}✓ Conteneur démarré${NC}" if [[ "$start" == "o" ]]; then
pct start "$vmid" && echo -e "${GREEN}✓ Conteneur démarré${NC}"
fi fi
else else
echo -e "${RED}✗ Erreur lors de la création du conteneur${NC}" error_exit "Échec de la création du conteneur"
fi fi
read -p "Appuyez sur Entrée pour continuer..." read -rp "Appuyez sur Entrée pour continuer..."
} }
# Fonction pour démarrer un conteneur # Fonction pour démarrer un conteneur
start_container() { start_container() {
show_logo show_logo
list_containers list_containers
read -p "Numéro du conteneur à démarrer: " vmid
if ! pct status $vmid &>/dev/null; then local vmid
echo -e "${RED}Erreur: Le conteneur $vmid n'existe pas${NC}" read -rp "Numéro du conteneur à démarrer: " vmid
read -p "Appuyez sur Entrée pour continuer..."
return if ! validate_vmid "$vmid"; then
error_exit "VMID invalide"
return 1
fi
if ! container_exists "$vmid"; then
error_exit "Le conteneur $vmid n'existe pas"
return 1
fi fi
echo -e "${YELLOW}Démarrage du conteneur $vmid...${NC}" echo -e "${YELLOW}Démarrage du conteneur $vmid...${NC}"
pct start $vmid
if [ $? -eq 0 ]; then if pct start "$vmid"; then
echo -e "${GREEN}✓ Conteneur $vmid démarré avec succès${NC}" echo -e "${GREEN}✓ Conteneur $vmid démarré avec succès${NC}"
else else
echo -e "${RED}✗ Erreur lors du démarrage${NC}" error_exit "Échec du démarrage"
fi fi
read -p "Appuyez sur Entrée pour continuer..." read -rp "Appuyez sur Entrée pour continuer..."
} }
# Fonction pour arrêter un conteneur # Fonction pour arrêter un conteneur
stop_container() { stop_container() {
show_logo show_logo
list_containers list_containers
read -p "Numéro du conteneur à arrêter: " vmid
if ! pct status $vmid &>/dev/null; then local vmid
echo -e "${RED}Erreur: Le conteneur $vmid n'existe pas${NC}" read -rp "Numéro du conteneur à arrêter: " vmid
read -p "Appuyez sur Entrée pour continuer..."
return if ! validate_vmid "$vmid"; then
error_exit "VMID invalide"
return 1
fi
if ! container_exists "$vmid"; then
error_exit "Le conteneur $vmid n'existe pas"
return 1
fi fi
echo "1) Arrêt normal (shutdown)" echo "1) Arrêt normal (shutdown)"
echo "2) Arrêt forcé (stop)" echo "2) Arrêt forcé (stop)"
read -p "Choix: " choice
if [ "$choice" = "1" ]; then local choice
read -rp "Choix: " choice
if [[ "$choice" == "1" ]]; then
echo -e "${YELLOW}Arrêt normal du conteneur $vmid...${NC}" echo -e "${YELLOW}Arrêt normal du conteneur $vmid...${NC}"
pct shutdown $vmid pct shutdown "$vmid" || error_exit "Échec de l'arrêt"
else else
echo -e "${YELLOW}Arrêt forcé du conteneur $vmid...${NC}" echo -e "${YELLOW}Arrêt forcé du conteneur $vmid...${NC}"
pct stop $vmid pct stop "$vmid" || error_exit "Échec de l'arrêt forcé"
fi fi
if [ $? -eq 0 ]; then
echo -e "${GREEN}✓ Conteneur $vmid arrêté${NC}" echo -e "${GREEN}✓ Conteneur $vmid arrêté${NC}"
else read -rp "Appuyez sur Entrée pour continuer..."
echo -e "${RED}✗ Erreur lors de l'arrêt${NC}"
fi
read -p "Appuyez sur Entrée pour continuer..."
} }
# Fonction pour redémarrer un conteneur # Fonction pour redémarrer un conteneur
reboot_container() { reboot_container() {
show_logo show_logo
list_containers list_containers
read -p "Numéro du conteneur à redémarrer: " vmid
if ! pct status $vmid &>/dev/null; then local vmid
echo -e "${RED}Erreur: Le conteneur $vmid n'existe pas${NC}" read -rp "Numéro du conteneur à redémarrer: " vmid
read -p "Appuyez sur Entrée pour continuer..."
return if ! validate_vmid "$vmid"; then
error_exit "VMID invalide"
return 1
fi
if ! container_exists "$vmid"; then
error_exit "Le conteneur $vmid n'existe pas"
return 1
fi fi
echo -e "${YELLOW}Redémarrage du conteneur $vmid...${NC}" echo -e "${YELLOW}Redémarrage du conteneur $vmid...${NC}"
pct reboot $vmid
if [ $? -eq 0 ]; then if pct reboot "$vmid"; then
echo -e "${GREEN}✓ Conteneur $vmid redémarré${NC}" echo -e "${GREEN}✓ Conteneur $vmid redémarré${NC}"
else else
echo -e "${RED}✗ Erreur lors du redémarrage${NC}" error_exit "Échec du redémarrage"
fi fi
read -p "Appuyez sur Entrée pour continuer..." read -rp "Appuyez sur Entrée pour continuer..."
} }
# Fonction pour supprimer un conteneur # Fonction pour supprimer un conteneur
delete_container() { delete_container() {
show_logo show_logo
list_containers list_containers
read -p "Numéro du conteneur à supprimer: " vmid
if ! pct status $vmid &>/dev/null; then local vmid
echo -e "${RED}Erreur: Le conteneur $vmid n'existe pas${NC}" read -rp "Numéro du conteneur à supprimer: " vmid
read -p "Appuyez sur Entrée pour continuer..."
return if ! validate_vmid "$vmid"; then
error_exit "VMID invalide"
return 1
fi
if ! container_exists "$vmid"; then
error_exit "Le conteneur $vmid n'existe pas"
return 1
fi fi
echo -e "${RED}⚠ ATTENTION: Cette action est irréversible!${NC}" echo -e "${RED}⚠ ATTENTION: Cette action est irréversible!${NC}"
read -p "Êtes-vous sûr de vouloir supprimer le conteneur $vmid? (oui/non): " confirm
if [ "$confirm" != "oui" ]; then local confirm
read -rp "Tapez exactement 'SUPPRIMER' pour confirmer: " confirm
if [[ "$confirm" != "SUPPRIMER" ]]; then
echo -e "${YELLOW}Suppression annulée${NC}" echo -e "${YELLOW}Suppression annulée${NC}"
read -p "Appuyez sur Entrée pour continuer..." read -rp "Appuyez sur Entrée pour continuer..."
return return
fi fi
# Vérifier si le conteneur est en cours d'exécution # Vérifier si le conteneur est en cours d'exécution
if pct status $vmid | grep -q "running"; then if pct status "$vmid" | grep -q "running"; then
echo -e "${YELLOW}Arrêt du conteneur en cours...${NC}" echo -e "${YELLOW}Arrêt du conteneur en cours...${NC}"
pct stop $vmid pct stop "$vmid" || true
sleep 2 sleep 2
fi fi
echo -e "${YELLOW}Suppression du conteneur $vmid...${NC}" echo -e "${YELLOW}Suppression du conteneur $vmid...${NC}"
pct destroy $vmid --purge
if [ $? -eq 0 ]; then if pct destroy "$vmid" --purge; then
echo -e "${GREEN}✓ Conteneur $vmid supprimé avec succès${NC}" echo -e "${GREEN}✓ Conteneur $vmid supprimé avec succès${NC}"
else else
echo -e "${RED}✗ Erreur lors de la suppression${NC}" error_exit "Échec de la suppression"
fi fi
read -p "Appuyez sur Entrée pour continuer..." read -rp "Appuyez sur Entrée pour continuer..."
} }
# Fonction pour déverrouiller un conteneur # Fonction pour déverrouiller un conteneur
unlock_container() { unlock_container() {
show_logo show_logo
list_containers list_containers
read -p "Numéro du conteneur à déverrouiller: " vmid
if ! pct status $vmid &>/dev/null; then local vmid
echo -e "${RED}Erreur: Le conteneur $vmid n'existe pas${NC}" read -rp "Numéro du conteneur à déverrouiller: " vmid
read -p "Appuyez sur Entrée pour continuer..."
return if ! validate_vmid "$vmid"; then
error_exit "VMID invalide"
return 1
fi
if ! container_exists "$vmid"; then
error_exit "Le conteneur $vmid n'existe pas"
return 1
fi fi
echo -e "${YELLOW}Déverrouillage du conteneur $vmid...${NC}" echo -e "${YELLOW}Déverrouillage du conteneur $vmid...${NC}"
pct unlock $vmid
if [ $? -eq 0 ]; then if pct unlock "$vmid"; then
echo -e "${GREEN}✓ Conteneur $vmid déverrouillé${NC}" echo -e "${GREEN}✓ Conteneur $vmid déverrouillé${NC}"
else else
echo -e "${RED}✗ Erreur lors du déverrouillage${NC}" error_exit "Échec du déverrouillage"
fi fi
read -p "Appuyez sur Entrée pour continuer..." read -rp "Appuyez sur Entrée pour continuer..."
} }
# Fonction pour backup local # Fonction pour backup local
backup_local() { backup_local() {
show_logo show_logo
list_containers list_containers
read -p "Numéro du conteneur à sauvegarder: " vmid
if ! pct status $vmid &>/dev/null; then local vmid
echo -e "${RED}Erreur: Le conteneur $vmid n'existe pas${NC}" read -rp "Numéro du conteneur à sauvegarder: " vmid
read -p "Appuyez sur Entrée pour continuer..."
return if ! validate_vmid "$vmid"; then
error_exit "VMID invalide"
return 1
fi
if ! container_exists "$vmid"; then
error_exit "Le conteneur $vmid n'existe pas"
return 1
fi fi
# Stockage disponible pour backup # Stockage disponible pour backup
echo -e "\n${BLUE}Stockages disponibles:${NC}" echo -e "\n${BLUE}Stockages disponibles:${NC}"
pvesm status | grep -v "^Disk" pvesm status | grep -v "^Disk"
echo "" echo ""
read -p "Stockage pour la sauvegarde (défaut: local): " dumpdir
local dumpdir
read -rp "Stockage pour la sauvegarde (défaut: local): " dumpdir
dumpdir=${dumpdir:-local} dumpdir=${dumpdir:-local}
# Vérifier que le stockage existe
if ! pvesm status | grep -q "^${dumpdir}"; then
error_exit "Le stockage '$dumpdir' n'existe pas"
return 1
fi
# Type de compression # Type de compression
echo -e "\n${BLUE}Type de compression:${NC}" echo -e "\n${BLUE}Type de compression:${NC}"
echo "1) gzip (rapide, compression moyenne)" echo "1) gzip (rapide, compression moyenne)"
echo "2) lzo (très rapide, faible compression)" echo "2) lzo (très rapide, faible compression)"
echo "3) zstd (bon compromis vitesse/compression)" echo "3) zstd (bon compromis vitesse/compression)"
read -p "Choix (défaut: 1): " compress_choice
local compress_choice compress
read -rp "Choix (défaut: 1): " compress_choice
case $compress_choice in case $compress_choice in
2) compress="lzo";; 2) compress="lzo";;
@@ -334,7 +541,9 @@ backup_local() {
echo "1) Snapshot (plus rapide, nécessite ZFS/LVM)" echo "1) Snapshot (plus rapide, nécessite ZFS/LVM)"
echo "2) Stop (arrêt du conteneur)" echo "2) Stop (arrêt du conteneur)"
echo "3) Suspend (suspension temporaire)" echo "3) Suspend (suspension temporaire)"
read -p "Choix (défaut: 1): " mode_choice
local mode_choice mode
read -rp "Choix (défaut: 1): " mode_choice
case $mode_choice in case $mode_choice in
2) mode="stop";; 2) mode="stop";;
@@ -343,16 +552,15 @@ backup_local() {
esac esac
echo -e "\n${YELLOW}Création de la sauvegarde...${NC}" echo -e "\n${YELLOW}Création de la sauvegarde...${NC}"
vzdump $vmid --storage $dumpdir --mode $mode --compress $compress
if [ $? -eq 0 ]; then if vzdump "$vmid" --storage "$dumpdir" --mode "$mode" --compress "$compress"; then
echo -e "${GREEN}✓ Sauvegarde créée avec succès${NC}" echo -e "${GREEN}✓ Sauvegarde créée avec succès${NC}"
echo -e "${BLUE}Emplacement: $dumpdir${NC}" echo -e "${BLUE}Emplacement: $dumpdir${NC}"
else else
echo -e "${RED}✗ Erreur lors de la sauvegarde${NC}" error_exit "Échec de la sauvegarde"
fi fi
read -p "Appuyez sur Entrée pour continuer..." read -rp "Appuyez sur Entrée pour continuer..."
} }
# Fonction pour restaurer un backup # Fonction pour restaurer un backup
@@ -365,40 +573,67 @@ restore_backup() {
pvesm list local | grep "vzdump" || echo "Aucune sauvegarde trouvée dans 'local'" pvesm list local | grep "vzdump" || echo "Aucune sauvegarde trouvée dans 'local'"
echo "" echo ""
read -p "Nom complet du fichier de sauvegarde: " backup_file local backup_file
read -p "Nouveau VMID pour la restauration: " new_vmid read -rp "Nom complet du fichier de sauvegarde: " backup_file
if pct status $new_vmid &>/dev/null; then if [[ -z "$backup_file" ]]; then
echo -e "${RED}Erreur: Le VMID $new_vmid existe déjà${NC}" error_exit "Le nom du fichier ne peut pas être vide"
read -p "Appuyez sur Entrée pour continuer..." return 1
return
fi fi
read -p "Stockage pour le conteneur (défaut: local-lvm): " storage local new_vmid
while true; do
read -rp "Nouveau VMID pour la restauration: " new_vmid
if ! validate_vmid "$new_vmid"; then
echo -e "${RED}VMID invalide${NC}"
continue
fi
if container_exists "$new_vmid"; then
echo -e "${RED}Erreur: Le VMID $new_vmid existe déjà${NC}"
continue
fi
break
done
local storage
read -rp "Stockage pour le conteneur (défaut: local-lvm): " storage
storage=${storage:-local-lvm} storage=${storage:-local-lvm}
echo -e "\n${YELLOW}Restauration en cours...${NC}" # Vérifier que le stockage existe
pct restore $new_vmid local:backup/$backup_file --storage $storage if ! pvesm status | grep -q "^${storage}"; then
error_exit "Le stockage '$storage' n'existe pas"
if [ $? -eq 0 ]; then return 1
echo -e "${GREEN}✓ Sauvegarde restaurée avec succès sur VMID $new_vmid${NC}"
else
echo -e "${RED}✗ Erreur lors de la restauration${NC}"
fi fi
read -p "Appuyez sur Entrée pour continuer..." echo -e "\n${YELLOW}Restauration en cours...${NC}"
if pct restore "$new_vmid" "local:backup/${backup_file}" --storage "$storage"; then
echo -e "${GREEN}✓ Sauvegarde restaurée avec succès sur VMID $new_vmid${NC}"
else
error_exit "Échec de la restauration"
fi
read -rp "Appuyez sur Entrée pour continuer..."
} }
# Fonction pour afficher les informations d'un conteneur # Fonction pour afficher les informations d'un conteneur
show_container_info() { show_container_info() {
show_logo show_logo
list_containers list_containers
read -p "Numéro du conteneur: " vmid
if ! pct status $vmid &>/dev/null; then local vmid
echo -e "${RED}Erreur: Le conteneur $vmid n'existe pas${NC}" read -rp "Numéro du conteneur: " vmid
read -p "Appuyez sur Entrée pour continuer..."
return if ! validate_vmid "$vmid"; then
error_exit "VMID invalide"
return 1
fi
if ! container_exists "$vmid"; then
error_exit "Le conteneur $vmid n'existe pas"
return 1
fi fi
echo -e "\n${BLUE}═══════════════════════════════════════════════${NC}" echo -e "\n${BLUE}═══════════════════════════════════════════════${NC}"
@@ -406,75 +641,107 @@ show_container_info() {
echo -e "${BLUE}═══════════════════════════════════════════════${NC}\n" echo -e "${BLUE}═══════════════════════════════════════════════${NC}\n"
echo -e "${YELLOW}Statut:${NC}" echo -e "${YELLOW}Statut:${NC}"
pct status $vmid pct status "$vmid" || true
echo "" echo ""
echo -e "${YELLOW}Configuration:${NC}" echo -e "${YELLOW}Configuration:${NC}"
pct config $vmid pct config "$vmid" || true
echo "" echo ""
echo -e "${YELLOW}Utilisation des ressources:${NC}" echo -e "${YELLOW}Utilisation des ressources:${NC}"
pct df $vmid 2>/dev/null || echo "Conteneur arrêté" pct df "$vmid" 2>/dev/null || echo "Conteneur arrêté"
echo "" echo ""
read -p "Appuyez sur Entrée pour continuer..." read -rp "Appuyez sur Entrée pour continuer..."
} }
# Fonction pour entrer dans un conteneur # Fonction pour entrer dans un conteneur
enter_container() { enter_container() {
show_logo show_logo
list_containers list_containers
read -p "Numéro du conteneur: " vmid
if ! pct status $vmid &>/dev/null; then local vmid
echo -e "${RED}Erreur: Le conteneur $vmid n'existe pas${NC}" read -rp "Numéro du conteneur: " vmid
read -p "Appuyez sur Entrée pour continuer..."
return if ! validate_vmid "$vmid"; then
error_exit "VMID invalide"
return 1
fi fi
if ! pct status $vmid | grep -q "running"; then if ! container_exists "$vmid"; then
echo -e "${RED}Erreur: Le conteneur doit être démarré${NC}" error_exit "Le conteneur $vmid n'existe pas"
read -p "Appuyez sur Entrée pour continuer..." return 1
return fi
if ! pct status "$vmid" | grep -q "running"; then
error_exit "Le conteneur doit être démarré"
return 1
fi fi
echo -e "${GREEN}Connexion au conteneur $vmid...${NC}" echo -e "${GREEN}Connexion au conteneur $vmid...${NC}"
echo -e "${YELLOW}(Tapez 'exit' pour quitter)${NC}\n" echo -e "${YELLOW}(Tapez 'exit' pour quitter)${NC}\n"
pct enter $vmid pct enter "$vmid" || error_exit "Échec de la connexion"
} }
# Fonction pour cloner un conteneur # Fonction pour cloner un conteneur
clone_container() { clone_container() {
show_logo show_logo
list_containers list_containers
read -p "Numéro du conteneur source: " source_vmid
if ! pct status $source_vmid &>/dev/null; then local source_vmid
echo -e "${RED}Erreur: Le conteneur $source_vmid n'existe pas${NC}" read -rp "Numéro du conteneur source: " source_vmid
read -p "Appuyez sur Entrée pour continuer..."
return if ! validate_vmid "$source_vmid"; then
error_exit "VMID source invalide"
return 1
fi fi
read -p "Numéro du nouveau conteneur: " new_vmid if ! container_exists "$source_vmid"; then
error_exit "Le conteneur $source_vmid n'existe pas"
return 1
fi
if pct status $new_vmid &>/dev/null; then local new_vmid
while true; do
read -rp "Numéro du nouveau conteneur: " new_vmid
if ! validate_vmid "$new_vmid"; then
echo -e "${RED}VMID invalide${NC}"
continue
fi
if container_exists "$new_vmid"; then
echo -e "${RED}Erreur: Le VMID $new_vmid existe déjà${NC}" echo -e "${RED}Erreur: Le VMID $new_vmid existe déjà${NC}"
read -p "Appuyez sur Entrée pour continuer..." continue
return fi
break
done
local new_hostname
while true; do
read -rp "Nom du nouveau conteneur: " new_hostname
if [[ -z "$new_hostname" ]]; then
echo -e "${RED}Le nom ne peut pas être vide${NC}"
continue
fi fi
read -p "Nom du nouveau conteneur: " new_hostname if ! validate_hostname "$new_hostname"; then
echo -e "${RED}Nom invalide${NC}"
continue
fi
break
done
echo -e "\n${YELLOW}Clonage en cours...${NC}" echo -e "\n${YELLOW}Clonage en cours...${NC}"
pct clone $source_vmid $new_vmid --hostname $new_hostname
if [ $? -eq 0 ]; then if pct clone "$source_vmid" "$new_vmid" --hostname "$new_hostname"; then
echo -e "${GREEN}✓ Conteneur cloné avec succès${NC}" echo -e "${GREEN}✓ Conteneur cloné avec succès${NC}"
else else
echo -e "${RED}✗ Erreur lors du clonage${NC}" error_exit "Échec du clonage"
fi fi
read -p "Appuyez sur Entrée pour continuer..." read -rp "Appuyez sur Entrée pour continuer..."
} }
# Menu principal # Menu principal
@@ -496,27 +763,34 @@ main_menu() {
echo "12) Cloner un conteneur" echo "12) Cloner un conteneur"
echo "0) Quitter" echo "0) Quitter"
echo "" echo ""
read -p "Votre choix: " choice
local choice
read -rp "Votre choix: " choice
case $choice in case $choice in
1) show_logo; list_containers; read -p "Appuyez sur Entrée pour continuer...";; 1) show_logo; list_containers; read -rp "Appuyez sur Entrée pour continuer...";;
2) create_container;; 2) create_container || true;;
3) start_container;; 3) start_container || true;;
4) stop_container;; 4) stop_container || true;;
5) reboot_container;; 5) reboot_container || true;;
6) delete_container;; 6) delete_container || true;;
7) unlock_container;; 7) unlock_container || true;;
8) backup_local;; 8) backup_local || true;;
9) restore_backup;; 9) restore_backup || true;;
10) show_container_info;; 10) show_container_info || true;;
11) enter_container;; 11) enter_container || true;;
12) clone_container;; 12) clone_container || true;;
0) echo -e "${GREEN}Au revoir!${NC}"; exit 0;; 0) echo -e "${GREEN}Au revoir!${NC}"; exit 0;;
*) echo -e "${RED}Choix invalide${NC}"; sleep 2;; *) echo -e "${RED}Choix invalide${NC}"; sleep 2;;
esac esac
done done
} }
# Vérification et lancement # Point d'entrée principal
check_proxmox main() {
main_menu check_proxmox
main_menu
}
# Lancement du script
main