Compare commits

...

47 Commits

Author SHA1 Message Date
grossmj
b5285cd142 Release v2.2.15 2020-10-07 15:29:52 +10:30
grossmj
69482343ba Fix custom symbol not sent to remote controller when installing appliance 2020-10-07 15:09:08 +10:30
grossmj
d4639c2e61 Development on 2.2.15dev1 2020-09-15 06:49:11 +09:30
grossmj
b85ade9dd7 Release v2.2.14 2020-09-15 05:52:48 +09:30
grossmj
e191cb8aa3 Fix tests. Ref #3002 2020-09-14 00:10:11 +09:30
grossmj
e6bc75ce26 Improvements to add a new version of an appliance from wizard. Fixes #3002. 2020-09-14 00:04:58 +09:30
grossmj
bc1df346f2 Development on 2.2.14dev1 2020-09-05 04:26:16 +09:30
grossmj
27c35321f0 Release v2.2.13 2020-09-04 23:13:28 +09:30
grossmj
7b99ba325b Development on 2.2.13dev1 2020-08-07 21:12:46 +09:30
grossmj
74763287fb Release v2.2.12 2020-08-07 19:27:32 +09:30
grossmj
737ff42d64 Merge branch 'master' into 2.2 2020-08-07 19:04:08 +09:30
Jeremy Grossmann
5656bd2d48 Downgrade psutil to version 5.6.7 2020-07-29 17:36:14 +09:30
Jeremy Grossmann
058c069394 Fix log shows the GUI command line without spaces between its arguments. Fixes #3026 2020-07-27 18:27:23 +09:30
grossmj
926ec48d00 Upgrade to psutil version 5.7.2 2020-07-21 15:49:58 +09:30
grossmj
410e5353b2 Use server host is console host is equal to "0:0:0:0:0:0:0:0" 2020-07-17 21:13:27 +09:30
grossmj
bfb90406ed Remove VMware promotion. 2020-07-17 21:12:59 +09:30
grossmj
439cdce287 Development on 2.2.12dev1 2020-07-09 21:37:03 +09:30
grossmj
4e50c2a4b1 Release v2.2.11 2020-07-09 20:37:10 +09:30
grossmj
94c636ae61 Merge branch 'master' into 2.2 2020-07-09 20:23:31 +09:30
grossmj
f53b9a266e Try to fix "Recent project" selection not working. Ref #3007 2020-07-09 15:37:47 +09:30
grossmj
2476448032 Fix debug entries shown twice in console window and double error messages with remote GNS3VM. Fixes #3010 #3011
Note that the debug level is broken (has been for a long time apparently).
2020-07-07 21:06:56 +09:30
grossmj
a34cd742e3 Merge branch '2.2' 2020-07-06 22:20:05 +09:30
grossmj
39698196ac Fix deprecation warning. Ref #3009 2020-07-06 22:08:10 +09:30
grossmj
61432ced4f Fix tests on macOS. Ref #3009 2020-07-06 22:03:29 +09:30
grossmj
2ddd13c445 Add Snyk badges. 2020-06-27 18:27:04 +09:30
grossmj
af6c4c5b3e Merge branch 'master' into 2.2 2020-06-26 21:30:37 +09:30
grossmj
d4012294bf Run tests inside container 2020-06-26 20:50:48 +09:30
grossmj
4b04b0e855 Use xvfb to run tests 2020-06-26 20:41:08 +09:30
grossmj
1bec5019bf Install PyQt5 using pip 2020-06-26 19:42:42 +09:30
grossmj
ec6b876baa Explicitly install sip 2020-06-26 19:38:10 +09:30
grossmj
7cee0d01ab Install PyQt5 for tests and add GitHub Actions badge 2020-06-26 19:34:02 +09:30
Jeremy Grossmann
dd3314d06b Set up GitHub Actions for running tests 2020-06-26 19:27:22 +09:30
grossmj
9c58b26265 Remove tox, Travis CI and pep8.sh script
Update dependencies
2020-06-26 19:21:51 +09:30
Jeremy Grossmann
83c26f47da Merge pull request #3005 from GNS3/whitesource/configure
Configure WhiteSource for GitHub.com
2020-06-26 09:04:39 +08:00
whitesource-for-github-com[bot]
8ed2f55600 Add .whitesource configuration file 2020-06-26 01:01:54 +00:00
Jeremy Grossmann
b435317904 Merge pull request #3003 from GNS3/snyk-fix-8bf3e4840df4587cc42afb85b857d470
[Snyk] Security upgrade psutil from 5.6.6 to 5.6.7
2020-06-25 11:41:01 +08:00
snyk-bot
acb8aa8ca2 fix: requirements.txt to reduce vulnerabilities
The following vulnerabilities are fixed by pinning transitive dependencies:
- https://snyk.io/vuln/SNYK-PYTHON-PSUTIL-483082
2020-06-24 13:10:33 +00:00
grossmj
c55d6b8a6f Fix sentry SDK is configured twice. 2020-06-24 12:40:06 +09:30
grossmj
a4039a254e Development on 2.2.11dev1 2020-06-18 19:06:00 +09:30
grossmj
85ed4b3026 Release v2.2.10 2020-06-18 12:29:33 +09:30
grossmj
5207a99692 New fix for multi-device selection/deselection not working as expected with right click. Fixes #2986 2020-06-09 13:50:31 +09:30
grossmj
d69527995d Revert "Fix Multi-device selection/deselection not working as expected with right click. Fixes #2986"
This reverts commit ddeb95cb0a.
2020-06-09 13:19:20 +09:30
grossmj
4b000ba2f7 Optimize snap-to-grid code for drawing items. Fixes #2997 2020-06-09 11:47:05 +09:30
grossmj
1b302b77a0 Move jsonschema 2.6.0 requirement in build repository.
https://github.com/GNS3/gns3-server/issues/1751
https://github.com/GNS3/gns3-gui/issues/2849

This is to avoid the following error:

```
ERROR: Double requirement given: jsonschema==2.6.0 (from -r gns3-gui\win-requirements.txt (line 4)) (already in jsonschema==3.2.0 (from -r gns3-gui\requirements.txt (line 1)), name='jsonschema')
```
2020-06-07 13:07:16 +09:30
grossmj
a5b5c404ec Only use jsonschema 2.6.0 on Windows and macOS.
https://github.com/GNS3/gns3-server/issues/1751
https://github.com/GNS3/gns3-gui/issues/2849
2020-06-07 12:55:22 +09:30
grossmj
6b97b0c6cd Disable default integrations for sentry sdk. 2020-06-06 15:37:17 +09:30
grossmj
115dd43eee Development on 2.2.10dev1 2020-06-04 21:06:30 +09:30
35 changed files with 167 additions and 221 deletions

19
.github/workflows/testing.yml vendored Normal file
View File

@@ -0,0 +1,19 @@
name: testing
on:
push:
branches: [ master ]
pull_request:
branches: [ master ]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Build and run Docker image
run: |
docker build -t gns3-gui-test .
docker run gns3-gui-test

View File

@@ -1,2 +0,0 @@
branch:
2.2

View File

@@ -1,21 +0,0 @@
sudo: required
services:
- docker
notifications:
email: false
script:
- docker build -t gns3-gui-test .
- docker run gns3-gui-test
before_deploy:
- sudo pip install twine
- sudo pip install urllib3[secure]
deploy:
provider: pypi
edge:
branch: v1.8.45
user: noplay
password:
secure: FofcqlJjgqf2jaDaXpLHeigVoexbrOz3WwnDuiJpwJxeFUlPY8s2cQs/Bm+dzxzZaOaGiVE0A83v/Xa10yD5tflThHt4sqYJK3iQCinA7wgeAlDimB4xrWUNplfNJZ/Eod5Ssa++E02W+3i29PxpXY//mjCY7qDxaoxul1gnFJY=
on:
tags: true
repo: GNS3/gns3-gui

13
.whitesource Normal file
View File

@@ -0,0 +1,13 @@
{
"scanSettings": {
"configMode": "AUTO",
"configExternalURL": "",
"projectToken" : ""
},
"checkRunSettings": {
"vulnerableCheckRunConclusionLevel": "failure"
},
"issueSettings": {
"minSeverityLevel": "LOW"
}
}

View File

@@ -1,5 +1,40 @@
# Change Log
## 2.2.15 07/10/2020
* Fix custom symbol not sent to remote controller when installing appliance
## 2.2.14 14/09/2020
* Improvements to add a new version of an appliance from wizard. Fixes #3002.
## 2.2.13 04/09/2020
* No changes
## 2.2.12 07/08/2020
* Downgrade psutil to version 5.6.7
* Fix log shows the GUI command line without spaces between its arguments. Fixes #3026
* Use server host is console host is equal to "0:0:0:0:0:0:0:0"
* Remove VMware promotion.
## 2.2.11 09/07/2020
* Try to fix "Recent project" selection not working. Ref #3007
* Fix debug entries shown twice in console window and double error messages with remote GNS3VM. Fixes #3010
* Fix deprecation warning. Ref #3009
* Fix tests on macOS. Ref #3009
* Fix sentry SDK is configured twice.
## 2.2.10 18/06/2020
* New fix for multi-device selection/deselection not working as expected with right click. Fixes #2986
* Optimize snap-to-grid code for drawing items. Fixes #2997
* Move jsonschema 2.6.0 requirement in build repository.
* Only use jsonschema 2.6.0 on Windows and macOS.
* Disable default integrations for sentry sdk.
## 2.2.9 04/06/2020
* Fix GUI doesn't detect another GUI on macOS. Fixes #2994

View File

@@ -1,22 +1,16 @@
# Run tests inside a container
FROM ubuntu:18.04
MAINTAINER GNS3 Team
#ENV DEBIAN_FRONTEND noninteractive
RUN apt-get update
RUN apt-get install -y --force-yes python3.6 python3-pyqt5 python3-pip python3-pyqt5.qtsvg python3-pyqt5.qtwebsockets python3.6-dev xvfb
RUN apt-get clean
ADD dev-requirements.txt /dev-requirements.txt
ADD requirements.txt /requirements.txt
RUN pip3 install -r /dev-requirements.txt
ADD . /src
WORKDIR /src
CMD xvfb-run python3.6 -m pytest -vv

View File

@@ -3,7 +3,6 @@ include AUTHORS
include LICENSE
include MANIFEST.in
include requirements.txt
include tox.ini
recursive-include tests *
recursive-include gns3 *
recursive-include resources *

View File

@@ -1,12 +1,15 @@
GNS3-gui
========
.. image:: https://travis-ci.org/GNS3/gns3-gui.svg?branch=master
:target: https://travis-ci.org/GNS3/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.

View File

@@ -1,6 +1,5 @@
-rrequirements.txt
pep8==1.7.0
pytest==4.4.1
pytest-pythonpath==0.7.3 # useful for running tests outside tox
pytest-timeout==1.3.3
pytest==5.4.3
flake8==3.8.3
pytest-timeout==1.4.1

View File

@@ -223,17 +223,10 @@ class ConsoleCmd(cmd.Cmd):
level = int(args[0])
if level == 0:
print("Deactivating debugging")
for handler in root.handlers:
if isinstance(handler, logging.StreamHandler):
root.removeHandler(handler)
root.setLevel(logging.INFO)
else:
root.addHandler(logging.StreamHandler(sys.stdout))
if level == 1:
print("Activating debugging")
else:
print("Activating full debugging")
root.setLevel(logging.DEBUG)
print("Activating debugging")
root.setLevel(logging.DEBUG)
from .main_window import MainWindow
MainWindow.instance().setSettings({"debug_level": level})
else:

View File

@@ -51,7 +51,7 @@ class CrashReport:
Report crash to a third party service
"""
DSN = "https://1a54ce2e5db84c5caa3bd1ad9ab5dd37:6fc7b3f8deca4a1ebf2f551b310e9b3f@o19455.ingest.sentry.io/38506"
DSN = "https://5120f215040a4d0f8fea454f6baea6a4:3d447073ba874997a4f755ccdfd0f8ed@o19455.ingest.sentry.io/38506"
_instance = None
def __init__(self):
@@ -78,12 +78,9 @@ class CrashReport:
sentry_sdk.init(dsn=CrashReport.DSN,
release=__version__,
ca_certs=cacert,
default_integrations=False,
integrations=[sentry_logging])
sentry_sdk.init(dsn=CrashReport.DSN,
release=__version__,
ca_certs=cacert)
tags = {
"os:name": platform.system(),
"os:release": platform.release(),

View File

@@ -475,8 +475,24 @@ class ApplianceWizard(QtWidgets.QWizard, Ui_ApplianceWizard):
Allow user to create a new version of an appliance
"""
new_version, ok = QtWidgets.QInputDialog.getText(self, "Creating a new version", "Create a new version for this appliance.\nPlease share your experience on the GNS3 community if this version works.\n\nVersion name:", QtWidgets.QLineEdit.Normal)
current = self.uiApplianceVersionTreeWidget.currentItem()
if current is None:
QtWidgets.QMessageBox.critical(self.parent(), "Base version", "Please select a base version")
return
base_version = current.data(0, QtCore.Qt.UserRole)
new_version_name, ok = QtWidgets.QInputDialog.getText(self, "Creating a new version", "Create a new version for this appliance.\nPlease share your experience on the GNS3 community if this version works.\n\nVersion name:", QtWidgets.QLineEdit.Normal, base_version.get("name"))
if ok:
new_version = {"name": new_version_name}
new_version["images"] = {}
for disk_type in base_version["images"]:
base_filename = base_version["images"][disk_type]["filename"]
filename, ok = QtWidgets.QInputDialog.getText(self, "Image", "Disk image filename for {}".format(disk_type), QtWidgets.QLineEdit.Normal, base_filename)
if not ok:
filename = base_filename
new_version["images"][disk_type] = {"filename": filename, "version": new_version_name}
try:
self._appliance.create_new_version(new_version)
except ApplianceError as e:

View File

@@ -237,13 +237,13 @@ class ProjectDialog(QtWidgets.QDialog, Ui_ProjectDialog):
"""
menu = QtWidgets.QMenu()
menu.triggered.connect(self._menuTriggeredSlot)
if Controller.instance().isRemote():
for action in self._main_window.recent_project_actions:
menu.addAction(action)
else:
for action in self._main_window.recent_file_actions:
menu.addAction(action)
menu.triggered.connect(self._menuTriggeredSlot)
menu.exec_(QtGui.QCursor.pos())
def _overwriteProjectCallback(self, result, error=False, **kwargs):

View File

@@ -67,7 +67,6 @@ class SetupWizard(QtWidgets.QWizard, Ui_SetupWizard):
self.uiRefreshPushButton.clicked.connect(self._refreshVMListSlot)
self.uiVmwareRadioButton.clicked.connect(self._listVMwareVMsSlot)
self.uiVirtualBoxRadioButton.clicked.connect(self._listVirtualBoxVMsSlot)
self.uiVMwareBannerButton.clicked.connect(self._VMwareBannerButtonClickedSlot)
settings = parent.settings()
self.uiShowCheckBox.setChecked(settings["hide_setup_wizard"])
@@ -94,11 +93,6 @@ class SetupWizard(QtWidgets.QWizard, Ui_SetupWizard):
self.uiLocalServerHostComboBox.addItem("::", "::") # all IPv6 addresses
self.uiLocalServerHostComboBox.addItem("0.0.0.0", "0.0.0.0") # all IPv4 addresses
if sys.platform.startswith("darwin"):
self.uiVMwareBannerButton.setIcon(QtGui.QIcon(":/images/vmware_fusion_banner.png"))
else:
self.uiVMwareBannerButton.setIcon(QtGui.QIcon(":/images/vmware_workstation_banner.png"))
if sys.platform.startswith("linux"):
self.uiLocalRadioButton.setChecked(True)
self.uiLocalLabel.setText("Dependencies like Dynamips and Qemu must be manually installed")
@@ -121,13 +115,6 @@ class SetupWizard(QtWidgets.QWizard, Ui_SetupWizard):
self.uiLocalServerPathLineEdit.setText(path)
def _VMwareBannerButtonClickedSlot(self):
if sys.platform.startswith("darwin"):
url = "http://send.onenetworkdirect.net/z/621395/CD225091/"
else:
url = "http://send.onenetworkdirect.net/z/616207/CD225091/"
QtGui.QDesktopServices.openUrl(QtCore.QUrl(url))
def _listVMwareVMsSlot(self):
"""
Slot to refresh the VMware VMs list.

View File

@@ -527,13 +527,12 @@ class GraphicsView(QtWidgets.QGraphicsView):
if is_not_link and is_not_logo and not self._adding_link:
if item and not sip.isdeleted(item):
# Right clicking on a selected item must de-select all other items
# excepting if CRTL is pressed
item.setSelected(True)
if not event.modifiers() & QtCore.Qt.ControlModifier:
for it in self.scene().items():
if item != it and it.isSelected():
# Prevent right clicking on a selected item from de-selecting all other items
if not item.isSelected():
if not event.modifiers() & QtCore.Qt.ControlModifier:
for it in self.scene().items():
it.setSelected(False)
item.setSelected(True)
self._showDeviceContextualMenu(event.globalPos())
# when more than one item is selected display the contextual menu even if mouse is not above an item
elif len(self.scene().selectedItems()) > 1:
@@ -755,6 +754,11 @@ class GraphicsView(QtWidgets.QGraphicsView):
self.populateDeviceContextualMenu(menu)
menu.exec_(pos)
menu.clear()
# Make sure to deselect all items.
# This is to prevent a bug on Windows
# see https://github.com/GNS3/gns3-gui/issues/2986
for it in self.scene().items():
it.setSelected(False)
def populateDeviceContextualMenu(self, menu):
"""

View File

@@ -212,14 +212,13 @@ class DrawingItem:
self._project.delete("/drawings/" + self._id, None, body=self.__json__())
def itemChange(self, change, value):
if change == QtWidgets.QGraphicsItem.ItemPositionHasChanged and self.isActive() and self._main_window.uiSnapToGridAction.isChecked():
if change == QtWidgets.QGraphicsItem.ItemPositionChange and self.isActive() and self._main_window.uiSnapToGridAction.isChecked():
grid_size = self._graphics_view.drawingGridSize()
mid_x = self.boundingRect().width() / 2
tmp_x = (grid_size * round((self.x() + mid_x) / grid_size)) - mid_x
value.setX((grid_size * round((value.x() + mid_x) / grid_size)) - mid_x)
mid_y = self.boundingRect().height() / 2
tmp_y = (grid_size * round((self.y() + mid_y) / grid_size)) - mid_y
if tmp_x != self.x() and tmp_y != self.y():
self.setPos(tmp_x, tmp_y)
value.setY((grid_size * round((value.y()+mid_y)/grid_size)) - mid_y)
if change == QtWidgets.QGraphicsItem.ItemSelectedChange:
if not value:

View File

@@ -255,8 +255,7 @@ def main():
current_year = datetime.date.today().year
log.info("GNS3 GUI version {}".format(__version__))
log.info("Copyright (c) 2007-{} GNS3 Technologies Inc.".format(current_year))
log.info("Application started with {}".format("".join(sys.argv)))
log.info("Application started with {}".format(" ".join(sys.argv)))
# update the exception file path to have it in the same directory as the settings file.
exception_file_path = os.path.join(LocalConfig.instance().configDirectory(), exception_file_path)

View File

@@ -1185,8 +1185,9 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
# restore debug level
if self._settings["debug_level"]:
print("Activating debugging (use command 'debug 0' to deactivate)")
root = logging.getLogger()
root.addHandler(logging.StreamHandler(sys.stdout))
root.setLevel(logging.DEBUG)
# restore the style
self._setStyle(self._settings.get("style"))

View File

@@ -654,7 +654,7 @@ class Node(BaseNode):
"""
host = self.settings()["console_host"]
if host is None or host == "::" or host == "0.0.0.0":
if host is None or host == "::" or host == "0.0.0.0" or host == "0:0:0:0:0:0:0:0":
host = Controller.instance().host()
return host

View File

@@ -115,10 +115,13 @@ class LogQMessageBox(QtWidgets.QMessageBox):
show a stack trace when a critical message box is shown in debug mode
"""
@staticmethod
def critical(parent, title, message, *args):
def critical(parent, title, message, *args, show_stack_info=False):
if message.startswith("QXcbConnection"): # Qt noise not relevant
return
LogQMessageBox._get_logger().critical(re.sub(r"<[^<]+?>", "", message), stack_info=LogQMessageBox.stack_info())
stack_info = None
if show_stack_info:
stack_info = LogQMessageBox.stack_info()
LogQMessageBox._get_logger().critical(re.sub(r"<[^<]+?>", "", message), stack_info=stack_info)
if parent is False:
# special case to display a QMessageBox before the main window is created.
parent = None

View File

@@ -19,7 +19,7 @@
import json
import copy
import os
import collections
import collections.abc
import jsonschema
@@ -30,7 +30,7 @@ class ApplianceError(Exception):
pass
class Appliance(collections.Mapping):
class Appliance(collections.abc.Mapping):
def __init__(self, registry, path):
"""
@@ -115,22 +115,14 @@ class Appliance(collections.Mapping):
if not found:
raise ApplianceError("Broken appliance missing file {} for version {}".format(filename, version["name"]))
def create_new_version(self, version_name):
def create_new_version(self, new_version):
"""
Duplicate a version in order to create a new version
"""
if 'versions' not in self._appliance.keys() or not self._appliance["versions"]:
if "versions" not in self._appliance.keys() or not self._appliance["versions"]:
raise ApplianceError("Your appliance file doesn't contain any versions")
ref = self._appliance["versions"][0]
new_version = {'name': version_name}
new_version['images'] = {}
for disk_type in ref['images']:
filename = ref['images'][disk_type]['filename']
filename = filename.replace(ref['images'][disk_type]['version'], version_name)
new_version['images'][disk_type] = {'filename': filename, 'version': version_name}
self._appliance['versions'].append(new_version)
self._appliance["versions"].append(new_version)
def search_images_for_version(self, version_name):
"""

View File

@@ -178,8 +178,9 @@ class ApplianceToTemplate:
if symbol_id.startswith(":/symbols/"):
return symbol_id
controller = Controller.instance()
path = os.path.join(Config().symbols_dir, symbol_id)
if os.path.exists(path):
if not controller.isRemote() and os.path.exists(path):
return os.path.basename(path)
if controller_symbols:
@@ -197,7 +198,6 @@ class ApplianceToTemplate:
url = "https://raw.githubusercontent.com/GNS3/gns3-registry/master/symbols/{}".format(symbol_id)
try:
self._downloadApplianceSymbol(url, path)
controller = Controller.instance()
controller.clearStaticCache()
if controller.isRemote():
controller.uploadSymbol(symbol_id, path)

View File

@@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>1081</width>
<height>534</height>
<width>1104</width>
<height>665</height>
</rect>
</property>
<property name="windowTitle">
@@ -234,33 +234,6 @@
<string>In order to run the GNS3 VM you must first have VMware or VirtualBox installed and the GNS3 VM.ova imported with one of these software.</string>
</property>
<layout class="QGridLayout" name="gridLayout_3">
<item row="0" column="0">
<widget class="QLabel" name="uiVirtualizationSoftwarLabel">
<property name="text">
<string>Virtualization software:</string>
</property>
</widget>
</item>
<item row="0" column="2" rowspan="4">
<widget class="QPushButton" name="uiVMwareBannerButton">
<property name="text">
<string/>
</property>
<property name="icon">
<iconset resource="../../resources/resources.qrc">
<normaloff>:/images/vmware_fusion_banner.png</normaloff>:/images/vmware_fusion_banner.png</iconset>
</property>
<property name="iconSize">
<size>
<width>300</width>
<height>150</height>
</size>
</property>
<property name="flat">
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QRadioButton" name="uiVmwareRadioButton">
<property name="toolTip">
@@ -274,18 +247,12 @@
</property>
</widget>
</item>
<item row="1" column="1">
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
<item row="0" column="0">
<widget class="QLabel" name="uiVirtualizationSoftwarLabel">
<property name="text">
<string>Virtualization software:</string>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>317</width>
<height>20</height>
</size>
</property>
</spacer>
</widget>
</item>
<item row="2" column="0">
<widget class="QRadioButton" name="uiVirtualBoxRadioButton">
@@ -328,7 +295,7 @@
</property>
</widget>
</item>
<item row="6" column="0" colspan="3">
<item row="6" column="0" colspan="2">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QComboBox" name="uiVMListComboBox">
@@ -349,7 +316,7 @@
</item>
</layout>
</item>
<item row="8" column="0" colspan="3">
<item row="8" column="0" colspan="2">
<widget class="QSpinBox" name="uiCPUSpinBox">
<property name="minimum">
<number>1</number>
@@ -362,7 +329,7 @@
</property>
</widget>
</item>
<item row="10" column="0" colspan="3">
<item row="10" column="0" colspan="2">
<widget class="QSpinBox" name="uiRAMSpinBox">
<property name="enabled">
<bool>true</bool>

View File

@@ -2,9 +2,10 @@
# Form implementation generated from reading ui file '/home/grossmj/PycharmProjects/gns3-gui/gns3/ui/setup_wizard.ui'
#
# Created by: PyQt5 UI code generator 5.13.0
# Created by: PyQt5 UI code generator 5.15.0
#
# 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_SetupWizard(object):
def setupUi(self, SetupWizard):
SetupWizard.setObjectName("SetupWizard")
SetupWizard.resize(1081, 534)
SetupWizard.resize(1104, 665)
SetupWizard.setModal(True)
SetupWizard.setWizardStyle(QtWidgets.QWizard.ModernStyle)
SetupWizard.setOptions(QtWidgets.QWizard.NoBackButtonOnStartPage)
@@ -114,24 +115,13 @@ class Ui_SetupWizard(object):
self.uiVMWizardPage.setObjectName("uiVMWizardPage")
self.gridLayout_3 = QtWidgets.QGridLayout(self.uiVMWizardPage)
self.gridLayout_3.setObjectName("gridLayout_3")
self.uiVirtualizationSoftwarLabel = QtWidgets.QLabel(self.uiVMWizardPage)
self.uiVirtualizationSoftwarLabel.setObjectName("uiVirtualizationSoftwarLabel")
self.gridLayout_3.addWidget(self.uiVirtualizationSoftwarLabel, 0, 0, 1, 1)
self.uiVMwareBannerButton = QtWidgets.QPushButton(self.uiVMWizardPage)
self.uiVMwareBannerButton.setText("")
icon = QtGui.QIcon()
icon.addPixmap(QtGui.QPixmap(":/images/vmware_fusion_banner.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
self.uiVMwareBannerButton.setIcon(icon)
self.uiVMwareBannerButton.setIconSize(QtCore.QSize(300, 150))
self.uiVMwareBannerButton.setFlat(True)
self.uiVMwareBannerButton.setObjectName("uiVMwareBannerButton")
self.gridLayout_3.addWidget(self.uiVMwareBannerButton, 0, 2, 4, 1)
self.uiVmwareRadioButton = QtWidgets.QRadioButton(self.uiVMWizardPage)
self.uiVmwareRadioButton.setChecked(True)
self.uiVmwareRadioButton.setObjectName("uiVmwareRadioButton")
self.gridLayout_3.addWidget(self.uiVmwareRadioButton, 1, 0, 1, 1)
spacerItem1 = QtWidgets.QSpacerItem(317, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
self.gridLayout_3.addItem(spacerItem1, 1, 1, 1, 1)
self.uiVirtualizationSoftwarLabel = QtWidgets.QLabel(self.uiVMWizardPage)
self.uiVirtualizationSoftwarLabel.setObjectName("uiVirtualizationSoftwarLabel")
self.gridLayout_3.addWidget(self.uiVirtualizationSoftwarLabel, 0, 0, 1, 1)
self.uiVirtualBoxRadioButton = QtWidgets.QRadioButton(self.uiVMWizardPage)
self.uiVirtualBoxRadioButton.setObjectName("uiVirtualBoxRadioButton")
self.gridLayout_3.addWidget(self.uiVirtualBoxRadioButton, 2, 0, 1, 1)
@@ -161,13 +151,13 @@ class Ui_SetupWizard(object):
self.uiRefreshPushButton = QtWidgets.QPushButton(self.uiVMWizardPage)
self.uiRefreshPushButton.setObjectName("uiRefreshPushButton")
self.horizontalLayout.addWidget(self.uiRefreshPushButton)
self.gridLayout_3.addLayout(self.horizontalLayout, 6, 0, 1, 3)
self.gridLayout_3.addLayout(self.horizontalLayout, 6, 0, 1, 2)
self.uiCPUSpinBox = QtWidgets.QSpinBox(self.uiVMWizardPage)
self.uiCPUSpinBox.setMinimum(1)
self.uiCPUSpinBox.setMaximum(128)
self.uiCPUSpinBox.setProperty("value", 1)
self.uiCPUSpinBox.setObjectName("uiCPUSpinBox")
self.gridLayout_3.addWidget(self.uiCPUSpinBox, 8, 0, 1, 3)
self.gridLayout_3.addWidget(self.uiCPUSpinBox, 8, 0, 1, 2)
self.uiRAMSpinBox = QtWidgets.QSpinBox(self.uiVMWizardPage)
self.uiRAMSpinBox.setEnabled(True)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed)
@@ -180,7 +170,7 @@ class Ui_SetupWizard(object):
self.uiRAMSpinBox.setSingleStep(512)
self.uiRAMSpinBox.setProperty("value", 2048)
self.uiRAMSpinBox.setObjectName("uiRAMSpinBox")
self.gridLayout_3.addWidget(self.uiRAMSpinBox, 10, 0, 1, 3)
self.gridLayout_3.addWidget(self.uiRAMSpinBox, 10, 0, 1, 2)
SetupWizard.addPage(self.uiVMWizardPage)
self.uiRemoteControllerWizardPage = QtWidgets.QWizardPage()
self.uiRemoteControllerWizardPage.setObjectName("uiRemoteControllerWizardPage")
@@ -260,9 +250,9 @@ class Ui_SetupWizard(object):
self.uiLocalServerStatusWizardPage.setSubTitle(_translate("SetupWizard", "Validation of the configuration for the local server"))
self.uiVMWizardPage.setTitle(_translate("SetupWizard", "GNS3 VM"))
self.uiVMWizardPage.setSubTitle(_translate("SetupWizard", "In order to run the GNS3 VM you must first have VMware or VirtualBox installed and the GNS3 VM.ova imported with one of these software."))
self.uiVirtualizationSoftwarLabel.setText(_translate("SetupWizard", "Virtualization software:"))
self.uiVmwareRadioButton.setToolTip(_translate("SetupWizard", "VMware is recommended to run Qemu based appliances (required for KVM)."))
self.uiVmwareRadioButton.setText(_translate("SetupWizard", "VMware (recommended)"))
self.uiVirtualizationSoftwarLabel.setText(_translate("SetupWizard", "Virtualization software:"))
self.uiVirtualBoxRadioButton.setToolTip(_translate("SetupWizard", "Use VirtualBox if you intend to only use Dynamips, IOU or VPCS."))
self.uiVirtualBoxRadioButton.setText(_translate("SetupWizard", "VirtualBox"))
self.uiVMNameLabel.setText(_translate("SetupWizard", "VM name:"))

View File

@@ -23,10 +23,9 @@
# or negative for a release candidate or beta (after the base version
# number has been incremented)
__version__ = "2.2.9"
__version_info__ = (2, 2, 9, 0)
__version__ = "2.2.15"
__version_info__ = (2, 2, 15, 0)
# If it's a git checkout try to add the commit
if "dev" in __version__:
try:
import os

View File

@@ -1,3 +1,2 @@
-rrequirements.txt
#PyQt5==5.7

View File

@@ -1,5 +1,4 @@
jsonschema==3.2.0; python_version >= '3.8' # pyup: ignore
jsonschema==2.6.0; python_version < '3.8' # pyup: ignore
jsonschema==3.2.0
sentry-sdk>=0.14.4
psutil==5.6.6
psutil==5.6.7
distro>=1.3.0

Binary file not shown.

Before

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 38 KiB

View File

@@ -326,8 +326,6 @@
<file>charcoal_icons/filter-hover.svg</file>
<file>charcoal_icons/filter-reset.svg</file>
<file>charcoal_icons/filter-reset-hover.svg</file>
<file>images/vmware_fusion_banner.png</file>
<file>images/vmware_workstation_banner.png</file>
<file>styles/charcoal.css</file>
</qresource>
</RCC>

View File

@@ -1,19 +0,0 @@
#!/bin/bash
echo '
_______ ________ _______ ______
| \ | \| \ / \
| $$$$$$$\| $$$$$$$$| $$$$$$$\| $$$$$$\
| $$__/ $$| $$__ | $$__/ $$| $$__/ $$
| $$ $$| $$ \ | $$ $$ >$$ $$
| $$$$$$$ | $$$$$ | $$$$$$$ | $$$$$$
| $$ | $$_____ | $$ | $$__/ $$
| $$ | $$ \| $$ \$$ $$
\$$ \$$$$$$$$ \$$ \$$$$$$
'
find . -name '*.py' -exec autopep8 --in-place -v --aggressive --aggressive \{\} \;
echo "It's clean"

View File

@@ -24,7 +24,7 @@ if len(sys.argv) >= 2 and sys.argv[1] == "install" and sys.version_info < (3, 4)
raise SystemExit("Python 3.4 or higher is required")
class Tox(TestCommand):
class PyTest(TestCommand):
def finalize_options(self):
TestCommand.finalize_options(self)
@@ -33,10 +33,10 @@ class Tox(TestCommand):
def run_tests(self):
# import here, cause outside the eggs aren't loaded
import tox
errcode = tox.cmdline(self.test_args)
sys.exit(errcode)
import pytest
errcode = pytest.main(self.test_args)
sys.exit(errcode)
if sys.platform.startswith('linux'):
data_files = [
@@ -61,8 +61,8 @@ setup(
version=__import__("gns3").__version__,
url="http://github.com/GNS3/gns3-gui",
license="GNU General Public License v3 (GPLv3)",
tests_require=["tox"],
cmdclass={"test": Tox},
tests_require=["pytest"],
cmdclass={"test": PyTest},
author="Jeremy Grossmann",
author_email="package-maintainer@gns3.net",
description="GNS3 graphical interface for the GNS3 server.",

View File

@@ -171,8 +171,8 @@ def test_create_new_version():
os.path.dirname(__file__), "appliances", "microcore-linux.gns3a")
a = Appliance(registry, appliance_path)
a.create_new_version("42.0")
new_version = {'images': {'hda_disk_image': {'filename': 'linux-microcore-42.0.img', 'version': '42.0'}}, 'name': '42.0'}
a.create_new_version(new_version)
v = a['versions'][-1:][0]
assert v == {
'images':

View File

@@ -22,6 +22,7 @@ import json
from unittest.mock import patch, MagicMock
from gns3.local_config import LocalConfig
from gns3.version import __version_info__
@pytest.fixture
@@ -119,16 +120,17 @@ def test_migrateOldConfigOSX(tmpdir):
local_config = LocalConfig()
assert os.path.exists(str(tmpdir / '.config' / 'GNS3'))
assert os.path.exists(str(tmpdir / '.config' / 'GNS3' / 'hello'))
version = "{}.{}".format(__version_info__[0], __version_info__[1])
assert os.path.exists(str(tmpdir / '.config' / 'GNS3' / version))
assert os.path.exists(str(tmpdir / '.config' / 'GNS3' / version / 'hello'))
assert os.path.exists(str(tmpdir / '.config' / 'gns3.net'))
# It should migrate only one time
open(str(tmpdir / '.config' / 'gns3.net' / 'world'), 'w+').close()
local_config._migrateOldConfigPath()
assert os.path.exists(str(tmpdir / '.config' / 'GNS3' / 'hello'))
assert not os.path.exists(str(tmpdir / '.config' / 'GNS3' / 'world'))
assert os.path.exists(str(tmpdir / '.config' / 'GNS3' / version / 'hello'))
assert not os.path.exists(str(tmpdir / '.config' / 'GNS3' / version / 'world'))
def test_migrate13Config(tmpdir):

19
tox.ini
View File

@@ -1,19 +0,0 @@
[tox]
envlist = py34
[testenv]
sitepackages=True
setenv = PYTHONPATH={toxinidir}
commands = py.test
[pep8]
ignore = E501,E402
[flake8]
ignore = E265,E501
exclude = tests/*,gns3/ui/*,./gns3/modules/*/ui
[pytest]
python_paths = {toxinidir}
norecursedirs = .tox
timeout = 10