From 2ace014a3c16478a8ffc13056bb9b88597f90537 Mon Sep 17 00:00:00 2001 From: Julien Duponchelle Date: Wed, 4 Feb 2015 17:18:53 +0100 Subject: [PATCH] Cleanup old temporary project at startup --- gns3server/main.py | 4 ++++ gns3server/modules/project.py | 31 ++++++++++++++++++++++++++-- tests/modules/test_project.py | 38 ++++++++++++++++++++++++++++++++++- 3 files changed, 70 insertions(+), 3 deletions(-) diff --git a/gns3server/main.py b/gns3server/main.py index 59ca9010..7b0bd3a7 100644 --- a/gns3server/main.py +++ b/gns3server/main.py @@ -26,6 +26,8 @@ from gns3server.server import Server from gns3server.web.logger import init_logger from gns3server.version import __version__ from gns3server.config import Config +from gns3server.modules.project import Project + import logging log = logging.getLogger(__name__) @@ -140,6 +142,8 @@ def main(): log.critical("The current working directory doesn't exist") return + Project.clean_project_directory() + host = server_config["host"] port = int(server_config["port"]) server = Server(host, port) diff --git a/gns3server/modules/project.py b/gns3server/modules/project.py index f78e78f4..55002bca 100644 --- a/gns3server/modules/project.py +++ b/gns3server/modules/project.py @@ -58,7 +58,6 @@ class Project: if config.get("local", False) is False: raise aiohttp.web.HTTPForbidden(text="You are not allowed to modifiy the project directory location") - self._temporary = temporary self._vms = set() self._vms_to_destroy = set() self._path = os.path.join(self._location, self._uuid) @@ -66,9 +65,11 @@ class Project: os.makedirs(os.path.join(self._path, "vms"), exist_ok=True) except OSError as e: raise aiohttp.web.HTTPInternalServerError(text="Could not create project directory: {}".format(e)) + self.temporary = temporary log.debug("Create project {uuid} in directory {path}".format(path=self._path, uuid=self._uuid)) - def _get_default_project_directory(self): + @classmethod + def _get_default_project_directory(cls): """ Return the default location for the project directory depending of the operating system @@ -109,8 +110,21 @@ class Project: @temporary.setter def temporary(self, temporary): + if hasattr(self, 'temporary') and temporary == self._temporary: + return + self._temporary = temporary + if self._temporary: + try: + with open(os.path.join(self._path, ".gns3_temporary"), 'w+') as f: + f.write("1") + except OSError as e: + raise aiohttp.web.HTTPInternalServerError(text="Could not create temporary project: {}".format(e)) + else: + if os.path.exists(os.path.join(self._path, ".gns3_temporary")): + os.remove(os.path.join(self._path, ".gns3_temporary")) + def vm_working_directory(self, vm): """ Return a working directory for a specific VM. @@ -222,3 +236,16 @@ class Project: """Remove project from disk""" yield from self._close_and_clean(True) + + @classmethod + def clean_project_directory(cls): + """At startup drop old temporary project. After a crash for example""" + + config = Config.instance().get_section_config("Server") + directory = config.get("project_directory", cls._get_default_project_directory()) + if os.path.exists(directory): + for project in os.listdir(directory): + path = os.path.join(directory, project) + if os.path.exists(os.path.join(path, ".gns3_temporary")): + log.warning("Purge old temporary project {}".format(project)) + shutil.rmtree(path) diff --git a/tests/modules/test_project.py b/tests/modules/test_project.py index 3c93da88..25919d68 100644 --- a/tests/modules/test_project.py +++ b/tests/modules/test_project.py @@ -21,6 +21,7 @@ import asyncio import pytest import aiohttp import shutil +from uuid import uuid4 from unittest.mock import patch from gns3server.modules.project import Project @@ -53,11 +54,21 @@ def test_path(tmpdir): assert p.path == os.path.join(str(tmpdir), p.uuid) assert os.path.exists(os.path.join(str(tmpdir), p.uuid)) assert os.path.exists(os.path.join(str(tmpdir), p.uuid, 'vms')) + assert not os.path.exists(os.path.join(p.path, '.gns3_temporary')) def test_temporary_path(): - p = Project() + p = Project(temporary=True) assert os.path.exists(p.path) + assert os.path.exists(os.path.join(p.path, '.gns3_temporary')) + + +def test_remove_temporary_flag(): + p = Project(temporary=True) + assert os.path.exists(p.path) + assert os.path.exists(os.path.join(p.path, '.gns3_temporary')) + p.temporary = False + assert not os.path.exists(os.path.join(p.path, '.gns3_temporary')) def test_changing_location_not_allowed(tmpdir): @@ -164,3 +175,28 @@ def test_get_default_project_directory(): path = os.path.normpath(os.path.expanduser("~/GNS3/projects")) assert project._get_default_project_directory() == path assert os.path.exists(path) + + +def test_clean_project_directory(tmpdir): + + # A non anonymous project with uuid. + project1 = tmpdir / uuid4() + project1.mkdir() + + # A non anonymous project. + oldproject = tmpdir / uuid4() + oldproject.mkdir() + + # an anonymous project + project2 = tmpdir / uuid4() + project2.mkdir() + tmp = (project2 / ".gns3_temporary") + with open(str(tmp), 'w+') as f: + f.write("1") + + with patch("gns3server.config.Config.get_section_config", return_value={"project_directory": str(tmpdir)}): + Project.clean_project_directory() + + assert os.path.exists(str(project1)) + assert os.path.exists(str(oldproject)) + assert not os.path.exists(str(project2))