blob: c5d9b05f95bddcc8b0e10cbdb05e633061613e71 [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
Ben Reiche779cf42020-12-15 03:21:31 +00008from distutils.version import LooseVersion
Yaakov Shaulcb1cfc32019-09-16 13:51:19 -06009import fileinput
Alex Klein87531182019-08-12 15:23:37 -060010import functools
Yaakov Shaul395ae832019-09-09 14:45:32 -060011import json
Chris McDonaldf7c03d42021-07-21 11:54:26 -060012import logging
Evan Hernandezb51f1522019-08-15 11:29:40 -060013import os
Michael Mortensenb70e8a82019-10-10 18:43:41 -060014import re
Yaakov Shaulcb1cfc32019-09-16 13:51:19 -060015import sys
Alex Klein68a28712021-11-08 11:08:30 -070016from typing import Iterable, List, NamedTuple, Optional, TYPE_CHECKING, Union
Alex Klein87531182019-08-12 15:23:37 -060017
Mike Frysinger2c024062021-05-22 15:43:22 -040018from chromite.third_party.google.protobuf import json_format
Yaakov Shaul730814a2019-09-10 13:58:25 -060019
Andrew Lamb2bde9e42019-11-04 13:24:09 -070020from chromite.api.gen.config import replication_config_pb2
Ram Chandrasekar60f69f32022-06-03 22:49:30 +000021from chromite.lib import chromeos_version
Alex Kleineb77ffa2019-05-28 14:47:44 -060022from chromite.lib import constants
Evan Hernandezb51f1522019-08-15 11:29:40 -060023from chromite.lib import cros_build_lib
Alex Kleineb77ffa2019-05-28 14:47:44 -060024from chromite.lib import git
Michael Mortensende716a12020-05-15 11:27:00 -060025from chromite.lib import image_lib
Michael Mortensenb70e8a82019-10-10 18:43:41 -060026from chromite.lib import osutils
Alex Kleineb77ffa2019-05-28 14:47:44 -060027from chromite.lib import portage_util
Andrew Lamb2bde9e42019-11-04 13:24:09 -070028from chromite.lib import replication_lib
Alex Kleind6195b62019-08-06 16:01:16 -060029from chromite.lib import uprev_lib
Alex Klein18a60af2020-06-11 12:08:47 -060030from chromite.lib.parser import package_info
Shao-Chuan Lee05e51142021-11-24 12:27:37 +090031from chromite.service import android
Alex Kleineb77ffa2019-05-28 14:47:44 -060032
Mike Frysinger68796b52019-08-25 00:04:27 -040033
Alex Klein5caab872021-09-10 11:44:37 -060034if TYPE_CHECKING:
Alex Klein1699fab2022-09-08 08:46:06 -060035 from chromite.lib import build_target_lib
36 from chromite.lib import chroot_lib
Chris McDonaldf7c03d42021-07-21 11:54:26 -060037
Alex Klein36b117f2019-09-30 15:13:46 -060038if cros_build_lib.IsInsideChroot():
Alex Klein1699fab2022-09-08 08:46:06 -060039 from chromite.lib import depgraph
40 from chromite.service import dependency
Alex Klein36b117f2019-09-30 15:13:46 -060041
Alex Klein87531182019-08-12 15:23:37 -060042# Registered handlers for uprevving versioned packages.
43_UPREV_FUNCS = {}
44
Alex Kleineb77ffa2019-05-28 14:47:44 -060045
46class Error(Exception):
Alex Klein1699fab2022-09-08 08:46:06 -060047 """Module's base error class."""
Alex Kleineb77ffa2019-05-28 14:47:44 -060048
49
Alex Klein4de25e82019-08-05 15:58:39 -060050class UnknownPackageError(Error):
Alex Klein1699fab2022-09-08 08:46:06 -060051 """Uprev attempted for a package without a registered handler."""
Alex Klein4de25e82019-08-05 15:58:39 -060052
53
Alex Kleineb77ffa2019-05-28 14:47:44 -060054class UprevError(Error):
Alex Klein1699fab2022-09-08 08:46:06 -060055 """An error occurred while uprevving packages."""
Alex Kleineb77ffa2019-05-28 14:47:44 -060056
57
Michael Mortensenb70e8a82019-10-10 18:43:41 -060058class NoAndroidVersionError(Error):
Alex Klein1699fab2022-09-08 08:46:06 -060059 """An error occurred while trying to determine the android version."""
Michael Mortensenb70e8a82019-10-10 18:43:41 -060060
61
62class NoAndroidBranchError(Error):
Alex Klein1699fab2022-09-08 08:46:06 -060063 """An error occurred while trying to determine the android branch."""
Michael Mortensenb70e8a82019-10-10 18:43:41 -060064
65
66class NoAndroidTargetError(Error):
Alex Klein1699fab2022-09-08 08:46:06 -060067 """An error occurred while trying to determine the android target."""
Michael Mortensenb70e8a82019-10-10 18:43:41 -060068
69
Lizzy Presland0b978e62022-09-09 16:55:29 +000070class KernelVersionError(Error):
71 """An error occurred while trying to determine the kernel version."""
72
73
Alex Klein4de25e82019-08-05 15:58:39 -060074class AndroidIsPinnedUprevError(UprevError):
Alex Klein1699fab2022-09-08 08:46:06 -060075 """Raised when we try to uprev while Android is pinned."""
Alex Klein4de25e82019-08-05 15:58:39 -060076
Alex Klein1699fab2022-09-08 08:46:06 -060077 def __init__(self, new_android_atom):
78 """Initialize a AndroidIsPinnedUprevError.
Alex Klein4de25e82019-08-05 15:58:39 -060079
Alex Klein1699fab2022-09-08 08:46:06 -060080 Args:
Alex Klein348e7692022-10-13 17:03:37 -060081 new_android_atom: The Android atom that we failed to uprev to, due
82 to Android being pinned.
Alex Klein1699fab2022-09-08 08:46:06 -060083 """
84 assert new_android_atom
85 msg = (
86 "Failed up uprev to Android version %s as Android was pinned."
87 % new_android_atom
88 )
89 super().__init__(msg)
90 self.new_android_atom = new_android_atom
Alex Klein87531182019-08-12 15:23:37 -060091
92
Andrew Lamb9563a152019-12-04 11:42:18 -070093class GeneratedCrosConfigFilesError(Error):
Alex Klein1699fab2022-09-08 08:46:06 -060094 """Error when cros_config_schema does not produce expected files"""
Andrew Lamb9563a152019-12-04 11:42:18 -070095
Alex Klein1699fab2022-09-08 08:46:06 -060096 def __init__(self, expected_files, found_files):
97 msg = "Expected to find generated C files: %s. Actually found: %s" % (
98 expected_files,
99 found_files,
100 )
101 super().__init__(msg)
Andrew Lamb9563a152019-12-04 11:42:18 -0700102
Alex Klein7a3a7dd2020-01-08 16:44:38 -0700103
Alex Klein1699fab2022-09-08 08:46:06 -0600104NeedsChromeSourceResult = collections.namedtuple(
105 "NeedsChromeSourceResult",
106 (
107 "needs_chrome_source",
108 "builds_chrome",
109 "packages",
110 "missing_chrome_prebuilt",
111 "missing_follower_prebuilt",
112 "local_uprev",
113 ),
114)
Alex Klein6becabc2020-09-11 14:03:05 -0600115
116
Yaakov Shaulcb1cfc32019-09-16 13:51:19 -0600117def patch_ebuild_vars(ebuild_path, variables):
Alex Klein1699fab2022-09-08 08:46:06 -0600118 """Updates variables in ebuild.
Yaakov Shaulcb1cfc32019-09-16 13:51:19 -0600119
Alex Klein1699fab2022-09-08 08:46:06 -0600120 Use this function rather than portage_util.EBuild.UpdateEBuild when you
121 want to preserve the variable position and quotes within the ebuild.
Yaakov Shaulcb1cfc32019-09-16 13:51:19 -0600122
Alex Klein1699fab2022-09-08 08:46:06 -0600123 Args:
Alex Klein348e7692022-10-13 17:03:37 -0600124 ebuild_path: The path of the ebuild.
125 variables: Dictionary of variables to update in ebuild.
Alex Klein1699fab2022-09-08 08:46:06 -0600126 """
127 try:
128 for line in fileinput.input(ebuild_path, inplace=1):
129 for var, value in variables.items():
130 line = re.sub(rf"\b{var}=\S+", f'{var}="{value}"', line)
131 sys.stdout.write(line)
132 finally:
133 fileinput.close()
Yaakov Shaulcb1cfc32019-09-16 13:51:19 -0600134
135
Alex Klein87531182019-08-12 15:23:37 -0600136def uprevs_versioned_package(package):
Alex Klein1699fab2022-09-08 08:46:06 -0600137 """Decorator to register package uprev handlers."""
138 assert package
Alex Klein87531182019-08-12 15:23:37 -0600139
Alex Klein1699fab2022-09-08 08:46:06 -0600140 def register(func):
141 """Registers |func| as a handler for |package|."""
142 _UPREV_FUNCS[package] = func
Alex Klein87531182019-08-12 15:23:37 -0600143
Alex Klein1699fab2022-09-08 08:46:06 -0600144 @functools.wraps(func)
145 def pass_through(*args, **kwargs):
146 return func(*args, **kwargs)
Alex Klein87531182019-08-12 15:23:37 -0600147
Alex Klein1699fab2022-09-08 08:46:06 -0600148 return pass_through
Alex Klein87531182019-08-12 15:23:37 -0600149
Alex Klein1699fab2022-09-08 08:46:06 -0600150 return register
Alex Klein87531182019-08-12 15:23:37 -0600151
152
Shao-Chuan Lee84bf9a22021-11-19 17:42:11 +0900153class UprevAndroidResult(NamedTuple):
Alex Klein1699fab2022-09-08 08:46:06 -0600154 """Results of an Android uprev."""
155
156 revved: bool
157 android_atom: str = None
158 modified_files: List[str] = None
Shao-Chuan Lee84bf9a22021-11-19 17:42:11 +0900159
160
161def uprev_android(
162 android_package: str,
Alex Klein1699fab2022-09-08 08:46:06 -0600163 chroot: "chroot_lib.Chroot",
164 build_targets: Optional[List["build_target_lib.BuildTarget"]] = None,
Shao-Chuan Lee84bf9a22021-11-19 17:42:11 +0900165 android_build_branch: Optional[str] = None,
166 android_version: Optional[str] = None,
Alex Klein1699fab2022-09-08 08:46:06 -0600167 skip_commit: bool = False,
168) -> UprevAndroidResult:
169 """Performs an Android uprev by calling cros_mark_android_as_stable.
Shao-Chuan Lee84bf9a22021-11-19 17:42:11 +0900170
Alex Klein1699fab2022-09-08 08:46:06 -0600171 Args:
Alex Klein348e7692022-10-13 17:03:37 -0600172 android_package: The Android package to uprev.
173 chroot: The chroot to enter.
174 build_targets: List of build targets to cleanup after uprev.
175 android_build_branch: Override the default Android branch corresponding
176 to the package.
177 android_version: Uprev to the particular version. By default the latest
178 available version is used.
179 skip_commit: Whether to skip committing the change after a successful
180 uprev.
Shao-Chuan Lee84bf9a22021-11-19 17:42:11 +0900181
Alex Klein1699fab2022-09-08 08:46:06 -0600182 Returns:
Alex Klein348e7692022-10-13 17:03:37 -0600183 The uprev result containing:
184 revved: Whether an uprev happened.
185 android_atom: If revved, the portage atom for the revved Android
186 ebuild.
187 modified_files: If revved, list of files being modified.
Alex Klein1699fab2022-09-08 08:46:06 -0600188 """
189 command = [
190 "cros_mark_android_as_stable",
191 f"--android_package={android_package}",
192 ]
193 if build_targets:
194 command.append(f'--boards={":".join(bt.name for bt in build_targets)}')
195 if android_build_branch:
196 command.append(f"--android_build_branch={android_build_branch}")
197 if android_version:
198 command.append(f"--force_version={android_version}")
199 if skip_commit:
200 command.append("--skip_commit")
Alex Klein4de25e82019-08-05 15:58:39 -0600201
Alex Klein1699fab2022-09-08 08:46:06 -0600202 result = cros_build_lib.run(
203 command,
204 stdout=True,
205 enter_chroot=True,
206 encoding="utf-8",
207 chroot_args=chroot.get_enter_args(),
208 )
Alex Klein4de25e82019-08-05 15:58:39 -0600209
Alex Klein1699fab2022-09-08 08:46:06 -0600210 # cros_mark_android_as_stable prints the uprev result to stdout as JSON in a
211 # single line. We only take the last line from stdout to make sure no junk
212 # output is included (e.g. messages from bashrc scripts that run upon entering
213 # the chroot.)
214 output = json.loads(result.stdout.strip().splitlines()[-1])
Shao-Chuan Leedea458f2021-11-25 23:46:53 +0900215
Alex Klein1699fab2022-09-08 08:46:06 -0600216 if not output["revved"]:
217 logging.info("Found nothing to rev.")
218 return UprevAndroidResult(revved=False)
Shao-Chuan Lee84bf9a22021-11-19 17:42:11 +0900219
Alex Klein1699fab2022-09-08 08:46:06 -0600220 android_atom = output["android_atom"]
Alex Klein4de25e82019-08-05 15:58:39 -0600221
Alex Klein1699fab2022-09-08 08:46:06 -0600222 for target in build_targets or []:
223 # Sanity check: We should always be able to merge the version of
224 # Android we just unmasked.
225 command = [f"emerge-{target.name}", "-p", "--quiet", f"={android_atom}"]
226 try:
227 cros_build_lib.run(
228 command, enter_chroot=True, chroot_args=chroot.get_enter_args()
229 )
230 except cros_build_lib.RunCommandError:
231 logging.error(
232 "Cannot emerge-%s =%s\nIs Android pinned to an older "
233 "version?",
234 target,
235 android_atom,
236 )
237 raise AndroidIsPinnedUprevError(android_atom)
Alex Klein4de25e82019-08-05 15:58:39 -0600238
Alex Klein1699fab2022-09-08 08:46:06 -0600239 return UprevAndroidResult(
240 revved=True,
241 android_atom=android_atom,
242 modified_files=output["modified_files"],
243 )
Shao-Chuan Lee05e51142021-11-24 12:27:37 +0900244
245
Alex Klein1699fab2022-09-08 08:46:06 -0600246def uprev_android_lkgb(
247 android_package: str,
248 build_targets: List["build_target_lib.BuildTarget"],
249 chroot: "chroot_lib.Chroot",
250) -> uprev_lib.UprevVersionedPackageResult:
251 """Uprevs an Android package to the version specified in the LKGB file.
Shao-Chuan Lee05e51142021-11-24 12:27:37 +0900252
Alex Klein1699fab2022-09-08 08:46:06 -0600253 This is the PUpr handler for Android packages, triggered whenever the
254 corresponding LKGB file is being updated.
Shao-Chuan Lee05e51142021-11-24 12:27:37 +0900255
Alex Klein1699fab2022-09-08 08:46:06 -0600256 PUpr for Android does not test the uprev change in CQ; instead we run separate
257 jobs to test new Android versions, and we write the latest vetted version to
258 the LKGB file. Find the design at go/android-uprev-recipes.
Shao-Chuan Lee05e51142021-11-24 12:27:37 +0900259
Alex Klein1699fab2022-09-08 08:46:06 -0600260 Args:
Alex Klein348e7692022-10-13 17:03:37 -0600261 android_package: The Android package to uprev.
262 build_targets: List of build targets to cleanup after uprev.
263 chroot: The chroot to enter.
Shao-Chuan Lee05e51142021-11-24 12:27:37 +0900264
Alex Klein1699fab2022-09-08 08:46:06 -0600265 Returns:
Alex Klein348e7692022-10-13 17:03:37 -0600266 An uprev_lib.UprevVersionedPackageResult containing the new version and
267 a list of modified files.
Alex Klein1699fab2022-09-08 08:46:06 -0600268 """
269 android_package_dir = android.GetAndroidPackageDir(android_package)
270 android_version = android.ReadLKGB(android_package_dir)
Shao-Chuan Lee05e51142021-11-24 12:27:37 +0900271
Alex Klein1699fab2022-09-08 08:46:06 -0600272 result = uprev_lib.UprevVersionedPackageResult()
273 uprev_result = uprev_android(
274 android_package,
275 chroot,
276 build_targets=build_targets,
277 android_version=android_version,
278 skip_commit=True,
279 )
280 if not uprev_result.revved:
281 return result
282
283 # cros_mark_android_as_stable returns paths relative to |android.OVERLAY_DIR|.
284 result.add_result(
285 android_version,
286 [
287 os.path.join(android.OVERLAY_DIR, f)
288 for f in uprev_result.modified_files
289 ],
290 )
Shao-Chuan Lee05e51142021-11-24 12:27:37 +0900291 return result
292
Shao-Chuan Lee05e51142021-11-24 12:27:37 +0900293
294def define_uprev_android_lkgb_handlers():
Alex Klein1699fab2022-09-08 08:46:06 -0600295 """Dynamically define uprev handlers for each Android package"""
Shao-Chuan Lee05e51142021-11-24 12:27:37 +0900296
Alex Klein1699fab2022-09-08 08:46:06 -0600297 def define_handler(android_package):
298 """Defines the uprev handler for an Android package."""
299 full_package_name = "chromeos-base/" + android_package
Shao-Chuan Lee05e51142021-11-24 12:27:37 +0900300
Alex Klein1699fab2022-09-08 08:46:06 -0600301 @uprevs_versioned_package(full_package_name)
302 def _handler(build_targets, _refs, chroot):
303 return uprev_android_lkgb(android_package, build_targets, chroot)
Shao-Chuan Lee05e51142021-11-24 12:27:37 +0900304
Alex Klein1699fab2022-09-08 08:46:06 -0600305 for android_package in constants.ANDROID_ALL_PACKAGES:
306 define_handler(android_package)
Shao-Chuan Lee05e51142021-11-24 12:27:37 +0900307
308
309define_uprev_android_lkgb_handlers()
Alex Klein4de25e82019-08-05 15:58:39 -0600310
311
Matthias Kaehlckebf7d1772021-11-04 16:01:36 -0700312def uprev_build_targets(
Alex Klein1699fab2022-09-08 08:46:06 -0600313 build_targets: Optional[List["build_target_lib.BuildTarget"]],
Matthias Kaehlckebf7d1772021-11-04 16:01:36 -0700314 overlay_type: str,
Alex Klein1699fab2022-09-08 08:46:06 -0600315 chroot: "chroot_lib.Chroot" = None,
316 output_dir: Optional[str] = None,
317):
318 """Uprev the set provided build targets, or all if not specified.
Alex Kleineb77ffa2019-05-28 14:47:44 -0600319
Alex Klein1699fab2022-09-08 08:46:06 -0600320 Args:
Alex Klein348e7692022-10-13 17:03:37 -0600321 build_targets: The build targets whose overlays should be uprevved,
322 empty or None for all.
323 overlay_type: One of the valid overlay types except None (see
324 constants.VALID_OVERLAYS).
325 chroot: The chroot to clean, if desired.
326 output_dir: The path to optionally dump result files.
Alex Klein1699fab2022-09-08 08:46:06 -0600327 """
328 # Need a valid overlay, but exclude None.
329 assert overlay_type and overlay_type in constants.VALID_OVERLAYS
Alex Kleineb77ffa2019-05-28 14:47:44 -0600330
Alex Klein1699fab2022-09-08 08:46:06 -0600331 if build_targets:
332 overlays = portage_util.FindOverlaysForBoards(
333 overlay_type, boards=[t.name for t in build_targets]
334 )
335 else:
336 overlays = portage_util.FindOverlays(overlay_type)
Alex Kleineb77ffa2019-05-28 14:47:44 -0600337
Alex Klein1699fab2022-09-08 08:46:06 -0600338 return uprev_overlays(
339 overlays,
340 build_targets=build_targets,
341 chroot=chroot,
342 output_dir=output_dir,
343 )
Alex Kleineb77ffa2019-05-28 14:47:44 -0600344
345
Matthias Kaehlckebf7d1772021-11-04 16:01:36 -0700346def uprev_overlays(
347 overlays: List[str],
Alex Klein1699fab2022-09-08 08:46:06 -0600348 build_targets: Optional[List["build_target_lib.BuildTarget"]] = None,
349 chroot: Optional["chroot_lib.Chroot"] = None,
350 output_dir: Optional[str] = None,
351) -> List[str]:
352 """Uprev the given overlays.
Alex Kleineb77ffa2019-05-28 14:47:44 -0600353
Alex Klein1699fab2022-09-08 08:46:06 -0600354 Args:
Alex Klein348e7692022-10-13 17:03:37 -0600355 overlays: The list of overlay paths.
356 build_targets: The build targets to clean in |chroot|, if desired. No
357 effect unless |chroot| is provided.
358 chroot: The chroot to clean, if desired.
359 output_dir: The path to optionally dump result files.
Alex Kleineb77ffa2019-05-28 14:47:44 -0600360
Alex Klein1699fab2022-09-08 08:46:06 -0600361 Returns:
Alex Klein348e7692022-10-13 17:03:37 -0600362 The paths to all the modified ebuild files. This includes the new files
363 that were added (i.e. the new versions) and all the removed files
Alex Klein1699fab2022-09-08 08:46:06 -0600364 (i.e. the old versions).
365 """
366 assert overlays
Alex Kleineb77ffa2019-05-28 14:47:44 -0600367
Alex Klein1699fab2022-09-08 08:46:06 -0600368 manifest = git.ManifestCheckout.Cached(constants.SOURCE_ROOT)
Alex Kleineb77ffa2019-05-28 14:47:44 -0600369
Alex Klein1699fab2022-09-08 08:46:06 -0600370 uprev_manager = uprev_lib.UprevOverlayManager(
371 overlays,
372 manifest,
373 build_targets=build_targets,
374 chroot=chroot,
375 output_dir=output_dir,
376 )
377 uprev_manager.uprev()
Alex Kleineb77ffa2019-05-28 14:47:44 -0600378
Alex Klein1699fab2022-09-08 08:46:06 -0600379 return uprev_manager.modified_ebuilds, uprev_manager.revved_packages
Alex Kleineb77ffa2019-05-28 14:47:44 -0600380
381
Matthias Kaehlckebf7d1772021-11-04 16:01:36 -0700382def uprev_versioned_package(
383 package: package_info.CPV,
Alex Klein1699fab2022-09-08 08:46:06 -0600384 build_targets: List["build_target_lib.BuildTarget"],
Matthias Kaehlckebf7d1772021-11-04 16:01:36 -0700385 refs: List[uprev_lib.GitRef],
Alex Klein1699fab2022-09-08 08:46:06 -0600386 chroot: "chroot_lib.Chroot",
387) -> "uprev_lib.UprevVersionedPackageResult":
388 """Call registered uprev handler function for the package.
Alex Klein87531182019-08-12 15:23:37 -0600389
Alex Klein1699fab2022-09-08 08:46:06 -0600390 Args:
Alex Klein348e7692022-10-13 17:03:37 -0600391 package: The package being uprevved.
392 build_targets: The build targets to clean on a successful uprev.
393 refs:
394 chroot: The chroot to enter for cleaning.
Alex Klein87531182019-08-12 15:23:37 -0600395
Alex Klein1699fab2022-09-08 08:46:06 -0600396 Returns:
Alex Klein348e7692022-10-13 17:03:37 -0600397 The result.
Alex Klein1699fab2022-09-08 08:46:06 -0600398 """
399 assert package
Alex Klein87531182019-08-12 15:23:37 -0600400
Alex Klein1699fab2022-09-08 08:46:06 -0600401 if package.cp not in _UPREV_FUNCS:
402 raise UnknownPackageError(
403 'Package "%s" does not have a registered handler.' % package.cp
404 )
Alex Klein87531182019-08-12 15:23:37 -0600405
Alex Klein1699fab2022-09-08 08:46:06 -0600406 return _UPREV_FUNCS[package.cp](build_targets, refs, chroot)
Alex Klein87531182019-08-12 15:23:37 -0600407
408
Alex Klein1699fab2022-09-08 08:46:06 -0600409@uprevs_versioned_package("media-libs/virglrenderer")
Navil Perezf57ba872020-06-04 22:38:37 +0000410def uprev_virglrenderer(_build_targets, refs, _chroot):
Alex Klein1699fab2022-09-08 08:46:06 -0600411 """Updates virglrenderer ebuilds.
Navil Perezf57ba872020-06-04 22:38:37 +0000412
Alex Klein1699fab2022-09-08 08:46:06 -0600413 See: uprev_versioned_package.
Navil Perezf57ba872020-06-04 22:38:37 +0000414
Alex Klein1699fab2022-09-08 08:46:06 -0600415 Returns:
Alex Klein348e7692022-10-13 17:03:37 -0600416 UprevVersionedPackageResult: The result of updating virglrenderer
417 ebuilds.
Alex Klein1699fab2022-09-08 08:46:06 -0600418 """
419 overlay = os.path.join(
420 constants.SOURCE_ROOT, constants.CHROMIUMOS_OVERLAY_DIR
421 )
422 repo_path = os.path.join(
423 constants.SOURCE_ROOT, "src", "third_party", "virglrenderer"
424 )
425 manifest = git.ManifestCheckout.Cached(repo_path)
Navil Perezf57ba872020-06-04 22:38:37 +0000426
Alex Klein1699fab2022-09-08 08:46:06 -0600427 uprev_manager = uprev_lib.UprevOverlayManager([overlay], manifest)
428 # TODO(crbug.com/1066242): Ebuilds for virglrenderer are currently
429 # denylisted. Do not force uprevs after builder is stable and ebuilds are no
430 # longer denylisted.
431 uprev_manager.uprev(package_list=["media-libs/virglrenderer"], force=True)
Navil Perezf57ba872020-06-04 22:38:37 +0000432
Alex Klein1699fab2022-09-08 08:46:06 -0600433 updated_files = uprev_manager.modified_ebuilds
434 result = uprev_lib.UprevVersionedPackageResult()
435 result.add_result(refs[-1].revision, updated_files)
436 return result
Navil Perezf57ba872020-06-04 22:38:37 +0000437
Alex Klein1699fab2022-09-08 08:46:06 -0600438
439@uprevs_versioned_package("chromeos-base/drivefs")
Jose Magana03b5a842020-08-19 12:52:59 +1000440def uprev_drivefs(_build_targets, refs, chroot):
Alex Klein1699fab2022-09-08 08:46:06 -0600441 """Updates drivefs ebuilds.
Jose Magana03b5a842020-08-19 12:52:59 +1000442
Alex Klein1699fab2022-09-08 08:46:06 -0600443 DriveFS versions follow the tag format of refs/tags/drivefs_1.2.3.
444 See: uprev_versioned_package.
Jose Magana03b5a842020-08-19 12:52:59 +1000445
Alex Klein1699fab2022-09-08 08:46:06 -0600446 Returns:
Alex Klein348e7692022-10-13 17:03:37 -0600447 UprevVersionedPackageResult: The result of updating drivefs ebuilds.
Alex Klein1699fab2022-09-08 08:46:06 -0600448 """
Jose Magana03b5a842020-08-19 12:52:59 +1000449
Alex Klein1699fab2022-09-08 08:46:06 -0600450 DRIVEFS_PATH_PREFIX = "src/private-overlays/chromeos-overlay/chromeos-base"
451 result = uprev_lib.UprevVersionedPackageResult()
452 all_changed_files = []
Jose Magana03b5a842020-08-19 12:52:59 +1000453
Alex Klein1699fab2022-09-08 08:46:06 -0600454 DRIVEFS_REFS_PREFIX = "refs/tags/drivefs_"
455 drivefs_version = _get_latest_version_from_refs(DRIVEFS_REFS_PREFIX, refs)
456 if not drivefs_version:
457 # No valid DriveFS version is identified.
458 return result
459
460 logging.debug("DriveFS version determined from refs: %s", drivefs_version)
461
462 # Attempt to uprev drivefs package.
463 pkg_path = os.path.join(DRIVEFS_PATH_PREFIX, "drivefs")
464 uprev_result = uprev_lib.uprev_workon_ebuild_to_version(
465 pkg_path, drivefs_version, chroot, allow_downrev=False
466 )
467
468 if not uprev_result:
469 return result
470 all_changed_files.extend(uprev_result.changed_files)
471 result.add_result(drivefs_version, all_changed_files)
472
Ben Reich4f3fa1b2020-12-19 08:21:26 +0000473 return result
Jose Magana03b5a842020-08-19 12:52:59 +1000474
Jose Magana03b5a842020-08-19 12:52:59 +1000475
Alex Klein1699fab2022-09-08 08:46:06 -0600476@uprevs_versioned_package("chromeos-base/perfetto")
Harvey Yang9c61e9c2021-03-02 16:32:43 +0800477def uprev_perfetto(_build_targets, refs, chroot):
Alex Klein1699fab2022-09-08 08:46:06 -0600478 """Updates Perfetto ebuilds.
Harvey Yang9c61e9c2021-03-02 16:32:43 +0800479
Alex Klein1699fab2022-09-08 08:46:06 -0600480 Perfetto versions follow the tag format of refs/tags/v1.2.
481 See: uprev_versioned_package.
Harvey Yang9c61e9c2021-03-02 16:32:43 +0800482
Alex Klein1699fab2022-09-08 08:46:06 -0600483 Returns:
Alex Klein348e7692022-10-13 17:03:37 -0600484 UprevVersionedPackageResult: The result of updating Perfetto ebuilds.
Alex Klein1699fab2022-09-08 08:46:06 -0600485 """
486 result = uprev_lib.UprevVersionedPackageResult()
Harvey Yang9c61e9c2021-03-02 16:32:43 +0800487
Alex Klein1699fab2022-09-08 08:46:06 -0600488 PERFETTO_REFS_PREFIX = "refs/tags/v"
Chinglin Yu84818732022-10-03 12:03:43 +0800489 # |perfetto_version| is only used in determining the ebuild version. The
490 # package is always updated to the latest HEAD.
Alex Klein1699fab2022-09-08 08:46:06 -0600491 perfetto_version = _get_latest_version_from_refs(PERFETTO_REFS_PREFIX, refs)
492 if not perfetto_version:
493 # No valid Perfetto version is identified.
494 return result
495
Alex Klein1699fab2022-09-08 08:46:06 -0600496 # Attempt to uprev perfetto package.
497 PERFETTO_PATH = "src/third_party/chromiumos-overlay/chromeos-base/perfetto"
498
499 uprev_result = uprev_lib.uprev_workon_ebuild_to_version(
500 PERFETTO_PATH,
501 perfetto_version,
502 chroot,
503 allow_downrev=False,
Chinglin Yu84818732022-10-03 12:03:43 +0800504 # Use default ref="HEAD"
Alex Klein1699fab2022-09-08 08:46:06 -0600505 )
506
507 if not uprev_result:
508 return result
509
510 result.add_result(perfetto_version, uprev_result.changed_files)
511
Harvey Yang9c61e9c2021-03-02 16:32:43 +0800512 return result
513
Harvey Yang9c61e9c2021-03-02 16:32:43 +0800514
Denis Nikitin63613e32022-09-09 22:26:50 -0700515class AfdoMetadata(NamedTuple):
516 """Data class holding AFDO metadata."""
517
518 var_name: str
519 path: str
520
521
Alex Klein1699fab2022-09-08 08:46:06 -0600522@uprevs_versioned_package("afdo/kernel-profiles")
Yaakov Shaul395ae832019-09-09 14:45:32 -0600523def uprev_kernel_afdo(*_args, **_kwargs):
Alex Klein1699fab2022-09-08 08:46:06 -0600524 """Updates kernel ebuilds with versions from kernel_afdo.json.
Yaakov Shaul395ae832019-09-09 14:45:32 -0600525
Alex Klein1699fab2022-09-08 08:46:06 -0600526 See: uprev_versioned_package.
Yaakov Shaul1eafe832019-09-10 16:50:26 -0600527
Alex Klein1699fab2022-09-08 08:46:06 -0600528 Raises:
Alex Klein348e7692022-10-13 17:03:37 -0600529 EbuildManifestError: When ebuild manifest does not complete
530 successfully.
531 JSONDecodeError: When json is malformed.
Alex Klein1699fab2022-09-08 08:46:06 -0600532 """
Denis Nikitin63613e32022-09-09 22:26:50 -0700533 metadata_dir = os.path.join(
Alex Klein1699fab2022-09-08 08:46:06 -0600534 constants.SOURCE_ROOT,
535 "src",
536 "third_party",
537 "toolchain-utils",
538 "afdo_metadata",
Denis Nikitin63613e32022-09-09 22:26:50 -0700539 )
540 metadata_files = (
541 AfdoMetadata(
542 var_name="AFDO_PROFILE_VERSION",
543 path=os.path.join(metadata_dir, "kernel_afdo.json"),
544 ),
545 AfdoMetadata(
546 var_name="ARM_AFDO_PROFILE_VERSION",
547 path=os.path.join(metadata_dir, "kernel_arm_afdo.json"),
548 ),
Alex Klein1699fab2022-09-08 08:46:06 -0600549 )
Yaakov Shaul395ae832019-09-09 14:45:32 -0600550
Alex Klein1699fab2022-09-08 08:46:06 -0600551 result = uprev_lib.UprevVersionedPackageResult()
Denis Nikitin63613e32022-09-09 22:26:50 -0700552 for metadata in metadata_files:
553 with open(metadata.path, "r") as f:
554 versions = json.load(f)
Yaakov Shaul1eafe832019-09-10 16:50:26 -0600555
Denis Nikitin63613e32022-09-09 22:26:50 -0700556 for kernel_pkg, version_info in versions.items():
557 path = os.path.join(
558 constants.CHROMIUMOS_OVERLAY_DIR, "sys-kernel", kernel_pkg
559 )
560 ebuild_path = os.path.join(
561 constants.SOURCE_ROOT, path, f"{kernel_pkg}-9999.ebuild"
562 )
563 chroot_ebuild_path = os.path.join(
564 constants.CHROOT_SOURCE_ROOT, path, f"{kernel_pkg}-9999.ebuild"
565 )
566 afdo_profile_version = version_info["name"]
567 patch_ebuild_vars(
568 ebuild_path, {metadata.var_name: afdo_profile_version}
Alex Klein1699fab2022-09-08 08:46:06 -0600569 )
Yaakov Shaul1eafe832019-09-10 16:50:26 -0600570
Denis Nikitin63613e32022-09-09 22:26:50 -0700571 try:
572 cmd = ["ebuild", chroot_ebuild_path, "manifest", "--force"]
573 cros_build_lib.run(cmd, enter_chroot=True)
574 except cros_build_lib.RunCommandError as e:
575 raise uprev_lib.EbuildManifestError(
576 "Error encountered when regenerating the manifest for "
577 f"ebuild: {chroot_ebuild_path}\n{e}",
578 e,
579 )
Yaakov Shaul1eafe832019-09-10 16:50:26 -0600580
Denis Nikitin63613e32022-09-09 22:26:50 -0700581 manifest_path = os.path.join(
582 constants.SOURCE_ROOT, path, "Manifest"
583 )
584 result.add_result(
585 afdo_profile_version, [ebuild_path, manifest_path]
586 )
Yaakov Shaul730814a2019-09-10 13:58:25 -0600587
Alex Klein1699fab2022-09-08 08:46:06 -0600588 return result
Yaakov Shaul395ae832019-09-09 14:45:32 -0600589
590
Alex Klein1699fab2022-09-08 08:46:06 -0600591@uprevs_versioned_package("chromeos-base/termina-dlc")
592@uprevs_versioned_package("chromeos-base/termina-tools-dlc")
Maciek Swiech6b12f662022-01-25 16:51:19 +0000593def uprev_termina_dlcs(_build_targets, _refs, chroot):
Alex Klein1699fab2022-09-08 08:46:06 -0600594 """Updates shared termina-dlc and termina-tools-dlc ebuilds.
Maciek Swiech6b12f662022-01-25 16:51:19 +0000595
Alex Klein1699fab2022-09-08 08:46:06 -0600596 termina-dlc - chromeos-base/termina-dlc
597 termina-tools-dlc - chromeos-base/termina-tools-dlc
Trent Beginaf51f1b2020-03-09 17:35:31 -0600598
Alex Klein1699fab2022-09-08 08:46:06 -0600599 See: uprev_versioned_package.
600 """
601 termina_dlc_pkg = "termina-dlc"
602 termina_dlc_pkg_path = os.path.join(
603 constants.CHROMIUMOS_OVERLAY_DIR, "chromeos-base", termina_dlc_pkg
604 )
605 tools_dlc_pkg = "termina-tools-dlc"
606 tools_dlc_pkg_path = os.path.join(
607 constants.CHROMIUMOS_OVERLAY_DIR, "chromeos-base", tools_dlc_pkg
608 )
Patrick Meiring5897add2020-09-16 16:30:17 +1000609
Alex Klein1699fab2022-09-08 08:46:06 -0600610 # termina-dlc and termina-tools-dlc are pinned to the same version.
611 version_pin_src_path = _get_version_pin_src_path(termina_dlc_pkg_path)
612 version_no_rev = osutils.ReadFile(version_pin_src_path).strip()
Patrick Meiring5897add2020-09-16 16:30:17 +1000613
Alex Klein1699fab2022-09-08 08:46:06 -0600614 result = uprev_lib.uprev_ebuild_from_pin(
615 termina_dlc_pkg_path, version_no_rev, chroot
616 )
617 result += uprev_lib.uprev_ebuild_from_pin(
618 tools_dlc_pkg_path, version_no_rev, chroot
619 )
Patrick Meiring5897add2020-09-16 16:30:17 +1000620
Alex Klein1699fab2022-09-08 08:46:06 -0600621 return result
Patrick Meiring5897add2020-09-16 16:30:17 +1000622
Alex Klein1699fab2022-09-08 08:46:06 -0600623
624@uprevs_versioned_package("chromeos-base/chromeos-lacros")
Julio Hurtadof1befec2021-05-05 21:34:26 +0000625def uprev_lacros(_build_targets, refs, chroot):
Alex Klein1699fab2022-09-08 08:46:06 -0600626 """Updates lacros ebuilds.
Julio Hurtadof1befec2021-05-05 21:34:26 +0000627
Alex Klein1699fab2022-09-08 08:46:06 -0600628 Version to uprev to is gathered from the QA qualified version tracking file
629 stored in chromium/src/chrome/LACROS_QA_QUALIFIED_VERSION. Uprev is triggered
630 on modification of this file across all chromium/src branches.
Julio Hurtadof1befec2021-05-05 21:34:26 +0000631
Alex Klein1699fab2022-09-08 08:46:06 -0600632 See: uprev_versioned_package.
633 """
634 result = uprev_lib.UprevVersionedPackageResult()
635 path = os.path.join(
636 constants.CHROMIUMOS_OVERLAY_DIR, "chromeos-base", "chromeos-lacros"
637 )
638 lacros_version = refs[0].revision
639 uprev_result = uprev_lib.uprev_workon_ebuild_to_version(
640 path, lacros_version, chroot, allow_downrev=False
641 )
Julio Hurtadoa994e002021-07-07 17:57:45 +0000642
Alex Klein1699fab2022-09-08 08:46:06 -0600643 if not uprev_result:
644 return result
645
646 result.add_result(lacros_version, uprev_result.changed_files)
Julio Hurtadoa994e002021-07-07 17:57:45 +0000647 return result
648
Julio Hurtadof1befec2021-05-05 21:34:26 +0000649
Alex Klein1699fab2022-09-08 08:46:06 -0600650@uprevs_versioned_package("chromeos-base/chromeos-lacros-parallel")
Julio Hurtado870ed322021-12-03 18:22:40 +0000651def uprev_lacros_in_parallel(
Alex Klein1699fab2022-09-08 08:46:06 -0600652 _build_targets: Optional[List["build_target_lib.BuildTarget"]],
Julio Hurtado870ed322021-12-03 18:22:40 +0000653 refs: List[uprev_lib.GitRef],
Alex Klein1699fab2022-09-08 08:46:06 -0600654 chroot: "chroot_lib.Chroot",
655) -> "uprev_lib.UprevVersionedPackageResult":
656 """Updates lacros ebuilds in parallel with ash-chrome.
Julio Hurtado870ed322021-12-03 18:22:40 +0000657
Alex Klein1699fab2022-09-08 08:46:06 -0600658 This handler is going to be used temporarily while lacros transitions to being
659 uprevved atomically with ash-chrome. Unlike a standalone lacros uprev, this
660 handler will not need to look at the QA qualified file. Rather, it will
661 function identical to ash-chrome using git tags.
Julio Hurtado870ed322021-12-03 18:22:40 +0000662
Alex Klein1699fab2022-09-08 08:46:06 -0600663 See: uprev_versioned_package.
Julio Hurtado870ed322021-12-03 18:22:40 +0000664
Alex Klein1699fab2022-09-08 08:46:06 -0600665 Returns:
Alex Klein348e7692022-10-13 17:03:37 -0600666 UprevVersionedPackageResult: The result.
Alex Klein1699fab2022-09-08 08:46:06 -0600667 """
668 result = uprev_lib.UprevVersionedPackageResult()
669 path = os.path.join(
670 constants.CHROMIUMOS_OVERLAY_DIR, "chromeos-base", "chromeos-lacros"
671 )
672 lacros_version = uprev_lib.get_version_from_refs(refs)
673 uprev_result = uprev_lib.uprev_workon_ebuild_to_version(
674 path, lacros_version, chroot, allow_downrev=False
675 )
Julio Hurtado870ed322021-12-03 18:22:40 +0000676
Alex Klein1699fab2022-09-08 08:46:06 -0600677 if not uprev_result:
678 return result
679
680 result.add_result(lacros_version, uprev_result.changed_files)
Julio Hurtado870ed322021-12-03 18:22:40 +0000681 return result
682
Julio Hurtado870ed322021-12-03 18:22:40 +0000683
Alex Klein1699fab2022-09-08 08:46:06 -0600684@uprevs_versioned_package("app-emulation/parallels-desktop")
Patrick Meiring5897add2020-09-16 16:30:17 +1000685def uprev_parallels_desktop(_build_targets, _refs, chroot):
Alex Klein1699fab2022-09-08 08:46:06 -0600686 """Updates Parallels Desktop ebuild - app-emulation/parallels-desktop.
Patrick Meiring5897add2020-09-16 16:30:17 +1000687
Alex Klein1699fab2022-09-08 08:46:06 -0600688 See: uprev_versioned_package
Patrick Meiring5897add2020-09-16 16:30:17 +1000689
Alex Klein1699fab2022-09-08 08:46:06 -0600690 Returns:
Alex Klein348e7692022-10-13 17:03:37 -0600691 UprevVersionedPackageResult: The result.
Alex Klein1699fab2022-09-08 08:46:06 -0600692 """
693 package = "parallels-desktop"
694 package_path = os.path.join(
695 constants.CHROMEOS_PARTNER_OVERLAY_DIR, "app-emulation", package
696 )
697 version_pin_src_path = _get_version_pin_src_path(package_path)
Patrick Meiring5897add2020-09-16 16:30:17 +1000698
Alex Klein1699fab2022-09-08 08:46:06 -0600699 # Expect a JSON blob like the following:
700 # {
701 # "version": "1.2.3",
702 # "test_image": { "url": "...", "size": 12345678,
703 # "sha256sum": "<32 bytes of hexadecimal>" }
704 # }
705 with open(version_pin_src_path, "r") as f:
706 pinned = json.load(f)
Patrick Meiring5897add2020-09-16 16:30:17 +1000707
Alex Klein1699fab2022-09-08 08:46:06 -0600708 if "version" not in pinned or "test_image" not in pinned:
709 raise UprevError(
710 "VERSION-PIN for %s missing version and/or "
711 "test_image field" % package
712 )
Patrick Meiring5897add2020-09-16 16:30:17 +1000713
Alex Klein1699fab2022-09-08 08:46:06 -0600714 version = pinned["version"]
715 if not isinstance(version, str):
716 raise UprevError("version in VERSION-PIN for %s not a string" % package)
Patrick Meiring5897add2020-09-16 16:30:17 +1000717
Alex Klein1699fab2022-09-08 08:46:06 -0600718 # Update the ebuild.
719 result = uprev_lib.uprev_ebuild_from_pin(package_path, version, chroot)
Patrick Meiring5897add2020-09-16 16:30:17 +1000720
Alex Klein1699fab2022-09-08 08:46:06 -0600721 # Update the VM image used for testing.
722 test_image_path = (
723 "src/platform/tast-tests-private/src/chromiumos/tast/"
724 "local/bundles/crosint/pita/data/"
725 "pluginvm_image.zip.external"
726 )
727 test_image_src_path = os.path.join(constants.SOURCE_ROOT, test_image_path)
728 with open(test_image_src_path, "w") as f:
729 json.dump(pinned["test_image"], f, indent=2)
730 result.add_result(version, [test_image_src_path])
Patrick Meiring5897add2020-09-16 16:30:17 +1000731
Alex Klein1699fab2022-09-08 08:46:06 -0600732 return result
Trent Beginaf51f1b2020-03-09 17:35:31 -0600733
734
Alex Klein1699fab2022-09-08 08:46:06 -0600735@uprevs_versioned_package("chromeos-base/chromeos-dtc-vm")
Trent Beginaf51f1b2020-03-09 17:35:31 -0600736def uprev_sludge(_build_targets, _refs, chroot):
Alex Klein1699fab2022-09-08 08:46:06 -0600737 """Updates sludge VM - chromeos-base/chromeos-dtc-vm.
Trent Begin315d9d92019-12-03 21:55:53 -0700738
Alex Klein1699fab2022-09-08 08:46:06 -0600739 See: uprev_versioned_package.
740 """
741 package = "chromeos-dtc-vm"
742 package_path = os.path.join(
743 "src",
744 "private-overlays",
745 "project-wilco-private",
746 "chromeos-base",
747 package,
748 )
749 version_pin_src_path = _get_version_pin_src_path(package_path)
750 version_no_rev = osutils.ReadFile(version_pin_src_path).strip()
Trent Begin315d9d92019-12-03 21:55:53 -0700751
Alex Klein1699fab2022-09-08 08:46:06 -0600752 return uprev_lib.uprev_ebuild_from_pin(package_path, version_no_rev, chroot)
Trent Begin315d9d92019-12-03 21:55:53 -0700753
754
Alex Klein1699fab2022-09-08 08:46:06 -0600755@uprevs_versioned_package("chromeos-base/borealis-dlc")
David Riley8513c1f2021-10-14 17:07:41 -0700756def uprev_borealis_dlc(_build_targets, _refs, chroot):
Alex Klein1699fab2022-09-08 08:46:06 -0600757 """Updates shared borealis-dlc ebuild - chromeos-base/borealis-dlc.
David Riley8513c1f2021-10-14 17:07:41 -0700758
Alex Klein1699fab2022-09-08 08:46:06 -0600759 See: uprev_versioned_package.
760 """
761 package_path = os.path.join(
762 "src",
763 "private-overlays",
764 "chromeos-partner-overlay",
765 "chromeos-base",
766 "borealis-dlc",
767 )
David Riley8513c1f2021-10-14 17:07:41 -0700768
Alex Klein1699fab2022-09-08 08:46:06 -0600769 version_pin_src_path = _get_version_pin_src_path(package_path)
770 version_no_rev = osutils.ReadFile(version_pin_src_path).strip()
David Riley8513c1f2021-10-14 17:07:41 -0700771
Alex Klein1699fab2022-09-08 08:46:06 -0600772 return uprev_lib.uprev_ebuild_from_pin(package_path, version_no_rev, chroot)
David Riley8513c1f2021-10-14 17:07:41 -0700773
774
Patrick Meiring5897add2020-09-16 16:30:17 +1000775def _get_version_pin_src_path(package_path):
Alex Klein1699fab2022-09-08 08:46:06 -0600776 """Returns the path to the VERSION-PIN file for the given package."""
777 return os.path.join(constants.SOURCE_ROOT, package_path, "VERSION-PIN")
Patrick Meiring5897add2020-09-16 16:30:17 +1000778
779
Alex Klein87531182019-08-12 15:23:37 -0600780@uprevs_versioned_package(constants.CHROME_CP)
Alex Klein4e839252022-01-06 13:29:18 -0700781def uprev_chrome_from_ref(build_targets, refs, _chroot):
Alex Klein1699fab2022-09-08 08:46:06 -0600782 """Uprev chrome and its related packages.
Alex Klein87531182019-08-12 15:23:37 -0600783
Alex Klein1699fab2022-09-08 08:46:06 -0600784 See: uprev_versioned_package.
785 """
786 # Determine the version from the refs (tags), i.e. the chrome versions are the
787 # tag names.
788 chrome_version = uprev_lib.get_version_from_refs(refs)
789 logging.debug("Chrome version determined from refs: %s", chrome_version)
Alex Klein87531182019-08-12 15:23:37 -0600790
Alex Klein1699fab2022-09-08 08:46:06 -0600791 return uprev_chrome(chrome_version, build_targets, None)
Alex Kleinf69bd802021-06-22 15:43:49 -0600792
793
Alex Klein9ce3f682021-06-23 15:06:44 -0600794def revbump_chrome(
Alex Klein1699fab2022-09-08 08:46:06 -0600795 build_targets: List["build_target_lib.BuildTarget"] = None,
796 chroot: Optional["chroot_lib.Chroot"] = None,
Alex Klein9ce3f682021-06-23 15:06:44 -0600797) -> uprev_lib.UprevVersionedPackageResult:
Alex Klein1699fab2022-09-08 08:46:06 -0600798 """Attempt to revbump chrome.
Alex Kleinf69bd802021-06-22 15:43:49 -0600799
Alex Klein1699fab2022-09-08 08:46:06 -0600800 Revbumps are done by executing an uprev using the current stable version.
801 E.g. if chrome is on 1.2.3.4 and has a 1.2.3.4_rc-r2.ebuild, performing an
802 uprev on version 1.2.3.4 when there are applicable changes (e.g. to the 9999
803 ebuild) will result in a revbump to 1.2.3.4_rc-r3.ebuild.
804 """
805 chrome_version = uprev_lib.get_stable_chrome_version()
806 return uprev_chrome(chrome_version, build_targets, chroot)
Alex Kleinf69bd802021-06-22 15:43:49 -0600807
808
Alex Klein9ce3f682021-06-23 15:06:44 -0600809def uprev_chrome(
Alex Klein16ea1b32021-10-01 15:48:50 -0600810 chrome_version: str,
Alex Klein1699fab2022-09-08 08:46:06 -0600811 build_targets: Optional[List["build_target_lib.BuildTarget"]],
812 chroot: Optional["chroot_lib.Chroot"],
Alex Klein9ce3f682021-06-23 15:06:44 -0600813) -> uprev_lib.UprevVersionedPackageResult:
Alex Klein1699fab2022-09-08 08:46:06 -0600814 """Attempt to uprev chrome and its related packages to the given version."""
815 uprev_manager = uprev_lib.UprevChromeManager(
816 chrome_version, build_targets=build_targets, chroot=chroot
817 )
818 result = uprev_lib.UprevVersionedPackageResult()
819 # TODO(crbug.com/1080429): Handle all possible outcomes of a Chrome uprev
820 # attempt. The expected behavior is documented in the following table:
821 #
822 # Outcome of Chrome uprev attempt:
823 # NEWER_VERSION_EXISTS:
824 # Do nothing.
825 # SAME_VERSION_EXISTS or REVISION_BUMP:
826 # Uprev followers
827 # Assert not VERSION_BUMP (any other outcome is fine)
828 # VERSION_BUMP or NEW_EBUILD_CREATED:
829 # Uprev followers
830 # Assert that Chrome & followers are at same package version
Alex Klein0b2ec2d2021-06-23 15:56:45 -0600831
Alex Klein1699fab2022-09-08 08:46:06 -0600832 # Start with chrome itself so we can proceed accordingly.
833 chrome_result = uprev_manager.uprev(constants.CHROME_CP)
834 if chrome_result.newer_version_exists:
835 # Cannot use the given version (newer version already exists).
836 return result
837
838 # Also uprev related packages.
839 for package in constants.OTHER_CHROME_PACKAGES:
840 follower_result = uprev_manager.uprev(package)
841 if chrome_result.stable_version and follower_result.version_bump:
842 logging.warning(
843 "%s had a version bump, but no more than a revision bump "
844 "should have been possible.",
845 package,
846 )
847
848 if uprev_manager.modified_ebuilds:
849 # Record changes when we have them.
850 return result.add_result(chrome_version, uprev_manager.modified_ebuilds)
851
David Burger37f48672019-09-18 17:07:56 -0600852 return result
Alex Klein87531182019-08-12 15:23:37 -0600853
Alex Klein87531182019-08-12 15:23:37 -0600854
Alex Klein1699fab2022-09-08 08:46:06 -0600855def _get_latest_version_from_refs(
856 refs_prefix: str, refs: List[uprev_lib.GitRef]
857) -> str:
858 """Get the latest version from refs
Alex Klein0b2ec2d2021-06-23 15:56:45 -0600859
Alex Klein1699fab2022-09-08 08:46:06 -0600860 Versions are compared using |distutils.version.LooseVersion| and
861 the latest version is returned.
Alex Klein87531182019-08-12 15:23:37 -0600862
Alex Klein1699fab2022-09-08 08:46:06 -0600863 Args:
Alex Klein348e7692022-10-13 17:03:37 -0600864 refs_prefix: The refs prefix of the tag format.
865 refs: The tags to parse for the latest version.
Alex Klein87531182019-08-12 15:23:37 -0600866
Alex Klein1699fab2022-09-08 08:46:06 -0600867 Returns:
Alex Klein348e7692022-10-13 17:03:37 -0600868 The latest version to use as string.
Alex Klein1699fab2022-09-08 08:46:06 -0600869 """
870 valid_refs = []
871 for gitiles in refs:
872 if gitiles.ref.startswith(refs_prefix):
873 valid_refs.append(gitiles.ref)
Ben Reiche779cf42020-12-15 03:21:31 +0000874
Alex Klein1699fab2022-09-08 08:46:06 -0600875 if not valid_refs:
876 return None
Ben Reiche779cf42020-12-15 03:21:31 +0000877
Alex Klein1699fab2022-09-08 08:46:06 -0600878 # Sort by version and take the latest version.
879 target_version_ref = sorted(valid_refs, key=LooseVersion, reverse=True)[0]
880 return target_version_ref.replace(refs_prefix, "")
Harvey Yang9c61e9c2021-03-02 16:32:43 +0800881
882
Matthias Kaehlckebf7d1772021-11-04 16:01:36 -0700883def _generate_platform_c_files(
884 replication_config: replication_config_pb2.ReplicationConfig,
Alex Klein1699fab2022-09-08 08:46:06 -0600885 chroot: "chroot_lib.Chroot",
886) -> List[str]:
887 """Generates platform C files from a platform JSON payload.
Andrew Lamb9563a152019-12-04 11:42:18 -0700888
Alex Klein1699fab2022-09-08 08:46:06 -0600889 Args:
Alex Klein348e7692022-10-13 17:03:37 -0600890 replication_config: A ReplicationConfig that has already been run. If it
891 produced a build_config.json file, that file will be used to
892 generate platform C files. Otherwise, nothing will be generated.
893 chroot: The chroot to use to generate.
Andrew Lamb9563a152019-12-04 11:42:18 -0700894
Alex Klein1699fab2022-09-08 08:46:06 -0600895 Returns:
Alex Klein348e7692022-10-13 17:03:37 -0600896 A list of generated files.
Alex Klein1699fab2022-09-08 08:46:06 -0600897 """
898 # Generate the platform C files from the build config. Note that it would be
899 # more intuitive to generate the platform C files from the platform config;
900 # however, cros_config_schema does not allow this, because the platform config
901 # payload is not always valid input. For example, if a property is both
902 # 'required' and 'build-only', it will fail schema validation. Thus, use the
903 # build config, and use '-f' to filter.
904 build_config_path = [
905 rule.destination_path
906 for rule in replication_config.file_replication_rules
907 if rule.destination_path.endswith("build_config.json")
908 ]
Andrew Lamb9563a152019-12-04 11:42:18 -0700909
Alex Klein1699fab2022-09-08 08:46:06 -0600910 if not build_config_path:
911 logging.info(
912 "No build_config.json found, will not generate platform C files. "
913 "Replication config: %s",
914 replication_config,
915 )
916 return []
Andrew Lamb9563a152019-12-04 11:42:18 -0700917
Alex Klein1699fab2022-09-08 08:46:06 -0600918 if len(build_config_path) > 1:
919 raise ValueError(
920 "Expected at most one build_config.json destination path. "
921 "Replication config: %s" % replication_config
922 )
Andrew Lamb9563a152019-12-04 11:42:18 -0700923
Alex Klein1699fab2022-09-08 08:46:06 -0600924 build_config_path = build_config_path[0]
Andrew Lamb9563a152019-12-04 11:42:18 -0700925
Alex Klein1699fab2022-09-08 08:46:06 -0600926 # Paths to the build_config.json and dir to output C files to, in the
927 # chroot.
928 build_config_chroot_path = os.path.join(
929 constants.CHROOT_SOURCE_ROOT, build_config_path
930 )
931 generated_output_chroot_dir = os.path.join(
932 constants.CHROOT_SOURCE_ROOT, os.path.dirname(build_config_path)
933 )
Andrew Lamb9563a152019-12-04 11:42:18 -0700934
Alex Klein1699fab2022-09-08 08:46:06 -0600935 command = [
936 "cros_config_schema",
937 "-m",
938 build_config_chroot_path,
939 "-g",
940 generated_output_chroot_dir,
941 "-f",
942 '"TRUE"',
943 ]
Andrew Lamb9563a152019-12-04 11:42:18 -0700944
Alex Klein1699fab2022-09-08 08:46:06 -0600945 cros_build_lib.run(
946 command, enter_chroot=True, chroot_args=chroot.get_enter_args()
947 )
Andrew Lamb9563a152019-12-04 11:42:18 -0700948
Alex Klein1699fab2022-09-08 08:46:06 -0600949 # A relative (to the source root) path to the generated C files.
950 generated_output_dir = os.path.dirname(build_config_path)
951 generated_files = []
952 expected_c_files = ["config.c", "ec_config.c", "ec_config.h"]
953 for f in expected_c_files:
954 if os.path.exists(
955 os.path.join(constants.SOURCE_ROOT, generated_output_dir, f)
956 ):
957 generated_files.append(os.path.join(generated_output_dir, f))
Andrew Lamb9563a152019-12-04 11:42:18 -0700958
Alex Klein1699fab2022-09-08 08:46:06 -0600959 if len(expected_c_files) != len(generated_files):
960 raise GeneratedCrosConfigFilesError(expected_c_files, generated_files)
Andrew Lamb9563a152019-12-04 11:42:18 -0700961
Alex Klein1699fab2022-09-08 08:46:06 -0600962 return generated_files
Andrew Lamb9563a152019-12-04 11:42:18 -0700963
964
Matthias Kaehlckebf7d1772021-11-04 16:01:36 -0700965def _get_private_overlay_package_root(ref: uprev_lib.GitRef, package: str):
Alex Klein1699fab2022-09-08 08:46:06 -0600966 """Returns the absolute path to the root of a given private overlay.
Andrew Lambe836f222019-12-09 12:27:38 -0700967
Alex Klein1699fab2022-09-08 08:46:06 -0600968 Args:
Alex Klein348e7692022-10-13 17:03:37 -0600969 ref: GitRef for the private overlay.
970 package: Path to the package in the overlay.
Alex Klein1699fab2022-09-08 08:46:06 -0600971 """
972 # There might be a cleaner way to map from package -> path within the source
973 # tree. For now, just use string patterns.
974 private_overlay_ref_pattern = (
975 r"/chromeos\/overlays\/overlay-([\w-]+)-private"
976 )
977 match = re.match(private_overlay_ref_pattern, ref.path)
978 if not match:
979 raise ValueError(
980 "ref.path must match the pattern: %s. Actual ref: %s"
981 % (private_overlay_ref_pattern, ref)
982 )
Andrew Lambe836f222019-12-09 12:27:38 -0700983
Alex Klein1699fab2022-09-08 08:46:06 -0600984 overlay = match.group(1)
Andrew Lambe836f222019-12-09 12:27:38 -0700985
Alex Klein1699fab2022-09-08 08:46:06 -0600986 return os.path.join(
987 constants.SOURCE_ROOT,
988 "src/private-overlays/overlay-%s-private" % overlay,
989 package,
990 )
Andrew Lambe836f222019-12-09 12:27:38 -0700991
992
Alex Klein1699fab2022-09-08 08:46:06 -0600993@uprevs_versioned_package("chromeos-base/chromeos-config-bsp")
Andrew Lambea9a8a22019-12-12 14:03:43 -0700994def replicate_private_config(_build_targets, refs, chroot):
Alex Klein1699fab2022-09-08 08:46:06 -0600995 """Replicate a private cros_config change to the corresponding public config.
Andrew Lamb2bde9e42019-11-04 13:24:09 -0700996
Alex Klein1699fab2022-09-08 08:46:06 -0600997 See uprev_versioned_package for args
998 """
999 package = "chromeos-base/chromeos-config-bsp"
Andrew Lambea9a8a22019-12-12 14:03:43 -07001000
Alex Klein1699fab2022-09-08 08:46:06 -06001001 if len(refs) != 1:
1002 raise ValueError("Expected exactly one ref, actual %s" % refs)
Andrew Lamb2bde9e42019-11-04 13:24:09 -07001003
Alex Klein1699fab2022-09-08 08:46:06 -06001004 # Expect a replication_config.jsonpb in the package root.
1005 package_root = _get_private_overlay_package_root(refs[0], package)
1006 replication_config_path = os.path.join(
1007 package_root, "replication_config.jsonpb"
1008 )
Andrew Lamb2bde9e42019-11-04 13:24:09 -07001009
Alex Klein1699fab2022-09-08 08:46:06 -06001010 try:
1011 replication_config = json_format.Parse(
1012 osutils.ReadFile(replication_config_path),
1013 replication_config_pb2.ReplicationConfig(),
1014 )
1015 except IOError:
1016 raise ValueError(
1017 "Expected ReplicationConfig missing at %s" % replication_config_path
1018 )
Andrew Lamb2bde9e42019-11-04 13:24:09 -07001019
Alex Klein1699fab2022-09-08 08:46:06 -06001020 replication_lib.Replicate(replication_config)
Andrew Lamb2bde9e42019-11-04 13:24:09 -07001021
Alex Klein1699fab2022-09-08 08:46:06 -06001022 modified_files = [
1023 rule.destination_path
1024 for rule in replication_config.file_replication_rules
1025 ]
Andrew Lamb2bde9e42019-11-04 13:24:09 -07001026
Alex Klein1699fab2022-09-08 08:46:06 -06001027 # The generated platform C files are not easily filtered by replication rules,
1028 # i.e. JSON / proto filtering can be described by a FieldMask, arbitrary C
1029 # files cannot. Therefore, replicate and filter the JSON payloads, and then
1030 # generate filtered C files from the JSON payload.
1031 modified_files.extend(
1032 _generate_platform_c_files(replication_config, chroot)
1033 )
Andrew Lamb2bde9e42019-11-04 13:24:09 -07001034
Alex Klein1699fab2022-09-08 08:46:06 -06001035 # Use the private repo's commit hash as the new version.
1036 new_private_version = refs[0].revision
Andrew Lamb2bde9e42019-11-04 13:24:09 -07001037
Alex Klein1699fab2022-09-08 08:46:06 -06001038 # modified_files should contain only relative paths at this point, but the
1039 # returned UprevVersionedPackageResult must contain only absolute paths.
1040 for i, modified_file in enumerate(modified_files):
1041 assert not os.path.isabs(modified_file)
1042 modified_files[i] = os.path.join(constants.SOURCE_ROOT, modified_file)
Andrew Lamb988f4da2019-12-10 10:16:43 -07001043
Alex Klein1699fab2022-09-08 08:46:06 -06001044 return uprev_lib.UprevVersionedPackageResult().add_result(
1045 new_private_version, modified_files
1046 )
Andrew Lamb2bde9e42019-11-04 13:24:09 -07001047
1048
Alex Klein1699fab2022-09-08 08:46:06 -06001049@uprevs_versioned_package("chromeos-base/crosvm")
Dennis Kempinef05f2b2021-09-08 16:36:49 -07001050def uprev_crosvm(_build_targets, refs, _chroot):
Alex Klein1699fab2022-09-08 08:46:06 -06001051 """Updates crosvm ebuilds to latest revision
Dennis Kempinef05f2b2021-09-08 16:36:49 -07001052
Alex Klein1699fab2022-09-08 08:46:06 -06001053 crosvm is not versioned. We are updating to the latest commit on the main
1054 branch.
Dennis Kempinef05f2b2021-09-08 16:36:49 -07001055
Alex Klein1699fab2022-09-08 08:46:06 -06001056 See: uprev_versioned_package.
Dennis Kempinef05f2b2021-09-08 16:36:49 -07001057
Alex Klein1699fab2022-09-08 08:46:06 -06001058 Returns:
Alex Klein348e7692022-10-13 17:03:37 -06001059 UprevVersionedPackageResult: The result of updating crosvm ebuilds.
Alex Klein1699fab2022-09-08 08:46:06 -06001060 """
1061 overlay = os.path.join(
1062 constants.SOURCE_ROOT, constants.CHROMIUMOS_OVERLAY_DIR
1063 )
1064 repo_path = os.path.join(constants.SOURCE_ROOT, "src", "crosvm")
1065 manifest = git.ManifestCheckout.Cached(repo_path)
Dennis Kempinef05f2b2021-09-08 16:36:49 -07001066
Alex Klein1699fab2022-09-08 08:46:06 -06001067 uprev_manager = uprev_lib.UprevOverlayManager([overlay], manifest)
1068 uprev_manager.uprev(
1069 package_list=[
1070 "chromeos-base/crosvm",
1071 "dev-rust/assertions",
1072 "dev-rust/cros_async",
1073 "dev-rust/cros_fuzz",
1074 "dev-rust/data_model",
1075 "dev-rust/enumn",
1076 "dev-rust/io_uring",
1077 "dev-rust/p9",
1078 "dev-rust/sync",
1079 "dev-rust/sys_util",
1080 "dev-rust/tempfile",
1081 "media-sound/audio_streams",
1082 ],
1083 force=True,
1084 )
Dennis Kempinef05f2b2021-09-08 16:36:49 -07001085
Alex Klein1699fab2022-09-08 08:46:06 -06001086 updated_files = uprev_manager.modified_ebuilds
1087 result = uprev_lib.UprevVersionedPackageResult()
1088 result.add_result(refs[0].revision, updated_files)
1089 return result
Dennis Kempinef05f2b2021-09-08 16:36:49 -07001090
1091
Alex Klein5caab872021-09-10 11:44:37 -06001092def get_best_visible(
Alex Klein1699fab2022-09-08 08:46:06 -06001093 atom: str, build_target: Optional["build_target_lib.BuildTarget"] = None
Alex Klein5caab872021-09-10 11:44:37 -06001094) -> package_info.PackageInfo:
Alex Klein1699fab2022-09-08 08:46:06 -06001095 """Returns the best visible CPV for the given atom.
Alex Kleinbbef2b32019-08-27 10:38:50 -06001096
Alex Klein1699fab2022-09-08 08:46:06 -06001097 Args:
Alex Klein348e7692022-10-13 17:03:37 -06001098 atom: The atom to look up.
1099 build_target: The build target whose sysroot should be searched, or the
1100 SDK if not provided.
Alex Kleinad6b48a2020-01-08 16:57:41 -07001101
Alex Klein1699fab2022-09-08 08:46:06 -06001102 Returns:
Alex Klein348e7692022-10-13 17:03:37 -06001103 The best visible package, or None if none are visible.
Alex Klein1699fab2022-09-08 08:46:06 -06001104 """
1105 assert atom
Alex Kleinbbef2b32019-08-27 10:38:50 -06001106
Alex Klein1699fab2022-09-08 08:46:06 -06001107 return portage_util.PortageqBestVisible(
1108 atom,
1109 board=build_target.name if build_target else None,
1110 sysroot=build_target.root if build_target else None,
1111 )
Alex Kleinda39c6d2019-09-16 14:36:36 -06001112
1113
Matthias Kaehlckebf7d1772021-11-04 16:01:36 -07001114def has_prebuilt(
1115 atom: str,
Alex Klein1699fab2022-09-08 08:46:06 -06001116 build_target: "build_target_lib.BuildTarget" = None,
1117 useflags: Union[Iterable[str], str] = None,
1118) -> bool:
1119 """Check if a prebuilt exists.
Alex Kleinda39c6d2019-09-16 14:36:36 -06001120
Alex Klein1699fab2022-09-08 08:46:06 -06001121 Args:
Alex Klein348e7692022-10-13 17:03:37 -06001122 atom: The package whose prebuilt is being queried.
1123 build_target: The build target whose sysroot should be searched, or the
1124 SDK if not provided.
1125 useflags: Any additional USE flags that should be set. May be a string
1126 of properly formatted USE flags, or an iterable of individual flags.
Alex Kleinad6b48a2020-01-08 16:57:41 -07001127
Alex Klein1699fab2022-09-08 08:46:06 -06001128 Returns:
Alex Klein348e7692022-10-13 17:03:37 -06001129 True if there is an available prebuilt, False otherwise.
Alex Klein1699fab2022-09-08 08:46:06 -06001130 """
1131 assert atom
Alex Kleinda39c6d2019-09-16 14:36:36 -06001132
Alex Klein1699fab2022-09-08 08:46:06 -06001133 board = build_target.name if build_target else None
1134 extra_env = None
1135 if useflags:
1136 new_flags = useflags
1137 if not isinstance(useflags, str):
1138 new_flags = " ".join(useflags)
Alex Klein149fd3b2019-12-16 16:01:05 -07001139
Alex Klein1699fab2022-09-08 08:46:06 -06001140 existing = os.environ.get("USE", "")
1141 final_flags = "%s %s" % (existing, new_flags)
1142 extra_env = {"USE": final_flags.strip()}
1143 return portage_util.HasPrebuilt(atom, board=board, extra_env=extra_env)
Alex Klein36b117f2019-09-30 15:13:46 -06001144
1145
David Burger0f9dd4e2019-10-08 12:33:42 -06001146def builds(atom, build_target, packages=None):
Alex Klein1699fab2022-09-08 08:46:06 -06001147 """Check if |build_target| builds |atom| (has it in its depgraph)."""
1148 cros_build_lib.AssertInsideChroot()
Alex Klein36b117f2019-09-30 15:13:46 -06001149
Alex Klein1699fab2022-09-08 08:46:06 -06001150 pkgs = tuple(packages) if packages else None
1151 # TODO(crbug/1081828): Receive and use sysroot.
1152 graph, _sdk_graph = dependency.GetBuildDependency(
1153 build_target.root, build_target.name, pkgs
1154 )
1155 return any(atom in package for package in graph["package_deps"])
Michael Mortensenb70e8a82019-10-10 18:43:41 -06001156
1157
Alex Klein6becabc2020-09-11 14:03:05 -06001158def needs_chrome_source(
Alex Klein1699fab2022-09-08 08:46:06 -06001159 build_target: "build_target_lib.BuildTarget",
Alex Klein6becabc2020-09-11 14:03:05 -06001160 compile_source=False,
1161 packages: Optional[List[package_info.PackageInfo]] = None,
Alex Klein1699fab2022-09-08 08:46:06 -06001162 useflags=None,
1163):
1164 """Check if the chrome source is needed.
Alex Klein6becabc2020-09-11 14:03:05 -06001165
Alex Klein1699fab2022-09-08 08:46:06 -06001166 The chrome source is needed if the build target builds chrome or any of its
1167 follower packages, and can't use a prebuilt for them either because it's not
1168 available, or because we can't use prebuilts because it must build from
1169 source.
1170 """
1171 cros_build_lib.AssertInsideChroot()
Alex Klein6becabc2020-09-11 14:03:05 -06001172
Alex Klein1699fab2022-09-08 08:46:06 -06001173 # Check if it builds chrome and/or a follower package.
1174 graph = depgraph.get_sysroot_dependency_graph(build_target.root, packages)
1175 builds_chrome = constants.CHROME_CP in graph
1176 builds_follower = {
1177 pkg: pkg in graph for pkg in constants.OTHER_CHROME_PACKAGES
1178 }
Alex Klein6becabc2020-09-11 14:03:05 -06001179
Alex Klein1699fab2022-09-08 08:46:06 -06001180 local_uprev = builds_chrome and revbump_chrome([build_target])
Alex Klein9ce3f682021-06-23 15:06:44 -06001181
Alex Klein1699fab2022-09-08 08:46:06 -06001182 # When we are compiling source set False since we do not use prebuilts.
1183 # When not compiling from source, start with True, i.e. we have every prebuilt
1184 # we've checked for up to this point.
1185 has_chrome_prebuilt = not compile_source
1186 has_follower_prebuilts = not compile_source
1187 # Save packages that need prebuilts for reporting.
1188 pkgs_needing_prebuilts = []
1189 if compile_source:
1190 # Need everything.
Alex Klein6becabc2020-09-11 14:03:05 -06001191 pkgs_needing_prebuilts.append(constants.CHROME_CP)
Alex Klein1699fab2022-09-08 08:46:06 -06001192 pkgs_needing_prebuilts.extend(
1193 [pkg for pkg, builds_pkg in builds_follower.items() if builds_pkg]
1194 )
1195 else:
1196 # Check chrome itself.
1197 if builds_chrome:
1198 has_chrome_prebuilt = has_prebuilt(
1199 constants.CHROME_CP,
1200 build_target=build_target,
1201 useflags=useflags,
1202 )
1203 if not has_chrome_prebuilt:
1204 pkgs_needing_prebuilts.append(constants.CHROME_CP)
1205 # Check follower packages.
1206 for pkg, builds_pkg in builds_follower.items():
1207 if not builds_pkg:
1208 continue
1209 prebuilt = has_prebuilt(
1210 pkg, build_target=build_target, useflags=useflags
1211 )
1212 has_follower_prebuilts &= prebuilt
1213 if not prebuilt:
1214 pkgs_needing_prebuilts.append(pkg)
1215 # Postcondition: has_chrome_prebuilt and has_follower_prebuilts now correctly
1216 # reflect whether we actually have the corresponding prebuilts for the build.
Alex Klein6becabc2020-09-11 14:03:05 -06001217
Alex Klein1699fab2022-09-08 08:46:06 -06001218 needs_chrome = builds_chrome and not has_chrome_prebuilt
1219 needs_follower = (
1220 any(builds_follower.values()) and not has_follower_prebuilts
1221 )
Alex Klein6becabc2020-09-11 14:03:05 -06001222
Alex Klein1699fab2022-09-08 08:46:06 -06001223 return NeedsChromeSourceResult(
1224 needs_chrome_source=needs_chrome or needs_follower,
1225 builds_chrome=builds_chrome,
1226 packages=[package_info.parse(p) for p in pkgs_needing_prebuilts],
1227 missing_chrome_prebuilt=not has_chrome_prebuilt,
1228 missing_follower_prebuilt=not has_follower_prebuilts,
1229 local_uprev=local_uprev,
1230 )
Alex Klein6becabc2020-09-11 14:03:05 -06001231
1232
Alex Klein68a28712021-11-08 11:08:30 -07001233class TargetVersions(NamedTuple):
Alex Klein1699fab2022-09-08 08:46:06 -06001234 """Data class for the info that makes up the "target versions"."""
1235
1236 android_version: str
1237 android_branch: str
1238 android_target: str
1239 chrome_version: str
1240 platform_version: str
1241 milestone_version: str
1242 full_version: str
Alex Klein68a28712021-11-08 11:08:30 -07001243
1244
1245def get_target_versions(
Alex Klein1699fab2022-09-08 08:46:06 -06001246 build_target: "build_target_lib.BuildTarget",
1247 packages: List[package_info.PackageInfo] = None,
Alex Klein68a28712021-11-08 11:08:30 -07001248) -> TargetVersions:
Alex Klein1699fab2022-09-08 08:46:06 -06001249 """Aggregate version info for a few key packages and the OS as a whole."""
1250 # Android version.
1251 android_version = determine_android_version(build_target.name)
1252 logging.info("Found android version: %s", android_version)
1253 # Android branch version.
1254 android_branch = determine_android_branch(build_target.name)
1255 logging.info("Found android branch version: %s", android_branch)
1256 # Android target version.
1257 android_target = determine_android_target(build_target.name)
1258 logging.info("Found android target version: %s", android_target)
Alex Klein68a28712021-11-08 11:08:30 -07001259
Alex Klein1699fab2022-09-08 08:46:06 -06001260 # TODO(crbug/1019770): Investigate cases where builds_chrome is true but
1261 # chrome_version is None.
Alex Klein68a28712021-11-08 11:08:30 -07001262
Alex Klein1699fab2022-09-08 08:46:06 -06001263 builds_chrome = builds(constants.CHROME_CP, build_target, packages=packages)
1264 chrome_version = None
1265 if builds_chrome:
1266 # Chrome version fetch.
1267 chrome_version = determine_chrome_version(build_target)
1268 logging.info("Found chrome version: %s", chrome_version)
Alex Klein68a28712021-11-08 11:08:30 -07001269
Alex Klein1699fab2022-09-08 08:46:06 -06001270 # The ChromeOS version info.
1271 platform_version = determine_platform_version()
1272 milestone_version = determine_milestone_version()
1273 full_version = determine_full_version()
Alex Klein68a28712021-11-08 11:08:30 -07001274
Alex Klein1699fab2022-09-08 08:46:06 -06001275 return TargetVersions(
1276 android_version,
1277 android_branch,
1278 android_target,
1279 chrome_version,
1280 platform_version,
1281 milestone_version,
1282 full_version,
1283 )
Alex Klein68a28712021-11-08 11:08:30 -07001284
1285
Matthias Kaehlckebf7d1772021-11-04 16:01:36 -07001286def determine_chrome_version(
Alex Klein1699fab2022-09-08 08:46:06 -06001287 build_target: "build_target_lib.BuildTarget",
1288) -> Optional[str]:
1289 """Returns the current Chrome version for the board (or in buildroot).
Michael Mortensenc2615b72019-10-15 08:12:24 -06001290
Alex Klein1699fab2022-09-08 08:46:06 -06001291 Args:
Alex Klein348e7692022-10-13 17:03:37 -06001292 build_target: The board build target.
Alex Kleinad6b48a2020-01-08 16:57:41 -07001293
Alex Klein1699fab2022-09-08 08:46:06 -06001294 Returns:
Alex Klein348e7692022-10-13 17:03:37 -06001295 The chrome version if available.
Alex Klein1699fab2022-09-08 08:46:06 -06001296 """
1297 # TODO(crbug/1019770): Long term we should not need the try/catch here once
1298 # the builds function above only returns True for chrome when
1299 # determine_chrome_version will succeed.
1300 try:
1301 pkg_info = portage_util.PortageqBestVisible(
1302 constants.CHROME_CP, build_target.name, cwd=constants.SOURCE_ROOT
1303 )
1304 except cros_build_lib.RunCommandError as e:
1305 # Return None because portage failed when trying to determine the chrome
1306 # version.
1307 logging.warning("Caught exception in determine_chrome_package: %s", e)
1308 return None
1309 # Something like 78.0.3877.4_rc -> 78.0.3877.4
1310 return pkg_info.version.partition("_")[0]
Michael Mortensenc2615b72019-10-15 08:12:24 -06001311
1312
Alex Klein68a28712021-11-08 11:08:30 -07001313@functools.lru_cache()
Matthias Kaehlckebf7d1772021-11-04 16:01:36 -07001314def determine_android_package(board: str) -> Optional[str]:
Alex Klein1699fab2022-09-08 08:46:06 -06001315 """Returns the active Android container package in use by the board.
Michael Mortensenb70e8a82019-10-10 18:43:41 -06001316
Alex Klein1699fab2022-09-08 08:46:06 -06001317 Args:
Alex Klein348e7692022-10-13 17:03:37 -06001318 board: The board name this is specific to.
Alex Kleinad6b48a2020-01-08 16:57:41 -07001319
Alex Klein1699fab2022-09-08 08:46:06 -06001320 Returns:
Alex Klein348e7692022-10-13 17:03:37 -06001321 The android package string if there is one.
Alex Klein1699fab2022-09-08 08:46:06 -06001322 """
1323 try:
1324 packages = portage_util.GetPackageDependencies(
1325 "virtual/target-os", board=board
1326 )
1327 except cros_build_lib.RunCommandError as e:
1328 # Return None because a command (likely portage) failed when trying to
1329 # determine the package.
1330 logging.warning("Caught exception in determine_android_package: %s", e)
1331 return None
1332
1333 # We assume there is only one Android package in the depgraph.
1334 for package in packages:
1335 if package.startswith(
1336 "chromeos-base/android-container-"
1337 ) or package.startswith("chromeos-base/android-vm-"):
1338 return package
Michael Mortensene0f4b542019-10-24 15:30:23 -06001339 return None
Michael Mortensenb70e8a82019-10-10 18:43:41 -06001340
1341
Matthias Kaehlckebf7d1772021-11-04 16:01:36 -07001342def determine_android_version(board: str, package: str = None):
Alex Klein1699fab2022-09-08 08:46:06 -06001343 """Determine the current Android version in buildroot now and return it.
Michael Mortensenb70e8a82019-10-10 18:43:41 -06001344
Alex Klein1699fab2022-09-08 08:46:06 -06001345 This uses the typical portage logic to determine which version of Android
1346 is active right now in the buildroot.
Michael Mortensenb70e8a82019-10-10 18:43:41 -06001347
Alex Klein1699fab2022-09-08 08:46:06 -06001348 Args:
Alex Klein348e7692022-10-13 17:03:37 -06001349 board: The board name this is specific to.
1350 package: The Android package, if already computed.
Michael Mortensenb70e8a82019-10-10 18:43:41 -06001351
Alex Klein1699fab2022-09-08 08:46:06 -06001352 Returns:
Alex Klein348e7692022-10-13 17:03:37 -06001353 The Android build ID of the container for the board.
Michael Mortensenb70e8a82019-10-10 18:43:41 -06001354
Alex Klein1699fab2022-09-08 08:46:06 -06001355 Raises:
Alex Klein348e7692022-10-13 17:03:37 -06001356 NoAndroidVersionError: if no unique Android version can be determined.
Alex Klein1699fab2022-09-08 08:46:06 -06001357 """
1358 if not package:
1359 package = determine_android_package(board)
1360 if not package:
1361 return None
1362 cpv = package_info.SplitCPV(package)
1363 if not cpv:
1364 raise NoAndroidVersionError(
1365 "Android version could not be determined for %s" % board
1366 )
1367 return cpv.version_no_rev
Michael Mortensenb70e8a82019-10-10 18:43:41 -06001368
Alex Klein7a3a7dd2020-01-08 16:44:38 -07001369
Mike Frysinger8e1c99a2021-03-05 00:58:11 -05001370def determine_android_branch(board, package=None):
Alex Klein1699fab2022-09-08 08:46:06 -06001371 """Returns the Android branch in use by the active container ebuild."""
1372 if not package:
1373 package = determine_android_package(board)
1374 if not package:
1375 return None
1376 ebuild_path = portage_util.FindEbuildForBoardPackage(package, board)
1377 # We assume all targets pull from the same branch and that we always
1378 # have at least one of the following targets.
1379 targets = constants.ANDROID_ALL_BUILD_TARGETS
1380 ebuild_content = osutils.SourceEnvironment(ebuild_path, targets)
1381 for target in targets:
1382 if target in ebuild_content:
1383 branch = re.search(r"(.*?)-linux-", ebuild_content[target])
1384 if branch is not None:
1385 return branch.group(1)
1386 raise NoAndroidBranchError(
1387 "Android branch could not be determined for %s (ebuild empty?)" % board
1388 )
Michael Mortensenb70e8a82019-10-10 18:43:41 -06001389
1390
Mike Frysinger8e1c99a2021-03-05 00:58:11 -05001391def determine_android_target(board, package=None):
Alex Klein1699fab2022-09-08 08:46:06 -06001392 """Returns the Android target in use by the active container ebuild."""
1393 if not package:
1394 package = determine_android_package(board)
1395 if not package:
1396 return None
1397 if package.startswith("chromeos-base/android-vm-"):
1398 return "bertha"
1399 elif package.startswith("chromeos-base/android-container-"):
1400 return "cheets"
Michael Mortensenb70e8a82019-10-10 18:43:41 -06001401
Alex Klein1699fab2022-09-08 08:46:06 -06001402 raise NoAndroidTargetError(
1403 "Android Target cannot be determined for the package: %s" % package
1404 )
Michael Mortensen9fdb14b2019-10-17 11:17:30 -06001405
1406
1407def determine_platform_version():
Alex Klein1699fab2022-09-08 08:46:06 -06001408 """Returns the platform version from the source root."""
1409 # Platform version is something like '12575.0.0'.
1410 version = chromeos_version.VersionInfo.from_repo(constants.SOURCE_ROOT)
1411 return version.VersionString()
Michael Mortensen009cb662019-10-21 11:38:43 -06001412
1413
1414def determine_milestone_version():
Alex Klein1699fab2022-09-08 08:46:06 -06001415 """Returns the platform version from the source root."""
1416 # Milestone version is something like '79'.
1417 version = chromeos_version.VersionInfo.from_repo(constants.SOURCE_ROOT)
1418 return version.chrome_branch
Michael Mortensen009cb662019-10-21 11:38:43 -06001419
Alex Klein7a3a7dd2020-01-08 16:44:38 -07001420
Michael Mortensen009cb662019-10-21 11:38:43 -06001421def determine_full_version():
Alex Klein1699fab2022-09-08 08:46:06 -06001422 """Returns the full version from the source root."""
1423 # Full version is something like 'R79-12575.0.0'.
1424 milestone_version = determine_milestone_version()
1425 platform_version = determine_platform_version()
1426 full_version = "R%s-%s" % (milestone_version, platform_version)
1427 return full_version
Michael Mortensen71ef5682020-05-07 14:29:24 -06001428
1429
Matthias Kaehlckebf7d1772021-11-04 16:01:36 -07001430def find_fingerprints(
Alex Klein1699fab2022-09-08 08:46:06 -06001431 build_target: "build_target_lib.BuildTarget",
1432) -> List[str]:
1433 """Returns a list of fingerprints for this build.
Michael Mortensende716a12020-05-15 11:27:00 -06001434
Alex Klein1699fab2022-09-08 08:46:06 -06001435 Args:
Alex Klein348e7692022-10-13 17:03:37 -06001436 build_target: The build target.
Michael Mortensende716a12020-05-15 11:27:00 -06001437
Alex Klein1699fab2022-09-08 08:46:06 -06001438 Returns:
Alex Klein348e7692022-10-13 17:03:37 -06001439 List of fingerprint strings.
Alex Klein1699fab2022-09-08 08:46:06 -06001440 """
1441 cros_build_lib.AssertInsideChroot()
1442 fp_file = "cheets-fingerprint.txt"
1443 fp_path = os.path.join(
1444 image_lib.GetLatestImageLink(build_target.name), fp_file
1445 )
1446 if not os.path.isfile(fp_path):
1447 logging.info("Fingerprint file not found: %s", fp_path)
1448 return []
1449 logging.info("Reading fingerprint file: %s", fp_path)
1450 fingerprints = osutils.ReadFile(fp_path).splitlines()
1451 return fingerprints
Michael Mortensende716a12020-05-15 11:27:00 -06001452
1453
Alex Klein1699fab2022-09-08 08:46:06 -06001454def get_all_firmware_versions(build_target: "build_target_lib.BuildTarget"):
1455 """Extract firmware version for all models present.
Michael Mortensen59e30872020-05-18 14:12:49 -06001456
Alex Klein1699fab2022-09-08 08:46:06 -06001457 Args:
Alex Klein348e7692022-10-13 17:03:37 -06001458 build_target: The build target.
Michael Mortensen59e30872020-05-18 14:12:49 -06001459
Alex Klein1699fab2022-09-08 08:46:06 -06001460 Returns:
Alex Klein348e7692022-10-13 17:03:37 -06001461 A dict of FirmwareVersions namedtuple instances by model.
1462 Each element will be populated based on whether it was present in the
1463 command output.
Alex Klein1699fab2022-09-08 08:46:06 -06001464 """
1465 cros_build_lib.AssertInsideChroot()
1466 result = {}
1467 # Note that example output for _get_firmware_version_cmd_result is available
1468 # in the packages_unittest.py for testing get_all_firmware_versions.
1469 cmd_result = _get_firmware_version_cmd_result(build_target)
Michael Mortensen59e30872020-05-18 14:12:49 -06001470
Alex Klein1699fab2022-09-08 08:46:06 -06001471 if cmd_result:
1472 # There is a blank line between the version info for each model.
1473 firmware_version_payloads = cmd_result.split("\n\n")
1474 for firmware_version_payload in firmware_version_payloads:
1475 if "BIOS" in firmware_version_payload:
1476 firmware_version = _find_firmware_versions(
1477 firmware_version_payload
1478 )
1479 result[firmware_version.model] = firmware_version
1480 return result
Michael Mortensen59e30872020-05-18 14:12:49 -06001481
1482
Benjamin Shai0858cd32022-01-10 20:23:49 +00001483class FirmwareVersions(NamedTuple):
Alex Klein1699fab2022-09-08 08:46:06 -06001484 """Tuple to hold firmware versions, with truthiness."""
Benjamin Shai0858cd32022-01-10 20:23:49 +00001485
Alex Klein1699fab2022-09-08 08:46:06 -06001486 model: Optional[str]
1487 main: Optional[str]
1488 main_rw: Optional[str]
1489 ec: Optional[str]
1490 ec_rw: Optional[str]
1491
1492 def __bool__(self):
1493 return bool(
1494 self.model or self.main or self.main_rw or self.ec or self.ec_rw
1495 )
Michael Mortensen71ef5682020-05-07 14:29:24 -06001496
1497
Alex Klein1699fab2022-09-08 08:46:06 -06001498def get_firmware_versions(build_target: "build_target_lib.BuildTarget"):
1499 """Extract version information from the firmware updater, if one exists.
Michael Mortensen71ef5682020-05-07 14:29:24 -06001500
Alex Klein1699fab2022-09-08 08:46:06 -06001501 Args:
Alex Klein348e7692022-10-13 17:03:37 -06001502 build_target: The build target.
Michael Mortensen71ef5682020-05-07 14:29:24 -06001503
Alex Klein1699fab2022-09-08 08:46:06 -06001504 Returns:
Alex Klein348e7692022-10-13 17:03:37 -06001505 A FirmwareVersions namedtuple instance.
1506 Each element will either be set to the string output by the firmware
1507 updater shellball, or None if there is no firmware updater.
Alex Klein1699fab2022-09-08 08:46:06 -06001508 """
1509 cros_build_lib.AssertInsideChroot()
1510 cmd_result = _get_firmware_version_cmd_result(build_target)
1511 if cmd_result:
1512 return _find_firmware_versions(cmd_result)
1513 else:
1514 return FirmwareVersions(None, None, None, None, None)
Michael Mortensen71ef5682020-05-07 14:29:24 -06001515
1516
Matthias Kaehlckebf7d1772021-11-04 16:01:36 -07001517def _get_firmware_version_cmd_result(
Alex Klein1699fab2022-09-08 08:46:06 -06001518 build_target: "build_target_lib.BuildTarget",
1519) -> Optional[str]:
1520 """Gets the raw result output of the firmware updater version command.
Michael Mortensen71ef5682020-05-07 14:29:24 -06001521
Alex Klein1699fab2022-09-08 08:46:06 -06001522 Args:
Alex Klein348e7692022-10-13 17:03:37 -06001523 build_target: The build target.
Michael Mortensen71ef5682020-05-07 14:29:24 -06001524
Alex Klein1699fab2022-09-08 08:46:06 -06001525 Returns:
Alex Klein348e7692022-10-13 17:03:37 -06001526 Command execution result.
Alex Klein1699fab2022-09-08 08:46:06 -06001527 """
1528 updater = os.path.join(
1529 build_target.root, "usr/sbin/chromeos-firmwareupdate"
1530 )
1531 logging.info("Calling updater %s", updater)
1532 # Call the updater using the chroot-based path.
1533 try:
1534 return cros_build_lib.run(
1535 [updater, "-V"],
1536 capture_output=True,
1537 log_output=True,
1538 encoding="utf-8",
1539 ).stdout
1540 except cros_build_lib.RunCommandError:
1541 # Updater probably doesn't exist (e.g. betty).
1542 return None
Michael Mortensen71ef5682020-05-07 14:29:24 -06001543
1544
1545def _find_firmware_versions(cmd_output):
Alex Klein1699fab2022-09-08 08:46:06 -06001546 """Finds firmware version output via regex matches against the cmd_output.
Michael Mortensen71ef5682020-05-07 14:29:24 -06001547
Alex Klein1699fab2022-09-08 08:46:06 -06001548 Args:
Alex Klein348e7692022-10-13 17:03:37 -06001549 cmd_output: The raw output to search against.
Michael Mortensen71ef5682020-05-07 14:29:24 -06001550
Alex Klein1699fab2022-09-08 08:46:06 -06001551 Returns:
Alex Klein348e7692022-10-13 17:03:37 -06001552 FirmwareVersions namedtuple with results.
1553 Each element will either be set to the string output by the firmware
1554 updater shellball, or None if there is no match.
Alex Klein1699fab2022-09-08 08:46:06 -06001555 """
Michael Mortensen71ef5682020-05-07 14:29:24 -06001556
Alex Klein1699fab2022-09-08 08:46:06 -06001557 # Sometimes a firmware bundle includes a special combination of RO+RW
1558 # firmware. In this case, the RW firmware version is indicated with a "(RW)
1559 # version" field. In other cases, the "(RW) version" field is not present.
1560 # Therefore, search for the "(RW)" fields first and if they aren't present,
1561 # fallback to the other format. e.g. just "BIOS version:".
1562 # TODO(mmortensen): Use JSON once the firmware updater supports it.
1563 main = None
1564 main_rw = None
1565 ec = None
1566 ec_rw = None
1567 model = None
Michael Mortensen71ef5682020-05-07 14:29:24 -06001568
Alex Klein1699fab2022-09-08 08:46:06 -06001569 match = re.search(r"BIOS version:\s*(?P<version>.*)", cmd_output)
1570 if match:
1571 main = match.group("version")
Michael Mortensen71ef5682020-05-07 14:29:24 -06001572
Alex Klein1699fab2022-09-08 08:46:06 -06001573 match = re.search(r"BIOS \(RW\) version:\s*(?P<version>.*)", cmd_output)
1574 if match:
1575 main_rw = match.group("version")
Michael Mortensen71ef5682020-05-07 14:29:24 -06001576
Alex Klein1699fab2022-09-08 08:46:06 -06001577 match = re.search(r"EC version:\s*(?P<version>.*)", cmd_output)
1578 if match:
1579 ec = match.group("version")
Michael Mortensen71ef5682020-05-07 14:29:24 -06001580
Alex Klein1699fab2022-09-08 08:46:06 -06001581 match = re.search(r"EC \(RW\) version:\s*(?P<version>.*)", cmd_output)
1582 if match:
1583 ec_rw = match.group("version")
Michael Mortensen71ef5682020-05-07 14:29:24 -06001584
Alex Klein1699fab2022-09-08 08:46:06 -06001585 match = re.search(r"Model:\s*(?P<model>.*)", cmd_output)
1586 if match:
1587 model = match.group("model")
Michael Mortensen71ef5682020-05-07 14:29:24 -06001588
Alex Klein1699fab2022-09-08 08:46:06 -06001589 return FirmwareVersions(model, main, main_rw, ec, ec_rw)
Michael Mortensena4af79e2020-05-06 16:18:48 -06001590
1591
Benjamin Shai0858cd32022-01-10 20:23:49 +00001592class MainEcFirmwareVersions(NamedTuple):
Alex Klein1699fab2022-09-08 08:46:06 -06001593 """Tuple to hold main and ec firmware versions, with truthiness."""
Benjamin Shai0858cd32022-01-10 20:23:49 +00001594
Alex Klein1699fab2022-09-08 08:46:06 -06001595 main_fw_version: Optional[str]
1596 ec_fw_version: Optional[str]
1597
1598 def __bool__(self):
1599 return bool(self.main_fw_version or self.ec_fw_version)
Benjamin Shai0858cd32022-01-10 20:23:49 +00001600
Michael Mortensena4af79e2020-05-06 16:18:48 -06001601
Alex Klein1699fab2022-09-08 08:46:06 -06001602def determine_firmware_versions(build_target: "build_target_lib.BuildTarget"):
1603 """Returns a namedtuple with main and ec firmware versions.
Michael Mortensena4af79e2020-05-06 16:18:48 -06001604
Alex Klein1699fab2022-09-08 08:46:06 -06001605 Args:
Alex Klein348e7692022-10-13 17:03:37 -06001606 build_target: The build target.
Michael Mortensena4af79e2020-05-06 16:18:48 -06001607
Alex Klein1699fab2022-09-08 08:46:06 -06001608 Returns:
Alex Klein348e7692022-10-13 17:03:37 -06001609 MainEcFirmwareVersions namedtuple with results.
Alex Klein1699fab2022-09-08 08:46:06 -06001610 """
1611 fw_versions = get_firmware_versions(build_target)
1612 main_fw_version = fw_versions.main_rw or fw_versions.main
1613 ec_fw_version = fw_versions.ec_rw or fw_versions.ec
Michael Mortensena4af79e2020-05-06 16:18:48 -06001614
Alex Klein1699fab2022-09-08 08:46:06 -06001615 return MainEcFirmwareVersions(main_fw_version, ec_fw_version)
Michael Mortensenfbf2b2d2020-05-14 16:33:06 -06001616
Benjamin Shai0858cd32022-01-10 20:23:49 +00001617
Matthias Kaehlckebf7d1772021-11-04 16:01:36 -07001618def determine_kernel_version(
Alex Klein1699fab2022-09-08 08:46:06 -06001619 build_target: "build_target_lib.BuildTarget",
Lizzy Presland0b978e62022-09-09 16:55:29 +00001620) -> str:
Alex Klein1699fab2022-09-08 08:46:06 -06001621 """Returns a string containing the kernel version for this build target.
Michael Mortensenfbf2b2d2020-05-14 16:33:06 -06001622
Alex Klein1699fab2022-09-08 08:46:06 -06001623 Args:
Alex Klein348e7692022-10-13 17:03:37 -06001624 build_target: The build target.
Michael Mortensenfbf2b2d2020-05-14 16:33:06 -06001625
Alex Klein1699fab2022-09-08 08:46:06 -06001626 Returns:
Alex Klein348e7692022-10-13 17:03:37 -06001627 The kernel versions, or empty string.
Alex Klein1699fab2022-09-08 08:46:06 -06001628 """
Lizzy Presland0b978e62022-09-09 16:55:29 +00001629 target_virtual_pkg = "virtual/linux-sources"
Alex Klein1699fab2022-09-08 08:46:06 -06001630 try:
Lizzy Presland0b978e62022-09-09 16:55:29 +00001631 candidate_packages = portage_util.GetFlattenedDepsForPackage(
1632 target_virtual_pkg,
1633 sysroot=build_target.root,
1634 board=build_target.name,
1635 depth=1,
1636 )
1637 installed_packages = portage_util.GetPackageDependencies(
1638 target_virtual_pkg, board=build_target.name
Alex Klein1699fab2022-09-08 08:46:06 -06001639 )
1640 except cros_build_lib.RunCommandError as e:
1641 logging.warning("Unable to get package list for metadata: %s", e)
Lizzy Presland0b978e62022-09-09 16:55:29 +00001642 return ""
1643 if not candidate_packages:
1644 raise KernelVersionError("No package found in FlattenedDepsForPackage")
1645 if not installed_packages:
1646 raise KernelVersionError("No package found in GetPackageDependencies")
1647 packages = [
1648 p
1649 for p in installed_packages
1650 if p in candidate_packages and target_virtual_pkg not in p
1651 ]
1652 if len(packages) == 0:
1653 raise KernelVersionError(
1654 "No matches for installed packages were found in candidate "
1655 "packages. Did GetFlattenedDepsForPackage search all possible "
1656 "package versions?\tInstalled: %s\tCandidates: %s"
1657 % (" ".join(installed_packages), " ".join(candidate_packages))
1658 )
1659 if len(packages) > 1:
1660 raise KernelVersionError(
1661 "Too many packages found in intersection of installed packages and "
1662 "possible kernel versions (%s)" % "".join(packages)
1663 )
1664 kernel_version = package_info.SplitCPV(packages[0]).version
1665 logging.info("Found active kernel version: %s", kernel_version)
1666 return kernel_version
Michael Mortensen125bb012020-05-21 14:02:10 -06001667
1668
Matthias Kaehlckebf7d1772021-11-04 16:01:36 -07001669def get_models(
Alex Klein1699fab2022-09-08 08:46:06 -06001670 build_target: "build_target_lib.BuildTarget", log_output: bool = True
1671) -> Optional[List[str]]:
1672 """Obtain a list of models supported by a unified board.
Michael Mortensen125bb012020-05-21 14:02:10 -06001673
Alex Klein1699fab2022-09-08 08:46:06 -06001674 This ignored whitelabel models since GoldenEye has no specific support for
1675 these at present.
Michael Mortensen125bb012020-05-21 14:02:10 -06001676
Alex Klein1699fab2022-09-08 08:46:06 -06001677 Args:
Alex Klein348e7692022-10-13 17:03:37 -06001678 build_target: The build target.
1679 log_output: Whether to log the output of the cros_config_host
1680 invocation.
Michael Mortensen125bb012020-05-21 14:02:10 -06001681
Alex Klein1699fab2022-09-08 08:46:06 -06001682 Returns:
Alex Klein348e7692022-10-13 17:03:37 -06001683 A list of models supported by this board, if it is a unified build;
1684 None, if it is not a unified build.
Alex Klein1699fab2022-09-08 08:46:06 -06001685 """
1686 return _run_cros_config_host(
1687 build_target, ["list-models"], log_output=log_output
1688 )
Michael Mortensen125bb012020-05-21 14:02:10 -06001689
1690
Matthias Kaehlckebf7d1772021-11-04 16:01:36 -07001691def get_key_id(
Alex Klein1699fab2022-09-08 08:46:06 -06001692 build_target: "build_target_lib.BuildTarget", model: str
1693) -> Optional[str]:
1694 """Obtain the key_id for a model within the build_target.
Michael Mortensen359c1f32020-05-28 19:35:42 -06001695
Alex Klein1699fab2022-09-08 08:46:06 -06001696 Args:
Alex Klein348e7692022-10-13 17:03:37 -06001697 build_target: The build target.
1698 model: The model name
Michael Mortensen359c1f32020-05-28 19:35:42 -06001699
Alex Klein1699fab2022-09-08 08:46:06 -06001700 Returns:
Alex Klein348e7692022-10-13 17:03:37 -06001701 A key_id or None.
Alex Klein1699fab2022-09-08 08:46:06 -06001702 """
1703 model_arg = "--model=" + model
1704 key_id_list = _run_cros_config_host(
1705 build_target, [model_arg, "get", "/firmware-signing", "key-id"]
1706 )
1707 key_id = None
1708 if len(key_id_list) == 1:
1709 key_id = key_id_list[0]
1710 return key_id
Michael Mortensen359c1f32020-05-28 19:35:42 -06001711
1712
Matthias Kaehlckebf7d1772021-11-04 16:01:36 -07001713def _run_cros_config_host(
Alex Klein1699fab2022-09-08 08:46:06 -06001714 build_target: "build_target_lib.BuildTarget",
Matthias Kaehlckebf7d1772021-11-04 16:01:36 -07001715 args: List[str],
Alex Klein1699fab2022-09-08 08:46:06 -06001716 log_output: bool = True,
1717) -> Optional[List[str]]:
1718 """Run the cros_config_host tool.
Michael Mortensen125bb012020-05-21 14:02:10 -06001719
Alex Klein1699fab2022-09-08 08:46:06 -06001720 Args:
Alex Klein348e7692022-10-13 17:03:37 -06001721 build_target: The build target.
1722 args: List of arguments to pass.
1723 log_output: Whether to log the output of the cros_config_host.
Michael Mortensen125bb012020-05-21 14:02:10 -06001724
Alex Klein1699fab2022-09-08 08:46:06 -06001725 Returns:
Alex Klein348e7692022-10-13 17:03:37 -06001726 Output of the tool
Alex Klein1699fab2022-09-08 08:46:06 -06001727 """
1728 cros_build_lib.AssertInsideChroot()
1729 tool = "/usr/bin/cros_config_host"
1730 if not os.path.isfile(tool):
1731 return None
Michael Mortensen125bb012020-05-21 14:02:10 -06001732
Alex Klein1699fab2022-09-08 08:46:06 -06001733 config_fname = build_target.full_path(
1734 "usr/share/chromeos-config/yaml/config.yaml"
1735 )
Michael Mortensen125bb012020-05-21 14:02:10 -06001736
Alex Klein1699fab2022-09-08 08:46:06 -06001737 result = cros_build_lib.run(
1738 [tool, "-c", config_fname] + args,
1739 capture_output=True,
1740 encoding="utf-8",
1741 log_output=log_output,
1742 check=False,
1743 )
1744 if result.returncode:
1745 # Show the output for debugging purposes.
1746 if "No such file or directory" not in result.stderr:
1747 logging.error("cros_config_host failed: %s\n", result.stderr)
1748 return None
1749 return result.stdout.strip().splitlines()