blob: c4b5edd120e49dda839ea73125c0d2a41c0a58db [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 Lee293389c2023-01-20 17:44:35 +0900272 lkgb = android.ReadLKGB(android_package_dir)
273 android_version = lkgb["build_id"]
274 android_branch = lkgb.get("branch", None)
Shao-Chuan Lee05e51142021-11-24 12:27:37 +0900275
Alex Klein1699fab2022-09-08 08:46:06 -0600276 result = uprev_lib.UprevVersionedPackageResult()
277 uprev_result = uprev_android(
278 android_package,
279 chroot,
280 build_targets=build_targets,
Shao-Chuan Lee293389c2023-01-20 17:44:35 +0900281 android_build_branch=android_branch,
Alex Klein1699fab2022-09-08 08:46:06 -0600282 android_version=android_version,
283 skip_commit=True,
284 )
285 if not uprev_result.revved:
286 return result
287
Alex Kleinfee86da2023-01-20 18:40:06 -0700288 # cros_mark_android_as_stable returns paths relative to
289 # |android.OVERLAY_DIR|.
Alex Klein1699fab2022-09-08 08:46:06 -0600290 result.add_result(
291 android_version,
292 [
293 os.path.join(android.OVERLAY_DIR, f)
294 for f in uprev_result.modified_files
295 ],
296 )
Shao-Chuan Lee05e51142021-11-24 12:27:37 +0900297 return result
298
Shao-Chuan Lee05e51142021-11-24 12:27:37 +0900299
300def define_uprev_android_lkgb_handlers():
Alex Klein1699fab2022-09-08 08:46:06 -0600301 """Dynamically define uprev handlers for each Android package"""
Shao-Chuan Lee05e51142021-11-24 12:27:37 +0900302
Alex Klein1699fab2022-09-08 08:46:06 -0600303 def define_handler(android_package):
304 """Defines the uprev handler for an Android package."""
305 full_package_name = "chromeos-base/" + android_package
Shao-Chuan Lee05e51142021-11-24 12:27:37 +0900306
Alex Klein1699fab2022-09-08 08:46:06 -0600307 @uprevs_versioned_package(full_package_name)
308 def _handler(build_targets, _refs, chroot):
309 return uprev_android_lkgb(android_package, build_targets, chroot)
Shao-Chuan Lee05e51142021-11-24 12:27:37 +0900310
Shao-Chuan Leeca2cbcc2022-11-02 08:28:31 +0900311 for android_package in android.GetAllAndroidPackages():
Alex Klein1699fab2022-09-08 08:46:06 -0600312 define_handler(android_package)
Shao-Chuan Lee05e51142021-11-24 12:27:37 +0900313
314
315define_uprev_android_lkgb_handlers()
Alex Klein4de25e82019-08-05 15:58:39 -0600316
317
Matthias Kaehlckebf7d1772021-11-04 16:01:36 -0700318def uprev_build_targets(
Alex Klein1699fab2022-09-08 08:46:06 -0600319 build_targets: Optional[List["build_target_lib.BuildTarget"]],
Matthias Kaehlckebf7d1772021-11-04 16:01:36 -0700320 overlay_type: str,
Alex Klein1699fab2022-09-08 08:46:06 -0600321 chroot: "chroot_lib.Chroot" = None,
322 output_dir: Optional[str] = None,
323):
324 """Uprev the set provided build targets, or all if not specified.
Alex Kleineb77ffa2019-05-28 14:47:44 -0600325
Alex Klein1699fab2022-09-08 08:46:06 -0600326 Args:
Alex Klein348e7692022-10-13 17:03:37 -0600327 build_targets: The build targets whose overlays should be uprevved,
328 empty or None for all.
329 overlay_type: One of the valid overlay types except None (see
330 constants.VALID_OVERLAYS).
331 chroot: The chroot to clean, if desired.
332 output_dir: The path to optionally dump result files.
Alex Klein1699fab2022-09-08 08:46:06 -0600333 """
334 # Need a valid overlay, but exclude None.
335 assert overlay_type and overlay_type in constants.VALID_OVERLAYS
Alex Kleineb77ffa2019-05-28 14:47:44 -0600336
Alex Klein1699fab2022-09-08 08:46:06 -0600337 if build_targets:
338 overlays = portage_util.FindOverlaysForBoards(
339 overlay_type, boards=[t.name for t in build_targets]
340 )
341 else:
342 overlays = portage_util.FindOverlays(overlay_type)
Alex Kleineb77ffa2019-05-28 14:47:44 -0600343
Alex Klein1699fab2022-09-08 08:46:06 -0600344 return uprev_overlays(
345 overlays,
346 build_targets=build_targets,
347 chroot=chroot,
348 output_dir=output_dir,
349 )
Alex Kleineb77ffa2019-05-28 14:47:44 -0600350
351
Matthias Kaehlckebf7d1772021-11-04 16:01:36 -0700352def uprev_overlays(
353 overlays: List[str],
Alex Klein1699fab2022-09-08 08:46:06 -0600354 build_targets: Optional[List["build_target_lib.BuildTarget"]] = None,
355 chroot: Optional["chroot_lib.Chroot"] = None,
356 output_dir: Optional[str] = None,
357) -> List[str]:
358 """Uprev the given overlays.
Alex Kleineb77ffa2019-05-28 14:47:44 -0600359
Alex Klein1699fab2022-09-08 08:46:06 -0600360 Args:
Alex Klein348e7692022-10-13 17:03:37 -0600361 overlays: The list of overlay paths.
362 build_targets: The build targets to clean in |chroot|, if desired. No
363 effect unless |chroot| is provided.
364 chroot: The chroot to clean, if desired.
365 output_dir: The path to optionally dump result files.
Alex Kleineb77ffa2019-05-28 14:47:44 -0600366
Alex Klein1699fab2022-09-08 08:46:06 -0600367 Returns:
Alex Klein348e7692022-10-13 17:03:37 -0600368 The paths to all the modified ebuild files. This includes the new files
369 that were added (i.e. the new versions) and all the removed files
Alex Klein1699fab2022-09-08 08:46:06 -0600370 (i.e. the old versions).
371 """
372 assert overlays
Alex Kleineb77ffa2019-05-28 14:47:44 -0600373
Alex Klein1699fab2022-09-08 08:46:06 -0600374 manifest = git.ManifestCheckout.Cached(constants.SOURCE_ROOT)
Alex Kleineb77ffa2019-05-28 14:47:44 -0600375
Alex Klein1699fab2022-09-08 08:46:06 -0600376 uprev_manager = uprev_lib.UprevOverlayManager(
377 overlays,
378 manifest,
379 build_targets=build_targets,
380 chroot=chroot,
381 output_dir=output_dir,
382 )
383 uprev_manager.uprev()
Alex Kleineb77ffa2019-05-28 14:47:44 -0600384
Alex Klein1699fab2022-09-08 08:46:06 -0600385 return uprev_manager.modified_ebuilds, uprev_manager.revved_packages
Alex Kleineb77ffa2019-05-28 14:47:44 -0600386
387
Matthias Kaehlckebf7d1772021-11-04 16:01:36 -0700388def uprev_versioned_package(
Alex Kleind3b84042023-05-19 14:43:59 -0600389 package: package_info.PackageInfo,
Alex Klein1699fab2022-09-08 08:46:06 -0600390 build_targets: List["build_target_lib.BuildTarget"],
Matthias Kaehlckebf7d1772021-11-04 16:01:36 -0700391 refs: List[uprev_lib.GitRef],
Alex Klein1699fab2022-09-08 08:46:06 -0600392 chroot: "chroot_lib.Chroot",
393) -> "uprev_lib.UprevVersionedPackageResult":
394 """Call registered uprev handler function for the package.
Alex Klein87531182019-08-12 15:23:37 -0600395
Alex Klein1699fab2022-09-08 08:46:06 -0600396 Args:
Alex Klein348e7692022-10-13 17:03:37 -0600397 package: The package being uprevved.
398 build_targets: The build targets to clean on a successful uprev.
399 refs:
400 chroot: The chroot to enter for cleaning.
Alex Klein87531182019-08-12 15:23:37 -0600401
Alex Klein1699fab2022-09-08 08:46:06 -0600402 Returns:
Alex Klein348e7692022-10-13 17:03:37 -0600403 The result.
Alex Klein1699fab2022-09-08 08:46:06 -0600404 """
405 assert package
Alex Klein87531182019-08-12 15:23:37 -0600406
Alex Klein1699fab2022-09-08 08:46:06 -0600407 if package.cp not in _UPREV_FUNCS:
408 raise UnknownPackageError(
409 'Package "%s" does not have a registered handler.' % package.cp
410 )
Alex Klein87531182019-08-12 15:23:37 -0600411
Alex Klein1699fab2022-09-08 08:46:06 -0600412 return _UPREV_FUNCS[package.cp](build_targets, refs, chroot)
Alex Klein87531182019-08-12 15:23:37 -0600413
414
Alex Klein1699fab2022-09-08 08:46:06 -0600415@uprevs_versioned_package("media-libs/virglrenderer")
Navil Perezf57ba872020-06-04 22:38:37 +0000416def uprev_virglrenderer(_build_targets, refs, _chroot):
Alex Klein1699fab2022-09-08 08:46:06 -0600417 """Updates virglrenderer ebuilds.
Navil Perezf57ba872020-06-04 22:38:37 +0000418
Alex Klein1699fab2022-09-08 08:46:06 -0600419 See: uprev_versioned_package.
Navil Perezf57ba872020-06-04 22:38:37 +0000420
Alex Klein1699fab2022-09-08 08:46:06 -0600421 Returns:
Alex Klein348e7692022-10-13 17:03:37 -0600422 UprevVersionedPackageResult: The result of updating virglrenderer
Trent Aptedb18e36f2023-05-10 15:06:38 +1000423 ebuilds.
Alex Klein1699fab2022-09-08 08:46:06 -0600424 """
425 overlay = os.path.join(
426 constants.SOURCE_ROOT, constants.CHROMIUMOS_OVERLAY_DIR
427 )
428 repo_path = os.path.join(
429 constants.SOURCE_ROOT, "src", "third_party", "virglrenderer"
430 )
431 manifest = git.ManifestCheckout.Cached(repo_path)
Navil Perezf57ba872020-06-04 22:38:37 +0000432
Alex Klein1699fab2022-09-08 08:46:06 -0600433 uprev_manager = uprev_lib.UprevOverlayManager([overlay], manifest)
434 # TODO(crbug.com/1066242): Ebuilds for virglrenderer are currently
435 # denylisted. Do not force uprevs after builder is stable and ebuilds are no
436 # longer denylisted.
437 uprev_manager.uprev(package_list=["media-libs/virglrenderer"], force=True)
Navil Perezf57ba872020-06-04 22:38:37 +0000438
Alex Klein1699fab2022-09-08 08:46:06 -0600439 updated_files = uprev_manager.modified_ebuilds
440 result = uprev_lib.UprevVersionedPackageResult()
441 result.add_result(refs[-1].revision, updated_files)
442 return result
Navil Perezf57ba872020-06-04 22:38:37 +0000443
Alex Klein1699fab2022-09-08 08:46:06 -0600444
Matthew Lam59ca37d2022-10-24 18:11:06 +0000445@uprevs_versioned_package("x11-apps/igt-gpu-tools")
446def uprev_igt_gpu_tools(_build_targets, refs, _chroot):
447 """Updates igt-gpu-tools ebuilds.
448
449 See: uprev_versioned_package.
450
451 Returns:
Alex Kleinfee86da2023-01-20 18:40:06 -0700452 UprevVersionedPackageResult: The result of updating igt-gpu-tools
Trent Aptedb18e36f2023-05-10 15:06:38 +1000453 ebuilds.
Matthew Lam59ca37d2022-10-24 18:11:06 +0000454 """
455 overlay = os.path.join(
456 constants.SOURCE_ROOT, constants.CHROMIUMOS_OVERLAY_DIR
457 )
458 repo_path = os.path.join(
459 constants.SOURCE_ROOT, "src", "third_party", "igt-gpu-tools"
460 )
461 manifest = git.ManifestCheckout.Cached(repo_path)
462
463 uprev_manager = uprev_lib.UprevOverlayManager([overlay], manifest)
464 uprev_manager.uprev(package_list=["x11-apps/igt-gpu-tools"], force=True)
465
466 updated_files = uprev_manager.modified_ebuilds
467 result = uprev_lib.UprevVersionedPackageResult()
468 result.add_result(refs[-1].revision, updated_files)
469 return result
470
471
Alex Klein1699fab2022-09-08 08:46:06 -0600472@uprevs_versioned_package("chromeos-base/drivefs")
Jose Magana03b5a842020-08-19 12:52:59 +1000473def uprev_drivefs(_build_targets, refs, chroot):
Alex Klein1699fab2022-09-08 08:46:06 -0600474 """Updates drivefs ebuilds.
Jose Magana03b5a842020-08-19 12:52:59 +1000475
Alex Klein1699fab2022-09-08 08:46:06 -0600476 DriveFS versions follow the tag format of refs/tags/drivefs_1.2.3.
477 See: uprev_versioned_package.
Jose Magana03b5a842020-08-19 12:52:59 +1000478
Alex Klein1699fab2022-09-08 08:46:06 -0600479 Returns:
Alex Klein348e7692022-10-13 17:03:37 -0600480 UprevVersionedPackageResult: The result of updating drivefs ebuilds.
Alex Klein1699fab2022-09-08 08:46:06 -0600481 """
Jose Magana03b5a842020-08-19 12:52:59 +1000482
Alex Klein1699fab2022-09-08 08:46:06 -0600483 DRIVEFS_PATH_PREFIX = "src/private-overlays/chromeos-overlay/chromeos-base"
484 result = uprev_lib.UprevVersionedPackageResult()
485 all_changed_files = []
Jose Magana03b5a842020-08-19 12:52:59 +1000486
Alex Klein1699fab2022-09-08 08:46:06 -0600487 DRIVEFS_REFS_PREFIX = "refs/tags/drivefs_"
488 drivefs_version = _get_latest_version_from_refs(DRIVEFS_REFS_PREFIX, refs)
489 if not drivefs_version:
490 # No valid DriveFS version is identified.
491 return result
492
493 logging.debug("DriveFS version determined from refs: %s", drivefs_version)
494
495 # Attempt to uprev drivefs package.
496 pkg_path = os.path.join(DRIVEFS_PATH_PREFIX, "drivefs")
497 uprev_result = uprev_lib.uprev_workon_ebuild_to_version(
498 pkg_path, drivefs_version, chroot, allow_downrev=False
499 )
500
501 if not uprev_result:
502 return result
503 all_changed_files.extend(uprev_result.changed_files)
504 result.add_result(drivefs_version, all_changed_files)
505
Ben Reich4f3fa1b2020-12-19 08:21:26 +0000506 return result
Jose Magana03b5a842020-08-19 12:52:59 +1000507
Jose Magana03b5a842020-08-19 12:52:59 +1000508
Alex Klein1699fab2022-09-08 08:46:06 -0600509@uprevs_versioned_package("chromeos-base/perfetto")
Chinglin Yufa728552023-04-13 03:12:04 +0000510@uprevs_versioned_package("dev-go/perfetto-protos")
Harvey Yang9c61e9c2021-03-02 16:32:43 +0800511def uprev_perfetto(_build_targets, refs, chroot):
Alex Klein1699fab2022-09-08 08:46:06 -0600512 """Updates Perfetto ebuilds.
Harvey Yang9c61e9c2021-03-02 16:32:43 +0800513
Alex Klein1699fab2022-09-08 08:46:06 -0600514 Perfetto versions follow the tag format of refs/tags/v1.2.
515 See: uprev_versioned_package.
Harvey Yang9c61e9c2021-03-02 16:32:43 +0800516
Alex Klein1699fab2022-09-08 08:46:06 -0600517 Returns:
Alex Klein348e7692022-10-13 17:03:37 -0600518 UprevVersionedPackageResult: The result of updating Perfetto ebuilds.
Alex Klein1699fab2022-09-08 08:46:06 -0600519 """
520 result = uprev_lib.UprevVersionedPackageResult()
Harvey Yang9c61e9c2021-03-02 16:32:43 +0800521
Alex Klein1699fab2022-09-08 08:46:06 -0600522 PERFETTO_REFS_PREFIX = "refs/tags/v"
Chinglin Yufa728552023-04-13 03:12:04 +0000523
524 perfetto_ebuilds = ["chromeos-base/perfetto", "dev-go/perfetto-protos"]
525 perfetto_paths = [
526 os.path.join(constants.CHROMIUMOS_OVERLAY_DIR, e)
527 for e in perfetto_ebuilds
528 ]
529 # chromeos-base/perfetto is the primary ebuild.
530 primary_ebuild_path = perfetto_paths[0]
Chinglin Yuad12a512022-10-07 17:26:12 +0800531
532 # Decide the version number to uprev to:
533 # * If |refs| contains refs/tags/v*, get the latest from them.
Alex Klein1699fab2022-09-08 08:46:06 -0600534 perfetto_version = _get_latest_version_from_refs(PERFETTO_REFS_PREFIX, refs)
Chinglin Yuad12a512022-10-07 17:26:12 +0800535 # * Or if |refs| contains only the latest trunk revisions, use the current
536 # stable ebuild version for a revision bump.
537 if refs and not perfetto_version:
Chinglin Yufa728552023-04-13 03:12:04 +0000538 perfetto_version = uprev_lib.get_stable_ebuild_version(
539 primary_ebuild_path
540 )
Chinglin Yuad12a512022-10-07 17:26:12 +0800541
Alex Klein1699fab2022-09-08 08:46:06 -0600542 if not perfetto_version:
543 # No valid Perfetto version is identified.
544 return result
545
Chinglin Yufa728552023-04-13 03:12:04 +0000546 for path in perfetto_paths:
547 # Attempt to uprev perfetto package.
548 # |perfetto_version| is only used in determining the ebuild version. The
549 # package is always updated to the latest HEAD.
550 uprev_result = uprev_lib.uprev_workon_ebuild_to_version(
551 path,
552 perfetto_version,
553 chroot,
554 allow_downrev=False,
555 # Use default ref="HEAD"
556 )
Alex Klein1699fab2022-09-08 08:46:06 -0600557
Chinglin Yufa728552023-04-13 03:12:04 +0000558 if not uprev_result:
559 return result
Alex Klein1699fab2022-09-08 08:46:06 -0600560
Chinglin Yufa728552023-04-13 03:12:04 +0000561 # Include short git sha hash in the uprev commit message.
562 # Use 9 digits to match the short hash length in `perfetto --version`.
563 short_revision = refs[-1].revision[0:9]
564 version_and_rev = f"{perfetto_version}-{short_revision}"
565 result.add_result(version_and_rev, uprev_result.changed_files)
Alex Klein1699fab2022-09-08 08:46:06 -0600566
Harvey Yang9c61e9c2021-03-02 16:32:43 +0800567 return result
568
Harvey Yang9c61e9c2021-03-02 16:32:43 +0800569
Denis Nikitin63613e32022-09-09 22:26:50 -0700570class AfdoMetadata(NamedTuple):
571 """Data class holding AFDO metadata."""
572
573 var_name: str
574 path: str
575
576
Alex Klein1699fab2022-09-08 08:46:06 -0600577@uprevs_versioned_package("afdo/kernel-profiles")
Brian Norrisf0c68572023-07-12 17:32:20 -0700578def uprev_kernel_afdo(_build_targets, _refs, chroot: "chroot_lib.Chroot"):
Alex Klein1699fab2022-09-08 08:46:06 -0600579 """Updates kernel ebuilds with versions from kernel_afdo.json.
Yaakov Shaul395ae832019-09-09 14:45:32 -0600580
Alex Klein1699fab2022-09-08 08:46:06 -0600581 See: uprev_versioned_package.
Yaakov Shaul1eafe832019-09-10 16:50:26 -0600582
Alex Klein1699fab2022-09-08 08:46:06 -0600583 Raises:
Alex Klein348e7692022-10-13 17:03:37 -0600584 EbuildManifestError: When ebuild manifest does not complete
585 successfully.
586 JSONDecodeError: When json is malformed.
Alex Klein1699fab2022-09-08 08:46:06 -0600587 """
Denis Nikitin63613e32022-09-09 22:26:50 -0700588 metadata_dir = os.path.join(
Alex Klein1699fab2022-09-08 08:46:06 -0600589 constants.SOURCE_ROOT,
590 "src",
591 "third_party",
592 "toolchain-utils",
593 "afdo_metadata",
Denis Nikitin63613e32022-09-09 22:26:50 -0700594 )
595 metadata_files = (
596 AfdoMetadata(
597 var_name="AFDO_PROFILE_VERSION",
598 path=os.path.join(metadata_dir, "kernel_afdo.json"),
599 ),
600 AfdoMetadata(
601 var_name="ARM_AFDO_PROFILE_VERSION",
602 path=os.path.join(metadata_dir, "kernel_arm_afdo.json"),
603 ),
Alex Klein1699fab2022-09-08 08:46:06 -0600604 )
Yaakov Shaul395ae832019-09-09 14:45:32 -0600605
Alex Klein1699fab2022-09-08 08:46:06 -0600606 result = uprev_lib.UprevVersionedPackageResult()
Denis Nikitin63613e32022-09-09 22:26:50 -0700607 for metadata in metadata_files:
Mike Frysinger81a98062023-02-24 15:42:04 -0500608 with open(metadata.path, "r", encoding="utf-8") as f:
Denis Nikitin63613e32022-09-09 22:26:50 -0700609 versions = json.load(f)
Yaakov Shaul1eafe832019-09-10 16:50:26 -0600610
Denis Nikitin63613e32022-09-09 22:26:50 -0700611 for kernel_pkg, version_info in versions.items():
612 path = os.path.join(
613 constants.CHROMIUMOS_OVERLAY_DIR, "sys-kernel", kernel_pkg
614 )
615 ebuild_path = os.path.join(
616 constants.SOURCE_ROOT, path, f"{kernel_pkg}-9999.ebuild"
617 )
618 chroot_ebuild_path = os.path.join(
619 constants.CHROOT_SOURCE_ROOT, path, f"{kernel_pkg}-9999.ebuild"
620 )
621 afdo_profile_version = version_info["name"]
622 patch_ebuild_vars(
623 ebuild_path, {metadata.var_name: afdo_profile_version}
Alex Klein1699fab2022-09-08 08:46:06 -0600624 )
Yaakov Shaul1eafe832019-09-10 16:50:26 -0600625
Denis Nikitin63613e32022-09-09 22:26:50 -0700626 try:
627 cmd = ["ebuild", chroot_ebuild_path, "manifest", "--force"]
Brian Norrisf0c68572023-07-12 17:32:20 -0700628 cros_build_lib.run(
629 cmd, enter_chroot=True, chroot_args=chroot.get_enter_args()
630 )
Denis Nikitin63613e32022-09-09 22:26:50 -0700631 except cros_build_lib.RunCommandError as e:
632 raise uprev_lib.EbuildManifestError(
633 "Error encountered when regenerating the manifest for "
634 f"ebuild: {chroot_ebuild_path}\n{e}",
635 e,
636 )
Yaakov Shaul1eafe832019-09-10 16:50:26 -0600637
Denis Nikitin63613e32022-09-09 22:26:50 -0700638 manifest_path = os.path.join(
639 constants.SOURCE_ROOT, path, "Manifest"
640 )
641 result.add_result(
642 afdo_profile_version, [ebuild_path, manifest_path]
643 )
Yaakov Shaul730814a2019-09-10 13:58:25 -0600644
Alex Klein1699fab2022-09-08 08:46:06 -0600645 return result
Yaakov Shaul395ae832019-09-09 14:45:32 -0600646
647
Alex Klein1699fab2022-09-08 08:46:06 -0600648@uprevs_versioned_package("chromeos-base/termina-dlc")
649@uprevs_versioned_package("chromeos-base/termina-tools-dlc")
Maciek Swiech6b12f662022-01-25 16:51:19 +0000650def uprev_termina_dlcs(_build_targets, _refs, chroot):
Alex Klein1699fab2022-09-08 08:46:06 -0600651 """Updates shared termina-dlc and termina-tools-dlc ebuilds.
Maciek Swiech6b12f662022-01-25 16:51:19 +0000652
Alex Klein1699fab2022-09-08 08:46:06 -0600653 termina-dlc - chromeos-base/termina-dlc
654 termina-tools-dlc - chromeos-base/termina-tools-dlc
Trent Beginaf51f1b2020-03-09 17:35:31 -0600655
Alex Klein1699fab2022-09-08 08:46:06 -0600656 See: uprev_versioned_package.
657 """
658 termina_dlc_pkg = "termina-dlc"
659 termina_dlc_pkg_path = os.path.join(
660 constants.CHROMIUMOS_OVERLAY_DIR, "chromeos-base", termina_dlc_pkg
661 )
662 tools_dlc_pkg = "termina-tools-dlc"
663 tools_dlc_pkg_path = os.path.join(
664 constants.CHROMIUMOS_OVERLAY_DIR, "chromeos-base", tools_dlc_pkg
665 )
Patrick Meiring5897add2020-09-16 16:30:17 +1000666
Alex Klein1699fab2022-09-08 08:46:06 -0600667 # termina-dlc and termina-tools-dlc are pinned to the same version.
668 version_pin_src_path = _get_version_pin_src_path(termina_dlc_pkg_path)
669 version_no_rev = osutils.ReadFile(version_pin_src_path).strip()
Patrick Meiring5897add2020-09-16 16:30:17 +1000670
Alex Klein1699fab2022-09-08 08:46:06 -0600671 result = uprev_lib.uprev_ebuild_from_pin(
672 termina_dlc_pkg_path, version_no_rev, chroot
673 )
674 result += uprev_lib.uprev_ebuild_from_pin(
675 tools_dlc_pkg_path, version_no_rev, chroot
676 )
Patrick Meiring5897add2020-09-16 16:30:17 +1000677
Alex Klein1699fab2022-09-08 08:46:06 -0600678 return result
Patrick Meiring5897add2020-09-16 16:30:17 +1000679
Alex Klein1699fab2022-09-08 08:46:06 -0600680
681@uprevs_versioned_package("chromeos-base/chromeos-lacros")
Julio Hurtadof1befec2021-05-05 21:34:26 +0000682def uprev_lacros(_build_targets, refs, chroot):
Alex Klein1699fab2022-09-08 08:46:06 -0600683 """Updates lacros ebuilds.
Julio Hurtadof1befec2021-05-05 21:34:26 +0000684
Alex Klein1699fab2022-09-08 08:46:06 -0600685 Version to uprev to is gathered from the QA qualified version tracking file
Alex Kleinfee86da2023-01-20 18:40:06 -0700686 stored in chromium/src/chrome/LACROS_QA_QUALIFIED_VERSION. Uprev is
687 triggered on modification of this file across all chromium/src branches.
Julio Hurtadof1befec2021-05-05 21:34:26 +0000688
Alex Klein1699fab2022-09-08 08:46:06 -0600689 See: uprev_versioned_package.
690 """
691 result = uprev_lib.UprevVersionedPackageResult()
692 path = os.path.join(
693 constants.CHROMIUMOS_OVERLAY_DIR, "chromeos-base", "chromeos-lacros"
694 )
695 lacros_version = refs[0].revision
696 uprev_result = uprev_lib.uprev_workon_ebuild_to_version(
697 path, lacros_version, chroot, allow_downrev=False
698 )
Julio Hurtadoa994e002021-07-07 17:57:45 +0000699
Alex Klein1699fab2022-09-08 08:46:06 -0600700 if not uprev_result:
701 return result
702
703 result.add_result(lacros_version, uprev_result.changed_files)
Julio Hurtadoa994e002021-07-07 17:57:45 +0000704 return result
705
Julio Hurtadof1befec2021-05-05 21:34:26 +0000706
Alex Klein1699fab2022-09-08 08:46:06 -0600707@uprevs_versioned_package("chromeos-base/chromeos-lacros-parallel")
Julio Hurtado870ed322021-12-03 18:22:40 +0000708def uprev_lacros_in_parallel(
Alex Klein1699fab2022-09-08 08:46:06 -0600709 _build_targets: Optional[List["build_target_lib.BuildTarget"]],
Julio Hurtado870ed322021-12-03 18:22:40 +0000710 refs: List[uprev_lib.GitRef],
Alex Klein1699fab2022-09-08 08:46:06 -0600711 chroot: "chroot_lib.Chroot",
712) -> "uprev_lib.UprevVersionedPackageResult":
713 """Updates lacros ebuilds in parallel with ash-chrome.
Julio Hurtado870ed322021-12-03 18:22:40 +0000714
Alex Kleinfee86da2023-01-20 18:40:06 -0700715 This handler is going to be used temporarily while lacros transitions to
716 being uprevved atomically with ash-chrome. Unlike a standalone lacros uprev,
717 this handler will not need to look at the QA qualified file. Rather, it will
Alex Klein1699fab2022-09-08 08:46:06 -0600718 function identical to ash-chrome using git tags.
Julio Hurtado870ed322021-12-03 18:22:40 +0000719
Alex Klein1699fab2022-09-08 08:46:06 -0600720 See: uprev_versioned_package.
Julio Hurtado870ed322021-12-03 18:22:40 +0000721
Alex Klein1699fab2022-09-08 08:46:06 -0600722 Returns:
Alex Klein348e7692022-10-13 17:03:37 -0600723 UprevVersionedPackageResult: The result.
Alex Klein1699fab2022-09-08 08:46:06 -0600724 """
725 result = uprev_lib.UprevVersionedPackageResult()
726 path = os.path.join(
727 constants.CHROMIUMOS_OVERLAY_DIR, "chromeos-base", "chromeos-lacros"
728 )
729 lacros_version = uprev_lib.get_version_from_refs(refs)
730 uprev_result = uprev_lib.uprev_workon_ebuild_to_version(
731 path, lacros_version, chroot, allow_downrev=False
732 )
Julio Hurtado870ed322021-12-03 18:22:40 +0000733
Alex Klein1699fab2022-09-08 08:46:06 -0600734 if not uprev_result:
735 return result
736
737 result.add_result(lacros_version, uprev_result.changed_files)
Julio Hurtado870ed322021-12-03 18:22:40 +0000738 return result
739
Julio Hurtado870ed322021-12-03 18:22:40 +0000740
Alex Klein1699fab2022-09-08 08:46:06 -0600741@uprevs_versioned_package("app-emulation/parallels-desktop")
Patrick Meiring5897add2020-09-16 16:30:17 +1000742def uprev_parallels_desktop(_build_targets, _refs, chroot):
Alex Klein1699fab2022-09-08 08:46:06 -0600743 """Updates Parallels Desktop ebuild - app-emulation/parallels-desktop.
Patrick Meiring5897add2020-09-16 16:30:17 +1000744
Alex Klein1699fab2022-09-08 08:46:06 -0600745 See: uprev_versioned_package
Patrick Meiring5897add2020-09-16 16:30:17 +1000746
Alex Klein1699fab2022-09-08 08:46:06 -0600747 Returns:
Alex Klein348e7692022-10-13 17:03:37 -0600748 UprevVersionedPackageResult: The result.
Alex Klein1699fab2022-09-08 08:46:06 -0600749 """
750 package = "parallels-desktop"
751 package_path = os.path.join(
752 constants.CHROMEOS_PARTNER_OVERLAY_DIR, "app-emulation", package
753 )
754 version_pin_src_path = _get_version_pin_src_path(package_path)
Patrick Meiring5897add2020-09-16 16:30:17 +1000755
Alex Klein1699fab2022-09-08 08:46:06 -0600756 # Expect a JSON blob like the following:
757 # {
758 # "version": "1.2.3",
759 # "test_image": { "url": "...", "size": 12345678,
760 # "sha256sum": "<32 bytes of hexadecimal>" }
761 # }
Mike Frysinger81a98062023-02-24 15:42:04 -0500762 with open(version_pin_src_path, "r", encoding="utf-8") as f:
Alex Klein1699fab2022-09-08 08:46:06 -0600763 pinned = json.load(f)
Patrick Meiring5897add2020-09-16 16:30:17 +1000764
Alex Klein1699fab2022-09-08 08:46:06 -0600765 if "version" not in pinned or "test_image" not in pinned:
766 raise UprevError(
Trent Aptedb18e36f2023-05-10 15:06:38 +1000767 "VERSION-PIN for %s missing version and/or test_image field"
768 % package
Alex Klein1699fab2022-09-08 08:46:06 -0600769 )
Patrick Meiring5897add2020-09-16 16:30:17 +1000770
Alex Klein1699fab2022-09-08 08:46:06 -0600771 version = pinned["version"]
772 if not isinstance(version, str):
773 raise UprevError("version in VERSION-PIN for %s not a string" % package)
Patrick Meiring5897add2020-09-16 16:30:17 +1000774
Alex Klein1699fab2022-09-08 08:46:06 -0600775 # Update the ebuild.
776 result = uprev_lib.uprev_ebuild_from_pin(package_path, version, chroot)
Patrick Meiring5897add2020-09-16 16:30:17 +1000777
Alex Klein1699fab2022-09-08 08:46:06 -0600778 # Update the VM image used for testing.
779 test_image_path = (
Timothy Loh0cdf15d2023-06-19 17:54:22 +1000780 "src/platform/tast-tests-private/"
Dmitry Torokhov257eba12023-05-30 13:42:48 -0700781 "src/go.chromium.org/tast-tests-private/crosint/"
Alex Klein1699fab2022-09-08 08:46:06 -0600782 "local/bundles/crosint/pita/data/"
783 "pluginvm_image.zip.external"
784 )
785 test_image_src_path = os.path.join(constants.SOURCE_ROOT, test_image_path)
Mike Frysinger81a98062023-02-24 15:42:04 -0500786 with open(test_image_src_path, "w", encoding="utf-8") as f:
Alex Klein1699fab2022-09-08 08:46:06 -0600787 json.dump(pinned["test_image"], f, indent=2)
788 result.add_result(version, [test_image_src_path])
Patrick Meiring5897add2020-09-16 16:30:17 +1000789
Alex Klein1699fab2022-09-08 08:46:06 -0600790 return result
Trent Beginaf51f1b2020-03-09 17:35:31 -0600791
792
Alex Klein1699fab2022-09-08 08:46:06 -0600793@uprevs_versioned_package("chromeos-base/chromeos-dtc-vm")
Trent Beginaf51f1b2020-03-09 17:35:31 -0600794def uprev_sludge(_build_targets, _refs, chroot):
Alex Klein1699fab2022-09-08 08:46:06 -0600795 """Updates sludge VM - chromeos-base/chromeos-dtc-vm.
Trent Begin315d9d92019-12-03 21:55:53 -0700796
Alex Klein1699fab2022-09-08 08:46:06 -0600797 See: uprev_versioned_package.
798 """
799 package = "chromeos-dtc-vm"
800 package_path = os.path.join(
801 "src",
802 "private-overlays",
803 "project-wilco-private",
804 "chromeos-base",
805 package,
806 )
807 version_pin_src_path = _get_version_pin_src_path(package_path)
808 version_no_rev = osutils.ReadFile(version_pin_src_path).strip()
Trent Begin315d9d92019-12-03 21:55:53 -0700809
Alex Klein1699fab2022-09-08 08:46:06 -0600810 return uprev_lib.uprev_ebuild_from_pin(package_path, version_no_rev, chroot)
Trent Begin315d9d92019-12-03 21:55:53 -0700811
812
Alex Klein1699fab2022-09-08 08:46:06 -0600813@uprevs_versioned_package("chromeos-base/borealis-dlc")
David Riley8513c1f2021-10-14 17:07:41 -0700814def uprev_borealis_dlc(_build_targets, _refs, chroot):
Alex Klein1699fab2022-09-08 08:46:06 -0600815 """Updates shared borealis-dlc ebuild - chromeos-base/borealis-dlc.
David Riley8513c1f2021-10-14 17:07:41 -0700816
Alex Klein1699fab2022-09-08 08:46:06 -0600817 See: uprev_versioned_package.
818 """
819 package_path = os.path.join(
820 "src",
821 "private-overlays",
822 "chromeos-partner-overlay",
823 "chromeos-base",
824 "borealis-dlc",
825 )
David Riley8513c1f2021-10-14 17:07:41 -0700826
Alex Klein1699fab2022-09-08 08:46:06 -0600827 version_pin_src_path = _get_version_pin_src_path(package_path)
828 version_no_rev = osutils.ReadFile(version_pin_src_path).strip()
David Riley8513c1f2021-10-14 17:07:41 -0700829
Alex Klein1699fab2022-09-08 08:46:06 -0600830 return uprev_lib.uprev_ebuild_from_pin(package_path, version_no_rev, chroot)
David Riley8513c1f2021-10-14 17:07:41 -0700831
832
Po-Hsien Wang92fb1e52023-04-27 11:35:04 -0700833@uprevs_versioned_package("chromeos-base/borealis-dlc-nvidia")
834def uprev_borealis_dlc_nvidia(_build_targets, _refs, chroot):
Trent Apted380d1c62023-05-16 09:19:31 +1000835 """Updates shared chromeos-base/borealis-dlc-nvidia ebuild.
Po-Hsien Wang92fb1e52023-04-27 11:35:04 -0700836
837 See: uprev_versioned_package.
838 """
839 package_path = os.path.join(
840 "src",
841 "private-overlays",
842 "chromeos-partner-overlay",
843 "chromeos-base",
844 "borealis-dlc-nvidia",
845 )
846
847 version_pin_src_path = _get_version_pin_src_path(package_path)
848 version_no_rev = osutils.ReadFile(version_pin_src_path).strip()
849
850 return uprev_lib.uprev_ebuild_from_pin(package_path, version_no_rev, chroot)
851
852
Syed Faaiz Hussainef29cf82023-06-06 22:14:07 -0700853@uprevs_versioned_package("chromeos-base/borealis-dlc-chroot")
854def uprev_borealis_dlc_chroot(_build_targets, _refs, chroot):
Sergey Frolov8eb38c12023-06-21 19:17:17 -0600855 """Updates shared chromeos-base/borealis-dlc-chroot ebuild.
Syed Faaiz Hussainef29cf82023-06-06 22:14:07 -0700856
857 See: uprev_versioned_package.
858 """
859 package_path = os.path.join(
860 "src",
861 "private-overlays",
862 "chromeos-partner-overlay",
863 "chromeos-base",
864 "borealis-dlc-chroot",
865 )
866
867 version_pin_src_path = _get_version_pin_src_path(package_path)
868 version_no_rev = osutils.ReadFile(version_pin_src_path).strip()
869
870 return uprev_lib.uprev_ebuild_from_pin(package_path, version_no_rev, chroot)
871
872
Patrick Meiring5897add2020-09-16 16:30:17 +1000873def _get_version_pin_src_path(package_path):
Alex Klein1699fab2022-09-08 08:46:06 -0600874 """Returns the path to the VERSION-PIN file for the given package."""
875 return os.path.join(constants.SOURCE_ROOT, package_path, "VERSION-PIN")
Patrick Meiring5897add2020-09-16 16:30:17 +1000876
877
Alex Klein87531182019-08-12 15:23:37 -0600878@uprevs_versioned_package(constants.CHROME_CP)
Alex Klein4e839252022-01-06 13:29:18 -0700879def uprev_chrome_from_ref(build_targets, refs, _chroot):
Alex Klein1699fab2022-09-08 08:46:06 -0600880 """Uprev chrome and its related packages.
Alex Klein87531182019-08-12 15:23:37 -0600881
Alex Klein1699fab2022-09-08 08:46:06 -0600882 See: uprev_versioned_package.
883 """
Alex Kleinfee86da2023-01-20 18:40:06 -0700884 # Determine the version from the refs (tags), i.e. the chrome versions are
885 # the tag names.
Alex Klein1699fab2022-09-08 08:46:06 -0600886 chrome_version = uprev_lib.get_version_from_refs(refs)
887 logging.debug("Chrome version determined from refs: %s", chrome_version)
Alex Klein87531182019-08-12 15:23:37 -0600888
Alex Klein1699fab2022-09-08 08:46:06 -0600889 return uprev_chrome(chrome_version, build_targets, None)
Alex Kleinf69bd802021-06-22 15:43:49 -0600890
891
Alex Klein9ce3f682021-06-23 15:06:44 -0600892def revbump_chrome(
Alex Klein1699fab2022-09-08 08:46:06 -0600893 build_targets: List["build_target_lib.BuildTarget"] = None,
894 chroot: Optional["chroot_lib.Chroot"] = None,
Alex Klein9ce3f682021-06-23 15:06:44 -0600895) -> uprev_lib.UprevVersionedPackageResult:
Alex Klein1699fab2022-09-08 08:46:06 -0600896 """Attempt to revbump chrome.
Alex Kleinf69bd802021-06-22 15:43:49 -0600897
Alex Klein1699fab2022-09-08 08:46:06 -0600898 Revbumps are done by executing an uprev using the current stable version.
899 E.g. if chrome is on 1.2.3.4 and has a 1.2.3.4_rc-r2.ebuild, performing an
900 uprev on version 1.2.3.4 when there are applicable changes (e.g. to the 9999
901 ebuild) will result in a revbump to 1.2.3.4_rc-r3.ebuild.
902 """
903 chrome_version = uprev_lib.get_stable_chrome_version()
904 return uprev_chrome(chrome_version, build_targets, chroot)
Alex Kleinf69bd802021-06-22 15:43:49 -0600905
906
Alex Klein9ce3f682021-06-23 15:06:44 -0600907def uprev_chrome(
Alex Klein16ea1b32021-10-01 15:48:50 -0600908 chrome_version: str,
Alex Klein1699fab2022-09-08 08:46:06 -0600909 build_targets: Optional[List["build_target_lib.BuildTarget"]],
910 chroot: Optional["chroot_lib.Chroot"],
Alex Klein9ce3f682021-06-23 15:06:44 -0600911) -> uprev_lib.UprevVersionedPackageResult:
Alex Klein1699fab2022-09-08 08:46:06 -0600912 """Attempt to uprev chrome and its related packages to the given version."""
913 uprev_manager = uprev_lib.UprevChromeManager(
914 chrome_version, build_targets=build_targets, chroot=chroot
915 )
916 result = uprev_lib.UprevVersionedPackageResult()
917 # TODO(crbug.com/1080429): Handle all possible outcomes of a Chrome uprev
918 # attempt. The expected behavior is documented in the following table:
919 #
920 # Outcome of Chrome uprev attempt:
921 # NEWER_VERSION_EXISTS:
922 # Do nothing.
923 # SAME_VERSION_EXISTS or REVISION_BUMP:
924 # Uprev followers
925 # Assert not VERSION_BUMP (any other outcome is fine)
926 # VERSION_BUMP or NEW_EBUILD_CREATED:
927 # Uprev followers
928 # Assert that Chrome & followers are at same package version
Alex Klein0b2ec2d2021-06-23 15:56:45 -0600929
Alex Klein1699fab2022-09-08 08:46:06 -0600930 # Start with chrome itself so we can proceed accordingly.
931 chrome_result = uprev_manager.uprev(constants.CHROME_CP)
932 if chrome_result.newer_version_exists:
933 # Cannot use the given version (newer version already exists).
934 return result
935
936 # Also uprev related packages.
937 for package in constants.OTHER_CHROME_PACKAGES:
938 follower_result = uprev_manager.uprev(package)
939 if chrome_result.stable_version and follower_result.version_bump:
940 logging.warning(
941 "%s had a version bump, but no more than a revision bump "
942 "should have been possible.",
943 package,
944 )
945
946 if uprev_manager.modified_ebuilds:
947 # Record changes when we have them.
948 return result.add_result(chrome_version, uprev_manager.modified_ebuilds)
949
David Burger37f48672019-09-18 17:07:56 -0600950 return result
Alex Klein87531182019-08-12 15:23:37 -0600951
Alex Klein87531182019-08-12 15:23:37 -0600952
Alex Klein1699fab2022-09-08 08:46:06 -0600953def _get_latest_version_from_refs(
954 refs_prefix: str, refs: List[uprev_lib.GitRef]
955) -> str:
956 """Get the latest version from refs
Alex Klein0b2ec2d2021-06-23 15:56:45 -0600957
Alex Klein1699fab2022-09-08 08:46:06 -0600958 Versions are compared using |distutils.version.LooseVersion| and
959 the latest version is returned.
Alex Klein87531182019-08-12 15:23:37 -0600960
Alex Klein1699fab2022-09-08 08:46:06 -0600961 Args:
Alex Klein348e7692022-10-13 17:03:37 -0600962 refs_prefix: The refs prefix of the tag format.
963 refs: The tags to parse for the latest version.
Alex Klein87531182019-08-12 15:23:37 -0600964
Alex Klein1699fab2022-09-08 08:46:06 -0600965 Returns:
Alex Klein348e7692022-10-13 17:03:37 -0600966 The latest version to use as string.
Alex Klein1699fab2022-09-08 08:46:06 -0600967 """
968 valid_refs = []
969 for gitiles in refs:
970 if gitiles.ref.startswith(refs_prefix):
971 valid_refs.append(gitiles.ref)
Ben Reiche779cf42020-12-15 03:21:31 +0000972
Alex Klein1699fab2022-09-08 08:46:06 -0600973 if not valid_refs:
974 return None
Ben Reiche779cf42020-12-15 03:21:31 +0000975
Alex Klein1699fab2022-09-08 08:46:06 -0600976 # Sort by version and take the latest version.
977 target_version_ref = sorted(valid_refs, key=LooseVersion, reverse=True)[0]
978 return target_version_ref.replace(refs_prefix, "")
Harvey Yang9c61e9c2021-03-02 16:32:43 +0800979
980
Matthias Kaehlckebf7d1772021-11-04 16:01:36 -0700981def _generate_platform_c_files(
982 replication_config: replication_config_pb2.ReplicationConfig,
Alex Klein1699fab2022-09-08 08:46:06 -0600983 chroot: "chroot_lib.Chroot",
984) -> List[str]:
985 """Generates platform C files from a platform JSON payload.
Andrew Lamb9563a152019-12-04 11:42:18 -0700986
Alex Klein1699fab2022-09-08 08:46:06 -0600987 Args:
Alex Klein348e7692022-10-13 17:03:37 -0600988 replication_config: A ReplicationConfig that has already been run. If it
989 produced a build_config.json file, that file will be used to
990 generate platform C files. Otherwise, nothing will be generated.
991 chroot: The chroot to use to generate.
Andrew Lamb9563a152019-12-04 11:42:18 -0700992
Alex Klein1699fab2022-09-08 08:46:06 -0600993 Returns:
Alex Klein348e7692022-10-13 17:03:37 -0600994 A list of generated files.
Alex Klein1699fab2022-09-08 08:46:06 -0600995 """
996 # Generate the platform C files from the build config. Note that it would be
997 # more intuitive to generate the platform C files from the platform config;
Alex Kleinfee86da2023-01-20 18:40:06 -0700998 # however, cros_config_schema does not allow this, because the platform
999 # config payload is not always valid input. For example, if a property is
1000 # both 'required' and 'build-only', it will fail schema validation. Thus,
1001 # use the build config, and use '-f' to filter.
Alex Klein1699fab2022-09-08 08:46:06 -06001002 build_config_path = [
1003 rule.destination_path
1004 for rule in replication_config.file_replication_rules
1005 if rule.destination_path.endswith("build_config.json")
1006 ]
Andrew Lamb9563a152019-12-04 11:42:18 -07001007
Alex Klein1699fab2022-09-08 08:46:06 -06001008 if not build_config_path:
1009 logging.info(
1010 "No build_config.json found, will not generate platform C files. "
1011 "Replication config: %s",
1012 replication_config,
1013 )
1014 return []
Andrew Lamb9563a152019-12-04 11:42:18 -07001015
Alex Klein1699fab2022-09-08 08:46:06 -06001016 if len(build_config_path) > 1:
1017 raise ValueError(
1018 "Expected at most one build_config.json destination path. "
1019 "Replication config: %s" % replication_config
1020 )
Andrew Lamb9563a152019-12-04 11:42:18 -07001021
Alex Klein1699fab2022-09-08 08:46:06 -06001022 build_config_path = build_config_path[0]
Andrew Lamb9563a152019-12-04 11:42:18 -07001023
Alex Klein1699fab2022-09-08 08:46:06 -06001024 # Paths to the build_config.json and dir to output C files to, in the
1025 # chroot.
1026 build_config_chroot_path = os.path.join(
1027 constants.CHROOT_SOURCE_ROOT, build_config_path
1028 )
1029 generated_output_chroot_dir = os.path.join(
1030 constants.CHROOT_SOURCE_ROOT, os.path.dirname(build_config_path)
1031 )
Andrew Lamb9563a152019-12-04 11:42:18 -07001032
Alex Klein1699fab2022-09-08 08:46:06 -06001033 command = [
1034 "cros_config_schema",
1035 "-m",
1036 build_config_chroot_path,
1037 "-g",
1038 generated_output_chroot_dir,
1039 "-f",
1040 '"TRUE"',
1041 ]
Andrew Lamb9563a152019-12-04 11:42:18 -07001042
Alex Klein1699fab2022-09-08 08:46:06 -06001043 cros_build_lib.run(
1044 command, enter_chroot=True, chroot_args=chroot.get_enter_args()
1045 )
Andrew Lamb9563a152019-12-04 11:42:18 -07001046
Alex Klein1699fab2022-09-08 08:46:06 -06001047 # A relative (to the source root) path to the generated C files.
1048 generated_output_dir = os.path.dirname(build_config_path)
1049 generated_files = []
1050 expected_c_files = ["config.c", "ec_config.c", "ec_config.h"]
1051 for f in expected_c_files:
1052 if os.path.exists(
1053 os.path.join(constants.SOURCE_ROOT, generated_output_dir, f)
1054 ):
1055 generated_files.append(os.path.join(generated_output_dir, f))
Andrew Lamb9563a152019-12-04 11:42:18 -07001056
Alex Klein1699fab2022-09-08 08:46:06 -06001057 if len(expected_c_files) != len(generated_files):
1058 raise GeneratedCrosConfigFilesError(expected_c_files, generated_files)
Andrew Lamb9563a152019-12-04 11:42:18 -07001059
Alex Klein1699fab2022-09-08 08:46:06 -06001060 return generated_files
Andrew Lamb9563a152019-12-04 11:42:18 -07001061
1062
Matthias Kaehlckebf7d1772021-11-04 16:01:36 -07001063def _get_private_overlay_package_root(ref: uprev_lib.GitRef, package: str):
Alex Klein1699fab2022-09-08 08:46:06 -06001064 """Returns the absolute path to the root of a given private overlay.
Andrew Lambe836f222019-12-09 12:27:38 -07001065
Alex Klein1699fab2022-09-08 08:46:06 -06001066 Args:
Alex Klein348e7692022-10-13 17:03:37 -06001067 ref: GitRef for the private overlay.
1068 package: Path to the package in the overlay.
Alex Klein1699fab2022-09-08 08:46:06 -06001069 """
1070 # There might be a cleaner way to map from package -> path within the source
1071 # tree. For now, just use string patterns.
1072 private_overlay_ref_pattern = (
1073 r"/chromeos\/overlays\/overlay-([\w-]+)-private"
1074 )
1075 match = re.match(private_overlay_ref_pattern, ref.path)
1076 if not match:
1077 raise ValueError(
1078 "ref.path must match the pattern: %s. Actual ref: %s"
1079 % (private_overlay_ref_pattern, ref)
1080 )
Andrew Lambe836f222019-12-09 12:27:38 -07001081
Alex Klein1699fab2022-09-08 08:46:06 -06001082 overlay = match.group(1)
Andrew Lambe836f222019-12-09 12:27:38 -07001083
Alex Klein1699fab2022-09-08 08:46:06 -06001084 return os.path.join(
1085 constants.SOURCE_ROOT,
1086 "src/private-overlays/overlay-%s-private" % overlay,
1087 package,
1088 )
Andrew Lambe836f222019-12-09 12:27:38 -07001089
1090
Alex Klein1699fab2022-09-08 08:46:06 -06001091@uprevs_versioned_package("chromeos-base/chromeos-config-bsp")
Andrew Lambea9a8a22019-12-12 14:03:43 -07001092def replicate_private_config(_build_targets, refs, chroot):
Alex Kleinfee86da2023-01-20 18:40:06 -07001093 """Replicate private cros_config change to the corresponding public config.
Andrew Lamb2bde9e42019-11-04 13:24:09 -07001094
Alex Klein1699fab2022-09-08 08:46:06 -06001095 See uprev_versioned_package for args
1096 """
1097 package = "chromeos-base/chromeos-config-bsp"
Andrew Lambea9a8a22019-12-12 14:03:43 -07001098
Alex Klein1699fab2022-09-08 08:46:06 -06001099 if len(refs) != 1:
1100 raise ValueError("Expected exactly one ref, actual %s" % refs)
Andrew Lamb2bde9e42019-11-04 13:24:09 -07001101
Alex Klein1699fab2022-09-08 08:46:06 -06001102 # Expect a replication_config.jsonpb in the package root.
1103 package_root = _get_private_overlay_package_root(refs[0], package)
1104 replication_config_path = os.path.join(
1105 package_root, "replication_config.jsonpb"
1106 )
Andrew Lamb2bde9e42019-11-04 13:24:09 -07001107
Alex Klein1699fab2022-09-08 08:46:06 -06001108 try:
1109 replication_config = json_format.Parse(
1110 osutils.ReadFile(replication_config_path),
1111 replication_config_pb2.ReplicationConfig(),
1112 )
1113 except IOError:
1114 raise ValueError(
1115 "Expected ReplicationConfig missing at %s" % replication_config_path
1116 )
Andrew Lamb2bde9e42019-11-04 13:24:09 -07001117
Alex Klein1699fab2022-09-08 08:46:06 -06001118 replication_lib.Replicate(replication_config)
Andrew Lamb2bde9e42019-11-04 13:24:09 -07001119
Alex Klein1699fab2022-09-08 08:46:06 -06001120 modified_files = [
1121 rule.destination_path
1122 for rule in replication_config.file_replication_rules
1123 ]
Andrew Lamb2bde9e42019-11-04 13:24:09 -07001124
Alex Kleinfee86da2023-01-20 18:40:06 -07001125 # The generated platform C files are not easily filtered by replication
1126 # rules, i.e. JSON / proto filtering can be described by a FieldMask,
1127 # arbitrary C files cannot. Therefore, replicate and filter the JSON
1128 # payloads, and then generate filtered C files from the JSON payload.
Alex Klein1699fab2022-09-08 08:46:06 -06001129 modified_files.extend(
1130 _generate_platform_c_files(replication_config, chroot)
1131 )
Andrew Lamb2bde9e42019-11-04 13:24:09 -07001132
Alex Klein1699fab2022-09-08 08:46:06 -06001133 # Use the private repo's commit hash as the new version.
1134 new_private_version = refs[0].revision
Andrew Lamb2bde9e42019-11-04 13:24:09 -07001135
Alex Klein1699fab2022-09-08 08:46:06 -06001136 # modified_files should contain only relative paths at this point, but the
1137 # returned UprevVersionedPackageResult must contain only absolute paths.
1138 for i, modified_file in enumerate(modified_files):
1139 assert not os.path.isabs(modified_file)
1140 modified_files[i] = os.path.join(constants.SOURCE_ROOT, modified_file)
Andrew Lamb988f4da2019-12-10 10:16:43 -07001141
Alex Klein1699fab2022-09-08 08:46:06 -06001142 return uprev_lib.UprevVersionedPackageResult().add_result(
1143 new_private_version, modified_files
1144 )
Andrew Lamb2bde9e42019-11-04 13:24:09 -07001145
1146
Alex Klein1699fab2022-09-08 08:46:06 -06001147@uprevs_versioned_package("chromeos-base/crosvm")
Dennis Kempinef05f2b2021-09-08 16:36:49 -07001148def uprev_crosvm(_build_targets, refs, _chroot):
Alex Klein1699fab2022-09-08 08:46:06 -06001149 """Updates crosvm ebuilds to latest revision
Dennis Kempinef05f2b2021-09-08 16:36:49 -07001150
Alex Klein1699fab2022-09-08 08:46:06 -06001151 crosvm is not versioned. We are updating to the latest commit on the main
1152 branch.
Dennis Kempinef05f2b2021-09-08 16:36:49 -07001153
Alex Klein1699fab2022-09-08 08:46:06 -06001154 See: uprev_versioned_package.
Dennis Kempinef05f2b2021-09-08 16:36:49 -07001155
Alex Klein1699fab2022-09-08 08:46:06 -06001156 Returns:
Alex Klein348e7692022-10-13 17:03:37 -06001157 UprevVersionedPackageResult: The result of updating crosvm ebuilds.
Alex Klein1699fab2022-09-08 08:46:06 -06001158 """
1159 overlay = os.path.join(
1160 constants.SOURCE_ROOT, constants.CHROMIUMOS_OVERLAY_DIR
1161 )
1162 repo_path = os.path.join(constants.SOURCE_ROOT, "src", "crosvm")
1163 manifest = git.ManifestCheckout.Cached(repo_path)
Dennis Kempinef05f2b2021-09-08 16:36:49 -07001164
Alex Klein1699fab2022-09-08 08:46:06 -06001165 uprev_manager = uprev_lib.UprevOverlayManager([overlay], manifest)
1166 uprev_manager.uprev(
1167 package_list=[
1168 "chromeos-base/crosvm",
1169 "dev-rust/assertions",
1170 "dev-rust/cros_async",
1171 "dev-rust/cros_fuzz",
1172 "dev-rust/data_model",
1173 "dev-rust/enumn",
1174 "dev-rust/io_uring",
1175 "dev-rust/p9",
1176 "dev-rust/sync",
1177 "dev-rust/sys_util",
1178 "dev-rust/tempfile",
1179 "media-sound/audio_streams",
1180 ],
1181 force=True,
1182 )
Dennis Kempinef05f2b2021-09-08 16:36:49 -07001183
Alex Klein1699fab2022-09-08 08:46:06 -06001184 updated_files = uprev_manager.modified_ebuilds
1185 result = uprev_lib.UprevVersionedPackageResult()
1186 result.add_result(refs[0].revision, updated_files)
1187 return result
Dennis Kempinef05f2b2021-09-08 16:36:49 -07001188
1189
Yi Choua4854ac2022-11-14 10:54:24 +08001190@uprevs_versioned_package("chromeos-base/ti50-emulator")
1191def uprev_ti50_emulator(_build_targets, refs, _chroot):
1192 """Updates ti50-emulator ebuilds to latest revision
1193
1194 ti50-emulator is not versioned. We are updating to the latest commit on the
1195 main branch.
1196
1197 See: uprev_versioned_package.
1198
1199 Returns:
1200 UprevVersionedPackageResult: The result of updating ti50-emulator
Trent Aptedb18e36f2023-05-10 15:06:38 +10001201 ebuild.
Yi Choua4854ac2022-11-14 10:54:24 +08001202 """
1203 overlay = os.path.join(
1204 constants.SOURCE_ROOT, constants.CHROMEOS_OVERLAY_DIR
1205 )
1206
1207 # The ti50-emulator will touch multiple repos.
1208 manifest = git.ManifestCheckout.Cached(constants.SOURCE_ROOT)
1209
1210 uprev_manager = uprev_lib.UprevOverlayManager([overlay], manifest)
1211 uprev_manager.uprev(
1212 package_list=["chromeos-base/ti50-emulator"],
1213 force=True,
1214 )
1215
1216 updated_files = uprev_manager.modified_ebuilds
1217 result = uprev_lib.UprevVersionedPackageResult()
1218 result.add_result(refs[-1].revision, updated_files)
1219 return result
1220
1221
Jeremy Bettisaf96afb2023-01-11 16:09:58 -07001222@uprevs_versioned_package("chromeos-base/ec-devutils")
Jeremy Bettis0186d252023-01-19 14:47:46 -07001223def uprev_ecdevutils(_build_targets, refs, _chroot):
1224 """Updates ec-devutils ebuilds to latest revision
1225
Alex Kleinfee86da2023-01-20 18:40:06 -07001226 ec-devutils is not versioned. We are updating to the latest commit on the
1227 main branch.
Jeremy Bettis0186d252023-01-19 14:47:46 -07001228
1229 See: uprev_versioned_package.
1230
1231 Returns:
1232 UprevVersionedPackageResult: The result of updating ec-devutils ebuilds.
1233 """
1234 overlay = os.path.join(
1235 constants.SOURCE_ROOT, constants.CHROMIUMOS_OVERLAY_DIR
1236 )
1237 repo_path = os.path.join(constants.SOURCE_ROOT, "src", "platform", "ec")
1238 manifest = git.ManifestCheckout.Cached(repo_path)
1239
1240 uprev_manager = uprev_lib.UprevOverlayManager([overlay], manifest)
1241 uprev_manager.uprev(
1242 package_list=[
1243 "chromeos-base/ec-devutils",
1244 ],
1245 force=True,
1246 )
1247
1248 updated_files = uprev_manager.modified_ebuilds
1249 result = uprev_lib.UprevVersionedPackageResult()
1250 result.add_result(refs[0].revision, updated_files)
1251 return result
1252
1253
Jeremy Bettisaf96afb2023-01-11 16:09:58 -07001254@uprevs_versioned_package("chromeos-base/ec-utils")
Jeremy Bettisaf96afb2023-01-11 16:09:58 -07001255def uprev_ecutils(_build_targets, refs, _chroot):
1256 """Updates ec-utils ebuilds to latest revision
1257
1258 ec-utils is not versioned. We are updating to the latest commit on the main
1259 branch.
1260
1261 See: uprev_versioned_package.
1262
1263 Returns:
1264 UprevVersionedPackageResult: The result of updating ec-utils ebuilds.
1265 """
1266 overlay = os.path.join(
1267 constants.SOURCE_ROOT, constants.CHROMIUMOS_OVERLAY_DIR
1268 )
1269 repo_path = os.path.join(constants.SOURCE_ROOT, "src", "platform", "ec")
1270 manifest = git.ManifestCheckout.Cached(repo_path)
1271
1272 uprev_manager = uprev_lib.UprevOverlayManager([overlay], manifest)
1273 uprev_manager.uprev(
1274 package_list=[
Jeremy Bettisaf96afb2023-01-11 16:09:58 -07001275 "chromeos-base/ec-utils",
Jeremy Bettis0186d252023-01-19 14:47:46 -07001276 ],
1277 force=True,
1278 )
1279
1280 updated_files = uprev_manager.modified_ebuilds
1281 result = uprev_lib.UprevVersionedPackageResult()
1282 result.add_result(refs[0].revision, updated_files)
1283 return result
1284
1285
1286@uprevs_versioned_package("chromeos-base/ec-utils-test")
1287def uprev_ecutilstest(_build_targets, refs, _chroot):
1288 """Updates ec-utils-test ebuilds to latest revision
1289
Alex Kleinfee86da2023-01-20 18:40:06 -07001290 ec-utils-test is not versioned. We are updating to the latest commit on the
1291 main branch.
Jeremy Bettis0186d252023-01-19 14:47:46 -07001292
1293 See: uprev_versioned_package.
1294
1295 Returns:
Alex Kleinfee86da2023-01-20 18:40:06 -07001296 UprevVersionedPackageResult: The result of updating ec-utils-test
Trent Aptedb18e36f2023-05-10 15:06:38 +10001297 ebuilds.
Jeremy Bettis0186d252023-01-19 14:47:46 -07001298 """
1299 overlay = os.path.join(
1300 constants.SOURCE_ROOT, constants.CHROMIUMOS_OVERLAY_DIR
1301 )
1302 repo_path = os.path.join(constants.SOURCE_ROOT, "src", "platform", "ec")
1303 manifest = git.ManifestCheckout.Cached(repo_path)
1304
1305 uprev_manager = uprev_lib.UprevOverlayManager([overlay], manifest)
1306 uprev_manager.uprev(
1307 package_list=[
Jeremy Bettisaf96afb2023-01-11 16:09:58 -07001308 "chromeos-base/ec-utils-test",
1309 ],
1310 force=True,
1311 )
1312
1313 updated_files = uprev_manager.modified_ebuilds
1314 result = uprev_lib.UprevVersionedPackageResult()
1315 result.add_result(refs[0].revision, updated_files)
1316 return result
1317
1318
Alex Klein5caab872021-09-10 11:44:37 -06001319def get_best_visible(
Alex Klein1699fab2022-09-08 08:46:06 -06001320 atom: str, build_target: Optional["build_target_lib.BuildTarget"] = None
Alex Klein5caab872021-09-10 11:44:37 -06001321) -> package_info.PackageInfo:
Alex Klein1699fab2022-09-08 08:46:06 -06001322 """Returns the best visible CPV for the given atom.
Alex Kleinbbef2b32019-08-27 10:38:50 -06001323
Alex Klein1699fab2022-09-08 08:46:06 -06001324 Args:
Alex Klein348e7692022-10-13 17:03:37 -06001325 atom: The atom to look up.
1326 build_target: The build target whose sysroot should be searched, or the
1327 SDK if not provided.
Alex Kleinad6b48a2020-01-08 16:57:41 -07001328
Alex Klein1699fab2022-09-08 08:46:06 -06001329 Returns:
Alex Klein348e7692022-10-13 17:03:37 -06001330 The best visible package, or None if none are visible.
Alex Klein1699fab2022-09-08 08:46:06 -06001331 """
1332 assert atom
Alex Kleinbbef2b32019-08-27 10:38:50 -06001333
Alex Klein1699fab2022-09-08 08:46:06 -06001334 return portage_util.PortageqBestVisible(
1335 atom,
1336 board=build_target.name if build_target else None,
1337 sysroot=build_target.root if build_target else None,
1338 )
Alex Kleinda39c6d2019-09-16 14:36:36 -06001339
1340
Matthias Kaehlckebf7d1772021-11-04 16:01:36 -07001341def has_prebuilt(
1342 atom: str,
Alex Klein1699fab2022-09-08 08:46:06 -06001343 build_target: "build_target_lib.BuildTarget" = None,
1344 useflags: Union[Iterable[str], str] = None,
1345) -> bool:
1346 """Check if a prebuilt exists.
Alex Kleinda39c6d2019-09-16 14:36:36 -06001347
Alex Klein1699fab2022-09-08 08:46:06 -06001348 Args:
Alex Klein348e7692022-10-13 17:03:37 -06001349 atom: The package whose prebuilt is being queried.
1350 build_target: The build target whose sysroot should be searched, or the
1351 SDK if not provided.
1352 useflags: Any additional USE flags that should be set. May be a string
1353 of properly formatted USE flags, or an iterable of individual flags.
Alex Kleinad6b48a2020-01-08 16:57:41 -07001354
Alex Klein1699fab2022-09-08 08:46:06 -06001355 Returns:
Alex Klein348e7692022-10-13 17:03:37 -06001356 True if there is an available prebuilt, False otherwise.
Alex Klein1699fab2022-09-08 08:46:06 -06001357 """
1358 assert atom
Alex Kleinda39c6d2019-09-16 14:36:36 -06001359
Alex Klein1699fab2022-09-08 08:46:06 -06001360 board = build_target.name if build_target else None
1361 extra_env = None
1362 if useflags:
1363 new_flags = useflags
1364 if not isinstance(useflags, str):
1365 new_flags = " ".join(useflags)
Alex Klein149fd3b2019-12-16 16:01:05 -07001366
Alex Klein1699fab2022-09-08 08:46:06 -06001367 existing = os.environ.get("USE", "")
1368 final_flags = "%s %s" % (existing, new_flags)
1369 extra_env = {"USE": final_flags.strip()}
1370 return portage_util.HasPrebuilt(atom, board=board, extra_env=extra_env)
Alex Klein36b117f2019-09-30 15:13:46 -06001371
1372
David Burger0f9dd4e2019-10-08 12:33:42 -06001373def builds(atom, build_target, packages=None):
Alex Klein1699fab2022-09-08 08:46:06 -06001374 """Check if |build_target| builds |atom| (has it in its depgraph)."""
1375 cros_build_lib.AssertInsideChroot()
Alex Klein36b117f2019-09-30 15:13:46 -06001376
Alex Klein1699fab2022-09-08 08:46:06 -06001377 pkgs = tuple(packages) if packages else None
1378 # TODO(crbug/1081828): Receive and use sysroot.
1379 graph, _sdk_graph = dependency.GetBuildDependency(
1380 build_target.root, build_target.name, pkgs
1381 )
1382 return any(atom in package for package in graph["package_deps"])
Michael Mortensenb70e8a82019-10-10 18:43:41 -06001383
1384
Alex Klein6becabc2020-09-11 14:03:05 -06001385def needs_chrome_source(
Alex Klein1699fab2022-09-08 08:46:06 -06001386 build_target: "build_target_lib.BuildTarget",
Alex Klein6becabc2020-09-11 14:03:05 -06001387 compile_source=False,
1388 packages: Optional[List[package_info.PackageInfo]] = None,
Alex Klein1699fab2022-09-08 08:46:06 -06001389 useflags=None,
1390):
1391 """Check if the chrome source is needed.
Alex Klein6becabc2020-09-11 14:03:05 -06001392
Alex Klein1699fab2022-09-08 08:46:06 -06001393 The chrome source is needed if the build target builds chrome or any of its
1394 follower packages, and can't use a prebuilt for them either because it's not
1395 available, or because we can't use prebuilts because it must build from
1396 source.
1397 """
1398 cros_build_lib.AssertInsideChroot()
Alex Klein6becabc2020-09-11 14:03:05 -06001399
Sergey Frolov8eb38c12023-06-21 19:17:17 -06001400 # Find latest chrome PackageInfo.
1401 try:
1402 chrome_pi = portage_util.PortageqBestVisible(
1403 constants.CHROME_CP, board=build_target.name
1404 )
1405 chrome_cpvr = chrome_pi.cpvr
1406 except (portage_util.NoVisiblePackageError, package_info.ParseTypeError):
1407 chrome_cpvr = constants.CHROME_CP
1408
Alex Klein1699fab2022-09-08 08:46:06 -06001409 # Check if it builds chrome and/or a follower package.
1410 graph = depgraph.get_sysroot_dependency_graph(build_target.root, packages)
1411 builds_chrome = constants.CHROME_CP in graph
1412 builds_follower = {
1413 pkg: pkg in graph for pkg in constants.OTHER_CHROME_PACKAGES
1414 }
Alex Klein6becabc2020-09-11 14:03:05 -06001415
Alex Klein1699fab2022-09-08 08:46:06 -06001416 local_uprev = builds_chrome and revbump_chrome([build_target])
Alex Klein9ce3f682021-06-23 15:06:44 -06001417
Alex Kleinfee86da2023-01-20 18:40:06 -07001418 # When we are compiling source set False since we do not use prebuilts. When
1419 # not compiling from source, start with True, i.e. we have every prebuilt
Alex Klein1699fab2022-09-08 08:46:06 -06001420 # we've checked for up to this point.
1421 has_chrome_prebuilt = not compile_source
1422 has_follower_prebuilts = not compile_source
1423 # Save packages that need prebuilts for reporting.
1424 pkgs_needing_prebuilts = []
1425 if compile_source:
1426 # Need everything.
Sergey Frolov8eb38c12023-06-21 19:17:17 -06001427 pkgs_needing_prebuilts.append(chrome_cpvr)
Alex Klein1699fab2022-09-08 08:46:06 -06001428 pkgs_needing_prebuilts.extend(
1429 [pkg for pkg, builds_pkg in builds_follower.items() if builds_pkg]
1430 )
1431 else:
1432 # Check chrome itself.
1433 if builds_chrome:
1434 has_chrome_prebuilt = has_prebuilt(
Sergey Frolov8eb38c12023-06-21 19:17:17 -06001435 chrome_cpvr,
Alex Klein1699fab2022-09-08 08:46:06 -06001436 build_target=build_target,
1437 useflags=useflags,
1438 )
1439 if not has_chrome_prebuilt:
Sergey Frolov8eb38c12023-06-21 19:17:17 -06001440 pkgs_needing_prebuilts.append(chrome_cpvr)
Alex Klein1699fab2022-09-08 08:46:06 -06001441 # Check follower packages.
1442 for pkg, builds_pkg in builds_follower.items():
1443 if not builds_pkg:
1444 continue
1445 prebuilt = has_prebuilt(
1446 pkg, build_target=build_target, useflags=useflags
1447 )
1448 has_follower_prebuilts &= prebuilt
1449 if not prebuilt:
1450 pkgs_needing_prebuilts.append(pkg)
Alex Kleinfee86da2023-01-20 18:40:06 -07001451 # Postcondition: has_chrome_prebuilt and has_follower_prebuilts now
1452 # correctly reflect whether we actually have the corresponding prebuilts for
1453 # the build.
Alex Klein6becabc2020-09-11 14:03:05 -06001454
Alex Klein1699fab2022-09-08 08:46:06 -06001455 needs_chrome = builds_chrome and not has_chrome_prebuilt
1456 needs_follower = (
1457 any(builds_follower.values()) and not has_follower_prebuilts
1458 )
Alex Klein6becabc2020-09-11 14:03:05 -06001459
Alex Klein1699fab2022-09-08 08:46:06 -06001460 return NeedsChromeSourceResult(
1461 needs_chrome_source=needs_chrome or needs_follower,
1462 builds_chrome=builds_chrome,
1463 packages=[package_info.parse(p) for p in pkgs_needing_prebuilts],
1464 missing_chrome_prebuilt=not has_chrome_prebuilt,
1465 missing_follower_prebuilt=not has_follower_prebuilts,
1466 local_uprev=local_uprev,
1467 )
Alex Klein6becabc2020-09-11 14:03:05 -06001468
1469
Alex Klein68a28712021-11-08 11:08:30 -07001470class TargetVersions(NamedTuple):
Alex Klein1699fab2022-09-08 08:46:06 -06001471 """Data class for the info that makes up the "target versions"."""
1472
1473 android_version: str
1474 android_branch: str
1475 android_target: str
1476 chrome_version: str
1477 platform_version: str
1478 milestone_version: str
1479 full_version: str
Gilberto Contreras4f2d1452023-01-30 23:22:58 +00001480 lacros_version: str
Alex Klein68a28712021-11-08 11:08:30 -07001481
1482
1483def get_target_versions(
Alex Klein1699fab2022-09-08 08:46:06 -06001484 build_target: "build_target_lib.BuildTarget",
1485 packages: List[package_info.PackageInfo] = None,
Alex Klein68a28712021-11-08 11:08:30 -07001486) -> TargetVersions:
Alex Klein1699fab2022-09-08 08:46:06 -06001487 """Aggregate version info for a few key packages and the OS as a whole."""
1488 # Android version.
1489 android_version = determine_android_version(build_target.name)
1490 logging.info("Found android version: %s", android_version)
1491 # Android branch version.
1492 android_branch = determine_android_branch(build_target.name)
1493 logging.info("Found android branch version: %s", android_branch)
1494 # Android target version.
1495 android_target = determine_android_target(build_target.name)
1496 logging.info("Found android target version: %s", android_target)
Alex Klein68a28712021-11-08 11:08:30 -07001497
Alex Klein1699fab2022-09-08 08:46:06 -06001498 # TODO(crbug/1019770): Investigate cases where builds_chrome is true but
1499 # chrome_version is None.
Alex Klein68a28712021-11-08 11:08:30 -07001500
Alex Klein1699fab2022-09-08 08:46:06 -06001501 builds_chrome = builds(constants.CHROME_CP, build_target, packages=packages)
1502 chrome_version = None
1503 if builds_chrome:
1504 # Chrome version fetch.
Gilberto Contreras4f2d1452023-01-30 23:22:58 +00001505 chrome_version = determine_package_version(
1506 constants.CHROME_CP, build_target
1507 )
Alex Klein1699fab2022-09-08 08:46:06 -06001508 logging.info("Found chrome version: %s", chrome_version)
Alex Klein68a28712021-11-08 11:08:30 -07001509
Gilberto Contreras4f2d1452023-01-30 23:22:58 +00001510 builds_lacros = builds(constants.LACROS_CP, build_target, packages=packages)
1511 lacros_version = None
1512 if builds_lacros:
1513 # LaCrOS version fetch.
1514 lacros_version = determine_package_version(
1515 constants.LACROS_CP, build_target
1516 )
1517 logging.info("Found LaCrOS version: %s", lacros_version)
1518
Alex Klein1699fab2022-09-08 08:46:06 -06001519 # The ChromeOS version info.
1520 platform_version = determine_platform_version()
1521 milestone_version = determine_milestone_version()
1522 full_version = determine_full_version()
Alex Klein68a28712021-11-08 11:08:30 -07001523
Alex Klein1699fab2022-09-08 08:46:06 -06001524 return TargetVersions(
1525 android_version,
1526 android_branch,
1527 android_target,
1528 chrome_version,
1529 platform_version,
1530 milestone_version,
1531 full_version,
Gilberto Contreras4f2d1452023-01-30 23:22:58 +00001532 lacros_version,
Alex Klein1699fab2022-09-08 08:46:06 -06001533 )
Alex Klein68a28712021-11-08 11:08:30 -07001534
1535
Gilberto Contreras4f2d1452023-01-30 23:22:58 +00001536def determine_package_version(
1537 cpv_name: str,
Alex Klein1699fab2022-09-08 08:46:06 -06001538 build_target: "build_target_lib.BuildTarget",
1539) -> Optional[str]:
Gilberto Contreras4f2d1452023-01-30 23:22:58 +00001540 """Returns the current package version for the board (or in buildroot).
Michael Mortensenc2615b72019-10-15 08:12:24 -06001541
Alex Klein1699fab2022-09-08 08:46:06 -06001542 Args:
Gilberto Contreras4f2d1452023-01-30 23:22:58 +00001543 cpv_name: the name of the ebuild CPV
Alex Klein348e7692022-10-13 17:03:37 -06001544 build_target: The board build target.
Alex Kleinad6b48a2020-01-08 16:57:41 -07001545
Alex Klein1699fab2022-09-08 08:46:06 -06001546 Returns:
Gilberto Contreras4f2d1452023-01-30 23:22:58 +00001547 The version of the package, if available.
Alex Klein1699fab2022-09-08 08:46:06 -06001548 """
1549 # TODO(crbug/1019770): Long term we should not need the try/catch here once
1550 # the builds function above only returns True for chrome when
1551 # determine_chrome_version will succeed.
1552 try:
1553 pkg_info = portage_util.PortageqBestVisible(
Gilberto Contreras4f2d1452023-01-30 23:22:58 +00001554 cpv_name, build_target.name, cwd=constants.SOURCE_ROOT
Alex Klein1699fab2022-09-08 08:46:06 -06001555 )
1556 except cros_build_lib.RunCommandError as e:
1557 # Return None because portage failed when trying to determine the chrome
1558 # version.
1559 logging.warning("Caught exception in determine_chrome_package: %s", e)
1560 return None
1561 # Something like 78.0.3877.4_rc -> 78.0.3877.4
1562 return pkg_info.version.partition("_")[0]
Michael Mortensenc2615b72019-10-15 08:12:24 -06001563
1564
Alex Klein68a28712021-11-08 11:08:30 -07001565@functools.lru_cache()
Matthias Kaehlckebf7d1772021-11-04 16:01:36 -07001566def determine_android_package(board: str) -> Optional[str]:
Alex Klein1699fab2022-09-08 08:46:06 -06001567 """Returns the active Android container package in use by the board.
Michael Mortensenb70e8a82019-10-10 18:43:41 -06001568
Alex Klein1699fab2022-09-08 08:46:06 -06001569 Args:
Alex Klein348e7692022-10-13 17:03:37 -06001570 board: The board name this is specific to.
Alex Kleinad6b48a2020-01-08 16:57:41 -07001571
Alex Klein1699fab2022-09-08 08:46:06 -06001572 Returns:
Alex Klein348e7692022-10-13 17:03:37 -06001573 The android package string if there is one.
Alex Klein1699fab2022-09-08 08:46:06 -06001574 """
1575 try:
1576 packages = portage_util.GetPackageDependencies(
1577 "virtual/target-os", board=board
1578 )
1579 except cros_build_lib.RunCommandError as e:
1580 # Return None because a command (likely portage) failed when trying to
1581 # determine the package.
1582 logging.warning("Caught exception in determine_android_package: %s", e)
1583 return None
1584
1585 # We assume there is only one Android package in the depgraph.
1586 for package in packages:
1587 if package.startswith(
1588 "chromeos-base/android-container-"
1589 ) or package.startswith("chromeos-base/android-vm-"):
1590 return package
Michael Mortensene0f4b542019-10-24 15:30:23 -06001591 return None
Michael Mortensenb70e8a82019-10-10 18:43:41 -06001592
1593
Matthias Kaehlckebf7d1772021-11-04 16:01:36 -07001594def determine_android_version(board: str, package: str = None):
Alex Klein1699fab2022-09-08 08:46:06 -06001595 """Determine the current Android version in buildroot now and return it.
Michael Mortensenb70e8a82019-10-10 18:43:41 -06001596
Alex Klein1699fab2022-09-08 08:46:06 -06001597 This uses the typical portage logic to determine which version of Android
1598 is active right now in the buildroot.
Michael Mortensenb70e8a82019-10-10 18:43:41 -06001599
Alex Klein1699fab2022-09-08 08:46:06 -06001600 Args:
Alex Klein348e7692022-10-13 17:03:37 -06001601 board: The board name this is specific to.
1602 package: The Android package, if already computed.
Michael Mortensenb70e8a82019-10-10 18:43:41 -06001603
Alex Klein1699fab2022-09-08 08:46:06 -06001604 Returns:
Alex Klein348e7692022-10-13 17:03:37 -06001605 The Android build ID of the container for the board.
Michael Mortensenb70e8a82019-10-10 18:43:41 -06001606
Alex Klein1699fab2022-09-08 08:46:06 -06001607 Raises:
Alex Klein348e7692022-10-13 17:03:37 -06001608 NoAndroidVersionError: if no unique Android version can be determined.
Alex Klein1699fab2022-09-08 08:46:06 -06001609 """
1610 if not package:
1611 package = determine_android_package(board)
1612 if not package:
1613 return None
Alex Klein7bd88b12023-05-19 15:39:55 -06001614 cpv = package_info.parse(package)
Alex Klein1699fab2022-09-08 08:46:06 -06001615 if not cpv:
1616 raise NoAndroidVersionError(
1617 "Android version could not be determined for %s" % board
1618 )
Alex Klein7bd88b12023-05-19 15:39:55 -06001619 return cpv.version
Michael Mortensenb70e8a82019-10-10 18:43:41 -06001620
Alex Klein7a3a7dd2020-01-08 16:44:38 -07001621
Mike Frysinger8e1c99a2021-03-05 00:58:11 -05001622def determine_android_branch(board, package=None):
Alex Klein1699fab2022-09-08 08:46:06 -06001623 """Returns the Android branch in use by the active container ebuild."""
1624 if not package:
1625 package = determine_android_package(board)
1626 if not package:
1627 return None
1628 ebuild_path = portage_util.FindEbuildForBoardPackage(package, board)
1629 # We assume all targets pull from the same branch and that we always
1630 # have at least one of the following targets.
Shao-Chuan Leeca2cbcc2022-11-02 08:28:31 +09001631 # TODO(b/187795671): Do this in a less hacky way.
1632 targets = android.GetAllAndroidEbuildTargets()
Alex Klein1699fab2022-09-08 08:46:06 -06001633 ebuild_content = osutils.SourceEnvironment(ebuild_path, targets)
1634 for target in targets:
1635 if target in ebuild_content:
1636 branch = re.search(r"(.*?)-linux-", ebuild_content[target])
1637 if branch is not None:
1638 return branch.group(1)
1639 raise NoAndroidBranchError(
1640 "Android branch could not be determined for %s (ebuild empty?)" % board
1641 )
Michael Mortensenb70e8a82019-10-10 18:43:41 -06001642
1643
Mike Frysinger8e1c99a2021-03-05 00:58:11 -05001644def determine_android_target(board, package=None):
Alex Klein1699fab2022-09-08 08:46:06 -06001645 """Returns the Android target in use by the active container ebuild."""
1646 if not package:
1647 package = determine_android_package(board)
1648 if not package:
1649 return None
1650 if package.startswith("chromeos-base/android-vm-"):
1651 return "bertha"
1652 elif package.startswith("chromeos-base/android-container-"):
1653 return "cheets"
Michael Mortensenb70e8a82019-10-10 18:43:41 -06001654
Alex Klein1699fab2022-09-08 08:46:06 -06001655 raise NoAndroidTargetError(
1656 "Android Target cannot be determined for the package: %s" % package
1657 )
Michael Mortensen9fdb14b2019-10-17 11:17:30 -06001658
1659
1660def determine_platform_version():
Alex Klein1699fab2022-09-08 08:46:06 -06001661 """Returns the platform version from the source root."""
1662 # Platform version is something like '12575.0.0'.
1663 version = chromeos_version.VersionInfo.from_repo(constants.SOURCE_ROOT)
1664 return version.VersionString()
Michael Mortensen009cb662019-10-21 11:38:43 -06001665
1666
1667def determine_milestone_version():
Alex Klein1699fab2022-09-08 08:46:06 -06001668 """Returns the platform version from the source root."""
1669 # Milestone version is something like '79'.
1670 version = chromeos_version.VersionInfo.from_repo(constants.SOURCE_ROOT)
1671 return version.chrome_branch
Michael Mortensen009cb662019-10-21 11:38:43 -06001672
Alex Klein7a3a7dd2020-01-08 16:44:38 -07001673
Michael Mortensen009cb662019-10-21 11:38:43 -06001674def determine_full_version():
Alex Klein1699fab2022-09-08 08:46:06 -06001675 """Returns the full version from the source root."""
1676 # Full version is something like 'R79-12575.0.0'.
1677 milestone_version = determine_milestone_version()
1678 platform_version = determine_platform_version()
1679 full_version = "R%s-%s" % (milestone_version, platform_version)
1680 return full_version
Michael Mortensen71ef5682020-05-07 14:29:24 -06001681
1682
Matthias Kaehlckebf7d1772021-11-04 16:01:36 -07001683def find_fingerprints(
Alex Klein1699fab2022-09-08 08:46:06 -06001684 build_target: "build_target_lib.BuildTarget",
1685) -> List[str]:
1686 """Returns a list of fingerprints for this build.
Michael Mortensende716a12020-05-15 11:27:00 -06001687
Alex Klein1699fab2022-09-08 08:46:06 -06001688 Args:
Alex Klein348e7692022-10-13 17:03:37 -06001689 build_target: The build target.
Michael Mortensende716a12020-05-15 11:27:00 -06001690
Alex Klein1699fab2022-09-08 08:46:06 -06001691 Returns:
Alex Klein348e7692022-10-13 17:03:37 -06001692 List of fingerprint strings.
Alex Klein1699fab2022-09-08 08:46:06 -06001693 """
1694 cros_build_lib.AssertInsideChroot()
1695 fp_file = "cheets-fingerprint.txt"
1696 fp_path = os.path.join(
1697 image_lib.GetLatestImageLink(build_target.name), fp_file
1698 )
1699 if not os.path.isfile(fp_path):
1700 logging.info("Fingerprint file not found: %s", fp_path)
1701 return []
1702 logging.info("Reading fingerprint file: %s", fp_path)
1703 fingerprints = osutils.ReadFile(fp_path).splitlines()
1704 return fingerprints
Michael Mortensende716a12020-05-15 11:27:00 -06001705
1706
Alex Klein1699fab2022-09-08 08:46:06 -06001707def get_all_firmware_versions(build_target: "build_target_lib.BuildTarget"):
1708 """Extract firmware version for all models present.
Michael Mortensen59e30872020-05-18 14:12:49 -06001709
Alex Klein1699fab2022-09-08 08:46:06 -06001710 Args:
Alex Klein348e7692022-10-13 17:03:37 -06001711 build_target: The build target.
Michael Mortensen59e30872020-05-18 14:12:49 -06001712
Alex Klein1699fab2022-09-08 08:46:06 -06001713 Returns:
Alex Klein348e7692022-10-13 17:03:37 -06001714 A dict of FirmwareVersions namedtuple instances by model.
1715 Each element will be populated based on whether it was present in the
1716 command output.
Alex Klein1699fab2022-09-08 08:46:06 -06001717 """
1718 cros_build_lib.AssertInsideChroot()
1719 result = {}
1720 # Note that example output for _get_firmware_version_cmd_result is available
1721 # in the packages_unittest.py for testing get_all_firmware_versions.
1722 cmd_result = _get_firmware_version_cmd_result(build_target)
Michael Mortensen59e30872020-05-18 14:12:49 -06001723
Alex Klein1699fab2022-09-08 08:46:06 -06001724 if cmd_result:
1725 # There is a blank line between the version info for each model.
1726 firmware_version_payloads = cmd_result.split("\n\n")
1727 for firmware_version_payload in firmware_version_payloads:
1728 if "BIOS" in firmware_version_payload:
1729 firmware_version = _find_firmware_versions(
1730 firmware_version_payload
1731 )
1732 result[firmware_version.model] = firmware_version
1733 return result
Michael Mortensen59e30872020-05-18 14:12:49 -06001734
1735
Benjamin Shai0858cd32022-01-10 20:23:49 +00001736class FirmwareVersions(NamedTuple):
Alex Klein1699fab2022-09-08 08:46:06 -06001737 """Tuple to hold firmware versions, with truthiness."""
Benjamin Shai0858cd32022-01-10 20:23:49 +00001738
Alex Klein1699fab2022-09-08 08:46:06 -06001739 model: Optional[str]
1740 main: Optional[str]
1741 main_rw: Optional[str]
1742 ec: Optional[str]
1743 ec_rw: Optional[str]
1744
1745 def __bool__(self):
1746 return bool(
1747 self.model or self.main or self.main_rw or self.ec or self.ec_rw
1748 )
Michael Mortensen71ef5682020-05-07 14:29:24 -06001749
1750
Alex Klein1699fab2022-09-08 08:46:06 -06001751def get_firmware_versions(build_target: "build_target_lib.BuildTarget"):
1752 """Extract version information from the firmware updater, if one exists.
Michael Mortensen71ef5682020-05-07 14:29:24 -06001753
Alex Klein1699fab2022-09-08 08:46:06 -06001754 Args:
Alex Klein348e7692022-10-13 17:03:37 -06001755 build_target: The build target.
Michael Mortensen71ef5682020-05-07 14:29:24 -06001756
Alex Klein1699fab2022-09-08 08:46:06 -06001757 Returns:
Alex Klein348e7692022-10-13 17:03:37 -06001758 A FirmwareVersions namedtuple instance.
1759 Each element will either be set to the string output by the firmware
1760 updater shellball, or None if there is no firmware updater.
Alex Klein1699fab2022-09-08 08:46:06 -06001761 """
1762 cros_build_lib.AssertInsideChroot()
1763 cmd_result = _get_firmware_version_cmd_result(build_target)
1764 if cmd_result:
1765 return _find_firmware_versions(cmd_result)
1766 else:
1767 return FirmwareVersions(None, None, None, None, None)
Michael Mortensen71ef5682020-05-07 14:29:24 -06001768
1769
Matthias Kaehlckebf7d1772021-11-04 16:01:36 -07001770def _get_firmware_version_cmd_result(
Alex Klein1699fab2022-09-08 08:46:06 -06001771 build_target: "build_target_lib.BuildTarget",
1772) -> Optional[str]:
1773 """Gets the raw result output of the firmware updater version command.
Michael Mortensen71ef5682020-05-07 14:29:24 -06001774
Alex Klein1699fab2022-09-08 08:46:06 -06001775 Args:
Alex Klein348e7692022-10-13 17:03:37 -06001776 build_target: The build target.
Michael Mortensen71ef5682020-05-07 14:29:24 -06001777
Alex Klein1699fab2022-09-08 08:46:06 -06001778 Returns:
Alex Klein348e7692022-10-13 17:03:37 -06001779 Command execution result.
Alex Klein1699fab2022-09-08 08:46:06 -06001780 """
1781 updater = os.path.join(
1782 build_target.root, "usr/sbin/chromeos-firmwareupdate"
1783 )
1784 logging.info("Calling updater %s", updater)
1785 # Call the updater using the chroot-based path.
1786 try:
1787 return cros_build_lib.run(
1788 [updater, "-V"],
1789 capture_output=True,
1790 log_output=True,
1791 encoding="utf-8",
1792 ).stdout
1793 except cros_build_lib.RunCommandError:
1794 # Updater probably doesn't exist (e.g. betty).
1795 return None
Michael Mortensen71ef5682020-05-07 14:29:24 -06001796
1797
1798def _find_firmware_versions(cmd_output):
Alex Klein1699fab2022-09-08 08:46:06 -06001799 """Finds firmware version output via regex matches against the cmd_output.
Michael Mortensen71ef5682020-05-07 14:29:24 -06001800
Alex Klein1699fab2022-09-08 08:46:06 -06001801 Args:
Alex Klein348e7692022-10-13 17:03:37 -06001802 cmd_output: The raw output to search against.
Michael Mortensen71ef5682020-05-07 14:29:24 -06001803
Alex Klein1699fab2022-09-08 08:46:06 -06001804 Returns:
Alex Klein348e7692022-10-13 17:03:37 -06001805 FirmwareVersions namedtuple with results.
1806 Each element will either be set to the string output by the firmware
1807 updater shellball, or None if there is no match.
Alex Klein1699fab2022-09-08 08:46:06 -06001808 """
Michael Mortensen71ef5682020-05-07 14:29:24 -06001809
Alex Klein1699fab2022-09-08 08:46:06 -06001810 # Sometimes a firmware bundle includes a special combination of RO+RW
1811 # firmware. In this case, the RW firmware version is indicated with a "(RW)
1812 # version" field. In other cases, the "(RW) version" field is not present.
1813 # Therefore, search for the "(RW)" fields first and if they aren't present,
1814 # fallback to the other format. e.g. just "BIOS version:".
1815 # TODO(mmortensen): Use JSON once the firmware updater supports it.
1816 main = None
1817 main_rw = None
1818 ec = None
1819 ec_rw = None
1820 model = None
Michael Mortensen71ef5682020-05-07 14:29:24 -06001821
Alex Klein1699fab2022-09-08 08:46:06 -06001822 match = re.search(r"BIOS version:\s*(?P<version>.*)", cmd_output)
1823 if match:
1824 main = match.group("version")
Michael Mortensen71ef5682020-05-07 14:29:24 -06001825
Alex Klein1699fab2022-09-08 08:46:06 -06001826 match = re.search(r"BIOS \(RW\) version:\s*(?P<version>.*)", cmd_output)
1827 if match:
1828 main_rw = match.group("version")
Michael Mortensen71ef5682020-05-07 14:29:24 -06001829
Alex Klein1699fab2022-09-08 08:46:06 -06001830 match = re.search(r"EC version:\s*(?P<version>.*)", cmd_output)
1831 if match:
1832 ec = match.group("version")
Michael Mortensen71ef5682020-05-07 14:29:24 -06001833
Alex Klein1699fab2022-09-08 08:46:06 -06001834 match = re.search(r"EC \(RW\) version:\s*(?P<version>.*)", cmd_output)
1835 if match:
1836 ec_rw = match.group("version")
Michael Mortensen71ef5682020-05-07 14:29:24 -06001837
Alex Klein1699fab2022-09-08 08:46:06 -06001838 match = re.search(r"Model:\s*(?P<model>.*)", cmd_output)
1839 if match:
1840 model = match.group("model")
Michael Mortensen71ef5682020-05-07 14:29:24 -06001841
Alex Klein1699fab2022-09-08 08:46:06 -06001842 return FirmwareVersions(model, main, main_rw, ec, ec_rw)
Michael Mortensena4af79e2020-05-06 16:18:48 -06001843
1844
Benjamin Shai0858cd32022-01-10 20:23:49 +00001845class MainEcFirmwareVersions(NamedTuple):
Alex Klein1699fab2022-09-08 08:46:06 -06001846 """Tuple to hold main and ec firmware versions, with truthiness."""
Benjamin Shai0858cd32022-01-10 20:23:49 +00001847
Alex Klein1699fab2022-09-08 08:46:06 -06001848 main_fw_version: Optional[str]
1849 ec_fw_version: Optional[str]
1850
1851 def __bool__(self):
1852 return bool(self.main_fw_version or self.ec_fw_version)
Benjamin Shai0858cd32022-01-10 20:23:49 +00001853
Michael Mortensena4af79e2020-05-06 16:18:48 -06001854
Alex Klein1699fab2022-09-08 08:46:06 -06001855def determine_firmware_versions(build_target: "build_target_lib.BuildTarget"):
1856 """Returns a namedtuple with main and ec firmware versions.
Michael Mortensena4af79e2020-05-06 16:18:48 -06001857
Alex Klein1699fab2022-09-08 08:46:06 -06001858 Args:
Alex Klein348e7692022-10-13 17:03:37 -06001859 build_target: The build target.
Michael Mortensena4af79e2020-05-06 16:18:48 -06001860
Alex Klein1699fab2022-09-08 08:46:06 -06001861 Returns:
Alex Klein348e7692022-10-13 17:03:37 -06001862 MainEcFirmwareVersions namedtuple with results.
Alex Klein1699fab2022-09-08 08:46:06 -06001863 """
1864 fw_versions = get_firmware_versions(build_target)
1865 main_fw_version = fw_versions.main_rw or fw_versions.main
1866 ec_fw_version = fw_versions.ec_rw or fw_versions.ec
Michael Mortensena4af79e2020-05-06 16:18:48 -06001867
Alex Klein1699fab2022-09-08 08:46:06 -06001868 return MainEcFirmwareVersions(main_fw_version, ec_fw_version)
Michael Mortensenfbf2b2d2020-05-14 16:33:06 -06001869
Benjamin Shai0858cd32022-01-10 20:23:49 +00001870
Matthias Kaehlckebf7d1772021-11-04 16:01:36 -07001871def determine_kernel_version(
Alex Klein1699fab2022-09-08 08:46:06 -06001872 build_target: "build_target_lib.BuildTarget",
Lizzy Presland0b978e62022-09-09 16:55:29 +00001873) -> str:
Alex Klein1699fab2022-09-08 08:46:06 -06001874 """Returns a string containing the kernel version for this build target.
Michael Mortensenfbf2b2d2020-05-14 16:33:06 -06001875
Alex Klein1699fab2022-09-08 08:46:06 -06001876 Args:
Alex Klein348e7692022-10-13 17:03:37 -06001877 build_target: The build target.
Michael Mortensenfbf2b2d2020-05-14 16:33:06 -06001878
Alex Klein1699fab2022-09-08 08:46:06 -06001879 Returns:
Alex Klein348e7692022-10-13 17:03:37 -06001880 The kernel versions, or empty string.
Alex Klein1699fab2022-09-08 08:46:06 -06001881 """
Lizzy Presland0b978e62022-09-09 16:55:29 +00001882 target_virtual_pkg = "virtual/linux-sources"
Alex Klein1699fab2022-09-08 08:46:06 -06001883 try:
Lizzy Presland0b978e62022-09-09 16:55:29 +00001884 candidate_packages = portage_util.GetFlattenedDepsForPackage(
1885 target_virtual_pkg,
1886 sysroot=build_target.root,
1887 board=build_target.name,
1888 depth=1,
1889 )
1890 installed_packages = portage_util.GetPackageDependencies(
1891 target_virtual_pkg, board=build_target.name
Alex Klein1699fab2022-09-08 08:46:06 -06001892 )
1893 except cros_build_lib.RunCommandError as e:
1894 logging.warning("Unable to get package list for metadata: %s", e)
Lizzy Presland0b978e62022-09-09 16:55:29 +00001895 return ""
1896 if not candidate_packages:
1897 raise KernelVersionError("No package found in FlattenedDepsForPackage")
1898 if not installed_packages:
1899 raise KernelVersionError("No package found in GetPackageDependencies")
1900 packages = [
1901 p
1902 for p in installed_packages
1903 if p in candidate_packages and target_virtual_pkg not in p
1904 ]
1905 if len(packages) == 0:
1906 raise KernelVersionError(
1907 "No matches for installed packages were found in candidate "
1908 "packages. Did GetFlattenedDepsForPackage search all possible "
1909 "package versions?\tInstalled: %s\tCandidates: %s"
1910 % (" ".join(installed_packages), " ".join(candidate_packages))
1911 )
1912 if len(packages) > 1:
1913 raise KernelVersionError(
1914 "Too many packages found in intersection of installed packages and "
1915 "possible kernel versions (%s)" % "".join(packages)
1916 )
1917 kernel_version = package_info.SplitCPV(packages[0]).version
1918 logging.info("Found active kernel version: %s", kernel_version)
1919 return kernel_version
Michael Mortensen125bb012020-05-21 14:02:10 -06001920
1921
Matthias Kaehlckebf7d1772021-11-04 16:01:36 -07001922def get_models(
Alex Klein1699fab2022-09-08 08:46:06 -06001923 build_target: "build_target_lib.BuildTarget", log_output: bool = True
1924) -> Optional[List[str]]:
1925 """Obtain a list of models supported by a unified board.
Michael Mortensen125bb012020-05-21 14:02:10 -06001926
Alex Klein1699fab2022-09-08 08:46:06 -06001927 This ignored whitelabel models since GoldenEye has no specific support for
1928 these at present.
Michael Mortensen125bb012020-05-21 14:02:10 -06001929
Alex Klein1699fab2022-09-08 08:46:06 -06001930 Args:
Alex Klein348e7692022-10-13 17:03:37 -06001931 build_target: The build target.
1932 log_output: Whether to log the output of the cros_config_host
1933 invocation.
Michael Mortensen125bb012020-05-21 14:02:10 -06001934
Alex Klein1699fab2022-09-08 08:46:06 -06001935 Returns:
Alex Klein348e7692022-10-13 17:03:37 -06001936 A list of models supported by this board, if it is a unified build;
1937 None, if it is not a unified build.
Alex Klein1699fab2022-09-08 08:46:06 -06001938 """
1939 return _run_cros_config_host(
1940 build_target, ["list-models"], log_output=log_output
1941 )
Michael Mortensen125bb012020-05-21 14:02:10 -06001942
1943
Matthias Kaehlckebf7d1772021-11-04 16:01:36 -07001944def get_key_id(
Alex Klein1699fab2022-09-08 08:46:06 -06001945 build_target: "build_target_lib.BuildTarget", model: str
1946) -> Optional[str]:
1947 """Obtain the key_id for a model within the build_target.
Michael Mortensen359c1f32020-05-28 19:35:42 -06001948
Alex Klein1699fab2022-09-08 08:46:06 -06001949 Args:
Alex Klein348e7692022-10-13 17:03:37 -06001950 build_target: The build target.
1951 model: The model name
Michael Mortensen359c1f32020-05-28 19:35:42 -06001952
Alex Klein1699fab2022-09-08 08:46:06 -06001953 Returns:
Alex Klein348e7692022-10-13 17:03:37 -06001954 A key_id or None.
Alex Klein1699fab2022-09-08 08:46:06 -06001955 """
1956 model_arg = "--model=" + model
1957 key_id_list = _run_cros_config_host(
1958 build_target, [model_arg, "get", "/firmware-signing", "key-id"]
1959 )
1960 key_id = None
1961 if len(key_id_list) == 1:
1962 key_id = key_id_list[0]
1963 return key_id
Michael Mortensen359c1f32020-05-28 19:35:42 -06001964
1965
Matthias Kaehlckebf7d1772021-11-04 16:01:36 -07001966def _run_cros_config_host(
Alex Klein1699fab2022-09-08 08:46:06 -06001967 build_target: "build_target_lib.BuildTarget",
Matthias Kaehlckebf7d1772021-11-04 16:01:36 -07001968 args: List[str],
Alex Klein1699fab2022-09-08 08:46:06 -06001969 log_output: bool = True,
1970) -> Optional[List[str]]:
1971 """Run the cros_config_host tool.
Michael Mortensen125bb012020-05-21 14:02:10 -06001972
Alex Klein1699fab2022-09-08 08:46:06 -06001973 Args:
Alex Klein348e7692022-10-13 17:03:37 -06001974 build_target: The build target.
1975 args: List of arguments to pass.
1976 log_output: Whether to log the output of the cros_config_host.
Michael Mortensen125bb012020-05-21 14:02:10 -06001977
Alex Klein1699fab2022-09-08 08:46:06 -06001978 Returns:
Alex Klein348e7692022-10-13 17:03:37 -06001979 Output of the tool
Alex Klein1699fab2022-09-08 08:46:06 -06001980 """
1981 cros_build_lib.AssertInsideChroot()
1982 tool = "/usr/bin/cros_config_host"
1983 if not os.path.isfile(tool):
1984 return None
Michael Mortensen125bb012020-05-21 14:02:10 -06001985
Alex Klein1699fab2022-09-08 08:46:06 -06001986 config_fname = build_target.full_path(
1987 "usr/share/chromeos-config/yaml/config.yaml"
1988 )
Michael Mortensen125bb012020-05-21 14:02:10 -06001989
Alex Klein1699fab2022-09-08 08:46:06 -06001990 result = cros_build_lib.run(
1991 [tool, "-c", config_fname] + args,
1992 capture_output=True,
1993 encoding="utf-8",
1994 log_output=log_output,
1995 check=False,
1996 )
1997 if result.returncode:
1998 # Show the output for debugging purposes.
1999 if "No such file or directory" not in result.stderr:
2000 logging.error("cros_config_host failed: %s\n", result.stderr)
2001 return None
2002 return result.stdout.strip().splitlines()