Run recovery installer in chroot (#901)

The recovery installer now has as few dependencies on the
Android recovery system as possible.
This commit is contained in:
Attila Szöllősi 2017-11-16 23:20:57 +01:00 committed by Oliver Smith
parent 4c7793e766
commit d9e7a3d7de
9 changed files with 131 additions and 95 deletions

View File

@ -1,5 +1,5 @@
pkgname=postmarketos-android-recovery-installer
pkgver=0.0.7
pkgver=0.1.0
pkgrel=0
pkgdesc="TWRP compatible postmarketOS installer script"
url="https://github.com/postmarketOS"
@ -7,6 +7,7 @@ url="https://github.com/postmarketOS"
depends="busybox-extras lddtree cryptsetup multipath-tools device-mapper parted util-linux zip e2fsprogs tar"
source="build_zip.sh
update-binary
pmos_chroot
pmos_install
pmos_install_functions
pmos_setpw"
@ -16,18 +17,18 @@ license="GPL3"
package() {
install -Dm755 "$srcdir/build_zip.sh" \
"$pkgdir/sbin/build-recovery-zip"
mkdir -p "$pkgdir/var/lib/postmarketos-android-recovery-installer/META-INF/com/google/android/"
install -Dm644 "$srcdir"/update-binary \
"$pkgdir/var/lib/postmarketos-android-recovery-installer/META-INF/com/google/android/update-binary"
mkdir "$pkgdir/var/lib/postmarketos-android-recovery-installer/bin/"
install -Dm755 "$srcdir"/pmos_chroot \
"$pkgdir/var/lib/postmarketos-android-recovery-installer/pmos_chroot"
for file in pmos_install pmos_install_functions pmos_setpw; do
install -Dm755 "$srcdir/$file" \
"$pkgdir/var/lib/postmarketos-android-recovery-installer/bin/$file"
"$pkgdir/var/lib/postmarketos-android-recovery-installer/chroot/bin/$file"
done
mkdir "$pkgdir/var/lib/postmarketos-android-recovery-installer/lib/"
}
sha512sums="5934797c1aec8b3f8650dd1a149000c1227552f768b5417eafebf2772da6b34579f3c96d9441053d152500b2f68f29ba0dccbabf6fd0191c924daffd01be6f89 build_zip.sh
6e658b6924c31deb55561c256eea842824d2d21fc90e4b8227c0c910153d3cf16dca86eab6a3dcdaeb36d625c34c1153f4858e6813df5f909d2f3445b3a6c710 update-binary
bc340a1a83673c7a66da09e44dc40b20305e5ef52dea3c9d8151d3c07064b7b2016d4fe99869bb9d725a5a3aeb0bd570af3e26a91c7da6905cd9f281a99adb4d pmos_install
fb9507a82d44c580af714488d18e7b59a1be0aa60292578e6571df7905c312caaaefd7d54eb6ce1a0b768616e356ece45b50c3e28acce86312d6d8e028bdf389 pmos_install_functions
27dd89aa8471349995a1cbbc1034ead662a0d1dd70ca5490f3191ceaaeb853331003c20ffddbbd95fe822135a85c1beb1e2a32bb33b10c2a4177b30347a40555 pmos_setpw"
sha512sums="f02e67d26f4f977c5098ff6eee51b53ec962982c41b8b33c1a206c218c483bd20f782c06622cf8d724a9a1cdb5b9cc1b76d3bf32e562c9b558747ca3f3408ffd build_zip.sh
7c396f4ae50f71d8c5ecf0528d1841639da75934dc8bd160311969e0d461dfc2f851eb6aa0373ec5cced11430ebc961f55a79863badb68d70fcad43725f9396b update-binary
4a049428862cbbf9eef6ee0f49ccefa6e51bfdfac5a48000fb5f199d8e09ef7c44219429b558ec7beaf6a86f84b6185d160f0eb3e921b979b122121c2fc0060e pmos_chroot
caafd0e6345e2082e4a2dc7169b1dedf11fd4423e72a2a2d33a6056cf2ecbed2ffa5c995491cbc0a62518623d3d2830d754c28cc4dc68db2c4a9224492409168 pmos_install
36d8ca5ae092f8de0a9e2658581d3d1f83483b5076446aebaf5e1ab377e49615c31b81c00a23bc74d569de12a73977291c9a73e4f19b2faa694d981010c3eb35 pmos_install_functions
558680cfeac4ab5e191cffa0f875e762b923fa281ba65cbe64da525710f82e6f7707cb9e346ee53fa50bb19afc567c331b005cd9c20d00ec3869819cadd992a4 pmos_setpw"

View File

@ -1,7 +1,6 @@
#!/bin/ash
# shellcheck shell=dash
#!/bin/sh
# Copyright 2017 Attila Szöllősi
# Copyright 2017 Attila Szollosi
#
# This file is part of postmarketos-android-recovery-installer.
#
@ -20,6 +19,8 @@
set -e
DEVICE="$1"
# Copy files to the destination specified
# $1: files
# $2: destination
@ -40,14 +41,11 @@ check_whether_exists()
fi
}
# shellcheck disable=SC1091
. ./install_options
BINARIES="/bin/umount /sbin/cryptsetup /sbin/findfs /sbin/kpartx /sbin/mkfs.ext2 /sbin/mkfs.ext4 /usr/sbin/parted /usr/sbin/partprobe"
BINARIES="/bin/busybox /bin/umount /sbin/cryptsetup /sbin/findfs /sbin/kpartx /sbin/mkfs.ext2 /sbin/mkfs.ext4 \
/usr/sbin/parted /usr/sbin/partprobe"
# shellcheck disable=SC2086
LIBRARIES=$(lddtree -l $BINARIES | awk '/lib/ {print}' | sort -u)
copy_files "$BINARIES" bin/
copy_files "$LIBRARIES" lib/
copy_files "$BINARIES" chroot/bin/
copy_files "$LIBRARIES" chroot/lib/
check_whether_exists rootfs.tar.gz
[ "$FLASH_BOOT" = "true" ] && check_whether_exists boot.img
zip -0 -r "pmos-$DEVICE.zip" .

View File

@ -0,0 +1,44 @@
#!/sbin/sh
exec > /tmp/postmarketos/pmos_chroot.log 2>&1
set -ex
export CHROOT='/tmp/postmarketos/chroot'
# Extract chroot
unzip -o "$ZIP" chroot/* -d /tmp/postmarketos
# shellcheck source=/dev/null
. "$CHROOT"/install_options
if [ "$FDE" = 'true' ]
then
# Install password setting script
{
echo '#!/sbin/sh'
echo "chroot $CHROOT /bin/pmos_setpw"
} > /sbin/pmos_setpw
chmod 755 /sbin/pmos_setpw
fi
# Mount pmos.zip so we can access it inside the chroot
{ umount "$CHROOT"/pmos.zip ; rm "$CHROOT"/pmos.zip ; } || :
touch "$CHROOT"/pmos.zip
mount --bind "$ZIP" "$CHROOT"/pmos.zip
# Create copy of fstab file provided by the recovery
cp /etc/recovery.fstab "$CHROOT"/recovery.fstab || {
[ "$?" = '255' ] && echo 'recovery.fstab not found, continuing...' || exit "$?" ; }
# Mount necessary filesystems for the chroot
for mountpoint in "/dev" "/proc" "/sys"
do
mkdir -p "$CHROOT""$mountpoint"
mount --bind "$mountpoint" "$CHROOT""$mountpoint"
done
# Set permissions and start the installation script
chmod 755 "$CHROOT"/bin/*
chroot "$CHROOT" /bin/pmos_install || {
echo 'Installation script failed.'
echo 'Check /tmp/postmarketos/chroot/pmos.log for more information.'
exit 1
}

View File

@ -1,7 +1,7 @@
#!/sbin/ash
# shellcheck shell=dash
#!/bin/busybox ash
# shellcheck shell=sh
# Copyright 2017 Attila Szöllősi
# Copyright 2017 Attila Szollosi
#
# This file is part of postmarketos-android-recovery-installer.
#
@ -18,14 +18,14 @@
# You should have received a copy of the GNU General Public License
# along with postmarketos-android-recovery-installer. If not, see <http://www.gnu.org/licenses/>.
# shellcheck source=pmos_install_functions
. /tmp/postmarketos/bin/pmos_install_functions "$1" "$2"
# shellcheck source=/dev/null
. "$WORKING_DIR"/install_options
exec > "$WORKING_DIR"/pmos.log 2>&1
exec > /pmos.log 2>&1
set -ex
/bin/busybox --install /bin
# shellcheck source=pmos_install_functions
. /bin/pmos_install_functions
ui_print " "
ui_print " 8 "
ui_print " 888 "
@ -52,13 +52,10 @@ ui_print " "
ui_print "postmarketOS recovery installer "
ui_print " "
ui_print "Entering working directory..."
cd "$WORKING_DIR"
ui_print "Extracting files..."
busybox unzip -o "$ZIP" -x rootfs.tar.gz
mkdir -p /lib
ui_print "Symlinking .so files to /lib/..."
ln -sf "$WORKING_DIR"/lib/* /lib/
# Umount and close install partition if mounted/open
mountpoint -q /mnt/pmOS && umount -R /mnt/pmOS
[ -e /dev/mapper/pm_crypt ] && cryptsetup close pm_crypt
ui_print "Symlinking block devices..."
ln -sf /dev/block/* /dev/
ui_print "Extracting partition table..."
@ -68,55 +65,55 @@ umount_install_partition
ui_print "Creating partition table on $INSTALL_DEVICE..."
# parted returns nonzero even when command executed successfully
partition_install_device || :
ui_print "Creating mountpoint..."
mkdir -p /mnt/pmOS
if [ "$FDE" = "true" ]
then
[ -e /dev/mapper/pm_crypt ] && cryptsetup close pm_crypt
ui_print "Generating temporary keyfile with random data..."
busybox dd bs=512 count=4 if=/dev/urandom of="$WORKING_DIR"/lukskey
dd bs=512 count=4 if=/dev/urandom of=/lukskey
ui_print "Initializing LUKS device..."
cryptsetup luksFormat --use-urandom -c "$CIPHER" -q "$ROOT_PARTITION" "$WORKING_DIR"/lukskey
cryptsetup luksFormat --use-urandom -c "$CIPHER" -q "$ROOT_PARTITION" /lukskey
ui_print "Opening LUKS partition..."
cryptsetup luksOpen -d "$WORKING_DIR"/lukskey "$ROOT_PARTITION" pm_crypt
cryptsetup luksOpen -d /lukskey "$ROOT_PARTITION" pm_crypt
ui_print "Formatting LUKS partition..."
mkfs.ext4 -L 'pmOS_root' /dev/mapper/pm_crypt
ui_print "Mounting LUKS partition..."
mount -t ext4 -rw /dev/mapper/pm_crypt /"$INSTALL_PARTITION"
mount -t ext4 -rw /dev/mapper/pm_crypt /mnt/pmOS
else
ui_print "Formatting root partition..."
mkfs.ext4 -L 'pmOS_root' "$ROOT_PARTITION"
ui_print "Mounting root partition..."
mount -t ext4 -rw "$ROOT_PARTITION" /"$INSTALL_PARTITION"
mount -t ext4 -rw "$ROOT_PARTITION" /mnt/pmOS
fi
ui_print "Formatting pmOS_boot..."
mkfs.ext2 -q -L 'pmOS_boot' "$PMOS_BOOT"
ui_print "Mounting pmOS_boot..."
mkdir /"$INSTALL_PARTITION"/boot
mount -t ext2 -rw "$PMOS_BOOT" /"$INSTALL_PARTITION"/boot || {
mkdir /mnt/pmOS/boot
mount -t ext2 -rw "$PMOS_BOOT" /mnt/pmOS/boot || {
ui_print "Failed to format/mount ext2 partition."
ui_print "Trying ext4..."
mkfs.ext4 -L 'pmOS_boot' "$PMOS_BOOT"
mount -t ext4 -rw "$PMOS_BOOT" /"$INSTALL_PARTITION"/boot
mount -t ext4 -rw "$PMOS_BOOT" /mnt/pmOS/boot
}
ui_print "Installing rootfs..."
busybox unzip -p "$ZIP" rootfs.tar.gz | busybox tar -xz -C /"$INSTALL_PARTITION"
unzip -p pmos.zip rootfs.tar.gz | tar -xz -C /mnt/pmOS
if [ "$FLASH_KERNEL" = "true" ]
then
if [ "$ISOREC" = "true" ]
then
ui_print "Flashing kernel..."
busybox dd if=/"$INSTALL_PARTITION"/boot/vmlinuz-"$FLAVOR" of="$KERNEL_PARTITION"
dd if=/mnt/pmOS/boot/vmlinuz-"$FLAVOR" of="$KERNEL_PARTITION"
ui_print "Flashing initfs..."
busybox gunzip -c /"$INSTALL_PARTITION"/boot/initramfs-"$FLAVOR" | busybox lzop \
gunzip -c /mnt/pmOS/boot/initramfs-"$FLAVOR" | lzop \
> "$INITFS_PARTITION"
else
ui_print "Flashing boot.img..."
busybox dd if=/"$INSTALL_PARTITION"/boot/boot.img-"$FLAVOR" of="$BOOT_PARTITION"
dd if=/mnt/pmOS/boot/boot.img-"$FLAVOR" of="$BOOT_PARTITION"
fi
fi
if [ "$FDE" = "true" ]
then
ui_print "Creating a symlink for password setting script in /sbin/..."
ln -sf "$WORKING_DIR"/bin/pmos_setpw /sbin/
ui_print "Do not forget to add a password to the LUKS partition!"
ui_print "Run the command: pmos_setpw from the terminal/adb shell!"
fi

View File

@ -1,7 +1,6 @@
#!/sbin/ash
# shellcheck shell=dash
#!/bin/sh
# Copyright 2017 Attila Szöllősi
# Copyright 2017 Attila Szollosi
#
# This file is part of postmarketos-android-recovery-installer.
#
@ -18,25 +17,17 @@
# You should have received a copy of the GNU General Public License
# along with postmarketos-android-recovery-installer. If not, see <http://www.gnu.org/licenses/>.
export OUTFD=$1
export ZIP=$2
export WORKING_DIR="/tmp/postmarketos"
export PATH=$PATH:"$WORKING_DIR"/bin
# Use findfs and umount from util-linux
# shellcheck disable=SC2139
alias findfs="$WORKING_DIR/bin/findfs"
# shellcheck disable=SC2139
alias umount="$WORKING_DIR/bin/umount"
export PATH="/bin"
export LD_LIBRARY_PATH="/lib"
# shellcheck source=/dev/null
. "$WORKING_DIR"/install_options
. /install_options
# taken from https://github.com/Debuffer-XDA/Gov-Tuner/blob/master/META-INF/com/google/android/update-binary
# Copyright (c) 2016 - 2017 Debuffer
ui_print() {
echo -n -e "ui_print $1\n" > /proc/self/fd/"$OUTFD"
echo -n -e "ui_print\n" > /proc/self/fd/"$OUTFD"
echo "ui_print $1" > /proc/self/fd/"$OUTFD"
echo "ui_print" > /proc/self/fd/"$OUTFD"
}
extract_partition_table() {
@ -44,10 +35,10 @@ extract_partition_table() {
"system")
_INSTALL_DEVICE=$(findfs PARTLABEL="$SYSTEM_PARTLABEL") || \
# We need to resolve symlinks, to make set_subpartitions() work.
_INSTALL_DEVICE=$(busybox readlink -fn "$(awk '/^\/system/ {print $3}' /etc/recovery.fstab)")
_INSTALL_DEVICE=$(readlink -fn "$(awk '/^\/system/ {print $3}' /recovery.fstab)")
;;
"external_sd")
_INSTALL_DEVICE=$(busybox readlink -fn "$(awk '/^\/external_sd/ {print $4}' /etc/recovery.fstab)")
_INSTALL_DEVICE=$(readlink -fn "$(awk '/^\/external_sd/ {print $4}' /recovery.fstab)")
;;
*)
echo "No support for flashing $INSTALL_PARTITION."
@ -70,7 +61,7 @@ extract_partition_table() {
INITFS_PARTITION=$(findfs PARTLABEL="$INITFS_PARTLABEL")
else
_BOOT_PARTITION=$(findfs PARTLABEL="boot") || \
_BOOT_PARTITION=$(awk '/^\/boot/ {print $3}' /etc/recovery.fstab)
_BOOT_PARTITION=$(awk '/^\/boot/ {print $3}' /recovery.fstab)
if [ ! -z "$_BOOT_PARTITION" ]
then
echo "boot partition found at $_BOOT_PARTITION"
@ -100,17 +91,16 @@ partition_install_device() {
set_subpartitions() {
export PMOS_BOOT
PMOS_BOOT=/dev/mapper/"$(busybox basename "$INSTALL_DEVICE")"p1
PMOS_BOOT=/dev/mapper/"$(basename "$INSTALL_DEVICE")"p1
export ROOT_PARTITION
ROOT_PARTITION=/dev/mapper/"$(busybox basename "$INSTALL_DEVICE")"p2
ROOT_PARTITION=/dev/mapper/"$(basename "$INSTALL_DEVICE")"p2
}
umount_install_partition() {
if busybox mountpoint -q "/$INSTALL_PARTITION/"
if [ -n "$(awk '$1 == install_part' install_part="$INSTALL_DEVICE" /proc/mounts)" ]
then
umount -R /"$INSTALL_PARTITION"/
umount "$INSTALL_DEVICE"
else
echo 'Continuing...'
return 0
echo "$INSTALL_DEVICE is not mounted, continuing..."
fi
}

View File

@ -1,7 +1,6 @@
#!/sbin/ash -e
# shellcheck shell=dash
#!/bin/sh
# Copyright 2017 Attila Szöllősi
# Copyright 2017 Attila Szollosi
#
# This file is part of postmarketos-android-recovery-installer.
#
@ -18,13 +17,15 @@
# You should have received a copy of the GNU General Public License
# along with postmarketos-android-recovery-installer. If not, see <http://www.gnu.org/licenses/>.
set -e
# shellcheck source=pmos_install_functions
. /tmp/postmarketos/bin/pmos_install_functions
. /bin/pmos_install_functions
extract_partition_table
set_subpartitions
echo "Set the password of the encrypted rootfs!"
cryptsetup luksAddKey -d "$WORKING_DIR"/lukskey "$ROOT_PARTITION"
echo "Set the password of the encrypted rootfs."
cryptsetup luksAddKey -d /lukskey "$ROOT_PARTITION"
# Remove temporary keyfile
cryptsetup luksRemoveKey "$ROOT_PARTITION" "$WORKING_DIR"/lukskey
cryptsetup luksRemoveKey "$ROOT_PARTITION" /lukskey
echo "Successfully added key to the LUKS device."

View File

@ -1,7 +1,6 @@
#!/sbin/ash
# shellcheck shell=dash
#!/sbin/sh
# Copyright 2017 Attila Szöllősi
# Copyright 2017 Attila Szollosi
#
# This file is part of postmarketos-android-recovery-installer.
#
@ -18,15 +17,20 @@
# You should have received a copy of the GNU General Public License
# along with postmarketos-android-recovery-installer. If not, see <http://www.gnu.org/licenses/>.
export OUTFD=$2
export ZIP=$3
# Print fail information
OUTFD=$2
fail_info() {
FAIL_MSG="Failed. Check /tmp/postmarketos/pmos.log for more info!"
echo -n -e "ui_print $FAIL_MSG\n" > /proc/self/fd/"$OUTFD"
echo -n -e "ui_print\n" > /proc/self/fd/"$OUTFD"
FAIL_MSG="Failed. Check /tmp/postmarketos/pmos_chroot.log for more info!"
echo "ui_print $FAIL_MSG" > /proc/self/fd/"$OUTFD"
echo "ui_print" > /proc/self/fd/"$OUTFD"
}
# Create working directory
mkdir -p /tmp/postmarketos/
# Extract and start the installer script
busybox unzip -o "$3" "bin/pmos_install" "bin/pmos_install_functions" "install_options" -d /tmp/postmarketos/
/tmp/postmarketos/bin/pmos_install "$2" "$3" || { fail_info ; exit 1 ; }
unzip -o "$ZIP" "pmos_chroot" -d /tmp/postmarketos/
chmod 755 /tmp/postmarketos/pmos_chroot
/tmp/postmarketos/pmos_chroot || { fail_info ; exit 1 ; }

View File

@ -64,7 +64,7 @@ def create_zip(args, suffix):
commands = [
# Move config file from /tmp/ to zip root
["mv", "/tmp/install_options", "install_options"],
["mv", "/tmp/install_options", "chroot/install_options"],
# Create tar archive of the rootfs
["tar", "-pcf", "rootfs.tar", "--exclude",
"./home/" + args.user + "/*", "-C", rootfs, "."],
@ -72,6 +72,6 @@ def create_zip(args, suffix):
["tar", "-prf", "rootfs.tar", "-C", "/", "./etc/apk/keys"],
# Compress with -1 for speed improvement
["gzip", "-f1", "rootfs.tar"],
["build-recovery-zip"]]
["build-recovery-zip", args.device]]
for command in commands:
pmb.chroot.root(args, command, suffix, working_dir=zip_root)

View File

@ -29,6 +29,7 @@ sh_files="
./aports/main/postmarketos-mkinitfs/init_functions.sh
./aports/main/postmarketos-update-kernel/update-kernel.sh
./aports/main/postmarketos-android-recovery-installer/build_zip.sh
./aports/main/postmarketos-android-recovery-installer/pmos_chroot
./aports/main/postmarketos-android-recovery-installer/pmos_install
./aports/main/postmarketos-android-recovery-installer/pmos_install_functions
./aports/main/postmarketos-android-recovery-installer/pmos_setpw
@ -40,7 +41,7 @@ sh_files="
for file in ${sh_files}; do
echo "Test with shellcheck: $file"
cd "$DIR/../$(dirname "$file")"
shellcheck -x "$(basename "$file")"
shellcheck -e SC1008 -x "$(basename "$file")"
done
# Python: flake8