diff --git a/pmb/helpers/frontend.py b/pmb/helpers/frontend.py index 311576d0..604c29c3 100644 --- a/pmb/helpers/frontend.py +++ b/pmb/helpers/frontend.py @@ -227,6 +227,8 @@ def install(args): if not args.ondev_rootfs: raise ValueError("--no-rootfs can only be combined with --ondev." " Do you mean --no-image?") + if args.ondev_cp: + raise ValueError("--cp can only be combined with --ondev") # On-device installer overrides if args.on_device_installer: diff --git a/pmb/install/_install.py b/pmb/install/_install.py index 8369c69d..308619e3 100644 --- a/pmb/install/_install.py +++ b/pmb/install/_install.py @@ -637,6 +637,14 @@ def install_on_device_installer(args, step, steps): "ONDEV_UI": args.ui} pmb.chroot.root(args, ["ondev-prepare"], suffix_installer, env=env) + # Copy files specified with 'pmbootstrap install --ondev --cp' + if args.ondev_cp: + for host_src, chroot_dest in args.ondev_cp: + host_dest = f"{args.work}/chroot_{suffix_installer}/{chroot_dest}" + logging.info(f"({suffix_installer}) add {host_src} as" + f" {chroot_dest}") + pmb.helpers.run.root(args, ["cp", host_src, host_dest]) + # Remove $DEVICE-boot.img (we will generate a new one if --split was # specified, otherwise the separate boot image is not needed) if args.ondev_rootfs: diff --git a/pmb/parse/arguments.py b/pmb/parse/arguments.py index 7ff0d1b1..d1d5d6ff 100644 --- a/pmb/parse/arguments.py +++ b/pmb/parse/arguments.py @@ -2,6 +2,7 @@ # SPDX-License-Identifier: GPL-3.0-or-later import argparse import copy +import os try: import argcomplete @@ -22,6 +23,29 @@ import pmb.helpers.pmaports See pmb/helpers/args.py for more information about the args variable. """ +def type_ondev_cp(val): + """ Parse and validate arguments to 'pmbootstrap install --ondev --cp'. + + :param val: 'HOST_SRC:CHROOT_DEST' string + :returns: (HOST_SRC, CHROOT_DEST) """ + ret = val.split(":") + + if len(ret) != 2: + raise argparse.ArgumentTypeError("does not have HOST_SRC:CHROOT_DEST" + f" format: {val}") + host_src = ret[0] + if not os.path.exists(host_src): + raise argparse.ArgumentTypeError(f"HOST_SRC not found: {host_src}") + if not os.path.isfile(host_src): + raise argparse.ArgumentTypeError(f"HOST_SRC is not a file: {host_src}") + + chroot_dest = ret[1] + if not chroot_dest.startswith("/"): + raise argparse.ArgumentTypeError("CHROOT_DEST must start with '/':" + f" {chroot_dest}") + return ret + + def arguments_install(subparser): ret = subparser.add_parser("install", help="set up device specific" " chroot and install to SD card or image file") @@ -119,6 +143,10 @@ def arguments_install(subparser): group.add_argument("--no-rootfs", dest="ondev_rootfs", help="do not generate the postmarketOS rootfs to be" " installed", action="store_false") + group.add_argument("--cp", dest="ondev_cp", nargs="+", + metavar="HOST_SRC:CHROOT_DEST", type=type_ondev_cp, + help="copy one or more files from the host system path" + " HOST_SRC to the target path CHROOT_DEST") def arguments_export(subparser):