Rename unsupported reason container to software (#3240)

* Rename unsupported reason container to software

* rename in tests
This commit is contained in:
Joakim Sørensen 2021-10-19 11:26:58 +02:00 committed by GitHub
parent 03f0a136ab
commit ef5b6a5f4c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 37 additions and 39 deletions

View File

@ -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"

View File

@ -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 {}

View File

@ -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

View File

@ -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)