xref: /aosp_15_r20/tools/acloud/create/remote_image_local_instance.py (revision 800a58d989c669b8eb8a71d8df53b1ba3d411444)
1*800a58d9SAndroid Build Coastguard Worker#!/usr/bin/env python
2*800a58d9SAndroid Build Coastguard Worker#
3*800a58d9SAndroid Build Coastguard Worker# Copyright 2018 - The Android Open Source Project
4*800a58d9SAndroid Build Coastguard Worker#
5*800a58d9SAndroid Build Coastguard Worker# Licensed under the Apache License, Version 2.0 (the "License");
6*800a58d9SAndroid Build Coastguard Worker# you may not use this file except in compliance with the License.
7*800a58d9SAndroid Build Coastguard Worker# You may obtain a copy of the License at
8*800a58d9SAndroid Build Coastguard Worker#
9*800a58d9SAndroid Build Coastguard Worker#     http://www.apache.org/licenses/LICENSE-2.0
10*800a58d9SAndroid Build Coastguard Worker#
11*800a58d9SAndroid Build Coastguard Worker# Unless required by applicable law or agreed to in writing, software
12*800a58d9SAndroid Build Coastguard Worker# distributed under the License is distributed on an "AS IS" BASIS,
13*800a58d9SAndroid Build Coastguard Worker# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14*800a58d9SAndroid Build Coastguard Worker# See the License for the specific language governing permissions and
15*800a58d9SAndroid Build Coastguard Worker# limitations under the License.
16*800a58d9SAndroid Build Coastguard Workerr"""RemoteImageLocalInstance class.
17*800a58d9SAndroid Build Coastguard Worker
18*800a58d9SAndroid Build Coastguard WorkerCreate class that is responsible for creating a local instance AVD with a
19*800a58d9SAndroid Build Coastguard Workerremote image.
20*800a58d9SAndroid Build Coastguard Worker"""
21*800a58d9SAndroid Build Coastguard Workerimport logging
22*800a58d9SAndroid Build Coastguard Workerimport os
23*800a58d9SAndroid Build Coastguard Workerimport shutil
24*800a58d9SAndroid Build Coastguard Workerimport subprocess
25*800a58d9SAndroid Build Coastguard Workerimport sys
26*800a58d9SAndroid Build Coastguard Worker
27*800a58d9SAndroid Build Coastguard Workerfrom acloud import errors
28*800a58d9SAndroid Build Coastguard Workerfrom acloud.create import create_common
29*800a58d9SAndroid Build Coastguard Workerfrom acloud.create import local_image_local_instance
30*800a58d9SAndroid Build Coastguard Workerfrom acloud.internal import constants
31*800a58d9SAndroid Build Coastguard Workerfrom acloud.internal.lib import android_build_client
32*800a58d9SAndroid Build Coastguard Workerfrom acloud.internal.lib import auth
33*800a58d9SAndroid Build Coastguard Workerfrom acloud.internal.lib import cvd_utils
34*800a58d9SAndroid Build Coastguard Workerfrom acloud.internal.lib import ota_tools
35*800a58d9SAndroid Build Coastguard Workerfrom acloud.internal.lib import utils
36*800a58d9SAndroid Build Coastguard Workerfrom acloud.setup import setup_common
37*800a58d9SAndroid Build Coastguard Worker
38*800a58d9SAndroid Build Coastguard Worker
39*800a58d9SAndroid Build Coastguard Workerlogger = logging.getLogger(__name__)
40*800a58d9SAndroid Build Coastguard Worker
41*800a58d9SAndroid Build Coastguard Worker# Download remote image variables.
42*800a58d9SAndroid Build Coastguard Worker_CUTTLEFISH_COMMON_BIN_PATH = "/usr/lib/cuttlefish-common/bin/"
43*800a58d9SAndroid Build Coastguard Worker_CONFIRM_DOWNLOAD_DIR = ("Download dir %(download_dir)s does not have enough "
44*800a58d9SAndroid Build Coastguard Worker                         "space (available space %(available_space)sGB, "
45*800a58d9SAndroid Build Coastguard Worker                         "require %(required_space)sGB).\nPlease enter "
46*800a58d9SAndroid Build Coastguard Worker                         "alternate path or 'q' to exit: ")
47*800a58d9SAndroid Build Coastguard Worker_HOME_FOLDER = os.path.expanduser("~")
48*800a58d9SAndroid Build Coastguard Worker# The downloaded image artifacts will take up ~8G:
49*800a58d9SAndroid Build Coastguard Worker#   $du -lh --time $ANDROID_PRODUCT_OUT/aosp_cf_x86_phone-img-eng.XXX.zip
50*800a58d9SAndroid Build Coastguard Worker#   422M
51*800a58d9SAndroid Build Coastguard Worker# And decompressed becomes 7.2G (as of 11/2018).
52*800a58d9SAndroid Build Coastguard Worker# Let's add an extra buffer (~2G) to make sure user has enough disk space
53*800a58d9SAndroid Build Coastguard Worker# for the downloaded image artifacts.
54*800a58d9SAndroid Build Coastguard Worker_REQUIRED_SPACE = 10
55*800a58d9SAndroid Build Coastguard Worker
56*800a58d9SAndroid Build Coastguard Worker_SYSTEM_MIX_IMAGE_DIR = "mix_image_{build_id}"
57*800a58d9SAndroid Build Coastguard Worker
58*800a58d9SAndroid Build Coastguard Worker
59*800a58d9SAndroid Build Coastguard Workerdef _ShouldClearFetchDir(fetch_dir, avd_spec, fetch_cvd_args_str,
60*800a58d9SAndroid Build Coastguard Worker                         fetch_cvd_args_file):
61*800a58d9SAndroid Build Coastguard Worker    """Check if the previous fetch directory should be removed.
62*800a58d9SAndroid Build Coastguard Worker
63*800a58d9SAndroid Build Coastguard Worker    The fetch directory would be removed when the user explicitly sets the
64*800a58d9SAndroid Build Coastguard Worker    --force-sync flag, or when the fetch_cvd_args_str changed.
65*800a58d9SAndroid Build Coastguard Worker
66*800a58d9SAndroid Build Coastguard Worker    Args:
67*800a58d9SAndroid Build Coastguard Worker        fetch_dir: String, path to the fetch directory.
68*800a58d9SAndroid Build Coastguard Worker        avd_spec: AVDSpec object that tells us what we're going to create.
69*800a58d9SAndroid Build Coastguard Worker        fetch_cvd_args_str: String, args for current fetch_cvd command.
70*800a58d9SAndroid Build Coastguard Worker        fetch_cvd_args_file: String, path to file of previous fetch_cvd args.
71*800a58d9SAndroid Build Coastguard Worker
72*800a58d9SAndroid Build Coastguard Worker    Returns:
73*800a58d9SAndroid Build Coastguard Worker        Boolean. True if the fetch directory should be removed.
74*800a58d9SAndroid Build Coastguard Worker    """
75*800a58d9SAndroid Build Coastguard Worker    if not os.path.exists(fetch_dir):
76*800a58d9SAndroid Build Coastguard Worker        return False
77*800a58d9SAndroid Build Coastguard Worker    if avd_spec.force_sync:
78*800a58d9SAndroid Build Coastguard Worker        return True
79*800a58d9SAndroid Build Coastguard Worker
80*800a58d9SAndroid Build Coastguard Worker    if not os.path.exists(fetch_cvd_args_file):
81*800a58d9SAndroid Build Coastguard Worker        return True
82*800a58d9SAndroid Build Coastguard Worker    with open(fetch_cvd_args_file, "r") as f:
83*800a58d9SAndroid Build Coastguard Worker        return fetch_cvd_args_str != f.read()
84*800a58d9SAndroid Build Coastguard Worker
85*800a58d9SAndroid Build Coastguard Worker
86*800a58d9SAndroid Build Coastguard Worker@utils.TimeExecute(function_description="Downloading Android Build image")
87*800a58d9SAndroid Build Coastguard Workerdef DownloadAndProcessImageFiles(avd_spec):
88*800a58d9SAndroid Build Coastguard Worker    """Download the CF image artifacts and process them.
89*800a58d9SAndroid Build Coastguard Worker
90*800a58d9SAndroid Build Coastguard Worker    To download rom images, Acloud would download the tool fetch_cvd that can
91*800a58d9SAndroid Build Coastguard Worker    help process mixed build images, and store the fetch_cvd_build_args in
92*800a58d9SAndroid Build Coastguard Worker    FETCH_CVD_ARGS_FILE when the fetch command executes successfully. Next
93*800a58d9SAndroid Build Coastguard Worker    time when this function is called with the same image_download_dir, the
94*800a58d9SAndroid Build Coastguard Worker    FETCH_CVD_ARGS_FILE would be used to check whether this image_download_dir
95*800a58d9SAndroid Build Coastguard Worker    can be reused or not.
96*800a58d9SAndroid Build Coastguard Worker
97*800a58d9SAndroid Build Coastguard Worker    Args:
98*800a58d9SAndroid Build Coastguard Worker        avd_spec: AVDSpec object that tells us what we're going to create.
99*800a58d9SAndroid Build Coastguard Worker
100*800a58d9SAndroid Build Coastguard Worker    Returns:
101*800a58d9SAndroid Build Coastguard Worker        extract_path: String, path to image folder.
102*800a58d9SAndroid Build Coastguard Worker
103*800a58d9SAndroid Build Coastguard Worker    Raises:
104*800a58d9SAndroid Build Coastguard Worker        errors.GetRemoteImageError: Fails to download rom images.
105*800a58d9SAndroid Build Coastguard Worker    """
106*800a58d9SAndroid Build Coastguard Worker    cfg = avd_spec.cfg
107*800a58d9SAndroid Build Coastguard Worker    build_id = avd_spec.remote_image[constants.BUILD_ID]
108*800a58d9SAndroid Build Coastguard Worker    build_target = avd_spec.remote_image[constants.BUILD_TARGET]
109*800a58d9SAndroid Build Coastguard Worker
110*800a58d9SAndroid Build Coastguard Worker    extract_path = os.path.join(
111*800a58d9SAndroid Build Coastguard Worker        avd_spec.image_download_dir,
112*800a58d9SAndroid Build Coastguard Worker        constants.TEMP_ARTIFACTS_FOLDER,
113*800a58d9SAndroid Build Coastguard Worker        build_id + build_target)
114*800a58d9SAndroid Build Coastguard Worker
115*800a58d9SAndroid Build Coastguard Worker    logger.debug("Extract path: %s", extract_path)
116*800a58d9SAndroid Build Coastguard Worker
117*800a58d9SAndroid Build Coastguard Worker    build_api = (
118*800a58d9SAndroid Build Coastguard Worker        android_build_client.AndroidBuildClient(auth.CreateCredentials(cfg)))
119*800a58d9SAndroid Build Coastguard Worker    fetch_cvd_build_args = build_api.GetFetchBuildArgs(
120*800a58d9SAndroid Build Coastguard Worker        avd_spec.remote_image,
121*800a58d9SAndroid Build Coastguard Worker        avd_spec.system_build_info,
122*800a58d9SAndroid Build Coastguard Worker        avd_spec.kernel_build_info,
123*800a58d9SAndroid Build Coastguard Worker        avd_spec.boot_build_info,
124*800a58d9SAndroid Build Coastguard Worker        avd_spec.bootloader_build_info,
125*800a58d9SAndroid Build Coastguard Worker        avd_spec.android_efi_loader_build_info,
126*800a58d9SAndroid Build Coastguard Worker        avd_spec.ota_build_info,
127*800a58d9SAndroid Build Coastguard Worker        avd_spec.host_package_build_info)
128*800a58d9SAndroid Build Coastguard Worker
129*800a58d9SAndroid Build Coastguard Worker    fetch_cvd_args_str = " ".join(fetch_cvd_build_args)
130*800a58d9SAndroid Build Coastguard Worker    fetch_cvd_args_file = os.path.join(extract_path,
131*800a58d9SAndroid Build Coastguard Worker                                       constants.FETCH_CVD_ARGS_FILE)
132*800a58d9SAndroid Build Coastguard Worker    if _ShouldClearFetchDir(extract_path, avd_spec, fetch_cvd_args_str,
133*800a58d9SAndroid Build Coastguard Worker                            fetch_cvd_args_file):
134*800a58d9SAndroid Build Coastguard Worker        shutil.rmtree(extract_path)
135*800a58d9SAndroid Build Coastguard Worker
136*800a58d9SAndroid Build Coastguard Worker    if not os.path.exists(extract_path):
137*800a58d9SAndroid Build Coastguard Worker        os.makedirs(extract_path)
138*800a58d9SAndroid Build Coastguard Worker
139*800a58d9SAndroid Build Coastguard Worker        # Download rom images via cvd fetch
140*800a58d9SAndroid Build Coastguard Worker        fetch_cvd_args = list(constants.CMD_CVD_FETCH)
141*800a58d9SAndroid Build Coastguard Worker        creds_cache_file = os.path.join(_HOME_FOLDER, cfg.creds_cache_file)
142*800a58d9SAndroid Build Coastguard Worker        fetch_cvd_cert_arg = build_api.GetFetchCertArg(creds_cache_file)
143*800a58d9SAndroid Build Coastguard Worker        fetch_cvd_args.extend([f"-directory={extract_path}",
144*800a58d9SAndroid Build Coastguard Worker                          fetch_cvd_cert_arg])
145*800a58d9SAndroid Build Coastguard Worker        fetch_cvd_args.extend(fetch_cvd_build_args)
146*800a58d9SAndroid Build Coastguard Worker        logger.debug("Download images command: %s", fetch_cvd_args)
147*800a58d9SAndroid Build Coastguard Worker        if not setup_common.PackageInstalled(constants.CUTTLEFISH_COMMOM_PKG):
148*800a58d9SAndroid Build Coastguard Worker            raise errors.NoCuttlefishCommonInstalled(
149*800a58d9SAndroid Build Coastguard Worker                "cuttlefish-common package is required to run cvd fetch")
150*800a58d9SAndroid Build Coastguard Worker        try:
151*800a58d9SAndroid Build Coastguard Worker            subprocess.check_call(fetch_cvd_args)
152*800a58d9SAndroid Build Coastguard Worker        except subprocess.CalledProcessError as e:
153*800a58d9SAndroid Build Coastguard Worker            raise errors.GetRemoteImageError(f"Fails to download images: {e}")
154*800a58d9SAndroid Build Coastguard Worker
155*800a58d9SAndroid Build Coastguard Worker        # Save the fetch cvd build args when the fetch command succeeds
156*800a58d9SAndroid Build Coastguard Worker        with open(fetch_cvd_args_file, "w") as output:
157*800a58d9SAndroid Build Coastguard Worker            output.write(fetch_cvd_args_str)
158*800a58d9SAndroid Build Coastguard Worker
159*800a58d9SAndroid Build Coastguard Worker    return extract_path
160*800a58d9SAndroid Build Coastguard Worker
161*800a58d9SAndroid Build Coastguard Worker
162*800a58d9SAndroid Build Coastguard Workerdef ConfirmDownloadRemoteImageDir(download_dir):
163*800a58d9SAndroid Build Coastguard Worker    """Confirm download remote image directory.
164*800a58d9SAndroid Build Coastguard Worker
165*800a58d9SAndroid Build Coastguard Worker    If available space of download_dir is less than _REQUIRED_SPACE, ask
166*800a58d9SAndroid Build Coastguard Worker    the user to choose a different download dir or to exit out since acloud will
167*800a58d9SAndroid Build Coastguard Worker    fail to download the artifacts due to insufficient disk space.
168*800a58d9SAndroid Build Coastguard Worker
169*800a58d9SAndroid Build Coastguard Worker    Args:
170*800a58d9SAndroid Build Coastguard Worker        download_dir: String, a directory for download and decompress.
171*800a58d9SAndroid Build Coastguard Worker
172*800a58d9SAndroid Build Coastguard Worker    Returns:
173*800a58d9SAndroid Build Coastguard Worker        String, Specific download directory when user confirm to change.
174*800a58d9SAndroid Build Coastguard Worker    """
175*800a58d9SAndroid Build Coastguard Worker    while True:
176*800a58d9SAndroid Build Coastguard Worker        download_dir = os.path.expanduser(download_dir)
177*800a58d9SAndroid Build Coastguard Worker        if not os.path.exists(download_dir):
178*800a58d9SAndroid Build Coastguard Worker            answer = utils.InteractWithQuestion(
179*800a58d9SAndroid Build Coastguard Worker                "No such directory %s.\nEnter 'y' to create it, enter "
180*800a58d9SAndroid Build Coastguard Worker                "anything else to exit out[y/N]: " % download_dir)
181*800a58d9SAndroid Build Coastguard Worker            if answer.lower() == "y":
182*800a58d9SAndroid Build Coastguard Worker                os.makedirs(download_dir)
183*800a58d9SAndroid Build Coastguard Worker            else:
184*800a58d9SAndroid Build Coastguard Worker                sys.exit(constants.EXIT_BY_USER)
185*800a58d9SAndroid Build Coastguard Worker
186*800a58d9SAndroid Build Coastguard Worker        stat = os.statvfs(download_dir)
187*800a58d9SAndroid Build Coastguard Worker        available_space = stat.f_bavail*stat.f_bsize/(1024)**3
188*800a58d9SAndroid Build Coastguard Worker        if available_space < _REQUIRED_SPACE:
189*800a58d9SAndroid Build Coastguard Worker            download_dir = utils.InteractWithQuestion(
190*800a58d9SAndroid Build Coastguard Worker                _CONFIRM_DOWNLOAD_DIR % {"download_dir":download_dir,
191*800a58d9SAndroid Build Coastguard Worker                                         "available_space":available_space,
192*800a58d9SAndroid Build Coastguard Worker                                         "required_space":_REQUIRED_SPACE})
193*800a58d9SAndroid Build Coastguard Worker            if download_dir.lower() == "q":
194*800a58d9SAndroid Build Coastguard Worker                sys.exit(constants.EXIT_BY_USER)
195*800a58d9SAndroid Build Coastguard Worker        else:
196*800a58d9SAndroid Build Coastguard Worker            return download_dir
197*800a58d9SAndroid Build Coastguard Worker
198*800a58d9SAndroid Build Coastguard Worker
199*800a58d9SAndroid Build Coastguard Workerclass RemoteImageLocalInstance(local_image_local_instance.LocalImageLocalInstance):
200*800a58d9SAndroid Build Coastguard Worker    """Create class for a remote image local instance AVD.
201*800a58d9SAndroid Build Coastguard Worker
202*800a58d9SAndroid Build Coastguard Worker    RemoteImageLocalInstance just defines logic in downloading the remote image
203*800a58d9SAndroid Build Coastguard Worker    artifacts and leverages the existing logic to launch a local instance in
204*800a58d9SAndroid Build Coastguard Worker    LocalImageLocalInstance.
205*800a58d9SAndroid Build Coastguard Worker    """
206*800a58d9SAndroid Build Coastguard Worker
207*800a58d9SAndroid Build Coastguard Worker    # pylint: disable=too-many-locals
208*800a58d9SAndroid Build Coastguard Worker    def GetImageArtifactsPath(self, avd_spec):
209*800a58d9SAndroid Build Coastguard Worker        """Download the image artifacts and return the paths to them.
210*800a58d9SAndroid Build Coastguard Worker
211*800a58d9SAndroid Build Coastguard Worker        Args:
212*800a58d9SAndroid Build Coastguard Worker            avd_spec: AVDSpec object that tells us what we're going to create.
213*800a58d9SAndroid Build Coastguard Worker
214*800a58d9SAndroid Build Coastguard Worker        Raises:
215*800a58d9SAndroid Build Coastguard Worker            errors.NoCuttlefishCommonInstalled: cuttlefish-common doesn't install.
216*800a58d9SAndroid Build Coastguard Worker
217*800a58d9SAndroid Build Coastguard Worker        Returns:
218*800a58d9SAndroid Build Coastguard Worker            local_image_local_instance.ArtifactPaths object.
219*800a58d9SAndroid Build Coastguard Worker        """
220*800a58d9SAndroid Build Coastguard Worker        if not setup_common.PackageInstalled("cuttlefish-common"):
221*800a58d9SAndroid Build Coastguard Worker            raise errors.NoCuttlefishCommonInstalled(
222*800a58d9SAndroid Build Coastguard Worker                "Package [cuttlefish-common] is not installed!\n"
223*800a58d9SAndroid Build Coastguard Worker                "Please run 'acloud setup --host' to install.")
224*800a58d9SAndroid Build Coastguard Worker
225*800a58d9SAndroid Build Coastguard Worker        avd_spec.image_download_dir = ConfirmDownloadRemoteImageDir(
226*800a58d9SAndroid Build Coastguard Worker            avd_spec.image_download_dir)
227*800a58d9SAndroid Build Coastguard Worker
228*800a58d9SAndroid Build Coastguard Worker        image_dir = DownloadAndProcessImageFiles(avd_spec)
229*800a58d9SAndroid Build Coastguard Worker        launch_cvd_path = os.path.join(image_dir, "bin",
230*800a58d9SAndroid Build Coastguard Worker                                       constants.CMD_LAUNCH_CVD)
231*800a58d9SAndroid Build Coastguard Worker        if not os.path.exists(launch_cvd_path):
232*800a58d9SAndroid Build Coastguard Worker            raise errors.GetCvdLocalHostPackageError(
233*800a58d9SAndroid Build Coastguard Worker                "No launch_cvd found. Please check downloaded artifacts dir: %s"
234*800a58d9SAndroid Build Coastguard Worker                % image_dir)
235*800a58d9SAndroid Build Coastguard Worker
236*800a58d9SAndroid Build Coastguard Worker        mix_image_dir = None
237*800a58d9SAndroid Build Coastguard Worker        misc_info_path = None
238*800a58d9SAndroid Build Coastguard Worker        ota_tools_dir = None
239*800a58d9SAndroid Build Coastguard Worker        system_image_path = None
240*800a58d9SAndroid Build Coastguard Worker        system_ext_image_path = None
241*800a58d9SAndroid Build Coastguard Worker        product_image_path = None
242*800a58d9SAndroid Build Coastguard Worker        boot_image_path = None
243*800a58d9SAndroid Build Coastguard Worker        vendor_boot_image_path = None
244*800a58d9SAndroid Build Coastguard Worker        kernel_image_path = None
245*800a58d9SAndroid Build Coastguard Worker        initramfs_image_path = None
246*800a58d9SAndroid Build Coastguard Worker        vendor_image_path = None
247*800a58d9SAndroid Build Coastguard Worker        vendor_dlkm_image_path = None
248*800a58d9SAndroid Build Coastguard Worker        odm_image_path = None
249*800a58d9SAndroid Build Coastguard Worker        odm_dlkm_image_path = None
250*800a58d9SAndroid Build Coastguard Worker        host_bins_path = image_dir
251*800a58d9SAndroid Build Coastguard Worker        if avd_spec.local_system_image or avd_spec.local_vendor_image:
252*800a58d9SAndroid Build Coastguard Worker            build_id = avd_spec.remote_image[constants.BUILD_ID]
253*800a58d9SAndroid Build Coastguard Worker            build_target = avd_spec.remote_image[constants.BUILD_TARGET]
254*800a58d9SAndroid Build Coastguard Worker            mix_image_dir = os.path.join(
255*800a58d9SAndroid Build Coastguard Worker                image_dir, _SYSTEM_MIX_IMAGE_DIR.format(build_id=build_id))
256*800a58d9SAndroid Build Coastguard Worker            if not os.path.exists(mix_image_dir):
257*800a58d9SAndroid Build Coastguard Worker                os.makedirs(mix_image_dir)
258*800a58d9SAndroid Build Coastguard Worker                create_common.DownloadRemoteArtifact(
259*800a58d9SAndroid Build Coastguard Worker                    avd_spec.cfg, build_target, build_id,
260*800a58d9SAndroid Build Coastguard Worker                    cvd_utils.GetMixBuildTargetFilename(
261*800a58d9SAndroid Build Coastguard Worker                        build_target, build_id),
262*800a58d9SAndroid Build Coastguard Worker                    mix_image_dir, decompress=True)
263*800a58d9SAndroid Build Coastguard Worker            misc_info_path = cvd_utils.FindMiscInfo(mix_image_dir)
264*800a58d9SAndroid Build Coastguard Worker            mix_image_dir = cvd_utils.FindImageDir(mix_image_dir)
265*800a58d9SAndroid Build Coastguard Worker            tool_dirs = (avd_spec.local_tool_dirs +
266*800a58d9SAndroid Build Coastguard Worker                         create_common.GetNonEmptyEnvVars(
267*800a58d9SAndroid Build Coastguard Worker                             constants.ENV_ANDROID_SOONG_HOST_OUT,
268*800a58d9SAndroid Build Coastguard Worker                             constants.ENV_ANDROID_HOST_OUT))
269*800a58d9SAndroid Build Coastguard Worker            ota_tools_dir = os.path.abspath(
270*800a58d9SAndroid Build Coastguard Worker                ota_tools.FindOtaToolsDir(tool_dirs))
271*800a58d9SAndroid Build Coastguard Worker
272*800a58d9SAndroid Build Coastguard Worker            # When using local vendor image, use cvd in local-tool if it
273*800a58d9SAndroid Build Coastguard Worker            # exists. Fall back to downloaded tools in case it's missing
274*800a58d9SAndroid Build Coastguard Worker
275*800a58d9SAndroid Build Coastguard Worker            if avd_spec.local_vendor_image and avd_spec.local_tool_dirs:
276*800a58d9SAndroid Build Coastguard Worker                try:
277*800a58d9SAndroid Build Coastguard Worker                    host_bins_path = self._FindCvdHostBinaries(tool_dirs)
278*800a58d9SAndroid Build Coastguard Worker                except errors.GetCvdLocalHostPackageError:
279*800a58d9SAndroid Build Coastguard Worker                    logger.debug("fall back to downloaded cvd host binaries")
280*800a58d9SAndroid Build Coastguard Worker
281*800a58d9SAndroid Build Coastguard Worker        if avd_spec.local_system_image:
282*800a58d9SAndroid Build Coastguard Worker            (
283*800a58d9SAndroid Build Coastguard Worker                system_image_path,
284*800a58d9SAndroid Build Coastguard Worker                system_ext_image_path,
285*800a58d9SAndroid Build Coastguard Worker                product_image_path,
286*800a58d9SAndroid Build Coastguard Worker            ) = create_common.FindSystemImages(avd_spec.local_system_image)
287*800a58d9SAndroid Build Coastguard Worker
288*800a58d9SAndroid Build Coastguard Worker        if avd_spec.local_kernel_image:
289*800a58d9SAndroid Build Coastguard Worker            (
290*800a58d9SAndroid Build Coastguard Worker                boot_image_path,
291*800a58d9SAndroid Build Coastguard Worker                vendor_boot_image_path,
292*800a58d9SAndroid Build Coastguard Worker                kernel_image_path,
293*800a58d9SAndroid Build Coastguard Worker                initramfs_image_path,
294*800a58d9SAndroid Build Coastguard Worker            ) = self.FindBootOrKernelImages(
295*800a58d9SAndroid Build Coastguard Worker                os.path.abspath(avd_spec.local_kernel_image))
296*800a58d9SAndroid Build Coastguard Worker
297*800a58d9SAndroid Build Coastguard Worker        if avd_spec.local_vendor_boot_image:
298*800a58d9SAndroid Build Coastguard Worker            vendor_boot_image_path = create_common.FindVendorBootImage(
299*800a58d9SAndroid Build Coastguard Worker                avd_spec.local_vendor_boot_image)
300*800a58d9SAndroid Build Coastguard Worker
301*800a58d9SAndroid Build Coastguard Worker        if avd_spec.local_vendor_image:
302*800a58d9SAndroid Build Coastguard Worker            vendor_image_paths = cvd_utils.FindVendorImages(
303*800a58d9SAndroid Build Coastguard Worker                avd_spec.local_vendor_image)
304*800a58d9SAndroid Build Coastguard Worker            vendor_image_path = vendor_image_paths.vendor
305*800a58d9SAndroid Build Coastguard Worker            vendor_dlkm_image_path = vendor_image_paths.vendor_dlkm
306*800a58d9SAndroid Build Coastguard Worker            odm_image_path = vendor_image_paths.odm
307*800a58d9SAndroid Build Coastguard Worker            odm_dlkm_image_path = vendor_image_paths.odm_dlkm
308*800a58d9SAndroid Build Coastguard Worker
309*800a58d9SAndroid Build Coastguard Worker        return local_image_local_instance.ArtifactPaths(
310*800a58d9SAndroid Build Coastguard Worker            image_dir=mix_image_dir or image_dir,
311*800a58d9SAndroid Build Coastguard Worker            host_bins=host_bins_path,
312*800a58d9SAndroid Build Coastguard Worker            host_artifacts=image_dir,
313*800a58d9SAndroid Build Coastguard Worker            misc_info=misc_info_path,
314*800a58d9SAndroid Build Coastguard Worker            ota_tools_dir=ota_tools_dir,
315*800a58d9SAndroid Build Coastguard Worker            system_image=system_image_path,
316*800a58d9SAndroid Build Coastguard Worker            system_ext_image=system_ext_image_path,
317*800a58d9SAndroid Build Coastguard Worker            product_image=product_image_path,
318*800a58d9SAndroid Build Coastguard Worker            vendor_image=vendor_image_path,
319*800a58d9SAndroid Build Coastguard Worker            vendor_dlkm_image=vendor_dlkm_image_path,
320*800a58d9SAndroid Build Coastguard Worker            odm_image=odm_image_path,
321*800a58d9SAndroid Build Coastguard Worker            odm_dlkm_image=odm_dlkm_image_path,
322*800a58d9SAndroid Build Coastguard Worker            boot_image=boot_image_path,
323*800a58d9SAndroid Build Coastguard Worker            vendor_boot_image=vendor_boot_image_path,
324*800a58d9SAndroid Build Coastguard Worker            kernel_image=kernel_image_path,
325*800a58d9SAndroid Build Coastguard Worker            initramfs_image=initramfs_image_path)
326