mirror of
https://github.com/GNS3/gns3-server.git
synced 2026-08-29 13:30:12 +03:00
Compare commits
No commits in common. "master" and "v2.2.58" have entirely different histories.
@ -1,57 +0,0 @@
|
|||||||
# Version control
|
|
||||||
.git
|
|
||||||
.gitignore
|
|
||||||
.gitattributes
|
|
||||||
|
|
||||||
# CI / GitHub / Docker
|
|
||||||
.github
|
|
||||||
.whitesource
|
|
||||||
.dockerignore
|
|
||||||
|
|
||||||
# Editor / IDE
|
|
||||||
.idea
|
|
||||||
.vscode
|
|
||||||
.settings
|
|
||||||
.project
|
|
||||||
.pydevproject
|
|
||||||
.mr.developer.cfg
|
|
||||||
|
|
||||||
# Claude
|
|
||||||
.claude
|
|
||||||
|
|
||||||
# Python build artifacts
|
|
||||||
__pycache__
|
|
||||||
*.py[cod]
|
|
||||||
*.so
|
|
||||||
*.egg
|
|
||||||
*.egg-info
|
|
||||||
build/
|
|
||||||
dist/
|
|
||||||
eggs/
|
|
||||||
parts/
|
|
||||||
var/
|
|
||||||
sdist/
|
|
||||||
develop-eggs/
|
|
||||||
.installed.cfg
|
|
||||||
lib/
|
|
||||||
lib64/
|
|
||||||
.ropeproject
|
|
||||||
|
|
||||||
# Test & coverage
|
|
||||||
tests/
|
|
||||||
pytest.ini
|
|
||||||
.coveragerc
|
|
||||||
.coverage
|
|
||||||
.coverage*
|
|
||||||
.tox
|
|
||||||
.cache
|
|
||||||
.pytest_cache
|
|
||||||
nosetests.xml
|
|
||||||
|
|
||||||
# Virtualenv
|
|
||||||
env/
|
|
||||||
venv/
|
|
||||||
.venv/
|
|
||||||
|
|
||||||
# Editor backup files
|
|
||||||
*~
|
|
||||||
40
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
40
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
@ -1,40 +0,0 @@
|
|||||||
name: Bug report
|
|
||||||
description: Report a bug so we can fix it.
|
|
||||||
title: "[Bug]: "
|
|
||||||
labels: ["bug"]
|
|
||||||
body:
|
|
||||||
- type: textarea
|
|
||||||
id: what-happened
|
|
||||||
attributes:
|
|
||||||
label: What happened?
|
|
||||||
description: A clear description of the bug.
|
|
||||||
validations:
|
|
||||||
required: true
|
|
||||||
- type: textarea
|
|
||||||
id: reproduce
|
|
||||||
attributes:
|
|
||||||
label: Steps to reproduce
|
|
||||||
description: How can we reproduce this? Numbered steps if possible.
|
|
||||||
validations:
|
|
||||||
required: true
|
|
||||||
- type: textarea
|
|
||||||
id: expected
|
|
||||||
attributes:
|
|
||||||
label: Expected behavior
|
|
||||||
description: What did you expect to happen instead?
|
|
||||||
- type: input
|
|
||||||
id: version
|
|
||||||
attributes:
|
|
||||||
label: Version / commit
|
|
||||||
description: Which version or commit hash are you on?
|
|
||||||
- type: textarea
|
|
||||||
id: environment
|
|
||||||
attributes:
|
|
||||||
label: Environment
|
|
||||||
description: OS, runtime version, anything else that might be relevant.
|
|
||||||
- type: textarea
|
|
||||||
id: logs
|
|
||||||
attributes:
|
|
||||||
label: Relevant logs
|
|
||||||
description: Paste any relevant log output. This is automatically rendered as code.
|
|
||||||
render: shell
|
|
||||||
@ -10,7 +10,7 @@ jobs:
|
|||||||
name: Add issue to project
|
name: Add issue to project
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/add-to-project@v2
|
- uses: actions/add-to-project@v1.0.1
|
||||||
with:
|
with:
|
||||||
project-url: https://github.com/orgs/GNS3/projects/3
|
project-url: https://github.com/orgs/GNS3/projects/3
|
||||||
github-token: ${{ secrets.ADD_NEW_ISSUES_TO_PROJECT }}
|
github-token: ${{ secrets.ADD_NEW_ISSUES_TO_PROJECT }}
|
||||||
|
|||||||
6
.github/workflows/codeql-analysis.yml
vendored
6
.github/workflows/codeql-analysis.yml
vendored
@ -56,11 +56,11 @@ jobs:
|
|||||||
# 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
|
# 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:
|
steps:
|
||||||
- name: Checkout repository
|
- name: Checkout repository
|
||||||
uses: actions/checkout@v7
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
# Initializes the CodeQL tools for scanning.
|
# Initializes the CodeQL tools for scanning.
|
||||||
- name: Initialize CodeQL
|
- name: Initialize CodeQL
|
||||||
uses: github/codeql-action/init@v4
|
uses: github/codeql-action/init@v3
|
||||||
with:
|
with:
|
||||||
languages: ${{ matrix.language }}
|
languages: ${{ matrix.language }}
|
||||||
build-mode: ${{ matrix.build-mode }}
|
build-mode: ${{ matrix.build-mode }}
|
||||||
@ -88,6 +88,6 @@ jobs:
|
|||||||
exit 1
|
exit 1
|
||||||
|
|
||||||
- name: Perform CodeQL Analysis
|
- name: Perform CodeQL Analysis
|
||||||
uses: github/codeql-action/analyze@v4
|
uses: github/codeql-action/analyze@v3
|
||||||
with:
|
with:
|
||||||
category: "/language:${{matrix.language}}"
|
category: "/language:${{matrix.language}}"
|
||||||
|
|||||||
52
.github/workflows/docker-build.yml
vendored
52
.github/workflows/docker-build.yml
vendored
@ -10,59 +10,31 @@ on:
|
|||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
env:
|
|
||||||
DOCKERHUB_ORG: ${{ vars.DOCKERHUB_ORG || 'gns3' }}
|
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@v7
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Check for stable release
|
|
||||||
id: ver
|
|
||||||
run: |
|
|
||||||
TAG="${GITHUB_REF_NAME#v}"
|
|
||||||
echo "tag=$TAG" >> $GITHUB_OUTPUT
|
|
||||||
if echo "$TAG" | grep -qE '^[0-9]+\.[0-9]+\.[0-9]+$'; then
|
|
||||||
echo "stable=true" >> $GITHUB_OUTPUT
|
|
||||||
else
|
|
||||||
echo "stable=false" >> $GITHUB_OUTPUT
|
|
||||||
fi
|
|
||||||
|
|
||||||
- name: Set lowercase image name vars
|
|
||||||
if: steps.ver.outputs.stable == 'true'
|
|
||||||
id: names
|
|
||||||
run: |
|
|
||||||
echo "owner=$(echo '${{ github.repository_owner }}' | tr '[:upper:]' '[:lower:]')" >> "$GITHUB_OUTPUT"
|
|
||||||
echo "repo=$(echo '${{ github.event.repository.name }}' | tr '[:upper:]' '[:lower:]')" >> "$GITHUB_OUTPUT"
|
|
||||||
|
|
||||||
- name: Set up Docker Buildx
|
|
||||||
if: steps.ver.outputs.stable == 'true'
|
|
||||||
uses: docker/setup-buildx-action@v3
|
|
||||||
|
|
||||||
- name: Login to GitHub Container Registry
|
- name: Login to GitHub Container Registry
|
||||||
if: steps.ver.outputs.stable == 'true'
|
uses: docker/login-action@v3
|
||||||
uses: docker/login-action@v4
|
|
||||||
with:
|
with:
|
||||||
registry: ghcr.io
|
registry: ghcr.io
|
||||||
username: ${{ github.repository_owner }}
|
username: ${{ github.repository_owner }}
|
||||||
password: ${{ secrets.GITHUB_TOKEN }}
|
password: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
- name: Login to Docker Hub
|
- name: Login to Docker Hub
|
||||||
if: steps.ver.outputs.stable == 'true'
|
uses: docker/login-action@v3
|
||||||
uses: docker/login-action@v4
|
|
||||||
with:
|
with:
|
||||||
registry: docker.io
|
registry: docker.io
|
||||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||||
|
|
||||||
- name: Build and push
|
- name: Build and push to GitHub Container Registry
|
||||||
if: steps.ver.outputs.stable == 'true'
|
run: |
|
||||||
uses: docker/build-push-action@v6
|
docker build -t ghcr.io/$(echo "${{ github.repository }}" | tr '[:upper:]' '[:lower:]'):latest .
|
||||||
with:
|
docker push ghcr.io/$(echo "${{ github.repository }}" | tr '[:upper:]' '[:lower:]'):latest
|
||||||
context: .
|
|
||||||
push: true
|
- name: Build and push to Docker Hub
|
||||||
tags: |
|
run: |
|
||||||
${{ env.DOCKERHUB_ORG }}/${{ github.event.repository.name }}:${{ steps.ver.outputs.tag }}
|
docker build -t gns3/${{ github.event.repository.name }}:latest .
|
||||||
${{ env.DOCKERHUB_ORG }}/${{ github.event.repository.name }}:latest
|
docker push gns3/${{ github.event.repository.name }}:latest
|
||||||
ghcr.io/${{ steps.names.outputs.owner }}/${{ steps.names.outputs.repo }}:${{ steps.ver.outputs.tag }}
|
|
||||||
ghcr.io/${{ steps.names.outputs.owner }}/${{ steps.names.outputs.repo }}:latest
|
|
||||||
|
|||||||
@ -12,11 +12,11 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v7
|
- uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
ref: "gh-pages"
|
ref: "gh-pages"
|
||||||
- uses: actions/setup-python@v6
|
- uses: actions/setup-python@v5
|
||||||
with:
|
with:
|
||||||
python-version: 3.8
|
python-version: 3.8
|
||||||
- name: Merge changes from 3.0 branch
|
- name: Merge changes from 3.0 branch
|
||||||
|
|||||||
4
.github/workflows/testing.yml
vendored
4
.github/workflows/testing.yml
vendored
@ -21,9 +21,9 @@ jobs:
|
|||||||
python-version: ["3.9", "3.10", "3.11", "3.12", "3.13", "3.14"]
|
python-version: ["3.9", "3.10", "3.11", "3.12", "3.13", "3.14"]
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v7
|
- uses: actions/checkout@v4
|
||||||
- name: Set up Python ${{ matrix.python-version }}
|
- name: Set up Python ${{ matrix.python-version }}
|
||||||
uses: actions/setup-python@v6
|
uses: actions/setup-python@v5
|
||||||
with:
|
with:
|
||||||
python-version: ${{ matrix.python-version }}
|
python-version: ${{ matrix.python-version }}
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
|
|||||||
34
CHANGELOG
34
CHANGELOG
@ -1,39 +1,5 @@
|
|||||||
# Change Log
|
# Change Log
|
||||||
|
|
||||||
## 2.2.61 30/07/2026
|
|
||||||
|
|
||||||
* Sync appliances
|
|
||||||
* fix(import): unvalidated symlink creation in import_project
|
|
||||||
* fix(qemu): fix addition of QEMU RNG device causes interface names to change
|
|
||||||
* fix(qemu): remove trailing space from RNG object argument
|
|
||||||
* fix: do not start nodes when deleting a project
|
|
||||||
* fix: correct always-true state check in DockerVM.stop()
|
|
||||||
|
|
||||||
## 2.2.60 15/07/2026
|
|
||||||
|
|
||||||
* Sync appliances
|
|
||||||
* Only set IOU images to be executable when importing images
|
|
||||||
* fix(import): project import does not move images symlinks into place
|
|
||||||
* Search for system UEFI that is compatible with Python < 3.12
|
|
||||||
* Add OVMF firmware directory configuration
|
|
||||||
* Automatically add a Random Number Generator (RNG) device when using uefi option is enabled
|
|
||||||
* fix(docker): handle container name conflict automatically
|
|
||||||
* fix: gns3-server crashes on startup if "Open this project in the background" is active but there is a problem with that project
|
|
||||||
* Handle HTTPNotFound exception when retrieving compute status
|
|
||||||
* Fix: Check compute connectivity before open() during project deletion
|
|
||||||
* API endpoints to manage base configuration files for templates
|
|
||||||
|
|
||||||
## 2.2.59 08/05/2026
|
|
||||||
|
|
||||||
* Sync appliances
|
|
||||||
* Fix snapshot restore does not work after export/import of project
|
|
||||||
* Warn to use 64-bit IOU images. Fixes #2716 32-bit IOU image support has been removed from the GNS3 VM.
|
|
||||||
* Fix telnet console silent-proxy hang on non-ConnectionError exit (#2344)
|
|
||||||
|
|
||||||
## 2.2.58.1 12/04/2026
|
|
||||||
|
|
||||||
* Sync appliances
|
|
||||||
|
|
||||||
## 2.2.58 10/04/2026
|
## 2.2.58 10/04/2026
|
||||||
|
|
||||||
* Bundle web-ui v2.2.58
|
* Bundle web-ui v2.2.58
|
||||||
|
|||||||
@ -103,8 +103,6 @@ enable_hardware_acceleration = True
|
|||||||
require_hardware_acceleration = False
|
require_hardware_acceleration = False
|
||||||
; Allow unsafe additional command line options
|
; Allow unsafe additional command line options
|
||||||
allow_unsafe_options = False
|
allow_unsafe_options = False
|
||||||
; Path to the OVMF firmware directory
|
|
||||||
ovmf_firmware_dir = "/usr/share/OVMF"
|
|
||||||
|
|
||||||
[VMware]
|
[VMware]
|
||||||
; First vmnet interface of the range that can be managed by the GNS3 server
|
; First vmnet interface of the range that can be managed by the GNS3 server
|
||||||
|
|||||||
@ -1,17 +0,0 @@
|
|||||||
curl -i -X 'http://localhost:3080/v2/templates/19021f99-e36f-394d-b4a1-8aaa902ab9cc/base-config/vpcs_base_config.txt'
|
|
||||||
|
|
||||||
GET /v2/templates/19021f99-e36f-394d-b4a1-8aaa902ab9cc/base-config/vpcs_base_config.txt HTTP/1.1
|
|
||||||
|
|
||||||
HTTP/1.1 200 OK
|
|
||||||
Connection: close
|
|
||||||
X-Route: /v2/templates/{template_id}/base-config/{filename}
|
|
||||||
Server: Python/3.14 GNS3/2.2.60.dev1+713dbb7f
|
|
||||||
Content-Type: application/json
|
|
||||||
Content-Length: 144
|
|
||||||
Date: Mon, 18 May 2026 18:34:10 GMT
|
|
||||||
|
|
||||||
{
|
|
||||||
"content": "# test config\n\ndhcp\n",
|
|
||||||
"filename": "vpcs_base_config.txt",
|
|
||||||
"template_id": "19021f99-e36f-394d-b4a1-8aaa902ab9cc"
|
|
||||||
}
|
|
||||||
@ -1,44 +0,0 @@
|
|||||||
curl -i -X 'http://localhost:3080/v2/templates/base-configs'
|
|
||||||
|
|
||||||
GET /v2/templates/base-configs HTTP/1.1
|
|
||||||
|
|
||||||
HTTP/1.1 200 OK
|
|
||||||
Connection: close
|
|
||||||
X-Route: /v2/templates/base-configs
|
|
||||||
Server: Python/3.14 GNS3/2.2.60.dev1+713dbb7f
|
|
||||||
Content-Type: application/json
|
|
||||||
Content-Length: 576
|
|
||||||
Date: Mon, 18 May 2026 18:28:53 GMT
|
|
||||||
|
|
||||||
[
|
|
||||||
{
|
|
||||||
"filename": "config1.txt"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"filename": "config2.txt"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"filename": "ios_base_startup-config.txt"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"filename": "ios_etherswitch_startup-config.txt"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"filename": "iou_l2_base_startup-config.txt"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"filename": "iou_l3_base_startup-config.txt"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"filename": "test_config.txt"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"filename": "update_test.txt"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"filename": "vpcs_base_config.txt"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"filename": "vpcs_base_config2.txt"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
@ -1,17 +0,0 @@
|
|||||||
curl -i -X 'http://localhost:3080/v2/templates/19021f99-e36f-394d-b4a1-8aaa902ab9cc/base-config/vpcs_base_config.txt'
|
|
||||||
|
|
||||||
PUT /v2/templates/19021f99-e36f-394d-b4a1-8aaa902ab9cc/base-config/vpcs_base_config.txt HTTP/1.1
|
|
||||||
|
|
||||||
HTTP/1.1 200 OK
|
|
||||||
Connection: close
|
|
||||||
X-Route: /v2/templates/{template_id}/base-config/{filename}
|
|
||||||
Server: Python/3.14 GNS3/2.2.60.dev1+713dbb7f
|
|
||||||
Content-Type: application/json
|
|
||||||
Content-Length: 144
|
|
||||||
Date: Mon, 18 May 2026 18:37:57 GMT
|
|
||||||
|
|
||||||
{
|
|
||||||
"content": "# test config\n\ndhcp\n",
|
|
||||||
"filename": "vpcs_base_config.txt",
|
|
||||||
"template_id": "19021f99-e36f-394d-b4a1-8aaa902ab9cc"
|
|
||||||
}
|
|
||||||
@ -1,38 +0,0 @@
|
|||||||
GET /v2/templates/base-configs
|
|
||||||
------------------------------------------------------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
.. contents::
|
|
||||||
|
|
||||||
GET /v2/templates/base-configs
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
List all available base configuration files
|
|
||||||
|
|
||||||
Response status codes
|
|
||||||
**********************
|
|
||||||
- **200**: List of base configuration files returned
|
|
||||||
|
|
||||||
Output
|
|
||||||
*******
|
|
||||||
|
|
||||||
.. raw:: html
|
|
||||||
|
|
||||||
<table>
|
|
||||||
<tr>
|
|
||||||
<th>Name</th>
|
|
||||||
<th>Type</th>
|
|
||||||
<th>Description</th>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<tr>
|
|
||||||
<td>filename</td>
|
|
||||||
<td>string</td>
|
|
||||||
<td>Name of the base configuration file</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
</table>
|
|
||||||
|
|
||||||
Sample session
|
|
||||||
***************
|
|
||||||
|
|
||||||
.. literalinclude:: ../../../examples/controller_get_templatesbaseconfigs.txt
|
|
||||||
@ -1,90 +0,0 @@
|
|||||||
/v2/templates/{template_id}/base-config/{filename}
|
|
||||||
------------------------------------------------------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
.. contents::
|
|
||||||
|
|
||||||
GET /v2/templates/**{template_id}**/base-configs/**{filename}**
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
List all available base configuration files
|
|
||||||
|
|
||||||
Response status codes
|
|
||||||
**********************
|
|
||||||
- **200**: List of base configuration files returned
|
|
||||||
|
|
||||||
Output
|
|
||||||
*******
|
|
||||||
|
|
||||||
.. raw:: html
|
|
||||||
|
|
||||||
<table>
|
|
||||||
<tr>
|
|
||||||
<th>Name</th>
|
|
||||||
<th>Type</th>
|
|
||||||
<th>Description</th>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<tr>
|
|
||||||
<td>filename</td>
|
|
||||||
<td>string</td>
|
|
||||||
<td>Name of the base configuration file</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
</table>
|
|
||||||
|
|
||||||
Sample session
|
|
||||||
***************
|
|
||||||
|
|
||||||
.. literalinclude:: ../../../examples/controller_get_templateidbaseconfig.txt
|
|
||||||
|
|
||||||
|
|
||||||
PUT /v2/templates/**{template_id}**/base-config/**{filename}**
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
Update base configuration file content
|
|
||||||
|
|
||||||
Response status codes
|
|
||||||
**********************
|
|
||||||
- **200**: File updated
|
|
||||||
- **404**: File not found
|
|
||||||
|
|
||||||
Input
|
|
||||||
*******
|
|
||||||
|
|
||||||
.. raw:: html
|
|
||||||
|
|
||||||
<table>
|
|
||||||
<tr>
|
|
||||||
<th>Name</th>
|
|
||||||
<th>Mandatory</th>
|
|
||||||
<th>Type</th>
|
|
||||||
<th>Description</th>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<tr><td>content</td><td>✔</td><td>string</td><td>New file content</td></tr>
|
|
||||||
|
|
||||||
</table>
|
|
||||||
|
|
||||||
Output
|
|
||||||
*******
|
|
||||||
|
|
||||||
.. raw:: html
|
|
||||||
|
|
||||||
<table>
|
|
||||||
<tr>
|
|
||||||
<th>Name</th>
|
|
||||||
<th>Mandatory</th>
|
|
||||||
<th>Type</th>
|
|
||||||
<th>Description</th>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<tr><td>template_id</td><td>✔</td><td>string</td><td>Template UUID</td></tr>
|
|
||||||
<tr><td>filename</td><td>✔</td><td>string</td><td>Base configuration filename</td></tr>
|
|
||||||
<tr><td>content</td><td>✔</td><td>string</td><td>Updated file content</td></tr>
|
|
||||||
|
|
||||||
</table>
|
|
||||||
|
|
||||||
Sample session
|
|
||||||
***************
|
|
||||||
|
|
||||||
.. literalinclude:: ../../../examples/controller_put_templateidbaseconfig.txt
|
|
||||||
@ -25,30 +25,6 @@
|
|||||||
"options": "-cpu host -nographic"
|
"options": "-cpu host -nographic"
|
||||||
},
|
},
|
||||||
"images": [
|
"images": [
|
||||||
{
|
|
||||||
"filename": "AlmaLinux-10-GenericCloud-10.0-20250528.0.x86_64.qcow2",
|
|
||||||
"version": "10.0",
|
|
||||||
"md5sum": "e5099e33f16014b6cc851482d865720d",
|
|
||||||
"filesize": 460062720,
|
|
||||||
"download_url": "https://vault.almalinux.org/10.0/cloud/x86_64/images/",
|
|
||||||
"direct_download_url": "https://vault.almalinux.org/10.0/cloud/x86_64/images/AlmaLinux-10-GenericCloud-10.0-20250528.0.x86_64.qcow2"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"filename": "AlmaLinux-9-GenericCloud-9.6-20250522.x86_64.qcow2",
|
|
||||||
"version": "9.6",
|
|
||||||
"md5sum": "ae02074389961caf08bbe44439603061",
|
|
||||||
"filesize": 530776064,
|
|
||||||
"download_url": "https://vault.almalinux.org/9.6/cloud/x86_64/images/",
|
|
||||||
"direct_download_url": "https://vault.almalinux.org/9.6/cloud/x86_64/images/AlmaLinux-9-GenericCloud-9.6-20250522.x86_64.qcow2"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"filename": "AlmaLinux-9-GenericCloud-9.5-20241120.x86_64.qcow2",
|
|
||||||
"version": "9.5",
|
|
||||||
"md5sum": "cb48bc1c609a1d3d62f48397acdd038e",
|
|
||||||
"filesize": 490995712,
|
|
||||||
"download_url": "https://vault.almalinux.org/9.5/cloud/x86_64/images/",
|
|
||||||
"direct_download_url": "https://vault.almalinux.org/9.5/cloud/x86_64/images/AlmaLinux-9-GenericCloud-9.5-20241120.x86_64"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"filename": "AlmaLinux-9-GenericCloud-9.4-20240805.x86_64.qcow2",
|
"filename": "AlmaLinux-9-GenericCloud-9.4-20240805.x86_64.qcow2",
|
||||||
"version": "9.4",
|
"version": "9.4",
|
||||||
@ -99,27 +75,6 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"versions": [
|
"versions": [
|
||||||
{
|
|
||||||
"name": "10.0",
|
|
||||||
"images": {
|
|
||||||
"hda_disk_image": "AlmaLinux-10-GenericCloud-10.0-20250528.0.x86_64.qcow2",
|
|
||||||
"cdrom_image": "almalinux-cloud-init-data.iso"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "9.6",
|
|
||||||
"images": {
|
|
||||||
"hda_disk_image": "AlmaLinux-9-GenericCloud-9.6-20250522.x86_64.qcow2",
|
|
||||||
"cdrom_image": "almalinux-cloud-init-data.iso"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "9.5",
|
|
||||||
"images": {
|
|
||||||
"hda_disk_image": "AlmaLinux-9-GenericCloud-9.5-20241120.x86_64.qcow2",
|
|
||||||
"cdrom_image": "almalinux-cloud-init-data.iso"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"name": "9.4",
|
"name": "9.4",
|
||||||
"images": {
|
"images": {
|
||||||
|
|||||||
@ -1,59 +0,0 @@
|
|||||||
{
|
|
||||||
"appliance_id": "b3b90fde-143a-4129-8031-ccbba73c5e02",
|
|
||||||
"name": "armbian",
|
|
||||||
"category": "guest",
|
|
||||||
"description": "A highly optimized base operating system specialized for single board computers (SBCs) and its extensive build framework.",
|
|
||||||
"vendor_name": "The Armbian team",
|
|
||||||
"vendor_url": "https://armbian.com/",
|
|
||||||
"documentation_url": "https://docs.armbian.com/",
|
|
||||||
"product_name": "Armbian UEFI x86",
|
|
||||||
"product_url": "https://armbian.com/boards/uefi-x86",
|
|
||||||
"registry_version": 4,
|
|
||||||
"status": "stable",
|
|
||||||
"maintainer": "GNS3 Team",
|
|
||||||
"maintainer_email": "developers@gns3.net",
|
|
||||||
"usage": "By first login you create root password and new sudo user.\n\nBoot disk from UEFI shell, type: FS0:EFI\\BOOT\\BOOTX64 and press <Enter>",
|
|
||||||
"port_name_format": "Ethernet{0}",
|
|
||||||
"qemu": {
|
|
||||||
"adapter_type": "virtio-net-pci",
|
|
||||||
"adapters": 2,
|
|
||||||
"ram": 256,
|
|
||||||
"hda_disk_interface": "virtio",
|
|
||||||
"arch": "x86_64",
|
|
||||||
"console_type": "spice+agent",
|
|
||||||
"uefi": false,
|
|
||||||
"boot_priority": "c",
|
|
||||||
"kvm": "require",
|
|
||||||
"options": "-nographic"
|
|
||||||
},
|
|
||||||
"images": [
|
|
||||||
{
|
|
||||||
"filename": "OVMF-edk2-stable202305.fd",
|
|
||||||
"version": "stable202305",
|
|
||||||
"md5sum": "6c4cf1519fec4a4b95525d9ae562963a",
|
|
||||||
"filesize": 4194304,
|
|
||||||
"download_url": "https://sourceforge.net/projects/gns-3/files/Qemu%20Appliances/",
|
|
||||||
"direct_download_url": "https://sourceforge.net/projects/gns-3/files/Qemu%20Appliances/OVMF-edk2-stable202305.fd.zip/download",
|
|
||||||
"compression": "zip"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"filename": "Armbian_26.5.1_Uefi-x86_trixie_cloud_6.18.32_minimal.img.qcow2",
|
|
||||||
"version": "Armbian 26.5.1 Minimal (CLI)",
|
|
||||||
"md5sum": "7f4c915668718d6135406de5a6c4fc30",
|
|
||||||
"filesize": 877920512,
|
|
||||||
"download_url": "https://armbian.com/boards/uefi-x86",
|
|
||||||
"direct_download_url": "https://armbian.atomonetworks.com/dl/uefi-x86/archive/Armbian_26.5.1_Uefi-x86_trixie_cloud_6.18.32_minimal.img.qcow2.xz",
|
|
||||||
"compression": "xz"
|
|
||||||
}
|
|
||||||
|
|
||||||
],
|
|
||||||
"versions": [
|
|
||||||
{
|
|
||||||
"name": "Armbian 26.5.1 Minimal (CLI)",
|
|
||||||
"images": {
|
|
||||||
"bios_image": "OVMF-edk2-stable202305.fd",
|
|
||||||
"hda_disk_image": "Armbian_26.5.1_Uefi-x86_trixie_cloud_6.18.32_minimal.img.qcow2"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
@ -1,56 +1,41 @@
|
|||||||
{
|
{
|
||||||
"appliance_id": "8fecbf89-5cd1-4aea-b735-5f36cf0efbb7",
|
"appliance_id": "088df570-f637-46f5-8a68-85acde538e5e",
|
||||||
"name": "BIRD",
|
"name": "BIRD",
|
||||||
"category": "router",
|
"category": "router",
|
||||||
"description": "The BIRD project aims to develop a fully functional dynamic IP routing daemon primarily targeted on (but not limited to) Linux, FreeBSD and other UNIX-like systems and distributed under the GNU General Public License.",
|
"description": "The BIRD project aims to develop a fully functional dynamic IP routing daemon primarily targeted on (but not limited to) Linux, FreeBSD and other UNIX-like systems and distributed under the GNU General Public License.",
|
||||||
"vendor_name": "CZ.NIC Labs",
|
"vendor_name": "CZ.NIC Labs",
|
||||||
"vendor_url": "https://bird.network.cz",
|
"vendor_url": "http://bird.network.cz/",
|
||||||
"documentation_url": "https://bird.network.cz/?get_doc&f=bird.html&v=20",
|
"documentation_url": "http://bird.network.cz/?get_doc&f=bird.html",
|
||||||
"product_name": "BIRD internet routing daemon",
|
"product_name": "BIRD internet routing daemon",
|
||||||
"registry_version": 4,
|
"registry_version": 4,
|
||||||
"status": "stable",
|
"status": "stable",
|
||||||
"maintainer": "Bernhard Ehlers",
|
"maintainer": "GNS3 Team",
|
||||||
"maintainer_email": "dev-ehlers@mailbox.org",
|
"maintainer_email": "developers@gns3.net",
|
||||||
"usage": "Username:\tgns3\nPassword:\tgns3\nTo become root, use \"sudo -s\".\n\nNetwork configuration:\nsudo nano /etc/network/interfaces\nsudo systemctl restart networking\n\nBIRD:\nRestart: sudo systemctl restart bird\nReconfigure: birdc configure",
|
"usage": "\n*** BIRD v1 is end-of-life ***\nPlease use the BIRD2 appliance.\n\nConfigure interfaces in /opt/bootlocal.sh, BIRD configuration is done in /usr/local/etc/bird",
|
||||||
"port_name_format": "eth{0}",
|
|
||||||
"qemu": {
|
"qemu": {
|
||||||
"adapter_type": "virtio-net-pci",
|
"adapter_type": "e1000",
|
||||||
"adapters": 4,
|
"adapters": 4,
|
||||||
"ram": 512,
|
"ram": 128,
|
||||||
"hda_disk_interface": "scsi",
|
"hda_disk_interface": "ide",
|
||||||
"arch": "x86_64",
|
"arch": "x86_64",
|
||||||
"console_type": "telnet",
|
"console_type": "telnet",
|
||||||
"kvm": "allow"
|
"kvm": "allow"
|
||||||
},
|
},
|
||||||
"images": [
|
"images": [
|
||||||
{
|
{
|
||||||
"filename": "bird2-debian-2.14.qcow2",
|
"filename": "bird-tinycore64-1.5.0.img",
|
||||||
"version": "2.14",
|
"version": "1.5.0",
|
||||||
"md5sum": "029cf1756201ee79497c169502b08b88",
|
"md5sum": "08d50ba2b1b262e2e03e4babf90abf69",
|
||||||
"filesize": 303717376,
|
"filesize": 22413312,
|
||||||
"download_url": "https://sourceforge.net/projects/gns-3/files/Qemu%20Appliances/",
|
"download_url": "https://sourceforge.net/projects/gns-3/files/Qemu%20Appliances/",
|
||||||
"direct_download_url": "https://downloads.sourceforge.net/project/gns-3/Qemu%20Appliances/bird2-debian-2.14.qcow2"
|
"direct_download_url": "http://downloads.sourceforge.net/project/gns-3/Qemu%20Appliances/bird-tinycore64-1.5.0.img"
|
||||||
},
|
|
||||||
{
|
|
||||||
"filename": "bird2-debian-2.0.12.qcow2",
|
|
||||||
"version": "2.0.12",
|
|
||||||
"md5sum": "435218a2e90cba921cc7fde1d64a9419",
|
|
||||||
"filesize": 287965184,
|
|
||||||
"download_url": "https://sourceforge.net/projects/gns-3/files/Qemu%20Appliances/",
|
|
||||||
"direct_download_url": "https://downloads.sourceforge.net/project/gns-3/Qemu%20Appliances/bird2-debian-2.0.12.qcow2"
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"versions": [
|
"versions": [
|
||||||
{
|
{
|
||||||
"name": "2.14",
|
"name": "1.5.0",
|
||||||
"images": {
|
"images": {
|
||||||
"hda_disk_image": "bird2-debian-2.14.qcow2"
|
"hda_disk_image": "bird-tinycore64-1.5.0.img"
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "2.0.12",
|
|
||||||
"images": {
|
|
||||||
"hda_disk_image": "bird2-debian-2.0.12.qcow2"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|||||||
57
gns3server/appliances/bird2.gns3a
Normal file
57
gns3server/appliances/bird2.gns3a
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
{
|
||||||
|
"appliance_id": "8fecbf89-5cd1-4aea-b735-5f36cf0efbb7",
|
||||||
|
"name": "BIRD2",
|
||||||
|
"category": "router",
|
||||||
|
"description": "The BIRD project aims to develop a fully functional dynamic IP routing daemon primarily targeted on (but not limited to) Linux, FreeBSD and other UNIX-like systems and distributed under the GNU General Public License.",
|
||||||
|
"vendor_name": "CZ.NIC Labs",
|
||||||
|
"vendor_url": "https://bird.network.cz",
|
||||||
|
"documentation_url": "https://bird.network.cz/?get_doc&f=bird.html&v=20",
|
||||||
|
"product_name": "BIRD internet routing daemon",
|
||||||
|
"registry_version": 4,
|
||||||
|
"status": "stable",
|
||||||
|
"maintainer": "Bernhard Ehlers",
|
||||||
|
"maintainer_email": "dev-ehlers@mailbox.org",
|
||||||
|
"usage": "Username:\tgns3\nPassword:\tgns3\nTo become root, use \"sudo -s\".\n\nNetwork configuration:\nsudo nano /etc/network/interfaces\nsudo systemctl restart networking\n\nBIRD:\nRestart: sudo systemctl restart bird\nReconfigure: birdc configure",
|
||||||
|
"port_name_format": "eth{0}",
|
||||||
|
"qemu": {
|
||||||
|
"adapter_type": "virtio-net-pci",
|
||||||
|
"adapters": 4,
|
||||||
|
"ram": 512,
|
||||||
|
"hda_disk_interface": "scsi",
|
||||||
|
"arch": "x86_64",
|
||||||
|
"console_type": "telnet",
|
||||||
|
"kvm": "allow"
|
||||||
|
},
|
||||||
|
"images": [
|
||||||
|
{
|
||||||
|
"filename": "bird2-debian-2.14.qcow2",
|
||||||
|
"version": "2.14",
|
||||||
|
"md5sum": "029cf1756201ee79497c169502b08b88",
|
||||||
|
"filesize": 303717376,
|
||||||
|
"download_url": "https://sourceforge.net/projects/gns-3/files/Qemu%20Appliances/",
|
||||||
|
"direct_download_url": "https://downloads.sourceforge.net/project/gns-3/Qemu%20Appliances/bird2-debian-2.14.qcow2"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "bird2-debian-2.0.12.qcow2",
|
||||||
|
"version": "2.0.12",
|
||||||
|
"md5sum": "435218a2e90cba921cc7fde1d64a9419",
|
||||||
|
"filesize": 287965184,
|
||||||
|
"download_url": "https://sourceforge.net/projects/gns-3/files/Qemu%20Appliances/",
|
||||||
|
"direct_download_url": "https://downloads.sourceforge.net/project/gns-3/Qemu%20Appliances/bird2-debian-2.0.12.qcow2"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"versions": [
|
||||||
|
{
|
||||||
|
"name": "2.14",
|
||||||
|
"images": {
|
||||||
|
"hda_disk_image": "bird2-debian-2.14.qcow2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "2.0.12",
|
||||||
|
"images": {
|
||||||
|
"hda_disk_image": "bird2-debian-2.0.12.qcow2"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@ -27,20 +27,20 @@
|
|||||||
},
|
},
|
||||||
"images": [
|
"images": [
|
||||||
{
|
{
|
||||||
"filename": "CentOS-Stream-GenericCloud-10-20260504.0.x86_64.qcow2",
|
"filename": "CentOS-Stream-GenericCloud-x86_64-10-20250331.0.x86_64.qcow2",
|
||||||
"version": "Stream-10 (20260504.0)",
|
"version": "Stream-10 (20250331.0)",
|
||||||
"md5sum": "932b0bcc7e5c7404f91432979dc95314",
|
"md5sum": "776033371ca346001dd6390f0cbaf0d0",
|
||||||
"filesize": 2173501440,
|
"filesize": 952041472,
|
||||||
"download_url": "https://cloud.centos.org/centos/10-stream/x86_64/images",
|
"download_url": "https://cloud.centos.org/centos/10-stream/x86_64/images",
|
||||||
"direct_download_url": "https://cloud.centos.org/centos/10-stream/x86_64/images/CentOS-Stream-GenericCloud-10-20260504.0.x86_64.qcow2"
|
"direct_download_url": "https://cloud.centos.org/centos/10-stream/x86_64/images/CentOS-Stream-GenericCloud-x86_64-10-20250331.0.x86_64.qcow2"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"filename": "CentOS-Stream-GenericCloud-9-20260504.0.x86_64.qcow2",
|
"filename": "CentOS-Stream-GenericCloud-9-20250331.0.x86_64.qcow2",
|
||||||
"version": "Stream-9 (20260504.0)",
|
"version": "Stream-9 (20250331.0)",
|
||||||
"md5sum": "ebfbbd23ba7b85bbaf83c6c0626c2b70",
|
"md5sum": "4aaeddc6ca497065522c75a7471f9bfd",
|
||||||
"filesize": 1877251072,
|
"filesize": 1250625536,
|
||||||
"download_url": "https://cloud.centos.org/centos/9-stream/x86_64/images",
|
"download_url": "https://cloud.centos.org/centos/9-stream/x86_64/images",
|
||||||
"direct_download_url": "https://cloud.centos.org/centos/9-stream/x86_64/images/CentOS-Stream-GenericCloud-9-20260504.0.x86_64.qcow2"
|
"direct_download_url": "https://cloud.centos.org/centos/9-stream/x86_64/images/CentOS-Stream-GenericCloud-9-20250331.0.x86_64.qcow2"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"filename": "CentOS-Stream-GenericCloud-8-20240603.0.x86_64.qcow2",
|
"filename": "CentOS-Stream-GenericCloud-8-20240603.0.x86_64.qcow2",
|
||||||
@ -61,16 +61,16 @@
|
|||||||
],
|
],
|
||||||
"versions": [
|
"versions": [
|
||||||
{
|
{
|
||||||
"name": "Stream-10 (20260504.0)",
|
"name": "Stream-10 (20250331.0)",
|
||||||
"images": {
|
"images": {
|
||||||
"hda_disk_image": "CentOS-Stream-GenericCloud-10-20260504.0.x86_64.qcow2",
|
"hda_disk_image": "CentOS-Stream-GenericCloud-x86_64-10-20250331.0.x86_64.qcow2",
|
||||||
"cdrom_image": "centos-cloud-init-data.iso"
|
"cdrom_image": "centos-cloud-init-data.iso"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Stream-9 (20260504.0)",
|
"name": "Stream-9 (20250331.0)",
|
||||||
"images": {
|
"images": {
|
||||||
"hda_disk_image": "CentOS-Stream-GenericCloud-9-20260504.0.x86_64.qcow2",
|
"hda_disk_image": "CentOS-Stream-GenericCloud-9-20250331.0.x86_64.qcow2",
|
||||||
"cdrom_image": "centos-cloud-init-data.iso"
|
"cdrom_image": "centos-cloud-init-data.iso"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@ -1,6 +1,5 @@
|
|||||||
{
|
{
|
||||||
"appliance_id": "cc2b1802-3520-4963-8ff7-c19b1f6418c5",
|
"appliance_id": "cc2b1802-3520-4963-8ff7-c19b1f6418c5",
|
||||||
"tags": ["device_type:cisco_ios_telnet"],
|
|
||||||
"name": "Cisco 1700",
|
"name": "Cisco 1700",
|
||||||
"category": "router",
|
"category": "router",
|
||||||
"description": "Cisco 1700 Router",
|
"description": "Cisco 1700 Router",
|
||||||
|
|||||||
@ -1,6 +1,5 @@
|
|||||||
{
|
{
|
||||||
"appliance_id": "ed474fea-cd3b-4e2e-be84-a855a133060a",
|
"appliance_id": "ed474fea-cd3b-4e2e-be84-a855a133060a",
|
||||||
"tags": ["device_type:cisco_ios_telnet"],
|
|
||||||
"name": "Cisco 2600",
|
"name": "Cisco 2600",
|
||||||
"category": "router",
|
"category": "router",
|
||||||
"description": "Cisco 2600 Router",
|
"description": "Cisco 2600 Router",
|
||||||
|
|||||||
@ -1,6 +1,5 @@
|
|||||||
{
|
{
|
||||||
"appliance_id": "ed0f079e-a506-4cb4-b46c-714a80bbe2d3",
|
"appliance_id": "ed0f079e-a506-4cb4-b46c-714a80bbe2d3",
|
||||||
"tags": ["device_type:cisco_ios_telnet"],
|
|
||||||
"name": "Cisco 2691",
|
"name": "Cisco 2691",
|
||||||
"category": "router",
|
"category": "router",
|
||||||
"description": "Cisco 2691 Router",
|
"description": "Cisco 2691 Router",
|
||||||
|
|||||||
@ -1,6 +1,5 @@
|
|||||||
{
|
{
|
||||||
"appliance_id": "7ada6336-7280-4306-9f32-6b1e242ae989",
|
"appliance_id": "7ada6336-7280-4306-9f32-6b1e242ae989",
|
||||||
"tags": ["device_type:cisco_ios_telnet"],
|
|
||||||
"name": "Cisco 3620",
|
"name": "Cisco 3620",
|
||||||
"category": "router",
|
"category": "router",
|
||||||
"description": "Cisco 3620 Router",
|
"description": "Cisco 3620 Router",
|
||||||
|
|||||||
@ -1,6 +1,5 @@
|
|||||||
{
|
{
|
||||||
"appliance_id": "ef119e49-19fe-4239-9c6b-16ea12f6ec01",
|
"appliance_id": "ef119e49-19fe-4239-9c6b-16ea12f6ec01",
|
||||||
"tags": ["device_type:cisco_ios_telnet"],
|
|
||||||
"name": "Cisco 3640",
|
"name": "Cisco 3640",
|
||||||
"category": "router",
|
"category": "router",
|
||||||
"description": "Cisco 3640 Router",
|
"description": "Cisco 3640 Router",
|
||||||
|
|||||||
@ -1,6 +1,5 @@
|
|||||||
{
|
{
|
||||||
"appliance_id": "ac460a9c-9274-4ccf-a056-af50b699925f",
|
"appliance_id": "ac460a9c-9274-4ccf-a056-af50b699925f",
|
||||||
"tags": ["device_type:cisco_ios_telnet"],
|
|
||||||
"name": "Cisco 3660",
|
"name": "Cisco 3660",
|
||||||
"category": "router",
|
"category": "router",
|
||||||
"description": "Cisco 3660 Router",
|
"description": "Cisco 3660 Router",
|
||||||
|
|||||||
@ -1,6 +1,5 @@
|
|||||||
{
|
{
|
||||||
"appliance_id": "5b9c5293-a5a7-47a3-9df4-6cf658f2f378",
|
"appliance_id": "5b9c5293-a5a7-47a3-9df4-6cf658f2f378",
|
||||||
"tags": ["device_type:cisco_ios_telnet"],
|
|
||||||
"name": "Cisco 3725",
|
"name": "Cisco 3725",
|
||||||
"category": "router",
|
"category": "router",
|
||||||
"description": "Cisco 3725 Router",
|
"description": "Cisco 3725 Router",
|
||||||
|
|||||||
@ -1,6 +1,5 @@
|
|||||||
{
|
{
|
||||||
"appliance_id": "18737edb-e43f-4fb0-8a0f-88982cff58b1",
|
"appliance_id": "18737edb-e43f-4fb0-8a0f-88982cff58b1",
|
||||||
"tags": ["device_type:cisco_ios_telnet"],
|
|
||||||
"name": "Cisco 3745",
|
"name": "Cisco 3745",
|
||||||
"category": "router",
|
"category": "router",
|
||||||
"description": "Cisco 3745 Multiservice Access Router",
|
"description": "Cisco 3745 Multiservice Access Router",
|
||||||
|
|||||||
@ -1,6 +1,5 @@
|
|||||||
{
|
{
|
||||||
"appliance_id": "38aa3135-f169-4131-9b64-73605787b5ef",
|
"appliance_id": "38aa3135-f169-4131-9b64-73605787b5ef",
|
||||||
"tags": ["device_type:cisco_ios_telnet"],
|
|
||||||
"name": "Cisco 7200",
|
"name": "Cisco 7200",
|
||||||
"category": "router",
|
"category": "router",
|
||||||
"description": "Cisco 7200 Router",
|
"description": "Cisco 7200 Router",
|
||||||
|
|||||||
@ -9,7 +9,7 @@
|
|||||||
"product_name": "Alpine Linux Virt",
|
"product_name": "Alpine Linux Virt",
|
||||||
"product_url": "https://developer.cisco.com/modeling-labs/",
|
"product_url": "https://developer.cisco.com/modeling-labs/",
|
||||||
"registry_version": 4,
|
"registry_version": 4,
|
||||||
"status": "experimental",
|
"status": "beta",
|
||||||
"maintainer": "GNS3 Team",
|
"maintainer": "GNS3 Team",
|
||||||
"maintainer_email": "developers@gns3.net",
|
"maintainer_email": "developers@gns3.net",
|
||||||
"usage": "By default, a \"cisco\" account with password \"cisco\" is created.",
|
"usage": "By default, a \"cisco\" account with password \"cisco\" is created.",
|
||||||
|
|||||||
@ -26,13 +26,6 @@
|
|||||||
"kvm": "require"
|
"kvm": "require"
|
||||||
},
|
},
|
||||||
"images": [
|
"images": [
|
||||||
{
|
|
||||||
"filename": "asav9-23-1.qcow2",
|
|
||||||
"version": "9.23.1 CML",
|
|
||||||
"md5sum": "30454794b46fe07d1cd6a3ee72b511e1",
|
|
||||||
"filesize": 400687104,
|
|
||||||
"download_url": "https://u.cisco.com/my-learning/my-account"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"filename": "asav9-22-1-1.qcow2",
|
"filename": "asav9-22-1-1.qcow2",
|
||||||
"version": "9.22.1.1 CML",
|
"version": "9.22.1.1 CML",
|
||||||
@ -140,12 +133,6 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"versions": [
|
"versions": [
|
||||||
{
|
|
||||||
"name": "9.23.1 CML",
|
|
||||||
"images": {
|
|
||||||
"hda_disk_image": "asav9-23-1.qcow2"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"name": "9.22.1.1 CML",
|
"name": "9.22.1.1 CML",
|
||||||
"images": {
|
"images": {
|
||||||
|
|||||||
@ -17,7 +17,7 @@
|
|||||||
"qemu": {
|
"qemu": {
|
||||||
"adapter_type": "vmxnet3",
|
"adapter_type": "vmxnet3",
|
||||||
"adapters": 4,
|
"adapters": 4,
|
||||||
"ram": 4096,
|
"ram": 3072,
|
||||||
"hda_disk_interface": "ide",
|
"hda_disk_interface": "ide",
|
||||||
"arch": "x86_64",
|
"arch": "x86_64",
|
||||||
"console_type": "telnet",
|
"console_type": "telnet",
|
||||||
|
|||||||
@ -1,12 +1,11 @@
|
|||||||
{
|
{
|
||||||
"appliance_id": "3bf492b6-5717-4257-9bfd-b34617c6f133",
|
"appliance_id": "3bf492b6-5717-4257-9bfd-b34617c6f133",
|
||||||
"tags": ["device_type:cisco_ios_telnet"],
|
|
||||||
"name": "Cisco IOSv",
|
"name": "Cisco IOSv",
|
||||||
"category": "router",
|
"category": "router",
|
||||||
"description": "Cisco Virtual IOS allows user to run IOS on a standard computer.",
|
"description": "Cisco Virtual IOS allows user to run IOS on a standard computer.",
|
||||||
"vendor_name": "Cisco",
|
"vendor_name": "Cisco",
|
||||||
"vendor_url": "http://www.cisco.com/",
|
"vendor_url": "http://www.cisco.com/",
|
||||||
"documentation_url": "https://developer.cisco.com/docs/modeling-labs/iosv/",
|
"documentation_url": "https://developer.cisco.com/docs/modeling-labs/iol/",
|
||||||
"product_name": "IOSv",
|
"product_name": "IOSv",
|
||||||
"product_url": "https://developer.cisco.com/modeling-labs/",
|
"product_url": "https://developer.cisco.com/modeling-labs/",
|
||||||
"registry_version": 4,
|
"registry_version": 4,
|
||||||
@ -26,13 +25,6 @@
|
|||||||
"kvm": "require"
|
"kvm": "require"
|
||||||
},
|
},
|
||||||
"images": [
|
"images": [
|
||||||
{
|
|
||||||
"filename": "vios-adventerprisek9-m.spa.159-3.m10.qcow2",
|
|
||||||
"version": "15.9(3)M10",
|
|
||||||
"md5sum": "960ff630ce3fc030f6155a8e77d64105",
|
|
||||||
"filesize": 57323520,
|
|
||||||
"download_url": "https://u.cisco.com/my-learning/my-account"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"filename": "vios-adventerprisek9-m.spa.159-3.m9.qcow2",
|
"filename": "vios-adventerprisek9-m.spa.159-3.m9.qcow2",
|
||||||
"version": "15.9(3)M9",
|
"version": "15.9(3)M9",
|
||||||
@ -120,13 +112,6 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"versions": [
|
"versions": [
|
||||||
{
|
|
||||||
"name": "15.9(3)M10",
|
|
||||||
"images": {
|
|
||||||
"hda_disk_image": "vios-adventerprisek9-m.spa.159-3.m10.qcow2",
|
|
||||||
"hdb_disk_image": "IOSv_startup_config.img"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"name": "15.9(3)M9",
|
"name": "15.9(3)M9",
|
||||||
"images": {
|
"images": {
|
||||||
|
|||||||
@ -1,6 +1,5 @@
|
|||||||
{
|
{
|
||||||
"appliance_id": "4368f802-ddec-4863-adbd-a36a6d83cd4c",
|
"appliance_id": "4368f802-ddec-4863-adbd-a36a6d83cd4c",
|
||||||
"tags": ["device_type:cisco_ios_telnet"],
|
|
||||||
"name": "Cisco IOSvL2",
|
"name": "Cisco IOSvL2",
|
||||||
"category": "multilayer_switch",
|
"category": "multilayer_switch",
|
||||||
"description": "Cisco Virtual IOS L2 allows user to run a IOS switching image on a standard computer.",
|
"description": "Cisco Virtual IOS L2 allows user to run a IOS switching image on a standard computer.",
|
||||||
|
|||||||
@ -19,21 +19,13 @@
|
|||||||
"adapter_type": "virtio-net-pci",
|
"adapter_type": "virtio-net-pci",
|
||||||
"adapters": 7,
|
"adapters": 7,
|
||||||
"ram": 16384,
|
"ram": 16384,
|
||||||
"cpus": 4,
|
|
||||||
"hda_disk_interface": "ide",
|
"hda_disk_interface": "ide",
|
||||||
"arch": "x86_64",
|
"arch": "x86_64",
|
||||||
"console_type": "telnet",
|
"console_type": "telnet",
|
||||||
"kvm": "require",
|
"kvm": "require",
|
||||||
"options": "-cpu host"
|
"options": "-smp 4 -cpu host"
|
||||||
},
|
},
|
||||||
"images": [
|
"images": [
|
||||||
{
|
|
||||||
"filename": "xrv9k-fullk9-x-25.1.1.qcow2",
|
|
||||||
"version": "25.1.1",
|
|
||||||
"md5sum": "554d795d495badf90b6c75a2a342b409",
|
|
||||||
"filesize": 2002911232,
|
|
||||||
"download_url": "https://u.cisco.com/my-learning/my-account"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"filename": "xrv9k-fullk9-x-24.3.1.qcow2",
|
"filename": "xrv9k-fullk9-x-24.3.1.qcow2",
|
||||||
"version": "24.3.1",
|
"version": "24.3.1",
|
||||||
@ -57,12 +49,6 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"versions": [
|
"versions": [
|
||||||
{
|
|
||||||
"name": "25.1.1",
|
|
||||||
"images": {
|
|
||||||
"hda_disk_image": "xrv9k-fullk9-x-25.1.1.qcow2"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"name": "24.3.1",
|
"name": "24.3.1",
|
||||||
"images": {
|
"images": {
|
||||||
|
|||||||
@ -1,6 +1,5 @@
|
|||||||
{
|
{
|
||||||
"appliance_id": "9593db48-558a-4914-bb78-a20605f39c65",
|
"appliance_id": "9593db48-558a-4914-bb78-a20605f39c65",
|
||||||
"tags": ["device_type:cisco_ios_telnet"],
|
|
||||||
"name": "Cisco IOU L2",
|
"name": "Cisco IOU L2",
|
||||||
"category": "multilayer_switch",
|
"category": "multilayer_switch",
|
||||||
"description": "Cisco IOS on UNIX Layer 2 image.",
|
"description": "Cisco IOS on UNIX Layer 2 image.",
|
||||||
@ -38,6 +37,18 @@
|
|||||||
"version": "17.12.1",
|
"version": "17.12.1",
|
||||||
"md5sum": "2b5055e4cef8fd257416d74a94adb626",
|
"md5sum": "2b5055e4cef8fd257416d74a94adb626",
|
||||||
"filesize": 240355720
|
"filesize": 240355720
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "i86bi_linux_l2-adventerprisek9-ms.SSA.high_iron_20190423.bin",
|
||||||
|
"version": "15.2(20190423)",
|
||||||
|
"md5sum": "ffe884f8e762b762d7886c51d8ee015c",
|
||||||
|
"filesize": 126249700
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "i86bi_LinuxL2-AdvEnterpriseK9-M_152_May_2018.bin",
|
||||||
|
"version": "15.2(20180510)",
|
||||||
|
"md5sum": "d704b68c5f4c4f92e56b754b49b92012",
|
||||||
|
"filesize": 126226692
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"versions": [
|
"versions": [
|
||||||
@ -58,6 +69,18 @@
|
|||||||
"images": {
|
"images": {
|
||||||
"image": "x86_64_crb_linux_l2-adventerprisek9-ms"
|
"image": "x86_64_crb_linux_l2-adventerprisek9-ms"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "15.2(20190423)",
|
||||||
|
"images": {
|
||||||
|
"image": "i86bi_linux_l2-adventerprisek9-ms.SSA.high_iron_20190423.bin"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "15.2(20180510)",
|
||||||
|
"images": {
|
||||||
|
"image": "i86bi_LinuxL2-AdvEnterpriseK9-M_152_May_2018.bin"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,5 @@
|
|||||||
{
|
{
|
||||||
"appliance_id": "87bf6f58-1e5a-4ee2-afe7-715dabffcf18",
|
"appliance_id": "87bf6f58-1e5a-4ee2-afe7-715dabffcf18",
|
||||||
"tags": ["device_type:cisco_ios_telnet"],
|
|
||||||
"name": "Cisco IOU L3",
|
"name": "Cisco IOU L3",
|
||||||
"category": "router",
|
"category": "router",
|
||||||
"description": "Cisco IOS on UNIX Layer 3 image.",
|
"description": "Cisco IOS on UNIX Layer 3 image.",
|
||||||
@ -38,6 +37,12 @@
|
|||||||
"version": "17.12.1",
|
"version": "17.12.1",
|
||||||
"md5sum": "4a2fce8de21d1831fbceffd155e41ae7",
|
"md5sum": "4a2fce8de21d1831fbceffd155e41ae7",
|
||||||
"filesize": 288947184
|
"filesize": 288947184
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "i86bi_LinuxL3-AdvEnterpriseK9-M2_157_3_May_2018.bin",
|
||||||
|
"version": "15.7(3)M2",
|
||||||
|
"md5sum": "d6874260c3daeeb96d10fc844ae0b93b",
|
||||||
|
"filesize": 184759244
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"versions": [
|
"versions": [
|
||||||
@ -58,6 +63,12 @@
|
|||||||
"images": {
|
"images": {
|
||||||
"image": "x86_64_crb_linux-adventerprisek9-ms"
|
"image": "x86_64_crb_linux-adventerprisek9-ms"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "15.7(3)M2",
|
||||||
|
"images": {
|
||||||
|
"image": "i86bi_LinuxL3-AdvEnterpriseK9-M2_157_3_May_2018.bin"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,69 +0,0 @@
|
|||||||
{
|
|
||||||
"appliance_id": "4c7fd5da-be86-4168-8484-7071dc9c71fb",
|
|
||||||
"name": "Cisco NX-OSv 9000 Lite",
|
|
||||||
"category": "multilayer_switch",
|
|
||||||
"description": "The NX-OSv 9000 is a virtual platform that is designed to simulate the control plane aspects of a network element running Cisco Nexus 9000 software. The NX-OSv 9000 shares the same software image running on Cisco Nexus 9000 hardware platform although no specific hardware emulation is implemented. When the software runs as a virtual machine, line card (LC) ASIC provisioning or any interaction from the control plane to hardware ASIC is handled by the NX-OSv 9000 software data plane.\nThe NX-OSv 9000 for the Cisco Nexus 9000 Series provides a useful tool to enable the devops model and rapidly test changes to the infrastructure or to infrastructure automation tools. This enables network simulations in large scale for customers to validate configuration changes on a simulated network prior to applying them on a production network. Some users have also expressed interest in using the simulation system for feature test ,verification, and automation tooling development and test simualtion prior to deployment. NX-OSv 9000 can be used as a programmability vehicle to validate software defined networks (SDNs) and Network Function Virtualization (NFV) based solutions.\nThe lite version has a reduced memory footprint, resulting in a much smaller image size than the earlier images for Cisco Nexus 9300v and 9500v.",
|
|
||||||
"vendor_name": "Cisco",
|
|
||||||
"vendor_url": "http://www.cisco.com/",
|
|
||||||
"documentation_url": "https://developer.cisco.com/docs/modeling-labs/nx-os-9000/",
|
|
||||||
"product_name": "NX-OSv 9000",
|
|
||||||
"product_url": "https://developer.cisco.com/modeling-labs/",
|
|
||||||
"registry_version": 4,
|
|
||||||
"status": "stable",
|
|
||||||
"availability": "service-contract",
|
|
||||||
"maintainer": "GNS3 Team",
|
|
||||||
"maintainer_email": "developers@gns3.net",
|
|
||||||
"first_port_name": "mgmt0",
|
|
||||||
"port_name_format": "Ethernet1/{port1}",
|
|
||||||
"qemu": {
|
|
||||||
"adapter_type": "e1000",
|
|
||||||
"adapters": 10,
|
|
||||||
"ram": 6144,
|
|
||||||
"cpus": 2,
|
|
||||||
"hda_disk_interface": "sata",
|
|
||||||
"arch": "x86_64",
|
|
||||||
"console_type": "telnet",
|
|
||||||
"kvm": "require"
|
|
||||||
},
|
|
||||||
"images": [
|
|
||||||
{
|
|
||||||
"filename": "nexus9500v64-lite.10.5.5.M.qcow2",
|
|
||||||
"version": "9500v lite 10.5.5.M",
|
|
||||||
"md5sum": "a9aafd88f36a7f44a5a2ef3322cd9bde",
|
|
||||||
"filesize": 2617638912,
|
|
||||||
"download_url": "https://software.cisco.com/download/home/286312239/type/282088129/release/10.5(5)"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"filename": "nexus9300v64-lite.10.5.5.M.qcow2",
|
|
||||||
"version": "9300v lite 10.5.5.M",
|
|
||||||
"md5sum": "78610953005faab9505252baf4c86b78",
|
|
||||||
"filesize": 2617573376,
|
|
||||||
"download_url": "https://software.cisco.com/download/home/286312239/type/282088129/release/10.5(5)"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"filename": "OVMF-edk2-stable202305.fd",
|
|
||||||
"version": "stable202305",
|
|
||||||
"md5sum": "6c4cf1519fec4a4b95525d9ae562963a",
|
|
||||||
"filesize": 4194304,
|
|
||||||
"download_url": "https://sourceforge.net/projects/gns-3/files/Qemu%20Appliances/",
|
|
||||||
"direct_download_url": "https://sourceforge.net/projects/gns-3/files/Qemu%20Appliances/OVMF-edk2-stable202305.fd.zip/download",
|
|
||||||
"compression": "zip"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"versions": [
|
|
||||||
{
|
|
||||||
"name": "9500v lite 10.5.5.M",
|
|
||||||
"images": {
|
|
||||||
"bios_image": "OVMF-edk2-stable202305.fd",
|
|
||||||
"hda_disk_image": "nexus9500v64-lite.10.5.5.M.qcow2"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "9300v lite 10.5.5.M",
|
|
||||||
"images": {
|
|
||||||
"bios_image": "OVMF-edk2-stable202305.fd",
|
|
||||||
"hda_disk_image": "nexus9300v64-lite.10.5.5.M.qcow2"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
@ -27,20 +27,6 @@
|
|||||||
"kvm": "require"
|
"kvm": "require"
|
||||||
},
|
},
|
||||||
"images": [
|
"images": [
|
||||||
{
|
|
||||||
"filename": "nexus9500v64.10.5.5.M.qcow2",
|
|
||||||
"version": "9500v 10.5.5.M",
|
|
||||||
"md5sum": "c1d34bb3331d958d3219a56b6885150e",
|
|
||||||
"filesize": 2919170048,
|
|
||||||
"download_url": "https://software.cisco.com/download/home/286312239/type/282088129/release/10.5(5)"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"filename": "nexus9300v64.10.5.5.M.qcow2",
|
|
||||||
"version": "9300v 10.5.5.M",
|
|
||||||
"md5sum": "f1cc2342b920320654d232b68551ccfd",
|
|
||||||
"filesize": 2919104512,
|
|
||||||
"download_url": "https://software.cisco.com/download/home/286312239/type/282088129/release/10.5(5)"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"filename": "nexus9500v64.10.5.1.F.qcow2",
|
"filename": "nexus9500v64.10.5.1.F.qcow2",
|
||||||
"version": "9500v 10.5.1.F",
|
"version": "9500v 10.5.1.F",
|
||||||
@ -94,20 +80,6 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"versions": [
|
"versions": [
|
||||||
{
|
|
||||||
"name": "9500v 10.5.5.M",
|
|
||||||
"images": {
|
|
||||||
"bios_image": "OVMF-edk2-stable202305.fd",
|
|
||||||
"hda_disk_image": "nexus9500v64.10.5.5.M.qcow2"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "9300v 10.5.5.M",
|
|
||||||
"images": {
|
|
||||||
"bios_image": "OVMF-edk2-stable202305.fd",
|
|
||||||
"hda_disk_image": "nexus9300v64.10.5.5.M.qcow2"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"name": "9500v 10.5.1.F",
|
"name": "9500v 10.5.1.F",
|
||||||
"images": {
|
"images": {
|
||||||
|
|||||||
@ -26,30 +26,6 @@
|
|||||||
"options": "-nographic"
|
"options": "-nographic"
|
||||||
},
|
},
|
||||||
"images": [
|
"images": [
|
||||||
{
|
|
||||||
"filename": "Fedora-Cloud-Base-Generic-44-1.7.x86_64.qcow2",
|
|
||||||
"version": "44-1.7",
|
|
||||||
"md5sum": "49784011eb752291bfead24d3be8163f",
|
|
||||||
"filesize": 583729152,
|
|
||||||
"download_url": "https://download.fedoraproject.org/pub/fedora/linux/releases/44/Cloud/x86_64/images",
|
|
||||||
"direct_download_url": "https://fedora.mirrorservice.org/fedora/linux/releases/44/Cloud/x86_64/images/Fedora-Cloud-Base-Generic-44-1.7.x86_64.qcow2"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"filename": "Fedora-Cloud-Base-Generic-43-1.6.x86_64.qcow2",
|
|
||||||
"version": "43-1.6",
|
|
||||||
"md5sum": "f2f671db53fae58b79bb2e2259fa3622",
|
|
||||||
"filesize": 583335936,
|
|
||||||
"download_url": "https://download.fedoraproject.org/pub/fedora/linux/releases/43/Cloud/x86_64/images",
|
|
||||||
"direct_download_url": "https://fedora.mirrorservice.org/fedora/linux/releases/43/Cloud/x86_64/images/Fedora-Cloud-Base-Generic-43-1.6.x86_64.qcow2"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"filename": "Fedora-Cloud-Base-Generic-42-1.1.x86_64.qcow2",
|
|
||||||
"version": "42-1.1",
|
|
||||||
"md5sum": "2d660d2adc20b1fe793df5cb66f1d868",
|
|
||||||
"filesize": 532217856,
|
|
||||||
"download_url": "https://download.fedoraproject.org/pub/fedora/linux/releases/42/Cloud/x86_64/images",
|
|
||||||
"direct_download_url": "https://fedora.mirrorservice.org/fedora/linux/releases/42/Cloud/x86_64/images/Fedora-Cloud-Base-Generic-42-1.1.x86_64.qcow2"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"filename": "Fedora-Cloud-Base-Generic-41-1.4.x86_64.qcow2",
|
"filename": "Fedora-Cloud-Base-Generic-41-1.4.x86_64.qcow2",
|
||||||
"version": "41-1.4",
|
"version": "41-1.4",
|
||||||
@ -58,6 +34,30 @@
|
|||||||
"download_url": "https://download.fedoraproject.org/pub/fedora/linux/releases/41/Cloud/x86_64/images",
|
"download_url": "https://download.fedoraproject.org/pub/fedora/linux/releases/41/Cloud/x86_64/images",
|
||||||
"direct_download_url": "https://fedora.mirrorservice.org/fedora/linux/releases/41/Cloud/x86_64/images/Fedora-Cloud-Base-Generic-41-1.4.x86_64.qcow2"
|
"direct_download_url": "https://fedora.mirrorservice.org/fedora/linux/releases/41/Cloud/x86_64/images/Fedora-Cloud-Base-Generic-41-1.4.x86_64.qcow2"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"filename": "Fedora-Cloud-Base-Generic.x86_64-40-1.14.qcow2",
|
||||||
|
"version": "40-1.14",
|
||||||
|
"md5sum": "3eed4b1a9de35208ed30d9bb72c1522d",
|
||||||
|
"filesize": 397475840,
|
||||||
|
"download_url": "https://download.fedoraproject.org/pub/fedora/linux/releases/40/Cloud/x86_64/images",
|
||||||
|
"direct_download_url": "https://fedora.mirrorservice.org/fedora/linux/releases/40/Cloud/x86_64/images/Fedora-Cloud-Base-Generic.x86_64-40-1.14.qcow2"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "Fedora-Cloud-Base-39-1.5.x86_64.qcow2",
|
||||||
|
"version": "39-1.5",
|
||||||
|
"md5sum": "800a10df2d369891ed65900bcacacd47",
|
||||||
|
"filesize": 544604160,
|
||||||
|
"download_url": "https://download.fedoraproject.org/pub/fedora/linux/releases/39/Cloud/x86_64/images",
|
||||||
|
"direct_download_url": "https://download.fedoraproject.org/pub/fedora/linux/releases/39/Cloud/x86_64/images/Fedora-Cloud-Base-39-1.5.x86_64.qcow2"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "Fedora-Cloud-Base-38-1.6.x86_64.qcow2",
|
||||||
|
"version": "38-1.6",
|
||||||
|
"md5sum": "53ddfe7b28666d5ddc55e93ff06abad2",
|
||||||
|
"filesize": 497287168,
|
||||||
|
"download_url": "https://download.fedoraproject.org/pub/fedora/linux/releases/38/Cloud/x86_64/images",
|
||||||
|
"direct_download_url": "https://download.fedoraproject.org/pub/fedora/linux/releases/38/Cloud/x86_64/images/Fedora-Cloud-Base-38-1.6.x86_64.qcow2"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"filename": "fedora-cloud-init-data.iso",
|
"filename": "fedora-cloud-init-data.iso",
|
||||||
"version": "1.0",
|
"version": "1.0",
|
||||||
@ -68,33 +68,33 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"versions": [
|
"versions": [
|
||||||
{
|
|
||||||
"name": "44-1.7",
|
|
||||||
"images": {
|
|
||||||
"hda_disk_image": "Fedora-Cloud-Base-Generic-44-1.7.x86_64.qcow2",
|
|
||||||
"cdrom_image": "fedora-cloud-init-data.iso"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "43-1.6",
|
|
||||||
"images": {
|
|
||||||
"hda_disk_image": "Fedora-Cloud-Base-Generic-43-1.6.x86_64.qcow2",
|
|
||||||
"cdrom_image": "fedora-cloud-init-data.iso"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "42-1.1",
|
|
||||||
"images": {
|
|
||||||
"hda_disk_image": "Fedora-Cloud-Base-Generic-42-1.1.x86_64.qcow2",
|
|
||||||
"cdrom_image": "fedora-cloud-init-data.iso"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"name": "41-1.4",
|
"name": "41-1.4",
|
||||||
"images": {
|
"images": {
|
||||||
"hda_disk_image": "Fedora-Cloud-Base-Generic-41-1.4.x86_64.qcow2",
|
"hda_disk_image": "Fedora-Cloud-Base-Generic-41-1.4.x86_64.qcow2",
|
||||||
"cdrom_image": "fedora-cloud-init-data.iso"
|
"cdrom_image": "fedora-cloud-init-data.iso"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "40-1.14",
|
||||||
|
"images": {
|
||||||
|
"hda_disk_image": "Fedora-Cloud-Base-Generic.x86_64-40-1.14.qcow2",
|
||||||
|
"cdrom_image": "fedora-cloud-init-data.iso"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "39-1.5",
|
||||||
|
"images": {
|
||||||
|
"hda_disk_image": "Fedora-Cloud-Base-39-1.5.x86_64.qcow2",
|
||||||
|
"cdrom_image": "fedora-cloud-init-data.iso"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "38-1.6",
|
||||||
|
"images": {
|
||||||
|
"hda_disk_image": "Fedora-Cloud-Base-38-1.6.x86_64.qcow2",
|
||||||
|
"cdrom_image": "fedora-cloud-init-data.iso"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@ -51,12 +51,250 @@
|
|||||||
"download_url": "https://support.fortinet.com/Download/FirmwareImages.aspx"
|
"download_url": "https://support.fortinet.com/Download/FirmwareImages.aspx"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"filename": "empty500G.qcow2",
|
"filename": "FMG_VM64_KVM-v7.4.3-build2487-FORTINET.out.kvm.qcow2",
|
||||||
|
"version": "7.4.3",
|
||||||
|
"md5sum": "b01d9f86aa27c538407d518df1326863",
|
||||||
|
"filesize": 346107904,
|
||||||
|
"download_url": "https://support.fortinet.com/Download/FirmwareImages.aspx"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "FMG_VM64_KVM-v7.4.2-build2397-FORTINET.out.kvm.qcow2",
|
||||||
|
"version": "7.4.2",
|
||||||
|
"md5sum": "36371fbf06210ded57c00b2ff290f2c5",
|
||||||
|
"filesize": 322514944,
|
||||||
|
"download_url": "https://support.fortinet.com/Download/FirmwareImages.aspx"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "FMG_VM64_KVM-v7.4.1-build2308-FORTINET.out.kvm.qcow2",
|
||||||
|
"version": "7.4.1",
|
||||||
|
"md5sum": "e542cc8f2d8f46e9c32b783bf31bef39",
|
||||||
|
"filesize": 309387264,
|
||||||
|
"download_url": "https://support.fortinet.com/Download/FirmwareImages.aspx"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "FMG_VM64_KVM-v7.2.5-build1574-FORTINET.out.kvm.qcow2",
|
||||||
|
"version": "7.2.5",
|
||||||
|
"md5sum": "754326845096afd909ec45d98f8d5a83",
|
||||||
|
"filesize": 278401024,
|
||||||
|
"download_url": "https://support.fortinet.com/Download/FirmwareImages.aspx"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "FMG_VM64_KVM-v7.2.4-build1460-FORTINET.out.kvm.qcow2",
|
||||||
|
"version": "7.2.4",
|
||||||
|
"md5sum": "98fa9830d9ecb5911a703d03b80026b6",
|
||||||
|
"filesize": 261992448,
|
||||||
|
"download_url": "https://support.fortinet.com/Download/FirmwareImages.aspx"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "FMG_VM64_KVM-v7.2.2-build1334-FORTINET.out.kvm.qcow2",
|
||||||
|
"version": "7.2.2",
|
||||||
|
"md5sum": "2ff1298257321cd485d2cad91d6ce510",
|
||||||
|
"filesize": 246083584,
|
||||||
|
"download_url": "https://support.fortinet.com/Download/FirmwareImages.aspx"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "FMG_VM64_KVM-v7.2.1-build1215-FORTINET.out.kvm.qcow2",
|
||||||
|
"version": "7.2.1",
|
||||||
|
"md5sum": "1a3eeff1204fa8f4243773f7521e12b5",
|
||||||
|
"filesize": 242814976,
|
||||||
|
"download_url": "https://support.fortinet.com/Download/FirmwareImages.aspx"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "FMG_VM64_KVM-v7.0.12-build0623-FORTINET.out.kvm.qcow2",
|
||||||
|
"version": "7.0.12",
|
||||||
|
"md5sum": "5b6f6a2b8bc00e56337aa7023a9025cf",
|
||||||
|
"filesize": 249520128,
|
||||||
|
"download_url": "https://support.fortinet.com/Download/FirmwareImages.aspx"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "FMG_VM64_KVM-v7.0.11-build0595-FORTINET.out.kvm.qcow2",
|
||||||
|
"version": "7.0.11",
|
||||||
|
"md5sum": "7b166222136e26190159f37cccbaab6e",
|
||||||
|
"filesize": 249360384,
|
||||||
|
"download_url": "https://support.fortinet.com/Download/FirmwareImages.aspx"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "FMG_VM64_KVM-v7.0.9-build0489-FORTINET.out.kvm.qcow2",
|
||||||
|
"version": "7.0.9",
|
||||||
|
"md5sum": "dbeb6a79b6e421000573dbbbdb50b8b5",
|
||||||
|
"filesize": 247955456,
|
||||||
|
"download_url": "https://support.fortinet.com/Download/FirmwareImages.aspx"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "FMG_VM64_KVM-v7.0.6-build0372-FORTINET.out.kvm.qcow2",
|
||||||
|
"version": "7.0.6",
|
||||||
|
"md5sum": "dfa4df9e976ed87e73cb9601a8a70323",
|
||||||
|
"filesize": 239190016,
|
||||||
|
"download_url": "https://support.fortinet.com/Download/FirmwareImages.aspx"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "FMG_VM64_KVM-v7.0.5-build0365-FORTINET.out.kvm.qcow2",
|
||||||
|
"version": "7.0.5",
|
||||||
|
"md5sum": "e8b9c992784cea766b52a427a5fe0279",
|
||||||
|
"filesize": 237535232,
|
||||||
|
"download_url": "https://support.fortinet.com/Download/FirmwareImages.aspx"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "FMG_VM64_KVM-v6.4.14-build2660-FORTINET.out.kvm.qcow2",
|
||||||
|
"version": "6.4.14",
|
||||||
|
"md5sum": "0fe56e363b166c07b710bde795e36049",
|
||||||
|
"filesize": 219430912,
|
||||||
|
"download_url": "https://support.fortinet.com/Download/FirmwareImages.aspx"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "FMG_VM64_KVM-v6.4.12-build2610-FORTINET.out.kvm.qcow2",
|
||||||
|
"version": "6.4.12",
|
||||||
|
"md5sum": "36c0dc531d921e5f1e1e09b030f7c813",
|
||||||
|
"filesize": 219455488,
|
||||||
|
"download_url": "https://support.fortinet.com/Download/FirmwareImages.aspx"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "FMG_VM64_KVM-v6-build2288-FORTINET.out.kvm.qcow2",
|
||||||
|
"version": "6.4.5",
|
||||||
|
"md5sum": "bd2791984b03f55a6825297e83c6576a",
|
||||||
|
"filesize": 117014528,
|
||||||
|
"download_url": "https://support.fortinet.com/Download/FirmwareImages.aspx"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "FMG_VM64_KVM-v6-build2253-FORTINET.out.kvm.qcow2",
|
||||||
|
"version": "6.4.4",
|
||||||
|
"md5sum": "3554a47fde2dc91d17eec16fd0dc10a3",
|
||||||
|
"filesize": 116621312,
|
||||||
|
"download_url": "https://support.fortinet.com/Download/FirmwareImages.aspx"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "FMG_VM64_KVM-v6-build1183-FORTINET.out.kvm.qcow2",
|
||||||
|
"version": "6.2.2",
|
||||||
|
"md5sum": "f5051a8fe49d916bb554b9bae32a1eb4",
|
||||||
|
"filesize": 139145216,
|
||||||
|
"download_url": "https://support.fortinet.com/Download/FirmwareImages.aspx"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "FMG_VM64_KVM-v6-build1050-FORTINET.out.kvm.qcow2",
|
||||||
|
"version": "6.2.0",
|
||||||
|
"md5sum": "c19d2527f91ad1bbafbde5bf08487867",
|
||||||
|
"filesize": 126894080,
|
||||||
|
"download_url": "https://support.fortinet.com/Download/FirmwareImages.aspx"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "FMG_VM64_KVM-v6-build0349-FORTINET.out.kvm.qcow2",
|
||||||
|
"version": "6.0.6",
|
||||||
|
"md5sum": "d03f024c948ba6e2bb9e66c11ca8f34c",
|
||||||
|
"filesize": 112553984,
|
||||||
|
"download_url": "https://support.fortinet.com/Download/FirmwareImages.aspx"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "FMG_VM64_KVM-v6-build0255-FORTINET.out.kvm.qcow2",
|
||||||
|
"version": "6.0.3",
|
||||||
|
"md5sum": "5f34d52d9289b0be2a4c04943446ea39",
|
||||||
|
"filesize": 115703808,
|
||||||
|
"download_url": "https://support.fortinet.com/Download/FirmwareImages.aspx"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "FMG_VM64_KVM-v6-build0205-FORTINET.out.kvm.qcow2",
|
||||||
|
"version": "6.0.2",
|
||||||
|
"md5sum": "8f748649c537d9b5466b24c5b4e62017",
|
||||||
|
"filesize": 116981760,
|
||||||
|
"download_url": "https://support.fortinet.com/Download/FirmwareImages.aspx"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "FMG_VM64_KVM-v6-build0092-FORTINET.out.kvm.qcow2",
|
||||||
|
"version": "6.0.0",
|
||||||
|
"md5sum": "73bfe1bc70124521a524d857646b9c2e",
|
||||||
|
"filesize": 119066624,
|
||||||
|
"download_url": "https://support.fortinet.com/Download/FirmwareImages.aspx"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "FMG_VM64_KVM-v5-build1631-FORTINET.out.kvm.qcow2",
|
||||||
|
"version": "5.6.2",
|
||||||
|
"md5sum": "c81cc247e8eb03249b475fe0e847653e",
|
||||||
|
"filesize": 106946560,
|
||||||
|
"download_url": "https://support.fortinet.com/Download/FirmwareImages.aspx"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "FMG_VM64_KVM-v5-build1619-FORTINET.out.kvm.qcow2",
|
||||||
|
"version": "5.6.1",
|
||||||
|
"md5sum": "8cc553842564d232af295d6a0c784c1f",
|
||||||
|
"filesize": 106831872,
|
||||||
|
"download_url": "https://support.fortinet.com/Download/FirmwareImages.aspx"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "FMG_VM64_KVM-v5-build1557-FORTINET.out.kvm.qcow2",
|
||||||
|
"version": "5.6.0",
|
||||||
|
"md5sum": "f8bd600796f894f4ca1ea2d6b4066d3d",
|
||||||
|
"filesize": 108363776,
|
||||||
|
"download_url": "https://support.fortinet.com/Download/FirmwareImages.aspx"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "FMG_VM64_KVM-v5-build1225-FORTINET.out.kvm.qcow2",
|
||||||
|
"version": "5.4.4",
|
||||||
|
"md5sum": "53bc6e320fe7bde5d2b636bde95a910c",
|
||||||
|
"filesize": 89911296,
|
||||||
|
"download_url": "https://support.fortinet.com/Download/FirmwareImages.aspx"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "FMG_VM64_KVM-v5-build1187-FORTINET.out.kvm.qcow2",
|
||||||
|
"version": "5.4.3",
|
||||||
|
"md5sum": "53602c776d215d98e32163a10804fc49",
|
||||||
|
"filesize": 87425024,
|
||||||
|
"download_url": "https://support.fortinet.com/Download/FirmwareImages.aspx"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "FMG_VM64_KVM-v5-build1151-FORTINET.out.kvm.qcow2",
|
||||||
|
"version": "5.4.2",
|
||||||
|
"md5sum": "8e131ad40009c740f3efdee6dc3a0ac3",
|
||||||
|
"filesize": 86437888,
|
||||||
|
"download_url": "https://support.fortinet.com/Download/FirmwareImages.aspx"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "FMG_VM64_KVM-v5-build1082-FORTINET.out.kvm.qcow2",
|
||||||
|
"version": "5.4.1",
|
||||||
|
"md5sum": "fc1815410f3f0536e2e3a9c1c5c07f41",
|
||||||
|
"filesize": 83124224,
|
||||||
|
"download_url": "https://support.fortinet.com/Download/FirmwareImages.aspx"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "FMG_VM64_KVM-v5-build1019-FORTINET.out.kvm.qcow2",
|
||||||
|
"version": "5.4.0",
|
||||||
|
"md5sum": "1cfb22671cb372d8bf3e47b9c3c55ded",
|
||||||
|
"filesize": 77541376,
|
||||||
|
"download_url": "https://support.fortinet.com/Download/FirmwareImages.aspx"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "FMG_VM64_KVM-v5-build0786-FORTINET.out.kvm.qcow2",
|
||||||
|
"version": "5.2.10",
|
||||||
|
"md5sum": "377fe38bf07bc2435608e5b65f780f07",
|
||||||
|
"filesize": 64962560,
|
||||||
|
"download_url": "https://support.fortinet.com/Download/FirmwareImages.aspx"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "FMG_VM64_KVM-v5-build0780-FORTINET.out.kvm.qcow2",
|
||||||
|
"version": "5.2.9",
|
||||||
|
"md5sum": "04268e779d3d5e6c928c6fd638423c52",
|
||||||
|
"filesize": 65007616,
|
||||||
|
"download_url": "https://support.fortinet.com/Download/FirmwareImages.aspx"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "FMG_VM64_KVM-v5-build0777-FORTINET.out.kvm.qcow2",
|
||||||
|
"version": "5.2.8",
|
||||||
|
"md5sum": "6dbf148ace9bf309ad383757afd75fad",
|
||||||
|
"filesize": 65011712,
|
||||||
|
"download_url": "https://support.fortinet.com/Download/FirmwareImages.aspx"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "FMG_VM64_KVM-v5-build0757-FORTINET.out.kvm.qcow2",
|
||||||
|
"version": "5.2.7",
|
||||||
|
"md5sum": "d37dbaa49d7522324681eeba19f7699b",
|
||||||
|
"filesize": 65056768,
|
||||||
|
"download_url": "https://support.fortinet.com/Download/FirmwareImages.aspx"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "empty30G.qcow2",
|
||||||
"version": "1.0",
|
"version": "1.0",
|
||||||
"md5sum": "658c825441b9b3080ba00f9eec002eaa",
|
"md5sum": "3411a599e822f2ac6be560a26405821a",
|
||||||
"filesize": 204608,
|
"filesize": 197120,
|
||||||
"download_url": "https://sourceforge.net/projects/gns-3/files/Empty%20Qemu%20disk/",
|
"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/empty500G.qcow2/download"
|
"direct_download_url": "https://sourceforge.net/projects/gns-3/files/Empty%20Qemu%20disk/empty30G.qcow2/download"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"versions": [
|
"versions": [
|
||||||
@ -64,21 +302,259 @@
|
|||||||
"name": "7.4.6",
|
"name": "7.4.6",
|
||||||
"images": {
|
"images": {
|
||||||
"hda_disk_image": "FMG_VM64_KVM-v7.4.6.M-build2588-FORTINET.out.kvm.qcow2",
|
"hda_disk_image": "FMG_VM64_KVM-v7.4.6.M-build2588-FORTINET.out.kvm.qcow2",
|
||||||
"hdb_disk_image": "empty500G.qcow2"
|
"hdb_disk_image": "empty30G.qcow2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "7.4.5",
|
"name": "7.4.5",
|
||||||
"images": {
|
"images": {
|
||||||
"hda_disk_image": "FMG_VM64_KVM-v7.4.5.M-build2553-FORTINET.out.kvm.qcow2",
|
"hda_disk_image": "FMG_VM64_KVM-v7.4.5.M-build2553-FORTINET.out.kvm.qcow2",
|
||||||
"hdb_disk_image": "empty500G.qcow2"
|
"hdb_disk_image": "empty30G.qcow2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "7.4.4",
|
"name": "7.4.4",
|
||||||
"images": {
|
"images": {
|
||||||
"hda_disk_image": "FMG_VM64_KVM-v7.4.4.F-build2550-FORTINET.out.kvm.qcow2",
|
"hda_disk_image": "FMG_VM64_KVM-v7.4.4.F-build2550-FORTINET.out.kvm.qcow2",
|
||||||
"hdb_disk_image": "empty500G.qcow2"
|
"hdb_disk_image": "empty30G.qcow2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "7.4.3",
|
||||||
|
"images": {
|
||||||
|
"hda_disk_image": "FMG_VM64_KVM-v7.4.3-build2487-FORTINET.out.kvm.qcow2",
|
||||||
|
"hdb_disk_image": "empty30G.qcow2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "7.4.2",
|
||||||
|
"images": {
|
||||||
|
"hda_disk_image": "FMG_VM64_KVM-v7.4.2-build2397-FORTINET.out.kvm.qcow2",
|
||||||
|
"hdb_disk_image": "empty30G.qcow2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "7.4.1",
|
||||||
|
"images": {
|
||||||
|
"hda_disk_image": "FMG_VM64_KVM-v7.4.1-build2308-FORTINET.out.kvm.qcow2",
|
||||||
|
"hdb_disk_image": "empty30G.qcow2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "7.2.5",
|
||||||
|
"images": {
|
||||||
|
"hda_disk_image": "FMG_VM64_KVM-v7.2.5-build1574-FORTINET.out.kvm.qcow2",
|
||||||
|
"hdb_disk_image": "empty30G.qcow2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "7.2.4",
|
||||||
|
"images": {
|
||||||
|
"hda_disk_image": "FMG_VM64_KVM-v7.2.4-build1460-FORTINET.out.kvm.qcow2",
|
||||||
|
"hdb_disk_image": "empty30G.qcow2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "7.2.2",
|
||||||
|
"images": {
|
||||||
|
"hda_disk_image": "FMG_VM64_KVM-v7.2.2-build1334-FORTINET.out.kvm.qcow2",
|
||||||
|
"hdb_disk_image": "empty30G.qcow2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "7.2.1",
|
||||||
|
"images": {
|
||||||
|
"hda_disk_image": "FMG_VM64_KVM-v7.2.1-build1215-FORTINET.out.kvm.qcow2",
|
||||||
|
"hdb_disk_image": "empty30G.qcow2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "7.0.12",
|
||||||
|
"images": {
|
||||||
|
"hda_disk_image": "FMG_VM64_KVM-v7.0.12-build0623-FORTINET.out.kvm.qcow2",
|
||||||
|
"hdb_disk_image": "empty30G.qcow2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "7.0.11",
|
||||||
|
"images": {
|
||||||
|
"hda_disk_image": "FMG_VM64_KVM-v7.0.11-build0595-FORTINET.out.kvm.qcow2",
|
||||||
|
"hdb_disk_image": "empty30G.qcow2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "7.0.9",
|
||||||
|
"images": {
|
||||||
|
"hda_disk_image": "FMG_VM64_KVM-v7.0.9-build0489-FORTINET.out.kvm.qcow2",
|
||||||
|
"hdb_disk_image": "empty30G.qcow2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "7.0.6",
|
||||||
|
"images": {
|
||||||
|
"hda_disk_image": "FMG_VM64_KVM-v7.0.6-build0372-FORTINET.out.kvm.qcow2",
|
||||||
|
"hdb_disk_image": "empty30G.qcow2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "7.0.5",
|
||||||
|
"images": {
|
||||||
|
"hda_disk_image": "FMG_VM64_KVM-v7.0.5-build0365-FORTINET.out.kvm.qcow2",
|
||||||
|
"hdb_disk_image": "empty30G.qcow2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "6.4.14",
|
||||||
|
"images": {
|
||||||
|
"hda_disk_image": "FMG_VM64_KVM-v6.4.14-build2660-FORTINET.out.kvm.qcow2",
|
||||||
|
"hdb_disk_image": "empty30G.qcow2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "6.4.12",
|
||||||
|
"images": {
|
||||||
|
"hda_disk_image": "FMG_VM64_KVM-v6.4.12-build2610-FORTINET.out.kvm.qcow2",
|
||||||
|
"hdb_disk_image": "empty30G.qcow2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "6.4.5",
|
||||||
|
"images": {
|
||||||
|
"hda_disk_image": "FMG_VM64_KVM-v6-build2288-FORTINET.out.kvm.qcow2",
|
||||||
|
"hdb_disk_image": "empty30G.qcow2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "6.4.4",
|
||||||
|
"images": {
|
||||||
|
"hda_disk_image": "FMG_VM64_KVM-v6-build2253-FORTINET.out.kvm.qcow2",
|
||||||
|
"hdb_disk_image": "empty30G.qcow2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "6.2.2",
|
||||||
|
"images": {
|
||||||
|
"hda_disk_image": "FMG_VM64_KVM-v6-build1183-FORTINET.out.kvm.qcow2",
|
||||||
|
"hdb_disk_image": "empty30G.qcow2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "6.2.0",
|
||||||
|
"images": {
|
||||||
|
"hda_disk_image": "FMG_VM64_KVM-v6-build1050-FORTINET.out.kvm.qcow2",
|
||||||
|
"hdb_disk_image": "empty30G.qcow2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "6.0.6",
|
||||||
|
"images": {
|
||||||
|
"hda_disk_image": "FMG_VM64_KVM-v6-build0349-FORTINET.out.kvm.qcow2",
|
||||||
|
"hdb_disk_image": "empty30G.qcow2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "6.0.3",
|
||||||
|
"images": {
|
||||||
|
"hda_disk_image": "FMG_VM64_KVM-v6-build0255-FORTINET.out.kvm.qcow2",
|
||||||
|
"hdb_disk_image": "empty30G.qcow2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "6.0.2",
|
||||||
|
"images": {
|
||||||
|
"hda_disk_image": "FMG_VM64_KVM-v6-build0205-FORTINET.out.kvm.qcow2",
|
||||||
|
"hdb_disk_image": "empty30G.qcow2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "6.0.0",
|
||||||
|
"images": {
|
||||||
|
"hda_disk_image": "FMG_VM64_KVM-v6-build0092-FORTINET.out.kvm.qcow2",
|
||||||
|
"hdb_disk_image": "empty30G.qcow2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "5.6.2",
|
||||||
|
"images": {
|
||||||
|
"hda_disk_image": "FMG_VM64_KVM-v5-build1631-FORTINET.out.kvm.qcow2",
|
||||||
|
"hdb_disk_image": "empty30G.qcow2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "5.6.1",
|
||||||
|
"images": {
|
||||||
|
"hda_disk_image": "FMG_VM64_KVM-v5-build1619-FORTINET.out.kvm.qcow2",
|
||||||
|
"hdb_disk_image": "empty30G.qcow2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "5.6.0",
|
||||||
|
"images": {
|
||||||
|
"hda_disk_image": "FMG_VM64_KVM-v5-build1557-FORTINET.out.kvm.qcow2",
|
||||||
|
"hdb_disk_image": "empty30G.qcow2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "5.4.4",
|
||||||
|
"images": {
|
||||||
|
"hda_disk_image": "FMG_VM64_KVM-v5-build1225-FORTINET.out.kvm.qcow2",
|
||||||
|
"hdb_disk_image": "empty30G.qcow2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "5.4.3",
|
||||||
|
"images": {
|
||||||
|
"hda_disk_image": "FMG_VM64_KVM-v5-build1187-FORTINET.out.kvm.qcow2",
|
||||||
|
"hdb_disk_image": "empty30G.qcow2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "5.4.2",
|
||||||
|
"images": {
|
||||||
|
"hda_disk_image": "FMG_VM64_KVM-v5-build1151-FORTINET.out.kvm.qcow2",
|
||||||
|
"hdb_disk_image": "empty30G.qcow2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "5.4.1",
|
||||||
|
"images": {
|
||||||
|
"hda_disk_image": "FMG_VM64_KVM-v5-build1082-FORTINET.out.kvm.qcow2",
|
||||||
|
"hdb_disk_image": "empty30G.qcow2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "5.4.0",
|
||||||
|
"images": {
|
||||||
|
"hda_disk_image": "FMG_VM64_KVM-v5-build1019-FORTINET.out.kvm.qcow2",
|
||||||
|
"hdb_disk_image": "empty30G.qcow2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "5.2.10",
|
||||||
|
"images": {
|
||||||
|
"hda_disk_image": "FMG_VM64_KVM-v5-build0786-FORTINET.out.kvm.qcow2",
|
||||||
|
"hdb_disk_image": "empty30G.qcow2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "5.2.9",
|
||||||
|
"images": {
|
||||||
|
"hda_disk_image": "FMG_VM64_KVM-v5-build0780-FORTINET.out.kvm.qcow2",
|
||||||
|
"hdb_disk_image": "empty30G.qcow2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "5.2.8",
|
||||||
|
"images": {
|
||||||
|
"hda_disk_image": "FMG_VM64_KVM-v5-build0777-FORTINET.out.kvm.qcow2",
|
||||||
|
"hdb_disk_image": "empty30G.qcow2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "5.2.7",
|
||||||
|
"images": {
|
||||||
|
"hda_disk_image": "FMG_VM64_KVM-v5-build0757-FORTINET.out.kvm.qcow2",
|
||||||
|
"hdb_disk_image": "empty30G.qcow2"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|||||||
@ -1,6 +1,5 @@
|
|||||||
{
|
{
|
||||||
"appliance_id": "bd86792e-9870-4b42-8f16-cb2776f1d5d5",
|
"appliance_id": "bd86792e-9870-4b42-8f16-cb2776f1d5d5",
|
||||||
"tags": ["device_type:gns3_huawei_telnet_ce"],
|
|
||||||
"name": "HuaWei CE12800",
|
"name": "HuaWei CE12800",
|
||||||
"category": "multilayer_switch",
|
"category": "multilayer_switch",
|
||||||
"description": "CE12800 series switches are high-performance core switches designed for data center networks and high-end campus networks. The switches provide stable, reliable, secure, and high-performance Layer 2/Layer 3 switching services, to help build an elastic, virtualized, agile, and high-quality network.",
|
"description": "CE12800 series switches are high-performance core switches designed for data center networks and high-end campus networks. The switches provide stable, reliable, secure, and high-performance Layer 2/Layer 3 switching services, to help build an elastic, virtualized, agile, and high-quality network.",
|
||||||
|
|||||||
@ -132,37 +132,9 @@
|
|||||||
"md5sum": "24cd1006734993dab338e5c75f80b875",
|
"md5sum": "24cd1006734993dab338e5c75f80b875",
|
||||||
"version": "26.03.0",
|
"version": "26.03.0",
|
||||||
"direct_download_url": "https://github.com/kernelkit/infix/releases/download/v26.03.0/infix-x86_64-v26.03.0.qcow2"
|
"direct_download_url": "https://github.com/kernelkit/infix/releases/download/v26.03.0/infix-x86_64-v26.03.0.qcow2"
|
||||||
},
|
|
||||||
{
|
|
||||||
"filename": "infix-x86_64-v26.05.0.qcow2",
|
|
||||||
"filesize": 330039296,
|
|
||||||
"md5sum": "60f7c36c389c33ab108acc021f41ccd5",
|
|
||||||
"version": "26.05.0",
|
|
||||||
"direct_download_url": "https://github.com/kernelkit/infix/releases/download/v26.05.0/infix-x86_64-v26.05.0.qcow2"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"filename": "infix-x86_64-v26.06.0.qcow2",
|
|
||||||
"filesize": 363593728,
|
|
||||||
"md5sum": "79ca8bd8534bbaa1af0ab874a49d6f4c",
|
|
||||||
"version": "26.06.0",
|
|
||||||
"direct_download_url": "https://github.com/kernelkit/infix/releases/download/v26.06.0/infix-x86_64-v26.06.0.qcow2"
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"versions": [
|
"versions": [
|
||||||
{
|
|
||||||
"name": "26.06.0",
|
|
||||||
"images": {
|
|
||||||
"bios_image": "OVMF-edk2-stable202305.fd",
|
|
||||||
"hda_disk_image": "infix-x86_64-v26.06.0.qcow2"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "26.05.0",
|
|
||||||
"images": {
|
|
||||||
"bios_image": "OVMF-edk2-stable202305.fd",
|
|
||||||
"hda_disk_image": "infix-x86_64-v26.05.0.qcow2"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"name": "26.03.0",
|
"name": "26.03.0",
|
||||||
"images": {
|
"images": {
|
||||||
|
|||||||
@ -17,7 +17,7 @@
|
|||||||
"qemu": {
|
"qemu": {
|
||||||
"adapter_type": "virtio-net-pci",
|
"adapter_type": "virtio-net-pci",
|
||||||
"adapters": 1,
|
"adapters": 1,
|
||||||
"ram": 1536,
|
"ram": 1024,
|
||||||
"hda_disk_interface": "virtio",
|
"hda_disk_interface": "virtio",
|
||||||
"arch": "x86_64",
|
"arch": "x86_64",
|
||||||
"console_type": "telnet",
|
"console_type": "telnet",
|
||||||
@ -27,36 +27,60 @@
|
|||||||
},
|
},
|
||||||
"images": [
|
"images": [
|
||||||
{
|
{
|
||||||
"filename": "OL10U1_x86_64-kvm-b270.qcow2",
|
"filename": "OL9U5_x86_64-kvm-b259.qcow2",
|
||||||
"version": "10.1",
|
"version": "9.5",
|
||||||
"md5sum": "c3ed48965110e0cbbd75734d3c23a2ce",
|
"md5sum": "05e9b62c408ab49a02d6833fc683d1ad",
|
||||||
"filesize": 1044119552,
|
"filesize": 652935168,
|
||||||
"download_url": "https://yum.oracle.com/oracle-linux-templates.html",
|
"download_url": "https://yum.oracle.com/oracle-linux-templates.html",
|
||||||
"direct_download_url": "https://yum.oracle.com/templates/OracleLinux/OL10/u1/x86_64/OL10U1_x86_64-kvm-b270.qcow2"
|
"direct_download_url": "https://yum.oracle.com/templates/OracleLinux/OL9/u5/x86_64/OL9U5_x86_64-kvm-b259.qcow2"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"filename": "OL9U7_x86_64-kvm-b269.qcow2",
|
"filename": "OL9U2_x86_64-kvm-b197.qcow",
|
||||||
"version": "9.7",
|
"version": "9.2",
|
||||||
"md5sum": "fe0c555620d2001bb4d4d95a53b43738",
|
"md5sum": "2ff3d0bc8a243ad89c96215f303f1c73",
|
||||||
"filesize": 792985600,
|
"filesize": 560791552,
|
||||||
"download_url": "https://yum.oracle.com/oracle-linux-templates.html",
|
"download_url": "https://yum.oracle.com/oracle-linux-templates.html",
|
||||||
"direct_download_url": "https://yum.oracle.com/templates/OracleLinux/OL9/u7/x86_64/OL9U7_x86_64-kvm-b269.qcow2"
|
"direct_download_url": "https://yum.oracle.com/templates/OracleLinux/OL9/u2/x86_64/OL9U2_x86_64-kvm-b197.qcow"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"filename": "OL8U10_x86_64-kvm-b271.qcow2",
|
"filename": "OL9U1_x86_64-kvm-b158.qcow",
|
||||||
|
"version": "9.1",
|
||||||
|
"md5sum": "9f32851b96fc38191892197fa11f7435",
|
||||||
|
"filesize": 539033600,
|
||||||
|
"download_url": "https://yum.oracle.com/oracle-linux-templates.html",
|
||||||
|
"direct_download_url": "https://yum.oracle.com/templates/OracleLinux/OL9/u1/x86_64/OL9U1_x86_64-kvm-b158.qcow"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "OL8U10_x86_64-kvm-b258.qcow2",
|
||||||
"version": "8.10",
|
"version": "8.10",
|
||||||
"md5sum": "f3184e536af1c2aba6b6f499b1a7085a",
|
"md5sum": "bb07581af5122515b6822595ded5deef",
|
||||||
"filesize": 1585643520,
|
"filesize": 1251672064,
|
||||||
"download_url": "https://yum.oracle.com/oracle-linux-templates.html",
|
"download_url": "https://yum.oracle.com/oracle-linux-templates.html",
|
||||||
"direct_download_url": "https://yum.oracle.com/templates/OracleLinux/OL8/u10/x86_64/OL8U10_x86_64-kvm-b271.qcow2"
|
"direct_download_url": "https://yum.oracle.com/templates/OracleLinux/OL8/u10/x86_64/OL8U10_x86_64-kvm-b258.qcow2"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"filename": "OL7U9_x86_64-kvm-b257.qcow2",
|
"filename": "OL8U8_x86_64-kvm-b198.qcow",
|
||||||
"version": "7.9",
|
"version": "8.8",
|
||||||
"md5sum": "d3af7cf0b8f44d298a67ce9ebe184494",
|
"md5sum": "717622f373d77349cc102a3a325efbd3",
|
||||||
"filesize": 998244352,
|
"filesize": 934215680,
|
||||||
"download_url": "https://yum.oracle.com/oracle-linux-templates.html",
|
"download_url": "https://yum.oracle.com/oracle-linux-templates.html",
|
||||||
"direct_download_url": "https://yum.oracle.com/templates/OracleLinux/OL7/u9/x86_64/OL7U9_x86_64-kvm-b257.qcow2"
|
"direct_download_url": "https://yum.oracle.com/templates/OracleLinux/OL8/u8/x86_64/OL8U8_x86_64-kvm-b198.qcow"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "OL8U7_x86_64-kvm-b148.qcow",
|
||||||
|
"version": "8.7",
|
||||||
|
"md5sum": "962cdde7e810888b9914e937222f687f",
|
||||||
|
"filesize": 913965056,
|
||||||
|
"download_url": "https://yum.oracle.com/oracle-linux-templates.html",
|
||||||
|
"direct_download_url": "https://yum.oracle.com/templates/OracleLinux/OL8/u7/x86_64/OL8U7_x86_64-kvm-b148.qcow"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "OL7U9_x86_64-kvm-b145.qcow",
|
||||||
|
"version": "7.9",
|
||||||
|
"md5sum": "e60d4145a69b34026db6121109ca9131",
|
||||||
|
"filesize": 725221376,
|
||||||
|
"download_url": "https://yum.oracle.com/oracle-linux-templates.html",
|
||||||
|
"direct_download_url": "https://yum.oracle.com/templates/OracleLinux/OL7/u9/x86_64/OL7U9_x86_64-kvm-b145.qcow"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"filename": "oracle-cloud-init-data.iso",
|
"filename": "oracle-cloud-init-data.iso",
|
||||||
@ -69,30 +93,51 @@
|
|||||||
],
|
],
|
||||||
"versions": [
|
"versions": [
|
||||||
{
|
{
|
||||||
"name": "10.1",
|
"name": "9.5",
|
||||||
"images": {
|
"images": {
|
||||||
"hda_disk_image": "OL10U1_x86_64-kvm-b270.qcow2",
|
"hda_disk_image": "OL9U5_x86_64-kvm-b259.qcow2",
|
||||||
"cdrom_image": "oracle-cloud-init-data.iso"
|
"cdrom_image": "oracle-cloud-init-data.iso"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "9.7",
|
"name": "9.2",
|
||||||
"images": {
|
"images": {
|
||||||
"hda_disk_image": "OL9U7_x86_64-kvm-b269.qcow2",
|
"hda_disk_image": "OL9U2_x86_64-kvm-b197.qcow",
|
||||||
|
"cdrom_image": "oracle-cloud-init-data.iso"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "9.1",
|
||||||
|
"images": {
|
||||||
|
"hda_disk_image": "OL9U1_x86_64-kvm-b158.qcow",
|
||||||
"cdrom_image": "oracle-cloud-init-data.iso"
|
"cdrom_image": "oracle-cloud-init-data.iso"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "8.10",
|
"name": "8.10",
|
||||||
"images": {
|
"images": {
|
||||||
"hda_disk_image": "OL8U10_x86_64-kvm-b271.qcow2",
|
"hda_disk_image": "OL8U10_x86_64-kvm-b258.qcow2",
|
||||||
|
"cdrom_image": "oracle-cloud-init-data.iso"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "8.8",
|
||||||
|
"images": {
|
||||||
|
"hda_disk_image": "OL8U8_x86_64-kvm-b198.qcow",
|
||||||
|
"cdrom_image": "oracle-cloud-init-data.iso"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "8.7",
|
||||||
|
"images": {
|
||||||
|
"hda_disk_image": "OL8U7_x86_64-kvm-b148.qcow",
|
||||||
"cdrom_image": "oracle-cloud-init-data.iso"
|
"cdrom_image": "oracle-cloud-init-data.iso"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "7.9",
|
"name": "7.9",
|
||||||
"images": {
|
"images": {
|
||||||
"hda_disk_image": "OL7U9_x86_64-kvm-b257.qcow2",
|
"hda_disk_image": "OL7U9_x86_64-kvm-b145.qcow",
|
||||||
"cdrom_image": "oracle-cloud-init-data.iso"
|
"cdrom_image": "oracle-cloud-init-data.iso"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -17,7 +17,7 @@
|
|||||||
"qemu": {
|
"qemu": {
|
||||||
"adapter_type": "virtio-net-pci",
|
"adapter_type": "virtio-net-pci",
|
||||||
"adapters": 1,
|
"adapters": 1,
|
||||||
"ram": 1536,
|
"ram": 1024,
|
||||||
"hda_disk_interface": "virtio",
|
"hda_disk_interface": "virtio",
|
||||||
"arch": "x86_64",
|
"arch": "x86_64",
|
||||||
"console_type": "telnet",
|
"console_type": "telnet",
|
||||||
@ -26,22 +26,6 @@
|
|||||||
"options": "-nographic -cpu host"
|
"options": "-nographic -cpu host"
|
||||||
},
|
},
|
||||||
"images": [
|
"images": [
|
||||||
{
|
|
||||||
"filename": "Rocky-10-GenericCloud-Base-10.1-20251116.0.x86_64.qcow2",
|
|
||||||
"version": "10.1",
|
|
||||||
"md5sum": "729d7235716bd41a0a15e07d2b44c679",
|
|
||||||
"filesize": 575406080,
|
|
||||||
"download_url": "https://download.rockylinux.org/pub/rocky/9/images/x86_64/",
|
|
||||||
"direct_download_url": "https://download.rockylinux.org/pub/rocky/10/images/x86_64/Rocky-10-GenericCloud-Base-10.1-20251116.0.x86_64.qcow2"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"filename": "Rocky-9-GenericCloud-Base-9.7-20251123.2.x86_64.qcow2",
|
|
||||||
"version": "9.7",
|
|
||||||
"md5sum": "4a0cbfb45b97f09b690044429aaca1c8",
|
|
||||||
"filesize": 648806400,
|
|
||||||
"download_url": "https://download.rockylinux.org/pub/rocky/9/images/x86_64/",
|
|
||||||
"direct_download_url": "https://download.rockylinux.org/pub/rocky/9/images/x86_64/Rocky-9-GenericCloud-Base-9.7-20251123.2.x86_64.qcow2"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"filename": "Rocky-9-GenericCloud-Base-9.5-20241118.0.x86_64.qcow2",
|
"filename": "Rocky-9-GenericCloud-Base-9.5-20241118.0.x86_64.qcow2",
|
||||||
"version": "9.5",
|
"version": "9.5",
|
||||||
@ -92,20 +76,6 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"versions": [
|
"versions": [
|
||||||
{
|
|
||||||
"name": "10.1",
|
|
||||||
"images": {
|
|
||||||
"hda_disk_image": "Rocky-10-GenericCloud-Base-10.1-20251116.0.x86_64.qcow2",
|
|
||||||
"cdrom_image": "rocky-cloud-init-data.iso"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "9.7",
|
|
||||||
"images": {
|
|
||||||
"hda_disk_image": "Rocky-9-GenericCloud-Base-9.7-20251123.2.x86_64.qcow2",
|
|
||||||
"cdrom_image": "rocky-cloud-init-data.iso"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"name": "9.5",
|
"name": "9.5",
|
||||||
"images": {
|
"images": {
|
||||||
|
|||||||
@ -14,7 +14,7 @@
|
|||||||
"symbol": "linux_guest.svg",
|
"symbol": "linux_guest.svg",
|
||||||
"docker": {
|
"docker": {
|
||||||
"adapters": 1,
|
"adapters": 1,
|
||||||
"image": "gns3/ubuntu:resolute",
|
"image": "gns3/ubuntu:noble",
|
||||||
"console_type": "telnet"
|
"console_type": "telnet"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,86 +0,0 @@
|
|||||||
{
|
|
||||||
"appliance_id": "90afc191-6195-4ff2-905b-5470573a882b",
|
|
||||||
"name": "Westermo WeOS",
|
|
||||||
"category": "router",
|
|
||||||
"description": "Westermo Operating System (WeOS) is a leading-edge industrial network operating system that is being continuously developed whilst being subjected to exhaustive quality testing. It powers the most reliable switches and routers on the market, designed for harsh industrial environments. WeOS has extensive support for network and security protocols that have been made simple to configure and maintain. WeOS along with Westermo’s robust hardware provides the world’s most reliable network solutions.",
|
|
||||||
"vendor_name": "Westermo",
|
|
||||||
"vendor_url": "https://www.westermo.com/",
|
|
||||||
"vendor_logo_url": "https://api-0831ddf0-b06c-4a4e-bcf7-afba78872de1.digizuite.app/DigizuiteCore/CollaborationService/api/share/asset/4C90E538E869D47D2782840A06F726F6D7548D864857388E38218F",
|
|
||||||
"documentation_url": "https://docs.westermo.com/weos/weos-5/",
|
|
||||||
"product_name": "WeOS",
|
|
||||||
"product_url": "https://www.westermo.com/products/software/weos",
|
|
||||||
"registry_version": 4,
|
|
||||||
"status": "stable",
|
|
||||||
"availability": "free",
|
|
||||||
"maintainer": "Westermo",
|
|
||||||
"maintainer_email": "info@westermo.com",
|
|
||||||
"usage": "\nFactory Configuration\n=====================\nAll ports are in VLAN1 untagged. The system will acquire a link-local\nIPv4 address (169.254.0.0/16) and will also request an address using\nDHCP. mDNS is enabled and the device is reachable under these names\n(where XX-XX-XX corresponds to the last three octets in the device's\nMAC address): zero-XX-XX-XX.local, zero.local, and weos.local.\n\nManagement\n==========\nAccessible via console, ssh, and http/https.\n\nUsername: admin\nPassword: admin\n\nUpgrade\n=======\nTo upgrade a device, simply download the new version and replace the\nHDA (Primary Master) image under the HDD tab in the configuration pane\nof the device.\n",
|
|
||||||
"symbol": ":/symbols/classic/router.svg",
|
|
||||||
"port_name_format": "eth{0}",
|
|
||||||
"linked_clone": true,
|
|
||||||
"qemu": {
|
|
||||||
"adapter_type": "virtio-net-pci",
|
|
||||||
"adapters": 8,
|
|
||||||
"ram": 512,
|
|
||||||
"cpus": 1,
|
|
||||||
"hda_disk_interface": "virtio",
|
|
||||||
"hdb_disk_interface": "virtio",
|
|
||||||
"arch": "x86_64",
|
|
||||||
"console_type": "telnet",
|
|
||||||
"kvm": "allow",
|
|
||||||
"options": "-nographic --machine pc-i440fx-4.2"
|
|
||||||
},
|
|
||||||
"images": [
|
|
||||||
{
|
|
||||||
"filename": "Config-zero-1.0.0.disk",
|
|
||||||
"version": "1.0.0",
|
|
||||||
"md5sum": "afe7b74683971fec48802997f6470ca5",
|
|
||||||
"filesize": 17825792,
|
|
||||||
"direct_download_url": "https://dropzone.westermo.com/file.aspx?id=e6a7676d-85a7-4374-8961-c68aacb74921"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"filename": "WeOS-zero-5.29.0.disk",
|
|
||||||
"version": "5.29.0",
|
|
||||||
"filesize": 81788928,
|
|
||||||
"md5sum": "f464de7b2b424f4a8ad7c650108fee3d",
|
|
||||||
"direct_download_url": "https://dropzone.westermo.com/file.aspx?id=52655074-0fab-4119-ba01-b68200a733ab"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"filename": "WeOS-zero-5.28.0.disk",
|
|
||||||
"version": "5.28.0",
|
|
||||||
"md5sum": "7b4e29761091c12ec2cd482f7c1a0bea",
|
|
||||||
"filesize": 75497472,
|
|
||||||
"direct_download_url": "https://dropzone.westermo.com/file.aspx?id=4926adbe-0cd6-4851-b70f-e9d60b3b3f06"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"filename": "WeOS-zero-5.27.0.disk",
|
|
||||||
"version": "5.27.0",
|
|
||||||
"md5sum": "8bd4944b60eaeca391bb5d1dc0defb8b",
|
|
||||||
"filesize": 78643200,
|
|
||||||
"direct_download_url": "https://dropzone.westermo.com/file.aspx?id=1a7bf389-a4b1-4dae-b121-6fb3d6781542"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"versions": [
|
|
||||||
{
|
|
||||||
"name": "5.29.0",
|
|
||||||
"images": {
|
|
||||||
"hda_disk_image": "WeOS-zero-5.29.0.disk",
|
|
||||||
"hdb_disk_image": "Config-zero-1.0.0.disk"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "5.28.0",
|
|
||||||
"images": {
|
|
||||||
"hda_disk_image": "WeOS-zero-5.28.0.disk",
|
|
||||||
"hdb_disk_image": "Config-zero-1.0.0.disk"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "5.27.0",
|
|
||||||
"images": {
|
|
||||||
"hda_disk_image": "WeOS-zero-5.27.0.disk",
|
|
||||||
"hdb_disk_image": "Config-zero-1.0.0.disk"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
@ -311,7 +311,7 @@ class Cloud(BaseNode):
|
|||||||
if not port_info["interface"] in network_interfaces:
|
if not port_info["interface"] in network_interfaces:
|
||||||
raise NodeError("Interface '{}' could not be found on this system, please update '{}'".format(port_info["interface"], self.name))
|
raise NodeError("Interface '{}' could not be found on this system, please update '{}'".format(port_info["interface"], self.name))
|
||||||
|
|
||||||
if sys.platform.startswith("linux") or sys.platform.startswith("openbsd"):
|
if sys.platform.startswith("linux"):
|
||||||
await self._add_linux_ethernet(port_info, bridge_name)
|
await self._add_linux_ethernet(port_info, bridge_name)
|
||||||
elif sys.platform.startswith("darwin"):
|
elif sys.platform.startswith("darwin"):
|
||||||
await self._add_osx_ethernet(port_info, bridge_name)
|
await self._add_osx_ethernet(port_info, bridge_name)
|
||||||
|
|||||||
@ -33,7 +33,7 @@ from gns3server.config import Config
|
|||||||
from gns3server.utils.asyncio import locking
|
from gns3server.utils.asyncio import locking
|
||||||
from gns3server.compute.base_manager import BaseManager
|
from gns3server.compute.base_manager import BaseManager
|
||||||
from gns3server.compute.docker.docker_vm import DockerVM
|
from gns3server.compute.docker.docker_vm import DockerVM
|
||||||
from gns3server.compute.docker.docker_error import DockerError, DockerHttp304Error, DockerHttp404Error, DockerHttp409Error
|
from gns3server.compute.docker.docker_error import DockerError, DockerHttp304Error, DockerHttp404Error
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
@ -236,8 +236,6 @@ class Docker(BaseManager):
|
|||||||
raise DockerHttp304Error("Docker has returned an error: {} {}".format(response.status, body))
|
raise DockerHttp304Error("Docker has returned an error: {} {}".format(response.status, body))
|
||||||
elif response.status == 404:
|
elif response.status == 404:
|
||||||
raise DockerHttp404Error("Docker has returned an error: {} {}".format(response.status, body))
|
raise DockerHttp404Error("Docker has returned an error: {} {}".format(response.status, body))
|
||||||
elif response.status == 409:
|
|
||||||
raise DockerHttp409Error("Docker has returned an error: {} {}".format(response.status, body))
|
|
||||||
else:
|
else:
|
||||||
raise DockerError("Docker has returned an error: {} {}".format(response.status, body))
|
raise DockerError("Docker has returned an error: {} {}".format(response.status, body))
|
||||||
return response
|
return response
|
||||||
|
|||||||
@ -32,7 +32,3 @@ class DockerHttp304Error(DockerError):
|
|||||||
|
|
||||||
class DockerHttp404Error(DockerError):
|
class DockerHttp404Error(DockerError):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class DockerHttp409Error(DockerError):
|
|
||||||
pass
|
|
||||||
|
|||||||
@ -43,8 +43,7 @@ from ..nios.nio_udp import NIOUDP
|
|||||||
from .docker_error import (
|
from .docker_error import (
|
||||||
DockerError,
|
DockerError,
|
||||||
DockerHttp304Error,
|
DockerHttp304Error,
|
||||||
DockerHttp404Error,
|
DockerHttp404Error
|
||||||
DockerHttp409Error
|
|
||||||
)
|
)
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
@ -460,31 +459,10 @@ class DockerVM(BaseNode):
|
|||||||
if extra_hosts:
|
if extra_hosts:
|
||||||
params["Env"].append("GNS3_EXTRA_HOSTS={}".format(extra_hosts))
|
params["Env"].append("GNS3_EXTRA_HOSTS={}".format(extra_hosts))
|
||||||
|
|
||||||
try:
|
# Support name in Doker: [a-zA-Z0-9][a-zA-Z0-9_.-]
|
||||||
# Supported names in Docker: [a-zA-Z0-9][a-zA-Z0-9_.-]
|
result = await self.manager.query("POST", "containers/create?name={}".format(self.docker_name), data=params)
|
||||||
result = await self.manager.query("POST", f"containers/create?name={self.docker_name}", data=params)
|
self._cid = result['Id']
|
||||||
except DockerHttp409Error:
|
log.info("Docker container '{name}' [{id}] created".format(name=self._name, id=self._id))
|
||||||
# Container name already exists. This can happen when the server crashes
|
|
||||||
# and leaves containers behind. Try to remove the conflicting container.
|
|
||||||
log.warning(f"Container name '{self.docker_name}' is already in use, attempting to clean up the stale container...")
|
|
||||||
try:
|
|
||||||
# Try to get and remove the conflicting container
|
|
||||||
try:
|
|
||||||
container_info = await self.manager.query("GET", f"containers/{self.docker_name}/json")
|
|
||||||
container_id = container_info["Id"]
|
|
||||||
# Force remove the container
|
|
||||||
await self.manager.query("DELETE", f"containers/{container_id}", params={"force": 1, "v": 1})
|
|
||||||
log.info(f"Removed stale container '{self.docker_name}' ({container_id})")
|
|
||||||
except DockerHttp404Error:
|
|
||||||
# Container doesn't exist anymore, race condition - just continue
|
|
||||||
pass
|
|
||||||
# Retry creating the container
|
|
||||||
result = await self.manager.query("POST", f"containers/create?name={self.docker_name}", data=params)
|
|
||||||
except DockerError as e:
|
|
||||||
log.error(f"Failed to clean up conflicting container '{self.docker_name}': {e}")
|
|
||||||
raise
|
|
||||||
self._cid = result["Id"]
|
|
||||||
log.info(f"Docker container '{self._name}' [{self._id}] created")
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def _format_env(self, variables, env):
|
def _format_env(self, variables, env):
|
||||||
@ -869,7 +847,7 @@ class DockerVM(BaseNode):
|
|||||||
await self._fix_permissions()
|
await self._fix_permissions()
|
||||||
|
|
||||||
state = await self._get_container_state()
|
state = await self._get_container_state()
|
||||||
if state != "stopped" and state != "exited":
|
if state != "stopped" or state != "exited":
|
||||||
# t=5 number of seconds to wait before killing the container
|
# t=5 number of seconds to wait before killing the container
|
||||||
try:
|
try:
|
||||||
await self.manager.query("POST", "containers/{}/stop".format(self._cid), params={"t": 5})
|
await self.manager.query("POST", "containers/{}/stop".format(self._cid), params={"t": 5})
|
||||||
|
|||||||
@ -578,7 +578,7 @@ class IOUVM(BaseNode):
|
|||||||
callback = functools.partial(self._termination_callback, "IOU")
|
callback = functools.partial(self._termination_callback, "IOU")
|
||||||
gns3server.utils.asyncio.monitor_process(self._iou_process, callback)
|
gns3server.utils.asyncio.monitor_process(self._iou_process, callback)
|
||||||
except FileNotFoundError as e:
|
except FileNotFoundError as e:
|
||||||
raise IOUError("Could not start IOU: {}: 32-bit binary support is probably not installed, it is recommended to use a 64-bit image instead".format(e))
|
raise IOUError("Could not start IOU: {}: 32-bit binary support is probably not installed".format(e))
|
||||||
except (OSError, subprocess.SubprocessError) as e:
|
except (OSError, subprocess.SubprocessError) as e:
|
||||||
iou_stdout = self.read_iou_stdout()
|
iou_stdout = self.read_iou_stdout()
|
||||||
log.error("Could not start IOU {}: {}\n{}".format(self._path, e, iou_stdout))
|
log.error("Could not start IOU {}: {}\n{}".format(self._path, e, iou_stdout))
|
||||||
|
|||||||
@ -35,7 +35,6 @@ import time
|
|||||||
import json
|
import json
|
||||||
import psutil
|
import psutil
|
||||||
|
|
||||||
from pathlib import Path
|
|
||||||
from gns3server.utils import parse_version, shlex_quote
|
from gns3server.utils import parse_version, shlex_quote
|
||||||
from gns3server.utils.asyncio import subprocess_check_output, cancellable_wait_run_in_executor
|
from gns3server.utils.asyncio import subprocess_check_output, cancellable_wait_run_in_executor
|
||||||
from .qemu_error import QemuError
|
from .qemu_error import QemuError
|
||||||
@ -2058,23 +2057,15 @@ class QemuVM(BaseNode):
|
|||||||
options.extend(["-bios", self._bios_image.replace(",", ",,")])
|
options.extend(["-bios", self._bios_image.replace(",", ",,")])
|
||||||
|
|
||||||
elif self._uefi:
|
elif self._uefi:
|
||||||
ovmf_firmware_dir = self._manager.config.get_section_config("Qemu").get("ovmf_firmware_dir", "/usr/share/OVMF")
|
|
||||||
system_ovmf_firmware_dir = Path(ovmf_firmware_dir)
|
|
||||||
log.info("Using OVMF firmware directory: {}".format(system_ovmf_firmware_dir))
|
|
||||||
old_ovmf_vars_path = os.path.join(self.working_dir, "OVMF_VARS.fd")
|
old_ovmf_vars_path = os.path.join(self.working_dir, "OVMF_VARS.fd")
|
||||||
if os.path.exists(old_ovmf_vars_path):
|
if os.path.exists(old_ovmf_vars_path):
|
||||||
# the node has its own UEFI variables store already, we must also use the old UEFI firmware
|
# the node has its own UEFI variables store already, we must also use the old UEFI firmware
|
||||||
ovmf_firmware_path = self.manager.get_abs_image_path("OVMF_CODE.fd")
|
ovmf_firmware_path = self.manager.get_abs_image_path("OVMF_CODE.fd")
|
||||||
else:
|
else:
|
||||||
# Use a manual case-insensitive search instead
|
system_ovmf_firmware_path = "/usr/share/OVMF/OVMF_CODE_4M.fd"
|
||||||
try:
|
if os.path.exists(system_ovmf_firmware_path):
|
||||||
system_ovmf_firmware_path = next((f for f in system_ovmf_firmware_dir.glob("*.fd")
|
ovmf_firmware_path = system_ovmf_firmware_path
|
||||||
if f.name.lower() == "ovmf_code_4m.fd"), None)
|
|
||||||
except (FileNotFoundError, StopIteration):
|
|
||||||
system_ovmf_firmware_path = None
|
|
||||||
|
|
||||||
if system_ovmf_firmware_path:
|
|
||||||
ovmf_firmware_path = str(system_ovmf_firmware_path)
|
|
||||||
else:
|
else:
|
||||||
# otherwise, get the UEFI firmware from the images directory
|
# otherwise, get the UEFI firmware from the images directory
|
||||||
ovmf_firmware_path = self.manager.get_abs_image_path("OVMF_CODE_4M.fd")
|
ovmf_firmware_path = self.manager.get_abs_image_path("OVMF_CODE_4M.fd")
|
||||||
@ -2083,13 +2074,9 @@ class QemuVM(BaseNode):
|
|||||||
options.extend(["-drive", "if=pflash,format=raw,readonly,file={}".format(ovmf_firmware_path)])
|
options.extend(["-drive", "if=pflash,format=raw,readonly,file={}".format(ovmf_firmware_path)])
|
||||||
|
|
||||||
# try to use the UEFI variables store from the system first
|
# try to use the UEFI variables store from the system first
|
||||||
try:
|
system_ovmf_vars_path = "/usr/share/OVMF/OVMF_VARS_4M.fd"
|
||||||
system_ovmf_vars_path = next((f for f in system_ovmf_firmware_dir.glob("*.fd")
|
if os.path.exists(system_ovmf_vars_path):
|
||||||
if f.name.lower() == "ovmf_vars_4m.fd"), None)
|
ovmf_vars_path = system_ovmf_vars_path
|
||||||
except (FileNotFoundError, StopIteration):
|
|
||||||
system_ovmf_vars_path = None
|
|
||||||
if system_ovmf_vars_path:
|
|
||||||
ovmf_vars_path = str(system_ovmf_vars_path)
|
|
||||||
else:
|
else:
|
||||||
# otherwise, get the UEFI variables store from the images directory
|
# otherwise, get the UEFI variables store from the images directory
|
||||||
ovmf_vars_path = self.manager.get_abs_image_path("OVMF_VARS_4M.fd")
|
ovmf_vars_path = self.manager.get_abs_image_path("OVMF_VARS_4M.fd")
|
||||||
@ -2105,10 +2092,6 @@ class QemuVM(BaseNode):
|
|||||||
except OSError as e:
|
except OSError as e:
|
||||||
raise QemuError("Cannot copy OVMF_VARS_4M.fd file to the node working directory: {}".format(e))
|
raise QemuError("Cannot copy OVMF_VARS_4M.fd file to the node working directory: {}".format(e))
|
||||||
options.extend(["-drive", "if=pflash,format=raw,file={}".format(ovmf_vars_node_path)])
|
options.extend(["-drive", "if=pflash,format=raw,file={}".format(ovmf_vars_node_path)])
|
||||||
|
|
||||||
# edk2 firmware requires a Random Number Generator (RNG) device in order to turn network adapters on
|
|
||||||
options.extend(["-object", "rng-random,filename=/dev/urandom,id=rng0"])
|
|
||||||
options.extend(["-device", "virtio-rng-pci,rng=rng0"])
|
|
||||||
return options
|
return options
|
||||||
|
|
||||||
def _linux_boot_options(self):
|
def _linux_boot_options(self):
|
||||||
@ -2480,6 +2463,7 @@ class QemuVM(BaseNode):
|
|||||||
elif sys.platform.startswith("win") or sys.platform.startswith("darwin"):
|
elif sys.platform.startswith("win") or sys.platform.startswith("darwin"):
|
||||||
command.extend(["-enable-hax"])
|
command.extend(["-enable-hax"])
|
||||||
command.extend(["-boot", "order={}".format(self._boot_priority)])
|
command.extend(["-boot", "order={}".format(self._boot_priority)])
|
||||||
|
command.extend(self._bios_option())
|
||||||
command.extend(self._cdrom_option())
|
command.extend(self._cdrom_option())
|
||||||
command.extend((await self._disk_options()))
|
command.extend((await self._disk_options()))
|
||||||
command.extend(self._linux_boot_options())
|
command.extend(self._linux_boot_options())
|
||||||
@ -2497,8 +2481,6 @@ class QemuVM(BaseNode):
|
|||||||
raise QemuError("Console type {} is unknown".format(self._console_type))
|
raise QemuError("Console type {} is unknown".format(self._console_type))
|
||||||
command.extend(self._monitor_options())
|
command.extend(self._monitor_options())
|
||||||
command.extend((await self._network_options()))
|
command.extend((await self._network_options()))
|
||||||
# bios options must be last to have predictable NIC numbering, see https://github.com/GNS3/gns3-server/issues/2838
|
|
||||||
command.extend(self._bios_option())
|
|
||||||
if self.on_close != "save_vm_state":
|
if self.on_close != "save_vm_state":
|
||||||
await self._clear_save_vm_stated()
|
await self._clear_save_vm_stated()
|
||||||
else:
|
else:
|
||||||
|
|||||||
@ -562,15 +562,7 @@ class Controller:
|
|||||||
|
|
||||||
for project in self._projects.values():
|
for project in self._projects.values():
|
||||||
if project.auto_open:
|
if project.auto_open:
|
||||||
try:
|
await project.open()
|
||||||
await project.open()
|
|
||||||
except aiohttp.web.HTTPClientError as e:
|
|
||||||
details = e.text or e.reason or str(e)
|
|
||||||
log.warning(
|
|
||||||
"Failed to auto-open project '%s': %s",
|
|
||||||
project.name,
|
|
||||||
details,
|
|
||||||
)
|
|
||||||
|
|
||||||
def get_free_project_name(self, base_name):
|
def get_free_project_name(self, base_name):
|
||||||
"""
|
"""
|
||||||
|
|||||||
@ -166,52 +166,24 @@ async def import_project(
|
|||||||
project = await controller.load_project(dot_gns3_path, load=False)
|
project = await controller.load_project(dot_gns3_path, load=False)
|
||||||
return project
|
return project
|
||||||
|
|
||||||
|
|
||||||
def _create_symbolic_links(zip_file, path):
|
def _create_symbolic_links(zip_file, path):
|
||||||
"""
|
"""
|
||||||
Manually create symbolic links (if any) because ZipFile does not support it.
|
Manually create symbolic links (if any) because ZipFile does not support it.
|
||||||
Refuse any target that escapes `path`.
|
|
||||||
|
|
||||||
:param zip_file: ZipFile instance
|
:param zip_file: ZipFile instance
|
||||||
:param path: project location
|
:param path: project location
|
||||||
"""
|
"""
|
||||||
|
|
||||||
path_root = os.path.realpath(path) + os.sep
|
|
||||||
for zip_info in zip_file.infolist():
|
for zip_info in zip_file.infolist():
|
||||||
if not stat.S_ISLNK(zip_info.external_attr >> 16):
|
if stat.S_ISLNK(zip_info.external_attr >> 16):
|
||||||
continue
|
symlink_target = zip_file.read(zip_info.filename).decode()
|
||||||
symlink_target = zip_file.read(zip_info.filename).decode()
|
symlink_path = os.path.join(path, zip_info.filename)
|
||||||
symlink_path = os.path.join(path, zip_info.filename)
|
try:
|
||||||
|
# remove the regular file and replace it by a symbolic link
|
||||||
# 1. Reject absolute targets outright.
|
os.remove(symlink_path)
|
||||||
if os.path.isabs(symlink_target):
|
os.symlink(symlink_target, symlink_path)
|
||||||
raise aiohttp.web.HTTPConflict(
|
except OSError as e:
|
||||||
text=f"Symlink {zip_info.filename!r} has absolute target {symlink_target!r}, refusing"
|
raise aiohttp.web.HTTPConflict(text=f"Cannot create symbolic link: {e}")
|
||||||
)
|
|
||||||
|
|
||||||
# 2. Reject paths where the entry name itself escapes (defence in depth;
|
|
||||||
# extractall normally would already have caught this).
|
|
||||||
member_abs = os.path.realpath(symlink_path)
|
|
||||||
if not (member_abs + os.sep).startswith(path_root) and member_abs + os.sep != path_root:
|
|
||||||
raise aiohttp.web.HTTPConflict(
|
|
||||||
text=f"Symlink entry {zip_info.filename!r} escapes project dir, refusing"
|
|
||||||
)
|
|
||||||
|
|
||||||
# 3. Resolve the symlink target relative to the entry's own parent
|
|
||||||
# directory and verify the resolved real path stays inside `path`.
|
|
||||||
link_dir = os.path.realpath(os.path.dirname(symlink_path))
|
|
||||||
resolved_target = os.path.realpath(os.path.join(link_dir, symlink_target))
|
|
||||||
if not (resolved_target + os.sep).startswith(path_root) and resolved_target + os.sep != path_root:
|
|
||||||
raise aiohttp.web.HTTPConflict(
|
|
||||||
text=f"Symlink {zip_info.filename!r} -> {symlink_target!r} escapes project dir, refusing"
|
|
||||||
)
|
|
||||||
|
|
||||||
try:
|
|
||||||
os.remove(symlink_path)
|
|
||||||
os.symlink(symlink_target, symlink_path)
|
|
||||||
except OSError as e:
|
|
||||||
raise aiohttp.web.HTTPConflict(text=f"Cannot create symbolic link: {e}")
|
|
||||||
|
|
||||||
|
|
||||||
def regenerate_topology_ids(topology, new_project_path, reset_mac_addresses=False):
|
def regenerate_topology_ids(topology, new_project_path, reset_mac_addresses=False):
|
||||||
"""
|
"""
|
||||||
@ -299,7 +271,7 @@ async def _upload_file(compute, project_id, file_path, path):
|
|||||||
|
|
||||||
async def _import_images(controller, images_path):
|
async def _import_images(controller, images_path):
|
||||||
"""
|
"""
|
||||||
Copy images to the images directory or delete them if they already exist.
|
Copy images to the images directory or delete them if they already exists.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
image_dir = controller.images_path()
|
image_dir = controller.images_path()
|
||||||
@ -307,19 +279,12 @@ async def _import_images(controller, images_path):
|
|||||||
for (dirpath, dirnames, filenames) in os.walk(root, followlinks=False):
|
for (dirpath, dirnames, filenames) in os.walk(root, followlinks=False):
|
||||||
for filename in filenames:
|
for filename in filenames:
|
||||||
path = os.path.join(dirpath, filename)
|
path = os.path.join(dirpath, filename)
|
||||||
|
if os.path.islink(path):
|
||||||
|
continue
|
||||||
dst = os.path.join(image_dir, os.path.relpath(path, root))
|
dst = os.path.join(image_dir, os.path.relpath(path, root))
|
||||||
os.makedirs(os.path.dirname(dst), exist_ok=True)
|
os.makedirs(os.path.dirname(dst), exist_ok=True)
|
||||||
if not os.path.exists(dst):
|
await wait_run_in_executor(shutil.move, path, dst)
|
||||||
await wait_run_in_executor(shutil.move, path, dst)
|
|
||||||
try:
|
|
||||||
with open(dst, "rb") as f:
|
|
||||||
# read the first 7 bytes of the file.
|
|
||||||
elf_header_start = f.read(7)
|
|
||||||
# IOU images must start with the ELF magic number, be 32-bit or 64-bit, little endian and have an ELF version of 1
|
|
||||||
if elf_header_start == b'\x7fELF\x01\x01\x01' or elf_header_start == b'\x7fELF\x02\x01\x01':
|
|
||||||
os.chmod(dst, stat.S_IWRITE | stat.S_IREAD | stat.S_IEXEC)
|
|
||||||
except OSError as e:
|
|
||||||
continue
|
|
||||||
|
|
||||||
async def update_snapshots(snapshots_dir, project_path, project_name, project_id, reset_mac_addresses=True):
|
async def update_snapshots(snapshots_dir, project_path, project_name, project_id, reset_mac_addresses=True):
|
||||||
"""
|
"""
|
||||||
@ -351,7 +316,7 @@ async def update_snapshots(snapshots_dir, project_path, project_name, project_id
|
|||||||
topology = json.load(f)
|
topology = json.load(f)
|
||||||
topology["name"] = project_name
|
topology["name"] = project_name
|
||||||
topology["project_id"] = project_id
|
topology["project_id"] = project_id
|
||||||
regenerate_topology_ids(topology, tmpdir, reset_mac_addresses)
|
regenerate_topology_ids(topology, project_path, reset_mac_addresses)
|
||||||
with open(topology_file_path, "w+", encoding="utf-8") as f:
|
with open(topology_file_path, "w+", encoding="utf-8") as f:
|
||||||
json.dump(topology, f, indent=4, sort_keys=True)
|
json.dump(topology, f, indent=4, sort_keys=True)
|
||||||
except OSError as e:
|
except OSError as e:
|
||||||
|
|||||||
@ -779,9 +779,8 @@ class Project:
|
|||||||
try:
|
try:
|
||||||
with open(self._snapshot_conf_path, encoding="utf-8") as f:
|
with open(self._snapshot_conf_path, encoding="utf-8") as f:
|
||||||
self._snapshot_conf = json.load(f)
|
self._snapshot_conf = json.load(f)
|
||||||
except (OSError, UnicodeDecodeError, ValueError):
|
except (OSError, UnicodeDecodeError, ValueError) as e:
|
||||||
log.exception("Could not read snapshot config %s", self._snapshot_conf_path)
|
raise aiohttp.web.HTTPConflict(text="Could not read snapshot config {}: {}".format(self._snapshot_conf_path, str(e)))
|
||||||
raise aiohttp.web.HTTPConflict(text="Could not read snapshot configuration file")
|
|
||||||
|
|
||||||
# Load all legacy snapshots (.gns3project files) to create an initial snapshot config if it doesn't exist
|
# Load all legacy snapshots (.gns3project files) to create an initial snapshot config if it doesn't exist
|
||||||
if os.path.exists(snapshot_dir) and not self._snapshot_conf:
|
if os.path.exists(snapshot_dir) and not self._snapshot_conf:
|
||||||
@ -905,23 +904,12 @@ class Project:
|
|||||||
|
|
||||||
async def delete(self):
|
async def delete(self):
|
||||||
|
|
||||||
# Check compute connectivity before open() to avoid 120s timeout
|
|
||||||
# when remote computes are unreachable
|
|
||||||
disconnected = self._get_disconnected_computes()
|
|
||||||
if disconnected:
|
|
||||||
compute_names = ", ".join([f"'{c.name}'" for c in disconnected])
|
|
||||||
raise aiohttp.web.HTTPForbidden(
|
|
||||||
f"Cannot delete project '{self.name}': {len(disconnected)} compute(s) are disconnected: {compute_names}. "
|
|
||||||
f"Please fix the connection or delete the project manually on those computes."
|
|
||||||
)
|
|
||||||
|
|
||||||
if self._status != "opened":
|
if self._status != "opened":
|
||||||
try:
|
try:
|
||||||
await self.open(auto_start=False)
|
await self.open()
|
||||||
except aiohttp.web.HTTPConflict as e:
|
except aiohttp.web.HTTPConflict as e:
|
||||||
# ignore missing images or other conflicts when deleting a project
|
# ignore missing images or other conflicts when deleting a project
|
||||||
log.warning(f"Conflict while deleting project: {e}")
|
log.warning("Conflict while deleting project: {}".format(e.text))
|
||||||
|
|
||||||
await self.delete_on_computes()
|
await self.delete_on_computes()
|
||||||
await self.close()
|
await self.close()
|
||||||
try:
|
try:
|
||||||
@ -933,42 +921,6 @@ class Project:
|
|||||||
raise aiohttp.web.HTTPConflict(text="Cannot delete project directory {}: {}".format(self.path, str(e)))
|
raise aiohttp.web.HTTPConflict(text="Cannot delete project directory {}: {}".format(self.path, str(e)))
|
||||||
self.emit_controller_notification("project.deleted", self.__json__())
|
self.emit_controller_notification("project.deleted", self.__json__())
|
||||||
|
|
||||||
def _get_disconnected_computes(self):
|
|
||||||
"""
|
|
||||||
Check compute connectivity by reading the topology file directly,
|
|
||||||
without opening the project (which would try to connect to computes).
|
|
||||||
Returns a list of disconnected Compute objects.
|
|
||||||
"""
|
|
||||||
if self._status == "opened":
|
|
||||||
# Project is already open, use the already-loaded _computes list
|
|
||||||
compute_ids = self._computes
|
|
||||||
else:
|
|
||||||
# Read compute IDs from topology file without connecting
|
|
||||||
path = self._topology_file()
|
|
||||||
if not os.path.exists(path):
|
|
||||||
return []
|
|
||||||
try:
|
|
||||||
project_data = load_topology(path)
|
|
||||||
except (ValueError, OSError) as e:
|
|
||||||
log.warning(f"Could not read topology file for project '{self._name}': {e}")
|
|
||||||
return []
|
|
||||||
topology = project_data.get("topology", {})
|
|
||||||
compute_ids = set()
|
|
||||||
for node in topology.get("nodes", []):
|
|
||||||
compute_id = node.get("compute_id")
|
|
||||||
if compute_id:
|
|
||||||
compute_ids.add(compute_id)
|
|
||||||
|
|
||||||
disconnected = []
|
|
||||||
for compute_id in compute_ids:
|
|
||||||
try:
|
|
||||||
compute = self._controller.get_compute(compute_id)
|
|
||||||
if not compute.connected:
|
|
||||||
disconnected.append(compute)
|
|
||||||
except aiohttp.web.HTTPNotFound:
|
|
||||||
log.warning(f"Compute '{compute_id}' not found in controller")
|
|
||||||
return disconnected
|
|
||||||
|
|
||||||
async def delete_on_computes(self):
|
async def delete_on_computes(self):
|
||||||
"""
|
"""
|
||||||
Delete the project on computes but not on controller
|
Delete the project on computes but not on controller
|
||||||
@ -998,12 +950,9 @@ class Project:
|
|||||||
return os.path.join(self.path, self._filename)
|
return os.path.join(self.path, self._filename)
|
||||||
|
|
||||||
@locking
|
@locking
|
||||||
async def open(self, auto_start=True):
|
async def open(self):
|
||||||
"""
|
"""
|
||||||
Load topology elements
|
Load topology elements
|
||||||
|
|
||||||
:param auto_start: whether the nodes may be started when the project
|
|
||||||
has auto start enabled
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if self._closing:
|
if self._closing:
|
||||||
@ -1117,7 +1066,7 @@ class Project:
|
|||||||
self._loading = False
|
self._loading = False
|
||||||
self.emit_controller_notification("project.opened", self.__json__())
|
self.emit_controller_notification("project.opened", self.__json__())
|
||||||
# Should we start the nodes when project is open
|
# Should we start the nodes when project is open
|
||||||
if self._auto_start and auto_start:
|
if self._auto_start:
|
||||||
# Start all in the background without waiting for completion
|
# Start all in the background without waiting for completion
|
||||||
# we ignore errors because we want to let the user open
|
# we ignore errors because we want to let the user open
|
||||||
# their project and fix it
|
# their project and fix it
|
||||||
|
|||||||
@ -139,7 +139,7 @@ class Snapshot:
|
|||||||
# delete the current project files
|
# delete the current project files
|
||||||
project_files_path = os.path.join(self._project.path, "project-files")
|
project_files_path = os.path.join(self._project.path, "project-files")
|
||||||
if os.path.exists(project_files_path):
|
if os.path.exists(project_files_path):
|
||||||
await wait_run_in_executor(shutil.rmtree, project_files_path, ignore_errors=True)
|
await wait_run_in_executor(shutil.rmtree, project_files_path)
|
||||||
with open(self._path, "rb") as f:
|
with open(self._path, "rb") as f:
|
||||||
project = await import_project(
|
project = await import_project(
|
||||||
self._project.controller,
|
self._project.controller,
|
||||||
|
|||||||
@ -57,7 +57,7 @@ class CrashReport:
|
|||||||
Report crash to a third party service
|
Report crash to a third party service
|
||||||
"""
|
"""
|
||||||
|
|
||||||
DSN = "https://89ba0bf8d773c2c95518bfb696d6d86f@o19455.ingest.us.sentry.io/38482"
|
DSN = "https://74851857a3f05aecd909415e2a4cbd60@o19455.ingest.us.sentry.io/38482"
|
||||||
_instance = None
|
_instance = None
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
|||||||
@ -22,7 +22,6 @@ from gns3server.schemas.template import TEMPLATE_USAGE_SCHEMA
|
|||||||
|
|
||||||
import hashlib
|
import hashlib
|
||||||
import json
|
import json
|
||||||
import os
|
|
||||||
|
|
||||||
from gns3server.schemas.template import (
|
from gns3server.schemas.template import (
|
||||||
TEMPLATE_OBJECT_SCHEMA,
|
TEMPLATE_OBJECT_SCHEMA,
|
||||||
@ -174,131 +173,3 @@ class TemplateHandler:
|
|||||||
compute_id=request.json.get("compute_id"))
|
compute_id=request.json.get("compute_id"))
|
||||||
response.set_status(201)
|
response.set_status(201)
|
||||||
response.json(node)
|
response.json(node)
|
||||||
|
|
||||||
@Route.get(
|
|
||||||
r"/templates/{template_id}/base-config/{filename}",
|
|
||||||
description="Get base configuration file content",
|
|
||||||
)
|
|
||||||
def get_base_config(request, response):
|
|
||||||
|
|
||||||
controller = Controller.instance()
|
|
||||||
|
|
||||||
template_id = request.match_info["template_id"]
|
|
||||||
|
|
||||||
template = controller.template_manager.get_template(template_id)
|
|
||||||
|
|
||||||
filename = os.path.basename(request.match_info["filename"])
|
|
||||||
|
|
||||||
path = os.path.join(controller.configs_path(), filename)
|
|
||||||
|
|
||||||
try:
|
|
||||||
if not os.path.exists(path):
|
|
||||||
response.set_status(404)
|
|
||||||
response.json({"message": "File not found"})
|
|
||||||
return
|
|
||||||
|
|
||||||
with open(path, encoding="utf-8", errors="ignore") as f:
|
|
||||||
content = f.read()
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
response.set_status(500)
|
|
||||||
response.json({"message": str(e)})
|
|
||||||
return
|
|
||||||
|
|
||||||
response.set_status(200)
|
|
||||||
response.json({
|
|
||||||
"template_id": template.id,
|
|
||||||
"filename": filename,
|
|
||||||
"content": content
|
|
||||||
})
|
|
||||||
|
|
||||||
@Route.put(
|
|
||||||
r"/templates/{template_id}/base-config/{filename}",
|
|
||||||
description="Update base configuration file content",
|
|
||||||
parameters={
|
|
||||||
"template_id": "Template UUID",
|
|
||||||
"filename": "Base config filename"
|
|
||||||
},
|
|
||||||
status_codes={
|
|
||||||
200: "File updated",
|
|
||||||
400: "Invalid request",
|
|
||||||
404: "Template or file not found"
|
|
||||||
},
|
|
||||||
)
|
|
||||||
def update_base_config(request, response):
|
|
||||||
|
|
||||||
controller = Controller.instance()
|
|
||||||
|
|
||||||
template_id = request.match_info["template_id"]
|
|
||||||
filename = os.path.basename(request.match_info["filename"])
|
|
||||||
|
|
||||||
try:
|
|
||||||
template = controller.template_manager.get_template(template_id)
|
|
||||||
except Exception:
|
|
||||||
response.set_status(404)
|
|
||||||
response.json({"message": "Template not found"})
|
|
||||||
return
|
|
||||||
|
|
||||||
path = os.path.join(controller.configs_path(), filename)
|
|
||||||
|
|
||||||
body = request.json
|
|
||||||
|
|
||||||
if not body or "content" not in body:
|
|
||||||
response.set_status(400)
|
|
||||||
response.json({"message": "Missing 'content' field"})
|
|
||||||
return
|
|
||||||
|
|
||||||
content = body["content"]
|
|
||||||
|
|
||||||
try:
|
|
||||||
os.makedirs(controller.configs_path(), exist_ok=True)
|
|
||||||
|
|
||||||
with open(path, "w", encoding="utf-8") as f:
|
|
||||||
f.write(content)
|
|
||||||
|
|
||||||
except OSError as e:
|
|
||||||
response.set_status(500)
|
|
||||||
response.json({"message": str(e)})
|
|
||||||
return
|
|
||||||
|
|
||||||
response.set_status(200)
|
|
||||||
response.json({
|
|
||||||
"template_id": template.id,
|
|
||||||
"filename": filename,
|
|
||||||
"content": content
|
|
||||||
})
|
|
||||||
|
|
||||||
@Route.get(
|
|
||||||
r"/templates/base-configs",
|
|
||||||
description="List all available base configuration files",
|
|
||||||
status_codes={
|
|
||||||
200: "List of base configuration files returned"
|
|
||||||
}
|
|
||||||
)
|
|
||||||
def list_base_configs(request, response):
|
|
||||||
|
|
||||||
controller = Controller.instance()
|
|
||||||
|
|
||||||
configs_path = controller.configs_path()
|
|
||||||
|
|
||||||
try:
|
|
||||||
files = []
|
|
||||||
|
|
||||||
if os.path.exists(configs_path):
|
|
||||||
for filename in os.listdir(configs_path):
|
|
||||||
|
|
||||||
path = os.path.join(configs_path, filename)
|
|
||||||
|
|
||||||
if os.path.isfile(path):
|
|
||||||
files.append({"filename": filename})
|
|
||||||
|
|
||||||
except OSError as e:
|
|
||||||
response.set_status(500)
|
|
||||||
response.json({
|
|
||||||
"message": str(e)
|
|
||||||
})
|
|
||||||
return
|
|
||||||
|
|
||||||
files = sorted(files, key=lambda x: x["filename"])
|
|
||||||
response.set_status(200)
|
|
||||||
response.json(files)
|
|
||||||
|
|||||||
@ -215,32 +215,18 @@ class AsyncioTelnetServer:
|
|||||||
await self._write_intro(network_writer, echo=self._echo, binary=self._binary, naws=self._naws)
|
await self._write_intro(network_writer, echo=self._echo, binary=self._binary, naws=self._naws)
|
||||||
await connection.connected()
|
await connection.connected()
|
||||||
await self._process(network_reader, network_writer, connection)
|
await self._process(network_reader, network_writer, connection)
|
||||||
except (ConnectionError, OSError, asyncio.CancelledError):
|
except (ConnectionError, OSError):
|
||||||
pass
|
|
||||||
except Exception:
|
|
||||||
# Catch any unexpected exception so the cleanup below still runs.
|
|
||||||
# Without the try/finally, an uncaught exception here would leave
|
|
||||||
# _reader_process pinned to a dead reader, and subsequent client
|
|
||||||
# connections would see _get_reader() return None and never
|
|
||||||
# receive node output -- the "silent proxy" hang (issue #2344).
|
|
||||||
log.exception("Unexpected error in telnet proxy; cleaning up client connection...")
|
|
||||||
finally:
|
|
||||||
async with self._lock:
|
async with self._lock:
|
||||||
try:
|
network_writer.close()
|
||||||
network_writer.close()
|
# await network_writer.wait_closed() # this doesn't work in Python 3.6
|
||||||
finally:
|
if self._reader_process == network_reader:
|
||||||
if self._reader_process == network_reader:
|
self._reader_process = None
|
||||||
self._reader_process = None
|
# Cancel current read from this reader
|
||||||
# Cancel current read from this reader
|
if self._current_read is not None:
|
||||||
if self._current_read is not None:
|
self._current_read.cancel()
|
||||||
self._current_read.cancel()
|
|
||||||
self._current_read = None
|
await connection.disconnected()
|
||||||
try:
|
del self._connections[network_writer]
|
||||||
await connection.disconnected()
|
|
||||||
finally:
|
|
||||||
# Use pop() to avoid KeyError if connection was already removed
|
|
||||||
# elsewhere (e.g. by the broadcast loop's timeout handler)
|
|
||||||
self._connections.pop(network_writer, None)
|
|
||||||
|
|
||||||
async def close(self):
|
async def close(self):
|
||||||
for writer, connection in self._connections.items():
|
for writer, connection in self._connections.items():
|
||||||
@ -332,7 +318,7 @@ class AsyncioTelnetServer:
|
|||||||
except (OSError, ConnectionError, asyncio.TimeoutError) as e:
|
except (OSError, ConnectionError, asyncio.TimeoutError) as e:
|
||||||
log.debug(f"Error sending data to client {client_info}: {e}, closing and removing from connection table.")
|
log.debug(f"Error sending data to client {client_info}: {e}, closing and removing from connection table.")
|
||||||
connection.close()
|
connection.close()
|
||||||
self._connections.pop(connection_key, None)
|
del self._connections[connection_key]
|
||||||
|
|
||||||
async def _read(self, cmd, buffer, location, reader):
|
async def _read(self, cmd, buffer, location, reader):
|
||||||
""" Reads next op from the buffer or reader"""
|
""" Reads next op from the buffer or reader"""
|
||||||
|
|||||||
@ -147,7 +147,7 @@ def is_interface_up(interface):
|
|||||||
:returns: boolean
|
:returns: boolean
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if sys.platform.startswith("linux") or sys.platform.startswith("openbsd"):
|
if sys.platform.startswith("linux"):
|
||||||
|
|
||||||
if interface not in psutil.net_if_addrs():
|
if interface not in psutil.net_if_addrs():
|
||||||
return False
|
return False
|
||||||
@ -234,7 +234,7 @@ def interfaces():
|
|||||||
result["special"] = False
|
result["special"] = False
|
||||||
for special_interface in ("lo", "vmnet", "vboxnet", "docker", "lxcbr",
|
for special_interface in ("lo", "vmnet", "vboxnet", "docker", "lxcbr",
|
||||||
"virbr", "ovs-system", "veth", "fw", "p2p",
|
"virbr", "ovs-system", "veth", "fw", "p2p",
|
||||||
"bridge", "vmware", "virtualbox", "gns3","veb"):
|
"bridge", "vmware", "virtualbox", "gns3"):
|
||||||
if result["name"].lower().startswith(special_interface):
|
if result["name"].lower().startswith(special_interface):
|
||||||
result["special"] = True
|
result["special"] = True
|
||||||
for special_interface in ("-nic"):
|
for special_interface in ("-nic"):
|
||||||
|
|||||||
@ -23,8 +23,8 @@
|
|||||||
# or negative for a release candidate or beta (after the base version
|
# or negative for a release candidate or beta (after the base version
|
||||||
# number has been incremented)
|
# number has been incremented)
|
||||||
|
|
||||||
__version__ = "2.2.61"
|
__version__ = "2.2.58"
|
||||||
__version_info__ = (2, 2, 61, 0)
|
__version_info__ = (2, 2, 58, 0)
|
||||||
|
|
||||||
if "dev" in __version__:
|
if "dev" in __version__:
|
||||||
try:
|
try:
|
||||||
|
|||||||
@ -1,11 +1,10 @@
|
|||||||
jsonschema==4.25.1; python_version == '3.9' # version 4.25.1 is the last to support Python 3.9
|
jsonschema>=4.25.1,<4.26 # version 4.25.1 is the last to support Python 3.9
|
||||||
jsonschema>=4.26.0,<4.27; python_version >= '3.10'
|
aiohttp>=3.13.3,<3.14
|
||||||
aiohttp>=3.13.5,<3.14
|
|
||||||
aiohttp-cors>=0.8.1,<0.9
|
aiohttp-cors>=0.8.1,<0.9
|
||||||
aiofiles>=25.1.0,<26.0
|
aiofiles>=25.1.0,<26.0
|
||||||
Jinja2>=3.1.6,<3.2
|
Jinja2>=3.1.6,<3.2
|
||||||
sentry-sdk>=2.59.0,<3 # optional dependency
|
sentry-sdk>=2.50.0,<3 # optional dependency
|
||||||
psutil>=7.2.2
|
psutil>=7.2.1
|
||||||
async-timeout>=5.0.1,<5.1 # this library has effectively been upstreamed into Python 3.11+
|
async-timeout>=5.0.1,<5.1 # this library has effectively been upstreamed into Python 3.11+
|
||||||
distro>=1.9.0
|
distro>=1.9.0
|
||||||
py-cpuinfo>=9.0.0,<10.0
|
py-cpuinfo>=9.0.0,<10.0
|
||||||
|
|||||||
2
setup.py
2
setup.py
@ -64,7 +64,7 @@ setup(
|
|||||||
include_package_data=True,
|
include_package_data=True,
|
||||||
zip_safe=False,
|
zip_safe=False,
|
||||||
platforms="any",
|
platforms="any",
|
||||||
python_requires=">=3.9",
|
python_requires=">=3.8",
|
||||||
setup_requires=["setuptools>=45.2"],
|
setup_requires=["setuptools>=45.2"],
|
||||||
classifiers=[
|
classifiers=[
|
||||||
"Development Status :: 5 - Production/Stable",
|
"Development Status :: 5 - Production/Stable",
|
||||||
|
|||||||
@ -1503,19 +1503,3 @@ async def test_read_console_output_with_binary_mode(vm):
|
|||||||
with asyncio_patch('gns3server.compute.docker.docker_vm.DockerVM.stop'):
|
with asyncio_patch('gns3server.compute.docker.docker_vm.DockerVM.stop'):
|
||||||
await vm._read_console_output(input_stream, output_stream)
|
await vm._read_console_output(input_stream, output_stream)
|
||||||
output_stream.feed_data.assert_called_once_with(b"test")
|
output_stream.feed_data.assert_called_once_with(b"test")
|
||||||
|
|
||||||
|
|
||||||
async def test_stop_exited_container_no_stop_query(vm):
|
|
||||||
|
|
||||||
vm._ubridge_hypervisor = None
|
|
||||||
vm._fix_permissions = MagicMock()
|
|
||||||
|
|
||||||
with asyncio_patch("gns3server.compute.docker.DockerVM._get_container_state", return_value="exited"):
|
|
||||||
with asyncio_patch("gns3server.compute.docker.Docker.query") as mock_query:
|
|
||||||
vm._permissions_fixed = False
|
|
||||||
await vm.stop()
|
|
||||||
assert not any(
|
|
||||||
call.args[:2] == ("POST", "containers/e90e34656842/stop")
|
|
||||||
for call in mock_query.mock_calls
|
|
||||||
)
|
|
||||||
assert vm.status == "stopped"
|
|
||||||
|
|||||||
@ -19,8 +19,6 @@ import os
|
|||||||
import uuid
|
import uuid
|
||||||
import json
|
import json
|
||||||
import zipfile
|
import zipfile
|
||||||
import pytest
|
|
||||||
import aiohttp
|
|
||||||
|
|
||||||
from tests.utils import asyncio_patch, AsyncioMagicMock
|
from tests.utils import asyncio_patch, AsyncioMagicMock
|
||||||
from unittest.mock import patch, MagicMock
|
from unittest.mock import patch, MagicMock
|
||||||
@ -119,48 +117,36 @@ async def write_file(path, z):
|
|||||||
f.write(chunk)
|
f.write(chunk)
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
async def test_import_project_containing_symlink(tmpdir, controller):
|
||||||
def export_project_with_symlink(tmpdir, controller):
|
|
||||||
async def _export(symlink_target):
|
|
||||||
project = Project(controller=controller, name="test")
|
|
||||||
project.dump = MagicMock()
|
|
||||||
|
|
||||||
topology = {
|
project = Project(controller=controller, name="test")
|
||||||
"project_id": str(uuid.uuid4()),
|
project.dump = MagicMock()
|
||||||
"name": "test",
|
path = project.path
|
||||||
"auto_open": True,
|
|
||||||
"auto_start": True,
|
|
||||||
"topology": {
|
|
||||||
},
|
|
||||||
"version": "2.0.0"
|
|
||||||
}
|
|
||||||
|
|
||||||
with open(os.path.join(project.path, "project.gns3"), 'w+') as f:
|
|
||||||
json.dump(topology, f)
|
|
||||||
|
|
||||||
os.makedirs(os.path.join(project.path, "vm1", "dynamips"))
|
|
||||||
symlink_path = os.path.join(project.path, "vm1", "dynamips", "symlink")
|
|
||||||
os.symlink(symlink_target, symlink_path)
|
|
||||||
|
|
||||||
zip_path = str(tmpdir / "project.zip")
|
|
||||||
with aiozipstream.ZipFile() as z:
|
|
||||||
with patch("gns3server.compute.Dynamips.get_images_directory", return_value=str(tmpdir / "IOS"),):
|
|
||||||
await export_project(z, project, str(tmpdir), include_images=False)
|
|
||||||
await write_file(zip_path, z)
|
|
||||||
|
|
||||||
return zip_path
|
|
||||||
|
|
||||||
return _export
|
|
||||||
|
|
||||||
|
|
||||||
async def test_import_project_containing_symlink(controller, export_project_with_symlink):
|
|
||||||
"""
|
|
||||||
Test importing a project containing a valid symlink (target inside the project directory).
|
|
||||||
"""
|
|
||||||
|
|
||||||
project_id = str(uuid.uuid4())
|
project_id = str(uuid.uuid4())
|
||||||
symlink_target = "../symlink_target"
|
topology = {
|
||||||
zip_path = await export_project_with_symlink(symlink_target)
|
"project_id": str(uuid.uuid4()),
|
||||||
|
"name": "test",
|
||||||
|
"auto_open": True,
|
||||||
|
"auto_start": True,
|
||||||
|
"topology": {
|
||||||
|
},
|
||||||
|
"version": "2.0.0"
|
||||||
|
}
|
||||||
|
|
||||||
|
with open(os.path.join(path, "project.gns3"), 'w+') as f:
|
||||||
|
json.dump(topology, f)
|
||||||
|
|
||||||
|
os.makedirs(os.path.join(path, "vm1", "dynamips"))
|
||||||
|
symlink_path = os.path.join(project.path, "vm1", "dynamips", "symlink")
|
||||||
|
symlink_target = "/tmp/anywhere"
|
||||||
|
os.symlink(symlink_target, symlink_path)
|
||||||
|
|
||||||
|
zip_path = str(tmpdir / "project.zip")
|
||||||
|
with aiozipstream.ZipFile() as z:
|
||||||
|
with patch("gns3server.compute.Dynamips.get_images_directory", return_value=str(tmpdir / "IOS"),):
|
||||||
|
await export_project(z, project, str(tmpdir), include_images=False)
|
||||||
|
await write_file(zip_path, z)
|
||||||
|
|
||||||
with open(zip_path, "rb") as f:
|
with open(zip_path, "rb") as f:
|
||||||
project = await import_project(controller, project_id, f)
|
project = await import_project(controller, project_id, f)
|
||||||
@ -172,36 +158,6 @@ async def test_import_project_containing_symlink(controller, export_project_with
|
|||||||
assert os.readlink(symlink_path) == symlink_target
|
assert os.readlink(symlink_path) == symlink_target
|
||||||
|
|
||||||
|
|
||||||
async def test_import_project_containing_absolute_symlink(controller, export_project_with_symlink):
|
|
||||||
"""
|
|
||||||
Test importing a project containing an absolute symlink.
|
|
||||||
This should fail because absolute symlinks are not allowed for security reasons.
|
|
||||||
"""
|
|
||||||
|
|
||||||
project_id = str(uuid.uuid4())
|
|
||||||
symlink_target = "/tmp/anywhere"
|
|
||||||
zip_path = await export_project_with_symlink(symlink_target)
|
|
||||||
|
|
||||||
with pytest.raises(aiohttp.web.HTTPConflict):
|
|
||||||
with open(zip_path, "rb") as f:
|
|
||||||
await import_project(controller, project_id, f)
|
|
||||||
|
|
||||||
|
|
||||||
async def test_import_project_containing_escaping_symlink(controller, export_project_with_symlink):
|
|
||||||
"""
|
|
||||||
Test importing a project containing a symlink that escapes the project directory.
|
|
||||||
This should fail because symlinks that escape the project directory are not allowed for security reasons.
|
|
||||||
"""
|
|
||||||
|
|
||||||
project_id = str(uuid.uuid4())
|
|
||||||
symlink_target = "../../../../symlink_target"
|
|
||||||
zip_path = await export_project_with_symlink(symlink_target)
|
|
||||||
|
|
||||||
with pytest.raises(aiohttp.web.HTTPConflict):
|
|
||||||
with open(zip_path, "rb") as f:
|
|
||||||
await import_project(controller, project_id, f)
|
|
||||||
|
|
||||||
|
|
||||||
async def test_import_upgrade(tmpdir, controller):
|
async def test_import_upgrade(tmpdir, controller):
|
||||||
"""
|
"""
|
||||||
Topology made for previous GNS3 version are upgraded during the process
|
Topology made for previous GNS3 version are upgraded during the process
|
||||||
|
|||||||
@ -655,19 +655,6 @@ async def test_delete(project):
|
|||||||
assert not os.path.exists(project.path)
|
assert not os.path.exists(project.path)
|
||||||
|
|
||||||
|
|
||||||
async def test_delete_does_not_start_nodes(project):
|
|
||||||
"""
|
|
||||||
Deleting a project must not start its nodes, even when auto_start is enabled.
|
|
||||||
"""
|
|
||||||
|
|
||||||
project.auto_start = True
|
|
||||||
project.dump()
|
|
||||||
await project.close()
|
|
||||||
project.start_all = AsyncioMagicMock()
|
|
||||||
await project.delete()
|
|
||||||
assert not project.start_all.called
|
|
||||||
|
|
||||||
|
|
||||||
async def test_dump(projects_dir):
|
async def test_dump(projects_dir):
|
||||||
|
|
||||||
directory = projects_dir
|
directory = projects_dir
|
||||||
|
|||||||
@ -14,7 +14,8 @@
|
|||||||
#
|
#
|
||||||
# You should have received a copy of the GNU General Public License
|
# You should have received a copy of the GNU General Public License
|
||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
import os
|
|
||||||
|
|
||||||
import uuid
|
import uuid
|
||||||
|
|
||||||
from tests.utils import asyncio_patch
|
from tests.utils import asyncio_patch
|
||||||
@ -954,81 +955,3 @@ async def test_create_node_from_template(controller_api, controller, project):
|
|||||||
mock.assert_called_with(id, x=42, y=12, name=None, compute_id=None)
|
mock.assert_called_with(id, x=42, y=12, name=None, compute_id=None)
|
||||||
assert response.route == "/projects/{project_id}/templates/{template_id}"
|
assert response.route == "/projects/{project_id}/templates/{template_id}"
|
||||||
assert response.status == 201
|
assert response.status == 201
|
||||||
|
|
||||||
|
|
||||||
async def test_get_base_config(controller_api, controller):
|
|
||||||
|
|
||||||
template_id = str(uuid.uuid4())
|
|
||||||
|
|
||||||
controller.template_manager._templates[template_id] = Template(template_id, {
|
|
||||||
"template_type": "vpcs",
|
|
||||||
"category": 0,
|
|
||||||
"name": "test",
|
|
||||||
"symbol": "guest.svg",
|
|
||||||
"default_name_format": "{name}-{0}",
|
|
||||||
"compute_id": "local"
|
|
||||||
})
|
|
||||||
|
|
||||||
config_path = os.path.join(controller.configs_path(), "test_config.txt")
|
|
||||||
|
|
||||||
with open(config_path, "w") as f:
|
|
||||||
f.write("hello config")
|
|
||||||
|
|
||||||
response = await controller_api.get(
|
|
||||||
f"/templates/{template_id}/base-config/test_config.txt"
|
|
||||||
)
|
|
||||||
|
|
||||||
assert response.status == 200
|
|
||||||
assert response.json["filename"] == "test_config.txt"
|
|
||||||
assert response.json["content"] == "hello config"
|
|
||||||
|
|
||||||
async def test_update_base_config(controller_api, controller):
|
|
||||||
|
|
||||||
template_id = str(uuid.uuid4())
|
|
||||||
|
|
||||||
controller.template_manager._templates[template_id] = Template(template_id, {
|
|
||||||
"template_type": "vpcs",
|
|
||||||
"category": 0,
|
|
||||||
"name": "test",
|
|
||||||
"symbol": "guest.svg",
|
|
||||||
"default_name_format": "{name}-{0}",
|
|
||||||
"compute_id": "local"
|
|
||||||
})
|
|
||||||
|
|
||||||
config_path = os.path.join(controller.configs_path(), "update_test.txt")
|
|
||||||
|
|
||||||
with open(config_path, "w") as f:
|
|
||||||
f.write("old content")
|
|
||||||
|
|
||||||
response = await controller_api.put(
|
|
||||||
f"/templates/{template_id}/base-config/update_test.txt",
|
|
||||||
{
|
|
||||||
"content": "new updated content"
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
assert response.status == 200
|
|
||||||
assert response.json["content"] == "new updated content"
|
|
||||||
|
|
||||||
with open(config_path) as f:
|
|
||||||
assert f.read() == "new updated content"
|
|
||||||
|
|
||||||
async def test_list_base_configs(controller_api, controller):
|
|
||||||
|
|
||||||
config1 = os.path.join(controller.configs_path(), "config1.txt")
|
|
||||||
config2 = os.path.join(controller.configs_path(), "config2.txt")
|
|
||||||
|
|
||||||
with open(config1, "w") as f:
|
|
||||||
f.write("test1")
|
|
||||||
|
|
||||||
with open(config2, "w") as f:
|
|
||||||
f.write("test2")
|
|
||||||
|
|
||||||
response = await controller_api.get("/templates/base-configs")
|
|
||||||
|
|
||||||
assert response.status == 200
|
|
||||||
|
|
||||||
filenames = [item["filename"] for item in response.json]
|
|
||||||
|
|
||||||
assert "config1.txt" in filenames
|
|
||||||
assert "config2.txt" in filenames
|
|
||||||
Loading…
x
Reference in New Issue
Block a user