Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion aiohasupervisor/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,10 +86,11 @@ async def _request(
json: dict[str, Any] | None = None,
data: Any = None,
timeout: ClientTimeout | None = DEFAULT_TIMEOUT,
uri_encoded: bool = False,
) -> Response:
"""Handle a request to Supervisor."""
try:
url = URL(self.api_host).joinpath(uri)
url = URL(self.api_host).joinpath(uri, encoded=uri_encoded)
except ValueError as err:
raise SupervisorError from err

Expand Down Expand Up @@ -158,6 +159,7 @@ async def get(
params: dict[str, str] | MultiDict[str] | None = None,
response_type: ResponseType = ResponseType.JSON,
timeout: ClientTimeout | None = DEFAULT_TIMEOUT,
uri_encoded: bool = False,
) -> Response:
"""Handle a GET request to Supervisor."""
return await self._request(
Expand All @@ -166,6 +168,7 @@ async def get(
params=params,
response_type=response_type,
timeout=timeout,
uri_encoded=uri_encoded,
)

async def post(
Expand All @@ -177,6 +180,7 @@ async def post(
json: dict[str, Any] | None = None,
data: Any = None,
timeout: ClientTimeout | None = DEFAULT_TIMEOUT,
uri_encoded: bool = False,
) -> Response:
"""Handle a POST request to Supervisor."""
return await self._request(
Expand All @@ -187,6 +191,7 @@ async def post(
json=json,
data=data,
timeout=timeout,
uri_encoded=uri_encoded,
)

async def put(
Expand All @@ -196,6 +201,7 @@ async def put(
params: dict[str, str] | MultiDict[str] | None = None,
json: dict[str, Any] | None = None,
timeout: ClientTimeout | None = DEFAULT_TIMEOUT,
uri_encoded: bool = False,
) -> Response:
"""Handle a PUT request to Supervisor."""
return await self._request(
Expand All @@ -205,6 +211,7 @@ async def put(
response_type=ResponseType.NONE,
json=json,
timeout=timeout,
uri_encoded=uri_encoded,
)

async def delete(
Expand All @@ -214,6 +221,7 @@ async def delete(
params: dict[str, str] | MultiDict[str] | None = None,
json: dict[str, Any] | None = None,
timeout: ClientTimeout | None = DEFAULT_TIMEOUT,
uri_encoded: bool = False,
) -> Response:
"""Handle a DELETE request to Supervisor."""
return await self._request(
Expand All @@ -223,6 +231,7 @@ async def delete(
response_type=ResponseType.NONE,
json=json,
timeout=timeout,
uri_encoded=uri_encoded,
)

async def close(self) -> None:
Expand Down
30 changes: 30 additions & 0 deletions aiohasupervisor/host.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,23 @@
"""Host client for supervisor."""

import re
from urllib.parse import quote

from .client import _SupervisorComponentClient
from .const import TIMEOUT_60_SECONDS
from .exceptions import SupervisorError
from .models.host import (
HostInfo,
HostOptions,
NVMeStatus,
RebootOptions,
Service,
ServiceList,
ShutdownOptions,
)

RE_NVME_DEVICE = re.compile(r"^(?:[-A-Fa-f0-9]+|\/dev\/[-_a-z0-9]+)$")


class HostClient(_SupervisorComponentClient):
"""Handles host access in supervisor."""
Expand Down Expand Up @@ -47,4 +54,27 @@ async def services(self) -> list[Service]:
result = await self._client.get("host/services")
return ServiceList.from_dict(result.data).services

async def nvme_status(self, device: str | None = None) -> NVMeStatus:
"""Get NVMe status for a device.

Device can be the Host ID or device path (e.g. /dev/nvme0n1).
If omitted, returns status of datadisk if it is an nvme device.
"""
if device is not None:
# Encoding must be done here because something like /dev/nvme0n1 is
# valid and that won't work in the resource path. But that means we
# bypass part of the safety check that would normally raise on any
# encoded chars. So strict validation needs to be done here rather
# then letting Supervisor handle it like normal.
if not RE_NVME_DEVICE.match(device):
raise SupervisorError(f"Invalid device: {device}")

encoded = quote(device, safe="")
result = await self._client.get(
f"host/nvme/{encoded}/status", uri_encoded=True
)
else:
result = await self._client.get("host/nvme/status")
return NVMeStatus.from_dict(result.data)

# Omitted for now - Log endpoints
182 changes: 92 additions & 90 deletions aiohasupervisor/models/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@
from aiohasupervisor.models.host import (
HostInfo,
HostOptions,
NVMeStatus,
RebootOptions,
Service,
ServiceState,
Expand Down Expand Up @@ -152,130 +153,131 @@
)

__all__ = [
"HostFeature",
"SupervisorState",
"UpdateChannel",
"LogLevel",
"UpdateType",
"RootInfo",
"AvailableUpdate",
"AddonStage",
"AddonStartup",
"LOCATION_CLOUD_BACKUP",
"LOCATION_LOCAL_STORAGE",
"AccessPoint",
"AddonBoot",
"AddonBootConfig",
"CpuArch",
"Capability",
"AppArmor",
"SupervisorRole",
"AddonSet",
"AddonStage",
"AddonStartup",
"AddonState",
"StoreAddon",
"StoreAddonComplete",
"InstalledAddon",
"InstalledAddonComplete",
"AddonsOptions",
"AddonsConfigValidate",
"AddonsOptions",
"AddonsRebuild",
"AddonsSecurityOptions",
"AddonsStats",
"AddonsUninstall",
"Repository",
"StoreInfo",
"StoreAddonUpdate",
"StoreAddRepository",
"Check",
"CheckOptions",
"CheckType",
"ContextType",
"Issue",
"IssueType",
"ResolutionInfo",
"Suggestion",
"SuggestionType",
"UnhealthyReason",
"UnsupportedReason",
"SupervisorInfo",
"SupervisorOptions",
"SupervisorStats",
"SupervisorUpdateOptions",
"HomeAssistantInfo",
"HomeAssistantOptions",
"HomeAssistantRebuildOptions",
"HomeAssistantRestartOptions",
"HomeAssistantStats",
"HomeAssistantStopOptions",
"HomeAssistantUpdateOptions",
"RaucState",
"BootSlotName",
"BootSlot",
"OSInfo",
"OSUpdate",
"MigrateDataOptions",
"DataDisk",
"SetBootSlotOptions",
"GreenInfo",
"GreenOptions",
"YellowInfo",
"YellowOptions",
"LOCATION_CLOUD_BACKUP",
"LOCATION_LOCAL_STORAGE",
"AddonSet",
"AppArmor",
"AuthMethod",
"AvailableUpdate",
"Backup",
"BackupAddon",
"BackupComplete",
"BackupContent",
"BackupJob",
"BackupLocationAttributes",
"BackupType",
"BackupsInfo",
"BackupsOptions",
"BackupType",
"BootSlot",
"BootSlotName",
"CIFSMountRequest",
"CIFSMountResponse",
"Capability",
"Check",
"CheckOptions",
"CheckType",
"ContextType",
"CpuArch",
"DataDisk",
"Discovery",
"DiscoveryConfig",
"DockerNetwork",
"DownloadBackupOptions",
"Folder",
"FreezeOptions",
"FullBackupOptions",
"FullRestoreOptions",
"NewBackup",
"PartialBackupOptions",
"PartialRestoreOptions",
"RemoveBackupOptions",
"UploadBackupOptions",
"Discovery",
"DiscoveryConfig",
"AccessPoint",
"AuthMethod",
"DockerNetwork",
"InterfaceMethod",
"InterfaceType",
"GreenInfo",
"GreenOptions",
"HomeAssistantInfo",
"HomeAssistantOptions",
"HomeAssistantRebuildOptions",
"HomeAssistantRestartOptions",
"HomeAssistantStats",
"HomeAssistantStopOptions",
"HomeAssistantUpdateOptions",
"HostFeature",
"HostInfo",
"HostOptions",
"IPv4",
"IPv4Config",
"IPv6",
"IPv6Config",
"NetworkInfo",
"NetworkInterface",
"NetworkInterfaceConfig",
"Vlan",
"VlanConfig",
"Wifi",
"WifiConfig",
"WifiMode",
"HostInfo",
"HostOptions",
"RebootOptions",
"Service",
"ServiceState",
"ShutdownOptions",
"InstalledAddon",
"InstalledAddonComplete",
"InterfaceMethod",
"InterfaceType",
"Issue",
"IssueType",
"Job",
"JobCondition",
"JobError",
"JobsInfo",
"JobsOptions",
"CIFSMountRequest",
"CIFSMountResponse",
"LogLevel",
"MigrateDataOptions",
"MountCifsVersion",
"MountsInfo",
"MountsOptions",
"MountState",
"MountType",
"MountUsage",
"MountsInfo",
"MountsOptions",
"NFSMountRequest",
"NFSMountResponse",
"NVMeStatus",
"NetworkInfo",
"NetworkInterface",
"NetworkInterfaceConfig",
"NewBackup",
"OSInfo",
"OSUpdate",
"PartialBackupOptions",
"PartialRestoreOptions",
"RaucState",
"RebootOptions",
"RemoveBackupOptions",
"Repository",
"ResolutionInfo",
"RootInfo",
"Service",
"ServiceState",
"SetBootSlotOptions",
"ShutdownOptions",
"StoreAddRepository",
"StoreAddon",
"StoreAddonComplete",
"StoreAddonUpdate",
"StoreInfo",
"Suggestion",
"SuggestionType",
"SupervisorInfo",
"SupervisorOptions",
"SupervisorRole",
"SupervisorState",
"SupervisorStats",
"SupervisorUpdateOptions",
"UnhealthyReason",
"UnsupportedReason",
"UpdateChannel",
"UpdateType",
"UploadBackupOptions",
"Vlan",
"VlanConfig",
"Wifi",
"WifiConfig",
"WifiMode",
"YellowInfo",
"YellowOptions",
]
Loading