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__ diff --git a/gns3server/modules/dynamips/backends/vm.py b/gns3server/modules/dynamips/backends/vm.py index 091ed607..6e1d0bc3 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 gns3dms.cloud.rackspace_ctrl import get_provider from ..dynamips_error import DynamipsError @@ -62,6 +63,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 @@ -714,6 +716,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 f00f39b1..7496ca28 100644 --- a/gns3server/modules/dynamips/schemas/vm.py +++ b/gns3server/modules/dynamips/schemas/vm.py @@ -491,6 +491,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", diff --git a/gns3server/version.py b/gns3server/version.py index 652ac6fd..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.dev2" +__version__ = "1.0.dev1" __version_info__ = (1, 0, 0, -99)