From 9276cf0226d341927d0a7e682a8db677e25ae5dd Mon Sep 17 00:00:00 2001 From: Yifan Hong Date: Wed, 21 Aug 2019 16:37:04 -0700 Subject: [PATCH] Check VINTF compatibility at OTA generation time. Instead of relying on META/{system,vendor}_{manifest,matrix}.xml and blindly copy compatibility.zip from target files package to OTA package, do a static check on the input target files package before generating the OTA package. META/{system,vendor}_{manifest,matrix} does not contain ODM manifest fragments, which is incorrect. Also, the on-device check of compatibility.zip uses a old libvintf binary on the device, which may not understand the incoming VINTF metadata. This change removes the on-device check. Hence, it removes the requirement of forwards compatibility of libvintf. This behavior can be skipped with --skip-compatibility-check. Test: build OTA package Bug: 139300422 Bug: 131425279 Change-Id: I7fb93be9eb73f578fc05a182c6c9d1f073db2800 --- core/Makefile | 14 --- tools/releasetools/Android.bp | 1 + tools/releasetools/merge_target_files.py | 4 - tools/releasetools/ota_from_target_files.py | 124 ++++---------------- 4 files changed, 24 insertions(+), 119 deletions(-) diff --git a/core/Makefile b/core/Makefile index 6f6eee2eb..f56df1f2c 100644 --- a/core/Makefile +++ b/core/Makefile @@ -4011,10 +4011,6 @@ $(BUILT_TARGET_FILES_PACKAGE): \ $(HOST_OUT_EXECUTABLES)/fs_config \ $(ADD_IMG_TO_TARGET_FILES) \ $(MAKE_RECOVERY_PATCH) \ - $(BUILT_ASSEMBLED_FRAMEWORK_MANIFEST) \ - $(BUILT_ASSEMBLED_VENDOR_MANIFEST) \ - $(BUILT_SYSTEM_MATRIX) \ - $(BUILT_VENDOR_MATRIX) \ $(BUILT_KERNEL_CONFIGS_FILE) \ $(BUILT_KERNEL_VERSION_FILE) \ | $(ACP) @@ -4255,16 +4251,6 @@ ifdef BUILDING_SYSTEM_OTHER_IMAGE $(hide) $(call fs_config,$(zip_root)/SYSTEM_OTHER,system/) > $(zip_root)/META/system_other_filesystem_config.txt endif @# Metadata for compatibility verification. - $(hide) cp $(BUILT_SYSTEM_MATRIX) $(zip_root)/META/system_matrix.xml -ifdef BUILT_ASSEMBLED_FRAMEWORK_MANIFEST - $(hide) cp $(BUILT_ASSEMBLED_FRAMEWORK_MANIFEST) $(zip_root)/META/system_manifest.xml -endif -ifdef BUILT_ASSEMBLED_VENDOR_MANIFEST - $(hide) cp $(BUILT_ASSEMBLED_VENDOR_MANIFEST) $(zip_root)/META/vendor_manifest.xml -endif -ifdef BUILT_VENDOR_MATRIX - $(hide) cp $(BUILT_VENDOR_MATRIX) $(zip_root)/META/vendor_matrix.xml -endif ifdef BUILT_KERNEL_CONFIGS_FILE $(hide) cp $(BUILT_KERNEL_CONFIGS_FILE) $(zip_root)/META/kernel_configs.txt endif diff --git a/tools/releasetools/Android.bp b/tools/releasetools/Android.bp index ef76c52ef..a920ffb13 100644 --- a/tools/releasetools/Android.bp +++ b/tools/releasetools/Android.bp @@ -96,6 +96,7 @@ python_defaults { "target_files_diff.py", ], libs: [ + "releasetools_check_target_files_vintf", "releasetools_common", "releasetools_verity_utils", ], diff --git a/tools/releasetools/merge_target_files.py b/tools/releasetools/merge_target_files.py index b7ed6458a..916c80374 100755 --- a/tools/releasetools/merge_target_files.py +++ b/tools/releasetools/merge_target_files.py @@ -117,8 +117,6 @@ DEFAULT_FRAMEWORK_ITEM_LIST = ( 'META/apkcerts.txt', 'META/filesystem_config.txt', 'META/root_filesystem_config.txt', - 'META/system_manifest.xml', - 'META/system_matrix.xml', 'META/update_engine_config.txt', 'PRODUCT/*', 'ROOT/*', @@ -163,8 +161,6 @@ DEFAULT_VENDOR_ITEM_LIST = ( 'META/otakeys.txt', 'META/releasetools.py', 'META/vendor_filesystem_config.txt', - 'META/vendor_manifest.xml', - 'META/vendor_matrix.xml', 'BOOT/*', 'DATA/*', 'ODM/*', diff --git a/tools/releasetools/ota_from_target_files.py b/tools/releasetools/ota_from_target_files.py index c6c859c85..60b73e798 100755 --- a/tools/releasetools/ota_from_target_files.py +++ b/tools/releasetools/ota_from_target_files.py @@ -72,7 +72,7 @@ Common options that apply to both of non-A/B and A/B OTAs --skip_postinstall is implied. --skip_compatibility_check - Skip adding the compatibility package to the generated OTA package. + Skip checking compatibility of the input target files package. --output_metadata_path Write a copy of the metadata to a separate file. Therefore, users can @@ -189,9 +189,9 @@ import shlex import shutil import struct import sys -import tempfile import zipfile +import check_target_files_vintf import common import edify_generator import verity_utils @@ -723,20 +723,15 @@ def HasPartition(target_files_zip, partition): return False -def HasVendorPartition(target_files_zip): - return HasPartition(target_files_zip, "vendor") +def HasTrebleEnabled(target_files, target_info): + def HasVendorPartition(target_files): + if os.path.isdir(target_files): + return os.path.isdir(os.path.join(target_files, "VENDOR")) + if zipfile.is_zipfile(target_files): + return HasPartition(zipfile.ZipFile(target_files), "vendor") + raise ValueError("Unknown target_files argument") - -def HasProductPartition(target_files_zip): - return HasPartition(target_files_zip, "product") - - -def HasOdmPartition(target_files_zip): - return HasPartition(target_files_zip, "odm") - - -def HasTrebleEnabled(target_files_zip, target_info): - return (HasVendorPartition(target_files_zip) and + return (HasVendorPartition(target_files) and target_info.GetBuildProp("ro.treble.enabled") == "true") @@ -761,74 +756,23 @@ def WriteFingerprintAssertion(script, target_info, source_info): source_info.GetBuildProp("ro.build.thumbprint")) -def AddCompatibilityArchiveIfTrebleEnabled(target_zip, output_zip, target_info, - source_info=None): - """Adds compatibility info into the output zip if it's Treble-enabled target. +def CheckVintfIfTrebleEnabled(target_files, target_info): + """Checks compatibility info of the input target files. - Metadata used for on-device compatibility verification is retrieved from - target_zip then added to compatibility.zip which is added to the output_zip - archive. + Metadata used for compatibility verification is retrieved from target_zip. - Compatibility archive should only be included for devices that have enabled + Compatibility should only be checked for devices that have enabled Treble support. Args: - target_zip: Zip file containing the source files to be included for OTA. - output_zip: Zip file that will be sent for OTA. + target_files: Path to zip file containing the source files to be included + for OTA. Can also be the path to extracted directory. target_info: The BuildInfo instance that holds the target build info. - source_info: The BuildInfo instance that holds the source build info, if - generating an incremental OTA; None otherwise. """ - def AddCompatibilityArchive(framework_updated, device_updated): - """Adds compatibility info based on update status of both sides of Treble - boundary. - - Args: - framework_updated: If True, the system / product image will be updated - and therefore their metadata should be included. - device_updated: If True, the vendor / odm image will be updated and - therefore their metadata should be included. - """ - # Determine what metadata we need. Files are names relative to META/. - compatibility_files = [] - device_metadata = ("vendor_manifest.xml", "vendor_matrix.xml") - framework_metadata = ("system_manifest.xml", "system_matrix.xml") - if device_updated: - compatibility_files += device_metadata - if framework_updated: - compatibility_files += framework_metadata - - # Create new archive. - compatibility_archive = tempfile.NamedTemporaryFile() - compatibility_archive_zip = zipfile.ZipFile( - compatibility_archive, "w", compression=zipfile.ZIP_DEFLATED) - - # Add metadata. - for file_name in compatibility_files: - target_file_name = "META/" + file_name - - if target_file_name in target_zip.namelist(): - data = target_zip.read(target_file_name) - common.ZipWriteStr(compatibility_archive_zip, file_name, data) - - # Ensure files are written before we copy into output_zip. - compatibility_archive_zip.close() - - # Only add the archive if we have any compatibility info. - if compatibility_archive_zip.namelist(): - common.ZipWrite(output_zip, compatibility_archive.name, - arcname="compatibility.zip", - compress_type=zipfile.ZIP_STORED) - - def FingerprintChanged(source_fp, target_fp): - if source_fp is None or target_fp is None: - return True - return source_fp != target_fp - # Will only proceed if the target has enabled the Treble support (as well as # having a /vendor partition). - if not HasTrebleEnabled(target_zip, target_info): + if not HasTrebleEnabled(target_files, target_info): return # Skip adding the compatibility package as a workaround for b/114240221. The @@ -836,28 +780,8 @@ def AddCompatibilityArchiveIfTrebleEnabled(target_zip, output_zip, target_info, if OPTIONS.skip_compatibility_check: return - # Full OTA carries the info for system/vendor/product/odm - if source_info is None: - AddCompatibilityArchive(True, True) - return - - source_fp = source_info.fingerprint - target_fp = target_info.fingerprint - system_updated = source_fp != target_fp - - # other build fingerprints could be possibly blacklisted at build time. For - # such a case, we consider those images being changed. - vendor_updated = FingerprintChanged(source_info.vendor_fingerprint, - target_info.vendor_fingerprint) - product_updated = HasProductPartition(target_zip) and \ - FingerprintChanged(source_info.product_fingerprint, - target_info.product_fingerprint) - odm_updated = HasOdmPartition(target_zip) and \ - FingerprintChanged(source_info.odm_fingerprint, - target_info.odm_fingerprint) - - AddCompatibilityArchive(system_updated or product_updated, - vendor_updated or odm_updated) + if not check_target_files_vintf.CheckVintf(target_files, target_info): + raise RuntimeError("VINTF compatibility check failed") def GetBlockDifferences(target_zip, source_zip, target_info, source_info, @@ -1068,7 +992,7 @@ else if get_stage("%(bcb_dev)s") == "3/3" then progress=progress_dict.get(block_diff.partition), write_verify_script=OPTIONS.verify) - AddCompatibilityArchiveIfTrebleEnabled(input_zip, output_zip, target_info) + CheckVintfIfTrebleEnabled(OPTIONS.input_tmp, target_info) boot_img = common.GetBootableImage( "boot.img", "boot.img", OPTIONS.input_tmp, "BOOT") @@ -1643,8 +1567,7 @@ def WriteBlockIncrementalOTAPackage(target_zip, source_zip, output_file): source_info=source_info, device_specific=device_specific) - AddCompatibilityArchiveIfTrebleEnabled( - target_zip, output_zip, target_info, source_info) + CheckVintfIfTrebleEnabled(OPTIONS.target_tmp, target_info) # Assertions (e.g. device properties check). target_info.WriteDeviceAssertions(script, OPTIONS.oem_no_mount) @@ -2079,11 +2002,10 @@ def GenerateAbOtaPackage(target_file, output_file, source_file=None): else: logger.warning("Cannot find care map file in target_file package") - AddCompatibilityArchiveIfTrebleEnabled( - target_zip, output_zip, target_info, source_info) - common.ZipClose(target_zip) + CheckVintfIfTrebleEnabled(target_file, target_info) + # We haven't written the metadata entry yet, which will be handled in # FinalizeMetadata(). common.ZipClose(output_zip)