Ejemplo n.º 1
0
    def _cache_vol_2_2(self, context, vol, image_meta, image_service):
        image_id = image_meta['id']
        # Pull down image and determine if valid
        with image_utils.TemporaryImages.fetch(image_service,
                                               context,
                                               image_id) as tmp_image:
            data = image_utils.qemu_img_info(tmp_image)
            fmt = data.file_format
            if fmt is None:
                raise exception.ImageUnacceptable(
                    reason=_("'qemu-img info' parsing failed."),
                    image_id=image_id)

            backing_file = data.backing_file
            if backing_file is not None:
                raise exception.ImageUnacceptable(
                    image_id=image_id,
                    reason=_("fmt=%(fmt)s backed by:%(backing_file)s")
                    % {'fmt': fmt, 'backing_file': backing_file, })

            vsize = int(
                math.ceil(float(data.virtual_size) / units.Gi))
            vol['size'] = vsize
            vtype = vol['volume_type_id']
            LOG.info("Creating cached image with volume type: %(vtype)s and "
                     "size %(size)s", {'vtype': vtype, 'size': vsize})
            self._create_volume_2_2(vol)
            with self._connect_vol(context, vol) as device:
                LOG.debug("Moving image %s to volume %s",
                          image_meta['id'], datc.get_name(vol))
                image_utils.convert_image(tmp_image,
                                          device,
                                          'raw',
                                          run_as_root=True)
                LOG.debug("Finished moving image %s to volume %s",
                          image_meta['id'], datc.get_name(vol))
                data = image_utils.qemu_img_info(device, run_as_root=True)
                if data.file_format != 'raw':
                    raise exception.ImageUnacceptable(
                        image_id=image_id,
                        reason=_(
                            "Converted to %(vol_format)s, but format is "
                            "now %(file_format)s") % {
                                'vol_format': 'raw',
                                'file_format': data.file_format})
        # TODO(_alastor_): Remove this snapshot creation when we fix
        # "created_at" attribute in the frontend
        # We don't actually care about the snapshot uuid, we just want
        # a single snapshot
        snapshot = {'id': str(uuid.uuid4()),
                    'volume_id': vol['id'],
                    'project_id': vol['project_id']}
        self._create_snapshot_2_2(snapshot)
        metadata = {'type': 'cached_image'}
        tenant = self.get_tenant(vol['project_id'])
        ai = self.cvol_to_ai(vol, tenant=tenant)
        ai.metadata.set(tenant=tenant, **metadata)
        # Cloning offline AI is ~4 seconds faster than cloning online AI
        self._detach_volume_2_2(None, vol)
Ejemplo n.º 2
0
 def _manage_existing_2_2(self, volume, existing_ref):
     # Only volumes created under the requesting tenant can be managed in
     # the v2.1+ API.  Eg.  If tenant A is the tenant for the volume to be
     # managed, it must also be tenant A that makes this request.
     # This will be fixed in a later API update
     existing_ref = existing_ref['source-name']
     app_inst_name, __, __, __ = datc._parse_vol_ref(existing_ref)
     LOG.debug("Managing existing Datera volume %s  "
               "Changing name to %s", datc.get_name(volume), existing_ref)
     # Rename AppInstance
     dummy_vol = {'id': app_inst_name, 'project_id': volume['project_id']}
     tenant = self.get_tenant(volume['project_id'])
     ai = self.cvol_to_ai(dummy_vol, tenant=tenant)
     data = {'name': datc.get_name(volume)}
     ai.set(tenant=tenant, **data)
     self._add_vol_meta_2_2(volume)
Ejemplo n.º 3
0
    def _create_volume_from_snapshot_2_2(self, volume, snapshot):
        # Handle case where snapshot is "managed"
        dummy_vol = {'id': snapshot['volume_id'],
                     'project_id': snapshot['project_id']}
        tenant = self.get_tenant(dummy_vol['project_id'])
        dvol = self.cvol_to_dvol(dummy_vol, tenant=tenant)
        found_snap = None
        provider_location = snapshot.get('provider_location')
        if provider_location:
            found_snap = dvol.snapshots.get(provider_location, tenant=tenant)
        else:
            snapshots = dvol.snapshots.list(tenant=tenant)
            for snap in snapshots:
                if snap.uuid == snapshot['id']:
                    found_snap = snap
                    break
            else:
                raise exception.SnapshotNotFound(snapshot_id=snapshot['id'])

        self._snap_poll_2_2(found_snap, tenant)

        src = found_snap.path
        app_params = (
            {
                'create_mode': 'openstack',
                'uuid': str(volume['id']),
                'name': datc.get_name(volume),
                'clone_snapshot_src': {'path': src},
            })

        self.api.app_instances.create(tenant=tenant, **app_params)
        if (volume['size'] > snapshot['volume_size']):
            self._extend_volume_2_2(volume, volume['size'])
        self._add_vol_meta_2_2(volume)
Ejemplo n.º 4
0
    def _update_migrated_volume_2_2(self, context, volume, new_volume,
                                    volume_status):
        """Rename the newly created volume to the original volume.

        So we can find it correctly.
        """
        tenant = self.get_tenant(new_volume['project_id'])
        ai = self.cvol_to_ai(new_volume, tenant=tenant)
        data = {'name': datc.get_name(volume)}
        ai.set(tenant=tenant, **data)
        return {'_name_id': None}
Ejemplo n.º 5
0
    def _create_volume_2_1(self, volume):
        policies = self._get_policies_for_resource(volume)
        num_replicas = int(policies['replica_count'])
        storage_name = 'storage-1'
        volume_name = 'volume-1'
        template = policies['template']
        placement = policies['placement_mode']
        ip_pool = policies['ip_pool']

        name = datc.get_name(volume)

        if template:
            app_params = ({
                'create_mode': 'openstack',
                # 'uuid': str(volume['id']),
                'name': name,
                'app_template': {
                    'path': '/app_templates/{}'.format(template)
                }
            })
        else:

            app_params = ({
                'create_mode':
                'openstack',
                'uuid':
                str(volume['id']),
                'name':
                name,
                'access_control_mode':
                'deny_all',
                'storage_instances': [{
                    'name':
                    storage_name,
                    'ip_pool': {
                        'path': ('/access_network_ip_pools/'
                                 '{}'.format(ip_pool))
                    },
                    'volumes': [{
                        'name': volume_name,
                        'size': volume['size'],
                        'placement_mode': placement,
                        'replica_count': num_replicas,
                        'snapshot_policies': []
                    }]
                }]
            })

        tenant = self.create_tenant(volume['project_id'])
        self.api.app_instances.create(tenant=tenant, **app_params)
        self._update_qos_2_1(volume, policies)
        self._add_vol_meta_2_1(volume)
Ejemplo n.º 6
0
    def _delete_snapshot_2_2(self, snapshot):
        # Handle case where snapshot is "managed"
        dummy_vol = {
            'id': snapshot['volume_id'],
            'project_id': snapshot['project_id']
        }
        tenant = self.get_tenant(dummy_vol['project_id'])
        dvol = self.cvol_to_dvol(dummy_vol, tenant=tenant)

        snapshots = None

        # Shortcut if this is a managed snapshot
        provider_location = snapshot.get('provider_location')
        if provider_location:
            snap = dvol.snapshots.get(provider_location, tenant=tenant)
            snap.delete(tenant=tenant)
            return

        # Long-way.  UUID identification
        try:
            snapshots = dvol.snapshots.list(tenant=tenant)
        except exception.NotFound:
            msg = ("Tried to delete snapshot %s, but parent volume %s was "
                   "not found in Datera cluster. Continuing with delete.")
            LOG.info(msg, datc.get_name(snapshot),
                     datc.get_name({'id': snapshot['volume_id']}))
            return

        try:
            for snap in snapshots:
                if snap.uuid == snapshot['id']:
                    snap.delete(tenant=tenant)
                    break
            else:
                raise exception.NotFound
        except exception.NotFound:
            msg = ("Tried to delete snapshot %s, but was not found in "
                   "Datera cluster. Continuing with delete.")
            LOG.info(msg, datc.get_name(snapshot))
Ejemplo n.º 7
0
    def _create_cloned_volume_2_2(self, volume, src_vref):
        tenant = self.get_tenant(volume['project_id'])
        sdvol = self.cvol_to_dvol(src_vref, tenant=tenant)
        src = sdvol.path
        data = {
            'create_mode': 'openstack',
            'name': datc.get_name(volume),
            'uuid': str(volume['id']),
            'clone_volume_src': {'path': src},
        }
        tenant = self.get_tenant(volume['project_id'])
        self.api.app_instances.create(tenant=tenant, **data)

        if volume['size'] > src_vref['size']:
            self._extend_volume_2_2(volume, volume['size'])
        self._add_vol_meta_2_2(volume)
Ejemplo n.º 8
0
    def _delete_volume_2_2(self, volume):
        try:
            tenant = self.get_tenant(volume['project_id'])
            ai = self.cvol_to_ai(volume, tenant=tenant)
            si = ai.storage_instances.list(tenant=tenant)[0]

            # Clear out ACL
            acl = si.acl_policy.get(tenant=tenant)
            acl.set(tenant=tenant, initiators=[])

            # Bring volume offline
            data = {'admin_state': 'offline', 'force': True}
            ai.set(tenant=tenant, **data)

            ai.delete(tenant=tenant, force=True)
        except exception.NotFound:
            msg = ("Tried to delete volume %s, but it was not found in the "
                   "Datera cluster. Continuing with delete.")
            LOG.info(msg, datc.get_name(volume))
Ejemplo n.º 9
0
 def _manage_existing_snapshot_2_2(self, snapshot, existing_ref):
     existing_ref = existing_ref['source-name']
     datc._check_snap_ref(existing_ref)
     LOG.debug("Managing existing Datera volume snapshot %s for volume %s",
               existing_ref, datc.get_name({'id': snapshot['volume_id']}))
     return {'provider_location': existing_ref}
Ejemplo n.º 10
0
    def _create_volume_2_2(self, volume):
        policies = self._get_policies_for_resource(volume)
        num_replicas = int(policies['replica_count'])
        storage_name = 'storage-1'
        volume_name = 'volume-1'
        template = policies['template']
        placement = policies['placement_mode']
        ppolicy = policies['placement_policy']
        ip_pool = datc.get_ip_pool(policies)

        name = datc.get_name(volume)

        if template:
            app_params = ({
                'create_mode': 'openstack',
                # 'uuid': str(volume['id']),
                'name': name,
                'app_template': {
                    'path': '/app_templates/{}'.format(template)
                }
            })
            if self._support_template_override_2_2():
                app_params['template_override'] = {
                    'storage_instances': {
                        storage_name: {
                            'volumes': {
                                volume_name: {
                                    'size': str(volume['size'])
                                }
                            }
                        }
                    }
                }

        else:

            app_params = ({
                'create_mode':
                'openstack',
                'uuid':
                str(volume['id']),
                'name':
                name,
                'access_control_mode':
                'deny_all',
                'storage_instances': [{
                    'name':
                    storage_name,
                    'ip_pool': {
                        'path': ('/access_network_ip_pools/'
                                 '{}'.format(ip_pool))
                    },
                    'volumes': [{
                        'name': volume_name,
                        'size': volume['size'],
                        'replica_count': num_replicas,
                        'snapshot_policies': []
                    }]
                }]
            })
            create_vol = app_params['storage_instances'][0]['volumes'][0]
            if datc.dat_version_gte(self.datera_version, '3.3.0.0'):
                create_vol['placement_policy'] = {
                    'path': '/placement_policies/{}'.format(ppolicy)
                }
            else:
                create_vol['placement_mode'] = placement

        tenant = self.create_tenant(volume['project_id'])
        self.api.app_instances.create(tenant=tenant, **app_params)
        self._update_qos_2_2(volume, policies)
        self._add_vol_meta_2_2(volume)