diff --git a/ironic/db/sqlalchemy/alembic/versions/e918ff30eb42_resize_column_nodes_instance_info.py b/ironic/db/sqlalchemy/alembic/versions/e918ff30eb42_resize_column_nodes_instance_info.py new file mode 100644 index 0000000000..cc03f3b3bc --- /dev/null +++ b/ironic/db/sqlalchemy/alembic/versions/e918ff30eb42_resize_column_nodes_instance_info.py @@ -0,0 +1,32 @@ +# 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. + +"""resize column nodes instance_info + +Revision ID: e918ff30eb42 +Revises: b4130a7fc904 +Create Date: 2016-06-28 13:30:19.396203 + +""" + +# revision identifiers, used by Alembic. +revision = 'e918ff30eb42' +down_revision = 'b4130a7fc904' + +from alembic import op +from oslo_db.sqlalchemy import types as db_types + + +def upgrade(): + op.alter_column('nodes', 'instance_info', + existing_type=db_types.JsonEncodedDict.impl, + type_=db_types.JsonEncodedDict(mysql_as_long=True).impl) diff --git a/ironic/db/sqlalchemy/models.py b/ironic/db/sqlalchemy/models.py index 8573fef71d..c64f1a19d4 100644 --- a/ironic/db/sqlalchemy/models.py +++ b/ironic/db/sqlalchemy/models.py @@ -136,7 +136,7 @@ class Node(Base): target_provision_state = Column(String(15), nullable=True) provision_updated_at = Column(DateTime, nullable=True) last_error = Column(Text, nullable=True) - instance_info = Column(db_types.JsonEncodedDict) + instance_info = Column(db_types.JsonEncodedDict(mysql_as_long=True)) properties = Column(db_types.JsonEncodedDict) driver = Column(String(255)) driver_info = Column(db_types.JsonEncodedDict) diff --git a/ironic/tests/unit/db/sqlalchemy/test_migrations.py b/ironic/tests/unit/db/sqlalchemy/test_migrations.py index 8bb969ee94..3ae8267af0 100644 --- a/ironic/tests/unit/db/sqlalchemy/test_migrations.py +++ b/ironic/tests/unit/db/sqlalchemy/test_migrations.py @@ -698,6 +698,44 @@ class TestMigrationsMySQL(MigrationCheckersMixin, test_base.BaseTestCase): FIXTURE = test_fixtures.MySQLOpportunisticFixture + def _pre_upgrade_e918ff30eb42(self, engine): + + nodes = db_utils.get_table(engine, 'nodes') + + # this should always fail pre-upgrade + mediumtext = 'a' * (pow(2, 16) + 1) + uuid = uuidutils.generate_uuid() + expected_to_fail_data = {'uuid': uuid, 'instance_info': mediumtext} + self.assertRaises(db_exc.DBError, + nodes.insert().execute, expected_to_fail_data) + + # this should always work pre-upgrade + text = 'a' * (pow(2, 16) - 1) + uuid = uuidutils.generate_uuid() + valid_pre_upgrade_data = {'uuid': uuid, 'instance_info': text} + nodes.insert().execute(valid_pre_upgrade_data) + + return valid_pre_upgrade_data + + def _check_e918ff30eb42(self, engine, data): + + nodes = db_utils.get_table(engine, 'nodes') + + # check that the data for the successful pre-upgrade + # entry didn't change + node = nodes.select(nodes.c.uuid == data['uuid']).execute().first() + self.assertIsNotNone(node) + self.assertEqual(data['instance_info'], node['instance_info']) + + # now this should pass post-upgrade + test = 'b' * (pow(2, 16) + 1) + uuid = uuidutils.generate_uuid() + data = {'uuid': uuid, 'instance_info': test} + nodes.insert().execute(data) + + node = nodes.select(nodes.c.uuid == uuid).execute().first() + self.assertEqual(test, node['instance_info']) + class TestMigrationsPostgreSQL(MigrationCheckersMixin, WalkVersionsMixin, diff --git a/releasenotes/notes/bug-1596421-0cb8f59073f56240.yaml b/releasenotes/notes/bug-1596421-0cb8f59073f56240.yaml new file mode 100644 index 0000000000..9d7b4688bb --- /dev/null +++ b/releasenotes/notes/bug-1596421-0cb8f59073f56240.yaml @@ -0,0 +1,9 @@ +--- +upgrade: + - Extends the ``instance_info`` column in the nodes table for MySQL/MariaDB + from up to 64KiB to up to 4GiB (type is changed from TEXT to LONGTEXT). + This upgrade will not be executed on PostgreSQL as its TEXT is unlimited. +fixes: + - The config drive passed to the node can now contain more than 64KiB + in case of MySQL/MariaDB. For more details see `bug 1596421 + `_.