Fix: ZFS-Fehlerlogs auf LXC/non-ZFS-Systemen unterdrückt

- ZFS_AVAILABLE Flag beim Import gesetzt (shutil.which)
- FileNotFoundError in run_command: ERROR → DEBUG
- list_pools/get_pool_status/list_datasets/list_snapshots: frühzeitiger
  Return wenn kein zpool vorhanden → keine nutzlosen Subprocess-Aufrufe

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-06-05 15:08:23 +02:00
parent f49793e6f2
commit 2b6d508ca4
+17 -1
View File
@@ -15,6 +15,10 @@ import re
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
# Detect ZFS availability once at import time — avoids repeated ERROR logs on LXC/non-ZFS systems
import shutil as _shutil
ZFS_AVAILABLE = bool(_shutil.which("zpool"))
# Cache with TTL # Cache with TTL
@dataclass @dataclass
class CacheEntry: class CacheEntry:
@@ -83,7 +87,7 @@ class ZFSRunner:
logger.error(f"Command timeout after {timeout}s: {' '.join(cmd)}") logger.error(f"Command timeout after {timeout}s: {' '.join(cmd)}")
return "", f"Command timeout after {timeout}s", -1 return "", f"Command timeout after {timeout}s", -1
except FileNotFoundError: except FileNotFoundError:
logger.error(f"Command not found: {' '.join(cmd)}") logger.debug(f"Command not found: {' '.join(cmd)}")
return "", f"Command not found: {cmd[0]}", -1 return "", f"Command not found: {cmd[0]}", -1
except Exception as e: except Exception as e:
logger.error(f"Command execution error: {e}") logger.error(f"Command execution error: {e}")
@@ -100,6 +104,9 @@ class ZFSRunner:
if cached: if cached:
return cached return cached
if not ZFS_AVAILABLE:
return []
stdout, stderr, rc = self.run_command(["zpool", "list", "-H", "-p"]) stdout, stderr, rc = self.run_command(["zpool", "list", "-H", "-p"])
if rc != 0: if rc != 0:
@@ -266,6 +273,9 @@ class ZFSRunner:
""" """
Get detailed pool status including VDEV tree and error counters Get detailed pool status including VDEV tree and error counters
""" """
if not ZFS_AVAILABLE:
return {}
stdout, stderr, rc = self.run_command(["zpool", "status", pool_name]) stdout, stderr, rc = self.run_command(["zpool", "status", pool_name])
if rc != 0: if rc != 0:
@@ -347,6 +357,9 @@ class ZFSRunner:
if cached and cached.get(pool_name): if cached and cached.get(pool_name):
return cached[pool_name] return cached[pool_name]
if not ZFS_AVAILABLE:
return []
stdout, stderr, rc = self.run_command([ stdout, stderr, rc = self.run_command([
"zfs", "list", "-d", str(max_depth), "-H", "-p", "zfs", "list", "-d", str(max_depth), "-H", "-p",
"-o", "name,used,avail,refer,mountpoint,type", "-o", "name,used,avail,refer,mountpoint,type",
@@ -446,6 +459,9 @@ class ZFSRunner:
if cached: if cached:
return cached return cached
if not ZFS_AVAILABLE:
return []
if dataset_name: if dataset_name:
# No -d limit so sub-datasets (e.g. tank/share) are included # No -d limit so sub-datasets (e.g. tank/share) are included
cmd = ["zfs", "list", "-t", "snapshot", "-r", "-H", "-p", cmd = ["zfs", "list", "-t", "snapshot", "-r", "-H", "-p",