pushimage: add support for handling base image

'pushimage' currently assumes the image to be signed is of 'recovery' type
if no type was specified.  It can handle firmware and factory image
types if the corresponding instructions files are present.

With this change, pushimage can handle 'base' image type.  Specifically, it
copies base images to signers and flags them for singing if the
'base' image type is specified via '--sign-types' commandline flag.

This change does not change the default behavior when '--sign-types' is
not specified at commandline.

BUG=chromium:512940
TEST=unittests and trybots
CQ-DEPEND=CL:*226855

Change-Id: Ide4befb61354d2880350fa562dd91530986599d8
Reviewed-on: https://chromium-review.googlesource.com/292987
Commit-Ready: Amey Deshpande <ameyd@google.com>
Tested-by: Amey Deshpande <ameyd@google.com>
Reviewed-by: Mike Frysinger <vapier@chromium.org>
diff --git a/scripts/pushimage_unittest.py b/scripts/pushimage_unittest.py
index 1dd7c4a..44caf6f 100644
--- a/scripts/pushimage_unittest.py
+++ b/scripts/pushimage_unittest.py
@@ -195,12 +195,31 @@
              'ChromeOS-recovery-R34-5126.0.0-test.board.instructions')],
     }
 
-    urls = pushimage.PushImage('/src', 'test.board', 'R34-5126.0.0',
-                               sign_types=['recovery'])
+    with mock.patch.object(gs.GSContext, 'Exists', return_value=True):
+      urls = pushimage.PushImage('/src', 'test.board', 'R34-5126.0.0',
+                                 sign_types=['recovery'])
     self.assertEqual(self.gs_mock.call_count, 20)
     self.assertTrue(self.mark_mock.called)
     self.assertEqual(urls, EXPECTED)
 
+  def testSignTypesBase(self):
+    """Only sign the requested recovery type"""
+    EXPECTED = {
+        'canary': [
+            ('gs://chromeos-releases/canary-channel/test.board/5126.0.0/'
+             'ChromeOS-base-R34-5126.0.0-test.board.instructions')],
+        'dev': [
+            ('gs://chromeos-releases/dev-channel/test.board/5126.0.0/'
+             'ChromeOS-base-R34-5126.0.0-test.board.instructions')],
+    }
+
+    with mock.patch.object(gs.GSContext, 'Exists', return_value=True):
+      urls = pushimage.PushImage('/src', 'test.board', 'R34-5126.0.0',
+                                 sign_types=['base'])
+    self.assertEqual(self.gs_mock.call_count, 22)
+    self.assertTrue(self.mark_mock.called)
+    self.assertEqual(urls, EXPECTED)
+
   def testSignTypesNone(self):
     """Verify nothing is signed when we request an unavailable type"""
     urls = pushimage.PushImage('/src', 'test.board', 'R34-5126.0.0',