mirror of
https://gitlab.postmarketos.org/postmarketOS/pmbootstrap.git
synced 2025-07-20 19:15:08 +03:00
remove ondev support
The on-device installer has been unsupported for a while, start removing it from pmbootstrap to simplify the partitioning code, for example we no longer need to support having some "reserved" space in the rootfs. This follows various discussions which essentially indicated that future on device installation methods will take a different approach which will not require bespoke partitioning. Signed-off-by: Casey Connolly <kcxt@postmarketos.org>
This commit is contained in:
parent
08148a6e5d
commit
13f4c415d2
6 changed files with 31 additions and 319 deletions
|
@ -84,26 +84,6 @@ def _parse_suffix(args: PmbArgs) -> Chroot:
|
||||||
return Chroot(ChrootType.NATIVE)
|
return Chroot(ChrootType.NATIVE)
|
||||||
|
|
||||||
|
|
||||||
def _install_ondev_verify_no_rootfs(device: str, ondev_cp: list[tuple[str, str]]) -> None:
|
|
||||||
chroot_dest = "/var/lib/rootfs.img"
|
|
||||||
dest = Chroot(ChrootType.INSTALLER, device) / chroot_dest
|
|
||||||
if dest.exists():
|
|
||||||
return
|
|
||||||
|
|
||||||
if ondev_cp:
|
|
||||||
for _, chroot_dest_cp in ondev_cp:
|
|
||||||
if chroot_dest_cp == chroot_dest:
|
|
||||||
return
|
|
||||||
|
|
||||||
raise ValueError(
|
|
||||||
f"--no-rootfs set, but rootfs.img not found in install"
|
|
||||||
" chroot. Either run 'pmbootstrap install' without"
|
|
||||||
" --no-rootfs first to let it generate the postmarketOS"
|
|
||||||
" rootfs once, or supply a rootfs file with:"
|
|
||||||
f" --cp os.img:{chroot_dest}"
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def build(args: PmbArgs) -> None:
|
def build(args: PmbArgs) -> None:
|
||||||
# Strict mode: zap everything
|
# Strict mode: zap everything
|
||||||
if args.strict:
|
if args.strict:
|
||||||
|
@ -316,55 +296,6 @@ def install(args: PmbArgs) -> None:
|
||||||
if args.rsync and args.filesystem == "btrfs":
|
if args.rsync and args.filesystem == "btrfs":
|
||||||
raise ValueError("Installation using rsync is not currently supported on btrfs filesystem.")
|
raise ValueError("Installation using rsync is not currently supported on btrfs filesystem.")
|
||||||
|
|
||||||
# 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 --disk.
|
|
||||||
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 args.filesystem:
|
|
||||||
raise ValueError("--on-device-installer cannot be combined with --filesystem")
|
|
||||||
|
|
||||||
if deviceinfo.cgpt_kpart:
|
|
||||||
raise ValueError("--on-device-installer cannot be used with ChromeOS devices")
|
|
||||||
else:
|
|
||||||
if args.ondev_cp:
|
|
||||||
raise ValueError("--cp can only be combined with --ondev")
|
|
||||||
if args.ondev_no_rootfs:
|
|
||||||
raise ValueError(
|
|
||||||
"--no-rootfs can only be combined with --ondev. Do you mean --no-image?"
|
|
||||||
)
|
|
||||||
if args.ondev_no_rootfs:
|
|
||||||
_install_ondev_verify_no_rootfs(device, args.ondev_cp)
|
|
||||||
|
|
||||||
# On-device installer overrides
|
|
||||||
if args.on_device_installer:
|
|
||||||
# To make code for the on-device installer not needlessly complex, just
|
|
||||||
# hardcode "user" as username here. (The on-device installer will set
|
|
||||||
# a password for the user, disable SSH password authentication,
|
|
||||||
# optionally add a new user for SSH that must not have the same
|
|
||||||
# username etc.)
|
|
||||||
if config.user != "user":
|
|
||||||
logging.warning(
|
|
||||||
f"WARNING: custom username '{config.user}' will be"
|
|
||||||
" replaced with 'user' for the on-device"
|
|
||||||
" installer."
|
|
||||||
)
|
|
||||||
config.user = "user"
|
|
||||||
|
|
||||||
if not args.disk and args.split is None:
|
if not args.disk and args.split is None:
|
||||||
# Default to split if the flash method requires it
|
# Default to split if the flash method requires it
|
||||||
flasher = pmb.config.flashers.get(deviceinfo.flash_method, {})
|
flasher = pmb.config.flashers.get(deviceinfo.flash_method, {})
|
||||||
|
@ -392,20 +323,6 @@ def install(args: PmbArgs) -> None:
|
||||||
" --fde --android-recovery-zip'."
|
" --fde --android-recovery-zip'."
|
||||||
)
|
)
|
||||||
|
|
||||||
# Don't install locally compiled packages and package signing keys
|
|
||||||
if not args.install_local_pkgs:
|
|
||||||
# Implies that we don't build outdated packages (overriding the answer
|
|
||||||
# in 'pmbootstrap init')
|
|
||||||
config.build_pkgs_on_install = False
|
|
||||||
|
|
||||||
# Safest way to avoid installing local packages is having none
|
|
||||||
if list((config.work / "packages").glob("*")):
|
|
||||||
raise ValueError(
|
|
||||||
"--no-local-pkgs specified, but locally built"
|
|
||||||
" packages found. Consider 'pmbootstrap zap -p'"
|
|
||||||
" to delete them."
|
|
||||||
)
|
|
||||||
|
|
||||||
# Verify that the root filesystem is supported by current pmaports branch
|
# Verify that the root filesystem is supported by current pmaports branch
|
||||||
pmb.install.get_root_filesystem(args)
|
pmb.install.get_root_filesystem(args)
|
||||||
|
|
||||||
|
|
|
@ -278,7 +278,6 @@ def setup_login(args: PmbArgs, config: Config, chroot: Chroot) -> None:
|
||||||
:param suffix: of the chroot, where passwd will be execute (either the
|
:param suffix: of the chroot, where passwd will be execute (either the
|
||||||
rootfs_{args.device} or installer_{args.device}
|
rootfs_{args.device} or installer_{args.device}
|
||||||
"""
|
"""
|
||||||
if not args.on_device_installer:
|
|
||||||
# User password
|
# User password
|
||||||
logging.info(f" *** SET LOGIN PASSWORD FOR: '{config.user}' ***")
|
logging.info(f" *** SET LOGIN PASSWORD FOR: '{config.user}' ***")
|
||||||
if args.password:
|
if args.password:
|
||||||
|
@ -492,25 +491,14 @@ def print_sshd_info(args: PmbArgs) -> None:
|
||||||
logging.info("") # make the note stand out
|
logging.info("") # make the note stand out
|
||||||
logging.info("*** SSH DAEMON INFORMATION ***")
|
logging.info("*** SSH DAEMON INFORMATION ***")
|
||||||
|
|
||||||
if not args.ondev_no_rootfs:
|
|
||||||
if args.no_sshd:
|
if args.no_sshd:
|
||||||
logging.info("SSH daemon is disabled (--no-sshd).")
|
logging.info("SSH daemon is disabled (--no-sshd).")
|
||||||
else:
|
else:
|
||||||
logging.info("SSH daemon is enabled (disable with --no-sshd).")
|
logging.info("SSH daemon is enabled (disable with --no-sshd).")
|
||||||
logging.info(
|
logging.info(
|
||||||
f"Login as '{get_context().config.user}' with the password given"
|
f"Login as '{get_context().config.user}' with the password given during installation."
|
||||||
" during installation."
|
|
||||||
)
|
)
|
||||||
|
|
||||||
if args.on_device_installer:
|
|
||||||
# We don't disable sshd in the installer OS. If the device is reachable
|
|
||||||
# on the network by default (e.g. Raspberry Pi), one can lock down the
|
|
||||||
# installer OS down by disabling the debug user (see wiki page).
|
|
||||||
logging.info(
|
|
||||||
"SSH daemon is enabled in the installer OS, to allow debugging the installer image."
|
|
||||||
)
|
|
||||||
logging.info("More info: https://postmarketos.org/ondev-debug")
|
|
||||||
|
|
||||||
|
|
||||||
def disable_service_systemd(chroot: Chroot, service_name: str) -> None:
|
def disable_service_systemd(chroot: Chroot, service_name: str) -> None:
|
||||||
preset = f"/usr/lib/systemd/system-preset/80-pmbootstrap-install-disable-{service_name}.preset"
|
preset = f"/usr/lib/systemd/system-preset/80-pmbootstrap-install-disable-{service_name}.preset"
|
||||||
|
@ -753,27 +741,8 @@ def sanity_check_disk_size(args: PmbArgs) -> None:
|
||||||
raise RuntimeError("Aborted.")
|
raise RuntimeError("Aborted.")
|
||||||
|
|
||||||
|
|
||||||
def get_ondev_pkgver(args: PmbArgs) -> str:
|
def get_partition_layout(kernel: bool) -> PartitionLayout:
|
||||||
arch = pmb.parse.deviceinfo().arch
|
|
||||||
package = pmb.helpers.package.get("postmarketos-ondev", arch)
|
|
||||||
return package.version.split("-r")[0]
|
|
||||||
|
|
||||||
|
|
||||||
def sanity_check_ondev_version(args: PmbArgs) -> None:
|
|
||||||
ver_pkg = get_ondev_pkgver(args)
|
|
||||||
ver_min = pmb.config.ondev_min_version
|
|
||||||
if pmb.parse.version.compare(ver_pkg, ver_min) == -1:
|
|
||||||
raise RuntimeError(
|
|
||||||
"This version of pmbootstrap requires"
|
|
||||||
f" postmarketos-ondev version {ver_min} or"
|
|
||||||
" higher. The postmarketos-ondev found in pmaports"
|
|
||||||
f" / in the binary packages has version {ver_pkg}."
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def get_partition_layout(reserve: bool | int, kernel: bool) -> PartitionLayout:
|
|
||||||
"""
|
"""
|
||||||
:param reserve: create an empty partition between root and boot (pma#463)
|
|
||||||
:param kernel: create a separate kernel partition before all other
|
:param kernel: create a separate kernel partition before all other
|
||||||
partitions, e.g. for the ChromeOS devices with cgpt
|
partitions, e.g. for the ChromeOS devices with cgpt
|
||||||
:returns: the partition layout, e.g. without reserve and kernel:
|
:returns: the partition layout, e.g. without reserve and kernel:
|
||||||
|
@ -843,11 +812,6 @@ def create_fstab(args: PmbArgs, layout: PartitionLayout | None, chroot: Chroot)
|
||||||
:param chroot: of the chroot, which fstab will be created to
|
:param chroot: of the chroot, which fstab will be created to
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# Do not install fstab into target rootfs when using on-device
|
|
||||||
# installer. Provide fstab only to installer suffix
|
|
||||||
if args.on_device_installer and chroot.type == ChrootType.ROOTFS:
|
|
||||||
return
|
|
||||||
|
|
||||||
if layout:
|
if layout:
|
||||||
boot_dev = Path(f"/dev/installp{layout['boot']}")
|
boot_dev = Path(f"/dev/installp{layout['boot']}")
|
||||||
root_dev = Path(f"/dev/installp{layout['root']}")
|
root_dev = Path(f"/dev/installp{layout['root']}")
|
||||||
|
@ -894,7 +858,6 @@ def create_fstab(args: PmbArgs, layout: PartitionLayout | None, chroot: Chroot)
|
||||||
|
|
||||||
def install_system_image(
|
def install_system_image(
|
||||||
args: PmbArgs,
|
args: PmbArgs,
|
||||||
size_reserve: int,
|
|
||||||
chroot: Chroot,
|
chroot: Chroot,
|
||||||
step: int,
|
step: int,
|
||||||
steps: int,
|
steps: int,
|
||||||
|
@ -928,12 +891,12 @@ def install_system_image(
|
||||||
else:
|
else:
|
||||||
layout = None
|
layout = None
|
||||||
if not args.rsync:
|
if not args.rsync:
|
||||||
pmb.install.blockdevice.create(args, size_boot, size_root, size_reserve, split, disk)
|
pmb.install.blockdevice.create(args, size_boot, size_root, split, disk)
|
||||||
if not split and layout:
|
if not split and layout:
|
||||||
if pmb.parse.deviceinfo().cgpt_kpart and args.install_cgpt:
|
if pmb.parse.deviceinfo().cgpt_kpart and args.install_cgpt:
|
||||||
pmb.install.partition_cgpt(layout, size_boot, size_reserve)
|
pmb.install.partition_cgpt(layout, size_boot)
|
||||||
else:
|
else:
|
||||||
pmb.install.partition(layout, size_boot, size_reserve)
|
pmb.install.partition(layout, size_boot)
|
||||||
|
|
||||||
# Inform kernel about changed partition table in case parted couldn't
|
# Inform kernel about changed partition table in case parted couldn't
|
||||||
pmb.chroot.root(["partprobe", "/dev/install"], check=False)
|
pmb.chroot.root(["partprobe", "/dev/install"], check=False)
|
||||||
|
@ -1129,90 +1092,6 @@ def install_recovery_zip(args: PmbArgs, device: str, arch: Arch, steps: int) ->
|
||||||
logging.info("https://postmarketos.org/recoveryzip")
|
logging.info("https://postmarketos.org/recoveryzip")
|
||||||
|
|
||||||
|
|
||||||
def install_on_device_installer(args: PmbArgs, step: int, steps: int) -> None:
|
|
||||||
# Generate the rootfs image
|
|
||||||
config = get_context().config
|
|
||||||
if not args.ondev_no_rootfs:
|
|
||||||
suffix_rootfs = Chroot.rootfs(config.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-{config.device}",
|
|
||||||
"postmarketos-ondev",
|
|
||||||
*get_kernel_package(config),
|
|
||||||
*get_nonfree_packages(config.device),
|
|
||||||
]
|
|
||||||
|
|
||||||
chroot_installer = Chroot(ChrootType.INSTALLER, config.device)
|
|
||||||
pmb.chroot.apk.install(packages, chroot_installer)
|
|
||||||
|
|
||||||
# Move rootfs image into installer chroot
|
|
||||||
img_path_dest = chroot_installer / "var/lib/rootfs.img"
|
|
||||||
if not args.ondev_no_rootfs:
|
|
||||||
img = f"{config.device}-root.img"
|
|
||||||
img_path_src = Chroot.native() / "home/pmos/rootfs" / img
|
|
||||||
logging.info(f"({chroot_installer}) add {img} as /var/lib/rootfs.img")
|
|
||||||
pmb.install.losetup.umount(img_path_src)
|
|
||||||
pmb.helpers.run.root(["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"({chroot_installer}) ondev-prepare")
|
|
||||||
channel = pmb.config.pmaports.read_config()["channel"]
|
|
||||||
channel_cfg = pmb.config.pmaports.read_config_channel()
|
|
||||||
env: Env = {
|
|
||||||
"ONDEV_CHANNEL": channel,
|
|
||||||
"ONDEV_CHANNEL_BRANCH_APORTS": channel_cfg["branch_aports"],
|
|
||||||
"ONDEV_CHANNEL_BRANCH_PMAPORTS": channel_cfg["branch_pmaports"],
|
|
||||||
"ONDEV_CHANNEL_DESCRIPTION": channel_cfg["description"],
|
|
||||||
"ONDEV_CHANNEL_MIRRORDIR_ALPINE": channel_cfg["mirrordir_alpine"],
|
|
||||||
"ONDEV_CIPHER": args.cipher,
|
|
||||||
"ONDEV_PMBOOTSTRAP_VERSION": pmb.__version__,
|
|
||||||
"ONDEV_UI": config.ui,
|
|
||||||
}
|
|
||||||
pmb.chroot.root(["ondev-prepare"], chroot_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 = chroot_installer / chroot_dest
|
|
||||||
logging.info(f"({chroot_installer}) add {host_src} as {chroot_dest}")
|
|
||||||
pmb.helpers.run.root(["install", "-Dm644", 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 not args.ondev_no_rootfs:
|
|
||||||
img_boot = f"{config.device}-boot.img"
|
|
||||||
logging.info(f"(native) rm {img_boot}")
|
|
||||||
pmb.chroot.root(["rm", f"/home/pmos/rootfs/{img_boot}"])
|
|
||||||
|
|
||||||
# Disable root login
|
|
||||||
setup_login(args, config, chroot_installer)
|
|
||||||
|
|
||||||
# Generate installer image
|
|
||||||
size_reserve = round(os.path.getsize(img_path_dest) / 1024 / 1024) + 200
|
|
||||||
pmaports_cfg = pmb.config.pmaports.read_config()
|
|
||||||
boot_label = pmaports_cfg.get("supported_install_boot_label", "pmOS_inst_boot")
|
|
||||||
install_system_image(
|
|
||||||
args,
|
|
||||||
size_reserve,
|
|
||||||
chroot_installer,
|
|
||||||
step,
|
|
||||||
steps,
|
|
||||||
boot_label,
|
|
||||||
"pmOS_install",
|
|
||||||
args.split,
|
|
||||||
args.single_partition,
|
|
||||||
args.disk,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def get_selected_providers(args: PmbArgs, packages: list[str]) -> list[str]:
|
def get_selected_providers(args: PmbArgs, packages: list[str]) -> list[str]:
|
||||||
"""
|
"""
|
||||||
Look through the specified packages and see which providers were selected
|
Look through the specified packages and see which providers were selected
|
||||||
|
@ -1361,11 +1240,7 @@ def create_device_rootfs(args: PmbArgs, step: int, steps: int) -> None:
|
||||||
# postmarketos-base supports a dummy package for blocking unl0kr install
|
# postmarketos-base supports a dummy package for blocking unl0kr install
|
||||||
# when not required
|
# when not required
|
||||||
if pmaports_cfg.get("supported_base_nofde", None):
|
if pmaports_cfg.get("supported_base_nofde", None):
|
||||||
# The ondev installer *could* enable fde at runtime, so include it
|
if args.full_disk_encryption:
|
||||||
# explicitly in the rootfs until there's a mechanism to selectively
|
|
||||||
# install it when the ondev installer is running.
|
|
||||||
# Always install it when --fde is specified.
|
|
||||||
if args.full_disk_encryption or args.on_device_installer:
|
|
||||||
# Pick the most suitable unlocker depending on the packages
|
# Pick the most suitable unlocker depending on the packages
|
||||||
# selected for installation
|
# selected for installation
|
||||||
unlocker = pmb.parse.depends.package_provider(
|
unlocker = pmb.parse.depends.package_provider(
|
||||||
|
@ -1445,8 +1320,6 @@ def install(args: PmbArgs) -> None:
|
||||||
steps = 2
|
steps = 2
|
||||||
elif args.android_recovery_zip:
|
elif args.android_recovery_zip:
|
||||||
steps = 3
|
steps = 3
|
||||||
elif args.on_device_installer:
|
|
||||||
steps = 4 if args.ondev_no_rootfs else 7
|
|
||||||
else:
|
else:
|
||||||
steps = 4
|
steps = 4
|
||||||
|
|
||||||
|
@ -1460,7 +1333,6 @@ def install(args: PmbArgs) -> None:
|
||||||
pmb.chroot.apk.install(pmb.config.install_native_packages, Chroot.native(), build=False)
|
pmb.chroot.apk.install(pmb.config.install_native_packages, Chroot.native(), build=False)
|
||||||
step += 1
|
step += 1
|
||||||
|
|
||||||
if not args.ondev_no_rootfs:
|
|
||||||
create_device_rootfs(args, step, steps)
|
create_device_rootfs(args, step, steps)
|
||||||
step += 1
|
step += 1
|
||||||
|
|
||||||
|
@ -1468,10 +1340,6 @@ def install(args: PmbArgs) -> None:
|
||||||
return
|
return
|
||||||
elif args.android_recovery_zip:
|
elif args.android_recovery_zip:
|
||||||
return install_recovery_zip(args, device, deviceinfo.arch, steps)
|
return install_recovery_zip(args, device, deviceinfo.arch, steps)
|
||||||
|
|
||||||
if args.on_device_installer:
|
|
||||||
# Runs install_system_image twice
|
|
||||||
install_on_device_installer(args, step, steps)
|
|
||||||
else:
|
else:
|
||||||
install_system_image(
|
install_system_image(
|
||||||
args,
|
args,
|
||||||
|
|
|
@ -62,14 +62,13 @@ def mount_disk(path: Path) -> None:
|
||||||
|
|
||||||
|
|
||||||
def create_and_mount_image(
|
def create_and_mount_image(
|
||||||
args: PmbArgs, size_boot: int, size_root: int, size_reserve: int, split: bool = False
|
args: PmbArgs, size_boot: int, size_root: int, split: bool = False
|
||||||
) -> None:
|
) -> None:
|
||||||
"""
|
"""
|
||||||
Create a new image file, and mount it as /dev/install.
|
Create a new image file, and mount it as /dev/install.
|
||||||
|
|
||||||
:param size_boot: size of the boot partition in MiB
|
:param size_boot: size of the boot partition in MiB
|
||||||
:param size_root: size of the root partition in MiB
|
:param size_root: size of the root partition in MiB
|
||||||
:param size_reserve: empty partition between root and boot in MiB (pma#463)
|
|
||||||
:param split: create separate images for boot and root partitions
|
:param split: create separate images for boot and root partitions
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
@ -90,7 +89,7 @@ def create_and_mount_image(
|
||||||
pmb.chroot.root(["rm", img_path])
|
pmb.chroot.root(["rm", img_path])
|
||||||
|
|
||||||
# Make sure there is enough free space
|
# Make sure there is enough free space
|
||||||
size_mb = round(size_boot + size_reserve + size_root)
|
size_mb = round(size_boot + size_root)
|
||||||
disk_data = os.statvfs(get_context().config.work)
|
disk_data = os.statvfs(get_context().config.work)
|
||||||
free = round((disk_data.f_bsize * disk_data.f_bavail) / (1024**2))
|
free = round((disk_data.f_bsize * disk_data.f_bavail) / (1024**2))
|
||||||
if size_mb > free:
|
if size_mb > free:
|
||||||
|
@ -123,14 +122,13 @@ def create_and_mount_image(
|
||||||
|
|
||||||
|
|
||||||
def create(
|
def create(
|
||||||
args: PmbArgs, size_boot: int, size_root: int, size_reserve: int, split: bool, disk: Path | None
|
args: PmbArgs, size_boot: int, size_root: int, split: bool, disk: Path | None
|
||||||
) -> None:
|
) -> None:
|
||||||
"""
|
"""
|
||||||
Create /dev/install (the "install blockdevice").
|
Create /dev/install (the "install blockdevice").
|
||||||
|
|
||||||
:param size_boot: size of the boot partition in MiB
|
:param size_boot: size of the boot partition in MiB
|
||||||
:param size_root: size of the root partition in MiB
|
:param size_root: size of the root partition in MiB
|
||||||
:param size_reserve: empty partition between root and boot in MiB (pma#463)
|
|
||||||
:param split: create separate images for boot and root partitions
|
:param split: create separate images for boot and root partitions
|
||||||
:param disk: path to disk block device (e.g. /dev/mmcblk0) or None
|
:param disk: path to disk block device (e.g. /dev/mmcblk0) or None
|
||||||
"""
|
"""
|
||||||
|
@ -138,4 +136,4 @@ def create(
|
||||||
if disk:
|
if disk:
|
||||||
mount_disk(disk)
|
mount_disk(disk)
|
||||||
else:
|
else:
|
||||||
create_and_mount_image(args, size_boot, size_root, size_reserve, split)
|
create_and_mount_image(args, size_boot, size_root, split)
|
||||||
|
|
|
@ -60,19 +60,15 @@ def partitions_mount(device: str, layout: PartitionLayout, disk: Path | None) ->
|
||||||
pmb.helpers.mount.bind_file(source, target)
|
pmb.helpers.mount.bind_file(source, target)
|
||||||
|
|
||||||
|
|
||||||
def partition(layout: PartitionLayout, size_boot: int, size_reserve: int) -> None:
|
def partition(layout: PartitionLayout, size_boot: int) -> None:
|
||||||
"""
|
"""
|
||||||
Partition /dev/install and create /dev/install{p1,p2,p3}:
|
Partition /dev/install and create /dev/install{p1,p2,p3}:
|
||||||
* /dev/installp1: boot
|
* /dev/installp1: boot
|
||||||
* /dev/installp2: root (or reserved space)
|
* /dev/installp2: root (or reserved space)
|
||||||
* /dev/installp3: (root, if reserved space > 0)
|
* /dev/installp3: (root, if reserved space > 0)
|
||||||
|
|
||||||
When adjusting this function, make sure to also adjust
|
|
||||||
ondev-prepare-internal-storage.sh in postmarketos-ondev.git!
|
|
||||||
|
|
||||||
:param layout: partition layout from get_partition_layout()
|
:param layout: partition layout from get_partition_layout()
|
||||||
:param size_boot: size of the boot partition in MiB
|
:param size_boot: size of the boot partition in MiB
|
||||||
:param size_reserve: empty partition between root and boot in MiB (pma#463)
|
|
||||||
"""
|
"""
|
||||||
# Convert to MB and print info
|
# Convert to MB and print info
|
||||||
mb_boot = f"{size_boot}M"
|
mb_boot = f"{size_boot}M"
|
||||||
|
@ -120,7 +116,7 @@ def partition(layout: PartitionLayout, size_boot: int, size_reserve: int) -> Non
|
||||||
pmb.chroot.root(["parted", "-s", "/dev/install", *command], check=False)
|
pmb.chroot.root(["parted", "-s", "/dev/install", *command], check=False)
|
||||||
|
|
||||||
|
|
||||||
def partition_cgpt(layout: PartitionLayout, size_boot: int, size_reserve: int) -> None:
|
def partition_cgpt(layout: PartitionLayout, size_boot: int) -> None:
|
||||||
"""
|
"""
|
||||||
This function does similar functionality to partition(), but this
|
This function does similar functionality to partition(), but this
|
||||||
one is for ChromeOS devices which use special GPT. We don't follow
|
one is for ChromeOS devices which use special GPT. We don't follow
|
||||||
|
@ -128,7 +124,6 @@ def partition_cgpt(layout: PartitionLayout, size_boot: int, size_reserve: int) -
|
||||||
|
|
||||||
:param layout: partition layout from get_partition_layout()
|
:param layout: partition layout from get_partition_layout()
|
||||||
:param size_boot: size of the boot partition in MiB
|
:param size_boot: size of the boot partition in MiB
|
||||||
:param size_reserve: empty partition between root and boot in MiB (pma#463)
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
pmb.chroot.apk.install(["cgpt"], Chroot.native(), build=False)
|
pmb.chroot.apk.install(["cgpt"], Chroot.native(), build=False)
|
||||||
|
@ -147,17 +142,13 @@ def partition_cgpt(layout: PartitionLayout, size_boot: int, size_reserve: int) -
|
||||||
|
|
||||||
# Convert to MB and print info
|
# Convert to MB and print info
|
||||||
mb_boot = f"{size_boot}M"
|
mb_boot = f"{size_boot}M"
|
||||||
mb_reserved = f"{size_reserve}M"
|
logging.info(f"(native) partition /dev/install (boot: {mb_boot})")
|
||||||
logging.info(
|
|
||||||
f"(native) partition /dev/install (boot: {mb_boot},"
|
|
||||||
f" reserved: {mb_reserved}, root: the rest)"
|
|
||||||
)
|
|
||||||
|
|
||||||
boot_part_start = str(int(cgpt["kpart_start"]) + int(cgpt["kpart_size"]))
|
boot_part_start = str(int(cgpt["kpart_start"]) + int(cgpt["kpart_size"]))
|
||||||
|
|
||||||
# Convert to sectors
|
# Convert to sectors
|
||||||
s_boot = str(int(size_boot * 1024 * 1024 / 512))
|
s_boot = str(int(size_boot * 1024 * 1024 / 512))
|
||||||
s_root_start = str(int(int(boot_part_start) + int(s_boot) + size_reserve * 1024 * 1024 / 512))
|
s_root_start = str(int(int(boot_part_start) + int(s_boot)))
|
||||||
|
|
||||||
commands = [
|
commands = [
|
||||||
["parted", "-s", "/dev/install", "mktable", "gpt"],
|
["parted", "-s", "/dev/install", "mktable", "gpt"],
|
||||||
|
|
|
@ -62,29 +62,6 @@ def toggle_other_boolean_flags(
|
||||||
return SetOtherDestinationsAction
|
return SetOtherDestinationsAction
|
||||||
|
|
||||||
|
|
||||||
def type_ondev_cp(val: str) -> list[str]:
|
|
||||||
"""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(f"does not have HOST_SRC:CHROOT_DEST 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(f"CHROOT_DEST must start with '/': {chroot_dest}")
|
|
||||||
return ret
|
|
||||||
|
|
||||||
|
|
||||||
def arguments_install(subparser: argparse._SubParsersAction) -> None:
|
def arguments_install(subparser: argparse._SubParsersAction) -> None:
|
||||||
ret = subparser.add_parser(
|
ret = subparser.add_parser(
|
||||||
"install", help="set up device specific chroot and install to SD card or image file"
|
"install", help="set up device specific chroot and install to SD card or image file"
|
||||||
|
@ -240,42 +217,6 @@ def arguments_install(subparser: argparse._SubParsersAction) -> None:
|
||||||
"--no-sparse", help="do not generate sparse image file", dest="sparse", action="store_false"
|
"--no-sparse", help="do not generate sparse image file", dest="sparse", action="store_false"
|
||||||
)
|
)
|
||||||
|
|
||||||
# On-device installer
|
|
||||||
group = ret.add_argument_group(
|
|
||||||
"optional on-device installer arguments",
|
|
||||||
"Wrap the resulting image in a postmarketOS based installation OS, so"
|
|
||||||
" it can be encrypted and customized on first boot."
|
|
||||||
" Related: https://postmarketos.org/on-device-installer",
|
|
||||||
)
|
|
||||||
group.add_argument(
|
|
||||||
"--on-device-installer", "--ondev", action="store_true", help="enable on-device installer"
|
|
||||||
)
|
|
||||||
group.add_argument(
|
|
||||||
"--no-local-pkgs",
|
|
||||||
dest="install_local_pkgs",
|
|
||||||
help="do not install locally compiled packages and package signing keys",
|
|
||||||
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",
|
|
||||||
)
|
|
||||||
group.add_argument(
|
|
||||||
"--no-rootfs",
|
|
||||||
dest="ondev_no_rootfs",
|
|
||||||
help="do not generate a pmOS rootfs as"
|
|
||||||
" /var/lib/rootfs.img (install chroot). The file"
|
|
||||||
" must either exist from a previous"
|
|
||||||
" 'pmbootstrap install' run or by providing it"
|
|
||||||
" as CHROOT_DEST with --cp",
|
|
||||||
action="store_true",
|
|
||||||
)
|
|
||||||
|
|
||||||
# Other
|
# Other
|
||||||
group = ret.add_argument_group("other optional arguments")
|
group = ret.add_argument_group("other optional arguments")
|
||||||
group.add_argument(
|
group.add_argument(
|
||||||
|
|
|
@ -191,9 +191,6 @@ class PmbArgs(Namespace):
|
||||||
non_existing: str
|
non_existing: str
|
||||||
odin_flashable_tar: bool
|
odin_flashable_tar: bool
|
||||||
offline: bool
|
offline: bool
|
||||||
on_device_installer: bool
|
|
||||||
ondev_cp: list[tuple[str, str]]
|
|
||||||
ondev_no_rootfs: bool
|
|
||||||
output: RunOutputType
|
output: RunOutputType
|
||||||
overview: bool
|
overview: bool
|
||||||
# FIXME (#2324): figure out the args.package vs args.packages situation
|
# FIXME (#2324): figure out the args.package vs args.packages situation
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue