mirror of
https://github.com/GNS3/gns3-server
synced 2024-11-28 03:08:14 +00:00
Merge remote-tracking branch 'origin/master'
This commit is contained in:
commit
2de1a97076
@ -16,7 +16,6 @@
|
|||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import base64
|
|
||||||
import ntpath
|
import ntpath
|
||||||
import time
|
import time
|
||||||
from gns3server.modules import IModule
|
from gns3server.modules import IModule
|
||||||
@ -412,36 +411,38 @@ class VM(object):
|
|||||||
|
|
||||||
response = {}
|
response = {}
|
||||||
try:
|
try:
|
||||||
startup_config_path = os.path.join(router.hypervisor.working_dir, "configs", "i{}_startup-config.cfg".format(router.id))
|
default_startup_config_path = os.path.join(router.hypervisor.working_dir, "configs", "i{}_startup-config.cfg".format(router.id))
|
||||||
private_config_path = os.path.join(router.hypervisor.working_dir, "configs", "i{}_private-config.cfg".format(router.id))
|
default_private_config_path = os.path.join(router.hypervisor.working_dir, "configs", "i{}_private-config.cfg".format(router.id))
|
||||||
|
|
||||||
# a new startup-config has been pushed
|
# a new startup-config has been pushed
|
||||||
if "startup_config_base64" in request:
|
if "startup_config_base64" in request:
|
||||||
# update the request with the new local startup-config path
|
# update the request with the new local startup-config path
|
||||||
request["startup_config"] = self.create_config_from_base64(request["startup_config_base64"], router, startup_config_path)
|
request["startup_config"] = self.create_config_from_base64(request["startup_config_base64"], router, default_startup_config_path)
|
||||||
|
|
||||||
# a new private-config has been pushed
|
# a new private-config has been pushed
|
||||||
if "private_config_base64" in request:
|
if "private_config_base64" in request:
|
||||||
# update the request with the new local private-config path
|
# update the request with the new local private-config path
|
||||||
request["private_config"] = self.create_config_from_base64(request["private_config_base64"], router, private_config_path)
|
request["private_config"] = self.create_config_from_base64(request["private_config_base64"], router, default_private_config_path)
|
||||||
|
|
||||||
if "startup_config" in request:
|
if "startup_config" in request:
|
||||||
if os.path.isfile(request["startup_config"]) and request["startup_config"] != startup_config_path:
|
startup_config_path = request["startup_config"].replace("\\", '/')
|
||||||
|
if os.path.isfile(startup_config_path) and startup_config_path != default_startup_config_path:
|
||||||
# this is a local file set in the GUI
|
# this is a local file set in the GUI
|
||||||
request["startup_config"] = self.create_config_from_file(request["startup_config"], router, startup_config_path)
|
startup_config_path = self.create_config_from_file(startup_config_path, router, default_startup_config_path)
|
||||||
router.set_config(request["startup_config"])
|
router.set_config(startup_config_path)
|
||||||
else:
|
else:
|
||||||
router.set_config(request["startup_config"])
|
router.set_config(startup_config_path)
|
||||||
response["startup_config"] = request["startup_config"]
|
response["startup_config"] = startup_config_path
|
||||||
|
|
||||||
if "private_config" in request:
|
if "private_config" in request:
|
||||||
if os.path.isfile(request["private_config"]) and request["private_config"] != private_config_path:
|
private_config_path = request["private_config"].replace("\\", '/')
|
||||||
|
if os.path.isfile(private_config_path) and private_config_path != default_private_config_path:
|
||||||
# this is a local file set in the GUI
|
# this is a local file set in the GUI
|
||||||
request["private_config"] = self.create_config_from_file(request["private_config"], router, private_config_path)
|
private_config_path = self.create_config_from_file(private_config_path, router, default_private_config_path)
|
||||||
router.set_config(router.startup_config, request["private_config"])
|
router.set_config(router.startup_config, private_config_path)
|
||||||
else:
|
else:
|
||||||
router.set_config(router.startup_config, request["private_config"])
|
router.set_config(router.startup_config, private_config_path)
|
||||||
response["private_config"] = request["private_config"]
|
response["private_config"] = private_config_path
|
||||||
|
|
||||||
except DynamipsError as e:
|
except DynamipsError as e:
|
||||||
self.send_custom_error(str(e))
|
self.send_custom_error(str(e))
|
||||||
|
@ -67,11 +67,14 @@ class Qemu(IModule):
|
|||||||
qemu_config = config.get_section_config(name.upper())
|
qemu_config = config.get_section_config(name.upper())
|
||||||
self._console_start_port_range = qemu_config.get("console_start_port_range", 5001)
|
self._console_start_port_range = qemu_config.get("console_start_port_range", 5001)
|
||||||
self._console_end_port_range = qemu_config.get("console_end_port_range", 5500)
|
self._console_end_port_range = qemu_config.get("console_end_port_range", 5500)
|
||||||
|
self._monitor_start_port_range = qemu_config.get("monitor_start_port_range", 5501)
|
||||||
|
self._monitor_end_port_range = qemu_config.get("monitor_end_port_range", 6000)
|
||||||
self._allocated_udp_ports = []
|
self._allocated_udp_ports = []
|
||||||
self._udp_start_port_range = qemu_config.get("udp_start_port_range", 40001)
|
self._udp_start_port_range = qemu_config.get("udp_start_port_range", 40001)
|
||||||
self._udp_end_port_range = qemu_config.get("udp_end_port_range", 45500)
|
self._udp_end_port_range = qemu_config.get("udp_end_port_range", 45500)
|
||||||
self._host = qemu_config.get("host", kwargs["host"])
|
self._host = qemu_config.get("host", kwargs["host"])
|
||||||
self._console_host = qemu_config.get("console_host", kwargs["console_host"])
|
self._console_host = qemu_config.get("console_host", kwargs["console_host"])
|
||||||
|
self._monitor_host = qemu_config.get("monitor_host", "127.0.0.1")
|
||||||
self._projects_dir = kwargs["projects_dir"]
|
self._projects_dir = kwargs["projects_dir"]
|
||||||
self._tempdir = kwargs["temp_dir"]
|
self._tempdir = kwargs["temp_dir"]
|
||||||
self._working_dir = self._projects_dir
|
self._working_dir = self._projects_dir
|
||||||
@ -137,6 +140,8 @@ class Qemu(IModule):
|
|||||||
- project_name
|
- project_name
|
||||||
- console_start_port_range
|
- console_start_port_range
|
||||||
- console_end_port_range
|
- console_end_port_range
|
||||||
|
- monitor_start_port_range
|
||||||
|
- monitor_end_port_range
|
||||||
- udp_start_port_range
|
- udp_start_port_range
|
||||||
- udp_end_port_range
|
- udp_end_port_range
|
||||||
|
|
||||||
@ -174,6 +179,10 @@ class Qemu(IModule):
|
|||||||
self._console_start_port_range = request["console_start_port_range"]
|
self._console_start_port_range = request["console_start_port_range"]
|
||||||
self._console_end_port_range = request["console_end_port_range"]
|
self._console_end_port_range = request["console_end_port_range"]
|
||||||
|
|
||||||
|
if "monitor_start_port_range" in request and "monitor_end_port_range" in request:
|
||||||
|
self._monitor_start_port_range = request["monitor_start_port_range"]
|
||||||
|
self._monitor_end_port_range = request["monitor_end_port_range"]
|
||||||
|
|
||||||
if "udp_start_port_range" in request and "udp_end_port_range" in request:
|
if "udp_start_port_range" in request and "udp_end_port_range" in request:
|
||||||
self._udp_start_port_range = request["udp_start_port_range"]
|
self._udp_start_port_range = request["udp_start_port_range"]
|
||||||
self._udp_end_port_range = request["udp_end_port_range"]
|
self._udp_end_port_range = request["udp_end_port_range"]
|
||||||
@ -191,6 +200,7 @@ class Qemu(IModule):
|
|||||||
|
|
||||||
Optional request parameters:
|
Optional request parameters:
|
||||||
- console (QEMU VM console port)
|
- console (QEMU VM console port)
|
||||||
|
- monitor (QEMU VM monitor port)
|
||||||
|
|
||||||
Response parameters:
|
Response parameters:
|
||||||
- id (QEMU VM instance identifier)
|
- id (QEMU VM instance identifier)
|
||||||
@ -207,6 +217,7 @@ class Qemu(IModule):
|
|||||||
name = request["name"]
|
name = request["name"]
|
||||||
qemu_path = request["qemu_path"]
|
qemu_path = request["qemu_path"]
|
||||||
console = request.get("console")
|
console = request.get("console")
|
||||||
|
monitor = request.get("monitor")
|
||||||
qemu_id = request.get("qemu_id")
|
qemu_id = request.get("qemu_id")
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@ -218,7 +229,11 @@ class Qemu(IModule):
|
|||||||
console,
|
console,
|
||||||
self._console_host,
|
self._console_host,
|
||||||
self._console_start_port_range,
|
self._console_start_port_range,
|
||||||
self._console_end_port_range)
|
self._console_end_port_range,
|
||||||
|
monitor,
|
||||||
|
self._monitor_host,
|
||||||
|
self._monitor_start_port_range,
|
||||||
|
self._monitor_end_port_range)
|
||||||
|
|
||||||
except QemuError as e:
|
except QemuError as e:
|
||||||
self.send_custom_error(str(e))
|
self.send_custom_error(str(e))
|
||||||
|
@ -26,6 +26,7 @@ import random
|
|||||||
import subprocess
|
import subprocess
|
||||||
import shlex
|
import shlex
|
||||||
import ntpath
|
import ntpath
|
||||||
|
import telnetlib
|
||||||
|
|
||||||
from gns3server.config import Config
|
from gns3server.config import Config
|
||||||
from gns3dms.cloud.rackspace_ctrl import get_provider
|
from gns3dms.cloud.rackspace_ctrl import get_provider
|
||||||
@ -52,10 +53,15 @@ class QemuVM(object):
|
|||||||
:param console_host: IP address to bind for console connections
|
:param console_host: IP address to bind for console connections
|
||||||
:param console_start_port_range: TCP console port range start
|
:param console_start_port_range: TCP console port range start
|
||||||
:param console_end_port_range: TCP console port range end
|
:param console_end_port_range: TCP console port range end
|
||||||
|
:param monitor: TCP monitor port
|
||||||
|
:param monitor_host: IP address to bind for monitor connections
|
||||||
|
:param monitor_start_port_range: TCP monitor port range start
|
||||||
|
:param monitor_end_port_range: TCP monitor port range end
|
||||||
"""
|
"""
|
||||||
|
|
||||||
_instances = []
|
_instances = []
|
||||||
_allocated_console_ports = []
|
_allocated_console_ports = []
|
||||||
|
_allocated_monitor_ports = []
|
||||||
|
|
||||||
def __init__(self,
|
def __init__(self,
|
||||||
name,
|
name,
|
||||||
@ -66,7 +72,11 @@ class QemuVM(object):
|
|||||||
console=None,
|
console=None,
|
||||||
console_host="0.0.0.0",
|
console_host="0.0.0.0",
|
||||||
console_start_port_range=5001,
|
console_start_port_range=5001,
|
||||||
console_end_port_range=5500):
|
console_end_port_range=5500,
|
||||||
|
monitor=None,
|
||||||
|
monitor_host="0.0.0.0",
|
||||||
|
monitor_start_port_range=5501,
|
||||||
|
monitor_end_port_range=6000):
|
||||||
|
|
||||||
if not qemu_id:
|
if not qemu_id:
|
||||||
self._id = 0
|
self._id = 0
|
||||||
@ -95,6 +105,9 @@ class QemuVM(object):
|
|||||||
self._console_host = console_host
|
self._console_host = console_host
|
||||||
self._console_start_port_range = console_start_port_range
|
self._console_start_port_range = console_start_port_range
|
||||||
self._console_end_port_range = console_end_port_range
|
self._console_end_port_range = console_end_port_range
|
||||||
|
self._monitor_host = monitor_host
|
||||||
|
self._monitor_start_port_range = monitor_start_port_range
|
||||||
|
self._monitor_end_port_range = monitor_end_port_range
|
||||||
self._cloud_path = None
|
self._cloud_path = None
|
||||||
|
|
||||||
# QEMU settings
|
# QEMU settings
|
||||||
@ -104,6 +117,7 @@ class QemuVM(object):
|
|||||||
self._options = ""
|
self._options = ""
|
||||||
self._ram = 256
|
self._ram = 256
|
||||||
self._console = console
|
self._console = console
|
||||||
|
self._monitor = monitor
|
||||||
self._ethernet_adapters = []
|
self._ethernet_adapters = []
|
||||||
self._adapter_type = "e1000"
|
self._adapter_type = "e1000"
|
||||||
self._initrd = ""
|
self._initrd = ""
|
||||||
@ -135,6 +149,20 @@ class QemuVM(object):
|
|||||||
raise QemuError("Console port {} is already used by another QEMU VM".format(console))
|
raise QemuError("Console port {} is already used by another QEMU VM".format(console))
|
||||||
self._allocated_console_ports.append(self._console)
|
self._allocated_console_ports.append(self._console)
|
||||||
|
|
||||||
|
if not self._monitor:
|
||||||
|
# allocate a monitor port
|
||||||
|
try:
|
||||||
|
self._monitor = find_unused_port(self._monitor_start_port_range,
|
||||||
|
self._monitor_end_port_range,
|
||||||
|
self._monitor_host,
|
||||||
|
ignore_ports=self._allocated_monitor_ports)
|
||||||
|
except Exception as e:
|
||||||
|
raise QemuError(e)
|
||||||
|
|
||||||
|
if self._monitor in self._allocated_monitor_ports:
|
||||||
|
raise QemuError("Monitor port {} is already used by another QEMU VM".format(monitor))
|
||||||
|
self._allocated_monitor_ports.append(self._monitor)
|
||||||
|
|
||||||
self.adapters = 1 # creates 1 adapter by default
|
self.adapters = 1 # creates 1 adapter by default
|
||||||
log.info("QEMU VM {name} [id={id}] has been created".format(name=self._name,
|
log.info("QEMU VM {name} [id={id}] has been created".format(name=self._name,
|
||||||
id=self._id))
|
id=self._id))
|
||||||
@ -155,6 +183,7 @@ class QemuVM(object):
|
|||||||
"adapters": self.adapters,
|
"adapters": self.adapters,
|
||||||
"adapter_type": self._adapter_type,
|
"adapter_type": self._adapter_type,
|
||||||
"console": self._console,
|
"console": self._console,
|
||||||
|
"monitor": self._monitor,
|
||||||
"initrd": self._initrd,
|
"initrd": self._initrd,
|
||||||
"kernel_image": self._kernel_image,
|
"kernel_image": self._kernel_image,
|
||||||
"kernel_command_line": self._kernel_command_line,
|
"kernel_command_line": self._kernel_command_line,
|
||||||
@ -183,6 +212,7 @@ class QemuVM(object):
|
|||||||
|
|
||||||
cls._instances.clear()
|
cls._instances.clear()
|
||||||
cls._allocated_console_ports.clear()
|
cls._allocated_console_ports.clear()
|
||||||
|
cls._allocated_monitor_ports.clear()
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def name(self):
|
def name(self):
|
||||||
@ -267,6 +297,35 @@ class QemuVM(object):
|
|||||||
id=self._id,
|
id=self._id,
|
||||||
port=console))
|
port=console))
|
||||||
|
|
||||||
|
@property
|
||||||
|
def monitor(self):
|
||||||
|
"""
|
||||||
|
Returns the TCP monitor port.
|
||||||
|
|
||||||
|
:returns: monitor port (integer)
|
||||||
|
"""
|
||||||
|
|
||||||
|
return self._monitor
|
||||||
|
|
||||||
|
@monitor.setter
|
||||||
|
def monitor(self, monitor):
|
||||||
|
"""
|
||||||
|
Sets the TCP monitor port.
|
||||||
|
|
||||||
|
:param monitor: monitor port (integer)
|
||||||
|
"""
|
||||||
|
|
||||||
|
if monitor in self._allocated_monitor_ports:
|
||||||
|
raise QemuError("Monitor port {} is already used by another QEMU VM".format(monitor))
|
||||||
|
|
||||||
|
self._allocated_monitor_ports.remove(self._monitor)
|
||||||
|
self._monitor = monitor
|
||||||
|
self._allocated_monitor_ports.append(self._monitor)
|
||||||
|
|
||||||
|
log.info("QEMU VM {name} [id={id}]: monitor port set to {port}".format(name=self._name,
|
||||||
|
id=self._id,
|
||||||
|
port=monitor))
|
||||||
|
|
||||||
def delete(self):
|
def delete(self):
|
||||||
"""
|
"""
|
||||||
Deletes this QEMU VM.
|
Deletes this QEMU VM.
|
||||||
@ -276,8 +335,11 @@ class QemuVM(object):
|
|||||||
if self._id in self._instances:
|
if self._id in self._instances:
|
||||||
self._instances.remove(self._id)
|
self._instances.remove(self._id)
|
||||||
|
|
||||||
if self.console and self.console in self._allocated_console_ports:
|
if self._console and self._console in self._allocated_console_ports:
|
||||||
self._allocated_console_ports.remove(self.console)
|
self._allocated_console_ports.remove(self._console)
|
||||||
|
|
||||||
|
if self._monitor and self._monitor in self._allocated_monitor_ports:
|
||||||
|
self._allocated_monitor_ports.remove(self._monitor)
|
||||||
|
|
||||||
log.info("QEMU VM {name} [id={id}] has been deleted".format(name=self._name,
|
log.info("QEMU VM {name} [id={id}] has been deleted".format(name=self._name,
|
||||||
id=self._id))
|
id=self._id))
|
||||||
@ -291,8 +353,11 @@ class QemuVM(object):
|
|||||||
if self._id in self._instances:
|
if self._id in self._instances:
|
||||||
self._instances.remove(self._id)
|
self._instances.remove(self._id)
|
||||||
|
|
||||||
if self.console:
|
if self._console:
|
||||||
self._allocated_console_ports.remove(self.console)
|
self._allocated_console_ports.remove(self._console)
|
||||||
|
|
||||||
|
if self._monitor:
|
||||||
|
self._allocated_monitor_ports.remove(self._monitor)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
shutil.rmtree(self._working_dir)
|
shutil.rmtree(self._working_dir)
|
||||||
@ -718,7 +783,13 @@ class QemuVM(object):
|
|||||||
Starts this QEMU VM.
|
Starts this QEMU VM.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if not self.is_running():
|
if self.is_running():
|
||||||
|
|
||||||
|
# resume the VM if it is paused
|
||||||
|
self.resume()
|
||||||
|
return
|
||||||
|
|
||||||
|
else:
|
||||||
|
|
||||||
if not os.path.isfile(self._qemu_path) or not os.path.exists(self._qemu_path):
|
if not os.path.isfile(self._qemu_path) or not os.path.exists(self._qemu_path):
|
||||||
found = False
|
found = False
|
||||||
@ -825,26 +896,77 @@ class QemuVM(object):
|
|||||||
self._started = False
|
self._started = False
|
||||||
self._stop_cpulimit()
|
self._stop_cpulimit()
|
||||||
|
|
||||||
|
def _control_vm(self, command, expected=None, timeout=30):
|
||||||
|
"""
|
||||||
|
Executes a command with QEMU monitor when this VM is running.
|
||||||
|
|
||||||
|
:param command: QEMU monitor command (e.g. info status, stop etc.)
|
||||||
|
:param timeout: how long to wait for QEMU monitor
|
||||||
|
|
||||||
|
:returns: result of the command (string)
|
||||||
|
"""
|
||||||
|
|
||||||
|
result = None
|
||||||
|
if self.is_running() and self._monitor:
|
||||||
|
log.debug("Execute QEMU monitor command: {}".format(command))
|
||||||
|
tn = telnetlib.Telnet(self._monitor_host, self._monitor, timeout=timeout)
|
||||||
|
try:
|
||||||
|
tn.write(command.encode('ascii') + b"\n")
|
||||||
|
except OSError as e:
|
||||||
|
log.warn("Could not write to QEMU monitor: {}".format(e))
|
||||||
|
tn.close()
|
||||||
|
return result
|
||||||
|
if expected:
|
||||||
|
try:
|
||||||
|
ind, obj, dat = tn.expect(list=expected, timeout=timeout)
|
||||||
|
if ind >= 0:
|
||||||
|
result = expected[ind].decode('ascii')
|
||||||
|
except EOFError as e:
|
||||||
|
log.warn("Could not read from QEMU monitor: {}".format(e))
|
||||||
|
tn.close()
|
||||||
|
return result
|
||||||
|
|
||||||
|
def _get_vm_status(self):
|
||||||
|
"""
|
||||||
|
Returns this VM suspend status (running|paused)
|
||||||
|
|
||||||
|
:returns: status (string)
|
||||||
|
"""
|
||||||
|
|
||||||
|
result = self._control_vm("info status", [b"running", b"paused"])
|
||||||
|
return result
|
||||||
|
|
||||||
def suspend(self):
|
def suspend(self):
|
||||||
"""
|
"""
|
||||||
Suspends this QEMU VM.
|
Suspends this QEMU VM.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
pass
|
vm_status = self._get_vm_status()
|
||||||
|
if vm_status == "running":
|
||||||
|
self._control_vm("stop")
|
||||||
|
log.debug("QEMU VM has been suspended")
|
||||||
|
else:
|
||||||
|
log.info("QEMU VM is not running to be suspended, current status is {}".format(vm_status))
|
||||||
|
|
||||||
def reload(self):
|
def reload(self):
|
||||||
"""
|
"""
|
||||||
Reloads this QEMU VM.
|
Reloads this QEMU VM.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
pass
|
self._control_vm("system_reset")
|
||||||
|
log.debug("QEMU VM has been reset")
|
||||||
|
|
||||||
def resume(self):
|
def resume(self):
|
||||||
"""
|
"""
|
||||||
Resumes this QEMU VM.
|
Resumes this QEMU VM.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
pass
|
vm_status = self._get_vm_status()
|
||||||
|
if vm_status == "paused":
|
||||||
|
self._control_vm("cont")
|
||||||
|
log.debug("QEMU VM has been resumed")
|
||||||
|
else:
|
||||||
|
log.info("QEMU VM is not paused to be resumed, current status is {}".format(vm_status))
|
||||||
|
|
||||||
def port_add_nio_binding(self, adapter_id, nio):
|
def port_add_nio_binding(self, adapter_id, nio):
|
||||||
"""
|
"""
|
||||||
@ -941,6 +1063,13 @@ class QemuVM(object):
|
|||||||
else:
|
else:
|
||||||
return []
|
return []
|
||||||
|
|
||||||
|
def _monitor_options(self):
|
||||||
|
|
||||||
|
if self._monitor:
|
||||||
|
return ["-monitor", "telnet:{}:{},server,nowait".format(self._monitor_host, self._monitor)]
|
||||||
|
else:
|
||||||
|
return []
|
||||||
|
|
||||||
def _disk_options(self):
|
def _disk_options(self):
|
||||||
|
|
||||||
options = []
|
options = []
|
||||||
@ -1047,6 +1176,7 @@ class QemuVM(object):
|
|||||||
command.extend(self._disk_options())
|
command.extend(self._disk_options())
|
||||||
command.extend(self._linux_boot_options())
|
command.extend(self._linux_boot_options())
|
||||||
command.extend(self._serial_options())
|
command.extend(self._serial_options())
|
||||||
|
command.extend(self._monitor_options())
|
||||||
additional_options = self._options.strip()
|
additional_options = self._options.strip()
|
||||||
if additional_options:
|
if additional_options:
|
||||||
command.extend(shlex.split(additional_options))
|
command.extend(shlex.split(additional_options))
|
||||||
|
@ -41,6 +41,12 @@ QEMU_CREATE_SCHEMA = {
|
|||||||
"maximum": 65535,
|
"maximum": 65535,
|
||||||
"type": "integer"
|
"type": "integer"
|
||||||
},
|
},
|
||||||
|
"monitor": {
|
||||||
|
"description": "monitor TCP port",
|
||||||
|
"minimum": 1,
|
||||||
|
"maximum": 65535,
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
},
|
},
|
||||||
"additionalProperties": False,
|
"additionalProperties": False,
|
||||||
"required": ["name", "qemu_path"],
|
"required": ["name", "qemu_path"],
|
||||||
@ -108,6 +114,12 @@ QEMU_UPDATE_SCHEMA = {
|
|||||||
"maximum": 65535,
|
"maximum": 65535,
|
||||||
"type": "integer"
|
"type": "integer"
|
||||||
},
|
},
|
||||||
|
"monitor": {
|
||||||
|
"description": "monitor TCP port",
|
||||||
|
"minimum": 1,
|
||||||
|
"maximum": 65535,
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
"initrd": {
|
"initrd": {
|
||||||
"description": "QEMU initrd path",
|
"description": "QEMU initrd path",
|
||||||
"type": "string",
|
"type": "string",
|
||||||
|
Loading…
Reference in New Issue
Block a user