diff options
author | Artom Lifshitz <alifshit@redhat.com> | 2017-12-14 11:56:47 -0500 |
---|---|---|
committer | Matt Riedemann <mriedem.os@gmail.com> | 2017-12-18 19:43:54 +0000 |
commit | 4f0ff43c79c02689a118dc8100187c19b5c21238 (patch) | |
tree | 6d0e3fca93d462cb5290bdf5228a3dbc798212e3 | |
parent | 684ad9dac2a0f23c84c8e7bee9a70ed8da53bda3 (diff) | |
download | nova-4f0ff43c79c02689a118dc8100187c19b5c21238.tar.gz |
Make request_spec.spec MediumText15.1.0
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.
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 40d74339082fe0eb1ce9216e89cf6e65a39e6968)
(cherry picked from commit 9adf97c0132c3e0d34bbb2e33b59c6e5b00bec57)
4 files changed, 67 insertions, 1 deletions
diff --git a/nova/db/sqlalchemy/api_migrations/migrate_repo/versions/031_request_specs_spec_mediumtext.py b/nova/db/sqlalchemy/api_migrations/migrate_repo/versions/031_request_specs_spec_mediumtext.py new file mode 100644 index 0000000000..e0eef79a02 --- /dev/null +++ b/nova/db/sqlalchemy/api_migrations/migrate_repo/versions/031_request_specs_spec_mediumtext.py @@ -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()) diff --git a/nova/db/sqlalchemy/api_models.py b/nova/db/sqlalchemy/api_models.py index e5c5720dc3..586b8b3fea 100644 --- a/nova/db/sqlalchemy/api_models.py +++ b/nova/db/sqlalchemy/api_models.py @@ -168,7 +168,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): diff --git a/nova/tests/functional/db/api/test_migrations.py b/nova/tests/functional/db/api/test_migrations.py index b66e2623dc..d0e8c3c4ec 100644 --- a/nova/tests/functional/db/api/test_migrations.py +++ b/nova/tests/functional/db/api/test_migrations.py @@ -35,6 +35,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 @@ -43,6 +44,7 @@ from nova.db.sqlalchemy.api_migrations import migrate_repo from nova.db.sqlalchemy import api_models from nova.db.sqlalchemy import migration as sa_migration from nova import test +from nova.test import uuids from nova.tests import fixtures as nova_fixtures @@ -578,6 +580,34 @@ class NovaAPIMigrationsWalk(test_migrations.WalkVersionsMixin): for column in ['created_at', 'updated_at', 'id', 'uuid']: self.assertColumnExists(engine, 'placement_aggregates', column) + def _pre_upgrade_031(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': uuids.instance} + request_specs.insert().execute(fake_request_spec) + + def _check_031(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(uuids.instance, 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, diff --git a/releasenotes/notes/bug-1738094-request_specs.spec-migration-22d3421ea1536a37.yaml b/releasenotes/notes/bug-1738094-request_specs.spec-migration-22d3421ea1536a37.yaml new file mode 100644 index 0000000000..c333cc93e7 --- /dev/null +++ b/releasenotes/notes/bug-1738094-request_specs.spec-migration-22d3421ea1536a37.yaml @@ -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. |