From 38db375fea8d1580ea13141a5e912d96651bb6da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joakim=20S=C3=B8rensen?= Date: Tue, 6 Oct 2020 11:26:56 +0200 Subject: [PATCH] Add docker/info API (#2095) --- supervisor/api/__init__.py | 35 ++++++++++++++++++----------------- supervisor/api/docker.py | 25 ++++++++++++++++++++++++- supervisor/const.py | 3 +++ tests/api/test_docker.py | 13 +++++++++++++ tests/conftest.py | 16 +++++++++++++++- 5 files changed, 73 insertions(+), 19 deletions(-) create mode 100644 tests/api/test_docker.py diff --git a/supervisor/api/__init__.py b/supervisor/api/__init__.py index c0ed69c3b..854dbd50e 100644 --- a/supervisor/api/__init__.py +++ b/supervisor/api/__init__.py @@ -52,27 +52,27 @@ class RestAPI(CoreSysAttributes): async def load(self) -> None: """Register REST API Calls.""" - self._register_supervisor() - self._register_host() - self._register_os() + self._register_addons() + self._register_audio() + self._register_auth() self._register_cli() - self._register_observer() - self._register_multicast() - self._register_network() + self._register_discovery() + self._register_dns() + self._register_docker() self._register_hardware() self._register_homeassistant() - self._register_proxy() - self._register_panel() - self._register_addons() - self._register_ingress() - self._register_snapshots() - self._register_discovery() - self._register_services() + self._register_host() self._register_info() - self._register_auth() - self._register_dns() - self._register_audio() - self._register_docker() + self._register_ingress() + self._register_multicast() + self._register_network() + self._register_observer() + self._register_os() + self._register_panel() + self._register_proxy() + self._register_services() + self._register_snapshots() + self._register_supervisor() def _register_host(self) -> None: """Register hostcontrol functions.""" @@ -417,6 +417,7 @@ class RestAPI(CoreSysAttributes): self.webapp.add_routes( [ + web.get("/docker/info", api_docker.info), web.get("/docker/registries", api_docker.registries), web.post("/docker/registries", api_docker.create_registry), web.post( diff --git a/supervisor/api/docker.py b/supervisor/api/docker.py index d51730ac3..f2895712c 100644 --- a/supervisor/api/docker.py +++ b/supervisor/api/docker.py @@ -5,7 +5,15 @@ from typing import Any, Dict from aiohttp import web import voluptuous as vol -from ..const import ATTR_HOSTNAME, ATTR_PASSWORD, ATTR_REGISTRIES, ATTR_USERNAME +from ..const import ( + ATTR_HOSTNAME, + ATTR_LOGGING, + ATTR_PASSWORD, + ATTR_REGISTRIES, + ATTR_STORAGE, + ATTR_USERNAME, + ATTR_VERSION, +) from ..coresys import CoreSysAttributes from .utils import api_process, api_validate @@ -51,3 +59,18 @@ class APIDocker(CoreSysAttributes): hostname = request.match_info.get(ATTR_HOSTNAME) del self.sys_docker.config.registries[hostname] self.sys_docker.config.save_data() + + @api_process + async def info(self, request: web.Request): + """Get docker info.""" + data_registries = {} + for hostname, registry in self.sys_docker.config.registries.items(): + data_registries[hostname] = { + ATTR_USERNAME: registry[ATTR_USERNAME], + } + return { + ATTR_VERSION: self.sys_docker.info.version, + ATTR_STORAGE: self.sys_docker.info.storage, + ATTR_LOGGING: self.sys_docker.info.logging, + ATTR_REGISTRIES: data_registries, + } diff --git a/supervisor/const.py b/supervisor/const.py index 97f6aea8a..9fe5d3ed2 100644 --- a/supervisor/const.py +++ b/supervisor/const.py @@ -116,6 +116,7 @@ ATTR_CHASSIS = "chassis" ATTR_CLI = "cli" ATTR_CONFIG = "config" ATTR_CONNECTIONS = "connections" +ATTR_CONTAINERS = "containers" ATTR_CPE = "cpe" ATTR_CPU_PERCENT = "cpu_percent" ATTR_CRYPTO = "crypto" @@ -163,6 +164,7 @@ ATTR_HOSTNAME = "hostname" ATTR_ICON = "icon" ATTR_ID = "id" ATTR_IMAGE = "image" +ATTR_IMAGES = "images" ATTR_INDEX = "index" ATTR_INGRESS = "ingress" ATTR_INGRESS_ENTRY = "ingress_entry" @@ -246,6 +248,7 @@ ATTR_STARTUP = "startup" ATTR_STATE = "state" ATTR_STATIC = "static" ATTR_STDIN = "stdin" +ATTR_STORAGE = "storage" ATTR_SUPERVISOR = "supervisor" ATTR_SUPPORTED = "supported" ATTR_SUPPORTED_ARCH = "supported_arch" diff --git a/tests/api/test_docker.py b/tests/api/test_docker.py new file mode 100644 index 000000000..3390ff284 --- /dev/null +++ b/tests/api/test_docker.py @@ -0,0 +1,13 @@ +"""Test Docker API.""" +import pytest + + +@pytest.mark.asyncio +async def test_api_docker_info(api_client): + """Test docker info api.""" + resp = await api_client.get("/docker/info") + result = await resp.json() + + assert result["data"]["logging"] == "journald" + assert result["data"]["storage"] == "overlay2" + assert result["data"]["version"] == "1.0.0" diff --git a/tests/conftest.py b/tests/conftest.py index ab0522212..04d93b346 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -31,8 +31,19 @@ def docker() -> DockerAPI: "supervisor.docker.DockerAPI.api", return_value=MagicMock() ), patch( "supervisor.docker.DockerAPI.images.list", return_value=images + ), patch( + "supervisor.docker.DockerAPI.info", + return_value=MagicMock(), + ), patch( + "supervisor.docker.DockerConfig", + return_value=MagicMock(), ): docker_obj = DockerAPI() + docker_obj.info.logging = "journald" + docker_obj.info.storage = "overlay2" + docker_obj.info.version = "1.0.0" + + docker_obj.config.registries = {} yield docker_obj @@ -105,6 +116,9 @@ async def coresys(loop, docker, dbus, network_manager, aiohttp_client) -> CoreSy coresys_obj._dbus = dbus coresys_obj._dbus.network = network_manager + # Mock docker + coresys_obj._docker = docker + yield coresys_obj @@ -126,7 +140,7 @@ def sys_supervisor(): @pytest.fixture -async def api_client(aiohttp_client, coresys): +async def api_client(aiohttp_client, coresys: CoreSys): """Fixture for RestAPI client.""" api = RestAPI(coresys) api.webapp = web.Application()