summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2022-05-23 23:28:37 +0000
committerAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2022-05-23 23:28:37 +0000
commit810ae0d8980afe19c075b31e7bd185cb24656a8b (patch)
tree0f2934b817bee3c4214c428f48148bb202f7ab5d
parent128a20fd6b3fd1ba0eae2e3a3415e08101ef5889 (diff)
parenta444cd384e39b7540d882ab11ffe55e60cc2a8a5 (diff)
downloadapex-810ae0d8980afe19c075b31e7bd185cb24656a8b.tar.gz
Change-Id: Ic0660afa96a52fb1b39ebb115acc4626c95b4f33
-rw-r--r--apexer/apexer.py165
-rwxr-xr-xapexer/runtests.sh9
2 files changed, 40 insertions, 134 deletions
diff --git a/apexer/apexer.py b/apexer/apexer.py
index d2155950..65ea25f3 100644
--- a/apexer/apexer.py
+++ b/apexer/apexer.py
@@ -187,12 +187,6 @@ def ParseArgs(argv):
'Add testOnly=true attribute to application element in '
'AndroidManifest file.')
)
- parser.add_argument(
- '--apex_version_placeholder',
- default = "__APEX_VERSION_PLACEHOLDER__",
- required=False,
- help='Default placeholder string in the APEX directory paths to be' +
- 'replaced with the APEX version code.')
return parser.parse_args(argv)
@@ -352,13 +346,14 @@ def ValidateArgs(args):
return False
if not args.canned_fs_config:
- if build_info is not None:
- with tempfile.NamedTemporaryFile(delete=False) as temp:
- temp.write(build_info.canned_fs_config)
- args.canned_fs_config = temp.name
- else:
- print('Missing --canned_fs_config {config} argument, or a --build_info argument!')
- return False
+ if not args.canned_fs_config:
+ if build_info is not None:
+ with tempfile.NamedTemporaryFile(delete=False) as temp:
+ temp.write(build_info.canned_fs_config)
+ args.canned_fs_config = temp.name
+ else:
+ print('Missing ----canned_fs_config {config} argument, or a --build_info argument!')
+ return False
if not args.target_sdk_version:
if build_info is not None:
@@ -388,18 +383,18 @@ def ValidateArgs(args):
return True
-def GenerateBuildInfo(args, file_contexts, canned_fs_config, android_manifest):
+def GenerateBuildInfo(args):
build_info = apex_build_info_pb2.ApexBuildInfo()
if (args.include_cmd_line_in_build_info):
build_info.apexer_command_line = str(sys.argv)
- with open(file_contexts, 'rb') as f:
+ with open(args.file_contexts, 'rb') as f:
build_info.file_contexts = f.read()
- with open(canned_fs_config, 'rb') as f:
+ with open(args.canned_fs_config, 'rb') as f:
build_info.canned_fs_config = f.read()
- with open(android_manifest, 'rb') as f:
+ with open(args.android_manifest, 'rb') as f:
build_info.android_manifest = f.read()
if args.target_sdk_version:
@@ -485,7 +480,7 @@ def ShaHashFiles(file_paths):
return h.hexdigest()
-def CreateImageExt4(args, staging_input_dir, work_dir, manifests_dir, img_file, canned_fs_config):
+def CreateImageExt4(args, work_dir, manifests_dir, img_file):
"""Create image for ext4 file system."""
lost_found_location = os.path.join(args.input_dir, 'lost+found')
@@ -494,16 +489,16 @@ def CreateImageExt4(args, staging_input_dir, work_dir, manifests_dir, img_file,
'has been known to cause non-deterministic apex builds.')
# sufficiently big = size + 16MB margin
- size_in_mb = (GetDirSize(staging_input_dir) // (1024 * 1024))
+ size_in_mb = (GetDirSize(args.input_dir) // (1024 * 1024))
size_in_mb += 16
- # Margin is for files that are not under staging_input_dir. this consists of
+ # Margin is for files that are not under args.input_dir. this consists of
# n inodes for apex_manifest files and 11 reserved inodes for ext4.
# TOBO(b/122991714) eliminate these details. Use build_image.py which
# determines the optimal inode count by first building an image and then
# count the inodes actually used.
inode_num_margin = GetFilesAndDirsCount(manifests_dir) + 11
- inode_num = GetFilesAndDirsCount(staging_input_dir) + inode_num_margin
+ inode_num = GetFilesAndDirsCount(args.input_dir) + inode_num_margin
cmd = ['mke2fs']
cmd.extend(['-O', '^has_journal']) # because image is read-only
@@ -535,10 +530,10 @@ def CreateImageExt4(args, staging_input_dir, work_dir, manifests_dir, img_file,
# Add files to the image file
cmd = ['e2fsdroid']
cmd.append('-e') # input is not android_sparse_file
- cmd.extend(['-f', staging_input_dir])
+ cmd.extend(['-f', args.input_dir])
cmd.extend(['-T', '0']) # time is set to epoch
cmd.extend(['-S', compiled_file_contexts])
- cmd.extend(['-C', canned_fs_config])
+ cmd.extend(['-C', args.canned_fs_config])
cmd.extend(['-a', '/'])
cmd.append('-s') # share dup blocks
cmd.append(img_file)
@@ -549,7 +544,7 @@ def CreateImageExt4(args, staging_input_dir, work_dir, manifests_dir, img_file,
cmd.extend(['-f', manifests_dir])
cmd.extend(['-T', '0']) # time is set to epoch
cmd.extend(['-S', compiled_file_contexts])
- cmd.extend(['-C', canned_fs_config])
+ cmd.extend(['-C', args.canned_fs_config])
cmd.extend(['-a', '/'])
cmd.append('-s') # share dup blocks
cmd.append(img_file)
@@ -562,12 +557,12 @@ def CreateImageExt4(args, staging_input_dir, work_dir, manifests_dir, img_file,
RunCommand(cmd, args.verbose, {'E2FSPROGS_FAKE_TIME': '1'})
-def CreateImageF2fs(args, staging_input_dir, manifests_dir, img_file, canned_fs_config):
+def CreateImageF2fs(args, manifests_dir, img_file):
"""Create image for f2fs file system."""
# F2FS requires a ~100M minimum size (necessary for ART, could be reduced
# a bit for other)
# TODO(b/158453869): relax these requirements for readonly devices
- size_in_mb = (GetDirSize(staging_input_dir) // (1024 * 1024))
+ size_in_mb = (GetDirSize(args.input_dir) // (1024 * 1024))
size_in_mb += 100
# Create an empty image
@@ -588,7 +583,7 @@ def CreateImageF2fs(args, staging_input_dir, manifests_dir, img_file, canned_fs_
# Add files to the image
cmd = ['sload_f2fs']
- cmd.extend(['-C', canned_fs_config])
+ cmd.extend(['-C', args.canned_fs_config])
cmd.extend(['-f', manifests_dir])
cmd.extend(['-s', args.file_contexts])
cmd.extend(['-T', '0'])
@@ -596,8 +591,8 @@ def CreateImageF2fs(args, staging_input_dir, manifests_dir, img_file, canned_fs_
RunCommand(cmd, args.verbose, expected_return_values={0, 1})
cmd = ['sload_f2fs']
- cmd.extend(['-C', canned_fs_config])
- cmd.extend(['-f', staging_input_dir])
+ cmd.extend(['-C', args.canned_fs_config])
+ cmd.extend(['-f', args.input_dir])
cmd.extend(['-s', args.file_contexts])
cmd.extend(['-T', '0'])
cmd.append(img_file)
@@ -606,7 +601,7 @@ def CreateImageF2fs(args, staging_input_dir, manifests_dir, img_file, canned_fs_
# TODO(b/158453869): resize the image file to save space
-def CreateImageErofs(args, staging_input_dir, work_dir, manifests_dir, img_file, canned_fs_config):
+def CreateImageErofs(args, work_dir, manifests_dir, img_file):
"""Create image for erofs file system."""
# mkfs.erofs doesn't support multiple input
@@ -614,13 +609,13 @@ def CreateImageErofs(args, staging_input_dir, work_dir, manifests_dir, img_file,
os.mkdir(tmp_input_dir)
cmd = ['/bin/cp', '-ra']
cmd.extend(glob.glob(manifests_dir + '/*'))
- cmd.extend(glob.glob(staging_input_dir + '/*'))
+ cmd.extend(glob.glob(args.input_dir + '/*'))
cmd.append(tmp_input_dir)
RunCommand(cmd, args.verbose)
cmd = ['make_erofs']
cmd.extend(['-z', 'lz4hc'])
- cmd.extend(['--fs-config-file', canned_fs_config])
+ cmd.extend(['--fs-config-file', args.canned_fs_config])
cmd.extend(['--file-contexts', args.file_contexts])
uu = str(uuid.uuid5(uuid.NAMESPACE_URL, 'www.android.com'))
cmd.extend(['-U', uu])
@@ -639,14 +634,14 @@ def CreateImageErofs(args, staging_input_dir, work_dir, manifests_dir, img_file,
RunCommand(cmd, verbose=False)
-def CreateImage(args, staging_input_dir, work_dir, manifests_dir, img_file, canned_fs_config):
+def CreateImage(args, work_dir, manifests_dir, img_file):
"""create payload image."""
if args.payload_fs_type == 'ext4':
- CreateImageExt4(args, staging_input_dir, work_dir, manifests_dir, img_file, canned_fs_config)
+ CreateImageExt4(args, work_dir, manifests_dir, img_file)
elif args.payload_fs_type == 'f2fs':
- CreateImageF2fs(args, staging_input_dir, manifests_dir, img_file, canned_fs_config)
+ CreateImageF2fs(args, manifests_dir, img_file)
elif args.payload_fs_type == 'erofs':
- CreateImageErofs(args, staging_input_dir, work_dir, manifests_dir, img_file, canned_fs_config)
+ CreateImageErofs(args, work_dir, manifests_dir, img_file)
def SignImage(args, manifest_apex, img_file):
@@ -699,39 +694,31 @@ def SignImage(args, manifest_apex, img_file):
RunCommand(cmd, args.verbose)
-def CreateApexPayload(
- args,
- staging_input_dir,
- work_dir,
- content_dir,
- manifests_dir,
- manifest_apex,
- canned_fs_config):
+def CreateApexPayload(args, work_dir, content_dir, manifests_dir,
+ manifest_apex):
"""Create payload.
Args:
args: apexer options
- staging_input_dir: the input directory to be turned into the payload
work_dir: apex container working directory
content_dir: the working directory for payload contents
manifests_dir: manifests directory
manifest_apex: apex manifest proto
- canned_fs_config: the canned fs_config file
Returns:
payload file
"""
if args.payload_type == 'image':
img_file = os.path.join(content_dir, 'apex_payload.img')
- CreateImage(args, staging_input_dir, work_dir, manifests_dir, img_file, canned_fs_config)
+ CreateImage(args, work_dir, manifests_dir, img_file)
if not args.unsigned_payload:
SignImage(args, manifest_apex, img_file)
else:
img_file = os.path.join(content_dir, 'apex_payload.zip')
cmd = ['soong_zip']
cmd.extend(['-o', img_file])
- cmd.extend(['-C', staging_input_dir])
- cmd.extend(['-D', staging_input_dir])
+ cmd.extend(['-C', args.input_dir])
+ cmd.extend(['-D', args.input_dir])
cmd.extend(['-C', manifests_dir])
cmd.extend(['-D', manifests_dir])
RunCommand(cmd, args.verbose)
@@ -769,59 +756,6 @@ def CreateAndroidManifestXml(args, work_dir, manifest_apex):
args.logging_parent)
return android_manifest_file
-def ReplaceApexVersionPlaceholder(args, work_dir, apex_version_code):
- """Replace args.apex_version_placeholder strings in APEX input paths with the version.
-
- See b/229574810 for more information.
-
- Args:
- args: apexer options
- work_dir: apex container working directory
- apex_version_code: apex version as a string
-
- Returns:
- a tuple of the new canned_fs_config and input directory with substituted input paths
- """
-
- # While manifest_apex.version is an int arg, let's be defensive here
- # and not rely on that being always the case. Check that the version
- # is a valid path fragment.
- version_re = r'^[\w\.\-\_]+$'
- if not re.match(version_re, apex_version_code, re.ASCII):
- raise Exception('Unable to use apex verson ' + apex_version_code +
- ' as filename suffix, valid characters are [a-zA-Z0-9_.-]')
-
- # Update the canned fs config since it contains entries for every file/dir
- # in the APEX.
- if args.canned_fs_config is not None:
- with open(args.canned_fs_config, 'r') as f:
- canned_fs_config_content = f.read().replace(
- args.apex_version_placeholder, apex_version_code)
- new_canned_fs_config = os.path.join(work_dir, 'canned_fs_config')
- with open(new_canned_fs_config, 'w') as f:
- f.write(canned_fs_config_content)
- else:
- # TODO(b/193473780): Zip apexes do not have canned fs_config files.
- # Delete when zipapex is deprecated.
- new_canned_fs_config = None
-
- # Copy the input dir into a staging area in the working directory. This is
- # necessary to perform any apexer-level changes on the file layouts, while
- # avoiding in-place changes to the real inputs.
- staging_input_dir = os.path.join(work_dir, 'input')
- os.makedirs(staging_input_dir, exist_ok=True)
- for root, _, files in os.walk(args.input_dir):
- root_relative = os.path.relpath(root, args.input_dir)
- root_relative = root_relative.replace(
- args.apex_version_placeholder, apex_version_code)
- for f in files:
- src = os.path.join(root, f)
- dest = os.path.normpath(os.path.join(staging_input_dir, root_relative, f))
- # APEX contents can be unresolved symlinks, so don't follow them.
- os.makedirs(os.path.dirname(dest), exist_ok=True)
- shutil.copy2(src, dest, follow_symlinks=False)
-
- return (new_canned_fs_config, staging_input_dir)
def CreateApex(args, work_dir):
if not ValidateArgs(args):
@@ -872,24 +806,9 @@ def CreateApex(args, work_dir):
CopyFile(args.manifest_json,
os.path.join(content_dir, 'apex_manifest.json'))
- apex_version_code = str(manifest_apex.version)
-
- # b/229574810: replace all instances of args.apex_version_placeholder
- # strings in /app and /priv-app inputs. This is necessary for the
- # package manager to correctly invalidate its directory-path based
- # cache keys and differentiate APKs based on their version codes.
- canned_fs_config, staging_input_dir = ReplaceApexVersionPlaceholder(
- args, work_dir, apex_version_code)
-
# Create payload
- img_file = CreateApexPayload(
- args,
- staging_input_dir,
- work_dir,
- content_dir,
- manifests_dir,
- manifest_apex,
- canned_fs_config)
+ img_file = CreateApexPayload(args, work_dir, content_dir, manifests_dir,
+ manifest_apex)
if args.unsigned_payload_only or args.payload_only:
shutil.copyfile(img_file, args.output)
@@ -905,11 +824,7 @@ def CreateApex(args, work_dir):
shutil.copyfile(args.pubkey, os.path.join(content_dir, 'apex_pubkey'))
if args.include_build_info:
- build_info = GenerateBuildInfo(
- args,
- args.file_contexts,
- canned_fs_config,
- args.android_manifest)
+ build_info = GenerateBuildInfo(args)
with open(os.path.join(content_dir, 'apex_build_info.pb'), 'wb') as f:
f.write(build_info.SerializeToString())
@@ -921,7 +836,7 @@ def CreateApex(args, work_dir):
cmd.extend(['--rename-manifest-package', args.override_apk_package_name])
# This version from apex_manifest.json is used when versionCode isn't
# specified in AndroidManifest.xml
- cmd.extend(['--version-code', apex_version_code])
+ cmd.extend(['--version-code', str(manifest_apex.version)])
if manifest_apex.versionName:
cmd.extend(['--version-name', manifest_apex.versionName])
if args.target_sdk_version:
diff --git a/apexer/runtests.sh b/apexer/runtests.sh
index d15bc5c2..4d9d6029 100755
--- a/apexer/runtests.sh
+++ b/apexer/runtests.sh
@@ -51,8 +51,6 @@ head -c 1M </dev/urandom > ${input_dir}/file1
head -c 1M </dev/urandom > ${input_dir}/file2
mkdir ${input_dir}/sub
head -c 1M </dev/urandom > ${input_dir}/sub/file3
-mkdir ${input_dir}/sub2@__APEX_VERSION_PLACEHOLDER__
-head -c 1M </dev/urandom > ${input_dir}/sub2@__APEX_VERSION_PLACEHOLDER__/file4
ln -s file1 ${input_dir}/sym1
# Create the APEX manifest file
@@ -66,7 +64,6 @@ file_contexts_file=$(mktemp)
echo '
(/.*)? u:object_r:root_file:s0
/sub(/.*)? u:object_r:sub_file:s0
-/sub2(/.*)? u:object_r:sub2_file:s0
/sub/file3 u:object_r:file3_file:s0
' > ${file_contexts_file}
@@ -77,8 +74,6 @@ echo '/ 1000 1000 0644
/file2 1001 1001 0644
/sub 1002 1002 0644
/sub/file3 1003 1003 0644
-/sub2@__APEX_VERSION_PLACEHOLDER__ 1004 1004 0644
-/sub2@__APEX_VERSION_PLACEHOLDER__/file4 1005 1005 0644
/sym1 1001 1001 0644' > ${canned_fs_config_file}
output_file=${output_dir}/test.apex
@@ -119,7 +114,6 @@ sudo diff ${manifest_file} ${output_dir}/apex_manifest.pb
sudo diff ${input_dir}/file1 ${output_dir}/mnt/file1
sudo diff ${input_dir}/file2 ${output_dir}/mnt/file2
sudo diff ${input_dir}/sub/file3 ${output_dir}/mnt/sub/file3
-sudo diff ${input_dir}/sub2@__APEX_VERSION_PLACEHOLDER__/file4 ${output_dir}/mnt/sub2@1/file4
[ `sudo readlink ${output_dir}/mnt/sym1` = "file1" ]
# check the uid/gid/type/mod
@@ -127,8 +121,6 @@ sudo diff ${input_dir}/sub2@__APEX_VERSION_PLACEHOLDER__/file4 ${output_dir}/mnt
[ `sudo stat -c '%u,%g,%A' ${output_dir}/mnt/file2` = "1001,1001,-rw-r--r--" ]
[ `sudo stat -c '%u,%g,%A' ${output_dir}/mnt/sub` = "1002,1002,drw-r--r--" ]
[ `sudo stat -c '%u,%g,%A' ${output_dir}/mnt/sub/file3` = "1003,1003,-rw-r--r--" ]
-[ `sudo stat -c '%u,%g,%A' ${output_dir}/mnt/sub2@1` = "1004,1004,drw-r--r--" ]
-[ `sudo stat -c '%u,%g,%A' ${output_dir}/mnt/sub2@1/file4` = "1005,1005,-rw-r--r--" ]
[ `sudo stat -c '%u,%g,%A' ${output_dir}/mnt/sym1` = "1001,1001,lrw-r--r--" ]
[ `sudo stat -c '%u,%g,%A' ${output_dir}/mnt/apex_manifest.pb` = "1000,1000,-rw-r--r--" ]
@@ -137,7 +129,6 @@ sudo diff ${input_dir}/sub2@__APEX_VERSION_PLACEHOLDER__/file4 ${output_dir}/mnt
[ `sudo ls -Z ${output_dir}/mnt/file2 | cut -d ' ' -f 1` = "u:object_r:root_file:s0" ]
[ `sudo ls -d -Z ${output_dir}/mnt/sub/ | cut -d ' ' -f 1` = "u:object_r:sub_file:s0" ]
[ `sudo ls -Z ${output_dir}/mnt/sub/file3 | cut -d ' ' -f 1` = "u:object_r:file3_file:s0" ]
-[ `sudo ls -Z ${output_dir}/mnt/sub2@1/file4 | cut -d ' ' -f 1` = "u:object_r:sub2_file:s0" ]
[ `sudo ls -Z ${output_dir}/mnt/apex_manifest.pb | cut -d ' ' -f 1` = "u:object_r:root_file:s0" ]
[ `sudo ls -Z ${output_dir}/mnt/sym1 | cut -d ' ' -f 1` = "u:object_r:root_file:s0" ]