Add get_minimum_version() to Service object and DB API
This gives us an easy way to query the current minimum service version of any service (by name/binary) in the database. We can then use this to drive policy about things like RPC versions. Related to blueprint service-version-behavior Change-Id: I6acec8b881c5950585e0ffb6e62804c472d371e8
This commit is contained in:
@@ -100,6 +100,12 @@ def service_get(context, service_id, use_slave=False):
|
||||
use_slave=use_slave)
|
||||
|
||||
|
||||
def service_get_minimum_version(context, binary, use_slave=False):
|
||||
"""Get the minimum service version in the database."""
|
||||
return IMPL.service_get_minimum_version(context, binary,
|
||||
use_slave=use_slave)
|
||||
|
||||
|
||||
def service_get_by_host_and_topic(context, host, topic):
|
||||
"""Get a service by hostname and topic it listens to."""
|
||||
return IMPL.service_get_by_host_and_topic(context, host, topic)
|
||||
|
||||
@@ -440,6 +440,17 @@ def service_get(context, service_id, use_slave=False):
|
||||
use_slave=use_slave)
|
||||
|
||||
|
||||
def service_get_minimum_version(context, binary, use_slave=False):
|
||||
session = get_session(use_slave=use_slave)
|
||||
with session.begin():
|
||||
min_version = session.query(
|
||||
func.min(models.Service.version)).\
|
||||
filter(models.Service.binary == binary).\
|
||||
filter(models.Service.forced_down == false()).\
|
||||
scalar()
|
||||
return min_version
|
||||
|
||||
|
||||
def service_get_all(context, disabled=None):
|
||||
query = model_query(context, models.Service)
|
||||
|
||||
|
||||
@@ -49,7 +49,7 @@ SERVICE_VERSION = 2
|
||||
# in the cluster are at the same level.
|
||||
SERVICE_VERSION_HISTORY = (
|
||||
# Version 0: Pre-history
|
||||
None,
|
||||
{'compute_rpc': '4.0'},
|
||||
|
||||
# Version 1: Introduction of SERVICE_VERSION
|
||||
{'compute_rpc': '4.4'},
|
||||
@@ -81,7 +81,8 @@ class Service(base.NovaPersistentObject, base.NovaObject,
|
||||
# Version 1.16: Added version
|
||||
# Version 1.17: ComputeNode version 1.13
|
||||
# Version 1.18: ComputeNode version 1.14
|
||||
VERSION = '1.18'
|
||||
# Version 1.19: Added get_minimum_version()
|
||||
VERSION = '1.19'
|
||||
|
||||
fields = {
|
||||
'id': fields.IntegerField(read_only=True),
|
||||
@@ -254,6 +255,16 @@ class Service(base.NovaPersistentObject, base.NovaObject,
|
||||
def destroy(self):
|
||||
db.service_destroy(self._context, self.id)
|
||||
|
||||
@base.remotable_classmethod
|
||||
def get_minimum_version(cls, context, binary, use_slave=False):
|
||||
version = db.service_get_minimum_version(context, binary,
|
||||
use_slave=use_slave)
|
||||
if version is None:
|
||||
return 0
|
||||
# NOTE(danms): Since our return value is not controlled by object
|
||||
# schema, be explicit here.
|
||||
return int(version)
|
||||
|
||||
|
||||
@base.NovaObjectRegistry.register
|
||||
class ServiceList(base.ObjectListBase, base.NovaObject):
|
||||
@@ -275,7 +286,8 @@ class ServiceList(base.ObjectListBase, base.NovaObject):
|
||||
# Version 1.14: Service version 1.16
|
||||
# Version 1.15: Service version 1.17
|
||||
# Version 1.16: Service version 1.18
|
||||
VERSION = '1.16'
|
||||
# Version 1.17: Service version 1.19
|
||||
VERSION = '1.17'
|
||||
|
||||
fields = {
|
||||
'objects': fields.ListOfObjectsField('Service'),
|
||||
@@ -287,7 +299,7 @@ class ServiceList(base.ObjectListBase, base.NovaObject):
|
||||
('1.6', '1.8'), ('1.7', '1.9'), ('1.8', '1.10'),
|
||||
('1.9', '1.11'), ('1.10', '1.12'), ('1.11', '1.13'),
|
||||
('1.12', '1.14'), ('1.13', '1.15'), ('1.14', '1.16'),
|
||||
('1.15', '1.17'), ('1.16', '1.18')],
|
||||
('1.15', '1.17'), ('1.16', '1.18'), ('1.17', '1.19')],
|
||||
}
|
||||
|
||||
@base.remotable_classmethod
|
||||
|
||||
@@ -3167,6 +3167,20 @@ class ServiceTestCase(test.TestCase, ModelsObjectComparatorMixin):
|
||||
self._assertEqualObjects(service1, real_service1,
|
||||
ignored_keys=['compute_node'])
|
||||
|
||||
def test_service_get_minimum_version(self):
|
||||
self._create_service({'version': 1,
|
||||
'host': 'host3',
|
||||
'binary': 'compute',
|
||||
'forced_down': True})
|
||||
self._create_service({'version': 2,
|
||||
'host': 'host1',
|
||||
'binary': 'compute'})
|
||||
self._create_service({'version': 3,
|
||||
'host': 'host2',
|
||||
'binary': 'compute'})
|
||||
self.assertEqual(2, db.service_get_minimum_version(self.ctxt,
|
||||
'compute'))
|
||||
|
||||
def test_service_get_not_found_exception(self):
|
||||
self.assertRaises(exception.ServiceNotFound,
|
||||
db.service_get, self.ctxt, 100500)
|
||||
|
||||
@@ -1243,8 +1243,8 @@ object_data = {
|
||||
'SecurityGroupList': '1.0-dc8bbea01ba09a2edb6e5233eae85cbc',
|
||||
'SecurityGroupRule': '1.1-ae1da17b79970012e8536f88cb3c6b29',
|
||||
'SecurityGroupRuleList': '1.1-674b323c9ccea02e93b1b40e7fd2091a',
|
||||
'Service': '1.18-f1c6e82b5479f63e35970fe7625c3878',
|
||||
'ServiceList': '1.16-b767102cba7cbed290e396114c3f86b3',
|
||||
'Service': '1.19-8914320cbeb4ec29f252d72ce55d07e1',
|
||||
'ServiceList': '1.17-b767102cba7cbed290e396114c3f86b3',
|
||||
'TaskLog': '1.0-78b0534366f29aa3eebb01860fbe18fe',
|
||||
'TaskLogList': '1.0-cc8cce1af8a283b9d28b55fcd682e777',
|
||||
'Tag': '1.1-8b8d7d5b48887651a0e01241672e2963',
|
||||
|
||||
@@ -279,6 +279,24 @@ class _TestServiceObject(object):
|
||||
'1.5',
|
||||
fake_service_dict['compute_node']['nova_object.version'])
|
||||
|
||||
@mock.patch('nova.db.service_get_minimum_version')
|
||||
def test_get_minimum_version_none(self, mock_get):
|
||||
mock_get.return_value = None
|
||||
self.assertEqual(0,
|
||||
objects.Service.get_minimum_version(self.context,
|
||||
'compute'))
|
||||
mock_get.assert_called_once_with(self.context, 'compute',
|
||||
use_slave=False)
|
||||
|
||||
@mock.patch('nova.db.service_get_minimum_version')
|
||||
def test_get_minimum_version(self, mock_get):
|
||||
mock_get.return_value = 123
|
||||
self.assertEqual(123,
|
||||
objects.Service.get_minimum_version(self.context,
|
||||
'compute'))
|
||||
mock_get.assert_called_once_with(self.context, 'compute',
|
||||
use_slave=False)
|
||||
|
||||
|
||||
class TestServiceObject(test_objects._LocalTest,
|
||||
_TestServiceObject):
|
||||
|
||||
Reference in New Issue
Block a user