feat: add /host-sys volume mount and HOST_SYS_PATH environment variable for sysfs serial fallback and SMART health detection
Add HOST_SYS_PATH=/host-sys to .env.example and app.py config with /host-sys default. Update _device_serial() to check HOST_SYS_PATH/class/block and HOST_SYS_PATH/block before fallback /sys paths for serial reads. Update raid_status() SMART regex to match both "SMART overall-health self-assessment test result" and "SMART Health Status" with case-insensitive flag for NVMe/SSD compatibility. Add /
This commit is contained in:
@@ -41,6 +41,7 @@ REQUEST_TIMEOUT = int(os.environ.get("REQUEST_TIMEOUT", "20"))
|
||||
DATASTORE_PATH = os.environ.get("DATASTORE_PATH", "/nesflix").rstrip("/") or "/"
|
||||
RAID_DEVICE = os.environ.get("RAID_DEVICE", "/dev/md127")
|
||||
HOST_DEVICE_PATH = os.environ.get("HOST_DEVICE_PATH", "/host-dev")
|
||||
HOST_SYS_PATH = os.environ.get("HOST_SYS_PATH", "/host-sys")
|
||||
STORAGE_CACHE_SECONDS = int(os.environ.get("STORAGE_CACHE_SECONDS", "900"))
|
||||
SMART_ENABLED = os.environ.get("SMART_ENABLED", "false").lower() in {"1", "true", "yes", "on"}
|
||||
|
||||
@@ -243,7 +244,7 @@ def _flatten_lsblk(nodes):
|
||||
def _device_serial(device):
|
||||
"""Read a disk serial from sysfs when lsblk cannot expose it in Docker."""
|
||||
name = Path(device).name
|
||||
for path in (Path("/sys/class/block") / name / "device/serial", Path("/sys/block") / name / "device/serial"):
|
||||
for path in (Path(HOST_SYS_PATH) / "class/block" / name / "device/serial", Path(HOST_SYS_PATH) / "block" / name / "device/serial", Path("/sys/class/block") / name / "device/serial", Path("/sys/block") / name / "device/serial"):
|
||||
try:
|
||||
value = path.read_text().strip()
|
||||
if value:
|
||||
@@ -357,7 +358,7 @@ def raid_status():
|
||||
if SMART_ENABLED and shutil.which("smartctl"):
|
||||
smart_device = disk["device"].replace("/dev/", f"{HOST_DEVICE_PATH.rstrip('/')}/", 1)
|
||||
smart_output, _ = _read_command(["smartctl", "-H", smart_device], timeout=6)
|
||||
health = re.search(r"SMART overall-health self-assessment test result:\s*(.+)", smart_output)
|
||||
health = re.search(r"(?:SMART overall-health self-assessment test result|SMART Health Status):\s*(.+)", smart_output, re.IGNORECASE)
|
||||
disk["smart"] = health.group(1).strip() if health else "Nicht verfügbar"
|
||||
missing = members_match and members_match.group(1) != members_match.group(2)
|
||||
failed = detail.get("failed_devices", 0) > 0 or any(disk["status"] == "failed" for disk in devices)
|
||||
|
||||
Reference in New Issue
Block a user