From 6a955527f3357293acf11ec6180460ef2ce1fe72 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20=C4=8Cerm=C3=A1k?= Date: Fri, 27 Feb 2026 17:59:11 +0100 Subject: [PATCH] Ensure dt_utc in /os/info always returns current time (#6602) The /os/info API endpoint has been using D-Bus property TimeUSec which got cached between requests, so the time returned was not always the same as current time on the host system at the time of the request. Since there's no reason to use D-Bus API for the time, as Supervisor runs on the same machine and time is global, simply format current datetime object with Python and return it in the response. Fixes #6581 --- supervisor/dbus/timedate.py | 9 +-------- supervisor/host/info.py | 6 +++--- tests/api/test_host.py | 9 +++++++-- tests/dbus/test_timedate.py | 4 ---- 4 files changed, 11 insertions(+), 17 deletions(-) diff --git a/supervisor/dbus/timedate.py b/supervisor/dbus/timedate.py index 334be6a83..c52d95b18 100644 --- a/supervisor/dbus/timedate.py +++ b/supervisor/dbus/timedate.py @@ -8,12 +8,11 @@ from typing import Any from dbus_fast.aio.message_bus import MessageBus from ..exceptions import DBusError, DBusInterfaceError, DBusServiceUnkownError -from ..utils.dt import get_time_zone, utc_from_timestamp +from ..utils.dt import get_time_zone from .const import ( DBUS_ATTR_LOCAL_RTC, DBUS_ATTR_NTP, DBUS_ATTR_NTPSYNCHRONIZED, - DBUS_ATTR_TIMEUSEC, DBUS_ATTR_TIMEZONE, DBUS_IFACE_TIMEDATE, DBUS_NAME_TIMEDATE, @@ -65,12 +64,6 @@ class TimeDate(DBusInterfaceProxy): """Return if NTP is synchronized.""" return self.properties[DBUS_ATTR_NTPSYNCHRONIZED] - @property - @dbus_property - def dt_utc(self) -> datetime: - """Return the system UTC time.""" - return utc_from_timestamp(self.properties[DBUS_ATTR_TIMEUSEC] / 1000000) - @property def timezone_tzinfo(self) -> tzinfo | None: """Return timezone as tzinfo object.""" diff --git a/supervisor/host/info.py b/supervisor/host/info.py index b42113fbe..60fd8ae64 100644 --- a/supervisor/host/info.py +++ b/supervisor/host/info.py @@ -1,7 +1,7 @@ """Info control for host.""" import asyncio -from datetime import datetime, tzinfo +from datetime import UTC, datetime, tzinfo import logging from ..coresys import CoreSysAttributes @@ -78,9 +78,9 @@ class InfoCenter(CoreSysAttributes): return self.sys_dbus.timedate.timezone_tzinfo @property - def dt_utc(self) -> datetime | None: + def dt_utc(self) -> datetime: """Return host UTC time.""" - return self.sys_dbus.timedate.dt_utc + return datetime.now(UTC) @property def use_rtc(self) -> bool | None: diff --git a/tests/api/test_host.py b/tests/api/test_host.py index 7c933cd63..b307b7122 100644 --- a/tests/api/test_host.py +++ b/tests/api/test_host.py @@ -1,10 +1,12 @@ """Test Host API.""" from collections.abc import AsyncGenerator +from datetime import UTC, datetime from unittest.mock import ANY, MagicMock, patch from aiohttp.test_utils import TestClient import pytest +import time_machine from supervisor.coresys import CoreSys from supervisor.dbus.resolved import Resolved @@ -39,14 +41,17 @@ async def fixture_coresys_disk_info(coresys: CoreSys) -> AsyncGenerator[CoreSys] async def test_api_host_info(api_client: TestClient, coresys_disk_info: CoreSys): """Test host info api.""" coresys = coresys_disk_info + dt_utc = datetime(2026, 2, 17, 1, 23, 45, 678901, tzinfo=UTC) await coresys.dbus.agent.connect(coresys.dbus.bus) await coresys.dbus.agent.update() - resp = await api_client.get("/host/info") - result = await resp.json() + with time_machine.travel(dt_utc, tick=False): + resp = await api_client.get("/host/info") + result = await resp.json() assert result["data"]["apparmor_version"] == "2.13.2" + assert result["data"]["dt_utc"] == "2026-02-17T01:23:45.678901+00:00" async def test_api_host_features( diff --git a/tests/dbus/test_timedate.py b/tests/dbus/test_timedate.py index 9b05678dc..e02a23c51 100644 --- a/tests/dbus/test_timedate.py +++ b/tests/dbus/test_timedate.py @@ -25,16 +25,12 @@ async def test_timedate_info( """Test timedate properties.""" timedate = TimeDate() - assert timedate.dt_utc is None assert timedate.ntp is None await timedate.connect(dbus_session_bus) - assert timedate.dt_utc == datetime(2021, 5, 19, 8, 36, 54, 405718, tzinfo=UTC) assert timedate.ntp is True - assert timedate.dt_utc.isoformat() == "2021-05-19T08:36:54.405718+00:00" - timedate_service.emit_properties_changed({"NTP": False}) await timedate_service.ping() assert timedate.ntp is False