Mike Frysinger | f1ba7ad | 2022-09-12 05:42:57 -0400 | [diff] [blame] | 1 | # Copyright 2019 The ChromiumOS Authors |
Tiancong Wang | af05017 | 2019-07-10 11:52:03 -0700 | [diff] [blame] | 2 | # Use of this source code is governed by a BSD-style license that can be |
| 3 | # found in the LICENSE file. |
| 4 | |
| 5 | """Toolchain-related operations.""" |
| 6 | |
LaMont Jones | b20b3d9 | 2019-11-23 11:47:48 -0700 | [diff] [blame] | 7 | import collections |
Chris McDonald | 1672ddb | 2021-07-21 11:48:23 -0600 | [diff] [blame] | 8 | import logging |
Alex Klein | cd03a5e | 2021-10-18 13:23:47 -0600 | [diff] [blame] | 9 | from pathlib import Path |
Jack Neus | 4ee7b1d | 2022-06-27 19:54:18 +0000 | [diff] [blame] | 10 | from typing import TYPE_CHECKING |
LaMont Jones | b20b3d9 | 2019-11-23 11:47:48 -0700 | [diff] [blame] | 11 | |
LaMont Jones | 5d2edcb | 2019-12-23 11:32:03 -0700 | [diff] [blame] | 12 | from chromite.api import controller |
Alex Klein | 076841b | 2019-08-29 15:19:39 -0600 | [diff] [blame] | 13 | from chromite.api import faux |
Alex Klein | 231d2da | 2019-07-22 16:44:45 -0600 | [diff] [blame] | 14 | from chromite.api import validate |
LaMont Jones | 5d2edcb | 2019-12-23 11:32:03 -0700 | [diff] [blame] | 15 | from chromite.api.controller import controller_util |
Tiancong Wang | 24a3df7 | 2019-08-20 15:48:51 -0700 | [diff] [blame] | 16 | from chromite.api.gen.chromite.api import toolchain_pb2 |
LaMont Jones | fd68cb1 | 2020-04-29 16:43:06 -0600 | [diff] [blame] | 17 | from chromite.api.gen.chromite.api.artifacts_pb2 import PrepareForBuildResponse |
Chris McDonald | 1672ddb | 2021-07-21 11:48:23 -0600 | [diff] [blame] | 18 | from chromite.api.gen.chromiumos.builder_config_pb2 import BuilderConfig |
Ryan Beltran | 8daf1dd | 2023-03-22 21:31:03 +0000 | [diff] [blame] | 19 | from chromite.api.gen.chromiumos.common_pb2 import PackageInfo |
Greg Edelston | dae510a | 2023-06-30 15:25:36 -0600 | [diff] [blame] | 20 | from chromite.lib import cros_build_lib |
Jack Neus | 4ee7b1d | 2022-06-27 19:54:18 +0000 | [diff] [blame] | 21 | from chromite.lib import toolchain as toolchain_lib |
Chris McDonald | 1672ddb | 2021-07-21 11:48:23 -0600 | [diff] [blame] | 22 | from chromite.lib import toolchain_util |
Ryan Beltran | f2a5dcc | 2022-04-19 20:34:00 +0000 | [diff] [blame] | 23 | from chromite.service import toolchain |
Ryan Beltran | 7d19180 | 2021-11-24 00:08:17 +0000 | [diff] [blame] | 24 | |
Mike Frysinger | ea11fdd | 2022-05-06 22:59:33 -0400 | [diff] [blame] | 25 | |
Jack Neus | 4ee7b1d | 2022-06-27 19:54:18 +0000 | [diff] [blame] | 26 | if TYPE_CHECKING: |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 27 | from chromite.api import api_config |
Jack Neus | 4ee7b1d | 2022-06-27 19:54:18 +0000 | [diff] [blame] | 28 | |
Ryan Beltran | f2a5dcc | 2022-04-19 20:34:00 +0000 | [diff] [blame] | 29 | # TODO(b/229665884): Move the implementation details for most/all endpoints to: |
| 30 | # chromite/services/toolchain.py |
| 31 | # This migration has been done for linting endpoints but not yet for others. |
Chris McDonald | 1672ddb | 2021-07-21 11:48:23 -0600 | [diff] [blame] | 32 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 33 | _Handlers = collections.namedtuple("_Handlers", ["name", "prepare", "bundle"]) |
LaMont Jones | b20b3d9 | 2019-11-23 11:47:48 -0700 | [diff] [blame] | 34 | _TOOLCHAIN_ARTIFACT_HANDLERS = { |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 35 | BuilderConfig.Artifacts.UNVERIFIED_CHROME_LLVM_ORDERFILE: _Handlers( |
| 36 | "UnverifiedChromeLlvmOrderfile", |
| 37 | toolchain_util.PrepareForBuild, |
| 38 | toolchain_util.BundleArtifacts, |
| 39 | ), |
| 40 | BuilderConfig.Artifacts.VERIFIED_CHROME_LLVM_ORDERFILE: _Handlers( |
| 41 | "VerifiedChromeLlvmOrderfile", |
| 42 | toolchain_util.PrepareForBuild, |
| 43 | toolchain_util.BundleArtifacts, |
| 44 | ), |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 45 | BuilderConfig.Artifacts.UNVERIFIED_LLVM_PGO_FILE: _Handlers( |
| 46 | "UnverifiedLlvmPgoFile", |
| 47 | toolchain_util.PrepareForBuild, |
| 48 | toolchain_util.BundleArtifacts, |
| 49 | ), |
| 50 | BuilderConfig.Artifacts.UNVERIFIED_CHROME_BENCHMARK_AFDO_FILE: _Handlers( |
| 51 | "UnverifiedChromeBenchmarkAfdoFile", |
| 52 | toolchain_util.PrepareForBuild, |
| 53 | toolchain_util.BundleArtifacts, |
| 54 | ), |
| 55 | BuilderConfig.Artifacts.CHROME_DEBUG_BINARY: _Handlers( |
| 56 | "ChromeDebugBinary", |
| 57 | toolchain_util.PrepareForBuild, |
| 58 | toolchain_util.BundleArtifacts, |
| 59 | ), |
| 60 | BuilderConfig.Artifacts.UNVERIFIED_CHROME_BENCHMARK_PERF_FILE: _Handlers( |
| 61 | "UnverifiedChromeBenchmarkPerfFile", |
| 62 | toolchain_util.PrepareForBuild, |
| 63 | toolchain_util.BundleArtifacts, |
| 64 | ), |
| 65 | BuilderConfig.Artifacts.VERIFIED_CHROME_BENCHMARK_AFDO_FILE: _Handlers( |
| 66 | "VerifiedChromeBenchmarkAfdoFile", |
| 67 | toolchain_util.PrepareForBuild, |
| 68 | toolchain_util.BundleArtifacts, |
| 69 | ), |
| 70 | BuilderConfig.Artifacts.UNVERIFIED_KERNEL_CWP_AFDO_FILE: _Handlers( |
| 71 | "UnverifiedKernelCwpAfdoFile", |
| 72 | toolchain_util.PrepareForBuild, |
| 73 | toolchain_util.BundleArtifacts, |
| 74 | ), |
| 75 | BuilderConfig.Artifacts.VERIFIED_KERNEL_CWP_AFDO_FILE: _Handlers( |
| 76 | "VerifiedKernelCwpAfdoFile", |
| 77 | toolchain_util.PrepareForBuild, |
| 78 | toolchain_util.BundleArtifacts, |
| 79 | ), |
| 80 | BuilderConfig.Artifacts.UNVERIFIED_CHROME_CWP_AFDO_FILE: _Handlers( |
| 81 | "UnverifiedChromeCwpAfdoFile", |
| 82 | toolchain_util.PrepareForBuild, |
| 83 | toolchain_util.BundleArtifacts, |
| 84 | ), |
| 85 | BuilderConfig.Artifacts.VERIFIED_CHROME_CWP_AFDO_FILE: _Handlers( |
| 86 | "VerifiedChromeCwpAfdoFile", |
| 87 | toolchain_util.PrepareForBuild, |
| 88 | toolchain_util.BundleArtifacts, |
| 89 | ), |
| 90 | BuilderConfig.Artifacts.VERIFIED_RELEASE_AFDO_FILE: _Handlers( |
| 91 | "VerifiedReleaseAfdoFile", |
| 92 | toolchain_util.PrepareForBuild, |
| 93 | toolchain_util.BundleArtifacts, |
| 94 | ), |
| 95 | BuilderConfig.Artifacts.TOOLCHAIN_WARNING_LOGS: _Handlers( |
| 96 | "ToolchainWarningLogs", |
| 97 | toolchain_util.PrepareForBuild, |
| 98 | toolchain_util.BundleArtifacts, |
| 99 | ), |
| 100 | BuilderConfig.Artifacts.CHROME_AFDO_PROFILE_FOR_ANDROID_LINUX: _Handlers( |
| 101 | "ChromeAFDOProfileForAndroidLinux", |
| 102 | toolchain_util.PrepareForBuild, |
| 103 | toolchain_util.BundleArtifacts, |
| 104 | ), |
| 105 | BuilderConfig.Artifacts.CLANG_CRASH_DIAGNOSES: _Handlers( |
| 106 | "ClangCrashDiagnoses", |
| 107 | toolchain_util.PrepareForBuild, |
| 108 | toolchain_util.BundleArtifacts, |
| 109 | ), |
| 110 | BuilderConfig.Artifacts.COMPILER_RUSAGE_LOG: _Handlers( |
| 111 | "CompilerRusageLogs", |
| 112 | toolchain_util.PrepareForBuild, |
| 113 | toolchain_util.BundleArtifacts, |
| 114 | ), |
LaMont Jones | b20b3d9 | 2019-11-23 11:47:48 -0700 | [diff] [blame] | 115 | } |
| 116 | |
Alex Klein | ab87ceb | 2023-01-24 12:00:51 -0700 | [diff] [blame] | 117 | # pylint: disable=line-too-long |
Tiancong Wang | d521413 | 2021-01-12 10:43:57 -0800 | [diff] [blame] | 118 | _TOOLCHAIN_COMMIT_HANDLERS = { |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 119 | BuilderConfig.Artifacts.VERIFIED_KERNEL_CWP_AFDO_FILE: "VerifiedKernelCwpAfdoFile" |
Tiancong Wang | d521413 | 2021-01-12 10:43:57 -0800 | [diff] [blame] | 120 | } |
Alex Klein | ab87ceb | 2023-01-24 12:00:51 -0700 | [diff] [blame] | 121 | # pylint: enable=line-too-long |
Tiancong Wang | d521413 | 2021-01-12 10:43:57 -0800 | [diff] [blame] | 122 | |
LaMont Jones | e782167 | 2020-04-09 08:56:26 -0600 | [diff] [blame] | 123 | |
LaMont Jones | b20b3d9 | 2019-11-23 11:47:48 -0700 | [diff] [blame] | 124 | # TODO(crbug/1031213): When @faux is expanded to have more than success/failure, |
| 125 | # this should be changed. |
| 126 | @faux.all_empty |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 127 | @validate.require("artifact_types") |
LaMont Jones | 5d2edcb | 2019-12-23 11:32:03 -0700 | [diff] [blame] | 128 | # Note: chroot and sysroot are unspecified the first time that the build_target |
| 129 | # recipe calls PrepareForBuild. The second time, they are specified. No |
| 130 | # validation check because "all" values are valid. |
LaMont Jones | b20b3d9 | 2019-11-23 11:47:48 -0700 | [diff] [blame] | 131 | @validate.validation_complete |
Jack Neus | 4ee7b1d | 2022-06-27 19:54:18 +0000 | [diff] [blame] | 132 | def PrepareForBuild( |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 133 | input_proto: "toolchain_pb2.PrepareForToolchainBuildRequest", |
| 134 | output_proto: "toolchain_pb2.PrepareForToolchainBuildResponse", |
| 135 | _config: "api_config.ApiConfig", |
| 136 | ): |
| 137 | """Prepare to build toolchain artifacts. |
LaMont Jones | b20b3d9 | 2019-11-23 11:47:48 -0700 | [diff] [blame] | 138 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 139 | The handlers (from _TOOLCHAIN_ARTIFACT_HANDLERS above) are called with: |
| 140 | artifact_name (str): name of the artifact type. |
| 141 | chroot (chroot_lib.Chroot): chroot. Will be None if the chroot has not |
| 142 | yet been created. |
| 143 | sysroot_path (str): sysroot path inside the chroot (e.g., /build/atlas). |
| 144 | Will be an empty string if the sysroot has not yet been created. |
Alex Klein | ab87ceb | 2023-01-24 12:00:51 -0700 | [diff] [blame] | 145 | build_target_name (str): name of the build target (e.g., atlas). Will be |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 146 | an empty string if the sysroot has not yet been created. |
Alex Klein | ab87ceb | 2023-01-24 12:00:51 -0700 | [diff] [blame] | 147 | input_artifacts ({(str) name:[str gs_locations]}): locations for |
| 148 | possible input artifacts. The handler is expected to know which |
| 149 | keys it should be using, and ignore any keys that it does not |
| 150 | understand. |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 151 | profile_info ({(str) name: (str) value}) Dictionary containing profile |
| 152 | information. |
LaMont Jones | a215f1e | 2019-12-06 10:18:58 -0700 | [diff] [blame] | 153 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 154 | They locate and modify any ebuilds and/or source required for the artifact |
Alex Klein | ab87ceb | 2023-01-24 12:00:51 -0700 | [diff] [blame] | 155 | being created, then return a value from |
| 156 | toolchain_util.PrepareForBuildReturn. |
LaMont Jones | b20b3d9 | 2019-11-23 11:47:48 -0700 | [diff] [blame] | 157 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 158 | This function sets output_proto.build_relevance to the result. |
LaMont Jones | 5d2edcb | 2019-12-23 11:32:03 -0700 | [diff] [blame] | 159 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 160 | Args: |
Alex Klein | 611dddd | 2022-10-11 17:02:01 -0600 | [diff] [blame] | 161 | input_proto: The input proto |
| 162 | output_proto: The output proto |
| 163 | _config): The API call config. |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 164 | """ |
| 165 | if input_proto.chroot.path: |
| 166 | chroot = controller_util.ParseChroot(input_proto.chroot) |
| 167 | else: |
| 168 | chroot = None |
LaMont Jones | 4579e8c | 2019-12-06 14:20:37 -0700 | [diff] [blame] | 169 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 170 | input_artifacts = collections.defaultdict(list) |
| 171 | for art in input_proto.input_artifacts: |
| 172 | item = _TOOLCHAIN_ARTIFACT_HANDLERS.get(art.input_artifact_type) |
| 173 | if item: |
| 174 | input_artifacts[item.name].extend( |
| 175 | ["gs://%s" % str(x) for x in art.input_artifact_gs_locations] |
| 176 | ) |
LaMont Jones | 5d2edcb | 2019-12-23 11:32:03 -0700 | [diff] [blame] | 177 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 178 | profile_info = _GetProfileInfoDict(input_proto.profile_info) |
LaMont Jones | 45ca6c4 | 2020-02-05 09:39:09 -0700 | [diff] [blame] | 179 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 180 | results = set() |
| 181 | sysroot_path = input_proto.sysroot.path |
| 182 | build_target = input_proto.sysroot.build_target.name |
| 183 | for artifact_type in input_proto.artifact_types: |
| 184 | # Unknown artifact_types are an error. |
| 185 | handler = _TOOLCHAIN_ARTIFACT_HANDLERS[artifact_type] |
| 186 | if handler.prepare: |
| 187 | results.add( |
| 188 | handler.prepare( |
| 189 | handler.name, |
| 190 | chroot, |
| 191 | sysroot_path, |
| 192 | build_target, |
| 193 | input_artifacts, |
| 194 | profile_info, |
| 195 | ) |
| 196 | ) |
LaMont Jones | b20b3d9 | 2019-11-23 11:47:48 -0700 | [diff] [blame] | 197 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 198 | # Translate the returns from the handlers we called. |
| 199 | # If any NEEDED => NEEDED |
| 200 | # elif any UNKNOWN => UNKNOWN |
| 201 | # elif any POINTLESS => POINTLESS |
| 202 | # else UNKNOWN. |
| 203 | if toolchain_util.PrepareForBuildReturn.NEEDED in results: |
| 204 | output_proto.build_relevance = PrepareForBuildResponse.NEEDED |
| 205 | elif toolchain_util.PrepareForBuildReturn.UNKNOWN in results: |
| 206 | output_proto.build_relevance = PrepareForBuildResponse.UNKNOWN |
| 207 | elif toolchain_util.PrepareForBuildReturn.POINTLESS in results: |
| 208 | output_proto.build_relevance = PrepareForBuildResponse.POINTLESS |
| 209 | else: |
| 210 | output_proto.build_relevance = PrepareForBuildResponse.UNKNOWN |
| 211 | return controller.RETURN_CODE_SUCCESS |
LaMont Jones | b20b3d9 | 2019-11-23 11:47:48 -0700 | [diff] [blame] | 212 | |
| 213 | |
| 214 | # TODO(crbug/1031213): When @faux is expanded to have more than success/failure, |
| 215 | # this should be changed. |
| 216 | @faux.all_empty |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 217 | @validate.require("chroot.path", "output_dir", "artifact_types") |
| 218 | @validate.exists("output_dir") |
LaMont Jones | 5d2edcb | 2019-12-23 11:32:03 -0700 | [diff] [blame] | 219 | @validate.validation_complete |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 220 | def BundleArtifacts( |
| 221 | input_proto: "toolchain_pb2.BundleToolchainRequest", |
| 222 | output_proto: "toolchain_pb2.BundleToolchainResponse", |
| 223 | _config: "api_config.ApiConfig", |
| 224 | ): |
| 225 | """Bundle valid toolchain artifacts. |
LaMont Jones | b20b3d9 | 2019-11-23 11:47:48 -0700 | [diff] [blame] | 226 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 227 | The handlers (from _TOOLCHAIN_ARTIFACT_HANDLERS above) are called with: |
| 228 | artifact_name (str): name of the artifact type |
| 229 | chroot (chroot_lib.Chroot): chroot |
| 230 | sysroot_path (str): sysroot path inside the chroot (e.g., /build/atlas), |
| 231 | or None. |
| 232 | chrome_root (str): path to chrome root. (e.g., /b/s/w/ir/k/chrome) |
Alex Klein | 611dddd | 2022-10-11 17:02:01 -0600 | [diff] [blame] | 233 | build_target_name (str): name of the build target (e.g. atlas), or None. |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 234 | output_dir (str): absolute path where artifacts are being bundled. |
Alex Klein | 611dddd | 2022-10-11 17:02:01 -0600 | [diff] [blame] | 235 | (e.g., /b/s/w/ir/k/recipe_cleanup/artifactssptfMU) |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 236 | profile_info ({(str) name: (str) value}) Dictionary containing profile |
| 237 | information. |
LaMont Jones | b20b3d9 | 2019-11-23 11:47:48 -0700 | [diff] [blame] | 238 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 239 | Note: the actual upload to GS is done by CI, not here. |
LaMont Jones | b20b3d9 | 2019-11-23 11:47:48 -0700 | [diff] [blame] | 240 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 241 | Args: |
Alex Klein | 611dddd | 2022-10-11 17:02:01 -0600 | [diff] [blame] | 242 | input_proto: The input proto |
| 243 | output_proto: The output proto |
| 244 | _config: The API call config. |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 245 | """ |
| 246 | chroot = controller_util.ParseChroot(input_proto.chroot) |
LaMont Jones | b20b3d9 | 2019-11-23 11:47:48 -0700 | [diff] [blame] | 247 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 248 | profile_info = _GetProfileInfoDict(input_proto.profile_info) |
LaMont Jones | 45ca6c4 | 2020-02-05 09:39:09 -0700 | [diff] [blame] | 249 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 250 | output_path = Path(input_proto.output_dir) |
Alex Klein | cd03a5e | 2021-10-18 13:23:47 -0600 | [diff] [blame] | 251 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 252 | for artifact_type in input_proto.artifact_types: |
| 253 | if artifact_type not in _TOOLCHAIN_ARTIFACT_HANDLERS: |
| 254 | logging.error("%s not understood", artifact_type) |
| 255 | return controller.RETURN_CODE_UNRECOVERABLE |
Alex Klein | cd03a5e | 2021-10-18 13:23:47 -0600 | [diff] [blame] | 256 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 257 | handler = _TOOLCHAIN_ARTIFACT_HANDLERS[artifact_type] |
| 258 | if not handler or not handler.bundle: |
| 259 | logging.warning( |
| 260 | "%s does not have a handler with a bundle function.", |
| 261 | artifact_type, |
| 262 | ) |
| 263 | continue |
Alex Klein | cd03a5e | 2021-10-18 13:23:47 -0600 | [diff] [blame] | 264 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 265 | artifacts = handler.bundle( |
| 266 | handler.name, |
| 267 | chroot, |
| 268 | input_proto.sysroot.path, |
| 269 | input_proto.sysroot.build_target.name, |
| 270 | input_proto.output_dir, |
| 271 | profile_info, |
| 272 | ) |
| 273 | if not artifacts: |
| 274 | continue |
Alex Klein | cd03a5e | 2021-10-18 13:23:47 -0600 | [diff] [blame] | 275 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 276 | # Filter out artifacts that do not exist or are empty. |
| 277 | usable_artifacts = [] |
| 278 | for artifact in artifacts: |
| 279 | artifact_path = output_path / artifact |
| 280 | if not artifact_path.exists(): |
| 281 | logging.warning("%s is not in the output directory.", artifact) |
| 282 | elif not artifact_path.stat().st_size: |
| 283 | logging.warning("%s is empty.", artifact) |
| 284 | else: |
| 285 | usable_artifacts.append(artifact) |
Alex Klein | cd03a5e | 2021-10-18 13:23:47 -0600 | [diff] [blame] | 286 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 287 | if not usable_artifacts: |
| 288 | logging.warning( |
| 289 | "No usable artifacts for artifact type %s", artifact_type |
| 290 | ) |
| 291 | continue |
Alex Klein | cd03a5e | 2021-10-18 13:23:47 -0600 | [diff] [blame] | 292 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 293 | # Add all usable artifacts. |
| 294 | art_info = output_proto.artifacts_info.add() |
| 295 | art_info.artifact_type = artifact_type |
| 296 | for artifact in usable_artifacts: |
| 297 | art_info.artifacts.add().path = artifact |
LaMont Jones | b20b3d9 | 2019-11-23 11:47:48 -0700 | [diff] [blame] | 298 | |
| 299 | |
Tiancong Wang | d521413 | 2021-01-12 10:43:57 -0800 | [diff] [blame] | 300 | def _GetUpdatedFilesResponse(_input_proto, output_proto, _config): |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 301 | """Add successful status to the faux response.""" |
| 302 | file_info = output_proto.updated_files.add() |
| 303 | file_info.path = "/any/modified/file" |
| 304 | output_proto.commit_message = "Commit message" |
Tiancong Wang | d521413 | 2021-01-12 10:43:57 -0800 | [diff] [blame] | 305 | |
| 306 | |
| 307 | @faux.empty_error |
| 308 | @faux.success(_GetUpdatedFilesResponse) |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 309 | @validate.require("uploaded_artifacts") |
Tiancong Wang | d521413 | 2021-01-12 10:43:57 -0800 | [diff] [blame] | 310 | @validate.validation_complete |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 311 | def GetUpdatedFiles( |
| 312 | input_proto: "toolchain_pb2.GetUpdatedFilesRequest", |
| 313 | output_proto: "toolchain_pb2.GetUpdatedFilesResponse", |
| 314 | _config: "api_config.ApiConfig", |
| 315 | ): |
| 316 | """Use uploaded artifacts to update some updates in a chromeos checkout. |
Tiancong Wang | d521413 | 2021-01-12 10:43:57 -0800 | [diff] [blame] | 317 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 318 | The function will call toolchain_util.GetUpdatedFiles using the type of |
| 319 | uploaded artifacts to make some changes in a checkout, and return the list |
| 320 | of change files together with commit message. |
Alex Klein | 611dddd | 2022-10-11 17:02:01 -0600 | [diff] [blame] | 321 | updated_artifacts: A list of UpdatedArtifacts type which contains a |
| 322 | tuple of artifact info and profile info. |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 323 | Note: the actual creation of the commit is done by CI, not here. |
Tiancong Wang | d521413 | 2021-01-12 10:43:57 -0800 | [diff] [blame] | 324 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 325 | Args: |
Alex Klein | 611dddd | 2022-10-11 17:02:01 -0600 | [diff] [blame] | 326 | input_proto: The input proto |
| 327 | output_proto: The output proto |
| 328 | _config: The API call config. |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 329 | """ |
| 330 | commit_message = "" |
| 331 | for artifact in input_proto.uploaded_artifacts: |
| 332 | artifact_type = artifact.artifact_info.artifact_type |
| 333 | if artifact_type not in _TOOLCHAIN_COMMIT_HANDLERS: |
| 334 | logging.error("%s not understood", artifact_type) |
| 335 | return controller.RETURN_CODE_UNRECOVERABLE |
| 336 | artifact_name = _TOOLCHAIN_COMMIT_HANDLERS[artifact_type] |
| 337 | if artifact_name: |
| 338 | assert ( |
| 339 | len(artifact.artifact_info.artifacts) == 1 |
| 340 | ), "Only one file to update per each artifact" |
| 341 | updated_files, message = toolchain_util.GetUpdatedFiles( |
| 342 | artifact_name, |
| 343 | artifact.artifact_info.artifacts[0].path, |
| 344 | _GetProfileInfoDict(artifact.profile_info), |
| 345 | ) |
| 346 | for f in updated_files: |
| 347 | file_info = output_proto.updated_files.add() |
| 348 | file_info.path = f |
Tiancong Wang | d521413 | 2021-01-12 10:43:57 -0800 | [diff] [blame] | 349 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 350 | commit_message += message + "\n" |
| 351 | output_proto.commit_message = commit_message |
| 352 | # No commit footer is added for now. Can add more here if needed |
Tiancong Wang | d521413 | 2021-01-12 10:43:57 -0800 | [diff] [blame] | 353 | |
| 354 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 355 | def _GetProfileInfoDict(profile_info: "toolchain_pb2.ArtifactProfileInfo"): |
| 356 | """Convert profile_info to a dict. |
Ryan Beltran | f2a5dcc | 2022-04-19 20:34:00 +0000 | [diff] [blame] | 357 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 358 | Args: |
Alex Klein | 611dddd | 2022-10-11 17:02:01 -0600 | [diff] [blame] | 359 | profile_info: The artifact profile_info. |
Ryan Beltran | f2a5dcc | 2022-04-19 20:34:00 +0000 | [diff] [blame] | 360 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 361 | Returns: |
Alex Klein | 611dddd | 2022-10-11 17:02:01 -0600 | [diff] [blame] | 362 | A dictionary containing profile info. |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 363 | """ |
| 364 | ret = {} |
| 365 | which = profile_info.WhichOneof("artifact_profile_info") |
| 366 | if which: |
| 367 | value = getattr(profile_info, which) |
Alex Klein | ab87ceb | 2023-01-24 12:00:51 -0700 | [diff] [blame] | 368 | # If it is a message, then use the contents of the message. This works |
| 369 | # as long as simple types do not have a 'DESCRIPTOR' attribute. (And |
| 370 | # protobuf messages do.) |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 371 | if getattr(value, "DESCRIPTOR", None): |
| 372 | ret.update({k.name: v for k, v in value.ListFields()}) |
| 373 | else: |
| 374 | ret[which] = value |
Denis Nikitin | 62e6986 | 2023-02-13 23:37:00 -0800 | [diff] [blame] | 375 | arch = getattr(profile_info, "arch", None) |
| 376 | if arch: |
| 377 | ret["arch"] = arch |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 378 | return ret |
Ryan Beltran | f2a5dcc | 2022-04-19 20:34:00 +0000 | [diff] [blame] | 379 | |
| 380 | |
| 381 | LINTER_CODES = { |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 382 | "clang_tidy": toolchain_pb2.LinterFinding.CLANG_TIDY, |
| 383 | "cargo_clippy": toolchain_pb2.LinterFinding.CARGO_CLIPPY, |
| 384 | "go_lint": toolchain_pb2.LinterFinding.GO_LINT, |
Ryan Beltran | f2a5dcc | 2022-04-19 20:34:00 +0000 | [diff] [blame] | 385 | } |
| 386 | |
| 387 | |
Adrian Dole | f87c576 | 2022-12-15 22:00:50 +0000 | [diff] [blame] | 388 | @validate.require("sysroot.build_target.name") |
| 389 | @validate.require("start_time") |
| 390 | @validate.validation_complete |
| 391 | def EmergeAndUploadLints( |
| 392 | input_proto: toolchain_pb2.DashboardLintRequest, |
| 393 | output_proto: toolchain_pb2.DashboardLintResponse, |
| 394 | _config, |
| 395 | ): |
Greg Edelston | dae510a | 2023-06-30 15:25:36 -0600 | [diff] [blame] | 396 | """Lint all platform2 packages and uploads lints to GS""" |
Adrian Dole | f87c576 | 2022-12-15 22:00:50 +0000 | [diff] [blame] | 397 | board = input_proto.sysroot.build_target.name |
| 398 | output_proto.gs_path = toolchain.emerge_and_upload_lints( |
| 399 | board, input_proto.start_time |
| 400 | ) |
| 401 | |
| 402 | |
Ryan Beltran | 0df7fb0 | 2021-11-10 20:58:51 +0000 | [diff] [blame] | 403 | @faux.all_empty |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 404 | @validate.exists("sysroot.path") |
| 405 | @validate.require("packages") |
Ryan Beltran | 0df7fb0 | 2021-11-10 20:58:51 +0000 | [diff] [blame] | 406 | @validate.validation_complete |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 407 | def EmergeWithLinting( |
| 408 | input_proto: "toolchain_pb2.LinterRequest", |
| 409 | output_proto: "toolchain_pb2.LinterResponse", |
| 410 | _config: "api_config.ApiConfig", |
| 411 | ): |
| 412 | """Emerge packages with linter features enabled and retrieves all findings. |
Ryan Beltran | 0df7fb0 | 2021-11-10 20:58:51 +0000 | [diff] [blame] | 413 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 414 | Args: |
Adrian Dole | f87c576 | 2022-12-15 22:00:50 +0000 | [diff] [blame] | 415 | input_proto: The input proto with package and sysroot info. |
Alex Klein | 611dddd | 2022-10-11 17:02:01 -0600 | [diff] [blame] | 416 | output_proto: The output proto where findings are stored. |
| 417 | _config: The API call config (unused). |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 418 | """ |
| 419 | packages = [ |
| 420 | controller_util.deserialize_package_info(package) |
| 421 | for package in input_proto.packages |
| 422 | ] |
Ryan Beltran | 7d19180 | 2021-11-24 00:08:17 +0000 | [diff] [blame] | 423 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 424 | build_linter = toolchain.BuildLinter( |
| 425 | packages, |
| 426 | input_proto.sysroot.path, |
| 427 | differential=input_proto.filter_modified, |
| 428 | ) |
Ryan Beltran | 7d19180 | 2021-11-24 00:08:17 +0000 | [diff] [blame] | 429 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 430 | use_clippy = ( |
| 431 | toolchain_pb2.LinterFinding.CARGO_CLIPPY |
| 432 | not in input_proto.disabled_linters |
| 433 | ) |
| 434 | use_tidy = ( |
| 435 | toolchain_pb2.LinterFinding.CLANG_TIDY |
| 436 | not in input_proto.disabled_linters |
| 437 | ) |
| 438 | use_golint = ( |
| 439 | toolchain_pb2.LinterFinding.GO_LINT not in input_proto.disabled_linters |
| 440 | ) |
Ryan Beltran | 1277cb8 | 2022-11-27 03:15:36 +0000 | [diff] [blame] | 441 | use_iwyu = ( |
| 442 | toolchain_pb2.LinterFinding.IWYU not in input_proto.disabled_linters |
| 443 | ) |
Ryan Beltran | 4425d5f | 2022-07-20 18:34:33 +0000 | [diff] [blame] | 444 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 445 | findings = build_linter.emerge_with_linting( |
Ryan Beltran | 1277cb8 | 2022-11-27 03:15:36 +0000 | [diff] [blame] | 446 | use_clippy=use_clippy, |
| 447 | use_tidy=use_tidy, |
| 448 | use_golint=use_golint, |
| 449 | use_iwyu=use_iwyu, |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 450 | ) |
Ryan Beltran | f9a86f4 | 2022-04-13 20:58:18 +0000 | [diff] [blame] | 451 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 452 | for finding in findings: |
| 453 | locations = [] |
| 454 | for location in finding.locations: |
| 455 | locations.append( |
| 456 | toolchain_pb2.LinterFindingLocation( |
| 457 | filepath=location.filepath, |
| 458 | line_start=location.line_start, |
| 459 | line_end=location.line_end, |
| 460 | ) |
| 461 | ) |
Alex Klein | 860d56f | 2023-07-19 11:16:46 -0600 | [diff] [blame] | 462 | |
| 463 | pkg = PackageInfo() |
| 464 | if finding.package: |
| 465 | pkg.category = finding.package.category |
| 466 | pkg.package_name = finding.package.package |
| 467 | pkg.version = finding.package.version |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 468 | output_proto.findings.append( |
| 469 | toolchain_pb2.LinterFinding( |
| 470 | message=finding.message, |
| 471 | locations=locations, |
| 472 | linter=LINTER_CODES[finding.linter], |
Alex Klein | 860d56f | 2023-07-19 11:16:46 -0600 | [diff] [blame] | 473 | package=pkg, |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 474 | ) |
| 475 | ) |
Jack Neus | 4ee7b1d | 2022-06-27 19:54:18 +0000 | [diff] [blame] | 476 | |
| 477 | |
| 478 | @faux.all_empty |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 479 | @validate.require("board") |
Jack Neus | 4ee7b1d | 2022-06-27 19:54:18 +0000 | [diff] [blame] | 480 | @validate.validation_complete |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 481 | def GetToolchainsForBoard( |
| 482 | input_proto: "toolchain_pb2.ToolchainsRequest", |
| 483 | output_proto: "toolchain_pb2.ToolchainsReponse", |
| 484 | _config: "api_config.ApiConfig", |
| 485 | ): |
Greg Edelston | dae510a | 2023-06-30 15:25:36 -0600 | [diff] [blame] | 486 | """Get the default and non-default toolchains for a board. |
Jack Neus | 4ee7b1d | 2022-06-27 19:54:18 +0000 | [diff] [blame] | 487 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 488 | Args: |
Alex Klein | 611dddd | 2022-10-11 17:02:01 -0600 | [diff] [blame] | 489 | input_proto: The input proto with board and sysroot info. |
| 490 | output_proto: The output proto where findings are stored. |
| 491 | _config: The API call config (unused). |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 492 | """ |
| 493 | toolchains = toolchain_lib.GetToolchainsForBoard(input_proto.board) |
| 494 | output_proto.default_toolchains.extend( |
| 495 | list(toolchain_lib.FilterToolchains(toolchains, "default", True)) |
| 496 | ) |
| 497 | output_proto.nondefault_toolchains.extend( |
| 498 | list(toolchain_lib.FilterToolchains(toolchains, "default", False)) |
| 499 | ) |
Greg Edelston | dae510a | 2023-06-30 15:25:36 -0600 | [diff] [blame] | 500 | |
| 501 | |
| 502 | @faux.all_empty |
Greg Edelston | dae510a | 2023-06-30 15:25:36 -0600 | [diff] [blame] | 503 | @validate.validation_complete |
| 504 | def SetupToolchains( |
| 505 | input_proto: "toolchain_pb2.SetupToolchainsRequest", |
| 506 | output_proto: "toolchain_pb2.SetupToolchainsResponse", |
| 507 | config: "api_config.ApiConfig", |
| 508 | ): |
| 509 | """Run `cros_setup_toolchains`.""" |
| 510 | del output_proto, config # Unused. |
| 511 | cros_build_lib.AssertInsideChroot() |
| 512 | include_boards = [bt.name for bt in input_proto.boards] |
| 513 | toolchain.setup_toolchains(include_boards=include_boards) |