From 0d0a06799d9c375c1aa297834ce4aa892f8bae10 Mon Sep 17 00:00:00 2001 From: grossmj Date: Mon, 29 Aug 2022 11:14:44 +0200 Subject: [PATCH 01/33] Development on 2.2.35dev1 --- gns3server/version.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gns3server/version.py b/gns3server/version.py index bdef617c..cd7e0db9 100644 --- a/gns3server/version.py +++ b/gns3server/version.py @@ -23,8 +23,8 @@ # or negative for a release candidate or beta (after the base version # number has been incremented) -__version__ = "2.2.34" -__version_info__ = (2, 2, 34, 0) +__version__ = "2.2.35dev1" +__version_info__ = (2, 2, 35, 99) if "dev" in __version__: try: From 9fb0ba5a71de0f678a66771d07d3911eedf1a9f0 Mon Sep 17 00:00:00 2001 From: grossmj Date: Mon, 10 Oct 2022 14:29:04 +0800 Subject: [PATCH 02/33] Upgrade dependencies --- requirements.txt | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/requirements.txt b/requirements.txt index 4703e6dc..30f9df05 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,10 +1,10 @@ jsonschema==3.2.0 -aiohttp==3.8.1 +aiohttp==3.8.3 aiohttp-cors==0.7.0 -aiofiles==0.8.0 -Jinja2==3.0.3 -sentry-sdk==1.9.5 -psutil==5.9.1 +aiofiles==22.1.0 +Jinja2==3.1.2 +sentry-sdk==1.9.10 +psutil==5.9.2 async-timeout==4.0.2 distro==1.7.0 py-cpuinfo==8.0.0 From 58471ea7f49dbbf47f3c66c86d9315171b80f951 Mon Sep 17 00:00:00 2001 From: grossmj Date: Mon, 10 Oct 2022 15:50:35 +0800 Subject: [PATCH 03/33] Downgrade aiofiles to support Python 3.6 --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 30f9df05..cdb93d0a 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,7 +1,7 @@ jsonschema==3.2.0 aiohttp==3.8.3 aiohttp-cors==0.7.0 -aiofiles==22.1.0 +aiofiles==0.8.0 Jinja2==3.1.2 sentry-sdk==1.9.10 psutil==5.9.2 From e5bee8ff52e80f0288f4620223036794a6816d04 Mon Sep 17 00:00:00 2001 From: grossmj Date: Mon, 10 Oct 2022 15:52:36 +0800 Subject: [PATCH 04/33] Downgrade Jinja2 to support Python 3.6 --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index cdb93d0a..eb7b6aea 100644 --- a/requirements.txt +++ b/requirements.txt @@ -2,7 +2,7 @@ jsonschema==3.2.0 aiohttp==3.8.3 aiohttp-cors==0.7.0 aiofiles==0.8.0 -Jinja2==3.1.2 +Jinja2==3.0.3 sentry-sdk==1.9.10 psutil==5.9.2 async-timeout==4.0.2 From e20d1adb0ebe031750dcf13ff56c5051e19fa1ed Mon Sep 17 00:00:00 2001 From: grossmj Date: Mon, 10 Oct 2022 16:30:28 +0800 Subject: [PATCH 05/33] Downgrade aiohttp to v3.8.1 --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index eb7b6aea..33e1aaa7 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,5 @@ jsonschema==3.2.0 -aiohttp==3.8.3 +aiohttp==3.8.1 aiohttp-cors==0.7.0 aiofiles==0.8.0 Jinja2==3.0.3 From 0303e210591af35e33071d2e5bffb37b4c982291 Mon Sep 17 00:00:00 2001 From: grossmj Date: Tue, 11 Oct 2022 23:01:24 +0800 Subject: [PATCH 06/33] Update requirements.txt --- requirements.txt | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/requirements.txt b/requirements.txt index 33e1aaa7..798ba5ef 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,12 +1,14 @@ jsonschema==3.2.0 aiohttp==3.8.1 aiohttp-cors==0.7.0 -aiofiles==0.8.0 -Jinja2==3.0.3 -sentry-sdk==1.9.10 -psutil==5.9.2 +aiofiles==22.1.0; python_version >= '3.7' +aiofiles==0.8.0; python_version < '3.7' # v0.8.0 is the last version to support Python 3.6 +Jinja2==3.1.2; python_version >= '3.7' +Jinja2==3.0.3; python_version < '3.7' # v3.0.3 is the last version to support Python 3.6 +sentry-sdk==1.9.10,<1.10 +psutil>=5.9.2,<5.10 async-timeout==4.0.2 -distro==1.7.0 +distro==1.8.0 py-cpuinfo==8.0.0 setuptools==60.6.0; python_version >= '3.7' # don't upgrade because of https://github.com/pypa/setuptools/issues/3084 -setuptools==59.6.0; python_version < '3.7' # v59.7.0 dropped support for Python 3.6 +setuptools==59.6.0; python_version < '3.7' # v59.6.0 is the last version to support Python 3.6 From 78b2b93540ed7e3c6523d929cd0d1c1829fd5961 Mon Sep 17 00:00:00 2001 From: grossmj Date: Tue, 11 Oct 2022 23:23:15 +0800 Subject: [PATCH 07/33] Update dev-requirements.txt --- dev-requirements.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dev-requirements.txt b/dev-requirements.txt index 86cc066f..8355921e 100644 --- a/dev-requirements.txt +++ b/dev-requirements.txt @@ -1,8 +1,8 @@ -rrequirements.txt -pytest==7.0.1; python_version < '3.7' # last version to support Python 3.6 -pytest==7.1.2; python_version >= '3.7' +pytest==7.1.3; python_version >= '3.7' +pytest==7.0.1; python_version < '3.7' # v7.0.1 is the last version to support Python 3.6 flake8==5.0.4 pytest-timeout==2.1.0 -pytest-aiohttp==0.3.0; python_version < '3.7' # last version to support Python 3.6 pytest-aiohttp==1.0.4; python_version >= '3.7' +pytest-aiohttp==0.3.0; python_version < '3.7' # last version to support Python 3.6 From 6b3d4feab88c29c97e31b6894063acee92bd7dc1 Mon Sep 17 00:00:00 2001 From: grossmj Date: Tue, 11 Oct 2022 23:28:11 +0800 Subject: [PATCH 08/33] Replace deprecated distro.linux_distribution() call --- gns3server/crash_report.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gns3server/crash_report.py b/gns3server/crash_report.py index 31d4b37e..459d2e5d 100644 --- a/gns3server/crash_report.py +++ b/gns3server/crash_report.py @@ -93,7 +93,7 @@ class CrashReport: "os:release": platform.release(), "os:win_32": " ".join(platform.win32_ver()), "os:mac": "{} {}".format(platform.mac_ver()[0], platform.mac_ver()[2]), - "os:linux": " ".join(distro.linux_distribution()), + "os:linux": distro.name(pretty=True), } From 9ff302592c19c259ac1a6ae3f0e2b14ddf74f822 Mon Sep 17 00:00:00 2001 From: grossmj Date: Wed, 12 Oct 2022 21:40:23 +0800 Subject: [PATCH 09/33] Upgrade to aiohttp 3.8.3 --- requirements.txt | 2 +- tests/handlers/api/compute/test_qemu.py | 14 ++++++++------ 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/requirements.txt b/requirements.txt index 798ba5ef..d2d2c86f 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,5 @@ jsonschema==3.2.0 -aiohttp==3.8.1 +aiohttp==3.8.3 aiohttp-cors==0.7.0 aiofiles==22.1.0; python_version >= '3.7' aiofiles==0.8.0; python_version < '3.7' # v0.8.0 is the last version to support Python 3.6 diff --git a/tests/handlers/api/compute/test_qemu.py b/tests/handlers/api/compute/test_qemu.py index 00245f25..95611f10 100644 --- a/tests/handlers/api/compute/test_qemu.py +++ b/tests/handlers/api/compute/test_qemu.py @@ -185,12 +185,14 @@ async def test_qemu_update(compute_api, vm, free_console_port, fake_qemu_vm): "hdb_disk_image": "linux载.img" } - response = await compute_api.put("/projects/{project_id}/qemu/nodes/{node_id}".format(project_id=vm["project_id"], node_id=vm["node_id"]), params) - assert response.status == 200 - assert response.json["name"] == "test" - assert response.json["console"] == free_console_port - assert response.json["hdb_disk_image"] == "linux载.img" - assert response.json["ram"] == 1024 + with patch("gns3server.compute.qemu.qemu_vm.QemuVM.updated") as mock: + response = await compute_api.put("/projects/{project_id}/qemu/nodes/{node_id}".format(project_id=vm["project_id"], node_id=vm["node_id"]), params) + assert response.status == 200 + assert response.json["name"] == "test" + assert response.json["console"] == free_console_port + assert response.json["hdb_disk_image"] == "linux载.img" + assert response.json["ram"] == 1024 + assert mock.called async def test_qemu_nio_create_udp(compute_api, vm): From 77dd772314cf78b630c1a7af8779730577ecf9be Mon Sep 17 00:00:00 2001 From: grossmj Date: Wed, 12 Oct 2022 22:07:37 +0800 Subject: [PATCH 10/33] Allow for more dependency versions at patch level --- requirements.txt | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/requirements.txt b/requirements.txt index d2d2c86f..b56713a4 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,14 +1,14 @@ -jsonschema==3.2.0 -aiohttp==3.8.3 -aiohttp-cors==0.7.0 -aiofiles==22.1.0; python_version >= '3.7' +jsonschema>=4.16.0,<4.17 +aiohttp>=3.8.3,<3.9 +aiohttp-cors>=0.7.0,<0.8 +aiofiles>=22.1.0,<22.2; python_version >= '3.7' aiofiles==0.8.0; python_version < '3.7' # v0.8.0 is the last version to support Python 3.6 -Jinja2==3.1.2; python_version >= '3.7' +Jinja2>=3.1.2,<3.2; python_version >= '3.7' Jinja2==3.0.3; python_version < '3.7' # v3.0.3 is the last version to support Python 3.6 sentry-sdk==1.9.10,<1.10 psutil>=5.9.2,<5.10 -async-timeout==4.0.2 -distro==1.8.0 -py-cpuinfo==8.0.0 -setuptools==60.6.0; python_version >= '3.7' # don't upgrade because of https://github.com/pypa/setuptools/issues/3084 +async-timeout>=4.0.2,<4.1 +distro>=1.7.0 +py-cpuinfo>=8.0.0,<8.1 +setuptools>=60.8.1; python_version >= '3.7' setuptools==59.6.0; python_version < '3.7' # v59.6.0 is the last version to support Python 3.6 From 8cfedce468634bd0def7b34611c2b4e43f01de71 Mon Sep 17 00:00:00 2001 From: grossmj Date: Wed, 12 Oct 2022 22:13:34 +0800 Subject: [PATCH 11/33] Use jsonschema v3.2.0 for Python 3.6 --- requirements.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index b56713a4..735c4eac 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,5 @@ -jsonschema>=4.16.0,<4.17 +jsonschema>=4.16.0,<4.17; python_version >= '3.7' +jsonschema==3.2.0; python_version < '3.7' # v3.2.0 is the last version to support Python 3.6 aiohttp>=3.8.3,<3.9 aiohttp-cors>=0.7.0,<0.8 aiofiles>=22.1.0,<22.2; python_version >= '3.7' From a6959de1f83ec0cc613ff274346bc273b4a1b2fa Mon Sep 17 00:00:00 2001 From: grossmj Date: Tue, 18 Oct 2022 21:14:53 +0800 Subject: [PATCH 12/33] Upgrade pytest. Fixes #2130 --- dev-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev-requirements.txt b/dev-requirements.txt index 86cc066f..ea23ee1f 100644 --- a/dev-requirements.txt +++ b/dev-requirements.txt @@ -1,7 +1,7 @@ -rrequirements.txt pytest==7.0.1; python_version < '3.7' # last version to support Python 3.6 -pytest==7.1.2; python_version >= '3.7' +pytest==7.1.3; python_version >= '3.7' flake8==5.0.4 pytest-timeout==2.1.0 pytest-aiohttp==0.3.0; python_version < '3.7' # last version to support Python 3.6 From de1654a50f9ed137c14e4383694f4143cb5fd056 Mon Sep 17 00:00:00 2001 From: grossmj Date: Tue, 18 Oct 2022 21:40:08 +0800 Subject: [PATCH 13/33] Upgrade pip and setuptools in appveyor.yml --- appveyor.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/appveyor.yml b/appveyor.yml index db38580a..9ddf6932 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -12,6 +12,7 @@ environment: install: - cinst nmap + - "%PYTHON%\\python.exe -m pip install -U pip setuptools" # upgrade pip & setuptools first - "%PYTHON%\\python.exe -m pip install -r dev-requirements.txt" - "%PYTHON%\\python.exe -m pip install -r win-requirements.txt" From c7df8331edd54c4b3d09f2540bc5985bb2682855 Mon Sep 17 00:00:00 2001 From: grossmj Date: Tue, 18 Oct 2022 21:47:10 +0800 Subject: [PATCH 14/33] Upgrade to Visual Studio 2022 in appveyor.yml --- appveyor.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appveyor.yml b/appveyor.yml index 9ddf6932..1a90685d 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,6 +1,6 @@ version: '{build}-{branch}' -image: Visual Studio 2015 +image: Visual Studio 2022 platform: x64 From f8ee3b3d5032b2e8578823d1b633002dbb26db38 Mon Sep 17 00:00:00 2001 From: grossmj Date: Wed, 19 Oct 2022 18:31:17 +0800 Subject: [PATCH 15/33] Upgrade pywin32 to v304 --- win-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/win-requirements.txt b/win-requirements.txt index 5c75f1f1..1a93fbb1 100644 --- a/win-requirements.txt +++ b/win-requirements.txt @@ -1,4 +1,4 @@ -rrequirements.txt -pywin32==303 +pywin32==304 wmi==1.5.1 From ec50cc7c0d3e9ed6820b7ac37ae2ef2529e61e4e Mon Sep 17 00:00:00 2001 From: grossmj Date: Sun, 30 Oct 2022 19:04:54 +0800 Subject: [PATCH 16/33] Support for Python 3.11 --- .github/workflows/testing.yml | 2 +- setup.py | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/testing.yml b/.github/workflows/testing.yml index 36039595..161878b9 100644 --- a/.github/workflows/testing.yml +++ b/.github/workflows/testing.yml @@ -16,7 +16,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: ["3.6", "3.7", "3.8", "3.9", "3.10"] + python-version: ["3.6", "3.7", "3.8", "3.9", "3.10", "3.11"] steps: - uses: actions/checkout@v2 diff --git a/setup.py b/setup.py index caf8f125..17cbbb42 100644 --- a/setup.py +++ b/setup.py @@ -81,6 +81,7 @@ setup( "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", "Programming Language :: Python :: Implementation :: CPython", ], ) From 2d74d1ad94fa3ae48651778a89918524c7910dfb Mon Sep 17 00:00:00 2001 From: grossmj Date: Sun, 30 Oct 2022 22:07:44 +0800 Subject: [PATCH 17/33] Fix tests for Python 3.11 --- gns3server/utils/asyncio/pool.py | 2 +- gns3server/web/route.py | 12 ++++++++---- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/gns3server/utils/asyncio/pool.py b/gns3server/utils/asyncio/pool.py index 0015e29c..8a900722 100644 --- a/gns3server/utils/asyncio/pool.py +++ b/gns3server/utils/asyncio/pool.py @@ -39,7 +39,7 @@ class Pool(): while len(self._tasks) > 0 or len(pending) > 0: while len(self._tasks) > 0 and len(pending) < self._concurrency: task, args, kwargs = self._tasks.pop(0) - pending.add(task(*args, **kwargs)) + pending.add(asyncio.create_task(task(*args, **kwargs))) (done, pending) = await asyncio.wait(pending, return_when=asyncio.FIRST_COMPLETED) for task in done: if task.exception(): diff --git a/gns3server/web/route.py b/gns3server/web/route.py index e788a32c..115d209c 100644 --- a/gns3server/web/route.py +++ b/gns3server/web/route.py @@ -164,8 +164,6 @@ class Route(object): "description": kw.get("description", ""), }) - func = asyncio.coroutine(func) - async def control_schema(request): # This block is executed at each method call server_config = Config.instance().get_section_config("Server") @@ -181,7 +179,10 @@ class Route(object): response = Response(request=request, route=route, output_schema=output_schema) request = await parse_request(request, None, raw) - await func(request, response) + if asyncio.iscoroutinefunction(func): + await func(request, response) + else: + func(request, response) return response # API call @@ -195,7 +196,10 @@ class Route(object): except OSError as e: log.warning("Could not write to the record file {}: {}".format(record_file, e)) response = Response(request=request, route=route, output_schema=output_schema) - await func(request, response) + if asyncio.iscoroutinefunction(func): + await func(request, response) + else: + func(request, response) except aiohttp.web.HTTPBadRequest as e: response = Response(request=request, route=route) response.set_status(e.status) From f3b8f43689e0c2e8ed9add50097a8501fa526d5c Mon Sep 17 00:00:00 2001 From: grossmj Date: Sun, 30 Oct 2022 22:21:28 +0800 Subject: [PATCH 18/33] Fix creating asyncio task in Python 3.6 --- gns3server/utils/asyncio/pool.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/gns3server/utils/asyncio/pool.py b/gns3server/utils/asyncio/pool.py index 8a900722..22750ead 100644 --- a/gns3server/utils/asyncio/pool.py +++ b/gns3server/utils/asyncio/pool.py @@ -15,6 +15,7 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . +import sys import asyncio @@ -39,7 +40,11 @@ class Pool(): while len(self._tasks) > 0 or len(pending) > 0: while len(self._tasks) > 0 and len(pending) < self._concurrency: task, args, kwargs = self._tasks.pop(0) - pending.add(asyncio.create_task(task(*args, **kwargs))) + if sys.version_info >= (3, 7): + t = asyncio.create_task(task(*args, **kwargs)) + else: + t = asyncio.get_event_loop().create_task(task(*args, **kwargs)) + pending.add(t) (done, pending) = await asyncio.wait(pending, return_when=asyncio.FIRST_COMPLETED) for task in done: if task.exception(): From 9cf2e4f5a630d47198e92e09c003c79246a45816 Mon Sep 17 00:00:00 2001 From: grossmj Date: Sun, 6 Nov 2022 17:51:31 +0800 Subject: [PATCH 19/33] Make version PEP 440 compliant --- gns3server/version.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/gns3server/version.py b/gns3server/version.py index cd7e0db9..f0cb635e 100644 --- a/gns3server/version.py +++ b/gns3server/version.py @@ -23,7 +23,7 @@ # or negative for a release candidate or beta (after the base version # number has been incremented) -__version__ = "2.2.35dev1" +__version__ = "2.2.35.dev2" __version_info__ = (2, 2, 35, 99) if "dev" in __version__: @@ -31,7 +31,7 @@ if "dev" in __version__: import os import subprocess if os.path.exists(os.path.join(os.path.dirname(os.path.abspath(__file__)), "..", ".git")): - r = subprocess.check_output(["git", "rev-parse", "--short", "HEAD"]).decode().strip() - __version__ = "{}-{}".format(__version__, r) + r = subprocess.check_output(["git", "rev-parse", "--short", "HEAD"]).decode().strip("\n") + __version__ += "+" + r except Exception as e: print(e) From 6f11df6189d5638ee8dfda900a4103a4f7b34ec0 Mon Sep 17 00:00:00 2001 From: grossmj Date: Sun, 6 Nov 2022 19:30:24 +0800 Subject: [PATCH 20/33] Add missing VMware settings in gns3_server.conf --- conf/gns3_server.conf | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/conf/gns3_server.conf b/conf/gns3_server.conf index 9f9e02dc..013ba7dd 100644 --- a/conf/gns3_server.conf +++ b/conf/gns3_server.conf @@ -90,3 +90,9 @@ require_kvm = True enable_hardware_acceleration = True ; Require hardware acceleration in order to start VMs (all platforms) require_hardware_acceleration = False + +[VMware] +; First vmnet interface of the range that can be managed by the GNS3 server +vmnet_start_range = 2 +; Last vmnet interface of the range that can be managed by the GNS3 server. It must be maximum 19 on Windows. +vmnet_end_range = 255 From f04702d607de31b014be65863e7c0b1716281727 Mon Sep 17 00:00:00 2001 From: grossmj Date: Sun, 6 Nov 2022 19:36:31 +0800 Subject: [PATCH 21/33] Fix console vnc don't use configured ports in some case. Fixes #2111 --- gns3server/compute/base_node.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/gns3server/compute/base_node.py b/gns3server/compute/base_node.py index f07ed957..a7b244cd 100644 --- a/gns3server/compute/base_node.py +++ b/gns3server/compute/base_node.py @@ -578,8 +578,12 @@ class BaseNode: # no need to allocate a port when the console type is none self._console = None elif console_type == "vnc": - # VNC is a special case and the range must be 5900-6000 - self._console = self._manager.port_manager.get_free_tcp_port(self._project, 5900, 6000) + vnc_console_start_port_range, vnc_console_end_port_range = self._get_vnc_console_port_range() + self._console = self._manager.port_manager.get_free_tcp_port( + self._project, + vnc_console_start_port_range, + vnc_console_end_port_range + ) else: self._console = self._manager.port_manager.get_free_tcp_port(self._project) From a4b24eacebf1dc2646606496ec898fbe50706502 Mon Sep 17 00:00:00 2001 From: grossmj Date: Mon, 7 Nov 2022 20:12:03 +0800 Subject: [PATCH 22/33] Use importlib_resources instead of pkg_resources and install built-in appliances in config dir. --- gns3server/controller/__init__.py | 20 ++++++------ gns3server/controller/appliance_manager.py | 36 +++++++++++++++++++--- gns3server/utils/get_resource.py | 33 ++++++-------------- requirements.txt | 1 + 4 files changed, 53 insertions(+), 37 deletions(-) diff --git a/gns3server/controller/__init__.py b/gns3server/controller/__init__.py index e000ea06..a3c16fb3 100644 --- a/gns3server/controller/__init__.py +++ b/gns3server/controller/__init__.py @@ -22,6 +22,7 @@ import uuid import socket import shutil import aiohttp +import importlib_resources from ..config import Config from .project import Project @@ -35,7 +36,6 @@ from .symbols import Symbols from ..version import __version__ from .topology import load_topology from .gns3vm import GNS3VM -from ..utils.get_resource import get_resource from .gns3vm.gns3_vm_error import GNS3VMError import logging @@ -65,7 +65,7 @@ class Controller: async def start(self): log.info("Controller is starting") - self.load_base_files() + self._load_base_files() server_config = Config.instance().get_section_config("Server") Config.instance().listen_for_config_changes(self._update_config) host = server_config.get("host", "localhost") @@ -242,6 +242,7 @@ class Controller: if "iou_license" in controller_settings: self._iou_license_settings = controller_settings["iou_license"] + self._appliance_manager.install_builtin_appliances() self._appliance_manager.appliances_etag = controller_settings.get("appliances_etag") self._appliance_manager.load_appliances() self._template_manager.load_templates(controller_settings.get("templates")) @@ -269,20 +270,21 @@ class Controller: except OSError as e: log.error(str(e)) - def load_base_files(self): + def _load_base_files(self): """ At startup we copy base file to the user location to allow them to customize it """ dst_path = self.configs_path() - src_path = get_resource('configs') try: - for file in os.listdir(src_path): - if not os.path.exists(os.path.join(dst_path, file)): - shutil.copy(os.path.join(src_path, file), os.path.join(dst_path, file)) - except OSError: - pass + for entry in importlib_resources.files('gns3server.configs').iterdir(): + full_path = os.path.join(dst_path, entry.name) + if entry.is_file() and not os.path.exists(full_path): + log.debug(f"Installing base config file {entry.name} to {full_path}") + shutil.copy(str(entry), os.path.join(dst_path, entry.name)) + except OSError as e: + log.error(f"Could not install base config files to {dst_path}: {e}") def images_path(self): """ diff --git a/gns3server/controller/appliance_manager.py b/gns3server/controller/appliance_manager.py index cebcad58..b9349152 100644 --- a/gns3server/controller/appliance_manager.py +++ b/gns3server/controller/appliance_manager.py @@ -16,11 +16,12 @@ # along with this program. If not, see . import os -import shutil import json import uuid import asyncio import aiohttp +import importlib_resources +import shutil from .appliance import Appliance from ..config import Config @@ -65,9 +66,9 @@ class ApplianceManager: return self._appliances - def appliances_path(self): + def _custom_appliances_path(self): """ - Get the image storage directory + Get the custom appliance storage directory """ server_config = Config.instance().get_section_config("Server") @@ -75,13 +76,38 @@ class ApplianceManager: os.makedirs(appliances_path, exist_ok=True) return appliances_path + def _builtin_appliances_path(self): + """ + Get the built-in appliance storage directory + """ + + config = Config.instance() + appliances_dir = os.path.join(config.config_dir, "appliances") + os.makedirs(appliances_dir, exist_ok=True) + return appliances_dir + + def install_builtin_appliances(self): + """ + At startup we copy the built-in appliances files. + """ + + dst_path = self._builtin_appliances_path() + try: + for entry in importlib_resources.files('gns3server.appliances').iterdir(): + full_path = os.path.join(dst_path, entry.name) + if entry.is_file() and not os.path.exists(full_path): + log.debug(f"Installing built-in appliance file {entry.name} to {full_path}") + shutil.copy(str(entry), os.path.join(dst_path, entry.name)) + except OSError as e: + log.error(f"Could not install built-in appliance files to {dst_path}: {e}") + def load_appliances(self, symbol_theme="Classic"): """ Loads appliance files from disk. """ self._appliances = {} - for directory, builtin in ((get_resource('appliances'), True,), (self.appliances_path(), False,)): + for directory, builtin in ((self._builtin_appliances_path(), True,), (self._custom_appliances_path(), False,)): if directory and os.path.isdir(directory): for file in os.listdir(directory): if not file.endswith('.gns3a') and not file.endswith('.gns3appliance'): @@ -181,7 +207,7 @@ class ApplianceManager: from . import Controller Controller.instance().save() json_data = await response.json() - appliances_dir = get_resource('appliances') + appliances_dir = self._builtin_appliances_path() downloaded_appliance_files = [] for appliance in json_data: if appliance["type"] == "file": diff --git a/gns3server/utils/get_resource.py b/gns3server/utils/get_resource.py index b988a200..b4b599bd 100644 --- a/gns3server/utils/get_resource.py +++ b/gns3server/utils/get_resource.py @@ -15,33 +15,18 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -import tempfile -import pkg_resources import atexit import logging import os import sys +import importlib_resources + +from contextlib import ExitStack +resource_manager = ExitStack() +atexit.register(resource_manager.close) log = logging.getLogger(__name__) -try: - egg_cache_dir = tempfile.mkdtemp() - pkg_resources.set_extraction_path(egg_cache_dir) -except ValueError: - # If the path is already set the module throw an error - pass - - -@atexit.register -def clean_egg_cache(): - try: - import shutil - log.debug("Clean egg cache %s", egg_cache_dir) - shutil.rmtree(egg_cache_dir) - except Exception: - # We don't care if we can not cleanup - pass - def get_resource(resource_name): """ @@ -51,7 +36,9 @@ def get_resource(resource_name): resource_path = None if hasattr(sys, "frozen"): resource_path = os.path.normpath(os.path.join(os.path.dirname(sys.executable), resource_name)) - elif not hasattr(sys, "frozen") and pkg_resources.resource_exists("gns3server", resource_name): - resource_path = pkg_resources.resource_filename("gns3server", resource_name) - resource_path = os.path.normpath(resource_path) + else: + ref = importlib_resources.files("gns3server") / resource_name + path = resource_manager.enter_context(importlib_resources.as_file(ref)) + if os.path.exists(path): + resource_path = os.path.normpath(path) return resource_path diff --git a/requirements.txt b/requirements.txt index 735c4eac..5bc393a9 100644 --- a/requirements.txt +++ b/requirements.txt @@ -11,5 +11,6 @@ psutil>=5.9.2,<5.10 async-timeout>=4.0.2,<4.1 distro>=1.7.0 py-cpuinfo>=8.0.0,<8.1 +importlib-resources>=1.3 setuptools>=60.8.1; python_version >= '3.7' setuptools==59.6.0; python_version < '3.7' # v59.6.0 is the last version to support Python 3.6 From 2e550d839e658d5d83a47535ee4931cfaa60bee9 Mon Sep 17 00:00:00 2001 From: grossmj Date: Mon, 7 Nov 2022 20:33:02 +0800 Subject: [PATCH 23/33] Fix tests --- tests/controller/test_controller.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/controller/test_controller.py b/tests/controller/test_controller.py index 48b8d98d..48ba98af 100644 --- a/tests/controller/test_controller.py +++ b/tests/controller/test_controller.py @@ -387,10 +387,10 @@ async def test_load_base_files(controller, config, tmpdir): with open(str(tmpdir / 'iou_l2_base_startup-config.txt'), 'w+') as f: f.write('test') - controller.load_base_files() + controller._load_base_files() assert os.path.exists(str(tmpdir / 'iou_l3_base_startup-config.txt')) - # Check is the file has not been overwrite + # Check is the file has not been overwritten with open(str(tmpdir / 'iou_l2_base_startup-config.txt')) as f: assert f.read() == 'test' From ece47dc279b4113f52a8a6b276b2889d4613a665 Mon Sep 17 00:00:00 2001 From: grossmj Date: Mon, 7 Nov 2022 21:48:45 +0800 Subject: [PATCH 24/33] Upgrade dependencies --- dev-requirements.txt | 2 +- requirements.txt | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/dev-requirements.txt b/dev-requirements.txt index 8355921e..8b0b9a2b 100644 --- a/dev-requirements.txt +++ b/dev-requirements.txt @@ -1,6 +1,6 @@ -rrequirements.txt -pytest==7.1.3; python_version >= '3.7' +pytest==7.2.0; python_version >= '3.7' pytest==7.0.1; python_version < '3.7' # v7.0.1 is the last version to support Python 3.6 flake8==5.0.4 pytest-timeout==2.1.0 diff --git a/requirements.txt b/requirements.txt index 735c4eac..e21f6f00 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,4 @@ -jsonschema>=4.16.0,<4.17; python_version >= '3.7' +jsonschema>=4.17.0,<4.18; python_version >= '3.7' jsonschema==3.2.0; python_version < '3.7' # v3.2.0 is the last version to support Python 3.6 aiohttp>=3.8.3,<3.9 aiohttp-cors>=0.7.0,<0.8 @@ -6,10 +6,10 @@ aiofiles>=22.1.0,<22.2; python_version >= '3.7' aiofiles==0.8.0; python_version < '3.7' # v0.8.0 is the last version to support Python 3.6 Jinja2>=3.1.2,<3.2; python_version >= '3.7' Jinja2==3.0.3; python_version < '3.7' # v3.0.3 is the last version to support Python 3.6 -sentry-sdk==1.9.10,<1.10 -psutil>=5.9.2,<5.10 +sentry-sdk==1.10.1,<1.11 +psutil>=5.9.3,<5.10 async-timeout>=4.0.2,<4.1 distro>=1.7.0 -py-cpuinfo>=8.0.0,<8.1 +py-cpuinfo>=9.0.0,<10.0 setuptools>=60.8.1; python_version >= '3.7' setuptools==59.6.0; python_version < '3.7' # v59.6.0 is the last version to support Python 3.6 From 5696d1ccb750c4fe8f61149d1e620fad46b07150 Mon Sep 17 00:00:00 2001 From: grossmj Date: Mon, 7 Nov 2022 23:59:33 +0800 Subject: [PATCH 25/33] Fix issues with VMnet interface on macOS >= 11.0. Ref #3381 --- gns3server/compute/vmware/__init__.py | 1 + gns3server/compute/vmware/vmware_vm.py | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/gns3server/compute/vmware/__init__.py b/gns3server/compute/vmware/__init__.py index 36121fb0..16ff2500 100644 --- a/gns3server/compute/vmware/__init__.py +++ b/gns3server/compute/vmware/__init__.py @@ -380,6 +380,7 @@ class VMware(BaseManager): if vmnet in vmnet_interfaces and self.is_managed_vmnet(vmnet) is False: vmnet_interfaces.remove(vmnet) + log.debug("VMnet interfaces found: ", vmnet_interfaces) self._vmnets = vmnet_interfaces @property diff --git a/gns3server/compute/vmware/vmware_vm.py b/gns3server/compute/vmware/vmware_vm.py index db8c6b87..52ebcea3 100644 --- a/gns3server/compute/vmware/vmware_vm.py +++ b/gns3server/compute/vmware/vmware_vm.py @@ -465,6 +465,10 @@ class VMwareVM(BaseNode): try: if self._ubridge_hypervisor: + if parse_version(platform.mac_ver()[0]) >= parse_version("11.0.0"): + # give VMware some time to create the bridge interfaces, so they can be found + # by psutil and used by uBridge + await asyncio.sleep(1) for adapter_number in range(0, self._adapters): nio = self._ethernet_adapters[adapter_number].get_nio(0) if nio: From 84914ecfa4c05dedb4199df1092e9ba7c539f86a Mon Sep 17 00:00:00 2001 From: grossmj Date: Tue, 8 Nov 2022 12:54:47 +0800 Subject: [PATCH 26/33] Add debug messages to fix VMnet interface list refresh. Ref https://github.com/GNS3/gns3-gui/issues/3381 --- gns3server/compute/vmware/__init__.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/gns3server/compute/vmware/__init__.py b/gns3server/compute/vmware/__init__.py index 16ff2500..3d836923 100644 --- a/gns3server/compute/vmware/__init__.py +++ b/gns3server/compute/vmware/__init__.py @@ -360,6 +360,8 @@ class VMware(BaseManager): def refresh_vmnet_list(self, ubridge=True): + log.debug("Refreshing VMnet list with uBridge={}".format(ubridge)) + if ubridge: # VMnet host adapters must be present when uBridge is used vmnet_interfaces = self._get_vmnet_interfaces_ubridge() @@ -368,6 +370,7 @@ class VMware(BaseManager): self._vmnets_info = vmnet_interfaces.copy() vmnet_interfaces = list(vmnet_interfaces.keys()) + log.debug("Found {} VMnet interfaces".format(len(vmnet_interfaces))) # remove vmnets already in use for vmware_vm in self._nodes.values(): for used_vmnet in vmware_vm.vmnets: @@ -378,9 +381,9 @@ class VMware(BaseManager): # remove vmnets that are not managed for vmnet in vmnet_interfaces.copy(): if vmnet in vmnet_interfaces and self.is_managed_vmnet(vmnet) is False: + log.debug("{} is not managed by GNS3".format(vmnet)) vmnet_interfaces.remove(vmnet) - log.debug("VMnet interfaces found: ", vmnet_interfaces) self._vmnets = vmnet_interfaces @property From f80aca7633a819bea849eb51b428ed6d123f904f Mon Sep 17 00:00:00 2001 From: grossmj Date: Tue, 8 Nov 2022 18:40:27 +0800 Subject: [PATCH 27/33] Sync appliance files --- gns3server/appliances/alpine-linux-virt.gns3a | 45 +++++++++++++ gns3server/appliances/aruba-arubaoscx.gns3a | 13 ++++ gns3server/appliances/debian.gns3a | 28 ++++---- gns3server/appliances/openwrt.gns3a | 30 +++++++++ gns3server/appliances/reactos.gns3a | 67 +++++++++++++++++++ gns3server/appliances/vyos.gns3a | 45 ++++++++----- 6 files changed, 198 insertions(+), 30 deletions(-) create mode 100644 gns3server/appliances/alpine-linux-virt.gns3a create mode 100644 gns3server/appliances/reactos.gns3a diff --git a/gns3server/appliances/alpine-linux-virt.gns3a b/gns3server/appliances/alpine-linux-virt.gns3a new file mode 100644 index 00000000..d7c2883d --- /dev/null +++ b/gns3server/appliances/alpine-linux-virt.gns3a @@ -0,0 +1,45 @@ +{ + "appliance_id": "3da5c614-772c-4963-af86-f24e058c9216", + "name": "Alpine Linux Virt", + "category": "guest", + "description": "Alpine Linux is a security-oriented, lightweight Linux distribution based on musl libc and busybox.\n\nThis is the qemu version of Alpine Linux, stripped down to the maximum, only the default packages are installed without an SSH server.", + "vendor_name": "Alpine Linux Development Team", + "vendor_url": "http://alpinelinux.org", + "documentation_url": "http://wiki.alpinelinux.org", + "product_name": "Alpine Linux Virt", + "registry_version": 4, + "status": "stable", + "availability": "free", + "maintainer": "Adnan RIHAN", + "maintainer_email": "adnan@rihan.fr", + "usage": "Autologin is enabled as \"root\" with no password.\n\nThe network interfaces aren't configured, you can do either of the following:\n- Use alpine's DHCP client: `udhcpc`\n- Configure them manually (ip address add …, ip route add …)\n- Modify interfaces file in /etc/network/interfaces\n- Use alpine's wizard: `setup-interfaces`", + "symbol": "alpine-virt-qemu.svg", + "port_name_format": "eth{0}", + "qemu": { + "adapter_type": "virtio-net-pci", + "adapters": 1, + "ram": 128, + "hda_disk_interface": "virtio", + "arch": "x86_64", + "console_type": "telnet", + "kvm": "allow" + }, + "images": [ + { + "filename": "alpine-virt-3.16.img", + "version": "3.16", + "md5sum": "ce90ff64b8f8e5860c49ea4a038e54cc", + "filesize": 96468992, + "download_url": "https://sourceforge.net/projects/gns-3/files/Qemu%20Appliances/", + "direct_download_url": "https://sourceforge.net/projects/gns-3/files/Qemu%20Appliances/alpine-virt-3.16.img/download" + } + ], + "versions": [ + { + "name": "3.16", + "images": { + "hda_disk_image": "alpine-virt-3.16.img" + } + } + ] +} diff --git a/gns3server/appliances/aruba-arubaoscx.gns3a b/gns3server/appliances/aruba-arubaoscx.gns3a index db45527b..39afe6a6 100644 --- a/gns3server/appliances/aruba-arubaoscx.gns3a +++ b/gns3server/appliances/aruba-arubaoscx.gns3a @@ -30,6 +30,13 @@ "process_priority": "normal" }, "images": [ + { + "filename": "arubaoscx-disk-image-genericx86-p4-20220815162137.vmdk", + "version": "10.10.1000", + "md5sum": "40f9ddf1e12640376af443b5d982f2f6", + "filesize": 356162560, + "download_url": "https://asp.arubanetworks.com/" + }, { "filename": "arubaoscx-disk-image-genericx86-p4-20220616193419.vmdk", "version": "10.10.0002", @@ -95,6 +102,12 @@ } ], "versions": [ + { + "name": "10.10.1000", + "images": { + "hda_disk_image": "arubaoscx-disk-image-genericx86-p4-20220815162137.vmdk" + } + }, { "name": "10.10.0002", "images": { diff --git a/gns3server/appliances/debian.gns3a b/gns3server/appliances/debian.gns3a index 4b98cc20..a4d33d93 100644 --- a/gns3server/appliances/debian.gns3a +++ b/gns3server/appliances/debian.gns3a @@ -24,20 +24,20 @@ }, "images": [ { - "filename": "debian-11-genericcloud-amd64-20220711-1073.qcow2", - "version": "11.4", - "md5sum": "e8fadf4bbf7324a2e2875a5ba00588e7", - "filesize": 253231104, + "filename": "debian-11-genericcloud-amd64-20220911-1135.qcow2", + "version": "11.5", + "md5sum": "06e481ddd23682af4326226661c13d8f", + "filesize": 254672896, "download_url": "https://cloud.debian.org/images/cloud/bullseye/", - "direct_download_url": "https://cloud.debian.org/images/cloud/bullseye/20220711-1073/debian-11-genericcloud-amd64-20220711-1073.qcow2" + "direct_download_url": "https://cloud.debian.org/images/cloud/bullseye/20220911-1135/debian-11-genericcloud-amd64-20220911-1135.qcow2" }, { - "filename": "debian-10-genericcloud-amd64-20220328-962.qcow2", - "version": "10.12", - "md5sum": "e92dfa1fc779fff807856f6ea6876e42", - "filesize": 232980480, + "filename": "debian-10-genericcloud-amd64-20220911-1135.qcow2", + "version": "10.13", + "md5sum": "9d4d1175bef974caba79dd6ca33d500c", + "filesize": 234749952, "download_url": "https://cloud.debian.org/images/cloud/buster/", - "direct_download_url": "https://cloud.debian.org/images/cloud/buster/20220328-962/debian-10-genericcloud-amd64-20220328-962.qcow2" + "direct_download_url": "https://cloud.debian.org/images/cloud/buster/20220911-1135/debian-10-genericcloud-amd64-20220911-1135.qcow2" }, { "filename": "debian-cloud-init-data.iso", @@ -49,16 +49,16 @@ ], "versions": [ { - "name": "11.4", + "name": "11.5", "images": { - "hda_disk_image": "debian-11-genericcloud-amd64-20220711-1073.qcow2", + "hda_disk_image": "debian-11-genericcloud-amd64-20220911-1135.qcow2", "cdrom_image": "debian-cloud-init-data.iso" } }, { - "name": "10.12", + "name": "10.13", "images": { - "hda_disk_image": "debian-10-genericcloud-amd64-20220328-962.qcow2", + "hda_disk_image": "debian-10-genericcloud-amd64-20220911-1135.qcow2", "cdrom_image": "debian-cloud-init-data.iso" } } diff --git a/gns3server/appliances/openwrt.gns3a b/gns3server/appliances/openwrt.gns3a index 2a293c62..a8bc8bf7 100644 --- a/gns3server/appliances/openwrt.gns3a +++ b/gns3server/appliances/openwrt.gns3a @@ -23,6 +23,24 @@ "kvm": "allow" }, "images": [ + { + "filename": "openwrt-22.03.0-x86-64-generic-ext4-combined.img", + "version": "22.03.0", + "md5sum": "0f9a266bd8a6cdfcaf0b59f7ba103a0e", + "filesize": 126353408, + "download_url": "https://downloads.openwrt.org/releases/22.03.0/targets/x86/64/", + "direct_download_url": "https://downloads.openwrt.org/releases/22.03.0/targets/x86/64/openwrt-22.03.0-x86-64-generic-ext4-combined.img.gz", + "compression": "gzip" + }, + { + "filename": "openwrt-21.02.3-x86-64-generic-ext4-combined.img", + "version": "21.02.3", + "md5sum": "652c432e758420cb8d749139e8bef14b", + "filesize": 126353408, + "download_url": "https://downloads.openwrt.org/releases/21.02.3/targets/x86/64/", + "direct_download_url": "https://downloads.openwrt.org/releases/21.02.3/targets/x86/64/openwrt-21.02.3-x86-64-generic-ext4-combined.img.gz", + "compression": "gzip" + }, { "filename": "openwrt-21.02.1-x86-64-generic-ext4-combined.img", "version": "21.02.1", @@ -196,6 +214,18 @@ } ], "versions": [ + { + "name": "22.03.0", + "images": { + "hda_disk_image": "openwrt-22.03.0-x86-64-generic-ext4-combined.img" + } + }, + { + "name": "21.02.3", + "images": { + "hda_disk_image": "openwrt-21.02.3-x86-64-generic-ext4-combined.img" + } + }, { "name": "21.02.1", "images": { diff --git a/gns3server/appliances/reactos.gns3a b/gns3server/appliances/reactos.gns3a new file mode 100644 index 00000000..391abe95 --- /dev/null +++ b/gns3server/appliances/reactos.gns3a @@ -0,0 +1,67 @@ +{ + "appliance_id": "c811e588-39ef-41e9-9f60-6e8e08618c3d", + "name": "ReactOS", + "category": "guest", + "description": "Imagine running your favorite Windows applications and drivers in an open-source environment you can trust.\nThat's the mission of ReactOS! ", + "vendor_name": "ReactOS Project", + "vendor_url": "https://reactos.org/", + "documentation_url": "https://reactos.org/what-is-reactos/", + "product_name": "ReactOS", + "product_url": "https://reactos.org/", + "registry_version": 3, + "status": "stable", + "maintainer": "Savio D'souza", + "maintainer_email": "savio2002@yahoo.co.in", + "usage": "Passwords are set during installation.", + "qemu": { + "adapter_type": "e1000", + "adapters": 1, + "ram": 1024, + "hda_disk_interface": "ide", + "arch": "x86_64", + "console_type": "vnc", + "kvm": "require" + }, + "images": [ + { + "filename": "ReactOS-0.4.14-release-15-gb6088a6.iso", + "version": "Installer-0.4.14-release-15", + "md5sum": "af4be6b27463446905f155f14232d2b4", + "filesize": 140509184, + "download_url": "https://reactos.org/download", + "direct_download_url": "https://sourceforge.net/projects/reactos/files/ReactOS/0.4.14/ReactOS-0.4.14-release-21-g1302c1b-iso.zip/download" + }, + { + "filename": "ReactOS-0.4.14-release-15-gb6088a6-Live.iso", + "version": "Live-0.4.14-release-15", + "md5sum": "73c1a0169a9a3b8a4feb91f4d00f5e97", + "filesize": 267386880, + "download_url": "https://reactos.org/download", + "direct_download_url": "https://sourceforge.net/projects/reactos/files/ReactOS/0.4.14/ReactOS-0.4.14-release-21-g1302c1b-live.zip/download" + }, + { + "filename": "empty30G.qcow2", + "version": "1.0", + "md5sum": "3411a599e822f2ac6be560a26405821a", + "filesize": 197120, + "download_url": "https://sourceforge.net/projects/gns-3/files/Empty%20Qemu%30disk/", + "direct_download_url": "https://sourceforge.net/projects/gns-3/files/Empty%20Qemu%20disk/empty30G.qcow2/download" + } + ], + "versions": [ + { + "name": "Installer-0.4.14-release-15", + "images": { + "hda_disk_image": "empty30G.qcow2", + "cdrom_image": "ReactOS-0.4.14-release-15-gb6088a6.iso" + } + }, + { + "name": "Live-0.4.14-release-15", + "images": { + "hda_disk_image": "empty30G.qcow2", + "cdrom_image": "ReactOS-0.4.14-release-15-gb6088a6-Live.iso" + } + } + ] +} diff --git a/gns3server/appliances/vyos.gns3a b/gns3server/appliances/vyos.gns3a index 4004a1bc..540bd1ed 100644 --- a/gns3server/appliances/vyos.gns3a +++ b/gns3server/appliances/vyos.gns3a @@ -2,7 +2,7 @@ "appliance_id": "f82b74c4-0f30-456f-a582-63daca528502", "name": "VyOS", "category": "router", - "description": "VyOS is a community fork of Vyatta, a Linux-based network operating system that provides software-based network routing, firewall, and VPN functionality. VyOS has a subscription LTS version and a community rolling release. The latest version in this appliance is the monthly snapshot of the rolling release track.", + "description": "VyOS is a community fork of Vyatta, a Linux-based network operating system that provides software-based network routing, firewall, and VPN functionality.", "vendor_name": "Linux", "vendor_url": "https://vyos.net/", "documentation_url": "https://docs.vyos.io/", @@ -26,6 +26,20 @@ "kvm": "allow" }, "images": [ + { + "filename": "vyos-1.3.2-amd64.iso", + "version": "1.3.2", + "md5sum": "070743faac800f9e5197058a8b6b3ba1", + "filesize": 334495744, + "download_url": "https://support.vyos.io/en/downloads/files/vyos-1-3-2-generic-iso-image" + }, + { + "filename": "vyos-1.3.1-S1-amd64.iso", + "version": "1.3.1-S1", + "md5sum": "781f345e8a4ab9eb9e075ce5c87c8817", + "filesize": 351272960, + "download_url": "https://support.vyos.io/en/downloads/files/vyos-1-3-1-s1-generic-iso-image" + }, { "filename": "vyos-1.3.1-amd64.iso", "version": "1.3.1", @@ -40,14 +54,6 @@ "filesize": 338690048, "download_url": "https://support.vyos.io/en/downloads/files/vyos-1-3-0-generic-iso-image" }, - { - "filename": "vyos-1.3.0-epa3-amd64.iso", - "version": "1.3.0-epa3", - "md5sum": "1b5de684d8995844e35fa5cec3171811", - "filesize": 331350016, - "download_url": "https://vyos.net/get/snapshots/", - "direct_download_url": "https://s3.amazonaws.com/s3-us.vyos.io/snapshot/vyos-1.3.0-epa3/vyos-1.3.0-epa3-amd64.iso" - }, { "filename": "vyos-1.2.8-amd64.iso", "version": "1.2.8", @@ -80,6 +86,20 @@ } ], "versions": [ + { + "name": "1.3.2", + "images": { + "hda_disk_image": "empty8G.qcow2", + "cdrom_image": "vyos-1.3.2-amd64.iso" + } + }, + { + "name": "1.3.1-S1", + "images": { + "hda_disk_image": "empty8G.qcow2", + "cdrom_image": "vyos-1.3.1-S1-amd64.iso" + } + }, { "name": "1.3.1", "images": { @@ -94,13 +114,6 @@ "cdrom_image": "vyos-1.3.0-amd64.iso" } }, - { - "name": "1.3.0-epa3", - "images": { - "hda_disk_image": "empty8G.qcow2", - "cdrom_image": "vyos-1.3.0-epa3-amd64.iso" - } - }, { "name": "1.2.8", "images": { From 521132726e555efc793b946645e2f3cd53eb11f4 Mon Sep 17 00:00:00 2001 From: grossmj Date: Tue, 8 Nov 2022 18:49:31 +0800 Subject: [PATCH 28/33] Upgrade psutil to v5.9.4 --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 4394f028..39c2c7d2 100644 --- a/requirements.txt +++ b/requirements.txt @@ -7,7 +7,7 @@ aiofiles==0.8.0; python_version < '3.7' # v0.8.0 is the last version to support Jinja2>=3.1.2,<3.2; python_version >= '3.7' Jinja2==3.0.3; python_version < '3.7' # v3.0.3 is the last version to support Python 3.6 sentry-sdk==1.10.1,<1.11 -psutil>=5.9.3,<5.10 +psutil>=5.9.4,<5.10 async-timeout>=4.0.2,<4.1 distro>=1.7.0 py-cpuinfo>=9.0.0,<10.0 From 18ba60d1a339148274f7e4a93f044764cba18064 Mon Sep 17 00:00:00 2001 From: grossmj Date: Tue, 8 Nov 2022 19:18:07 +0800 Subject: [PATCH 29/33] Downgrade psutil to v5.9.2 --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 39c2c7d2..53f1200d 100644 --- a/requirements.txt +++ b/requirements.txt @@ -7,7 +7,7 @@ aiofiles==0.8.0; python_version < '3.7' # v0.8.0 is the last version to support Jinja2>=3.1.2,<3.2; python_version >= '3.7' Jinja2==3.0.3; python_version < '3.7' # v3.0.3 is the last version to support Python 3.6 sentry-sdk==1.10.1,<1.11 -psutil>=5.9.4,<5.10 +psutil==5.9.2 async-timeout>=4.0.2,<4.1 distro>=1.7.0 py-cpuinfo>=9.0.0,<10.0 From 284a4b62fb651e6b7816c89da218c20a8c9f13b6 Mon Sep 17 00:00:00 2001 From: grossmj Date: Tue, 8 Nov 2022 22:50:59 +0800 Subject: [PATCH 30/33] Fix copying appliances and configs when app is frozen --- gns3server/controller/__init__.py | 16 +++++++++++----- gns3server/controller/appliance_manager.py | 18 ++++++++++++------ 2 files changed, 23 insertions(+), 11 deletions(-) diff --git a/gns3server/controller/__init__.py b/gns3server/controller/__init__.py index a3c16fb3..936b680a 100644 --- a/gns3server/controller/__init__.py +++ b/gns3server/controller/__init__.py @@ -278,11 +278,17 @@ class Controller: dst_path = self.configs_path() try: - for entry in importlib_resources.files('gns3server.configs').iterdir(): - full_path = os.path.join(dst_path, entry.name) - if entry.is_file() and not os.path.exists(full_path): - log.debug(f"Installing base config file {entry.name} to {full_path}") - shutil.copy(str(entry), os.path.join(dst_path, entry.name)) + if hasattr(sys, "frozen"): + resource_path = os.path.normpath(os.path.join(os.path.dirname(sys.executable), "configs")) + for filename in os.listdir(resource_path): + if not os.path.exists(os.path.join(dst_path, filename)): + shutil.copy(os.path.join(resource_path, filename), os.path.join(dst_path, filename)) + else: + for entry in importlib_resources.files('gns3server.configs').iterdir(): + full_path = os.path.join(dst_path, entry.name) + if entry.is_file() and not os.path.exists(full_path): + log.debug(f"Installing base config file {entry.name} to {full_path}") + shutil.copy(str(entry), os.path.join(dst_path, entry.name)) except OSError as e: log.error(f"Could not install base config files to {dst_path}: {e}") diff --git a/gns3server/controller/appliance_manager.py b/gns3server/controller/appliance_manager.py index b9349152..e0c74df6 100644 --- a/gns3server/controller/appliance_manager.py +++ b/gns3server/controller/appliance_manager.py @@ -15,6 +15,7 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . +import sys import os import json import uuid @@ -26,7 +27,6 @@ import shutil from .appliance import Appliance from ..config import Config from ..utils.asyncio import locking -from ..utils.get_resource import get_resource import logging log = logging.getLogger(__name__) @@ -93,11 +93,17 @@ class ApplianceManager: dst_path = self._builtin_appliances_path() try: - for entry in importlib_resources.files('gns3server.appliances').iterdir(): - full_path = os.path.join(dst_path, entry.name) - if entry.is_file() and not os.path.exists(full_path): - log.debug(f"Installing built-in appliance file {entry.name} to {full_path}") - shutil.copy(str(entry), os.path.join(dst_path, entry.name)) + if hasattr(sys, "frozen"): + resource_path = os.path.normpath(os.path.join(os.path.dirname(sys.executable), "appliances")) + for filename in os.listdir(resource_path): + if not os.path.exists(os.path.join(dst_path, filename)): + shutil.copy(os.path.join(resource_path, filename), os.path.join(dst_path, filename)) + else: + for entry in importlib_resources.files('gns3server.appliances').iterdir(): + full_path = os.path.join(dst_path, entry.name) + if entry.is_file() and not os.path.exists(full_path): + log.debug(f"Installing built-in appliance file {entry.name} to {full_path}") + shutil.copy(str(entry), os.path.join(dst_path, entry.name)) except OSError as e: log.error(f"Could not install built-in appliance files to {dst_path}: {e}") From c80a55b18c5137d730e18101c6d1315211a263e6 Mon Sep 17 00:00:00 2001 From: grossmj Date: Tue, 8 Nov 2022 23:07:45 +0800 Subject: [PATCH 31/33] Install appliances and configs without importlib_resources for Windows only --- gns3server/controller/__init__.py | 2 +- gns3server/controller/appliance_manager.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/gns3server/controller/__init__.py b/gns3server/controller/__init__.py index 936b680a..5c5236b9 100644 --- a/gns3server/controller/__init__.py +++ b/gns3server/controller/__init__.py @@ -278,7 +278,7 @@ class Controller: dst_path = self.configs_path() try: - if hasattr(sys, "frozen"): + if hasattr(sys, "frozen") and sys.platform.startswith("win"): resource_path = os.path.normpath(os.path.join(os.path.dirname(sys.executable), "configs")) for filename in os.listdir(resource_path): if not os.path.exists(os.path.join(dst_path, filename)): diff --git a/gns3server/controller/appliance_manager.py b/gns3server/controller/appliance_manager.py index e0c74df6..d15fc69b 100644 --- a/gns3server/controller/appliance_manager.py +++ b/gns3server/controller/appliance_manager.py @@ -93,7 +93,7 @@ class ApplianceManager: dst_path = self._builtin_appliances_path() try: - if hasattr(sys, "frozen"): + if hasattr(sys, "frozen") and sys.platform.startswith("win"): resource_path = os.path.normpath(os.path.join(os.path.dirname(sys.executable), "appliances")) for filename in os.listdir(resource_path): if not os.path.exists(os.path.join(dst_path, filename)): From 338128ca3e4d9332c072368986cdaa99b198a7eb Mon Sep 17 00:00:00 2001 From: grossmj Date: Tue, 8 Nov 2022 23:39:10 +0800 Subject: [PATCH 32/33] Upgrade pywin32 to v305 --- win-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/win-requirements.txt b/win-requirements.txt index 1a93fbb1..b2453b87 100644 --- a/win-requirements.txt +++ b/win-requirements.txt @@ -1,4 +1,4 @@ -rrequirements.txt -pywin32==304 +pywin32==305 wmi==1.5.1 From 1aca7dbe045293be7548f96eeca0049b0167a39a Mon Sep 17 00:00:00 2001 From: grossmj Date: Tue, 8 Nov 2022 23:40:25 +0800 Subject: [PATCH 33/33] Release v2.2.35 --- CHANGELOG | 15 +++++++++++++++ gns3server/crash_report.py | 2 +- gns3server/version.py | 4 ++-- 3 files changed, 18 insertions(+), 3 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index bf59e33f..19d82820 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,20 @@ # Change Log +## 2.2.35 08/11/2022 + +* Release web-ui v2.2.35 +* Fix issues with VMnet interface on macOS >= 11.0. Ref #3381 +* Use importlib_resources instead of pkg_resources and install built-in appliances in config dir. +* Fix console vnc don't use configured ports in some case. Fixes #2111 +* Add missing VMware settings in gns3_server.conf +* Make version PEP 440 compliant +* Support for Python 3.11 +* Allow for more dependency versions at patch level +* Replace deprecated distro.linux_distribution() call +* Update gns3.service.systemd +* gns3.service.openrc: make openrc script posix compliant +* fix: use exact match to find interface in windows to avoid get wrong interface + ## 2.2.34 28/08/2022 * Use original $PATH in init.sh for Docker containers. Ref #2069 diff --git a/gns3server/crash_report.py b/gns3server/crash_report.py index 459d2e5d..36a75f16 100644 --- a/gns3server/crash_report.py +++ b/gns3server/crash_report.py @@ -58,7 +58,7 @@ class CrashReport: Report crash to a third party service """ - DSN = "https://3f074423e7664595923ae5895b0819c4@o19455.ingest.sentry.io/38482" + DSN = "https://67695b9b3995495d9445159d973d2f0d@o19455.ingest.sentry.io/38482" _instance = None def __init__(self): diff --git a/gns3server/version.py b/gns3server/version.py index f0cb635e..4f912448 100644 --- a/gns3server/version.py +++ b/gns3server/version.py @@ -23,8 +23,8 @@ # or negative for a release candidate or beta (after the base version # number has been incremented) -__version__ = "2.2.35.dev2" -__version_info__ = (2, 2, 35, 99) +__version__ = "2.2.35" +__version_info__ = (2, 2, 35, 0) if "dev" in __version__: try: