blob: 667a5c93ec8a488846704888255d6ec3e88f68e0 [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(
235 "Cannot emerge-%s =%s\nIs Android pinned to an older "
236 "version?",
237 target,
238 android_atom,
239 )
240 raise AndroidIsPinnedUprevError(android_atom)
Alex Klein4de25e82019-08-05 15:58:39 -0600241
Alex Klein1699fab2022-09-08 08:46:06 -0600242 return UprevAndroidResult(
243 revved=True,
244 android_atom=android_atom,
245 modified_files=output["modified_files"],
246 )
Shao-Chuan Lee05e51142021-11-24 12:27:37 +0900247
248
Alex Klein1699fab2022-09-08 08:46:06 -0600249def uprev_android_lkgb(
250 android_package: str,
251 build_targets: List["build_target_lib.BuildTarget"],
252 chroot: "chroot_lib.Chroot",
253) -> uprev_lib.UprevVersionedPackageResult:
254 """Uprevs an Android package to the version specified in the LKGB file.
Shao-Chuan Lee05e51142021-11-24 12:27:37 +0900255
Alex Klein1699fab2022-09-08 08:46:06 -0600256 This is the PUpr handler for Android packages, triggered whenever the
257 corresponding LKGB file is being updated.
Shao-Chuan Lee05e51142021-11-24 12:27:37 +0900258
Alex Kleinfee86da2023-01-20 18:40:06 -0700259 PUpr for Android does not test the uprev change in CQ; instead we run
260 separate jobs to test new Android versions, and we write the latest vetted
261 version to the LKGB file. Find the design at go/android-uprev-recipes.
Shao-Chuan Lee05e51142021-11-24 12:27:37 +0900262
Alex Klein1699fab2022-09-08 08:46:06 -0600263 Args:
Alex Klein348e7692022-10-13 17:03:37 -0600264 android_package: The Android package to uprev.
265 build_targets: List of build targets to cleanup after uprev.
266 chroot: The chroot to enter.
Shao-Chuan Lee05e51142021-11-24 12:27:37 +0900267
Alex Klein1699fab2022-09-08 08:46:06 -0600268 Returns:
Alex Klein348e7692022-10-13 17:03:37 -0600269 An uprev_lib.UprevVersionedPackageResult containing the new version and
270 a list of modified files.
Alex Klein1699fab2022-09-08 08:46:06 -0600271 """
272 android_package_dir = android.GetAndroidPackageDir(android_package)
Shao-Chuan Leee0b9ba92023-01-18 19:35:36 +0900273 android_version = android.ReadLKGB(android_package_dir)["build_id"]
Shao-Chuan Lee05e51142021-11-24 12:27:37 +0900274
Alex Klein1699fab2022-09-08 08:46:06 -0600275 result = uprev_lib.UprevVersionedPackageResult()
276 uprev_result = uprev_android(
277 android_package,
278 chroot,
279 build_targets=build_targets,
280 android_version=android_version,
281 skip_commit=True,
282 )
283 if not uprev_result.revved:
284 return result
285
Alex Kleinfee86da2023-01-20 18:40:06 -0700286 # cros_mark_android_as_stable returns paths relative to
287 # |android.OVERLAY_DIR|.
Alex Klein1699fab2022-09-08 08:46:06 -0600288 result.add_result(
289 android_version,
290 [
291 os.path.join(android.OVERLAY_DIR, f)
292 for f in uprev_result.modified_files
293 ],
294 )
Shao-Chuan Lee05e51142021-11-24 12:27:37 +0900295 return result
296
Shao-Chuan Lee05e51142021-11-24 12:27:37 +0900297
298def define_uprev_android_lkgb_handlers():
Alex Klein1699fab2022-09-08 08:46:06 -0600299 """Dynamically define uprev handlers for each Android package"""
Shao-Chuan Lee05e51142021-11-24 12:27:37 +0900300
Alex Klein1699fab2022-09-08 08:46:06 -0600301 def define_handler(android_package):
302 """Defines the uprev handler for an Android package."""
303 full_package_name = "chromeos-base/" + android_package
Shao-Chuan Lee05e51142021-11-24 12:27:37 +0900304
Alex Klein1699fab2022-09-08 08:46:06 -0600305 @uprevs_versioned_package(full_package_name)
306 def _handler(build_targets, _refs, chroot):
307 return uprev_android_lkgb(android_package, build_targets, chroot)
Shao-Chuan Lee05e51142021-11-24 12:27:37 +0900308
Shao-Chuan Leeca2cbcc2022-11-02 08:28:31 +0900309 for android_package in android.GetAllAndroidPackages():
Alex Klein1699fab2022-09-08 08:46:06 -0600310 define_handler(android_package)
Shao-Chuan Lee05e51142021-11-24 12:27:37 +0900311
312
313define_uprev_android_lkgb_handlers()
Alex Klein4de25e82019-08-05 15:58:39 -0600314
315
Matthias Kaehlckebf7d1772021-11-04 16:01:36 -0700316def uprev_build_targets(
Alex Klein1699fab2022-09-08 08:46:06 -0600317 build_targets: Optional[List["build_target_lib.BuildTarget"]],
Matthias Kaehlckebf7d1772021-11-04 16:01:36 -0700318 overlay_type: str,
Alex Klein1699fab2022-09-08 08:46:06 -0600319 chroot: "chroot_lib.Chroot" = None,
320 output_dir: Optional[str] = None,
321):
322 """Uprev the set provided build targets, or all if not specified.
Alex Kleineb77ffa2019-05-28 14:47:44 -0600323
Alex Klein1699fab2022-09-08 08:46:06 -0600324 Args:
Alex Klein348e7692022-10-13 17:03:37 -0600325 build_targets: The build targets whose overlays should be uprevved,
326 empty or None for all.
327 overlay_type: One of the valid overlay types except None (see
328 constants.VALID_OVERLAYS).
329 chroot: The chroot to clean, if desired.
330 output_dir: The path to optionally dump result files.
Alex Klein1699fab2022-09-08 08:46:06 -0600331 """
332 # Need a valid overlay, but exclude None.
333 assert overlay_type and overlay_type in constants.VALID_OVERLAYS
Alex Kleineb77ffa2019-05-28 14:47:44 -0600334
Alex Klein1699fab2022-09-08 08:46:06 -0600335 if build_targets:
336 overlays = portage_util.FindOverlaysForBoards(
337 overlay_type, boards=[t.name for t in build_targets]
338 )
339 else:
340 overlays = portage_util.FindOverlays(overlay_type)
Alex Kleineb77ffa2019-05-28 14:47:44 -0600341
Alex Klein1699fab2022-09-08 08:46:06 -0600342 return uprev_overlays(
343 overlays,
344 build_targets=build_targets,
345 chroot=chroot,
346 output_dir=output_dir,
347 )
Alex Kleineb77ffa2019-05-28 14:47:44 -0600348
349
Matthias Kaehlckebf7d1772021-11-04 16:01:36 -0700350def uprev_overlays(
351 overlays: List[str],
Alex Klein1699fab2022-09-08 08:46:06 -0600352 build_targets: Optional[List["build_target_lib.BuildTarget"]] = None,
353 chroot: Optional["chroot_lib.Chroot"] = None,
354 output_dir: Optional[str] = None,
355) -> List[str]:
356 """Uprev the given overlays.
Alex Kleineb77ffa2019-05-28 14:47:44 -0600357
Alex Klein1699fab2022-09-08 08:46:06 -0600358 Args:
Alex Klein348e7692022-10-13 17:03:37 -0600359 overlays: The list of overlay paths.
360 build_targets: The build targets to clean in |chroot|, if desired. No
361 effect unless |chroot| is provided.
362 chroot: The chroot to clean, if desired.
363 output_dir: The path to optionally dump result files.
Alex Kleineb77ffa2019-05-28 14:47:44 -0600364
Alex Klein1699fab2022-09-08 08:46:06 -0600365 Returns:
Alex Klein348e7692022-10-13 17:03:37 -0600366 The paths to all the modified ebuild files. This includes the new files
367 that were added (i.e. the new versions) and all the removed files
Alex Klein1699fab2022-09-08 08:46:06 -0600368 (i.e. the old versions).
369 """
370 assert overlays
Alex Kleineb77ffa2019-05-28 14:47:44 -0600371
Alex Klein1699fab2022-09-08 08:46:06 -0600372 manifest = git.ManifestCheckout.Cached(constants.SOURCE_ROOT)
Alex Kleineb77ffa2019-05-28 14:47:44 -0600373
Alex Klein1699fab2022-09-08 08:46:06 -0600374 uprev_manager = uprev_lib.UprevOverlayManager(
375 overlays,
376 manifest,
377 build_targets=build_targets,
378 chroot=chroot,
379 output_dir=output_dir,
380 )
381 uprev_manager.uprev()
Alex Kleineb77ffa2019-05-28 14:47:44 -0600382
Alex Klein1699fab2022-09-08 08:46:06 -0600383 return uprev_manager.modified_ebuilds, uprev_manager.revved_packages
Alex Kleineb77ffa2019-05-28 14:47:44 -0600384
385
Matthias Kaehlckebf7d1772021-11-04 16:01:36 -0700386def uprev_versioned_package(
387 package: package_info.CPV,
Alex Klein1699fab2022-09-08 08:46:06 -0600388 build_targets: List["build_target_lib.BuildTarget"],
Matthias Kaehlckebf7d1772021-11-04 16:01:36 -0700389 refs: List[uprev_lib.GitRef],
Alex Klein1699fab2022-09-08 08:46:06 -0600390 chroot: "chroot_lib.Chroot",
391) -> "uprev_lib.UprevVersionedPackageResult":
392 """Call registered uprev handler function for the package.
Alex Klein87531182019-08-12 15:23:37 -0600393
Alex Klein1699fab2022-09-08 08:46:06 -0600394 Args:
Alex Klein348e7692022-10-13 17:03:37 -0600395 package: The package being uprevved.
396 build_targets: The build targets to clean on a successful uprev.
397 refs:
398 chroot: The chroot to enter for cleaning.
Alex Klein87531182019-08-12 15:23:37 -0600399
Alex Klein1699fab2022-09-08 08:46:06 -0600400 Returns:
Alex Klein348e7692022-10-13 17:03:37 -0600401 The result.
Alex Klein1699fab2022-09-08 08:46:06 -0600402 """
403 assert package
Alex Klein87531182019-08-12 15:23:37 -0600404
Alex Klein1699fab2022-09-08 08:46:06 -0600405 if package.cp not in _UPREV_FUNCS:
406 raise UnknownPackageError(
407 'Package "%s" does not have a registered handler.' % package.cp
408 )
Alex Klein87531182019-08-12 15:23:37 -0600409
Alex Klein1699fab2022-09-08 08:46:06 -0600410 return _UPREV_FUNCS[package.cp](build_targets, refs, chroot)
Alex Klein87531182019-08-12 15:23:37 -0600411
412
Alex Klein1699fab2022-09-08 08:46:06 -0600413@uprevs_versioned_package("media-libs/virglrenderer")
Navil Perezf57ba872020-06-04 22:38:37 +0000414def uprev_virglrenderer(_build_targets, refs, _chroot):
Alex Klein1699fab2022-09-08 08:46:06 -0600415 """Updates virglrenderer ebuilds.
Navil Perezf57ba872020-06-04 22:38:37 +0000416
Alex Klein1699fab2022-09-08 08:46:06 -0600417 See: uprev_versioned_package.
Navil Perezf57ba872020-06-04 22:38:37 +0000418
Alex Klein1699fab2022-09-08 08:46:06 -0600419 Returns:
Alex Klein348e7692022-10-13 17:03:37 -0600420 UprevVersionedPackageResult: The result of updating virglrenderer
421 ebuilds.
Alex Klein1699fab2022-09-08 08:46:06 -0600422 """
423 overlay = os.path.join(
424 constants.SOURCE_ROOT, constants.CHROMIUMOS_OVERLAY_DIR
425 )
426 repo_path = os.path.join(
427 constants.SOURCE_ROOT, "src", "third_party", "virglrenderer"
428 )
429 manifest = git.ManifestCheckout.Cached(repo_path)
Navil Perezf57ba872020-06-04 22:38:37 +0000430
Alex Klein1699fab2022-09-08 08:46:06 -0600431 uprev_manager = uprev_lib.UprevOverlayManager([overlay], manifest)
432 # TODO(crbug.com/1066242): Ebuilds for virglrenderer are currently
433 # denylisted. Do not force uprevs after builder is stable and ebuilds are no
434 # longer denylisted.
435 uprev_manager.uprev(package_list=["media-libs/virglrenderer"], force=True)
Navil Perezf57ba872020-06-04 22:38:37 +0000436
Alex Klein1699fab2022-09-08 08:46:06 -0600437 updated_files = uprev_manager.modified_ebuilds
438 result = uprev_lib.UprevVersionedPackageResult()
439 result.add_result(refs[-1].revision, updated_files)
440 return result
Navil Perezf57ba872020-06-04 22:38:37 +0000441
Alex Klein1699fab2022-09-08 08:46:06 -0600442
Matthew Lam59ca37d2022-10-24 18:11:06 +0000443@uprevs_versioned_package("x11-apps/igt-gpu-tools")
444def uprev_igt_gpu_tools(_build_targets, refs, _chroot):
445 """Updates igt-gpu-tools ebuilds.
446
447 See: uprev_versioned_package.
448
449 Returns:
Alex Kleinfee86da2023-01-20 18:40:06 -0700450 UprevVersionedPackageResult: The result of updating igt-gpu-tools
451 ebuilds.
Matthew Lam59ca37d2022-10-24 18:11:06 +0000452 """
453 overlay = os.path.join(
454 constants.SOURCE_ROOT, constants.CHROMIUMOS_OVERLAY_DIR
455 )
456 repo_path = os.path.join(
457 constants.SOURCE_ROOT, "src", "third_party", "igt-gpu-tools"
458 )
459 manifest = git.ManifestCheckout.Cached(repo_path)
460
461 uprev_manager = uprev_lib.UprevOverlayManager([overlay], manifest)
462 uprev_manager.uprev(package_list=["x11-apps/igt-gpu-tools"], force=True)
463
464 updated_files = uprev_manager.modified_ebuilds
465 result = uprev_lib.UprevVersionedPackageResult()
466 result.add_result(refs[-1].revision, updated_files)
467 return result
468
469
Alex Klein1699fab2022-09-08 08:46:06 -0600470@uprevs_versioned_package("chromeos-base/drivefs")
Jose Magana03b5a842020-08-19 12:52:59 +1000471def uprev_drivefs(_build_targets, refs, chroot):
Alex Klein1699fab2022-09-08 08:46:06 -0600472 """Updates drivefs ebuilds.
Jose Magana03b5a842020-08-19 12:52:59 +1000473
Alex Klein1699fab2022-09-08 08:46:06 -0600474 DriveFS versions follow the tag format of refs/tags/drivefs_1.2.3.
475 See: uprev_versioned_package.
Jose Magana03b5a842020-08-19 12:52:59 +1000476
Alex Klein1699fab2022-09-08 08:46:06 -0600477 Returns:
Alex Klein348e7692022-10-13 17:03:37 -0600478 UprevVersionedPackageResult: The result of updating drivefs ebuilds.
Alex Klein1699fab2022-09-08 08:46:06 -0600479 """
Jose Magana03b5a842020-08-19 12:52:59 +1000480
Alex Klein1699fab2022-09-08 08:46:06 -0600481 DRIVEFS_PATH_PREFIX = "src/private-overlays/chromeos-overlay/chromeos-base"
482 result = uprev_lib.UprevVersionedPackageResult()
483 all_changed_files = []
Jose Magana03b5a842020-08-19 12:52:59 +1000484
Alex Klein1699fab2022-09-08 08:46:06 -0600485 DRIVEFS_REFS_PREFIX = "refs/tags/drivefs_"
486 drivefs_version = _get_latest_version_from_refs(DRIVEFS_REFS_PREFIX, refs)
487 if not drivefs_version:
488 # No valid DriveFS version is identified.
489 return result
490
491 logging.debug("DriveFS version determined from refs: %s", drivefs_version)
492
493 # Attempt to uprev drivefs package.
494 pkg_path = os.path.join(DRIVEFS_PATH_PREFIX, "drivefs")
495 uprev_result = uprev_lib.uprev_workon_ebuild_to_version(
496 pkg_path, drivefs_version, chroot, allow_downrev=False
497 )
498
499 if not uprev_result:
500 return result
501 all_changed_files.extend(uprev_result.changed_files)
502 result.add_result(drivefs_version, all_changed_files)
503
Ben Reich4f3fa1b2020-12-19 08:21:26 +0000504 return result
Jose Magana03b5a842020-08-19 12:52:59 +1000505
Jose Magana03b5a842020-08-19 12:52:59 +1000506
Alex Klein1699fab2022-09-08 08:46:06 -0600507@uprevs_versioned_package("chromeos-base/perfetto")
Chinglin Yufa728552023-04-13 03:12:04 +0000508@uprevs_versioned_package("dev-go/perfetto-protos")
Harvey Yang9c61e9c2021-03-02 16:32:43 +0800509def uprev_perfetto(_build_targets, refs, chroot):
Alex Klein1699fab2022-09-08 08:46:06 -0600510 """Updates Perfetto ebuilds.
Harvey Yang9c61e9c2021-03-02 16:32:43 +0800511
Alex Klein1699fab2022-09-08 08:46:06 -0600512 Perfetto versions follow the tag format of refs/tags/v1.2.
513 See: uprev_versioned_package.
Harvey Yang9c61e9c2021-03-02 16:32:43 +0800514
Alex Klein1699fab2022-09-08 08:46:06 -0600515 Returns:
Alex Klein348e7692022-10-13 17:03:37 -0600516 UprevVersionedPackageResult: The result of updating Perfetto ebuilds.
Alex Klein1699fab2022-09-08 08:46:06 -0600517 """
518 result = uprev_lib.UprevVersionedPackageResult()
Harvey Yang9c61e9c2021-03-02 16:32:43 +0800519
Alex Klein1699fab2022-09-08 08:46:06 -0600520 PERFETTO_REFS_PREFIX = "refs/tags/v"
Chinglin Yufa728552023-04-13 03:12:04 +0000521
522 perfetto_ebuilds = ["chromeos-base/perfetto", "dev-go/perfetto-protos"]
523 perfetto_paths = [
524 os.path.join(constants.CHROMIUMOS_OVERLAY_DIR, e)
525 for e in perfetto_ebuilds
526 ]
527 # chromeos-base/perfetto is the primary ebuild.
528 primary_ebuild_path = perfetto_paths[0]
Chinglin Yuad12a512022-10-07 17:26:12 +0800529
530 # Decide the version number to uprev to:
531 # * If |refs| contains refs/tags/v*, get the latest from them.
Alex Klein1699fab2022-09-08 08:46:06 -0600532 perfetto_version = _get_latest_version_from_refs(PERFETTO_REFS_PREFIX, refs)
Chinglin Yuad12a512022-10-07 17:26:12 +0800533 # * Or if |refs| contains only the latest trunk revisions, use the current
534 # stable ebuild version for a revision bump.
535 if refs and not perfetto_version:
Chinglin Yufa728552023-04-13 03:12:04 +0000536 perfetto_version = uprev_lib.get_stable_ebuild_version(
537 primary_ebuild_path
538 )
Chinglin Yuad12a512022-10-07 17:26:12 +0800539
Alex Klein1699fab2022-09-08 08:46:06 -0600540 if not perfetto_version:
541 # No valid Perfetto version is identified.
542 return result
543
Chinglin Yufa728552023-04-13 03:12:04 +0000544 for path in perfetto_paths:
545 # Attempt to uprev perfetto package.
546 # |perfetto_version| is only used in determining the ebuild version. The
547 # package is always updated to the latest HEAD.
548 uprev_result = uprev_lib.uprev_workon_ebuild_to_version(
549 path,
550 perfetto_version,
551 chroot,
552 allow_downrev=False,
553 # Use default ref="HEAD"
554 )
Alex Klein1699fab2022-09-08 08:46:06 -0600555
Chinglin Yufa728552023-04-13 03:12:04 +0000556 if not uprev_result:
557 return result
Alex Klein1699fab2022-09-08 08:46:06 -0600558
Chinglin Yufa728552023-04-13 03:12:04 +0000559 # Include short git sha hash in the uprev commit message.
560 # Use 9 digits to match the short hash length in `perfetto --version`.
561 short_revision = refs[-1].revision[0:9]
562 version_and_rev = f"{perfetto_version}-{short_revision}"
563 result.add_result(version_and_rev, uprev_result.changed_files)
Alex Klein1699fab2022-09-08 08:46:06 -0600564
Harvey Yang9c61e9c2021-03-02 16:32:43 +0800565 return result
566
Harvey Yang9c61e9c2021-03-02 16:32:43 +0800567
Denis Nikitin63613e32022-09-09 22:26:50 -0700568class AfdoMetadata(NamedTuple):
569 """Data class holding AFDO metadata."""
570
571 var_name: str
572 path: str
573
574
Alex Klein1699fab2022-09-08 08:46:06 -0600575@uprevs_versioned_package("afdo/kernel-profiles")
Yaakov Shaul395ae832019-09-09 14:45:32 -0600576def uprev_kernel_afdo(*_args, **_kwargs):
Alex Klein1699fab2022-09-08 08:46:06 -0600577 """Updates kernel ebuilds with versions from kernel_afdo.json.
Yaakov Shaul395ae832019-09-09 14:45:32 -0600578
Alex Klein1699fab2022-09-08 08:46:06 -0600579 See: uprev_versioned_package.
Yaakov Shaul1eafe832019-09-10 16:50:26 -0600580
Alex Klein1699fab2022-09-08 08:46:06 -0600581 Raises:
Alex Klein348e7692022-10-13 17:03:37 -0600582 EbuildManifestError: When ebuild manifest does not complete
583 successfully.
584 JSONDecodeError: When json is malformed.
Alex Klein1699fab2022-09-08 08:46:06 -0600585 """
Denis Nikitin63613e32022-09-09 22:26:50 -0700586 metadata_dir = os.path.join(
Alex Klein1699fab2022-09-08 08:46:06 -0600587 constants.SOURCE_ROOT,
588 "src",
589 "third_party",
590 "toolchain-utils",
591 "afdo_metadata",
Denis Nikitin63613e32022-09-09 22:26:50 -0700592 )
593 metadata_files = (
594 AfdoMetadata(
595 var_name="AFDO_PROFILE_VERSION",
596 path=os.path.join(metadata_dir, "kernel_afdo.json"),
597 ),
598 AfdoMetadata(
599 var_name="ARM_AFDO_PROFILE_VERSION",
600 path=os.path.join(metadata_dir, "kernel_arm_afdo.json"),
601 ),
Alex Klein1699fab2022-09-08 08:46:06 -0600602 )
Yaakov Shaul395ae832019-09-09 14:45:32 -0600603
Alex Klein1699fab2022-09-08 08:46:06 -0600604 result = uprev_lib.UprevVersionedPackageResult()
Denis Nikitin63613e32022-09-09 22:26:50 -0700605 for metadata in metadata_files:
Mike Frysinger81a98062023-02-24 15:42:04 -0500606 with open(metadata.path, "r", encoding="utf-8") as f:
Denis Nikitin63613e32022-09-09 22:26:50 -0700607 versions = json.load(f)
Yaakov Shaul1eafe832019-09-10 16:50:26 -0600608
Denis Nikitin63613e32022-09-09 22:26:50 -0700609 for kernel_pkg, version_info in versions.items():
610 path = os.path.join(
611 constants.CHROMIUMOS_OVERLAY_DIR, "sys-kernel", kernel_pkg
612 )
613 ebuild_path = os.path.join(
614 constants.SOURCE_ROOT, path, f"{kernel_pkg}-9999.ebuild"
615 )
616 chroot_ebuild_path = os.path.join(
617 constants.CHROOT_SOURCE_ROOT, path, f"{kernel_pkg}-9999.ebuild"
618 )
619 afdo_profile_version = version_info["name"]
620 patch_ebuild_vars(
621 ebuild_path, {metadata.var_name: afdo_profile_version}
Alex Klein1699fab2022-09-08 08:46:06 -0600622 )
Yaakov Shaul1eafe832019-09-10 16:50:26 -0600623
Denis Nikitin63613e32022-09-09 22:26:50 -0700624 try:
625 cmd = ["ebuild", chroot_ebuild_path, "manifest", "--force"]
626 cros_build_lib.run(cmd, enter_chroot=True)
627 except cros_build_lib.RunCommandError as e:
628 raise uprev_lib.EbuildManifestError(
629 "Error encountered when regenerating the manifest for "
630 f"ebuild: {chroot_ebuild_path}\n{e}",
631 e,
632 )
Yaakov Shaul1eafe832019-09-10 16:50:26 -0600633
Denis Nikitin63613e32022-09-09 22:26:50 -0700634 manifest_path = os.path.join(
635 constants.SOURCE_ROOT, path, "Manifest"
636 )
637 result.add_result(
638 afdo_profile_version, [ebuild_path, manifest_path]
639 )
Yaakov Shaul730814a2019-09-10 13:58:25 -0600640
Alex Klein1699fab2022-09-08 08:46:06 -0600641 return result
Yaakov Shaul395ae832019-09-09 14:45:32 -0600642
643
Alex Klein1699fab2022-09-08 08:46:06 -0600644@uprevs_versioned_package("chromeos-base/termina-dlc")
645@uprevs_versioned_package("chromeos-base/termina-tools-dlc")
Maciek Swiech6b12f662022-01-25 16:51:19 +0000646def uprev_termina_dlcs(_build_targets, _refs, chroot):
Alex Klein1699fab2022-09-08 08:46:06 -0600647 """Updates shared termina-dlc and termina-tools-dlc ebuilds.
Maciek Swiech6b12f662022-01-25 16:51:19 +0000648
Alex Klein1699fab2022-09-08 08:46:06 -0600649 termina-dlc - chromeos-base/termina-dlc
650 termina-tools-dlc - chromeos-base/termina-tools-dlc
Trent Beginaf51f1b2020-03-09 17:35:31 -0600651
Alex Klein1699fab2022-09-08 08:46:06 -0600652 See: uprev_versioned_package.
653 """
654 termina_dlc_pkg = "termina-dlc"
655 termina_dlc_pkg_path = os.path.join(
656 constants.CHROMIUMOS_OVERLAY_DIR, "chromeos-base", termina_dlc_pkg
657 )
658 tools_dlc_pkg = "termina-tools-dlc"
659 tools_dlc_pkg_path = os.path.join(
660 constants.CHROMIUMOS_OVERLAY_DIR, "chromeos-base", tools_dlc_pkg
661 )
Patrick Meiring5897add2020-09-16 16:30:17 +1000662
Alex Klein1699fab2022-09-08 08:46:06 -0600663 # termina-dlc and termina-tools-dlc are pinned to the same version.
664 version_pin_src_path = _get_version_pin_src_path(termina_dlc_pkg_path)
665 version_no_rev = osutils.ReadFile(version_pin_src_path).strip()
Patrick Meiring5897add2020-09-16 16:30:17 +1000666
Alex Klein1699fab2022-09-08 08:46:06 -0600667 result = uprev_lib.uprev_ebuild_from_pin(
668 termina_dlc_pkg_path, version_no_rev, chroot
669 )
670 result += uprev_lib.uprev_ebuild_from_pin(
671 tools_dlc_pkg_path, version_no_rev, chroot
672 )
Patrick Meiring5897add2020-09-16 16:30:17 +1000673
Alex Klein1699fab2022-09-08 08:46:06 -0600674 return result
Patrick Meiring5897add2020-09-16 16:30:17 +1000675
Alex Klein1699fab2022-09-08 08:46:06 -0600676
677@uprevs_versioned_package("chromeos-base/chromeos-lacros")
Julio Hurtadof1befec2021-05-05 21:34:26 +0000678def uprev_lacros(_build_targets, refs, chroot):
Alex Klein1699fab2022-09-08 08:46:06 -0600679 """Updates lacros ebuilds.
Julio Hurtadof1befec2021-05-05 21:34:26 +0000680
Alex Klein1699fab2022-09-08 08:46:06 -0600681 Version to uprev to is gathered from the QA qualified version tracking file
Alex Kleinfee86da2023-01-20 18:40:06 -0700682 stored in chromium/src/chrome/LACROS_QA_QUALIFIED_VERSION. Uprev is
683 triggered on modification of this file across all chromium/src branches.
Julio Hurtadof1befec2021-05-05 21:34:26 +0000684
Alex Klein1699fab2022-09-08 08:46:06 -0600685 See: uprev_versioned_package.
686 """
687 result = uprev_lib.UprevVersionedPackageResult()
688 path = os.path.join(
689 constants.CHROMIUMOS_OVERLAY_DIR, "chromeos-base", "chromeos-lacros"
690 )
691 lacros_version = refs[0].revision
692 uprev_result = uprev_lib.uprev_workon_ebuild_to_version(
693 path, lacros_version, chroot, allow_downrev=False
694 )
Julio Hurtadoa994e002021-07-07 17:57:45 +0000695
Alex Klein1699fab2022-09-08 08:46:06 -0600696 if not uprev_result:
697 return result
698
699 result.add_result(lacros_version, uprev_result.changed_files)
Julio Hurtadoa994e002021-07-07 17:57:45 +0000700 return result
701
Julio Hurtadof1befec2021-05-05 21:34:26 +0000702
Alex Klein1699fab2022-09-08 08:46:06 -0600703@uprevs_versioned_package("chromeos-base/chromeos-lacros-parallel")
Julio Hurtado870ed322021-12-03 18:22:40 +0000704def uprev_lacros_in_parallel(
Alex Klein1699fab2022-09-08 08:46:06 -0600705 _build_targets: Optional[List["build_target_lib.BuildTarget"]],
Julio Hurtado870ed322021-12-03 18:22:40 +0000706 refs: List[uprev_lib.GitRef],
Alex Klein1699fab2022-09-08 08:46:06 -0600707 chroot: "chroot_lib.Chroot",
708) -> "uprev_lib.UprevVersionedPackageResult":
709 """Updates lacros ebuilds in parallel with ash-chrome.
Julio Hurtado870ed322021-12-03 18:22:40 +0000710
Alex Kleinfee86da2023-01-20 18:40:06 -0700711 This handler is going to be used temporarily while lacros transitions to
712 being uprevved atomically with ash-chrome. Unlike a standalone lacros uprev,
713 this handler will not need to look at the QA qualified file. Rather, it will
Alex Klein1699fab2022-09-08 08:46:06 -0600714 function identical to ash-chrome using git tags.
Julio Hurtado870ed322021-12-03 18:22:40 +0000715
Alex Klein1699fab2022-09-08 08:46:06 -0600716 See: uprev_versioned_package.
Julio Hurtado870ed322021-12-03 18:22:40 +0000717
Alex Klein1699fab2022-09-08 08:46:06 -0600718 Returns:
Alex Klein348e7692022-10-13 17:03:37 -0600719 UprevVersionedPackageResult: The result.
Alex Klein1699fab2022-09-08 08:46:06 -0600720 """
721 result = uprev_lib.UprevVersionedPackageResult()
722 path = os.path.join(
723 constants.CHROMIUMOS_OVERLAY_DIR, "chromeos-base", "chromeos-lacros"
724 )
725 lacros_version = uprev_lib.get_version_from_refs(refs)
726 uprev_result = uprev_lib.uprev_workon_ebuild_to_version(
727 path, lacros_version, chroot, allow_downrev=False
728 )
Julio Hurtado870ed322021-12-03 18:22:40 +0000729
Alex Klein1699fab2022-09-08 08:46:06 -0600730 if not uprev_result:
731 return result
732
733 result.add_result(lacros_version, uprev_result.changed_files)
Julio Hurtado870ed322021-12-03 18:22:40 +0000734 return result
735
Julio Hurtado870ed322021-12-03 18:22:40 +0000736
Alex Klein1699fab2022-09-08 08:46:06 -0600737@uprevs_versioned_package("app-emulation/parallels-desktop")
Patrick Meiring5897add2020-09-16 16:30:17 +1000738def uprev_parallels_desktop(_build_targets, _refs, chroot):
Alex Klein1699fab2022-09-08 08:46:06 -0600739 """Updates Parallels Desktop ebuild - app-emulation/parallels-desktop.
Patrick Meiring5897add2020-09-16 16:30:17 +1000740
Alex Klein1699fab2022-09-08 08:46:06 -0600741 See: uprev_versioned_package
Patrick Meiring5897add2020-09-16 16:30:17 +1000742
Alex Klein1699fab2022-09-08 08:46:06 -0600743 Returns:
Alex Klein348e7692022-10-13 17:03:37 -0600744 UprevVersionedPackageResult: The result.
Alex Klein1699fab2022-09-08 08:46:06 -0600745 """
746 package = "parallels-desktop"
747 package_path = os.path.join(
748 constants.CHROMEOS_PARTNER_OVERLAY_DIR, "app-emulation", package
749 )
750 version_pin_src_path = _get_version_pin_src_path(package_path)
Patrick Meiring5897add2020-09-16 16:30:17 +1000751
Alex Klein1699fab2022-09-08 08:46:06 -0600752 # Expect a JSON blob like the following:
753 # {
754 # "version": "1.2.3",
755 # "test_image": { "url": "...", "size": 12345678,
756 # "sha256sum": "<32 bytes of hexadecimal>" }
757 # }
Mike Frysinger81a98062023-02-24 15:42:04 -0500758 with open(version_pin_src_path, "r", encoding="utf-8") as f:
Alex Klein1699fab2022-09-08 08:46:06 -0600759 pinned = json.load(f)
Patrick Meiring5897add2020-09-16 16:30:17 +1000760
Alex Klein1699fab2022-09-08 08:46:06 -0600761 if "version" not in pinned or "test_image" not in pinned:
762 raise UprevError(
763 "VERSION-PIN for %s missing version and/or "
764 "test_image field" % package
765 )
Patrick Meiring5897add2020-09-16 16:30:17 +1000766
Alex Klein1699fab2022-09-08 08:46:06 -0600767 version = pinned["version"]
768 if not isinstance(version, str):
769 raise UprevError("version in VERSION-PIN for %s not a string" % package)
Patrick Meiring5897add2020-09-16 16:30:17 +1000770
Alex Klein1699fab2022-09-08 08:46:06 -0600771 # Update the ebuild.
772 result = uprev_lib.uprev_ebuild_from_pin(package_path, version, chroot)
Patrick Meiring5897add2020-09-16 16:30:17 +1000773
Alex Klein1699fab2022-09-08 08:46:06 -0600774 # Update the VM image used for testing.
775 test_image_path = (
776 "src/platform/tast-tests-private/src/chromiumos/tast/"
777 "local/bundles/crosint/pita/data/"
778 "pluginvm_image.zip.external"
779 )
780 test_image_src_path = os.path.join(constants.SOURCE_ROOT, test_image_path)
Mike Frysinger81a98062023-02-24 15:42:04 -0500781 with open(test_image_src_path, "w", encoding="utf-8") as f:
Alex Klein1699fab2022-09-08 08:46:06 -0600782 json.dump(pinned["test_image"], f, indent=2)
783 result.add_result(version, [test_image_src_path])
Patrick Meiring5897add2020-09-16 16:30:17 +1000784
Alex Klein1699fab2022-09-08 08:46:06 -0600785 return result
Trent Beginaf51f1b2020-03-09 17:35:31 -0600786
787
Alex Klein1699fab2022-09-08 08:46:06 -0600788@uprevs_versioned_package("chromeos-base/chromeos-dtc-vm")
Trent Beginaf51f1b2020-03-09 17:35:31 -0600789def uprev_sludge(_build_targets, _refs, chroot):
Alex Klein1699fab2022-09-08 08:46:06 -0600790 """Updates sludge VM - chromeos-base/chromeos-dtc-vm.
Trent Begin315d9d92019-12-03 21:55:53 -0700791
Alex Klein1699fab2022-09-08 08:46:06 -0600792 See: uprev_versioned_package.
793 """
794 package = "chromeos-dtc-vm"
795 package_path = os.path.join(
796 "src",
797 "private-overlays",
798 "project-wilco-private",
799 "chromeos-base",
800 package,
801 )
802 version_pin_src_path = _get_version_pin_src_path(package_path)
803 version_no_rev = osutils.ReadFile(version_pin_src_path).strip()
Trent Begin315d9d92019-12-03 21:55:53 -0700804
Alex Klein1699fab2022-09-08 08:46:06 -0600805 return uprev_lib.uprev_ebuild_from_pin(package_path, version_no_rev, chroot)
Trent Begin315d9d92019-12-03 21:55:53 -0700806
807
Alex Klein1699fab2022-09-08 08:46:06 -0600808@uprevs_versioned_package("chromeos-base/borealis-dlc")
David Riley8513c1f2021-10-14 17:07:41 -0700809def uprev_borealis_dlc(_build_targets, _refs, chroot):
Alex Klein1699fab2022-09-08 08:46:06 -0600810 """Updates shared borealis-dlc ebuild - chromeos-base/borealis-dlc.
David Riley8513c1f2021-10-14 17:07:41 -0700811
Alex Klein1699fab2022-09-08 08:46:06 -0600812 See: uprev_versioned_package.
813 """
814 package_path = os.path.join(
815 "src",
816 "private-overlays",
817 "chromeos-partner-overlay",
818 "chromeos-base",
819 "borealis-dlc",
820 )
David Riley8513c1f2021-10-14 17:07:41 -0700821
Alex Klein1699fab2022-09-08 08:46:06 -0600822 version_pin_src_path = _get_version_pin_src_path(package_path)
823 version_no_rev = osutils.ReadFile(version_pin_src_path).strip()
David Riley8513c1f2021-10-14 17:07:41 -0700824
Alex Klein1699fab2022-09-08 08:46:06 -0600825 return uprev_lib.uprev_ebuild_from_pin(package_path, version_no_rev, chroot)
David Riley8513c1f2021-10-14 17:07:41 -0700826
827
Po-Hsien Wang92fb1e52023-04-27 11:35:04 -0700828@uprevs_versioned_package("chromeos-base/borealis-dlc-nvidia")
829def uprev_borealis_dlc_nvidia(_build_targets, _refs, chroot):
830 """Updates shared borealis-dlc-nvidia ebuild - chromeos-base/borealis-dlc-nvidia.
831
832 See: uprev_versioned_package.
833 """
834 package_path = os.path.join(
835 "src",
836 "private-overlays",
837 "chromeos-partner-overlay",
838 "chromeos-base",
839 "borealis-dlc-nvidia",
840 )
841
842 version_pin_src_path = _get_version_pin_src_path(package_path)
843 version_no_rev = osutils.ReadFile(version_pin_src_path).strip()
844
845 return uprev_lib.uprev_ebuild_from_pin(package_path, version_no_rev, chroot)
846
847
Patrick Meiring5897add2020-09-16 16:30:17 +1000848def _get_version_pin_src_path(package_path):
Alex Klein1699fab2022-09-08 08:46:06 -0600849 """Returns the path to the VERSION-PIN file for the given package."""
850 return os.path.join(constants.SOURCE_ROOT, package_path, "VERSION-PIN")
Patrick Meiring5897add2020-09-16 16:30:17 +1000851
852
Alex Klein87531182019-08-12 15:23:37 -0600853@uprevs_versioned_package(constants.CHROME_CP)
Alex Klein4e839252022-01-06 13:29:18 -0700854def uprev_chrome_from_ref(build_targets, refs, _chroot):
Alex Klein1699fab2022-09-08 08:46:06 -0600855 """Uprev chrome and its related packages.
Alex Klein87531182019-08-12 15:23:37 -0600856
Alex Klein1699fab2022-09-08 08:46:06 -0600857 See: uprev_versioned_package.
858 """
Alex Kleinfee86da2023-01-20 18:40:06 -0700859 # Determine the version from the refs (tags), i.e. the chrome versions are
860 # the tag names.
Alex Klein1699fab2022-09-08 08:46:06 -0600861 chrome_version = uprev_lib.get_version_from_refs(refs)
862 logging.debug("Chrome version determined from refs: %s", chrome_version)
Alex Klein87531182019-08-12 15:23:37 -0600863
Alex Klein1699fab2022-09-08 08:46:06 -0600864 return uprev_chrome(chrome_version, build_targets, None)
Alex Kleinf69bd802021-06-22 15:43:49 -0600865
866
Alex Klein9ce3f682021-06-23 15:06:44 -0600867def revbump_chrome(
Alex Klein1699fab2022-09-08 08:46:06 -0600868 build_targets: List["build_target_lib.BuildTarget"] = None,
869 chroot: Optional["chroot_lib.Chroot"] = None,
Alex Klein9ce3f682021-06-23 15:06:44 -0600870) -> uprev_lib.UprevVersionedPackageResult:
Alex Klein1699fab2022-09-08 08:46:06 -0600871 """Attempt to revbump chrome.
Alex Kleinf69bd802021-06-22 15:43:49 -0600872
Alex Klein1699fab2022-09-08 08:46:06 -0600873 Revbumps are done by executing an uprev using the current stable version.
874 E.g. if chrome is on 1.2.3.4 and has a 1.2.3.4_rc-r2.ebuild, performing an
875 uprev on version 1.2.3.4 when there are applicable changes (e.g. to the 9999
876 ebuild) will result in a revbump to 1.2.3.4_rc-r3.ebuild.
877 """
878 chrome_version = uprev_lib.get_stable_chrome_version()
879 return uprev_chrome(chrome_version, build_targets, chroot)
Alex Kleinf69bd802021-06-22 15:43:49 -0600880
881
Alex Klein9ce3f682021-06-23 15:06:44 -0600882def uprev_chrome(
Alex Klein16ea1b32021-10-01 15:48:50 -0600883 chrome_version: str,
Alex Klein1699fab2022-09-08 08:46:06 -0600884 build_targets: Optional[List["build_target_lib.BuildTarget"]],
885 chroot: Optional["chroot_lib.Chroot"],
Alex Klein9ce3f682021-06-23 15:06:44 -0600886) -> uprev_lib.UprevVersionedPackageResult:
Alex Klein1699fab2022-09-08 08:46:06 -0600887 """Attempt to uprev chrome and its related packages to the given version."""
888 uprev_manager = uprev_lib.UprevChromeManager(
889 chrome_version, build_targets=build_targets, chroot=chroot
890 )
891 result = uprev_lib.UprevVersionedPackageResult()
892 # TODO(crbug.com/1080429): Handle all possible outcomes of a Chrome uprev
893 # attempt. The expected behavior is documented in the following table:
894 #
895 # Outcome of Chrome uprev attempt:
896 # NEWER_VERSION_EXISTS:
897 # Do nothing.
898 # SAME_VERSION_EXISTS or REVISION_BUMP:
899 # Uprev followers
900 # Assert not VERSION_BUMP (any other outcome is fine)
901 # VERSION_BUMP or NEW_EBUILD_CREATED:
902 # Uprev followers
903 # Assert that Chrome & followers are at same package version
Alex Klein0b2ec2d2021-06-23 15:56:45 -0600904
Alex Klein1699fab2022-09-08 08:46:06 -0600905 # Start with chrome itself so we can proceed accordingly.
906 chrome_result = uprev_manager.uprev(constants.CHROME_CP)
907 if chrome_result.newer_version_exists:
908 # Cannot use the given version (newer version already exists).
909 return result
910
911 # Also uprev related packages.
912 for package in constants.OTHER_CHROME_PACKAGES:
913 follower_result = uprev_manager.uprev(package)
914 if chrome_result.stable_version and follower_result.version_bump:
915 logging.warning(
916 "%s had a version bump, but no more than a revision bump "
917 "should have been possible.",
918 package,
919 )
920
921 if uprev_manager.modified_ebuilds:
922 # Record changes when we have them.
923 return result.add_result(chrome_version, uprev_manager.modified_ebuilds)
924
David Burger37f48672019-09-18 17:07:56 -0600925 return result
Alex Klein87531182019-08-12 15:23:37 -0600926
Alex Klein87531182019-08-12 15:23:37 -0600927
Alex Klein1699fab2022-09-08 08:46:06 -0600928def _get_latest_version_from_refs(
929 refs_prefix: str, refs: List[uprev_lib.GitRef]
930) -> str:
931 """Get the latest version from refs
Alex Klein0b2ec2d2021-06-23 15:56:45 -0600932
Alex Klein1699fab2022-09-08 08:46:06 -0600933 Versions are compared using |distutils.version.LooseVersion| and
934 the latest version is returned.
Alex Klein87531182019-08-12 15:23:37 -0600935
Alex Klein1699fab2022-09-08 08:46:06 -0600936 Args:
Alex Klein348e7692022-10-13 17:03:37 -0600937 refs_prefix: The refs prefix of the tag format.
938 refs: The tags to parse for the latest version.
Alex Klein87531182019-08-12 15:23:37 -0600939
Alex Klein1699fab2022-09-08 08:46:06 -0600940 Returns:
Alex Klein348e7692022-10-13 17:03:37 -0600941 The latest version to use as string.
Alex Klein1699fab2022-09-08 08:46:06 -0600942 """
943 valid_refs = []
944 for gitiles in refs:
945 if gitiles.ref.startswith(refs_prefix):
946 valid_refs.append(gitiles.ref)
Ben Reiche779cf42020-12-15 03:21:31 +0000947
Alex Klein1699fab2022-09-08 08:46:06 -0600948 if not valid_refs:
949 return None
Ben Reiche779cf42020-12-15 03:21:31 +0000950
Alex Klein1699fab2022-09-08 08:46:06 -0600951 # Sort by version and take the latest version.
952 target_version_ref = sorted(valid_refs, key=LooseVersion, reverse=True)[0]
953 return target_version_ref.replace(refs_prefix, "")
Harvey Yang9c61e9c2021-03-02 16:32:43 +0800954
955
Matthias Kaehlckebf7d1772021-11-04 16:01:36 -0700956def _generate_platform_c_files(
957 replication_config: replication_config_pb2.ReplicationConfig,
Alex Klein1699fab2022-09-08 08:46:06 -0600958 chroot: "chroot_lib.Chroot",
959) -> List[str]:
960 """Generates platform C files from a platform JSON payload.
Andrew Lamb9563a152019-12-04 11:42:18 -0700961
Alex Klein1699fab2022-09-08 08:46:06 -0600962 Args:
Alex Klein348e7692022-10-13 17:03:37 -0600963 replication_config: A ReplicationConfig that has already been run. If it
964 produced a build_config.json file, that file will be used to
965 generate platform C files. Otherwise, nothing will be generated.
966 chroot: The chroot to use to generate.
Andrew Lamb9563a152019-12-04 11:42:18 -0700967
Alex Klein1699fab2022-09-08 08:46:06 -0600968 Returns:
Alex Klein348e7692022-10-13 17:03:37 -0600969 A list of generated files.
Alex Klein1699fab2022-09-08 08:46:06 -0600970 """
971 # Generate the platform C files from the build config. Note that it would be
972 # more intuitive to generate the platform C files from the platform config;
Alex Kleinfee86da2023-01-20 18:40:06 -0700973 # however, cros_config_schema does not allow this, because the platform
974 # config payload is not always valid input. For example, if a property is
975 # both 'required' and 'build-only', it will fail schema validation. Thus,
976 # use the build config, and use '-f' to filter.
Alex Klein1699fab2022-09-08 08:46:06 -0600977 build_config_path = [
978 rule.destination_path
979 for rule in replication_config.file_replication_rules
980 if rule.destination_path.endswith("build_config.json")
981 ]
Andrew Lamb9563a152019-12-04 11:42:18 -0700982
Alex Klein1699fab2022-09-08 08:46:06 -0600983 if not build_config_path:
984 logging.info(
985 "No build_config.json found, will not generate platform C files. "
986 "Replication config: %s",
987 replication_config,
988 )
989 return []
Andrew Lamb9563a152019-12-04 11:42:18 -0700990
Alex Klein1699fab2022-09-08 08:46:06 -0600991 if len(build_config_path) > 1:
992 raise ValueError(
993 "Expected at most one build_config.json destination path. "
994 "Replication config: %s" % replication_config
995 )
Andrew Lamb9563a152019-12-04 11:42:18 -0700996
Alex Klein1699fab2022-09-08 08:46:06 -0600997 build_config_path = build_config_path[0]
Andrew Lamb9563a152019-12-04 11:42:18 -0700998
Alex Klein1699fab2022-09-08 08:46:06 -0600999 # Paths to the build_config.json and dir to output C files to, in the
1000 # chroot.
1001 build_config_chroot_path = os.path.join(
1002 constants.CHROOT_SOURCE_ROOT, build_config_path
1003 )
1004 generated_output_chroot_dir = os.path.join(
1005 constants.CHROOT_SOURCE_ROOT, os.path.dirname(build_config_path)
1006 )
Andrew Lamb9563a152019-12-04 11:42:18 -07001007
Alex Klein1699fab2022-09-08 08:46:06 -06001008 command = [
1009 "cros_config_schema",
1010 "-m",
1011 build_config_chroot_path,
1012 "-g",
1013 generated_output_chroot_dir,
1014 "-f",
1015 '"TRUE"',
1016 ]
Andrew Lamb9563a152019-12-04 11:42:18 -07001017
Alex Klein1699fab2022-09-08 08:46:06 -06001018 cros_build_lib.run(
1019 command, enter_chroot=True, chroot_args=chroot.get_enter_args()
1020 )
Andrew Lamb9563a152019-12-04 11:42:18 -07001021
Alex Klein1699fab2022-09-08 08:46:06 -06001022 # A relative (to the source root) path to the generated C files.
1023 generated_output_dir = os.path.dirname(build_config_path)
1024 generated_files = []
1025 expected_c_files = ["config.c", "ec_config.c", "ec_config.h"]
1026 for f in expected_c_files:
1027 if os.path.exists(
1028 os.path.join(constants.SOURCE_ROOT, generated_output_dir, f)
1029 ):
1030 generated_files.append(os.path.join(generated_output_dir, f))
Andrew Lamb9563a152019-12-04 11:42:18 -07001031
Alex Klein1699fab2022-09-08 08:46:06 -06001032 if len(expected_c_files) != len(generated_files):
1033 raise GeneratedCrosConfigFilesError(expected_c_files, generated_files)
Andrew Lamb9563a152019-12-04 11:42:18 -07001034
Alex Klein1699fab2022-09-08 08:46:06 -06001035 return generated_files
Andrew Lamb9563a152019-12-04 11:42:18 -07001036
1037
Matthias Kaehlckebf7d1772021-11-04 16:01:36 -07001038def _get_private_overlay_package_root(ref: uprev_lib.GitRef, package: str):
Alex Klein1699fab2022-09-08 08:46:06 -06001039 """Returns the absolute path to the root of a given private overlay.
Andrew Lambe836f222019-12-09 12:27:38 -07001040
Alex Klein1699fab2022-09-08 08:46:06 -06001041 Args:
Alex Klein348e7692022-10-13 17:03:37 -06001042 ref: GitRef for the private overlay.
1043 package: Path to the package in the overlay.
Alex Klein1699fab2022-09-08 08:46:06 -06001044 """
1045 # There might be a cleaner way to map from package -> path within the source
1046 # tree. For now, just use string patterns.
1047 private_overlay_ref_pattern = (
1048 r"/chromeos\/overlays\/overlay-([\w-]+)-private"
1049 )
1050 match = re.match(private_overlay_ref_pattern, ref.path)
1051 if not match:
1052 raise ValueError(
1053 "ref.path must match the pattern: %s. Actual ref: %s"
1054 % (private_overlay_ref_pattern, ref)
1055 )
Andrew Lambe836f222019-12-09 12:27:38 -07001056
Alex Klein1699fab2022-09-08 08:46:06 -06001057 overlay = match.group(1)
Andrew Lambe836f222019-12-09 12:27:38 -07001058
Alex Klein1699fab2022-09-08 08:46:06 -06001059 return os.path.join(
1060 constants.SOURCE_ROOT,
1061 "src/private-overlays/overlay-%s-private" % overlay,
1062 package,
1063 )
Andrew Lambe836f222019-12-09 12:27:38 -07001064
1065
Alex Klein1699fab2022-09-08 08:46:06 -06001066@uprevs_versioned_package("chromeos-base/chromeos-config-bsp")
Andrew Lambea9a8a22019-12-12 14:03:43 -07001067def replicate_private_config(_build_targets, refs, chroot):
Alex Kleinfee86da2023-01-20 18:40:06 -07001068 """Replicate private cros_config change to the corresponding public config.
Andrew Lamb2bde9e42019-11-04 13:24:09 -07001069
Alex Klein1699fab2022-09-08 08:46:06 -06001070 See uprev_versioned_package for args
1071 """
1072 package = "chromeos-base/chromeos-config-bsp"
Andrew Lambea9a8a22019-12-12 14:03:43 -07001073
Alex Klein1699fab2022-09-08 08:46:06 -06001074 if len(refs) != 1:
1075 raise ValueError("Expected exactly one ref, actual %s" % refs)
Andrew Lamb2bde9e42019-11-04 13:24:09 -07001076
Alex Klein1699fab2022-09-08 08:46:06 -06001077 # Expect a replication_config.jsonpb in the package root.
1078 package_root = _get_private_overlay_package_root(refs[0], package)
1079 replication_config_path = os.path.join(
1080 package_root, "replication_config.jsonpb"
1081 )
Andrew Lamb2bde9e42019-11-04 13:24:09 -07001082
Alex Klein1699fab2022-09-08 08:46:06 -06001083 try:
1084 replication_config = json_format.Parse(
1085 osutils.ReadFile(replication_config_path),
1086 replication_config_pb2.ReplicationConfig(),
1087 )
1088 except IOError:
1089 raise ValueError(
1090 "Expected ReplicationConfig missing at %s" % replication_config_path
1091 )
Andrew Lamb2bde9e42019-11-04 13:24:09 -07001092
Alex Klein1699fab2022-09-08 08:46:06 -06001093 replication_lib.Replicate(replication_config)
Andrew Lamb2bde9e42019-11-04 13:24:09 -07001094
Alex Klein1699fab2022-09-08 08:46:06 -06001095 modified_files = [
1096 rule.destination_path
1097 for rule in replication_config.file_replication_rules
1098 ]
Andrew Lamb2bde9e42019-11-04 13:24:09 -07001099
Alex Kleinfee86da2023-01-20 18:40:06 -07001100 # The generated platform C files are not easily filtered by replication
1101 # rules, i.e. JSON / proto filtering can be described by a FieldMask,
1102 # arbitrary C files cannot. Therefore, replicate and filter the JSON
1103 # payloads, and then generate filtered C files from the JSON payload.
Alex Klein1699fab2022-09-08 08:46:06 -06001104 modified_files.extend(
1105 _generate_platform_c_files(replication_config, chroot)
1106 )
Andrew Lamb2bde9e42019-11-04 13:24:09 -07001107
Alex Klein1699fab2022-09-08 08:46:06 -06001108 # Use the private repo's commit hash as the new version.
1109 new_private_version = refs[0].revision
Andrew Lamb2bde9e42019-11-04 13:24:09 -07001110
Alex Klein1699fab2022-09-08 08:46:06 -06001111 # modified_files should contain only relative paths at this point, but the
1112 # returned UprevVersionedPackageResult must contain only absolute paths.
1113 for i, modified_file in enumerate(modified_files):
1114 assert not os.path.isabs(modified_file)
1115 modified_files[i] = os.path.join(constants.SOURCE_ROOT, modified_file)
Andrew Lamb988f4da2019-12-10 10:16:43 -07001116
Alex Klein1699fab2022-09-08 08:46:06 -06001117 return uprev_lib.UprevVersionedPackageResult().add_result(
1118 new_private_version, modified_files
1119 )
Andrew Lamb2bde9e42019-11-04 13:24:09 -07001120
1121
Alex Klein1699fab2022-09-08 08:46:06 -06001122@uprevs_versioned_package("chromeos-base/crosvm")
Dennis Kempinef05f2b2021-09-08 16:36:49 -07001123def uprev_crosvm(_build_targets, refs, _chroot):
Alex Klein1699fab2022-09-08 08:46:06 -06001124 """Updates crosvm ebuilds to latest revision
Dennis Kempinef05f2b2021-09-08 16:36:49 -07001125
Alex Klein1699fab2022-09-08 08:46:06 -06001126 crosvm is not versioned. We are updating to the latest commit on the main
1127 branch.
Dennis Kempinef05f2b2021-09-08 16:36:49 -07001128
Alex Klein1699fab2022-09-08 08:46:06 -06001129 See: uprev_versioned_package.
Dennis Kempinef05f2b2021-09-08 16:36:49 -07001130
Alex Klein1699fab2022-09-08 08:46:06 -06001131 Returns:
Alex Klein348e7692022-10-13 17:03:37 -06001132 UprevVersionedPackageResult: The result of updating crosvm ebuilds.
Alex Klein1699fab2022-09-08 08:46:06 -06001133 """
1134 overlay = os.path.join(
1135 constants.SOURCE_ROOT, constants.CHROMIUMOS_OVERLAY_DIR
1136 )
1137 repo_path = os.path.join(constants.SOURCE_ROOT, "src", "crosvm")
1138 manifest = git.ManifestCheckout.Cached(repo_path)
Dennis Kempinef05f2b2021-09-08 16:36:49 -07001139
Alex Klein1699fab2022-09-08 08:46:06 -06001140 uprev_manager = uprev_lib.UprevOverlayManager([overlay], manifest)
1141 uprev_manager.uprev(
1142 package_list=[
1143 "chromeos-base/crosvm",
1144 "dev-rust/assertions",
1145 "dev-rust/cros_async",
1146 "dev-rust/cros_fuzz",
1147 "dev-rust/data_model",
1148 "dev-rust/enumn",
1149 "dev-rust/io_uring",
1150 "dev-rust/p9",
1151 "dev-rust/sync",
1152 "dev-rust/sys_util",
1153 "dev-rust/tempfile",
1154 "media-sound/audio_streams",
1155 ],
1156 force=True,
1157 )
Dennis Kempinef05f2b2021-09-08 16:36:49 -07001158
Alex Klein1699fab2022-09-08 08:46:06 -06001159 updated_files = uprev_manager.modified_ebuilds
1160 result = uprev_lib.UprevVersionedPackageResult()
1161 result.add_result(refs[0].revision, updated_files)
1162 return result
Dennis Kempinef05f2b2021-09-08 16:36:49 -07001163
1164
Yi Choua4854ac2022-11-14 10:54:24 +08001165@uprevs_versioned_package("chromeos-base/ti50-emulator")
1166def uprev_ti50_emulator(_build_targets, refs, _chroot):
1167 """Updates ti50-emulator ebuilds to latest revision
1168
1169 ti50-emulator is not versioned. We are updating to the latest commit on the
1170 main branch.
1171
1172 See: uprev_versioned_package.
1173
1174 Returns:
1175 UprevVersionedPackageResult: The result of updating ti50-emulator
1176 ebuild.
1177 """
1178 overlay = os.path.join(
1179 constants.SOURCE_ROOT, constants.CHROMEOS_OVERLAY_DIR
1180 )
1181
1182 # The ti50-emulator will touch multiple repos.
1183 manifest = git.ManifestCheckout.Cached(constants.SOURCE_ROOT)
1184
1185 uprev_manager = uprev_lib.UprevOverlayManager([overlay], manifest)
1186 uprev_manager.uprev(
1187 package_list=["chromeos-base/ti50-emulator"],
1188 force=True,
1189 )
1190
1191 updated_files = uprev_manager.modified_ebuilds
1192 result = uprev_lib.UprevVersionedPackageResult()
1193 result.add_result(refs[-1].revision, updated_files)
1194 return result
1195
1196
Jeremy Bettisaf96afb2023-01-11 16:09:58 -07001197@uprevs_versioned_package("chromeos-base/ec-devutils")
Jeremy Bettis0186d252023-01-19 14:47:46 -07001198def uprev_ecdevutils(_build_targets, refs, _chroot):
1199 """Updates ec-devutils ebuilds to latest revision
1200
Alex Kleinfee86da2023-01-20 18:40:06 -07001201 ec-devutils is not versioned. We are updating to the latest commit on the
1202 main branch.
Jeremy Bettis0186d252023-01-19 14:47:46 -07001203
1204 See: uprev_versioned_package.
1205
1206 Returns:
1207 UprevVersionedPackageResult: The result of updating ec-devutils ebuilds.
1208 """
1209 overlay = os.path.join(
1210 constants.SOURCE_ROOT, constants.CHROMIUMOS_OVERLAY_DIR
1211 )
1212 repo_path = os.path.join(constants.SOURCE_ROOT, "src", "platform", "ec")
1213 manifest = git.ManifestCheckout.Cached(repo_path)
1214
1215 uprev_manager = uprev_lib.UprevOverlayManager([overlay], manifest)
1216 uprev_manager.uprev(
1217 package_list=[
1218 "chromeos-base/ec-devutils",
1219 ],
1220 force=True,
1221 )
1222
1223 updated_files = uprev_manager.modified_ebuilds
1224 result = uprev_lib.UprevVersionedPackageResult()
1225 result.add_result(refs[0].revision, updated_files)
1226 return result
1227
1228
Jeremy Bettisaf96afb2023-01-11 16:09:58 -07001229@uprevs_versioned_package("chromeos-base/ec-utils")
Jeremy Bettisaf96afb2023-01-11 16:09:58 -07001230def uprev_ecutils(_build_targets, refs, _chroot):
1231 """Updates ec-utils ebuilds to latest revision
1232
1233 ec-utils is not versioned. We are updating to the latest commit on the main
1234 branch.
1235
1236 See: uprev_versioned_package.
1237
1238 Returns:
1239 UprevVersionedPackageResult: The result of updating ec-utils ebuilds.
1240 """
1241 overlay = os.path.join(
1242 constants.SOURCE_ROOT, constants.CHROMIUMOS_OVERLAY_DIR
1243 )
1244 repo_path = os.path.join(constants.SOURCE_ROOT, "src", "platform", "ec")
1245 manifest = git.ManifestCheckout.Cached(repo_path)
1246
1247 uprev_manager = uprev_lib.UprevOverlayManager([overlay], manifest)
1248 uprev_manager.uprev(
1249 package_list=[
Jeremy Bettisaf96afb2023-01-11 16:09:58 -07001250 "chromeos-base/ec-utils",
Jeremy Bettis0186d252023-01-19 14:47:46 -07001251 ],
1252 force=True,
1253 )
1254
1255 updated_files = uprev_manager.modified_ebuilds
1256 result = uprev_lib.UprevVersionedPackageResult()
1257 result.add_result(refs[0].revision, updated_files)
1258 return result
1259
1260
1261@uprevs_versioned_package("chromeos-base/ec-utils-test")
1262def uprev_ecutilstest(_build_targets, refs, _chroot):
1263 """Updates ec-utils-test ebuilds to latest revision
1264
Alex Kleinfee86da2023-01-20 18:40:06 -07001265 ec-utils-test is not versioned. We are updating to the latest commit on the
1266 main branch.
Jeremy Bettis0186d252023-01-19 14:47:46 -07001267
1268 See: uprev_versioned_package.
1269
1270 Returns:
Alex Kleinfee86da2023-01-20 18:40:06 -07001271 UprevVersionedPackageResult: The result of updating ec-utils-test
1272 ebuilds.
Jeremy Bettis0186d252023-01-19 14:47:46 -07001273 """
1274 overlay = os.path.join(
1275 constants.SOURCE_ROOT, constants.CHROMIUMOS_OVERLAY_DIR
1276 )
1277 repo_path = os.path.join(constants.SOURCE_ROOT, "src", "platform", "ec")
1278 manifest = git.ManifestCheckout.Cached(repo_path)
1279
1280 uprev_manager = uprev_lib.UprevOverlayManager([overlay], manifest)
1281 uprev_manager.uprev(
1282 package_list=[
Jeremy Bettisaf96afb2023-01-11 16:09:58 -07001283 "chromeos-base/ec-utils-test",
1284 ],
1285 force=True,
1286 )
1287
1288 updated_files = uprev_manager.modified_ebuilds
1289 result = uprev_lib.UprevVersionedPackageResult()
1290 result.add_result(refs[0].revision, updated_files)
1291 return result
1292
1293
Alex Klein5caab872021-09-10 11:44:37 -06001294def get_best_visible(
Alex Klein1699fab2022-09-08 08:46:06 -06001295 atom: str, build_target: Optional["build_target_lib.BuildTarget"] = None
Alex Klein5caab872021-09-10 11:44:37 -06001296) -> package_info.PackageInfo:
Alex Klein1699fab2022-09-08 08:46:06 -06001297 """Returns the best visible CPV for the given atom.
Alex Kleinbbef2b32019-08-27 10:38:50 -06001298
Alex Klein1699fab2022-09-08 08:46:06 -06001299 Args:
Alex Klein348e7692022-10-13 17:03:37 -06001300 atom: The atom to look up.
1301 build_target: The build target whose sysroot should be searched, or the
1302 SDK if not provided.
Alex Kleinad6b48a2020-01-08 16:57:41 -07001303
Alex Klein1699fab2022-09-08 08:46:06 -06001304 Returns:
Alex Klein348e7692022-10-13 17:03:37 -06001305 The best visible package, or None if none are visible.
Alex Klein1699fab2022-09-08 08:46:06 -06001306 """
1307 assert atom
Alex Kleinbbef2b32019-08-27 10:38:50 -06001308
Alex Klein1699fab2022-09-08 08:46:06 -06001309 return portage_util.PortageqBestVisible(
1310 atom,
1311 board=build_target.name if build_target else None,
1312 sysroot=build_target.root if build_target else None,
1313 )
Alex Kleinda39c6d2019-09-16 14:36:36 -06001314
1315
Matthias Kaehlckebf7d1772021-11-04 16:01:36 -07001316def has_prebuilt(
1317 atom: str,
Alex Klein1699fab2022-09-08 08:46:06 -06001318 build_target: "build_target_lib.BuildTarget" = None,
1319 useflags: Union[Iterable[str], str] = None,
1320) -> bool:
1321 """Check if a prebuilt exists.
Alex Kleinda39c6d2019-09-16 14:36:36 -06001322
Alex Klein1699fab2022-09-08 08:46:06 -06001323 Args:
Alex Klein348e7692022-10-13 17:03:37 -06001324 atom: The package whose prebuilt is being queried.
1325 build_target: The build target whose sysroot should be searched, or the
1326 SDK if not provided.
1327 useflags: Any additional USE flags that should be set. May be a string
1328 of properly formatted USE flags, or an iterable of individual flags.
Alex Kleinad6b48a2020-01-08 16:57:41 -07001329
Alex Klein1699fab2022-09-08 08:46:06 -06001330 Returns:
Alex Klein348e7692022-10-13 17:03:37 -06001331 True if there is an available prebuilt, False otherwise.
Alex Klein1699fab2022-09-08 08:46:06 -06001332 """
1333 assert atom
Alex Kleinda39c6d2019-09-16 14:36:36 -06001334
Alex Klein1699fab2022-09-08 08:46:06 -06001335 board = build_target.name if build_target else None
1336 extra_env = None
1337 if useflags:
1338 new_flags = useflags
1339 if not isinstance(useflags, str):
1340 new_flags = " ".join(useflags)
Alex Klein149fd3b2019-12-16 16:01:05 -07001341
Alex Klein1699fab2022-09-08 08:46:06 -06001342 existing = os.environ.get("USE", "")
1343 final_flags = "%s %s" % (existing, new_flags)
1344 extra_env = {"USE": final_flags.strip()}
1345 return portage_util.HasPrebuilt(atom, board=board, extra_env=extra_env)
Alex Klein36b117f2019-09-30 15:13:46 -06001346
1347
David Burger0f9dd4e2019-10-08 12:33:42 -06001348def builds(atom, build_target, packages=None):
Alex Klein1699fab2022-09-08 08:46:06 -06001349 """Check if |build_target| builds |atom| (has it in its depgraph)."""
1350 cros_build_lib.AssertInsideChroot()
Alex Klein36b117f2019-09-30 15:13:46 -06001351
Alex Klein1699fab2022-09-08 08:46:06 -06001352 pkgs = tuple(packages) if packages else None
1353 # TODO(crbug/1081828): Receive and use sysroot.
1354 graph, _sdk_graph = dependency.GetBuildDependency(
1355 build_target.root, build_target.name, pkgs
1356 )
1357 return any(atom in package for package in graph["package_deps"])
Michael Mortensenb70e8a82019-10-10 18:43:41 -06001358
1359
Alex Klein6becabc2020-09-11 14:03:05 -06001360def needs_chrome_source(
Alex Klein1699fab2022-09-08 08:46:06 -06001361 build_target: "build_target_lib.BuildTarget",
Alex Klein6becabc2020-09-11 14:03:05 -06001362 compile_source=False,
1363 packages: Optional[List[package_info.PackageInfo]] = None,
Alex Klein1699fab2022-09-08 08:46:06 -06001364 useflags=None,
1365):
1366 """Check if the chrome source is needed.
Alex Klein6becabc2020-09-11 14:03:05 -06001367
Alex Klein1699fab2022-09-08 08:46:06 -06001368 The chrome source is needed if the build target builds chrome or any of its
1369 follower packages, and can't use a prebuilt for them either because it's not
1370 available, or because we can't use prebuilts because it must build from
1371 source.
1372 """
1373 cros_build_lib.AssertInsideChroot()
Alex Klein6becabc2020-09-11 14:03:05 -06001374
Alex Klein1699fab2022-09-08 08:46:06 -06001375 # Check if it builds chrome and/or a follower package.
1376 graph = depgraph.get_sysroot_dependency_graph(build_target.root, packages)
1377 builds_chrome = constants.CHROME_CP in graph
1378 builds_follower = {
1379 pkg: pkg in graph for pkg in constants.OTHER_CHROME_PACKAGES
1380 }
Alex Klein6becabc2020-09-11 14:03:05 -06001381
Alex Klein1699fab2022-09-08 08:46:06 -06001382 local_uprev = builds_chrome and revbump_chrome([build_target])
Alex Klein9ce3f682021-06-23 15:06:44 -06001383
Alex Kleinfee86da2023-01-20 18:40:06 -07001384 # When we are compiling source set False since we do not use prebuilts. When
1385 # not compiling from source, start with True, i.e. we have every prebuilt
Alex Klein1699fab2022-09-08 08:46:06 -06001386 # we've checked for up to this point.
1387 has_chrome_prebuilt = not compile_source
1388 has_follower_prebuilts = not compile_source
1389 # Save packages that need prebuilts for reporting.
1390 pkgs_needing_prebuilts = []
1391 if compile_source:
1392 # Need everything.
Alex Klein6becabc2020-09-11 14:03:05 -06001393 pkgs_needing_prebuilts.append(constants.CHROME_CP)
Alex Klein1699fab2022-09-08 08:46:06 -06001394 pkgs_needing_prebuilts.extend(
1395 [pkg for pkg, builds_pkg in builds_follower.items() if builds_pkg]
1396 )
1397 else:
1398 # Check chrome itself.
1399 if builds_chrome:
1400 has_chrome_prebuilt = has_prebuilt(
1401 constants.CHROME_CP,
1402 build_target=build_target,
1403 useflags=useflags,
1404 )
1405 if not has_chrome_prebuilt:
1406 pkgs_needing_prebuilts.append(constants.CHROME_CP)
1407 # Check follower packages.
1408 for pkg, builds_pkg in builds_follower.items():
1409 if not builds_pkg:
1410 continue
1411 prebuilt = has_prebuilt(
1412 pkg, build_target=build_target, useflags=useflags
1413 )
1414 has_follower_prebuilts &= prebuilt
1415 if not prebuilt:
1416 pkgs_needing_prebuilts.append(pkg)
Alex Kleinfee86da2023-01-20 18:40:06 -07001417 # Postcondition: has_chrome_prebuilt and has_follower_prebuilts now
1418 # correctly reflect whether we actually have the corresponding prebuilts for
1419 # the build.
Alex Klein6becabc2020-09-11 14:03:05 -06001420
Alex Klein1699fab2022-09-08 08:46:06 -06001421 needs_chrome = builds_chrome and not has_chrome_prebuilt
1422 needs_follower = (
1423 any(builds_follower.values()) and not has_follower_prebuilts
1424 )
Alex Klein6becabc2020-09-11 14:03:05 -06001425
Alex Klein1699fab2022-09-08 08:46:06 -06001426 return NeedsChromeSourceResult(
1427 needs_chrome_source=needs_chrome or needs_follower,
1428 builds_chrome=builds_chrome,
1429 packages=[package_info.parse(p) for p in pkgs_needing_prebuilts],
1430 missing_chrome_prebuilt=not has_chrome_prebuilt,
1431 missing_follower_prebuilt=not has_follower_prebuilts,
1432 local_uprev=local_uprev,
1433 )
Alex Klein6becabc2020-09-11 14:03:05 -06001434
1435
Alex Klein68a28712021-11-08 11:08:30 -07001436class TargetVersions(NamedTuple):
Alex Klein1699fab2022-09-08 08:46:06 -06001437 """Data class for the info that makes up the "target versions"."""
1438
1439 android_version: str
1440 android_branch: str
1441 android_target: str
1442 chrome_version: str
1443 platform_version: str
1444 milestone_version: str
1445 full_version: str
Gilberto Contreras4f2d1452023-01-30 23:22:58 +00001446 lacros_version: str
Alex Klein68a28712021-11-08 11:08:30 -07001447
1448
1449def get_target_versions(
Alex Klein1699fab2022-09-08 08:46:06 -06001450 build_target: "build_target_lib.BuildTarget",
1451 packages: List[package_info.PackageInfo] = None,
Alex Klein68a28712021-11-08 11:08:30 -07001452) -> TargetVersions:
Alex Klein1699fab2022-09-08 08:46:06 -06001453 """Aggregate version info for a few key packages and the OS as a whole."""
1454 # Android version.
1455 android_version = determine_android_version(build_target.name)
1456 logging.info("Found android version: %s", android_version)
1457 # Android branch version.
1458 android_branch = determine_android_branch(build_target.name)
1459 logging.info("Found android branch version: %s", android_branch)
1460 # Android target version.
1461 android_target = determine_android_target(build_target.name)
1462 logging.info("Found android target version: %s", android_target)
Alex Klein68a28712021-11-08 11:08:30 -07001463
Alex Klein1699fab2022-09-08 08:46:06 -06001464 # TODO(crbug/1019770): Investigate cases where builds_chrome is true but
1465 # chrome_version is None.
Alex Klein68a28712021-11-08 11:08:30 -07001466
Alex Klein1699fab2022-09-08 08:46:06 -06001467 builds_chrome = builds(constants.CHROME_CP, build_target, packages=packages)
1468 chrome_version = None
1469 if builds_chrome:
1470 # Chrome version fetch.
Gilberto Contreras4f2d1452023-01-30 23:22:58 +00001471 chrome_version = determine_package_version(
1472 constants.CHROME_CP, build_target
1473 )
Alex Klein1699fab2022-09-08 08:46:06 -06001474 logging.info("Found chrome version: %s", chrome_version)
Alex Klein68a28712021-11-08 11:08:30 -07001475
Gilberto Contreras4f2d1452023-01-30 23:22:58 +00001476 builds_lacros = builds(constants.LACROS_CP, build_target, packages=packages)
1477 lacros_version = None
1478 if builds_lacros:
1479 # LaCrOS version fetch.
1480 lacros_version = determine_package_version(
1481 constants.LACROS_CP, build_target
1482 )
1483 logging.info("Found LaCrOS version: %s", lacros_version)
1484
Alex Klein1699fab2022-09-08 08:46:06 -06001485 # The ChromeOS version info.
1486 platform_version = determine_platform_version()
1487 milestone_version = determine_milestone_version()
1488 full_version = determine_full_version()
Alex Klein68a28712021-11-08 11:08:30 -07001489
Alex Klein1699fab2022-09-08 08:46:06 -06001490 return TargetVersions(
1491 android_version,
1492 android_branch,
1493 android_target,
1494 chrome_version,
1495 platform_version,
1496 milestone_version,
1497 full_version,
Gilberto Contreras4f2d1452023-01-30 23:22:58 +00001498 lacros_version,
Alex Klein1699fab2022-09-08 08:46:06 -06001499 )
Alex Klein68a28712021-11-08 11:08:30 -07001500
1501
Gilberto Contreras4f2d1452023-01-30 23:22:58 +00001502def determine_package_version(
1503 cpv_name: str,
Alex Klein1699fab2022-09-08 08:46:06 -06001504 build_target: "build_target_lib.BuildTarget",
1505) -> Optional[str]:
Gilberto Contreras4f2d1452023-01-30 23:22:58 +00001506 """Returns the current package version for the board (or in buildroot).
Michael Mortensenc2615b72019-10-15 08:12:24 -06001507
Alex Klein1699fab2022-09-08 08:46:06 -06001508 Args:
Gilberto Contreras4f2d1452023-01-30 23:22:58 +00001509 cpv_name: the name of the ebuild CPV
Alex Klein348e7692022-10-13 17:03:37 -06001510 build_target: The board build target.
Alex Kleinad6b48a2020-01-08 16:57:41 -07001511
Alex Klein1699fab2022-09-08 08:46:06 -06001512 Returns:
Gilberto Contreras4f2d1452023-01-30 23:22:58 +00001513 The version of the package, if available.
Alex Klein1699fab2022-09-08 08:46:06 -06001514 """
1515 # TODO(crbug/1019770): Long term we should not need the try/catch here once
1516 # the builds function above only returns True for chrome when
1517 # determine_chrome_version will succeed.
1518 try:
1519 pkg_info = portage_util.PortageqBestVisible(
Gilberto Contreras4f2d1452023-01-30 23:22:58 +00001520 cpv_name, build_target.name, cwd=constants.SOURCE_ROOT
Alex Klein1699fab2022-09-08 08:46:06 -06001521 )
1522 except cros_build_lib.RunCommandError as e:
1523 # Return None because portage failed when trying to determine the chrome
1524 # version.
1525 logging.warning("Caught exception in determine_chrome_package: %s", e)
1526 return None
1527 # Something like 78.0.3877.4_rc -> 78.0.3877.4
1528 return pkg_info.version.partition("_")[0]
Michael Mortensenc2615b72019-10-15 08:12:24 -06001529
1530
Alex Klein68a28712021-11-08 11:08:30 -07001531@functools.lru_cache()
Matthias Kaehlckebf7d1772021-11-04 16:01:36 -07001532def determine_android_package(board: str) -> Optional[str]:
Alex Klein1699fab2022-09-08 08:46:06 -06001533 """Returns the active Android container package in use by the board.
Michael Mortensenb70e8a82019-10-10 18:43:41 -06001534
Alex Klein1699fab2022-09-08 08:46:06 -06001535 Args:
Alex Klein348e7692022-10-13 17:03:37 -06001536 board: The board name this is specific to.
Alex Kleinad6b48a2020-01-08 16:57:41 -07001537
Alex Klein1699fab2022-09-08 08:46:06 -06001538 Returns:
Alex Klein348e7692022-10-13 17:03:37 -06001539 The android package string if there is one.
Alex Klein1699fab2022-09-08 08:46:06 -06001540 """
1541 try:
1542 packages = portage_util.GetPackageDependencies(
1543 "virtual/target-os", board=board
1544 )
1545 except cros_build_lib.RunCommandError as e:
1546 # Return None because a command (likely portage) failed when trying to
1547 # determine the package.
1548 logging.warning("Caught exception in determine_android_package: %s", e)
1549 return None
1550
1551 # We assume there is only one Android package in the depgraph.
1552 for package in packages:
1553 if package.startswith(
1554 "chromeos-base/android-container-"
1555 ) or package.startswith("chromeos-base/android-vm-"):
1556 return package
Michael Mortensene0f4b542019-10-24 15:30:23 -06001557 return None
Michael Mortensenb70e8a82019-10-10 18:43:41 -06001558
1559
Matthias Kaehlckebf7d1772021-11-04 16:01:36 -07001560def determine_android_version(board: str, package: str = None):
Alex Klein1699fab2022-09-08 08:46:06 -06001561 """Determine the current Android version in buildroot now and return it.
Michael Mortensenb70e8a82019-10-10 18:43:41 -06001562
Alex Klein1699fab2022-09-08 08:46:06 -06001563 This uses the typical portage logic to determine which version of Android
1564 is active right now in the buildroot.
Michael Mortensenb70e8a82019-10-10 18:43:41 -06001565
Alex Klein1699fab2022-09-08 08:46:06 -06001566 Args:
Alex Klein348e7692022-10-13 17:03:37 -06001567 board: The board name this is specific to.
1568 package: The Android package, if already computed.
Michael Mortensenb70e8a82019-10-10 18:43:41 -06001569
Alex Klein1699fab2022-09-08 08:46:06 -06001570 Returns:
Alex Klein348e7692022-10-13 17:03:37 -06001571 The Android build ID of the container for the board.
Michael Mortensenb70e8a82019-10-10 18:43:41 -06001572
Alex Klein1699fab2022-09-08 08:46:06 -06001573 Raises:
Alex Klein348e7692022-10-13 17:03:37 -06001574 NoAndroidVersionError: if no unique Android version can be determined.
Alex Klein1699fab2022-09-08 08:46:06 -06001575 """
1576 if not package:
1577 package = determine_android_package(board)
1578 if not package:
1579 return None
1580 cpv = package_info.SplitCPV(package)
1581 if not cpv:
1582 raise NoAndroidVersionError(
1583 "Android version could not be determined for %s" % board
1584 )
1585 return cpv.version_no_rev
Michael Mortensenb70e8a82019-10-10 18:43:41 -06001586
Alex Klein7a3a7dd2020-01-08 16:44:38 -07001587
Mike Frysinger8e1c99a2021-03-05 00:58:11 -05001588def determine_android_branch(board, package=None):
Alex Klein1699fab2022-09-08 08:46:06 -06001589 """Returns the Android branch in use by the active container ebuild."""
1590 if not package:
1591 package = determine_android_package(board)
1592 if not package:
1593 return None
1594 ebuild_path = portage_util.FindEbuildForBoardPackage(package, board)
1595 # We assume all targets pull from the same branch and that we always
1596 # have at least one of the following targets.
Shao-Chuan Leeca2cbcc2022-11-02 08:28:31 +09001597 # TODO(b/187795671): Do this in a less hacky way.
1598 targets = android.GetAllAndroidEbuildTargets()
Alex Klein1699fab2022-09-08 08:46:06 -06001599 ebuild_content = osutils.SourceEnvironment(ebuild_path, targets)
1600 for target in targets:
1601 if target in ebuild_content:
1602 branch = re.search(r"(.*?)-linux-", ebuild_content[target])
1603 if branch is not None:
1604 return branch.group(1)
1605 raise NoAndroidBranchError(
1606 "Android branch could not be determined for %s (ebuild empty?)" % board
1607 )
Michael Mortensenb70e8a82019-10-10 18:43:41 -06001608
1609
Mike Frysinger8e1c99a2021-03-05 00:58:11 -05001610def determine_android_target(board, package=None):
Alex Klein1699fab2022-09-08 08:46:06 -06001611 """Returns the Android target in use by the active container ebuild."""
1612 if not package:
1613 package = determine_android_package(board)
1614 if not package:
1615 return None
1616 if package.startswith("chromeos-base/android-vm-"):
1617 return "bertha"
1618 elif package.startswith("chromeos-base/android-container-"):
1619 return "cheets"
Michael Mortensenb70e8a82019-10-10 18:43:41 -06001620
Alex Klein1699fab2022-09-08 08:46:06 -06001621 raise NoAndroidTargetError(
1622 "Android Target cannot be determined for the package: %s" % package
1623 )
Michael Mortensen9fdb14b2019-10-17 11:17:30 -06001624
1625
1626def determine_platform_version():
Alex Klein1699fab2022-09-08 08:46:06 -06001627 """Returns the platform version from the source root."""
1628 # Platform version is something like '12575.0.0'.
1629 version = chromeos_version.VersionInfo.from_repo(constants.SOURCE_ROOT)
1630 return version.VersionString()
Michael Mortensen009cb662019-10-21 11:38:43 -06001631
1632
1633def determine_milestone_version():
Alex Klein1699fab2022-09-08 08:46:06 -06001634 """Returns the platform version from the source root."""
1635 # Milestone version is something like '79'.
1636 version = chromeos_version.VersionInfo.from_repo(constants.SOURCE_ROOT)
1637 return version.chrome_branch
Michael Mortensen009cb662019-10-21 11:38:43 -06001638
Alex Klein7a3a7dd2020-01-08 16:44:38 -07001639
Michael Mortensen009cb662019-10-21 11:38:43 -06001640def determine_full_version():
Alex Klein1699fab2022-09-08 08:46:06 -06001641 """Returns the full version from the source root."""
1642 # Full version is something like 'R79-12575.0.0'.
1643 milestone_version = determine_milestone_version()
1644 platform_version = determine_platform_version()
1645 full_version = "R%s-%s" % (milestone_version, platform_version)
1646 return full_version
Michael Mortensen71ef5682020-05-07 14:29:24 -06001647
1648
Matthias Kaehlckebf7d1772021-11-04 16:01:36 -07001649def find_fingerprints(
Alex Klein1699fab2022-09-08 08:46:06 -06001650 build_target: "build_target_lib.BuildTarget",
1651) -> List[str]:
1652 """Returns a list of fingerprints for this build.
Michael Mortensende716a12020-05-15 11:27:00 -06001653
Alex Klein1699fab2022-09-08 08:46:06 -06001654 Args:
Alex Klein348e7692022-10-13 17:03:37 -06001655 build_target: The build target.
Michael Mortensende716a12020-05-15 11:27:00 -06001656
Alex Klein1699fab2022-09-08 08:46:06 -06001657 Returns:
Alex Klein348e7692022-10-13 17:03:37 -06001658 List of fingerprint strings.
Alex Klein1699fab2022-09-08 08:46:06 -06001659 """
1660 cros_build_lib.AssertInsideChroot()
1661 fp_file = "cheets-fingerprint.txt"
1662 fp_path = os.path.join(
1663 image_lib.GetLatestImageLink(build_target.name), fp_file
1664 )
1665 if not os.path.isfile(fp_path):
1666 logging.info("Fingerprint file not found: %s", fp_path)
1667 return []
1668 logging.info("Reading fingerprint file: %s", fp_path)
1669 fingerprints = osutils.ReadFile(fp_path).splitlines()
1670 return fingerprints
Michael Mortensende716a12020-05-15 11:27:00 -06001671
1672
Alex Klein1699fab2022-09-08 08:46:06 -06001673def get_all_firmware_versions(build_target: "build_target_lib.BuildTarget"):
1674 """Extract firmware version for all models present.
Michael Mortensen59e30872020-05-18 14:12:49 -06001675
Alex Klein1699fab2022-09-08 08:46:06 -06001676 Args:
Alex Klein348e7692022-10-13 17:03:37 -06001677 build_target: The build target.
Michael Mortensen59e30872020-05-18 14:12:49 -06001678
Alex Klein1699fab2022-09-08 08:46:06 -06001679 Returns:
Alex Klein348e7692022-10-13 17:03:37 -06001680 A dict of FirmwareVersions namedtuple instances by model.
1681 Each element will be populated based on whether it was present in the
1682 command output.
Alex Klein1699fab2022-09-08 08:46:06 -06001683 """
1684 cros_build_lib.AssertInsideChroot()
1685 result = {}
1686 # Note that example output for _get_firmware_version_cmd_result is available
1687 # in the packages_unittest.py for testing get_all_firmware_versions.
1688 cmd_result = _get_firmware_version_cmd_result(build_target)
Michael Mortensen59e30872020-05-18 14:12:49 -06001689
Alex Klein1699fab2022-09-08 08:46:06 -06001690 if cmd_result:
1691 # There is a blank line between the version info for each model.
1692 firmware_version_payloads = cmd_result.split("\n\n")
1693 for firmware_version_payload in firmware_version_payloads:
1694 if "BIOS" in firmware_version_payload:
1695 firmware_version = _find_firmware_versions(
1696 firmware_version_payload
1697 )
1698 result[firmware_version.model] = firmware_version
1699 return result
Michael Mortensen59e30872020-05-18 14:12:49 -06001700
1701
Benjamin Shai0858cd32022-01-10 20:23:49 +00001702class FirmwareVersions(NamedTuple):
Alex Klein1699fab2022-09-08 08:46:06 -06001703 """Tuple to hold firmware versions, with truthiness."""
Benjamin Shai0858cd32022-01-10 20:23:49 +00001704
Alex Klein1699fab2022-09-08 08:46:06 -06001705 model: Optional[str]
1706 main: Optional[str]
1707 main_rw: Optional[str]
1708 ec: Optional[str]
1709 ec_rw: Optional[str]
1710
1711 def __bool__(self):
1712 return bool(
1713 self.model or self.main or self.main_rw or self.ec or self.ec_rw
1714 )
Michael Mortensen71ef5682020-05-07 14:29:24 -06001715
1716
Alex Klein1699fab2022-09-08 08:46:06 -06001717def get_firmware_versions(build_target: "build_target_lib.BuildTarget"):
1718 """Extract version information from the firmware updater, if one exists.
Michael Mortensen71ef5682020-05-07 14:29:24 -06001719
Alex Klein1699fab2022-09-08 08:46:06 -06001720 Args:
Alex Klein348e7692022-10-13 17:03:37 -06001721 build_target: The build target.
Michael Mortensen71ef5682020-05-07 14:29:24 -06001722
Alex Klein1699fab2022-09-08 08:46:06 -06001723 Returns:
Alex Klein348e7692022-10-13 17:03:37 -06001724 A FirmwareVersions namedtuple instance.
1725 Each element will either be set to the string output by the firmware
1726 updater shellball, or None if there is no firmware updater.
Alex Klein1699fab2022-09-08 08:46:06 -06001727 """
1728 cros_build_lib.AssertInsideChroot()
1729 cmd_result = _get_firmware_version_cmd_result(build_target)
1730 if cmd_result:
1731 return _find_firmware_versions(cmd_result)
1732 else:
1733 return FirmwareVersions(None, None, None, None, None)
Michael Mortensen71ef5682020-05-07 14:29:24 -06001734
1735
Matthias Kaehlckebf7d1772021-11-04 16:01:36 -07001736def _get_firmware_version_cmd_result(
Alex Klein1699fab2022-09-08 08:46:06 -06001737 build_target: "build_target_lib.BuildTarget",
1738) -> Optional[str]:
1739 """Gets the raw result output of the firmware updater version command.
Michael Mortensen71ef5682020-05-07 14:29:24 -06001740
Alex Klein1699fab2022-09-08 08:46:06 -06001741 Args:
Alex Klein348e7692022-10-13 17:03:37 -06001742 build_target: The build target.
Michael Mortensen71ef5682020-05-07 14:29:24 -06001743
Alex Klein1699fab2022-09-08 08:46:06 -06001744 Returns:
Alex Klein348e7692022-10-13 17:03:37 -06001745 Command execution result.
Alex Klein1699fab2022-09-08 08:46:06 -06001746 """
1747 updater = os.path.join(
1748 build_target.root, "usr/sbin/chromeos-firmwareupdate"
1749 )
1750 logging.info("Calling updater %s", updater)
1751 # Call the updater using the chroot-based path.
1752 try:
1753 return cros_build_lib.run(
1754 [updater, "-V"],
1755 capture_output=True,
1756 log_output=True,
1757 encoding="utf-8",
1758 ).stdout
1759 except cros_build_lib.RunCommandError:
1760 # Updater probably doesn't exist (e.g. betty).
1761 return None
Michael Mortensen71ef5682020-05-07 14:29:24 -06001762
1763
1764def _find_firmware_versions(cmd_output):
Alex Klein1699fab2022-09-08 08:46:06 -06001765 """Finds firmware version output via regex matches against the cmd_output.
Michael Mortensen71ef5682020-05-07 14:29:24 -06001766
Alex Klein1699fab2022-09-08 08:46:06 -06001767 Args:
Alex Klein348e7692022-10-13 17:03:37 -06001768 cmd_output: The raw output to search against.
Michael Mortensen71ef5682020-05-07 14:29:24 -06001769
Alex Klein1699fab2022-09-08 08:46:06 -06001770 Returns:
Alex Klein348e7692022-10-13 17:03:37 -06001771 FirmwareVersions namedtuple with results.
1772 Each element will either be set to the string output by the firmware
1773 updater shellball, or None if there is no match.
Alex Klein1699fab2022-09-08 08:46:06 -06001774 """
Michael Mortensen71ef5682020-05-07 14:29:24 -06001775
Alex Klein1699fab2022-09-08 08:46:06 -06001776 # Sometimes a firmware bundle includes a special combination of RO+RW
1777 # firmware. In this case, the RW firmware version is indicated with a "(RW)
1778 # version" field. In other cases, the "(RW) version" field is not present.
1779 # Therefore, search for the "(RW)" fields first and if they aren't present,
1780 # fallback to the other format. e.g. just "BIOS version:".
1781 # TODO(mmortensen): Use JSON once the firmware updater supports it.
1782 main = None
1783 main_rw = None
1784 ec = None
1785 ec_rw = None
1786 model = None
Michael Mortensen71ef5682020-05-07 14:29:24 -06001787
Alex Klein1699fab2022-09-08 08:46:06 -06001788 match = re.search(r"BIOS version:\s*(?P<version>.*)", cmd_output)
1789 if match:
1790 main = match.group("version")
Michael Mortensen71ef5682020-05-07 14:29:24 -06001791
Alex Klein1699fab2022-09-08 08:46:06 -06001792 match = re.search(r"BIOS \(RW\) version:\s*(?P<version>.*)", cmd_output)
1793 if match:
1794 main_rw = match.group("version")
Michael Mortensen71ef5682020-05-07 14:29:24 -06001795
Alex Klein1699fab2022-09-08 08:46:06 -06001796 match = re.search(r"EC version:\s*(?P<version>.*)", cmd_output)
1797 if match:
1798 ec = match.group("version")
Michael Mortensen71ef5682020-05-07 14:29:24 -06001799
Alex Klein1699fab2022-09-08 08:46:06 -06001800 match = re.search(r"EC \(RW\) version:\s*(?P<version>.*)", cmd_output)
1801 if match:
1802 ec_rw = match.group("version")
Michael Mortensen71ef5682020-05-07 14:29:24 -06001803
Alex Klein1699fab2022-09-08 08:46:06 -06001804 match = re.search(r"Model:\s*(?P<model>.*)", cmd_output)
1805 if match:
1806 model = match.group("model")
Michael Mortensen71ef5682020-05-07 14:29:24 -06001807
Alex Klein1699fab2022-09-08 08:46:06 -06001808 return FirmwareVersions(model, main, main_rw, ec, ec_rw)
Michael Mortensena4af79e2020-05-06 16:18:48 -06001809
1810
Benjamin Shai0858cd32022-01-10 20:23:49 +00001811class MainEcFirmwareVersions(NamedTuple):
Alex Klein1699fab2022-09-08 08:46:06 -06001812 """Tuple to hold main and ec firmware versions, with truthiness."""
Benjamin Shai0858cd32022-01-10 20:23:49 +00001813
Alex Klein1699fab2022-09-08 08:46:06 -06001814 main_fw_version: Optional[str]
1815 ec_fw_version: Optional[str]
1816
1817 def __bool__(self):
1818 return bool(self.main_fw_version or self.ec_fw_version)
Benjamin Shai0858cd32022-01-10 20:23:49 +00001819
Michael Mortensena4af79e2020-05-06 16:18:48 -06001820
Alex Klein1699fab2022-09-08 08:46:06 -06001821def determine_firmware_versions(build_target: "build_target_lib.BuildTarget"):
1822 """Returns a namedtuple with main and ec firmware versions.
Michael Mortensena4af79e2020-05-06 16:18:48 -06001823
Alex Klein1699fab2022-09-08 08:46:06 -06001824 Args:
Alex Klein348e7692022-10-13 17:03:37 -06001825 build_target: The build target.
Michael Mortensena4af79e2020-05-06 16:18:48 -06001826
Alex Klein1699fab2022-09-08 08:46:06 -06001827 Returns:
Alex Klein348e7692022-10-13 17:03:37 -06001828 MainEcFirmwareVersions namedtuple with results.
Alex Klein1699fab2022-09-08 08:46:06 -06001829 """
1830 fw_versions = get_firmware_versions(build_target)
1831 main_fw_version = fw_versions.main_rw or fw_versions.main
1832 ec_fw_version = fw_versions.ec_rw or fw_versions.ec
Michael Mortensena4af79e2020-05-06 16:18:48 -06001833
Alex Klein1699fab2022-09-08 08:46:06 -06001834 return MainEcFirmwareVersions(main_fw_version, ec_fw_version)
Michael Mortensenfbf2b2d2020-05-14 16:33:06 -06001835
Benjamin Shai0858cd32022-01-10 20:23:49 +00001836
Matthias Kaehlckebf7d1772021-11-04 16:01:36 -07001837def determine_kernel_version(
Alex Klein1699fab2022-09-08 08:46:06 -06001838 build_target: "build_target_lib.BuildTarget",
Lizzy Presland0b978e62022-09-09 16:55:29 +00001839) -> str:
Alex Klein1699fab2022-09-08 08:46:06 -06001840 """Returns a string containing the kernel version for this build target.
Michael Mortensenfbf2b2d2020-05-14 16:33:06 -06001841
Alex Klein1699fab2022-09-08 08:46:06 -06001842 Args:
Alex Klein348e7692022-10-13 17:03:37 -06001843 build_target: The build target.
Michael Mortensenfbf2b2d2020-05-14 16:33:06 -06001844
Alex Klein1699fab2022-09-08 08:46:06 -06001845 Returns:
Alex Klein348e7692022-10-13 17:03:37 -06001846 The kernel versions, or empty string.
Alex Klein1699fab2022-09-08 08:46:06 -06001847 """
Lizzy Presland0b978e62022-09-09 16:55:29 +00001848 target_virtual_pkg = "virtual/linux-sources"
Alex Klein1699fab2022-09-08 08:46:06 -06001849 try:
Lizzy Presland0b978e62022-09-09 16:55:29 +00001850 candidate_packages = portage_util.GetFlattenedDepsForPackage(
1851 target_virtual_pkg,
1852 sysroot=build_target.root,
1853 board=build_target.name,
1854 depth=1,
1855 )
1856 installed_packages = portage_util.GetPackageDependencies(
1857 target_virtual_pkg, board=build_target.name
Alex Klein1699fab2022-09-08 08:46:06 -06001858 )
1859 except cros_build_lib.RunCommandError as e:
1860 logging.warning("Unable to get package list for metadata: %s", e)
Lizzy Presland0b978e62022-09-09 16:55:29 +00001861 return ""
1862 if not candidate_packages:
1863 raise KernelVersionError("No package found in FlattenedDepsForPackage")
1864 if not installed_packages:
1865 raise KernelVersionError("No package found in GetPackageDependencies")
1866 packages = [
1867 p
1868 for p in installed_packages
1869 if p in candidate_packages and target_virtual_pkg not in p
1870 ]
1871 if len(packages) == 0:
1872 raise KernelVersionError(
1873 "No matches for installed packages were found in candidate "
1874 "packages. Did GetFlattenedDepsForPackage search all possible "
1875 "package versions?\tInstalled: %s\tCandidates: %s"
1876 % (" ".join(installed_packages), " ".join(candidate_packages))
1877 )
1878 if len(packages) > 1:
1879 raise KernelVersionError(
1880 "Too many packages found in intersection of installed packages and "
1881 "possible kernel versions (%s)" % "".join(packages)
1882 )
1883 kernel_version = package_info.SplitCPV(packages[0]).version
1884 logging.info("Found active kernel version: %s", kernel_version)
1885 return kernel_version
Michael Mortensen125bb012020-05-21 14:02:10 -06001886
1887
Matthias Kaehlckebf7d1772021-11-04 16:01:36 -07001888def get_models(
Alex Klein1699fab2022-09-08 08:46:06 -06001889 build_target: "build_target_lib.BuildTarget", log_output: bool = True
1890) -> Optional[List[str]]:
1891 """Obtain a list of models supported by a unified board.
Michael Mortensen125bb012020-05-21 14:02:10 -06001892
Alex Klein1699fab2022-09-08 08:46:06 -06001893 This ignored whitelabel models since GoldenEye has no specific support for
1894 these at present.
Michael Mortensen125bb012020-05-21 14:02:10 -06001895
Alex Klein1699fab2022-09-08 08:46:06 -06001896 Args:
Alex Klein348e7692022-10-13 17:03:37 -06001897 build_target: The build target.
1898 log_output: Whether to log the output of the cros_config_host
1899 invocation.
Michael Mortensen125bb012020-05-21 14:02:10 -06001900
Alex Klein1699fab2022-09-08 08:46:06 -06001901 Returns:
Alex Klein348e7692022-10-13 17:03:37 -06001902 A list of models supported by this board, if it is a unified build;
1903 None, if it is not a unified build.
Alex Klein1699fab2022-09-08 08:46:06 -06001904 """
1905 return _run_cros_config_host(
1906 build_target, ["list-models"], log_output=log_output
1907 )
Michael Mortensen125bb012020-05-21 14:02:10 -06001908
1909
Matthias Kaehlckebf7d1772021-11-04 16:01:36 -07001910def get_key_id(
Alex Klein1699fab2022-09-08 08:46:06 -06001911 build_target: "build_target_lib.BuildTarget", model: str
1912) -> Optional[str]:
1913 """Obtain the key_id for a model within the build_target.
Michael Mortensen359c1f32020-05-28 19:35:42 -06001914
Alex Klein1699fab2022-09-08 08:46:06 -06001915 Args:
Alex Klein348e7692022-10-13 17:03:37 -06001916 build_target: The build target.
1917 model: The model name
Michael Mortensen359c1f32020-05-28 19:35:42 -06001918
Alex Klein1699fab2022-09-08 08:46:06 -06001919 Returns:
Alex Klein348e7692022-10-13 17:03:37 -06001920 A key_id or None.
Alex Klein1699fab2022-09-08 08:46:06 -06001921 """
1922 model_arg = "--model=" + model
1923 key_id_list = _run_cros_config_host(
1924 build_target, [model_arg, "get", "/firmware-signing", "key-id"]
1925 )
1926 key_id = None
1927 if len(key_id_list) == 1:
1928 key_id = key_id_list[0]
1929 return key_id
Michael Mortensen359c1f32020-05-28 19:35:42 -06001930
1931
Matthias Kaehlckebf7d1772021-11-04 16:01:36 -07001932def _run_cros_config_host(
Alex Klein1699fab2022-09-08 08:46:06 -06001933 build_target: "build_target_lib.BuildTarget",
Matthias Kaehlckebf7d1772021-11-04 16:01:36 -07001934 args: List[str],
Alex Klein1699fab2022-09-08 08:46:06 -06001935 log_output: bool = True,
1936) -> Optional[List[str]]:
1937 """Run the cros_config_host tool.
Michael Mortensen125bb012020-05-21 14:02:10 -06001938
Alex Klein1699fab2022-09-08 08:46:06 -06001939 Args:
Alex Klein348e7692022-10-13 17:03:37 -06001940 build_target: The build target.
1941 args: List of arguments to pass.
1942 log_output: Whether to log the output of the cros_config_host.
Michael Mortensen125bb012020-05-21 14:02:10 -06001943
Alex Klein1699fab2022-09-08 08:46:06 -06001944 Returns:
Alex Klein348e7692022-10-13 17:03:37 -06001945 Output of the tool
Alex Klein1699fab2022-09-08 08:46:06 -06001946 """
1947 cros_build_lib.AssertInsideChroot()
1948 tool = "/usr/bin/cros_config_host"
1949 if not os.path.isfile(tool):
1950 return None
Michael Mortensen125bb012020-05-21 14:02:10 -06001951
Alex Klein1699fab2022-09-08 08:46:06 -06001952 config_fname = build_target.full_path(
1953 "usr/share/chromeos-config/yaml/config.yaml"
1954 )
Michael Mortensen125bb012020-05-21 14:02:10 -06001955
Alex Klein1699fab2022-09-08 08:46:06 -06001956 result = cros_build_lib.run(
1957 [tool, "-c", config_fname] + args,
1958 capture_output=True,
1959 encoding="utf-8",
1960 log_output=log_output,
1961 check=False,
1962 )
1963 if result.returncode:
1964 # Show the output for debugging purposes.
1965 if "No such file or directory" not in result.stderr:
1966 logging.error("cros_config_host failed: %s\n", result.stderr)
1967 return None
1968 return result.stdout.strip().splitlines()