aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xafe_lock_machine.py43
-rw-r--r--crosperf/experiment.py9
-rw-r--r--crosperf/experiment_runner.py32
-rw-r--r--crosperf/machine_manager.py9
4 files changed, 74 insertions, 19 deletions
diff --git a/afe_lock_machine.py b/afe_lock_machine.py
index 29693cc7..5d6ae921 100755
--- a/afe_lock_machine.py
+++ b/afe_lock_machine.py
@@ -41,14 +41,6 @@ class LockingError(AFELockException):
"""Raised when server fails to lock/unlock machine as requested."""
-class DuplicateLock(AFELockException):
- """Raised when user attempts to lock an already locked machine."""
-
-
-class DuplicateUnlock(AFELockException):
- """Raised when user attempts to unlock an already unlocked machine."""
-
-
class DontOwnLock(AFELockException):
"""Raised when user attmepts to unlock machine locked by someone else."""
# This should not be raised if the user specified '--force'
@@ -378,7 +370,11 @@ class AFELockManager(object):
Args:
lock_machines: Boolean indicating whether to lock the machines (True) or
unlock the machines (False).
+
+ Returns:
+ A list of the machines whose state was successfully updated.
"""
+ updated_machines = []
for m in self.machines:
self.UpdateLockInAFE(lock_machines, m)
@@ -388,6 +384,25 @@ class AFELockManager(object):
self.logger.LogOutput('Locked machine(s) %s.' % m)
else:
self.logger.LogOutput('Unlocked machine(s) %s.' % m)
+ updated_machines.append(m)
+
+ return updated_machines
+
+ def _InternalRemoveMachine(self, machine):
+ """Remove machine from internal list of machines.
+
+ Args:
+ machine: Name of machine to be removed from internal list.
+ """
+ # Check to see if machine is lab machine and if so, make sure it has
+ # ".cros" on the end.
+ cros_machine = machine
+ if machine.find('rack') > 0 and machine.find('row') > 0:
+ if machine.find('.cros') == -1:
+ cros_machine = cros_machine + '.cros'
+
+ self.machines = [m for m in self.machines if m != cros_machine and
+ m != machine]
def CheckMachineLocks(self, machine_states, cmd):
"""Check that every machine in requested list is in the proper state.
@@ -402,22 +417,22 @@ class AFELockManager(object):
cmd: 'lock' or 'unlock'. The user-requested action for the machines.
Raises:
- DuplicateLock: A machine requested to be locked is already locked.
- DuplicateUnlock: A machine requested to be unlocked is already unlocked.
DontOwnLock: The lock on a requested machine is owned by someone else.
"""
for k, state in machine_states.iteritems():
if cmd == 'unlock':
if not state['locked']:
- raise DuplicateUnlock('Attempt to unlock already unlocked machine '
- '(%s).' % k)
+ self.logger.LogWarning('Attempt to unlock already unlocked machine '
+ '(%s).' % k)
+ self._InternalRemoveMachine(k)
- if state['locked_by'] != self.user:
+ if state['locked'] and state['locked_by'] != self.user:
raise DontOwnLock('Attempt to unlock machine (%s) locked by someone '
'else (%s).' % (k, state['locked_by']))
elif cmd == 'lock':
if state['locked']:
- raise DuplicateLock('Attempt to lock already locked machine (%s)' % k)
+ self.logger.LogWarning('Attempt to lock already locked machine (%s)' % k)
+ self._InternalRemoveMachine(k)
def HasAFEServer(self, local):
"""Verifies that the AFELockManager has appropriate AFE server.
diff --git a/crosperf/experiment.py b/crosperf/experiment.py
index 33b3f878..9f88ed01 100644
--- a/crosperf/experiment.py
+++ b/crosperf/experiment.py
@@ -50,6 +50,7 @@ class Experiment(object):
# locking mechanism; if it is blank then we will use the AFE server
# locking mechanism.
self.locks_dir = locks_directory
+ self.locked_machines = []
# We need one chromeos_root to run the benchmarks in, but it doesn't
# matter where it is, unless the ABIs are different.
@@ -146,9 +147,11 @@ class Experiment(object):
# to unlock everything.
self.machine_manager.Cleanup()
else:
- all_machines = self.remote
- for l in self.labels:
- all_machines += l.remote
+ all_machines = self.locked_machines
+ if not all_machines:
+ return
+
+ # If we locked any machines earlier, make sure we unlock them now.
lock_mgr = afe_lock_machine.AFELockManager(all_machines, "",
self.labels[0].chromeos_root,
None)
diff --git a/crosperf/experiment_runner.py b/crosperf/experiment_runner.py
index dae3c2e3..541bebe0 100644
--- a/crosperf/experiment_runner.py
+++ b/crosperf/experiment_runner.py
@@ -31,6 +31,7 @@ class ExperimentRunner(object):
self.l = log or logger.GetLogger(experiment.log_dir)
self._ce = cmd_exec or command_executer.GetCommandExecuter(self.l)
self._terminated = False
+ self.locked_machines = []
if experiment.log_level != "verbose":
self.STATUS_TIME_DELAY = 10
@@ -46,6 +47,25 @@ class ExperimentRunner(object):
machines += l.remote
return machines
+ def _UpdateMachineList(self, locked_machines):
+ """Update machines lists to contain only locked machines.
+
+ Go through all the lists of requested machines, both global and
+ label-specific requests, and remove any machine that we were not
+ able to lock.
+
+ Args:
+ locked_machines: A list of the machines we successfully locked.
+ """
+ for m in self._experiment.remote:
+ if m not in locked_machines:
+ self._experiment.remote.remove(m)
+
+ for l in self._experiment.labels:
+ for m in l.remote:
+ if m not in locked_machines:
+ l.remote.remove(m)
+
def _LockAllMachines(self, experiment):
"""Attempt to globally lock all of the machines requested for run.
@@ -65,7 +85,12 @@ class ExperimentRunner(object):
lock_mgr.AddLocalMachine(m)
machine_states = lock_mgr.GetMachineStates("lock")
lock_mgr.CheckMachineLocks(machine_states, "lock")
- lock_mgr.UpdateMachines(True)
+ self.locked_machines = lock_mgr.UpdateMachines(True)
+ self._experiment.locked_machines = self.locked_machines
+ self._UpdateMachineList(self.locked_machines)
+ self._experiment.machine_manager.RemoveNonLockedMachines(self.locked_machines)
+ if len(self.locked_machines) == 0:
+ raise RuntimeError("Unable to lock any machines.")
def _UnlockAllMachines(self, experiment):
"""Attempt to globally unlock all of the machines requested for run.
@@ -73,8 +98,11 @@ class ExperimentRunner(object):
The method will use the AFE server to globally unlock all of the machines
requested for this crosperf run.
"""
+ if not self.locked_machines:
+ return
+
lock_mgr = afe_lock_machine.AFELockManager(
- self._GetMachineList(),
+ self.locked_machines,
"",
experiment.labels[0].chromeos_root,
None,
diff --git a/crosperf/machine_manager.py b/crosperf/machine_manager.py
index e36ae7d5..79423481 100644
--- a/crosperf/machine_manager.py
+++ b/crosperf/machine_manager.py
@@ -206,6 +206,15 @@ class MachineManager(object):
self._initialized_machines = []
self.chromeos_root = chromeos_root
+ def RemoveNonLockedMachines(self, locked_machines):
+ for m in self._all_machines:
+ if m.name not in locked_machines:
+ self._all_machines.remove(m)
+
+ for m in self._machines:
+ if m.name not in locked_machines:
+ self._machines.remove(m)
+
def ImageMachine(self, machine, label):
if label.image_type == "local":
checksum = ImageChecksummer().Checksum(label, self.log_level)