Add rpc client side version control.

This is a first pass at client side version control for rpc.  It allows
you to configure a max version of messages that clients are allowed to
send.  You can find one example of how clients need to adapt in the
conductor rpcapi.  All other changes in rpc apis since the grizzly
release are not applicable to this.

Some future improvements to this could be reporting the versions
supported by running services and having that be discoverable via the
API.  We could also consider allow setting these client side version
caps via the API.  For now, recommended values for these config
options while attempting a rolling upgrade will just have to be documented.

The config options allow specifying specific rpc api version numbers if
desired, but an alias of 'grizzly' is also supported.  So typically at
the start of a rolling upgrade you'd have:

    [upgrade_levels]
    compute=grizzly
    conductor=grizzly
    scheduler=grizzly
    ... etc ...

And as you update all instances of a service, you would remove that bit
from your configuration across the deployment using your config management
system of choice.

DocImpact

Implements blueprint rpc-version-control.

Change-Id: I2c0fd6dd7484c87823846d7c31d6525d93cd1b43
This commit is contained in:
Russell Bryant
2013-06-10 21:18:37 -04:00
parent b37c17952b
commit f0aaa78e78
2 changed files with 34 additions and 2 deletions

View File

@@ -18,11 +18,20 @@
Base RPC client and server common to all services.
"""
from oslo.config import cfg
from nova.openstack.common import jsonutils
from nova.openstack.common import rpc
import nova.openstack.common.rpc.proxy as rpc_proxy
CONF = cfg.CONF
rpcapi_cap_opt = cfg.StrOpt('baseapi',
default=None,
help='Set a version cap for messages sent to the base api in any '
'service')
CONF.register_opt(rpcapi_cap_opt, 'upgrade_levels')
_NAMESPACE = 'baseapi'
@@ -45,9 +54,16 @@ class BaseAPI(rpc_proxy.RpcProxy):
#
BASE_RPC_API_VERSION = '1.0'
VERSION_ALIASES = {
# baseapi was added in havana
}
def __init__(self, topic):
version_cap = self.VERSION_ALIASES.get(CONF.upgrade_levels.baseapi,
CONF.upgrade_levels.baseapi)
super(BaseAPI, self).__init__(topic=topic,
default_version=self.BASE_RPC_API_VERSION)
default_version=self.BASE_RPC_API_VERSION,
version_cap=version_cap)
self.namespace = _NAMESPACE
def ping(self, context, arg, timeout=None):

View File

@@ -32,6 +32,11 @@ rpcapi_opts = [
CONF = cfg.CONF
CONF.register_opts(rpcapi_opts)
rpcapi_cap_opt = cfg.StrOpt('scheduler',
default=None,
help='Set a version cap for messages sent to scheduler services')
CONF.register_opt(rpcapi_cap_opt, 'upgrade_levels')
class SchedulerAPI(nova.openstack.common.rpc.proxy.RpcProxy):
'''Client side of the scheduler rpc API.
@@ -58,6 +63,10 @@ class SchedulerAPI(nova.openstack.common.rpc.proxy.RpcProxy):
- accepts a list of capabilities
2.5 - Add get_backdoor_port()
2.6 - Add select_hosts()
... Grizzly supports message version 2.6. So, any changes to existing
methods in 2.x after that point should be done such that they can
handle the version_cap being set to 2.6.
'''
#
@@ -70,9 +79,16 @@ class SchedulerAPI(nova.openstack.common.rpc.proxy.RpcProxy):
#
BASE_RPC_API_VERSION = '2.0'
VERSION_ALIASES = {
'grizzly': '2.6',
}
def __init__(self):
version_cap = self.VERSION_ALIASES.get(CONF.upgrade_levels.scheduler,
CONF.upgrade_levels.scheduler)
super(SchedulerAPI, self).__init__(topic=CONF.scheduler_topic,
default_version=self.BASE_RPC_API_VERSION)
default_version=self.BASE_RPC_API_VERSION,
version_cap=version_cap)
def run_instance(self, ctxt, request_spec, admin_password,
injected_files, requested_networks, is_first_time,