diff --git a/gns3server/handlers/api/qemu_handler.py b/gns3server/handlers/api/qemu_handler.py index 7b43d34e..3be59314 100644 --- a/gns3server/handlers/api/qemu_handler.py +++ b/gns3server/handlers/api/qemu_handler.py @@ -53,8 +53,9 @@ class QEMUHandler: request.match_info["project_id"], request.json.pop("vm_id", None), qemu_path=request.json.pop("qemu_path", None), - platform=request.json.pop("platform", None), - console=request.json.pop("console", None)) + console=request.json.pop("console", None), + console_type=request.json.pop("console_type", "telnet"), + platform=request.json.pop("platform", None)) for name, value in request.json.items(): if hasattr(vm, name) and getattr(vm, name) != value: diff --git a/gns3server/modules/base_vm.py b/gns3server/modules/base_vm.py index f9dbc2df..19c78d5e 100644 --- a/gns3server/modules/base_vm.py +++ b/gns3server/modules/base_vm.py @@ -40,20 +40,25 @@ class BaseVM: :param console: TCP console port """ - def __init__(self, name, vm_id, project, manager, console=None): + def __init__(self, name, vm_id, project, manager, console=None, console_type="telnet"): self._name = name self._id = vm_id self._project = project self._manager = manager self._console = console + self._console_type = console_type self._temporary_directory = None self._vm_status = "stopped" if self._console is not None: self._console = self._manager.port_manager.reserve_tcp_port(self._console, self._project) else: - self._console = self._manager.port_manager.get_free_tcp_port(self._project) + if console_type == "vnc": + # VNC is a special case and the range must be 5900-6000 + self._console = self._manager.port_manager.get_free_tcp_port(self._project, 5900, 6000) + else: + self._console = self._manager.port_manager.get_free_tcp_port(self._project) log.debug("{module}: {name} [{id}] initialized. Console port {console}".format(module=self.manager.module_name, name=self.name, @@ -196,7 +201,7 @@ class BaseVM: @property def console(self): """ - Returns the console port of this VPCS vm. + Returns the console port of this VM. :returns: console port """ @@ -220,3 +225,40 @@ class BaseVM: name=self.name, id=self.id, port=console)) + + @property + def console_type(self): + """ + Returns the console type for this VM. + + :returns: console type (string) + """ + + return self._console_type + + @console_type.setter + def console_type(self, console_type): + """ + Sets the console type for this VM. + + :param console_type: console type (string) + """ + + log.info('QEMU VM "{name}" [{id}] has set the console type to {console_type}'.format(name=self._name, + id=self._id, + console_type=console_type)) + + if console_type != self._console_type: + # get a new port if the console type change + self._manager.port_manager.release_tcp_port(self._console, self._project) + if console_type == "vnc": + # VNC is a special case and the range must be 5900-6000 + self._console = self._manager.port_manager.get_free_tcp_port(self._project, 5900, 6000) + else: + self._console = self._manager.port_manager.get_free_tcp_port(self._project) + + self._console_type = console_type + log.info("{module}: '{name}' [{id}]: console type set to {console_type}".format(module=self.manager.module_name, + name=self.name, + id=self.id, + console_type=console_type)) diff --git a/gns3server/modules/port_manager.py b/gns3server/modules/port_manager.py index d0d3f7a0..79f2c7b6 100644 --- a/gns3server/modules/port_manager.py +++ b/gns3server/modules/port_manager.py @@ -169,15 +169,20 @@ class PortManager: host, last_exception)) - def get_free_tcp_port(self, project): + def get_free_tcp_port(self, project, port_range_start=None, port_range_end=None): """ Get an available TCP port and reserve it :param project: Project instance """ - port = self.find_unused_port(self._console_port_range[0], - self._console_port_range[1], + # use the default range is not specific one is given + if port_range_start is None and port_range_end is None: + port_range_start = self._console_port_range[0] + port_range_end = self._console_port_range[1] + + port = self.find_unused_port(port_range_start, + port_range_end, host=self._console_host, socket_type="TCP", ignore_ports=self._used_tcp_ports) diff --git a/gns3server/modules/qemu/qemu_vm.py b/gns3server/modules/qemu/qemu_vm.py index 067ed71c..0f7dcce9 100644 --- a/gns3server/modules/qemu/qemu_vm.py +++ b/gns3server/modules/qemu/qemu_vm.py @@ -60,9 +60,9 @@ class QemuVM(BaseVM): :param console: TCP console port """ - def __init__(self, name, vm_id, project, manager, qemu_path=None, console=None, platform=None): + def __init__(self, name, vm_id, project, manager, qemu_path=None, console=None, console_type="telnet", platform=None): - super().__init__(name, vm_id, project, manager, console=console) + super().__init__(name, vm_id, project, manager, console=console, console_type=console_type) server_config = manager.config.get_section_config("Server") self._host = server_config.get("host", "127.0.0.1") self._monitor_host = server_config.get("monitor_host", "127.0.0.1") @@ -91,7 +91,6 @@ class QemuVM(BaseVM): self._hdd_disk_image = "" self._mac_address = "" self._options = "" - self._console_type = "telnet" self._ram = 256 self._ethernet_adapters = [] self._adapter_type = "e1000" @@ -486,33 +485,6 @@ class QemuVM(BaseVM): self._options = options.strip() - @property - def console_type(self): - """ - Returns the console type for this QEMU VM. - - :returns: console type (string) - """ - - return self._console_type - - @console_type.setter - def console_type(self, console_type): - """ - Sets the console type for this QEMU VM. - - :param console_type: console type (string) - """ - - log.info('QEMU VM "{name}" [{id}] has set the console type to {console_type}'.format(name=self._name, - id=self._id, - console_type=console_type)) - - if self.is_running() and console_type != self._console_type: - raise QemuError("Sorry, changing the console type on a running Qemu VM is not supported.") - - self._console_type = console_type - @property def initrd(self): """ @@ -1009,7 +981,7 @@ class QemuVM(BaseVM): def _vnc_options(self): if self._console: - vnc_port = self._console - 5900 + vnc_port = self._console - 5900 # subtract by 5900 to get the display number return ["-vnc", "{}:{}".format(self._manager.port_manager.console_host, vnc_port)] else: return []