Merge pull request 'checkin: report host disk free/total (#41)' (#43) from feat/41-disk-reporting into main
Build edge-node / build (push) Successful in 59s
Publish public images / publish (edge-node, ./drb-edge-node, ./drb-edge-node/Dockerfile, edge-node) (push) Skipped
Publish public images / publish (icecast, ./icecast, ./icecast/Dockerfile, icecast) (push) Skipped
Publish public images / publish (op25-client, ./op25-container, ./op25-container/Dockerfile, op25-client) (push) Skipped
CI / lint (push) Successful in 8s
CI / test-op25 (push) Successful in 15s
Release images / ensure (drb-edge-node, edge-node) (push) Successful in 32s
Release images / ensure (icecast, icecast) (push) Successful in 42s
Release images / ensure (op25-container, op25-client) (push) Successful in 41s
Release images / ensure (secondary-sdr-container, secondary-sdr) (push) Successful in 38s
CI / test (push) Successful in 52s
Build edge-node / build (push) Successful in 59s
Publish public images / publish (edge-node, ./drb-edge-node, ./drb-edge-node/Dockerfile, edge-node) (push) Skipped
Publish public images / publish (icecast, ./icecast, ./icecast/Dockerfile, icecast) (push) Skipped
Publish public images / publish (op25-client, ./op25-container, ./op25-container/Dockerfile, op25-client) (push) Skipped
CI / lint (push) Successful in 8s
CI / test-op25 (push) Successful in 15s
Release images / ensure (drb-edge-node, edge-node) (push) Successful in 32s
Release images / ensure (icecast, icecast) (push) Successful in 42s
Release images / ensure (op25-container, op25-client) (push) Successful in 41s
Release images / ensure (secondary-sdr-container, secondary-sdr) (push) Successful in 38s
CI / test (push) Successful in 52s
This commit was merged in pull request #43.
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
import asyncio
|
||||
import json
|
||||
import shutil
|
||||
from datetime import datetime, timezone
|
||||
from collections import deque
|
||||
from typing import Optional, Callable, Awaitable, Dict, Any
|
||||
@@ -8,6 +9,22 @@ from app.config import settings
|
||||
from app.internal.logger import logger
|
||||
from app.internal import credentials, key_pickup
|
||||
|
||||
|
||||
def disk_report(path: str) -> Dict[str, Optional[int]]:
|
||||
"""Free/total bytes of the filesystem holding `path` (node-26#41).
|
||||
|
||||
/recordings is a bind mount of the host checkout, so this is the host disk
|
||||
the recorder writes to and Docker's images/build cache live on. A full disk
|
||||
stopped node-002 recording for 17 days while it still showed Online. Nulls
|
||||
on error, so C2 overwrites a stale reading instead of keeping it.
|
||||
"""
|
||||
try:
|
||||
usage = shutil.disk_usage(path)
|
||||
except OSError:
|
||||
return {"disk_free_bytes": None, "disk_total_bytes": None}
|
||||
return {"disk_free_bytes": usage.free, "disk_total_bytes": usage.total}
|
||||
|
||||
|
||||
CommandCallback = Callable[[Dict[str, Any]], Awaitable[None]]
|
||||
ConfigCallback = Callable[[Dict[str, Any]], Awaitable[None]]
|
||||
ApiKeyCallback = Callable[[Dict[str, Any]], Awaitable[None]]
|
||||
@@ -372,6 +389,7 @@ class MQTTManager:
|
||||
count = devices.get("count") or None
|
||||
if count is not None:
|
||||
payload["sdr_count"] = count
|
||||
payload.update(disk_report(settings.recordings_path))
|
||||
self._publish(self._t_checkin, payload, qos=1)
|
||||
|
||||
def _publish(self, topic: str, payload: dict, qos: int = 0, retain: bool = False):
|
||||
|
||||
@@ -140,3 +140,16 @@ def test_build_client_does_not_touch_offline_buffer(monkeypatch):
|
||||
|
||||
assert list(mqtt_manager._offline_buffer) == [("nodes/test/metadata", {"call_id": "sentinel"})]
|
||||
mqtt_manager._offline_buffer.clear()
|
||||
|
||||
|
||||
def test_disk_report_reads_free_and_total(tmp_path):
|
||||
from app.internal.mqtt_manager import disk_report
|
||||
rep = disk_report(str(tmp_path))
|
||||
assert rep["disk_total_bytes"] > 0
|
||||
assert 0 <= rep["disk_free_bytes"] <= rep["disk_total_bytes"]
|
||||
|
||||
|
||||
def test_disk_report_nulls_when_path_unreadable(tmp_path):
|
||||
# node-26#41: nulls (not omitted keys) so C2 never keeps a stale reading.
|
||||
from app.internal.mqtt_manager import disk_report
|
||||
assert disk_report(str(tmp_path / "missing")) == {"disk_free_bytes": None, "disk_total_bytes": None}
|
||||
|
||||
Reference in New Issue
Block a user