Add startup time and boot_timestamp (#3136)

* Add startup time

* Add boot_timestamp

* Fix type

* patch and rename properties fixture
This commit is contained in:
Joakim Sørensen 2021-09-22 11:15:38 +02:00 committed by GitHub
parent 6d2a38c96e
commit 40bcee38f3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 270 additions and 45 deletions

View File

@ -1,9 +1,11 @@
"""Const for API."""
ATTR_USE_RTC = "use_rtc"
ATTR_USE_NTP = "use_ntp"
ATTR_DT_UTC = "dt_utc"
ATTR_DT_SYNCHRONIZED = "dt_synchronized"
ATTR_DISK_DATA = "disk_data"
ATTR_DEVICE = "device"
ATTR_AGENT_VERSION = "agent_version"
ATTR_BOOT_TIMESTAMP = "boot_timestamp"
ATTR_DEVICE = "device"
ATTR_DISK_DATA = "disk_data"
ATTR_DT_SYNCHRONIZED = "dt_synchronized"
ATTR_DT_UTC = "dt_utc"
ATTR_STARTUP_TIME = "startup_time"
ATTR_USE_NTP = "use_ntp"
ATTR_USE_RTC = "use_rtc"

View File

@ -27,8 +27,10 @@ from ..const import (
from ..coresys import CoreSysAttributes
from .const import (
ATTR_AGENT_VERSION,
ATTR_BOOT_TIMESTAMP,
ATTR_DT_SYNCHRONIZED,
ATTR_DT_UTC,
ATTR_STARTUP_TIME,
ATTR_USE_NTP,
ATTR_USE_RTC,
)
@ -63,6 +65,8 @@ class APIHost(CoreSysAttributes):
ATTR_DT_SYNCHRONIZED: self.sys_host.info.dt_synchronized,
ATTR_USE_NTP: self.sys_host.info.use_ntp,
ATTR_USE_RTC: self.sys_host.info.use_rtc,
ATTR_STARTUP_TIME: self.sys_host.info.startup_time,
ATTR_BOOT_TIMESTAMP: self.sys_host.info.boot_timestamp,
}
@api_process

View File

@ -1,96 +1,102 @@
"""Constants for DBUS."""
from enum import Enum
DBUS_NAME_ACCESSPOINT = "org.freedesktop.NetworkManager.AccessPoint"
DBUS_NAME_CONNECTION_ACTIVE = "org.freedesktop.NetworkManager.Connection.Active"
DBUS_NAME_DEVICE = "org.freedesktop.NetworkManager.Device"
DBUS_NAME_DEVICE_WIRELESS = "org.freedesktop.NetworkManager.Device.Wireless"
DBUS_NAME_DNS = "org.freedesktop.NetworkManager.DnsManager"
DBUS_NAME_ACCESSPOINT = "org.freedesktop.NetworkManager.AccessPoint"
DBUS_NAME_HAOS = "io.hass.os"
DBUS_NAME_HAOS_APPARMOR = "io.hass.os.AppArmor"
DBUS_NAME_HAOS_CGROUP = "io.hass.os.CGroup"
DBUS_NAME_HAOS_DATADISK = "io.hass.os.DataDisk"
DBUS_NAME_HAOS_SYSTEM = "io.hass.os.System"
DBUS_NAME_HOSTNAME = "org.freedesktop.hostname1"
DBUS_NAME_IP4CONFIG = "org.freedesktop.NetworkManager.IP4Config"
DBUS_NAME_IP6CONFIG = "org.freedesktop.NetworkManager.IP6Config"
DBUS_NAME_LOGIND = "org.freedesktop.login1"
DBUS_NAME_NM = "org.freedesktop.NetworkManager"
DBUS_NAME_RAUC = "de.pengutronix.rauc"
DBUS_NAME_RAUC_INSTALLER = "de.pengutronix.rauc.Installer"
DBUS_NAME_RAUC_INSTALLER_COMPLETED = "de.pengutronix.rauc.Installer.Completed"
DBUS_NAME_SETTINGS_CONNECTION = "org.freedesktop.NetworkManager.Settings.Connection"
DBUS_NAME_NM_CONNECTION_ACTIVE_CHANGED = (
"org.freedesktop.NetworkManager.Connection.Active.PropertiesChanged"
)
DBUS_NAME_RAUC = "de.pengutronix.rauc"
DBUS_NAME_RAUC_INSTALLER = "de.pengutronix.rauc.Installer"
DBUS_NAME_RAUC_INSTALLER_COMPLETED = "de.pengutronix.rauc.Installer.Completed"
DBUS_NAME_ROOT = ""
DBUS_NAME_SETTINGS_CONNECTION = "org.freedesktop.NetworkManager.Settings.Connection"
DBUS_NAME_SYSTEMD = "org.freedesktop.systemd1"
DBUS_NAME_LOGIND = "org.freedesktop.login1"
DBUS_NAME_TIMEDATE = "org.freedesktop.timedate1"
DBUS_NAME_HAOS = "io.hass.os"
DBUS_NAME_HAOS_CGROUP = "io.hass.os.CGroup"
DBUS_NAME_HAOS_APPARMOR = "io.hass.os.AppArmor"
DBUS_NAME_HAOS_SYSTEM = "io.hass.os.System"
DBUS_NAME_HAOS_DATADISK = "io.hass.os.DataDisk"
DBUS_OBJECT_BASE = "/"
DBUS_OBJECT_DNS = "/org/freedesktop/NetworkManager/DnsManager"
DBUS_OBJECT_SETTINGS = "/org/freedesktop/NetworkManager/Settings"
DBUS_OBJECT_HOSTNAME = "/org/freedesktop/hostname1"
DBUS_OBJECT_NM = "/org/freedesktop/NetworkManager"
DBUS_OBJECT_SYSTEMD = "/org/freedesktop/systemd1"
DBUS_OBJECT_LOGIND = "/org/freedesktop/login1"
DBUS_OBJECT_TIMEDATE = "/org/freedesktop/timedate1"
DBUS_OBJECT_HAOS = "/io/hass/os"
DBUS_OBJECT_HAOS_CGROUP = "/io/hass/os/CGroup"
DBUS_OBJECT_HAOS_APPARMOR = "/io/hass/os/AppArmor"
DBUS_OBJECT_HAOS_SYSTEM = "/io/hass/os/System"
DBUS_OBJECT_HAOS_CGROUP = "/io/hass/os/CGroup"
DBUS_OBJECT_HAOS_DATADISK = "/io/hass/os/DataDisk"
DBUS_OBJECT_HAOS_SYSTEM = "/io/hass/os/System"
DBUS_OBJECT_HOSTNAME = "/org/freedesktop/hostname1"
DBUS_OBJECT_LOGIND = "/org/freedesktop/login1"
DBUS_OBJECT_NM = "/org/freedesktop/NetworkManager"
DBUS_OBJECT_SETTINGS = "/org/freedesktop/NetworkManager/Settings"
DBUS_OBJECT_SYSTEMD = "/org/freedesktop/systemd1"
DBUS_OBJECT_TIMEDATE = "/org/freedesktop/timedate1"
DBUS_ATTR_ACTIVE_CONNECTIONS = "ActiveConnections"
DBUS_ATTR_ACTIVE_CONNECTION = "ActiveConnection"
DBUS_ATTR_ACTIVE_ACCESSPOINT = "ActiveAccessPoint"
DBUS_ATTR_ACTIVE_CONNECTION = "ActiveConnection"
DBUS_ATTR_ACTIVE_CONNECTIONS = "ActiveConnections"
DBUS_ATTR_ADDRESS_DATA = "AddressData"
DBUS_ATTR_BOOT_SLOT = "BootSlot"
DBUS_ATTR_CHASSIS = "Chassis"
DBUS_ATTR_COMPATIBLE = "Compatible"
DBUS_ATTR_CONFIGURATION = "Configuration"
DBUS_ATTR_CONNECTION = "Connection"
DBUS_ATTR_CONNECTION_ENABLED = "ConnectivityCheckEnabled"
DBUS_ATTR_CURRENT_DEVICE = "CurrentDevice"
DBUS_ATTR_DEFAULT = "Default"
DBUS_ATTR_DEPLOYMENT = "Deployment"
DBUS_ATTR_DEVICE_INTERFACE = "Interface"
DBUS_ATTR_DEVICE_TYPE = "DeviceType"
DBUS_ATTR_DEVICES = "Devices"
DBUS_ATTR_DIAGNOSTICS = "Diagnostics"
DBUS_ATTR_DRIVER = "Driver"
DBUS_ATTR_GATEWAY = "Gateway"
DBUS_ATTR_ID = "Id"
DBUS_ATTR_SSID = "Ssid"
DBUS_ATTR_FINISH_TIMESTAMP = "FinishTimestamp"
DBUS_ATTR_FIRMWARE_TIMESTAMP_MONOTONIC = "FirmwareTimestampMonotonic"
DBUS_ATTR_FREQUENCY = "Frequency"
DBUS_ATTR_GATEWAY = "Gateway"
DBUS_ATTR_HWADDRESS = "HwAddress"
DBUS_ATTR_MODE = "Mode"
DBUS_ATTR_STRENGTH = "Strength"
DBUS_ATTR_ID = "Id"
DBUS_ATTR_IP4CONFIG = "Ip4Config"
DBUS_ATTR_IP6CONFIG = "Ip6Config"
DBUS_ATTR_KERNEL_RELEASE = "KernelRelease"
DBUS_ATTR_KERNEL_TIMESTAMP_MONOTONIC = "KernelTimestampMonotonic"
DBUS_ATTR_LAST_ERROR = "LastError"
DBUS_ATTR_LOADER_TIMESTAMP_MONOTONIC = "LoaderTimestampMonotonic"
DBUS_ATTR_LOCALRTC = "LocalRTC"
DBUS_ATTR_MANAGED = "Managed"
DBUS_ATTR_MODE = "Mode"
DBUS_ATTR_MODE = "Mode"
DBUS_ATTR_NAMESERVERS = "Nameservers"
DBUS_ATTR_NAMESERVER_DATA = "NameserverData"
DBUS_ATTR_NAMESERVERS = "Nameservers"
DBUS_ATTR_NTP = "NTP"
DBUS_ATTR_NTPSYNCHRONIZED = "NTPSynchronized"
DBUS_ATTR_OPERATING_SYSTEM_PRETTY_NAME = "OperatingSystemPrettyName"
DBUS_ATTR_OPERATION = "Operation"
DBUS_ATTR_PARSER_VERSION = "ParserVersion"
DBUS_ATTR_PRIMARY_CONNECTION = "PrimaryConnection"
DBUS_ATTR_RCMANAGER = "RcManager"
DBUS_ATTR_SSID = "Ssid"
DBUS_ATTR_STATE = "State"
DBUS_ATTR_STATIC_HOSTNAME = "StaticHostname"
DBUS_ATTR_STATIC_OPERATING_SYSTEM_CPE_NAME = "OperatingSystemCPEName"
DBUS_ATTR_STRENGTH = "Strength"
DBUS_ATTR_TIMEUSEC = "TimeUSec"
DBUS_ATTR_TIMEZONE = "Timezone"
DBUS_ATTR_TYPE = "Type"
DBUS_ATTR_USERSPACE_TIMESTAMP_MONOTONIC = "UserspaceTimestampMonotonic"
DBUS_ATTR_UUID = "Uuid"
DBUS_ATTR_VARIANT = "Variant"
DBUS_ATTR_VERSION = "Version"
DBUS_ATTR_MANAGED = "Managed"
DBUS_ATTR_CONNECTION_ENABLED = "ConnectivityCheckEnabled"
DBUS_ATTR_TIMEZONE = "Timezone"
DBUS_ATTR_LOCALRTC = "LocalRTC"
DBUS_ATTR_NTP = "NTP"
DBUS_ATTR_NTPSYNCHRONIZED = "NTPSynchronized"
DBUS_ATTR_TIMEUSEC = "TimeUSec"
DBUS_ATTR_DIAGNOSTICS = "Diagnostics"
DBUS_ATTR_CURRENT_DEVICE = "CurrentDevice"
DBUS_ATTR_PARSER_VERSION = "ParserVersion"
class RaucState(str, Enum):

View File

@ -1,10 +1,20 @@
"""Interface to Systemd over D-Bus."""
import logging
from typing import Any
from ..exceptions import DBusError, DBusInterfaceError
from ..utils.gdbus import DBus
from .const import DBUS_NAME_SYSTEMD, DBUS_OBJECT_SYSTEMD
from .interface import DBusInterface
from .const import (
DBUS_ATTR_FINISH_TIMESTAMP,
DBUS_ATTR_FIRMWARE_TIMESTAMP_MONOTONIC,
DBUS_ATTR_KERNEL_TIMESTAMP_MONOTONIC,
DBUS_ATTR_LOADER_TIMESTAMP_MONOTONIC,
DBUS_ATTR_USERSPACE_TIMESTAMP_MONOTONIC,
DBUS_NAME_ROOT,
DBUS_NAME_SYSTEMD,
DBUS_OBJECT_SYSTEMD,
)
from .interface import DBusInterface, dbus_property
from .utils import dbus_connected
_LOGGER: logging.Logger = logging.getLogger(__name__)
@ -15,6 +25,10 @@ class Systemd(DBusInterface):
name = DBUS_NAME_SYSTEMD
def __init__(self) -> None:
"""Initialize Properties."""
self.properties: dict[str, Any] = {}
async def connect(self):
"""Connect to D-Bus."""
try:
@ -26,6 +40,23 @@ class Systemd(DBusInterface):
"No systemd support on the host. Host control has been disabled."
)
@property
@dbus_property
def startup_time(self) -> float:
"""Return startup time in seconds."""
return (
float(self.properties[DBUS_ATTR_FIRMWARE_TIMESTAMP_MONOTONIC])
+ float(self.properties[DBUS_ATTR_LOADER_TIMESTAMP_MONOTONIC])
+ float(self.properties[DBUS_ATTR_KERNEL_TIMESTAMP_MONOTONIC])
+ float(self.properties[DBUS_ATTR_USERSPACE_TIMESTAMP_MONOTONIC])
) / 1e6
@property
@dbus_property
def boot_timestamp(self) -> int:
"""Return the boot timestamp."""
return self.properties[DBUS_ATTR_FINISH_TIMESTAMP]
@dbus_connected
def reboot(self):
"""Reboot host computer.
@ -81,3 +112,8 @@ class Systemd(DBusInterface):
Return a coroutine.
"""
return self.dbus.Manager.ListUnits()
@dbus_connected
async def update(self):
"""Update Properties."""
self.properties = await self.dbus.get_properties(DBUS_NAME_ROOT)

View File

@ -72,6 +72,16 @@ class InfoCenter(CoreSysAttributes):
"""Return true if host time is syncronized."""
return self.sys_dbus.timedate.ntp_synchronized
@property
def startup_time(self) -> Optional[float]:
"""Return startup time in seconds."""
return self.sys_dbus.systemd.startup_time
@property
def boot_timestamp(self) -> Optional[int]:
"""Return the boot timestamp."""
return self.sys_dbus.systemd.boot_timestamp
@property
def total_space(self) -> float:
"""Return total space (GiB) on disk for supervisor data directory."""
@ -123,5 +133,7 @@ class InfoCenter(CoreSysAttributes):
await self.sys_dbus.hostname.update()
if self.sys_dbus.timedate.is_connected:
await self.sys_dbus.timedate.update()
if self.sys_dbus.systemd.is_connected:
await self.sys_dbus.systemd.update()
except DBusError:
_LOGGER.warning("Can't update host system information!")

View File

@ -0,0 +1,27 @@
"""Test hostname dbus interface."""
from unittest.mock import patch
from supervisor.coresys import CoreSys
from supervisor.dbus.const import DBUS_NAME_SYSTEMD
from tests.common import load_json_fixture
async def test_dbus_systemd_info(coresys: CoreSys):
"""Test coresys dbus connection."""
assert coresys.dbus.systemd.boot_timestamp is None
assert coresys.dbus.systemd.startup_time is None
await coresys.dbus.systemd.connect()
async def mock_get_properties(dbus_obj, interface):
return load_json_fixture(
f"{DBUS_NAME_SYSTEMD.replace('.', '_')}_properties.json"
)
with patch("supervisor.utils.gdbus.DBus.get_properties", new=mock_get_properties):
await coresys.dbus.systemd.update()
assert coresys.dbus.systemd.boot_timestamp == 1632236713344227
assert coresys.dbus.systemd.startup_time == 45.304696

View File

@ -0,0 +1,138 @@
{
"Version": "245.4-4ubuntu3.11",
"Features": "+PAM +AUDIT +SELINUX +IMA +APPARMOR +SMACK +SYSVINIT +UTMP +LIBCRYPTSETUP +GCRYPT +GNUTLS +ACL +XZ +LZ4 +SECCOMP +BLKID +ELFUTILS +KMOD +IDN2 -IDN +PCRE2 default-hierarchy=hybrid",
"Virtualization": "",
"Architecture": "x86-64",
"Tainted": "",
"FirmwareTimestamp": 0,
"FirmwareTimestampMonotonic": 28723572,
"LoaderTimestamp": 0,
"LoaderTimestampMonotonic": 12402885,
"KernelTimestamp": 1632236694969442,
"KernelTimestampMonotonic": 0,
"InitRDTimestamp": 0,
"InitRDTimestampMonotonic": 0,
"UserspaceTimestamp": 1632236699147681,
"UserspaceTimestampMonotonic": 4178239,
"FinishTimestamp": 1632236713344227,
"FinishTimestampMonotonic": 18374785,
"SecurityStartTimestamp": 1632236699156494,
"SecurityStartTimestampMonotonic": 4187052,
"SecurityFinishTimestamp": 1632236699156980,
"SecurityFinishTimestampMonotonic": 4187538,
"GeneratorsStartTimestamp": 1632236699281427,
"GeneratorsStartTimestampMonotonic": 4311984,
"GeneratorsFinishTimestamp": 1632236699334042,
"GeneratorsFinishTimestampMonotonic": 4364600,
"UnitsLoadStartTimestamp": 1632236699334044,
"UnitsLoadStartTimestampMonotonic": 4364602,
"UnitsLoadFinishTimestamp": 1632236699424558,
"UnitsLoadFinishTimestampMonotonic": 4455116,
"InitRDSecurityStartTimestamp": 0,
"InitRDSecurityStartTimestampMonotonic": 0,
"InitRDSecurityFinishTimestamp": 0,
"InitRDSecurityFinishTimestampMonotonic": 0,
"InitRDGeneratorsStartTimestamp": 0,
"InitRDGeneratorsStartTimestampMonotonic": 0,
"InitRDGeneratorsFinishTimestamp": 0,
"InitRDGeneratorsFinishTimestampMonotonic": 0,
"InitRDUnitsLoadStartTimestamp": 0,
"InitRDUnitsLoadStartTimestampMonotonic": 0,
"InitRDUnitsLoadFinishTimestamp": 0,
"InitRDUnitsLoadFinishTimestampMonotonic": 0,
"LogLevel": "info",
"LogTarget": "journal-or-kmsg",
"NNames": 564,
"NFailedUnits": 0,
"NJobs": 0,
"NInstalledJobs": 1575,
"NFailedJobs": 0,
"Progress": 1.0,
"Environment": [
"LANG=en_US.UTF-8",
"LC_ADDRESS=nb_NO.UTF-8",
"LC_IDENTIFICATION=nb_NO.UTF-8",
"LC_MEASUREMENT=nb_NO.UTF-8",
"LC_MONETARY=nb_NO.UTF-8",
"LC_NAME=nb_NO.UTF-8",
"LC_NUMERIC=nb_NO.UTF-8",
"LC_PAPER=nb_NO.UTF-8",
"LC_TELEPHONE=nb_NO.UTF-8",
"LC_TIME=nb_NO.UTF-8",
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin"
],
"ConfirmSpawn": false,
"ShowStatus": false,
"UnitPath": [
"/etc/systemd/system.control",
"/run/systemd/system.control",
"/run/systemd/transient",
"/run/systemd/generator.early",
"/etc/systemd/system",
"/etc/systemd/system.attached",
"/run/systemd/system",
"/run/systemd/system.attached",
"/run/systemd/generator",
"/usr/local/lib/systemd/system",
"/lib/systemd/system",
"/usr/lib/systemd/system",
"/run/systemd/generator.late"
],
"DefaultStandardOutput": "journal",
"DefaultStandardError": "journal",
"RuntimeWatchdogUSec": 0,
"RebootWatchdogUSec": 600000000,
"KExecWatchdogUSec": 0,
"ServiceWatchdogs": true,
"ControlGroup": "",
"SystemState": "running",
"ExitCode": [
0
],
"DefaultTimerAccuracyUSec": 60000000,
"DefaultTimeoutStartUSec": 90000000,
"DefaultTimeoutStopUSec": 90000000,
"DefaultTimeoutAbortUSec": 90000000,
"DefaultRestartUSec": 100000,
"DefaultStartLimitIntervalUSec": 10000000,
"DefaultStartLimitBurst": 5,
"DefaultCPUAccounting": false,
"DefaultBlockIOAccounting": false,
"DefaultMemoryAccounting": true,
"DefaultTasksAccounting": true,
"DefaultLimitCPU": 18446744073709551615,
"DefaultLimitCPUSoft": 18446744073709551615,
"DefaultLimitFSIZE": 18446744073709551615,
"DefaultLimitFSIZESoft": 18446744073709551615,
"DefaultLimitDATA": 18446744073709551615,
"DefaultLimitDATASoft": 18446744073709551615,
"DefaultLimitSTACK": 18446744073709551615,
"DefaultLimitSTACKSoft": 8388608,
"DefaultLimitCORE": 18446744073709551615,
"DefaultLimitCORESoft": 0,
"DefaultLimitRSS": 18446744073709551615,
"DefaultLimitRSSSoft": 18446744073709551615,
"DefaultLimitNOFILE": 524288,
"DefaultLimitNOFILESoft": 1024,
"DefaultLimitAS": 18446744073709551615,
"DefaultLimitASSoft": 18446744073709551615,
"DefaultLimitNPROC": 127764,
"DefaultLimitNPROCSoft": 127764,
"DefaultLimitMEMLOCK": 65536,
"DefaultLimitMEMLOCKSoft": 65536,
"DefaultLimitLOCKS": 18446744073709551615,
"DefaultLimitLOCKSSoft": 18446744073709551615,
"DefaultLimitSIGPENDING": 127764,
"DefaultLimitSIGPENDINGSoft": 127764,
"DefaultLimitMSGQUEUE": 819200,
"DefaultLimitMSGQUEUESoft": 819200,
"DefaultLimitNICE": 0,
"DefaultLimitNICESoft": 0,
"DefaultLimitRTPRIO": 0,
"DefaultLimitRTPRIOSoft": 0,
"DefaultLimitRTTIME": 18446744073709551615,
"DefaultLimitRTTIMESoft": 18446744073709551615,
"DefaultTasksMax": 38329,
"TimerSlackNSec": 50000,
"DefaultOOMPolicy": "stop"
}