blob: 9fae09c9d326c71939b568fbe0b46ceb8220a6a3 [file] [log] [blame]
Chris Masone9807bd62012-07-11 14:44:17 -07001# Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
2# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
4
5import logging
6
7import common
8from autotest_lib.client.common_lib import error
9from autotest_lib.server.cros import frontend_wrappers
10
11"""HostLockManager class, for the dynamic_suite module.
12
13A HostLockManager instance manages locking and unlocking a set of
14autotest DUTs. Once primed with a given set, it is bound to that set
15for the remainder of its lifetime and cannot be repurposed. If the
16caller fails to unlock() locked hosts before the instance is destroyed,
17it will attempt to unlock() the hosts automatically, but this is to be
18avoided.
19
20Usage:
21 manager = host_lock_manager.HostLockManager()
22 try:
23 manager.prime(['host1'])
24 manager.lock()
25 # do things
26 finally:
27 manager.unlock()
28"""
29
30class HostLockManager(object):
31 """
32 @var _afe: an instance of AFE as defined in server/frontend.py.
33 @var _hosts: an iterable of DUT hostnames.
34 @var _hosts_are_locked: whether we believe the hosts are locked
35 """
36
37
38 def __init__(self, afe=None):
39 """
40 Constructor
41
42 @param afe: an instance of AFE as defined in server/frontend.py.
43 """
44 self._afe = afe or frontend_wrappers.RetryingAFE(timeout_min=30,
45 delay_sec=10,
46 debug=False)
47 self._hosts = None
48 self._hosts_are_locked = False
49
50
51 def __del__(self):
52 if self._hosts_are_locked:
53 logging.error('Caller failed to unlock %r! '
54 'Forcing unlock now.' % self._hosts)
55 self.unlock()
56
57
58 def prime(self, hosts):
59 """Permanently associate this instance with |hosts|.
60
61 @param hosts: iterable of hostnames to take over locking/unlocking.
62 @raise error.HostLockManagerReuse if already prime()d.
63 """
64 if not self._hosts:
65 self._hosts = frozenset(hosts)
66 else:
67 raise error.HostLockManagerReuse(
68 'Already primed with %r.' % self._hosts)
69
70
71 def lock(self):
72 """Lock all DUTs in self._hosts."""
73 self._host_modifier(locked=True)
74 self._hosts_are_locked = True
75
76
77 def unlock(self):
78 """Unlock all DUTs in self._hosts."""
79 self._host_modifier(locked=False)
80 self._hosts_are_locked = False
81
82
83 def _host_modifier(self, **kwargs):
84 """Helper that runs the modify_host() RPC with specified args.
85
86 Passes kwargs through to the RPC directly.
87 """
88 self._afe.run('modify_hosts',
89 host_filter_data={'hostname__in': self._hosts},
90 update_data=kwargs)