blob: 70dbfb2a31438f3457a3d0dc4dad4f08f3a4e692 [file] [log] [blame]
Mike Frysingerf1ba7ad2022-09-12 05:42:57 -04001# Copyright 2019 The ChromiumOS Authors
Alex Kleineb77ffa2019-05-28 14:47:44 -06002# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
4
5"""Package utility functionality."""
6
Yaakov Shaul730814a2019-09-10 13:58:25 -06007import collections
Trent Apted593c0742023-05-05 03:50:20 +00008
9# TODO(b/236161656): Fix.
10# pylint: disable-next=no-name-in-module,import-error
Ben Reiche779cf42020-12-15 03:21:31 +000011from distutils.version import LooseVersion
Yaakov Shaulcb1cfc32019-09-16 13:51:19 -060012import fileinput
Alex Klein87531182019-08-12 15:23:37 -060013import functools
Yaakov Shaul395ae832019-09-09 14:45:32 -060014import json
Chris McDonaldf7c03d42021-07-21 11:54:26 -060015import logging
Evan Hernandezb51f1522019-08-15 11:29:40 -060016import os
Michael Mortensenb70e8a82019-10-10 18:43:41 -060017import re
Yaakov Shaulcb1cfc32019-09-16 13:51:19 -060018import sys
Alex Klein68a28712021-11-08 11:08:30 -070019from typing import Iterable, List, NamedTuple, Optional, TYPE_CHECKING, Union
Alex Klein87531182019-08-12 15:23:37 -060020
Mike Frysinger2c024062021-05-22 15:43:22 -040021from chromite.third_party.google.protobuf import json_format
Yaakov Shaul730814a2019-09-10 13:58:25 -060022
Andrew Lamb2bde9e42019-11-04 13:24:09 -070023from chromite.api.gen.config import replication_config_pb2
Ram Chandrasekar60f69f32022-06-03 22:49:30 +000024from chromite.lib import chromeos_version
Alex Kleineb77ffa2019-05-28 14:47:44 -060025from chromite.lib import constants
Evan Hernandezb51f1522019-08-15 11:29:40 -060026from chromite.lib import cros_build_lib
Alex Kleineb77ffa2019-05-28 14:47:44 -060027from chromite.lib import git
Michael Mortensende716a12020-05-15 11:27:00 -060028from chromite.lib import image_lib
Michael Mortensenb70e8a82019-10-10 18:43:41 -060029from chromite.lib import osutils
Alex Kleineb77ffa2019-05-28 14:47:44 -060030from chromite.lib import portage_util
Andrew Lamb2bde9e42019-11-04 13:24:09 -070031from chromite.lib import replication_lib
Alex Kleind6195b62019-08-06 16:01:16 -060032from chromite.lib import uprev_lib
Alex Klein18a60af2020-06-11 12:08:47 -060033from chromite.lib.parser import package_info
Shao-Chuan Lee05e51142021-11-24 12:27:37 +090034from chromite.service import android
Alex Kleineb77ffa2019-05-28 14:47:44 -060035
Mike Frysinger68796b52019-08-25 00:04:27 -040036
Alex Klein5caab872021-09-10 11:44:37 -060037if TYPE_CHECKING:
Alex Klein1699fab2022-09-08 08:46:06 -060038 from chromite.lib import build_target_lib
39 from chromite.lib import chroot_lib
Chris McDonaldf7c03d42021-07-21 11:54:26 -060040
Alex Klein36b117f2019-09-30 15:13:46 -060041if cros_build_lib.IsInsideChroot():
Alex Klein1699fab2022-09-08 08:46:06 -060042 from chromite.lib import depgraph
43 from chromite.service import dependency
Alex Klein36b117f2019-09-30 15:13:46 -060044
Alex Klein87531182019-08-12 15:23:37 -060045# Registered handlers for uprevving versioned packages.
46_UPREV_FUNCS = {}
47
Alex Kleineb77ffa2019-05-28 14:47:44 -060048
49class Error(Exception):
Alex Klein1699fab2022-09-08 08:46:06 -060050 """Module's base error class."""
Alex Kleineb77ffa2019-05-28 14:47:44 -060051
52
Alex Klein4de25e82019-08-05 15:58:39 -060053class UnknownPackageError(Error):
Alex Klein1699fab2022-09-08 08:46:06 -060054 """Uprev attempted for a package without a registered handler."""
Alex Klein4de25e82019-08-05 15:58:39 -060055
56
Alex Kleineb77ffa2019-05-28 14:47:44 -060057class UprevError(Error):
Alex Klein1699fab2022-09-08 08:46:06 -060058 """An error occurred while uprevving packages."""
Alex Kleineb77ffa2019-05-28 14:47:44 -060059
60
Michael Mortensenb70e8a82019-10-10 18:43:41 -060061class NoAndroidVersionError(Error):
Alex Klein1699fab2022-09-08 08:46:06 -060062 """An error occurred while trying to determine the android version."""
Michael Mortensenb70e8a82019-10-10 18:43:41 -060063
64
65class NoAndroidBranchError(Error):
Alex Klein1699fab2022-09-08 08:46:06 -060066 """An error occurred while trying to determine the android branch."""
Michael Mortensenb70e8a82019-10-10 18:43:41 -060067
68
69class NoAndroidTargetError(Error):
Alex Klein1699fab2022-09-08 08:46:06 -060070 """An error occurred while trying to determine the android target."""
Michael Mortensenb70e8a82019-10-10 18:43:41 -060071
72
Lizzy Presland0b978e62022-09-09 16:55:29 +000073class KernelVersionError(Error):
74 """An error occurred while trying to determine the kernel version."""
75
76
Alex Klein4de25e82019-08-05 15:58:39 -060077class AndroidIsPinnedUprevError(UprevError):
Alex Klein1699fab2022-09-08 08:46:06 -060078 """Raised when we try to uprev while Android is pinned."""
Alex Klein4de25e82019-08-05 15:58:39 -060079
Alex Klein1699fab2022-09-08 08:46:06 -060080 def __init__(self, new_android_atom):
81 """Initialize a AndroidIsPinnedUprevError.
Alex Klein4de25e82019-08-05 15:58:39 -060082
Alex Klein1699fab2022-09-08 08:46:06 -060083 Args:
Alex Klein348e7692022-10-13 17:03:37 -060084 new_android_atom: The Android atom that we failed to uprev to, due
85 to Android being pinned.
Alex Klein1699fab2022-09-08 08:46:06 -060086 """
87 assert new_android_atom
88 msg = (
89 "Failed up uprev to Android version %s as Android was pinned."
90 % new_android_atom
91 )
92 super().__init__(msg)
93 self.new_android_atom = new_android_atom
Alex Klein87531182019-08-12 15:23:37 -060094
95
Andrew Lamb9563a152019-12-04 11:42:18 -070096class GeneratedCrosConfigFilesError(Error):
Alex Klein1699fab2022-09-08 08:46:06 -060097 """Error when cros_config_schema does not produce expected files"""
Andrew Lamb9563a152019-12-04 11:42:18 -070098
Alex Klein1699fab2022-09-08 08:46:06 -060099 def __init__(self, expected_files, found_files):
100 msg = "Expected to find generated C files: %s. Actually found: %s" % (
101 expected_files,
102 found_files,
103 )
104 super().__init__(msg)
Andrew Lamb9563a152019-12-04 11:42:18 -0700105
Alex Klein7a3a7dd2020-01-08 16:44:38 -0700106
Alex Klein1699fab2022-09-08 08:46:06 -0600107NeedsChromeSourceResult = collections.namedtuple(
108 "NeedsChromeSourceResult",
109 (
110 "needs_chrome_source",
111 "builds_chrome",
112 "packages",
113 "missing_chrome_prebuilt",
114 "missing_follower_prebuilt",
115 "local_uprev",
116 ),
117)
Alex Klein6becabc2020-09-11 14:03:05 -0600118
119
Yaakov Shaulcb1cfc32019-09-16 13:51:19 -0600120def patch_ebuild_vars(ebuild_path, variables):
Alex Klein1699fab2022-09-08 08:46:06 -0600121 """Updates variables in ebuild.
Yaakov Shaulcb1cfc32019-09-16 13:51:19 -0600122
Alex Klein1699fab2022-09-08 08:46:06 -0600123 Use this function rather than portage_util.EBuild.UpdateEBuild when you
124 want to preserve the variable position and quotes within the ebuild.
Yaakov Shaulcb1cfc32019-09-16 13:51:19 -0600125
Alex Klein1699fab2022-09-08 08:46:06 -0600126 Args:
Alex Klein348e7692022-10-13 17:03:37 -0600127 ebuild_path: The path of the ebuild.
128 variables: Dictionary of variables to update in ebuild.
Alex Klein1699fab2022-09-08 08:46:06 -0600129 """
130 try:
131 for line in fileinput.input(ebuild_path, inplace=1):
132 for var, value in variables.items():
133 line = re.sub(rf"\b{var}=\S+", f'{var}="{value}"', line)
134 sys.stdout.write(line)
135 finally:
136 fileinput.close()
Yaakov Shaulcb1cfc32019-09-16 13:51:19 -0600137
138
Alex Klein87531182019-08-12 15:23:37 -0600139def uprevs_versioned_package(package):
Alex Klein1699fab2022-09-08 08:46:06 -0600140 """Decorator to register package uprev handlers."""
141 assert package
Alex Klein87531182019-08-12 15:23:37 -0600142
Alex Klein1699fab2022-09-08 08:46:06 -0600143 def register(func):
144 """Registers |func| as a handler for |package|."""
145 _UPREV_FUNCS[package] = func
Alex Klein87531182019-08-12 15:23:37 -0600146
Alex Klein1699fab2022-09-08 08:46:06 -0600147 @functools.wraps(func)
148 def pass_through(*args, **kwargs):
149 return func(*args, **kwargs)
Alex Klein87531182019-08-12 15:23:37 -0600150
Alex Klein1699fab2022-09-08 08:46:06 -0600151 return pass_through
Alex Klein87531182019-08-12 15:23:37 -0600152
Alex Klein1699fab2022-09-08 08:46:06 -0600153 return register
Alex Klein87531182019-08-12 15:23:37 -0600154
155
Shao-Chuan Lee84bf9a22021-11-19 17:42:11 +0900156class UprevAndroidResult(NamedTuple):
Alex Klein1699fab2022-09-08 08:46:06 -0600157 """Results of an Android uprev."""
158
159 revved: bool
160 android_atom: str = None
161 modified_files: List[str] = None
Shao-Chuan Lee84bf9a22021-11-19 17:42:11 +0900162
163
164def uprev_android(
165 android_package: str,
Alex Klein1699fab2022-09-08 08:46:06 -0600166 chroot: "chroot_lib.Chroot",
167 build_targets: Optional[List["build_target_lib.BuildTarget"]] = None,
Shao-Chuan Lee84bf9a22021-11-19 17:42:11 +0900168 android_build_branch: Optional[str] = None,
169 android_version: Optional[str] = None,
Alex Klein1699fab2022-09-08 08:46:06 -0600170 skip_commit: bool = False,
171) -> UprevAndroidResult:
172 """Performs an Android uprev by calling cros_mark_android_as_stable.
Shao-Chuan Lee84bf9a22021-11-19 17:42:11 +0900173
Alex Klein1699fab2022-09-08 08:46:06 -0600174 Args:
Alex Klein348e7692022-10-13 17:03:37 -0600175 android_package: The Android package to uprev.
176 chroot: The chroot to enter.
177 build_targets: List of build targets to cleanup after uprev.
178 android_build_branch: Override the default Android branch corresponding
179 to the package.
180 android_version: Uprev to the particular version. By default the latest
181 available version is used.
182 skip_commit: Whether to skip committing the change after a successful
183 uprev.
Shao-Chuan Lee84bf9a22021-11-19 17:42:11 +0900184
Alex Klein1699fab2022-09-08 08:46:06 -0600185 Returns:
Alex Klein348e7692022-10-13 17:03:37 -0600186 The uprev result containing:
187 revved: Whether an uprev happened.
188 android_atom: If revved, the portage atom for the revved Android
189 ebuild.
190 modified_files: If revved, list of files being modified.
Alex Klein1699fab2022-09-08 08:46:06 -0600191 """
192 command = [
193 "cros_mark_android_as_stable",
194 f"--android_package={android_package}",
195 ]
196 if build_targets:
197 command.append(f'--boards={":".join(bt.name for bt in build_targets)}')
198 if android_build_branch:
199 command.append(f"--android_build_branch={android_build_branch}")
200 if android_version:
201 command.append(f"--force_version={android_version}")
202 if skip_commit:
203 command.append("--skip_commit")
Alex Klein4de25e82019-08-05 15:58:39 -0600204
Alex Klein1699fab2022-09-08 08:46:06 -0600205 result = cros_build_lib.run(
206 command,
207 stdout=True,
208 enter_chroot=True,
209 encoding="utf-8",
210 chroot_args=chroot.get_enter_args(),
211 )
Alex Klein4de25e82019-08-05 15:58:39 -0600212
Alex Klein1699fab2022-09-08 08:46:06 -0600213 # cros_mark_android_as_stable prints the uprev result to stdout as JSON in a
214 # single line. We only take the last line from stdout to make sure no junk
Alex Kleinfee86da2023-01-20 18:40:06 -0700215 # output is included (e.g. messages from bashrc scripts that run upon
216 # entering the chroot.)
Alex Klein1699fab2022-09-08 08:46:06 -0600217 output = json.loads(result.stdout.strip().splitlines()[-1])
Shao-Chuan Leedea458f2021-11-25 23:46:53 +0900218
Alex Klein1699fab2022-09-08 08:46:06 -0600219 if not output["revved"]:
220 logging.info("Found nothing to rev.")
221 return UprevAndroidResult(revved=False)
Shao-Chuan Lee84bf9a22021-11-19 17:42:11 +0900222
Alex Klein1699fab2022-09-08 08:46:06 -0600223 android_atom = output["android_atom"]
Alex Klein4de25e82019-08-05 15:58:39 -0600224
Alex Klein1699fab2022-09-08 08:46:06 -0600225 for target in build_targets or []:
226 # Sanity check: We should always be able to merge the version of
227 # Android we just unmasked.
228 command = [f"emerge-{target.name}", "-p", "--quiet", f"={android_atom}"]
229 try:
230 cros_build_lib.run(
231 command, enter_chroot=True, chroot_args=chroot.get_enter_args()
232 )
233 except cros_build_lib.RunCommandError:
234 logging.error(
Trent Aptedb18e36f2023-05-10 15:06:38 +1000235 "Cannot emerge-%s =%s\nIs Android pinned to an older version?",
Alex Klein1699fab2022-09-08 08:46:06 -0600236 target,
237 android_atom,
238 )
239 raise AndroidIsPinnedUprevError(android_atom)
Alex Klein4de25e82019-08-05 15:58:39 -0600240
Alex Klein1699fab2022-09-08 08:46:06 -0600241 return UprevAndroidResult(
242 revved=True,
243 android_atom=android_atom,
244 modified_files=output["modified_files"],
245 )
Shao-Chuan Lee05e51142021-11-24 12:27:37 +0900246
247
Alex Klein1699fab2022-09-08 08:46:06 -0600248def uprev_android_lkgb(
249 android_package: str,
250 build_targets: List["build_target_lib.BuildTarget"],
251 chroot: "chroot_lib.Chroot",
252) -> uprev_lib.UprevVersionedPackageResult:
253 """Uprevs an Android package to the version specified in the LKGB file.
Shao-Chuan Lee05e51142021-11-24 12:27:37 +0900254
Alex Klein1699fab2022-09-08 08:46:06 -0600255 This is the PUpr handler for Android packages, triggered whenever the
256 corresponding LKGB file is being updated.
Shao-Chuan Lee05e51142021-11-24 12:27:37 +0900257
Alex Kleinfee86da2023-01-20 18:40:06 -0700258 PUpr for Android does not test the uprev change in CQ; instead we run
259 separate jobs to test new Android versions, and we write the latest vetted
260 version to the LKGB file. Find the design at go/android-uprev-recipes.
Shao-Chuan Lee05e51142021-11-24 12:27:37 +0900261
Alex Klein1699fab2022-09-08 08:46:06 -0600262 Args:
Alex Klein348e7692022-10-13 17:03:37 -0600263 android_package: The Android package to uprev.
264 build_targets: List of build targets to cleanup after uprev.
265 chroot: The chroot to enter.
Shao-Chuan Lee05e51142021-11-24 12:27:37 +0900266
Alex Klein1699fab2022-09-08 08:46:06 -0600267 Returns:
Alex Klein348e7692022-10-13 17:03:37 -0600268 An uprev_lib.UprevVersionedPackageResult containing the new version and
269 a list of modified files.
Alex Klein1699fab2022-09-08 08:46:06 -0600270 """
271 android_package_dir = android.GetAndroidPackageDir(android_package)
Shao-Chuan Leee0b9ba92023-01-18 19:35:36 +0900272 android_version = android.ReadLKGB(android_package_dir)["build_id"]
Shao-Chuan Lee05e51142021-11-24 12:27:37 +0900273
Alex Klein1699fab2022-09-08 08:46:06 -0600274 result = uprev_lib.UprevVersionedPackageResult()
275 uprev_result = uprev_android(
276 android_package,
277 chroot,
278 build_targets=build_targets,
279 android_version=android_version,
280 skip_commit=True,
281 )
282 if not uprev_result.revved:
283 return result
284
Alex Kleinfee86da2023-01-20 18:40:06 -0700285 # cros_mark_android_as_stable returns paths relative to
286 # |android.OVERLAY_DIR|.
Alex Klein1699fab2022-09-08 08:46:06 -0600287 result.add_result(
288 android_version,
289 [
290 os.path.join(android.OVERLAY_DIR, f)
291 for f in uprev_result.modified_files
292 ],
293 )
Shao-Chuan Lee05e51142021-11-24 12:27:37 +0900294 return result
295
Shao-Chuan Lee05e51142021-11-24 12:27:37 +0900296
297def define_uprev_android_lkgb_handlers():
Alex Klein1699fab2022-09-08 08:46:06 -0600298 """Dynamically define uprev handlers for each Android package"""
Shao-Chuan Lee05e51142021-11-24 12:27:37 +0900299
Alex Klein1699fab2022-09-08 08:46:06 -0600300 def define_handler(android_package):
301 """Defines the uprev handler for an Android package."""
302 full_package_name = "chromeos-base/" + android_package
Shao-Chuan Lee05e51142021-11-24 12:27:37 +0900303
Alex Klein1699fab2022-09-08 08:46:06 -0600304 @uprevs_versioned_package(full_package_name)
305 def _handler(build_targets, _refs, chroot):
306 return uprev_android_lkgb(android_package, build_targets, chroot)
Shao-Chuan Lee05e51142021-11-24 12:27:37 +0900307
Shao-Chuan Leeca2cbcc2022-11-02 08:28:31 +0900308 for android_package in android.GetAllAndroidPackages():
Alex Klein1699fab2022-09-08 08:46:06 -0600309 define_handler(android_package)
Shao-Chuan Lee05e51142021-11-24 12:27:37 +0900310
311
312define_uprev_android_lkgb_handlers()
Alex Klein4de25e82019-08-05 15:58:39 -0600313
314
Matthias Kaehlckebf7d1772021-11-04 16:01:36 -0700315def uprev_build_targets(
Alex Klein1699fab2022-09-08 08:46:06 -0600316 build_targets: Optional[List["build_target_lib.BuildTarget"]],
Matthias Kaehlckebf7d1772021-11-04 16:01:36 -0700317 overlay_type: str,
Alex Klein1699fab2022-09-08 08:46:06 -0600318 chroot: "chroot_lib.Chroot" = None,
319 output_dir: Optional[str] = None,
320):
321 """Uprev the set provided build targets, or all if not specified.
Alex Kleineb77ffa2019-05-28 14:47:44 -0600322
Alex Klein1699fab2022-09-08 08:46:06 -0600323 Args:
Alex Klein348e7692022-10-13 17:03:37 -0600324 build_targets: The build targets whose overlays should be uprevved,
325 empty or None for all.
326 overlay_type: One of the valid overlay types except None (see
327 constants.VALID_OVERLAYS).
328 chroot: The chroot to clean, if desired.
329 output_dir: The path to optionally dump result files.
Alex Klein1699fab2022-09-08 08:46:06 -0600330 """
331 # Need a valid overlay, but exclude None.
332 assert overlay_type and overlay_type in constants.VALID_OVERLAYS
Alex Kleineb77ffa2019-05-28 14:47:44 -0600333
Alex Klein1699fab2022-09-08 08:46:06 -0600334 if build_targets:
335 overlays = portage_util.FindOverlaysForBoards(
336 overlay_type, boards=[t.name for t in build_targets]
337 )
338 else:
339 overlays = portage_util.FindOverlays(overlay_type)
Alex Kleineb77ffa2019-05-28 14:47:44 -0600340
Alex Klein1699fab2022-09-08 08:46:06 -0600341 return uprev_overlays(
342 overlays,
343 build_targets=build_targets,
344 chroot=chroot,
345 output_dir=output_dir,
346 )
Alex Kleineb77ffa2019-05-28 14:47:44 -0600347
348
Matthias Kaehlckebf7d1772021-11-04 16:01:36 -0700349def uprev_overlays(
350 overlays: List[str],
Alex Klein1699fab2022-09-08 08:46:06 -0600351 build_targets: Optional[List["build_target_lib.BuildTarget"]] = None,
352 chroot: Optional["chroot_lib.Chroot"] = None,
353 output_dir: Optional[str] = None,
354) -> List[str]:
355 """Uprev the given overlays.
Alex Kleineb77ffa2019-05-28 14:47:44 -0600356
Alex Klein1699fab2022-09-08 08:46:06 -0600357 Args:
Alex Klein348e7692022-10-13 17:03:37 -0600358 overlays: The list of overlay paths.
359 build_targets: The build targets to clean in |chroot|, if desired. No
360 effect unless |chroot| is provided.
361 chroot: The chroot to clean, if desired.
362 output_dir: The path to optionally dump result files.
Alex Kleineb77ffa2019-05-28 14:47:44 -0600363
Alex Klein1699fab2022-09-08 08:46:06 -0600364 Returns:
Alex Klein348e7692022-10-13 17:03:37 -0600365 The paths to all the modified ebuild files. This includes the new files
366 that were added (i.e. the new versions) and all the removed files
Alex Klein1699fab2022-09-08 08:46:06 -0600367 (i.e. the old versions).
368 """
369 assert overlays
Alex Kleineb77ffa2019-05-28 14:47:44 -0600370
Alex Klein1699fab2022-09-08 08:46:06 -0600371 manifest = git.ManifestCheckout.Cached(constants.SOURCE_ROOT)
Alex Kleineb77ffa2019-05-28 14:47:44 -0600372
Alex Klein1699fab2022-09-08 08:46:06 -0600373 uprev_manager = uprev_lib.UprevOverlayManager(
374 overlays,
375 manifest,
376 build_targets=build_targets,
377 chroot=chroot,
378 output_dir=output_dir,
379 )
380 uprev_manager.uprev()
Alex Kleineb77ffa2019-05-28 14:47:44 -0600381
Alex Klein1699fab2022-09-08 08:46:06 -0600382 return uprev_manager.modified_ebuilds, uprev_manager.revved_packages
Alex Kleineb77ffa2019-05-28 14:47:44 -0600383
384
Matthias Kaehlckebf7d1772021-11-04 16:01:36 -0700385def uprev_versioned_package(
Alex Kleind3b84042023-05-19 14:43:59 -0600386 package: package_info.PackageInfo,
Alex Klein1699fab2022-09-08 08:46:06 -0600387 build_targets: List["build_target_lib.BuildTarget"],
Matthias Kaehlckebf7d1772021-11-04 16:01:36 -0700388 refs: List[uprev_lib.GitRef],
Alex Klein1699fab2022-09-08 08:46:06 -0600389 chroot: "chroot_lib.Chroot",
390) -> "uprev_lib.UprevVersionedPackageResult":
391 """Call registered uprev handler function for the package.
Alex Klein87531182019-08-12 15:23:37 -0600392
Alex Klein1699fab2022-09-08 08:46:06 -0600393 Args:
Alex Klein348e7692022-10-13 17:03:37 -0600394 package: The package being uprevved.
395 build_targets: The build targets to clean on a successful uprev.
396 refs:
397 chroot: The chroot to enter for cleaning.
Alex Klein87531182019-08-12 15:23:37 -0600398
Alex Klein1699fab2022-09-08 08:46:06 -0600399 Returns:
Alex Klein348e7692022-10-13 17:03:37 -0600400 The result.
Alex Klein1699fab2022-09-08 08:46:06 -0600401 """
402 assert package
Alex Klein87531182019-08-12 15:23:37 -0600403
Alex Klein1699fab2022-09-08 08:46:06 -0600404 if package.cp not in _UPREV_FUNCS:
405 raise UnknownPackageError(
406 'Package "%s" does not have a registered handler.' % package.cp
407 )
Alex Klein87531182019-08-12 15:23:37 -0600408
Alex Klein1699fab2022-09-08 08:46:06 -0600409 return _UPREV_FUNCS[package.cp](build_targets, refs, chroot)
Alex Klein87531182019-08-12 15:23:37 -0600410
411
Alex Klein1699fab2022-09-08 08:46:06 -0600412@uprevs_versioned_package("media-libs/virglrenderer")
Navil Perezf57ba872020-06-04 22:38:37 +0000413def uprev_virglrenderer(_build_targets, refs, _chroot):
Alex Klein1699fab2022-09-08 08:46:06 -0600414 """Updates virglrenderer ebuilds.
Navil Perezf57ba872020-06-04 22:38:37 +0000415
Alex Klein1699fab2022-09-08 08:46:06 -0600416 See: uprev_versioned_package.
Navil Perezf57ba872020-06-04 22:38:37 +0000417
Alex Klein1699fab2022-09-08 08:46:06 -0600418 Returns:
Alex Klein348e7692022-10-13 17:03:37 -0600419 UprevVersionedPackageResult: The result of updating virglrenderer
Trent Aptedb18e36f2023-05-10 15:06:38 +1000420 ebuilds.
Alex Klein1699fab2022-09-08 08:46:06 -0600421 """
422 overlay = os.path.join(
423 constants.SOURCE_ROOT, constants.CHROMIUMOS_OVERLAY_DIR
424 )
425 repo_path = os.path.join(
426 constants.SOURCE_ROOT, "src", "third_party", "virglrenderer"
427 )
428 manifest = git.ManifestCheckout.Cached(repo_path)
Navil Perezf57ba872020-06-04 22:38:37 +0000429
Alex Klein1699fab2022-09-08 08:46:06 -0600430 uprev_manager = uprev_lib.UprevOverlayManager([overlay], manifest)
431 # TODO(crbug.com/1066242): Ebuilds for virglrenderer are currently
432 # denylisted. Do not force uprevs after builder is stable and ebuilds are no
433 # longer denylisted.
434 uprev_manager.uprev(package_list=["media-libs/virglrenderer"], force=True)
Navil Perezf57ba872020-06-04 22:38:37 +0000435
Alex Klein1699fab2022-09-08 08:46:06 -0600436 updated_files = uprev_manager.modified_ebuilds
437 result = uprev_lib.UprevVersionedPackageResult()
438 result.add_result(refs[-1].revision, updated_files)
439 return result
Navil Perezf57ba872020-06-04 22:38:37 +0000440
Alex Klein1699fab2022-09-08 08:46:06 -0600441
Matthew Lam59ca37d2022-10-24 18:11:06 +0000442@uprevs_versioned_package("x11-apps/igt-gpu-tools")
443def uprev_igt_gpu_tools(_build_targets, refs, _chroot):
444 """Updates igt-gpu-tools ebuilds.
445
446 See: uprev_versioned_package.
447
448 Returns:
Alex Kleinfee86da2023-01-20 18:40:06 -0700449 UprevVersionedPackageResult: The result of updating igt-gpu-tools
Trent Aptedb18e36f2023-05-10 15:06:38 +1000450 ebuilds.
Matthew Lam59ca37d2022-10-24 18:11:06 +0000451 """
452 overlay = os.path.join(
453 constants.SOURCE_ROOT, constants.CHROMIUMOS_OVERLAY_DIR
454 )
455 repo_path = os.path.join(
456 constants.SOURCE_ROOT, "src", "third_party", "igt-gpu-tools"
457 )
458 manifest = git.ManifestCheckout.Cached(repo_path)
459
460 uprev_manager = uprev_lib.UprevOverlayManager([overlay], manifest)
461 uprev_manager.uprev(package_list=["x11-apps/igt-gpu-tools"], force=True)
462
463 updated_files = uprev_manager.modified_ebuilds
464 result = uprev_lib.UprevVersionedPackageResult()
465 result.add_result(refs[-1].revision, updated_files)
466 return result
467
468
Alex Klein1699fab2022-09-08 08:46:06 -0600469@uprevs_versioned_package("chromeos-base/drivefs")
Jose Magana03b5a842020-08-19 12:52:59 +1000470def uprev_drivefs(_build_targets, refs, chroot):
Alex Klein1699fab2022-09-08 08:46:06 -0600471 """Updates drivefs ebuilds.
Jose Magana03b5a842020-08-19 12:52:59 +1000472
Alex Klein1699fab2022-09-08 08:46:06 -0600473 DriveFS versions follow the tag format of refs/tags/drivefs_1.2.3.
474 See: uprev_versioned_package.
Jose Magana03b5a842020-08-19 12:52:59 +1000475
Alex Klein1699fab2022-09-08 08:46:06 -0600476 Returns:
Alex Klein348e7692022-10-13 17:03:37 -0600477 UprevVersionedPackageResult: The result of updating drivefs ebuilds.
Alex Klein1699fab2022-09-08 08:46:06 -0600478 """
Jose Magana03b5a842020-08-19 12:52:59 +1000479
Alex Klein1699fab2022-09-08 08:46:06 -0600480 DRIVEFS_PATH_PREFIX = "src/private-overlays/chromeos-overlay/chromeos-base"
481 result = uprev_lib.UprevVersionedPackageResult()
482 all_changed_files = []
Jose Magana03b5a842020-08-19 12:52:59 +1000483
Alex Klein1699fab2022-09-08 08:46:06 -0600484 DRIVEFS_REFS_PREFIX = "refs/tags/drivefs_"
485 drivefs_version = _get_latest_version_from_refs(DRIVEFS_REFS_PREFIX, refs)
486 if not drivefs_version:
487 # No valid DriveFS version is identified.
488 return result
489
490 logging.debug("DriveFS version determined from refs: %s", drivefs_version)
491
492 # Attempt to uprev drivefs package.
493 pkg_path = os.path.join(DRIVEFS_PATH_PREFIX, "drivefs")
494 uprev_result = uprev_lib.uprev_workon_ebuild_to_version(
495 pkg_path, drivefs_version, chroot, allow_downrev=False
496 )
497
498 if not uprev_result:
499 return result
500 all_changed_files.extend(uprev_result.changed_files)
501 result.add_result(drivefs_version, all_changed_files)
502
Ben Reich4f3fa1b2020-12-19 08:21:26 +0000503 return result
Jose Magana03b5a842020-08-19 12:52:59 +1000504
Jose Magana03b5a842020-08-19 12:52:59 +1000505
Alex Klein1699fab2022-09-08 08:46:06 -0600506@uprevs_versioned_package("chromeos-base/perfetto")
Chinglin Yufa728552023-04-13 03:12:04 +0000507@uprevs_versioned_package("dev-go/perfetto-protos")
Harvey Yang9c61e9c2021-03-02 16:32:43 +0800508def uprev_perfetto(_build_targets, refs, chroot):
Alex Klein1699fab2022-09-08 08:46:06 -0600509 """Updates Perfetto ebuilds.
Harvey Yang9c61e9c2021-03-02 16:32:43 +0800510
Alex Klein1699fab2022-09-08 08:46:06 -0600511 Perfetto versions follow the tag format of refs/tags/v1.2.
512 See: uprev_versioned_package.
Harvey Yang9c61e9c2021-03-02 16:32:43 +0800513
Alex Klein1699fab2022-09-08 08:46:06 -0600514 Returns:
Alex Klein348e7692022-10-13 17:03:37 -0600515 UprevVersionedPackageResult: The result of updating Perfetto ebuilds.
Alex Klein1699fab2022-09-08 08:46:06 -0600516 """
517 result = uprev_lib.UprevVersionedPackageResult()
Harvey Yang9c61e9c2021-03-02 16:32:43 +0800518
Alex Klein1699fab2022-09-08 08:46:06 -0600519 PERFETTO_REFS_PREFIX = "refs/tags/v"
Chinglin Yufa728552023-04-13 03:12:04 +0000520
521 perfetto_ebuilds = ["chromeos-base/perfetto", "dev-go/perfetto-protos"]
522 perfetto_paths = [
523 os.path.join(constants.CHROMIUMOS_OVERLAY_DIR, e)
524 for e in perfetto_ebuilds
525 ]
526 # chromeos-base/perfetto is the primary ebuild.
527 primary_ebuild_path = perfetto_paths[0]
Chinglin Yuad12a512022-10-07 17:26:12 +0800528
529 # Decide the version number to uprev to:
530 # * If |refs| contains refs/tags/v*, get the latest from them.
Alex Klein1699fab2022-09-08 08:46:06 -0600531 perfetto_version = _get_latest_version_from_refs(PERFETTO_REFS_PREFIX, refs)
Chinglin Yuad12a512022-10-07 17:26:12 +0800532 # * Or if |refs| contains only the latest trunk revisions, use the current
533 # stable ebuild version for a revision bump.
534 if refs and not perfetto_version:
Chinglin Yufa728552023-04-13 03:12:04 +0000535 perfetto_version = uprev_lib.get_stable_ebuild_version(
536 primary_ebuild_path
537 )
Chinglin Yuad12a512022-10-07 17:26:12 +0800538
Alex Klein1699fab2022-09-08 08:46:06 -0600539 if not perfetto_version:
540 # No valid Perfetto version is identified.
541 return result
542
Chinglin Yufa728552023-04-13 03:12:04 +0000543 for path in perfetto_paths:
544 # Attempt to uprev perfetto package.
545 # |perfetto_version| is only used in determining the ebuild version. The
546 # package is always updated to the latest HEAD.
547 uprev_result = uprev_lib.uprev_workon_ebuild_to_version(
548 path,
549 perfetto_version,
550 chroot,
551 allow_downrev=False,
552 # Use default ref="HEAD"
553 )
Alex Klein1699fab2022-09-08 08:46:06 -0600554
Chinglin Yufa728552023-04-13 03:12:04 +0000555 if not uprev_result:
556 return result
Alex Klein1699fab2022-09-08 08:46:06 -0600557
Chinglin Yufa728552023-04-13 03:12:04 +0000558 # Include short git sha hash in the uprev commit message.
559 # Use 9 digits to match the short hash length in `perfetto --version`.
560 short_revision = refs[-1].revision[0:9]
561 version_and_rev = f"{perfetto_version}-{short_revision}"
562 result.add_result(version_and_rev, uprev_result.changed_files)
Alex Klein1699fab2022-09-08 08:46:06 -0600563
Harvey Yang9c61e9c2021-03-02 16:32:43 +0800564 return result
565
Harvey Yang9c61e9c2021-03-02 16:32:43 +0800566
Denis Nikitin63613e32022-09-09 22:26:50 -0700567class AfdoMetadata(NamedTuple):
568 """Data class holding AFDO metadata."""
569
570 var_name: str
571 path: str
572
573
Alex Klein1699fab2022-09-08 08:46:06 -0600574@uprevs_versioned_package("afdo/kernel-profiles")
Yaakov Shaul395ae832019-09-09 14:45:32 -0600575def uprev_kernel_afdo(*_args, **_kwargs):
Alex Klein1699fab2022-09-08 08:46:06 -0600576 """Updates kernel ebuilds with versions from kernel_afdo.json.
Yaakov Shaul395ae832019-09-09 14:45:32 -0600577
Alex Klein1699fab2022-09-08 08:46:06 -0600578 See: uprev_versioned_package.
Yaakov Shaul1eafe832019-09-10 16:50:26 -0600579
Alex Klein1699fab2022-09-08 08:46:06 -0600580 Raises:
Alex Klein348e7692022-10-13 17:03:37 -0600581 EbuildManifestError: When ebuild manifest does not complete
582 successfully.
583 JSONDecodeError: When json is malformed.
Alex Klein1699fab2022-09-08 08:46:06 -0600584 """
Denis Nikitin63613e32022-09-09 22:26:50 -0700585 metadata_dir = os.path.join(
Alex Klein1699fab2022-09-08 08:46:06 -0600586 constants.SOURCE_ROOT,
587 "src",
588 "third_party",
589 "toolchain-utils",
590 "afdo_metadata",
Denis Nikitin63613e32022-09-09 22:26:50 -0700591 )
592 metadata_files = (
593 AfdoMetadata(
594 var_name="AFDO_PROFILE_VERSION",
595 path=os.path.join(metadata_dir, "kernel_afdo.json"),
596 ),
597 AfdoMetadata(
598 var_name="ARM_AFDO_PROFILE_VERSION",
599 path=os.path.join(metadata_dir, "kernel_arm_afdo.json"),
600 ),
Alex Klein1699fab2022-09-08 08:46:06 -0600601 )
Yaakov Shaul395ae832019-09-09 14:45:32 -0600602
Alex Klein1699fab2022-09-08 08:46:06 -0600603 result = uprev_lib.UprevVersionedPackageResult()
Denis Nikitin63613e32022-09-09 22:26:50 -0700604 for metadata in metadata_files:
Mike Frysinger81a98062023-02-24 15:42:04 -0500605 with open(metadata.path, "r", encoding="utf-8") as f:
Denis Nikitin63613e32022-09-09 22:26:50 -0700606 versions = json.load(f)
Yaakov Shaul1eafe832019-09-10 16:50:26 -0600607
Denis Nikitin63613e32022-09-09 22:26:50 -0700608 for kernel_pkg, version_info in versions.items():
609 path = os.path.join(
610 constants.CHROMIUMOS_OVERLAY_DIR, "sys-kernel", kernel_pkg
611 )
612 ebuild_path = os.path.join(
613 constants.SOURCE_ROOT, path, f"{kernel_pkg}-9999.ebuild"
614 )
615 chroot_ebuild_path = os.path.join(
616 constants.CHROOT_SOURCE_ROOT, path, f"{kernel_pkg}-9999.ebuild"
617 )
618 afdo_profile_version = version_info["name"]
619 patch_ebuild_vars(
620 ebuild_path, {metadata.var_name: afdo_profile_version}
Alex Klein1699fab2022-09-08 08:46:06 -0600621 )
Yaakov Shaul1eafe832019-09-10 16:50:26 -0600622
Denis Nikitin63613e32022-09-09 22:26:50 -0700623 try:
624 cmd = ["ebuild", chroot_ebuild_path, "manifest", "--force"]
625 cros_build_lib.run(cmd, enter_chroot=True)
626 except cros_build_lib.RunCommandError as e:
627 raise uprev_lib.EbuildManifestError(
628 "Error encountered when regenerating the manifest for "
629 f"ebuild: {chroot_ebuild_path}\n{e}",
630 e,
631 )
Yaakov Shaul1eafe832019-09-10 16:50:26 -0600632
Denis Nikitin63613e32022-09-09 22:26:50 -0700633 manifest_path = os.path.join(
634 constants.SOURCE_ROOT, path, "Manifest"
635 )
636 result.add_result(
637 afdo_profile_version, [ebuild_path, manifest_path]
638 )
Yaakov Shaul730814a2019-09-10 13:58:25 -0600639
Alex Klein1699fab2022-09-08 08:46:06 -0600640 return result
Yaakov Shaul395ae832019-09-09 14:45:32 -0600641
642
Alex Klein1699fab2022-09-08 08:46:06 -0600643@uprevs_versioned_package("chromeos-base/termina-dlc")
644@uprevs_versioned_package("chromeos-base/termina-tools-dlc")
Maciek Swiech6b12f662022-01-25 16:51:19 +0000645def uprev_termina_dlcs(_build_targets, _refs, chroot):
Alex Klein1699fab2022-09-08 08:46:06 -0600646 """Updates shared termina-dlc and termina-tools-dlc ebuilds.
Maciek Swiech6b12f662022-01-25 16:51:19 +0000647
Alex Klein1699fab2022-09-08 08:46:06 -0600648 termina-dlc - chromeos-base/termina-dlc
649 termina-tools-dlc - chromeos-base/termina-tools-dlc
Trent Beginaf51f1b2020-03-09 17:35:31 -0600650
Alex Klein1699fab2022-09-08 08:46:06 -0600651 See: uprev_versioned_package.
652 """
653 termina_dlc_pkg = "termina-dlc"
654 termina_dlc_pkg_path = os.path.join(
655 constants.CHROMIUMOS_OVERLAY_DIR, "chromeos-base", termina_dlc_pkg
656 )
657 tools_dlc_pkg = "termina-tools-dlc"
658 tools_dlc_pkg_path = os.path.join(
659 constants.CHROMIUMOS_OVERLAY_DIR, "chromeos-base", tools_dlc_pkg
660 )
Patrick Meiring5897add2020-09-16 16:30:17 +1000661
Alex Klein1699fab2022-09-08 08:46:06 -0600662 # termina-dlc and termina-tools-dlc are pinned to the same version.
663 version_pin_src_path = _get_version_pin_src_path(termina_dlc_pkg_path)
664 version_no_rev = osutils.ReadFile(version_pin_src_path).strip()
Patrick Meiring5897add2020-09-16 16:30:17 +1000665
Alex Klein1699fab2022-09-08 08:46:06 -0600666 result = uprev_lib.uprev_ebuild_from_pin(
667 termina_dlc_pkg_path, version_no_rev, chroot
668 )
669 result += uprev_lib.uprev_ebuild_from_pin(
670 tools_dlc_pkg_path, version_no_rev, chroot
671 )
Patrick Meiring5897add2020-09-16 16:30:17 +1000672
Alex Klein1699fab2022-09-08 08:46:06 -0600673 return result
Patrick Meiring5897add2020-09-16 16:30:17 +1000674
Alex Klein1699fab2022-09-08 08:46:06 -0600675
676@uprevs_versioned_package("chromeos-base/chromeos-lacros")
Julio Hurtadof1befec2021-05-05 21:34:26 +0000677def uprev_lacros(_build_targets, refs, chroot):
Alex Klein1699fab2022-09-08 08:46:06 -0600678 """Updates lacros ebuilds.
Julio Hurtadof1befec2021-05-05 21:34:26 +0000679
Alex Klein1699fab2022-09-08 08:46:06 -0600680 Version to uprev to is gathered from the QA qualified version tracking file
Alex Kleinfee86da2023-01-20 18:40:06 -0700681 stored in chromium/src/chrome/LACROS_QA_QUALIFIED_VERSION. Uprev is
682 triggered on modification of this file across all chromium/src branches.
Julio Hurtadof1befec2021-05-05 21:34:26 +0000683
Alex Klein1699fab2022-09-08 08:46:06 -0600684 See: uprev_versioned_package.
685 """
686 result = uprev_lib.UprevVersionedPackageResult()
687 path = os.path.join(
688 constants.CHROMIUMOS_OVERLAY_DIR, "chromeos-base", "chromeos-lacros"
689 )
690 lacros_version = refs[0].revision
691 uprev_result = uprev_lib.uprev_workon_ebuild_to_version(
692 path, lacros_version, chroot, allow_downrev=False
693 )
Julio Hurtadoa994e002021-07-07 17:57:45 +0000694
Alex Klein1699fab2022-09-08 08:46:06 -0600695 if not uprev_result:
696 return result
697
698 result.add_result(lacros_version, uprev_result.changed_files)
Julio Hurtadoa994e002021-07-07 17:57:45 +0000699 return result
700
Julio Hurtadof1befec2021-05-05 21:34:26 +0000701
Alex Klein1699fab2022-09-08 08:46:06 -0600702@uprevs_versioned_package("chromeos-base/chromeos-lacros-parallel")
Julio Hurtado870ed322021-12-03 18:22:40 +0000703def uprev_lacros_in_parallel(
Alex Klein1699fab2022-09-08 08:46:06 -0600704 _build_targets: Optional[List["build_target_lib.BuildTarget"]],
Julio Hurtado870ed322021-12-03 18:22:40 +0000705 refs: List[uprev_lib.GitRef],
Alex Klein1699fab2022-09-08 08:46:06 -0600706 chroot: "chroot_lib.Chroot",
707) -> "uprev_lib.UprevVersionedPackageResult":
708 """Updates lacros ebuilds in parallel with ash-chrome.
Julio Hurtado870ed322021-12-03 18:22:40 +0000709
Alex Kleinfee86da2023-01-20 18:40:06 -0700710 This handler is going to be used temporarily while lacros transitions to
711 being uprevved atomically with ash-chrome. Unlike a standalone lacros uprev,
712 this handler will not need to look at the QA qualified file. Rather, it will
Alex Klein1699fab2022-09-08 08:46:06 -0600713 function identical to ash-chrome using git tags.
Julio Hurtado870ed322021-12-03 18:22:40 +0000714
Alex Klein1699fab2022-09-08 08:46:06 -0600715 See: uprev_versioned_package.
Julio Hurtado870ed322021-12-03 18:22:40 +0000716
Alex Klein1699fab2022-09-08 08:46:06 -0600717 Returns:
Alex Klein348e7692022-10-13 17:03:37 -0600718 UprevVersionedPackageResult: The result.
Alex Klein1699fab2022-09-08 08:46:06 -0600719 """
720 result = uprev_lib.UprevVersionedPackageResult()
721 path = os.path.join(
722 constants.CHROMIUMOS_OVERLAY_DIR, "chromeos-base", "chromeos-lacros"
723 )
724 lacros_version = uprev_lib.get_version_from_refs(refs)
725 uprev_result = uprev_lib.uprev_workon_ebuild_to_version(
726 path, lacros_version, chroot, allow_downrev=False
727 )
Julio Hurtado870ed322021-12-03 18:22:40 +0000728
Alex Klein1699fab2022-09-08 08:46:06 -0600729 if not uprev_result:
730 return result
731
732 result.add_result(lacros_version, uprev_result.changed_files)
Julio Hurtado870ed322021-12-03 18:22:40 +0000733 return result
734
Julio Hurtado870ed322021-12-03 18:22:40 +0000735
Alex Klein1699fab2022-09-08 08:46:06 -0600736@uprevs_versioned_package("app-emulation/parallels-desktop")
Patrick Meiring5897add2020-09-16 16:30:17 +1000737def uprev_parallels_desktop(_build_targets, _refs, chroot):
Alex Klein1699fab2022-09-08 08:46:06 -0600738 """Updates Parallels Desktop ebuild - app-emulation/parallels-desktop.
Patrick Meiring5897add2020-09-16 16:30:17 +1000739
Alex Klein1699fab2022-09-08 08:46:06 -0600740 See: uprev_versioned_package
Patrick Meiring5897add2020-09-16 16:30:17 +1000741
Alex Klein1699fab2022-09-08 08:46:06 -0600742 Returns:
Alex Klein348e7692022-10-13 17:03:37 -0600743 UprevVersionedPackageResult: The result.
Alex Klein1699fab2022-09-08 08:46:06 -0600744 """
745 package = "parallels-desktop"
746 package_path = os.path.join(
747 constants.CHROMEOS_PARTNER_OVERLAY_DIR, "app-emulation", package
748 )
749 version_pin_src_path = _get_version_pin_src_path(package_path)
Patrick Meiring5897add2020-09-16 16:30:17 +1000750
Alex Klein1699fab2022-09-08 08:46:06 -0600751 # Expect a JSON blob like the following:
752 # {
753 # "version": "1.2.3",
754 # "test_image": { "url": "...", "size": 12345678,
755 # "sha256sum": "<32 bytes of hexadecimal>" }
756 # }
Mike Frysinger81a98062023-02-24 15:42:04 -0500757 with open(version_pin_src_path, "r", encoding="utf-8") as f:
Alex Klein1699fab2022-09-08 08:46:06 -0600758 pinned = json.load(f)
Patrick Meiring5897add2020-09-16 16:30:17 +1000759
Alex Klein1699fab2022-09-08 08:46:06 -0600760 if "version" not in pinned or "test_image" not in pinned:
761 raise UprevError(
Trent Aptedb18e36f2023-05-10 15:06:38 +1000762 "VERSION-PIN for %s missing version and/or test_image field"
763 % package
Alex Klein1699fab2022-09-08 08:46:06 -0600764 )
Patrick Meiring5897add2020-09-16 16:30:17 +1000765
Alex Klein1699fab2022-09-08 08:46:06 -0600766 version = pinned["version"]
767 if not isinstance(version, str):
768 raise UprevError("version in VERSION-PIN for %s not a string" % package)
Patrick Meiring5897add2020-09-16 16:30:17 +1000769
Alex Klein1699fab2022-09-08 08:46:06 -0600770 # Update the ebuild.
771 result = uprev_lib.uprev_ebuild_from_pin(package_path, version, chroot)
Patrick Meiring5897add2020-09-16 16:30:17 +1000772
Alex Klein1699fab2022-09-08 08:46:06 -0600773 # Update the VM image used for testing.
774 test_image_path = (
Dmitry Torokhov257eba12023-05-30 13:42:48 -0700775 "src/go.chromium.org/tast-tests-private/crosint/"
Alex Klein1699fab2022-09-08 08:46:06 -0600776 "local/bundles/crosint/pita/data/"
777 "pluginvm_image.zip.external"
778 )
779 test_image_src_path = os.path.join(constants.SOURCE_ROOT, test_image_path)
Mike Frysinger81a98062023-02-24 15:42:04 -0500780 with open(test_image_src_path, "w", encoding="utf-8") as f:
Alex Klein1699fab2022-09-08 08:46:06 -0600781 json.dump(pinned["test_image"], f, indent=2)
782 result.add_result(version, [test_image_src_path])
Patrick Meiring5897add2020-09-16 16:30:17 +1000783
Alex Klein1699fab2022-09-08 08:46:06 -0600784 return result
Trent Beginaf51f1b2020-03-09 17:35:31 -0600785
786
Alex Klein1699fab2022-09-08 08:46:06 -0600787@uprevs_versioned_package("chromeos-base/chromeos-dtc-vm")
Trent Beginaf51f1b2020-03-09 17:35:31 -0600788def uprev_sludge(_build_targets, _refs, chroot):
Alex Klein1699fab2022-09-08 08:46:06 -0600789 """Updates sludge VM - chromeos-base/chromeos-dtc-vm.
Trent Begin315d9d92019-12-03 21:55:53 -0700790
Alex Klein1699fab2022-09-08 08:46:06 -0600791 See: uprev_versioned_package.
792 """
793 package = "chromeos-dtc-vm"
794 package_path = os.path.join(
795 "src",
796 "private-overlays",
797 "project-wilco-private",
798 "chromeos-base",
799 package,
800 )
801 version_pin_src_path = _get_version_pin_src_path(package_path)
802 version_no_rev = osutils.ReadFile(version_pin_src_path).strip()
Trent Begin315d9d92019-12-03 21:55:53 -0700803
Alex Klein1699fab2022-09-08 08:46:06 -0600804 return uprev_lib.uprev_ebuild_from_pin(package_path, version_no_rev, chroot)
Trent Begin315d9d92019-12-03 21:55:53 -0700805
806
Alex Klein1699fab2022-09-08 08:46:06 -0600807@uprevs_versioned_package("chromeos-base/borealis-dlc")
David Riley8513c1f2021-10-14 17:07:41 -0700808def uprev_borealis_dlc(_build_targets, _refs, chroot):
Alex Klein1699fab2022-09-08 08:46:06 -0600809 """Updates shared borealis-dlc ebuild - chromeos-base/borealis-dlc.
David Riley8513c1f2021-10-14 17:07:41 -0700810
Alex Klein1699fab2022-09-08 08:46:06 -0600811 See: uprev_versioned_package.
812 """
813 package_path = os.path.join(
814 "src",
815 "private-overlays",
816 "chromeos-partner-overlay",
817 "chromeos-base",
818 "borealis-dlc",
819 )
David Riley8513c1f2021-10-14 17:07:41 -0700820
Alex Klein1699fab2022-09-08 08:46:06 -0600821 version_pin_src_path = _get_version_pin_src_path(package_path)
822 version_no_rev = osutils.ReadFile(version_pin_src_path).strip()
David Riley8513c1f2021-10-14 17:07:41 -0700823
Alex Klein1699fab2022-09-08 08:46:06 -0600824 return uprev_lib.uprev_ebuild_from_pin(package_path, version_no_rev, chroot)
David Riley8513c1f2021-10-14 17:07:41 -0700825
826
Po-Hsien Wang92fb1e52023-04-27 11:35:04 -0700827@uprevs_versioned_package("chromeos-base/borealis-dlc-nvidia")
828def uprev_borealis_dlc_nvidia(_build_targets, _refs, chroot):
Trent Apted380d1c62023-05-16 09:19:31 +1000829 """Updates shared chromeos-base/borealis-dlc-nvidia ebuild.
Po-Hsien Wang92fb1e52023-04-27 11:35:04 -0700830
831 See: uprev_versioned_package.
832 """
833 package_path = os.path.join(
834 "src",
835 "private-overlays",
836 "chromeos-partner-overlay",
837 "chromeos-base",
838 "borealis-dlc-nvidia",
839 )
840
841 version_pin_src_path = _get_version_pin_src_path(package_path)
842 version_no_rev = osutils.ReadFile(version_pin_src_path).strip()
843
844 return uprev_lib.uprev_ebuild_from_pin(package_path, version_no_rev, chroot)
845
846
Syed Faaiz Hussainef29cf82023-06-06 22:14:07 -0700847@uprevs_versioned_package("chromeos-base/borealis-dlc-chroot")
848def uprev_borealis_dlc_chroot(_build_targets, _refs, chroot):
849 """Updates shared borealis-dlc-chroot ebuild - chromeos-base/borealis-dlc-chroot.
850
851 See: uprev_versioned_package.
852 """
853 package_path = os.path.join(
854 "src",
855 "private-overlays",
856 "chromeos-partner-overlay",
857 "chromeos-base",
858 "borealis-dlc-chroot",
859 )
860
861 version_pin_src_path = _get_version_pin_src_path(package_path)
862 version_no_rev = osutils.ReadFile(version_pin_src_path).strip()
863
864 return uprev_lib.uprev_ebuild_from_pin(package_path, version_no_rev, chroot)
865
866
Patrick Meiring5897add2020-09-16 16:30:17 +1000867def _get_version_pin_src_path(package_path):
Alex Klein1699fab2022-09-08 08:46:06 -0600868 """Returns the path to the VERSION-PIN file for the given package."""
869 return os.path.join(constants.SOURCE_ROOT, package_path, "VERSION-PIN")
Patrick Meiring5897add2020-09-16 16:30:17 +1000870
871
Alex Klein87531182019-08-12 15:23:37 -0600872@uprevs_versioned_package(constants.CHROME_CP)
Alex Klein4e839252022-01-06 13:29:18 -0700873def uprev_chrome_from_ref(build_targets, refs, _chroot):
Alex Klein1699fab2022-09-08 08:46:06 -0600874 """Uprev chrome and its related packages.
Alex Klein87531182019-08-12 15:23:37 -0600875
Alex Klein1699fab2022-09-08 08:46:06 -0600876 See: uprev_versioned_package.
877 """
Alex Kleinfee86da2023-01-20 18:40:06 -0700878 # Determine the version from the refs (tags), i.e. the chrome versions are
879 # the tag names.
Alex Klein1699fab2022-09-08 08:46:06 -0600880 chrome_version = uprev_lib.get_version_from_refs(refs)
881 logging.debug("Chrome version determined from refs: %s", chrome_version)
Alex Klein87531182019-08-12 15:23:37 -0600882
Alex Klein1699fab2022-09-08 08:46:06 -0600883 return uprev_chrome(chrome_version, build_targets, None)
Alex Kleinf69bd802021-06-22 15:43:49 -0600884
885
Alex Klein9ce3f682021-06-23 15:06:44 -0600886def revbump_chrome(
Alex Klein1699fab2022-09-08 08:46:06 -0600887 build_targets: List["build_target_lib.BuildTarget"] = None,
888 chroot: Optional["chroot_lib.Chroot"] = None,
Alex Klein9ce3f682021-06-23 15:06:44 -0600889) -> uprev_lib.UprevVersionedPackageResult:
Alex Klein1699fab2022-09-08 08:46:06 -0600890 """Attempt to revbump chrome.
Alex Kleinf69bd802021-06-22 15:43:49 -0600891
Alex Klein1699fab2022-09-08 08:46:06 -0600892 Revbumps are done by executing an uprev using the current stable version.
893 E.g. if chrome is on 1.2.3.4 and has a 1.2.3.4_rc-r2.ebuild, performing an
894 uprev on version 1.2.3.4 when there are applicable changes (e.g. to the 9999
895 ebuild) will result in a revbump to 1.2.3.4_rc-r3.ebuild.
896 """
897 chrome_version = uprev_lib.get_stable_chrome_version()
898 return uprev_chrome(chrome_version, build_targets, chroot)
Alex Kleinf69bd802021-06-22 15:43:49 -0600899
900
Alex Klein9ce3f682021-06-23 15:06:44 -0600901def uprev_chrome(
Alex Klein16ea1b32021-10-01 15:48:50 -0600902 chrome_version: str,
Alex Klein1699fab2022-09-08 08:46:06 -0600903 build_targets: Optional[List["build_target_lib.BuildTarget"]],
904 chroot: Optional["chroot_lib.Chroot"],
Alex Klein9ce3f682021-06-23 15:06:44 -0600905) -> uprev_lib.UprevVersionedPackageResult:
Alex Klein1699fab2022-09-08 08:46:06 -0600906 """Attempt to uprev chrome and its related packages to the given version."""
907 uprev_manager = uprev_lib.UprevChromeManager(
908 chrome_version, build_targets=build_targets, chroot=chroot
909 )
910 result = uprev_lib.UprevVersionedPackageResult()
911 # TODO(crbug.com/1080429): Handle all possible outcomes of a Chrome uprev
912 # attempt. The expected behavior is documented in the following table:
913 #
914 # Outcome of Chrome uprev attempt:
915 # NEWER_VERSION_EXISTS:
916 # Do nothing.
917 # SAME_VERSION_EXISTS or REVISION_BUMP:
918 # Uprev followers
919 # Assert not VERSION_BUMP (any other outcome is fine)
920 # VERSION_BUMP or NEW_EBUILD_CREATED:
921 # Uprev followers
922 # Assert that Chrome & followers are at same package version
Alex Klein0b2ec2d2021-06-23 15:56:45 -0600923
Alex Klein1699fab2022-09-08 08:46:06 -0600924 # Start with chrome itself so we can proceed accordingly.
925 chrome_result = uprev_manager.uprev(constants.CHROME_CP)
926 if chrome_result.newer_version_exists:
927 # Cannot use the given version (newer version already exists).
928 return result
929
930 # Also uprev related packages.
931 for package in constants.OTHER_CHROME_PACKAGES:
932 follower_result = uprev_manager.uprev(package)
933 if chrome_result.stable_version and follower_result.version_bump:
934 logging.warning(
935 "%s had a version bump, but no more than a revision bump "
936 "should have been possible.",
937 package,
938 )
939
940 if uprev_manager.modified_ebuilds:
941 # Record changes when we have them.
942 return result.add_result(chrome_version, uprev_manager.modified_ebuilds)
943
David Burger37f48672019-09-18 17:07:56 -0600944 return result
Alex Klein87531182019-08-12 15:23:37 -0600945
Alex Klein87531182019-08-12 15:23:37 -0600946
Alex Klein1699fab2022-09-08 08:46:06 -0600947def _get_latest_version_from_refs(
948 refs_prefix: str, refs: List[uprev_lib.GitRef]
949) -> str:
950 """Get the latest version from refs
Alex Klein0b2ec2d2021-06-23 15:56:45 -0600951
Alex Klein1699fab2022-09-08 08:46:06 -0600952 Versions are compared using |distutils.version.LooseVersion| and
953 the latest version is returned.
Alex Klein87531182019-08-12 15:23:37 -0600954
Alex Klein1699fab2022-09-08 08:46:06 -0600955 Args:
Alex Klein348e7692022-10-13 17:03:37 -0600956 refs_prefix: The refs prefix of the tag format.
957 refs: The tags to parse for the latest version.
Alex Klein87531182019-08-12 15:23:37 -0600958
Alex Klein1699fab2022-09-08 08:46:06 -0600959 Returns:
Alex Klein348e7692022-10-13 17:03:37 -0600960 The latest version to use as string.
Alex Klein1699fab2022-09-08 08:46:06 -0600961 """
962 valid_refs = []
963 for gitiles in refs:
964 if gitiles.ref.startswith(refs_prefix):
965 valid_refs.append(gitiles.ref)
Ben Reiche779cf42020-12-15 03:21:31 +0000966
Alex Klein1699fab2022-09-08 08:46:06 -0600967 if not valid_refs:
968 return None
Ben Reiche779cf42020-12-15 03:21:31 +0000969
Alex Klein1699fab2022-09-08 08:46:06 -0600970 # Sort by version and take the latest version.
971 target_version_ref = sorted(valid_refs, key=LooseVersion, reverse=True)[0]
972 return target_version_ref.replace(refs_prefix, "")
Harvey Yang9c61e9c2021-03-02 16:32:43 +0800973
974
Matthias Kaehlckebf7d1772021-11-04 16:01:36 -0700975def _generate_platform_c_files(
976 replication_config: replication_config_pb2.ReplicationConfig,
Alex Klein1699fab2022-09-08 08:46:06 -0600977 chroot: "chroot_lib.Chroot",
978) -> List[str]:
979 """Generates platform C files from a platform JSON payload.
Andrew Lamb9563a152019-12-04 11:42:18 -0700980
Alex Klein1699fab2022-09-08 08:46:06 -0600981 Args:
Alex Klein348e7692022-10-13 17:03:37 -0600982 replication_config: A ReplicationConfig that has already been run. If it
983 produced a build_config.json file, that file will be used to
984 generate platform C files. Otherwise, nothing will be generated.
985 chroot: The chroot to use to generate.
Andrew Lamb9563a152019-12-04 11:42:18 -0700986
Alex Klein1699fab2022-09-08 08:46:06 -0600987 Returns:
Alex Klein348e7692022-10-13 17:03:37 -0600988 A list of generated files.
Alex Klein1699fab2022-09-08 08:46:06 -0600989 """
990 # Generate the platform C files from the build config. Note that it would be
991 # more intuitive to generate the platform C files from the platform config;
Alex Kleinfee86da2023-01-20 18:40:06 -0700992 # however, cros_config_schema does not allow this, because the platform
993 # config payload is not always valid input. For example, if a property is
994 # both 'required' and 'build-only', it will fail schema validation. Thus,
995 # use the build config, and use '-f' to filter.
Alex Klein1699fab2022-09-08 08:46:06 -0600996 build_config_path = [
997 rule.destination_path
998 for rule in replication_config.file_replication_rules
999 if rule.destination_path.endswith("build_config.json")
1000 ]
Andrew Lamb9563a152019-12-04 11:42:18 -07001001
Alex Klein1699fab2022-09-08 08:46:06 -06001002 if not build_config_path:
1003 logging.info(
1004 "No build_config.json found, will not generate platform C files. "
1005 "Replication config: %s",
1006 replication_config,
1007 )
1008 return []
Andrew Lamb9563a152019-12-04 11:42:18 -07001009
Alex Klein1699fab2022-09-08 08:46:06 -06001010 if len(build_config_path) > 1:
1011 raise ValueError(
1012 "Expected at most one build_config.json destination path. "
1013 "Replication config: %s" % replication_config
1014 )
Andrew Lamb9563a152019-12-04 11:42:18 -07001015
Alex Klein1699fab2022-09-08 08:46:06 -06001016 build_config_path = build_config_path[0]
Andrew Lamb9563a152019-12-04 11:42:18 -07001017
Alex Klein1699fab2022-09-08 08:46:06 -06001018 # Paths to the build_config.json and dir to output C files to, in the
1019 # chroot.
1020 build_config_chroot_path = os.path.join(
1021 constants.CHROOT_SOURCE_ROOT, build_config_path
1022 )
1023 generated_output_chroot_dir = os.path.join(
1024 constants.CHROOT_SOURCE_ROOT, os.path.dirname(build_config_path)
1025 )
Andrew Lamb9563a152019-12-04 11:42:18 -07001026
Alex Klein1699fab2022-09-08 08:46:06 -06001027 command = [
1028 "cros_config_schema",
1029 "-m",
1030 build_config_chroot_path,
1031 "-g",
1032 generated_output_chroot_dir,
1033 "-f",
1034 '"TRUE"',
1035 ]
Andrew Lamb9563a152019-12-04 11:42:18 -07001036
Alex Klein1699fab2022-09-08 08:46:06 -06001037 cros_build_lib.run(
1038 command, enter_chroot=True, chroot_args=chroot.get_enter_args()
1039 )
Andrew Lamb9563a152019-12-04 11:42:18 -07001040
Alex Klein1699fab2022-09-08 08:46:06 -06001041 # A relative (to the source root) path to the generated C files.
1042 generated_output_dir = os.path.dirname(build_config_path)
1043 generated_files = []
1044 expected_c_files = ["config.c", "ec_config.c", "ec_config.h"]
1045 for f in expected_c_files:
1046 if os.path.exists(
1047 os.path.join(constants.SOURCE_ROOT, generated_output_dir, f)
1048 ):
1049 generated_files.append(os.path.join(generated_output_dir, f))
Andrew Lamb9563a152019-12-04 11:42:18 -07001050
Alex Klein1699fab2022-09-08 08:46:06 -06001051 if len(expected_c_files) != len(generated_files):
1052 raise GeneratedCrosConfigFilesError(expected_c_files, generated_files)
Andrew Lamb9563a152019-12-04 11:42:18 -07001053
Alex Klein1699fab2022-09-08 08:46:06 -06001054 return generated_files
Andrew Lamb9563a152019-12-04 11:42:18 -07001055
1056
Matthias Kaehlckebf7d1772021-11-04 16:01:36 -07001057def _get_private_overlay_package_root(ref: uprev_lib.GitRef, package: str):
Alex Klein1699fab2022-09-08 08:46:06 -06001058 """Returns the absolute path to the root of a given private overlay.
Andrew Lambe836f222019-12-09 12:27:38 -07001059
Alex Klein1699fab2022-09-08 08:46:06 -06001060 Args:
Alex Klein348e7692022-10-13 17:03:37 -06001061 ref: GitRef for the private overlay.
1062 package: Path to the package in the overlay.
Alex Klein1699fab2022-09-08 08:46:06 -06001063 """
1064 # There might be a cleaner way to map from package -> path within the source
1065 # tree. For now, just use string patterns.
1066 private_overlay_ref_pattern = (
1067 r"/chromeos\/overlays\/overlay-([\w-]+)-private"
1068 )
1069 match = re.match(private_overlay_ref_pattern, ref.path)
1070 if not match:
1071 raise ValueError(
1072 "ref.path must match the pattern: %s. Actual ref: %s"
1073 % (private_overlay_ref_pattern, ref)
1074 )
Andrew Lambe836f222019-12-09 12:27:38 -07001075
Alex Klein1699fab2022-09-08 08:46:06 -06001076 overlay = match.group(1)
Andrew Lambe836f222019-12-09 12:27:38 -07001077
Alex Klein1699fab2022-09-08 08:46:06 -06001078 return os.path.join(
1079 constants.SOURCE_ROOT,
1080 "src/private-overlays/overlay-%s-private" % overlay,
1081 package,
1082 )
Andrew Lambe836f222019-12-09 12:27:38 -07001083
1084
Alex Klein1699fab2022-09-08 08:46:06 -06001085@uprevs_versioned_package("chromeos-base/chromeos-config-bsp")
Andrew Lambea9a8a22019-12-12 14:03:43 -07001086def replicate_private_config(_build_targets, refs, chroot):
Alex Kleinfee86da2023-01-20 18:40:06 -07001087 """Replicate private cros_config change to the corresponding public config.
Andrew Lamb2bde9e42019-11-04 13:24:09 -07001088
Alex Klein1699fab2022-09-08 08:46:06 -06001089 See uprev_versioned_package for args
1090 """
1091 package = "chromeos-base/chromeos-config-bsp"
Andrew Lambea9a8a22019-12-12 14:03:43 -07001092
Alex Klein1699fab2022-09-08 08:46:06 -06001093 if len(refs) != 1:
1094 raise ValueError("Expected exactly one ref, actual %s" % refs)
Andrew Lamb2bde9e42019-11-04 13:24:09 -07001095
Alex Klein1699fab2022-09-08 08:46:06 -06001096 # Expect a replication_config.jsonpb in the package root.
1097 package_root = _get_private_overlay_package_root(refs[0], package)
1098 replication_config_path = os.path.join(
1099 package_root, "replication_config.jsonpb"
1100 )
Andrew Lamb2bde9e42019-11-04 13:24:09 -07001101
Alex Klein1699fab2022-09-08 08:46:06 -06001102 try:
1103 replication_config = json_format.Parse(
1104 osutils.ReadFile(replication_config_path),
1105 replication_config_pb2.ReplicationConfig(),
1106 )
1107 except IOError:
1108 raise ValueError(
1109 "Expected ReplicationConfig missing at %s" % replication_config_path
1110 )
Andrew Lamb2bde9e42019-11-04 13:24:09 -07001111
Alex Klein1699fab2022-09-08 08:46:06 -06001112 replication_lib.Replicate(replication_config)
Andrew Lamb2bde9e42019-11-04 13:24:09 -07001113
Alex Klein1699fab2022-09-08 08:46:06 -06001114 modified_files = [
1115 rule.destination_path
1116 for rule in replication_config.file_replication_rules
1117 ]
Andrew Lamb2bde9e42019-11-04 13:24:09 -07001118
Alex Kleinfee86da2023-01-20 18:40:06 -07001119 # The generated platform C files are not easily filtered by replication
1120 # rules, i.e. JSON / proto filtering can be described by a FieldMask,
1121 # arbitrary C files cannot. Therefore, replicate and filter the JSON
1122 # payloads, and then generate filtered C files from the JSON payload.
Alex Klein1699fab2022-09-08 08:46:06 -06001123 modified_files.extend(
1124 _generate_platform_c_files(replication_config, chroot)
1125 )
Andrew Lamb2bde9e42019-11-04 13:24:09 -07001126
Alex Klein1699fab2022-09-08 08:46:06 -06001127 # Use the private repo's commit hash as the new version.
1128 new_private_version = refs[0].revision
Andrew Lamb2bde9e42019-11-04 13:24:09 -07001129
Alex Klein1699fab2022-09-08 08:46:06 -06001130 # modified_files should contain only relative paths at this point, but the
1131 # returned UprevVersionedPackageResult must contain only absolute paths.
1132 for i, modified_file in enumerate(modified_files):
1133 assert not os.path.isabs(modified_file)
1134 modified_files[i] = os.path.join(constants.SOURCE_ROOT, modified_file)
Andrew Lamb988f4da2019-12-10 10:16:43 -07001135
Alex Klein1699fab2022-09-08 08:46:06 -06001136 return uprev_lib.UprevVersionedPackageResult().add_result(
1137 new_private_version, modified_files
1138 )
Andrew Lamb2bde9e42019-11-04 13:24:09 -07001139
1140
Alex Klein1699fab2022-09-08 08:46:06 -06001141@uprevs_versioned_package("chromeos-base/crosvm")
Dennis Kempinef05f2b2021-09-08 16:36:49 -07001142def uprev_crosvm(_build_targets, refs, _chroot):
Alex Klein1699fab2022-09-08 08:46:06 -06001143 """Updates crosvm ebuilds to latest revision
Dennis Kempinef05f2b2021-09-08 16:36:49 -07001144
Alex Klein1699fab2022-09-08 08:46:06 -06001145 crosvm is not versioned. We are updating to the latest commit on the main
1146 branch.
Dennis Kempinef05f2b2021-09-08 16:36:49 -07001147
Alex Klein1699fab2022-09-08 08:46:06 -06001148 See: uprev_versioned_package.
Dennis Kempinef05f2b2021-09-08 16:36:49 -07001149
Alex Klein1699fab2022-09-08 08:46:06 -06001150 Returns:
Alex Klein348e7692022-10-13 17:03:37 -06001151 UprevVersionedPackageResult: The result of updating crosvm ebuilds.
Alex Klein1699fab2022-09-08 08:46:06 -06001152 """
1153 overlay = os.path.join(
1154 constants.SOURCE_ROOT, constants.CHROMIUMOS_OVERLAY_DIR
1155 )
1156 repo_path = os.path.join(constants.SOURCE_ROOT, "src", "crosvm")
1157 manifest = git.ManifestCheckout.Cached(repo_path)
Dennis Kempinef05f2b2021-09-08 16:36:49 -07001158
Alex Klein1699fab2022-09-08 08:46:06 -06001159 uprev_manager = uprev_lib.UprevOverlayManager([overlay], manifest)
1160 uprev_manager.uprev(
1161 package_list=[
1162 "chromeos-base/crosvm",
1163 "dev-rust/assertions",
1164 "dev-rust/cros_async",
1165 "dev-rust/cros_fuzz",
1166 "dev-rust/data_model",
1167 "dev-rust/enumn",
1168 "dev-rust/io_uring",
1169 "dev-rust/p9",
1170 "dev-rust/sync",
1171 "dev-rust/sys_util",
1172 "dev-rust/tempfile",
1173 "media-sound/audio_streams",
1174 ],
1175 force=True,
1176 )
Dennis Kempinef05f2b2021-09-08 16:36:49 -07001177
Alex Klein1699fab2022-09-08 08:46:06 -06001178 updated_files = uprev_manager.modified_ebuilds
1179 result = uprev_lib.UprevVersionedPackageResult()
1180 result.add_result(refs[0].revision, updated_files)
1181 return result
Dennis Kempinef05f2b2021-09-08 16:36:49 -07001182
1183
Yi Choua4854ac2022-11-14 10:54:24 +08001184@uprevs_versioned_package("chromeos-base/ti50-emulator")
1185def uprev_ti50_emulator(_build_targets, refs, _chroot):
1186 """Updates ti50-emulator ebuilds to latest revision
1187
1188 ti50-emulator is not versioned. We are updating to the latest commit on the
1189 main branch.
1190
1191 See: uprev_versioned_package.
1192
1193 Returns:
1194 UprevVersionedPackageResult: The result of updating ti50-emulator
Trent Aptedb18e36f2023-05-10 15:06:38 +10001195 ebuild.
Yi Choua4854ac2022-11-14 10:54:24 +08001196 """
1197 overlay = os.path.join(
1198 constants.SOURCE_ROOT, constants.CHROMEOS_OVERLAY_DIR
1199 )
1200
1201 # The ti50-emulator will touch multiple repos.
1202 manifest = git.ManifestCheckout.Cached(constants.SOURCE_ROOT)
1203
1204 uprev_manager = uprev_lib.UprevOverlayManager([overlay], manifest)
1205 uprev_manager.uprev(
1206 package_list=["chromeos-base/ti50-emulator"],
1207 force=True,
1208 )
1209
1210 updated_files = uprev_manager.modified_ebuilds
1211 result = uprev_lib.UprevVersionedPackageResult()
1212 result.add_result(refs[-1].revision, updated_files)
1213 return result
1214
1215
Jeremy Bettisaf96afb2023-01-11 16:09:58 -07001216@uprevs_versioned_package("chromeos-base/ec-devutils")
Jeremy Bettis0186d252023-01-19 14:47:46 -07001217def uprev_ecdevutils(_build_targets, refs, _chroot):
1218 """Updates ec-devutils ebuilds to latest revision
1219
Alex Kleinfee86da2023-01-20 18:40:06 -07001220 ec-devutils is not versioned. We are updating to the latest commit on the
1221 main branch.
Jeremy Bettis0186d252023-01-19 14:47:46 -07001222
1223 See: uprev_versioned_package.
1224
1225 Returns:
1226 UprevVersionedPackageResult: The result of updating ec-devutils ebuilds.
1227 """
1228 overlay = os.path.join(
1229 constants.SOURCE_ROOT, constants.CHROMIUMOS_OVERLAY_DIR
1230 )
1231 repo_path = os.path.join(constants.SOURCE_ROOT, "src", "platform", "ec")
1232 manifest = git.ManifestCheckout.Cached(repo_path)
1233
1234 uprev_manager = uprev_lib.UprevOverlayManager([overlay], manifest)
1235 uprev_manager.uprev(
1236 package_list=[
1237 "chromeos-base/ec-devutils",
1238 ],
1239 force=True,
1240 )
1241
1242 updated_files = uprev_manager.modified_ebuilds
1243 result = uprev_lib.UprevVersionedPackageResult()
1244 result.add_result(refs[0].revision, updated_files)
1245 return result
1246
1247
Jeremy Bettisaf96afb2023-01-11 16:09:58 -07001248@uprevs_versioned_package("chromeos-base/ec-utils")
Jeremy Bettisaf96afb2023-01-11 16:09:58 -07001249def uprev_ecutils(_build_targets, refs, _chroot):
1250 """Updates ec-utils ebuilds to latest revision
1251
1252 ec-utils is not versioned. We are updating to the latest commit on the main
1253 branch.
1254
1255 See: uprev_versioned_package.
1256
1257 Returns:
1258 UprevVersionedPackageResult: The result of updating ec-utils ebuilds.
1259 """
1260 overlay = os.path.join(
1261 constants.SOURCE_ROOT, constants.CHROMIUMOS_OVERLAY_DIR
1262 )
1263 repo_path = os.path.join(constants.SOURCE_ROOT, "src", "platform", "ec")
1264 manifest = git.ManifestCheckout.Cached(repo_path)
1265
1266 uprev_manager = uprev_lib.UprevOverlayManager([overlay], manifest)
1267 uprev_manager.uprev(
1268 package_list=[
Jeremy Bettisaf96afb2023-01-11 16:09:58 -07001269 "chromeos-base/ec-utils",
Jeremy Bettis0186d252023-01-19 14:47:46 -07001270 ],
1271 force=True,
1272 )
1273
1274 updated_files = uprev_manager.modified_ebuilds
1275 result = uprev_lib.UprevVersionedPackageResult()
1276 result.add_result(refs[0].revision, updated_files)
1277 return result
1278
1279
1280@uprevs_versioned_package("chromeos-base/ec-utils-test")
1281def uprev_ecutilstest(_build_targets, refs, _chroot):
1282 """Updates ec-utils-test ebuilds to latest revision
1283
Alex Kleinfee86da2023-01-20 18:40:06 -07001284 ec-utils-test is not versioned. We are updating to the latest commit on the
1285 main branch.
Jeremy Bettis0186d252023-01-19 14:47:46 -07001286
1287 See: uprev_versioned_package.
1288
1289 Returns:
Alex Kleinfee86da2023-01-20 18:40:06 -07001290 UprevVersionedPackageResult: The result of updating ec-utils-test
Trent Aptedb18e36f2023-05-10 15:06:38 +10001291 ebuilds.
Jeremy Bettis0186d252023-01-19 14:47:46 -07001292 """
1293 overlay = os.path.join(
1294 constants.SOURCE_ROOT, constants.CHROMIUMOS_OVERLAY_DIR
1295 )
1296 repo_path = os.path.join(constants.SOURCE_ROOT, "src", "platform", "ec")
1297 manifest = git.ManifestCheckout.Cached(repo_path)
1298
1299 uprev_manager = uprev_lib.UprevOverlayManager([overlay], manifest)
1300 uprev_manager.uprev(
1301 package_list=[
Jeremy Bettisaf96afb2023-01-11 16:09:58 -07001302 "chromeos-base/ec-utils-test",
1303 ],
1304 force=True,
1305 )
1306
1307 updated_files = uprev_manager.modified_ebuilds
1308 result = uprev_lib.UprevVersionedPackageResult()
1309 result.add_result(refs[0].revision, updated_files)
1310 return result
1311
1312
Alex Klein5caab872021-09-10 11:44:37 -06001313def get_best_visible(
Alex Klein1699fab2022-09-08 08:46:06 -06001314 atom: str, build_target: Optional["build_target_lib.BuildTarget"] = None
Alex Klein5caab872021-09-10 11:44:37 -06001315) -> package_info.PackageInfo:
Alex Klein1699fab2022-09-08 08:46:06 -06001316 """Returns the best visible CPV for the given atom.
Alex Kleinbbef2b32019-08-27 10:38:50 -06001317
Alex Klein1699fab2022-09-08 08:46:06 -06001318 Args:
Alex Klein348e7692022-10-13 17:03:37 -06001319 atom: The atom to look up.
1320 build_target: The build target whose sysroot should be searched, or the
1321 SDK if not provided.
Alex Kleinad6b48a2020-01-08 16:57:41 -07001322
Alex Klein1699fab2022-09-08 08:46:06 -06001323 Returns:
Alex Klein348e7692022-10-13 17:03:37 -06001324 The best visible package, or None if none are visible.
Alex Klein1699fab2022-09-08 08:46:06 -06001325 """
1326 assert atom
Alex Kleinbbef2b32019-08-27 10:38:50 -06001327
Alex Klein1699fab2022-09-08 08:46:06 -06001328 return portage_util.PortageqBestVisible(
1329 atom,
1330 board=build_target.name if build_target else None,
1331 sysroot=build_target.root if build_target else None,
1332 )
Alex Kleinda39c6d2019-09-16 14:36:36 -06001333
1334
Matthias Kaehlckebf7d1772021-11-04 16:01:36 -07001335def has_prebuilt(
1336 atom: str,
Alex Klein1699fab2022-09-08 08:46:06 -06001337 build_target: "build_target_lib.BuildTarget" = None,
1338 useflags: Union[Iterable[str], str] = None,
1339) -> bool:
1340 """Check if a prebuilt exists.
Alex Kleinda39c6d2019-09-16 14:36:36 -06001341
Alex Klein1699fab2022-09-08 08:46:06 -06001342 Args:
Alex Klein348e7692022-10-13 17:03:37 -06001343 atom: The package whose prebuilt is being queried.
1344 build_target: The build target whose sysroot should be searched, or the
1345 SDK if not provided.
1346 useflags: Any additional USE flags that should be set. May be a string
1347 of properly formatted USE flags, or an iterable of individual flags.
Alex Kleinad6b48a2020-01-08 16:57:41 -07001348
Alex Klein1699fab2022-09-08 08:46:06 -06001349 Returns:
Alex Klein348e7692022-10-13 17:03:37 -06001350 True if there is an available prebuilt, False otherwise.
Alex Klein1699fab2022-09-08 08:46:06 -06001351 """
1352 assert atom
Alex Kleinda39c6d2019-09-16 14:36:36 -06001353
Alex Klein1699fab2022-09-08 08:46:06 -06001354 board = build_target.name if build_target else None
1355 extra_env = None
1356 if useflags:
1357 new_flags = useflags
1358 if not isinstance(useflags, str):
1359 new_flags = " ".join(useflags)
Alex Klein149fd3b2019-12-16 16:01:05 -07001360
Alex Klein1699fab2022-09-08 08:46:06 -06001361 existing = os.environ.get("USE", "")
1362 final_flags = "%s %s" % (existing, new_flags)
1363 extra_env = {"USE": final_flags.strip()}
1364 return portage_util.HasPrebuilt(atom, board=board, extra_env=extra_env)
Alex Klein36b117f2019-09-30 15:13:46 -06001365
1366
David Burger0f9dd4e2019-10-08 12:33:42 -06001367def builds(atom, build_target, packages=None):
Alex Klein1699fab2022-09-08 08:46:06 -06001368 """Check if |build_target| builds |atom| (has it in its depgraph)."""
1369 cros_build_lib.AssertInsideChroot()
Alex Klein36b117f2019-09-30 15:13:46 -06001370
Alex Klein1699fab2022-09-08 08:46:06 -06001371 pkgs = tuple(packages) if packages else None
1372 # TODO(crbug/1081828): Receive and use sysroot.
1373 graph, _sdk_graph = dependency.GetBuildDependency(
1374 build_target.root, build_target.name, pkgs
1375 )
1376 return any(atom in package for package in graph["package_deps"])
Michael Mortensenb70e8a82019-10-10 18:43:41 -06001377
1378
Alex Klein6becabc2020-09-11 14:03:05 -06001379def needs_chrome_source(
Alex Klein1699fab2022-09-08 08:46:06 -06001380 build_target: "build_target_lib.BuildTarget",
Alex Klein6becabc2020-09-11 14:03:05 -06001381 compile_source=False,
1382 packages: Optional[List[package_info.PackageInfo]] = None,
Alex Klein1699fab2022-09-08 08:46:06 -06001383 useflags=None,
1384):
1385 """Check if the chrome source is needed.
Alex Klein6becabc2020-09-11 14:03:05 -06001386
Alex Klein1699fab2022-09-08 08:46:06 -06001387 The chrome source is needed if the build target builds chrome or any of its
1388 follower packages, and can't use a prebuilt for them either because it's not
1389 available, or because we can't use prebuilts because it must build from
1390 source.
1391 """
1392 cros_build_lib.AssertInsideChroot()
Alex Klein6becabc2020-09-11 14:03:05 -06001393
Alex Klein1699fab2022-09-08 08:46:06 -06001394 # Check if it builds chrome and/or a follower package.
1395 graph = depgraph.get_sysroot_dependency_graph(build_target.root, packages)
1396 builds_chrome = constants.CHROME_CP in graph
1397 builds_follower = {
1398 pkg: pkg in graph for pkg in constants.OTHER_CHROME_PACKAGES
1399 }
Alex Klein6becabc2020-09-11 14:03:05 -06001400
Alex Klein1699fab2022-09-08 08:46:06 -06001401 local_uprev = builds_chrome and revbump_chrome([build_target])
Alex Klein9ce3f682021-06-23 15:06:44 -06001402
Alex Kleinfee86da2023-01-20 18:40:06 -07001403 # When we are compiling source set False since we do not use prebuilts. When
1404 # not compiling from source, start with True, i.e. we have every prebuilt
Alex Klein1699fab2022-09-08 08:46:06 -06001405 # we've checked for up to this point.
1406 has_chrome_prebuilt = not compile_source
1407 has_follower_prebuilts = not compile_source
1408 # Save packages that need prebuilts for reporting.
1409 pkgs_needing_prebuilts = []
1410 if compile_source:
1411 # Need everything.
Alex Klein6becabc2020-09-11 14:03:05 -06001412 pkgs_needing_prebuilts.append(constants.CHROME_CP)
Alex Klein1699fab2022-09-08 08:46:06 -06001413 pkgs_needing_prebuilts.extend(
1414 [pkg for pkg, builds_pkg in builds_follower.items() if builds_pkg]
1415 )
1416 else:
1417 # Check chrome itself.
1418 if builds_chrome:
1419 has_chrome_prebuilt = has_prebuilt(
1420 constants.CHROME_CP,
1421 build_target=build_target,
1422 useflags=useflags,
1423 )
1424 if not has_chrome_prebuilt:
1425 pkgs_needing_prebuilts.append(constants.CHROME_CP)
1426 # Check follower packages.
1427 for pkg, builds_pkg in builds_follower.items():
1428 if not builds_pkg:
1429 continue
1430 prebuilt = has_prebuilt(
1431 pkg, build_target=build_target, useflags=useflags
1432 )
1433 has_follower_prebuilts &= prebuilt
1434 if not prebuilt:
1435 pkgs_needing_prebuilts.append(pkg)
Alex Kleinfee86da2023-01-20 18:40:06 -07001436 # Postcondition: has_chrome_prebuilt and has_follower_prebuilts now
1437 # correctly reflect whether we actually have the corresponding prebuilts for
1438 # the build.
Alex Klein6becabc2020-09-11 14:03:05 -06001439
Alex Klein1699fab2022-09-08 08:46:06 -06001440 needs_chrome = builds_chrome and not has_chrome_prebuilt
1441 needs_follower = (
1442 any(builds_follower.values()) and not has_follower_prebuilts
1443 )
Alex Klein6becabc2020-09-11 14:03:05 -06001444
Alex Klein1699fab2022-09-08 08:46:06 -06001445 return NeedsChromeSourceResult(
1446 needs_chrome_source=needs_chrome or needs_follower,
1447 builds_chrome=builds_chrome,
1448 packages=[package_info.parse(p) for p in pkgs_needing_prebuilts],
1449 missing_chrome_prebuilt=not has_chrome_prebuilt,
1450 missing_follower_prebuilt=not has_follower_prebuilts,
1451 local_uprev=local_uprev,
1452 )
Alex Klein6becabc2020-09-11 14:03:05 -06001453
1454
Alex Klein68a28712021-11-08 11:08:30 -07001455class TargetVersions(NamedTuple):
Alex Klein1699fab2022-09-08 08:46:06 -06001456 """Data class for the info that makes up the "target versions"."""
1457
1458 android_version: str
1459 android_branch: str
1460 android_target: str
1461 chrome_version: str
1462 platform_version: str
1463 milestone_version: str
1464 full_version: str
Gilberto Contreras4f2d1452023-01-30 23:22:58 +00001465 lacros_version: str
Alex Klein68a28712021-11-08 11:08:30 -07001466
1467
1468def get_target_versions(
Alex Klein1699fab2022-09-08 08:46:06 -06001469 build_target: "build_target_lib.BuildTarget",
1470 packages: List[package_info.PackageInfo] = None,
Alex Klein68a28712021-11-08 11:08:30 -07001471) -> TargetVersions:
Alex Klein1699fab2022-09-08 08:46:06 -06001472 """Aggregate version info for a few key packages and the OS as a whole."""
1473 # Android version.
1474 android_version = determine_android_version(build_target.name)
1475 logging.info("Found android version: %s", android_version)
1476 # Android branch version.
1477 android_branch = determine_android_branch(build_target.name)
1478 logging.info("Found android branch version: %s", android_branch)
1479 # Android target version.
1480 android_target = determine_android_target(build_target.name)
1481 logging.info("Found android target version: %s", android_target)
Alex Klein68a28712021-11-08 11:08:30 -07001482
Alex Klein1699fab2022-09-08 08:46:06 -06001483 # TODO(crbug/1019770): Investigate cases where builds_chrome is true but
1484 # chrome_version is None.
Alex Klein68a28712021-11-08 11:08:30 -07001485
Alex Klein1699fab2022-09-08 08:46:06 -06001486 builds_chrome = builds(constants.CHROME_CP, build_target, packages=packages)
1487 chrome_version = None
1488 if builds_chrome:
1489 # Chrome version fetch.
Gilberto Contreras4f2d1452023-01-30 23:22:58 +00001490 chrome_version = determine_package_version(
1491 constants.CHROME_CP, build_target
1492 )
Alex Klein1699fab2022-09-08 08:46:06 -06001493 logging.info("Found chrome version: %s", chrome_version)
Alex Klein68a28712021-11-08 11:08:30 -07001494
Gilberto Contreras4f2d1452023-01-30 23:22:58 +00001495 builds_lacros = builds(constants.LACROS_CP, build_target, packages=packages)
1496 lacros_version = None
1497 if builds_lacros:
1498 # LaCrOS version fetch.
1499 lacros_version = determine_package_version(
1500 constants.LACROS_CP, build_target
1501 )
1502 logging.info("Found LaCrOS version: %s", lacros_version)
1503
Alex Klein1699fab2022-09-08 08:46:06 -06001504 # The ChromeOS version info.
1505 platform_version = determine_platform_version()
1506 milestone_version = determine_milestone_version()
1507 full_version = determine_full_version()
Alex Klein68a28712021-11-08 11:08:30 -07001508
Alex Klein1699fab2022-09-08 08:46:06 -06001509 return TargetVersions(
1510 android_version,
1511 android_branch,
1512 android_target,
1513 chrome_version,
1514 platform_version,
1515 milestone_version,
1516 full_version,
Gilberto Contreras4f2d1452023-01-30 23:22:58 +00001517 lacros_version,
Alex Klein1699fab2022-09-08 08:46:06 -06001518 )
Alex Klein68a28712021-11-08 11:08:30 -07001519
1520
Gilberto Contreras4f2d1452023-01-30 23:22:58 +00001521def determine_package_version(
1522 cpv_name: str,
Alex Klein1699fab2022-09-08 08:46:06 -06001523 build_target: "build_target_lib.BuildTarget",
1524) -> Optional[str]:
Gilberto Contreras4f2d1452023-01-30 23:22:58 +00001525 """Returns the current package version for the board (or in buildroot).
Michael Mortensenc2615b72019-10-15 08:12:24 -06001526
Alex Klein1699fab2022-09-08 08:46:06 -06001527 Args:
Gilberto Contreras4f2d1452023-01-30 23:22:58 +00001528 cpv_name: the name of the ebuild CPV
Alex Klein348e7692022-10-13 17:03:37 -06001529 build_target: The board build target.
Alex Kleinad6b48a2020-01-08 16:57:41 -07001530
Alex Klein1699fab2022-09-08 08:46:06 -06001531 Returns:
Gilberto Contreras4f2d1452023-01-30 23:22:58 +00001532 The version of the package, if available.
Alex Klein1699fab2022-09-08 08:46:06 -06001533 """
1534 # TODO(crbug/1019770): Long term we should not need the try/catch here once
1535 # the builds function above only returns True for chrome when
1536 # determine_chrome_version will succeed.
1537 try:
1538 pkg_info = portage_util.PortageqBestVisible(
Gilberto Contreras4f2d1452023-01-30 23:22:58 +00001539 cpv_name, build_target.name, cwd=constants.SOURCE_ROOT
Alex Klein1699fab2022-09-08 08:46:06 -06001540 )
1541 except cros_build_lib.RunCommandError as e:
1542 # Return None because portage failed when trying to determine the chrome
1543 # version.
1544 logging.warning("Caught exception in determine_chrome_package: %s", e)
1545 return None
1546 # Something like 78.0.3877.4_rc -> 78.0.3877.4
1547 return pkg_info.version.partition("_")[0]
Michael Mortensenc2615b72019-10-15 08:12:24 -06001548
1549
Alex Klein68a28712021-11-08 11:08:30 -07001550@functools.lru_cache()
Matthias Kaehlckebf7d1772021-11-04 16:01:36 -07001551def determine_android_package(board: str) -> Optional[str]:
Alex Klein1699fab2022-09-08 08:46:06 -06001552 """Returns the active Android container package in use by the board.
Michael Mortensenb70e8a82019-10-10 18:43:41 -06001553
Alex Klein1699fab2022-09-08 08:46:06 -06001554 Args:
Alex Klein348e7692022-10-13 17:03:37 -06001555 board: The board name this is specific to.
Alex Kleinad6b48a2020-01-08 16:57:41 -07001556
Alex Klein1699fab2022-09-08 08:46:06 -06001557 Returns:
Alex Klein348e7692022-10-13 17:03:37 -06001558 The android package string if there is one.
Alex Klein1699fab2022-09-08 08:46:06 -06001559 """
1560 try:
1561 packages = portage_util.GetPackageDependencies(
1562 "virtual/target-os", board=board
1563 )
1564 except cros_build_lib.RunCommandError as e:
1565 # Return None because a command (likely portage) failed when trying to
1566 # determine the package.
1567 logging.warning("Caught exception in determine_android_package: %s", e)
1568 return None
1569
1570 # We assume there is only one Android package in the depgraph.
1571 for package in packages:
1572 if package.startswith(
1573 "chromeos-base/android-container-"
1574 ) or package.startswith("chromeos-base/android-vm-"):
1575 return package
Michael Mortensene0f4b542019-10-24 15:30:23 -06001576 return None
Michael Mortensenb70e8a82019-10-10 18:43:41 -06001577
1578
Matthias Kaehlckebf7d1772021-11-04 16:01:36 -07001579def determine_android_version(board: str, package: str = None):
Alex Klein1699fab2022-09-08 08:46:06 -06001580 """Determine the current Android version in buildroot now and return it.
Michael Mortensenb70e8a82019-10-10 18:43:41 -06001581
Alex Klein1699fab2022-09-08 08:46:06 -06001582 This uses the typical portage logic to determine which version of Android
1583 is active right now in the buildroot.
Michael Mortensenb70e8a82019-10-10 18:43:41 -06001584
Alex Klein1699fab2022-09-08 08:46:06 -06001585 Args:
Alex Klein348e7692022-10-13 17:03:37 -06001586 board: The board name this is specific to.
1587 package: The Android package, if already computed.
Michael Mortensenb70e8a82019-10-10 18:43:41 -06001588
Alex Klein1699fab2022-09-08 08:46:06 -06001589 Returns:
Alex Klein348e7692022-10-13 17:03:37 -06001590 The Android build ID of the container for the board.
Michael Mortensenb70e8a82019-10-10 18:43:41 -06001591
Alex Klein1699fab2022-09-08 08:46:06 -06001592 Raises:
Alex Klein348e7692022-10-13 17:03:37 -06001593 NoAndroidVersionError: if no unique Android version can be determined.
Alex Klein1699fab2022-09-08 08:46:06 -06001594 """
1595 if not package:
1596 package = determine_android_package(board)
1597 if not package:
1598 return None
Alex Klein7bd88b12023-05-19 15:39:55 -06001599 cpv = package_info.parse(package)
Alex Klein1699fab2022-09-08 08:46:06 -06001600 if not cpv:
1601 raise NoAndroidVersionError(
1602 "Android version could not be determined for %s" % board
1603 )
Alex Klein7bd88b12023-05-19 15:39:55 -06001604 return cpv.version
Michael Mortensenb70e8a82019-10-10 18:43:41 -06001605
Alex Klein7a3a7dd2020-01-08 16:44:38 -07001606
Mike Frysinger8e1c99a2021-03-05 00:58:11 -05001607def determine_android_branch(board, package=None):
Alex Klein1699fab2022-09-08 08:46:06 -06001608 """Returns the Android branch in use by the active container ebuild."""
1609 if not package:
1610 package = determine_android_package(board)
1611 if not package:
1612 return None
1613 ebuild_path = portage_util.FindEbuildForBoardPackage(package, board)
1614 # We assume all targets pull from the same branch and that we always
1615 # have at least one of the following targets.
Shao-Chuan Leeca2cbcc2022-11-02 08:28:31 +09001616 # TODO(b/187795671): Do this in a less hacky way.
1617 targets = android.GetAllAndroidEbuildTargets()
Alex Klein1699fab2022-09-08 08:46:06 -06001618 ebuild_content = osutils.SourceEnvironment(ebuild_path, targets)
1619 for target in targets:
1620 if target in ebuild_content:
1621 branch = re.search(r"(.*?)-linux-", ebuild_content[target])
1622 if branch is not None:
1623 return branch.group(1)
1624 raise NoAndroidBranchError(
1625 "Android branch could not be determined for %s (ebuild empty?)" % board
1626 )
Michael Mortensenb70e8a82019-10-10 18:43:41 -06001627
1628
Mike Frysinger8e1c99a2021-03-05 00:58:11 -05001629def determine_android_target(board, package=None):
Alex Klein1699fab2022-09-08 08:46:06 -06001630 """Returns the Android target in use by the active container ebuild."""
1631 if not package:
1632 package = determine_android_package(board)
1633 if not package:
1634 return None
1635 if package.startswith("chromeos-base/android-vm-"):
1636 return "bertha"
1637 elif package.startswith("chromeos-base/android-container-"):
1638 return "cheets"
Michael Mortensenb70e8a82019-10-10 18:43:41 -06001639
Alex Klein1699fab2022-09-08 08:46:06 -06001640 raise NoAndroidTargetError(
1641 "Android Target cannot be determined for the package: %s" % package
1642 )
Michael Mortensen9fdb14b2019-10-17 11:17:30 -06001643
1644
1645def determine_platform_version():
Alex Klein1699fab2022-09-08 08:46:06 -06001646 """Returns the platform version from the source root."""
1647 # Platform version is something like '12575.0.0'.
1648 version = chromeos_version.VersionInfo.from_repo(constants.SOURCE_ROOT)
1649 return version.VersionString()
Michael Mortensen009cb662019-10-21 11:38:43 -06001650
1651
1652def determine_milestone_version():
Alex Klein1699fab2022-09-08 08:46:06 -06001653 """Returns the platform version from the source root."""
1654 # Milestone version is something like '79'.
1655 version = chromeos_version.VersionInfo.from_repo(constants.SOURCE_ROOT)
1656 return version.chrome_branch
Michael Mortensen009cb662019-10-21 11:38:43 -06001657
Alex Klein7a3a7dd2020-01-08 16:44:38 -07001658
Michael Mortensen009cb662019-10-21 11:38:43 -06001659def determine_full_version():
Alex Klein1699fab2022-09-08 08:46:06 -06001660 """Returns the full version from the source root."""
1661 # Full version is something like 'R79-12575.0.0'.
1662 milestone_version = determine_milestone_version()
1663 platform_version = determine_platform_version()
1664 full_version = "R%s-%s" % (milestone_version, platform_version)
1665 return full_version
Michael Mortensen71ef5682020-05-07 14:29:24 -06001666
1667
Matthias Kaehlckebf7d1772021-11-04 16:01:36 -07001668def find_fingerprints(
Alex Klein1699fab2022-09-08 08:46:06 -06001669 build_target: "build_target_lib.BuildTarget",
1670) -> List[str]:
1671 """Returns a list of fingerprints for this build.
Michael Mortensende716a12020-05-15 11:27:00 -06001672
Alex Klein1699fab2022-09-08 08:46:06 -06001673 Args:
Alex Klein348e7692022-10-13 17:03:37 -06001674 build_target: The build target.
Michael Mortensende716a12020-05-15 11:27:00 -06001675
Alex Klein1699fab2022-09-08 08:46:06 -06001676 Returns:
Alex Klein348e7692022-10-13 17:03:37 -06001677 List of fingerprint strings.
Alex Klein1699fab2022-09-08 08:46:06 -06001678 """
1679 cros_build_lib.AssertInsideChroot()
1680 fp_file = "cheets-fingerprint.txt"
1681 fp_path = os.path.join(
1682 image_lib.GetLatestImageLink(build_target.name), fp_file
1683 )
1684 if not os.path.isfile(fp_path):
1685 logging.info("Fingerprint file not found: %s", fp_path)
1686 return []
1687 logging.info("Reading fingerprint file: %s", fp_path)
1688 fingerprints = osutils.ReadFile(fp_path).splitlines()
1689 return fingerprints
Michael Mortensende716a12020-05-15 11:27:00 -06001690
1691
Alex Klein1699fab2022-09-08 08:46:06 -06001692def get_all_firmware_versions(build_target: "build_target_lib.BuildTarget"):
1693 """Extract firmware version for all models present.
Michael Mortensen59e30872020-05-18 14:12:49 -06001694
Alex Klein1699fab2022-09-08 08:46:06 -06001695 Args:
Alex Klein348e7692022-10-13 17:03:37 -06001696 build_target: The build target.
Michael Mortensen59e30872020-05-18 14:12:49 -06001697
Alex Klein1699fab2022-09-08 08:46:06 -06001698 Returns:
Alex Klein348e7692022-10-13 17:03:37 -06001699 A dict of FirmwareVersions namedtuple instances by model.
1700 Each element will be populated based on whether it was present in the
1701 command output.
Alex Klein1699fab2022-09-08 08:46:06 -06001702 """
1703 cros_build_lib.AssertInsideChroot()
1704 result = {}
1705 # Note that example output for _get_firmware_version_cmd_result is available
1706 # in the packages_unittest.py for testing get_all_firmware_versions.
1707 cmd_result = _get_firmware_version_cmd_result(build_target)
Michael Mortensen59e30872020-05-18 14:12:49 -06001708
Alex Klein1699fab2022-09-08 08:46:06 -06001709 if cmd_result:
1710 # There is a blank line between the version info for each model.
1711 firmware_version_payloads = cmd_result.split("\n\n")
1712 for firmware_version_payload in firmware_version_payloads:
1713 if "BIOS" in firmware_version_payload:
1714 firmware_version = _find_firmware_versions(
1715 firmware_version_payload
1716 )
1717 result[firmware_version.model] = firmware_version
1718 return result
Michael Mortensen59e30872020-05-18 14:12:49 -06001719
1720
Benjamin Shai0858cd32022-01-10 20:23:49 +00001721class FirmwareVersions(NamedTuple):
Alex Klein1699fab2022-09-08 08:46:06 -06001722 """Tuple to hold firmware versions, with truthiness."""
Benjamin Shai0858cd32022-01-10 20:23:49 +00001723
Alex Klein1699fab2022-09-08 08:46:06 -06001724 model: Optional[str]
1725 main: Optional[str]
1726 main_rw: Optional[str]
1727 ec: Optional[str]
1728 ec_rw: Optional[str]
1729
1730 def __bool__(self):
1731 return bool(
1732 self.model or self.main or self.main_rw or self.ec or self.ec_rw
1733 )
Michael Mortensen71ef5682020-05-07 14:29:24 -06001734
1735
Alex Klein1699fab2022-09-08 08:46:06 -06001736def get_firmware_versions(build_target: "build_target_lib.BuildTarget"):
1737 """Extract version information from the firmware updater, if one exists.
Michael Mortensen71ef5682020-05-07 14:29:24 -06001738
Alex Klein1699fab2022-09-08 08:46:06 -06001739 Args:
Alex Klein348e7692022-10-13 17:03:37 -06001740 build_target: The build target.
Michael Mortensen71ef5682020-05-07 14:29:24 -06001741
Alex Klein1699fab2022-09-08 08:46:06 -06001742 Returns:
Alex Klein348e7692022-10-13 17:03:37 -06001743 A FirmwareVersions namedtuple instance.
1744 Each element will either be set to the string output by the firmware
1745 updater shellball, or None if there is no firmware updater.
Alex Klein1699fab2022-09-08 08:46:06 -06001746 """
1747 cros_build_lib.AssertInsideChroot()
1748 cmd_result = _get_firmware_version_cmd_result(build_target)
1749 if cmd_result:
1750 return _find_firmware_versions(cmd_result)
1751 else:
1752 return FirmwareVersions(None, None, None, None, None)
Michael Mortensen71ef5682020-05-07 14:29:24 -06001753
1754
Matthias Kaehlckebf7d1772021-11-04 16:01:36 -07001755def _get_firmware_version_cmd_result(
Alex Klein1699fab2022-09-08 08:46:06 -06001756 build_target: "build_target_lib.BuildTarget",
1757) -> Optional[str]:
1758 """Gets the raw result output of the firmware updater version command.
Michael Mortensen71ef5682020-05-07 14:29:24 -06001759
Alex Klein1699fab2022-09-08 08:46:06 -06001760 Args:
Alex Klein348e7692022-10-13 17:03:37 -06001761 build_target: The build target.
Michael Mortensen71ef5682020-05-07 14:29:24 -06001762
Alex Klein1699fab2022-09-08 08:46:06 -06001763 Returns:
Alex Klein348e7692022-10-13 17:03:37 -06001764 Command execution result.
Alex Klein1699fab2022-09-08 08:46:06 -06001765 """
1766 updater = os.path.join(
1767 build_target.root, "usr/sbin/chromeos-firmwareupdate"
1768 )
1769 logging.info("Calling updater %s", updater)
1770 # Call the updater using the chroot-based path.
1771 try:
1772 return cros_build_lib.run(
1773 [updater, "-V"],
1774 capture_output=True,
1775 log_output=True,
1776 encoding="utf-8",
1777 ).stdout
1778 except cros_build_lib.RunCommandError:
1779 # Updater probably doesn't exist (e.g. betty).
1780 return None
Michael Mortensen71ef5682020-05-07 14:29:24 -06001781
1782
1783def _find_firmware_versions(cmd_output):
Alex Klein1699fab2022-09-08 08:46:06 -06001784 """Finds firmware version output via regex matches against the cmd_output.
Michael Mortensen71ef5682020-05-07 14:29:24 -06001785
Alex Klein1699fab2022-09-08 08:46:06 -06001786 Args:
Alex Klein348e7692022-10-13 17:03:37 -06001787 cmd_output: The raw output to search against.
Michael Mortensen71ef5682020-05-07 14:29:24 -06001788
Alex Klein1699fab2022-09-08 08:46:06 -06001789 Returns:
Alex Klein348e7692022-10-13 17:03:37 -06001790 FirmwareVersions namedtuple with results.
1791 Each element will either be set to the string output by the firmware
1792 updater shellball, or None if there is no match.
Alex Klein1699fab2022-09-08 08:46:06 -06001793 """
Michael Mortensen71ef5682020-05-07 14:29:24 -06001794
Alex Klein1699fab2022-09-08 08:46:06 -06001795 # Sometimes a firmware bundle includes a special combination of RO+RW
1796 # firmware. In this case, the RW firmware version is indicated with a "(RW)
1797 # version" field. In other cases, the "(RW) version" field is not present.
1798 # Therefore, search for the "(RW)" fields first and if they aren't present,
1799 # fallback to the other format. e.g. just "BIOS version:".
1800 # TODO(mmortensen): Use JSON once the firmware updater supports it.
1801 main = None
1802 main_rw = None
1803 ec = None
1804 ec_rw = None
1805 model = None
Michael Mortensen71ef5682020-05-07 14:29:24 -06001806
Alex Klein1699fab2022-09-08 08:46:06 -06001807 match = re.search(r"BIOS version:\s*(?P<version>.*)", cmd_output)
1808 if match:
1809 main = match.group("version")
Michael Mortensen71ef5682020-05-07 14:29:24 -06001810
Alex Klein1699fab2022-09-08 08:46:06 -06001811 match = re.search(r"BIOS \(RW\) version:\s*(?P<version>.*)", cmd_output)
1812 if match:
1813 main_rw = match.group("version")
Michael Mortensen71ef5682020-05-07 14:29:24 -06001814
Alex Klein1699fab2022-09-08 08:46:06 -06001815 match = re.search(r"EC version:\s*(?P<version>.*)", cmd_output)
1816 if match:
1817 ec = match.group("version")
Michael Mortensen71ef5682020-05-07 14:29:24 -06001818
Alex Klein1699fab2022-09-08 08:46:06 -06001819 match = re.search(r"EC \(RW\) version:\s*(?P<version>.*)", cmd_output)
1820 if match:
1821 ec_rw = match.group("version")
Michael Mortensen71ef5682020-05-07 14:29:24 -06001822
Alex Klein1699fab2022-09-08 08:46:06 -06001823 match = re.search(r"Model:\s*(?P<model>.*)", cmd_output)
1824 if match:
1825 model = match.group("model")
Michael Mortensen71ef5682020-05-07 14:29:24 -06001826
Alex Klein1699fab2022-09-08 08:46:06 -06001827 return FirmwareVersions(model, main, main_rw, ec, ec_rw)
Michael Mortensena4af79e2020-05-06 16:18:48 -06001828
1829
Benjamin Shai0858cd32022-01-10 20:23:49 +00001830class MainEcFirmwareVersions(NamedTuple):
Alex Klein1699fab2022-09-08 08:46:06 -06001831 """Tuple to hold main and ec firmware versions, with truthiness."""
Benjamin Shai0858cd32022-01-10 20:23:49 +00001832
Alex Klein1699fab2022-09-08 08:46:06 -06001833 main_fw_version: Optional[str]
1834 ec_fw_version: Optional[str]
1835
1836 def __bool__(self):
1837 return bool(self.main_fw_version or self.ec_fw_version)
Benjamin Shai0858cd32022-01-10 20:23:49 +00001838
Michael Mortensena4af79e2020-05-06 16:18:48 -06001839
Alex Klein1699fab2022-09-08 08:46:06 -06001840def determine_firmware_versions(build_target: "build_target_lib.BuildTarget"):
1841 """Returns a namedtuple with main and ec firmware versions.
Michael Mortensena4af79e2020-05-06 16:18:48 -06001842
Alex Klein1699fab2022-09-08 08:46:06 -06001843 Args:
Alex Klein348e7692022-10-13 17:03:37 -06001844 build_target: The build target.
Michael Mortensena4af79e2020-05-06 16:18:48 -06001845
Alex Klein1699fab2022-09-08 08:46:06 -06001846 Returns:
Alex Klein348e7692022-10-13 17:03:37 -06001847 MainEcFirmwareVersions namedtuple with results.
Alex Klein1699fab2022-09-08 08:46:06 -06001848 """
1849 fw_versions = get_firmware_versions(build_target)
1850 main_fw_version = fw_versions.main_rw or fw_versions.main
1851 ec_fw_version = fw_versions.ec_rw or fw_versions.ec
Michael Mortensena4af79e2020-05-06 16:18:48 -06001852
Alex Klein1699fab2022-09-08 08:46:06 -06001853 return MainEcFirmwareVersions(main_fw_version, ec_fw_version)
Michael Mortensenfbf2b2d2020-05-14 16:33:06 -06001854
Benjamin Shai0858cd32022-01-10 20:23:49 +00001855
Matthias Kaehlckebf7d1772021-11-04 16:01:36 -07001856def determine_kernel_version(
Alex Klein1699fab2022-09-08 08:46:06 -06001857 build_target: "build_target_lib.BuildTarget",
Lizzy Presland0b978e62022-09-09 16:55:29 +00001858) -> str:
Alex Klein1699fab2022-09-08 08:46:06 -06001859 """Returns a string containing the kernel version for this build target.
Michael Mortensenfbf2b2d2020-05-14 16:33:06 -06001860
Alex Klein1699fab2022-09-08 08:46:06 -06001861 Args:
Alex Klein348e7692022-10-13 17:03:37 -06001862 build_target: The build target.
Michael Mortensenfbf2b2d2020-05-14 16:33:06 -06001863
Alex Klein1699fab2022-09-08 08:46:06 -06001864 Returns:
Alex Klein348e7692022-10-13 17:03:37 -06001865 The kernel versions, or empty string.
Alex Klein1699fab2022-09-08 08:46:06 -06001866 """
Lizzy Presland0b978e62022-09-09 16:55:29 +00001867 target_virtual_pkg = "virtual/linux-sources"
Alex Klein1699fab2022-09-08 08:46:06 -06001868 try:
Lizzy Presland0b978e62022-09-09 16:55:29 +00001869 candidate_packages = portage_util.GetFlattenedDepsForPackage(
1870 target_virtual_pkg,
1871 sysroot=build_target.root,
1872 board=build_target.name,
1873 depth=1,
1874 )
1875 installed_packages = portage_util.GetPackageDependencies(
1876 target_virtual_pkg, board=build_target.name
Alex Klein1699fab2022-09-08 08:46:06 -06001877 )
1878 except cros_build_lib.RunCommandError as e:
1879 logging.warning("Unable to get package list for metadata: %s", e)
Lizzy Presland0b978e62022-09-09 16:55:29 +00001880 return ""
1881 if not candidate_packages:
1882 raise KernelVersionError("No package found in FlattenedDepsForPackage")
1883 if not installed_packages:
1884 raise KernelVersionError("No package found in GetPackageDependencies")
1885 packages = [
1886 p
1887 for p in installed_packages
1888 if p in candidate_packages and target_virtual_pkg not in p
1889 ]
1890 if len(packages) == 0:
1891 raise KernelVersionError(
1892 "No matches for installed packages were found in candidate "
1893 "packages. Did GetFlattenedDepsForPackage search all possible "
1894 "package versions?\tInstalled: %s\tCandidates: %s"
1895 % (" ".join(installed_packages), " ".join(candidate_packages))
1896 )
1897 if len(packages) > 1:
1898 raise KernelVersionError(
1899 "Too many packages found in intersection of installed packages and "
1900 "possible kernel versions (%s)" % "".join(packages)
1901 )
1902 kernel_version = package_info.SplitCPV(packages[0]).version
1903 logging.info("Found active kernel version: %s", kernel_version)
1904 return kernel_version
Michael Mortensen125bb012020-05-21 14:02:10 -06001905
1906
Matthias Kaehlckebf7d1772021-11-04 16:01:36 -07001907def get_models(
Alex Klein1699fab2022-09-08 08:46:06 -06001908 build_target: "build_target_lib.BuildTarget", log_output: bool = True
1909) -> Optional[List[str]]:
1910 """Obtain a list of models supported by a unified board.
Michael Mortensen125bb012020-05-21 14:02:10 -06001911
Alex Klein1699fab2022-09-08 08:46:06 -06001912 This ignored whitelabel models since GoldenEye has no specific support for
1913 these at present.
Michael Mortensen125bb012020-05-21 14:02:10 -06001914
Alex Klein1699fab2022-09-08 08:46:06 -06001915 Args:
Alex Klein348e7692022-10-13 17:03:37 -06001916 build_target: The build target.
1917 log_output: Whether to log the output of the cros_config_host
1918 invocation.
Michael Mortensen125bb012020-05-21 14:02:10 -06001919
Alex Klein1699fab2022-09-08 08:46:06 -06001920 Returns:
Alex Klein348e7692022-10-13 17:03:37 -06001921 A list of models supported by this board, if it is a unified build;
1922 None, if it is not a unified build.
Alex Klein1699fab2022-09-08 08:46:06 -06001923 """
1924 return _run_cros_config_host(
1925 build_target, ["list-models"], log_output=log_output
1926 )
Michael Mortensen125bb012020-05-21 14:02:10 -06001927
1928
Matthias Kaehlckebf7d1772021-11-04 16:01:36 -07001929def get_key_id(
Alex Klein1699fab2022-09-08 08:46:06 -06001930 build_target: "build_target_lib.BuildTarget", model: str
1931) -> Optional[str]:
1932 """Obtain the key_id for a model within the build_target.
Michael Mortensen359c1f32020-05-28 19:35:42 -06001933
Alex Klein1699fab2022-09-08 08:46:06 -06001934 Args:
Alex Klein348e7692022-10-13 17:03:37 -06001935 build_target: The build target.
1936 model: The model name
Michael Mortensen359c1f32020-05-28 19:35:42 -06001937
Alex Klein1699fab2022-09-08 08:46:06 -06001938 Returns:
Alex Klein348e7692022-10-13 17:03:37 -06001939 A key_id or None.
Alex Klein1699fab2022-09-08 08:46:06 -06001940 """
1941 model_arg = "--model=" + model
1942 key_id_list = _run_cros_config_host(
1943 build_target, [model_arg, "get", "/firmware-signing", "key-id"]
1944 )
1945 key_id = None
1946 if len(key_id_list) == 1:
1947 key_id = key_id_list[0]
1948 return key_id
Michael Mortensen359c1f32020-05-28 19:35:42 -06001949
1950
Matthias Kaehlckebf7d1772021-11-04 16:01:36 -07001951def _run_cros_config_host(
Alex Klein1699fab2022-09-08 08:46:06 -06001952 build_target: "build_target_lib.BuildTarget",
Matthias Kaehlckebf7d1772021-11-04 16:01:36 -07001953 args: List[str],
Alex Klein1699fab2022-09-08 08:46:06 -06001954 log_output: bool = True,
1955) -> Optional[List[str]]:
1956 """Run the cros_config_host tool.
Michael Mortensen125bb012020-05-21 14:02:10 -06001957
Alex Klein1699fab2022-09-08 08:46:06 -06001958 Args:
Alex Klein348e7692022-10-13 17:03:37 -06001959 build_target: The build target.
1960 args: List of arguments to pass.
1961 log_output: Whether to log the output of the cros_config_host.
Michael Mortensen125bb012020-05-21 14:02:10 -06001962
Alex Klein1699fab2022-09-08 08:46:06 -06001963 Returns:
Alex Klein348e7692022-10-13 17:03:37 -06001964 Output of the tool
Alex Klein1699fab2022-09-08 08:46:06 -06001965 """
1966 cros_build_lib.AssertInsideChroot()
1967 tool = "/usr/bin/cros_config_host"
1968 if not os.path.isfile(tool):
1969 return None
Michael Mortensen125bb012020-05-21 14:02:10 -06001970
Alex Klein1699fab2022-09-08 08:46:06 -06001971 config_fname = build_target.full_path(
1972 "usr/share/chromeos-config/yaml/config.yaml"
1973 )
Michael Mortensen125bb012020-05-21 14:02:10 -06001974
Alex Klein1699fab2022-09-08 08:46:06 -06001975 result = cros_build_lib.run(
1976 [tool, "-c", config_fname] + args,
1977 capture_output=True,
1978 encoding="utf-8",
1979 log_output=log_output,
1980 check=False,
1981 )
1982 if result.returncode:
1983 # Show the output for debugging purposes.
1984 if "No such file or directory" not in result.stderr:
1985 logging.error("cros_config_host failed: %s\n", result.stderr)
1986 return None
1987 return result.stdout.strip().splitlines()