diff --git a/.github/workflows/add-new-issues-to-project.yml b/.github/workflows/add-new-issues-to-project.yml index 63932bb4..aa825255 100644 --- a/.github/workflows/add-new-issues-to-project.yml +++ b/.github/workflows/add-new-issues-to-project.yml @@ -10,7 +10,7 @@ jobs: name: Add issue to project runs-on: ubuntu-latest steps: - - uses: actions/add-to-project@v0.4.0 + - uses: actions/add-to-project@v1.0.1 with: project-url: https://github.com/orgs/GNS3/projects/3 github-token: ${{ secrets.ADD_NEW_ISSUES_TO_PROJECT }} diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 01de419f..242000a4 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -15,62 +15,79 @@ on: push: branches: [ "master" ] pull_request: - # The branches below must be a subset of the branches above branches: [ "master" ] schedule: - - cron: '27 6 * * 2' + - cron: '17 22 * * 6' jobs: analyze: - name: Analyze - runs-on: ubuntu-latest + name: Analyze (${{ matrix.language }}) + # Runner size impacts CodeQL analysis time. To learn more, please see: + # - https://gh.io/recommended-hardware-resources-for-running-codeql + # - https://gh.io/supported-runners-and-hardware-resources + # - https://gh.io/using-larger-runners (GitHub.com only) + # Consider using larger runners or machines with greater resources for possible analysis time improvements. + runs-on: ${{ (matrix.language == 'swift' && 'macos-latest') || 'ubuntu-latest' }} + timeout-minutes: ${{ (matrix.language == 'swift' && 120) || 360 }} permissions: + # required for all workflows + security-events: write + + # required to fetch internal or private CodeQL packs + packages: read + + # only required for workflows in private repositories 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 - + include: + - language: python + build-mode: none + # CodeQL supports the following values keywords for 'language': 'c-cpp', 'csharp', 'go', 'java-kotlin', 'javascript-typescript', 'python', 'ruby', 'swift' + # Use `c-cpp` to analyze code written in C, C++ or both + # Use 'java-kotlin' to analyze code written in Java, Kotlin or both + # Use 'javascript-typescript' to analyze code written in JavaScript, TypeScript or both + # To learn more about changing the languages that are analyzed or customizing the build mode for your analysis, + # see https://docs.github.com/en/code-security/code-scanning/creating-an-advanced-setup-for-code-scanning/customizing-your-advanced-setup-for-code-scanning. + # If you are analyzing a compiled language, you can modify the 'build-mode' for that language to customize how + # your codebase is analyzed, see https://docs.github.com/en/code-security/code-scanning/creating-an-advanced-setup-for-code-scanning/codeql-code-scanning-for-compiled-languages steps: - name: Checkout repository - uses: actions/checkout@v3 + uses: actions/checkout@v4 # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@v2 + uses: github/codeql-action/init@v3 with: languages: ${{ matrix.language }} + build-mode: ${{ matrix.build-mode }} # 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 + # For more 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 - + # If the analyze step fails for one of the languages you are analyzing with + # "We were unable to automatically build your code", modify the matrix above + # to set the build mode to "manual" for that language. Then modify this step + # to build your code. # â„šī¸ 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 + - if: matrix.build-mode == 'manual' + shell: bash + run: | + echo 'If you are using a "manual" build mode for one or more of the' \ + 'languages you are analyzing, replace this with the commands to build' \ + 'your code, for example:' + echo ' make bootstrap' + echo ' make release' + exit 1 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v2 + uses: github/codeql-action/analyze@v3 with: category: "/language:${{matrix.language}}" diff --git a/.github/workflows/testing.yml b/.github/workflows/testing.yml index 27850fe2..218e526a 100644 --- a/.github/workflows/testing.yml +++ b/.github/workflows/testing.yml @@ -12,7 +12,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Build and run Docker image run: | docker build -t gns3-gui-test . diff --git a/Dockerfile b/Dockerfile index 1cf810aa..c9c4154d 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,16 +1,16 @@ # Run tests inside a container -FROM ubuntu:18.04 +FROM ubuntu:latest MAINTAINER GNS3 Team 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 install -y --force-yes python3 python3-pyqt5 python3-pip python3-pyqt5.qtsvg python3-pyqt5.qtwebsockets python3-dev xvfb RUN apt-get clean ADD dev-requirements.txt /dev-requirements.txt ADD requirements.txt /requirements.txt -RUN pip3 install --no-cache-dir -r /dev-requirements.txt +RUN python3 -m pip install --break-system-packages --no-cache-dir -r /dev-requirements.txt ADD . /src WORKDIR /src -CMD xvfb-run python3.6 -m pytest -vv +CMD xvfb-run python3 -m pytest -vv diff --git a/dev-requirements.txt b/dev-requirements.txt index 0b513056..19ce479b 100644 --- a/dev-requirements.txt +++ b/dev-requirements.txt @@ -1,3 +1,2 @@ -pytest==8.1.1 -flake8==5.0.4 # v5.0.4 is the last to support Python 3.7 +pytest==8.3.2 pytest-timeout==2.3.1 diff --git a/gns3/main_window.py b/gns3/main_window.py index db630383..6dfaf20c 100644 --- a/gns3/main_window.py +++ b/gns3/main_window.py @@ -287,6 +287,7 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow): self.uiExportDebugInformationAction.triggered.connect(self._exportDebugInformationSlot) self.uiDoctorAction.triggered.connect(self._doctorSlot) self.uiAcademyAction.triggered.connect(self._academyActionSlot) + self.uiShortcutsAction.triggered.connect(self._shortcutsActionSlot) # browsers tool bar connections self.uiBrowseRoutersAction.triggered.connect(self._browseRoutersActionSlot) @@ -1007,6 +1008,15 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow): setup_wizard.show() setup_wizard.exec_() + def _shortcutsActionSlot(self): + + shortcuts_text = "" + for action in self.findChildren(QtWidgets.QAction): + shortcut = action.shortcut().toString() + if shortcut: + shortcuts_text += f"{action.toolTip()}: {shortcut}\n" + QtWidgets.QMessageBox.information(self, "Shortcuts", shortcuts_text) + def _aboutQtActionSlot(self): """ Slot to display the Qt About dialog. diff --git a/gns3/schemas/appliance_v8.json b/gns3/schemas/appliance_v8.json index 4b0e23ed..214e7083 100644 --- a/gns3/schemas/appliance_v8.json +++ b/gns3/schemas/appliance_v8.json @@ -7,6 +7,7 @@ "enum": [ "router", "multilayer_switch", + "switch", "firewall", "guest" ] diff --git a/gns3/ui/main_window.ui b/gns3/ui/main_window.ui index d24e40e0..fcafdf53 100644 --- a/gns3/ui/main_window.ui +++ b/gns3/ui/main_window.ui @@ -113,6 +113,7 @@ background-none; + @@ -646,6 +647,9 @@ background-none; Start/Resume all devices + + Ctrl+B + @@ -665,6 +669,9 @@ background-none; Stop all devices + + Ctrl+E + @@ -799,6 +806,9 @@ background-none; Suspend all devices + + Ctrl+J + @@ -1149,6 +1159,9 @@ background-none; Fit in view + + Ctrl+1 + @@ -1334,6 +1347,11 @@ background-none; Reset GUI state + + + &Shortcuts + + diff --git a/gns3/ui/main_window_ui.py b/gns3/ui/main_window_ui.py index b68809d3..dee22ef7 100644 --- a/gns3/ui/main_window_ui.py +++ b/gns3/ui/main_window_ui.py @@ -2,7 +2,7 @@ # Form implementation generated from reading ui file '/home/grossmj/PycharmProjects/gns3-gui/gns3/ui/main_window.ui' # -# Created by: PyQt5 UI code generator 5.15.9 +# Created by: PyQt5 UI code generator 5.15.10 # # 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. @@ -463,6 +463,8 @@ class Ui_MainWindow(object): self.uiResetConsoleAllAction.setObjectName("uiResetConsoleAllAction") self.uiResetGUIStateAction = QtWidgets.QAction(MainWindow) self.uiResetGUIStateAction.setObjectName("uiResetGUIStateAction") + self.uiShortcutsAction = QtWidgets.QAction(MainWindow) + self.uiShortcutsAction.setObjectName("uiShortcutsAction") self.uiEditMenu.addAction(self.uiSelectAllAction) self.uiEditMenu.addAction(self.uiSelectNoneAction) self.uiEditMenu.addSeparator() @@ -488,6 +490,7 @@ class Ui_MainWindow(object): self.uiHelpMenu.addAction(self.uiAcademyAction) self.uiHelpMenu.addAction(self.uiDoctorAction) self.uiHelpMenu.addAction(self.uiExportDebugInformationAction) + self.uiHelpMenu.addAction(self.uiShortcutsAction) self.uiHelpMenu.addAction(self.uiAboutQtAction) self.uiHelpMenu.addAction(self.uiAboutAction) self.uiViewMenu.addAction(self.uiActionFullscreen) @@ -614,9 +617,11 @@ class Ui_MainWindow(object): self.uiStartAllAction.setText(_translate("MainWindow", "Start/Resume all nodes")) self.uiStartAllAction.setToolTip(_translate("MainWindow", "Start/Resume all nodes")) self.uiStartAllAction.setStatusTip(_translate("MainWindow", "Start/Resume all devices")) + self.uiStartAllAction.setShortcut(_translate("MainWindow", "Ctrl+B")) self.uiStopAllAction.setText(_translate("MainWindow", "Stop all nodes")) self.uiStopAllAction.setToolTip(_translate("MainWindow", "Stop all nodes")) self.uiStopAllAction.setStatusTip(_translate("MainWindow", "Stop all devices")) + self.uiStopAllAction.setShortcut(_translate("MainWindow", "Ctrl+E")) self.uiConsoleAllAction.setText(_translate("MainWindow", "Console connect to all nodes")) self.uiConsoleAllAction.setToolTip(_translate("MainWindow", "Console connect to all nodes")) self.uiConsoleAllAction.setStatusTip(_translate("MainWindow", "Console to all devices")) @@ -645,6 +650,7 @@ class Ui_MainWindow(object): self.uiSuspendAllAction.setText(_translate("MainWindow", "Suspend all nodes")) self.uiSuspendAllAction.setToolTip(_translate("MainWindow", "Suspend all nodes")) self.uiSuspendAllAction.setStatusTip(_translate("MainWindow", "Suspend all devices")) + self.uiSuspendAllAction.setShortcut(_translate("MainWindow", "Ctrl+J")) self.uiAddNoteAction.setText(_translate("MainWindow", "Add note")) self.uiAddNoteAction.setToolTip(_translate("MainWindow", "Add a note")) self.uiAddNoteAction.setStatusTip(_translate("MainWindow", "Add a note")) @@ -712,6 +718,7 @@ class Ui_MainWindow(object): self.uiAddLinkAction.setToolTip(_translate("MainWindow", "Add a link")) self.uiAddLinkAction.setStatusTip(_translate("MainWindow", "Add a link")) self.uiFitInViewAction.setText(_translate("MainWindow", "Fit in view")) + self.uiFitInViewAction.setShortcut(_translate("MainWindow", "Ctrl+1")) self.uiActionFullscreen.setText(_translate("MainWindow", "Fullscreen")) self.uiActionFullscreen.setShortcut(_translate("MainWindow", "Ctrl+F")) self.uiSetupWizard.setText(_translate("MainWindow", "&Setup Wizard")) @@ -738,6 +745,7 @@ class Ui_MainWindow(object): self.uiResetDocksAction.setText(_translate("MainWindow", "Reset docks")) self.uiResetConsoleAllAction.setText(_translate("MainWindow", "Reset all console connections")) self.uiResetGUIStateAction.setText(_translate("MainWindow", "Reset GUI state")) + self.uiShortcutsAction.setText(_translate("MainWindow", "&Shortcuts")) from ..compute_summary_view import ComputeSummaryView from ..console_view import ConsoleView from ..graphics_view import GraphicsView diff --git a/mac-requirements.txt b/mac-requirements.txt index ddcdc7b9..7e5d533d 100644 --- a/mac-requirements.txt +++ b/mac-requirements.txt @@ -1,3 +1,3 @@ -r requirements.txt -PyQt5==5.15.10 +PyQt5==5.15.11 diff --git a/requirements.txt b/requirements.txt index e196de1a..7de79d92 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,5 @@ -jsonschema>=4.22.0,<4.23 -sentry-sdk==2.7.1,<2.8 +jsonschema>=4.23,<4.24 +sentry-sdk==2.12,<2.13 psutil==6.0.0 distro>=1.9.0 truststore>=0.9.1; python_version >= '3.10' diff --git a/tests/registry/appliances/empty-vm-v8.gns3a b/tests/registry/appliances/empty-vm-v8.gns3a index 8e1cc179..bc1541a2 100644 --- a/tests/registry/appliances/empty-vm-v8.gns3a +++ b/tests/registry/appliances/empty-vm-v8.gns3a @@ -65,8 +65,8 @@ { "filename": "empty100G.qcow2", "version": "100G", - "checksum": "d08fdec95fffbda3f04e9a00db49295df73ae4a507396e442ba9e4ad5c14ce5a", - "checksum_type": "sha256", + "checksum": "1e6409a4523ada212dea2ebc50e50a65", + "checksum_type": "md5", "filesize": 198656, "download_url": "https://sourceforge.net/projects/gns-3/files/Empty%20Qemu%20disk/", "direct_download_url": "https://sourceforge.net/projects/gns-3/files/Empty%20Qemu%20disk/empty100G.qcow2/download" diff --git a/win-requirements.txt b/win-requirements.txt index a3acbf6a..c2e1233d 100644 --- a/win-requirements.txt +++ b/win-requirements.txt @@ -1,4 +1,4 @@ -r requirements.txt -PyQt5==5.15.10 # pyup: ignore +PyQt5==5.15.11 # pyup: ignore pywin32==306 # pyup: ignore