pmbootstrap install --ondev: new option
Add initial support for the on-device installer in pmbootstrap. Let pmbootstrap create a regular split image, then prepare a new installer rootfs and copy the previously generated rootfs image into the installer rootfs. Put the installer rootfs into a new image, with reserved space. There is more to do from here, such as disabling the generation of the user account when using --ondev. But this requires support in postmarketos-ondev first, so let's build that iteratively. Related: https://wiki.postmarketos.org/wiki/On-device_installer Related: https://gitlab.com/postmarketOS/postmarketos-ondev/-/issues
This commit is contained in:
parent
8d0f3a1c55
commit
ed4072956d
|
@ -67,10 +67,11 @@ def shutdown(args, only_install_related=False):
|
|||
path = path_outside[len(chroot):]
|
||||
pmb.install.losetup.umount(args, path, auto_init=False)
|
||||
|
||||
# Umount device rootfs chroot
|
||||
chroot_rootfs = args.work + "/chroot_rootfs_" + args.device
|
||||
if os.path.exists(chroot_rootfs):
|
||||
pmb.helpers.mount.umount_all(args, chroot_rootfs)
|
||||
# Umount device rootfs and installer chroots
|
||||
for prefix in ["rootfs", "installer"]:
|
||||
path = f"{args.work}/chroot_{prefix}_{args.device}"
|
||||
if os.path.exists(path):
|
||||
pmb.helpers.mount.umount_all(args, path)
|
||||
|
||||
if not only_install_related:
|
||||
# Umount all folders inside args.work
|
||||
|
|
|
@ -53,6 +53,7 @@ def zap(args, confirm=True, dry=False, pkgs_local=False, http=False,
|
|||
patterns = [
|
||||
"chroot_native",
|
||||
"chroot_buildroot_*",
|
||||
"chroot_installer_*",
|
||||
"chroot_rootfs_*",
|
||||
]
|
||||
if pkgs_local:
|
||||
|
|
|
@ -204,6 +204,24 @@ def install(args):
|
|||
if args.rsync and not args.sdcard:
|
||||
raise ValueError("Installation using rsync only works on sdcard.")
|
||||
|
||||
# On-device installer checks
|
||||
# Note that this can't be in the mutually exclusive group that has most of
|
||||
# the conflicting options, because then it would not work with --sdcard.
|
||||
if args.on_device_installer:
|
||||
if args.full_disk_encryption:
|
||||
raise ValueError("--on-device-installer cannot be combined with"
|
||||
" --fde. The user can choose to encrypt their"
|
||||
" installation later in the on-device installer.")
|
||||
if args.android_recovery_zip:
|
||||
raise ValueError("--on-device-installer cannot be combined with"
|
||||
" --android-recovery-zip (patches welcome)")
|
||||
if args.no_image:
|
||||
raise ValueError("--on-device-installer cannot be combined with"
|
||||
" --no-image")
|
||||
if args.rsync:
|
||||
raise ValueError("--on-device-installer cannot be combined with"
|
||||
" --rsync")
|
||||
|
||||
if not args.sdcard and args.split is None:
|
||||
# Default to split if the flash method requires it
|
||||
flasher = pmb.config.flashers.get(args.deviceinfo["flash_method"], {})
|
||||
|
|
|
@ -11,6 +11,7 @@ import pmb.chroot.apk
|
|||
import pmb.chroot.other
|
||||
import pmb.chroot.initfs
|
||||
import pmb.config
|
||||
import pmb.config.pmaports
|
||||
import pmb.helpers.devices
|
||||
import pmb.helpers.run
|
||||
import pmb.install.blockdevice
|
||||
|
@ -500,6 +501,56 @@ def install_recovery_zip(args):
|
|||
logging.info("<https://postmarketos.org/recoveryzip>")
|
||||
|
||||
|
||||
def install_on_device_installer(args, step, steps):
|
||||
# Generate the rootfs image
|
||||
suffix_rootfs = f"rootfs_{args.device}"
|
||||
install_system_image(args, 0, suffix_rootfs, step=step, steps=steps,
|
||||
split=True)
|
||||
step += 2
|
||||
|
||||
# Prepare the installer chroot
|
||||
logging.info(f"*** ({step}/{steps}) CREATE ON-DEVICE INSTALLER ROOTFS ***")
|
||||
step += 1
|
||||
packages = ([f"device-{args.device}",
|
||||
"postmarketos-ondev"] +
|
||||
get_kernel_package(args, args.device) +
|
||||
get_nonfree_packages(args, args.device))
|
||||
suffix_installer = f"installer_{args.device}"
|
||||
pmb.chroot.apk.install(args, packages, suffix_installer)
|
||||
|
||||
# Move rootfs image into installer chroot
|
||||
img = f"{args.device}-root.img"
|
||||
img_path_src = f"{args.work}/chroot_native/home/pmos/rootfs/{img}"
|
||||
img_path_dest = f"{args.work}/chroot_{suffix_installer}/var/lib/rootfs.img"
|
||||
logging.info(f"({suffix_installer}) add {img} as /var/lib/rootfs.img")
|
||||
pmb.install.losetup.umount(args, img_path_src)
|
||||
pmb.helpers.run.root(args, ["mv", img_path_src, img_path_dest])
|
||||
|
||||
# Run ondev-prepare, so it may generate nice configs from the channel
|
||||
# properties (e.g. to display the version number), or transform the image
|
||||
# file into another format. This can all be done without pmbootstrap
|
||||
# changes in the postmarketos-ondev package.
|
||||
logging.info(f"({suffix_installer}) ondev-prepare-image")
|
||||
channel = pmb.config.pmaports.read_config(args)["channel"]
|
||||
channel_cfg = pmb.config.pmaports.read_config_channel(args)
|
||||
pmb.chroot.root(args, ["ondev-prepare", channel,
|
||||
channel_cfg["description"],
|
||||
channel_cfg["branch_pmaports"],
|
||||
channel_cfg["branch_aports"],
|
||||
channel_cfg["mirrordir_alpine"]], suffix_installer)
|
||||
|
||||
# Remove $DEVICE-boot.img (we will generate a new one if --split was
|
||||
# specified, otherwise the separate boot image is not needed)
|
||||
img_boot = f"{args.device}-boot.img"
|
||||
logging.info(f"(native) rm {img_boot}")
|
||||
pmb.chroot.root(args, ["rm", f"/home/pmos/rootfs/{img_boot}"])
|
||||
|
||||
# Generate installer image
|
||||
size_reserve = round(os.path.getsize(img_path_dest) / 1024 / 1024) + 200
|
||||
install_system_image(args, size_reserve, suffix_installer, "pmOS_install",
|
||||
step, steps, args.split, args.sdcard)
|
||||
|
||||
|
||||
def install(args):
|
||||
# Sanity checks
|
||||
if not args.android_recovery_zip and args.sdcard:
|
||||
|
@ -510,6 +561,8 @@ def install(args):
|
|||
steps = 2
|
||||
elif args.android_recovery_zip:
|
||||
steps = 4
|
||||
elif args.on_device_installer:
|
||||
steps = 8
|
||||
else:
|
||||
steps = 5
|
||||
|
||||
|
@ -572,6 +625,10 @@ def install(args):
|
|||
elif args.android_recovery_zip:
|
||||
return install_recovery_zip(args)
|
||||
|
||||
install_system_image(args, 0, f"rootfs_{args.device}", split=args.split,
|
||||
sdcard=args.sdcard)
|
||||
print_flash_info(args)
|
||||
if args.on_device_installer:
|
||||
# Runs install_system_image twice
|
||||
install_on_device_installer(args, 3, steps)
|
||||
else:
|
||||
install_system_image(args, 0, f"rootfs_{args.device}",
|
||||
split=args.split, sdcard=args.sdcard)
|
||||
print_flash_info(args, steps)
|
||||
|
|
|
@ -25,7 +25,7 @@ def alpine_native():
|
|||
def from_chroot_suffix(args, suffix):
|
||||
if suffix == "native":
|
||||
return args.arch_native
|
||||
if suffix == "rootfs_" + args.device:
|
||||
if suffix in [f"rootfs_{args.device}", f"installer_{args.device}"]:
|
||||
return args.deviceinfo["arch"]
|
||||
if suffix.startswith("buildroot_"):
|
||||
return suffix.split("_", 1)[1]
|
||||
|
|
|
@ -557,6 +557,11 @@ def arguments():
|
|||
install.add_argument("--no-base",
|
||||
help="do not install postmarketos-base (advanced)",
|
||||
action="store_false", dest="install_base")
|
||||
install.add_argument("--on-device-installer", "--ondev",
|
||||
action="store_true",
|
||||
help="wrap the resulting image in a graphical"
|
||||
" on-device installer, so the installation can"
|
||||
" be customized after flashing")
|
||||
group = install.add_mutually_exclusive_group()
|
||||
group.add_argument("--sparse", help="generate sparse image file"
|
||||
" (even if unsupported by device)", default=None,
|
||||
|
|
Loading…
Reference in New Issue