diff --git a/CHANGELOG b/CHANGELOG index a234b157..5ce33d3c 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -140,6 +140,26 @@ * Implement #1153 into 2.2 branch. * Pin prompt-toolkit to latest version 1.0.15 +## 2.1.14 27/02/2019 + +* Fix issue when setting cpuid.corespersocket for the GNS3 VM. Fixes https://github.com/GNS3/gns3-gui/issues/2723 +* Bump ACPI Shutdown Timeout to 120 seconds. Ref #1536 + +## 2.1.13 26/02/2019 + +* Force jsonschema dependency to 2.6.0 +* Less aggressive connections to uBridge. Ref #1289 +* Fix topology images (Pictures) disappearing from projects. Fixes #1514. +* Reset MAC addresses when duplicating a project. Fixes #1522 +* Fix API call to create a node from an appliance doesn't return the new node data. Fixes #1527 +* Detect invalid environment variable and send a warning when creating a Docker node. Ref #2683 +* Do not export/import symlinks for projects. Fixes #2699 +* Fix symlink not being created for duplicated IOU devices. Fixes https://github.com/GNS3/gns3-gui/issues/2699 +* Configure coresPerSocket value in VMX file for the GNS3 VM. Fixes https://github.com/GNS3/gns3-gui/issues/2688 +* Count logical CPUs to detect if the number of vCPUs is too high when configuring the GNS3 VM. Fixes #2688. +* Add explicit error when trying to pull a Docker image from Docker Hub without Internet access. Fixes #1506. +* Fixes double display output in GRUB in QEMU v3.1. Fixes #1516. + ## 2.1.12 23/01/2019 * Tune how to get the size of SVG images. Ref https://github.com/GNS3/gns3-gui/issues/2674. diff --git a/gns3server/compute/qemu/__init__.py b/gns3server/compute/qemu/__init__.py index cf37224b..922064e8 100644 --- a/gns3server/compute/qemu/__init__.py +++ b/gns3server/compute/qemu/__init__.py @@ -100,10 +100,10 @@ class Qemu(BaseManager): paths.update(["/usr/bin", "/usr/local/bin", "/opt/local/bin"]) try: exec_dir = os.path.dirname(os.path.abspath(sys.executable)) - paths.add(os.path.abspath(os.path.join(exec_dir, "../Resources/qemu/bin/"))) + paths.add(os.path.abspath(os.path.join(exec_dir, "qemu/bin"))) # If the user run the server by hand from outside except FileNotFoundError: - paths.add("/Applications/GNS3.app/Contents/Resources/qemu/bin") + paths.add("/Applications/GNS3.app/Contents/MacOS/qemu/bin") return paths @staticmethod diff --git a/gns3server/compute/qemu/qemu_vm.py b/gns3server/compute/qemu/qemu_vm.py index 19a19241..a7f21ada 100644 --- a/gns3server/compute/qemu/qemu_vm.py +++ b/gns3server/compute/qemu/qemu_vm.py @@ -984,7 +984,7 @@ class QemuVM(BaseNode): log.info("QEMU process has stopped, return code: %d", returncode) await self.stop() # A return code of 1 seem fine on Windows - if returncode != 0 and (returncode != 1 or not sys.platform.startswith("win")): + if returncode != 0 and (not sys.platform.startswith("win") or returncode != 1): self.project.emit("log.error", {"message": "QEMU process has stopped, return code: {}\n{}".format(returncode, self.read_stdout())}) async def stop(self): @@ -1013,7 +1013,7 @@ class QemuVM(BaseNode): if self.on_close == "shutdown_signal": await self._control_vm("system_powerdown") - await gns3server.utils.asyncio.wait_for_process_termination(self._process, timeout=30) + await gns3server.utils.asyncio.wait_for_process_termination(self._process, timeout=120) else: self._process.terminate() await gns3server.utils.asyncio.wait_for_process_termination(self._process, timeout=3) diff --git a/gns3server/controller/drawing.py b/gns3server/controller/drawing.py index 58605e6d..4ef324b4 100644 --- a/gns3server/controller/drawing.py +++ b/gns3server/controller/drawing.py @@ -37,7 +37,7 @@ class Drawing: text, images, rectangle... They are pure SVG elements. """ - def __init__(self, project, drawing_id=None, svg="", x=0, y=0, z=2, rotation=0): + def __init__(self, project, drawing_id=None, svg="", x=0, y=0, z=2, locked=False, rotation=0): self._project = project if drawing_id is None: self._id = str(uuid.uuid4()) @@ -49,6 +49,7 @@ class Drawing: self._y = y self._z = z self._rotation = rotation + self._locked = locked @property def id(self): @@ -157,6 +158,14 @@ class Drawing: def z(self, val): self._z = val + @property + def locked(self): + return self._locked + + @locked.setter + def locked(self, val): + self._locked = val + @property def rotation(self): return self._rotation @@ -198,6 +207,7 @@ class Drawing: "x": self._x, "y": self._y, "z": self._z, + "locked": self._locked, "rotation": self._rotation, "svg": self._svg } @@ -207,6 +217,7 @@ class Drawing: "x": self._x, "y": self._y, "z": self._z, + "locked": self._locked, "rotation": self._rotation, "svg": self.svg } diff --git a/gns3server/controller/gns3vm/vmware_gns3_vm.py b/gns3server/controller/gns3vm/vmware_gns3_vm.py index cdc3cff4..118c9e44 100644 --- a/gns3server/controller/gns3vm/vmware_gns3_vm.py +++ b/gns3server/controller/gns3vm/vmware_gns3_vm.py @@ -73,11 +73,12 @@ class VMwareGNS3VM(BaseGNS3VM): if vcpus > available_vcpus: raise GNS3VMError("You have allocated too many vCPUs for the GNS3 VM! (max available is {} vCPUs)".format(available_vcpus)) - cores_per_sockets = int(available_vcpus / psutil.cpu_count(logical=False)) try: pairs = VMware.parse_vmware_file(self._vmx_path) pairs["numvcpus"] = str(vcpus) - pairs["cpuid.coresPerSocket"] = str(cores_per_sockets) + cores_per_sockets = int(available_vcpus / psutil.cpu_count(logical=False)) + if cores_per_sockets >= 1: + pairs["cpuid.corespersocket"] = str(cores_per_sockets) pairs["memsize"] = str(ram) VMware.write_vmx_file(self._vmx_path, pairs) log.info("GNS3 VM vCPU count set to {} and RAM amount set to {}".format(vcpus, ram)) diff --git a/gns3server/controller/node.py b/gns3server/controller/node.py index 60e70c01..fb8576a3 100644 --- a/gns3server/controller/node.py +++ b/gns3server/controller/node.py @@ -34,7 +34,7 @@ log = logging.getLogger(__name__) class Node: # This properties are used only on controller and are not forwarded to the compute - CONTROLLER_ONLY_PROPERTIES = ["x", "y", "z", "width", "height", "symbol", "label", "console_host", + CONTROLLER_ONLY_PROPERTIES = ["x", "y", "z", "locked", "width", "height", "symbol", "label", "console_host", "port_name_format", "first_port_name", "port_segment_size", "ports", "category", "console_auto_start"] @@ -74,6 +74,7 @@ class Node: self._x = 0 self._y = 0 self._z = 1 # default z value is 1 + self._locked = False self._ports = None self._symbol = None self._custom_adapters = [] @@ -236,6 +237,14 @@ class Node: def z(self, val): self._z = val + @property + def locked(self): + return self._locked + + @locked.setter + def locked(self, val): + self._locked = val + @property def width(self): return self._width @@ -681,6 +690,7 @@ class Node: "x": self._x, "y": self._y, "z": self._z, + "locked": self._locked, "width": self._width, "height": self._height, "symbol": self._symbol, @@ -708,6 +718,7 @@ class Node: "x": self._x, "y": self._y, "z": self._z, + "locked": self._locked, "width": self._width, "height": self._height, "symbol": self._symbol, diff --git a/gns3server/controller/project.py b/gns3server/controller/project.py index a2208877..16975a25 100644 --- a/gns3server/controller/project.py +++ b/gns3server/controller/project.py @@ -1075,6 +1075,7 @@ class Project: data['x'] = x data['y'] = y data['z'] = z + data['locked'] = False # duplicated node must not be locked new_node_uuid = str(uuid.uuid4()) new_node = await self.add_node( node.compute, diff --git a/gns3server/controller/topology.py b/gns3server/controller/topology.py index 50f150ed..bdde30d9 100644 --- a/gns3server/controller/topology.py +++ b/gns3server/controller/topology.py @@ -160,7 +160,7 @@ def load_topology(path): topo = _convert_2_1_0(topo, path) # Version GNS3 2.2 dev (for project created with 2.2dev). - # Appliance ID has been repleace by Template ID + # Appliance ID has been replaced by Template ID if topo["revision"] == 9: for node in topo.get("topology", {}).get("nodes", []): if "appliance_id" in node: @@ -177,7 +177,7 @@ def load_topology(path): try: with open(path, "w+", encoding="utf-8") as f: json.dump(topo, f, indent=4, sort_keys=True) - except (OSError) as e: + except OSError as e: raise aiohttp.web.HTTPConflict(text="Can't write the topology {}: {}".format(path, str(e))) return topo diff --git a/gns3server/schemas/drawing.py b/gns3server/schemas/drawing.py index b15a5e3c..37f8fd6c 100644 --- a/gns3server/schemas/drawing.py +++ b/gns3server/schemas/drawing.py @@ -47,6 +47,10 @@ DRAWING_OBJECT_SCHEMA = { "description": "Z property", "type": "integer" }, + "locked": { + "description": "Whether the element locked or not", + "type": "boolean" + }, "rotation": { "description": "Rotation of the element", "type": "integer", diff --git a/gns3server/schemas/node.py b/gns3server/schemas/node.py index 55ae1d05..5d3cc11a 100644 --- a/gns3server/schemas/node.py +++ b/gns3server/schemas/node.py @@ -193,6 +193,10 @@ NODE_OBJECT_SCHEMA = { "description": "Z position of the node", "type": "integer" }, + "locked": { + "description": "Whether the element locked or not", + "type": "boolean" + }, "port_name_format": { "description": "Formating for port name {0} will be replace by port number", "type": "string" diff --git a/gns3server/version.py b/gns3server/version.py index d2b3ff3a..dfb19bce 100644 --- a/gns3server/version.py +++ b/gns3server/version.py @@ -23,8 +23,8 @@ # or negative for a release candidate or beta (after the base version # number has been incremented) -__version__ = "2.2.0a1" -__version_info__ = (2, 2, 0, -99) +__version__ = "2.2.0dev6" +__version_info__ = (2, 2, 0, 99) # If it's a git checkout try to add the commit if "dev" in __version__: diff --git a/requirements.txt b/requirements.txt index 36bb8b4a..207656e1 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,4 @@ -jsonschema>=2.4.0 +jsonschema==2.6.0 # pyup: ignore aiohttp==3.5.4 aiohttp-cors==0.7.0 aiofiles==0.4.0 diff --git a/tests/controller/test_drawing.py b/tests/controller/test_drawing.py index 4a934923..5b5ffbfb 100644 --- a/tests/controller/test_drawing.py +++ b/tests/controller/test_drawing.py @@ -56,6 +56,7 @@ def test_json(project): "x": i.x, "y": i.y, "z": i.z, + "locked": i.locked, "svg": i.svg, "rotation": i.rotation } @@ -65,6 +66,7 @@ def test_json(project): "y": i.y, "z": i.z, "rotation": i.rotation, + "locked": i.locked, "svg": i.svg } diff --git a/tests/controller/test_node.py b/tests/controller/test_node.py index 7ed82881..e72b1db4 100644 --- a/tests/controller/test_node.py +++ b/tests/controller/test_node.py @@ -135,6 +135,7 @@ def test_json(node, compute): "x": node.x, "y": node.y, "z": node.z, + "locked": node.locked, "width": node.width, "height": node.height, "symbol": node.symbol, @@ -167,6 +168,7 @@ def test_json(node, compute): "x": node.x, "y": node.y, "z": node.z, + "locked": node.locked, "width": node.width, "height": node.height, "symbol": node.symbol,