From 632134a02ae3ebd67f6b123d137805bb97b97501 Mon Sep 17 00:00:00 2001 From: grossmj Date: Sat, 29 Nov 2014 14:11:51 -0700 Subject: [PATCH] Support for older Qemu versions like the 0.11.0 on Windows. --- gns3server/modules/qemu/__init__.py | 4 +- gns3server/modules/qemu/qemu_vm.py | 74 +++++++++++++++++++++++++---- gns3server/modules/qemu/schemas.py | 4 ++ 3 files changed, 72 insertions(+), 10 deletions(-) diff --git a/gns3server/modules/qemu/__init__.py b/gns3server/modules/qemu/__init__.py index aaf36352..18c005ee 100644 --- a/gns3server/modules/qemu/__init__.py +++ b/gns3server/modules/qemu/__init__.py @@ -626,6 +626,7 @@ class Qemu(IModule): if sys.platform.startswith("win"): # add specific Windows paths paths.append(os.path.join(os.getcwd(), "qemu")) + paths.append(os.path.join(os.getcwd(), "qemu-0.11.0")) if "PROGRAMFILES(X86)" in os.environ and os.path.exists(os.environ["PROGRAMFILES(X86)"]): paths.append(os.path.join(os.environ["PROGRAMFILES(X86)"], "qemu")) if "PROGRAMFILES" in os.environ and os.path.exists(os.environ["PROGRAMFILES"]): @@ -640,8 +641,7 @@ class Qemu(IModule): qemu_path = os.path.join(path, f) version = self._get_qemu_version(qemu_path) qemus.append({"path": qemu_path, "version": version}) - except (OSError, QemuError) as e: - log.warn("Could not find QEMU version for {}: {}".format(path, e)) + except OSError: continue response = {"qemus": qemus} diff --git a/gns3server/modules/qemu/qemu_vm.py b/gns3server/modules/qemu/qemu_vm.py index d5009fd4..bbe80c4b 100644 --- a/gns3server/modules/qemu/qemu_vm.py +++ b/gns3server/modules/qemu/qemu_vm.py @@ -19,6 +19,7 @@ QEMU VM instance. """ +import sys import os import shutil import random @@ -107,6 +108,7 @@ class QemuVM(object): self._initrd = "" self._kernel_image = "" self._kernel_command_line = "" + self._legacy_networking = False working_dir_path = os.path.join(working_dir, "qemu", "vm-{}".format(self._id)) @@ -152,7 +154,8 @@ class QemuVM(object): "console": self._console, "initrd": self._initrd, "kernel_image": self._kernel_image, - "kernel_command_line": self._kernel_command_line} + "kernel_command_line": self._kernel_command_line, + "legacy_networking": self._legacy_networking} return qemu_defaults @@ -437,6 +440,30 @@ class QemuVM(object): id=self._id, adapter_type=adapter_type)) + @property + def legacy_networking(self): + """ + Returns either QEMU legacy networking commands are used. + + :returns: boolean + """ + + return self._legacy_networking + + @legacy_networking.setter + def legacy_networking(self, legacy_networking): + """ + Sets either QEMU legacy networking commands are used. + + :param legacy_networking: boolean + """ + + if legacy_networking: + log.info("QEMU VM {name} [id={id}] has enabled legacy networking".format(name=self._name, id=self._id)) + else: + log.info("QEMU VM {name} [id={id}] has disabled legacy networking".format(name=self._name, id=self._id)) + self._legacy_networking = legacy_networking + @property def ram(self): """ @@ -617,6 +644,24 @@ class QemuVM(object): log.error("could not start QEMU {}: {}\n{}".format(self._qemu_path, e, stdout)) raise QemuError("could not start QEMU {}: {}\n{}".format(self._qemu_path, e, stdout)) + # change the process priority + if sys.platform.startswith("win"): + try: + import win32api + import win32con + import win32process + except ImportError: + log.error("pywin32 must be installed to change the priority class for QEMU VM {}".format(self._name)) + else: + log.info("setting QEMU VM {} priority class to BELOW_NORMAL".format(self._name)) + handle = win32api.OpenProcess(win32con.PROCESS_ALL_ACCESS, 0, self._process.pid) + win32process.SetPriorityClass(handle, win32process.BELOW_NORMAL_PRIORITY_CLASS) + else: + try: + subprocess.call(['renice', '-n', '19', '-p', str(self._process.pid)]) + except subprocess.SubprocessError as e: + log.error("could not change process priority for QEMU VM {}: {}".format(self._name, e)) + def stop(self): """ Stops this QEMU VM. @@ -819,16 +864,29 @@ class QemuVM(object): for adapter in self._ethernet_adapters: #TODO: let users specify a base mac address mac = "00:00:ab:%02x:%02x:%02d" % (random.randint(0x00, 0xff), random.randint(0x00, 0xff), adapter_id) - network_options.extend(["-device", "{},mac={},netdev=gns3-{}".format(self._adapter_type, mac, adapter_id)]) + if self._legacy_networking: + network_options.extend(["-net", "nic,vlan={},macaddr={},model={}".format(adapter_id, mac, self._adapter_type)]) + else: + network_options.extend(["-device", "{},mac={},netdev=gns3-{}".format(self._adapter_type, mac, adapter_id)]) nio = adapter.get_nio(0) if nio and isinstance(nio, NIO_UDP): - network_options.extend(["-netdev", "socket,id=gns3-{},udp={}:{},localaddr={}:{}".format(adapter_id, - nio.rhost, - nio.rport, - self._host, - nio.lport)]) + if self._legacy_networking: + network_options.extend(["-net", "udp,vlan={},sport={},dport={},daddr={}".format(adapter_id, + nio.lport, + nio.rport, + nio.rhost)]) + + else: + network_options.extend(["-netdev", "socket,id=gns3-{},udp={}:{},localaddr={}:{}".format(adapter_id, + nio.rhost, + nio.rport, + self._host, + nio.lport)]) else: - network_options.extend(["-netdev", "user,id=gns3-{}".format(adapter_id)]) + if self._legacy_networking: + network_options.extend(["-net", "user,vlan={}".format(adapter_id)]) + else: + network_options.extend(["-netdev", "user,id=gns3-{}".format(adapter_id)]) adapter_id += 1 return network_options diff --git a/gns3server/modules/qemu/schemas.py b/gns3server/modules/qemu/schemas.py index adc766f8..425cb1c4 100644 --- a/gns3server/modules/qemu/schemas.py +++ b/gns3server/modules/qemu/schemas.py @@ -124,6 +124,10 @@ QEMU_UPDATE_SCHEMA = { "description": "Path to the image in the cloud object store", "type": "string", }, + "legacy_networking": { + "description": "Use QEMU legagy networking commands (-net syntax)", + "type": "boolean", + }, "options": { "description": "additional QEMU options", "type": "string",