Use versionutils.is_compatible for Nova Objects

Oslo's check is designed to support version checking for a number of different
existing use-cases, including this one.

Related-Oslo-Commit: d7d74a752e34d5249fa47c8e8252da491d46012a
Change-Id: I8e03c7781330b02deb7af815d68538b5c0245c4d
This commit is contained in:
Rick Harris
2013-10-08 21:08:23 +00:00
parent c52259d386
commit 3ab91c4770
3 changed files with 55 additions and 29 deletions

View File

@@ -25,6 +25,7 @@ from nova.openstack.common.gettextutils import _
from nova.openstack.common import log as logging
from nova.openstack.common.rpc import common as rpc_common
import nova.openstack.common.rpc.serializer
from nova.openstack.common import versionutils
LOG = logging.getLogger('object')
@@ -149,30 +150,6 @@ def remotable(fn):
return wrapper
# Object versioning rules
#
# Each service has its set of objects, each with a version attached. When
# a client attempts to call an object method, the server checks to see if
# the version of that object matches (in a compatible way) its object
# implementation. If so, cool, and if not, fail.
def check_object_version(server, client):
try:
client_major, _client_minor = client.split('.')
server_major, _server_minor = server.split('.')
client_minor = int(_client_minor)
server_minor = int(_server_minor)
except ValueError:
raise exception.IncompatibleObjectVersion(
_('Invalid version string'))
if client_major != server_major:
raise exception.IncompatibleObjectVersion(
dict(client=client_major, server=server_major))
if client_minor > server_minor:
raise exception.IncompatibleObjectVersion(
dict(client=client_minor, server=server_minor))
class NovaObject(object):
"""Base class and object factory.
@@ -184,7 +161,12 @@ class NovaObject(object):
"""
__metaclass__ = NovaObjectMetaclass
# Version of this object (see rules above check_object_version())
# Object versioning rules
#
# Each service has its set of objects, each with a version attached. When
# a client attempts to call an object method, the server checks to see if
# the version of that object matches (in a compatible way) its object
# implementation. If so, cool, and if not, fail.
VERSION = '1.0'
# The fields present in this object as key:field pairs. For example:
@@ -218,11 +200,9 @@ class NovaObject(object):
for objclass in cls._obj_classes[objname]:
if objclass.VERSION == objver:
return objclass
try:
check_object_version(objclass.VERSION, objver)
if versionutils.is_compatible(objver, objclass.VERSION):
compatible_match = objclass
except exception.IncompatibleObjectVersion:
pass
if compatible_match:
return compatible_match

View File

@@ -0,0 +1,45 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright (c) 2013 OpenStack Foundation
# 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.
"""
Helpers for comparing version strings.
"""
import pkg_resources
def is_compatible(requested_version, current_version, same_major=True):
"""Determine whether `requested_version` is satisfied by
`current_version`; in other words, `current_version` is >=
`requested_version`.
:param requested_version: version to check for compatibility
:param current_version: version to check against
:param same_major: if True, the major version must be identical between
`requested_version` and `current_version`. This is used when a
major-version difference indicates incompatibility between the two
versions. Since this is the common-case in practice, the default is
True.
:returns: True if compatible, False if not
"""
requested_parts = pkg_resources.parse_version(requested_version)
current_parts = pkg_resources.parse_version(current_version)
if same_major and (requested_parts[0] != current_parts[0]):
return False
return current_parts >= requested_parts

View File

@@ -33,6 +33,7 @@ module=strutils
module=threadgroup
module=timeutils
module=uuidutils
module=versionutils
module=xmlutils
# The base module to hold the copy of openstack.common