pve-kernel-cleaner.sh aktualisiert
This commit is contained in:
+195
-52
@@ -6,20 +6,77 @@
|
||||
# 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 ===="
|
||||
# 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
|
||||
|
||||
# Hilfe anzeigen
|
||||
show_help() {
|
||||
cat << EOF
|
||||
Verwendung: $(basename "$0") [OPTIONEN]
|
||||
|
||||
Dieses Script entfernt alte Proxmox Kernel und behält eine definierte Anzahl neuer Kernel.
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
# Systeminformationen anzeigen
|
||||
kernel_info() {
|
||||
echo "=== PVE Kernel Cleaner Script ==="
|
||||
echo ""
|
||||
echo "Systeminformationen:"
|
||||
echo "─────────────────────────────"
|
||||
|
||||
current_kernel=$(uname -r)
|
||||
kernels_installed=($(dpkg --list | awk '/proxmox-kernel-.*-pve-signed/ {print $2}' | sort -V))
|
||||
num_kernels=${#kernels_installed[@]}
|
||||
|
||||
# 1. Prüfen ob EFI oder BIOS
|
||||
if [ -d /sys/firmware/efi ]; then
|
||||
echo "Bootmodus: EFI"
|
||||
echo "Boot-Modus: EFI"
|
||||
else
|
||||
echo "Bootmodus: BIOS (Legacy)"
|
||||
echo "Boot-Modus: Legacy (BIOS)"
|
||||
fi
|
||||
|
||||
# 1.1 Subscription-Status prüfen
|
||||
if [ -f /etc/os-release ]; then
|
||||
os_name=$(grep PRETTY_NAME /etc/os-release | cut -d= -f2 | tr -d '"')
|
||||
echo "Betriebssystem: $os_name"
|
||||
fi
|
||||
|
||||
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 "Aktueller Kernel: $current_kernel"
|
||||
echo "Installierte Proxmox-Kernel ($num_kernels):"
|
||||
for k in "${kernels_installed[@]}"; do
|
||||
echo " - $k"
|
||||
done
|
||||
echo "─────────────────────────────"
|
||||
echo ""
|
||||
}
|
||||
|
||||
# Prüfe Subscription-Status der APT-Repositories
|
||||
check_apt_repos() {
|
||||
echo "APT-Repositories:"
|
||||
repo_files=$(find /etc/apt/ -name "*.list")
|
||||
|
||||
@@ -30,64 +87,150 @@ elif grep -rq "no-subscription" $repo_files; then
|
||||
else
|
||||
echo "Kein bekanntes PVE Repository aktiv, prüfe apt-Sources manuell"
|
||||
fi
|
||||
|
||||
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"
|
||||
# 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<delete_count; i++)); do
|
||||
snap_to_delete=${snapshots[i]}
|
||||
echo "Lösche Snapshot: $snap_to_delete"
|
||||
if [ "$dry_run" = "false" ]; then
|
||||
zfs destroy "$snap_to_delete" || echo "${red}Snapshot $snap_to_delete konnte nicht gelöscht werden!${reset}"
|
||||
else
|
||||
echo "Snapshot würde gelöscht: $snap_to_delete"
|
||||
fi
|
||||
echo " → $pool: $cap $warn"
|
||||
done
|
||||
else
|
||||
echo "ZFS ist nicht installiert oder zpool-Befehl nicht verfügbar."
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
# Alte Kernel entfernen
|
||||
remove_old_kernels() {
|
||||
local keep=$1
|
||||
echo "Es werden alle außer den $keep neuesten Kernel entfernt..."
|
||||
|
||||
# Nur pve-signed Kernel-Pakete auflisten, sortiert
|
||||
mapfile -t kernels < <(dpkg --list | awk '/proxmox-kernel-.*-pve-signed/ {print $2}' | sort -V)
|
||||
local total=${#kernels[@]}
|
||||
|
||||
echo "Gefundene Kernel: $total"
|
||||
|
||||
if (( total <= keep )); then
|
||||
echo "Es gibt nicht mehr Kernel als die zu behaltenden ($keep). Kein Kernel wird entfernt."
|
||||
return
|
||||
fi
|
||||
|
||||
echo ""
|
||||
# Kernel die entfernt werden sollen
|
||||
to_remove=("${kernels[@]:0:total-keep}")
|
||||
num_to_remove=${#to_remove[@]}
|
||||
|
||||
# 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)"
|
||||
else
|
||||
echo " - $kernel (alt)"
|
||||
to_remove+=("$kernel")
|
||||
fi
|
||||
done <<< "$kernel_list"
|
||||
|
||||
echo ""
|
||||
if [ ${#to_remove[@]} -eq 0 ]; then
|
||||
echo "Keine alten Kernel gefunden, nichts zu tun."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# 4. Nutzerabfrage zur Entfernung
|
||||
echo "Die folgenden alten Kernel könnten entfernt werden:"
|
||||
echo "Folgende Kernel werden entfernt:"
|
||||
for k in "${to_remove[@]}"; do
|
||||
echo " - $k"
|
||||
done
|
||||
|
||||
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."
|
||||
# Nutzer fragt, ob er entfernen will
|
||||
printf "${bold}[!]${reset} Möchten Sie die ${bold}$num_to_remove${reset} ausgewählten PVE Kernel entfernen? [y/N]: "
|
||||
read -n 1 -r
|
||||
printf "\n"
|
||||
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
|
||||
echo "Abbruch durch Benutzer."
|
||||
return
|
||||
fi
|
||||
|
||||
# ZFS Snapshot vor dem Löschen
|
||||
create_snapshot
|
||||
|
||||
# Kernel entfernen
|
||||
for k in "${to_remove[@]}"; do
|
||||
printf "${bold}[-]${reset} Entferne Kernel-Paket: $k ... "
|
||||
if [ "$dry_run" = "false" ]; then
|
||||
apt-get purge -y "$k" > /dev/null 2>&1
|
||||
if [ $? -eq 0 ]; then
|
||||
printf "${green}Fertig!${reset}\n"
|
||||
else
|
||||
echo "Abbruch, keine Kernel wurden entfernt."
|
||||
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 ===="
|
||||
echo "Fertig."
|
||||
}
|
||||
|
||||
main "$@"
|
||||
|
||||
Reference in New Issue
Block a user