blob: 17c1343ca7a4c1087207a7805c0bac8efb0ff647 [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:
81 new_android_atom: The Android atom that we failed to
82 uprev to, due to Android being pinned.
83 """
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:
124 ebuild_path: The path of the ebuild.
125 variables: Dictionary of variables to update in ebuild.
126 """
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:
172 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 to
176 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 uprev.
Shao-Chuan Lee84bf9a22021-11-19 17:42:11 +0900180
Alex Klein1699fab2022-09-08 08:46:06 -0600181 Returns:
182 The uprev result containing:
183 revved: Whether an uprev happened.
184 android_atom: If revved, the portage atom for the revved Android ebuild.
185 modified_files: If revved, list of files being modified.
186 """
187 command = [
188 "cros_mark_android_as_stable",
189 f"--android_package={android_package}",
190 ]
191 if build_targets:
192 command.append(f'--boards={":".join(bt.name for bt in build_targets)}')
193 if android_build_branch:
194 command.append(f"--android_build_branch={android_build_branch}")
195 if android_version:
196 command.append(f"--force_version={android_version}")
197 if skip_commit:
198 command.append("--skip_commit")
Alex Klein4de25e82019-08-05 15:58:39 -0600199
Alex Klein1699fab2022-09-08 08:46:06 -0600200 result = cros_build_lib.run(
201 command,
202 stdout=True,
203 enter_chroot=True,
204 encoding="utf-8",
205 chroot_args=chroot.get_enter_args(),
206 )
Alex Klein4de25e82019-08-05 15:58:39 -0600207
Alex Klein1699fab2022-09-08 08:46:06 -0600208 # cros_mark_android_as_stable prints the uprev result to stdout as JSON in a
209 # single line. We only take the last line from stdout to make sure no junk
210 # output is included (e.g. messages from bashrc scripts that run upon entering
211 # the chroot.)
212 output = json.loads(result.stdout.strip().splitlines()[-1])
Shao-Chuan Leedea458f2021-11-25 23:46:53 +0900213
Alex Klein1699fab2022-09-08 08:46:06 -0600214 if not output["revved"]:
215 logging.info("Found nothing to rev.")
216 return UprevAndroidResult(revved=False)
Shao-Chuan Lee84bf9a22021-11-19 17:42:11 +0900217
Alex Klein1699fab2022-09-08 08:46:06 -0600218 android_atom = output["android_atom"]
Alex Klein4de25e82019-08-05 15:58:39 -0600219
Alex Klein1699fab2022-09-08 08:46:06 -0600220 for target in build_targets or []:
221 # Sanity check: We should always be able to merge the version of
222 # Android we just unmasked.
223 command = [f"emerge-{target.name}", "-p", "--quiet", f"={android_atom}"]
224 try:
225 cros_build_lib.run(
226 command, enter_chroot=True, chroot_args=chroot.get_enter_args()
227 )
228 except cros_build_lib.RunCommandError:
229 logging.error(
230 "Cannot emerge-%s =%s\nIs Android pinned to an older "
231 "version?",
232 target,
233 android_atom,
234 )
235 raise AndroidIsPinnedUprevError(android_atom)
Alex Klein4de25e82019-08-05 15:58:39 -0600236
Alex Klein1699fab2022-09-08 08:46:06 -0600237 return UprevAndroidResult(
238 revved=True,
239 android_atom=android_atom,
240 modified_files=output["modified_files"],
241 )
Shao-Chuan Lee05e51142021-11-24 12:27:37 +0900242
243
Alex Klein1699fab2022-09-08 08:46:06 -0600244def uprev_android_lkgb(
245 android_package: str,
246 build_targets: List["build_target_lib.BuildTarget"],
247 chroot: "chroot_lib.Chroot",
248) -> uprev_lib.UprevVersionedPackageResult:
249 """Uprevs an Android package to the version specified in the LKGB file.
Shao-Chuan Lee05e51142021-11-24 12:27:37 +0900250
Alex Klein1699fab2022-09-08 08:46:06 -0600251 This is the PUpr handler for Android packages, triggered whenever the
252 corresponding LKGB file is being updated.
Shao-Chuan Lee05e51142021-11-24 12:27:37 +0900253
Alex Klein1699fab2022-09-08 08:46:06 -0600254 PUpr for Android does not test the uprev change in CQ; instead we run separate
255 jobs to test new Android versions, and we write the latest vetted version to
256 the LKGB file. Find the design at go/android-uprev-recipes.
Shao-Chuan Lee05e51142021-11-24 12:27:37 +0900257
Alex Klein1699fab2022-09-08 08:46:06 -0600258 Args:
259 android_package: The Android package to uprev.
260 build_targets: List of build targets to cleanup after uprev.
261 chroot: The chroot to enter.
Shao-Chuan Lee05e51142021-11-24 12:27:37 +0900262
Alex Klein1699fab2022-09-08 08:46:06 -0600263 Returns:
264 An uprev_lib.UprevVersionedPackageResult containing the new version and a
265 list of modified files.
266 """
267 android_package_dir = android.GetAndroidPackageDir(android_package)
268 android_version = android.ReadLKGB(android_package_dir)
Shao-Chuan Lee05e51142021-11-24 12:27:37 +0900269
Alex Klein1699fab2022-09-08 08:46:06 -0600270 result = uprev_lib.UprevVersionedPackageResult()
271 uprev_result = uprev_android(
272 android_package,
273 chroot,
274 build_targets=build_targets,
275 android_version=android_version,
276 skip_commit=True,
277 )
278 if not uprev_result.revved:
279 return result
280
281 # cros_mark_android_as_stable returns paths relative to |android.OVERLAY_DIR|.
282 result.add_result(
283 android_version,
284 [
285 os.path.join(android.OVERLAY_DIR, f)
286 for f in uprev_result.modified_files
287 ],
288 )
Shao-Chuan Lee05e51142021-11-24 12:27:37 +0900289 return result
290
Shao-Chuan Lee05e51142021-11-24 12:27:37 +0900291
292def define_uprev_android_lkgb_handlers():
Alex Klein1699fab2022-09-08 08:46:06 -0600293 """Dynamically define uprev handlers for each Android package"""
Shao-Chuan Lee05e51142021-11-24 12:27:37 +0900294
Alex Klein1699fab2022-09-08 08:46:06 -0600295 def define_handler(android_package):
296 """Defines the uprev handler for an Android package."""
297 full_package_name = "chromeos-base/" + android_package
Shao-Chuan Lee05e51142021-11-24 12:27:37 +0900298
Alex Klein1699fab2022-09-08 08:46:06 -0600299 @uprevs_versioned_package(full_package_name)
300 def _handler(build_targets, _refs, chroot):
301 return uprev_android_lkgb(android_package, build_targets, chroot)
Shao-Chuan Lee05e51142021-11-24 12:27:37 +0900302
Alex Klein1699fab2022-09-08 08:46:06 -0600303 for android_package in constants.ANDROID_ALL_PACKAGES:
304 define_handler(android_package)
Shao-Chuan Lee05e51142021-11-24 12:27:37 +0900305
306
307define_uprev_android_lkgb_handlers()
Alex Klein4de25e82019-08-05 15:58:39 -0600308
309
Matthias Kaehlckebf7d1772021-11-04 16:01:36 -0700310def uprev_build_targets(
Alex Klein1699fab2022-09-08 08:46:06 -0600311 build_targets: Optional[List["build_target_lib.BuildTarget"]],
Matthias Kaehlckebf7d1772021-11-04 16:01:36 -0700312 overlay_type: str,
Alex Klein1699fab2022-09-08 08:46:06 -0600313 chroot: "chroot_lib.Chroot" = None,
314 output_dir: Optional[str] = None,
315):
316 """Uprev the set provided build targets, or all if not specified.
Alex Kleineb77ffa2019-05-28 14:47:44 -0600317
Alex Klein1699fab2022-09-08 08:46:06 -0600318 Args:
319 build_targets: The build targets
320 whose overlays should be uprevved, empty or None for all.
321 overlay_type: One of the valid overlay types except None (see
322 constants.VALID_OVERLAYS).
323 chroot: The chroot to clean, if desired.
324 output_dir: The path to optionally dump result files.
325 """
326 # Need a valid overlay, but exclude None.
327 assert overlay_type and overlay_type in constants.VALID_OVERLAYS
Alex Kleineb77ffa2019-05-28 14:47:44 -0600328
Alex Klein1699fab2022-09-08 08:46:06 -0600329 if build_targets:
330 overlays = portage_util.FindOverlaysForBoards(
331 overlay_type, boards=[t.name for t in build_targets]
332 )
333 else:
334 overlays = portage_util.FindOverlays(overlay_type)
Alex Kleineb77ffa2019-05-28 14:47:44 -0600335
Alex Klein1699fab2022-09-08 08:46:06 -0600336 return uprev_overlays(
337 overlays,
338 build_targets=build_targets,
339 chroot=chroot,
340 output_dir=output_dir,
341 )
Alex Kleineb77ffa2019-05-28 14:47:44 -0600342
343
Matthias Kaehlckebf7d1772021-11-04 16:01:36 -0700344def uprev_overlays(
345 overlays: List[str],
Alex Klein1699fab2022-09-08 08:46:06 -0600346 build_targets: Optional[List["build_target_lib.BuildTarget"]] = None,
347 chroot: Optional["chroot_lib.Chroot"] = None,
348 output_dir: Optional[str] = None,
349) -> List[str]:
350 """Uprev the given overlays.
Alex Kleineb77ffa2019-05-28 14:47:44 -0600351
Alex Klein1699fab2022-09-08 08:46:06 -0600352 Args:
353 overlays: The list of overlay paths.
354 build_targets: The build targets
355 to clean in |chroot|, if desired. No effect unless |chroot| is provided.
356 chroot: The chroot to clean, if desired.
357 output_dir: The path to optionally dump result files.
Alex Kleineb77ffa2019-05-28 14:47:44 -0600358
Alex Klein1699fab2022-09-08 08:46:06 -0600359 Returns:
360 The paths to all of the modified ebuild files. This includes the new files
361 that were added (i.e. the new versions) and all of the removed files
362 (i.e. the old versions).
363 """
364 assert overlays
Alex Kleineb77ffa2019-05-28 14:47:44 -0600365
Alex Klein1699fab2022-09-08 08:46:06 -0600366 manifest = git.ManifestCheckout.Cached(constants.SOURCE_ROOT)
Alex Kleineb77ffa2019-05-28 14:47:44 -0600367
Alex Klein1699fab2022-09-08 08:46:06 -0600368 uprev_manager = uprev_lib.UprevOverlayManager(
369 overlays,
370 manifest,
371 build_targets=build_targets,
372 chroot=chroot,
373 output_dir=output_dir,
374 )
375 uprev_manager.uprev()
Alex Kleineb77ffa2019-05-28 14:47:44 -0600376
Alex Klein1699fab2022-09-08 08:46:06 -0600377 return uprev_manager.modified_ebuilds, uprev_manager.revved_packages
Alex Kleineb77ffa2019-05-28 14:47:44 -0600378
379
Matthias Kaehlckebf7d1772021-11-04 16:01:36 -0700380def uprev_versioned_package(
381 package: package_info.CPV,
Alex Klein1699fab2022-09-08 08:46:06 -0600382 build_targets: List["build_target_lib.BuildTarget"],
Matthias Kaehlckebf7d1772021-11-04 16:01:36 -0700383 refs: List[uprev_lib.GitRef],
Alex Klein1699fab2022-09-08 08:46:06 -0600384 chroot: "chroot_lib.Chroot",
385) -> "uprev_lib.UprevVersionedPackageResult":
386 """Call registered uprev handler function for the package.
Alex Klein87531182019-08-12 15:23:37 -0600387
Alex Klein1699fab2022-09-08 08:46:06 -0600388 Args:
389 package: The package being uprevved.
390 build_targets: The build targets to clean on a successful uprev.
391 refs:
392 chroot: The chroot to enter for cleaning.
Alex Klein87531182019-08-12 15:23:37 -0600393
Alex Klein1699fab2022-09-08 08:46:06 -0600394 Returns:
395 The result.
396 """
397 assert package
Alex Klein87531182019-08-12 15:23:37 -0600398
Alex Klein1699fab2022-09-08 08:46:06 -0600399 if package.cp not in _UPREV_FUNCS:
400 raise UnknownPackageError(
401 'Package "%s" does not have a registered handler.' % package.cp
402 )
Alex Klein87531182019-08-12 15:23:37 -0600403
Alex Klein1699fab2022-09-08 08:46:06 -0600404 return _UPREV_FUNCS[package.cp](build_targets, refs, chroot)
Alex Klein87531182019-08-12 15:23:37 -0600405
406
Alex Klein1699fab2022-09-08 08:46:06 -0600407@uprevs_versioned_package("media-libs/virglrenderer")
Navil Perezf57ba872020-06-04 22:38:37 +0000408def uprev_virglrenderer(_build_targets, refs, _chroot):
Alex Klein1699fab2022-09-08 08:46:06 -0600409 """Updates virglrenderer ebuilds.
Navil Perezf57ba872020-06-04 22:38:37 +0000410
Alex Klein1699fab2022-09-08 08:46:06 -0600411 See: uprev_versioned_package.
Navil Perezf57ba872020-06-04 22:38:37 +0000412
Alex Klein1699fab2022-09-08 08:46:06 -0600413 Returns:
414 UprevVersionedPackageResult: The result of updating virglrenderer ebuilds.
415 """
416 overlay = os.path.join(
417 constants.SOURCE_ROOT, constants.CHROMIUMOS_OVERLAY_DIR
418 )
419 repo_path = os.path.join(
420 constants.SOURCE_ROOT, "src", "third_party", "virglrenderer"
421 )
422 manifest = git.ManifestCheckout.Cached(repo_path)
Navil Perezf57ba872020-06-04 22:38:37 +0000423
Alex Klein1699fab2022-09-08 08:46:06 -0600424 uprev_manager = uprev_lib.UprevOverlayManager([overlay], manifest)
425 # TODO(crbug.com/1066242): Ebuilds for virglrenderer are currently
426 # denylisted. Do not force uprevs after builder is stable and ebuilds are no
427 # longer denylisted.
428 uprev_manager.uprev(package_list=["media-libs/virglrenderer"], force=True)
Navil Perezf57ba872020-06-04 22:38:37 +0000429
Alex Klein1699fab2022-09-08 08:46:06 -0600430 updated_files = uprev_manager.modified_ebuilds
431 result = uprev_lib.UprevVersionedPackageResult()
432 result.add_result(refs[-1].revision, updated_files)
433 return result
Navil Perezf57ba872020-06-04 22:38:37 +0000434
Alex Klein1699fab2022-09-08 08:46:06 -0600435
436@uprevs_versioned_package("chromeos-base/drivefs")
Jose Magana03b5a842020-08-19 12:52:59 +1000437def uprev_drivefs(_build_targets, refs, chroot):
Alex Klein1699fab2022-09-08 08:46:06 -0600438 """Updates drivefs ebuilds.
Jose Magana03b5a842020-08-19 12:52:59 +1000439
Alex Klein1699fab2022-09-08 08:46:06 -0600440 DriveFS versions follow the tag format of refs/tags/drivefs_1.2.3.
441 See: uprev_versioned_package.
Jose Magana03b5a842020-08-19 12:52:59 +1000442
Alex Klein1699fab2022-09-08 08:46:06 -0600443 Returns:
444 UprevVersionedPackageResult: The result of updating drivefs ebuilds.
445 """
Jose Magana03b5a842020-08-19 12:52:59 +1000446
Alex Klein1699fab2022-09-08 08:46:06 -0600447 DRIVEFS_PATH_PREFIX = "src/private-overlays/chromeos-overlay/chromeos-base"
448 result = uprev_lib.UprevVersionedPackageResult()
449 all_changed_files = []
Jose Magana03b5a842020-08-19 12:52:59 +1000450
Alex Klein1699fab2022-09-08 08:46:06 -0600451 DRIVEFS_REFS_PREFIX = "refs/tags/drivefs_"
452 drivefs_version = _get_latest_version_from_refs(DRIVEFS_REFS_PREFIX, refs)
453 if not drivefs_version:
454 # No valid DriveFS version is identified.
455 return result
456
457 logging.debug("DriveFS version determined from refs: %s", drivefs_version)
458
459 # Attempt to uprev drivefs package.
460 pkg_path = os.path.join(DRIVEFS_PATH_PREFIX, "drivefs")
461 uprev_result = uprev_lib.uprev_workon_ebuild_to_version(
462 pkg_path, drivefs_version, chroot, allow_downrev=False
463 )
464
465 if not uprev_result:
466 return result
467 all_changed_files.extend(uprev_result.changed_files)
468 result.add_result(drivefs_version, all_changed_files)
469
Ben Reich4f3fa1b2020-12-19 08:21:26 +0000470 return result
Jose Magana03b5a842020-08-19 12:52:59 +1000471
Jose Magana03b5a842020-08-19 12:52:59 +1000472
Alex Klein1699fab2022-09-08 08:46:06 -0600473@uprevs_versioned_package("chromeos-base/perfetto")
Harvey Yang9c61e9c2021-03-02 16:32:43 +0800474def uprev_perfetto(_build_targets, refs, chroot):
Alex Klein1699fab2022-09-08 08:46:06 -0600475 """Updates Perfetto ebuilds.
Harvey Yang9c61e9c2021-03-02 16:32:43 +0800476
Alex Klein1699fab2022-09-08 08:46:06 -0600477 Perfetto versions follow the tag format of refs/tags/v1.2.
478 See: uprev_versioned_package.
Harvey Yang9c61e9c2021-03-02 16:32:43 +0800479
Alex Klein1699fab2022-09-08 08:46:06 -0600480 Returns:
481 UprevVersionedPackageResult: The result of updating Perfetto ebuilds.
482 """
483 result = uprev_lib.UprevVersionedPackageResult()
Harvey Yang9c61e9c2021-03-02 16:32:43 +0800484
Alex Klein1699fab2022-09-08 08:46:06 -0600485 PERFETTO_REFS_PREFIX = "refs/tags/v"
Chinglin Yu84818732022-10-03 12:03:43 +0800486 # |perfetto_version| is only used in determining the ebuild version. The
487 # package is always updated to the latest HEAD.
Alex Klein1699fab2022-09-08 08:46:06 -0600488 perfetto_version = _get_latest_version_from_refs(PERFETTO_REFS_PREFIX, refs)
489 if not perfetto_version:
490 # No valid Perfetto version is identified.
491 return result
492
Alex Klein1699fab2022-09-08 08:46:06 -0600493 # Attempt to uprev perfetto package.
494 PERFETTO_PATH = "src/third_party/chromiumos-overlay/chromeos-base/perfetto"
495
496 uprev_result = uprev_lib.uprev_workon_ebuild_to_version(
497 PERFETTO_PATH,
498 perfetto_version,
499 chroot,
500 allow_downrev=False,
Chinglin Yu84818732022-10-03 12:03:43 +0800501 # Use default ref="HEAD"
Alex Klein1699fab2022-09-08 08:46:06 -0600502 )
503
504 if not uprev_result:
505 return result
506
507 result.add_result(perfetto_version, uprev_result.changed_files)
508
Harvey Yang9c61e9c2021-03-02 16:32:43 +0800509 return result
510
Harvey Yang9c61e9c2021-03-02 16:32:43 +0800511
Denis Nikitin63613e32022-09-09 22:26:50 -0700512class AfdoMetadata(NamedTuple):
513 """Data class holding AFDO metadata."""
514
515 var_name: str
516 path: str
517
518
Alex Klein1699fab2022-09-08 08:46:06 -0600519@uprevs_versioned_package("afdo/kernel-profiles")
Yaakov Shaul395ae832019-09-09 14:45:32 -0600520def uprev_kernel_afdo(*_args, **_kwargs):
Alex Klein1699fab2022-09-08 08:46:06 -0600521 """Updates kernel ebuilds with versions from kernel_afdo.json.
Yaakov Shaul395ae832019-09-09 14:45:32 -0600522
Alex Klein1699fab2022-09-08 08:46:06 -0600523 See: uprev_versioned_package.
Yaakov Shaul1eafe832019-09-10 16:50:26 -0600524
Alex Klein1699fab2022-09-08 08:46:06 -0600525 Raises:
526 EbuildManifestError: When ebuild manifest does not complete successfuly.
Denis Nikitin63613e32022-09-09 22:26:50 -0700527 JSONDecodeError: When json is malformed.
Alex Klein1699fab2022-09-08 08:46:06 -0600528 """
Denis Nikitin63613e32022-09-09 22:26:50 -0700529 metadata_dir = os.path.join(
Alex Klein1699fab2022-09-08 08:46:06 -0600530 constants.SOURCE_ROOT,
531 "src",
532 "third_party",
533 "toolchain-utils",
534 "afdo_metadata",
Denis Nikitin63613e32022-09-09 22:26:50 -0700535 )
536 metadata_files = (
537 AfdoMetadata(
538 var_name="AFDO_PROFILE_VERSION",
539 path=os.path.join(metadata_dir, "kernel_afdo.json"),
540 ),
541 AfdoMetadata(
542 var_name="ARM_AFDO_PROFILE_VERSION",
543 path=os.path.join(metadata_dir, "kernel_arm_afdo.json"),
544 ),
Alex Klein1699fab2022-09-08 08:46:06 -0600545 )
Yaakov Shaul395ae832019-09-09 14:45:32 -0600546
Alex Klein1699fab2022-09-08 08:46:06 -0600547 result = uprev_lib.UprevVersionedPackageResult()
Denis Nikitin63613e32022-09-09 22:26:50 -0700548 for metadata in metadata_files:
549 with open(metadata.path, "r") as f:
550 versions = json.load(f)
Yaakov Shaul1eafe832019-09-10 16:50:26 -0600551
Denis Nikitin63613e32022-09-09 22:26:50 -0700552 for kernel_pkg, version_info in versions.items():
553 path = os.path.join(
554 constants.CHROMIUMOS_OVERLAY_DIR, "sys-kernel", kernel_pkg
555 )
556 ebuild_path = os.path.join(
557 constants.SOURCE_ROOT, path, f"{kernel_pkg}-9999.ebuild"
558 )
559 chroot_ebuild_path = os.path.join(
560 constants.CHROOT_SOURCE_ROOT, path, f"{kernel_pkg}-9999.ebuild"
561 )
562 afdo_profile_version = version_info["name"]
563 patch_ebuild_vars(
564 ebuild_path, {metadata.var_name: afdo_profile_version}
Alex Klein1699fab2022-09-08 08:46:06 -0600565 )
Yaakov Shaul1eafe832019-09-10 16:50:26 -0600566
Denis Nikitin63613e32022-09-09 22:26:50 -0700567 try:
568 cmd = ["ebuild", chroot_ebuild_path, "manifest", "--force"]
569 cros_build_lib.run(cmd, enter_chroot=True)
570 except cros_build_lib.RunCommandError as e:
571 raise uprev_lib.EbuildManifestError(
572 "Error encountered when regenerating the manifest for "
573 f"ebuild: {chroot_ebuild_path}\n{e}",
574 e,
575 )
Yaakov Shaul1eafe832019-09-10 16:50:26 -0600576
Denis Nikitin63613e32022-09-09 22:26:50 -0700577 manifest_path = os.path.join(
578 constants.SOURCE_ROOT, path, "Manifest"
579 )
580 result.add_result(
581 afdo_profile_version, [ebuild_path, manifest_path]
582 )
Yaakov Shaul730814a2019-09-10 13:58:25 -0600583
Alex Klein1699fab2022-09-08 08:46:06 -0600584 return result
Yaakov Shaul395ae832019-09-09 14:45:32 -0600585
586
Alex Klein1699fab2022-09-08 08:46:06 -0600587@uprevs_versioned_package("chromeos-base/termina-dlc")
588@uprevs_versioned_package("chromeos-base/termina-tools-dlc")
Maciek Swiech6b12f662022-01-25 16:51:19 +0000589def uprev_termina_dlcs(_build_targets, _refs, chroot):
Alex Klein1699fab2022-09-08 08:46:06 -0600590 """Updates shared termina-dlc and termina-tools-dlc ebuilds.
Maciek Swiech6b12f662022-01-25 16:51:19 +0000591
Alex Klein1699fab2022-09-08 08:46:06 -0600592 termina-dlc - chromeos-base/termina-dlc
593 termina-tools-dlc - chromeos-base/termina-tools-dlc
Trent Beginaf51f1b2020-03-09 17:35:31 -0600594
Alex Klein1699fab2022-09-08 08:46:06 -0600595 See: uprev_versioned_package.
596 """
597 termina_dlc_pkg = "termina-dlc"
598 termina_dlc_pkg_path = os.path.join(
599 constants.CHROMIUMOS_OVERLAY_DIR, "chromeos-base", termina_dlc_pkg
600 )
601 tools_dlc_pkg = "termina-tools-dlc"
602 tools_dlc_pkg_path = os.path.join(
603 constants.CHROMIUMOS_OVERLAY_DIR, "chromeos-base", tools_dlc_pkg
604 )
Patrick Meiring5897add2020-09-16 16:30:17 +1000605
Alex Klein1699fab2022-09-08 08:46:06 -0600606 # termina-dlc and termina-tools-dlc are pinned to the same version.
607 version_pin_src_path = _get_version_pin_src_path(termina_dlc_pkg_path)
608 version_no_rev = osutils.ReadFile(version_pin_src_path).strip()
Patrick Meiring5897add2020-09-16 16:30:17 +1000609
Alex Klein1699fab2022-09-08 08:46:06 -0600610 result = uprev_lib.uprev_ebuild_from_pin(
611 termina_dlc_pkg_path, version_no_rev, chroot
612 )
613 result += uprev_lib.uprev_ebuild_from_pin(
614 tools_dlc_pkg_path, version_no_rev, chroot
615 )
Patrick Meiring5897add2020-09-16 16:30:17 +1000616
Alex Klein1699fab2022-09-08 08:46:06 -0600617 return result
Patrick Meiring5897add2020-09-16 16:30:17 +1000618
Alex Klein1699fab2022-09-08 08:46:06 -0600619
620@uprevs_versioned_package("chromeos-base/chromeos-lacros")
Julio Hurtadof1befec2021-05-05 21:34:26 +0000621def uprev_lacros(_build_targets, refs, chroot):
Alex Klein1699fab2022-09-08 08:46:06 -0600622 """Updates lacros ebuilds.
Julio Hurtadof1befec2021-05-05 21:34:26 +0000623
Alex Klein1699fab2022-09-08 08:46:06 -0600624 Version to uprev to is gathered from the QA qualified version tracking file
625 stored in chromium/src/chrome/LACROS_QA_QUALIFIED_VERSION. Uprev is triggered
626 on modification of this file across all chromium/src branches.
Julio Hurtadof1befec2021-05-05 21:34:26 +0000627
Alex Klein1699fab2022-09-08 08:46:06 -0600628 See: uprev_versioned_package.
629 """
630 result = uprev_lib.UprevVersionedPackageResult()
631 path = os.path.join(
632 constants.CHROMIUMOS_OVERLAY_DIR, "chromeos-base", "chromeos-lacros"
633 )
634 lacros_version = refs[0].revision
635 uprev_result = uprev_lib.uprev_workon_ebuild_to_version(
636 path, lacros_version, chroot, allow_downrev=False
637 )
Julio Hurtadoa994e002021-07-07 17:57:45 +0000638
Alex Klein1699fab2022-09-08 08:46:06 -0600639 if not uprev_result:
640 return result
641
642 result.add_result(lacros_version, uprev_result.changed_files)
Julio Hurtadoa994e002021-07-07 17:57:45 +0000643 return result
644
Julio Hurtadof1befec2021-05-05 21:34:26 +0000645
Alex Klein1699fab2022-09-08 08:46:06 -0600646@uprevs_versioned_package("chromeos-base/chromeos-lacros-parallel")
Julio Hurtado870ed322021-12-03 18:22:40 +0000647def uprev_lacros_in_parallel(
Alex Klein1699fab2022-09-08 08:46:06 -0600648 _build_targets: Optional[List["build_target_lib.BuildTarget"]],
Julio Hurtado870ed322021-12-03 18:22:40 +0000649 refs: List[uprev_lib.GitRef],
Alex Klein1699fab2022-09-08 08:46:06 -0600650 chroot: "chroot_lib.Chroot",
651) -> "uprev_lib.UprevVersionedPackageResult":
652 """Updates lacros ebuilds in parallel with ash-chrome.
Julio Hurtado870ed322021-12-03 18:22:40 +0000653
Alex Klein1699fab2022-09-08 08:46:06 -0600654 This handler is going to be used temporarily while lacros transitions to being
655 uprevved atomically with ash-chrome. Unlike a standalone lacros uprev, this
656 handler will not need to look at the QA qualified file. Rather, it will
657 function identical to ash-chrome using git tags.
Julio Hurtado870ed322021-12-03 18:22:40 +0000658
Alex Klein1699fab2022-09-08 08:46:06 -0600659 See: uprev_versioned_package.
Julio Hurtado870ed322021-12-03 18:22:40 +0000660
Alex Klein1699fab2022-09-08 08:46:06 -0600661 Returns:
662 UprevVersionedPackageResult: The result.
663 """
664 result = uprev_lib.UprevVersionedPackageResult()
665 path = os.path.join(
666 constants.CHROMIUMOS_OVERLAY_DIR, "chromeos-base", "chromeos-lacros"
667 )
668 lacros_version = uprev_lib.get_version_from_refs(refs)
669 uprev_result = uprev_lib.uprev_workon_ebuild_to_version(
670 path, lacros_version, chroot, allow_downrev=False
671 )
Julio Hurtado870ed322021-12-03 18:22:40 +0000672
Alex Klein1699fab2022-09-08 08:46:06 -0600673 if not uprev_result:
674 return result
675
676 result.add_result(lacros_version, uprev_result.changed_files)
Julio Hurtado870ed322021-12-03 18:22:40 +0000677 return result
678
Julio Hurtado870ed322021-12-03 18:22:40 +0000679
Alex Klein1699fab2022-09-08 08:46:06 -0600680@uprevs_versioned_package("app-emulation/parallels-desktop")
Patrick Meiring5897add2020-09-16 16:30:17 +1000681def uprev_parallels_desktop(_build_targets, _refs, chroot):
Alex Klein1699fab2022-09-08 08:46:06 -0600682 """Updates Parallels Desktop ebuild - app-emulation/parallels-desktop.
Patrick Meiring5897add2020-09-16 16:30:17 +1000683
Alex Klein1699fab2022-09-08 08:46:06 -0600684 See: uprev_versioned_package
Patrick Meiring5897add2020-09-16 16:30:17 +1000685
Alex Klein1699fab2022-09-08 08:46:06 -0600686 Returns:
687 UprevVersionedPackageResult: The result.
688 """
689 package = "parallels-desktop"
690 package_path = os.path.join(
691 constants.CHROMEOS_PARTNER_OVERLAY_DIR, "app-emulation", package
692 )
693 version_pin_src_path = _get_version_pin_src_path(package_path)
Patrick Meiring5897add2020-09-16 16:30:17 +1000694
Alex Klein1699fab2022-09-08 08:46:06 -0600695 # Expect a JSON blob like the following:
696 # {
697 # "version": "1.2.3",
698 # "test_image": { "url": "...", "size": 12345678,
699 # "sha256sum": "<32 bytes of hexadecimal>" }
700 # }
701 with open(version_pin_src_path, "r") as f:
702 pinned = json.load(f)
Patrick Meiring5897add2020-09-16 16:30:17 +1000703
Alex Klein1699fab2022-09-08 08:46:06 -0600704 if "version" not in pinned or "test_image" not in pinned:
705 raise UprevError(
706 "VERSION-PIN for %s missing version and/or "
707 "test_image field" % package
708 )
Patrick Meiring5897add2020-09-16 16:30:17 +1000709
Alex Klein1699fab2022-09-08 08:46:06 -0600710 version = pinned["version"]
711 if not isinstance(version, str):
712 raise UprevError("version in VERSION-PIN for %s not a string" % package)
Patrick Meiring5897add2020-09-16 16:30:17 +1000713
Alex Klein1699fab2022-09-08 08:46:06 -0600714 # Update the ebuild.
715 result = uprev_lib.uprev_ebuild_from_pin(package_path, version, chroot)
Patrick Meiring5897add2020-09-16 16:30:17 +1000716
Alex Klein1699fab2022-09-08 08:46:06 -0600717 # Update the VM image used for testing.
718 test_image_path = (
719 "src/platform/tast-tests-private/src/chromiumos/tast/"
720 "local/bundles/crosint/pita/data/"
721 "pluginvm_image.zip.external"
722 )
723 test_image_src_path = os.path.join(constants.SOURCE_ROOT, test_image_path)
724 with open(test_image_src_path, "w") as f:
725 json.dump(pinned["test_image"], f, indent=2)
726 result.add_result(version, [test_image_src_path])
Patrick Meiring5897add2020-09-16 16:30:17 +1000727
Alex Klein1699fab2022-09-08 08:46:06 -0600728 return result
Trent Beginaf51f1b2020-03-09 17:35:31 -0600729
730
Alex Klein1699fab2022-09-08 08:46:06 -0600731@uprevs_versioned_package("chromeos-base/chromeos-dtc-vm")
Trent Beginaf51f1b2020-03-09 17:35:31 -0600732def uprev_sludge(_build_targets, _refs, chroot):
Alex Klein1699fab2022-09-08 08:46:06 -0600733 """Updates sludge VM - chromeos-base/chromeos-dtc-vm.
Trent Begin315d9d92019-12-03 21:55:53 -0700734
Alex Klein1699fab2022-09-08 08:46:06 -0600735 See: uprev_versioned_package.
736 """
737 package = "chromeos-dtc-vm"
738 package_path = os.path.join(
739 "src",
740 "private-overlays",
741 "project-wilco-private",
742 "chromeos-base",
743 package,
744 )
745 version_pin_src_path = _get_version_pin_src_path(package_path)
746 version_no_rev = osutils.ReadFile(version_pin_src_path).strip()
Trent Begin315d9d92019-12-03 21:55:53 -0700747
Alex Klein1699fab2022-09-08 08:46:06 -0600748 return uprev_lib.uprev_ebuild_from_pin(package_path, version_no_rev, chroot)
Trent Begin315d9d92019-12-03 21:55:53 -0700749
750
Alex Klein1699fab2022-09-08 08:46:06 -0600751@uprevs_versioned_package("chromeos-base/borealis-dlc")
David Riley8513c1f2021-10-14 17:07:41 -0700752def uprev_borealis_dlc(_build_targets, _refs, chroot):
Alex Klein1699fab2022-09-08 08:46:06 -0600753 """Updates shared borealis-dlc ebuild - chromeos-base/borealis-dlc.
David Riley8513c1f2021-10-14 17:07:41 -0700754
Alex Klein1699fab2022-09-08 08:46:06 -0600755 See: uprev_versioned_package.
756 """
757 package_path = os.path.join(
758 "src",
759 "private-overlays",
760 "chromeos-partner-overlay",
761 "chromeos-base",
762 "borealis-dlc",
763 )
David Riley8513c1f2021-10-14 17:07:41 -0700764
Alex Klein1699fab2022-09-08 08:46:06 -0600765 version_pin_src_path = _get_version_pin_src_path(package_path)
766 version_no_rev = osutils.ReadFile(version_pin_src_path).strip()
David Riley8513c1f2021-10-14 17:07:41 -0700767
Alex Klein1699fab2022-09-08 08:46:06 -0600768 return uprev_lib.uprev_ebuild_from_pin(package_path, version_no_rev, chroot)
David Riley8513c1f2021-10-14 17:07:41 -0700769
770
Patrick Meiring5897add2020-09-16 16:30:17 +1000771def _get_version_pin_src_path(package_path):
Alex Klein1699fab2022-09-08 08:46:06 -0600772 """Returns the path to the VERSION-PIN file for the given package."""
773 return os.path.join(constants.SOURCE_ROOT, package_path, "VERSION-PIN")
Patrick Meiring5897add2020-09-16 16:30:17 +1000774
775
Alex Klein87531182019-08-12 15:23:37 -0600776@uprevs_versioned_package(constants.CHROME_CP)
Alex Klein4e839252022-01-06 13:29:18 -0700777def uprev_chrome_from_ref(build_targets, refs, _chroot):
Alex Klein1699fab2022-09-08 08:46:06 -0600778 """Uprev chrome and its related packages.
Alex Klein87531182019-08-12 15:23:37 -0600779
Alex Klein1699fab2022-09-08 08:46:06 -0600780 See: uprev_versioned_package.
781 """
782 # Determine the version from the refs (tags), i.e. the chrome versions are the
783 # tag names.
784 chrome_version = uprev_lib.get_version_from_refs(refs)
785 logging.debug("Chrome version determined from refs: %s", chrome_version)
Alex Klein87531182019-08-12 15:23:37 -0600786
Alex Klein1699fab2022-09-08 08:46:06 -0600787 return uprev_chrome(chrome_version, build_targets, None)
Alex Kleinf69bd802021-06-22 15:43:49 -0600788
789
Alex Klein9ce3f682021-06-23 15:06:44 -0600790def revbump_chrome(
Alex Klein1699fab2022-09-08 08:46:06 -0600791 build_targets: List["build_target_lib.BuildTarget"] = None,
792 chroot: Optional["chroot_lib.Chroot"] = None,
Alex Klein9ce3f682021-06-23 15:06:44 -0600793) -> uprev_lib.UprevVersionedPackageResult:
Alex Klein1699fab2022-09-08 08:46:06 -0600794 """Attempt to revbump chrome.
Alex Kleinf69bd802021-06-22 15:43:49 -0600795
Alex Klein1699fab2022-09-08 08:46:06 -0600796 Revbumps are done by executing an uprev using the current stable version.
797 E.g. if chrome is on 1.2.3.4 and has a 1.2.3.4_rc-r2.ebuild, performing an
798 uprev on version 1.2.3.4 when there are applicable changes (e.g. to the 9999
799 ebuild) will result in a revbump to 1.2.3.4_rc-r3.ebuild.
800 """
801 chrome_version = uprev_lib.get_stable_chrome_version()
802 return uprev_chrome(chrome_version, build_targets, chroot)
Alex Kleinf69bd802021-06-22 15:43:49 -0600803
804
Alex Klein9ce3f682021-06-23 15:06:44 -0600805def uprev_chrome(
Alex Klein16ea1b32021-10-01 15:48:50 -0600806 chrome_version: str,
Alex Klein1699fab2022-09-08 08:46:06 -0600807 build_targets: Optional[List["build_target_lib.BuildTarget"]],
808 chroot: Optional["chroot_lib.Chroot"],
Alex Klein9ce3f682021-06-23 15:06:44 -0600809) -> uprev_lib.UprevVersionedPackageResult:
Alex Klein1699fab2022-09-08 08:46:06 -0600810 """Attempt to uprev chrome and its related packages to the given version."""
811 uprev_manager = uprev_lib.UprevChromeManager(
812 chrome_version, build_targets=build_targets, chroot=chroot
813 )
814 result = uprev_lib.UprevVersionedPackageResult()
815 # TODO(crbug.com/1080429): Handle all possible outcomes of a Chrome uprev
816 # attempt. The expected behavior is documented in the following table:
817 #
818 # Outcome of Chrome uprev attempt:
819 # NEWER_VERSION_EXISTS:
820 # Do nothing.
821 # SAME_VERSION_EXISTS or REVISION_BUMP:
822 # Uprev followers
823 # Assert not VERSION_BUMP (any other outcome is fine)
824 # VERSION_BUMP or NEW_EBUILD_CREATED:
825 # Uprev followers
826 # Assert that Chrome & followers are at same package version
Alex Klein0b2ec2d2021-06-23 15:56:45 -0600827
Alex Klein1699fab2022-09-08 08:46:06 -0600828 # Start with chrome itself so we can proceed accordingly.
829 chrome_result = uprev_manager.uprev(constants.CHROME_CP)
830 if chrome_result.newer_version_exists:
831 # Cannot use the given version (newer version already exists).
832 return result
833
834 # Also uprev related packages.
835 for package in constants.OTHER_CHROME_PACKAGES:
836 follower_result = uprev_manager.uprev(package)
837 if chrome_result.stable_version and follower_result.version_bump:
838 logging.warning(
839 "%s had a version bump, but no more than a revision bump "
840 "should have been possible.",
841 package,
842 )
843
844 if uprev_manager.modified_ebuilds:
845 # Record changes when we have them.
846 return result.add_result(chrome_version, uprev_manager.modified_ebuilds)
847
David Burger37f48672019-09-18 17:07:56 -0600848 return result
Alex Klein87531182019-08-12 15:23:37 -0600849
Alex Klein87531182019-08-12 15:23:37 -0600850
Alex Klein1699fab2022-09-08 08:46:06 -0600851def _get_latest_version_from_refs(
852 refs_prefix: str, refs: List[uprev_lib.GitRef]
853) -> str:
854 """Get the latest version from refs
Alex Klein0b2ec2d2021-06-23 15:56:45 -0600855
Alex Klein1699fab2022-09-08 08:46:06 -0600856 Versions are compared using |distutils.version.LooseVersion| and
857 the latest version is returned.
Alex Klein87531182019-08-12 15:23:37 -0600858
Alex Klein1699fab2022-09-08 08:46:06 -0600859 Args:
860 refs_prefix: The refs prefix of the tag format.
Chinglin Yu84818732022-10-03 12:03:43 +0800861 refs: The tags to parse for the latest version.
Alex Klein87531182019-08-12 15:23:37 -0600862
Alex Klein1699fab2022-09-08 08:46:06 -0600863 Returns:
Chinglin Yu84818732022-10-03 12:03:43 +0800864 The latest version to use as string.
Alex Klein1699fab2022-09-08 08:46:06 -0600865 """
866 valid_refs = []
867 for gitiles in refs:
868 if gitiles.ref.startswith(refs_prefix):
869 valid_refs.append(gitiles.ref)
Ben Reiche779cf42020-12-15 03:21:31 +0000870
Alex Klein1699fab2022-09-08 08:46:06 -0600871 if not valid_refs:
872 return None
Ben Reiche779cf42020-12-15 03:21:31 +0000873
Alex Klein1699fab2022-09-08 08:46:06 -0600874 # Sort by version and take the latest version.
875 target_version_ref = sorted(valid_refs, key=LooseVersion, reverse=True)[0]
876 return target_version_ref.replace(refs_prefix, "")
Harvey Yang9c61e9c2021-03-02 16:32:43 +0800877
878
Matthias Kaehlckebf7d1772021-11-04 16:01:36 -0700879def _generate_platform_c_files(
880 replication_config: replication_config_pb2.ReplicationConfig,
Alex Klein1699fab2022-09-08 08:46:06 -0600881 chroot: "chroot_lib.Chroot",
882) -> List[str]:
883 """Generates platform C files from a platform JSON payload.
Andrew Lamb9563a152019-12-04 11:42:18 -0700884
Alex Klein1699fab2022-09-08 08:46:06 -0600885 Args:
886 replication_config: A ReplicationConfig that has already been run. If it
887 produced a build_config.json file, that file will be used to generate
888 platform C files. Otherwise, nothing will be generated.
889 chroot: The chroot to use to generate.
Andrew Lamb9563a152019-12-04 11:42:18 -0700890
Alex Klein1699fab2022-09-08 08:46:06 -0600891 Returns:
892 A list of generated files.
893 """
894 # Generate the platform C files from the build config. Note that it would be
895 # more intuitive to generate the platform C files from the platform config;
896 # however, cros_config_schema does not allow this, because the platform config
897 # payload is not always valid input. For example, if a property is both
898 # 'required' and 'build-only', it will fail schema validation. Thus, use the
899 # build config, and use '-f' to filter.
900 build_config_path = [
901 rule.destination_path
902 for rule in replication_config.file_replication_rules
903 if rule.destination_path.endswith("build_config.json")
904 ]
Andrew Lamb9563a152019-12-04 11:42:18 -0700905
Alex Klein1699fab2022-09-08 08:46:06 -0600906 if not build_config_path:
907 logging.info(
908 "No build_config.json found, will not generate platform C files. "
909 "Replication config: %s",
910 replication_config,
911 )
912 return []
Andrew Lamb9563a152019-12-04 11:42:18 -0700913
Alex Klein1699fab2022-09-08 08:46:06 -0600914 if len(build_config_path) > 1:
915 raise ValueError(
916 "Expected at most one build_config.json destination path. "
917 "Replication config: %s" % replication_config
918 )
Andrew Lamb9563a152019-12-04 11:42:18 -0700919
Alex Klein1699fab2022-09-08 08:46:06 -0600920 build_config_path = build_config_path[0]
Andrew Lamb9563a152019-12-04 11:42:18 -0700921
Alex Klein1699fab2022-09-08 08:46:06 -0600922 # Paths to the build_config.json and dir to output C files to, in the
923 # chroot.
924 build_config_chroot_path = os.path.join(
925 constants.CHROOT_SOURCE_ROOT, build_config_path
926 )
927 generated_output_chroot_dir = os.path.join(
928 constants.CHROOT_SOURCE_ROOT, os.path.dirname(build_config_path)
929 )
Andrew Lamb9563a152019-12-04 11:42:18 -0700930
Alex Klein1699fab2022-09-08 08:46:06 -0600931 command = [
932 "cros_config_schema",
933 "-m",
934 build_config_chroot_path,
935 "-g",
936 generated_output_chroot_dir,
937 "-f",
938 '"TRUE"',
939 ]
Andrew Lamb9563a152019-12-04 11:42:18 -0700940
Alex Klein1699fab2022-09-08 08:46:06 -0600941 cros_build_lib.run(
942 command, enter_chroot=True, chroot_args=chroot.get_enter_args()
943 )
Andrew Lamb9563a152019-12-04 11:42:18 -0700944
Alex Klein1699fab2022-09-08 08:46:06 -0600945 # A relative (to the source root) path to the generated C files.
946 generated_output_dir = os.path.dirname(build_config_path)
947 generated_files = []
948 expected_c_files = ["config.c", "ec_config.c", "ec_config.h"]
949 for f in expected_c_files:
950 if os.path.exists(
951 os.path.join(constants.SOURCE_ROOT, generated_output_dir, f)
952 ):
953 generated_files.append(os.path.join(generated_output_dir, f))
Andrew Lamb9563a152019-12-04 11:42:18 -0700954
Alex Klein1699fab2022-09-08 08:46:06 -0600955 if len(expected_c_files) != len(generated_files):
956 raise GeneratedCrosConfigFilesError(expected_c_files, generated_files)
Andrew Lamb9563a152019-12-04 11:42:18 -0700957
Alex Klein1699fab2022-09-08 08:46:06 -0600958 return generated_files
Andrew Lamb9563a152019-12-04 11:42:18 -0700959
960
Matthias Kaehlckebf7d1772021-11-04 16:01:36 -0700961def _get_private_overlay_package_root(ref: uprev_lib.GitRef, package: str):
Alex Klein1699fab2022-09-08 08:46:06 -0600962 """Returns the absolute path to the root of a given private overlay.
Andrew Lambe836f222019-12-09 12:27:38 -0700963
Alex Klein1699fab2022-09-08 08:46:06 -0600964 Args:
965 ref: GitRef for the private overlay.
966 package: Path to the package in the overlay.
967 """
968 # There might be a cleaner way to map from package -> path within the source
969 # tree. For now, just use string patterns.
970 private_overlay_ref_pattern = (
971 r"/chromeos\/overlays\/overlay-([\w-]+)-private"
972 )
973 match = re.match(private_overlay_ref_pattern, ref.path)
974 if not match:
975 raise ValueError(
976 "ref.path must match the pattern: %s. Actual ref: %s"
977 % (private_overlay_ref_pattern, ref)
978 )
Andrew Lambe836f222019-12-09 12:27:38 -0700979
Alex Klein1699fab2022-09-08 08:46:06 -0600980 overlay = match.group(1)
Andrew Lambe836f222019-12-09 12:27:38 -0700981
Alex Klein1699fab2022-09-08 08:46:06 -0600982 return os.path.join(
983 constants.SOURCE_ROOT,
984 "src/private-overlays/overlay-%s-private" % overlay,
985 package,
986 )
Andrew Lambe836f222019-12-09 12:27:38 -0700987
988
Alex Klein1699fab2022-09-08 08:46:06 -0600989@uprevs_versioned_package("chromeos-base/chromeos-config-bsp")
Andrew Lambea9a8a22019-12-12 14:03:43 -0700990def replicate_private_config(_build_targets, refs, chroot):
Alex Klein1699fab2022-09-08 08:46:06 -0600991 """Replicate a private cros_config change to the corresponding public config.
Andrew Lamb2bde9e42019-11-04 13:24:09 -0700992
Alex Klein1699fab2022-09-08 08:46:06 -0600993 See uprev_versioned_package for args
994 """
995 package = "chromeos-base/chromeos-config-bsp"
Andrew Lambea9a8a22019-12-12 14:03:43 -0700996
Alex Klein1699fab2022-09-08 08:46:06 -0600997 if len(refs) != 1:
998 raise ValueError("Expected exactly one ref, actual %s" % refs)
Andrew Lamb2bde9e42019-11-04 13:24:09 -0700999
Alex Klein1699fab2022-09-08 08:46:06 -06001000 # Expect a replication_config.jsonpb in the package root.
1001 package_root = _get_private_overlay_package_root(refs[0], package)
1002 replication_config_path = os.path.join(
1003 package_root, "replication_config.jsonpb"
1004 )
Andrew Lamb2bde9e42019-11-04 13:24:09 -07001005
Alex Klein1699fab2022-09-08 08:46:06 -06001006 try:
1007 replication_config = json_format.Parse(
1008 osutils.ReadFile(replication_config_path),
1009 replication_config_pb2.ReplicationConfig(),
1010 )
1011 except IOError:
1012 raise ValueError(
1013 "Expected ReplicationConfig missing at %s" % replication_config_path
1014 )
Andrew Lamb2bde9e42019-11-04 13:24:09 -07001015
Alex Klein1699fab2022-09-08 08:46:06 -06001016 replication_lib.Replicate(replication_config)
Andrew Lamb2bde9e42019-11-04 13:24:09 -07001017
Alex Klein1699fab2022-09-08 08:46:06 -06001018 modified_files = [
1019 rule.destination_path
1020 for rule in replication_config.file_replication_rules
1021 ]
Andrew Lamb2bde9e42019-11-04 13:24:09 -07001022
Alex Klein1699fab2022-09-08 08:46:06 -06001023 # The generated platform C files are not easily filtered by replication rules,
1024 # i.e. JSON / proto filtering can be described by a FieldMask, arbitrary C
1025 # files cannot. Therefore, replicate and filter the JSON payloads, and then
1026 # generate filtered C files from the JSON payload.
1027 modified_files.extend(
1028 _generate_platform_c_files(replication_config, chroot)
1029 )
Andrew Lamb2bde9e42019-11-04 13:24:09 -07001030
Alex Klein1699fab2022-09-08 08:46:06 -06001031 # Use the private repo's commit hash as the new version.
1032 new_private_version = refs[0].revision
Andrew Lamb2bde9e42019-11-04 13:24:09 -07001033
Alex Klein1699fab2022-09-08 08:46:06 -06001034 # modified_files should contain only relative paths at this point, but the
1035 # returned UprevVersionedPackageResult must contain only absolute paths.
1036 for i, modified_file in enumerate(modified_files):
1037 assert not os.path.isabs(modified_file)
1038 modified_files[i] = os.path.join(constants.SOURCE_ROOT, modified_file)
Andrew Lamb988f4da2019-12-10 10:16:43 -07001039
Alex Klein1699fab2022-09-08 08:46:06 -06001040 return uprev_lib.UprevVersionedPackageResult().add_result(
1041 new_private_version, modified_files
1042 )
Andrew Lamb2bde9e42019-11-04 13:24:09 -07001043
1044
Alex Klein1699fab2022-09-08 08:46:06 -06001045@uprevs_versioned_package("chromeos-base/crosvm")
Dennis Kempinef05f2b2021-09-08 16:36:49 -07001046def uprev_crosvm(_build_targets, refs, _chroot):
Alex Klein1699fab2022-09-08 08:46:06 -06001047 """Updates crosvm ebuilds to latest revision
Dennis Kempinef05f2b2021-09-08 16:36:49 -07001048
Alex Klein1699fab2022-09-08 08:46:06 -06001049 crosvm is not versioned. We are updating to the latest commit on the main
1050 branch.
Dennis Kempinef05f2b2021-09-08 16:36:49 -07001051
Alex Klein1699fab2022-09-08 08:46:06 -06001052 See: uprev_versioned_package.
Dennis Kempinef05f2b2021-09-08 16:36:49 -07001053
Alex Klein1699fab2022-09-08 08:46:06 -06001054 Returns:
1055 UprevVersionedPackageResult: The result of updating crosvm ebuilds.
1056 """
1057 overlay = os.path.join(
1058 constants.SOURCE_ROOT, constants.CHROMIUMOS_OVERLAY_DIR
1059 )
1060 repo_path = os.path.join(constants.SOURCE_ROOT, "src", "crosvm")
1061 manifest = git.ManifestCheckout.Cached(repo_path)
Dennis Kempinef05f2b2021-09-08 16:36:49 -07001062
Alex Klein1699fab2022-09-08 08:46:06 -06001063 uprev_manager = uprev_lib.UprevOverlayManager([overlay], manifest)
1064 uprev_manager.uprev(
1065 package_list=[
1066 "chromeos-base/crosvm",
1067 "dev-rust/assertions",
1068 "dev-rust/cros_async",
1069 "dev-rust/cros_fuzz",
1070 "dev-rust/data_model",
1071 "dev-rust/enumn",
1072 "dev-rust/io_uring",
1073 "dev-rust/p9",
1074 "dev-rust/sync",
1075 "dev-rust/sys_util",
1076 "dev-rust/tempfile",
1077 "media-sound/audio_streams",
1078 ],
1079 force=True,
1080 )
Dennis Kempinef05f2b2021-09-08 16:36:49 -07001081
Alex Klein1699fab2022-09-08 08:46:06 -06001082 updated_files = uprev_manager.modified_ebuilds
1083 result = uprev_lib.UprevVersionedPackageResult()
1084 result.add_result(refs[0].revision, updated_files)
1085 return result
Dennis Kempinef05f2b2021-09-08 16:36:49 -07001086
1087
Alex Klein5caab872021-09-10 11:44:37 -06001088def get_best_visible(
Alex Klein1699fab2022-09-08 08:46:06 -06001089 atom: str, build_target: Optional["build_target_lib.BuildTarget"] = None
Alex Klein5caab872021-09-10 11:44:37 -06001090) -> package_info.PackageInfo:
Alex Klein1699fab2022-09-08 08:46:06 -06001091 """Returns the best visible CPV for the given atom.
Alex Kleinbbef2b32019-08-27 10:38:50 -06001092
Alex Klein1699fab2022-09-08 08:46:06 -06001093 Args:
1094 atom: The atom to look up.
1095 build_target: The build target whose sysroot should be searched, or the SDK
1096 if not provided.
Alex Kleinad6b48a2020-01-08 16:57:41 -07001097
Alex Klein1699fab2022-09-08 08:46:06 -06001098 Returns:
1099 The best visible package, or None if none are visible.
1100 """
1101 assert atom
Alex Kleinbbef2b32019-08-27 10:38:50 -06001102
Alex Klein1699fab2022-09-08 08:46:06 -06001103 return portage_util.PortageqBestVisible(
1104 atom,
1105 board=build_target.name if build_target else None,
1106 sysroot=build_target.root if build_target else None,
1107 )
Alex Kleinda39c6d2019-09-16 14:36:36 -06001108
1109
Matthias Kaehlckebf7d1772021-11-04 16:01:36 -07001110def has_prebuilt(
1111 atom: str,
Alex Klein1699fab2022-09-08 08:46:06 -06001112 build_target: "build_target_lib.BuildTarget" = None,
1113 useflags: Union[Iterable[str], str] = None,
1114) -> bool:
1115 """Check if a prebuilt exists.
Alex Kleinda39c6d2019-09-16 14:36:36 -06001116
Alex Klein1699fab2022-09-08 08:46:06 -06001117 Args:
1118 atom: The package whose prebuilt is being queried.
1119 build_target: The build target whose sysroot should be searched, or the
1120 SDK if not provided.
1121 useflags: Any additional USE flags that should be set. May be a string
1122 of properly formatted USE flags, or an iterable of individual flags.
Alex Kleinad6b48a2020-01-08 16:57:41 -07001123
Alex Klein1699fab2022-09-08 08:46:06 -06001124 Returns:
1125 True if there is an available prebuilt, False otherwise.
1126 """
1127 assert atom
Alex Kleinda39c6d2019-09-16 14:36:36 -06001128
Alex Klein1699fab2022-09-08 08:46:06 -06001129 board = build_target.name if build_target else None
1130 extra_env = None
1131 if useflags:
1132 new_flags = useflags
1133 if not isinstance(useflags, str):
1134 new_flags = " ".join(useflags)
Alex Klein149fd3b2019-12-16 16:01:05 -07001135
Alex Klein1699fab2022-09-08 08:46:06 -06001136 existing = os.environ.get("USE", "")
1137 final_flags = "%s %s" % (existing, new_flags)
1138 extra_env = {"USE": final_flags.strip()}
1139 return portage_util.HasPrebuilt(atom, board=board, extra_env=extra_env)
Alex Klein36b117f2019-09-30 15:13:46 -06001140
1141
David Burger0f9dd4e2019-10-08 12:33:42 -06001142def builds(atom, build_target, packages=None):
Alex Klein1699fab2022-09-08 08:46:06 -06001143 """Check if |build_target| builds |atom| (has it in its depgraph)."""
1144 cros_build_lib.AssertInsideChroot()
Alex Klein36b117f2019-09-30 15:13:46 -06001145
Alex Klein1699fab2022-09-08 08:46:06 -06001146 pkgs = tuple(packages) if packages else None
1147 # TODO(crbug/1081828): Receive and use sysroot.
1148 graph, _sdk_graph = dependency.GetBuildDependency(
1149 build_target.root, build_target.name, pkgs
1150 )
1151 return any(atom in package for package in graph["package_deps"])
Michael Mortensenb70e8a82019-10-10 18:43:41 -06001152
1153
Alex Klein6becabc2020-09-11 14:03:05 -06001154def needs_chrome_source(
Alex Klein1699fab2022-09-08 08:46:06 -06001155 build_target: "build_target_lib.BuildTarget",
Alex Klein6becabc2020-09-11 14:03:05 -06001156 compile_source=False,
1157 packages: Optional[List[package_info.PackageInfo]] = None,
Alex Klein1699fab2022-09-08 08:46:06 -06001158 useflags=None,
1159):
1160 """Check if the chrome source is needed.
Alex Klein6becabc2020-09-11 14:03:05 -06001161
Alex Klein1699fab2022-09-08 08:46:06 -06001162 The chrome source is needed if the build target builds chrome or any of its
1163 follower packages, and can't use a prebuilt for them either because it's not
1164 available, or because we can't use prebuilts because it must build from
1165 source.
1166 """
1167 cros_build_lib.AssertInsideChroot()
Alex Klein6becabc2020-09-11 14:03:05 -06001168
Alex Klein1699fab2022-09-08 08:46:06 -06001169 # Check if it builds chrome and/or a follower package.
1170 graph = depgraph.get_sysroot_dependency_graph(build_target.root, packages)
1171 builds_chrome = constants.CHROME_CP in graph
1172 builds_follower = {
1173 pkg: pkg in graph for pkg in constants.OTHER_CHROME_PACKAGES
1174 }
Alex Klein6becabc2020-09-11 14:03:05 -06001175
Alex Klein1699fab2022-09-08 08:46:06 -06001176 local_uprev = builds_chrome and revbump_chrome([build_target])
Alex Klein9ce3f682021-06-23 15:06:44 -06001177
Alex Klein1699fab2022-09-08 08:46:06 -06001178 # When we are compiling source set False since we do not use prebuilts.
1179 # When not compiling from source, start with True, i.e. we have every prebuilt
1180 # we've checked for up to this point.
1181 has_chrome_prebuilt = not compile_source
1182 has_follower_prebuilts = not compile_source
1183 # Save packages that need prebuilts for reporting.
1184 pkgs_needing_prebuilts = []
1185 if compile_source:
1186 # Need everything.
Alex Klein6becabc2020-09-11 14:03:05 -06001187 pkgs_needing_prebuilts.append(constants.CHROME_CP)
Alex Klein1699fab2022-09-08 08:46:06 -06001188 pkgs_needing_prebuilts.extend(
1189 [pkg for pkg, builds_pkg in builds_follower.items() if builds_pkg]
1190 )
1191 else:
1192 # Check chrome itself.
1193 if builds_chrome:
1194 has_chrome_prebuilt = has_prebuilt(
1195 constants.CHROME_CP,
1196 build_target=build_target,
1197 useflags=useflags,
1198 )
1199 if not has_chrome_prebuilt:
1200 pkgs_needing_prebuilts.append(constants.CHROME_CP)
1201 # Check follower packages.
1202 for pkg, builds_pkg in builds_follower.items():
1203 if not builds_pkg:
1204 continue
1205 prebuilt = has_prebuilt(
1206 pkg, build_target=build_target, useflags=useflags
1207 )
1208 has_follower_prebuilts &= prebuilt
1209 if not prebuilt:
1210 pkgs_needing_prebuilts.append(pkg)
1211 # Postcondition: has_chrome_prebuilt and has_follower_prebuilts now correctly
1212 # reflect whether we actually have the corresponding prebuilts for the build.
Alex Klein6becabc2020-09-11 14:03:05 -06001213
Alex Klein1699fab2022-09-08 08:46:06 -06001214 needs_chrome = builds_chrome and not has_chrome_prebuilt
1215 needs_follower = (
1216 any(builds_follower.values()) and not has_follower_prebuilts
1217 )
Alex Klein6becabc2020-09-11 14:03:05 -06001218
Alex Klein1699fab2022-09-08 08:46:06 -06001219 return NeedsChromeSourceResult(
1220 needs_chrome_source=needs_chrome or needs_follower,
1221 builds_chrome=builds_chrome,
1222 packages=[package_info.parse(p) for p in pkgs_needing_prebuilts],
1223 missing_chrome_prebuilt=not has_chrome_prebuilt,
1224 missing_follower_prebuilt=not has_follower_prebuilts,
1225 local_uprev=local_uprev,
1226 )
Alex Klein6becabc2020-09-11 14:03:05 -06001227
1228
Alex Klein68a28712021-11-08 11:08:30 -07001229class TargetVersions(NamedTuple):
Alex Klein1699fab2022-09-08 08:46:06 -06001230 """Data class for the info that makes up the "target versions"."""
1231
1232 android_version: str
1233 android_branch: str
1234 android_target: str
1235 chrome_version: str
1236 platform_version: str
1237 milestone_version: str
1238 full_version: str
Alex Klein68a28712021-11-08 11:08:30 -07001239
1240
1241def get_target_versions(
Alex Klein1699fab2022-09-08 08:46:06 -06001242 build_target: "build_target_lib.BuildTarget",
1243 packages: List[package_info.PackageInfo] = None,
Alex Klein68a28712021-11-08 11:08:30 -07001244) -> TargetVersions:
Alex Klein1699fab2022-09-08 08:46:06 -06001245 """Aggregate version info for a few key packages and the OS as a whole."""
1246 # Android version.
1247 android_version = determine_android_version(build_target.name)
1248 logging.info("Found android version: %s", android_version)
1249 # Android branch version.
1250 android_branch = determine_android_branch(build_target.name)
1251 logging.info("Found android branch version: %s", android_branch)
1252 # Android target version.
1253 android_target = determine_android_target(build_target.name)
1254 logging.info("Found android target version: %s", android_target)
Alex Klein68a28712021-11-08 11:08:30 -07001255
Alex Klein1699fab2022-09-08 08:46:06 -06001256 # TODO(crbug/1019770): Investigate cases where builds_chrome is true but
1257 # chrome_version is None.
Alex Klein68a28712021-11-08 11:08:30 -07001258
Alex Klein1699fab2022-09-08 08:46:06 -06001259 builds_chrome = builds(constants.CHROME_CP, build_target, packages=packages)
1260 chrome_version = None
1261 if builds_chrome:
1262 # Chrome version fetch.
1263 chrome_version = determine_chrome_version(build_target)
1264 logging.info("Found chrome version: %s", chrome_version)
Alex Klein68a28712021-11-08 11:08:30 -07001265
Alex Klein1699fab2022-09-08 08:46:06 -06001266 # The ChromeOS version info.
1267 platform_version = determine_platform_version()
1268 milestone_version = determine_milestone_version()
1269 full_version = determine_full_version()
Alex Klein68a28712021-11-08 11:08:30 -07001270
Alex Klein1699fab2022-09-08 08:46:06 -06001271 return TargetVersions(
1272 android_version,
1273 android_branch,
1274 android_target,
1275 chrome_version,
1276 platform_version,
1277 milestone_version,
1278 full_version,
1279 )
Alex Klein68a28712021-11-08 11:08:30 -07001280
1281
Matthias Kaehlckebf7d1772021-11-04 16:01:36 -07001282def determine_chrome_version(
Alex Klein1699fab2022-09-08 08:46:06 -06001283 build_target: "build_target_lib.BuildTarget",
1284) -> Optional[str]:
1285 """Returns the current Chrome version for the board (or in buildroot).
Michael Mortensenc2615b72019-10-15 08:12:24 -06001286
Alex Klein1699fab2022-09-08 08:46:06 -06001287 Args:
1288 build_target: The board build target.
Alex Kleinad6b48a2020-01-08 16:57:41 -07001289
Alex Klein1699fab2022-09-08 08:46:06 -06001290 Returns:
1291 The chrome version if available.
1292 """
1293 # TODO(crbug/1019770): Long term we should not need the try/catch here once
1294 # the builds function above only returns True for chrome when
1295 # determine_chrome_version will succeed.
1296 try:
1297 pkg_info = portage_util.PortageqBestVisible(
1298 constants.CHROME_CP, build_target.name, cwd=constants.SOURCE_ROOT
1299 )
1300 except cros_build_lib.RunCommandError as e:
1301 # Return None because portage failed when trying to determine the chrome
1302 # version.
1303 logging.warning("Caught exception in determine_chrome_package: %s", e)
1304 return None
1305 # Something like 78.0.3877.4_rc -> 78.0.3877.4
1306 return pkg_info.version.partition("_")[0]
Michael Mortensenc2615b72019-10-15 08:12:24 -06001307
1308
Alex Klein68a28712021-11-08 11:08:30 -07001309@functools.lru_cache()
Matthias Kaehlckebf7d1772021-11-04 16:01:36 -07001310def determine_android_package(board: str) -> Optional[str]:
Alex Klein1699fab2022-09-08 08:46:06 -06001311 """Returns the active Android container package in use by the board.
Michael Mortensenb70e8a82019-10-10 18:43:41 -06001312
Alex Klein1699fab2022-09-08 08:46:06 -06001313 Args:
1314 board: The board name this is specific to.
Alex Kleinad6b48a2020-01-08 16:57:41 -07001315
Alex Klein1699fab2022-09-08 08:46:06 -06001316 Returns:
1317 The android package string if there is one.
1318 """
1319 try:
1320 packages = portage_util.GetPackageDependencies(
1321 "virtual/target-os", board=board
1322 )
1323 except cros_build_lib.RunCommandError as e:
1324 # Return None because a command (likely portage) failed when trying to
1325 # determine the package.
1326 logging.warning("Caught exception in determine_android_package: %s", e)
1327 return None
1328
1329 # We assume there is only one Android package in the depgraph.
1330 for package in packages:
1331 if package.startswith(
1332 "chromeos-base/android-container-"
1333 ) or package.startswith("chromeos-base/android-vm-"):
1334 return package
Michael Mortensene0f4b542019-10-24 15:30:23 -06001335 return None
Michael Mortensenb70e8a82019-10-10 18:43:41 -06001336
1337
Matthias Kaehlckebf7d1772021-11-04 16:01:36 -07001338def determine_android_version(board: str, package: str = None):
Alex Klein1699fab2022-09-08 08:46:06 -06001339 """Determine the current Android version in buildroot now and return it.
Michael Mortensenb70e8a82019-10-10 18:43:41 -06001340
Alex Klein1699fab2022-09-08 08:46:06 -06001341 This uses the typical portage logic to determine which version of Android
1342 is active right now in the buildroot.
Michael Mortensenb70e8a82019-10-10 18:43:41 -06001343
Alex Klein1699fab2022-09-08 08:46:06 -06001344 Args:
1345 board: The board name this is specific to.
1346 package: The Android package, if already computed.
Michael Mortensenb70e8a82019-10-10 18:43:41 -06001347
Alex Klein1699fab2022-09-08 08:46:06 -06001348 Returns:
1349 The Android build ID of the container for the board.
Michael Mortensenb70e8a82019-10-10 18:43:41 -06001350
Alex Klein1699fab2022-09-08 08:46:06 -06001351 Raises:
1352 NoAndroidVersionError: if no unique Android version can be determined.
1353 """
1354 if not package:
1355 package = determine_android_package(board)
1356 if not package:
1357 return None
1358 cpv = package_info.SplitCPV(package)
1359 if not cpv:
1360 raise NoAndroidVersionError(
1361 "Android version could not be determined for %s" % board
1362 )
1363 return cpv.version_no_rev
Michael Mortensenb70e8a82019-10-10 18:43:41 -06001364
Alex Klein7a3a7dd2020-01-08 16:44:38 -07001365
Mike Frysinger8e1c99a2021-03-05 00:58:11 -05001366def determine_android_branch(board, package=None):
Alex Klein1699fab2022-09-08 08:46:06 -06001367 """Returns the Android branch in use by the active container ebuild."""
1368 if not package:
1369 package = determine_android_package(board)
1370 if not package:
1371 return None
1372 ebuild_path = portage_util.FindEbuildForBoardPackage(package, board)
1373 # We assume all targets pull from the same branch and that we always
1374 # have at least one of the following targets.
1375 targets = constants.ANDROID_ALL_BUILD_TARGETS
1376 ebuild_content = osutils.SourceEnvironment(ebuild_path, targets)
1377 for target in targets:
1378 if target in ebuild_content:
1379 branch = re.search(r"(.*?)-linux-", ebuild_content[target])
1380 if branch is not None:
1381 return branch.group(1)
1382 raise NoAndroidBranchError(
1383 "Android branch could not be determined for %s (ebuild empty?)" % board
1384 )
Michael Mortensenb70e8a82019-10-10 18:43:41 -06001385
1386
Mike Frysinger8e1c99a2021-03-05 00:58:11 -05001387def determine_android_target(board, package=None):
Alex Klein1699fab2022-09-08 08:46:06 -06001388 """Returns the Android target in use by the active container ebuild."""
1389 if not package:
1390 package = determine_android_package(board)
1391 if not package:
1392 return None
1393 if package.startswith("chromeos-base/android-vm-"):
1394 return "bertha"
1395 elif package.startswith("chromeos-base/android-container-"):
1396 return "cheets"
Michael Mortensenb70e8a82019-10-10 18:43:41 -06001397
Alex Klein1699fab2022-09-08 08:46:06 -06001398 raise NoAndroidTargetError(
1399 "Android Target cannot be determined for the package: %s" % package
1400 )
Michael Mortensen9fdb14b2019-10-17 11:17:30 -06001401
1402
1403def determine_platform_version():
Alex Klein1699fab2022-09-08 08:46:06 -06001404 """Returns the platform version from the source root."""
1405 # Platform version is something like '12575.0.0'.
1406 version = chromeos_version.VersionInfo.from_repo(constants.SOURCE_ROOT)
1407 return version.VersionString()
Michael Mortensen009cb662019-10-21 11:38:43 -06001408
1409
1410def determine_milestone_version():
Alex Klein1699fab2022-09-08 08:46:06 -06001411 """Returns the platform version from the source root."""
1412 # Milestone version is something like '79'.
1413 version = chromeos_version.VersionInfo.from_repo(constants.SOURCE_ROOT)
1414 return version.chrome_branch
Michael Mortensen009cb662019-10-21 11:38:43 -06001415
Alex Klein7a3a7dd2020-01-08 16:44:38 -07001416
Michael Mortensen009cb662019-10-21 11:38:43 -06001417def determine_full_version():
Alex Klein1699fab2022-09-08 08:46:06 -06001418 """Returns the full version from the source root."""
1419 # Full version is something like 'R79-12575.0.0'.
1420 milestone_version = determine_milestone_version()
1421 platform_version = determine_platform_version()
1422 full_version = "R%s-%s" % (milestone_version, platform_version)
1423 return full_version
Michael Mortensen71ef5682020-05-07 14:29:24 -06001424
1425
Matthias Kaehlckebf7d1772021-11-04 16:01:36 -07001426def find_fingerprints(
Alex Klein1699fab2022-09-08 08:46:06 -06001427 build_target: "build_target_lib.BuildTarget",
1428) -> List[str]:
1429 """Returns a list of fingerprints for this build.
Michael Mortensende716a12020-05-15 11:27:00 -06001430
Alex Klein1699fab2022-09-08 08:46:06 -06001431 Args:
1432 build_target: The build target.
Michael Mortensende716a12020-05-15 11:27:00 -06001433
Alex Klein1699fab2022-09-08 08:46:06 -06001434 Returns:
1435 List of fingerprint strings.
1436 """
1437 cros_build_lib.AssertInsideChroot()
1438 fp_file = "cheets-fingerprint.txt"
1439 fp_path = os.path.join(
1440 image_lib.GetLatestImageLink(build_target.name), fp_file
1441 )
1442 if not os.path.isfile(fp_path):
1443 logging.info("Fingerprint file not found: %s", fp_path)
1444 return []
1445 logging.info("Reading fingerprint file: %s", fp_path)
1446 fingerprints = osutils.ReadFile(fp_path).splitlines()
1447 return fingerprints
Michael Mortensende716a12020-05-15 11:27:00 -06001448
1449
Alex Klein1699fab2022-09-08 08:46:06 -06001450def get_all_firmware_versions(build_target: "build_target_lib.BuildTarget"):
1451 """Extract firmware version for all models present.
Michael Mortensen59e30872020-05-18 14:12:49 -06001452
Alex Klein1699fab2022-09-08 08:46:06 -06001453 Args:
1454 build_target: The build target.
Michael Mortensen59e30872020-05-18 14:12:49 -06001455
Alex Klein1699fab2022-09-08 08:46:06 -06001456 Returns:
1457 A dict of FirmwareVersions namedtuple instances by model.
1458 Each element will be populated based on whether it was present in the
1459 command output.
1460 """
1461 cros_build_lib.AssertInsideChroot()
1462 result = {}
1463 # Note that example output for _get_firmware_version_cmd_result is available
1464 # in the packages_unittest.py for testing get_all_firmware_versions.
1465 cmd_result = _get_firmware_version_cmd_result(build_target)
Michael Mortensen59e30872020-05-18 14:12:49 -06001466
Alex Klein1699fab2022-09-08 08:46:06 -06001467 if cmd_result:
1468 # There is a blank line between the version info for each model.
1469 firmware_version_payloads = cmd_result.split("\n\n")
1470 for firmware_version_payload in firmware_version_payloads:
1471 if "BIOS" in firmware_version_payload:
1472 firmware_version = _find_firmware_versions(
1473 firmware_version_payload
1474 )
1475 result[firmware_version.model] = firmware_version
1476 return result
Michael Mortensen59e30872020-05-18 14:12:49 -06001477
1478
Benjamin Shai0858cd32022-01-10 20:23:49 +00001479class FirmwareVersions(NamedTuple):
Alex Klein1699fab2022-09-08 08:46:06 -06001480 """Tuple to hold firmware versions, with truthiness."""
Benjamin Shai0858cd32022-01-10 20:23:49 +00001481
Alex Klein1699fab2022-09-08 08:46:06 -06001482 model: Optional[str]
1483 main: Optional[str]
1484 main_rw: Optional[str]
1485 ec: Optional[str]
1486 ec_rw: Optional[str]
1487
1488 def __bool__(self):
1489 return bool(
1490 self.model or self.main or self.main_rw or self.ec or self.ec_rw
1491 )
Michael Mortensen71ef5682020-05-07 14:29:24 -06001492
1493
Alex Klein1699fab2022-09-08 08:46:06 -06001494def get_firmware_versions(build_target: "build_target_lib.BuildTarget"):
1495 """Extract version information from the firmware updater, if one exists.
Michael Mortensen71ef5682020-05-07 14:29:24 -06001496
Alex Klein1699fab2022-09-08 08:46:06 -06001497 Args:
1498 build_target: The build target.
Michael Mortensen71ef5682020-05-07 14:29:24 -06001499
Alex Klein1699fab2022-09-08 08:46:06 -06001500 Returns:
1501 A FirmwareVersions namedtuple instance.
1502 Each element will either be set to the string output by the firmware
1503 updater shellball, or None if there is no firmware updater.
1504 """
1505 cros_build_lib.AssertInsideChroot()
1506 cmd_result = _get_firmware_version_cmd_result(build_target)
1507 if cmd_result:
1508 return _find_firmware_versions(cmd_result)
1509 else:
1510 return FirmwareVersions(None, None, None, None, None)
Michael Mortensen71ef5682020-05-07 14:29:24 -06001511
1512
Matthias Kaehlckebf7d1772021-11-04 16:01:36 -07001513def _get_firmware_version_cmd_result(
Alex Klein1699fab2022-09-08 08:46:06 -06001514 build_target: "build_target_lib.BuildTarget",
1515) -> Optional[str]:
1516 """Gets the raw result output of the firmware updater version command.
Michael Mortensen71ef5682020-05-07 14:29:24 -06001517
Alex Klein1699fab2022-09-08 08:46:06 -06001518 Args:
1519 build_target: The build target.
Michael Mortensen71ef5682020-05-07 14:29:24 -06001520
Alex Klein1699fab2022-09-08 08:46:06 -06001521 Returns:
1522 Command execution result.
1523 """
1524 updater = os.path.join(
1525 build_target.root, "usr/sbin/chromeos-firmwareupdate"
1526 )
1527 logging.info("Calling updater %s", updater)
1528 # Call the updater using the chroot-based path.
1529 try:
1530 return cros_build_lib.run(
1531 [updater, "-V"],
1532 capture_output=True,
1533 log_output=True,
1534 encoding="utf-8",
1535 ).stdout
1536 except cros_build_lib.RunCommandError:
1537 # Updater probably doesn't exist (e.g. betty).
1538 return None
Michael Mortensen71ef5682020-05-07 14:29:24 -06001539
1540
1541def _find_firmware_versions(cmd_output):
Alex Klein1699fab2022-09-08 08:46:06 -06001542 """Finds firmware version output via regex matches against the cmd_output.
Michael Mortensen71ef5682020-05-07 14:29:24 -06001543
Alex Klein1699fab2022-09-08 08:46:06 -06001544 Args:
1545 cmd_output: The raw output to search against.
Michael Mortensen71ef5682020-05-07 14:29:24 -06001546
Alex Klein1699fab2022-09-08 08:46:06 -06001547 Returns:
1548 FirmwareVersions namedtuple with results.
1549 Each element will either be set to the string output by the firmware
1550 updater shellball, or None if there is no match.
1551 """
Michael Mortensen71ef5682020-05-07 14:29:24 -06001552
Alex Klein1699fab2022-09-08 08:46:06 -06001553 # Sometimes a firmware bundle includes a special combination of RO+RW
1554 # firmware. In this case, the RW firmware version is indicated with a "(RW)
1555 # version" field. In other cases, the "(RW) version" field is not present.
1556 # Therefore, search for the "(RW)" fields first and if they aren't present,
1557 # fallback to the other format. e.g. just "BIOS version:".
1558 # TODO(mmortensen): Use JSON once the firmware updater supports it.
1559 main = None
1560 main_rw = None
1561 ec = None
1562 ec_rw = None
1563 model = None
Michael Mortensen71ef5682020-05-07 14:29:24 -06001564
Alex Klein1699fab2022-09-08 08:46:06 -06001565 match = re.search(r"BIOS version:\s*(?P<version>.*)", cmd_output)
1566 if match:
1567 main = match.group("version")
Michael Mortensen71ef5682020-05-07 14:29:24 -06001568
Alex Klein1699fab2022-09-08 08:46:06 -06001569 match = re.search(r"BIOS \(RW\) version:\s*(?P<version>.*)", cmd_output)
1570 if match:
1571 main_rw = match.group("version")
Michael Mortensen71ef5682020-05-07 14:29:24 -06001572
Alex Klein1699fab2022-09-08 08:46:06 -06001573 match = re.search(r"EC version:\s*(?P<version>.*)", cmd_output)
1574 if match:
1575 ec = match.group("version")
Michael Mortensen71ef5682020-05-07 14:29:24 -06001576
Alex Klein1699fab2022-09-08 08:46:06 -06001577 match = re.search(r"EC \(RW\) version:\s*(?P<version>.*)", cmd_output)
1578 if match:
1579 ec_rw = match.group("version")
Michael Mortensen71ef5682020-05-07 14:29:24 -06001580
Alex Klein1699fab2022-09-08 08:46:06 -06001581 match = re.search(r"Model:\s*(?P<model>.*)", cmd_output)
1582 if match:
1583 model = match.group("model")
Michael Mortensen71ef5682020-05-07 14:29:24 -06001584
Alex Klein1699fab2022-09-08 08:46:06 -06001585 return FirmwareVersions(model, main, main_rw, ec, ec_rw)
Michael Mortensena4af79e2020-05-06 16:18:48 -06001586
1587
Benjamin Shai0858cd32022-01-10 20:23:49 +00001588class MainEcFirmwareVersions(NamedTuple):
Alex Klein1699fab2022-09-08 08:46:06 -06001589 """Tuple to hold main and ec firmware versions, with truthiness."""
Benjamin Shai0858cd32022-01-10 20:23:49 +00001590
Alex Klein1699fab2022-09-08 08:46:06 -06001591 main_fw_version: Optional[str]
1592 ec_fw_version: Optional[str]
1593
1594 def __bool__(self):
1595 return bool(self.main_fw_version or self.ec_fw_version)
Benjamin Shai0858cd32022-01-10 20:23:49 +00001596
Michael Mortensena4af79e2020-05-06 16:18:48 -06001597
Alex Klein1699fab2022-09-08 08:46:06 -06001598def determine_firmware_versions(build_target: "build_target_lib.BuildTarget"):
1599 """Returns a namedtuple with main and ec firmware versions.
Michael Mortensena4af79e2020-05-06 16:18:48 -06001600
Alex Klein1699fab2022-09-08 08:46:06 -06001601 Args:
1602 build_target: The build target.
Michael Mortensena4af79e2020-05-06 16:18:48 -06001603
Alex Klein1699fab2022-09-08 08:46:06 -06001604 Returns:
1605 MainEcFirmwareVersions namedtuple with results.
1606 """
1607 fw_versions = get_firmware_versions(build_target)
1608 main_fw_version = fw_versions.main_rw or fw_versions.main
1609 ec_fw_version = fw_versions.ec_rw or fw_versions.ec
Michael Mortensena4af79e2020-05-06 16:18:48 -06001610
Alex Klein1699fab2022-09-08 08:46:06 -06001611 return MainEcFirmwareVersions(main_fw_version, ec_fw_version)
Michael Mortensenfbf2b2d2020-05-14 16:33:06 -06001612
Benjamin Shai0858cd32022-01-10 20:23:49 +00001613
Matthias Kaehlckebf7d1772021-11-04 16:01:36 -07001614def determine_kernel_version(
Alex Klein1699fab2022-09-08 08:46:06 -06001615 build_target: "build_target_lib.BuildTarget",
Lizzy Presland0b978e62022-09-09 16:55:29 +00001616) -> str:
Alex Klein1699fab2022-09-08 08:46:06 -06001617 """Returns a string containing the kernel version for this build target.
Michael Mortensenfbf2b2d2020-05-14 16:33:06 -06001618
Alex Klein1699fab2022-09-08 08:46:06 -06001619 Args:
1620 build_target: The build target.
Michael Mortensenfbf2b2d2020-05-14 16:33:06 -06001621
Alex Klein1699fab2022-09-08 08:46:06 -06001622 Returns:
Lizzy Presland0b978e62022-09-09 16:55:29 +00001623 The kernel versions, or empty string.
Alex Klein1699fab2022-09-08 08:46:06 -06001624 """
Lizzy Presland0b978e62022-09-09 16:55:29 +00001625 target_virtual_pkg = "virtual/linux-sources"
Alex Klein1699fab2022-09-08 08:46:06 -06001626 try:
Lizzy Presland0b978e62022-09-09 16:55:29 +00001627 candidate_packages = portage_util.GetFlattenedDepsForPackage(
1628 target_virtual_pkg,
1629 sysroot=build_target.root,
1630 board=build_target.name,
1631 depth=1,
1632 )
1633 installed_packages = portage_util.GetPackageDependencies(
1634 target_virtual_pkg, board=build_target.name
Alex Klein1699fab2022-09-08 08:46:06 -06001635 )
1636 except cros_build_lib.RunCommandError as e:
1637 logging.warning("Unable to get package list for metadata: %s", e)
Lizzy Presland0b978e62022-09-09 16:55:29 +00001638 return ""
1639 if not candidate_packages:
1640 raise KernelVersionError("No package found in FlattenedDepsForPackage")
1641 if not installed_packages:
1642 raise KernelVersionError("No package found in GetPackageDependencies")
1643 packages = [
1644 p
1645 for p in installed_packages
1646 if p in candidate_packages and target_virtual_pkg not in p
1647 ]
1648 if len(packages) == 0:
1649 raise KernelVersionError(
1650 "No matches for installed packages were found in candidate "
1651 "packages. Did GetFlattenedDepsForPackage search all possible "
1652 "package versions?\tInstalled: %s\tCandidates: %s"
1653 % (" ".join(installed_packages), " ".join(candidate_packages))
1654 )
1655 if len(packages) > 1:
1656 raise KernelVersionError(
1657 "Too many packages found in intersection of installed packages and "
1658 "possible kernel versions (%s)" % "".join(packages)
1659 )
1660 kernel_version = package_info.SplitCPV(packages[0]).version
1661 logging.info("Found active kernel version: %s", kernel_version)
1662 return kernel_version
Michael Mortensen125bb012020-05-21 14:02:10 -06001663
1664
Matthias Kaehlckebf7d1772021-11-04 16:01:36 -07001665def get_models(
Alex Klein1699fab2022-09-08 08:46:06 -06001666 build_target: "build_target_lib.BuildTarget", log_output: bool = True
1667) -> Optional[List[str]]:
1668 """Obtain a list of models supported by a unified board.
Michael Mortensen125bb012020-05-21 14:02:10 -06001669
Alex Klein1699fab2022-09-08 08:46:06 -06001670 This ignored whitelabel models since GoldenEye has no specific support for
1671 these at present.
Michael Mortensen125bb012020-05-21 14:02:10 -06001672
Alex Klein1699fab2022-09-08 08:46:06 -06001673 Args:
1674 build_target: The build target.
1675 log_output: Whether to log the output of the cros_config_host invocation.
Michael Mortensen125bb012020-05-21 14:02:10 -06001676
Alex Klein1699fab2022-09-08 08:46:06 -06001677 Returns:
1678 A list of models supported by this board, if it is a unified build; None,
1679 if it is not a unified build.
1680 """
1681 return _run_cros_config_host(
1682 build_target, ["list-models"], log_output=log_output
1683 )
Michael Mortensen125bb012020-05-21 14:02:10 -06001684
1685
Matthias Kaehlckebf7d1772021-11-04 16:01:36 -07001686def get_key_id(
Alex Klein1699fab2022-09-08 08:46:06 -06001687 build_target: "build_target_lib.BuildTarget", model: str
1688) -> Optional[str]:
1689 """Obtain the key_id for a model within the build_target.
Michael Mortensen359c1f32020-05-28 19:35:42 -06001690
Alex Klein1699fab2022-09-08 08:46:06 -06001691 Args:
1692 build_target: The build target.
1693 model: The model name
Michael Mortensen359c1f32020-05-28 19:35:42 -06001694
Alex Klein1699fab2022-09-08 08:46:06 -06001695 Returns:
1696 A key_id or None.
1697 """
1698 model_arg = "--model=" + model
1699 key_id_list = _run_cros_config_host(
1700 build_target, [model_arg, "get", "/firmware-signing", "key-id"]
1701 )
1702 key_id = None
1703 if len(key_id_list) == 1:
1704 key_id = key_id_list[0]
1705 return key_id
Michael Mortensen359c1f32020-05-28 19:35:42 -06001706
1707
Matthias Kaehlckebf7d1772021-11-04 16:01:36 -07001708def _run_cros_config_host(
Alex Klein1699fab2022-09-08 08:46:06 -06001709 build_target: "build_target_lib.BuildTarget",
Matthias Kaehlckebf7d1772021-11-04 16:01:36 -07001710 args: List[str],
Alex Klein1699fab2022-09-08 08:46:06 -06001711 log_output: bool = True,
1712) -> Optional[List[str]]:
1713 """Run the cros_config_host tool.
Michael Mortensen125bb012020-05-21 14:02:10 -06001714
Alex Klein1699fab2022-09-08 08:46:06 -06001715 Args:
1716 build_target: The build target.
1717 args: List of arguments to pass.
1718 log_output: Whether to log the output of the cros_config_host.
Michael Mortensen125bb012020-05-21 14:02:10 -06001719
Alex Klein1699fab2022-09-08 08:46:06 -06001720 Returns:
1721 Output of the tool
1722 """
1723 cros_build_lib.AssertInsideChroot()
1724 tool = "/usr/bin/cros_config_host"
1725 if not os.path.isfile(tool):
1726 return None
Michael Mortensen125bb012020-05-21 14:02:10 -06001727
Alex Klein1699fab2022-09-08 08:46:06 -06001728 config_fname = build_target.full_path(
1729 "usr/share/chromeos-config/yaml/config.yaml"
1730 )
Michael Mortensen125bb012020-05-21 14:02:10 -06001731
Alex Klein1699fab2022-09-08 08:46:06 -06001732 result = cros_build_lib.run(
1733 [tool, "-c", config_fname] + args,
1734 capture_output=True,
1735 encoding="utf-8",
1736 log_output=log_output,
1737 check=False,
1738 )
1739 if result.returncode:
1740 # Show the output for debugging purposes.
1741 if "No such file or directory" not in result.stderr:
1742 logging.error("cros_config_host failed: %s\n", result.stderr)
1743 return None
1744 return result.stdout.strip().splitlines()