diff options
author | Hsin-Yi Chen <hsinyichen@google.com> | 2023-11-22 09:46:55 +0000 |
---|---|---|
committer | Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com> | 2023-11-22 09:46:55 +0000 |
commit | 1786f4cea2f11c814d1f438196cda576d91af0ee (patch) | |
tree | 36f23b8caeee57704a00c25d79767502f8812bd9 | |
parent | ca593837a85c5eb1b8cabda3ab9feb133890578f (diff) | |
parent | 523412f3017879cc9579ab41f25ae42d1427ae30 (diff) | |
download | acloud-1786f4cea2f11c814d1f438196cda576d91af0ee.tar.gz |
Merge "Distinguish remote runtime directory and image directory" into main am: 523412f301
Original change: https://android-review.googlesource.com/c/platform/tools/acloud/+/2754427
Change-Id: Ia2ac29d9a5bdf2669a718cac2124e3fcd4e9b5cc
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
-rw-r--r-- | internal/lib/cvd_utils.py | 117 | ||||
-rw-r--r-- | public/actions/remote_host_cf_device_factory.py | 48 |
2 files changed, 93 insertions, 72 deletions
diff --git a/internal/lib/cvd_utils.py b/internal/lib/cvd_utils.py index 8f3a2f23..2923e105 100644 --- a/internal/lib/cvd_utils.py +++ b/internal/lib/cvd_utils.py @@ -52,22 +52,29 @@ VendorImagePaths = collections.namedtuple( "VendorImagePaths", ["vendor", "vendor_dlkm", "odm", "odm_dlkm"]) -# The relative path to the base directory containing cuttelfish images, tools, -# and runtime files. On a GCE instance, the directory is the SSH user's HOME. +# The relative path to the base directory containing cuttelfish runtime files. +# On a GCE instance, the directory is the SSH user's HOME. GCE_BASE_DIR = "." _REMOTE_HOST_BASE_DIR_FORMAT = "acloud_cf_%(num)d" -# Relative paths in a base directory. -_REMOTE_IMAGE_DIR = "acloud_image" -_REMOTE_BOOT_IMAGE_PATH = remote_path.join(_REMOTE_IMAGE_DIR, "boot.img") +# By default, fetch_cvd or UploadArtifacts creates remote cuttlefish images and +# tools in the base directory. The user can set the image directory path by +# --remote-image-dir. +# The user may specify extra images such as --local-system-image and +# --local-kernel-image. UploadExtraImages uploads them to "acloud_image" +# subdirectory in the image directory. The following are the relative paths +# under the image directory. +_REMOTE_EXTRA_IMAGE_DIR = "acloud_image" +_REMOTE_BOOT_IMAGE_PATH = remote_path.join(_REMOTE_EXTRA_IMAGE_DIR, "boot.img") _REMOTE_VENDOR_BOOT_IMAGE_PATH = remote_path.join( - _REMOTE_IMAGE_DIR, _VENDOR_BOOT_IMAGE_NAME) -_REMOTE_VBMETA_IMAGE_PATH = remote_path.join(_REMOTE_IMAGE_DIR, "vbmeta.img") + _REMOTE_EXTRA_IMAGE_DIR, _VENDOR_BOOT_IMAGE_NAME) +_REMOTE_VBMETA_IMAGE_PATH = remote_path.join( + _REMOTE_EXTRA_IMAGE_DIR, "vbmeta.img") _REMOTE_KERNEL_IMAGE_PATH = remote_path.join( - _REMOTE_IMAGE_DIR, _KERNEL_IMAGE_NAMES[0]) + _REMOTE_EXTRA_IMAGE_DIR, _KERNEL_IMAGE_NAMES[0]) _REMOTE_INITRAMFS_IMAGE_PATH = remote_path.join( - _REMOTE_IMAGE_DIR, _INITRAMFS_IMAGE_NAME) -_REMOTE_SUPER_IMAGE_PATH = remote_path.join(_REMOTE_IMAGE_DIR, - _SUPER_IMAGE_NAME) + _REMOTE_EXTRA_IMAGE_DIR, _INITRAMFS_IMAGE_NAME) +_REMOTE_SUPER_IMAGE_PATH = remote_path.join( + _REMOTE_EXTRA_IMAGE_DIR, _SUPER_IMAGE_NAME) # Remote host instance name _REMOTE_HOST_INSTANCE_NAME_FORMAT = ( @@ -169,27 +176,27 @@ def ExtractTargetFilesZip(zip_path, output_dir): zip_file.extract(entry, output_dir) -def _UploadImageZip(ssh_obj, remote_dir, image_zip): +def _UploadImageZip(ssh_obj, remote_image_dir, image_zip): """Upload an image zip to a remote host and a GCE instance. Args: ssh_obj: An Ssh object. - remote_dir: The remote base directory. + remote_image_dir: The remote image directory. image_zip: The path to the image zip. """ - remote_cmd = f"/usr/bin/install_zip.sh {remote_dir} < {image_zip}" + remote_cmd = f"/usr/bin/install_zip.sh {remote_image_dir} < {image_zip}" logger.debug("remote_cmd:\n %s", remote_cmd) ssh_obj.Run(remote_cmd) -def _UploadImageDir(ssh_obj, remote_dir, image_dir): +def _UploadImageDir(ssh_obj, remote_image_dir, image_dir): """Upload an image directory to a remote host or a GCE instance. The images are compressed for faster upload. Args: ssh_obj: An Ssh object. - remote_dir: The remote base directory. + remote_image_dir: The remote image directory. image_dir: The directory containing the files to be uploaded. """ try: @@ -208,48 +215,48 @@ def _UploadImageDir(ssh_obj, remote_dir, image_dir): artifact_files.append(constants.ANDROID_INFO_FILE) cmd = (f"tar -cf - --lzop -S -C {image_dir} {' '.join(artifact_files)} | " f"{ssh_obj.GetBaseCmd(constants.SSH_BIN)} -- " - f"tar -xf - --lzop -S -C {remote_dir}") + f"tar -xf - --lzop -S -C {remote_image_dir}") logger.debug("cmd:\n %s", cmd) ssh.ShellCmdWithRetry(cmd) -def _UploadCvdHostPackage(ssh_obj, remote_dir, cvd_host_package): +def _UploadCvdHostPackage(ssh_obj, remote_image_dir, cvd_host_package): """Upload a CVD host package to a remote host or a GCE instance. Args: ssh_obj: An Ssh object. - remote_dir: The remote base directory. + remote_image_dir: The remote base directory. cvd_host_package: The path to the CVD host package. """ if os.path.isdir(cvd_host_package): cmd = (f"tar -cf - --lzop -S -C {cvd_host_package} . | " f"{ssh_obj.GetBaseCmd(constants.SSH_BIN)} -- " - f"tar -xf - --lzop -S -C {remote_dir}") + f"tar -xf - --lzop -S -C {remote_image_dir}") logger.debug("cmd:\n %s", cmd) ssh.ShellCmdWithRetry(cmd) else: - remote_cmd = f"tar -xzf - -C {remote_dir} < {cvd_host_package}" + remote_cmd = f"tar -xzf - -C {remote_image_dir} < {cvd_host_package}" logger.debug("remote_cmd:\n %s", remote_cmd) ssh_obj.Run(remote_cmd) @utils.TimeExecute(function_description="Processing and uploading local images") -def UploadArtifacts(ssh_obj, remote_dir, image_path, cvd_host_package): +def UploadArtifacts(ssh_obj, remote_image_dir, image_path, cvd_host_package): """Upload images and a CVD host package to a remote host or a GCE instance. Args: ssh_obj: An Ssh object. - remote_dir: The remote base directory. + remote_image_dir: The remote image directory. image_path: A string, the path to the image zip built by `m dist`, the directory containing the images built by `m`, or the directory containing extracted target files. cvd_host_package: A string, the path to the CVD host package in gzip. """ if os.path.isdir(image_path): - _UploadImageDir(ssh_obj, remote_dir, FindImageDir(image_path)) + _UploadImageDir(ssh_obj, remote_image_dir, FindImageDir(image_path)) else: - _UploadImageZip(ssh_obj, remote_dir, image_path) - _UploadCvdHostPackage(ssh_obj, remote_dir, cvd_host_package) + _UploadImageZip(ssh_obj, remote_image_dir, image_path) + _UploadCvdHostPackage(ssh_obj, remote_image_dir, cvd_host_package) def FindBootImages(search_path): @@ -297,13 +304,13 @@ def FindKernelImages(search_path): @utils.TimeExecute(function_description="Uploading local kernel images.") -def _UploadKernelImages(ssh_obj, remote_dir, search_path): +def _UploadKernelImages(ssh_obj, remote_image_dir, search_path): """Find and upload kernel or boot images to a remote host or a GCE instance. Args: ssh_obj: An Ssh object. - remote_dir: The remote base directory. + remote_image_dir: The remote image directory. search_path: A path to an image file or an image directory. Returns: @@ -314,14 +321,15 @@ def _UploadKernelImages(ssh_obj, remote_dir, search_path): images. """ # Assume that the caller cleaned up the remote home directory. - ssh_obj.Run("mkdir -p " + remote_path.join(remote_dir, _REMOTE_IMAGE_DIR)) + ssh_obj.Run("mkdir -p " + + remote_path.join(remote_image_dir, _REMOTE_EXTRA_IMAGE_DIR)) kernel_image_path, initramfs_image_path = FindKernelImages(search_path) if kernel_image_path and initramfs_image_path: remote_kernel_image_path = remote_path.join( - remote_dir, _REMOTE_KERNEL_IMAGE_PATH) + remote_image_dir, _REMOTE_KERNEL_IMAGE_PATH) remote_initramfs_image_path = remote_path.join( - remote_dir, _REMOTE_INITRAMFS_IMAGE_PATH) + remote_image_dir, _REMOTE_INITRAMFS_IMAGE_PATH) ssh_obj.ScpPushFile(kernel_image_path, remote_kernel_image_path) ssh_obj.ScpPushFile(initramfs_image_path, remote_initramfs_image_path) return ["-kernel_path", remote_kernel_image_path, @@ -330,12 +338,12 @@ def _UploadKernelImages(ssh_obj, remote_dir, search_path): boot_image_path, vendor_boot_image_path = FindBootImages(search_path) if boot_image_path: remote_boot_image_path = remote_path.join( - remote_dir, _REMOTE_BOOT_IMAGE_PATH) + remote_image_dir, _REMOTE_BOOT_IMAGE_PATH) ssh_obj.ScpPushFile(boot_image_path, remote_boot_image_path) launch_cvd_args = ["-boot_image", remote_boot_image_path] if vendor_boot_image_path: remote_vendor_boot_image_path = remote_path.join( - remote_dir, _REMOTE_VENDOR_BOOT_IMAGE_PATH) + remote_image_dir, _REMOTE_VENDOR_BOOT_IMAGE_PATH) ssh_obj.ScpPushFile(vendor_boot_image_path, remote_vendor_boot_image_path) launch_cvd_args.extend(["-vendor_boot_image", @@ -425,18 +433,18 @@ def _MixSuperImage(super_image_path, avd_spec, target_files_dir, ota): @utils.TimeExecute(function_description="Uploading disabled vbmeta image.") -def _UploadVbmetaImage(ssh_obj, remote_dir, vbmeta_image_path): +def _UploadVbmetaImage(ssh_obj, remote_image_dir, vbmeta_image_path): """Upload disabled vbmeta image to a remote host or a GCE instance. Args: ssh_obj: An Ssh object. - remote_dir: The remote base directory. + remote_image_dir: The remote image directory. vbmeta_image_path: The path to the vbmeta image. Returns: A list of strings, the launch_cvd arguments including the remote paths. """ - remote_vbmeta_image_path = remote_path.join(remote_dir, + remote_vbmeta_image_path = remote_path.join(remote_image_dir, _REMOTE_VBMETA_IMAGE_PATH) ssh_obj.ScpPushFile(vbmeta_image_path, remote_vbmeta_image_path) return ["-vbmeta_image", remote_vbmeta_image_path] @@ -448,7 +456,7 @@ def AreTargetFilesRequired(avd_spec): avd_spec.local_system_dlkm_image) -def UploadExtraImages(ssh_obj, remote_dir, avd_spec, target_files_dir): +def UploadExtraImages(ssh_obj, remote_image_dir, avd_spec, target_files_dir): """Find and upload the images specified in avd_spec. This function finds the kernel, system, and vendor images specified in @@ -456,7 +464,7 @@ def UploadExtraImages(ssh_obj, remote_dir, avd_spec, target_files_dir): Args: ssh_obj: An Ssh object. - remote_dir: The remote base directory. + remote_image_dir: The remote image directory. avd_spec: An AvdSpec object containing extra image paths. target_files_dir: The path to an extracted target_files zip if the avd_spec requires building a super image. @@ -472,7 +480,7 @@ def UploadExtraImages(ssh_obj, remote_dir, avd_spec, target_files_dir): """ extra_img_args = [] if avd_spec.local_kernel_image: - extra_img_args += _UploadKernelImages(ssh_obj, remote_dir, + extra_img_args += _UploadKernelImages(ssh_obj, remote_image_dir, avd_spec.local_kernel_image) if AreTargetFilesRequired(avd_spec): @@ -484,35 +492,36 @@ def UploadExtraImages(ssh_obj, remote_dir, avd_spec, target_files_dir): avd_spec.local_tool_dirs + create_common.GetNonEmptyEnvVars( constants.ENV_ANDROID_SOONG_HOST_OUT, constants.ENV_ANDROID_HOST_OUT)) - ssh_obj.Run("mkdir -p " + - remote_path.join(remote_dir, _REMOTE_IMAGE_DIR)) + ssh_obj.Run( + "mkdir -p " + + remote_path.join(remote_image_dir, _REMOTE_EXTRA_IMAGE_DIR)) with tempfile.TemporaryDirectory() as super_image_dir: _MixSuperImage(os.path.join(super_image_dir, _SUPER_IMAGE_NAME), avd_spec, target_files_dir, ota) - extra_img_args += _UploadSuperImage(ssh_obj, remote_dir, + extra_img_args += _UploadSuperImage(ssh_obj, remote_image_dir, super_image_dir) vbmeta_image_path = os.path.join(super_image_dir, "vbmeta.img") ota.MakeDisabledVbmetaImage(vbmeta_image_path) - extra_img_args += _UploadVbmetaImage(ssh_obj, remote_dir, + extra_img_args += _UploadVbmetaImage(ssh_obj, remote_image_dir, vbmeta_image_path) return extra_img_args @utils.TimeExecute(function_description="Uploading super image.") -def _UploadSuperImage(ssh_obj, remote_dir, super_image_dir): +def _UploadSuperImage(ssh_obj, remote_image_dir, super_image_dir): """Upload a super image to a remote host or a GCE instance. Args: ssh_obj: An Ssh object. - remote_dir: The remote base directory. + remote_image_dir: The remote image directory. super_image_dir: The path to the directory containing the super image. Returns: A list of strings, the launch_cvd arguments including the remote paths. """ - remote_super_image_path = remote_path.join(remote_dir, + remote_super_image_path = remote_path.join(remote_image_dir, _REMOTE_SUPER_IMAGE_PATH) remote_super_image_dir = remote_path.dirname(remote_super_image_path) cmd = (f"tar -cf - --lzop -S -C {super_image_dir} {_SUPER_IMAGE_NAME} | " @@ -601,18 +610,19 @@ def ParseRemoteHostAddress(instance_name): return None -def GetConfigFromRemoteAndroidInfo(ssh_obj, remote_dir): +def GetConfigFromRemoteAndroidInfo(ssh_obj, remote_image_dir): """Get config from android-info.txt on a remote host or a GCE instance. Args: ssh_obj: An Ssh object. - remote_dir: The remote directory containing the images. + remote_image_dir: The remote image directory. Returns: A string, the config value. For example, "phone". """ android_info = ssh_obj.GetCmdOutput( - "cat " + remote_path.join(remote_dir, constants.ANDROID_INFO_FILE)) + "cat " + + remote_path.join(remote_image_dir, constants.ANDROID_INFO_FILE)) logger.debug("Android info: %s", android_info) config_match = _CONFIG_PATTERN.search(android_info) if config_match: @@ -774,17 +784,18 @@ def _GetRemoteRuntimeDirs(ssh_obj, remote_dir, base_instance_num, return legacy_runtime_dirs -def GetRemoteFetcherConfigJson(remote_dir): +def GetRemoteFetcherConfigJson(remote_image_dir): """Get the config created by fetch_cvd on a remote host or a GCE instance. Args: - remote_dir: The remote base directory. + remote_image_dir: The remote image directory. Returns: An object of report.LogFile. """ - return report.LogFile(remote_path.join(remote_dir, "fetcher_config.json"), - constants.LOG_TYPE_CUTTLEFISH_LOG) + return report.LogFile( + remote_path.join(remote_image_dir, "fetcher_config.json"), + constants.LOG_TYPE_CUTTLEFISH_LOG) def _GetRemoteTombstone(runtime_dir, name_suffix): diff --git a/public/actions/remote_host_cf_device_factory.py b/public/actions/remote_host_cf_device_factory.py index 82295b0a..b8a5c9d6 100644 --- a/public/actions/remote_host_cf_device_factory.py +++ b/public/actions/remote_host_cf_device_factory.py @@ -124,6 +124,11 @@ class RemoteHostDeviceFactory(base_device_factory.BaseDeviceFactory): return (remote_path.join(base_dir, relative_path) if relative_path else base_dir) + def _GetArtifactPath(self, relative_path=""): + """Append a relative path to the remote image directory.""" + # TODO(b/293966645): Append relative_path to --remote-image-dir. + return self._GetInstancePath(relative_path) + def _InitRemotehost(self): """Determine the remote host instance name and activate ssh. @@ -170,7 +175,7 @@ class RemoteHostDeviceFactory(base_device_factory.BaseDeviceFactory): A list of strings, the launch_cvd arguments. """ self._compute_client.SetStage(constants.STAGE_ARTIFACT) - self._ssh.Run(f"mkdir -p {self._GetInstancePath()}") + self._ssh.Run(f"mkdir -p {self._GetArtifactPath()}") launch_cvd_args = [] temp_dir = None @@ -191,7 +196,7 @@ class RemoteHostDeviceFactory(base_device_factory.BaseDeviceFactory): if self._avd_spec.image_source == constants.IMAGE_SRC_LOCAL: cvd_utils.UploadArtifacts( - self._ssh, self._GetInstancePath(), + self._ssh, self._GetArtifactPath(), (target_files_dir or self._local_image_artifact or self._avd_spec.local_image_dir), self._cvd_host_package_artifact) @@ -211,7 +216,7 @@ class RemoteHostDeviceFactory(base_device_factory.BaseDeviceFactory): self._UploadRemoteImageArtifacts(temp_dir) launch_cvd_args.extend( - cvd_utils.UploadExtraImages(self._ssh, self._GetInstancePath(), + cvd_utils.UploadExtraImages(self._ssh, self._GetArtifactPath(), self._avd_spec, target_files_dir)) finally: if temp_dir: @@ -248,19 +253,21 @@ class RemoteHostDeviceFactory(base_device_factory.BaseDeviceFactory): """ cfg = self._avd_spec.cfg if cfg.service_account_json_private_key_path: - return "-credential_source=" + self._GetInstancePath( + return "-credential_source=" + self._GetArtifactPath( constants.FETCH_CVD_CREDENTIAL_SOURCE) return self._build_api.GetFetchCertArg( os.path.join(_HOME_FOLDER, cfg.creds_cache_file)) @utils.TimeExecute( - function_description="Downloading artifacts on remote host by fetch cvd wrapper.") + function_description="Downloading artifacts on remote host by fetch " + "cvd wrapper.") def _DownloadArtifactsByFetchWrapper(self): - """Generate fetch_cvd args and run fetch cvd wrapper on remote host to download artifacts. + """Generate fetch_cvd args and run fetch cvd wrapper on remote host + to download artifacts. - Fetch cvd wrapper will fetch from cluster cached artifacts, and fallback to fetch_cvd if - the artifacts not exist. + Fetch cvd wrapper will fetch from cluster cached artifacts, and + fallback to fetch_cvd if the artifacts not exist. """ fetch_cvd_build_args = self._build_api.GetFetchBuildArgs( self._avd_spec.remote_image, @@ -272,9 +279,9 @@ class RemoteHostDeviceFactory(base_device_factory.BaseDeviceFactory): self._avd_spec.host_package_build_info) fetch_cvd_args = self._avd_spec.fetch_cvd_wrapper.split(',') + [ - f"-directory={self._GetInstancePath()}", - f"-fetch_cvd_path={self._GetInstancePath(constants.FETCH_CVD)}", - self._GetRemoteFetchCredentialArg()] + f"-directory={self._GetArtifactPath()}", + f"-fetch_cvd_path={self._GetArtifactPath(constants.FETCH_CVD)}", + self._GetRemoteFetchCredentialArg()] fetch_cvd_args.extend(fetch_cvd_build_args) ssh_cmd = self._ssh.GetBaseCmd(constants.SSH_BIN) @@ -282,9 +289,12 @@ class RemoteHostDeviceFactory(base_device_factory.BaseDeviceFactory): logger.debug("cmd:\n %s", cmd) ssh.ShellCmdWithRetry(cmd) - @utils.TimeExecute(function_description="Downloading artifacts on remote host") + @utils.TimeExecute( + function_description="Downloading artifacts on remote host") def _DownloadArtifactsRemotehost(self): - """Generate fetch_cvd args and run fetch_cvd on remote host to download artifacts.""" + """Generate fetch_cvd args and run fetch_cvd on remote host to + download artifacts. + """ fetch_cvd_build_args = self._build_api.GetFetchBuildArgs( self._avd_spec.remote_image, self._avd_spec.system_build_info, @@ -294,8 +304,8 @@ class RemoteHostDeviceFactory(base_device_factory.BaseDeviceFactory): self._avd_spec.ota_build_info, self._avd_spec.host_package_build_info) - fetch_cvd_args = [self._GetInstancePath(constants.FETCH_CVD), - f"-directory={self._GetInstancePath()}", + fetch_cvd_args = [self._GetArtifactPath(constants.FETCH_CVD), + f"-directory={self._GetArtifactPath()}", self._GetRemoteFetchCredentialArg()] fetch_cvd_args.extend(fetch_cvd_build_args) @@ -380,7 +390,7 @@ class RemoteHostDeviceFactory(base_device_factory.BaseDeviceFactory): cmd = (f"tar -cf - --lzop -S -C {images_dir} " f"{' '.join(artifact_files)} | " f"{ssh_cmd} -- " - f"tar -xf - --lzop -S -C {self._GetInstancePath()}") + f"tar -xf - --lzop -S -C {self._GetArtifactPath()}") logger.debug("cmd:\n %s", cmd) ssh.ShellCmdWithRetry(cmd) @@ -400,7 +410,7 @@ class RemoteHostDeviceFactory(base_device_factory.BaseDeviceFactory): """ self._compute_client.SetStage(constants.STAGE_BOOT_UP) config = cvd_utils.GetConfigFromRemoteAndroidInfo( - self._ssh, self._GetInstancePath()) + self._ssh, self._GetArtifactPath()) cmd = cvd_utils.GetRemoteLaunchCvdCmd( self._GetInstancePath(), self._avd_spec, config, image_args) boot_timeout_secs = (self._avd_spec.boot_timeout_secs or @@ -429,7 +439,7 @@ class RemoteHostDeviceFactory(base_device_factory.BaseDeviceFactory): if (self._avd_spec.image_source == constants.IMAGE_SRC_REMOTE and self._avd_spec.remote_fetch): logs.append( - cvd_utils.GetRemoteFetcherConfigJson(self._GetInstancePath())) + cvd_utils.GetRemoteFetcherConfigJson(self._GetArtifactPath())) logs.extend(cvd_utils.FindRemoteLogs( self._ssh, self._GetInstancePath(), @@ -509,7 +519,7 @@ class RemoteHostDeviceFactory(base_device_factory.BaseDeviceFactory): """ if not self._avd_spec.fetch_cvd_wrapper: return {} - path = os.path.join(self._GetInstancePath(), "fetch_cvd_wrapper_log.json") + path = os.path.join(self._GetArtifactPath(), "fetch_cvd_wrapper_log.json") ssh_cmd = self._ssh.GetBaseCmd(constants.SSH_BIN) + " cat " + path proc = subprocess.run(ssh_cmd, shell=True, capture_output=True, check=False) |