diff --git a/tools/utils/cleandb.sh b/tools/utils/cleandb.sh index ca7cf5a..2a14414 100644 --- a/tools/utils/cleandb.sh +++ b/tools/utils/cleandb.sh @@ -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 diff --git a/valet/api/common/__init__.py b/valet/api/common/__init__.py index ead1a25..3bdd265 100644 --- a/valet/api/common/__init__.py +++ b/valet/api/common/__init__.py @@ -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') diff --git a/valet/api/db/models/music/__init__.py b/valet/api/db/models/music/__init__.py index b6e481b..afe3239 100644 --- a/valet/api/db/models/music/__init__.py +++ b/valet/api/db/models/music/__init__.py @@ -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): diff --git a/valet/api/v1/controllers/errors.py b/valet/api/v1/controllers/errors.py index 47211b0..60a0fd2 100644 --- a/valet/api/v1/controllers/errors.py +++ b/valet/api/v1/controllers/errors.py @@ -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') diff --git a/valet/cli/groupcli.py b/valet/cli/groupcli.py index 3bcf6d6..2b7a0ed 100644 --- a/valet/cli/groupcli.py +++ b/valet/cli/groupcli.py @@ -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): diff --git a/valet/engine/conf.py b/valet/engine/conf.py index a44b932..1297e0e 100644 --- a/valet/engine/conf.py +++ b/valet/engine/conf.py @@ -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', diff --git a/valet/engine/optimizer/app_manager/app_topology_parser.py b/valet/engine/optimizer/app_manager/app_topology_parser.py index 56ff359..1b8e7f1 100755 --- a/valet/engine/optimizer/app_manager/app_topology_parser.py +++ b/valet/engine/optimizer/app_manager/app_topology_parser.py @@ -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"] diff --git a/valet/engine/optimizer/db_connect/music_handler.py b/valet/engine/optimizer/db_connect/music_handler.py index eedfecf..5add75a 100644 --- a/valet/engine/optimizer/db_connect/music_handler.py +++ b/valet/engine/optimizer/db_connect/music_handler.py @@ -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): diff --git a/valet/engine/optimizer/ostro/ostro.py b/valet/engine/optimizer/ostro/ostro.py index 6ee4f96..39e4520 100755 --- a/valet/engine/optimizer/ostro/ostro.py +++ b/valet/engine/optimizer/ostro/ostro.py @@ -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) diff --git a/valet/engine/resource_manager/compute_manager.py b/valet/engine/resource_manager/compute_manager.py index dee45f7..9406d23 100755 --- a/valet/engine/resource_manager/compute_manager.py +++ b/valet/engine/resource_manager/compute_manager.py @@ -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 diff --git a/valet/engine/resource_manager/resource.py b/valet/engine/resource_manager/resource.py index af41456..5230cfa 100755 --- a/valet/engine/resource_manager/resource.py +++ b/valet/engine/resource_manager/resource.py @@ -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 diff --git a/valet/ha/ha_valet.cfg b/valet/ha/ha_valet.cfg index 7aaa39d..84afa6c 100644 --- a/valet/ha/ha_valet.cfg +++ b/valet/ha/ha_valet.cfg @@ -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)" diff --git a/valet/ha/ha_valet.py b/valet/ha/ha_valet.py index 954d9e4..dceff65 100644 --- a/valet/ha/ha_valet.py +++ b/valet/ha/ha_valet.py @@ -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. diff --git a/valet/ha/ha_valet2.cfg b/valet/ha/ha_valet2.cfg index 2fd6154..d5c6e30 100644 --- a/valet/ha/ha_valet2.cfg +++ b/valet/ha/ha_valet2.cfg @@ -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)" diff --git a/valet/tests/tempest/scenario/analyzer.py b/valet/tests/tempest/scenario/analyzer.py index d41bd3b..0ad3dc9 100644 --- a/valet/tests/tempest/scenario/analyzer.py +++ b/valet/tests/tempest/scenario/analyzer.py @@ -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): diff --git a/valet/tests/tempest/scenario/scenario_base.py b/valet/tests/tempest/scenario/scenario_base.py index 178777e..78301a3 100644 --- a/valet/tests/tempest/scenario/scenario_base.py +++ b/valet/tests/tempest/scenario/scenario_base.py @@ -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: