mirror of
https://github.com/GNS3/gns3-gui.git
synced 2026-05-17 00:46:01 +03:00
Finalize appliance v8 support and add tests.
This commit is contained in:
@@ -94,9 +94,11 @@ class ApplianceWizard(QtWidgets.QWizard, Ui_ApplianceWizard):
|
||||
self.setWindowTitle("Install {} appliance".format(self._appliance["name"]))
|
||||
|
||||
# add a custom button to show appliance information
|
||||
self.setButtonText(QtWidgets.QWizard.CustomButton1, "&Appliance info")
|
||||
self.setOption(QtWidgets.QWizard.HaveCustomButton1, True)
|
||||
#self.customButtonClicked.connect(self._showApplianceInfoSlot)
|
||||
if self._appliance["registry_version"] < 8:
|
||||
# FIXME: show appliance info for v8
|
||||
self.setButtonText(QtWidgets.QWizard.CustomButton1, "&Appliance info")
|
||||
self.setOption(QtWidgets.QWizard.HaveCustomButton1, True)
|
||||
self.customButtonClicked.connect(self._showApplianceInfoSlot)
|
||||
|
||||
# customize the server selection
|
||||
self.uiRemoteRadioButton.toggled.connect(self._remoteServerToggledSlot)
|
||||
@@ -591,8 +593,8 @@ class ApplianceWizard(QtWidgets.QWizard, Ui_ApplianceWizard):
|
||||
if self._appliance["registry_version"] >= 8:
|
||||
if "settings" in appliance_configuration:
|
||||
for settings in appliance_configuration["settings"]:
|
||||
if settings["emulator_type"] == "qemu":
|
||||
settings["emulator_properties"]["path"] = self.uiQemuListComboBox.currentData()
|
||||
if settings["template_type"] == "qemu":
|
||||
settings["template_properties"]["path"] = self.uiQemuListComboBox.currentData()
|
||||
else:
|
||||
appliance_configuration["qemu"]["path"] = self.uiQemuListComboBox.currentData()
|
||||
|
||||
|
||||
@@ -74,7 +74,7 @@ class Appliance(collections.abc.Mapping):
|
||||
else:
|
||||
appliance_file = "appliance.json"
|
||||
|
||||
with open(get_resource("schemas/appliance.json")) as f:
|
||||
with open(get_resource("schemas/{}".format(appliance_file))) as f:
|
||||
schema = json.load(f)
|
||||
v = jsonschema.Draft4Validator(schema)
|
||||
try:
|
||||
@@ -161,7 +161,7 @@ class Appliance(collections.abc.Mapping):
|
||||
checksum_type = image.get("checksum_type", "md5") # md5 is the default and only supported type
|
||||
if checksum_type != "md5":
|
||||
raise ApplianceError("Checksum type {} is not supported".format(checksum_type))
|
||||
checksum = image.get("checksum")
|
||||
checksum = image.pop("checksum")
|
||||
|
||||
img = self._registry.search_image_file(self.template_type(), image["filename"], checksum, image.get("filesize"))
|
||||
if img is None:
|
||||
@@ -173,7 +173,7 @@ class Appliance(collections.abc.Mapping):
|
||||
image["path"] = img.path
|
||||
image["location"] = img.location
|
||||
|
||||
if not checksum:
|
||||
if "md5sum" not in image:
|
||||
image["md5sum"] = img.md5sum
|
||||
image["filesize"] = img.filesize
|
||||
|
||||
@@ -217,6 +217,8 @@ class Appliance(collections.abc.Mapping):
|
||||
elif settings["template_type"] and template_type != settings["template_type"]:
|
||||
# we are currently not supporting multiple different template types in the same appliance
|
||||
raise ApplianceError("Multiple different template types found in appliance")
|
||||
if not template_type:
|
||||
raise ApplianceError("No template type found in appliance {}".format(self._appliance["name"]))
|
||||
return template_type
|
||||
else:
|
||||
if "qemu" in self._appliance:
|
||||
|
||||
@@ -76,18 +76,29 @@ class ApplianceToTemplate:
|
||||
new_template["symbol"] = ":/symbols/firewall.svg"
|
||||
|
||||
if self._registry_version >= 8:
|
||||
for version in appliance_config["versions"]:
|
||||
if appliance_version and version["name"] == appliance_version:
|
||||
settings = self._get_settings(appliance_config, version.get("settings"))
|
||||
template_type = settings["template_type"]
|
||||
if template_type == "qemu":
|
||||
self._add_qemu_config(new_template, settings["template_properties"], appliance_config)
|
||||
elif template_type == "iou":
|
||||
self._add_iou_config(new_template, settings["template_properties"], appliance_config)
|
||||
elif template_type == "dynamips":
|
||||
self._add_dynamips_config(new_template, settings["template_properties"], appliance_config)
|
||||
elif template_type == "docker":
|
||||
self._add_docker_config(new_template, settings["template_properties"], appliance_config)
|
||||
if appliance_version:
|
||||
for version in appliance_config["versions"]:
|
||||
if appliance_version and version["name"] == appliance_version:
|
||||
# inject "usage", "category" and "symbol" specified at the version
|
||||
# level into the template properties
|
||||
usage = version.get("usage")
|
||||
if usage:
|
||||
new_template["usage"] = usage
|
||||
new_template["symbol"] = version.get("symbol", new_template["symbol"])
|
||||
new_template["category"] = version.get("category", new_template["category"])
|
||||
settings = self._get_settings(appliance_config, version.get("settings"))
|
||||
template_type = settings["template_type"]
|
||||
if template_type == "qemu":
|
||||
self._add_qemu_config(new_template, settings["template_properties"], appliance_config)
|
||||
elif template_type == "iou":
|
||||
self._add_iou_config(new_template, settings["template_properties"], appliance_config)
|
||||
elif template_type == "dynamips":
|
||||
self._add_dynamips_config(new_template, settings["template_properties"], appliance_config)
|
||||
else:
|
||||
# docker appliances have no version
|
||||
settings = self._get_settings(appliance_config)
|
||||
if settings["template_type"] == "docker":
|
||||
self._add_docker_config(new_template, settings["template_properties"], appliance_config)
|
||||
else:
|
||||
if "qemu" in appliance_config:
|
||||
self._add_qemu_config(new_template, appliance_config["qemu"], appliance_config)
|
||||
@@ -104,17 +115,28 @@ class ApplianceToTemplate:
|
||||
|
||||
def _get_settings(self, appliance_config, settings_name=None):
|
||||
|
||||
# first look for specific settings set if provided
|
||||
default_settings = None
|
||||
# first look for default settings, if any ('default' = true, first set that has it)
|
||||
for settings in appliance_config["settings"]:
|
||||
if settings.get("default", False):
|
||||
default_settings = settings
|
||||
break
|
||||
|
||||
# then look for specific settings set if a name is provided
|
||||
if settings_name:
|
||||
for settings in appliance_config["settings"]:
|
||||
if settings.get("name") == settings_name:
|
||||
if settings.get("inherit_default_properties", True) and \
|
||||
default_settings and default_settings["template_type"] == settings["template_type"]:
|
||||
default_settings["template_properties"].update(settings["template_properties"])
|
||||
return default_settings
|
||||
return settings
|
||||
raise ConfigException("Settings {} cannot be found", settings_name)
|
||||
raise ConfigException("Settings '{}' cannot be found in the appliance file", settings_name)
|
||||
elif default_settings:
|
||||
return default_settings
|
||||
|
||||
# then look for specified default settings ('default' = true)
|
||||
for settings in appliance_config["settings"]:
|
||||
if settings.get("default", False):
|
||||
return settings
|
||||
if not appliance_config.get("settings"):
|
||||
raise ConfigException("No settings found in the appliance file")
|
||||
|
||||
# if no default settings are specified, use the first available settings set
|
||||
return appliance_config["settings"][0]
|
||||
@@ -125,14 +147,16 @@ class ApplianceToTemplate:
|
||||
new_config.update(template_properties)
|
||||
|
||||
# the following properties are not valid for a template
|
||||
new_config.pop("kvm", None)
|
||||
new_config.pop("path", None)
|
||||
new_config.pop("arch", None)
|
||||
new_config.pop("kvm", None) # To check KVM setting against the server capabilities
|
||||
new_config.pop("path", None) # Qemu binary selected in previous step
|
||||
new_config.pop("arch", None) # Used for selecting the Qemu binary
|
||||
|
||||
options = template_properties.get("options", "")
|
||||
if template_properties.get("kvm", "allow") == "disable" and "-machine accel=tcg" not in options:
|
||||
options += " -machine accel=tcg"
|
||||
new_config["options"] = options.strip()
|
||||
options = options.strip()
|
||||
if options:
|
||||
new_config["options"] = options
|
||||
|
||||
for image in appliance_config["images"]:
|
||||
if image.get("path"):
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
"docker_properties": {
|
||||
"type": "object",
|
||||
"title": "Docker template properties",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string",
|
||||
@@ -83,13 +84,13 @@
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"adapters",
|
||||
"image"
|
||||
]
|
||||
},
|
||||
"iou_properties": {
|
||||
"type": "object",
|
||||
"title": "IOU template properties",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string",
|
||||
@@ -131,14 +132,7 @@
|
||||
"type": "string",
|
||||
"title": "Config loaded at startup"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"ethernet_adapters",
|
||||
"serial_adapters",
|
||||
"nvram",
|
||||
"ram",
|
||||
"startup_config"
|
||||
]
|
||||
}
|
||||
},
|
||||
"dynamips_slot": {
|
||||
"enum": [
|
||||
@@ -181,6 +175,7 @@
|
||||
"dynamips_properties": {
|
||||
"type": "object",
|
||||
"title": "Dynamips template properties",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string",
|
||||
@@ -305,9 +300,7 @@
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"platform",
|
||||
"ram",
|
||||
"nvram"
|
||||
"platform"
|
||||
]
|
||||
},
|
||||
"qemu_disk_interfaces": {
|
||||
@@ -325,6 +318,7 @@
|
||||
"qemu_properties": {
|
||||
"type": "object",
|
||||
"title": "Qemu template properties",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string",
|
||||
@@ -566,14 +560,7 @@
|
||||
"null"
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"adapter_type",
|
||||
"adapters",
|
||||
"ram",
|
||||
"platform",
|
||||
"console_type"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"properties": {
|
||||
@@ -686,9 +673,9 @@
|
||||
"type": "boolean",
|
||||
"title": "Whether these are the default settings"
|
||||
},
|
||||
"inherit_default_settings": {
|
||||
"inherit_default_properties": {
|
||||
"type": "boolean",
|
||||
"title": "Whether the default settings should be used",
|
||||
"title": "Whether the default properties should be used",
|
||||
"default": "true"
|
||||
},
|
||||
"template_type": {
|
||||
@@ -905,6 +892,7 @@
|
||||
"registry_version",
|
||||
"status",
|
||||
"maintainer",
|
||||
"maintainer_email"
|
||||
"maintainer_email",
|
||||
"settings"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -172,7 +172,7 @@ def local_server_config():
|
||||
return LocalServerConfig.instance()
|
||||
|
||||
|
||||
@pytest.yield_fixture(autouse=True)
|
||||
@pytest.fixture(autouse=True)
|
||||
def run_around_tests(local_config, main_window):
|
||||
"""
|
||||
This setup a temporay environnement around tests
|
||||
|
||||
50
tests/registry/appliances/arista-veos-v8.gns3a
Normal file
50
tests/registry/appliances/arista-veos-v8.gns3a
Normal file
@@ -0,0 +1,50 @@
|
||||
{
|
||||
"appliance_id": "1c784362-8aaf-4312-b0f5-4b138cf2e25b",
|
||||
"name": "Arista vEOS",
|
||||
"category": "router",
|
||||
"description": "Arista EOS® is the core of Arista cloud networking solutions for next-generation data centers and cloud networks. Cloud architectures built with Arista EOS scale to tens of thousands of compute and storage nodes with management and provisioning capabilities that work at scale. Through its programmability, EOS enables a set of software applications that deliver workflow automation, high availability, unprecedented network visibility and analytics and rapid integration with a wide range of third-party applications for virtualization, management, automation and orchestration services.\n\nArista Extensible Operating System (EOS) is a fully programmable and highly modular, Linux-based network operation system, using familiar industry standard CLI and runs a single binary software image across the Arista switching family. Architected for resiliency and programmability, EOS has a unique multi-process state sharing architecture that separates state information and packet forwarding from protocol processing and application logic.",
|
||||
"vendor_name": "Arista",
|
||||
"vendor_url": "http://www.arista.com/",
|
||||
"documentation_url": "http://www.arista.com/docs/Manuals/ConfigGuide.pdf",
|
||||
"product_name": "Arista vEOS",
|
||||
"product_url": "https://eos.arista.com/",
|
||||
"registry_version": 8,
|
||||
"status": "stable",
|
||||
"maintainer": "GNS3 Team",
|
||||
"maintainer_email": "developers@gns3.net",
|
||||
"settings": [
|
||||
{
|
||||
"template_type": "qemu",
|
||||
"template_properties": {
|
||||
"adapter_type": "e1000",
|
||||
"adapters": 8,
|
||||
"ram": 2048,
|
||||
"platform": "x86_64",
|
||||
"console_type": "telnet"
|
||||
}
|
||||
}
|
||||
],
|
||||
"images": [
|
||||
{
|
||||
"filename": "Aboot-veos-serial-2.1.0.iso",
|
||||
"version": "2.1.0",
|
||||
"md5sum": "2687534f2ff11b998dec0511066457c0",
|
||||
"download_url": "https://www.arista.com/en/support/software-download"
|
||||
},
|
||||
{
|
||||
"filename": "vEOS-lab-4.13.8M.vmdk",
|
||||
"version": "4.13.8M",
|
||||
"md5sum": "a47145b9e6e7a24171c0850f8755535e",
|
||||
"download_url": "https://www.arista.com/en/support/software-download"
|
||||
}
|
||||
],
|
||||
"versions": [
|
||||
{
|
||||
"name": "4.13.8M",
|
||||
"images": {
|
||||
"hda_disk_image": "Aboot-veos-serial-2.1.0.iso",
|
||||
"hdb_disk_image": "vEOS-lab-4.13.8M.vmdk"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
{
|
||||
"appliance_id": "1c784362-8aaf-4312-b0f5-4b138cf2e25b",
|
||||
"name": "Arista vEOS",
|
||||
"category": "router",
|
||||
"description": "Arista EOS® is the core of Arista cloud networking solutions for next-generation data centers and cloud networks. Cloud architectures built with Arista EOS scale to tens of thousands of compute and storage nodes with management and provisioning capabilities that work at scale. Through its programmability, EOS enables a set of software applications that deliver workflow automation, high availability, unprecedented network visibility and analytics and rapid integration with a wide range of third-party applications for virtualization, management, automation and orchestration services.\n\nArista Extensible Operating System (EOS) is a fully programmable and highly modular, Linux-based network operation system, using familiar industry standard CLI and runs a single binary software image across the Arista switching family. Architected for resiliency and programmability, EOS has a unique multi-process state sharing architecture that separates state information and packet forwarding from protocol processing and application logic.",
|
||||
@@ -11,7 +12,6 @@
|
||||
"status": "stable",
|
||||
"maintainer": "GNS3 Team",
|
||||
"maintainer_email": "developers@gns3.net",
|
||||
|
||||
"qemu": {
|
||||
"adapter_type": "e1000",
|
||||
"adapters": 8,
|
||||
@@ -19,7 +19,6 @@
|
||||
"arch": "x86_64",
|
||||
"console_type": "telnet"
|
||||
},
|
||||
|
||||
"images": [
|
||||
{
|
||||
"filename": "Aboot-veos-serial-2.1.0.iso",
|
||||
@@ -34,7 +33,6 @@
|
||||
"download_url": "https://www.arista.com/en/support/software-download"
|
||||
}
|
||||
],
|
||||
|
||||
"versions": [
|
||||
{
|
||||
"name": "4.13.8M",
|
||||
|
||||
@@ -11,7 +11,6 @@
|
||||
"status": "stable",
|
||||
"maintainer": "GNS3 Team",
|
||||
"maintainer_email": "developers@gns3.net",
|
||||
|
||||
"qemu": {
|
||||
"adapter_type": "e1000",
|
||||
"adapters": 1,
|
||||
@@ -19,7 +18,6 @@
|
||||
"arch": "i386",
|
||||
"console_type": "telnet"
|
||||
},
|
||||
|
||||
"images": [
|
||||
{
|
||||
"filename": "linux-microcore-3.4.1.img",
|
||||
@@ -30,7 +28,6 @@
|
||||
"direct_download_url": "http://downloads.sourceforge.net/project/gns-3/Qemu%20Appliances/linux-microcore-3.4.1.img"
|
||||
}
|
||||
],
|
||||
|
||||
"versions": [
|
||||
{
|
||||
"name": "3.4.1",
|
||||
|
||||
51
tests/registry/appliances/cisco-3745-v8.gns3a
Normal file
51
tests/registry/appliances/cisco-3745-v8.gns3a
Normal file
@@ -0,0 +1,51 @@
|
||||
{
|
||||
"appliance_id": "96dac9ff-581c-4262-a9f0-5c68890d049e",
|
||||
"category": "router",
|
||||
"status": "experimental",
|
||||
"maintainer": "GNS3 Team",
|
||||
"name": "Cisco 3745",
|
||||
"vendor_name": "Cisco",
|
||||
"product_name": "3745",
|
||||
"vendor_url": "http://www.cisco.com",
|
||||
"description": "Cisco 3745 Multiservice Access Router",
|
||||
"registry_version": 8,
|
||||
"maintainer_email": "developers@gns3.net",
|
||||
"documentation_url": "http://www.cisco.com/c/en/us/support/routers/3745-multiservice-access-router/model.html",
|
||||
"settings": [
|
||||
{
|
||||
"template_type": "dynamips",
|
||||
"template_properties": {
|
||||
"chassis": "",
|
||||
"platform": "c3745",
|
||||
"ram": 256,
|
||||
"nvram": 256,
|
||||
"startup_config": "ios_base_startup-config.txt",
|
||||
"slot0": "GT96100-FE",
|
||||
"slot1": "NM-1FE-TX",
|
||||
"slot2": "NM-4T",
|
||||
"slot3": "",
|
||||
"slot4": "",
|
||||
"wic0": "WIC-1T",
|
||||
"wic1": "WIC-1T",
|
||||
"wic2": "WIC-1T",
|
||||
"idlepc": "0x60aa1da0"
|
||||
}
|
||||
}
|
||||
],
|
||||
"versions": [
|
||||
{
|
||||
"name": "124-25d",
|
||||
"images": {
|
||||
"image": "c3745-adventerprisek9-mz.124-25d.image"
|
||||
}
|
||||
}
|
||||
],
|
||||
"images": [
|
||||
{
|
||||
"filesize": 82053028,
|
||||
"md5sum": "ddbaf74274822b50fa9670e10c75b08f",
|
||||
"version": "124-25d",
|
||||
"filename": "c3745-adventerprisek9-mz.124-25d.image"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
{
|
||||
"appliance_id": "96dac9ff-581c-4262-a9f0-5c68890d049e",
|
||||
"category": "router",
|
||||
"status": "experimental",
|
||||
"maintainer": "GNS3 Team",
|
||||
@@ -10,7 +11,6 @@
|
||||
"registry_version": 2,
|
||||
"maintainer_email": "developers@gns3.net",
|
||||
"documentation_url": "http://www.cisco.com/c/en/us/support/routers/3745-multiservice-access-router/model.html",
|
||||
|
||||
"dynamips": {
|
||||
"chassis": "",
|
||||
"platform": "c3745",
|
||||
@@ -26,7 +26,6 @@
|
||||
"wic1": "WIC-1T",
|
||||
"wic2": "WIC-1T"
|
||||
},
|
||||
|
||||
"versions": [
|
||||
{
|
||||
"images": {
|
||||
|
||||
41
tests/registry/appliances/cisco-iou-l3-v8.gns3a
Normal file
41
tests/registry/appliances/cisco-iou-l3-v8.gns3a
Normal file
@@ -0,0 +1,41 @@
|
||||
{
|
||||
"appliance_id": "a8f5935d-7229-4b32-8a01-24ef41758f2f",
|
||||
"category": "router",
|
||||
"status": "experimental",
|
||||
"maintainer": "GNS3 Team",
|
||||
"name": "Cisco IOU L3",
|
||||
"vendor_name": "Cisco",
|
||||
"product_name": "Cisco IOU L3",
|
||||
"vendor_url": "http://www.cisco.com",
|
||||
"description": "Cisco IOS on UNIX Layer 3 image.",
|
||||
"registry_version": 8,
|
||||
"maintainer_email": "developers@gns3.net",
|
||||
"settings": [
|
||||
{
|
||||
"template_type": "iou",
|
||||
"template_properties": {
|
||||
"ethernet_adapters": 2,
|
||||
"serial_adapters": 2,
|
||||
"nvram": 128,
|
||||
"ram": 256,
|
||||
"startup_config": "iou_l3_base_startup-config.txt"
|
||||
}
|
||||
}
|
||||
],
|
||||
"versions": [
|
||||
{
|
||||
"images": {
|
||||
"image": "i86bi-linux-l3-adventerprisek9-15.4.1T.bin"
|
||||
},
|
||||
"name": "15.4.1T"
|
||||
}
|
||||
],
|
||||
"images": [
|
||||
{
|
||||
"filesize": 152677848,
|
||||
"md5sum": "5d41402abc4b2a76b9719d911017c592",
|
||||
"version": "15.4.1T",
|
||||
"filename": "i86bi-linux-l3-adventerprisek9-15.4.1T.bin"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
{
|
||||
"appliance_id": "a8f5935d-7229-4b32-8a01-24ef41758f2f",
|
||||
"category": "router",
|
||||
"status": "experimental",
|
||||
"maintainer": "GNS3 Team",
|
||||
@@ -9,7 +10,6 @@
|
||||
"description": "Cisco IOS on UNIX Layer 3 image.",
|
||||
"registry_version": 2,
|
||||
"maintainer_email": "developers@gns3.net",
|
||||
|
||||
"iou": {
|
||||
"ethernet_adapters": 2,
|
||||
"serial_adapters": 2,
|
||||
@@ -17,7 +17,6 @@
|
||||
"ram": 256,
|
||||
"startup_config": "iou_l3_base_startup-config.txt"
|
||||
},
|
||||
|
||||
"versions": [
|
||||
{
|
||||
"images": {
|
||||
|
||||
115
tests/registry/appliances/empty-vm-v8.gns3a
Normal file
115
tests/registry/appliances/empty-vm-v8.gns3a
Normal file
@@ -0,0 +1,115 @@
|
||||
{
|
||||
"appliance_id": "1cfdf900-7c30-4cb7-8f03-3f61d2581633",
|
||||
"name": "Empty VM",
|
||||
"category": "guest",
|
||||
"description": "A empty VM with empty hard disks 8G, 30G, 100G & 200G.",
|
||||
"vendor_name": "GNS3",
|
||||
"vendor_url": "https://gns3.com",
|
||||
"documentation_url": "",
|
||||
"product_name": "QEMU",
|
||||
"product_url": "https://sourceforge.net/projects/gns-3/files/Empty%20Qemu%20disk/",
|
||||
"registry_version": 8,
|
||||
"status": "experimental",
|
||||
"maintainer": "GNS3 Team",
|
||||
"maintainer_email": "developers@gns3.net",
|
||||
"usage": "Default at first boot the VM will start from the cdrom.",
|
||||
"settings": [
|
||||
{
|
||||
"default": true,
|
||||
"template_type": "qemu",
|
||||
"template_properties": {
|
||||
"adapter_type": "e1000",
|
||||
"adapters": 1,
|
||||
"ram": 1024,
|
||||
"hda_disk_interface": "sata",
|
||||
"platform": "x86_64",
|
||||
"console_type": "vnc",
|
||||
"boot_priority": "d"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "i386 settings",
|
||||
"template_type": "qemu",
|
||||
"template_properties": {
|
||||
"platform": "i386",
|
||||
"adapters": 8
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "ARM settings",
|
||||
"inherit_default_properties": false,
|
||||
"template_type": "qemu",
|
||||
"template_properties": {
|
||||
"platform": "arm",
|
||||
"ram": 512
|
||||
}
|
||||
}
|
||||
],
|
||||
"images": [
|
||||
{
|
||||
"filename": "empty8G.qcow2",
|
||||
"version": "8G",
|
||||
"md5sum": "f1d2c25b6990f99bd05b433ab603bdb4",
|
||||
"filesize": 197120,
|
||||
"download_url": "https://sourceforge.net/projects/gns-3/files/Empty%20Qemu%20disk/",
|
||||
"direct_download_url": "https://sourceforge.net/projects/gns-3/files/Empty%20Qemu%20disk/empty8G.qcow2/download"
|
||||
},
|
||||
{
|
||||
"filename": "empty30G.qcow2",
|
||||
"version": "30G",
|
||||
"checksum": "3411a599e822f2ac6be560a26405821a",
|
||||
"filesize": 197120,
|
||||
"download_url": "https://sourceforge.net/projects/gns-3/files/Empty%20Qemu%20disk/",
|
||||
"direct_download_url": "https://sourceforge.net/projects/gns-3/files/Empty%20Qemu%20disk/empty30G.qcow2/download"
|
||||
},
|
||||
{
|
||||
"filename": "empty100G.qcow2",
|
||||
"version": "100G",
|
||||
"checksum": "d08fdec95fffbda3f04e9a00db49295df73ae4a507396e442ba9e4ad5c14ce5a",
|
||||
"checksum_type": "sha256",
|
||||
"filesize": 198656,
|
||||
"download_url": "https://sourceforge.net/projects/gns-3/files/Empty%20Qemu%20disk/",
|
||||
"direct_download_url": "https://sourceforge.net/projects/gns-3/files/Empty%20Qemu%20disk/empty100G.qcow2/download"
|
||||
},
|
||||
{
|
||||
"filename": "empty200G.qcow2",
|
||||
"version": "200G",
|
||||
"md5sum": "d1686d2f25695dee32eab9a6f4652c7c",
|
||||
"filesize": 200192,
|
||||
"download_url": "https://sourceforge.net/projects/gns-3/files/Empty%20Qemu%20disk/",
|
||||
"direct_download_url": "https://sourceforge.net/projects/gns-3/files/Empty%20Qemu%20disk/empty200G.qcow2/download"
|
||||
}
|
||||
],
|
||||
"versions": [
|
||||
{
|
||||
"name": "8G",
|
||||
"images": {
|
||||
"hda_disk_image": "empty8G.qcow2"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "30G",
|
||||
"settings": "i386 settings",
|
||||
"images": {
|
||||
"hda_disk_image": "empty30G.qcow2"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "100G",
|
||||
"settings": "ARM settings",
|
||||
"images": {
|
||||
"hda_disk_image": "empty100G.qcow2"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "200G",
|
||||
"settings": "ARM settings",
|
||||
"usage": "This is how to use this version",
|
||||
"symbol": "ethernet_switch",
|
||||
"category": "switch",
|
||||
"images": {
|
||||
"hda_disk_image": "empty200G.qcow2"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -3,8 +3,6 @@
|
||||
"vendor_name": "Juniper",
|
||||
"product_name": "vSRX",
|
||||
"name": "vSRX",
|
||||
|
||||
|
||||
"description": "The vSRX delivers core firewall, networking, advanced security, and automated lifecycle management capabilities for enterprises and service providers. The industry\u2019s fastest virtual security platform, the vSRX offers firewall speeds up to 17 Gbps using only two virtual CPUs, providing scalable, secure protection across private, public, and hybrid clouds.",
|
||||
"maintainer_email": "developers@gns3.net",
|
||||
"documentation_url": "http://www.juniper.net/techpubs/",
|
||||
@@ -13,7 +11,6 @@
|
||||
"status": "experimental",
|
||||
"vendor_url": "https://www.juniper.net",
|
||||
"registry_version": 1,
|
||||
|
||||
"qemu": {
|
||||
"console_type": "telnet",
|
||||
"ram": 2000,
|
||||
@@ -23,8 +20,6 @@
|
||||
"options": "-smp 2",
|
||||
"kvm": "require"
|
||||
},
|
||||
|
||||
|
||||
"images": [
|
||||
{
|
||||
"version": "12.1X47.4-domestic",
|
||||
@@ -34,7 +29,6 @@
|
||||
"download_url": "https://www.juniper.net/us/en/dm/free-vsrx-trial/"
|
||||
}
|
||||
],
|
||||
|
||||
"versions": [
|
||||
{
|
||||
"name": "12.1X47.4-domestic",
|
||||
@@ -43,4 +37,4 @@
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,6 @@
|
||||
"maintainer": "GNS3 Team",
|
||||
"maintainer_email": "developers@gns3.net",
|
||||
"usage": "Just start the appliance",
|
||||
|
||||
"qemu": {
|
||||
"adapter_type": "e1000",
|
||||
"adapters": 1,
|
||||
@@ -21,7 +20,6 @@
|
||||
"console_type": "telnet",
|
||||
"kvm": "allow"
|
||||
},
|
||||
|
||||
"images": [
|
||||
{
|
||||
"filename": "linux-microcore-3.4.1.img",
|
||||
@@ -40,7 +38,6 @@
|
||||
"direct_download_url": "http://downloads.sourceforge.net/project/gns-3/Qemu%20Appliances/linux-microcore-4.0.2-clean.img"
|
||||
}
|
||||
],
|
||||
|
||||
"versions": [
|
||||
{
|
||||
"name": "3.4.1",
|
||||
|
||||
24
tests/registry/appliances/openvswitch-v8.gns3a
Normal file
24
tests/registry/appliances/openvswitch-v8.gns3a
Normal file
@@ -0,0 +1,24 @@
|
||||
{
|
||||
"appliance_id": "40c84186-752f-4a71-b6fb-961ba36e8cf7",
|
||||
"name": "Open vSwitch",
|
||||
"category": "multilayer_switch",
|
||||
"description": "Open vSwitch is a production quality, multilayer virtual switch licensed under the open source Apache 2.0 license. It is designed to enable massive network automation through programmatic extension, while still supporting standard management interfaces and protocols (e.g. NetFlow, sFlow, IPFIX, RSPAN, CLI, LACP, 802.1ag). In addition, it is designed to support distribution across multiple physical servers similar to VMware's vNetwork distributed vswitch or Cisco's Nexus 1000V.",
|
||||
"vendor_name": "Open vSwitch",
|
||||
"vendor_url": "http://openvswitch.org/",
|
||||
"documentation_url": "http://openvswitch.org/support/",
|
||||
"product_name": "Open vSwitch",
|
||||
"registry_version": 8,
|
||||
"status": "stable",
|
||||
"maintainer": "GNS3 Team",
|
||||
"maintainer_email": "developers@gns3.net",
|
||||
"usage": "By default all interfaces are connected to the br0",
|
||||
"settings": [
|
||||
{
|
||||
"template_type": "docker",
|
||||
"template_properties": {
|
||||
"adapters": 16,
|
||||
"image": "gns3/openvswitch:latest"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
{
|
||||
"appliance_id": "40c84186-752f-4a71-b6fb-961ba36e8cf7",
|
||||
"name": "Open vSwitch",
|
||||
"category": "multilayer_switch",
|
||||
"description": "Open vSwitch is a production quality, multilayer virtual switch licensed under the open source Apache 2.0 license. It is designed to enable massive network automation through programmatic extension, while still supporting standard management interfaces and protocols (e.g. NetFlow, sFlow, IPFIX, RSPAN, CLI, LACP, 802.1ag). In addition, it is designed to support distribution across multiple physical servers similar to VMware's vNetwork distributed vswitch or Cisco's Nexus 1000V.",
|
||||
|
||||
@@ -202,6 +202,62 @@ def test_create_new_version():
|
||||
os.remove(wrong_appliance_file)
|
||||
|
||||
|
||||
def test_emulator():
|
||||
assert Appliance(registry, os.path.abspath("tests/registry/appliances/microcore-linux.gns3a")).emulator() == "qemu"
|
||||
assert Appliance(registry, os.path.abspath("tests/registry/appliances/cisco-iou-l3.gns3a")).emulator() == "iou"
|
||||
def test_template_type():
|
||||
assert Appliance(registry, os.path.abspath("tests/registry/appliances/microcore-linux.gns3a")).template_type() == "qemu"
|
||||
assert Appliance(registry, os.path.abspath("tests/registry/appliances/cisco-iou-l3.gns3a")).template_type() == "iou"
|
||||
|
||||
|
||||
def test_checksum_in_appliance_format_v8(registry, images_dir):
|
||||
|
||||
path_empty_8g = os.path.join(images_dir, "QEMU", "empty8G.qcow2")
|
||||
with open(path_empty_8g, 'w+') as f:
|
||||
f.write("hello")
|
||||
|
||||
appliance = Appliance(registry, os.path.abspath("tests/registry/appliances/empty-vm-v8.gns3a"))
|
||||
appliance._appliance['versions'][0]['images']['hda_disk_image']['filesize'] = 5
|
||||
appliance._appliance['versions'][0]['images']['hda_disk_image']['md5sum'] = "5d41402abc4b2a76b9719d911017c592"
|
||||
|
||||
detected = appliance.search_images_for_version("8G")
|
||||
assert detected["images"][0]["md5sum"] == "5d41402abc4b2a76b9719d911017c592"
|
||||
assert detected["images"][0]["filesize"] == 5
|
||||
|
||||
path_empty_30g = os.path.join(images_dir, "QEMU", "empty30G.qcow2")
|
||||
os.rename(path_empty_8g, path_empty_30g)
|
||||
appliance._appliance['versions'][1]['images']['hda_disk_image']['filesize'] = 5
|
||||
appliance._appliance['versions'][1]['images']['hda_disk_image']['checksum'] = "5d41402abc4b2a76b9719d911017c592"
|
||||
detected = appliance.search_images_for_version("30G")
|
||||
assert detected["images"][0]["md5sum"] == "5d41402abc4b2a76b9719d911017c592"
|
||||
assert detected["images"][0]["filesize"] == 5
|
||||
|
||||
with pytest.raises(ApplianceError):
|
||||
appliance.search_images_for_version("100G")
|
||||
|
||||
|
||||
def test_multiple_different_template_types_found():
|
||||
|
||||
appliance_path = "tests/registry/appliances/empty-vm-v8.gns3a"
|
||||
wrong_appliance_fp, wrong_appliance_file = tempfile.mkstemp()
|
||||
|
||||
with open(appliance_path, encoding='utf-8') as f:
|
||||
appliance = json.loads(f.read())
|
||||
appliance["settings"][0]["template_type"] = "dynamips"
|
||||
os.write(wrong_appliance_fp, json.dumps(appliance).encode())
|
||||
os.close(wrong_appliance_fp)
|
||||
|
||||
with pytest.raises(ApplianceError):
|
||||
Appliance(registry, wrong_appliance_file).template_type()
|
||||
|
||||
|
||||
def test_appliance_without_settings():
|
||||
|
||||
appliance_path = "tests/registry/appliances/empty-vm-v8.gns3a"
|
||||
wrong_appliance_fp, wrong_appliance_file = tempfile.mkstemp()
|
||||
|
||||
with open(appliance_path, encoding='utf-8') as f:
|
||||
appliance = json.loads(f.read())
|
||||
del appliance["settings"]
|
||||
os.write(wrong_appliance_fp, json.dumps(appliance).encode())
|
||||
os.close(wrong_appliance_fp)
|
||||
|
||||
with pytest.raises(ApplianceError):
|
||||
Appliance(registry, wrong_appliance_file).template_type()
|
||||
|
||||
@@ -64,8 +64,15 @@ def empty_config(tmpdir, images_dir, symbols_dir, local_server_config):
|
||||
return Config(path)
|
||||
|
||||
|
||||
def test_add_appliance_iou(iou_l3):
|
||||
with open("tests/registry/appliances/cisco-iou-l3.gns3a", encoding="utf-8") as f:
|
||||
@pytest.mark.parametrize(
|
||||
"appliance_file",
|
||||
[
|
||||
"cisco-iou-l3.gns3a",
|
||||
"cisco-iou-l3-v8.gns3a"
|
||||
]
|
||||
)
|
||||
def test_add_appliance_iou(iou_l3, appliance_file):
|
||||
with open("tests/registry/appliances/{}".format(appliance_file), encoding="utf-8") as f:
|
||||
config = json.load(f)
|
||||
config["images"] = [
|
||||
{
|
||||
@@ -74,7 +81,7 @@ def test_add_appliance_iou(iou_l3):
|
||||
"path": iou_l3
|
||||
}
|
||||
]
|
||||
new_template = ApplianceToTemplate().new_template(config, "local")
|
||||
new_template = ApplianceToTemplate().new_template(config, "local", "15.4.1T")
|
||||
assert new_template == {
|
||||
"category": "router",
|
||||
"template_type": "iou",
|
||||
@@ -91,8 +98,15 @@ def test_add_appliance_iou(iou_l3):
|
||||
}
|
||||
|
||||
|
||||
def test_add_appliance_docker():
|
||||
with open("tests/registry/appliances/openvswitch.gns3a", encoding="utf-8") as f:
|
||||
@pytest.mark.parametrize(
|
||||
"appliance_file",
|
||||
[
|
||||
"openvswitch.gns3a",
|
||||
"openvswitch-v8.gns3a"
|
||||
]
|
||||
)
|
||||
def test_add_appliance_docker(appliance_file):
|
||||
with open("tests/registry/appliances/{}".format(appliance_file), encoding="utf-8") as f:
|
||||
config = json.load(f)
|
||||
|
||||
new_template = ApplianceToTemplate().new_template(config, "local")
|
||||
@@ -108,8 +122,15 @@ def test_add_appliance_docker():
|
||||
}
|
||||
|
||||
|
||||
def test_add_appliance_dynamips(cisco_3745):
|
||||
with open("tests/registry/appliances/cisco-3745.gns3a", encoding="utf-8") as f:
|
||||
@pytest.mark.parametrize(
|
||||
"appliance_file",
|
||||
[
|
||||
"cisco-3745.gns3a",
|
||||
"cisco-3745-v8.gns3a"
|
||||
]
|
||||
)
|
||||
def test_add_appliance_dynamips(cisco_3745, appliance_file):
|
||||
with open("tests/registry/appliances/{}".format(appliance_file), encoding="utf-8") as f:
|
||||
config = json.load(f)
|
||||
config["images"] = [
|
||||
{
|
||||
@@ -120,7 +141,7 @@ def test_add_appliance_dynamips(cisco_3745):
|
||||
}
|
||||
]
|
||||
|
||||
new_template = ApplianceToTemplate().new_template(config, "local")
|
||||
new_template = ApplianceToTemplate().new_template(config, "local", "124-25d")
|
||||
assert new_template == {
|
||||
"template_type": "dynamips",
|
||||
"category": "router",
|
||||
@@ -166,7 +187,6 @@ def test_add_appliance_guest(linux_microcore_img):
|
||||
"symbol": ":/symbols/qemu_guest.svg",
|
||||
"hda_disk_image": "linux-microcore-3.4.1.img",
|
||||
"name": "Micro Core Linux",
|
||||
"options": "",
|
||||
"qemu_path": "qemu-system-i386",
|
||||
"usage": "Just start the appliance",
|
||||
"ram": 32,
|
||||
@@ -238,8 +258,15 @@ def test_add_appliance_with_boot_priority(linux_microcore_img):
|
||||
assert new_template["boot_priority"] == "dc"
|
||||
|
||||
|
||||
def test_add_appliance_router_two_disk(images_dir):
|
||||
with open("tests/registry/appliances/arista-veos.gns3a", encoding="utf-8") as f:
|
||||
@pytest.mark.parametrize(
|
||||
"appliance_file",
|
||||
[
|
||||
"arista-veos.gns3a",
|
||||
"arista-veos-v8.gns3a"
|
||||
]
|
||||
)
|
||||
def test_add_appliance_router_two_disk(images_dir, appliance_file):
|
||||
with open("tests/registry/appliances/{}".format(appliance_file), encoding="utf-8") as f:
|
||||
config = json.load(f)
|
||||
|
||||
config["images"] = [
|
||||
@@ -255,8 +282,8 @@ def test_add_appliance_router_two_disk(images_dir):
|
||||
}
|
||||
]
|
||||
|
||||
new_template = ApplianceToTemplate().new_template(config, "local")
|
||||
assert new_template == {
|
||||
new_template = ApplianceToTemplate().new_template(config, "local", "4.13.8M")
|
||||
expected_result = {
|
||||
"template_type": "qemu",
|
||||
"adapter_type": "e1000",
|
||||
"adapters": 8,
|
||||
@@ -265,12 +292,76 @@ def test_add_appliance_router_two_disk(images_dir):
|
||||
"hda_disk_image": "a",
|
||||
"hdb_disk_image": "b",
|
||||
"name": "Arista vEOS",
|
||||
"options": "",
|
||||
"qemu_path": "qemu-system-x86_64",
|
||||
"ram": 2048,
|
||||
"console_type": "telnet",
|
||||
"compute_id": "local"
|
||||
}
|
||||
if "v8" in appliance_file:
|
||||
expected_result["platform"] = "x86_64" # platform was added in v8
|
||||
assert new_template == expected_result
|
||||
|
||||
|
||||
def test_add_appliance_v8_default_properties_inheritance(images_dir):
|
||||
with open("tests/registry/appliances/empty-vm-v8.gns3a", encoding="utf-8") as f:
|
||||
config = json.load(f)
|
||||
|
||||
# check that default properties are used
|
||||
new_template = ApplianceToTemplate().new_template(config, "local", "8G")
|
||||
expected_result = {
|
||||
"name": "Empty VM",
|
||||
"template_type": "qemu",
|
||||
"symbol": ":/symbols/qemu_guest.svg",
|
||||
"category": "guest",
|
||||
"adapter_type": "e1000",
|
||||
"adapters": 1,
|
||||
"ram": 1024,
|
||||
"qemu_path": "qemu-system-x86_64",
|
||||
"hda_disk_interface": "sata",
|
||||
"platform": "x86_64",
|
||||
"console_type": "vnc",
|
||||
"boot_priority": "d",
|
||||
"compute_id": "local",
|
||||
"usage": "Default at first boot the VM will start from the cdrom."
|
||||
}
|
||||
assert new_template == expected_result
|
||||
|
||||
# check that specific properties are used along with default properties
|
||||
new_template = ApplianceToTemplate().new_template(config, "local", "30G")
|
||||
expected_result.update(
|
||||
{
|
||||
"adapters": 8,
|
||||
"qemu_path": "qemu-system-i386",
|
||||
"platform": "i386",
|
||||
}
|
||||
)
|
||||
assert new_template == expected_result
|
||||
|
||||
# check that specific properties are used along without default properties
|
||||
new_template = ApplianceToTemplate().new_template(config, "local", "100G")
|
||||
expected_result = {
|
||||
"name": "Empty VM",
|
||||
"template_type": "qemu",
|
||||
"symbol": ":/symbols/qemu_guest.svg",
|
||||
"category": "guest",
|
||||
"ram": 512,
|
||||
"qemu_path": "qemu-system-arm",
|
||||
"platform": "arm",
|
||||
"compute_id": "local",
|
||||
"usage": "Default at first boot the VM will start from the cdrom."
|
||||
}
|
||||
assert new_template == expected_result
|
||||
|
||||
# check that specific properties are used with "usage", "symbol" and "category" defined at the version level
|
||||
new_template = ApplianceToTemplate().new_template(config, "local", "200G")
|
||||
expected_result.update(
|
||||
{
|
||||
"usage": "This is how to use this version",
|
||||
"symbol": "ethernet_switch",
|
||||
"category": "switch"
|
||||
}
|
||||
)
|
||||
assert new_template == expected_result
|
||||
|
||||
|
||||
def test_add_appliance_path_relative_to_images_dir(tmpdir, linux_microcore_img):
|
||||
|
||||
@@ -47,7 +47,7 @@ def http_client(http_request, network_manager):
|
||||
return HTTPClient({"protocol": "http", "host": "127.0.0.1", "port": "3080"}, network_manager=network_manager)
|
||||
|
||||
|
||||
@pytest.yield_fixture(autouse=True)
|
||||
@pytest.fixture(autouse=True)
|
||||
def http_request():
|
||||
|
||||
mock = unittest.mock.Mock()
|
||||
|
||||
@@ -34,7 +34,7 @@ def images_dir(tmpdir):
|
||||
return path
|
||||
|
||||
|
||||
@pytest.yield_fixture
|
||||
@pytest.fixture
|
||||
def image_manager(tmpdir, images_dir):
|
||||
ImageManager._instance = None
|
||||
settings = LOCAL_SERVER_SETTINGS
|
||||
|
||||
@@ -32,7 +32,7 @@ def local_server_path(tmpdir):
|
||||
return str(tmpdir / "gns3server")
|
||||
|
||||
|
||||
@pytest.yield_fixture
|
||||
@pytest.fixture
|
||||
def local_server(local_server_path, tmpdir):
|
||||
with open(str(tmpdir / "test.cfg"), "w+") as f:
|
||||
f.write("""
|
||||
|
||||
@@ -26,14 +26,14 @@ from gns3.update_manager import UpdateManager
|
||||
from gns3 import version
|
||||
|
||||
|
||||
@pytest.yield_fixture
|
||||
@pytest.fixture
|
||||
def frozen():
|
||||
sys.frozen = True
|
||||
yield
|
||||
delattr(sys, 'frozen')
|
||||
|
||||
|
||||
@pytest.yield_fixture
|
||||
@pytest.fixture
|
||||
def devVersion():
|
||||
old_version_info = version.__version_info__
|
||||
old_version = version.__version__
|
||||
@@ -44,7 +44,7 @@ def devVersion():
|
||||
version.__version__ = old_version
|
||||
|
||||
|
||||
@pytest.yield_fixture
|
||||
@pytest.fixture
|
||||
def stableVersion():
|
||||
old_version_info = version.__version_info__
|
||||
old_version = version.__version__
|
||||
|
||||
Reference in New Issue
Block a user