1# Copyright 2018 - The Android Open Source Project 2# 3# Licensed under the Apache License, Version 2.0 (the "License"); 4# you may not use this file except in compliance with the License. 5# You may obtain a copy of the License at 6# 7# http://www.apache.org/licenses/LICENSE-2.0 8# 9# Unless required by applicable law or agreed to in writing, software 10# distributed under the License is distributed on an "AS IS" BASIS, 11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12# See the License for the specific language governing permissions and 13# limitations under the License. 14r"""Create args. 15 16Defines the create arg parser that holds create specific args. 17""" 18 19import argparse 20import logging 21import os 22 23from acloud import errors 24from acloud.create import create_common 25from acloud.internal import constants 26from acloud.internal.lib import utils 27 28logger = logging.getLogger(__name__) 29_DEFAULT_GPU = "default" 30CMD_CREATE = "create" 31 32 33# TODO: Add this into main create args once create_cf/gf is deprecated. 34# pylint: disable=too-many-statements 35def AddCommonCreateArgs(parser): 36 """Adds arguments common to create parsers. 37 38 Args: 39 parser: ArgumentParser object, used to parse flags. 40 """ 41 parser.add_argument( 42 "--num", 43 type=int, 44 dest="num", 45 required=False, 46 default=1, 47 help="Number of instances to create.") 48 parser.add_argument( 49 "--serial-log-file", 50 type=str, 51 dest="serial_log_file", 52 required=False, 53 help="Path to a *tar.gz file where serial logs will be saved " 54 "when a device fails on boot.") 55 parser.add_argument( 56 "--autoconnect", 57 type=str, 58 nargs="?", 59 const=constants.INS_KEY_WEBRTC, 60 dest="autoconnect", 61 required=False, 62 choices=[constants.INS_KEY_VNC, constants.INS_KEY_ADB, 63 constants.INS_KEY_FASTBOOT, constants.INS_KEY_WEBRTC], 64 help="Determines to establish a tunnel forwarding adb/fastboot/vnc and " 65 "launch VNC/webrtc. Establish a tunnel forwarding adb, fastboot and vnc " 66 "then launch vnc if --autoconnect vnc is provided. Establish a " 67 "tunnel forwarding adb and fastboot if --autoconnect adb is provided. Enstablish a " 68 "tunnel forwarding adb and fastboot if --autoconnect fastboot is provided. " 69 "Establish a tunnel forwarding adb, fastboot and auto-launch on the browser " 70 "if --autoconnect webrtc is provided. For local goldfish " 71 "instance, create a window.") 72 parser.add_argument( 73 "--no-autoconnect", 74 action="store_false", 75 dest="autoconnect", 76 required=False, 77 help="Will not automatically create ssh tunnels forwarding adb & vnc " 78 "when instance created.") 79 parser.set_defaults(autoconnect=constants.INS_KEY_WEBRTC) 80 parser.add_argument( 81 "--unlock", 82 action="store_true", 83 dest="unlock_screen", 84 required=False, 85 default=False, 86 help="This can unlock screen after invoke vnc client.") 87 parser.add_argument( 88 "--report-internal-ip", 89 action="store_true", 90 dest="report_internal_ip", 91 required=False, 92 help="Report internal ip of the created instance instead of external " 93 "ip. Using the internal ip is used when connecting from another " 94 "GCE instance.") 95 parser.add_argument( 96 "--disable-external-ip", 97 action="store_true", 98 dest="disable_external_ip", 99 required=False, 100 help="Disable the external ip of the created instance.") 101 parser.add_argument( 102 "--extra-files", 103 nargs='+', 104 type=str, 105 dest="extra_files", 106 required=False, 107 help="Upload the extra files into GCE instance. e.g. " 108 "/path/to/file_in_local,/path/to/file_in_gce") 109 parser.add_argument( 110 "--network", 111 type=str, 112 dest="network", 113 required=False, 114 help="Set the network the GCE instance will utilize.") 115 parser.add_argument( 116 "--skip-pre-run-check", 117 action="store_true", 118 dest="skip_pre_run_check", 119 required=False, 120 help="Skip the pre-run check.") 121 parser.add_argument( 122 "--force-sync", 123 action="store_true", 124 dest="force_sync", 125 required=False, 126 help="Force to sync image files from Android Build servers even if " 127 "they are already existed for local instance mode.") 128 parser.add_argument( 129 "--boot-timeout", 130 dest="boot_timeout_secs", 131 type=int, 132 required=False, 133 help="The maximum time in seconds used to wait for the AVD to download " 134 "artifacts and boot.") 135 parser.add_argument( 136 "--wait-for-ins-stable", 137 dest="ins_timeout_secs", 138 type=int, 139 required=False, 140 help="The maximum time in seconds used to wait for the instance boot " 141 "up. The default value to wait for instance up time is 300 secs.") 142 parser.add_argument( 143 "--build-target", 144 type=str, 145 dest="build_target", 146 help="Android build target, e.g. aosp_cf_x86_64_phone-userdebug, " 147 "or short names: phone, tablet, or tablet_mobile.") 148 parser.add_argument( 149 "--branch", 150 type=str, 151 dest="branch", 152 help="Android branch, e.g. mnc-dev or git_mnc-dev") 153 parser.add_argument( 154 "--build-id", 155 type=str, 156 dest="build_id", 157 help="Android build id, e.g. 2145099, P2804227") 158 parser.add_argument( 159 "--bootloader-branch", 160 type=str, 161 dest="bootloader_branch", 162 help="'cuttlefish only' Branch to consume the bootloader from.", 163 required=False) 164 parser.add_argument( 165 "--bootloader-build-id", 166 type=str, 167 dest="bootloader_build_id", 168 help="'cuttlefish only' Bootloader build id, e.g. P2804227", 169 required=False) 170 parser.add_argument( 171 "--bootloader-build-target", 172 type=str, 173 dest="bootloader_build_target", 174 help="'cuttlefish only' Bootloader build target.", 175 required=False) 176 parser.add_argument( 177 "--kernel-build-id", 178 type=str, 179 dest="kernel_build_id", 180 required=False, 181 help="Android kernel build id, e.g. 4586590. This is to test a new" 182 " kernel build with a particular Android build (--build-id). If neither" 183 " kernel-branch nor kernel-build-id are specified, the kernel that's" 184 " bundled with the Android build would be used.") 185 parser.add_argument( 186 "--kernel-branch", 187 type=str, 188 dest="kernel_branch", 189 required=False, 190 help="Android kernel build branch name, e.g." 191 " kernel-common-android-4.14. This is to test a new kernel build with a" 192 " particular Android build (--build-id). If specified without" 193 " specifying kernel-build-id, the last green build in the branch will" 194 " be used. If neither kernel-branch nor kernel-build-id are specified," 195 " the kernel that's bundled with the Android build would be used.") 196 parser.add_argument( 197 "--kernel-build-target", 198 type=str, 199 dest="kernel_build_target", 200 default="kernel", 201 help="Kernel build target, specify if different from 'kernel'") 202 parser.add_argument( 203 "--boot-build-id", 204 type=str, 205 dest="boot_build_id", 206 required=False, 207 help="Boot image build ID, e.g., 8747889, 8748012.") 208 parser.add_argument( 209 "--boot-branch", 210 type=str, 211 dest="boot_branch", 212 required=False, 213 help="Boot image branch, e.g., aosp-gki13-boot-release, aosp-master.") 214 parser.add_argument( 215 "--boot-build-target", 216 type=str, 217 dest="boot_build_target", 218 required=False, 219 help="Boot image build target, " 220 "e.g., gki_x86_64-userdebug, aosp_cf_x86_64_phone-userdebug.") 221 parser.add_argument( 222 "--boot-artifact", 223 type=str, 224 dest="boot_artifact", 225 required=False, 226 help="The name of the boot image to be retrieved from Android build, " 227 "e.g., boot-5.10.img, boot.img.") 228 parser.add_argument( 229 "--ota-branch", 230 type=str, 231 dest="ota_branch", 232 required=False, 233 help="'cuttlefish only' OTA tools branch name. e.g. aosp-master") 234 parser.add_argument( 235 "--ota-build-id", 236 type=str, 237 dest="ota_build_id", 238 required=False, 239 help="'cuttlefish only' OTA tools build id, e.g. 2145099, P2804227") 240 parser.add_argument( 241 "--ota-build-target", 242 type=str, 243 dest="ota_build_target", 244 required=False, 245 help="'cuttlefish only' OTA tools build target, e.g. " 246 "cf_x86_64_phone-userdebug.") 247 parser.add_argument( 248 "--system-branch", 249 type=str, 250 dest="system_branch", 251 help="'cuttlefish only' Branch to consume the system image (system.img) " 252 "from, will default to what is defined by --branch. " 253 "That feature allows to (automatically) test various combinations " 254 "of vendor.img (CF, e.g.) and system images (GSI, e.g.). ", 255 required=False) 256 parser.add_argument( 257 "--system-build-id", 258 type=str, 259 dest="system_build_id", 260 help="'cuttlefish only' System image build id, e.g. 2145099, P2804227", 261 required=False) 262 parser.add_argument( 263 "--system-build-target", 264 type=str, 265 dest="system_build_target", 266 help="'cuttlefish only' System image build target, specify if different " 267 "from --build-target", 268 required=False) 269 parser.add_argument( 270 "--launch-args", 271 type=str, 272 dest="launch_args", 273 help="'cuttlefish only' Add extra args to launch_cvd command.", 274 required=False) 275 parser.add_argument( 276 "--pet-name", 277 "--webrtc_device_id", 278 type=str, 279 dest="webrtc_device_id", 280 help="'cuttlefish only' Give the pet name of the instance.", 281 required=False) 282 parser.add_argument( 283 "--gce-metadata", 284 type=str, 285 dest="gce_metadata", 286 default=None, 287 help="'GCE instance only' Record data into GCE instance metadata with " 288 "key-value pair format. e.g. id:12,name:unknown.") 289 parser.add_argument( 290 "--fetch_cvd-build-id", 291 type=str, 292 dest="fetch_cvd_build_id", 293 required=False, 294 help="'cuttlefish only' Build id of fetch_cvd, e.g. 2145099, P2804227") 295 # TODO(146314062): Remove --multi-stage-launch after infra don't use this 296 # args. 297 parser.add_argument( 298 "--multi-stage-launch", 299 dest="multi_stage_launch", 300 action="store_true", 301 required=False, 302 default=True, 303 help="Enable the multi-stage cuttlefish launch.") 304 parser.add_argument( 305 "--no-multi-stage-launch", 306 dest="multi_stage_launch", 307 action="store_false", 308 required=False, 309 default=None, 310 help="Disable the multi-stage cuttlefish launch.") 311 parser.add_argument( 312 "--no-pull-log", 313 dest="no_pull_log", 314 action="store_true", 315 required=False, 316 default=None, 317 help="Disable auto download logs when AVD booting up failed.") 318 parser.add_argument( 319 "--no-mkcert", 320 dest="mkcert", 321 action="store_false", 322 required=False, 323 default=True, 324 help="Disable mkcert setup process on the host.") 325 # TODO(147335651): Add gpu in user config. 326 # TODO(147335651): Support "--gpu" without giving any value. 327 parser.add_argument( 328 "--gpu", 329 type=str, 330 const=_DEFAULT_GPU, 331 nargs="?", 332 dest="gpu", 333 required=False, 334 default=None, 335 help="GPU accelerator to use if any. e.g. nvidia-tesla-k80. For local " 336 "instances, this arg without assigning any value is to enable " 337 "local gpu support.") 338 parser.add_argument( 339 "--num-avds-per-instance", 340 "--num-instances", 341 "--num_instances", 342 type=int, 343 dest="num_avds_per_instance", 344 required=False, 345 default=1, 346 help="'cuttlefish only' Create multiple cuttlefish AVDs in one local " 347 "instance.") 348 parser.add_argument( 349 "--connect-hostname", 350 action="store_true", 351 dest="connect_hostname", 352 required=False, 353 default=False, 354 help="Ssh connects to the GCE instance with hostname.") 355 parser.add_argument( 356 "--gce-only", 357 action="store_true", 358 dest="gce_only", 359 required=False, 360 default=False, 361 help="Only create the GCE instance. It won't create virtual devices.") 362 # Hide following args for users, it is only used in infra. 363 parser.add_argument( 364 "--local-instance-dir", 365 dest="local_instance_dir", 366 required=False, 367 help=argparse.SUPPRESS) 368 parser.add_argument( 369 "--oxygen", 370 action="store_true", 371 dest="oxygen", 372 required=False, 373 help=argparse.SUPPRESS) 374 parser.add_argument( 375 "--zone", 376 type=str, 377 dest="zone", 378 required=False, 379 help=argparse.SUPPRESS) 380 381 # TODO(b/118439885): Old arg formats to support transition, delete when 382 # transistion is done. 383 parser.add_argument( 384 "--serial_log_file", 385 type=str, 386 dest="serial_log_file", 387 required=False, 388 help=argparse.SUPPRESS) 389 parser.add_argument( 390 "--build_id", 391 type=str, 392 dest="build_id", 393 required=False, 394 help=argparse.SUPPRESS) 395 parser.add_argument( 396 "--build_target", 397 type=str, 398 dest="build_target", 399 required=False, 400 help=argparse.SUPPRESS) 401 parser.add_argument( 402 "--system_branch", 403 type=str, 404 dest="system_branch", 405 required=False, 406 help=argparse.SUPPRESS) 407 parser.add_argument( 408 "--system_build_id", 409 type=str, 410 dest="system_build_id", 411 required=False, 412 help=argparse.SUPPRESS) 413 parser.add_argument( 414 "--system_build_target", 415 type=str, 416 dest="system_build_target", 417 required=False, 418 help=argparse.SUPPRESS) 419 parser.add_argument( 420 "--kernel_build_id", 421 type=str, 422 dest="kernel_build_id", 423 required=False, 424 help=argparse.SUPPRESS) 425 parser.add_argument( 426 "--kernel_branch", 427 type=str, 428 dest="kernel_branch", 429 required=False, 430 help=argparse.SUPPRESS) 431 parser.add_argument( 432 "--kernel_build_target", 433 type=str, 434 dest="kernel_build_target", 435 default="kernel", 436 help=argparse.SUPPRESS) 437 parser.add_argument( 438 "--bootloader_branch", 439 type=str, 440 dest="bootloader_branch", 441 help=argparse.SUPPRESS, 442 required=False) 443 parser.add_argument( 444 "--bootloader_build_id", 445 type=str, 446 dest="bootloader_build_id", 447 help=argparse.SUPPRESS, 448 required=False) 449 parser.add_argument( 450 "--bootloader_build_target", 451 type=str, 452 dest="bootloader_build_target", 453 help=argparse.SUPPRESS, 454 required=False) 455 parser.add_argument( 456 "--fetch_cvd_build_id", 457 type=str, 458 dest="fetch_cvd_build_id", 459 help=argparse.SUPPRESS, 460 required=False) 461 parser.add_argument( 462 "--remote-fetch", 463 action="store_true", 464 dest="remote_fetch", 465 required=False, 466 default=None, 467 help="'cuttlefish only' Fetch artifacts in remote host.") 468 parser.add_argument( 469 "--fetch-cvd-wrapper", 470 dest="fetch_cvd_wrapper", 471 type=str, 472 required=False, 473 help="'cuttlefish only' Fetch artifacts in remote host by a" 474 " provided static executable fetch cvd wrapper file. " 475 " (Still in experiment, this flag only works on lab hosts" 476 " with special setup.)") 477 478 479def GetCreateArgParser(subparser): 480 """Return the create arg parser. 481 482 Args: 483 subparser: argparse.ArgumentParser that is attached to main acloud cmd. 484 485 Returns: 486 argparse.ArgumentParser with create options defined. 487 """ 488 create_parser = subparser.add_parser(CMD_CREATE) 489 create_parser.required = False 490 create_parser.set_defaults(which=CMD_CREATE) 491 # Use default=None to distinguish remote instance or local. The instance 492 # type will be remote if the arg is not provided. 493 create_parser.add_argument( 494 "--local-instance", 495 type=_PositiveInteger, 496 const=0, 497 metavar="ID", 498 nargs="?", 499 dest="local_instance", 500 required=False, 501 help="Create a local AVD instance using the resources associated with " 502 "the ID. Choose an unused ID automatically if the value is " 503 "not specified (primarily for infra usage).") 504 create_parser.add_argument( 505 "--adb-port", "-p", 506 type=int, 507 default=None, 508 dest="adb_port", 509 required=False, 510 help="Specify port for adb forwarding.") 511 create_parser.add_argument( 512 "--fastboot-port", "-f", 513 type=int, 514 default=None, 515 dest="fastboot_port", 516 required=False, 517 help="Specify port for fastboot forwarding.") 518 create_parser.add_argument( 519 "--base-instance-num", 520 type=int, 521 default=None, 522 dest="base_instance_num", 523 required=False, 524 help="'cuttlefish only' The instance number of the created device.") 525 create_parser.add_argument( 526 "--avd-type", 527 type=str, 528 dest="avd_type", 529 default=constants.TYPE_CF, 530 choices=[constants.TYPE_GCE, constants.TYPE_CF, constants.TYPE_GF, constants.TYPE_CHEEPS, 531 constants.TYPE_FVP], 532 help="Android Virtual Device type (default %s)." % constants.TYPE_CF) 533 create_parser.add_argument( 534 "--config", "--flavor", 535 type=str, 536 dest="flavor", 537 help="The device flavor of the AVD (default %s). e.g. phone, tv, foldable." 538 % constants.FLAVOR_PHONE) 539 create_parser.add_argument( 540 "--local-image", 541 const=constants.FIND_IN_BUILD_ENV, 542 type=str, 543 dest="local_image", 544 nargs="?", 545 required=False, 546 help="Use the locally built image for the AVD. Look for the image " 547 "artifact in $ANDROID_PRODUCT_OUT if no args value is provided." 548 "e.g --local-image or --local-image /path/to/dir or --local-image " 549 "/path/to/file") 550 create_parser.add_argument( 551 "--local-kernel-image", "--local-boot-image", 552 const=constants.FIND_IN_BUILD_ENV, 553 type=str, 554 dest="local_kernel_image", 555 nargs="?", 556 required=False, 557 help="Use the locally built kernel and ramdisk for the AVD. Look " 558 "for boot.img, vendor_boot.img, kernel, initramfs.img, etc. if the " 559 "argument is a directory. Look for the images in $ANDROID_PRODUCT_OUT " 560 "if no argument is provided. e.g., --local-kernel-image, " 561 "--local-kernel-image /path/to/dir, or --local-kernel-image " 562 "/path/to/boot.img") 563 create_parser.add_argument( 564 "--local-system-image", 565 const=constants.FIND_IN_BUILD_ENV, 566 type=str, 567 dest="local_system_image", 568 nargs="?", 569 required=False, 570 help="Use the locally built system images for the AVD. Look for the " 571 "images in $ANDROID_PRODUCT_OUT if no args value is provided. " 572 "e.g., --local-system-image, --local-system-image /path/to/dir, or " 573 "--local-system-image /path/to/img") 574 create_parser.add_argument( 575 "--local-vendor-image", 576 const=constants.FIND_IN_BUILD_ENV, 577 type=str, 578 dest="local_vendor_image", 579 nargs="?", 580 required=False, 581 help="'cuttlefish only' Use the locally built vendor images for the " 582 "AVD. Look for vendor.img, vendor_dlkm.img, odm.img, and odm_dlkm.img " 583 "if the argument is a directory. Look for the images in " 584 "$ANDROID_PRODUCT_OUT if no argument is provided. e.g., " 585 "--local-vendor-image, or --local-vendor-image /path/to/dir") 586 create_parser.add_argument( 587 "--local-tool", 588 type=str, 589 dest="local_tool", 590 action="append", 591 default=[], 592 required=False, 593 help="Use the tools in the specified directory to create local " 594 "instances. The directory structure follows $ANDROID_SOONG_HOST_OUT " 595 "or $ANDROID_EMULATOR_PREBUILTS.") 596 create_parser.add_argument( 597 "--cvd-host-package", 598 type=str, 599 dest="cvd_host_package", 600 required=False, 601 help="Use the specified path of the cvd host package to create " 602 "instances. e.g. /path/cvd-host_package_v1.tar.gz") 603 create_parser.add_argument( 604 "--image-download-dir", 605 type=str, 606 dest="image_download_dir", 607 required=False, 608 help="Define remote image download directory, e.g. /usr/local/dl.") 609 create_parser.add_argument( 610 "--yes", "-y", 611 action="store_true", 612 dest="no_prompt", 613 required=False, 614 help=("Automatic yes to prompts. Assume 'yes' as answer to all prompts " 615 "and run non-interactively.")) 616 create_parser.add_argument( 617 "--reuse-gce", 618 type=str, 619 const=constants.SELECT_ONE_GCE_INSTANCE, 620 nargs="?", 621 dest="reuse_gce", 622 required=False, 623 help="'cuttlefish only' This can help users use their own instance. " 624 "Reusing specific gce instance if --reuse-gce [instance_name] is " 625 "provided. Select one gce instance to reuse if --reuse-gce is " 626 "provided.") 627 create_parser.add_argument( 628 "--openwrt", 629 action="store_true", 630 dest="openwrt", 631 required=False, 632 help="'cuttlefish only' Create OpenWrt device when launching cuttlefish " 633 "device.") 634 create_parser.add_argument( 635 "--use-launch_cvd", 636 action="store_true", 637 dest="use_launch_cvd", 638 required=False, 639 help="'cuttlefish only' Use launch_cvd to create cuttlefish devices.") 640 create_parser.add_argument( 641 "--host", 642 type=str, 643 dest="remote_host", 644 default=None, 645 help="'cuttlefish only' Provide host name to clean up the remote host. " 646 "For example: '--host 1.1.1.1'") 647 create_parser.add_argument( 648 "--host-user", 649 type=str, 650 dest="host_user", 651 default=constants.GCE_USER, 652 help="'remote host only' Provide host user for logging in to the host. " 653 "The default value is vsoc-01. For example: '--host 1.1.1.1 --host-user " 654 "vsoc-02'") 655 create_parser.add_argument( 656 "--host-ssh-private-key-path", 657 type=str, 658 dest="host_ssh_private_key_path", 659 default=None, 660 help="'remote host only' Provide host key for login on on this host.") 661 # User should not specify --spec and --hw_property at the same time. 662 hw_spec_group = create_parser.add_mutually_exclusive_group() 663 hw_spec_group.add_argument( 664 "--hw-property", 665 type=str, 666 dest="hw_property", 667 required=False, 668 help="Supported HW properties and example values: %s" % 669 constants.HW_PROPERTIES_CMD_EXAMPLE) 670 hw_spec_group.add_argument( 671 "--spec", 672 type=str, 673 dest="spec", 674 required=False, 675 choices=constants.SPEC_NAMES, 676 help="The name of a pre-configured device spec that we are " 677 "going to use.") 678 create_parser.add_argument( 679 "--disk-type", 680 type=str, 681 dest="disk_type", 682 required=False, 683 help="This is used to customize the GCE instance disk type, the " 684 "default disk type is from the stable host image. Use pd-ssd or " 685 "pd-standard to specify instance disk type.") 686 create_parser.add_argument( 687 "--stable-host-image-name", 688 type=str, 689 dest="stable_host_image_name", 690 required=False, 691 default=None, 692 help=("'cuttlefish only' The Cuttlefish host image from which instances " 693 "are launched. If specified here, the value set in Acloud config " 694 "file will be overridden.")) 695 696 # Arguments for goldfish type. 697 create_parser.add_argument( 698 "--emulator-build-id", 699 type=str, 700 dest="emulator_build_id", 701 required=False, 702 help="'goldfish only' Emulator build ID used to run the images. " 703 "e.g. 4669466.") 704 create_parser.add_argument( 705 "--emulator-build-target", 706 dest="emulator_build_target", 707 required=False, 708 help="'goldfish remote host only' Emulator build target used to run " 709 "the images. e.g. emulator-linux_x64_nolocationui.") 710 create_parser.add_argument( 711 "--emulator-zip", 712 dest="emulator_zip", 713 required=False, 714 help="'goldfish remote host only' Emulator zip used to run the " 715 "images. e.g., /path/sdk-repo-linux-emulator-1234567.zip.") 716 717 # Arguments for cheeps type. 718 create_parser.add_argument( 719 "--stable-cheeps-host-image-name", 720 type=str, 721 dest="stable_cheeps_host_image_name", 722 required=False, 723 default=None, 724 help=("'cheeps only' The Cheeps host image from which instances are " 725 "launched. If specified here, the value set in Acloud config " 726 "file will be overridden.")) 727 create_parser.add_argument( 728 "--stable-cheeps-host-image-project", 729 type=str, 730 dest="stable_cheeps_host_image_project", 731 required=False, 732 default=None, 733 help=("'cheeps only' The project hosting the specified Cheeps host " 734 "image. If specified here, the value set in Acloud config file " 735 "will be overridden.")) 736 create_parser.add_argument( 737 "--user", 738 type=str, 739 dest="username", 740 required=False, 741 default=None, 742 help="'cheeps only' username to log in to Chrome OS as.") 743 create_parser.add_argument( 744 "--password", 745 type=str, 746 dest="password", 747 required=False, 748 default=None, 749 help="'cheeps only' password to log in to Chrome OS with.") 750 create_parser.add_argument( 751 "--betty-image", 752 type=str, 753 dest="cheeps_betty_image", 754 required=False, 755 default=None, 756 help=("'cheeps only' The L1 betty version to use. Only makes sense " 757 "when launching a controller image with " 758 "stable-cheeps-host-image")) 759 create_parser.add_argument( 760 "--cheeps-feature", 761 type=str, 762 dest="cheeps_features", 763 required=False, 764 action="append", 765 default=[], 766 help=("'cheeps only' Cheeps feature to enable. Can be repeated.")) 767 768 AddCommonCreateArgs(create_parser) 769 return create_parser 770 771 772def _PositiveInteger(arg): 773 """Convert an argument from a string to a positive integer.""" 774 try: 775 value = int(arg) 776 except ValueError as e: 777 raise argparse.ArgumentTypeError(arg + " is not an integer.") from e 778 if value <= 0: 779 raise argparse.ArgumentTypeError(arg + " is not positive.") 780 return value 781 782 783def _VerifyLocalArgs(args): 784 """Verify args starting with --local. 785 786 Args: 787 args: Namespace object from argparse.parse_args. 788 789 Raises: 790 errors.CheckPathError: Image path doesn't exist. 791 errors.UnsupportedCreateArgs: The specified avd type does not support 792 --local-system-image. 793 errors.UnsupportedLocalInstanceId: Local instance ID is invalid. 794 """ 795 if args.local_image and not os.path.exists(args.local_image): 796 raise errors.CheckPathError( 797 "Specified path doesn't exist: %s" % args.local_image) 798 799 if args.local_instance_dir and not os.path.exists(args.local_instance_dir): 800 raise errors.CheckPathError( 801 "Specified path doesn't exist: %s" % args.local_instance_dir) 802 803 if not (args.local_system_image is None or 804 args.avd_type in (constants.TYPE_CF, constants.TYPE_GF)): 805 raise errors.UnsupportedCreateArgs("%s instance does not support " 806 "--local-system-image" % 807 args.avd_type) 808 # TODO(b/179340595): To support local image remote instance with kernel build. 809 if args.local_instance is None and args.local_image is not None and ( 810 args.kernel_branch or args.kernel_build_id): 811 raise errors.UnsupportedCreateArgs( 812 "Acloud didn't support local image with specific kernel. " 813 "Please download the specific kernel and put it into " 814 "your local image folder: '%s'." % ( 815 args.local_image if args.local_image else 816 utils.GetBuildEnvironmentVariable(constants.ENV_ANDROID_PRODUCT_OUT))) 817 818 if (args.local_system_image and 819 not os.path.exists(args.local_system_image)): 820 raise errors.CheckPathError( 821 "Specified path doesn't exist: %s" % args.local_system_image) 822 823 for tool_dir in args.local_tool: 824 if not os.path.exists(tool_dir): 825 raise errors.CheckPathError( 826 "Specified path doesn't exist: %s" % tool_dir) 827 828 829def _VerifyHostArgs(args): 830 """Verify args starting with --host. 831 832 Args: 833 args: Namespace object from argparse.parse_args. 834 835 Raises: 836 errors.UnsupportedCreateArgs: When a create arg is specified but 837 unsupported for remote host mode. 838 """ 839 if args.remote_host and args.local_instance is not None: 840 raise errors.UnsupportedCreateArgs( 841 "--host is not supported for local instance.") 842 843 if args.remote_host and args.num > 1: 844 raise errors.UnsupportedCreateArgs( 845 "--num is not supported for remote host.") 846 847 if args.host_user != constants.GCE_USER and args.remote_host is None: 848 raise errors.UnsupportedCreateArgs( 849 "--host-user only support for remote host.") 850 851 if args.host_ssh_private_key_path and args.remote_host is None: 852 raise errors.UnsupportedCreateArgs( 853 "--host-ssh-private-key-path only support for remote host.") 854 855 856def _VerifyGoldfishArgs(args): 857 """Verify goldfish args. 858 859 Args: 860 args: Namespace object from argparse.parse_args. 861 862 Raises: 863 errors.UnsupportedCreateArgs: When a create arg is specified but 864 unsupported for goldfish. 865 """ 866 goldfish_only_flags = [ 867 args.emulator_build_id, 868 args.emulator_build_target, 869 args.emulator_zip 870 ] 871 if args.avd_type != constants.TYPE_GF and any(goldfish_only_flags): 872 raise errors.UnsupportedCreateArgs( 873 f"--emulator-* is only valid with avd_type == {constants.TYPE_GF}") 874 875 # Exclude kernel_build_target because the default value isn't empty. 876 remote_kernel_flags = [ 877 args.kernel_build_id, 878 args.kernel_branch, 879 ] 880 if args.avd_type == constants.TYPE_GF and any(remote_kernel_flags): 881 raise errors.UnsupportedCreateArgs( 882 "--kernel-* is not supported for goldfish.") 883 884 remote_boot_flags = [ 885 args.boot_build_id, 886 args.boot_build_target, 887 args.boot_branch, 888 args.boot_artifact, 889 ] 890 if (args.avd_type == constants.TYPE_GF and any(remote_boot_flags) and 891 not all(remote_boot_flags)): 892 raise errors.UnsupportedCreateArgs( 893 "Either none or all of --boot-branch, --boot-build-target, " 894 "--boot-build-id, and --boot-artifact must be specified for " 895 "goldfish.") 896 897 remote_system_flags = [ 898 args.system_build_target, 899 args.system_build_id, 900 args.system_branch, 901 ] 902 if (args.avd_type == constants.TYPE_GF and any(remote_system_flags) and 903 not all(remote_system_flags)): 904 raise errors.UnsupportedCreateArgs( 905 "Either none or all of --system-branch, --system-build-target, " 906 "and --system-build-id must be specified for goldfish.") 907 908 remote_host_only_flags = remote_boot_flags + remote_system_flags 909 if args.avd_type == constants.TYPE_GF and args.remote_host is None and any( 910 remote_host_only_flags): 911 raise errors.UnsupportedCreateArgs( 912 "--boot-* and --system-* for goldfish are only supported for " 913 "remote host.") 914 915 916def VerifyArgs(args): 917 """Verify args. 918 919 Args: 920 args: Namespace object from argparse.parse_args. 921 922 Raises: 923 errors.UnsupportedMultiAdbPort: multi adb port doesn't support. 924 errors.UnsupportedCreateArgs: When a create arg is specified but 925 unsupported for a particular avd type. 926 (e.g. --system-build-id for gf) 927 """ 928 # Verify that user specified flavor name is in support list. 929 # We don't use argparse's builtin validation because we need to be able to 930 # tell when a user doesn't specify a flavor. 931 if args.flavor and args.flavor not in constants.ALL_FLAVORS: 932 logger.debug("Flavor[%s] isn't in default support list: %s", 933 args.flavor, constants.ALL_FLAVORS) 934 935 if args.avd_type not in (constants.TYPE_CF, constants.TYPE_GF): 936 if args.system_branch or args.system_build_id or args.system_build_target: 937 raise errors.UnsupportedCreateArgs( 938 "--system-* args are not supported for AVD type: %s" 939 % args.avd_type) 940 941 if args.num > 1: 942 if args.adb_port is not None: 943 raise errors.UnsupportedMultiAdbPort( 944 "--adb-port is not supported for multi-devices.") 945 946 if args.fastboot_port is not None: 947 raise errors.UnsupportedMultiAdbPort( 948 "--fastboot-port is not supported for multi-devices.") 949 950 if args.local_instance is not None: 951 raise errors.UnsupportedCreateArgs( 952 "--num is not supported for local instance.") 953 954 if args.local_instance is None and args.gpu == _DEFAULT_GPU: 955 raise errors.UnsupportedCreateArgs( 956 "Please assign one gpu model for GCE instance. Reference: " 957 "https://cloud.google.com/compute/docs/gpus") 958 959 if args.adb_port is not None: 960 utils.CheckPortFree(args.adb_port) 961 962 if args.fastboot_port is not None: 963 utils.CheckPortFree(args.fastboot_port) 964 965 hw_properties = create_common.ParseKeyValuePairArgs(args.hw_property) 966 for key in hw_properties: 967 if key not in constants.HW_PROPERTIES: 968 raise errors.InvalidHWPropertyError( 969 "[%s] is an invalid hw property, supported values are:%s. " 970 % (key, constants.HW_PROPERTIES)) 971 972 cheeps_only_flags = [args.stable_cheeps_host_image_name, 973 args.stable_cheeps_host_image_project, 974 args.username, 975 args.password, 976 args.cheeps_betty_image, 977 args.cheeps_features] 978 if args.avd_type != constants.TYPE_CHEEPS and any(cheeps_only_flags): 979 raise errors.UnsupportedCreateArgs( 980 "--stable-cheeps-*, --betty-image, --cheeps-feature, --username " 981 "and --password are only valid with avd_type == %s" 982 % constants.TYPE_CHEEPS) 983 if (args.username or args.password) and not (args.username and args.password): 984 raise ValueError("--username and --password must both be set") 985 if not args.autoconnect and args.unlock_screen: 986 raise ValueError("--no-autoconnect and --unlock couldn't be " 987 "passed in together.") 988 989 _VerifyGoldfishArgs(args) 990 _VerifyLocalArgs(args) 991 _VerifyHostArgs(args) 992