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
# Date: 16/12/2025
# Date: 18/12/2025
# Description: Gestion complète des conteneurs LXC
#############################################
# Sécurité stricte
set -euo pipefail
# 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
readonly RED='\033[0;31m'
readonly GREEN='\033[0;32m'
readonly YELLOW='\033[1;33m'
readonly BLUE='\033[0;34m'
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
show_logo() {
@@ -19,7 +65,7 @@ show_logo() {
echo -e "${BLUE}"
echo "╔═══════════════════════════════════════════════╗"
echo "║ GESTIONNAIRE LXC PROXMOX VE ║"
echo "║ Version 1.0 ║"
echo "║ Version 2.0 - Sécurisé ║"
echo "╚═══════════════════════════════════════════════╝"
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}"
exit 1
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
@@ -37,10 +88,16 @@ list_containers() {
echo -e "${BLUE}═══════════════════════════════════════════════${NC}"
echo -e "${GREEN}Liste des conteneurs LXC:${NC}"
echo -e "${BLUE}═══════════════════════════════════════════════${NC}"
pct list
pct list || error_exit "Impossible de lister les conteneurs"
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
create_container() {
show_logo
@@ -49,279 +106,429 @@ create_container() {
# Liste des conteneurs existants
list_containers
# Demande du VMID
# Demande et validation du VMID
local 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}"
read -rp "Entrez le numéro du conteneur (VMID, 100-999999999): " vmid
if ! validate_vmid "$vmid"; then
echo -e "${RED}Erreur: VMID invalide (doit être entre 100 et 999999999)${NC}"
continue
fi
if pct status $vmid &>/dev/null; then
if container_exists "$vmid"; 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
# Nom du conteneur avec validation
local hostname
while true; do
read -rp "Nom du conteneur (ex: web-server): " hostname
if [[ -z "$hostname" ]]; then
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
read -sp "Mot de passe root: " password
echo ""
# 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 ""
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
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
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
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
local template
read -rp "Template à utiliser (ex: debian-12-standard): " template
if [[ -z "$template" ]]; then
error_exit "Le template ne peut pas être vide"
return 1
fi
# Ressources
read -p "RAM en MB (défaut: 512): " memory
memory=${memory:-512}
# 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" || {
error_exit "Échec du téléchargement du template"
return 1
}
fi
read -p "Swap en MB (défaut: 512): " swap
swap=${swap:-512}
# Ressources avec validation
local memory
while true; do
read -rp "RAM en MB (défaut: 512): " memory
memory=${memory:-512}
if validate_positive_number "$memory"; then
break
fi
echo -e "${RED}Erreur: Valeur invalide${NC}"
done
read -p "Espace disque en GB (défaut: 8): " disk
disk=${disk:-8}
local swap
while true; do
read -rp "Swap en MB (défaut: 512): " swap
swap=${swap:-512}
if validate_positive_number "$swap"; then
break
fi
echo -e "${RED}Erreur: Valeur invalide${NC}"
done
read -p "Nombre de CPU cores (défaut: 1): " cores
cores=${cores:-1}
local disk
while true; do
read -rp "Espace disque en GB (défaut: 8): " disk
disk=${disk:-8}
if validate_positive_number "$disk"; then
break
fi
echo -e "${RED}Erreur: Valeur invalide${NC}"
done
# Bridge réseau
read -p "Bridge réseau (défaut: vmbr0): " bridge
local cores
while true; do
read -rp "Nombre de CPU cores (défaut: 1): " cores
cores=${cores:-1}
if validate_positive_number "$cores"; then
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}
if [[ ! "$bridge" =~ ^vmbr[0-9]+$ ]]; then
error_exit "Bridge invalide (format: vmbr0, vmbr1, etc.)"
return 1
fi
# 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"
local net_choice
read -rp "Choix: " net_choice
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
net_config="name=eth0,bridge=$bridge,ip=dhcp"
net_config="name=eth0,bridge=${bridge},ip=dhcp"
fi
# 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"
[ "$autostart" = "o" ] && onboot="1"
[[ "$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 \
if 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
--memory "$memory" \
--swap "$swap" \
--rootfs "${storage}:${disk}" \
--cores "$cores" \
--net0 "$net_config" \
--onboot "$onboot" \
--unprivileged 1; 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}"
local start
read -rp "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}"
error_exit "Échec de la création du conteneur"
fi
read -p "Appuyez sur Entrée pour continuer..."
read -rp "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
local vmid
read -rp "Numéro du conteneur à démarrer: " vmid
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
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}"
else
echo -e "${RED}✗ Erreur lors du démarrage${NC}"
error_exit "Échec du démarrage"
fi
read -p "Appuyez sur Entrée pour continuer..."
read -rp "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
local vmid
read -rp "Numéro du conteneur à arrêter: " vmid
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
echo "1) Arrêt normal (shutdown)"
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}"
pct shutdown $vmid
pct shutdown "$vmid" || error_exit "Échec de l'arrêt"
else
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
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..."
echo -e "${GREEN}✓ Conteneur $vmid arrêté${NC}"
read -rp "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
local vmid
read -rp "Numéro du conteneur à redémarrer: " vmid
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
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}"
else
echo -e "${RED}✗ Erreur lors du redémarrage${NC}"
error_exit "Échec du redémarrage"
fi
read -p "Appuyez sur Entrée pour continuer..."
read -rp "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
local vmid
read -rp "Numéro du conteneur à supprimer: " vmid
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
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}"
read -p "Appuyez sur Entrée pour continuer..."
read -rp "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
if pct status "$vmid" | grep -q "running"; then
echo -e "${YELLOW}Arrêt du conteneur en cours...${NC}"
pct stop $vmid
pct stop "$vmid" || true
sleep 2
fi
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}"
else
echo -e "${RED}✗ Erreur lors de la suppression${NC}"
error_exit "Échec de la suppression"
fi
read -p "Appuyez sur Entrée pour continuer..."
read -rp "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
local vmid
read -rp "Numéro du conteneur à déverrouiller: " vmid
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
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}"
else
echo -e "${RED}✗ Erreur lors du déverrouillage${NC}"
error_exit "Échec du déverrouillage"
fi
read -p "Appuyez sur Entrée pour continuer..."
read -rp "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
local vmid
read -rp "Numéro du conteneur à sauvegarder: " vmid
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
# 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
local dumpdir
read -rp "Stockage pour la sauvegarde (défaut: local): " dumpdir
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
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
local compress_choice compress
read -rp "Choix (défaut: 1): " compress_choice
case $compress_choice in
2) compress="lzo";;
@@ -334,7 +541,9 @@ backup_local() {
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
local mode_choice mode
read -rp "Choix (défaut: 1): " mode_choice
case $mode_choice in
2) mode="stop";;
@@ -343,16 +552,15 @@ backup_local() {
esac
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 "${BLUE}Emplacement: $dumpdir${NC}"
else
echo -e "${RED}✗ Erreur lors de la sauvegarde${NC}"
error_exit "Échec de la sauvegarde"
fi
read -p "Appuyez sur Entrée pour continuer..."
read -rp "Appuyez sur Entrée pour continuer..."
}
# Fonction pour restaurer un backup
@@ -365,40 +573,67 @@ restore_backup() {
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
local backup_file
read -rp "Nom complet du fichier de sauvegarde: " backup_file
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
if [[ -z "$backup_file" ]]; then
error_exit "Le nom du fichier ne peut pas être vide"
return 1
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}
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}"
# Vérifier que le stockage existe
if ! pvesm status | grep -q "^${storage}"; then
error_exit "Le stockage '$storage' n'existe pas"
return 1
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
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
local vmid
read -rp "Numéro du conteneur: " vmid
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
echo -e "\n${BLUE}═══════════════════════════════════════════════${NC}"
@@ -406,75 +641,107 @@ show_container_info() {
echo -e "${BLUE}═══════════════════════════════════════════════${NC}\n"
echo -e "${YELLOW}Statut:${NC}"
pct status $vmid
pct status "$vmid" || true
echo ""
echo -e "${YELLOW}Configuration:${NC}"
pct config $vmid
pct config "$vmid" || true
echo ""
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 ""
read -p "Appuyez sur Entrée pour continuer..."
read -rp "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
local vmid
read -rp "Numéro du conteneur: " vmid
if ! validate_vmid "$vmid"; then
error_exit "VMID invalide"
return 1
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
if ! container_exists "$vmid"; then
error_exit "Le conteneur $vmid n'existe pas"
return 1
fi
if ! pct status "$vmid" | grep -q "running"; then
error_exit "Le conteneur doit être démarré"
return 1
fi
echo -e "${GREEN}Connexion au conteneur $vmid...${NC}"
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
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
local source_vmid
read -rp "Numéro du conteneur source: " source_vmid
if ! validate_vmid "$source_vmid"; then
error_exit "VMID source invalide"
return 1
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
if ! container_exists "$source_vmid"; then
error_exit "Le conteneur $source_vmid n'existe pas"
return 1
fi
read -p "Nom du nouveau conteneur: " new_hostname
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}"
continue
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
if ! validate_hostname "$new_hostname"; then
echo -e "${RED}Nom invalide${NC}"
continue
fi
break
done
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}"
else
echo -e "${RED}✗ Erreur lors du clonage${NC}"
error_exit "Échec du clonage"
fi
read -p "Appuyez sur Entrée pour continuer..."
read -rp "Appuyez sur Entrée pour continuer..."
}
# Menu principal
@@ -496,27 +763,34 @@ main_menu() {
echo "12) Cloner un conteneur"
echo "0) Quitter"
echo ""
read -p "Votre choix: " choice
local choice
read -rp "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;;
1) show_logo; list_containers; read -rp "Appuyez sur Entrée pour continuer...";;
2) create_container || true;;
3) start_container || true;;
4) stop_container || true;;
5) reboot_container || true;;
6) delete_container || true;;
7) unlock_container || true;;
8) backup_local || true;;
9) restore_backup || true;;
10) show_container_info || true;;
11) enter_container || true;;
12) clone_container || true;;
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
# Point d'entrée principal
main() {
check_proxmox
main_menu
}
# Lancement du script
main