Skip to content

Commit

Permalink
Add implementation for DockerService.List (#199)
Browse files Browse the repository at this point in the history
  • Loading branch information
hdwhdw authored Jan 14, 2025
1 parent 744c673 commit 0430ada
Show file tree
Hide file tree
Showing 2 changed files with 78 additions and 3 deletions.
36 changes: 35 additions & 1 deletion host_modules/docker_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import docker
import signal
import errno
import json
import logging

MOD_NAME = "docker_service"
Expand Down Expand Up @@ -273,4 +274,37 @@ def load(self, image):
except FileNotFoundError:
return errno.ENOENT, "File {} not found.".format(image)
except Exception as e:
return 1, "Failed to load image {}: {}".format(image, str(e))
return 1, "Failed to load image {}: {}".format(image, str(e))

@host_service.method(
host_service.bus_name(MOD_NAME), in_signature="ba{sv}", out_signature="is"
)
def list(self, all, filter):
"""
List Docker containers.
Args:
all (bool): Whether to list all containers or only running ones.
filter (dict): Filters to apply when listing containers.
Returns:
tuple: A tuple containing the exit code (int) and a JSON string of the container list.
"""
try:
client = docker.from_env()
listed_containers = client.containers.list(all=all, filters=filter)
container_list = [
{
"id": container.id,
"name": container.name,
"status": container.status,
"image": container.image.tags[0] if container.image.tags else "",
"labels": container.labels,
"hash": container.image.id,
}
for container in listed_containers
]
logging.info("List of containers: {}".format(container_list))
return 0, json.dumps(container_list)
except Exception as e:
return 1, "Failed to list containers: {} {}".format(str(e), container_list)
45 changes: 43 additions & 2 deletions tests/host_modules/docker_service_test.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import errno
import docker
import json
from unittest import mock
from host_modules.docker_service import DockerService

Expand Down Expand Up @@ -303,7 +304,7 @@ def test_docker_load_success(self, MockInit, MockBusName, MockSystemBus):
assert rc == 0, "Return code is wrong"
mock_docker_client.images.load.assert_called_once_with(MockOpen.return_value)
MockOpen.assert_called_once_with("image.tar", "rb")

@mock.patch("dbus.SystemBus")
@mock.patch("dbus.service.BusName")
@mock.patch("dbus.service.Object.__init__")
Expand All @@ -317,4 +318,44 @@ def test_docker_load_file_not_found(self, MockInit, MockBusName, MockSystemBus):
rc, _ = docker_service.load("non_existent_image.tar")

assert rc == errno.ENOENT, "Return code is wrong"
MockOpen.assert_called_once_with("non_existent_image.tar", "rb")
MockOpen.assert_called_once_with("non_existent_image.tar", "rb")

@mock.patch("dbus.SystemBus")
@mock.patch("dbus.service.BusName")
@mock.patch("dbus.service.Object.__init__")
def test_docker_list_success(self, MockInit, MockBusName, MockSystemBus):
mock_docker_client = mock.Mock()
mock_container_1 = mock.Mock(id="1", status="running", image=mock.Mock(tags=["image1"], id="hash1"), labels={})
mock_container_2 = mock.Mock(id="2", status="exited", image=mock.Mock(tags=["image2"], id="hash2"), labels={})
# The name attribute needs to be explicitly set for the mock object.
mock_container_1.name = "container1"
mock_container_2.name = "container2"
mock_docker_client.containers.list.return_value = [
mock_container_1, mock_container_2
]

with mock.patch.object(docker, "from_env", return_value=mock_docker_client):
docker_service = DockerService(MOD_NAME)
rc, containers = docker_service.list(True, {})

assert rc == 0, "Return code is wrong {}".format(containers)
expected_containers = [
{
"id": "1",
"name": "container1",
"status": "running",
"image": "image1",
"labels": {},
"hash": "hash1",
},
{
"id": "2",
"name": "container2",
"status": "exited",
"image": "image2",
"labels": {},
"hash": "hash2",
},
]
assert json.loads(containers) == expected_containers, "Containers list is wrong"
mock_docker_client.containers.list.assert_called_once_with(all=True, filters={})

0 comments on commit 0430ada

Please sign in to comment.