mirror of
https://github.com/GNS3/gns3-server.git
synced 2025-01-19 03:06:32 +00:00
commit
4bf7838543
11
CHANGELOG
11
CHANGELOG
@ -1,5 +1,16 @@
|
|||||||
# Change Log
|
# 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
|
## 2.2.39 08/05/2023
|
||||||
|
|
||||||
* Install web-ui v2.2.39
|
* Install web-ui v2.2.39
|
||||||
|
@ -37,7 +37,8 @@
|
|||||||
"version": "1.0",
|
"version": "1.0",
|
||||||
"md5sum": "72fb52af76e9561d125dd99224e2c1d1",
|
"md5sum": "72fb52af76e9561d125dd99224e2c1d1",
|
||||||
"filesize": 374784,
|
"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": [
|
"versions": [
|
||||||
|
@ -32,6 +32,13 @@
|
|||||||
"process_priority": "normal"
|
"process_priority": "normal"
|
||||||
},
|
},
|
||||||
"images": [
|
"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",
|
"filename": "arubaoscx-disk-image-genericx86-p4-20221130174651.vmdk",
|
||||||
"version": "10.11.0001",
|
"version": "10.11.0001",
|
||||||
@ -111,6 +118,12 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"versions": [
|
"versions": [
|
||||||
|
{
|
||||||
|
"name": "10.12.0006",
|
||||||
|
"images": {
|
||||||
|
"hda_disk_image": "arubaoscx-disk-image-genericx86-p4-20230531220439.vmdk"
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "10.11.0001",
|
"name": "10.11.0001",
|
||||||
"images": {
|
"images": {
|
||||||
|
@ -26,33 +26,37 @@
|
|||||||
"options": "-nographic"
|
"options": "-nographic"
|
||||||
},
|
},
|
||||||
"images": [
|
"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",
|
"filename": "CentOS-7-x86_64-GenericCloud-2111.qcow2",
|
||||||
"version": "7 (2111)",
|
"version": "7 (2111)",
|
||||||
"md5sum": "730b8662695831670721c8245be61dac",
|
"md5sum": "730b8662695831670721c8245be61dac",
|
||||||
"filesize": 897384448,
|
"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",
|
"filename": "CentOS-7-x86_64-GenericCloud-1809.qcow2",
|
||||||
"version": "7 (1809)",
|
"version": "7 (1809)",
|
||||||
"md5sum": "da79108d1324b27bd1759362b82fbe40",
|
"md5sum": "da79108d1324b27bd1759362b82fbe40",
|
||||||
"filesize": 914948096,
|
"filesize": 914948096,
|
||||||
"download_url": "https://cloud.centos.org/centos/7/images/CentOS-7-x86_64-GenericCloud-1809.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-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"
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"filename": "centos-cloud-init-data.iso",
|
"filename": "centos-cloud-init-data.iso",
|
||||||
"version": "1.0",
|
"version": "1.1",
|
||||||
"md5sum": "15ca60c12db6d13b8eeae1a19613fd6e",
|
"md5sum": "59ea8223fd659d8bce9081ff175912e9",
|
||||||
"filesize": 378880,
|
"filesize": 374784,
|
||||||
"download_url": "https://github.com/asenci/gns3-centos-cloud-init-data/raw/master/centos-cloud-init-data.iso"
|
"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": [
|
"versions": [
|
||||||
|
@ -44,7 +44,8 @@
|
|||||||
"version": "1.0",
|
"version": "1.0",
|
||||||
"md5sum": "43f6bf70c178a9d3c270b5c24971e578",
|
"md5sum": "43f6bf70c178a9d3c270b5c24971e578",
|
||||||
"filesize": 374784,
|
"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": [
|
"versions": [
|
||||||
|
@ -31,14 +31,16 @@
|
|||||||
"version": "35-1.2",
|
"version": "35-1.2",
|
||||||
"md5sum": "cfa9cdcfb946e5f4cf9dd4d7906008d0",
|
"md5sum": "cfa9cdcfb946e5f4cf9dd4d7906008d0",
|
||||||
"filesize": 376897536,
|
"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",
|
"filename": "fedora-cloud-init-data.iso",
|
||||||
"version": "1.0",
|
"version": "1.0",
|
||||||
"md5sum": "3d0d6391d3f5ece1180c70b9667c4dca",
|
"md5sum": "3d0d6391d3f5ece1180c70b9667c4dca",
|
||||||
"filesize": 374784,
|
"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": [
|
"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.",
|
"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": {
|
"docker": {
|
||||||
"adapters": 1,
|
"adapters": 1,
|
||||||
"image": "ntop/ntopng:latest",
|
"image": "ntop/ntopng:stable",
|
||||||
"start_command": "--dns-mode 2 --interface eth0",
|
"start_command": "--dns-mode 2 --interface eth0",
|
||||||
"console_type": "http",
|
"console_type": "http",
|
||||||
"console_http_port": 3000,
|
"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",
|
"version": "1.0",
|
||||||
"md5sum": "33ffda3a81436e305f37fb913edd6d43",
|
"md5sum": "33ffda3a81436e305f37fb913edd6d43",
|
||||||
"filesize": 374784,
|
"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": [
|
"versions": [
|
||||||
|
@ -29,51 +29,34 @@
|
|||||||
{
|
{
|
||||||
"filename": "ubuntu-22.04-server-cloudimg-amd64.img",
|
"filename": "ubuntu-22.04-server-cloudimg-amd64.img",
|
||||||
"version": "22.04 (LTS)",
|
"version": "22.04 (LTS)",
|
||||||
"md5sum": "ac2351289daa173fa1ed6b2b81d81d7c",
|
"md5sum": "3ce0b84f9592482fb645e8253b979827",
|
||||||
"filesize": 624295936,
|
"filesize": 686096384,
|
||||||
"download_url": "https://cloud-images.ubuntu.com/releases/jammy/release/ubuntu-22.04-server-cloudimg-amd64.img"
|
"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",
|
"filename": "ubuntu-20.04-server-cloudimg-amd64.img",
|
||||||
"version": "20.04 (LTS)",
|
"version": "20.04 (LTS)",
|
||||||
"md5sum": "044bc979b2238192ee3edb44e2bb6405",
|
"md5sum": "044bc979b2238192ee3edb44e2bb6405",
|
||||||
"filesize": 552337408,
|
"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",
|
"filename": "ubuntu-18.04-server-cloudimg-amd64.img",
|
||||||
"version": "18.04 (LTS)",
|
"version": "18.04 (LTS)",
|
||||||
"md5sum": "f4134e7fa16d7fa766c7467cbe25c949",
|
"md5sum": "f4134e7fa16d7fa766c7467cbe25c949",
|
||||||
"filesize": 336134144,
|
"filesize": 336134144,
|
||||||
"download_url": "https://cloud-images.ubuntu.com/releases/18.04/release-20180426.2/ubuntu-18.04-server-cloudimg-amd64.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-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"
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"filename": "ubuntu-cloud-init-data.iso",
|
"filename": "ubuntu-cloud-init-data.iso",
|
||||||
"version": "1.0",
|
"version": "1.1",
|
||||||
"md5sum": "328469100156ae8dbf262daa319c27ff",
|
"md5sum": "9a90ee8f88736204c756015b3cd86500",
|
||||||
"filesize": 131072,
|
"filesize": 374784,
|
||||||
"download_url": "https://github.com/asenci/gns3-ubuntu-cloud-init-data/raw/master/ubuntu-cloud-init-data.iso"
|
"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": [
|
"versions": [
|
||||||
@ -97,27 +80,6 @@
|
|||||||
"hda_disk_image": "ubuntu-18.04-server-cloudimg-amd64.img",
|
"hda_disk_image": "ubuntu-18.04-server-cloudimg-amd64.img",
|
||||||
"cdrom_image": "ubuntu-cloud-init-data.iso"
|
"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:
|
if self._wrapper_telnet_server:
|
||||||
self._wrap_console_writer.close()
|
self._wrap_console_writer.close()
|
||||||
if sys.version_info >= (3, 7, 0):
|
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()
|
self._wrapper_telnet_server.close()
|
||||||
await self._wrapper_telnet_server.wait_closed()
|
await self._wrapper_telnet_server.wait_closed()
|
||||||
self._wrapper_telnet_server = None
|
self._wrapper_telnet_server = None
|
||||||
|
@ -150,9 +150,9 @@ class Docker(BaseManager):
|
|||||||
data=data,
|
data=data,
|
||||||
headers={"content-type": "application/json", },
|
headers={"content-type": "application/json", },
|
||||||
timeout=timeout)
|
timeout=timeout)
|
||||||
except (aiohttp.ClientResponseError, aiohttp.ClientOSError) as e:
|
except aiohttp.ClientError as e:
|
||||||
raise DockerError("Docker has returned an error: {}".format(str(e)))
|
raise DockerError("Docker has returned an error: {}".format(str(e)))
|
||||||
except (asyncio.TimeoutError):
|
except asyncio.TimeoutError:
|
||||||
raise DockerError("Docker timeout " + method + " " + path)
|
raise DockerError("Docker timeout " + method + " " + path)
|
||||||
if response.status >= 300:
|
if response.status >= 300:
|
||||||
body = await response.read()
|
body = await response.read()
|
||||||
|
@ -85,7 +85,6 @@ class DockerVM(BaseNode):
|
|||||||
self._ethernet_adapters = []
|
self._ethernet_adapters = []
|
||||||
self._temporary_directory = None
|
self._temporary_directory = None
|
||||||
self._telnet_servers = []
|
self._telnet_servers = []
|
||||||
self._xvfb_process = None
|
|
||||||
self._vnc_process = None
|
self._vnc_process = None
|
||||||
self._vncconfig_process = None
|
self._vncconfig_process = None
|
||||||
self._console_resolution = console_resolution
|
self._console_resolution = console_resolution
|
||||||
@ -585,8 +584,8 @@ class DockerVM(BaseNode):
|
|||||||
self._display = self._get_free_display_port()
|
self._display = self._get_free_display_port()
|
||||||
tigervnc_path = shutil.which("Xtigervnc") or shutil.which("Xvnc")
|
tigervnc_path = shutil.which("Xtigervnc") or shutil.which("Xvnc")
|
||||||
|
|
||||||
if not (tigervnc_path or shutil.which("Xvfb") and shutil.which("x11vnc")):
|
if not tigervnc_path:
|
||||||
raise DockerError("Please install TigerVNC (recommended) or Xvfb + x11vnc before using VNC support")
|
raise DockerError("Please install TigerVNC server before using VNC support")
|
||||||
|
|
||||||
if tigervnc_path:
|
if tigervnc_path:
|
||||||
with open(os.path.join(self.working_dir, "vnc.log"), "w") as fd:
|
with open(os.path.join(self.working_dir, "vnc.log"), "w") as fd:
|
||||||
@ -600,29 +599,6 @@ class DockerVM(BaseNode):
|
|||||||
"-SecurityTypes", "None",
|
"-SecurityTypes", "None",
|
||||||
":{}".format(self._display),
|
":{}".format(self._display),
|
||||||
stdout=fd, stderr=subprocess.STDOUT)
|
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):
|
async def _start_vnc(self):
|
||||||
"""
|
"""
|
||||||
@ -631,8 +607,8 @@ class DockerVM(BaseNode):
|
|||||||
|
|
||||||
self._display = self._get_free_display_port()
|
self._display = self._get_free_display_port()
|
||||||
tigervnc_path = shutil.which("Xtigervnc") or shutil.which("Xvnc")
|
tigervnc_path = shutil.which("Xtigervnc") or shutil.which("Xvnc")
|
||||||
if not (tigervnc_path or shutil.which("Xvfb") and shutil.which("x11vnc")):
|
if not tigervnc_path:
|
||||||
raise DockerError("Please install TigerVNC server (recommended) or Xvfb + x11vnc before using VNC support")
|
raise DockerError("Please install TigerVNC server before using VNC support")
|
||||||
await self._start_vnc_process()
|
await self._start_vnc_process()
|
||||||
x11_socket = os.path.join("/tmp/.X11-unix/", "X{}".format(self._display))
|
x11_socket = os.path.join("/tmp/.X11-unix/", "X{}".format(self._display))
|
||||||
try:
|
try:
|
||||||
@ -875,12 +851,6 @@ class DockerVM(BaseNode):
|
|||||||
await self._vnc_process.wait()
|
await self._vnc_process.wait()
|
||||||
except ProcessLookupError:
|
except ProcessLookupError:
|
||||||
pass
|
pass
|
||||||
if self._xvfb_process:
|
|
||||||
try:
|
|
||||||
self._xvfb_process.terminate()
|
|
||||||
await self._xvfb_process.wait()
|
|
||||||
except ProcessLookupError:
|
|
||||||
pass
|
|
||||||
|
|
||||||
if self._display:
|
if self._display:
|
||||||
display = "/tmp/.X11-unix/X{}".format(self._display)
|
display = "/tmp/.X11-unix/X{}".format(self._display)
|
||||||
|
@ -2150,6 +2150,8 @@ class QemuVM(BaseNode):
|
|||||||
else:
|
else:
|
||||||
# newer QEMU networking syntax
|
# newer QEMU networking syntax
|
||||||
device_string = "{},mac={}".format(adapter_type, mac)
|
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)
|
bridge_id = math.floor(pci_device_id / 32)
|
||||||
if bridge_id > 0:
|
if bridge_id > 0:
|
||||||
if pci_bridges_created < bridge_id:
|
if pci_bridges_created < bridge_id:
|
||||||
|
@ -450,7 +450,7 @@ class Compute:
|
|||||||
elif response.type == aiohttp.WSMsgType.CLOSED:
|
elif response.type == aiohttp.WSMsgType.CLOSED:
|
||||||
pass
|
pass
|
||||||
break
|
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))
|
log.error("Client response error received on compute '{}' WebSocket '{}': {}".format(self._id, ws_url,e))
|
||||||
finally:
|
finally:
|
||||||
self._connected = False
|
self._connected = False
|
||||||
|
@ -122,9 +122,9 @@ class VirtualBoxGNS3VM(BaseGNS3VM):
|
|||||||
continue
|
continue
|
||||||
return interface
|
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
|
:returns: None or vboxnet name
|
||||||
"""
|
"""
|
||||||
@ -133,7 +133,7 @@ class VirtualBoxGNS3VM(BaseGNS3VM):
|
|||||||
for info in result.splitlines():
|
for info in result.splitlines():
|
||||||
if '=' in info:
|
if '=' in info:
|
||||||
name, value = info.split('=', 1)
|
name, value = info.split('=', 1)
|
||||||
if name == "hostonlyadapter{}".format(interface_number):
|
if name == "{}{}".format(backend_type, interface_number):
|
||||||
return value.strip('"')
|
return value.strip('"')
|
||||||
return None
|
return None
|
||||||
|
|
||||||
@ -159,7 +159,7 @@ class VirtualBoxGNS3VM(BaseGNS3VM):
|
|||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
async def _check_vboxnet_exists(self, vboxnet):
|
async def _check_vboxnet_exists(self, vboxnet, vboxnet_type):
|
||||||
"""
|
"""
|
||||||
Check if the vboxnet interface exists
|
Check if the vboxnet interface exists
|
||||||
|
|
||||||
@ -167,7 +167,7 @@ class VirtualBoxGNS3VM(BaseGNS3VM):
|
|||||||
:returns: boolean
|
:returns: boolean
|
||||||
"""
|
"""
|
||||||
|
|
||||||
properties = await self._execute("list", ["hostonlyifs"])
|
properties = await self._execute("list", ["{}".format(vboxnet_type)])
|
||||||
for prop in properties.splitlines():
|
for prop in properties.splitlines():
|
||||||
try:
|
try:
|
||||||
name, value = prop.split(':', 1)
|
name, value = prop.split(':', 1)
|
||||||
@ -230,29 +230,42 @@ class VirtualBoxGNS3VM(BaseGNS3VM):
|
|||||||
if nat_interface_number < 0:
|
if nat_interface_number < 0:
|
||||||
raise GNS3VMError('VM "{}" must have a NAT interface configured in order to start'.format(self.vmname))
|
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 sys.platform.startswith("darwin") and parse_version(self._system_properties["API version"]) >= parse_version("7_0"):
|
||||||
if hostonly_interface_number < 0:
|
# VirtualBox 7.0+ on macOS requires a host-only network interface
|
||||||
raise GNS3VMError('VM "{}" must have a host-only interface configured in order to start'.format(self.vmname))
|
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:
|
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":
|
if sys.platform.startswith("win") and vboxnet == "vboxnet0":
|
||||||
# The GNS3 VM is configured with vboxnet0 by default which is not available
|
# 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.
|
# on Windows. Try to patch this with the first available vboxnet we find.
|
||||||
first_available_vboxnet = await self._find_first_available_vboxnet()
|
first_available_vboxnet = await self._find_first_available_vboxnet()
|
||||||
if first_available_vboxnet is None:
|
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))
|
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(hostonly_interface_number, first_available_vboxnet)
|
await self.set_hostonly_network(interface_number, first_available_vboxnet)
|
||||||
vboxnet = first_available_vboxnet
|
vboxnet = first_available_vboxnet
|
||||||
else:
|
else:
|
||||||
raise GNS3VMError('VirtualBox host-only network "{}" does not exist, please make the sure the network adapter {} configuration is valid for "{}"'.format(vboxnet,
|
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))
|
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))
|
raise GNS3VMError('DHCP must be enabled on VirtualBox host-only network "{}"'.format(vboxnet))
|
||||||
|
|
||||||
vm_state = await self._get_state()
|
vm_state = await self._get_state()
|
||||||
@ -296,7 +309,7 @@ class VirtualBoxGNS3VM(BaseGNS3VM):
|
|||||||
await self._execute("controlvm", [self._vmname, "natpf{}".format(nat_interface_number),
|
await self._execute("controlvm", [self._vmname, "natpf{}".format(nat_interface_number),
|
||||||
"GNS3VM,tcp,{},{},,{}".format(ip_address, api_port, self.port)])
|
"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))
|
log.info("GNS3 VM has been started with IP {}".format(self.ip_address))
|
||||||
self.running = True
|
self.running = True
|
||||||
|
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
# You should have received a copy of the GNU General Public License
|
# You should have received a copy of the GNU General Public License
|
||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
import ipaddress
|
||||||
import aiohttp
|
import aiohttp
|
||||||
import asyncio
|
import asyncio
|
||||||
import html
|
import html
|
||||||
@ -716,6 +717,17 @@ class Node:
|
|||||||
"first_port_name": self._first_port_name,
|
"first_port_name": self._first_port_name,
|
||||||
"custom_adapters": self._custom_adapters
|
"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 {
|
return {
|
||||||
"compute_id": str(self._compute.id),
|
"compute_id": str(self._compute.id),
|
||||||
"project_id": self._project.id,
|
"project_id": self._project.id,
|
||||||
@ -725,7 +737,7 @@ class Node:
|
|||||||
"node_directory": self._node_directory,
|
"node_directory": self._node_directory,
|
||||||
"name": self._name,
|
"name": self._name,
|
||||||
"console": self._console,
|
"console": self._console,
|
||||||
"console_host": str(self._compute.console_host),
|
"console_host": console_host,
|
||||||
"console_type": self._console_type,
|
"console_type": self._console_type,
|
||||||
"console_auto_start": self._console_auto_start,
|
"console_auto_start": self._console_auto_start,
|
||||||
"command_line": self._command_line,
|
"command_line": self._command_line,
|
||||||
|
@ -798,7 +798,7 @@ class Project:
|
|||||||
try:
|
try:
|
||||||
await compute.post("/projects/{}/close".format(self._id), dont_connect=True)
|
await compute.post("/projects/{}/close".format(self._id), dont_connect=True)
|
||||||
# We don't care if a compute is down at this step
|
# 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
|
pass
|
||||||
self._clean_pictures()
|
self._clean_pictures()
|
||||||
self._status = "closed"
|
self._status = "closed"
|
||||||
|
@ -58,7 +58,7 @@ class CrashReport:
|
|||||||
Report crash to a third party service
|
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
|
_instance = None
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
File diff suppressed because one or more lines are too long
@ -46,6 +46,6 @@
|
|||||||
|
|
||||||
gtag('config', 'G-5D6FZL9923');
|
gtag('config', 'G-5D6FZL9923');
|
||||||
</script>
|
</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>
|
</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:
|
if stderr:
|
||||||
proc = await asyncio.create_subprocess_exec(*args, stderr=asyncio.subprocess.PIPE, cwd=cwd, env=env)
|
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:
|
else:
|
||||||
proc = await asyncio.create_subprocess_exec(*args, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.DEVNULL, cwd=cwd, env=env)
|
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:
|
if output is None:
|
||||||
return ""
|
return ""
|
||||||
# If we received garbage we ignore invalid characters
|
# If we received garbage we ignore invalid characters
|
||||||
|
@ -23,8 +23,8 @@
|
|||||||
# or negative for a release candidate or beta (after the base version
|
# or negative for a release candidate or beta (after the base version
|
||||||
# number has been incremented)
|
# number has been incremented)
|
||||||
|
|
||||||
__version__ = "2.2.39"
|
__version__ = "2.2.40"
|
||||||
__version_info__ = (2, 2, 39, 0)
|
__version_info__ = (2, 2, 40, 0)
|
||||||
|
|
||||||
if "dev" in __version__:
|
if "dev" in __version__:
|
||||||
try:
|
try:
|
||||||
|
@ -1115,8 +1115,7 @@ async def test_close(vm, port_manager):
|
|||||||
async def test_close_vnc(vm):
|
async def test_close_vnc(vm):
|
||||||
|
|
||||||
vm._console_type = "vnc"
|
vm._console_type = "vnc"
|
||||||
vm._x11vnc_process = MagicMock()
|
vm._vnc_process = MagicMock()
|
||||||
vm._xvfb_process = MagicMock()
|
|
||||||
|
|
||||||
with asyncio_patch("gns3server.compute.docker.DockerVM._get_container_state", return_value="stopped"):
|
with asyncio_patch("gns3server.compute.docker.DockerVM._get_container_state", return_value="stopped"):
|
||||||
with asyncio_patch("gns3server.compute.docker.Docker.query") as mock_query:
|
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})
|
mock_query.assert_called_with("DELETE", "containers/e90e34656842", params={"force": 1, "v": 1})
|
||||||
|
|
||||||
assert vm._closed is True
|
assert vm._closed is True
|
||||||
assert vm._xvfb_process.terminate.called
|
assert vm._vnc_process.terminate.called
|
||||||
|
|
||||||
|
|
||||||
async def test_get_namespace(vm):
|
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:
|
with asyncio_patch("asyncio.create_subprocess_exec", return_value=mock_process) as mock_exec:
|
||||||
mock_process.returncode = None
|
mock_process.returncode = None
|
||||||
|
mock_process.communicate = AsyncioMagicMock(return_value=(None, None))
|
||||||
await vm.start()
|
await vm.start()
|
||||||
assert vm.is_running()
|
assert vm.is_running()
|
||||||
assert vm.command_line == ' '.join(mock_exec.call_args[0])
|
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 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:
|
with asyncio_patch("asyncio.create_subprocess_exec", return_value=mock_process) as exec_mock:
|
||||||
mock_process.returncode = None
|
mock_process.returncode = None
|
||||||
|
mock_process.communicate = AsyncioMagicMock(return_value=(None, None))
|
||||||
await vm.start()
|
await vm.start()
|
||||||
assert vm.is_running()
|
assert vm.is_running()
|
||||||
arsgs, kwargs = exec_mock.call_args
|
arsgs, kwargs = exec_mock.call_args
|
||||||
@ -165,11 +167,12 @@ async def test_stop(vm):
|
|||||||
future = asyncio.Future()
|
future = asyncio.Future()
|
||||||
future.set_result(True)
|
future.set_result(True)
|
||||||
process.wait.return_value = future
|
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("asyncio.create_subprocess_exec", return_value=process):
|
||||||
with asyncio_patch("gns3server.utils.asyncio.wait_for_process_termination"):
|
with asyncio_patch("gns3server.utils.asyncio.wait_for_process_termination"):
|
||||||
await vm.start()
|
await vm.start()
|
||||||
process.returncode = None
|
|
||||||
assert vm.is_running()
|
assert vm.is_running()
|
||||||
await vm.stop()
|
await vm.stop()
|
||||||
assert vm.is_running() is False
|
assert vm.is_running() is False
|
||||||
@ -190,6 +193,7 @@ async def test_reload(vm, fake_iou_bin):
|
|||||||
future.set_result(True)
|
future.set_result(True)
|
||||||
process.wait.return_value = future
|
process.wait.return_value = future
|
||||||
process.returncode = None
|
process.returncode = None
|
||||||
|
process.communicate = AsyncioMagicMock(return_value=(None, None))
|
||||||
|
|
||||||
with asyncio_patch("asyncio.create_subprocess_exec", return_value=process):
|
with asyncio_patch("asyncio.create_subprocess_exec", return_value=process):
|
||||||
with asyncio_patch("gns3server.utils.asyncio.wait_for_process_termination"):
|
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):
|
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._start_ubridge = AsyncioMagicMock(return_value=True)
|
||||||
vm._ubridge_send = AsyncioMagicMock()
|
vm._ubridge_send = AsyncioMagicMock()
|
||||||
with asyncio_patch("gns3server.compute.iou.iou_vm.IOUVM._check_requirements", return_value=True):
|
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()
|
await vm.start()
|
||||||
port = vm.console
|
port = vm.console
|
||||||
await vm.close()
|
await vm.close()
|
||||||
|
@ -737,6 +737,20 @@ async def test_build_command_large_number_of_adapters(vm):
|
|||||||
await vm._build_command()
|
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")
|
@pytest.mark.skipif(sys.platform.startswith("win"), reason="Not supported on Windows")
|
||||||
async def test_build_command_with_invalid_options(vm):
|
async def test_build_command_with_invalid_options(vm):
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user