1*800a58d9SAndroid Build Coastguard Worker# Copyright 2018 - The Android Open Source Project 2*800a58d9SAndroid Build Coastguard Worker# 3*800a58d9SAndroid Build Coastguard Worker# Licensed under the Apache License, Version 2.0 (the "License"); 4*800a58d9SAndroid Build Coastguard Worker# you may not use this file except in compliance with the License. 5*800a58d9SAndroid Build Coastguard Worker# You may obtain a copy of the License at 6*800a58d9SAndroid Build Coastguard Worker# 7*800a58d9SAndroid Build Coastguard Worker# http://www.apache.org/licenses/LICENSE-2.0 8*800a58d9SAndroid Build Coastguard Worker# 9*800a58d9SAndroid Build Coastguard Worker# Unless required by applicable law or agreed to in writing, software 10*800a58d9SAndroid Build Coastguard Worker# distributed under the License is distributed on an "AS IS" BASIS, 11*800a58d9SAndroid Build Coastguard Worker# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12*800a58d9SAndroid Build Coastguard Worker# See the License for the specific language governing permissions and 13*800a58d9SAndroid Build Coastguard Worker# limitations under the License. 14*800a58d9SAndroid Build Coastguard Workerr"""List entry point. 15*800a58d9SAndroid Build Coastguard Worker 16*800a58d9SAndroid Build Coastguard WorkerList will handle all the logic related to list a local/remote instance 17*800a58d9SAndroid Build Coastguard Workerof an Android Virtual Device. 18*800a58d9SAndroid Build Coastguard Worker""" 19*800a58d9SAndroid Build Coastguard Worker 20*800a58d9SAndroid Build Coastguard Workerfrom __future__ import print_function 21*800a58d9SAndroid Build Coastguard Workerimport getpass 22*800a58d9SAndroid Build Coastguard Workerimport logging 23*800a58d9SAndroid Build Coastguard Workerimport os 24*800a58d9SAndroid Build Coastguard Worker 25*800a58d9SAndroid Build Coastguard Workerfrom acloud import errors 26*800a58d9SAndroid Build Coastguard Workerfrom acloud.internal import constants 27*800a58d9SAndroid Build Coastguard Workerfrom acloud.internal.lib import auth 28*800a58d9SAndroid Build Coastguard Workerfrom acloud.internal.lib import gcompute_client 29*800a58d9SAndroid Build Coastguard Workerfrom acloud.internal.lib import utils 30*800a58d9SAndroid Build Coastguard Workerfrom acloud.list import instance 31*800a58d9SAndroid Build Coastguard Workerfrom acloud.public import config 32*800a58d9SAndroid Build Coastguard Worker 33*800a58d9SAndroid Build Coastguard Worker 34*800a58d9SAndroid Build Coastguard Workerlogger = logging.getLogger(__name__) 35*800a58d9SAndroid Build Coastguard Worker 36*800a58d9SAndroid Build Coastguard Worker_COMMAND_PS_LAUNCH_CVD = ["ps", "-wweo", "lstart,cmd"] 37*800a58d9SAndroid Build Coastguard Worker_NOT_CONNECTED_DEVICE_HINT = ( 38*800a58d9SAndroid Build Coastguard Worker "\nFor not connected device, you can try \"$ acloud reconnect\" or " 39*800a58d9SAndroid Build Coastguard Worker "\"$ acloud restart\" to get the device back.") 40*800a58d9SAndroid Build Coastguard Worker 41*800a58d9SAndroid Build Coastguard Worker 42*800a58d9SAndroid Build Coastguard Workerdef _ProcessInstances(instance_list): 43*800a58d9SAndroid Build Coastguard Worker """Get more details of remote instances. 44*800a58d9SAndroid Build Coastguard Worker 45*800a58d9SAndroid Build Coastguard Worker Args: 46*800a58d9SAndroid Build Coastguard Worker instance_list: List of dicts which contain info about the remote instances, 47*800a58d9SAndroid Build Coastguard Worker they're the response from the GCP GCE api. 48*800a58d9SAndroid Build Coastguard Worker 49*800a58d9SAndroid Build Coastguard Worker Returns: 50*800a58d9SAndroid Build Coastguard Worker instance_detail_list: List of instance.Instance() with detail info. 51*800a58d9SAndroid Build Coastguard Worker """ 52*800a58d9SAndroid Build Coastguard Worker return [instance.RemoteInstance(gce_instance) for gce_instance in instance_list] 53*800a58d9SAndroid Build Coastguard Worker 54*800a58d9SAndroid Build Coastguard Worker 55*800a58d9SAndroid Build Coastguard Workerdef _SortInstancesForDisplay(instances): 56*800a58d9SAndroid Build Coastguard Worker """Sort the instances by connected first and then by age. 57*800a58d9SAndroid Build Coastguard Worker 58*800a58d9SAndroid Build Coastguard Worker Args: 59*800a58d9SAndroid Build Coastguard Worker instances: List of instance.Instance() 60*800a58d9SAndroid Build Coastguard Worker 61*800a58d9SAndroid Build Coastguard Worker Returns: 62*800a58d9SAndroid Build Coastguard Worker List of instance.Instance() after sorted. 63*800a58d9SAndroid Build Coastguard Worker """ 64*800a58d9SAndroid Build Coastguard Worker instances.sort(key=lambda ins: ins.createtime, reverse=True) 65*800a58d9SAndroid Build Coastguard Worker instances.sort(key=lambda ins: ins.AdbConnected(), reverse=True) 66*800a58d9SAndroid Build Coastguard Worker return instances 67*800a58d9SAndroid Build Coastguard Worker 68*800a58d9SAndroid Build Coastguard Worker 69*800a58d9SAndroid Build Coastguard Workerdef PrintInstancesDetails(instance_list, verbose=False): 70*800a58d9SAndroid Build Coastguard Worker """Display instances information. 71*800a58d9SAndroid Build Coastguard Worker 72*800a58d9SAndroid Build Coastguard Worker Example of non-verbose case: 73*800a58d9SAndroid Build Coastguard Worker [1]device serial: 127.0.0.1:55685 (ins-1ff036dc-5128057-cf-x86-phone-userdebug) 74*800a58d9SAndroid Build Coastguard Worker [2]device serial: 127.0.0.1:60979 (ins-80952669-5128057-cf-x86-phone-userdebug) 75*800a58d9SAndroid Build Coastguard Worker [3]device serial: 127.0.0.1:6520 (local-instance) 76*800a58d9SAndroid Build Coastguard Worker 77*800a58d9SAndroid Build Coastguard Worker Example of verbose case: 78*800a58d9SAndroid Build Coastguard Worker [1] name: ins-244710f0-5091715-aosp-cf-x86-phone-userdebug 79*800a58d9SAndroid Build Coastguard Worker IP: None 80*800a58d9SAndroid Build Coastguard Worker create time: 2018-10-25T06:32:08.182-07:00 81*800a58d9SAndroid Build Coastguard Worker status: TERMINATED 82*800a58d9SAndroid Build Coastguard Worker avd type: cuttlefish 83*800a58d9SAndroid Build Coastguard Worker display: 1080x1920 (240) 84*800a58d9SAndroid Build Coastguard Worker 85*800a58d9SAndroid Build Coastguard Worker [2] name: ins-82979192-5091715-aosp-cf-x86-phone-userdebug 86*800a58d9SAndroid Build Coastguard Worker IP: 35.232.77.15 87*800a58d9SAndroid Build Coastguard Worker adb serial: 127.0.0.1:33537 88*800a58d9SAndroid Build Coastguard Worker create time: 2018-10-25T06:34:22.716-07:00 89*800a58d9SAndroid Build Coastguard Worker status: RUNNING 90*800a58d9SAndroid Build Coastguard Worker avd type: cuttlefish 91*800a58d9SAndroid Build Coastguard Worker display: 1080x1920 (240) 92*800a58d9SAndroid Build Coastguard Worker 93*800a58d9SAndroid Build Coastguard Worker Args: 94*800a58d9SAndroid Build Coastguard Worker verbose: Boolean, True to print all details and only full name if False. 95*800a58d9SAndroid Build Coastguard Worker instance_list: List of instances. 96*800a58d9SAndroid Build Coastguard Worker """ 97*800a58d9SAndroid Build Coastguard Worker not_any_connected_device = False 98*800a58d9SAndroid Build Coastguard Worker if not instance_list: 99*800a58d9SAndroid Build Coastguard Worker print("No remote or local instances found") 100*800a58d9SAndroid Build Coastguard Worker 101*800a58d9SAndroid Build Coastguard Worker for num, instance_info in enumerate(instance_list, 1): 102*800a58d9SAndroid Build Coastguard Worker idx_str = f"[{num}]" 103*800a58d9SAndroid Build Coastguard Worker utils.PrintColorString(idx_str, end="") 104*800a58d9SAndroid Build Coastguard Worker if verbose: 105*800a58d9SAndroid Build Coastguard Worker print(instance_info.Summary()) 106*800a58d9SAndroid Build Coastguard Worker # add space between instances in verbose mode. 107*800a58d9SAndroid Build Coastguard Worker print("") 108*800a58d9SAndroid Build Coastguard Worker else: 109*800a58d9SAndroid Build Coastguard Worker print(instance_info) 110*800a58d9SAndroid Build Coastguard Worker 111*800a58d9SAndroid Build Coastguard Worker if not instance_info.AdbConnected(): 112*800a58d9SAndroid Build Coastguard Worker not_any_connected_device = True 113*800a58d9SAndroid Build Coastguard Worker if not_any_connected_device: 114*800a58d9SAndroid Build Coastguard Worker utils.PrintColorString(_NOT_CONNECTED_DEVICE_HINT) 115*800a58d9SAndroid Build Coastguard Worker 116*800a58d9SAndroid Build Coastguard Worker 117*800a58d9SAndroid Build Coastguard Workerdef GetRemoteInstances(cfg): 118*800a58d9SAndroid Build Coastguard Worker """Look for remote instances. 119*800a58d9SAndroid Build Coastguard Worker 120*800a58d9SAndroid Build Coastguard Worker We're going to query the GCP project for all instances that created by user. 121*800a58d9SAndroid Build Coastguard Worker 122*800a58d9SAndroid Build Coastguard Worker Args: 123*800a58d9SAndroid Build Coastguard Worker cfg: AcloudConfig object. 124*800a58d9SAndroid Build Coastguard Worker 125*800a58d9SAndroid Build Coastguard Worker Returns: 126*800a58d9SAndroid Build Coastguard Worker instance_list: List of remote instances. 127*800a58d9SAndroid Build Coastguard Worker """ 128*800a58d9SAndroid Build Coastguard Worker credentials = auth.CreateCredentials(cfg) 129*800a58d9SAndroid Build Coastguard Worker compute_client = gcompute_client.ComputeClient(cfg, credentials) 130*800a58d9SAndroid Build Coastguard Worker filter_item = f"labels.{constants.LABEL_CREATE_BY}={getpass.getuser()}" 131*800a58d9SAndroid Build Coastguard Worker all_instances = compute_client.ListInstances(instance_filter=filter_item) 132*800a58d9SAndroid Build Coastguard Worker 133*800a58d9SAndroid Build Coastguard Worker logger.debug("Instance list from: (filter: %s\n%s):", 134*800a58d9SAndroid Build Coastguard Worker filter_item, all_instances) 135*800a58d9SAndroid Build Coastguard Worker 136*800a58d9SAndroid Build Coastguard Worker return _SortInstancesForDisplay(_ProcessInstances(all_instances)) 137*800a58d9SAndroid Build Coastguard Worker 138*800a58d9SAndroid Build Coastguard Worker 139*800a58d9SAndroid Build Coastguard Workerdef _GetLocalCuttlefishInstances(id_cfg_pairs): 140*800a58d9SAndroid Build Coastguard Worker """Look for local cuttelfish instances. 141*800a58d9SAndroid Build Coastguard Worker 142*800a58d9SAndroid Build Coastguard Worker Gather local instances information from cuttlefish runtime config. 143*800a58d9SAndroid Build Coastguard Worker 144*800a58d9SAndroid Build Coastguard Worker Args: 145*800a58d9SAndroid Build Coastguard Worker id_cfg_pairs: List of tuples. Each tuple consists of an instance id and 146*800a58d9SAndroid Build Coastguard Worker a config path. 147*800a58d9SAndroid Build Coastguard Worker 148*800a58d9SAndroid Build Coastguard Worker Returns: 149*800a58d9SAndroid Build Coastguard Worker instance_list: List of local instances. 150*800a58d9SAndroid Build Coastguard Worker """ 151*800a58d9SAndroid Build Coastguard Worker local_instance_list = [] 152*800a58d9SAndroid Build Coastguard Worker for ins_id, cfg_path in id_cfg_pairs: 153*800a58d9SAndroid Build Coastguard Worker ins_lock = instance.GetLocalInstanceLock(ins_id) 154*800a58d9SAndroid Build Coastguard Worker if not ins_lock.Lock(): 155*800a58d9SAndroid Build Coastguard Worker logger.warning("Cuttlefish Instance %d is locked by another " 156*800a58d9SAndroid Build Coastguard Worker "process.", ins_id) 157*800a58d9SAndroid Build Coastguard Worker continue 158*800a58d9SAndroid Build Coastguard Worker try: 159*800a58d9SAndroid Build Coastguard Worker if not os.path.isfile(cfg_path): 160*800a58d9SAndroid Build Coastguard Worker continue 161*800a58d9SAndroid Build Coastguard Worker instances = instance.GetCuttleFishLocalInstances(cfg_path) 162*800a58d9SAndroid Build Coastguard Worker for ins in instances: 163*800a58d9SAndroid Build Coastguard Worker if ins.CvdStatus(): 164*800a58d9SAndroid Build Coastguard Worker local_instance_list.append(ins) 165*800a58d9SAndroid Build Coastguard Worker else: 166*800a58d9SAndroid Build Coastguard Worker logger.info("Cvd runtime config is found at %s but instance " 167*800a58d9SAndroid Build Coastguard Worker "%d is not active.", cfg_path, ins_id) 168*800a58d9SAndroid Build Coastguard Worker finally: 169*800a58d9SAndroid Build Coastguard Worker ins_lock.Unlock() 170*800a58d9SAndroid Build Coastguard Worker return local_instance_list 171*800a58d9SAndroid Build Coastguard Worker 172*800a58d9SAndroid Build Coastguard Worker 173*800a58d9SAndroid Build Coastguard Workerdef GetActiveCVD(local_instance_id): 174*800a58d9SAndroid Build Coastguard Worker """Check if the local AVD with specific instance id is running 175*800a58d9SAndroid Build Coastguard Worker 176*800a58d9SAndroid Build Coastguard Worker This function does not lock the instance. 177*800a58d9SAndroid Build Coastguard Worker 178*800a58d9SAndroid Build Coastguard Worker Args: 179*800a58d9SAndroid Build Coastguard Worker local_instance_id: Integer of instance id. 180*800a58d9SAndroid Build Coastguard Worker 181*800a58d9SAndroid Build Coastguard Worker Return: 182*800a58d9SAndroid Build Coastguard Worker LocalInstance object. 183*800a58d9SAndroid Build Coastguard Worker """ 184*800a58d9SAndroid Build Coastguard Worker cfg_path = instance.GetLocalInstanceConfig(local_instance_id) 185*800a58d9SAndroid Build Coastguard Worker if cfg_path: 186*800a58d9SAndroid Build Coastguard Worker ins = instance.LocalInstance(cfg_path) 187*800a58d9SAndroid Build Coastguard Worker if ins.CvdStatus(): 188*800a58d9SAndroid Build Coastguard Worker return ins 189*800a58d9SAndroid Build Coastguard Worker cfg_path = instance.GetDefaultCuttlefishConfig() 190*800a58d9SAndroid Build Coastguard Worker if local_instance_id == 1 and cfg_path: 191*800a58d9SAndroid Build Coastguard Worker ins = instance.LocalInstance(cfg_path) 192*800a58d9SAndroid Build Coastguard Worker if ins.CvdStatus(): 193*800a58d9SAndroid Build Coastguard Worker return ins 194*800a58d9SAndroid Build Coastguard Worker return None 195*800a58d9SAndroid Build Coastguard Worker 196*800a58d9SAndroid Build Coastguard Worker 197*800a58d9SAndroid Build Coastguard Workerdef GetLocalInstances(): 198*800a58d9SAndroid Build Coastguard Worker """Look for local cuttleifsh and goldfish instances. 199*800a58d9SAndroid Build Coastguard Worker 200*800a58d9SAndroid Build Coastguard Worker Returns: 201*800a58d9SAndroid Build Coastguard Worker List of local instances. 202*800a58d9SAndroid Build Coastguard Worker """ 203*800a58d9SAndroid Build Coastguard Worker # Running instances on local is not supported on all OS. 204*800a58d9SAndroid Build Coastguard Worker if not utils.IsSupportedPlatform(): 205*800a58d9SAndroid Build Coastguard Worker return [] 206*800a58d9SAndroid Build Coastguard Worker 207*800a58d9SAndroid Build Coastguard Worker id_cfg_pairs = instance.GetAllLocalInstanceConfigs() 208*800a58d9SAndroid Build Coastguard Worker return (_GetLocalCuttlefishInstances(id_cfg_pairs) + 209*800a58d9SAndroid Build Coastguard Worker instance.LocalGoldfishInstance.GetExistingInstances()) 210*800a58d9SAndroid Build Coastguard Worker 211*800a58d9SAndroid Build Coastguard Worker 212*800a58d9SAndroid Build Coastguard Workerdef GetInstances(cfg): 213*800a58d9SAndroid Build Coastguard Worker """Look for remote/local instances. 214*800a58d9SAndroid Build Coastguard Worker 215*800a58d9SAndroid Build Coastguard Worker Args: 216*800a58d9SAndroid Build Coastguard Worker cfg: AcloudConfig object. 217*800a58d9SAndroid Build Coastguard Worker 218*800a58d9SAndroid Build Coastguard Worker Returns: 219*800a58d9SAndroid Build Coastguard Worker instance_list: List of instances. 220*800a58d9SAndroid Build Coastguard Worker """ 221*800a58d9SAndroid Build Coastguard Worker return GetRemoteInstances(cfg) + GetLocalInstances() 222*800a58d9SAndroid Build Coastguard Worker 223*800a58d9SAndroid Build Coastguard Worker 224*800a58d9SAndroid Build Coastguard Workerdef ChooseInstancesFromList(instances): 225*800a58d9SAndroid Build Coastguard Worker """Let user choose instances from a list. 226*800a58d9SAndroid Build Coastguard Worker 227*800a58d9SAndroid Build Coastguard Worker Args: 228*800a58d9SAndroid Build Coastguard Worker instances: List of Instance objects. 229*800a58d9SAndroid Build Coastguard Worker 230*800a58d9SAndroid Build Coastguard Worker Returns: 231*800a58d9SAndroid Build Coastguard Worker List of Instance objects. 232*800a58d9SAndroid Build Coastguard Worker """ 233*800a58d9SAndroid Build Coastguard Worker if len(instances) > 1: 234*800a58d9SAndroid Build Coastguard Worker print("Multiple instances detected, choose any one to proceed:") 235*800a58d9SAndroid Build Coastguard Worker return utils.GetAnswerFromList(instances, enable_choose_all=True) 236*800a58d9SAndroid Build Coastguard Worker return instances 237*800a58d9SAndroid Build Coastguard Worker 238*800a58d9SAndroid Build Coastguard Worker 239*800a58d9SAndroid Build Coastguard Workerdef ChooseInstances(cfg, select_all_instances=False): 240*800a58d9SAndroid Build Coastguard Worker """Get instances. 241*800a58d9SAndroid Build Coastguard Worker 242*800a58d9SAndroid Build Coastguard Worker Retrieve all remote/local instances and if there is more than 1 instance 243*800a58d9SAndroid Build Coastguard Worker found, ask user which instance they'd like. 244*800a58d9SAndroid Build Coastguard Worker 245*800a58d9SAndroid Build Coastguard Worker Args: 246*800a58d9SAndroid Build Coastguard Worker cfg: AcloudConfig object. 247*800a58d9SAndroid Build Coastguard Worker select_all_instances: True if select all instances by default and no 248*800a58d9SAndroid Build Coastguard Worker need to ask user to choose. 249*800a58d9SAndroid Build Coastguard Worker 250*800a58d9SAndroid Build Coastguard Worker Returns: 251*800a58d9SAndroid Build Coastguard Worker List of Instance() object. 252*800a58d9SAndroid Build Coastguard Worker """ 253*800a58d9SAndroid Build Coastguard Worker instances = GetInstances(cfg) 254*800a58d9SAndroid Build Coastguard Worker if not select_all_instances: 255*800a58d9SAndroid Build Coastguard Worker return ChooseInstancesFromList(instances) 256*800a58d9SAndroid Build Coastguard Worker return instances 257*800a58d9SAndroid Build Coastguard Worker 258*800a58d9SAndroid Build Coastguard Worker 259*800a58d9SAndroid Build Coastguard Workerdef ChooseOneRemoteInstance(cfg): 260*800a58d9SAndroid Build Coastguard Worker """Get one remote cuttlefish instance. 261*800a58d9SAndroid Build Coastguard Worker 262*800a58d9SAndroid Build Coastguard Worker Retrieve all remote cuttlefish instances and if there is more than 1 instance 263*800a58d9SAndroid Build Coastguard Worker found, ask user which instance they'd like. 264*800a58d9SAndroid Build Coastguard Worker 265*800a58d9SAndroid Build Coastguard Worker Args: 266*800a58d9SAndroid Build Coastguard Worker cfg: AcloudConfig object. 267*800a58d9SAndroid Build Coastguard Worker 268*800a58d9SAndroid Build Coastguard Worker Raises: 269*800a58d9SAndroid Build Coastguard Worker errors.NoInstancesFound: No cuttlefish remote instance found. 270*800a58d9SAndroid Build Coastguard Worker 271*800a58d9SAndroid Build Coastguard Worker Returns: 272*800a58d9SAndroid Build Coastguard Worker list.Instance() object. 273*800a58d9SAndroid Build Coastguard Worker """ 274*800a58d9SAndroid Build Coastguard Worker instances_list = GetCFRemoteInstances(cfg) 275*800a58d9SAndroid Build Coastguard Worker if not instances_list: 276*800a58d9SAndroid Build Coastguard Worker raise errors.NoInstancesFound( 277*800a58d9SAndroid Build Coastguard Worker "Can't find any cuttlefish remote instances, please try " 278*800a58d9SAndroid Build Coastguard Worker "'$acloud create' to create instances") 279*800a58d9SAndroid Build Coastguard Worker if len(instances_list) > 1: 280*800a58d9SAndroid Build Coastguard Worker print("Multiple instances detected, choose any one to proceed:") 281*800a58d9SAndroid Build Coastguard Worker instances = utils.GetAnswerFromList(instances_list, 282*800a58d9SAndroid Build Coastguard Worker enable_choose_all=False) 283*800a58d9SAndroid Build Coastguard Worker return instances[0] 284*800a58d9SAndroid Build Coastguard Worker 285*800a58d9SAndroid Build Coastguard Worker return instances_list[0] 286*800a58d9SAndroid Build Coastguard Worker 287*800a58d9SAndroid Build Coastguard Worker 288*800a58d9SAndroid Build Coastguard Workerdef _FilterInstancesByNames(instances, names): 289*800a58d9SAndroid Build Coastguard Worker """Find instances by names. 290*800a58d9SAndroid Build Coastguard Worker 291*800a58d9SAndroid Build Coastguard Worker Args: 292*800a58d9SAndroid Build Coastguard Worker instances: Collection of Instance objects. 293*800a58d9SAndroid Build Coastguard Worker names: Collection of strings, the names of the instances to search for. 294*800a58d9SAndroid Build Coastguard Worker 295*800a58d9SAndroid Build Coastguard Worker Returns: 296*800a58d9SAndroid Build Coastguard Worker List of Instance objects. 297*800a58d9SAndroid Build Coastguard Worker 298*800a58d9SAndroid Build Coastguard Worker Raises: 299*800a58d9SAndroid Build Coastguard Worker errors.NoInstancesFound if any instance is not found. 300*800a58d9SAndroid Build Coastguard Worker """ 301*800a58d9SAndroid Build Coastguard Worker instance_map = {inst.name: inst for inst in instances} 302*800a58d9SAndroid Build Coastguard Worker found_instances = [] 303*800a58d9SAndroid Build Coastguard Worker missing_instance_names = [] 304*800a58d9SAndroid Build Coastguard Worker for name in names: 305*800a58d9SAndroid Build Coastguard Worker if name in instance_map: 306*800a58d9SAndroid Build Coastguard Worker found_instances.append(instance_map[name]) 307*800a58d9SAndroid Build Coastguard Worker else: 308*800a58d9SAndroid Build Coastguard Worker missing_instance_names.append(name) 309*800a58d9SAndroid Build Coastguard Worker 310*800a58d9SAndroid Build Coastguard Worker if missing_instance_names: 311*800a58d9SAndroid Build Coastguard Worker raise errors.NoInstancesFound("Did not find the following instances: %s" % 312*800a58d9SAndroid Build Coastguard Worker " ".join(missing_instance_names)) 313*800a58d9SAndroid Build Coastguard Worker return found_instances 314*800a58d9SAndroid Build Coastguard Worker 315*800a58d9SAndroid Build Coastguard Worker 316*800a58d9SAndroid Build Coastguard Workerdef GetLocalInstanceLockByName(name): 317*800a58d9SAndroid Build Coastguard Worker """Get the lock of a local cuttelfish or goldfish instance. 318*800a58d9SAndroid Build Coastguard Worker 319*800a58d9SAndroid Build Coastguard Worker Args: 320*800a58d9SAndroid Build Coastguard Worker name: The instance name. 321*800a58d9SAndroid Build Coastguard Worker 322*800a58d9SAndroid Build Coastguard Worker Returns: 323*800a58d9SAndroid Build Coastguard Worker LocalInstanceLock object. None if the name is invalid. 324*800a58d9SAndroid Build Coastguard Worker """ 325*800a58d9SAndroid Build Coastguard Worker cf_id = instance.GetLocalInstanceIdByName(name) 326*800a58d9SAndroid Build Coastguard Worker if cf_id is not None: 327*800a58d9SAndroid Build Coastguard Worker return instance.GetLocalInstanceLock(cf_id) 328*800a58d9SAndroid Build Coastguard Worker 329*800a58d9SAndroid Build Coastguard Worker gf_id = instance.LocalGoldfishInstance.GetIdByName(name) 330*800a58d9SAndroid Build Coastguard Worker if gf_id is not None: 331*800a58d9SAndroid Build Coastguard Worker return instance.LocalGoldfishInstance.GetLockById(gf_id) 332*800a58d9SAndroid Build Coastguard Worker 333*800a58d9SAndroid Build Coastguard Worker return None 334*800a58d9SAndroid Build Coastguard Worker 335*800a58d9SAndroid Build Coastguard Worker 336*800a58d9SAndroid Build Coastguard Workerdef GetLocalInstancesByNames(names): 337*800a58d9SAndroid Build Coastguard Worker """Get local cuttlefish and goldfish instances by names. 338*800a58d9SAndroid Build Coastguard Worker 339*800a58d9SAndroid Build Coastguard Worker This method does not raise an error if it cannot find all instances. 340*800a58d9SAndroid Build Coastguard Worker 341*800a58d9SAndroid Build Coastguard Worker Args: 342*800a58d9SAndroid Build Coastguard Worker names: Collection of instance names. 343*800a58d9SAndroid Build Coastguard Worker 344*800a58d9SAndroid Build Coastguard Worker Returns: 345*800a58d9SAndroid Build Coastguard Worker List consisting of LocalInstance and LocalGoldfishInstance objects. 346*800a58d9SAndroid Build Coastguard Worker """ 347*800a58d9SAndroid Build Coastguard Worker id_cfg_pairs = [] 348*800a58d9SAndroid Build Coastguard Worker for name in names: 349*800a58d9SAndroid Build Coastguard Worker ins_id = instance.GetLocalInstanceIdByName(name) 350*800a58d9SAndroid Build Coastguard Worker if ins_id is None: 351*800a58d9SAndroid Build Coastguard Worker continue 352*800a58d9SAndroid Build Coastguard Worker cfg_path = instance.GetLocalInstanceConfig(ins_id) 353*800a58d9SAndroid Build Coastguard Worker if cfg_path: 354*800a58d9SAndroid Build Coastguard Worker id_cfg_pairs.append((ins_id, cfg_path)) 355*800a58d9SAndroid Build Coastguard Worker if ins_id == 1: 356*800a58d9SAndroid Build Coastguard Worker cfg_path = instance.GetDefaultCuttlefishConfig() 357*800a58d9SAndroid Build Coastguard Worker if cfg_path: 358*800a58d9SAndroid Build Coastguard Worker id_cfg_pairs.append((ins_id, cfg_path)) 359*800a58d9SAndroid Build Coastguard Worker 360*800a58d9SAndroid Build Coastguard Worker gf_instances = [ins for ins in 361*800a58d9SAndroid Build Coastguard Worker instance.LocalGoldfishInstance.GetExistingInstances() 362*800a58d9SAndroid Build Coastguard Worker if ins.name in names] 363*800a58d9SAndroid Build Coastguard Worker 364*800a58d9SAndroid Build Coastguard Worker return _GetLocalCuttlefishInstances(id_cfg_pairs) + gf_instances 365*800a58d9SAndroid Build Coastguard Worker 366*800a58d9SAndroid Build Coastguard Worker 367*800a58d9SAndroid Build Coastguard Workerdef GetInstancesFromInstanceNames(cfg, instance_names): 368*800a58d9SAndroid Build Coastguard Worker """Get instances from instance names. 369*800a58d9SAndroid Build Coastguard Worker 370*800a58d9SAndroid Build Coastguard Worker Turn a list of instance names into a list of Instance(). 371*800a58d9SAndroid Build Coastguard Worker 372*800a58d9SAndroid Build Coastguard Worker Args: 373*800a58d9SAndroid Build Coastguard Worker cfg: AcloudConfig object. 374*800a58d9SAndroid Build Coastguard Worker instance_names: list of instance name. 375*800a58d9SAndroid Build Coastguard Worker 376*800a58d9SAndroid Build Coastguard Worker Returns: 377*800a58d9SAndroid Build Coastguard Worker List of Instance() objects. 378*800a58d9SAndroid Build Coastguard Worker 379*800a58d9SAndroid Build Coastguard Worker Raises: 380*800a58d9SAndroid Build Coastguard Worker errors.NoInstancesFound: No instances found. 381*800a58d9SAndroid Build Coastguard Worker """ 382*800a58d9SAndroid Build Coastguard Worker return _FilterInstancesByNames( 383*800a58d9SAndroid Build Coastguard Worker GetLocalInstancesByNames(instance_names) + GetRemoteInstances(cfg), 384*800a58d9SAndroid Build Coastguard Worker instance_names) 385*800a58d9SAndroid Build Coastguard Worker 386*800a58d9SAndroid Build Coastguard Worker 387*800a58d9SAndroid Build Coastguard Workerdef FilterInstancesByAdbPort(instances, adb_port): 388*800a58d9SAndroid Build Coastguard Worker """Find an instance by adb port. 389*800a58d9SAndroid Build Coastguard Worker 390*800a58d9SAndroid Build Coastguard Worker Args: 391*800a58d9SAndroid Build Coastguard Worker instances: Collection of Instance objects. 392*800a58d9SAndroid Build Coastguard Worker adb_port: int, adb port of the instance to search for. 393*800a58d9SAndroid Build Coastguard Worker 394*800a58d9SAndroid Build Coastguard Worker Returns: 395*800a58d9SAndroid Build Coastguard Worker List of Instance() objects. 396*800a58d9SAndroid Build Coastguard Worker 397*800a58d9SAndroid Build Coastguard Worker Raises: 398*800a58d9SAndroid Build Coastguard Worker errors.NoInstancesFound: No instances found. 399*800a58d9SAndroid Build Coastguard Worker """ 400*800a58d9SAndroid Build Coastguard Worker all_instance_info = [] 401*800a58d9SAndroid Build Coastguard Worker for instance_object in instances: 402*800a58d9SAndroid Build Coastguard Worker if instance_object.adb_port == adb_port: 403*800a58d9SAndroid Build Coastguard Worker return [instance_object] 404*800a58d9SAndroid Build Coastguard Worker all_instance_info.append(instance_object.fullname) 405*800a58d9SAndroid Build Coastguard Worker 406*800a58d9SAndroid Build Coastguard Worker # Show devices information to user when user provides wrong adb port. 407*800a58d9SAndroid Build Coastguard Worker if all_instance_info: 408*800a58d9SAndroid Build Coastguard Worker hint_message = ("No instance with adb port %d, available instances:\n%s" 409*800a58d9SAndroid Build Coastguard Worker % (adb_port, "\n".join(all_instance_info))) 410*800a58d9SAndroid Build Coastguard Worker else: 411*800a58d9SAndroid Build Coastguard Worker hint_message = "No instances to delete." 412*800a58d9SAndroid Build Coastguard Worker raise errors.NoInstancesFound(hint_message) 413*800a58d9SAndroid Build Coastguard Worker 414*800a58d9SAndroid Build Coastguard Worker 415*800a58d9SAndroid Build Coastguard Workerdef GetCFRemoteInstances(cfg): 416*800a58d9SAndroid Build Coastguard Worker """Look for cuttlefish remote instances. 417*800a58d9SAndroid Build Coastguard Worker 418*800a58d9SAndroid Build Coastguard Worker Args: 419*800a58d9SAndroid Build Coastguard Worker cfg: AcloudConfig object. 420*800a58d9SAndroid Build Coastguard Worker 421*800a58d9SAndroid Build Coastguard Worker Returns: 422*800a58d9SAndroid Build Coastguard Worker instance_list: List of instance names. 423*800a58d9SAndroid Build Coastguard Worker """ 424*800a58d9SAndroid Build Coastguard Worker instances = GetRemoteInstances(cfg) 425*800a58d9SAndroid Build Coastguard Worker return [ins for ins in instances if ins.avd_type == constants.TYPE_CF] 426*800a58d9SAndroid Build Coastguard Worker 427*800a58d9SAndroid Build Coastguard Worker 428*800a58d9SAndroid Build Coastguard Workerdef Run(args): 429*800a58d9SAndroid Build Coastguard Worker """Run list. 430*800a58d9SAndroid Build Coastguard Worker 431*800a58d9SAndroid Build Coastguard Worker Args: 432*800a58d9SAndroid Build Coastguard Worker args: Namespace object from argparse.parse_args. 433*800a58d9SAndroid Build Coastguard Worker """ 434*800a58d9SAndroid Build Coastguard Worker instances = GetLocalInstances() 435*800a58d9SAndroid Build Coastguard Worker cfg = config.GetAcloudConfig(args) 436*800a58d9SAndroid Build Coastguard Worker if not args.local_only and cfg.SupportRemoteInstance(): 437*800a58d9SAndroid Build Coastguard Worker instances.extend(GetRemoteInstances(cfg)) 438*800a58d9SAndroid Build Coastguard Worker 439*800a58d9SAndroid Build Coastguard Worker PrintInstancesDetails(instances, args.verbose) 440