def _create_full_snapshot(self, description, name, pool_names, profile_id, src_virtual_disk): pools = self._get_available_disk_pools(pool_names) destination_pool = datacore_utils.get_first_or_default( lambda pool: (pool.ServerId == src_virtual_disk.FirstHostId or pool.ServerId == src_virtual_disk.SecondHostId), pools, None) if not destination_pool: msg = _("Suitable snapshot destination disk pool not found for " "virtual disk %s.") % src_virtual_disk.Id LOG.error(msg) raise cinder_exception.VolumeDriverException(message=msg) server = datacore_utils.get_first( lambda srv: srv.Id == destination_pool.ServerId, self._api.get_servers()) if not server.SnapshotMapStorePoolId: self._api.designate_map_store(destination_pool.Id) snapshot = self._api.create_snapshot(src_virtual_disk.Id, name, description, destination_pool.Id, 'Full', False, profile_id) return snapshot
def _get_logical_disk_on_host(virtual_disk_id, host_id, logical_disks): logical_disk = datacore_utils.get_first( lambda disk: (disk.ServerHostId == host_id and disk.VirtualDiskId == virtual_disk_id), logical_disks) return logical_disk
def _create_virtual_disk_copy(self, src_virtual_disk, name, description, profile_id=None, pool_names=None): snapshot = self._create_full_snapshot(description, name, pool_names, profile_id, src_virtual_disk) try: snapshot = self._await_snapshot_migrated(snapshot.Id) self._api.delete_snapshot(snapshot.Id) except Exception: with excutils.save_and_reraise_exception(): LOG.exception( "Split operation failed for snapshot " "%(snapshot)s.", {'snapshot': snapshot.Id}) try: logical_disk_copy = datacore_utils.get_first( lambda disk: (disk.Id == snapshot.DestinationLogicalDiskId), self._api.get_logical_disks()) virtual_disk_copy = datacore_utils.get_first( lambda disk: (disk.Id == logical_disk_copy.VirtualDiskId), self._api.get_virtual_disks()) self._api.delete_virtual_disk(virtual_disk_copy.Id, True) except datacore_exception.DataCoreException as e: LOG.warning( "An error occurred on a cleanup after failed " "split of snapshot %(snapshot)s: %(error)s.", { 'snapshot': snapshot.Id, 'error': e }) logical_disk_copy = datacore_utils.get_first( lambda disk: disk.Id == snapshot.DestinationLogicalDiskId, self._api.get_logical_disks()) virtual_disk_copy = datacore_utils.get_first( lambda disk: disk.Id == logical_disk_copy.VirtualDiskId, self._api.get_virtual_disks()) return virtual_disk_copy
def test_get_first(self): disk_a = {'id': 'disk-a', 'type': 'Single', 'size': 5} disk_b = {'id': 'disk-b', 'type': 'Single', 'size': 1} disk_c = {'id': 'disk-c', 'type': 'Mirrored', 'size': 5} disk_d = {'id': 'disk-d', 'type': 'Single', 'size': 10} test_source = [disk_a, disk_b, disk_c, disk_d] first = utils.get_first(lambda item: item['id'] == 'disk-c', test_source) self.assertEqual(disk_c, first) self.assertRaises(StopIteration, utils.get_first, lambda item: item['type'] == 'Dual', test_source)
def _create_virtual_disk_copy(self, src_virtual_disk, name, description, profile_id=None, pool_names=None): snapshot = self._create_full_snapshot( description, name, pool_names, profile_id, src_virtual_disk) try: snapshot = self._await_snapshot_migrated(snapshot.Id) self._api.delete_snapshot(snapshot.Id) except Exception: with excutils.save_and_reraise_exception(): LOG.exception("Split operation failed for snapshot " "%(snapshot)s.", {'snapshot': snapshot.Id}) try: logical_disk_copy = datacore_utils.get_first( lambda disk: ( disk.Id == snapshot.DestinationLogicalDiskId), self._api.get_logical_disks()) virtual_disk_copy = datacore_utils.get_first( lambda disk: ( disk.Id == logical_disk_copy.VirtualDiskId), self._api.get_virtual_disks()) self._api.delete_virtual_disk(virtual_disk_copy.Id, True) except datacore_exception.DataCoreException as e: LOG.warning("An error occurred on a cleanup after failed " "split of snapshot %(snapshot)s: %(error)s.", {'snapshot': snapshot.Id, 'error': e}) logical_disk_copy = datacore_utils.get_first( lambda disk: disk.Id == snapshot.DestinationLogicalDiskId, self._api.get_logical_disks()) virtual_disk_copy = datacore_utils.get_first( lambda disk: disk.Id == logical_disk_copy.VirtualDiskId, self._api.get_virtual_disks()) return virtual_disk_copy
def inner(): snapshot_data = datacore_utils.get_first( lambda snapshot: snapshot.Id == snapshot_id, self._api.get_snapshots()) if snapshot_data.State == 'Migrated': raise loopingcall.LoopingCallDone(snapshot_data) elif (snapshot_data.State != 'Healthy' and snapshot_data.Failure != 'NoFailure'): msg = (_("Full migration of snapshot %(snapshot)s failed. " "Snapshot is in %(state)s state.") % {'snapshot': snapshot_data.Id, 'state': snapshot_data.State}) LOG.error(msg) raise cinder_exception.VolumeDriverException(message=msg)
def inner(): snapshot_data = datacore_utils.get_first( lambda snapshot: snapshot.Id == snapshot_id, self._api.get_snapshots()) if snapshot_data.State == 'Migrated': raise loopingcall.LoopingCallDone(snapshot_data) elif (snapshot_data.State != 'Healthy' and snapshot_data.Failure != 'NoFailure'): msg = (_("Full migration of snapshot %(snapshot)s failed. " "Snapshot is in %(state)s state.") % { 'snapshot': snapshot_data.Id, 'state': snapshot_data.State }) LOG.error(msg) raise cinder_exception.VolumeDriverException(message=msg)
def test_get_first(self): disk_a = {'id': 'disk-a', 'type': 'Single', 'size': 5} disk_b = {'id': 'disk-b', 'type': 'Single', 'size': 1} disk_c = {'id': 'disk-c', 'type': 'Mirrored', 'size': 5} disk_d = {'id': 'disk-d', 'type': 'Single', 'size': 10} test_source = [disk_a, disk_b, disk_c, disk_d] first = utils.get_first(lambda item: item['id'] == 'disk-c', test_source) self.assertEqual(disk_c, first) self.assertRaises(StopIteration, utils.get_first, lambda item: item['type'] == 'Dual', test_source)
def inner(start_time): disk_failed_delay = self.configuration.datacore_disk_failed_delay virtual_disk = datacore_utils.get_first( lambda disk: disk.Id == virtual_disk_id, self._api.get_virtual_disks()) if virtual_disk.DiskStatus == 'Online': raise loopingcall.LoopingCallDone(virtual_disk) elif (virtual_disk.DiskStatus != 'FailedRedundancy' and time.time() - start_time >= disk_failed_delay): msg = (_("Virtual disk %(disk)s did not come out of the " "%(state)s state after %(timeout)s seconds.") % {'disk': virtual_disk.Id, 'state': virtual_disk.DiskStatus, 'timeout': disk_failed_delay}) LOG.error(msg) raise cinder_exception.VolumeDriverException(message=msg)
def inner(start_time): disk_failed_delay = self.configuration.datacore_disk_failed_delay virtual_disk = datacore_utils.get_first( lambda disk: disk.Id == virtual_disk_id, self._api.get_virtual_disks()) if virtual_disk.DiskStatus == 'Online': raise loopingcall.LoopingCallDone(virtual_disk) elif (virtual_disk.DiskStatus != 'FailedRedundancy' and time.time() - start_time >= disk_failed_delay): msg = (_("Virtual disk %(disk)s did not come out of the " "%(state)s state after %(timeout)s seconds.") % { 'disk': virtual_disk.Id, 'state': virtual_disk.DiskStatus, 'timeout': disk_failed_delay }) LOG.error(msg) raise cinder_exception.VolumeDriverException(message=msg)
def _check_iscsi_chap_configuration(self, iscsi_chap_enabled, targets): logical_units = self._api.get_logical_units() target_devices = self._api.get_target_devices() for logical_unit in logical_units: target_device_id = logical_unit.VirtualTargetDeviceId target_device = datacore_utils.get_first( lambda device, key=target_device_id: device.Id == key, target_devices) target_port_id = target_device.TargetPortId target = datacore_utils.get_first_or_default( lambda target_port, key=target_port_id: target_port.Id == key, targets, None) if (target and iscsi_chap_enabled == (target.ServerPortProperties.Authentication == 'None')): msg = _("iSCSI CHAP authentication can't be configured for " "target %s. Device exists that served through " "this target.") % target.PortName LOG.error(msg) raise cinder_exception.VolumeDriverException(message=msg)
def _create_full_snapshot(self, description, name, pool_names, profile_id, src_virtual_disk): pools = self._get_available_disk_pools(pool_names) destination_pool = datacore_utils.get_first_or_default( lambda pool: (pool.ServerId == src_virtual_disk.FirstHostId or pool .ServerId == src_virtual_disk.SecondHostId), pools, None) if not destination_pool: msg = _("Suitable snapshot destination disk pool not found for " "virtual disk %s.") % src_virtual_disk.Id LOG.error(msg) raise cinder_exception.VolumeDriverException(message=msg) server = datacore_utils.get_first( lambda srv: srv.Id == destination_pool.ServerId, self._api.get_servers()) if not server.SnapshotMapStorePoolId: self._api.designate_map_store(destination_pool.Id) snapshot = self._api.create_snapshot(src_virtual_disk.Id, name, description, destination_pool.Id, 'Full', False, profile_id) return snapshot
def _create_volume_from(self, volume, src_obj): src_virtual_disk = self._get_virtual_disk_for(src_obj, raise_not_found=True) if src_virtual_disk.DiskStatus != 'Online': LOG.warning("Attempting to create a volume from virtual disk " "%(disk)s that is in %(state)s state.", {'disk': src_virtual_disk.Id, 'state': src_virtual_disk.DiskStatus}) volume_options = self._get_volume_options(volume) profile_id = self._get_storage_profile_id( volume_options[self.DATACORE_STORAGE_PROFILE_KEY]) pool_names = volume_options[self.DATACORE_DISK_POOLS_KEY] volume_virtual_disk = self._create_virtual_disk_copy( src_virtual_disk, volume['id'], volume['display_name'], profile_id=profile_id, pool_names=pool_names) volume_logical_disk = datacore_utils.get_first( lambda disk: disk.VirtualDiskId == volume_virtual_disk.Id, self._api.get_logical_disks()) try: volume_virtual_disk = self._set_virtual_disk_size( volume_virtual_disk, self._get_size_in_bytes(volume['size'])) disk_type = volume_options[self.DATACORE_DISK_TYPE_KEY] if disk_type == self.DATACORE_MIRRORED_DISK: pools = self._get_available_disk_pools(pool_names) selected_pool = datacore_utils.get_first_or_default( lambda pool: ( pool.ServerId != volume_logical_disk.ServerHostId and pool.Id != volume_logical_disk.PoolId), pools, None) if selected_pool: logical_disk = self._api.create_pool_logical_disk( selected_pool.Id, 'Striped', volume_virtual_disk.Size.Value) self._api.bind_logical_disk(volume_virtual_disk.Id, logical_disk.Id, 'Second', True, False, True) else: msg = _("Can not create mirrored virtual disk. " "Suitable disk pools not found.") LOG.error(msg) raise cinder_exception.VolumeDriverException(message=msg) volume_virtual_disk = self._await_virtual_disk_online( volume_virtual_disk.Id) except Exception: with excutils.save_and_reraise_exception(): LOG.exception("Creation of volume %(volume)s failed.", {'volume': volume['id']}) try: self._api.delete_virtual_disk(volume_virtual_disk.Id, True) except datacore_exception.DataCoreException as e: LOG.warning("An error occurred on a cleanup after failed " "creation of volume %(volume)s: %(error)s.", {'volume': volume['id'], 'error': e}) return {'provider_location': volume_virtual_disk.Id}
def _get_our_server_group(self): server_group = datacore_utils.get_first(lambda group: group.OurGroup, self._api.get_server_groups()) return server_group
def _create_volume_from(self, volume, src_obj): src_virtual_disk = self._get_virtual_disk_for(src_obj, raise_not_found=True) if src_virtual_disk.DiskStatus != 'Online': LOG.warning( "Attempting to create a volume from virtual disk " "%(disk)s that is in %(state)s state.", { 'disk': src_virtual_disk.Id, 'state': src_virtual_disk.DiskStatus }) volume_options = self._get_volume_options(volume) profile_id = self._get_storage_profile_id( volume_options[self.DATACORE_STORAGE_PROFILE_KEY]) pool_names = volume_options[self.DATACORE_DISK_POOLS_KEY] volume_virtual_disk = self._create_virtual_disk_copy( src_virtual_disk, volume['id'], volume['display_name'], profile_id=profile_id, pool_names=pool_names) volume_logical_disk = datacore_utils.get_first( lambda disk: disk.VirtualDiskId == volume_virtual_disk.Id, self._api.get_logical_disks()) try: volume_virtual_disk = self._set_virtual_disk_size( volume_virtual_disk, self._get_size_in_bytes(volume['size'])) disk_type = volume_options[self.DATACORE_DISK_TYPE_KEY] if disk_type == self.DATACORE_MIRRORED_DISK: pools = self._get_available_disk_pools(pool_names) selected_pool = datacore_utils.get_first_or_default( lambda pool: (pool.ServerId != volume_logical_disk.ServerHostId and pool .Id != volume_logical_disk.PoolId), pools, None) if selected_pool: logical_disk = self._api.create_pool_logical_disk( selected_pool.Id, 'Striped', volume_virtual_disk.Size.Value) self._api.bind_logical_disk(volume_virtual_disk.Id, logical_disk.Id, 'Second', True, False, True) else: msg = _("Can not create mirrored virtual disk. " "Suitable disk pools not found.") LOG.error(msg) raise cinder_exception.VolumeDriverException(message=msg) volume_virtual_disk = self._await_virtual_disk_online( volume_virtual_disk.Id) except Exception: with excutils.save_and_reraise_exception(): LOG.exception("Creation of volume %(volume)s failed.", {'volume': volume['id']}) try: self._api.delete_virtual_disk(volume_virtual_disk.Id, True) except datacore_exception.DataCoreException as e: LOG.warning( "An error occurred on a cleanup after failed " "creation of volume %(volume)s: %(error)s.", { 'volume': volume['id'], 'error': e }) return {'provider_location': volume_virtual_disk.Id}
def _get_our_server_group(self): server_group = datacore_utils.get_first(lambda group: group.OurGroup, self._api.get_server_groups()) return server_group