From 4fed98617bc7fa86ba467e3b9edd7c48c8d1e25b Mon Sep 17 00:00:00 2001 From: Julien Duponchelle Date: Mon, 13 Feb 2017 11:39:21 +0100 Subject: [PATCH 01/15] Add Dockerfile for development --- Dockerfile | 34 ++++++++++++++++++++++++++++++++++ README.rst | 10 ++++++++++ 2 files changed, 44 insertions(+) create mode 100644 Dockerfile diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 00000000..5f6dcc4a --- /dev/null +++ b/Dockerfile @@ -0,0 +1,34 @@ +# Dockerfile for GNS3 server development + +FROM ubuntu:16.04 + +ENV DEBIAN_FRONTEND noninteractive + +# Set the locale +RUN locale-gen en_US.UTF-8 +ENV LANG en_US.UTF-8 +ENV LANGUAGE en_US:en +ENV LC_ALL en_US.UTF-8 + +RUN apt-get update && apt-get install -y software-properties-common +RUN add-apt-repository ppa:gns3/ppa +RUN apt-get update && apt-get install -y \ + python3-pip \ + python3-dev \ + qemu-system-x86 \ + qemu-system-arm \ + qemu-kvm \ + libvirt-bin \ + x11vnc + +# Install uninstall to install dependencies +RUN apt-get install -y vpcs ubridge + +ADD . /server +WORKDIR /server + +RUN pip3 install -r /server/requirements.txt + +EXPOSE 3080 + +ENTRYPOINT python3 -m gns3server --local diff --git a/README.rst b/README.rst index 81ffc9d5..6da27c4f 100644 --- a/README.rst +++ b/README.rst @@ -71,6 +71,16 @@ To run tests use: py.test -v +Docker container +**************** + +For development you can run the GNS3 server in a container + +.. code:: bash + docker build -t gns3-server . + docker run -i --expose=8001 -p 8001:8001/tcp -t gns3-server python3 -m gns3server --local --port 8001 + + Run as daemon (Unix only) ************************** From defcf8261048cc17acd8d85a54884ff96b0083c4 Mon Sep 17 00:00:00 2001 From: Julien Duponchelle Date: Mon, 13 Feb 2017 15:18:00 +0100 Subject: [PATCH 02/15] Fix a rare error when closing a project Fix #897 --- gns3server/controller/project.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gns3server/controller/project.py b/gns3server/controller/project.py index 8796e028..5bf23744 100644 --- a/gns3server/controller/project.py +++ b/gns3server/controller/project.py @@ -536,7 +536,7 @@ class Project: @asyncio.coroutine def close(self, ignore_notification=False): yield from self.stop_all() - for compute in self._project_created_on_compute: + for compute in list(self._project_created_on_compute): try: yield from compute.post("/projects/{}/close".format(self._id), dont_connect=True) # We don't care if a compute is down at this step From 5639cbe8601c51b125f1efc86e52075e922c0b41 Mon Sep 17 00:00:00 2001 From: Julien Duponchelle Date: Mon, 13 Feb 2017 15:24:22 +0100 Subject: [PATCH 03/15] Fix a rare crash when closing a project Fix #900 --- gns3server/controller/__init__.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/gns3server/controller/__init__.py b/gns3server/controller/__init__.py index 581a9897..d0726713 100644 --- a/gns3server/controller/__init__.py +++ b/gns3server/controller/__init__.py @@ -367,7 +367,8 @@ class Controller: return project def remove_project(self, project): - del self._projects[project.id] + if project.id in self._projects: + del self._projects[project.id] @asyncio.coroutine def load_project(self, path, load=True): From a576c57873ea2019f4dde867b91d396966c25608 Mon Sep 17 00:00:00 2001 From: Julien Duponchelle Date: Mon, 13 Feb 2017 15:30:02 +0100 Subject: [PATCH 04/15] Catch permission error when restoring a snapshot Fix #899 --- gns3server/controller/snapshot.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/gns3server/controller/snapshot.py b/gns3server/controller/snapshot.py index 217a16b7..4163a6b1 100644 --- a/gns3server/controller/snapshot.py +++ b/gns3server/controller/snapshot.py @@ -20,6 +20,7 @@ import os import uuid import shutil import asyncio +import aiohttp.web from datetime import datetime, timezone @@ -80,10 +81,13 @@ class Snapshot: # We don't send close notif to clients because the close / open dance is purely internal yield from self._project.close(ignore_notification=True) self._project.controller.notification.emit("snapshot.restored", self.__json__()) - if os.path.exists(os.path.join(self._project.path, "project-files")): - shutil.rmtree(os.path.join(self._project.path, "project-files")) - with open(self._path, "rb") as f: - project = yield from import_project(self._project.controller, self._project.id, f, location=self._project.path) + try: + if os.path.exists(os.path.join(self._project.path, "project-files")): + shutil.rmtree(os.path.join(self._project.path, "project-files")) + with open(self._path, "rb") as f: + project = yield from import_project(self._project.controller, self._project.id, f, location=self._project.path) + except (OSError, PermissionError) as e: + raise aiohttp.web.HTTPConflict(text=str(e)) yield from project.open() return project From 0dbd92db1156049e18ce4ec352146cc4b36da81e Mon Sep 17 00:00:00 2001 From: Julien Duponchelle Date: Mon, 13 Feb 2017 19:11:29 +0100 Subject: [PATCH 05/15] Fix disk lost when save as a project using linked clone VirtualBox Fix https://github.com/GNS3/gns3-gui/issues/1824 --- .../compute/virtualbox/virtualbox_vm.py | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/gns3server/compute/virtualbox/virtualbox_vm.py b/gns3server/compute/virtualbox/virtualbox_vm.py index 801988e2..e1d520dc 100644 --- a/gns3server/compute/virtualbox/virtualbox_vm.py +++ b/gns3server/compute/virtualbox/virtualbox_vm.py @@ -19,14 +19,16 @@ VirtualBox VM instance. """ -import sys -import shlex import re import os -import tempfile +import sys import json +import uuid +import shlex +import shutil import socket import asyncio +import tempfile import xml.etree.ElementTree as ET from gns3server.utils import parse_version @@ -209,7 +211,16 @@ class VirtualBoxVM(BaseNode): if os.path.exists(self._linked_vbox_file()): tree = ET.parse(self._linked_vbox_file()) machine = tree.getroot().find("{http://www.virtualbox.org/}Machine") - if machine is not None: + if machine is not None and machine.get("uuid") != "{" + self.id + "}": + + for image in tree.getroot().findall("{http://www.virtualbox.org/}Image"): + currentSnapshot = machine.get("currentSnapshot") + if currentSnapshot: + newSnapshot = re.sub("\{.*\}", "{" + str(uuid.uuid4()) + "}", currentSnapshot) + shutil.move(os.path.join(self.working_dir, self._vmname, "Snapshots", currentSnapshot) + ".vdi", + os.path.join(self.working_dir, self._vmname, "Snapshots", newSnapshot) + ".vdi") + image.set("uuid", newSnapshot) + machine.set("uuid", "{" + self.id + "}") tree.write(self._linked_vbox_file()) From a191029c4f364ee9bcbc28fb6adf9fae9aaedb63 Mon Sep 17 00:00:00 2001 From: Julien Duponchelle Date: Tue, 14 Feb 2017 14:45:48 +0100 Subject: [PATCH 06/15] Fix linked_clone property lost during topology convert --- gns3server/controller/topology.py | 2 ++ tests/controller/test_export_project.py | 24 +++++++++---------- .../1_5_virtualbox/after/1_5_virtualbox.gns3 | 1 + .../1_5_vmware/after/1_5_vmware.gns3 | 1 + 4 files changed, 16 insertions(+), 12 deletions(-) diff --git a/gns3server/controller/topology.py b/gns3server/controller/topology.py index 3f7a1540..c188e9a9 100644 --- a/gns3server/controller/topology.py +++ b/gns3server/controller/topology.py @@ -321,10 +321,12 @@ def _convert_1_3_later(topo, topo_path): node["properties"]["ram"] = PLATFORMS_DEFAULT_RAM[old_node["type"].lower()] elif old_node["type"] == "VMwareVM": node["node_type"] = "vmware" + node["properties"]["linked_clone"] = old_node.get("linked_clone", False) if node["symbol"] is None: node["symbol"] = ":/symbols/vmware_guest.svg" elif old_node["type"] == "VirtualBoxVM": node["node_type"] = "virtualbox" + node["properties"]["linked_clone"] = old_node.get("linked_clone", False) if node["symbol"] is None: node["symbol"] = ":/symbols/vbox_guest.svg" elif old_node["type"] == "IOUDevice": diff --git a/tests/controller/test_export_project.py b/tests/controller/test_export_project.py index 65b1e80f..da7c3c1d 100644 --- a/tests/controller/test_export_project.py +++ b/tests/controller/test_export_project.py @@ -202,7 +202,7 @@ def test_export_disallow_some_type(tmpdir, project, async_run): with pytest.raises(aiohttp.web.HTTPConflict): z = async_run(export_project(project, str(tmpdir))) - z = async_run(export_project(project, str(tmpdir), allow_all_nodes=True)) + z = async_run(export_project(project, str(tmpdir), allow_all_nodes=True)) def test_export_fix_path(tmpdir, project, async_run): @@ -215,18 +215,18 @@ def test_export_fix_path(tmpdir, project, async_run): topology = { "topology": { "nodes": [ - { - "properties": { - "image": "/tmp/c3725-adventerprisek9-mz.124-25d.image" - }, - "node_type": "dynamips" - }, { - "properties": { - "image": "gns3/webterm:lastest" - }, - "node_type": "docker" - } + "properties": { + "image": "/tmp/c3725-adventerprisek9-mz.124-25d.image" + }, + "node_type": "dynamips" + }, + { + "properties": { + "image": "gns3/webterm:lastest" + }, + "node_type": "docker" + } ] } } diff --git a/tests/topologies/1_5_virtualbox/after/1_5_virtualbox.gns3 b/tests/topologies/1_5_virtualbox/after/1_5_virtualbox.gns3 index 1f591b24..ba17e46d 100644 --- a/tests/topologies/1_5_virtualbox/after/1_5_virtualbox.gns3 +++ b/tests/topologies/1_5_virtualbox/after/1_5_virtualbox.gns3 @@ -34,6 +34,7 @@ "port_segment_size": 0, "first_port_name": null, "properties": { + "linked_clone": false, "acpi_shutdown": false, "adapter_type": "Intel PRO/1000 MT Desktop (82540EM)", "adapters": 1, diff --git a/tests/topologies/1_5_vmware/after/1_5_vmware.gns3 b/tests/topologies/1_5_vmware/after/1_5_vmware.gns3 index 98a25f62..8238605c 100644 --- a/tests/topologies/1_5_vmware/after/1_5_vmware.gns3 +++ b/tests/topologies/1_5_vmware/after/1_5_vmware.gns3 @@ -34,6 +34,7 @@ "port_segment_size": 0, "first_port_name": null, "properties": { + "linked_clone": false, "acpi_shutdown": false, "adapter_type": "e1000", "adapters": 1, From e04eb44a15227cf5901f685ddc010464ae7a8dfa Mon Sep 17 00:00:00 2001 From: Julien Duponchelle Date: Tue, 14 Feb 2017 16:41:31 +0100 Subject: [PATCH 07/15] Disallow export of project with VirtualBox linked clone Fix https://github.com/GNS3/gns3-gui/issues/1824 --- gns3server/controller/export_project.py | 2 ++ tests/controller/test_export_project.py | 24 +++++++++++++++++++++--- tests/controller/test_project.py | 2 +- 3 files changed, 24 insertions(+), 4 deletions(-) diff --git a/gns3server/controller/export_project.py b/gns3server/controller/export_project.py index 6fb0dd64..25c167e2 100644 --- a/gns3server/controller/export_project.py +++ b/gns3server/controller/export_project.py @@ -136,6 +136,8 @@ def _export_project_file(project, path, z, include_images, keep_compute_id, allo if "topology" in topology: if "nodes" in topology["topology"]: for node in topology["topology"]["nodes"]: + if node["node_type"] == "virtualbox" and node.get("properties", {}).get("linked_clone"): + raise aiohttp.web.HTTPConflict(text="Topology with a linked {} clone could not be exported. Use qemu instead.".format(node["node_type"])) if not allow_all_nodes and node["node_type"] in ["virtualbox", "vmware", "cloud"]: raise aiohttp.web.HTTPConflict(text="Topology with a {} could not be exported".format(node["node_type"])) diff --git a/tests/controller/test_export_project.py b/tests/controller/test_export_project.py index da7c3c1d..2b6b6610 100644 --- a/tests/controller/test_export_project.py +++ b/tests/controller/test_export_project.py @@ -190,9 +190,9 @@ def test_export_disallow_some_type(tmpdir, project, async_run): topology = { "topology": { "nodes": [ - { - "node_type": "virtualbox" - } + { + "node_type": "cloud" + } ] } } @@ -204,6 +204,24 @@ def test_export_disallow_some_type(tmpdir, project, async_run): z = async_run(export_project(project, str(tmpdir))) z = async_run(export_project(project, str(tmpdir), allow_all_nodes=True)) + # VirtualBox is always disallowed + topology = { + "topology": { + "nodes": [ + { + "node_type": "virtualbox", + "properties": { + "linked_clone": True + } + } + ] + } + } + with open(os.path.join(path, "test.gns3"), 'w+') as f: + json.dump(topology, f) + with pytest.raises(aiohttp.web.HTTPConflict): + z = async_run(export_project(project, str(tmpdir), allow_all_nodes=True)) + def test_export_fix_path(tmpdir, project, async_run): """ diff --git a/tests/controller/test_project.py b/tests/controller/test_project.py index 1fec7320..4422c0d1 100644 --- a/tests/controller/test_project.py +++ b/tests/controller/test_project.py @@ -427,7 +427,7 @@ def test_duplicate(project, async_run, controller): remote_vpcs = async_run(project.add_node(compute, "test", None, node_type="vpcs", properties={"startup_config": "test.cfg"})) # We allow node not allowed for standard import / export - remote_virtualbox = async_run(project.add_node(compute, "test", None, node_type="virtualbox", properties={"startup_config": "test.cfg"})) + remote_virtualbox = async_run(project.add_node(compute, "test", None, node_type="vmware", properties={"startup_config": "test.cfg"})) new_project = async_run(project.duplicate(name="Hello")) assert new_project.id != project.id From b7e5c08fdfce4451cec99c50c1a8361d9fb7e904 Mon Sep 17 00:00:00 2001 From: Julien Duponchelle Date: Wed, 15 Feb 2017 12:58:12 +0100 Subject: [PATCH 08/15] Display git version in commit --- gns3server/version.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/gns3server/version.py b/gns3server/version.py index fda1c3dd..34300d3c 100644 --- a/gns3server/version.py +++ b/gns3server/version.py @@ -24,4 +24,16 @@ # number has been incremented) __version__ = "2.0.0dev8" + +# If it's a git checkout try to add the commit +if "dev" in __version__: + try: + import os + import subprocess + if os.path.exists(os.path.join(os.path.dirname(os.path.abspath(__file__)), "..", ".git")): + r = subprocess.run(["git", "rev-parse", "--short", "HEAD"], stdout=subprocess.PIPE).stdout.decode().strip("\n") + __version__ += "-" + r + except Exception as e: + print(e) + __version_info__ = (2, 0, 0, -99) From a2337ed6c65cb8985e7bb14aef67fda3eff82482 Mon Sep 17 00:00:00 2001 From: Julien Duponchelle Date: Wed, 15 Feb 2017 16:41:23 +0100 Subject: [PATCH 09/15] Force installation of last aiohttp --- requirements.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/requirements.txt b/requirements.txt index f79cf434..629ad599 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,7 +1,7 @@ jsonschema>=2.4.0 -aiohttp>=1.2.0 +aiohttp>=1.3.1 aiohttp_cors>=0.4.0 -yarl>=0.8.1 +yarl>=0.9.6 typing>=3.5.3.0 # Otherwise yarl fail with python 3.4 Jinja2>=2.7.3 raven>=5.23.0 From 897c9cb42c24005076f78d8dc9d7d9b6cd6cc977 Mon Sep 17 00:00:00 2001 From: Julien Duponchelle Date: Wed, 15 Feb 2017 19:31:18 +0100 Subject: [PATCH 10/15] Improve docker container for development --- Dockerfile | 2 +- README.rst | 4 ++-- scripts/docker_dev_server.sh | 23 +++++++++++++++++++++++ 3 files changed, 26 insertions(+), 3 deletions(-) create mode 100644 scripts/docker_dev_server.sh diff --git a/Dockerfile b/Dockerfile index 5f6dcc4a..fec7d333 100644 --- a/Dockerfile +++ b/Dockerfile @@ -31,4 +31,4 @@ RUN pip3 install -r /server/requirements.txt EXPOSE 3080 -ENTRYPOINT python3 -m gns3server --local +CMD python3 -m gns3server --local diff --git a/README.rst b/README.rst index 6da27c4f..e3ebfde5 100644 --- a/README.rst +++ b/README.rst @@ -77,8 +77,8 @@ Docker container For development you can run the GNS3 server in a container .. code:: bash - docker build -t gns3-server . - docker run -i --expose=8001 -p 8001:8001/tcp -t gns3-server python3 -m gns3server --local --port 8001 + + bash scripts/docker_dev_server.sh Run as daemon (Unix only) diff --git a/scripts/docker_dev_server.sh b/scripts/docker_dev_server.sh new file mode 100644 index 00000000..a2f6e784 --- /dev/null +++ b/scripts/docker_dev_server.sh @@ -0,0 +1,23 @@ +#!/bin/sh +# +# Copyright (C) 2016 GNS3 Technologies Inc. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# A docker server use for localy test a remote GNS3 server + +docker build -t gns3-server . +docker run -i -h gns3vm -p 8001:8001/tcp -t gns3-server python3 -m gns3server --local --port 8001 + + From 10b039074f8aa164a0ecf7d1c8be17af39ba6a82 Mon Sep 17 00:00:00 2001 From: Julien Duponchelle Date: Wed, 15 Feb 2017 19:31:38 +0100 Subject: [PATCH 11/15] Avoid a crash in some conditions when reading the serial console --- gns3server/utils/asyncio/serial.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/gns3server/utils/asyncio/serial.py b/gns3server/utils/asyncio/serial.py index 48d12bc0..c118a87e 100644 --- a/gns3server/utils/asyncio/serial.py +++ b/gns3server/utils/asyncio/serial.py @@ -34,6 +34,7 @@ class SerialReaderWriterProtocol(asyncio.Protocol): def __init__(self): self._output = asyncio.StreamReader() + self._closed = False self.transport = None def read(self, n=-1): @@ -54,9 +55,11 @@ class SerialReaderWriterProtocol(asyncio.Protocol): self.transport = transport def data_received(self, data): - self._output.feed_data(data) + if not self._closed: + self._output.feed_data(data) def close(self): + self._closed = True self._output.feed_eof() From 8d2c27eafdb4c47dc3b42fa475d0163e67a88a69 Mon Sep 17 00:00:00 2001 From: Julien Duponchelle Date: Wed, 15 Feb 2017 20:10:41 +0100 Subject: [PATCH 12/15] Lock aiohttp to see if it's the reason of Unkown error from Qt --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 629ad599..222e4b5a 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,5 @@ jsonschema>=2.4.0 -aiohttp>=1.3.1 +aiohttp==1.2.0 aiohttp_cors>=0.4.0 yarl>=0.9.6 typing>=3.5.3.0 # Otherwise yarl fail with python 3.4 From 0f33448af2f433fa5f1299b9a0e6638d9059c035 Mon Sep 17 00:00:00 2001 From: Julien Duponchelle Date: Thu, 16 Feb 2017 11:19:27 +0100 Subject: [PATCH 13/15] 2.0.0 beta 4 --- CHANGELOG | 35 ++++++++++++++++++++++++++++++++++- gns3server/version.py | 2 +- 2 files changed, 35 insertions(+), 2 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index f598184c..9762117b 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,38 @@ # Change Log +## 2.0.0 beta 4 16/02/2017 + +* Lock aiohttp to 1.2.0 because 1.3 create bug with Qt +* Avoid a crash in some conditions when reading the serial console +* Disallow export of project with VirtualBox linked clone +* Fix linked_clone property lost during topology convert +* Catch permission error when restoring a snapshot +* Fix a rare crash when closing a project +* Fix error when you have error on your filesystem during project convertion +* Catch error when we can't access to a unix socket +* If we can't resolve compute name return 0.0.0.0 +* Raise an error if you put an invalid key in node name +* Improve a lot project loading speed +* Fix a potential crash +* Fix the server don't start if a remote is unavailable +* Do not crash if you pass {name} in name +* Fix import/export of dynamips configuration +* Simplify conversion process from 1.3 to 2.0 +* Prevent corruption of VM in VirtualBox when using linked clone +* Fix creation of qemu img +* Fix rare race condition when stopping ubridge +* Prevent renaming of a running VirtualBox linked VM +* Avoid crash when you broke your system permissions +* Do not crash when you broke permission on your file system during execution +* Fix a crash when you broke permission on your file system +* Fix a rare race condition when exporting debug informations +* Do not try to start the GNS3 VM if the name is none +* Fix version check for VPCS +* Fix pcap for PPP link with IOU +* Correct link are not connected to the correct ethernet switch port after conversion +* Fix an error if you don't have permissions on your symbols directory +* Fix an error when converting some topologies from 1.3 + ## 2.0.0 beta 3 19/01/2017 * Force the dependency on typing because otherwise it's broke on 3.4 @@ -45,7 +78,7 @@ * Replace JSONDecodeError by ValueError (Python 3.4 compatibility) * Catch an error when we can't create the IOU directory -## 1.5.3 12/01/2016 +## 1.5.3 12/01/2017 * Fix sporadically systemd is unable to start gns3-server diff --git a/gns3server/version.py b/gns3server/version.py index 34300d3c..5e460b9c 100644 --- a/gns3server/version.py +++ b/gns3server/version.py @@ -23,7 +23,7 @@ # or negative for a release candidate or beta (after the base version # number has been incremented) -__version__ = "2.0.0dev8" +__version__ = "2.0.0b4" # If it's a git checkout try to add the commit if "dev" in __version__: From 5796f47a55faa0ad5d23e8130be5b2914636127a Mon Sep 17 00:00:00 2001 From: Julien Duponchelle Date: Thu, 16 Feb 2017 11:21:39 +0100 Subject: [PATCH 14/15] Crash report key for b4 --- gns3server/crash_report.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gns3server/crash_report.py b/gns3server/crash_report.py index ecd23733..7edc2865 100644 --- a/gns3server/crash_report.py +++ b/gns3server/crash_report.py @@ -53,7 +53,7 @@ class CrashReport: Report crash to a third party service """ - DSN = "sync+https://b7430bad849c4b88b3a928032d6cce5e:f140bfdd2ebb4bf4b929c002b45b2357@sentry.io/38482" + DSN = "sync+https://83564b27a6f6475488a3eb74c78f1760:ed5ac7c6d3f7428d960a84da98450b69@sentry.io/38482" if hasattr(sys, "frozen"): cacert = get_resource("cacert.pem") if cacert is not None and os.path.isfile(cacert): From a730fce5143429d6cec9bd42ac1fa18f42f10ac5 Mon Sep 17 00:00:00 2001 From: Julien Duponchelle Date: Thu, 16 Feb 2017 11:23:19 +0100 Subject: [PATCH 15/15] 2.0.0dev9 --- gns3server/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gns3server/version.py b/gns3server/version.py index 5e460b9c..f30973c3 100644 --- a/gns3server/version.py +++ b/gns3server/version.py @@ -23,7 +23,7 @@ # or negative for a release candidate or beta (after the base version # number has been incremented) -__version__ = "2.0.0b4" +__version__ = "2.0.0dev9" # If it's a git checkout try to add the commit if "dev" in __version__: