Cleanup unbreakable space

pull/565/head
Julien Duponchelle 8 years ago
parent 8cb5cedb5d
commit 871fea33e0
No known key found for this signature in database
GPG Key ID: CE8B29639E07F5E8

@ -10,7 +10,7 @@
* Docker support * Docker support
* import / export portable projects (.gns3project) * import / export portable projects (.gns3project)
## 1.4.6 28/04/2016 ## 1.4.6 28/04/2016
* More robust save/restore for VirtualBox linked clone VM hard disks. * More robust save/restore for VirtualBox linked clone VM hard disks.
* Prevent non linked cloned hard disks to be detached when using VirtualBox linked cloned VMs. Fixes #1184. * Prevent non linked cloned hard disks to be detached when using VirtualBox linked cloned VMs. Fixes #1184.
@ -119,7 +119,7 @@
* Support VM usage for qemu * Support VM usage for qemu
* Raise an error if psutil version is invalid * Raise an error if psutil version is invalid
## 1.4.0rc1 12/11/2015 ## 1.4.0rc1 12/11/2015
* Raise error if server received windows path * Raise error if server received windows path
* Update sentry key * Update sentry key
@ -259,7 +259,7 @@
* Send an error when vmware executable cannot be found on Linux. Fixes #288. * Send an error when vmware executable cannot be found on Linux. Fixes #288.
* Support for CPUs setting for Qemu VMs. * Support for CPUs setting for Qemu VMs.
## 1.4.0alpha4 04/08/2015 ## 1.4.0alpha4 04/08/2015
* Quote command in qemu debug logs so you can copy/paste them * Quote command in qemu debug logs so you can copy/paste them
* Support for Qemu disk interfaces, cd/dvd-rom image and boot priority. Fixes #278. * Support for Qemu disk interfaces, cd/dvd-rom image and boot priority. Fixes #278.
@ -267,11 +267,11 @@
* Catch GeneratorExit exception when trying to create a Ghost IOS image. * Catch GeneratorExit exception when trying to create a Ghost IOS image.
* Backport: removes code that deletes IOS router instance files. * Backport: removes code that deletes IOS router instance files.
## 1.3.9 03/08/2015 ## 1.3.9 03/08/2015
* Backport: removes code that deletes IOS router instance files. * Backport: removes code that deletes IOS router instance files.
## 1.4.0alpha3 28/07/2015 ## 1.4.0alpha3 28/07/2015
* Raise error if qemu image already exist when creating disk * Raise error if qemu image already exist when creating disk
* Prevent user to create a qemu to a different directory on non local server * Prevent user to create a qemu to a different directory on non local server
@ -291,7 +291,7 @@
* Update documentation * Update documentation
* API for listing current projects * API for listing current projects
## 1.3.8 27/07/2015 ## 1.3.8 27/07/2015
* Catch ProcessLookupError when updating iouyap config. Fixes #255. * Catch ProcessLookupError when updating iouyap config. Fixes #255.
* Fixes IOS adapters and WICS cannot be removed. Fixes #282. * Fixes IOS adapters and WICS cannot be removed. Fixes #282.
@ -308,7 +308,7 @@
* Backport from 1.4: Fixes RuntimeError: Event loop is closed. * Backport from 1.4: Fixes RuntimeError: Event loop is closed.
* Backport from 1.4: Bind host on 0.0.0.0 when checking for a free UDP port. * Backport from 1.4: Bind host on 0.0.0.0 when checking for a free UDP port.
## 1.4.0alpha2 22/07/2015 ## 1.4.0alpha2 22/07/2015
* Deactivate uBridge process monitoring (process returns 1 on Windows when stopping). * Deactivate uBridge process monitoring (process returns 1 on Windows when stopping).
* Prevent using different hypervisors that leverage hardware virtualization. - Implemented for Qemu when a VMware or VirtualBox VM with hardware virtualization is already running. - Implemented for VirtualBox only when a Qemu VM with KVM is already running. * Prevent using different hypervisors that leverage hardware virtualization. - Implemented for Qemu when a VMware or VirtualBox VM with hardware virtualization is already running. - Implemented for VirtualBox only when a Qemu VM with KVM is already running.
@ -363,15 +363,15 @@
* A notification stream with process monitoring * A notification stream with process monitoring
* VMware support * VMware support
## 1.3.7 22/06/2015 ## 1.3.7 22/06/2015
* Prevent install on Python 2 * Prevent install on Python 2
## 1.3.6 16/06/2015 ## 1.3.6 16/06/2015
* Fix an issue with 1.4dev compatibility * Fix an issue with 1.4dev compatibility
## 1.3.5 16/06/15 ## 1.3.5 16/06/15
* Ignore invalid characters when reading the output of a process * Ignore invalid characters when reading the output of a process
* Turn on / off authentication * Turn on / off authentication
@ -531,7 +531,7 @@
* Initialize chassis when creating an IOS router. Fixes #107. * Initialize chassis when creating an IOS router. Fixes #107.
* Lock the dynamips reader an writer * Lock the dynamips reader an writer
## 1.3.0rc1 19/03/2015 ## 1.3.0rc1 19/03/2015
* Save IOS router config when saving the project * Save IOS router config when saving the project
* Look in legacy IOU images directory * Look in legacy IOU images directory
@ -540,7 +540,7 @@
* Support all QEMU status * Support all QEMU status
* Bind tunnel UDP to the correct source index * Bind tunnel UDP to the correct source index
## 1.3.0beta2 13/03/2015 ## 1.3.0beta2 13/03/2015
* Fixed issue when VBoxManage returns an error. * Fixed issue when VBoxManage returns an error.
* Server handler to shutdown a local server. * Server handler to shutdown a local server.
@ -550,7 +550,7 @@
* Alternative local server shutdown (intended for Windows). * Alternative local server shutdown (intended for Windows).
* Request user permission to kill the local server if it cannot be stopped. * Request user permission to kill the local server if it cannot be stopped.
## 1.3.0beta1 11/03/2015 ## 1.3.0beta1 11/03/2015
* Optional IOU license key check. * Optional IOU license key check.
* Relative path support of IOU, IOS and Qemu images. * Relative path support of IOU, IOS and Qemu images.
@ -573,7 +573,7 @@
* Fixed Telnet server initialization issue in VirtualBox. * Fixed Telnet server initialization issue in VirtualBox.
* Disconnect network cable if adapter is not attached in VirtualBox vNIC. * Disconnect network cable if adapter is not attached in VirtualBox vNIC.
## 1.3.0alpha1 03/03/2015 ## 1.3.0alpha1 03/03/2015
* HTTP Rest API instead of WebSocket * HTTP Rest API instead of WebSocket
* API documentation * API documentation
@ -588,7 +588,7 @@
## 1.2.2 2015/01/16 ## 1.2.2 2015/01/16
### Small improvements / new features ### Small improvements / new features
* Auxiliary console support for IOS routers. * Auxiliary console support for IOS routers.
* Suspend / resume support for Qemu. * Suspend / resume support for Qemu.
@ -620,7 +620,7 @@
* VirtualBox linked clones support (experimental, still some problems with temporary projects). * VirtualBox linked clones support (experimental, still some problems with temporary projects).
## 1.1 2014/10/23 ## 1.1 2014/10/23
* Serial console for local VirtualBox. * Serial console for local VirtualBox.

@ -18,13 +18,13 @@ it on https://github.com/GNS3/gns3-gui we will take care of the triage.
For bugs specific to the GNS3 VM, please report on https://github.com/GNS3/gns3-vm For bugs specific to the GNS3 VM, please report on https://github.com/GNS3/gns3-vm
## Asking for new features ## Asking for new features
The best is to start a discussion on the community website in order to get feedback The best is to start a discussion on the community website in order to get feedback
from the whole community. from the whole community.
## Contributing code ## Contributing code
We welcome code contribution from everyone including beginners. We welcome code contribution from everyone including beginners.
Don't be afraid to submit a half finished or mediocre contribution and we will help you. Don't be afraid to submit a half finished or mediocre contribution and we will help you.
@ -45,6 +45,6 @@ The reason we do this is to ensure, to the extent possible, that we dont “t
More information there: https://github.com/GNS3/cla More information there: https://github.com/GNS3/cla
### Pull requests ### Pull requests
Creating a pull request is the easiest way to contribute code. Do not hesitate to create one early when contributing for new feature in order to get our feedback. Creating a pull request is the easiest way to contribute code. Do not hesitate to create one early when contributing for new feature in order to get our feedback.

@ -29,7 +29,7 @@ You can check the server version with a simple curl command:
.. code-block:: shell-session .. code-block:: shell-session
# curl "http://localhost:3080/v1/version" # curl "http://localhost:3080/v1/version"
{ {
"version": "1.3.dev1" "version": "1.3.dev1"
} }
@ -39,7 +39,7 @@ The next step is to create a project.
.. code-block:: shell-session .. code-block:: shell-session
# curl -X POST "http://localhost:3080/v1/projects" -d '{"name": "test"}' # curl -X POST "http://localhost:3080/v1/projects" -d '{"name": "test"}'
{ {
"project_id": "42f9feee-3217-4104-981e-85d5f0a806ec", "project_id": "42f9feee-3217-4104-981e-85d5f0a806ec",
"temporary": false, "temporary": false,
@ -50,7 +50,7 @@ With this project id we can now create two VPCS VM.
.. code-block:: shell-session .. code-block:: shell-session
# curl -X POST "http://localhost:3080/v1/projects/42f9feee-3217-4104-981e-85d5f0a806ec/vpcs/vms" -d '{"name": "VPCS 1"}' # curl -X POST "http://localhost:3080/v1/projects/42f9feee-3217-4104-981e-85d5f0a806ec/vpcs/vms" -d '{"name": "VPCS 1"}'
{ {
"console": 2000, "console": 2000,
"name": "VPCS 1", "name": "VPCS 1",
@ -58,7 +58,7 @@ With this project id we can now create two VPCS VM.
"vm_id": "24d2e16b-fbef-4259-ae34-7bc21a41ee28" "vm_id": "24d2e16b-fbef-4259-ae34-7bc21a41ee28"
}% }%
# curl -X POST "http://localhost:3080/v1/projects/42f9feee-3217-4104-981e-85d5f0a806ec/vpcs/vms" -d '{"name": "VPCS 2"}' # curl -X POST "http://localhost:3080/v1/projects/42f9feee-3217-4104-981e-85d5f0a806ec/vpcs/vms" -d '{"name": "VPCS 2"}'
{ {
"console": 2001, "console": 2001,
"name": "VPCS 2", "name": "VPCS 2",
@ -86,7 +86,7 @@ communication is made by creating two UDP tunnels.
.. code-block:: shell-session .. code-block:: shell-session
# curl -X POST "http://localhost:3080/v1/projects/42f9feee-3217-4104-981e-85d5f0a806ec/vpcs/vms/24d2e16b-fbef-4259-ae34-7bc21a41ee28/adapters/0/ports/0/nio" -d '{"lport": 10000, "rhost": "127.0.0.1", "rport": 10001, "type": "nio_udp"}' # curl -X POST "http://localhost:3080/v1/projects/42f9feee-3217-4104-981e-85d5f0a806ec/vpcs/vms/24d2e16b-fbef-4259-ae34-7bc21a41ee28/adapters/0/ports/0/nio" -d '{"lport": 10000, "rhost": "127.0.0.1", "rport": 10001, "type": "nio_udp"}'
{ {
"lport": 10000, "lport": 10000,
"rhost": "127.0.0.1", "rhost": "127.0.0.1",
@ -106,7 +106,7 @@ Now we can start the two VM
.. code-block:: shell-session .. code-block:: shell-session
# curl -X POST "http://localhost:3080/v1/projects/42f9feee-3217-4104-981e-85d5f0a806ec/vpcs/vms/24d2e16b-fbef-4259-ae34-7bc21a41ee28/start" -d "{}" # curl -X POST "http://localhost:3080/v1/projects/42f9feee-3217-4104-981e-85d5f0a806ec/vpcs/vms/24d2e16b-fbef-4259-ae34-7bc21a41ee28/start" -d "{}"
# curl -X POST "http://localhost:3080/v1/projects/42f9feee-3217-4104-981e-85d5f0a806ec/vpcs/vms/daefc24a-103c-4717-8e01-6517d931c1ae/start" -d '{}' # curl -X POST "http://localhost:3080/v1/projects/42f9feee-3217-4104-981e-85d5f0a806ec/vpcs/vms/daefc24a-103c-4717-8e01-6517d931c1ae/start" -d '{}'
Everything should be started now. You can connect via telnet to the different VM. Everything should be started now. You can connect via telnet to the different VM.
@ -114,7 +114,7 @@ The port is the field console in the create VM request.
.. code-block:: shell-session .. code-block:: shell-session
# telnet 127.0.0.1 2000 # telnet 127.0.0.1 2000
Trying 127.0.0.1... Trying 127.0.0.1...
Connected to localhost. Connected to localhost.
Escape character is '^]'. Escape character is '^]'.
@ -140,7 +140,7 @@ The port is the field console in the create VM request.
Good-bye Good-bye
Connection closed by foreign host. Connection closed by foreign host.
# telnet 127.0.0.1 2001 # telnet 127.0.0.1 2001
telnet 127.0.0.1 2001 telnet 127.0.0.1 2001
Trying 127.0.0.1... Trying 127.0.0.1...
Connected to localhost. Connected to localhost.

@ -36,7 +36,7 @@ import logging
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
# Dev build # Dev build
if __version_info__[3] != 0: if __version_info__[3] != 0:
import faulthandler import faulthandler

@ -236,7 +236,7 @@ class ProjectHandler:
:returns: hash :returns: hash
""" """
stats = {} stats = {}
# Non blocking call in order to get cpu usage. First call will return 0 # Non blocking call in order to get cpu usage. First call will return 0
stats["cpu_usage_percent"] = psutil.cpu_percent(interval=None) stats["cpu_usage_percent"] = psutil.cpu_percent(interval=None)
stats["memory_usage_percent"] = psutil.virtual_memory().percent stats["memory_usage_percent"] = psutil.virtual_memory().percent
return {"action": "ping", "event": stats} return {"action": "ping", "event": stats}
@ -280,7 +280,7 @@ class ProjectHandler:
path = request.match_info["path"] path = request.match_info["path"]
path = os.path.normpath(path) path = os.path.normpath(path)
# Raise error if user try to escape # Raise error if user try to escape
if path[0] == ".": if path[0] == ".":
raise aiohttp.web.HTTPForbidden raise aiohttp.web.HTTPForbidden
path = os.path.join(project.path, path) path = os.path.join(project.path, path)
@ -325,7 +325,7 @@ class ProjectHandler:
path = request.match_info["path"] path = request.match_info["path"]
path = os.path.normpath(path) path = os.path.normpath(path)
# Raise error if user try to escape # Raise error if user try to escape
if path[0] == ".": if path[0] == ".":
raise aiohttp.web.HTTPForbidden raise aiohttp.web.HTTPForbidden
path = os.path.join(project.path, path) path = os.path.join(project.path, path)
@ -394,10 +394,10 @@ class ProjectHandler:
project = pm.create_project(project_id=project_id) project = pm.create_project(project_id=project_id)
# We write the content to a temporary location # We write the content to a temporary location
# and after extract all. It could be more optimal to stream # and after extract all. It could be more optimal to stream
# this but it's not implemented in Python. # this but it's not implemented in Python.
#  #
# Spooled mean the file is temporary keep in ram until max_size # Spooled mean the file is temporary keep in ram until max_size
try: try:
with tempfile.SpooledTemporaryFile(max_size=10000) as temp: with tempfile.SpooledTemporaryFile(max_size=10000) as temp:
while True: while True:

@ -423,7 +423,7 @@ class BaseManager:
return force_unix_path(path) return force_unix_path(path)
else: else:
# For non local server we disallow using absolute path outside image directory # For non local server we disallow using absolute path outside image directory
if Config.instance().get_section_config("Server").get("local", False) is False: if Config.instance().get_section_config("Server").get("local", False) is False:
img_directory = self.config.get_section_config("Server").get("images_path", os.path.expanduser("~/GNS3/images")) img_directory = self.config.get_section_config("Server").get("images_path", os.path.expanduser("~/GNS3/images"))
img_directory = force_unix_path(img_directory) img_directory = force_unix_path(img_directory)

@ -71,7 +71,7 @@ class BaseVM:
else: else:
self._console = self._manager.port_manager.reserve_tcp_port(self._console, self._project) self._console = self._manager.port_manager.reserve_tcp_port(self._console, self._project)
# We need to allocate aux before giving a random console port # We need to allocate aux before giving a random console port
if self._aux is not None: if self._aux is not None:
self._aux = self._manager.port_manager.reserve_tcp_port(self._aux, self._project) self._aux = self._manager.port_manager.reserve_tcp_port(self._aux, self._project)

@ -117,11 +117,11 @@ class Docker(BaseManager):
pass pass
log.debug("Query Docker %s %s params=%s data=%s Response: %s", method, path, params, data, body) log.debug("Query Docker %s %s params=%s data=%s Response: %s", method, path, params, data, body)
if response.status == 304: if response.status == 304:
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))
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
@asyncio.coroutine @asyncio.coroutine

@ -367,7 +367,7 @@ class DockerVM(BaseVM):
""" """
# We can not use the API because docker doesn't expose a websocket api for exec # We can not use the API because docker doesn't expose a websocket api for exec
# https://github.com/GNS3/gns3-gui/issues/1039 # https://github.com/GNS3/gns3-gui/issues/1039
process = yield from asyncio.subprocess.create_subprocess_exec( process = yield from asyncio.subprocess.create_subprocess_exec(
"docker", "exec", "-i", self._cid, "/gns3/bin/busybox", "script", "-qfc", "/gns3/bin/busybox sh", "/dev/null", "docker", "exec", "-i", self._cid, "/gns3/bin/busybox", "script", "-qfc", "/gns3/bin/busybox sh", "/dev/null",
stdout=asyncio.subprocess.PIPE, stdout=asyncio.subprocess.PIPE,

@ -17,7 +17,7 @@
# #
# This script is injected into the container and launch before # This script is injected into the container and launch before
# the start command of the container # the start command of the container
# #
OLD_PATH="$PATH" OLD_PATH="$PATH"
PATH=/gns3/bin:/tmp/gns3/bin PATH=/gns3/bin:/tmp/gns3/bin

@ -219,7 +219,7 @@ class Dynamips(BaseManager):
continue continue
# Release the dynamips ids if we want to reload the same project # Release the dynamips ids if we want to reload the same project
# later # later
if project.id in self._dynamips_ids: if project.id in self._dynamips_ids:
del self._dynamips_ids[project.id] del self._dynamips_ids[project.id]

@ -131,7 +131,7 @@ class IOUVM(BaseVM):
self._path = self.manager.get_abs_image_path(path) self._path = self.manager.get_abs_image_path(path)
# In 1.2 users uploaded images to the images roots # In 1.2 users uploaded images to the images roots
# after the migration their images are inside images/IOU # after the migration their images are inside images/IOU
# but old topologies use old path # but old topologies use old path
if "IOU" not in self._path: if "IOU" not in self._path:
location, filename = os.path.split(self._path) location, filename = os.path.split(self._path)

@ -533,7 +533,7 @@ class Project:
if os.path.split(root)[-1:][0] == "project-files": if os.path.split(root)[-1:][0] == "project-files":
dirs[:] = [d for d in dirs if d not in ("snapshots", "captures")] dirs[:] = [d for d in dirs if d not in ("snapshots", "captures")]
# Ignore log files and OS noise # Ignore log files and OS noise
files = [f for f in files if not f.endswith('_log.txt') and not f.endswith('.log') and f != '.DS_Store'] files = [f for f in files if not f.endswith('_log.txt') and not f.endswith('.log') and f != '.DS_Store']
for file in files: for file in files:

@ -82,8 +82,8 @@ class QemuVM(BaseVM):
try: try:
self.qemu_path = qemu_path self.qemu_path = qemu_path
except QemuError as e: except QemuError as e:
# If the binary is not found for topologies 1.4 and later # If the binary is not found for topologies 1.4 and later
# search via the platform otherwise use the binary name # search via the platform otherwise use the binary name
if platform: if platform:
self.platform = platform self.platform = platform
else: else:

@ -83,8 +83,8 @@ class VirtualBox(BaseManager):
@asyncio.coroutine @asyncio.coroutine
def execute(self, subcommand, args, timeout=60): def execute(self, subcommand, args, timeout=60):
# We use a lock prevent parallel execution due to strange errors # We use a lock prevent parallel execution due to strange errors
# reported by a user and reproduced by us. # reported by a user and reproduced by us.
# https://github.com/GNS3/gns3-gui/issues/261 # https://github.com/GNS3/gns3-gui/issues/261
with (yield from self._execute_lock): with (yield from self._execute_lock):
vboxmanage_path = self.vboxmanage_path vboxmanage_path = self.vboxmanage_path

@ -73,7 +73,7 @@ def parse_version(version):
version.append("00000") version.append("00000")
if len(version) == 2: if len(version) == 2:
version.append("000000") version.append("000000")
# We want rc to be at lower level than dev version # We want rc to be at lower level than dev version
if info == 'rc': if info == 'rc':
info = 'c' info = 'c'
version.append(info) version.append(info)

@ -54,7 +54,7 @@ def subprocess_check_output(*args, cwd=None, env=None):
if output is None: if output is None:
return "" return ""
# If we received garbage we ignore invalid characters # If we received garbage we ignore invalid characters
# it should happend only when user try to use another binary # it should happend only when user try to use another binary
# and the code of VPCS, dynamips... Will detect it's not the correct binary # and the code of VPCS, dynamips... Will detect it's not the correct binary
return output.decode("utf-8", errors="ignore") return output.decode("utf-8", errors="ignore")

@ -69,7 +69,7 @@ class AsyncioTelnetServer:
self._binary = binary self._binary = binary
# If echo is true when the client send data # If echo is true when the client send data
# the data is echo on his terminal by telnet otherwise # the data is echo on his terminal by telnet otherwise
# it's our job (or the wrapped app) to send back the data # it's our job (or the wrapped app) to send back the data
self._echo = echo self._echo = echo

@ -74,7 +74,7 @@ class ColouredStreamHandler(logging.StreamHandler):
stream.write(msg) stream.write(msg)
stream.write(self.terminator) stream.write(self.terminator)
self.flush() self.flush()
# On OSX when frozen flush raise a BrokenPipeError # On OSX when frozen flush raise a BrokenPipeError
except BrokenPipeError: except BrokenPipeError:
pass pass
except Exception: except Exception:

@ -18,7 +18,7 @@
# #
# Install GNS3 on a remote Ubuntu 14.04 LTS server # Install GNS3 on a remote Ubuntu 14.04 LTS server
# This create a dedicated user and setup all the package # This create a dedicated user and setup all the package
# and optionnaly a VPN # and optionnaly a VPN
# #
function help { function help {
@ -115,7 +115,7 @@ apt-get update
log "Upgrade packages" log "Upgrade packages"
apt-get upgrade -y apt-get upgrade -y
log " Install GNS3 packages" log " Install GNS3 packages"
apt-get install -y gns3-server apt-get install -y gns3-server
log "Create user GNS3 with /opt/gns3 as home directory" log "Create user GNS3 with /opt/gns3 as home directory"

@ -683,7 +683,7 @@ def test_add_ubridge_connection_no_free_interface(loop, vm):
nio = vm.manager.create_nio(0, nio) nio = vm.manager.create_nio(0, nio)
with pytest.raises(DockerError): with pytest.raises(DockerError):
# We create fake ethernet interfaces for docker # We create fake ethernet interfaces for docker
interfaces = ["veth-gns3-ext{}".format(index) for index in range(128)] interfaces = ["veth-gns3-ext{}".format(index) for index in range(128)]
with patch("psutil.net_if_addrs", return_value=interfaces): with patch("psutil.net_if_addrs", return_value=interfaces):

@ -216,7 +216,7 @@ def test_path(vm, fake_iou_bin):
def test_path_12_location(vm, fake_iou_bin): def test_path_12_location(vm, fake_iou_bin):
# In 1.2 users uploaded images to the images roots # In 1.2 users uploaded images to the images roots
# after the migration their images are inside images/IOU # after the migration their images are inside images/IOU
# but old topologies use old path # but old topologies use old path
with patch("gns3server.config.Config.get_section_config", return_value={"local": True}): with patch("gns3server.config.Config.get_section_config", return_value={"local": True}):
vm.path = fake_iou_bin.replace("/IOU", "") vm.path = fake_iou_bin.replace("/IOU", "")

Loading…
Cancel
Save