Use uuid as the primary key
- Use uuid as the primary key - Correct some attributes definitions of the DB models NOTE: Nimble will support setting the scope check unique instance name in following patches Change-Id: Ia4cdaccb2162d15710dc0bdcc0e12ed1f7b76257
This commit is contained in:
parent
49e32319f5
commit
357a2dcfc4
@ -145,7 +145,7 @@ class InvalidUUID(Invalid):
|
||||
|
||||
|
||||
class InstanceTypeAlreadyExists(NimbleException):
|
||||
_msg_fmt = _("InstanceType with name %(name)s already exists.")
|
||||
_msg_fmt = _("InstanceType with uuid %(uuid)s already exists.")
|
||||
|
||||
|
||||
class InstanceTypeNotFound(NotFound):
|
||||
|
@ -81,7 +81,7 @@ class Connection(object):
|
||||
|
||||
@abc.abstractmethod
|
||||
def extra_specs_update_or_create(self, context,
|
||||
instance_type_id, extra_specs):
|
||||
instance_type_uuid, extra_specs):
|
||||
"""Create or update instance type extra specs.
|
||||
|
||||
This adds or modifies the key/value pairs specified in the
|
||||
@ -93,7 +93,7 @@ class Connection(object):
|
||||
"""Get instance type extra specs"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def type_extra_specs_delete(self, context, instance_type_id, key):
|
||||
def type_extra_specs_delete(self, context, instance_type_uuid, key):
|
||||
"""Delete instance type extra specs.
|
||||
|
||||
This deletes the key/value pairs specified in the
|
||||
|
@ -32,13 +32,11 @@ def upgrade():
|
||||
'instance_types',
|
||||
sa.Column('created_at', sa.DateTime(), nullable=True),
|
||||
sa.Column('updated_at', sa.DateTime(), nullable=True),
|
||||
sa.Column('id', sa.Integer(), nullable=False),
|
||||
sa.Column('uuid', sa.String(length=36), nullable=False),
|
||||
sa.Column('name', sa.String(length=255), nullable=False),
|
||||
sa.Column('description', sa.String(length=255), nullable=True),
|
||||
sa.Column('is_public', sa.Boolean(), nullable=False),
|
||||
sa.PrimaryKeyConstraint('id'),
|
||||
sa.UniqueConstraint('name', name='uniq_instance_types0name'),
|
||||
sa.PrimaryKeyConstraint('uuid'),
|
||||
mysql_ENGINE='InnoDB',
|
||||
mysql_DEFAULT_CHARSET='UTF8'
|
||||
)
|
||||
@ -47,10 +45,11 @@ def upgrade():
|
||||
sa.Column('created_at', sa.DateTime(), nullable=True),
|
||||
sa.Column('updated_at', sa.DateTime(), nullable=True),
|
||||
sa.Column('id', sa.Integer(), nullable=False),
|
||||
sa.Column('instance_type_id', sa.Integer(), nullable=False),
|
||||
sa.Column('instance_type_uuid', sa.String(length=36), nullable=False),
|
||||
sa.Column('key', sa.String(length=255), nullable=False),
|
||||
sa.Column('value', sa.String(length=255), nullable=False),
|
||||
sa.ForeignKeyConstraint(['instance_type_id'], ['instance_types.id'], ),
|
||||
sa.ForeignKeyConstraint(['instance_type_uuid'],
|
||||
['instance_types.uuid']),
|
||||
sa.PrimaryKeyConstraint('id'),
|
||||
mysql_ENGINE='InnoDB',
|
||||
mysql_DEFAULT_CHARSET='UTF8'
|
||||
@ -60,9 +59,10 @@ def upgrade():
|
||||
sa.Column('created_at', sa.DateTime(), nullable=True),
|
||||
sa.Column('updated_at', sa.DateTime(), nullable=True),
|
||||
sa.Column('id', sa.Integer(), nullable=False),
|
||||
sa.Column('instance_type_id', sa.Integer(), nullable=True),
|
||||
sa.Column('instance_type_uuid', sa.String(length=36), nullable=True),
|
||||
sa.Column('project_id', sa.String(length=36), nullable=True),
|
||||
sa.ForeignKeyConstraint(['instance_type_id'], ['instance_types.id'], ),
|
||||
sa.ForeignKeyConstraint(['instance_type_uuid'],
|
||||
['instance_types.uuid']),
|
||||
sa.PrimaryKeyConstraint('id'),
|
||||
mysql_ENGINE='InnoDB',
|
||||
mysql_DEFAULT_CHARSET='UTF8'
|
||||
@ -71,7 +71,6 @@ def upgrade():
|
||||
'instances',
|
||||
sa.Column('created_at', sa.DateTime(), nullable=True),
|
||||
sa.Column('updated_at', sa.DateTime(), nullable=True),
|
||||
sa.Column('id', sa.Integer(), nullable=False),
|
||||
sa.Column('uuid', sa.String(length=36), nullable=True),
|
||||
sa.Column('user_id', sa.String(length=36), nullable=True),
|
||||
sa.Column('project_id', sa.String(length=36), nullable=True),
|
||||
@ -85,9 +84,8 @@ def upgrade():
|
||||
sa.Column('availability_zone', sa.String(length=255), nullable=True),
|
||||
sa.Column('node_uuid', sa.String(length=36), nullable=True),
|
||||
sa.Column('extra', sa.Text(), nullable=True),
|
||||
sa.PrimaryKeyConstraint('id'),
|
||||
sa.PrimaryKeyConstraint('uuid'),
|
||||
sa.UniqueConstraint('uuid', name='uniq_instances0uuid'),
|
||||
sa.UniqueConstraint('name', name='uniq_instances0name'),
|
||||
mysql_ENGINE='InnoDB',
|
||||
mysql_DEFAULT_CHARSET='UTF8'
|
||||
)
|
||||
|
@ -120,7 +120,7 @@ class Connection(api.Connection):
|
||||
session.add(instance_type)
|
||||
session.flush()
|
||||
except db_exc.DBDuplicateEntry:
|
||||
raise exception.InstanceTypeAlreadyExists(name=values['name'])
|
||||
raise exception.InstanceTypeAlreadyExists(uuid=values['uuid'])
|
||||
return _dict_with_extra_specs(instance_type)
|
||||
|
||||
def instance_type_get(self, context, instance_type_uuid):
|
||||
@ -143,7 +143,7 @@ class Connection(api.Connection):
|
||||
extra_query = model_query(
|
||||
context,
|
||||
models.InstanceTypeExtraSpecs).filter_by(
|
||||
instance_type_id=type_id)
|
||||
instance_type_uuid=type_id)
|
||||
extra_query.delete()
|
||||
|
||||
# Then delete the type record
|
||||
@ -214,7 +214,8 @@ class Connection(api.Connection):
|
||||
ref.update(values)
|
||||
return ref
|
||||
|
||||
def extra_specs_update_or_create(self, context, instance_type_id, specs,
|
||||
def extra_specs_update_or_create(self, context,
|
||||
instance_type_uuid, specs,
|
||||
max_retries=10):
|
||||
"""Create or update instance type extra specs.
|
||||
|
||||
@ -226,7 +227,7 @@ class Connection(api.Connection):
|
||||
try:
|
||||
spec_refs = model_query(
|
||||
context, models.InstanceTypeExtraSpecs). \
|
||||
filter_by(instance_type_id=instance_type_id). \
|
||||
filter_by(instance_type_uuid=instance_type_uuid). \
|
||||
filter(models.InstanceTypeExtraSpecs.key.in_(
|
||||
specs.keys())).with_lockmode('update').all()
|
||||
|
||||
@ -242,7 +243,7 @@ class Connection(api.Connection):
|
||||
spec_ref = models.InstanceTypeExtraSpecs()
|
||||
spec_ref.update(
|
||||
{"key": key, "value": value,
|
||||
"instance_type_id": instance_type_id})
|
||||
"instance_type_uuid": instance_type_uuid})
|
||||
|
||||
session.add(spec_ref)
|
||||
session.flush()
|
||||
@ -253,7 +254,7 @@ class Connection(api.Connection):
|
||||
# try again unless this was the last attempt
|
||||
if attempt == max_retries - 1:
|
||||
raise exception.TypeExtraSpecUpdateCreateFailed(
|
||||
id=instance_type_id, retries=max_retries)
|
||||
id=instance_type_uuid, retries=max_retries)
|
||||
|
||||
def instance_type_extra_specs_get(self, context, type_id):
|
||||
rows = _type_extra_specs_get_query(context, type_id).all()
|
||||
@ -278,9 +279,9 @@ def _type_get_id_from_type(context, type_id):
|
||||
result = _type_get_id_from_type_query(context, type_id).first()
|
||||
if not result:
|
||||
raise exception.InstanceTypeNotFound(type_id=type_id)
|
||||
return result.id
|
||||
return result.uuid
|
||||
|
||||
|
||||
def _type_extra_specs_get_query(context, type_id):
|
||||
return model_query(context, models.InstanceTypeExtraSpecs). \
|
||||
filter_by(instance_type_id=type_id)
|
||||
filter_by(instance_type_uuid=type_id)
|
||||
|
@ -58,71 +58,15 @@ class NimbleBase(models.TimestampMixin,
|
||||
Base = declarative_base(cls=NimbleBase)
|
||||
|
||||
|
||||
class InstanceTypes(Base):
|
||||
"""Represents possible types for instances."""
|
||||
|
||||
__tablename__ = 'instance_types'
|
||||
__table_args__ = (
|
||||
schema.UniqueConstraint('name', name='uniq_instance_types0name'),
|
||||
table_args()
|
||||
)
|
||||
id = Column(Integer, primary_key=True)
|
||||
uuid = Column(String(36), nullable=False)
|
||||
name = Column(String(255), nullable=False)
|
||||
description = Column(String(255), nullable=True)
|
||||
is_public = Column(Boolean, default=True)
|
||||
|
||||
|
||||
class InstanceTypeProjects(Base):
|
||||
"""Represents projects associated instance_types."""
|
||||
|
||||
__tablename__ = 'instance_type_projects'
|
||||
__table_args__ = (
|
||||
schema.UniqueConstraint(
|
||||
'instance_type_id', 'project_id',
|
||||
name='uniq_instance_type_projects0instance_type_id0project_id'
|
||||
),
|
||||
table_args()
|
||||
)
|
||||
id = Column(Integer, primary_key=True)
|
||||
instance_type_id = Column(Integer, nullable=True)
|
||||
project_id = Column(String(36), nullable=True)
|
||||
|
||||
|
||||
class InstanceTypeExtraSpecs(Base):
|
||||
"""Represents additional specs as key/value pairs for an instance_type."""
|
||||
__tablename__ = 'instance_type_extra_specs'
|
||||
__table_args__ = (
|
||||
schema.UniqueConstraint(
|
||||
"instance_type_id", "key",
|
||||
name=("uniq_instance_type_extra_specs0"
|
||||
"instance_type_id")
|
||||
),
|
||||
{'mysql_collate': 'utf8_bin'},
|
||||
)
|
||||
id = Column(Integer, primary_key=True)
|
||||
key = Column(String(255))
|
||||
value = Column(String(255))
|
||||
instance_type_id = Column(Integer, ForeignKey('instance_types.id'),
|
||||
nullable=False)
|
||||
instance_type = orm.relationship(
|
||||
InstanceTypes, backref="extra_specs",
|
||||
foreign_keys=instance_type_id,
|
||||
primaryjoin='and_(InstanceTypeExtraSpecs.instance_type_id '
|
||||
'== InstanceTypes.id)')
|
||||
|
||||
|
||||
class Instance(Base):
|
||||
"""Represents possible types for instances."""
|
||||
|
||||
__tablename__ = 'instances'
|
||||
__table_args__ = (
|
||||
schema.UniqueConstraint('uuid', name='uniq_instances0uuid'),
|
||||
schema.UniqueConstraint('name', name='uniq_instances0name'),
|
||||
table_args()
|
||||
)
|
||||
id = Column(Integer, primary_key=True)
|
||||
uuid = Column(String(36), nullable=True)
|
||||
uuid = Column(String(36), primary_key=True)
|
||||
name = Column(String(255), nullable=False)
|
||||
description = Column(String(255), nullable=True)
|
||||
project_id = Column(String(36), nullable=True)
|
||||
@ -135,3 +79,63 @@ class Instance(Base):
|
||||
node_uuid = Column(String(36), nullable=True)
|
||||
launched_at = Column(DateTime, nullable=True)
|
||||
extra = Column(db_types.JsonEncodedDict)
|
||||
|
||||
|
||||
class InstanceTypes(Base):
|
||||
"""Represents possible types for instances."""
|
||||
|
||||
__tablename__ = 'instance_types'
|
||||
uuid = Column(String(36), primary_key=True)
|
||||
name = Column(String(255), nullable=False)
|
||||
description = Column(String(255), nullable=True)
|
||||
is_public = Column(Boolean, default=True)
|
||||
instances = orm.relationship(
|
||||
Instance,
|
||||
backref=orm.backref('instance_type', uselist=False),
|
||||
foreign_keys=uuid,
|
||||
primaryjoin='Instance.instance_type_uuid == InstanceTypes.uuid')
|
||||
|
||||
|
||||
class InstanceTypeProjects(Base):
|
||||
"""Represents projects associated instance_types."""
|
||||
|
||||
__tablename__ = 'instance_type_projects'
|
||||
__table_args__ = (
|
||||
schema.UniqueConstraint(
|
||||
'instance_type_uuid', 'project_id',
|
||||
name='uniq_instance_type_projects0instance_type_uuid0project_id'
|
||||
),
|
||||
table_args()
|
||||
)
|
||||
id = Column(Integer, primary_key=True)
|
||||
instance_type_uuid = Column(Integer, nullable=True)
|
||||
project_id = Column(String(36), nullable=True)
|
||||
instances = orm.relationship(
|
||||
InstanceTypes,
|
||||
backref=orm.backref('projects', uselist=False),
|
||||
foreign_keys=instance_type_uuid,
|
||||
primaryjoin='InstanceTypeProjects.instance_type_uuid'
|
||||
' == InstanceTypes.uuid')
|
||||
|
||||
|
||||
class InstanceTypeExtraSpecs(Base):
|
||||
"""Represents additional specs as key/value pairs for an instance_type."""
|
||||
__tablename__ = 'instance_type_extra_specs'
|
||||
__table_args__ = (
|
||||
schema.UniqueConstraint(
|
||||
"instance_type_uuid", "key",
|
||||
name=("uniq_instance_type_extra_specs0"
|
||||
"instance_type_uuid")
|
||||
),
|
||||
{'mysql_collate': 'utf8_bin'},
|
||||
)
|
||||
id = Column(Integer, primary_key=True)
|
||||
key = Column(String(255))
|
||||
value = Column(String(255))
|
||||
instance_type_uuid = Column(String(36), ForeignKey('instance_types.uuid'),
|
||||
nullable=False)
|
||||
instance_type = orm.relationship(
|
||||
InstanceTypes, backref="extra_specs",
|
||||
foreign_keys=instance_type_uuid,
|
||||
primaryjoin='InstanceTypeExtraSpecs.instance_type_uuid '
|
||||
'== InstanceTypes.uuid')
|
||||
|
@ -29,7 +29,6 @@ class Instance(base.NimbleObject, object_base.VersionedObjectDictCompat):
|
||||
dbapi = dbapi.get_instance()
|
||||
|
||||
fields = {
|
||||
'id': object_fields.IntegerField(),
|
||||
'uuid': object_fields.UUIDField(nullable=True),
|
||||
'name': object_fields.StringField(nullable=True),
|
||||
'description': object_fields.StringField(nullable=True),
|
||||
|
@ -30,7 +30,6 @@ class InstanceType(base.NimbleObject, object_base.VersionedObjectDictCompat):
|
||||
dbapi = dbapi.get_instance()
|
||||
|
||||
fields = {
|
||||
'id': object_fields.IntegerField(),
|
||||
'uuid': object_fields.UUIDField(nullable=True),
|
||||
'name': object_fields.StringField(nullable=True),
|
||||
'description': object_fields.StringField(nullable=True),
|
||||
@ -71,10 +70,10 @@ class InstanceType(base.NimbleObject, object_base.VersionedObjectDictCompat):
|
||||
context)
|
||||
|
||||
@classmethod
|
||||
def get(cls, context, instance_type_id):
|
||||
def get(cls, context, instance_type_uuid):
|
||||
"""Find a Instance Type and return a Instance Type object."""
|
||||
db_instance_type = cls.dbapi.instance_type_get(context,
|
||||
instance_type_id)
|
||||
instance_type_uuid)
|
||||
instance_type = InstanceType._from_db_object(cls(context),
|
||||
db_instance_type)
|
||||
return instance_type
|
||||
|
@ -28,11 +28,6 @@ class DbInstanceTestCase(base.DbTestCase):
|
||||
def test_instance_create(self):
|
||||
utils.create_test_instance()
|
||||
|
||||
def test_instance_create_already_exist(self):
|
||||
utils.create_test_instance()
|
||||
self.assertRaises(exception.InstanceAlreadyExists,
|
||||
utils.create_test_instance)
|
||||
|
||||
def test_instance_create_with_same_uuid(self):
|
||||
utils.create_test_instance(uuid='uuid', name='instance1')
|
||||
self.assertRaises(exception.InstanceAlreadyExists,
|
||||
@ -40,17 +35,9 @@ class DbInstanceTestCase(base.DbTestCase):
|
||||
uuid='uuid',
|
||||
name='instance2')
|
||||
|
||||
def test_instance_create_with_duplicate_name(self):
|
||||
utils.create_test_instance(uuid='uuid-1', name='instance')
|
||||
self.assertRaises(exception.InstanceAlreadyExists,
|
||||
utils.create_test_instance,
|
||||
uuid='uuid-2',
|
||||
name='instance')
|
||||
|
||||
def test_instance_get_by_uuid(self):
|
||||
instance = utils.create_test_instance()
|
||||
res = self.dbapi.instance_get(self.context, instance.uuid)
|
||||
self.assertEqual(instance.id, res.id)
|
||||
self.assertEqual(instance.uuid, res.uuid)
|
||||
|
||||
def test_instance_get_not_exist(self):
|
||||
@ -119,7 +106,7 @@ class DbInstanceTestCase(base.DbTestCase):
|
||||
self.assertNotEqual(old_extra, new_extra)
|
||||
|
||||
res = self.dbapi.instance_update(self.context,
|
||||
instance.id,
|
||||
instance.uuid,
|
||||
{'extra': new_extra})
|
||||
self.assertEqual(new_extra, res.extra)
|
||||
|
||||
@ -128,15 +115,5 @@ class DbInstanceTestCase(base.DbTestCase):
|
||||
self.assertRaises(exception.InvalidParameterValue,
|
||||
self.dbapi.instance_update,
|
||||
self.context,
|
||||
instance.id,
|
||||
instance.uuid,
|
||||
{'uuid': '12345678-9999-0000-aaaa-123456789012'})
|
||||
|
||||
def test_instance_update_with_duplicate_name(self):
|
||||
instance1 = utils.create_test_instance(uuid=uuidutils.generate_uuid(),
|
||||
name='spam')
|
||||
instance2 = utils.create_test_instance(uuid=uuidutils.generate_uuid())
|
||||
self.assertRaises(exception.DuplicateName,
|
||||
self.dbapi.instance_update,
|
||||
self.context,
|
||||
instance2.id,
|
||||
{'name': instance1.name})
|
||||
|
@ -14,6 +14,7 @@
|
||||
# under the License.
|
||||
"""Nimble test utilities."""
|
||||
|
||||
from oslo_utils import uuidutils
|
||||
|
||||
from nimble.db import api as db_api
|
||||
from nimble.engine import status
|
||||
@ -38,8 +39,7 @@ def get_test_instance(**kw):
|
||||
}
|
||||
|
||||
return {
|
||||
'id': kw.get('id', 123),
|
||||
'uuid': kw.get('uuid', '1be26c0b-03f2-4d2e-ae87-c02d7f33c123'),
|
||||
'uuid': kw.get('uuid', uuidutils.generate_uuid()),
|
||||
'name': kw.get('name', 'test'),
|
||||
'description': kw.get('description', 'test'),
|
||||
'project_id': kw.get('project_id',
|
||||
@ -72,9 +72,6 @@ def create_test_instance(context={}, **kw):
|
||||
|
||||
"""
|
||||
instance = get_test_instance(**kw)
|
||||
# Let DB generate ID if it isn't specified explicitly
|
||||
if 'id' not in kw:
|
||||
del instance['id']
|
||||
dbapi = db_api.get_instance()
|
||||
|
||||
return dbapi.instance_create(context, instance)
|
||||
@ -82,8 +79,7 @@ def create_test_instance(context={}, **kw):
|
||||
|
||||
def get_test_instance_type(**kw):
|
||||
return {
|
||||
'id': kw.get('id', 123),
|
||||
'uuid': kw.get('uuid', 'e5ddde02-f84d-4da7-ade3-957c55072986'),
|
||||
'uuid': kw.get('uuid', uuidutils.generate_uuid()),
|
||||
'name': kw.get('name', 'test'),
|
||||
'description': kw.get('description', 'test'),
|
||||
'is_public': kw.get('is_public', 1),
|
||||
@ -103,9 +99,6 @@ def create_test_instance_type(context={}, **kw):
|
||||
|
||||
"""
|
||||
instance_type = get_test_instance_type(**kw)
|
||||
# Let DB generate ID if it isn't specified explicitly
|
||||
if 'id' not in kw:
|
||||
del instance_type['id']
|
||||
dbapi = db_api.get_instance()
|
||||
|
||||
return dbapi.instance_type_create(context, instance_type)
|
||||
|
@ -63,7 +63,7 @@ class TestInstanceObject(base.DbTestCase):
|
||||
values = instance.obj_get_changes()
|
||||
instance.create(self.context)
|
||||
mock_instance_create.assert_called_once_with(self.context, values)
|
||||
self.assertEqual(self.fake_instance['id'], instance['id'])
|
||||
self.assertEqual(self.fake_instance['uuid'], instance['uuid'])
|
||||
|
||||
def test_destroy(self):
|
||||
uuid = self.fake_instance['uuid']
|
||||
|
@ -59,7 +59,7 @@ class TestInstanceTypeObject(base.DbTestCase):
|
||||
values = instance_type.obj_get_changes()
|
||||
instance_type.create(self.context)
|
||||
mock_type_create.assert_called_once_with(self.context, values)
|
||||
self.assertEqual(self.fake_type['id'], instance_type['id'])
|
||||
self.assertEqual(self.fake_type['uuid'], instance_type['uuid'])
|
||||
|
||||
def test_destroy(self):
|
||||
uuid = self.fake_type['uuid']
|
||||
|
@ -382,8 +382,8 @@ class _TestObject(object):
|
||||
# version bump. It is md5 hash of object fields and remotable methods.
|
||||
# The fingerprint values should only be changed if there is a version bump.
|
||||
expected_object_fingerprints = {
|
||||
'Instance': '1.0-8e0020044883e77e6d8d02f6a28c50d8',
|
||||
'InstanceType': '1.0-7f2a032fc45bb605dc792dc22462d98d',
|
||||
'Instance': '1.0-b861be9748601f713458a7a709eafd6b',
|
||||
'InstanceType': '1.0-589b096651fcdb30898ff50f748dd948',
|
||||
'MyObj': '1.1-4f5efe8f0fcaf182bbe1c7fe3ba858db',
|
||||
'FakeNode': '1.0-295d1b08ce3048535926c47dedd27211',
|
||||
}
|
||||
|
@ -50,10 +50,6 @@ def get_test_instance(ctxt, **kw):
|
||||
get_db_instance_checked = check_keyword_arguments(
|
||||
db_utils.get_test_instance)
|
||||
db_instance = get_db_instance_checked(**kw)
|
||||
|
||||
# Let DB generate ID if it isn't specified explicitly
|
||||
if 'id' not in kw:
|
||||
del db_instance['id']
|
||||
instance = objects.Instance(ctxt)
|
||||
for key in db_instance:
|
||||
setattr(instance, key, db_instance[key])
|
||||
|
Loading…
Reference in New Issue
Block a user