blob: 702b1d11bcc68649dc3efe03cf6e5d657ba8d6a1 [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
Alex Kleine21a0952019-08-23 16:08:16 -0600113 chroot = controller_util.ParseChroot(input_proto.chroot)
114
Alex Klein238d8862019-05-07 11:32:46 -0600115 if target:
Alex Kleine21a0952019-08-23 16:08:16 -0600116 sysroot_path = os.path.join('/build', target)
Alex Klein238d8862019-05-07 11:32:46 -0600117 else:
118 # New style call, use chroot and sysroot.
Alex Klein238d8862019-05-07 11:32:46 -0600119 sysroot_path = input_proto.sysroot.path
120 if not sysroot_path:
121 cros_build_lib.Die('sysroot.path is required.')
122
Alex Kleine21a0952019-08-23 16:08:16 -0600123 sysroot = sysroot_lib.Sysroot(sysroot_path)
Alex Klein238d8862019-05-07 11:32:46 -0600124
Alex Klein231d2da2019-07-22 16:44:45 -0600125 # TODO(saklein): Switch to the validate_only decorator when legacy handling
126 # is removed.
127 if config.validate_only:
128 return controller.RETURN_CODE_VALID_INPUT
129
Alex Kleine21a0952019-08-23 16:08:16 -0600130 if not sysroot.Exists(chroot=chroot):
Alex Klein238d8862019-05-07 11:32:46 -0600131 cros_build_lib.Die('Sysroot path must exist: %s', sysroot.path)
132
133 try:
134 # Note that this returns the full path to *multiple* tarballs.
Alex Kleine21a0952019-08-23 16:08:16 -0600135 archives = artifacts.BundleAutotestFiles(chroot, sysroot, output_dir)
Alex Klein238d8862019-05-07 11:32:46 -0600136 except artifacts.Error as e:
137 cros_build_lib.Die(e.message)
138
139 for archive in archives.values():
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600140 output_proto.artifacts.add().path = archive
141
142
Alex Kleinb9d810b2019-07-01 12:38:02 -0600143@validate.require('output_dir')
Alex Klein231d2da2019-07-22 16:44:45 -0600144@validate.exists('output_dir')
145def BundleTastFiles(input_proto, output_proto, config):
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600146 """Tar the tast files for a build target.
147
148 Args:
149 input_proto (BundleRequest): The input proto.
Alex Klein6504eca2019-04-18 15:37:56 -0600150 output_proto (BundleResponse): The output proto.
Alex Klein231d2da2019-07-22 16:44:45 -0600151 config (api_config.ApiConfig): The API call config.
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600152 """
153 target = input_proto.build_target.name
154 output_dir = input_proto.output_dir
155 build_root = constants.SOURCE_ROOT
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600156
Alex Kleinb9d810b2019-07-01 12:38:02 -0600157 chroot = controller_util.ParseChroot(input_proto.chroot)
158 sysroot_path = input_proto.sysroot.path
159
160 # TODO(saklein) Cleanup legacy handling after it has been switched over.
161 if target:
162 # Legacy handling.
Alex Klein171da612019-08-06 14:00:42 -0600163 chroot = chroot_lib.Chroot(path=os.path.join(build_root, 'chroot'))
Alex Kleinb9d810b2019-07-01 12:38:02 -0600164 sysroot_path = os.path.join('/build', target)
165
166 # New handling - chroot & sysroot based.
167 # TODO(saklein) Switch this to the require decorator when legacy is removed.
168 if not sysroot_path:
169 cros_build_lib.Die('sysroot.path is required.')
170
Alex Klein231d2da2019-07-22 16:44:45 -0600171 # TODO(saklein): Switch to the validation_complete decorator when legacy
172 # handling is removed.
173 if config.validate_only:
174 return controller.RETURN_CODE_VALID_INPUT
175
Alex Kleinb9d810b2019-07-01 12:38:02 -0600176 sysroot = sysroot_lib.Sysroot(sysroot_path)
Alex Klein231d2da2019-07-22 16:44:45 -0600177 if not sysroot.Exists(chroot=chroot):
Alex Kleinb9d810b2019-07-01 12:38:02 -0600178 cros_build_lib.Die('Sysroot must exist.')
179
180 archive = artifacts.BundleTastFiles(chroot, sysroot, output_dir)
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600181
Evan Hernandez9a5d3122019-04-09 10:51:23 -0600182 if archive is None:
183 cros_build_lib.Die(
184 'Could not bundle Tast files. '
185 'No Tast directories found for %s.', target)
186
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600187 output_proto.artifacts.add().path = archive
188
189
Alex Klein231d2da2019-07-22 16:44:45 -0600190@validate.require('build_target.name', 'output_dir')
191@validate.exists('output_dir')
192@validate.validation_complete
193def BundlePinnedGuestImages(input_proto, output_proto, _config):
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600194 """Tar the pinned guest images for a build target.
195
196 Args:
197 input_proto (BundleRequest): The input proto.
Alex Klein6504eca2019-04-18 15:37:56 -0600198 output_proto (BundleResponse): The output proto.
Alex Klein231d2da2019-07-22 16:44:45 -0600199 _config (api_config.ApiConfig): The API call config.
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600200 """
201 target = input_proto.build_target.name
202 output_dir = input_proto.output_dir
203 build_root = constants.SOURCE_ROOT
204
Alex Kleine2612a02019-04-18 13:51:06 -0600205 # TODO(crbug.com/954299): Replace with a chromite/service implementation.
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600206 archive = commands.BuildPinnedGuestImagesTarball(build_root, target,
207 output_dir)
208
Evan Hernandez9a5d3122019-04-09 10:51:23 -0600209 if archive is None:
Evan Hernandezde445982019-04-22 13:42:34 -0600210 logging.warning('Found no pinned guest images for %s.', target)
211 return
Evan Hernandez9a5d3122019-04-09 10:51:23 -0600212
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600213 output_proto.artifacts.add().path = os.path.join(output_dir, archive)
214
215
Alex Klein231d2da2019-07-22 16:44:45 -0600216@validate.require('sysroot.path')
217@validate.validation_complete
218def FetchPinnedGuestImages(input_proto, output_proto, _config):
Alex Klein7bf0ecb2019-06-25 10:04:15 -0600219 """Get the pinned guest image information."""
220 sysroot_path = input_proto.sysroot.path
Alex Klein7bf0ecb2019-06-25 10:04:15 -0600221
222 chroot = controller_util.ParseChroot(input_proto.chroot)
223 sysroot = sysroot_lib.Sysroot(sysroot_path)
224
225 if not chroot.exists():
226 cros_build_lib.Die('Chroot does not exist: %s', chroot.path)
Alex Klein231d2da2019-07-22 16:44:45 -0600227 elif not sysroot.Exists(chroot=chroot):
Alex Klein7bf0ecb2019-06-25 10:04:15 -0600228 cros_build_lib.Die('Sysroot does not exist: %s',
229 chroot.full_path(sysroot.path))
230
231 pins = artifacts.FetchPinnedGuestImages(chroot, sysroot)
232
233 for pin in pins:
234 pinned_image = output_proto.pinned_images.add()
235 pinned_image.filename = pin.filename
236 pinned_image.uri = pin.uri
237
238
Michael Mortensen38675192019-06-28 16:52:55 +0000239@validate.require('output_dir', 'sysroot.path')
Alex Klein231d2da2019-07-22 16:44:45 -0600240@validate.exists('output_dir')
241@validate.validation_complete
242def BundleFirmware(input_proto, output_proto, _config):
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600243 """Tar the firmware images for a build target.
244
245 Args:
246 input_proto (BundleRequest): The input proto.
Alex Klein6504eca2019-04-18 15:37:56 -0600247 output_proto (BundleResponse): The output proto.
Alex Klein231d2da2019-07-22 16:44:45 -0600248 _config (api_config.ApiConfig): The API call config.
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600249 """
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600250 output_dir = input_proto.output_dir
Michael Mortensen38675192019-06-28 16:52:55 +0000251 chroot = controller_util.ParseChroot(input_proto.chroot)
252 sysroot_path = input_proto.sysroot.path
253 sysroot = sysroot_lib.Sysroot(sysroot_path)
Alex Klein231d2da2019-07-22 16:44:45 -0600254
255 if not chroot.exists():
256 cros_build_lib.Die('Chroot does not exist: %s', chroot.path)
257 elif not sysroot.Exists(chroot=chroot):
258 cros_build_lib.Die('Sysroot does not exist: %s',
259 chroot.full_path(sysroot.path))
260
Michael Mortensen38675192019-06-28 16:52:55 +0000261 archive = artifacts.BuildFirmwareArchive(chroot, sysroot, output_dir)
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600262
Evan Hernandez9a5d3122019-04-09 10:51:23 -0600263 if archive is None:
264 cros_build_lib.Die(
Michael Mortensen38675192019-06-28 16:52:55 +0000265 'Could not create firmware archive. No firmware found for %s.',
266 sysroot_path)
Evan Hernandez9a5d3122019-04-09 10:51:23 -0600267
Alex Klein231d2da2019-07-22 16:44:45 -0600268 output_proto.artifacts.add().path = archive
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600269
270
Michael Mortensen3f382cb2019-07-29 13:21:49 -0600271@validate.exists('output_dir')
Alex Klein231d2da2019-07-22 16:44:45 -0600272def BundleEbuildLogs(input_proto, output_proto, config):
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600273 """Tar the ebuild logs for a build target.
274
275 Args:
276 input_proto (BundleRequest): The input proto.
Alex Klein6504eca2019-04-18 15:37:56 -0600277 output_proto (BundleResponse): The output proto.
Alex Klein231d2da2019-07-22 16:44:45 -0600278 config (api_config.ApiConfig): The API call config.
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600279 """
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600280 output_dir = input_proto.output_dir
Michael Mortensen3f382cb2019-07-29 13:21:49 -0600281 sysroot_path = input_proto.sysroot.path
282 chroot = controller_util.ParseChroot(input_proto.chroot)
Evan Hernandeza478d802019-04-08 15:08:24 -0600283
Michael Mortensen3f382cb2019-07-29 13:21:49 -0600284 # TODO(mmortensen) Cleanup legacy handling after it has been switched over.
285 target = input_proto.build_target.name
286 if target:
287 # Legacy handling.
288 build_root = constants.SOURCE_ROOT
Alex Klein171da612019-08-06 14:00:42 -0600289 chroot = chroot_lib.Chroot(path=os.path.join(build_root, 'chroot'))
Michael Mortensen3f382cb2019-07-29 13:21:49 -0600290 sysroot_path = os.path.join('/build', target)
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600291
Alex Klein231d2da2019-07-22 16:44:45 -0600292 # TODO(saklein): Switch to validation_complete decorator after legacy
293 # handling has been cleaned up.
294 if config.validate_only:
295 return controller.RETURN_CODE_VALID_INPUT
296
Michael Mortensen3f382cb2019-07-29 13:21:49 -0600297 sysroot = sysroot_lib.Sysroot(sysroot_path)
298 archive = artifacts.BundleEBuildLogsTarball(chroot, sysroot, output_dir)
Evan Hernandez9a5d3122019-04-09 10:51:23 -0600299 if archive is None:
300 cros_build_lib.Die(
Michael Mortensen3f382cb2019-07-29 13:21:49 -0600301 'Could not create ebuild logs archive. No logs found for %s.',
302 sysroot.path)
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600303 output_proto.artifacts.add().path = os.path.join(output_dir, archive)
Alex Klein6504eca2019-04-18 15:37:56 -0600304
305
Andrew Lamb811aead2019-08-12 10:25:05 -0600306@validate.exists('output_dir')
307@validate.validation_complete
308def BundleChromeOSConfig(input_proto, output_proto, _config):
309 """Output the ChromeOS Config payload for a build target.
310
311 Args:
312 input_proto (BundleRequest): The input proto.
313 output_proto (BundleResponse): The output proto.
314 _config (api_config.ApiConfig): The API call config.
315 """
316 output_dir = input_proto.output_dir
Andrew Lamb67bd68f2019-08-15 09:09:15 -0600317 sysroot_path = input_proto.sysroot.path
Andrew Lamb811aead2019-08-12 10:25:05 -0600318 chroot = controller_util.ParseChroot(input_proto.chroot)
319
Andrew Lamb67bd68f2019-08-15 09:09:15 -0600320 # TODO(mmortensen) Cleanup legacy handling after it has been switched over.
321 target = input_proto.build_target.name
322 if target:
323 # Legacy handling.
324 build_root = constants.SOURCE_ROOT
325 chroot = chroot_lib.Chroot(path=os.path.join(build_root, 'chroot'))
326 sysroot_path = os.path.join('/build', target)
327
328 sysroot = sysroot_lib.Sysroot(sysroot_path)
Andrew Lamb811aead2019-08-12 10:25:05 -0600329 chromeos_config = artifacts.BundleChromeOSConfig(chroot, sysroot, output_dir)
330 if chromeos_config is None:
331 cros_build_lib.Die(
332 'Could not create ChromeOS Config payload. No config found for %s.',
333 sysroot.path)
334 output_proto.artifacts.add().path = os.path.join(output_dir, chromeos_config)
335
336
Alex Klein231d2da2019-07-22 16:44:45 -0600337@validate.require('output_dir', 'sysroot.build_target.name', 'sysroot.path')
338@validate.exists('output_dir')
339@validate.validation_complete
340def BundleSimpleChromeArtifacts(input_proto, output_proto, _config):
Alex Klein2275d692019-04-23 16:04:12 -0600341 """Create the simple chrome artifacts."""
342 # Required args.
343 sysroot_path = input_proto.sysroot.path
344 build_target_name = input_proto.sysroot.build_target.name
345 output_dir = input_proto.output_dir
346
Alex Klein2275d692019-04-23 16:04:12 -0600347 # Optional args.
348 chroot_path = input_proto.chroot.path or constants.DEFAULT_CHROOT_PATH
349 cache_dir = input_proto.chroot.cache_dir
350
351 # Build out the argument instances.
352 build_target = build_target_util.BuildTarget(build_target_name)
353 chroot = chroot_lib.Chroot(path=chroot_path, cache_dir=cache_dir)
354 # Sysroot.path needs to be the fully qualified path, including the chroot.
355 full_sysroot_path = os.path.join(chroot.path, sysroot_path.lstrip(os.sep))
356 sysroot = sysroot_lib.Sysroot(full_sysroot_path)
357
358 # Quick sanity check that the sysroot exists before we go on.
359 if not sysroot.Exists():
360 cros_build_lib.Die('The sysroot does not exist.')
361
362 try:
363 results = artifacts.BundleSimpleChromeArtifacts(chroot, sysroot,
364 build_target, output_dir)
365 except artifacts.Error as e:
366 cros_build_lib.Die('Error %s raised in BundleSimpleChromeArtifacts: %s',
367 type(e), e)
368
369 for file_name in results:
370 output_proto.artifacts.add().path = file_name
371
372
Michael Mortensen51f06722019-07-18 09:55:50 -0600373@validate.require('chroot.path', 'test_results_dir', 'output_dir')
Alex Klein231d2da2019-07-22 16:44:45 -0600374@validate.exists('output_dir')
375@validate.validation_complete
376def BundleVmFiles(input_proto, output_proto, _config):
Alex Klein6504eca2019-04-18 15:37:56 -0600377 """Tar VM disk and memory files.
378
379 Args:
380 input_proto (SysrootBundleRequest): The input proto.
381 output_proto (BundleResponse): The output proto.
Alex Klein231d2da2019-07-22 16:44:45 -0600382 _config (api_config.ApiConfig): The API call config.
Alex Klein6504eca2019-04-18 15:37:56 -0600383 """
Michael Mortensen51f06722019-07-18 09:55:50 -0600384 chroot = controller_util.ParseChroot(input_proto.chroot)
385 test_results_dir = input_proto.test_results_dir
Alex Klein6504eca2019-04-18 15:37:56 -0600386 output_dir = input_proto.output_dir
387
Michael Mortensen51f06722019-07-18 09:55:50 -0600388 archives = artifacts.BundleVmFiles(
389 chroot, test_results_dir, output_dir)
Alex Klein6504eca2019-04-18 15:37:56 -0600390 for archive in archives:
391 output_proto.artifacts.add().path = archive
Tiancong Wangc4805b72019-06-11 12:12:03 -0700392
Alex Klein231d2da2019-07-22 16:44:45 -0600393
Tiancong Wang50b80a92019-08-01 14:46:15 -0700394_VALID_ARTIFACT_TYPES = [artifacts_pb2.BENCHMARK_AFDO,
395 artifacts_pb2.ORDERFILE]
Alex Klein231d2da2019-07-22 16:44:45 -0600396@validate.require('build_target.name', 'output_dir')
Tiancong Wang50b80a92019-08-01 14:46:15 -0700397@validate.is_in('artifact_type', _VALID_ARTIFACT_TYPES)
Alex Klein231d2da2019-07-22 16:44:45 -0600398@validate.exists('output_dir')
399@validate.validation_complete
Tiancong Wang50b80a92019-08-01 14:46:15 -0700400def BundleAFDOGenerationArtifacts(input_proto, output_proto, _config):
401 """Generic function for creating tarballs of both AFDO and orerfile.
Tiancong Wangc4805b72019-06-11 12:12:03 -0700402
403 Args:
Tiancong Wang50b80a92019-08-01 14:46:15 -0700404 input_proto (BundleChromeAFDORequest): The input proto.
Tiancong Wangc4805b72019-06-11 12:12:03 -0700405 output_proto (BundleResponse): The output proto.
Alex Klein231d2da2019-07-22 16:44:45 -0600406 _config (api_config.ApiConfig): The API call config.
Tiancong Wangc4805b72019-06-11 12:12:03 -0700407 """
Tiancong Wang50b80a92019-08-01 14:46:15 -0700408
Tiancong Wangc4805b72019-06-11 12:12:03 -0700409 # Required args.
Alex Klein231d2da2019-07-22 16:44:45 -0600410 build_target = build_target_util.BuildTarget(input_proto.build_target.name)
Tiancong Wangc4805b72019-06-11 12:12:03 -0700411 output_dir = input_proto.output_dir
Tiancong Wang50b80a92019-08-01 14:46:15 -0700412 artifact_type = input_proto.artifact_type
Tiancong Wangc4805b72019-06-11 12:12:03 -0700413
Tiancong Wangc4805b72019-06-11 12:12:03 -0700414 chroot = controller_util.ParseChroot(input_proto.chroot)
415
416 try:
Tiancong Wang50b80a92019-08-01 14:46:15 -0700417 is_orderfile = bool(artifact_type is artifacts_pb2.ORDERFILE)
418 results = artifacts.BundleAFDOGenerationArtifacts(
419 is_orderfile, chroot,
420 build_target, output_dir)
Tiancong Wangc4805b72019-06-11 12:12:03 -0700421 except artifacts.Error as e:
422 cros_build_lib.Die('Error %s raised in BundleSimpleChromeArtifacts: %s',
423 type(e), e)
424
425 for file_name in results:
426 output_proto.artifacts.add().path = file_name
Alex Klein0b1cbfc2019-08-14 10:09:58 -0600427
428
429@validate.exists('output_dir')
430def ExportCpeReport(input_proto, output_proto, config):
431 """Export a CPE report.
432
433 Args:
434 input_proto (BundleRequest): The input proto.
435 output_proto (BundleResponse): The output proto.
436 config (api_config.ApiConfig): The API call config.
437 """
438 chroot = controller_util.ParseChroot(input_proto.chroot)
439 output_dir = input_proto.output_dir
440
441 if input_proto.build_target.name:
442 # Legacy handling - use the default sysroot path for the build target.
443 build_target = controller_util.ParseBuildTarget(input_proto.build_target)
444 sysroot = sysroot_lib.Sysroot(build_target.root)
445 elif input_proto.sysroot.path:
446 sysroot = sysroot_lib.Sysroot(input_proto.sysroot.path)
447 else:
448 # TODO(saklein): Switch to validate decorators once legacy handling can be
449 # cleaned up.
450 cros_build_lib.Die('sysroot.path is required.')
451
452 if config.validate_only:
453 return controller.RETURN_CODE_VALID_INPUT
454
455 cpe_result = artifacts.GenerateCpeReport(chroot, sysroot, output_dir)
456
457 output_proto.artifacts.add().path = cpe_result.report
458 output_proto.artifacts.add().path = cpe_result.warnings