Exemple #1
0
    def delete(self, context, backup, force=False):
        """Make the RPC call to delete a volume backup.

        Call backup manager to execute backup delete or force delete operation.
        :param context: running context
        :param backup: the dict of backup that is got from DB.
        :param force: indicate force delete or not
        :raises InvalidBackup:
        :raises BackupDriverException:
        :raises ServiceNotFound:
        """
        context.authorize(policy.DELETE_POLICY, target_obj=backup)
        if not force and backup.status not in [
                fields.BackupStatus.AVAILABLE, fields.BackupStatus.ERROR
        ]:
            msg = _('Backup status must be available or error')
            raise exception.InvalidBackup(reason=msg)
        if force and not self._check_support_to_force_delete(
                context, backup.host):
            msg = _('force delete')
            raise exception.NotSupportedOperation(operation=msg)

        # Don't allow backup to be deleted if there are incremental
        # backups dependent on it.
        deltas = self.get_all(context, search_opts={'parent_id': backup.id})
        if deltas and len(deltas):
            msg = _('Incremental backups exist for this backup.')
            raise exception.InvalidBackup(reason=msg)

        backup.status = fields.BackupStatus.DELETING
        backup.host = self._get_available_backup_service_host(
            backup.host, backup.availability_zone)
        backup.save()
        self.backup_rpcapi.delete_backup(context, backup)
Exemple #2
0
    def delete(self, context, backup, force=False):
        """Make the RPC call to delete a volume backup.

        Call backup manager to execute backup delete or force delete operation.
        :param context: running context
        :param backup: the dict of backup that is got from DB.
        :param force: indicate force delete or not
        :raises: InvalidBackup
        :raises: BackupDriverException
        """
        check_policy(context, 'delete')
        if not force and backup.status not in ['available', 'error']:
            msg = _('Backup status must be available or error')
            raise exception.InvalidBackup(reason=msg)
        if force and not self._check_support_to_force_delete(context,
                                                             backup.host):
            msg = _('force delete')
            raise exception.NotSupportedOperation(operation=msg)

        # Don't allow backup to be deleted if there are incremental
        # backups dependent on it.
        deltas = self.get_all(context, {'parent_id': backup.id})
        if deltas and len(deltas):
            msg = _('Incremental backups exist for this backup.')
            raise exception.InvalidBackup(reason=msg)

        backup.status = 'deleting'
        backup.save()
        self.backup_rpcapi.delete_backup(context, backup)
Exemple #3
0
    def _copy_volume_from_snapshot(self, snapshot, volume, volume_size,
                                   src_encryption_key_id=None,
                                   new_encryption_key_id=None):
        """Copy data from snapshot to destination volume."""

        if new_encryption_key_id:
            msg = _("Encryption key %s was requested. Volume "
                    "encryption is not currently supported.")
            raise exception.NotSupportedOperation(
                message=msg % new_encryption_key_id)

        LOG.debug("snapshot: %(snap)s, volume: %(vol)s, "
                  "volume_size: %(size)s",
                  {'snap': snapshot.id,
                   'vol': volume.id,
                   'size': snapshot.volume_size})

        vol_dir = self._local_volume_dir(snapshot.volume)

        # Find the file which backs this file, which represents the point
        # when this snapshot was created.
        backing_file = self._get_snapshot_backing_file(snapshot)
        snapshot_path = os.path.join(vol_dir, backing_file)

        volume_path = self.local_path(volume)
        vhd_type = self._get_vhd_type()

        self._delete(volume_path)
        self._vhdutils.convert_vhd(snapshot_path,
                                   volume_path,
                                   vhd_type=vhd_type)
        self._vhdutils.set_vhd_guid(volume_path, volume.id)
        self._vhdutils.resize_vhd(volume_path, volume_size * units.Gi,
                                  is_file_max_size=False)
Exemple #4
0
def _get_qemu_convert_cmd(src,
                          dest,
                          out_format,
                          src_format=None,
                          out_subformat=None,
                          cache_mode=None,
                          prefix=None,
                          cipher_spec=None,
                          passphrase_file=None,
                          compress=False,
                          src_passphrase_file=None):

    if src_passphrase_file is not None:
        if passphrase_file is None:
            message = _("Can't create unencrypted volume %(format)s "
                        "from an encrypted source volume.") % {
                            'format': out_format
                        }
            LOG.error(message)
            # TODO(enriquetaso): handle encrypted->unencrypted
            raise exception.NotSupportedOperation(operation=message)
        return _get_qemu_convert_luks_cmd(
            src,
            dest,
            out_format,
            src_format=src_format,
            out_subformat=out_subformat,
            cache_mode=cache_mode,
            prefix=None,
            cipher_spec=cipher_spec,
            passphrase_file=passphrase_file,
            src_passphrase_file=src_passphrase_file)

    if out_format == 'vhd':
        # qemu-img still uses the legacy vpc name
        out_format = 'vpc'

    cmd = ['qemu-img', 'convert', '-O', out_format]

    if prefix:
        cmd = list(prefix) + cmd

    if cache_mode:
        cmd += ('-t', cache_mode)

    if CONF.image_compress_on_upload and compress:
        if out_format in COMPRESSIBLE_IMAGE_FORMATS:
            cmd += ('-c', )

    if out_subformat:
        cmd += ('-o', 'subformat=%s' % out_subformat)

    # AMI images can be raw or qcow2 but qemu-img doesn't accept "ami" as
    # an image format, so we use automatic detection.
    # TODO(geguileo): This fixes unencrypted AMI image case, but we need to
    # fix the encrypted case.

    if (src_format or '').lower() not in ('', 'ami'):
        cmd += ('-f', src_format)  # prevent detection of format

    # NOTE(lyarwood): When converting to LUKS add the cipher spec if present
    # and create a secret for the passphrase, written to a temp file
    if out_format == 'luks':
        check_qemu_img_version(QEMU_IMG_MIN_CONVERT_LUKS_VERSION)
        if cipher_spec:
            cmd += ('-o', 'cipher-alg=%s,cipher-mode=%s,ivgen-alg=%s' %
                    (cipher_spec['cipher_alg'], cipher_spec['cipher_mode'],
                     cipher_spec['ivgen_alg']))
        cmd += ('--object',
                'secret,id=luks_sec,format=raw,file=%s' % passphrase_file,
                '-o', 'key-secret=luks_sec')

    cmd += [src, dest]

    return cmd