diff --git a/gns3server/modules/virtualbox/__init__.py b/gns3server/modules/virtualbox/__init__.py index 24f2f684..8e7754fb 100644 --- a/gns3server/modules/virtualbox/__init__.py +++ b/gns3server/modules/virtualbox/__init__.py @@ -115,6 +115,45 @@ class VirtualBox(BaseManager): return stdout_data.decode("utf-8", errors="ignore").splitlines() + @asyncio.coroutine + def _find_inaccessible_hdd_files(self): + """ + Finds inaccessible disk files (to clean up the VirtualBox media manager) + """ + + hdds = [] + properties = yield from self.execute("list", ["hdds"]) + flag_inaccessible = False + for prop in properties: + try: + name, value = prop.split(':', 1) + except ValueError: + continue + if name.strip() == "State" and value.strip() == "inaccessible": + flag_inaccessible = True + if flag_inaccessible and name.strip() == "Location": + hdds.append(value.strip()) + flag_inaccessible = False + return reversed(hdds) + + @asyncio.coroutine + def project_closed(self, project): + """ + Called when a project is closed. + + :param project: Project instance + """ + + yield from super().project_closed(project) + hdd_files_to_close = yield from self._find_inaccessible_hdd_files() + for hdd_file in hdd_files_to_close: + log.info("Closing VirtualBox VM disk file {}".format(os.path.basename(hdd_file))) + try: + yield from self.execute("closemedium", ["disk", hdd_file]) + except VirtualBoxError as e: + log.warning("Could not close VirtualBox VM disk file {}: {error}".format(os.path.basename(hdd_file), e)) + continue + @asyncio.coroutine def get_list(self): """ diff --git a/gns3server/modules/virtualbox/virtualbox_vm.py b/gns3server/modules/virtualbox/virtualbox_vm.py index e0a181be..ed1580ab 100644 --- a/gns3server/modules/virtualbox/virtualbox_vm.py +++ b/gns3server/modules/virtualbox/virtualbox_vm.py @@ -321,7 +321,6 @@ class VirtualBoxVM(BaseVM): if self._linked_clone: hdd_table = [] - hdd_files_to_close = [] if os.path.exists(self.working_dir): hdd_files = yield from self._get_all_hdd_files() vm_info = yield from self._get_vm_info() @@ -332,7 +331,6 @@ class VirtualBoxVM(BaseVM): port = match.group(2) device = match.group(3) if value in hdd_files: - hdd_files_to_close.append(value) log.info("VirtualBox VM '{name}' [{id}] detaching HDD {controller} {port} {device}".format(name=self.name, id=self.id, controller=controller, @@ -353,12 +351,6 @@ class VirtualBoxVM(BaseVM): log.info("VirtualBox VM '{name}' [{id}] unregistering".format(name=self.name, id=self.id)) yield from self.manager.execute("unregistervm", [self._name]) - for hdd_file in hdd_files_to_close: - log.info("VirtualBox VM '{name}' [{id}] closing disk {disk}".format(name=self.name, - id=self.id, - disk=os.path.basename(hdd_file))) - yield from self.manager.execute("closemedium", ["disk", hdd_file]) - if hdd_table: try: hdd_info_file = os.path.join(self.working_dir, self._vmname, "hdd_info.json")