mirror of
https://github.com/GNS3/gns3-server
synced 2024-12-26 00:38:10 +00:00
parent
60eea1f171
commit
3259ec1220
@ -270,6 +270,15 @@ class Controller:
|
|||||||
self.notification.emit("compute.updated", self._computes[compute_id].__json__())
|
self.notification.emit("compute.updated", self._computes[compute_id].__json__())
|
||||||
return self._computes[compute_id]
|
return self._computes[compute_id]
|
||||||
|
|
||||||
|
@asyncio.coroutine
|
||||||
|
def close_compute_projects(self, compute):
|
||||||
|
"""
|
||||||
|
Close projects running on a compute
|
||||||
|
"""
|
||||||
|
for project in self._projects.values():
|
||||||
|
if compute in project.computes:
|
||||||
|
yield from project.close()
|
||||||
|
|
||||||
@asyncio.coroutine
|
@asyncio.coroutine
|
||||||
def delete_compute(self, compute_id):
|
def delete_compute(self, compute_id):
|
||||||
"""
|
"""
|
||||||
@ -281,11 +290,7 @@ class Controller:
|
|||||||
compute = self.get_compute(compute_id)
|
compute = self.get_compute(compute_id)
|
||||||
except aiohttp.web.HTTPNotFound:
|
except aiohttp.web.HTTPNotFound:
|
||||||
return
|
return
|
||||||
|
yield from self.close_compute_projects(compute)
|
||||||
for project in self._projects.values():
|
|
||||||
if compute in project.computes:
|
|
||||||
yield from project.close()
|
|
||||||
|
|
||||||
yield from compute.close()
|
yield from compute.close()
|
||||||
del self._computes[compute_id]
|
del self._computes[compute_id]
|
||||||
self.save()
|
self.save()
|
||||||
|
@ -107,6 +107,8 @@ class Compute:
|
|||||||
# Cache of interfaces on remote host
|
# Cache of interfaces on remote host
|
||||||
self._interfaces_cache = None
|
self._interfaces_cache = None
|
||||||
|
|
||||||
|
self._connection_failure = 0
|
||||||
|
|
||||||
def _session(self):
|
def _session(self):
|
||||||
if self._http_session is None or self._http_session.closed is True:
|
if self._http_session is None or self._http_session.closed is True:
|
||||||
self._http_session = aiohttp.ClientSession(connector=aiohttp.TCPConnector(limit=None, force_close=True))
|
self._http_session = aiohttp.ClientSession(connector=aiohttp.TCPConnector(limit=None, force_close=True))
|
||||||
@ -344,14 +346,17 @@ class Compute:
|
|||||||
return StreamResponse(response)
|
return StreamResponse(response)
|
||||||
|
|
||||||
@asyncio.coroutine
|
@asyncio.coroutine
|
||||||
def http_query(self, method, path, data=None, **kwargs):
|
def http_query(self, method, path, data=None, dont_connect=False, **kwargs):
|
||||||
if not self._connected:
|
"""
|
||||||
|
:param dont_connect: If true do not reconnect if not connected
|
||||||
|
"""
|
||||||
|
if not self._connected and not dont_connect:
|
||||||
if self._id == "vm" and not self._controller.gns3vm.running:
|
if self._id == "vm" and not self._controller.gns3vm.running:
|
||||||
yield from self._controller.gns3vm.start()
|
yield from self._controller.gns3vm.start()
|
||||||
|
|
||||||
yield from self.connect()
|
yield from self.connect()
|
||||||
if not self._connected:
|
if not self._connected and not dont_connect:
|
||||||
raise aiohttp.web.HTTPConflict(text="Can't connect to {}".format(self._name))
|
raise ComputeError("Can't connect to {}".format(self._name))
|
||||||
response = yield from self._run_http_query(method, path, data=data, **kwargs)
|
response = yield from self._run_http_query(method, path, data=data, **kwargs)
|
||||||
return response
|
return response
|
||||||
|
|
||||||
@ -366,7 +371,12 @@ class Compute:
|
|||||||
except ComputeError:
|
except ComputeError:
|
||||||
# Try to reconnect after 2 seconds if server unavailable only if not during tests (otherwise we create a ressources usage bomb)
|
# Try to reconnect after 2 seconds if server unavailable only if not during tests (otherwise we create a ressources usage bomb)
|
||||||
if not hasattr(sys, "_called_from_test") or not sys._called_from_test:
|
if not hasattr(sys, "_called_from_test") or not sys._called_from_test:
|
||||||
|
self._connection_failure += 1
|
||||||
|
# After 5 failure we close the project using the compute to avoid sync issues
|
||||||
|
if self._connection_failure == 5:
|
||||||
|
yield from self._controller.close_compute_projects(self)
|
||||||
asyncio.get_event_loop().call_later(2, lambda: asyncio.async(self.connect()))
|
asyncio.get_event_loop().call_later(2, lambda: asyncio.async(self.connect()))
|
||||||
|
|
||||||
return
|
return
|
||||||
except aiohttp.web.HTTPNotFound:
|
except aiohttp.web.HTTPNotFound:
|
||||||
raise aiohttp.web.HTTPConflict(text="The server {} is not a GNS3 server or it's a 1.X server".format(self._id))
|
raise aiohttp.web.HTTPConflict(text="The server {} is not a GNS3 server or it's a 1.X server".format(self._id))
|
||||||
@ -383,6 +393,7 @@ class Compute:
|
|||||||
|
|
||||||
self._notifications = asyncio.gather(self._connect_notification())
|
self._notifications = asyncio.gather(self._connect_notification())
|
||||||
self._connected = True
|
self._connected = True
|
||||||
|
self._connection_failure = 0
|
||||||
self._controller.notification.emit("compute.updated", self.__json__())
|
self._controller.notification.emit("compute.updated", self.__json__())
|
||||||
|
|
||||||
@asyncio.coroutine
|
@asyncio.coroutine
|
||||||
|
@ -425,7 +425,7 @@ class Node:
|
|||||||
Stop a node
|
Stop a node
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
yield from self.post("/stop", timeout=240)
|
yield from self.post("/stop", timeout=240, dont_connect=True)
|
||||||
# We don't care if a node is down at this step
|
# We don't care if a node is down at this step
|
||||||
except (ComputeError, aiohttp.errors.ClientHttpProcessingError, aiohttp.web.HTTPError):
|
except (ComputeError, aiohttp.errors.ClientHttpProcessingError, aiohttp.web.HTTPError):
|
||||||
pass
|
pass
|
||||||
|
@ -541,7 +541,7 @@ class Project:
|
|||||||
yield from self.stop_all()
|
yield from self.stop_all()
|
||||||
for compute in self._project_created_on_compute:
|
for compute in self._project_created_on_compute:
|
||||||
try:
|
try:
|
||||||
yield from compute.post("/projects/{}/close".format(self._id))
|
yield from compute.post("/projects/{}/close".format(self._id), dont_connect=True)
|
||||||
# We don't care if a compute is down at this step
|
# We don't care if a compute is down at this step
|
||||||
except (ComputeError, aiohttp.web.HTTPError, aiohttp.ClientResponseError, TimeoutError):
|
except (ComputeError, aiohttp.web.HTTPError, aiohttp.ClientResponseError, TimeoutError):
|
||||||
pass
|
pass
|
||||||
|
@ -36,6 +36,7 @@ class Pool():
|
|||||||
Wait for all task to finish
|
Wait for all task to finish
|
||||||
"""
|
"""
|
||||||
pending = set()
|
pending = set()
|
||||||
|
exceptions = set()
|
||||||
while len(self._tasks) > 0 or len(pending) > 0:
|
while len(self._tasks) > 0 or len(pending) > 0:
|
||||||
while len(self._tasks) > 0 and len(pending) < self._concurrency:
|
while len(self._tasks) > 0 and len(pending) < self._concurrency:
|
||||||
task, args, kwargs = self._tasks.pop(0)
|
task, args, kwargs = self._tasks.pop(0)
|
||||||
@ -43,7 +44,9 @@ class Pool():
|
|||||||
(done, pending) = yield from asyncio.wait(pending, return_when=asyncio.FIRST_COMPLETED)
|
(done, pending) = yield from asyncio.wait(pending, return_when=asyncio.FIRST_COMPLETED)
|
||||||
for task in done:
|
for task in done:
|
||||||
if task.exception():
|
if task.exception():
|
||||||
raise task.exception()
|
exceptions.add(task.exception())
|
||||||
|
if len(exceptions) > 0:
|
||||||
|
raise exceptions.pop()
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
|
@ -366,7 +366,7 @@ def test_stop(node, compute, project, async_run):
|
|||||||
compute.post = AsyncioMagicMock()
|
compute.post = AsyncioMagicMock()
|
||||||
|
|
||||||
async_run(node.stop())
|
async_run(node.stop())
|
||||||
compute.post.assert_called_with("/projects/{}/vpcs/nodes/{}/stop".format(node.project.id, node.id), timeout=240)
|
compute.post.assert_called_with("/projects/{}/vpcs/nodes/{}/stop".format(node.project.id, node.id), timeout=240, dont_connect=True)
|
||||||
|
|
||||||
|
|
||||||
def test_suspend(node, compute, project, async_run):
|
def test_suspend(node, compute, project, async_run):
|
||||||
|
Loading…
Reference in New Issue
Block a user