From a1094e9f0c9ef4694104b849de4ed98fbecee1ee Mon Sep 17 00:00:00 2001 From: Daniel Norman Date: Thu, 29 Jul 2021 17:04:40 -0700 Subject: [PATCH] Rebuild vendor images in sign_target_files_apks with vendor otatools. This is needed until image compilation tooling is backwards compatible. Bug: 188491126 Bug: 192253131 Bug: 192422274 Test: Sign a GRF R+S merged target_files package using: sign_target_files_apks \ --vendor_otatools= \ --vendor_partitions=vendor,odm,vbmeta \ merged-target_files.zip \ signed-target_files.zip Change-Id: Iec208f544b56f8ed577344d8d6ca904773d8baab --- tools/releasetools/add_img_to_target_files.py | 121 +++++++++--------- tools/releasetools/sign_target_files_apks.py | 28 +++- 2 files changed, 85 insertions(+), 64 deletions(-) diff --git a/tools/releasetools/add_img_to_target_files.py b/tools/releasetools/add_img_to_target_files.py index f3b58f87af..5275087f60 100644 --- a/tools/releasetools/add_img_to_target_files.py +++ b/tools/releasetools/add_img_to_target_files.py @@ -42,6 +42,10 @@ Usage: add_img_to_target_files [flag] target_files --is_signing Skip building & adding the images for "userdata" and "cache" if we are signing the target files. + + --skip_list + Optional comma-separated list of partitions to skip when + processing the zipfile. """ from __future__ import print_function @@ -78,6 +82,7 @@ OPTIONS.replace_updated_files_list = [] OPTIONS.replace_verity_public_key = False OPTIONS.replace_verity_private_key = False OPTIONS.is_signing = False +OPTIONS.skip_list = [] # Use a fixed timestamp (01/01/2009 00:00:00 UTC) for files when packaging # images. (b/24377993, b/80600931) @@ -589,7 +594,7 @@ def CheckAbOtaImages(output_zip, ab_partitions): AssertionError: If it can't find an image. """ for partition in ab_partitions: - img_name = partition.strip() + ".img" + img_name = partition + ".img" # Assert that the image is present under IMAGES/ now. if output_zip: @@ -796,7 +801,7 @@ def AddImagesToTargetFiles(filename): logger.info("\n\n++++ %s ++++\n\n", s) boot_image = None - if has_boot: + if has_boot and "boot" not in OPTIONS.skip_list: banner("boot") boot_images = OPTIONS.info_dict.get("boot_images") if boot_images is None: @@ -817,7 +822,7 @@ def AddImagesToTargetFiles(filename): if output_zip: boot_image.AddToZip(output_zip) - if has_vendor_boot: + if has_vendor_boot and "vendor_boot" not in OPTIONS.skip_list: banner("vendor_boot") vendor_boot_image = common.GetVendorBootImage( "IMAGES/vendor_boot.img", "vendor_boot.img", OPTIONS.input_tmp, @@ -831,7 +836,7 @@ def AddImagesToTargetFiles(filename): vendor_boot_image.AddToZip(output_zip) recovery_image = None - if has_recovery: + if has_recovery and "recovery" not in OPTIONS.skip_list: banner("recovery") recovery_image = common.GetBootableImage( "IMAGES/recovery.img", "recovery.img", OPTIONS.input_tmp, "RECOVERY") @@ -856,59 +861,39 @@ def AddImagesToTargetFiles(filename): if output_zip: recovery_two_step_image.AddToZip(output_zip) - if has_system: - banner("system") - partitions['system'] = AddSystem( - output_zip, recovery_img=recovery_image, boot_img=boot_image) + def add_partition(call): + partition, has_partition, add_func, add_args = call + if has_partition and partition not in OPTIONS.skip_list: + banner(partition) + partitions[partition] = add_func(output_zip, *add_args) - if has_vendor: - banner("vendor") - partitions['vendor'] = AddVendor( - output_zip, recovery_img=recovery_image, boot_img=boot_image) - - if has_product: - banner("product") - partitions['product'] = AddProduct(output_zip) - - if has_system_ext: - banner("system_ext") - partitions['system_ext'] = AddSystemExt(output_zip) - - if has_odm: - banner("odm") - partitions['odm'] = AddOdm(output_zip) - - if has_vendor_dlkm: - banner("vendor_dlkm") - partitions['vendor_dlkm'] = AddVendorDlkm(output_zip) - - if has_odm_dlkm: - banner("odm_dlkm") - partitions['odm_dlkm'] = AddOdmDlkm(output_zip) - - if has_system_other: - banner("system_other") - AddSystemOther(output_zip) + add_partition_calls = ( + ("system", has_system, AddSystem, [recovery_image, boot_image]), + ("vendor", has_vendor, AddVendor, [recovery_image, boot_image]), + ("product", has_product, AddProduct, []), + ("system_ext", has_system_ext, AddSystemExt, []), + ("odm", has_odm, AddOdm, []), + ("vendor_dlkm", has_vendor_dlkm, AddVendorDlkm, []), + ("odm_dlkm", has_odm_dlkm, AddOdmDlkm, []), + ("system_other", has_system_other, AddSystemOther, []), + ) + for call in add_partition_calls: + add_partition(call) AddApexInfo(output_zip) if not OPTIONS.is_signing: - banner("userdata") - AddUserdata(output_zip) - banner("cache") - AddCache(output_zip) + add_partition(("userdata", True, AddUserdata, [])) + add_partition(("cache", True, AddUserdata, [])) if OPTIONS.info_dict.get("board_bpt_enable") == "true": banner("partition-table") AddPartitionTable(output_zip) - if OPTIONS.info_dict.get("has_dtbo") == "true": - banner("dtbo") - partitions['dtbo'] = AddDtbo(output_zip) - - if OPTIONS.info_dict.get("has_pvmfw") == "true": - banner("pvmfw") - partitions['pvmfw'] = AddPvmfw(output_zip) + add_partition( + ("dtbo", OPTIONS.info_dict.get("has_dtbo") == "true", AddDtbo, [])) + add_partition( + ("pvmfw", OPTIONS.info_dict.get("has_pvmfw") == "true", AddPvmfw, [])) # Custom images. custom_partitions = OPTIONS.info_dict.get( @@ -926,7 +911,7 @@ def AddImagesToTargetFiles(filename): vbmeta_partitions = common.AVB_PARTITIONS[:] + tuple(custom_partitions) vbmeta_system = OPTIONS.info_dict.get("avb_vbmeta_system", "").strip() - if vbmeta_system: + if vbmeta_system and "vbmeta_system" not in OPTIONS.skip_list: banner("vbmeta_system") partitions["vbmeta_system"] = AddVBMeta( output_zip, partitions, "vbmeta_system", vbmeta_system.split()) @@ -936,7 +921,7 @@ def AddImagesToTargetFiles(filename): vbmeta_partitions.append("vbmeta_system") vbmeta_vendor = OPTIONS.info_dict.get("avb_vbmeta_vendor", "").strip() - if vbmeta_vendor: + if vbmeta_vendor and "vbmeta_vendor" not in OPTIONS.skip_list: banner("vbmeta_vendor") partitions["vbmeta_vendor"] = AddVBMeta( output_zip, partitions, "vbmeta_vendor", vbmeta_vendor.split()) @@ -945,16 +930,20 @@ def AddImagesToTargetFiles(filename): if item not in vbmeta_vendor.split()] vbmeta_partitions.append("vbmeta_vendor") - if OPTIONS.info_dict.get("avb_building_vbmeta_image") == "true": + if OPTIONS.info_dict.get("avb_building_vbmeta_image" + ) == "true" and "vbmeta" not in OPTIONS.skip_list: banner("vbmeta") AddVBMeta(output_zip, partitions, "vbmeta", vbmeta_partitions) if OPTIONS.info_dict.get("use_dynamic_partitions") == "true": - if OPTIONS.info_dict.get("build_super_empty_partition") == "true": + if OPTIONS.info_dict.get( + "build_super_empty_partition" + ) == "true" and "super_empty" not in OPTIONS.skip_list: banner("super_empty") AddSuperEmpty(output_zip) - if OPTIONS.info_dict.get("build_super_partition") == "true": + if OPTIONS.info_dict.get( + "build_super_partition") == "true" and "super" not in OPTIONS.skip_list: if OPTIONS.info_dict.get( "build_retrofit_dynamic_partitions_ota_package") == "true": banner("super split images") @@ -965,17 +954,20 @@ def AddImagesToTargetFiles(filename): "ab_partitions.txt") if os.path.exists(ab_partitions_txt): with open(ab_partitions_txt) as f: - ab_partitions = f.readlines() + ab_partitions = f.read().splitlines() - # For devices using A/B update, make sure we have all the needed images - # ready under IMAGES/ or RADIO/. - CheckAbOtaImages(output_zip, ab_partitions) + # Skip care_map generation if any A/B partitions are in the skip list, + # since this file cannot be generated without those partitions. + if not set(ab_partitions).intersection(set(OPTIONS.skip_list)): + # For devices using A/B update, make sure we have all the needed images + # ready under IMAGES/ or RADIO/. + CheckAbOtaImages(output_zip, ab_partitions) - # Generate care_map.pb for ab_partitions, then write this file to - # target_files package. - output_care_map = os.path.join(OPTIONS.input_tmp, "META", "care_map.pb") - AddCareMapForAbOta(output_zip if output_zip else output_care_map, - ab_partitions, partitions) + # Generate care_map.pb for ab_partitions, then write this file to + # target_files package. + output_care_map = os.path.join(OPTIONS.input_tmp, "META", "care_map.pb") + AddCareMapForAbOta(output_zip if output_zip else output_care_map, + ab_partitions, partitions) # Radio images that need to be packed into IMAGES/, and product-img.zip. pack_radioimages_txt = os.path.join( @@ -984,7 +976,8 @@ def AddImagesToTargetFiles(filename): with open(pack_radioimages_txt) as f: AddPackRadioImages(output_zip, f.readlines()) - AddVbmetaDigest(output_zip) + if "vbmeta" not in OPTIONS.skip_list: + AddVbmetaDigest(output_zip) if output_zip: common.ZipClose(output_zip) @@ -1005,6 +998,8 @@ def main(argv): OPTIONS.replace_verity_public_key = (True, a) elif o == "--is_signing": OPTIONS.is_signing = True + elif o == "--skip_list": + OPTIONS.skip_list = a.split(',') else: return False return True @@ -1014,7 +1009,7 @@ def main(argv): extra_long_opts=["add_missing", "rebuild_recovery", "replace_verity_public_key=", "replace_verity_private_key=", - "is_signing"], + "is_signing","skip_list="], extra_option_handler=option_handler) if len(args) != 1: diff --git a/tools/releasetools/sign_target_files_apks.py b/tools/releasetools/sign_target_files_apks.py index 0842af9018..47703bb785 100755 --- a/tools/releasetools/sign_target_files_apks.py +++ b/tools/releasetools/sign_target_files_apks.py @@ -189,6 +189,8 @@ OPTIONS.gki_signing_key = None OPTIONS.gki_signing_algorithm = None OPTIONS.gki_signing_extra_args = None OPTIONS.android_jar_path = None +OPTIONS.vendor_partitions = [] +OPTIONS.vendor_otatools = None AVB_FOOTER_ARGS_BY_PARTITION = { @@ -1289,6 +1291,10 @@ def main(argv): OPTIONS.gki_signing_algorithm = a elif o == "--gki_signing_extra_args": OPTIONS.gki_signing_extra_args = a + elif o == "--vendor_otatools": + OPTIONS.vendor_otatools = a + elif o == "--vendor_partitions": + OPTIONS.vendor_partitions = a.split(",") else: return False return True @@ -1339,6 +1345,8 @@ def main(argv): "gki_signing_key=", "gki_signing_algorithm=", "gki_signing_extra_args=", + "vendor_partitions=", + "vendor_otatools=", ], extra_option_handler=option_handler) @@ -1385,7 +1393,12 @@ def main(argv): common.ZipClose(output_zip) # Skip building userdata.img and cache.img when signing the target files. - new_args = ["--is_signing"] + new_args = ["--is_signing", "--verbose"] + if OPTIONS.vendor_partitions: + new_args += [ + "--skip_list", + ','.join(OPTIONS.vendor_partitions), + ] # add_img_to_target_files builds the system image from scratch, so the # recovery patch is guaranteed to be regenerated there. if OPTIONS.rebuild_recovery: @@ -1393,6 +1406,19 @@ def main(argv): new_args.append(args[1]) add_img_to_target_files.main(new_args) + # Rebuild the vendor partitions using vendor_otatools. + # TODO(b/192253131): Remove the need for image compilation with vendor_otatools + if OPTIONS.vendor_partitions and OPTIONS.vendor_otatools: + vendor_otatools_dir = common.MakeTempDir(prefix="vendor_otatools_") + common.UnzipToDir(OPTIONS.vendor_otatools, vendor_otatools_dir) + cmd = [ + os.path.join(vendor_otatools_dir, "bin", "add_img_to_target_files"), + "--verbose", + "--add_missing", + args[1], + ] + common.RunAndCheckOutput(cmd, verbose=True) + print("done.")