blob: f9d649b0424db8058856643f5f9fe3269016f298 [file] [log] [blame]
Alex Kleineb77ffa2019-05-28 14:47:44 -06001# Copyright 2019 The Chromium OS Authors. All rights reserved.
2# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
4
5"""Package related functionality."""
6
Chris McDonald1672ddb2021-07-21 11:48:23 -06007import logging
8
Alex Klein076841b2019-08-29 15:19:39 -06009from chromite.api import faux
David Burger1e0fe232019-07-01 14:52:07 -060010from chromite.api import validate
Alex Kleineb77ffa2019-05-28 14:47:44 -060011from chromite.api.controller import controller_util
12from chromite.api.gen.chromite.api import binhost_pb2
Alex Klein6becabc2020-09-11 14:03:05 -060013from chromite.api.gen.chromite.api import packages_pb2
David Burger1e0fe232019-07-01 14:52:07 -060014from chromite.api.gen.chromiumos import common_pb2
Alex Kleineb77ffa2019-05-28 14:47:44 -060015from chromite.lib import constants
16from chromite.lib import cros_build_lib
Michael Mortensenbbce7e42020-05-01 15:03:49 -060017from chromite.lib import portage_util
Alex Klein6becabc2020-09-11 14:03:05 -060018from chromite.lib.parser import package_info
Chris McDonald1672ddb2021-07-21 11:48:23 -060019from chromite.lib.uprev_lib import GitRef
Alex Kleineb77ffa2019-05-28 14:47:44 -060020from chromite.service import packages
21
22
23_OVERLAY_TYPE_TO_NAME = {
24 binhost_pb2.OVERLAYTYPE_PUBLIC: constants.PUBLIC_OVERLAYS,
25 binhost_pb2.OVERLAYTYPE_PRIVATE: constants.PRIVATE_OVERLAYS,
26 binhost_pb2.OVERLAYTYPE_BOTH: constants.BOTH_OVERLAYS,
27}
28
Michael Mortensen2677bf62019-10-29 08:31:25 -060029def _UprevResponse(_input_proto, output_proto, _config):
30 """Add fake paths to a successful uprev response."""
31 output_proto.modified_ebuilds.add().path = '/fake/path1'
32 output_proto.modified_ebuilds.add().path = '/fake/path2'
Alex Kleineb77ffa2019-05-28 14:47:44 -060033
Michael Mortensen2677bf62019-10-29 08:31:25 -060034@faux.success(_UprevResponse)
35@faux.empty_error
Alex Klein231d2da2019-07-22 16:44:45 -060036@validate.require('overlay_type')
37@validate.is_in('overlay_type', _OVERLAY_TYPE_TO_NAME)
38@validate.validation_complete
39def Uprev(input_proto, output_proto, _config):
Alex Kleineb77ffa2019-05-28 14:47:44 -060040 """Uprev all cros workon ebuilds that have changes."""
Alex Klein26e472b2020-03-10 14:35:01 -060041 build_targets = controller_util.ParseBuildTargets(input_proto.build_targets)
Alex Kleineb77ffa2019-05-28 14:47:44 -060042 overlay_type = _OVERLAY_TYPE_TO_NAME[input_proto.overlay_type]
43 chroot = controller_util.ParseChroot(input_proto.chroot)
44 output_dir = input_proto.output_dir or None
45
46 try:
Dhanya Ganeshd03a4162021-08-25 00:21:50 +000047 modified_ebuilds, revved_packages = (
48 packages.uprev_build_targets(build_targets, overlay_type, chroot,
49 output_dir))
Alex Kleineb77ffa2019-05-28 14:47:44 -060050 except packages.Error as e:
51 # Handle module errors nicely, let everything else bubble up.
Mike Frysinger6b5c3cd2019-08-27 16:51:00 -040052 cros_build_lib.Die(e)
David Burger1e0fe232019-07-01 14:52:07 -060053
Dhanya Ganeshd03a4162021-08-25 00:21:50 +000054 for path in modified_ebuilds:
Alex Klein5dd6b1e2019-07-31 15:45:24 -060055 output_proto.modified_ebuilds.add().path = path
56
Dhanya Ganeshd03a4162021-08-25 00:21:50 +000057 for package in revved_packages:
58 pkg_info = package_info.parse(package)
59 pkg_proto = output_proto.packages.add()
60 controller_util.serialize_package_info(pkg_info, pkg_proto)
Alex Klein231d2da2019-07-22 16:44:45 -060061
Michael Mortensen2677bf62019-10-29 08:31:25 -060062def _UprevVersionedPackageResponse(_input_proto, output_proto, _config):
63 """Add fake paths to a successful uprev versioned package response."""
64 uprev_response = output_proto.responses.add()
65 uprev_response.modified_ebuilds.add().path = '/uprev/response/path'
66
67
68@faux.success(_UprevVersionedPackageResponse)
69@faux.empty_error
Alex Klein87531182019-08-12 15:23:37 -060070@validate.require('versions')
71@validate.require('package_info.package_name', 'package_info.category')
Alex Klein231d2da2019-07-22 16:44:45 -060072@validate.validation_complete
Alex Klein87531182019-08-12 15:23:37 -060073def UprevVersionedPackage(input_proto, output_proto, _config):
Evan Hernandez38555d42019-08-05 15:11:54 -060074 """Uprev a versioned package.
75
76 See go/pupr-generator for details about this endpoint.
77 """
Alex Klein87531182019-08-12 15:23:37 -060078 chroot = controller_util.ParseChroot(input_proto.chroot)
79 build_targets = controller_util.ParseBuildTargets(input_proto.build_targets)
80 package = controller_util.PackageInfoToCPV(input_proto.package_info)
81 refs = []
82 for ref in input_proto.versions:
83 refs.append(GitRef(path=ref.repository, ref=ref.ref, revision=ref.revision))
84
85 try:
Alex Klein34afcbc2019-08-22 16:14:31 -060086 result = packages.uprev_versioned_package(package, build_targets, refs,
87 chroot)
Alex Klein87531182019-08-12 15:23:37 -060088 except packages.Error as e:
89 # Handle module errors nicely, let everything else bubble up.
Mike Frysinger6b5c3cd2019-08-27 16:51:00 -040090 cros_build_lib.Die(e)
Alex Klein87531182019-08-12 15:23:37 -060091
Alex Klein16ea1b32021-10-01 15:48:50 -060092 for modified in result.modified:
93 uprev_response = output_proto.responses.add()
94 uprev_response.version = modified.new_version
95 for path in modified.files:
96 uprev_response.modified_ebuilds.add().path = path
97
98
99@faux.success(_UprevVersionedPackageResponse)
100@faux.empty_error
101@validate.validation_complete
102def RevBumpChrome(_input_proto, output_proto, _config):
103 result = packages.revbump_chrome()
Alex Klein34afcbc2019-08-22 16:14:31 -0600104
Yaakov Shaul730814a2019-09-10 13:58:25 -0600105 for modified in result.modified:
106 uprev_response = output_proto.responses.add()
107 uprev_response.version = modified.new_version
108 for path in modified.files:
109 uprev_response.modified_ebuilds.add().path = path
110
Alex Klein87531182019-08-12 15:23:37 -0600111
Michael Mortensen2677bf62019-10-29 08:31:25 -0600112def _GetBestVisibleResponse(_input_proto, output_proto, _config):
113 """Add fake paths to a successful GetBestVisible response."""
Alex Klein6becabc2020-09-11 14:03:05 -0600114 pkg_info_msg = common_pb2.PackageInfo(
Michael Mortensen2677bf62019-10-29 08:31:25 -0600115 category='category',
116 package_name='name',
117 version='1.01',
118 )
Alex Klein6becabc2020-09-11 14:03:05 -0600119 output_proto.package_info.CopyFrom(pkg_info_msg)
Michael Mortensen2677bf62019-10-29 08:31:25 -0600120
121
122@faux.success(_GetBestVisibleResponse)
123@faux.empty_error
David Burger1e0fe232019-07-01 14:52:07 -0600124@validate.require('atom')
Alex Klein231d2da2019-07-22 16:44:45 -0600125@validate.validation_complete
126def GetBestVisible(input_proto, output_proto, _config):
David Burger1e0fe232019-07-01 14:52:07 -0600127 """Returns the best visible PackageInfo for the indicated atom."""
Alex Kleinbbef2b32019-08-27 10:38:50 -0600128 build_target = None
129 if input_proto.build_target.name:
130 build_target = controller_util.ParseBuildTarget(input_proto.build_target)
131
Alex Klein5caab872021-09-10 11:44:37 -0600132 best = packages.get_best_visible(input_proto.atom, build_target=build_target)
133 controller_util.serialize_package_info(best, output_proto.package_info)
Alex Klein551e8052019-08-29 11:23:48 -0600134
135
Michael Mortensen68abdb72019-10-28 09:43:52 -0600136def _ChromeVersionResponse(_input_proto, output_proto, _config):
137 """Add a fake chrome version to a successful response."""
138 output_proto.version = '78.0.3900.0'
139
140
141@faux.success(_ChromeVersionResponse)
142@faux.empty_error
Alex Klein551e8052019-08-29 11:23:48 -0600143@validate.require('build_target.name')
144@validate.validation_complete
145def GetChromeVersion(input_proto, output_proto, _config):
146 """Returns the chrome version."""
147 build_target = controller_util.ParseBuildTarget(input_proto.build_target)
Michael Mortensen9fe740c2019-10-29 14:42:48 -0600148 chrome_version = packages.determine_chrome_version(build_target)
149 if chrome_version:
150 output_proto.version = chrome_version
Alex Kleinda39c6d2019-09-16 14:36:36 -0600151
152
Michael Mortensen2677bf62019-10-29 08:31:25 -0600153def _GetTargetVersionsResponse(_input_proto, output_proto, _config):
154 """Add fake target version fields to a successful response."""
155 output_proto.android_version = '5812377'
156 output_proto.android_branch_version = 'git_nyc-mr1-arc'
157 output_proto.android_target_version = 'cheets'
158 output_proto.chrome_version = '78.0.3900.0'
159 output_proto.platform_version = '12438.0.0'
160 output_proto.milestone_version = '78'
161 output_proto.full_version = 'R78-12438.0.0'
162
163
164@faux.success(_GetTargetVersionsResponse)
165@faux.empty_error
Michael Mortensenb70e8a82019-10-10 18:43:41 -0600166@validate.require('build_target.name')
Alex Klein45b73432020-09-23 13:51:20 -0600167@validate.require_each('packages', ['category', 'package_name'])
Michael Mortensenb70e8a82019-10-10 18:43:41 -0600168@validate.validation_complete
169def GetTargetVersions(input_proto, output_proto, _config):
170 """Returns the target versions."""
171 build_target = controller_util.ParseBuildTarget(input_proto.build_target)
Alex Klein5a008442021-11-08 11:30:12 -0700172 package_list = [
173 controller_util.PackageInfoToCPV(x) for x in input_proto.packages or []
174 ]
175 target_versions = packages.get_target_versions(build_target, package_list)
Alex Klein445ae3c2020-01-08 16:40:43 -0700176
Alex Klein5a008442021-11-08 11:30:12 -0700177 output_proto.android_version = target_versions.android_version or ''
178 output_proto.android_branch_version = target_versions.android_branch or ''
179 output_proto.android_target_version = target_versions.android_target or ''
180 output_proto.chrome_version = target_versions.chrome_version or ''
181 output_proto.platform_version = target_versions.platform_version or ''
182 output_proto.milestone_version = target_versions.milestone_version or ''
183 output_proto.full_version = target_versions.full_version or ''
Michael Mortensenb70e8a82019-10-10 18:43:41 -0600184
185
Michael Mortensenbfc56392020-04-30 15:23:47 -0600186def _GetBuilderMetadataResponse(input_proto, output_proto, _config):
187 """Add fake metadata fields to a successful response."""
188 # Populate only a few fields to validate faux testing.
189 build_target_metadata = output_proto.build_target_metadata.add()
190 build_target_metadata.build_target = input_proto.build_target.name
191 build_target_metadata.android_container_branch = 'git_pi-arc'
192 model_metadata = output_proto.model_metadata.add()
193 model_metadata.model_name = 'astronaut'
194 model_metadata.ec_firmware_version = 'coral_v1.1.1234-56789f'
195
196
197@faux.success(_GetBuilderMetadataResponse)
198@faux.empty_error
199@validate.require('build_target.name')
200@validate.validation_complete
201def GetBuilderMetadata(input_proto, output_proto, _config):
202 """Returns the target builder metadata."""
203 build_target = controller_util.ParseBuildTarget(input_proto.build_target)
204 build_target_metadata = output_proto.build_target_metadata.add()
205 build_target_metadata.build_target = build_target.name
Michael Mortensenbbce7e42020-05-01 15:03:49 -0600206 # Android version.
Mike Frysingerb53f1822021-03-05 00:44:50 -0500207 android_version = packages.determine_android_version(build_target.name)
Michael Mortensenbbce7e42020-05-01 15:03:49 -0600208 logging.info('Found android version: %s', android_version)
209 if android_version:
210 build_target_metadata.android_container_version = android_version
211 # Android branch version.
Michael Mortensen027ecd82020-05-05 13:13:40 -0600212 android_branch_version = packages.determine_android_branch(build_target.name)
Michael Mortensenbbce7e42020-05-01 15:03:49 -0600213 logging.info('Found android branch version: %s', android_branch_version)
214 if android_branch_version:
215 build_target_metadata.android_container_branch = android_branch_version
216 # Android target version.
Michael Mortensen027ecd82020-05-05 13:13:40 -0600217 android_target_version = packages.determine_android_target(build_target.name)
Michael Mortensenbbce7e42020-05-01 15:03:49 -0600218 logging.info('Found android target version: %s', android_target_version)
219 if android_target_version:
220 build_target_metadata.android_container_target = android_target_version
221
222 build_target_metadata.arc_use_set = 'arc' in portage_util.GetBoardUseFlags(
223 build_target.name)
224
Michael Mortensena4af79e2020-05-06 16:18:48 -0600225 fw_versions = packages.determine_firmware_versions(build_target)
Benjamin Shai0858cd32022-01-10 20:23:49 +0000226 if fw_versions:
227 build_target_metadata.main_firmware_version = fw_versions.main_fw_version
228 build_target_metadata.ec_firmware_version = fw_versions.ec_fw_version
229
Michael Mortensenfbf2b2d2020-05-14 16:33:06 -0600230 build_target_metadata.kernel_version = packages.determine_kernel_version(
Alex Klein3bb171a2022-05-09 17:27:00 -0600231 build_target) or ''
Michael Mortensend81d81e2020-06-09 14:20:59 -0600232 fingerprints = packages.find_fingerprints(build_target)
233 build_target_metadata.fingerprints.extend(fingerprints)
Michael Mortensenbfc56392020-04-30 15:23:47 -0600234
Michael Mortensen770bc122020-05-27 17:53:30 -0600235 models = packages.get_models(build_target)
236 if models:
237 all_fw_versions = packages.get_all_firmware_versions(build_target)
238 for model in models:
239 if model in all_fw_versions:
240 fw_versions = all_fw_versions[model]
241 ec = fw_versions.ec_rw or fw_versions.ec
242 main_ro = fw_versions.main
243 main_rw = fw_versions.main_rw or main_ro
244 # Get the firmware key-id for the current board and model.
245 key_id = packages.get_key_id(build_target, model)
246 model_metadata = output_proto.model_metadata.add()
247 model_metadata.model_name = model
248 model_metadata.ec_firmware_version = ec
249 model_metadata.firmware_key_id = key_id
250 model_metadata.main_readonly_firmware_version = main_ro
251 model_metadata.main_readwrite_firmware_version = main_rw
252
253
Alex Klein7d66c092020-03-23 15:13:18 -0600254def _HasPrebuiltSuccess(_input_proto, output_proto, _config):
Michael Mortensen68abdb72019-10-28 09:43:52 -0600255 """The mock success case for HasChromePrebuilt."""
256 output_proto.has_prebuilt = True
257
258
Alex Klein7d66c092020-03-23 15:13:18 -0600259@faux.success(_HasPrebuiltSuccess)
Alex Kleinda39c6d2019-09-16 14:36:36 -0600260@faux.empty_error
261@validate.require('build_target.name')
262@validate.validation_complete
263def HasChromePrebuilt(input_proto, output_proto, _config):
264 """Checks if the most recent version of Chrome has a prebuilt."""
265 build_target = controller_util.ParseBuildTarget(input_proto.build_target)
Alex Klein149fd3b2019-12-16 16:01:05 -0700266 useflags = 'chrome_internal' if input_proto.chrome else None
267 exists = packages.has_prebuilt(constants.CHROME_CP, build_target=build_target,
268 useflags=useflags)
Alex Kleinda39c6d2019-09-16 14:36:36 -0600269
270 output_proto.has_prebuilt = exists
Alex Klein73fb6572019-09-30 16:55:23 -0600271
272
Alex Klein7d66c092020-03-23 15:13:18 -0600273@faux.success(_HasPrebuiltSuccess)
274@faux.empty_error
George Engelbrechtfce26aa2020-03-23 20:53:41 -0600275@validate.require('build_target.name', 'package_info.category',
276 'package_info.package_name')
Alex Klein7d66c092020-03-23 15:13:18 -0600277@validate.validation_complete
278def HasPrebuilt(input_proto, output_proto, _config):
279 """Checks if the most recent version of Chrome has a prebuilt."""
280 build_target = controller_util.ParseBuildTarget(input_proto.build_target)
281 package = controller_util.PackageInfoToCPV(input_proto.package_info).cp
282 useflags = 'chrome_internal' if input_proto.chrome else None
283 exists = packages.has_prebuilt(
284 package, build_target=build_target, useflags=useflags)
285
286 output_proto.has_prebuilt = exists
287
288
Alex Klein73fb6572019-09-30 16:55:23 -0600289def _BuildsChromeSuccess(_input_proto, output_proto, _config):
290 """Mock success case for BuildsChrome."""
291 output_proto.builds_chrome = True
292
293
294@faux.success(_BuildsChromeSuccess)
295@faux.empty_error
296@validate.require('build_target.name')
Alex Klein45b73432020-09-23 13:51:20 -0600297@validate.require_each('packages', ['category', 'package_name'])
Alex Klein73fb6572019-09-30 16:55:23 -0600298@validate.validation_complete
299def BuildsChrome(input_proto, output_proto, _config):
300 """Check if the board builds chrome."""
Alex Kleine65131f2019-10-03 10:34:01 -0600301 build_target = controller_util.ParseBuildTarget(input_proto.build_target)
David Burger0f9dd4e2019-10-08 12:33:42 -0600302 cpvs = [controller_util.PackageInfoToCPV(pi) for pi in input_proto.packages]
303 builds_chrome = packages.builds(constants.CHROME_CP, build_target, cpvs)
Alex Kleine65131f2019-10-03 10:34:01 -0600304 output_proto.builds_chrome = builds_chrome
Alex Klein6becabc2020-09-11 14:03:05 -0600305
306
307def _NeedsChromeSourceSuccess(_input_proto, output_proto, _config):
308 """Mock success case for NeedsChromeSource."""
309 output_proto.needs_chrome_source = True
310 output_proto.builds_chrome = True
311
312 output_proto.reasons.append(
313 packages_pb2.NeedsChromeSourceResponse.NO_PREBUILT)
314 pkg_info_msg = output_proto.packages.add()
315 pkg_info_msg.category = constants.CHROME_CN
316 pkg_info_msg.package_name = constants.CHROME_PN
317
318 output_proto.reasons.append(
319 packages_pb2.NeedsChromeSourceResponse.FOLLOWER_LACKS_PREBUILT)
320 for pkg in constants.OTHER_CHROME_PACKAGES:
321 pkg_info_msg = output_proto.packages.add()
322 pkg_info = package_info.parse(pkg)
323 controller_util.serialize_package_info(pkg_info, pkg_info_msg)
324
325
326@faux.success(_NeedsChromeSourceSuccess)
327@faux.empty_error
328@validate.require('install_request.sysroot.build_target.name')
329@validate.exists('install_request.sysroot.path')
330@validate.validation_complete
331def NeedsChromeSource(input_proto, output_proto, _config):
332 """Check if the build will need the chrome source."""
333 # Input parsing.
334 build_target = controller_util.ParseBuildTarget(
335 input_proto.install_request.sysroot.build_target)
Mike Frysingercf36bb02021-03-05 01:37:20 -0500336 compile_source = (input_proto.install_request.flags.compile_source or
337 input_proto.install_request.flags.toolchain_changed)
Alex Klein6becabc2020-09-11 14:03:05 -0600338 pkgs = [controller_util.deserialize_package_info(pi) for pi in
339 input_proto.install_request.packages]
Alex Kleina8052162021-02-03 14:28:22 -0700340 use_flags = [f.flag for f in input_proto.install_request.use_flags]
Alex Klein6becabc2020-09-11 14:03:05 -0600341
342 result = packages.needs_chrome_source(
343 build_target,
344 compile_source=compile_source,
345 packages=pkgs,
346 useflags=use_flags)
347
348 # Record everything in the response.
349 output_proto.needs_chrome_source = result.needs_chrome_source
350 output_proto.builds_chrome = result.builds_chrome
351
352 # Compile source reason.
353 if compile_source:
354 output_proto.reasons.append(
355 packages_pb2.NeedsChromeSourceResponse.COMPILE_SOURCE)
356
Alex Klein9ce3f682021-06-23 15:06:44 -0600357 # Local uprev reason.
358 if result.local_uprev:
359 output_proto.reasons.append(
360 packages_pb2.NeedsChromeSourceResponse.LOCAL_UPREV)
361
Alex Klein6becabc2020-09-11 14:03:05 -0600362 # No chrome prebuilt reason.
363 if result.missing_chrome_prebuilt:
364 output_proto.reasons.append(
365 packages_pb2.NeedsChromeSourceResponse.NO_PREBUILT)
366
367 # Follower package(s) lack prebuilt reason.
368 if result.missing_follower_prebuilt:
369 output_proto.reasons.append(
370 packages_pb2.NeedsChromeSourceResponse.FOLLOWER_LACKS_PREBUILT)
371
372 for pkg in result.packages:
373 pkg_info = output_proto.packages.add()
374 controller_util.serialize_package_info(pkg, pkg_info)
Shao-Chuan Leeeb834a32021-05-12 17:10:55 +0900375
376
377def _GetAndroidMetadataResponse(_input_proto, output_proto, _config):
378 """Mock Android metadata on successful run."""
379 output_proto.android_package = 'android-vm-rvc'
380 output_proto.android_branch = 'git_rvc-arc'
381 output_proto.android_version = '7123456'
382
383
384@faux.success(_GetAndroidMetadataResponse)
385@faux.empty_error
386@validate.require('build_target.name')
387@validate.validation_complete
388def GetAndroidMetadata(input_proto, output_proto, _config):
389 """Returns Android-related metadata."""
390 build_target = controller_util.ParseBuildTarget(input_proto.build_target)
391 # This returns a full CPVR string, e.g.
392 # 'chromeos-base/android-vm-rvc-7336577-r1'
393 android_full_package = packages.determine_android_package(build_target.name)
394 if android_full_package:
395 logging.info('Found Android package: %s', android_full_package)
396 info = package_info.parse(android_full_package)
397 output_proto.android_package = info.package
398
399 android_branch = packages.determine_android_branch(
400 build_target.name, package=android_full_package)
401 logging.info('Found Android branch: %s', android_branch)
402 output_proto.android_branch = android_branch
403
404 android_version = packages.determine_android_version(
405 build_target.name, package=android_full_package)
406 logging.info('Found Android version: %s', android_version)
407 output_proto.android_version = android_version