diff --git a/gns3server/handlers/api/project_handler.py b/gns3server/handlers/api/project_handler.py index a67d9c57..85257423 100644 --- a/gns3server/handlers/api/project_handler.py +++ b/gns3server/handlers/api/project_handler.py @@ -84,9 +84,11 @@ class ProjectHandler: project.name = request.json.get("name", project.name) project_path = request.json.get("path", project.path) if project_path != project.path: + old_path = project.path project.path = project_path for module in MODULES: yield from module.instance().project_moved(project) + yield from project.clean_old_path(old_path) # Very important we need to remove temporary flag after moving the project project.temporary = request.json.get("temporary", project.temporary) response.json(project) diff --git a/gns3server/modules/project.py b/gns3server/modules/project.py index 7018d1b7..0c87cc37 100644 --- a/gns3server/modules/project.py +++ b/gns3server/modules/project.py @@ -146,11 +146,15 @@ class Project: self._path = path self._update_temporary_file() - # The order of operation is important because we want to avoid losing - # data - if old_path: + @asyncio.coroutine + def clean_old_path(self, old_path): + """ + Called after a project location change. All the modules should + have been notified before + """ + if self._temporary: try: - shutil.rmtree(old_path) + yield from wait_run_in_executor(shutil.rmtree, old_path) except OSError as e: log.warn("Can't remove temporary directory {}: {}".format(old_path, e)) diff --git a/tests/handlers/api/test_project.py b/tests/handlers/api/test_project.py index cd0bc419..6f255221 100644 --- a/tests/handlers/api/test_project.py +++ b/tests/handlers/api/test_project.py @@ -20,6 +20,7 @@ This test suite check /project endpoint """ import uuid +import os from unittest.mock import patch from tests.utils import asyncio_patch @@ -85,18 +86,43 @@ def test_update_temporary_project(server): assert response.json["temporary"] is False -def test_update_path_project(server, tmpdir): +def test_update_path_project_temporary(server, tmpdir): + + os.makedirs(str(tmpdir / "a")) + os.makedirs(str(tmpdir / "b")) with patch("gns3server.modules.project.Project.is_local", return_value=True): - response = server.post("/projects", {"name": "first_name"}) + response = server.post("/projects", {"name": "first_name", "path": str(tmpdir / "a"), "temporary": True}) assert response.status == 201 assert response.json["name"] == "first_name" - query = {"name": "second_name", "path": str(tmpdir)} + query = {"name": "second_name", "path": str(tmpdir / "b")} response = server.put("/projects/{project_id}".format(project_id=response.json["project_id"]), query, example=True) assert response.status == 200 - assert response.json["path"] == str(tmpdir) + assert response.json["path"] == str(tmpdir / "b") + assert response.json["name"] == "second_name" + + assert not os.path.exists(str(tmpdir / "a")) + assert os.path.exists(str(tmpdir / "b")) + + +def test_update_path_project_non_temporary(server, tmpdir): + + os.makedirs(str(tmpdir / "a")) + os.makedirs(str(tmpdir / "b")) + + with patch("gns3server.modules.project.Project.is_local", return_value=True): + response = server.post("/projects", {"name": "first_name", "path": str(tmpdir / "a")}) + assert response.status == 201 + assert response.json["name"] == "first_name" + query = {"name": "second_name", "path": str(tmpdir / "b")} + response = server.put("/projects/{project_id}".format(project_id=response.json["project_id"]), query, example=True) + assert response.status == 200 + assert response.json["path"] == str(tmpdir / "b") assert response.json["name"] == "second_name" + assert os.path.exists(str(tmpdir / "a")) + assert os.path.exists(str(tmpdir / "b")) + def test_update_path_project_non_local(server, tmpdir): diff --git a/tests/modules/test_project.py b/tests/modules/test_project.py index c4eaee4b..68896361 100644 --- a/tests/modules/test_project.py +++ b/tests/modules/test_project.py @@ -73,10 +73,6 @@ def test_changing_path_temporary_flag(tmpdir): assert os.path.exists(os.path.join(p.path, ".gns3_temporary")) p.path = str(tmpdir) - p.temporary = False - assert not os.path.exists(os.path.join(p.path, ".gns3_temporary")) - assert not os.path.exists(os.path.join(str(tmpdir), ".gns3_temporary")) - assert not os.path.exists(original_path) def test_temporary_path():