diff --git a/gns3server/handlers/virtualbox_handler.py b/gns3server/handlers/virtualbox_handler.py index 84a340ed..78a0310a 100644 --- a/gns3server/handlers/virtualbox_handler.py +++ b/gns3server/handlers/virtualbox_handler.py @@ -45,11 +45,10 @@ class VirtualBoxHandler: request.json["project_uuid"], request.json.get("uuid"), request.json["vmname"], - request.json.get("linked_clone", False)) + request.json["linked_clone"], + console=request.json.get("console")) response.set_status(201) - response.json({"name": vm.name, - "uuid": vm.uuid, - "project_uuid": vm.project.uuid}) + response.json(vm) @classmethod @Route.post( diff --git a/gns3server/modules/base_manager.py b/gns3server/modules/base_manager.py index 3dcbca25..32423fba 100644 --- a/gns3server/modules/base_manager.py +++ b/gns3server/modules/base_manager.py @@ -49,6 +49,16 @@ class BaseManager: cls._instance = cls() return cls._instance + @property + def module_name(self): + """ + Returns the module name. + + :returns: module name + """ + + return self.__class__.__name__ + @property def port_manager(self): """ diff --git a/gns3server/modules/base_vm.py b/gns3server/modules/base_vm.py index c4531fba..3db4bb32 100644 --- a/gns3server/modules/base_vm.py +++ b/gns3server/modules/base_vm.py @@ -29,6 +29,10 @@ class BaseVM: self._project = project self._manager = manager + log.info("{module}: {name} [{uuid}] has been created".format(module=self.manager.module_name, + name=self.name, + uuid=self.uuid)) + # TODO: When delete release console ports @property @@ -59,10 +63,10 @@ class BaseVM: :param new_name: name """ - log.info("{module} {name} [{uuid}]: renamed to {new_name}".format(module=self.module_name, - name=self._name, - uuid=self.uuid, - new_name=new_name)) + log.info("{module}: {name} [{uuid}]: renamed to {new_name}".format(module=self.manager.module_name, + name=self.name, + uuid=self.uuid, + new_name=new_name)) self._name = new_name @property @@ -91,7 +95,7 @@ class BaseVM: Return VM working directory """ - return self._project.vm_working_directory(self.module_name, self._uuid) + return self._project.vm_working_directory(self.manager.module_name.lower(), self._uuid) def create(self): """ diff --git a/gns3server/modules/project.py b/gns3server/modules/project.py index c924a9d5..31e00171 100644 --- a/gns3server/modules/project.py +++ b/gns3server/modules/project.py @@ -47,7 +47,7 @@ class Project: self._path = os.path.join(self._location, self._uuid) try: - os.makedirs(os.path.join(self._path, 'vms'), exist_ok=True) + 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)) @@ -75,7 +75,7 @@ class Project: :param vm_uuid: VM UUID """ - p = os.path.join(self._path, "vms", module, vm_uuid) + p = os.path.join(self._path, module, vm_uuid) try: os.makedirs(p, exist_ok=True) except FileExistsError: diff --git a/gns3server/modules/virtualbox/virtualbox_vm.py b/gns3server/modules/virtualbox/virtualbox_vm.py index 772beedc..27695215 100644 --- a/gns3server/modules/virtualbox/virtualbox_vm.py +++ b/gns3server/modules/virtualbox/virtualbox_vm.py @@ -49,7 +49,7 @@ class VirtualBoxVM(BaseVM): VirtualBox VM implementation. """ - def __init__(self, name, uuid, project, manager, vmname, linked_clone): + def __init__(self, name, uuid, project, manager, vmname, linked_clone, console=None): super().__init__(name, uuid, project, manager) @@ -71,22 +71,14 @@ class VirtualBoxVM(BaseVM): if not os.access(self._vboxmanage_path, os.X_OK): raise VirtualBoxError("VBoxManage is not executable") - self._vmname = vmname self._started = False self._linked_clone = linked_clone self._system_properties = {} self._queue = asyncio.Queue() self._created = asyncio.Future() + self._running = True self._worker = asyncio.async(self._run()) - return - - self._command = [] - self._vbox_user = vbox_user - - self._telnet_server_thread = None - self._serial_pipe = None - # VirtualBox settings self._console = console self._ethernet_adapters = [] @@ -96,27 +88,30 @@ class VirtualBoxVM(BaseVM): self._adapter_start_index = 0 self._adapter_type = "Intel PRO/1000 MT Desktop (82540EM)" - working_dir_path = os.path.join(working_dir, "vbox") - - if vbox_id and not os.path.isdir(working_dir_path): - raise VirtualBoxError("Working directory {} doesn't exist".format(working_dir_path)) - - # create the device own working directory - self.working_dir = working_dir_path - if linked_clone: - if vbox_id and os.path.isdir(os.path.join(self.working_dir, self._vmname)): + if uuid and os.path.isdir(os.path.join(self.working_dir, self._vmname)): vbox_file = os.path.join(self.working_dir, self._vmname, self._vmname + ".vbox") self._execute("registervm", [vbox_file]) self._reattach_hdds() else: self._create_linked_clone() - self._maximum_adapters = 8 - self.adapters = 2 # creates 2 adapters by default + #self._maximum_adapters = 8 + #self.adapters = 2 # creates 2 adapters by default - log.info("VirtualBox VM {name} [id={id}] has been created".format(name=self._name, - id=self._id)) + return + + self._command = [] + self._vbox_user = vbox_user + + self._telnet_server_thread = None + self._serial_pipe = None + + def __json__(self): + + return {"name": self.name, + "uuid": self.uuid, + "project_uuid": self.project.uuid} @asyncio.coroutine def _execute(self, subcommand, args, timeout=60): @@ -156,12 +151,13 @@ class VirtualBoxVM(BaseVM): try: yield from self._get_system_properties() + #TODO: check for API version self._created.set_result(True) except VirtualBoxError as e: self._created.set_exception(e) return - while True: + while self._running: future, subcommand, args = yield from self._queue.get() try: yield from self._execute(subcommand, args) diff --git a/gns3server/modules/vpcs/vpcs_vm.py b/gns3server/modules/vpcs/vpcs_vm.py index 548b7ec3..35c61407 100644 --- a/gns3server/modules/vpcs/vpcs_vm.py +++ b/gns3server/modules/vpcs/vpcs_vm.py @@ -106,8 +106,8 @@ class VPCSVM(BaseVM): def __json__(self): - return {"name": self._name, - "uuid": self._uuid, + return {"name": self.name, + "uuid": self.uuid, "console": self._console, "project_uuid": self.project.uuid, "script_file": self.script_file, diff --git a/gns3server/schemas/virtualbox.py b/gns3server/schemas/virtualbox.py index 63e1664e..d272efe1 100644 --- a/gns3server/schemas/virtualbox.py +++ b/gns3server/schemas/virtualbox.py @@ -55,7 +55,7 @@ VBOX_CREATE_SCHEMA = { }, }, "additionalProperties": False, - "required": ["name", "vmname"], + "required": ["name", "vmname", "linked_clone", "project_uuid"], } VBOX_OBJECT_SCHEMA = { @@ -90,5 +90,5 @@ VBOX_OBJECT_SCHEMA = { }, }, "additionalProperties": False, - "required": ["name", "uuid"] + "required": ["name", "uuid", "project_uuid"] } diff --git a/tests/api/test_virtualbox.py b/tests/api/test_virtualbox.py index 820bf34a..ed5ae696 100644 --- a/tests/api/test_virtualbox.py +++ b/tests/api/test_virtualbox.py @@ -16,14 +16,21 @@ # along with this program. If not, see . from tests.utils import asyncio_patch -from gns3server.modules.virtualbox.virtualbox_vm import VirtualBoxVM def test_vbox_create(server, project): - response = server.post("/virtualbox", {"name": "VM1", "vmname": "VM1", "project_uuid": project.uuid}, example=True) - assert response.status == 201 - assert response.route == "/virtualbox" - assert response.json["name"] == "VM1" + + with asyncio_patch("gns3server.modules.VirtualBox.create_vm", return_value={"name": "VM1", + "uuid": "61d61bdd-aa7d-4912-817f-65a9eb54d3ab", + "project_uuid": project.uuid}): + response = server.post("/virtualbox", {"name": "VM1", + "vmname": "VM1", + "linked_clone": False, + "project_uuid": project.uuid}, + example=True) + assert response.status == 201 + assert response.json["name"] == "VM1" + assert response.json["project_uuid"] == project.uuid def test_vbox_start(server):