Compare commits

...

14 Commits

Author SHA1 Message Date
grossmj
f0e5cd2ba2 Release v2.2.16 2020-11-05 15:38:19 +10:30
grossmj
f59ef6378a Fix broken security link (replaced by email). Fixes #3085 2020-11-05 15:00:04 +10:30
grossmj
61ef08d1b7 Fix packets capture stops after some time. Fixes #3067 2020-11-05 14:21:22 +10:30
grossmj
e812c000fd Option to allocate or not the vCPUs and RAM settings for the GNS3 VM. Fixes https://github.com/GNS3/gns3-gui/issues/3069 2020-11-05 11:13:57 +10:30
grossmj
4b0cc11cab Development on 2.2.16dev1 2020-10-07 16:30:03 +10:30
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
14 changed files with 154 additions and 95 deletions

View File

@@ -1,5 +1,22 @@
# Change Log
## 2.2.16 05/11/2020
* Fix packets capture stops after some time. Fixes #3067
* Option to allocate or not the vCPUs and RAM settings for the GNS3 VM. Fixes https://github.com/GNS3/gns3-gui/issues/3069
## 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

View File

@@ -54,6 +54,7 @@ https://github.com/Kozea/wdb
Security issues
----------------
Please contact us using contact informations available here:
http://docs.gns3.com/1ON9JBXSeR7Nt2-Qum2o3ZX0GU86BZwlmNSUgvmqNWGY/index.html
Please contact us at security@gns3.net

View File

@@ -51,7 +51,7 @@ class CrashReport:
Report crash to a third party service
"""
DSN = "https://19d5ca7c4cfe447b92ea140f78b01c35:fd234a69afcc490bb7ca37bbb3eefefd@o19455.ingest.sentry.io/38506"
DSN = "https://7327ec4a849d436dba47b2fea9e2420e:efa92865e9534a22afab21a47692de8e@o19455.ingest.sentry.io/38506"
_instance = None
def __init__(self):

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

@@ -50,6 +50,7 @@ class SetupWizard(QtWidgets.QWizard, Ui_SetupWizard):
"headless": False,
"when_exit": "stop",
"engine": "vmware",
"allocate_vcpus_ram": True,
"vcpus": 1,
"ram": 2048,
"vmname": "GNS3 VM",

View File

@@ -19,7 +19,6 @@
Manages and stores everything needed for a connection between 2 devices.
"""
import os
import re
from .qt import sip
import uuid
@@ -79,6 +78,7 @@ class Link(QtCore.QObject):
self._deleting = False
self._capture_file_path = None
self._capture_file = None
self._response_stream = None
self._capture_compute_id = None
self._initialized = False
self._filters = {}
@@ -119,13 +119,15 @@ class Link(QtCore.QObject):
else:
self._capture_file = QtCore.QFile(self._capture_file_path)
self._capture_file.open(QtCore.QFile.WriteOnly)
Controller.instance().get("/projects/{project_id}/links/{link_id}/pcap".format(project_id=self.project().id(), link_id=self._link_id),
None,
showProgress=False,
downloadProgressCallback=self._downloadPcapProgress,
ignoreErrors=True, # If something is wrong avoid disconnect us from server
timeout=None)
log.debug("Capturing packets to '{}'".format(self._capture_file_path))
self._response_stream = Controller.instance().get("/projects/{project_id}/links/{link_id}/pcap".format(project_id=self.project().id(), link_id=self._link_id),
None,
showProgress=False,
downloadProgressCallback=self._downloadPcapProgress,
ignoreErrors=True, # If something is wrong avoid disconnect us from server
timeout=None)
log.debug("Has successfully started capturing packets on link {} to '{}'".format(self._link_id, self._capture_file_path))
else:
self._response_stream = None
if "nodes" in result:
self._nodes = result["nodes"]
@@ -356,9 +358,8 @@ class Link(QtCore.QObject):
def _startCaptureCallback(self, result, error=False, **kwargs):
if error:
log.error("Error while starting capture on link: {}".format(result["message"]))
log.error("Error while starting capture on link {}: {}".format(self._link_id, result["message"]))
return
#self._parseResponse(result)
def _downloadPcapProgress(self, content, server=None, context={}, **kwargs):
"""
@@ -386,11 +387,12 @@ class Link(QtCore.QObject):
link_id=self._link_id),
self._stopCaptureCallback)
def _stopCaptureCallback(self, result, error=False, **kwargs):
if error:
log.error("Error while stopping capture on link: {}".format(result["message"]))
log.error("Error while stopping capture on link {}: {}".format(self._link_id, result["message"]))
return
#self._parseResponse(result)
log.debug("Has successfully stopped capturing packets on link {}".format(self._link_id))
def get(self, path, callback, **kwargs):
"""

View File

@@ -90,12 +90,11 @@ class PacketCapture:
def _updatedLinkSlot(self, link_id):
link = self.topology().getLink(link_id)
if link:
if link.capturing():
if self._autostart.get(link) and link not in self._tail_process:
log.debug("Starting packet capture reader for link {}".format(link.link_id()))
self.startPacketCaptureReader(link)
log.debug("Has successfully started capturing packets on {} to {}".format(link.id(), link.capture_file_path()))
else:
self.stopPacketCaptureReader(link)
@@ -108,7 +107,6 @@ class PacketCapture:
"""
link.stopCapture()
log.debug("Has successfully stopped capturing packets on {}".format(link.id()))
def startPacketCaptureReader(self, link):
"""
@@ -121,6 +119,7 @@ class PacketCapture:
Stop the packet capture reader
"""
if link in self._tail_process and self._tail_process[link].poll() is None:
log.debug("Stopping packet capture reader for link {}".format(link.link_id()))
self._tail_process[link].kill()
del self._tail_process[link]

View File

@@ -42,6 +42,7 @@ class GNS3VMPreferencesPage(QtWidgets.QWidget, Ui_GNS3VMPreferencesPageWidget):
self._initialized = False
self.uiRefreshPushButton.clicked.connect(self._refreshVMSlot)
self.uiGNS3VMEngineComboBox.currentIndexChanged.connect(self._engineChangedSlot)
self.uiAllocatevCPUsRAMCheckBox.stateChanged.connect(self._allocatevCPUsRAMSlot)
Controller.instance().connected_signal.connect(self.loadPreferences)
def pageInitialized(self):
@@ -74,6 +75,18 @@ class GNS3VMPreferencesPage(QtWidgets.QWidget, Ui_GNS3VMPreferencesPageWidget):
self.uiPortSpinBox.setVisible(True)
self._refreshVMSlot(ignore_error=True)
def _allocatevCPUsRAMSlot(self, state):
"""
Slot to enable or not the vCPUS and RAM spin boxes.
"""
if state:
self.uiRamSpinBox.setEnabled(True)
self.uiCpuSpinBox.setEnabled(True)
else:
self.uiRamSpinBox.setEnabled(False)
self.uiCpuSpinBox.setEnabled(False)
def loadPreferences(self):
"""
Loads the preference from controller.
@@ -95,6 +108,7 @@ class GNS3VMPreferencesPage(QtWidgets.QWidget, Ui_GNS3VMPreferencesPageWidget):
return
self._old_settings = copy.copy(result)
self._settings = result
self.uiAllocatevCPUsRAMCheckBox.setChecked(self._settings["allocate_vcpus_ram"])
self.uiRamSpinBox.setValue(self._settings["ram"])
self.uiCpuSpinBox.setValue(self._settings["vcpus"])
self.uiPortSpinBox.setValue(self._settings.get("port", 3080))
@@ -174,6 +188,7 @@ class GNS3VMPreferencesPage(QtWidgets.QWidget, Ui_GNS3VMPreferencesPageWidget):
"headless": self.uiHeadlessCheckBox.isChecked(),
"when_exit": when_exit,
"engine": self.uiGNS3VMEngineComboBox.currentData(),
"allocate_vcpus_ram": self.uiAllocatevCPUsRAMCheckBox.isChecked(),
"ram": self.uiRamSpinBox.value(),
"vcpus": self.uiCpuSpinBox.value(),
"port": self.uiPortSpinBox.value()

View File

@@ -115,22 +115,14 @@ class Appliance(collections.abc.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

@@ -85,28 +85,28 @@
<string>Settings</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="8" column="0" colspan="2">
<widget class="QLabel" name="uiActionCloseLabel">
<property name="text">
<string>Action when closing GNS3:</string>
</property>
</widget>
</item>
<item row="1" column="0" colspan="2">
<item row="3" column="0" colspan="2">
<widget class="QCheckBox" name="uiHeadlessCheckBox">
<property name="text">
<string>Run the VM in headless mode</string>
</property>
</widget>
</item>
<item row="9" column="0" colspan="2">
<item row="11" column="0" colspan="2">
<widget class="QLabel" name="uiActionCloseLabel">
<property name="text">
<string>Action when closing GNS3:</string>
</property>
</widget>
</item>
<item row="12" column="0" colspan="2">
<widget class="QRadioButton" name="uiWhenExitKeepRadioButton">
<property name="text">
<string>keep the GNS3 VM running</string>
</property>
</widget>
</item>
<item row="10" column="0" colspan="2">
<item row="13" column="0" colspan="2">
<widget class="QRadioButton" name="uiWhenExitSuspendRadioButton">
<property name="text">
<string>suspend the GNS3 VM</string>
@@ -141,22 +141,25 @@
</item>
</layout>
</item>
<item row="11" column="0" colspan="2">
<item row="14" column="0" colspan="2">
<widget class="QRadioButton" name="uiWhenExitStopRadioButton">
<property name="text">
<string>stop the GNS3 VM</string>
</property>
</widget>
</item>
<item row="4" column="0">
<item row="6" column="0">
<widget class="QLabel" name="uiRamLabel">
<property name="text">
<string>RAM:</string>
</property>
</widget>
</item>
<item row="4" column="1">
<item row="6" column="1">
<widget class="QSpinBox" name="uiRamSpinBox">
<property name="enabled">
<bool>false</bool>
</property>
<property name="suffix">
<string> MB</string>
</property>
@@ -174,23 +177,6 @@
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="QSpinBox" name="uiCpuSpinBox">
<property name="minimum">
<number>1</number>
</property>
<property name="value">
<number>1</number>
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QLabel" name="uiCpuLabel">
<property name="text">
<string>vCPUs:</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="uiPortLabel">
<property name="text">
@@ -211,6 +197,33 @@
</property>
</widget>
</item>
<item row="4" column="0" colspan="2">
<widget class="QCheckBox" name="uiAllocatevCPUsRAMCheckBox">
<property name="text">
<string>Allocate vCPUs and RAM</string>
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QLabel" name="uiCpuLabel">
<property name="text">
<string>vCPUs:</string>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="QSpinBox" name="uiCpuSpinBox">
<property name="enabled">
<bool>false</bool>
</property>
<property name="minimum">
<number>1</number>
</property>
<property name="value">
<number>1</number>
</property>
</widget>
</item>
</layout>
</widget>
</item>
@@ -234,9 +247,7 @@
<tabstop>uiGNS3VMEngineComboBox</tabstop>
<tabstop>uiVMListComboBox</tabstop>
<tabstop>uiRefreshPushButton</tabstop>
<tabstop>uiHeadlessCheckBox</tabstop>
<tabstop>uiRamSpinBox</tabstop>
<tabstop>uiCpuSpinBox</tabstop>
<tabstop>uiWhenExitKeepRadioButton</tabstop>
<tabstop>uiWhenExitSuspendRadioButton</tabstop>
<tabstop>uiWhenExitStopRadioButton</tabstop>

View File

@@ -2,9 +2,10 @@
# Form implementation generated from reading ui file '/home/grossmj/PycharmProjects/gns3-gui/gns3/ui/gns3_vm_preferences_page.ui'
#
# Created by: PyQt5 UI code generator 5.13.2
# 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
@@ -54,18 +55,18 @@ class Ui_GNS3VMPreferencesPageWidget(object):
self.uiGNS3VMSettingsGroupBox.setObjectName("uiGNS3VMSettingsGroupBox")
self.gridLayout = QtWidgets.QGridLayout(self.uiGNS3VMSettingsGroupBox)
self.gridLayout.setObjectName("gridLayout")
self.uiActionCloseLabel = QtWidgets.QLabel(self.uiGNS3VMSettingsGroupBox)
self.uiActionCloseLabel.setObjectName("uiActionCloseLabel")
self.gridLayout.addWidget(self.uiActionCloseLabel, 8, 0, 1, 2)
self.uiHeadlessCheckBox = QtWidgets.QCheckBox(self.uiGNS3VMSettingsGroupBox)
self.uiHeadlessCheckBox.setObjectName("uiHeadlessCheckBox")
self.gridLayout.addWidget(self.uiHeadlessCheckBox, 1, 0, 1, 2)
self.gridLayout.addWidget(self.uiHeadlessCheckBox, 3, 0, 1, 2)
self.uiActionCloseLabel = QtWidgets.QLabel(self.uiGNS3VMSettingsGroupBox)
self.uiActionCloseLabel.setObjectName("uiActionCloseLabel")
self.gridLayout.addWidget(self.uiActionCloseLabel, 11, 0, 1, 2)
self.uiWhenExitKeepRadioButton = QtWidgets.QRadioButton(self.uiGNS3VMSettingsGroupBox)
self.uiWhenExitKeepRadioButton.setObjectName("uiWhenExitKeepRadioButton")
self.gridLayout.addWidget(self.uiWhenExitKeepRadioButton, 9, 0, 1, 2)
self.gridLayout.addWidget(self.uiWhenExitKeepRadioButton, 12, 0, 1, 2)
self.uiWhenExitSuspendRadioButton = QtWidgets.QRadioButton(self.uiGNS3VMSettingsGroupBox)
self.uiWhenExitSuspendRadioButton.setObjectName("uiWhenExitSuspendRadioButton")
self.gridLayout.addWidget(self.uiWhenExitSuspendRadioButton, 10, 0, 1, 2)
self.gridLayout.addWidget(self.uiWhenExitSuspendRadioButton, 13, 0, 1, 2)
self.uiVMNameLabel = QtWidgets.QLabel(self.uiGNS3VMSettingsGroupBox)
self.uiVMNameLabel.setObjectName("uiVMNameLabel")
self.gridLayout.addWidget(self.uiVMNameLabel, 0, 0, 1, 1)
@@ -85,25 +86,18 @@ class Ui_GNS3VMPreferencesPageWidget(object):
self.gridLayout.addLayout(self.horizontalLayout, 0, 1, 1, 1)
self.uiWhenExitStopRadioButton = QtWidgets.QRadioButton(self.uiGNS3VMSettingsGroupBox)
self.uiWhenExitStopRadioButton.setObjectName("uiWhenExitStopRadioButton")
self.gridLayout.addWidget(self.uiWhenExitStopRadioButton, 11, 0, 1, 2)
self.gridLayout.addWidget(self.uiWhenExitStopRadioButton, 14, 0, 1, 2)
self.uiRamLabel = QtWidgets.QLabel(self.uiGNS3VMSettingsGroupBox)
self.uiRamLabel.setObjectName("uiRamLabel")
self.gridLayout.addWidget(self.uiRamLabel, 4, 0, 1, 1)
self.gridLayout.addWidget(self.uiRamLabel, 6, 0, 1, 1)
self.uiRamSpinBox = QtWidgets.QSpinBox(self.uiGNS3VMSettingsGroupBox)
self.uiRamSpinBox.setEnabled(False)
self.uiRamSpinBox.setMinimum(512)
self.uiRamSpinBox.setMaximum(1000000)
self.uiRamSpinBox.setSingleStep(512)
self.uiRamSpinBox.setProperty("value", 2048)
self.uiRamSpinBox.setObjectName("uiRamSpinBox")
self.gridLayout.addWidget(self.uiRamSpinBox, 4, 1, 1, 1)
self.uiCpuSpinBox = QtWidgets.QSpinBox(self.uiGNS3VMSettingsGroupBox)
self.uiCpuSpinBox.setMinimum(1)
self.uiCpuSpinBox.setProperty("value", 1)
self.uiCpuSpinBox.setObjectName("uiCpuSpinBox")
self.gridLayout.addWidget(self.uiCpuSpinBox, 5, 1, 1, 1)
self.uiCpuLabel = QtWidgets.QLabel(self.uiGNS3VMSettingsGroupBox)
self.uiCpuLabel.setObjectName("uiCpuLabel")
self.gridLayout.addWidget(self.uiCpuLabel, 5, 0, 1, 1)
self.gridLayout.addWidget(self.uiRamSpinBox, 6, 1, 1, 1)
self.uiPortLabel = QtWidgets.QLabel(self.uiGNS3VMSettingsGroupBox)
self.uiPortLabel.setObjectName("uiPortLabel")
self.gridLayout.addWidget(self.uiPortLabel, 2, 0, 1, 1)
@@ -113,6 +107,18 @@ class Ui_GNS3VMPreferencesPageWidget(object):
self.uiPortSpinBox.setProperty("value", 80)
self.uiPortSpinBox.setObjectName("uiPortSpinBox")
self.gridLayout.addWidget(self.uiPortSpinBox, 2, 1, 1, 1)
self.uiAllocatevCPUsRAMCheckBox = QtWidgets.QCheckBox(self.uiGNS3VMSettingsGroupBox)
self.uiAllocatevCPUsRAMCheckBox.setObjectName("uiAllocatevCPUsRAMCheckBox")
self.gridLayout.addWidget(self.uiAllocatevCPUsRAMCheckBox, 4, 0, 1, 2)
self.uiCpuLabel = QtWidgets.QLabel(self.uiGNS3VMSettingsGroupBox)
self.uiCpuLabel.setObjectName("uiCpuLabel")
self.gridLayout.addWidget(self.uiCpuLabel, 5, 0, 1, 1)
self.uiCpuSpinBox = QtWidgets.QSpinBox(self.uiGNS3VMSettingsGroupBox)
self.uiCpuSpinBox.setEnabled(False)
self.uiCpuSpinBox.setMinimum(1)
self.uiCpuSpinBox.setProperty("value", 1)
self.uiCpuSpinBox.setObjectName("uiCpuSpinBox")
self.gridLayout.addWidget(self.uiCpuSpinBox, 5, 1, 1, 1)
self.verticalLayout.addWidget(self.uiGNS3VMSettingsGroupBox)
spacerItem = QtWidgets.QSpacerItem(10, 10, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
self.verticalLayout.addItem(spacerItem)
@@ -122,10 +128,8 @@ class Ui_GNS3VMPreferencesPageWidget(object):
GNS3VMPreferencesPageWidget.setTabOrder(self.uiEnableVMCheckBox, self.uiGNS3VMEngineComboBox)
GNS3VMPreferencesPageWidget.setTabOrder(self.uiGNS3VMEngineComboBox, self.uiVMListComboBox)
GNS3VMPreferencesPageWidget.setTabOrder(self.uiVMListComboBox, self.uiRefreshPushButton)
GNS3VMPreferencesPageWidget.setTabOrder(self.uiRefreshPushButton, self.uiHeadlessCheckBox)
GNS3VMPreferencesPageWidget.setTabOrder(self.uiHeadlessCheckBox, self.uiRamSpinBox)
GNS3VMPreferencesPageWidget.setTabOrder(self.uiRamSpinBox, self.uiCpuSpinBox)
GNS3VMPreferencesPageWidget.setTabOrder(self.uiCpuSpinBox, self.uiWhenExitKeepRadioButton)
GNS3VMPreferencesPageWidget.setTabOrder(self.uiRefreshPushButton, self.uiRamSpinBox)
GNS3VMPreferencesPageWidget.setTabOrder(self.uiRamSpinBox, self.uiWhenExitKeepRadioButton)
GNS3VMPreferencesPageWidget.setTabOrder(self.uiWhenExitKeepRadioButton, self.uiWhenExitSuspendRadioButton)
GNS3VMPreferencesPageWidget.setTabOrder(self.uiWhenExitSuspendRadioButton, self.uiWhenExitStopRadioButton)
@@ -136,8 +140,8 @@ class Ui_GNS3VMPreferencesPageWidget(object):
self.uiVirtualizationGroupBox.setTitle(_translate("GNS3VMPreferencesPageWidget", "Virtualization engine"))
self.uiEngineDescriptionLabel.setText(_translate("GNS3VMPreferencesPageWidget", "Description"))
self.uiGNS3VMSettingsGroupBox.setTitle(_translate("GNS3VMPreferencesPageWidget", "Settings"))
self.uiActionCloseLabel.setText(_translate("GNS3VMPreferencesPageWidget", "Action when closing GNS3:"))
self.uiHeadlessCheckBox.setText(_translate("GNS3VMPreferencesPageWidget", "Run the VM in headless mode"))
self.uiActionCloseLabel.setText(_translate("GNS3VMPreferencesPageWidget", "Action when closing GNS3:"))
self.uiWhenExitKeepRadioButton.setText(_translate("GNS3VMPreferencesPageWidget", "keep the GNS3 VM running"))
self.uiWhenExitSuspendRadioButton.setText(_translate("GNS3VMPreferencesPageWidget", "suspend the GNS3 VM"))
self.uiVMNameLabel.setText(_translate("GNS3VMPreferencesPageWidget", "VM name:"))
@@ -145,5 +149,6 @@ class Ui_GNS3VMPreferencesPageWidget(object):
self.uiWhenExitStopRadioButton.setText(_translate("GNS3VMPreferencesPageWidget", "stop the GNS3 VM"))
self.uiRamLabel.setText(_translate("GNS3VMPreferencesPageWidget", "RAM:"))
self.uiRamSpinBox.setSuffix(_translate("GNS3VMPreferencesPageWidget", " MB"))
self.uiCpuLabel.setText(_translate("GNS3VMPreferencesPageWidget", "vCPUs:"))
self.uiPortLabel.setText(_translate("GNS3VMPreferencesPageWidget", "Port:"))
self.uiAllocatevCPUsRAMCheckBox.setText(_translate("GNS3VMPreferencesPageWidget", "Allocate vCPUs and RAM"))
self.uiCpuLabel.setText(_translate("GNS3VMPreferencesPageWidget", "vCPUs:"))

View File

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

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':