2021-01-07 22:30:30 +00:00
|
|
|
# Copyright 2021 Oliver Smith
|
2020-02-20 20:07:28 +00:00
|
|
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
2017-05-26 20:08:45 +00:00
|
|
|
import logging
|
|
|
|
import os
|
2017-06-04 00:57:37 +00:00
|
|
|
import glob
|
2017-05-26 20:08:45 +00:00
|
|
|
import pmb.helpers.mount
|
|
|
|
import pmb.install.losetup
|
|
|
|
import pmb.helpers.cli
|
|
|
|
import pmb.config
|
|
|
|
|
|
|
|
|
2020-06-09 13:43:25 +00:00
|
|
|
def previous_install(args, path):
|
2017-10-21 00:33:58 +00:00
|
|
|
"""
|
2021-02-28 19:01:31 +00:00
|
|
|
Search the sdcard for possible existence of a previous installation of
|
|
|
|
pmOS. We temporarily mount the possible pmOS_boot partition as
|
|
|
|
/dev/sdcardp1 inside the native chroot to check the label from there.
|
2020-06-09 13:43:25 +00:00
|
|
|
:param path: path to sdcard device (e.g. /dev/mmcblk0)
|
2017-10-21 00:33:58 +00:00
|
|
|
"""
|
|
|
|
label = ""
|
2020-06-09 13:43:25 +00:00
|
|
|
for blockdevice_outside in [f"{path}1", f"{path}p1"]:
|
2017-10-21 00:33:58 +00:00
|
|
|
if not os.path.exists(blockdevice_outside):
|
|
|
|
continue
|
|
|
|
blockdevice_inside = "/dev/sdcardp1"
|
2020-01-20 12:27:40 +00:00
|
|
|
pmb.helpers.mount.bind_file(args, blockdevice_outside,
|
2021-02-28 19:01:31 +00:00
|
|
|
args.work + '/chroot_native' +
|
|
|
|
blockdevice_inside)
|
install: do not choke on blockdevices without fs (MR 2153)
when blkid returns 2 while searching for existing pmos installations,
do not abort. That might happen if there is a block device without a
filesystem.
Error given:
(1653851) [21:39:19] (native) % blkid -s LABEL -o value /dev/sdcardp1
(1653851) [21:39:19] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
(1653851) [21:39:19] NOTE: The failed command's output is above the ^^^ line in the log file: /home/andi/.local/var/pmbootstrap/log.txt
(1653851) [21:39:19] ERROR: Command failed: (native) % blkid -s LABEL -o value /dev/sdcardp1
(1653851) [21:39:19] See also: <https://postmarketos.org/troubleshooting>
(1653851) [21:39:19] Traceback (most recent call last):
File "/home/andi/.local/lib/python3.9/site-packages/pmb/__init__.py", line 49, in main
getattr(frontend, args.action)(args)
File "/home/andi/.local/lib/python3.9/site-packages/pmb/helpers/frontend.py", line 314, in install
pmb.install.install(args)
File "/home/andi/.local/lib/python3.9/site-packages/pmb/install/_install.py", line 944, in install
install_system_image(args, 0, f"rootfs_{args.device}", step, steps,
File "/home/andi/.local/lib/python3.9/site-packages/pmb/install/_install.py", line 586, in install_system_image
pmb.install.blockdevice.create(args, size_boot, size_root,
File "/home/andi/.local/lib/python3.9/site-packages/pmb/install/blockdevice.py", line 138, in create
mount_sdcard(args, sdcard)
File "/home/andi/.local/lib/python3.9/site-packages/pmb/install/blockdevice.py", line 51, in mount_sdcard
if previous_install(args, path):
File "/home/andi/.local/lib/python3.9/site-packages/pmb/install/blockdevice.py", line 27, in previous_install
label = pmb.chroot.root(args, ["blkid", "-s", "LABEL", "-o", "value",
File "/home/andi/.local/lib/python3.9/site-packages/pmb/chroot/root.py", line 76, in root
return pmb.helpers.run_core.core(args, msg, cmd_sudo, None, output,
File "/home/andi/.local/lib/python3.9/site-packages/pmb/helpers/run_core.py", line 343, in core
check_return_code(args, code, log_message)
File "/home/andi/.local/lib/python3.9/site-packages/pmb/helpers/run_core.py", line 219, in check_return_code
raise RuntimeError("Command failed: " + log_message)
RuntimeError: Command failed: (native) % blkid -s LABEL -o value /dev/sdcardp1
2021-12-28 21:16:40 +00:00
|
|
|
try:
|
|
|
|
label = pmb.chroot.root(args, ["blkid", "-s", "LABEL",
|
|
|
|
"-o", "value",
|
|
|
|
blockdevice_inside],
|
|
|
|
output_return=True)
|
|
|
|
except RuntimeError:
|
|
|
|
logging.info("WARNING: Could not get block device label,"
|
|
|
|
" assume no previous installation on that partition")
|
|
|
|
|
2021-02-28 19:01:31 +00:00
|
|
|
pmb.helpers.run.root(args, ["umount", args.work + "/chroot_native" +
|
|
|
|
blockdevice_inside])
|
2017-10-21 00:33:58 +00:00
|
|
|
return "pmOS_boot" in label
|
|
|
|
|
|
|
|
|
2020-06-09 13:43:25 +00:00
|
|
|
def mount_sdcard(args, path):
|
|
|
|
"""
|
|
|
|
:param path: path to sdcard device (e.g. /dev/mmcblk0)
|
|
|
|
"""
|
2017-05-26 20:08:45 +00:00
|
|
|
# Sanity checks
|
2018-03-07 22:35:02 +00:00
|
|
|
if args.deviceinfo["external_storage"] != "true":
|
2017-05-26 20:08:45 +00:00
|
|
|
raise RuntimeError("According to the deviceinfo, this device does"
|
|
|
|
" not support a sdcard installation.")
|
2020-06-09 13:43:25 +00:00
|
|
|
if not os.path.exists(path):
|
|
|
|
raise RuntimeError(f"The sdcard device does not exist: {path}")
|
|
|
|
for path_mount in glob.glob(f"{path}*"):
|
|
|
|
if pmb.helpers.mount.ismount(path_mount):
|
|
|
|
raise RuntimeError(f"{path_mount} is mounted! Will not attempt to"
|
|
|
|
" format this!")
|
|
|
|
logging.info(f"(native) mount /dev/install (host: {path})")
|
|
|
|
pmb.helpers.mount.bind_file(args, path,
|
2020-01-20 12:27:40 +00:00
|
|
|
args.work + "/chroot_native/dev/install")
|
2020-06-09 13:43:25 +00:00
|
|
|
if previous_install(args, path):
|
2017-10-21 00:33:58 +00:00
|
|
|
if not pmb.helpers.cli.confirm(args, "WARNING: This device has a"
|
|
|
|
" previous installation of pmOS."
|
|
|
|
" CONTINUE?"):
|
|
|
|
raise RuntimeError("Aborted.")
|
|
|
|
else:
|
2020-06-09 13:43:25 +00:00
|
|
|
if not pmb.helpers.cli.confirm(args, f"EVERYTHING ON {path} WILL BE"
|
|
|
|
" ERASED! CONTINUE?"):
|
2017-10-21 00:33:58 +00:00
|
|
|
raise RuntimeError("Aborted.")
|
2017-05-26 20:08:45 +00:00
|
|
|
|
|
|
|
|
2020-06-06 17:05:11 +00:00
|
|
|
def create_and_mount_image(args, size_boot, size_root, size_reserve,
|
|
|
|
split=False):
|
2017-08-18 19:19:48 +00:00
|
|
|
"""
|
|
|
|
Create a new image file, and mount it as /dev/install.
|
|
|
|
|
2020-06-06 16:39:21 +00:00
|
|
|
:param size_boot: size of the boot partition in MiB
|
|
|
|
:param size_root: size of the root partition in MiB
|
2020-06-06 17:05:11 +00:00
|
|
|
:param size_reserve: empty partition between root and boot in MiB (pma#463)
|
2020-06-04 09:17:49 +00:00
|
|
|
:param split: create separate images for boot and root partitions
|
2017-08-18 19:19:48 +00:00
|
|
|
"""
|
2020-06-04 09:17:49 +00:00
|
|
|
|
2017-05-26 20:08:45 +00:00
|
|
|
# Short variables for paths
|
|
|
|
chroot = args.work + "/chroot_native"
|
2018-05-01 00:18:40 +00:00
|
|
|
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 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])
|
2017-05-26 20:08:45 +00:00
|
|
|
|
2017-10-13 18:52:43 +00:00
|
|
|
# Make sure there is enough free space
|
2020-06-06 17:05:11 +00:00
|
|
|
size_mb = round(size_boot + size_reserve + size_root)
|
2017-10-13 18:52:43 +00:00
|
|
|
disk_data = os.statvfs(args.work)
|
|
|
|
free = round((disk_data.f_bsize * disk_data.f_bavail) / (1024**2))
|
|
|
|
if size_mb > free:
|
2021-02-28 19:01:31 +00:00
|
|
|
raise RuntimeError("Not enough free space to create rootfs image! "
|
|
|
|
f"(free: {free}M, required: {size_mb}M)")
|
2017-05-26 20:08:45 +00:00
|
|
|
|
2018-05-01 00:18:40 +00:00
|
|
|
# Create empty image files
|
2017-10-12 20:08:10 +00:00
|
|
|
pmb.chroot.user(args, ["mkdir", "-p", "/home/pmos/rootfs"])
|
2018-05-01 00:18:40 +00:00
|
|
|
size_mb_full = str(size_mb) + "M"
|
2020-06-06 16:39:21 +00:00
|
|
|
size_mb_boot = str(round(size_boot)) + "M"
|
|
|
|
size_mb_root = str(round(size_root)) + "M"
|
2018-05-01 00:18:40 +00:00
|
|
|
images = {img_path_full: size_mb_full}
|
2020-06-04 09:17:49 +00:00
|
|
|
if split:
|
2018-05-01 00:18:40 +00:00
|
|
|
images = {img_path_boot: size_mb_boot,
|
|
|
|
img_path_root: size_mb_root}
|
|
|
|
for img_path, size_mb in images.items():
|
2021-02-28 19:01:31 +00:00
|
|
|
logging.info(f"(native) create {os.path.basename(img_path)} "
|
|
|
|
f"({size_mb})")
|
2018-05-01 00:18:40 +00:00
|
|
|
pmb.chroot.root(args, ["truncate", "-s", size_mb, img_path])
|
2017-05-26 20:08:45 +00:00
|
|
|
|
|
|
|
# Mount to /dev/install
|
2018-05-01 00:18:40 +00:00
|
|
|
mount_image_paths = {img_path_full: "/dev/install"}
|
2020-06-04 09:17:49 +00:00
|
|
|
if split:
|
2018-05-01 00:18:40 +00:00
|
|
|
mount_image_paths = {img_path_boot: "/dev/installp1",
|
|
|
|
img_path_root: "/dev/installp2"}
|
2017-05-26 20:08:45 +00:00
|
|
|
|
2018-05-01 00:18:40 +00:00
|
|
|
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)
|
2020-01-20 12:27:40 +00:00
|
|
|
pmb.helpers.mount.bind_file(args, device,
|
|
|
|
args.work + "/chroot_native" + mount_point)
|
2017-05-26 20:08:45 +00:00
|
|
|
|
2018-05-01 00:18:40 +00:00
|
|
|
|
2020-06-09 13:43:25 +00:00
|
|
|
def create(args, size_boot, size_root, size_reserve, split, sdcard):
|
2017-05-26 20:08:45 +00:00
|
|
|
"""
|
|
|
|
Create /dev/install (the "install blockdevice").
|
2017-08-18 19:19:48 +00:00
|
|
|
|
2020-06-06 16:39:21 +00:00
|
|
|
:param size_boot: size of the boot partition in MiB
|
|
|
|
:param size_root: size of the root partition in MiB
|
2020-06-06 17:05:11 +00:00
|
|
|
:param size_reserve: empty partition between root and boot in MiB (pma#463)
|
2020-06-07 07:05:30 +00:00
|
|
|
:param split: create separate images for boot and root partitions
|
2020-06-09 13:43:25 +00:00
|
|
|
:param sdcard: path to sdcard device (e.g. /dev/mmcblk0) or None
|
2017-05-26 20:08:45 +00:00
|
|
|
"""
|
|
|
|
pmb.helpers.mount.umount_all(
|
|
|
|
args, args.work + "/chroot_native/dev/install")
|
2020-06-09 13:43:25 +00:00
|
|
|
if sdcard:
|
|
|
|
mount_sdcard(args, sdcard)
|
2017-05-26 20:08:45 +00:00
|
|
|
else:
|
2020-06-06 17:05:11 +00:00
|
|
|
create_and_mount_image(args, size_boot, size_root, size_reserve,
|
2020-06-07 07:05:30 +00:00
|
|
|
split)
|