During the process of launching a new VM instance, the function "get_instance_availability_zone()" of the module "nova.availability_zones" is called multiple times to retrieve the info of availability zone of the VM being created.
This function, at first, it will try to get the info of availability zone from the memory cache. If the info of availability zone is not contained in memory cache, then the function continues retrieving the info of availability zone from the host aggregate.
However, the default availability zone (for example "nova") is always specified in the memory cache. Furthermore, the memory cache is not updated immediately after a new availability zone is created. Instead, the memory cache is updated for every one hour (the const AZ_CACHE_SECONDS is the proof) . Consequently, the if-clause never holds.
def get_instance_availability_zone(context, instance):
"""Return availability zone of specified instance."""
host = str(instance.get('host'))
if not host:
return None
cache_key = _make_cache_key(host)
cache = _get_cache()
az = cache.get(cache_key)
if not az:
elevated = context.elevated()
az = get_host_availability_zone(elevated, host) cache.set(cache_key, az, AZ_CACHE_SECONDS)
return az
It should be noted that the info of availability zone (during the process of launching new VM) is retrieved not only from the memory cache (as seen in this function) but it is also retrieved (somewhere else) directly from the host aggregate. Therefore, it results in the toggling effect of Horizon dashboard (i.e. value of availability zone is sometimes the default one and sometimes the newly-created one).
Proposal:
modify the function "get_instance_availability_zone()" of the module "nova.availability_zones" in such a manner that if the info of availability zone retrieved from memory cache is different from the one included in the VM instance (being launched), then memory cache will be updated manually and the info of availability zone included in the VM instance (being launched) will be returned.
Root cause of this bug is as follows.
During the process of launching a new VM instance, the function "get_instance_ availability_ zone()" of the module "nova.availabil ity_zones" is called multiple times to retrieve the info of availability zone of the VM being created.
This function, at first, it will try to get the info of availability zone from the memory cache. If the info of availability zone is not contained in memory cache, then the function continues retrieving the info of availability zone from the host aggregate.
However, the default availability zone (for example "nova") is always specified in the memory cache. Furthermore, the memory cache is not updated immediately after a new availability zone is created. Instead, the memory cache is updated for every one hour (the const AZ_CACHE_SECONDS is the proof) . Consequently, the if-clause never holds.
def get_instance_ availability_ zone(context, instance): get('host' ))
"""Return availability zone of specified instance."""
host = str(instance.
if not host:
return None
cache_key = _make_cache_ key(host) cache_key)
cache = _get_cache()
az = cache.get(
if not az: availability_ zone(elevated, host)
cache. set(cache_ key, az, AZ_CACHE_SECONDS)
elevated = context.elevated()
az = get_host_
return az
It should be noted that the info of availability zone (during the process of launching new VM) is retrieved not only from the memory cache (as seen in this function) but it is also retrieved (somewhere else) directly from the host aggregate. Therefore, it results in the toggling effect of Horizon dashboard (i.e. value of availability zone is sometimes the default one and sometimes the newly-created one).
Proposal: availability_ zone()" of the module "nova.availabil ity_zones" in such a manner that if the info of availability zone retrieved from memory cache is different from the one included in the VM instance (being launched), then memory cache will be updated manually and the info of availability zone included in the VM instance (being launched) will be returned.
modify the function "get_instance_