Make request_spec.spec MediumText

request_spec.instance_group.members is a list of instance UUIDs. It
can get so long that it overflows its TEXT column. This patch changes
request_spec.spec to MEDIUMTEXT.

NOTE(artom): Conflicts in
nova/tests/functional/db/api/test_migrations.py because of backport
migration renumbering. Also the uuids module isn't in newton so
a hard-coded uuid is used.

NOTE(mriedem): Since this is a backport, this contains a release
note not found in the original change on master.

Change-Id: I6bf0fa19b72887803e77b66698587c2108c9372a
Closes-bug: 1738094
(cherry picked from commit 40d7433908)
(cherry picked from commit 1cfcc40643)
(cherry picked from commit 4f0ff43c79)
This commit is contained in:
Artom Lifshitz 2017-12-14 11:56:47 -05:00 committed by Matt Riedemann
parent e9f896632f
commit e4e7b8da56
4 changed files with 68 additions and 1 deletions

View File

@ -0,0 +1,25 @@
# 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
request_specs = Table('request_specs', meta, autoload=True)
if request_specs.c.spec.type != api_models.MediumText():
request_specs.c.spec.alter(type=api_models.MediumText())

View File

@ -167,7 +167,7 @@ class RequestSpec(API_BASE):
id = Column(Integer, primary_key=True)
instance_uuid = Column(String(36), nullable=False)
spec = Column(Text, nullable=False)
spec = Column(MediumText(), nullable=False)
class Flavors(API_BASE):

View File

@ -36,6 +36,7 @@ import mock
from oslo_db.sqlalchemy import test_base
from oslo_db.sqlalchemy import test_migrations
from oslo_db.sqlalchemy import utils as db_utils
from oslo_serialization import jsonutils
import sqlalchemy
from sqlalchemy.engine import reflection
@ -480,6 +481,36 @@ class NovaAPIMigrationsWalk(test_migrations.WalkVersionsMixin):
self.assertEqual('{"uuid": "foo", "name": "bar"}',
fake_build_req.instance)
def _pre_upgrade_022(self, engine):
request_specs = db_utils.get_table(engine, 'request_specs')
# The spec value is a serialized json blob.
spec = jsonutils.dumps(
{"instance_group": {"id": 42,
"members": ["uuid1",
"uuid2",
"uuid3"]}})
fake_request_spec = {
'id': 42, 'spec': spec,
'instance_uuid': 'c65539ad-b7f5-43d8-934a-018d42424da8'}
request_specs.insert().execute(fake_request_spec)
def _check_022(self, engine, data):
request_specs = db_utils.get_table(engine, 'request_specs')
if engine.name == 'mysql':
self.assertIsInstance(request_specs.c.spec.type,
sqlalchemy.dialects.mysql.MEDIUMTEXT)
expected_spec = {"instance_group": {"id": 42,
"members": ["uuid1",
"uuid2",
"uuid3"]}}
from_db_request_spec = request_specs.select(
request_specs.c.id == 42).execute().first()
self.assertEqual('c65539ad-b7f5-43d8-934a-018d42424da8',
from_db_request_spec['instance_uuid'])
db_spec = jsonutils.loads(from_db_request_spec['spec'])
self.assertDictEqual(expected_spec, db_spec)
class TestNovaAPIMigrationsWalkSQLite(NovaAPIMigrationsWalk,
test_base.DbTestCase,

View File

@ -0,0 +1,11 @@
---
upgrade:
- |
This release contains a schema migration for the ``nova_api`` database
in order to address bug 1738094:
https://bugs.launchpad.net/nova/+bug/1738094
The migration is optional and can be postponed if you have not been
affected by the bug. The bug manifests itself through "Data too long for
column 'spec'" database errors.