From: Thang Pham Date: Fri, 24 Jul 2015 14:56:32 +0000 (-0700) Subject: Add version columns to services table X-Git-Url: https://review.fuel-infra.org/gitweb?a=commitdiff_plain;h=677ff1c699387dc3d7a598e52d1860b5ba8da1bc;p=openstack-build%2Fcinder-build.git Add version columns to services table The following patch is part of the cinder effort to support rolling upgrade. This patch adds columns to the services table to track the RPC and oslo_versionedobjects versions of each service. Follow up patches will be made to have each service: register its RPC and oslo_versionedobjects versions on startup, make the RPC and oslo_versionedobjects versions compatible with an older release, and update the versions once all services are updated to the latest release. Change-Id: Ifa6c6ac230988c75dcc4e5fe220bfc5ee70ac338 Partial-Implements: blueprint rpc-object-compatibility --- diff --git a/cinder/backup/rpcapi.py b/cinder/backup/rpcapi.py index a237119ec..19419c629 100644 --- a/cinder/backup/rpcapi.py +++ b/cinder/backup/rpcapi.py @@ -41,13 +41,15 @@ class BackupAPI(object): """ BASE_RPC_API_VERSION = '1.0' + RPC_API_VERSION = '1.1' def __init__(self): super(BackupAPI, self).__init__() target = messaging.Target(topic=CONF.backup_topic, version=self.BASE_RPC_API_VERSION) serializer = objects_base.CinderObjectSerializer() - self.client = rpc.get_client(target, '1.1', serializer=serializer) + self.client = rpc.get_client(target, self.RPC_API_VERSION, + serializer=serializer) def create_backup(self, ctxt, backup): LOG.debug("create_backup in rpcapi backup_id %s", backup.id) diff --git a/cinder/db/sqlalchemy/migrate_repo/versions/053_add_version_columns_to_service.py b/cinder/db/sqlalchemy/migrate_repo/versions/053_add_version_columns_to_service.py new file mode 100644 index 000000000..8caae5ca8 --- /dev/null +++ b/cinder/db/sqlalchemy/migrate_repo/versions/053_add_version_columns_to_service.py @@ -0,0 +1,51 @@ +# Copyright (C) 2015 SimpliVity Corp. +# All Rights Reserved. +# +# 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, String, Table + + +def upgrade(migrate_engine): + meta = MetaData() + meta.bind = migrate_engine + + services = Table('services', meta, autoload=True) + rpc_current_version = Column('rpc_current_version', String(36)) + rpc_available_version = Column('rpc_available_version', String(36)) + object_current_version = Column('object_current_version', String(36)) + object_available_version = Column('object_available_version', String(36)) + services.create_column(rpc_current_version) + services.create_column(rpc_available_version) + services.create_column(object_current_version) + services.create_column(object_available_version) + services.update().values(rpc_current_version=None).execute() + services.update().values(rpc_available_version=None).execute() + services.update().values(object_current_version=None).execute() + services.update().values(object_available_version=None).execute() + + +def downgrade(migrate_engine): + meta = MetaData() + meta.bind = migrate_engine + + services = Table('services', meta, autoload=True) + rpc_current_version = services.columns.rpc_current_version + rpc_available_version = services.columns.rpc_available_version + object_current_version = services.columns.object_current_version + object_available_version = services.columns.object_available_version + services.drop_column(rpc_current_version) + services.drop_column(rpc_available_version) + services.drop_column(object_current_version) + services.drop_column(object_available_version) diff --git a/cinder/db/sqlalchemy/models.py b/cinder/db/sqlalchemy/models.py index 3011c9463..f2bdc27d8 100644 --- a/cinder/db/sqlalchemy/models.py +++ b/cinder/db/sqlalchemy/models.py @@ -69,6 +69,14 @@ class Service(BASE, CinderBase): # periodic updates modified_at = Column(DateTime) + # Version columns to support rolling upgrade. + # Current version is what the service is running now (i.e. minimum). + # Available version is what the service can support (i.e. max). + rpc_current_version = Column(String(36)) + rpc_available_version = Column(String(36)) + object_current_version = Column(String(36)) + object_available_version = Column(String(36)) + class ConsistencyGroup(BASE, CinderBase): """Represents a consistencygroup.""" diff --git a/cinder/objects/backup.py b/cinder/objects/backup.py index b6f17674d..0586e5179 100644 --- a/cinder/objects/backup.py +++ b/cinder/objects/backup.py @@ -69,6 +69,7 @@ class Backup(base.CinderPersistentObject, base.CinderObject, def obj_make_compatible(self, primitive, target_version): """Make an object representation compatible with a target version.""" + super(Backup, self).obj_make_compatible(primitive, target_version) target_version = utils.convert_version_to_tuple(target_version) @staticmethod diff --git a/cinder/objects/base.py b/cinder/objects/base.py index 961308955..105aa915d 100644 --- a/cinder/objects/base.py +++ b/cinder/objects/base.py @@ -43,6 +43,11 @@ class CinderObject(base.VersionedObject): # from one another. OBJ_PROJECT_NAMESPACE = 'cinder' + # NOTE(thangp): As more objects are added to cinder, each object should + # have a custom map of version compatibility. This just anchors the base + # version compatibility. + VERSION_COMPATIBILITY = {'7.0.0': '1.0'} + def cinder_obj_get_changes(self): """Returns a dict of changed fields with tz unaware datetimes. diff --git a/cinder/objects/snapshot.py b/cinder/objects/snapshot.py index c48231389..ebfbf96dc 100644 --- a/cinder/objects/snapshot.py +++ b/cinder/objects/snapshot.py @@ -98,6 +98,7 @@ class Snapshot(base.CinderPersistentObject, base.CinderObject, def obj_make_compatible(self, primitive, target_version): """Make an object representation compatible with a target version.""" + super(Snapshot, self).obj_make_compatible(primitive, target_version) target_version = utils.convert_version_to_tuple(target_version) @staticmethod diff --git a/cinder/objects/volume.py b/cinder/objects/volume.py index 6270c55c0..a4d999e82 100644 --- a/cinder/objects/volume.py +++ b/cinder/objects/volume.py @@ -96,6 +96,7 @@ class Volume(base.CinderPersistentObject, base.CinderObject, def obj_make_compatible(self, primitive, target_version): """Make an object representation compatible with a target version.""" + super(Volume, self).obj_make_compatible(primitive, target_version) target_version = utils.convert_version_to_tuple(target_version) @staticmethod diff --git a/cinder/tests/unit/test_migrations.py b/cinder/tests/unit/test_migrations.py index f0e5d5677..e5a335f72 100644 --- a/cinder/tests/unit/test_migrations.py +++ b/cinder/tests/unit/test_migrations.py @@ -865,6 +865,24 @@ class MigrationsMixin(test_migrations.WalkVersionsMixin): snapshots = db_utils.get_table(engine, 'snapshots') self.assertNotIn('provider_auth', snapshots.c) + def _check_053(self, engine, data): + services = db_utils.get_table(engine, 'services') + self.assertIsInstance(services.c.rpc_current_version.type, + sqlalchemy.types.VARCHAR) + self.assertIsInstance(services.c.rpc_available_version.type, + sqlalchemy.types.VARCHAR) + self.assertIsInstance(services.c.object_current_version.type, + sqlalchemy.types.VARCHAR) + self.assertIsInstance(services.c.object_available_version.type, + sqlalchemy.types.VARCHAR) + + def _post_downgrade_053(self, engine): + services = db_utils.get_table(engine, 'services') + self.assertNotIn('rpc_current_version', services.c) + self.assertNotIn('rpc_available_version', services.c) + self.assertNotIn('object_current_version', services.c) + self.assertNotIn('object_available_version', services.c) + def test_walk_versions(self): self.walk_versions(True, False)