1
0
mirror of https://github.com/GNS3/gns3-server synced 2024-12-25 16:28:11 +00:00

Adds a handler for getting the Qemu related capabilities of the server. Currently includes just a check for KVM architectures.

This commit is contained in:
Vasil Rangelov 2016-01-01 02:40:12 +02:00
parent 38622c4da3
commit d00efbfb0f
4 changed files with 99 additions and 7 deletions

View File

@ -25,7 +25,9 @@ from ...schemas.nio import NIO_SCHEMA
from ...schemas.qemu import QEMU_CREATE_SCHEMA
from ...schemas.qemu import QEMU_UPDATE_SCHEMA
from ...schemas.qemu import QEMU_OBJECT_SCHEMA
from ...schemas.qemu import QEMU_BINARY_FILTER_SCHEMA
from ...schemas.qemu import QEMU_BINARY_LIST_SCHEMA
from ...schemas.qemu import QEMU_CAPABILITY_LIST_SCHEMA
from ...schemas.qemu import QEMU_IMAGE_CREATE_SCHEMA
from ...schemas.vm import VM_LIST_IMAGES_SCHEMA
from ...modules.qemu import Qemu
@ -300,10 +302,11 @@ class QEMUHandler:
404: "Instance doesn't exist"
},
description="Get a list of available Qemu binaries",
input=QEMU_BINARY_FILTER_SCHEMA,
output=QEMU_BINARY_LIST_SCHEMA)
def list_binaries(request, response):
binaries = yield from Qemu.binary_list()
binaries = yield from Qemu.binary_list(request.json["archs"] if "archs" in request.json else None)
response.json(binaries)
@classmethod
@ -321,6 +324,21 @@ class QEMUHandler:
binaries = yield from Qemu.img_binary_list()
response.json(binaries)
@Route.get(
r"/qemu/capabilities",
status_codes={
200: "Success"
},
description="Get a list of Qemu capabilities on this server",
output=QEMU_CAPABILITY_LIST_SCHEMA
)
def get_capabilities(request, response):
capabilities = {}
kvms = Qemu.get_kvm_archs()
if kvms:
capabilities["kvm"] = kvms
response.json(capabilities)
@classmethod
@Route.post(
r"/qemu/img",

View File

@ -21,6 +21,7 @@ Qemu server module.
import asyncio
import os
import platform
import sys
import re
import subprocess
@ -38,6 +39,27 @@ class Qemu(BaseManager):
_VM_CLASS = QemuVM
@staticmethod
def get_kvm_archs():
"""
Gets a list of architectures for which KVM is available on this server.
:returns: List of architectures for which KVM is available on this server.
"""
kvm = []
x86_64_aliases = ["x86_64", "x86-64", "x64", "AMD64", "amd64", "Intel 64", "EM64T"]
i386_aliases = ["i386", "x86", "x32"]
if sys.platform.startswith("linux") and subprocess.call("kvm-ok") == 0:
arch = platform.machine()
if arch in x86_64_aliases:
kvm.append("x86_64")
kvm.append("i386")
elif arch in i386_aliases:
kvm.append("i386")
else:
kvm.append(platform.machine())
return kvm
@staticmethod
def paths_list():
"""
@ -82,7 +104,7 @@ class Qemu(BaseManager):
return paths
@staticmethod
def binary_list():
def binary_list(archs=None):
"""
Gets QEMU binaries list available on the host.
@ -96,9 +118,17 @@ class Qemu(BaseManager):
if (f.startswith("qemu-system") or f.startswith("qemu-kvm") or f == "qemu" or f == "qemu.exe") and \
os.access(os.path.join(path, f), os.X_OK) and \
os.path.isfile(os.path.join(path, f)):
qemu_path = os.path.join(path, f)
version = yield from Qemu.get_qemu_version(qemu_path)
qemus.append({"path": qemu_path, "version": version})
if archs is not None:
for arch in archs:
if f.endswith(arch) or f.endswith("{}.exe".format(arch)) or f.endswith("{}w.exe".format(arch)):
qemu_path = os.path.join(path, f)
version = yield from Qemu.get_qemu_version(qemu_path)
qemus.append({"path": qemu_path, "version": version})
else:
qemu_path = os.path.join(path, f)
version = yield from Qemu.get_qemu_version(qemu_path)
qemus.append({"path": qemu_path, "version": version})
except OSError:
continue

View File

@ -601,6 +601,21 @@ QEMU_OBJECT_SCHEMA = {
"vm_directory"]
}
QEMU_BINARY_FILTER_SCHEMA = {
"$schema": "http://json-schema.org/draft-04/schema#",
"description": "Request validation for a list of qemu capabilities",
"properties": {
"archs": {
"description": "Architectures to filter binaries by",
"type": "array",
"items": {
"enum": QEMU_PLATFORMS
}
}
},
"additionalProperties": False,
}
QEMU_BINARY_LIST_SCHEMA = {
"$schema": "http://json-schema.org/draft-04/schema#",
"description": "Request validation for a list of qemu binaries",
@ -626,6 +641,21 @@ QEMU_BINARY_LIST_SCHEMA = {
"additionalProperties": False,
}
QEMU_CAPABILITY_LIST_SCHEMA = {
"$schema": "http://json-schema.org/draft-04/schema#",
"description": "Request validation for a list of qemu capabilities",
"properties": {
"kvm": {
"description": "Architectures that KVM is enabled for",
"type": "array",
"items": {
"enum": QEMU_PLATFORMS
}
}
},
"additionalProperties": False,
}
QEMU_IMAGE_CREATE_SCHEMA = {
"$schema": "http://json-schema.org/draft-04/schema#",
"description": "Create a new qemu image. Options can be specific to a format. Read qemu-img manual for more information",

View File

@ -58,18 +58,32 @@ def test_binary_list(loop):
os.chmod(path, stat.S_IRUSR | stat.S_IWUSR | stat.S_IXUSR)
with asyncio_patch("gns3server.modules.qemu.subprocess_check_output", return_value="QEMU emulator version 2.2.0, Copyright (c) 2003-2008 Fabrice Bellard") as mock:
qemus = loop.run_until_complete(asyncio.async(Qemu.binary_list()))
if sys.platform.startswith("win"):
version = ""
else:
version = "2.2.0"
qemus = loop.run_until_complete(asyncio.async(Qemu.binary_list()))
assert {"path": os.path.join(os.environ["PATH"], "qemu-system-x86"), "version": version} in qemus
assert {"path": os.path.join(os.environ["PATH"], "qemu-kvm"), "version": version} in qemus
assert {"path": os.path.join(os.environ["PATH"], "qemu-system-x42"), "version": version} in qemus
assert {"path": os.path.join(os.environ["PATH"], "hello"), "version": version} not in qemus
qemus = loop.run_until_complete(asyncio.async(Qemu.binary_list(["x86"])))
assert {"path": os.path.join(os.environ["PATH"], "qemu-system-x86"), "version": version} in qemus
assert {"path": os.path.join(os.environ["PATH"], "qemu-kvm"), "version": version} not in qemus
assert {"path": os.path.join(os.environ["PATH"], "qemu-system-x42"), "version": version} not in qemus
assert {"path": os.path.join(os.environ["PATH"], "hello"), "version": version} not in qemus
qemus = loop.run_until_complete(asyncio.async(Qemu.binary_list(["x86", "x42"])))
assert {"path": os.path.join(os.environ["PATH"], "qemu-system-x86"), "version": version} in qemus
assert {"path": os.path.join(os.environ["PATH"], "qemu-kvm"), "version": version} not in qemus
assert {"path": os.path.join(os.environ["PATH"], "qemu-system-x42"), "version": version} in qemus
assert {"path": os.path.join(os.environ["PATH"], "hello"), "version": version} not in qemus
def test_img_binary_list(loop):