2019-10-25 11:42:40 +05:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								# TODO
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#  1. send an email to an email address defined by env['admin-email']
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#     if resources are finished
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#  2. Introduce a status endpoint of the scheduler -
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#     maybe expose a prometheus compatible output
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2020-01-03 18:38:59 +05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								import argparse
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2019-12-31 11:30:02 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								from uncloud.common.request import RequestEntry, RequestType
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								from uncloud.shared import shared
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								from uncloud.settings import settings
							 | 
						
					
						
							
								
									
										
										
										
											2020-01-03 18:38:59 +05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								from .helper import (dead_host_mitigation, dead_host_detection, assign_host, NoSuitableHostFound)
							 | 
						
					
						
							
								
									
										
										
										
											2019-12-03 16:49:10 +05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								from . import logger
							 | 
						
					
						
							
								
									
										
										
										
											2019-10-25 11:42:40 +05:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2020-01-03 18:38:59 +05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								arg_parser = argparse.ArgumentParser('scheduler', add_help=False)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2019-10-25 11:42:40 +05:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2019-12-31 14:22:44 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								def main(debug=False):
							 | 
						
					
						
							
								
									
										
										
										
											2019-10-25 11:42:40 +05:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    for request_iterator in [
							 | 
						
					
						
							
								
									
										
										
										
											2019-12-30 14:35:07 +05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        shared.etcd_client.get_prefix(
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            settings["etcd"]["request_prefix"], value_in_json=True
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        ),
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        shared.etcd_client.watch_prefix(
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            settings["etcd"]["request_prefix"],
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            timeout=5,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            value_in_json=True,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        ),
							 | 
						
					
						
							
								
									
										
										
										
											2019-10-25 11:42:40 +05:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    ]:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        for request_event in request_iterator:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            request_entry = RequestEntry(request_event)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            # Never Run time critical mechanism inside timeout
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            # mechanism because timeout mechanism only comes
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            # when no other event is happening. It means under
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            # heavy load there would not be a timeout event.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            if request_entry.type == "TIMEOUT":
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                # Detect hosts that are dead and set their status
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                # to "DEAD", and their VMs' status to "KILLED"
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                dead_hosts = dead_host_detection()
							 | 
						
					
						
							
								
									
										
										
										
											2019-11-25 11:52:36 +05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                if dead_hosts:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    logger.debug("Dead hosts: %s", dead_hosts)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    dead_host_mitigation(dead_hosts)
							 | 
						
					
						
							
								
									
										
										
										
											2019-10-25 11:42:40 +05:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            elif request_entry.type == RequestType.ScheduleVM:
							 | 
						
					
						
							
								
									
										
										
										
											2020-01-01 14:59:47 +05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                logger.debug("%s, %s", request_entry.key, request_entry.value)
							 | 
						
					
						
							
								
									
										
										
										
											2019-11-25 11:52:36 +05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2019-12-22 12:26:48 +05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                vm_entry = shared.vm_pool.get(request_entry.uuid)
							 | 
						
					
						
							
								
									
										
										
										
											2019-11-11 23:42:57 +05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                if vm_entry is None:
							 | 
						
					
						
							
								
									
										
										
										
											2020-01-01 14:59:47 +05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                    logger.info("Trying to act on {} but it is deleted".format(request_entry.uuid))
							 | 
						
					
						
							
								
									
										
										
										
											2019-11-11 23:42:57 +05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                    continue
							 | 
						
					
						
							
								
									
										
										
										
											2020-01-01 14:59:47 +05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                shared.etcd_client.client.delete(request_entry.key)  # consume Request
							 | 
						
					
						
							
								
									
										
										
										
											2019-10-25 11:42:40 +05:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2019-12-28 15:39:11 +05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                try:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    assign_host(vm_entry)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                except NoSuitableHostFound:
							 | 
						
					
						
							
								
									
										
										
										
											2020-01-01 14:59:47 +05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                    vm_entry.add_log("Can't schedule VM. No Resource Left.")
							 | 
						
					
						
							
								
									
										
										
										
											2019-12-28 15:39:11 +05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                    shared.vm_pool.put(vm_entry)
							 | 
						
					
						
							
								
									
										
										
										
											2019-10-25 11:42:40 +05:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2019-12-28 15:39:11 +05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                    logger.info("No Resource Left. Emailing admin....")
							 | 
						
					
						
							
								
									
										
										
										
											2019-10-25 11:42:40 +05:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2019-11-02 20:42:24 +05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								if __name__ == "__main__":
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    main()
							 |