diff --git a/CHANGELOG b/CHANGELOG index 059c85b7..9e50db48 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,19 @@ # Change Log +## 1.5.0rc2 15/06/2016 + +* Fix black screen with Qt app in Docker container +* Detect when command in the container exit +* Docker when the aux console exit and restart it +* Pass by default the environment variable container=docker +* Fix busybox binary location +* Avoid loosing console port for Docker +* Workaround a crash in x11vnc +* Delete volume when dropping the container +* Catch connection reset in ioucon +* Delete vlan.dat for L2IOL during config import. Fixes #1285. +* Copy original ressources from VOLUMES + ## 1.5.0rc1 01/06/2016 * Save an restore docker permission diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 74bba784..408ccb52 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -18,6 +18,10 @@ it on https://github.com/GNS3/gns3-gui we will take care of the triage. For bugs specific to the GNS3 VM, please report on https://github.com/GNS3/gns3-vm +## Security issues + +For security issues please keep it private and send an email to developers@gns3.net + ## Asking for new features The best is to start a discussion on the community website in order to get feedback diff --git a/gns3server/compute/docker/docker_vm.py b/gns3server/compute/docker/docker_vm.py index b73ea734..70b43d37 100644 --- a/gns3server/compute/docker/docker_vm.py +++ b/gns3server/compute/docker/docker_vm.py @@ -279,7 +279,7 @@ class DockerVM(BaseNode): "Binds": self._mount_binds(image_infos) }, "Volumes": {}, - "Env": [], + "Env": ["container=docker"], # Systemd compliant: https://github.com/GNS3/gns3-server/issues/573 "Cmd": [], "Entrypoint": image_infos.get("Config", {"Entrypoint": []})["Entrypoint"] } @@ -306,6 +306,7 @@ class DockerVM(BaseNode): if self._console_type == "vnc": yield from self._start_vnc() + params["Env"].append("QT_GRAPHICSSYSTEM=native") # To fix a Qt issue: https://github.com/GNS3/gns3-server/issues/556 params["Env"].append("DISPLAY=:{}".format(self._display)) params["HostConfig"]["Binds"].append("/tmp/.X11-unix/:/tmp/.X11-unix/") @@ -384,7 +385,7 @@ class DockerVM(BaseNode): # We can not use the API because docker doesn't expose a websocket api for exec # https://github.com/GNS3/gns3-gui/issues/1039 process = yield from asyncio.subprocess.create_subprocess_exec( - "docker", "exec", "-i", self._cid, "/gns3/bin/busybox", "script", "-qfc", "/gns3/bin/busybox sh", "/dev/null", + "docker", "exec", "-i", self._cid, "/gns3/bin/busybox", "script", "-qfc", "while true; do /gns3/bin/busybox sh; done", "/dev/null", stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.STDOUT, stdin=asyncio.subprocess.PIPE) @@ -493,7 +494,9 @@ class DockerVM(BaseNode): out.feed_eof() ws.close() break + yield from self.stop() + @asyncio.coroutine def is_running(self): """Checks if the container is running. @@ -535,21 +538,21 @@ class DockerVM(BaseNode): if state == "paused": yield from self.unpause() - yield from self._fix_permissions() - - # t=5 number of seconds to wait before killing the container - try: - yield from self.manager.query("POST", "containers/{}/stop".format(self._cid), params={"t": 5}) - log.info("Docker container '{name}' [{image}] stopped".format(name=self._name, image=self._image)) - except DockerHttp304Error: - # Container is already stopped - pass - finally: - self.status = "stopped" + if state != "stopped": + yield from self._fix_permissions() + # t=5 number of seconds to wait before killing the container + try: + yield from self.manager.query("POST", "containers/{}/stop".format(self._cid), params={"t": 5}) + log.info("Docker container '{name}' [{image}] stopped".format( + name=self._name, image=self._image)) + except DockerHttp304Error: + # Container is already stopped + pass # Ignore runtime error because when closing the server except RuntimeError as e: log.debug("Docker runtime error when closing: {}".format(str(e))) return + self.status = "stopped" @asyncio.coroutine def pause(self): diff --git a/tests/compute/docker/test_docker_vm.py b/tests/compute/docker/test_docker_vm.py index 49254269..0bf611d0 100644 --- a/tests/compute/docker/test_docker_vm.py +++ b/tests/compute/docker/test_docker_vm.py @@ -105,6 +105,7 @@ def test_create(loop, project, manager): "Hostname": "test", "Image": "ubuntu:latest", "Env": [ + "container=docker", "GNS3_MAX_ETHERNET=eth0", "GNS3_VOLUMES=/etc/network" ], @@ -143,6 +144,7 @@ def test_create_with_tag(loop, project, manager): "Hostname": "test", "Image": "ubuntu:16.04", "Env": [ + "container=docker", "GNS3_MAX_ETHERNET=eth0", "GNS3_VOLUMES=/etc/network" ], @@ -185,8 +187,10 @@ def test_create_vnc(loop, project, manager): "Hostname": "test", "Image": "ubuntu:latest", "Env": [ + "container=docker", "GNS3_MAX_ETHERNET=eth0", "GNS3_VOLUMES=/etc/network", + "QT_GRAPHICSSYSTEM=native", "DISPLAY=:42" ], "Entrypoint": ["/gns3/init.sh"], @@ -229,6 +233,7 @@ def test_create_start_cmd(loop, project, manager): "Hostname": "test", "Image": "ubuntu:latest", "Env": [ + "container=docker", "GNS3_MAX_ETHERNET=eth0", "GNS3_VOLUMES=/etc/network" ] @@ -261,6 +266,7 @@ def test_create_environment(loop, project, manager): "Privileged": True }, "Env": [ + "container=docker", "GNS3_MAX_ETHERNET=eth0", "GNS3_VOLUMES=/etc/network", "YES=1", @@ -320,6 +326,7 @@ def test_create_image_not_available(loop, project, manager): "Hostname": "test", "Image": "ubuntu:latest", "Env": [ + "container=docker", "GNS3_MAX_ETHERNET=eth0", "GNS3_VOLUMES=/etc/network" ], @@ -540,6 +547,7 @@ def test_update(loop, vm): "Hostname": "test", "Image": "ubuntu:latest", "Env": [ + "container=docker", "GNS3_MAX_ETHERNET=eth0", "GNS3_VOLUMES=/etc/network" ], @@ -608,6 +616,7 @@ def test_update_running(loop, vm): "Hostname": "test", "Image": "ubuntu:latest", "Env": [ + "container=docker", "GNS3_MAX_ETHERNET=eth0", "GNS3_VOLUMES=/etc/network" ], @@ -904,7 +913,7 @@ def test_start_aux(vm, loop): with asyncio_patch("asyncio.subprocess.create_subprocess_exec", return_value=MagicMock()) as mock_exec: loop.run_until_complete(asyncio.async(vm._start_aux())) - mock_exec.assert_called_with('docker', 'exec', '-i', 'e90e34656842', '/gns3/bin/busybox', 'script', '-qfc', '/gns3/bin/busybox sh', '/dev/null', stderr=asyncio.subprocess.STDOUT, stdin=asyncio.subprocess.PIPE, stdout=asyncio.subprocess.PIPE) + mock_exec.assert_called_with('docker', 'exec', '-i', 'e90e34656842', '/gns3/bin/busybox', 'script', '-qfc', 'while true; do /gns3/bin/busybox sh; done', '/dev/null', stderr=asyncio.subprocess.STDOUT, stdin=asyncio.subprocess.PIPE, stdout=asyncio.subprocess.PIPE) def test_create_network_interfaces(vm):