diff options
Diffstat (limited to 'automation/server/machine_manager.py')
-rw-r--r-- | automation/server/machine_manager.py | 77 |
1 files changed, 77 insertions, 0 deletions
diff --git a/automation/server/machine_manager.py b/automation/server/machine_manager.py new file mode 100644 index 00000000..b7186077 --- /dev/null +++ b/automation/server/machine_manager.py @@ -0,0 +1,77 @@ +# Copyright 2010 Google Inc. All Rights Reserved. + +__author__ = 'asharif@google.com (Ahmad Sharif)' + +from operator import attrgetter +import copy +import csv +import threading +import os.path + +from automation.common import machine + +DEFAULT_MACHINES_FILE = os.path.join(os.path.dirname(__file__), 'test_pool.csv') + + +class MachineManager(object): + """Container for list of machines one can run jobs on.""" + + @classmethod + def FromMachineListFile(cls, filename): + # Read the file and skip header + csv_file = csv.reader(open(filename, 'rb'), delimiter=',', quotechar='"') + csv_file.next() + + return cls([machine.Machine(hostname, label, cpu, int(cores), os, user) + for hostname, label, cpu, cores, os, user in csv_file]) + + def __init__(self, machines): + self._machine_pool = machines + self._lock = threading.RLock() + + def _GetMachine(self, mach_spec): + available_pool = [m for m in self._machine_pool if mach_spec.IsMatch(m)] + + if available_pool: + # find a machine with minimum uses + uses = attrgetter('uses') + + mach = min(available_pool, key=uses) + + if mach_spec.preferred_machines: + preferred_pool = [m + for m in available_pool + if m.hostname in mach_spec.preferred_machines] + if preferred_pool: + mach = min(preferred_pool, key=uses) + + mach.Acquire(mach_spec.lock_required) + + return mach + + def GetMachines(self, required_machines): + """Acquire machines for use by a job.""" + + with self._lock: + acquired_machines = [self._GetMachine(ms) for ms in required_machines] + + if not all(acquired_machines): + # Roll back acquires + while acquired_machines: + mach = acquired_machines.pop() + if mach: + mach.Release() + + return acquired_machines + + def GetMachineList(self): + with self._lock: + return copy.deepcopy(self._machine_pool) + + def ReturnMachines(self, machines): + with self._lock: + for m in machines: + m.Release() + + def __str__(self): + return str(self._machine_pool) |