ImageService/Create: Implement base_is_recovery
An image named "recovery_image.bin" needs to exist in order for the
Chromebook Recovery Utility, GoldenEye and other tools to discover an
image for a given build target.
This change adds an attribute to the
BuildConfig, base_is_recovery, that when true, skips recovery image
creation and copies the base image to "recovery_image.bin" instead.
BUG=b:229382044
TEST=./run_tests
Change-Id: I622a0a8cb68e032060c978523eb22698dc786ba4
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/chromite/+/3687376
Tested-by: Joseph Sussman <josephsussman@google.com>
Reviewed-by: Chris Gerber <gerb@google.com>
Auto-Submit: Joseph Sussman <josephsussman@google.com>
Commit-Queue: Chris Gerber <gerb@google.com>
diff --git a/api/controller/image_unittest.py b/api/controller/image_unittest.py
index ee63b29..6d31fa9 100644
--- a/api/controller/image_unittest.py
+++ b/api/controller/image_unittest.py
@@ -5,6 +5,7 @@
"""Image service tests."""
import os
+from pathlib import Path
from unittest import mock
from chromite.api import api_config
@@ -33,7 +34,8 @@
types=None,
version=None,
builder_path=None,
- disable_rootfs_verification=False):
+ disable_rootfs_verification=False,
+ base_is_recovery=False):
"""Helper to build a request instance."""
return image_pb2.CreateImageRequest(
build_target={'name': board},
@@ -41,6 +43,7 @@
disable_rootfs_verification=disable_rootfs_verification,
version=version,
builder_path=builder_path,
+ base_is_recovery=base_is_recovery,
)
def testValidateOnly(self):
@@ -166,6 +169,35 @@
rc)
self.assertFalse(self.response.failed_packages)
+ def testBaseIsRecoveryTrue(self):
+ """Test that cp is called."""
+ types = [common_pb2.IMAGE_TYPE_BASE,
+ common_pb2.IMAGE_TYPE_RECOVERY]
+ input_proto = self._GetRequest(board='board', types=types,
+ base_is_recovery=True)
+ # Images must exist to be added to the result.
+ self.PatchObject(Path, 'exists', return_value=True)
+ rc_mock = cros_test_lib.RunCommandMock()
+ rc_mock.SetDefaultCmdResult(returncode=0)
+ with rc_mock:
+ image_controller.Create(input_proto, self.response, self.api_config)
+ rc_mock.assertCommandContains(['cp', mock.ANY, mock.ANY])
+
+ def testBaseIsRecoveryFalse(self):
+ """Test that mod_image_for_recovery.sh is called."""
+ types = [common_pb2.IMAGE_TYPE_BASE,
+ common_pb2.IMAGE_TYPE_RECOVERY]
+ input_proto = self._GetRequest(board='board', types=types,
+ base_is_recovery=False)
+ self.PatchObject(Path, 'exists', return_value=True)
+ rc_mock = cros_test_lib.RunCommandMock()
+ rc_mock.SetDefaultCmdResult(returncode=0)
+ with rc_mock:
+ image_controller.Create(input_proto, self.response, self.api_config)
+ mod_script = os.path.join(constants.CROSUTILS_DIR,
+ 'mod_image_for_recovery.sh')
+ rc_mock.assertCommandContains([mod_script, '--board', 'board', mock.ANY])
+
class ImageSignerTestTest(cros_test_lib.MockTempDirTestCase,
api_config.ApiConfigMixin):