Ejemplo n.º 1
0
    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
Ejemplo n.º 2
0
    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
Ejemplo n.º 3
0
    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)
Ejemplo n.º 4
0
 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)
Ejemplo n.º 5
0
    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)
Ejemplo n.º 6
0
    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
Ejemplo n.º 7
0
    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
Ejemplo n.º 8
0
    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)