Merge changes from topic "apexd_host" am: c269ec3538

Original change: https://android-review.googlesource.com/c/platform/build/+/2639710

Change-Id: Ibf39a1ca5f9ed74b0ff4ca598f6c7e58855497c1
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
Jooyung Han
2023-06-28 18:42:27 +00:00
committed by Automerger Merge Worker
5 changed files with 39 additions and 134 deletions

View File

@@ -4827,25 +4827,24 @@ ifeq (,$(TARGET_BUILD_UNBUNDLED))
intermediates := $(call intermediates-dir-for,PACKAGING,check_vintf_all) intermediates := $(call intermediates-dir-for,PACKAGING,check_vintf_all)
check_vintf_all_deps := check_vintf_all_deps :=
APEX_OUT := $(PRODUCT_OUT)/apex
# ----------------------------------------------------------------- # -----------------------------------------------------------------
# Create apex-info-file.xml # Activate vendor APEXes for checkvintf
apex_dirs := \ apex_dirs := \
$(TARGET_OUT)/apex/% \
$(TARGET_OUT_SYSTEM_EXT)/apex/% \
$(TARGET_OUT_VENDOR)/apex/% \ $(TARGET_OUT_VENDOR)/apex/% \
$(TARGET_OUT_ODM)/apex/% \
$(TARGET_OUT_PRODUCT)/apex/% \
apex_files := $(sort $(filter $(apex_dirs), $(INTERNAL_ALLIMAGES_FILES))) apex_files := $(sort $(filter $(apex_dirs), $(INTERNAL_ALLIMAGES_FILES)))
APEX_OUT := $(intermediates)/apex
APEX_INFO_FILE := $(APEX_OUT)/apex-info-list.xml APEX_INFO_FILE := $(APEX_OUT)/apex-info-list.xml
# dump_apex_info scans $(PRODUCT_OUT)/apex and writes apex-info-list.xml there. # apexd_host scans/activates APEX files and writes /apex/apex-info-list.xml
# This relies on the fact that rules for .apex files install the contents in $(PRODUCT_OUT)/apex. $(APEX_INFO_FILE): $(HOST_OUT_EXECUTABLES)/apexd_host $(apex_files)
$(APEX_INFO_FILE): $(HOST_OUT_EXECUTABLES)/dump_apex_info $(apex_files) @echo "Extracting apexes..."
@echo "Creating apex-info-file in $(PRODUCT_OUT) " @rm -rf $(APEX_OUT)
$< --root_dir $(PRODUCT_OUT) @mkdir -p $(APEX_OUT)
$< --vendor_path $(TARGET_OUT_VENDOR) \
--apex_path $(APEX_OUT)
apex_files := apex_files :=
apex_dirs := apex_dirs :=
@@ -5301,7 +5300,6 @@ INTERNAL_OTATOOLS_MODULES += \
apex_compression_tool \ apex_compression_tool \
deapexer \ deapexer \
debugfs_static \ debugfs_static \
dump_apex_info \
fsck.erofs \ fsck.erofs \
make_erofs \ make_erofs \
merge_zips \ merge_zips \

View File

@@ -99,9 +99,8 @@ python_defaults {
"releasetools_common", "releasetools_common",
], ],
required: [ required: [
"apexd_host",
"checkvintf", "checkvintf",
"deapexer",
"dump_apex_info",
], ],
} }

View File

@@ -129,8 +129,9 @@ def CheckVintfFromExtractedTargetFiles(input_tmp, info_dict=None):
dirmap = GetDirmap(input_tmp) dirmap = GetDirmap(input_tmp)
# Simulate apexd from target-files. # Simulate apexd with target-files.
dirmap['/apex'] = PrepareApexDirectory(input_tmp) # add a mapping('/apex' => ${input_tmp}/APEX) to dirmap
PrepareApexDirectory(input_tmp, dirmap)
args_for_skus = GetArgsForSkus(info_dict) args_for_skus = GetArgsForSkus(info_dict)
shipping_api_level_args = GetArgsForShippingApiLevel(info_dict) shipping_api_level_args = GetArgsForShippingApiLevel(info_dict)
@@ -204,7 +205,8 @@ def GetVintfApexUnzipPatterns():
return patterns return patterns
def PrepareApexDirectory(inp):
def PrepareApexDirectory(inp, dirmap):
""" Prepare /apex directory before running checkvintf """ Prepare /apex directory before running checkvintf
Apex binaries do not support dirmaps, in order to use these binaries we Apex binaries do not support dirmaps, in order to use these binaries we
@@ -212,93 +214,25 @@ def PrepareApexDirectory(inp):
expected device locations. expected device locations.
This simulates how apexd activates APEXes. This simulates how apexd activates APEXes.
1. create {inp}/APEX which is treated as a "/" on device. 1. create {inp}/APEX which is treated as a "/apex" on device.
2. copy apexes from target-files to {root}/{partition}/apex. 2. invoke apexd_host with vendor APEXes.
3. mount apexes under {root}/{partition}/apex at {root}/apex.
4. generate info files with dump_apex_info.
We'll get the following layout
{inp}/APEX/apex # Activated APEXes + some info files
{inp}/APEX/system/apex # System APEXes
{inp}/APEX/vendor/apex # Vendor APEXes
...
Args:
inp: path to the directory that contains the extracted target files archive.
Returns:
directory representing /apex on device
""" """
deapexer = 'deapexer' apex_dir = os.path.join(inp, 'APEX')
debugfs_path = 'debugfs' # checkvintf needs /apex dirmap
fsckerofs_path = 'fsck.erofs' dirmap['/apex'] = apex_dir
if OPTIONS.search_path:
debugfs_path = os.path.join(OPTIONS.search_path, 'bin', 'debugfs_static')
deapexer_path = os.path.join(OPTIONS.search_path, 'bin', 'deapexer')
fsckerofs_path = os.path.join(OPTIONS.search_path, 'bin', 'fsck.erofs')
if os.path.isfile(deapexer_path):
deapexer = deapexer_path
def ExtractApexes(path, outp):
# Extract all APEXes found in input path.
logger.info('Extracting APEXs in %s', path)
for f in os.listdir(path):
logger.info(' adding APEX %s', os.path.basename(f))
apex = os.path.join(path, f)
if os.path.isdir(apex) and os.path.isfile(os.path.join(apex, 'apex_manifest.pb')):
info = ParseApexManifest(os.path.join(apex, 'apex_manifest.pb'))
# Flattened APEXes may have symlinks for libs (linked to /system/lib)
# We need to blindly copy them all.
shutil.copytree(apex, os.path.join(outp, info.name), symlinks=True)
elif os.path.isfile(apex) and apex.endswith(('.apex', '.capex')):
cmd = [deapexer,
'--debugfs_path', debugfs_path,
'info',
apex]
info = json.loads(common.RunAndCheckOutput(cmd))
cmd = [deapexer,
'--debugfs_path', debugfs_path,
'--fsckerofs_path', fsckerofs_path,
'extract',
apex,
os.path.join(outp, info['name'])]
common.RunAndCheckOutput(cmd)
else:
logger.info(' .. skipping %s (is it APEX?)', path)
root_dir_name = 'APEX'
root_dir = os.path.join(inp, root_dir_name)
extracted_root = os.path.join(root_dir, 'apex')
# Always create /apex directory for dirmap # Always create /apex directory for dirmap
os.makedirs(extracted_root) os.makedirs(apex_dir)
create_info_file = False # Invoke apexd_host to activate vendor APEXes for checkvintf
apex_host = os.path.join(OPTIONS.search_path, 'bin', 'apexd_host')
cmd = [apex_host, '--tool_path', OPTIONS.search_path]
cmd += ['--apex_path', dirmap['/apex']]
if '/vendor' in dirmap:
cmd += ['--vendor_path', dirmap['/vendor']]
common.RunAndCheckOutput(cmd)
# Loop through search path looking for and processing apex/ directories.
for device_path, target_files_rel_paths in DIR_SEARCH_PATHS.items():
# checkvintf only needs vendor apexes. skip other partitions for efficiency
if device_path not in ['/vendor', '/odm']:
continue
# First, copy VENDOR/apex/foo.apex to APEX/vendor/apex/foo.apex
# Then, extract the contents to APEX/apex/foo/
for target_files_rel_path in target_files_rel_paths:
inp_partition = os.path.join(inp, target_files_rel_path,"apex")
if os.path.exists(inp_partition):
apex_dir = root_dir + os.path.join(device_path + "/apex");
os.makedirs(root_dir + device_path)
shutil.copytree(inp_partition, apex_dir, symlinks=True)
ExtractApexes(apex_dir, extracted_root)
create_info_file = True
if create_info_file:
### Dump apex info files
dump_cmd = ['dump_apex_info', '--root_dir', root_dir]
common.RunAndCheckOutput(dump_cmd)
return extracted_root
def CheckVintfFromTargetFiles(inp, info_dict=None): def CheckVintfFromTargetFiles(inp, info_dict=None):
""" """

View File

@@ -50,6 +50,7 @@ python_binary_host {
"releasetools_ota_from_target_files", "releasetools_ota_from_target_files",
], ],
required: [ required: [
"apexd_host",
"checkvintf", "checkvintf",
"host_init_verifier", "host_init_verifier",
"secilc", "secilc",

View File

@@ -118,39 +118,12 @@ def MergeDexopt(temp_dir, output_target_files_dir):
apex_extract_root_dir = os.path.join(temp_dir, 'apex') apex_extract_root_dir = os.path.join(temp_dir, 'apex')
os.makedirs(apex_extract_root_dir) os.makedirs(apex_extract_root_dir)
# The directory structure for updatable APEXes is:
#
# SYSTEM
# apex
# com.android.adbd.apex
# com.android.appsearch.apex
# com.android.art.apex
# ...
apex_root = os.path.join(output_target_files_dir, 'SYSTEM', 'apex')
for apex in (glob.glob(os.path.join(apex_root, '*.apex')) +
glob.glob(os.path.join(apex_root, '*.capex'))):
logging.info(' apex: %s', apex)
# deapexer is in the same directory as the merge_target_files binary extracted
# from otatools.zip.
apex_json_info = subprocess.check_output(['deapexer', 'info', apex])
logging.info(' info: %s', apex_json_info)
apex_info = json.loads(apex_json_info)
apex_name = apex_info['name']
logging.info(' name: %s', apex_name)
apex_extract_dir = os.path.join(apex_extract_root_dir, apex_name)
os.makedirs(apex_extract_dir)
# deapexer uses debugfs_static/fsck.erofs from otatools.zip.
command = [ command = [
'deapexer', 'apexd_host',
'--debugfs_path', '--system_path',
'debugfs_static', os.path.join(temp_dir, 'system'),
'--fsckerofs_path', '--apex_path',
'fsck.erofs', apex_extract_root_dir,
'extract',
apex,
apex_extract_dir,
] ]
logging.info(' running %s', command) logging.info(' running %s', command)
subprocess.check_call(command) subprocess.check_call(command)