diff --git a/CHANGELOG b/CHANGELOG index 91835c49..abf6dca2 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,12 @@ # Change Log +## 1.3.3 14/05/15 + +* Check for empty iourc path. +* Fixes bugs with IOS router configs. Fixes #354. +* Use a temporary directory as egg cache +* Catch crash error in IOU in case of permission denied + ## 1.3.3rc1 07/05/2015 * Return an error if an adapter slot doesn't exist on an IOS router. diff --git a/gns3server/crash_report.py b/gns3server/crash_report.py index 89800189..23ee7bc0 100644 --- a/gns3server/crash_report.py +++ b/gns3server/crash_report.py @@ -40,7 +40,7 @@ class CrashReport: Report crash to a third party service """ - DSN = "sync+https://45147533567b4d529ca09c093758681f:12d8b456cdb34d23aba771325aa64ee6@app.getsentry.com/38482" + DSN = "sync+https://9e6f04df72c74b6894a6dcd2928d069e:2035d1beb1654136b170f1e91f05ee51@app.getsentry.com/38482" if hasattr(sys, "frozen"): cacert = os.path.join(os.getcwd(), "cacert.pem") if os.path.isfile(cacert): diff --git a/gns3server/handlers/api/dynamips_vm_handler.py b/gns3server/handlers/api/dynamips_vm_handler.py index 6d46fc86..6a4f41ec 100644 --- a/gns3server/handlers/api/dynamips_vm_handler.py +++ b/gns3server/handlers/api/dynamips_vm_handler.py @@ -368,15 +368,16 @@ class DynamipsVMHandler: else: # nvram doesn't contain anything if the router has not been started at least once # in this case just use the startup-config file - startup_config_path = os.path.join(module_workdir, vm.startup_config) - if os.path.exists(startup_config_path): - try: - with open(startup_config_path, "rb") as f: - content = f.read().decode("utf-8", errors='replace') - if content: - result["startup_config_content"] = content - except OSError as e: - raise DynamipsError("Could not read the startup-config {}: {}".format(startup_config_path, e)) + if vm.startup_config: + startup_config_path = os.path.join(module_workdir, vm.startup_config) + if os.path.isfile(startup_config_path): + try: + with open(startup_config_path, "rb") as f: + content = f.read().decode("utf-8", errors='replace') + if content: + result["startup_config_content"] = content + except OSError as e: + raise DynamipsError("Could not read the startup-config {}: {}".format(startup_config_path, e)) if private_config_base64: private_config_content = base64.b64decode(private_config_base64).decode("utf-8", errors='replace') @@ -384,15 +385,16 @@ class DynamipsVMHandler: else: # nvram doesn't contain anything if the router has not been started at least once # in this case just use the private-config file - private_config_path = os.path.join(module_workdir, vm.private_config) - if os.path.exists(private_config_path): - try: - with open(private_config_path, "rb") as f: - content = f.read().decode("utf-8", errors='replace') - if content: - result["private_config_content"] = content - except OSError as e: - raise DynamipsError("Could not read the private-config {}: {}".format(private_config_path, e)) + if vm.private_config: + private_config_path = os.path.join(module_workdir, vm.private_config) + if os.path.isfile(private_config_path): + try: + with open(private_config_path, "rb") as f: + content = f.read().decode("utf-8", errors='replace') + if content: + result["private_config_content"] = content + except OSError as e: + raise DynamipsError("Could not read the private-config {}: {}".format(private_config_path, e)) response.set_status(200) response.json(result) diff --git a/gns3server/main.py b/gns3server/main.py index 4c964408..f000c7ca 100644 --- a/gns3server/main.py +++ b/gns3server/main.py @@ -20,6 +20,14 @@ Entry point of the server. It's support daemonize the process """ +# WARNING +# Due to buggy user machines we choose to put this as the first loading modules +# otherwise the egg cache is initialized in his standard location and +# if is not writetable the application crash. It's the user fault +# because one day the user as used sudo to run an egg and break his +# filesystem permissions, but it's a common mistake. +import gns3server.utils.get_resource + import os import sys diff --git a/gns3server/modules/dynamips/__init__.py b/gns3server/modules/dynamips/__init__.py index 38aeac83..a8bb51e2 100644 --- a/gns3server/modules/dynamips/__init__.py +++ b/gns3server/modules/dynamips/__init__.py @@ -535,17 +535,19 @@ class Dynamips(BaseManager): default_private_config_path = os.path.join(module_workdir, "configs", "i{}_private-config.cfg".format(vm.dynamips_id)) startup_config_path = settings.get("startup_config") + startup_config_content = settings.get("startup_config_content") if startup_config_path: yield from vm.set_configs(startup_config_path) - else: - startup_config_path = self._create_config(vm, default_startup_config_path, settings.get("startup_config_content")) + elif startup_config_content: + startup_config_path = self._create_config(vm, default_startup_config_path, startup_config_content) yield from vm.set_configs(startup_config_path) private_config_path = settings.get("private_config") + private_config_content = settings.get("private_config_content") if private_config_path: yield from vm.set_configs(vm.startup_config, private_config_path) - else: - private_config_path = self._create_config(vm, default_private_config_path, settings.get("private_config_content")) + elif private_config_content: + private_config_path = self._create_config(vm, default_private_config_path, private_config_content) yield from vm.set_configs(vm.startup_config, private_config_path) def _create_config(self, vm, path, content=None): diff --git a/gns3server/modules/iou/iou_vm.py b/gns3server/modules/iou/iou_vm.py index ae51f1c9..590925c4 100644 --- a/gns3server/modules/iou/iou_vm.py +++ b/gns3server/modules/iou/iou_vm.py @@ -433,11 +433,14 @@ class IOUVM(BaseVM): yield from self._library_check() - self._rename_nvram_file() + try: + self._rename_nvram_file() + except OSError as e: + raise IOUError("Could not rename nvram files: {}".format(e)) iourc_path = self.iourc_path - if iourc_path is None: - raise IOUError("Could not find a iourc file (IOU license)") + if not iourc_path: + raise IOUError("Could not find an iourc file (IOU license)") if not os.path.isfile(iourc_path): raise IOUError("The iourc path '{}' is not a regular file".format(iourc_path)) diff --git a/gns3server/utils/get_resource.py b/gns3server/utils/get_resource.py new file mode 100644 index 00000000..dae285fc --- /dev/null +++ b/gns3server/utils/get_resource.py @@ -0,0 +1,41 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2015 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 . + +import tempfile +import pkg_resources +import atexit +import logging + +log = logging.getLogger(__name__) + +try: + egg_cache_dir = tempfile.mkdtemp() + pkg_resources.set_extraction_path(egg_cache_dir) +except ValueError: + # If the path is already set the module throw an error + pass + + +@atexit.register +def clean_egg_cache(): + try: + import shutil + log.debug("Clean egg cache %s", egg_cache_dir) + shutil.rmtree(egg_cache_dir) + except Exception: + # We don't care if we can not cleanup + pass diff --git a/tests/modules/qemu/test_qemu_vm.py b/tests/modules/qemu/test_qemu_vm.py index 36cd9c47..ac939473 100644 --- a/tests/modules/qemu/test_qemu_vm.py +++ b/tests/modules/qemu/test_qemu_vm.py @@ -275,7 +275,7 @@ def test_build_command(vm, loop, fake_qemu_binary, port_manager): "-net", "none", "-device", - "e1000,mac=00:00:ab:0e:0f:00", + "e1000,mac=00:00:ab:0e:0f:00" ]