blob: ac6302939d140540a62a8e9f9a0a00d82bbe25c3 [file] [log] [blame]
Keun Soo Yimb293fdb2016-09-21 16:03:44 -07001#!/usr/bin/env python
2#
3# Copyright 2016 - The Android Open Source Project
4#
5# Licensed under the Apache License, Version 2.0 (the "License");
6# you may not use this file except in compliance with the License.
7# You may obtain a copy of the License at
8#
9# http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS,
13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14# See the License for the specific language governing permissions and
15# limitations under the License.
Sam Chiu42ac7c52018-10-22 12:27:34 +080016r"""
17Welcome to
18 ___ _______ ____ __ _____
19 / _ |/ ___/ / / __ \/ / / / _ \
20 / __ / /__/ /__/ /_/ / /_/ / // /
21/_/ |_\___/____/\____/\____/____/
Keun Soo Yimb293fdb2016-09-21 16:03:44 -070022
Sam Chiu42ac7c52018-10-22 12:27:34 +080023
24This a tool to create Android Virtual Devices locally/remotely.
Keun Soo Yimb293fdb2016-09-21 16:03:44 -070025
26- Prerequisites:
Sam Chiu42ac7c52018-10-22 12:27:34 +080027 The manual will be available at
28 https://android.googlesource.com/platform/tools/acloud/+/master/README.md
Keun Soo Yimb293fdb2016-09-21 16:03:44 -070029
Sam Chiu42ac7c52018-10-22 12:27:34 +080030- To get started:
31 - Create instances:
32 1) To create a remote cuttlefish instance with the local built image.
33 Example:
chojoyce1c4ecc92018-12-06 14:16:44 +080034 $ acloud create --local-image
35 Or specify built image dir:
36 $ acloud create --local-image /tmp/image_dir
Sam Chiu42ac7c52018-10-22 12:27:34 +080037 2) To create a local cuttlefish instance using the image which has been
38 built out in your workspace.
39 Example:
40 $ acloud create --local-instance --local-image
Keun Soo Yimb293fdb2016-09-21 16:03:44 -070041
Sam Chiu42ac7c52018-10-22 12:27:34 +080042 - Delete instances:
43 $ acloud delete
Keun Soo Yimb293fdb2016-09-21 16:03:44 -070044
Sam Chiua263b9e2019-08-08 13:52:54 +080045 - Reconnect:
46 To reconnect adb/vnc to an existing instance that's been disconnected:
47 $ acloud reconnect
48 Or to specify a specific instance:
49 $ acloud reconnect --instance-names <instance_name like ins-123-cf-x86-phone>
50
51 - List:
52 List will retrieve all the remote instances you've created in addition to any
53 local instances created as well.
54 To show device IP address, adb port and instance name:
55 $ acloud list
56 To show more detail info on the list.
57 $ acloud list -vv
58
herbertxue2904a682019-10-25 11:33:55 +080059- Pull:
60 Pull will download log files or show the log file in screen from one remote
61 cuttlefish instance:
62 $ acloud pull
63 Pull from a specified instance:
64 $ acloud pull --instance-name "your_instance_name"
65
Sam Chiu42ac7c52018-10-22 12:27:34 +080066Try $acloud [cmd] --help for further details.
Keun Soo Yimb293fdb2016-09-21 16:03:44 -070067
Keun Soo Yimb293fdb2016-09-21 16:03:44 -070068"""
Kevin Cheng1ea015f2019-01-08 09:10:58 -080069
70from __future__ import print_function
Keun Soo Yimb293fdb2016-09-21 16:03:44 -070071import argparse
Keun Soo Yimb293fdb2016-09-21 16:03:44 -070072import logging
chojoyce2a82d302019-12-24 18:13:36 +080073import os
Kevin Cheng1ea015f2019-01-08 09:10:58 -080074import platform
Keun Soo Yimb293fdb2016-09-21 16:03:44 -070075import sys
chojoyce2a82d302019-12-24 18:13:36 +080076import sysconfig
Sam Chiue791f602019-05-03 15:18:10 +080077import traceback
Keun Soo Yimb293fdb2016-09-21 16:03:44 -070078
Kevin Cheng1ea015f2019-01-08 09:10:58 -080079# TODO: Remove this once we switch over to embedded launcher.
80# Exit out if python version is < 2.7.13 due to b/120883119.
81if (sys.version_info.major == 2
82 and sys.version_info.minor == 7
83 and sys.version_info.micro < 13):
84 print("Acloud requires python version 2.7.13+ (currently @ %d.%d.%d)" %
85 (sys.version_info.major, sys.version_info.minor,
86 sys.version_info.micro))
87 print("Update your 2.7 python with:")
88 # pylint: disable=invalid-name
89 os_type = platform.system().lower()
90 if os_type == "linux":
91 print(" apt-get install python2.7")
92 elif os_type == "darwin":
93 print(" brew install python@2 (and then follow instructions at "
94 "https://docs.python-guide.org/starting/install/osx/)")
95 print(" - or -")
96 print(" POSIXLY_CORRECT=1 port -N install python27")
97 sys.exit(1)
chojoyce2a82d302019-12-24 18:13:36 +080098# This is a workaround to put '/usr/lib/python3.X' ahead of googleapiclient of
99# build system path list to fix python3 issue of http.client(b/144743252)
100# that googleapiclient existed http.py conflict with python3 build-in lib.
101# Using embedded_launcher(b/135639220) perhaps work whereas it didn't solve yet.
102if sys.version_info.major == 3:
103 sys.path.insert(0, os.path.dirname(sysconfig.get_paths()['purelib']))
Kevin Cheng1ea015f2019-01-08 09:10:58 -0800104
Sam Chiue791f602019-05-03 15:18:10 +0800105# By Default silence root logger's stream handler since 3p lib may initial
106# root logger no matter what level we're using. The acloud logger behavior will
107# be defined in _SetupLogging(). This also could workaround to get rid of below
108# oauth2client warning:
Sam Chiu29d858f2018-08-14 20:06:25 +0800109# 'No handlers could be found for logger "oauth2client.contrib.multistore_file'
Sam Chiue791f602019-05-03 15:18:10 +0800110DEFAULT_STREAM_HANDLER = logging.StreamHandler()
111DEFAULT_STREAM_HANDLER.setLevel(logging.CRITICAL)
112logging.getLogger().addHandler(DEFAULT_STREAM_HANDLER)
Kevin Chengb5963882018-05-09 00:06:27 -0700113
Kevin Chengf4137c62018-05-22 16:06:58 -0700114# pylint: disable=wrong-import-position
Sam Chiu7de3b232018-12-06 19:45:52 +0800115from acloud import errors
Kevin Cheng6001db32018-10-23 12:34:20 -0700116from acloud.create import create
117from acloud.create import create_args
118from acloud.delete import delete
119from acloud.delete import delete_args
Sam Chiue791f602019-05-03 15:18:10 +0800120from acloud.internal import constants
cylan4569dca2018-11-02 12:12:53 +0800121from acloud.reconnect import reconnect
122from acloud.reconnect import reconnect_args
Sam Chiu56c58892018-10-25 09:53:19 +0800123from acloud.list import list as list_instances
124from acloud.list import list_args
Kevin Cheng6001db32018-10-23 12:34:20 -0700125from acloud.metrics import metrics
Keun Soo Yimb293fdb2016-09-21 16:03:44 -0700126from acloud.public import acloud_common
127from acloud.public import config
Kevin Chengb5963882018-05-09 00:06:27 -0700128from acloud.public.actions import create_cuttlefish_action
129from acloud.public.actions import create_goldfish_action
herbertxue61bfd972019-09-24 15:51:52 +0800130from acloud.pull import pull
131from acloud.pull import pull_args
Kevin Chengee6030f2018-06-26 10:55:30 -0700132from acloud.setup import setup
133from acloud.setup import setup_args
Keun Soo Yimb293fdb2016-09-21 16:03:44 -0700134
herbertxue1512f8a2019-06-27 13:56:23 +0800135
Sam Chiu445941f2018-10-04 11:54:40 +0800136LOGGING_FMT = "%(asctime)s |%(levelname)s| %(module)s:%(lineno)s| %(message)s"
Sam Chiu29d858f2018-08-14 20:06:25 +0800137ACLOUD_LOGGER = "acloud"
herbertxue14a98d82020-01-06 20:22:48 +0800138NO_ERROR_MESSAGE = ""
cylan9af14692020-02-21 18:11:35 +0800139PROG = "acloud"
Keun Soo Yimb293fdb2016-09-21 16:03:44 -0700140
141# Commands
Kevin Chengb5963882018-05-09 00:06:27 -0700142CMD_CREATE_CUTTLEFISH = "create_cf"
143CMD_CREATE_GOLDFISH = "create_gf"
Keun Soo Yimb293fdb2016-09-21 16:03:44 -0700144
145
Kevin Cheng3031f8a2018-05-16 13:21:51 -0700146# pylint: disable=too-many-statements
Keun Soo Yimb293fdb2016-09-21 16:03:44 -0700147def _ParseArgs(args):
148 """Parse args.
149
150 Args:
151 args: Argument list passed from main.
152
153 Returns:
154 Parsed args.
155 """
Kevin Cheng3031f8a2018-05-16 13:21:51 -0700156 usage = ",".join([
Sam Chiue669ef72018-10-16 16:23:37 +0800157 setup_args.CMD_SETUP,
158 create_args.CMD_CREATE,
Sam Chiu56c58892018-10-25 09:53:19 +0800159 list_args.CMD_LIST,
Kevin Chengeb85e862018-10-09 15:35:13 -0700160 delete_args.CMD_DELETE,
cylan4569dca2018-11-02 12:12:53 +0800161 reconnect_args.CMD_RECONNECT,
herbertxue61bfd972019-09-24 15:51:52 +0800162 pull_args.CMD_PULL,
Kevin Cheng3031f8a2018-05-16 13:21:51 -0700163 ])
Keun Soo Yimb293fdb2016-09-21 16:03:44 -0700164 parser = argparse.ArgumentParser(
165 description=__doc__,
166 formatter_class=argparse.RawDescriptionHelpFormatter,
Sam Chiu42ac7c52018-10-22 12:27:34 +0800167 usage="acloud {" + usage + "} ...")
cylan9af14692020-02-21 18:11:35 +0800168 parser = argparse.ArgumentParser(prog=PROG)
169 parser.add_argument('--version', action='version', version=(
170 '%(prog)s ' + config.GetVersion()))
Kevin Cheng6bd8d132019-02-25 23:00:38 -0800171 subparsers = parser.add_subparsers(metavar="{" + usage + "}")
Keun Soo Yimb293fdb2016-09-21 16:03:44 -0700172 subparser_list = []
173
Kevin Chengb5963882018-05-09 00:06:27 -0700174 # Command "create_cf", create cuttlefish instances
175 create_cf_parser = subparsers.add_parser(CMD_CREATE_CUTTLEFISH)
176 create_cf_parser.required = False
177 create_cf_parser.set_defaults(which=CMD_CREATE_CUTTLEFISH)
Sam Chiu4f398b72020-03-04 20:43:04 +0800178 create_cf_parser.add_argument(
179 "--num-avds-per-instance",
180 type=int,
181 dest="num_avds_per_instance",
182 required=False,
183 default=1,
184 help="Number of devices to create on a gce instance.")
Kevin Cheng3087af52018-08-13 13:26:50 -0700185 create_args.AddCommonCreateArgs(create_cf_parser)
Kevin Chengb5963882018-05-09 00:06:27 -0700186 subparser_list.append(create_cf_parser)
187
188 # Command "create_gf", create goldfish instances
189 # In order to create a goldfish device we need the following parameters:
190 # 1. The emulator build we wish to use, this is the binary that emulates
191 # an android device. See go/emu-dev for more
192 # 2. A system-image. This is the android release we wish to run on the
193 # emulated hardware.
194 create_gf_parser = subparsers.add_parser(CMD_CREATE_GOLDFISH)
195 create_gf_parser.required = False
196 create_gf_parser.set_defaults(which=CMD_CREATE_GOLDFISH)
197 create_gf_parser.add_argument(
Kevin Chengb5963882018-05-09 00:06:27 -0700198 "--emulator_build_id",
199 type=str,
200 dest="emulator_build_id",
201 required=False,
202 help="Emulator build used to run the images. e.g. 4669466.")
203 create_gf_parser.add_argument(
Kevin Cheng85187b72019-06-04 15:38:45 -0700204 "--emulator_branch",
205 type=str,
206 dest="emulator_branch",
207 required=False,
208 help="Emulator build branch name, e.g. aosp-emu-master-dev. If specified"
209 " without emulator_build_id, the last green build will be used.")
210 create_gf_parser.add_argument(
Kevin Chengbced4af2018-06-26 10:35:01 -0700211 "--base_image",
212 type=str,
213 dest="base_image",
214 required=False,
215 help="Name of the goldfish base image to be used to create the instance. "
216 "This will override stable_goldfish_host_image_name from config. "
217 "e.g. emu-dev-cts-061118")
Erwin Jansenf39798d2019-05-14 21:06:44 -0700218 create_gf_parser.add_argument(
219 "--tags",
220 dest="tags",
221 nargs="*",
222 required=False,
223 default=None,
224 help="Tags to be set on to the created instance. e.g. https-server.")
Kevin Chengb5963882018-05-09 00:06:27 -0700225
Kevin Cheng3087af52018-08-13 13:26:50 -0700226 create_args.AddCommonCreateArgs(create_gf_parser)
Kevin Chengb5963882018-05-09 00:06:27 -0700227 subparser_list.append(create_gf_parser)
228
Kevin Chengeb85e862018-10-09 15:35:13 -0700229 # Command "create"
230 subparser_list.append(create_args.GetCreateArgParser(subparsers))
231
Kevin Chengee6030f2018-06-26 10:55:30 -0700232 # Command "setup"
233 subparser_list.append(setup_args.GetSetupArgParser(subparsers))
234
Sam Chiu56c58892018-10-25 09:53:19 +0800235 # Command "delete"
Kevin Chengeb85e862018-10-09 15:35:13 -0700236 subparser_list.append(delete_args.GetDeleteArgParser(subparsers))
237
Sam Chiu56c58892018-10-25 09:53:19 +0800238 # Command "list"
239 subparser_list.append(list_args.GetListArgParser(subparsers))
240
herbertxue61bfd972019-09-24 15:51:52 +0800241 # Command "reconnect"
cylan4569dca2018-11-02 12:12:53 +0800242 subparser_list.append(reconnect_args.GetReconnectArgParser(subparsers))
243
herbertxue61bfd972019-09-24 15:51:52 +0800244 # Command "pull"
245 subparser_list.append(pull_args.GetPullArgParser(subparsers))
246
Keun Soo Yimb293fdb2016-09-21 16:03:44 -0700247 # Add common arguments.
Kevin Chengb21d7712018-05-24 14:54:55 -0700248 for subparser in subparser_list:
249 acloud_common.AddCommonArguments(subparser)
Keun Soo Yimb293fdb2016-09-21 16:03:44 -0700250
251 return parser.parse_args(args)
252
253
herbertxue2625b042018-08-16 23:28:20 +0800254# pylint: disable=too-many-branches
Keun Soo Yimb293fdb2016-09-21 16:03:44 -0700255def _VerifyArgs(parsed_args):
256 """Verify args.
257
258 Args:
259 parsed_args: Parsed args.
260
261 Raises:
262 errors.CommandArgError: If args are invalid.
herbertxue23b2a962019-07-24 22:39:20 +0800263 errors.UnsupportedCreateArgs: When a create arg is specified but
264 unsupported for a particular avd type.
265 (e.g. --system-build-id for gf)
Keun Soo Yimb293fdb2016-09-21 16:03:44 -0700266 """
herbertxue2625b042018-08-16 23:28:20 +0800267 if parsed_args.which == create_args.CMD_CREATE:
268 create_args.VerifyArgs(parsed_args)
Kevin Cheng84d3eed2018-08-16 15:16:00 -0700269 if parsed_args.which == CMD_CREATE_CUTTLEFISH:
Kevin Chengd1671ce2019-07-23 01:13:52 -0700270 if not parsed_args.build_id and not parsed_args.branch:
Kevin Cheng3031f8a2018-05-16 13:21:51 -0700271 raise errors.CommandArgError(
Kevin Chengd1671ce2019-07-23 01:13:52 -0700272 "Must specify --build_id or --branch")
Kevin Chengb5963882018-05-09 00:06:27 -0700273 if parsed_args.which == CMD_CREATE_GOLDFISH:
Kevin Cheng85187b72019-06-04 15:38:45 -0700274 if not parsed_args.emulator_build_id and not parsed_args.build_id and (
275 not parsed_args.emulator_branch and not parsed_args.branch):
276 raise errors.CommandArgError(
277 "Must specify either --build_id or --branch or "
278 "--emulator_branch or --emulator_build_id")
Kevin Cheng84d3eed2018-08-16 15:16:00 -0700279 if not parsed_args.build_target:
280 raise errors.CommandArgError("Must specify --build_target")
herbertxue23b2a962019-07-24 22:39:20 +0800281 if (parsed_args.system_branch
282 or parsed_args.system_build_id
283 or parsed_args.system_build_target):
284 raise errors.UnsupportedCreateArgs(
285 "--system-* args are not supported for AVD type: %s"
286 % constants.TYPE_GF)
Kevin Chengb5963882018-05-09 00:06:27 -0700287
288 if parsed_args.which in [
Kevin Cheng3087af52018-08-13 13:26:50 -0700289 create_args.CMD_CREATE, CMD_CREATE_CUTTLEFISH, CMD_CREATE_GOLDFISH
Kevin Chengb5963882018-05-09 00:06:27 -0700290 ]:
Kevin Cheng3031f8a2018-05-16 13:21:51 -0700291 if (parsed_args.serial_log_file
292 and not parsed_args.serial_log_file.endswith(".tar.gz")):
Keun Soo Yimb293fdb2016-09-21 16:03:44 -0700293 raise errors.CommandArgError(
294 "--serial_log_file must ends with .tar.gz")
Keun Soo Yimb293fdb2016-09-21 16:03:44 -0700295
296
Sam Chiu29d858f2018-08-14 20:06:25 +0800297def _SetupLogging(log_file, verbose):
Keun Soo Yimb293fdb2016-09-21 16:03:44 -0700298 """Setup logging.
299
Sam Chiu29d858f2018-08-14 20:06:25 +0800300 This function define the logging policy in below manners.
301 - without -v , -vv ,--log_file:
302 Only display critical log and print() message on screen.
303
304 - with -v:
305 Display INFO log and set StreamHandler to acloud parent logger to turn on
306 ONLY acloud modules logging.(silence all 3p libraries)
307
308 - with -vv:
309 Display INFO/DEBUG log and set StreamHandler to root logger to turn on all
310 acloud modules and 3p libraries logging.
311
312 - with --log_file.
313 Dump logs to FileHandler with DEBUG level.
314
Keun Soo Yimb293fdb2016-09-21 16:03:44 -0700315 Args:
Sam Chiu29d858f2018-08-14 20:06:25 +0800316 log_file: String, if not None, dump the log to log file.
317 verbose: Int, if verbose = 1(-v), log at INFO level and turn on
318 logging on libraries to a StreamHandler.
319 If verbose = 2(-vv), log at DEBUG level and turn on logging on
320 all libraries and 3rd party libraries to a StreamHandler.
Keun Soo Yimb293fdb2016-09-21 16:03:44 -0700321 """
Sam Chiu29d858f2018-08-14 20:06:25 +0800322 # Define logging level and hierarchy by verbosity.
323 shandler_level = None
324 logger = None
325 if verbose == 0:
326 shandler_level = logging.CRITICAL
327 logger = logging.getLogger(ACLOUD_LOGGER)
328 elif verbose == 1:
329 shandler_level = logging.INFO
330 logger = logging.getLogger(ACLOUD_LOGGER)
331 elif verbose > 1:
332 shandler_level = logging.DEBUG
Keun Soo Yimb293fdb2016-09-21 16:03:44 -0700333 logger = logging.getLogger()
Keun Soo Yimb293fdb2016-09-21 16:03:44 -0700334
Sam Chiu29d858f2018-08-14 20:06:25 +0800335 # Add StreamHandler by default.
336 shandler = logging.StreamHandler()
337 shandler.setFormatter(logging.Formatter(LOGGING_FMT))
338 shandler.setLevel(shandler_level)
339 logger.addHandler(shandler)
340 # Set the default level to DEBUG, the other handlers will handle
341 # their own levels via the args supplied (-v and --log_file).
342 logger.setLevel(logging.DEBUG)
Keun Soo Yimb293fdb2016-09-21 16:03:44 -0700343
Sam Chiu29d858f2018-08-14 20:06:25 +0800344 # Add FileHandler if log_file is provided.
Sam Chiufde41e92018-08-07 18:37:02 +0800345 if log_file:
Sam Chiu29d858f2018-08-14 20:06:25 +0800346 fhandler = logging.FileHandler(filename=log_file)
347 fhandler.setFormatter(logging.Formatter(LOGGING_FMT))
348 fhandler.setLevel(logging.DEBUG)
349 logger.addHandler(fhandler)
Keun Soo Yimb293fdb2016-09-21 16:03:44 -0700350
351
Erwin Jansen95559242018-11-08 15:38:18 -0800352def main(argv=None):
Keun Soo Yimb293fdb2016-09-21 16:03:44 -0700353 """Main entry.
354
355 Args:
356 argv: A list of system arguments.
357
358 Returns:
herbertxue14a98d82020-01-06 20:22:48 +0800359 Job status: Integer, 0 if success. None-zero if fails.
360 Stack trace: String of errors.
Keun Soo Yimb293fdb2016-09-21 16:03:44 -0700361 """
Erwin Jansen95559242018-11-08 15:38:18 -0800362 if argv is None:
363 argv = sys.argv[1:]
364
Keun Soo Yimb293fdb2016-09-21 16:03:44 -0700365 args = _ParseArgs(argv)
Sam Chiu29d858f2018-08-14 20:06:25 +0800366 _SetupLogging(args.log_file, args.verbose)
Keun Soo Yimb293fdb2016-09-21 16:03:44 -0700367 _VerifyArgs(args)
368
cylan9af14692020-02-21 18:11:35 +0800369 if args.verbose:
370 print("%s %s" % (PROG, config.GetVersion()))
371
Sam Chiuc64f3432018-08-17 11:19:06 +0800372 cfg = config.GetAcloudConfig(args)
Kevin Cheng3087af52018-08-13 13:26:50 -0700373 # TODO: Move this check into the functions it is actually needed.
Fang Dengcef4b112017-03-02 11:20:17 -0800374 # Check access.
Kevin Cheng3087af52018-08-13 13:26:50 -0700375 # device_driver.CheckAccess(cfg)
Fang Dengcef4b112017-03-02 11:20:17 -0800376
Kevin Chengee6030f2018-06-26 10:55:30 -0700377 report = None
chojoyce7a361732018-11-26 16:26:13 +0800378 if args.which == create_args.CMD_CREATE:
herbertxue48bba082019-12-31 12:12:16 +0800379 report = create.Run(args)
Kevin Chengb5963882018-05-09 00:06:27 -0700380 elif args.which == CMD_CREATE_CUTTLEFISH:
381 report = create_cuttlefish_action.CreateDevices(
382 cfg=cfg,
383 build_target=args.build_target,
384 build_id=args.build_id,
Kevin Cheng81d43952019-06-07 11:37:45 -0700385 branch=args.branch,
Kevin Chengb5963882018-05-09 00:06:27 -0700386 kernel_build_id=args.kernel_build_id,
Kevin Chengcf5bbf52019-05-09 16:17:08 -0700387 kernel_branch=args.kernel_branch,
Kevin Cheng85987fc2019-06-19 10:51:21 -0700388 kernel_build_target=args.kernel_build_target,
Kevin Cheng4eeb9d42019-06-05 10:17:18 -0700389 system_branch=args.system_branch,
390 system_build_id=args.system_build_id,
391 system_build_target=args.system_build_target,
herbertxue9a651d62020-01-08 21:58:34 +0800392 gpu=args.gpu,
Kevin Chengb5963882018-05-09 00:06:27 -0700393 num=args.num,
394 serial_log_file=args.serial_log_file,
Kevin Cheng86d43c72018-08-30 10:59:14 -0700395 autoconnect=args.autoconnect,
cylanbab76b12019-07-16 16:36:39 +0800396 report_internal_ip=args.report_internal_ip,
herbertxue40e7efb2019-12-13 11:47:24 +0800397 boot_timeout_secs=args.boot_timeout_secs,
398 ins_timeout_secs=args.ins_timeout_secs)
Kevin Chengb5963882018-05-09 00:06:27 -0700399 elif args.which == CMD_CREATE_GOLDFISH:
400 report = create_goldfish_action.CreateDevices(
401 cfg=cfg,
402 build_target=args.build_target,
403 build_id=args.build_id,
404 emulator_build_id=args.emulator_build_id,
Kevin Cheng85187b72019-06-04 15:38:45 -0700405 branch=args.branch,
406 emulator_branch=args.emulator_branch,
Kevin Cheng7be06d62019-06-14 16:00:15 -0700407 kernel_build_id=args.kernel_build_id,
408 kernel_branch=args.kernel_branch,
Roman Kiryanov9118bb62019-11-06 14:41:23 -0800409 kernel_build_target=args.kernel_build_target,
Kevin Chengb5963882018-05-09 00:06:27 -0700410 gpu=args.gpu,
411 num=args.num,
412 serial_log_file=args.serial_log_file,
Kevin Cheng84d3eed2018-08-16 15:16:00 -0700413 autoconnect=args.autoconnect,
Erwin Jansenf39798d2019-05-14 21:06:44 -0700414 tags=args.tags,
Kevin Cheng86d43c72018-08-30 10:59:14 -0700415 report_internal_ip=args.report_internal_ip)
Sam Chiu56c58892018-10-25 09:53:19 +0800416 elif args.which == delete_args.CMD_DELETE:
Kevin Chengeb85e862018-10-09 15:35:13 -0700417 report = delete.Run(args)
Sam Chiu56c58892018-10-25 09:53:19 +0800418 elif args.which == list_args.CMD_LIST:
419 list_instances.Run(args)
cylan4569dca2018-11-02 12:12:53 +0800420 elif args.which == reconnect_args.CMD_RECONNECT:
421 reconnect.Run(args)
herbertxue61bfd972019-09-24 15:51:52 +0800422 elif args.which == pull_args.CMD_PULL:
423 report = pull.Run(args)
Kevin Chengee6030f2018-06-26 10:55:30 -0700424 elif args.which == setup_args.CMD_SETUP:
herbertxue34776bb2018-07-03 21:57:48 +0800425 setup.Run(args)
Keun Soo Yimb293fdb2016-09-21 16:03:44 -0700426 else:
herbertxue14a98d82020-01-06 20:22:48 +0800427 error_msg = "Invalid command %s" % args.which
428 sys.stderr.write(error_msg)
429 return constants.EXIT_BY_WRONG_CMD, error_msg
Keun Soo Yimb293fdb2016-09-21 16:03:44 -0700430
herbertxue07293a32018-11-05 20:40:11 +0800431 if report and args.report_file:
Kevin Chengee6030f2018-06-26 10:55:30 -0700432 report.Dump(args.report_file)
herbertxuea639fae2019-12-10 16:26:22 +0800433 if report and report.errors:
herbertxue14a98d82020-01-06 20:22:48 +0800434 error_msg = "\n".join(report.errors)
435 sys.stderr.write("Encountered the following errors:\n%s\n" % error_msg)
436 return constants.EXIT_BY_FAIL_REPORT, error_msg
437 return constants.EXIT_SUCCESS, NO_ERROR_MESSAGE
Tri Vo8e292532016-10-01 16:55:51 -0700438
439
440if __name__ == "__main__":
Sam Chiue791f602019-05-03 15:18:10 +0800441 EXIT_CODE = None
442 EXCEPTION_STACKTRACE = None
443 EXCEPTION_LOG = None
Sam Chiu37b1ee32019-06-20 10:49:56 +0800444 LOG_METRICS = metrics.LogUsage(sys.argv[1:])
Sam Chiue791f602019-05-03 15:18:10 +0800445 try:
herbertxue14a98d82020-01-06 20:22:48 +0800446 EXIT_CODE, EXCEPTION_STACKTRACE = main(sys.argv[1:])
Sam Chiue791f602019-05-03 15:18:10 +0800447 except Exception as e:
448 EXIT_CODE = constants.EXIT_BY_ERROR
449 EXCEPTION_STACKTRACE = traceback.format_exc()
450 EXCEPTION_LOG = str(e)
451 raise
452 finally:
453 # Log Exit event here to calculate the consuming time.
Sam Chiu37b1ee32019-06-20 10:49:56 +0800454 if LOG_METRICS:
455 metrics.LogExitEvent(EXIT_CODE,
456 stacktrace=EXCEPTION_STACKTRACE,
457 logs=EXCEPTION_LOG)