def _fetch_image(context, instance, image_path): disk_path = None try: images.fetch(context, instance.image_ref, image_path, instance.user_id, instance.project_id) # Avoid conflicts vhdutils.check_disk_uuid(image_path) disk_info = vhdutils.disk_info(image_path) disk_format = disk_info[constants.VHD_IMAGE_TYPE] disk_path = image_path + "." + disk_format.lower() manage.VBoxManage.clone_hd(image_path, disk_path, disk_format=disk_format) manage.VBoxManage.close_medium(constants.MEDIUM_DISK, image_path, delete=True) except (vbox_exc.VBoxException, exception.NovaException): with excutils.save_and_reraise_exception(): for path in (image_path, disk_path): if path and os.path.exists(path): manage.VBoxManage.close_medium(constants.MEDIUM_DISK, path) pathutils.delete_path(path) return disk_path
def _cleanup_failed_disk_migration(self, instance_path, revert_path, dest_path): if dest_path and os.path.exists(dest_path): self._remove_disks(dest_path) pathutils.delete_path(dest_path) if revert_path and os.path.exists(revert_path): os.rename(revert_path, instance_path)
def _clenup_disk(self, disk): LOG.debug('Trying to close and remove the disk %(disk)s if exists.', {"disk": disk}) if disk and os.path.exists(disk): try: self._vbox_manage.close_medium(constants.MEDIUM_DISK, disk) except exception.VBoxManageError as error: LOG.warning(i18n._LW("Failed to remove %(disk)s: %(reason)s"), {"disk": disk, "reason": error}) pathutils.delete_path(disk)
def test_delete(self, mock_exists, mock_is_dir, mock_remove, mock_rmtree): mock_exists.side_effect = [False, True, True] mock_is_dir.side_effect = [True, False] for _ in range(3): pathutils.delete_path(mock.sentinel.path) self.assertEqual(3, mock_exists.call_count) self.assertEqual(2, mock_is_dir.call_count) mock_remove.assert_called_once_with(mock.sentinel.path) mock_rmtree.assert_called_once_with(mock.sentinel.path)
def _remove_disks(self, path): for disk_file in os.listdir(path): disk_path = os.path.join(path, disk_file) try: LOG.debug("Trying to unregister %(path)s", {"path": disk_path}) self._vbox_manage.close_medium( constants.MEDIUM_DISK, disk_path, delete=True) except vbox_exc.VBoxException: LOG.debug("Remove file: %(path)s", {"path": disk_path}) pathutils.delete_path(disk_path)
def _remove_disks(self, path): for disk_file in os.listdir(path): disk_path = os.path.join(path, disk_file) try: LOG.debug("Trying to unregister %(path)s", {"path": disk_path}) self._vbox_manage.close_medium(constants.MEDIUM_DISK, disk_path, delete=True) except vbox_exc.VBoxException: LOG.debug("Remove file: %(path)s", {"path": disk_path}) pathutils.delete_path(disk_path)
def _clenup_disk(self, disk): LOG.debug('Trying to close and remove the disk %(disk)s if exists.', {"disk": disk}) if disk and os.path.exists(disk): try: self._vbox_manage.close_medium(constants.MEDIUM_DISK, disk) except exception.VBoxManageError as error: LOG.warning(i18n._LW("Failed to remove %(disk)s: %(reason)s"), { "disk": disk, "reason": error }) pathutils.delete_path(disk)
def _migrate_disk_files(self, instance, disk_files, destination): local_ips = hostutils.get_local_ips() local_ips.append(hostutils.get_ip()) same_host = destination in local_ips LOG.debug("Destination `%(dest)s` %(local_ips)s", { "dest": destination, "local_ips": local_ips }) instance_basepath = pathutils.instance_basepath(instance) revert_path = pathutils.revert_dir(instance, action=constants.PATH_OVERWRITE) if same_host: destination_path = ("%(path)s%(suffix)s" % { "path": instance_basepath, "suffix": self._SUFFIX }) else: LOG.warning(i18n._LW("Only resize on the same host is supported!")) raise NotImplementedError() # Delete the destination path if already exists pathutils.delete_path(destination_path) # Create the destination path pathutils.create_path(destination_path) try: self._migrate_disk(disk_files[0], destination_path, root_disk=True) for disk_file in disk_files[1:]: self._migrate_disk(disk_file, destination_path) # Remove the instance from the Hypervisor self._vbox_ops.destroy(instance, destroy_disks=False) # Move files to revert path os.rename(instance_basepath, revert_path) if same_host: os.rename(destination_path, instance_basepath) except (OSError, vbox_exc.VBoxException): with excutils.save_and_reraise_exception(): try: self._cleanup_failed_disk_migration( instance_basepath, revert_path, destination_path) except vbox_exc.VBoxException as exc: # Log and ignore this exception LOG.exception(exc)
def _migrate_disk_files(self, instance, disk_files, destination): local_ips = hostutils.get_local_ips() local_ips.append(hostutils.get_ip()) same_host = destination in local_ips LOG.debug("Destination `%(dest)s` %(local_ips)s", {"dest": destination, "local_ips": local_ips}) instance_basepath = pathutils.instance_basepath(instance) revert_path = pathutils.revert_dir( instance, action=constants.PATH_OVERWRITE) if same_host: destination_path = ( "%(path)s%(suffix)s" % {"path": instance_basepath, "suffix": self._SUFFIX}) else: LOG.warning( i18n._LW("Only resize on the same host is supported!")) raise NotImplementedError() # Delete the destination path if already exists pathutils.delete_path(destination_path) # Create the destination path pathutils.create_path(destination_path) try: self._migrate_disk(disk_files[0], destination_path, root_disk=True) for disk_file in disk_files[1:]: self._migrate_disk(disk_file, destination_path) # Remove the instance from the Hypervisor self._vbox_ops.destroy(instance, destroy_disks=False) # Move files to revert path os.rename(instance_basepath, revert_path) if same_host: os.rename(destination_path, instance_basepath) except (OSError, vbox_exc.VBoxException): with excutils.save_and_reraise_exception(): try: self._cleanup_failed_disk_migration( instance_basepath, revert_path, destination_path) except vbox_exc.VBoxException as exc: # Log and ignore this exception LOG.exception(exc)
def confirm_migration(self, migration, instance, network_info): """Confirms a resize, destroying the source VM.""" LOG.debug("`Confirms migration` method called.") revert_path = pathutils.revert_dir(instance) self._remove_disks(revert_path) pathutils.delete_path(revert_path)