mirror of
https://github.com/home-assistant/supervisor.git
synced 2025-11-27 19:48:07 +00:00
Compare commits
8 Commits
remove-unk
...
2025.11.5
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
906838e325 | ||
|
|
3be0c13fc5 | ||
|
|
bb450cad4f | ||
|
|
10af48a65b | ||
|
|
2f334c48c3 | ||
|
|
6d87e8f591 | ||
|
|
4d1dd63248 | ||
|
|
0c2d0cf5c1 |
2
.github/workflows/update_frontend.yml
vendored
2
.github/workflows/update_frontend.yml
vendored
@@ -68,7 +68,7 @@ jobs:
|
||||
run: |
|
||||
rm -f supervisor/api/panel/home_assistant_frontend_supervisor-*.tar.gz
|
||||
- name: Create PR
|
||||
uses: peter-evans/create-pull-request@271a8d0340265f705b14b6d32b9829c1cb33d45e # v7.0.8
|
||||
uses: peter-evans/create-pull-request@84ae59a2cdc2258d6fa0732dd66352dddae2a412 # v7.0.9
|
||||
with:
|
||||
commit-message: "Update frontend to version ${{ needs.check-version.outputs.latest_version }}"
|
||||
branch: autoupdate-frontend
|
||||
|
||||
@@ -4,7 +4,7 @@ aiohttp==3.13.2
|
||||
atomicwrites-homeassistant==1.4.1
|
||||
attrs==25.4.0
|
||||
awesomeversion==25.8.0
|
||||
backports.zstd==1.0.0
|
||||
backports.zstd==1.1.0
|
||||
blockbuster==1.5.25
|
||||
brotli==1.2.0
|
||||
ciso8601==2.3.3
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
astroid==4.0.2
|
||||
coverage==7.12.0
|
||||
mypy==1.18.2
|
||||
pre-commit==4.4.0
|
||||
pre-commit==4.5.0
|
||||
pylint==4.0.3
|
||||
pytest-aiohttp==1.1.0
|
||||
pytest-asyncio==1.3.0
|
||||
pytest-cov==7.0.0
|
||||
pytest-timeout==2.4.0
|
||||
pytest==9.0.1
|
||||
ruff==0.14.5
|
||||
time-machine==3.0.0
|
||||
ruff==0.14.6
|
||||
time-machine==3.1.0
|
||||
types-docker==7.1.0.20251009
|
||||
types-pyyaml==6.0.12.20250915
|
||||
types-requests==2.32.4.20250913
|
||||
|
||||
@@ -343,7 +343,7 @@ class APIHost(CoreSysAttributes):
|
||||
|
||||
disk = self.sys_hardware.disk
|
||||
|
||||
total, used, _ = await self.sys_run_in_executor(
|
||||
total, _, free = await self.sys_run_in_executor(
|
||||
disk.disk_usage, self.sys_config.path_supervisor
|
||||
)
|
||||
|
||||
@@ -365,12 +365,13 @@ class APIHost(CoreSysAttributes):
|
||||
"id": "root",
|
||||
"label": "Root",
|
||||
"total_bytes": total,
|
||||
"used_bytes": used,
|
||||
"used_bytes": total - free,
|
||||
"children": [
|
||||
{
|
||||
"id": "system",
|
||||
"label": "System",
|
||||
"used_bytes": used
|
||||
"used_bytes": total
|
||||
- free
|
||||
- sum(path["used_bytes"] for path in known_paths),
|
||||
},
|
||||
*known_paths,
|
||||
|
||||
@@ -306,6 +306,8 @@ class DeviceType(IntEnum):
|
||||
VLAN = 11
|
||||
TUN = 16
|
||||
VETH = 20
|
||||
WIREGUARD = 29
|
||||
LOOPBACK = 32
|
||||
|
||||
|
||||
class WirelessMethodType(IntEnum):
|
||||
|
||||
@@ -134,9 +134,10 @@ class NetworkManager(DBusInterfaceProxy):
|
||||
async def check_connectivity(self, *, force: bool = False) -> ConnectivityState:
|
||||
"""Check the connectivity of the host."""
|
||||
if force:
|
||||
return await self.connected_dbus.call("check_connectivity")
|
||||
else:
|
||||
return await self.connected_dbus.get("connectivity")
|
||||
return ConnectivityState(
|
||||
await self.connected_dbus.call("check_connectivity")
|
||||
)
|
||||
return ConnectivityState(await self.connected_dbus.get("connectivity"))
|
||||
|
||||
async def connect(self, bus: MessageBus) -> None:
|
||||
"""Connect to system's D-Bus."""
|
||||
|
||||
@@ -69,7 +69,7 @@ class NetworkConnection(DBusInterfaceProxy):
|
||||
@dbus_property
|
||||
def state(self) -> ConnectionStateType:
|
||||
"""Return the state of the connection."""
|
||||
return self.properties[DBUS_ATTR_STATE]
|
||||
return ConnectionStateType(self.properties[DBUS_ATTR_STATE])
|
||||
|
||||
@property
|
||||
def state_flags(self) -> set[ConnectionStateFlags]:
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
"""NetworkInterface object for Network Manager."""
|
||||
|
||||
import logging
|
||||
from typing import Any
|
||||
|
||||
from dbus_fast.aio.message_bus import MessageBus
|
||||
@@ -23,6 +24,8 @@ from .connection import NetworkConnection
|
||||
from .setting import NetworkSetting
|
||||
from .wireless import NetworkWireless
|
||||
|
||||
_LOGGER: logging.Logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class NetworkInterface(DBusInterfaceProxy):
|
||||
"""NetworkInterface object represents Network Manager Device objects.
|
||||
@@ -57,7 +60,15 @@ class NetworkInterface(DBusInterfaceProxy):
|
||||
@dbus_property
|
||||
def type(self) -> DeviceType:
|
||||
"""Return interface type."""
|
||||
return self.properties[DBUS_ATTR_DEVICE_TYPE]
|
||||
try:
|
||||
return DeviceType(self.properties[DBUS_ATTR_DEVICE_TYPE])
|
||||
except ValueError:
|
||||
_LOGGER.debug(
|
||||
"Unknown device type %s for %s, treating as UNKNOWN",
|
||||
self.properties[DBUS_ATTR_DEVICE_TYPE],
|
||||
self.object_path,
|
||||
)
|
||||
return DeviceType.UNKNOWN
|
||||
|
||||
@property
|
||||
@dbus_property
|
||||
|
||||
@@ -5,8 +5,6 @@ from ...coresys import CoreSys
|
||||
from ..const import UnsupportedReason
|
||||
from .base import EvaluateBase
|
||||
|
||||
SUPPORTED_OS = ["Debian GNU/Linux 12 (bookworm)"]
|
||||
|
||||
|
||||
def setup(coresys: CoreSys) -> EvaluateBase:
|
||||
"""Initialize evaluation-setup function."""
|
||||
@@ -33,6 +31,4 @@ class EvaluateOperatingSystem(EvaluateBase):
|
||||
|
||||
async def evaluate(self) -> bool:
|
||||
"""Run evaluation."""
|
||||
if self.sys_os.available:
|
||||
return False
|
||||
return self.sys_host.info.operating_system not in SUPPORTED_OS
|
||||
return not self.sys_os.available
|
||||
|
||||
@@ -184,3 +184,20 @@ async def test_interface_becomes_unmanaged(
|
||||
assert wireless.is_connected is False
|
||||
assert eth0.connection is None
|
||||
assert connection.is_connected is False
|
||||
|
||||
|
||||
async def test_unknown_device_type(
|
||||
device_eth0_service: DeviceService, dbus_session_bus: MessageBus
|
||||
):
|
||||
"""Test unknown device types are handled gracefully."""
|
||||
interface = NetworkInterface("/org/freedesktop/NetworkManager/Devices/1")
|
||||
await interface.connect(dbus_session_bus)
|
||||
|
||||
# Emit an unknown device type (e.g., 1000 which doesn't exist in the enum)
|
||||
device_eth0_service.emit_properties_changed({"DeviceType": 1000})
|
||||
await device_eth0_service.ping()
|
||||
|
||||
# Should return UNKNOWN instead of crashing
|
||||
assert interface.type == DeviceType.UNKNOWN
|
||||
# Wireless should be None since it's not a wireless device
|
||||
assert interface.wireless is None
|
||||
|
||||
@@ -5,10 +5,7 @@ from unittest.mock import MagicMock, patch
|
||||
|
||||
from supervisor.const import CoreState
|
||||
from supervisor.coresys import CoreSys
|
||||
from supervisor.resolution.evaluations.operating_system import (
|
||||
SUPPORTED_OS,
|
||||
EvaluateOperatingSystem,
|
||||
)
|
||||
from supervisor.resolution.evaluations.operating_system import EvaluateOperatingSystem
|
||||
|
||||
|
||||
async def test_evaluation(coresys: CoreSys):
|
||||
@@ -25,13 +22,7 @@ async def test_evaluation(coresys: CoreSys):
|
||||
assert operating_system.reason in coresys.resolution.unsupported
|
||||
|
||||
coresys.os._available = True
|
||||
await operating_system()
|
||||
assert operating_system.reason not in coresys.resolution.unsupported
|
||||
coresys.os._available = False
|
||||
|
||||
coresys.host._info = MagicMock(
|
||||
operating_system=SUPPORTED_OS[0], timezone=None, timezone_tzinfo=None
|
||||
)
|
||||
assert coresys.os.available
|
||||
await operating_system()
|
||||
assert operating_system.reason not in coresys.resolution.unsupported
|
||||
|
||||
|
||||
Reference in New Issue
Block a user