522 lines
16 KiB
Bash
522 lines
16 KiB
Bash
#!/bin/bash
|
|
|
|
#############################################
|
|
# Script de Gestion LXC pour Proxmox VE
|
|
# Date: 16/12/2025
|
|
# Description: Gestion complète des conteneurs LXC
|
|
#############################################
|
|
|
|
# Couleurs pour l'affichage
|
|
RED='\033[0;31m'
|
|
GREEN='\033[0;32m'
|
|
YELLOW='\033[1;33m'
|
|
BLUE='\033[0;34m'
|
|
NC='\033[0m' # No Color
|
|
|
|
# Fonction pour afficher le logo
|
|
show_logo() {
|
|
clear
|
|
echo -e "${BLUE}"
|
|
echo "╔═══════════════════════════════════════════════╗"
|
|
echo "║ GESTIONNAIRE LXC PROXMOX VE ║"
|
|
echo "║ Version 1.0 ║"
|
|
echo "╚═══════════════════════════════════════════════╝"
|
|
echo -e "${NC}"
|
|
}
|
|
|
|
# Fonction pour vérifier si on est sur Proxmox
|
|
check_proxmox() {
|
|
if ! command -v pct &> /dev/null; then
|
|
echo -e "${RED}Erreur: Ce script doit être exécuté sur un serveur Proxmox VE${NC}"
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
# Fonction pour lister les conteneurs
|
|
list_containers() {
|
|
echo -e "${BLUE}═══════════════════════════════════════════════${NC}"
|
|
echo -e "${GREEN}Liste des conteneurs LXC:${NC}"
|
|
echo -e "${BLUE}═══════════════════════════════════════════════${NC}"
|
|
pct list
|
|
echo ""
|
|
}
|
|
|
|
# Fonction pour créer un conteneur
|
|
create_container() {
|
|
show_logo
|
|
echo -e "${GREEN}Création d'un nouveau conteneur LXC${NC}\n"
|
|
|
|
# Liste des conteneurs existants
|
|
list_containers
|
|
|
|
# Demande du VMID
|
|
while true; do
|
|
read -p "Entrez le numéro du conteneur (VMID, ex: 100): " vmid
|
|
if [[ ! "$vmid" =~ ^[0-9]+$ ]]; then
|
|
echo -e "${RED}Erreur: Veuillez entrer un numéro valide${NC}"
|
|
continue
|
|
fi
|
|
if pct status $vmid &>/dev/null; then
|
|
echo -e "${RED}Erreur: Le VMID $vmid existe déjà${NC}"
|
|
continue
|
|
fi
|
|
break
|
|
done
|
|
|
|
# Nom du conteneur
|
|
read -p "Nom du conteneur: " hostname
|
|
|
|
# Mot de passe root
|
|
read -sp "Mot de passe root: " password
|
|
echo ""
|
|
|
|
# Stockage disponible
|
|
echo -e "\n${BLUE}Stockages disponibles:${NC}"
|
|
pvesm status | grep -E "^(local|local-lvm)" || pvesm status
|
|
echo ""
|
|
read -p "Stockage pour le conteneur (ex: local-lvm): " storage
|
|
|
|
# Template disponible
|
|
echo -e "\n${BLUE}Templates disponibles:${NC}"
|
|
pveam available | grep -i "system" | head -10
|
|
echo ""
|
|
read -p "Template à utiliser (ex: debian-12-standard): " template
|
|
|
|
# Si le template n'est pas téléchargé
|
|
if ! pveam list $storage | grep -q "$template"; then
|
|
echo -e "${YELLOW}Téléchargement du template...${NC}"
|
|
pveam download $storage $template
|
|
fi
|
|
|
|
# Ressources
|
|
read -p "RAM en MB (défaut: 512): " memory
|
|
memory=${memory:-512}
|
|
|
|
read -p "Swap en MB (défaut: 512): " swap
|
|
swap=${swap:-512}
|
|
|
|
read -p "Espace disque en GB (défaut: 8): " disk
|
|
disk=${disk:-8}
|
|
|
|
read -p "Nombre de CPU cores (défaut: 1): " cores
|
|
cores=${cores:-1}
|
|
|
|
# Bridge réseau
|
|
read -p "Bridge réseau (défaut: vmbr0): " bridge
|
|
bridge=${bridge:-vmbr0}
|
|
|
|
# Configuration IP
|
|
echo -e "\n${BLUE}Configuration réseau:${NC}"
|
|
echo "1) DHCP"
|
|
echo "2) IP statique"
|
|
read -p "Choix: " net_choice
|
|
|
|
if [ "$net_choice" = "2" ]; then
|
|
read -p "Adresse IP/CIDR (ex: 192.168.1.100/24): " ip
|
|
read -p "Passerelle: " gateway
|
|
net_config="name=eth0,bridge=$bridge,ip=$ip,gw=$gateway"
|
|
else
|
|
net_config="name=eth0,bridge=$bridge,ip=dhcp"
|
|
fi
|
|
|
|
# Démarrage automatique
|
|
read -p "Démarrage automatique? (o/n, défaut: n): " autostart
|
|
onboot="0"
|
|
[ "$autostart" = "o" ] && onboot="1"
|
|
|
|
# Création du conteneur
|
|
echo -e "\n${YELLOW}Création du conteneur en cours...${NC}"
|
|
|
|
pct create $vmid $storage:vztmpl/$template \
|
|
--hostname $hostname \
|
|
--password "$password" \
|
|
--memory $memory \
|
|
--swap $swap \
|
|
--rootfs $storage:$disk \
|
|
--cores $cores \
|
|
--net0 $net_config \
|
|
--onboot $onboot \
|
|
--unprivileged 1
|
|
|
|
if [ $? -eq 0 ]; then
|
|
echo -e "${GREEN}✓ Conteneur $vmid créé avec succès!${NC}"
|
|
read -p "Démarrer le conteneur maintenant? (o/n): " start
|
|
if [ "$start" = "o" ]; then
|
|
pct start $vmid
|
|
echo -e "${GREEN}✓ Conteneur démarré${NC}"
|
|
fi
|
|
else
|
|
echo -e "${RED}✗ Erreur lors de la création du conteneur${NC}"
|
|
fi
|
|
|
|
read -p "Appuyez sur Entrée pour continuer..."
|
|
}
|
|
|
|
# Fonction pour démarrer un conteneur
|
|
start_container() {
|
|
show_logo
|
|
list_containers
|
|
read -p "Numéro du conteneur à démarrer: " vmid
|
|
|
|
if ! pct status $vmid &>/dev/null; then
|
|
echo -e "${RED}Erreur: Le conteneur $vmid n'existe pas${NC}"
|
|
read -p "Appuyez sur Entrée pour continuer..."
|
|
return
|
|
fi
|
|
|
|
echo -e "${YELLOW}Démarrage du conteneur $vmid...${NC}"
|
|
pct start $vmid
|
|
|
|
if [ $? -eq 0 ]; then
|
|
echo -e "${GREEN}✓ Conteneur $vmid démarré avec succès${NC}"
|
|
else
|
|
echo -e "${RED}✗ Erreur lors du démarrage${NC}"
|
|
fi
|
|
|
|
read -p "Appuyez sur Entrée pour continuer..."
|
|
}
|
|
|
|
# Fonction pour arrêter un conteneur
|
|
stop_container() {
|
|
show_logo
|
|
list_containers
|
|
read -p "Numéro du conteneur à arrêter: " vmid
|
|
|
|
if ! pct status $vmid &>/dev/null; then
|
|
echo -e "${RED}Erreur: Le conteneur $vmid n'existe pas${NC}"
|
|
read -p "Appuyez sur Entrée pour continuer..."
|
|
return
|
|
fi
|
|
|
|
echo "1) Arrêt normal (shutdown)"
|
|
echo "2) Arrêt forcé (stop)"
|
|
read -p "Choix: " choice
|
|
|
|
if [ "$choice" = "1" ]; then
|
|
echo -e "${YELLOW}Arrêt normal du conteneur $vmid...${NC}"
|
|
pct shutdown $vmid
|
|
else
|
|
echo -e "${YELLOW}Arrêt forcé du conteneur $vmid...${NC}"
|
|
pct stop $vmid
|
|
fi
|
|
|
|
if [ $? -eq 0 ]; then
|
|
echo -e "${GREEN}✓ Conteneur $vmid arrêté${NC}"
|
|
else
|
|
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
|
|
reboot_container() {
|
|
show_logo
|
|
list_containers
|
|
read -p "Numéro du conteneur à redémarrer: " vmid
|
|
|
|
if ! pct status $vmid &>/dev/null; then
|
|
echo -e "${RED}Erreur: Le conteneur $vmid n'existe pas${NC}"
|
|
read -p "Appuyez sur Entrée pour continuer..."
|
|
return
|
|
fi
|
|
|
|
echo -e "${YELLOW}Redémarrage du conteneur $vmid...${NC}"
|
|
pct reboot $vmid
|
|
|
|
if [ $? -eq 0 ]; then
|
|
echo -e "${GREEN}✓ Conteneur $vmid redémarré${NC}"
|
|
else
|
|
echo -e "${RED}✗ Erreur lors du redémarrage${NC}"
|
|
fi
|
|
|
|
read -p "Appuyez sur Entrée pour continuer..."
|
|
}
|
|
|
|
# Fonction pour supprimer un conteneur
|
|
delete_container() {
|
|
show_logo
|
|
list_containers
|
|
read -p "Numéro du conteneur à supprimer: " vmid
|
|
|
|
if ! pct status $vmid &>/dev/null; then
|
|
echo -e "${RED}Erreur: Le conteneur $vmid n'existe pas${NC}"
|
|
read -p "Appuyez sur Entrée pour continuer..."
|
|
return
|
|
fi
|
|
|
|
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
|
|
echo -e "${YELLOW}Suppression annulée${NC}"
|
|
read -p "Appuyez sur Entrée pour continuer..."
|
|
return
|
|
fi
|
|
|
|
# Vérifier si le conteneur est en cours d'exécution
|
|
if pct status $vmid | grep -q "running"; then
|
|
echo -e "${YELLOW}Arrêt du conteneur en cours...${NC}"
|
|
pct stop $vmid
|
|
sleep 2
|
|
fi
|
|
|
|
echo -e "${YELLOW}Suppression du conteneur $vmid...${NC}"
|
|
pct destroy $vmid --purge
|
|
|
|
if [ $? -eq 0 ]; then
|
|
echo -e "${GREEN}✓ Conteneur $vmid supprimé avec succès${NC}"
|
|
else
|
|
echo -e "${RED}✗ Erreur lors de la suppression${NC}"
|
|
fi
|
|
|
|
read -p "Appuyez sur Entrée pour continuer..."
|
|
}
|
|
|
|
# Fonction pour déverrouiller un conteneur
|
|
unlock_container() {
|
|
show_logo
|
|
list_containers
|
|
read -p "Numéro du conteneur à déverrouiller: " vmid
|
|
|
|
if ! pct status $vmid &>/dev/null; then
|
|
echo -e "${RED}Erreur: Le conteneur $vmid n'existe pas${NC}"
|
|
read -p "Appuyez sur Entrée pour continuer..."
|
|
return
|
|
fi
|
|
|
|
echo -e "${YELLOW}Déverrouillage du conteneur $vmid...${NC}"
|
|
pct unlock $vmid
|
|
|
|
if [ $? -eq 0 ]; then
|
|
echo -e "${GREEN}✓ Conteneur $vmid déverrouillé${NC}"
|
|
else
|
|
echo -e "${RED}✗ Erreur lors du déverrouillage${NC}"
|
|
fi
|
|
|
|
read -p "Appuyez sur Entrée pour continuer..."
|
|
}
|
|
|
|
# Fonction pour backup local
|
|
backup_local() {
|
|
show_logo
|
|
list_containers
|
|
read -p "Numéro du conteneur à sauvegarder: " vmid
|
|
|
|
if ! pct status $vmid &>/dev/null; then
|
|
echo -e "${RED}Erreur: Le conteneur $vmid n'existe pas${NC}"
|
|
read -p "Appuyez sur Entrée pour continuer..."
|
|
return
|
|
fi
|
|
|
|
# Stockage disponible pour backup
|
|
echo -e "\n${BLUE}Stockages disponibles:${NC}"
|
|
pvesm status | grep -v "^Disk"
|
|
echo ""
|
|
read -p "Stockage pour la sauvegarde (défaut: local): " dumpdir
|
|
dumpdir=${dumpdir:-local}
|
|
|
|
# Type de compression
|
|
echo -e "\n${BLUE}Type de compression:${NC}"
|
|
echo "1) gzip (rapide, compression moyenne)"
|
|
echo "2) lzo (très rapide, faible compression)"
|
|
echo "3) zstd (bon compromis vitesse/compression)"
|
|
read -p "Choix (défaut: 1): " compress_choice
|
|
|
|
case $compress_choice in
|
|
2) compress="lzo";;
|
|
3) compress="zstd";;
|
|
*) compress="gzip";;
|
|
esac
|
|
|
|
# Mode de backup
|
|
echo -e "\n${BLUE}Mode de sauvegarde:${NC}"
|
|
echo "1) Snapshot (plus rapide, nécessite ZFS/LVM)"
|
|
echo "2) Stop (arrêt du conteneur)"
|
|
echo "3) Suspend (suspension temporaire)"
|
|
read -p "Choix (défaut: 1): " mode_choice
|
|
|
|
case $mode_choice in
|
|
2) mode="stop";;
|
|
3) mode="suspend";;
|
|
*) mode="snapshot";;
|
|
esac
|
|
|
|
echo -e "\n${YELLOW}Création de la sauvegarde...${NC}"
|
|
vzdump $vmid --storage $dumpdir --mode $mode --compress $compress
|
|
|
|
if [ $? -eq 0 ]; then
|
|
echo -e "${GREEN}✓ Sauvegarde créée avec succès${NC}"
|
|
echo -e "${BLUE}Emplacement: $dumpdir${NC}"
|
|
else
|
|
echo -e "${RED}✗ Erreur lors de la sauvegarde${NC}"
|
|
fi
|
|
|
|
read -p "Appuyez sur Entrée pour continuer..."
|
|
}
|
|
|
|
# Fonction pour restaurer un backup
|
|
restore_backup() {
|
|
show_logo
|
|
echo -e "${GREEN}Restauration d'une sauvegarde${NC}\n"
|
|
|
|
# Lister les sauvegardes disponibles
|
|
echo -e "${BLUE}Sauvegardes disponibles:${NC}"
|
|
pvesm list local | grep "vzdump" || echo "Aucune sauvegarde trouvée dans 'local'"
|
|
echo ""
|
|
|
|
read -p "Nom complet du fichier de sauvegarde: " backup_file
|
|
read -p "Nouveau VMID pour la restauration: " new_vmid
|
|
|
|
if pct status $new_vmid &>/dev/null; then
|
|
echo -e "${RED}Erreur: Le VMID $new_vmid existe déjà${NC}"
|
|
read -p "Appuyez sur Entrée pour continuer..."
|
|
return
|
|
fi
|
|
|
|
read -p "Stockage pour le conteneur (défaut: local-lvm): " storage
|
|
storage=${storage:-local-lvm}
|
|
|
|
echo -e "\n${YELLOW}Restauration en cours...${NC}"
|
|
pct restore $new_vmid local:backup/$backup_file --storage $storage
|
|
|
|
if [ $? -eq 0 ]; then
|
|
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
|
|
|
|
read -p "Appuyez sur Entrée pour continuer..."
|
|
}
|
|
|
|
# Fonction pour afficher les informations d'un conteneur
|
|
show_container_info() {
|
|
show_logo
|
|
list_containers
|
|
read -p "Numéro du conteneur: " vmid
|
|
|
|
if ! pct status $vmid &>/dev/null; then
|
|
echo -e "${RED}Erreur: Le conteneur $vmid n'existe pas${NC}"
|
|
read -p "Appuyez sur Entrée pour continuer..."
|
|
return
|
|
fi
|
|
|
|
echo -e "\n${BLUE}═══════════════════════════════════════════════${NC}"
|
|
echo -e "${GREEN}Informations du conteneur $vmid:${NC}"
|
|
echo -e "${BLUE}═══════════════════════════════════════════════${NC}\n"
|
|
|
|
echo -e "${YELLOW}Statut:${NC}"
|
|
pct status $vmid
|
|
echo ""
|
|
|
|
echo -e "${YELLOW}Configuration:${NC}"
|
|
pct config $vmid
|
|
echo ""
|
|
|
|
echo -e "${YELLOW}Utilisation des ressources:${NC}"
|
|
pct df $vmid 2>/dev/null || echo "Conteneur arrêté"
|
|
echo ""
|
|
|
|
read -p "Appuyez sur Entrée pour continuer..."
|
|
}
|
|
|
|
# Fonction pour entrer dans un conteneur
|
|
enter_container() {
|
|
show_logo
|
|
list_containers
|
|
read -p "Numéro du conteneur: " vmid
|
|
|
|
if ! pct status $vmid &>/dev/null; then
|
|
echo -e "${RED}Erreur: Le conteneur $vmid n'existe pas${NC}"
|
|
read -p "Appuyez sur Entrée pour continuer..."
|
|
return
|
|
fi
|
|
|
|
if ! pct status $vmid | grep -q "running"; then
|
|
echo -e "${RED}Erreur: Le conteneur doit être démarré${NC}"
|
|
read -p "Appuyez sur Entrée pour continuer..."
|
|
return
|
|
fi
|
|
|
|
echo -e "${GREEN}Connexion au conteneur $vmid...${NC}"
|
|
echo -e "${YELLOW}(Tapez 'exit' pour quitter)${NC}\n"
|
|
pct enter $vmid
|
|
}
|
|
|
|
# Fonction pour cloner un conteneur
|
|
clone_container() {
|
|
show_logo
|
|
list_containers
|
|
read -p "Numéro du conteneur source: " source_vmid
|
|
|
|
if ! pct status $source_vmid &>/dev/null; then
|
|
echo -e "${RED}Erreur: Le conteneur $source_vmid n'existe pas${NC}"
|
|
read -p "Appuyez sur Entrée pour continuer..."
|
|
return
|
|
fi
|
|
|
|
read -p "Numéro du nouveau conteneur: " new_vmid
|
|
|
|
if pct status $new_vmid &>/dev/null; then
|
|
echo -e "${RED}Erreur: Le VMID $new_vmid existe déjà${NC}"
|
|
read -p "Appuyez sur Entrée pour continuer..."
|
|
return
|
|
fi
|
|
|
|
read -p "Nom du nouveau conteneur: " new_hostname
|
|
|
|
echo -e "\n${YELLOW}Clonage en cours...${NC}"
|
|
pct clone $source_vmid $new_vmid --hostname $new_hostname
|
|
|
|
if [ $? -eq 0 ]; then
|
|
echo -e "${GREEN}✓ Conteneur cloné avec succès${NC}"
|
|
else
|
|
echo -e "${RED}✗ Erreur lors du clonage${NC}"
|
|
fi
|
|
|
|
read -p "Appuyez sur Entrée pour continuer..."
|
|
}
|
|
|
|
# Menu principal
|
|
main_menu() {
|
|
while true; do
|
|
show_logo
|
|
echo -e "${GREEN}Menu Principal:${NC}\n"
|
|
echo "1) Lister les conteneurs"
|
|
echo "2) Créer un conteneur"
|
|
echo "3) Démarrer un conteneur"
|
|
echo "4) Arrêter un conteneur"
|
|
echo "5) Redémarrer un conteneur"
|
|
echo "6) Supprimer un conteneur"
|
|
echo "7) Déverrouiller un conteneur"
|
|
echo "8) Sauvegarder un conteneur"
|
|
echo "9) Restaurer une sauvegarde"
|
|
echo "10) Afficher les informations"
|
|
echo "11) Entrer dans un conteneur"
|
|
echo "12) Cloner un conteneur"
|
|
echo "0) Quitter"
|
|
echo ""
|
|
read -p "Votre choix: " choice
|
|
|
|
case $choice in
|
|
1) show_logo; list_containers; read -p "Appuyez sur Entrée pour continuer...";;
|
|
2) create_container;;
|
|
3) start_container;;
|
|
4) stop_container;;
|
|
5) reboot_container;;
|
|
6) delete_container;;
|
|
7) unlock_container;;
|
|
8) backup_local;;
|
|
9) restore_backup;;
|
|
10) show_container_info;;
|
|
11) enter_container;;
|
|
12) clone_container;;
|
|
0) echo -e "${GREEN}Au revoir!${NC}"; exit 0;;
|
|
*) echo -e "${RED}Choix invalide${NC}"; sleep 2;;
|
|
esac
|
|
done
|
|
}
|
|
|
|
# Vérification et lancement
|
|
check_proxmox
|
|
main_menu |