blob: b8a137c83e9ed89509956414e60838b9fa2b8ed5 [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.
Fang Dengfed6a6f2017-03-01 18:27:28 -080016r"""Cloud Android Driver.
Keun Soo Yimb293fdb2016-09-21 16:03:44 -070017
18This CLI manages google compute engine project for android devices.
19
20- Prerequisites:
21 See: go/acloud-manual
22
23- Configuration:
24 The script takes a required configuration file, which should look like
25 <Start of the file>
26 # If using service account
27 service_account_name: "your_account@developer.gserviceaccount.com"
28 service_account_private_key_path: "/path/to/your-project.p12"
xingdai8a00d462018-07-30 14:24:48 -070029 # Or
30 service_account_json_private_key_path: "/path/to/your-project.json"
Keun Soo Yimb293fdb2016-09-21 16:03:44 -070031
32 # If using OAuth2 authentication flow
33 client_id: <client id created in the project>
34 client_secret: <client secret for the client id>
35
36 # Optional
Fang Deng69498c32017-03-02 14:29:30 -080037 ssh_private_key_path: "~/.ssh/acloud_rsa"
38 ssh_public_key_path: "~/.ssh/acloud_rsa.pub"
Keun Soo Yimb293fdb2016-09-21 16:03:44 -070039 orientation: "portrait"
40 resolution: "800x1280x32x213"
41 network: "default"
42 machine_type: "n1-standard-1"
43 extra_data_disk_size_gb: 10 # 4G or 10G
44
45 # Required
46 project: "your-project"
47 zone: "us-central1-f"
48 storage_bucket_name: "your_google_storage_bucket_name"
49 <End of the file>
50
51 Save it at /path/to/acloud.config
52
53- Example calls:
54 - Create two instances:
Kevin Chengb5963882018-05-09 00:06:27 -070055 $ acloud.par create_cf
56 --build_target aosp_cf_x86_phone-userdebug \
Fang Dengfed6a6f2017-03-01 18:27:28 -080057 --build_id 3744001 --num 2 --config_file /path/to/acloud.config \
Keun Soo Yimb293fdb2016-09-21 16:03:44 -070058 --report_file /tmp/acloud_report.json --log_file /tmp/acloud.log
59
60 - Delete two instances:
61 $ acloud.par delete --instance_names
Fang Dengfed6a6f2017-03-01 18:27:28 -080062 ins-b638cdba-3744001-gce-x86-phone-userdebug-fastbuild3c-linux
Keun Soo Yimb293fdb2016-09-21 16:03:44 -070063 --config_file /path/to/acloud.config
64 --report_file /tmp/acloud_report.json --log_file /tmp/acloud.log
65"""
66import argparse
67import getpass
68import logging
Keun Soo Yimb293fdb2016-09-21 16:03:44 -070069import sys
70
Kevin Chengf4137c62018-05-22 16:06:58 -070071# Needed to silence oauth2client.
Sam Chiu29d858f2018-08-14 20:06:25 +080072# This is a workaround to get rid of below warning message:
73# 'No handlers could be found for logger "oauth2client.contrib.multistore_file'
74# TODO(b/112803893): Remove this code once bug is fixed.
75OAUTH2_LOGGER = logging.getLogger('oauth2client.contrib.multistore_file')
76OAUTH2_LOGGER.setLevel(logging.CRITICAL)
77OAUTH2_LOGGER.addHandler(logging.FileHandler("/dev/null"))
Kevin Chengb5963882018-05-09 00:06:27 -070078
Kevin Chengf4137c62018-05-22 16:06:58 -070079# pylint: disable=wrong-import-position
Keun Soo Yimb293fdb2016-09-21 16:03:44 -070080from acloud.internal import constants
81from acloud.public import acloud_common
82from acloud.public import config
83from acloud.public import device_driver
84from acloud.public import errors
Kevin Chengb5963882018-05-09 00:06:27 -070085from acloud.public.actions import create_cuttlefish_action
86from acloud.public.actions import create_goldfish_action
Kevin Cheng3087af52018-08-13 13:26:50 -070087from acloud.create import create
88from acloud.create import create_args
Kevin Chengeb85e862018-10-09 15:35:13 -070089from acloud.delete import delete
90from acloud.delete import delete_args
Kevin Chengee6030f2018-06-26 10:55:30 -070091from acloud.setup import setup
92from acloud.setup import setup_args
Keun Soo Yimb293fdb2016-09-21 16:03:44 -070093
Sam Chiu445941f2018-10-04 11:54:40 +080094LOGGING_FMT = "%(asctime)s |%(levelname)s| %(module)s:%(lineno)s| %(message)s"
Sam Chiu29d858f2018-08-14 20:06:25 +080095ACLOUD_LOGGER = "acloud"
Keun Soo Yimb293fdb2016-09-21 16:03:44 -070096
97# Commands
Kevin Chengb5963882018-05-09 00:06:27 -070098CMD_CREATE_CUTTLEFISH = "create_cf"
99CMD_CREATE_GOLDFISH = "create_gf"
Keun Soo Yimb293fdb2016-09-21 16:03:44 -0700100CMD_DELETE = "delete"
101CMD_CLEANUP = "cleanup"
Fang Deng69498c32017-03-02 14:29:30 -0800102CMD_SSHKEY = "project_sshkey"
Keun Soo Yimb293fdb2016-09-21 16:03:44 -0700103
104
Kevin Cheng3031f8a2018-05-16 13:21:51 -0700105# pylint: disable=too-many-statements
Keun Soo Yimb293fdb2016-09-21 16:03:44 -0700106def _ParseArgs(args):
107 """Parse args.
108
109 Args:
110 args: Argument list passed from main.
111
112 Returns:
113 Parsed args.
114 """
Kevin Cheng3031f8a2018-05-16 13:21:51 -0700115 usage = ",".join([
Sam Chiue669ef72018-10-16 16:23:37 +0800116 setup_args.CMD_SETUP,
117 create_args.CMD_CREATE,
Kevin Chengab0b36b2018-08-02 14:38:30 -0700118 CMD_CREATE_CUTTLEFISH,
119 CMD_CREATE_GOLDFISH,
Kevin Chengeb85e862018-10-09 15:35:13 -0700120 delete_args.CMD_DELETE,
Kevin Cheng3031f8a2018-05-16 13:21:51 -0700121 ])
Sam Chiue669ef72018-10-16 16:23:37 +0800122 usage_msg = ("acloud { %s } ..."
123 "\nTry 'acloud --help' for more information.") % usage
Keun Soo Yimb293fdb2016-09-21 16:03:44 -0700124 parser = argparse.ArgumentParser(
125 description=__doc__,
126 formatter_class=argparse.RawDescriptionHelpFormatter,
Sam Chiue669ef72018-10-16 16:23:37 +0800127 usage=usage_msg)
Keun Soo Yimb293fdb2016-09-21 16:03:44 -0700128 subparsers = parser.add_subparsers()
129 subparser_list = []
130
Kevin Chengb5963882018-05-09 00:06:27 -0700131 # Command "create_cf", create cuttlefish instances
132 create_cf_parser = subparsers.add_parser(CMD_CREATE_CUTTLEFISH)
133 create_cf_parser.required = False
134 create_cf_parser.set_defaults(which=CMD_CREATE_CUTTLEFISH)
135 create_cf_parser.add_argument(
136 "--build_target",
137 type=str,
138 dest="build_target",
139 help="Android build target, should be a cuttlefish target name.")
140 create_cf_parser.add_argument(
141 "--branch",
142 type=str,
143 dest="branch",
144 help="Android branch, e.g. git_master")
145 create_cf_parser.add_argument(
146 "--build_id",
147 type=str,
148 dest="build_id",
149 help="Android build id, e.g. 2145099, P2804227")
150 create_cf_parser.add_argument(
151 "--kernel_build_id",
152 type=str,
153 dest="kernel_build_id",
154 required=False,
155 help="Android kernel build id, e.g. 4586590. This is to test a new"
156 " kernel build with a particular Android build (--build_id). If not"
157 " specified, the kernel that's bundled with the Android build would"
158 " be used.")
Kevin Chengb5963882018-05-09 00:06:27 -0700159
Kevin Cheng3087af52018-08-13 13:26:50 -0700160 create_args.AddCommonCreateArgs(create_cf_parser)
Kevin Chengb5963882018-05-09 00:06:27 -0700161 subparser_list.append(create_cf_parser)
162
163 # Command "create_gf", create goldfish instances
164 # In order to create a goldfish device we need the following parameters:
165 # 1. The emulator build we wish to use, this is the binary that emulates
166 # an android device. See go/emu-dev for more
167 # 2. A system-image. This is the android release we wish to run on the
168 # emulated hardware.
169 create_gf_parser = subparsers.add_parser(CMD_CREATE_GOLDFISH)
170 create_gf_parser.required = False
171 create_gf_parser.set_defaults(which=CMD_CREATE_GOLDFISH)
172 create_gf_parser.add_argument(
173 "--build_target",
174 type=str,
175 dest="build_target",
176 help="Android build target, should be a goldfish target name.")
177 create_gf_parser.add_argument(
178 "--branch",
179 type=str,
180 dest="branch",
181 help="Android branch, e.g. git_master")
182 create_gf_parser.add_argument(
183 "--build_id",
184 type=str,
185 dest="build_id",
186 help="Android build id, e.g. 4669424, P2804227")
187 create_gf_parser.add_argument(
188 "--emulator_build_id",
189 type=str,
190 dest="emulator_build_id",
191 required=False,
192 help="Emulator build used to run the images. e.g. 4669466.")
193 create_gf_parser.add_argument(
194 "--gpu",
195 type=str,
196 dest="gpu",
197 required=False,
198 default=None,
199 help="GPU accelerator to use if any."
200 " e.g. nvidia-tesla-k80, omit to use swiftshader")
201 create_gf_parser.add_argument(
Kevin Chengbced4af2018-06-26 10:35:01 -0700202 "--base_image",
203 type=str,
204 dest="base_image",
205 required=False,
206 help="Name of the goldfish base image to be used to create the instance. "
207 "This will override stable_goldfish_host_image_name from config. "
208 "e.g. emu-dev-cts-061118")
Kevin Chengb5963882018-05-09 00:06:27 -0700209
Kevin Cheng3087af52018-08-13 13:26:50 -0700210 create_args.AddCommonCreateArgs(create_gf_parser)
Kevin Chengb5963882018-05-09 00:06:27 -0700211 subparser_list.append(create_gf_parser)
212
Keun Soo Yimb293fdb2016-09-21 16:03:44 -0700213 # Command "cleanup"
214 cleanup_parser = subparsers.add_parser(CMD_CLEANUP)
215 cleanup_parser.required = False
216 cleanup_parser.set_defaults(which=CMD_CLEANUP)
217 cleanup_parser.add_argument(
218 "--expiration_mins",
219 type=int,
220 dest="expiration_mins",
221 required=True,
222 help="Garbage collect all gce instances, gce images, cached disk "
223 "images that are older than |expiration_mins|.")
224 subparser_list.append(cleanup_parser)
225
Fang Deng69498c32017-03-02 14:29:30 -0800226 # Command "project_sshkey"
Keun Soo Yimb293fdb2016-09-21 16:03:44 -0700227 sshkey_parser = subparsers.add_parser(CMD_SSHKEY)
228 sshkey_parser.required = False
229 sshkey_parser.set_defaults(which=CMD_SSHKEY)
230 sshkey_parser.add_argument(
231 "--user",
232 type=str,
233 dest="user",
234 default=getpass.getuser(),
235 help="The user name which the sshkey belongs to, default to: %s." %
236 getpass.getuser())
237 sshkey_parser.add_argument(
238 "--ssh_rsa_path",
239 type=str,
240 dest="ssh_rsa_path",
241 required=True,
Fang Deng69498c32017-03-02 14:29:30 -0800242 help="Absolute path to the file that contains the public rsa key "
Kevin Cheng3031f8a2018-05-16 13:21:51 -0700243 "that will be added as project-wide ssh key.")
Keun Soo Yimb293fdb2016-09-21 16:03:44 -0700244 subparser_list.append(sshkey_parser)
245
Kevin Chengeb85e862018-10-09 15:35:13 -0700246 # Command "create"
247 subparser_list.append(create_args.GetCreateArgParser(subparsers))
248
Kevin Chengee6030f2018-06-26 10:55:30 -0700249 # Command "setup"
250 subparser_list.append(setup_args.GetSetupArgParser(subparsers))
251
Kevin Chengeb85e862018-10-09 15:35:13 -0700252 # Command "Delete"
253 subparser_list.append(delete_args.GetDeleteArgParser(subparsers))
254
Keun Soo Yimb293fdb2016-09-21 16:03:44 -0700255 # Add common arguments.
Kevin Chengb21d7712018-05-24 14:54:55 -0700256 for subparser in subparser_list:
257 acloud_common.AddCommonArguments(subparser)
Keun Soo Yimb293fdb2016-09-21 16:03:44 -0700258
259 return parser.parse_args(args)
260
261
herbertxueb617e8a2018-08-22 10:02:19 +0800262# TODO(b/112803893): Delete this method once the new create method has been completed.
Keun Soo Yimb293fdb2016-09-21 16:03:44 -0700263def _TranslateAlias(parsed_args):
264 """Translate alias to Launch Control compatible values.
265
266 This method translates alias to Launch Control compatible values.
267 - branch: "git_" prefix will be added if branch name doesn't have it.
268 - build_target: For example, "phone" will be translated to full target
269 name "git_x86_phone-userdebug",
270
271 Args:
272 parsed_args: Parsed args.
273
274 Returns:
275 Parsed args with its values being translated.
276 """
Kevin Cheng3087af52018-08-13 13:26:50 -0700277 if parsed_args.which == create_args.CMD_CREATE:
Keun Soo Yimb293fdb2016-09-21 16:03:44 -0700278 if (parsed_args.branch and
279 not parsed_args.branch.startswith(constants.BRANCH_PREFIX)):
280 parsed_args.branch = constants.BRANCH_PREFIX + parsed_args.branch
281 parsed_args.build_target = constants.BUILD_TARGET_MAPPING.get(
282 parsed_args.build_target, parsed_args.build_target)
283 return parsed_args
284
285
herbertxue2625b042018-08-16 23:28:20 +0800286# pylint: disable=too-many-branches
Keun Soo Yimb293fdb2016-09-21 16:03:44 -0700287def _VerifyArgs(parsed_args):
288 """Verify args.
289
290 Args:
291 parsed_args: Parsed args.
292
293 Raises:
294 errors.CommandArgError: If args are invalid.
295 """
herbertxue2625b042018-08-16 23:28:20 +0800296 if parsed_args.which == create_args.CMD_CREATE:
297 create_args.VerifyArgs(parsed_args)
298
Kevin Cheng3087af52018-08-13 13:26:50 -0700299 if (parsed_args.which == create_args.CMD_CREATE
300 and parsed_args.avd_type == constants.TYPE_GCE):
Keun Soo Yimb293fdb2016-09-21 16:03:44 -0700301 if (parsed_args.spec and parsed_args.spec not in constants.SPEC_NAMES):
302 raise errors.CommandArgError(
303 "%s is not valid. Choose from: %s" %
304 (parsed_args.spec, ", ".join(constants.SPEC_NAMES)))
Kevin Cheng3031f8a2018-05-16 13:21:51 -0700305 if not ((parsed_args.build_id and parsed_args.build_target)
306 or parsed_args.gce_image or parsed_args.local_disk_image):
Keun Soo Yimb293fdb2016-09-21 16:03:44 -0700307 raise errors.CommandArgError(
308 "At least one of the following should be specified: "
309 "--build_id and --build_target, or --gce_image, or "
310 "--local_disk_image.")
311 if bool(parsed_args.build_id) != bool(parsed_args.build_target):
312 raise errors.CommandArgError(
313 "Must specify --build_id and --build_target at the same time.")
Kevin Chengb5963882018-05-09 00:06:27 -0700314
Kevin Cheng84d3eed2018-08-16 15:16:00 -0700315 if parsed_args.which == CMD_CREATE_CUTTLEFISH:
Kevin Chengb5963882018-05-09 00:06:27 -0700316 if not parsed_args.build_id or not parsed_args.build_target:
Kevin Cheng3031f8a2018-05-16 13:21:51 -0700317 raise errors.CommandArgError(
318 "Must specify --build_id and --build_target")
Kevin Chengb5963882018-05-09 00:06:27 -0700319
320 if parsed_args.which == CMD_CREATE_GOLDFISH:
Kevin Cheng84d3eed2018-08-16 15:16:00 -0700321 if not parsed_args.emulator_build_id and not parsed_args.build_id:
322 raise errors.CommandArgError("Must specify either "
323 "--emulator_build_id or --build_id")
324 if not parsed_args.build_target:
325 raise errors.CommandArgError("Must specify --build_target")
Kevin Chengb5963882018-05-09 00:06:27 -0700326
327 if parsed_args.which in [
Kevin Cheng3087af52018-08-13 13:26:50 -0700328 create_args.CMD_CREATE, CMD_CREATE_CUTTLEFISH, CMD_CREATE_GOLDFISH
Kevin Chengb5963882018-05-09 00:06:27 -0700329 ]:
Kevin Cheng3031f8a2018-05-16 13:21:51 -0700330 if (parsed_args.serial_log_file
331 and not parsed_args.serial_log_file.endswith(".tar.gz")):
Keun Soo Yimb293fdb2016-09-21 16:03:44 -0700332 raise errors.CommandArgError(
333 "--serial_log_file must ends with .tar.gz")
Kevin Cheng3031f8a2018-05-16 13:21:51 -0700334 if (parsed_args.logcat_file
335 and not parsed_args.logcat_file.endswith(".tar.gz")):
Keun Soo Yimb293fdb2016-09-21 16:03:44 -0700336 raise errors.CommandArgError(
337 "--logcat_file must ends with .tar.gz")
338
339
Sam Chiu29d858f2018-08-14 20:06:25 +0800340def _SetupLogging(log_file, verbose):
Keun Soo Yimb293fdb2016-09-21 16:03:44 -0700341 """Setup logging.
342
Sam Chiu29d858f2018-08-14 20:06:25 +0800343 This function define the logging policy in below manners.
344 - without -v , -vv ,--log_file:
345 Only display critical log and print() message on screen.
346
347 - with -v:
348 Display INFO log and set StreamHandler to acloud parent logger to turn on
349 ONLY acloud modules logging.(silence all 3p libraries)
350
351 - with -vv:
352 Display INFO/DEBUG log and set StreamHandler to root logger to turn on all
353 acloud modules and 3p libraries logging.
354
355 - with --log_file.
356 Dump logs to FileHandler with DEBUG level.
357
Keun Soo Yimb293fdb2016-09-21 16:03:44 -0700358 Args:
Sam Chiu29d858f2018-08-14 20:06:25 +0800359 log_file: String, if not None, dump the log to log file.
360 verbose: Int, if verbose = 1(-v), log at INFO level and turn on
361 logging on libraries to a StreamHandler.
362 If verbose = 2(-vv), log at DEBUG level and turn on logging on
363 all libraries and 3rd party libraries to a StreamHandler.
Keun Soo Yimb293fdb2016-09-21 16:03:44 -0700364 """
Sam Chiu29d858f2018-08-14 20:06:25 +0800365 # Define logging level and hierarchy by verbosity.
366 shandler_level = None
367 logger = None
368 if verbose == 0:
369 shandler_level = logging.CRITICAL
370 logger = logging.getLogger(ACLOUD_LOGGER)
371 elif verbose == 1:
372 shandler_level = logging.INFO
373 logger = logging.getLogger(ACLOUD_LOGGER)
374 elif verbose > 1:
375 shandler_level = logging.DEBUG
Keun Soo Yimb293fdb2016-09-21 16:03:44 -0700376 logger = logging.getLogger()
Keun Soo Yimb293fdb2016-09-21 16:03:44 -0700377
Sam Chiu29d858f2018-08-14 20:06:25 +0800378 # Add StreamHandler by default.
379 shandler = logging.StreamHandler()
380 shandler.setFormatter(logging.Formatter(LOGGING_FMT))
381 shandler.setLevel(shandler_level)
382 logger.addHandler(shandler)
383 # Set the default level to DEBUG, the other handlers will handle
384 # their own levels via the args supplied (-v and --log_file).
385 logger.setLevel(logging.DEBUG)
Keun Soo Yimb293fdb2016-09-21 16:03:44 -0700386
Sam Chiu29d858f2018-08-14 20:06:25 +0800387 # Add FileHandler if log_file is provided.
Sam Chiufde41e92018-08-07 18:37:02 +0800388 if log_file:
Sam Chiu29d858f2018-08-14 20:06:25 +0800389 fhandler = logging.FileHandler(filename=log_file)
390 fhandler.setFormatter(logging.Formatter(LOGGING_FMT))
391 fhandler.setLevel(logging.DEBUG)
392 logger.addHandler(fhandler)
Keun Soo Yimb293fdb2016-09-21 16:03:44 -0700393
394
395def main(argv):
396 """Main entry.
397
398 Args:
399 argv: A list of system arguments.
400
401 Returns:
402 0 if success. None-zero if fails.
403 """
404 args = _ParseArgs(argv)
Sam Chiu29d858f2018-08-14 20:06:25 +0800405 _SetupLogging(args.log_file, args.verbose)
herbertxueb617e8a2018-08-22 10:02:19 +0800406 # Translation of the branch will happen in AvdSpec(), skip it for now.
407 #args = _TranslateAlias(args)
Keun Soo Yimb293fdb2016-09-21 16:03:44 -0700408 _VerifyArgs(args)
409
Sam Chiuc64f3432018-08-17 11:19:06 +0800410 cfg = config.GetAcloudConfig(args)
Kevin Cheng3087af52018-08-13 13:26:50 -0700411 # TODO: Move this check into the functions it is actually needed.
Fang Dengcef4b112017-03-02 11:20:17 -0800412 # Check access.
Kevin Cheng3087af52018-08-13 13:26:50 -0700413 # device_driver.CheckAccess(cfg)
Fang Dengcef4b112017-03-02 11:20:17 -0800414
Kevin Chengee6030f2018-06-26 10:55:30 -0700415 report = None
Kevin Cheng3087af52018-08-13 13:26:50 -0700416 if (args.which == create_args.CMD_CREATE
417 and args.avd_type == constants.TYPE_GCE):
Keun Soo Yimb293fdb2016-09-21 16:03:44 -0700418 report = device_driver.CreateAndroidVirtualDevices(
419 cfg,
420 args.build_target,
421 args.build_id,
422 args.num,
423 args.gce_image,
424 args.local_disk_image,
425 cleanup=not args.no_cleanup,
426 serial_log_file=args.serial_log_file,
Kevin Chengb5963882018-05-09 00:06:27 -0700427 logcat_file=args.logcat_file,
Kevin Cheng86d43c72018-08-30 10:59:14 -0700428 autoconnect=args.autoconnect,
429 report_internal_ip=args.report_internal_ip)
Kevin Cheng3087af52018-08-13 13:26:50 -0700430 elif args.which == create_args.CMD_CREATE:
Kevin Chengc3d0d5e2018-08-14 14:22:44 -0700431 create.Run(args)
Kevin Chengb5963882018-05-09 00:06:27 -0700432 elif args.which == CMD_CREATE_CUTTLEFISH:
433 report = create_cuttlefish_action.CreateDevices(
434 cfg=cfg,
435 build_target=args.build_target,
436 build_id=args.build_id,
437 kernel_build_id=args.kernel_build_id,
438 num=args.num,
439 serial_log_file=args.serial_log_file,
440 logcat_file=args.logcat_file,
Kevin Cheng86d43c72018-08-30 10:59:14 -0700441 autoconnect=args.autoconnect,
442 report_internal_ip=args.report_internal_ip)
Kevin Chengb5963882018-05-09 00:06:27 -0700443 elif args.which == CMD_CREATE_GOLDFISH:
444 report = create_goldfish_action.CreateDevices(
445 cfg=cfg,
446 build_target=args.build_target,
447 build_id=args.build_id,
448 emulator_build_id=args.emulator_build_id,
449 gpu=args.gpu,
450 num=args.num,
451 serial_log_file=args.serial_log_file,
452 logcat_file=args.logcat_file,
Kevin Cheng84d3eed2018-08-16 15:16:00 -0700453 autoconnect=args.autoconnect,
Kevin Cheng86d43c72018-08-30 10:59:14 -0700454 branch=args.branch,
455 report_internal_ip=args.report_internal_ip)
Keun Soo Yimb293fdb2016-09-21 16:03:44 -0700456 elif args.which == CMD_DELETE:
Kevin Chengeb85e862018-10-09 15:35:13 -0700457 report = delete.Run(args)
Keun Soo Yimb293fdb2016-09-21 16:03:44 -0700458 elif args.which == CMD_CLEANUP:
459 report = device_driver.Cleanup(cfg, args.expiration_mins)
460 elif args.which == CMD_SSHKEY:
461 report = device_driver.AddSshRsa(cfg, args.user, args.ssh_rsa_path)
Kevin Chengee6030f2018-06-26 10:55:30 -0700462 elif args.which == setup_args.CMD_SETUP:
herbertxue34776bb2018-07-03 21:57:48 +0800463 setup.Run(args)
Keun Soo Yimb293fdb2016-09-21 16:03:44 -0700464 else:
465 sys.stderr.write("Invalid command %s" % args.which)
466 return 2
467
Kevin Chengee6030f2018-06-26 10:55:30 -0700468 if report:
469 report.Dump(args.report_file)
470 if report.errors:
471 msg = "\n".join(report.errors)
472 sys.stderr.write("Encountered the following errors:\n%s\n" % msg)
473 return 1
Keun Soo Yimb293fdb2016-09-21 16:03:44 -0700474 return 0
Tri Vo8e292532016-10-01 16:55:51 -0700475
476
477if __name__ == "__main__":
478 main(sys.argv[1:])