blob: 9a809ccd0f858f92aaa44066332ae5b4a0ab6cda [file] [log] [blame]
Tiancong Wangaf050172019-07-10 11:52:03 -07001# -*- 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"""Toolchain-related operations."""
7
8from __future__ import print_function
9
LaMont Jonesb20b3d92019-11-23 11:47:48 -070010import collections
11
LaMont Jones5d2edcb2019-12-23 11:32:03 -070012from chromite.api import controller
Alex Klein076841b2019-08-29 15:19:39 -060013from chromite.api import faux
Alex Klein231d2da2019-07-22 16:44:45 -060014from chromite.api import validate
LaMont Jones5d2edcb2019-12-23 11:32:03 -070015from chromite.api.controller import controller_util
Tiancong Wang24a3df72019-08-20 15:48:51 -070016from chromite.api.gen.chromite.api import toolchain_pb2
LaMont Jonesb20b3d92019-11-23 11:47:48 -070017from chromite.api.gen.chromiumos.builder_config_pb2 import BuilderConfig
LaMont Jones5d2edcb2019-12-23 11:32:03 -070018from chromite.lib import cros_logging as logging
19from chromite.lib import toolchain_util
Tiancong Wangaf050172019-07-10 11:52:03 -070020
LaMont Jonesb20b3d92019-11-23 11:47:48 -070021# TODO(crbug/1019868): Add handlers as needed.
22_Handlers = collections.namedtuple('_Handlers', ['name', 'prepare', 'bundle'])
23_TOOLCHAIN_ARTIFACT_HANDLERS = {
24 BuilderConfig.Artifacts.UNVERIFIED_ORDERING_FILE:
LaMont Jones5d2edcb2019-12-23 11:32:03 -070025 _Handlers('UnverifiedOrderingFile',
26 toolchain_util.PrepareForBuild,
27 toolchain_util.BundleArtifacts),
LaMont Jonesb20b3d92019-11-23 11:47:48 -070028 BuilderConfig.Artifacts.VERIFIED_ORDERING_FILE:
LaMont Jones5d2edcb2019-12-23 11:32:03 -070029 _Handlers('VerifiedOrderingFile',
30 toolchain_util.PrepareForBuild,
31 toolchain_util.BundleArtifacts),
LaMont Jonesb20b3d92019-11-23 11:47:48 -070032 BuilderConfig.Artifacts.CHROME_CLANG_WARNINGS_FILE:
LaMont Jones5d2edcb2019-12-23 11:32:03 -070033 _Handlers('ChromeClangWarningsFile',
LaMont Jones90bab632020-01-27 15:58:26 -070034 toolchain_util.PrepareForBuild,
35 toolchain_util.BundleArtifacts),
LaMont Jonesb20b3d92019-11-23 11:47:48 -070036 BuilderConfig.Artifacts.UNVERIFIED_LLVM_PGO_FILE:
LaMont Jones5d2edcb2019-12-23 11:32:03 -070037 _Handlers('UnverifiedLlvmPgoFile',
LaMont Jones90bab632020-01-27 15:58:26 -070038 toolchain_util.PrepareForBuild,
39 toolchain_util.BundleArtifacts),
LaMont Jonesb20b3d92019-11-23 11:47:48 -070040 BuilderConfig.Artifacts.UNVERIFIED_CHROME_AFDO_FILE:
LaMont Jones5d2edcb2019-12-23 11:32:03 -070041 _Handlers('UnverifiedChromeAfdoFile',
LaMont Jones90bab632020-01-27 15:58:26 -070042 toolchain_util.PrepareForBuild,
43 toolchain_util.BundleArtifacts),
LaMont Jonesb20b3d92019-11-23 11:47:48 -070044 BuilderConfig.Artifacts.VERIFIED_CHROME_AFDO_FILE:
LaMont Jones5d2edcb2019-12-23 11:32:03 -070045 _Handlers('VerifiedChromeAfdoFile',
LaMont Jones90bab632020-01-27 15:58:26 -070046 toolchain_util.PrepareForBuild,
47 toolchain_util.BundleArtifacts),
LaMont Jonesb20b3d92019-11-23 11:47:48 -070048 BuilderConfig.Artifacts.VERIFIED_KERNEL_AFDO_FILE:
LaMont Jones5d2edcb2019-12-23 11:32:03 -070049 _Handlers('VerifiedKernelAfdoFile',
LaMont Jones90bab632020-01-27 15:58:26 -070050 toolchain_util.PrepareForBuild,
51 toolchain_util.BundleArtifacts),
LaMont Jonesb20b3d92019-11-23 11:47:48 -070052}
53
54
55# TODO(crbug/1031213): When @faux is expanded to have more than success/failure,
56# this should be changed.
57@faux.all_empty
LaMont Jones5d2edcb2019-12-23 11:32:03 -070058@validate.require('artifact_types')
59# Note: chroot and sysroot are unspecified the first time that the build_target
60# recipe calls PrepareForBuild. The second time, they are specified. No
61# validation check because "all" values are valid.
LaMont Jonesb20b3d92019-11-23 11:47:48 -070062@validate.validation_complete
63def PrepareForBuild(input_proto, output_proto, _config):
64 """Prepare to build toolchain artifacts.
65
66 The handlers (from _TOOLCHAIN_ARTIFACT_HANDLERS above) are called with:
67 artifact_name (str): name of the artifact type.
LaMont Jones5d2edcb2019-12-23 11:32:03 -070068 chroot (chroot_lib.Chroot): chroot. Will be None if the chroot has not
69 yet been created.
70 sysroot_path (str): sysroot path inside the chroot (e.g., /build/atlas).
71 Will be an empty string if the sysroot has not yet been created.
72 build_target_name (str): name of the build target (e.g., atlas). Will be
73 an empty string if the sysroot has not yet been created.
74 input_artifacts ({(str) name:[str gs_locations]}): locations for possible
75 input artifacts. The handler is expected to know which keys it should
76 be using, and ignore any keys that it does not understand.
LaMont Jonesa215f1e2019-12-06 10:18:58 -070077
78 They locate and modify any ebuilds and/or source required for the artifact
79 being created, then return a value from toolchain_util.PrepareForBuildReturn.
LaMont Jonesb20b3d92019-11-23 11:47:48 -070080
LaMont Jones5d2edcb2019-12-23 11:32:03 -070081 This function sets output_proto.build_relevance to the result.
82
LaMont Jonesb20b3d92019-11-23 11:47:48 -070083 Args:
84 input_proto (PrepareForToolchainBuildRequest): The input proto
85 output_proto (PrepareForToolchainBuildResponse): The output proto
86 _config (api_config.ApiConfig): The API call config.
87 """
LaMont Jones5d2edcb2019-12-23 11:32:03 -070088 if input_proto.chroot.path:
89 chroot = controller_util.ParseChroot(input_proto.chroot)
90 else:
91 chroot = None
LaMont Jones4579e8c2019-12-06 14:20:37 -070092
LaMont Jones5d2edcb2019-12-23 11:32:03 -070093 input_artifacts = collections.defaultdict(list)
94 for art in input_proto.input_artifacts:
95 item = _TOOLCHAIN_ARTIFACT_HANDLERS.get(art.input_artifact_type)
96 if item:
97 input_artifacts[item.name].extend(
98 ['gs://%s' % str(x) for x in art.input_artifact_gs_locations])
99
100 results = set()
101 sysroot_path = input_proto.sysroot.path
102 build_target = input_proto.sysroot.build_target.name
LaMont Jonesb20b3d92019-11-23 11:47:48 -0700103 for artifact_type in input_proto.artifact_types:
LaMont Jones5d2edcb2019-12-23 11:32:03 -0700104 # Unknown artifact_types are an error.
105 handler = _TOOLCHAIN_ARTIFACT_HANDLERS[artifact_type]
106 if handler.prepare:
LaMont Jonesa215f1e2019-12-06 10:18:58 -0700107 results.add(handler.prepare(
LaMont Jones5d2edcb2019-12-23 11:32:03 -0700108 handler.name, chroot, sysroot_path, build_target, input_artifacts))
LaMont Jonesb20b3d92019-11-23 11:47:48 -0700109
110 # Translate the returns from the handlers we called.
111 # If any NEEDED => NEEDED
112 # elif any UNKNOWN => UNKNOWN
113 # elif any POINTLESS => POINTLESS
114 # else UNKNOWN.
115 proto_resp = toolchain_pb2.PrepareForToolchainBuildResponse
116 if toolchain_util.PrepareForBuildReturn.NEEDED in results:
117 output_proto.build_relevance = proto_resp.NEEDED
118 elif toolchain_util.PrepareForBuildReturn.UNKNOWN in results:
119 output_proto.build_relevance = proto_resp.UNKNOWN
120 elif toolchain_util.PrepareForBuildReturn.POINTLESS in results:
121 output_proto.build_relevance = proto_resp.POINTLESS
122 else:
123 output_proto.build_relevance = proto_resp.UNKNOWN
LaMont Jones5d2edcb2019-12-23 11:32:03 -0700124 return controller.RETURN_CODE_SUCCESS
LaMont Jonesb20b3d92019-11-23 11:47:48 -0700125
126
127# TODO(crbug/1031213): When @faux is expanded to have more than success/failure,
128# this should be changed.
129@faux.all_empty
LaMont Jones4579e8c2019-12-06 14:20:37 -0700130@validate.require('chroot.path', 'sysroot.path', 'sysroot.build_target.name',
131 'output_dir', 'artifact_types')
132@validate.exists('output_dir')
LaMont Jones5d2edcb2019-12-23 11:32:03 -0700133@validate.validation_complete
LaMont Jonesb20b3d92019-11-23 11:47:48 -0700134def BundleArtifacts(input_proto, output_proto, _config):
135 """Bundle toolchain artifacts.
136
137 The handlers (from _TOOLCHAIN_ARTIFACT_HANDLERS above) are called with:
LaMont Jonesa215f1e2019-12-06 10:18:58 -0700138 artifact_name (str): name of the artifact type
LaMont Jones5d2edcb2019-12-23 11:32:03 -0700139 chroot (chroot_lib.Chroot): chroot
LaMont Jonesb20b3d92019-11-23 11:47:48 -0700140 sysroot_path (str): sysroot path inside the chroot (e.g., /build/atlas)
LaMont Jones5d2edcb2019-12-23 11:32:03 -0700141 chrome_root (str): path to chrome root. (e.g., /b/s/w/ir/k/chrome)
LaMont Jonesb20b3d92019-11-23 11:47:48 -0700142 build_target_name (str): name of the build target (e.g., atlas)
143 output_dir (str): absolute path where artifacts are being bundled.
144 (e.g., /b/s/w/ir/k/recipe_cleanup/artifactssptfMU)
145
146 Note: the actual upload to GS is done by CI, not here.
147
148 Args:
149 input_proto (BundleToolchainRequest): The input proto
150 output_proto (BundleToolchainResponse): The output proto
151 _config (api_config.ApiConfig): The API call config.
152 """
LaMont Jones5d2edcb2019-12-23 11:32:03 -0700153 chroot = controller_util.ParseChroot(input_proto.chroot)
LaMont Jonesb20b3d92019-11-23 11:47:48 -0700154
155 for artifact_type in input_proto.artifact_types:
LaMont Jones5d2edcb2019-12-23 11:32:03 -0700156 if artifact_type not in _TOOLCHAIN_ARTIFACT_HANDLERS:
157 logging.error('%s not understood', artifact_type)
158 return controller.RETURN_CODE_UNRECOVERABLE
159 handler = _TOOLCHAIN_ARTIFACT_HANDLERS[artifact_type]
LaMont Jonesb20b3d92019-11-23 11:47:48 -0700160 if handler and handler.bundle:
161 artifacts = handler.bundle(
LaMont Jones5d2edcb2019-12-23 11:32:03 -0700162 handler.name, chroot, input_proto.sysroot.path,
LaMont Jonesb20b3d92019-11-23 11:47:48 -0700163 input_proto.sysroot.build_target.name, input_proto.output_dir)
164 if artifacts:
LaMont Jones5d2edcb2019-12-23 11:32:03 -0700165 art_info = output_proto.artifacts_info.add()
166 art_info.artifact_type = artifact_type
167 for artifact in artifacts:
168 art_info.artifacts.add().path = artifact
LaMont Jonesb20b3d92019-11-23 11:47:48 -0700169
170
171# TODO(crbug/1019868): Remove legacy code when cbuildbot builders are gone.
172_NAMES_FOR_AFDO_ARTIFACTS = {
Tiancong Wangf9c736c2019-08-26 13:54:38 -0700173 toolchain_pb2.ORDERFILE: 'orderfile',
174 toolchain_pb2.KERNEL_AFDO: 'kernel_afdo',
175 toolchain_pb2.CHROME_AFDO: 'chrome_afdo'
176}
177
LaMont Jonesb20b3d92019-11-23 11:47:48 -0700178# TODO(crbug/1019868): Remove legacy code when cbuildbot builders are gone.
Tiancong Wangf9c736c2019-08-26 13:54:38 -0700179# Using a function instead of a dict because we need to mock these
180# functions in unittest, and mock doesn't play well with a dict definition.
LaMont Jonesb20b3d92019-11-23 11:47:48 -0700181def _GetMethodForUpdatingAFDOArtifacts(artifact_type):
Tiancong Wangf9c736c2019-08-26 13:54:38 -0700182 return {
183 toolchain_pb2.ORDERFILE: toolchain_util.OrderfileUpdateChromeEbuild,
184 toolchain_pb2.KERNEL_AFDO: toolchain_util.AFDOUpdateKernelEbuild,
185 toolchain_pb2.CHROME_AFDO: toolchain_util.AFDOUpdateChromeEbuild
186 }[artifact_type]
Tiancong Wang24a3df72019-08-20 15:48:51 -0700187
Tiancong Wangaf050172019-07-10 11:52:03 -0700188
LaMont Jonesb20b3d92019-11-23 11:47:48 -0700189# TODO(crbug/1019868): Remove legacy code when cbuildbot builders are gone.
Michael Mortensen54bd70a2019-11-21 14:45:38 -0700190def _UpdateEbuildWithAFDOArtifactsResponse(_input_proto, output_proto, _config):
191 """Add successful status to the faux response."""
192 output_proto.status = True
193
194
LaMont Jonesb20b3d92019-11-23 11:47:48 -0700195# TODO(crbug/1019868): Remove legacy code when cbuildbot builders are gone.
Michael Mortensen54bd70a2019-11-21 14:45:38 -0700196@faux.success(_UpdateEbuildWithAFDOArtifactsResponse)
197@faux.empty_error
Alex Klein231d2da2019-07-22 16:44:45 -0600198@validate.require('build_target.name')
LaMont Jonesb20b3d92019-11-23 11:47:48 -0700199@validate.is_in('artifact_type', _NAMES_FOR_AFDO_ARTIFACTS)
Alex Klein231d2da2019-07-22 16:44:45 -0600200@validate.validation_complete
Tiancong Wang24a3df72019-08-20 15:48:51 -0700201def UpdateEbuildWithAFDOArtifacts(input_proto, output_proto, _config):
202 """Update Chrome or kernel ebuild with most recent unvetted artifacts.
Tiancong Wangaf050172019-07-10 11:52:03 -0700203
204 Args:
Tiancong Wang24a3df72019-08-20 15:48:51 -0700205 input_proto (VerifyAFDOArtifactsRequest): The input proto
206 output_proto (VerifyAFDOArtifactsResponse): The output proto
Alex Klein231d2da2019-07-22 16:44:45 -0600207 _config (api_config.ApiConfig): The API call config.
Tiancong Wangaf050172019-07-10 11:52:03 -0700208 """
Tiancong Wangaf050172019-07-10 11:52:03 -0700209 board = input_proto.build_target.name
LaMont Jonesb20b3d92019-11-23 11:47:48 -0700210 update_method = _GetMethodForUpdatingAFDOArtifacts(input_proto.artifact_type)
Tiancong Wangf9c736c2019-08-26 13:54:38 -0700211 output_proto.status = update_method(board)
Tiancong Wangaf050172019-07-10 11:52:03 -0700212
213
LaMont Jonesb20b3d92019-11-23 11:47:48 -0700214# TODO(crbug/1019868): Remove legacy code when cbuildbot builders are gone.
Michael Mortensen54bd70a2019-11-21 14:45:38 -0700215def _UploadVettedAFDOArtifactsResponse(_input_proto, output_proto, _config):
216 """Add successful status to the faux response."""
217 output_proto.status = True
218
219
LaMont Jonesb20b3d92019-11-23 11:47:48 -0700220# TODO(crbug/1019868): Remove legacy code when cbuildbot builders are gone.
Michael Mortensen54bd70a2019-11-21 14:45:38 -0700221@faux.success(_UploadVettedAFDOArtifactsResponse)
222@faux.empty_error
Tiancong Wang24a3df72019-08-20 15:48:51 -0700223@validate.require('build_target.name')
LaMont Jonesb20b3d92019-11-23 11:47:48 -0700224@validate.is_in('artifact_type', _NAMES_FOR_AFDO_ARTIFACTS)
Alex Klein231d2da2019-07-22 16:44:45 -0600225@validate.validation_complete
Tiancong Wang24a3df72019-08-20 15:48:51 -0700226def UploadVettedAFDOArtifacts(input_proto, output_proto, _config):
Tiancong Wangaf050172019-07-10 11:52:03 -0700227 """Upload a vetted orderfile to GS bucket.
228
229 Args:
Tiancong Wang24a3df72019-08-20 15:48:51 -0700230 input_proto (VerifyAFDOArtifactsRequest): The input proto
231 output_proto (VerifyAFDOArtifactsResponse): The output proto
Alex Klein231d2da2019-07-22 16:44:45 -0600232 _config (api_config.ApiConfig): The API call config.
Tiancong Wangaf050172019-07-10 11:52:03 -0700233 """
Tiancong Wang24a3df72019-08-20 15:48:51 -0700234 board = input_proto.build_target.name
LaMont Jonesb20b3d92019-11-23 11:47:48 -0700235 artifact_type = _NAMES_FOR_AFDO_ARTIFACTS[input_proto.artifact_type]
Tiancong Wang24a3df72019-08-20 15:48:51 -0700236 output_proto.status = toolchain_util.UploadAndPublishVettedAFDOArtifacts(
237 artifact_type, board)