Compare commits

...

98 Commits

Author SHA1 Message Date
grossmj
705cbf8bb9 Release v2.2.39 2023-05-08 19:17:02 +08:00
Jeremy Grossmann
ab6e0ce496 Merge pull request #3461 from GNS3/fix/3441
Fix nodes are not snapped to the grid at the moment of creation
2023-05-08 17:13:20 +08:00
grossmj
8042c9eb6f Fix tests 2023-05-08 17:08:10 +08:00
grossmj
ad3c8a09db Fix nodes are not snapped to the grid at the moment of creation 2023-04-23 05:18:02 -10:00
grossmj
ea4a7f201e Upgrade sentry-sdk 2023-03-23 21:41:50 -10:00
grossmj
28c82b8718 Upgrade distro and aiohttp dependencies 2023-03-01 18:03:28 +10:00
grossmj
6a4dd59e81 Development on 2.2.39.dev1 2023-02-28 17:09:39 +10:00
grossmj
737e32f5c3 Release v2.2.38 2023-02-28 15:35:17 +10:00
grossmj
cfc09d2c14 Merge branch 'master' into 2.2 2023-02-28 15:07:07 +10:00
grossmj
f6ab5cae16 Add long description content type in setup.py 2023-02-01 09:56:02 +08:00
grossmj
39ec7eb8ea Automatically add new issues to GNS3 project 2023-01-31 09:31:52 +08:00
grossmj
64c579d43c Development 2.2.38.dev1 2023-01-25 18:36:39 +08:00
grossmj
98cc82e6fd Release v2.2.37 2023-01-25 15:06:12 +08:00
grossmj
4b795112b4 Merge branch 'master' into 2.2 2023-01-25 14:44:11 +08:00
grossmj
0e186afaf1 Comment AllocConsole() 2023-01-25 14:41:55 +08:00
grossmj
b218f7fdf8 Bump version to 2.2.37.dev3 2023-01-25 14:13:07 +08:00
grossmj
f1cb6d66f3 Try to fix hiding console. Ref #3290 2023-01-25 14:08:52 +08:00
grossmj
29758f1b4f Debug win32console 2023-01-24 22:25:39 +08:00
grossmj
445dcf3e3b Upgrade to PyQt5 v5.15.7 2023-01-24 18:54:15 +08:00
grossmj
f623f28509 Add venv to .gitignore 2023-01-17 13:40:37 +08:00
grossmj
9d02d57162 Bump version to 2.2.37.dev2 2023-01-17 13:30:09 +08:00
Jeremy Grossmann
df03f50e3d Merge pull request #3427 from eantowne/master
Changed Windows Terminal telnet console profile from OS X to Windows ref: #3193
2023-01-17 05:52:31 +05:45
Ean Towne
3b72a66ca5 Changed Windows Terminal telnet console profile from OS X to windows ref: issue #3193 2023-01-16 16:50:57 -05:00
grossmj
f8aee44442 Fix tests 2023-01-10 08:42:25 +08:00
grossmj
6dd4d1700e Convert README to Markdown 2023-01-10 08:16:17 +08:00
grossmj
9b674669db Development on 2.2.37.dev1 2023-01-05 09:13:30 +08:00
grossmj
53073d458f Merge branch '2.2' 2023-01-05 09:12:01 +08:00
grossmj
957d89d450 Release v2.2.36 2023-01-04 19:46:30 +08:00
Jeremy Grossmann
db02cbdb2f Merge pull request #3421 from GNS3/qemu-tpm-support
Trusted Platform Module (TPM) support for Qemu VMs
2023-01-04 10:55:52 +05:45
grossmj
0c9f70152f Add checkbox to enable TPM 2023-01-04 12:45:40 +08:00
grossmj
9016975958 Add Trusted Platform Module (TPM) support for Qemu VMs 2023-01-04 12:13:19 +08:00
grossmj
bf295060fd Add "on_close" setting to appliance schema. Fixes https://github.com/GNS3/gns3-server/issues/2148 2023-01-01 16:23:17 +08:00
grossmj
c22ec9f8bd Add default 'ide' disk interface when manually creating Qemu VM template. Fixes #3360 2022-12-29 08:54:40 +08:00
grossmj
bb49cadc6a Fix zoom factor is multiplied when loading projects. Fixes #3408 2022-12-29 08:49:10 +08:00
grossmj
131a49160c Update sentry-sdk dependency 2022-12-28 15:13:26 +08:00
grossmj
225b829eae Fix syntax error in .whitesource 2022-12-27 12:27:26 +08:00
grossmj
e5ef6180b1 Add more base branches for Mend to scan 2022-12-27 12:25:49 +08:00
grossmj
6e7947eea3 Remove deprecated PuTTY option in preferences. Ref https://github.com/GNS3/gns3-gui/discussions/3415 2022-12-24 11:19:29 +08:00
Jeremy Grossmann
3922d370a8 Create SECURITY.md 2022-12-20 21:28:08 +08:00
grossmj
833b9d00c9 Upgrade dependencies 2022-12-18 14:14:56 +08:00
Jeremy Grossmann
377b8dfcaf Create codeql.yml 2022-12-18 14:08:00 +08:00
grossmj
e68937475f Development on v2.2.36.dev2 2022-11-11 00:36:47 +08:00
grossmj
6f418f0853 Release v2.2.35.1 2022-11-10 22:21:14 +08:00
grossmj
8e59927ada Merge branch 'master' into 2.2 2022-11-10 22:06:25 +08:00
grossmj
1012686053 Development on 2.2.36.dev1 2022-11-09 20:02:20 +08:00
grossmj
672bd850ad Merge branch '2.2' 2022-11-09 20:00:38 +08:00
grossmj
5db5e1f9fe Release v2.2.35 2022-11-08 23:40:25 +08:00
grossmj
ca94c71bf2 Use Visual Studio 2022 in appveyor.yml 2022-11-08 23:09:23 +08:00
grossmj
76264c55ce Merge branch 'master' into 2.2 2022-11-08 19:29:49 +08:00
grossmj
fd243c42a8 Downgrade psutil to v5.9.2 2022-11-08 19:18:07 +08:00
grossmj
a6521ef9e4 Upgrade psutil to v5.9.4 2022-11-08 18:49:31 +08:00
grossmj
9fa833762c Upgrade pywin32 to v305 2022-11-08 18:29:51 +08:00
grossmj
ca0c6468b5 Fix "variables": [] in project file leads to unlimited increase of empty name/value pairs in GUI. Fixes #3397 2022-11-07 22:29:02 +08:00
grossmj
15f6945a94 Upgrade dependencies 2022-11-07 21:48:45 +08:00
grossmj
645deb8c79 Ignore local revision when comparing versions. 2022-11-07 20:03:05 +08:00
grossmj
428f12a2b3 Make version PEP 440 compliant 2022-11-06 17:51:31 +08:00
grossmj
9ad5760ee6 Support for Python 3.11 2022-10-30 19:04:54 +08:00
grossmj
82fc4fb3c9 Revert "Fix issue when using tail.exe with non-ascii paths. Fixes #3021"
This reverts commit df42147d92.
2022-10-19 19:38:43 +08:00
grossmj
df42147d92 Fix issue when using tail.exe with non-ascii paths. Fixes #3021 2022-10-19 19:04:29 +08:00
grossmj
da5520aa90 Upgrade PyQt to 5.15.7 and pywin32 to v304 2022-10-19 18:31:40 +08:00
Jeremy Grossmann
491c66a315 Merge pull request #3395 from GNS3/fix/3393
Update requirements.txt
2022-10-18 22:30:11 +08:00
Jeremy Grossmann
e5c81da700 Merge branch '2.2' into fix/3393 2022-10-18 22:28:32 +08:00
grossmj
65fad1b4f4 Upgrade to Visual Studio 2022 in appveyor.yml 2022-10-18 21:47:10 +08:00
grossmj
34661908d9 Upgrade to Python 3.7 in appveyor.yml 2022-10-18 21:42:51 +08:00
grossmj
aee5ffa17f Upgrade pip and setuptools in appveyor.yml 2022-10-18 21:40:08 +08:00
grossmj
e9e8be42b5 Upgrade pytest. Fixes #3399 2022-10-18 21:16:46 +08:00
grossmj
ae0d928383 Use jsonschema v3.2.0 for Python 3.6 2022-10-12 22:13:34 +08:00
grossmj
8db3c1be42 Allow for more dependency versions at patch level 2022-10-12 22:07:37 +08:00
grossmj
f50da3ebd7 Replace deprecated distro.linux_distribution() call 2022-10-11 23:28:11 +08:00
grossmj
75b52fc9a4 Update dev-requirements.txt 2022-10-11 23:23:15 +08:00
grossmj
1952da5876 Update requirements.txt 2022-10-11 23:01:24 +08:00
Jeremy Grossmann
1f620026d4 Merge pull request #3394 from KaisenCAS/master
CVE-2007-4559 patch
2022-10-10 23:31:52 +08:00
grossmj
1d293618e5 Upgrade dependencies 2022-10-10 14:29:04 +08:00
Kevin Chevreuil - Kaisen
2622549ce6 Add a fix for the CVE-2007-4559 2022-10-09 22:55:15 +02:00
grossmj
900bd1c0b4 Development on 2.2.35dev1 2022-08-29 11:14:44 +02:00
grossmj
0b3dbb2843 Release v2.2.34 2022-08-28 23:28:12 +02:00
grossmj
ef4f6b2b27 Upgrade Sentry dependency 2022-08-28 00:02:54 +02:00
grossmj
e9806345ca Downgrade to pytest v7.0.1 (last version to support 2022-08-27 19:35:36 +02:00
grossmj
ee23e32c75 Upgrade dev dependencies 2022-08-27 19:29:42 +02:00
grossmj
fbeacdcb2a Implement new option (Delete All) to contextual menu in "Console" dock. Fixes #3325 2022-08-16 17:48:58 +02:00
grossmj
b3937c7b94 Fix 2560x1440 resolution for Docker container 2022-08-07 23:56:11 +02:00
grossmj
f2711732db Back to development on v2.2.34dev2 2022-06-21 11:52:58 +02:00
grossmj
148ac4b072 Revert "Development on v2.2.34dev2"
This reverts commit 65eeb79b26.
2022-06-21 11:51:01 +02:00
grossmj
65eeb79b26 Development on v2.2.34dev2 2022-06-21 11:38:09 +02:00
grossmj
537304ce08 Release v2.2.33.1 2022-06-21 10:48:02 +02:00
grossmj
f22df5f016 Development on v2.2.34dev1 2022-06-20 21:47:42 +02:00
grossmj
8dfc8b7714 Release v2.2.33 2022-06-20 20:53:21 +02:00
grossmj
8c6fa9433f Upgrade sentry-sdk and psutil 2022-06-20 20:05:34 +02:00
Jeremy Grossmann
63837578c5 Merge pull request #3340 from GNS3/node-name-checks
Check node names
2022-06-20 19:02:37 +02:00
grossmj
b719703dbe Check that node names for Qemu and Docker are valid 2022-06-18 16:59:14 +02:00
grossmj
084d14c17e Backport reset all console connections. Fixes #2072 2022-06-15 15:58:15 +02:00
grossmj
8c0fca1dd7 Add more video resolutions to Docker containers using VNC. Fixes #3329 2022-06-09 00:26:39 +08:00
grossmj
863d05c923 Add python_requires=">=3.4" in setup.py. Fixes #3326 2022-06-07 18:27:01 +08:00
grossmj
3ebaac8a2c Only allow post release corrective versions of GUI and server to interact 2022-06-07 18:22:06 +08:00
grossmj
16878c9dfa Allow minor versions of GUI and server to interact 2022-06-07 18:06:53 +08:00
grossmj
45da18bb7c Update VirtViewer path. Fixes #3334 2022-06-07 17:35:55 +08:00
grossmj
7a6d06ea0c Development on 2.2.33dev1 2022-04-27 19:51:24 +07:00
grossmj
d371042647 Upgrade distro package to v1.7.0 2022-04-27 19:48:50 +07:00
46 changed files with 497 additions and 146 deletions

View File

@@ -0,0 +1,16 @@
name: Add new issues to GNS3 project
on:
issues:
types:
- opened
jobs:
add-to-project:
name: Add issue to project
runs-on: ubuntu-latest
steps:
- uses: actions/add-to-project@v0.4.0
with:
project-url: https://github.com/orgs/GNS3/projects/3
github-token: ${{ secrets.ADD_NEW_ISSUES_TO_PROJECT }}

76
.github/workflows/codeql.yml vendored Normal file
View File

@@ -0,0 +1,76 @@
# For most projects, this workflow file will not need changing; you simply need
# to commit it to your repository.
#
# You may wish to alter this file to override the set of languages analyzed,
# or to provide custom queries or build logic.
#
# ******** NOTE ********
# We have attempted to detect the languages in your repository. Please check
# the `language` matrix defined below to confirm you have the correct set of
# supported CodeQL languages.
#
name: "CodeQL"
on:
push:
branches: [ "master" ]
pull_request:
# The branches below must be a subset of the branches above
branches: [ "master" ]
schedule:
- cron: '27 6 * * 2'
jobs:
analyze:
name: Analyze
runs-on: ubuntu-latest
permissions:
actions: read
contents: read
security-events: write
strategy:
fail-fast: false
matrix:
language: [ 'python' ]
# CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ]
# Use only 'java' to analyze code written in Java, Kotlin or both
# Use only 'javascript' to analyze code written in JavaScript, TypeScript or both
# Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support
steps:
- name: Checkout repository
uses: actions/checkout@v3
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v2
with:
languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file.
# By default, queries listed here will override any specified in a config file.
# Prefix the list here with "+" to use these queries and those in the config file.
# Details on CodeQL's query packs refer to : https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs
# queries: security-extended,security-and-quality
# Autobuild attempts to build any compiled languages (C/C++, C#, Go, or Java).
# If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild
uses: github/codeql-action/autobuild@v2
# Command-line programs to run using the OS shell.
# 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
# If the Autobuild fails above, remove it and uncomment the following three lines.
# modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance.
# - run: |
# echo "Run, Build Application using script"
# ./location_of_script_within_repo/buildscript.sh
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v2
with:
category: "/language:${{matrix.language}}"

1
.gitignore vendored
View File

@@ -63,3 +63,4 @@ __pycache__
# Virtualenv
env
venv

View File

@@ -2,7 +2,8 @@
"scanSettings": {
"configMode": "AUTO",
"configExternalURL": "",
"projectToken" : ""
"projectToken" : "",
"baseBranches": ["master", "2.2", "3.0"]
},
"checkRunSettings": {
"vulnerableCheckRunConclusionLevel": "failure"

View File

@@ -1,5 +1,65 @@
# Change Log
## 2.2.39 08/05/2023
* Fix nodes are not snapped to the grid at the moment of creation
* Upgrade distro and aiohttp dependencies
## 2.2.38 28/02/2023
* Add long description content type in setup.py
* Automatically add new issues to GNS3 project
* Development 2.2.38.dev1
## 2.2.37 25/01/2023
* Upgrade to PyQt5 v5.15.7
* Changed Windows Terminal telnet console profile from OS X to windows ref: issue #3193
## 2.2.36 04/01/2023
* Add Trusted Platform Module (TPM) support for Qemu VMs
* Add "on_close" setting to appliance schema. Fixes https://github.com/GNS3/gns3-server/issues/2148
* Add default 'ide' disk interface when manually creating Qemu VM template. Fixes #3360
* Fix zoom factor is multiplied when loading projects. Fixes #3408
* Remove deprecated PuTTY option in preferences. Ref https://github.com/GNS3/gns3-gui/discussions/3415
## 2.2.35.1 10/11/2022
* Re-release Web-Ui v2.2.35
## 2.2.35 08/11/2022
* Fix "variables": [] in project file leads to unlimited increase of empty name/value pairs in GUI. Fixes #3397
* Make version PEP 440 compliant
* Support for Python 3.11
* Upgrade PyQt to 5.15.7 and pywin32 to v305
* Allow for more dependency versions at patch level
* Replace deprecated distro.linux_distribution() call
* Add a fix for the CVE-2007-4559
## 2.2.34 28/08/2022
* Upgrade dev dependencies
* Implement new option (Delete All) to contextual menu in "Console" dock. Fixes #3325
* Fix 2560x1440 resolution for Docker container
## 2.2.33.1 21/06/2022
* Match GNS3 server version
## 2.2.33 20/06/2022
* Upgrade sentry-sdk and psutil
* Check that node names for Qemu and Docker are valid
* Backport reset all console connections. Fixes #2072
* Add more video resolutions to Docker containers using VNC. Fixes #3329
* Add python_requires=">=3.4" in setup.py. Fixes #3326
* Only allow post release corrective versions of GUI and server to interact
* Allow minor versions of GUI and server to interact
* Update VirtViewer path. Fixes #3334
## 2.2.32 27/04/2022
* Use public DSNs for Sentry

View File

@@ -1,4 +1,4 @@
include README.rst
include README.md
include AUTHORS
include LICENSE
include MANIFEST.in

62
README.md Normal file
View File

@@ -0,0 +1,62 @@
GNS3-gui
========
[![image](https://github.com/GNS3/gns3-gui/workflows/testing/badge.svg)](https://github.com/GNS3/gns3-gui/actions?query=workflow%3Atesting)
[![image](https://img.shields.io/pypi/v/gns3-gui.svg)](https://pypi.python.org/pypi/gns3-gui)
[![image](https://snyk.io/test/github/GNS3/gns3-gui/badge.svg)](https://snyk.io/test/github/GNS3/gns3-gui)
GNS3 GUI repository.
Installation
------------
Please see <https://docs.gns3.com/>
Software dependencies
---------------------
PyQt5 which is either part of the Linux distribution or installable from
PyPi. The other Python dependencies are automatically installed during
the GNS3 GUI installation and are listed
[here](https://github.com/GNS3/gns3-gui/blob/master/requirements.txt)
For connecting to nodes using Telnet, a Telnet client is required. On
Linux that's a terminal emulator like xterm, gnome-terminal, konsole
plus the telnet program. For connecting to nodes with a GUI, a VNC
client is required, optionally a SPICE client can be used for Qemu
nodes.
For using packet captures within GNS3, Wireshark should be installed.
It's recommended, but if you don't need that functionality you can go
without it.
Development
-----------
If you want to update the interface, modify the .ui files using QT
tools. And:
``` {.bash}
cd scripts
python build_pyqt.py
```
### Debug
If you want to see the full logs in the internal shell you can type:
``` {.bash}
debug 2
```
Or start the app with --debug flag.
Due to the fact PyQT intercept you can use a web debugger for inspecting
stuff: <https://github.com/Kozea/wdb>
Security issues
---------------
Please contact us at <security@gns3.net>

View File

@@ -1,60 +0,0 @@
GNS3-gui
========
.. image:: https://github.com/GNS3/gns3-gui/workflows/testing/badge.svg
:target: https://github.com/GNS3/gns3-gui/actions?query=workflow%3Atesting
.. image:: https://img.shields.io/pypi/v/gns3-gui.svg
:target: https://pypi.python.org/pypi/gns3-gui
.. image:: https://snyk.io/test/github/GNS3/gns3-gui/badge.svg
:target: https://snyk.io/test/github/GNS3/gns3-gui
GNS3 GUI repository.
Installation
------------
Please see https://docs.gns3.com/
Software dependencies
---------------------
PyQt5 which is either part of the Linux distribution or installable from PyPi. The other Python dependencies are automatically installed during the GNS3 GUI installation and are listed `here <https://github.com/GNS3/gns3-gui/blob/master/requirements.txt>`_
For connecting to nodes using Telnet, a Telnet client is required. On Linux that's a terminal emulator like xterm, gnome-terminal, konsole plus the telnet program. For connecting to nodes with a GUI, a VNC client is required, optionally a SPICE client can be used for Qemu nodes.
For using packet captures within GNS3, Wireshark should be installed. It's recommended, but if you don't need that functionality you can go without it.
Development
-------------
If you want to update the interface, modify the .ui files using QT tools. And:
.. code:: bash
cd scripts
python build_pyqt.py
Debug
"""""
If you want to see the full logs in the internal shell you can type:
.. code:: bash
debug 2
Or start the app with --debug flag.
Due to the fact PyQT intercept you can use a web debugger for inspecting stuff:
https://github.com/Kozea/wdb
Security issues
----------------
Please contact us at security@gns3.net

5
SECURITY.md Normal file
View File

@@ -0,0 +1,5 @@
# Security Policy
## Reporting a Vulnerability
Please use GitHub's report a vulnerability feature. More information can be found in https://docs.github.com/en/code-security/security-advisories/guidance-on-reporting-and-writing/privately-reporting-a-security-vulnerability

View File

@@ -1,15 +1,16 @@
version: '{build}-{branch}'
image: Visual Studio 2017
image: Visual Studio 2022
platform: x64
environment:
PYTHON: "C:\\Python36-x64"
PYTHON: "C:\\Python37-x64"
DISTUTILS_USE_SDK: "1"
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"

View File

@@ -1,5 +1,6 @@
-rrequirements.txt
pytest==6.2.4
flake8==3.9.2
pytest-timeout==1.4.2
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

View File

@@ -22,7 +22,7 @@ import inspect
import datetime
import platform
from .qt import QtCore
from .qt import QtCore, QtWidgets
from .topology import Topology
from .version import __version__
from .console_cmd import ConsoleCmd
@@ -109,6 +109,29 @@ class ConsoleView(PyCutExt, ConsoleCmd):
self.stdout = sys.stdout
self._topology = Topology.instance()
def contextMenuEvent(self, event):
"""
Handles all context menu events.
:param event: QContextMenuEvent instance
"""
menu = self.createStandardContextMenu()
delete_all_action = QtWidgets.QAction("Delete All", menu)
delete_all_action.triggered.connect(self._deleteAllActionSlot)
menu.addAction(delete_all_action)
menu.exec_(event.globalPos());
def _deleteAllActionSlot(self):
"""
Delete all action slot
"""
self.clear()
self.write(self.prompt)
self.lines = []
self._clearLine()
def _writeMessageSlot(self, message, level):
"""
Write a message in the console.

View File

@@ -51,7 +51,7 @@ class CrashReport:
Report crash to a third party service
"""
DSN = "https://8aa9e09917494af7b7def60f0aed8512@o19455.ingest.sentry.io/38506"
DSN = "https://de4e2c3e542f47149bf89dffb48491ae@o19455.ingest.sentry.io/38506"
_instance = None
def __init__(self):
@@ -86,7 +86,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),
}

View File

@@ -46,19 +46,11 @@ class EditProjectDialog(QtWidgets.QDialog, Ui_EditProjectDialog):
self.uiNewVarButton.clicked.connect(self.onAddNewVariable)
self.uiGlobalVariablesGrid.addWidget(self.uiNewVarButton, 0, 3, QtCore.Qt.AlignRight)
self._variables = self.setUpVariables()
self._variables = self._project.variables()
if not self._variables:
self._variables = [{"name": "", "value": ""}]
self.updateGlobalVariables()
def setUpVariables(self):
new_variable = {"name": "", "value": ""}
variables = self._project.variables()
if variables is not None:
variables.append(new_variable)
else:
variables = [new_variable]
return variables
def updateGlobalVariables(self):
while True:
item = self.uiGlobalVariablesGrid.takeAt(1)

View File

@@ -121,8 +121,6 @@ class GraphicsView(QtWidgets.QGraphicsView):
def setZoom(self, zoom):
"""
Sets zoom of the Graphics View
:param zoom:
:return:
"""
if zoom:
factor = zoom / 100.
@@ -193,6 +191,9 @@ class GraphicsView(QtWidgets.QGraphicsView):
# clear all objects on the scene
self.scene().clear()
# reset zoom / scale
self.resetTransform()
def _loadSettings(self):
"""

View File

@@ -404,17 +404,12 @@ class HTTPClient(QtCore.QObject):
self._query_waiting_connections = []
return
if params["version"].split("-")[0] != __version__.split("-")[0]:
if params["version"].split("+")[0] != __version__.split("+")[0]:
msg = "Client version {} is not the same as server (controller) version {}".format(__version__, params["version"])
# Stable release
if __version_info__[3] == 0:
log.error(msg)
for request, callback in self._query_waiting_connections:
if callback is not None:
callback({"message": msg}, error=True, server=server)
return
# We don't allow different major version to interact even with dev build
elif parse_version(__version__)[:2] != parse_version(params["version"])[:2]:
# We don't allow different versions to interact even with dev build
# (excepting post release corrections e.g 2.2.32.1, occassionally done when fixing a packaging problem)
# TODO: we should probably follow this standard starting with v3.0: https://semver.org/
if parse_version(__version__)[:3] != parse_version(params["version"])[:3]:
log.error(msg)
for request, callback in self._query_waiting_connections:
if callback is not None:

View File

@@ -213,7 +213,7 @@ class DrawingItem:
def itemChange(self, change, value):
if change == QtWidgets.QGraphicsItem.ItemPositionChange and self.isActive() and self._main_window.uiSnapToGridAction.isChecked():
if change == QtWidgets.QGraphicsItem.ItemPositionChange and self._main_window.uiSnapToGridAction.isChecked():
grid_size = self._graphics_view.drawingGridSize()
mid_x = self.boundingRect().width() / 2
value.setX((grid_size * round((value.x() + mid_x) / grid_size)) - mid_x)

View File

@@ -108,6 +108,9 @@ class NodeItem(QtSvg.QGraphicsSvgItem):
if node.initialized():
self.createdSlot(node.id())
if self._main_window.uiSnapToGridAction.isChecked():
self.setPos(QtCore.QPointF(self._node.x() + 0.1, self._node.y()))
def updateNode(self):
"""
Sync change to the node
@@ -466,7 +469,7 @@ class NodeItem(QtSvg.QGraphicsSvgItem):
:param value: value of the change
"""
if change == QtWidgets.QGraphicsItem.ItemPositionChange and self.isActive() and self._main_window.uiSnapToGridAction.isChecked():
if change == QtWidgets.QGraphicsItem.ItemPositionChange and self._main_window.uiSnapToGridAction.isChecked():
grid_size = self._main_window.uiGraphicsView.nodeGridSize()
mid_x = self.boundingRect().width() / 2
value.setX((grid_size * round((value.x() + mid_x) / grid_size)) - mid_x)

View File

@@ -220,10 +220,14 @@ def main():
if not options.debug:
try:
# hide the console
# win32console.AllocConsole()
console_window = win32console.GetConsoleWindow()
win32gui.ShowWindow(console_window, win32con.SW_HIDE)
if console_window:
win32gui.ShowWindow(console_window, win32con.SW_HIDE)
else:
log.warning("Could not get the console window")
except win32console.error as e:
print("warning: could not allocate console: {}".format(e))
log.warning("Could not allocate console: {}".format(e))
local_config = LocalConfig.instance()

View File

@@ -246,6 +246,7 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
self.uiReloadAllAction.triggered.connect(self._reloadAllActionSlot)
self.uiAuxConsoleAllAction.triggered.connect(self._auxConsoleAllActionSlot)
self.uiConsoleAllAction.triggered.connect(self._consoleAllActionSlot)
self.uiResetConsoleAllAction.triggered.connect(self._consoleResetAllActionSlot)
# device menu is contextual and is build on-the-fly
self.uiDeviceMenu.aboutToShow.connect(self._deviceMenuActionSlot)
@@ -870,6 +871,15 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
if project is not None:
project.reload_all_nodes()
def _consoleResetAllActionSlot(self):
"""
Slot called when reset all console connections.
"""
project = Topology.instance().project()
if project is not None:
project.reset_console_all_nodes()
def _deviceMenuActionSlot(self):
"""
Slot to contextually show the device menu.

View File

@@ -116,6 +116,18 @@ class DockerVM(Node):
from .pages.docker_vm_configuration_page import DockerVMConfigurationPage
return DockerVMConfigurationPage
@staticmethod
def validateHostname(hostname):
"""
Checks if the hostname is valid.
:param hostname: hostname to check
:returns: boolean
"""
return DockerVM.isValidRfc1123Hostname(hostname)
@staticmethod
def defaultSymbol():
"""

View File

@@ -175,11 +175,26 @@
</item>
<item row="8" column="1">
<widget class="QComboBox" name="uiConsoleResolutionComboBox">
<item>
<property name="text">
<string>2560x1440</string>
</property>
</item>
<item>
<property name="text">
<string>1920x1080</string>
</property>
</item>
<item>
<property name="text">
<string>1680x1050</string>
</property>
</item>
<item>
<property name="text">
<string>1440x900</string>
</property>
</item>
<item>
<property name="text">
<string>1366x768</string>

View File

@@ -2,12 +2,15 @@
# Form implementation generated from reading ui file '/home/grossmj/PycharmProjects/gns3-gui/gns3/modules/docker/ui/docker_vm_configuration_page.ui'
#
# Created by: PyQt5 UI code generator 5.11.3
# Created by: PyQt5 UI code generator 5.15.7
#
# WARNING! All changes made in this file will be lost!
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again. Do not edit this file unless you know what you are doing.
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_dockerVMConfigPageWidget(object):
def setupUi(self, dockerVMConfigPageWidget):
dockerVMConfigPageWidget.setObjectName("dockerVMConfigPageWidget")
@@ -100,6 +103,9 @@ class Ui_dockerVMConfigPageWidget(object):
self.uiConsoleResolutionComboBox.addItem("")
self.uiConsoleResolutionComboBox.addItem("")
self.uiConsoleResolutionComboBox.addItem("")
self.uiConsoleResolutionComboBox.addItem("")
self.uiConsoleResolutionComboBox.addItem("")
self.uiConsoleResolutionComboBox.addItem("")
self.gridLayout.addWidget(self.uiConsoleResolutionComboBox, 8, 1, 1, 1)
self.label = QtWidgets.QLabel(self.tab)
self.label.setObjectName("label")
@@ -190,13 +196,16 @@ class Ui_dockerVMConfigPageWidget(object):
self.uiConsoleTypeComboBox.setItemText(4, _translate("dockerVMConfigPageWidget", "none"))
self.uiConsoleAutoStartCheckBox.setText(_translate("dockerVMConfigPageWidget", "Auto start console"))
self.uiConsoleResolutionLabel.setText(_translate("dockerVMConfigPageWidget", "VNC console resolution:"))
self.uiConsoleResolutionComboBox.setItemText(0, _translate("dockerVMConfigPageWidget", "1920x1080"))
self.uiConsoleResolutionComboBox.setItemText(1, _translate("dockerVMConfigPageWidget", "1366x768"))
self.uiConsoleResolutionComboBox.setItemText(2, _translate("dockerVMConfigPageWidget", "1280x1024"))
self.uiConsoleResolutionComboBox.setItemText(3, _translate("dockerVMConfigPageWidget", "1280x800"))
self.uiConsoleResolutionComboBox.setItemText(4, _translate("dockerVMConfigPageWidget", "1024x768"))
self.uiConsoleResolutionComboBox.setItemText(5, _translate("dockerVMConfigPageWidget", "800x600"))
self.uiConsoleResolutionComboBox.setItemText(6, _translate("dockerVMConfigPageWidget", "640x480"))
self.uiConsoleResolutionComboBox.setItemText(0, _translate("dockerVMConfigPageWidget", "2560x1440"))
self.uiConsoleResolutionComboBox.setItemText(1, _translate("dockerVMConfigPageWidget", "1920x1080"))
self.uiConsoleResolutionComboBox.setItemText(2, _translate("dockerVMConfigPageWidget", "1680x1050"))
self.uiConsoleResolutionComboBox.setItemText(3, _translate("dockerVMConfigPageWidget", "1440x900"))
self.uiConsoleResolutionComboBox.setItemText(4, _translate("dockerVMConfigPageWidget", "1366x768"))
self.uiConsoleResolutionComboBox.setItemText(5, _translate("dockerVMConfigPageWidget", "1280x1024"))
self.uiConsoleResolutionComboBox.setItemText(6, _translate("dockerVMConfigPageWidget", "1280x800"))
self.uiConsoleResolutionComboBox.setItemText(7, _translate("dockerVMConfigPageWidget", "1024x768"))
self.uiConsoleResolutionComboBox.setItemText(8, _translate("dockerVMConfigPageWidget", "800x600"))
self.uiConsoleResolutionComboBox.setItemText(9, _translate("dockerVMConfigPageWidget", "640x480"))
self.label.setText(_translate("dockerVMConfigPageWidget", "HTTP port in the container:"))
self.label_2.setText(_translate("dockerVMConfigPageWidget", "HTTP path:"))
self.uiEnvironmentLabel.setText(_translate("dockerVMConfigPageWidget", "Environment variables:\n"
@@ -217,4 +226,3 @@ class Ui_dockerVMConfigPageWidget(object):
self.uiExtraVolumeTextEdit.setPlaceholderText(_translate("dockerVMConfigPageWidget", "e.g. /etc/sysctl.d"))
self.uiTabWidget.setTabText(self.uiTabWidget.indexOf(self.tab_2), _translate("dockerVMConfigPageWidget", "Advanced"))
self.uiTabWidget.setTabText(self.uiTabWidget.indexOf(self.tab_3), _translate("dockerVMConfigPageWidget", "Usage"))

View File

@@ -310,8 +310,8 @@ class Router(Node):
# IOS names must start with a letter, end with a letter or digit, and
# have as interior characters only letters, digits, and hyphens.
# They must be 63 characters or fewer.
if re.search(r"""^[\-\w]+$""", hostname) and len(hostname) <= 63:
# They must be 63 characters or fewer (ARPANET rules).
if re.search(r"""^(?!-|[0-9])[a-zA-Z0-9-]{1,63}(?<!-)$""", hostname):
return True
return False

View File

@@ -131,8 +131,8 @@ class IOUDevice(Node):
# IOS names must start with a letter, end with a letter or digit, and
# have as interior characters only letters, digits, and hyphens.
# They must be 63 characters or fewer.
if re.search(r"""^[\-\w]+$""", hostname) and len(hostname) <= 63:
# They must be 63 characters or fewer (ARPANET rules).
if re.search(r"""^(?!-|[0-9])[a-zA-Z0-9-]{1,63}(?<!-)$""", hostname):
return True
return False

View File

@@ -157,6 +157,7 @@ class QemuVMWizard(VMWithImagesWizard, Ui_QemuVMWizard):
if self.uiHdaDiskImageLineEdit.text().strip():
settings["hda_disk_image"] = self.uiHdaDiskImageLineEdit.text().strip()
settings["hda_disk_interface"] = "ide"
if self.uiLegacyASACheckBox.isChecked():
# special settings for legacy ASA VM

View File

@@ -578,6 +578,7 @@ class QemuVMConfigurationPage(QtWidgets.QWidget, Ui_QemuVMConfigPageWidget):
self.uiProcessPriorityComboBox.setCurrentIndex(index)
self.uiQemuOptionsLineEdit.setText(settings["options"])
self.uiUsageTextEdit.setPlainText(settings["usage"])
self.uiTPMCheckBox.setChecked(settings["tpm"])
def saveSettings(self, settings, node=None, group=False):
"""
@@ -692,4 +693,5 @@ class QemuVMConfigurationPage(QtWidgets.QWidget, Ui_QemuVMConfigPageWidget):
settings["process_priority"] = self.uiProcessPriorityComboBox.currentText().lower()
settings["options"] = self.uiQemuOptionsLineEdit.text()
settings["usage"] = self.uiUsageTextEdit.toPlainText()
settings["tpm"] = self.uiTPMCheckBox.isChecked()
return settings

View File

@@ -19,6 +19,8 @@
QEMU VM implementation.
"""
import re
from gns3.node import Node
from .settings import QEMU_VM_SETTINGS
@@ -72,6 +74,7 @@ class QemuVM(Node):
"mac_address": QEMU_VM_SETTINGS["mac_address"],
"legacy_networking": QEMU_VM_SETTINGS["legacy_networking"],
"replicate_network_connection_state": QEMU_VM_SETTINGS["replicate_network_connection_state"],
"tpm": QEMU_VM_SETTINGS["tpm"],
"create_config_disk": QEMU_VM_SETTINGS["create_config_disk"],
"platform": QEMU_VM_SETTINGS["platform"],
"on_close": QEMU_VM_SETTINGS["on_close"],
@@ -163,6 +166,18 @@ class QemuVM(Node):
from .pages.qemu_vm_configuration_page import QemuVMConfigurationPage
return QemuVMConfigurationPage
@staticmethod
def validateHostname(hostname):
"""
Checks if the hostname is valid.
:param hostname: hostname to check
:returns: boolean
"""
return QemuVM.isValidRfc1123Hostname(hostname)
@staticmethod
def defaultSymbol():
"""

View File

@@ -57,6 +57,7 @@ QEMU_VM_SETTINGS = {
"mac_address": "",
"legacy_networking": False,
"replicate_network_connection_state": True,
"tpm": False,
"create_config_disk": False,
"on_close": "power_off",
"platform": "",

View File

@@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>941</width>
<height>939</height>
<width>478</width>
<height>550</height>
</rect>
</property>
<property name="windowTitle">
@@ -890,7 +890,7 @@
</property>
</widget>
</item>
<item row="1" column="0" colspan="2">
<item row="2" column="0" colspan="2">
<widget class="QCheckBox" name="uiBaseVMCheckBox">
<property name="enabled">
<bool>true</bool>
@@ -900,10 +900,18 @@
</property>
</widget>
</item>
<item row="1" column="0" colspan="2">
<widget class="QCheckBox" name="uiTPMCheckBox">
<property name="text">
<string>Enable Trusted Platform Module (TPM)</string>
</property>
</widget>
</item>
</layout>
<zorder>uiQemuOptionsLineEdit</zorder>
<zorder>uiQemuOptionsLabel</zorder>
<zorder>uiBaseVMCheckBox</zorder>
<zorder>uiTPMCheckBox</zorder>
</widget>
</item>
<item>

View File

@@ -2,9 +2,10 @@
# Form implementation generated from reading ui file '/home/grossmj/PycharmProjects/gns3-gui/gns3/modules/qemu/ui/qemu_vm_configuration_page.ui'
#
# Created by: PyQt5 UI code generator 5.13.2
# Created by: PyQt5 UI code generator 5.15.6
#
# WARNING! All changes made in this file will be lost!
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again. Do not edit this file unless you know what you are doing.
from PyQt5 import QtCore, QtGui, QtWidgets
@@ -13,7 +14,7 @@ from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_QemuVMConfigPageWidget(object):
def setupUi(self, QemuVMConfigPageWidget):
QemuVMConfigPageWidget.setObjectName("QemuVMConfigPageWidget")
QemuVMConfigPageWidget.resize(941, 939)
QemuVMConfigPageWidget.resize(478, 550)
self.verticalLayout = QtWidgets.QVBoxLayout(QemuVMConfigPageWidget)
self.verticalLayout.setObjectName("verticalLayout")
self.uiQemutabWidget = QtWidgets.QTabWidget(QemuVMConfigPageWidget)
@@ -436,10 +437,14 @@ class Ui_QemuVMConfigPageWidget(object):
self.uiBaseVMCheckBox = QtWidgets.QCheckBox(self.groupBox)
self.uiBaseVMCheckBox.setEnabled(True)
self.uiBaseVMCheckBox.setObjectName("uiBaseVMCheckBox")
self.gridLayout_3.addWidget(self.uiBaseVMCheckBox, 1, 0, 1, 2)
self.gridLayout_3.addWidget(self.uiBaseVMCheckBox, 2, 0, 1, 2)
self.uiTPMCheckBox = QtWidgets.QCheckBox(self.groupBox)
self.uiTPMCheckBox.setObjectName("uiTPMCheckBox")
self.gridLayout_3.addWidget(self.uiTPMCheckBox, 1, 0, 1, 2)
self.uiQemuOptionsLineEdit.raise_()
self.uiQemuOptionsLabel.raise_()
self.uiBaseVMCheckBox.raise_()
self.uiTPMCheckBox.raise_()
self.verticalLayout_2.addWidget(self.groupBox)
spacerItem4 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
self.verticalLayout_2.addItem(spacerItem4)
@@ -556,5 +561,6 @@ class Ui_QemuVMConfigPageWidget(object):
"</ul>\n"
"</body></html>"))
self.uiBaseVMCheckBox.setText(_translate("QemuVMConfigPageWidget", "Use as a linked base VM"))
self.uiTPMCheckBox.setText(_translate("QemuVMConfigPageWidget", "Enable Trusted Platform Module (TPM)"))
self.uiQemutabWidget.setTabText(self.uiQemutabWidget.indexOf(self.uiAdvancedSettingsTab), _translate("QemuVMConfigPageWidget", "Advanced"))
self.uiQemutabWidget.setTabText(self.uiQemutabWidget.indexOf(self.uiUsageTab), _translate("QemuVMConfigPageWidget", "Usage"))

View File

@@ -17,6 +17,7 @@
import os
import pathlib
import re
from gns3.controller import Controller
from gns3.ports.ethernet_port import EthernetPort
@@ -864,6 +865,33 @@ class Node(BaseNode):
if error and "message" in result:
log.error("Error while import config: {}".format(result["message"]))
@staticmethod
def isValidRfc1123Hostname(hostname):
"""
Validate a hostname according to RFC 1123
Each element of the hostname must be from 1 to 63 characters long
and the entire hostname, including the dots, can be at most 253
characters long. Valid characters for hostnames are ASCII
letters from a to z, the digits from 0 to 9, and the hyphen (-).
A hostname may not start with a hyphen.
"""
if hostname[-1] == ".":
hostname = hostname[:-1] # strip exactly one dot from the right, if present
if len(hostname) > 253:
return False
labels = hostname.split(".")
# the TLD must be not all-numeric
if re.match(r"[0-9]+$", labels[-1]):
return False
allowed = re.compile(r"(?!-)[a-zA-Z0-9-]{1,63}(?<!-)$")
return all(allowed.match(label) for label in labels)
@staticmethod
def onCloseOptions():
"""

View File

@@ -365,6 +365,15 @@ class Project(QtCore.QObject):
Controller.instance().post("/projects/{project_id}/nodes/reload".format(project_id=self._id), None, body={}, timeout=None)
def reset_console_all_nodes(self):
"""Reset console for all nodes belonging to this project"""
# Don't do anything if the project doesn't exist on the server
if self._id is None:
return
Controller.instance().post("/projects/{project_id}/nodes/console/reset".format(project_id=self._id), None, body={}, timeout=None)
def get(self, path, callback, **kwargs):
"""
HTTP GET on the remote server

View File

@@ -59,7 +59,7 @@ class Appliance(collections.abc.Mapping):
"""
if "registry_version" not in self._appliance:
raise ApplianceError("Invalid appliance configuration please report the issue on https://github.com/GNS3/gns3-registry")
if self._appliance["registry_version"] > 6:
if self._appliance["registry_version"] > 7:
raise ApplianceError("Please update GNS3 in order to install this appliance")
with open(get_resource(os.path.join("schemas", "appliance.json"))) as f:

View File

@@ -350,6 +350,14 @@
"maximum": 100,
"title": "Throttle the CPU"
},
"tpm": {
"type": "boolean",
"title": "Enable the Trusted Platform Module (TPM)"
},
"on_close": {
"title": "Action to execute on the VM is closed",
"enum": ["power_off", "shutdown_signal", "save_vm_state"]
},
"process_priority": {
"title": "Process priority for QEMU",
"enum": ["realtime",

View File

@@ -56,7 +56,6 @@ if sys.platform.startswith("win"):
program_files_x86 = program_files = os.environ["PROGRAMFILES"]
PRECONFIGURED_TELNET_CONSOLE_COMMANDS = {'Putty (normal standalone version)': 'putty_standalone.exe -telnet %h %p -loghost "%d"',
'Putty (custom deprecated version)': 'putty.exe -telnet %h %p -wt "%d" -gns3 5 -skin 4',
'MobaXterm': r'"{}\Mobatek\MobaXterm Personal Edition\MobaXterm.exe" -newtab "telnet %h %p"'.format(program_files_x86),
'Royal TS V3': r'{}\code4ward.net\Royal TS V3\RTS3App.exe /connectadhoc:%h /adhoctype:terminal /p:IsTelnetConnection="true" /p:ConnectionType="telnet;Telnet Connection" /p:Port="%p" /p:Name="%d"'.format(program_files),
'Royal TS V5': r'"{}\Royal TS V5\RoyalTS.exe" /protocol:terminal /using:adhoc /uri:"%h" /property:Port="%p" /property:IsTelnetConnection="true" /property:Name="%d"'.format(program_files_x86),
@@ -65,6 +64,7 @@ if sys.platform.startswith("win"):
'SecureCRT (personal profile)': r'"{}\AppData\Local\VanDyke Software\SecureCRT\SecureCRT.exe" /T /N "%d" /TELNET %h %p'.format(userprofile),
'TeraTerm Pro': r'"{}\teraterm\ttermpro.exe" /W="%d" /M="ttstart.macro" /T=1 %h %p'.format(program_files_x86),
'Telnet': 'telnet %h %p',
'Windows Terminal': 'wt.exe -w 1 new-tab --title %d telnet %h %p',
'Xshell 4': r'"{}\NetSarang\Xshell 4\xshell.exe" -url telnet://%h:%p'.format(program_files_x86),
'Xshell 5': r'"{}\NetSarang\Xshell 5\xshell.exe" -url telnet://%h:%p -newtab %d'.format(program_files_x86),
'ZOC 6': r'"{}\ZOC6\zoc.exe" "/TELNET:%h:%p" /TABBED "/TITLE:%d"'.format(program_files_x86)}
@@ -141,7 +141,6 @@ elif sys.platform.startswith("darwin"):
r""" -e 'end tell'""",
'Royal TSX': "open 'rtsx://telnet%3A%2F%2F%h:%p'",
'SecureCRT': '/Applications/SecureCRT.app/Contents/MacOS/SecureCRT /N "%d" /T /TELNET %h %p',
'Windows Terminal': 'wt.exe -w 1 new-tab --title %d telnet %h %p',
'ZOC 6': '/Applications/zoc6.app/Contents/MacOS/zoc6 "/TELNET:%h:%p" /TABBED "/TITLE:%d"',
'ZOC 7': '/Applications/zoc7.app/Contents/MacOS/zoc7 "/TELNET:%h:%p" /TABBED "/TITLE:%d"',
'ZOC 8': '/Applications/zoc8.app/Contents/MacOS/zoc8 "/TELNET:%h:%p" /TABBED "/TITLE:%d"'
@@ -213,7 +212,7 @@ else:
if sys.platform.startswith("win"):
# Windows
PRECONFIGURED_SPICE_CONSOLE_COMMANDS = {
'Remote Viewer': r'"{}\VirtViewer v7.0-256\bin\remote-viewer.exe" spice://%h:%p'.format(program_files),
'Remote Viewer': r'"{}\VirtViewer v11.0-256\bin\remote-viewer.exe" spice://%h:%p'.format(program_files),
}
# default Windows SPICE console command

View File

@@ -10,7 +10,7 @@
<x>0</x>
<y>0</y>
<width>986</width>
<height>716</height>
<height>719</height>
</rect>
</property>
<property name="contextMenuPolicy">
@@ -151,6 +151,7 @@ background-none;
<addaction name="uiReloadAllAction"/>
<addaction name="uiAuxConsoleAllAction"/>
<addaction name="uiConsoleAllAction"/>
<addaction name="uiResetConsoleAllAction"/>
</widget>
<widget class="QMenu" name="uiAnnotateMenu">
<property name="title">
@@ -1294,6 +1295,11 @@ background-none;
<string>Reset docks</string>
</property>
</action>
<action name="uiResetConsoleAllAction">
<property name="text">
<string>Reset all console connections</string>
</property>
</action>
</widget>
<customwidgets>
<customwidget>

View File

@@ -450,6 +450,11 @@ class Ui_MainWindow(object):
self.uiNewTemplateAction.setObjectName("uiNewTemplateAction")
self.uiResetDocksAction = QtWidgets.QAction(MainWindow)
self.uiResetDocksAction.setObjectName("uiResetDocksAction")
self.uiEditReadmeAction = QtWidgets.QAction(MainWindow)
self.uiEditReadmeAction.setIcon(icon31)
self.uiEditReadmeAction.setObjectName("uiEditReadmeAction")
self.uiResetConsoleAllAction = QtWidgets.QAction(MainWindow)
self.uiResetConsoleAllAction.setObjectName("uiResetConsoleAllAction")
self.uiEditMenu.addAction(self.uiSelectAllAction)
self.uiEditMenu.addAction(self.uiSelectNoneAction)
self.uiEditMenu.addSeparator()
@@ -498,6 +503,7 @@ class Ui_MainWindow(object):
self.uiControlMenu.addAction(self.uiReloadAllAction)
self.uiControlMenu.addAction(self.uiAuxConsoleAllAction)
self.uiControlMenu.addAction(self.uiConsoleAllAction)
self.uiControlMenu.addAction(self.uiResetConsoleAllAction)
self.uiAnnotateMenu.addAction(self.uiAddNoteAction)
self.uiAnnotateMenu.addAction(self.uiInsertImageAction)
self.uiAnnotateMenu.addAction(self.uiDrawRectangleAction)
@@ -715,6 +721,9 @@ class Ui_MainWindow(object):
self.uiWebUIAction.setText(_translate("MainWindow", "Web UI - beta"))
self.uiNewTemplateAction.setText(_translate("MainWindow", "New template"))
self.uiResetDocksAction.setText(_translate("MainWindow", "Reset docks"))
self.uiEditReadmeAction.setText(_translate("MainWindow", "Edit readme"))
self.uiEditReadmeAction.setToolTip(_translate("MainWindow", "Edit readme"))
self.uiResetConsoleAllAction.setText(_translate("MainWindow", "Reset all console connections"))
from ..compute_summary_view import ComputeSummaryView
from ..console_view import ConsoleView
from ..graphics_view import GraphicsView

View File

@@ -239,4 +239,22 @@ class UpdateManager(QtCore.QObject):
for member in members:
# Path separator is always / even on windows
member.name = member.name.split("/", 1)[1]
tar.extractall(path=self._package_directory, members=members)
def is_within_directory(directory, target):
abs_directory = os.path.abspath(directory)
abs_target = os.path.abspath(target)
prefix = os.path.commonprefix([abs_directory, abs_target])
return prefix == abs_directory
def safe_extract(tar, path=".", members=None, *, numeric_owner=False):
for member in tar.getmembers():
member_path = os.path.join(path, member.name)
if not is_within_directory(path, member_path):
raise Exception("Attempted Path Traversal in Tar File")
tar.extractall(path, members, numeric_owner=numeric_owner)
safe_extract(tar, path=self._package_directory, members=members)

View File

@@ -23,8 +23,8 @@
# or negative for a release candidate or beta (after the base version
# number has been incremented)
__version__ = "2.2.32"
__version_info__ = (2, 2, 32, 0)
__version__ = "2.2.39"
__version_info__ = (2, 2, 39, 0)
if "dev" in __version__:
try:
@@ -32,6 +32,6 @@ if "dev" in __version__:
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("\n")
__version__ += "-" + r
__version__ += "+" + r
except Exception as e:
print(e)

View File

@@ -1,3 +1,3 @@
-rrequirements.txt
PyQt5==5.15.6
PyQt5==5.15.7

View File

@@ -1,6 +1,7 @@
jsonschema==3.2.0
sentry-sdk==1.5.10
psutil==5.9.0
distro==1.6.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
jsonschema>=4.17.3,<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
sentry-sdk==1.17.0,<1.18
psutil==5.9.4
distro>=1.8.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

View File

@@ -66,7 +66,8 @@ setup(
author="Jeremy Grossmann",
author_email="package-maintainer@gns3.net",
description="GNS3 graphical interface for the GNS3 server.",
long_description=open("README.rst", "r").read(),
long_description=open("README.md", "r").read(),
long_description_content_type="text/markdown",
install_requires=open("requirements.txt", "r").read().splitlines(),
entry_points={
"gui_scripts": [
@@ -78,6 +79,7 @@ setup(
include_package_data=True,
package_data={"gns3": ["configs/*.txt", "schemas/*.json"]},
platforms="any",
python_requires=">=3.4",
setup_requires=["setuptools>=17.1"],
classifiers=[
"Development Status :: 5 - Production/Stable",
@@ -98,6 +100,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",
],
)

View File

@@ -61,6 +61,7 @@ def test_toSvg_negative_y(project, controller):
def test_fromSvg(project, controller):
line = LineItem(project=project)
line._main_window.uiSnapToGridAction.isChecked = lambda: False
line.setPos(50, 84)
line.fromSvg('<svg height="150" width="250"><line x1="0" y1="0" x2="250" y2="150" stroke-width="5" stroke="#0000ff" stroke-dasharray="5, 25, 25" /></svg>')
assert line.line().x1() == 0
@@ -75,6 +76,7 @@ def test_fromSvg(project, controller):
def test_fromSvg_top_direction(project, controller):
line = LineItem(project=project)
line._main_window.uiSnapToGridAction.isChecked = lambda: False
line.setPos(50, 84)
line.fromSvg('<svg height="150" width="250"><line x1="0" y1="150" x2="250" y2="0" stroke-width="5" stroke="#0000ff" stroke-dasharray="5, 25, 25" /></svg>')
assert line.line().x1() == 0

View File

@@ -311,7 +311,7 @@ def test_callbackConnect_major_version_invalid(http_client):
def test_callbackConnect_minor_version_invalid(http_client):
new_version = "{}.{}.{}".format(__version_info__[0], __version_info__[1], __version_info__[2] + 1)
new_version = "{}.{}.{}".format(__version_info__[0], __version_info__[1] + 1, 0)
params = {
"local": True,
"version": new_version
@@ -319,14 +319,23 @@ def test_callbackConnect_minor_version_invalid(http_client):
mock = unittest.mock.MagicMock()
http_client._query_waiting_connections.append((None, mock))
# Stable release
if __version_info__[3] == 0:
http_client._callbackConnect(params)
assert http_client._connected is False
mock.assert_called_with({"message": "Client version {} is not the same as server (controller) version {}".format(__version__, new_version)}, error=True, server=None)
else:
http_client._callbackConnect(params)
assert http_client._connected is True
http_client._callbackConnect(params)
assert http_client._connected is False
mock.assert_called_with({"message": "Client version {} is not the same as server (controller) version {}".format(__version__, new_version)}, error=True, server=None)
def test_callbackConnect_patch_version(http_client):
new_version = "{}.{}.{}.{}".format(__version_info__[0], __version_info__[1], __version_info__[2], 42)
params = {
"local": True,
"version": new_version
}
mock = unittest.mock.MagicMock()
http_client._query_waiting_connections.append((None, mock))
http_client._callbackConnect(params)
assert http_client._connected is True
def test_callbackConnect_non_gns3_server(http_client):

View File

@@ -1,4 +1,4 @@
-rrequirements.txt
PyQt5==5.15.6 # pyup: ignore
pywin32==303 # pyup: ignore
PyQt5==5.15.7 # pyup: ignore
pywin32==305 # pyup: ignore