diff --git a/CHANGELOG b/CHANGELOG
index 56efdc1f..8ff28a7f 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,5 +1,16 @@
# Change Log
+## 2.2.40 06/06/2023
+
+* qemu : with network adapter_type equal to "virtio-net-pci", fix the speed to 10000 and duplex to full. The values are actually fake. (https://github.com/GNS3/gns3-gui/issues/3476)
+* Parse name for request to node creation from template
+* Remove Xvfb + x11vnc support
+* Require a Host-Only Network to start the VirtualBox GNS3 VM on macOS with VirtualBox 7
+* Properly catch aiohttp client exception. Ref #2228
+* Catch ConnectionResetError when waiting for the wrap console
+* Fix open IPv6 address for HTTP consoles on controller. Fixes https://github.com/GNS3/gns3-gui/issues/3448
+* Use proc.communicate() when checking for subprocess output As recommended in https://docs.python.org/3/library/asyncio-subprocess.html#asyncio.subprocess.Process.stderr
+
## 2.2.39 08/05/2023
* Install web-ui v2.2.39
diff --git a/gns3server/appliances/almalinux.gns3a b/gns3server/appliances/almalinux.gns3a
index 78c7cf43..0f60291b 100644
--- a/gns3server/appliances/almalinux.gns3a
+++ b/gns3server/appliances/almalinux.gns3a
@@ -37,7 +37,8 @@
"version": "1.0",
"md5sum": "72fb52af76e9561d125dd99224e2c1d1",
"filesize": 374784,
- "download_url": "https://github.com/GNS3/gns3-registry/raw/master/cloud-init/AlmaLinux/almalinux-cloud-init-data.iso"
+ "download_url": "https://github.com/GNS3/gns3-registry/tree/master/cloud-init/AlmaLinux",
+ "direct_download_url": "https://github.com/GNS3/gns3-registry/raw/master/cloud-init/AlmaLinux/almalinux-cloud-init-data.iso"
}
],
"versions": [
diff --git a/gns3server/appliances/aruba-arubaoscx.gns3a b/gns3server/appliances/aruba-arubaoscx.gns3a
index a0a08345..1fecc275 100644
--- a/gns3server/appliances/aruba-arubaoscx.gns3a
+++ b/gns3server/appliances/aruba-arubaoscx.gns3a
@@ -32,6 +32,13 @@
"process_priority": "normal"
},
"images": [
+ {
+ "filename": "arubaoscx-disk-image-genericx86-p4-20230531220439.vmdk",
+ "version": "10.12.0006",
+ "md5sum": "c4f80fecd02ef93b431b75dd610e0063",
+ "filesize": 384638464,
+ "download_url": "https://asp.arubanetworks.com/"
+ },
{
"filename": "arubaoscx-disk-image-genericx86-p4-20221130174651.vmdk",
"version": "10.11.0001",
@@ -111,6 +118,12 @@
}
],
"versions": [
+ {
+ "name": "10.12.0006",
+ "images": {
+ "hda_disk_image": "arubaoscx-disk-image-genericx86-p4-20230531220439.vmdk"
+ }
+ },
{
"name": "10.11.0001",
"images": {
diff --git a/gns3server/appliances/centos-cloud.gns3a b/gns3server/appliances/centos-cloud.gns3a
index 52bfd90f..4a41ff7d 100644
--- a/gns3server/appliances/centos-cloud.gns3a
+++ b/gns3server/appliances/centos-cloud.gns3a
@@ -26,33 +26,37 @@
"options": "-nographic"
},
"images": [
+ {
+ "filename": "CentOS-8-GenericCloud-8.4.2105-20210603.0.x86_64.qcow2",
+ "version": "8.4 (2105)",
+ "md5sum": "032eed270415526546eac07628905a62",
+ "filesize": 1309652992,
+ "download_url": "https://cloud.centos.org/centos/8/x86_64/images",
+ "direct_download_url": "https://cloud.centos.org/centos/8/x86_64/images/CentOS-8-GenericCloud-8.4.2105-20210603.0.x86_64.qcow2"
+ },
{
"filename": "CentOS-7-x86_64-GenericCloud-2111.qcow2",
"version": "7 (2111)",
"md5sum": "730b8662695831670721c8245be61dac",
"filesize": 897384448,
- "download_url": "https://cloud.centos.org/centos/7/images/CentOS-7-x86_64-GenericCloud-2111.qcow2"
+ "download_url": "https://cloud.centos.org/centos/7/images",
+ "direct_download_url": "https://cloud.centos.org/centos/7/images/CentOS-7-x86_64-GenericCloud-2111.qcow2"
},
{
"filename": "CentOS-7-x86_64-GenericCloud-1809.qcow2",
"version": "7 (1809)",
"md5sum": "da79108d1324b27bd1759362b82fbe40",
"filesize": 914948096,
- "download_url": "https://cloud.centos.org/centos/7/images/CentOS-7-x86_64-GenericCloud-1809.qcow2"
- },
- {
- "filename": "CentOS-8-GenericCloud-8.4.2105-20210603.0.x86_64.qcow2",
- "version": "8.4 (2105)",
- "md5sum": "032eed270415526546eac07628905a62",
- "filesize": 1309652992,
- "download_url": "https://cloud.centos.org/centos/8/x86_64/images/CentOS-8-GenericCloud-8.4.2105-20210603.0.x86_64.qcow2"
+ "download_url": "https://cloud.centos.org/centos/7/images",
+ "direct_download_url": "https://cloud.centos.org/centos/7/images/CentOS-7-x86_64-GenericCloud-1809.qcow2"
},
{
"filename": "centos-cloud-init-data.iso",
- "version": "1.0",
- "md5sum": "15ca60c12db6d13b8eeae1a19613fd6e",
- "filesize": 378880,
- "download_url": "https://github.com/asenci/gns3-centos-cloud-init-data/raw/master/centos-cloud-init-data.iso"
+ "version": "1.1",
+ "md5sum": "59ea8223fd659d8bce9081ff175912e9",
+ "filesize": 374784,
+ "download_url": "https://github.com/GNS3/gns3-registry/tree/master/cloud-init/centos-cloud",
+ "direct_download_url": "https://github.com/GNS3/gns3-registry/raw/master/cloud-init/centos-cloud/centos-cloud-init-data.iso"
}
],
"versions": [
diff --git a/gns3server/appliances/debian.gns3a b/gns3server/appliances/debian.gns3a
index 6bee9798..49858688 100644
--- a/gns3server/appliances/debian.gns3a
+++ b/gns3server/appliances/debian.gns3a
@@ -44,7 +44,8 @@
"version": "1.0",
"md5sum": "43f6bf70c178a9d3c270b5c24971e578",
"filesize": 374784,
- "download_url": "https://github.com/GNS3/gns3-registry/raw/master/cloud-init/Debian/debian-cloud-init-data.iso"
+ "download_url": "https://github.com/GNS3/gns3-registry/tree/master/cloud-init/Debian",
+ "direct_download_url": "https://github.com/GNS3/gns3-registry/raw/master/cloud-init/Debian/debian-cloud-init-data.iso"
}
],
"versions": [
diff --git a/gns3server/appliances/fedora-cloud.gns3a b/gns3server/appliances/fedora-cloud.gns3a
index 9679fe69..93ec221b 100644
--- a/gns3server/appliances/fedora-cloud.gns3a
+++ b/gns3server/appliances/fedora-cloud.gns3a
@@ -31,14 +31,16 @@
"version": "35-1.2",
"md5sum": "cfa9cdcfb946e5f4cf9dd4d7906008d0",
"filesize": 376897536,
- "download_url": "https://download.fedoraproject.org/pub/fedora/linux/releases/35/Cloud/x86_64/images/Fedora-Cloud-Base-35-1.2.x86_64.qcow2"
+ "download_url": "https://download.fedoraproject.org/pub/fedora/linux/releases/35/Cloud/x86_64/images",
+ "direct_download_url": "https://download.fedoraproject.org/pub/fedora/linux/releases/35/Cloud/x86_64/images/Fedora-Cloud-Base-35-1.2.x86_64.qcow2"
},
{
"filename": "fedora-cloud-init-data.iso",
"version": "1.0",
"md5sum": "3d0d6391d3f5ece1180c70b9667c4dca",
"filesize": 374784,
- "download_url": "https://github.com/GNS3/gns3-registry/raw/master/cloud-init/fedora-cloud/fedora-cloud-init-data.iso"
+ "download_url": "https://github.com/GNS3/gns3-registry/tree/master/cloud-init/fedora-cloud",
+ "direct_download_url": "https://github.com/GNS3/gns3-registry/raw/master/cloud-init/fedora-cloud/fedora-cloud-init-data.iso"
}
],
"versions": [
diff --git a/gns3server/appliances/mikrotik-winbox.gns3a b/gns3server/appliances/mikrotik-winbox.gns3a
new file mode 100644
index 00000000..ce0f9caf
--- /dev/null
+++ b/gns3server/appliances/mikrotik-winbox.gns3a
@@ -0,0 +1,19 @@
+{
+ "appliance_id": "b770027f-1822-4ab6-b2f9-73336ca0983d",
+ "name": "Mikrotik WinBox",
+ "category": "guest",
+ "description": "Mikrotik's WinBox router management software for GNS3",
+ "vendor_name": "Mikrotik",
+ "vendor_url": "https://mikrotik.com",
+ "product_name": "Mikrotik WinBox",
+ "registry_version": 4,
+ "status": "stable",
+ "availability": "free",
+ "maintainer": "Alexander Horner",
+ "maintainer_email": "contact@alexhorner.cc",
+ "docker": {
+ "adapters": 1,
+ "image": "gns3/mikrotik-winbox",
+ "console_type": "vnc"
+ }
+}
diff --git a/gns3server/appliances/ntopng.gns3a b/gns3server/appliances/ntopng.gns3a
index 78639951..c54cc217 100644
--- a/gns3server/appliances/ntopng.gns3a
+++ b/gns3server/appliances/ntopng.gns3a
@@ -14,7 +14,7 @@
"usage": "In the web interface login as admin/admin\n\nPersistent configuration:\n- Add \"/var/lib/redis\" as an additional persistent directory.\n- Use \"redis-cli save\" in an auxiliary console to save the configuration.",
"docker": {
"adapters": 1,
- "image": "ntop/ntopng:latest",
+ "image": "ntop/ntopng:stable",
"start_command": "--dns-mode 2 --interface eth0",
"console_type": "http",
"console_http_port": 3000,
diff --git a/gns3server/appliances/oracle-linux-cloud.gns3a b/gns3server/appliances/oracle-linux-cloud.gns3a
new file mode 100644
index 00000000..a9709bcc
--- /dev/null
+++ b/gns3server/appliances/oracle-linux-cloud.gns3a
@@ -0,0 +1,70 @@
+{
+ "appliance_id": "88e67f45-e0de-4e5e-9f36-2dc83e4a6c60",
+ "name": "Oracle Linux Cloud Guest",
+ "category": "guest",
+ "description": "A highly performant and secure operating environment, Oracle Linux delivers virtualization, management, automation, and cloud native computing tools, along with the operating system, in a single, easy-to-manage support offering. Oracle Linux provides a 100% application binary compatible alternative to Red Hat Enterprise Linux and CentOS Linux and is supported across both hybrid and multicloud environments.",
+ "vendor_name": "Oracle Corporation",
+ "vendor_url": "https://www.oracle.com",
+ "documentation_url": "https://docs.oracle.com/en-us/iaas/images/",
+ "product_name": "Oracle Linux Cloud Guest",
+ "product_url": "https://www.oracle.com/au/linux/",
+ "registry_version": 4,
+ "status": "stable",
+ "maintainer": "GNS3 Team",
+ "maintainer_email": "developers@gns3.net",
+ "usage": "Username: oracle\nPassword: oracle",
+ "port_name_format": "Ethernet{0}",
+ "qemu": {
+ "adapter_type": "virtio-net-pci",
+ "adapters": 1,
+ "ram": 1024,
+ "hda_disk_interface": "virtio",
+ "arch": "x86_64",
+ "console_type": "telnet",
+ "boot_priority": "c",
+ "kvm": "require",
+ "options": "-cpu host -nographic"
+ },
+ "images": [
+ {
+ "filename": "OL9U1_x86_64-kvm-b158.qcow",
+ "version": "9.1",
+ "md5sum": "9f32851b96fc38191892197fa11f7435",
+ "filesize": 539033600,
+ "download_url": "https://yum.oracle.com/oracle-linux-templates.html",
+ "direct_download_url": "https://yum.oracle.com/templates/OracleLinux/OL9/u1/x86_64/OL9U1_x86_64-kvm-b158.qcow"
+ },
+ {
+ "filename": "OL8U7_x86_64-kvm-b148.qcow",
+ "version": "8.7",
+ "md5sum": "962cdde7e810888b9914e937222f687f",
+ "filesize": 913965056,
+ "download_url": "https://yum.oracle.com/oracle-linux-templates.html",
+ "direct_download_url": "https://yum.oracle.com/templates/OracleLinux/OL8/u7/x86_64/OL8U7_x86_64-kvm-b148.qcow"
+ },
+ {
+ "filename": "oracle-cloud-init-data.iso",
+ "version": "1.1",
+ "md5sum": "cb51bc42ae9dfb7345bfa7362a313baf",
+ "filesize": 374784,
+ "download_url": "https://github.com/GNS3/gns3-registry/tree/master/cloud-init/oracle-cloud",
+ "direct_download_url": "https://github.com/GNS3/gns3-registry/raw/master/cloud-init/oracle-cloud/oracle-cloud-init-data.iso"
+ }
+ ],
+ "versions": [
+ {
+ "name": "9.1",
+ "images": {
+ "hda_disk_image": "OL9U1_x86_64-kvm-b158.qcow",
+ "cdrom_image": "oracle-cloud-init-data.iso"
+ }
+ },
+ {
+ "name": "8.7",
+ "images": {
+ "hda_disk_image": "OL8U7_x86_64-kvm-b148.qcow",
+ "cdrom_image": "oracle-cloud-init-data.iso"
+ }
+ }
+ ]
+}
diff --git a/gns3server/appliances/rockylinux.gns3a b/gns3server/appliances/rockylinux.gns3a
index 86900cb9..2dd3fd1b 100644
--- a/gns3server/appliances/rockylinux.gns3a
+++ b/gns3server/appliances/rockylinux.gns3a
@@ -39,7 +39,8 @@
"version": "1.0",
"md5sum": "33ffda3a81436e305f37fb913edd6d43",
"filesize": 374784,
- "download_url": "https://github.com/GNS3/gns3-registry/raw/master/cloud-init/rocky-cloud/rocky-cloud-init-data.iso"
+ "download_url": "https://github.com/GNS3/gns3-registry/tree/master/cloud-init/rocky-cloud",
+ "direct_download_url": "https://github.com/GNS3/gns3-registry/raw/master/cloud-init/rocky-cloud/rocky-cloud-init-data.iso"
}
],
"versions": [
diff --git a/gns3server/appliances/ubuntu-cloud.gns3a b/gns3server/appliances/ubuntu-cloud.gns3a
index 59aba8a7..ad8d2421 100644
--- a/gns3server/appliances/ubuntu-cloud.gns3a
+++ b/gns3server/appliances/ubuntu-cloud.gns3a
@@ -29,51 +29,34 @@
{
"filename": "ubuntu-22.04-server-cloudimg-amd64.img",
"version": "22.04 (LTS)",
- "md5sum": "ac2351289daa173fa1ed6b2b81d81d7c",
- "filesize": 624295936,
- "download_url": "https://cloud-images.ubuntu.com/releases/jammy/release/ubuntu-22.04-server-cloudimg-amd64.img"
+ "md5sum": "3ce0b84f9592482fb645e8253b979827",
+ "filesize": 686096384,
+ "download_url": "https://cloud-images.ubuntu.com/releases/jammy/release",
+ "direct_download_url": "https://cloud-images.ubuntu.com/releases/jammy/release/ubuntu-22.04-server-cloudimg-amd64.img"
},
{
"filename": "ubuntu-20.04-server-cloudimg-amd64.img",
"version": "20.04 (LTS)",
"md5sum": "044bc979b2238192ee3edb44e2bb6405",
"filesize": 552337408,
- "download_url": "https://cloud-images.ubuntu.com/releases/focal/release-20210119.1/ubuntu-20.04-server-cloudimg-amd64.img"
+ "download_url": "https://cloud-images.ubuntu.com/releases/focal/release-20210119.1/",
+ "direct_download_url": "https://cloud-images.ubuntu.com/releases/focal/release-20210119.1/ubuntu-20.04-server-cloudimg-amd64.img"
},
{
"filename": "ubuntu-18.04-server-cloudimg-amd64.img",
"version": "18.04 (LTS)",
"md5sum": "f4134e7fa16d7fa766c7467cbe25c949",
"filesize": 336134144,
- "download_url": "https://cloud-images.ubuntu.com/releases/18.04/release-20180426.2/ubuntu-18.04-server-cloudimg-amd64.img"
- },
- {
- "filename": "ubuntu-17.10-server-cloudimg-amd64.img",
- "version": "17.10",
- "md5sum": "331b44f2b05858c251b3ea92c8b65152",
- "filesize": 320405504,
- "download_url": "https://cloud-images.ubuntu.com/releases/17.10/release-20180404/ubuntu-17.10-server-cloudimg-amd64.img"
- },
- {
- "filename": "ubuntu-16.04-server-cloudimg-amd64-disk1.img",
- "version": "16.04 (LTS)",
- "md5sum": "22c124ba65ea096cdef8b0a197dd613a",
- "filesize": 290193408,
- "download_url": "https://cloud-images.ubuntu.com/releases/16.04/release-20180405/ubuntu-16.04-server-cloudimg-amd64-disk1.img"
- },
- {
- "filename": "ubuntu-14.04-server-cloudimg-amd64-disk1.img",
- "version": "14.04 (LTS)",
- "md5sum": "d11b89321d41d0eeddcacf73bf0d2262",
- "filesize": 262668800,
- "download_url": "https://cloud-images.ubuntu.com/releases/14.04/release-20180404/ubuntu-14.04-server-cloudimg-amd64-disk1.img"
+ "download_url": "https://cloud-images.ubuntu.com/releases/18.04/release-20180426.2/",
+ "direct_download_url": "https://cloud-images.ubuntu.com/releases/18.04/release-20180426.2/ubuntu-18.04-server-cloudimg-amd64.img"
},
{
"filename": "ubuntu-cloud-init-data.iso",
- "version": "1.0",
- "md5sum": "328469100156ae8dbf262daa319c27ff",
- "filesize": 131072,
- "download_url": "https://github.com/asenci/gns3-ubuntu-cloud-init-data/raw/master/ubuntu-cloud-init-data.iso"
+ "version": "1.1",
+ "md5sum": "9a90ee8f88736204c756015b3cd86500",
+ "filesize": 374784,
+ "download_url": "https://github.com/GNS3/gns3-registry/tree/master/cloud-init/ubuntu-cloud",
+ "direct_download_url": "https://github.com/GNS3/gns3-registry/raw/master/cloud-init/ubuntu-cloud/ubuntu-cloud-init-data.iso"
}
],
"versions": [
@@ -97,27 +80,6 @@
"hda_disk_image": "ubuntu-18.04-server-cloudimg-amd64.img",
"cdrom_image": "ubuntu-cloud-init-data.iso"
}
- },
- {
- "name": "17.10",
- "images": {
- "hda_disk_image": "ubuntu-17.10-server-cloudimg-amd64.img",
- "cdrom_image": "ubuntu-cloud-init-data.iso"
- }
- },
- {
- "name": "16.04 (LTS)",
- "images": {
- "hda_disk_image": "ubuntu-16.04-server-cloudimg-amd64-disk1.img",
- "cdrom_image": "ubuntu-cloud-init-data.iso"
- }
- },
- {
- "name": "14.04 (LTS)",
- "images": {
- "hda_disk_image": "ubuntu-14.04-server-cloudimg-amd64-disk1.img",
- "cdrom_image": "ubuntu-cloud-init-data.iso"
- }
}
]
}
diff --git a/gns3server/compute/base_node.py b/gns3server/compute/base_node.py
index 54dea0d6..a41a417a 100644
--- a/gns3server/compute/base_node.py
+++ b/gns3server/compute/base_node.py
@@ -409,7 +409,10 @@ class BaseNode:
if self._wrapper_telnet_server:
self._wrap_console_writer.close()
if sys.version_info >= (3, 7, 0):
- await self._wrap_console_writer.wait_closed()
+ try:
+ await self._wrap_console_writer.wait_closed()
+ except ConnectionResetError:
+ pass
self._wrapper_telnet_server.close()
await self._wrapper_telnet_server.wait_closed()
self._wrapper_telnet_server = None
diff --git a/gns3server/compute/docker/__init__.py b/gns3server/compute/docker/__init__.py
index ea2a63cd..cc82daf9 100644
--- a/gns3server/compute/docker/__init__.py
+++ b/gns3server/compute/docker/__init__.py
@@ -150,9 +150,9 @@ class Docker(BaseManager):
data=data,
headers={"content-type": "application/json", },
timeout=timeout)
- except (aiohttp.ClientResponseError, aiohttp.ClientOSError) as e:
+ except aiohttp.ClientError as e:
raise DockerError("Docker has returned an error: {}".format(str(e)))
- except (asyncio.TimeoutError):
+ except asyncio.TimeoutError:
raise DockerError("Docker timeout " + method + " " + path)
if response.status >= 300:
body = await response.read()
diff --git a/gns3server/compute/docker/docker_vm.py b/gns3server/compute/docker/docker_vm.py
index 79bdb128..a10312e3 100644
--- a/gns3server/compute/docker/docker_vm.py
+++ b/gns3server/compute/docker/docker_vm.py
@@ -85,7 +85,6 @@ class DockerVM(BaseNode):
self._ethernet_adapters = []
self._temporary_directory = None
self._telnet_servers = []
- self._xvfb_process = None
self._vnc_process = None
self._vncconfig_process = None
self._console_resolution = console_resolution
@@ -585,8 +584,8 @@ class DockerVM(BaseNode):
self._display = self._get_free_display_port()
tigervnc_path = shutil.which("Xtigervnc") or shutil.which("Xvnc")
- if not (tigervnc_path or shutil.which("Xvfb") and shutil.which("x11vnc")):
- raise DockerError("Please install TigerVNC (recommended) or Xvfb + x11vnc before using VNC support")
+ if not tigervnc_path:
+ raise DockerError("Please install TigerVNC server before using VNC support")
if tigervnc_path:
with open(os.path.join(self.working_dir, "vnc.log"), "w") as fd:
@@ -600,29 +599,6 @@ class DockerVM(BaseNode):
"-SecurityTypes", "None",
":{}".format(self._display),
stdout=fd, stderr=subprocess.STDOUT)
- else:
- if restart is False:
- self._xvfb_process = await asyncio.create_subprocess_exec("Xvfb",
- "-nolisten", "tcp",
- "-extension", "MIT-SHM",
- ":{}".format(self._display),
- "-screen", "0",
- self._console_resolution + "x16")
-
- # We pass a port for TCPV6 due to a crash in X11VNC if not here: https://github.com/GNS3/gns3-server/issues/569
- with open(os.path.join(self.working_dir, "vnc.log"), "w") as fd:
- self._vnc_process = await asyncio.create_subprocess_exec("x11vnc",
- "-forever",
- "-nopw",
- "-shared",
- "-noshm",
- "-geometry", self._console_resolution,
- "-display", "WAIT:{}".format(self._display),
- "-rfbport", str(self.console),
- "-rfbportv6", str(self.console),
- "-noncache",
- "-listen", self._manager.port_manager.console_host,
- stdout=fd, stderr=subprocess.STDOUT)
async def _start_vnc(self):
"""
@@ -631,8 +607,8 @@ class DockerVM(BaseNode):
self._display = self._get_free_display_port()
tigervnc_path = shutil.which("Xtigervnc") or shutil.which("Xvnc")
- if not (tigervnc_path or shutil.which("Xvfb") and shutil.which("x11vnc")):
- raise DockerError("Please install TigerVNC server (recommended) or Xvfb + x11vnc before using VNC support")
+ if not tigervnc_path:
+ raise DockerError("Please install TigerVNC server before using VNC support")
await self._start_vnc_process()
x11_socket = os.path.join("/tmp/.X11-unix/", "X{}".format(self._display))
try:
@@ -875,12 +851,6 @@ class DockerVM(BaseNode):
await self._vnc_process.wait()
except ProcessLookupError:
pass
- if self._xvfb_process:
- try:
- self._xvfb_process.terminate()
- await self._xvfb_process.wait()
- except ProcessLookupError:
- pass
if self._display:
display = "/tmp/.X11-unix/X{}".format(self._display)
diff --git a/gns3server/compute/qemu/qemu_vm.py b/gns3server/compute/qemu/qemu_vm.py
index 6a8ef00b..2a111021 100644
--- a/gns3server/compute/qemu/qemu_vm.py
+++ b/gns3server/compute/qemu/qemu_vm.py
@@ -2150,6 +2150,8 @@ class QemuVM(BaseNode):
else:
# newer QEMU networking syntax
device_string = "{},mac={}".format(adapter_type, mac)
+ if adapter_type == "virtio-net-pci":
+ device_string = "{},speed=10000,duplex=full".format(device_string)
bridge_id = math.floor(pci_device_id / 32)
if bridge_id > 0:
if pci_bridges_created < bridge_id:
diff --git a/gns3server/controller/compute.py b/gns3server/controller/compute.py
index bf69b863..2b903745 100644
--- a/gns3server/controller/compute.py
+++ b/gns3server/controller/compute.py
@@ -450,7 +450,7 @@ class Compute:
elif response.type == aiohttp.WSMsgType.CLOSED:
pass
break
- except aiohttp.client_exceptions.ClientResponseError as e:
+ except aiohttp.ClientError as e:
log.error("Client response error received on compute '{}' WebSocket '{}': {}".format(self._id, ws_url,e))
finally:
self._connected = False
diff --git a/gns3server/controller/gns3vm/virtualbox_gns3_vm.py b/gns3server/controller/gns3vm/virtualbox_gns3_vm.py
index ddb6b3ea..ab8f84ed 100644
--- a/gns3server/controller/gns3vm/virtualbox_gns3_vm.py
+++ b/gns3server/controller/gns3vm/virtualbox_gns3_vm.py
@@ -122,9 +122,9 @@ class VirtualBoxGNS3VM(BaseGNS3VM):
continue
return interface
- async def _look_for_vboxnet(self, interface_number):
+ async def _look_for_vboxnet(self, backend_type, interface_number):
"""
- Look for the VirtualBox network name associated with a host only interface.
+ Look for the VirtualBox network name associated with an interface.
:returns: None or vboxnet name
"""
@@ -133,7 +133,7 @@ class VirtualBoxGNS3VM(BaseGNS3VM):
for info in result.splitlines():
if '=' in info:
name, value = info.split('=', 1)
- if name == "hostonlyadapter{}".format(interface_number):
+ if name == "{}{}".format(backend_type, interface_number):
return value.strip('"')
return None
@@ -159,7 +159,7 @@ class VirtualBoxGNS3VM(BaseGNS3VM):
return True
return False
- async def _check_vboxnet_exists(self, vboxnet):
+ async def _check_vboxnet_exists(self, vboxnet, vboxnet_type):
"""
Check if the vboxnet interface exists
@@ -167,7 +167,7 @@ class VirtualBoxGNS3VM(BaseGNS3VM):
:returns: boolean
"""
- properties = await self._execute("list", ["hostonlyifs"])
+ properties = await self._execute("list", ["{}".format(vboxnet_type)])
for prop in properties.splitlines():
try:
name, value = prop.split(':', 1)
@@ -230,29 +230,42 @@ class VirtualBoxGNS3VM(BaseGNS3VM):
if nat_interface_number < 0:
raise GNS3VMError('VM "{}" must have a NAT interface configured in order to start'.format(self.vmname))
- hostonly_interface_number = await self._look_for_interface("hostonly")
- if hostonly_interface_number < 0:
- raise GNS3VMError('VM "{}" must have a host-only interface configured in order to start'.format(self.vmname))
+ if sys.platform.startswith("darwin") and parse_version(self._system_properties["API version"]) >= parse_version("7_0"):
+ # VirtualBox 7.0+ on macOS requires a host-only network interface
+ backend_type = "hostonly-network"
+ backend_description = "host-only network"
+ vboxnet_type = "hostonlynets"
+ interface_number = await self._look_for_interface("hostonlynetwork")
+ if interface_number < 0:
+ raise GNS3VMError('VM "{}" must have a network adapter attached to a host-only network in order to start'.format(self.vmname))
+ else:
+ backend_type = "hostonlyadapter"
+ backend_description = "host-only adapter"
+ vboxnet_type = "hostonlyifs"
+ interface_number = await self._look_for_interface("hostonly")
- vboxnet = await self._look_for_vboxnet(hostonly_interface_number)
+ if interface_number < 0:
+ raise GNS3VMError('VM "{}" must have a network adapter attached to a {} in order to start'.format(self.vmname, backend_description))
+
+ vboxnet = await self._look_for_vboxnet(backend_type, interface_number)
if vboxnet is None:
- raise GNS3VMError('A VirtualBox host-only network could not be found on network adapter {} for "{}"'.format(hostonly_interface_number, self._vmname))
+ raise GNS3VMError('A VirtualBox host-only network could not be found on network adapter {} for "{}"'.format(interface_number, self._vmname))
- if not (await self._check_vboxnet_exists(vboxnet)):
+ if not (await self._check_vboxnet_exists(vboxnet, vboxnet_type)):
if sys.platform.startswith("win") and vboxnet == "vboxnet0":
# The GNS3 VM is configured with vboxnet0 by default which is not available
# on Windows. Try to patch this with the first available vboxnet we find.
first_available_vboxnet = await self._find_first_available_vboxnet()
if first_available_vboxnet is None:
- raise GNS3VMError('Please add a VirtualBox host-only network with DHCP enabled and attached it to network adapter {} for "{}"'.format(hostonly_interface_number, self._vmname))
- await self.set_hostonly_network(hostonly_interface_number, first_available_vboxnet)
+ raise GNS3VMError('Please add a VirtualBox host-only network with DHCP enabled and attached it to network adapter {} for "{}"'.format(interface_number, self._vmname))
+ await self.set_hostonly_network(interface_number, first_available_vboxnet)
vboxnet = first_available_vboxnet
else:
raise GNS3VMError('VirtualBox host-only network "{}" does not exist, please make the sure the network adapter {} configuration is valid for "{}"'.format(vboxnet,
- hostonly_interface_number,
+ interface_number,
self._vmname))
- if not (await self._check_dhcp_server(vboxnet)):
+ if backend_type == "hostonlyadapter" and not (await self._check_dhcp_server(vboxnet)):
raise GNS3VMError('DHCP must be enabled on VirtualBox host-only network "{}"'.format(vboxnet))
vm_state = await self._get_state()
@@ -296,7 +309,7 @@ class VirtualBoxGNS3VM(BaseGNS3VM):
await self._execute("controlvm", [self._vmname, "natpf{}".format(nat_interface_number),
"GNS3VM,tcp,{},{},,{}".format(ip_address, api_port, self.port)])
- self.ip_address = await self._get_ip(hostonly_interface_number, api_port)
+ self.ip_address = await self._get_ip(interface_number, api_port)
log.info("GNS3 VM has been started with IP {}".format(self.ip_address))
self.running = True
diff --git a/gns3server/controller/node.py b/gns3server/controller/node.py
index 906556b8..f07b25df 100644
--- a/gns3server/controller/node.py
+++ b/gns3server/controller/node.py
@@ -15,6 +15,7 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see .
+import ipaddress
import aiohttp
import asyncio
import html
@@ -716,6 +717,17 @@ class Node:
"first_port_name": self._first_port_name,
"custom_adapters": self._custom_adapters
}
+
+ # add brackets around console host for http/https console type
+ console_host = str(self._compute.console_host)
+ if self._console_type == "http" or self._console_type == "https":
+ try:
+ ip = ipaddress.ip_address(console_host)
+ if isinstance(ip, ipaddress.IPv6Address):
+ console_host = '[' + console_host + ']'
+ except ValueError:
+ pass
+
return {
"compute_id": str(self._compute.id),
"project_id": self._project.id,
@@ -725,7 +737,7 @@ class Node:
"node_directory": self._node_directory,
"name": self._name,
"console": self._console,
- "console_host": str(self._compute.console_host),
+ "console_host": console_host,
"console_type": self._console_type,
"console_auto_start": self._console_auto_start,
"command_line": self._command_line,
diff --git a/gns3server/controller/project.py b/gns3server/controller/project.py
index 1a7213da..c4dc3b95 100644
--- a/gns3server/controller/project.py
+++ b/gns3server/controller/project.py
@@ -798,7 +798,7 @@ class Project:
try:
await compute.post("/projects/{}/close".format(self._id), dont_connect=True)
# We don't care if a compute is down at this step
- except (ComputeError, aiohttp.web.HTTPError, aiohttp.ClientResponseError, TimeoutError):
+ except (ComputeError, aiohttp.web.HTTPError, aiohttp.ClientError, TimeoutError):
pass
self._clean_pictures()
self._status = "closed"
diff --git a/gns3server/crash_report.py b/gns3server/crash_report.py
index 7a1bc4f5..df6ed998 100644
--- a/gns3server/crash_report.py
+++ b/gns3server/crash_report.py
@@ -58,7 +58,7 @@ class CrashReport:
Report crash to a third party service
"""
- DSN = "https://75db396c4c294ad7a05ff7e8804ae5b8@o19455.ingest.sentry.io/38482"
+ DSN = "https://b929a9b102684c4d809647f1e613853a@o19455.ingest.sentry.io/38482"
_instance = None
def __init__(self):
diff --git a/gns3server/static/web-ui/26.52bf50eec59e1bcb0895.js b/gns3server/static/web-ui/26.52bf50eec59e1bcb0895.js
deleted file mode 100644
index 161a604f..00000000
--- a/gns3server/static/web-ui/26.52bf50eec59e1bcb0895.js
+++ /dev/null
@@ -1 +0,0 @@
-"use strict";(self.webpackChunkgns3_web_ui=self.webpackChunkgns3_web_ui||[]).push([[26],{91026:function(W,g,a){a.r(g),a.d(g,{TopologySummaryComponent:function(){return U}});var t=a(38999),_=a(96852),h=a(14200),f=a(36889),v=a(3941),y=a(15132),p=a(40098),x=a(39095),c=a(88802),S=a(73044),d=a(59412),T=a(93386);function C(i,e){if(1&i){var o=t.EpF();t.TgZ(0,"div",2),t.NdJ("mousemove",function(r){return t.CHM(o),t.oxw().dragWidget(r)},!1,t.evT)("mouseup",function(){return t.CHM(o),t.oxw().toggleDragging(!1)},!1,t.evT),t.qZA()}}function b(i,e){1&i&&(t.O4$(),t.TgZ(0,"svg",28),t._UZ(1,"rect",29),t.qZA())}function E(i,e){1&i&&(t.O4$(),t.TgZ(0,"svg",28),t._UZ(1,"rect",30),t.qZA())}function Z(i,e){1&i&&(t.O4$(),t.TgZ(0,"svg",28),t._UZ(1,"rect",31),t.qZA())}function O(i,e){if(1&i&&(t.TgZ(0,"div"),t._uU(1),t.qZA()),2&i){var o=t.oxw().$implicit;t.xp6(1),t.lnq(" ",o.console_type," ",o.console_host,":",o.console," ")}}function P(i,e){1&i&&(t.TgZ(0,"div"),t._uU(1," none "),t.qZA())}function M(i,e){if(1&i&&(t.TgZ(0,"div",25),t.TgZ(1,"div"),t.YNc(2,b,2,0,"svg",26),t.YNc(3,E,2,0,"svg",26),t.YNc(4,Z,2,0,"svg",26),t._uU(5),t.qZA(),t.YNc(6,O,2,3,"div",27),t.YNc(7,P,2,0,"div",27),t.qZA()),2&i){var o=e.$implicit;t.xp6(2),t.Q6J("ngIf","started"===o.status),t.xp6(1),t.Q6J("ngIf","suspended"===o.status),t.xp6(1),t.Q6J("ngIf","stopped"===o.status),t.xp6(1),t.hij(" ",o.name," "),t.xp6(1),t.Q6J("ngIf",null!=o.console&&null!=o.console&&"none"!=o.console_type),t.xp6(1),t.Q6J("ngIf",null==o.console||"none"===o.console_type)}}function w(i,e){1&i&&(t.O4$(),t.TgZ(0,"svg",28),t._UZ(1,"rect",29),t.qZA())}function A(i,e){1&i&&(t.O4$(),t.TgZ(0,"svg",28),t._UZ(1,"rect",31),t.qZA())}function F(i,e){if(1&i&&(t.TgZ(0,"div",25),t.TgZ(1,"div"),t.YNc(2,w,2,0,"svg",26),t.YNc(3,A,2,0,"svg",26),t._uU(4),t.qZA(),t.TgZ(5,"div"),t._uU(6),t.qZA(),t.TgZ(7,"div"),t._uU(8),t.qZA(),t.qZA()),2&i){var o=e.$implicit,s=t.oxw(2);t.xp6(2),t.Q6J("ngIf",o.connected),t.xp6(1),t.Q6J("ngIf",!o.connected),t.xp6(1),t.hij(" ",o.name," "),t.xp6(2),t.hij(" ",o.host," "),t.xp6(2),t.hij(" ",s.server.location," ")}}var I=function(i){return{lightTheme:i}},D=function(){return{right:!0,left:!0,bottom:!0,top:!0}};function N(i,e){if(1&i){var o=t.EpF();t.TgZ(0,"div",3),t.NdJ("mousedown",function(){return t.CHM(o),t.oxw().toggleDragging(!0)})("resizeStart",function(){return t.CHM(o),t.oxw().toggleDragging(!1)})("resizeEnd",function(n){return t.CHM(o),t.oxw().onResizeEnd(n)}),t.TgZ(1,"div",4),t.TgZ(2,"mat-tab-group"),t.TgZ(3,"mat-tab",5),t.NdJ("click",function(){return t.CHM(o),t.oxw().toggleTopologyVisibility(!0)}),t.TgZ(4,"div",6),t.TgZ(5,"div",7),t.TgZ(6,"mat-select",8),t.TgZ(7,"mat-optgroup",9),t.TgZ(8,"mat-option",10),t.NdJ("onSelectionChange",function(){return t.CHM(o),t.oxw().applyStatusFilter("started")}),t._uU(9,"started"),t.qZA(),t.TgZ(10,"mat-option",11),t.NdJ("onSelectionChange",function(){return t.CHM(o),t.oxw().applyStatusFilter("suspended")}),t._uU(11,"suspended"),t.qZA(),t.TgZ(12,"mat-option",12),t.NdJ("onSelectionChange",function(){return t.CHM(o),t.oxw().applyStatusFilter("stopped")}),t._uU(13,"stopped"),t.qZA(),t.qZA(),t.TgZ(14,"mat-optgroup",13),t.TgZ(15,"mat-option",14),t.NdJ("onSelectionChange",function(){return t.CHM(o),t.oxw().applyCaptureFilter("capture")}),t._uU(16,"active capture(s)"),t.qZA(),t.TgZ(17,"mat-option",15),t.NdJ("onSelectionChange",function(){return t.CHM(o),t.oxw().applyCaptureFilter("packet")}),t._uU(18,"active packet captures"),t.qZA(),t.qZA(),t.qZA(),t.qZA(),t.TgZ(19,"div",16),t.TgZ(20,"mat-select",17),t.NdJ("selectionChange",function(){return t.CHM(o),t.oxw().setSortingOrder()})("valueChange",function(n){return t.CHM(o),t.oxw().sortingOrder=n}),t.TgZ(21,"mat-option",18),t._uU(22,"sort by name ascending"),t.qZA(),t.TgZ(23,"mat-option",19),t._uU(24,"sort by name descending"),t.qZA(),t.qZA(),t.qZA(),t._UZ(25,"mat-divider",20),t.TgZ(26,"div",21),t.YNc(27,M,8,6,"div",22),t.qZA(),t.qZA(),t.qZA(),t.TgZ(28,"mat-tab",23),t.NdJ("click",function(){return t.CHM(o),t.oxw().toggleTopologyVisibility(!1)}),t.TgZ(29,"div",6),t.TgZ(30,"div",24),t.YNc(31,F,9,5,"div",22),t.qZA(),t.qZA(),t.qZA(),t.qZA(),t.qZA(),t.qZA()}if(2&i){var s=t.oxw();t.Q6J("ngStyle",s.style)("ngClass",t.VKq(9,I,s.isLightThemeEnabled))("validateResize",s.validate)("resizeEdges",t.DdM(11,D))("enableGhostResize",!0),t.xp6(20),t.Q6J("value",s.sortingOrder),t.xp6(6),t.Q6J("ngStyle",s.styleInside),t.xp6(1),t.Q6J("ngForOf",s.filteredNodes),t.xp6(4),t.Q6J("ngForOf",s.computes)}}var U=function(){function i(e,o,s,r,n){this.nodesDataSource=e,this.projectService=o,this.computeService=s,this.linksDataSource=r,this.themeService=n,this.closeTopologySummary=new t.vpe,this.style={},this.styleInside={height:"280px"},this.subscriptions=[],this.nodes=[],this.filteredNodes=[],this.sortingOrder="asc",this.startedStatusFilterEnabled=!1,this.suspendedStatusFilterEnabled=!1,this.stoppedStatusFilterEnabled=!1,this.captureFilterEnabled=!1,this.packetFilterEnabled=!1,this.computes=[],this.isTopologyVisible=!0,this.isDraggingEnabled=!1,this.isLightThemeEnabled=!1}return i.prototype.ngOnInit=function(){var e=this;this.isLightThemeEnabled="light"===this.themeService.getActualTheme(),this.subscriptions.push(this.nodesDataSource.changes.subscribe(function(o){e.nodes=o,e.nodes.forEach(function(s){("0.0.0.0"===s.console_host||"0:0:0:0:0:0:0:0"===s.console_host||"::"===s.console_host)&&(s.console_host=e.server.host)}),e.filteredNodes=o.sort("asc"===e.sortingOrder?e.compareAsc:e.compareDesc)})),this.projectService.getStatistics(this.server,this.project.project_id).subscribe(function(o){e.projectsStatistics=o}),this.computeService.getComputes(this.server).subscribe(function(o){e.computes=o}),this.revertPosition()},i.prototype.revertPosition=function(){var e=localStorage.getItem("leftPosition"),o=localStorage.getItem("rightPosition"),s=localStorage.getItem("topPosition"),r=localStorage.getItem("widthOfWidget"),n=localStorage.getItem("heightOfWidget");this.style=s?{position:"fixed",left:+e+"px",right:+o+"px",top:+s+"px",width:+r+"px",height:+n+"px"}:{top:"60px",right:"0px",width:"320px",height:"400px"}},i.prototype.toggleDragging=function(e){this.isDraggingEnabled=e},i.prototype.dragWidget=function(e){var o=Number(e.movementX),s=Number(e.movementY),r=Number(this.style.width.split("px")[0]),n=Number(this.style.height.split("px")[0]),l=Number(this.style.top.split("px")[0])+s;if(this.style.left){var u=Number(this.style.left.split("px")[0])+o;this.style={position:"fixed",left:u+"px",top:l+"px",width:r+"px",height:n+"px"},localStorage.setItem("leftPosition",u.toString()),localStorage.setItem("topPosition",l.toString()),localStorage.setItem("widthOfWidget",r.toString()),localStorage.setItem("heightOfWidget",n.toString())}else{var m=Number(this.style.right.split("px")[0])-o;this.style={position:"fixed",right:m+"px",top:l+"px",width:r+"px",height:n+"px"},localStorage.setItem("rightPosition",m.toString()),localStorage.setItem("topPosition",l.toString()),localStorage.setItem("widthOfWidget",r.toString()),localStorage.setItem("heightOfWidget",n.toString())}},i.prototype.validate=function(e){return!(e.rectangle.width&&e.rectangle.height&&(e.rectangle.width<290||e.rectangle.height<260))},i.prototype.onResizeEnd=function(e){this.style={position:"fixed",left:e.rectangle.left+"px",top:e.rectangle.top+"px",width:e.rectangle.width+"px",height:e.rectangle.height+"px"},this.styleInside={height:e.rectangle.height-120+"px"}},i.prototype.toggleTopologyVisibility=function(e){this.isTopologyVisible=e,this.revertPosition()},i.prototype.compareAsc=function(e,o){return e.name
-
+