Loading tools/releasetools/add_img_to_target_files.py +2 −2 Original line number Diff line number Diff line Loading @@ -62,7 +62,7 @@ import common import verity_utils import ota_metadata_pb2 from apex_utils import GetSystemApexInfoFromTargetFiles from apex_utils import GetApexInfoFromTargetFiles from common import AddCareMapForAbOta if sys.hexversion < 0x02070000: Loading Loading @@ -686,7 +686,7 @@ def HasPartition(partition_name): "{}.img".format(partition_name)))) def AddApexInfo(output_zip): apex_infos = GetSystemApexInfoFromTargetFiles(OPTIONS.input_tmp) apex_infos = GetApexInfoFromTargetFiles(OPTIONS.input_tmp, 'system') apex_metadata_proto = ota_metadata_pb2.ApexMetadata() apex_metadata_proto.apex_info.extend(apex_infos) apex_info_bytes = apex_metadata_proto.SerializeToString() Loading tools/releasetools/apex_utils.py +6 −3 Original line number Diff line number Diff line Loading @@ -516,7 +516,7 @@ def SignApex(avbtool, apex_data, payload_key, container_key, container_pw, raise ApexInfoError( 'Failed to get type for {}:\n{}'.format(apex_file, e)) def GetSystemApexInfoFromTargetFiles(input_file): def GetApexInfoFromTargetFiles(input_file, partition, compressed_only=True): """ Get information about system APEX stored in the input_file zip Loading @@ -532,15 +532,17 @@ def GetSystemApexInfoFromTargetFiles(input_file): if not isinstance(input_file, str): raise RuntimeError("must pass filepath to target-files zip or directory") apex_subdir = os.path.join(partition.upper(), 'apex') if os.path.isdir(input_file): tmp_dir = input_file else: tmp_dir = UnzipTemp(input_file, ["SYSTEM/apex/*"]) target_dir = os.path.join(tmp_dir, "SYSTEM/apex/") tmp_dir = UnzipTemp(input_file, [os.path.join(apex_subdir, '*')]) target_dir = os.path.join(tmp_dir, apex_subdir) # Partial target-files packages for vendor-only builds may not contain # a system apex directory. if not os.path.exists(target_dir): logger.info('No APEX directory at path: %s', target_dir) return [] apex_infos = [] Loading Loading @@ -585,6 +587,7 @@ def GetSystemApexInfoFromTargetFiles(input_file): '--output', decompressed_file_path]) apex_info.decompressed_size = os.path.getsize(decompressed_file_path) if not compressed_only or apex_info.is_compressed: apex_infos.append(apex_info) return apex_infos tools/releasetools/merge_target_files.py +33 −0 Original line number Diff line number Diff line Loading @@ -96,6 +96,7 @@ import zipfile from xml.etree import ElementTree import add_img_to_target_files import apex_utils import build_image import build_super_image import check_target_files_vintf Loading Loading @@ -739,6 +740,35 @@ def compile_split_sepolicy(product_out, partition_map, output_policy): return cmd def validate_merged_apex_info(output_target_files_dir, partitions): """Validates the APEX files in the merged target files directory. Checks the APEX files in all possible preinstalled APEX directories. Depends on the <partition>/apex/* APEX files within partitions. Args: output_target_files_dir: Output directory containing merged partition directories. partitions: A list of all the partitions in the output directory. Raises: RuntimeError: if apex_utils fails to parse any APEX file. ExternalError: if the same APEX package is provided by multiple partitions. """ apex_packages = set() apex_partitions = ('system', 'system_ext', 'product', 'vendor') for partition in filter(lambda p: p in apex_partitions, partitions): apex_info = apex_utils.GetApexInfoFromTargetFiles( output_target_files_dir, partition, compressed_only=False) partition_apex_packages = set([info.package_name for info in apex_info]) duplicates = apex_packages.intersection(partition_apex_packages) if duplicates: raise ExternalError( 'Duplicate APEX packages found in multiple partitions: %s' % ' '.join(duplicates)) apex_packages.update(partition_apex_packages) def generate_care_map(partitions, output_target_files_dir): """Generates a merged META/care_map.pb file in the output target files dir. Loading Loading @@ -1116,6 +1146,9 @@ def merge_target_files(temp_dir, framework_target_files, framework_item_list, common.RunAndCheckOutput(split_sepolicy_cmd) # TODO(b/178864050): Run tests on the combined.policy file. # Run validation checks on the pre-installed APEX files. validate_merged_apex_info(output_target_files_temp_dir, partition_map.keys()) generate_images(output_target_files_temp_dir, rebuild_recovery) generate_super_empty_image(output_target_files_temp_dir, output_super_empty) Loading tools/releasetools/test_merge_target_files.py +35 −1 Original line number Diff line number Diff line Loading @@ -15,6 +15,7 @@ # import os.path import shutil import common import test_utils Loading @@ -22,7 +23,7 @@ from merge_target_files import ( validate_config_lists, DEFAULT_FRAMEWORK_ITEM_LIST, DEFAULT_VENDOR_ITEM_LIST, DEFAULT_FRAMEWORK_MISC_INFO_KEYS, copy_items, item_list_to_partition_set, process_apex_keys_apk_certs_common, compile_split_sepolicy) compile_split_sepolicy, validate_merged_apex_info) class MergeTargetFilesTest(test_utils.ReleaseToolsTestCase): Loading Loading @@ -274,3 +275,36 @@ class MergeTargetFilesTest(test_utils.ReleaseToolsTestCase): '{OTP}/vendor/etc/selinux/plat_pub_versioned.cil ' '{OTP}/product/etc/selinux/mapping/30.0.cil').format( OTP=product_out_dir)) def _copy_apex(self, source, output_dir, partition): shutil.copy( source, os.path.join(output_dir, partition, 'apex', os.path.basename(source))) @test_utils.SkipIfExternalToolsUnavailable() def test_validate_merged_apex_info(self): output_dir = common.MakeTempDir() os.makedirs(os.path.join(output_dir, 'SYSTEM/apex')) os.makedirs(os.path.join(output_dir, 'VENDOR/apex')) self._copy_apex( os.path.join(self.testdata_dir, 'has_apk.apex'), output_dir, 'SYSTEM') self._copy_apex( os.path.join(test_utils.get_current_dir(), 'com.android.apex.compressed.v1.capex'), output_dir, 'VENDOR') validate_merged_apex_info(output_dir, ('system', 'vendor')) @test_utils.SkipIfExternalToolsUnavailable() def test_validate_merged_apex_info_RaisesOnPackageInMultiplePartitions(self): output_dir = common.MakeTempDir() os.makedirs(os.path.join(output_dir, 'SYSTEM/apex')) os.makedirs(os.path.join(output_dir, 'VENDOR/apex')) same_apex_package = os.path.join(self.testdata_dir, 'has_apk.apex') self._copy_apex(same_apex_package, output_dir, 'SYSTEM') self._copy_apex(same_apex_package, output_dir, 'VENDOR') self.assertRaisesRegexp( common.ExternalError, 'Duplicate APEX packages found in multiple partitions: com.android.wifi', validate_merged_apex_info, output_dir, ('system', 'vendor')) tools/releasetools/test_ota_from_target_files.py +3 −3 Original line number Diff line number Diff line Loading @@ -33,7 +33,7 @@ from ota_from_target_files import ( GetTargetFilesZipWithoutPostinstallConfig, Payload, PayloadSigner, POSTINSTALL_CONFIG, StreamingPropertyFiles, AB_PARTITIONS) from apex_utils import GetSystemApexInfoFromTargetFiles from apex_utils import GetApexInfoFromTargetFiles from test_utils import PropertyFilesTestCase Loading Loading @@ -281,9 +281,9 @@ class OtaFromTargetFilesTest(test_utils.ReleaseToolsTestCase): metadata) @test_utils.SkipIfExternalToolsUnavailable() def test_GetSystemApexInfoFromTargetFiles(self): def test_GetApexInfoFromTargetFiles(self): target_files = construct_target_files(compressedApex=True) apex_infos = GetSystemApexInfoFromTargetFiles(target_files) apex_infos = GetApexInfoFromTargetFiles(target_files, 'system') self.assertEqual(len(apex_infos), 1) self.assertEqual(apex_infos[0].package_name, "com.android.apex.compressed") self.assertEqual(apex_infos[0].version, 1) Loading Loading
tools/releasetools/add_img_to_target_files.py +2 −2 Original line number Diff line number Diff line Loading @@ -62,7 +62,7 @@ import common import verity_utils import ota_metadata_pb2 from apex_utils import GetSystemApexInfoFromTargetFiles from apex_utils import GetApexInfoFromTargetFiles from common import AddCareMapForAbOta if sys.hexversion < 0x02070000: Loading Loading @@ -686,7 +686,7 @@ def HasPartition(partition_name): "{}.img".format(partition_name)))) def AddApexInfo(output_zip): apex_infos = GetSystemApexInfoFromTargetFiles(OPTIONS.input_tmp) apex_infos = GetApexInfoFromTargetFiles(OPTIONS.input_tmp, 'system') apex_metadata_proto = ota_metadata_pb2.ApexMetadata() apex_metadata_proto.apex_info.extend(apex_infos) apex_info_bytes = apex_metadata_proto.SerializeToString() Loading
tools/releasetools/apex_utils.py +6 −3 Original line number Diff line number Diff line Loading @@ -516,7 +516,7 @@ def SignApex(avbtool, apex_data, payload_key, container_key, container_pw, raise ApexInfoError( 'Failed to get type for {}:\n{}'.format(apex_file, e)) def GetSystemApexInfoFromTargetFiles(input_file): def GetApexInfoFromTargetFiles(input_file, partition, compressed_only=True): """ Get information about system APEX stored in the input_file zip Loading @@ -532,15 +532,17 @@ def GetSystemApexInfoFromTargetFiles(input_file): if not isinstance(input_file, str): raise RuntimeError("must pass filepath to target-files zip or directory") apex_subdir = os.path.join(partition.upper(), 'apex') if os.path.isdir(input_file): tmp_dir = input_file else: tmp_dir = UnzipTemp(input_file, ["SYSTEM/apex/*"]) target_dir = os.path.join(tmp_dir, "SYSTEM/apex/") tmp_dir = UnzipTemp(input_file, [os.path.join(apex_subdir, '*')]) target_dir = os.path.join(tmp_dir, apex_subdir) # Partial target-files packages for vendor-only builds may not contain # a system apex directory. if not os.path.exists(target_dir): logger.info('No APEX directory at path: %s', target_dir) return [] apex_infos = [] Loading Loading @@ -585,6 +587,7 @@ def GetSystemApexInfoFromTargetFiles(input_file): '--output', decompressed_file_path]) apex_info.decompressed_size = os.path.getsize(decompressed_file_path) if not compressed_only or apex_info.is_compressed: apex_infos.append(apex_info) return apex_infos
tools/releasetools/merge_target_files.py +33 −0 Original line number Diff line number Diff line Loading @@ -96,6 +96,7 @@ import zipfile from xml.etree import ElementTree import add_img_to_target_files import apex_utils import build_image import build_super_image import check_target_files_vintf Loading Loading @@ -739,6 +740,35 @@ def compile_split_sepolicy(product_out, partition_map, output_policy): return cmd def validate_merged_apex_info(output_target_files_dir, partitions): """Validates the APEX files in the merged target files directory. Checks the APEX files in all possible preinstalled APEX directories. Depends on the <partition>/apex/* APEX files within partitions. Args: output_target_files_dir: Output directory containing merged partition directories. partitions: A list of all the partitions in the output directory. Raises: RuntimeError: if apex_utils fails to parse any APEX file. ExternalError: if the same APEX package is provided by multiple partitions. """ apex_packages = set() apex_partitions = ('system', 'system_ext', 'product', 'vendor') for partition in filter(lambda p: p in apex_partitions, partitions): apex_info = apex_utils.GetApexInfoFromTargetFiles( output_target_files_dir, partition, compressed_only=False) partition_apex_packages = set([info.package_name for info in apex_info]) duplicates = apex_packages.intersection(partition_apex_packages) if duplicates: raise ExternalError( 'Duplicate APEX packages found in multiple partitions: %s' % ' '.join(duplicates)) apex_packages.update(partition_apex_packages) def generate_care_map(partitions, output_target_files_dir): """Generates a merged META/care_map.pb file in the output target files dir. Loading Loading @@ -1116,6 +1146,9 @@ def merge_target_files(temp_dir, framework_target_files, framework_item_list, common.RunAndCheckOutput(split_sepolicy_cmd) # TODO(b/178864050): Run tests on the combined.policy file. # Run validation checks on the pre-installed APEX files. validate_merged_apex_info(output_target_files_temp_dir, partition_map.keys()) generate_images(output_target_files_temp_dir, rebuild_recovery) generate_super_empty_image(output_target_files_temp_dir, output_super_empty) Loading
tools/releasetools/test_merge_target_files.py +35 −1 Original line number Diff line number Diff line Loading @@ -15,6 +15,7 @@ # import os.path import shutil import common import test_utils Loading @@ -22,7 +23,7 @@ from merge_target_files import ( validate_config_lists, DEFAULT_FRAMEWORK_ITEM_LIST, DEFAULT_VENDOR_ITEM_LIST, DEFAULT_FRAMEWORK_MISC_INFO_KEYS, copy_items, item_list_to_partition_set, process_apex_keys_apk_certs_common, compile_split_sepolicy) compile_split_sepolicy, validate_merged_apex_info) class MergeTargetFilesTest(test_utils.ReleaseToolsTestCase): Loading Loading @@ -274,3 +275,36 @@ class MergeTargetFilesTest(test_utils.ReleaseToolsTestCase): '{OTP}/vendor/etc/selinux/plat_pub_versioned.cil ' '{OTP}/product/etc/selinux/mapping/30.0.cil').format( OTP=product_out_dir)) def _copy_apex(self, source, output_dir, partition): shutil.copy( source, os.path.join(output_dir, partition, 'apex', os.path.basename(source))) @test_utils.SkipIfExternalToolsUnavailable() def test_validate_merged_apex_info(self): output_dir = common.MakeTempDir() os.makedirs(os.path.join(output_dir, 'SYSTEM/apex')) os.makedirs(os.path.join(output_dir, 'VENDOR/apex')) self._copy_apex( os.path.join(self.testdata_dir, 'has_apk.apex'), output_dir, 'SYSTEM') self._copy_apex( os.path.join(test_utils.get_current_dir(), 'com.android.apex.compressed.v1.capex'), output_dir, 'VENDOR') validate_merged_apex_info(output_dir, ('system', 'vendor')) @test_utils.SkipIfExternalToolsUnavailable() def test_validate_merged_apex_info_RaisesOnPackageInMultiplePartitions(self): output_dir = common.MakeTempDir() os.makedirs(os.path.join(output_dir, 'SYSTEM/apex')) os.makedirs(os.path.join(output_dir, 'VENDOR/apex')) same_apex_package = os.path.join(self.testdata_dir, 'has_apk.apex') self._copy_apex(same_apex_package, output_dir, 'SYSTEM') self._copy_apex(same_apex_package, output_dir, 'VENDOR') self.assertRaisesRegexp( common.ExternalError, 'Duplicate APEX packages found in multiple partitions: com.android.wifi', validate_merged_apex_info, output_dir, ('system', 'vendor'))
tools/releasetools/test_ota_from_target_files.py +3 −3 Original line number Diff line number Diff line Loading @@ -33,7 +33,7 @@ from ota_from_target_files import ( GetTargetFilesZipWithoutPostinstallConfig, Payload, PayloadSigner, POSTINSTALL_CONFIG, StreamingPropertyFiles, AB_PARTITIONS) from apex_utils import GetSystemApexInfoFromTargetFiles from apex_utils import GetApexInfoFromTargetFiles from test_utils import PropertyFilesTestCase Loading Loading @@ -281,9 +281,9 @@ class OtaFromTargetFilesTest(test_utils.ReleaseToolsTestCase): metadata) @test_utils.SkipIfExternalToolsUnavailable() def test_GetSystemApexInfoFromTargetFiles(self): def test_GetApexInfoFromTargetFiles(self): target_files = construct_target_files(compressedApex=True) apex_infos = GetSystemApexInfoFromTargetFiles(target_files) apex_infos = GetApexInfoFromTargetFiles(target_files, 'system') self.assertEqual(len(apex_infos), 1) self.assertEqual(apex_infos[0].package_name, "com.android.apex.compressed") self.assertEqual(apex_infos[0].version, 1) Loading