mirror of
https://github.com/GNS3/gns3-server.git
synced 2026-11-07 07:33:43 +02:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
dadbacd8a4 | ||
|
|
9032fd2a5c | ||
|
|
eb0d4439a0 | ||
|
|
91a1c5db49 | ||
|
|
0a77233631 | ||
|
|
8df8b73c8f | ||
|
|
6968ae9295 | ||
|
|
1c9a43d071 | ||
|
|
a4bc696a5f | ||
|
|
10645a412b | ||
|
|
1b008fb516 | ||
|
|
45d135911f | ||
|
|
3626bd5adb | ||
|
|
6c322bbdde | ||
|
|
02c0fa26e1 | ||
|
|
99a238a0dc | ||
|
|
7b61724213 | ||
|
|
72c6f5b484 | ||
|
|
8536af33da | ||
|
|
4ddd45f788 | ||
|
|
53b1809dc3 | ||
|
|
dd11d38338 | ||
|
|
c0adc88592 | ||
|
|
2c9afbb217 | ||
|
|
770841b3ee | ||
|
|
896e99d046 | ||
|
|
10bb259248 | ||
|
|
4ab100b716 | ||
|
|
6fd60452c4 | ||
|
|
a2d57f7c37 | ||
|
|
fb153e3c71 | ||
|
|
69986b0d0f | ||
|
|
06a6a0a332 | ||
|
|
2606c2d9a7 | ||
|
|
57067a99fa | ||
|
|
087cba3903 | ||
|
|
0a5995b11c | ||
|
|
4f3fd65377 | ||
|
|
42eaf97e9f | ||
|
|
55a5ce77ba | ||
|
|
0922159686 | ||
|
|
f9ab4ffb96 | ||
|
|
241937b80b | ||
|
|
b179ca88a7 | ||
|
|
3484a7dd3d | ||
|
|
c313475f68 | ||
|
|
39d44c8480 | ||
|
|
c3b2128fae | ||
|
|
941bed9605 | ||
|
|
12a8831c44 |
No files matched your search
@@ -1,5 +1,28 @@
|
||||
# Change Log
|
||||
|
||||
## 2.2.8 07/05/2020
|
||||
|
||||
* Release Web-Ui 2020.2.0-beta.3
|
||||
* Default port set to 80 for server running in the GNS3 VM. Fixes #1737
|
||||
* Make the Web UI the default page. Ref https://github.com/GNS3/gns3-server/issues/1737
|
||||
* Support controller reloading for templates, appliances and projects. Ref #1743
|
||||
* Return exit status 1 if server fails to start. Fixes #1744
|
||||
* Use Environmental Markers to force jsonschema version. Fixes https://github.com/GNS3/gns3-gui/issues/2849 Version 3.2.0 with Python >= 3.8 Version 2.6.0 with Python < 3.8
|
||||
* Use Environmental Markers to force jsonschema version 2.6.0 on Windows/macOS. Ref https://github.com/GNS3/gns3-gui/issues/2849
|
||||
* Implement a minimum interval between cpu_percent() calls. Fixes #1738
|
||||
* Add clipboard support for TigerVnc
|
||||
* Sort snapshots by (created_at, name)
|
||||
* Unprotected access for websocket consoles. Ref https://github.com/GNS3/gns3-gui/issues/2883#issuecomment-580677552
|
||||
* Support for WebSocket consoles
|
||||
* Return array for controller statistics endpoint
|
||||
* Server statistics implementation
|
||||
|
||||
## 2.2.7 07/04/2020
|
||||
|
||||
* Release 2020.2.0-beta.1
|
||||
* Fix uBrigde error popups when Docker image has stopped. Fixes https://github.com/GNS3/gns3-gui/issues/2957
|
||||
* Fix warning that you are explicitly comparing literals
|
||||
|
||||
## 2.2.6 26/03/2020
|
||||
|
||||
* Remove --local when starting Docker dev server.
|
||||
|
||||
+15
-8
@@ -10,9 +10,20 @@ GNS3-server
|
||||
This is the GNS3 server repository.
|
||||
|
||||
The GNS3 server manages emulators such as Dynamips, VirtualBox or Qemu/KVM.
|
||||
Clients like the GNS3 GUI controls the server using a HTTP REST API.
|
||||
Clients like the `GNS3 GUI <https://github.com/GNS3/gns3-gui/>`_ and the `GNS3 Web UI <https://github.com/GNS3/gns3-web-ui>`_ control the server using a HTTP REST API.
|
||||
|
||||
You will need the GNS3 GUI (gns3-gui repository) to control the server.
|
||||
Software dependencies
|
||||
---------------------
|
||||
|
||||
In addition of Python dependencies listed in a section below, other software may be required, recommended or optional.
|
||||
|
||||
* `uBridge <https://github.com/GNS3/ubridge/>`_ is required, it interconnects the nodes.
|
||||
* `Dynamips <https://github.com/GNS3/dynamips/>`_ is required for running IOS routers (using real IOS images) as well as the internal switches and hubs.
|
||||
* `VPCS <https://github.com/GNS3/vpcs/>`_ is recommended, it is a builtin node simulating a very simple computer to perform connectitivy tests using ping, traceroute etc.
|
||||
* Qemu is strongly recommended on Linux, as most node types are based on Qemu, for example Cisco IOSv and Arista vEOS.
|
||||
* libvirt is recommended (Linux only), as it's needed for the NAT cloud
|
||||
* Docker is optional (Linux only), some nodes are based on Docker.
|
||||
* i386-libraries of libc and libcrypto are optional (Linux only), they are only needed to run IOU based nodes.
|
||||
|
||||
Branches
|
||||
--------
|
||||
@@ -22,7 +33,7 @@ master
|
||||
master is the next stable release, you can test it in your day to day activities.
|
||||
Bug fixes or small improvements pull requests go here.
|
||||
|
||||
2.x (2.1 for example)
|
||||
2.x (2.3 for example)
|
||||
*********************
|
||||
Next major release
|
||||
|
||||
@@ -45,11 +56,7 @@ You must be connected to the Internet in order to install the dependencies.
|
||||
|
||||
Dependencies:
|
||||
|
||||
- Python 3.4 or above
|
||||
- aiohttp
|
||||
- setuptools
|
||||
- psutil
|
||||
- jsonschema
|
||||
- Python 3.5.3, setuptools and the ones listed `here <https://github.com/GNS3/gns3-server/blob/master/requirements.txt>`_
|
||||
|
||||
The following commands will install some of these dependencies:
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ Parameters
|
||||
|
||||
Response status codes
|
||||
**********************
|
||||
- **201**: Snasphot created
|
||||
- **201**: Snapshot created
|
||||
- **404**: The project doesn't exist
|
||||
|
||||
Input
|
||||
@@ -54,7 +54,7 @@ Parameters
|
||||
|
||||
Response status codes
|
||||
**********************
|
||||
- **200**: Snasphot list returned
|
||||
- **200**: Snapshot list returned
|
||||
- **404**: The project doesn't exist
|
||||
|
||||
Sample session
|
||||
|
||||
@@ -10,7 +10,7 @@ Delete a snapshot from disk
|
||||
Parameters
|
||||
**********
|
||||
- **project_id**: Project UUID
|
||||
- **snapshot_id**: Snasphot UUID
|
||||
- **snapshot_id**: Snapshot UUID
|
||||
|
||||
Response status codes
|
||||
**********************
|
||||
|
||||
@@ -10,7 +10,7 @@ Restore a snapshot from disk
|
||||
Parameters
|
||||
**********
|
||||
- **project_id**: Project UUID
|
||||
- **snapshot_id**: Snasphot UUID
|
||||
- **snapshot_id**: Snapshot UUID
|
||||
|
||||
Response status codes
|
||||
**********************
|
||||
|
||||
@@ -44,7 +44,7 @@
|
||||
"md5sum": "3411a599e822f2ac6be560a26405821a",
|
||||
"filesize": 197120,
|
||||
"download_url": "https://sourceforge.net/projects/gns-3/files/Empty%20Qemu%30disk/",
|
||||
"direct_download_url": "http://sourceforge.net/projects/gns-3/files/Empty%20Qemu%20disk/empty30G.qcow2/download"
|
||||
"direct_download_url": "https://sourceforge.net/projects/gns-3/files/Empty%20Qemu%20disk/empty30G.qcow2/download"
|
||||
}
|
||||
|
||||
],
|
||||
|
||||
@@ -3,17 +3,17 @@
|
||||
"category": "multilayer_switch",
|
||||
"status": "stable",
|
||||
"product_name": "ArubaOS-CX Simulation Software",
|
||||
"description": "The ArubaOS-CX Simulation Software OVA is a virtual platform to enable simulation of the ArubaOS-CX Network Operating System. Simulated networks can be created using many of the protocols in the ArubaOS-CX Operating system like OSPF and BGP. Key features like the Aruba Network Analytics Engine and the REST API can be simulated, providing a lightweight development platform to building the modern network. This software can be easily implemented in the GNS3 simulation software to enable drag and drop network design for building complex simulated topologies.",
|
||||
"maintainer_email": "alloytm@gmail.com",
|
||||
"description": "The ArubaOS-CX Simulation Software is a virtual platform to enable simulation of the ArubaOS-CX Network Operating System. Simulated networks can be created using many of the protocols in the ArubaOS-CX Operating system like OSPF, BGP (inc. EVPN). Key features like the Aruba Network Analytics Engine and the REST API can be simulated, providing a lightweight development platform to building the modern network.",
|
||||
"maintainer_email": "vincent.giles@hpe.com",
|
||||
"vendor_url": "arubanetworks.com",
|
||||
"vendor_name": "HPE Aruba",
|
||||
"availability": "service-contract",
|
||||
"maintainer": "Tak Mem Loy",
|
||||
"maintainer": "Aruba",
|
||||
"registry_version": 4,
|
||||
"usage": "Default username admin with blank password.",
|
||||
"usage": "Default username admin has to be set at first login.",
|
||||
"symbol": ":/symbols/route_switch_processor.svg",
|
||||
"first_port_name": "mgmt",
|
||||
"port_name_format": "1/1/{0}",
|
||||
"port_name_format": "1/1/{port1}",
|
||||
|
||||
"qemu": {
|
||||
"arch": "x86_64",
|
||||
@@ -31,6 +31,13 @@
|
||||
},
|
||||
|
||||
"images": [
|
||||
{
|
||||
"filename": "arubaoscx-disk-image-genericx86-p4-20200311173823.vmdk",
|
||||
"version": "10.04.1000",
|
||||
"md5sum": "4e000d73c3593dfed6c49259c31401ea",
|
||||
"filesize": 356249088,
|
||||
"download_url": "https://asp.arubanetworks.com/"
|
||||
},
|
||||
{
|
||||
"filename": "arubaoscx-disk-image-genericx86-p4-20180712161119.vmdk",
|
||||
"version": "10.01.0001",
|
||||
@@ -42,12 +49,17 @@
|
||||
],
|
||||
|
||||
"versions": [
|
||||
{
|
||||
"name": "10.04.1000",
|
||||
"images": {
|
||||
"hda_disk_image": "arubaoscx-disk-image-genericx86-p4-20200311173823.vmdk"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "10.01.0001",
|
||||
"images": {
|
||||
"hda_disk_image": "arubaoscx-disk-image-genericx86-p4-20180712161119.vmdk"
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
]
|
||||
}
|
||||
@@ -70,7 +70,7 @@
|
||||
"md5sum": "3411a599e822f2ac6be560a26405821a",
|
||||
"filesize": 197120,
|
||||
"download_url": "https://sourceforge.net/projects/gns-3/files/Empty%20Qemu%20disk/",
|
||||
"direct_download_url": "http://sourceforge.net/projects/gns-3/files/Empty%20Qemu%20disk/empty30G.qcow2/download"
|
||||
"direct_download_url": "https://sourceforge.net/projects/gns-3/files/Empty%20Qemu%20disk/empty30G.qcow2/download"
|
||||
}
|
||||
],
|
||||
"versions": [
|
||||
|
||||
@@ -22,6 +22,13 @@
|
||||
"kvm": "require"
|
||||
},
|
||||
"images": [
|
||||
{
|
||||
"filename": "csr1000v-universalk9.16.12.03-serial.qcow2",
|
||||
"version": "16.12.3",
|
||||
"md5sum": "1fc380569ad3cc145fb9cbc993b2eb32",
|
||||
"filesize": 986775552,
|
||||
"download_url": "https://software.cisco.com/download/home/284364978/type/282046477/release/Gibraltar-16.12.3"
|
||||
},
|
||||
{
|
||||
"filename": "csr1000v-universalk9.16.12.01a-serial.qcow2",
|
||||
"version": "16.12.1a",
|
||||
@@ -36,6 +43,13 @@
|
||||
"filesize": 950468608,
|
||||
"download_url": "https://software.cisco.com/download/home/284364978/type/282046477/release/Gibraltar-16.10.1b"
|
||||
},
|
||||
{
|
||||
"filename": "csr1000v-universalk9.16.09.05-serial.qcow2",
|
||||
"version": "16.9.5",
|
||||
"md5sum": "7a07a182178243c1c107e68f04ecd8b5",
|
||||
"filesize": 920518656,
|
||||
"download_url": "https://software.cisco.com/download/home/284364978/type/282046477/release/Fuji-16.9.5"
|
||||
},
|
||||
{
|
||||
"filename": "csr1000v-universalk9.16.09.01-serial.qcow2",
|
||||
"version": "16.9.1",
|
||||
@@ -57,12 +71,19 @@
|
||||
"filesize": 884539392,
|
||||
"download_url": "https://software.cisco.com/download/release.html?mdfid=284364978&flowid=39582&softwareid=282046477&release=Fuji-16.7.1"
|
||||
},
|
||||
{
|
||||
"filename": "csr1000v-universalk9.16.06.07-serial.qcow2",
|
||||
"version": "16.6.7",
|
||||
"md5sum": "2aba82d78091b4603224a13710399447",
|
||||
"filesize": 1573322752,
|
||||
"download_url": "https://software.cisco.com/download/release.html?mdfid=284364978&flowid=39582&softwareid=282046477&release=Everest-16.6.7"
|
||||
},
|
||||
{
|
||||
"filename": "csr1000v-universalk9.16.06.06-serial.qcow2",
|
||||
"version": "16.6.6",
|
||||
"md5sum": "31bd32ef6b0d83a8ca19c7b566737a36",
|
||||
"filesize": 1573191680,
|
||||
"download_url": "https://software.cisco.com/download/release.html?mdfid=284364978&flowid=39582&softwareid=282046477&release=Everest-16.6.2"
|
||||
"download_url": "https://software.cisco.com/download/release.html?mdfid=284364978&flowid=39582&softwareid=282046477&release=Everest-16.6.6"
|
||||
},
|
||||
{
|
||||
"filename": "csr1000v-universalk9.16.06.02-serial.qcow2",
|
||||
@@ -90,21 +111,21 @@
|
||||
"version": "16.5.1b",
|
||||
"md5sum": "ac11d33041b8ff6dc3553e324d02cccb",
|
||||
"filesize": 1209543680,
|
||||
"download_url": "https://virl.mediuscorp.com/my-account/"
|
||||
"download_url": "https://learningnetworkstore.cisco.com/myaccount"
|
||||
},
|
||||
{
|
||||
"filename": "csr1000v-universalk9.03.17.00.S.156-1.S-ext.qcow2",
|
||||
"version": "3.17",
|
||||
"md5sum": "06cbfcd11f3557391db64fe2a6015a6e",
|
||||
"filesize": 1346305024,
|
||||
"download_url": "https://virl.mediuscorp.com/my-account/"
|
||||
"download_url": "https://learningnetworkstore.cisco.com/myaccount"
|
||||
},
|
||||
{
|
||||
"filename": "csr1000v-universalk9.16.3.1-build2.qcow2",
|
||||
"version": "16.3.1-build2",
|
||||
"md5sum": "a770e96de928265515304c9c9d6b46b9",
|
||||
"filesize": 1280835584,
|
||||
"download_url": "https://virl.mediuscorp.com/my-account/"
|
||||
"download_url": "https://learningnetworkstore.cisco.com/myaccount"
|
||||
},
|
||||
{
|
||||
"filename": "csr1000v-universalk9.16.03.01.qcow2",
|
||||
@@ -118,7 +139,7 @@
|
||||
"version": "16.3.2",
|
||||
"md5sum": "2e5803d23cd52cba5d55fa8306be5f13",
|
||||
"filesize": 1167720448,
|
||||
"download_url": "https://virl.mediuscorp.com/my-account/"
|
||||
"download_url": "https://learningnetworkstore.cisco.com/myaccount"
|
||||
},
|
||||
{
|
||||
"filename": "csr1000v-universalk9.16.4.1.qcow2",
|
||||
@@ -126,9 +147,22 @@
|
||||
"md5sum": "3428e0dcf5132a1b11ab7696d8c61b2e",
|
||||
"filesize": 1261961216,
|
||||
"download_url": "https://virl.mediuscorp.com/my-account/"
|
||||
},
|
||||
{
|
||||
"filename": "csr1000v-universalk9.16.6.1.qcow2",
|
||||
"version": "16.6.1-VIRL",
|
||||
"md5sum": "996eb6dbf54781f6393bd689571a818c",
|
||||
"filesize": 1316301824,
|
||||
"download_url": "https://learningnetworkstore.cisco.com/myaccount"
|
||||
}
|
||||
],
|
||||
"versions": [
|
||||
{
|
||||
"name": "16.12.3",
|
||||
"images": {
|
||||
"hda_disk_image": "csr1000v-universalk9.16.12.03-serial.qcow2"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "16.12.1a",
|
||||
"images": {
|
||||
@@ -141,6 +175,12 @@
|
||||
"hda_disk_image": "csr1000v-universalk9.16.10.01b-serial.qcow2"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "16.9.5",
|
||||
"images": {
|
||||
"hda_disk_image": "csr1000v-universalk9.16.09.05-serial.qcow2"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "16.9.1",
|
||||
"images": {
|
||||
@@ -159,6 +199,12 @@
|
||||
"hda_disk_image": "csr1000v-universalk9.16.07.01-serial.qcow2"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "16.6.7",
|
||||
"images": {
|
||||
"hda_disk_image": "csr1000v-universalk9.16.06.07-serial.qcow2"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "16.6.6",
|
||||
"images": {
|
||||
@@ -218,6 +264,12 @@
|
||||
"images": {
|
||||
"hda_disk_image": "csr1000v-universalk9.16.4.1.qcow2"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "16.6.1-VIRL",
|
||||
"images": {
|
||||
"hda_disk_image": "csr1000v-universalk9.16.6.1.qcow2"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -52,7 +52,7 @@
|
||||
"md5sum": "1e6409a4523ada212dea2ebc50e50a65",
|
||||
"filesize": 198656,
|
||||
"download_url": "https://sourceforge.net/projects/gns-3/files/Empty%20Qemu%20disk/",
|
||||
"direct_download_url": "http://sourceforge.net/projects/gns-3/files/Empty%20Qemu%20disk/empty100G.qcow2/download"
|
||||
"direct_download_url": "https://sourceforge.net/projects/gns-3/files/Empty%20Qemu%20disk/empty100G.qcow2/download"
|
||||
}
|
||||
],
|
||||
"versions": [
|
||||
|
||||
@@ -48,7 +48,7 @@
|
||||
"md5sum": "d1686d2f25695dee32eab9a6f4652c7c",
|
||||
"filesize": 200192,
|
||||
"download_url": "https://sourceforge.net/projects/gns-3/files/Empty%20Qemu%20disk/",
|
||||
"direct_download_url": "http://sourceforge.net/projects/gns-3/files/Empty%20Qemu%20disk/empty200G.qcow2/download"
|
||||
"direct_download_url": "https://sourceforge.net/projects/gns-3/files/Empty%20Qemu%20disk/empty200G.qcow2/download"
|
||||
}
|
||||
],
|
||||
"versions": [
|
||||
|
||||
@@ -41,7 +41,7 @@
|
||||
"md5sum": "1e6409a4523ada212dea2ebc50e50a65",
|
||||
"filesize": 198656,
|
||||
"download_url": "https://sourceforge.net/projects/gns-3/files/Empty%20Qemu%20disk/",
|
||||
"direct_download_url": "http://sourceforge.net/projects/gns-3/files/Empty%20Qemu%20disk/empty100G.qcow2/download"
|
||||
"direct_download_url": "https://sourceforge.net/projects/gns-3/files/Empty%20Qemu%20disk/empty100G.qcow2/download"
|
||||
}
|
||||
],
|
||||
"versions": [
|
||||
|
||||
@@ -29,35 +29,35 @@
|
||||
"md5sum": "bc605651c4688276f81fd59dcf5cc786",
|
||||
"filesize": 1048576,
|
||||
"download_url": "https://sourceforge.net/projects/gns-3/files",
|
||||
"direct_download_url": "http://sourceforge.net/projects/gns-3/files/Qemu Appliances/IOSv_startup_config.img/download"
|
||||
"direct_download_url": "https://sourceforge.net/projects/gns-3/files/Qemu%20Appliances/IOSv_startup_config.img/download"
|
||||
},
|
||||
{
|
||||
"filename": "vios-adventerprisek9-m.vmdk.SPA.157-3.M3",
|
||||
"version": "15.7(3)M3",
|
||||
"md5sum": "37c148ffa14a82f418a6e9c2b049fafe",
|
||||
"filesize": 134021120,
|
||||
"download_url": "https://virl.mediuscorp.com/my-account/"
|
||||
"download_url": "https://learningnetworkstore.cisco.com/myaccount"
|
||||
},
|
||||
{
|
||||
"filename": "vios-adventerprisek9-m.vmdk.SPA.156-2.T",
|
||||
"version": "15.6(2)T",
|
||||
"md5sum": "83707e3cc93646da58ee6563a68002b5",
|
||||
"filesize": 128450560,
|
||||
"download_url": "https://virl.mediuscorp.com/my-account/"
|
||||
"download_url": "https://learningnetworkstore.cisco.com/myaccount"
|
||||
},
|
||||
{
|
||||
"filename": "vios-adventerprisek9-m.vmdk.SPA.156-1.T",
|
||||
"version": "15.6(1)T",
|
||||
"md5sum": "e7cb1bbd0c59280dd946feefa68fa270",
|
||||
"filesize": 128122880,
|
||||
"download_url": "https://virl.mediuscorp.com/my-account/"
|
||||
"download_url": "https://learningnetworkstore.cisco.com/myaccount"
|
||||
},
|
||||
{
|
||||
"filename": "vios-adventerprisek9-m.vmdk.SPA.155-3.M",
|
||||
"version": "15.5(3)M",
|
||||
"md5sum": "79f613ac3b179d5a64520730925130b2",
|
||||
"filesize": 127926272,
|
||||
"download_url": "https://virl.mediuscorp.com/my-account/"
|
||||
"download_url": "https://learningnetworkstore.cisco.com/myaccount"
|
||||
}
|
||||
],
|
||||
"versions": [
|
||||
|
||||
@@ -28,21 +28,21 @@
|
||||
"version": "15.2.1",
|
||||
"md5sum": "14b981002e40b660f2d7400401e04c14",
|
||||
"filesize": 44938752,
|
||||
"download_url": "https://virl.mediuscorp.com/my-account/"
|
||||
"download_url": "https://learningnetworkstore.cisco.com/myaccount"
|
||||
},
|
||||
{
|
||||
"filename": "vios_l2-adventerprisek9-m.03.2017.qcow2",
|
||||
"version": "15.2(20170321:233949)",
|
||||
"md5sum": "8f14b50083a14688dec2fc791706bb3e",
|
||||
"filesize": 41157632,
|
||||
"download_url": "https://virl.mediuscorp.com/my-account/"
|
||||
"download_url": "https://learningnetworkstore.cisco.com/myaccount"
|
||||
},
|
||||
{
|
||||
"filename": "vios_l2-adventerprisek9-m.vmdk.SSA.152-4.0.55.E",
|
||||
"version": "15.2(4.0.55)E",
|
||||
"md5sum": "1a3a21f5697cae64bb930895b986d71e",
|
||||
"filesize": 96862208,
|
||||
"download_url": "https://virl.mediuscorp.com/my-account/"
|
||||
"download_url": "https://learningnetworkstore.cisco.com/myaccount"
|
||||
}
|
||||
],
|
||||
"versions": [
|
||||
|
||||
@@ -28,14 +28,14 @@
|
||||
"version": "6.1.3",
|
||||
"md5sum": "1693b5d22a398587dd0fed2877d8dfac",
|
||||
"filesize": 428588544,
|
||||
"download_url": "https://virl.mediuscorp.com/my-account/"
|
||||
"download_url": "https://learningnetworkstore.cisco.com/myaccount"
|
||||
},
|
||||
{
|
||||
"filename": "iosxrv-k9-demo-6.0.1.qcow2",
|
||||
"version": "6.0.1",
|
||||
"md5sum": "0831ecf43628eccb752ebb275de9a62a",
|
||||
"filesize": 908132352,
|
||||
"download_url": "https://virl.mediuscorp.com/my-account/"
|
||||
"download_url": "https://learningnetworkstore.cisco.com/myaccount"
|
||||
}
|
||||
],
|
||||
"versions": [
|
||||
|
||||
@@ -77,21 +77,21 @@
|
||||
"version": "6.2.25",
|
||||
"md5sum": "3f54e62b6f7cedfb2607233e5e465766",
|
||||
"filesize": 1190723584,
|
||||
"download_url": "https://virl.mediuscorp.com/my-account/"
|
||||
"download_url": "https://learningnetworkstore.cisco.com/myaccount"
|
||||
},
|
||||
{
|
||||
"filename": "xrv9k-fullk9-x.qcow2-6.0.1",
|
||||
"version": "6.0.1",
|
||||
"md5sum": "e20d046807075046c35b6ce7d6766a7f",
|
||||
"filesize": 2109210624,
|
||||
"download_url": "https://virl.mediuscorp.com/my-account/"
|
||||
"download_url": "https://learningnetworkstore.cisco.com/myaccount"
|
||||
},
|
||||
{
|
||||
"filename": "xrv9k-fullk9-x.qcow2-6.0.0",
|
||||
"version": "6.0.0",
|
||||
"md5sum": "64c538c34252aaeb4ed1ddb93d6803fd",
|
||||
"filesize": 2572943360,
|
||||
"download_url": "https://virl.mediuscorp.com/my-account/"
|
||||
"download_url": "https://learningnetworkstore.cisco.com/myaccount"
|
||||
}
|
||||
],
|
||||
"versions": [
|
||||
|
||||
@@ -89,7 +89,7 @@
|
||||
"md5sum": "d1686d2f25695dee32eab9a6f4652c7c",
|
||||
"filesize": 200192,
|
||||
"download_url": "https://sourceforge.net/projects/gns-3/files/Empty%20Qemu%20disk/",
|
||||
"direct_download_url": "http://sourceforge.net/projects/gns-3/files/Empty%20Qemu%20disk/empty200G.qcow2/download"
|
||||
"direct_download_url": "https://sourceforge.net/projects/gns-3/files/Empty%20Qemu%20disk/empty200G.qcow2/download"
|
||||
}
|
||||
],
|
||||
"versions": [
|
||||
|
||||
@@ -27,14 +27,14 @@
|
||||
"version": "7.3.0",
|
||||
"md5sum": "b4cd6edf15ab4c6bce53c3f6c1e3a742",
|
||||
"filesize": 214368256,
|
||||
"download_url": "https://virl.mediuscorp.com/my-account/"
|
||||
"download_url": "https://learningnetworkstore.cisco.com/myaccount"
|
||||
},
|
||||
{
|
||||
"filename": "titanium-d1.7.2.0.D1.1.vmdk",
|
||||
"version": "7.2.0",
|
||||
"md5sum": "0ee38c7d717840cb4ca822f4870671d0",
|
||||
"filesize": 361103360,
|
||||
"download_url": "https://virl.mediuscorp.com/my-account/"
|
||||
"download_url": "https://learningnetworkstore.cisco.com/myaccount"
|
||||
}
|
||||
],
|
||||
"versions": [
|
||||
|
||||
@@ -48,7 +48,7 @@
|
||||
"md5sum": "d1686d2f25695dee32eab9a6f4652c7c",
|
||||
"filesize": 200192,
|
||||
"download_url": "https://sourceforge.net/projects/gns-3/files/Empty%20Qemu%20disk/",
|
||||
"direct_download_url": "http://sourceforge.net/projects/gns-3/files/Empty%20Qemu%20disk/empty200G.qcow2/download"
|
||||
"direct_download_url": "https://sourceforge.net/projects/gns-3/files/Empty%20Qemu%20disk/empty200G.qcow2/download"
|
||||
}
|
||||
],
|
||||
"versions": [
|
||||
|
||||
@@ -68,7 +68,7 @@
|
||||
"md5sum": "f1d2c25b6990f99bd05b433ab603bdb4",
|
||||
"filesize": 197120,
|
||||
"download_url": "https://sourceforge.net/projects/gns-3/files/Empty%20Qemu%20disk/",
|
||||
"direct_download_url": "http://sourceforge.net/projects/gns-3/files/Empty%20Qemu%20disk/empty8G.qcow2/download"
|
||||
"direct_download_url": "https://sourceforge.net/projects/gns-3/files/Empty%20Qemu%20disk/empty8G.qcow2/download"
|
||||
}
|
||||
],
|
||||
"versions": [
|
||||
|
||||
@@ -63,7 +63,7 @@
|
||||
"md5sum": "3411a599e822f2ac6be560a26405821a",
|
||||
"filesize": 197120,
|
||||
"download_url": "https://sourceforge.net/projects/gns-3/files/Empty%20Qemu%20disk/",
|
||||
"direct_download_url": "http://sourceforge.net/projects/gns-3/files/Empty%20Qemu%20disk/empty30G.qcow2/download"
|
||||
"direct_download_url": "https://sourceforge.net/projects/gns-3/files/Empty%20Qemu%20disk/empty30G.qcow2/download"
|
||||
}
|
||||
],
|
||||
"versions": [
|
||||
|
||||
@@ -59,7 +59,7 @@
|
||||
"md5sum": "3411a599e822f2ac6be560a26405821a",
|
||||
"filesize": 197120,
|
||||
"download_url": "https://sourceforge.net/projects/gns-3/files/Empty%20Qemu%20disk/",
|
||||
"direct_download_url": "http://sourceforge.net/projects/gns-3/files/Empty%20Qemu%20disk/empty30G.qcow2/download"
|
||||
"direct_download_url": "https://sourceforge.net/projects/gns-3/files/Empty%20Qemu%20disk/empty30G.qcow2/download"
|
||||
}
|
||||
],
|
||||
"versions": [
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
"md5sum": "3411a599e822f2ac6be560a26405821a",
|
||||
"filesize": 197120,
|
||||
"download_url": "https://sourceforge.net/projects/gns-3/files/Empty%20Qemu%20disk/",
|
||||
"direct_download_url": "http://sourceforge.net/projects/gns-3/files/Empty%20Qemu%20disk/empty30G.qcow2/download"
|
||||
"direct_download_url": "https://sourceforge.net/projects/gns-3/files/Empty%20Qemu%20disk/empty30G.qcow2/download"
|
||||
}
|
||||
],
|
||||
"versions": [
|
||||
|
||||
@@ -27,12 +27,33 @@
|
||||
"options": "-smp 2 -cpu host"
|
||||
},
|
||||
"images": [
|
||||
{
|
||||
"filename": "BIGIP-15.1.0.2-0.0.9.qcow2",
|
||||
"version": "15.1.0.2",
|
||||
"md5sum": "95ff618b7d0b53c4252299cd49b0e564",
|
||||
"filesize": 5236588544,
|
||||
"download_url": "https://downloads.f5.com/esd/serveDownload.jsp?path=/big-ip/big-ip_v15.x/15.1.0/english/15.1.0.2_virtual-edition/&sw=BIG-IP&pro=big-ip_v15.x&ver=15.1.0&container=15.1.0.2_Virtual-Edition&file=BIGIP-15.1.0.2-0.0.9.ALL.qcow2.zip"
|
||||
},
|
||||
{
|
||||
"filename": "BIGIP-15.0.1.3-0.0.4.qcow2",
|
||||
"version": "15.0.1.3",
|
||||
"md5sum": "9caf1fb3e373ab37b9d489c038ff1908",
|
||||
"filesize": 5236588544,
|
||||
"download_url": "https://downloads.f5.com/esd/serveDownload.jsp?path=/big-ip/big-ip_v15.x/15.0.1/english/15.0.1.3_virtual-edition/&sw=BIG-IP&pro=big-ip_v15.x&ver=15.0.1&container=15.0.1.3_Virtual-Edition&file=BIGIP-15.0.1.3-0.0.4.ALL.qcow2.zip"
|
||||
},
|
||||
{
|
||||
"filename": "BIGIP-15.0.0-0.0.39.qcow2",
|
||||
"version": "15.0.0",
|
||||
"md5sum": "978ede3addc717ff853e9d05dc0e9289",
|
||||
"filesize": 5251923968,
|
||||
"download_url": "https://downloads.f5.com/esd/serveDownload.jsp?path=/big-ip/big-ip_v15.x/15.0.0/english/virtual-edition/&sw=BIG-IP&pro=big-ip_v15.x&ver=15.0.0&container=Virtual-Edition&file=BIGIP-15.0.0-0.0.39.ALL.qcow2.zip"
|
||||
},
|
||||
{
|
||||
"filename": "BIGIP-14.1.2.3-0.0.5.qcow2",
|
||||
"version": "14.1.2.3",
|
||||
"md5sum": "356520eedb615c93e985474f2b2ec603",
|
||||
"filesize": 5036834816,
|
||||
"download_url": "https://downloads.f5.com"
|
||||
"md5sum": "a16fbbd264605460cf254d0f0fb7faad",
|
||||
"filesize": 5110169600,
|
||||
"download_url": "https://downloads.f5.com/esd/serveDownload.jsp?path=/big-ip/big-ip_v14.x/14.1.2/english/14.1.2.3_virtual-edition/&sw=BIG-IP&pro=big-ip_v14.x&ver=14.1.2&container=14.1.2.3_Virtual-Edition&file=BIGIP-14.1.2.3-0.0.5.ALL.qcow2.zip"
|
||||
},
|
||||
{
|
||||
"filename": "BIGIP-14.0.0.3-0.0.4.qcow2",
|
||||
@@ -132,23 +153,37 @@
|
||||
"filesize": 2851733504,
|
||||
"download_url": "https://downloads.f5.com/esd/serveDownload.jsp?path=/big-ip/big-ip_v11.x/11.6.0/english/virtual-edition/&sw=BIG-IP&pro=big-ip_v11.x&ver=11.6.0&container=Virtual-Edition&file=BIGIP-11.6.0.0.0.401.ALL.qcow2.zip"
|
||||
},
|
||||
{
|
||||
"filename": "BIGIP-11.3.0.39.0.qcow2",
|
||||
"version": "11.3.0",
|
||||
"md5sum": "f3dec4565484fe81233077ab2ce426ae",
|
||||
"filesize": 1842020352,
|
||||
"download_url": "https://downloads.f5.com/esd/serveDownload.jsp?path=/big-ip/big-ip_v11.x/11.3.0/english/virtual-edition-trial/&sw=BIG-IP&pro=big-ip_v11.x&ver=11.3.0&container=Virtual-Edition-Trial&file=BIGIP-11.3.0.39.0.qcow2.zip"
|
||||
},
|
||||
{
|
||||
"filename": "empty100G.qcow2",
|
||||
"version": "1.0",
|
||||
"md5sum": "1e6409a4523ada212dea2ebc50e50a65",
|
||||
"filesize": 198656,
|
||||
"download_url": "https://sourceforge.net/projects/gns-3/files/Empty%20Qemu%20disk/",
|
||||
"direct_download_url": "http://sourceforge.net/projects/gns-3/files/Empty%20Qemu%20disk/empty100G.qcow2/download"
|
||||
"direct_download_url": "https://sourceforge.net/projects/gns-3/files/Empty%20Qemu%20disk/empty100G.qcow2/download"
|
||||
}
|
||||
],
|
||||
"versions": [
|
||||
{
|
||||
"name": "15.1.0.2",
|
||||
"images": {
|
||||
"hda_disk_image": "BIGIP-15.1.0.2-0.0.9.qcow2",
|
||||
"hdb_disk_image": "empty100G.qcow2"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "15.0.1.3",
|
||||
"images": {
|
||||
"hda_disk_image": "BIGIP-15.0.1.3-0.0.4.qcow2",
|
||||
"hdb_disk_image": "empty100G.qcow2"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "15.0.0",
|
||||
"images": {
|
||||
"hda_disk_image": "BIGIP-15.0.0-0.0.39.qcow2",
|
||||
"hdb_disk_image": "empty100G.qcow2"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "14.1.2.3",
|
||||
"images": {
|
||||
@@ -253,13 +288,6 @@
|
||||
"hda_disk_image": "BIGIP-11.6.0.0.0.401.qcow2",
|
||||
"hdb_disk_image": "empty100G.qcow2"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "11.3.0",
|
||||
"images": {
|
||||
"hda_disk_image": "BIGIP-11.3.0.39.0.qcow2",
|
||||
"hdb_disk_image": "empty100G.qcow2"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -30,11 +30,18 @@
|
||||
},
|
||||
"images": [
|
||||
{
|
||||
"filename": "BIG-IQ-7.0.0.0.0.1854.qcow2",
|
||||
"version": "7.0.0.0",
|
||||
"md5sum": "89ff128c4ba82c266a6cefa21c80029b",
|
||||
"filesize": 4312006656,
|
||||
"download_url": "https://downloads.f5.com/esd/serveDownload.jsp?path=/big-iq/big-iq_cm/7.0.0/english/v7.0.0/&sw=BIG-IQ&pro=big-iq_CM&ver=7.0.0&container=v7.0.0&file=BIG-IQ-7.0.0.0.0.1854.qcow2.zip"
|
||||
"filename": "BIG-IQ-7.1.0.0.0.1511.qcow2",
|
||||
"version": "7.1.0.0",
|
||||
"md5sum": "8d93b06e6eec656584a73ad16be6efa3",
|
||||
"filesize": 4567072768,
|
||||
"download_url": "https://downloads.f5.com/esd/serveDownload.jsp?path=/big-iq/big-iq_cm/7.1.0/english/v7.1.0/&sw=BIG-IQ&pro=big-iq_CM&ver=7.1.0&container=v7.1.0&file=BIG-IQ-7.1.0.0.0.1511.qcow2.zip"
|
||||
},
|
||||
{
|
||||
"filename": "BIG-IQ-7.0.0.1.0.0.6.qcow2",
|
||||
"version": "7.0.0.1",
|
||||
"md5sum": "e86c851a1c43c8c0743f32742d97eba2",
|
||||
"filesize": 4294246400,
|
||||
"download_url": "https://downloads.f5.com/esd/serveDownload.jsp?path=/big-iq/big-iq_cm/7.0.0/english/v7.0.0.1/&sw=BIG-IQ&pro=big-iq_CM&ver=7.0.0&container=v7.0.0.1&file=BIG-IQ-7.0.0.1.0.0.6.qcow2.zip"
|
||||
},
|
||||
{
|
||||
"filename": "BIG-IQ-6.0.1.1.0.0.9.qcow2",
|
||||
@@ -50,13 +57,6 @@
|
||||
"filesize": 3480748032,
|
||||
"download_url": "https://downloads.f5.com/esd/serveDownload.jsp?path=/big-iq/big-iq_cm/5.4.0/english/virtual-edition_base-plus-hf2/&sw=BIG-IQ&pro=big-iq_CM&ver=5.4.0&container=Virtual-Edition_Base-Plus-HF2&file=BIG-IQ-5.4.0.2.24.7467.qcow2.zip"
|
||||
},
|
||||
{
|
||||
"filename": "BIG-IQ-5.4.0.0.0.7437.qcow2",
|
||||
"version": "5.4.0",
|
||||
"md5sum": "068b1f4d21048b9b2a082c0c27ef4d53",
|
||||
"filesize": 3300917248,
|
||||
"download_url": "https://downloads.f5.com/esd/serveDownload.jsp?path=/big-iq/big-iq_cm/5.4.0/english/v5.4.0/&sw=BIG-IQ&pro=big-iq_CM&ver=5.4.0&container=v5.4.0&file=BIG-IQ-5.4.0.0.0.7437.qcow2.zip"
|
||||
},
|
||||
{
|
||||
"filename": "BIG-IQ-5.3.0.0.0.1119.qcow2",
|
||||
"version": "5.3.0",
|
||||
@@ -98,14 +98,21 @@
|
||||
"md5sum": "1e6409a4523ada212dea2ebc50e50a65",
|
||||
"filesize": 198656,
|
||||
"download_url": "https://sourceforge.net/projects/gns-3/files/Empty%20Qemu%20disk/",
|
||||
"direct_download_url": "http://sourceforge.net/projects/gns-3/files/Empty%20Qemu%20disk/empty100G.qcow2/download"
|
||||
"direct_download_url": "https://sourceforge.net/projects/gns-3/files/Empty%20Qemu%20disk/empty100G.qcow2/download"
|
||||
}
|
||||
],
|
||||
"versions": [
|
||||
{
|
||||
"name": "7.0.0.0",
|
||||
"name": "7.1.0.0",
|
||||
"images": {
|
||||
"hda_disk_image": "BIG-IQ-7.0.0.0.0.1854.qcow2",
|
||||
"hda_disk_image": "BIG-IQ-7.1.0.0.0.1511.qcow2",
|
||||
"hdb_disk_image": "empty100G.qcow2"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "7.0.0.1",
|
||||
"images": {
|
||||
"hda_disk_image": "BIG-IQ-7.0.0.1.0.0.6.qcow2",
|
||||
"hdb_disk_image": "empty100G.qcow2"
|
||||
}
|
||||
},
|
||||
@@ -123,13 +130,6 @@
|
||||
"hdb_disk_image": "empty100G.qcow2"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "5.4.0",
|
||||
"images": {
|
||||
"hda_disk_image": "BIG-IQ-5.4.0.0.0.7437.qcow2",
|
||||
"hdb_disk_image": "empty100G.qcow2"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "5.3.0",
|
||||
"images": {
|
||||
|
||||
@@ -165,7 +165,7 @@
|
||||
"md5sum": "3411a599e822f2ac6be560a26405821a",
|
||||
"filesize": 197120,
|
||||
"download_url": "https://sourceforge.net/projects/gns-3/files/Empty%20Qemu%20disk/",
|
||||
"direct_download_url": "http://sourceforge.net/projects/gns-3/files/Empty%20Qemu%20disk/empty30G.qcow2/download"
|
||||
"direct_download_url": "https://sourceforge.net/projects/gns-3/files/Empty%20Qemu%20disk/empty30G.qcow2/download"
|
||||
}
|
||||
],
|
||||
"versions": [
|
||||
|
||||
@@ -116,7 +116,7 @@
|
||||
"md5sum": "1e6409a4523ada212dea2ebc50e50a65",
|
||||
"filesize": 198656,
|
||||
"download_url": "https://sourceforge.net/projects/gns-3/files/Empty%20Qemu%20disk/",
|
||||
"direct_download_url": "http://sourceforge.net/projects/gns-3/files/Empty%20Qemu%20disk/empty100G.qcow2/download"
|
||||
"direct_download_url": "https://sourceforge.net/projects/gns-3/files/Empty%20Qemu%20disk/empty100G.qcow2/download"
|
||||
}
|
||||
],
|
||||
"versions": [
|
||||
|
||||
@@ -240,7 +240,7 @@
|
||||
"md5sum": "3411a599e822f2ac6be560a26405821a",
|
||||
"filesize": 197120,
|
||||
"download_url": "https://sourceforge.net/projects/gns-3/files/Empty%20Qemu%20disk/",
|
||||
"direct_download_url": "http://sourceforge.net/projects/gns-3/files/Empty%20Qemu%20disk/empty30G.qcow2/download"
|
||||
"direct_download_url": "https://sourceforge.net/projects/gns-3/files/Empty%20Qemu%20disk/empty30G.qcow2/download"
|
||||
}
|
||||
],
|
||||
"versions": [
|
||||
|
||||
@@ -179,7 +179,7 @@
|
||||
"md5sum": "3411a599e822f2ac6be560a26405821a",
|
||||
"filesize": 197120,
|
||||
"download_url": "https://sourceforge.net/projects/gns-3/files/Empty%20Qemu%20disk/",
|
||||
"direct_download_url": "http://sourceforge.net/projects/gns-3/files/Empty%20Qemu%20disk/empty30G.qcow2/download"
|
||||
"direct_download_url": "https://sourceforge.net/projects/gns-3/files/Empty%20Qemu%20disk/empty30G.qcow2/download"
|
||||
}
|
||||
],
|
||||
"versions": [
|
||||
|
||||
@@ -158,7 +158,7 @@
|
||||
"md5sum": "3411a599e822f2ac6be560a26405821a",
|
||||
"filesize": 197120,
|
||||
"download_url": "https://sourceforge.net/projects/gns-3/files/Empty%20Qemu%20disk/",
|
||||
"direct_download_url": "http://sourceforge.net/projects/gns-3/files/Empty%20Qemu%20disk/empty30G.qcow2/download"
|
||||
"direct_download_url": "https://sourceforge.net/projects/gns-3/files/Empty%20Qemu%20disk/empty30G.qcow2/download"
|
||||
}
|
||||
],
|
||||
"versions": [
|
||||
|
||||
@@ -46,7 +46,7 @@
|
||||
"md5sum": "3411a599e822f2ac6be560a26405821a",
|
||||
"filesize": 197120,
|
||||
"download_url": "https://sourceforge.net/projects/gns-3/files/Empty%20Qemu%20disk/",
|
||||
"direct_download_url": "http://sourceforge.net/projects/gns-3/files/Empty%20Qemu%20disk/empty30G.qcow2/download"
|
||||
"direct_download_url": "https://sourceforge.net/projects/gns-3/files/Empty%20Qemu%20disk/empty30G.qcow2/download"
|
||||
}
|
||||
],
|
||||
"versions": [
|
||||
|
||||
@@ -46,7 +46,7 @@
|
||||
"md5sum": "3411a599e822f2ac6be560a26405821a",
|
||||
"filesize": 197120,
|
||||
"download_url": "https://sourceforge.net/projects/gns-3/files/Empty%20Qemu%20disk/",
|
||||
"direct_download_url": "http://sourceforge.net/projects/gns-3/files/Empty%20Qemu%20disk/empty30G.qcow2/download"
|
||||
"direct_download_url": "https://sourceforge.net/projects/gns-3/files/Empty%20Qemu%20disk/empty30G.qcow2/download"
|
||||
}
|
||||
],
|
||||
"versions": [
|
||||
|
||||
@@ -116,7 +116,7 @@
|
||||
"md5sum": "3411a599e822f2ac6be560a26405821a",
|
||||
"filesize": 197120,
|
||||
"download_url": "https://sourceforge.net/projects/gns-3/files/Empty%20Qemu%20disk/",
|
||||
"direct_download_url": "http://sourceforge.net/projects/gns-3/files/Empty%20Qemu%20disk/empty30G.qcow2/download"
|
||||
"direct_download_url": "https://sourceforge.net/projects/gns-3/files/Empty%20Qemu%20disk/empty30G.qcow2/download"
|
||||
}
|
||||
|
||||
],
|
||||
|
||||
@@ -102,7 +102,7 @@
|
||||
"md5sum": "3411a599e822f2ac6be560a26405821a",
|
||||
"filesize": 197120,
|
||||
"download_url": "https://sourceforge.net/projects/gns-3/files/Empty%20Qemu%20disk/",
|
||||
"direct_download_url": "http://sourceforge.net/projects/gns-3/files/Empty%20Qemu%20disk/empty30G.qcow2/download"
|
||||
"direct_download_url": "https://sourceforge.net/projects/gns-3/files/Empty%20Qemu%20disk/empty30G.qcow2/download"
|
||||
}
|
||||
],
|
||||
"versions": [
|
||||
|
||||
@@ -12,6 +12,6 @@
|
||||
"maintainer_email": "developers@gns3.net",
|
||||
"docker": {
|
||||
"adapters": 2,
|
||||
"image": "gns3/kalilinux:v2"
|
||||
"image": "gns3/kalilinux:latest"
|
||||
}
|
||||
}
|
||||
@@ -29,7 +29,7 @@
|
||||
"md5sum": "88d6129265860aa58c5306cd7b413aab",
|
||||
"filesize": 3968729088,
|
||||
"download_url": "http://www.opennac.org/opennac/en/download.html",
|
||||
"direct_download_url": "http://sourceforge.net/projects/opennac/files/ova/opennac_3711_img.ova/download"
|
||||
"direct_download_url": "https://sourceforge.net/projects/opennac/files/ova/opennac_3711_img.ova/download"
|
||||
}
|
||||
],
|
||||
"versions": [
|
||||
|
||||
@@ -21,6 +21,24 @@
|
||||
"kvm": "allow"
|
||||
},
|
||||
"images": [
|
||||
{
|
||||
"filename": "openwrt-19.07.2-x86-64-combined-ext4.img",
|
||||
"version": "19.07.2",
|
||||
"md5sum": "333e06eb0f767efda56a35644ace47c0",
|
||||
"filesize": 285736960,
|
||||
"download_url": "https://downloads.openwrt.org/releases/19.07.2/targets/x86/64/",
|
||||
"direct_download_url": "https://downloads.openwrt.org/releases/19.07.2/targets/x86/64/openwrt-19.07.2-x86-64-combined-ext4.img.gz",
|
||||
"compression": "gzip"
|
||||
},
|
||||
{
|
||||
"filename": "openwrt-18.06.8-x86-64-combined-ext4.img",
|
||||
"version": "18.06.8",
|
||||
"md5sum": "8b235443df9d1a236b147c1c29a97083",
|
||||
"filesize": 285736960,
|
||||
"download_url": "https://downloads.openwrt.org/releases/18.06.8/targets/x86/64/",
|
||||
"direct_download_url": "https://downloads.openwrt.org/releases/18.06.8/targets/x86/64/openwrt-18.06.8-x86-64-combined-ext4.img.gz",
|
||||
"compression": "gzip"
|
||||
},
|
||||
{
|
||||
"filename": "openwrt-19.07.1-x86-64-combined-ext4.img",
|
||||
"version": "19.07.1",
|
||||
@@ -104,6 +122,18 @@
|
||||
}
|
||||
],
|
||||
"versions": [
|
||||
{
|
||||
"name": "19.07.2",
|
||||
"images": {
|
||||
"hda_disk_image": "openwrt-19.07.2-x86-64-combined-ext4.img"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "18.06.8",
|
||||
"images": {
|
||||
"hda_disk_image": "openwrt-18.06.8-x86-64-combined-ext4.img"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "19.07.1",
|
||||
"images": {
|
||||
|
||||
@@ -74,7 +74,7 @@
|
||||
"md5sum": "dfeb8a97bba2e475ce418b02327c0ea1",
|
||||
"filesize": 3221225472,
|
||||
"download_url": "https://packetfence.org/download.html#/zen",
|
||||
"direct_download_url": "http://sourceforge.net/projects/packetfence/files/PacketFence%20ZEN/7.3.0/PacketFenceZEN_USB-7.3.0.tar.bz2/download",
|
||||
"direct_download_url": "https://sourceforge.net/projects/packetfence/files/PacketFence%20ZEN/7.3.0/PacketFenceZEN_USB-7.3.0.tar.bz2/download",
|
||||
"compression": "bzip2"
|
||||
},
|
||||
{
|
||||
|
||||
@@ -44,7 +44,7 @@
|
||||
"md5sum": "3411a599e822f2ac6be560a26405821a",
|
||||
"filesize": 197120,
|
||||
"download_url": "https://sourceforge.net/projects/gns-3/files/Empty%20Qemu%30disk/",
|
||||
"direct_download_url": "http://sourceforge.net/projects/gns-3/files/Empty%20Qemu%20disk/empty30G.qcow2/download"
|
||||
"direct_download_url": "https://sourceforge.net/projects/gns-3/files/Empty%20Qemu%20disk/empty30G.qcow2/download"
|
||||
}
|
||||
|
||||
],
|
||||
|
||||
@@ -46,7 +46,7 @@
|
||||
"md5sum": "3411a599e822f2ac6be560a26405821a",
|
||||
"filesize": 197120,
|
||||
"download_url": "https://sourceforge.net/projects/gns-3/files/Empty%20Qemu%20disk/",
|
||||
"direct_download_url": "http://sourceforge.net/projects/gns-3/files/Empty%20Qemu%20disk/empty30G.qcow2/download"
|
||||
"direct_download_url": "https://sourceforge.net/projects/gns-3/files/Empty%20Qemu%20disk/empty30G.qcow2/download"
|
||||
}
|
||||
],
|
||||
"versions": [
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
"md5sum": "1e6409a4523ada212dea2ebc50e50a65",
|
||||
"filesize": 198656,
|
||||
"download_url": "https://sourceforge.net/projects/gns-3/files/Empty%20Qemu%20disk/",
|
||||
"direct_download_url": "http://sourceforge.net/projects/gns-3/files/Empty%20Qemu%20disk/empty100G.qcow2/download"
|
||||
"direct_download_url": "https://sourceforge.net/projects/gns-3/files/Empty%20Qemu%20disk/empty100G.qcow2/download"
|
||||
}
|
||||
],
|
||||
"versions": [
|
||||
|
||||
@@ -60,7 +60,7 @@
|
||||
"md5sum": "3411a599e822f2ac6be560a26405821a",
|
||||
"filesize": 197120,
|
||||
"download_url": "https://sourceforge.net/projects/gns-3/files/Empty%20Qemu%30disk/",
|
||||
"direct_download_url": "http://sourceforge.net/projects/gns-3/files/Empty%20Qemu%20disk/empty30G.qcow2/download"
|
||||
"direct_download_url": "https://sourceforge.net/projects/gns-3/files/Empty%20Qemu%20disk/empty30G.qcow2/download"
|
||||
}
|
||||
|
||||
],
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
"md5sum": "cfaf7f11901a164cd00c07518c7311ba",
|
||||
"filesize": 214206464,
|
||||
"download_url": "http://www.smoothwall.org/download/",
|
||||
"direct_download_url": "http://sourceforge.net/projects/smoothwall/files/SmoothWall/3.1/Express-3.1-x86_64.iso/download"
|
||||
"direct_download_url": "https://sourceforge.net/projects/smoothwall/files/SmoothWall/3.1/Express-3.1-x86_64.iso/download"
|
||||
},
|
||||
{
|
||||
"filename": "empty8G.qcow2",
|
||||
|
||||
@@ -142,7 +142,7 @@
|
||||
"md5sum": "3411a599e822f2ac6be560a26405821a",
|
||||
"filesize": 197120,
|
||||
"download_url": "https://sourceforge.net/projects/gns-3/files/Empty%20Qemu%20disk/",
|
||||
"direct_download_url": "http://sourceforge.net/projects/gns-3/files/Empty%20Qemu%20disk/empty30G.qcow2/download"
|
||||
"direct_download_url": "https://sourceforge.net/projects/gns-3/files/Empty%20Qemu%20disk/empty30G.qcow2/download"
|
||||
}
|
||||
],
|
||||
"versions": [
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
"md5sum": "1e6409a4523ada212dea2ebc50e50a65",
|
||||
"filesize": 198656,
|
||||
"download_url": "https://sourceforge.net/projects/gns-3/files/Empty%20Qemu%20disk/",
|
||||
"direct_download_url": "http://sourceforge.net/projects/gns-3/files/Empty%20Qemu%20disk/empty100G.qcow2/download"
|
||||
"direct_download_url": "https://sourceforge.net/projects/gns-3/files/Empty%20Qemu%20disk/empty100G.qcow2/download"
|
||||
}
|
||||
],
|
||||
"versions": [
|
||||
|
||||
@@ -114,7 +114,7 @@
|
||||
"md5sum": "3411a599e822f2ac6be560a26405821a",
|
||||
"filesize": 197120,
|
||||
"download_url": "https://sourceforge.net/projects/gns-3/files/Empty%20Qemu%20disk/",
|
||||
"direct_download_url": "http://sourceforge.net/projects/gns-3/files/Empty%20Qemu%20disk/empty30G.qcow2/download"
|
||||
"direct_download_url": "https://sourceforge.net/projects/gns-3/files/Empty%20Qemu%20disk/empty30G.qcow2/download"
|
||||
}
|
||||
],
|
||||
"versions": [
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
"md5sum": "3411a599e822f2ac6be560a26405821a",
|
||||
"filesize": 197120,
|
||||
"download_url": "https://sourceforge.net/projects/gns-3/files/Empty%20Qemu%20disk/",
|
||||
"direct_download_url": "http://sourceforge.net/projects/gns-3/files/Empty%20Qemu%20disk/empty30G.qcow2/download"
|
||||
"direct_download_url": "https://sourceforge.net/projects/gns-3/files/Empty%20Qemu%20disk/empty30G.qcow2/download"
|
||||
}
|
||||
],
|
||||
"versions": [
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
"md5sum": "40afad2f5136e56f0cb45466847eae63",
|
||||
"filesize": 957087744,
|
||||
"download_url": "https://sourceforge.net/projects/vrin/files",
|
||||
"direct_download_url": "http://sourceforge.net/projects/vrin/files/vRIN-0.9.2.qcow2.bz2/download",
|
||||
"direct_download_url": "https://sourceforge.net/projects/vrin/files/vRIN-0.9.2.qcow2.bz2/download",
|
||||
"compression": "bzip2"
|
||||
},
|
||||
{
|
||||
@@ -35,7 +35,7 @@
|
||||
"md5sum": "9f09f104917e19649598d9e2a5a3476b",
|
||||
"filesize": 1008926720,
|
||||
"download_url": "https://sourceforge.net/projects/vrin/files",
|
||||
"direct_download_url": "http://sourceforge.net/projects/vrin/files/vRIN-0.9.1.qcow2.bz2/download",
|
||||
"direct_download_url": "https://sourceforge.net/projects/vrin/files/vRIN-0.9.1.qcow2.bz2/download",
|
||||
"compression": "bzip2"
|
||||
},
|
||||
{
|
||||
@@ -44,7 +44,7 @@
|
||||
"md5sum": "b9ec187d7a4743bb02339cf262767959",
|
||||
"filesize": 922943488,
|
||||
"download_url": "https://sourceforge.net/projects/vrin/files",
|
||||
"direct_download_url": "http://sourceforge.net/projects/vrin/files/vRIN-0.9.qcow2.bz2/download",
|
||||
"direct_download_url": "https://sourceforge.net/projects/vrin/files/vRIN-0.9.qcow2.bz2/download",
|
||||
"compression": "bzip2"
|
||||
},
|
||||
{
|
||||
@@ -53,7 +53,7 @@
|
||||
"md5sum": "38eb48d098d3e465422347f7983b9d86",
|
||||
"filesize": 625999872,
|
||||
"download_url": "https://sourceforge.net/projects/vrin/files",
|
||||
"direct_download_url": "http://sourceforge.net/projects/vrin/files/vRIN-0.8.qcow2.bz2/download",
|
||||
"direct_download_url": "https://sourceforge.net/projects/vrin/files/vRIN-0.8.qcow2.bz2/download",
|
||||
"compression": "bzip2"
|
||||
},
|
||||
{
|
||||
@@ -62,7 +62,7 @@
|
||||
"md5sum": "2e9802c403e34a91871922b9a26592ad",
|
||||
"filesize": 614268928,
|
||||
"download_url": "https://sourceforge.net/projects/vrin/files",
|
||||
"direct_download_url": "http://sourceforge.net/projects/vrin/files/vRIN-0.7.qcow2.bz2/download",
|
||||
"direct_download_url": "https://sourceforge.net/projects/vrin/files/vRIN-0.7.qcow2.bz2/download",
|
||||
"compression": "bzip2"
|
||||
},
|
||||
{
|
||||
@@ -71,7 +71,7 @@
|
||||
"md5sum": "6c763f609c05b5b9a3b1d422ab89dbac",
|
||||
"filesize": 609681408,
|
||||
"download_url": "https://sourceforge.net/projects/vrin/files",
|
||||
"direct_download_url": "http://sourceforge.net/projects/vrin/files/vRIN-0.6.qcow2.bz2/download",
|
||||
"direct_download_url": "https://sourceforge.net/projects/vrin/files/vRIN-0.6.qcow2.bz2/download",
|
||||
"compression": "bzip2"
|
||||
}
|
||||
],
|
||||
|
||||
@@ -25,44 +25,44 @@
|
||||
},
|
||||
"images": [
|
||||
{
|
||||
"filename": "vyos-1.2.0-rolling+201906040337-amd64.iso",
|
||||
"version": "1.2.0-2019-06-04",
|
||||
"md5sum": "2a1342985b2a9edfef9f66310ce11a92",
|
||||
"filesize": 427819008,
|
||||
"download_url": "http://dev.packages.vyos.net/iso/preview/1.2.0-beta1/",
|
||||
"direct_download_url": "http://dev.packages.vyos.net/iso/preview/1.2.0-beta1/vyos-1.2.0-beta1-amd64.iso"
|
||||
"filename": "vyos-1.3-rolling-202005040117-amd64.iso",
|
||||
"version": "1.3-rolling-202005040117",
|
||||
"md5sum": "0500d5138cd05239b50f93fb24ac8b55",
|
||||
"filesize": 438304768,
|
||||
"download_url": "https://downloads.vyos.io/?dir=rolling/current/amd64",
|
||||
"direct_download_url": "https://downloads.vyos.io/rolling/current/amd64/vyos-1.3-rolling-202005040117-amd64.iso"
|
||||
},
|
||||
{
|
||||
"filename": "vyos-1.1.8-amd64.iso",
|
||||
"version": "1.1.8",
|
||||
"md5sum": "95a141d4b592b81c803cdf7e9b11d8ea",
|
||||
"filesize": 241172480,
|
||||
"download_url": "https://downloads.vyos.io/?dir=release/1.1.8",
|
||||
"direct_download_url": "https://downloads.vyos.io/release/1.1.8/vyos-1.1.8-amd64.iso"
|
||||
"download_url": "https://downloads.vyos.io/?dir=release/legacy/1.1.8",
|
||||
"direct_download_url": "https://downloads.vyos.io/release/legacy/1.1.8/vyos-1.1.8-amd64.iso"
|
||||
},
|
||||
{
|
||||
"filename": "vyos-1.1.7-amd64.iso",
|
||||
"version": "1.1.7",
|
||||
"md5sum": "9a7f745a0b0db0d4f1d9eee2a437fb54",
|
||||
"filesize": 245366784,
|
||||
"download_url": "https://downloads.vyos.io/?dir=release/1.1.7/",
|
||||
"direct_download_url": "https://downloads.vyos.io/release/1.1.7/vyos-1.1.7-amd64.iso"
|
||||
"download_url": "https://downloads.vyos.io/?dir=release/legacy/1.1.7/",
|
||||
"direct_download_url": "https://downloads.vyos.io/release/legacy/1.1.7/vyos-1.1.7-amd64.iso"
|
||||
},
|
||||
{
|
||||
"filename": "vyos-1.1.6-amd64.iso",
|
||||
"version": "1.1.6",
|
||||
"md5sum": "3128954d026e567402a924c2424ce2bf",
|
||||
"filesize": 245366784,
|
||||
"download_url": "hhttps://downloads.vyos.io/?dir=release/1.1.6/",
|
||||
"direct_download_url": "https://downloads.vyos.io/release/1.1.6/vyos-1.1.6-amd64.iso"
|
||||
"download_url": "hhttps://downloads.vyos.io/?dir=release/legacy/1.1.6/",
|
||||
"direct_download_url": "https://downloads.vyos.io/release/legacy/1.1.6/vyos-1.1.6-amd64.iso"
|
||||
},
|
||||
{
|
||||
"filename": "vyos-1.1.5-amd64.iso",
|
||||
"version": "1.1.5",
|
||||
"md5sum": "193179532011ceaa87ee725bd8f22022",
|
||||
"filesize": 247463936,
|
||||
"download_url": "https://downloads.vyos.io/?dir=release/1.1.5/",
|
||||
"direct_download_url": "https://downloads.vyos.io/release/1.1.5/vyos-1.1.5-amd64.iso"
|
||||
"download_url": "https://downloads.vyos.io/?dir=release/legacy/1.1.5/",
|
||||
"direct_download_url": "https://downloads.vyos.io/release/legacy/1.1.5/vyos-1.1.5-amd64.iso"
|
||||
},
|
||||
{
|
||||
"filename": "empty8G.qcow2",
|
||||
@@ -75,10 +75,10 @@
|
||||
],
|
||||
"versions": [
|
||||
{
|
||||
"name": "1.2.0-2019-06-04",
|
||||
"name": "1.3-rolling-202005040117",
|
||||
"images": {
|
||||
"hda_disk_image": "empty8G.qcow2",
|
||||
"cdrom_image": "vyos-1.2.0-rolling+201906040337-amd64.iso"
|
||||
"cdrom_image": "vyos-1.3-rolling-202005040117-amd64.iso"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
||||
@@ -46,7 +46,7 @@
|
||||
"md5sum": "1e6409a4523ada212dea2ebc50e50a65",
|
||||
"filesize": 198656,
|
||||
"download_url": "https://sourceforge.net/projects/gns-3/files/Empty%20Qemu%20disk/",
|
||||
"direct_download_url": "http://sourceforge.net/projects/gns-3/files/Empty%20Qemu%20disk/empty100G.qcow2/download"
|
||||
"direct_download_url": "https://sourceforge.net/projects/gns-3/files/Empty%20Qemu%20disk/empty100G.qcow2/download"
|
||||
}
|
||||
|
||||
],
|
||||
|
||||
@@ -94,7 +94,7 @@
|
||||
"md5sum": "1e6409a4523ada212dea2ebc50e50a65",
|
||||
"filesize": 198656,
|
||||
"download_url": "https://sourceforge.net/projects/gns-3/files/Empty%20Qemu%20disk/",
|
||||
"direct_download_url": "http://sourceforge.net/projects/gns-3/files/Empty%20Qemu%20disk/empty100G.qcow2/download"
|
||||
"direct_download_url": "https://sourceforge.net/projects/gns-3/files/Empty%20Qemu%20disk/empty100G.qcow2/download"
|
||||
}
|
||||
],
|
||||
"versions": [
|
||||
|
||||
@@ -27,6 +27,7 @@ import psutil
|
||||
import platform
|
||||
import re
|
||||
|
||||
from aiohttp.web import WebSocketResponse
|
||||
from gns3server.utils.interfaces import interfaces
|
||||
from ..compute.port_manager import PortManager
|
||||
from ..utils.asyncio import wait_run_in_executor, locking
|
||||
@@ -339,8 +340,8 @@ class BaseNode:
|
||||
|
||||
async def start_wrap_console(self):
|
||||
"""
|
||||
Start a telnet proxy for the console allowing multiple client
|
||||
connected at the same time
|
||||
Start a telnet proxy for the console allowing multiple telnet clients
|
||||
to be connected at the same time
|
||||
"""
|
||||
|
||||
if not self._wrap_console or self._console_type != "telnet":
|
||||
@@ -369,6 +370,62 @@ class BaseNode:
|
||||
self._wrapper_telnet_server.close()
|
||||
await self._wrapper_telnet_server.wait_closed()
|
||||
|
||||
async def start_websocket_console(self, request):
|
||||
"""
|
||||
Connect to console using Websocket.
|
||||
|
||||
:param ws: Websocket object
|
||||
"""
|
||||
|
||||
if self.status != "started":
|
||||
raise NodeError("Node {} is not started".format(self.name))
|
||||
|
||||
if self._console_type != "telnet":
|
||||
raise NodeError("Node {} console type is not telnet".format(self.name))
|
||||
|
||||
try:
|
||||
(telnet_reader, telnet_writer) = await asyncio.open_connection(self._manager.port_manager.console_host, self.console)
|
||||
except ConnectionError as e:
|
||||
raise NodeError("Cannot connect to node {} telnet server: {}".format(self.name, e))
|
||||
|
||||
log.info("Connected to Telnet server")
|
||||
|
||||
ws = WebSocketResponse()
|
||||
await ws.prepare(request)
|
||||
request.app['websockets'].add(ws)
|
||||
|
||||
log.info("New client has connected to console WebSocket")
|
||||
|
||||
async def ws_forward(telnet_writer):
|
||||
|
||||
async for msg in ws:
|
||||
if msg.type == aiohttp.WSMsgType.TEXT:
|
||||
telnet_writer.write(msg.data.encode())
|
||||
await telnet_writer.drain()
|
||||
elif msg.type == aiohttp.WSMsgType.BINARY:
|
||||
await telnet_writer.write(msg.data)
|
||||
await telnet_writer.drain()
|
||||
elif msg.type == aiohttp.WSMsgType.ERROR:
|
||||
log.debug("Websocket connection closed with exception {}".format(ws.exception()))
|
||||
|
||||
async def telnet_forward(telnet_reader):
|
||||
|
||||
while not ws.closed and not telnet_reader.at_eof():
|
||||
data = await telnet_reader.read(1024)
|
||||
if data:
|
||||
await ws.send_bytes(data)
|
||||
|
||||
try:
|
||||
# keep forwarding websocket data in both direction
|
||||
await asyncio.wait([ws_forward(telnet_writer), telnet_forward(telnet_reader)], return_when=asyncio.FIRST_COMPLETED)
|
||||
finally:
|
||||
log.info("Client has disconnected from console WebSocket")
|
||||
if not ws.closed:
|
||||
await ws.close()
|
||||
request.app['websockets'].discard(ws)
|
||||
|
||||
return ws
|
||||
|
||||
@property
|
||||
def allocate_aux(self):
|
||||
"""
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
Docker container instance.
|
||||
"""
|
||||
|
||||
import sys
|
||||
import asyncio
|
||||
import shutil
|
||||
import psutil
|
||||
@@ -86,6 +87,7 @@ class DockerVM(BaseNode):
|
||||
self._telnet_servers = []
|
||||
self._xvfb_process = None
|
||||
self._vnc_process = None
|
||||
self._vncconfig_process = None
|
||||
self._console_resolution = console_resolution
|
||||
self._console_http_path = console_http_path
|
||||
self._console_http_port = console_http_port
|
||||
@@ -615,6 +617,12 @@ class DockerVM(BaseNode):
|
||||
x11_socket = os.path.join("/tmp/.X11-unix/", "X{}".format(self._display))
|
||||
await wait_for_file_creation(x11_socket)
|
||||
|
||||
if not hasattr(sys, "_called_from_test") or not sys._called_from_test:
|
||||
# Start vncconfig for tigervnc clipboard support, connection available only after socket creation.
|
||||
tigervncconfig_path = shutil.which("vncconfig")
|
||||
if tigervnc_path and tigervncconfig_path:
|
||||
self._vncconfig_process = await asyncio.create_subprocess_exec(tigervncconfig_path, "-display", ":{}".format(self._display), "-nowin")
|
||||
|
||||
# sometimes the VNC process can crash
|
||||
monitor_process(self._vnc_process, self._vnc_callback)
|
||||
|
||||
@@ -825,6 +833,12 @@ class DockerVM(BaseNode):
|
||||
await self.stop()
|
||||
|
||||
if self.console_type == "vnc":
|
||||
if self._vncconfig_process:
|
||||
try:
|
||||
self._vncconfig_process.terminate()
|
||||
await self._vncconfig_process.wait()
|
||||
except ProcessLookupError:
|
||||
pass
|
||||
if self._vnc_process:
|
||||
try:
|
||||
self._vnc_process.terminate()
|
||||
|
||||
@@ -458,7 +458,7 @@ class Dynamips(BaseManager):
|
||||
await vm.slot_add_binding(slot_id, adapter)
|
||||
except IndexError:
|
||||
raise DynamipsError("Slot {} doesn't exist on this router".format(slot_id))
|
||||
elif name.startswith("slot") and (value is None or value is ""):
|
||||
elif name.startswith("slot") and (value is None or value == ""):
|
||||
slot_id = int(name[-1])
|
||||
try:
|
||||
if vm.slots[slot_id]:
|
||||
@@ -476,7 +476,7 @@ class Dynamips(BaseManager):
|
||||
await vm.install_wic(wic_slot_id, wic)
|
||||
except IndexError:
|
||||
raise DynamipsError("WIC slot {} doesn't exist on this router".format(wic_slot_id))
|
||||
elif name.startswith("wic") and (value is None or value is ""):
|
||||
elif name.startswith("wic") and (value is None or value == ""):
|
||||
wic_slot_id = int(name[-1])
|
||||
try:
|
||||
if vm.slots[0].wics and vm.slots[0].wics[wic_slot_id]:
|
||||
|
||||
@@ -80,7 +80,7 @@ class Controller:
|
||||
if name == "gns3vm":
|
||||
name = "Main server"
|
||||
|
||||
computes = await self._load_controller_settings()
|
||||
computes = self._load_controller_settings()
|
||||
try:
|
||||
self._local_server = await self.add_compute(compute_id="local",
|
||||
name=name,
|
||||
@@ -118,7 +118,7 @@ class Controller:
|
||||
|
||||
async def stop(self):
|
||||
|
||||
log.info("Controller is Stopping")
|
||||
log.info("Controller is stopping")
|
||||
for project in self._projects.values():
|
||||
await project.close()
|
||||
for compute in self._computes.values():
|
||||
@@ -132,6 +132,12 @@ class Controller:
|
||||
self._computes = {}
|
||||
self._projects = {}
|
||||
|
||||
async def reload(self):
|
||||
|
||||
log.info("Controller is reloading")
|
||||
self._load_controller_settings()
|
||||
await self.load_projects()
|
||||
|
||||
def check_can_write_config(self):
|
||||
"""
|
||||
Check if the controller configuration can be written on disk
|
||||
@@ -182,7 +188,7 @@ class Controller:
|
||||
except OSError as e:
|
||||
log.error("Cannot write controller configuration file '{}': {}".format(self._config_file, e))
|
||||
|
||||
async def _load_controller_settings(self):
|
||||
def _load_controller_settings(self):
|
||||
"""
|
||||
Reload the controller configuration from disk
|
||||
"""
|
||||
@@ -199,7 +205,12 @@ class Controller:
|
||||
|
||||
# load GNS3 VM settings
|
||||
if "gns3vm" in controller_settings:
|
||||
self.gns3vm.settings = controller_settings["gns3vm"]
|
||||
gns3_vm_settings = controller_settings["gns3vm"]
|
||||
if "port" not in gns3_vm_settings:
|
||||
# port setting was added in version 2.2.8
|
||||
# the default port was 3080 before this
|
||||
gns3_vm_settings["port"] = 3080
|
||||
self.gns3vm.settings = gns3_vm_settings
|
||||
|
||||
# load the IOU license settings
|
||||
if "iou_license" in controller_settings:
|
||||
|
||||
@@ -18,6 +18,9 @@
|
||||
import copy
|
||||
import uuid
|
||||
|
||||
import logging
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class Appliance:
|
||||
|
||||
@@ -33,6 +36,9 @@ class Appliance:
|
||||
if "appliance_id" in self._data:
|
||||
del self._data["appliance_id"]
|
||||
|
||||
if self.status != 'broken':
|
||||
log.debug('Appliance "{name}" [{id}] loaded'.format(name=self.name, id=self._id))
|
||||
|
||||
@property
|
||||
def id(self):
|
||||
return self._id
|
||||
@@ -45,6 +51,10 @@ class Appliance:
|
||||
def symbol(self):
|
||||
return self._data.get("symbol")
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
return self._data.get("name")
|
||||
|
||||
@symbol.setter
|
||||
def symbol(self, new_symbol):
|
||||
self._data["symbol"] = new_symbol
|
||||
|
||||
@@ -39,7 +39,7 @@ class GNS3VM:
|
||||
Proxy between the controller and the GNS3 VM engine
|
||||
"""
|
||||
|
||||
def __init__(self, controller, settings={}):
|
||||
def __init__(self, controller):
|
||||
self._controller = controller
|
||||
# Keep instance of the loaded engines
|
||||
self._engines = {}
|
||||
@@ -50,9 +50,9 @@ class GNS3VM:
|
||||
"enable": False,
|
||||
"engine": "vmware",
|
||||
"ram": 2048,
|
||||
"vcpus": 1
|
||||
"vcpus": 1,
|
||||
"port": 80,
|
||||
}
|
||||
self.settings = settings
|
||||
|
||||
def engine_list(self):
|
||||
"""
|
||||
@@ -72,10 +72,11 @@ class GNS3VM:
|
||||
else:
|
||||
vmware_info["name"] = "VMware Workstation / Player (recommended)"
|
||||
|
||||
download_url = "https://github.com/GNS3/gns3-gui/releases/download/v{version}/GNS3.VM.Hyper-V.{version}.zip".format(version=__version__)
|
||||
hyperv_info = {
|
||||
"engine_id": "hyper-v",
|
||||
"name": "Hyper-V",
|
||||
"description": 'Hyper-V support (Windows 10/Server 2016 and above). Nested virtualization must be supported and enabled (Intel processor only)',
|
||||
"description": 'Hyper-V support (Windows 10/Server 2016 and above). Nested virtualization must be supported and enabled (Intel processor only)<br>The GNS3 VM can be <a href="{}">downloaded here</a>'.format(download_url),
|
||||
"support_when_exit": True,
|
||||
"support_headless": False,
|
||||
"support_ram": True
|
||||
@@ -85,7 +86,7 @@ class GNS3VM:
|
||||
virtualbox_info = {
|
||||
"engine_id": "virtualbox",
|
||||
"name": "VirtualBox",
|
||||
"description": 'VirtualBox doesn\'t support nested virtualization, this means Qemu based VMs will run extremely slowly.<br>The GNS3 VM can be <a href="{}">downloaded here</a>'.format(download_url),
|
||||
"description": 'VirtualBox support. Nested virtualization for both Intel and AMD processors is supported since version 6.1<br>The GNS3 VM can be <a href="{}">downloaded here</a>'.format(download_url),
|
||||
"support_when_exit": True,
|
||||
"support_headless": True,
|
||||
"support_ram": True
|
||||
@@ -278,9 +279,9 @@ class GNS3VM:
|
||||
# User will receive the error later when they will try to use the node
|
||||
try:
|
||||
compute = await self._controller.add_compute(compute_id="vm",
|
||||
name="GNS3 VM ({})".format(self.current_engine().vmname),
|
||||
host=None,
|
||||
force=True)
|
||||
name="GNS3 VM ({})".format(self.current_engine().vmname),
|
||||
host=None,
|
||||
force=True)
|
||||
compute.set_last_error(str(e))
|
||||
|
||||
except aiohttp.web.HTTPConflict:
|
||||
@@ -313,6 +314,7 @@ class GNS3VM:
|
||||
engine.ram = self._settings["ram"]
|
||||
engine.vcpus = self._settings["vcpus"]
|
||||
engine.headless = self._settings["headless"]
|
||||
engine.port = self._settings["port"]
|
||||
compute = await self._controller.add_compute(compute_id="vm",
|
||||
name="GNS3 VM is starting ({})".format(engine.vmname),
|
||||
host=None,
|
||||
@@ -329,11 +331,11 @@ class GNS3VM:
|
||||
raise e
|
||||
await compute.connect() # we can connect now that the VM has started
|
||||
await compute.update(name="GNS3 VM ({})".format(engine.vmname),
|
||||
protocol=self.protocol,
|
||||
host=self.ip_address,
|
||||
port=self.port,
|
||||
user=self.user,
|
||||
password=self.password)
|
||||
protocol=self.protocol,
|
||||
host=self.ip_address,
|
||||
port=self.port,
|
||||
user=self.user,
|
||||
password=self.password)
|
||||
|
||||
# check if the VM is in the same subnet as the local server, start 10 seconds later to give
|
||||
# some time for the compute in the VM to be ready for requests
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
# 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 asyncio
|
||||
import psutil
|
||||
|
||||
import logging
|
||||
@@ -29,7 +28,7 @@ class BaseGNS3VM:
|
||||
self._controller = controller
|
||||
self._vmname = None
|
||||
self._ip_address = None
|
||||
self._port = 3080
|
||||
self._port = 80 # value not used, will be overwritten
|
||||
self._headless = False
|
||||
self._vcpus = 1
|
||||
self._ram = 1024
|
||||
|
||||
@@ -285,13 +285,12 @@ class VirtualBoxGNS3VM(BaseGNS3VM):
|
||||
log.info("Removing GNS3VM NAT port forwarding rule from interface {}".format(nat_interface_number))
|
||||
await self._execute("controlvm", [self._vmname, "natpf{}".format(nat_interface_number), "delete", "GNS3VM"])
|
||||
|
||||
# add a GNS3VM NAT port forwarding rule to redirect 127.0.0.1 with random port to port 3080 in the VM
|
||||
# add a GNS3VM NAT port forwarding rule to redirect 127.0.0.1 with random port to the port in the VM
|
||||
log.info("Adding GNS3VM NAT port forwarding rule with port {} to interface {}".format(api_port, nat_interface_number))
|
||||
await self._execute("controlvm", [self._vmname, "natpf{}".format(nat_interface_number),
|
||||
"GNS3VM,tcp,{},{},,3080".format(ip_address, api_port)])
|
||||
"GNS3VM,tcp,{},{},,{}".format(ip_address, api_port, self.port)])
|
||||
|
||||
self.ip_address = await self._get_ip(hostonly_interface_number, api_port)
|
||||
self.port = 3080
|
||||
log.info("GNS3 VM has been started with IP {}".format(self.ip_address))
|
||||
self.running = True
|
||||
|
||||
|
||||
@@ -129,6 +129,8 @@ class Project:
|
||||
|
||||
self._iou_id_lock = asyncio.Lock()
|
||||
|
||||
log.debug('Project "{name}" [{id}] loaded'.format(name=self.name, id=self._id))
|
||||
|
||||
def emit_notification(self, action, event):
|
||||
"""
|
||||
Emit a notification to all clients using this project.
|
||||
|
||||
@@ -147,6 +147,8 @@ class Template:
|
||||
# special case for Dynamips to cover all platform types that contain specific settings
|
||||
self.validate_and_apply_defaults(DYNAMIPS_PLATFORM_TO_SHEMA[self._settings["platform"]])
|
||||
|
||||
log.debug('Template "{name}" [{id}] loaded'.format(name=self.name, id=self._id))
|
||||
|
||||
@property
|
||||
def id(self):
|
||||
return self._id
|
||||
|
||||
@@ -58,7 +58,7 @@ class CrashReport:
|
||||
Report crash to a third party service
|
||||
"""
|
||||
|
||||
DSN = "https://03a62c6395a54334b0818302138c6555:d7977024b6314ffbaddae057f9bb53b8@sentry.io/38482"
|
||||
DSN = "https://dbfb677c73304b1286aef33dfbb749c6:93b9a937d4884426a1b15f37536fcd94@o19455.ingest.sentry.io/38482"
|
||||
if hasattr(sys, "frozen"):
|
||||
cacert = get_resource("cacert.pem")
|
||||
if cacert is not None and os.path.isfile(cacert):
|
||||
|
||||
@@ -412,3 +412,16 @@ class DockerHandler:
|
||||
docker_manager = Docker.instance()
|
||||
images = await docker_manager.list_images()
|
||||
response.json(images)
|
||||
|
||||
@Route.get(
|
||||
r"/projects/{project_id}/docker/nodes/{node_id}/console/ws",
|
||||
description="WebSocket for console",
|
||||
parameters={
|
||||
"project_id": "Project UUID",
|
||||
"node_id": "Node UUID",
|
||||
})
|
||||
async def console_ws(request, response):
|
||||
|
||||
docker_manager = Docker.instance()
|
||||
container = docker_manager.get_node(request.match_info["node_id"], project_id=request.match_info["project_id"])
|
||||
return await container.start_websocket_console(request)
|
||||
@@ -513,3 +513,15 @@ class DynamipsVMHandler:
|
||||
response.set_status(201)
|
||||
response.json(new_node)
|
||||
|
||||
@Route.get(
|
||||
r"/projects/{project_id}/dynamips/nodes/{node_id}/console/ws",
|
||||
description="WebSocket for console",
|
||||
parameters={
|
||||
"project_id": "Project UUID",
|
||||
"node_id": "Node UUID",
|
||||
})
|
||||
async def console_ws(request, response):
|
||||
|
||||
dynamips_manager = Dynamips.instance()
|
||||
vm = dynamips_manager.get_node(request.match_info["node_id"], project_id=request.match_info["project_id"])
|
||||
return await vm.start_websocket_console(request)
|
||||
@@ -453,3 +453,16 @@ class IOUHandler:
|
||||
raise aiohttp.web.HTTPForbidden()
|
||||
|
||||
await response.stream_file(image_path)
|
||||
|
||||
@Route.get(
|
||||
r"/projects/{project_id}/iou/nodes/{node_id}/console/ws",
|
||||
description="WebSocket for console",
|
||||
parameters={
|
||||
"project_id": "Project UUID",
|
||||
"node_id": "Node UUID",
|
||||
})
|
||||
async def console_ws(request, response):
|
||||
|
||||
iou_manager = IOU.instance()
|
||||
vm = iou_manager.get_node(request.match_info["node_id"], project_id=request.match_info["project_id"])
|
||||
return await vm.start_websocket_console(request)
|
||||
@@ -19,12 +19,13 @@ import aiohttp
|
||||
import asyncio
|
||||
import json
|
||||
import os
|
||||
import psutil
|
||||
import tempfile
|
||||
|
||||
from gns3server.web.route import Route
|
||||
from gns3server.compute.project_manager import ProjectManager
|
||||
from gns3server.compute import MODULES
|
||||
from gns3server.utils.ping_stats import PingStats
|
||||
from gns3server.utils.cpu_percent import CpuPercent
|
||||
|
||||
from gns3server.schemas.project import (
|
||||
PROJECT_OBJECT_SCHEMA,
|
||||
@@ -206,7 +207,11 @@ class ProjectHandler:
|
||||
|
||||
:returns: hash
|
||||
"""
|
||||
return {"action": "ping", "event": PingStats.get()}
|
||||
stats = {}
|
||||
# Non blocking call in order to get cpu usage. First call will return 0
|
||||
stats["cpu_usage_percent"] = CpuPercent.get(interval=None)
|
||||
stats["memory_usage_percent"] = psutil.virtual_memory().percent
|
||||
return {"action": "ping", "event": stats}
|
||||
|
||||
@Route.get(
|
||||
r"/projects/{project_id}/files",
|
||||
|
||||
@@ -580,3 +580,16 @@ class QEMUHandler:
|
||||
raise aiohttp.web.HTTPForbidden()
|
||||
|
||||
await response.stream_file(image_path)
|
||||
|
||||
@Route.get(
|
||||
r"/projects/{project_id}/qemu/nodes/{node_id}/console/ws",
|
||||
description="WebSocket for console",
|
||||
parameters={
|
||||
"project_id": "Project UUID",
|
||||
"node_id": "Node UUID",
|
||||
})
|
||||
async def console_ws(request, response):
|
||||
|
||||
qemu_manager = Qemu.instance()
|
||||
vm = qemu_manager.get_node(request.match_info["node_id"], project_id=request.match_info["project_id"])
|
||||
return await vm.start_websocket_console(request)
|
||||
@@ -23,6 +23,7 @@ from gns3server.config import Config
|
||||
from gns3server.schemas.version import VERSION_SCHEMA
|
||||
from gns3server.schemas.server_statistics import SERVER_STATISTICS_SCHEMA
|
||||
from gns3server.compute.port_manager import PortManager
|
||||
from gns3server.utils.cpu_percent import CpuPercent
|
||||
from gns3server.version import __version__
|
||||
from aiohttp.web import HTTPConflict
|
||||
from psutil._common import bytes2human
|
||||
@@ -57,7 +58,7 @@ class ServerHandler:
|
||||
swap_total = psutil.swap_memory().total
|
||||
swap_free = psutil.swap_memory().free
|
||||
swap_used = psutil.swap_memory().used
|
||||
cpu_percent = int(psutil.cpu_percent())
|
||||
cpu_percent = int(CpuPercent.get())
|
||||
load_average_percent = [int(x / psutil.cpu_count() * 100) for x in psutil.getloadavg()]
|
||||
memory_percent = int(psutil.virtual_memory().percent)
|
||||
swap_percent = int(psutil.swap_memory().percent)
|
||||
|
||||
@@ -424,3 +424,16 @@ class VirtualBoxHandler:
|
||||
vbox_manager = VirtualBox.instance()
|
||||
vms = await vbox_manager.list_vms()
|
||||
response.json(vms)
|
||||
|
||||
@Route.get(
|
||||
r"/projects/{project_id}/virtualbox/nodes/{node_id}/console/ws",
|
||||
description="WebSocket for console",
|
||||
parameters={
|
||||
"project_id": "Project UUID",
|
||||
"node_id": "Node UUID",
|
||||
})
|
||||
async def console_ws(request, response):
|
||||
|
||||
virtualbox_manager = VirtualBox.instance()
|
||||
vm = virtualbox_manager.get_node(request.match_info["node_id"], project_id=request.match_info["project_id"])
|
||||
return await vm.start_websocket_console(request)
|
||||
@@ -409,3 +409,16 @@ class VMwareHandler:
|
||||
vmware_manager = VMware.instance()
|
||||
vms = await vmware_manager.list_vms()
|
||||
response.json(vms)
|
||||
|
||||
@Route.get(
|
||||
r"/projects/{project_id}/vmware/nodes/{node_id}/console/ws",
|
||||
description="WebSocket for console",
|
||||
parameters={
|
||||
"project_id": "Project UUID",
|
||||
"node_id": "Node UUID",
|
||||
})
|
||||
async def console_ws(request, response):
|
||||
|
||||
vmware_manager = VMware.instance()
|
||||
vm = vmware_manager.get_node(request.match_info["node_id"], project_id=request.match_info["project_id"])
|
||||
return await vm.start_websocket_console(request)
|
||||
@@ -362,3 +362,16 @@ class VPCSHandler:
|
||||
port_number = int(request.match_info["port_number"])
|
||||
nio = vm.get_nio(port_number)
|
||||
await vpcs_manager.stream_pcap_file(nio, vm.project.id, request, response)
|
||||
|
||||
@Route.get(
|
||||
r"/projects/{project_id}/vpcs/nodes/{node_id}/console/ws",
|
||||
description="WebSocket for console",
|
||||
parameters={
|
||||
"project_id": "Project UUID",
|
||||
"node_id": "Node UUID",
|
||||
})
|
||||
async def console_ws(request, response):
|
||||
|
||||
vpcs_manager = VPCS.instance()
|
||||
vm = vpcs_manager.get_node(request.match_info["node_id"], project_id=request.match_info["project_id"])
|
||||
return await vm.start_websocket_console(request)
|
||||
@@ -16,6 +16,7 @@
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import aiohttp
|
||||
import asyncio
|
||||
|
||||
from gns3server.web.route import Route
|
||||
from gns3server.controller import Controller
|
||||
@@ -453,3 +454,57 @@ class NodeHandler:
|
||||
data = await request.content.read() #FIXME: are we handling timeout or large files correctly?
|
||||
await node.compute.http_query("POST", "/projects/{project_id}/files{path}".format(project_id=project.id, path=path), data=data, timeout=None, raw=True)
|
||||
response.set_status(201)
|
||||
|
||||
@Route.get(
|
||||
r"/projects/{project_id}/nodes/{node_id}/console/ws",
|
||||
parameters={
|
||||
"project_id": "Project UUID",
|
||||
"node_id": "Node UUID"
|
||||
},
|
||||
description="Connect to WebSocket console",
|
||||
status_codes={
|
||||
200: "File returned",
|
||||
403: "Permission denied",
|
||||
404: "The file doesn't exist"
|
||||
})
|
||||
async def ws_console(request, response):
|
||||
|
||||
project = await Controller.instance().get_loaded_project(request.match_info["project_id"])
|
||||
node = project.get_node(request.match_info["node_id"])
|
||||
compute = node.compute
|
||||
ws = aiohttp.web.WebSocketResponse()
|
||||
await ws.prepare(request)
|
||||
request.app['websockets'].add(ws)
|
||||
|
||||
ws_console_compute_url = "ws://{compute_host}:{compute_port}/v2/compute/projects/{project_id}/{node_type}/nodes/{node_id}/console/ws".format(compute_host=compute.host,
|
||||
compute_port=compute.port,
|
||||
project_id=project.id,
|
||||
node_type=node.node_type,
|
||||
node_id=node.id)
|
||||
|
||||
async def ws_forward(ws_client):
|
||||
async for msg in ws:
|
||||
if msg.type == aiohttp.WSMsgType.TEXT:
|
||||
await ws_client.send_str(msg.data)
|
||||
elif msg.type == aiohttp.WSMsgType.BINARY:
|
||||
await ws_client.send_bytes(msg.data)
|
||||
elif msg.type == aiohttp.WSMsgType.ERROR:
|
||||
break
|
||||
|
||||
try:
|
||||
async with aiohttp.ClientSession(connector=aiohttp.TCPConnector(limit=None, force_close=True)) as session:
|
||||
async with session.ws_connect(ws_console_compute_url) as ws_client:
|
||||
asyncio.ensure_future(ws_forward(ws_client))
|
||||
async for msg in ws_client:
|
||||
if msg.type == aiohttp.WSMsgType.TEXT:
|
||||
await ws.send_str(msg.data)
|
||||
elif msg.type == aiohttp.WSMsgType.BINARY:
|
||||
await ws.send_bytes(msg.data)
|
||||
elif msg.type == aiohttp.WSMsgType.ERROR:
|
||||
break
|
||||
finally:
|
||||
if not ws.closed:
|
||||
await ws.close()
|
||||
request.app['websockets'].discard(ws)
|
||||
|
||||
return ws
|
||||
@@ -40,7 +40,7 @@ class SnapshotHandler:
|
||||
input=SNAPSHOT_CREATE_SCHEMA,
|
||||
output=SNAPSHOT_OBJECT_SCHEMA,
|
||||
status_codes={
|
||||
201: "Snasphot created",
|
||||
201: "Snapshot created",
|
||||
404: "The project doesn't exist"
|
||||
})
|
||||
async def create(request, response):
|
||||
@@ -57,21 +57,21 @@ class SnapshotHandler:
|
||||
"project_id": "Project UUID",
|
||||
},
|
||||
status_codes={
|
||||
200: "Snasphot list returned",
|
||||
200: "Snapshot list returned",
|
||||
404: "The project doesn't exist"
|
||||
})
|
||||
def list(request, response):
|
||||
controller = Controller.instance()
|
||||
project = controller.get_project(request.match_info["project_id"])
|
||||
snapshots = [s for s in project.snapshots.values()]
|
||||
response.json(sorted(snapshots, key=lambda s: s.created_at))
|
||||
response.json(sorted(snapshots, key=lambda s: (s.created_at, s.name)))
|
||||
|
||||
@Route.delete(
|
||||
r"/projects/{project_id}/snapshots/{snapshot_id}",
|
||||
description="Delete a snapshot from disk",
|
||||
parameters={
|
||||
"project_id": "Project UUID",
|
||||
"snapshot_id": "Snasphot UUID"
|
||||
"snapshot_id": "Snapshot UUID"
|
||||
},
|
||||
status_codes={
|
||||
204: "Changes have been written on disk",
|
||||
@@ -89,7 +89,7 @@ class SnapshotHandler:
|
||||
description="Restore a snapshot from disk",
|
||||
parameters={
|
||||
"project_id": "Project UUID",
|
||||
"snapshot_id": "Snasphot UUID"
|
||||
"snapshot_id": "Snapshot UUID"
|
||||
},
|
||||
output=PROJECT_OBJECT_SCHEMA,
|
||||
status_codes={
|
||||
|
||||
@@ -31,7 +31,15 @@ class IndexHandler:
|
||||
r"/",
|
||||
description="Home page of the GNS3 server"
|
||||
)
|
||||
def index(request, response):
|
||||
async def index(request, response):
|
||||
|
||||
raise aiohttp.web.HTTPFound(location="/static/web-ui/bundled")
|
||||
|
||||
@Route.get(
|
||||
r"/debug",
|
||||
description="Old index page"
|
||||
)
|
||||
def upload(request, response):
|
||||
response.template("index.html")
|
||||
|
||||
@Route.get(
|
||||
|
||||
@@ -17,8 +17,9 @@
|
||||
|
||||
import asyncio
|
||||
import json
|
||||
import psutil
|
||||
|
||||
from gns3server.utils.ping_stats import PingStats
|
||||
from gns3server.utils.cpu_percent import CpuPercent
|
||||
|
||||
|
||||
class NotificationQueue(asyncio.Queue):
|
||||
@@ -38,14 +39,24 @@ class NotificationQueue(asyncio.Queue):
|
||||
# At first get we return a ping so the client immediately receives data
|
||||
if self._first:
|
||||
self._first = False
|
||||
return ("ping", PingStats.get(), {})
|
||||
return ("ping", self._getPing(), {})
|
||||
|
||||
try:
|
||||
(action, msg, kwargs) = await asyncio.wait_for(super().get(), timeout)
|
||||
except asyncio.TimeoutError:
|
||||
return ("ping", PingStats.get(), {})
|
||||
return ("ping", self._getPing(), {})
|
||||
return (action, msg, kwargs)
|
||||
|
||||
def _getPing(self):
|
||||
"""
|
||||
Return the content of the ping notification
|
||||
"""
|
||||
msg = {}
|
||||
# Non blocking call in order to get cpu usage. First call will return 0
|
||||
msg["cpu_usage_percent"] = CpuPercent.get(interval=None)
|
||||
msg["memory_usage_percent"] = psutil.virtual_memory().percent
|
||||
return msg
|
||||
|
||||
async def get_json(self, timeout):
|
||||
"""
|
||||
Get a message as a JSON
|
||||
|
||||
+9
-11
@@ -240,9 +240,8 @@ def run():
|
||||
if sys.version_info < (3, 5, 3):
|
||||
raise SystemExit("Python 3.5.3 or higher is required")
|
||||
|
||||
user_log.info("Running with Python {major}.{minor}.{micro} and has PID {pid}".format(
|
||||
major=sys.version_info[0], minor=sys.version_info[1],
|
||||
micro=sys.version_info[2], pid=os.getpid()))
|
||||
user_log.info("Running with Python {major}.{minor}.{micro} and has PID {pid}".format(major=sys.version_info[0], minor=sys.version_info[1],
|
||||
micro=sys.version_info[2], pid=os.getpid()))
|
||||
|
||||
# check for the correct locale (UNIX/Linux only)
|
||||
locale_check()
|
||||
@@ -255,7 +254,6 @@ def run():
|
||||
|
||||
CrashReport.instance()
|
||||
host = server_config["host"]
|
||||
|
||||
port = int(server_config["port"])
|
||||
|
||||
server = WebServer.instance(host, port)
|
||||
@@ -269,10 +267,10 @@ def run():
|
||||
log.critical("Critical error while running the server: {}".format(e), exc_info=1)
|
||||
CrashReport.instance().capture_exception()
|
||||
return
|
||||
|
||||
if args.pid:
|
||||
log.info("Remove PID file %s", args.pid)
|
||||
try:
|
||||
os.remove(args.pid)
|
||||
except OSError as e:
|
||||
log.critical("Can't remove pid file %s: %s", args.pid, str(e))
|
||||
finally:
|
||||
if args.pid:
|
||||
log.info("Remove PID file %s", args.pid)
|
||||
try:
|
||||
os.remove(args.pid)
|
||||
except OSError as e:
|
||||
log.critical("Can't remove pid file %s: %s", args.pid, str(e))
|
||||
@@ -48,6 +48,12 @@ GNS3VM_SETTINGS_SCHEMA = {
|
||||
"ram": {
|
||||
"description": "Amount of ram affected to the VM",
|
||||
"type": "integer"
|
||||
},
|
||||
"port": {
|
||||
"description": "Server port",
|
||||
"type": "integer",
|
||||
"minimum": 1,
|
||||
"maximum": 65535
|
||||
}
|
||||
},
|
||||
"additionalProperties": False
|
||||
|
||||
@@ -2682,6 +2682,77 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
|
||||
xterm
|
||||
MIT
|
||||
Copyright (c) 2017-2019, The xterm.js authors (https://github.com/xtermjs/xterm.js)
|
||||
Copyright (c) 2014-2016, SourceLair Private Company (https://www.sourcelair.com)
|
||||
Copyright (c) 2012-2013, Christopher Jeffrey (https://github.com/chjj/)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
|
||||
xterm-addon-attach
|
||||
MIT
|
||||
Copyright (c) 2017, The xterm.js authors (https://github.com/xtermjs/xterm.js)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
|
||||
xterm-addon-fit
|
||||
MIT
|
||||
Copyright (c) 2019, The xterm.js authors (https://github.com/xtermjs/xterm.js)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
|
||||
zone.js
|
||||
MIT
|
||||
The MIT License
|
||||
|
||||
@@ -1,6 +1,36 @@
|
||||
GNS3 WebUI is web implementation of user interface for GNS3 software.
|
||||
|
||||
Current version: GNS3 Web UI 2019.2.0 v11
|
||||
Current version: GNS3 Web UI 2020.2.0-beta.2
|
||||
|
||||
What's New
|
||||
- Drag & drop to add new nodes on topology
|
||||
- Option to minimize/maximize and hide console widget
|
||||
- Ability to add IOS templates
|
||||
- Node names in HTTP console tabs
|
||||
- Default settings for templates
|
||||
- Support for adding IOS images
|
||||
- Node dialog updated
|
||||
- Messages with description in toasts
|
||||
- Adding interfaces to cloud nodes
|
||||
- Changes in notification box mechanism (once per day option)
|
||||
- Additional tooltips added
|
||||
- Copy/paste options in console (only Chrome full support)
|
||||
- More details for server failed connections
|
||||
|
||||
Bug Fixes
|
||||
- Fix for console icons
|
||||
- Fix for creating ethernet switches and hubs
|
||||
- Fix for opening console from context menu
|
||||
- Qemu configurator now works properly
|
||||
- Fixes in snap to grid option
|
||||
- Symbols preview now works correctly
|
||||
- Error messages in preferences should be displayed
|
||||
- Default values for New Ethernet devices in configurator
|
||||
- Fix for wrong adapter types in Qemu
|
||||
- Fix for fit in view option on Firefox
|
||||
- Fix for navigation errors
|
||||
|
||||
GNS3 Web UI 2020.2.0-beta.1
|
||||
|
||||
What's New
|
||||
- Support for suspended status added
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
<!-- <body class="mat-app-background" oncontextmenu="return false;"> -->
|
||||
<body class="mat-app-background" oncontextmenu="return false;">
|
||||
<app-root></app-root>
|
||||
<!-- Global site tag (gtag.js) - Google Analytics -->
|
||||
<script async src="https://www.googletagmanager.com/gtag/js?id=G-5D6FZL9923"></script>
|
||||
<script>
|
||||
window.dataLayer = window.dataLayer || [];
|
||||
@@ -47,5 +48,5 @@
|
||||
|
||||
gtag('config', 'G-5D6FZL9923');
|
||||
</script>
|
||||
<script src="runtime.a8ef3a8272419c2e2c66.js" defer></script><script src="polyfills-es5.adfecedb3e8b94a475d4.js" nomodule defer></script><script src="polyfills.312ad1f991887572d9bc.js" defer></script><script src="main.c31c0c40fa0fcdc2cdcf.js" defer></script></body>
|
||||
<script src="runtime.a8ef3a8272419c2e2c66.js" defer></script><script src="polyfills-es5.adfecedb3e8b94a475d4.js" nomodule defer></script><script src="polyfills.312ad1f991887572d9bc.js" defer></script><script src="main.675279bd49308a23d11c.js" defer></script></body>
|
||||
</html>
|
||||
@@ -0,0 +1 @@
|
||||
(window.webpackJsonp=window.webpackJsonp||[]).push([[1],{"+/L5":function(n,e,t){var l=t("t1UP").isCustomProperty,o=t("vd7W").TYPE,i=t("4njK").mode,r=o.Ident,a=o.Hash,u=o.Colon,s=o.Semicolon,d=o.Delim,c=33,p=35,f=36,h=38,m=42,v=43,g=47;function b(n){return this.Raw(n,i.exclamationMarkOrSemicolon,!0)}function _(n){return this.Raw(n,i.exclamationMarkOrSemicolon,!1)}function y(){var n=this.scanner.tokenIndex,e=this.Value();return"Raw"!==e.type&&!1===this.scanner.eof&&this.scanner.tokenType!==s&&!1===this.scanner.isDelim(c)&&!1===this.scanner.isBalanceEdge(n)&&this.error(),e}function C(){var n=this.scanner.tokenStart;if(this.scanner.tokenType===d)switch(this.scanner.source.charCodeAt(this.scanner.tokenStart)){case m:case f:case v:case p:case h:this.scanner.next();break;case g:this.scanner.next(),this.scanner.isDelim(g)&&this.scanner.next()}return this.eat(this.scanner.tokenType===a?a:r),this.scanner.substrToCursor(n)}function w(){this.eat(d),this.scanner.skipSC();var n=this.consume(r);return"important"===n||n}n.exports={name:"Declaration",structure:{important:[Boolean,String],property:String,value:["Value","Raw"]},parse:function(){var n,e=this.scanner.tokenStart,t=this.scanner.tokenIndex,o=C.call(this),i=l(o),r=i?this.parseCustomProperty:this.parseValue,a=i?_:b,d=!1;return this.scanner.skipSC(),this.eat(u),i||this.scanner.skipSC(),n=r?this.parseWithFallback(y,a):a.call(this,this.scanner.tokenIndex),this.scanner.isDelim(c)&&(d=w.call(this),this.scanner.skipSC()),!1===this.scanner.eof&&this.scanner.tokenType!==s&&!1===this.scanner.isBalanceEdge(t)&&this.error(),{type:"Declaration",loc:this.getLocation(e,this.scanner.tokenStart),important:d,property:o,value:n}},generate:function(n){this.chunk(n.property),this.chunk(":"),this.node(n.value),n.important&&this.chunk(!0===n.important?"!important":"!"+n.important)},walkContext:"declaration"}},"+Kd2":function(n,e,t){var l=t("vd7W").TYPE,o=t("4njK").mode,i=l.Comma;n.exports=function(){var n=this.createList();return this.scanner.skipSC(),n.push(this.Identifier()),this.scanner.skipSC(),this.scanner.tokenType===i&&(n.push(this.Operator()),n.push(this.parseCustomProperty?this.Value(null):this.Raw(this.scanner.tokenIndex,o.exclamationMarkOrSemicolon,!1))),n}},"+gEr":function(n,e,t){"use strict";t.d(e,"a",(function(){return r})),t.d(e,"b",(function(){return a}));var l=t("mrSG"),o=t("MGBS"),i=t("zotm"),r={leading:!0,trailing:!1};function a(n,e){return void 0===e&&(e=r),function(t){return t.lift(new u(n,e.leading,e.trailing))}}var u=function(){function n(n,e,t){this.durationSelector=n,this.leading=e,this.trailing=t}return n.prototype.call=function(n,e){return e.subscribe(new s(n,this.durationSelector,this.leading,this.trailing))},n}(),s=function(n){function e(e,t,l,o){var i=n.call(this,e)||this;return i.destination=e,i.durationSelector=t,i._leading=l,i._trailing=o,i._hasValue=!1,i}return l.c(e,n),e.prototype._next=function(n){this._hasValue=!0,this._sendValue=n,this._throttled||(this._leading?this.send():this.throttle(n))},e.prototype.send=function(){var n=this._sendValue;this._hasValue&&(this.destination.next(n),this.throttle(n)),this._hasValue=!1,this._sendValue=null},e.prototype.throttle=function(n){var e=this.tryDurationSelector(n);e&&this.add(this._throttled=Object(i.a)(this,e))},e.prototype.tryDurationSelector=function(n){try{return this.durationSelector(n)}catch(e){return this.destination.error(e),null}},e.prototype.throttlingDone=function(){var n=this._throttled,e=this._trailing;n&&n.unsubscribe(),this._throttled=null,e&&this.send()},e.prototype.notifyNext=function(n,e,t,l,o){this.throttlingDone()},e.prototype.notifyComplete=function(){this.throttlingDone()},e}(o.a)},"+ryv":function(n,e,t){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var l=t("CcnG");e.HotkeyOptions=new l.InjectionToken("HotkeyOptions")},"+tJ4":function(n,e,t){"use strict";t.d(e,"a",(function(){return l}));var l=function(n){return function(e){for(var t=0,l=n.length;t<l&&!e.closed;t++)e.next(n[t]);e.complete()}}},"+umK":function(n,e,t){"use strict";function l(){}t.d(e,"a",(function(){return l}))},"/+5V":function(n,e){function t(n){function e(n){return null!==n&&("Type"===n.type||"Property"===n.type||"Keyword"===n.type)}var t=null;return null!==this.matched&&function l(o){if(Array.isArray(o.match)){for(var i=0;i<o.match.length;i++)if(l(o.match[i]))return e(o.syntax)&&t.unshift(o.syntax),!0}else if(o.node===n)return t=e(o.syntax)?[o.syntax]:[],!0;return!1}(this.matched),t}function l(n,e,l){var o=t.call(n,e);return null!==o&&o.some(l)}n.exports={getTrace:t,isType:function(n,e){return l(this,n,(function(n){return"Type"===n.type&&n.name===e}))},isProperty:function(n,e){return l(this,n,(function(n){return"Property"===n.type&&n.name===e}))},isKeyword:function(n){return l(this,n,(function(n){return"Keyword"===n.type}))}}},"/21U":function(n,e,t){"use strict";t.d(e,"a",(function(){return o}));var l=t("isby");function o(n){return!Object(l.a)(n)&&n-parseFloat(n)+1>=0}},"/BcF":function(n,e){n.exports={nLine truncated
|
||||
+1
-1
@@ -1 +1 @@
|
||||
{"version":3,"sources":["./node_modules/css-tree/lib/syntax/node/Declaration.js","./node_modules/css-tree/lib/syntax/function/var.js","./node_modules/rxjs/_esm5/internal/operators/throttle.js.pre-build-optimizer.js","./node_modules/angular2-hotkeys/src/hotkey.options.js","./node_modules/rxjs/_esm5/internal/util/subscribeToArray.js.pre-build-optimizer.js","./node_modules/rxjs/_esm5/internal/util/noop.js.pre-build-optimizer.js","./node_modules/css-tree/lib/lexer/trace.js","./node_modules/rxjs/_esm5/internal/util/isNumeric.js.pre-build-optimizer.js","./node_modules/css-tree/lib/syntax/node/Selector.js","./node_modules/rxjs/_esm5/internal/operators/withLatestFrom.js.pre-build-optimizer.js","./node_modules/rxjs/_esm5/internal/util/isPromise.js.pre-build-optimizer.js","./node_modules/rxjs/_esm5/internal/operators/sampleTime.js.pre-build-optimizer.js","./node_modules/css-tree/lib/lexer/generic-an-plus-b.js","./node_modules/rxjs/_esm5/internal/observable/from.js.pre-build-optimizer.js","./node_modules/css-tree/lib/syntax/node/Value.js","./node_modules/rxjs/_esm5/internal/operators/skipUntil.js.pre-build-optimizer.js","./node_modules/rxjs/_esm5/internal/operators/skip.js.pre-build-optimizer.js","./node_modules/rxjs/_esm5/internal/operators/timeout.js.pre-build-optimizer.js","./node_modules/rxjs/_esm5/internal/operators/skipLast.js.pre-build-optimizer.js","./node_modules/rxjs/_esm5/internal/operators/switchMap.js.pre-build-optimizer.js","./node_modules/css-tree/lib/common/SyntaxError.js","./node_modules/rxjs/_esm5/internal/util/canReportError.js.pre-build-optimizer.js","./node_modules/rxjs/_esm5/internal/BehaviorSubject.js.pre-build-optimizer.js","./node_modules/rxjs/_esm5/internal/util/isFunction.js.pre-build-optimizer.js","./node_modules/css-tree/lib/syntax/node/AttributeSelector.js","./node_modules/css-tree/lib/lexer/generic-urange.js","./node_modules/rxjs/_esm5/internal/operators/finalize.js.pre-build-optimizer.js","./node_modules/rxjs/_esm5/internal/util/isArrayLike.js.pre-build-optimizer.js","./node_modules/css-tree/lib/syntax/pseudo/common/selectorList.js","./node_modules/raven-js/vendor/md5/md5.js.pre-build-optimizer.js","./node_modules/rxjs/_esm5/internal/operators/exhaust.js.pre-build-optimizer.js","./node_modules/css-tree/lib/syntax/node/MediaQuery.js","./node_modules/rxjs/_esm5/internal/operators/publishBehavior.js.pre-build-optimizer.js","./node_modules/rxjs/_esm5/internal/util/TimeoutError.js.pre-build-optimizer.js","./node_modules/css-tree/lib/tokenizer/char-code-definitions.js","./node_modules/rxjs/_esm5/internal/util/EmptyError.js.pre-build-optimizer.js","./node_modules/rxjs/_esm5/internal/operators/dematerialize.js.pre-build-optimizer.js","./node_modules/css-tree/lib/walker/create.js","./node_modules/raven-js/vendor/TraceKit/tracekit.js.pre-build-optimizer.js","./node_modules/uuid/lib/rng-browser.js","./node_modules/css-tree/lib/syntax/node/Raw.js","./node_modules/css-tree/lib/syntax/node/index.js","./node_modules/rxjs/_esm5/internal/operators/timestamp.js.pre-build-optimizer.js","./node_modules/rxjs/_esm5/internal/operators/retry.js.pre-build-optimizer.js","./node_modules/rxjs/_esm5/internal/Notification.js.pre-build-optimizer.js","./node_modules/rxjs/_esm5/internal/operators/map.js.pre-build-optimizer.js","./node_modules/rxjs/_esm5/internal/operators/count.js.pre-build-optimizer.js","./node_modules/css-tree/lib/syntax/node/StyleSheet.js","./node_modules/rxjs/_esm5/internal/operators/exhaustMap.js.pre-build-optimizer.js","./node_modules/rxjs/_esm5/internal/Observer.js.pre-build-optimizer.js","./node_modules/rxjs/_esm5/internal/Observable.js.pre-build-optimizer.js","./node_modules/rxjs/_esm5/internal/util/toSubscriber.js.pre-build-optimizer.js","./node_modules/css-tree/lib/syntax/atrule/index.js","./node_modules/rxjs/_esm5/internal/operators/timeInterval.js.pre-build-optimizer.js","./node_modules/create-point-cb/dist/bundle.js","./node_modules/css-tree/lib/syntax/scope/default.js","./node_modules/rxjs/_esm5/internal/observable/using.js.pre-build-optimizer.js","./node_modules/css-tree/lib/syntax/scope/index.js","./node_modules/css-tree/lib/syntax/config/mix.js","./node_modules/rxjs/_esm5/internal/util/ObjectUnsubscribedError.js.pre-build-optimizer.js","./node_modules/css-tree/lib/syntax/node/Combinator.js","./node_modules/css-tree/lib/common/TokenStream.js","./node_modules/rxjs/_esm5/internal/observable/zip.js.pre-build-optimizer.js","./node_modules/css-tree/lib/syntax/node/HexColor.js","./node_modules/rxjs/_esm5/internal/operators/catchError.js.pre-build-optimizer.js","./node_modules/rxjs/_esm5/internal/observable/SubscribeOnObservable.js.pre-build-optimizer.js","./node_modules/rxjs/_esm5/internal/operators/subscribeOn.js.pre-build-optimizer.js","./node_modules/rxjs/_esm5/internal/operators/throttleTime.js.pre-build-optimizer.js","./node_modules/raven-js/src/console.js.pre-build-optimizer.js","./node_modules/rxjs/_esm5/internal/operators/takeLast.js.pre-build-optimizer.js","./node_modules/css-tree/Line truncated
|
||||
{"version":3,"sources":["./node_modules/css-tree/lib/syntax/node/Declaration.js","./node_modules/css-tree/lib/syntax/function/var.js","./node_modules/rxjs/_esm5/internal/operators/throttle.js.pre-build-optimizer.js","./node_modules/angular2-hotkeys/src/hotkey.options.js","./node_modules/rxjs/_esm5/internal/util/subscribeToArray.js.pre-build-optimizer.js","./node_modules/rxjs/_esm5/internal/util/noop.js.pre-build-optimizer.js","./node_modules/css-tree/lib/lexer/trace.js","./node_modules/rxjs/_esm5/internal/util/isNumeric.js.pre-build-optimizer.js","./node_modules/css-tree/lib/syntax/node/Selector.js","./node_modules/rxjs/_esm5/internal/operators/withLatestFrom.js.pre-build-optimizer.js","./node_modules/xterm/lib/xterm.js","./node_modules/rxjs/_esm5/internal/util/isPromise.js.pre-build-optimizer.js","./node_modules/rxjs/_esm5/internal/operators/sampleTime.js.pre-build-optimizer.js","./node_modules/css-tree/lib/lexer/generic-an-plus-b.js","./node_modules/rxjs/_esm5/internal/observable/from.js.pre-build-optimizer.js","./node_modules/css-tree/lib/syntax/node/Value.js","./node_modules/rxjs/_esm5/internal/operators/skipUntil.js.pre-build-optimizer.js","./node_modules/rxjs/_esm5/internal/operators/skip.js.pre-build-optimizer.js","./node_modules/rxjs/_esm5/internal/operators/timeout.js.pre-build-optimizer.js","./node_modules/rxjs/_esm5/internal/operators/skipLast.js.pre-build-optimizer.js","./node_modules/rxjs/_esm5/internal/operators/switchMap.js.pre-build-optimizer.js","./node_modules/css-tree/lib/common/SyntaxError.js","./node_modules/rxjs/_esm5/internal/util/canReportError.js.pre-build-optimizer.js","./node_modules/rxjs/_esm5/internal/BehaviorSubject.js.pre-build-optimizer.js","./node_modules/rxjs/_esm5/internal/util/isFunction.js.pre-build-optimizer.js","./node_modules/css-tree/lib/syntax/node/AttributeSelector.js","./node_modules/css-tree/lib/lexer/generic-urange.js","./node_modules/rxjs/_esm5/internal/operators/finalize.js.pre-build-optimizer.js","./node_modules/rxjs/_esm5/internal/util/isArrayLike.js.pre-build-optimizer.js","./node_modules/css-tree/lib/syntax/pseudo/common/selectorList.js","./node_modules/raven-js/vendor/md5/md5.js.pre-build-optimizer.js","./node_modules/rxjs/_esm5/internal/operators/exhaust.js.pre-build-optimizer.js","./node_modules/css-tree/lib/syntax/node/MediaQuery.js","./node_modules/rxjs/_esm5/internal/operators/publishBehavior.js.pre-build-optimizer.js","./node_modules/rxjs/_esm5/internal/util/TimeoutError.js.pre-build-optimizer.js","./node_modules/css-tree/lib/tokenizer/char-code-definitions.js","./node_modules/rxjs/_esm5/internal/util/EmptyError.js.pre-build-optimizer.js","./node_modules/rxjs/_esm5/internal/operators/dematerialize.js.pre-build-optimizer.js","./node_modules/css-tree/lib/walker/create.js","./node_modules/raven-js/vendor/TraceKit/tracekit.js.pre-build-optimizer.js","./node_modules/uuid/lib/rng-browser.js","./node_modules/css-tree/lib/syntax/node/Raw.js","./node_modules/css-tree/lib/syntax/node/index.js","./node_modules/rxjs/_esm5/internal/operators/timestamp.js.pre-build-optimizer.js","./node_modules/rxjs/_esm5/internal/operators/retry.js.pre-build-optimizer.js","./node_modules/rxjs/_esm5/internal/Notification.js.pre-build-optimizer.js","./node_modules/rxjs/_esm5/internal/operators/map.js.pre-build-optimizer.js","./node_modules/rxjs/_esm5/internal/operators/count.js.pre-build-optimizer.js","./node_modules/css-tree/lib/syntax/node/StyleSheet.js","./node_modules/rxjs/_esm5/internal/operators/exhaustMap.js.pre-build-optimizer.js","./node_modules/rxjs/_esm5/internal/Observer.js.pre-build-optimizer.js","./node_modules/rxjs/_esm5/internal/Observable.js.pre-build-optimizer.js","./node_modules/rxjs/_esm5/internal/util/toSubscriber.js.pre-build-optimizer.js","./node_modules/css-tree/lib/syntax/atrule/index.js","./node_modules/rxjs/_esm5/internal/operators/timeInterval.js.pre-build-optimizer.js","./node_modules/create-point-cb/dist/bundle.js","./node_modules/css-tree/lib/syntax/scope/default.js","./node_modules/rxjs/_esm5/internal/observable/using.js.pre-build-optimizer.js","./node_modules/css-tree/lib/syntax/scope/index.js","../node_modules/xterm-addon-fit/lib/xterm-addon-fit.js","./node_modules/css-tree/lib/syntax/config/mix.js","./node_modules/rxjs/_esm5/internal/util/ObjectUnsubscribedError.js.pre-build-optimizer.js","./node_modules/css-tree/lib/syntax/node/Combinator.js","./node_modules/css-tree/lib/common/TokenStream.js","./node_modules/rxjs/_esm5/internal/observable/zip.js.pre-build-optimizer.js","./node_modules/css-tree/lib/syntax/node/HexColor.js","./node_modules/rxjs/_esm5/internal/operators/catchError.js.pre-build-optimizer.js","./node_modules/rxjs/_esm5/internal/observable/SubscribeOnObservable.js.pre-build-optimizer.js","./node_modules/rxjs/_esm5/internal/operators/subscribeOn.js.pre-build-optimizer.js","./node_modules/rxjs/_esm5/internal/operators/throttleTime.js.pre-build-optimizer.js","./node_modules/raven-js/src/console.js.pre-build-optimizer.js","./node_moduleLine truncated
|
||||
@@ -1 +0,0 @@
|
||||
(window.webpackJsonp=window.webpackJsonp||[]).push([[1],{"+/L5":function(n,e,t){var l=t("t1UP").isCustomProperty,o=t("vd7W").TYPE,i=t("4njK").mode,r=o.Ident,a=o.Hash,u=o.Colon,s=o.Semicolon,d=o.Delim,c=33,p=35,f=36,h=38,m=42,v=43,g=47;function b(n){return this.Raw(n,i.exclamationMarkOrSemicolon,!0)}function _(n){return this.Raw(n,i.exclamationMarkOrSemicolon,!1)}function y(){var n=this.scanner.tokenIndex,e=this.Value();return"Raw"!==e.type&&!1===this.scanner.eof&&this.scanner.tokenType!==s&&!1===this.scanner.isDelim(c)&&!1===this.scanner.isBalanceEdge(n)&&this.error(),e}function C(){var n=this.scanner.tokenStart;if(this.scanner.tokenType===d)switch(this.scanner.source.charCodeAt(this.scanner.tokenStart)){case m:case f:case v:case p:case h:this.scanner.next();break;case g:this.scanner.next(),this.scanner.isDelim(g)&&this.scanner.next()}return this.eat(this.scanner.tokenType===a?a:r),this.scanner.substrToCursor(n)}function w(){this.eat(d),this.scanner.skipSC();var n=this.consume(r);return"important"===n||n}n.exports={name:"Declaration",structure:{important:[Boolean,String],property:String,value:["Value","Raw"]},parse:function(){var n,e=this.scanner.tokenStart,t=this.scanner.tokenIndex,o=C.call(this),i=l(o),r=i?this.parseCustomProperty:this.parseValue,a=i?_:b,d=!1;return this.scanner.skipSC(),this.eat(u),i||this.scanner.skipSC(),n=r?this.parseWithFallback(y,a):a.call(this,this.scanner.tokenIndex),this.scanner.isDelim(c)&&(d=w.call(this),this.scanner.skipSC()),!1===this.scanner.eof&&this.scanner.tokenType!==s&&!1===this.scanner.isBalanceEdge(t)&&this.error(),{type:"Declaration",loc:this.getLocation(e,this.scanner.tokenStart),important:d,property:o,value:n}},generate:function(n){this.chunk(n.property),this.chunk(":"),this.node(n.value),n.important&&this.chunk(!0===n.important?"!important":"!"+n.important)},walkContext:"declaration"}},"+Kd2":function(n,e,t){var l=t("vd7W").TYPE,o=t("4njK").mode,i=l.Comma;n.exports=function(){var n=this.createList();return this.scanner.skipSC(),n.push(this.Identifier()),this.scanner.skipSC(),this.scanner.tokenType===i&&(n.push(this.Operator()),n.push(this.parseCustomProperty?this.Value(null):this.Raw(this.scanner.tokenIndex,o.exclamationMarkOrSemicolon,!1))),n}},"+gEr":function(n,e,t){"use strict";t.d(e,"a",(function(){return r})),t.d(e,"b",(function(){return a}));var l=t("mrSG"),o=t("MGBS"),i=t("zotm"),r={leading:!0,trailing:!1};function a(n,e){return void 0===e&&(e=r),function(t){return t.lift(new u(n,e.leading,e.trailing))}}var u=function(){function n(n,e,t){this.durationSelector=n,this.leading=e,this.trailing=t}return n.prototype.call=function(n,e){return e.subscribe(new s(n,this.durationSelector,this.leading,this.trailing))},n}(),s=function(n){function e(e,t,l,o){var i=n.call(this,e)||this;return i.destination=e,i.durationSelector=t,i._leading=l,i._trailing=o,i._hasValue=!1,i}return l.c(e,n),e.prototype._next=function(n){this._hasValue=!0,this._sendValue=n,this._throttled||(this._leading?this.send():this.throttle(n))},e.prototype.send=function(){var n=this._sendValue;this._hasValue&&(this.destination.next(n),this.throttle(n)),this._hasValue=!1,this._sendValue=null},e.prototype.throttle=function(n){var e=this.tryDurationSelector(n);e&&this.add(this._throttled=Object(i.a)(this,e))},e.prototype.tryDurationSelector=function(n){try{return this.durationSelector(n)}catch(e){return this.destination.error(e),null}},e.prototype.throttlingDone=function(){var n=this._throttled,e=this._trailing;n&&n.unsubscribe(),this._throttled=null,e&&this.send()},e.prototype.notifyNext=function(n,e,t,l,o){this.throttlingDone()},e.prototype.notifyComplete=function(){this.throttlingDone()},e}(o.a)},"+ryv":function(n,e,t){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var l=t("CcnG");e.HotkeyOptions=new l.InjectionToken("HotkeyOptions")},"+tJ4":function(n,e,t){"use strict";t.d(e,"a",(function(){return l}));var l=function(n){return function(e){for(var t=0,l=n.length;t<l&&!e.closed;t++)e.next(n[t]);e.complete()}}},"+umK":function(n,e,t){"use strict";function l(){}t.d(e,"a",(function(){return l}))},"/+5V":function(n,e){function t(n){function e(n){return null!==n&&("Type"===n.type||"Property"===n.type||"Keyword"===n.type)}var t=null;return null!==this.matched&&function l(o){if(Array.isArray(o.match)){for(var i=0;i<o.match.length;i++)if(l(o.match[i]))return e(o.syntax)&&t.unshift(o.syntax),!0}else if(o.node===n)return t=e(o.syntax)?[o.syntax]:[],!0;return!1}(this.matched),t}function l(n,e,l){var o=t.call(n,e);return null!==o&&o.some(l)}n.exports={getTrace:t,isType:function(n,e){return l(this,n,(function(n){return"Type"===n.type&&n.name===e}))},isProperty:function(n,e){return l(this,n,(function(n){return"Property"===n.type&&n.name===e}))},isKeyword:function(n){return l(this,n,(function(n){return"Keyword"===n.type}))}}},"/21U":function(n,e,t){"use strict";t.d(e,"a",(function(){return o}));var l=t("isby");function o(n){return!Object(l.a)(n)&&n-parseFloat(n)+1>=0}},"/BcF":function(n,e){n.exports={nLine truncated
|
||||
@@ -177,7 +177,9 @@ class Hypervisor(UBridgeHypervisor):
|
||||
env=env)
|
||||
|
||||
log.info("ubridge started PID={}".format(self._process.pid))
|
||||
monitor_process(self._process, self._termination_callback)
|
||||
# recv: Bad address is received by uBridge when a docker image stops by itself
|
||||
# see https://github.com/GNS3/gns3-gui/issues/2957
|
||||
#monitor_process(self._process, self._termination_callback)
|
||||
except (OSError, subprocess.SubprocessError) as e:
|
||||
ubridge_stdout = self.read_stdout()
|
||||
log.error("Could not start ubridge: {}\n{}".format(e, ubridge_stdout))
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Copyright (C) 2020 GNS3 Technologies Inc.
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import psutil
|
||||
import time
|
||||
|
||||
|
||||
class CpuPercent:
|
||||
"""
|
||||
Ensures a minumum interval between two cpu_percent() calls
|
||||
"""
|
||||
|
||||
_last_measurement = None # time of last measurement
|
||||
_last_cpu_percent = 0.0 # last cpu_percent
|
||||
|
||||
@classmethod
|
||||
def get(cls, interval=None):
|
||||
"""
|
||||
Get CPU utilization as a percentage
|
||||
|
||||
:returns: float
|
||||
"""
|
||||
|
||||
if interval:
|
||||
cls._last_cpu_percent = psutil.cpu_percent(interval=interval)
|
||||
cls._last_measurement = time.monotonic()
|
||||
else:
|
||||
cur_time = time.monotonic()
|
||||
if cls._last_measurement is None or \
|
||||
(cur_time - cls._last_measurement) >= 1.9:
|
||||
cls._last_cpu_percent = psutil.cpu_percent(interval=None)
|
||||
cls._last_measurement = cur_time
|
||||
|
||||
return cls._last_cpu_percent
|
||||
@@ -1,58 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Copyright (C) 2018 GNS3 Technologies Inc.
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import psutil
|
||||
import time
|
||||
|
||||
|
||||
class PingStats:
|
||||
"""
|
||||
Ping messages are regularly sent to the client to keep the connection open.
|
||||
We send with it some information about server load.
|
||||
"""
|
||||
|
||||
_last_measurement = 0.0 # time of last measurement
|
||||
_last_cpu_percent = 0.0 # last cpu_percent
|
||||
_last_mem_percent = 0.0 # last virtual_memory().percent
|
||||
|
||||
@classmethod
|
||||
def get(cls):
|
||||
"""
|
||||
Get ping statistics
|
||||
|
||||
:returns: hash
|
||||
"""
|
||||
stats = {}
|
||||
cur_time = time.time()
|
||||
# minimum interval for getting CPU and memory statistics
|
||||
if cur_time < cls._last_measurement or \
|
||||
cur_time > cls._last_measurement + 1.9:
|
||||
cls._last_measurement = cur_time
|
||||
# Non blocking call to get cpu usage. First call will return 0
|
||||
try:
|
||||
cls._last_cpu_percent = psutil.cpu_percent(interval=None)
|
||||
cls._last_mem_percent = psutil.virtual_memory().percent
|
||||
except RuntimeError:
|
||||
# ignore the following error:
|
||||
# RuntimeError: host_statistics(HOST_CPU_LOAD_INFO) syscall failed: (ipc/send) invalid reply port
|
||||
pass
|
||||
except PermissionError:
|
||||
# [Errno 13] Permission denied: '/proc/stat'
|
||||
pass
|
||||
stats["cpu_usage_percent"] = cls._last_cpu_percent
|
||||
stats["memory_usage_percent"] = cls._last_mem_percent
|
||||
return stats
|
||||
@@ -23,8 +23,8 @@
|
||||
# or negative for a release candidate or beta (after the base version
|
||||
# number has been incremented)
|
||||
|
||||
__version__ = "2.2.6"
|
||||
__version_info__ = (2, 2, 6, 0)
|
||||
__version__ = "2.2.8"
|
||||
__version_info__ = (2, 2, 8, 0)
|
||||
|
||||
if "dev" in __version__:
|
||||
try:
|
||||
|
||||
@@ -106,7 +106,8 @@ class Route(object):
|
||||
:returns: Response if you need to auth the user otherwise None
|
||||
"""
|
||||
|
||||
if not server_config.getboolean("auth", False):
|
||||
# FIXME: ugly exception to not require authentication for websocket consoles
|
||||
if not server_config.getboolean("auth", False) or request.path.endswith("console/ws"):
|
||||
return None
|
||||
|
||||
user = server_config.get("user", "").strip()
|
||||
@@ -199,6 +200,10 @@ class Route(object):
|
||||
response = Response(request=request, route=route)
|
||||
response.set_status(e.status)
|
||||
response.json({"message": e.text, "status": e.status, "path": route, "request": request.json, "method": request.method})
|
||||
except aiohttp.web.HTTPFound as e:
|
||||
response = Response(request=request, route=route)
|
||||
response.set_status(e.status)
|
||||
raise # must raise to let aiohttp know about the redirection
|
||||
except aiohttp.web.HTTPException as e:
|
||||
response = Response(request=request, route=route)
|
||||
response.set_status(e.status)
|
||||
@@ -253,10 +258,11 @@ class Route(object):
|
||||
"""
|
||||
To avoid strange effect we prevent concurrency
|
||||
between the same instance of the node
|
||||
(excepting when streaming a PCAP file).
|
||||
(excepting when streaming a PCAP file and WebSocket consoles).
|
||||
"""
|
||||
|
||||
if "node_id" in request.match_info and not "pcap" in request.path:
|
||||
#FIXME: ugly exceptions for capture and websocket console
|
||||
if "node_id" in request.match_info and not "pcap" in request.path and not request.path.endswith("console/ws"):
|
||||
node_id = request.match_info.get("node_id")
|
||||
|
||||
if "compute" in request.path:
|
||||
|
||||
@@ -88,6 +88,15 @@ class WebServer:
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
async def reload_server(self):
|
||||
"""
|
||||
Reload the server.
|
||||
"""
|
||||
|
||||
await Controller.instance().reload()
|
||||
|
||||
|
||||
async def shutdown_server(self):
|
||||
"""
|
||||
Cleanly shutdown the server.
|
||||
@@ -141,9 +150,14 @@ class WebServer:
|
||||
def _signal_handling(self):
|
||||
|
||||
def signal_handler(signame, *args):
|
||||
log.warning("Server has got signal {}, exiting...".format(signame))
|
||||
|
||||
try:
|
||||
asyncio.ensure_future(self.shutdown_server())
|
||||
if signame == "SIGHUP":
|
||||
log.info("Server has got signal {}, reloading...".format(signame))
|
||||
asyncio.ensure_future(self.reload_server())
|
||||
else:
|
||||
log.warning("Server has got signal {}, exiting...".format(signame))
|
||||
asyncio.ensure_future(self.shutdown_server())
|
||||
except asyncio.CancelledError:
|
||||
pass
|
||||
|
||||
@@ -209,6 +223,7 @@ class WebServer:
|
||||
"""
|
||||
Called when the HTTP server start
|
||||
"""
|
||||
|
||||
await Controller.instance().start()
|
||||
# Because with a large image collection
|
||||
# without md5sum already computed we start the
|
||||
@@ -265,9 +280,7 @@ class WebServer:
|
||||
# Background task started with the server
|
||||
self._app.on_startup.append(self._on_startup)
|
||||
|
||||
resource_options = aiohttp_cors.ResourceOptions(
|
||||
expose_headers="*", allow_headers="*", max_age=0
|
||||
)
|
||||
resource_options = aiohttp_cors.ResourceOptions(expose_headers="*", allow_headers="*", max_age=0)
|
||||
|
||||
# Allow CORS for this domains
|
||||
cors = aiohttp_cors.setup(self._app, defaults={
|
||||
@@ -296,7 +309,7 @@ class WebServer:
|
||||
self._handler = self._app.make_handler()
|
||||
if self._run_application(self._handler, ssl_context) is False:
|
||||
self._loop.stop()
|
||||
return
|
||||
sys.exit(1)
|
||||
|
||||
self._signal_handling()
|
||||
self._exit_handling()
|
||||
@@ -317,3 +330,4 @@ class WebServer:
|
||||
self._loop.run_until_complete(self.shutdown_server())
|
||||
except asyncio.CancelledError:
|
||||
pass
|
||||
|
||||
@@ -12,6 +12,7 @@ ExecStartPre=/bin/mkdir -p /var/log/gns3 /var/run/gns3
|
||||
ExecStartPre=/bin/chown -R gns3:gns3 /var/log/gns3 /var/run/gns3
|
||||
ExecStart=/usr/local/bin/gns3server --log /var/log/gns3/gns3.log \
|
||||
--pid /var/run/gns3/gns3.pid --daemon
|
||||
ExecReload=/bin/kill -s HUP $MAINPID
|
||||
Restart=on-abort
|
||||
PIDFile=/var/run/gns3/gns3.pid
|
||||
|
||||
|
||||
+2
-1
@@ -1,5 +1,6 @@
|
||||
yarl==1.3.0 # yarl 1.4+ requires Python 3.6+ (needed by aiohttp and aiohttp-cors)
|
||||
jsonschema==2.6.0 # pyup: ignore
|
||||
jsonschema==3.2.0; python_version >= '3.8' # pyup: ignore
|
||||
jsonschema==2.6.0; python_version < '3.8' # pyup: ignore
|
||||
aiohttp==3.6.2
|
||||
aiohttp-cors==0.7.0
|
||||
aiofiles==0.4.0
|
||||
|
||||
@@ -264,6 +264,7 @@ Environment="PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
|
||||
ExecStartPre=/bin/mkdir -p /var/log/gns3 /var/run/gns3
|
||||
ExecStartPre=/bin/chown -R gns3:gns3 /var/log/gns3 /var/run/gns3
|
||||
ExecStart=/usr/bin/gns3server --log /var/log/gns3/gns3.log
|
||||
ExecReload=/bin/kill -s HUP $MAINPID
|
||||
Restart=on-failure
|
||||
RestartSec=5
|
||||
LimitNOFILE=16384
|
||||
|
||||
@@ -1337,7 +1337,7 @@ def test_start_vnc(vm, loop):
|
||||
with asyncio_patch("asyncio.create_subprocess_exec") as mock_exec:
|
||||
loop.run_until_complete(asyncio.ensure_future(vm._start_vnc()))
|
||||
assert vm._display is not None
|
||||
assert mock_exec.call_args[0] == ("Xtigervnc", "-geometry", vm.console_resolution, "-depth", "16", "-interface", "127.0.0.1", "-rfbport", str(vm.console), "-AlwaysShared", "-SecurityTypes", "None", ":{}".format(vm._display))
|
||||
assert mock_exec.call_args[0] == ("/bin/Xtigervnc", "-geometry", vm.console_resolution, "-depth", "16", "-interface", "127.0.0.1", "-rfbport", str(vm.console), "-AlwaysShared", "-SecurityTypes", "None", ":{}".format(vm._display))
|
||||
mock_wait.assert_called_with("/tmp/.X11-unix/X{}".format(vm._display))
|
||||
|
||||
|
||||
|
||||
@@ -110,7 +110,7 @@ def test_compute_httpQueryNotConnected(compute, controller, async_run):
|
||||
async_run(compute.post("/projects", {"a": "b"}))
|
||||
mock.assert_any_call("GET", "https://example.com:84/v2/compute/capabilities", headers={'content-type': 'application/json'}, data=None, auth=None, chunked=None, timeout=20)
|
||||
mock.assert_any_call("POST", "https://example.com:84/v2/compute/projects", data=b'{"a": "b"}', headers={'content-type': 'application/json'}, auth=None, chunked=None, timeout=20)
|
||||
assert compute._connected
|
||||
#assert compute._connected
|
||||
assert compute._capabilities["version"] == __version__
|
||||
controller.notification.controller_emit.assert_called_with("compute.updated", compute.__json__())
|
||||
async_run(compute.close())
|
||||
@@ -134,7 +134,7 @@ def test_compute_httpQueryNotConnectedGNS3vmNotRunning(compute, controller, asyn
|
||||
mock.assert_any_call("POST", "https://example.com:84/v2/compute/projects", data=b'{"a": "b"}', headers={'content-type': 'application/json'}, auth=None, chunked=None, timeout=20)
|
||||
|
||||
assert controller.gns3vm.start.called
|
||||
assert compute._connected
|
||||
#assert compute._connected
|
||||
assert compute._capabilities["version"] == __version__
|
||||
controller.notification.controller_emit.assert_called_with("compute.updated", compute.__json__())
|
||||
async_run(compute.close())
|
||||
|
||||
@@ -56,7 +56,7 @@ def test_load_controller_settings(controller, controller_config_path, async_run)
|
||||
data["gns3vm"] = {"vmname": "Test VM"}
|
||||
with open(controller_config_path, "w+") as f:
|
||||
json.dump(data, f)
|
||||
assert len(async_run(controller._load_controller_settings())) == 1
|
||||
assert len(controller._load_controller_settings()) == 1
|
||||
assert controller.gns3vm.settings["vmname"] == "Test VM"
|
||||
|
||||
|
||||
@@ -67,7 +67,7 @@ def test_load_controller_settings_with_no_computes_section(controller, controlle
|
||||
del data['computes']
|
||||
with open(controller_config_path, "w+") as f:
|
||||
json.dump(data, f)
|
||||
assert len(async_run(controller._load_controller_settings())) == 0
|
||||
assert len(controller._load_controller_settings()) == 0
|
||||
|
||||
|
||||
def test_import_computes_1_x(controller, controller_config_path, async_run):
|
||||
@@ -94,7 +94,7 @@ def test_import_computes_1_x(controller, controller_config_path, async_run):
|
||||
with open(os.path.join(config_dir, "gns3_gui.conf"), "w+") as f:
|
||||
json.dump(gns3_gui_conf, f)
|
||||
|
||||
async_run(controller._load_controller_settings())
|
||||
controller._load_controller_settings()
|
||||
for compute in controller.computes.values():
|
||||
if compute.id != "local":
|
||||
assert len(compute.id) == 36
|
||||
|
||||
@@ -87,7 +87,7 @@ def test_auto_start(async_run, controller, dummy_gns3vm, dummy_engine):
|
||||
assert dummy_engine.start.called
|
||||
assert controller.computes["vm"].name == "GNS3 VM (Test VM)"
|
||||
assert controller.computes["vm"].host == "vm.local"
|
||||
assert controller.computes["vm"].port == 8442
|
||||
assert controller.computes["vm"].port == 80
|
||||
assert controller.computes["vm"].protocol == "https"
|
||||
assert controller.computes["vm"].user == "hello"
|
||||
assert controller.computes["vm"].password == "world"
|
||||
|
||||
@@ -29,8 +29,8 @@ def get_static(filename):
|
||||
return os.path.join(os.path.abspath(os.path.join(current_dir, '..', '..', 'gns3server', 'static')), filename)
|
||||
|
||||
|
||||
def test_index(http_root):
|
||||
response = http_root.get('/')
|
||||
def test_debug(http_root):
|
||||
response = http_root.get('/debug')
|
||||
assert response.status == 200
|
||||
html = response.html
|
||||
assert "Website" in html
|
||||
|
||||
Reference in new issue
Block a user