| OLD | NEW |
| 1 import os, re, shutil, signal, subprocess, errno, time, heapq, traceback | 1 import os, re, shutil, signal, subprocess, errno, time, heapq, traceback |
| 2 import common, logging | 2 import common, logging |
| 3 from autotest_lib.client.common_lib import error, global_config | 3 from autotest_lib.client.common_lib import error, global_config |
| 4 from autotest_lib.scheduler import email_manager, drone_utility, drones | 4 from autotest_lib.scheduler import email_manager, drone_utility, drones |
| 5 from autotest_lib.scheduler import scheduler_config | 5 from autotest_lib.scheduler import scheduler_config |
| 6 | 6 |
| 7 | 7 |
| 8 # results on drones will be placed under the drone_installation_directory in a | 8 # results on drones will be placed under the drone_installation_directory in a |
| 9 # directory with this name | 9 # directory with this name |
| 10 _DRONE_RESULTS_DIR_SUFFIX = 'results' | 10 _DRONE_RESULTS_DIR_SUFFIX = 'results' |
| (...skipping 434 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 445 def _choose_drone_for_execution(self, num_processes, username, | 445 def _choose_drone_for_execution(self, num_processes, username, |
| 446 drone_hostnames_allowed): | 446 drone_hostnames_allowed): |
| 447 # cycle through drones is order of increasing used capacity until | 447 # cycle through drones is order of increasing used capacity until |
| 448 # we find one that can handle these processes | 448 # we find one that can handle these processes |
| 449 checked_drones = [] | 449 checked_drones = [] |
| 450 usable_drones = [] | 450 usable_drones = [] |
| 451 drone_to_use = None | 451 drone_to_use = None |
| 452 while self._drone_queue: | 452 while self._drone_queue: |
| 453 drone = heapq.heappop(self._drone_queue).drone | 453 drone = heapq.heappop(self._drone_queue).drone |
| 454 checked_drones.append(drone) | 454 checked_drones.append(drone) |
| 455 logging.info('Checking drone %s', drone.hostname) |
| 455 if not drone.usable_by(username): | 456 if not drone.usable_by(username): |
| 456 continue | 457 continue |
| 457 | 458 |
| 458 drone_allowed = (drone_hostnames_allowed is None | 459 drone_allowed = (drone_hostnames_allowed is None |
| 459 or drone.hostname in drone_hostnames_allowed) | 460 or drone.hostname in drone_hostnames_allowed) |
| 460 if not drone_allowed: | 461 if not drone_allowed: |
| 462 logging.debug('Drone %s not allowed: ', drone.hostname) |
| 461 continue | 463 continue |
| 462 | 464 |
| 463 usable_drones.append(drone) | 465 usable_drones.append(drone) |
| 464 | 466 |
| 465 if drone.active_processes + num_processes <= drone.max_processes: | 467 if drone.active_processes + num_processes <= drone.max_processes: |
| 466 drone_to_use = drone | 468 drone_to_use = drone |
| 467 break | 469 break |
| 470 logging.info('Drone %s has %d active + %s requested > %s max', |
| 471 drone.hostname, drone.active_processes, num_processes, |
| 472 drone.max_processes) |
| 468 | 473 |
| 469 if not drone_to_use and usable_drones: | 474 if not drone_to_use and usable_drones: |
| 470 drone_summary = ','.join('%s %s/%s' % (drone.hostname, | 475 drone_summary = ','.join('%s %s/%s' % (drone.hostname, |
| 471 drone.active_processes, | 476 drone.active_processes, |
| 472 drone.max_processes) | 477 drone.max_processes) |
| 473 for drone in usable_drones) | 478 for drone in usable_drones) |
| 474 logging.error('No drone has capacity to handle %d processes (%s) ' | 479 logging.error('No drone has capacity to handle %d processes (%s) ' |
| 475 'for user %s', num_processes, drone_summary, username) | 480 'for user %s', num_processes, drone_summary, username) |
| 476 drone_to_use = self._least_loaded_drone(usable_drones) | 481 drone_to_use = self._least_loaded_drone(usable_drones) |
| 477 | 482 |
| (...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 695 | 700 |
| 696 def instance(): | 701 def instance(): |
| 697 if _the_instance is None: | 702 if _the_instance is None: |
| 698 _set_instance(DroneManager()) | 703 _set_instance(DroneManager()) |
| 699 return _the_instance | 704 return _the_instance |
| 700 | 705 |
| 701 | 706 |
| 702 def _set_instance(instance): # usable for testing | 707 def _set_instance(instance): # usable for testing |
| 703 global _the_instance | 708 global _the_instance |
| 704 _the_instance = instance | 709 _the_instance = instance |
| OLD | NEW |