From c333e9451f4c0bc44668468ce56607588a7d4bc2 Mon Sep 17 00:00:00 2001 From: Julien Duponchelle Date: Wed, 24 Feb 2016 17:08:28 +0100 Subject: [PATCH] Fix pull of images Fix #445 --- gns3server/modules/docker/docker_vm.py | 12 ++--- tests/modules/docker/test_docker_vm.py | 62 ++++++++++++++++---------- 2 files changed, 44 insertions(+), 30 deletions(-) diff --git a/gns3server/modules/docker/docker_vm.py b/gns3server/modules/docker/docker_vm.py index 847a9386..6ad6df6b 100644 --- a/gns3server/modules/docker/docker_vm.py +++ b/gns3server/modules/docker/docker_vm.py @@ -150,7 +150,12 @@ class DockerVM(BaseVM): def create(self): """Creates the Docker container.""" - image_infos = yield from self._get_image_informations() + try: + image_infos = yield from self._get_image_informations() + except DockerHttp404Error: + log.info("Image %s is missing pulling it from docker hub", self._image) + yield from self.pull_image(self._image) + image_infos = yield from self._get_image_informations() params = { "Hostname": self._name, @@ -173,11 +178,6 @@ class DockerVM(BaseVM): if self._environment: params.update({"Env": [e.strip() for e in self._environment.split("\n")]}) - images = [i["image"] for i in (yield from self.manager.list_images())] - if self._image not in images: - log.info("Image %s is missing pulling it from docker hub", self._image) - yield from self.pull_image(self._image) - result = yield from self.manager.query("POST", "containers/create", data=params) self._cid = result['Id'] log.info("Docker container '{name}' [{id}] created".format( diff --git a/tests/modules/docker/test_docker_vm.py b/tests/modules/docker/test_docker_vm.py index 1704c4ca..47b08d95 100644 --- a/tests/modules/docker/test_docker_vm.py +++ b/tests/modules/docker/test_docker_vm.py @@ -23,7 +23,7 @@ from tests.utils import asyncio_patch from gns3server.ubridge.ubridge_error import UbridgeNamespaceError from gns3server.modules.docker.docker_vm import DockerVM -from gns3server.modules.docker.docker_error import DockerError +from gns3server.modules.docker.docker_error import * from gns3server.modules.docker import Docker @@ -161,33 +161,47 @@ def test_create_environment(loop, project, manager): def test_create_image_not_available(loop, project, manager): + call = 0 + + @asyncio.coroutine + def informations(): + nonlocal call + if call == 0: + call += 1 + raise DockerHttp404Error("missing") + else: + return {} + response = { "Id": "e90e34656806", "Warnings": [] } - with asyncio_patch("gns3server.modules.docker.Docker.list_images", return_value=[]) as mock_list_images: - with asyncio_patch("gns3server.modules.docker.DockerVM.pull_image", return_value=True) as mock_pull: - with asyncio_patch("gns3server.modules.docker.Docker.query", return_value=response) as mock: - vm = DockerVM("test", str(uuid.uuid4()), project, manager, "ubuntu") - loop.run_until_complete(asyncio.async(vm.create())) - mock.assert_called_with("POST", "containers/create", data={ - "Tty": True, - "OpenStdin": True, - "StdinOnce": False, - "HostConfig": - { - "CapAdd": ["ALL"], - "Binds": [], - "Privileged": True - }, - "Volumes": {}, - "NetworkDisabled": True, - "Name": "test", - "Hostname": "test", - "Image": "ubuntu" - }) - assert vm._cid == "e90e34656806" - mock_pull.assert_called_with("ubuntu") + + vm = DockerVM("test", str(uuid.uuid4()), project, manager, "ubuntu") + vm._get_image_informations = MagicMock() + vm._get_image_informations.side_effect = informations + + with asyncio_patch("gns3server.modules.docker.DockerVM.pull_image", return_value=True) as mock_pull: + with asyncio_patch("gns3server.modules.docker.Docker.query", return_value=response) as mock: + loop.run_until_complete(asyncio.async(vm.create())) + mock.assert_called_with("POST", "containers/create", data={ + "Tty": True, + "OpenStdin": True, + "StdinOnce": False, + "HostConfig": + { + "CapAdd": ["ALL"], + "Binds": [], + "Privileged": True + }, + "Volumes": {}, + "NetworkDisabled": True, + "Name": "test", + "Hostname": "test", + "Image": "ubuntu" + }) + assert vm._cid == "e90e34656806" + mock_pull.assert_called_with("ubuntu") def test_get_container_state(loop, vm):