Add support for isorec flashing in recovery installer (#609)

This commit is contained in:
Attila Szöllősi 2017-09-29 00:05:00 +02:00 committed by Oliver Smith
parent 9c4c1e9575
commit 3cbd0d19c2
11 changed files with 135 additions and 68 deletions

View File

@ -1,10 +1,10 @@
pkgname=postmarketos-android-recovery-installer
pkgver=0.0.2
pkgver=0.0.3
pkgrel=1
pkgdesc="TWRP compatible postmarketOS installer script"
url="https://github.com/postmarketOS"
# multipath-tools: kpartx
depends="busybox-extras lddtree cryptsetup multipath-tools device-mapper parted zip"
depends="busybox-extras lddtree cryptsetup multipath-tools device-mapper parted util-linux zip"
source="build_zip.sh
update-binary
pmos_install
@ -26,8 +26,8 @@ package() {
done
mkdir "$pkgdir/var/lib/postmarketos-android-recovery-installer/lib/"
}
sha512sums="4e4f56c84b404c53c3835304e8f7b651d6dbf19a653358daa6be1cc47e23360cb1dabb1331c13dd288fabb8eabaf8a01d094f054c334a156ca79f03948c9a17f build_zip.sh
22083b3c776ae2e3e098dc8d9c4e085e7aae543aef20b42732c6750608e22c69211e199b946d55581403b71eb78e6508f618128122058a59466ad8a632e46ed8 update-binary
446d0d00322c92a5af7e5be340e9f185ef41eaa9cf6df4f5b29f3437dfcf45e0bc5e845c1c5a864694f8e89efd1a30e5e615b7ccfff1b7a0571dfb6f1f5cf3e5 pmos_install
152bcf1375cff515205af2427e537ae8536537f3ce7cbcbe7b848496be5af45baa149fe676c2d4979dcef017b843280752d35587b1e81905fa6daa2444e037c8 pmos_install_functions
sha512sums="d065577f587ee604cfa635c3eaba5c856800e9dafbbab65d4311dc89b72feab131fc23605bc0a344979f0760162bc509ac2056ee3c4d3e78e56be15032e314c1 build_zip.sh
156f889593d82d4b1c88f3873299fc054e70e78bf26af37af4dd7770ed31a0a581f2cf03cad9e11a60159f424d2d3869fd6cd28600ad305469ddf01eaff49f6c update-binary
bc60b75dcd499084d66453c9f9beb989ad386a4bb394d0018982dc16e4f23f05c2b3308119fc513a3a391d7878047e65f46557b214a543a6a4cdfd92f6f7cf5a pmos_install
b4c669ab6dfe330a30c575f864cea916ac357ae96547c2296d1b5399669c6f49570c60554985d2939a1d3e3cb464e3229e2b4724eba1dd5d920dcec1b0f7f0e3 pmos_install_functions
27dd89aa8471349995a1cbbc1034ead662a0d1dd70ca5490f3191ceaaeb853331003c20ffddbbd95fe822135a85c1beb1e2a32bb33b10c2a4177b30347a40555 pmos_setpw"

View File

@ -43,7 +43,7 @@ check_whether_exists()
# shellcheck disable=SC1091
. ./install_options
BINARIES="/sbin/cryptsetup /sbin/kpartx /usr/sbin/parted /usr/sbin/partprobe"
BINARIES="/sbin/cryptsetup /sbin/kpartx /usr/sbin/parted /usr/sbin/partprobe /sbin/findfs"
# shellcheck disable=SC2086
LIBRARIES=$(lddtree -l $BINARIES | awk '/lib/ {print}' | sort -u)
copy_files "$BINARIES" bin/

View File

@ -52,15 +52,17 @@ ui_print " "
ui_print "postmarketOS recovery installer "
ui_print " "
ui_print "Extracting partition info from fstab..."
extract_partition_table
ui_print "Entering working directory..."
cd "$WORKING_DIR"
ui_print "Extracting files..."
unzip -o "$ZIP"
busybox unzip -o "$ZIP"
mkdir /lib
ui_print "Symlinking .so files to /lib/..."
ln -s "$WORKING_DIR"/lib/* /lib/
ui_print "Symlinking block devices..."
ln -s /dev/block/* /dev/
ui_print "Extracting partition table..."
extract_partition_table
ui_print "Unmounting /$INSTALL_PARTITION..."
umount_install_partition
ui_print "Creating partition table on $INSTALL_DEVICE..."
@ -69,7 +71,7 @@ partition_install_device || :
if [ "$FDE" = "true" ]
then
ui_print "Generating temporary keyfile with random data..."
dd bs=512 count=4 if=/dev/urandom of="$WORKING_DIR"/lukskey
busybox dd bs=512 count=4 if=/dev/urandom of="$WORKING_DIR"/lukskey
ui_print "Initializing LUKS device..."
cryptsetup luksFormat --use-urandom -c "$CIPHER" -q "$ROOT_PARTITION" "$WORKING_DIR"/lukskey
ui_print "Opening LUKS partition..."
@ -96,10 +98,19 @@ mount -t ext2 -rw "$PMOS_BOOT" /"$INSTALL_PARTITION"/boot || {
}
ui_print "Installing rootfs..."
tar -xf rootfs.tar.gz -C /"$INSTALL_PARTITION"
if [ "$FLASH_BOOTIMG" = "true" ]
if [ "$FLASH_KERNEL" = "true" ]
then
ui_print "Flashing boot.img..."
dd if=boot.img of="$BOOT"
if [ "$ISOREC" = "true" ]
then
ui_print "Flashing kernel..."
busybox dd if=/"$INSTALL_PARTITION"/boot/vmlinuz-"$FLAVOR" of="$KERNEL_PARTITION"
ui_print "Flashing initfs..."
busybox gunzip -c /"$INSTALL_PARTITION"/boot/initramfs-"$FLAVOR" | busybox lzop \
> "$INITFS_PARTITION"
else
ui_print "Flashing boot.img..."
busybox dd if=/"$INSTALL_PARTITION"/boot/boot.img-"$FLAVOR" of="$BOOT_PARTITION"
fi
fi
if [ "$FDE" = "true" ]
then

View File

@ -23,6 +23,10 @@ export ZIP=$2
export WORKING_DIR="/tmp/postmarketos"
export PATH=$PATH:"$WORKING_DIR"/bin
# Use findfs from util-linux
# shellcheck disable=SC2139
alias findfs="$WORKING_DIR/bin/findfs"
# shellcheck source=/dev/null
. "$WORKING_DIR"/install_options
@ -36,11 +40,12 @@ ui_print() {
extract_partition_table() {
case "$INSTALL_PARTITION" in
"system")
# We need to resolve symlinks, to make set_subpartitions() work.
_INSTALL_DEVICE=$(readlink -fn "$(awk '/^\/system/ {print $3}' /etc/recovery.fstab)")
_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)")
;;
"external_sd")
_INSTALL_DEVICE=$(readlink -fn "$(awk '/^\/external_sd/ {print $4}' /etc/recovery.fstab)")
_INSTALL_DEVICE=$(busybox readlink -fn "$(awk '/^\/external_sd/ {print $4}' /etc/recovery.fstab)")
;;
*)
echo "No support for flashing $INSTALL_PARTITION."
@ -52,17 +57,26 @@ extract_partition_table() {
echo "install device found at $_INSTALL_DEVICE"
export INSTALL_DEVICE=$_INSTALL_DEVICE
else
echo "Couldn't find /$INSTALL_PARTITION/ in fstab."
echo "Couldn't find $INSTALL_PARTITION partition."
return 1
fi
_BOOT=$(awk '/^\/boot/ {print $3}' /etc/recovery.fstab)
if [ ! -z "$_BOOT" ]
if [ "$ISOREC" = "true" ]
then
echo "boot partition found at $_BOOT"
export BOOT=$_BOOT
export KERNEL_PARTITION
KERNEL_PARTITION=$(findfs PARTLABEL="$KERNEL_PARTLABEL")
export INITFS_PARTITION
INITFS_PARTITION=$(findfs PARTLABEL="$INITFS_PARTLABEL")
else
echo "Couldn't find /boot/ in fstab."
return 1
_BOOT_PARTITION=$(findfs PARTLABEL="boot") || \
_BOOT_PARTITION=$(awk '/^\/boot/ {print $3}' /etc/recovery.fstab)
if [ ! -z "$_BOOT_PARTITION" ]
then
echo "boot partition found at $_BOOT_PARTITION"
export BOOT_PARTITION=$_BOOT_PARTITION
else
echo "Couldn't find boot partition."
return 1
fi
fi
}
@ -78,18 +92,19 @@ partition_install_device() {
if [ "$INSTALL_PARTITION" = "system" ]
then
kpartx -afs "$INSTALL_DEVICE"
ln -s /dev/mapper/* /dev/block/
fi
set_subpartitions
}
set_subpartitions() {
export PMOS_BOOT="$INSTALL_DEVICE"p1
export ROOT_PARTITION="$INSTALL_DEVICE"p2
export PMOS_BOOT
PMOS_BOOT=/dev/mapper/"$(busybox basename "$INSTALL_DEVICE")"p1
export ROOT_PARTITION
ROOT_PARTITION=/dev/mapper/"$(busybox basename "$INSTALL_DEVICE")"p2
}
umount_install_partition() {
if mountpoint -q "/$INSTALL_PARTITION/"
if busybox mountpoint -q "/$INSTALL_PARTITION/"
then
umount /"$INSTALL_PARTITION"/
else

View File

@ -28,5 +28,5 @@ fail_info() {
# Create working directory
mkdir /tmp/postmarketos/
# Extract and start the installer script
unzip "$3" "bin/pmos_install" "bin/pmos_install_functions" "install_options" -d /tmp/postmarketos/
busybox unzip "$3" "bin/pmos_install" "bin/pmos_install_functions" "install_options" -d /tmp/postmarketos/
/tmp/postmarketos/bin/pmos_install "$2" "$3" || { fail_info ; exit 1 ; }

View File

@ -18,4 +18,5 @@ along with pmbootstrap. If not, see <http://www.gnu.org/licenses/>.
"""
from pmb.flasher.init import init
from pmb.flasher.run import run
from pmb.flasher.variables import variables
from pmb.flasher.frontend import frontend

View File

@ -79,6 +79,12 @@ def list_devices(args):
def sideload(args):
method = args.flash_method or args.deviceinfo["flash_methods"]
cfg = pmb.config.flashers[method]
# Install depends
pmb.chroot.apk.install(args, cfg["depends"])
# Mount the buildroot
suffix = "buildroot_" + args.deviceinfo["arch"]
mountpoint = "/mnt/" + suffix

View File

@ -30,30 +30,8 @@ def run(args, action, flavor=None):
raise RuntimeError("action " + action + " is not"
" configured for method " + method + "!")
_cmdline = args.deviceinfo["kernel_cmdline"]
if "cmdline" in args and args.cmdline:
_cmdline = args.cmdline
if method == "fastboot":
_partition_system = "system"
else:
_partition_system = args.deviceinfo["flash_heimdall_partition_system"] or "SYSTEM"
if "partition" in args and args.partition:
_partition_system = args.partition
# Variable setup
vars = {
"$BOOT": "/mnt/rootfs_" + args.device + "/boot",
"$FLAVOR": flavor if flavor is not None else "",
"$IMAGE": "/home/user/rootfs/" + args.device + ".img",
"$KERNEL_CMDLINE": _cmdline,
"$PARTITION_KERNEL": args.deviceinfo["flash_heimdall_partition_kernel"] or "KERNEL",
"$PARTITION_INITFS": args.deviceinfo["flash_heimdall_partition_initfs"] or "RECOVERY",
"$PARTITION_SYSTEM": _partition_system,
"$RECOVERY_ZIP": "/mnt/buildroot_" + args.deviceinfo["arch"] +
"/var/lib/postmarketos-android-recovery-installer"
"/pmos-" + args.device + ".zip",
}
vars = pmb.flasher.variables(args, flavor, method)
# Run the commands of each action
for command in cfg["actions"][action]:

46
pmb/flasher/variables.py Normal file
View File

@ -0,0 +1,46 @@
"""
Copyright 2017 Oliver Smith
This file is part of pmbootstrap.
pmbootstrap is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
pmbootstrap is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with pmbootstrap. If not, see <http://www.gnu.org/licenses/>.
"""
def variables(args, flavor, method):
_cmdline = args.deviceinfo["kernel_cmdline"]
if "cmdline" in args and args.cmdline:
_cmdline = args.cmdline
if method == "fastboot":
_partition_system = "system"
else:
_partition_system = args.deviceinfo["flash_heimdall_partition_system"] or "SYSTEM"
if "partition" in args and args.partition:
_partition_system = args.partition
vars = {
"$BOOT": "/mnt/rootfs_" + args.device + "/boot",
"$FLAVOR": flavor if flavor is not None else "",
"$IMAGE": "/home/user/rootfs/" + args.device + ".img",
"$KERNEL_CMDLINE": _cmdline,
"$PARTITION_KERNEL": args.deviceinfo["flash_heimdall_partition_kernel"] or "KERNEL",
"$PARTITION_INITFS": args.deviceinfo["flash_heimdall_partition_initfs"] or "RECOVERY",
"$PARTITION_SYSTEM": _partition_system,
"$RECOVERY_ZIP": "/mnt/buildroot_" + args.deviceinfo["arch"] +
"/var/lib/postmarketos-android-recovery-installer"
"/pmos-" + args.device + ".zip",
}
return vars

View File

@ -19,6 +19,7 @@ along with pmbootstrap. If not, see <http://www.gnu.org/licenses/>.
import logging
import pmb.chroot
import pmb.flasher
import pmb.helpers.frontend
@ -29,6 +30,8 @@ def create_zip(args, suffix):
zip_root = "/var/lib/postmarketos-android-recovery-installer/"
rootfs = "/mnt/rootfs_" + args.device
flavor = pmb.helpers.frontend._parse_flavor(args)
method = args.deviceinfo["flash_methods"]
vars = pmb.flasher.variables(args, flavor, method)
# Install recovery installer package in buildroot
pmb.chroot.apk.install(args,
@ -38,23 +41,30 @@ def create_zip(args, suffix):
logging.info("(" + suffix + ") create recovery zip")
# Create config file for the recovery installer
with open(args.work + "/chroot_" + suffix + "/tmp/install_options",
"w") as install_options:
install_options.write(
"\n".join(['DEVICE="{}"'.format(args.device),
'FLASH_BOOTIMG="{}"'.format(
str(args.recovery_flash_bootimg).lower()),
'INSTALL_PARTITION="{}"'.format(
args.recovery_install_partition),
'CIPHER="{}"'.format(args.cipher),
'FDE="{}"'.format(
str(args.full_disk_encryption).lower())]))
options = {
"DEVICE": args.device,
"FLAVOR": flavor,
"FLASH_KERNEL": args.recovery_flash_kernel,
"ISOREC": method == "heimdall-isorec",
"KERNEL_PARTLABEL": vars["$PARTITION_KERNEL"],
"INITFS_PARTLABEL": vars["$PARTITION_INITFS"],
"SYSTEM_PARTLABEL": vars["$PARTITION_SYSTEM"],
"INSTALL_PARTITION": args.recovery_install_partition,
"CIPHER": args.cipher,
"FDE": args.full_disk_encryption,
}
# Write to a temporary file
config_temp = args.work + "/chroot_" + suffix + "/tmp/install_options"
with open(config_temp, "w") as handle:
for key, value in options.items():
if isinstance(value, bool):
value = str(value).lower()
handle.write(key + "='" + value + "'\n")
commands = [
# Move config file from /tmp/ to zip root
["mv", "/tmp/install_options", "install_options"],
# Copy boot.img to zip root
["cp", rootfs + "/boot/boot.img-" + flavor, "boot.img"],
# Create tar archive of the rootfs
["tar", "-pczf", "rootfs.tar.gz", "--exclude", "./home/user/*",
"-C", rootfs, "."],

View File

@ -216,13 +216,13 @@ def arguments():
install.add_argument("--android-recovery-zip",
help="generate TWRP flashable zip",
action="store_true", dest="android_recovery_zip")
install.add_argument("--recovery-flash-bootimg",
help="include kernel in recovery flashable zip",
action="store_true", dest="recovery_flash_bootimg")
install.add_argument("--recovery-install-partition", default="system",
help="partition to flash from recovery,"
" eg. external_sd",
dest="recovery_install_partition")
install.add_argument("--recovery-no-kernel",
help="do not overwrite the existing kernel",
action="store_false", dest="recovery_flash_kernel")
# Action: menuconfig / parse_apkbuild
menuconfig = sub.add_parser("menuconfig", help="run menuconfig on"