From 82c99418b4c8aaa2e2501c498ccddb4bf82935b9 Mon Sep 17 00:00:00 2001 From: Julien Duponchelle Date: Wed, 11 Jan 2017 17:23:36 +0100 Subject: [PATCH] Fix If cloud interface is down the project doesn't open Fix https://github.com/GNS3/gns3-gui/issues/1751 --- gns3server/compute/builtin/nodes/cloud.py | 37 +++++++++++++------ .../handlers/api/compute/cloud_handler.py | 3 +- tests/compute/builtin/nodes/test_cloud.py | 6 ++- tests/handlers/api/compute/test_cloud.py | 2 +- 4 files changed, 33 insertions(+), 15 deletions(-) diff --git a/gns3server/compute/builtin/nodes/cloud.py b/gns3server/compute/builtin/nodes/cloud.py index dcf0c5cb..23bc525b 100644 --- a/gns3server/compute/builtin/nodes/cloud.py +++ b/gns3server/compute/builtin/nodes/cloud.py @@ -81,7 +81,7 @@ class Cloud(BaseNode): "project_id": self.project.id, "ports_mapping": self._ports_mapping, "interfaces": host_interfaces, - "status": "started"} + "status": self.status} @property def ports_mapping(self): @@ -118,9 +118,23 @@ class Cloud(BaseNode): Creates this cloud. """ - yield from self._start_ubridge() + yield from self.start() log.info('Cloud "{name}" [{id}] has been created'.format(name=self._name, id=self._id)) + @asyncio.coroutine + def start(self): + if self.status != "started": + if self._ubridge_hypervisor and self._ubridge_hypervisor.is_running(): + yield from self._stop_ubridge() + yield from self._start_ubridge() + for port_number in self._nios: + if self._nios[port_number]: + try: + yield from self._add_ubridge_connection(self._nios[port_number], port_number) + except (UbridgeError, NodeError) as e: + self.status = "stopped" + raise e + @asyncio.coroutine def close(self): """ @@ -280,18 +294,17 @@ class Cloud(BaseNode): port=port_number)) self._nios[port_number] = nio try: + yield from self.start() yield from self._add_ubridge_connection(nio, port_number) except NodeError as e: - del self._nios[port_number] - raise e + self.project.emit("log.error", {"message": str(e)}) + yield from self._stop_ubridge() + self.status = "stopped" # Cleanup stuff except UbridgeError as e: - try: - self._delete_ubridge_connection(port_number) - except UbridgeError: - pass - del self._nios[port_number] - raise e + self.project.emit("log.error", {"message": str(e)}) + yield from self._stop_ubridge() + self.status = "stopped" @asyncio.coroutine def _delete_ubridge_connection(self, port_number): @@ -327,7 +340,9 @@ class Cloud(BaseNode): port=port_number)) del self._nios[port_number] - yield from self._delete_ubridge_connection(port_number) + if self._ubridge_hypervisor and self._ubridge_hypervisor.is_running(): + yield from self._delete_ubridge_connection(port_number) + yield from self.start() return nio @asyncio.coroutine diff --git a/gns3server/handlers/api/compute/cloud_handler.py b/gns3server/handlers/api/compute/cloud_handler.py index ea0f1ec9..242fa534 100644 --- a/gns3server/handlers/api/compute/cloud_handler.py +++ b/gns3server/handlers/api/compute/cloud_handler.py @@ -135,7 +135,8 @@ class CloudHandler: description="Start a cloud") def start(request, response): - Builtin.instance().get_node(request.match_info["node_id"], project_id=request.match_info["project_id"]) + node = Builtin.instance().get_node(request.match_info["node_id"], project_id=request.match_info["project_id"]) + yield from node.start() response.set_status(204) @Route.post( diff --git a/tests/compute/builtin/nodes/test_cloud.py b/tests/compute/builtin/nodes/test_cloud.py index 462677f8..52687c97 100644 --- a/tests/compute/builtin/nodes/test_cloud.py +++ b/tests/compute/builtin/nodes/test_cloud.py @@ -43,7 +43,7 @@ def test_json_with_ports(on_gns3vm, project): "name": "cloud1", "node_id": cloud.id, "project_id": project.id, - "status": "started", + "status": "stopped", "ports_mapping": [ { "interface": "virbr0", @@ -69,7 +69,7 @@ def test_json_without_ports(on_gns3vm, project): "name": "cloud1", "node_id": cloud.id, "project_id": project.id, - "status": "started", + "status": "stopped", "ports_mapping": [ { "interface": "eth0", @@ -141,6 +141,7 @@ def test_linux_ethernet_raw_add_nio(linux_platform, project, async_run, nio): } ] cloud = Cloud("cloud1", str(uuid.uuid4()), project, MagicMock(), ports=ports) + cloud.status = "started" with asyncio_patch("gns3server.compute.builtin.nodes.cloud.Cloud._ubridge_send") as ubridge_mock: with patch("gns3server.compute.builtin.nodes.cloud.Cloud._interfaces", return_value=[{"name": "eth0"}]): @@ -167,6 +168,7 @@ def test_linux_ethernet_raw_add_nio_bridge(linux_platform, project, async_run, n } ] cloud = Cloud("cloud1", str(uuid.uuid4()), project, MagicMock(), ports=ports) + cloud.status = "started" with asyncio_patch("gns3server.compute.builtin.nodes.cloud.Cloud._ubridge_send") as ubridge_mock: with patch("gns3server.compute.builtin.nodes.cloud.Cloud._interfaces", return_value=[{"name": "bridge0"}]): diff --git a/tests/handlers/api/compute/test_cloud.py b/tests/handlers/api/compute/test_cloud.py index 7bfad05c..611d55c6 100644 --- a/tests/handlers/api/compute/test_cloud.py +++ b/tests/handlers/api/compute/test_cloud.py @@ -54,7 +54,7 @@ def test_cloud_get(http_compute, project, vm): assert response.route == "/projects/{project_id}/cloud/nodes/{node_id}" assert response.json["name"] == "Cloud 1" assert response.json["project_id"] == project.id - assert response.json["status"] == "started" + assert response.json["status"] == "stopped" def test_cloud_nio_create_udp(http_compute, vm):