mirror of
https://github.com/GNS3/gns3-server.git
synced 2024-12-20 05:17:56 +00:00
Possibility to customize port names and adapter types for Qemu, VirtualBox, VMware and Docker. Fixes #2361.
MAC addresses can customized for Qemu as well.
This commit is contained in:
parent
509b171b06
commit
757c103c03
@ -77,6 +77,7 @@ class BaseNode:
|
|||||||
self._wrap_console = wrap_console
|
self._wrap_console = wrap_console
|
||||||
self._wrapper_telnet_server = None
|
self._wrapper_telnet_server = None
|
||||||
self._internal_console_port = None
|
self._internal_console_port = None
|
||||||
|
self._custom_adapters = []
|
||||||
|
|
||||||
if self._console is not None:
|
if self._console is not None:
|
||||||
if console_type == "vnc":
|
if console_type == "vnc":
|
||||||
@ -123,6 +124,14 @@ class BaseNode:
|
|||||||
def linked_clone(self, val):
|
def linked_clone(self, val):
|
||||||
self._linked_clone = val
|
self._linked_clone = val
|
||||||
|
|
||||||
|
@property
|
||||||
|
def custom_adapters(self):
|
||||||
|
return self._custom_adapters
|
||||||
|
|
||||||
|
@custom_adapters.setter
|
||||||
|
def custom_adapters(self, val):
|
||||||
|
self._custom_adapters = val
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def status(self):
|
def status(self):
|
||||||
"""
|
"""
|
||||||
@ -760,3 +769,10 @@ class BaseNode:
|
|||||||
percentage_left,
|
percentage_left,
|
||||||
platform.node())
|
platform.node())
|
||||||
self.project.emit("log.warning", {"message": message})
|
self.project.emit("log.warning", {"message": message})
|
||||||
|
|
||||||
|
def _get_custom_adapter_settings(self, adapter_number):
|
||||||
|
|
||||||
|
for custom_adapter in self.custom_adapters:
|
||||||
|
if custom_adapter["adapter_number"] == adapter_number:
|
||||||
|
return custom_adapter
|
||||||
|
return {}
|
||||||
|
@ -1696,10 +1696,17 @@ class QemuVM(BaseNode):
|
|||||||
if adapter_number not in self._local_udp_tunnels:
|
if adapter_number not in self._local_udp_tunnels:
|
||||||
self._local_udp_tunnels[adapter_number] = self._create_local_udp_tunnel()
|
self._local_udp_tunnels[adapter_number] = self._create_local_udp_tunnel()
|
||||||
nio = self._local_udp_tunnels[adapter_number][0]
|
nio = self._local_udp_tunnels[adapter_number][0]
|
||||||
|
|
||||||
|
custom_adapter = self._get_custom_adapter_settings(adapter_number)
|
||||||
|
adapter_type = custom_adapter.get("adapter_type", self._adapter_type)
|
||||||
|
custom_mac_address = custom_adapter.get("mac_address")
|
||||||
|
if custom_mac_address:
|
||||||
|
mac = int_to_macaddress(macaddress_to_int(custom_mac_address))
|
||||||
|
|
||||||
if self._legacy_networking:
|
if self._legacy_networking:
|
||||||
# legacy QEMU networking syntax (-net)
|
# legacy QEMU networking syntax (-net)
|
||||||
if nio:
|
if nio:
|
||||||
network_options.extend(["-net", "nic,vlan={},macaddr={},model={}".format(adapter_number, mac, self._adapter_type)])
|
network_options.extend(["-net", "nic,vlan={},macaddr={},model={}".format(adapter_number, mac, adapter_type)])
|
||||||
if isinstance(nio, NIOUDP):
|
if isinstance(nio, NIOUDP):
|
||||||
if patched_qemu:
|
if patched_qemu:
|
||||||
# use patched Qemu syntax
|
# use patched Qemu syntax
|
||||||
@ -1719,11 +1726,11 @@ class QemuVM(BaseNode):
|
|||||||
elif isinstance(nio, NIOTAP):
|
elif isinstance(nio, NIOTAP):
|
||||||
network_options.extend(["-net", "tap,name=gns3-{},ifname={}".format(adapter_number, nio.tap_device)])
|
network_options.extend(["-net", "tap,name=gns3-{},ifname={}".format(adapter_number, nio.tap_device)])
|
||||||
else:
|
else:
|
||||||
network_options.extend(["-net", "nic,vlan={},macaddr={},model={}".format(adapter_number, mac, self._adapter_type)])
|
network_options.extend(["-net", "nic,vlan={},macaddr={},model={}".format(adapter_number, mac, adapter_type)])
|
||||||
|
|
||||||
else:
|
else:
|
||||||
# newer QEMU networking syntax
|
# newer QEMU networking syntax
|
||||||
device_string = "{},mac={}".format(self._adapter_type, mac)
|
device_string = "{},mac={}".format(adapter_type, mac)
|
||||||
bridge_id = math.floor(pci_device_id / 32)
|
bridge_id = math.floor(pci_device_id / 32)
|
||||||
if bridge_id > 0:
|
if bridge_id > 0:
|
||||||
addr = pci_device_id % 32
|
addr = pci_device_id % 32
|
||||||
|
@ -852,18 +852,22 @@ class VirtualBoxVM(BaseNode):
|
|||||||
continue
|
continue
|
||||||
|
|
||||||
yield from self._modify_vm("--nictrace{} off".format(adapter_number + 1))
|
yield from self._modify_vm("--nictrace{} off".format(adapter_number + 1))
|
||||||
|
|
||||||
|
custom_adapter = self._get_custom_adapter_settings(adapter_number)
|
||||||
|
adapter_type = custom_adapter.get("adapter_type", self._adapter_type)
|
||||||
|
|
||||||
vbox_adapter_type = "82540EM"
|
vbox_adapter_type = "82540EM"
|
||||||
if self._adapter_type == "PCnet-PCI II (Am79C970A)":
|
if adapter_type == "PCnet-PCI II (Am79C970A)":
|
||||||
vbox_adapter_type = "Am79C970A"
|
vbox_adapter_type = "Am79C970A"
|
||||||
if self._adapter_type == "PCNet-FAST III (Am79C973)":
|
if adapter_type == "PCNet-FAST III (Am79C973)":
|
||||||
vbox_adapter_type = "Am79C973"
|
vbox_adapter_type = "Am79C973"
|
||||||
if self._adapter_type == "Intel PRO/1000 MT Desktop (82540EM)":
|
if adapter_type == "Intel PRO/1000 MT Desktop (82540EM)":
|
||||||
vbox_adapter_type = "82540EM"
|
vbox_adapter_type = "82540EM"
|
||||||
if self._adapter_type == "Intel PRO/1000 T Server (82543GC)":
|
if adapter_type == "Intel PRO/1000 T Server (82543GC)":
|
||||||
vbox_adapter_type = "82543GC"
|
vbox_adapter_type = "82543GC"
|
||||||
if self._adapter_type == "Intel PRO/1000 MT Server (82545EM)":
|
if adapter_type == "Intel PRO/1000 MT Server (82545EM)":
|
||||||
vbox_adapter_type = "82545EM"
|
vbox_adapter_type = "82545EM"
|
||||||
if self._adapter_type == "Paravirtualized Network (virtio-net)":
|
if adapter_type == "Paravirtualized Network (virtio-net)":
|
||||||
vbox_adapter_type = "virtio"
|
vbox_adapter_type = "virtio"
|
||||||
args = [self._vmname, "--nictype{}".format(adapter_number + 1), vbox_adapter_type]
|
args = [self._vmname, "--nictype{}".format(adapter_number + 1), vbox_adapter_type]
|
||||||
yield from self.manager.execute("modifyvm", args)
|
yield from self.manager.execute("modifyvm", args)
|
||||||
|
@ -258,17 +258,20 @@ class VMwareVM(BaseNode):
|
|||||||
self.manager.refresh_vmnet_list()
|
self.manager.refresh_vmnet_list()
|
||||||
for adapter_number in range(0, self._adapters):
|
for adapter_number in range(0, self._adapters):
|
||||||
|
|
||||||
|
custom_adapter = self._get_custom_adapter_settings(adapter_number)
|
||||||
|
adapter_type = custom_adapter.get("adapter_type", self._adapter_type)
|
||||||
|
|
||||||
# add/update the interface
|
# add/update the interface
|
||||||
if self._adapter_type == "default":
|
if adapter_type == "default":
|
||||||
# force default to e1000 because some guest OS don't detect the adapter (i.e. Windows 2012 server)
|
# force default to e1000 because some guest OS don't detect the adapter (i.e. Windows 2012 server)
|
||||||
# when 'virtualdev' is not set in the VMX file.
|
# when 'virtualdev' is not set in the VMX file.
|
||||||
adapter_type = "e1000"
|
vmware_adapter_type = "e1000"
|
||||||
else:
|
else:
|
||||||
adapter_type = self._adapter_type
|
vmware_adapter_type = adapter_type
|
||||||
ethernet_adapter = {"ethernet{}.present".format(adapter_number): "TRUE",
|
ethernet_adapter = {"ethernet{}.present".format(adapter_number): "TRUE",
|
||||||
"ethernet{}.addresstype".format(adapter_number): "generated",
|
"ethernet{}.addresstype".format(adapter_number): "generated",
|
||||||
"ethernet{}.generatedaddressoffset".format(adapter_number): "0",
|
"ethernet{}.generatedaddressoffset".format(adapter_number): "0",
|
||||||
"ethernet{}.virtualdev".format(adapter_number): adapter_type}
|
"ethernet{}.virtualdev".format(adapter_number): vmware_adapter_type}
|
||||||
self._vmx_pairs.update(ethernet_adapter)
|
self._vmx_pairs.update(ethernet_adapter)
|
||||||
|
|
||||||
connection_type = "ethernet{}.connectiontype".format(adapter_number)
|
connection_type = "ethernet{}.connectiontype".format(adapter_number)
|
||||||
|
@ -74,6 +74,7 @@ class Node:
|
|||||||
self._z = 0
|
self._z = 0
|
||||||
self._ports = None
|
self._ports = None
|
||||||
self._symbol = None
|
self._symbol = None
|
||||||
|
self._custom_adapters = []
|
||||||
if node_type == "iou":
|
if node_type == "iou":
|
||||||
self._port_name_format = "Ethernet{segment0}/{port0}"
|
self._port_name_format = "Ethernet{segment0}/{port0}"
|
||||||
self._port_by_adapter = 4
|
self._port_by_adapter = 4
|
||||||
@ -305,6 +306,14 @@ class Node:
|
|||||||
def first_port_name(self, val):
|
def first_port_name(self, val):
|
||||||
self._first_port_name = val
|
self._first_port_name = val
|
||||||
|
|
||||||
|
@property
|
||||||
|
def custom_adapters(self):
|
||||||
|
return self._custom_adapters
|
||||||
|
|
||||||
|
@custom_adapters.setter
|
||||||
|
def custom_adapters(self, val):
|
||||||
|
self._custom_adapters = val
|
||||||
|
|
||||||
def add_link(self, link):
|
def add_link(self, link):
|
||||||
"""
|
"""
|
||||||
A link is connected to the node
|
A link is connected to the node
|
||||||
@ -330,6 +339,7 @@ class Node:
|
|||||||
data["node_id"] = self._id
|
data["node_id"] = self._id
|
||||||
if self._node_type == "docker":
|
if self._node_type == "docker":
|
||||||
timeout = None
|
timeout = None
|
||||||
|
|
||||||
else:
|
else:
|
||||||
timeout = 1200
|
timeout = 1200
|
||||||
trial = 0
|
trial = 0
|
||||||
@ -374,6 +384,9 @@ class Node:
|
|||||||
else:
|
else:
|
||||||
setattr(self, prop, kwargs[prop])
|
setattr(self, prop, kwargs[prop])
|
||||||
|
|
||||||
|
if compute_properties and "custom_adapters" in compute_properties:
|
||||||
|
# we need to check custom adapters to update the custom port names
|
||||||
|
self.custom_adapters = compute_properties["custom_adapters"]
|
||||||
self._list_ports()
|
self._list_ports()
|
||||||
if update_compute:
|
if update_compute:
|
||||||
data = self._node_data(properties=compute_properties)
|
data = self._node_data(properties=compute_properties)
|
||||||
@ -442,6 +455,8 @@ class Node:
|
|||||||
data["console"] = self._console
|
data["console"] = self._console
|
||||||
if self._console_type:
|
if self._console_type:
|
||||||
data["console_type"] = self._console_type
|
data["console_type"] = self._console_type
|
||||||
|
if self.custom_adapters:
|
||||||
|
data["custom_adapters"] = self.custom_adapters
|
||||||
|
|
||||||
# None properties are not be send. Because it can mean the emulator doesn't support it
|
# None properties are not be send. Because it can mean the emulator doesn't support it
|
||||||
for key in list(data.keys()):
|
for key in list(data.keys()):
|
||||||
@ -585,7 +600,7 @@ class Node:
|
|||||||
"""
|
"""
|
||||||
Generate the list of port display in the client
|
Generate the list of port display in the client
|
||||||
if the compute has sent a list we return it (use by
|
if the compute has sent a list we return it (use by
|
||||||
node where you can not personnalize the port naming).
|
node where you can not personalize the port naming).
|
||||||
"""
|
"""
|
||||||
self._ports = []
|
self._ports = []
|
||||||
# Some special cases
|
# Some special cases
|
||||||
@ -615,7 +630,14 @@ class Node:
|
|||||||
return
|
return
|
||||||
elif self._node_type == "docker":
|
elif self._node_type == "docker":
|
||||||
for adapter_number in range(0, self._properties["adapters"]):
|
for adapter_number in range(0, self._properties["adapters"]):
|
||||||
self._ports.append(PortFactory("eth{}".format(adapter_number), 0, adapter_number, 0, "ethernet", short_name="eth{}".format(adapter_number)))
|
custom_adapter_settings = {}
|
||||||
|
for custom_adapter in self.custom_adapters:
|
||||||
|
if custom_adapter["adapter_number"] == adapter_number:
|
||||||
|
custom_adapter_settings = custom_adapter
|
||||||
|
break
|
||||||
|
port_name = "eth{}".format(adapter_number)
|
||||||
|
port_name = custom_adapter_settings.get("port_name", port_name)
|
||||||
|
self._ports.append(PortFactory(port_name, 0, adapter_number, 0, "ethernet", short_name="eth{}".format(adapter_number)))
|
||||||
elif self._node_type in ("ethernet_switch", "ethernet_hub"):
|
elif self._node_type in ("ethernet_switch", "ethernet_hub"):
|
||||||
# Basic node we don't want to have adapter number
|
# Basic node we don't want to have adapter number
|
||||||
port_number = 0
|
port_number = 0
|
||||||
@ -630,7 +652,7 @@ class Node:
|
|||||||
self._ports.append(PortFactory(port["name"], 0, 0, port_number, "ethernet", short_name=port["name"]))
|
self._ports.append(PortFactory(port["name"], 0, 0, port_number, "ethernet", short_name=port["name"]))
|
||||||
port_number += 1
|
port_number += 1
|
||||||
else:
|
else:
|
||||||
self._ports = StandardPortFactory(self._properties, self._port_by_adapter, self._first_port_name, self._port_name_format, self._port_segment_size)
|
self._ports = StandardPortFactory(self._properties, self._port_by_adapter, self._first_port_name, self._port_name_format, self._port_segment_size, self._custom_adapters)
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return "<gns3server.controller.Node {} {}>".format(self._node_type, self._name)
|
return "<gns3server.controller.Node {} {}>".format(self._node_type, self._name)
|
||||||
@ -644,6 +666,7 @@ class Node:
|
|||||||
"""
|
"""
|
||||||
:param topology_dump: Filter to keep only properties require for saving on disk
|
:param topology_dump: Filter to keep only properties require for saving on disk
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if topology_dump:
|
if topology_dump:
|
||||||
return {
|
return {
|
||||||
"compute_id": str(self._compute.id),
|
"compute_id": str(self._compute.id),
|
||||||
@ -662,7 +685,8 @@ class Node:
|
|||||||
"symbol": self._symbol,
|
"symbol": self._symbol,
|
||||||
"port_name_format": self._port_name_format,
|
"port_name_format": self._port_name_format,
|
||||||
"port_segment_size": self._port_segment_size,
|
"port_segment_size": self._port_segment_size,
|
||||||
"first_port_name": self._first_port_name
|
"first_port_name": self._first_port_name,
|
||||||
|
"custom_adapters": self._custom_adapters
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
"compute_id": str(self._compute.id),
|
"compute_id": str(self._compute.id),
|
||||||
@ -687,5 +711,6 @@ class Node:
|
|||||||
"port_name_format": self._port_name_format,
|
"port_name_format": self._port_name_format,
|
||||||
"port_segment_size": self._port_segment_size,
|
"port_segment_size": self._port_segment_size,
|
||||||
"first_port_name": self._first_port_name,
|
"first_port_name": self._first_port_name,
|
||||||
|
"custom_adapters": self._custom_adapters,
|
||||||
"ports": [port.__json__() for port in self.ports]
|
"ports": [port.__json__() for port in self.ports]
|
||||||
}
|
}
|
||||||
|
@ -51,7 +51,7 @@ class StandardPortFactory:
|
|||||||
"""
|
"""
|
||||||
Create ports for standard device
|
Create ports for standard device
|
||||||
"""
|
"""
|
||||||
def __new__(cls, properties, port_by_adapter, first_port_name, port_name_format, port_segment_size):
|
def __new__(cls, properties, port_by_adapter, first_port_name, port_name_format, port_segment_size, custom_adapters):
|
||||||
ports = []
|
ports = []
|
||||||
adapter_number = interface_number = segment_number = 0
|
adapter_number = interface_number = segment_number = 0
|
||||||
|
|
||||||
@ -61,9 +61,16 @@ class StandardPortFactory:
|
|||||||
ethernet_adapters = properties.get("adapters", 1)
|
ethernet_adapters = properties.get("adapters", 1)
|
||||||
|
|
||||||
for adapter_number in range(adapter_number, ethernet_adapters + adapter_number):
|
for adapter_number in range(adapter_number, ethernet_adapters + adapter_number):
|
||||||
|
|
||||||
|
custom_adapter_settings = {}
|
||||||
|
for custom_adapter in custom_adapters:
|
||||||
|
if custom_adapter["adapter_number"] == adapter_number:
|
||||||
|
custom_adapter_settings = custom_adapter
|
||||||
|
break
|
||||||
|
|
||||||
for port_number in range(0, port_by_adapter):
|
for port_number in range(0, port_by_adapter):
|
||||||
if first_port_name and adapter_number == 0:
|
if first_port_name and adapter_number == 0:
|
||||||
port_name = first_port_name
|
port_name = custom_adapter_settings.get("port_name", first_port_name)
|
||||||
port = PortFactory(port_name, segment_number, adapter_number, port_number, "ethernet")
|
port = PortFactory(port_name, segment_number, adapter_number, port_number, "ethernet")
|
||||||
else:
|
else:
|
||||||
try:
|
try:
|
||||||
@ -74,6 +81,8 @@ class StandardPortFactory:
|
|||||||
**cls._generate_replacement(interface_number, segment_number))
|
**cls._generate_replacement(interface_number, segment_number))
|
||||||
except (ValueError, KeyError) as e:
|
except (ValueError, KeyError) as e:
|
||||||
raise aiohttp.web.HTTPConflict(text="Invalid port name format {}: {}".format(port_name_format, str(e)))
|
raise aiohttp.web.HTTPConflict(text="Invalid port name format {}: {}".format(port_name_format, str(e)))
|
||||||
|
|
||||||
|
port_name = custom_adapter_settings.get("port_name", port_name)
|
||||||
port = PortFactory(port_name, segment_number, adapter_number, port_number, "ethernet")
|
port = PortFactory(port_name, segment_number, adapter_number, port_number, "ethernet")
|
||||||
interface_number += 1
|
interface_number += 1
|
||||||
if port_segment_size:
|
if port_segment_size:
|
||||||
|
@ -221,7 +221,7 @@ class DockerHandler:
|
|||||||
"project_id": "Project UUID",
|
"project_id": "Project UUID",
|
||||||
"node_id": "Node UUID",
|
"node_id": "Node UUID",
|
||||||
"adapter_number": "Adapter where the nio should be added",
|
"adapter_number": "Adapter where the nio should be added",
|
||||||
"port_number": "Port on the adapter"
|
"port_number": "Port on the adapter (always 0)"
|
||||||
},
|
},
|
||||||
status_codes={
|
status_codes={
|
||||||
201: "NIO created",
|
201: "NIO created",
|
||||||
|
49
gns3server/schemas/custom_adapters.py
Normal file
49
gns3server/schemas/custom_adapters.py
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
#
|
||||||
|
# Copyright (C) 2016 GNS3 Technologies Inc.
|
||||||
|
#
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
CUSTOM_ADAPTERS_ARRAY_SCHEMA = {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "object",
|
||||||
|
"description": "Custom properties",
|
||||||
|
"properties": {
|
||||||
|
"adapter_number": {
|
||||||
|
"type": "integer",
|
||||||
|
"description": "Adapter number"
|
||||||
|
},
|
||||||
|
"port_name": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Custom port name",
|
||||||
|
"minLength": 1,
|
||||||
|
},
|
||||||
|
"adapter_type": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Custom adapter type",
|
||||||
|
"minLength": 1,
|
||||||
|
},
|
||||||
|
"mac_address": {
|
||||||
|
"description": "Custom MAC address",
|
||||||
|
"type": "string",
|
||||||
|
"minLength": 1,
|
||||||
|
"pattern": "^([0-9a-fA-F]{2}[:]){5}([0-9a-fA-F]{2})$"
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"additionalProperties": False,
|
||||||
|
"required": ["adapter_number"]
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
@ -16,6 +16,9 @@
|
|||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
|
||||||
|
from .custom_adapters import CUSTOM_ADAPTERS_ARRAY_SCHEMA
|
||||||
|
|
||||||
|
|
||||||
DOCKER_CREATE_SCHEMA = {
|
DOCKER_CREATE_SCHEMA = {
|
||||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||||
"description": "Request validation to create a new Docker container",
|
"description": "Request validation to create a new Docker container",
|
||||||
@ -93,7 +96,8 @@ DOCKER_CREATE_SCHEMA = {
|
|||||||
"minLength": 12,
|
"minLength": 12,
|
||||||
"maxLength": 64,
|
"maxLength": 64,
|
||||||
"pattern": "^[a-f0-9]+$"
|
"pattern": "^[a-f0-9]+$"
|
||||||
}
|
},
|
||||||
|
"custom_adapters": CUSTOM_ADAPTERS_ARRAY_SCHEMA # not used at this time
|
||||||
},
|
},
|
||||||
"additionalProperties": False,
|
"additionalProperties": False,
|
||||||
"required": ["name", "image"]
|
"required": ["name", "image"]
|
||||||
@ -192,6 +196,7 @@ DOCKER_OBJECT_SCHEMA = {
|
|||||||
"description": "VM status Read only",
|
"description": "VM status Read only",
|
||||||
"enum": ["started", "stopped", "suspended"]
|
"enum": ["started", "stopped", "suspended"]
|
||||||
},
|
},
|
||||||
|
"custom_adapters": CUSTOM_ADAPTERS_ARRAY_SCHEMA # not used at this time
|
||||||
},
|
},
|
||||||
"additionalProperties": False,
|
"additionalProperties": False,
|
||||||
}
|
}
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
|
|
||||||
import copy
|
import copy
|
||||||
from .label import LABEL_OBJECT_SCHEMA
|
from .label import LABEL_OBJECT_SCHEMA
|
||||||
|
from .custom_adapters import CUSTOM_ADAPTERS_ARRAY_SCHEMA
|
||||||
|
|
||||||
NODE_TYPE_SCHEMA = {
|
NODE_TYPE_SCHEMA = {
|
||||||
"description": "Type of node",
|
"description": "Type of node",
|
||||||
@ -194,6 +195,7 @@ NODE_OBJECT_SCHEMA = {
|
|||||||
"description": "Name of the first port",
|
"description": "Name of the first port",
|
||||||
"type": ["string", "null"],
|
"type": ["string", "null"],
|
||||||
},
|
},
|
||||||
|
"custom_adapters": CUSTOM_ADAPTERS_ARRAY_SCHEMA,
|
||||||
"ports": {
|
"ports": {
|
||||||
"description": "List of node ports READ only",
|
"description": "List of node ports READ only",
|
||||||
"type": "array",
|
"type": "array",
|
||||||
|
@ -15,6 +15,8 @@
|
|||||||
# You should have received a copy of the GNU General Public License
|
# You should have received a copy of the GNU General Public License
|
||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
from .custom_adapters import CUSTOM_ADAPTERS_ARRAY_SCHEMA
|
||||||
|
|
||||||
QEMU_PLATFORMS = ["aarch64", "alpha", "arm", "cris", "i386", "lm32", "m68k", "microblaze", "microblazeel", "mips", "mips64", "mips64el", "mipsel", "moxie", "or32", "ppc", "ppc64", "ppcemb", "s390x", "sh4", "sh4eb", "sparc", "sparc64", "tricore", "unicore32", "x86_64", "xtensa", "xtensaeb"]
|
QEMU_PLATFORMS = ["aarch64", "alpha", "arm", "cris", "i386", "lm32", "m68k", "microblaze", "microblazeel", "mips", "mips64", "mips64el", "mipsel", "moxie", "or32", "ppc", "ppc64", "ppcemb", "s390x", "sh4", "sh4eb", "sparc", "sparc64", "tricore", "unicore32", "x86_64", "xtensa", "xtensaeb"]
|
||||||
|
|
||||||
|
|
||||||
@ -207,7 +209,8 @@ QEMU_CREATE_SCHEMA = {
|
|||||||
"options": {
|
"options": {
|
||||||
"description": "Additional QEMU options",
|
"description": "Additional QEMU options",
|
||||||
"type": ["string", "null"],
|
"type": ["string", "null"],
|
||||||
}
|
},
|
||||||
|
"custom_adapters": CUSTOM_ADAPTERS_ARRAY_SCHEMA
|
||||||
},
|
},
|
||||||
"additionalProperties": False,
|
"additionalProperties": False,
|
||||||
"required": ["name"],
|
"required": ["name"],
|
||||||
@ -392,7 +395,8 @@ QEMU_UPDATE_SCHEMA = {
|
|||||||
"options": {
|
"options": {
|
||||||
"description": "Additional QEMU options",
|
"description": "Additional QEMU options",
|
||||||
"type": ["string", "null"],
|
"type": ["string", "null"],
|
||||||
}
|
},
|
||||||
|
"custom_adapters": CUSTOM_ADAPTERS_ARRAY_SCHEMA
|
||||||
},
|
},
|
||||||
"additionalProperties": False,
|
"additionalProperties": False,
|
||||||
}
|
}
|
||||||
|
@ -16,6 +16,9 @@
|
|||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
|
||||||
|
from .custom_adapters import CUSTOM_ADAPTERS_ARRAY_SCHEMA
|
||||||
|
|
||||||
|
|
||||||
VBOX_CREATE_SCHEMA = {
|
VBOX_CREATE_SCHEMA = {
|
||||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||||
"description": "Request validation to create a new VirtualBox VM instance",
|
"description": "Request validation to create a new VirtualBox VM instance",
|
||||||
@ -84,6 +87,7 @@ VBOX_CREATE_SCHEMA = {
|
|||||||
"description": "Action to execute on the VM is closed",
|
"description": "Action to execute on the VM is closed",
|
||||||
"enum": ["power_off", "shutdown_signal", "save_vm_state"],
|
"enum": ["power_off", "shutdown_signal", "save_vm_state"],
|
||||||
},
|
},
|
||||||
|
"custom_adapters": CUSTOM_ADAPTERS_ARRAY_SCHEMA
|
||||||
},
|
},
|
||||||
"additionalProperties": False,
|
"additionalProperties": False,
|
||||||
"required": ["name", "vmname"],
|
"required": ["name", "vmname"],
|
||||||
@ -169,7 +173,8 @@ VBOX_OBJECT_SCHEMA = {
|
|||||||
"linked_clone": {
|
"linked_clone": {
|
||||||
"description": "Whether the VM is a linked clone or not",
|
"description": "Whether the VM is a linked clone or not",
|
||||||
"type": "boolean"
|
"type": "boolean"
|
||||||
}
|
},
|
||||||
|
"custom_adapters": CUSTOM_ADAPTERS_ARRAY_SCHEMA
|
||||||
},
|
},
|
||||||
"additionalProperties": False,
|
"additionalProperties": False,
|
||||||
}
|
}
|
||||||
|
@ -15,6 +15,8 @@
|
|||||||
# You should have received a copy of the GNU General Public License
|
# You should have received a copy of the GNU General Public License
|
||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
from .custom_adapters import CUSTOM_ADAPTERS_ARRAY_SCHEMA
|
||||||
|
|
||||||
|
|
||||||
VMWARE_CREATE_SCHEMA = {
|
VMWARE_CREATE_SCHEMA = {
|
||||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||||
@ -74,7 +76,8 @@ VMWARE_CREATE_SCHEMA = {
|
|||||||
"use_any_adapter": {
|
"use_any_adapter": {
|
||||||
"description": "Allow GNS3 to use any VMware adapter",
|
"description": "Allow GNS3 to use any VMware adapter",
|
||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
}
|
},
|
||||||
|
"custom_adapters": CUSTOM_ADAPTERS_ARRAY_SCHEMA
|
||||||
},
|
},
|
||||||
"additionalProperties": False,
|
"additionalProperties": False,
|
||||||
"required": ["name", "vmx_path", "linked_clone"],
|
"required": ["name", "vmx_path", "linked_clone"],
|
||||||
@ -154,7 +157,8 @@ VMWARE_OBJECT_SCHEMA = {
|
|||||||
"linked_clone": {
|
"linked_clone": {
|
||||||
"description": "Whether the VM is a linked clone or not",
|
"description": "Whether the VM is a linked clone or not",
|
||||||
"type": "boolean"
|
"type": "boolean"
|
||||||
}
|
},
|
||||||
|
"custom_adapters": CUSTOM_ADAPTERS_ARRAY_SCHEMA
|
||||||
},
|
},
|
||||||
"additionalProperties": False
|
"additionalProperties": False
|
||||||
}
|
}
|
||||||
|
@ -141,6 +141,7 @@ def test_json(node, compute):
|
|||||||
"port_name_format": "Ethernet{0}",
|
"port_name_format": "Ethernet{0}",
|
||||||
"port_segment_size": 0,
|
"port_segment_size": 0,
|
||||||
"first_port_name": None,
|
"first_port_name": None,
|
||||||
|
"custom_adapters": [],
|
||||||
"ports": [
|
"ports": [
|
||||||
{
|
{
|
||||||
"adapter_number": 0,
|
"adapter_number": 0,
|
||||||
@ -169,7 +170,8 @@ def test_json(node, compute):
|
|||||||
"label": node.label,
|
"label": node.label,
|
||||||
"port_name_format": "Ethernet{0}",
|
"port_name_format": "Ethernet{0}",
|
||||||
"port_segment_size": 0,
|
"port_segment_size": 0,
|
||||||
"first_port_name": None
|
"first_port_name": None,
|
||||||
|
"custom_adapters": []
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user