# Copyright 2019 The ChromiumOS Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""Artifacts service.

This service houses the high level business logic for all created artifacts.
"""

import collections
import glob
import logging
import os
import shutil
from typing import Dict, List, Optional, TYPE_CHECKING

from chromite.lib import autotest_util
from chromite.lib import constants
from chromite.lib import cros_build_lib
from chromite.lib import osutils
from chromite.lib import parallel
from chromite.lib import portage_util
from chromite.lib.paygen import paygen_payload_lib
from chromite.lib.paygen import paygen_provision_payload
from chromite.lib.paygen import paygen_stateful_payload_lib


if TYPE_CHECKING:
    from chromite.lib import build_target_lib
    from chromite.lib import chroot_lib
    from chromite.lib import sysroot_lib

# Archive type constants.
ARCHIVE_CONTROL_FILES = "control"
ARCHIVE_PACKAGES = "packages"
ARCHIVE_SERVER_PACKAGES = "server_packages"
ARCHIVE_TEST_SUITES = "test_suites"

CPE_WARNINGS_FILE_TEMPLATE = "cpe-warnings-chromeos-%s.txt"
CPE_RESULT_FILE_TEMPLATE = "cpe-chromeos-%s.txt"

# The individual image archives for ArchiveImages.
IMAGE_TARS = {
    constants.BASE_IMAGE_BIN: constants.BASE_IMAGE_TAR,
    constants.TEST_IMAGE_BIN: constants.TEST_IMAGE_TAR,
    constants.RECOVERY_IMAGE_BIN: constants.RECOVERY_IMAGE_TAR,
    constants.TEST_GUEST_VM_DIR: constants.TEST_GUEST_VM_TAR,
    constants.BASE_GUEST_VM_DIR: constants.BASE_GUEST_VM_TAR,
    constants.KERNEL_IMAGE_BIN: constants.KERNEL_IMAGE_TAR,
    constants.FLEXOR_KERNEL_IMAGE_TAR: constants.FLEXOR_KERNEL_IMAGE_TAR,
}

# Additional files under sysroot that will be archived with individual image.
IMAGE_ADDITIONAL_SYSROOT_FILES = {
    constants.KERNEL_IMAGE_BIN: [
        "usr/lib/debug/boot/%s" % constants.KERNEL_SYMBOL_NAME
    ],
}

TAST_BUNDLE_NAME = "tast_bundles.tar.bz2"
TAST_INTEL_BUNDLE_NAME = "tast_intel_bundles.tar.bz2"
TAST_COMPRESSOR = cros_build_lib.CompressionType.BZIP2

CpeResult = collections.namedtuple("CpeResult", ["report", "warnings"])


class Error(Exception):
    """Base module error."""


class ArchiveBaseDirNotFound(Error):
    """Raised when the archive base directory does not exist.

    This error most likely indicates the board was not built.
    """


class CrosGenerateSysrootError(Error):
    """Error when running CrosGenerateSysroot."""


class NoFilesError(Error):
    """When there are no files to archive."""


def BuildFirmwareArchive(
    chroot: "chroot_lib.Chroot",
    sysroot: "sysroot_lib.Sysroot",
    output_directory: str,
) -> Optional[str]:
    """Build firmware_from_source.tar.bz2 in sysroot's firmware directory.

    Args:
        chroot: The chroot to be used.
        sysroot: The sysroot whose artifacts are being archived.
        output_directory: The path were the completed archives should be put.

    Returns:
        The archive file path if created, None otherwise.
    """
    firmware_root = chroot.full_path(sysroot.JoinPath("firmware"))
    if not os.path.exists(firmware_root):
        return None

    # Private fingerprint libraries should not be uploaded.
    private_fingerprint_dirs = glob.glob(
        os.path.join(firmware_root, "**/ec-private/fingerprint"), recursive=True
    )

    source_list = []
    for directory, _, filenames in os.walk(firmware_root):
        if any(directory.startswith(e) for e in private_fingerprint_dirs):
            continue
        for filename in filenames:
            source_list.append(
                os.path.relpath(
                    os.path.join(directory, filename), firmware_root
                )
            )

    if not source_list:
        return None

    archive_file = os.path.join(
        output_directory, constants.FIRMWARE_ARCHIVE_NAME
    )
    cros_build_lib.CreateTarball(
        archive_file,
        firmware_root,
        compression=cros_build_lib.CompressionType.BZIP2,
        chroot=chroot.path,
        inputs=source_list,
    )

    return archive_file


def BundleFpmcuUnittests(
    chroot: "chroot_lib.Chroot",
    sysroot: "sysroot_lib.Sysroot",
    output_directory: "str",
) -> Optional[str]:
    """Create artifact tarball for fingerprint MCU on-device unittests.

    Args:
        chroot: The chroot containing the sysroot.
        sysroot: The sysroot whose artifacts are being archived.
        output_directory: The path were the completed archives should be put.

    Returns:
        The archive file path if created, None otherwise.
    """
    fpmcu_unittests_root = chroot.full_path(
        sysroot.JoinPath(
            "firmware",
            "chromeos-fpmcu-unittests",
        )
    )
    files = [
        os.path.relpath(f, fpmcu_unittests_root)
        for f in glob.iglob(os.path.join(fpmcu_unittests_root, "*"))
    ]
    if not files:
        return None

    archive_file = os.path.join(
        output_directory, constants.FPMCU_UNITTESTS_ARCHIVE_NAME
    )
    cros_build_lib.CreateTarball(
        archive_file,
        fpmcu_unittests_root,
        compression=cros_build_lib.CompressionType.BZIP2,
        chroot=chroot.path,
        inputs=files,
    )

    return archive_file


def BundleAutotestFiles(
    chroot: "chroot_lib.Chroot",
    sysroot: "sysroot_lib.Sysroot",
    output_directory: str,
) -> Dict[str, str]:
    """Create the Autotest Hardware Test archives.

    Args:
        chroot: The chroot containing the sysroot.
        sysroot: The sysroot whose artifacts are being archived.
        output_directory: The path were the completed archives should be put.

    Returns:
        The paths of the files created in |output_directory| by their type.
    """
    assert sysroot.Exists(chroot=chroot)
    assert output_directory

    logging.debug(
        "Inside artifacts_service BundleAutotestFiles (%s %s %s)",
        chroot.path,
        sysroot.path,
        output_directory,
    )
    # archive_basedir is the base directory where the archive commands are run.
    # We want the folder containing the board's autotest folder.
    archive_basedir = chroot.full_path(
        sysroot.path, constants.AUTOTEST_BUILD_PATH
    )
    archive_basedir = os.path.dirname(archive_basedir)

    if not os.path.exists(archive_basedir):
        return {}

    builder = autotest_util.AutotestTarballBuilder(
        archive_basedir, output_directory, chroot, sysroot
    )
    results = {
        ARCHIVE_CONTROL_FILES: builder.BuildAutotestControlFilesTarball(),
        ARCHIVE_PACKAGES: builder.BuildAutotestPackagesTarball(),
        ARCHIVE_SERVER_PACKAGES: builder.BuildAutotestServerPackageTarball(),
        ARCHIVE_TEST_SUITES: builder.BuildAutotestTestSuitesTarball(),
    }

    # Strip the list down to just the successfully created archives.
    return {k: v for k, v in results.items() if v}


def BundleEBuildLogsTarball(
    chroot: "chroot_lib.Chroot",
    sysroot: "sysroot_lib.Sysroot",
    archive_dir: str,
) -> Optional[str]:
    """Builds a tarball containing ebuild logs.

    Args:
        chroot: The chroot to be used.
        sysroot: Sysroot whose images are being fetched.
        archive_dir: The directory to drop the tarball in.

    Returns:
        The file name of the output tarball, None if no package found.
    """
    tarball_paths = []
    logs_path = chroot.full_path(sysroot.path, "tmp/portage")

    if not os.path.isdir(logs_path):
        return None

    if not os.path.exists(os.path.join(logs_path, "logs")):
        return None

    tarball_paths.append("logs")
    tarball_output = os.path.join(archive_dir, "ebuild_logs.tar.xz")
    try:
        cros_build_lib.CreateTarball(
            tarball_output,
            cwd=logs_path,
            chroot=chroot.path,
            inputs=tarball_paths,
        )
    except cros_build_lib.TarballError:
        logging.warning(
            "Unable to create logs tarball; ignoring until "
            "https://crbug.com/999933 is sorted out."
        )
        return None
    return os.path.basename(tarball_output)


def BundleChromeOSConfig(
    chroot: "chroot_lib.Chroot",
    sysroot: "sysroot_lib.Sysroot",
    archive_dir: str,
) -> Optional[str]:
    """Outputs the ChromeOS Config payload.

    Args:
        chroot: The chroot to be used.
        sysroot: Sysroot whose config is being fetched.
        archive_dir: The directory to drop the config in.

    Returns:
        The file name of the output config, None if no config found.
    """
    config_path = chroot.full_path(
        sysroot.path, "usr/share/chromeos-config/yaml/config.yaml"
    )

    if not os.path.exists(config_path):
        return None

    config_output = os.path.join(archive_dir, "config.yaml")
    shutil.copy(config_path, config_output)
    return os.path.basename(config_output)


def BundleSimpleChromeArtifacts(
    chroot: "chroot_lib.Chroot",
    sysroot: "sysroot_lib.Sysroot",
    build_target: "build_target_lib.BuildTarget",
    output_dir: str,
) -> List[str]:
    """Gather all of the simple chrome artifacts.

    Args:
        chroot: The chroot to be used.
        sysroot: The sysroot.
        build_target: The sysroot's build target.
        output_dir: Where all result files should be stored.
    """
    files = []
    files.extend(CreateChromeRoot(chroot, build_target, output_dir))
    files.append(ArchiveChromeEbuildEnv(sysroot, output_dir))

    return files


def BundleVmFiles(
    chroot: "chroot_lib.Chroot", test_results_dir: str, output_dir: str
) -> List[str]:
    """Gather all of the VM files.

    Args:
        chroot: The chroot to be used.
        test_results_dir: Test directory relative to chroot.
        output_dir: Where all result files should be stored.
    """
    image_dir = chroot.full_path(test_results_dir)
    archives = ArchiveFilesFromImageDir(image_dir, output_dir)
    return archives


# TODO(mmortensen): Refactor ArchiveFilesFromImageDir to be part of a library
# module. I tried moving it to lib/vm.py but this causes a circular dependency.
def ArchiveFilesFromImageDir(images_dir: str, archive_path: str) -> List[str]:
    """Archives the files into tarballs if they match a prefix from prefix_list.

    Create and return a list of tarballs from the images_dir of files that match
    VM disk and memory prefixes.

    Args:
        images_dir: The directory containing the images to archive.
        archive_path: The directory where the archives should be created.

    Returns:
        The paths to the tarballs.
    """
    images = []

    tar_files = []
    for image_path in images:
        image_rel_path = os.path.relpath(image_path, images_dir)
        image_parent_dir = os.path.dirname(image_path)
        image_file = os.path.basename(image_path)
        tarball_path = os.path.join(
            archive_path, "%s.tar" % image_rel_path.replace("/", "_")
        )
        # Note that tar will chdir to |image_parent_dir|, so that |image_file|
        # is at the top-level of the tar file.
        cros_build_lib.CreateTarball(
            tarball_path,
            image_parent_dir,
            compression=cros_build_lib.CompressionType.BZIP2,
            inputs=[image_file],
        )
        tar_files.append(tarball_path)

    return tar_files


def ArchiveChromeEbuildEnv(
    sysroot: "sysroot_lib.Sysroot", output_dir: str
) -> str:
    """Generate Chrome ebuild environment.

    Args:
        sysroot: The sysroot where the original environment archive can be
            found.
        output_dir: Where the result should be stored.

    Returns:
        The path to the archive.

    Raises:
        NoFilesException: When the package cannot be found.
    """
    pkg_dir = os.path.join(sysroot.path, portage_util.VDB_PATH)
    files = glob.glob(os.path.join(pkg_dir, constants.CHROME_CP) + "-*")
    if not files:
        raise NoFilesError("Failed to find package %s" % constants.CHROME_CP)

    if len(files) > 1:
        logging.warning(
            "Expected one package for %s, found %d",
            constants.CHROME_CP,
            len(files),
        )

    chrome_dir = sorted(files)[-1]
    env_bzip = os.path.join(chrome_dir, "environment.bz2")
    result_path = os.path.join(output_dir, constants.CHROME_ENV_TAR)
    with osutils.TempDir() as tempdir:
        # Convert from bzip2 to tar format.
        bzip2 = cros_build_lib.FindCompressor(
            cros_build_lib.CompressionType.BZIP2
        )
        tempdir_tar_path = os.path.join(tempdir, constants.CHROME_ENV_FILE)
        cros_build_lib.run(
            [bzip2, "-d", env_bzip, "-c"], stdout=tempdir_tar_path
        )

        cros_build_lib.CreateTarball(result_path, tempdir)

    return result_path


def ArchiveImages(
    chroot: "chroot_lib.Chroot",
    sysroot: "sysroot_lib.Sysroot",
    image_dir: str,
    output_dir: str,
) -> List[str]:
    """Create a .tar.xz archive for each image that has been created.

    This copies already compressed images to output_dir.

    Args:
        chroot: The chroot containing the sysroot.
        sysroot: The sysroot whose artifacts are being archived.
        image_dir: The directory where the images are located.
        output_dir: The location where the archives should be created.

    Returns:
        The list of created file names.
    """
    files = os.listdir(image_dir)

    archives = []
    # Filter down to the ones that exist first.
    images = {img: tar for img, tar in IMAGE_TARS.items() if img in files}
    for img, tar in images.items():
        tarball_path = os.path.join(output_dir, tar)
        content = [img]
        extra_args = []
        if img in IMAGE_ADDITIONAL_SYSROOT_FILES:
            additional_files = {
                full_path
                for f in IMAGE_ADDITIONAL_SYSROOT_FILES[img]
                if os.path.isfile(
                    full_path := chroot.full_path(sysroot.path, f)
                )
            }
            content.extend(additional_files)
            # Remove path folders created for additional files
            extra_args.append("--transform=s#.*/##")

        if img == constants.FLEXOR_KERNEL_IMAGE_TAR:
            # Flexor is already compressed, so copy it.
            image_path = os.path.join(image_dir, img)
            shutil.copy(image_path, tarball_path)
        else:
            # Otherwise create a tarball.
            cros_build_lib.CreateTarball(
                tarball_path,
                image_dir,
                inputs=content,
                print_cmd=False,
                extra_args=extra_args,
            )
        archives.append(tar)

    return archives


def BundleImageZip(output_dir: str, image_dir: str) -> str:
    """Bundle image.zip.

    Args:
        output_dir: The location outside the chroot where the files should be
            stored.
        image_dir: The directory containing the image.
    """

    filename = "image.zip"
    zipfile = os.path.join(output_dir, filename)
    cros_build_lib.run(
        ["7za", "a", "-tzip", "-mm=Deflate", "-mx=1", "-mmt=on", zipfile, "."],
        cwd=image_dir,
        capture_output=True,
    )
    return filename


def CreateChromeRoot(
    chroot: "chroot_lib.Chroot",
    build_target: "build_target_lib.BuildTarget",
    output_dir: str,
) -> List[str]:
    """Create the chrome sysroot.

    Args:
        chroot: The chroot in which the sysroot should be built.
        build_target: The build target.
        output_dir: The location outside the chroot where the files should be
            stored.

    Returns:
        The list of created files.

    Raises:
        CrosGenerateSysrootError: When cros_generate_sysroot does not complete
            successfully.
    """
    extra_env = {"USE": "chrome_internal"}
    with chroot.tempdir() as tempdir:
        in_chroot_path = chroot.chroot_path(tempdir)
        cmd = [
            "cros_generate_sysroot",
            "--out-dir",
            in_chroot_path,
            "--board",
            build_target.name,
            "--deps-only",
            "--package",
            constants.CHROME_CP,
        ]

        try:
            chroot.run(
                cmd,
                extra_env=extra_env,
            )
        except cros_build_lib.RunCommandError as e:
            raise CrosGenerateSysrootError(
                "Error encountered when running cros_generate_sysroot: %s" % e,
                e,
            )

        files = []
        for path in osutils.DirectoryIterator(tempdir):
            if os.path.isfile(path):
                rel_path = os.path.relpath(path, tempdir)
                files.append(os.path.join(output_dir, rel_path))
        osutils.CopyDirContents(tempdir, output_dir, allow_nonempty=True)

        return files


def BundleTestUpdatePayloads(
    chroot: "chroot_lib.Chroot", image_path: str, output_dir: str
) -> List[str]:
    """Generate the test update payloads.

    Args:
        chroot: Chroot we're operating with.
        image_path: The full path to an image file.
        output_dir: The path where the payloads should be generated.

    Returns:
        The list of generated payloads.
    """
    payloads = GenerateTestPayloads(
        chroot,
        image_path,
        output_dir,
        full=True,
        stateful=True,
        delta=True,
        dlc=True,
    )
    payloads.extend(
        paygen_provision_payload.GenerateProvisionPayloads(
            image_path, output_dir
        )
    )

    return payloads


def ExtendBinPaths(cros_payload_path: str) -> List[str]:
    """Return an array with corresponding .json and .log for a .bin."""
    return [
        cros_payload_path,
        cros_payload_path + ".json",
        cros_payload_path + ".log",
    ]


def GenerateTestPayloads(
    chroot: "chroot_lib.Chroot",
    target_image_path: str,
    archive_dir: str,
    full: bool = False,
    delta: bool = False,
    stateful: bool = False,
    dlc: bool = False,
) -> List[str]:
    """Generates the payloads for hw testing.

    Args:
        chroot: The chroot to be used.
        target_image_path: The path to the image to generate payloads to.
        archive_dir: Where to store payloads we generated.
        full: Generate full payloads.
        delta: Generate delta payloads.
        stateful: Generate stateful payload.
        dlc: Generate sample-dlc payload if available.

    Returns:
        The list of artifacts that were generated.
    """
    real_target = os.path.realpath(target_image_path)
    # The path to the target should look something like this:
    # .../link/R37-5952.0.2014_06_12_2302-a1/chromiumos_test_image.bin
    board, os_version = real_target.split("/")[-3:-1]
    cros_prefix = "chromeos"
    minios_prefix = "minios"
    suffix = "dev.bin"

    # DLC constants.
    dlc_prefix = "dlc"
    dlc_id = "sample-dlc"
    dlc_package = "package"
    sample_dlc_image = os.path.join(
        os.path.dirname(target_image_path),
        dlc_prefix,
        dlc_id,
        dlc_package,
        "dlc.img",
    )

    def _do_full():
        # Names for full payloads look something like this:
        # chromeos_R37-5952.0.2014_06_12_2302-a1_link_full_dev.bin
        cros_name = "_".join([cros_prefix, os_version, board, "full", suffix])
        cros_payload_path = os.path.join(archive_dir, cros_name)
        result_paths = paygen_payload_lib.GenerateUpdatePayload(
            chroot, target_image_path, cros_payload_path
        )
        if not result_paths:
            logging.info("CrOS full payload generation skipped.")
        return sum((ExtendBinPaths(path) for path in result_paths), [])

    def _do_full_minios():
        # Names for full payloads look something like this:
        # minios_R37-5952.0.2014_06_12_2302-a1_link_full_dev.bin
        minios_name = "_".join(
            [minios_prefix, os_version, board, "full", suffix]
        )
        minios_payload_path = os.path.join(archive_dir, minios_name)
        result_paths = paygen_payload_lib.GenerateUpdatePayload(
            chroot, target_image_path, minios_payload_path, minios=True
        )
        if not result_paths:
            logging.info("MiniOS full payload generation skipped.")
        return sum((ExtendBinPaths(path) for path in result_paths), [])

    def _do_delta():
        # Names for delta payloads look something like this:
        # chromeos_R37-5952.0.2014_06_12_2302-a1_R37-
        # 5952.0.2014_06_12_2302-a1_link_delta_dev.bin
        cros_name = "_".join(
            [cros_prefix, os_version, os_version, board, "delta", suffix]
        )
        cros_payload_path = os.path.join(archive_dir, cros_name)
        result_paths = paygen_payload_lib.GenerateUpdatePayload(
            chroot,
            target_image_path,
            cros_payload_path,
            src_image=target_image_path,
        )
        if not result_paths:
            logging.info("CrOS delta payload generation skipped.")
        return sum((ExtendBinPaths(path) for path in result_paths), [])

    def _do_delta_minios():
        # Names for delta payloads look something like this:
        # minios_R37-5952.0.2014_06_12_2302-a1_R37-
        # 5952.0.2014_06_12_2302-a1_link_delta_dev.bin
        minios_name = "_".join(
            [minios_prefix, os_version, os_version, board, "delta", suffix]
        )
        minios_payload_path = os.path.join(archive_dir, minios_name)
        result_paths = paygen_payload_lib.GenerateUpdatePayload(
            chroot,
            target_image_path,
            minios_payload_path,
            src_image=target_image_path,
            minios=True,
        )
        if not result_paths:
            logging.info("MiniOS delta payload generation skipped.")
        return sum((ExtendBinPaths(path) for path in result_paths), [])

    def _do_full_dlc():
        # pylint: disable=line-too-long
        # Names for full sample-dlc payloads look something like this:
        # dlc_sample-dlc_package_R37-5952.0.2014_06_12_2302-a1_link_full_dev.bin
        # pylint: enable=line-too-long
        name = "_".join(
            [
                dlc_prefix,
                dlc_id,
                dlc_package,
                os_version,
                board,
                "full",
                suffix,
            ]
        )
        payload_path = os.path.join(archive_dir, name)
        result_paths = paygen_payload_lib.GenerateUpdatePayload(
            chroot, sample_dlc_image, payload_path
        )
        if not result_paths:
            logging.info("DLC (%s) full payload generation skipped.", dlc_id)
        return sum((ExtendBinPaths(path) for path in result_paths), [])

    def _do_delta_dlc():
        # Names for delta payloads look something like this:
        # dlc_sample-dlc_package_R37-5952.0.2014_06_12_2302-a1_R37-
        # 5952.0.2014_06_12_2302-a1_link_delta_dev.bin
        name = "_".join(
            [
                dlc_prefix,
                dlc_id,
                dlc_package,
                os_version,
                os_version,
                board,
                "delta",
                suffix,
            ]
        )
        payload_path = os.path.join(archive_dir, name)
        result_paths = paygen_payload_lib.GenerateUpdatePayload(
            chroot, sample_dlc_image, payload_path, src_image=sample_dlc_image
        )
        if not result_paths:
            logging.info("DLC (%s) delta payload generation skipped.", dlc_id)
        return sum((ExtendBinPaths(path) for path in result_paths), [])

    def _do_stateful():
        return [
            paygen_stateful_payload_lib.GenerateStatefulPayload(
                target_image_path, archive_dir
            ),
            paygen_stateful_payload_lib.GenerateZstdStatefulPayload(
                target_image_path, archive_dir
            ),
        ]

    steps = []
    if full:
        steps.append(_do_full)
        steps.append(_do_full_minios)
    if delta:
        steps.append(_do_delta)
        steps.append(_do_delta_minios)
    if dlc and "dlc" in portage_util.GetBoardUseFlags(board):
        if full:
            steps.append(_do_full_dlc)
        if delta:
            steps.append(_do_delta_dlc)
    if stateful:
        steps.append(_do_stateful)

    # In theory we should do them all in parallel, this resulted in runtimes
    # around 7 minutes on builders. We have space constraints and this is
    # taking up 80ish GB at peak while running fully parallel. Until we can
    # land some mitigation, reduce the parallelism at the expense of runtime.
    # BUG=b:273941464.
    gen_files = parallel.RunParallelSteps(
        steps, return_values=True, max_parallel=2
    )
    return [i for sl in gen_files for i in sl]


def BundleTastFiles(
    chroot: "chroot_lib.Chroot", sysroot: "sysroot_lib.Sysroot", output_dir: str
) -> Optional[str]:
    """Tar up the Tast private test bundles.

    Args:
        chroot: Chroot containing the sysroot.
        sysroot: Sysroot whose files are being archived.
        output_dir: Location for storing the result tarball.

    Returns:
        Path of the generated tarball, or None if there is no private test
            bundles.
    """
    cwd = chroot.full_path(sysroot.JoinPath("build"))

    dirs = []
    srcs = [
        "libexec/tast/bundles/local/crosint",
        "share/tast/metadata/local/crosint.pb",
        "share/tast/data/go.chromium.org/tast-tests-private",
    ]
    for d in srcs:
        if os.path.exists(os.path.join(cwd, d)):
            dirs.append(d)
    if not dirs:
        return None

    tarball = os.path.join(output_dir, TAST_BUNDLE_NAME)
    cros_build_lib.CreateTarball(
        tarball,
        cwd,
        compression=TAST_COMPRESSOR,
        chroot=chroot.path,
        inputs=dirs,
    )

    return tarball


def BundleTastIntelFiles(
    chroot: "chroot_lib.Chroot", sysroot: "sysroot_lib.Sysroot", output_dir: str
) -> Optional[str]:
    """Tar up the Tast Intel private test bundles.

    Args:
        chroot: Chroot containing the sysroot.
        sysroot: Sysroot whose files are being archived.
        output_dir: Location for storing the result tarball.

    Returns:
        Path of the generated tarball, or None if there is no private test
            bundles.
    """
    cwd = chroot.full_path(sysroot.JoinPath("build"))

    dirs = []
    srcs = [
        "libexec/tast/bundles/local/crosint_intel",
        "share/tast/metadata/local/crosint_intel.pb",
        "share/tast/data/go.chromium.org/partner-intel-private/",
    ]
    for d in srcs:
        if os.path.exists(os.path.join(cwd, d)):
            dirs.append(d)
    if not dirs:
        return None

    tarball = os.path.join(output_dir, TAST_INTEL_BUNDLE_NAME)
    cros_build_lib.CreateTarball(
        tarball,
        cwd,
        compression=TAST_COMPRESSOR,
        chroot=chroot.path,
        inputs=dirs,
    )

    return tarball


def BundleGceTarball(output_dir: str, image_dir: str) -> str:
    """Bundle the test image into a tarball suitable for importing into GCE.

    Args:
        output_dir: The location outside the chroot where the files should be
            stored.
        image_dir: The directory containing the image.

    Returns:
        Path to the generated tarball.
    """
    test_image = os.path.join(image_dir, constants.TEST_IMAGE_BIN)
    tarball = os.path.join(output_dir, constants.TEST_IMAGE_GCE_TAR)

    with osutils.TempDir() as tempdir:
        disk_raw = os.path.join(tempdir, "disk.raw")
        osutils.SafeSymlink(test_image, disk_raw)
        cros_build_lib.CreateTarball(
            tarball,
            tempdir,
            compression=cros_build_lib.CompressionType.GZIP,
            inputs=("disk.raw",),
            extra_args=["--dereference", "--format=oldgnu"],
        )

    return tarball
