mirror of
https://github.com/home-assistant/supervisor.git
synced 2025-07-13 04:06:33 +00:00
Rename unsupported reason container to software (#3240)
* Rename unsupported reason container to software * rename in tests
This commit is contained in:
parent
03f0a136ab
commit
ef5b6a5f4c
@ -28,7 +28,6 @@ class UnsupportedReason(str, Enum):
|
|||||||
"""Reasons for unsupported status."""
|
"""Reasons for unsupported status."""
|
||||||
|
|
||||||
APPARMOR = "apparmor"
|
APPARMOR = "apparmor"
|
||||||
CONTAINER = "container"
|
|
||||||
CONTENT_TRUST = "content_trust"
|
CONTENT_TRUST = "content_trust"
|
||||||
DBUS = "dbus"
|
DBUS = "dbus"
|
||||||
DOCKER_CONFIGURATION = "docker_configuration"
|
DOCKER_CONFIGURATION = "docker_configuration"
|
||||||
@ -39,6 +38,7 @@ class UnsupportedReason(str, Enum):
|
|||||||
OS = "os"
|
OS = "os"
|
||||||
OS_AGENT = "os_agent"
|
OS_AGENT = "os_agent"
|
||||||
PRIVILEGED = "privileged"
|
PRIVILEGED = "privileged"
|
||||||
|
SOFTWARE = "software"
|
||||||
SOURCE_MODS = "source_mods"
|
SOURCE_MODS = "source_mods"
|
||||||
SYSTEMD = "systemd"
|
SYSTEMD = "systemd"
|
||||||
|
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
"""Evaluation class for container."""
|
"""Evaluation class for container."""
|
||||||
import logging
|
import logging
|
||||||
from typing import Any
|
|
||||||
|
|
||||||
from docker.errors import DockerException
|
from docker.errors import DockerException
|
||||||
from requests import RequestException
|
from requests import RequestException
|
||||||
@ -18,7 +17,7 @@ from .base import EvaluateBase
|
|||||||
|
|
||||||
_LOGGER: logging.Logger = logging.getLogger(__name__)
|
_LOGGER: logging.Logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
DOCKER_IMAGE_DENYLIST = [
|
UNHEALTHY_IMAGES = [
|
||||||
"watchtower",
|
"watchtower",
|
||||||
"ouroboros",
|
"ouroboros",
|
||||||
]
|
]
|
||||||
@ -41,7 +40,7 @@ class EvaluateContainer(EvaluateBase):
|
|||||||
@property
|
@property
|
||||||
def reason(self) -> UnsupportedReason:
|
def reason(self) -> UnsupportedReason:
|
||||||
"""Return a UnsupportedReason enum."""
|
"""Return a UnsupportedReason enum."""
|
||||||
return UnsupportedReason.CONTAINER
|
return UnsupportedReason.SOFTWARE
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def on_failure(self) -> str:
|
def on_failure(self) -> str:
|
||||||
@ -69,32 +68,32 @@ class EvaluateContainer(EvaluateBase):
|
|||||||
self._images.clear()
|
self._images.clear()
|
||||||
|
|
||||||
for image in await self.sys_run_in_executor(self._get_images):
|
for image in await self.sys_run_in_executor(self._get_images):
|
||||||
for tag in image.tags:
|
self.sys_resolution.evaluate.cached_images.add(image)
|
||||||
self.sys_resolution.evaluate.cached_images.add(tag)
|
|
||||||
|
|
||||||
# Evalue system
|
image_name = image.partition(":")[0]
|
||||||
image_name = tag.partition(":")[0]
|
if image_name not in self.known_images:
|
||||||
if image_name not in self.known_images:
|
self._images.add(image_name)
|
||||||
self._images.add(image_name)
|
if any(
|
||||||
if any(
|
image_name.split("/")[-1].startswith(unhealthy)
|
||||||
image_name.split("/")[-1].startswith(deny_name)
|
for unhealthy in UNHEALTHY_IMAGES
|
||||||
for deny_name in DOCKER_IMAGE_DENYLIST
|
):
|
||||||
):
|
_LOGGER.error(
|
||||||
_LOGGER.error(
|
"Found image in unhealthy image list '%s' on the host",
|
||||||
"Found image in deny-list '%s' on the host", image_name
|
image_name,
|
||||||
)
|
)
|
||||||
self.sys_resolution.unhealthy = UnhealthyReason.DOCKER
|
self.sys_resolution.unhealthy = UnhealthyReason.DOCKER
|
||||||
|
|
||||||
return len(self._images) != 0
|
return len(self._images) != 0
|
||||||
|
|
||||||
def _get_images(self) -> list[Any]:
|
def _get_images(self) -> set[str]:
|
||||||
"""Return a list of images."""
|
"""Return a set of images."""
|
||||||
images = []
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
images = [
|
return {
|
||||||
container.image for container in self.sys_docker.containers.list()
|
image
|
||||||
]
|
for container in self.sys_docker.containers.list()
|
||||||
|
if (config := container.attrs.get("Config")) is not None
|
||||||
|
and (image := config.get("Image")) is not None
|
||||||
|
}
|
||||||
except (DockerException, RequestException) as err:
|
except (DockerException, RequestException) as err:
|
||||||
_LOGGER.error("Corrupt docker overlayfs detect: %s", err)
|
_LOGGER.error("Corrupt docker overlayfs detect: %s", err)
|
||||||
self.sys_resolution.create_issue(
|
self.sys_resolution.create_issue(
|
||||||
@ -103,4 +102,4 @@ class EvaluateContainer(EvaluateBase):
|
|||||||
suggestions=[SuggestionType.EXECUTE_REPAIR],
|
suggestions=[SuggestionType.EXECUTE_REPAIR],
|
||||||
)
|
)
|
||||||
|
|
||||||
return images
|
return {}
|
||||||
|
@ -6,6 +6,7 @@ from docker.errors import DockerException
|
|||||||
|
|
||||||
from supervisor.const import CoreState
|
from supervisor.const import CoreState
|
||||||
from supervisor.coresys import CoreSys
|
from supervisor.coresys import CoreSys
|
||||||
|
from supervisor.resolution.const import UnhealthyReason
|
||||||
from supervisor.resolution.evaluations.container import EvaluateContainer
|
from supervisor.resolution.evaluations.container import EvaluateContainer
|
||||||
|
|
||||||
|
|
||||||
@ -31,22 +32,20 @@ async def test_evaluation(coresys: CoreSys):
|
|||||||
coresys.core.state = CoreState.RUNNING
|
coresys.core.state = CoreState.RUNNING
|
||||||
|
|
||||||
assert container.reason not in coresys.resolution.unsupported
|
assert container.reason not in coresys.resolution.unsupported
|
||||||
|
assert UnhealthyReason.DOCKER not in coresys.resolution.unhealthy
|
||||||
|
|
||||||
with patch(
|
with patch(
|
||||||
"supervisor.resolution.evaluations.container.EvaluateContainer._get_images",
|
"supervisor.resolution.evaluations.container.EvaluateContainer._get_images",
|
||||||
return_value=[
|
return_value=[
|
||||||
MagicMock(
|
"armhfbuild/watchtower:latest",
|
||||||
tags=[
|
"concerco/watchtowerv6:10.0.2",
|
||||||
"armhfbuild/watchtower:latest",
|
"containrrr/watchtower:1.1",
|
||||||
"concerco/watchtowerv6:10.0.2",
|
"pyouroboros/ouroboros:1.4.3",
|
||||||
"containrrr/watchtower:1.1",
|
|
||||||
"pyouroboros/ouroboros:1.4.3",
|
|
||||||
]
|
|
||||||
)
|
|
||||||
],
|
],
|
||||||
):
|
):
|
||||||
await container()
|
await container()
|
||||||
assert container.reason in coresys.resolution.unsupported
|
assert container.reason in coresys.resolution.unsupported
|
||||||
|
assert UnhealthyReason.DOCKER in coresys.resolution.unhealthy
|
||||||
|
|
||||||
assert coresys.resolution.evaluate.cached_images == {
|
assert coresys.resolution.evaluate.cached_images == {
|
||||||
"armhfbuild/watchtower:latest",
|
"armhfbuild/watchtower:latest",
|
||||||
@ -57,7 +56,7 @@ async def test_evaluation(coresys: CoreSys):
|
|||||||
|
|
||||||
with patch(
|
with patch(
|
||||||
"supervisor.resolution.evaluations.container.EvaluateContainer._get_images",
|
"supervisor.resolution.evaluations.container.EvaluateContainer._get_images",
|
||||||
return_value=[MagicMock(tags=[])],
|
return_value=[],
|
||||||
):
|
):
|
||||||
await container()
|
await container()
|
||||||
assert container.reason not in coresys.resolution.unsupported
|
assert container.reason not in coresys.resolution.unsupported
|
||||||
|
@ -112,10 +112,10 @@ async def test_resolution_create_issue_suggestion(coresys: CoreSys):
|
|||||||
@pytest.mark.asyncio
|
@pytest.mark.asyncio
|
||||||
async def test_resolution_dismiss_unsupported(coresys: CoreSys):
|
async def test_resolution_dismiss_unsupported(coresys: CoreSys):
|
||||||
"""Test resolution manager dismiss unsupported reason."""
|
"""Test resolution manager dismiss unsupported reason."""
|
||||||
coresys.resolution.unsupported = UnsupportedReason.CONTAINER
|
coresys.resolution.unsupported = UnsupportedReason.SOFTWARE
|
||||||
|
|
||||||
coresys.resolution.dismiss_unsupported(UnsupportedReason.CONTAINER)
|
coresys.resolution.dismiss_unsupported(UnsupportedReason.SOFTWARE)
|
||||||
assert UnsupportedReason.CONTAINER not in coresys.resolution.unsupported
|
assert UnsupportedReason.SOFTWARE not in coresys.resolution.unsupported
|
||||||
|
|
||||||
with pytest.raises(ResolutionError):
|
with pytest.raises(ResolutionError):
|
||||||
coresys.resolution.dismiss_unsupported(UnsupportedReason.CONTAINER)
|
coresys.resolution.dismiss_unsupported(UnsupportedReason.SOFTWARE)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user