def _get_all_available_hosts(context): hosts_api = hosts.API() hosts = novaclient(context).hosts.index() hosts_states = hosts_api.get_all_hosts_load_states_sorted_list(context) hosts_temp = list() for uuid, host_load_state in hosts_states: if host_load_state == 'normalload': hosts_temp.add(uuid) for i in hosts_temp: if i not in hosts['id']: del hosts_temp[i] available_hosts = hosts_temp return available_hosts
def dynamic_resource_scheduling(self, context): controller_topic = CONF.controller_topic data_collection_topic = CONF.data_collection_topic load_detection_topic = CONF.load_detection_topic vms_selection_topic = CONF.vms_selection_topic vms_migration_topic = CONF.vms_migration_topic """ 所有主机uuid信息; """ hosts = dict() hosts_uuid = dict() try: hosts_init_data = self.hosts_api.get_all_hosts_init_data(context) except exception.HostInitDataNotFound: msg = _('host init data not found') raise webob.exc.HTTPBadRequest(explanation=msg) for host_init_data in hosts_init_data: host_uuid = host_init_data['host_id'] host_name = host_init_data['host_name'] hosts_uuid.add(host_uuid) hosts[host_uuid] = host_name """ 所有主机本地数据采集; """ try: self.data_collection_rpcapi.hosts_vms_data_collection(context, data_collection_topic) except exception.DataCollectionError: msg = _('There are some error in hosts and vms data collection operation.') raise webob.exc.HTTPBadRequest(explanation=msg) time.sleep(CONF.wait_time) """ 所有主机本地负载检测; """ try: self.load_detection_rpcapi.hosts_load_detection(context, load_detection_topic) except exception.LoadDetectionError: msg = _('There are some error in hosts load detection operation.') raise webob.exc.HTTPBadRequest(explanation=msg) time.sleep(CONF.wait_time) """ 针对负载状态为过载的主机,选取其上合适数量的虚拟机实例,以便进行虚拟机的迁移操作; """ vms_mrigation_selection = dict() underload_hosts_uuid = list() for host_uuid in hosts_uuid: try: host_load_states = self.hosts_api.get_host_load_states_by_id(context, host_uuid) except exception.NotFound: raise exc.HTTPNotFound() host_load_state = host_load_states['host_load_state'] if host_load_state == 'underload': underload_hosts_uuid.add(host_uuid) if host_load_state == 'overload': try: vm_mrigation_list = self.vms_selection_rpcapi.vms_selection(context, host_uuid, vms_selection_topic) except exception.VmsSelectionError: msg = _('There are some error in vms selection operation.') raise webob.exc.HTTPBadRequest(explanation=msg) vms_mrigation_selection[host_uuid] = vm_mrigation_list time.sleep(CONF.wait_time) """ 针对过载主机的要迁移的虚拟机实例进行迁移目标主机的分配; 选取虚拟机----主机映射算法; """ host_scheduler_algorithm = self.hosts_api.get_vm_select_algorithm_in_used(context) host_scheduler_algorithm_name = host_scheduler_algorithm['algorithm_name'] host_scheduler_algorithm_fuction = CONF.host_scheduler_algorithm_path + '.' + host_scheduler_algorithm_name vms_hosts_mapper = dict() """ 针对可用的目标主机列表,复制其HostCpuData中的cpu_data数据到临时数据表HostCpuDataTemp中, 以便在为所有需要迁移的虚拟机实例选取目标主机的算法中应用; 因为要进行虚拟机的预迁移操作,会若干次改变不同目标主机的cpu_data,为了不改变HostCpuData中 的数据,所以这里要对其复制生成临时的数据表HostCpuDataTemp。 HostCPUDataTemp这里包括主机内存的使用信息,数据表名称有待商榷; """ for host_uuid, vm_mrigation_list in vms_mrigation_selection: try: cpu_data = self.hosts_api.get_host_cpu_data_by_id(context, host_uuid) except exception.HostCpuDataNotFound: msg = _('host cpu data not found') raise webob.exc.HTTPBadRequest(explanation=msg) try: host_meminfo = self.hosts_api.get_meminfo_by_id(context, host_uuid) except exception.HostMemroyInfoNotFound: msg = _('host memroy info not found') raise webob.exc.HTTPBadRequest(explanation=msg) update_values = (cpu_data, host_meminfo) try: hosts_cpu_data_temp = self.hosts_api.create_host_cpu_data_temp_by_id(context, update_values, host_uuid) except exception.HostCpuDataNotFound: msg = _('host cpu data not found') raise webob.exc.HTTPBadRequest(explanation=msg) for host_uuid, vm_mrigation_list in vms_mrigation_selection: available_hosts = self._get_all_available_hosts(context) filter_scheduler_algorithms_fuctions = self._get_filter_scheduler_algorithms_in_use(context) available_filter_hosts = self._get_filter_hosts(available_hosts, filter_scheduler_algorithms_fuctions) """ @@@@注:及时更新HostLoadState中的信息; """ vm_host_mapper, vms_hosts_mapper_fales = host_scheduler_algorithm_fuction( vm_mrigation_list, host_uuid, available_filter_hosts) """ vms_hosts_mapper = {host_uuid1:{vm1:host1,vm2:host2,......}, host_uuid2:{vm3:host1,vm4:host2,......}, ......} """ vms_hosts_mapper[host_uuid] = vm_host_mapper """ 实现相关虚拟机到目标主机的迁移操作; 注:如果判断虚拟机迁移是否成功,估计要对nova和novaclient中的相关源码进行改进; """ for host_uuid, vm_host_mapper in vms_hosts_mapper: for vm_uuid, host_uuid in vm_host_mapper: novaclient(context).servers.live_migrate(vm_uuid, host_uuid, False, False) """ 检测欠载的主机是否仍为欠载状态,将仍为欠载状态的主机上的所有虚拟机实例迁移出去,并设置 主机为低功耗状态; """ vms_underload_hosts_mapper = dict() for host_uuid in underload_hosts_uuid: try: host_load_states = self.hosts_api.get_host_load_states_by_id(context, host_uuid) except exception.NotFound: raise exc.HTTPNotFound() host_load_state = host_load_states['host_load_state'] if host_load_state == 'underload': available_hosts = self._get_all_available_hosts(context) filter_scheduler_algorithms_fuctions = self._get_filter_scheduler_algorithms_in_use(context) available_filter_hosts = self._get_filter_hosts(available_hosts, filter_scheduler_algorithms_fuctions) """ 远程获取指定主机上所有的虚拟机实例; """ vir_connection = libvirt.openReadOnly(host_uuid) vms_current = self._get_current_vms(vir_connection) vm_host_mapper = host_scheduler_algorithm_fuction(vms_current, available_filter_hosts) vms_underload_hosts_mapper[host_uuid] = vm_host_mapper """ 实现相关虚拟机到目标主机的迁移操作; 注:如果判断虚拟机迁移是否成功,估计要对nova和novaclient中的相关源码进行改进; """ for uuid, vm_host_mapper in vms_underload_hosts_mapper: for vm_uuid, host_uuid in vm_host_mapper: novaclient(context).servers.live_migrate(vm_uuid, host_uuid, False, False) """ 实现欠载主机的虚拟机迁移操作之后,设置其运行状态为低功耗模式; """ sleep_command = CONF.sleep_command for uuid, vm_host_mapper in vms_underload_hosts_mapper: try: self.controller_rpcapi.switch_host_off(context, sleep_command, uuid, controller_topic) except exception.DataCollectionError: msg = _('There are some error in hosts and vms data collection operation.') raise webob.exc.HTTPBadRequest(explanation=msg) time.sleep(CONF.wait_time)
def vm_to_host_migrate(self, context, vm, orig_host, dest_host): return novaclient(context).servers.live_migrate(vm, dest_host, False, False)