ArtifactsService: add endpoint for creating GCE tarball from test image

BUG=b:168762436
TEST=run_tests; \
     api/contrib/gen_call_scripts -b betty-arc-r && \
     api/contrib/call_scripts/artifacts__bundle_gce_tarball; \
     upload image to GCE, launch instance from it

Change-Id: I921df783e3ef1cf86139e65185660ad834e1d467
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/chromite/+/2507306
Tested-by: Shao-Chuan Lee <shaochuan@chromium.org>
Reviewed-by: Michael Mortensen <mmortensen@google.com>
Commit-Queue: Shao-Chuan Lee <shaochuan@chromium.org>
diff --git a/api/controller/artifacts.py b/api/controller/artifacts.py
index 4d0a089..26de0f0 100644
--- a/api/controller/artifacts.py
+++ b/api/controller/artifacts.py
@@ -627,3 +627,32 @@
 
   output_proto.artifacts.add().path = cpe_result.report
   output_proto.artifacts.add().path = cpe_result.warnings
+
+
+def _BundleGceTarballResponse(input_proto, output_proto, _config):
+  """Add artifact tarball to a successful response."""
+  output_proto.artifacts.add().path = os.path.join(input_proto.output_dir,
+                                                   constants.TEST_IMAGE_GCE_TAR)
+
+
+@faux.success(_BundleGceTarballResponse)
+@faux.empty_error
+@validate.require('build_target.name', 'output_dir')
+@validate.exists('output_dir')
+@validate.validation_complete
+def BundleGceTarball(input_proto, output_proto, _config):
+  """Bundle the test image into a tarball suitable for importing into GCE.
+
+  Args:
+    input_proto (BundleRequest): The input proto.
+    output_proto (BundleResponse): The output proto.
+    _config (api_config.ApiConfig): The API call config.
+  """
+  target = input_proto.build_target.name
+  output_dir = input_proto.output_dir
+  image_dir = _GetImageDir(constants.SOURCE_ROOT, target)
+  if image_dir is None:
+    return None
+
+  tarball = artifacts.BundleGceTarball(output_dir, image_dir)
+  output_proto.artifacts.add().path = tarball