blob: 798e59d324d1f317c34efcfe7c1a62c8cc1808c3 [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
12from chromite.cbuildbot import commands
13from chromite.lib import constants
14from chromite.lib import cros_build_lib
Evan Hernandezde445982019-04-22 13:42:34 -060015from chromite.lib import cros_logging as logging
Evan Hernandezf388cbf2019-04-01 11:15:23 -060016from chromite.lib import osutils
17
18
Evan Hernandez9f125ac2019-04-08 17:18:47 -060019def _GetImageDir(build_root, target):
20 """Return path containing images for the given build target.
21
Alex Kleine2612a02019-04-18 13:51:06 -060022 TODO(saklein) Expand image_lib.GetLatestImageLink to support this use case.
23
Evan Hernandez9f125ac2019-04-08 17:18:47 -060024 Args:
25 build_root (str): Path to checkout where build occurs.
26 target (str): Name of the build target.
27
28 Returns:
29 Path to the directory containing target images.
30
31 Raises:
32 DieSystemExit: If the image dir does not exist.
33 """
34 image_dir = os.path.join(build_root, 'src/build/images', target, 'latest')
35 if not os.path.exists(image_dir):
36 cros_build_lib.Die('Expected to find image output for target %s at %s, '
37 'but path does not exist' % (target, image_dir))
38 return image_dir
39
40
41def BundleImageZip(input_proto, output_proto):
42 """Bundle image.zip.
43
44 Args:
45 input_proto (BundleRequest): The input proto.
46 output_proto (BundleRequest): The output proto.
47 """
48 target = input_proto.build_target.name
49 output_dir = input_proto.output_dir
50 image_dir = _GetImageDir(constants.SOURCE_ROOT, target)
51 archive = commands.BuildImageZip(output_dir, image_dir)
52 output_proto.artifacts.add().path = os.path.join(output_dir, archive)
53
54
Evan Hernandezf388cbf2019-04-01 11:15:23 -060055def BundleTestUpdatePayloads(input_proto, output_proto):
56 """Generate minimal update payloads for the build target for testing.
57
58 Args:
59 input_proto (BundleRequest): The input proto.
60 output_proto (BundleRequest): The output proto.
61 """
62 target = input_proto.build_target.name
63 output_dir = input_proto.output_dir
64 build_root = constants.SOURCE_ROOT
65
66 # Use the first available image to create the update payload.
Evan Hernandez9f125ac2019-04-08 17:18:47 -060067 img_dir = _GetImageDir(build_root, target)
Evan Hernandezf388cbf2019-04-01 11:15:23 -060068 img_types = [
69 constants.IMAGE_TYPE_TEST, constants.IMAGE_TYPE_DEV,
70 constants.IMAGE_TYPE_BASE
71 ]
72 img_paths = []
73 for img_type in img_types:
Evan Hernandez9f125ac2019-04-08 17:18:47 -060074 img_path = os.path.join(img_dir, constants.IMAGE_TYPE_TO_NAME[img_type])
Evan Hernandezf388cbf2019-04-01 11:15:23 -060075 if os.path.exists(img_path):
76 img_paths.append(img_path)
77
78 if not img_paths:
79 cros_build_lib.Die(
80 'Expected to find an image of type among %r for target "%s" '
Evan Hernandez9f125ac2019-04-08 17:18:47 -060081 'at path %s.', img_types, target, img_dir)
Evan Hernandezf388cbf2019-04-01 11:15:23 -060082 img = img_paths[0]
83
84 # Unfortunately, the relevant commands.py functions do not return
85 # a list of generated files. As a workaround, we have commands.py
86 # put the files in a separate temporary directory so we can catalog them,
87 # then move them to the output dir.
Alex Kleine2612a02019-04-18 13:51:06 -060088 # TODO(crbug.com/954283): Replace with a chromite/service implementation.
Evan Hernandezf388cbf2019-04-01 11:15:23 -060089 with osutils.TempDir() as temp:
90 commands.GeneratePayloads(img, temp, full=True, stateful=True, delta=True)
91 commands.GenerateQuickProvisionPayloads(img, temp)
92 for path in osutils.DirectoryIterator(temp):
93 if os.path.isfile(path):
94 rel_path = os.path.relpath(path, temp)
95 output_proto.artifacts.add().path = os.path.join(output_dir, rel_path)
Evan Hernandezb04e2aa2019-04-08 16:55:54 -060096 osutils.CopyDirContents(temp, output_dir, allow_nonempty=True)
Evan Hernandezf388cbf2019-04-01 11:15:23 -060097
98
99def BundleAutotestFiles(input_proto, output_proto):
100 """Tar the autotest files for a build target.
101
102 Args:
103 input_proto (BundleRequest): The input proto.
104 output_proto (BundleRequest): The output proto.
105 """
106 target = input_proto.build_target.name
107 output_dir = input_proto.output_dir
108 build_root = constants.SOURCE_ROOT
Evan Hernandez36589c62019-04-05 18:14:42 -0600109 cwd = os.path.join(build_root, 'chroot/build', target, 'usr/local/build')
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600110
111 # Note that unlike the functions below, this returns the full path
112 # to *multiple* tarballs.
Alex Kleine2612a02019-04-18 13:51:06 -0600113 # TODO(crbug.com/954289): Replace with a chromite/service implementation.
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600114 archives = commands.BuildAutotestTarballsForHWTest(build_root, cwd,
115 output_dir)
116
117 for archive in archives:
118 output_proto.artifacts.add().path = archive
119
120
121def BundleTastFiles(input_proto, output_proto):
122 """Tar the tast files for a build target.
123
124 Args:
125 input_proto (BundleRequest): The input proto.
126 output_proto (BundleRequest): The output proto.
127 """
128 target = input_proto.build_target.name
129 output_dir = input_proto.output_dir
130 build_root = constants.SOURCE_ROOT
Evan Hernandez36589c62019-04-05 18:14:42 -0600131 cwd = os.path.join(build_root, 'chroot/build', target, 'build')
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600132
133 # Note that unlike the functions below, this returns the full path
134 # to the tarball.
Alex Kleine2612a02019-04-18 13:51:06 -0600135 # TODO(crbug.com/954294): Replace with a chromite/service implementation.
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600136 archive = commands.BuildTastBundleTarball(build_root, cwd, output_dir)
137
Evan Hernandez9a5d3122019-04-09 10:51:23 -0600138 if archive is None:
139 cros_build_lib.Die(
140 'Could not bundle Tast files. '
141 'No Tast directories found for %s.', target)
142
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600143 output_proto.artifacts.add().path = archive
144
145
146def BundlePinnedGuestImages(input_proto, output_proto):
147 """Tar the pinned guest images for a build target.
148
149 Args:
150 input_proto (BundleRequest): The input proto.
151 output_proto (BundleRequest): The output proto.
152 """
153 target = input_proto.build_target.name
154 output_dir = input_proto.output_dir
155 build_root = constants.SOURCE_ROOT
156
Alex Kleine2612a02019-04-18 13:51:06 -0600157 # TODO(crbug.com/954299): Replace with a chromite/service implementation.
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600158 archive = commands.BuildPinnedGuestImagesTarball(build_root, target,
159 output_dir)
160
Evan Hernandez9a5d3122019-04-09 10:51:23 -0600161 if archive is None:
Evan Hernandezde445982019-04-22 13:42:34 -0600162 logging.warning('Found no pinned guest images for %s.', target)
163 return
Evan Hernandez9a5d3122019-04-09 10:51:23 -0600164
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600165 output_proto.artifacts.add().path = os.path.join(output_dir, archive)
166
167
168def BundleFirmware(input_proto, output_proto):
169 """Tar the firmware images for a build target.
170
171 Args:
172 input_proto (BundleRequest): The input proto.
173 output_proto (BundleRequest): The output proto.
174 """
175 target = input_proto.build_target.name
176 output_dir = input_proto.output_dir
177 build_root = constants.SOURCE_ROOT
178
Alex Kleine2612a02019-04-18 13:51:06 -0600179 # TODO(crbug.com/954300): Replace with a chromite/service implementation.
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600180 archive = commands.BuildFirmwareArchive(build_root, target, output_dir)
181
Evan Hernandez9a5d3122019-04-09 10:51:23 -0600182 if archive is None:
183 cros_build_lib.Die(
184 'Could not create firmware archive. No firmware found for %s.', target)
185
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600186 output_proto.artifacts.add().path = os.path.join(output_dir, archive)
187
188
189def BundleEbuildLogs(input_proto, output_proto):
190 """Tar the ebuild logs for a build target.
191
192 Args:
193 input_proto (BundleRequest): The input proto.
194 output_proto (BundleRequest): The output proto.
195 """
196 target = input_proto.build_target.name
197 output_dir = input_proto.output_dir
Evan Hernandeza478d802019-04-08 15:08:24 -0600198
199 # commands.BuildEbuildLogsTarball conflates "buildroot" with sysroot.
200 # Adjust accordingly...
201 build_root = os.path.join(constants.SOURCE_ROOT, 'chroot', 'build')
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600202
Alex Kleine2612a02019-04-18 13:51:06 -0600203 # TODO(crbug.com/954303): Replace with a chromite/service implementation.
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600204 archive = commands.BuildEbuildLogsTarball(build_root, target, output_dir)
205
Evan Hernandez9a5d3122019-04-09 10:51:23 -0600206 if archive is None:
207 cros_build_lib.Die(
208 'Could not create ebuild logs archive. No logs found for %s.', target)
209
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600210 output_proto.artifacts.add().path = os.path.join(output_dir, archive)