image service: generate recovery images

Add the ability to generate recovery images via the same Create
endpoint. This adds a bit of management around ensuring that
dependent image types (base) are also generated.

BUG=b:181231500
TEST=./run_tests.py

Change-Id: I0e5c9203987bc3e983db3e820aafc40fa6b50c72
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/chromite/+/2743542
Reviewed-by: Alex Klein <saklein@chromium.org>
Commit-Queue: George Engelbrecht <engeg@google.com>
Tested-by: George Engelbrecht <engeg@google.com>
diff --git a/api/controller/image_unittest.py b/api/controller/image_unittest.py
index 6fabccf..478e07c 100644
--- a/api/controller/image_unittest.py
+++ b/api/controller/image_unittest.py
@@ -121,6 +121,21 @@
     build_patch.assert_called_with(
         images=expected_images, board='board', config=mock.ANY)
 
+  def testRecoveryImpliedTypes(self):
+    """Test implied type handling of recovery images."""
+    # The TEST_VM type should force it to build the test image.
+    types = [common_pb2.IMAGE_TYPE_RECOVERY]
+
+    request = self._GetRequest(board='board', types=types)
+
+    # Failed result to avoid the success handling logic.
+    result = image_service.BuildResult(1, [])
+    build_patch = self.PatchObject(image_service, 'Build', return_value=result)
+
+    image_controller.Create(request, self.response, self.api_config)
+    build_patch.assert_called_with(
+        images=[constants.IMAGE_TYPE_BASE], board='board', config=mock.ANY)
+
   def testFailedPackageHandling(self):
     """Test failed packages are populated correctly."""
     result = image_service.BuildResult(1, ['foo/bar', 'cat/pkg'])