# -*- encoding: utf-8 -*- # # Copyright (c) 2013-2015 Wind River Systems, Inc. # # SPDX-License-Identifier: Apache-2.0 # from cgtsclient.common import base from cgtsclient import exc from cgtsclient.openstack.common.gettextutils import _ CREATION_ATTRIBUTES = ['ihost_uuid', 'inode_uuid', 'cpu', 'core', 'thread', 'cpu_family', 'cpu_model', 'allocated_function', 'numa_node', 'capabilities', 'function', 'num_cores_on_processor0', 'num_cores_on_processor1', 'num_cores_on_processor2', 'num_cores_on_processor3'] PLATFORM_CPU_TYPE = "Platform" VSWITCH_CPU_TYPE = "Vswitch" SHARED_CPU_TYPE = "Shared" APPLICATION_CPU_TYPE = "Applications" NONE_CPU_TYPE = "None" CPU_TYPE_LIST = [PLATFORM_CPU_TYPE, VSWITCH_CPU_TYPE, SHARED_CPU_TYPE, APPLICATION_CPU_TYPE, NONE_CPU_TYPE] PLATFORM_CPU_TYPE_FORMAT = _("Platform") VSWITCH_CPU_TYPE_FORMAT = _("vSwitch") SHARED_CPU_TYPE_FORMAT = _("Shared") APPLICATION_CPU_TYPE_FORMAT = _("Applications") NONE_CPU_TYPE_FORMAT = _("None") CPU_TYPE_FORMATS = {PLATFORM_CPU_TYPE: PLATFORM_CPU_TYPE_FORMAT, VSWITCH_CPU_TYPE: VSWITCH_CPU_TYPE_FORMAT, SHARED_CPU_TYPE: SHARED_CPU_TYPE_FORMAT, APPLICATION_CPU_TYPE: APPLICATION_CPU_TYPE_FORMAT, NONE_CPU_TYPE: NONE_CPU_TYPE_FORMAT} def _cpu_function_formatter(allocated_function): if allocated_function in CPU_TYPE_FORMATS: return CPU_TYPE_FORMATS[allocated_function] return "unknown({})".format(allocated_function) def _cpu_function_tuple_formatter(data): return _cpu_function_formatter(data.allocated_function) class icpu(base.Resource): def __repr__(self): return "" % self._info class icpuManager(base.Manager): resource_class = icpu def list(self, ihost_id): path = '/v1/ihosts/%s/icpus' % ihost_id return self._list(path, "icpus") def get(self, icpu_id): path = '/v1/icpus/%s' % icpu_id try: return self._list(path)[0] except IndexError: return None def create(self, **kwargs): path = '/v1/icpus/' new = {} for (key, value) in kwargs.items(): if key in CREATION_ATTRIBUTES: new[key] = value else: raise exc.InvalidAttribute(key) return self._create(path, new) def delete(self, icpu_id): path = '/v1/icpus/%s' % icpu_id return self._delete(path) def update(self, icpu_id, patch): path = '/v1/icpus/%s' % icpu_id return self._update(path, patch) class CpuFunction (): def __init__(self, function): self.allocated_function = function self.socket_cores = {} self.socket_cores_number = {} def check_core_functions(personality, icpus): platform_cores = 0 vswitch_cores = 0 vm_cores = 0 for cpu in icpus: allocated_function = cpu.allocated_function if allocated_function == PLATFORM_CPU_TYPE: platform_cores += 1 elif allocated_function == VSWITCH_CPU_TYPE: vswitch_cores += 1 elif allocated_function == APPLICATION_CPU_TYPE: vm_cores += 1 error_string = "" if platform_cores == 0: error_string = ("There must be at least one core for %s." % PLATFORM_CPU_TYPE_FORMAT) elif personality == 'worker' and vswitch_cores == 0: error_string = ("There must be at least one core for %s." % VSWITCH_CPU_TYPE_FORMAT) elif personality == 'worker' and vm_cores == 0: error_string = ("There must be at least one core for %s." % APPLICATION_CPU_TYPE_FORMAT) return error_string def compress_range(c_list): c_list.append(999) c_list.sort() c_sep = "" c_item = "" c_str = "" pn = 0 # pn is not used until second loop anyways for n in c_list: if not c_item: c_item = "%s" % n else: if n > (pn + 1): if int(pn) == int(c_item): c_str = "%s%s%s" % (c_str, c_sep, c_item) else: c_str = "%s%s%s-%s" % (c_str, c_sep, c_item, pn) c_sep = "," c_item = "%s" % n pn = n return c_str def restructure_host_cpu_data(host): host.core_assignment = [] if host.cpus: host.cpu_model = host.cpus[0].cpu_model host.sockets = len(host.nodes) host.hyperthreading = "No" host.physical_cores = 0 core_assignment = {} number_of_cores = {} host.node_min_max_cores = {} for cpu in host.cpus: if cpu.numa_node == 0 and cpu.thread == 0: host.physical_cores += 1 elif cpu.thread > 0: host.hyperthreading = "Yes" if cpu.numa_node not in host.node_min_max_cores: host.node_min_max_cores[cpu.numa_node] = {'min': 99999, 'max': 0} if cpu.cpu < host.node_min_max_cores[cpu.numa_node]['min']: host.node_min_max_cores[cpu.numa_node]['min'] = cpu.cpu if cpu.cpu > host.node_min_max_cores[cpu.numa_node]['max']: host.node_min_max_cores[cpu.numa_node]['max'] = cpu.cpu if cpu.allocated_function is None: cpu.allocated_function = NONE_CPU_TYPE if cpu.allocated_function not in core_assignment: core_assignment[cpu.allocated_function] = {} number_of_cores[cpu.allocated_function] = {} if cpu.numa_node not in core_assignment[cpu.allocated_function]: core_assignment[cpu.allocated_function][cpu.numa_node] = [int(cpu.cpu)] number_of_cores[cpu.allocated_function][cpu.numa_node] = 1 else: core_assignment[cpu.allocated_function][cpu.numa_node].append(int(cpu.cpu)) number_of_cores[cpu.allocated_function][cpu.numa_node] = number_of_cores[cpu.allocated_function][cpu.numa_node] + 1 for f in CPU_TYPE_LIST: cpufunction = CpuFunction(f) if f in core_assignment: host.core_assignment.append(cpufunction) for s, cores in core_assignment[f].items(): cpufunction.socket_cores[s] = compress_range(cores) cpufunction.socket_cores_number[s] = number_of_cores[f][s] else: if (f == PLATFORM_CPU_TYPE or (hasattr(host, 'subfunctions') and 'worker' in host.subfunctions)): if f != NONE_CPU_TYPE: host.core_assignment.append(cpufunction) for s in range(0, len(host.nodes)): cpufunction.socket_cores[s] = "" cpufunction.socket_cores_number[s] = 0