From 1dd90e6e7c5aa98fb034d2f4ca427d59b5f59f1e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20=C4=8Cerm=C3=A1k?= Date: Thu, 30 Jan 2025 18:12:08 +0100 Subject: [PATCH] Make sure the oldest boot ID is included in the boot list If the system is running for a long time, or the logging is particularly chatty, the Systemd journal message we use to detect boot will be rotated out of the journal. Currently we only handled it if there was one boot, but we usually always missed the oldest boot if there were more boots. Adjust the method for getting boot IDs to always get the very first log line in the journal instead of the last one, and make sure its boot ID is included in the list. --- supervisor/host/logs.py | 42 ++++++++++++++++++++++------------------- 1 file changed, 23 insertions(+), 19 deletions(-) diff --git a/supervisor/host/logs.py b/supervisor/host/logs.py index 68cdc06b47b..6c923db640d 100644 --- a/supervisor/host/logs.py +++ b/supervisor/host/logs.py @@ -111,25 +111,29 @@ async def get_boot_ids(self) -> list[str]: _LOGGER.error, ) from err - # If a system has not been rebooted in a long time query can come back with zero results - # Fallback is to get latest log line and its boot ID so we always have at least one. - if not text: - try: - async with self.journald_logs( - range_header="entries=:-1:1", - accept=LogFormat.JSON, - timeout=ClientTimeout(total=20), - ) as resp: - text = await resp.text() - except (ClientError, TimeoutError) as err: - raise HostLogError( - "Could not get a list of boot IDs from systemd-journal-gatewayd", - _LOGGER.error, - ) from err - - self._boot_ids = [ - json.loads(entry)[PARAM_BOOT_ID] for entry in text.split("\n") if entry - ] + # Get the oldest log entry. This makes sure that its ID is included + # if the start of the oldest boot was rotated out of the journal. + try: + async with self.journald_logs( + range_header="entries=:0:1", + accept=LogFormat.JSON, + timeout=ClientTimeout(total=20), + ) as resp: + text = await resp.text() + text + except (ClientError, TimeoutError) as err: + raise HostLogError( + "Could not get a list of boot IDs from systemd-journal-gatewayd", + _LOGGER.error, + ) from err + + self._boot_ids = [] + for entry in text.split("\n"): + if ( + entry + and (boot_id := json.loads(entry)[PARAM_BOOT_ID]) not in self._boot_ids + ): + self._boot_ids.append(boot_id) + return self._boot_ids async def get_identifiers(self) -> list[str]: