blob: 044747d54e6ba9d795d8a4fd988ca22d27bad43e [file] [log] [blame]
Mike Frysingerf1ba7ad2022-09-12 05:42:57 -04001# Copyright 2019 The ChromiumOS Authors
Evan Hernandezf388cbf2019-04-01 11:15:23 -06002# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
4
5"""Implements ArtifactService."""
6
Chris McDonald1672ddb2021-07-21 11:48:23 -06007import logging
Evan Hernandezf388cbf2019-04-01 11:15:23 -06008import os
Varun Somani04dccd72021-10-09 01:06:11 +00009from typing import Any, NamedTuple, Optional, TYPE_CHECKING
Evan Hernandezf388cbf2019-04-01 11:15:23 -060010
Alex Klein231d2da2019-07-22 16:44:45 -060011from chromite.api import controller
Alex Klein076841b2019-08-29 15:19:39 -060012from chromite.api import faux
Alex Klein2b236722019-06-19 15:44:26 -060013from chromite.api import validate
Alex Klein238d8862019-05-07 11:32:46 -060014from chromite.api.controller import controller_util
George Engelbrechtc9a8e812021-06-16 18:14:17 -060015from chromite.api.controller import image as image_controller
16from chromite.api.controller import sysroot as sysroot_controller
David Wellingc1433c22021-06-25 16:29:48 +000017from chromite.api.controller import test as test_controller
LaMont Jones58362a42021-02-04 17:40:08 -070018from chromite.api.gen.chromite.api import artifacts_pb2
Jaques Clapauchf616bcd2021-04-09 20:14:40 +000019from chromite.api.gen.chromiumos import common_pb2
Evan Hernandezf388cbf2019-04-01 11:15:23 -060020from chromite.lib import constants
21from chromite.lib import cros_build_lib
Alex Klein2275d692019-04-23 16:04:12 -060022from chromite.lib import sysroot_lib
23from chromite.service import artifacts
Greg Edelstondc941072021-08-11 12:32:30 -060024from chromite.service import test
Evan Hernandezf388cbf2019-04-01 11:15:23 -060025
Mike Frysinger1cc8f1f2022-04-28 22:40:40 -040026
Varun Somani04dccd72021-10-09 01:06:11 +000027if TYPE_CHECKING:
Alex Klein1699fab2022-09-08 08:46:06 -060028 from chromite.api import api_config
29
Evan Hernandezf388cbf2019-04-01 11:15:23 -060030
George Engelbrechtc9a8e812021-06-16 18:14:17 -060031class RegisteredGet(NamedTuple):
Alex Kleinb6847e22022-11-07 10:44:48 -070032 """A registered function for calling Get on an artifact type."""
Alex Klein1699fab2022-09-08 08:46:06 -060033
34 output_proto: artifacts_pb2.GetResponse
35 artifact_dict: Any
LaMont Jones0f5171b2021-01-29 12:28:56 -070036
37
Alex Kleinb6847e22022-11-07 10:44:48 -070038def ExampleGetResponse(_input_proto, _output_proto, _config) -> Optional[int]:
Alex Klein1699fab2022-09-08 08:46:06 -060039 """Give an example GetResponse with a minimal coverage set."""
40 _output_proto = artifacts_pb2.GetResponse(
41 artifacts=common_pb2.UploadedArtifactsByService(
42 image=image_controller.ExampleGetResponse(),
43 sysroot=sysroot_controller.ExampleGetResponse(),
44 )
45 )
46 return controller.RETURN_CODE_SUCCESS
George Engelbrechtc9a8e812021-06-16 18:14:17 -060047
48
LaMont Jones0f5171b2021-01-29 12:28:56 -070049@faux.empty_error
George Engelbrechtc9a8e812021-06-16 18:14:17 -060050@faux.success(ExampleGetResponse)
Alex Klein1699fab2022-09-08 08:46:06 -060051@validate.exists("result_path.path.path")
LaMont Jones0f5171b2021-01-29 12:28:56 -070052@validate.validation_complete
Varun Somani04dccd72021-10-09 01:06:11 +000053def Get(
54 input_proto: artifacts_pb2.GetRequest,
55 output_proto: artifacts_pb2.GetResponse,
Alex Klein1699fab2022-09-08 08:46:06 -060056 _config: "api_config.ApiConfig",
Alex Kleinb6847e22022-11-07 10:44:48 -070057) -> Optional[int]:
Alex Klein1699fab2022-09-08 08:46:06 -060058 """Get all artifacts.
LaMont Jones0f5171b2021-01-29 12:28:56 -070059
Alex Klein1699fab2022-09-08 08:46:06 -060060 Get all artifacts for the build.
LaMont Jones0f5171b2021-01-29 12:28:56 -070061
Alex Klein1699fab2022-09-08 08:46:06 -060062 Note: As the individual artifact_type bundlers are added here, they *must*
63 stop uploading it via the individual bundler function.
Alex Klein1699fab2022-09-08 08:46:06 -060064 """
65 output_dir = input_proto.result_path.path.path
Jaques Clapauchf616bcd2021-04-09 20:14:40 +000066
Alex Klein1699fab2022-09-08 08:46:06 -060067 sysroot = controller_util.ParseSysroot(input_proto.sysroot)
68 # This endpoint does not currently support any artifacts that are built
69 # without a sysroot being present.
70 if not sysroot.path:
71 return controller.RETURN_CODE_SUCCESS
72
73 chroot = controller_util.ParseChroot(input_proto.chroot)
74 build_target = controller_util.ParseBuildTarget(
75 input_proto.sysroot.build_target
76 )
77
78 # A list of RegisteredGet tuples (input proto, output proto, get results).
79 get_res_list = [
80 RegisteredGet(
81 output_proto.artifacts.image,
82 image_controller.GetArtifacts(
83 input_proto.artifact_info.image,
84 chroot,
85 sysroot,
86 build_target,
87 output_dir,
88 ),
89 ),
90 RegisteredGet(
91 output_proto.artifacts.sysroot,
92 sysroot_controller.GetArtifacts(
93 input_proto.artifact_info.sysroot,
94 chroot,
95 sysroot,
96 build_target,
97 output_dir,
98 ),
99 ),
100 RegisteredGet(
101 output_proto.artifacts.test,
102 test_controller.GetArtifacts(
103 input_proto.artifact_info.test,
104 chroot,
105 sysroot,
106 build_target,
107 output_dir,
108 ),
109 ),
110 ]
111
112 for get_res in get_res_list:
113 for artifact_dict in get_res.artifact_dict:
Jack Neus26b94672022-10-27 17:33:21 +0000114 kwargs = {}
115 # TODO(b/255838545): Remove the kwargs funkness when these fields
116 # have been added for all services.
117 if "failed" in artifact_dict:
118 kwargs["failed"] = artifact_dict.get("failed", False)
119 kwargs["failure_reason"] = artifact_dict.get("failure_reason")
Alex Klein1699fab2022-09-08 08:46:06 -0600120 get_res.output_proto.artifacts.add(
121 artifact_type=artifact_dict["type"],
122 paths=[
123 common_pb2.Path(
124 path=x, location=common_pb2.Path.Location.OUTSIDE
125 )
Jack Neus26b94672022-10-27 17:33:21 +0000126 for x in artifact_dict.get("paths", [])
Alex Klein1699fab2022-09-08 08:46:06 -0600127 ],
Jack Neus26b94672022-10-27 17:33:21 +0000128 **kwargs,
Alex Klein1699fab2022-09-08 08:46:06 -0600129 )
LaMont Jones8b88e9d2021-06-28 16:37:34 -0600130 return controller.RETURN_CODE_SUCCESS
131
LaMont Jones0f5171b2021-01-29 12:28:56 -0700132
Alex Kleinb6847e22022-11-07 10:44:48 -0700133def _BuildSetupResponse(_input_proto, output_proto, _config) -> None:
Alex Klein1699fab2022-09-08 08:46:06 -0600134 """Just return POINTLESS for now."""
Alex Kleinb6847e22022-11-07 10:44:48 -0700135 # All the artifact types we support claim that the build is POINTLESS.
Alex Klein1699fab2022-09-08 08:46:06 -0600136 output_proto.build_relevance = artifacts_pb2.BuildSetupResponse.POINTLESS
LaMont Jones58362a42021-02-04 17:40:08 -0700137
138
139@faux.success(_BuildSetupResponse)
140@faux.empty_error
141@validate.validation_complete
Varun Somani04dccd72021-10-09 01:06:11 +0000142def BuildSetup(
143 _input_proto: artifacts_pb2.GetRequest,
144 output_proto: artifacts_pb2.GetResponse,
Alex Klein1699fab2022-09-08 08:46:06 -0600145 _config: "api_config.ApiConfig",
Alex Kleinb6847e22022-11-07 10:44:48 -0700146) -> Optional[int]:
Alex Klein1699fab2022-09-08 08:46:06 -0600147 """Setup anything needed for building artifacts
LaMont Jones58362a42021-02-04 17:40:08 -0700148
Alex Klein1699fab2022-09-08 08:46:06 -0600149 If any artifact types require steps prior to building the package, they go
150 here. For example, see ToolchainService/PrepareForBuild.
LaMont Jones58362a42021-02-04 17:40:08 -0700151
Alex Klein1699fab2022-09-08 08:46:06 -0600152 Note: crbug/1034529 introduces this method as a noop. As the individual
153 artifact_type bundlers are added here, they *must* stop uploading it via the
154 individual bundler function.
Alex Klein1699fab2022-09-08 08:46:06 -0600155 """
156 # If any artifact_type says "NEEDED", the return is NEEDED.
157 # Otherwise, if any artifact_type says "UNKNOWN", the return is UNKNOWN.
158 # Otherwise, the return is POINTLESS.
159 output_proto.build_relevance = artifacts_pb2.BuildSetupResponse.POINTLESS
160 return controller.RETURN_CODE_SUCCESS
LaMont Jones58362a42021-02-04 17:40:08 -0700161
162
Varun Somani04dccd72021-10-09 01:06:11 +0000163def _GetImageDir(build_root: str, target: str) -> Optional[str]:
Alex Klein1699fab2022-09-08 08:46:06 -0600164 """Return path containing images for the given build target.
Evan Hernandez9f125ac2019-04-08 17:18:47 -0600165
Alex Klein1699fab2022-09-08 08:46:06 -0600166 TODO(saklein) Expand image_lib.GetLatestImageLink to support this use case.
Alex Kleine2612a02019-04-18 13:51:06 -0600167
Alex Klein1699fab2022-09-08 08:46:06 -0600168 Args:
Alex Klein611dddd2022-10-11 17:02:01 -0600169 build_root: Path to checkout where build occurs.
170 target: Name of the build target.
Evan Hernandez9f125ac2019-04-08 17:18:47 -0600171
Alex Klein1699fab2022-09-08 08:46:06 -0600172 Returns:
Alex Klein611dddd2022-10-11 17:02:01 -0600173 Path to the latest directory containing target images or None.
Alex Klein1699fab2022-09-08 08:46:06 -0600174 """
175 image_dir = os.path.join(build_root, "src/build/images", target, "latest")
176 if not os.path.exists(image_dir):
177 logging.warning(
178 "Expected to find image output for target %s at %s, but "
179 "path does not exist",
180 target,
181 image_dir,
182 )
183 return None
Alex Kleind2bf1462019-10-24 16:37:04 -0600184
Alex Klein1699fab2022-09-08 08:46:06 -0600185 return image_dir
Evan Hernandez9f125ac2019-04-08 17:18:47 -0600186
187
Alex Kleinb6847e22022-11-07 10:44:48 -0700188def _BundleImageArchivesResponse(input_proto, output_proto, _config) -> None:
Alex Klein1699fab2022-09-08 08:46:06 -0600189 """Add artifact paths to a successful response."""
Brian Norris4543de42023-07-18 11:09:00 -0700190 output_proto.artifacts.add(
191 artifact_path=common_pb2.Path(
192 path=os.path.join(
193 input_proto.result_path.path.path, "path0.tar.xz"
194 ),
195 location=common_pb2.Path.OUTSIDE,
196 )
Alex Klein1699fab2022-09-08 08:46:06 -0600197 )
Brian Norris4543de42023-07-18 11:09:00 -0700198 output_proto.artifacts.add(
199 artifact_path=common_pb2.Path(
200 path=os.path.join(
201 input_proto.result_path.path.path, "path1.tar.xz"
202 ),
203 location=common_pb2.Path.OUTSIDE,
204 )
Alex Klein1699fab2022-09-08 08:46:06 -0600205 )
Michael Mortensen2d6a2402019-11-26 13:40:40 -0700206
207
208@faux.success(_BundleImageArchivesResponse)
209@faux.empty_error
Hsin-Yi Wang09663da2023-06-28 21:40:24 +0800210@validate.require("sysroot.build_target.name", "sysroot.path")
Brian Norris4543de42023-07-18 11:09:00 -0700211@validate.exists("result_path.path.path")
Alex Kleind91e95a2019-09-17 10:39:02 -0600212@validate.validation_complete
Alex Kleinb6847e22022-11-07 10:44:48 -0700213def BundleImageArchives(
214 input_proto: artifacts_pb2.BundleRequest,
215 output_proto: artifacts_pb2.BundleResponse,
216 _config: "api_config.ApiConfig",
217) -> Optional[int]:
Alex Klein1699fab2022-09-08 08:46:06 -0600218 """Create a .tar.xz archive for each image that has been created."""
Hsin-Yi Wang09663da2023-06-28 21:40:24 +0800219 build_target = controller_util.ParseBuildTarget(
220 input_proto.sysroot.build_target
221 )
222 chroot = controller_util.ParseChroot(input_proto.chroot)
223 sysroot = controller_util.ParseSysroot(input_proto.sysroot)
Brian Norris4543de42023-07-18 11:09:00 -0700224 output_dir = input_proto.result_path.path.path
Alex Klein1699fab2022-09-08 08:46:06 -0600225 image_dir = _GetImageDir(constants.SOURCE_ROOT, build_target.name)
226 if image_dir is None:
227 return
Alex Kleind91e95a2019-09-17 10:39:02 -0600228
Hsin-Yi Wang09663da2023-06-28 21:40:24 +0800229 if not sysroot.Exists(chroot=chroot):
230 logging.warning("Sysroot does not exist: %s", sysroot.path)
231
232 archives = artifacts.ArchiveImages(chroot, sysroot, image_dir, output_dir)
Alex Kleind91e95a2019-09-17 10:39:02 -0600233
Alex Klein1699fab2022-09-08 08:46:06 -0600234 for archive in archives:
Brian Norris4543de42023-07-18 11:09:00 -0700235 output_proto.artifacts.add(
236 artifact_path=common_pb2.Path(
237 path=os.path.join(output_dir, archive),
238 location=common_pb2.Path.OUTSIDE,
239 )
240 )
Alex Kleind91e95a2019-09-17 10:39:02 -0600241
242
Alex Kleinb6847e22022-11-07 10:44:48 -0700243def _BundleImageZipResponse(input_proto, output_proto, _config) -> None:
Alex Klein1699fab2022-09-08 08:46:06 -0600244 """Add artifact zip files to a successful response."""
Brian Norris4543de42023-07-18 11:09:00 -0700245 output_proto.artifacts.add(
246 artifact_path=common_pb2.Path(
247 path=os.path.join(input_proto.result_path.path.path, "image.zip"),
248 location=common_pb2.Path.OUTSIDE,
249 )
Alex Klein1699fab2022-09-08 08:46:06 -0600250 )
Michael Mortensen2d6a2402019-11-26 13:40:40 -0700251
252
253@faux.success(_BundleImageZipResponse)
254@faux.empty_error
Brian Norris4543de42023-07-18 11:09:00 -0700255@validate.require("build_target.name", "result_path.path.path")
256@validate.exists("result_path.path.path")
Alex Klein231d2da2019-07-22 16:44:45 -0600257@validate.validation_complete
Varun Somani04dccd72021-10-09 01:06:11 +0000258def BundleImageZip(
259 input_proto: artifacts_pb2.BundleRequest,
260 output_proto: artifacts_pb2.BundleResponse,
Alex Klein1699fab2022-09-08 08:46:06 -0600261 _config: "api_config.ApiConfig",
Alex Kleinb6847e22022-11-07 10:44:48 -0700262) -> Optional[int]:
263 """Bundle image.zip."""
Alex Klein1699fab2022-09-08 08:46:06 -0600264 target = input_proto.build_target.name
Brian Norris4543de42023-07-18 11:09:00 -0700265 output_dir = input_proto.result_path.path.path
Alex Klein1699fab2022-09-08 08:46:06 -0600266 image_dir = _GetImageDir(constants.SOURCE_ROOT, target)
267 if image_dir is None:
Alex Kleinb6847e22022-11-07 10:44:48 -0700268 logging.warning("Image build directory not found.")
Alex Klein1699fab2022-09-08 08:46:06 -0600269 return None
Alex Klein231d2da2019-07-22 16:44:45 -0600270
Alex Klein1699fab2022-09-08 08:46:06 -0600271 archive = artifacts.BundleImageZip(output_dir, image_dir)
Brian Norris4543de42023-07-18 11:09:00 -0700272 output_proto.artifacts.add(
273 artifact_path=common_pb2.Path(
274 path=os.path.join(output_dir, archive),
275 location=common_pb2.Path.OUTSIDE,
276 )
277 )
Evan Hernandez9f125ac2019-04-08 17:18:47 -0600278
279
Alex Kleinb6847e22022-11-07 10:44:48 -0700280def _BundleTestUpdatePayloadsResponse(
281 input_proto, output_proto, _config
282) -> None:
Alex Klein1699fab2022-09-08 08:46:06 -0600283 """Add test payload files to a successful response."""
Brian Norris4543de42023-07-18 11:09:00 -0700284 output_proto.artifacts.add(
285 artifact_path=common_pb2.Path(
286 path=os.path.join(
287 input_proto.result_path.path.path, "payload1.bin"
288 ),
289 location=common_pb2.Path.OUTSIDE,
290 )
Alex Klein1699fab2022-09-08 08:46:06 -0600291 )
Brian Norris4543de42023-07-18 11:09:00 -0700292 output_proto.artifacts.add(
293 artifact_path=common_pb2.Path(
294 path=os.path.join(
295 input_proto.result_path.path.path, "payload1.json"
296 ),
297 location=common_pb2.Path.OUTSIDE,
298 )
Alex Klein1699fab2022-09-08 08:46:06 -0600299 )
Brian Norris4543de42023-07-18 11:09:00 -0700300 output_proto.artifacts.add(
301 artifact_path=common_pb2.Path(
302 path=os.path.join(
303 input_proto.result_path.path.path, "payload1.log"
304 ),
305 location=common_pb2.Path.OUTSIDE,
306 )
Alex Klein1699fab2022-09-08 08:46:06 -0600307 )
Michael Mortensen2d6a2402019-11-26 13:40:40 -0700308
309
310@faux.success(_BundleTestUpdatePayloadsResponse)
311@faux.empty_error
Brian Norris76b5aa62023-07-18 14:36:17 -0700312@validate.require("build_target.name")
Alex Klein231d2da2019-07-22 16:44:45 -0600313@validate.validation_complete
Varun Somani04dccd72021-10-09 01:06:11 +0000314def BundleTestUpdatePayloads(
315 input_proto: artifacts_pb2.BundleRequest,
316 output_proto: artifacts_pb2.BundleResponse,
Alex Klein1699fab2022-09-08 08:46:06 -0600317 _config: "api_config.ApiConfig",
Alex Kleinb6847e22022-11-07 10:44:48 -0700318) -> Optional[int]:
319 """Generate minimal update payloads for the build target for testing."""
Alex Klein1699fab2022-09-08 08:46:06 -0600320 target = input_proto.build_target.name
Brian Norrisdd2e7e62023-06-16 14:07:32 -0700321 chroot = controller_util.ParseChroot(input_proto.chroot)
Alex Klein1699fab2022-09-08 08:46:06 -0600322 build_root = constants.SOURCE_ROOT
Brian Norris76b5aa62023-07-18 14:36:17 -0700323 # Leave artifact output intact, for the router layer to copy it out of the
324 # chroot. This may leave stray files leftover, but builders should clean
325 # these up.
326 output_dir = chroot.tempdir(delete=False)
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600327
Alex Klein1699fab2022-09-08 08:46:06 -0600328 # Use the first available image to create the update payload.
329 img_dir = _GetImageDir(build_root, target)
330 if img_dir is None:
331 return None
Alex Kleind2bf1462019-10-24 16:37:04 -0600332
Alex Klein1699fab2022-09-08 08:46:06 -0600333 img_types = [
334 constants.IMAGE_TYPE_TEST,
335 constants.IMAGE_TYPE_DEV,
336 constants.IMAGE_TYPE_BASE,
337 ]
338 img_names = [constants.IMAGE_TYPE_TO_NAME[t] for t in img_types]
339 img_paths = [os.path.join(img_dir, x) for x in img_names]
340 valid_images = [x for x in img_paths if os.path.exists(x)]
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600341
Alex Klein1699fab2022-09-08 08:46:06 -0600342 if not valid_images:
343 cros_build_lib.Die(
344 'Expected to find an image of type among %r for target "%s" '
345 "at path %s.",
346 img_types,
347 target,
348 img_dir,
349 )
350 image = valid_images[0]
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600351
Brian Norris76b5aa62023-07-18 14:36:17 -0700352 payloads = artifacts.BundleTestUpdatePayloads(
353 chroot, image, str(output_dir)
354 )
Alex Klein1699fab2022-09-08 08:46:06 -0600355 for payload in payloads:
Brian Norris4543de42023-07-18 11:09:00 -0700356 output_proto.artifacts.add(
357 artifact_path=common_pb2.Path(
Brian Norris76b5aa62023-07-18 14:36:17 -0700358 path=payload, location=common_pb2.Path.INSIDE
Brian Norris4543de42023-07-18 11:09:00 -0700359 ),
360 )
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600361
362
Alex Kleinb6847e22022-11-07 10:44:48 -0700363def _BundleAutotestFilesResponse(input_proto, output_proto, _config) -> None:
Alex Klein1699fab2022-09-08 08:46:06 -0600364 """Add test autotest files to a successful response."""
Brian Norris4543de42023-07-18 11:09:00 -0700365 output_proto.artifacts.add(
366 artifact_path=common_pb2.Path(
367 path=os.path.join(
368 input_proto.result_path.path.path, "autotest-a.tar.gz"
369 ),
370 location=common_pb2.Path.OUTSIDE,
371 )
Alex Klein1699fab2022-09-08 08:46:06 -0600372 )
Michael Mortensen2d6a2402019-11-26 13:40:40 -0700373
374
375@faux.success(_BundleAutotestFilesResponse)
376@faux.empty_error
Alex Klein1699fab2022-09-08 08:46:06 -0600377@validate.require("sysroot.path")
Brian Norris4543de42023-07-18 11:09:00 -0700378@validate.exists("result_path.path.path")
Alex Klein036833d2022-06-01 13:05:01 -0600379@validate.validation_complete
Alex Klein1699fab2022-09-08 08:46:06 -0600380def BundleAutotestFiles(
381 input_proto: artifacts_pb2.BundleRequest,
382 output_proto: artifacts_pb2.BundleResponse,
383 _config: "api_config.ApiConfig",
Alex Kleinb6847e22022-11-07 10:44:48 -0700384) -> Optional[int]:
Alex Klein1699fab2022-09-08 08:46:06 -0600385 """Tar the autotest files for a build target."""
Brian Norris4543de42023-07-18 11:09:00 -0700386 output_dir = input_proto.result_path.path.path
Alex Klein1699fab2022-09-08 08:46:06 -0600387 chroot = controller_util.ParseChroot(input_proto.chroot)
388 sysroot = controller_util.ParseSysroot(input_proto.sysroot)
Alex Klein231d2da2019-07-22 16:44:45 -0600389
Alex Klein1699fab2022-09-08 08:46:06 -0600390 if not sysroot.Exists(chroot=chroot):
391 logging.warning("Sysroot does not exist: %s", sysroot.path)
392 return
Alex Klein238d8862019-05-07 11:32:46 -0600393
Alex Klein1699fab2022-09-08 08:46:06 -0600394 try:
395 # Note that this returns the full path to *multiple* tarballs.
396 archives = artifacts.BundleAutotestFiles(chroot, sysroot, output_dir)
397 except artifacts.Error as e:
398 logging.warning(e)
399 return
Alex Klein238d8862019-05-07 11:32:46 -0600400
Alex Klein1699fab2022-09-08 08:46:06 -0600401 for archive in archives.values():
Brian Norris4543de42023-07-18 11:09:00 -0700402 output_proto.artifacts.add(
403 artifact_path=common_pb2.Path(
404 path=archive, location=common_pb2.Path.OUTSIDE
405 )
406 )
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600407
408
Alex Kleinb6847e22022-11-07 10:44:48 -0700409def _BundleTastFilesResponse(input_proto, output_proto, _config) -> None:
Alex Klein1699fab2022-09-08 08:46:06 -0600410 """Add test tast files to a successful response."""
Brian Norris4543de42023-07-18 11:09:00 -0700411 output_proto.artifacts.add(
412 artifact_path=common_pb2.Path(
413 path=os.path.join(
414 input_proto.result_path.path.path, "tast_bundles.tar.gz"
415 ),
416 location=common_pb2.Path.OUTSIDE,
417 )
Alex Klein1699fab2022-09-08 08:46:06 -0600418 )
Michael Mortensen2d6a2402019-11-26 13:40:40 -0700419
420
421@faux.success(_BundleTastFilesResponse)
422@faux.empty_error
Alex Klein1699fab2022-09-08 08:46:06 -0600423@validate.require("sysroot.path")
Brian Norris4543de42023-07-18 11:09:00 -0700424@validate.exists("result_path.path.path")
Alex Klein036833d2022-06-01 13:05:01 -0600425@validate.validation_complete
Alex Klein1699fab2022-09-08 08:46:06 -0600426def BundleTastFiles(
427 input_proto: artifacts_pb2.BundleRequest,
428 output_proto: artifacts_pb2.BundleResponse,
429 _config: "api_config.ApiConfig",
Alex Kleinb6847e22022-11-07 10:44:48 -0700430) -> Optional[int]:
Alex Klein1699fab2022-09-08 08:46:06 -0600431 """Tar the tast files for a build target."""
Brian Norris4543de42023-07-18 11:09:00 -0700432 output_dir = input_proto.result_path.path.path
Alex Klein1699fab2022-09-08 08:46:06 -0600433 chroot = controller_util.ParseChroot(input_proto.chroot)
434 sysroot = controller_util.ParseSysroot(input_proto.sysroot)
Alex Kleinb9d810b2019-07-01 12:38:02 -0600435
Alex Klein1699fab2022-09-08 08:46:06 -0600436 if not sysroot.Exists(chroot=chroot):
437 logging.warning("Sysroot does not exist: %s", sysroot.path)
438 return
Alex Kleinb9d810b2019-07-01 12:38:02 -0600439
Alex Klein1699fab2022-09-08 08:46:06 -0600440 archive = artifacts.BundleTastFiles(chroot, sysroot, output_dir)
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600441
Alex Klein1699fab2022-09-08 08:46:06 -0600442 if not archive:
443 logging.warning("Found no tast files for %s.", sysroot.path)
444 return
Alex Klein036833d2022-06-01 13:05:01 -0600445
Brian Norris4543de42023-07-18 11:09:00 -0700446 output_proto.artifacts.add(
447 artifact_path=common_pb2.Path(
448 path=archive, location=common_pb2.Path.OUTSIDE
449 )
450 )
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600451
452
Fergus Dall34d74e12020-09-29 15:52:32 +1000453def BundlePinnedGuestImages(_input_proto, _output_proto, _config):
Alex Klein1699fab2022-09-08 08:46:06 -0600454 # TODO(crbug/1034529): Remove this endpoint
455 pass
456
Michael Mortensen2d6a2402019-11-26 13:40:40 -0700457
Fergus Dall34d74e12020-09-29 15:52:32 +1000458def FetchPinnedGuestImageUris(_input_proto, _output_proto, _config):
Alex Klein1699fab2022-09-08 08:46:06 -0600459 # TODO(crbug/1034529): Remove this endpoint
460 pass
Alex Klein7bf0ecb2019-06-25 10:04:15 -0600461
462
Alex Kleinb6847e22022-11-07 10:44:48 -0700463def _FetchMetadataResponse(
464 _input_proto, output_proto, _config
465) -> Optional[int]:
Alex Klein1699fab2022-09-08 08:46:06 -0600466 """Populate the output_proto with sample data."""
467 for fp in ("/metadata/foo.txt", "/metadata/bar.jsonproto"):
468 output_proto.filepaths.add(
469 path=common_pb2.Path(path=fp, location=common_pb2.Path.OUTSIDE)
470 )
471 return controller.RETURN_CODE_SUCCESS
Greg Edelstondc941072021-08-11 12:32:30 -0600472
473
474@faux.success(_FetchMetadataResponse)
475@faux.empty_error
Alex Klein1699fab2022-09-08 08:46:06 -0600476@validate.exists("chroot.path")
477@validate.require("sysroot.path")
Greg Edelstondc941072021-08-11 12:32:30 -0600478@validate.validation_complete
Varun Somani04dccd72021-10-09 01:06:11 +0000479def FetchMetadata(
480 input_proto: artifacts_pb2.FetchMetadataRequest,
481 output_proto: artifacts_pb2.FetchMetadataResponse,
Alex Klein1699fab2022-09-08 08:46:06 -0600482 _config: "api_config.ApiConfig",
Alex Kleinb6847e22022-11-07 10:44:48 -0700483) -> Optional[int]:
Alex Klein1699fab2022-09-08 08:46:06 -0600484 """FetchMetadata returns the paths to all build/test metadata files.
Greg Edelstondc941072021-08-11 12:32:30 -0600485
Alex Klein1699fab2022-09-08 08:46:06 -0600486 This implements ArtifactsService.FetchMetadata.
Alex Klein1699fab2022-09-08 08:46:06 -0600487 """
488 chroot = controller_util.ParseChroot(input_proto.chroot)
489 sysroot = controller_util.ParseSysroot(input_proto.sysroot)
490 for path in test.FindAllMetadataFiles(chroot, sysroot):
491 output_proto.filepaths.add(
492 path=common_pb2.Path(path=path, location=common_pb2.Path.OUTSIDE)
493 )
494 return controller.RETURN_CODE_SUCCESS
Greg Edelstondc941072021-08-11 12:32:30 -0600495
496
Michael Mortensen2d6a2402019-11-26 13:40:40 -0700497def _BundleFirmwareResponse(input_proto, output_proto, _config):
Alex Klein1699fab2022-09-08 08:46:06 -0600498 """Add test firmware image files to a successful response."""
Brian Norris4543de42023-07-18 11:09:00 -0700499 output_proto.artifacts.add(
500 artifact_path=common_pb2.Path(
501 path=os.path.join(
502 input_proto.result_path.path.path, "firmware.tar.gz"
503 ),
504 location=common_pb2.Path.OUTSIDE,
505 )
Alex Klein1699fab2022-09-08 08:46:06 -0600506 )
Michael Mortensen2d6a2402019-11-26 13:40:40 -0700507
508
509@faux.success(_BundleFirmwareResponse)
510@faux.empty_error
Alex Klein1699fab2022-09-08 08:46:06 -0600511@validate.require("sysroot.path")
Brian Norris4543de42023-07-18 11:09:00 -0700512@validate.exists("result_path.path.path")
Alex Klein231d2da2019-07-22 16:44:45 -0600513@validate.validation_complete
Alex Klein1699fab2022-09-08 08:46:06 -0600514def BundleFirmware(
515 input_proto: artifacts_pb2.BundleRequest,
516 output_proto: artifacts_pb2.BundleResponse,
517 _config: "api_config.ApiConfig",
Alex Kleinb6847e22022-11-07 10:44:48 -0700518) -> Optional[int]:
Alex Klein1699fab2022-09-08 08:46:06 -0600519 """Tar the firmware images for a build target."""
Brian Norris4543de42023-07-18 11:09:00 -0700520 output_dir = input_proto.result_path.path.path
Alex Klein1699fab2022-09-08 08:46:06 -0600521 chroot = controller_util.ParseChroot(input_proto.chroot)
522 sysroot = controller_util.ParseSysroot(input_proto.sysroot)
Alex Klein231d2da2019-07-22 16:44:45 -0600523
Alex Klein1699fab2022-09-08 08:46:06 -0600524 if not chroot.exists():
525 logging.warning("Chroot does not exist: %s", chroot.path)
526 return
527 elif not sysroot.Exists(chroot=chroot):
528 logging.warning("Sysroot does not exist: %s", sysroot.path)
529 return
Alex Klein231d2da2019-07-22 16:44:45 -0600530
Alex Klein1699fab2022-09-08 08:46:06 -0600531 archive = artifacts.BuildFirmwareArchive(chroot, sysroot, output_dir)
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600532
Alex Klein1699fab2022-09-08 08:46:06 -0600533 if not archive:
534 logging.warning(
535 "Could not create firmware archive. No firmware found for %s.",
536 sysroot.path,
537 )
538 return
Evan Hernandez9a5d3122019-04-09 10:51:23 -0600539
Brian Norris4543de42023-07-18 11:09:00 -0700540 output_proto.artifacts.add(
541 artifact_path=common_pb2.Path(
542 path=archive, location=common_pb2.Path.OUTSIDE
543 )
544 )
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600545
546
Alex Kleinb6847e22022-11-07 10:44:48 -0700547def _BundleFpmcuUnittestsResponse(input_proto, output_proto, _config) -> None:
Alex Klein1699fab2022-09-08 08:46:06 -0600548 """Add fingerprint MCU unittest binaries to a successful response."""
Brian Norris4543de42023-07-18 11:09:00 -0700549 output_proto.artifacts.add(
550 artifact_path=common_pb2.Path(
551 path=os.path.join(
552 input_proto.result_path.path.path, "fpmcu_unittests.tar.gz"
553 ),
554 location=common_pb2.Path.OUTSIDE,
555 )
Alex Klein1699fab2022-09-08 08:46:06 -0600556 )
Yicheng Liea1181f2020-09-22 11:51:10 -0700557
558
559@faux.success(_BundleFpmcuUnittestsResponse)
560@faux.empty_error
Alex Klein1699fab2022-09-08 08:46:06 -0600561@validate.require("sysroot.path")
Brian Norris4543de42023-07-18 11:09:00 -0700562@validate.exists("result_path.path.path")
Yicheng Liea1181f2020-09-22 11:51:10 -0700563@validate.validation_complete
Alex Klein1699fab2022-09-08 08:46:06 -0600564def BundleFpmcuUnittests(
565 input_proto: artifacts_pb2.BundleRequest,
566 output_proto: artifacts_pb2.BundleResponse,
567 _config: "api_config.ApiConfig",
Alex Kleinb6847e22022-11-07 10:44:48 -0700568) -> Optional[int]:
569 """Tar the fingerprint MCU unittest binaries for a build target."""
Brian Norris4543de42023-07-18 11:09:00 -0700570 output_dir = input_proto.result_path.path.path
Alex Klein1699fab2022-09-08 08:46:06 -0600571 chroot = controller_util.ParseChroot(input_proto.chroot)
572 sysroot = controller_util.ParseSysroot(input_proto.sysroot)
Yicheng Liea1181f2020-09-22 11:51:10 -0700573
Alex Klein1699fab2022-09-08 08:46:06 -0600574 if not chroot.exists():
575 logging.warning("Chroot does not exist: %s", chroot.path)
576 return
577 elif not sysroot.Exists(chroot=chroot):
578 logging.warning("Sysroot does not exist: %s", sysroot.path)
579 return
Yicheng Liea1181f2020-09-22 11:51:10 -0700580
Alex Klein1699fab2022-09-08 08:46:06 -0600581 archive = artifacts.BundleFpmcuUnittests(chroot, sysroot, output_dir)
Yicheng Liea1181f2020-09-22 11:51:10 -0700582
Alex Klein1699fab2022-09-08 08:46:06 -0600583 if not archive:
584 logging.warning("No fpmcu unittests found for %s.", sysroot.path)
585 return
Yicheng Liea1181f2020-09-22 11:51:10 -0700586
Brian Norris4543de42023-07-18 11:09:00 -0700587 output_proto.artifacts.add(
588 artifact_path=common_pb2.Path(
589 path=archive, location=common_pb2.Path.OUTSIDE
590 )
591 )
Yicheng Liea1181f2020-09-22 11:51:10 -0700592
593
Alex Kleinb6847e22022-11-07 10:44:48 -0700594def _BundleEbuildLogsResponse(input_proto, output_proto, _config) -> None:
Alex Klein1699fab2022-09-08 08:46:06 -0600595 """Add test log files to a successful response."""
Brian Norris4543de42023-07-18 11:09:00 -0700596 output_proto.artifacts.add(
597 artifact_path=common_pb2.Path(
598 path=os.path.join(
599 input_proto.result_path.path.path, "ebuild-logs.tar.gz"
600 ),
601 location=common_pb2.Path.OUTSIDE,
602 )
Alex Klein1699fab2022-09-08 08:46:06 -0600603 )
Michael Mortensen2d6a2402019-11-26 13:40:40 -0700604
605
606@faux.success(_BundleEbuildLogsResponse)
607@faux.empty_error
Alex Klein1699fab2022-09-08 08:46:06 -0600608@validate.require("sysroot.path")
Brian Norris4543de42023-07-18 11:09:00 -0700609@validate.exists("result_path.path.path")
Alex Klein036833d2022-06-01 13:05:01 -0600610@validate.validation_complete
Alex Klein1699fab2022-09-08 08:46:06 -0600611def BundleEbuildLogs(
612 input_proto: artifacts_pb2.BundleRequest,
613 output_proto: artifacts_pb2.BundleResponse,
614 _config: "api_config.ApiConfig",
Alex Kleinb6847e22022-11-07 10:44:48 -0700615) -> Optional[int]:
Alex Klein1699fab2022-09-08 08:46:06 -0600616 """Tar the ebuild logs for a build target."""
Brian Norris4543de42023-07-18 11:09:00 -0700617 output_dir = input_proto.result_path.path.path
Alex Klein1699fab2022-09-08 08:46:06 -0600618 chroot = controller_util.ParseChroot(input_proto.chroot)
619 sysroot = controller_util.ParseSysroot(input_proto.sysroot)
Evan Hernandeza478d802019-04-08 15:08:24 -0600620
Alex Klein1699fab2022-09-08 08:46:06 -0600621 if not sysroot.Exists(chroot=chroot):
622 logging.warning("Sysroot does not exist: %s", sysroot.path)
623 return
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600624
Alex Klein1699fab2022-09-08 08:46:06 -0600625 archive = artifacts.BundleEBuildLogsTarball(chroot, sysroot, output_dir)
Alex Klein036833d2022-06-01 13:05:01 -0600626
Alex Klein1699fab2022-09-08 08:46:06 -0600627 if not archive:
628 logging.warning(
629 "Could not create ebuild logs archive. No logs found for %s.",
630 sysroot.path,
631 )
632 return
Alex Klein036833d2022-06-01 13:05:01 -0600633
Brian Norris4543de42023-07-18 11:09:00 -0700634 output_proto.artifacts.add(
635 artifact_path=common_pb2.Path(
636 path=os.path.join(output_dir, archive),
637 location=common_pb2.Path.OUTSIDE,
638 )
639 )
Alex Klein6504eca2019-04-18 15:37:56 -0600640
641
Alex Kleinb6847e22022-11-07 10:44:48 -0700642def _BundleChromeOSConfigResponse(input_proto, output_proto, _config) -> None:
Alex Klein1699fab2022-09-08 08:46:06 -0600643 """Add test config files to a successful response."""
Brian Norris4543de42023-07-18 11:09:00 -0700644 output_proto.artifacts.add(
645 artifact_path=common_pb2.Path(
646 path=os.path.join(input_proto.result_path.path.path, "config.yaml"),
647 location=common_pb2.Path.OUTSIDE,
648 )
Alex Klein1699fab2022-09-08 08:46:06 -0600649 )
Michael Mortensen2d6a2402019-11-26 13:40:40 -0700650
651
652@faux.success(_BundleChromeOSConfigResponse)
653@faux.empty_error
Alex Klein1699fab2022-09-08 08:46:06 -0600654@validate.require("sysroot.path")
Brian Norris4543de42023-07-18 11:09:00 -0700655@validate.exists("result_path.path.path")
Andrew Lamb811aead2019-08-12 10:25:05 -0600656@validate.validation_complete
Varun Somani04dccd72021-10-09 01:06:11 +0000657def BundleChromeOSConfig(
658 input_proto: artifacts_pb2.BundleRequest,
659 output_proto: artifacts_pb2.BundleResponse,
Alex Klein1699fab2022-09-08 08:46:06 -0600660 _config: "api_config.ApiConfig",
Alex Kleinb6847e22022-11-07 10:44:48 -0700661) -> Optional[int]:
Alex Klein1699fab2022-09-08 08:46:06 -0600662 """Output the ChromeOS Config payload for a build target."""
Brian Norris4543de42023-07-18 11:09:00 -0700663 output_dir = input_proto.result_path.path.path
Alex Klein1699fab2022-09-08 08:46:06 -0600664 chroot = controller_util.ParseChroot(input_proto.chroot)
665 sysroot = controller_util.ParseSysroot(input_proto.sysroot)
Andrew Lamb811aead2019-08-12 10:25:05 -0600666
Alex Klein1699fab2022-09-08 08:46:06 -0600667 chromeos_config = artifacts.BundleChromeOSConfig(
668 chroot, sysroot, output_dir
669 )
Alex Klein2d8333c2022-06-01 13:29:01 -0600670
Alex Klein1699fab2022-09-08 08:46:06 -0600671 if not chromeos_config:
672 logging.warning(
673 "Could not create ChromeOS Config for %s.", sysroot.path
674 )
675 return
Alex Klein383a7a32021-12-07 16:01:19 -0700676
Brian Norris4543de42023-07-18 11:09:00 -0700677 output_proto.artifacts.add(
678 artifact_path=common_pb2.Path(
679 path=os.path.join(output_dir, chromeos_config),
680 location=common_pb2.Path.OUTSIDE,
681 )
Alex Klein1699fab2022-09-08 08:46:06 -0600682 )
Andrew Lamb811aead2019-08-12 10:25:05 -0600683
684
Alex Kleinb6847e22022-11-07 10:44:48 -0700685def _BundleSimpleChromeArtifactsResponse(
686 input_proto, output_proto, _config
687) -> None:
Alex Klein1699fab2022-09-08 08:46:06 -0600688 """Add test simple chrome files to a successful response."""
Brian Norris4543de42023-07-18 11:09:00 -0700689 output_proto.artifacts.add(
690 artifact_path=common_pb2.Path(
691 path=os.path.join(
692 input_proto.result_path.path.path, "simple_chrome.txt"
693 ),
694 location=common_pb2.Path.OUTSIDE,
695 )
Alex Klein1699fab2022-09-08 08:46:06 -0600696 )
Michael Mortensen2d6a2402019-11-26 13:40:40 -0700697
698
699@faux.success(_BundleSimpleChromeArtifactsResponse)
700@faux.empty_error
Brian Norris4543de42023-07-18 11:09:00 -0700701@validate.require(
702 "result_path.path.path", "sysroot.build_target.name", "sysroot.path"
703)
704@validate.exists("result_path.path.path")
Alex Klein231d2da2019-07-22 16:44:45 -0600705@validate.validation_complete
Alex Kleinb6847e22022-11-07 10:44:48 -0700706def BundleSimpleChromeArtifacts(
707 input_proto, output_proto, _config
708) -> Optional[int]:
Alex Klein1699fab2022-09-08 08:46:06 -0600709 """Create the simple chrome artifacts."""
710 sysroot_path = input_proto.sysroot.path
Brian Norris4543de42023-07-18 11:09:00 -0700711 output_dir = input_proto.result_path.path.path
Alex Klein2275d692019-04-23 16:04:12 -0600712
Alex Klein1699fab2022-09-08 08:46:06 -0600713 # Build out the argument instances.
714 build_target = controller_util.ParseBuildTarget(
715 input_proto.sysroot.build_target
716 )
717 chroot = controller_util.ParseChroot(input_proto.chroot)
718 # Sysroot.path needs to be the fully qualified path, including the chroot.
Brian Norrisd3e391e2023-06-30 09:53:11 -0700719 full_sysroot_path = chroot.full_path(sysroot_path)
Alex Klein1699fab2022-09-08 08:46:06 -0600720 sysroot = sysroot_lib.Sysroot(full_sysroot_path)
Alex Klein2275d692019-04-23 16:04:12 -0600721
Alex Klein1699fab2022-09-08 08:46:06 -0600722 # Check that the sysroot exists before we go on.
723 if not sysroot.Exists():
Alex Kleinb6847e22022-11-07 10:44:48 -0700724 logging.warning("The sysroot does not exist.")
725 return
Alex Klein2275d692019-04-23 16:04:12 -0600726
Alex Klein1699fab2022-09-08 08:46:06 -0600727 try:
728 results = artifacts.BundleSimpleChromeArtifacts(
729 chroot, sysroot, build_target, output_dir
730 )
731 except artifacts.Error as e:
Alex Kleinb6847e22022-11-07 10:44:48 -0700732 logging.warning(
Alex Klein1699fab2022-09-08 08:46:06 -0600733 "Error %s raised in BundleSimpleChromeArtifacts: %s", type(e), e
734 )
Alex Kleinb6847e22022-11-07 10:44:48 -0700735 return
Alex Klein2275d692019-04-23 16:04:12 -0600736
Alex Klein1699fab2022-09-08 08:46:06 -0600737 for file_name in results:
Brian Norris4543de42023-07-18 11:09:00 -0700738 output_proto.artifacts.add(
739 artifact_path=common_pb2.Path(
740 path=file_name, location=common_pb2.Path.OUTSIDE
741 )
742 )
Alex Klein2275d692019-04-23 16:04:12 -0600743
744
Alex Kleinb6847e22022-11-07 10:44:48 -0700745def _BundleVmFilesResponse(input_proto, output_proto, _config) -> None:
Alex Klein1699fab2022-09-08 08:46:06 -0600746 """Add test vm files to a successful response."""
747 output_proto.artifacts.add().path = os.path.join(
748 input_proto.output_dir, "f1.tar"
749 )
Michael Mortensen2d6a2402019-11-26 13:40:40 -0700750
751
752@faux.success(_BundleVmFilesResponse)
753@faux.empty_error
Alex Klein1699fab2022-09-08 08:46:06 -0600754@validate.require("chroot.path", "test_results_dir", "output_dir")
755@validate.exists("output_dir")
Alex Klein231d2da2019-07-22 16:44:45 -0600756@validate.validation_complete
Varun Somani04dccd72021-10-09 01:06:11 +0000757def BundleVmFiles(
758 input_proto: artifacts_pb2.BundleVmFilesRequest,
759 output_proto: artifacts_pb2.BundleResponse,
Alex Klein1699fab2022-09-08 08:46:06 -0600760 _config: "api_config.ApiConfig",
Alex Kleinb6847e22022-11-07 10:44:48 -0700761) -> None:
762 """Tar VM disk and memory files."""
Alex Klein1699fab2022-09-08 08:46:06 -0600763 chroot = controller_util.ParseChroot(input_proto.chroot)
764 test_results_dir = input_proto.test_results_dir
765 output_dir = input_proto.output_dir
Alex Klein6504eca2019-04-18 15:37:56 -0600766
Alex Klein1699fab2022-09-08 08:46:06 -0600767 archives = artifacts.BundleVmFiles(chroot, test_results_dir, output_dir)
768 for archive in archives:
769 output_proto.artifacts.add().path = archive
770
Tiancong Wangc4805b72019-06-11 12:12:03 -0700771
Alex Kleinb6847e22022-11-07 10:44:48 -0700772def _BundleGceTarballResponse(input_proto, output_proto, _config) -> None:
Alex Klein1699fab2022-09-08 08:46:06 -0600773 """Add artifact tarball to a successful response."""
Brian Norris4543de42023-07-18 11:09:00 -0700774 output_proto.artifacts.add(
775 artifact_path=common_pb2.Path(
776 path=os.path.join(
777 input_proto.result_path.path.path, constants.TEST_IMAGE_GCE_TAR
778 ),
779 location=common_pb2.Path.OUTSIDE,
780 )
Alex Klein1699fab2022-09-08 08:46:06 -0600781 )
Shao-Chuan Leea44dddc2020-10-30 17:16:55 +0900782
783
784@faux.success(_BundleGceTarballResponse)
785@faux.empty_error
Brian Norris4543de42023-07-18 11:09:00 -0700786@validate.require("build_target.name", "result_path.path.path")
787@validate.exists("result_path.path.path")
Shao-Chuan Leea44dddc2020-10-30 17:16:55 +0900788@validate.validation_complete
Varun Somani04dccd72021-10-09 01:06:11 +0000789def BundleGceTarball(
790 input_proto: artifacts_pb2.BundleRequest,
791 output_proto: artifacts_pb2.BundleResponse,
Alex Klein1699fab2022-09-08 08:46:06 -0600792 _config: "api_config.ApiConfig",
Alex Kleinb6847e22022-11-07 10:44:48 -0700793) -> Optional[int]:
794 """Bundle the test image into a tarball suitable for importing into GCE."""
Alex Klein1699fab2022-09-08 08:46:06 -0600795 target = input_proto.build_target.name
Brian Norris4543de42023-07-18 11:09:00 -0700796 output_dir = input_proto.result_path.path.path
Alex Klein1699fab2022-09-08 08:46:06 -0600797 image_dir = _GetImageDir(constants.SOURCE_ROOT, target)
798 if image_dir is None:
799 return None
Shao-Chuan Leea44dddc2020-10-30 17:16:55 +0900800
Alex Klein1699fab2022-09-08 08:46:06 -0600801 tarball = artifacts.BundleGceTarball(output_dir, image_dir)
Brian Norris4543de42023-07-18 11:09:00 -0700802 output_proto.artifacts.add(
803 artifact_path=common_pb2.Path(
804 path=tarball, location=common_pb2.Path.OUTSIDE
805 )
806 )