def test_extra_specs_update(self): expected_specs = {"k1": "v1"} updated_specs = {"k1": "v2"} self._test_extra_specs_empty() self.set_key(self.instance_type_name, "k1", "v1") actual_specs = db.instance_type_extra_specs_get(context.get_admin_context(), self.instance_type_flavorid) self.assertEquals(expected_specs, actual_specs) self.set_key(self.instance_type_name, "k1", "v2") actual_specs = db.instance_type_extra_specs_get(context.get_admin_context(), self.instance_type_flavorid) self.assertEquals(updated_specs, actual_specs) self.unset_key(self.instance_type_name, "k1")
def test_extra_specs_update(self): expected_specs = {'k1': 'v1'} updated_specs = {'k1': 'v2'} self._test_extra_specs_empty() self.set_key(self.instance_type_name, "k1", "v1") actual_specs = db.instance_type_extra_specs_get( context.get_admin_context(), self.instance_type_flavorid) self.assertEquals(expected_specs, actual_specs) self.set_key(self.instance_type_name, "k1", "v2") actual_specs = db.instance_type_extra_specs_get( context.get_admin_context(), self.instance_type_flavorid) self.assertEquals(updated_specs, actual_specs) self.unset_key(self.instance_type_name, "k1")
def test_instance_type_specs_get(self): expected_specs = dict(cpu_arch="x86_64", cpu_model="Nehalem", xpu_arch="fermi", xpus="2", xpu_model="Tesla 2050") actual_specs = db.instance_type_extra_specs_get( self.context, self.flavorid) self.assertEquals(expected_specs, actual_specs)
def test_instance_type_extra_specs_delete(self): expected_specs = dict(cpu_arch="x86_64", cpu_model="Nehalem", xpu_arch="fermi", xpus="2") db.instance_type_extra_specs_delete(self.context, self.instance_type_id, "xpu_model") actual_specs = db.instance_type_extra_specs_get( self.context, self.instance_type_id) self.assertEquals(expected_specs, actual_specs)
def test_instance_type_extra_specs_update(self): expected_specs = dict(cpu_arch="x86_64", cpu_model="Sandy Bridge", xpu_arch="fermi", xpus="2", xpu_model="Tesla 2050") db.instance_type_extra_specs_update_or_create( self.context, self.flavorid, dict(cpu_model="Sandy Bridge")) actual_specs = db.instance_type_extra_specs_get( self.context, self.flavorid) self.assertEquals(expected_specs, actual_specs)
def test_extra_specs_multiple(self): two_items_extra_specs = {"k1": "v1", "k3": "v3"} self._test_extra_specs_empty() self.set_key(self.instance_type_name, "k1", "v1") self.set_key(self.instance_type_name, "k3", "v3") actual_specs = db.instance_type_extra_specs_get(context.get_admin_context(), self.instance_type_flavorid) self.assertEquals(two_items_extra_specs, actual_specs) self.unset_key(self.instance_type_name, "k1") self.unset_key(self.instance_type_name, "k3")
def test_extra_specs_set_unset(self): expected_specs = {'k1': 'v1'} self._test_extra_specs_empty() self.set_key(self.instance_type_name, "k1", "v1") actual_specs = db.instance_type_extra_specs_get( context.get_admin_context(), self.instance_type_id) self.assertEquals(expected_specs, actual_specs) self.unset_key(self.instance_type_name, "k1") self._test_extra_specs_empty()
def test_extra_specs_multiple(self): two_items_extra_specs = {'k1': 'v1', 'k3': 'v3'} self._test_extra_specs_empty() self.set_key(self.instance_type_name, "k1", "v1") self.set_key(self.instance_type_name, "k3", "v3") actual_specs = db.instance_type_extra_specs_get( context.get_admin_context(), self.instance_type_flavorid) self.assertEquals(two_items_extra_specs, actual_specs) self.unset_key(self.instance_type_name, "k1") self.unset_key(self.instance_type_name, "k3")
def test_instance_type_extra_specs_create(self): expected_specs = dict(cpu_arch="x86_64", cpu_model="Nehalem", xpu_arch="fermi", xpus="2", xpu_model="Tesla 2050", net_arch="ethernet", net_mbps="10000") db.instance_type_extra_specs_update_or_create( self.context, self.flavorid, dict(net_arch="ethernet", net_mbps=10000)) actual_specs = db.instance_type_extra_specs_get( self.context, self.flavorid) self.assertEquals(expected_specs, actual_specs)
def build_request_spec(ctxt, image, instances): """Build a request_spec for the scheduler. The request_spec assumes that all instances to be scheduled are the same type. """ instance = instances[0] instance_type = flavors.extract_flavor(instance) # NOTE(comstud): This is a bit ugly, but will get cleaned up when # we're passing an InstanceType internal object. extra_specs = db.instance_type_extra_specs_get(ctxt, instance_type['flavorid']) instance_type['extra_specs'] = extra_specs request_spec = { 'image': image, 'instance_properties': instance, 'instance_type': instance_type, 'instance_uuids': [inst['uuid'] for inst in instances]} return jsonutils.to_primitive(request_spec)
def build_request_spec(ctxt, image, instances): """Build a request_spec for the scheduler. The request_spec assumes that all instances to be scheduled are the same type. """ instance = instances[0] instance_type = flavors.extract_flavor(instance) # NOTE(comstud): This is a bit ugly, but will get cleaned up when # we're passing an InstanceType internal object. extra_specs = db.instance_type_extra_specs_get(ctxt, instance_type['flavorid']) instance_type['extra_specs'] = extra_specs request_spec = { 'image': image, 'instance_properties': instance, 'instance_type': instance_type, 'num_instances': len(instances), # NOTE(alaski): This should be removed as logic moves from the # scheduler to conductor. Provides backwards compatibility now. 'instance_uuids': [inst['uuid'] for inst in instances]} return jsonutils.to_primitive(request_spec)
def build_request_spec(ctxt, image, instances): """Build a request_spec for the scheduler. The request_spec assumes that all instances to be scheduled are the same type. """ instance = instances[0] instance_type = flavors.extract_flavor(instance) # NOTE(comstud): This is a bit ugly, but will get cleaned up when # we're passing an InstanceType internal object. extra_specs = db.instance_type_extra_specs_get(ctxt, instance_type['flavorid']) instance_type['extra_specs'] = extra_specs request_spec = { 'image': image, 'instance_properties': instance, 'instance_type': instance_type, 'num_instances': len(instances), # NOTE(alaski): This should be removed as logic moves from the # scheduler to conductor. Provides backwards compatibility now. 'instance_uuids': [inst['uuid'] for inst in instances] } return jsonutils.to_primitive(request_spec)
def _get_extra_specs(self, context, flavor_id): extra_specs = db.instance_type_extra_specs_get(context, flavor_id) return dict(extra_specs=extra_specs)
def _test_extra_specs_empty(self): empty_specs = {} actual_specs = db.instance_type_extra_specs_get( context.get_admin_context(), self.instance_type_id) self.assertEquals(empty_specs, actual_specs)
def _get_extra_specs(self, context, flavor_id): extra_specs = db.instance_type_extra_specs_get(context, flavor_id) specs_dict = {} for key, value in extra_specs.iteritems(): specs_dict[key] = value return dict(extra_specs=specs_dict)
def hosts_up_with_arch(self, context, topic, request_spec): # def hosts_up_with_arch(self, context, topic, instance_id): """Figure out what is requested """ LOG.debug(_("## req: %s"), request_spec) instance_type = request_spec['instance_type'] LOG.debug(_("## it: %s"), instance_type) # instance = db.instance_get(context, instance_id) # LOG.debug(_("## instance %s"), instance) # LOG.debug(_("## instance.id %s"), instance.id) # LOG.debug(_("## instance.cpu_arch %s"), instance.cpu_arch) services = db.service_get_all_by_topic(context.elevated(), topic) LOG.debug(_("## services %s"), services) hosts = [] # from instance table wanted_vcpus = instance_type['vcpus'] wanted_memory_mb = instance_type['memory_mb'] wanted_root_gb = instance_type['root_gb'] instance_id = instance_type['id'] LOG.debug(_("## wanted-vcpus=%s"), wanted_vcpus) LOG.debug(_("## wanted-memory=%s"), wanted_memory_mb) LOG.debug(_("## wanted-hard=%s"), wanted_root_gb) LOG.debug(_("## instance_id=%s"), instance_id) # from instance_metadata table # instance_meta = db.instance_metadata_get(context, instance_id) # LOG.debug(_("## inst-meta=%s"), instance_meta) # from instance_type_extra_specs table # instance_extra = db.instance_type_extra_specs_get( \ instance_meta = db.instance_type_extra_specs_get( \ context, instance_id) LOG.debug(_("## inst-meta=%s"), instance_meta) # combine to inatance_meta # instance_meta.update(instance_extra) # LOG.debug(_("## new inst meta=%s"), instance_meta) try: wanted_cpu_arch = instance_meta['cpu_arch'] except: wanted_cpu_arch = None LOG.debug(_("## wanted-cpu-arch=%s"), wanted_cpu_arch) """Get capability from zone_manager and match cpu_arch and others """ cap = self.zone_manager.get_hosts_capabilities(context) for host, host_dict_cap in cap.iteritems(): LOG.debug(_("## host=%s"), host) for service_name_cap, service_dict_cap in \ host_dict_cap.iteritems(): if (service_name_cap != 'compute'): continue resource_cap = {} for cap, value in service_dict_cap.iteritems(): if type(value) is int: # value is int resource_cap[cap] = value elif (type(value) is not str) and \ (type(value) is not unicode): continue # string and one value elif value.find(':') == -1 and value.find(',') == -1: try: resource_cap[cap] = int(value) except: resource_cap[cap] = value # complex; multi-level key-value pairs. # example: cpu_info = { "vendor":"intel", features= # ["dia", "est"], toplogy={"core":4, "thread":1}} # only the lowest key-value pair is recorded. So, in the # previous eample, the final dict is: # resource["vendor"] = "intel", # resource["features"] = "dia, est", # resource["core"] = "4", # resource["thread"] = "1", # No key is availabel for cpu_info and topology else: # decompose capability new_key = '' new_val = '' splitted = value.split(',') for pair in splitted: if pair.find(':') != -1: # key:value pair if len(new_key) != 0: try: resource_cap[new_key] = int(new_val) except: resource_cap[new_key] = new_val nspl = pair.split(':') right = nspl[-2].rfind('"', 0, len(nspl[-2])) left = nspl[-2].rfind('"', 0, right) new_key = nspl[-2][left + 1:right] right = nspl[-1].rfind('"', 0, len(nspl[-1])) left = nspl[-1].rfind('"', 0, right) new_val = nspl[-1][left + 1:right] else: # value only right = pair.rfind('"', 0, len(pair)) left = pair.rfind('"', 0, right) if right != -1 and left != -1: new_val += "," + pair[left + 1:right] else: new_val += ", " + pair try: resource_cap[new_key] = int(new_val) except: resource_cap[new_key] = new_val # if the same architecture is found if ((wanted_cpu_arch is None) \ or (wanted_cpu_arch == resource_cap['cpu_arch'])): # basic requirements from instance_type LOG.debug(_("## *** wanted arch found: <%s> ***"), wanted_cpu_arch) LOG.debug(_("## cap vcpus = <%s>"), int(resource_cap['vcpus']) \ - int(resource_cap['vcpus_used'])) LOG.debug(_("## cap memory_mb = <%s>"), resource_cap['host_memory_free']) if wanted_vcpus > (int(resource_cap['vcpus']) \ - int(resource_cap['vcpus_used'])) \ or wanted_memory_mb > \ int(resource_cap['host_memory_free']) \ or wanted_root_gb > (int(resource_cap['disk_total']) \ - int(resource_cap['disk_used'])): flag_different = 1 else: flag_different = 0 # extra requirements from instance_type_extra_spec # or instance_metadata table for kkey in instance_meta: try: if (flag_different == 0): wanted_value = instance_meta[kkey] LOG.debug(_("## wanted-key=%s"), kkey) LOG.debug(_("## wanted-value=%s"), \ wanted_value) if (wanted_value is not None): flag_different = 1 if (resource_cap[kkey] is None): LOG.debug(_("## cap is None")) elif type(resource_cap[kkey]) is int: LOG.debug(_("## offered(int)=%s"), \ resource_cap[kkey]) if int(wanted_value) <= \ resource_cap[kkey]: LOG.debug(_("## found")) flag_different = 0 else: LOG.debug(_("**not found")) else: # get wanted list first wanted = wanted_value.split(',') # get provided list now if resource_cap[kkey].find(',') == -1: offered = [resource_cap[kkey]] else: offered = resource_cap[kkey]. \ split(',') LOG.debug(_("## offered(str)=%s"), \ offered) # check if the required are provided flag_different = 0 for want in wanted: found = 0 for item in offered: if (want == item): found = 1 break if found == 0: flag_different = 1 LOG.debug(_("**not found")) break else: LOG.debug(_("## found")) except: pass if (flag_different == 0): LOG.debug(_("##\t***** found **********=")) hosts.append(host) else: LOG.debug(_("##\t***** not found **********=")) LOG.debug(_("## hosts = %s"), hosts) return hosts