def _verify_cache_volume(self, context, img_meta, img_service, cachevol_props): """Verify if we have a cache volume that we want. If we don't, create one. If we do, check if it's been updated: * If so, delete it and recreate a new volume * If not, we are good. If it's out of date, delete it and create a new one. After the function returns, there should be a cache volume available, ready for cloning. """ lcfg = self.configuration cache_dir = '%s/' % lcfg.zfssa_cache_directory cache_vol_obj = Volume() cache_vol_obj.provider_location = self.mount_path + '/' + cache_dir cache_vol_obj._name_id = cachevol_props['id'] cachevol_name = cache_dir + cache_vol_obj.name LOG.debug('Verifying cache volume %s:', cachevol_name) try: cache_vol = self.zfssa.get_volume(cachevol_name) except exception.VolumeNotFound: # There is no existing cache volume, create one: LOG.debug('Cache volume not found. Creating one...') return self._create_cache_volume(context, img_meta, img_service, cachevol_props) # A cache volume does exist, check if it's updated: if ((cache_vol['updated_at'] != cachevol_props['updated_at']) or (cache_vol['image_id'] != cachevol_props['image_id'])): if cache_vol['numclones'] > 0: # The cache volume is updated, but has clones exception_msg = (_('Cannot delete ' 'cache volume: %(cachevol_name)s. ' 'It was updated at %(updated_at)s ' 'and currently has %(numclones)d ' 'volume instances.'), {'cachevol_name': cachevol_name, 'updated_at': cachevol_props['updated_at'], 'numclones': cache_vol['numclones']}) LOG.error(exception_msg) raise exception.VolumeBackendAPIException(data=exception_msg) # The cache volume is updated, but has no clone, so we delete it # and re-create a new one: super(ZFSSANFSDriver, self).delete_volume(cache_vol_obj) return self._create_cache_volume(context, img_meta, img_service, cachevol_props) return cachevol_name
def _create_cache_volume(self, context, img_meta, img_service, cachevol_props): """Create a cache volume from an image. Returns name of the cache volume. """ lcfg = self.configuration cache_dir = '%s/' % lcfg.zfssa_cache_directory cache_vol = Volume() cache_vol.provider_location = self.mount_path cache_vol._name_id = cachevol_props['id'] cache_vol.size = cachevol_props['size'] cache_vol_name = cache_dir + cache_vol.name LOG.debug('Creating cache volume %s', cache_vol_name) try: self.create_volume(cache_vol) LOG.debug('Copying image data:') super(ZFSSANFSDriver, self).copy_image_to_volume(context, cache_vol, img_service, img_meta['id']) self.zfssa.webdavclient.request(src_file=cache_vol.name, dst_file=cache_vol_name, method='MOVE') except Exception as exc: exc_msg = (_('Fail to create cache volume %(volume)s. ' 'Error: %(err)s'), { 'volume': cache_vol_name, 'err': six.text_type(exc) }) LOG.error(exc_msg) self.zfssa.delete_file(cache_vol_name) raise exception.VolumeBackendAPIException(data=exc_msg) cachevol_meta = { 'updated_at': cachevol_props['updated_at'], 'image_id': cachevol_props['image_id'], } cachevol_meta.update({'numclones': '0'}) self.zfssa.set_file_props(cache_vol_name, cachevol_meta) return cache_vol_name
def _create_cache_volume(self, context, img_meta, img_service, cachevol_props): """Create a cache volume from an image. Returns name of the cache volume. """ lcfg = self.configuration cache_dir = '%s/' % lcfg.zfssa_cache_directory cache_vol = Volume() cache_vol.provider_location = self.mount_path cache_vol._name_id = cachevol_props['id'] cache_vol.size = cachevol_props['size'] cache_vol_name = cache_dir + cache_vol.name LOG.debug('Creating cache volume %s', cache_vol_name) try: self.create_volume(cache_vol) LOG.debug('Copying image data:') super(ZFSSANFSDriver, self).copy_image_to_volume(context, cache_vol, img_service, img_meta['id']) self.zfssa.webdavclient.request(src_file=cache_vol.name, dst_file=cache_vol_name, method='MOVE') except Exception as exc: exc_msg = (_('Fail to create cache volume %(volume)s. ' 'Error: %(err)s'), {'volume': cache_vol_name, 'err': six.text_type(exc)}) LOG.error(exc_msg) self.zfssa.delete_file(cache_vol_name) raise exception.VolumeBackendAPIException(data=exc_msg) cachevol_meta = { 'updated_at': cachevol_props['updated_at'], 'image_id': cachevol_props['image_id'], } cachevol_meta.update({'numclones': '0'}) self.zfssa.set_file_props(cache_vol_name, cachevol_meta) return cache_vol_name