Merge "Calculate the runtime ro.build.id in ota scripts"
This commit is contained in:
@@ -420,8 +420,9 @@ def CreateImage(input_dir, info_dict, what, output_file, block_list=None):
|
|||||||
image_props["block_list"] = block_list.name
|
image_props["block_list"] = block_list.name
|
||||||
|
|
||||||
# Use repeatable ext4 FS UUID and hash_seed UUID (based on partition name and
|
# Use repeatable ext4 FS UUID and hash_seed UUID (based on partition name and
|
||||||
# build fingerprint).
|
# build fingerprint). Also use the legacy build id, because the vbmeta digest
|
||||||
build_info = common.BuildInfo(info_dict)
|
# isn't available at this point.
|
||||||
|
build_info = common.BuildInfo(info_dict, use_legacy_id=True)
|
||||||
uuid_seed = what + "-" + build_info.GetPartitionFingerprint(what)
|
uuid_seed = what + "-" + build_info.GetPartitionFingerprint(what)
|
||||||
image_props["uuid"] = str(uuid.uuid5(uuid.NAMESPACE_URL, uuid_seed))
|
image_props["uuid"] = str(uuid.uuid5(uuid.NAMESPACE_URL, uuid_seed))
|
||||||
hash_seed = "hash_seed-" + uuid_seed
|
hash_seed = "hash_seed-" + uuid_seed
|
||||||
|
@@ -372,7 +372,10 @@ class BuildInfo(object):
|
|||||||
"product", "product_services", "odm", "vendor", "system"]
|
"product", "product_services", "odm", "vendor", "system"]
|
||||||
_RO_PRODUCT_PROPS_DEFAULT_SOURCE_ORDER_LEGACY = []
|
_RO_PRODUCT_PROPS_DEFAULT_SOURCE_ORDER_LEGACY = []
|
||||||
|
|
||||||
def __init__(self, info_dict, oem_dicts=None):
|
# The length of vbmeta digest to append to the fingerprint
|
||||||
|
_VBMETA_DIGEST_SIZE_USED = 8
|
||||||
|
|
||||||
|
def __init__(self, info_dict, oem_dicts=None, use_legacy_id=False):
|
||||||
"""Initializes a BuildInfo instance with the given dicts.
|
"""Initializes a BuildInfo instance with the given dicts.
|
||||||
|
|
||||||
Note that it only wraps up the given dicts, without making copies.
|
Note that it only wraps up the given dicts, without making copies.
|
||||||
@@ -383,6 +386,9 @@ class BuildInfo(object):
|
|||||||
that it always uses the first dict to calculate the fingerprint or the
|
that it always uses the first dict to calculate the fingerprint or the
|
||||||
device name. The rest would be used for asserting OEM properties only
|
device name. The rest would be used for asserting OEM properties only
|
||||||
(e.g. one package can be installed on one of these devices).
|
(e.g. one package can be installed on one of these devices).
|
||||||
|
use_legacy_id: Use the legacy build id to construct the fingerprint. This
|
||||||
|
is used when we need a BuildInfo class, while the vbmeta digest is
|
||||||
|
unavailable.
|
||||||
|
|
||||||
Raises:
|
Raises:
|
||||||
ValueError: On invalid inputs.
|
ValueError: On invalid inputs.
|
||||||
@@ -391,6 +397,7 @@ class BuildInfo(object):
|
|||||||
self.oem_dicts = oem_dicts
|
self.oem_dicts = oem_dicts
|
||||||
|
|
||||||
self._is_ab = info_dict.get("ab_update") == "true"
|
self._is_ab = info_dict.get("ab_update") == "true"
|
||||||
|
self.use_legacy_id = use_legacy_id
|
||||||
|
|
||||||
# Skip _oem_props if oem_dicts is None to use BuildInfo in
|
# Skip _oem_props if oem_dicts is None to use BuildInfo in
|
||||||
# sign_target_files_apks
|
# sign_target_files_apks
|
||||||
@@ -491,6 +498,9 @@ class BuildInfo(object):
|
|||||||
if prop in BuildInfo._RO_PRODUCT_RESOLVE_PROPS:
|
if prop in BuildInfo._RO_PRODUCT_RESOLVE_PROPS:
|
||||||
return self._ResolveRoProductBuildProp(prop)
|
return self._ResolveRoProductBuildProp(prop)
|
||||||
|
|
||||||
|
if prop == "ro.build.id":
|
||||||
|
return self._GetBuildId()
|
||||||
|
|
||||||
prop_val = self._GetRawBuildProp(prop, None)
|
prop_val = self._GetRawBuildProp(prop, None)
|
||||||
if prop_val is not None:
|
if prop_val is not None:
|
||||||
return prop_val
|
return prop_val
|
||||||
@@ -557,6 +567,34 @@ class BuildInfo(object):
|
|||||||
|
|
||||||
return self.GetBuildProp("ro.build.version.release")
|
return self.GetBuildProp("ro.build.version.release")
|
||||||
|
|
||||||
|
def _GetBuildId(self):
|
||||||
|
build_id = self._GetRawBuildProp("ro.build.id", None)
|
||||||
|
if build_id:
|
||||||
|
return build_id
|
||||||
|
|
||||||
|
legacy_build_id = self.GetBuildProp("ro.build.legacy.id")
|
||||||
|
if not legacy_build_id:
|
||||||
|
raise ExternalError("Couldn't find build id in property file")
|
||||||
|
|
||||||
|
if self.use_legacy_id:
|
||||||
|
return legacy_build_id
|
||||||
|
|
||||||
|
# Append the top 8 chars of vbmeta digest to the existing build id. The
|
||||||
|
# logic needs to match the one in init, so that OTA can deliver correctly.
|
||||||
|
avb_enable = self.info_dict.get("avb_enable") == "true"
|
||||||
|
if not avb_enable:
|
||||||
|
raise ExternalError("AVB isn't enabled when using legacy build id")
|
||||||
|
|
||||||
|
vbmeta_digest = self.info_dict.get("vbmeta_digest")
|
||||||
|
if not vbmeta_digest:
|
||||||
|
raise ExternalError("Vbmeta digest isn't provided when using legacy build"
|
||||||
|
" id")
|
||||||
|
if len(vbmeta_digest) < self._VBMETA_DIGEST_SIZE_USED:
|
||||||
|
raise ExternalError("Invalid vbmeta digest " + vbmeta_digest)
|
||||||
|
|
||||||
|
digest_prefix = vbmeta_digest[:self._VBMETA_DIGEST_SIZE_USED]
|
||||||
|
return legacy_build_id + '.' + digest_prefix
|
||||||
|
|
||||||
def _GetPartitionPlatformVersion(self, partition):
|
def _GetPartitionPlatformVersion(self, partition):
|
||||||
try:
|
try:
|
||||||
return self.GetPartitionBuildProp("ro.build.version.release_or_codename",
|
return self.GetPartitionBuildProp("ro.build.version.release_or_codename",
|
||||||
@@ -790,12 +828,19 @@ def LoadInfoDict(input_file, repacking=False):
|
|||||||
# Set up the salt (based on fingerprint) that will be used when adding AVB
|
# Set up the salt (based on fingerprint) that will be used when adding AVB
|
||||||
# hash / hashtree footers.
|
# hash / hashtree footers.
|
||||||
if d.get("avb_enable") == "true":
|
if d.get("avb_enable") == "true":
|
||||||
build_info = BuildInfo(d)
|
build_info = BuildInfo(d, use_legacy_id=True)
|
||||||
for partition in PARTITIONS_WITH_BUILD_PROP:
|
for partition in PARTITIONS_WITH_BUILD_PROP:
|
||||||
fingerprint = build_info.GetPartitionFingerprint(partition)
|
fingerprint = build_info.GetPartitionFingerprint(partition)
|
||||||
if fingerprint:
|
if fingerprint:
|
||||||
d["avb_{}_salt".format(partition)] = sha256(
|
d["avb_{}_salt".format(partition)] = sha256(
|
||||||
fingerprint.encode()).hexdigest()
|
fingerprint.encode()).hexdigest()
|
||||||
|
|
||||||
|
# Set the vbmeta digest if exists
|
||||||
|
try:
|
||||||
|
d["vbmeta_digest"] = read_helper("META/vbmeta_digest.txt").rstrip()
|
||||||
|
except KeyError:
|
||||||
|
pass
|
||||||
|
|
||||||
try:
|
try:
|
||||||
d["ab_partitions"] = read_helper("META/ab_partitions.txt").split("\n")
|
d["ab_partitions"] = read_helper("META/ab_partitions.txt").split("\n")
|
||||||
except KeyError:
|
except KeyError:
|
||||||
@@ -1339,7 +1384,7 @@ def ConstructAftlMakeImageCommands(output_image):
|
|||||||
|
|
||||||
vbmeta_image = MakeTempFile()
|
vbmeta_image = MakeTempFile()
|
||||||
os.rename(output_image, vbmeta_image)
|
os.rename(output_image, vbmeta_image)
|
||||||
build_info = BuildInfo(OPTIONS.info_dict)
|
build_info = BuildInfo(OPTIONS.info_dict, use_legacy_id=True)
|
||||||
version_incremental = build_info.GetBuildProp("ro.build.version.incremental")
|
version_incremental = build_info.GetBuildProp("ro.build.version.incremental")
|
||||||
aftltool = OPTIONS.aftl_tool_path
|
aftltool = OPTIONS.aftl_tool_path
|
||||||
server_argument_list = [OPTIONS.aftl_server, OPTIONS.aftl_key_path]
|
server_argument_list = [OPTIONS.aftl_server, OPTIONS.aftl_key_path]
|
||||||
|
@@ -48,6 +48,22 @@ def get_2gb_string():
|
|||||||
|
|
||||||
class BuildInfoTest(test_utils.ReleaseToolsTestCase):
|
class BuildInfoTest(test_utils.ReleaseToolsTestCase):
|
||||||
|
|
||||||
|
TEST_INFO_FINGERPRINT_DICT = {
|
||||||
|
'build.prop': common.PartitionBuildProps.FromDictionary(
|
||||||
|
'system', {
|
||||||
|
'ro.product.brand': 'product-brand',
|
||||||
|
'ro.product.name': 'product-name',
|
||||||
|
'ro.product.device': 'product-device',
|
||||||
|
'ro.build.version.release': 'version-release',
|
||||||
|
'ro.build.id': 'build-id',
|
||||||
|
'ro.build.version.incremental': 'version-incremental',
|
||||||
|
'ro.build.type': 'build-type',
|
||||||
|
'ro.build.tags': 'build-tags',
|
||||||
|
'ro.build.version.sdk': 30,
|
||||||
|
}
|
||||||
|
),
|
||||||
|
}
|
||||||
|
|
||||||
TEST_INFO_DICT = {
|
TEST_INFO_DICT = {
|
||||||
'build.prop': common.PartitionBuildProps.FromDictionary(
|
'build.prop': common.PartitionBuildProps.FromDictionary(
|
||||||
'system', {
|
'system', {
|
||||||
@@ -202,6 +218,33 @@ class BuildInfoTest(test_utils.ReleaseToolsTestCase):
|
|||||||
'ro.build.fingerprint'] = 'bad\x80fingerprint'
|
'ro.build.fingerprint'] = 'bad\x80fingerprint'
|
||||||
self.assertRaises(ValueError, common.BuildInfo, info_dict, None)
|
self.assertRaises(ValueError, common.BuildInfo, info_dict, None)
|
||||||
|
|
||||||
|
def test_init_goodFingerprint(self):
|
||||||
|
info_dict = copy.deepcopy(self.TEST_INFO_FINGERPRINT_DICT)
|
||||||
|
build_info = common.BuildInfo(info_dict)
|
||||||
|
self.assertEqual(
|
||||||
|
'product-brand/product-name/product-device:version-release/build-id/'
|
||||||
|
'version-incremental:build-type/build-tags', build_info.fingerprint)
|
||||||
|
|
||||||
|
build_props = info_dict['build.prop'].build_props
|
||||||
|
del build_props['ro.build.id']
|
||||||
|
build_props['ro.build.legacy.id'] = 'legacy-build-id'
|
||||||
|
build_info = common.BuildInfo(info_dict, use_legacy_id=True)
|
||||||
|
self.assertEqual(
|
||||||
|
'product-brand/product-name/product-device:version-release/'
|
||||||
|
'legacy-build-id/version-incremental:build-type/build-tags',
|
||||||
|
build_info.fingerprint)
|
||||||
|
|
||||||
|
self.assertRaises(common.ExternalError, common.BuildInfo, info_dict, None,
|
||||||
|
False)
|
||||||
|
|
||||||
|
info_dict['avb_enable'] = 'true'
|
||||||
|
info_dict['vbmeta_digest'] = 'abcde12345'
|
||||||
|
build_info = common.BuildInfo(info_dict, use_legacy_id=False)
|
||||||
|
self.assertEqual(
|
||||||
|
'product-brand/product-name/product-device:version-release/'
|
||||||
|
'legacy-build-id.abcde123/version-incremental:build-type/build-tags',
|
||||||
|
build_info.fingerprint)
|
||||||
|
|
||||||
def test___getitem__(self):
|
def test___getitem__(self):
|
||||||
target_info = common.BuildInfo(self.TEST_INFO_DICT, None)
|
target_info = common.BuildInfo(self.TEST_INFO_DICT, None)
|
||||||
self.assertEqual('value1', target_info['property1'])
|
self.assertEqual('value1', target_info['property1'])
|
||||||
|
Reference in New Issue
Block a user