blob: 442ba1b47c1cc84c398f88816566c035ed4f199d [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"
486 perfetto_version = _get_latest_version_from_refs(PERFETTO_REFS_PREFIX, refs)
487 if not perfetto_version:
488 # No valid Perfetto version is identified.
489 return result
490
491 logging.debug("Perfetto version determined from refs: %s", perfetto_version)
492
493 # 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,
501 ref=PERFETTO_REFS_PREFIX + perfetto_version,
502 )
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
Alex Klein1699fab2022-09-08 08:46:06 -0600512@uprevs_versioned_package("afdo/kernel-profiles")
Yaakov Shaul395ae832019-09-09 14:45:32 -0600513def uprev_kernel_afdo(*_args, **_kwargs):
Alex Klein1699fab2022-09-08 08:46:06 -0600514 """Updates kernel ebuilds with versions from kernel_afdo.json.
Yaakov Shaul395ae832019-09-09 14:45:32 -0600515
Alex Klein1699fab2022-09-08 08:46:06 -0600516 See: uprev_versioned_package.
Yaakov Shaul1eafe832019-09-10 16:50:26 -0600517
Alex Klein1699fab2022-09-08 08:46:06 -0600518 Raises:
519 EbuildManifestError: When ebuild manifest does not complete successfuly.
520 """
521 path = os.path.join(
522 constants.SOURCE_ROOT,
523 "src",
524 "third_party",
525 "toolchain-utils",
526 "afdo_metadata",
527 "kernel_afdo.json",
528 )
Yaakov Shaul395ae832019-09-09 14:45:32 -0600529
Alex Klein1699fab2022-09-08 08:46:06 -0600530 with open(path, "r") as f:
531 versions = json.load(f)
Yaakov Shaul395ae832019-09-09 14:45:32 -0600532
Alex Klein1699fab2022-09-08 08:46:06 -0600533 result = uprev_lib.UprevVersionedPackageResult()
534 for kernel_pkg, version_info in versions.items():
535 path = os.path.join(
536 constants.CHROMIUMOS_OVERLAY_DIR, "sys-kernel", kernel_pkg
537 )
538 ebuild_path = os.path.join(
539 constants.SOURCE_ROOT, path, "%s-9999.ebuild" % kernel_pkg
540 )
541 chroot_ebuild_path = os.path.join(
542 constants.CHROOT_SOURCE_ROOT, path, "%s-9999.ebuild" % kernel_pkg
543 )
544 afdo_profile_version = version_info["name"]
545 patch_ebuild_vars(
546 ebuild_path, dict(AFDO_PROFILE_VERSION=afdo_profile_version)
547 )
Yaakov Shaul1eafe832019-09-10 16:50:26 -0600548
Alex Klein1699fab2022-09-08 08:46:06 -0600549 try:
550 cmd = ["ebuild", chroot_ebuild_path, "manifest", "--force"]
551 cros_build_lib.run(cmd, enter_chroot=True)
552 except cros_build_lib.RunCommandError as e:
553 raise uprev_lib.EbuildManifestError(
554 "Error encountered when regenerating the manifest for ebuild: %s\n%s"
555 % (chroot_ebuild_path, e),
556 e,
557 )
Yaakov Shaul1eafe832019-09-10 16:50:26 -0600558
Alex Klein1699fab2022-09-08 08:46:06 -0600559 manifest_path = os.path.join(constants.SOURCE_ROOT, path, "Manifest")
Yaakov Shaul1eafe832019-09-10 16:50:26 -0600560
Alex Klein1699fab2022-09-08 08:46:06 -0600561 result.add_result(afdo_profile_version, [ebuild_path, manifest_path])
Yaakov Shaul730814a2019-09-10 13:58:25 -0600562
Alex Klein1699fab2022-09-08 08:46:06 -0600563 return result
Yaakov Shaul395ae832019-09-09 14:45:32 -0600564
565
Alex Klein1699fab2022-09-08 08:46:06 -0600566@uprevs_versioned_package("chromeos-base/termina-dlc")
567@uprevs_versioned_package("chromeos-base/termina-tools-dlc")
Maciek Swiech6b12f662022-01-25 16:51:19 +0000568def uprev_termina_dlcs(_build_targets, _refs, chroot):
Alex Klein1699fab2022-09-08 08:46:06 -0600569 """Updates shared termina-dlc and termina-tools-dlc ebuilds.
Maciek Swiech6b12f662022-01-25 16:51:19 +0000570
Alex Klein1699fab2022-09-08 08:46:06 -0600571 termina-dlc - chromeos-base/termina-dlc
572 termina-tools-dlc - chromeos-base/termina-tools-dlc
Trent Beginaf51f1b2020-03-09 17:35:31 -0600573
Alex Klein1699fab2022-09-08 08:46:06 -0600574 See: uprev_versioned_package.
575 """
576 termina_dlc_pkg = "termina-dlc"
577 termina_dlc_pkg_path = os.path.join(
578 constants.CHROMIUMOS_OVERLAY_DIR, "chromeos-base", termina_dlc_pkg
579 )
580 tools_dlc_pkg = "termina-tools-dlc"
581 tools_dlc_pkg_path = os.path.join(
582 constants.CHROMIUMOS_OVERLAY_DIR, "chromeos-base", tools_dlc_pkg
583 )
Patrick Meiring5897add2020-09-16 16:30:17 +1000584
Alex Klein1699fab2022-09-08 08:46:06 -0600585 # termina-dlc and termina-tools-dlc are pinned to the same version.
586 version_pin_src_path = _get_version_pin_src_path(termina_dlc_pkg_path)
587 version_no_rev = osutils.ReadFile(version_pin_src_path).strip()
Patrick Meiring5897add2020-09-16 16:30:17 +1000588
Alex Klein1699fab2022-09-08 08:46:06 -0600589 result = uprev_lib.uprev_ebuild_from_pin(
590 termina_dlc_pkg_path, version_no_rev, chroot
591 )
592 result += uprev_lib.uprev_ebuild_from_pin(
593 tools_dlc_pkg_path, version_no_rev, chroot
594 )
Patrick Meiring5897add2020-09-16 16:30:17 +1000595
Alex Klein1699fab2022-09-08 08:46:06 -0600596 return result
Patrick Meiring5897add2020-09-16 16:30:17 +1000597
Alex Klein1699fab2022-09-08 08:46:06 -0600598
599@uprevs_versioned_package("chromeos-base/chromeos-lacros")
Julio Hurtadof1befec2021-05-05 21:34:26 +0000600def uprev_lacros(_build_targets, refs, chroot):
Alex Klein1699fab2022-09-08 08:46:06 -0600601 """Updates lacros ebuilds.
Julio Hurtadof1befec2021-05-05 21:34:26 +0000602
Alex Klein1699fab2022-09-08 08:46:06 -0600603 Version to uprev to is gathered from the QA qualified version tracking file
604 stored in chromium/src/chrome/LACROS_QA_QUALIFIED_VERSION. Uprev is triggered
605 on modification of this file across all chromium/src branches.
Julio Hurtadof1befec2021-05-05 21:34:26 +0000606
Alex Klein1699fab2022-09-08 08:46:06 -0600607 See: uprev_versioned_package.
608 """
609 result = uprev_lib.UprevVersionedPackageResult()
610 path = os.path.join(
611 constants.CHROMIUMOS_OVERLAY_DIR, "chromeos-base", "chromeos-lacros"
612 )
613 lacros_version = refs[0].revision
614 uprev_result = uprev_lib.uprev_workon_ebuild_to_version(
615 path, lacros_version, chroot, allow_downrev=False
616 )
Julio Hurtadoa994e002021-07-07 17:57:45 +0000617
Alex Klein1699fab2022-09-08 08:46:06 -0600618 if not uprev_result:
619 return result
620
621 result.add_result(lacros_version, uprev_result.changed_files)
Julio Hurtadoa994e002021-07-07 17:57:45 +0000622 return result
623
Julio Hurtadof1befec2021-05-05 21:34:26 +0000624
Alex Klein1699fab2022-09-08 08:46:06 -0600625@uprevs_versioned_package("chromeos-base/chromeos-lacros-parallel")
Julio Hurtado870ed322021-12-03 18:22:40 +0000626def uprev_lacros_in_parallel(
Alex Klein1699fab2022-09-08 08:46:06 -0600627 _build_targets: Optional[List["build_target_lib.BuildTarget"]],
Julio Hurtado870ed322021-12-03 18:22:40 +0000628 refs: List[uprev_lib.GitRef],
Alex Klein1699fab2022-09-08 08:46:06 -0600629 chroot: "chroot_lib.Chroot",
630) -> "uprev_lib.UprevVersionedPackageResult":
631 """Updates lacros ebuilds in parallel with ash-chrome.
Julio Hurtado870ed322021-12-03 18:22:40 +0000632
Alex Klein1699fab2022-09-08 08:46:06 -0600633 This handler is going to be used temporarily while lacros transitions to being
634 uprevved atomically with ash-chrome. Unlike a standalone lacros uprev, this
635 handler will not need to look at the QA qualified file. Rather, it will
636 function identical to ash-chrome using git tags.
Julio Hurtado870ed322021-12-03 18:22:40 +0000637
Alex Klein1699fab2022-09-08 08:46:06 -0600638 See: uprev_versioned_package.
Julio Hurtado870ed322021-12-03 18:22:40 +0000639
Alex Klein1699fab2022-09-08 08:46:06 -0600640 Returns:
641 UprevVersionedPackageResult: The result.
642 """
643 result = uprev_lib.UprevVersionedPackageResult()
644 path = os.path.join(
645 constants.CHROMIUMOS_OVERLAY_DIR, "chromeos-base", "chromeos-lacros"
646 )
647 lacros_version = uprev_lib.get_version_from_refs(refs)
648 uprev_result = uprev_lib.uprev_workon_ebuild_to_version(
649 path, lacros_version, chroot, allow_downrev=False
650 )
Julio Hurtado870ed322021-12-03 18:22:40 +0000651
Alex Klein1699fab2022-09-08 08:46:06 -0600652 if not uprev_result:
653 return result
654
655 result.add_result(lacros_version, uprev_result.changed_files)
Julio Hurtado870ed322021-12-03 18:22:40 +0000656 return result
657
Julio Hurtado870ed322021-12-03 18:22:40 +0000658
Alex Klein1699fab2022-09-08 08:46:06 -0600659@uprevs_versioned_package("app-emulation/parallels-desktop")
Patrick Meiring5897add2020-09-16 16:30:17 +1000660def uprev_parallels_desktop(_build_targets, _refs, chroot):
Alex Klein1699fab2022-09-08 08:46:06 -0600661 """Updates Parallels Desktop ebuild - app-emulation/parallels-desktop.
Patrick Meiring5897add2020-09-16 16:30:17 +1000662
Alex Klein1699fab2022-09-08 08:46:06 -0600663 See: uprev_versioned_package
Patrick Meiring5897add2020-09-16 16:30:17 +1000664
Alex Klein1699fab2022-09-08 08:46:06 -0600665 Returns:
666 UprevVersionedPackageResult: The result.
667 """
668 package = "parallels-desktop"
669 package_path = os.path.join(
670 constants.CHROMEOS_PARTNER_OVERLAY_DIR, "app-emulation", package
671 )
672 version_pin_src_path = _get_version_pin_src_path(package_path)
Patrick Meiring5897add2020-09-16 16:30:17 +1000673
Alex Klein1699fab2022-09-08 08:46:06 -0600674 # Expect a JSON blob like the following:
675 # {
676 # "version": "1.2.3",
677 # "test_image": { "url": "...", "size": 12345678,
678 # "sha256sum": "<32 bytes of hexadecimal>" }
679 # }
680 with open(version_pin_src_path, "r") as f:
681 pinned = json.load(f)
Patrick Meiring5897add2020-09-16 16:30:17 +1000682
Alex Klein1699fab2022-09-08 08:46:06 -0600683 if "version" not in pinned or "test_image" not in pinned:
684 raise UprevError(
685 "VERSION-PIN for %s missing version and/or "
686 "test_image field" % package
687 )
Patrick Meiring5897add2020-09-16 16:30:17 +1000688
Alex Klein1699fab2022-09-08 08:46:06 -0600689 version = pinned["version"]
690 if not isinstance(version, str):
691 raise UprevError("version in VERSION-PIN for %s not a string" % package)
Patrick Meiring5897add2020-09-16 16:30:17 +1000692
Alex Klein1699fab2022-09-08 08:46:06 -0600693 # Update the ebuild.
694 result = uprev_lib.uprev_ebuild_from_pin(package_path, version, chroot)
Patrick Meiring5897add2020-09-16 16:30:17 +1000695
Alex Klein1699fab2022-09-08 08:46:06 -0600696 # Update the VM image used for testing.
697 test_image_path = (
698 "src/platform/tast-tests-private/src/chromiumos/tast/"
699 "local/bundles/crosint/pita/data/"
700 "pluginvm_image.zip.external"
701 )
702 test_image_src_path = os.path.join(constants.SOURCE_ROOT, test_image_path)
703 with open(test_image_src_path, "w") as f:
704 json.dump(pinned["test_image"], f, indent=2)
705 result.add_result(version, [test_image_src_path])
Patrick Meiring5897add2020-09-16 16:30:17 +1000706
Alex Klein1699fab2022-09-08 08:46:06 -0600707 return result
Trent Beginaf51f1b2020-03-09 17:35:31 -0600708
709
Alex Klein1699fab2022-09-08 08:46:06 -0600710@uprevs_versioned_package("chromeos-base/chromeos-dtc-vm")
Trent Beginaf51f1b2020-03-09 17:35:31 -0600711def uprev_sludge(_build_targets, _refs, chroot):
Alex Klein1699fab2022-09-08 08:46:06 -0600712 """Updates sludge VM - chromeos-base/chromeos-dtc-vm.
Trent Begin315d9d92019-12-03 21:55:53 -0700713
Alex Klein1699fab2022-09-08 08:46:06 -0600714 See: uprev_versioned_package.
715 """
716 package = "chromeos-dtc-vm"
717 package_path = os.path.join(
718 "src",
719 "private-overlays",
720 "project-wilco-private",
721 "chromeos-base",
722 package,
723 )
724 version_pin_src_path = _get_version_pin_src_path(package_path)
725 version_no_rev = osutils.ReadFile(version_pin_src_path).strip()
Trent Begin315d9d92019-12-03 21:55:53 -0700726
Alex Klein1699fab2022-09-08 08:46:06 -0600727 return uprev_lib.uprev_ebuild_from_pin(package_path, version_no_rev, chroot)
Trent Begin315d9d92019-12-03 21:55:53 -0700728
729
Alex Klein1699fab2022-09-08 08:46:06 -0600730@uprevs_versioned_package("chromeos-base/borealis-dlc")
David Riley8513c1f2021-10-14 17:07:41 -0700731def uprev_borealis_dlc(_build_targets, _refs, chroot):
Alex Klein1699fab2022-09-08 08:46:06 -0600732 """Updates shared borealis-dlc ebuild - chromeos-base/borealis-dlc.
David Riley8513c1f2021-10-14 17:07:41 -0700733
Alex Klein1699fab2022-09-08 08:46:06 -0600734 See: uprev_versioned_package.
735 """
736 package_path = os.path.join(
737 "src",
738 "private-overlays",
739 "chromeos-partner-overlay",
740 "chromeos-base",
741 "borealis-dlc",
742 )
David Riley8513c1f2021-10-14 17:07:41 -0700743
Alex Klein1699fab2022-09-08 08:46:06 -0600744 version_pin_src_path = _get_version_pin_src_path(package_path)
745 version_no_rev = osutils.ReadFile(version_pin_src_path).strip()
David Riley8513c1f2021-10-14 17:07:41 -0700746
Alex Klein1699fab2022-09-08 08:46:06 -0600747 return uprev_lib.uprev_ebuild_from_pin(package_path, version_no_rev, chroot)
David Riley8513c1f2021-10-14 17:07:41 -0700748
749
Patrick Meiring5897add2020-09-16 16:30:17 +1000750def _get_version_pin_src_path(package_path):
Alex Klein1699fab2022-09-08 08:46:06 -0600751 """Returns the path to the VERSION-PIN file for the given package."""
752 return os.path.join(constants.SOURCE_ROOT, package_path, "VERSION-PIN")
Patrick Meiring5897add2020-09-16 16:30:17 +1000753
754
Alex Klein87531182019-08-12 15:23:37 -0600755@uprevs_versioned_package(constants.CHROME_CP)
Alex Klein4e839252022-01-06 13:29:18 -0700756def uprev_chrome_from_ref(build_targets, refs, _chroot):
Alex Klein1699fab2022-09-08 08:46:06 -0600757 """Uprev chrome and its related packages.
Alex Klein87531182019-08-12 15:23:37 -0600758
Alex Klein1699fab2022-09-08 08:46:06 -0600759 See: uprev_versioned_package.
760 """
761 # Determine the version from the refs (tags), i.e. the chrome versions are the
762 # tag names.
763 chrome_version = uprev_lib.get_version_from_refs(refs)
764 logging.debug("Chrome version determined from refs: %s", chrome_version)
Alex Klein87531182019-08-12 15:23:37 -0600765
Alex Klein1699fab2022-09-08 08:46:06 -0600766 return uprev_chrome(chrome_version, build_targets, None)
Alex Kleinf69bd802021-06-22 15:43:49 -0600767
768
Alex Klein9ce3f682021-06-23 15:06:44 -0600769def revbump_chrome(
Alex Klein1699fab2022-09-08 08:46:06 -0600770 build_targets: List["build_target_lib.BuildTarget"] = None,
771 chroot: Optional["chroot_lib.Chroot"] = None,
Alex Klein9ce3f682021-06-23 15:06:44 -0600772) -> uprev_lib.UprevVersionedPackageResult:
Alex Klein1699fab2022-09-08 08:46:06 -0600773 """Attempt to revbump chrome.
Alex Kleinf69bd802021-06-22 15:43:49 -0600774
Alex Klein1699fab2022-09-08 08:46:06 -0600775 Revbumps are done by executing an uprev using the current stable version.
776 E.g. if chrome is on 1.2.3.4 and has a 1.2.3.4_rc-r2.ebuild, performing an
777 uprev on version 1.2.3.4 when there are applicable changes (e.g. to the 9999
778 ebuild) will result in a revbump to 1.2.3.4_rc-r3.ebuild.
779 """
780 chrome_version = uprev_lib.get_stable_chrome_version()
781 return uprev_chrome(chrome_version, build_targets, chroot)
Alex Kleinf69bd802021-06-22 15:43:49 -0600782
783
Alex Klein9ce3f682021-06-23 15:06:44 -0600784def uprev_chrome(
Alex Klein16ea1b32021-10-01 15:48:50 -0600785 chrome_version: str,
Alex Klein1699fab2022-09-08 08:46:06 -0600786 build_targets: Optional[List["build_target_lib.BuildTarget"]],
787 chroot: Optional["chroot_lib.Chroot"],
Alex Klein9ce3f682021-06-23 15:06:44 -0600788) -> uprev_lib.UprevVersionedPackageResult:
Alex Klein1699fab2022-09-08 08:46:06 -0600789 """Attempt to uprev chrome and its related packages to the given version."""
790 uprev_manager = uprev_lib.UprevChromeManager(
791 chrome_version, build_targets=build_targets, chroot=chroot
792 )
793 result = uprev_lib.UprevVersionedPackageResult()
794 # TODO(crbug.com/1080429): Handle all possible outcomes of a Chrome uprev
795 # attempt. The expected behavior is documented in the following table:
796 #
797 # Outcome of Chrome uprev attempt:
798 # NEWER_VERSION_EXISTS:
799 # Do nothing.
800 # SAME_VERSION_EXISTS or REVISION_BUMP:
801 # Uprev followers
802 # Assert not VERSION_BUMP (any other outcome is fine)
803 # VERSION_BUMP or NEW_EBUILD_CREATED:
804 # Uprev followers
805 # Assert that Chrome & followers are at same package version
Alex Klein0b2ec2d2021-06-23 15:56:45 -0600806
Alex Klein1699fab2022-09-08 08:46:06 -0600807 # Start with chrome itself so we can proceed accordingly.
808 chrome_result = uprev_manager.uprev(constants.CHROME_CP)
809 if chrome_result.newer_version_exists:
810 # Cannot use the given version (newer version already exists).
811 return result
812
813 # Also uprev related packages.
814 for package in constants.OTHER_CHROME_PACKAGES:
815 follower_result = uprev_manager.uprev(package)
816 if chrome_result.stable_version and follower_result.version_bump:
817 logging.warning(
818 "%s had a version bump, but no more than a revision bump "
819 "should have been possible.",
820 package,
821 )
822
823 if uprev_manager.modified_ebuilds:
824 # Record changes when we have them.
825 return result.add_result(chrome_version, uprev_manager.modified_ebuilds)
826
David Burger37f48672019-09-18 17:07:56 -0600827 return result
Alex Klein87531182019-08-12 15:23:37 -0600828
Alex Klein87531182019-08-12 15:23:37 -0600829
Alex Klein1699fab2022-09-08 08:46:06 -0600830def _get_latest_version_from_refs(
831 refs_prefix: str, refs: List[uprev_lib.GitRef]
832) -> str:
833 """Get the latest version from refs
Alex Klein0b2ec2d2021-06-23 15:56:45 -0600834
Alex Klein1699fab2022-09-08 08:46:06 -0600835 Versions are compared using |distutils.version.LooseVersion| and
836 the latest version is returned.
Alex Klein87531182019-08-12 15:23:37 -0600837
Alex Klein1699fab2022-09-08 08:46:06 -0600838 Args:
839 refs_prefix: The refs prefix of the tag format.
840 refs: The tags to parse for the latest Perfetto version.
Alex Klein87531182019-08-12 15:23:37 -0600841
Alex Klein1699fab2022-09-08 08:46:06 -0600842 Returns:
843 The latest Perfetto version to use.
844 """
845 valid_refs = []
846 for gitiles in refs:
847 if gitiles.ref.startswith(refs_prefix):
848 valid_refs.append(gitiles.ref)
Ben Reiche779cf42020-12-15 03:21:31 +0000849
Alex Klein1699fab2022-09-08 08:46:06 -0600850 if not valid_refs:
851 return None
Ben Reiche779cf42020-12-15 03:21:31 +0000852
Alex Klein1699fab2022-09-08 08:46:06 -0600853 # Sort by version and take the latest version.
854 target_version_ref = sorted(valid_refs, key=LooseVersion, reverse=True)[0]
855 return target_version_ref.replace(refs_prefix, "")
Harvey Yang9c61e9c2021-03-02 16:32:43 +0800856
857
Matthias Kaehlckebf7d1772021-11-04 16:01:36 -0700858def _generate_platform_c_files(
859 replication_config: replication_config_pb2.ReplicationConfig,
Alex Klein1699fab2022-09-08 08:46:06 -0600860 chroot: "chroot_lib.Chroot",
861) -> List[str]:
862 """Generates platform C files from a platform JSON payload.
Andrew Lamb9563a152019-12-04 11:42:18 -0700863
Alex Klein1699fab2022-09-08 08:46:06 -0600864 Args:
865 replication_config: A ReplicationConfig that has already been run. If it
866 produced a build_config.json file, that file will be used to generate
867 platform C files. Otherwise, nothing will be generated.
868 chroot: The chroot to use to generate.
Andrew Lamb9563a152019-12-04 11:42:18 -0700869
Alex Klein1699fab2022-09-08 08:46:06 -0600870 Returns:
871 A list of generated files.
872 """
873 # Generate the platform C files from the build config. Note that it would be
874 # more intuitive to generate the platform C files from the platform config;
875 # however, cros_config_schema does not allow this, because the platform config
876 # payload is not always valid input. For example, if a property is both
877 # 'required' and 'build-only', it will fail schema validation. Thus, use the
878 # build config, and use '-f' to filter.
879 build_config_path = [
880 rule.destination_path
881 for rule in replication_config.file_replication_rules
882 if rule.destination_path.endswith("build_config.json")
883 ]
Andrew Lamb9563a152019-12-04 11:42:18 -0700884
Alex Klein1699fab2022-09-08 08:46:06 -0600885 if not build_config_path:
886 logging.info(
887 "No build_config.json found, will not generate platform C files. "
888 "Replication config: %s",
889 replication_config,
890 )
891 return []
Andrew Lamb9563a152019-12-04 11:42:18 -0700892
Alex Klein1699fab2022-09-08 08:46:06 -0600893 if len(build_config_path) > 1:
894 raise ValueError(
895 "Expected at most one build_config.json destination path. "
896 "Replication config: %s" % replication_config
897 )
Andrew Lamb9563a152019-12-04 11:42:18 -0700898
Alex Klein1699fab2022-09-08 08:46:06 -0600899 build_config_path = build_config_path[0]
Andrew Lamb9563a152019-12-04 11:42:18 -0700900
Alex Klein1699fab2022-09-08 08:46:06 -0600901 # Paths to the build_config.json and dir to output C files to, in the
902 # chroot.
903 build_config_chroot_path = os.path.join(
904 constants.CHROOT_SOURCE_ROOT, build_config_path
905 )
906 generated_output_chroot_dir = os.path.join(
907 constants.CHROOT_SOURCE_ROOT, os.path.dirname(build_config_path)
908 )
Andrew Lamb9563a152019-12-04 11:42:18 -0700909
Alex Klein1699fab2022-09-08 08:46:06 -0600910 command = [
911 "cros_config_schema",
912 "-m",
913 build_config_chroot_path,
914 "-g",
915 generated_output_chroot_dir,
916 "-f",
917 '"TRUE"',
918 ]
Andrew Lamb9563a152019-12-04 11:42:18 -0700919
Alex Klein1699fab2022-09-08 08:46:06 -0600920 cros_build_lib.run(
921 command, enter_chroot=True, chroot_args=chroot.get_enter_args()
922 )
Andrew Lamb9563a152019-12-04 11:42:18 -0700923
Alex Klein1699fab2022-09-08 08:46:06 -0600924 # A relative (to the source root) path to the generated C files.
925 generated_output_dir = os.path.dirname(build_config_path)
926 generated_files = []
927 expected_c_files = ["config.c", "ec_config.c", "ec_config.h"]
928 for f in expected_c_files:
929 if os.path.exists(
930 os.path.join(constants.SOURCE_ROOT, generated_output_dir, f)
931 ):
932 generated_files.append(os.path.join(generated_output_dir, f))
Andrew Lamb9563a152019-12-04 11:42:18 -0700933
Alex Klein1699fab2022-09-08 08:46:06 -0600934 if len(expected_c_files) != len(generated_files):
935 raise GeneratedCrosConfigFilesError(expected_c_files, generated_files)
Andrew Lamb9563a152019-12-04 11:42:18 -0700936
Alex Klein1699fab2022-09-08 08:46:06 -0600937 return generated_files
Andrew Lamb9563a152019-12-04 11:42:18 -0700938
939
Matthias Kaehlckebf7d1772021-11-04 16:01:36 -0700940def _get_private_overlay_package_root(ref: uprev_lib.GitRef, package: str):
Alex Klein1699fab2022-09-08 08:46:06 -0600941 """Returns the absolute path to the root of a given private overlay.
Andrew Lambe836f222019-12-09 12:27:38 -0700942
Alex Klein1699fab2022-09-08 08:46:06 -0600943 Args:
944 ref: GitRef for the private overlay.
945 package: Path to the package in the overlay.
946 """
947 # There might be a cleaner way to map from package -> path within the source
948 # tree. For now, just use string patterns.
949 private_overlay_ref_pattern = (
950 r"/chromeos\/overlays\/overlay-([\w-]+)-private"
951 )
952 match = re.match(private_overlay_ref_pattern, ref.path)
953 if not match:
954 raise ValueError(
955 "ref.path must match the pattern: %s. Actual ref: %s"
956 % (private_overlay_ref_pattern, ref)
957 )
Andrew Lambe836f222019-12-09 12:27:38 -0700958
Alex Klein1699fab2022-09-08 08:46:06 -0600959 overlay = match.group(1)
Andrew Lambe836f222019-12-09 12:27:38 -0700960
Alex Klein1699fab2022-09-08 08:46:06 -0600961 return os.path.join(
962 constants.SOURCE_ROOT,
963 "src/private-overlays/overlay-%s-private" % overlay,
964 package,
965 )
Andrew Lambe836f222019-12-09 12:27:38 -0700966
967
Alex Klein1699fab2022-09-08 08:46:06 -0600968@uprevs_versioned_package("chromeos-base/chromeos-config-bsp")
Andrew Lambea9a8a22019-12-12 14:03:43 -0700969def replicate_private_config(_build_targets, refs, chroot):
Alex Klein1699fab2022-09-08 08:46:06 -0600970 """Replicate a private cros_config change to the corresponding public config.
Andrew Lamb2bde9e42019-11-04 13:24:09 -0700971
Alex Klein1699fab2022-09-08 08:46:06 -0600972 See uprev_versioned_package for args
973 """
974 package = "chromeos-base/chromeos-config-bsp"
Andrew Lambea9a8a22019-12-12 14:03:43 -0700975
Alex Klein1699fab2022-09-08 08:46:06 -0600976 if len(refs) != 1:
977 raise ValueError("Expected exactly one ref, actual %s" % refs)
Andrew Lamb2bde9e42019-11-04 13:24:09 -0700978
Alex Klein1699fab2022-09-08 08:46:06 -0600979 # Expect a replication_config.jsonpb in the package root.
980 package_root = _get_private_overlay_package_root(refs[0], package)
981 replication_config_path = os.path.join(
982 package_root, "replication_config.jsonpb"
983 )
Andrew Lamb2bde9e42019-11-04 13:24:09 -0700984
Alex Klein1699fab2022-09-08 08:46:06 -0600985 try:
986 replication_config = json_format.Parse(
987 osutils.ReadFile(replication_config_path),
988 replication_config_pb2.ReplicationConfig(),
989 )
990 except IOError:
991 raise ValueError(
992 "Expected ReplicationConfig missing at %s" % replication_config_path
993 )
Andrew Lamb2bde9e42019-11-04 13:24:09 -0700994
Alex Klein1699fab2022-09-08 08:46:06 -0600995 replication_lib.Replicate(replication_config)
Andrew Lamb2bde9e42019-11-04 13:24:09 -0700996
Alex Klein1699fab2022-09-08 08:46:06 -0600997 modified_files = [
998 rule.destination_path
999 for rule in replication_config.file_replication_rules
1000 ]
Andrew Lamb2bde9e42019-11-04 13:24:09 -07001001
Alex Klein1699fab2022-09-08 08:46:06 -06001002 # The generated platform C files are not easily filtered by replication rules,
1003 # i.e. JSON / proto filtering can be described by a FieldMask, arbitrary C
1004 # files cannot. Therefore, replicate and filter the JSON payloads, and then
1005 # generate filtered C files from the JSON payload.
1006 modified_files.extend(
1007 _generate_platform_c_files(replication_config, chroot)
1008 )
Andrew Lamb2bde9e42019-11-04 13:24:09 -07001009
Alex Klein1699fab2022-09-08 08:46:06 -06001010 # Use the private repo's commit hash as the new version.
1011 new_private_version = refs[0].revision
Andrew Lamb2bde9e42019-11-04 13:24:09 -07001012
Alex Klein1699fab2022-09-08 08:46:06 -06001013 # modified_files should contain only relative paths at this point, but the
1014 # returned UprevVersionedPackageResult must contain only absolute paths.
1015 for i, modified_file in enumerate(modified_files):
1016 assert not os.path.isabs(modified_file)
1017 modified_files[i] = os.path.join(constants.SOURCE_ROOT, modified_file)
Andrew Lamb988f4da2019-12-10 10:16:43 -07001018
Alex Klein1699fab2022-09-08 08:46:06 -06001019 return uprev_lib.UprevVersionedPackageResult().add_result(
1020 new_private_version, modified_files
1021 )
Andrew Lamb2bde9e42019-11-04 13:24:09 -07001022
1023
Alex Klein1699fab2022-09-08 08:46:06 -06001024@uprevs_versioned_package("chromeos-base/crosvm")
Dennis Kempinef05f2b2021-09-08 16:36:49 -07001025def uprev_crosvm(_build_targets, refs, _chroot):
Alex Klein1699fab2022-09-08 08:46:06 -06001026 """Updates crosvm ebuilds to latest revision
Dennis Kempinef05f2b2021-09-08 16:36:49 -07001027
Alex Klein1699fab2022-09-08 08:46:06 -06001028 crosvm is not versioned. We are updating to the latest commit on the main
1029 branch.
Dennis Kempinef05f2b2021-09-08 16:36:49 -07001030
Alex Klein1699fab2022-09-08 08:46:06 -06001031 See: uprev_versioned_package.
Dennis Kempinef05f2b2021-09-08 16:36:49 -07001032
Alex Klein1699fab2022-09-08 08:46:06 -06001033 Returns:
1034 UprevVersionedPackageResult: The result of updating crosvm ebuilds.
1035 """
1036 overlay = os.path.join(
1037 constants.SOURCE_ROOT, constants.CHROMIUMOS_OVERLAY_DIR
1038 )
1039 repo_path = os.path.join(constants.SOURCE_ROOT, "src", "crosvm")
1040 manifest = git.ManifestCheckout.Cached(repo_path)
Dennis Kempinef05f2b2021-09-08 16:36:49 -07001041
Alex Klein1699fab2022-09-08 08:46:06 -06001042 uprev_manager = uprev_lib.UprevOverlayManager([overlay], manifest)
1043 uprev_manager.uprev(
1044 package_list=[
1045 "chromeos-base/crosvm",
1046 "dev-rust/assertions",
1047 "dev-rust/cros_async",
1048 "dev-rust/cros_fuzz",
1049 "dev-rust/data_model",
1050 "dev-rust/enumn",
1051 "dev-rust/io_uring",
1052 "dev-rust/p9",
1053 "dev-rust/sync",
1054 "dev-rust/sys_util",
1055 "dev-rust/tempfile",
1056 "media-sound/audio_streams",
1057 ],
1058 force=True,
1059 )
Dennis Kempinef05f2b2021-09-08 16:36:49 -07001060
Alex Klein1699fab2022-09-08 08:46:06 -06001061 updated_files = uprev_manager.modified_ebuilds
1062 result = uprev_lib.UprevVersionedPackageResult()
1063 result.add_result(refs[0].revision, updated_files)
1064 return result
Dennis Kempinef05f2b2021-09-08 16:36:49 -07001065
1066
Alex Klein5caab872021-09-10 11:44:37 -06001067def get_best_visible(
Alex Klein1699fab2022-09-08 08:46:06 -06001068 atom: str, build_target: Optional["build_target_lib.BuildTarget"] = None
Alex Klein5caab872021-09-10 11:44:37 -06001069) -> package_info.PackageInfo:
Alex Klein1699fab2022-09-08 08:46:06 -06001070 """Returns the best visible CPV for the given atom.
Alex Kleinbbef2b32019-08-27 10:38:50 -06001071
Alex Klein1699fab2022-09-08 08:46:06 -06001072 Args:
1073 atom: The atom to look up.
1074 build_target: The build target whose sysroot should be searched, or the SDK
1075 if not provided.
Alex Kleinad6b48a2020-01-08 16:57:41 -07001076
Alex Klein1699fab2022-09-08 08:46:06 -06001077 Returns:
1078 The best visible package, or None if none are visible.
1079 """
1080 assert atom
Alex Kleinbbef2b32019-08-27 10:38:50 -06001081
Alex Klein1699fab2022-09-08 08:46:06 -06001082 return portage_util.PortageqBestVisible(
1083 atom,
1084 board=build_target.name if build_target else None,
1085 sysroot=build_target.root if build_target else None,
1086 )
Alex Kleinda39c6d2019-09-16 14:36:36 -06001087
1088
Matthias Kaehlckebf7d1772021-11-04 16:01:36 -07001089def has_prebuilt(
1090 atom: str,
Alex Klein1699fab2022-09-08 08:46:06 -06001091 build_target: "build_target_lib.BuildTarget" = None,
1092 useflags: Union[Iterable[str], str] = None,
1093) -> bool:
1094 """Check if a prebuilt exists.
Alex Kleinda39c6d2019-09-16 14:36:36 -06001095
Alex Klein1699fab2022-09-08 08:46:06 -06001096 Args:
1097 atom: The package whose prebuilt is being queried.
1098 build_target: The build target whose sysroot should be searched, or the
1099 SDK if not provided.
1100 useflags: Any additional USE flags that should be set. May be a string
1101 of properly formatted USE flags, or an iterable of individual flags.
Alex Kleinad6b48a2020-01-08 16:57:41 -07001102
Alex Klein1699fab2022-09-08 08:46:06 -06001103 Returns:
1104 True if there is an available prebuilt, False otherwise.
1105 """
1106 assert atom
Alex Kleinda39c6d2019-09-16 14:36:36 -06001107
Alex Klein1699fab2022-09-08 08:46:06 -06001108 board = build_target.name if build_target else None
1109 extra_env = None
1110 if useflags:
1111 new_flags = useflags
1112 if not isinstance(useflags, str):
1113 new_flags = " ".join(useflags)
Alex Klein149fd3b2019-12-16 16:01:05 -07001114
Alex Klein1699fab2022-09-08 08:46:06 -06001115 existing = os.environ.get("USE", "")
1116 final_flags = "%s %s" % (existing, new_flags)
1117 extra_env = {"USE": final_flags.strip()}
1118 return portage_util.HasPrebuilt(atom, board=board, extra_env=extra_env)
Alex Klein36b117f2019-09-30 15:13:46 -06001119
1120
David Burger0f9dd4e2019-10-08 12:33:42 -06001121def builds(atom, build_target, packages=None):
Alex Klein1699fab2022-09-08 08:46:06 -06001122 """Check if |build_target| builds |atom| (has it in its depgraph)."""
1123 cros_build_lib.AssertInsideChroot()
Alex Klein36b117f2019-09-30 15:13:46 -06001124
Alex Klein1699fab2022-09-08 08:46:06 -06001125 pkgs = tuple(packages) if packages else None
1126 # TODO(crbug/1081828): Receive and use sysroot.
1127 graph, _sdk_graph = dependency.GetBuildDependency(
1128 build_target.root, build_target.name, pkgs
1129 )
1130 return any(atom in package for package in graph["package_deps"])
Michael Mortensenb70e8a82019-10-10 18:43:41 -06001131
1132
Alex Klein6becabc2020-09-11 14:03:05 -06001133def needs_chrome_source(
Alex Klein1699fab2022-09-08 08:46:06 -06001134 build_target: "build_target_lib.BuildTarget",
Alex Klein6becabc2020-09-11 14:03:05 -06001135 compile_source=False,
1136 packages: Optional[List[package_info.PackageInfo]] = None,
Alex Klein1699fab2022-09-08 08:46:06 -06001137 useflags=None,
1138):
1139 """Check if the chrome source is needed.
Alex Klein6becabc2020-09-11 14:03:05 -06001140
Alex Klein1699fab2022-09-08 08:46:06 -06001141 The chrome source is needed if the build target builds chrome or any of its
1142 follower packages, and can't use a prebuilt for them either because it's not
1143 available, or because we can't use prebuilts because it must build from
1144 source.
1145 """
1146 cros_build_lib.AssertInsideChroot()
Alex Klein6becabc2020-09-11 14:03:05 -06001147
Alex Klein1699fab2022-09-08 08:46:06 -06001148 # Check if it builds chrome and/or a follower package.
1149 graph = depgraph.get_sysroot_dependency_graph(build_target.root, packages)
1150 builds_chrome = constants.CHROME_CP in graph
1151 builds_follower = {
1152 pkg: pkg in graph for pkg in constants.OTHER_CHROME_PACKAGES
1153 }
Alex Klein6becabc2020-09-11 14:03:05 -06001154
Alex Klein1699fab2022-09-08 08:46:06 -06001155 local_uprev = builds_chrome and revbump_chrome([build_target])
Alex Klein9ce3f682021-06-23 15:06:44 -06001156
Alex Klein1699fab2022-09-08 08:46:06 -06001157 # When we are compiling source set False since we do not use prebuilts.
1158 # When not compiling from source, start with True, i.e. we have every prebuilt
1159 # we've checked for up to this point.
1160 has_chrome_prebuilt = not compile_source
1161 has_follower_prebuilts = not compile_source
1162 # Save packages that need prebuilts for reporting.
1163 pkgs_needing_prebuilts = []
1164 if compile_source:
1165 # Need everything.
Alex Klein6becabc2020-09-11 14:03:05 -06001166 pkgs_needing_prebuilts.append(constants.CHROME_CP)
Alex Klein1699fab2022-09-08 08:46:06 -06001167 pkgs_needing_prebuilts.extend(
1168 [pkg for pkg, builds_pkg in builds_follower.items() if builds_pkg]
1169 )
1170 else:
1171 # Check chrome itself.
1172 if builds_chrome:
1173 has_chrome_prebuilt = has_prebuilt(
1174 constants.CHROME_CP,
1175 build_target=build_target,
1176 useflags=useflags,
1177 )
1178 if not has_chrome_prebuilt:
1179 pkgs_needing_prebuilts.append(constants.CHROME_CP)
1180 # Check follower packages.
1181 for pkg, builds_pkg in builds_follower.items():
1182 if not builds_pkg:
1183 continue
1184 prebuilt = has_prebuilt(
1185 pkg, build_target=build_target, useflags=useflags
1186 )
1187 has_follower_prebuilts &= prebuilt
1188 if not prebuilt:
1189 pkgs_needing_prebuilts.append(pkg)
1190 # Postcondition: has_chrome_prebuilt and has_follower_prebuilts now correctly
1191 # reflect whether we actually have the corresponding prebuilts for the build.
Alex Klein6becabc2020-09-11 14:03:05 -06001192
Alex Klein1699fab2022-09-08 08:46:06 -06001193 needs_chrome = builds_chrome and not has_chrome_prebuilt
1194 needs_follower = (
1195 any(builds_follower.values()) and not has_follower_prebuilts
1196 )
Alex Klein6becabc2020-09-11 14:03:05 -06001197
Alex Klein1699fab2022-09-08 08:46:06 -06001198 return NeedsChromeSourceResult(
1199 needs_chrome_source=needs_chrome or needs_follower,
1200 builds_chrome=builds_chrome,
1201 packages=[package_info.parse(p) for p in pkgs_needing_prebuilts],
1202 missing_chrome_prebuilt=not has_chrome_prebuilt,
1203 missing_follower_prebuilt=not has_follower_prebuilts,
1204 local_uprev=local_uprev,
1205 )
Alex Klein6becabc2020-09-11 14:03:05 -06001206
1207
Alex Klein68a28712021-11-08 11:08:30 -07001208class TargetVersions(NamedTuple):
Alex Klein1699fab2022-09-08 08:46:06 -06001209 """Data class for the info that makes up the "target versions"."""
1210
1211 android_version: str
1212 android_branch: str
1213 android_target: str
1214 chrome_version: str
1215 platform_version: str
1216 milestone_version: str
1217 full_version: str
Alex Klein68a28712021-11-08 11:08:30 -07001218
1219
1220def get_target_versions(
Alex Klein1699fab2022-09-08 08:46:06 -06001221 build_target: "build_target_lib.BuildTarget",
1222 packages: List[package_info.PackageInfo] = None,
Alex Klein68a28712021-11-08 11:08:30 -07001223) -> TargetVersions:
Alex Klein1699fab2022-09-08 08:46:06 -06001224 """Aggregate version info for a few key packages and the OS as a whole."""
1225 # Android version.
1226 android_version = determine_android_version(build_target.name)
1227 logging.info("Found android version: %s", android_version)
1228 # Android branch version.
1229 android_branch = determine_android_branch(build_target.name)
1230 logging.info("Found android branch version: %s", android_branch)
1231 # Android target version.
1232 android_target = determine_android_target(build_target.name)
1233 logging.info("Found android target version: %s", android_target)
Alex Klein68a28712021-11-08 11:08:30 -07001234
Alex Klein1699fab2022-09-08 08:46:06 -06001235 # TODO(crbug/1019770): Investigate cases where builds_chrome is true but
1236 # chrome_version is None.
Alex Klein68a28712021-11-08 11:08:30 -07001237
Alex Klein1699fab2022-09-08 08:46:06 -06001238 builds_chrome = builds(constants.CHROME_CP, build_target, packages=packages)
1239 chrome_version = None
1240 if builds_chrome:
1241 # Chrome version fetch.
1242 chrome_version = determine_chrome_version(build_target)
1243 logging.info("Found chrome version: %s", chrome_version)
Alex Klein68a28712021-11-08 11:08:30 -07001244
Alex Klein1699fab2022-09-08 08:46:06 -06001245 # The ChromeOS version info.
1246 platform_version = determine_platform_version()
1247 milestone_version = determine_milestone_version()
1248 full_version = determine_full_version()
Alex Klein68a28712021-11-08 11:08:30 -07001249
Alex Klein1699fab2022-09-08 08:46:06 -06001250 return TargetVersions(
1251 android_version,
1252 android_branch,
1253 android_target,
1254 chrome_version,
1255 platform_version,
1256 milestone_version,
1257 full_version,
1258 )
Alex Klein68a28712021-11-08 11:08:30 -07001259
1260
Matthias Kaehlckebf7d1772021-11-04 16:01:36 -07001261def determine_chrome_version(
Alex Klein1699fab2022-09-08 08:46:06 -06001262 build_target: "build_target_lib.BuildTarget",
1263) -> Optional[str]:
1264 """Returns the current Chrome version for the board (or in buildroot).
Michael Mortensenc2615b72019-10-15 08:12:24 -06001265
Alex Klein1699fab2022-09-08 08:46:06 -06001266 Args:
1267 build_target: The board build target.
Alex Kleinad6b48a2020-01-08 16:57:41 -07001268
Alex Klein1699fab2022-09-08 08:46:06 -06001269 Returns:
1270 The chrome version if available.
1271 """
1272 # TODO(crbug/1019770): Long term we should not need the try/catch here once
1273 # the builds function above only returns True for chrome when
1274 # determine_chrome_version will succeed.
1275 try:
1276 pkg_info = portage_util.PortageqBestVisible(
1277 constants.CHROME_CP, build_target.name, cwd=constants.SOURCE_ROOT
1278 )
1279 except cros_build_lib.RunCommandError as e:
1280 # Return None because portage failed when trying to determine the chrome
1281 # version.
1282 logging.warning("Caught exception in determine_chrome_package: %s", e)
1283 return None
1284 # Something like 78.0.3877.4_rc -> 78.0.3877.4
1285 return pkg_info.version.partition("_")[0]
Michael Mortensenc2615b72019-10-15 08:12:24 -06001286
1287
Alex Klein68a28712021-11-08 11:08:30 -07001288@functools.lru_cache()
Matthias Kaehlckebf7d1772021-11-04 16:01:36 -07001289def determine_android_package(board: str) -> Optional[str]:
Alex Klein1699fab2022-09-08 08:46:06 -06001290 """Returns the active Android container package in use by the board.
Michael Mortensenb70e8a82019-10-10 18:43:41 -06001291
Alex Klein1699fab2022-09-08 08:46:06 -06001292 Args:
1293 board: The board name this is specific to.
Alex Kleinad6b48a2020-01-08 16:57:41 -07001294
Alex Klein1699fab2022-09-08 08:46:06 -06001295 Returns:
1296 The android package string if there is one.
1297 """
1298 try:
1299 packages = portage_util.GetPackageDependencies(
1300 "virtual/target-os", board=board
1301 )
1302 except cros_build_lib.RunCommandError as e:
1303 # Return None because a command (likely portage) failed when trying to
1304 # determine the package.
1305 logging.warning("Caught exception in determine_android_package: %s", e)
1306 return None
1307
1308 # We assume there is only one Android package in the depgraph.
1309 for package in packages:
1310 if package.startswith(
1311 "chromeos-base/android-container-"
1312 ) or package.startswith("chromeos-base/android-vm-"):
1313 return package
Michael Mortensene0f4b542019-10-24 15:30:23 -06001314 return None
Michael Mortensenb70e8a82019-10-10 18:43:41 -06001315
1316
Matthias Kaehlckebf7d1772021-11-04 16:01:36 -07001317def determine_android_version(board: str, package: str = None):
Alex Klein1699fab2022-09-08 08:46:06 -06001318 """Determine the current Android version in buildroot now and return it.
Michael Mortensenb70e8a82019-10-10 18:43:41 -06001319
Alex Klein1699fab2022-09-08 08:46:06 -06001320 This uses the typical portage logic to determine which version of Android
1321 is active right now in the buildroot.
Michael Mortensenb70e8a82019-10-10 18:43:41 -06001322
Alex Klein1699fab2022-09-08 08:46:06 -06001323 Args:
1324 board: The board name this is specific to.
1325 package: The Android package, if already computed.
Michael Mortensenb70e8a82019-10-10 18:43:41 -06001326
Alex Klein1699fab2022-09-08 08:46:06 -06001327 Returns:
1328 The Android build ID of the container for the board.
Michael Mortensenb70e8a82019-10-10 18:43:41 -06001329
Alex Klein1699fab2022-09-08 08:46:06 -06001330 Raises:
1331 NoAndroidVersionError: if no unique Android version can be determined.
1332 """
1333 if not package:
1334 package = determine_android_package(board)
1335 if not package:
1336 return None
1337 cpv = package_info.SplitCPV(package)
1338 if not cpv:
1339 raise NoAndroidVersionError(
1340 "Android version could not be determined for %s" % board
1341 )
1342 return cpv.version_no_rev
Michael Mortensenb70e8a82019-10-10 18:43:41 -06001343
Alex Klein7a3a7dd2020-01-08 16:44:38 -07001344
Mike Frysinger8e1c99a2021-03-05 00:58:11 -05001345def determine_android_branch(board, package=None):
Alex Klein1699fab2022-09-08 08:46:06 -06001346 """Returns the Android branch in use by the active container ebuild."""
1347 if not package:
1348 package = determine_android_package(board)
1349 if not package:
1350 return None
1351 ebuild_path = portage_util.FindEbuildForBoardPackage(package, board)
1352 # We assume all targets pull from the same branch and that we always
1353 # have at least one of the following targets.
1354 targets = constants.ANDROID_ALL_BUILD_TARGETS
1355 ebuild_content = osutils.SourceEnvironment(ebuild_path, targets)
1356 for target in targets:
1357 if target in ebuild_content:
1358 branch = re.search(r"(.*?)-linux-", ebuild_content[target])
1359 if branch is not None:
1360 return branch.group(1)
1361 raise NoAndroidBranchError(
1362 "Android branch could not be determined for %s (ebuild empty?)" % board
1363 )
Michael Mortensenb70e8a82019-10-10 18:43:41 -06001364
1365
Mike Frysinger8e1c99a2021-03-05 00:58:11 -05001366def determine_android_target(board, package=None):
Alex Klein1699fab2022-09-08 08:46:06 -06001367 """Returns the Android target 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 if package.startswith("chromeos-base/android-vm-"):
1373 return "bertha"
1374 elif package.startswith("chromeos-base/android-container-"):
1375 return "cheets"
Michael Mortensenb70e8a82019-10-10 18:43:41 -06001376
Alex Klein1699fab2022-09-08 08:46:06 -06001377 raise NoAndroidTargetError(
1378 "Android Target cannot be determined for the package: %s" % package
1379 )
Michael Mortensen9fdb14b2019-10-17 11:17:30 -06001380
1381
1382def determine_platform_version():
Alex Klein1699fab2022-09-08 08:46:06 -06001383 """Returns the platform version from the source root."""
1384 # Platform version is something like '12575.0.0'.
1385 version = chromeos_version.VersionInfo.from_repo(constants.SOURCE_ROOT)
1386 return version.VersionString()
Michael Mortensen009cb662019-10-21 11:38:43 -06001387
1388
1389def determine_milestone_version():
Alex Klein1699fab2022-09-08 08:46:06 -06001390 """Returns the platform version from the source root."""
1391 # Milestone version is something like '79'.
1392 version = chromeos_version.VersionInfo.from_repo(constants.SOURCE_ROOT)
1393 return version.chrome_branch
Michael Mortensen009cb662019-10-21 11:38:43 -06001394
Alex Klein7a3a7dd2020-01-08 16:44:38 -07001395
Michael Mortensen009cb662019-10-21 11:38:43 -06001396def determine_full_version():
Alex Klein1699fab2022-09-08 08:46:06 -06001397 """Returns the full version from the source root."""
1398 # Full version is something like 'R79-12575.0.0'.
1399 milestone_version = determine_milestone_version()
1400 platform_version = determine_platform_version()
1401 full_version = "R%s-%s" % (milestone_version, platform_version)
1402 return full_version
Michael Mortensen71ef5682020-05-07 14:29:24 -06001403
1404
Matthias Kaehlckebf7d1772021-11-04 16:01:36 -07001405def find_fingerprints(
Alex Klein1699fab2022-09-08 08:46:06 -06001406 build_target: "build_target_lib.BuildTarget",
1407) -> List[str]:
1408 """Returns a list of fingerprints for this build.
Michael Mortensende716a12020-05-15 11:27:00 -06001409
Alex Klein1699fab2022-09-08 08:46:06 -06001410 Args:
1411 build_target: The build target.
Michael Mortensende716a12020-05-15 11:27:00 -06001412
Alex Klein1699fab2022-09-08 08:46:06 -06001413 Returns:
1414 List of fingerprint strings.
1415 """
1416 cros_build_lib.AssertInsideChroot()
1417 fp_file = "cheets-fingerprint.txt"
1418 fp_path = os.path.join(
1419 image_lib.GetLatestImageLink(build_target.name), fp_file
1420 )
1421 if not os.path.isfile(fp_path):
1422 logging.info("Fingerprint file not found: %s", fp_path)
1423 return []
1424 logging.info("Reading fingerprint file: %s", fp_path)
1425 fingerprints = osutils.ReadFile(fp_path).splitlines()
1426 return fingerprints
Michael Mortensende716a12020-05-15 11:27:00 -06001427
1428
Alex Klein1699fab2022-09-08 08:46:06 -06001429def get_all_firmware_versions(build_target: "build_target_lib.BuildTarget"):
1430 """Extract firmware version for all models present.
Michael Mortensen59e30872020-05-18 14:12:49 -06001431
Alex Klein1699fab2022-09-08 08:46:06 -06001432 Args:
1433 build_target: The build target.
Michael Mortensen59e30872020-05-18 14:12:49 -06001434
Alex Klein1699fab2022-09-08 08:46:06 -06001435 Returns:
1436 A dict of FirmwareVersions namedtuple instances by model.
1437 Each element will be populated based on whether it was present in the
1438 command output.
1439 """
1440 cros_build_lib.AssertInsideChroot()
1441 result = {}
1442 # Note that example output for _get_firmware_version_cmd_result is available
1443 # in the packages_unittest.py for testing get_all_firmware_versions.
1444 cmd_result = _get_firmware_version_cmd_result(build_target)
Michael Mortensen59e30872020-05-18 14:12:49 -06001445
Alex Klein1699fab2022-09-08 08:46:06 -06001446 if cmd_result:
1447 # There is a blank line between the version info for each model.
1448 firmware_version_payloads = cmd_result.split("\n\n")
1449 for firmware_version_payload in firmware_version_payloads:
1450 if "BIOS" in firmware_version_payload:
1451 firmware_version = _find_firmware_versions(
1452 firmware_version_payload
1453 )
1454 result[firmware_version.model] = firmware_version
1455 return result
Michael Mortensen59e30872020-05-18 14:12:49 -06001456
1457
Benjamin Shai0858cd32022-01-10 20:23:49 +00001458class FirmwareVersions(NamedTuple):
Alex Klein1699fab2022-09-08 08:46:06 -06001459 """Tuple to hold firmware versions, with truthiness."""
Benjamin Shai0858cd32022-01-10 20:23:49 +00001460
Alex Klein1699fab2022-09-08 08:46:06 -06001461 model: Optional[str]
1462 main: Optional[str]
1463 main_rw: Optional[str]
1464 ec: Optional[str]
1465 ec_rw: Optional[str]
1466
1467 def __bool__(self):
1468 return bool(
1469 self.model or self.main or self.main_rw or self.ec or self.ec_rw
1470 )
Michael Mortensen71ef5682020-05-07 14:29:24 -06001471
1472
Alex Klein1699fab2022-09-08 08:46:06 -06001473def get_firmware_versions(build_target: "build_target_lib.BuildTarget"):
1474 """Extract version information from the firmware updater, if one exists.
Michael Mortensen71ef5682020-05-07 14:29:24 -06001475
Alex Klein1699fab2022-09-08 08:46:06 -06001476 Args:
1477 build_target: The build target.
Michael Mortensen71ef5682020-05-07 14:29:24 -06001478
Alex Klein1699fab2022-09-08 08:46:06 -06001479 Returns:
1480 A FirmwareVersions namedtuple instance.
1481 Each element will either be set to the string output by the firmware
1482 updater shellball, or None if there is no firmware updater.
1483 """
1484 cros_build_lib.AssertInsideChroot()
1485 cmd_result = _get_firmware_version_cmd_result(build_target)
1486 if cmd_result:
1487 return _find_firmware_versions(cmd_result)
1488 else:
1489 return FirmwareVersions(None, None, None, None, None)
Michael Mortensen71ef5682020-05-07 14:29:24 -06001490
1491
Matthias Kaehlckebf7d1772021-11-04 16:01:36 -07001492def _get_firmware_version_cmd_result(
Alex Klein1699fab2022-09-08 08:46:06 -06001493 build_target: "build_target_lib.BuildTarget",
1494) -> Optional[str]:
1495 """Gets the raw result output of the firmware updater version command.
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 Command execution result.
1502 """
1503 updater = os.path.join(
1504 build_target.root, "usr/sbin/chromeos-firmwareupdate"
1505 )
1506 logging.info("Calling updater %s", updater)
1507 # Call the updater using the chroot-based path.
1508 try:
1509 return cros_build_lib.run(
1510 [updater, "-V"],
1511 capture_output=True,
1512 log_output=True,
1513 encoding="utf-8",
1514 ).stdout
1515 except cros_build_lib.RunCommandError:
1516 # Updater probably doesn't exist (e.g. betty).
1517 return None
Michael Mortensen71ef5682020-05-07 14:29:24 -06001518
1519
1520def _find_firmware_versions(cmd_output):
Alex Klein1699fab2022-09-08 08:46:06 -06001521 """Finds firmware version output via regex matches against the cmd_output.
Michael Mortensen71ef5682020-05-07 14:29:24 -06001522
Alex Klein1699fab2022-09-08 08:46:06 -06001523 Args:
1524 cmd_output: The raw output to search against.
Michael Mortensen71ef5682020-05-07 14:29:24 -06001525
Alex Klein1699fab2022-09-08 08:46:06 -06001526 Returns:
1527 FirmwareVersions namedtuple with results.
1528 Each element will either be set to the string output by the firmware
1529 updater shellball, or None if there is no match.
1530 """
Michael Mortensen71ef5682020-05-07 14:29:24 -06001531
Alex Klein1699fab2022-09-08 08:46:06 -06001532 # Sometimes a firmware bundle includes a special combination of RO+RW
1533 # firmware. In this case, the RW firmware version is indicated with a "(RW)
1534 # version" field. In other cases, the "(RW) version" field is not present.
1535 # Therefore, search for the "(RW)" fields first and if they aren't present,
1536 # fallback to the other format. e.g. just "BIOS version:".
1537 # TODO(mmortensen): Use JSON once the firmware updater supports it.
1538 main = None
1539 main_rw = None
1540 ec = None
1541 ec_rw = None
1542 model = None
Michael Mortensen71ef5682020-05-07 14:29:24 -06001543
Alex Klein1699fab2022-09-08 08:46:06 -06001544 match = re.search(r"BIOS version:\s*(?P<version>.*)", cmd_output)
1545 if match:
1546 main = match.group("version")
Michael Mortensen71ef5682020-05-07 14:29:24 -06001547
Alex Klein1699fab2022-09-08 08:46:06 -06001548 match = re.search(r"BIOS \(RW\) version:\s*(?P<version>.*)", cmd_output)
1549 if match:
1550 main_rw = match.group("version")
Michael Mortensen71ef5682020-05-07 14:29:24 -06001551
Alex Klein1699fab2022-09-08 08:46:06 -06001552 match = re.search(r"EC version:\s*(?P<version>.*)", cmd_output)
1553 if match:
1554 ec = match.group("version")
Michael Mortensen71ef5682020-05-07 14:29:24 -06001555
Alex Klein1699fab2022-09-08 08:46:06 -06001556 match = re.search(r"EC \(RW\) version:\s*(?P<version>.*)", cmd_output)
1557 if match:
1558 ec_rw = match.group("version")
Michael Mortensen71ef5682020-05-07 14:29:24 -06001559
Alex Klein1699fab2022-09-08 08:46:06 -06001560 match = re.search(r"Model:\s*(?P<model>.*)", cmd_output)
1561 if match:
1562 model = match.group("model")
Michael Mortensen71ef5682020-05-07 14:29:24 -06001563
Alex Klein1699fab2022-09-08 08:46:06 -06001564 return FirmwareVersions(model, main, main_rw, ec, ec_rw)
Michael Mortensena4af79e2020-05-06 16:18:48 -06001565
1566
Benjamin Shai0858cd32022-01-10 20:23:49 +00001567class MainEcFirmwareVersions(NamedTuple):
Alex Klein1699fab2022-09-08 08:46:06 -06001568 """Tuple to hold main and ec firmware versions, with truthiness."""
Benjamin Shai0858cd32022-01-10 20:23:49 +00001569
Alex Klein1699fab2022-09-08 08:46:06 -06001570 main_fw_version: Optional[str]
1571 ec_fw_version: Optional[str]
1572
1573 def __bool__(self):
1574 return bool(self.main_fw_version or self.ec_fw_version)
Benjamin Shai0858cd32022-01-10 20:23:49 +00001575
Michael Mortensena4af79e2020-05-06 16:18:48 -06001576
Alex Klein1699fab2022-09-08 08:46:06 -06001577def determine_firmware_versions(build_target: "build_target_lib.BuildTarget"):
1578 """Returns a namedtuple with main and ec firmware versions.
Michael Mortensena4af79e2020-05-06 16:18:48 -06001579
Alex Klein1699fab2022-09-08 08:46:06 -06001580 Args:
1581 build_target: The build target.
Michael Mortensena4af79e2020-05-06 16:18:48 -06001582
Alex Klein1699fab2022-09-08 08:46:06 -06001583 Returns:
1584 MainEcFirmwareVersions namedtuple with results.
1585 """
1586 fw_versions = get_firmware_versions(build_target)
1587 main_fw_version = fw_versions.main_rw or fw_versions.main
1588 ec_fw_version = fw_versions.ec_rw or fw_versions.ec
Michael Mortensena4af79e2020-05-06 16:18:48 -06001589
Alex Klein1699fab2022-09-08 08:46:06 -06001590 return MainEcFirmwareVersions(main_fw_version, ec_fw_version)
Michael Mortensenfbf2b2d2020-05-14 16:33:06 -06001591
Benjamin Shai0858cd32022-01-10 20:23:49 +00001592
Matthias Kaehlckebf7d1772021-11-04 16:01:36 -07001593def determine_kernel_version(
Alex Klein1699fab2022-09-08 08:46:06 -06001594 build_target: "build_target_lib.BuildTarget",
Lizzy Presland0b978e62022-09-09 16:55:29 +00001595) -> str:
Alex Klein1699fab2022-09-08 08:46:06 -06001596 """Returns a string containing the kernel version for this build target.
Michael Mortensenfbf2b2d2020-05-14 16:33:06 -06001597
Alex Klein1699fab2022-09-08 08:46:06 -06001598 Args:
1599 build_target: The build target.
Michael Mortensenfbf2b2d2020-05-14 16:33:06 -06001600
Alex Klein1699fab2022-09-08 08:46:06 -06001601 Returns:
Lizzy Presland0b978e62022-09-09 16:55:29 +00001602 The kernel versions, or empty string.
Alex Klein1699fab2022-09-08 08:46:06 -06001603 """
Lizzy Presland0b978e62022-09-09 16:55:29 +00001604 target_virtual_pkg = "virtual/linux-sources"
Alex Klein1699fab2022-09-08 08:46:06 -06001605 try:
Lizzy Presland0b978e62022-09-09 16:55:29 +00001606 candidate_packages = portage_util.GetFlattenedDepsForPackage(
1607 target_virtual_pkg,
1608 sysroot=build_target.root,
1609 board=build_target.name,
1610 depth=1,
1611 )
1612 installed_packages = portage_util.GetPackageDependencies(
1613 target_virtual_pkg, board=build_target.name
Alex Klein1699fab2022-09-08 08:46:06 -06001614 )
1615 except cros_build_lib.RunCommandError as e:
1616 logging.warning("Unable to get package list for metadata: %s", e)
Lizzy Presland0b978e62022-09-09 16:55:29 +00001617 return ""
1618 if not candidate_packages:
1619 raise KernelVersionError("No package found in FlattenedDepsForPackage")
1620 if not installed_packages:
1621 raise KernelVersionError("No package found in GetPackageDependencies")
1622 packages = [
1623 p
1624 for p in installed_packages
1625 if p in candidate_packages and target_virtual_pkg not in p
1626 ]
1627 if len(packages) == 0:
1628 raise KernelVersionError(
1629 "No matches for installed packages were found in candidate "
1630 "packages. Did GetFlattenedDepsForPackage search all possible "
1631 "package versions?\tInstalled: %s\tCandidates: %s"
1632 % (" ".join(installed_packages), " ".join(candidate_packages))
1633 )
1634 if len(packages) > 1:
1635 raise KernelVersionError(
1636 "Too many packages found in intersection of installed packages and "
1637 "possible kernel versions (%s)" % "".join(packages)
1638 )
1639 kernel_version = package_info.SplitCPV(packages[0]).version
1640 logging.info("Found active kernel version: %s", kernel_version)
1641 return kernel_version
Michael Mortensen125bb012020-05-21 14:02:10 -06001642
1643
Matthias Kaehlckebf7d1772021-11-04 16:01:36 -07001644def get_models(
Alex Klein1699fab2022-09-08 08:46:06 -06001645 build_target: "build_target_lib.BuildTarget", log_output: bool = True
1646) -> Optional[List[str]]:
1647 """Obtain a list of models supported by a unified board.
Michael Mortensen125bb012020-05-21 14:02:10 -06001648
Alex Klein1699fab2022-09-08 08:46:06 -06001649 This ignored whitelabel models since GoldenEye has no specific support for
1650 these at present.
Michael Mortensen125bb012020-05-21 14:02:10 -06001651
Alex Klein1699fab2022-09-08 08:46:06 -06001652 Args:
1653 build_target: The build target.
1654 log_output: Whether to log the output of the cros_config_host invocation.
Michael Mortensen125bb012020-05-21 14:02:10 -06001655
Alex Klein1699fab2022-09-08 08:46:06 -06001656 Returns:
1657 A list of models supported by this board, if it is a unified build; None,
1658 if it is not a unified build.
1659 """
1660 return _run_cros_config_host(
1661 build_target, ["list-models"], log_output=log_output
1662 )
Michael Mortensen125bb012020-05-21 14:02:10 -06001663
1664
Matthias Kaehlckebf7d1772021-11-04 16:01:36 -07001665def get_key_id(
Alex Klein1699fab2022-09-08 08:46:06 -06001666 build_target: "build_target_lib.BuildTarget", model: str
1667) -> Optional[str]:
1668 """Obtain the key_id for a model within the build_target.
Michael Mortensen359c1f32020-05-28 19:35:42 -06001669
Alex Klein1699fab2022-09-08 08:46:06 -06001670 Args:
1671 build_target: The build target.
1672 model: The model name
Michael Mortensen359c1f32020-05-28 19:35:42 -06001673
Alex Klein1699fab2022-09-08 08:46:06 -06001674 Returns:
1675 A key_id or None.
1676 """
1677 model_arg = "--model=" + model
1678 key_id_list = _run_cros_config_host(
1679 build_target, [model_arg, "get", "/firmware-signing", "key-id"]
1680 )
1681 key_id = None
1682 if len(key_id_list) == 1:
1683 key_id = key_id_list[0]
1684 return key_id
Michael Mortensen359c1f32020-05-28 19:35:42 -06001685
1686
Matthias Kaehlckebf7d1772021-11-04 16:01:36 -07001687def _run_cros_config_host(
Alex Klein1699fab2022-09-08 08:46:06 -06001688 build_target: "build_target_lib.BuildTarget",
Matthias Kaehlckebf7d1772021-11-04 16:01:36 -07001689 args: List[str],
Alex Klein1699fab2022-09-08 08:46:06 -06001690 log_output: bool = True,
1691) -> Optional[List[str]]:
1692 """Run the cros_config_host tool.
Michael Mortensen125bb012020-05-21 14:02:10 -06001693
Alex Klein1699fab2022-09-08 08:46:06 -06001694 Args:
1695 build_target: The build target.
1696 args: List of arguments to pass.
1697 log_output: Whether to log the output of the cros_config_host.
Michael Mortensen125bb012020-05-21 14:02:10 -06001698
Alex Klein1699fab2022-09-08 08:46:06 -06001699 Returns:
1700 Output of the tool
1701 """
1702 cros_build_lib.AssertInsideChroot()
1703 tool = "/usr/bin/cros_config_host"
1704 if not os.path.isfile(tool):
1705 return None
Michael Mortensen125bb012020-05-21 14:02:10 -06001706
Alex Klein1699fab2022-09-08 08:46:06 -06001707 config_fname = build_target.full_path(
1708 "usr/share/chromeos-config/yaml/config.yaml"
1709 )
Michael Mortensen125bb012020-05-21 14:02:10 -06001710
Alex Klein1699fab2022-09-08 08:46:06 -06001711 result = cros_build_lib.run(
1712 [tool, "-c", config_fname] + args,
1713 capture_output=True,
1714 encoding="utf-8",
1715 log_output=log_output,
1716 check=False,
1717 )
1718 if result.returncode:
1719 # Show the output for debugging purposes.
1720 if "No such file or directory" not in result.stderr:
1721 logging.error("cros_config_host failed: %s\n", result.stderr)
1722 return None
1723 return result.stdout.strip().splitlines()