Actualiser lxc-manager.sh

This commit is contained in:
Johnny 2025-12-31 08:43:51 +00:00
parent 85ff9f3c06
commit 00dbd3eb28
1 changed files with 429 additions and 34 deletions

View File

@ -226,17 +226,18 @@ create_container() {
break break
done done
# Stockage disponible # Stockage disponible pour le rootfs
echo -e "\n${BLUE}Stockages disponibles:${NC}" echo -e "\n${BLUE}Stockages disponibles pour le conteneur:${NC}"
mapfile -t storages_list < <(pvesm status | awk 'NR>1 {print $1}') mapfile -t storages_rootfs < <(pvesm status | awk 'NR>1 {print $1}')
if [[ ${#storages_list[@]} -eq 0 ]]; then if [[ ${#storages_rootfs[@]} -eq 0 ]]; then
error_exit "Aucun stockage disponible" error_exit "Aucun stockage disponible"
return 1 return 1
fi fi
for i in "${!storages_list[@]}"; do for i in "${!storages_rootfs[@]}"; do
echo "$((i+1))) ${storages_list[$i]}" local storage_info=$(pvesm status | grep "^${storages_rootfs[$i]}" | awk '{print $1" ("$3")"}')
echo "$((i+1))) $storage_info"
done done
echo "" echo ""
@ -244,30 +245,54 @@ create_container() {
read -rp "Choisir le stockage pour le conteneur (défaut: 1): " storage_choice read -rp "Choisir le stockage pour le conteneur (défaut: 1): " storage_choice
storage_choice=${storage_choice:-1} storage_choice=${storage_choice:-1}
if [[ ! "$storage_choice" =~ ^[0-9]+$ ]] || [[ $storage_choice -lt 1 ]] || [[ $storage_choice -gt ${#storages_list[@]} ]]; then if [[ ! "$storage_choice" =~ ^[0-9]+$ ]] || [[ $storage_choice -lt 1 ]] || [[ $storage_choice -gt ${#storages_rootfs[@]} ]]; then
error_exit "Choix invalide" error_exit "Choix invalide"
return 1 return 1
fi fi
local storage="${storages_list[$((storage_choice-1))]}" local storage="${storages_rootfs[$((storage_choice-1))]}"
# Template disponible # Trouver un stockage pour les templates (doit supporter les templates)
echo -e "\n${BLUE}Templates disponibles:${NC}" local template_storage="local"
pveam available | grep -i "system" | head -10 mapfile -t template_storages < <(pvesm status -content vztmpl 2>/dev/null | awk 'NR>1 {print $1}')
echo ""
local template if [[ ${#template_storages[@]} -gt 0 ]]; then
read -rp "Template à utiliser (ex: debian-12-standard): " template template_storage="${template_storages[0]}"
fi
if [[ -z "$template" ]]; then # Template disponible avec numérotation
error_exit "Le template ne peut pas être vide" echo -e "\n${BLUE}Templates disponibles sur '$template_storage':${NC}"
mapfile -t templates < <(pveam available | grep -i "system" | awk '{print $2}' | head -20)
if [[ ${#templates[@]} -eq 0 ]]; then
error_exit "Aucun template disponible"
return 1 return 1
fi fi
for i in "${!templates[@]}"; do
local template_name="${templates[$i]}"
# Extraire l'OS et la version
local os_name=$(echo "$template_name" | cut -d'-' -f1)
local os_version=$(echo "$template_name" | cut -d'-' -f2 | cut -d'_' -f1)
echo "$((i+1))) $os_name $os_version - $template_name"
done
echo ""
local template_choice
read -rp "Choisir le template (défaut: 1): " template_choice
template_choice=${template_choice:-1}
if [[ ! "$template_choice" =~ ^[0-9]+$ ]] || [[ $template_choice -lt 1 ]] || [[ $template_choice -gt ${#templates[@]} ]]; then
error_exit "Choix invalide"
return 1
fi
local template="${templates[$((template_choice-1))]}"
# Si le template n'est pas téléchargé # Si le template n'est pas téléchargé
if ! pveam list "$storage" | grep -q "$template"; then if ! pveam list "$template_storage" | grep -q "$template"; then
echo -e "${YELLOW}Téléchargement du template...${NC}" echo -e "${YELLOW}Téléchargement du template sur '$template_storage'...${NC}"
pveam download "$storage" "$template" || { pveam download "$template_storage" "$template" || {
error_exit "Échec du téléchargement du template" error_exit "Échec du téléchargement du template"
return 1 return 1
} }
@ -355,6 +380,64 @@ create_container() {
net_config="name=eth0,bridge=${bridge},ip=dhcp" net_config="name=eth0,bridge=${bridge},ip=dhcp"
fi fi
# Mode privilégié ou non
echo -e "\n${BLUE}Mode du conteneur:${NC}"
echo "1) Unprivileged (recommandé, plus sécurisé)"
echo "2) Privileged (accès root complet)"
local priv_choice unprivileged
read -rp "Choix (défaut: 1): " priv_choice
priv_choice=${priv_choice:-1}
if [[ "$priv_choice" == "2" ]]; then
unprivileged="0"
echo -e "${YELLOW}⚠ Mode privileged sélectionné${NC}"
else
unprivileged="1"
fi
# Fonctionnalités avancées (nesting, fuse, etc.)
echo -e "\n${BLUE}Fonctionnalités avancées:${NC}"
local features=""
read -rp "Activer nesting (Docker dans LXC)? (o/n, défaut: n): " enable_nesting
if [[ "$enable_nesting" == "o" ]]; then
features="${features}nesting=1,"
fi
read -rp "Activer FUSE (systèmes de fichiers utilisateur)? (o/n, défaut: n): " enable_fuse
if [[ "$enable_fuse" == "o" ]]; then
features="${features}fuse=1,"
fi
local mount_list=""
read -rp "Activer NFS (montage NFS)? (o/n, défaut: n): " enable_nfs
if [[ "$enable_nfs" == "o" ]]; then
mount_list="${mount_list}nfs;"
fi
read -rp "Activer SMB/CIFS (montage Windows)? (o/n, défaut: n): " enable_cifs
if [[ "$enable_cifs" == "o" ]]; then
mount_list="${mount_list}cifs;"
fi
# Retirer le séparateur final
mount_list="${mount_list%;}"
# Ajouter mount aux features si nécessaire
if [[ -n "$mount_list" ]]; then
features="${features}mount=${mount_list},"
fi
# Retirer la virgule finale
features="${features%,}"
local features_param=""
if [[ -n "$features" ]]; then
features_param="--features $features"
fi
# Démarrage automatique # Démarrage automatique
local autostart onboot local autostart onboot
read -rp "Démarrage automatique? (o/n, défaut: n): " autostart read -rp "Démarrage automatique? (o/n, défaut: n): " autostart
@ -370,7 +453,7 @@ create_container() {
# 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}"
if pct create "$vmid" "${storage}:vztmpl/${template}" \ if pct create "$vmid" "${template_storage}:vztmpl/${template}" \
--hostname "$hostname" \ --hostname "$hostname" \
--password "$password" \ --password "$password" \
--memory "$memory" \ --memory "$memory" \
@ -379,7 +462,8 @@ create_container() {
--cores "$cores" \ --cores "$cores" \
--net0 "$net_config" \ --net0 "$net_config" \
--onboot "$onboot" \ --onboot "$onboot" \
--unprivileged 1 \ --unprivileged "$unprivileged" \
$features_param \
$protection_flag; then $protection_flag; then
echo -e "${GREEN}✓ Conteneur $vmid créé avec succès!${NC}" echo -e "${GREEN}✓ Conteneur $vmid créé avec succès!${NC}"
@ -1052,6 +1136,314 @@ clone_container() {
read -rp "Appuyez sur Entrée pour continuer..." read -rp "Appuyez sur Entrée pour continuer..."
} }
# Fonction pour modifier les options d'un conteneur
modify_container_options() {
show_logo
list_containers
local vmid
read -rp "Numéro du conteneur à modifier: " 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
# Vérifier si le conteneur est arrêté
if pct status "$vmid" | grep -q "running"; then
echo -e "${YELLOW}⚠ Le conteneur est en cours d'exécution${NC}"
echo -e "${YELLOW}Certaines modifications nécessitent un redémarrage${NC}\n"
fi
# Afficher les options actuelles
echo -e "\n${BLUE}Configuration actuelle:${NC}"
local current_config=$(pct config "$vmid" | grep -E "^(features|mount):")
echo -e "${GREEN}${current_config:-Aucune fonctionnalité activée}${NC}"
echo ""
# Extraire les options actuelles depuis features
local current_features=$(pct config "$vmid" | grep "^features:" | cut -d' ' -f2-)
local current_nesting="0"
local current_fuse="0"
local current_nfs="0"
local current_cifs="0"
[[ "$current_features" =~ nesting=1 ]] && current_nesting="1"
[[ "$current_features" =~ fuse=1 ]] && current_fuse="1"
[[ "$current_features" =~ mount=.*nfs ]] && current_nfs="1"
[[ "$current_features" =~ mount=.*cifs ]] && current_cifs="1"
echo -e "${BLUE}Modification des fonctionnalités avancées:${NC}\n"
# Nesting
echo -e "Nesting (Docker dans LXC) - Actuellement: $([ "$current_nesting" == "1" ] && echo -e "${GREEN}activé${NC}" || echo -e "${YELLOW}désactivé${NC}")"
read -rp "Modifier? (o/activer, n/désactiver, Entrée/garder): " mod_nesting
case $mod_nesting in
o) current_nesting="1";;
n) current_nesting="0";;
esac
# FUSE
echo -e "FUSE (systèmes de fichiers utilisateur) - Actuellement: $([ "$current_fuse" == "1" ] && echo -e "${GREEN}activé${NC}" || echo -e "${YELLOW}désactivé${NC}")"
read -rp "Modifier? (o/activer, n/désactiver, Entrée/garder): " mod_fuse
case $mod_fuse in
o) current_fuse="1";;
n) current_fuse="0";;
esac
# NFS
echo -e "NFS (montage NFS) - Actuellement: $([ "$current_nfs" == "1" ] && echo -e "${GREEN}activé${NC}" || echo -e "${YELLOW}désactivé${NC}")"
read -rp "Modifier? (o/activer, n/désactiver, Entrée/garder): " mod_nfs
case $mod_nfs in
o) current_nfs="1";;
n) current_nfs="0";;
esac
# CIFS
echo -e "SMB/CIFS (montage Windows) - Actuellement: $([ "$current_cifs" == "1" ] && echo -e "${GREEN}activé${NC}" || echo -e "${YELLOW}désactivé${NC}")"
read -rp "Modifier? (o/activer, n/désactiver, Entrée/garder): " mod_cifs
case $mod_cifs in
o) current_cifs="1";;
n) current_cifs="0";;
esac
# Construire la chaîne de fonctionnalités complète
local new_features=""
# Ajouter nesting et fuse
[[ "$current_nesting" == "1" ]] && new_features="${new_features}nesting=1,"
[[ "$current_fuse" == "1" ]] && new_features="${new_features}fuse=1,"
# Ajouter mount si nécessaire
local mount_list=""
[[ "$current_nfs" == "1" ]] && mount_list="${mount_list}nfs;"
[[ "$current_cifs" == "1" ]] && mount_list="${mount_list}cifs;"
mount_list="${mount_list%;}"
if [[ -n "$mount_list" ]]; then
new_features="${new_features}mount=${mount_list},"
fi
# Retirer la virgule finale
new_features="${new_features%,}"
# Appliquer les modifications
echo -e "\n${YELLOW}Application des modifications...${NC}"
if [[ -n "$new_features" ]]; then
if pct set "$vmid" --features "$new_features"; then
echo -e "${GREEN}✓ Configuration mise à jour${NC}"
echo -e "${BLUE}Nouvelles options: $new_features${NC}"
else
error_exit "Échec de la mise à jour"
return 1
fi
else
if pct set "$vmid" --delete features 2>/dev/null; then
echo -e "${GREEN}✓ Toutes les fonctionnalités ont été désactivées${NC}"
else
echo -e "${YELLOW}Note: Aucune fonctionnalité à désactiver${NC}"
fi
fi
# Demander si un redémarrage est nécessaire
if pct status "$vmid" | grep -q "running"; then
echo -e "\n${YELLOW}Le conteneur doit être redémarré pour que les changements prennent effet${NC}"
read -rp "Redémarrer maintenant? (o/n): " restart_choice
if [[ "$restart_choice" == "o" ]]; then
pct reboot "$vmid" && echo -e "${GREEN}✓ Conteneur redémarré${NC}"
fi
fi
read -rp "Appuyez sur Entrée pour continuer..."
}
# Fonction pour supprimer des sauvegardes
delete_backups() {
show_logo
echo -e "${GREEN}Suppression de sauvegardes${NC}\n"
# Lister tous les conteneurs
list_containers
local vmid
read -rp "Numéro du conteneur (ou Entrée pour toutes les sauvegardes): " vmid
if [[ -n "$vmid" ]] && ! validate_vmid "$vmid"; then
error_exit "VMID invalide"
return 1
fi
# Lister tous les stockages disponibles
echo -e "\n${BLUE}Stockages disponibles:${NC}"
mapfile -t storages < <(pvesm status | awk 'NR>1 {print $1}')
if [[ ${#storages[@]} -eq 0 ]]; then
error_exit "Aucun stockage disponible"
return 1
fi
for i in "${!storages[@]}"; do
echo "$((i+1))) ${storages[$i]}"
done
echo ""
# Sélection du stockage
local storage_choice
read -rp "Choisir le stockage contenant les sauvegardes (défaut: 1): " storage_choice
storage_choice=${storage_choice:-1}
if [[ ! "$storage_choice" =~ ^[0-9]+$ ]] || [[ $storage_choice -lt 1 ]] || [[ $storage_choice -gt ${#storages[@]} ]]; then
error_exit "Choix invalide"
return 1
fi
local selected_storage="${storages[$((storage_choice-1))]}"
# Lister les sauvegardes
echo -e "\n${BLUE}Sauvegardes disponibles sur '$selected_storage':${NC}"
local filter=""
if [[ -n "$vmid" ]]; then
filter="vzdump-lxc-${vmid}-"
echo -e "${YELLOW}Filtrage pour le conteneur $vmid${NC}\n"
fi
mapfile -t backups < <(pvesm list "$selected_storage" | grep "vzdump" | grep "$filter" | awk '{print $1}' | sed "s/^${selected_storage}://")
if [[ ${#backups[@]} -eq 0 ]]; then
error_exit "Aucune sauvegarde trouvée"
return 1
fi
# Afficher les sauvegardes avec numéros
for i in "${!backups[@]}"; do
local backup_name="${backups[$i]}"
local filename=$(basename "$backup_name")
local vmid_backup=$(echo "$filename" | grep -oP 'vzdump-lxc-\K[0-9]+' || echo "N/A")
local date_backup=$(echo "$filename" | grep -oP '\d{4}_\d{2}_\d{2}-\d{2}_\d{2}_\d{2}' || echo "")
local size_backup=$(pvesm list "$selected_storage" | grep "$filename" | awk '{print $3}')
echo -e "$((i+1))) ${MAGENTA}VMID:${NC} $vmid_backup ${MAGENTA}Date:${NC} $date_backup ${MAGENTA}Taille:${NC} $size_backup"
echo -e " ${BLUE}Fichier:${NC} $filename"
echo ""
done
# Sélection des sauvegardes à supprimer
echo -e "${YELLOW}Options de sélection:${NC}"
echo "- Un numéro: 3"
echo "- Plusieurs numéros séparés par des espaces: 1 3 5"
echo "- Une plage: 1-3"
echo "- Combinaison: 1 3-5 7"
echo "- 'all' pour tout supprimer"
echo ""
local selection
read -rp "Sélection: " selection
if [[ -z "$selection" ]]; then
echo -e "${YELLOW}Aucune sélection, opération annulée${NC}"
read -rp "Appuyez sur Entrée pour continuer..."
return
fi
# Parser la sélection
local -a selected_indices=()
if [[ "$selection" == "all" ]]; then
for i in "${!backups[@]}"; do
selected_indices+=($i)
done
else
for part in $selection; do
if [[ "$part" =~ ^([0-9]+)-([0-9]+)$ ]]; then
# Plage
local start=${BASH_REMATCH[1]}
local end=${BASH_REMATCH[2]}
for ((j=start; j<=end; j++)); do
if [[ $j -ge 1 ]] && [[ $j -le ${#backups[@]} ]]; then
selected_indices+=($((j-1)))
fi
done
elif [[ "$part" =~ ^[0-9]+$ ]]; then
# Numéro simple
if [[ $part -ge 1 ]] && [[ $part -le ${#backups[@]} ]]; then
selected_indices+=($((part-1)))
fi
fi
done
fi
if [[ ${#selected_indices[@]} -eq 0 ]]; then
error_exit "Aucune sauvegarde valide sélectionnée"
return 1
fi
# Afficher les sauvegardes sélectionnées
echo -e "\n${RED}⚠ Sauvegardes sélectionnées pour suppression:${NC}"
local total_size=0
for idx in "${selected_indices[@]}"; do
local backup_name="${backups[$idx]}"
local filename=$(basename "$backup_name")
echo -e "${RED} - $filename${NC}"
done
echo ""
# Confirmation
if [[ "$PROTECTION_ENABLED" == true ]]; then
read -rp "Tapez exactement 'SUPPRIMER' pour confirmer: " confirm
if [[ "$confirm" != "SUPPRIMER" ]]; then
echo -e "${YELLOW}Suppression annulée${NC}"
read -rp "Appuyez sur Entrée pour continuer..."
return
fi
else
read -rp "Confirmer la suppression? (o/n): " confirm
if [[ "$confirm" != "o" ]]; then
echo -e "${YELLOW}Suppression annulée${NC}"
read -rp "Appuyez sur Entrée pour continuer..."
return
fi
fi
# Suppression des sauvegardes
echo -e "\n${YELLOW}Suppression en cours...${NC}\n"
local success_count=0
local fail_count=0
for idx in "${selected_indices[@]}"; do
local backup_path="${backups[$idx]}"
local filename=$(basename "$backup_path")
echo -e "${BLUE}Suppression de: $filename${NC}"
if pvesm free "${selected_storage}:${backup_path}"; then
echo -e "${GREEN}✓ Supprimé${NC}\n"
((success_count++))
else
echo -e "${RED}✗ Échec${NC}\n"
((fail_count++))
fi
done
# Résumé
echo -e "${BLUE}═══════════════════════════════════════════════${NC}"
echo -e "${GREEN}✓ Supprimées avec succès: $success_count${NC}"
if [[ $fail_count -gt 0 ]]; then
echo -e "${RED}✗ Échecs: $fail_count${NC}"
fi
echo -e "${BLUE}═══════════════════════════════════════════════${NC}"
read -rp "Appuyez sur Entrée pour continuer..."
}
# Fonction pour basculer le mode protection global # Fonction pour basculer le mode protection global
toggle_global_protection() { toggle_global_protection() {
show_logo show_logo
@ -1097,14 +1489,16 @@ main_menu() {
echo "7) Déverrouiller un conteneur" echo "7) Déverrouiller un conteneur"
echo "8) Sauvegarder un conteneur" echo "8) Sauvegarder un conteneur"
echo "9) Restaurer une sauvegarde" echo "9) Restaurer une sauvegarde"
echo "10) Afficher les informations" echo "10) Supprimer des sauvegardes"
echo "11) Entrer dans un conteneur" echo "11) Afficher les informations"
echo "12) Cloner un conteneur" echo "12) Entrer dans un conteneur"
echo -e "13) ${MAGENTA}Gérer la protection d'un conteneur${NC}" echo "13) Cloner un conteneur"
echo -e "14) ${MAGENTA}Modifier les options (nesting/fuse/nfs/cifs)${NC}"
echo -e "15) ${MAGENTA}Gérer la protection d'un conteneur${NC}"
if [[ "$PROTECTION_ENABLED" == true ]]; then if [[ "$PROTECTION_ENABLED" == true ]]; then
echo -e "14) ${MAGENTA}Mode protection global (ACTIVÉ)${NC}" echo -e "16) ${MAGENTA}Mode protection global (ACTIVÉ)${NC}"
else else
echo -e "14) ${MAGENTA}Mode protection global (DÉSACTIVÉ)${NC}" echo -e "16) ${MAGENTA}Mode protection global (DÉSACTIVÉ)${NC}"
fi fi
echo "0) Quitter" echo "0) Quitter"
echo "" echo ""
@ -1122,11 +1516,13 @@ main_menu() {
7) unlock_container || true;; 7) unlock_container || true;;
8) backup_local || true;; 8) backup_local || true;;
9) restore_backup || true;; 9) restore_backup || true;;
10) show_container_info || true;; 10) delete_backups || true;;
11) enter_container || true;; 11) show_container_info || true;;
12) clone_container || true;; 12) enter_container || true;;
13) toggle_protection || true;; 13) clone_container || true;;
14) toggle_global_protection || true;; 14) modify_container_options || true;;
15) toggle_protection || true;;
16) toggle_global_protection || 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
@ -1139,5 +1535,4 @@ main() {
main_menu main_menu
} }
# Lancement du script # Lancement du script
main