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 22import posixpath as remote_path 23 24from acloud import errors 25from acloud.create import create_common 26from acloud.internal import constants 27from acloud.internal.lib import utils 28 29logger = logging.getLogger(__name__) 30_DEFAULT_GPU = "default" 31CMD_CREATE = "create" 32 33 34# TODO: Add this into main create args once create_cf/gf is deprecated. 35# pylint: disable=too-many-statements 36def AddCommonCreateArgs(parser): 37 """Adds arguments common to create parsers. 38 39 Args: 40 parser: ArgumentParser object, used to parse flags. 41 """ 42 parser.add_argument( 43 "--num", 44 type=int, 45 dest="num", 46 required=False, 47 default=1, 48 help="Number of instances to create.") 49 parser.add_argument( 50 "--serial-log-file", 51 type=str, 52 dest="serial_log_file", 53 required=False, 54 help="Path to a *tar.gz file where serial logs will be saved " 55 "when a device fails on boot.") 56 parser.add_argument( 57 "--autoconnect", 58 type=str, 59 nargs="?", 60 const=constants.INS_KEY_WEBRTC, 61 dest="autoconnect", 62 required=False, 63 choices=[constants.INS_KEY_VNC, constants.INS_KEY_ADB, 64 constants.INS_KEY_WEBRTC], 65 help="Determines to establish a tunnel forwarding adb/vnc and " 66 "launch VNC/webrtc. Establish a tunnel forwarding adb and vnc " 67 "then launch vnc if --autoconnect vnc is provided. Establish a " 68 "tunnel forwarding adb if --autoconnect adb is provided. " 69 "Establish a tunnel forwarding adb 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-trunk_staging-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 "--android-efi-loader-build-id", 178 type=str, 179 dest="android_efi_loader_build_id", 180 help="'cuttlefish only' Android EFI loader build id, e.g. P2804227", 181 required=False) 182 parser.add_argument( 183 "--android-efi-loader-artifact", 184 type=str, 185 dest="android_efi_loader_artifact", 186 help="'cuttlefish only' Android EFI loader artifact name, e.g. gbl_aarch64.efi", 187 required=False) 188 parser.add_argument( 189 "--kernel-build-id", 190 type=str, 191 dest="kernel_build_id", 192 required=False, 193 help="Android kernel build id, e.g. 4586590. This is to test a new" 194 " kernel build with a particular Android build (--build-id). If neither" 195 " kernel-branch nor kernel-build-id are specified, the kernel that's" 196 " bundled with the Android build would be used.") 197 parser.add_argument( 198 "--kernel-branch", 199 type=str, 200 dest="kernel_branch", 201 required=False, 202 help="Android kernel build branch name, e.g." 203 " kernel-common-android-4.14. This is to test a new kernel build with a" 204 " particular Android build (--build-id). If specified without" 205 " specifying kernel-build-id, the last green build in the branch will" 206 " be used. If neither kernel-branch nor kernel-build-id are specified," 207 " the kernel that's bundled with the Android build would be used.") 208 parser.add_argument( 209 "--kernel-build-target", 210 type=str, 211 dest="kernel_build_target", 212 default="kernel", 213 help="Kernel build target, specify if different from 'kernel'") 214 parser.add_argument( 215 "--boot-build-id", 216 type=str, 217 dest="boot_build_id", 218 required=False, 219 help="Boot image build ID, e.g., 8747889, 8748012.") 220 parser.add_argument( 221 "--boot-branch", 222 type=str, 223 dest="boot_branch", 224 required=False, 225 help="Boot image branch, e.g., aosp-gki13-boot-release, aosp-main.") 226 parser.add_argument( 227 "--boot-build-target", 228 type=str, 229 dest="boot_build_target", 230 required=False, 231 help="Boot image build target, " 232 "e.g., gki_x86_64-userdebug, aosp_cf_x86_64_phone-trunk_staging-userdebug.") 233 parser.add_argument( 234 "--boot-artifact", 235 type=str, 236 dest="boot_artifact", 237 required=False, 238 help="The name of the boot image to be retrieved from Android build, " 239 "e.g., boot-5.10.img, boot.img.") 240 parser.add_argument( 241 "--ota-branch", 242 type=str, 243 dest="ota_branch", 244 required=False, 245 help="'cuttlefish only' OTA tools branch name. e.g. aosp-main") 246 parser.add_argument( 247 "--ota-build-id", 248 type=str, 249 dest="ota_build_id", 250 required=False, 251 help="'cuttlefish only' OTA tools build id, e.g. 2145099, P2804227") 252 parser.add_argument( 253 "--ota-build-target", 254 type=str, 255 dest="ota_build_target", 256 required=False, 257 help="'cuttlefish only' OTA tools build target, e.g. " 258 "cf_x86_64_phone-trunk_staging-userdebug.") 259 parser.add_argument( 260 "--host-package-branch", "--host_package_branch", 261 type=str, 262 dest="host_package_branch", 263 required=False, 264 help="'cuttlefish and trusty only' Host package branch name. e.g. " 265 "aosp-main") 266 parser.add_argument( 267 "--host-package-build-id", "--host_package_build_id", 268 type=str, 269 dest="host_package_build_id", 270 required=False, 271 help="'cuttlefish and trusty only' Host package build id, e.g. " 272 "2145099, P2804227") 273 parser.add_argument( 274 "--host-package-build-target", "--host_package_build_target", 275 type=str, 276 dest="host_package_build_target", 277 required=False, 278 help="'cuttlefish and trusty only' Host package build target, e.g. " 279 "cf_x86_64_phone-trunk_staging-userdebug.") 280 parser.add_argument( 281 "--system-branch", 282 type=str, 283 dest="system_branch", 284 help="'cuttlefish only' Branch to consume the system image (system.img) " 285 "from, will default to what is defined by --branch. " 286 "That feature allows to (automatically) test various combinations " 287 "of vendor.img (CF, e.g.) and system images (GSI, e.g.). ", 288 required=False) 289 parser.add_argument( 290 "--system-build-id", 291 type=str, 292 dest="system_build_id", 293 help="'cuttlefish only' System image build id, e.g. 2145099, P2804227", 294 required=False) 295 parser.add_argument( 296 "--system-build-target", 297 type=str, 298 dest="system_build_target", 299 help="'cuttlefish only' System image build target, specify if different " 300 "from --build-target", 301 required=False) 302 parser.add_argument( 303 "--launch-args", 304 type=str, 305 dest="launch_args", 306 help="'cuttlefish only' Add extra args to launch_cvd command.", 307 required=False) 308 parser.add_argument( 309 "--pet-name", 310 "--webrtc_device_id", 311 type=str, 312 dest="webrtc_device_id", 313 help="'cuttlefish only' Give the pet name of the instance.", 314 required=False) 315 parser.add_argument( 316 "--gce-metadata", 317 type=str, 318 dest="gce_metadata", 319 default=None, 320 help="'GCE instance only' Record data into GCE instance metadata with " 321 "key-value pair format. e.g. id:12,name:unknown.") 322 parser.add_argument( 323 "--fetch_cvd-build-id", 324 type=str, 325 dest="fetch_cvd_build_id", 326 required=False, 327 help="Deprecated - any values input through this param are ignored") 328 # TODO(146314062): Remove --multi-stage-launch after infra don't use this 329 # args. 330 parser.add_argument( 331 "--multi-stage-launch", 332 dest="multi_stage_launch", 333 action="store_true", 334 required=False, 335 default=True, 336 help="Enable the multi-stage cuttlefish launch.") 337 parser.add_argument( 338 "--no-multi-stage-launch", 339 dest="multi_stage_launch", 340 action="store_false", 341 required=False, 342 default=None, 343 help="Disable the multi-stage cuttlefish launch.") 344 parser.add_argument( 345 "--no-pull-log", 346 dest="no_pull_log", 347 action="store_true", 348 required=False, 349 default=None, 350 help="Disable auto download logs when AVD booting up failed.") 351 parser.add_argument( 352 "--no-mkcert", 353 dest="mkcert", 354 action="store_false", 355 required=False, 356 default=True, 357 help="Disable mkcert setup process on the host.") 358 # TODO(147335651): Add gpu in user config. 359 # TODO(147335651): Support "--gpu" without giving any value. 360 parser.add_argument( 361 "--gpu", 362 type=str, 363 const=_DEFAULT_GPU, 364 nargs="?", 365 dest="gpu", 366 required=False, 367 default=None, 368 help="GPU accelerator to use if any. e.g. nvidia-tesla-k80. For local " 369 "instances, this arg without assigning any value is to enable " 370 "local gpu support.") 371 parser.add_argument( 372 "--num-avds-per-instance", 373 "--num-instances", 374 "--num_instances", 375 type=int, 376 dest="num_avds_per_instance", 377 required=False, 378 default=1, 379 help="'cuttlefish only' Create multiple cuttlefish AVDs in one local " 380 "instance.") 381 parser.add_argument( 382 "--connect-hostname", 383 action="store_true", 384 dest="connect_hostname", 385 required=False, 386 default=False, 387 help="Ssh connects to the GCE instance with hostname.") 388 parser.add_argument( 389 "--gce-only", 390 action="store_true", 391 dest="gce_only", 392 required=False, 393 default=False, 394 help="Only create the GCE instance. It won't create virtual devices.") 395 # Hide following args for users, it is only used in infra. 396 parser.add_argument( 397 "--local-instance-dir", 398 dest="local_instance_dir", 399 required=False, 400 help=argparse.SUPPRESS) 401 parser.add_argument( 402 "--mix-system_dlkm-into-vendor-ramdisk", 403 dest="mix_system_dlkm_into_vendor_ramdisk", 404 action="store_true", 405 required=False, 406 # Extract system_dlkm image and mix it into vendor ramdisk. The mixing 407 # process overwrites some of the modules in the vendor ramdisk. It is 408 # effective only if both --local-boot-image and 409 # --local-system_dlkm-image are specified. 410 help=argparse.SUPPRESS) 411 parser.add_argument( 412 "--remote-image-dir", 413 dest="remote_image_dir", 414 required=False, 415 # 'cuttlefish remote host only' Upload images and cvd host package to 416 # the remote directory instead of the instance's own directory. If the 417 # directory has been initialized, acloud ignores the image arguments 418 # given by command line and reuses the images in the directory. 419 help=argparse.SUPPRESS) 420 parser.add_argument( 421 "--oxygen", 422 action="store_true", 423 dest="oxygen", 424 required=False, 425 help=argparse.SUPPRESS) 426 parser.add_argument( 427 "--zone", 428 type=str, 429 dest="zone", 430 required=False, 431 help=argparse.SUPPRESS) 432 433 # TODO(b/118439885): Old arg formats to support transition, delete when 434 # transistion is done. 435 parser.add_argument( 436 "--serial_log_file", 437 type=str, 438 dest="serial_log_file", 439 required=False, 440 help=argparse.SUPPRESS) 441 parser.add_argument( 442 "--build_id", 443 type=str, 444 dest="build_id", 445 required=False, 446 help=argparse.SUPPRESS) 447 parser.add_argument( 448 "--build_target", 449 type=str, 450 dest="build_target", 451 required=False, 452 help=argparse.SUPPRESS) 453 parser.add_argument( 454 "--system_branch", 455 type=str, 456 dest="system_branch", 457 required=False, 458 help=argparse.SUPPRESS) 459 parser.add_argument( 460 "--system_build_id", 461 type=str, 462 dest="system_build_id", 463 required=False, 464 help=argparse.SUPPRESS) 465 parser.add_argument( 466 "--system_build_target", 467 type=str, 468 dest="system_build_target", 469 required=False, 470 help=argparse.SUPPRESS) 471 parser.add_argument( 472 "--kernel_build_id", 473 type=str, 474 dest="kernel_build_id", 475 required=False, 476 help=argparse.SUPPRESS) 477 parser.add_argument( 478 "--kernel_branch", 479 type=str, 480 dest="kernel_branch", 481 required=False, 482 help=argparse.SUPPRESS) 483 parser.add_argument( 484 "--kernel_build_target", 485 type=str, 486 dest="kernel_build_target", 487 default="kernel", 488 help=argparse.SUPPRESS) 489 parser.add_argument( 490 "--bootloader_branch", 491 type=str, 492 dest="bootloader_branch", 493 help=argparse.SUPPRESS, 494 required=False) 495 parser.add_argument( 496 "--bootloader_build_id", 497 type=str, 498 dest="bootloader_build_id", 499 help=argparse.SUPPRESS, 500 required=False) 501 parser.add_argument( 502 "--bootloader_build_target", 503 type=str, 504 dest="bootloader_build_target", 505 help=argparse.SUPPRESS, 506 required=False) 507 parser.add_argument( 508 "--fetch_cvd_build_id", 509 type=str, 510 dest="fetch_cvd_build_id", 511 help=argparse.SUPPRESS, 512 required=False) 513 parser.add_argument( 514 "--remote-fetch", 515 action="store_true", 516 dest="remote_fetch", 517 required=False, 518 default=None, 519 help="'cuttlefish only' Fetch artifacts in remote host.") 520 parser.add_argument( 521 "--fetch-cvd-wrapper", 522 dest="fetch_cvd_wrapper", 523 type=str, 524 required=False, 525 help="'cuttlefish only' Fetch artifacts in remote host by a" 526 " provided static executable fetch cvd wrapper file. " 527 " (Still in experiment, this flag only works on lab hosts" 528 " with special setup.)") 529 parser.add_argument( 530 "--enable_fetch_local_caching", 531 action="store_true", 532 dest="enable_fetch_local_caching", 533 required=False, 534 help="'cuttlefish only' When enabled, fetched artifacts may be saved " 535 "to a local cache to avoid network requests on repeated fetches of the" 536 " same artifacts." 537 ) 538 539 540def GetCreateArgParser(subparser): 541 """Return the create arg parser. 542 543 Args: 544 subparser: argparse.ArgumentParser that is attached to main acloud cmd. 545 546 Returns: 547 argparse.ArgumentParser with create options defined. 548 """ 549 create_parser = subparser.add_parser(CMD_CREATE) 550 create_parser.required = False 551 create_parser.set_defaults(which=CMD_CREATE) 552 # Use default=None to distinguish remote instance or local. The instance 553 # type will be remote if the arg is not provided. 554 create_parser.add_argument( 555 "--local-instance", 556 type=_PositiveInteger, 557 const=0, 558 metavar="ID", 559 nargs="?", 560 dest="local_instance", 561 required=False, 562 help="Create a local AVD instance using the resources associated with " 563 "the ID. Choose an unused ID automatically if the value is " 564 "not specified (primarily for infra usage).") 565 create_parser.add_argument( 566 "--adb-port", "-p", 567 type=int, 568 default=None, 569 dest="adb_port", 570 required=False, 571 help="Specify port for adb forwarding.") 572 create_parser.add_argument( 573 "--base-instance-num", 574 type=int, 575 default=None, 576 dest="base_instance_num", 577 required=False, 578 help="'cuttlefish only' The instance number of the created device.") 579 create_parser.add_argument( 580 "--avd-type", 581 type=str, 582 dest="avd_type", 583 default=constants.TYPE_CF, 584 choices=[constants.TYPE_GCE, constants.TYPE_CF, constants.TYPE_GF, constants.TYPE_CHEEPS, 585 constants.TYPE_FVP, constants.TYPE_TRUSTY], 586 help="Android Virtual Device type (default %s)." % constants.TYPE_CF) 587 create_parser.add_argument( 588 "--config", "--flavor", 589 type=str, 590 dest="flavor", 591 help="The device flavor of the AVD (default %s). e.g. phone, tv, foldable." 592 % constants.FLAVOR_PHONE) 593 create_parser.add_argument( 594 "--local-image", 595 const=constants.FIND_IN_BUILD_ENV, 596 type=str, 597 dest="local_image", 598 nargs="?", 599 required=False, 600 help="Use the locally built image for the AVD. Look for the image " 601 "artifact in $ANDROID_PRODUCT_OUT if no args value is provided." 602 "e.g --local-image or --local-image /path/to/dir or --local-image " 603 "/path/to/file") 604 create_parser.add_argument( 605 "--local-kernel-image", "--local-boot-image", 606 const=constants.FIND_IN_BUILD_ENV, 607 type=str, 608 dest="local_kernel_image", 609 nargs="?", 610 required=False, 611 help="Use the locally built kernel and ramdisk for the AVD. Look " 612 "for boot.img, vendor_boot.img, kernel, initramfs.img, etc. if the " 613 "argument is a directory. Look for the images in $ANDROID_PRODUCT_OUT " 614 "if no argument is provided. e.g., --local-kernel-image, " 615 "--local-kernel-image /path/to/dir, or --local-kernel-image " 616 "/path/to/boot.img") 617 create_parser.add_argument( 618 "--local-system-image", 619 const=constants.FIND_IN_BUILD_ENV, 620 type=str, 621 dest="local_system_image", 622 nargs="?", 623 required=False, 624 help="Use the locally built system images for the AVD. Look for the " 625 "images in $ANDROID_PRODUCT_OUT if no args value is provided. " 626 "e.g., --local-system-image, --local-system-image /path/to/dir, or " 627 "--local-system-image /path/to/img") 628 create_parser.add_argument( 629 "--local-system_dlkm-image", 630 const=constants.FIND_IN_BUILD_ENV, 631 type=str, 632 dest="local_system_dlkm_image", 633 nargs="?", 634 required=False, 635 help="`remote host only` Use the locally built system_dlkm image for " 636 "the AVD. Look for the image in $ANDROID_PRODUCT_OUT if no args value " 637 "is provided.") 638 create_parser.add_argument( 639 "--local-vendor-image", 640 const=constants.FIND_IN_BUILD_ENV, 641 type=str, 642 dest="local_vendor_image", 643 nargs="?", 644 required=False, 645 help="'cuttlefish only' Use the locally built vendor images for the " 646 "AVD. Look for vendor.img, vendor_dlkm.img, odm.img, and odm_dlkm.img " 647 "if the argument is a directory. Look for the images in " 648 "$ANDROID_PRODUCT_OUT if no argument is provided. e.g., " 649 "--local-vendor-image, or --local-vendor-image /path/to/dir") 650 create_parser.add_argument( 651 "--local-vendor_boot-image", "--local-vendor-boot-image", 652 const=constants.FIND_IN_BUILD_ENV, 653 type=str, 654 dest="local_vendor_boot_image", 655 nargs="?", 656 required=False, 657 help="'cuttlefish only' Use the locally built vendor boot image for " 658 "the AVD. Look for the vendor_boot.img in $ANDROID_PRODUCT_OUT " 659 "if no argument is provided. e.g., --local-vendor-boot-image, or " 660 "--local-vendor-boot-image /path/to/dir, or " 661 "--local-vendor-boot-image /path/to/img") 662 create_parser.add_argument( 663 "--local-tool", 664 type=str, 665 dest="local_tool", 666 action="append", 667 default=[], 668 required=False, 669 help="Use the tools in the specified directory to create local " 670 "instances. The directory structure follows $ANDROID_SOONG_HOST_OUT " 671 "or $ANDROID_EMULATOR_PREBUILTS.") 672 create_parser.add_argument( 673 "--cvd-host-package", 674 type=str, 675 dest="cvd_host_package", 676 required=False, 677 help="Use the specified path of the cvd host package to create " 678 "instances. e.g. /path/cvd-host_package_v1.tar.gz") 679 create_parser.add_argument( 680 "--image-download-dir", 681 type=str, 682 dest="image_download_dir", 683 required=False, 684 help="Define remote image download directory, e.g. /usr/local/dl.") 685 create_parser.add_argument( 686 "--yes", "-y", 687 action="store_true", 688 dest="no_prompt", 689 required=False, 690 help=("Automatic yes to prompts. Assume 'yes' as answer to all prompts " 691 "and run non-interactively.")) 692 create_parser.add_argument( 693 "--reuse-gce", 694 type=str, 695 const=constants.SELECT_ONE_GCE_INSTANCE, 696 nargs="?", 697 dest="reuse_gce", 698 required=False, 699 help="'cuttlefish only' This can help users use their own instance. " 700 "Reusing specific gce instance if --reuse-gce [instance_name] is " 701 "provided. Select one gce instance to reuse if --reuse-gce is " 702 "provided.") 703 create_parser.add_argument( 704 "--openwrt", 705 action="store_true", 706 dest="openwrt", 707 required=False, 708 help="'cuttlefish only' Create OpenWrt device when launching cuttlefish " 709 "device.") 710 create_parser.add_argument( 711 "--use-launch_cvd", 712 action="store_true", 713 dest="use_launch_cvd", 714 required=False, 715 help="'cuttlefish only' Use launch_cvd to create cuttlefish devices.") 716 create_parser.add_argument( 717 "--host", 718 type=str, 719 dest="remote_host", 720 default=None, 721 help="'cuttlefish only' Provide host name to clean up the remote host. " 722 "For example: '--host 1.1.1.1'") 723 create_parser.add_argument( 724 "--host-user", 725 type=str, 726 dest="host_user", 727 default=constants.GCE_USER, 728 help="'remote host only' Provide host user for logging in to the host. " 729 "The default value is vsoc-01. For example: '--host 1.1.1.1 --host-user " 730 "vsoc-02'") 731 create_parser.add_argument( 732 "--host-ssh-private-key-path", 733 type=str, 734 dest="host_ssh_private_key_path", 735 default=None, 736 help="'remote host only' Provide host key for login on on this host.") 737 # User should not specify --spec and --hw_property at the same time. 738 hw_spec_group = create_parser.add_mutually_exclusive_group() 739 hw_spec_group.add_argument( 740 "--hw-property", 741 type=str, 742 dest="hw_property", 743 required=False, 744 help="Supported HW properties and example values: %s" % 745 constants.HW_PROPERTIES_CMD_EXAMPLE) 746 hw_spec_group.add_argument( 747 "--spec", 748 type=str, 749 dest="spec", 750 required=False, 751 choices=constants.SPEC_NAMES, 752 help="The name of a pre-configured device spec that we are " 753 "going to use.") 754 create_parser.add_argument( 755 "--disk-type", 756 type=str, 757 dest="disk_type", 758 required=False, 759 help="This is used to customize the GCE instance disk type, the " 760 "default disk type is from the stable host image. Use pd-ssd or " 761 "pd-standard to specify instance disk type.") 762 create_parser.add_argument( 763 "--stable-host-image-name", 764 type=str, 765 dest="stable_host_image_name", 766 required=False, 767 default=None, 768 help=("'cuttlefish only' The Cuttlefish host image from which instances " 769 "are launched. If specified here, the value set in Acloud config " 770 "file will be overridden.")) 771 772 # Arguments for goldfish type. 773 create_parser.add_argument( 774 "--emulator-build-id", 775 type=str, 776 dest="emulator_build_id", 777 required=False, 778 help="'goldfish only' Emulator build ID used to run the images. " 779 "e.g. 4669466.") 780 create_parser.add_argument( 781 "--emulator-build-target", 782 dest="emulator_build_target", 783 required=False, 784 help="'goldfish remote host only' Emulator build target used to run " 785 "the images. e.g. emulator-linux_x64_nolocationui.") 786 create_parser.add_argument( 787 "--emulator-zip", 788 dest="emulator_zip", 789 required=False, 790 help="'goldfish remote host only' Emulator zip used to run the " 791 "images. e.g., /path/sdk-repo-linux-emulator-1234567.zip.") 792 793 # Arguments for cheeps type. 794 create_parser.add_argument( 795 "--stable-cheeps-host-image-name", 796 type=str, 797 dest="stable_cheeps_host_image_name", 798 required=False, 799 default=None, 800 help=("'cheeps only' The Cheeps host image from which instances are " 801 "launched. If specified here, the value set in Acloud config " 802 "file will be overridden.")) 803 create_parser.add_argument( 804 "--stable-cheeps-host-image-project", 805 type=str, 806 dest="stable_cheeps_host_image_project", 807 required=False, 808 default=None, 809 help=("'cheeps only' The project hosting the specified Cheeps host " 810 "image. If specified here, the value set in Acloud config file " 811 "will be overridden.")) 812 create_parser.add_argument( 813 "--user", 814 type=str, 815 dest="username", 816 required=False, 817 default=None, 818 help="'cheeps only' username to log in to Chrome OS as.") 819 create_parser.add_argument( 820 "--password", 821 type=str, 822 dest="password", 823 required=False, 824 default=None, 825 help="'cheeps only' password to log in to Chrome OS with.") 826 create_parser.add_argument( 827 "--betty-image", 828 type=str, 829 dest="cheeps_betty_image", 830 required=False, 831 default=None, 832 help=("'cheeps only' The L1 betty version to use. Only makes sense " 833 "when launching a controller image with " 834 "stable-cheeps-host-image")) 835 create_parser.add_argument( 836 "--cheeps-feature", 837 type=str, 838 dest="cheeps_features", 839 required=False, 840 action="append", 841 default=[], 842 help=("'cheeps only' Cheeps feature to enable. Can be repeated.")) 843 844 # Arguments for trusty type 845 create_parser.add_argument( 846 "--trusty-host-package", 847 type=str, 848 dest="trusty_host_package", 849 required=False, 850 help="Use the specified path of the trusty host package to create " 851 "instances. e.g. /path/trusty-host_package.tar.gz") 852 create_parser.add_argument( 853 "--local-trusty-image", 854 type=str, 855 dest="local_trusty_image", 856 required=False, 857 help="'trusty only' Use the specified path for the locally built " 858 "trusty emulator images package, built with " 859 "PACKAGE_TRUSTY_IMAGE_TARBALL=true in the Trusty build. E.g., " 860 "/path/trusty_image_package.tar.gz") 861 create_parser.add_argument( 862 "--trusty-build-id", 863 type=str, 864 dest="trusty_build_id", 865 required=False, 866 help="Trusty image package build ID, e.g., 8747889, 8748012.") 867 create_parser.add_argument( 868 "--trusty-branch", 869 type=str, 870 dest="trusty_branch", 871 required=False, 872 help="Trusty image package branch, e.g., aosp-trusty-master.") 873 create_parser.add_argument( 874 "--trusty-build-target", 875 type=str, 876 dest="trusty_build_target", 877 required=False, 878 help="Trusty image package build target, " 879 "e.g., qemu_generic_arm64_test_debug.") 880 881 AddCommonCreateArgs(create_parser) 882 return create_parser 883 884 885def _PositiveInteger(arg): 886 """Convert an argument from a string to a positive integer.""" 887 try: 888 value = int(arg) 889 except ValueError as e: 890 raise argparse.ArgumentTypeError(arg + " is not an integer.") from e 891 if value <= 0: 892 raise argparse.ArgumentTypeError(arg + " is not positive.") 893 return value 894 895 896def _VerifyLocalArgs(args): 897 """Verify args starting with --local. 898 899 Args: 900 args: Namespace object from argparse.parse_args. 901 902 Raises: 903 errors.CheckPathError: Image path doesn't exist. 904 errors.UnsupportedCreateArgs: The specified avd type does not support 905 a provided argument. 906 errors.UnsupportedLocalInstanceId: Local instance ID is invalid. 907 """ 908 for local_path in [args.local_image, args.local_instance_dir, 909 args.local_kernel_image, args.local_system_image, 910 args.local_system_dlkm_image, args.local_vendor_image, 911 args.local_vendor_boot_image] + args.local_tool: 912 if local_path and not os.path.exists(local_path): 913 raise errors.CheckPathError( 914 f"Specified path doesn't exist: {local_path}") 915 916 if args.local_instance_dir and not os.path.exists(args.local_instance_dir): 917 raise errors.CheckPathError( 918 "Specified path doesn't exist: %s" % args.local_instance_dir) 919 920 if args.mix_system_dlkm_into_vendor_ramdisk and ( 921 args.local_kernel_image is None or 922 args.local_system_dlkm_image is None): 923 raise errors.UnsupportedCreateArgs( 924 "If --mix-system_dlkm-into-vendor-ramdisk is specified, " 925 "--local-system_dlkm-image and --local-kernel-image must be " 926 "specified.") 927 928 if not (args.local_system_image is None or 929 args.avd_type in (constants.TYPE_CF, constants.TYPE_GF)): 930 raise errors.UnsupportedCreateArgs("%s instance does not support " 931 "--local-system-image" % 932 args.avd_type) 933 # TODO(b/179340595): To support local image remote instance with kernel build. 934 if args.local_instance is None and args.local_image is not None and ( 935 args.kernel_branch or args.kernel_build_id): 936 raise errors.UnsupportedCreateArgs( 937 "Acloud didn't support local image with specific kernel. " 938 "Please download the specific kernel and put it into " 939 "your local image folder: '%s'." % ( 940 args.local_image if args.local_image else 941 utils.GetBuildEnvironmentVariable(constants.ENV_ANDROID_PRODUCT_OUT))) 942 943 944def _VerifyHostArgs(args): 945 """Verify args starting with --host. 946 947 Args: 948 args: Namespace object from argparse.parse_args. 949 950 Raises: 951 errors.UnsupportedCreateArgs: When a create arg is specified but 952 unsupported for remote host mode. 953 """ 954 if args.remote_host and args.local_instance is not None: 955 raise errors.UnsupportedCreateArgs( 956 "--host is not supported for local instance.") 957 958 if args.remote_host and args.num > 1: 959 raise errors.UnsupportedCreateArgs( 960 "--num is not supported for remote host.") 961 962 if args.host_user != constants.GCE_USER and args.remote_host is None: 963 raise errors.UnsupportedCreateArgs( 964 "--host-user is only supported for remote host.") 965 966 if args.host_ssh_private_key_path and args.remote_host is None: 967 raise errors.UnsupportedCreateArgs( 968 "--host-ssh-private-key-path is only supported for remote host.") 969 970 if args.remote_image_dir: 971 if args.remote_host is None: 972 raise errors.UnsupportedCreateArgs( 973 "--remote-image-dir is only supported for remote host.") 974 if remote_path.basename( 975 remote_path.normpath(args.remote_image_dir)) in ("..", "."): 976 raise errors.UnsupportedCreateArgs( 977 "--remote-image-dir must not include the working directory.") 978 979 980def _VerifyGoldfishArgs(args): 981 """Verify goldfish args. 982 983 Args: 984 args: Namespace object from argparse.parse_args. 985 986 Raises: 987 errors.UnsupportedCreateArgs: When a create arg is specified but 988 unsupported for goldfish. 989 """ 990 goldfish_only_flags = [ 991 args.emulator_build_id, 992 args.emulator_build_target, 993 args.emulator_zip, 994 args.mix_system_dlkm_into_vendor_ramdisk, 995 ] 996 if args.avd_type != constants.TYPE_GF and any(goldfish_only_flags): 997 raise errors.UnsupportedCreateArgs( 998 "--emulator-* and --mix-system_dlkm-into-vendor-ramdisk are only " 999 f"valid with avd_type == {constants.TYPE_GF}") 1000 1001 # Exclude kernel_build_target because the default value isn't empty. 1002 remote_kernel_flags = [ 1003 args.kernel_build_id, 1004 args.kernel_branch, 1005 ] 1006 if args.avd_type == constants.TYPE_GF and any(remote_kernel_flags): 1007 raise errors.UnsupportedCreateArgs( 1008 "--kernel-* is not supported for goldfish.") 1009 1010 remote_boot_flags = [ 1011 args.boot_build_id, 1012 args.boot_build_target, 1013 args.boot_branch, 1014 args.boot_artifact, 1015 ] 1016 if (args.avd_type == constants.TYPE_GF and any(remote_boot_flags) and 1017 not all(remote_boot_flags)): 1018 raise errors.UnsupportedCreateArgs( 1019 "Either none or all of --boot-branch, --boot-build-target, " 1020 "--boot-build-id, and --boot-artifact must be specified for " 1021 "goldfish.") 1022 1023 remote_system_flags = [ 1024 args.system_build_target, 1025 args.system_build_id, 1026 args.system_branch, 1027 ] 1028 if (args.avd_type == constants.TYPE_GF and any(remote_system_flags) and 1029 not all(remote_system_flags)): 1030 raise errors.UnsupportedCreateArgs( 1031 "Either none or all of --system-branch, --system-build-target, " 1032 "and --system-build-id must be specified for goldfish.") 1033 1034 remote_host_only_flags = remote_boot_flags + remote_system_flags 1035 if args.avd_type == constants.TYPE_GF and args.remote_host is None and any( 1036 remote_host_only_flags): 1037 raise errors.UnsupportedCreateArgs( 1038 "--boot-* and --system-* for goldfish are only supported for " 1039 "remote host.") 1040 1041 1042def _VerifyTrustyArgs(args): 1043 """Verify trusty args. 1044 1045 Args: 1046 args: Namespace object from argparse.parse_args. 1047 1048 Raises: 1049 errors.UnsupportedCreateArgs: When specified arguments are 1050 unsupported for trusty. 1051 errors.CheckPathError: A specified local path does not exist. 1052 """ 1053 if args.avd_type != constants.TYPE_TRUSTY: 1054 if args.local_trusty_image: 1055 raise errors.UnsupportedCreateArgs( 1056 "--local-trusty-image is only valid with " 1057 f"avd_type == {constants.TYPE_TRUSTY}") 1058 if args.trusty_host_package: 1059 raise errors.UnsupportedCreateArgs( 1060 "--trusty-host-package is only valid with " 1061 f"avd_type == {constants.TYPE_TRUSTY}") 1062 # Only check these args if AVD type is Trusty 1063 return 1064 1065 for arg_type, unsupported_args in [ 1066 ( 1067 "--boot-*", 1068 [ 1069 args.boot_build_id, 1070 args.boot_build_target, 1071 args.boot_branch, 1072 args.boot_artifact, 1073 ], 1074 ), 1075 ( 1076 "--bootloader-*", 1077 [ 1078 args.bootloader_build_id, 1079 args.bootloader_build_target, 1080 args.bootloader_branch, 1081 ], 1082 ), 1083 ( 1084 "--android-efi-loader-*", 1085 [ 1086 args.android_efi_loader_build_id, 1087 args.android_efi_loader_artifact, 1088 ], 1089 ), 1090 ( 1091 "--ota-*", 1092 [ 1093 args.ota_branch, 1094 args.ota_build_target, 1095 args.ota_build_id, 1096 ], 1097 ), 1098 ]: 1099 if any(unsupported_args): 1100 raise errors.UnsupportedCreateArgs( 1101 f"{arg_type} is not supported for Trusty." 1102 ) 1103 1104 if args.local_image is None and not args.build_target: 1105 raise errors.UnsupportedCreateArgs( 1106 "Trusty android build target not provided and cannot be " 1107 "auto-detected, use --build-target to specify a build target, " 1108 "e.g. qemu_trusty_arm64-trunk_staging-userdebug") 1109 if args.local_trusty_image: 1110 if not os.path.exists(args.local_trusty_image): 1111 raise errors.CheckPathError( 1112 f"Specified path doesn't exist: {args.local_trusty_image}") 1113 if args.trusty_host_package: 1114 if not os.path.exists(args.trusty_host_package): 1115 raise errors.CheckPathError( 1116 f"Specified path doesn't exist: {args.trusty_host_package}") 1117 1118 1119def VerifyArgs(args): 1120 """Verify args. 1121 1122 Args: 1123 args: Namespace object from argparse.parse_args. 1124 1125 Raises: 1126 errors.UnsupportedMultiAdbPort: multi adb port doesn't support. 1127 errors.UnsupportedCreateArgs: When a create arg is specified but 1128 unsupported for a particular avd type. 1129 (e.g. --system-build-id for gf) 1130 """ 1131 # Verify that user specified flavor name is in support list. 1132 # We don't use argparse's builtin validation because we need to be able to 1133 # tell when a user doesn't specify a flavor. 1134 if args.flavor and args.flavor not in constants.ALL_FLAVORS: 1135 logger.debug("Flavor[%s] isn't in default support list: %s", 1136 args.flavor, constants.ALL_FLAVORS) 1137 1138 if args.avd_type not in (constants.TYPE_CF, constants.TYPE_GF): 1139 if args.system_branch or args.system_build_id or args.system_build_target: 1140 raise errors.UnsupportedCreateArgs( 1141 "--system-* args are not supported for AVD type: %s" 1142 % args.avd_type) 1143 1144 if args.num > 1 and args.adb_port: 1145 raise errors.UnsupportedMultiAdbPort( 1146 "--adb-port is not supported for multi-devices.") 1147 1148 if args.num > 1 and args.local_instance is not None: 1149 raise errors.UnsupportedCreateArgs( 1150 "--num is not supported for local instance.") 1151 1152 if args.local_instance is None and args.gpu == _DEFAULT_GPU: 1153 raise errors.UnsupportedCreateArgs( 1154 "Please assign one gpu model for GCE instance. Reference: " 1155 "https://cloud.google.com/compute/docs/gpus") 1156 1157 if args.adb_port: 1158 utils.CheckPortFree(args.adb_port) 1159 1160 hw_properties = create_common.ParseKeyValuePairArgs(args.hw_property) 1161 for key in hw_properties: 1162 if key not in constants.HW_PROPERTIES: 1163 raise errors.InvalidHWPropertyError( 1164 "[%s] is an invalid hw property, supported values are:%s. " 1165 % (key, constants.HW_PROPERTIES)) 1166 1167 cheeps_only_flags = [args.stable_cheeps_host_image_name, 1168 args.stable_cheeps_host_image_project, 1169 args.username, 1170 args.password, 1171 args.cheeps_betty_image, 1172 args.cheeps_features] 1173 if args.avd_type != constants.TYPE_CHEEPS and any(cheeps_only_flags): 1174 raise errors.UnsupportedCreateArgs( 1175 "--stable-cheeps-*, --betty-image, --cheeps-feature, --username " 1176 "and --password are only valid with avd_type == %s" 1177 % constants.TYPE_CHEEPS) 1178 if (args.username or args.password) and not (args.username and args.password): 1179 raise ValueError("--username and --password must both be set") 1180 if not args.autoconnect and args.unlock_screen: 1181 raise ValueError("--no-autoconnect and --unlock couldn't be " 1182 "passed in together.") 1183 1184 _VerifyGoldfishArgs(args) 1185 _VerifyTrustyArgs(args) 1186 _VerifyLocalArgs(args) 1187 _VerifyHostArgs(args) 1188