Forbid controller and compute servers to be different versions.

Report last compute server error to clients and display in the server summary.
This commit is contained in:
grossmj 2018-08-22 16:54:43 +07:00
parent 59ce105a50
commit 089d25c79d
6 changed files with 38 additions and 8 deletions

View File

@ -29,7 +29,7 @@ from ..utils import parse_version
from ..utils.images import list_images from ..utils.images import list_images
from ..utils.asyncio import locked_coroutine from ..utils.asyncio import locked_coroutine
from ..controller.controller_error import ControllerError from ..controller.controller_error import ControllerError
from ..version import __version__ from ..version import __version__, __version_info__
import logging import logging
@ -95,6 +95,7 @@ class Compute:
self._set_auth(user, password) self._set_auth(user, password)
self._cpu_usage_percent = None self._cpu_usage_percent = None
self._memory_usage_percent = None self._memory_usage_percent = None
self._last_error = None
self._capabilities = { self._capabilities = {
"version": None, "version": None,
"node_types": [] "node_types": []
@ -301,7 +302,8 @@ class Compute:
"connected": self._connected, "connected": self._connected,
"cpu_usage_percent": self._cpu_usage_percent, "cpu_usage_percent": self._cpu_usage_percent,
"memory_usage_percent": self._memory_usage_percent, "memory_usage_percent": self._memory_usage_percent,
"capabilities": self._capabilities "capabilities": self._capabilities,
"last_error": self._last_error
} }
@asyncio.coroutine @asyncio.coroutine
@ -404,7 +406,7 @@ class Compute:
Check if remote server is accessible Check if remote server is accessible
""" """
if not self._connected and not self._closed: if not self._connected and not self._closed and self.host:
try: try:
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")
@ -428,16 +430,36 @@ class Compute:
raise aiohttp.web.HTTPConflict(text="Invalid server url for server {}".format(self._id)) raise aiohttp.web.HTTPConflict(text="Invalid server url for server {}".format(self._id))
if "version" not in response.json: if "version" not in response.json:
msg = "The server {} is not a GNS3 server".format(self._id)
log.error(msg)
self._http_session.close() self._http_session.close()
raise aiohttp.web.HTTPConflict(text="The server {} is not a GNS3 server".format(self._id)) raise aiohttp.web.HTTPConflict(text=msg)
self._capabilities = response.json self._capabilities = response.json
if parse_version(__version__)[:2] != parse_version(response.json["version"])[:2]:
self._http_session.close() if response.json["version"].split("-")[0] != __version__.split("-")[0]:
raise aiohttp.web.HTTPConflict(text="The server {} versions are not compatible {} != {}".format(self._id, __version__, response.json["version"])) msg = "GNS3 controller version {} is not the same as compute server {} version {}".format(__version__,
self._name,
response.json["version"])
if __version_info__[3] == 0:
# Stable release
log.error(msg)
self._http_session.close()
self._last_error = msg
raise aiohttp.web.HTTPConflict(text=msg)
elif parse_version(__version__)[:2] != parse_version(response.json["version"])[:2]:
# We don't allow different major version to interact even with dev build
log.error(msg)
self._http_session.close()
self._last_error = msg
raise aiohttp.web.HTTPConflict(text=msg)
else:
msg = "{}\nUsing different versions may result in unexpected problems. Please use at your own risk.".format(msg)
self._controller.notification.emit("log.warning", {"message": msg})
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._connection_failure = 0
self._last_error = None
self._controller.notification.emit("compute.updated", self.__json__()) self._controller.notification.emit("compute.updated", self.__json__())
@asyncio.coroutine @asyncio.coroutine

View File

@ -336,6 +336,8 @@ class GNS3VM:
self._controller.notification.emit("log.warning", {"message": msg}) self._controller.notification.emit("log.warning", {"message": msg})
except ComputeError as e: except ComputeError as e:
log.warning("Could not check the VM is in the same subnet as the local server: {}".format(e)) log.warning("Could not check the VM is in the same subnet as the local server: {}".format(e))
except aiohttp.web.HTTPConflict as e:
log.warning("Could not check the VM is in the same subnet as the local server: {}".format(e.text))
@locked_coroutine @locked_coroutine
def _suspend(self): def _suspend(self):

View File

@ -104,6 +104,10 @@ COMPUTE_OBJECT_SCHEMA = {
"maximum": 100, "maximum": 100,
"minimum": 0 "minimum": 0
}, },
"last_error": {
"description": "Last error on the compute",
"type": ["string", "null"]
},
"capabilities": CAPABILITIES_SCHEMA "capabilities": CAPABILITIES_SCHEMA
}, },
"additionalProperties": False, "additionalProperties": False,

View File

@ -23,7 +23,7 @@
# or negative for a release candidate or beta (after the base version # or negative for a release candidate or beta (after the base version
# number has been incremented) # number has been incremented)
__version__ = "2.1.10dev1" __version__ = "2.1.10dev2"
__version_info__ = (2, 1, 10, 99) __version_info__ = (2, 1, 10, 99)
# If it's a git checkout try to add the commit # If it's a git checkout try to add the commit

View File

@ -277,6 +277,7 @@ def test_json(compute):
"cpu_usage_percent": None, "cpu_usage_percent": None,
"memory_usage_percent": None, "memory_usage_percent": None,
"connected": True, "connected": True,
"last_error": None,
"capabilities": { "capabilities": {
"version": None, "version": None,
"node_types": [] "node_types": []

View File

@ -131,6 +131,7 @@ def test_compute_list(http_controller, controller):
'name': 'My super server', 'name': 'My super server',
'cpu_usage_percent': None, 'cpu_usage_percent': None,
'memory_usage_percent': None, 'memory_usage_percent': None,
'last_error': None,
'capabilities': { 'capabilities': {
'version': None, 'version': None,
'node_types': [] 'node_types': []