diff --git a/gns3server/modules/qemu/qemu_vm.py b/gns3server/modules/qemu/qemu_vm.py index 026e2a13c..7cc2f62f6 100644 --- a/gns3server/modules/qemu/qemu_vm.py +++ b/gns3server/modules/qemu/qemu_vm.py @@ -150,7 +150,7 @@ class QemuVM(BaseVM): self._platform = "x86_64" else: self._platform = re.sub(r'^qemu-system-(.*)(w.exe)?$', r'\1', os.path.basename(qemu_path), re.IGNORECASE) - if self._platform not in QEMU_PLATFORMS: + if self._platform.split(".")[0] not in QEMU_PLATFORMS: raise QemuError("Platform {} is unknown".format(self._platform)) log.info('QEMU VM "{name}" [{id}] has set the QEMU path to {qemu_path}'.format(name=self._name, id=self._id, @@ -1356,6 +1356,27 @@ class QemuVM(BaseVM): return [] return ["-nographic"] + def _run_with_kvm(self, qemu_path, options): + """ + Check if we could run qemu with KVM + + :param qemu_path: Path to qemu + :param options: String of qemu user options + :returns: Boolean True if we need to enable KVM + """ + + if sys.platform.startswith("linux") and self.manager.config.get_section_config("Qemu").getboolean("enable_kvm", True) \ + and "-no-kvm" not in options: + + # Turn OFF kvm for non x86 architectures + if os.path.basename(qemu_path) not in ["qemu-system-x86_64", "qemu-system-i386", "qemu-kvm"]: + return False + + if not os.path.exists("/dev/kvm"): + raise QemuError("KVM acceleration cannot be used (/dev/kvm doesn't exist)") + return True + return False + @asyncio.coroutine def _build_command(self): """ @@ -1367,10 +1388,7 @@ class QemuVM(BaseVM): command.extend(["-name", self._name]) command.extend(["-m", str(self._ram)]) command.extend(["-smp", "cpus={}".format(self._cpus)]) - if sys.platform.startswith("linux") and self.manager.config.get_section_config("Qemu").getboolean("enable_kvm", True) \ - and "-no-kvm" not in self._options: - if not os.path.exists("/dev/kvm"): - raise QemuError("KVM acceleration cannot be used (/dev/kvm doesn't exist)") + if self._run_with_kvm(self.qemu_path, self._options): command.extend(["-enable-kvm"]) command.extend(["-boot", "order={}".format(self._boot_priority)]) disk_options = yield from self._disk_options() diff --git a/tests/conftest.py b/tests/conftest.py index c96f96099..b983a89cb 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -165,3 +165,35 @@ def run_around_tests(monkeypatch): shutil.rmtree(tmppath) except: pass + +@pytest.yield_fixture +def darwin_platform(): + """ + Change sys.plaform to Darwin + """ + old_platform = sys.platform + sys.platform = "darwin10.10" + yield + sys.plaform = old_platform + + +@pytest.yield_fixture +def windows_platform(): + """ + Change sys.plaform to Windows + """ + old_platform = sys.platform + sys.platform = "win10" + yield + sys.plaform = old_platform + + +@pytest.yield_fixture +def linux_platform(): + """ + Change sys.plaform to Linux + """ + old_platform = sys.platform + sys.platform = "linuxdebian" + yield + sys.plaform = old_platform diff --git a/tests/modules/qemu/test_qemu_vm.py b/tests/modules/qemu/test_qemu_vm.py index 44444b255..676ec9b8c 100644 --- a/tests/modules/qemu/test_qemu_vm.py +++ b/tests/modules/qemu/test_qemu_vm.py @@ -428,3 +428,54 @@ def test_get_qemu_img_not_exist(vm, tmpdir): vm._qemu_path = str(tmpdir / "qemu-sytem-x86_64") with pytest.raises(QemuError): vm._get_qemu_img() + + +def test_run_with_kvm_darwin(darwin_platform, vm): + + with patch("configparser.SectionProxy.getboolean", return_value=True): + assert vm._run_with_kvm("qemu-system-x86_64", "") is False + + + +def test_run_with_kvm_windows(windows_platform, vm): + + with patch("configparser.SectionProxy.getboolean", return_value=True): + assert vm._run_with_kvm("qemu-system-x86_64.exe", "") is False + + +def test_run_with_kvm_linux(linux_platform, vm): + + with patch("os.path.exists", return_value=True) as os_path: + with patch("configparser.SectionProxy.getboolean", return_value=True): + assert vm._run_with_kvm("qemu-system-x86_64", "") is True + os_path.assert_called_with("/dev/kvm") + + +def test_run_with_kvm_linux_config_desactivated(linux_platform, vm): + + with patch("os.path.exists", return_value=True) as os_path: + with patch("configparser.SectionProxy.getboolean", return_value=False): + assert vm._run_with_kvm("qemu-system-x86_64", "") is False + + +def test_run_with_kvm_linux_options_no_kvm(linux_platform, vm): + + with patch("os.path.exists", return_value=True) as os_path: + with patch("configparser.SectionProxy.getboolean", return_value=True): + assert vm._run_with_kvm("qemu-system-x86_64", "-no-kvm") is False + + +def test_run_with_kvm_not_x86(linux_platform, vm): + + with patch("os.path.exists", return_value=True) as os_path: + with patch("configparser.SectionProxy.getboolean", return_value=True): + assert vm._run_with_kvm("qemu-system-arm", "") is False + + + +def test_run_with_kvm_linux_dev_kvm_missing(linux_platform, vm): + + with patch("os.path.exists", return_value=False) as os_path: + with patch("configparser.SectionProxy.getboolean", return_value=True): + with pytest.raises(QemuError): + vm._run_with_kvm("qemu-system-x86_64", "")