blob: fa2646e72615006576e2335541812cc15e6e63b2 [file] [log] [blame] [edit]
# 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.
"""Android operations."""
import logging
import os
from typing import TYPE_CHECKING
from chromite.api import faux
from chromite.api import validate
from chromite.api.controller import controller_util
from chromite.api.gen.chromite.api import android_pb2
from chromite.lib import constants
from chromite.lib import osutils
from chromite.lib.parser import package_info
from chromite.service import android
from chromite.service import packages
if TYPE_CHECKING:
from chromite.api import api_config
ANDROIDPIN_MASK_PATH = os.path.join(
constants.SOURCE_ROOT,
constants.CHROMIUMOS_OVERLAY_DIR,
"profiles",
"default",
"linux",
"package.mask",
"androidpin",
)
def _GetLatestBuildResponse(_request, response, _config) -> None:
"""Fake GetLatestBuild response."""
response.android_version = "7123456"
@faux.success(_GetLatestBuildResponse)
@faux.empty_error
@validate.require("android_package")
@validate.validation_complete
def GetLatestBuild(request, response, _config) -> None:
build_id, _ = android.GetLatestBuild(
request.android_package,
build_branch=request.android_build_branch,
)
response.android_version = build_id
def _MarkStableResponse(_request, response, _config) -> None:
"""Add fake status to a successful response."""
response.android_atom.category = "category"
response.android_atom.package_name = "android-package-name"
response.android_atom.version = "1.2"
response.status = android_pb2.MARK_STABLE_STATUS_SUCCESS
@faux.success(_MarkStableResponse)
@faux.empty_error
@validate.require("package_name")
@validate.validation_complete
def MarkStable(
request: android_pb2.MarkStableRequest,
response: android_pb2.MarkStableResponse,
_config: "api_config.ApiConfig",
) -> None:
"""Uprev Android, if able.
Uprev Android, verify that the newly uprevved package can be emerged, and
return the new package info.
See AndroidService documentation in api/proto/android.proto.
Args:
request: The input proto.
response: The output proto.
_config: The call config.
"""
chroot = controller_util.ParseChroot(request.chroot)
build_targets = controller_util.ParseBuildTargets(request.build_targets)
package_name = request.package_name
android_build_branch = request.android_build_branch
android_version = request.android_version
skip_commit = request.skip_commit
ignore_data_collector_artifacts = request.ignore_data_collector_artifacts
# Assume success.
response.status = android_pb2.MARK_STABLE_STATUS_SUCCESS
# TODO(crbug/904939): This should move to service/android.py and the port
# should be finished.
android_atom_to_build = None
try:
result = packages.uprev_android(
android_package=package_name,
chroot=chroot,
build_targets=build_targets,
android_build_branch=android_build_branch,
android_version=android_version,
skip_commit=skip_commit,
ignore_data_collector_artifacts=ignore_data_collector_artifacts,
)
if result.revved:
android_atom_to_build = result.android_atom
except packages.AndroidIsPinnedUprevError as e:
# If the uprev failed due to a pin, CI needs to unpin and retry.
android_atom_to_build = e.new_android_atom
response.status = android_pb2.MARK_STABLE_STATUS_PINNED
if android_atom_to_build:
pkg = package_info.parse(android_atom_to_build)
controller_util.serialize_package_info(pkg, response.android_atom)
else:
response.status = android_pb2.MARK_STABLE_STATUS_EARLY_EXIT
# We don't use @faux.success for UnpinVersion because response is unused.
@faux.all_empty
@validate.validation_complete
def UnpinVersion(
_request: android_pb2.UnpinVersionRequest,
_response: android_pb2.UnpinVersionResponse,
_config: "api_config.ApiConfig",
) -> None:
"""Unpin the Android version.
See AndroidService documentation in api/proto/android.proto.
Args:
_request: The input proto. (not used.)
_response: The output proto. (not used.)
_config: The call config.
"""
osutils.SafeUnlink(ANDROIDPIN_MASK_PATH)
def _WriteLKGBResponse(_request, response, _config) -> None:
"""Fake WriteLKGB response."""
response.modified_files.append("fake_file")
@faux.success(_WriteLKGBResponse)
@faux.empty_error
@validate.require("android_package", "android_version")
@validate.validation_complete
def WriteLKGB(request, response, _config) -> None:
android_package = request.android_package
android_version = request.android_version
android_branch = (
request.android_branch
or android.GetAndroidBranchForPackage(android_package)
)
android_package_dir = android.GetAndroidPackageDir(android_package)
# Attempt to read current LKGB, if available.
current_lkgb = None
try:
current_lkgb = android.ReadLKGB(android_package_dir)
except android.MissingLKGBError:
logging.info("LKGB file is missing, creating a new one.")
except android.InvalidLKGBError:
logging.warning("Current LKGB file is invalid, overwriting.")
# For release branches: check if the runtime artifacts pin exists.
milestone = packages.determine_milestone_version()
runtime_artifacts_pin = android.FindRuntimeArtifactsPin(
android_package, milestone
)
if runtime_artifacts_pin is not None:
logging.info(
"Found runtime artifacts pin for M%s: %s",
milestone,
runtime_artifacts_pin,
)
lkgb = android.LKGB(
build_id=android_version,
branch=android_branch,
runtime_artifacts_pin=runtime_artifacts_pin,
)
# Do nothing if LKGB is already set to the requested version.
if current_lkgb == lkgb:
logging.warning(
"LKGB of %s is already %s, doing nothing.",
android_package,
android_version,
)
return
# Actually update LKGB.
modified = android.WriteLKGB(android_package_dir, lkgb)
response.modified_files.append(modified)