Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rename unsupported reason container to software #3240

Merged
merged 4 commits into from
Oct 19, 2021
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion supervisor/resolution/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ class UnsupportedReason(str, Enum):
"""Reasons for unsupported status."""

APPARMOR = "apparmor"
CONTAINER = "container"
CONTENT_TRUST = "content_trust"
DBUS = "dbus"
DOCKER_CONFIGURATION = "docker_configuration"
Expand All @@ -39,6 +38,7 @@ class UnsupportedReason(str, Enum):
OS = "os"
OS_AGENT = "os_agent"
PRIVILEGED = "privileged"
SOFTWARE = "software"
SOURCE_MODS = "source_mods"
SYSTEMD = "systemd"

Expand Down
51 changes: 25 additions & 26 deletions supervisor/resolution/evaluations/container.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
"""Evaluation class for container."""
import logging
from typing import Any

from docker.errors import DockerException
from requests import RequestException
Expand All @@ -18,7 +17,7 @@

_LOGGER: logging.Logger = logging.getLogger(__name__)

DOCKER_IMAGE_DENYLIST = [
UNHEALTHY_IMAGES = [
"watchtower",
"ouroboros",
]
Expand All @@ -41,7 +40,7 @@ def __init__(self, coresys: CoreSys) -> None:
@property
def reason(self) -> UnsupportedReason:
"""Return a UnsupportedReason enum."""
return UnsupportedReason.CONTAINER
return UnsupportedReason.SOFTWARE

@property
def on_failure(self) -> str:
Expand Down Expand Up @@ -69,32 +68,32 @@ async def evaluate(self) -> None:
self._images.clear()

for image in await self.sys_run_in_executor(self._get_images):
for tag in image.tags:
self.sys_resolution.evaluate.cached_images.add(tag)

# Evalue system
image_name = tag.partition(":")[0]
if image_name not in self.known_images:
self._images.add(image_name)
if any(
image_name.split("/")[-1].startswith(deny_name)
for deny_name in DOCKER_IMAGE_DENYLIST
):
_LOGGER.error(
"Found image in deny-list '%s' on the host", image_name
)
self.sys_resolution.unhealthy = UnhealthyReason.DOCKER
self.sys_resolution.evaluate.cached_images.add(image)

image_name = image.partition(":")[0]
if image_name not in self.known_images:
self._images.add(image_name)
if any(
image_name.split("/")[-1].startswith(unhealthy)
for unhealthy in UNHEALTHY_IMAGES
):
_LOGGER.error(
"Found image in unhealthy image list '%s' on the host",
image_name,
)
self.sys_resolution.unhealthy = UnhealthyReason.DOCKER

return len(self._images) != 0

def _get_images(self) -> list[Any]:
"""Return a list of images."""
images = []

def _get_images(self) -> set[str]:
"""Return a set of images."""
try:
images = [
container.image for container in self.sys_docker.containers.list()
]
return {
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:
_LOGGER.error("Corrupt docker overlayfs detect: %s", err)
self.sys_resolution.create_issue(
Expand All @@ -103,4 +102,4 @@ def _get_images(self) -> list[Any]:
suggestions=[SuggestionType.EXECUTE_REPAIR],
)

return images
return {}
17 changes: 8 additions & 9 deletions tests/resolution/evaluation/test_evaluate_container.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

from supervisor.const import CoreState
from supervisor.coresys import CoreSys
from supervisor.resolution.const import UnhealthyReason
from supervisor.resolution.evaluations.container import EvaluateContainer


Expand All @@ -31,22 +32,20 @@ async def test_evaluation(coresys: CoreSys):
coresys.core.state = CoreState.RUNNING

assert container.reason not in coresys.resolution.unsupported
assert UnhealthyReason.DOCKER not in coresys.resolution.unhealthy

with patch(
"supervisor.resolution.evaluations.container.EvaluateContainer._get_images",
return_value=[
MagicMock(
tags=[
"armhfbuild/watchtower:latest",
"concerco/watchtowerv6:10.0.2",
"containrrr/watchtower:1.1",
"pyouroboros/ouroboros:1.4.3",
]
)
"armhfbuild/watchtower:latest",
"concerco/watchtowerv6:10.0.2",
"containrrr/watchtower:1.1",
"pyouroboros/ouroboros:1.4.3",
],
):
await container()
assert container.reason in coresys.resolution.unsupported
assert UnhealthyReason.DOCKER in coresys.resolution.unhealthy

assert coresys.resolution.evaluate.cached_images == {
"armhfbuild/watchtower:latest",
Expand All @@ -57,7 +56,7 @@ async def test_evaluation(coresys: CoreSys):

with patch(
"supervisor.resolution.evaluations.container.EvaluateContainer._get_images",
return_value=[MagicMock(tags=[])],
return_value=[],
):
await container()
assert container.reason not in coresys.resolution.unsupported
Expand Down
8 changes: 4 additions & 4 deletions tests/resolution/test_resolution_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -112,10 +112,10 @@ async def test_resolution_create_issue_suggestion(coresys: CoreSys):
@pytest.mark.asyncio
async def test_resolution_dismiss_unsupported(coresys: CoreSys):
"""Test resolution manager dismiss unsupported reason."""
coresys.resolution.unsupported = UnsupportedReason.CONTAINER
coresys.resolution.unsupported = UnsupportedReason.SOFTWARE

coresys.resolution.dismiss_unsupported(UnsupportedReason.CONTAINER)
assert UnsupportedReason.CONTAINER not in coresys.resolution.unsupported
coresys.resolution.dismiss_unsupported(UnsupportedReason.SOFTWARE)
assert UnsupportedReason.SOFTWARE not in coresys.resolution.unsupported

with pytest.raises(ResolutionError):
coresys.resolution.dismiss_unsupported(UnsupportedReason.CONTAINER)
coresys.resolution.dismiss_unsupported(UnsupportedReason.SOFTWARE)