blob: 07f0ed44aea1a5578d23f0da36ada2c5764fd286 [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
Evan Hernandezf388cbf2019-04-01 11:15:23 -060015from chromite.cbuildbot import commands
Alex Klein2275d692019-04-23 16:04:12 -060016from chromite.lib import build_target_util
17from chromite.lib import chroot_lib
Evan Hernandezf388cbf2019-04-01 11:15:23 -060018from chromite.lib import constants
19from chromite.lib import cros_build_lib
Evan Hernandezde445982019-04-22 13:42:34 -060020from chromite.lib import cros_logging as logging
Alex Klein2275d692019-04-23 16:04:12 -060021from chromite.lib import sysroot_lib
22from chromite.service import artifacts
Evan Hernandezf388cbf2019-04-01 11:15:23 -060023
24
Evan Hernandez9f125ac2019-04-08 17:18:47 -060025def _GetImageDir(build_root, target):
26 """Return path containing images for the given build target.
27
Alex Kleine2612a02019-04-18 13:51:06 -060028 TODO(saklein) Expand image_lib.GetLatestImageLink to support this use case.
29
Evan Hernandez9f125ac2019-04-08 17:18:47 -060030 Args:
31 build_root (str): Path to checkout where build occurs.
32 target (str): Name of the build target.
33
34 Returns:
35 Path to the directory containing target images.
36
37 Raises:
38 DieSystemExit: If the image dir does not exist.
39 """
40 image_dir = os.path.join(build_root, 'src/build/images', target, 'latest')
41 if not os.path.exists(image_dir):
42 cros_build_lib.Die('Expected to find image output for target %s at %s, '
43 'but path does not exist' % (target, image_dir))
44 return image_dir
45
46
Michael Mortensen01910922019-07-24 14:48:10 -060047@validate.require('build_target.name', 'output_dir')
Alex Klein231d2da2019-07-22 16:44:45 -060048@validate.exists('output_dir')
49@validate.validation_complete
50def BundleImageZip(input_proto, output_proto, _config):
Evan Hernandez9f125ac2019-04-08 17:18:47 -060051 """Bundle image.zip.
52
53 Args:
54 input_proto (BundleRequest): The input proto.
Alex Klein6504eca2019-04-18 15:37:56 -060055 output_proto (BundleResponse): The output proto.
Alex Klein231d2da2019-07-22 16:44:45 -060056 _config (api_config.ApiConfig): The API call config.
Evan Hernandez9f125ac2019-04-08 17:18:47 -060057 """
58 target = input_proto.build_target.name
59 output_dir = input_proto.output_dir
60 image_dir = _GetImageDir(constants.SOURCE_ROOT, target)
Alex Klein231d2da2019-07-22 16:44:45 -060061
Michael Mortensen01910922019-07-24 14:48:10 -060062 archive = artifacts.BundleImageZip(output_dir, image_dir)
Evan Hernandez9f125ac2019-04-08 17:18:47 -060063 output_proto.artifacts.add().path = os.path.join(output_dir, archive)
64
65
Alex Klein231d2da2019-07-22 16:44:45 -060066@validate.require('build_target.name', 'output_dir')
67@validate.exists('output_dir')
68@validate.validation_complete
69def BundleTestUpdatePayloads(input_proto, output_proto, _config):
Evan Hernandezf388cbf2019-04-01 11:15:23 -060070 """Generate minimal update payloads for the build target for testing.
71
72 Args:
73 input_proto (BundleRequest): The input proto.
Alex Klein6504eca2019-04-18 15:37:56 -060074 output_proto (BundleResponse): The output proto.
Alex Klein231d2da2019-07-22 16:44:45 -060075 _config (api_config.ApiConfig): The API call config.
Evan Hernandezf388cbf2019-04-01 11:15:23 -060076 """
77 target = input_proto.build_target.name
78 output_dir = input_proto.output_dir
79 build_root = constants.SOURCE_ROOT
80
81 # Use the first available image to create the update payload.
Evan Hernandez9f125ac2019-04-08 17:18:47 -060082 img_dir = _GetImageDir(build_root, target)
Alex Kleincb541e82019-06-26 15:06:11 -060083 img_types = [constants.IMAGE_TYPE_TEST, constants.IMAGE_TYPE_DEV,
84 constants.IMAGE_TYPE_BASE]
85 img_names = [constants.IMAGE_TYPE_TO_NAME[t] for t in img_types]
Mike Frysinger66ce4132019-07-17 22:52:52 -040086 img_paths = [os.path.join(img_dir, x) for x in img_names]
Mike Frysingera552be42018-08-17 14:39:32 -040087 valid_images = [x for x in img_paths if os.path.exists(x)]
Evan Hernandezf388cbf2019-04-01 11:15:23 -060088
Alex Kleincb541e82019-06-26 15:06:11 -060089 if not valid_images:
Evan Hernandezf388cbf2019-04-01 11:15:23 -060090 cros_build_lib.Die(
91 'Expected to find an image of type among %r for target "%s" '
Evan Hernandez9f125ac2019-04-08 17:18:47 -060092 'at path %s.', img_types, target, img_dir)
Alex Kleincb541e82019-06-26 15:06:11 -060093 image = valid_images[0]
Evan Hernandezf388cbf2019-04-01 11:15:23 -060094
Alex Kleincb541e82019-06-26 15:06:11 -060095 payloads = artifacts.BundleTestUpdatePayloads(image, output_dir)
96 for payload in payloads:
97 output_proto.artifacts.add().path = payload
Evan Hernandezf388cbf2019-04-01 11:15:23 -060098
99
Alex Klein231d2da2019-07-22 16:44:45 -0600100@validate.require('output_dir')
101@validate.exists('output_dir')
102def BundleAutotestFiles(input_proto, output_proto, config):
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600103 """Tar the autotest files for a build target.
104
105 Args:
106 input_proto (BundleRequest): The input proto.
Alex Klein6504eca2019-04-18 15:37:56 -0600107 output_proto (BundleResponse): The output proto.
Alex Klein231d2da2019-07-22 16:44:45 -0600108 config (api_config.ApiConfig): The API call config.
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600109 """
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600110 output_dir = input_proto.output_dir
Alex Klein238d8862019-05-07 11:32:46 -0600111 target = input_proto.build_target.name
112 if target:
113 # Legacy call, build out sysroot path from default source root and the
114 # build target.
115 target = input_proto.build_target.name
116 build_root = constants.SOURCE_ROOT
117 sysroot_path = os.path.join(build_root, constants.DEFAULT_CHROOT_DIR,
118 'build', target)
119 sysroot = sysroot_lib.Sysroot(sysroot_path)
120 else:
121 # New style call, use chroot and sysroot.
122 chroot = controller_util.ParseChroot(input_proto.chroot)
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600123
Alex Klein238d8862019-05-07 11:32:46 -0600124 sysroot_path = input_proto.sysroot.path
125 if not sysroot_path:
126 cros_build_lib.Die('sysroot.path is required.')
127
128 # Since we're staying outside the chroot, prepend the chroot path to the
129 # sysroot path so we have a valid full path to the sysroot.
130 sysroot = sysroot_lib.Sysroot(os.path.join(chroot.path,
131 sysroot_path.lstrip(os.sep)))
132
Alex Klein231d2da2019-07-22 16:44:45 -0600133 # TODO(saklein): Switch to the validate_only decorator when legacy handling
134 # is removed.
135 if config.validate_only:
136 return controller.RETURN_CODE_VALID_INPUT
137
Alex Klein238d8862019-05-07 11:32:46 -0600138 if not sysroot.Exists():
139 cros_build_lib.Die('Sysroot path must exist: %s', sysroot.path)
140
141 try:
142 # Note that this returns the full path to *multiple* tarballs.
143 archives = artifacts.BundleAutotestFiles(sysroot, output_dir)
144 except artifacts.Error as e:
145 cros_build_lib.Die(e.message)
146
147 for archive in archives.values():
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600148 output_proto.artifacts.add().path = archive
149
150
Alex Kleinb9d810b2019-07-01 12:38:02 -0600151@validate.require('output_dir')
Alex Klein231d2da2019-07-22 16:44:45 -0600152@validate.exists('output_dir')
153def BundleTastFiles(input_proto, output_proto, config):
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600154 """Tar the tast files for a build target.
155
156 Args:
157 input_proto (BundleRequest): The input proto.
Alex Klein6504eca2019-04-18 15:37:56 -0600158 output_proto (BundleResponse): The output proto.
Alex Klein231d2da2019-07-22 16:44:45 -0600159 config (api_config.ApiConfig): The API call config.
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600160 """
161 target = input_proto.build_target.name
162 output_dir = input_proto.output_dir
163 build_root = constants.SOURCE_ROOT
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600164
Alex Kleinb9d810b2019-07-01 12:38:02 -0600165 chroot = controller_util.ParseChroot(input_proto.chroot)
166 sysroot_path = input_proto.sysroot.path
167
168 # TODO(saklein) Cleanup legacy handling after it has been switched over.
169 if target:
170 # Legacy handling.
Alex Klein171da612019-08-06 14:00:42 -0600171 chroot = chroot_lib.Chroot(path=os.path.join(build_root, 'chroot'))
Alex Kleinb9d810b2019-07-01 12:38:02 -0600172 sysroot_path = os.path.join('/build', target)
173
174 # New handling - chroot & sysroot based.
175 # TODO(saklein) Switch this to the require decorator when legacy is removed.
176 if not sysroot_path:
177 cros_build_lib.Die('sysroot.path is required.')
178
Alex Klein231d2da2019-07-22 16:44:45 -0600179 # TODO(saklein): Switch to the validation_complete decorator when legacy
180 # handling is removed.
181 if config.validate_only:
182 return controller.RETURN_CODE_VALID_INPUT
183
Alex Kleinb9d810b2019-07-01 12:38:02 -0600184 sysroot = sysroot_lib.Sysroot(sysroot_path)
Alex Klein231d2da2019-07-22 16:44:45 -0600185 if not sysroot.Exists(chroot=chroot):
Alex Kleinb9d810b2019-07-01 12:38:02 -0600186 cros_build_lib.Die('Sysroot must exist.')
187
188 archive = artifacts.BundleTastFiles(chroot, sysroot, output_dir)
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600189
Evan Hernandez9a5d3122019-04-09 10:51:23 -0600190 if archive is None:
191 cros_build_lib.Die(
192 'Could not bundle Tast files. '
193 'No Tast directories found for %s.', target)
194
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600195 output_proto.artifacts.add().path = archive
196
197
Alex Klein231d2da2019-07-22 16:44:45 -0600198@validate.require('build_target.name', 'output_dir')
199@validate.exists('output_dir')
200@validate.validation_complete
201def BundlePinnedGuestImages(input_proto, output_proto, _config):
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600202 """Tar the pinned guest images for a build target.
203
204 Args:
205 input_proto (BundleRequest): The input proto.
Alex Klein6504eca2019-04-18 15:37:56 -0600206 output_proto (BundleResponse): The output proto.
Alex Klein231d2da2019-07-22 16:44:45 -0600207 _config (api_config.ApiConfig): The API call config.
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600208 """
209 target = input_proto.build_target.name
210 output_dir = input_proto.output_dir
211 build_root = constants.SOURCE_ROOT
212
Alex Kleine2612a02019-04-18 13:51:06 -0600213 # TODO(crbug.com/954299): Replace with a chromite/service implementation.
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600214 archive = commands.BuildPinnedGuestImagesTarball(build_root, target,
215 output_dir)
216
Evan Hernandez9a5d3122019-04-09 10:51:23 -0600217 if archive is None:
Evan Hernandezde445982019-04-22 13:42:34 -0600218 logging.warning('Found no pinned guest images for %s.', target)
219 return
Evan Hernandez9a5d3122019-04-09 10:51:23 -0600220
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600221 output_proto.artifacts.add().path = os.path.join(output_dir, archive)
222
223
Alex Klein231d2da2019-07-22 16:44:45 -0600224@validate.require('sysroot.path')
225@validate.validation_complete
226def FetchPinnedGuestImages(input_proto, output_proto, _config):
Alex Klein7bf0ecb2019-06-25 10:04:15 -0600227 """Get the pinned guest image information."""
228 sysroot_path = input_proto.sysroot.path
Alex Klein7bf0ecb2019-06-25 10:04:15 -0600229
230 chroot = controller_util.ParseChroot(input_proto.chroot)
231 sysroot = sysroot_lib.Sysroot(sysroot_path)
232
233 if not chroot.exists():
234 cros_build_lib.Die('Chroot does not exist: %s', chroot.path)
Alex Klein231d2da2019-07-22 16:44:45 -0600235 elif not sysroot.Exists(chroot=chroot):
Alex Klein7bf0ecb2019-06-25 10:04:15 -0600236 cros_build_lib.Die('Sysroot does not exist: %s',
237 chroot.full_path(sysroot.path))
238
239 pins = artifacts.FetchPinnedGuestImages(chroot, sysroot)
240
241 for pin in pins:
242 pinned_image = output_proto.pinned_images.add()
243 pinned_image.filename = pin.filename
244 pinned_image.uri = pin.uri
245
246
Michael Mortensen38675192019-06-28 16:52:55 +0000247@validate.require('output_dir', 'sysroot.path')
Alex Klein231d2da2019-07-22 16:44:45 -0600248@validate.exists('output_dir')
249@validate.validation_complete
250def BundleFirmware(input_proto, output_proto, _config):
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600251 """Tar the firmware images for a build target.
252
253 Args:
254 input_proto (BundleRequest): The input proto.
Alex Klein6504eca2019-04-18 15:37:56 -0600255 output_proto (BundleResponse): The output proto.
Alex Klein231d2da2019-07-22 16:44:45 -0600256 _config (api_config.ApiConfig): The API call config.
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600257 """
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600258 output_dir = input_proto.output_dir
Michael Mortensen38675192019-06-28 16:52:55 +0000259 chroot = controller_util.ParseChroot(input_proto.chroot)
260 sysroot_path = input_proto.sysroot.path
261 sysroot = sysroot_lib.Sysroot(sysroot_path)
Alex Klein231d2da2019-07-22 16:44:45 -0600262
263 if not chroot.exists():
264 cros_build_lib.Die('Chroot does not exist: %s', chroot.path)
265 elif not sysroot.Exists(chroot=chroot):
266 cros_build_lib.Die('Sysroot does not exist: %s',
267 chroot.full_path(sysroot.path))
268
Michael Mortensen38675192019-06-28 16:52:55 +0000269 archive = artifacts.BuildFirmwareArchive(chroot, sysroot, output_dir)
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600270
Evan Hernandez9a5d3122019-04-09 10:51:23 -0600271 if archive is None:
272 cros_build_lib.Die(
Michael Mortensen38675192019-06-28 16:52:55 +0000273 'Could not create firmware archive. No firmware found for %s.',
274 sysroot_path)
Evan Hernandez9a5d3122019-04-09 10:51:23 -0600275
Alex Klein231d2da2019-07-22 16:44:45 -0600276 output_proto.artifacts.add().path = archive
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600277
278
Michael Mortensen3f382cb2019-07-29 13:21:49 -0600279@validate.exists('output_dir')
Alex Klein231d2da2019-07-22 16:44:45 -0600280def BundleEbuildLogs(input_proto, output_proto, config):
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600281 """Tar the ebuild logs for a build target.
282
283 Args:
284 input_proto (BundleRequest): The input proto.
Alex Klein6504eca2019-04-18 15:37:56 -0600285 output_proto (BundleResponse): The output proto.
Alex Klein231d2da2019-07-22 16:44:45 -0600286 config (api_config.ApiConfig): The API call config.
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600287 """
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600288 output_dir = input_proto.output_dir
Michael Mortensen3f382cb2019-07-29 13:21:49 -0600289 sysroot_path = input_proto.sysroot.path
290 chroot = controller_util.ParseChroot(input_proto.chroot)
Evan Hernandeza478d802019-04-08 15:08:24 -0600291
Michael Mortensen3f382cb2019-07-29 13:21:49 -0600292 # TODO(mmortensen) Cleanup legacy handling after it has been switched over.
293 target = input_proto.build_target.name
294 if target:
295 # Legacy handling.
296 build_root = constants.SOURCE_ROOT
Alex Klein171da612019-08-06 14:00:42 -0600297 chroot = chroot_lib.Chroot(path=os.path.join(build_root, 'chroot'))
Michael Mortensen3f382cb2019-07-29 13:21:49 -0600298 sysroot_path = os.path.join('/build', target)
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600299
Alex Klein231d2da2019-07-22 16:44:45 -0600300 # TODO(saklein): Switch to validation_complete decorator after legacy
301 # handling has been cleaned up.
302 if config.validate_only:
303 return controller.RETURN_CODE_VALID_INPUT
304
Michael Mortensen3f382cb2019-07-29 13:21:49 -0600305 sysroot = sysroot_lib.Sysroot(sysroot_path)
306 archive = artifacts.BundleEBuildLogsTarball(chroot, sysroot, output_dir)
Evan Hernandez9a5d3122019-04-09 10:51:23 -0600307 if archive is None:
308 cros_build_lib.Die(
Michael Mortensen3f382cb2019-07-29 13:21:49 -0600309 'Could not create ebuild logs archive. No logs found for %s.',
310 sysroot.path)
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600311 output_proto.artifacts.add().path = os.path.join(output_dir, archive)
Alex Klein6504eca2019-04-18 15:37:56 -0600312
313
Andrew Lamb811aead2019-08-12 10:25:05 -0600314@validate.exists('output_dir')
315@validate.validation_complete
316def BundleChromeOSConfig(input_proto, output_proto, _config):
317 """Output the ChromeOS Config payload for a build target.
318
319 Args:
320 input_proto (BundleRequest): The input proto.
321 output_proto (BundleResponse): The output proto.
322 _config (api_config.ApiConfig): The API call config.
323 """
324 output_dir = input_proto.output_dir
Andrew Lamb67bd68f2019-08-15 09:09:15 -0600325 sysroot_path = input_proto.sysroot.path
Andrew Lamb811aead2019-08-12 10:25:05 -0600326 chroot = controller_util.ParseChroot(input_proto.chroot)
327
Andrew Lamb67bd68f2019-08-15 09:09:15 -0600328 # TODO(mmortensen) Cleanup legacy handling after it has been switched over.
329 target = input_proto.build_target.name
330 if target:
331 # Legacy handling.
332 build_root = constants.SOURCE_ROOT
333 chroot = chroot_lib.Chroot(path=os.path.join(build_root, 'chroot'))
334 sysroot_path = os.path.join('/build', target)
335
336 sysroot = sysroot_lib.Sysroot(sysroot_path)
Andrew Lamb811aead2019-08-12 10:25:05 -0600337 chromeos_config = artifacts.BundleChromeOSConfig(chroot, sysroot, output_dir)
338 if chromeos_config is None:
339 cros_build_lib.Die(
340 'Could not create ChromeOS Config payload. No config found for %s.',
341 sysroot.path)
342 output_proto.artifacts.add().path = os.path.join(output_dir, chromeos_config)
343
344
Alex Klein231d2da2019-07-22 16:44:45 -0600345@validate.require('output_dir', 'sysroot.build_target.name', 'sysroot.path')
346@validate.exists('output_dir')
347@validate.validation_complete
348def BundleSimpleChromeArtifacts(input_proto, output_proto, _config):
Alex Klein2275d692019-04-23 16:04:12 -0600349 """Create the simple chrome artifacts."""
350 # Required args.
351 sysroot_path = input_proto.sysroot.path
352 build_target_name = input_proto.sysroot.build_target.name
353 output_dir = input_proto.output_dir
354
Alex Klein2275d692019-04-23 16:04:12 -0600355 # Optional args.
356 chroot_path = input_proto.chroot.path or constants.DEFAULT_CHROOT_PATH
357 cache_dir = input_proto.chroot.cache_dir
358
359 # Build out the argument instances.
360 build_target = build_target_util.BuildTarget(build_target_name)
361 chroot = chroot_lib.Chroot(path=chroot_path, cache_dir=cache_dir)
362 # Sysroot.path needs to be the fully qualified path, including the chroot.
363 full_sysroot_path = os.path.join(chroot.path, sysroot_path.lstrip(os.sep))
364 sysroot = sysroot_lib.Sysroot(full_sysroot_path)
365
366 # Quick sanity check that the sysroot exists before we go on.
367 if not sysroot.Exists():
368 cros_build_lib.Die('The sysroot does not exist.')
369
370 try:
371 results = artifacts.BundleSimpleChromeArtifacts(chroot, sysroot,
372 build_target, output_dir)
373 except artifacts.Error as e:
374 cros_build_lib.Die('Error %s raised in BundleSimpleChromeArtifacts: %s',
375 type(e), e)
376
377 for file_name in results:
378 output_proto.artifacts.add().path = file_name
379
380
Michael Mortensen51f06722019-07-18 09:55:50 -0600381@validate.require('chroot.path', 'test_results_dir', 'output_dir')
Alex Klein231d2da2019-07-22 16:44:45 -0600382@validate.exists('output_dir')
383@validate.validation_complete
384def BundleVmFiles(input_proto, output_proto, _config):
Alex Klein6504eca2019-04-18 15:37:56 -0600385 """Tar VM disk and memory files.
386
387 Args:
388 input_proto (SysrootBundleRequest): The input proto.
389 output_proto (BundleResponse): The output proto.
Alex Klein231d2da2019-07-22 16:44:45 -0600390 _config (api_config.ApiConfig): The API call config.
Alex Klein6504eca2019-04-18 15:37:56 -0600391 """
Michael Mortensen51f06722019-07-18 09:55:50 -0600392 chroot = controller_util.ParseChroot(input_proto.chroot)
393 test_results_dir = input_proto.test_results_dir
Alex Klein6504eca2019-04-18 15:37:56 -0600394 output_dir = input_proto.output_dir
395
Michael Mortensen51f06722019-07-18 09:55:50 -0600396 archives = artifacts.BundleVmFiles(
397 chroot, test_results_dir, output_dir)
Alex Klein6504eca2019-04-18 15:37:56 -0600398 for archive in archives:
399 output_proto.artifacts.add().path = archive
Tiancong Wangc4805b72019-06-11 12:12:03 -0700400
Alex Klein231d2da2019-07-22 16:44:45 -0600401
402@validate.require('build_target.name', 'output_dir')
403@validate.exists('output_dir')
404@validate.validation_complete
405def BundleOrderfileGenerationArtifacts(input_proto, output_proto, _config):
Tiancong Wangc4805b72019-06-11 12:12:03 -0700406 """Create tarballs of all the artifacts of orderfile_generate builder.
407
408 Args:
409 input_proto (BundleRequest): The input proto.
410 output_proto (BundleResponse): The output proto.
Alex Klein231d2da2019-07-22 16:44:45 -0600411 _config (api_config.ApiConfig): The API call config.
Tiancong Wangc4805b72019-06-11 12:12:03 -0700412 """
413 # Required args.
Alex Klein231d2da2019-07-22 16:44:45 -0600414 build_target = build_target_util.BuildTarget(input_proto.build_target.name)
Tiancong Wangc4805b72019-06-11 12:12:03 -0700415 output_dir = input_proto.output_dir
Tiancong Wangc4805b72019-06-11 12:12:03 -0700416
Tiancong Wangc4805b72019-06-11 12:12:03 -0700417 chroot = controller_util.ParseChroot(input_proto.chroot)
418
419 try:
420 results = artifacts.BundleOrderfileGenerationArtifacts(
Alex Klein231d2da2019-07-22 16:44:45 -0600421 chroot, build_target, output_dir)
Tiancong Wangc4805b72019-06-11 12:12:03 -0700422 except artifacts.Error as e:
423 cros_build_lib.Die('Error %s raised in BundleSimpleChromeArtifacts: %s',
424 type(e), e)
425
426 for file_name in results:
427 output_proto.artifacts.add().path = file_name
Alex Klein0b1cbfc2019-08-14 10:09:58 -0600428
429
430@validate.exists('output_dir')
431def ExportCpeReport(input_proto, output_proto, config):
432 """Export a CPE report.
433
434 Args:
435 input_proto (BundleRequest): The input proto.
436 output_proto (BundleResponse): The output proto.
437 config (api_config.ApiConfig): The API call config.
438 """
439 chroot = controller_util.ParseChroot(input_proto.chroot)
440 output_dir = input_proto.output_dir
441
442 if input_proto.build_target.name:
443 # Legacy handling - use the default sysroot path for the build target.
444 build_target = controller_util.ParseBuildTarget(input_proto.build_target)
445 sysroot = sysroot_lib.Sysroot(build_target.root)
446 elif input_proto.sysroot.path:
447 sysroot = sysroot_lib.Sysroot(input_proto.sysroot.path)
448 else:
449 # TODO(saklein): Switch to validate decorators once legacy handling can be
450 # cleaned up.
451 cros_build_lib.Die('sysroot.path is required.')
452
453 if config.validate_only:
454 return controller.RETURN_CODE_VALID_INPUT
455
456 cpe_result = artifacts.GenerateCpeReport(chroot, sysroot, output_dir)
457
458 output_proto.artifacts.add().path = cpe_result.report
459 output_proto.artifacts.add().path = cpe_result.warnings