blob: 5546a51bace85f8a01048c012082f63964f30958 [file] [log] [blame]
Alex Klein2966e302019-01-17 13:29:38 -07001# Copyright 2018 The Chromium OS Authors. All rights reserved.
2# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
4
5"""Image API Service.
6
7The image related API endpoints should generally be found here.
8"""
9
Jack Neus5e56fef2021-06-18 16:57:28 +000010import functools
Chris McDonald1672ddb2021-07-21 11:48:23 -060011import logging
Alex Klein2966e302019-01-17 13:29:38 -070012import os
13
Alex Klein8cb365a2019-05-15 16:24:53 -060014from chromite.api import controller
Alex Klein076841b2019-08-29 15:19:39 -060015from chromite.api import faux
Alex Klein2b236722019-06-19 15:44:26 -060016from chromite.api import validate
Alex Kleine9a7dbf2020-10-06 18:12:12 -060017from chromite.api.controller import controller_util
David Burgerb171d652019-05-13 16:07:00 -060018from chromite.api.gen.chromiumos import common_pb2
Will Bradley9bc85452019-10-10 10:48:21 -060019from chromite.api.metrics import deserialize_metrics_log
George Engelbrechtc9a8e812021-06-16 18:14:17 -060020from chromite.lib import build_target_lib
21from chromite.lib import chroot_lib
Alex Klein56355682019-02-07 10:36:54 -070022from chromite.lib import constants
Chris McDonald1672ddb2021-07-21 11:48:23 -060023from chromite.lib import cros_build_lib
Alex Klein56355682019-02-07 10:36:54 -070024from chromite.lib import image_lib
George Engelbrechtc9a8e812021-06-16 18:14:17 -060025from chromite.lib import sysroot_lib
Jack Neus761e1842020-12-01 18:20:11 +000026from chromite.scripts import pushimage
Alex Kleinb7cdbe62019-02-22 11:41:32 -070027from chromite.service import image
Will Bradley9bc85452019-10-10 10:48:21 -060028from chromite.utils import metrics
Alex Klein2966e302019-01-17 13:29:38 -070029
Alex Klein56355682019-02-07 10:36:54 -070030# The image.proto ImageType enum ids.
George Engelbrechtc55d6312021-05-05 12:11:13 -060031_BASE_ID = common_pb2.IMAGE_TYPE_BASE
32_DEV_ID = common_pb2.IMAGE_TYPE_DEV
33_TEST_ID = common_pb2.IMAGE_TYPE_TEST
34_BASE_VM_ID = common_pb2.IMAGE_TYPE_BASE_VM
35_TEST_VM_ID = common_pb2.IMAGE_TYPE_TEST_VM
36_RECOVERY_ID = common_pb2.IMAGE_TYPE_RECOVERY
37_FACTORY_ID = common_pb2.IMAGE_TYPE_FACTORY
38_FIRMWARE_ID = common_pb2.IMAGE_TYPE_FIRMWARE
39_BASE_GUEST_VM_ID = common_pb2.IMAGE_TYPE_BASE_GUEST_VM
40_TEST_GUEST_VM_ID = common_pb2.IMAGE_TYPE_TEST_GUEST_VM
Alex Klein56355682019-02-07 10:36:54 -070041
42# Dict to allow easily translating names to enum ids and vice versa.
43_IMAGE_MAPPING = {
44 _BASE_ID: constants.IMAGE_TYPE_BASE,
45 constants.IMAGE_TYPE_BASE: _BASE_ID,
46 _DEV_ID: constants.IMAGE_TYPE_DEV,
47 constants.IMAGE_TYPE_DEV: _DEV_ID,
48 _TEST_ID: constants.IMAGE_TYPE_TEST,
49 constants.IMAGE_TYPE_TEST: _TEST_ID,
Michael Mortenseneefe8952019-08-12 15:37:15 -060050 _RECOVERY_ID: constants.IMAGE_TYPE_RECOVERY,
51 constants.IMAGE_TYPE_RECOVERY: _RECOVERY_ID,
Alex Klein9039a952021-07-27 13:52:39 -060052 _FACTORY_ID: constants.IMAGE_TYPE_FACTORY_SHIM,
53 constants.IMAGE_TYPE_FACTORY_SHIM: _FACTORY_ID,
Michael Mortenseneefe8952019-08-12 15:37:15 -060054 _FIRMWARE_ID: constants.IMAGE_TYPE_FIRMWARE,
55 constants.IMAGE_TYPE_FIRMWARE: _FIRMWARE_ID,
Alex Klein56355682019-02-07 10:36:54 -070056}
57
George Engelbrecht9f4f8322021-03-08 12:04:17 -070058# Dict to describe the prerequisite built images for each VM image type.
Alex Klein21b95022019-05-09 14:14:46 -060059_VM_IMAGE_MAPPING = {
60 _BASE_VM_ID: _IMAGE_MAPPING[_BASE_ID],
61 _TEST_VM_ID: _IMAGE_MAPPING[_TEST_ID],
Trent Begin008cade2019-10-31 13:40:59 -060062 _BASE_GUEST_VM_ID: _IMAGE_MAPPING[_BASE_ID],
63 _TEST_GUEST_VM_ID: _IMAGE_MAPPING[_TEST_ID],
Alex Klein21b95022019-05-09 14:14:46 -060064}
65
George Engelbrecht9f4f8322021-03-08 12:04:17 -070066# Dict to describe the prerequisite built images for each mod image type.
67_MOD_IMAGE_MAPPING = {
68 _RECOVERY_ID: _IMAGE_MAPPING[_BASE_ID],
69}
70
Jack Neus761e1842020-12-01 18:20:11 +000071# Supported image types for PushImage.
72SUPPORTED_IMAGE_TYPES = {
73 common_pb2.IMAGE_TYPE_RECOVERY: constants.IMAGE_TYPE_RECOVERY,
74 common_pb2.IMAGE_TYPE_FACTORY: constants.IMAGE_TYPE_FACTORY,
75 common_pb2.IMAGE_TYPE_FIRMWARE: constants.IMAGE_TYPE_FIRMWARE,
76 common_pb2.IMAGE_TYPE_ACCESSORY_USBPD: constants.IMAGE_TYPE_ACCESSORY_USBPD,
77 common_pb2.IMAGE_TYPE_ACCESSORY_RWSIG: constants.IMAGE_TYPE_ACCESSORY_RWSIG,
78 common_pb2.IMAGE_TYPE_BASE: constants.IMAGE_TYPE_BASE,
George Engelbrecht9f4f8322021-03-08 12:04:17 -070079 common_pb2.IMAGE_TYPE_GSC_FIRMWARE: constants.IMAGE_TYPE_GSC_FIRMWARE,
Jack Neus761e1842020-12-01 18:20:11 +000080}
81
Alex Klein56355682019-02-07 10:36:54 -070082
George Engelbrecht9f4f8322021-03-08 12:04:17 -070083def _add_image_to_proto(output_proto, path, image_type, board):
84 """Quick helper function to add a new image to the output proto."""
85 new_image = output_proto.images.add()
86 new_image.path = path
87 new_image.type = image_type
88 new_image.build_target.name = board
89
90
George Engelbrechtc9a8e812021-06-16 18:14:17 -060091def ExampleGetResponse():
92 """Give an example response to assemble upstream in caller artifacts."""
93 uabs = common_pb2.UploadedArtifactsByService
94 cabs = common_pb2.ArtifactsByService
95 return uabs.Sysroot(artifacts=[
96 uabs.Image.ArtifactPaths(
97 artifact_type=cabs.Image.ArtifactType.DLC_IMAGE,
98 paths=[
99 common_pb2.Path(
100 path='/tmp/dlc/dlc.img', location=common_pb2.Path.OUTSIDE)
101 ])
102 ])
103
104
105def GetArtifacts(in_proto: common_pb2.ArtifactsByService.Image,
Alex Kleincaace392021-07-26 14:28:13 -0600106 chroot: chroot_lib.Chroot, sysroot_class: sysroot_lib.Sysroot,
107 build_target: build_target_lib.BuildTarget,
108 output_dir) -> list:
George Engelbrechtc9a8e812021-06-16 18:14:17 -0600109 """Builds and copies images to specified output_dir.
110
111 Copies (after optionally bundling) all required images into the output_dir,
112 returning a mapping of image type to a list of (output_dir) paths to
113 the desired files. Note that currently it is only processing one image (DLC),
114 but the future direction is to process all required images. Required images
115 are located within output_artifact.artifact_type.
116
117 Args:
118 in_proto: Proto request defining reqs.
119 chroot: The chroot proto used for these artifacts.
120 sysroot_class: The sysroot proto used for these artifacts.
121 build_target: The build target used for these artifacts.
122 output_dir: The path to write artifacts to.
123
124 Returns:
125 A list of dictionary mappings of ArtifactType to list of paths.
126 """
Pi-Hsun Shih8d9c8e42021-06-30 03:27:28 +0000127 base_path = chroot.full_path(sysroot_class.path)
Jack Neus5e56fef2021-06-18 16:57:28 +0000128 board = build_target.name
129
130 generated = []
131 dlc_func = functools.partial(image.copy_dlc_image, base_path)
132 license_func = functools.partial(image.copy_license_credits, board)
133 artifact_types = {
Alex Kleincaace392021-07-26 14:28:13 -0600134 in_proto.ArtifactType.DLC_IMAGE: dlc_func,
135 in_proto.ArtifactType.LICENSE_CREDITS: license_func,
Jack Neus5e56fef2021-06-18 16:57:28 +0000136 }
George Engelbrechtc9a8e812021-06-16 18:14:17 -0600137
138 for output_artifact in in_proto.output_artifacts:
Jack Neus5e56fef2021-06-18 16:57:28 +0000139 for artifact_type, func in artifact_types.items():
140 if artifact_type in output_artifact.artifact_types:
141 result = func(output_dir)
142 if result:
143 generated.append({
144 'paths': [result] if isinstance(result, str) else result,
145 'type': artifact_type,
146 })
George Engelbrechtc9a8e812021-06-16 18:14:17 -0600147
Jack Neus5e56fef2021-06-18 16:57:28 +0000148 return generated
Pi-Hsun Shih8d9c8e42021-06-30 03:27:28 +0000149
Alex Kleincaace392021-07-26 14:28:13 -0600150
Michael Mortensen10146cf2019-11-19 19:59:22 -0700151def _CreateResponse(_input_proto, output_proto, _config):
152 """Set output_proto success field on a successful Create response."""
153 output_proto.success = True
154
155
156@faux.success(_CreateResponse)
Michael Mortensen85d38402019-12-12 09:50:29 -0700157@faux.empty_completed_unsuccessfully_error
Alex Klein2b236722019-06-19 15:44:26 -0600158@validate.require('build_target.name')
Alex Klein231d2da2019-07-22 16:44:45 -0600159@validate.validation_complete
Will Bradley9bc85452019-10-10 10:48:21 -0600160@metrics.collect_metrics
Alex Klein231d2da2019-07-22 16:44:45 -0600161def Create(input_proto, output_proto, _config):
George Engelbrecht9f4f8322021-03-08 12:04:17 -0700162 """Build images.
Alex Klein56355682019-02-07 10:36:54 -0700163
164 Args:
165 input_proto (image_pb2.CreateImageRequest): The input message.
166 output_proto (image_pb2.CreateImageResult): The output message.
Alex Klein231d2da2019-07-22 16:44:45 -0600167 _config (api_config.ApiConfig): The API call config.
Alex Klein56355682019-02-07 10:36:54 -0700168 """
169 board = input_proto.build_target.name
Alex Klein56355682019-02-07 10:36:54 -0700170
Alex Klein56355682019-02-07 10:36:54 -0700171 # Build the base image if no images provided.
172 to_build = input_proto.image_types or [_BASE_ID]
Alex Klein56355682019-02-07 10:36:54 -0700173
George Engelbrecht9f4f8322021-03-08 12:04:17 -0700174 image_types, vm_types, mod_image_types = _ParseImagesToCreate(to_build)
Alex Klein21b95022019-05-09 14:14:46 -0600175 build_config = _ParseCreateBuildConfig(input_proto)
Alex Klein56355682019-02-07 10:36:54 -0700176
177 # Sorted isn't really necessary here, but it's much easier to test.
Jack Neus761e1842020-12-01 18:20:11 +0000178 result = image.Build(
179 board=board, images=sorted(list(image_types)), config=build_config)
Alex Klein56355682019-02-07 10:36:54 -0700180
Alex Klein1bcd9882019-03-19 13:25:24 -0600181 output_proto.success = result.success
Will Bradley29a49c22019-10-21 11:50:08 -0600182
Alex Klein1bcd9882019-03-19 13:25:24 -0600183 if result.success:
184 # Success -- we need to list out the images we built in the output.
185 _PopulateBuiltImages(board, image_types, output_proto)
Will Bradley29a49c22019-10-21 11:50:08 -0600186
George Engelbrecht9f4f8322021-03-08 12:04:17 -0700187 for vm_type in vm_types:
188 is_test = vm_type in [_TEST_VM_ID, _TEST_GUEST_VM_ID]
189 try:
190 if vm_type in [_BASE_GUEST_VM_ID, _TEST_GUEST_VM_ID]:
191 vm_path = image.CreateGuestVm(board, is_test=is_test)
192 else:
193 vm_path = image.CreateVm(
194 board, disk_layout=build_config.disk_layout, is_test=is_test)
195 except image.ImageToVmError as e:
196 cros_build_lib.Die(e)
Will Bradley29a49c22019-10-21 11:50:08 -0600197
George Engelbrecht9f4f8322021-03-08 12:04:17 -0700198 _add_image_to_proto(output_proto, vm_path, vm_type, board)
199
200 for mod_type in mod_image_types:
201 if mod_type == _RECOVERY_ID:
202 base_image_path = _GetBaseImagePath(output_proto)
Alex Kleincaace392021-07-26 14:28:13 -0600203 result = image.BuildRecoveryImage(
204 board=board, image_path=base_image_path)
George Engelbrecht9f4f8322021-03-08 12:04:17 -0700205 if result.success:
206 _PopulateBuiltImages(board, [_IMAGE_MAPPING[mod_type]], output_proto)
207 else:
208 cros_build_lib.Die('Failed to create recovery image.')
209 else:
210 cros_build_lib.Die('_RECOVERY_ID is the only mod_image_type.')
Will Bradley29a49c22019-10-21 11:50:08 -0600211
212 # Read metric events log and pipe them into output_proto.events.
213 deserialize_metrics_log(output_proto.events, prefix=board)
214 return controller.RETURN_CODE_SUCCESS
215
Alex Klein1bcd9882019-03-19 13:25:24 -0600216 else:
Alex Klein2557b4f2019-07-11 14:34:00 -0600217 # Failure, include all of the failed packages in the output when available.
218 if not result.failed_packages:
219 return controller.RETURN_CODE_COMPLETED_UNSUCCESSFULLY
220
Alex Klein1bcd9882019-03-19 13:25:24 -0600221 for package in result.failed_packages:
222 current = output_proto.failed_packages.add()
Alex Kleine9a7dbf2020-10-06 18:12:12 -0600223 controller_util.serialize_package_info(package, current)
Alex Klein1bcd9882019-03-19 13:25:24 -0600224
Alex Klein8cb365a2019-05-15 16:24:53 -0600225 return controller.RETURN_CODE_UNSUCCESSFUL_RESPONSE_AVAILABLE
Alex Klein1bcd9882019-03-19 13:25:24 -0600226
Alex Kleincaace392021-07-26 14:28:13 -0600227
George Engelbrecht9f4f8322021-03-08 12:04:17 -0700228def _GetBaseImagePath(output_proto):
229 """From image_pb2.CreateImageResult, return base image path or None."""
230 ret = None
231 for i in output_proto.images:
232 if i.type == _BASE_ID:
233 ret = i.path
234 return ret
235
Alex Klein21b95022019-05-09 14:14:46 -0600236
237def _ParseImagesToCreate(to_build):
238 """Helper function to parse the image types to build.
239
George Engelbrecht9f4f8322021-03-08 12:04:17 -0700240 This function expresses the dependencies of each image type and adds
241 the requisite image types if they're not explicitly defined.
Alex Klein21b95022019-05-09 14:14:46 -0600242
243 Args:
244 to_build (list[int]): The image type list.
245
246 Returns:
George Engelbrecht9f4f8322021-03-08 12:04:17 -0700247 (set, set, set): The image, vm, and mod_image types that need to be built.
Alex Klein21b95022019-05-09 14:14:46 -0600248 """
249 image_types = set()
250 vm_types = set()
George Engelbrecht9f4f8322021-03-08 12:04:17 -0700251 mod_image_types = set()
Alex Klein21b95022019-05-09 14:14:46 -0600252 for current in to_build:
George Engelbrecht9f4f8322021-03-08 12:04:17 -0700253 # Find out if it's a special case (vm, img mod), or just any old image.
254 if current in _VM_IMAGE_MAPPING:
Alex Klein21b95022019-05-09 14:14:46 -0600255 vm_types.add(current)
256 # Make sure we build the image required to build the VM.
257 image_types.add(_VM_IMAGE_MAPPING[current])
George Engelbrecht9f4f8322021-03-08 12:04:17 -0700258 elif current in _MOD_IMAGE_MAPPING:
259 mod_image_types.add(current)
260 image_types.add(_MOD_IMAGE_MAPPING[current])
261 elif current in _IMAGE_MAPPING:
262 image_types.add(_IMAGE_MAPPING[current])
Alex Klein21b95022019-05-09 14:14:46 -0600263 else:
264 # Not expected, but at least it will be obvious if this comes up.
265 cros_build_lib.Die(
266 "The service's known image types do not match those in image.proto. "
267 'Unknown Enum ID: %s' % current)
268
Trent Begin008cade2019-10-31 13:40:59 -0600269 # We can only build one type of these images at a time since image_to_vm.sh
270 # uses the default path if a name is not provided.
271 if vm_types.issuperset({_BASE_VM_ID, _TEST_VM_ID}):
Alex Klein21b95022019-05-09 14:14:46 -0600272 cros_build_lib.Die('Cannot create more than one VM.')
273
George Engelbrecht9f4f8322021-03-08 12:04:17 -0700274 return image_types, vm_types, mod_image_types
Alex Klein21b95022019-05-09 14:14:46 -0600275
276
277def _ParseCreateBuildConfig(input_proto):
278 """Helper to parse the image build config for Create."""
279 enable_rootfs_verification = not input_proto.disable_rootfs_verification
280 version = input_proto.version or None
281 disk_layout = input_proto.disk_layout or None
282 builder_path = input_proto.builder_path or None
283 return image.BuildConfig(
Jack Neus761e1842020-12-01 18:20:11 +0000284 enable_rootfs_verification=enable_rootfs_verification,
285 replace=True,
286 version=version,
287 disk_layout=disk_layout,
288 builder_path=builder_path,
Alex Klein21b95022019-05-09 14:14:46 -0600289 )
290
Alex Klein1bcd9882019-03-19 13:25:24 -0600291
292def _PopulateBuiltImages(board, image_types, output_proto):
293 """Helper to list out built images for Create."""
Alex Klein56355682019-02-07 10:36:54 -0700294 # Build out the ImageType->ImagePath mapping in the output.
295 # We're using the default path, so just fetch that, but read the symlink so
296 # the path we're returning is somewhat more permanent.
297 latest_link = image_lib.GetLatestImageLink(board)
Alex Klein4f0eb432019-05-02 13:56:04 -0600298 base_path = os.path.realpath(latest_link)
Alex Klein56355682019-02-07 10:36:54 -0700299
300 for current in image_types:
301 type_id = _IMAGE_MAPPING[current]
302 path = os.path.join(base_path, constants.IMAGE_TYPE_TO_NAME[current])
George Engelbrecht9f4f8322021-03-08 12:04:17 -0700303 _add_image_to_proto(output_proto, path, type_id, board)
Alex Klein4f0eb432019-05-02 13:56:04 -0600304
305
Michael Mortensen10146cf2019-11-19 19:59:22 -0700306def _SignerTestResponse(_input_proto, output_proto, _config):
307 """Set output_proto success field on a successful SignerTest response."""
308 output_proto.success = True
309 return controller.RETURN_CODE_SUCCESS
310
311
312@faux.success(_SignerTestResponse)
Michael Mortensen85d38402019-12-12 09:50:29 -0700313@faux.empty_completed_unsuccessfully_error
Michael Mortensenc83c9952019-08-05 12:15:12 -0600314@validate.exists('image.path')
Alex Klein231d2da2019-07-22 16:44:45 -0600315@validate.validation_complete
316def SignerTest(input_proto, output_proto, _config):
Michael Mortensenc83c9952019-08-05 12:15:12 -0600317 """Run image tests.
318
319 Args:
320 input_proto (image_pb2.ImageTestRequest): The input message.
321 output_proto (image_pb2.ImageTestResult): The output message.
Alex Klein231d2da2019-07-22 16:44:45 -0600322 _config (api_config.ApiConfig): The API call config.
Michael Mortensenc83c9952019-08-05 12:15:12 -0600323 """
Michael Mortensenc83c9952019-08-05 12:15:12 -0600324 image_path = input_proto.image.path
325
Alex Klein231d2da2019-07-22 16:44:45 -0600326 result = image_lib.SecurityTest(image=image_path)
Michael Mortensenc83c9952019-08-05 12:15:12 -0600327 output_proto.success = result
328 if result:
329 return controller.RETURN_CODE_SUCCESS
330 else:
331 return controller.RETURN_CODE_COMPLETED_UNSUCCESSFULLY
332
Alex Klein076841b2019-08-29 15:19:39 -0600333
Michael Mortensen10146cf2019-11-19 19:59:22 -0700334def _TestResponse(_input_proto, output_proto, _config):
335 """Set output_proto success field on a successful Test response."""
336 output_proto.success = True
337 return controller.RETURN_CODE_SUCCESS
338
339
340@faux.success(_TestResponse)
Michael Mortensen85d38402019-12-12 09:50:29 -0700341@faux.empty_completed_unsuccessfully_error
Alex Klein2b236722019-06-19 15:44:26 -0600342@validate.require('build_target.name', 'result.directory')
343@validate.exists('image.path')
Alex Klein231d2da2019-07-22 16:44:45 -0600344def Test(input_proto, output_proto, config):
Alex Klein2966e302019-01-17 13:29:38 -0700345 """Run image tests.
346
347 Args:
348 input_proto (image_pb2.ImageTestRequest): The input message.
349 output_proto (image_pb2.ImageTestResult): The output message.
Alex Klein231d2da2019-07-22 16:44:45 -0600350 config (api_config.ApiConfig): The API call config.
Alex Klein2966e302019-01-17 13:29:38 -0700351 """
352 image_path = input_proto.image.path
353 board = input_proto.build_target.name
354 result_directory = input_proto.result.directory
355
Alex Klein2966e302019-01-17 13:29:38 -0700356 if not os.path.isfile(image_path) or not image_path.endswith('.bin'):
Alex Klein4f0eb432019-05-02 13:56:04 -0600357 cros_build_lib.Die(
Alex Klein2966e302019-01-17 13:29:38 -0700358 'The image.path must be an existing image file with a .bin extension.')
359
Alex Klein231d2da2019-07-22 16:44:45 -0600360 if config.validate_only:
361 return controller.RETURN_CODE_VALID_INPUT
362
Alex Klein8cb365a2019-05-15 16:24:53 -0600363 success = image.Test(board, result_directory, image_dir=image_path)
364 output_proto.success = success
365
366 if success:
367 return controller.RETURN_CODE_SUCCESS
368 else:
369 return controller.RETURN_CODE_COMPLETED_UNSUCCESSFULLY
Jack Neus761e1842020-12-01 18:20:11 +0000370
371
372@faux.empty_success
373@faux.empty_completed_unsuccessfully_error
374@validate.require('gs_image_dir', 'sysroot.build_target.name')
375def PushImage(input_proto, _output_proto, config):
376 """Push artifacts from the archive bucket to the release bucket.
377
378 Wraps chromite/scripts/pushimage.py.
379
380 Args:
381 input_proto (PushImageRequest): Input proto.
382 _output_proto (PushImageResponse): Output proto.
383 config (api.config.ApiConfig): The API call config.
384
385 Returns:
386 A controller return code (e.g. controller.RETURN_CODE_SUCCESS).
387 """
388 sign_types = []
389 if input_proto.sign_types:
390 for sign_type in input_proto.sign_types:
391 if sign_type not in SUPPORTED_IMAGE_TYPES:
392 logging.error('unsupported sign type %g', sign_type)
393 return controller.RETURN_CODE_INVALID_INPUT
394 sign_types.append(SUPPORTED_IMAGE_TYPES[sign_type])
395
396 # If configured for validation only we're done here.
397 if config.validate_only:
398 return controller.RETURN_CODE_VALID_INPUT
399
Jack Neus485a9d22020-12-21 03:15:15 +0000400 kwargs = {}
401 if input_proto.profile.name:
402 kwargs['profile'] = input_proto.profile.name
403 if input_proto.dest_bucket:
404 kwargs['dest_bucket'] = input_proto.dest_bucket
Jack Neus761e1842020-12-01 18:20:11 +0000405 try:
406 pushimage.PushImage(
407 input_proto.gs_image_dir,
408 input_proto.sysroot.build_target.name,
409 dry_run=input_proto.dryrun,
Jack Neus485a9d22020-12-21 03:15:15 +0000410 sign_types=sign_types,
411 **kwargs)
Jack Neus761e1842020-12-01 18:20:11 +0000412 return controller.RETURN_CODE_SUCCESS
413 except Exception:
Jack Neuse3150a42021-01-29 17:16:36 +0000414 logging.error('PushImage failed: ', exc_info=True)
Jack Neus761e1842020-12-01 18:20:11 +0000415 return controller.RETURN_CODE_COMPLETED_UNSUCCESSFULLY