1*800a58d9SAndroid Build Coastguard Worker#!/usr/bin/env python 2*800a58d9SAndroid Build Coastguard Worker# 3*800a58d9SAndroid Build Coastguard Worker# Copyright 2016 - The Android Open Source Project 4*800a58d9SAndroid Build Coastguard Worker# 5*800a58d9SAndroid Build Coastguard Worker# Licensed under the Apache License, Version 2.0 (the "License"); 6*800a58d9SAndroid Build Coastguard Worker# you may not use this file except in compliance with the License. 7*800a58d9SAndroid Build Coastguard Worker# You may obtain a copy of the License at 8*800a58d9SAndroid Build Coastguard Worker# 9*800a58d9SAndroid Build Coastguard Worker# http://www.apache.org/licenses/LICENSE-2.0 10*800a58d9SAndroid Build Coastguard Worker# 11*800a58d9SAndroid Build Coastguard Worker# Unless required by applicable law or agreed to in writing, software 12*800a58d9SAndroid Build Coastguard Worker# distributed under the License is distributed on an "AS IS" BASIS, 13*800a58d9SAndroid Build Coastguard Worker# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14*800a58d9SAndroid Build Coastguard Worker# See the License for the specific language governing permissions and 15*800a58d9SAndroid Build Coastguard Worker# limitations under the License. 16*800a58d9SAndroid Build Coastguard Workerr""" 17*800a58d9SAndroid Build Coastguard WorkerWelcome to 18*800a58d9SAndroid Build Coastguard Worker ___ _______ ____ __ _____ 19*800a58d9SAndroid Build Coastguard Worker / _ |/ ___/ / / __ \/ / / / _ \ 20*800a58d9SAndroid Build Coastguard Worker / __ / /__/ /__/ /_/ / /_/ / // / 21*800a58d9SAndroid Build Coastguard Worker/_/ |_\___/____/\____/\____/____/ 22*800a58d9SAndroid Build Coastguard Worker 23*800a58d9SAndroid Build Coastguard Worker 24*800a58d9SAndroid Build Coastguard WorkerThis a tool to create Android Virtual Devices locally/remotely. 25*800a58d9SAndroid Build Coastguard Worker 26*800a58d9SAndroid Build Coastguard Worker- Prerequisites: 27*800a58d9SAndroid Build Coastguard Worker The manual will be available at 28*800a58d9SAndroid Build Coastguard Worker https://android.googlesource.com/platform/tools/acloud/+/master/README.md 29*800a58d9SAndroid Build Coastguard Worker 30*800a58d9SAndroid Build Coastguard Worker- To get started: 31*800a58d9SAndroid Build Coastguard Worker - Create instances: 32*800a58d9SAndroid Build Coastguard Worker 1) To create a remote cuttlefish instance with the local built image. 33*800a58d9SAndroid Build Coastguard Worker Example: 34*800a58d9SAndroid Build Coastguard Worker $ acloud create --local-image 35*800a58d9SAndroid Build Coastguard Worker Or specify built image dir: 36*800a58d9SAndroid Build Coastguard Worker $ acloud create --local-image /tmp/image_dir 37*800a58d9SAndroid Build Coastguard Worker 2) To create a local cuttlefish instance using the image which has been 38*800a58d9SAndroid Build Coastguard Worker built out in your workspace. 39*800a58d9SAndroid Build Coastguard Worker Example: 40*800a58d9SAndroid Build Coastguard Worker $ acloud create --local-instance --local-image 41*800a58d9SAndroid Build Coastguard Worker 42*800a58d9SAndroid Build Coastguard Worker - Delete instances: 43*800a58d9SAndroid Build Coastguard Worker $ acloud delete 44*800a58d9SAndroid Build Coastguard Worker 45*800a58d9SAndroid Build Coastguard Worker - Reconnect: 46*800a58d9SAndroid Build Coastguard Worker To reconnect adb/vnc to an existing instance that's been disconnected: 47*800a58d9SAndroid Build Coastguard Worker $ acloud reconnect 48*800a58d9SAndroid Build Coastguard Worker Or to specify a specific instance: 49*800a58d9SAndroid Build Coastguard Worker $ acloud reconnect --instance-names <instance_name like ins-123-cf-x86-phone> 50*800a58d9SAndroid Build Coastguard Worker 51*800a58d9SAndroid Build Coastguard Worker - List: 52*800a58d9SAndroid Build Coastguard Worker List will retrieve all the remote instances you've created in addition to any 53*800a58d9SAndroid Build Coastguard Worker local instances created as well. 54*800a58d9SAndroid Build Coastguard Worker To show device IP address, adb port and instance name: 55*800a58d9SAndroid Build Coastguard Worker $ acloud list 56*800a58d9SAndroid Build Coastguard Worker To show more detail info on the list. 57*800a58d9SAndroid Build Coastguard Worker $ acloud list -vv 58*800a58d9SAndroid Build Coastguard Worker 59*800a58d9SAndroid Build Coastguard Worker- Pull: 60*800a58d9SAndroid Build Coastguard Worker Pull will download log files or show the log file in screen from one remote 61*800a58d9SAndroid Build Coastguard Worker cuttlefish instance: 62*800a58d9SAndroid Build Coastguard Worker $ acloud pull 63*800a58d9SAndroid Build Coastguard Worker Pull from a specified instance: 64*800a58d9SAndroid Build Coastguard Worker $ acloud pull --instance-name "your_instance_name" 65*800a58d9SAndroid Build Coastguard Worker 66*800a58d9SAndroid Build Coastguard WorkerTry $acloud [cmd] --help for further details. 67*800a58d9SAndroid Build Coastguard Worker 68*800a58d9SAndroid Build Coastguard Worker""" 69*800a58d9SAndroid Build Coastguard Worker 70*800a58d9SAndroid Build Coastguard Workerfrom __future__ import print_function 71*800a58d9SAndroid Build Coastguard Workerimport argparse 72*800a58d9SAndroid Build Coastguard Workerimport logging 73*800a58d9SAndroid Build Coastguard Workerimport os 74*800a58d9SAndroid Build Coastguard Workerimport sys 75*800a58d9SAndroid Build Coastguard Workerimport traceback 76*800a58d9SAndroid Build Coastguard Worker 77*800a58d9SAndroid Build Coastguard Workerif sys.version_info.major == 2: 78*800a58d9SAndroid Build Coastguard Worker print("Acloud only supports python3 (currently @ %d.%d.%d)." 79*800a58d9SAndroid Build Coastguard Worker " Please run Acloud with python3." % (sys.version_info.major, 80*800a58d9SAndroid Build Coastguard Worker sys.version_info.minor, 81*800a58d9SAndroid Build Coastguard Worker sys.version_info.micro)) 82*800a58d9SAndroid Build Coastguard Worker sys.exit(1) 83*800a58d9SAndroid Build Coastguard Worker 84*800a58d9SAndroid Build Coastguard Worker# By Default silence root logger's stream handler since 3p lib may initial 85*800a58d9SAndroid Build Coastguard Worker# root logger no matter what level we're using. The acloud logger behavior will 86*800a58d9SAndroid Build Coastguard Worker# be defined in _SetupLogging(). This also could workaround to get rid of below 87*800a58d9SAndroid Build Coastguard Worker# oauth2client warning: 88*800a58d9SAndroid Build Coastguard Worker# 'No handlers could be found for logger "oauth2client.contrib.multistore_file' 89*800a58d9SAndroid Build Coastguard WorkerDEFAULT_STREAM_HANDLER = logging.StreamHandler() 90*800a58d9SAndroid Build Coastguard WorkerDEFAULT_STREAM_HANDLER.setLevel(logging.CRITICAL) 91*800a58d9SAndroid Build Coastguard Workerlogging.getLogger().addHandler(DEFAULT_STREAM_HANDLER) 92*800a58d9SAndroid Build Coastguard Worker 93*800a58d9SAndroid Build Coastguard Worker# pylint: disable=wrong-import-position 94*800a58d9SAndroid Build Coastguard Workerfrom acloud import errors 95*800a58d9SAndroid Build Coastguard Workerfrom acloud.create import create 96*800a58d9SAndroid Build Coastguard Workerfrom acloud.create import create_args 97*800a58d9SAndroid Build Coastguard Workerfrom acloud.delete import delete 98*800a58d9SAndroid Build Coastguard Workerfrom acloud.delete import delete_args 99*800a58d9SAndroid Build Coastguard Workerfrom acloud.internal import constants 100*800a58d9SAndroid Build Coastguard Workerfrom acloud.reconnect import reconnect 101*800a58d9SAndroid Build Coastguard Workerfrom acloud.reconnect import reconnect_args 102*800a58d9SAndroid Build Coastguard Workerfrom acloud.list import list as list_instances 103*800a58d9SAndroid Build Coastguard Workerfrom acloud.list import list_args 104*800a58d9SAndroid Build Coastguard Workerfrom acloud.metrics import metrics 105*800a58d9SAndroid Build Coastguard Workerfrom acloud.powerwash import powerwash 106*800a58d9SAndroid Build Coastguard Workerfrom acloud.powerwash import powerwash_args 107*800a58d9SAndroid Build Coastguard Workerfrom acloud.public import acloud_common 108*800a58d9SAndroid Build Coastguard Workerfrom acloud.public import config 109*800a58d9SAndroid Build Coastguard Workerfrom acloud.public import report 110*800a58d9SAndroid Build Coastguard Workerfrom acloud.public.actions import create_goldfish_action 111*800a58d9SAndroid Build Coastguard Workerfrom acloud.pull import pull 112*800a58d9SAndroid Build Coastguard Workerfrom acloud.pull import pull_args 113*800a58d9SAndroid Build Coastguard Workerfrom acloud.restart import restart 114*800a58d9SAndroid Build Coastguard Workerfrom acloud.restart import restart_args 115*800a58d9SAndroid Build Coastguard Workerfrom acloud.setup import setup 116*800a58d9SAndroid Build Coastguard Workerfrom acloud.setup import setup_args 117*800a58d9SAndroid Build Coastguard Workerfrom acloud.hostcleanup import hostcleanup 118*800a58d9SAndroid Build Coastguard Workerfrom acloud.hostcleanup import hostcleanup_args 119*800a58d9SAndroid Build Coastguard Worker 120*800a58d9SAndroid Build Coastguard Worker 121*800a58d9SAndroid Build Coastguard WorkerLOGGING_FMT = "%(asctime)s |%(levelname)s| %(module)s:%(lineno)s| %(message)s" 122*800a58d9SAndroid Build Coastguard WorkerACLOUD_LOGGER = "acloud" 123*800a58d9SAndroid Build Coastguard Worker_LOGGER = logging.getLogger(ACLOUD_LOGGER) 124*800a58d9SAndroid Build Coastguard WorkerNO_ERROR_MESSAGE = "" 125*800a58d9SAndroid Build Coastguard WorkerPROG = "acloud" 126*800a58d9SAndroid Build Coastguard WorkerDEFAULT_SUPPORT_ARGS = ["--version", "-h", "--help"] 127*800a58d9SAndroid Build Coastguard Worker 128*800a58d9SAndroid Build Coastguard Worker# Commands 129*800a58d9SAndroid Build Coastguard WorkerCMD_CREATE_GOLDFISH = "create_gf" 130*800a58d9SAndroid Build Coastguard Worker 131*800a58d9SAndroid Build Coastguard Worker# Config requires fields. 132*800a58d9SAndroid Build Coastguard Worker_CREATE_REQUIRE_FIELDS = ["project", "zone", "machine_type"] 133*800a58d9SAndroid Build Coastguard Worker# show contact info to user. 134*800a58d9SAndroid Build Coastguard Worker_CONTACT_INFO = ("If you have any question or need acloud team support, " 135*800a58d9SAndroid Build Coastguard Worker "please feel free to contact us by email at " 136*800a58d9SAndroid Build Coastguard Worker "[email protected]") 137*800a58d9SAndroid Build Coastguard Worker_LOG_INFO = " and attach those log files from %s" 138*800a58d9SAndroid Build Coastguard Worker 139*800a58d9SAndroid Build Coastguard Worker 140*800a58d9SAndroid Build Coastguard Worker# pylint: disable=too-many-statements 141*800a58d9SAndroid Build Coastguard Workerdef _ParseArgs(args): 142*800a58d9SAndroid Build Coastguard Worker """Parse args. 143*800a58d9SAndroid Build Coastguard Worker 144*800a58d9SAndroid Build Coastguard Worker Args: 145*800a58d9SAndroid Build Coastguard Worker args: Argument list passed from main. 146*800a58d9SAndroid Build Coastguard Worker 147*800a58d9SAndroid Build Coastguard Worker Returns: 148*800a58d9SAndroid Build Coastguard Worker Parsed args and a list of unknown argument strings. 149*800a58d9SAndroid Build Coastguard Worker """ 150*800a58d9SAndroid Build Coastguard Worker acloud_cmds = [ 151*800a58d9SAndroid Build Coastguard Worker setup_args.CMD_SETUP, 152*800a58d9SAndroid Build Coastguard Worker create_args.CMD_CREATE, 153*800a58d9SAndroid Build Coastguard Worker list_args.CMD_LIST, 154*800a58d9SAndroid Build Coastguard Worker delete_args.CMD_DELETE, 155*800a58d9SAndroid Build Coastguard Worker reconnect_args.CMD_RECONNECT, 156*800a58d9SAndroid Build Coastguard Worker powerwash_args.CMD_POWERWASH, 157*800a58d9SAndroid Build Coastguard Worker pull_args.CMD_PULL, 158*800a58d9SAndroid Build Coastguard Worker restart_args.CMD_RESTART, 159*800a58d9SAndroid Build Coastguard Worker hostcleanup_args.CMD_HOSTCLEANUP, 160*800a58d9SAndroid Build Coastguard Worker CMD_CREATE_GOLDFISH] 161*800a58d9SAndroid Build Coastguard Worker usage = ",".join(acloud_cmds) 162*800a58d9SAndroid Build Coastguard Worker parser = argparse.ArgumentParser( 163*800a58d9SAndroid Build Coastguard Worker description=__doc__, 164*800a58d9SAndroid Build Coastguard Worker formatter_class=argparse.RawDescriptionHelpFormatter, 165*800a58d9SAndroid Build Coastguard Worker usage="acloud {" + usage + "} ...") 166*800a58d9SAndroid Build Coastguard Worker parser = argparse.ArgumentParser(prog=PROG) 167*800a58d9SAndroid Build Coastguard Worker parser.add_argument('--version', action='version', version=( 168*800a58d9SAndroid Build Coastguard Worker '%(prog)s ' + config.GetVersion())) 169*800a58d9SAndroid Build Coastguard Worker subparsers = parser.add_subparsers(metavar="{" + usage + "}") 170*800a58d9SAndroid Build Coastguard Worker subparser_list = [] 171*800a58d9SAndroid Build Coastguard Worker 172*800a58d9SAndroid Build Coastguard Worker # Command "create_gf", create goldfish instances 173*800a58d9SAndroid Build Coastguard Worker # In order to create a goldfish device we need the following parameters: 174*800a58d9SAndroid Build Coastguard Worker # 1. The emulator build we wish to use, this is the binary that emulates 175*800a58d9SAndroid Build Coastguard Worker # an android device. See go/emu-dev for more 176*800a58d9SAndroid Build Coastguard Worker # 2. A system-image. This is the android release we wish to run on the 177*800a58d9SAndroid Build Coastguard Worker # emulated hardware. 178*800a58d9SAndroid Build Coastguard Worker create_gf_parser = subparsers.add_parser(CMD_CREATE_GOLDFISH) 179*800a58d9SAndroid Build Coastguard Worker create_gf_parser.required = False 180*800a58d9SAndroid Build Coastguard Worker create_gf_parser.set_defaults(which=CMD_CREATE_GOLDFISH) 181*800a58d9SAndroid Build Coastguard Worker create_gf_parser.add_argument( 182*800a58d9SAndroid Build Coastguard Worker "--emulator-build-id", 183*800a58d9SAndroid Build Coastguard Worker type=str, 184*800a58d9SAndroid Build Coastguard Worker dest="emulator_build_id", 185*800a58d9SAndroid Build Coastguard Worker required=False, 186*800a58d9SAndroid Build Coastguard Worker help="Emulator build used to run the images. e.g. 4669466.") 187*800a58d9SAndroid Build Coastguard Worker create_gf_parser.add_argument( 188*800a58d9SAndroid Build Coastguard Worker "--emulator-branch", 189*800a58d9SAndroid Build Coastguard Worker type=str, 190*800a58d9SAndroid Build Coastguard Worker dest="emulator_branch", 191*800a58d9SAndroid Build Coastguard Worker required=False, 192*800a58d9SAndroid Build Coastguard Worker help="Emulator build branch name, e.g. aosp-emu-master-dev. If specified" 193*800a58d9SAndroid Build Coastguard Worker " without emulator-build-id, the last green build will be used.") 194*800a58d9SAndroid Build Coastguard Worker create_gf_parser.add_argument( 195*800a58d9SAndroid Build Coastguard Worker "--emulator-build-target", 196*800a58d9SAndroid Build Coastguard Worker dest="emulator_build_target", 197*800a58d9SAndroid Build Coastguard Worker required=False, 198*800a58d9SAndroid Build Coastguard Worker help="Emulator build target used to run the images. e.g. " 199*800a58d9SAndroid Build Coastguard Worker "emulator-linux_x64_nolocationui.") 200*800a58d9SAndroid Build Coastguard Worker create_gf_parser.add_argument( 201*800a58d9SAndroid Build Coastguard Worker "--base-image", 202*800a58d9SAndroid Build Coastguard Worker type=str, 203*800a58d9SAndroid Build Coastguard Worker dest="base_image", 204*800a58d9SAndroid Build Coastguard Worker required=False, 205*800a58d9SAndroid Build Coastguard Worker help="Name of the goldfish base image to be used to create the instance. " 206*800a58d9SAndroid Build Coastguard Worker "This will override stable_goldfish_host_image_name from config. " 207*800a58d9SAndroid Build Coastguard Worker "e.g. emu-dev-cts-061118") 208*800a58d9SAndroid Build Coastguard Worker create_gf_parser.add_argument( 209*800a58d9SAndroid Build Coastguard Worker "--tags", 210*800a58d9SAndroid Build Coastguard Worker dest="tags", 211*800a58d9SAndroid Build Coastguard Worker nargs="*", 212*800a58d9SAndroid Build Coastguard Worker required=False, 213*800a58d9SAndroid Build Coastguard Worker default=None, 214*800a58d9SAndroid Build Coastguard Worker help="Tags to be set on to the created instance. e.g. https-server.") 215*800a58d9SAndroid Build Coastguard Worker # Arguments in old format 216*800a58d9SAndroid Build Coastguard Worker create_gf_parser.add_argument( 217*800a58d9SAndroid Build Coastguard Worker "--emulator_build_id", 218*800a58d9SAndroid Build Coastguard Worker type=str, 219*800a58d9SAndroid Build Coastguard Worker dest="emulator_build_id", 220*800a58d9SAndroid Build Coastguard Worker required=False, 221*800a58d9SAndroid Build Coastguard Worker help=argparse.SUPPRESS) 222*800a58d9SAndroid Build Coastguard Worker create_gf_parser.add_argument( 223*800a58d9SAndroid Build Coastguard Worker "--emulator_branch", 224*800a58d9SAndroid Build Coastguard Worker type=str, 225*800a58d9SAndroid Build Coastguard Worker dest="emulator_branch", 226*800a58d9SAndroid Build Coastguard Worker required=False, 227*800a58d9SAndroid Build Coastguard Worker help=argparse.SUPPRESS) 228*800a58d9SAndroid Build Coastguard Worker create_gf_parser.add_argument( 229*800a58d9SAndroid Build Coastguard Worker "--base_image", 230*800a58d9SAndroid Build Coastguard Worker type=str, 231*800a58d9SAndroid Build Coastguard Worker dest="base_image", 232*800a58d9SAndroid Build Coastguard Worker required=False, 233*800a58d9SAndroid Build Coastguard Worker help=argparse.SUPPRESS) 234*800a58d9SAndroid Build Coastguard Worker 235*800a58d9SAndroid Build Coastguard Worker create_args.AddCommonCreateArgs(create_gf_parser) 236*800a58d9SAndroid Build Coastguard Worker subparser_list.append(create_gf_parser) 237*800a58d9SAndroid Build Coastguard Worker 238*800a58d9SAndroid Build Coastguard Worker # Command "create" 239*800a58d9SAndroid Build Coastguard Worker subparser_list.append(create_args.GetCreateArgParser(subparsers)) 240*800a58d9SAndroid Build Coastguard Worker 241*800a58d9SAndroid Build Coastguard Worker # Command "setup" 242*800a58d9SAndroid Build Coastguard Worker subparser_list.append(setup_args.GetSetupArgParser(subparsers)) 243*800a58d9SAndroid Build Coastguard Worker 244*800a58d9SAndroid Build Coastguard Worker # Command "delete" 245*800a58d9SAndroid Build Coastguard Worker subparser_list.append(delete_args.GetDeleteArgParser(subparsers)) 246*800a58d9SAndroid Build Coastguard Worker 247*800a58d9SAndroid Build Coastguard Worker # Command "list" 248*800a58d9SAndroid Build Coastguard Worker subparser_list.append(list_args.GetListArgParser(subparsers)) 249*800a58d9SAndroid Build Coastguard Worker 250*800a58d9SAndroid Build Coastguard Worker # Command "reconnect" 251*800a58d9SAndroid Build Coastguard Worker subparser_list.append(reconnect_args.GetReconnectArgParser(subparsers)) 252*800a58d9SAndroid Build Coastguard Worker 253*800a58d9SAndroid Build Coastguard Worker # Command "restart" 254*800a58d9SAndroid Build Coastguard Worker subparser_list.append(restart_args.GetRestartArgParser(subparsers)) 255*800a58d9SAndroid Build Coastguard Worker 256*800a58d9SAndroid Build Coastguard Worker # Command "powerwash" 257*800a58d9SAndroid Build Coastguard Worker subparser_list.append(powerwash_args.GetPowerwashArgParser(subparsers)) 258*800a58d9SAndroid Build Coastguard Worker 259*800a58d9SAndroid Build Coastguard Worker # Command "pull" 260*800a58d9SAndroid Build Coastguard Worker subparser_list.append(pull_args.GetPullArgParser(subparsers)) 261*800a58d9SAndroid Build Coastguard Worker 262*800a58d9SAndroid Build Coastguard Worker # Command "hostcleanup" 263*800a58d9SAndroid Build Coastguard Worker subparser_list.append(hostcleanup_args.GetHostcleanupArgParser(subparsers)) 264*800a58d9SAndroid Build Coastguard Worker 265*800a58d9SAndroid Build Coastguard Worker # Add common arguments. 266*800a58d9SAndroid Build Coastguard Worker for subparser in subparser_list: 267*800a58d9SAndroid Build Coastguard Worker acloud_common.AddCommonArguments(subparser) 268*800a58d9SAndroid Build Coastguard Worker 269*800a58d9SAndroid Build Coastguard Worker support_args = acloud_cmds + DEFAULT_SUPPORT_ARGS 270*800a58d9SAndroid Build Coastguard Worker if not args or args[0] not in support_args: 271*800a58d9SAndroid Build Coastguard Worker parser.print_help() 272*800a58d9SAndroid Build Coastguard Worker sys.exit(constants.EXIT_BY_WRONG_CMD) 273*800a58d9SAndroid Build Coastguard Worker 274*800a58d9SAndroid Build Coastguard Worker return parser.parse_known_args(args) 275*800a58d9SAndroid Build Coastguard Worker 276*800a58d9SAndroid Build Coastguard Worker 277*800a58d9SAndroid Build Coastguard Worker# pylint: disable=too-many-branches 278*800a58d9SAndroid Build Coastguard Workerdef _VerifyArgs(parsed_args): 279*800a58d9SAndroid Build Coastguard Worker """Verify args. 280*800a58d9SAndroid Build Coastguard Worker 281*800a58d9SAndroid Build Coastguard Worker Args: 282*800a58d9SAndroid Build Coastguard Worker parsed_args: Parsed args. 283*800a58d9SAndroid Build Coastguard Worker 284*800a58d9SAndroid Build Coastguard Worker Raises: 285*800a58d9SAndroid Build Coastguard Worker errors.CommandArgError: If args are invalid. 286*800a58d9SAndroid Build Coastguard Worker errors.UnsupportedCreateArgs: When a create arg is specified but 287*800a58d9SAndroid Build Coastguard Worker unsupported for a particular avd type. 288*800a58d9SAndroid Build Coastguard Worker (e.g. --system-build-id for gf) 289*800a58d9SAndroid Build Coastguard Worker """ 290*800a58d9SAndroid Build Coastguard Worker if parsed_args.which == create_args.CMD_CREATE: 291*800a58d9SAndroid Build Coastguard Worker create_args.VerifyArgs(parsed_args) 292*800a58d9SAndroid Build Coastguard Worker if parsed_args.which == setup_args.CMD_SETUP: 293*800a58d9SAndroid Build Coastguard Worker setup_args.VerifyArgs(parsed_args) 294*800a58d9SAndroid Build Coastguard Worker if parsed_args.which == CMD_CREATE_GOLDFISH: 295*800a58d9SAndroid Build Coastguard Worker if not parsed_args.emulator_build_id and not parsed_args.build_id and ( 296*800a58d9SAndroid Build Coastguard Worker not parsed_args.emulator_branch and not parsed_args.branch): 297*800a58d9SAndroid Build Coastguard Worker raise errors.CommandArgError( 298*800a58d9SAndroid Build Coastguard Worker "Must specify either --build-id or --branch or " 299*800a58d9SAndroid Build Coastguard Worker "--emulator-branch or --emulator-build-id") 300*800a58d9SAndroid Build Coastguard Worker if not parsed_args.build_target: 301*800a58d9SAndroid Build Coastguard Worker raise errors.CommandArgError("Must specify --build-target") 302*800a58d9SAndroid Build Coastguard Worker if (parsed_args.system_branch 303*800a58d9SAndroid Build Coastguard Worker or parsed_args.system_build_id 304*800a58d9SAndroid Build Coastguard Worker or parsed_args.system_build_target): 305*800a58d9SAndroid Build Coastguard Worker raise errors.UnsupportedCreateArgs( 306*800a58d9SAndroid Build Coastguard Worker "--system-* args are not supported for AVD type: %s" 307*800a58d9SAndroid Build Coastguard Worker % constants.TYPE_GF) 308*800a58d9SAndroid Build Coastguard Worker 309*800a58d9SAndroid Build Coastguard Worker if parsed_args.which in [create_args.CMD_CREATE, CMD_CREATE_GOLDFISH]: 310*800a58d9SAndroid Build Coastguard Worker if (parsed_args.serial_log_file 311*800a58d9SAndroid Build Coastguard Worker and not parsed_args.serial_log_file.endswith(".tar.gz")): 312*800a58d9SAndroid Build Coastguard Worker raise errors.CommandArgError( 313*800a58d9SAndroid Build Coastguard Worker "--serial-log-file must ends with .tar.gz") 314*800a58d9SAndroid Build Coastguard Worker 315*800a58d9SAndroid Build Coastguard Worker 316*800a58d9SAndroid Build Coastguard Workerdef _ValidateAuthFile(cfg): 317*800a58d9SAndroid Build Coastguard Worker """Check if the authentication file exist. 318*800a58d9SAndroid Build Coastguard Worker 319*800a58d9SAndroid Build Coastguard Worker Args: 320*800a58d9SAndroid Build Coastguard Worker cfg: AcloudConfig object. 321*800a58d9SAndroid Build Coastguard Worker """ 322*800a58d9SAndroid Build Coastguard Worker auth_file = os.path.join(os.path.expanduser("~"), cfg.creds_cache_file) 323*800a58d9SAndroid Build Coastguard Worker if not os.path.exists(auth_file): 324*800a58d9SAndroid Build Coastguard Worker print("Notice: Acloud will bring up browser to proceed authentication. " 325*800a58d9SAndroid Build Coastguard Worker "For cloudtop, please run in remote desktop.") 326*800a58d9SAndroid Build Coastguard Worker 327*800a58d9SAndroid Build Coastguard Worker 328*800a58d9SAndroid Build Coastguard Workerdef _ParsingConfig(args, cfg): 329*800a58d9SAndroid Build Coastguard Worker """Parse config to check if missing any field. 330*800a58d9SAndroid Build Coastguard Worker 331*800a58d9SAndroid Build Coastguard Worker Args: 332*800a58d9SAndroid Build Coastguard Worker args: Namespace object from argparse.parse_args. 333*800a58d9SAndroid Build Coastguard Worker cfg: AcloudConfig object. 334*800a58d9SAndroid Build Coastguard Worker 335*800a58d9SAndroid Build Coastguard Worker Returns: 336*800a58d9SAndroid Build Coastguard Worker error message about list of missing config fields. 337*800a58d9SAndroid Build Coastguard Worker """ 338*800a58d9SAndroid Build Coastguard Worker missing_fields = [] 339*800a58d9SAndroid Build Coastguard Worker if (args.which == create_args.CMD_CREATE and 340*800a58d9SAndroid Build Coastguard Worker args.local_instance is None and not args.remote_host): 341*800a58d9SAndroid Build Coastguard Worker missing_fields = cfg.GetMissingFields(_CREATE_REQUIRE_FIELDS) 342*800a58d9SAndroid Build Coastguard Worker if missing_fields: 343*800a58d9SAndroid Build Coastguard Worker return (f"Config file ({config.GetUserConfigPath(args.config_file)}) " 344*800a58d9SAndroid Build Coastguard Worker f"missing required fields: {missing_fields}, please add these " 345*800a58d9SAndroid Build Coastguard Worker "fields or reset config file. For reset config information: " 346*800a58d9SAndroid Build Coastguard Worker "go/acloud-googler-setup#reset-configuration") 347*800a58d9SAndroid Build Coastguard Worker return None 348*800a58d9SAndroid Build Coastguard Worker 349*800a58d9SAndroid Build Coastguard Worker 350*800a58d9SAndroid Build Coastguard Workerdef _SetupLogging(log_file, verbose): 351*800a58d9SAndroid Build Coastguard Worker """Setup logging. 352*800a58d9SAndroid Build Coastguard Worker 353*800a58d9SAndroid Build Coastguard Worker This function define the logging policy in below manners. 354*800a58d9SAndroid Build Coastguard Worker - without -v , -vv ,--log-file: 355*800a58d9SAndroid Build Coastguard Worker Only display critical log and print() message on screen. 356*800a58d9SAndroid Build Coastguard Worker 357*800a58d9SAndroid Build Coastguard Worker - with -v: 358*800a58d9SAndroid Build Coastguard Worker Display INFO log and set StreamHandler to acloud parent logger to turn on 359*800a58d9SAndroid Build Coastguard Worker ONLY acloud modules logging.(silence all 3p libraries) 360*800a58d9SAndroid Build Coastguard Worker 361*800a58d9SAndroid Build Coastguard Worker - with -vv: 362*800a58d9SAndroid Build Coastguard Worker Display INFO/DEBUG log and set StreamHandler to root logger to turn on all 363*800a58d9SAndroid Build Coastguard Worker acloud modules and 3p libraries logging. 364*800a58d9SAndroid Build Coastguard Worker 365*800a58d9SAndroid Build Coastguard Worker - with --log-file. 366*800a58d9SAndroid Build Coastguard Worker Dump logs to FileHandler with DEBUG level. 367*800a58d9SAndroid Build Coastguard Worker 368*800a58d9SAndroid Build Coastguard Worker Args: 369*800a58d9SAndroid Build Coastguard Worker log_file: String, if not None, dump the log to log file. 370*800a58d9SAndroid Build Coastguard Worker verbose: Int, if verbose = 1(-v), log at INFO level and turn on 371*800a58d9SAndroid Build Coastguard Worker logging on libraries to a StreamHandler. 372*800a58d9SAndroid Build Coastguard Worker If verbose = 2(-vv), log at DEBUG level and turn on logging on 373*800a58d9SAndroid Build Coastguard Worker all libraries and 3rd party libraries to a StreamHandler. 374*800a58d9SAndroid Build Coastguard Worker """ 375*800a58d9SAndroid Build Coastguard Worker # Define logging level and hierarchy by verbosity. 376*800a58d9SAndroid Build Coastguard Worker shandler_level = None 377*800a58d9SAndroid Build Coastguard Worker logger = None 378*800a58d9SAndroid Build Coastguard Worker if verbose == 0: 379*800a58d9SAndroid Build Coastguard Worker shandler_level = logging.CRITICAL 380*800a58d9SAndroid Build Coastguard Worker logger = logging.getLogger(ACLOUD_LOGGER) 381*800a58d9SAndroid Build Coastguard Worker elif verbose == 1: 382*800a58d9SAndroid Build Coastguard Worker shandler_level = logging.INFO 383*800a58d9SAndroid Build Coastguard Worker logger = logging.getLogger(ACLOUD_LOGGER) 384*800a58d9SAndroid Build Coastguard Worker elif verbose > 1: 385*800a58d9SAndroid Build Coastguard Worker shandler_level = logging.DEBUG 386*800a58d9SAndroid Build Coastguard Worker logger = logging.getLogger() 387*800a58d9SAndroid Build Coastguard Worker 388*800a58d9SAndroid Build Coastguard Worker # Add StreamHandler by default. 389*800a58d9SAndroid Build Coastguard Worker shandler = logging.StreamHandler() 390*800a58d9SAndroid Build Coastguard Worker shandler.setFormatter(logging.Formatter(LOGGING_FMT)) 391*800a58d9SAndroid Build Coastguard Worker shandler.setLevel(shandler_level) 392*800a58d9SAndroid Build Coastguard Worker logger.addHandler(shandler) 393*800a58d9SAndroid Build Coastguard Worker # Set the default level to DEBUG, the other handlers will handle 394*800a58d9SAndroid Build Coastguard Worker # their own levels via the args supplied (-v and --log-file). 395*800a58d9SAndroid Build Coastguard Worker logger.setLevel(logging.DEBUG) 396*800a58d9SAndroid Build Coastguard Worker 397*800a58d9SAndroid Build Coastguard Worker # Add FileHandler if log_file is provided. 398*800a58d9SAndroid Build Coastguard Worker if log_file: 399*800a58d9SAndroid Build Coastguard Worker fhandler = logging.FileHandler(filename=log_file) 400*800a58d9SAndroid Build Coastguard Worker fhandler.setFormatter(logging.Formatter(LOGGING_FMT)) 401*800a58d9SAndroid Build Coastguard Worker fhandler.setLevel(logging.DEBUG) 402*800a58d9SAndroid Build Coastguard Worker logger.addHandler(fhandler) 403*800a58d9SAndroid Build Coastguard Worker 404*800a58d9SAndroid Build Coastguard Worker 405*800a58d9SAndroid Build Coastguard Workerdef main(argv=None): 406*800a58d9SAndroid Build Coastguard Worker """Main entry. 407*800a58d9SAndroid Build Coastguard Worker 408*800a58d9SAndroid Build Coastguard Worker Args: 409*800a58d9SAndroid Build Coastguard Worker argv: A list of system arguments. 410*800a58d9SAndroid Build Coastguard Worker 411*800a58d9SAndroid Build Coastguard Worker Returns: 412*800a58d9SAndroid Build Coastguard Worker Job status: Integer, 0 if success. None-zero if fails. 413*800a58d9SAndroid Build Coastguard Worker Stack trace: String of errors. 414*800a58d9SAndroid Build Coastguard Worker """ 415*800a58d9SAndroid Build Coastguard Worker args, unknown_args = _ParseArgs(argv) 416*800a58d9SAndroid Build Coastguard Worker _SetupLogging(args.log_file, args.verbose) 417*800a58d9SAndroid Build Coastguard Worker _VerifyArgs(args) 418*800a58d9SAndroid Build Coastguard Worker _LOGGER.info("Acloud version: %s", config.GetVersion()) 419*800a58d9SAndroid Build Coastguard Worker 420*800a58d9SAndroid Build Coastguard Worker cfg = config.GetAcloudConfig(args) 421*800a58d9SAndroid Build Coastguard Worker parsing_config_error = _ParsingConfig(args, cfg) 422*800a58d9SAndroid Build Coastguard Worker _ValidateAuthFile(cfg) 423*800a58d9SAndroid Build Coastguard Worker # TODO: Move this check into the functions it is actually needed. 424*800a58d9SAndroid Build Coastguard Worker # Check access. 425*800a58d9SAndroid Build Coastguard Worker # device_driver.CheckAccess(cfg) 426*800a58d9SAndroid Build Coastguard Worker 427*800a58d9SAndroid Build Coastguard Worker reporter = None 428*800a58d9SAndroid Build Coastguard Worker if parsing_config_error: 429*800a58d9SAndroid Build Coastguard Worker reporter = report.Report(command=args.which) 430*800a58d9SAndroid Build Coastguard Worker reporter.UpdateFailure(parsing_config_error, 431*800a58d9SAndroid Build Coastguard Worker constants.ACLOUD_CONFIG_ERROR) 432*800a58d9SAndroid Build Coastguard Worker elif unknown_args: 433*800a58d9SAndroid Build Coastguard Worker reporter = report.Report(command=args.which) 434*800a58d9SAndroid Build Coastguard Worker reporter.UpdateFailure( 435*800a58d9SAndroid Build Coastguard Worker "unrecognized arguments: %s" % ",".join(unknown_args), 436*800a58d9SAndroid Build Coastguard Worker constants.ACLOUD_UNKNOWN_ARGS_ERROR) 437*800a58d9SAndroid Build Coastguard Worker elif args.which == create_args.CMD_CREATE: 438*800a58d9SAndroid Build Coastguard Worker reporter = create.Run(args) 439*800a58d9SAndroid Build Coastguard Worker elif args.which == CMD_CREATE_GOLDFISH: 440*800a58d9SAndroid Build Coastguard Worker reporter = create_goldfish_action.CreateDevices( 441*800a58d9SAndroid Build Coastguard Worker cfg=cfg, 442*800a58d9SAndroid Build Coastguard Worker build_target=args.build_target, 443*800a58d9SAndroid Build Coastguard Worker branch=args.branch, 444*800a58d9SAndroid Build Coastguard Worker build_id=args.build_id, 445*800a58d9SAndroid Build Coastguard Worker emulator_build_id=args.emulator_build_id, 446*800a58d9SAndroid Build Coastguard Worker emulator_branch=args.emulator_branch, 447*800a58d9SAndroid Build Coastguard Worker emulator_build_target=args.emulator_build_target, 448*800a58d9SAndroid Build Coastguard Worker kernel_build_id=args.kernel_build_id, 449*800a58d9SAndroid Build Coastguard Worker kernel_branch=args.kernel_branch, 450*800a58d9SAndroid Build Coastguard Worker kernel_build_target=args.kernel_build_target, 451*800a58d9SAndroid Build Coastguard Worker gpu=args.gpu, 452*800a58d9SAndroid Build Coastguard Worker num=args.num, 453*800a58d9SAndroid Build Coastguard Worker serial_log_file=args.serial_log_file, 454*800a58d9SAndroid Build Coastguard Worker autoconnect=args.autoconnect, 455*800a58d9SAndroid Build Coastguard Worker tags=args.tags, 456*800a58d9SAndroid Build Coastguard Worker report_internal_ip=args.report_internal_ip, 457*800a58d9SAndroid Build Coastguard Worker boot_timeout_secs=args.boot_timeout_secs) 458*800a58d9SAndroid Build Coastguard Worker elif args.which == delete_args.CMD_DELETE: 459*800a58d9SAndroid Build Coastguard Worker reporter = delete.Run(args) 460*800a58d9SAndroid Build Coastguard Worker elif args.which == list_args.CMD_LIST: 461*800a58d9SAndroid Build Coastguard Worker list_instances.Run(args) 462*800a58d9SAndroid Build Coastguard Worker elif args.which == reconnect_args.CMD_RECONNECT: 463*800a58d9SAndroid Build Coastguard Worker reconnect.Run(args) 464*800a58d9SAndroid Build Coastguard Worker elif args.which == restart_args.CMD_RESTART: 465*800a58d9SAndroid Build Coastguard Worker reporter = restart.Run(args) 466*800a58d9SAndroid Build Coastguard Worker elif args.which == powerwash_args.CMD_POWERWASH: 467*800a58d9SAndroid Build Coastguard Worker reporter = powerwash.Run(args) 468*800a58d9SAndroid Build Coastguard Worker elif args.which == pull_args.CMD_PULL: 469*800a58d9SAndroid Build Coastguard Worker reporter = pull.Run(args) 470*800a58d9SAndroid Build Coastguard Worker elif args.which == setup_args.CMD_SETUP: 471*800a58d9SAndroid Build Coastguard Worker setup.Run(args) 472*800a58d9SAndroid Build Coastguard Worker elif args.which == hostcleanup_args.CMD_HOSTCLEANUP: 473*800a58d9SAndroid Build Coastguard Worker hostcleanup.Run(args) 474*800a58d9SAndroid Build Coastguard Worker else: 475*800a58d9SAndroid Build Coastguard Worker error_msg = "Invalid command %s" % args.which 476*800a58d9SAndroid Build Coastguard Worker sys.stderr.write(error_msg) 477*800a58d9SAndroid Build Coastguard Worker return constants.EXIT_BY_WRONG_CMD, error_msg 478*800a58d9SAndroid Build Coastguard Worker 479*800a58d9SAndroid Build Coastguard Worker if reporter and args.report_file: 480*800a58d9SAndroid Build Coastguard Worker reporter.Dump(args.report_file) 481*800a58d9SAndroid Build Coastguard Worker if reporter and reporter.errors: 482*800a58d9SAndroid Build Coastguard Worker error_msg = "\n".join(reporter.errors) 483*800a58d9SAndroid Build Coastguard Worker help_msg = _CONTACT_INFO 484*800a58d9SAndroid Build Coastguard Worker if reporter.data.get(constants.ERROR_LOG_FOLDER): 485*800a58d9SAndroid Build Coastguard Worker help_msg += _LOG_INFO % reporter.data.get(constants.ERROR_LOG_FOLDER) 486*800a58d9SAndroid Build Coastguard Worker sys.stderr.write("Encountered the following errors:\n%s\n\n%s.\n" % 487*800a58d9SAndroid Build Coastguard Worker (error_msg, help_msg)) 488*800a58d9SAndroid Build Coastguard Worker return constants.EXIT_BY_FAIL_REPORT, error_msg 489*800a58d9SAndroid Build Coastguard Worker return constants.EXIT_SUCCESS, NO_ERROR_MESSAGE 490*800a58d9SAndroid Build Coastguard Worker 491*800a58d9SAndroid Build Coastguard Worker 492*800a58d9SAndroid Build Coastguard Workerif __name__ == "__main__": 493*800a58d9SAndroid Build Coastguard Worker EXIT_CODE = None 494*800a58d9SAndroid Build Coastguard Worker EXCEPTION_STACKTRACE = None 495*800a58d9SAndroid Build Coastguard Worker EXCEPTION_LOG = None 496*800a58d9SAndroid Build Coastguard Worker LOG_METRICS = metrics.LogUsage(sys.argv[1:]) 497*800a58d9SAndroid Build Coastguard Worker try: 498*800a58d9SAndroid Build Coastguard Worker EXIT_CODE, EXCEPTION_STACKTRACE = main(sys.argv[1:]) 499*800a58d9SAndroid Build Coastguard Worker except Exception as e: 500*800a58d9SAndroid Build Coastguard Worker EXIT_CODE = constants.EXIT_BY_ERROR 501*800a58d9SAndroid Build Coastguard Worker EXCEPTION_STACKTRACE = traceback.format_exc() 502*800a58d9SAndroid Build Coastguard Worker EXCEPTION_LOG = str(e) 503*800a58d9SAndroid Build Coastguard Worker sys.stderr.write("Exception: %s" % (EXCEPTION_STACKTRACE)) 504*800a58d9SAndroid Build Coastguard Worker 505*800a58d9SAndroid Build Coastguard Worker # Log Exit event here to calculate the consuming time. 506*800a58d9SAndroid Build Coastguard Worker if LOG_METRICS: 507*800a58d9SAndroid Build Coastguard Worker metrics.LogExitEvent(EXIT_CODE, 508*800a58d9SAndroid Build Coastguard Worker stacktrace=EXCEPTION_STACKTRACE, 509*800a58d9SAndroid Build Coastguard Worker logs=EXCEPTION_LOG) 510*800a58d9SAndroid Build Coastguard Worker sys.exit(EXIT_CODE) 511