1faf1fbb13009fcbc3342b6d3226f28aa3dc177fcTan Gao# Copyright (c) 2013 The Chromium Authors. All rights reserved. 2faf1fbb13009fcbc3342b6d3226f28aa3dc177fcTan Gao# Use of this source code is governed by a BSD-style license that can be 3faf1fbb13009fcbc3342b6d3226f28aa3dc177fcTan Gao# found in the LICENSE file. 4faf1fbb13009fcbc3342b6d3226f28aa3dc177fcTan Gao 5faf1fbb13009fcbc3342b6d3226f28aa3dc177fcTan Gaoimport logging 6e6f9c09d74b8823c16de839a18a571149c7b8740Tan Gaoimport random 7faf1fbb13009fcbc3342b6d3226f28aa3dc177fcTan Gao 8faf1fbb13009fcbc3342b6d3226f28aa3dc177fcTan Gaofrom time import sleep 9faf1fbb13009fcbc3342b6d3226f28aa3dc177fcTan Gao 102e4e57453f2713d12f79734e2ab3f03b4371a99dAlex Millerimport common 11fe3237a922ced95b3178859a8262098e6e55e164Jason Abelefrom autotest_lib.client.common_lib import utils 1222093e32603a2c850e8a15121f4718f15e435415Roshan Piusfrom autotest_lib.server.cros.ap_configurators import \ 13faf1fbb13009fcbc3342b6d3226f28aa3dc177fcTan Gao ap_configurator_factory 1422093e32603a2c850e8a15121f4718f15e435415Roshan Piusfrom autotest_lib.client.common_lib.cros.network import ap_constants 1522093e32603a2c850e8a15121f4718f15e435415Roshan Piusfrom autotest_lib.server.cros.ap_configurators import ap_cartridge 16faf1fbb13009fcbc3342b6d3226f28aa3dc177fcTan Gao 17faf1fbb13009fcbc3342b6d3226f28aa3dc177fcTan Gao 18faf1fbb13009fcbc3342b6d3226f28aa3dc177fcTan Gao# Max number of retry attempts to lock an ap. 19faf1fbb13009fcbc3342b6d3226f28aa3dc177fcTan GaoMAX_RETRIES = 3 20faf1fbb13009fcbc3342b6d3226f28aa3dc177fcTan Gao 21faf1fbb13009fcbc3342b6d3226f28aa3dc177fcTan Gao 22faf1fbb13009fcbc3342b6d3226f28aa3dc177fcTan Gaoclass ApLocker(object): 23faf1fbb13009fcbc3342b6d3226f28aa3dc177fcTan Gao """Object to keep track of AP lock state. 24faf1fbb13009fcbc3342b6d3226f28aa3dc177fcTan Gao 25faf1fbb13009fcbc3342b6d3226f28aa3dc177fcTan Gao @attribute configurator: an APConfigurator object. 26faf1fbb13009fcbc3342b6d3226f28aa3dc177fcTan Gao @attribute to_be_locked: a boolean, True iff ap has not been locked. 27faf1fbb13009fcbc3342b6d3226f28aa3dc177fcTan Gao @attribute retries: an integer, max number of retry attempts to lock ap. 28faf1fbb13009fcbc3342b6d3226f28aa3dc177fcTan Gao """ 29faf1fbb13009fcbc3342b6d3226f28aa3dc177fcTan Gao 30faf1fbb13009fcbc3342b6d3226f28aa3dc177fcTan Gao 31faf1fbb13009fcbc3342b6d3226f28aa3dc177fcTan Gao def __init__(self, configurator, retries): 32faf1fbb13009fcbc3342b6d3226f28aa3dc177fcTan Gao """Initialize. 33faf1fbb13009fcbc3342b6d3226f28aa3dc177fcTan Gao 34faf1fbb13009fcbc3342b6d3226f28aa3dc177fcTan Gao @param configurator: an APConfigurator object. 35faf1fbb13009fcbc3342b6d3226f28aa3dc177fcTan Gao @param retries: an integer, max number of retry attempts to lock ap. 36faf1fbb13009fcbc3342b6d3226f28aa3dc177fcTan Gao """ 37faf1fbb13009fcbc3342b6d3226f28aa3dc177fcTan Gao self.configurator = configurator 38faf1fbb13009fcbc3342b6d3226f28aa3dc177fcTan Gao self.to_be_locked = True 39faf1fbb13009fcbc3342b6d3226f28aa3dc177fcTan Gao self.retries = retries 40faf1fbb13009fcbc3342b6d3226f28aa3dc177fcTan Gao 41faf1fbb13009fcbc3342b6d3226f28aa3dc177fcTan Gao 42faf1fbb13009fcbc3342b6d3226f28aa3dc177fcTan Gao def __repr__(self): 43faf1fbb13009fcbc3342b6d3226f28aa3dc177fcTan Gao """@return class name, ap host name, lock status and retries.""" 44faf1fbb13009fcbc3342b6d3226f28aa3dc177fcTan Gao return 'class: %s, host name: %s, to_be_locked = %s, retries = %d' % ( 45faf1fbb13009fcbc3342b6d3226f28aa3dc177fcTan Gao self.__class__.__name__, 46faf1fbb13009fcbc3342b6d3226f28aa3dc177fcTan Gao self.configurator.host_name, 47faf1fbb13009fcbc3342b6d3226f28aa3dc177fcTan Gao self.to_be_locked, 48faf1fbb13009fcbc3342b6d3226f28aa3dc177fcTan Gao self.retries) 49faf1fbb13009fcbc3342b6d3226f28aa3dc177fcTan Gao 50faf1fbb13009fcbc3342b6d3226f28aa3dc177fcTan Gao 5122093e32603a2c850e8a15121f4718f15e435415Roshan Piusdef construct_ap_lockers(ap_spec, retries, hostname_matching_only=False, 5222093e32603a2c850e8a15121f4718f15e435415Roshan Pius ap_test_type=ap_constants.AP_TEST_TYPE_CHAOS): 53faf1fbb13009fcbc3342b6d3226f28aa3dc177fcTan Gao """Convert APConfigurator objects to ApLocker objects for locking. 54faf1fbb13009fcbc3342b6d3226f28aa3dc177fcTan Gao 55506a99d582456eff2f6d5e534cbf00a62990e97dKris Rambish @param ap_spec: an APSpec object 56faf1fbb13009fcbc3342b6d3226f28aa3dc177fcTan Gao @param retries: an integer, max number of retry attempts to lock ap. 5748407e81a9fe4dbb13609b2f871761d02123e237Kris Rambish @param hostname_matching_only: a boolean, if True matching against 5848407e81a9fe4dbb13609b2f871761d02123e237Kris Rambish all other APSpec parameters is not 5948407e81a9fe4dbb13609b2f871761d02123e237Kris Rambish performed. 6022093e32603a2c850e8a15121f4718f15e435415Roshan Pius @param ap_test_type: Used to determine which type of test we're 6122093e32603a2c850e8a15121f4718f15e435415Roshan Pius currently running (Chaos vs Clique). 6248407e81a9fe4dbb13609b2f871761d02123e237Kris Rambish 63faf1fbb13009fcbc3342b6d3226f28aa3dc177fcTan Gao @return a list of ApLocker objects. 64faf1fbb13009fcbc3342b6d3226f28aa3dc177fcTan Gao """ 65faf1fbb13009fcbc3342b6d3226f28aa3dc177fcTan Gao ap_lockers_list = [] 66d2ae97483945e7f78e57e41cafcd800553e08598Tien Chang factory = ap_configurator_factory.APConfiguratorFactory(ap_test_type, 67d2ae97483945e7f78e57e41cafcd800553e08598Tien Chang ap_spec) 6848407e81a9fe4dbb13609b2f871761d02123e237Kris Rambish if hostname_matching_only: 6948407e81a9fe4dbb13609b2f871761d02123e237Kris Rambish for ap in factory.get_aps_by_hostnames(ap_spec.hostnames): 7048407e81a9fe4dbb13609b2f871761d02123e237Kris Rambish ap_lockers_list.append(ApLocker(ap, retries)) 7148407e81a9fe4dbb13609b2f871761d02123e237Kris Rambish else: 7248407e81a9fe4dbb13609b2f871761d02123e237Kris Rambish for ap in factory.get_ap_configurators_by_spec(ap_spec): 7348407e81a9fe4dbb13609b2f871761d02123e237Kris Rambish ap_lockers_list.append(ApLocker(ap, retries)) 74faf1fbb13009fcbc3342b6d3226f28aa3dc177fcTan Gao 75c00e83b0c1d8eac549a633d44dccebf0fb8eb875Christopher Wiley if not len(ap_lockers_list): 7613fad55d8088ec511d93f31b1c3813a907aef141Tien Chang logging.error('Found no matching APs to test against for %s', ap_spec) 77c00e83b0c1d8eac549a633d44dccebf0fb8eb875Christopher Wiley 78faf1fbb13009fcbc3342b6d3226f28aa3dc177fcTan Gao logging.debug('Found %d APs', len(ap_lockers_list)) 79faf1fbb13009fcbc3342b6d3226f28aa3dc177fcTan Gao return ap_lockers_list 80faf1fbb13009fcbc3342b6d3226f28aa3dc177fcTan Gao 81faf1fbb13009fcbc3342b6d3226f28aa3dc177fcTan Gao 82faf1fbb13009fcbc3342b6d3226f28aa3dc177fcTan Gaoclass ApBatchLocker(object): 83faf1fbb13009fcbc3342b6d3226f28aa3dc177fcTan Gao """Object to lock/unlock an APConfigurator. 84faf1fbb13009fcbc3342b6d3226f28aa3dc177fcTan Gao 85faf1fbb13009fcbc3342b6d3226f28aa3dc177fcTan Gao @attribute SECONDS_TO_SLEEP: an integer, number of seconds to sleep between 86faf1fbb13009fcbc3342b6d3226f28aa3dc177fcTan Gao retries. 87506a99d582456eff2f6d5e534cbf00a62990e97dKris Rambish @attribute ap_spec: an APSpec object 88faf1fbb13009fcbc3342b6d3226f28aa3dc177fcTan Gao @attribute retries: an integer, max number of retry attempts to lock ap. 89faf1fbb13009fcbc3342b6d3226f28aa3dc177fcTan Gao Defaults to MAX_RETRIES. 90faf1fbb13009fcbc3342b6d3226f28aa3dc177fcTan Gao @attribute aps_to_lock: a list of ApLocker objects. 91faf1fbb13009fcbc3342b6d3226f28aa3dc177fcTan Gao @attribute manager: a HostLockManager object, used to lock/unlock APs. 92faf1fbb13009fcbc3342b6d3226f28aa3dc177fcTan Gao """ 93faf1fbb13009fcbc3342b6d3226f28aa3dc177fcTan Gao 94faf1fbb13009fcbc3342b6d3226f28aa3dc177fcTan Gao 95e6f9c09d74b8823c16de839a18a571149c7b8740Tan Gao MIN_SECONDS_TO_SLEEP = 30 96e6f9c09d74b8823c16de839a18a571149c7b8740Tan Gao MAX_SECONDS_TO_SLEEP = 120 97faf1fbb13009fcbc3342b6d3226f28aa3dc177fcTan Gao 98faf1fbb13009fcbc3342b6d3226f28aa3dc177fcTan Gao 9948407e81a9fe4dbb13609b2f871761d02123e237Kris Rambish def __init__(self, lock_manager, ap_spec, retries=MAX_RETRIES, 10022093e32603a2c850e8a15121f4718f15e435415Roshan Pius hostname_matching_only=False, 10122093e32603a2c850e8a15121f4718f15e435415Roshan Pius ap_test_type=ap_constants.AP_TEST_TYPE_CHAOS): 102faf1fbb13009fcbc3342b6d3226f28aa3dc177fcTan Gao """Initialize. 103faf1fbb13009fcbc3342b6d3226f28aa3dc177fcTan Gao 104506a99d582456eff2f6d5e534cbf00a62990e97dKris Rambish @param ap_spec: an APSpec object 105faf1fbb13009fcbc3342b6d3226f28aa3dc177fcTan Gao @param retries: an integer, max number of retry attempts to lock ap. 106faf1fbb13009fcbc3342b6d3226f28aa3dc177fcTan Gao Defaults to MAX_RETRIES. 10748407e81a9fe4dbb13609b2f871761d02123e237Kris Rambish @param hostname_matching_only : a boolean, if True matching against 10848407e81a9fe4dbb13609b2f871761d02123e237Kris Rambish all other APSpec parameters is not 10948407e81a9fe4dbb13609b2f871761d02123e237Kris Rambish performed. 11022093e32603a2c850e8a15121f4718f15e435415Roshan Pius @param ap_test_type: Used to determine which type of test we're 11122093e32603a2c850e8a15121f4718f15e435415Roshan Pius currently running (Chaos vs Clique). 112faf1fbb13009fcbc3342b6d3226f28aa3dc177fcTan Gao """ 11348407e81a9fe4dbb13609b2f871761d02123e237Kris Rambish self.aps_to_lock = construct_ap_lockers(ap_spec, retries, 11422093e32603a2c850e8a15121f4718f15e435415Roshan Pius hostname_matching_only=hostname_matching_only, 11522093e32603a2c850e8a15121f4718f15e435415Roshan Pius ap_test_type=ap_test_type) 116ca4e36ca5d3a37f4c8438e9545ff93fff284653cChristopher Wiley self.manager = lock_manager 117ca4e36ca5d3a37f4c8438e9545ff93fff284653cChristopher Wiley self._locked_aps = [] 118faf1fbb13009fcbc3342b6d3226f28aa3dc177fcTan Gao 119faf1fbb13009fcbc3342b6d3226f28aa3dc177fcTan Gao 120faf1fbb13009fcbc3342b6d3226f28aa3dc177fcTan Gao def has_more_aps(self): 121faf1fbb13009fcbc3342b6d3226f28aa3dc177fcTan Gao """@return True iff there is at least one AP to be locked.""" 122faf1fbb13009fcbc3342b6d3226f28aa3dc177fcTan Gao return len(self.aps_to_lock) > 0 123faf1fbb13009fcbc3342b6d3226f28aa3dc177fcTan Gao 124faf1fbb13009fcbc3342b6d3226f28aa3dc177fcTan Gao 125faf1fbb13009fcbc3342b6d3226f28aa3dc177fcTan Gao def lock_ap_in_afe(self, ap_locker): 126faf1fbb13009fcbc3342b6d3226f28aa3dc177fcTan Gao """Locks an AP host in AFE. 127faf1fbb13009fcbc3342b6d3226f28aa3dc177fcTan Gao 128faf1fbb13009fcbc3342b6d3226f28aa3dc177fcTan Gao @param ap_locker: an ApLocker object, AP to be locked. 129faf1fbb13009fcbc3342b6d3226f28aa3dc177fcTan Gao @return a boolean, True iff ap_locker is locked. 130faf1fbb13009fcbc3342b6d3226f28aa3dc177fcTan Gao """ 131fe3237a922ced95b3178859a8262098e6e55e164Jason Abele if not utils.host_is_in_lab_zone(ap_locker.configurator.host_name): 132fe3237a922ced95b3178859a8262098e6e55e164Jason Abele ap_locker.to_be_locked = False 133fe3237a922ced95b3178859a8262098e6e55e164Jason Abele return True 134fe3237a922ced95b3178859a8262098e6e55e164Jason Abele 135751b85445709dc1015a6b31b8b51b379abbfdc78Tan Gao if self.manager.lock([ap_locker.configurator.host_name]): 136ba0006bba9e24725aefb3c123ed5e88946ebafa4Kris Rambish self._locked_aps.append(ap_locker) 137e6f9c09d74b8823c16de839a18a571149c7b8740Tan Gao logging.info('locked %s', ap_locker.configurator.host_name) 138faf1fbb13009fcbc3342b6d3226f28aa3dc177fcTan Gao ap_locker.to_be_locked = False 139faf1fbb13009fcbc3342b6d3226f28aa3dc177fcTan Gao return True 140e6f9c09d74b8823c16de839a18a571149c7b8740Tan Gao else: 141faf1fbb13009fcbc3342b6d3226f28aa3dc177fcTan Gao ap_locker.retries -= 1 142faf1fbb13009fcbc3342b6d3226f28aa3dc177fcTan Gao logging.info('%d retries left for %s', 143faf1fbb13009fcbc3342b6d3226f28aa3dc177fcTan Gao ap_locker.retries, 144faf1fbb13009fcbc3342b6d3226f28aa3dc177fcTan Gao ap_locker.configurator.host_name) 145faf1fbb13009fcbc3342b6d3226f28aa3dc177fcTan Gao if ap_locker.retries == 0: 146faf1fbb13009fcbc3342b6d3226f28aa3dc177fcTan Gao logging.info('No more retries left. Remove %s from list', 147faf1fbb13009fcbc3342b6d3226f28aa3dc177fcTan Gao ap_locker.configurator.host_name) 148e6f9c09d74b8823c16de839a18a571149c7b8740Tan Gao ap_locker.to_be_locked = False 149e6f9c09d74b8823c16de839a18a571149c7b8740Tan Gao 150faf1fbb13009fcbc3342b6d3226f28aa3dc177fcTan Gao return False 151faf1fbb13009fcbc3342b6d3226f28aa3dc177fcTan Gao 152faf1fbb13009fcbc3342b6d3226f28aa3dc177fcTan Gao 153faf1fbb13009fcbc3342b6d3226f28aa3dc177fcTan Gao def get_ap_batch(self, batch_size=ap_cartridge.THREAD_MAX): 154faf1fbb13009fcbc3342b6d3226f28aa3dc177fcTan Gao """Allocates a batch of locked APs. 155faf1fbb13009fcbc3342b6d3226f28aa3dc177fcTan Gao 156faf1fbb13009fcbc3342b6d3226f28aa3dc177fcTan Gao @param batch_size: an integer, max. number of aps to lock in one batch. 157faf1fbb13009fcbc3342b6d3226f28aa3dc177fcTan Gao Defaults to THREAD_MAX in ap_cartridge.py 158faf1fbb13009fcbc3342b6d3226f28aa3dc177fcTan Gao @return a list of APConfigurator objects, locked on AFE. 159faf1fbb13009fcbc3342b6d3226f28aa3dc177fcTan Gao """ 160faf1fbb13009fcbc3342b6d3226f28aa3dc177fcTan Gao # We need this while loop to continuously loop over the for loop. 161faf1fbb13009fcbc3342b6d3226f28aa3dc177fcTan Gao # To exit the while loop, we either: 162faf1fbb13009fcbc3342b6d3226f28aa3dc177fcTan Gao # - locked batch_size number of aps and return them 163faf1fbb13009fcbc3342b6d3226f28aa3dc177fcTan Gao # - exhausted all retries on all aps in aps_to_lock 164e6f9c09d74b8823c16de839a18a571149c7b8740Tan Gao while len(self.aps_to_lock): 165e6f9c09d74b8823c16de839a18a571149c7b8740Tan Gao ap_batch = [] 166e6f9c09d74b8823c16de839a18a571149c7b8740Tan Gao 167faf1fbb13009fcbc3342b6d3226f28aa3dc177fcTan Gao for ap_locker in self.aps_to_lock: 168e6f9c09d74b8823c16de839a18a571149c7b8740Tan Gao logging.info('checking %s', ap_locker.configurator.host_name) 169e6f9c09d74b8823c16de839a18a571149c7b8740Tan Gao if self.lock_ap_in_afe(ap_locker): 170e6f9c09d74b8823c16de839a18a571149c7b8740Tan Gao ap_batch.append(ap_locker.configurator) 171e6f9c09d74b8823c16de839a18a571149c7b8740Tan Gao if len(ap_batch) == batch_size: 172e6f9c09d74b8823c16de839a18a571149c7b8740Tan Gao break 173e6f9c09d74b8823c16de839a18a571149c7b8740Tan Gao 174e6f9c09d74b8823c16de839a18a571149c7b8740Tan Gao # Remove locked APs from list of APs to process. 175e6f9c09d74b8823c16de839a18a571149c7b8740Tan Gao aps_to_rm = [ap for ap in self.aps_to_lock if not ap.to_be_locked] 176e6f9c09d74b8823c16de839a18a571149c7b8740Tan Gao self.aps_to_lock = list(set(self.aps_to_lock) - set(aps_to_rm)) 177e6f9c09d74b8823c16de839a18a571149c7b8740Tan Gao for ap in aps_to_rm: 178e6f9c09d74b8823c16de839a18a571149c7b8740Tan Gao logging.info('Removed %s from self.aps_to_lock', 179e6f9c09d74b8823c16de839a18a571149c7b8740Tan Gao ap.configurator.host_name) 180e6f9c09d74b8823c16de839a18a571149c7b8740Tan Gao logging.info('Remaining aps to lock = %s', 181e6f9c09d74b8823c16de839a18a571149c7b8740Tan Gao [ap.configurator.host_name for ap in self.aps_to_lock]) 182e6f9c09d74b8823c16de839a18a571149c7b8740Tan Gao 183e6f9c09d74b8823c16de839a18a571149c7b8740Tan Gao # Return available APs and retry remaining ones later. 184e6f9c09d74b8823c16de839a18a571149c7b8740Tan Gao if ap_batch: 185e6f9c09d74b8823c16de839a18a571149c7b8740Tan Gao return ap_batch 186e6f9c09d74b8823c16de839a18a571149c7b8740Tan Gao 187e6f9c09d74b8823c16de839a18a571149c7b8740Tan Gao # Sleep before next retry. 188e6f9c09d74b8823c16de839a18a571149c7b8740Tan Gao if self.aps_to_lock: 189e6f9c09d74b8823c16de839a18a571149c7b8740Tan Gao seconds_to_sleep = random.randint(self.MIN_SECONDS_TO_SLEEP, 190e6f9c09d74b8823c16de839a18a571149c7b8740Tan Gao self.MAX_SECONDS_TO_SLEEP) 191e6f9c09d74b8823c16de839a18a571149c7b8740Tan Gao logging.info('Sleep %d sec before retry', seconds_to_sleep) 192e6f9c09d74b8823c16de839a18a571149c7b8740Tan Gao sleep(seconds_to_sleep) 193e6f9c09d74b8823c16de839a18a571149c7b8740Tan Gao 194e6f9c09d74b8823c16de839a18a571149c7b8740Tan Gao return [] 195e6f9c09d74b8823c16de839a18a571149c7b8740Tan Gao 196e6f9c09d74b8823c16de839a18a571149c7b8740Tan Gao 197ba0006bba9e24725aefb3c123ed5e88946ebafa4Kris Rambish def unlock_one_ap(self, host_name): 198751b85445709dc1015a6b31b8b51b379abbfdc78Tan Gao """Unlock one AP after we're done. 199751b85445709dc1015a6b31b8b51b379abbfdc78Tan Gao 200ba0006bba9e24725aefb3c123ed5e88946ebafa4Kris Rambish @param host_name: a string, host name. 201751b85445709dc1015a6b31b8b51b379abbfdc78Tan Gao """ 202ba0006bba9e24725aefb3c123ed5e88946ebafa4Kris Rambish for ap_locker in self._locked_aps: 203ba0006bba9e24725aefb3c123ed5e88946ebafa4Kris Rambish if host_name == ap_locker.configurator.host_name: 204ba0006bba9e24725aefb3c123ed5e88946ebafa4Kris Rambish self.manager.unlock(hosts=[host_name]) 2055320048ccfec8291a1b84838eeb925f2e0bb1965Kris Rambish self._locked_aps.remove(ap_locker) 206ba0006bba9e24725aefb3c123ed5e88946ebafa4Kris Rambish return 207ca4e36ca5d3a37f4c8438e9545ff93fff284653cChristopher Wiley 208ba0006bba9e24725aefb3c123ed5e88946ebafa4Kris Rambish logging.error('Tried to unlock a host we have not locked (%s)?', 209ba0006bba9e24725aefb3c123ed5e88946ebafa4Kris Rambish host_name) 210751b85445709dc1015a6b31b8b51b379abbfdc78Tan Gao 211751b85445709dc1015a6b31b8b51b379abbfdc78Tan Gao 212e6f9c09d74b8823c16de839a18a571149c7b8740Tan Gao def unlock_aps(self): 213e6f9c09d74b8823c16de839a18a571149c7b8740Tan Gao """Unlock APs after we're done.""" 2145320048ccfec8291a1b84838eeb925f2e0bb1965Kris Rambish # Make a copy of all of the hostnames to process 2155320048ccfec8291a1b84838eeb925f2e0bb1965Kris Rambish host_names = list() 216ba0006bba9e24725aefb3c123ed5e88946ebafa4Kris Rambish for ap_locker in self._locked_aps: 2175320048ccfec8291a1b84838eeb925f2e0bb1965Kris Rambish host_names.append(ap_locker.configurator.host_name) 2185320048ccfec8291a1b84838eeb925f2e0bb1965Kris Rambish for host_name in host_names: 2195320048ccfec8291a1b84838eeb925f2e0bb1965Kris Rambish self.unlock_one_ap(host_name) 220ba0006bba9e24725aefb3c123ed5e88946ebafa4Kris Rambish 221ba0006bba9e24725aefb3c123ed5e88946ebafa4Kris Rambish 2221afc69706f835eee0cd324e2aaf3f59101f89a69Kris Rambish def unlock_and_reclaim_ap(self, host_name): 2231afc69706f835eee0cd324e2aaf3f59101f89a69Kris Rambish """Unlock an AP but return it to the remaining batch of APs. 2241afc69706f835eee0cd324e2aaf3f59101f89a69Kris Rambish 2251afc69706f835eee0cd324e2aaf3f59101f89a69Kris Rambish @param host_name: a string, host name. 2261afc69706f835eee0cd324e2aaf3f59101f89a69Kris Rambish """ 2271afc69706f835eee0cd324e2aaf3f59101f89a69Kris Rambish for ap_locker in self._locked_aps: 2281afc69706f835eee0cd324e2aaf3f59101f89a69Kris Rambish if host_name == ap_locker.configurator.host_name: 2295320048ccfec8291a1b84838eeb925f2e0bb1965Kris Rambish self.aps_to_lock.append(ap_locker) 2305320048ccfec8291a1b84838eeb925f2e0bb1965Kris Rambish self.unlock_one_ap(host_name) 2315320048ccfec8291a1b84838eeb925f2e0bb1965Kris Rambish return 2321afc69706f835eee0cd324e2aaf3f59101f89a69Kris Rambish 2331afc69706f835eee0cd324e2aaf3f59101f89a69Kris Rambish 234ba0006bba9e24725aefb3c123ed5e88946ebafa4Kris Rambish def unlock_and_reclaim_aps(self): 2351afc69706f835eee0cd324e2aaf3f59101f89a69Kris Rambish """Unlock APs but return them to the batch of remining APs. 236ba0006bba9e24725aefb3c123ed5e88946ebafa4Kris Rambish 237ba0006bba9e24725aefb3c123ed5e88946ebafa4Kris Rambish unlock_aps() will remove the remaining APs from the list of all APs 238ba0006bba9e24725aefb3c123ed5e88946ebafa4Kris Rambish to process. This method will add the remaining APs back to the pool 239ba0006bba9e24725aefb3c123ed5e88946ebafa4Kris Rambish of unprocessed APs. 240ba0006bba9e24725aefb3c123ed5e88946ebafa4Kris Rambish 241ba0006bba9e24725aefb3c123ed5e88946ebafa4Kris Rambish """ 242ba0006bba9e24725aefb3c123ed5e88946ebafa4Kris Rambish # Add the APs back into the pool 243ba0006bba9e24725aefb3c123ed5e88946ebafa4Kris Rambish self.aps_to_lock.extend(self._locked_aps) 244ba0006bba9e24725aefb3c123ed5e88946ebafa4Kris Rambish self.unlock_aps() 245