blob: 7db51efaae260072bc81095b85db5f038ea39552 [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
Alex Klein076841b2019-08-29 15:19:39 -060012from chromite.api import faux
Alex Klein231d2da2019-07-22 16:44:45 -060013from chromite.api import validate
Tiancong Wang24a3df72019-08-20 15:48:51 -070014from chromite.api.gen.chromite.api import toolchain_pb2
Tiancong Wangaf050172019-07-10 11:52:03 -070015from chromite.lib import toolchain_util
LaMont Jonesb20b3d92019-11-23 11:47:48 -070016from chromite.api.gen.chromiumos.builder_config_pb2 import BuilderConfig
Tiancong Wangaf050172019-07-10 11:52:03 -070017
LaMont Jonesb20b3d92019-11-23 11:47:48 -070018# TODO(crbug/1019868): Add handlers as needed.
19_Handlers = collections.namedtuple('_Handlers', ['name', 'prepare', 'bundle'])
20_TOOLCHAIN_ARTIFACT_HANDLERS = {
21 BuilderConfig.Artifacts.UNVERIFIED_ORDERING_FILE:
22 _Handlers('UnverifiedOrderingFile', None, None),
23 BuilderConfig.Artifacts.VERIFIED_ORDERING_FILE:
24 _Handlers('VerifedOrderingFile', None, None),
25 BuilderConfig.Artifacts.CHROME_CLANG_WARNINGS_FILE:
26 _Handlers('ChromeClangWarningsFile', None, None),
27 BuilderConfig.Artifacts.UNVERIFIED_LLVM_PGO_FILE:
28 _Handlers('UnverifiedLlvmPgoFile', None, None),
29 BuilderConfig.Artifacts.UNVERIFIED_CHROME_AFDO_FILE:
30 _Handlers('UnverifiedChromeAfdoFile', None, None),
31 BuilderConfig.Artifacts.VERIFIED_CHROME_AFDO_FILE:
32 _Handlers('VerifiedChromeAfdoFile', None, None),
33 BuilderConfig.Artifacts.VERIFIED_KERNEL_AFDO_FILE:
34 _Handlers('VerifiedKernelAfdoFile', None, None),
35}
36
37
38# TODO(crbug/1031213): When @faux is expanded to have more than success/failure,
39# this should be changed.
40@faux.all_empty
41@validate.require('artifact_types')
42@validate.validation_complete
43def PrepareForBuild(input_proto, output_proto, _config):
44 """Prepare to build toolchain artifacts.
45
46 The handlers (from _TOOLCHAIN_ARTIFACT_HANDLERS above) are called with:
47 artifact_name (str): name of the artifact type.
LaMont Jonesa215f1e2019-12-06 10:18:58 -070048 chroot_path (str): chroot path (absolute path)
49 sysroot_path (str): sysroot path inside the chroot (e.g., /build/atlas)
50 build_target_name (str): name of the build target (e.g., atlas)
51
52 They locate and modify any ebuilds and/or source required for the artifact
53 being created, then return a value from toolchain_util.PrepareForBuildReturn.
LaMont Jonesb20b3d92019-11-23 11:47:48 -070054
55 Args:
56 input_proto (PrepareForToolchainBuildRequest): The input proto
57 output_proto (PrepareForToolchainBuildResponse): The output proto
58 _config (api_config.ApiConfig): The API call config.
59 """
60 results = set()
61 for artifact_type in input_proto.artifact_types:
62 # Ignore any artifact_types not handled.
63 handler = _TOOLCHAIN_ARTIFACT_HANDLERS.get(artifact_type)
64 if handler and handler.prepare:
LaMont Jonesa215f1e2019-12-06 10:18:58 -070065 results.add(handler.prepare(
66 handler.name, input_proto.chroot.path, input_proto.sysroot.path,
67 input_proto.sysroot.build_target.name))
LaMont Jonesb20b3d92019-11-23 11:47:48 -070068
69 # Translate the returns from the handlers we called.
70 # If any NEEDED => NEEDED
71 # elif any UNKNOWN => UNKNOWN
72 # elif any POINTLESS => POINTLESS
73 # else UNKNOWN.
74 proto_resp = toolchain_pb2.PrepareForToolchainBuildResponse
75 if toolchain_util.PrepareForBuildReturn.NEEDED in results:
76 output_proto.build_relevance = proto_resp.NEEDED
77 elif toolchain_util.PrepareForBuildReturn.UNKNOWN in results:
78 output_proto.build_relevance = proto_resp.UNKNOWN
79 elif toolchain_util.PrepareForBuildReturn.POINTLESS in results:
80 output_proto.build_relevance = proto_resp.POINTLESS
81 else:
82 output_proto.build_relevance = proto_resp.UNKNOWN
83
84
85# TODO(crbug/1031213): When @faux is expanded to have more than success/failure,
86# this should be changed.
87@faux.all_empty
88@validate.require('artifact_types')
89@validate.require('output_dir')
90def BundleArtifacts(input_proto, output_proto, _config):
91 """Bundle toolchain artifacts.
92
93 The handlers (from _TOOLCHAIN_ARTIFACT_HANDLERS above) are called with:
LaMont Jonesa215f1e2019-12-06 10:18:58 -070094 artifact_name (str): name of the artifact type
LaMont Jonesb20b3d92019-11-23 11:47:48 -070095 chroot_path (str): chroot path (absolute path)
96 sysroot_path (str): sysroot path inside the chroot (e.g., /build/atlas)
97 build_target_name (str): name of the build target (e.g., atlas)
98 output_dir (str): absolute path where artifacts are being bundled.
99 (e.g., /b/s/w/ir/k/recipe_cleanup/artifactssptfMU)
100
101 Note: the actual upload to GS is done by CI, not here.
102
103 Args:
104 input_proto (BundleToolchainRequest): The input proto
105 output_proto (BundleToolchainResponse): The output proto
106 _config (api_config.ApiConfig): The API call config.
107 """
LaMont Jonesa215f1e2019-12-06 10:18:58 -0700108 # TODO(crbug/1019868): This is moving, handle both cases.
109 resp_artifact = (
110 getattr(toolchain_pb2.BundleToolchainResponse, 'ArtifactInfo', None) or
111 getattr(toolchain_pb2, 'ArtifactInfo'))
112 # resp_artifact = toolchain_pb2.ArtifactInfo
LaMont Jonesb20b3d92019-11-23 11:47:48 -0700113
114 for artifact_type in input_proto.artifact_types:
115 # Ignore any artifact_types not handled.
116 handler = _TOOLCHAIN_ARTIFACT_HANDLERS.get(artifact_type)
117 if handler and handler.bundle:
118 artifacts = handler.bundle(
119 handler.name, input_proto.chroot.path, input_proto.sysroot.path,
120 input_proto.sysroot.build_target.name, input_proto.output_dir)
121 if artifacts:
122 output_proto.artifacts_info.append(
123 resp_artifact(artifact_type=artifact_type, artifacts=artifacts))
124
125
126# TODO(crbug/1019868): Remove legacy code when cbuildbot builders are gone.
127_NAMES_FOR_AFDO_ARTIFACTS = {
Tiancong Wangf9c736c2019-08-26 13:54:38 -0700128 toolchain_pb2.ORDERFILE: 'orderfile',
129 toolchain_pb2.KERNEL_AFDO: 'kernel_afdo',
130 toolchain_pb2.CHROME_AFDO: 'chrome_afdo'
131}
132
LaMont Jonesb20b3d92019-11-23 11:47:48 -0700133# TODO(crbug/1019868): Remove legacy code when cbuildbot builders are gone.
Tiancong Wangf9c736c2019-08-26 13:54:38 -0700134# Using a function instead of a dict because we need to mock these
135# functions in unittest, and mock doesn't play well with a dict definition.
LaMont Jonesb20b3d92019-11-23 11:47:48 -0700136def _GetMethodForUpdatingAFDOArtifacts(artifact_type):
Tiancong Wangf9c736c2019-08-26 13:54:38 -0700137 return {
138 toolchain_pb2.ORDERFILE: toolchain_util.OrderfileUpdateChromeEbuild,
139 toolchain_pb2.KERNEL_AFDO: toolchain_util.AFDOUpdateKernelEbuild,
140 toolchain_pb2.CHROME_AFDO: toolchain_util.AFDOUpdateChromeEbuild
141 }[artifact_type]
Tiancong Wang24a3df72019-08-20 15:48:51 -0700142
Tiancong Wangaf050172019-07-10 11:52:03 -0700143
LaMont Jonesb20b3d92019-11-23 11:47:48 -0700144# TODO(crbug/1019868): Remove legacy code when cbuildbot builders are gone.
Michael Mortensen54bd70a2019-11-21 14:45:38 -0700145def _UpdateEbuildWithAFDOArtifactsResponse(_input_proto, output_proto, _config):
146 """Add successful status to the faux response."""
147 output_proto.status = True
148
149
LaMont Jonesb20b3d92019-11-23 11:47:48 -0700150# TODO(crbug/1019868): Remove legacy code when cbuildbot builders are gone.
Michael Mortensen54bd70a2019-11-21 14:45:38 -0700151@faux.success(_UpdateEbuildWithAFDOArtifactsResponse)
152@faux.empty_error
Alex Klein231d2da2019-07-22 16:44:45 -0600153@validate.require('build_target.name')
LaMont Jonesb20b3d92019-11-23 11:47:48 -0700154@validate.is_in('artifact_type', _NAMES_FOR_AFDO_ARTIFACTS)
Alex Klein231d2da2019-07-22 16:44:45 -0600155@validate.validation_complete
Tiancong Wang24a3df72019-08-20 15:48:51 -0700156def UpdateEbuildWithAFDOArtifacts(input_proto, output_proto, _config):
157 """Update Chrome or kernel ebuild with most recent unvetted artifacts.
Tiancong Wangaf050172019-07-10 11:52:03 -0700158
159 Args:
Tiancong Wang24a3df72019-08-20 15:48:51 -0700160 input_proto (VerifyAFDOArtifactsRequest): The input proto
161 output_proto (VerifyAFDOArtifactsResponse): The output proto
Alex Klein231d2da2019-07-22 16:44:45 -0600162 _config (api_config.ApiConfig): The API call config.
Tiancong Wangaf050172019-07-10 11:52:03 -0700163 """
Tiancong Wangaf050172019-07-10 11:52:03 -0700164 board = input_proto.build_target.name
LaMont Jonesb20b3d92019-11-23 11:47:48 -0700165 update_method = _GetMethodForUpdatingAFDOArtifacts(input_proto.artifact_type)
Tiancong Wangf9c736c2019-08-26 13:54:38 -0700166 output_proto.status = update_method(board)
Tiancong Wangaf050172019-07-10 11:52:03 -0700167
168
LaMont Jonesb20b3d92019-11-23 11:47:48 -0700169# TODO(crbug/1019868): Remove legacy code when cbuildbot builders are gone.
Michael Mortensen54bd70a2019-11-21 14:45:38 -0700170def _UploadVettedAFDOArtifactsResponse(_input_proto, output_proto, _config):
171 """Add successful status to the faux response."""
172 output_proto.status = True
173
174
LaMont Jonesb20b3d92019-11-23 11:47:48 -0700175# TODO(crbug/1019868): Remove legacy code when cbuildbot builders are gone.
Michael Mortensen54bd70a2019-11-21 14:45:38 -0700176@faux.success(_UploadVettedAFDOArtifactsResponse)
177@faux.empty_error
Tiancong Wang24a3df72019-08-20 15:48:51 -0700178@validate.require('build_target.name')
LaMont Jonesb20b3d92019-11-23 11:47:48 -0700179@validate.is_in('artifact_type', _NAMES_FOR_AFDO_ARTIFACTS)
Alex Klein231d2da2019-07-22 16:44:45 -0600180@validate.validation_complete
Tiancong Wang24a3df72019-08-20 15:48:51 -0700181def UploadVettedAFDOArtifacts(input_proto, output_proto, _config):
Tiancong Wangaf050172019-07-10 11:52:03 -0700182 """Upload a vetted orderfile to GS bucket.
183
184 Args:
Tiancong Wang24a3df72019-08-20 15:48:51 -0700185 input_proto (VerifyAFDOArtifactsRequest): The input proto
186 output_proto (VerifyAFDOArtifactsResponse): The output proto
Alex Klein231d2da2019-07-22 16:44:45 -0600187 _config (api_config.ApiConfig): The API call config.
Tiancong Wangaf050172019-07-10 11:52:03 -0700188 """
Tiancong Wang24a3df72019-08-20 15:48:51 -0700189 board = input_proto.build_target.name
LaMont Jonesb20b3d92019-11-23 11:47:48 -0700190 artifact_type = _NAMES_FOR_AFDO_ARTIFACTS[input_proto.artifact_type]
Tiancong Wang24a3df72019-08-20 15:48:51 -0700191 output_proto.status = toolchain_util.UploadAndPublishVettedAFDOArtifacts(
192 artifact_type, board)