From 3048a2ab6a65e5c19bff65708d7d91ce7a08414e Mon Sep 17 00:00:00 2001 From: patrick Date: Sat, 21 Jun 2025 01:29:03 +0200 Subject: [PATCH] pve-kernel-cleaner.sh aktualisiert --- pve-kernel-cleaner.sh | 287 +++++++++++++++++++++++++++++++----------- 1 file changed, 215 insertions(+), 72 deletions(-) diff --git a/pve-kernel-cleaner.sh b/pve-kernel-cleaner.sh index 559c736..9e207ea 100644 --- a/pve-kernel-cleaner.sh +++ b/pve-kernel-cleaner.sh @@ -6,88 +6,231 @@ # Autor: Patrick Perlbach # Datum: 2025-06-20 -set -e +# Farben & Formatierung +bold=$(tput bold) +reset=$(tput sgr0) +green=$(tput setaf 2) +yellow=$(tput setaf 3) +red=$(tput setaf 1) -echo "==== PVE Kernel Cleaner ====" -echo "" +# Einstellungen +ZFS_DATASET="rpool/ROOT/pve-1" # ZFS Dataset für Boot-Pool +SNAPSHOT_TAG="pve-kernel-cleaner" # Tag für Snapshots +MAX_SNAPSHOTS=5 # Max. Snapshots behalten +LOGFILE="/var/log/pve-kernel-cleaner.log" # Logdatei +TIMESTAMP=$(date +%Y-%m-%d-%H-%M-%S) # Zeitstempel für Snapshots +dry_run="false" # Standard: kein Testlauf -# 1. Prüfen ob EFI oder BIOS -if [ -d /sys/firmware/efi ]; then - echo "Bootmodus: EFI" -else - echo "Bootmodus: BIOS (Legacy)" -fi +# Hilfe anzeigen +show_help() { + cat << EOF +Verwendung: $(basename "$0") [OPTIONEN] -# 1.1 Subscription-Status prüfen -echo "" -echo "APT-Repositories:" -repo_files=$(find /etc/apt/ -name "*.list") +Dieses Script entfernt alte Proxmox Kernel und behält eine definierte Anzahl neuer Kernel. -if grep -rq "enterprise.proxmox.com" $repo_files; then - echo "PVE Enterprise Repository (Subscription) ist aktiv" -elif grep -rq "no-subscription" $repo_files; then - echo "PVE No-Subscription Repository ist aktiv" -else - echo "Kein bekanntes PVE Repository aktiv, prüfe apt-Sources manuell" -fi +Optionen: + -k NUM Anzahl der Kernel, die behalten werden sollen (Standard: 1) + -d Testmodus (Dry-Run), keine Änderungen werden vorgenommen + -h Diese Hilfe anzeigen +EOF +} -echo "" +# Systeminformationen anzeigen +kernel_info() { + echo "=== PVE Kernel Cleaner Script ===" + echo "" + echo "Systeminformationen:" + echo "─────────────────────────────" -# 2. ZFS Pools prüfen -echo "ZFS Pool Übersicht:" -if command -v zpool &> /dev/null; then - zpool list -Ho name,capacity | while read -r pool cap; do - cap_num=$(echo $cap | tr -d '%') - warn="" - if (( cap_num >= 80 )); then - warn="ACHTUNG: >80% belegt" - fi - echo " → $pool: $cap $warn" - done -else - echo "ZFS ist nicht installiert oder zpool-Befehl nicht verfügbar." -fi + current_kernel=$(uname -r) + kernels_installed=($(dpkg --list | awk '/proxmox-kernel-.*-pve-signed/ {print $2}' | sort -V)) + num_kernels=${#kernels_installed[@]} -echo "" - -# 3. Liste der installierten PVE-Kernel anzeigen und alte Kernel identifizieren -echo "Installierte PVE-Kernel:" -kernel_list=$(dpkg --list | grep pve-kernel | awk '{print $2}' | sort -V) -current_kernel=$(uname -r | cut -d '-' -f1-2) - -to_remove=() - -while read -r kernel; do - version=$(echo "$kernel" | sed -n 's/^pve-kernel-\([0-9.]*-[0-9]*\).*/\1/p') - if [ "$version" == "$current_kernel" ]; then - echo " * $kernel (aktuell in Verwendung)" + if [ -d /sys/firmware/efi ]; then + echo "Boot-Modus: EFI" else - echo " - $kernel (alt)" - to_remove+=("$kernel") + echo "Boot-Modus: Legacy (BIOS)" fi -done <<< "$kernel_list" -echo "" -if [ ${#to_remove[@]} -eq 0 ]; then - echo "Keine alten Kernel gefunden, nichts zu tun." - exit 0 -fi + if [ -f /etc/os-release ]; then + os_name=$(grep PRETTY_NAME /etc/os-release | cut -d= -f2 | tr -d '"') + echo "Betriebssystem: $os_name" + fi -# 4. Nutzerabfrage zur Entfernung -echo "Die folgenden alten Kernel könnten entfernt werden:" -for k in "${to_remove[@]}"; do - echo " - $k" -done + if zfs list $ZFS_DATASET &>/dev/null; then + boot_used=$(zfs get -H -o value used $ZFS_DATASET) + boot_avail=$(zfs get -H -o value available $ZFS_DATASET) + echo "ZFS Boot-Pool ($ZFS_DATASET): benutzt $boot_used, verfügbar $boot_avail" + else + boot_df=($(df -h /boot | tail -1)) + echo "Boot-Partition: ${boot_df[2]} verwendet von ${boot_df[1]} verfügbar (${boot_df[4]} voll)" + fi -echo "" -read -p "Möchtest du diese alten Kernel jetzt entfernen? (j/n): " confirm -if [[ "$confirm" =~ ^[Jj]$ ]]; then - echo "Entferne alte Kernel..." - apt remove --purge -y "${to_remove[@]}" - echo "Alte Kernel wurden entfernt." -else - echo "Abbruch, keine Kernel wurden entfernt." -fi + echo "Aktueller Kernel: $current_kernel" + echo "Installierte Proxmox-Kernel ($num_kernels):" + for k in "${kernels_installed[@]}"; do + echo " - $k" + done + echo "─────────────────────────────" + echo "" +} -echo "" -echo "==== Fertig ====" \ No newline at end of file +# Prüfe Subscription-Status der APT-Repositories +check_apt_repos() { + echo "APT-Repositories:" + repo_files=$(find /etc/apt/ -name "*.list") + + if grep -rq "enterprise.proxmox.com" $repo_files; then + echo "PVE Enterprise Repository (Subscription) ist aktiv" + elif grep -rq "no-subscription" $repo_files; then + echo "PVE No-Subscription Repository ist aktiv" + else + echo "Kein bekanntes PVE Repository aktiv, prüfe apt-Sources manuell" + fi + echo "" +} + +# Snapshot erstellen, falls ZFS vorhanden +create_snapshot() { + if zfs list $ZFS_DATASET &>/dev/null; then + snapshot_name="${ZFS_DATASET}@${SNAPSHOT_TAG}-${TIMESTAMP}" + echo "Erstelle ZFS Snapshot: $snapshot_name" + if [ "$dry_run" = "false" ]; then + zfs snapshot "$snapshot_name" || echo "${red}Snapshot konnte nicht erstellt werden!${reset}" + else + echo "Snapshot würde erstellt: $snapshot_name" + fi + fi +} + +# Alte Snapshots löschen, wenn zu viele vorhanden sind +cleanup_snapshots() { + if zfs list $ZFS_DATASET &>/dev/null; then + snapshots=($(zfs list -t snapshot -o name -s creation | grep "$SNAPSHOT_TAG" | grep "^${ZFS_DATASET}@${SNAPSHOT_TAG}" || true)) + num_snapshots=${#snapshots[@]} + if (( num_snapshots > MAX_SNAPSHOTS )); then + delete_count=$((num_snapshots - MAX_SNAPSHOTS)) + echo "Es sind $num_snapshots Snapshots mit Tag '$SNAPSHOT_TAG' vorhanden. Entferne $delete_count alte Snapshot(s)." + for ((i=0; i /dev/null 2>&1 + if [ $? -eq 0 ]; then + printf "${green}Fertig!${reset}\n" + else + printf "${red}Fehler!${reset}\n" + fi + else + echo "Kernel würde entfernt: $k" + fi + done + + # Grub aktualisieren + printf "${bold}[*]${reset} Aktualisiere GRUB... " + if [ "$dry_run" = "false" ]; then + if command -v proxmox-boot-tool >/dev/null 2>&1; then + proxmox-boot-tool refresh > /dev/null 2>&1 + else + update-grub > /dev/null 2>&1 + fi + printf "${green}Fertig!${reset}\n" + else + echo "GRUB würde aktualisiert werden." + fi + + # Alte Snapshots bereinigen + cleanup_snapshots +} + +main() { + local keep=1 + + # Optionen parsen + while getopts ":k:dh" opt; do + case $opt in + k) keep=$OPTARG ;; + d) dry_run="true" ;; + h) show_help; exit 0 ;; + \?) echo "Ungültige Option: -$OPTARG" >&2; show_help; exit 1 ;; + :) echo "Option -$OPTARG benötigt ein Argument." >&2; show_help; exit 1 ;; + esac + done + + kernel_info + check_apt_repos + + echo "[-] PVE kernel search complete!" + echo "" + + # Kernel-Keeping abfragen + read -rp "Wie viele Kernel sollen behalten werden? [Standard: $keep]: " user_keep + if [[ "$user_keep" =~ ^[0-9]+$ ]]; then + keep=$user_keep + fi + + remove_old_kernels "$keep" + + # Anzahl Snapshots am Ende anzeigen + if zfs list $ZFS_DATASET &>/dev/null; then + snapshots=($(zfs list -t snapshot -o name -s creation | grep "$SNAPSHOT_TAG" | grep "^${ZFS_DATASET}@${SNAPSHOT_TAG}" || true)) + num_snapshots=${#snapshots[@]} + echo "" + echo "Anzahl vorhandener Snapshots mit Tag '$SNAPSHOT_TAG': $num_snapshots" + fi + + echo "" + echo "Fertig." +} + +main "$@"