blob: 40b6db84558cf7054ecf073abc29ac0cb4518c22 [file] [log] [blame]
Evan Hernandezf388cbf2019-04-01 11:15:23 -06001# -*- coding: utf-8 -*-
2# Copyright 2019 The Chromium OS Authors. All rights reserved.
3# Use of this source code is governed by a BSD-style license that can be
4# found in the LICENSE file.
5
6"""Implements ArtifactService."""
7
8from __future__ import print_function
9
10import os
11
Alex Klein231d2da2019-07-22 16:44:45 -060012from chromite.api import controller
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
Tiancong Wang50b80a92019-08-01 14:46:15 -070015from chromite.api.gen.chromite.api import artifacts_pb2
Evan Hernandezf388cbf2019-04-01 11:15:23 -060016from chromite.cbuildbot import commands
Alex Klein2275d692019-04-23 16:04:12 -060017from chromite.lib import build_target_util
18from chromite.lib import chroot_lib
Evan Hernandezf388cbf2019-04-01 11:15:23 -060019from chromite.lib import constants
20from chromite.lib import cros_build_lib
Evan Hernandezde445982019-04-22 13:42:34 -060021from chromite.lib import cros_logging as logging
Alex Klein2275d692019-04-23 16:04:12 -060022from chromite.lib import sysroot_lib
23from chromite.service import artifacts
Evan Hernandezf388cbf2019-04-01 11:15:23 -060024
25
Evan Hernandez9f125ac2019-04-08 17:18:47 -060026def _GetImageDir(build_root, target):
27 """Return path containing images for the given build target.
28
Alex Kleine2612a02019-04-18 13:51:06 -060029 TODO(saklein) Expand image_lib.GetLatestImageLink to support this use case.
30
Evan Hernandez9f125ac2019-04-08 17:18:47 -060031 Args:
32 build_root (str): Path to checkout where build occurs.
33 target (str): Name of the build target.
34
35 Returns:
36 Path to the directory containing target images.
37
38 Raises:
39 DieSystemExit: If the image dir does not exist.
40 """
41 image_dir = os.path.join(build_root, 'src/build/images', target, 'latest')
42 if not os.path.exists(image_dir):
43 cros_build_lib.Die('Expected to find image output for target %s at %s, '
44 'but path does not exist' % (target, image_dir))
45 return image_dir
46
47
Michael Mortensen01910922019-07-24 14:48:10 -060048@validate.require('build_target.name', 'output_dir')
Alex Klein231d2da2019-07-22 16:44:45 -060049@validate.exists('output_dir')
50@validate.validation_complete
51def BundleImageZip(input_proto, output_proto, _config):
Evan Hernandez9f125ac2019-04-08 17:18:47 -060052 """Bundle image.zip.
53
54 Args:
55 input_proto (BundleRequest): The input proto.
Alex Klein6504eca2019-04-18 15:37:56 -060056 output_proto (BundleResponse): The output proto.
Alex Klein231d2da2019-07-22 16:44:45 -060057 _config (api_config.ApiConfig): The API call config.
Evan Hernandez9f125ac2019-04-08 17:18:47 -060058 """
59 target = input_proto.build_target.name
60 output_dir = input_proto.output_dir
61 image_dir = _GetImageDir(constants.SOURCE_ROOT, target)
Alex Klein231d2da2019-07-22 16:44:45 -060062
Michael Mortensen01910922019-07-24 14:48:10 -060063 archive = artifacts.BundleImageZip(output_dir, image_dir)
Evan Hernandez9f125ac2019-04-08 17:18:47 -060064 output_proto.artifacts.add().path = os.path.join(output_dir, archive)
65
66
Alex Klein231d2da2019-07-22 16:44:45 -060067@validate.require('build_target.name', 'output_dir')
68@validate.exists('output_dir')
69@validate.validation_complete
70def BundleTestUpdatePayloads(input_proto, output_proto, _config):
Evan Hernandezf388cbf2019-04-01 11:15:23 -060071 """Generate minimal update payloads for the build target for testing.
72
73 Args:
74 input_proto (BundleRequest): The input proto.
Alex Klein6504eca2019-04-18 15:37:56 -060075 output_proto (BundleResponse): The output proto.
Alex Klein231d2da2019-07-22 16:44:45 -060076 _config (api_config.ApiConfig): The API call config.
Evan Hernandezf388cbf2019-04-01 11:15:23 -060077 """
78 target = input_proto.build_target.name
79 output_dir = input_proto.output_dir
80 build_root = constants.SOURCE_ROOT
81
82 # Use the first available image to create the update payload.
Evan Hernandez9f125ac2019-04-08 17:18:47 -060083 img_dir = _GetImageDir(build_root, target)
Alex Kleincb541e82019-06-26 15:06:11 -060084 img_types = [constants.IMAGE_TYPE_TEST, constants.IMAGE_TYPE_DEV,
85 constants.IMAGE_TYPE_BASE]
86 img_names = [constants.IMAGE_TYPE_TO_NAME[t] for t in img_types]
Mike Frysinger66ce4132019-07-17 22:52:52 -040087 img_paths = [os.path.join(img_dir, x) for x in img_names]
Mike Frysingera552be42018-08-17 14:39:32 -040088 valid_images = [x for x in img_paths if os.path.exists(x)]
Evan Hernandezf388cbf2019-04-01 11:15:23 -060089
Alex Kleincb541e82019-06-26 15:06:11 -060090 if not valid_images:
Evan Hernandezf388cbf2019-04-01 11:15:23 -060091 cros_build_lib.Die(
92 'Expected to find an image of type among %r for target "%s" '
Evan Hernandez9f125ac2019-04-08 17:18:47 -060093 'at path %s.', img_types, target, img_dir)
Alex Kleincb541e82019-06-26 15:06:11 -060094 image = valid_images[0]
Evan Hernandezf388cbf2019-04-01 11:15:23 -060095
Alex Kleincb541e82019-06-26 15:06:11 -060096 payloads = artifacts.BundleTestUpdatePayloads(image, output_dir)
97 for payload in payloads:
98 output_proto.artifacts.add().path = payload
Evan Hernandezf388cbf2019-04-01 11:15:23 -060099
100
Alex Klein231d2da2019-07-22 16:44:45 -0600101@validate.require('output_dir')
102@validate.exists('output_dir')
103def BundleAutotestFiles(input_proto, output_proto, config):
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600104 """Tar the autotest files for a build target.
105
106 Args:
107 input_proto (BundleRequest): The input proto.
Alex Klein6504eca2019-04-18 15:37:56 -0600108 output_proto (BundleResponse): The output proto.
Alex Klein231d2da2019-07-22 16:44:45 -0600109 config (api_config.ApiConfig): The API call config.
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600110 """
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600111 output_dir = input_proto.output_dir
Alex Klein238d8862019-05-07 11:32:46 -0600112 target = input_proto.build_target.name
113 if target:
114 # Legacy call, build out sysroot path from default source root and the
115 # build target.
116 target = input_proto.build_target.name
117 build_root = constants.SOURCE_ROOT
118 sysroot_path = os.path.join(build_root, constants.DEFAULT_CHROOT_DIR,
119 'build', target)
120 sysroot = sysroot_lib.Sysroot(sysroot_path)
121 else:
122 # New style call, use chroot and sysroot.
123 chroot = controller_util.ParseChroot(input_proto.chroot)
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600124
Alex Klein238d8862019-05-07 11:32:46 -0600125 sysroot_path = input_proto.sysroot.path
126 if not sysroot_path:
127 cros_build_lib.Die('sysroot.path is required.')
128
129 # Since we're staying outside the chroot, prepend the chroot path to the
130 # sysroot path so we have a valid full path to the sysroot.
131 sysroot = sysroot_lib.Sysroot(os.path.join(chroot.path,
132 sysroot_path.lstrip(os.sep)))
133
Alex Klein231d2da2019-07-22 16:44:45 -0600134 # TODO(saklein): Switch to the validate_only decorator when legacy handling
135 # is removed.
136 if config.validate_only:
137 return controller.RETURN_CODE_VALID_INPUT
138
Alex Klein238d8862019-05-07 11:32:46 -0600139 if not sysroot.Exists():
140 cros_build_lib.Die('Sysroot path must exist: %s', sysroot.path)
141
142 try:
143 # Note that this returns the full path to *multiple* tarballs.
144 archives = artifacts.BundleAutotestFiles(sysroot, output_dir)
145 except artifacts.Error as e:
146 cros_build_lib.Die(e.message)
147
148 for archive in archives.values():
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600149 output_proto.artifacts.add().path = archive
150
151
Alex Kleinb9d810b2019-07-01 12:38:02 -0600152@validate.require('output_dir')
Alex Klein231d2da2019-07-22 16:44:45 -0600153@validate.exists('output_dir')
154def BundleTastFiles(input_proto, output_proto, config):
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600155 """Tar the tast files for a build target.
156
157 Args:
158 input_proto (BundleRequest): The input proto.
Alex Klein6504eca2019-04-18 15:37:56 -0600159 output_proto (BundleResponse): The output proto.
Alex Klein231d2da2019-07-22 16:44:45 -0600160 config (api_config.ApiConfig): The API call config.
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600161 """
162 target = input_proto.build_target.name
163 output_dir = input_proto.output_dir
164 build_root = constants.SOURCE_ROOT
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600165
Alex Kleinb9d810b2019-07-01 12:38:02 -0600166 chroot = controller_util.ParseChroot(input_proto.chroot)
167 sysroot_path = input_proto.sysroot.path
168
169 # TODO(saklein) Cleanup legacy handling after it has been switched over.
170 if target:
171 # Legacy handling.
Alex Klein171da612019-08-06 14:00:42 -0600172 chroot = chroot_lib.Chroot(path=os.path.join(build_root, 'chroot'))
Alex Kleinb9d810b2019-07-01 12:38:02 -0600173 sysroot_path = os.path.join('/build', target)
174
175 # New handling - chroot & sysroot based.
176 # TODO(saklein) Switch this to the require decorator when legacy is removed.
177 if not sysroot_path:
178 cros_build_lib.Die('sysroot.path is required.')
179
Alex Klein231d2da2019-07-22 16:44:45 -0600180 # TODO(saklein): Switch to the validation_complete decorator when legacy
181 # handling is removed.
182 if config.validate_only:
183 return controller.RETURN_CODE_VALID_INPUT
184
Alex Kleinb9d810b2019-07-01 12:38:02 -0600185 sysroot = sysroot_lib.Sysroot(sysroot_path)
Alex Klein231d2da2019-07-22 16:44:45 -0600186 if not sysroot.Exists(chroot=chroot):
Alex Kleinb9d810b2019-07-01 12:38:02 -0600187 cros_build_lib.Die('Sysroot must exist.')
188
189 archive = artifacts.BundleTastFiles(chroot, sysroot, output_dir)
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600190
Evan Hernandez9a5d3122019-04-09 10:51:23 -0600191 if archive is None:
192 cros_build_lib.Die(
193 'Could not bundle Tast files. '
194 'No Tast directories found for %s.', target)
195
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600196 output_proto.artifacts.add().path = archive
197
198
Alex Klein231d2da2019-07-22 16:44:45 -0600199@validate.require('build_target.name', 'output_dir')
200@validate.exists('output_dir')
201@validate.validation_complete
202def BundlePinnedGuestImages(input_proto, output_proto, _config):
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600203 """Tar the pinned guest images for a build target.
204
205 Args:
206 input_proto (BundleRequest): The input proto.
Alex Klein6504eca2019-04-18 15:37:56 -0600207 output_proto (BundleResponse): The output proto.
Alex Klein231d2da2019-07-22 16:44:45 -0600208 _config (api_config.ApiConfig): The API call config.
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600209 """
210 target = input_proto.build_target.name
211 output_dir = input_proto.output_dir
212 build_root = constants.SOURCE_ROOT
213
Alex Kleine2612a02019-04-18 13:51:06 -0600214 # TODO(crbug.com/954299): Replace with a chromite/service implementation.
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600215 archive = commands.BuildPinnedGuestImagesTarball(build_root, target,
216 output_dir)
217
Evan Hernandez9a5d3122019-04-09 10:51:23 -0600218 if archive is None:
Evan Hernandezde445982019-04-22 13:42:34 -0600219 logging.warning('Found no pinned guest images for %s.', target)
220 return
Evan Hernandez9a5d3122019-04-09 10:51:23 -0600221
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600222 output_proto.artifacts.add().path = os.path.join(output_dir, archive)
223
224
Alex Klein231d2da2019-07-22 16:44:45 -0600225@validate.require('sysroot.path')
226@validate.validation_complete
227def FetchPinnedGuestImages(input_proto, output_proto, _config):
Alex Klein7bf0ecb2019-06-25 10:04:15 -0600228 """Get the pinned guest image information."""
229 sysroot_path = input_proto.sysroot.path
Alex Klein7bf0ecb2019-06-25 10:04:15 -0600230
231 chroot = controller_util.ParseChroot(input_proto.chroot)
232 sysroot = sysroot_lib.Sysroot(sysroot_path)
233
234 if not chroot.exists():
235 cros_build_lib.Die('Chroot does not exist: %s', chroot.path)
Alex Klein231d2da2019-07-22 16:44:45 -0600236 elif not sysroot.Exists(chroot=chroot):
Alex Klein7bf0ecb2019-06-25 10:04:15 -0600237 cros_build_lib.Die('Sysroot does not exist: %s',
238 chroot.full_path(sysroot.path))
239
240 pins = artifacts.FetchPinnedGuestImages(chroot, sysroot)
241
242 for pin in pins:
243 pinned_image = output_proto.pinned_images.add()
244 pinned_image.filename = pin.filename
245 pinned_image.uri = pin.uri
246
247
Michael Mortensen38675192019-06-28 16:52:55 +0000248@validate.require('output_dir', 'sysroot.path')
Alex Klein231d2da2019-07-22 16:44:45 -0600249@validate.exists('output_dir')
250@validate.validation_complete
251def BundleFirmware(input_proto, output_proto, _config):
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600252 """Tar the firmware images for a build target.
253
254 Args:
255 input_proto (BundleRequest): The input proto.
Alex Klein6504eca2019-04-18 15:37:56 -0600256 output_proto (BundleResponse): The output proto.
Alex Klein231d2da2019-07-22 16:44:45 -0600257 _config (api_config.ApiConfig): The API call config.
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600258 """
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600259 output_dir = input_proto.output_dir
Michael Mortensen38675192019-06-28 16:52:55 +0000260 chroot = controller_util.ParseChroot(input_proto.chroot)
261 sysroot_path = input_proto.sysroot.path
262 sysroot = sysroot_lib.Sysroot(sysroot_path)
Alex Klein231d2da2019-07-22 16:44:45 -0600263
264 if not chroot.exists():
265 cros_build_lib.Die('Chroot does not exist: %s', chroot.path)
266 elif not sysroot.Exists(chroot=chroot):
267 cros_build_lib.Die('Sysroot does not exist: %s',
268 chroot.full_path(sysroot.path))
269
Michael Mortensen38675192019-06-28 16:52:55 +0000270 archive = artifacts.BuildFirmwareArchive(chroot, sysroot, output_dir)
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600271
Evan Hernandez9a5d3122019-04-09 10:51:23 -0600272 if archive is None:
273 cros_build_lib.Die(
Michael Mortensen38675192019-06-28 16:52:55 +0000274 'Could not create firmware archive. No firmware found for %s.',
275 sysroot_path)
Evan Hernandez9a5d3122019-04-09 10:51:23 -0600276
Alex Klein231d2da2019-07-22 16:44:45 -0600277 output_proto.artifacts.add().path = archive
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600278
279
Michael Mortensen3f382cb2019-07-29 13:21:49 -0600280@validate.exists('output_dir')
Alex Klein231d2da2019-07-22 16:44:45 -0600281def BundleEbuildLogs(input_proto, output_proto, config):
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600282 """Tar the ebuild logs for a build target.
283
284 Args:
285 input_proto (BundleRequest): The input proto.
Alex Klein6504eca2019-04-18 15:37:56 -0600286 output_proto (BundleResponse): The output proto.
Alex Klein231d2da2019-07-22 16:44:45 -0600287 config (api_config.ApiConfig): The API call config.
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600288 """
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600289 output_dir = input_proto.output_dir
Michael Mortensen3f382cb2019-07-29 13:21:49 -0600290 sysroot_path = input_proto.sysroot.path
291 chroot = controller_util.ParseChroot(input_proto.chroot)
Evan Hernandeza478d802019-04-08 15:08:24 -0600292
Michael Mortensen3f382cb2019-07-29 13:21:49 -0600293 # TODO(mmortensen) Cleanup legacy handling after it has been switched over.
294 target = input_proto.build_target.name
295 if target:
296 # Legacy handling.
297 build_root = constants.SOURCE_ROOT
Alex Klein171da612019-08-06 14:00:42 -0600298 chroot = chroot_lib.Chroot(path=os.path.join(build_root, 'chroot'))
Michael Mortensen3f382cb2019-07-29 13:21:49 -0600299 sysroot_path = os.path.join('/build', target)
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600300
Alex Klein231d2da2019-07-22 16:44:45 -0600301 # TODO(saklein): Switch to validation_complete decorator after legacy
302 # handling has been cleaned up.
303 if config.validate_only:
304 return controller.RETURN_CODE_VALID_INPUT
305
Michael Mortensen3f382cb2019-07-29 13:21:49 -0600306 sysroot = sysroot_lib.Sysroot(sysroot_path)
307 archive = artifacts.BundleEBuildLogsTarball(chroot, sysroot, output_dir)
Evan Hernandez9a5d3122019-04-09 10:51:23 -0600308 if archive is None:
309 cros_build_lib.Die(
Michael Mortensen3f382cb2019-07-29 13:21:49 -0600310 'Could not create ebuild logs archive. No logs found for %s.',
311 sysroot.path)
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600312 output_proto.artifacts.add().path = os.path.join(output_dir, archive)
Alex Klein6504eca2019-04-18 15:37:56 -0600313
314
Andrew Lamb811aead2019-08-12 10:25:05 -0600315@validate.exists('output_dir')
316@validate.validation_complete
317def BundleChromeOSConfig(input_proto, output_proto, _config):
318 """Output the ChromeOS Config payload for a build target.
319
320 Args:
321 input_proto (BundleRequest): The input proto.
322 output_proto (BundleResponse): The output proto.
323 _config (api_config.ApiConfig): The API call config.
324 """
325 output_dir = input_proto.output_dir
Andrew Lamb67bd68f2019-08-15 09:09:15 -0600326 sysroot_path = input_proto.sysroot.path
Andrew Lamb811aead2019-08-12 10:25:05 -0600327 chroot = controller_util.ParseChroot(input_proto.chroot)
328
Andrew Lamb67bd68f2019-08-15 09:09:15 -0600329 # TODO(mmortensen) Cleanup legacy handling after it has been switched over.
330 target = input_proto.build_target.name
331 if target:
332 # Legacy handling.
333 build_root = constants.SOURCE_ROOT
334 chroot = chroot_lib.Chroot(path=os.path.join(build_root, 'chroot'))
335 sysroot_path = os.path.join('/build', target)
336
337 sysroot = sysroot_lib.Sysroot(sysroot_path)
Andrew Lamb811aead2019-08-12 10:25:05 -0600338 chromeos_config = artifacts.BundleChromeOSConfig(chroot, sysroot, output_dir)
339 if chromeos_config is None:
340 cros_build_lib.Die(
341 'Could not create ChromeOS Config payload. No config found for %s.',
342 sysroot.path)
343 output_proto.artifacts.add().path = os.path.join(output_dir, chromeos_config)
344
345
Alex Klein231d2da2019-07-22 16:44:45 -0600346@validate.require('output_dir', 'sysroot.build_target.name', 'sysroot.path')
347@validate.exists('output_dir')
348@validate.validation_complete
349def BundleSimpleChromeArtifacts(input_proto, output_proto, _config):
Alex Klein2275d692019-04-23 16:04:12 -0600350 """Create the simple chrome artifacts."""
351 # Required args.
352 sysroot_path = input_proto.sysroot.path
353 build_target_name = input_proto.sysroot.build_target.name
354 output_dir = input_proto.output_dir
355
Alex Klein2275d692019-04-23 16:04:12 -0600356 # Optional args.
357 chroot_path = input_proto.chroot.path or constants.DEFAULT_CHROOT_PATH
358 cache_dir = input_proto.chroot.cache_dir
359
360 # Build out the argument instances.
361 build_target = build_target_util.BuildTarget(build_target_name)
362 chroot = chroot_lib.Chroot(path=chroot_path, cache_dir=cache_dir)
363 # Sysroot.path needs to be the fully qualified path, including the chroot.
364 full_sysroot_path = os.path.join(chroot.path, sysroot_path.lstrip(os.sep))
365 sysroot = sysroot_lib.Sysroot(full_sysroot_path)
366
367 # Quick sanity check that the sysroot exists before we go on.
368 if not sysroot.Exists():
369 cros_build_lib.Die('The sysroot does not exist.')
370
371 try:
372 results = artifacts.BundleSimpleChromeArtifacts(chroot, sysroot,
373 build_target, output_dir)
374 except artifacts.Error as e:
375 cros_build_lib.Die('Error %s raised in BundleSimpleChromeArtifacts: %s',
376 type(e), e)
377
378 for file_name in results:
379 output_proto.artifacts.add().path = file_name
380
381
Michael Mortensen51f06722019-07-18 09:55:50 -0600382@validate.require('chroot.path', 'test_results_dir', 'output_dir')
Alex Klein231d2da2019-07-22 16:44:45 -0600383@validate.exists('output_dir')
384@validate.validation_complete
385def BundleVmFiles(input_proto, output_proto, _config):
Alex Klein6504eca2019-04-18 15:37:56 -0600386 """Tar VM disk and memory files.
387
388 Args:
389 input_proto (SysrootBundleRequest): The input proto.
390 output_proto (BundleResponse): The output proto.
Alex Klein231d2da2019-07-22 16:44:45 -0600391 _config (api_config.ApiConfig): The API call config.
Alex Klein6504eca2019-04-18 15:37:56 -0600392 """
Michael Mortensen51f06722019-07-18 09:55:50 -0600393 chroot = controller_util.ParseChroot(input_proto.chroot)
394 test_results_dir = input_proto.test_results_dir
Alex Klein6504eca2019-04-18 15:37:56 -0600395 output_dir = input_proto.output_dir
396
Michael Mortensen51f06722019-07-18 09:55:50 -0600397 archives = artifacts.BundleVmFiles(
398 chroot, test_results_dir, output_dir)
Alex Klein6504eca2019-04-18 15:37:56 -0600399 for archive in archives:
400 output_proto.artifacts.add().path = archive
Tiancong Wangc4805b72019-06-11 12:12:03 -0700401
Alex Klein231d2da2019-07-22 16:44:45 -0600402
Tiancong Wang50b80a92019-08-01 14:46:15 -0700403_VALID_ARTIFACT_TYPES = [artifacts_pb2.BENCHMARK_AFDO,
404 artifacts_pb2.ORDERFILE]
Alex Klein231d2da2019-07-22 16:44:45 -0600405@validate.require('build_target.name', 'output_dir')
Tiancong Wang50b80a92019-08-01 14:46:15 -0700406@validate.is_in('artifact_type', _VALID_ARTIFACT_TYPES)
Alex Klein231d2da2019-07-22 16:44:45 -0600407@validate.exists('output_dir')
408@validate.validation_complete
Tiancong Wang50b80a92019-08-01 14:46:15 -0700409def BundleAFDOGenerationArtifacts(input_proto, output_proto, _config):
410 """Generic function for creating tarballs of both AFDO and orerfile.
Tiancong Wangc4805b72019-06-11 12:12:03 -0700411
412 Args:
Tiancong Wang50b80a92019-08-01 14:46:15 -0700413 input_proto (BundleChromeAFDORequest): The input proto.
Tiancong Wangc4805b72019-06-11 12:12:03 -0700414 output_proto (BundleResponse): The output proto.
Alex Klein231d2da2019-07-22 16:44:45 -0600415 _config (api_config.ApiConfig): The API call config.
Tiancong Wangc4805b72019-06-11 12:12:03 -0700416 """
Tiancong Wang50b80a92019-08-01 14:46:15 -0700417
Tiancong Wangc4805b72019-06-11 12:12:03 -0700418 # Required args.
Alex Klein231d2da2019-07-22 16:44:45 -0600419 build_target = build_target_util.BuildTarget(input_proto.build_target.name)
Tiancong Wangc4805b72019-06-11 12:12:03 -0700420 output_dir = input_proto.output_dir
Tiancong Wang50b80a92019-08-01 14:46:15 -0700421 artifact_type = input_proto.artifact_type
Tiancong Wangc4805b72019-06-11 12:12:03 -0700422
Tiancong Wangc4805b72019-06-11 12:12:03 -0700423 chroot = controller_util.ParseChroot(input_proto.chroot)
424
425 try:
Tiancong Wang50b80a92019-08-01 14:46:15 -0700426 is_orderfile = bool(artifact_type is artifacts_pb2.ORDERFILE)
427 results = artifacts.BundleAFDOGenerationArtifacts(
428 is_orderfile, chroot,
429 build_target, output_dir)
Tiancong Wangc4805b72019-06-11 12:12:03 -0700430 except artifacts.Error as e:
431 cros_build_lib.Die('Error %s raised in BundleSimpleChromeArtifacts: %s',
432 type(e), e)
433
434 for file_name in results:
435 output_proto.artifacts.add().path = file_name
Alex Klein0b1cbfc2019-08-14 10:09:58 -0600436
437
438@validate.exists('output_dir')
439def ExportCpeReport(input_proto, output_proto, config):
440 """Export a CPE report.
441
442 Args:
443 input_proto (BundleRequest): The input proto.
444 output_proto (BundleResponse): The output proto.
445 config (api_config.ApiConfig): The API call config.
446 """
447 chroot = controller_util.ParseChroot(input_proto.chroot)
448 output_dir = input_proto.output_dir
449
450 if input_proto.build_target.name:
451 # Legacy handling - use the default sysroot path for the build target.
452 build_target = controller_util.ParseBuildTarget(input_proto.build_target)
453 sysroot = sysroot_lib.Sysroot(build_target.root)
454 elif input_proto.sysroot.path:
455 sysroot = sysroot_lib.Sysroot(input_proto.sysroot.path)
456 else:
457 # TODO(saklein): Switch to validate decorators once legacy handling can be
458 # cleaned up.
459 cros_build_lib.Die('sysroot.path is required.')
460
461 if config.validate_only:
462 return controller.RETURN_CODE_VALID_INPUT
463
464 cpe_result = artifacts.GenerateCpeReport(chroot, sysroot, output_dir)
465
466 output_proto.artifacts.add().path = cpe_result.report
467 output_proto.artifacts.add().path = cpe_result.warnings