[autotest] Add HostLockManager class, for locking/unlockin DUTs

An instance of HostLockManager is intended to be bound to a set of
hostnames shortly after instantiation.  Thereafter, it can be used to
lock/unlock those hosts freely, until it is destroyed.  At that time,
it will unlock() the associated hosts for you and complain that you
should've done it yourself.

This class is intended for use with dynamic_suite.Reimager and
dynamic_suite.Suite.  The purpose is to allow Reimager.attempt() to
lock some hosts while allowing Suite.run_and_wait() to unlock them
during the course of its run.  Therefore, a HostLockManager must be
instantiated _before_ we know what hosts are being reimaged, and live
after Reimager.attempt() has finished execution.  Hence, the prime()
method that takes an iterable of hostnames.

BUG=chromium-os:30978
TEST=unit

Change-Id: I806a39ccc4951b011b2f7664aa4e942506829bbb
Reviewed-on: https://gerrit.chromium.org/gerrit/27204
Tested-by: Chris Masone <cmasone@chromium.org>
Reviewed-by: Scott Zawalski <scottz@chromium.org>
Commit-Ready: Chris Masone <cmasone@chromium.org>
diff --git a/client/common_lib/error.py b/client/common_lib/error.py
index b903080..d9047c8 100644
--- a/client/common_lib/error.py
+++ b/client/common_lib/error.py
@@ -535,7 +535,12 @@
 
 
 class NoControlFileList(CrosDynamicSuiteException):
-    """Raised when to indicate that a listing can't be done."""
+    """Raised to indicate that a listing can't be done."""
+    pass
+
+
+class HostLockManagerReuse(CrosDynamicSuiteException):
+    """Raised when a caller tries to re-use a HostLockManager instance."""
     pass