Add install flag to generate separate boot and system images (#1442)
* Usage: pmbootstrap install --split * Make obvious that export is the next step when split images are created * Fix note for missing rootfs image on export * Change wording from "system image" to "rootfs image" * The idea was to show the note only when the rootfs image was not generated yet. But this was broken, because the path we checked for was missing the chroot path prefix (which is added now). * Also don't display the message, when the split image files exist
This commit is contained in:
parent
4e665a2190
commit
827a60cd25
|
@ -1,3 +1,4 @@
|
|||
import glob
|
||||
import logging
|
||||
import os
|
||||
|
||||
|
@ -13,10 +14,11 @@ def frontend(args):
|
|||
if not os.path.exists(target):
|
||||
pmb.helpers.run.user(args, ["mkdir", "-p", target])
|
||||
|
||||
# System image note
|
||||
img_path = "/home/pmos/rootfs/" + args.device + ".img"
|
||||
if not os.path.exists(args.work + "/chroot_native" + img_path):
|
||||
logging.info("NOTE: To export the system image, run 'pmbootstrap"
|
||||
# Rootfs image note
|
||||
chroot = args.work + "/chroot_native"
|
||||
pattern = chroot + "/home/pmos/rootfs/" + args.device + "*.img"
|
||||
if not glob.glob(pattern):
|
||||
logging.info("NOTE: To export the rootfs image, run 'pmbootstrap"
|
||||
" install' first (without the 'sdcard' parameter).")
|
||||
|
||||
# Rebuild the initramfs, just to make sure (see #69)
|
||||
|
|
|
@ -42,6 +42,8 @@ def symlinks(args, flavor, folder):
|
|||
"uImage-" + flavor: "Kernel, legacy u-boot image format",
|
||||
"vmlinuz-" + flavor: "Linux kernel",
|
||||
args.device + ".img": "Rootfs with partitions for /boot and /",
|
||||
args.device + "-boot.img": "Boot partition image",
|
||||
args.device + "-root.img": "Root partition image",
|
||||
"pmos-" + args.device + ".zip": "Android recovery flashable zip",
|
||||
}
|
||||
|
||||
|
@ -51,6 +53,8 @@ def symlinks(args, flavor, folder):
|
|||
path_buildroot = args.work + "/chroot_buildroot_" + args.deviceinfo["arch"]
|
||||
patterns = [path_boot + "/*-" + flavor,
|
||||
path_native + "/home/pmos/rootfs/" + args.device + ".img",
|
||||
path_native + "/home/pmos/rootfs/" + args.device + "-boot.img",
|
||||
path_native + "/home/pmos/rootfs/" + args.device + "-root.img",
|
||||
path_buildroot +
|
||||
"/var/lib/postmarketos-android-recovery-installer/pmos-" +
|
||||
args.device + ".zip"]
|
||||
|
|
|
@ -46,9 +46,9 @@ def mount_device_rootfs(args, suffix="native"):
|
|||
|
||||
def get_subpartitions_size(args):
|
||||
"""
|
||||
Calculate the size of the whole image and boot subpartition.
|
||||
Calculate the size of the boot and root subpartition.
|
||||
|
||||
:returns: (full, boot) the size of the full image and boot
|
||||
:returns: (boot, root) the size of the boot and root
|
||||
partition as integer in bytes
|
||||
"""
|
||||
# Calculate required sizes first
|
||||
|
@ -66,7 +66,7 @@ def get_subpartitions_size(args):
|
|||
full *= 1.20
|
||||
full += 50 * 1024 * 1024
|
||||
boot += 15 * 1024 * 1024
|
||||
return (full, boot)
|
||||
return (boot, full - boot)
|
||||
|
||||
|
||||
def get_nonfree_packages(args, device):
|
||||
|
@ -284,11 +284,13 @@ def install_system_image(args):
|
|||
# Partition and fill image/sdcard
|
||||
logging.info("*** (3/5) PREPARE INSTALL BLOCKDEVICE ***")
|
||||
pmb.chroot.shutdown(args, True)
|
||||
(size_image, size_boot) = get_subpartitions_size(args)
|
||||
(size_boot, size_root) = get_subpartitions_size(args)
|
||||
if not args.rsync:
|
||||
pmb.install.blockdevice.create(args, size_image)
|
||||
pmb.install.partition(args, size_boot)
|
||||
pmb.install.partitions_mount(args)
|
||||
pmb.install.blockdevice.create(args, size_boot, size_root)
|
||||
if not args.split:
|
||||
pmb.install.partition(args, size_boot)
|
||||
if not args.split:
|
||||
pmb.install.partitions_mount(args)
|
||||
|
||||
if args.full_disk_encryption:
|
||||
logging.info("WARNING: Full disk encryption is enabled!")
|
||||
|
@ -309,7 +311,7 @@ def install_system_image(args):
|
|||
pmb.chroot.shutdown(args, True)
|
||||
|
||||
# Convert system image to sparse using img2simg
|
||||
if args.deviceinfo["flash_sparse"] == "true":
|
||||
if args.deviceinfo["flash_sparse"] == "true" and not args.split:
|
||||
logging.info("(native) make sparse system image")
|
||||
pmb.chroot.apk.install(args, ["libsparse"])
|
||||
sys_image = args.device + ".img"
|
||||
|
@ -325,7 +327,7 @@ def install_system_image(args):
|
|||
" target device:")
|
||||
|
||||
# System flash information
|
||||
if not args.sdcard:
|
||||
if not args.sdcard and not args.split:
|
||||
logging.info("* pmbootstrap flasher flash_rootfs")
|
||||
logging.info(" Flashes the generated rootfs image to your device:")
|
||||
logging.info(" " + args.work + "/chroot_native/home/pmos/rootfs/" +
|
||||
|
@ -346,9 +348,14 @@ def install_system_image(args):
|
|||
" Use 'pmbootstrap flasher boot' to do that.)")
|
||||
|
||||
# Export information
|
||||
logging.info("* If the above steps do not work, you can also create"
|
||||
" symlinks to the generated files with 'pmbootstrap export'"
|
||||
" and flash outside of pmbootstrap.")
|
||||
if args.split:
|
||||
logging.info("* Boot and root image files have been generated, run"
|
||||
" 'pmbootstrap export' to create symlinks and flash"
|
||||
" outside of pmbootstrap.")
|
||||
else:
|
||||
logging.info("* If the above steps do not work, you can also create"
|
||||
" symlinks to the generated files with 'pmbootstrap export'"
|
||||
" and flash outside of pmbootstrap.")
|
||||
|
||||
|
||||
def install_recovery_zip(args):
|
||||
|
|
|
@ -70,56 +70,73 @@ def mount_sdcard(args):
|
|||
raise RuntimeError("Aborted.")
|
||||
|
||||
|
||||
def create_and_mount_image(args, size):
|
||||
def create_and_mount_image(args, size_boot, size_root):
|
||||
"""
|
||||
Create a new image file, and mount it as /dev/install.
|
||||
|
||||
:param size: of the whole image in bytes
|
||||
:param size_boot: size of the boot partition in bytes
|
||||
:param size_root: size of the root partition in bytes
|
||||
"""
|
||||
# Short variables for paths
|
||||
chroot = args.work + "/chroot_native"
|
||||
img_path = "/home/pmos/rootfs/" + args.device + ".img"
|
||||
img_path_outside = chroot + img_path
|
||||
img_path_prefix = "/home/pmos/rootfs/" + args.device
|
||||
img_path_full = img_path_prefix + ".img"
|
||||
img_path_boot = img_path_prefix + "-boot.img"
|
||||
img_path_root = img_path_prefix + "-root.img"
|
||||
|
||||
# Umount and delete existing image
|
||||
if os.path.exists(img_path_outside):
|
||||
pmb.helpers.mount.umount_all(args, chroot + "/mnt")
|
||||
pmb.install.losetup.umount(args, img_path)
|
||||
pmb.chroot.root(args, ["rm", img_path])
|
||||
if os.path.exists(img_path_outside):
|
||||
raise RuntimeError("Failed to remove old image file: " +
|
||||
img_path_outside)
|
||||
# Umount and delete existing images
|
||||
for img_path in [img_path_full, img_path_boot, img_path_root]:
|
||||
outside = chroot + img_path
|
||||
if os.path.exists(outside):
|
||||
pmb.helpers.mount.umount_all(args, chroot + "/mnt")
|
||||
pmb.install.losetup.umount(args, img_path)
|
||||
pmb.chroot.root(args, ["rm", img_path])
|
||||
|
||||
# Make sure there is enough free space
|
||||
size_mb = round(size / (1024**2))
|
||||
size_mb = round((size_boot + size_root) / (1024**2))
|
||||
disk_data = os.statvfs(args.work)
|
||||
free = round((disk_data.f_bsize * disk_data.f_bavail) / (1024**2))
|
||||
if size_mb > free:
|
||||
raise RuntimeError("Not enough free space to create rootfs image! (free: " + str(free) + "M, required: " + str(size_mb) + "M)")
|
||||
mb = str(size_mb) + "M"
|
||||
|
||||
# Create empty image file
|
||||
logging.info("(native) create " + args.device + ".img (" + mb + ")")
|
||||
# Create empty image files
|
||||
pmb.chroot.user(args, ["mkdir", "-p", "/home/pmos/rootfs"])
|
||||
pmb.chroot.root(args, ["truncate", "-s", mb, img_path])
|
||||
size_mb_full = str(size_mb) + "M"
|
||||
size_mb_boot = str(round(size_boot / (1024**2))) + "M"
|
||||
size_mb_root = str(round(size_root / (1024**2))) + "M"
|
||||
images = {img_path_full: size_mb_full}
|
||||
if args.split:
|
||||
images = {img_path_boot: size_mb_boot,
|
||||
img_path_root: size_mb_root}
|
||||
for img_path, size_mb in images.items():
|
||||
logging.info("(native) create " + os.path.basename(img_path) + " (" + size_mb + ")")
|
||||
pmb.chroot.root(args, ["truncate", "-s", size_mb, img_path])
|
||||
|
||||
# Mount to /dev/install
|
||||
logging.info("(native) mount /dev/install (" + args.device + ".img)")
|
||||
pmb.install.losetup.mount(args, img_path)
|
||||
device = pmb.install.losetup.device_by_back_file(args, img_path)
|
||||
pmb.helpers.mount.bind_blockdevice(args, device, args.work +
|
||||
"/chroot_native/dev/install")
|
||||
mount_image_paths = {img_path_full: "/dev/install"}
|
||||
if args.split:
|
||||
mount_image_paths = {img_path_boot: "/dev/installp1",
|
||||
img_path_root: "/dev/installp2"}
|
||||
|
||||
for img_path, mount_point in mount_image_paths.items():
|
||||
logging.info("(native) mount " + mount_point +
|
||||
" (" + os.path.basename(img_path) + ")")
|
||||
pmb.install.losetup.mount(args, img_path)
|
||||
device = pmb.install.losetup.device_by_back_file(args, img_path)
|
||||
pmb.helpers.mount.bind_blockdevice(args, device, args.work +
|
||||
"/chroot_native" + mount_point)
|
||||
|
||||
|
||||
def create(args, size):
|
||||
def create(args, size_boot, size_root):
|
||||
"""
|
||||
Create /dev/install (the "install blockdevice").
|
||||
|
||||
:param size: of the whole image in bytes
|
||||
:param size_boot: size of the boot partition in bytes
|
||||
:param size_root: size of the root partition in bytes
|
||||
"""
|
||||
pmb.helpers.mount.umount_all(
|
||||
args, args.work + "/chroot_native/dev/install")
|
||||
if args.sdcard:
|
||||
mount_sdcard(args)
|
||||
else:
|
||||
create_and_mount_image(args, size)
|
||||
create_and_mount_image(args, size_boot, size_root)
|
||||
|
|
|
@ -321,8 +321,14 @@ def arguments():
|
|||
# Action: install
|
||||
install = sub.add_parser("install", help="set up device specific" +
|
||||
" chroot and install to sdcard or image file")
|
||||
install.add_argument("--sdcard", help="path to the sdcard device,"
|
||||
" eg. /dev/mmcblk0")
|
||||
group = install.add_mutually_exclusive_group()
|
||||
group.add_argument("--sdcard", help="path to the sdcard device,"
|
||||
" eg. /dev/mmcblk0")
|
||||
group.add_argument("--split", help="install the boot and root partition"
|
||||
" in separated image files", action="store_true")
|
||||
group.add_argument("--android-recovery-zip",
|
||||
help="generate TWRP flashable zip",
|
||||
action="store_true", dest="android_recovery_zip")
|
||||
install.add_argument("--rsync", help="update the sdcard using rsync,"
|
||||
" only works with --no-fde", action="store_true")
|
||||
install.add_argument("--cipher", help="cryptsetup cipher used to"
|
||||
|
@ -337,9 +343,6 @@ def arguments():
|
|||
install.add_argument("--flavor",
|
||||
help="Specify kernel flavor to include in recovery"
|
||||
" flashable zip", default=None)
|
||||
install.add_argument("--android-recovery-zip",
|
||||
help="generate TWRP flashable zip",
|
||||
action="store_true", dest="android_recovery_zip")
|
||||
install.add_argument("--recovery-install-partition", default="system",
|
||||
help="partition to flash from recovery,"
|
||||
" eg. external_sd",
|
||||
|
|
Loading…
Reference in New Issue