From 0eaad579c21a79c5235dc8d516b7adfd4ddeade2 Mon Sep 17 00:00:00 2001 From: Jeremy Date: Wed, 25 Feb 2015 18:55:35 -0700 Subject: [PATCH] IOU + VirtualBox conversion of old projects. --- gns3server/modules/base_manager.py | 71 ++++++++++++++--------- gns3server/modules/dynamips/__init__.py | 4 +- gns3server/modules/iou/__init__.py | 8 ++- gns3server/modules/qemu/__init__.py | 24 ++++---- gns3server/modules/virtualbox/__init__.py | 8 ++- gns3server/modules/vpcs/__init__.py | 7 ++- tests/modules/iou/test_iou_vm.py | 4 +- tests/modules/qemu/test_qemu_manager.py | 4 +- 8 files changed, 79 insertions(+), 51 deletions(-) diff --git a/gns3server/modules/base_manager.py b/gns3server/modules/base_manager.py index 8845d4cb..82d3104d 100644 --- a/gns3server/modules/base_manager.py +++ b/gns3server/modules/base_manager.py @@ -44,6 +44,8 @@ class BaseManager: Responsible of management of a VM pool """ + _convert_lock = asyncio.Lock() + def __init__(self): self._vms = {} @@ -146,6 +148,45 @@ class BaseManager: return vm + @asyncio.coroutine + def _convert_old_project(self, project, legacy_id, name): + """ + Convert project made before version 1.3 + + :param project: Project instance + :param legacy_id: old identifier + :param name: VM name + + :returns: new VM identifier + """ + + vm_id = str(uuid4()) + if hasattr(self, "get_legacy_vm_workdir"): + # move old project VM files to a new location + log.info("Converting old project...") + project_name = os.path.basename(project.path) + project_files_dir = os.path.join(project.path, "{}-files".format(project_name)) + legacy_vm_dir = self.get_legacy_vm_workdir(legacy_id, name) + vm_working_dir = os.path.join(project_files_dir, legacy_vm_dir) + new_vm_working_dir = os.path.join(project.path, "project-files", self.module_name.lower(), vm_id) + try: + log.info('Moving "{}" to "{}"'.format(vm_working_dir, new_vm_working_dir)) + yield from wait_run_in_executor(shutil.move, vm_working_dir, new_vm_working_dir) + except OSError as e: + raise aiohttp.web.HTTPInternalServerError(text="Could not move VM working directory: {} to {} {}".format(vm_working_dir, new_vm_working_dir, e)) + + try: + os.rmdir(os.path.dirname(vm_working_dir)) + except OSError: + pass + + try: + os.rmdir(project_files_dir) + except OSError: + pass + + return vm_id + @asyncio.coroutine def create_vm(self, name, project_id, vm_id, *args, **kwargs): """ @@ -157,34 +198,10 @@ class BaseManager: """ project = ProjectManager.instance().get_project(project_id) - # If it's not an UUID, old topology - if vm_id and (isinstance(vm_id, int) or len(vm_id) != 36): - legacy_id = int(vm_id) - vm_id = str(uuid4()) - if hasattr(self, "get_legacy_vm_workdir_name"): - # move old project VM files to a new location - - log.info("Converting old project...") - project_name = os.path.basename(project.path) - project_files_dir = os.path.join(project.path, "{}-files".format(project_name)) - module_path = os.path.join(project_files_dir, self.module_name.lower()) - vm_working_dir = os.path.join(module_path, self.get_legacy_vm_workdir_name(legacy_id)) - new_vm_working_dir = os.path.join(project.path, "project-files", self.module_name.lower(), vm_id) - try: - yield from wait_run_in_executor(shutil.move, vm_working_dir, new_vm_working_dir) - except OSError as e: - raise aiohttp.web.HTTPInternalServerError(text="Could not move VM working directory: {} to {} {}".format(vm_working_dir, new_vm_working_dir, e)) - - try: - os.rmdir(module_path) - except OSError: - pass - - try: - os.rmdir(project_files_dir) - except OSError: - pass + if vm_id and isinstance(vm_id, int): + with (yield from BaseManager._convert_lock): + vm_id = yield from self._convert_old_project(project, vm_id, name) if not vm_id: vm_id = str(uuid4()) diff --git a/gns3server/modules/dynamips/__init__.py b/gns3server/modules/dynamips/__init__.py index 55376ed2..004dc14a 100644 --- a/gns3server/modules/dynamips/__init__.py +++ b/gns3server/modules/dynamips/__init__.py @@ -105,7 +105,7 @@ class Dynamips(BaseManager): _VM_CLASS = DynamipsVM _DEVICE_CLASS = DynamipsDevice - ghost_ios_lock = asyncio.Lock() + _ghost_ios_lock = asyncio.Lock() def __init__(self): @@ -331,7 +331,7 @@ class Dynamips(BaseManager): ghost_ios_support = self.config.get_section_config("Dynamips").get("ghost_ios_support", True) if ghost_ios_support: - with (yield from Dynamips.ghost_ios_lock): + with (yield from Dynamips._ghost_ios_lock): yield from self._set_ghost_ios(vm) @asyncio.coroutine diff --git a/gns3server/modules/iou/__init__.py b/gns3server/modules/iou/__init__.py index 30d35915..1a7211e5 100644 --- a/gns3server/modules/iou/__init__.py +++ b/gns3server/modules/iou/__init__.py @@ -19,6 +19,7 @@ IOU server module. """ +import os import asyncio from ..base_manager import BaseManager @@ -63,12 +64,15 @@ class IOU(BaseManager): return self._used_application_ids.get(vm_id, 1) - def get_legacy_vm_workdir_name(legacy_vm_id): + @staticmethod + def get_legacy_vm_workdir(legacy_vm_id, name): """ Returns the name of the legacy working directory (pre 1.3) name for a VM. :param legacy_vm_id: legacy VM identifier (integer) + :param name: VM name (not used) + :returns: working directory name """ - return "device-{}".format(legacy_vm_id) + return os.path.join("iou", "device-{}".format(legacy_vm_id)) diff --git a/gns3server/modules/qemu/__init__.py b/gns3server/modules/qemu/__init__.py index 2d643204..aa9e2f90 100644 --- a/gns3server/modules/qemu/__init__.py +++ b/gns3server/modules/qemu/__init__.py @@ -34,17 +34,6 @@ from .qemu_vm import QemuVM class Qemu(BaseManager): _VM_CLASS = QemuVM - @staticmethod - def get_legacy_vm_workdir_name(legacy_vm_id): - """ - Returns the name of the legacy working directory name for a VM. - - :param legacy_vm_id: legacy VM identifier (integer) - :returns: working directory name - """ - - return "vm-{}".format(legacy_vm_id) - @staticmethod def binary_list(): """ @@ -108,3 +97,16 @@ class Qemu(BaseManager): raise QemuError("Could not determine the Qemu version for {}".format(qemu_path)) except subprocess.SubprocessError as e: raise QemuError("Error while looking for the Qemu version: {}".format(e)) + + @staticmethod + def get_legacy_vm_workdir(legacy_vm_id, name): + """ + Returns the name of the legacy working directory name for a VM. + + :param legacy_vm_id: legacy VM identifier (integer) + :param: VM name (not used) + + :returns: working directory name + """ + + return os.path.join("qemu", "vm-{}".format(legacy_vm_id)) diff --git a/gns3server/modules/virtualbox/__init__.py b/gns3server/modules/virtualbox/__init__.py index 346b237c..e0394373 100644 --- a/gns3server/modules/virtualbox/__init__.py +++ b/gns3server/modules/virtualbox/__init__.py @@ -129,12 +129,14 @@ class VirtualBox(BaseManager): return vms @staticmethod - def get_legacy_vm_workdir_name(legacy_vm_id): + def get_legacy_vm_workdir(legacy_vm_id, name): """ Returns the name of the legacy working directory name for a VM. - :param legacy_vm_id: legacy VM identifier (integer) + :param legacy_vm_id: legacy VM identifier (not used) + :param name: VM name + :returns: working directory name """ - return "vm-{}".format(legacy_vm_id) + return os.path.join("vbox", "{}".format(name)) diff --git a/gns3server/modules/vpcs/__init__.py b/gns3server/modules/vpcs/__init__.py index 826e6fd8..03250c55 100644 --- a/gns3server/modules/vpcs/__init__.py +++ b/gns3server/modules/vpcs/__init__.py @@ -19,6 +19,7 @@ VPCS server module. """ +import os import asyncio from ..base_manager import BaseManager @@ -65,12 +66,14 @@ class VPCS(BaseManager): return self._used_mac_ids.get(vm_id, 1) @staticmethod - def get_legacy_vm_workdir_name(legacy_vm_id): + def get_legacy_vm_workdir(legacy_vm_id, name): """ Returns the name of the legacy working directory name for a VM. :param legacy_vm_id: legacy VM identifier (integer) + :param name: VM name (not used) + :returns: working directory name """ - return "pc-{}".format(legacy_vm_id) + return os.path.join("vpcs", "pc-{}".format(legacy_vm_id)) diff --git a/tests/modules/iou/test_iou_vm.py b/tests/modules/iou/test_iou_vm.py index cb5507cc..2333c217 100644 --- a/tests/modules/iou/test_iou_vm.py +++ b/tests/modules/iou/test_iou_vm.py @@ -303,6 +303,6 @@ def test_stop_capture(vm, tmpdir, manager, free_console_port, loop): assert vm._adapters[0].get_nio(0).capturing is False -def test_get_legacy_vm_workdir_name(): +def test_get_legacy_vm_workdir(): - assert IOU.get_legacy_vm_workdir_name(42) == "device-42" + assert IOU.get_legacy_vm_workdir(42) == "iou/device-42" diff --git a/tests/modules/qemu/test_qemu_manager.py b/tests/modules/qemu/test_qemu_manager.py index 65870191..83092dbe 100644 --- a/tests/modules/qemu/test_qemu_manager.py +++ b/tests/modules/qemu/test_qemu_manager.py @@ -48,6 +48,6 @@ def test_binary_list(loop): assert {"path": os.path.join(os.environ["PATH"], "hello"), "version": "2.2.0"} not in qemus -def test_get_legacy_vm_workdir_name(): +def test_get_legacy_vm_workdir(): - assert Qemu.get_legacy_vm_workdir_name(42) == "vm-42" + assert Qemu.get_legacy_vm_workdir(42) == "qemu/vm-42"