]> review.fuel-infra Code Review - openstack-build/cinder-build.git/commitdiff
Add version columns to services table
authorThang Pham <thang.g.pham@gmail.com>
Fri, 24 Jul 2015 14:56:32 +0000 (07:56 -0700)
committerThang Pham <thang.g.pham@gmail.com>
Mon, 17 Aug 2015 23:31:34 +0000 (16:31 -0700)
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

cinder/backup/rpcapi.py
cinder/db/sqlalchemy/migrate_repo/versions/053_add_version_columns_to_service.py [new file with mode: 0644]
cinder/db/sqlalchemy/models.py
cinder/objects/backup.py
cinder/objects/base.py
cinder/objects/snapshot.py
cinder/objects/volume.py
cinder/tests/unit/test_migrations.py

index a237119ec5eaa34cd014999d3dfc42e3b2c6622a..19419c6298d676665535ffaeeed635fc2151df8d 100644 (file)
@@ -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 (file)
index 0000000..8caae5c
--- /dev/null
@@ -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)
index 3011c9463607ef72b8b22ec23559934926ffb275..f2bdc27d8691fdea2eb79725dcc0a15b6a92dc25 100644 (file)
@@ -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."""
index b6f17674dd293f8b8a465b8873eff96e5d19df3c..0586e51790fb4bfce4c82d3a69de0a6ab08fd09a 100644 (file)
@@ -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
index 961308955559984792ccbf93f05cf7798a81920e..105aa915d1f5b2f11113bc96cf1e87b4d145bf27 100644 (file)
@@ -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.
 
index c482313894cde4282c39645a08a77c08bd468855..ebfbf96dcfd0fdbe386391e5cfadbdd5d7ec9d8c 100644 (file)
@@ -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
index 6270c55c0d2a694ee0e7bf22c6236451f51de03d..a4d999e82a8b888ad339aa74db7f2a2cb1a2efe6 100644 (file)
@@ -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
index f0e5d5677d1d16375b66e401a9bf189a3157f7b5..e5a335f721d6732ba527f6f353f839c05bef7e5c 100644 (file)
@@ -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)