mirror of
https://github.com/GNS3/gns3-server.git
synced 2024-11-16 16:54:51 +02:00
commit
4bf7838543
11
CHANGELOG
11
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
|
||||
|
@ -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": [
|
||||
|
@ -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": {
|
||||
|
@ -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": [
|
||||
|
@ -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": [
|
||||
|
@ -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": [
|
||||
|
19
gns3server/appliances/mikrotik-winbox.gns3a
Normal file
19
gns3server/appliances/mikrotik-winbox.gns3a
Normal file
@ -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"
|
||||
}
|
||||
}
|
@ -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,
|
||||
|
70
gns3server/appliances/oracle-linux-cloud.gns3a
Normal file
70
gns3server/appliances/oracle-linux-cloud.gns3a
Normal file
@ -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"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
@ -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": [
|
||||
|
@ -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"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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()
|
||||
|
@ -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)
|
||||
|
@ -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:
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -15,6 +15,7 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
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,
|
||||
|
@ -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"
|
||||
|
@ -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):
|
||||
|
File diff suppressed because one or more lines are too long
@ -46,6 +46,6 @@
|
||||
|
||||
gtag('config', 'G-5D6FZL9923');
|
||||
</script>
|
||||
<script src="runtime.91a209cf21f6fb848205.js" defer></script><script src="polyfills-es5.865074f5cd9a121111a2.js" nomodule defer></script><script src="polyfills.2f91a039d848e57ff02e.js" defer></script><script src="main.96be36058f5df0ca7e7f.js" defer></script>
|
||||
<script src="runtime.baa1121a4737aeb68bb7.js" defer></script><script src="polyfills-es5.865074f5cd9a121111a2.js" nomodule defer></script><script src="polyfills.2f91a039d848e57ff02e.js" defer></script><script src="main.8448c96e4facbe79a613.js" defer></script>
|
||||
|
||||
</body></html>
|
File diff suppressed because one or more lines are too long
@ -1 +0,0 @@
|
||||
!function(){"use strict";var e,v={},g={};function n(e){var u=g[e];if(void 0!==u)return u.exports;var t=g[e]={id:e,loaded:!1,exports:{}};return v[e](t,t.exports,n),t.loaded=!0,t.exports}n.m=v,e=[],n.O=function(u,t,a,o){if(!t){var r=1/0;for(i=0;i<e.length;i++){t=e[i][0],a=e[i][1],o=e[i][2];for(var l=!0,f=0;f<t.length;f++)(!1&o||r>=o)&&Object.keys(n.O).every(function(b){return n.O[b](t[f])})?t.splice(f--,1):(l=!1,o<r&&(r=o));if(l){e.splice(i--,1);var s=a();void 0!==s&&(u=s)}}return u}o=o||0;for(var i=e.length;i>0&&e[i-1][2]>o;i--)e[i]=e[i-1];e[i]=[t,a,o]},n.n=function(e){var u=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(u,{a:u}),u},n.d=function(e,u){for(var t in u)n.o(u,t)&&!n.o(e,t)&&Object.defineProperty(e,t,{enumerable:!0,get:u[t]})},n.f={},n.e=function(e){return Promise.all(Object.keys(n.f).reduce(function(u,t){return n.f[t](e,u),u},[]))},n.u=function(e){return e+".52bf50eec59e1bcb0895.js"},n.miniCssF=function(e){return"styles.f8555f2eecf8cf87f666.css"},n.hmd=function(e){return(e=Object.create(e)).children||(e.children=[]),Object.defineProperty(e,"exports",{enumerable:!0,set:function(){throw new Error("ES Modules may not assign module.exports or exports.*, Use ESM export syntax, instead: "+e.id)}}),e},n.o=function(e,u){return Object.prototype.hasOwnProperty.call(e,u)},function(){var e={},u="gns3-web-ui:";n.l=function(t,a,o,i){if(e[t])e[t].push(a);else{var r,l;if(void 0!==o)for(var f=document.getElementsByTagName("script"),s=0;s<f.length;s++){var c=f[s];if(c.getAttribute("src")==t||c.getAttribute("data-webpack")==u+o){r=c;break}}r||(l=!0,(r=document.createElement("script")).charset="utf-8",r.timeout=120,n.nc&&r.setAttribute("nonce",n.nc),r.setAttribute("data-webpack",u+o),r.src=n.tu(t)),e[t]=[a];var d=function(h,b){r.onerror=r.onload=null,clearTimeout(p);var _=e[t];if(delete e[t],r.parentNode&&r.parentNode.removeChild(r),_&&_.forEach(function(m){return m(b)}),h)return h(b)},p=setTimeout(d.bind(null,void 0,{type:"timeout",target:r}),12e4);r.onerror=d.bind(null,r.onerror),r.onload=d.bind(null,r.onload),l&&document.head.appendChild(r)}}}(),n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},function(){var e;n.tu=function(u){return void 0===e&&(e={createScriptURL:function(t){return t}},"undefined"!=typeof trustedTypes&&trustedTypes.createPolicy&&(e=trustedTypes.createPolicy("angular#bundler",e))),e.createScriptURL(u)}}(),n.p="",function(){var e={666:0};n.f.j=function(a,o){var i=n.o(e,a)?e[a]:void 0;if(0!==i)if(i)o.push(i[2]);else if(666!=a){var r=new Promise(function(c,d){i=e[a]=[c,d]});o.push(i[2]=r);var l=n.p+n.u(a),f=new Error;n.l(l,function(c){if(n.o(e,a)&&(0!==(i=e[a])&&(e[a]=void 0),i)){var d=c&&("load"===c.type?"missing":c.type),p=c&&c.target&&c.target.src;f.message="Loading chunk "+a+" failed.\n("+d+": "+p+")",f.name="ChunkLoadError",f.type=d,f.request=p,i[1](f)}},"chunk-"+a,a)}else e[a]=0},n.O.j=function(a){return 0===e[a]};var u=function(a,o){var f,s,i=o[0],r=o[1],l=o[2],c=0;for(f in r)n.o(r,f)&&(n.m[f]=r[f]);if(l)var d=l(n);for(a&&a(o);c<i.length;c++)n.o(e,s=i[c])&&e[s]&&e[s][0](),e[i[c]]=0;return n.O(d)},t=self.webpackChunkgns3_web_ui=self.webpackChunkgns3_web_ui||[];t.forEach(u.bind(null,0)),t.push=u.bind(null,t.push.bind(t))}()}();
|
@ -71,10 +71,10 @@ async def subprocess_check_output(*args, cwd=None, env=None, stderr=False):
|
||||
|
||||
if stderr:
|
||||
proc = await asyncio.create_subprocess_exec(*args, stderr=asyncio.subprocess.PIPE, cwd=cwd, env=env)
|
||||
output = await proc.stderr.read()
|
||||
_, output = await proc.communicate()
|
||||
else:
|
||||
proc = await asyncio.create_subprocess_exec(*args, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.DEVNULL, cwd=cwd, env=env)
|
||||
output = await proc.stdout.read()
|
||||
output, _ = await proc.communicate()
|
||||
if output is None:
|
||||
return ""
|
||||
# If we received garbage we ignore invalid characters
|
||||
|
@ -23,8 +23,8 @@
|
||||
# or negative for a release candidate or beta (after the base version
|
||||
# number has been incremented)
|
||||
|
||||
__version__ = "2.2.39"
|
||||
__version_info__ = (2, 2, 39, 0)
|
||||
__version__ = "2.2.40"
|
||||
__version_info__ = (2, 2, 40, 0)
|
||||
|
||||
if "dev" in __version__:
|
||||
try:
|
||||
|
@ -1115,8 +1115,7 @@ async def test_close(vm, port_manager):
|
||||
async def test_close_vnc(vm):
|
||||
|
||||
vm._console_type = "vnc"
|
||||
vm._x11vnc_process = MagicMock()
|
||||
vm._xvfb_process = MagicMock()
|
||||
vm._vnc_process = MagicMock()
|
||||
|
||||
with asyncio_patch("gns3server.compute.docker.DockerVM._get_container_state", return_value="stopped"):
|
||||
with asyncio_patch("gns3server.compute.docker.Docker.query") as mock_query:
|
||||
@ -1124,7 +1123,7 @@ async def test_close_vnc(vm):
|
||||
mock_query.assert_called_with("DELETE", "containers/e90e34656842", params={"force": 1, "v": 1})
|
||||
|
||||
assert vm._closed is True
|
||||
assert vm._xvfb_process.terminate.called
|
||||
assert vm._vnc_process.terminate.called
|
||||
|
||||
|
||||
async def test_get_namespace(vm):
|
||||
|
@ -102,6 +102,7 @@ async def test_start(vm):
|
||||
|
||||
with asyncio_patch("asyncio.create_subprocess_exec", return_value=mock_process) as mock_exec:
|
||||
mock_process.returncode = None
|
||||
mock_process.communicate = AsyncioMagicMock(return_value=(None, None))
|
||||
await vm.start()
|
||||
assert vm.is_running()
|
||||
assert vm.command_line == ' '.join(mock_exec.call_args[0])
|
||||
@ -130,6 +131,7 @@ async def test_start_with_iourc(vm, tmpdir):
|
||||
with patch("gns3server.config.Config.get_section_config", return_value={"iourc_path": fake_file}):
|
||||
with asyncio_patch("asyncio.create_subprocess_exec", return_value=mock_process) as exec_mock:
|
||||
mock_process.returncode = None
|
||||
mock_process.communicate = AsyncioMagicMock(return_value=(None, None))
|
||||
await vm.start()
|
||||
assert vm.is_running()
|
||||
arsgs, kwargs = exec_mock.call_args
|
||||
@ -165,11 +167,12 @@ async def test_stop(vm):
|
||||
future = asyncio.Future()
|
||||
future.set_result(True)
|
||||
process.wait.return_value = future
|
||||
process.returncode = None
|
||||
process.communicate = AsyncioMagicMock(return_value=(None, None))
|
||||
|
||||
with asyncio_patch("asyncio.create_subprocess_exec", return_value=process):
|
||||
with asyncio_patch("gns3server.utils.asyncio.wait_for_process_termination"):
|
||||
await vm.start()
|
||||
process.returncode = None
|
||||
assert vm.is_running()
|
||||
await vm.stop()
|
||||
assert vm.is_running() is False
|
||||
@ -190,6 +193,7 @@ async def test_reload(vm, fake_iou_bin):
|
||||
future.set_result(True)
|
||||
process.wait.return_value = future
|
||||
process.returncode = None
|
||||
process.communicate = AsyncioMagicMock(return_value=(None, None))
|
||||
|
||||
with asyncio_patch("asyncio.create_subprocess_exec", return_value=process):
|
||||
with asyncio_patch("gns3server.utils.asyncio.wait_for_process_termination"):
|
||||
@ -202,10 +206,13 @@ async def test_reload(vm, fake_iou_bin):
|
||||
|
||||
async def test_close(vm, port_manager):
|
||||
|
||||
process = MagicMock()
|
||||
process.returncode = None
|
||||
process.communicate = AsyncioMagicMock(return_value=(None, None))
|
||||
vm._start_ubridge = AsyncioMagicMock(return_value=True)
|
||||
vm._ubridge_send = AsyncioMagicMock()
|
||||
with asyncio_patch("gns3server.compute.iou.iou_vm.IOUVM._check_requirements", return_value=True):
|
||||
with asyncio_patch("asyncio.create_subprocess_exec", return_value=MagicMock()):
|
||||
with asyncio_patch("asyncio.create_subprocess_exec", return_value=process):
|
||||
await vm.start()
|
||||
port = vm.console
|
||||
await vm.close()
|
||||
|
@ -737,6 +737,20 @@ async def test_build_command_large_number_of_adapters(vm):
|
||||
await vm._build_command()
|
||||
|
||||
|
||||
async def test_build_command_with_virtio_net_pci_adapter(vm):
|
||||
"""
|
||||
Test virtio-net-pci adapter which has parameters speed=1000 & duplex=full hard-coded
|
||||
"""
|
||||
|
||||
vm.manager.get_qemu_version = AsyncioMagicMock(return_value="2.4.0")
|
||||
vm.adapters = 1
|
||||
vm.mac_address = "00:00:ab:0e:0f:09"
|
||||
vm._adapter_type = "virtio-net-pci"
|
||||
with asyncio_patch("asyncio.create_subprocess_exec", return_value=MagicMock()):
|
||||
cmd = await vm._build_command()
|
||||
assert "virtio-net-pci,mac=00:00:ab:0e:0f:09,speed=10000,duplex=full,netdev=gns3-0" in cmd
|
||||
|
||||
|
||||
@pytest.mark.skipif(sys.platform.startswith("win"), reason="Not supported on Windows")
|
||||
async def test_build_command_with_invalid_options(vm):
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user