def _get_manageable_volumes_2_2(self, cinder_volumes, marker, limit, offset, sort_keys, sort_dirs): LOG.debug("Listing manageable Datera volumes") results = self._list_manageable_2_2(cinder_volumes) page_results = volutils.paginate_entries_list( results, marker, limit, offset, sort_keys, sort_dirs) return page_results
def _get_manageable_volumes_2_1(self, cinder_volumes, marker, limit, offset, sort_keys, sort_dirs): # Use the first volume to determine the tenant we're working under if cinder_volumes: tenant = self._create_tenant(cinder_volumes[0]) else: tenant = None LOG.debug("Listing manageable Datera volumes") app_instances = self._issue_api_request(datc.URL_TEMPLATES['ai'](), api_version='2.1', tenant=tenant)['data'] results = [] cinder_volume_ids = [vol['id'] for vol in cinder_volumes] for ai in app_instances: ai_name = ai['name'] reference = None size = None safe_to_manage = False reason_not_safe = "" cinder_id = None extra_info = None if re.match(datc.UUID4_RE, ai_name): cinder_id = ai_name.lstrip(datc.OS_PREFIX) if (not cinder_id and ai_name.lstrip(datc.OS_PREFIX) not in cinder_volume_ids): safe_to_manage, reason_not_safe = self._is_manageable_2_1(ai) if safe_to_manage: si = list(ai['storage_instances'].values())[0] si_name = si['name'] vol = list(si['volumes'].values())[0] vol_name = vol['name'] size = vol['size'] reference = { "source-name": "{}:{}:{}".format(ai_name, si_name, vol_name) } results.append({ 'reference': reference, 'size': size, 'safe_to_manage': safe_to_manage, 'reason_not_safe': reason_not_safe, 'cinder_id': cinder_id, 'extra_info': extra_info }) page_results = volume_utils.paginate_entries_list( results, marker, limit, offset, sort_keys, sort_dirs) return page_results
def _get_manageable_vols(self, cinder_resources, resource_type, marker, limit, offset, sort_keys, sort_dirs): """List volumes or snapshots on the backend.""" # We can't translate a backend volume name into a Cinder id # directly, so we create a map to do it. volume_name_to_id = {} for resource in cinder_resources: key = self._get_backend_volume_name(resource['id'], resource_type) value = resource['id'] volume_name_to_id[key] = value self.client_login() try: vols = self.client.get_volumes(filter_type=resource_type) except stx_exception.RequestError as ex: LOG.exception("Error getting manageable volumes.") raise exception.Invalid(ex) finally: self.client_logout() entries = [] for vol in vols.values(): vol_info = { 'reference': { 'source-name': vol['name'] }, 'size': vol['size'], 'cinder_id': None, 'extra_info': None } potential_id = volume_name_to_id.get(vol['name']) if potential_id: vol_info['safe_to_manage'] = False vol_info['reason_not_safe'] = 'already managed' vol_info['cinder_id'] = potential_id elif vol['mapped']: vol_info['safe_to_manage'] = False vol_info['reason_not_safe'] = '%s in use' % resource_type else: vol_info['safe_to_manage'] = True vol_info['reason_not_safe'] = None if resource_type == 'snapshot': origin = vol['parent'] vol_info['source_reference'] = {'source-name': origin} entries.append(vol_info) return volume_utils.paginate_entries_list(entries, marker, limit, offset, sort_keys, sort_dirs)
def get_manageable_snapshots(self, cinder_snapshots, marker, limit, offset, sort_keys, sort_dirs): """List manageable snapshots in Vitastor.""" manageable_snapshots = [] cinder_snapshot_ids = [resource['id'] for resource in cinder_snapshots] # List all volumes # FIXME: It's possible to use pagination in our case, but.. do we want it? self._etcd_foreach( 'config/inode/' + str(self.cfg['pool_id']), lambda kv: self._add_manageable_volume(kv, manageable_snapshots, cinder_snapshot_ids)) return volume_utils.paginate_entries_list(manageable_snapshots, marker, limit, offset, sort_keys, sort_dirs)
def _get_manageable_resource_info(self, cinder_resources, resource_type, marker, limit, offset, sort_keys, sort_dirs): entries = [] lvs = self.vg.get_volumes() cinder_ids = [resource['id'] for resource in cinder_resources] for lv in lvs: is_snap = self.vg.lv_is_snapshot(lv['name']) if ((resource_type == 'volume' and is_snap) or (resource_type == 'snapshot' and not is_snap)): continue if resource_type == 'volume': potential_id = volume_utils.extract_id_from_volume_name( lv['name']) else: unescape = self._unescape_snapshot(lv['name']) potential_id = volume_utils.extract_id_from_snapshot_name( unescape) lv_info = { 'reference': { 'source-name': lv['name'] }, 'size': int(math.ceil(float(lv['size']))), 'cinder_id': None, 'extra_info': None } if potential_id in cinder_ids: lv_info['safe_to_manage'] = False lv_info['reason_not_safe'] = 'already managed' lv_info['cinder_id'] = potential_id elif self.vg.lv_is_open(lv['name']): lv_info['safe_to_manage'] = False lv_info['reason_not_safe'] = '%s in use' % resource_type else: lv_info['safe_to_manage'] = True lv_info['reason_not_safe'] = None if resource_type == 'snapshot': origin = self.vg.lv_get_origin(lv['name']) lv_info['source_reference'] = {'source-name': origin} entries.append(lv_info) return volume_utils.paginate_entries_list(entries, marker, limit, offset, sort_keys, sort_dirs)
def _get_manageable_snapshots_2_2(self, cinder_snapshots, marker, limit, offset, sort_keys, sort_dirs): LOG.debug("Listing manageable Datera snapshots") results = self._list_manageable_2_2(cinder_snapshots) snap_results = [] snapids = set((snap['id'] for snap in cinder_snapshots)) snaprefs = set( (snap.get('provider_location') for snap in cinder_snapshots)) for volume in results: snaps = json.loads(volume["extra_info"]["snapshots"]) for snapshot in snaps: reference = snapshot[0] uuid = snapshot[1] size = volume["size"] safe_to_manage = True reason_not_safe = "" cinder_id = "" extra_info = {} source_reference = volume["reference"] if uuid in snapids or reference in snaprefs: safe_to_manage = False reason_not_safe = _("already managed by Cinder") elif not volume['safe_to_manage'] and not volume['cinder_id']: safe_to_manage = False reason_not_safe = _("parent volume not safe to manage") snap_results.append({ 'reference': { 'source-name': reference }, 'size': size, 'safe_to_manage': safe_to_manage, 'reason_not_safe': reason_not_safe, 'cinder_id': cinder_id, 'extra_info': extra_info, 'source_reference': source_reference }) page_results = volutils.paginate_entries_list(snap_results, marker, limit, offset, sort_keys, sort_dirs) return page_results
def get_manageable_snapshots(self, cinder_snapshots, marker, limit, offset, sort_keys, sort_dirs): """Interface to support listing manageable snapshots and volumes""" # Get all snapshots vpsa_snapshots = self.vpsa._get_all_vpsa_snapshots() # Get all snapshots of all volumes all_vpsa_snapshots = [] for vpsa_snap in vpsa_snapshots: if (vpsa_snap['pool_name'] == self.configuration.zadara_vpsa_poolname): vpsa_snap['volume_name'] = vpsa_snap['volume_display_name'] vpsa_snap['size'] = float(vpsa_snap['volume_capacity_mb'] / 1024) all_vpsa_snapshots.append(vpsa_snap) existing_snapshots = {} for cinder_snapshot in cinder_snapshots: if cinder_snapshot.provider_location: snapshots = (list(filter(lambda snapshot: ((snapshot['volume_ext_name'] == cinder_snapshot.volume.provider_location) and (snapshot['name'] == cinder_snapshot.provider_location)), all_vpsa_snapshots))) else: volume_name = (self._get_zadara_vol_template_name( cinder_snapshot.volume_name)) snapshots = (list(filter(lambda snapshot: ((snapshot['volume_display_name'] == volume_name) and (snapshot['display_name'] == cinder_snapshot.name)), all_vpsa_snapshots))) for snapshot in snapshots: existing_snapshots[snapshot['name']] = cinder_snapshot.id manageable_snapshots = [] try: unique_snapshots = [] for snapshot in all_vpsa_snapshots: snap_id = snapshot['name'] if snap_id in unique_snapshots: continue cinder_id = existing_snapshots.get(snap_id) is_safe = True reason_not_safe = None if cinder_id: is_safe = False reason_not_safe = _("Snapshot already managed.") manageable_snapshots.append({ 'reference': {'name': snapshot['display_name']}, 'size': snapshot['size'], 'safe_to_manage': is_safe, 'reason_not_safe': reason_not_safe, 'cinder_id': cinder_id, 'extra_info': None, 'source_reference': {'name': snapshot['volume_name']}, }) unique_snapshots.append(snap_id) return volume_utils.paginate_entries_list( manageable_snapshots, marker, limit, offset, sort_keys, sort_dirs) except Exception as e: msg = (_('Exception: %s') % six.text_type(e)) LOG.error(msg) raise
def get_manageable_volumes(self, cinder_volumes, marker, limit, offset, sort_keys, sort_dirs): """List volumes on the backend available for management by Cinder""" # Get all vpsa volumes all_vpsa_volumes = self.vpsa._get_all_vpsa_volumes() # Create a dictionary of existing volumes existing_vols = {} for cinder_vol in cinder_volumes: if cinder_vol.provider_location: volumes = (list(filter(lambda volume: (volume['name'] == cinder_vol.provider_location), all_vpsa_volumes))) else: cinder_name = (self._get_zadara_vol_template_name( cinder_vol.name)) volumes = (list(filter(lambda volume: (volume['display_name'] == cinder_name), all_vpsa_volumes))) for volume in volumes: existing_vols[volume['name']] = cinder_vol.id # Filter out all volumes already attached to any server volumes_in_use = {} volumes_not_available = {} for volume in all_vpsa_volumes: if volume['name'] in existing_vols: continue if volume['status'] == 'In-use': volumes_in_use[volume['name']] =\ self.vpsa._get_servers_attached_to_volume(volume) continue if volume['status'] != 'Available': volumes_not_available[volume['name']] = volume['display_name'] continue manageable_vols = [] for vpsa_volume in all_vpsa_volumes: vol_name = vpsa_volume['name'] vol_display_name = vpsa_volume['display_name'] cinder_id = existing_vols.get(vol_name) not_safe_msgs = [] if vol_name in volumes_in_use: host_list = volumes_in_use[vol_name] not_safe_msgs.append(_('Volume connected to host(s) %s') % host_list) elif vol_name in volumes_not_available: not_safe_msgs.append(_('Volume not available')) if cinder_id: not_safe_msgs.append(_('Volume already managed')) is_safe = (len(not_safe_msgs) == 0) reason_not_safe = ' && '.join(not_safe_msgs) manageable_vols.append({ 'reference': {'name': vol_display_name}, 'size': vpsa_volume['virtual_capacity'], 'safe_to_manage': is_safe, 'reason_not_safe': reason_not_safe, 'cinder_id': cinder_id, }) return volume_utils.paginate_entries_list( manageable_vols, marker, limit, offset, sort_keys, sort_dirs)