diff --git a/host_modules/docker_service.py b/host_modules/docker_service.py index a88ed368..a6a17737 100644 --- a/host_modules/docker_service.py +++ b/host_modules/docker_service.py @@ -251,3 +251,26 @@ def run(self, image, command, kwargs): return errno.ENOENT, "Image {} not found.".format(image) except Exception as e: return 1, "Failed to run image {}: {}".format(image, str(e)) + + @host_service.method( + host_service.bus_name(MOD_NAME), in_signature="s", out_signature="is" + ) + def load(self, image): + """ + Load a Docker image from a tar archive. + + Args: + image (str): The path to the tar archive containing the Docker image. + + Returns: + tuple: A tuple containing the exit code (int) and a message indicating the result of the operation. + """ + try: + client = docker.from_env() + with open(image, 'rb') as image_tar: + client.images.load(image_tar) + return 0, "Image {} has been loaded.".format(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)) \ No newline at end of file diff --git a/tests/host_modules/docker_service_test.py b/tests/host_modules/docker_service_test.py index 4152fbc8..3c9bd84c 100644 --- a/tests/host_modules/docker_service_test.py +++ b/tests/host_modules/docker_service_test.py @@ -287,3 +287,34 @@ def test_docker_run_fail_non_empty_command( docker_service = DockerService(MOD_NAME) rc, msg = docker_service.run("docker-syncd-brcm:latest", "rm -rf /", {}) assert rc == errno.EPERM, "Return code is wrong" + + @mock.patch("dbus.SystemBus") + @mock.patch("dbus.service.BusName") + @mock.patch("dbus.service.Object.__init__") + def test_docker_load_success(self, MockInit, MockBusName, MockSystemBus): + mock_docker_client = mock.Mock() + mock_docker_client.images.load.return_value = ["loaded_image"] + + with mock.patch("builtins.open", mock.mock_open(read_data="data")) as MockOpen, \ + mock.patch.object(docker, "from_env", return_value=mock_docker_client): + docker_service = DockerService(MOD_NAME) + rc, _ = docker_service.load("image.tar") + + 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__") + def test_docker_load_file_not_found(self, MockInit, MockBusName, MockSystemBus): + mock_docker_client = mock.Mock() + + with mock.patch("builtins.open", mock.mock_open()) as MockOpen, \ + mock.patch.object(docker, "from_env", return_value=mock_docker_client): + MockOpen.side_effect = FileNotFoundError + docker_service = DockerService(MOD_NAME) + 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") \ No newline at end of file