diff --git a/CHANGELOG b/CHANGELOG
index ad5b3aba..a5321a44 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,5 +1,27 @@
# Change Log
+## 2.2.6 26/03/2020
+
+* Remove --local when starting Docker dev server.
+* Release 2020.1.0-alpha.1
+* Monitor ubrige processes.
+* Add Xvnc command to the VNC servers list. Fixes #172
+* Allow controller to reconnect to compute if communication is lost. Ref #1634
+* Improvement of support for docker USER directive. Fixes #1727.
+* Fix cannot delete Dynamips router the content of the "usage" field. Fixes https://github.com/GNS3/gns3-gui/issues/2947
+* Prevent locked drawings to be deleted. Fixes https://github.com/GNS3/gns3-gui/issues/2948
+* Fix issues with empty project variables. Fixes https://github.com/GNS3/gns3-gui/issues/2941
+* Upgrade psutil to version 5.6.6 due to CVE-2019-18874 https://github.com/advisories/GHSA-qfc5-mcwq-26q8
+* Remove 'format=raw' from the Qemu options of the disk interfaces. Ref #1699
+* Allocate application IDs for IOU nodes on the controller. An application ID is used by IOU to generate its interface Mac addresses. They must be unique across all opened projects sharing the same computes to avoid Mac address collisions.
+* Require VirtualBox >= 6.0 on AMD and >= 6.1 on Intel processors (for GNS3 VM only). Fixes #1610
+* Add nvme disk interface and fix scsi disk interface for Qemu VMs.
+* Disallow using "legacy networking mode" with Qemu >= 2.9.0
+* Add latest Qemu nic models.
+* Attempt to fix error when loading wmi module. Fixes #1712
+* Handle "aborted" state for VirtualBox VMs. Fixes #1702
+* Change how Hyper-V VMs are found. Ref #1612
+
## 2.2.5 09/01/2020
* No changes
diff --git a/Dockerfile b/Dockerfile
index 4b176018..118feb61 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -16,7 +16,6 @@ RUN apt-get update && apt-get install -y \
python3-pip \
python3-dev \
qemu-system-x86 \
- qemu-system-arm \
qemu-kvm \
libvirt-bin \
x11vnc
@@ -33,4 +32,4 @@ RUN pip3 install -r /server/requirements.txt
EXPOSE 3080
-CMD python3 -m gns3server --local
+CMD python3 -m gns3server
diff --git a/gns3server/appliances/cisco-2691.gns3a b/gns3server/appliances/cisco-2691.gns3a
index f0bce68a..e678c81e 100644
--- a/gns3server/appliances/cisco-2691.gns3a
+++ b/gns3server/appliances/cisco-2691.gns3a
@@ -11,7 +11,7 @@
"maintainer": "GNS3 Team",
"maintainer_email": "developers@gns3.net",
"dynamips": {
- "platform": "c3600",
+ "platform": "c2691",
"ram": 192,
"nvram": 256,
"startup_config": "ios_base_startup-config.txt",
diff --git a/gns3server/appliances/cisco-ise.gns3a b/gns3server/appliances/cisco-ise.gns3a
index 5c9a0016..2f3876f9 100644
--- a/gns3server/appliances/cisco-ise.gns3a
+++ b/gns3server/appliances/cisco-ise.gns3a
@@ -7,7 +7,7 @@
"documentation_url": "http://www.cisco.com/c/en/us/support/security/identity-services-engine/tsd-products-support-series-home.html",
"product_name": "Identity Services Engine",
"product_url": "http://www.cisco.com/c/en/us/products/security/identity-services-engine/index.html",
- "registry_version": 3,
+ "registry_version": 4,
"status": "experimental",
"maintainer": "GNS3 Team",
"maintainer_email": "developers@gns3.net",
@@ -15,9 +15,10 @@
"symbol": "cisco-ise.svg",
"port_name_format": "GigabitEthernet{0}",
"qemu": {
+ "cpus": 2,
"adapter_type": "e1000",
- "adapters": 2,
- "ram": 4096,
+ "adapters": 6,
+ "ram": 8192,
"hda_disk_interface": "ide",
"arch": "x86_64",
"console_type": "vnc",
@@ -26,12 +27,33 @@
"options": "-smp 2 -smbios type=1,product=KVM"
},
"images": [
+ {
+ "filename": "ise-2.7.0.356.SPA.x86_64.iso",
+ "version": "2.7.0.356",
+ "md5sum": "efbc831bf05513e4df8695eb3a362921",
+ "filesize": 9184415744,
+ "download_url": "https://software.cisco.com/download/home/283801620/type/283802505/release/2.7.0"
+ },
+ {
+ "filename": "ise-2.6.0.156.SPA.x86_64.iso",
+ "version": "2.6.0.156",
+ "md5sum": "296e65b662821269ad67dd3dea8804d9",
+ "filesize": 8618913792,
+ "download_url": "https://software.cisco.com/download/home/283801620/type/283802505/release/2.6.0"
+ },
{
"filename": "ise-2.4.0.357.SPA.x86_64.iso",
"version": "2.4.0.357",
- "md5sum": "766945618a0ff35f6c720b3bc4b46bfb",
+ "md5sum": "7f32a28f8d95c7525885786a6556913e",
"filesize": 8326062080,
"download_url": "https://software.cisco.com/download/home/283801620/type/283802505/release/2.4.0"
+ },
+ {
+ "filename": "ise-2.3.0.298.SPA.x86_64.iso",
+ "version": "2.3.0.298",
+ "md5sum": "da98d1a34f6b11d63da0f29bd5ef9caf",
+ "filesize": 8174278656,
+ "download_url": "https://software.cisco.com/download/home/283801620/type/283802505/release/2.3.0"
},
{
"filename": "ise-2.2.0.470.SPA.x86_64.iso",
@@ -71,12 +93,33 @@
}
],
"versions": [
+ {
+ "name": "2.7.0.356",
+ "images": {
+ "hda_disk_image": "empty200G.qcow2",
+ "cdrom_image": "ise-2.7.0.356.SPA.x86_64.iso"
+ }
+ },
+ {
+ "name": "2.6.0.156",
+ "images": {
+ "hda_disk_image": "empty200G.qcow2",
+ "cdrom_image": "ise-2.6.0.156.SPA.x86_64.iso"
+ }
+ },
{
"name": "2.4.0.357",
"images": {
"hda_disk_image": "empty200G.qcow2",
"cdrom_image": "ise-2.4.0.357.SPA.x86_64.iso"
}
+ },
+ {
+ "name": "2.3.0.298",
+ "images": {
+ "hda_disk_image": "empty200G.qcow2",
+ "cdrom_image": "ise-2.3.0.298.SPA.x86_64.iso"
+ }
},
{
"name": "2.2.0.470",
diff --git a/gns3server/appliances/cisco-nxosv9k.gns3a b/gns3server/appliances/cisco-nxosv9k.gns3a
index acf4da38..3557a6d6 100644
--- a/gns3server/appliances/cisco-nxosv9k.gns3a
+++ b/gns3server/appliances/cisco-nxosv9k.gns3a
@@ -25,7 +25,21 @@
"kvm": "require"
},
"images": [
- {
+ {
+ "filename": "nexus9500v.9.3.3.qcow2",
+ "version": "9500v 9.3.3",
+ "md5sum": "7230c944041fdaa0e1b18cecccbc9a32",
+ "filesize": 1714159616,
+ "download_url": "https://software.cisco.com/download/home/286312239/type/282088129/release/9.3(3)"
+ },
+ {
+ "filename": "nexus9300v.9.3.3.qcow2",
+ "version": "9300v 9.3.3",
+ "md5sum": "8e9a7c4815907ef47d850623f77042e2",
+ "filesize": 1714225152,
+ "download_url": "https://software.cisco.com/download/home/286312239/type/282088129/release/9.3(3)"
+ },
+ {
"filename": "nxosv.9.3.1.qcow2",
"version": "9.3.1",
"md5sum": "148fd38cb1ff78df2883f844e172fad9",
@@ -134,6 +148,20 @@
}
],
"versions": [
+ {
+ "name": "9500v 9.3.3",
+ "images": {
+ "bios_image": "OVMF-20160813.fd",
+ "hda_disk_image": "nexus9500v.9.3.3.qcow2"
+ }
+ },
+ {
+ "name": "9300v 9.3.3",
+ "images": {
+ "bios_image": "OVMF-20160813.fd",
+ "hda_disk_image": "nexus9300v.9.3.3.qcow2"
+ }
+ },
{
"name": "9.3.1",
"images": {
diff --git a/gns3server/appliances/f5-bigip.gns3a b/gns3server/appliances/f5-bigip.gns3a
index efaf8464..412a5f00 100644
--- a/gns3server/appliances/f5-bigip.gns3a
+++ b/gns3server/appliances/f5-bigip.gns3a
@@ -27,6 +27,13 @@
"options": "-smp 2 -cpu host"
},
"images": [
+ {
+ "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"
+ },
{
"filename": "BIGIP-14.0.0.3-0.0.4.qcow2",
"version": "14.0.0 HF3",
@@ -142,6 +149,13 @@
}
],
"versions": [
+ {
+ "name": "14.1.2.3",
+ "images": {
+ "hda_disk_image": "BIGIP-14.1.2.3-0.0.5.qcow2",
+ "hdb_disk_image": "empty100G.qcow2"
+ }
+ },
{
"name": "14.0.0 HF3",
"images": {
diff --git a/gns3server/appliances/mikrotik-chr.gns3a b/gns3server/appliances/mikrotik-chr.gns3a
index bd4f2e4a..e765be2a 100644
--- a/gns3server/appliances/mikrotik-chr.gns3a
+++ b/gns3server/appliances/mikrotik-chr.gns3a
@@ -27,6 +27,15 @@
},
"images": [
{
+ "filename": "chr-7.0beta5.img",
+ "version": "7.0beta5",
+ "md5sum": "3c9855f0efdc23df29511c76aee52c95",
+ "filesize": 67108864,
+ "download_url": "http://www.mikrotik.com/download",
+ "direct_download_url": "https://download.mikrotik.com/routeros/7.0beta5/chr-7.0beta5.img.zip",
+ "compression": "zip"
+ },
+ {
"filename": "chr-7.0beta3.img",
"version": "7.0beta3",
"md5sum": "938c59989df039cb9f33e0da96c22174",
@@ -34,8 +43,26 @@
"download_url": "http://www.mikrotik.com/download",
"direct_download_url": "https://download.mikrotik.com/routeros/7.0beta3/chr-7.0beta3.img.zip",
"compression": "zip"
+ },
+ {
+ "filename": "chr-6.46.3.img",
+ "version": "6.46.3",
+ "md5sum": "72d72c4a585a04eb9ed24ec9e4678486",
+ "filesize": 67108864,
+ "download_url": "http://www.mikrotik.com/download",
+ "direct_download_url": "https://download.mikrotik.com/routeros/6.46.3/chr-6.46.3.img.zip",
+ "compression": "zip"
},
{
+ "filename": "chr-6.45.8.img",
+ "version": "6.45.8",
+ "md5sum": "73cc01e22e0b301dc29416f59ced8a7d",
+ "filesize": 67108864,
+ "download_url": "http://www.mikrotik.com/download",
+ "direct_download_url": "https://download.mikrotik.com/routeros/6.45.8/chr-6.45.8.img.zip",
+ "compression": "zip"
+ },
+ {
"filename": "chr-6.45.6.img",
"version": "6.45.6",
"md5sum": "e68db699ba23ac7e4fba95b3075c1c6b",
@@ -155,10 +182,28 @@
],
"versions": [
{
+ "name": "7.0beta5",
+ "images": {
+ "hda_disk_image": "chr-7.0beta5.img"
+ }
+ },
+ {
"name": "7.0beta3",
"images": {
"hda_disk_image": "chr-7.0beta3.img"
}
+ },
+ {
+ "name": "6.46.3",
+ "images": {
+ "hda_disk_image": "chr-6.46.3.img"
+ }
+ },
+ {
+ "name": "6.45.8",
+ "images": {
+ "hda_disk_image": "chr-6.45.8.img"
+ }
},
{
"name": "6.45.6",
diff --git a/gns3server/appliances/openwrt.gns3a b/gns3server/appliances/openwrt.gns3a
index de7a750d..744359fd 100644
--- a/gns3server/appliances/openwrt.gns3a
+++ b/gns3server/appliances/openwrt.gns3a
@@ -21,6 +21,42 @@
"kvm": "allow"
},
"images": [
+ {
+ "filename": "openwrt-19.07.1-x86-64-combined-ext4.img",
+ "version": "19.07.1",
+ "md5sum": "2d36f48bcc37edf3c5cfc28fed44b533",
+ "filesize": 285736960,
+ "download_url": "https://downloads.openwrt.org/releases/19.07.1/targets/x86/64/",
+ "direct_download_url": "https://downloads.openwrt.org/releases/19.07.1/targets/x86/64/openwrt-19.07.1-x86-64-combined-ext4.img.gz",
+ "compression": "gzip"
+ },
+ {
+ "filename": "openwrt-18.06.7-x86-64-combined-ext4.img",
+ "version": "18.06.7",
+ "md5sum": "f463f38cccf89e1a2229f74a4c42d3ef",
+ "filesize": 285736960,
+ "download_url": "https://downloads.openwrt.org/releases/18.06.7/targets/x86/64/",
+ "direct_download_url": "https://downloads.openwrt.org/releases/18.06.7/targets/x86/64/openwrt-18.06.7-x86-64-combined-ext4.img.gz",
+ "compression": "gzip"
+ },
+ {
+ "filename": "openwrt-19.07.0-x86-64-combined-ext4.img",
+ "version": "19.07.0",
+ "md5sum": "cf2a353d10e017b9e71cd3761f7aa724",
+ "filesize": 285736960,
+ "download_url": "https://downloads.openwrt.org/releases/19.07.0/targets/x86/64/",
+ "direct_download_url": "https://downloads.openwrt.org/releases/19.07.0/targets/x86/64/openwrt-19.07.0-x86-64-combined-ext4.img.gz",
+ "compression": "gzip"
+ },
+ {
+ "filename": "openwrt-18.06.6-x86-64-combined-ext4.img",
+ "version": "18.06.6",
+ "md5sum": "0afeec80ad7e5035f739e0ed0a07fb83",
+ "filesize": 285736960,
+ "download_url": "https://downloads.openwrt.org/releases/18.06.6/targets/x86/64/",
+ "direct_download_url": "https://downloads.openwrt.org/releases/18.06.6/targets/x86/64/openwrt-18.06.6-x86-64-combined-ext4.img.gz",
+ "compression": "gzip"
+ },
{
"filename": "openwrt-18.06.5-x86-64-combined-ext4.img",
"version": "18.06.5",
@@ -68,6 +104,30 @@
}
],
"versions": [
+ {
+ "name": "19.07.1",
+ "images": {
+ "hda_disk_image": "openwrt-19.07.1-x86-64-combined-ext4.img"
+ }
+ },
+ {
+ "name": "18.06.7",
+ "images": {
+ "hda_disk_image": "openwrt-18.06.7-x86-64-combined-ext4.img"
+ }
+ },
+ {
+ "name": "19.07.0",
+ "images": {
+ "hda_disk_image": "openwrt-19.07.0-x86-64-combined-ext4.img"
+ }
+ },
+ {
+ "name": "18.06.6",
+ "images": {
+ "hda_disk_image": "openwrt-18.06.6-x86-64-combined-ext4.img"
+ }
+ },
{
"name": "18.06.5",
"images": {
diff --git a/gns3server/compute/docker/docker_vm.py b/gns3server/compute/docker/docker_vm.py
index d7d4b0dc..25a9b5e7 100644
--- a/gns3server/compute/docker/docker_vm.py
+++ b/gns3server/compute/docker/docker_vm.py
@@ -564,12 +564,14 @@ class DockerVM(BaseNode):
"""
self._display = self._get_free_display_port()
- if not (shutil.which("Xtigervnc") or shutil.which("Xvfb") and shutil.which("x11vnc")):
- raise DockerError("Please install tigervnc-standalone-server (recommended) or Xvfb + x11vnc before using VNC support")
+ tigervnc_path = shutil.which("Xtigervnc") or shutil.which("Xvnc")
- if shutil.which("Xtigervnc"):
+ if not (tigervnc_path or shutil.which("Xvfb") and shutil.which("x11vnc")):
+ raise DockerError("Please install TigerVNC (recommended) or Xvfb + x11vnc before using VNC support")
+
+ if tigervnc_path:
with open(os.path.join(self.working_dir, "vnc.log"), "w") as fd:
- self._vnc_process = await asyncio.create_subprocess_exec("Xtigervnc",
+ self._vnc_process = await asyncio.create_subprocess_exec(tigervnc_path,
"-geometry", self._console_resolution,
"-depth", "16",
"-interface", self._manager.port_manager.console_host,
@@ -606,8 +608,9 @@ class DockerVM(BaseNode):
"""
self._display = self._get_free_display_port()
- if not (shutil.which("Xtigervnc") or shutil.which("Xvfb") and shutil.which("x11vnc")):
- raise DockerError("Please install tigervnc-standalone-server (recommended) or Xvfb + x11vnc before using VNC support")
+ tigervnc_path = shutil.which("Xtigervnc") or shutil.which("Xvnc")
+ if not (tigervnc_path or shutil.which("Xvfb") and shutil.which("x11vnc")):
+ raise DockerError("Please install TigerVNC server (recommended) or Xvfb + x11vnc before using VNC support")
await self._start_vnc_process()
x11_socket = os.path.join("/tmp/.X11-unix/", "X{}".format(self._display))
await wait_for_file_creation(x11_socket)
diff --git a/gns3server/compute/docker/resources/init.sh b/gns3server/compute/docker/resources/init.sh
index bc33ea1c..8040d025 100755
--- a/gns3server/compute/docker/resources/init.sh
+++ b/gns3server/compute/docker/resources/init.sh
@@ -87,9 +87,5 @@ done
ifup -a -f
# continue normal docker startup
-GNS3_CMD="PATH=$OLD_PATH exec"
-while test "$#" -gt 0 ; do
- GNS3_CMD="${GNS3_CMD} \"${1//\"/\\\"}\""
- shift
-done
-exec su ${GNS3_USER-root} -p -c "$GNS3_CMD"
+eval HOME=$(echo ~${GNS3_USER-root})
+exec su ${GNS3_USER-root} -p -- /gns3/run-cmd.sh "$OLD_PATH" "$@"
diff --git a/gns3server/compute/docker/resources/run-cmd.sh b/gns3server/compute/docker/resources/run-cmd.sh
new file mode 100755
index 00000000..610d8d53
--- /dev/null
+++ b/gns3server/compute/docker/resources/run-cmd.sh
@@ -0,0 +1,6 @@
+#!/bin/sh
+# run docker startup, first arg is new PATH, remainder is command
+
+PATH="$1"
+shift
+exec "$@"
diff --git a/gns3server/compute/dynamips/__init__.py b/gns3server/compute/dynamips/__init__.py
index c7b35147..a996d5f5 100644
--- a/gns3server/compute/dynamips/__init__.py
+++ b/gns3server/compute/dynamips/__init__.py
@@ -493,7 +493,7 @@ class Dynamips(BaseManager):
await vm.set_sparsemem(False)
usage = settings.get("usage")
- if usage and usage != vm.usage:
+ if usage is not None and usage != vm.usage:
vm.usage = usage
# update the configs if needed
diff --git a/gns3server/compute/iou/__init__.py b/gns3server/compute/iou/__init__.py
index 028736b7..89d47e3e 100644
--- a/gns3server/compute/iou/__init__.py
+++ b/gns3server/compute/iou/__init__.py
@@ -25,7 +25,6 @@ import asyncio
from ..base_manager import BaseManager
from .iou_error import IOUError
from .iou_vm import IOUVM
-from .utils.application_id import get_next_application_id
import logging
log = logging.getLogger(__name__)
@@ -48,12 +47,7 @@ class IOU(BaseManager):
:returns: IOUVM instance
"""
- async with self._iou_id_lock:
- # wait for a node to be completely created before adding a new one
- # this is important otherwise we allocate the same application ID
- # when creating multiple IOU node at the same time
- application_id = get_next_application_id(self.nodes)
- node = await super().create_node(*args, application_id=application_id, **kwargs)
+ node = await super().create_node(*args, **kwargs)
return node
@staticmethod
diff --git a/gns3server/compute/iou/iou_vm.py b/gns3server/compute/iou/iou_vm.py
index 9db7c88d..e08357ef 100644
--- a/gns3server/compute/iou/iou_vm.py
+++ b/gns3server/compute/iou/iou_vm.py
@@ -70,6 +70,10 @@ class IOUVM(BaseNode):
super().__init__(name, node_id, project, manager, console=console, console_type=console_type)
+ log.info('IOU "{name}" [{id}]: assigned with application ID {application_id}'.format(name=self._name,
+ id=self._id,
+ application_id=application_id))
+
self._iou_process = None
self._telnet_server = None
self._iou_stdout_file = ""
diff --git a/gns3server/compute/qemu/qemu_vm.py b/gns3server/compute/qemu/qemu_vm.py
index 88c27d85..6b0a61fa 100644
--- a/gns3server/compute/qemu/qemu_vm.py
+++ b/gns3server/compute/qemu/qemu_vm.py
@@ -1647,7 +1647,16 @@ class QemuVM(BaseNode):
options.extend(["-device", 'ahci,id=ahci{}'.format(disk_index)])
options.extend(["-drive", 'file={},if=none,id=drive{},index={},media=disk'.format(disk, disk_index, disk_index)])
options.extend(["-device", 'ide-drive,drive=drive{},bus=ahci{}.0,id=drive{}'.format(disk_index, disk_index, disk_index)])
-
+ elif interface == "nvme":
+ options.extend(["-drive", 'file={},if=none,id=drive{},index={},media=disk'.format(disk, disk_index, disk_index)])
+ options.extend(["-device", 'nvme,drive=drive{},serial={}'.format(disk_index, disk_index)])
+ elif interface == "scsi":
+ options.extend(["-device", 'virtio-scsi-pci,id=scsi{}'.format(disk_index)])
+ options.extend(["-drive", 'file={},if=none,id=drive{},index={},media=disk'.format(disk, disk_index, disk_index)])
+ options.extend(["-device", 'scsi-hd,drive=drive{}'.format(disk_index)])
+ #elif interface == "sd":
+ # options.extend(["-drive", 'file={},id=drive{},index={}'.format(disk, disk_index, disk_index)])
+ # options.extend(["-device", 'sd-card,drive=drive{},id=drive{}'.format(disk_index, disk_index, disk_index)])
else:
options.extend(["-drive", 'file={},if={},index={},media=disk,id=drive{}'.format(disk, interface, disk_index, disk_index)])
@@ -1723,10 +1732,13 @@ class QemuVM(BaseNode):
patched_qemu = False
if self._legacy_networking:
- version = await self.manager.get_qemu_version(self.qemu_path)
- if version and parse_version(version) < parse_version("1.1.0"):
- # this is a patched Qemu if version is below 1.1.0
- patched_qemu = True
+ qemu_version = await self.manager.get_qemu_version(self.qemu_path)
+ if qemu_version:
+ if parse_version(qemu_version) >= parse_version("2.9.0"):
+ raise QemuError("Qemu version 2.9.0 and later doesn't support legacy networking mode")
+ if parse_version(qemu_version) < parse_version("1.1.0"):
+ # this is a patched Qemu if version is below 1.1.0
+ patched_qemu = True
# Each 32 PCI device we need to add a PCI bridge with max 9 bridges
pci_devices = 4 + len(self._ethernet_adapters) # 4 PCI devices are use by default by qemu
diff --git a/gns3server/compute/virtualbox/virtualbox_vm.py b/gns3server/compute/virtualbox/virtualbox_vm.py
index 36070b5a..a1d00597 100644
--- a/gns3server/compute/virtualbox/virtualbox_vm.py
+++ b/gns3server/compute/virtualbox/virtualbox_vm.py
@@ -279,7 +279,7 @@ class VirtualBoxVM(BaseNode):
await self._set_network_options()
await self._set_serial_console()
else:
- raise VirtualBoxError("VirtualBox VM not powered off")
+ raise VirtualBoxError("VirtualBox VM '{}' is not powered off (current state is '{}')".format(self.name, vm_state))
# check if there is enough RAM to run
self.check_available_ram(self.ram)
@@ -320,7 +320,8 @@ class VirtualBoxVM(BaseNode):
await self._stop_ubridge()
await self._stop_remote_console()
vm_state = await self._get_vm_state()
- if vm_state in ("running", "paused", "stuck"):
+ log.info("Stopping VirtualBox VM '{name}' [{id}] (current state is {vm_state})".format(name=self.name, id=self.id, vm_state=vm_state))
+ if vm_state in ("running", "paused"):
if self.on_close == "save_vm_state":
# add a guest property to know the VM has been saved
@@ -348,7 +349,10 @@ class VirtualBoxVM(BaseNode):
result = await self._control_vm("poweroff")
self.status = "stopped"
log.debug("Stop result: {}".format(result))
+ elif vm_state == "aborted":
+ self.status = "stopped"
+ if self.status == "stopped":
log.info("VirtualBox VM '{name}' [{id}] stopped".format(name=self.name, id=self.id))
await asyncio.sleep(0.5) # give some time for VirtualBox to unlock the VM
if self.on_close != "save_vm_state":
diff --git a/gns3server/controller/__init__.py b/gns3server/controller/__init__.py
index cae729d4..20132f81 100644
--- a/gns3server/controller/__init__.py
+++ b/gns3server/controller/__init__.py
@@ -481,7 +481,7 @@ class Controller:
@property
def projects(self):
"""
- :returns: The dictionary of projects managed by GNS3
+ :returns: The dictionary of projects managed by the controller
"""
return self._projects
diff --git a/gns3server/controller/compute.py b/gns3server/controller/compute.py
index 419d3e07..1e7c55ac 100644
--- a/gns3server/controller/compute.py
+++ b/gns3server/controller/compute.py
@@ -448,11 +448,11 @@ class Compute:
log.error("Error received on compute WebSocket '{}': {}".format(ws_url, ws.exception()))
elif response.type == aiohttp.WSMsgType.CLOSED:
pass
- self._connected = False
break
except aiohttp.client_exceptions.ClientResponseError as e:
log.error("Client response error received on compute WebSocket '{}': {}".format(ws_url,e))
finally:
+ self._connected = False
log.info("Connection closed to compute WebSocket '{}'".format(ws_url))
# Try to reconnect after 1 second if server unavailable only if not during tests (otherwise we create a ressources usage bomb)
diff --git a/gns3server/controller/drawing.py b/gns3server/controller/drawing.py
index 4ef324b4..de929b2f 100644
--- a/gns3server/controller/drawing.py
+++ b/gns3server/controller/drawing.py
@@ -16,7 +16,6 @@
# along with this program. If not, see