fstrim-lxc/fstrim-lxc.v1.sh
2025-10-31 15:40:45 +01:00

179 lines
4.1 KiB
Bash

#!/usr/bin/env bash
# Beschreibung: Führt fstrim in LXC-Containern auf einem Proxmox-Host aus
# Aufrufbeispiele:
# ./fstrim-lxc.sh --all #Alle LXCs
# ./fstrim-lxc.sh -i 102,103 #Gewünschte IDs
# ./fstrim-lxc.sh #Interaktiver Modus mit Auswahlmenü
# Synapse: https://git.techniverse.net/scriptos/fstrim-lxc.git
# Autor: Patrick Asmus
# Web: https://www.cleveradmin.de
# Version: 1.0
# Datum: 31.10.2025
# Modifikation: Initial
#####################################################
set -euo pipefail
# --- Einstellungen ---
DEFAULT_TIMEOUT=60 # Sekunden; je pct fstrim-Aufruf
# ---------------------
log() { echo "[$(date +'%F %T')] $*"; }
have() { command -v "$1" >/dev/null 2>&1; }
usage() {
cat <<'EOF'
Verwendung:
fstrim-lxc.pct.v1.sh -all [--timeout SECONDS]
-> pct fstrim auf allen laufenden LXC-Containern ausführen
fstrim-lxc.pct.v1.sh -i 102,103 [--timeout SECONDS]
fstrim-lxc.pct.v1.sh -102,103 [--timeout SECONDS]
-> pct fstrim nur auf diesen IDs ausführen
fstrim-lxc.pct.v1.sh
-> Interaktives Menü
Optionen:
--timeout N : Timeout pro Container (Sekunden), Default 60
-h | --help : Hilfe
Hinweise:
- Gestoppte Container werden übersprungen (kein Auto-Start).
- Benötigt root und das Proxmox-Tool "pct".
EOF
}
require_root() {
if [[ $EUID -ne 0 ]]; then
echo "Bitte als root ausführen." >&2
exit 1
fi
}
list_all_ids() {
pct list | awk 'NR>1 {print $1}'
}
exists_id() {
local id="$1"
list_all_ids | grep -qx "$id"
}
is_running() {
local id="$1"
pct status "$id" 2>/dev/null | grep -q "status: running"
}
do_fstrim() {
local id="$1"
local timeout_s="$2"
if ! exists_id "$id"; then
log "[ID $id] existiert nicht. Übersprungen."
return 1
fi
if ! is_running "$id"; then
log "[ID $id] gestoppt. Übersprungen (kein Auto-Start)."
return 2
fi
if ! have pct; then
log "Fehler: pct nicht gefunden."
return 3
fi
log "[ID $id] pct fstrim (Timeout ${timeout_s}s)..."
if timeout "$timeout_s" pct fstrim "$id"; then
log "[ID $id] OK."
return 0
else
log "[ID $id] Fehler oder Timeout."
return 4
fi
}
run_for_ids() {
local ids_csv="$1"
local timeout_s="$2"
ids_csv="${ids_csv//[[:space:]]/}"
IFS=',' read -r -a ids <<< "$ids_csv"
[[ ${#ids[@]} -gt 0 ]] || { echo "Keine gültigen IDs."; exit 1; }
local rc=0
for id in "${ids[@]}"; do
if [[ ! "$id" =~ ^[0-9]+$ ]]; then
log "[$id] keine numerische ID. Übersprungen."
rc=1
continue
fi
do_fstrim "$id" "$timeout_s" || rc=1
done
return $rc
}
run_for_all() {
local timeout_s="$1"
mapfile -t all_ids < <(list_all_ids)
if [[ ${#all_ids[@]} -eq 0 ]]; then
log "Keine LXC-Container gefunden."
return 0
fi
log "Starte pct fstrim für alle laufenden Container: ${all_ids[*]}"
local rc=0
for id in "${all_ids[@]}"; do
do_fstrim "$id" "$timeout_s" || rc=1
done
return $rc
}
interactive_menu() {
echo "Kein Parameter übergeben. Bitte auswählen:"
echo " 1) Alle laufenden LXC-Container trimmen"
echo " 2) Bestimmte IDs (kommagetrennt)"
read -r -p "Auswahl [1/2]: " choice
case "$choice" in
1) run_for_all "$TIMEOUT_S" ;;
2)
read -r -p "IDs (z. B. 102,103): " ids
run_for_ids "$ids" "$TIMEOUT_S"
;;
*) echo "Ungültige Auswahl."; exit 1 ;;
esac
}
# --- Main ---
require_root
have pct || { echo "Fehler: 'pct' nicht verfügbar. Bitte auf einem Proxmox-Host ausführen."; exit 1; }
TIMEOUT_S=$DEFAULT_TIMEOUT
# globale Option --timeout vorziehen
while [[ $# -gt 1 ]]; do
case "$1" in
--timeout) TIMEOUT_S="${2:-$DEFAULT_TIMEOUT}"; shift 2 ;;
*) break ;;
esac
done
if [[ $# -eq 0 ]]; then
interactive_menu
exit $?
fi
case "$1" in
-h|--help) usage; exit 0 ;;
-all|--all) run_for_all "$TIMEOUT_S"; exit $? ;;
-i|--ids)
[[ -z "${2:-}" ]] && { echo "Fehler: IDs fehlen, z. B. -i 101,102"; exit 1; }
run_for_ids "$2" "$TIMEOUT_S"; exit $? ;;
-[0-9]*)
ids_arg="${1#-}"
run_for_ids "$ids_arg" "$TIMEOUT_S"; exit $? ;;
*)
echo "Unbekannter Parameter: $1"
usage
exit 1
;;
esac