mirror of
https://github.com/GNS3/gns3-server.git
synced 2025-01-18 07:23:47 +02:00
Clean GNS3 close if one remote server is down. Fixes #1357.
This commit is contained in:
parent
e3c8c9d484
commit
a54359d243
@ -481,6 +481,18 @@ class Controller:
|
|||||||
if compute in project.computes:
|
if compute in project.computes:
|
||||||
yield from project.close()
|
yield from project.close()
|
||||||
|
|
||||||
|
def compute_has_open_project(self, compute):
|
||||||
|
"""
|
||||||
|
Check is compute has a project opened.
|
||||||
|
|
||||||
|
:returns: True if a project is open
|
||||||
|
"""
|
||||||
|
|
||||||
|
for project in self._projects.values():
|
||||||
|
if compute in project.computes and project.status == "opened":
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
@asyncio.coroutine
|
@asyncio.coroutine
|
||||||
def delete_compute(self, compute_id):
|
def delete_compute(self, compute_id):
|
||||||
"""
|
"""
|
||||||
|
@ -409,12 +409,16 @@ class Compute:
|
|||||||
log.info("Connecting to compute '{}'".format(self._id))
|
log.info("Connecting to compute '{}'".format(self._id))
|
||||||
response = yield from self._run_http_query("GET", "/capabilities")
|
response = yield from self._run_http_query("GET", "/capabilities")
|
||||||
except ComputeError as e:
|
except ComputeError as e:
|
||||||
# Try to reconnect after 2 seconds if server unavailable only if not during tests (otherwise we create a ressources usage bomb)
|
log.warning("Cannot connect to compute '{}': {}".format(self._id, e))
|
||||||
|
# Try to reconnect after 2 seconds if server unavailable only if not during tests (otherwise we create a ressource 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:
|
||||||
|
if self.id != "local" and not self._controller.compute_has_open_project(self):
|
||||||
|
log.info("Not reconnecting to compute '{}' because there is no project opened on it".format(self._id))
|
||||||
|
return
|
||||||
self._connection_failure += 1
|
self._connection_failure += 1
|
||||||
# After 5 failure we close the project using the compute to avoid sync issues
|
# After 5 failure we close the project using the compute to avoid sync issues
|
||||||
if self._connection_failure == 5:
|
if self._connection_failure == 10:
|
||||||
log.warning("Cannot connect to compute '{}': {}".format(self._id, e))
|
log.error("Could not connect to compute '{}' after multiple attempts: {}".format(self._id, e))
|
||||||
yield from self._controller.close_compute_projects(self)
|
yield from self._controller.close_compute_projects(self)
|
||||||
asyncio.get_event_loop().call_later(2, lambda: asyncio_ensure_future(self._try_reconnect()))
|
asyncio.get_event_loop().call_later(2, lambda: asyncio_ensure_future(self._try_reconnect()))
|
||||||
return
|
return
|
||||||
@ -522,11 +526,7 @@ class Compute:
|
|||||||
else:
|
else:
|
||||||
data = json.dumps(data).encode("utf-8")
|
data = json.dumps(data).encode("utf-8")
|
||||||
try:
|
try:
|
||||||
log.debug("Attempting request to compute: {method} {url} {headers}".format(
|
log.debug("Attempting request to compute: {method} {url} {headers}".format(method=method, url=url, headers=headers))
|
||||||
method=method,
|
|
||||||
url=url,
|
|
||||||
headers=headers
|
|
||||||
))
|
|
||||||
response = yield from self._session().request(method, url, headers=headers, data=data, auth=self._auth, chunked=chunked, timeout=timeout)
|
response = yield from self._session().request(method, url, headers=headers, data=data, auth=self._auth, chunked=chunked, timeout=timeout)
|
||||||
except asyncio.TimeoutError:
|
except asyncio.TimeoutError:
|
||||||
raise ComputeError("Timeout error for {} call to {} after {}s".format(method, url, timeout))
|
raise ComputeError("Timeout error for {} call to {} after {}s".format(method, url, timeout))
|
||||||
@ -633,7 +633,7 @@ class Compute:
|
|||||||
else:
|
else:
|
||||||
images = sorted(images, key=itemgetter('image'))
|
images = sorted(images, key=itemgetter('image'))
|
||||||
except OSError as e:
|
except OSError as e:
|
||||||
raise ComputeError("Can't list images: {}".format(str(e)))
|
raise ComputeError("Cannot list images: {}".format(str(e)))
|
||||||
return images
|
return images
|
||||||
|
|
||||||
@asyncio.coroutine
|
@asyncio.coroutine
|
||||||
|
@ -146,7 +146,6 @@ class Project:
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def reset(self):
|
def reset(self):
|
||||||
"""
|
"""
|
||||||
Called when open/close a project. Cleanup internal stuff
|
Called when open/close a project. Cleanup internal stuff
|
||||||
@ -324,7 +323,7 @@ class Project:
|
|||||||
@property
|
@property
|
||||||
def auto_close(self):
|
def auto_close(self):
|
||||||
"""
|
"""
|
||||||
Should project automaticaly closed when client
|
Should project automatically closed when client
|
||||||
stop listening for notification
|
stop listening for notification
|
||||||
"""
|
"""
|
||||||
return self._auto_close
|
return self._auto_close
|
||||||
@ -765,7 +764,6 @@ class Project:
|
|||||||
except KeyError:
|
except KeyError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
for pict in pictures:
|
for pict in pictures:
|
||||||
os.remove(os.path.join(self.pictures_directory, pict))
|
os.remove(os.path.join(self.pictures_directory, pict))
|
||||||
except OSError as e:
|
except OSError as e:
|
||||||
|
Loading…
Reference in New Issue
Block a user