From 4195bdc7dddb8d011dd4ae82ea9fc66d0d8df19b Mon Sep 17 00:00:00 2001 From: grossmj Date: Mon, 13 Oct 2014 19:53:17 -0600 Subject: [PATCH 1/4] Auto idle-pc feature and improvements/bug fixes for GNS3 preferences. --- gns3server/modules/dynamips/backends/vm.py | 72 +++++++++++++++++++++ gns3server/modules/dynamips/nodes/router.py | 9 +++ gns3server/modules/dynamips/schemas/vm.py | 14 ++++ 3 files changed, 95 insertions(+) diff --git a/gns3server/modules/dynamips/backends/vm.py b/gns3server/modules/dynamips/backends/vm.py index 6a471620..4d09f9bd 100644 --- a/gns3server/modules/dynamips/backends/vm.py +++ b/gns3server/modules/dynamips/backends/vm.py @@ -17,6 +17,7 @@ import os import base64 +import time from gns3server.modules import IModule from ..dynamips_error import DynamipsError @@ -61,6 +62,7 @@ from ..schemas.vm import VM_STOP_CAPTURE_SCHEMA from ..schemas.vm import VM_SAVE_CONFIG_SCHEMA from ..schemas.vm import VM_EXPORT_CONFIG_SCHEMA from ..schemas.vm import VM_IDLEPCS_SCHEMA +from ..schemas.vm import VM_AUTO_IDLEPC_SCHEMA from ..schemas.vm import VM_ALLOCATE_UDP_PORT_SCHEMA from ..schemas.vm import VM_ADD_NIO_SCHEMA from ..schemas.vm import VM_DELETE_NIO_SCHEMA @@ -704,6 +706,76 @@ class VM(object): "idlepcs": idlepcs} self.send_response(response) + @IModule.route("dynamips.vm.auto_idlepc") + def vm_auto_idlepc(self, request): + """ + Auto idle-pc calculation. + + Mandatory request parameters: + - id (vm identifier) + + Response parameters: + - id (vm identifier) + - logs (logs for the calculation) + - idlepc (idle-pc value) + + :param request: JSON request + """ + + # validate the request + if not self.validate_request(request, VM_AUTO_IDLEPC_SCHEMA): + return + + # get the router instance + router = self.get_device_instance(request["id"], self._routers) + if not router: + return + + try: + router.idlepc = "0x0" # reset the current idle-pc value before calculating a new one + was_auto_started = False + if router.get_status() != "running": + router.start() + was_auto_started = True + time.sleep(20) # leave time to the router to boot + + logs = [] + validated_idlepc = "0x0" + idlepcs = router.get_idle_pc_prop() + if not idlepcs: + logs.append("No idle-pc values found") + + for idlepc in idlepcs: + router.idlepc = idlepc.split()[0] + logs.append("Trying idle-pc value {}".format(router.idlepc)) + start_time = time.time() + initial_cpu_usage = router.get_cpu_usage() + logs.append("Initial CPU usage = {}%".format(initial_cpu_usage)) + time.sleep(4) # wait 4 seconds to probe the cpu again + elapsed_time = time.time() - start_time + cpu_elapsed_usage = router.get_cpu_usage() - initial_cpu_usage + cpu_usage = abs(cpu_elapsed_usage * 100.0 / elapsed_time) + logs.append("CPU usage after {:.2} seconds = {:.2}%".format(elapsed_time, cpu_usage)) + if cpu_usage > 100: + cpu_usage = 100 + if cpu_usage < 70: + validated_idlepc = router.idlepc + logs.append("Idle-PC value {} has been validated".format(validated_idlepc)) + break + except DynamipsError as e: + self.send_custom_error(str(e)) + return + finally: + if was_auto_started: + router.stop() + + validated_idlepc = "0x0" + response = {"id": router.id, + "logs": logs, + "idlepc": validated_idlepc} + + self.send_response(response) + @IModule.route("dynamips.vm.allocate_udp_port") def vm_allocate_udp_port(self, request): """ diff --git a/gns3server/modules/dynamips/nodes/router.py b/gns3server/modules/dynamips/nodes/router.py index b79bc551..f985af1c 100644 --- a/gns3server/modules/dynamips/nodes/router.py +++ b/gns3server/modules/dynamips/nodes/router.py @@ -1255,6 +1255,15 @@ class Router(object): return (self._hypervisor.send("{platform} show_hardware {name}".format(platform=self._platform, name=self._name))) + def get_cpu_usage(self): + """ + Returns the CPU usage. + + :return: CPU usage in percent + """ + + return int(self._hypervisor.send("vm cpu_usage {name} 0".format(name=self._name))[0]) + def get_slot_bindings(self): """ Returns slot bindings. diff --git a/gns3server/modules/dynamips/schemas/vm.py b/gns3server/modules/dynamips/schemas/vm.py index 328a10db..bc11bd7a 100644 --- a/gns3server/modules/dynamips/schemas/vm.py +++ b/gns3server/modules/dynamips/schemas/vm.py @@ -487,6 +487,20 @@ VM_IDLEPCS_SCHEMA = { "required": ["id"] } +VM_AUTO_IDLEPC_SCHEMA = { + "$schema": "http://json-schema.org/draft-04/schema#", + "description": "Request an auto idle-pc calculation for this VM instance", + "type": "object", + "properties": { + "id": { + "description": "VM instance ID", + "type": "integer" + }, + }, + "additionalProperties": False, + "required": ["id"] +} + VM_ALLOCATE_UDP_PORT_SCHEMA = { "$schema": "http://json-schema.org/draft-04/schema#", "description": "Request validation to allocate an UDP port for a VM instance", From f854752c8417b4e63279667236087e62988a48c5 Mon Sep 17 00:00:00 2001 From: grossmj Date: Tue, 14 Oct 2014 17:20:28 -0600 Subject: [PATCH 2/4] Bump to version 1.0-beta4. --- gns3server/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gns3server/version.py b/gns3server/version.py index 652ac6fd..6d7ef205 100644 --- a/gns3server/version.py +++ b/gns3server/version.py @@ -23,5 +23,5 @@ # or negative for a release candidate or beta (after the base version # number has been incremented) -__version__ = "1.0beta4.dev2" +__version__ = "1.0beta4" __version_info__ = (1, 0, 0, -99) From 5f4b3c547bb34bed294588f6f02f5b8f880425a9 Mon Sep 17 00:00:00 2001 From: grossmj Date: Tue, 14 Oct 2014 17:47:52 -0600 Subject: [PATCH 3/4] Bump to version 1.0.dev1. --- gns3server/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gns3server/version.py b/gns3server/version.py index 6d7ef205..2680c5ca 100644 --- a/gns3server/version.py +++ b/gns3server/version.py @@ -23,5 +23,5 @@ # or negative for a release candidate or beta (after the base version # number has been incremented) -__version__ = "1.0beta4" +__version__ = "1.0.dev1" __version_info__ = (1, 0, 0, -99) From b88abb7c91f13617b15e48005e516d76605436e3 Mon Sep 17 00:00:00 2001 From: grossmj Date: Sun, 19 Oct 2014 17:29:04 -0600 Subject: [PATCH 4/4] Remote servers and load-balancing (still things to improve). --- gns3server/handlers/version_handler.py | 1 - 1 file changed, 1 deletion(-) diff --git a/gns3server/handlers/version_handler.py b/gns3server/handlers/version_handler.py index ec83d4ce..30c55d40 100644 --- a/gns3server/handlers/version_handler.py +++ b/gns3server/handlers/version_handler.py @@ -15,7 +15,6 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -import tornado.web from .auth_handler import GNS3BaseHandler from ..version import __version__