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 585c08bad5
commit fdbbc774a9
7 changed files with 127 additions and 92 deletions

View file

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

View file

@ -1,7 +1,6 @@
#!/bin/ash #!/bin/sh
# shellcheck shell=dash
# Copyright 2017 Attila Szöllősi # Copyright 2017 Attila Szollosi
# #
# This file is part of postmarketos-android-recovery-installer. # This file is part of postmarketos-android-recovery-installer.
# #
@ -20,6 +19,8 @@
set -e set -e
DEVICE="$1"
# Copy files to the destination specified # Copy files to the destination specified
# $1: files # $1: files
# $2: destination # $2: destination
@ -40,14 +41,11 @@ check_whether_exists()
fi fi
} }
# shellcheck disable=SC1091 BINARIES="/bin/busybox /bin/umount /sbin/cryptsetup /sbin/findfs /sbin/kpartx /sbin/mkfs.ext2 /sbin/mkfs.ext4 \
. ./install_options /usr/sbin/parted /usr/sbin/partprobe"
BINARIES="/bin/umount /sbin/cryptsetup /sbin/findfs /sbin/kpartx /sbin/mkfs.ext2 /sbin/mkfs.ext4 /usr/sbin/parted /usr/sbin/partprobe"
# shellcheck disable=SC2086 # shellcheck disable=SC2086
LIBRARIES=$(lddtree -l $BINARIES | awk '/lib/ {print}' | sort -u) LIBRARIES=$(lddtree -l $BINARIES | awk '/lib/ {print}' | sort -u)
copy_files "$BINARIES" bin/ copy_files "$BINARIES" chroot/bin/
copy_files "$LIBRARIES" lib/ copy_files "$LIBRARIES" chroot/lib/
check_whether_exists rootfs.tar.gz check_whether_exists rootfs.tar.gz
[ "$FLASH_BOOT" = "true" ] && check_whether_exists boot.img
zip -0 -r "pmos-$DEVICE.zip" . 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 #!/bin/busybox ash
# shellcheck shell=dash # shellcheck shell=sh
# Copyright 2017 Attila Szöllősi # Copyright 2017 Attila Szollosi
# #
# This file is part of postmarketos-android-recovery-installer. # 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 # 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/>. # along with postmarketos-android-recovery-installer. If not, see <http://www.gnu.org/licenses/>.
# shellcheck source=pmos_install_functions exec > /pmos.log 2>&1
. /tmp/postmarketos/bin/pmos_install_functions "$1" "$2"
# shellcheck source=/dev/null
. "$WORKING_DIR"/install_options
exec > "$WORKING_DIR"/pmos.log 2>&1
set -ex set -ex
/bin/busybox --install /bin
# shellcheck source=pmos_install_functions
. /bin/pmos_install_functions
ui_print " " ui_print " "
ui_print " 8 " ui_print " 8 "
ui_print " 888 " ui_print " 888 "
@ -52,13 +52,10 @@ ui_print " "
ui_print "postmarketOS recovery installer " ui_print "postmarketOS recovery installer "
ui_print " " ui_print " "
ui_print "Entering working directory..." # Umount and close install partition if mounted/open
cd "$WORKING_DIR" mountpoint -q /mnt/pmOS && umount -R /mnt/pmOS
ui_print "Extracting files..." [ -e /dev/mapper/pm_crypt ] && cryptsetup close pm_crypt
busybox unzip -o "$ZIP" -x rootfs.tar.gz
mkdir -p /lib
ui_print "Symlinking .so files to /lib/..."
ln -sf "$WORKING_DIR"/lib/* /lib/
ui_print "Symlinking block devices..." ui_print "Symlinking block devices..."
ln -sf /dev/block/* /dev/ ln -sf /dev/block/* /dev/
ui_print "Extracting partition table..." ui_print "Extracting partition table..."
@ -68,55 +65,55 @@ umount_install_partition
ui_print "Creating partition table on $INSTALL_DEVICE..." ui_print "Creating partition table on $INSTALL_DEVICE..."
# parted returns nonzero even when command executed successfully # parted returns nonzero even when command executed successfully
partition_install_device || : partition_install_device || :
ui_print "Creating mountpoint..."
mkdir -p /mnt/pmOS
if [ "$FDE" = "true" ] if [ "$FDE" = "true" ]
then then
[ -e /dev/mapper/pm_crypt ] && cryptsetup close pm_crypt
ui_print "Generating temporary keyfile with random data..." 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..." 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..." 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..." ui_print "Formatting LUKS partition..."
mkfs.ext4 -L 'pmOS_root' /dev/mapper/pm_crypt mkfs.ext4 -L 'pmOS_root' /dev/mapper/pm_crypt
ui_print "Mounting LUKS partition..." 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 else
ui_print "Formatting root partition..." ui_print "Formatting root partition..."
mkfs.ext4 -L 'pmOS_root' "$ROOT_PARTITION" mkfs.ext4 -L 'pmOS_root' "$ROOT_PARTITION"
ui_print "Mounting root partition..." ui_print "Mounting root partition..."
mount -t ext4 -rw "$ROOT_PARTITION" /"$INSTALL_PARTITION" mount -t ext4 -rw "$ROOT_PARTITION" /mnt/pmOS
fi fi
ui_print "Formatting pmOS_boot..." ui_print "Formatting pmOS_boot..."
mkfs.ext2 -q -L 'pmOS_boot' "$PMOS_BOOT" mkfs.ext2 -q -L 'pmOS_boot' "$PMOS_BOOT"
ui_print "Mounting pmOS_boot..." ui_print "Mounting pmOS_boot..."
mkdir /"$INSTALL_PARTITION"/boot mkdir /mnt/pmOS/boot
mount -t ext2 -rw "$PMOS_BOOT" /"$INSTALL_PARTITION"/boot || { mount -t ext2 -rw "$PMOS_BOOT" /mnt/pmOS/boot || {
ui_print "Failed to format/mount ext2 partition." ui_print "Failed to format/mount ext2 partition."
ui_print "Trying ext4..." ui_print "Trying ext4..."
mkfs.ext4 -L 'pmOS_boot' "$PMOS_BOOT" 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..." 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" ] if [ "$FLASH_KERNEL" = "true" ]
then then
if [ "$ISOREC" = "true" ] if [ "$ISOREC" = "true" ]
then then
ui_print "Flashing kernel..." 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..." ui_print "Flashing initfs..."
busybox gunzip -c /"$INSTALL_PARTITION"/boot/initramfs-"$FLAVOR" | busybox lzop \ gunzip -c /mnt/pmOS/boot/initramfs-"$FLAVOR" | lzop \
> "$INITFS_PARTITION" > "$INITFS_PARTITION"
else else
ui_print "Flashing boot.img..." 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
fi fi
if [ "$FDE" = "true" ] if [ "$FDE" = "true" ]
then 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 "Do not forget to add a password to the LUKS partition!"
ui_print "Run the command: pmos_setpw from the terminal/adb shell!" ui_print "Run the command: pmos_setpw from the terminal/adb shell!"
fi fi

View file

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

View file

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

View file

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