mirror of
https://github.com/GNS3/gns3-server
synced 2024-12-26 00:38:10 +00:00
Add total RAM, CPUs and disk size to servers summary as well as disk usage in percent. Fixes https://github.com/GNS3/gns3-server/issues/1532
This commit is contained in:
parent
00a6765405
commit
3dc4ea46d6
@ -80,9 +80,13 @@ 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._disk_usage_percent = None
|
||||||
self._last_error = None
|
self._last_error = None
|
||||||
self._capabilities = {
|
self._capabilities = {
|
||||||
"version": None,
|
"version": None,
|
||||||
|
"cpus": None,
|
||||||
|
"memory": None,
|
||||||
|
"disk_size": None,
|
||||||
"node_types": []
|
"node_types": []
|
||||||
}
|
}
|
||||||
self.name = name
|
self.name = name
|
||||||
@ -270,6 +274,10 @@ class Compute:
|
|||||||
def memory_usage_percent(self):
|
def memory_usage_percent(self):
|
||||||
return self._memory_usage_percent
|
return self._memory_usage_percent
|
||||||
|
|
||||||
|
@property
|
||||||
|
def disk_usage_percent(self):
|
||||||
|
return self._disk_usage_percent
|
||||||
|
|
||||||
def __json__(self, topology_dump=False):
|
def __json__(self, topology_dump=False):
|
||||||
"""
|
"""
|
||||||
:param topology_dump: Filter to keep only properties require for saving on disk
|
:param topology_dump: Filter to keep only properties require for saving on disk
|
||||||
@ -292,6 +300,7 @@ 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,
|
||||||
|
"disk_usage_percent": self._disk_usage_percent,
|
||||||
"capabilities": self._capabilities,
|
"capabilities": self._capabilities,
|
||||||
"last_error": self._last_error
|
"last_error": self._last_error
|
||||||
}
|
}
|
||||||
@ -437,6 +446,7 @@ class Compute:
|
|||||||
if action == "ping":
|
if action == "ping":
|
||||||
self._cpu_usage_percent = event["cpu_usage_percent"]
|
self._cpu_usage_percent = event["cpu_usage_percent"]
|
||||||
self._memory_usage_percent = event["memory_usage_percent"]
|
self._memory_usage_percent = event["memory_usage_percent"]
|
||||||
|
self._disk_usage_percent = event["disk_usage_percent"]
|
||||||
#FIXME: slow down number of compute events
|
#FIXME: slow down number of compute events
|
||||||
self._controller.notification.controller_emit("compute.updated", self.__json__())
|
self._controller.notification.controller_emit("compute.updated", self.__json__())
|
||||||
else:
|
else:
|
||||||
@ -461,6 +471,7 @@ class Compute:
|
|||||||
|
|
||||||
self._cpu_usage_percent = None
|
self._cpu_usage_percent = None
|
||||||
self._memory_usage_percent = None
|
self._memory_usage_percent = None
|
||||||
|
self._disk_usage_percent = None
|
||||||
self._controller.notification.controller_emit("compute.updated", self.__json__())
|
self._controller.notification.controller_emit("compute.updated", self.__json__())
|
||||||
|
|
||||||
def _getUrl(self, path):
|
def _getUrl(self, path):
|
||||||
|
@ -16,11 +16,13 @@
|
|||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
|
import psutil
|
||||||
|
|
||||||
from gns3server.web.route import Route
|
from gns3server.web.route import Route
|
||||||
from gns3server.schemas.capabilities import CAPABILITIES_SCHEMA
|
from gns3server.schemas.capabilities import CAPABILITIES_SCHEMA
|
||||||
from gns3server.version import __version__
|
from gns3server.version import __version__
|
||||||
from gns3server.compute import MODULES
|
from gns3server.compute import MODULES
|
||||||
|
from gns3server.utils.path import get_default_project_directory
|
||||||
|
|
||||||
|
|
||||||
class CapabilitiesHandler:
|
class CapabilitiesHandler:
|
||||||
@ -38,5 +40,8 @@ class CapabilitiesHandler:
|
|||||||
response.json({
|
response.json({
|
||||||
"version": __version__,
|
"version": __version__,
|
||||||
"platform": sys.platform,
|
"platform": sys.platform,
|
||||||
|
"cpus": psutil.cpu_count(logical=True),
|
||||||
|
"memory": psutil.virtual_memory().total,
|
||||||
|
"disk_size": psutil.disk_usage(get_default_project_directory()).total,
|
||||||
"node_types": node_types
|
"node_types": node_types
|
||||||
})
|
})
|
||||||
|
@ -20,12 +20,12 @@ import asyncio
|
|||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
import psutil
|
import psutil
|
||||||
import tempfile
|
|
||||||
|
|
||||||
from gns3server.web.route import Route
|
from gns3server.web.route import Route
|
||||||
from gns3server.compute.project_manager import ProjectManager
|
from gns3server.compute.project_manager import ProjectManager
|
||||||
from gns3server.compute import MODULES
|
from gns3server.compute import MODULES
|
||||||
from gns3server.utils.cpu_percent import CpuPercent
|
from gns3server.utils.cpu_percent import CpuPercent
|
||||||
|
from gns3server.utils.path import get_default_project_directory
|
||||||
|
|
||||||
from gns3server.schemas.project import (
|
from gns3server.schemas.project import (
|
||||||
PROJECT_OBJECT_SCHEMA,
|
PROJECT_OBJECT_SCHEMA,
|
||||||
@ -211,6 +211,7 @@ class ProjectHandler:
|
|||||||
# Non blocking call in order to get cpu usage. First call will return 0
|
# Non blocking call in order to get cpu usage. First call will return 0
|
||||||
stats["cpu_usage_percent"] = CpuPercent.get(interval=None)
|
stats["cpu_usage_percent"] = CpuPercent.get(interval=None)
|
||||||
stats["memory_usage_percent"] = psutil.virtual_memory().percent
|
stats["memory_usage_percent"] = psutil.virtual_memory().percent
|
||||||
|
stats["disk_usage_percent"] = psutil.disk_usage(get_default_project_directory()).percent
|
||||||
return {"action": "ping", "event": stats}
|
return {"action": "ping", "event": stats}
|
||||||
|
|
||||||
@Route.get(
|
@Route.get(
|
||||||
|
@ -25,6 +25,7 @@ from gns3server.schemas.server_statistics import SERVER_STATISTICS_SCHEMA
|
|||||||
from gns3server.compute.port_manager import PortManager
|
from gns3server.compute.port_manager import PortManager
|
||||||
from gns3server.utils.cpu_percent import CpuPercent
|
from gns3server.utils.cpu_percent import CpuPercent
|
||||||
from gns3server.version import __version__
|
from gns3server.version import __version__
|
||||||
|
from gns3server.utils.path import get_default_project_directory
|
||||||
from aiohttp.web import HTTPConflict
|
from aiohttp.web import HTTPConflict
|
||||||
|
|
||||||
|
|
||||||
@ -61,7 +62,7 @@ class ServerHandler:
|
|||||||
load_average_percent = [int(x / psutil.cpu_count() * 100) for x in psutil.getloadavg()]
|
load_average_percent = [int(x / psutil.cpu_count() * 100) for x in psutil.getloadavg()]
|
||||||
memory_percent = int(psutil.virtual_memory().percent)
|
memory_percent = int(psutil.virtual_memory().percent)
|
||||||
swap_percent = int(psutil.swap_memory().percent)
|
swap_percent = int(psutil.swap_memory().percent)
|
||||||
disk_usage_percent = int(psutil.disk_usage('/').percent)
|
disk_usage_percent = int(psutil.disk_usage(get_default_project_directory()).percent)
|
||||||
except psutil.Error as e:
|
except psutil.Error as e:
|
||||||
raise HTTPConflict(text="Psutil error detected: {}".format(e))
|
raise HTTPConflict(text="Psutil error detected: {}".format(e))
|
||||||
response.json({"memory_total": memory_total,
|
response.json({"memory_total": memory_total,
|
||||||
|
@ -20,6 +20,7 @@ import json
|
|||||||
import psutil
|
import psutil
|
||||||
|
|
||||||
from gns3server.utils.cpu_percent import CpuPercent
|
from gns3server.utils.cpu_percent import CpuPercent
|
||||||
|
from gns3server.utils.path import get_default_project_directory
|
||||||
|
|
||||||
|
|
||||||
class NotificationQueue(asyncio.Queue):
|
class NotificationQueue(asyncio.Queue):
|
||||||
@ -55,6 +56,7 @@ class NotificationQueue(asyncio.Queue):
|
|||||||
# Non blocking call in order to get cpu usage. First call will return 0
|
# Non blocking call in order to get cpu usage. First call will return 0
|
||||||
msg["cpu_usage_percent"] = CpuPercent.get(interval=None)
|
msg["cpu_usage_percent"] = CpuPercent.get(interval=None)
|
||||||
msg["memory_usage_percent"] = psutil.virtual_memory().percent
|
msg["memory_usage_percent"] = psutil.virtual_memory().percent
|
||||||
|
msg["disk_usage_percent"] = psutil.disk_usage(get_default_project_directory()).percent
|
||||||
return msg
|
return msg
|
||||||
|
|
||||||
async def get_json(self, timeout):
|
async def get_json(self, timeout):
|
||||||
|
@ -36,7 +36,19 @@ CAPABILITIES_SCHEMA = {
|
|||||||
"platform": {
|
"platform": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"description": "Platform where the compute is running"
|
"description": "Platform where the compute is running"
|
||||||
}
|
},
|
||||||
|
"cpus": {
|
||||||
|
"description": "Number of CPUs on this compute. Read only",
|
||||||
|
"type": ["integer", "null"],
|
||||||
|
},
|
||||||
|
"memory": {
|
||||||
|
"description": "Amount of memory on this compute. Read only",
|
||||||
|
"type": ["integer", "null"],
|
||||||
|
},
|
||||||
|
"disk_size": {
|
||||||
|
"description": "Disk size on this compute. Read only",
|
||||||
|
"type": ["integer", "null"],
|
||||||
|
},
|
||||||
},
|
},
|
||||||
"additionalProperties": False
|
"additionalProperties": False
|
||||||
}
|
}
|
||||||
|
@ -104,6 +104,12 @@ COMPUTE_OBJECT_SCHEMA = {
|
|||||||
"maximum": 100,
|
"maximum": 100,
|
||||||
"minimum": 0
|
"minimum": 0
|
||||||
},
|
},
|
||||||
|
"disk_usage_percent": {
|
||||||
|
"description": "Disk usage of the compute. Read only",
|
||||||
|
"type": ["number", "null"],
|
||||||
|
"maximum": 100,
|
||||||
|
"minimum": 0
|
||||||
|
},
|
||||||
"last_error": {
|
"last_error": {
|
||||||
"description": "Last error on the compute",
|
"description": "Last error on the compute",
|
||||||
"type": ["string", "null"]
|
"type": ["string", "null"]
|
||||||
|
@ -292,10 +292,14 @@ async def test_json(compute):
|
|||||||
"user": "test",
|
"user": "test",
|
||||||
"cpu_usage_percent": None,
|
"cpu_usage_percent": None,
|
||||||
"memory_usage_percent": None,
|
"memory_usage_percent": None,
|
||||||
|
"disk_usage_percent": None,
|
||||||
"connected": True,
|
"connected": True,
|
||||||
"last_error": None,
|
"last_error": None,
|
||||||
"capabilities": {
|
"capabilities": {
|
||||||
"version": None,
|
"version": None,
|
||||||
|
"cpus": None,
|
||||||
|
"memory": None,
|
||||||
|
"disk_size": None,
|
||||||
"node_types": []
|
"node_types": []
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,8 +18,10 @@
|
|||||||
|
|
||||||
import sys
|
import sys
|
||||||
import pytest
|
import pytest
|
||||||
|
import psutil
|
||||||
|
|
||||||
from gns3server.version import __version__
|
from gns3server.version import __version__
|
||||||
|
from gns3server.utils.path import get_default_project_directory
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.skipif(sys.platform.startswith("win"), reason="Not supported on Windows")
|
@pytest.mark.skipif(sys.platform.startswith("win"), reason="Not supported on Windows")
|
||||||
@ -27,7 +29,13 @@ async def test_get(compute_api, windows_platform):
|
|||||||
|
|
||||||
response = await compute_api.get('/capabilities')
|
response = await compute_api.get('/capabilities')
|
||||||
assert response.status == 200
|
assert response.status == 200
|
||||||
assert response.json == {'node_types': ['cloud', 'ethernet_hub', 'ethernet_switch', 'nat', 'vpcs', 'virtualbox', 'dynamips', 'frame_relay_switch', 'atm_switch', 'qemu', 'vmware', 'traceng', 'docker', 'iou'], 'version': __version__, 'platform': sys.platform}
|
assert response.json == {'node_types': ['cloud', 'ethernet_hub', 'ethernet_switch', 'nat', 'vpcs', 'virtualbox', 'dynamips', 'frame_relay_switch', 'atm_switch', 'qemu', 'vmware', 'traceng', 'docker', 'iou'],
|
||||||
|
'version': __version__,
|
||||||
|
'platform': sys.platform,
|
||||||
|
'cpus': psutil.cpu_count(logical=True),
|
||||||
|
'memory': psutil.virtual_memory().total,
|
||||||
|
'disk_size': psutil.disk_usage(get_default_project_directory()).total,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.skipif(sys.platform.startswith("win"), reason="Not supported on Windows")
|
@pytest.mark.skipif(sys.platform.startswith("win"), reason="Not supported on Windows")
|
||||||
@ -35,4 +43,10 @@ async def test_get_on_gns3vm(compute_api, on_gns3vm):
|
|||||||
|
|
||||||
response = await compute_api.get('/capabilities')
|
response = await compute_api.get('/capabilities')
|
||||||
assert response.status == 200
|
assert response.status == 200
|
||||||
assert response.json == {'node_types': ['cloud', 'ethernet_hub', 'ethernet_switch', 'nat', 'vpcs', 'virtualbox', 'dynamips', 'frame_relay_switch', 'atm_switch', 'qemu', 'vmware', 'traceng', 'docker', 'iou'], 'version': __version__, 'platform': sys.platform}
|
assert response.json == {'node_types': ['cloud', 'ethernet_hub', 'ethernet_switch', 'nat', 'vpcs', 'virtualbox', 'dynamips', 'frame_relay_switch', 'atm_switch', 'qemu', 'vmware', 'traceng', 'docker', 'iou'],
|
||||||
|
'version': __version__,
|
||||||
|
'platform': sys.platform,
|
||||||
|
'cpus': psutil.cpu_count(logical=True),
|
||||||
|
'memory': psutil.virtual_memory().total,
|
||||||
|
'disk_size': psutil.disk_usage(get_default_project_directory()).total,
|
||||||
|
}
|
||||||
|
@ -133,9 +133,13 @@ async def test_compute_list(controller_api):
|
|||||||
'name': 'My super server',
|
'name': 'My super server',
|
||||||
'cpu_usage_percent': None,
|
'cpu_usage_percent': None,
|
||||||
'memory_usage_percent': None,
|
'memory_usage_percent': None,
|
||||||
|
'disk_usage_percent': None,
|
||||||
'last_error': None,
|
'last_error': None,
|
||||||
'capabilities': {
|
'capabilities': {
|
||||||
'version': None,
|
'version': None,
|
||||||
|
'cpus': None,
|
||||||
|
'memory': None,
|
||||||
|
'disk_size': None,
|
||||||
'node_types': []
|
'node_types': []
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -53,7 +53,7 @@ def write_config(tmpdir, settings):
|
|||||||
return path
|
return path
|
||||||
|
|
||||||
|
|
||||||
def test_get_section_config(tmpdir):
|
def test_get_section_config(loop, tmpdir):
|
||||||
|
|
||||||
config = load_config(tmpdir, {
|
config = load_config(tmpdir, {
|
||||||
"Server": {
|
"Server": {
|
||||||
@ -63,7 +63,7 @@ def test_get_section_config(tmpdir):
|
|||||||
assert dict(config.get_section_config("Server")) == {"host": "127.0.0.1"}
|
assert dict(config.get_section_config("Server")) == {"host": "127.0.0.1"}
|
||||||
|
|
||||||
|
|
||||||
def test_set_section_config(tmpdir):
|
def test_set_section_config(loop, tmpdir):
|
||||||
|
|
||||||
config = load_config(tmpdir, {
|
config = load_config(tmpdir, {
|
||||||
"Server": {
|
"Server": {
|
||||||
@ -77,7 +77,7 @@ def test_set_section_config(tmpdir):
|
|||||||
assert dict(config.get_section_config("Server")) == {"host": "192.168.1.1", "local": "true"}
|
assert dict(config.get_section_config("Server")) == {"host": "192.168.1.1", "local": "true"}
|
||||||
|
|
||||||
|
|
||||||
def test_set(tmpdir):
|
def test_set(loop, tmpdir):
|
||||||
|
|
||||||
config = load_config(tmpdir, {
|
config = load_config(tmpdir, {
|
||||||
"Server": {
|
"Server": {
|
||||||
@ -90,7 +90,7 @@ def test_set(tmpdir):
|
|||||||
assert dict(config.get_section_config("Server")) == {"host": "192.168.1.1"}
|
assert dict(config.get_section_config("Server")) == {"host": "192.168.1.1"}
|
||||||
|
|
||||||
|
|
||||||
def test_reload(tmpdir):
|
def test_reload(loop, tmpdir):
|
||||||
|
|
||||||
config = load_config(tmpdir, {
|
config = load_config(tmpdir, {
|
||||||
"Server": {
|
"Server": {
|
||||||
|
Loading…
Reference in New Issue
Block a user