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
示例#2
0
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)
示例#4
0
    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)
示例#6
0
    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 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)
示例#9
0
 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)
示例#10
0
 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)
示例#11
0
    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)
示例#14
0
 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)