Merge "Fix logic for checking if az can be updated"
This commit is contained in:
commit
9d77ab1290
@ -3578,34 +3578,17 @@ class AggregateAPI(base.Base):
|
|||||||
"""
|
"""
|
||||||
if 'availability_zone' in metadata:
|
if 'availability_zone' in metadata:
|
||||||
_hosts = hosts or aggregate.hosts
|
_hosts = hosts or aggregate.hosts
|
||||||
zones, not_zones = availability_zones.get_availability_zones(
|
host_aggregates = objects.AggregateList.get_by_metadata_key(
|
||||||
context, with_hosts=True)
|
context, 'availability_zone', hosts=_hosts)
|
||||||
for host in _hosts:
|
conflicting_azs = [
|
||||||
# NOTE(sbauza): Host can only be in one AZ, so let's take only
|
agg.availability_zone for agg in host_aggregates
|
||||||
# the first element
|
if agg.availability_zone != metadata['availability_zone']
|
||||||
host_azs = [az for (az, az_hosts) in zones
|
and agg.id != aggregate.id]
|
||||||
if host in az_hosts
|
if conflicting_azs:
|
||||||
and az != CONF.internal_service_availability_zone]
|
msg = _("One or more hosts already in availability zone(s) "
|
||||||
host_az = host_azs.pop()
|
"%s") % conflicting_azs
|
||||||
if host_azs:
|
self._raise_invalid_aggregate_exc(action_name, aggregate.id,
|
||||||
LOG.warning(_LW("More than 1 AZ for host %s"), host)
|
msg)
|
||||||
if host_az == CONF.default_availability_zone:
|
|
||||||
# NOTE(sbauza): Aggregate with AZ set to default AZ can
|
|
||||||
# exist, we need to check
|
|
||||||
host_aggs = objects.AggregateList.get_by_host(
|
|
||||||
context, host, key='availability_zone')
|
|
||||||
default_aggs = [agg for agg in host_aggs
|
|
||||||
if agg['metadata'].get(
|
|
||||||
'availability_zone'
|
|
||||||
) == CONF.default_availability_zone]
|
|
||||||
else:
|
|
||||||
default_aggs = []
|
|
||||||
if (host_az != aggregate.metadata.get('availability_zone') and
|
|
||||||
(host_az != CONF.default_availability_zone or
|
|
||||||
len(default_aggs) != 0)):
|
|
||||||
self._check_az_for_host(
|
|
||||||
metadata, host_az, aggregate.id,
|
|
||||||
action_name=action_name)
|
|
||||||
|
|
||||||
def _raise_invalid_aggregate_exc(self, action_name, aggregate_id, reason):
|
def _raise_invalid_aggregate_exc(self, action_name, aggregate_id, reason):
|
||||||
if action_name == AGGREGATE_ACTION_ADD:
|
if action_name == AGGREGATE_ACTION_ADD:
|
||||||
@ -3624,27 +3607,6 @@ class AggregateAPI(base.Base):
|
|||||||
raise exception.NovaException(
|
raise exception.NovaException(
|
||||||
_("Unexpected aggregate action %s") % action_name)
|
_("Unexpected aggregate action %s") % action_name)
|
||||||
|
|
||||||
def _check_az_for_host(self, aggregate_meta, host_az, aggregate_id,
|
|
||||||
action_name=AGGREGATE_ACTION_ADD):
|
|
||||||
# NOTE(mtreinish) The availability_zone key returns a set of
|
|
||||||
# zones so loop over each zone. However there should only
|
|
||||||
# ever be one zone in the set because an aggregate can only
|
|
||||||
# have a single availability zone set at one time.
|
|
||||||
if isinstance(aggregate_meta["availability_zone"], six.string_types):
|
|
||||||
azs = set([aggregate_meta["availability_zone"]])
|
|
||||||
else:
|
|
||||||
azs = aggregate_meta["availability_zone"]
|
|
||||||
|
|
||||||
for aggregate_az in azs:
|
|
||||||
# NOTE(mtreinish) Ensure that the aggregate_az is not none
|
|
||||||
# if it is none then that is just a regular aggregate and
|
|
||||||
# it is valid to have a host in multiple aggregates.
|
|
||||||
if aggregate_az and aggregate_az != host_az:
|
|
||||||
msg = _("Host already in availability zone "
|
|
||||||
"%s") % host_az
|
|
||||||
self._raise_invalid_aggregate_exc(action_name,
|
|
||||||
aggregate_id, msg)
|
|
||||||
|
|
||||||
def _update_az_cache_for_host(self, context, host_name, aggregate_meta):
|
def _update_az_cache_for_host(self, context, host_name, aggregate_meta):
|
||||||
# Update the availability_zone cache to avoid getting wrong
|
# Update the availability_zone cache to avoid getting wrong
|
||||||
# availability_zone in cache retention time when add/remove
|
# availability_zone in cache retention time when add/remove
|
||||||
@ -3664,11 +3626,9 @@ class AggregateAPI(base.Base):
|
|||||||
# validates the host; ComputeHostNotFound is raised if invalid
|
# validates the host; ComputeHostNotFound is raised if invalid
|
||||||
objects.Service.get_by_compute_host(context, host_name)
|
objects.Service.get_by_compute_host(context, host_name)
|
||||||
|
|
||||||
metadata = self.db.aggregate_metadata_get_by_metadata_key(
|
|
||||||
context, aggregate_id, 'availability_zone')
|
|
||||||
aggregate = objects.Aggregate.get_by_id(context, aggregate_id)
|
aggregate = objects.Aggregate.get_by_id(context, aggregate_id)
|
||||||
self.is_safe_to_update_az(context, metadata, hosts=[host_name],
|
self.is_safe_to_update_az(context, aggregate.metadata,
|
||||||
aggregate=aggregate)
|
hosts=[host_name], aggregate=aggregate)
|
||||||
|
|
||||||
aggregate.add_host(host_name)
|
aggregate.add_host(host_name)
|
||||||
self.scheduler_client.update_aggregates(context, [aggregate])
|
self.scheduler_client.update_aggregates(context, [aggregate])
|
||||||
|
@ -194,7 +194,7 @@ class AggregateList(base.ObjectListBase, base.NovaObject):
|
|||||||
@base.remotable_classmethod
|
@base.remotable_classmethod
|
||||||
def get_by_metadata_key(cls, context, key, hosts=None):
|
def get_by_metadata_key(cls, context, key, hosts=None):
|
||||||
db_aggregates = db.aggregate_get_by_metadata_key(context, key=key)
|
db_aggregates = db.aggregate_get_by_metadata_key(context, key=key)
|
||||||
if hosts:
|
if hosts is not None:
|
||||||
db_aggregates = cls._filter_db_aggregates(db_aggregates, hosts)
|
db_aggregates = cls._filter_db_aggregates(db_aggregates, hosts)
|
||||||
return base.obj_make_list(context, cls(context), objects.Aggregate,
|
return base.obj_make_list(context, cls(context), objects.Aggregate,
|
||||||
db_aggregates)
|
db_aggregates)
|
||||||
|
@ -10319,19 +10319,8 @@ class ComputeAPIAggrTestCase(BaseTestCase):
|
|||||||
self.mox.StubOutWithMock(availability_zones,
|
self.mox.StubOutWithMock(availability_zones,
|
||||||
'update_host_availability_zone_cache')
|
'update_host_availability_zone_cache')
|
||||||
|
|
||||||
def _stub_update_host_avail_zone_cache(host, az=None):
|
availability_zones.update_host_availability_zone_cache(self.context,
|
||||||
if az is not None:
|
fake_host)
|
||||||
availability_zones.update_host_availability_zone_cache(
|
|
||||||
self.context, host, az)
|
|
||||||
else:
|
|
||||||
availability_zones.update_host_availability_zone_cache(
|
|
||||||
self.context, host)
|
|
||||||
|
|
||||||
for (avail_zone, hosts) in values:
|
|
||||||
for host in hosts:
|
|
||||||
_stub_update_host_avail_zone_cache(
|
|
||||||
host, CONF.default_availability_zone)
|
|
||||||
_stub_update_host_avail_zone_cache(fake_host)
|
|
||||||
self.mox.ReplayAll()
|
self.mox.ReplayAll()
|
||||||
|
|
||||||
fake_notifier.NOTIFICATIONS = []
|
fake_notifier.NOTIFICATIONS = []
|
||||||
|
Loading…
Reference in New Issue
Block a user