Browse Source

Add patches

master
Pekka Helenius 2 years ago
parent
commit
19e4093603
4 changed files with 935 additions and 0 deletions
  1. +266
    -0
      patches/gns3-gui/patch_gns3gui_linkcolors.patch
  2. +432
    -0
      patches/gns3-gui/patch_gns3gui_qemu-envvars.patch
  3. +107
    -0
      patches/gns3-server/patch_gns3server_linkcolors.patch
  4. +130
    -0
      patches/gns3-server/patch_gns3server_qemu-envvars.patch

+ 266
- 0
patches/gns3-gui/patch_gns3gui_linkcolors.patch View File

@ -0,0 +1,266 @@
Author: Pekka Helenius <pekka.helenius@fjordtek.com>
Date: Sun, 6 Jun 2021 15:15:14 +0200
Subject: [PATCH] GNS3 GUI: Link colors.
Add link color support for GNS3 GUI.
--- a/gns3/items/serial_link_item.py
+++ b/gns3/items/serial_link_item.py
@@ -50,10 +50,16 @@
LinkItem.adjust(self)
- if self._hovered:
- self.setPen(QtGui.QPen(QtCore.Qt.red, self._pen_width + 1, QtCore.Qt.SolidLine, QtCore.Qt.RoundCap, QtCore.Qt.RoundJoin))
- else:
- self.setPen(QtGui.QPen(QtCore.Qt.darkRed, self._pen_width, QtCore.Qt.SolidLine, QtCore.Qt.RoundCap, QtCore.Qt.RoundJoin))
+ try:
+ if self._hovered:
+ self.setPen(QtGui.QPen(QtCore.Qt.red, self._link._link_style["width"] + 1, QtCore.Qt.SolidLine, QtCore.Qt.RoundCap, QtCore.Qt.RoundJoin))
+ else:
+ self.setPen(QtGui.QPen(QtGui.QColor(self._link._link_style["color"]), self._link._link_style["width"], self._link._link_style["type"], QtCore.Qt.RoundCap, QtCore.Qt.RoundJoin))
+ except:
+ if self._hovered:
+ self.setPen(QtGui.QPen(QtCore.Qt.red, self._pen_width + 1, QtCore.Qt.SolidLine, QtCore.Qt.RoundCap, QtCore.Qt.RoundJoin))
+ else:
+ self.setPen(QtGui.QPen(QtCore.Qt.darkRed, self._pen_width, QtCore.Qt.SolidLine, QtCore.Qt.RoundCap, QtCore.Qt.RoundJoin))
# get source to destination angle
vector_angle = math.atan2(self.dy, self.dx)
--- a/gns3/items/link_item.py
+++ b/gns3/items/link_item.py
@@ -25,6 +25,7 @@
from ..packet_capture import PacketCapture
from ..dialogs.filter_dialog import FilterDialog
+from ..dialogs.style_editor_dialog_link import StyleEditorDialogLink
from ..utils.get_icon import get_icon
@@ -40,7 +41,6 @@
self.parentItem().mousePressEvent(event)
event.accept()
-
class LinkItem(QtWidgets.QGraphicsPathItem):
"""
@@ -137,6 +137,21 @@
def _suspendActionSlot(self, *args):
self._link.toggleSuspend()
+ @qslot
+ def _styleActionSlot(self, *args):
+ style_dialog = StyleEditorDialogLink(self, self._main_window)
+ style_dialog.show()
+ style_dialog.exec_()
+
+ def setLinkStyle(self, link_style):
+ self._link._link_style["color"] = link_style["color"]
+ self._link._link_style["width"] = link_style["width"]
+ self._link._link_style["type"] = link_style["type"]
+
+ # This refers to functions in link.py!
+ self._link.setLinkStyle(link_style)
+ self._link.update()
+
def delete(self):
"""
Delete this link
@@ -266,6 +281,12 @@
resume_action.triggered.connect(self._suspendActionSlot)
menu.addAction(resume_action)
+ # style
+ style_action = QtWidgets.QAction("Style", menu)
+ style_action.setIcon(get_icon("node_conception.svg"))
+ style_action.triggered.connect(self._styleActionSlot)
+ menu.addAction(style_action)
+
# delete
delete_action = QtWidgets.QAction("Delete", menu)
delete_action.setIcon(get_icon('delete.svg'))
--- a/gns3/items/ethernet_link_item.py
+++ b/gns3/items/ethernet_link_item.py
@@ -1,5 +1,6 @@
# -*- coding: utf-8 -*-
#
+# Copyright (C) 2019 Pekka Helenius
# Copyright (C) 2014 GNS3 Technologies Inc.
#
# This program is free software: you can redistribute it and/or modify
@@ -51,10 +52,16 @@
LinkItem.adjust(self)
- if self._hovered:
- self.setPen(QtGui.QPen(QtCore.Qt.red, self._pen_width + 1, QtCore.Qt.SolidLine, QtCore.Qt.RoundCap, QtCore.Qt.RoundJoin))
- else:
- self.setPen(QtGui.QPen(QtCore.Qt.black, self._pen_width, QtCore.Qt.SolidLine, QtCore.Qt.RoundCap, QtCore.Qt.RoundJoin))
+ try:
+ if self._hovered:
+ self.setPen(QtGui.QPen(QtCore.Qt.red, self._link._link_style["width"] + 1, QtCore.Qt.SolidLine, QtCore.Qt.RoundCap, QtCore.Qt.RoundJoin))
+ else:
+ self.setPen(QtGui.QPen(QtGui.QColor(self._link._link_style["color"]), self._link._link_style["width"], self._link._link_style["type"], QtCore.Qt.RoundCap, QtCore.Qt.RoundJoin))
+ except:
+ if self._hovered:
+ self.setPen(QtGui.QPen(QtCore.Qt.red, self._pen_width + 1, QtCore.Qt.SolidLine, QtCore.Qt.RoundCap, QtCore.Qt.RoundJoin))
+ else:
+ self.setPen(QtGui.QPen(QtGui.QColor("#000000"), self._pen_width, QtCore.Qt.SolidLine, QtCore.Qt.RoundCap, QtCore.Qt.RoundJoin))
# draw a line between nodes
path = QtGui.QPainterPath(self.source)
--- /dev/null 2019-05-22 14:27:07.219999993 +0300
+++ b/gns3/dialogs/style_editor_dialog_link.py
@@ -0,0 +1,112 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2019 Pekka Helenius
+# Copyright (C) 2014 GNS3 Technologies Inc.
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+"""
+Style editor to edit Link items.
+"""
+
+from ..qt import QtCore, QtWidgets, QtGui
+from ..ui.style_editor_dialog_ui import Ui_StyleEditorDialog
+
+
+class StyleEditorDialogLink(QtWidgets.QDialog, Ui_StyleEditorDialog):
+
+ """
+ Style editor dialog.
+
+ :param parent: parent widget
+ :param link: selected link
+ """
+
+ def __init__(self, link, parent):
+
+ super().__init__(parent)
+ self.setupUi(self)
+
+ self._link = link
+ self._link_style = {}
+
+ self.uiBorderColorPushButton.clicked.connect(self._setBorderColorSlot)
+ self.uiButtonBox.button(QtWidgets.QDialogButtonBox.Apply).clicked.connect(self._applyPreferencesSlot)
+
+ self.uiBorderStyleComboBox.addItem("Solid", QtCore.Qt.SolidLine)
+ self.uiBorderStyleComboBox.addItem("Dash", QtCore.Qt.DashLine)
+ self.uiBorderStyleComboBox.addItem("Dot", QtCore.Qt.DotLine)
+ self.uiBorderStyleComboBox.addItem("Dash Dot", QtCore.Qt.DashDotLine)
+ self.uiBorderStyleComboBox.addItem("Dash Dot Dot", QtCore.Qt.DashDotDotLine)
+
+ self.uiColorLabel.hide()
+ self.uiColorPushButton.hide()
+ self._color = None
+
+ self.uiRotationLabel.hide()
+ self.uiRotationSpinBox.hide()
+
+ pen = link.pen()
+
+ self._border_color = pen.color()
+ self.uiBorderColorPushButton.setStyleSheet("background-color: rgba({}, {}, {}, {});".format(self._border_color.red(),
+ self._border_color.green(),
+ self._border_color.blue(),
+ self._border_color.alpha()))
+ self.uiBorderWidthSpinBox.setValue(pen.width())
+ index = self.uiBorderStyleComboBox.findData(pen.style())
+ if index != -1:
+ self.uiBorderStyleComboBox.setCurrentIndex(index)
+
+ def _setBorderColorSlot(self):
+ """
+ Slot to select the border color.
+ """
+
+ color = QtWidgets.QColorDialog.getColor(self._border_color, self, "Select Color", QtWidgets.QColorDialog.ShowAlphaChannel)
+ if color.isValid():
+ self._border_color = color
+ self.uiBorderColorPushButton.setStyleSheet("background-color: rgba({}, {}, {}, {});".format(self._border_color.red(),
+ self._border_color.green(),
+ self._border_color.blue(),
+ self._border_color.alpha()))
+
+ def _applyPreferencesSlot(self):
+ """
+ Applies the new style settings.
+ """
+
+ border_style = QtCore.Qt.PenStyle(self.uiBorderStyleComboBox.itemData(self.uiBorderStyleComboBox.currentIndex()))
+ pen = QtGui.QPen(self._border_color, self.uiBorderWidthSpinBox.value(), border_style, QtCore.Qt.RoundCap, QtCore.Qt.RoundJoin)
+
+ self._link.setPen(pen)
+
+ new_link_style = {}
+ new_link_style["color"] = self._border_color.name()
+ new_link_style["width"] = self.uiBorderWidthSpinBox.value()
+ new_link_style["type"] = border_style
+
+ # Store values
+ self._link.setLinkStyle(new_link_style)
+
+ def done(self, result):
+ """
+ Called when the dialog is closed.
+
+ :param result: boolean (accepted or rejected)
+ """
+
+ if result:
+ self._applyPreferencesSlot()
+ super().done(result)
--- a/gns3/link.py
+++ b/gns3/link.py
@@ -90,6 +90,8 @@
self._nodes = []
+ self._link_style = {}
+
self._source_node.addLink(self)
self._destination_node.addLink(self)
@@ -127,6 +129,8 @@
self._updateLabels()
if "filters" in result:
self._filters = result["filters"]
+ if "link_style" in result:
+ self._link_style = result["link_style"]
if "suspend" in result:
self._suspend = result["suspend"]
self.updated_link_signal.emit(self._id)
@@ -209,6 +213,7 @@
}
],
"filters": self._filters,
+ "link_style": self._link_style,
"suspend": self._suspend
}
if self._source_port.label():
@@ -462,3 +467,9 @@
:params filters: List of filters
"""
self._filters = filters
+
+ def setLinkStyle(self, link_style):
+ """
+ :params _link_style: Set link style attributes
+ """
+ self._link_style = link_style

+ 432
- 0
patches/gns3-gui/patch_gns3gui_qemu-envvars.patch View File

@ -0,0 +1,432 @@
Author: Pekka Helenius <pekka.helenius@fjordtek.com>
Date: Sun, 6 Jun 2021 15:10:45 +0200
Subject: [PATCH] GNS3 GUI: QEMU environment variables.
Add support for QEMU environment variables for GNS3 GUI.
--- a/tests/test_local_config.py
+++ b/tests/test_local_config.py
@@ -285,6 +285,7 @@
"enable_kvm": True,
"vms": [
{
+ "env_vars": "",
"kernel_image": "",
"kernel_command_line": "",
"first_port_name": "",
@@ -323,6 +324,7 @@
"platform": ""
},
{
+ "env_vars": "",
"kernel_image": "",
"kernel_command_line": "",
"server": "vm",
--- a/gns3/modules/qemu/settings.py
+++ b/gns3/modules/qemu/settings.py
@@ -27,6 +27,7 @@
}
QEMU_VM_SETTINGS = {
+ "env_vars": "",
"name": "",
"default_name_format": "{name}-{0}",
"usage": "",
--- a/gns3/modules/qemu/qemu_vm.py
+++ b/gns3/modules/qemu/qemu_vm.py
@@ -42,7 +42,8 @@
self._linked_clone = True
- qemu_vm_settings = {"usage": "",
+ qemu_vm_settings = {"env_vars": "",
+ "usage": "",
"qemu_path": "",
"hda_disk_image": "",
"hdb_disk_image": "",
--- a/gns3/modules/qemu/ui/qemu_vm_configuration_page_ui.py
+++ b/gns3/modules/qemu/ui/qemu_vm_configuration_page_ui.py
@@ -63,6 +63,12 @@
self.uiCPULabel = QtWidgets.QLabel(self.uiGeneralSettingsTab)
self.uiCPULabel.setObjectName("uiCPULabel")
self.gridLayout_4.addWidget(self.uiCPULabel, 5, 0, 1, 1)
+ self.uiEnvvarLabel = QtWidgets.QLabel(self.uiGeneralSettingsTab)
+ self.uiEnvvarLabel.setObjectName("uiEnvvarLabel")
+ self.gridLayout_4.addWidget(self.uiEnvvarLabel, 9, 0, 1, 1)
+ self.uiEnvvarLineEdit = QtWidgets.QLineEdit(self.uiGeneralSettingsTab)
+ self.uiEnvvarLineEdit.setObjectName("uiEnvvarLineEdit")
+ self.gridLayout_4.addWidget(self.uiEnvvarLineEdit, 9, 1, 1, 1)
self.uiCPUSpinBox = QtWidgets.QSpinBox(self.uiGeneralSettingsTab)
self.uiCPUSpinBox.setMinimum(1)
self.uiCPUSpinBox.setMaximum(255)
@@ -93,7 +99,7 @@
self.gridLayout_4.addWidget(self.uiOnCloseComboBox, 8, 1, 1, 1)
self.uiConsoleTypeLabel = QtWidgets.QLabel(self.uiGeneralSettingsTab)
self.uiConsoleTypeLabel.setObjectName("uiConsoleTypeLabel")
- self.gridLayout_4.addWidget(self.uiConsoleTypeLabel, 9, 0, 1, 1)
+ self.gridLayout_4.addWidget(self.uiConsoleTypeLabel, 10, 0, 1, 1)
self.horizontalLayout_2 = QtWidgets.QHBoxLayout()
self.horizontalLayout_2.setObjectName("horizontalLayout_2")
self.uiConsoleTypeComboBox = QtWidgets.QComboBox(self.uiGeneralSettingsTab)
@@ -107,9 +113,9 @@
self.uiConsoleAutoStartCheckBox = QtWidgets.QCheckBox(self.uiGeneralSettingsTab)
self.uiConsoleAutoStartCheckBox.setObjectName("uiConsoleAutoStartCheckBox")
self.horizontalLayout_2.addWidget(self.uiConsoleAutoStartCheckBox)
- self.gridLayout_4.addLayout(self.horizontalLayout_2, 9, 1, 1, 1)
+ self.gridLayout_4.addLayout(self.horizontalLayout_2, 10, 1, 1, 1)
spacerItem = QtWidgets.QSpacerItem(263, 94, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
- self.gridLayout_4.addItem(spacerItem, 10, 1, 1, 1)
+ self.gridLayout_4.addItem(spacerItem, 11, 1, 1, 1)
self.uiQemutabWidget.addTab(self.uiGeneralSettingsTab, "")
self.uiHddTab = QtWidgets.QWidget()
self.uiHddTab.setObjectName("uiHddTab")
@@ -462,6 +468,7 @@
self.uiRamLabel.setText(_translate("QemuVMConfigPageWidget", "RAM:"))
self.uiRamSpinBox.setSuffix(_translate("QemuVMConfigPageWidget", " MB"))
self.uiCPULabel.setText(_translate("QemuVMConfigPageWidget", "vCPUs:"))
+ self.uiEnvvarLabel.setText(_translate("QemuVMConfigPageWidget", "Environment variables:"))
self.uiQemuListLabel.setText(_translate("QemuVMConfigPageWidget", "Qemu binary:"))
self.uiBootPriorityLabel.setText(_translate("QemuVMConfigPageWidget", "Boot priority:"))
self.uiOnCloseLabel.setText(_translate("QemuVMConfigPageWidget", "On close:"))
--- a/gns3/modules/qemu/ui/qemu_vm_configuration_page.ui
+++ b/gns3/modules/qemu/ui/qemu_vm_configuration_page.ui
@@ -24,26 +24,23 @@
<string>General settings</string>
</attribute>
<layout class="QGridLayout" name="gridLayout_4">
- <item row="0" column="0">
- <widget class="QLabel" name="uiNameLabel">
+ <item row="1" column="0">
+ <widget class="QLabel" name="uiDefaultNameFormatLabel">
<property name="text">
- <string>Name:</string>
+ <string>Default name format:</string>
</property>
</widget>
</item>
- <item row="0" column="1">
- <widget class="QLineEdit" name="uiNameLineEdit"/>
+ <item row="8" column="2">
+ <widget class="QComboBox" name="uiOnCloseComboBox"/>
</item>
- <item row="1" column="0">
- <widget class="QLabel" name="uiDefaultNameFormatLabel">
+ <item row="0" column="0">
+ <widget class="QLabel" name="uiNameLabel">
<property name="text">
- <string>Default name format:</string>
+ <string>Name:</string>
</property>
</widget>
</item>
- <item row="1" column="1">
- <widget class="QLineEdit" name="uiDefaultNameFormatLineEdit"/>
- </item>
<item row="2" column="0">
<widget class="QLabel" name="uiSymbolLabel">
<property name="text">
@@ -51,64 +48,23 @@
</property>
</widget>
</item>
- <item row="2" column="1">
- <layout class="QHBoxLayout" name="horizontalLayout_7">
- <item>
- <widget class="QLineEdit" name="uiSymbolLineEdit"/>
- </item>
- <item>
- <widget class="QToolButton" name="uiSymbolToolButton">
- <property name="text">
- <string>&amp;Browse...</string>
- </property>
- <property name="toolButtonStyle">
- <enum>Qt::ToolButtonTextOnly</enum>
- </property>
- </widget>
- </item>
- </layout>
+ <item row="7" column="2">
+ <widget class="QComboBox" name="uiBootPriorityComboBox"/>
</item>
- <item row="3" column="0">
- <widget class="QLabel" name="uiCategoryLabel">
- <property name="text">
- <string>Category:</string>
+ <item row="6" column="2">
+ <widget class="QComboBox" name="uiQemuListComboBox">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
</property>
</widget>
</item>
- <item row="3" column="1">
+ <item row="3" column="2">
<widget class="QComboBox" name="uiCategoryComboBox"/>
</item>
- <item row="4" column="0">
- <widget class="QLabel" name="uiRamLabel">
- <property name="text">
- <string>RAM:</string>
- </property>
- </widget>
- </item>
- <item row="4" column="1">
- <widget class="QSpinBox" name="uiRamSpinBox">
- <property name="suffix">
- <string> MB</string>
- </property>
- <property name="minimum">
- <number>32</number>
- </property>
- <property name="maximum">
- <number>65535</number>
- </property>
- <property name="value">
- <number>256</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="5" column="1">
+ <item row="5" column="2">
<widget class="QSpinBox" name="uiCPUSpinBox">
<property name="minimum">
<number>1</number>
@@ -125,16 +81,33 @@
</property>
</widget>
</item>
- <item row="6" column="1">
- <widget class="QComboBox" name="uiQemuListComboBox">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
+ <item row="8" column="0">
+ <widget class="QLabel" name="uiOnCloseLabel">
+ <property name="text">
+ <string>On close:</string>
</property>
</widget>
</item>
+ <item row="9" column="0">
+ <widget class="QLabel" name="uiConsoleTypeLabel">
+ <property name="text">
+ <string>Console type:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="11" column="2">
+ <spacer name="spacer">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>263</width>
+ <height>94</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
<item row="7" column="0">
<widget class="QLabel" name="uiBootPriorityLabel">
<property name="text">
@@ -142,27 +115,67 @@
</property>
</widget>
</item>
- <item row="7" column="1">
- <widget class="QComboBox" name="uiBootPriorityComboBox"/>
+ <item row="4" column="2">
+ <widget class="QSpinBox" name="uiRamSpinBox">
+ <property name="suffix">
+ <string> MB</string>
+ </property>
+ <property name="minimum">
+ <number>32</number>
+ </property>
+ <property name="maximum">
+ <number>65535</number>
+ </property>
+ <property name="value">
+ <number>256</number>
+ </property>
+ </widget>
</item>
- <item row="8" column="0">
- <widget class="QLabel" name="uiOnCloseLabel">
+ <item row="0" column="2">
+ <widget class="QLineEdit" name="uiNameLineEdit"/>
+ </item>
+ <item row="3" column="0">
+ <widget class="QLabel" name="uiCategoryLabel">
<property name="text">
- <string>On close:</string>
+ <string>Category:</string>
</property>
</widget>
</item>
- <item row="8" column="1">
- <widget class="QComboBox" name="uiOnCloseComboBox"/>
+ <item row="1" column="2">
+ <widget class="QLineEdit" name="uiDefaultNameFormatLineEdit"/>
</item>
- <item row="9" column="0">
- <widget class="QLabel" name="uiConsoleTypeLabel">
+ <item row="4" column="0">
+ <widget class="QLabel" name="uiRamLabel">
<property name="text">
- <string>Console type:</string>
+ <string>RAM:</string>
</property>
</widget>
</item>
- <item row="9" column="1">
+ <item row="2" column="2">
+ <layout class="QHBoxLayout" name="horizontalLayout_7">
+ <item>
+ <widget class="QLineEdit" name="uiSymbolLineEdit"/>
+ </item>
+ <item>
+ <widget class="QToolButton" name="uiSymbolToolButton">
+ <property name="text">
+ <string>&amp;Browse...</string>
+ </property>
+ <property name="toolButtonStyle">
+ <enum>Qt::ToolButtonTextOnly</enum>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item row="5" column="0">
+ <widget class="QLabel" name="uiCPULabel">
+ <property name="text">
+ <string>vCPUs:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="9" column="2">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QComboBox" name="uiConsoleTypeComboBox">
@@ -202,18 +215,15 @@
</item>
</layout>
</item>
- <item row="10" column="1">
- <spacer name="spacer">
- <property name="orientation">
- <enum>Qt::Vertical</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>263</width>
- <height>94</height>
- </size>
+ <item row="10" column="2">
+ <widget class="QLineEdit" name="uiEnvvarLineEdit"/>
+ </item>
+ <item row="10" column="0">
+ <widget class="QLabel" name="uiEnvvarLabel">
+ <property name="text">
+ <string>Environment variables:</string>
</property>
- </spacer>
+ </widget>
</item>
</layout>
</widget>
@@ -470,7 +480,16 @@
<string>CD/DVD</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_4">
- <property name="margin">
+ <property name="leftMargin">
+ <number>10</number>
+ </property>
+ <property name="topMargin">
+ <number>10</number>
+ </property>
+ <property name="rightMargin">
+ <number>10</number>
+ </property>
+ <property name="bottomMargin">
<number>10</number>
</property>
<item>
--- a/gns3/modules/qemu/pages/qemu_vm_configuration_page.py
+++ b/gns3/modules/qemu/pages/qemu_vm_configuration_page.py
@@ -444,6 +444,8 @@
self.uiInitrdLineEdit.setText(settings["initrd"])
self.uiKernelImageLineEdit.setText(settings["kernel_image"])
else:
+ self.uiEnvvarLabel.hide()
+ self.uiEnvvarLineEdit.hide()
self.uiNameLabel.hide()
self.uiNameLineEdit.hide()
self.uiHddTab.hide()
@@ -542,6 +544,7 @@
self.uiProcessPriorityComboBox.setCurrentIndex(index)
self.uiQemuOptionsLineEdit.setText(settings["options"])
self.uiUsageTextEdit.setPlainText(settings["usage"])
+ self.uiEnvvarLineEdit.setText(settings["env_vars"])
def saveSettings(self, settings, node=None, group=False):
"""
@@ -653,4 +656,5 @@
settings["process_priority"] = self.uiProcessPriorityComboBox.currentText().lower()
settings["options"] = self.uiQemuOptionsLineEdit.text()
settings["usage"] = self.uiUsageTextEdit.toPlainText()
+ settings["env_vars"] = self.uiEnvvarLineEdit.text()
return settings
--- a/gns3/modules/qemu/pages/qemu_vm_preferences_page.py
+++ b/gns3/modules/qemu/pages/qemu_vm_preferences_page.py
@@ -117,7 +117,7 @@
QtWidgets.QTreeWidgetItem(section_item, ["Base MAC address:", qemu_vm["mac_address"]])
# fill out the Linux boot section
- if qemu_vm["initrd"] or qemu_vm["kernel_image"] or qemu_vm["kernel_command_line"]:
+ if qemu_vm["initrd"] or qemu_vm["kernel_image"] or qemu_vm["kernel_command_line"] or qemu_vm["env_vars"]:
section_item = self._createSectionItem("Linux boot")
if qemu_vm["initrd"]:
QtWidgets.QTreeWidgetItem(section_item, ["Initial RAM disk:", qemu_vm["initrd"]])
@@ -125,6 +125,8 @@
QtWidgets.QTreeWidgetItem(section_item, ["Kernel image:", qemu_vm["kernel_image"]])
if qemu_vm["kernel_command_line"]:
QtWidgets.QTreeWidgetItem(section_item, ["Kernel command line:", qemu_vm["kernel_command_line"]])
+ if qemu_vm["env_vars"]:
+ QtWidgets.QTreeWidgetItem(section_item, ["Environment variables:", qemu_vm["env_vars"]])
# performance section
section_item = self._createSectionItem("Optimizations")
--- a/gns3/schemas/appliance.json
+++ b/gns3/schemas/appliance.json
@@ -329,6 +329,10 @@
"title": "KVM requirements",
"enum": ["require", "allow", "disable"]
},
+ "env_vars": {
+ "type": "string",
+ "title": "Environment variables"
+ },
"options": {
"type": "string",
"title": "Optional additional qemu command line options"

+ 107
- 0
patches/gns3-server/patch_gns3server_linkcolors.patch View File

@ -0,0 +1,107 @@
Author: Pekka Helenius <pekka.helenius@fjordtek.com>
Date: Sun, 6 Jun 2021 15:16:28 +0200
Subject: [PATCH] GNS3 Server: Link colors.
Add link color support for GNS3 Server.
--- a/gns3server/schemas/link.py
+++ b/gns3server/schemas/link.py
@@ -68,6 +68,27 @@
"type": "boolean",
"description": "Suspend the link"
},
+ "link_style": {
+ "type": "object",
+ "description": "Link line style",
+ "items": {
+ "type": "object",
+ "properties": {
+ "color": {
+ "description": "Link line color",
+ "type": "string"
+ },
+ "width": {
+ "description": "Link line width",
+ "type": "integer"
+ },
+ "type": {
+ "description": "Link line type",
+ "type": "integer"
+ }
+ }
+ }
+ },
"filters": FILTER_OBJECT_SCHEMA,
"capturing": {
"description": "Read only property. True if a capture running on the link",
--- a/gns3server/handlers/api/controller/link_handler.py
+++ b/gns3server/handlers/api/controller/link_handler.py
@@ -64,6 +64,8 @@
link = await project.add_link()
if "filters" in request.json:
await link.update_filters(request.json["filters"])
+ if "link_style" in request.json:
+ await link.update_link_style(request.json["link_style"])
if "suspend" in request.json:
await link.update_suspend(request.json["suspend"])
try:
@@ -135,6 +137,8 @@
link = project.get_link(request.match_info["link_id"])
if "filters" in request.json:
await link.update_filters(request.json["filters"])
+ if "link_style" in request.json:
+ await link.update_link_style(request.json["link_style"])
if "suspend" in request.json:
await link.update_suspend(request.json["suspend"])
if "nodes" in request.json:
--- a/gns3server/controller/project.py
+++ b/gns3server/controller/project.py
@@ -905,6 +905,8 @@
link = await self.add_link(link_id=link_data["link_id"])
if "filters" in link_data:
await link.update_filters(link_data["filters"])
+ if "link_style" in link_data:
+ await link.update_link_style(link_data["link_style"])
for node_link in link_data.get("nodes", []):
node = self.get_node(node_link["node_id"])
port = node.get_port(node_link["adapter_number"], node_link["port_number"])
--- a/gns3server/controller/link.py
+++ b/gns3server/controller/link.py
@@ -125,6 +125,8 @@
self._suspended = False
self._filters = {}
+ self._link_style = {}
+
@property
def filters(self):
"""
@@ -209,6 +211,13 @@
self._project.emit_notification("link.updated", self.__json__())
self._project.dump()
+ async def update_link_style(self, link_style):
+ if link_style != self._link_style:
+ self._link_style = link_style
+ await self.update()
+ self._project.emit_notification("link.updated", self.__json__())
+ self._project.dump()
+
@property
def created(self):
"""
@@ -446,6 +455,7 @@
"nodes": res,
"link_id": self._id,
"filters": self._filters,
+ "link_style": self._link_style,
"suspend": self._suspended
}
return {
@@ -457,5 +467,6 @@
"capture_file_path": self.capture_file_path,
"link_type": self._link_type,
"filters": self._filters,
+ "link_style": self._link_style,
"suspend": self._suspended
}

+ 130
- 0
patches/gns3-server/patch_gns3server_qemu-envvars.patch View File

@ -0,0 +1,130 @@
Author: Pekka Helenius <pekka.helenius@fjordtek.com>
Date: Sun, 6 Jun 2021 15:09:21 +0200
Subject: [PATCH] GNS3 Server: QEMU environment variables.
Add support for QEMU environment variables for GNS3 Server.
--- a/gns3server/schemas/qemu.py
+++ b/gns3server/schemas/qemu.py
@@ -65,6 +65,10 @@
"description": "Console type",
"enum": ["telnet", "vnc", "spice"]
},
+ "env_vars": {
+ "description": "Environment variables",
+ "type": "string",
+ },
"hda_disk_image": {
"description": "QEMU hda disk image path",
"type": "string",
@@ -250,6 +254,10 @@
"description": "Whether the VM is a linked clone or not",
"type": "boolean"
},
+ "env_vars": {
+ "description": "Environment variables",
+ "type": "string",
+ },
"hda_disk_image": {
"description": "QEMU hda disk image path",
"type": "string",
@@ -434,6 +442,10 @@
"description": "Platform to emulate",
"enum": QEMU_PLATFORMS
},
+ "env_vars": {
+ "description": "Environment variables",
+ "type": "string",
+ },
"hda_disk_image": {
"description": "QEMU hda disk image path",
"type": "string",
@@ -603,6 +615,7 @@
"qemu_path",
"platform",
"console_type",
+ "env_vars",
"hda_disk_image",
"hdb_disk_image",
"hdc_disk_image",
--- a/gns3server/schemas/qemu_template.py
+++ b/gns3server/schemas/qemu_template.py
@@ -22,6 +22,11 @@
QEMU_TEMPLATE_PROPERTIES = {
+ "env_vars": {
+ "description": "Environment variables",
+ "type": "string",
+ "default": ""
+ },
"qemu_path": {
"description": "Path to QEMU",
"type": "string",
--- a/gns3server/compute/qemu/qemu_vm.py
+++ b/gns3server/compute/qemu/qemu_vm.py
@@ -93,6 +93,7 @@
else:
self.platform = platform
+ self._env_vars = ""
self._hda_disk_image = ""
self._hdb_disk_image = ""
self._hdc_disk_image = ""
@@ -219,6 +220,32 @@
disk_image=value))
@property
+ def env_vars(self):
+ """
+ Returns the environment variables for this QEMU VM.
+
+ :returns: QEMU env vars
+ """
+
+ return self._env_vars
+
+ @env_vars.setter
+ def env_vars(self, env_vars):
+ """
+ Sets the environment variables for this QEMU VM.
+
+ :param env vars: QEMU env vars
+ """
+
+ log.info('QEMU VM "{name}" [{id}] has set the QEMU environment variables to {env_vars}'.format(name=self._name,
+ id=self._id,
+ env_vars=env_vars))
+ if sys.platform.startswith("linux"):
+ self._env_vars = env_vars.strip()
+ else:
+ self._env_vars = ""
+
+ @property
def hda_disk_image(self):
"""
Returns the hda disk image path for this QEMU VM.
@@ -912,7 +939,7 @@
with open(self._stdout_file, "w", encoding="utf-8") as fd:
fd.write("Start QEMU with {}\n\nExecution log:\n".format(command_string))
self.command_line = ' '.join(command)
- self._process = await asyncio.create_subprocess_exec(*command,
+ self._process = await asyncio.create_subprocess_shell(command_string,
stdout=fd,
stderr=subprocess.STDOUT,
cwd=self.working_dir)
@@ -1651,7 +1678,10 @@
additional_options = additional_options.replace("%vm-id%", self._id)
additional_options = additional_options.replace("%project-id%", self.project.id)
additional_options = additional_options.replace("%project-path%", '"' + self.project.path.replace('"', '\\"') + '"')
- command = [self.qemu_path]
+ command = []
+ if self._env_vars:
+ command.extend([self._env_vars])
+ command.extend([self.qemu_path])
command.extend(["-name", self._name])
command.extend(["-m", "{}M".format(self._ram)])
command.extend(["-smp", "cpus={}".format(self._cpus)])

Loading…
Cancel
Save