Actualiser lxc_manager.sh
This commit is contained in:
642
lxc_manager.sh
642
lxc_manager.sh
@@ -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
|
||||
|
||||
# Mot de passe root
|
||||
read -sp "Mot de passe root: " password
|
||||
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 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
|
||||
# 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
|
||||
|
||||
# Ressources avec validation
|
||||
local memory
|
||||
while true; do
|
||||
read -rp "RAM en MB (défaut: 512): " memory
|
||||
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}
|
||||
|
||||
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}
|
||||
|
||||
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}
|
||||
|
||||
# Bridge réseau
|
||||
read -p "Bridge réseau (défaut: vmbr0): " bridge
|
||||
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
|
||||
--memory "$memory" \
|
||||
--swap "$swap" \
|
||||
--rootfs "${storage}:${disk}" \
|
||||
--cores "$cores" \
|
||||
--net0 "$net_config" \
|
||||
--onboot "$onboot" \
|
||||
--unprivileged 1; then
|
||||
|
||||
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}"
|
||||
|
||||
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..."
|
||||
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 ! 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}"
|
||||
read -p "Appuyez sur Entrée pour continuer..."
|
||||
return
|
||||
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
|
||||
|
||||
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}"
|
||||
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
|
||||
# Point d'entrée principal
|
||||
main() {
|
||||
check_proxmox
|
||||
main_menu
|
||||
}
|
||||
|
||||
# Lancement du script
|
||||
main
|
||||
Reference in New Issue
Block a user