Merge pull request #2192 from GNS3/2.2

Release v2.2.38
pull/2211/head
Jeremy Grossmann 1 year ago committed by GitHub
commit 0406083991
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -1,5 +1,14 @@
# Change Log
## 2.2.38 28/02/2023
* Bundle web-ui v2.2.38
* Fix c7200_i0_log.txt is created in the current directory. Fixes #2191
* Check swtpm version and start swtpm before qemu
* Fix broken websocket console with Python 3.11
* Fix "cannot reopen console". Ref #2182
* Fix Qemu binary not set when adding appliance from template
## 2.2.37 25/01/2023
* Fix link communication issues on Windows with uBridge

@ -33,6 +33,27 @@
"filesize": 1592000512,
"download_url": "https://software.cisco.com/download/home/286312239/type/282088129/release/10.1(1)"
},
{
"filename": "nexus9300v.10.1.1.qcow2",
"version": "9300v 10.1.1",
"md5sum": "4051bdb96aff6e54b72b7e3b06c9d6eb",
"filesize": 1990983680,
"download_url": "https://software.cisco.com/download/home/286312239/type/282088129/release/10.1(1)"
},
{
"filename": "nexus9500v.9.3.9.qcow2",
"version": "9500v 9.3.9",
"md5sum": "30c25039927f89aebe73ea20d15abd6d",
"filesize": 1980760064,
"download_url": "https://software.cisco.com/download/home/286312239/type/282088129/release/9.3(9)"
},
{
"filename": "nexus9300v.9.3.9.qcow2",
"version": "9300v 9.3.9",
"md5sum": "e807005cb7d2d2957b4af0e59f368b36",
"filesize": 1980563456,
"download_url": "https://software.cisco.com/download/home/286312239/type/282088129/release/9.3(9)"
},
{
"filename": "nexus9300v.9.3.8.qcow2",
"version": "9300v 9.3.8",
@ -184,6 +205,27 @@
"hda_disk_image": "nexus9500v64.10.1.1.qcow2"
}
},
{
"name": "9300v 10.1.1",
"images": {
"bios_image": "OVMF-20160813.fd",
"hda_disk_image": "nexus9300v.10.1.1.qcow2"
}
},
{
"name": "9500v 9.3.9",
"images": {
"bios_image": "OVMF-20160813.fd",
"hda_disk_image": "nexus9500v.9.3.9.qcow2"
}
},
{
"name": "9300v 9.3.9",
"images": {
"bios_image": "OVMF-20160813.fd",
"hda_disk_image": "nexus9300v.9.3.9.qcow2"
}
},
{
"name": "9300v 9.3.8",
"images": {

@ -27,6 +27,13 @@
"kvm": "allow"
},
"images": [
{
"filename": "FWB_KVM-v700-build0129-FORTINET.out.kvm.qcow2",
"version": "7.0.5",
"md5sum": "dc14114c68cf42df322e5b89bffd9bf7",
"filesize": 258146816,
"download_url": "https://support.fortinet.com/Download/FirmwareImages.aspx"
},
{
"filename": "FWB_KVM-v700-build0097-FORTINET.out.kvm.qcow2",
"version": "7.0.1",
@ -128,6 +135,13 @@
}
],
"versions": [
{
"name": "7.0.5",
"images": {
"hda_disk_image": "FWB_KVM-v700-build0129-FORTINET.out.kvm.qcow2",
"hdb_disk_image": "empty30G.qcow2"
}
},
{
"name": "7.0.1",
"images": {

@ -27,6 +27,13 @@
"options": "-smp 2"
},
"images": [
{
"filename": "PA-VM-KVM-10.1.0.qcow2",
"version": "10.1.0",
"md5sum": "8266fd412a22694749f2cd4afcd5fa33",
"filesize": 3597467648,
"download_url": "https://support.paloaltonetworks.com/Updates/SoftwareUpdates/"
},
{
"filename": "PA-VM-KVM-10.0.0.qcow2",
"version": "10.0.0",
@ -120,6 +127,12 @@
}
],
"versions": [
{
"name": "10.1.0",
"images": {
"hda_disk_image": "PA-VM-KVM-10.1.0.qcow2"
}
},
{
"name": "10.0.0",
"images": {

@ -17,7 +17,7 @@
"qemu": {
"adapter_type": "e1000",
"adapters": 1,
"ram": 96,
"ram": 128,
"hda_disk_interface": "virtio",
"arch": "i386",
"console_type": "vnc",
@ -28,7 +28,7 @@
{
"filename": "linux-tinycore-11.1.qcow2",
"version": "11.1",
"md5sum": "993d1ce9b86cb131c90e8263891d51b8",
"md5sum": "00a65300a1dcc956e4e677c638bf4445",
"filesize": 33816576,
"download_url": "https://sourceforge.net/projects/gns-3/files/Qemu%20Appliances/",
"direct_download_url": "http://downloads.sourceforge.net/project/gns-3/Qemu%20Appliances/linux-tinycore-11.1.qcow2"

@ -1,45 +0,0 @@
{
"appliance_id": "d2a23e69-9e92-4c3f-83c8-8caa1aa58ece",
"name": "Ubuntu Server",
"category": "guest",
"description": "This is a custom Ubuntu server which comes with Canonical security updates, Xorg and Telnetd",
"vendor_name": "Canonical Inc.",
"vendor_url": "https://www.ubuntu.com",
"documentation_url": "https://help.ubuntu.com",
"product_name": "Ubuntu",
"product_url": "https://ubuntu.com/server",
"registry_version": 4,
"status": "stable",
"maintainer": "Mohamad Siblini",
"maintainer_email": "info@ictkin.com",
"usage": "Username: gns3\nPassword: gns3 | MD5: 435f15a54f7f673e302ad26f05226e0e",
"port_name_format": "ens{0}",
"qemu": {
"adapter_type": "virtio-net-pci",
"adapters": 1,
"ram": 2048,
"hda_disk_interface": "virtio",
"arch": "x86_64",
"console_type": "vnc",
"boot_priority": "c",
"kvm": "require",
"options": "-vga virtio"
},
"images": [
{
"filename": "Ubuntu Server 18.04.3 LTS (64bit).vmdk",
"version": "18.04.3 LTS Server",
"md5sum": "435f15a54f7f673e302ad26f05226e0e",
"filesize": 2707814912,
"download_url": "https://www.ictkin.com/gns3-appliance/"
}
],
"versions": [
{
"name": "18.04.3 LTS Server",
"images": {
"hda_disk_image": "Ubuntu Server 18.04.3 LTS (64bit).vmdk"
}
}
]
}

@ -469,7 +469,18 @@ class BaseNode:
try:
# keep forwarding websocket data in both direction
await asyncio.wait([ws_forward(telnet_writer), telnet_forward(telnet_reader)], return_when=asyncio.FIRST_COMPLETED)
if sys.version_info >= (3, 11, 0):
# Starting with Python 3.11, passing coroutine objects to wait() directly is forbidden.
aws = [asyncio.create_task(ws_forward(telnet_writer)), asyncio.create_task(telnet_forward(telnet_reader))]
else:
aws = [ws_forward(telnet_writer), telnet_forward(telnet_reader)]
done, pending = await asyncio.wait(aws, return_when=asyncio.FIRST_COMPLETED)
for task in done:
if task.exception():
log.warning(f"Exception while forwarding WebSocket data to Telnet server {task.exception()}")
for task in pending:
task.cancel()
finally:
log.info("Client has disconnected from console WebSocket")
if not ws.closed:

@ -273,7 +273,7 @@ class Dynamips(BaseManager):
"""
try:
output = await subprocess_check_output(dynamips_path)
output = await subprocess_check_output(dynamips_path, "-P", "none")
match = re.search(r"Cisco Router Simulation Platform \(version\s+([\d.]+)", output)
if match:
version = match.group(1)

@ -223,7 +223,7 @@ class Qemu(BaseManager):
version = match.group(1)
return version
else:
raise QemuError("Could not determine the Qemu version for {}".format(qemu_path))
raise QemuError("Could not determine the Qemu version for '{}'".format(qemu_path))
except (OSError, subprocess.SubprocessError) as e:
raise QemuError("Error while looking for the Qemu version: {}".format(e))
@ -242,10 +242,29 @@ class Qemu(BaseManager):
version = match.group(1)
return version
else:
raise QemuError("Could not determine the Qemu-img version for {}".format(qemu_img_path))
raise QemuError("Could not determine the Qemu-img version for '{}'".format(qemu_img_path))
except (OSError, subprocess.SubprocessError) as e:
raise QemuError("Error while looking for the Qemu-img version: {}".format(e))
@staticmethod
async def get_swtpm_version(swtpm_path):
"""
Gets the swtpm version.
:param swtpm_path: path to swtpm executable.
"""
try:
output = await subprocess_check_output(swtpm_path, "--version")
match = re.search(r"version\s+([\d.]+)", output)
if match:
version = match.group(1)
return version
else:
raise QemuError("Could not determine the swtpm version for '{}'".format(swtpm_path))
except (OSError, subprocess.SubprocessError) as e:
raise QemuError("Error while looking for the swtpm version: {}".format(e))
@staticmethod
def get_haxm_windows_version():
"""

@ -216,7 +216,7 @@ class QemuVM(BaseNode):
if qemu_bin == "qemu":
self._platform = "i386"
else:
self._platform = re.sub(r'^qemu-system-(.*)$', r'\1', qemu_bin, re.IGNORECASE)
self._platform = re.sub(r'^qemu-system-(\w+).*$', r'\1', qemu_bin, re.IGNORECASE)
if self._platform.split(".")[0] not in QEMU_PLATFORMS:
raise QemuError("Platform {} is unknown".format(self._platform))
log.info('QEMU VM "{name}" [{id}] has set the QEMU path to {qemu_path}'.format(name=self._name,
@ -1079,6 +1079,10 @@ class QemuVM(BaseNode):
# check if there is enough RAM to run
self.check_available_ram(self.ram)
# start swtpm (TPM emulator) first if TPM is enabled
if self._tpm:
await self._start_swtpm()
command = await self._build_command()
command_string = " ".join(shlex_quote(s) for s in command)
try:
@ -1104,8 +1108,6 @@ class QemuVM(BaseNode):
await self._set_process_priority()
if self._cpu_throttling:
self._set_cpu_throttling()
if self._tpm:
self._start_swtpm()
if "-enable-kvm" in command_string or "-enable-hax" in command_string:
self._hw_virtualization = True
@ -2019,10 +2021,9 @@ class QemuVM(BaseNode):
options.extend(["-kernel", self._kernel_image.replace(",", ",,")])
if self._kernel_command_line:
options.extend(["-append", self._kernel_command_line])
return options
def _start_swtpm(self):
async def _start_swtpm(self):
"""
Start swtpm (TPM emulator)
"""
@ -2035,6 +2036,10 @@ class QemuVM(BaseNode):
swtpm = shutil.which("swtpm")
if not swtpm:
raise QemuError("Could not find swtpm (TPM emulator)")
swtpm_version = await self.manager.get_swtpm_version(swtpm)
if swtpm_version and parse_version(swtpm_version) < parse_version("0.8.0"):
# swtpm >= version 0.8.0 is required
raise QemuError("swtpm version 0.8.0 or above must be installed (detected version is {})".format(swtpm_version))
try:
command = [
swtpm,
@ -2066,6 +2071,8 @@ class QemuVM(BaseNode):
"""
tpm_sock = os.path.join(self.temporary_directory, "swtpm.sock")
if not os.path.exists(tpm_sock):
raise QemuError("swtpm socket file '{}' does not exist".format(tpm_sock))
options = [
"-chardev",
"socket,id=chrtpm,path={}".format(tpm_sock),

@ -58,7 +58,7 @@ class CrashReport:
Report crash to a third party service
"""
DSN = "https://5eb3c88b4e4949d985a6c4c71157b9c3@o19455.ingest.sentry.io/38482"
DSN = "https://4f6a87fd456f468ab0a87ecbc97ed8fb@o19455.ingest.sentry.io/38482"
_instance = None
def __init__(self):

@ -29,6 +29,9 @@ from gns3server.schemas.node import (
NODE_DUPLICATE_SCHEMA
)
import logging
log = logging.getLogger(__name__)
class NodeHandler:
"""
@ -500,6 +503,8 @@ class NodeHandler:
await ws.send_bytes(msg.data)
elif msg.type == aiohttp.WSMsgType.ERROR:
break
except ConnectionResetError:
log.info("Websocket console connection with compute disconnected")
finally:
if not ws.closed:
await ws.close()

@ -35,7 +35,7 @@ QEMU_TEMPLATE_PROPERTIES = {
"platform": {
"description": "Platform to emulate",
"enum": QEMU_PLATFORMS,
"default": "i386"
"default": ""
},
"linked_clone": {
"description": "Whether the VM is a linked clone or not",

@ -46,6 +46,6 @@
gtag('config', 'G-5D6FZL9923');
</script>
<script src="runtime.91a209cf21f6fb848205.js" defer></script><script src="polyfills-es5.865074f5cd9a121111a2.js" nomodule defer></script><script src="polyfills.2f91a039d848e57ff02e.js" defer></script><script src="main.b8506a62709d0cc9f214.js" defer></script>
<script src="runtime.91a209cf21f6fb848205.js" defer></script><script src="polyfills-es5.865074f5cd9a121111a2.js" nomodule defer></script><script src="polyfills.2f91a039d848e57ff02e.js" defer></script><script src="main.11410ae4eaf4d4c08cd0.js" defer></script>
</body></html>

@ -203,8 +203,7 @@ class AsyncioTelnetServer:
except ConnectionError:
async with self._lock:
network_writer.close()
if sys.version_info >= (3, 7, 0):
await network_writer.wait_closed()
# await network_writer.wait_closed() # this doesn't work in Python 3.6
if self._reader_process == network_reader:
self._reader_process = None
# Cancel current read from this reader
@ -220,8 +219,7 @@ class AsyncioTelnetServer:
writer.write_eof()
await writer.drain()
writer.close()
if sys.version_info >= (3, 7, 0):
await writer.wait_closed()
# await writer.wait_closed() # this doesn't work in Python 3.6
except (AttributeError, ConnectionError):
continue

@ -23,8 +23,8 @@
# or negative for a release candidate or beta (after the base version
# number has been incremented)
__version__ = "2.2.37"
__version_info__ = (2, 2, 37, 0)
__version__ = "2.2.38"
__version_info__ = (2, 2, 38, 0)
if "dev" in __version__:
try:

@ -409,7 +409,8 @@ async def test_tpm_option(vm, tmpdir, fake_qemu_img_binary):
vm.manager.get_qemu_version = AsyncioMagicMock(return_value="3.1.0")
vm._tpm = True
tpm_sock = os.path.join(vm.temporary_directory, "swtpm.sock")
options = await vm._build_command()
with patch("os.path.exists", return_value=True) as os_path:
options = await vm._build_command()
assert '-chardev socket,id=chrtpm,path={}'.format(tpm_sock) in ' '.join(options)
assert '-tpmdev emulator,id=tpm0,chardev=chrtpm' in ' '.join(options)
assert '-device tpm-tis,tpmdev=tpm0' in ' '.join(options)

Loading…
Cancel
Save