diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py index 9299a4f5d6de..e26146d3c744 100644 --- a/nova/db/sqlalchemy/api.py +++ b/nova/db/sqlalchemy/api.py @@ -1733,6 +1733,7 @@ def instance_create(context, values): 'pci_requests': None, 'vcpu_model': None, 'trusted_certs': None, + 'vpmems': None, }) instance_ref['extra'].update(values.pop('extra', {})) instance_ref.update(values) @@ -3008,7 +3009,7 @@ def instance_extra_get_by_instance_uuid(context, instance_uuid, filter_by(instance_uuid=instance_uuid) if columns is None: columns = ['numa_topology', 'pci_requests', 'flavor', 'vcpu_model', - 'trusted_certs', 'migration_context'] + 'trusted_certs', 'vpmems', 'migration_context'] for column in columns: query = query.options(undefer(column)) instance_extra = query.first() diff --git a/nova/db/sqlalchemy/migrate_repo/versions/398_add_vpmems.py b/nova/db/sqlalchemy/migrate_repo/versions/398_add_vpmems.py new file mode 100644 index 000000000000..e6bdee5c6ebb --- /dev/null +++ b/nova/db/sqlalchemy/migrate_repo/versions/398_add_vpmems.py @@ -0,0 +1,31 @@ +# 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 Column +from sqlalchemy import MetaData +from sqlalchemy import Table +from sqlalchemy import Text + + +BASE_TABLE_NAME = 'instance_extra' +NEW_COLUMN_NAME = 'vpmems' + + +def upgrade(migrate_engine): + meta = MetaData() + meta.bind = migrate_engine + + for prefix in ('', 'shadow_'): + table = Table(prefix + BASE_TABLE_NAME, meta, autoload=True) + new_column = Column(NEW_COLUMN_NAME, Text, nullable=True) + if not hasattr(table.c, NEW_COLUMN_NAME): + table.create_column(new_column) diff --git a/nova/db/sqlalchemy/models.py b/nova/db/sqlalchemy/models.py index 95e21582579a..3b15a43333ce 100644 --- a/nova/db/sqlalchemy/models.py +++ b/nova/db/sqlalchemy/models.py @@ -389,6 +389,7 @@ class InstanceExtra(BASE, NovaBase, models.SoftDeleteMixin): migration_context = orm.deferred(Column(Text)) keypairs = orm.deferred(Column(Text)) trusted_certs = orm.deferred(Column(Text)) + vpmems = orm.deferred(Column(Text)) instance = orm.relationship(Instance, backref=orm.backref('extra', uselist=False), diff --git a/nova/tests/unit/db/test_db_api.py b/nova/tests/unit/db/test_db_api.py index 0e39db19a4ef..726c902067fd 100644 --- a/nova/tests/unit/db/test_db_api.py +++ b/nova/tests/unit/db/test_db_api.py @@ -3291,6 +3291,7 @@ class InstanceExtraTestCase(test.TestCase): db.instance_extra_update_by_uuid(self.ctxt, self.instance['uuid'], {'numa_topology': 'changed', 'trusted_certs': "['123', 'foo']", + 'vpmems': "['vpmem0', 'vpmem1']", }) inst_extra = db.instance_extra_get_by_instance_uuid( self.ctxt, self.instance['uuid']) @@ -3298,6 +3299,7 @@ class InstanceExtraTestCase(test.TestCase): # NOTE(jackie-truong): trusted_certs is stored as a Text type in # instance_extra and read as a list of strings self.assertEqual("['123', 'foo']", inst_extra.trusted_certs) + self.assertEqual("['vpmem0', 'vpmem1']", inst_extra.vpmems) def test_instance_extra_update_by_uuid_and_create(self): @sqlalchemy_api.pick_context_manager_writer @@ -3322,12 +3324,13 @@ class InstanceExtraTestCase(test.TestCase): def test_instance_extra_get_with_columns(self): extra = db.instance_extra_get_by_instance_uuid( self.ctxt, self.instance['uuid'], - columns=['numa_topology', 'vcpu_model', 'trusted_certs']) + columns=['numa_topology', 'vcpu_model', 'trusted_certs', 'vpmems']) self.assertRaises(SQLAlchemyError, extra.__getitem__, 'pci_requests') self.assertIn('numa_topology', extra) self.assertIn('vcpu_model', extra) self.assertIn('trusted_certs', extra) + self.assertIn('vpmems', extra) class ServiceTestCase(test.TestCase, ModelsObjectComparatorMixin): diff --git a/nova/tests/unit/db/test_migrations.py b/nova/tests/unit/db/test_migrations.py index f6bf8da1ff98..dfe709adf018 100644 --- a/nova/tests/unit/db/test_migrations.py +++ b/nova/tests/unit/db/test_migrations.py @@ -1027,6 +1027,10 @@ class NovaMigrationsCheckers(test_migrations.ModelsMigrationsSync, self.assertColumnExists( engine, '%smigrations' % prefix, 'cross_cell_move') + def _check_398(self, engine, data): + self.assertColumnExists(engine, 'instance_extra', 'vpmems') + self.assertColumnExists(engine, 'shadow_instance_extra', 'vpmems') + class TestNovaMigrationsSQLite(NovaMigrationsCheckers, test_fixtures.OpportunisticDBTestMixin,