mirror of
https://github.com/GNS3/gns3-server.git
synced 2026-08-27 12:30:13 +03:00
Merge remote-tracking branch 'origin/2.2' into 3.0
# Conflicts: # .github/workflows/testing.yml # CHANGELOG # README.md # gns3server/appliances/infix.gns3a # gns3server/compute/docker/__init__.py # gns3server/compute/docker/docker_vm.py # gns3server/crash_report.py # gns3server/version.py # gns3server/web/web_server.py # setup.py # tests/controller/test_project.py
This commit is contained in:
commit
60c10e7ecc
40
.github/workflows/docker-build.yml
vendored
Normal file
40
.github/workflows/docker-build.yml
vendored
Normal file
@ -0,0 +1,40 @@
|
||||
name: Build and Push Docker Image
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
push:
|
||||
tags:
|
||||
- v2.*
|
||||
- v3.*
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Login to GitHub Container Registry
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.repository_owner }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Login to Docker Hub
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: docker.io
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
|
||||
- name: Build and push to GitHub Container Registry
|
||||
run: |
|
||||
docker build -t ghcr.io/$(echo "${{ github.repository }}" | tr '[:upper:]' '[:lower:]'):latest .
|
||||
docker push ghcr.io/$(echo "${{ github.repository }}" | tr '[:upper:]' '[:lower:]'):latest
|
||||
|
||||
- name: Build and push to Docker Hub
|
||||
run: |
|
||||
docker build -t gns3/${{ github.event.repository.name }}:latest .
|
||||
docker push gns3/${{ github.event.repository.name }}:latest
|
||||
2
.github/workflows/testing.yml
vendored
2
.github/workflows/testing.yml
vendored
@ -18,7 +18,7 @@ jobs:
|
||||
strategy:
|
||||
matrix:
|
||||
os: ["ubuntu-latest"]
|
||||
python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"]
|
||||
python-version: ["3.8", "3.9", "3.10", "3.11", "3.12", "3.13", "3.14"]
|
||||
#include:
|
||||
# only test with Python 3.10 on Windows
|
||||
# - os: windows-latest
|
||||
|
||||
13
CHANGELOG
13
CHANGELOG
@ -1,5 +1,18 @@
|
||||
# Change Log
|
||||
|
||||
## 2.2.55 19/11/2025
|
||||
|
||||
* Docker API version requirements and process to handle older daemons
|
||||
* Use docker_name property when creating a container
|
||||
* Set name of container in Docker
|
||||
* Support for Python 3.14
|
||||
* Enable ip cef in IOU L2 and IOU L3 base configs
|
||||
* Only build and push Docker image when releasing a new version
|
||||
* Fix pushing Docker image to Docker hub
|
||||
* Update security issues in README.md. Fixes #2535
|
||||
* Add missing 'nat' template type in schema. Fixes #2529
|
||||
* Resolve deprecation warnings of regex library
|
||||
|
||||
## 3.0.5 14/05/2025
|
||||
|
||||
* Bundle web-ui v3.0.5
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
"vendor_name": "Asterfusion",
|
||||
"vendor_url": "https://cloudswit.ch/",
|
||||
"vendor_logo_url": "https://raw.githubusercontent.com/GNS3/gns3-registry/master/vendor-logos/asterfusion.png",
|
||||
"documentation_url": "https://help.cloudswit.ch/portal/en/kb/articles/vasternos",
|
||||
"documentation_url": "https://asternos.com/community/space/vasternos/post/vasternos-for-data-center-network",
|
||||
"product_name": "vAsterNOS",
|
||||
"product_url": "https://cloudswit.ch/product/sonic-enterprise-distribution",
|
||||
"registry_version": 4,
|
||||
@ -30,18 +30,18 @@
|
||||
},
|
||||
"images": [
|
||||
{
|
||||
"filename": "vAsterNOS-V3.1.img",
|
||||
"filename": "AsterNOS_V3.1_R0408P01-VS.img.gz",
|
||||
"version": "V3.1",
|
||||
"md5sum": "c323c9c3f60e1a93eca2acdc5034b85c",
|
||||
"filesize": 2724659200,
|
||||
"download_url": "https://drive.cloudswitch.io/external/8ae2e3932ad8bb2ec30dd25be415d288ff3e4a949c557c6bd48ac6e6265bcfc1"
|
||||
"md5sum": "5c182306af67be2c79a5642551412e48",
|
||||
"filesize": 1425945924,
|
||||
"download_url": "http://pub.asternos.com/AsterNOS_V3.1_R0408P01-VS.img.gz"
|
||||
}
|
||||
],
|
||||
"versions": [
|
||||
{
|
||||
"name": "V3.1",
|
||||
"images": {
|
||||
"hda_disk_image": "vAsterNOS-V3.1.img"
|
||||
"hda_disk_image": "AsterNOS_V3.1_R0408P01-VS.img.gz"
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
@ -50,6 +50,12 @@
|
||||
"version": "124-25G",
|
||||
"md5sum": "9c7cc9b3f3b3571411a7f62faaa2c036",
|
||||
"filesize": 71528984
|
||||
},
|
||||
{
|
||||
"filename": "c7200-itpk9-mz.124-15.SW.image",
|
||||
"version": "124-15.SW",
|
||||
"md5sum": "3334a0facdbd26164e83d3c201fff5b5",
|
||||
"filesize": 46423952
|
||||
}
|
||||
],
|
||||
"versions": [
|
||||
@ -87,6 +93,13 @@
|
||||
"images": {
|
||||
"image": "c7200-a3jk9s-mz.124-25g.image"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "124-15.SW",
|
||||
"idlepc": "0x60b2bc68",
|
||||
"images": {
|
||||
"image": "c7200-itpk9-mz.124-15.SW.image"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@ -28,6 +28,13 @@
|
||||
"options": "-nographic"
|
||||
},
|
||||
"images": [
|
||||
{
|
||||
"filename": "FEGNS3.9.3.0.0.qcow2",
|
||||
"version": "v9.3.0.0",
|
||||
"md5sum": "2abfa8d64219aa75522238f87b782726",
|
||||
"filesize": 490209280,
|
||||
"direct_download_url": "https://akamai-ep.extremenetworks.com/Extreme_P/github-en/Virtual_VOSS/FEGNS3.9.3.0.0.qcow2"
|
||||
},
|
||||
{
|
||||
"filename": "VOSSGNS3.8.10.1.0.qcow2",
|
||||
"version": "v8.10.1.0",
|
||||
@ -93,6 +100,13 @@
|
||||
}
|
||||
],
|
||||
"versions": [
|
||||
{
|
||||
"name": "v9.3.0.0",
|
||||
"images":
|
||||
{
|
||||
"hda_disk_image": "FEGNS3.9.3.0.0.qcow2"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "v8.10.1.0",
|
||||
"images":
|
||||
|
||||
@ -25,19 +25,19 @@
|
||||
},
|
||||
"images": [
|
||||
{
|
||||
"filename": "rtr.qcow2",
|
||||
"version": "20.7.1",
|
||||
"md5sum": "4707415d15d20ced92423d90e52eedcd",
|
||||
"filesize": 254767616,
|
||||
"download_url": "http://freerouter.nop.hu/",
|
||||
"direct_download_url": "http://dl.nop.hu/rtr.qcow2"
|
||||
"filename": "rtr-x86_64.qcow2",
|
||||
"version": "25.8.29",
|
||||
"md5sum": "13d72fdfd772258808a9d4b75fa67083",
|
||||
"filesize": 73269248,
|
||||
"download_url": "http://www.freertr.org/",
|
||||
"direct_download_url": "http://dl.nop.hu/rtr-x86_64.qcow2"
|
||||
}
|
||||
],
|
||||
"versions": [
|
||||
{
|
||||
"name": "20.7.1",
|
||||
"name": "25.8.29",
|
||||
"images": {
|
||||
"hda_disk_image": "rtr.qcow2"
|
||||
"hda_disk_image": "rtr-x86_64.qcow2"
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
@ -23,6 +23,15 @@
|
||||
"kvm": "allow"
|
||||
},
|
||||
"images": [
|
||||
{
|
||||
"filename": "openwrt-24.10.2-x86-64-generic-ext4-combined.img",
|
||||
"version": "24.10.2",
|
||||
"md5sum": "0769916238524161b0a9a639ae261381",
|
||||
"filesize": 126353408,
|
||||
"download_url": "https://downloads.openwrt.org/releases/24.10.2/targets/x86/64/",
|
||||
"direct_download_url": "https://downloads.openwrt.org/releases/24.10.2/targets/x86/64/openwrt-24.10.2-x86-64-generic-ext4-combined.img.gz",
|
||||
"compression": "gzip"
|
||||
},
|
||||
{
|
||||
"filename": "openwrt-23.05.0-x86-64-generic-ext4-combined.img",
|
||||
"version": "23.05.0",
|
||||
@ -223,7 +232,13 @@
|
||||
}
|
||||
],
|
||||
"versions": [
|
||||
{
|
||||
{
|
||||
"name": "24.10.2",
|
||||
"images": {
|
||||
"hda_disk_image": "openwrt-24.10.2-x86-64-generic-ext4-combined.img"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "23.05.0",
|
||||
"images": {
|
||||
"hda_disk_image": "openwrt-23.05.0-x86-64-generic-ext4-combined.img"
|
||||
|
||||
@ -25,6 +25,20 @@
|
||||
"kvm": "require"
|
||||
},
|
||||
"images": [
|
||||
{
|
||||
"filename": "OPNsense-25.7-nano-amd64.img",
|
||||
"version": "25.7",
|
||||
"md5sum": "07aa8b44ebc57fa9ca0145f777901a59",
|
||||
"filesize": 3221225472,
|
||||
"download_url": "https://opnsense.c0urier.net/releases/25.7/"
|
||||
},
|
||||
{
|
||||
"filename": "OPNsense-25.1-nano-amd64.img",
|
||||
"version": "25.1",
|
||||
"md5sum": "9c119e4fed7dd7c1c162d8be4088d983",
|
||||
"filesize": 3221225472,
|
||||
"download_url": "https://opnsense.c0urier.net/releases/25.1/"
|
||||
},
|
||||
{
|
||||
"filename": "OPNsense-24.7-nano-amd64.img",
|
||||
"version": "24.7",
|
||||
|
||||
@ -30,6 +30,20 @@
|
||||
"on_close": "shutdown_signal"
|
||||
},
|
||||
"images": [
|
||||
{
|
||||
"filename": "vyos-1.4.3-kvm-amd64.qcow2",
|
||||
"version": "1.4.3",
|
||||
"md5sum": "4eec0ba2ec367bbbdf2d2f212f947746",
|
||||
"filesize": 515047424,
|
||||
"download_url": "https://support.vyos.io/"
|
||||
},
|
||||
{
|
||||
"filename": "vyos-1.4.2-kvm-amd64.qcow2",
|
||||
"version": "1.4.2",
|
||||
"md5sum": "78c5935e05a7bbd94a639fcee18f5799",
|
||||
"filesize": 514064384,
|
||||
"download_url": "https://support.vyos.io/"
|
||||
},
|
||||
{
|
||||
"filename": "vyos-1.4.1-kvm-amd64.qcow2",
|
||||
"version": "1.4.1",
|
||||
@ -116,6 +130,18 @@
|
||||
}
|
||||
],
|
||||
"versions": [
|
||||
{
|
||||
"name": "1.4.3",
|
||||
"images": {
|
||||
"hda_disk_image": "vyos-1.4.3-kvm-amd64.qcow2"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "1.4.2",
|
||||
"images": {
|
||||
"hda_disk_image": "vyos-1.4.2-kvm-amd64.qcow2"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "1.4.1",
|
||||
"images": {
|
||||
|
||||
@ -38,9 +38,9 @@ log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
# Be careful to keep it consistent
|
||||
DOCKER_MINIMUM_API_VERSION = "1.25"
|
||||
DOCKER_MINIMUM_VERSION = "1.13"
|
||||
DOCKER_PREFERRED_API_VERSION = "1.30"
|
||||
DOCKER_MINIMUM_API_VERSION = "1.40"
|
||||
DOCKER_MINIMUM_VERSION = "19.03.8"
|
||||
DOCKER_PREFERRED_API_VERSION = "1.44"
|
||||
CHUNK_SIZE = 1024 * 8 # 8KB
|
||||
|
||||
|
||||
@ -125,22 +125,28 @@ class Docker(BaseManager):
|
||||
if not self._connected:
|
||||
try:
|
||||
self._connected = True
|
||||
version = await self.query("GET", "version")
|
||||
docker_info = await self.query("GET", "version")
|
||||
except (aiohttp.ClientError, FileNotFoundError):
|
||||
self._connected = False
|
||||
raise DockerError("Can't connect to docker daemon")
|
||||
raise DockerError("Can't connect to Docker daemon")
|
||||
|
||||
docker_version = parse_version(version["ApiVersion"])
|
||||
api_version = parse_version(docker_info['ApiVersion'])
|
||||
version = docker_info["Version"]
|
||||
|
||||
if docker_version < parse_version(DOCKER_MINIMUM_API_VERSION):
|
||||
raise DockerError(
|
||||
f"Docker version is {version['Version']}. "
|
||||
f"GNS3 requires a minimum version of {DOCKER_MINIMUM_VERSION}"
|
||||
if api_version < parse_version(DOCKER_MINIMUM_API_VERSION):
|
||||
raise DockerError(f"Docker version is {version}. "
|
||||
f"GNS3 requires a minimum version of {DOCKER_MINIMUM_VERSION}"
|
||||
)
|
||||
|
||||
preferred_api_version = parse_version(DOCKER_PREFERRED_API_VERSION)
|
||||
if docker_version >= preferred_api_version:
|
||||
if api_version >= preferred_api_version:
|
||||
self._api_version = DOCKER_PREFERRED_API_VERSION
|
||||
else:
|
||||
# use the Min API version supported by the daemon
|
||||
self._api_version = docker_info['MinAPIVersion']
|
||||
log.warning("Using Docker client with the minimum API version {}".format(self._api_version))
|
||||
|
||||
log.info("Connected to Docker daemon version {} using API version {}".format(version, self._api_version))
|
||||
|
||||
def connector(self):
|
||||
|
||||
@ -188,7 +194,7 @@ class Docker(BaseManager):
|
||||
|
||||
:param method: HTTP method
|
||||
:param path: Endpoint in API
|
||||
:param data: Dictionnary with the body. Will be transformed to a JSON
|
||||
:param data: Dictionary with the body. Will be transformed to a JSON
|
||||
:param params: Parameters added as a query arg
|
||||
:param timeout: Timeout
|
||||
:returns: HTTP response
|
||||
@ -199,12 +205,11 @@ class Docker(BaseManager):
|
||||
timeout = 60 * 60 * 24 * 31 # One month timeout
|
||||
|
||||
if path == 'version':
|
||||
url = "http://docker/v1.24/" + path
|
||||
url = "http://docker/" + path
|
||||
else:
|
||||
url = "http://docker/v" + DOCKER_MINIMUM_API_VERSION + "/" + path
|
||||
await self._check_connection() # version is use by check connection
|
||||
url = "http://docker/v" + self._api_version + "/" + path
|
||||
try:
|
||||
if path != "version": # version is use by check connection
|
||||
await self._check_connection()
|
||||
if self._session is None or self._session.closed:
|
||||
connector = self.connector()
|
||||
self._session = aiohttp.ClientSession(connector=connector)
|
||||
|
||||
@ -195,6 +195,14 @@ class DockerVM(BaseNode):
|
||||
def ethernet_adapters(self):
|
||||
return self._ethernet_adapters
|
||||
|
||||
@property
|
||||
def docker_name(self):
|
||||
"""
|
||||
Container name in Docker
|
||||
"""
|
||||
|
||||
return "GNS3.{}.{}".format(self.name, self._project.id)
|
||||
|
||||
@property
|
||||
def mac_address(self):
|
||||
"""
|
||||
@ -539,7 +547,8 @@ class DockerVM(BaseNode):
|
||||
if extra_hosts:
|
||||
params["Env"].append(f"GNS3_EXTRA_HOSTS={extra_hosts}")
|
||||
|
||||
result = await self.manager.query("POST", "containers/create", data=params)
|
||||
# Support name in Doker: [a-zA-Z0-9][a-zA-Z0-9_.-]
|
||||
result = await self.manager.query("POST", f"containers/create?name={self.docker_name}", data=params)
|
||||
self._cid = result["Id"]
|
||||
log.info(f"Docker container '{self._name}' [{self._id}] created")
|
||||
if self._cpus > 0:
|
||||
|
||||
@ -13,8 +13,7 @@ logging console discriminator EXCESS
|
||||
!
|
||||
no ip icmp rate-limit unreachable
|
||||
!
|
||||
! due to some bugs with IOU, try to change the following line to 'ip cef' if your routing does not work
|
||||
no ip cef
|
||||
ip cef
|
||||
no ip domain lookup
|
||||
!
|
||||
!
|
||||
|
||||
@ -12,8 +12,7 @@ no ip icmp rate-limit unreachable
|
||||
!
|
||||
!
|
||||
!
|
||||
! due to some bugs with IOU, try to change the following line to 'ip cef' if your routing does not work
|
||||
no ip cef
|
||||
ip cef
|
||||
no ip domain lookup
|
||||
!
|
||||
!
|
||||
|
||||
@ -60,7 +60,14 @@ class FileWatcher:
|
||||
self._hashed[path] = zlib.adler32(open(path, "rb").read())
|
||||
except OSError:
|
||||
self._hashed[path] = None
|
||||
asyncio.get_event_loop().call_later(self._delay, self._check_config_file_change)
|
||||
|
||||
try:
|
||||
loop = asyncio.get_running_loop()
|
||||
except RuntimeError:
|
||||
loop = asyncio.new_event_loop()
|
||||
asyncio.set_event_loop(loop)
|
||||
|
||||
loop.call_later(self._delay, self._check_config_file_change)
|
||||
|
||||
def __del__(self):
|
||||
self._closed = True
|
||||
|
||||
@ -7,8 +7,8 @@ aiohttp>=3.11.16,<3.12
|
||||
async-timeout==5.0.1; python_version < '3.11'
|
||||
aiofiles>=24.1.0,<25.0
|
||||
Jinja2>=3.1.6,<3.2
|
||||
sentry-sdk>=2.26.1,<2.27 # optional dependency
|
||||
psutil>=7.0.0
|
||||
sentry-sdk>=2.44.0,<2.45 # optional dependency
|
||||
psutil>=7.1.3
|
||||
async-timeout>=5.0.1,<5.1
|
||||
distro>=1.9.0
|
||||
py-cpuinfo>=9.0.0,<10.0
|
||||
|
||||
@ -49,7 +49,7 @@ async def test_query_success(vm):
|
||||
vm._session.request = AsyncioMagicMock(return_value=response)
|
||||
data = await vm.query("POST", "test", data={"a": True}, params={"b": 1})
|
||||
vm._session.request.assert_called_with('POST',
|
||||
'http://docker/v1.25/test',
|
||||
'http://docker/v{}/test'.format(DOCKER_MINIMUM_API_VERSION),
|
||||
data='{"a": true}',
|
||||
headers={'content-type': 'application/json'},
|
||||
params={'b': 1},
|
||||
@ -72,7 +72,7 @@ async def test_query_error(vm):
|
||||
with pytest.raises(DockerError):
|
||||
await vm.query("POST", "test", data={"a": True}, params={"b": 1})
|
||||
vm._session.request.assert_called_with('POST',
|
||||
'http://docker/v1.25/test',
|
||||
'http://docker/v{}/test'.format(DOCKER_MINIMUM_API_VERSION),
|
||||
data='{"a": true}',
|
||||
headers={'content-type': 'application/json'},
|
||||
params={'b': 1},
|
||||
@ -93,7 +93,7 @@ async def test_query_error_json(vm):
|
||||
with pytest.raises(DockerError):
|
||||
await vm.query("POST", "test", data={"a": True}, params={"b": 1})
|
||||
vm._session.request.assert_called_with('POST',
|
||||
'http://docker/v1.25/test',
|
||||
'http://docker/v{}/test'.format(DOCKER_MINIMUM_API_VERSION),
|
||||
data='{"a": true}',
|
||||
headers={'content-type': 'application/json'},
|
||||
params={'b': 1},
|
||||
@ -188,7 +188,9 @@ async def test_docker_check_connection_docker_minimum_version(vm):
|
||||
async def test_docker_check_connection_docker_preferred_version_against_newer(vm):
|
||||
|
||||
response = {
|
||||
'ApiVersion': '1.31'
|
||||
'ApiVersion': '1.52',
|
||||
'Version': '29.0.1',
|
||||
|
||||
}
|
||||
|
||||
with patch("gns3server.compute.docker.Docker.connector"), \
|
||||
@ -202,7 +204,9 @@ async def test_docker_check_connection_docker_preferred_version_against_newer(vm
|
||||
async def test_docker_check_connection_docker_preferred_version_against_older(vm):
|
||||
|
||||
response = {
|
||||
'ApiVersion': '1.27',
|
||||
'ApiVersion': '1.43',
|
||||
'Version': '24.0.2',
|
||||
'MinAPIVersion': '1.40'
|
||||
}
|
||||
|
||||
with patch("gns3server.compute.docker.Docker.connector"), \
|
||||
@ -212,6 +216,20 @@ async def test_docker_check_connection_docker_preferred_version_against_older(vm
|
||||
assert vm._api_version == DOCKER_MINIMUM_API_VERSION
|
||||
|
||||
|
||||
async def test_docker_check_connection_docker_unsupported_version(vm):
|
||||
|
||||
response = {
|
||||
'ApiVersion': '1.25',
|
||||
'Version': '1.13.1',
|
||||
}
|
||||
|
||||
with patch("gns3server.compute.docker.Docker.connector"), \
|
||||
asyncio_patch("gns3server.compute.docker.Docker.query", return_value=response):
|
||||
vm._connected = False
|
||||
with pytest.raises(DockerError) as e:
|
||||
await vm._check_connection()
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_install_busybox():
|
||||
|
||||
|
||||
@ -99,7 +99,7 @@ async def test_create(compute_project, manager):
|
||||
with asyncio_patch("gns3server.compute.docker.Docker.query", return_value=response) as mock:
|
||||
vm = DockerVM("test", str(uuid.uuid4()), compute_project, manager, "ubuntu:latest")
|
||||
await vm.create()
|
||||
mock.assert_called_with("POST", "containers/create", data={
|
||||
mock.assert_called_with("POST", "containers/create?name={}".format(vm.docker_name), data={
|
||||
"Tty": True,
|
||||
"OpenStdin": True,
|
||||
"StdinOnce": False,
|
||||
@ -150,7 +150,7 @@ async def test_create_with_tag(compute_project, manager):
|
||||
with asyncio_patch("gns3server.compute.docker.Docker.query", return_value=response) as mock:
|
||||
vm = DockerVM("test", str(uuid.uuid4()), compute_project, manager, "ubuntu:16.04")
|
||||
await vm.create()
|
||||
mock.assert_called_with("POST", "containers/create", data={
|
||||
mock.assert_called_with("POST", "containers/create?name={}".format(vm.docker_name), data={
|
||||
"Tty": True,
|
||||
"OpenStdin": True,
|
||||
"StdinOnce": False,
|
||||
@ -204,7 +204,7 @@ async def test_create_vnc(compute_project, manager):
|
||||
vm._start_vnc = MagicMock()
|
||||
vm._display = 42
|
||||
await vm.create()
|
||||
mock.assert_called_with("POST", "containers/create", data={
|
||||
mock.assert_called_with("POST", "containers/create?name={}".format(vm.docker_name), data={
|
||||
"Tty": True,
|
||||
"OpenStdin": True,
|
||||
"StdinOnce": False,
|
||||
@ -356,7 +356,7 @@ async def test_create_start_cmd(compute_project, manager):
|
||||
vm = DockerVM("test", str(uuid.uuid4()), compute_project, manager, "ubuntu:latest")
|
||||
vm._start_command = "/bin/ls"
|
||||
await vm.create()
|
||||
mock.assert_called_with("POST", "containers/create", data={
|
||||
mock.assert_called_with("POST", "containers/create?name={}".format(vm.docker_name), data={
|
||||
"Tty": True,
|
||||
"OpenStdin": True,
|
||||
"StdinOnce": False,
|
||||
@ -469,7 +469,7 @@ async def test_create_image_not_available(compute_project, manager):
|
||||
with asyncio_patch("gns3server.compute.docker.DockerVM.pull_image", return_value=True) as mock_pull:
|
||||
with asyncio_patch("gns3server.compute.docker.Docker.query", return_value=response) as mock:
|
||||
await vm.create()
|
||||
mock.assert_called_with("POST", "containers/create", data={
|
||||
mock.assert_called_with("POST", "containers/create?name={}".format(vm.docker_name), data={
|
||||
"Tty": True,
|
||||
"OpenStdin": True,
|
||||
"StdinOnce": False,
|
||||
@ -524,7 +524,7 @@ async def test_create_with_user(compute_project, manager):
|
||||
with asyncio_patch("gns3server.compute.docker.Docker.query", return_value=response) as mock:
|
||||
vm = DockerVM("test", str(uuid.uuid4()), compute_project, manager, "ubuntu:latest")
|
||||
await vm.create()
|
||||
mock.assert_called_with("POST", "containers/create", data={
|
||||
mock.assert_called_with("POST", "containers/create?name={}".format(vm.docker_name), data={
|
||||
"Tty": True,
|
||||
"OpenStdin": True,
|
||||
"StdinOnce": False,
|
||||
@ -624,7 +624,7 @@ async def test_create_with_extra_volumes_duplicate_1_image(compute_project, mana
|
||||
with asyncio_patch("gns3server.compute.docker.Docker.query", return_value=response) as mock:
|
||||
vm = DockerVM("test", str(uuid.uuid4()), compute_project, manager, "ubuntu:latest", extra_volumes=["/vol/1"])
|
||||
await vm.create()
|
||||
mock.assert_called_with("POST", "containers/create", data={
|
||||
mock.assert_called_with("POST", "containers/create?name={}".format(vm.docker_name), data={
|
||||
"Tty": True,
|
||||
"OpenStdin": True,
|
||||
"StdinOnce": False,
|
||||
@ -680,7 +680,7 @@ async def test_create_with_extra_volumes_duplicate_2_user(compute_project, manag
|
||||
with asyncio_patch("gns3server.compute.docker.Docker.query", return_value=response) as mock:
|
||||
vm = DockerVM("test", str(uuid.uuid4()), compute_project, manager, "ubuntu:latest", extra_volumes=["/vol/1", "/vol/1"])
|
||||
await vm.create()
|
||||
mock.assert_called_with("POST", "containers/create", data={
|
||||
mock.assert_called_with("POST", "containers/create?name={}".format(vm.docker_name), data={
|
||||
"Tty": True,
|
||||
"OpenStdin": True,
|
||||
"StdinOnce": False,
|
||||
@ -736,7 +736,7 @@ async def test_create_with_extra_volumes_duplicate_3_subdir(compute_project, man
|
||||
with asyncio_patch("gns3server.compute.docker.Docker.query", return_value=response) as mock:
|
||||
vm = DockerVM("test", str(uuid.uuid4()), compute_project, manager, "ubuntu:latest", extra_volumes=["/vol/1/", "/vol"])
|
||||
await vm.create()
|
||||
mock.assert_called_with("POST", "containers/create", data={
|
||||
mock.assert_called_with("POST", "containers/create?name={}".format(vm.docker_name), data={
|
||||
"Tty": True,
|
||||
"OpenStdin": True,
|
||||
"StdinOnce": False,
|
||||
@ -792,7 +792,7 @@ async def test_create_with_extra_volumes_duplicate_4_backslash(compute_project,
|
||||
with asyncio_patch("gns3server.compute.docker.Docker.query", return_value=response) as mock:
|
||||
vm = DockerVM("test", str(uuid.uuid4()), compute_project, manager, "ubuntu:latest", extra_volumes=["/vol//", "/vol"])
|
||||
await vm.create()
|
||||
mock.assert_called_with("POST", "containers/create", data={
|
||||
mock.assert_called_with("POST", "containers/create?name={}".format(vm.docker_name), data={
|
||||
"Tty": True,
|
||||
"OpenStdin": True,
|
||||
"StdinOnce": False,
|
||||
@ -848,7 +848,7 @@ async def test_create_with_extra_volumes_duplicate_5_subdir_issue_1595(compute_p
|
||||
with asyncio_patch("gns3server.compute.docker.Docker.query", return_value=response) as mock:
|
||||
vm = DockerVM("test", str(uuid.uuid4()), compute_project, manager, "ubuntu:latest", extra_volumes=["/etc"])
|
||||
await vm.create()
|
||||
mock.assert_called_with("POST", "containers/create", data={
|
||||
mock.assert_called_with("POST", "containers/create?name={}".format(vm.docker_name), data={
|
||||
"Tty": True,
|
||||
"OpenStdin": True,
|
||||
"StdinOnce": False,
|
||||
@ -899,7 +899,7 @@ async def test_create_with_extra_volumes_duplicate_6_subdir_issue_1595(compute_p
|
||||
with asyncio_patch("gns3server.compute.docker.Docker.query", return_value=response) as mock:
|
||||
vm = DockerVM("test", str(uuid.uuid4()), compute_project, manager, "ubuntu:latest", extra_volumes=["/etc/test", "/etc"])
|
||||
await vm.create()
|
||||
mock.assert_called_with("POST", "containers/create", data={
|
||||
mock.assert_called_with("POST", "containers/create?name={}".format(vm.docker_name), data={
|
||||
"Tty": True,
|
||||
"OpenStdin": True,
|
||||
"StdinOnce": False,
|
||||
@ -956,7 +956,7 @@ async def test_create_with_extra_volumes(compute_project, manager):
|
||||
with asyncio_patch("gns3server.compute.docker.Docker.query", return_value=response) as mock:
|
||||
vm = DockerVM("test", str(uuid.uuid4()), compute_project, manager, "ubuntu:latest", extra_volumes=["/vol/2"])
|
||||
await vm.create()
|
||||
mock.assert_called_with("POST", "containers/create", data={
|
||||
mock.assert_called_with("POST", "containers/create?name={}".format(vm.docker_name), data={
|
||||
"Tty": True,
|
||||
"OpenStdin": True,
|
||||
"StdinOnce": False,
|
||||
@ -1243,7 +1243,7 @@ async def test_update(vm):
|
||||
await vm.update()
|
||||
|
||||
mock_query.assert_any_call("DELETE", "containers/e90e34656842", params={"force": 1, "v": 1})
|
||||
mock_query.assert_any_call("POST", "containers/create", data={
|
||||
mock_query.assert_any_call("POST", "containers/create?name={}".format(vm.docker_name), data={
|
||||
"Tty": True,
|
||||
"OpenStdin": True,
|
||||
"StdinOnce": False,
|
||||
@ -1325,7 +1325,7 @@ async def test_update_running(vm):
|
||||
await vm.update()
|
||||
|
||||
mock_query.assert_any_call("DELETE", "containers/e90e34656842", params={"force": 1, "v": 1})
|
||||
mock_query.assert_any_call("POST", "containers/create", data={
|
||||
mock_query.assert_any_call("POST", "containers/create?name={}".format(vm.docker_name), data={
|
||||
"Tty": True,
|
||||
"OpenStdin": True,
|
||||
"StdinOnce": False,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user