Пример #1
0
    def test_connections_lazy_loading_from_ovo(self, get_all_mock):
        """Test we don't reload connections if data is in OVO."""
        vol = objects.Volume(self.backend, size=10)
        vol._connections = None
        delattr(vol._ovo, '_obj_volume_attachment')

        conns = [objects.Connection(self.backend, connector={'k': 'v'},
                                    volume_id=vol.id, status='attached',
                                    attach_mode='rw',
                                    connection_info={'conn': {}},
                                    name='my_snap')]
        ovo_conns = [conn._ovo for conn in conns]
        ovo_attach_list = cinder_ovos.VolumeAttachmentList(objects=ovo_conns)
        get_all_mock.return_value = ovo_attach_list
        mock_get_conns = self.persistence.get_connections

        ovo_result = vol._ovo.volume_attachment

        mock_get_conns.not_called()
        self.assertEqual(ovo_attach_list, ovo_result)
        # Cinderlib object doesn't have the connections yet
        self.assertIsNone(vol._connections)
        self.assertEqual(1, len(vol._ovo.volume_attachment))
        self.assertEqual(vol._ovo.volume_attachment[0], ovo_result[0])
        # There is no second call when we access the cinderlib object, as the
        # data is retrieved from the OVO that already has it
        result = vol.connections
        mock_get_conns.not_called()
        # Confirm we used the OVO
        self.assertIs(ovo_conns[0], result[0]._ovo)
Пример #2
0
    def _from_db_object(context, volume, db_volume, expected_attrs=None):
        if expected_attrs is None:
            expected_attrs = []
        for name, field in volume.fields.items():
            if name in Volume.OPTIONAL_FIELDS:
                continue
            value = db_volume.get(name)
            if isinstance(field, fields.IntegerField):
                value = value or 0
            volume[name] = value

        # Get data from db_volume object that was queried by joined query
        # from DB
        if 'metadata' in expected_attrs:
            metadata = db_volume.get('volume_metadata', [])
            volume.metadata = {item['key']: item['value'] for item in metadata}
        if 'admin_metadata' in expected_attrs:
            metadata = db_volume.get('volume_admin_metadata', [])
            volume.admin_metadata = {
                item['key']: item['value']
                for item in metadata
            }
        if 'glance_metadata' in expected_attrs:
            metadata = db_volume.get('volume_glance_metadata', [])
            volume.glance_metadata = {
                item['key']: item['value']
                for item in metadata
            }
        if 'volume_type' in expected_attrs:
            db_volume_type = db_volume.get('volume_type')
            if db_volume_type:
                vt_expected_attrs = []
                if 'volume_type.extra_specs' in expected_attrs:
                    vt_expected_attrs.append('extra_specs')
                volume.volume_type = objects.VolumeType._from_db_object(
                    context,
                    objects.VolumeType(),
                    db_volume_type,
                    expected_attrs=vt_expected_attrs)
        if 'volume_attachment' in expected_attrs:
            attachments = base.obj_make_list(
                context, objects.VolumeAttachmentList(context),
                objects.VolumeAttachment, db_volume.get('volume_attachment'))
            volume.volume_attachment = attachments
        if 'consistencygroup' in expected_attrs:
            consistencygroup = objects.ConsistencyGroup(context)
            consistencygroup._from_db_object(context, consistencygroup,
                                             db_volume['consistencygroup'])
            volume.consistencygroup = consistencygroup
        if 'snapshots' in expected_attrs:
            snapshots = base.obj_make_list(context,
                                           objects.SnapshotList(context),
                                           objects.Snapshot,
                                           db_volume['snapshots'])
            volume.snapshots = snapshots

        volume._context = context
        volume.obj_reset_changes()
        return volume
Пример #3
0
    def connections(self):
        # Lazy loading
        if self._connections is None:
            self._connections = self.persistence.get_connections(
                volume_id=self.id)
            for conn in self._connections:
                conn.volume = self
            ovos = [conn._ovo for conn in self._connections]
            setattr(self._ovo, CONNECTIONS_OVO_FIELD,
                    cinder_objs.VolumeAttachmentList(objects=ovos))
            self._ovo.obj_reset_changes((CONNECTIONS_OVO_FIELD, ))

        return self._connections
Пример #4
0
    def test_view_get_attachments(self):
        fake_volume = self._fake_create_volume()
        fake_volume['attach_status'] = fields.VolumeAttachStatus.ATTACHING
        att_time = datetime.datetime(2017,
                                     8,
                                     31,
                                     21,
                                     55,
                                     7,
                                     tzinfo=iso8601.UTC)
        a1 = {
            'id': fake.UUID1,
            'volume_id': fake.UUID2,
            'instance': None,
            'attached_host': None,
            'mountpoint': None,
            'attach_time': None,
            'attach_status': fields.VolumeAttachStatus.ATTACHING
        }
        a2 = {
            'id': fake.UUID3,
            'volume_id': fake.UUID4,
            'instance_uuid': fake.UUID5,
            'attached_host': 'host1',
            'mountpoint': 'na',
            'attach_time': att_time,
            'attach_status': fields.VolumeAttachStatus.ATTACHED
        }
        attachment1 = objects.VolumeAttachment(self.ctxt, **a1)
        attachment2 = objects.VolumeAttachment(self.ctxt, **a2)
        atts = {'objects': [attachment1, attachment2]}
        attachments = objects.VolumeAttachmentList(self.ctxt, **atts)

        fake_volume['volume_attachment'] = attachments

        # get_attachments should only return attachments with the
        # attached status = ATTACHED
        attachments = ViewBuilder()._get_attachments(fake_volume)

        self.assertEqual(1, len(attachments))
        self.assertEqual(fake.UUID3, attachments[0]['attachment_id'])
        self.assertEqual(fake.UUID4, attachments[0]['volume_id'])
        self.assertEqual(fake.UUID5, attachments[0]['server_id'])
        self.assertEqual('host1', attachments[0]['host_name'])
        self.assertEqual('na', attachments[0]['device'])
        self.assertEqual(att_time, attachments[0]['attached_at'])
    def _from_db_object(context, volume, db_volume, expected_attrs=None):
        if expected_attrs is None:
            expected_attrs = []
        for name, field in volume.fields.items():
            if name in OPTIONAL_FIELDS:
                continue
            value = db_volume.get(name)
            if isinstance(field, fields.IntegerField):
                value = value or 0
            volume[name] = value

        # Get data from db_volume object that was queried by joined query
        # from DB
        if 'metadata' in expected_attrs:
            volume.metadata = {}
            metadata = db_volume.get('volume_metadata', [])
            if metadata:
                volume.metadata = {
                    item['key']: item['value']
                    for item in metadata
                }
        if 'admin_metadata' in expected_attrs:
            volume.admin_metadata = {}
            metadata = db_volume.get('volume_admin_metadata', [])
            if metadata:
                volume.admin_metadata = {
                    item['key']: item['value']
                    for item in metadata
                }
        if 'volume_type' in expected_attrs:
            db_volume_type = db_volume.get('volume_type')
            if db_volume_type:
                volume.volume_type = objects.VolumeType._from_db_object(
                    context,
                    objects.VolumeType(),
                    db_volume_type,
                    expected_attrs='extra_specs')
        if 'volume_attachment' in expected_attrs:
            attachments = base.obj_make_list(
                context, objects.VolumeAttachmentList(context),
                objects.VolumeAttachment, db_volume.get('volume_attachment'))
            volume.volume_attachment = attachments.objects

        volume._context = context
        volume.obj_reset_changes()
        return volume
    def test_obj_load_attr(self, mock_va_get_all_by_vol, mock_vt_get_by_id,
                           mock_admin_metadata_get, mock_metadata_get):
        volume = objects.Volume._from_db_object(self.context, objects.Volume(),
                                                fake_volume.fake_db_volume())

        # Test metadata lazy-loaded field
        metadata = {'foo': 'bar'}
        mock_metadata_get.return_value = metadata
        self.assertEqual(metadata, volume.metadata)
        mock_metadata_get.assert_called_once_with(self.context, volume.id)

        # Test volume_type lazy-loaded field
        volume_type = objects.VolumeType(context=self.context, id=5)
        mock_vt_get_by_id.return_value = volume_type
        self.assertEqual(volume_type, volume.volume_type)
        mock_vt_get_by_id.assert_called_once_with(self.context,
                                                  volume.volume_type_id)

        # Test volume_attachment lazy-loaded field
        va_objs = [
            objects.VolumeAttachment(context=self.context, id=i)
            for i in [3, 4, 5]
        ]
        va_list = objects.VolumeAttachmentList(context=self.context,
                                               objects=va_objs)
        mock_va_get_all_by_vol.return_value = va_list
        self.assertEqual(va_list, volume.volume_attachment)
        mock_va_get_all_by_vol.assert_called_once_with(self.context, volume.id)

        # Test admin_metadata lazy-loaded field - user context
        adm_metadata = {'bar': 'foo'}
        mock_admin_metadata_get.return_value = adm_metadata
        self.assertEqual({}, volume.admin_metadata)
        self.assertFalse(mock_admin_metadata_get.called)

        # Test admin_metadata lazy-loaded field - admin context
        adm_context = self.context.elevated()
        volume = objects.Volume._from_db_object(adm_context, objects.Volume(),
                                                fake_volume.fake_db_volume())
        adm_metadata = {'bar': 'foo'}
        mock_admin_metadata_get.return_value = adm_metadata
        self.assertEqual(adm_metadata, volume.admin_metadata)
        mock_admin_metadata_get.assert_called_once_with(adm_context, volume.id)
Пример #7
0
 def test_volume_detached_with_attachment(self, volume_attachment_get,
                                          volume_detached, metadata_delete):
     va_objs = [
         objects.VolumeAttachment(context=self.context, id=i)
         for i in [fake.OBJECT_ID, fake.OBJECT2_ID, fake.OBJECT3_ID]
     ]
     # As changes are not saved, we need reset it here. Later changes
     # will be checked.
     for obj in va_objs:
         obj.obj_reset_changes()
     va_list = objects.VolumeAttachmentList(context=self.context,
                                            objects=va_objs)
     va_list.obj_reset_changes()
     volume_attachment_get.return_value = va_list
     admin_context = context.get_admin_context()
     volume = fake_volume.fake_volume_obj(admin_context,
                                          volume_attachment=va_list,
                                          volume_admin_metadata=[{
                                              'key':
                                              'attached_mode',
                                              'value':
                                              'rw'
                                          }])
     self.assertEqual(3, len(volume.volume_attachment))
     volume_detached.return_value = ({
         'status': 'in-use'
     }, {
         'attached_mode': 'rw'
     })
     with mock.patch.object(admin_context, 'elevated') as mock_elevated:
         mock_elevated.return_value = admin_context
         volume.finish_detach(fake.OBJECT_ID)
         volume_detached.assert_called_once_with(admin_context, volume.id,
                                                 fake.OBJECT_ID)
         metadata_delete.assert_called_once_with(admin_context, volume.id,
                                                 'attached_mode')
         self.assertEqual('in-use', volume.status)
         self.assertEqual({}, volume.cinder_obj_get_changes())
         self.assertEqual(2, len(volume.volume_attachment))
         self.assertIsNone(volume.admin_metadata.get('attached_mode'))
Пример #8
0
    def connections(self):
        # Lazy loading
        if self._connections is None:
            # Check if the driver has already lazy loaded it using OVOs
            if self._ovo.obj_attr_is_set(CONNECTIONS_OVO_FIELD):
                conns = [Connection(None, volume=self, __ovo=ovo)
                         for ovo
                         in getattr(self._ovo, CONNECTIONS_OVO_FIELD).objects]

            # Retrieve data from persistence storage
            else:
                conns = self.persistence.get_connections(volume_id=self.id)
                for conn in conns:
                    conn.volume = self
                ovos = [conn._ovo for conn in conns]
                setattr(self._ovo, CONNECTIONS_OVO_FIELD,
                        cinder_objs.VolumeAttachmentList(objects=ovos))
                self._ovo.obj_reset_changes((CONNECTIONS_OVO_FIELD,))

            self._connections = conns

        return self._connections
Пример #9
0
    def test_obj_load_attr(self, mock_sl_get_all_for_volume, mock_cg_get_by_id,
                           mock_va_get_all_by_vol, mock_vt_get_by_id,
                           mock_admin_metadata_get, mock_glance_metadata_get,
                           mock_metadata_get):
        volume = objects.Volume._from_db_object(self.context, objects.Volume(),
                                                fake_volume.fake_db_volume())

        # Test metadata lazy-loaded field
        metadata = {'foo': 'bar'}
        mock_metadata_get.return_value = metadata
        self.assertEqual(metadata, volume.metadata)
        mock_metadata_get.assert_called_once_with(self.context, volume.id)

        # Test glance_metadata lazy-loaded field
        glance_metadata = [{'key': 'foo', 'value': 'bar'}]
        mock_glance_metadata_get.return_value = glance_metadata
        self.assertEqual({'foo': 'bar'}, volume.glance_metadata)
        mock_glance_metadata_get.assert_called_once_with(
            self.context, volume.id)

        # Test volume_type lazy-loaded field
        # Case1. volume.volume_type_id = None
        self.assertIsNone(volume.volume_type)

        # Case2. volume2.volume_type_id = 1
        fake2 = fake_volume.fake_db_volume()
        fake2.update({'volume_type_id': fake.volume_id})
        volume2 = objects.Volume._from_db_object(self.context,
                                                 objects.Volume(), fake2)
        volume_type = objects.VolumeType(context=self.context,
                                         id=fake.volume_type_id)
        mock_vt_get_by_id.return_value = volume_type
        self.assertEqual(volume_type, volume2.volume_type)
        mock_vt_get_by_id.assert_called_once_with(self.context,
                                                  volume2.volume_type_id)

        # Test consistencygroup lazy-loaded field
        consistencygroup = objects.ConsistencyGroup(
            context=self.context, id=fake.consistency_group_id)
        mock_cg_get_by_id.return_value = consistencygroup
        self.assertEqual(consistencygroup, volume.consistencygroup)
        mock_cg_get_by_id.assert_called_once_with(self.context,
                                                  volume.consistencygroup_id)

        # Test snapshots lazy-loaded field
        snapshots = objects.SnapshotList(context=self.context,
                                         id=fake.snapshot_id)
        mock_sl_get_all_for_volume.return_value = snapshots
        self.assertEqual(snapshots, volume.snapshots)
        mock_sl_get_all_for_volume.assert_called_once_with(
            self.context, volume.id)

        # Test volume_attachment lazy-loaded field
        va_objs = [
            objects.VolumeAttachment(context=self.context, id=i)
            for i in [fake.object_id, fake.object2_id, fake.object3_id]
        ]
        va_list = objects.VolumeAttachmentList(context=self.context,
                                               objects=va_objs)
        mock_va_get_all_by_vol.return_value = va_list
        self.assertEqual(va_list, volume.volume_attachment)
        mock_va_get_all_by_vol.assert_called_once_with(self.context, volume.id)

        # Test admin_metadata lazy-loaded field - user context
        adm_metadata = {'bar': 'foo'}
        mock_admin_metadata_get.return_value = adm_metadata
        self.assertEqual({}, volume.admin_metadata)
        self.assertFalse(mock_admin_metadata_get.called)

        # Test admin_metadata lazy-loaded field - admin context
        adm_context = self.context.elevated()
        volume = objects.Volume._from_db_object(adm_context, objects.Volume(),
                                                fake_volume.fake_db_volume())
        adm_metadata = {'bar': 'foo'}
        mock_admin_metadata_get.return_value = adm_metadata
        self.assertEqual(adm_metadata, volume.admin_metadata)
        mock_admin_metadata_get.assert_called_once_with(adm_context, volume.id)
Пример #10
0
    def _from_db_object(cls, context, volume, db_volume, expected_attrs=None):
        if expected_attrs is None:
            expected_attrs = []
        for name, field in volume.fields.items():
            if name in cls.OPTIONAL_FIELDS:
                continue
            value = db_volume.get(name)
            if isinstance(field, fields.IntegerField):
                value = value or 0
            volume[name] = value

        # Get data from db_volume object that was queried by joined query
        # from DB
        if 'metadata' in expected_attrs:
            metadata = db_volume.get('volume_metadata', [])
            volume.metadata = {item['key']: item['value'] for item in metadata}
        if 'admin_metadata' in expected_attrs:
            metadata = db_volume.get('volume_admin_metadata', [])
            volume.admin_metadata = {item['key']: item['value']
                                     for item in metadata}
        if 'glance_metadata' in expected_attrs:
            metadata = db_volume.get('volume_glance_metadata', [])
            volume.glance_metadata = {item['key']: item['value']
                                      for item in metadata}
        if 'volume_type' in expected_attrs:
            db_volume_type = db_volume.get('volume_type')
            if db_volume_type:
                vt_expected_attrs = []
                if 'volume_type.extra_specs' in expected_attrs:
                    vt_expected_attrs.append('extra_specs')
                volume.volume_type = objects.VolumeType._from_db_object(
                    context, objects.VolumeType(), db_volume_type,
                    expected_attrs=vt_expected_attrs)
        if 'volume_attachment' in expected_attrs:
            attachments = base.obj_make_list(
                context, objects.VolumeAttachmentList(context),
                objects.VolumeAttachment,
                db_volume.get('volume_attachment'))
            volume.volume_attachment = attachments
        if volume.consistencygroup_id and 'consistencygroup' in expected_attrs:
            consistencygroup = objects.ConsistencyGroup(context)
            consistencygroup._from_db_object(context,
                                             consistencygroup,
                                             db_volume['consistencygroup'])
            volume.consistencygroup = consistencygroup
        if 'snapshots' in expected_attrs:
            snapshots = base.obj_make_list(
                context, objects.SnapshotList(context),
                objects.Snapshot,
                db_volume['snapshots'])
            volume.snapshots = snapshots
        if 'cluster' in expected_attrs:
            db_cluster = db_volume.get('cluster')
            # If this volume doesn't belong to a cluster the cluster field in
            # the ORM instance will have value of None.
            if db_cluster:
                volume.cluster = objects.Cluster(context)
                objects.Cluster._from_db_object(context, volume.cluster,
                                                db_cluster)
            else:
                volume.cluster = None
        if volume.group_id and 'group' in expected_attrs:
            group = objects.Group(context)
            group._from_db_object(context,
                                  group,
                                  db_volume['group'])
            volume.group = group

        volume._context = context
        volume.obj_reset_changes()
        return volume
Пример #11
0
    def __init__(self, backend_or_vol, pool_name=None, **kwargs):
        # Accept backend name for convenience
        if isinstance(backend_or_vol, six.string_types):
            backend_name = backend_or_vol
            backend_or_vol = self._get_backend(backend_or_vol)
        elif isinstance(backend_or_vol, self.backend_class):
            backend_name = backend_or_vol.id
        elif isinstance(backend_or_vol, Volume):
            backend_str, pool = backend_or_vol._ovo.host.split('#')
            backend_name = backend_str.split('@')[-1]
            pool_name = pool_name or pool
            for key in backend_or_vol._ovo.fields:
                if (backend_or_vol._ovo.obj_attr_is_set(key)
                        and key not in self._ignore_keys):
                    kwargs.setdefault(key, getattr(backend_or_vol._ovo, key))
            if backend_or_vol.volume_type:
                kwargs.setdefault('extra_specs',
                                  backend_or_vol.volume_type.extra_specs)
                if backend_or_vol.volume_type.qos_specs:
                    kwargs.setdefault(
                        'qos_specs',
                        backend_or_vol.volume_type.qos_specs.specs)
            backend_or_vol = backend_or_vol.backend

        if '__ovo' not in kwargs:
            kwargs[CONNECTIONS_OVO_FIELD] = (cinder_objs.VolumeAttachmentList(
                context=self.CONTEXT))
            kwargs['snapshots'] = (cinder_objs.SnapshotList(
                context=self.CONTEXT))
            self._snapshots = []
            self._connections = []

        qos_specs = kwargs.pop('qos_specs', None)
        extra_specs = kwargs.pop('extra_specs', {})

        super(Volume, self).__init__(backend_or_vol, **kwargs)
        self._populate_data()
        self.local_attach = None

        # If we overwrote the host, then we ignore pool_name and don't set a
        # default value or copy the one from the source either.
        if 'host' not in kwargs and '__ovo' not in kwargs:
            # TODO(geguileo): Add pool support
            pool_name = pool_name or backend_or_vol.pool_names[0]
            self._ovo.host = ('%s@%s#%s' %
                              (cfg.CONF.host, backend_name, pool_name))

        if qos_specs or extra_specs:
            if qos_specs:
                qos_specs = cinder_objs.QualityOfServiceSpecs(
                    id=self.id,
                    name=self.id,
                    consumer='back-end',
                    specs=qos_specs)
                qos_specs_id = self.id
            else:
                qos_specs = qos_specs_id = None

            self._ovo.volume_type = cinder_objs.VolumeType(
                context=self.CONTEXT,
                is_public=True,
                id=self.id,
                name=self.id,
                qos_specs_id=qos_specs_id,
                extra_specs=extra_specs,
                qos_specs=qos_specs)
            self._ovo.volume_type_id = self.id
Пример #12
0
 def __connections_get(self, context, volume_id):
     # Used by drivers to lazy load volume_attachment
     connections = self.persistence.get_connections(volume_id=volume_id)
     ovos = [conn._ovo for conn in connections]
     result = objects.VolumeAttachmentList(objects=ovos)
     return result