def restore_backup(self, context, backup, volume, backup_service): """ Restore an existing backup to a new or existing volume. """ volume_name = self.VOLUME_PREFIX + str(volume.id) backup_snapshot_name = self.SNAPSHOT_BACKUP_PREFIX + str(backup['id']) LOG.debug('libovsvolumedriver.ovs_backup_restore {0} {1}'.format( volume_name, backup_snapshot_name)) api = self._setup_ovs_client() snapshot, vdisk_guid, vdisk_name = VDiskHelper.get_snapshot_by_name( snapshot_name=backup_snapshot_name, vpool_guid=self.vpool_guid, api=api) if vdisk_name == volume_name: # rollback VDiskSetup.rollback_to_snapshot(vpool_guid=self.vpool_guid, snapshot_name=backup_snapshot_name, api=api) else: # to new volume storagerouter_ip = random.choice([ sr for sr in StoragerouterHelper.get_storagerouters( api=api).values() if self.vpool_guid in sr['vpools_guids'] ]) VDiskSetup.create_clone(vpool_guid=self.vpool_guid, new_vdisk_name=volume_name, storagerouter_ip=storagerouter_ip, api=api, snapshot_name=backup_snapshot_name) # return volume location storage_ip = VDiskHelper.get_vdisk_location_by_name( vdisk_name=volume_name, vpool_guid=self.vpool_guid, api=api)['storage_ip'] location = self._get_volume_location(volume_name=volume_name, storage_ip=storage_ip) volume['provider_location'] = location return {'provider_location': volume['provider_location']}
def _rollback_vdisks(cls, stored_vdisks, vpool, amount_checks=MAX_ROLLBACK_CHECKS, timeout=ROLLBACK_TIMEOUT): """ Rollback the given mapped vdisks :param stored_vdisks: dict with stored vdisks, snapshot, location, ... :type stored_vdisks: dict :param vpool: a valid vpool object :type vpool: ovs.model.hybrids.vpool :param amount_checks: amount of checks to perform after a vdisk has been rolled back :type amount_checks: int :param timeout: timeout between checks :type timeout: int :return: None """ for stored_vdisk in stored_vdisks: # fetch vdisk vdisk = VDiskHelper.get_vdisk_by_guid( vdisk_guid=stored_vdisk['vdisk_guid']) # Commencing rollback cls.LOGGER.info( "Starting rollback on vdisk `{0}` to first snapshot `{1}`". format(vdisk.name, stored_vdisk['snapshots'][0])) VDiskSetup.rollback_to_snapshot( vdisk_name=vdisk.name + '.raw', vpool_name=vpool.name, snapshot_id=stored_vdisk['snapshots'][0]['snapshot_guid']) # Start checking when disk is rollback'ed tries = 0 while tries < amount_checks: current_statistics = vdisk.storagedriver_client.info_volume( str(vdisk.volume_id)).stored if current_statistics < stored_vdisk['snapshots'][1][ 'stored_data']: cls.LOGGER.info( "VDisk `{0}` matched the requirements for rollback with {1} < {2}" .format(stored_vdisk['vdisk_guid'], current_statistics, stored_vdisk['snapshots'][1]['stored_data'])) break else: tries += 1 cls.LOGGER.warning( "Try `{0}` when checking stored data on volumedriver for VDisk " "`{1}`, with currently `{2}` but it should be less than `{3}`. " "Now sleeping for `{4}` seconds ...".format( tries, stored_vdisk['vdisk_guid'], current_statistics, stored_vdisk['snapshots'][1]['stored_data'], timeout)) time.sleep(timeout) # check if amount of tries has exceeded if tries == amount_checks: error_msg = "VDisk `{0}` should have been rollback'ed but max. amount of checks have exceeded!"\ .format(vdisk.name) cls.LOGGER.error(error_msg) raise RuntimeError(error_msg) else: cls.LOGGER.info( "Successfully finished rollback'ing on vdisk `{0}`".format( vdisk.name)) # commencing deleting volumes cls.LOGGER.info("Starting to remove VDisk `{0}`".format( vdisk.name)) VDiskRemover.remove_vdisk(stored_vdisk['vdisk_guid']) cls.LOGGER.info("Finished removing VDisk `{0}`".format(vdisk.name))