diff --git a/nova/api/openstack/compute/contrib/server_groups.py b/nova/api/openstack/compute/contrib/server_groups.py index 3a970f83a33e..fdb2d3d0ce63 100644 --- a/nova/api/openstack/compute/contrib/server_groups.py +++ b/nova/api/openstack/compute/contrib/server_groups.py @@ -137,7 +137,9 @@ class ServerGroupController(wsgi.Controller): server_group['id'] = group.uuid server_group['name'] = group.name server_group['policies'] = group.policies or [] - server_group['metadata'] = group.metadetails or {} + # NOTE(danms): This has been exposed to the user, but never used. + # Since we can't remove it, just make sure it's always empty. + server_group['metadata'] = {} members = [] if group.members: # Display the instances that are not deleted. diff --git a/nova/db/api.py b/nova/db/api.py index 801a0d0fe6bd..81b38e0a0684 100644 --- a/nova/db/api.py +++ b/nova/db/api.py @@ -801,15 +801,13 @@ def instance_remove_security_group(context, instance_id, security_group_id): #################### -def instance_group_create(context, values, policies=None, metadata=None, - members=None): - """Create a new group with metadata. +def instance_group_create(context, values, policies=None, members=None): + """Create a new group. Each group will receive a unique uuid. This will be used for access to the group. """ - return IMPL.instance_group_create(context, values, policies, metadata, - members) + return IMPL.instance_group_create(context, values, policies, members) def instance_group_get(context, group_uuid): diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py index f92e498a688c..e52ca35d6d35 100644 --- a/nova/db/sqlalchemy/api.py +++ b/nova/db/sqlalchemy/api.py @@ -5684,8 +5684,7 @@ def archive_deleted_rows(context, max_rows=None): def _instance_group_get_query(context, model_class, id_field=None, id=None, session=None, read_deleted=None): - columns_to_join = {models.InstanceGroup: ['_policies', '_metadata', - '_members']} + columns_to_join = {models.InstanceGroup: ['_policies', '_members']} query = model_query(context, model_class, session=session, read_deleted=read_deleted) @@ -5698,9 +5697,9 @@ def _instance_group_get_query(context, model_class, id_field=None, id=None, return query -def instance_group_create(context, values, policies=None, metadata=None, +def instance_group_create(context, values, policies=None, members=None): - """Create a new group with metadata.""" + """Create a new group.""" uuid = values.get('uuid', None) if uuid is None: uuid = uuidutils.generate_uuid() @@ -5717,14 +5716,10 @@ def instance_group_create(context, values, policies=None, metadata=None, # We don't want these to be lazy loaded later. We know there is # nothing here since we just created this instance group. group._policies = [] - group._metadata = [] group._members = [] if policies: _instance_group_policies_add(context, group.id, policies, session=session) - if metadata: - _instance_group_metadata_add(context, group.id, metadata, - session=session) if members: _instance_group_members_add(context, group.id, members, session=session) @@ -5766,13 +5761,6 @@ def instance_group_update(context, group_uuid, values): values.pop('policies'), set_delete=True, session=session) - metadata = values.get('metadata') - if metadata is not None: - _instance_group_metadata_add(context, - group.id, - values.pop('metadata'), - set_delete=True, - session=session) members = values.get('members') if members is not None: _instance_group_members_add(context, @@ -5785,8 +5773,6 @@ def instance_group_update(context, group_uuid, values): if policies: values['policies'] = policies - if metadata: - values['metadata'] = metadata if members: values['members'] = members @@ -5807,7 +5793,6 @@ def instance_group_delete(context, group_uuid): # Delete policies, metadata and members instance_models = [models.InstanceGroupPolicy, - models.InstanceGroupMetadata, models.InstanceGroupMember] for model in instance_models: model_query(context, model, session=session).\ @@ -5850,70 +5835,6 @@ def _instance_group_id(context, group_uuid, session=None): return result.id -def _instance_group_metadata_add(context, id, metadata, set_delete=False, - session=None): - if not session: - session = get_session() - - with session.begin(subtransactions=True): - all_keys = metadata.keys() - query = _instance_group_model_get_query(context, - models.InstanceGroupMetadata, - id, - session=session) - if set_delete: - query.filter(~models.InstanceGroupMetadata.key.in_(all_keys)).\ - soft_delete(synchronize_session=False) - - query = query.filter(models.InstanceGroupMetadata.key.in_(all_keys)) - already_existing_keys = set() - for meta_ref in query.all(): - key = meta_ref.key - meta_ref.update({'value': metadata[key]}) - already_existing_keys.add(key) - - for key, value in metadata.iteritems(): - if key in already_existing_keys: - continue - meta_ref = models.InstanceGroupMetadata() - meta_ref.update({'key': key, - 'value': value, - 'group_id': id}) - session.add(meta_ref) - - return metadata - - -def instance_group_metadata_add(context, group_uuid, metadata, - set_delete=False): - id = _instance_group_id(context, group_uuid) - return _instance_group_metadata_add(context, id, metadata, - set_delete=set_delete) - - -def instance_group_metadata_delete(context, group_uuid, key): - id = _instance_group_id(context, group_uuid) - count = _instance_group_get_query(context, - models.InstanceGroupMetadata, - models.InstanceGroupMetadata.group_id, - id).\ - filter_by(key=key).\ - soft_delete() - if count == 0: - raise exception.InstanceGroupMetadataNotFound(group_uuid=group_uuid, - metadata_key=key) - - -def instance_group_metadata_get(context, group_uuid): - id = _instance_group_id(context, group_uuid) - rows = model_query(context, - models.InstanceGroupMetadata.key, - models.InstanceGroupMetadata.value, - base_model=models.InstanceGroupMetadata).\ - filter_by(group_id=id).all() - return dict((r[0], r[1]) for r in rows) - - def _instance_group_members_add(context, id, members, set_delete=False, session=None): if not session: diff --git a/nova/db/sqlalchemy/models.py b/nova/db/sqlalchemy/models.py index e1008515cc5b..9f985963c9ed 100644 --- a/nova/db/sqlalchemy/models.py +++ b/nova/db/sqlalchemy/models.py @@ -1305,19 +1305,6 @@ class InstanceGroupPolicy(BASE, NovaBase): nullable=False) -class InstanceGroupMetadata(BASE, NovaBase): - """Represents a key/value pair for an instance group.""" - __tablename__ = 'instance_group_metadata' - __table_args__ = ( - Index('instance_group_metadata_key_idx', 'key'), - ) - id = Column(Integer, primary_key=True, nullable=False) - key = Column(String(255)) - value = Column(String(255)) - group_id = Column(Integer, ForeignKey('instance_groups.id'), - nullable=False) - - class InstanceGroup(BASE, NovaBase): """Represents an instance group. @@ -1340,10 +1327,6 @@ class InstanceGroup(BASE, NovaBase): 'InstanceGroup.id == InstanceGroupPolicy.group_id,' 'InstanceGroupPolicy.deleted == 0,' 'InstanceGroup.deleted == 0)') - _metadata = orm.relationship(InstanceGroupMetadata, primaryjoin='and_(' - 'InstanceGroup.id == InstanceGroupMetadata.group_id,' - 'InstanceGroupMetadata.deleted == 0,' - 'InstanceGroup.deleted == 0)') _members = orm.relationship(InstanceGroupMember, primaryjoin='and_(' 'InstanceGroup.id == InstanceGroupMember.group_id,' 'InstanceGroupMember.deleted == 0,' @@ -1353,10 +1336,6 @@ class InstanceGroup(BASE, NovaBase): def policies(self): return [p.policy for p in self._policies] - @property - def metadetails(self): - return dict((m.key, m.value) for m in self._metadata) - @property def members(self): return [m.instance_id for m in self._members] diff --git a/nova/objects/instance_group.py b/nova/objects/instance_group.py index 5e8ea18e174a..1e1691701c26 100644 --- a/nova/objects/instance_group.py +++ b/nova/objects/instance_group.py @@ -28,7 +28,8 @@ class InstanceGroup(base.NovaPersistentObject, base.NovaObject): # Version 1.4: Add add_members() # Version 1.5: Add get_hosts() # Version 1.6: Add get_by_name() - VERSION = '1.6' + # Version 1.7: Deprecate metadetails + VERSION = '1.7' fields = { 'id': fields.IntegerField(), @@ -40,10 +41,15 @@ class InstanceGroup(base.NovaPersistentObject, base.NovaObject): 'name': fields.StringField(nullable=True), 'policies': fields.ListOfStringsField(nullable=True), - 'metadetails': fields.DictOfStringsField(nullable=True), 'members': fields.ListOfStringsField(nullable=True), } + def obj_make_compatible(self, primitive, target_version): + if target_version < (1, 7): + # NOTE(danms): Before 1.7, we had an always-empty + # metadetails property + primitive['metadetails'] = {} + @staticmethod def _from_db_object(context, instance_group, db_inst): """Method to help with migration to objects. @@ -95,11 +101,6 @@ class InstanceGroup(base.NovaPersistentObject, base.NovaObject): if not updates: return - metadata = None - if 'metadetails' in updates: - metadata = updates.pop('metadetails') - updates.update({'metadata': metadata}) - db.instance_group_update(context, self.uuid, updates) db_inst = db.instance_group_get(context, self.uuid) self._from_db_object(context, self, db_inst) @@ -122,11 +123,9 @@ class InstanceGroup(base.NovaPersistentObject, base.NovaObject): updates.pop('id', None) policies = updates.pop('policies', None) members = updates.pop('members', None) - metadetails = updates.pop('metadetails', None) db_inst = db.instance_group_create(context, updates, policies=policies, - metadata=metadetails, members=members) self._from_db_object(context, self, db_inst) @@ -165,6 +164,8 @@ class InstanceGroupList(base.ObjectListBase, base.NovaObject): # InstanceGroup <= version 1.3 # Version 1.1: InstanceGroup <= version 1.4 # Version 1.2: InstanceGroup <= version 1.5 + # Version 1.3: InstanceGroup <= version 1.6 + # Version 1.4: InstanceGroup <= version 1.7 VERSION = '1.2' fields = { @@ -176,6 +177,7 @@ class InstanceGroupList(base.ObjectListBase, base.NovaObject): '1.1': '1.4', '1.2': '1.5', '1.3': '1.6', + '1.4': '1.7', } @base.remotable_classmethod diff --git a/nova/tests/api/openstack/compute/contrib/test_server_groups.py b/nova/tests/api/openstack/compute/contrib/test_server_groups.py index 62745133d7d8..54b1241d7170 100644 --- a/nova/tests/api/openstack/compute/contrib/test_server_groups.py +++ b/nova/tests/api/openstack/compute/contrib/test_server_groups.py @@ -48,7 +48,6 @@ def server_group_resp_template(**kwargs): sgroup.setdefault('name', 'test') sgroup.setdefault('policies', []) sgroup.setdefault('members', []) - sgroup.setdefault('metadata', {}) return sgroup @@ -66,10 +65,6 @@ def server_group_db(sg): attrs['members'] = members else: attrs['members'] = [] - if 'metadata' in attrs: - attrs['metadetails'] = attrs.pop('metadata') - else: - attrs['metadetails'] = {} attrs['deleted'] = 0 attrs['deleted_at'] = None attrs['created_at'] = None @@ -257,7 +252,7 @@ class ServerGroupTest(test.TestCase): groups = [] policies = ['anti-affinity'] members = [] - metadata = {'key1': 'value1'} + metadata = {} # always empty names = ['default-x', 'test'] sg1 = server_group_resp_template(id=str(1345), name=names[0], @@ -287,7 +282,7 @@ class ServerGroupTest(test.TestCase): tenant_groups = [] policies = ['anti-affinity'] members = [] - metadata = {'key1': 'value1'} + metadata = {} # always empty names = ['default-x', 'test'] sg1 = server_group_resp_template(id=str(1345), name=names[0], @@ -428,7 +423,6 @@ class TestServerGroupXMLSerializer(test.TestCase): def _verify_server_group(self, raw_group, tree): policies = raw_group['policies'] members = raw_group['members'] - metadata = raw_group['metadata'] self.assertEqual('server_group', self._tag(tree)) self.assertEqual(raw_group['id'], tree.get('id')) self.assertEqual(raw_group['name'], tree.get('name')) @@ -448,16 +442,7 @@ class TestServerGroupXMLSerializer(test.TestCase): self.assertEqual(members[idx], gr_child.text) elif child_tag == 'metadata': - self.assertEqual(len(metadata), len(child)) - metas = {} - for idx, gr_child in enumerate(child): - self.assertEqual(self._tag(gr_child), 'meta') - key = gr_child.get('key') - self.assertIn(key, ['key1', 'key2']) - metas[key] = gr_child.text - self.assertEqual(len(metas), len(metadata)) - for k in metadata: - self.assertEqual(metadata[k], metas[k]) + self.assertEqual(0, len(child)) def _verify_server_group_brief(self, raw_group, tree): self.assertEqual('server_group', self._tag(tree)) @@ -467,13 +452,11 @@ class TestServerGroupXMLSerializer(test.TestCase): def test_group_serializer(self): policies = ["policy-1", "policy-2"] members = ["1", "2"] - metadata = dict(key1="value1", key2="value2") raw_group = dict( id='890', name='name', policies=policies, - members=members, - metadata=metadata) + members=members) sg_group = dict(server_group=raw_group) text = self.default_serializer.serialize(sg_group) @@ -485,19 +468,16 @@ class TestServerGroupXMLSerializer(test.TestCase): policies = ["policy-1", "policy-2", "policy-3"] members = ["1", "2", "3"] - metadata = dict(key1="value1", key2="value2") groups = [dict( id='890', name='test', policies=policies[0:2], - members=members[0:2], - metadata=metadata), + members=members[0:2]), dict( id='123', name='default', policies=policies[2:], - members=members[2:], - metadata=metadata)] + members=members[2:])] sg_groups = dict(server_groups=groups) text = self.index_serializer.serialize(sg_groups) diff --git a/nova/tests/db/test_db_api.py b/nova/tests/db/test_db_api.py index 437830d527f5..67fd107a225f 100644 --- a/nova/tests/db/test_db_api.py +++ b/nova/tests/db/test_db_api.py @@ -6667,9 +6667,9 @@ class InstanceGroupDBApiTestCase(test.TestCase, ModelsObjectComparatorMixin): 'project_id': self.project_id} def _create_instance_group(self, context, values, policies=None, - metadata=None, members=None): + members=None): return db.instance_group_create(context, values, policies=policies, - metadata=metadata, members=members) + members=members) def test_instance_group_create_no_key(self): values = self._get_default_values() @@ -6781,15 +6781,6 @@ class InstanceGroupDBApiTestCase(test.TestCase, ModelsObjectComparatorMixin): db.instance_group_update(self.context, id, values) result = db.instance_group_get(self.context, id) self.assertEqual(result['name'], 'new_fake_name') - # update metadata - values = self._get_default_values() - metadataInput = {'key11': 'value1', - 'key12': 'value2'} - values['metadata'] = metadataInput - db.instance_group_update(self.context, id, values) - result = db.instance_group_get(self.context, id) - metadata = result['metadetails'] - self._assertEqualObjects(metadata, metadataInput) # update update members values = self._get_default_values() members = ['instance_id1', 'instance_id2'] @@ -6810,86 +6801,6 @@ class InstanceGroupDBApiTestCase(test.TestCase, ModelsObjectComparatorMixin): 'invalid_id', values) -class InstanceGroupMetadataDBApiTestCase(InstanceGroupDBApiTestCase): - def test_instance_group_metadata_on_create(self): - values = self._get_default_values() - values['uuid'] = 'fake_id' - metadata = {'key11': 'value1', - 'key12': 'value2'} - result = self._create_instance_group(self.context, values, - metadata=metadata) - ignored_keys = ['id', 'deleted', 'deleted_at', 'updated_at', - 'created_at'] - self._assertEqualObjects(result, values, ignored_keys) - self._assertEqualObjects(metadata, result['metadetails']) - - def test_instance_group_metadata_add(self): - values = self._get_default_values() - values['uuid'] = 'fake_id' - result = self._create_instance_group(self.context, values) - id = result['uuid'] - metadata = db.instance_group_metadata_get(self.context, id) - self._assertEqualObjects(metadata, {}) - metadata = {'key1': 'value1', - 'key2': 'value2'} - db.instance_group_metadata_add(self.context, id, metadata) - metadata2 = db.instance_group_metadata_get(self.context, id) - self._assertEqualObjects(metadata, metadata2) - - def test_instance_group_update(self): - values = self._get_default_values() - values['uuid'] = 'fake_id' - result = self._create_instance_group(self.context, values) - id = result['uuid'] - metadata = {'key1': 'value1', - 'key2': 'value2'} - db.instance_group_metadata_add(self.context, id, metadata) - metadata2 = db.instance_group_metadata_get(self.context, id) - self._assertEqualObjects(metadata, metadata2) - # check add with existing keys - metadata = {'key1': 'value1', - 'key2': 'value2', - 'key3': 'value3'} - db.instance_group_metadata_add(self.context, id, metadata) - metadata3 = db.instance_group_metadata_get(self.context, id) - self._assertEqualObjects(metadata, metadata3) - - def test_instance_group_delete(self): - values = self._get_default_values() - values['uuid'] = 'fake_id' - result = self._create_instance_group(self.context, values) - id = result['uuid'] - metadata = {'key1': 'value1', - 'key2': 'value2', - 'key3': 'value3'} - db.instance_group_metadata_add(self.context, id, metadata) - metadata3 = db.instance_group_metadata_get(self.context, id) - self._assertEqualObjects(metadata, metadata3) - db.instance_group_metadata_delete(self.context, id, 'key1') - metadata = db.instance_group_metadata_get(self.context, id) - self.assertNotIn('key1', metadata) - db.instance_group_metadata_delete(self.context, id, 'key2') - metadata = db.instance_group_metadata_get(self.context, id) - self.assertNotIn('key2', metadata) - - def test_instance_group_metadata_invalid_ids(self): - values = self._get_default_values() - result = self._create_instance_group(self.context, values) - id = result['uuid'] - self.assertRaises(exception.InstanceGroupNotFound, - db.instance_group_metadata_get, - self.context, 'invalid') - self.assertRaises(exception.InstanceGroupNotFound, - db.instance_group_metadata_delete, self.context, - 'invalidid', 'key1') - metadata = {'key1': 'value1', - 'key2': 'value2'} - db.instance_group_metadata_add(self.context, id, metadata) - self.assertRaises(exception.InstanceGroupMetadataNotFound, - db.instance_group_metadata_delete, - self.context, id, 'invalidkey') - - class InstanceGroupMembersDBApiTestCase(InstanceGroupDBApiTestCase): def test_instance_group_members_on_create(self): values = self._get_default_values() diff --git a/nova/tests/objects/test_instance_group.py b/nova/tests/objects/test_instance_group.py index c2093ef04718..113e0dd688dc 100644 --- a/nova/tests/objects/test_instance_group.py +++ b/nova/tests/objects/test_instance_group.py @@ -38,23 +38,19 @@ class _TestInstanceGroupObjects(test.TestCase): 'project_id': self.project_id} def _create_instance_group(self, context, values, policies=None, - metadata=None, members=None): + members=None): return db.instance_group_create(context, values, policies=policies, - metadata=metadata, members=members) + members=members) def test_get_by_uuid(self): values = self._get_default_values() - metadata = {'key11': 'value1', - 'key12': 'value2'} policies = ['policy1', 'policy2'] members = ['instance_id1', 'instance_id2'] db_result = self._create_instance_group(self.context, values, - metadata=metadata, policies=policies, members=members) obj_result = instance_group.InstanceGroup.get_by_uuid(self.context, db_result.uuid) - self.assertEqual(obj_result.metadetails, metadata) self.assertEqual(obj_result.members, members) self.assertEqual(obj_result.policies, policies) @@ -105,18 +101,6 @@ class _TestInstanceGroupObjects(test.TestCase): result = db.instance_group_get(self.context, db_result['uuid']) self.assertEqual(result['members'], members) - def test_save_metadata(self): - values = self._get_default_values() - db_result = self._create_instance_group(self.context, values) - obj_result = instance_group.InstanceGroup.get_by_uuid(self.context, - db_result.uuid) - metadata = {'foo': 'bar'} - obj_result.metadetails = metadata - obj_result.save() - db.instance_group_metadata_get(self.context, db_result['uuid']) - for key, value in metadata.iteritems(): - self.assertEqual(value, metadata[key]) - def test_create(self): group1 = instance_group.InstanceGroup() group1.uuid = 'fake-uuid' @@ -150,17 +134,6 @@ class _TestInstanceGroupObjects(test.TestCase): self.assertEqual(group1.id, group2.id) self.assertEqual(group1.members, group2.members) - def test_create_with_metadata(self): - group1 = instance_group.InstanceGroup() - metadata = {'foo': 'bar'} - group1.metadetails = metadata - group1.create(self.context) - group2 = instance_group.InstanceGroup.get_by_uuid(self.context, - group1.uuid) - self.assertEqual(group1.id, group2.id) - for key, value in metadata.iteritems(): - self.assertEqual(value, group2.metadetails[key]) - def test_recreate_fails(self): group = instance_group.InstanceGroup() group.create(self.context) diff --git a/nova/tests/objects/test_objects.py b/nova/tests/objects/test_objects.py index 278e8fe85496..59fe895d273c 100644 --- a/nova/tests/objects/test_objects.py +++ b/nova/tests/objects/test_objects.py @@ -924,7 +924,7 @@ object_data = { 'InstanceExternalEvent': '1.0-f1134523654407a875fd59b80f759ee7', 'InstanceFault': '1.2-313438e37e9d358f3566c85f6ddb2d3e', 'InstanceFaultList': '1.1-bd578be60d045629ca7b3ce1a2493ae4', - 'InstanceGroup': '1.6-c032430832b3cbaf92c99088e4b2fdc8', + 'InstanceGroup': '1.7-b31ea31fdb452ab7810adbe789244f91', 'InstanceGroupList': '1.2-bebd07052779ae3b47311efe85428a8b', 'InstanceInfoCache': '1.5-ef64b604498bfa505a8c93747a9d8b2f', 'InstanceList': '1.6-78800140a5f9818ab00f8c052437655f',