1#!/bin/bash 2 3# Copyright (C) 2018 The Android Open Source Project 4# 5# Licensed under the Apache License, Version 2.0 (the "License"); 6# you may not use this file except in compliance with the License. 7# You may obtain a copy of the License at 8# 9# http://www.apache.org/licenses/LICENSE-2.0 10# 11# Unless required by applicable law or agreed to in writing, software 12# distributed under the License is distributed on an "AS IS" BASIS, 13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14# See the License for the specific language governing permissions and 15# limitations under the License. 16# 17 18if [[ -z ${ANDROID_BUILD_TOP} ]]; then 19 echo "You need to source and lunch before you can use this script" 20 exit 1 21fi 22 23echo "Running test" 24set -e # fail early 25 26source ${ANDROID_BUILD_TOP}/build/envsetup.sh 27m -j apexer 28export APEXER_TOOL_PATH="${ANDROID_BUILD_TOP}/out/host/linux-x86/bin:${ANDROID_BUILD_TOP}/prebuilts/sdk/tools/linux/bin" 29PATH+=":${ANDROID_BUILD_TOP}/prebuilts/sdk/tools/linux/bin" 30 31for fs_type in ext4 f2fs erofs 32do 33input_dir=$(mktemp -d) 34output_dir=$(mktemp -d) 35 36function cleanup { 37 sudo umount /dev/loop10 38 sudo losetup --detach /dev/loop10 39 40 rm -rf ${input_dir} 41 rm -rf ${output_dir} 42} 43 44trap cleanup ERR 45############################################# 46# prepare the inputs 47############################################# 48# Create the input directory having 3 files with random bits and a symlink from 49# ${input_dir}/sym1 -> ${input_dir}/file1 50head -c 1M </dev/urandom > ${input_dir}/file1 51head -c 1M </dev/urandom > ${input_dir}/file2 52mkdir ${input_dir}/sub 53head -c 1M </dev/urandom > ${input_dir}/sub/file3 54ln -s file1 ${input_dir}/sym1 55 56# Create the APEX manifest file 57manifest_dir=$(mktemp -d) 58manifest_file=${manifest_dir}/apex_manifest.pb 59echo '{"name": "com.android.example.apex", "version": 1}' > ${manifest_dir}/apex_manifest.json 60${ANDROID_BUILD_TOP}/out/host/linux-x86/bin/conv_apex_manifest proto ${manifest_dir}/apex_manifest.json -o ${manifest_file} 61 62# Create the file_contexts file 63file_contexts_file=$(mktemp) 64echo ' 65(/.*)? u:object_r:root_file:s0 66/sub(/.*)? u:object_r:sub_file:s0 67/sub/file3 u:object_r:file3_file:s0 68' > ${file_contexts_file} 69 70canned_fs_config_file=$(mktemp) 71echo '/ 1000 1000 0644 72/apex_manifest.pb 1000 1000 0644 73/file1 1001 1001 0644 74/file2 1001 1001 0644 75/sub 1002 1002 0644 76/sub/file3 1003 1003 0644 77/sym1 1001 1001 0644' > ${canned_fs_config_file} 78 79output_file=${output_dir}/test.apex 80 81############################################# 82# run the tool 83############################################# 84${ANDROID_HOST_OUT}/bin/apexer --verbose --manifest ${manifest_file} \ 85 --file_contexts ${file_contexts_file} \ 86 --canned_fs_config ${canned_fs_config_file} \ 87 --payload_fs_type ${fs_type} \ 88 --key ${ANDROID_BUILD_TOP}/system/apex/apexer/testdata/com.android.example.apex.pem \ 89 --android_jar_path ${ANDROID_BUILD_TOP}/prebuilts/sdk/current/public/android.jar \ 90 ${input_dir} ${output_file} 91 92############################################# 93# check the result 94############################################# 95offset=$(zipalign -v -c 4096 ${output_file} | grep apex_payload.img | tr -s ' ' | cut -d ' ' -f 2) 96 97unzip ${output_file} apex_payload.img -d ${output_dir} 98size=$(avbtool info_image --image ${output_dir}/apex_payload.img | awk '/Image size:/{print $3}') 99 100 101# test if it is mountable 102mkdir ${output_dir}/mnt 103sudo losetup -o ${offset} --sizelimit ${size} /dev/loop10 ${output_file} 104sudo mount -o ro /dev/loop10 ${output_dir}/mnt 105unzip ${output_file} apex_manifest.pb -d ${output_dir} 106 107# verify vbmeta 108avbtool verify_image --image ${output_dir}/apex_payload.img \ 109--key ${ANDROID_BUILD_TOP}/system/apex/apexer/testdata/com.android.example.apex.pem 110 111# check the contents 112sudo diff ${manifest_file} ${output_dir}/mnt/apex_manifest.pb 113sudo diff ${manifest_file} ${output_dir}/apex_manifest.pb 114sudo diff ${input_dir}/file1 ${output_dir}/mnt/file1 115sudo diff ${input_dir}/file2 ${output_dir}/mnt/file2 116sudo diff ${input_dir}/sub/file3 ${output_dir}/mnt/sub/file3 117[ `sudo readlink ${output_dir}/mnt/sym1` = "file1" ] 118 119# check the uid/gid/type/mod 120[ `sudo stat -c '%u,%g,%A' ${output_dir}/mnt/file1` = "1001,1001,-rw-r--r--" ] 121[ `sudo stat -c '%u,%g,%A' ${output_dir}/mnt/file2` = "1001,1001,-rw-r--r--" ] 122[ `sudo stat -c '%u,%g,%A' ${output_dir}/mnt/sub` = "1002,1002,drw-r--r--" ] 123[ `sudo stat -c '%u,%g,%A' ${output_dir}/mnt/sub/file3` = "1003,1003,-rw-r--r--" ] 124[ `sudo stat -c '%u,%g,%A' ${output_dir}/mnt/sym1` = "1001,1001,lrw-r--r--" ] 125[ `sudo stat -c '%u,%g,%A' ${output_dir}/mnt/apex_manifest.pb` = "1000,1000,-rw-r--r--" ] 126 127# check the selinux labels 128[ `sudo ls -Z ${output_dir}/mnt/file1 | cut -d ' ' -f 1` = "u:object_r:root_file:s0" ] 129[ `sudo ls -Z ${output_dir}/mnt/file2 | cut -d ' ' -f 1` = "u:object_r:root_file:s0" ] 130[ `sudo ls -d -Z ${output_dir}/mnt/sub/ | cut -d ' ' -f 1` = "u:object_r:sub_file:s0" ] 131[ `sudo ls -Z ${output_dir}/mnt/sub/file3 | cut -d ' ' -f 1` = "u:object_r:file3_file:s0" ] 132[ `sudo ls -Z ${output_dir}/mnt/apex_manifest.pb | cut -d ' ' -f 1` = "u:object_r:root_file:s0" ] 133[ `sudo ls -Z ${output_dir}/mnt/sym1 | cut -d ' ' -f 1` = "u:object_r:root_file:s0" ] 134 135# check the android manifest 136aapt dump xmltree ${output_file} AndroidManifest.xml 137 138echo "Passed for ${fs_type}" 139cleanup 140done 141 142echo "Passed for all fs types" 143