Merge "apidb: Compact Ocata database migrations"
This commit is contained in:
commit
f512ee632c
|
@ -1,23 +0,0 @@
|
|||
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
# This is a placeholder for backports.
|
||||
# Do not use this number for new work. New work starts after
|
||||
# all the placeholders.
|
||||
#
|
||||
# See this for more information:
|
||||
# http://lists.openstack.org/pipermail/openstack-dev/2013-March/006827.html
|
||||
|
||||
|
||||
def upgrade(migrate_engine):
|
||||
pass
|
|
@ -1,23 +0,0 @@
|
|||
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
# This is a placeholder for backports.
|
||||
# Do not use this number for new work. New work starts after
|
||||
# all the placeholders.
|
||||
#
|
||||
# See this for more information:
|
||||
# http://lists.openstack.org/pipermail/openstack-dev/2013-March/006827.html
|
||||
|
||||
|
||||
def upgrade(migrate_engine):
|
||||
pass
|
|
@ -1,23 +0,0 @@
|
|||
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
# This is a placeholder for backports.
|
||||
# Do not use this number for new work. New work starts after
|
||||
# all the placeholders.
|
||||
#
|
||||
# See this for more information:
|
||||
# http://lists.openstack.org/pipermail/openstack-dev/2013-March/006827.html
|
||||
|
||||
|
||||
def upgrade(migrate_engine):
|
||||
pass
|
|
@ -1,23 +0,0 @@
|
|||
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
# This is a placeholder for backports.
|
||||
# Do not use this number for new work. New work starts after
|
||||
# all the placeholders.
|
||||
#
|
||||
# See this for more information:
|
||||
# http://lists.openstack.org/pipermail/openstack-dev/2013-March/006827.html
|
||||
|
||||
|
||||
def upgrade(migrate_engine):
|
||||
pass
|
|
@ -1,23 +0,0 @@
|
|||
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
# This is a placeholder for backports.
|
||||
# Do not use this number for new work. New work starts after
|
||||
# all the placeholders.
|
||||
#
|
||||
# See this for more information:
|
||||
# http://lists.openstack.org/pipermail/openstack-dev/2013-March/006827.html
|
||||
|
||||
|
||||
def upgrade(migrate_engine):
|
||||
pass
|
|
@ -1,36 +0,0 @@
|
|||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from migrate import UniqueConstraint
|
||||
from sqlalchemy import Column
|
||||
from sqlalchemy import DateTime
|
||||
from sqlalchemy import Integer
|
||||
from sqlalchemy import MetaData
|
||||
from sqlalchemy import String
|
||||
from sqlalchemy import Table
|
||||
|
||||
|
||||
def upgrade(migrate_engine):
|
||||
meta = MetaData()
|
||||
meta.bind = migrate_engine
|
||||
|
||||
resource_classes = Table('resource_classes', meta,
|
||||
Column('id', Integer, primary_key=True, nullable=False),
|
||||
Column('name', String(length=255), nullable=False),
|
||||
Column('created_at', DateTime),
|
||||
Column('updated_at', DateTime),
|
||||
UniqueConstraint('name', name='uniq_resource_classes0name'),
|
||||
mysql_engine='InnoDB',
|
||||
mysql_charset='latin1'
|
||||
)
|
||||
|
||||
resource_classes.create(checkfirst=True)
|
|
@ -1,124 +0,0 @@
|
|||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
"""API Database migrations for quotas"""
|
||||
|
||||
from migrate import UniqueConstraint
|
||||
from sqlalchemy import Column
|
||||
from sqlalchemy import DateTime
|
||||
from sqlalchemy import ForeignKey
|
||||
from sqlalchemy import Index
|
||||
from sqlalchemy import Integer
|
||||
from sqlalchemy import MetaData
|
||||
from sqlalchemy import String
|
||||
from sqlalchemy import Table
|
||||
|
||||
|
||||
def upgrade(migrate_engine):
|
||||
meta = MetaData()
|
||||
meta.bind = migrate_engine
|
||||
|
||||
quota_classes = Table('quota_classes', meta,
|
||||
Column('created_at', DateTime),
|
||||
Column('updated_at', DateTime),
|
||||
Column('id', Integer, primary_key=True, nullable=False),
|
||||
Column('class_name', String(length=255)),
|
||||
Column('resource', String(length=255)),
|
||||
Column('hard_limit', Integer),
|
||||
Index('quota_classes_class_name_idx', 'class_name'),
|
||||
mysql_engine='InnoDB',
|
||||
mysql_charset='utf8'
|
||||
)
|
||||
|
||||
quota_classes.create(checkfirst=True)
|
||||
|
||||
quota_usages = Table('quota_usages', meta,
|
||||
Column('created_at', DateTime),
|
||||
Column('updated_at', DateTime),
|
||||
Column('id', Integer, primary_key=True, nullable=False),
|
||||
Column('project_id', String(length=255)),
|
||||
Column('resource', String(length=255), nullable=False),
|
||||
Column('in_use', Integer, nullable=False),
|
||||
Column('reserved', Integer, nullable=False),
|
||||
Column('until_refresh', Integer),
|
||||
Column('user_id', String(length=255)),
|
||||
Index('quota_usages_project_id_idx', 'project_id'),
|
||||
Index('quota_usages_user_id_idx', 'user_id'),
|
||||
mysql_engine='InnoDB',
|
||||
mysql_charset='utf8'
|
||||
)
|
||||
|
||||
quota_usages.create(checkfirst=True)
|
||||
|
||||
quotas = Table('quotas', meta,
|
||||
Column('id', Integer, primary_key=True, nullable=False),
|
||||
Column('created_at', DateTime),
|
||||
Column('updated_at', DateTime),
|
||||
Column('project_id', String(length=255)),
|
||||
Column('resource', String(length=255), nullable=False),
|
||||
Column('hard_limit', Integer),
|
||||
UniqueConstraint('project_id', 'resource',
|
||||
name='uniq_quotas0project_id0resource'),
|
||||
mysql_engine='InnoDB',
|
||||
mysql_charset='utf8'
|
||||
)
|
||||
|
||||
quotas.create(checkfirst=True)
|
||||
|
||||
uniq_name = "uniq_project_user_quotas0user_id0project_id0resource"
|
||||
project_user_quotas = Table('project_user_quotas', meta,
|
||||
Column('id', Integer, primary_key=True,
|
||||
nullable=False),
|
||||
Column('created_at', DateTime),
|
||||
Column('updated_at', DateTime),
|
||||
Column('user_id',
|
||||
String(length=255),
|
||||
nullable=False),
|
||||
Column('project_id',
|
||||
String(length=255),
|
||||
nullable=False),
|
||||
Column('resource',
|
||||
String(length=255),
|
||||
nullable=False),
|
||||
Column('hard_limit', Integer, nullable=True),
|
||||
UniqueConstraint('user_id', 'project_id', 'resource',
|
||||
name=uniq_name),
|
||||
Index('project_user_quotas_project_id_idx',
|
||||
'project_id'),
|
||||
Index('project_user_quotas_user_id_idx',
|
||||
'user_id'),
|
||||
mysql_engine='InnoDB',
|
||||
mysql_charset='utf8',
|
||||
)
|
||||
|
||||
project_user_quotas.create(checkfirst=True)
|
||||
|
||||
reservations = Table('reservations', meta,
|
||||
Column('created_at', DateTime),
|
||||
Column('updated_at', DateTime),
|
||||
Column('id', Integer, primary_key=True, nullable=False),
|
||||
Column('uuid', String(length=36), nullable=False),
|
||||
Column('usage_id', Integer, ForeignKey('quota_usages.id'),
|
||||
nullable=False),
|
||||
Column('project_id', String(length=255)),
|
||||
Column('resource', String(length=255)),
|
||||
Column('delta', Integer, nullable=False),
|
||||
Column('expire', DateTime),
|
||||
Column('user_id', String(length=255)),
|
||||
Index('reservations_project_id_idx', 'project_id'),
|
||||
Index('reservations_uuid_idx', 'uuid'),
|
||||
Index('reservations_expire_idx', 'expire'),
|
||||
Index('reservations_user_id_idx', 'user_id'),
|
||||
mysql_engine='InnoDB',
|
||||
mysql_charset='utf8'
|
||||
)
|
||||
|
||||
reservations.create(checkfirst=True)
|
|
@ -1,24 +0,0 @@
|
|||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from sqlalchemy import MetaData
|
||||
from sqlalchemy import Table
|
||||
|
||||
from nova.db.sqlalchemy import api_models
|
||||
|
||||
|
||||
def upgrade(migrate_engine):
|
||||
meta = MetaData()
|
||||
meta.bind = migrate_engine
|
||||
|
||||
build_requests = Table('build_requests', meta, autoload=True)
|
||||
build_requests.c.instance.alter(type=api_models.MediumText())
|
|
@ -1,37 +0,0 @@
|
|||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
"""API Database migrations for placement_aggregates"""
|
||||
|
||||
from migrate import UniqueConstraint
|
||||
from sqlalchemy import Column
|
||||
from sqlalchemy import DateTime
|
||||
from sqlalchemy import Integer
|
||||
from sqlalchemy import MetaData
|
||||
from sqlalchemy import String
|
||||
from sqlalchemy import Table
|
||||
|
||||
|
||||
def upgrade(migrate_engine):
|
||||
meta = MetaData()
|
||||
meta.bind = migrate_engine
|
||||
|
||||
placement_aggregates = Table('placement_aggregates', meta,
|
||||
Column('created_at', DateTime),
|
||||
Column('updated_at', DateTime),
|
||||
Column('id', Integer, primary_key=True, nullable=False),
|
||||
Column('uuid', String(length=36), index=True),
|
||||
UniqueConstraint('uuid', name='uniq_placement_aggregates0uuid'),
|
||||
mysql_engine='InnoDB',
|
||||
mysql_charset='latin1'
|
||||
)
|
||||
|
||||
placement_aggregates.create(checkfirst=True)
|
|
@ -174,7 +174,7 @@ def upgrade(migrate_engine):
|
|||
'locked_by',
|
||||
Enum('owner', 'admin', name='build_requests0locked_by')),
|
||||
Column('instance_uuid', String(length=36)),
|
||||
Column('instance', Text()),
|
||||
Column('instance', MediumText()),
|
||||
Column('block_device_mappings', MediumText()),
|
||||
UniqueConstraint(
|
||||
'instance_uuid', name='uniq_build_requests0instance_uuid'),
|
||||
|
@ -201,6 +201,16 @@ def upgrade(migrate_engine):
|
|||
mysql_charset='utf8'
|
||||
)
|
||||
|
||||
resource_classes = Table('resource_classes', meta,
|
||||
Column('id', Integer, primary_key=True, nullable=False),
|
||||
Column('name', String(length=255), nullable=False),
|
||||
Column('created_at', DateTime),
|
||||
Column('updated_at', DateTime),
|
||||
UniqueConstraint('name', name='uniq_resource_classes0name'),
|
||||
mysql_engine='InnoDB',
|
||||
mysql_charset='latin1'
|
||||
)
|
||||
|
||||
nameargs = {}
|
||||
if migrate_engine.name == 'mysql':
|
||||
nameargs['collation'] = 'utf8_bin'
|
||||
|
@ -281,6 +291,16 @@ def upgrade(migrate_engine):
|
|||
mysql_charset='latin1'
|
||||
)
|
||||
|
||||
placement_aggregates = Table('placement_aggregates', meta,
|
||||
Column('created_at', DateTime),
|
||||
Column('updated_at', DateTime),
|
||||
Column('id', Integer, primary_key=True, nullable=False),
|
||||
Column('uuid', String(length=36), index=True),
|
||||
UniqueConstraint('uuid', name='uniq_placement_aggregates0uuid'),
|
||||
mysql_engine='InnoDB',
|
||||
mysql_charset='latin1'
|
||||
)
|
||||
|
||||
aggregates = Table('aggregates', meta,
|
||||
Column('created_at', DateTime),
|
||||
Column('updated_at', DateTime),
|
||||
|
@ -365,6 +385,87 @@ def upgrade(migrate_engine):
|
|||
mysql_charset='utf8',
|
||||
)
|
||||
|
||||
quota_classes = Table('quota_classes', meta,
|
||||
Column('created_at', DateTime),
|
||||
Column('updated_at', DateTime),
|
||||
Column('id', Integer, primary_key=True, nullable=False),
|
||||
Column('class_name', String(length=255)),
|
||||
Column('resource', String(length=255)),
|
||||
Column('hard_limit', Integer),
|
||||
Index('quota_classes_class_name_idx', 'class_name'),
|
||||
mysql_engine='InnoDB',
|
||||
mysql_charset='utf8',
|
||||
)
|
||||
|
||||
quota_usages = Table('quota_usages', meta,
|
||||
Column('created_at', DateTime),
|
||||
Column('updated_at', DateTime),
|
||||
Column('id', Integer, primary_key=True, nullable=False),
|
||||
Column('project_id', String(length=255)),
|
||||
Column('resource', String(length=255), nullable=False),
|
||||
Column('in_use', Integer, nullable=False),
|
||||
Column('reserved', Integer, nullable=False),
|
||||
Column('until_refresh', Integer),
|
||||
Column('user_id', String(length=255)),
|
||||
Index('quota_usages_project_id_idx', 'project_id'),
|
||||
Index('quota_usages_user_id_idx', 'user_id'),
|
||||
mysql_engine='InnoDB',
|
||||
mysql_charset='utf8',
|
||||
)
|
||||
|
||||
quotas = Table('quotas', meta,
|
||||
Column('id', Integer, primary_key=True, nullable=False),
|
||||
Column('created_at', DateTime),
|
||||
Column('updated_at', DateTime),
|
||||
Column('project_id', String(length=255)),
|
||||
Column('resource', String(length=255), nullable=False),
|
||||
Column('hard_limit', Integer),
|
||||
UniqueConstraint(
|
||||
'project_id', 'resource', name='uniq_quotas0project_id0resource'),
|
||||
mysql_engine='InnoDB',
|
||||
mysql_charset='utf8',
|
||||
)
|
||||
|
||||
project_user_quotas = Table('project_user_quotas', meta,
|
||||
Column('id', Integer, primary_key=True, nullable=False),
|
||||
Column('created_at', DateTime),
|
||||
Column('updated_at', DateTime),
|
||||
Column('user_id', String(length=255), nullable=False),
|
||||
Column('project_id', String(length=255), nullable=False),
|
||||
Column('resource', String(length=255), nullable=False),
|
||||
Column('hard_limit', Integer, nullable=True),
|
||||
UniqueConstraint(
|
||||
'user_id', 'project_id', 'resource',
|
||||
name='uniq_project_user_quotas0user_id0project_id0resource'),
|
||||
Index(
|
||||
'project_user_quotas_project_id_idx', 'project_id'),
|
||||
Index(
|
||||
'project_user_quotas_user_id_idx', 'user_id'),
|
||||
mysql_engine='InnoDB',
|
||||
mysql_charset='utf8',
|
||||
)
|
||||
|
||||
reservations = Table('reservations', meta,
|
||||
Column('created_at', DateTime),
|
||||
Column('updated_at', DateTime),
|
||||
Column('id', Integer, primary_key=True, nullable=False),
|
||||
Column('uuid', String(length=36), nullable=False),
|
||||
Column(
|
||||
'usage_id', Integer, ForeignKey('quota_usages.id'),
|
||||
nullable=False),
|
||||
Column('project_id', String(length=255)),
|
||||
Column('resource', String(length=255)),
|
||||
Column('delta', Integer, nullable=False),
|
||||
Column('expire', DateTime),
|
||||
Column('user_id', String(length=255)),
|
||||
Index('reservations_project_id_idx', 'project_id'),
|
||||
Index('reservations_uuid_idx', 'uuid'),
|
||||
Index('reservations_expire_idx', 'expire'),
|
||||
Index('reservations_user_id_idx', 'user_id'),
|
||||
mysql_engine='InnoDB',
|
||||
mysql_charset='utf8',
|
||||
)
|
||||
|
||||
tables = [
|
||||
cell_mappings,
|
||||
host_mappings,
|
||||
|
@ -375,16 +476,23 @@ def upgrade(migrate_engine):
|
|||
request_specs,
|
||||
build_requests,
|
||||
keypairs,
|
||||
resource_classes,
|
||||
resource_providers,
|
||||
inventories,
|
||||
allocations,
|
||||
resource_provider_aggregates,
|
||||
placement_aggregates,
|
||||
aggregates,
|
||||
aggregate_hosts,
|
||||
aggregate_metadata,
|
||||
groups,
|
||||
group_policy,
|
||||
group_member,
|
||||
quota_classes,
|
||||
quota_usages,
|
||||
quotas,
|
||||
project_user_quotas,
|
||||
reservations,
|
||||
]
|
||||
for table in tables:
|
||||
table.create(checkfirst=True)
|
|
@ -1,59 +0,0 @@
|
|||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from oslo_log import log as logging
|
||||
from sqlalchemy import MetaData, Table, func, select
|
||||
|
||||
from nova import exception
|
||||
from nova.i18n import _
|
||||
from nova import objects
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def upgrade(migrate_engine):
|
||||
meta = MetaData()
|
||||
meta.bind = migrate_engine
|
||||
|
||||
flavors = Table('flavors', meta, autoload=True)
|
||||
count = select([func.count()]).select_from(flavors).scalar()
|
||||
if count == 0:
|
||||
# NOTE(danms): We need to be careful here if this is a new
|
||||
# installation, which can't possibly have any mappings. Check
|
||||
# to see if any flavors are defined to determine if we are
|
||||
# upgrading an existing system. If not, then don't obsess over
|
||||
# the lack of mappings
|
||||
return
|
||||
|
||||
cell_mappings = Table('cell_mappings', meta, autoload=True)
|
||||
count = select([func.count()]).select_from(cell_mappings).scalar()
|
||||
# Two mappings are required at a minimum, cell0 and your first cell
|
||||
if count < 2:
|
||||
msg = _('Cell mappings are not created, but required for Ocata. '
|
||||
'Please run nova-manage cell_v2 simple_cell_setup before '
|
||||
'continuing.')
|
||||
raise exception.ValidationError(detail=msg)
|
||||
|
||||
count = select([func.count()]).select_from(cell_mappings).where(
|
||||
cell_mappings.c.uuid == objects.CellMapping.CELL0_UUID).scalar()
|
||||
if count != 1:
|
||||
msg = _('A mapping for Cell0 was not found, but is required for '
|
||||
'Ocata. Please run nova-manage cell_v2 simple_cell_setup '
|
||||
'before continuing.')
|
||||
raise exception.ValidationError(detail=msg)
|
||||
|
||||
host_mappings = Table('host_mappings', meta, autoload=True)
|
||||
count = select([func.count()]).select_from(host_mappings).scalar()
|
||||
if count == 0:
|
||||
LOG.warning('No host mappings were found, but are required for Ocata. '
|
||||
'Please run nova-manage cell_v2 simple_cell_setup before '
|
||||
'continuing.')
|
|
@ -29,7 +29,7 @@ from nova.i18n import _
|
|||
|
||||
INIT_VERSION = {}
|
||||
INIT_VERSION['main'] = 401
|
||||
INIT_VERSION['api'] = 19
|
||||
INIT_VERSION['api'] = 29
|
||||
_REPOSITORY = {}
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
|
|
@ -172,7 +172,6 @@ class NovaAPIMigrationsWalk(test_migrations.WalkVersionsMixin):
|
|||
return self.engine
|
||||
|
||||
def _skippable_migrations(self):
|
||||
newton_placeholders = list(range(21, 26))
|
||||
ocata_placeholders = list(range(31, 41))
|
||||
pike_placeholders = list(range(45, 50))
|
||||
queens_placeholders = list(range(53, 58))
|
||||
|
@ -183,10 +182,8 @@ class NovaAPIMigrationsWalk(test_migrations.WalkVersionsMixin):
|
|||
victoria_placeholders = list(range(78, 83))
|
||||
special_cases = [
|
||||
self.INIT_VERSION + 1, # initial change
|
||||
30, # Enforcement migration, no changes to test
|
||||
]
|
||||
return (newton_placeholders +
|
||||
ocata_placeholders +
|
||||
return (ocata_placeholders +
|
||||
pike_placeholders +
|
||||
queens_placeholders +
|
||||
stein_placeholders +
|
||||
|
@ -226,119 +223,6 @@ class NovaAPIMigrationsWalk(test_migrations.WalkVersionsMixin):
|
|||
self.assertRaises(sqlalchemy.exc.NoSuchTableError,
|
||||
db_utils.get_table, engine, table_name)
|
||||
|
||||
def _check_026(self, engine, data):
|
||||
self.assertColumnExists(engine, 'resource_classes', 'id')
|
||||
self.assertColumnExists(engine, 'resource_classes', 'name')
|
||||
|
||||
def _check_027(self, engine, data):
|
||||
# quota_classes
|
||||
for column in ['created_at',
|
||||
'updated_at',
|
||||
'id',
|
||||
'class_name',
|
||||
'resource',
|
||||
'hard_limit']:
|
||||
self.assertColumnExists(engine, 'quota_classes', column)
|
||||
|
||||
self.assertIndexExists(engine, 'quota_classes',
|
||||
'quota_classes_class_name_idx')
|
||||
|
||||
# quota_usages
|
||||
for column in ['created_at',
|
||||
'updated_at',
|
||||
'id',
|
||||
'project_id',
|
||||
'resource',
|
||||
'in_use',
|
||||
'reserved',
|
||||
'until_refresh',
|
||||
'user_id']:
|
||||
self.assertColumnExists(engine, 'quota_usages', column)
|
||||
|
||||
self.assertIndexExists(engine, 'quota_usages',
|
||||
'quota_usages_project_id_idx')
|
||||
self.assertIndexExists(engine, 'quota_usages',
|
||||
'quota_usages_user_id_idx')
|
||||
|
||||
# quotas
|
||||
for column in ['created_at',
|
||||
'updated_at',
|
||||
'id',
|
||||
'project_id',
|
||||
'resource',
|
||||
'hard_limit']:
|
||||
self.assertColumnExists(engine, 'quotas', column)
|
||||
|
||||
self.assertUniqueConstraintExists(engine, 'quotas',
|
||||
['project_id', 'resource'])
|
||||
|
||||
# project_user_quotas
|
||||
for column in ['created_at',
|
||||
'updated_at',
|
||||
'id',
|
||||
'user_id',
|
||||
'project_id',
|
||||
'resource',
|
||||
'hard_limit']:
|
||||
self.assertColumnExists(engine, 'project_user_quotas', column)
|
||||
|
||||
self.assertUniqueConstraintExists(engine, 'project_user_quotas',
|
||||
['user_id', 'project_id', 'resource'])
|
||||
self.assertIndexExists(engine, 'project_user_quotas',
|
||||
'project_user_quotas_project_id_idx')
|
||||
self.assertIndexExists(engine, 'project_user_quotas',
|
||||
'project_user_quotas_user_id_idx')
|
||||
|
||||
# reservations
|
||||
for column in ['created_at',
|
||||
'updated_at',
|
||||
'id',
|
||||
'uuid',
|
||||
'usage_id',
|
||||
'project_id',
|
||||
'resource',
|
||||
'delta',
|
||||
'expire',
|
||||
'user_id']:
|
||||
self.assertColumnExists(engine, 'reservations', column)
|
||||
|
||||
self.assertIndexExists(engine, 'reservations',
|
||||
'reservations_project_id_idx')
|
||||
self.assertIndexExists(engine, 'reservations',
|
||||
'reservations_uuid_idx')
|
||||
self.assertIndexExists(engine, 'reservations',
|
||||
'reservations_expire_idx')
|
||||
self.assertIndexExists(engine, 'reservations',
|
||||
'reservations_user_id_idx')
|
||||
# Ensure the foreign key still exists
|
||||
inspector = reflection.Inspector.from_engine(engine)
|
||||
# There should only be one foreign key here
|
||||
fk = inspector.get_foreign_keys('reservations')[0]
|
||||
self.assertEqual('quota_usages', fk['referred_table'])
|
||||
self.assertEqual(['id'], fk['referred_columns'])
|
||||
|
||||
def _pre_upgrade_028(self, engine):
|
||||
build_requests = db_utils.get_table(engine, 'build_requests')
|
||||
fake_build_req = {'id': 2021,
|
||||
'project_id': 'fake_proj_id',
|
||||
'instance': '{"uuid": "foo", "name": "bar"}'}
|
||||
build_requests.insert().execute(fake_build_req)
|
||||
|
||||
def _check_028(self, engine, data):
|
||||
build_requests = db_utils.get_table(engine, 'build_requests')
|
||||
if engine.name == 'mysql':
|
||||
self.assertIsInstance(build_requests.c.block_device_mappings.type,
|
||||
sqlalchemy.dialects.mysql.MEDIUMTEXT)
|
||||
|
||||
fake_build_req = build_requests.select(
|
||||
build_requests.c.id == 2021).execute().first()
|
||||
self.assertEqual('{"uuid": "foo", "name": "bar"}',
|
||||
fake_build_req.instance)
|
||||
|
||||
def _check_029(self, engine, data):
|
||||
for column in ['created_at', 'updated_at', 'id', 'uuid']:
|
||||
self.assertColumnExists(engine, 'placement_aggregates', column)
|
||||
|
||||
def _check_041(self, engine, data):
|
||||
self.assertColumnExists(engine, 'traits', 'id')
|
||||
self.assertUniqueConstraintExists(engine, 'traits', ['name'])
|
||||
|
|
|
@ -12,22 +12,14 @@
|
|||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import importlib
|
||||
|
||||
from migrate import exceptions as versioning_exceptions
|
||||
from migrate.versioning import api as versioning_api
|
||||
import mock
|
||||
from oslo_db.sqlalchemy import utils as db_utils
|
||||
from oslo_utils.fixture import uuidsentinel
|
||||
import sqlalchemy
|
||||
|
||||
from nova import context
|
||||
from nova.db.sqlalchemy import api as db_api
|
||||
from nova.db.sqlalchemy import migration
|
||||
from nova import exception
|
||||
from nova import objects
|
||||
from nova import test
|
||||
from nova.tests import fixtures as nova_fixtures
|
||||
|
||||
|
||||
@mock.patch.object(migration, 'db_version', return_value=2)
|
||||
|
@ -163,96 +155,3 @@ class TestGetEngine(test.NoDBTestCase):
|
|||
engine = migration.get_engine('api')
|
||||
self.assertEqual('api_engine', engine)
|
||||
mock_get_engine.assert_called_once_with()
|
||||
|
||||
|
||||
class TestNewtonCellsCheck(test.NoDBTestCase):
|
||||
USES_DB_SELF = True
|
||||
|
||||
def setUp(self):
|
||||
super(TestNewtonCellsCheck, self).setUp()
|
||||
self.useFixture(nova_fixtures.Database('api', 28))
|
||||
self.context = context.get_admin_context()
|
||||
self.migration = importlib.import_module(
|
||||
'nova.db.sqlalchemy.api_migrations.migrate_repo.versions.'
|
||||
'030_require_cell_setup')
|
||||
self.engine = db_api.get_api_engine()
|
||||
|
||||
def _flavor_me(self):
|
||||
# We can't use the Flavor object or model to create the flavor because
|
||||
# the model and object have the description field now but at this point
|
||||
# we have not run the migration schema to add the description column.
|
||||
flavors = db_utils.get_table(self.engine, 'flavors')
|
||||
values = dict(name='foo', memory_mb=123,
|
||||
vcpus=1, root_gb=1,
|
||||
flavorid='m1.foo', swap=0)
|
||||
flavors.insert().execute(values)
|
||||
|
||||
def _create_cell_mapping(self, **values):
|
||||
mappings = db_utils.get_table(self.engine, 'cell_mappings')
|
||||
return mappings.insert().execute(**values).inserted_primary_key[0]
|
||||
|
||||
def _create_host_mapping(self, **values):
|
||||
mappings = db_utils.get_table(self.engine, 'host_mappings')
|
||||
return mappings.insert().execute(**values).inserted_primary_key[0]
|
||||
|
||||
def test_upgrade_with_no_cell_mappings(self):
|
||||
self._flavor_me()
|
||||
self.assertRaisesRegex(exception.ValidationError,
|
||||
'Cell mappings',
|
||||
self.migration.upgrade, self.engine)
|
||||
|
||||
def test_upgrade_with_only_cell0(self):
|
||||
self._flavor_me()
|
||||
self._create_cell_mapping(uuid=objects.CellMapping.CELL0_UUID,
|
||||
name='cell0',
|
||||
transport_url='fake',
|
||||
database_connection='fake')
|
||||
self.assertRaisesRegex(exception.ValidationError,
|
||||
'Cell mappings',
|
||||
self.migration.upgrade, self.engine)
|
||||
|
||||
def test_upgrade_without_cell0(self):
|
||||
self._flavor_me()
|
||||
self._create_cell_mapping(uuid=uuidsentinel.cell1,
|
||||
name='cell1',
|
||||
transport_url='fake',
|
||||
database_connection='fake')
|
||||
self._create_cell_mapping(uuid=uuidsentinel.cell2,
|
||||
name='cell2',
|
||||
transport_url='fake',
|
||||
database_connection='fake')
|
||||
self.assertRaisesRegex(exception.ValidationError,
|
||||
'Cell0',
|
||||
self.migration.upgrade, self.engine)
|
||||
|
||||
def test_upgrade_with_no_host_mappings(self):
|
||||
self._flavor_me()
|
||||
self._create_cell_mapping(uuid=objects.CellMapping.CELL0_UUID,
|
||||
name='cell0',
|
||||
transport_url='fake',
|
||||
database_connection='fake')
|
||||
self._create_cell_mapping(uuid=uuidsentinel.cell1,
|
||||
name='cell1',
|
||||
transport_url='fake',
|
||||
database_connection='fake')
|
||||
|
||||
with mock.patch.object(self.migration, 'LOG') as log:
|
||||
self.migration.upgrade(self.engine)
|
||||
self.assertTrue(log.warning.called)
|
||||
|
||||
def test_upgrade_with_required_mappings(self):
|
||||
self._flavor_me()
|
||||
self._create_cell_mapping(uuid=objects.CellMapping.CELL0_UUID,
|
||||
name='cell0',
|
||||
transport_url='fake',
|
||||
database_connection='fake')
|
||||
cell1_id = self._create_cell_mapping(uuid=uuidsentinel.cell1,
|
||||
name='cell1',
|
||||
transport_url='fake',
|
||||
database_connection='fake')
|
||||
self._create_host_mapping(cell_id=cell1_id, host='foo')
|
||||
|
||||
self.migration.upgrade(self.engine)
|
||||
|
||||
def test_upgrade_new_deploy(self):
|
||||
self.migration.upgrade(self.engine)
|
||||
|
|
Loading…
Reference in New Issue