blob: 93ce232c01c86d68aad304ab9766638e4cae52ee [file] [log] [blame]
Alex Kleineb77ffa2019-05-28 14:47:44 -06001# -*- coding: utf-8 -*-
2# Copyright 2019 The Chromium OS Authors. All rights reserved.
3# Use of this source code is governed by a BSD-style license that can be
4# found in the LICENSE file.
5
6"""Package related functionality."""
7
8from __future__ import print_function
9
Alex Klein076841b2019-08-29 15:19:39 -060010from chromite.api import faux
David Burger1e0fe232019-07-01 14:52:07 -060011from chromite.api import validate
Alex Kleineb77ffa2019-05-28 14:47:44 -060012from chromite.api.controller import controller_util
13from chromite.api.gen.chromite.api import binhost_pb2
Alex Klein6becabc2020-09-11 14:03:05 -060014from chromite.api.gen.chromite.api import packages_pb2
David Burger1e0fe232019-07-01 14:52:07 -060015from chromite.api.gen.chromiumos import common_pb2
Alex Kleineb77ffa2019-05-28 14:47:44 -060016from chromite.lib import constants
17from chromite.lib import cros_build_lib
Alex Klein445ae3c2020-01-08 16:40:43 -070018from chromite.lib import cros_logging as logging
Michael Mortensenbbce7e42020-05-01 15:03:49 -060019from chromite.lib import portage_util
Alex Klein87531182019-08-12 15:23:37 -060020from chromite.lib.uprev_lib import GitRef
Alex Klein6becabc2020-09-11 14:03:05 -060021from chromite.lib.parser import package_info
Alex Kleineb77ffa2019-05-28 14:47:44 -060022from chromite.service import packages
23
24
25_OVERLAY_TYPE_TO_NAME = {
26 binhost_pb2.OVERLAYTYPE_PUBLIC: constants.PUBLIC_OVERLAYS,
27 binhost_pb2.OVERLAYTYPE_PRIVATE: constants.PRIVATE_OVERLAYS,
28 binhost_pb2.OVERLAYTYPE_BOTH: constants.BOTH_OVERLAYS,
29}
30
Michael Mortensen2677bf62019-10-29 08:31:25 -060031def _UprevResponse(_input_proto, output_proto, _config):
32 """Add fake paths to a successful uprev response."""
33 output_proto.modified_ebuilds.add().path = '/fake/path1'
34 output_proto.modified_ebuilds.add().path = '/fake/path2'
Alex Kleineb77ffa2019-05-28 14:47:44 -060035
Michael Mortensen2677bf62019-10-29 08:31:25 -060036@faux.success(_UprevResponse)
37@faux.empty_error
Alex Klein231d2da2019-07-22 16:44:45 -060038@validate.require('overlay_type')
39@validate.is_in('overlay_type', _OVERLAY_TYPE_TO_NAME)
40@validate.validation_complete
41def Uprev(input_proto, output_proto, _config):
Alex Kleineb77ffa2019-05-28 14:47:44 -060042 """Uprev all cros workon ebuilds that have changes."""
Alex Klein26e472b2020-03-10 14:35:01 -060043 build_targets = controller_util.ParseBuildTargets(input_proto.build_targets)
Alex Kleineb77ffa2019-05-28 14:47:44 -060044 overlay_type = _OVERLAY_TYPE_TO_NAME[input_proto.overlay_type]
45 chroot = controller_util.ParseChroot(input_proto.chroot)
46 output_dir = input_proto.output_dir or None
47
48 try:
Alex Klein5dd6b1e2019-07-31 15:45:24 -060049 uprevved = packages.uprev_build_targets(build_targets, overlay_type, chroot,
50 output_dir)
Alex Kleineb77ffa2019-05-28 14:47:44 -060051 except packages.Error as e:
52 # Handle module errors nicely, let everything else bubble up.
Mike Frysinger6b5c3cd2019-08-27 16:51:00 -040053 cros_build_lib.Die(e)
David Burger1e0fe232019-07-01 14:52:07 -060054
Alex Klein5dd6b1e2019-07-31 15:45:24 -060055 for path in uprevved:
56 output_proto.modified_ebuilds.add().path = path
57
Alex Klein231d2da2019-07-22 16:44:45 -060058
Michael Mortensen2677bf62019-10-29 08:31:25 -060059def _UprevVersionedPackageResponse(_input_proto, output_proto, _config):
60 """Add fake paths to a successful uprev versioned package response."""
61 uprev_response = output_proto.responses.add()
62 uprev_response.modified_ebuilds.add().path = '/uprev/response/path'
63
64
65@faux.success(_UprevVersionedPackageResponse)
66@faux.empty_error
Alex Klein87531182019-08-12 15:23:37 -060067@validate.require('versions')
68@validate.require('package_info.package_name', 'package_info.category')
Alex Klein231d2da2019-07-22 16:44:45 -060069@validate.validation_complete
Alex Klein87531182019-08-12 15:23:37 -060070def UprevVersionedPackage(input_proto, output_proto, _config):
Evan Hernandez38555d42019-08-05 15:11:54 -060071 """Uprev a versioned package.
72
73 See go/pupr-generator for details about this endpoint.
74 """
Alex Klein87531182019-08-12 15:23:37 -060075 chroot = controller_util.ParseChroot(input_proto.chroot)
76 build_targets = controller_util.ParseBuildTargets(input_proto.build_targets)
77 package = controller_util.PackageInfoToCPV(input_proto.package_info)
78 refs = []
79 for ref in input_proto.versions:
80 refs.append(GitRef(path=ref.repository, ref=ref.ref, revision=ref.revision))
81
82 try:
Alex Klein34afcbc2019-08-22 16:14:31 -060083 result = packages.uprev_versioned_package(package, build_targets, refs,
84 chroot)
Alex Klein87531182019-08-12 15:23:37 -060085 except packages.Error as e:
86 # Handle module errors nicely, let everything else bubble up.
Mike Frysinger6b5c3cd2019-08-27 16:51:00 -040087 cros_build_lib.Die(e)
Alex Klein87531182019-08-12 15:23:37 -060088
Alex Klein34afcbc2019-08-22 16:14:31 -060089 if not result.uprevved:
90 # No uprevs executed, skip the output population.
91 return
92
Yaakov Shaul730814a2019-09-10 13:58:25 -060093 for modified in result.modified:
94 uprev_response = output_proto.responses.add()
95 uprev_response.version = modified.new_version
96 for path in modified.files:
97 uprev_response.modified_ebuilds.add().path = path
98
Alex Klein87531182019-08-12 15:23:37 -060099
Michael Mortensen2677bf62019-10-29 08:31:25 -0600100def _GetBestVisibleResponse(_input_proto, output_proto, _config):
101 """Add fake paths to a successful GetBestVisible response."""
Alex Klein6becabc2020-09-11 14:03:05 -0600102 pkg_info_msg = common_pb2.PackageInfo(
Michael Mortensen2677bf62019-10-29 08:31:25 -0600103 category='category',
104 package_name='name',
105 version='1.01',
106 )
Alex Klein6becabc2020-09-11 14:03:05 -0600107 output_proto.package_info.CopyFrom(pkg_info_msg)
Michael Mortensen2677bf62019-10-29 08:31:25 -0600108
109
110@faux.success(_GetBestVisibleResponse)
111@faux.empty_error
David Burger1e0fe232019-07-01 14:52:07 -0600112@validate.require('atom')
Alex Klein231d2da2019-07-22 16:44:45 -0600113@validate.validation_complete
114def GetBestVisible(input_proto, output_proto, _config):
David Burger1e0fe232019-07-01 14:52:07 -0600115 """Returns the best visible PackageInfo for the indicated atom."""
Alex Kleinbbef2b32019-08-27 10:38:50 -0600116 build_target = None
117 if input_proto.build_target.name:
118 build_target = controller_util.ParseBuildTarget(input_proto.build_target)
119
120 cpv = packages.get_best_visible(input_proto.atom, build_target=build_target)
Alex Klein6becabc2020-09-11 14:03:05 -0600121 pkg_info_msg = common_pb2.PackageInfo()
122 controller_util.CPVToPackageInfo(cpv, pkg_info_msg)
123 output_proto.package_info.CopyFrom(pkg_info_msg)
Alex Klein551e8052019-08-29 11:23:48 -0600124
125
Michael Mortensen68abdb72019-10-28 09:43:52 -0600126def _ChromeVersionResponse(_input_proto, output_proto, _config):
127 """Add a fake chrome version to a successful response."""
128 output_proto.version = '78.0.3900.0'
129
130
131@faux.success(_ChromeVersionResponse)
132@faux.empty_error
Alex Klein551e8052019-08-29 11:23:48 -0600133@validate.require('build_target.name')
134@validate.validation_complete
135def GetChromeVersion(input_proto, output_proto, _config):
136 """Returns the chrome version."""
137 build_target = controller_util.ParseBuildTarget(input_proto.build_target)
Michael Mortensen9fe740c2019-10-29 14:42:48 -0600138 chrome_version = packages.determine_chrome_version(build_target)
139 if chrome_version:
140 output_proto.version = chrome_version
Alex Kleinda39c6d2019-09-16 14:36:36 -0600141
142
Michael Mortensen2677bf62019-10-29 08:31:25 -0600143def _GetTargetVersionsResponse(_input_proto, output_proto, _config):
144 """Add fake target version fields to a successful response."""
145 output_proto.android_version = '5812377'
146 output_proto.android_branch_version = 'git_nyc-mr1-arc'
147 output_proto.android_target_version = 'cheets'
148 output_proto.chrome_version = '78.0.3900.0'
149 output_proto.platform_version = '12438.0.0'
150 output_proto.milestone_version = '78'
151 output_proto.full_version = 'R78-12438.0.0'
152
153
154@faux.success(_GetTargetVersionsResponse)
155@faux.empty_error
Michael Mortensenb70e8a82019-10-10 18:43:41 -0600156@validate.require('build_target.name')
Alex Klein45b73432020-09-23 13:51:20 -0600157@validate.require_each('packages', ['category', 'package_name'])
Michael Mortensenb70e8a82019-10-10 18:43:41 -0600158@validate.validation_complete
159def GetTargetVersions(input_proto, output_proto, _config):
160 """Returns the target versions."""
161 build_target = controller_util.ParseBuildTarget(input_proto.build_target)
Alex Klein445ae3c2020-01-08 16:40:43 -0700162 # Android version.
Michael Mortensen027ecd82020-05-05 13:13:40 -0600163 android_version = packages.determine_android_version([build_target.name])
Alex Klein445ae3c2020-01-08 16:40:43 -0700164 logging.info('Found android version: %s', android_version)
Michael Mortensenedf76532019-10-16 14:22:37 -0600165 if android_version:
166 output_proto.android_version = android_version
Alex Klein445ae3c2020-01-08 16:40:43 -0700167 # Android branch version.
Michael Mortensen027ecd82020-05-05 13:13:40 -0600168 android_branch_version = packages.determine_android_branch(build_target.name)
Alex Klein445ae3c2020-01-08 16:40:43 -0700169 logging.info('Found android branch version: %s', android_branch_version)
Michael Mortensenedf76532019-10-16 14:22:37 -0600170 if android_branch_version:
171 output_proto.android_branch_version = android_branch_version
Alex Klein445ae3c2020-01-08 16:40:43 -0700172 # Android target version.
Michael Mortensen027ecd82020-05-05 13:13:40 -0600173 android_target_version = packages.determine_android_target(build_target.name)
Alex Klein445ae3c2020-01-08 16:40:43 -0700174 logging.info('Found android target version: %s', android_target_version)
Michael Mortensenedf76532019-10-16 14:22:37 -0600175 if android_target_version:
176 output_proto.android_target_version = android_target_version
Alex Klein445ae3c2020-01-08 16:40:43 -0700177
Michael Mortensen9fe740c2019-10-29 14:42:48 -0600178 # TODO(crbug/1019770): Investigate cases where builds_chrome is true but
179 # chrome_version is None.
Michael Mortensen42c330e32020-09-02 09:59:16 -0600180
181 # If input_proto.packages is empty, then the default set of packages will
182 # be used as defined in dependency.GetBuildDependency.
183 package_list = None
184 if input_proto.packages:
185 package_list = [
186 controller_util.PackageInfoToCPV(x) for x in input_proto.packages
187 ]
188 builds_chrome = packages.builds(constants.CHROME_CP, build_target,
189 packages=package_list)
Michael Mortensen1d2ab0d2019-10-17 13:19:25 -0600190 if builds_chrome:
Alex Klein445ae3c2020-01-08 16:40:43 -0700191 # Chrome version fetch.
Michael Mortensen9fe740c2019-10-29 14:42:48 -0600192 chrome_version = packages.determine_chrome_version(build_target)
Alex Klein445ae3c2020-01-08 16:40:43 -0700193 logging.info('Found chrome version: %s', chrome_version)
Michael Mortensen9fe740c2019-10-29 14:42:48 -0600194 if chrome_version:
195 output_proto.chrome_version = chrome_version
Alex Klein445ae3c2020-01-08 16:40:43 -0700196
197 # The ChromeOS version info.
Michael Mortensen9fdb14b2019-10-17 11:17:30 -0600198 output_proto.platform_version = packages.determine_platform_version()
Michael Mortensen009cb662019-10-21 11:38:43 -0600199 output_proto.milestone_version = packages.determine_milestone_version()
200 output_proto.full_version = packages.determine_full_version()
Michael Mortensenb70e8a82019-10-10 18:43:41 -0600201
202
Michael Mortensenbfc56392020-04-30 15:23:47 -0600203def _GetBuilderMetadataResponse(input_proto, output_proto, _config):
204 """Add fake metadata fields to a successful response."""
205 # Populate only a few fields to validate faux testing.
206 build_target_metadata = output_proto.build_target_metadata.add()
207 build_target_metadata.build_target = input_proto.build_target.name
208 build_target_metadata.android_container_branch = 'git_pi-arc'
209 model_metadata = output_proto.model_metadata.add()
210 model_metadata.model_name = 'astronaut'
211 model_metadata.ec_firmware_version = 'coral_v1.1.1234-56789f'
212
213
214@faux.success(_GetBuilderMetadataResponse)
215@faux.empty_error
216@validate.require('build_target.name')
217@validate.validation_complete
218def GetBuilderMetadata(input_proto, output_proto, _config):
219 """Returns the target builder metadata."""
220 build_target = controller_util.ParseBuildTarget(input_proto.build_target)
221 build_target_metadata = output_proto.build_target_metadata.add()
222 build_target_metadata.build_target = build_target.name
Michael Mortensenbbce7e42020-05-01 15:03:49 -0600223 # Android version.
Michael Mortensen027ecd82020-05-05 13:13:40 -0600224 android_version = packages.determine_android_version([build_target.name])
Michael Mortensenbbce7e42020-05-01 15:03:49 -0600225 logging.info('Found android version: %s', android_version)
226 if android_version:
227 build_target_metadata.android_container_version = android_version
228 # Android branch version.
Michael Mortensen027ecd82020-05-05 13:13:40 -0600229 android_branch_version = packages.determine_android_branch(build_target.name)
Michael Mortensenbbce7e42020-05-01 15:03:49 -0600230 logging.info('Found android branch version: %s', android_branch_version)
231 if android_branch_version:
232 build_target_metadata.android_container_branch = android_branch_version
233 # Android target version.
Michael Mortensen027ecd82020-05-05 13:13:40 -0600234 android_target_version = packages.determine_android_target(build_target.name)
Michael Mortensenbbce7e42020-05-01 15:03:49 -0600235 logging.info('Found android target version: %s', android_target_version)
236 if android_target_version:
237 build_target_metadata.android_container_target = android_target_version
238
239 build_target_metadata.arc_use_set = 'arc' in portage_util.GetBoardUseFlags(
240 build_target.name)
241
Michael Mortensena4af79e2020-05-06 16:18:48 -0600242 fw_versions = packages.determine_firmware_versions(build_target)
243 build_target_metadata.main_firmware_version = fw_versions.main_fw_version
244 build_target_metadata.ec_firmware_version = fw_versions.ec_fw_version
Michael Mortensenfbf2b2d2020-05-14 16:33:06 -0600245 build_target_metadata.kernel_version = packages.determine_kernel_version(
246 build_target)
Michael Mortensend81d81e2020-06-09 14:20:59 -0600247 fingerprints = packages.find_fingerprints(build_target)
248 build_target_metadata.fingerprints.extend(fingerprints)
Michael Mortensenbfc56392020-04-30 15:23:47 -0600249
Michael Mortensen770bc122020-05-27 17:53:30 -0600250 models = packages.get_models(build_target)
251 if models:
252 all_fw_versions = packages.get_all_firmware_versions(build_target)
253 for model in models:
254 if model in all_fw_versions:
255 fw_versions = all_fw_versions[model]
256 ec = fw_versions.ec_rw or fw_versions.ec
257 main_ro = fw_versions.main
258 main_rw = fw_versions.main_rw or main_ro
259 # Get the firmware key-id for the current board and model.
260 key_id = packages.get_key_id(build_target, model)
261 model_metadata = output_proto.model_metadata.add()
262 model_metadata.model_name = model
263 model_metadata.ec_firmware_version = ec
264 model_metadata.firmware_key_id = key_id
265 model_metadata.main_readonly_firmware_version = main_ro
266 model_metadata.main_readwrite_firmware_version = main_rw
267
268
Alex Klein7d66c092020-03-23 15:13:18 -0600269def _HasPrebuiltSuccess(_input_proto, output_proto, _config):
Michael Mortensen68abdb72019-10-28 09:43:52 -0600270 """The mock success case for HasChromePrebuilt."""
271 output_proto.has_prebuilt = True
272
273
Alex Klein7d66c092020-03-23 15:13:18 -0600274@faux.success(_HasPrebuiltSuccess)
Alex Kleinda39c6d2019-09-16 14:36:36 -0600275@faux.empty_error
276@validate.require('build_target.name')
277@validate.validation_complete
278def HasChromePrebuilt(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)
Alex Klein149fd3b2019-12-16 16:01:05 -0700281 useflags = 'chrome_internal' if input_proto.chrome else None
282 exists = packages.has_prebuilt(constants.CHROME_CP, build_target=build_target,
283 useflags=useflags)
Alex Kleinda39c6d2019-09-16 14:36:36 -0600284
285 output_proto.has_prebuilt = exists
Alex Klein73fb6572019-09-30 16:55:23 -0600286
287
Alex Klein7d66c092020-03-23 15:13:18 -0600288@faux.success(_HasPrebuiltSuccess)
289@faux.empty_error
George Engelbrechtfce26aa2020-03-23 20:53:41 -0600290@validate.require('build_target.name', 'package_info.category',
291 'package_info.package_name')
Alex Klein7d66c092020-03-23 15:13:18 -0600292@validate.validation_complete
293def HasPrebuilt(input_proto, output_proto, _config):
294 """Checks if the most recent version of Chrome has a prebuilt."""
295 build_target = controller_util.ParseBuildTarget(input_proto.build_target)
296 package = controller_util.PackageInfoToCPV(input_proto.package_info).cp
297 useflags = 'chrome_internal' if input_proto.chrome else None
298 exists = packages.has_prebuilt(
299 package, build_target=build_target, useflags=useflags)
300
301 output_proto.has_prebuilt = exists
302
303
Alex Klein73fb6572019-09-30 16:55:23 -0600304def _BuildsChromeSuccess(_input_proto, output_proto, _config):
305 """Mock success case for BuildsChrome."""
306 output_proto.builds_chrome = True
307
308
309@faux.success(_BuildsChromeSuccess)
310@faux.empty_error
311@validate.require('build_target.name')
Alex Klein45b73432020-09-23 13:51:20 -0600312@validate.require_each('packages', ['category', 'package_name'])
Alex Klein73fb6572019-09-30 16:55:23 -0600313@validate.validation_complete
314def BuildsChrome(input_proto, output_proto, _config):
315 """Check if the board builds chrome."""
Alex Kleine65131f2019-10-03 10:34:01 -0600316 build_target = controller_util.ParseBuildTarget(input_proto.build_target)
David Burger0f9dd4e2019-10-08 12:33:42 -0600317 cpvs = [controller_util.PackageInfoToCPV(pi) for pi in input_proto.packages]
318 builds_chrome = packages.builds(constants.CHROME_CP, build_target, cpvs)
Alex Kleine65131f2019-10-03 10:34:01 -0600319 output_proto.builds_chrome = builds_chrome
Alex Klein6becabc2020-09-11 14:03:05 -0600320
321
322def _NeedsChromeSourceSuccess(_input_proto, output_proto, _config):
323 """Mock success case for NeedsChromeSource."""
324 output_proto.needs_chrome_source = True
325 output_proto.builds_chrome = True
326
327 output_proto.reasons.append(
328 packages_pb2.NeedsChromeSourceResponse.NO_PREBUILT)
329 pkg_info_msg = output_proto.packages.add()
330 pkg_info_msg.category = constants.CHROME_CN
331 pkg_info_msg.package_name = constants.CHROME_PN
332
333 output_proto.reasons.append(
334 packages_pb2.NeedsChromeSourceResponse.FOLLOWER_LACKS_PREBUILT)
335 for pkg in constants.OTHER_CHROME_PACKAGES:
336 pkg_info_msg = output_proto.packages.add()
337 pkg_info = package_info.parse(pkg)
338 controller_util.serialize_package_info(pkg_info, pkg_info_msg)
339
340
341@faux.success(_NeedsChromeSourceSuccess)
342@faux.empty_error
343@validate.require('install_request.sysroot.build_target.name')
344@validate.exists('install_request.sysroot.path')
345@validate.validation_complete
346def NeedsChromeSource(input_proto, output_proto, _config):
347 """Check if the build will need the chrome source."""
348 # Input parsing.
349 build_target = controller_util.ParseBuildTarget(
350 input_proto.install_request.sysroot.build_target)
Mike Frysingercf36bb02021-03-05 01:37:20 -0500351 compile_source = (input_proto.install_request.flags.compile_source or
352 input_proto.install_request.flags.toolchain_changed)
Alex Klein6becabc2020-09-11 14:03:05 -0600353 pkgs = [controller_util.deserialize_package_info(pi) for pi in
354 input_proto.install_request.packages]
Alex Kleina8052162021-02-03 14:28:22 -0700355 use_flags = [f.flag for f in input_proto.install_request.use_flags]
Alex Klein6becabc2020-09-11 14:03:05 -0600356
357 result = packages.needs_chrome_source(
358 build_target,
359 compile_source=compile_source,
360 packages=pkgs,
361 useflags=use_flags)
362
363 # Record everything in the response.
364 output_proto.needs_chrome_source = result.needs_chrome_source
365 output_proto.builds_chrome = result.builds_chrome
366
367 # Compile source reason.
368 if compile_source:
369 output_proto.reasons.append(
370 packages_pb2.NeedsChromeSourceResponse.COMPILE_SOURCE)
371
372 # No chrome prebuilt reason.
373 if result.missing_chrome_prebuilt:
374 output_proto.reasons.append(
375 packages_pb2.NeedsChromeSourceResponse.NO_PREBUILT)
376
377 # Follower package(s) lack prebuilt reason.
378 if result.missing_follower_prebuilt:
379 output_proto.reasons.append(
380 packages_pb2.NeedsChromeSourceResponse.FOLLOWER_LACKS_PREBUILT)
381
382 for pkg in result.packages:
383 pkg_info = output_proto.packages.add()
384 controller_util.serialize_package_info(pkg, pkg_info)