diff --git a/CHANGELOG b/CHANGELOG index 9e50db48..e7e59199 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,14 @@ # Change Log +## 1.5.0 27/06/2016 + +* Fix import of project with no disk +* Allow for (a lot) more docker container ports. Fixes #593. +* Raise an error if you try to use Docker on non Linux host +* Fix a crash in Docker if daemon stop to respond +* Fix a crash if Dynamips router has no initial configuration +* Kill ghosts process at startup (Dynamips, VPCS, Ubridge) + ## 1.5.0rc2 15/06/2016 * Fix black screen with Qt app in Docker container diff --git a/gns3server/compute/docker/__init__.py b/gns3server/compute/docker/__init__.py index d1b2e1c7..4521da13 100644 --- a/gns3server/compute/docker/__init__.py +++ b/gns3server/compute/docker/__init__.py @@ -114,7 +114,7 @@ class Docker(BaseManager): data=data, headers={"content-type": "application/json", }, ) - except aiohttp.ClientResponseError as e: + except (aiohttp.ClientResponseError, aiohttp.ClientOSError) as e: raise DockerError("Docker has returned an error: {}".format(str(e))) if response.status >= 300: body = yield from response.read() diff --git a/gns3server/compute/docker/docker_vm.py b/gns3server/compute/docker/docker_vm.py index a8f2126c..0bfc46ac 100644 --- a/gns3server/compute/docker/docker_vm.py +++ b/gns3server/compute/docker/docker_vm.py @@ -624,10 +624,10 @@ class DockerVM(BaseNode): adapter_number=adapter_number)) for index in range(4096): - if "veth-gns3-ext{}".format(index) not in psutil.net_if_addrs(): + if "veth-gns3-e{}".format(index) not in psutil.net_if_addrs(): adapter.ifc = "eth{}".format(str(index)) - adapter.host_ifc = "veth-gns3-ext{}".format(str(index)) - adapter.guest_ifc = "veth-gns3-int{}".format(str(index)) + adapter.host_ifc = "veth-gns3-e{}".format(str(index)) + adapter.guest_ifc = "veth-gns3-i{}".format(str(index)) break if not hasattr(adapter, "ifc"): raise DockerError("Adapter {adapter_number} couldn't allocate interface on Docker container '{name}'. Too many Docker interfaces already exists".format(name=self.name, @@ -663,6 +663,8 @@ class DockerVM(BaseNode): :param adapter_number: adapter number """ + if not self.ubridge: + return adapter = self._ethernet_adapters[adapter_number] try: @@ -704,6 +706,18 @@ class DockerVM(BaseNode): yield from self._ubridge_send('bridge start bridge{adapter}'.format(adapter=adapter_number)) + if self.status == "started" and self._ubridge_hypervisor and self._ubridge_hypervisor.is_running(): + # the container is running, let's add the UDP tunnel to connect to another node + yield from self._ubridge_hypervisor.send('bridge create bridge{}'.format(adapter_number)) + yield from self._ubridge_hypervisor.send('bridge add_nio_linux_raw bridge{adapter} {ifc}'.format(ifc=adapter.host_ifc, adapter=adapter_number)) + + yield from self._ubridge_hypervisor.send('bridge add_nio_udp bridge{adapter} {lport} {rhost} {rport}'.format(adapter=adapter_number, + lport=nio.lport, + rhost=nio.rhost, + rport=nio.rport)) + + yield from self._ubridge_hypervisor.send('bridge start bridge{adapter}'.format(adapter=adapter_number)) + adapter.add_nio(0, nio) log.info("Docker container '{name}' [{id}]: {nio} added to adapter {adapter_number}".format(name=self.name, id=self._id, diff --git a/gns3server/compute/iou/iou_vm.py b/gns3server/compute/iou/iou_vm.py index ab510ef4..4b623693 100644 --- a/gns3server/compute/iou/iou_vm.py +++ b/gns3server/compute/iou/iou_vm.py @@ -679,7 +679,10 @@ class IOUVM(BaseNode): except asyncio.TimeoutError: if self._iou_process.returncode is None: log.warn("IOU process {} is still running... killing it".format(self._iou_process.pid)) - self._iou_process.kill() + try: + self._iou_process.kill() + except ProcessLookupError: + pass self._iou_process = None if self.is_iouyap_running(): diff --git a/gns3server/web/route.py b/gns3server/web/route.py index 6e594749..22bad4c0 100644 --- a/gns3server/web/route.py +++ b/gns3server/web/route.py @@ -187,7 +187,7 @@ class Route(object): except aiohttp.web.HTTPBadRequest as e: response = Response(request=request, route=route) response.set_status(e.status) - response.json({"message": e.text, "status": e.status, "path": route, "request": request.json}) + response.json({"message": e.text, "status": e.status, "path": route, "request": request.json, "method": request.method}) except aiohttp.web.HTTPException as e: response = Response(request=request, route=route) response.set_status(e.status) diff --git a/tests/compute/docker/test_docker_vm.py b/tests/compute/docker/test_docker_vm.py index 11a3b809..802cfe66 100644 --- a/tests/compute/docker/test_docker_vm.py +++ b/tests/compute/docker/test_docker_vm.py @@ -692,10 +692,10 @@ def test_add_ubridge_connection(loop, vm): loop.run_until_complete(asyncio.async(vm._add_ubridge_connection(nio, 0, 42))) calls = [ - call.send("docker create_veth veth-gns3-ext0 veth-gns3-int0"), - call.send('docker move_to_ns veth-gns3-int0 42 eth0'), + call.send("docker create_veth veth-gns3-e0 veth-gns3-i0"), + call.send('docker move_to_ns veth-gns3-i0 42 eth0'), call.send('bridge create bridge0'), - call.send('bridge add_nio_linux_raw bridge0 veth-gns3-ext0'), + call.send('bridge add_nio_linux_raw bridge0 veth-gns3-e0'), call.send('bridge add_nio_udp bridge0 4242 127.0.0.1 4343'), call.send('bridge start_capture bridge0 "/tmp/capture.pcap"'), call.send('bridge start bridge0') @@ -712,8 +712,8 @@ def test_add_ubridge_connection_none_nio(loop, vm): loop.run_until_complete(asyncio.async(vm._add_ubridge_connection(nio, 0, 42))) calls = [ - call.send("docker create_veth veth-gns3-ext0 veth-gns3-int0"), - call.send('docker move_to_ns veth-gns3-int0 42 eth0'), + call.send("docker create_veth veth-gns3-e0 veth-gns3-i0"), + call.send('docker move_to_ns veth-gns3-i0 42 eth0'), ] # We need to check any_order ortherwise mock is confused by asyncio vm._ubridge_hypervisor.assert_has_calls(calls, any_order=True) @@ -740,7 +740,7 @@ def test_add_ubridge_connection_no_free_interface(loop, vm): with pytest.raises(DockerError): # We create fake ethernet interfaces for docker - interfaces = ["veth-gns3-ext{}".format(index) for index in range(4096)] + interfaces = ["veth-gns3-e{}".format(index) for index in range(4096)] with patch("psutil.net_if_addrs", return_value=interfaces): loop.run_until_complete(asyncio.async(vm._add_ubridge_connection(nio, 0, 42))) @@ -760,7 +760,7 @@ def test_delete_ubridge_connection(loop, vm): calls = [ call.send("bridge delete bridge0"), - call.send('docker delete_veth veth-gns3-ext0') + call.send('docker delete_veth veth-gns3-e0') ] vm._ubridge_hypervisor.assert_has_calls(calls, any_order=True)