Allow merging target files without framework ab_partitions.txt

Introduce a new option `--allow-partial-ab` in merge_target_files,
which allows merging a non-AB framework with an AB vendor.

The reason for adding this option is to support merging a real
device framework with a cuttlefish vendor. Cuttlefish enables AB
partition by default; however, some real devices do not.

Bug: 318326532
Test: merge_target_files
Test: atest --host releasetools_test
Change-Id: Iaebd06796153fe82fbf56e86fcc8c500b6d60771
This commit is contained in:
Dennis Song
2024-02-01 09:44:14 +00:00
parent dc7efff9f6
commit bc7e0a9f25
2 changed files with 51 additions and 28 deletions

View File

@@ -53,23 +53,31 @@ PARTITION_TAG_PATTERN = re.compile(r'partition="(.*?)"')
MODULE_KEY_PATTERN = re.compile(r'name="(.+)\.(apex|apk)"')
def MergeUpdateEngineConfig(input_metadir1, input_metadir2, merged_meta_dir):
UPDATE_ENGINE_CONFIG_NAME = "update_engine_config.txt"
config1_path = os.path.join(
input_metadir1, UPDATE_ENGINE_CONFIG_NAME)
config2_path = os.path.join(
input_metadir2, UPDATE_ENGINE_CONFIG_NAME)
config1 = ParseUpdateEngineConfig(config1_path)
config2 = ParseUpdateEngineConfig(config2_path)
def MergeUpdateEngineConfig(framework_meta_dir, vendor_meta_dir,
merged_meta_dir):
"""Merges META/update_engine_config.txt.
The output is the configuration for maximum compatibility.
"""
_CONFIG_NAME = 'update_engine_config.txt'
framework_config_path = os.path.join(framework_meta_dir, _CONFIG_NAME)
vendor_config_path = os.path.join(vendor_meta_dir, _CONFIG_NAME)
merged_config_path = os.path.join(merged_meta_dir, _CONFIG_NAME)
if os.path.exists(framework_config_path):
framework_config = ParseUpdateEngineConfig(framework_config_path)
vendor_config = ParseUpdateEngineConfig(vendor_config_path)
# Copy older config to merged target files for maximum compatibility
# update_engine in system partition is from system side, but
# update_engine_sideload in recovery is from vendor side.
if config1 < config2:
shutil.copy(config1_path, os.path.join(
merged_meta_dir, UPDATE_ENGINE_CONFIG_NAME))
if framework_config < vendor_config:
shutil.copy(framework_config_path, merged_config_path)
else:
shutil.copy(config2_path, os.path.join(
merged_meta_dir, UPDATE_ENGINE_CONFIG_NAME))
shutil.copy(vendor_config_path, merged_config_path)
else:
if not OPTIONS.allow_partial_ab:
raise FileNotFoundError(framework_config_path)
shutil.copy(vendor_config_path, merged_config_path)
def MergeMetaFiles(temp_dir, merged_dir, framework_partitions):
@@ -125,8 +133,7 @@ def MergeMetaFiles(temp_dir, merged_dir, framework_partitions):
if OPTIONS.merged_misc_info.get('ab_update') == 'true':
MergeUpdateEngineConfig(
framework_meta_dir,
vendor_meta_dir, merged_meta_dir)
framework_meta_dir, vendor_meta_dir, merged_meta_dir)
# Write the now-finalized OPTIONS.merged_misc_info.
merge_utils.WriteSortedData(
@@ -140,16 +147,24 @@ def MergeAbPartitions(framework_meta_dir, vendor_meta_dir, merged_meta_dir,
The output contains the union of the partition names.
"""
with open(os.path.join(framework_meta_dir, 'ab_partitions.txt')) as f:
framework_ab_partitions = []
framework_ab_config = os.path.join(framework_meta_dir, 'ab_partitions.txt')
if os.path.exists(framework_ab_config):
with open(framework_ab_config) as f:
# Filter out some partitions here to support the case that the
# ab_partitions.txt of framework-target-files has non-framework partitions.
# This case happens when we use a complete merged target files package as
# the framework-target-files.
framework_ab_partitions = [
# ab_partitions.txt of framework-target-files has non-framework
# partitions. This case happens when we use a complete merged target
# files package as the framework-target-files.
framework_ab_partitions.extend([
partition
for partition in f.read().splitlines()
if partition in framework_partitions
]
])
else:
if not OPTIONS.allow_partial_ab:
raise FileNotFoundError(framework_ab_config)
logger.info('Use partial AB because framework ab_partitions.txt does not '
'exist.')
with open(os.path.join(vendor_meta_dir, 'ab_partitions.txt')) as f:
vendor_ab_partitions = f.read().splitlines()

View File

@@ -98,6 +98,10 @@ Usage: merge_target_files [args]
If provided, resolve the conflict AVB rollback index location when
necessary.
--allow-partial-ab
If provided, allow merging non-AB framework target files with AB vendor
target files, which means that only the vendor has AB partitions.
The following only apply when using the VSDK to perform dexopt on vendor apps:
--framework-dexpreopt-config
@@ -154,6 +158,7 @@ OPTIONS.vendor_otatools = None
OPTIONS.rebuild_sepolicy = False
OPTIONS.keep_tmp = False
OPTIONS.avb_resolve_rollback_index_location_conflict = False
OPTIONS.allow_partial_ab = False
OPTIONS.framework_dexpreopt_config = None
OPTIONS.framework_dexpreopt_tools = None
OPTIONS.vendor_dexpreopt_config = None
@@ -576,6 +581,8 @@ def main():
OPTIONS.keep_tmp = True
elif o == '--avb-resolve-rollback-index-location-conflict':
OPTIONS.avb_resolve_rollback_index_location_conflict = True
elif o == '--allow-partial-ab':
OPTIONS.allow_partial_ab = True
elif o == '--framework-dexpreopt-config':
OPTIONS.framework_dexpreopt_config = a
elif o == '--framework-dexpreopt-tools':
@@ -617,6 +624,7 @@ def main():
'rebuild-sepolicy',
'keep-tmp',
'avb-resolve-rollback-index-location-conflict',
'allow-partial-ab',
],
extra_option_handler=option_handler)