Resolve affinity group with flavor id

Fix tempest exclusivity test
default_ram_allocation_ratio to float
cpu&disk ratio to float
incorrect types for conf options
valet-engine does not restart after manual kill

Change-Id: I3eae2bb2144a5857dae17b99fb868b57116cef05
This commit is contained in:
Gueyoung Jung 2017-01-25 04:05:44 -05:00 committed by Omar Rivera
parent 6185beead9
commit fc0d8fc3fc
16 changed files with 166 additions and 120 deletions

View File

@ -4,7 +4,7 @@ if [ -z $VALET_KEYSPACE ]; then
echo "ERR: VALET_KEYSPACE is not defined."
exit
else
sed -ie "s/#VALET_KEYSPACE#/${VALET_KEYSPACE}/g" ./populate.cql
sed -i.bak "s/#VALET_KEYSPACE#/${VALET_KEYSPACE}/g" ./populate.cql
fi
if [ -z $CASSANDRA_BIN ]; then

View File

@ -26,7 +26,7 @@ def terminate_thread(thread):
if not thread.isAlive():
return
print('valet watcher thread: notifier thread is alive... - kill it...')
# print('valet watcher thread: notifier thread is alive... - kill it...')
exc = ctypes.py_object(SystemExit)
res = ctypes.pythonapi.PyThreadState_SetAsyncExc(ctypes.c_long(thread.ident), exc)
if res == 0:
@ -36,4 +36,4 @@ def terminate_thread(thread):
# and you should call it again with exc=NULL to revert the effect
ctypes.pythonapi.PyThreadState_SetAsyncExc(thread.ident, None)
raise SystemError("PyThreadState_SetAsyncExc failed")
print('valet watcher thread exits')
# print('valet watcher thread exits')

View File

@ -211,18 +211,13 @@ class Query(object):
def __rows_to_objects(self, rows):
"""Convert query response rows to objects"""
try:
results = []
pk_name = self.model.pk_name() # pylint: disable=E1101
for __, row in rows.iteritems(): # pylint: disable=W0612
the_id = row.pop(pk_name)
result = self.model(_insert=False, **row)
setattr(result, pk_name, the_id)
results.append(result)
except Exception:
import traceback
print(traceback.format_exc())
results = []
pk_name = self.model.pk_name() # pylint: disable=E1101
for __, row in rows.iteritems(): # pylint: disable=W0612
the_id = row.pop(pk_name)
result = self.model(_insert=False, **row)
setattr(result, pk_name, the_id)
results.append(result)
return Results(results)
def all(self):

View File

@ -76,12 +76,7 @@ class ErrorsController(object):
response.status = 401
response.content_type = 'text/plain'
LOG.error('unauthorized')
import traceback
traceback.print_stack()
LOG.error(self.__class__)
LOG.error(kw)
response.body = _('Authentication required')
LOG.error(response.body)
return response
@expose('json')

View File

@ -37,13 +37,7 @@ class ConnectionError(Exception):
def print_verbose(verbose, url, headers, body, rest_cmd, timeout):
"""Print verbose data."""
# TODO(Chris Martin): Replace prints with logs
if verbose:
print("Sending Request:\nurl: %s\nheaders: "
"%s\nbody: %s\ncmd: %s\ntimeout: %d\n"
% (url, headers, body,
rest_cmd.__name__ if rest_cmd is not None else None, timeout))
pass
def pretty_print_json(json_thing, sort=True, indents=4):

View File

@ -31,7 +31,8 @@ ostro_cli_opts = [
engine_group = cfg.OptGroup(name='engine', title='Valet Engine conf')
engine_opts = [
cfg.StrOpt('pid', default='/var/run/valet/ostro-daemon.pid'),
cfg.StrOpt('mode', default='live', help='sim will let Ostro simulate datacenter, while live will let it handle a real datacenter'),
cfg.StrOpt('mode', default='live', help='sim will let Ostro simulate datacenter, '
'while live will let it handle a real datacenter'),
cfg.StrOpt('sim_cfg_loc', default='/etc/valet/engine/ostro_sim.cfg'),
cfg.BoolOpt('network_control', default=False, help='whether network controller (i.e., Tegu) has been deployed'),
cfg.StrOpt('network_control_url', default='http://network_control:29444/tegu/api'),
@ -56,18 +57,19 @@ engine_opts = [
help='Set trigger time or frequency for checking datacenter topology (i.e., call AIC Formation)'),
cfg.IntOpt('topology_trigger_frequency', default=3600,
help='Set trigger time or frequency for checking datacenter topology (i.e., call AIC Formation)'),
cfg.IntOpt('default_cpu_allocation_ratio', default=16, help='Set default overbooking ratios. '
'Note that each compute node can have its own ratios'),
cfg.IntOpt('default_ram_allocation_ratio', default=1.5, help='Set default overbooking ratios. '
'Note that each compute node can have its own ratios'),
cfg.IntOpt('default_disk_allocation_ratio', default=1, help='Set default overbooking ratios. '
'Note that each compute node can have its own ratios'),
cfg.IntOpt('static_cpu_standby_ratio', default=20, help='unused percentages of resources (i.e. standby) '
'that are set aside for applications workload spikes.'),
cfg.IntOpt('static_mem_standby_ratio', default=20, help='unused percentages of resources (i.e. standby) '
'that are set aside for applications workload spikes.'),
cfg.IntOpt('static_local_disk_standby_ratio', default=20, help='unused percentages of resources (i.e. standby) '
'that are set aside for applications workload spikes.'),
cfg.FloatOpt('default_cpu_allocation_ratio', default=16, help='Set default overbooking ratios. Note that '
'each compute node can have its own ratios'),
cfg.FloatOpt('default_ram_allocation_ratio', default=1.5, help='Set default overbooking ratios. Note that '
'each compute node can have its own ratios'),
cfg.FloatOpt('default_disk_allocation_ratio', default=1, help='Set default overbooking ratios. Note that '
'each compute node can have its own ratios'),
cfg.FloatOpt('static_cpu_standby_ratio', default=20, help='unused percentages of resources (i.e. standby) '
'that are set aside for applications workload spikes.'),
cfg.FloatOpt('static_mem_standby_ratio', default=20, help='unused percentages of resources (i.e. standby) '
'that are set aside for applications workload spikes.'),
cfg.FloatOpt('static_local_disk_standby_ratio', default=20, help='unused percentages of resources (i.e. standby) '
'that are set aside for applications workload '
'spikes.'),
] + logger_conf("engine")
listener_group = cfg.OptGroup(name='events_listener',

View File

@ -14,7 +14,6 @@
# limitations under the License.
"""App Topology Parser.
- Restrictions of nested groups: EX in EX, EX in DIV, DIV in EX, DIV in DIV
- VM/group cannot exist in multiple EX groups
- Nested group's level cannot be higher than nesting group
@ -26,6 +25,7 @@
OS::Heat::ResourceGroup
"""
import six
from valet.engine.optimizer.app_manager.app_topology_base \
import VGroup, VGroupLink, VM, VMLink, LEVELS
@ -92,7 +92,11 @@ class Parser(object):
else:
vm.name = vm.uuid
vm.flavor = r["properties"]["flavor"]
flavor_id = r["properties"]["flavor"]
if isinstance(flavor_id, six.string_types):
vm.flavor = flavor_id
else:
vm.flavor = str(flavor_id)
if "availability_zone" in r["properties"].keys():
az = r["properties"]["availability_zone"]

View File

@ -564,6 +564,8 @@ class MusicHandler(object):
self.logger.error("DB: " + str(e))
return False
self.logger.info("DB: resource status updated")
return True
def update_resource_log_index(self, _k, _index):

View File

@ -140,11 +140,11 @@ class Ostro(object):
return False
if len(resource_status) > 0:
self.logger.info("bootstrap from db")
self.logger.info("bootstrap from DB")
if not self.resource.bootstrap_from_db(resource_status):
self.logger.error("failed to parse bootstrap data!")
self.logger.info("read bootstrap data from OpenStack")
self.logger.info("bootstrap from OpenStack")
if not self._set_hosts():
return False
@ -303,12 +303,12 @@ class Ostro(object):
for _, vm in app_topology.vms.iteritems():
if self._set_vm_flavor_information(vm) is False:
self.status = "fail to set flavor information"
self.logger.error("failed to set flavor information ")
self.logger.error(self.status)
return None
for _, vg in app_topology.vgroups.iteritems():
if self._set_vm_flavor_information(vg) is False:
self.status = "fail to set flavor information in a group"
self.logger.error("failed to set flavor information in a group")
self.logger.error(self.status)
return None
self.data_lock.acquire()
@ -341,12 +341,12 @@ class Ostro(object):
def _set_vm_flavor_information(self, _v):
if isinstance(_v, VM):
if self._set_vm_flavor_properties(_v) is False:
return False
return self._set_vm_flavor_properties(_v)
else: # affinity group
for _, sg in _v.subvgroups.iteritems():
if self._set_vm_flavor_information(sg) is False:
return False
return True
def _set_vm_flavor_properties(self, _vm):
flavor = self.resource.get_flavor(_vm.flavor)

View File

@ -403,12 +403,13 @@ class ComputeManager(threading.Thread):
fk + ") added")
for rfk in self.resource.flavors.keys():
rf = self.resource.flavors[rfk]
if rfk not in _flavors.keys():
self.resource.flavors[rfk].status = "disabled"
rf.status = "disabled"
self.resource.flavors[rfk].last_update = time.time()
self.logger.warn("ComputeManager: flavor (" +
rfk + ") removed")
rf.last_update = time.time()
self.logger.warn("ComputeManager: flavor (" + rfk + ":" +
rf.flavor_id + ") removed")
for fk in _flavors.keys():
f = _flavors[fk]
@ -416,8 +417,8 @@ class ComputeManager(threading.Thread):
if self._check_flavor_spec_update(f, rf) is True:
rf.last_update = time.time()
self.logger.warn("ComputeManager: flavor (" +
fk + ") spec updated")
self.logger.warn("ComputeManager: flavor (" + fk + ":" +
rf.flavor_id + ") spec updated")
def _check_flavor_spec_update(self, _f, _rf):
spec_updated = False

View File

@ -672,31 +672,31 @@ class Resource(object):
hs.last_update = time.time()
# called from handle_events
def update_host_resources(self, _hn, _st, _vcpus, _vcpus_used, _mem, _fmem,
_ldisk, _fldisk, _avail_least):
"""Return True if status or compute resources avail on host changed."""
updated = False
host = self.hosts[_hn]
if host.status != _st:
host.status = _st
self.logger.debug("Resource.update_host_resources: host status "
"changed")
self.logger.debug("Resource.update_host_resources: host(" + _hn +
") status changed")
updated = True
if host.original_vCPUs != _vcpus or \
host.vCPUs_used != _vcpus_used:
self.logger.debug("Resource.update_host_resources: host cpu "
"changed")
self.logger.debug("Resource.update_host_resources: host(" + _hn +
") cpu changed")
host.original_vCPUs = _vcpus
host.vCPUs_used = _vcpus_used
updated = True
if host.free_mem_mb != _fmem or \
host.original_mem_cap != _mem:
self.logger.debug("Resource.update_host_resources: host mem "
"changed")
self.logger.debug("Resource.update_host_resources: host(" + _hn +
") mem changed")
host.free_mem_mb = _fmem
host.original_mem_cap = _mem
updated = True
@ -704,8 +704,9 @@ class Resource(object):
if host.free_disk_gb != _fldisk or \
host.original_local_disk_cap != _ldisk or \
host.disk_available_least != _avail_least:
self.logger.debug("Resource.update_host_resources: host disk "
"changed")
self.logger.debug("Resource.update_host_resources: host(" + _hn +
") disk changed")
host.free_disk_gb = _fldisk
host.original_local_disk_cap = _ldisk
host.disk_available_least = _avail_least

View File

@ -49,9 +49,9 @@ priority=1
host=valet1
user=m04060
stand_by_list=valet2
start="ssh -o ConnectTimeout=1 %s@%s 'python /usr/local/lib/python2.7/dist-packages/valet/engine/optimizer/ostro_server/ostro_daemon.py -c restart'" % (user, host)
stop="ssh -o ConnectTimeout=1 %s@%s 'python /usr/local/lib/python2.7/dist-packages/valet/engine/optimizer/ostro_server/ostro_daemon.py -c stop'" % (user, host)
test="ssh -o ConnectTimeout=1 %s@%s 'python /usr/local/lib/python2.7/dist-packages/valet/engine/optimizer/ostro_server/health_checker.py ; exit $?'" % (user, host)
start="ssh -o ConnectTimeout=1 %(user)s@%(host)s 'python /usr/local/lib/python2.7/dist-packages/valet/engine/optimizer/ostro_server/ostro_daemon.py -c restart'"
stop="ssh -o ConnectTimeout=1 %(user)s@%(host)s 'python /usr/local/lib/python2.7/dist-packages/valet/engine/optimizer/ostro_server/ostro_daemon.py -c stop'"
test="ssh -o ConnectTimeout=1 %(user)s@%(host)s 'python /usr/local/lib/python2.7/dist-packages/valet/engine/optimizer/ostro_server/health_checker.py ; exit $?'"
[ValetApi]
@ -60,7 +60,7 @@ priority=1
host=valet1
stand_by_list=valet2
user=m04060
start="ssh -o ConnectTimeout=1 %s@%s 'sudo service apache2 restart'" % (user, host)
stop="ssh -o ConnectTimeout=1 %s@%s 'sudo apachectl stop'" % (user, host)
test="exit $(wget -T 1 -t 1 -qO- http://%s:8090/v1 | grep CURRENT | wc -l)" % (host)
start="ssh -o ConnectTimeout=1 %(user)s@%(host)s 'sudo service apache2 restart'"
stop="ssh -o ConnectTimeout=1 %(user)s@%(host)s 'sudo apachectl stop'"
test="exit $(wget -T 1 -t 1 -qO- http://%(host)s:8090/v1 | grep CURRENT | wc -l)"

View File

@ -215,7 +215,7 @@ class HaValetThread (threading.Thread):
user = self.data.get(USER, None)
self.use(user)
my_priority = int(self.data.get(PRIORITY, 1))
start_command = eval(self.data.get(START_COMMAND, None))
start_command = self.data.get(START_COMMAND, None)
stop_command = self.data.get(STOP_COMMAND, None)
test_command = self.data.get(TEST_COMMAND, None)
standby_list = self.data.get(STAND_BY_LIST)
@ -247,31 +247,50 @@ class HaValetThread (threading.Thread):
continue
self.log.info('checking status on - ' + host_in_list)
<<<<<<< HEAD
host = host_in_list
host_active, host_priority = \
self._is_active(eval(test_command))
host = self.data.get(HOST, 'localhost')
self.log.info(host_in_list + ' - host_active = ' +
str(host_active) + ', ' + str(host_priority))
=======
# host = host_in_list
host_active, host_priority = self._is_active(test_command % {'host': host_in_list, 'user': user})
# host = self.data.get(HOST, 'localhost')
self.log.info(host_in_list + ' - host_active = ' + str(host_active) + ', ' + str(host_priority))
>>>>>>> da5d947... Resolve affinity group with flavor id
# Check for split brain: 2 valets active
if i_am_active and host_active:
self.log.info('found two live instances, '
'checking priorities')
should_be_active = self._should_be_active(host_priority, my_priority)
if should_be_active:
<<<<<<< HEAD
self.log.info('deactivate myself, ' + host_in_list +
' already running')
# Deactivate myself
self._deactivate_process(eval(stop_command))
=======
self.log.info('deactivate myself, ' + host_in_list + ' already running')
self._deactivate_process(stop_command % {'host': host, 'user': user}) # Deactivate myself
>>>>>>> da5d947... Resolve affinity group with flavor id
i_am_active = False
else:
self.log.info('deactivate ' + self.data[NAME] +
' on ' + host_in_list +
', already running here')
<<<<<<< HEAD
host = host_in_list
# Deactivate other valet
self._deactivate_process(eval(stop_command))
host = self.data.get(HOST, 'localhost')
=======
# host = host_in_list
# Deactivate other valet
self._deactivate_process(stop_command % {'host': host_in_list, 'user': user})
# host = self.data.get(HOST, 'localhost')
>>>>>>> da5d947... Resolve affinity group with flavor id
# Track that at-least one valet is active
any_active = any_active or host_active
@ -301,6 +320,7 @@ class HaValetThread (threading.Thread):
last_start = now
priority_wait = False
<<<<<<< HEAD
if (not i_am_active and my_priority == PRIMARY_SETUP) or \
(standby_list is not None):
self.log.info('no running instance found, '
@ -313,6 +333,16 @@ class HaValetThread (threading.Thread):
'on %s; last start %s' % (host, diff))
self._activate_process(start_command, my_priority)
host = self.data.get(HOST, 'localhost')
=======
if (not i_am_active and my_priority == PRIMARY_SETUP) or (standby_list is not None):
self.log.info('no running instance found, starting here; last start %s' % diff)
self._activate_process(start_command % {'host': host, 'user': user}, my_priority)
else:
# host = standby_list[0] # LIMITATION - supporting only 1 stand by host
self.log.info('no running instances found, starting on %s; last start %s' % (host, diff))
self._activate_process(start_command % {'host': standby_list[0], 'user': user}, my_priority)
# host = self.data.get(HOST, 'localhost')
>>>>>>> da5d947... Resolve affinity group with flavor id
else:
priority_wait = True
else:
@ -405,6 +435,7 @@ class HAValet(object):
os.makedirs(LOG_DIR)
self.log = None
<<<<<<< HEAD
@DeprecationWarning
def _parse_valet_conf_v010(self, conf_file_name=DEFAULT_CONF_FILE,
process=''):
@ -455,6 +486,8 @@ class HAValet(object):
print('unable to open %s file for some reason' % conf_file_name)
return cdata
=======
>>>>>>> da5d947... Resolve affinity group with flavor id
def _valid_process_conf_data(self, process_data):
"""Valid Process conf data.

View File

@ -49,9 +49,9 @@ priority=2
host=valet2
user=m04060
stand_by_list=valet1
start="ssh -o ConnectTimeout=1 %s@%s 'python /usr/local/lib/python2.7/dist-packages/valet/engine/optimizer/ostro_server/ostro_daemon.py -c restart'" % (user, host)
stop="ssh -o ConnectTimeout=1 %s@%s 'python /usr/local/lib/python2.7/dist-packages/valet/engine/optimizer/ostro_server/ostro_daemon.py -c stop'" % (user, host)
test="ssh -o ConnectTimeout=1 %s@%s 'python /usr/local/lib/python2.7/dist-packages/valet/engine/optimizer/ostro_server/health_checker.py ; exit $?'" % (user, host)
start="ssh -o ConnectTimeout=1 %(user)s@%(host)s 'python /usr/local/lib/python2.7/dist-packages/valet/engine/optimizer/ostro_server/ostro_daemon.py -c restart'"
stop="ssh -o ConnectTimeout=1 %(user)s@%(host)s 'python /usr/local/lib/python2.7/dist-packages/valet/engine/optimizer/ostro_server/ostro_daemon.py -c stop'"
test="ssh -o ConnectTimeout=1 %(user)s@%(host)s 'python /usr/local/lib/python2.7/dist-packages/valet/engine/optimizer/ostro_server/health_checker.py ; exit $?'"
[ValetApi]
@ -60,8 +60,7 @@ priority=2
host=valet2
stand_by_list=valet1
user=m04060
start="ssh -o ConnectTimeout=1 %s@%s 'sudo service apache2 restart'" % (user, host)
stop="ssh -o ConnectTimeout=1 %s@%s 'sudo apachectl stop'" % (user, host)
test="exit $(wget -T 1 -t 1 -qO- http://%s:8090/v1 | grep CURRENT | wc -l)" % (host)
start="ssh -o ConnectTimeout=1 %(user)s@%(host)s 'sudo service apache2 restart'
stop="ssh -o ConnectTimeout=1 %(user)s@%(host)s 'sudo apachectl stop'"
test="exit $(wget -T 1 -t 1 -qO- http://%(host)s:8090/v1 | grep CURRENT | wc -l)"

View File

@ -36,8 +36,9 @@ class Analyzer(object):
self.stack_identifier = stack_id
self.log = logger
self.resource_name = {}
self.instance_on_server = {}
self.host_instance_dict = {}
self.group_instance_name = {}
self.instances_on_host = defaultdict(list)
self.tries = CONF.valet.TRIES_TO_SHOW_SERVER
def check(self, resources):
@ -45,7 +46,6 @@ class Analyzer(object):
self.log.log_info("Starting to check instances location")
result = True
self.init_servers_list()
self.init_resources(resources)
ins_group = self.init_instances_for_group(resources)
@ -73,6 +73,7 @@ class Analyzer(object):
def init_instances_for_group(self, resources):
"""Init instances for a group with the given resources."""
self.log.log_info("initializing instances for group")
ins_group = defaultdict(list)
for grp in resources.groups.keys():
@ -95,22 +96,27 @@ class Analyzer(object):
def init_servers_list(self):
"""Init server list from nova client."""
self.log.log_info("initializing the servers list")
servers_list = self.nova_client.list_servers()
for i in range(len(servers_list["servers"])):
self.log.log_debug("show_server %s from list %s " %
(servers_list["servers"][i]["id"], servers_list["servers"]))
try:
server = \
self.nova_client.show_server(servers_list["servers"][i]["id"])
self.instance_on_server[servers_list["servers"][i]["name"]] = \
server["server"]["OS-EXT-SRV-ATTR:host"]
except Exception:
self.log.log_error("Exception trying to show_server: %s" % traceback.format_exc())
if self.tries > 0:
time.sleep(CONF.valet.PAUSE)
self.init_servers_list()
self.tries -= 1
try:
for i in range(len(servers_list["servers"])):
server = self.nova_client.show_server(servers_list["servers"][i]["id"])
host_name = server["server"]["OS-EXT-SRV-ATTR:host"]
instance_name = servers_list["servers"][i]["name"]
self.host_instance_dict[instance_name] = host_name
self.instances_on_host[host_name].append(instance_name)
except Exception:
self.log.log_error("Exception trying to show_server: %s" % traceback.format_exc())
if self.tries > 0:
time.sleep(CONF.valet.PAUSE)
self.tries -= 1
self.init_servers_list()
for host in self.instances_on_host:
self.instances_on_host[host] = set(self.instances_on_host[host])
def get_instance_name(self, res_name):
"""Return instance name (resource name)."""
@ -120,22 +126,20 @@ class Analyzer(object):
"""Return host of instance with matching name."""
hosts = []
if len(self.instance_on_server) == 0:
self.init_servers_list()
self.log.log_info("instance_on_server: %s" %
self.instance_on_server)
self.init_servers_list()
self.log.log_debug("host - instance dictionary is: %s" % self.host_instance_dict)
for res in res_name:
name = self.get_instance_name(res)
hosts.append(self.instance_on_server[name])
hosts.append(self.host_instance_dict[name])
return hosts
def are_the_same(self, res_name, level):
"""Return true if host aren't the same otherwise return False."""
self.log.log_info("are_the_same")
self.log.log_info("verifying instances are on the same host/racks")
hosts_list = self.get_instance_host(res_name)
self.log.log_info(hosts_list)
self.log.log_debug("hosts to compare: %s" % hosts_list)
try:
for h in hosts_list:
@ -143,43 +147,50 @@ class Analyzer(object):
self.get_host_or_rack(level, h),
self.get_host_or_rack(level, hosts_list[0])) is False:
return False
return True
except Exception as ex:
self.log.log_error("Exception at method are_the_same: %s" %
ex, traceback.format_exc())
self.log.log_error("Exception while verifying instances are on "
"the same host/racks: %s" % ex, traceback.format_exc())
return False
return True
def are_different(self, res_name, level):
"""Check if all hosts (and racks) are different for all instances."""
self.log.log_info("are_different")
self.log.log_info("verifying instances are on different hosts/racks")
diction = {}
hosts_list = self.get_instance_host(res_name)
self.log.log_info(hosts_list)
self.log.log_debug("hosts to compare: %s" % hosts_list)
try:
for h in hosts_list:
if self.is_already_exists(diction, self.get_host_or_rack(level,
h)):
return False
return True
except Exception as ex:
self.log.log_error("Exception at method are_all_hosts_different: %s"
% ex, traceback.format_exc())
self.log.log_error("Exception while verifying instances are on "
"different hosts/racks: %s" % ex, traceback.format_exc())
return False
return True
def are_we_alone(self, ins_for_group, level):
"""Return True if no other instances in group on server."""
self.log.log_info("are_we_alone ")
self.log.log_info(ins_for_group)
self.log.log_info("verifying instances are on the same group hosts/racks")
exclusivity_group_hosts = self.get_exclusivity_group_hosts()
self.log.log_debug("exclusivity group hosts are: %s " % exclusivity_group_hosts)
# instances - all the instances on the exclusivity group hosts
for host in exclusivity_group_hosts:
instances = self.instances_on_host[host]
self.log.log_debug("exclusivity group instances are: %s " % instances)
instances = self.instance_on_server.keys()
if level == "rack":
instances = self.get_rack_instances(set(
self.instance_on_server.values()))
instances = self.get_rack_instances(set(self.host_instance_dict.values()))
# instance_on_server should be all the instances on the rack
# host_instance_dict should be all the instances on the rack
if len(instances) < 1:
return False
@ -202,6 +213,16 @@ class Analyzer(object):
ins_group[x].append(internal_ins)
return ins_group
def get_exclusivity_group_hosts(self):
''' Get all the hosts that the exclusivity group instances are located on '''
servers_list = self.nova_client.list_servers()
exclusivity_hosts = []
for serv in servers_list["servers"]:
if "exclusivity" in serv["name"]:
server = self.nova_client.show_server(serv["id"])
exclusivity_hosts.append(server["server"]["OS-EXT-SRV-ATTR:host"])
return set(exclusivity_hosts)
def get_group_instances(self, resources, group_ins):
"""Get the instance object according to the group_ins.
@ -226,8 +247,8 @@ class Analyzer(object):
racks.append(self.get_rack(host))
instances = []
for x in self.instance_on_server:
if self.get_rack(self.instance_on_server[x]) in racks:
for x in self.host_instance_dict:
if self.get_rack(self.host_instance_dict[x]) in racks:
instances.append(x)
return instances
@ -241,12 +262,10 @@ class Analyzer(object):
def compare_rack(self, current_host, first_host):
"""Compare racks for hosts, return true if racks equal."""
self.log.log_debug(current_host)
return self.get_rack(current_host) == self.get_rack(first_host)
def compare_host(self, current_host, first_host):
"""Compare current to first host, return True if equal."""
self.log.log_debug(current_host)
return current_host == first_host
def get_rack(self, host):

View File

@ -100,7 +100,7 @@ class ScenarioTestCase(test.BaseTestCase):
for key in groups:
if groups[key].group_type == "exclusivity":
self.log.log_info(" creating group ")
self.log.log_info(" creating valet group ")
grp_name = data_utils.rand_name(name=groups[key].group_name)
template_resources.template_data = \
template_resources.template_data.replace(
@ -119,7 +119,7 @@ class ScenarioTestCase(test.BaseTestCase):
return res
except Exception:
self.log.log_error("Failed to create stack", traceback.format_exc())
self.log.log_error("Failed to prepare stack for creation", traceback.format_exc())
return False
return True
@ -142,6 +142,7 @@ class ScenarioTestCase(test.BaseTestCase):
def get_env_file(self, template):
try:
env_url = template.replace(".yml", ".env")
self.log.log_debug("loading environment file (%s)" % env_url)
if os.path.exists(env_url):
with open(env_url, "r") as f: