mirror of
https://github.com/home-assistant/supervisor.git
synced 2025-07-24 09:36:31 +00:00
commit
2e4b545265
4
API.md
4
API.md
@ -252,6 +252,10 @@ return:
|
||||
}
|
||||
```
|
||||
|
||||
- GET `/host/logs`
|
||||
|
||||
Return host dmesg
|
||||
|
||||
- POST `/host/options`
|
||||
|
||||
```json
|
||||
|
@ -74,6 +74,7 @@ class RestAPI(CoreSysAttributes):
|
||||
self.webapp.add_routes(
|
||||
[
|
||||
web.get("/host/info", api_host.info),
|
||||
web.get("/host/logs", api_host.logs),
|
||||
web.post("/host/reboot", api_host.reboot),
|
||||
web.post("/host/shutdown", api_host.shutdown),
|
||||
web.post("/host/reload", api_host.reload),
|
||||
|
@ -1,24 +1,27 @@
|
||||
"""Init file for Supervisor host RESTful API."""
|
||||
import asyncio
|
||||
import logging
|
||||
from typing import Awaitable
|
||||
|
||||
from aiohttp import web
|
||||
import voluptuous as vol
|
||||
|
||||
from .utils import api_process, api_validate
|
||||
from ..const import (
|
||||
ATTR_HOSTNAME,
|
||||
ATTR_FEATURES,
|
||||
ATTR_KERNEL,
|
||||
ATTR_OPERATING_SYSTEM,
|
||||
ATTR_CHASSIS,
|
||||
ATTR_DEPLOYMENT,
|
||||
ATTR_STATE,
|
||||
ATTR_NAME,
|
||||
ATTR_DESCRIPTON,
|
||||
ATTR_SERVICES,
|
||||
ATTR_CPE,
|
||||
ATTR_DEPLOYMENT,
|
||||
ATTR_DESCRIPTON,
|
||||
ATTR_FEATURES,
|
||||
ATTR_HOSTNAME,
|
||||
ATTR_KERNEL,
|
||||
ATTR_NAME,
|
||||
ATTR_OPERATING_SYSTEM,
|
||||
ATTR_SERVICES,
|
||||
ATTR_STATE,
|
||||
CONTENT_TYPE_BINARY,
|
||||
)
|
||||
from ..coresys import CoreSysAttributes
|
||||
from .utils import api_process, api_process_raw, api_validate
|
||||
|
||||
_LOGGER: logging.Logger = logging.getLogger(__name__)
|
||||
|
||||
@ -107,3 +110,8 @@ class APIHost(CoreSysAttributes):
|
||||
"""Restart a service."""
|
||||
unit = request.match_info.get(SERVICE)
|
||||
return asyncio.shield(self.sys_host.services.restart(unit))
|
||||
|
||||
@api_process_raw(CONTENT_TYPE_BINARY)
|
||||
def logs(self, request: web.Request) -> Awaitable[bytes]:
|
||||
"""Return host kernel logs."""
|
||||
return self.sys_host.info.get_dmesg()
|
||||
|
@ -65,7 +65,7 @@ class HaCli(CoreSysAttributes, JsonConfig):
|
||||
|
||||
await self.instance.attach(tag=self.version)
|
||||
except DockerAPIError:
|
||||
_LOGGER.info("No Audio plugin Docker image %s found.", self.instance.image)
|
||||
_LOGGER.info("No cli plugin Docker image %s found.", self.instance.image)
|
||||
|
||||
# Install cli
|
||||
with suppress(CliError):
|
||||
@ -89,7 +89,7 @@ class HaCli(CoreSysAttributes, JsonConfig):
|
||||
|
||||
if self.latest_version:
|
||||
with suppress(DockerAPIError):
|
||||
await self.instance.install(self.latest_version)
|
||||
await self.instance.install(self.latest_version, latest=True)
|
||||
break
|
||||
_LOGGER.warning("Error on install cli plugin. Retry in 30sec")
|
||||
await asyncio.sleep(30)
|
||||
@ -111,10 +111,16 @@ class HaCli(CoreSysAttributes, JsonConfig):
|
||||
except DockerAPIError:
|
||||
_LOGGER.error("HA cli update fails")
|
||||
raise CliUpdateError() from None
|
||||
else:
|
||||
# Cleanup
|
||||
with suppress(DockerAPIError):
|
||||
await self.instance.cleanup()
|
||||
|
||||
# Cleanup
|
||||
with suppress(DockerAPIError):
|
||||
await self.instance.cleanup()
|
||||
|
||||
self.version = version
|
||||
self.save_data()
|
||||
|
||||
# Start cli
|
||||
await self.start()
|
||||
|
||||
async def start(self) -> None:
|
||||
"""Run cli."""
|
||||
|
@ -3,7 +3,7 @@ from enum import Enum
|
||||
from ipaddress import ip_network
|
||||
from pathlib import Path
|
||||
|
||||
SUPERVISOR_VERSION = "211"
|
||||
SUPERVISOR_VERSION = "212"
|
||||
|
||||
|
||||
URL_HASSIO_ADDONS = "https://github.com/home-assistant/hassio-addons"
|
||||
|
@ -165,15 +165,16 @@ class CoreDNS(JsonConfig, CoreSysAttributes):
|
||||
_LOGGER.warning("Version %s is already installed for CoreDNS", version)
|
||||
return
|
||||
|
||||
# Update
|
||||
try:
|
||||
await self.instance.update(version)
|
||||
except DockerAPIError:
|
||||
_LOGGER.error("CoreDNS update fails")
|
||||
raise CoreDNSUpdateError() from None
|
||||
else:
|
||||
# Cleanup
|
||||
with suppress(DockerAPIError):
|
||||
await self.instance.cleanup()
|
||||
|
||||
# Cleanup
|
||||
with suppress(DockerAPIError):
|
||||
await self.instance.cleanup()
|
||||
|
||||
self.version = version
|
||||
self.save_data()
|
||||
|
@ -1,9 +1,15 @@
|
||||
"""Info control for host."""
|
||||
import asyncio
|
||||
import logging
|
||||
from typing import Optional
|
||||
|
||||
from ..coresys import CoreSysAttributes
|
||||
from ..exceptions import HostNotSupportedError, DBusNotConnectedError, DBusError
|
||||
from ..exceptions import (
|
||||
HostNotSupportedError,
|
||||
HostError,
|
||||
DBusNotConnectedError,
|
||||
DBusError,
|
||||
)
|
||||
|
||||
_LOGGER: logging.Logger = logging.getLogger(__name__)
|
||||
|
||||
@ -45,6 +51,21 @@ class InfoCenter(CoreSysAttributes):
|
||||
"""Return local CPE."""
|
||||
return self.sys_dbus.hostname.cpe
|
||||
|
||||
async def get_dmesg(self) -> bytes:
|
||||
"""Return host dmesg output."""
|
||||
proc = await asyncio.create_subprocess_shell(
|
||||
"dmesg", stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.STDOUT
|
||||
)
|
||||
|
||||
# Get kernel log
|
||||
try:
|
||||
stdout, _ = await proc.communicate()
|
||||
except OSError as err:
|
||||
_LOGGER.error("Can't read kernel log: %s", err)
|
||||
raise HostError()
|
||||
|
||||
return stdout
|
||||
|
||||
async def update(self):
|
||||
"""Update properties over dbus."""
|
||||
_LOGGER.info("Update local host information")
|
||||
|
Loading…
x
Reference in New Issue
Block a user