Merge "Make os-availability-zones know about cells"

This commit is contained in:
Jenkins 2017-03-16 15:39:50 +00:00 committed by Gerrit Code Review
commit 03d04063b3
5 changed files with 54 additions and 11 deletions

View File

@ -16,8 +16,8 @@ from nova.api.openstack.compute.schemas import availability_zone as schema
from nova.api.openstack import extensions
from nova.api.openstack import wsgi
from nova import availability_zones
from nova import compute
import nova.conf
from nova import objects
from nova.policies import availability_zone as az_policies
from nova import servicegroup
@ -32,6 +32,7 @@ class AvailabilityZoneController(wsgi.Controller):
def __init__(self):
super(AvailabilityZoneController, self).__init__()
self.servicegroup_api = servicegroup.API()
self.host_api = compute.HostAPI()
def _get_filtered_availability_zones(self, zones, is_available):
result = []
@ -62,8 +63,9 @@ class AvailabilityZoneController(wsgi.Controller):
availability_zones.get_availability_zones(ctxt)
# Available services
enabled_services = objects.ServiceList.get_all(context, disabled=False,
set_zones=True)
enabled_services = self.host_api.service_get_all(
context, {'disabled': False}, set_zones=True, all_cells=True)
zone_hosts = {}
host_services = {}
api_services = ('nova-osapi_compute', 'nova-ec2', 'nova-metadata')

View File

@ -120,8 +120,12 @@ def get_availability_zones(context, get_only_available=False,
:param with_hosts: whether to return hosts part of the AZs
:type with_hosts: bool
"""
enabled_services = objects.ServiceList.get_all(context, disabled=False,
set_zones=True)
# NOTE(danms): Avoid circular import
from nova import compute
hostapi = compute.HostAPI()
enabled_services = hostapi.service_get_all(
context, {'disabled': False}, set_zones=True, all_cells=True)
available_zones = []
for (zone, host) in [(service['availability_zone'], service['host'])
@ -136,8 +140,8 @@ def get_availability_zones(context, get_only_available=False,
available_zones = list(_available_zones.items())
if not get_only_available:
disabled_services = objects.ServiceList.get_all(context, disabled=True,
set_zones=True)
disabled_services = hostapi.service_get_all(
context, {'disabled': True}, set_zones=True, all_cells=True)
not_available_zones = []
azs = available_zones if not with_hosts else dict(available_zones)
zones = [(service['availability_zone'], service['host'])

View File

@ -4328,20 +4328,36 @@ class HostAPI(base.Base):
payload)
return result
def service_get_all(self, context, filters=None, set_zones=False):
def service_get_all(self, context, filters=None, set_zones=False,
all_cells=False):
"""Returns a list of services, optionally filtering the results.
If specified, 'filters' should be a dictionary containing services
attributes and matching values. Ie, to get a list of services for
the 'compute' topic, use filters={'topic': 'compute'}.
If all_cells=True, then scan all cells and merge the results.
"""
if filters is None:
filters = {}
disabled = filters.pop('disabled', None)
if 'availability_zone' in filters:
set_zones = True
services = objects.ServiceList.get_all(context, disabled,
set_zones=set_zones)
# NOTE(danms): Eventually this all_cells nonsense should go away
# and we should always iterate over the cells. However, certain
# callers need the legacy behavior for now.
if all_cells:
load_cells()
services = []
for cell in CELLS:
with nova_context.target_cell(context, cell):
cell_services = objects.ServiceList.get_all(
context, disabled, set_zones=set_zones)
services.extend(cell_services)
else:
services = objects.ServiceList.get_all(context, disabled,
set_zones=set_zones)
ret_services = []
for service in services:
for key, val in filters.items():

View File

@ -546,7 +546,13 @@ class HostAPI(compute_api.HostAPI):
"""Returns the result of calling "uptime" on the target host."""
return self.cells_rpcapi.get_host_uptime(context, host_name)
def service_get_all(self, context, filters=None, set_zones=False):
def service_get_all(self, context, filters=None, set_zones=False,
all_cells=False):
"""Get all services.
Note that this is the cellsv1 variant, which means we ignore the
"all_cells" parameter.
"""
if filters is None:
filters = {}
if 'availability_zone' in filters:

View File

@ -173,6 +173,17 @@ class ComputeHostAPITestCase(test.TestCase):
_do_test()
def test_service_get_all_cells(self):
cells = objects.CellMappingList.get_all(self.ctxt)
for cell in cells:
with context.target_cell(self.ctxt, cell):
objects.Service(context=self.ctxt,
binary='nova-compute',
host='host-%s' % cell.uuid).create()
services = self.host_api.service_get_all(self.ctxt, all_cells=True)
self.assertEqual(sorted(['host-%s' % cell.uuid for cell in cells]),
sorted([svc.host for svc in services]))
def test_service_get_all_no_zones(self):
services = [dict(test_service.fake_service,
id=1, topic='compute', host='host1'),
@ -338,6 +349,10 @@ class ComputeHostAPICellsTestCase(ComputeHostAPITestCase):
self.flags(cell_type='api', group='cells')
super(ComputeHostAPICellsTestCase, self).setUp()
@testtools.skip('cellsv1 does not use this')
def test_service_get_all_cells(self):
pass
def test_service_get_all_no_zones(self):
services = [
cells_utils.ServiceProxy(