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
This commit is contained in:
parent
442aea54c9
commit
677ff1c699
|
@ -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)
|
||||
|
|
|
@ -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)
|
|
@ -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."""
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
Loading…
Reference in New Issue