forked from Mirror/pmbootstrap
parse: deviceinfo: make Deviceinfo a class (MR 2252)
Introduce a Deviceinfo class and use it rather than the dictionary. This gives us sweet sweet autocomplete, and lays the foundation for having a proper deviceinfo validator in the future. Additionally, continue refactoring out args... Signed-off-by: Caleb Connolly <caleb@postmarketos.org>
This commit is contained in:
parent
b51d31acab
commit
97bd8b96ec
27 changed files with 372 additions and 288 deletions
|
@ -1,16 +1,16 @@
|
|||
# Copyright 2023 Oliver Smith
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
from pmb.core import get_context
|
||||
from pmb.types import PmbArgs
|
||||
from pmb.parse.deviceinfo import Deviceinfo
|
||||
import pmb.helpers.run
|
||||
import pmb.aportgen.core
|
||||
import pmb.parse.apkindex
|
||||
import pmb.parse.arch
|
||||
|
||||
|
||||
def generate_apkbuild(pkgname, deviceinfo, patches):
|
||||
def generate_apkbuild(pkgname, deviceinfo: Deviceinfo, patches):
|
||||
device = "-".join(pkgname.split("-")[1:])
|
||||
carch = pmb.parse.arch.alpine_to_kernel(deviceinfo["arch"])
|
||||
carch = pmb.parse.arch.alpine_to_kernel(deviceinfo.arch)
|
||||
|
||||
makedepends = ["bash", "bc", "bison", "devicepkg-dev", "findutils", "flex",
|
||||
"openssl-dev", "perl"]
|
||||
|
@ -24,13 +24,13 @@ def generate_apkbuild(pkgname, deviceinfo, patches):
|
|||
downstreamkernel_package "$builddir" "$pkgdir" "$_carch\" \\
|
||||
"$_flavor" "$_outdir\""""
|
||||
|
||||
if deviceinfo.get("header_version") == "2":
|
||||
if deviceinfo.header_version == "2":
|
||||
package += """
|
||||
|
||||
make dtbs_install O="$_outdir" ARCH="$_carch" \\
|
||||
INSTALL_DTBS_PATH="$pkgdir\"/boot/dtbs"""
|
||||
|
||||
if deviceinfo["bootimg_qcdt"] == "true":
|
||||
if deviceinfo.bootimg_qcdt == "true":
|
||||
build += """\n
|
||||
# Master DTB (deviceinfo_bootimg_qcdt)"""
|
||||
vendors = ["spreadtrum", "exynos", "other"]
|
||||
|
@ -68,8 +68,8 @@ def generate_apkbuild(pkgname, deviceinfo, patches):
|
|||
pkgname={pkgname}
|
||||
pkgver=3.x.x
|
||||
pkgrel=0
|
||||
pkgdesc="{deviceinfo["name"]} kernel fork"
|
||||
arch="{deviceinfo["arch"]}"
|
||||
pkgdesc="{deviceinfo.name} kernel fork"
|
||||
arch="{deviceinfo.arch}"
|
||||
_carch="{carch}"
|
||||
_flavor="{device}"
|
||||
url="https://kernel.org"
|
||||
|
|
|
@ -13,7 +13,7 @@ from pmb.core import Chroot, ChrootType, get_context
|
|||
|
||||
|
||||
# FIXME (#2324): type hint Arch
|
||||
def arch_from_deviceinfo(args: PmbArgs, pkgname, aport: Path) -> Optional[str]:
|
||||
def arch_from_deviceinfo(pkgname, aport: Path) -> Optional[str]:
|
||||
"""
|
||||
The device- packages are noarch packages. But it only makes sense to build
|
||||
them for the device's architecture, which is specified in the deviceinfo
|
||||
|
@ -31,12 +31,12 @@ def arch_from_deviceinfo(args: PmbArgs, pkgname, aport: Path) -> Optional[str]:
|
|||
|
||||
# Return its arch
|
||||
device = pkgname.split("-", 1)[1]
|
||||
arch = pmb.parse.deviceinfo(device)["arch"]
|
||||
arch = pmb.parse.deviceinfo(device).arch
|
||||
logging.verbose(pkgname + ": arch from deviceinfo: " + arch)
|
||||
return arch
|
||||
|
||||
|
||||
def arch(args: PmbArgs, pkgname: str):
|
||||
def arch(pkgname: str):
|
||||
"""
|
||||
Find a good default in case the user did not specify for which architecture
|
||||
a package should be built.
|
||||
|
@ -50,7 +50,7 @@ def arch(args: PmbArgs, pkgname: str):
|
|||
aport = pmb.helpers.pmaports.find(pkgname)
|
||||
if not aport:
|
||||
raise FileNotFoundError(f"APKBUILD not found for {pkgname}")
|
||||
ret = arch_from_deviceinfo(args, pkgname, aport)
|
||||
ret = arch_from_deviceinfo(pkgname, aport)
|
||||
if ret:
|
||||
return ret
|
||||
|
||||
|
@ -59,11 +59,11 @@ def arch(args: PmbArgs, pkgname: str):
|
|||
deviceinfo = pmb.parse.deviceinfo()
|
||||
|
||||
if get_context().config.build_default_device_arch:
|
||||
preferred_arch = deviceinfo["arch"]
|
||||
preferred_arch = deviceinfo.arch
|
||||
preferred_arch_2nd = pmb.config.arch_native
|
||||
else:
|
||||
preferred_arch = pmb.config.arch_native
|
||||
preferred_arch_2nd = deviceinfo["arch"]
|
||||
preferred_arch_2nd = deviceinfo.arch
|
||||
|
||||
if "noarch" in arches or "all" in arches or preferred_arch in arches:
|
||||
return preferred_arch
|
||||
|
|
|
@ -190,7 +190,7 @@ def package_kernel(args: PmbArgs):
|
|||
modify_apkbuild(pkgname, aport)
|
||||
apkbuild_path = context.config.work / "aportgen/APKBUILD"
|
||||
|
||||
arch = pmb.parse.deviceinfo()["arch"]
|
||||
arch = pmb.parse.deviceinfo().arch
|
||||
apkbuild = pmb.parse.apkbuild(apkbuild_path, check_pkgname=False)
|
||||
if apkbuild["_outdir"]:
|
||||
kbuild_out = apkbuild["_outdir"]
|
||||
|
|
|
@ -58,7 +58,7 @@ def shutdown_cryptsetup_device(name: str):
|
|||
raise RuntimeError("Failed to parse 'cryptsetup status' output!")
|
||||
|
||||
|
||||
def shutdown(args: PmbArgs, only_install_related=False):
|
||||
def shutdown(only_install_related=False):
|
||||
# Stop daemons
|
||||
kill_adb()
|
||||
kill_sccache()
|
||||
|
|
|
@ -4,17 +4,18 @@ import glob
|
|||
from pmb.helpers import logging
|
||||
import os
|
||||
|
||||
import pmb.build.other
|
||||
import pmb.config.workdir
|
||||
import pmb.chroot
|
||||
import pmb.config.pmaports
|
||||
import pmb.config.workdir
|
||||
from pmb.types import PmbArgs
|
||||
import pmb.helpers.pmaports
|
||||
import pmb.helpers.run
|
||||
import pmb.parse.apkindex
|
||||
from pmb.core import Chroot, get_context
|
||||
|
||||
|
||||
def zap(args: PmbArgs, confirm=True, dry=False, pkgs_local=False, http=False,
|
||||
def zap(confirm=True, dry=False, pkgs_local=False, http=False,
|
||||
pkgs_local_mismatch=False, pkgs_online_mismatch=False, distfiles=False,
|
||||
rust=False, netboot=False):
|
||||
"""
|
||||
|
@ -38,13 +39,13 @@ def zap(args: PmbArgs, confirm=True, dry=False, pkgs_local=False, http=False,
|
|||
# Delete packages with a different version compared to aports,
|
||||
# then re-index
|
||||
if pkgs_local_mismatch:
|
||||
zap_pkgs_local_mismatch(args, confirm, dry)
|
||||
zap_pkgs_local_mismatch(confirm, dry)
|
||||
|
||||
# Delete outdated binary packages
|
||||
if pkgs_online_mismatch:
|
||||
zap_pkgs_online_mismatch(args, confirm, dry)
|
||||
zap_pkgs_online_mismatch(confirm, dry)
|
||||
|
||||
pmb.chroot.shutdown(args)
|
||||
pmb.chroot.shutdown()
|
||||
|
||||
# Deletion patterns for folders inside get_context().config.work
|
||||
patterns = list(Chroot.iter_patterns())
|
||||
|
@ -72,7 +73,7 @@ def zap(args: PmbArgs, confirm=True, dry=False, pkgs_local=False, http=False,
|
|||
pmb.helpers.run.root(["rm", "-rf", match])
|
||||
|
||||
# Remove config init dates for deleted chroots
|
||||
pmb.config.workdir.clean(args)
|
||||
pmb.config.workdir.clean()
|
||||
|
||||
# Chroots were zapped, so no repo lists exist anymore
|
||||
pmb.helpers.other.cache["apk_repository_list_updated"].clear()
|
||||
|
@ -82,7 +83,7 @@ def zap(args: PmbArgs, confirm=True, dry=False, pkgs_local=False, http=False,
|
|||
logging.info("Dry run: nothing has been deleted")
|
||||
|
||||
|
||||
def zap_pkgs_local_mismatch(args: PmbArgs, confirm=True, dry=False):
|
||||
def zap_pkgs_local_mismatch(confirm=True, dry=False):
|
||||
channel = pmb.config.pmaports.read_config()["channel"]
|
||||
if not os.path.exists(f"{get_context().config.work}/packages/{channel}"):
|
||||
return
|
||||
|
@ -131,10 +132,10 @@ def zap_pkgs_local_mismatch(args: PmbArgs, confirm=True, dry=False):
|
|||
reindex = True
|
||||
|
||||
if reindex:
|
||||
pmb.build.other.index_repo(args)
|
||||
pmb.build.other.index_repo()
|
||||
|
||||
|
||||
def zap_pkgs_online_mismatch(args: PmbArgs, confirm=True, dry=False):
|
||||
def zap_pkgs_online_mismatch(confirm=True, dry=False):
|
||||
# Check whether we need to do anything
|
||||
paths = glob.glob(f"{get_context().config.work}/cache_apk_*")
|
||||
if not len(paths):
|
||||
|
|
|
@ -745,6 +745,6 @@ def frontend(args: PmbArgs):
|
|||
setattr(args, "deviceinfo", info)
|
||||
|
||||
# Do not zap any existing packages or cache_http directories
|
||||
pmb.chroot.zap(args, confirm=False)
|
||||
pmb.chroot.zap(confirm=False)
|
||||
|
||||
logging.info("DONE!")
|
||||
|
|
|
@ -90,7 +90,7 @@ def chroot_check_channel(chroot: Chroot):
|
|||
f" '{channel}' channel now. {msg_again}")
|
||||
|
||||
|
||||
def clean(args: PmbArgs):
|
||||
def clean():
|
||||
"""Remove obsolete data data from workdir.cfg.
|
||||
|
||||
:returns: None if workdir does not exist,
|
||||
|
|
|
@ -33,4 +33,4 @@ def frontend(args: PmbArgs): # FIXME: ARGS_REFACTOR
|
|||
logging.info(f"Export symlinks to: {target}")
|
||||
if args.odin_flashable_tar:
|
||||
pmb.export.odin(context, flavor, target)
|
||||
pmb.export.symlinks(args, flavor, target)
|
||||
pmb.export.symlinks(flavor, target)
|
||||
|
|
|
@ -18,7 +18,7 @@ def odin(context: Context, flavor, folder: Path):
|
|||
for devices configured with the flasher method 'heimdall-isorec'
|
||||
and with boot.img for devices with 'heimdall-bootimg'
|
||||
"""
|
||||
pmb.flasher.init(context.device)
|
||||
pmb.flasher.init(context.device, "heimdall-isorec")
|
||||
suffix = Chroot(ChrootType.ROOTFS, context.device)
|
||||
deviceinfo = pmb.parse.deviceinfo(context.device)
|
||||
|
||||
|
@ -29,7 +29,7 @@ def odin(context: Context, flavor, folder: Path):
|
|||
suffix_flavor = ""
|
||||
|
||||
# Validate method
|
||||
method = deviceinfo["flash_method"]
|
||||
method = deviceinfo.flash_method or ""
|
||||
if not method.startswith("heimdall-"):
|
||||
raise RuntimeError("An odin flashable tar is not supported"
|
||||
f" for the flash method '{method}' specified"
|
||||
|
@ -37,8 +37,8 @@ def odin(context: Context, flavor, folder: Path):
|
|||
" Only 'heimdall' methods are supported.")
|
||||
|
||||
# Partitions
|
||||
partition_kernel = deviceinfo["flash_heimdall_partition_kernel"] or "KERNEL"
|
||||
partition_initfs = deviceinfo["flash_heimdall_partition_initfs"] or "RECOVERY"
|
||||
partition_kernel = deviceinfo.flash_heimdall_partition_kernel or "KERNEL"
|
||||
partition_initfs = deviceinfo.flash_heimdall_partition_initfs or "RECOVERY"
|
||||
|
||||
# Temporary folder
|
||||
temp_folder = "/tmp/odin-flashable-tar"
|
||||
|
|
|
@ -9,19 +9,18 @@ import pmb.build
|
|||
import pmb.chroot.apk
|
||||
import pmb.config
|
||||
import pmb.config.pmaports
|
||||
from pmb.types import PmbArgs
|
||||
import pmb.flasher
|
||||
import pmb.helpers.file
|
||||
from pmb.core import Chroot, ChrootType
|
||||
|
||||
|
||||
def symlinks(args: PmbArgs, flavor, folder: Path):
|
||||
def symlinks(flavor, folder: Path):
|
||||
"""
|
||||
Create convenience symlinks to the rootfs and boot files.
|
||||
"""
|
||||
|
||||
context = get_context()
|
||||
arch = pmb.parse.deviceinfo(context.device)["arch"]
|
||||
arch = pmb.parse.deviceinfo(context.device).arch
|
||||
|
||||
# Backwards compatibility with old mkinitfs (pma#660)
|
||||
suffix = f"-{flavor}"
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
# Copyright 2023 Oliver Smith
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
from typing import Dict
|
||||
from pmb.core.context import get_context
|
||||
from pmb.helpers import logging
|
||||
|
||||
import pmb.config
|
||||
from pmb.parse.deviceinfo import Deviceinfo
|
||||
from pmb.types import PmbArgs
|
||||
import pmb.flasher
|
||||
import pmb.install
|
||||
|
@ -17,11 +17,11 @@ import pmb.parse.kconfig
|
|||
from pmb.core import Chroot, ChrootType
|
||||
|
||||
|
||||
def kernel(device: str, deviceinfo: Dict[str, str], boot: bool = False, autoinstall: bool = False):
|
||||
def kernel(deviceinfo: Deviceinfo, method: str, boot: bool = False, autoinstall: bool = False):
|
||||
# Rebuild the initramfs, just to make sure (see #69)
|
||||
flavor = pmb.helpers.frontend._parse_flavor(device, autoinstall)
|
||||
flavor = pmb.helpers.frontend._parse_flavor(deviceinfo.codename, autoinstall)
|
||||
if autoinstall:
|
||||
pmb.chroot.initfs.build(flavor, Chroot(ChrootType.ROOTFS, device))
|
||||
pmb.chroot.initfs.build(flavor, Chroot(ChrootType.ROOTFS, deviceinfo.codename))
|
||||
|
||||
# Check kernel config
|
||||
pmb.parse.kconfig.check(flavor, must_exist=False)
|
||||
|
@ -29,10 +29,10 @@ def kernel(device: str, deviceinfo: Dict[str, str], boot: bool = False, autoinst
|
|||
# Generate the paths and run the flasher
|
||||
if boot:
|
||||
logging.info("(native) boot " + flavor + " kernel")
|
||||
pmb.flasher.run(device, deviceinfo, "boot", flavor)
|
||||
pmb.flasher.run(deviceinfo, method, "boot", flavor)
|
||||
else:
|
||||
logging.info("(native) flash kernel " + flavor)
|
||||
pmb.flasher.run(device, deviceinfo, "flash_kernel", flavor)
|
||||
pmb.flasher.run(deviceinfo, method, "flash_kernel", flavor)
|
||||
logging.info("You will get an IP automatically assigned to your "
|
||||
"USB interface shortly.")
|
||||
logging.info("Then you can connect to your device using ssh after pmOS has"
|
||||
|
@ -49,61 +49,61 @@ def list_flavors(device: str):
|
|||
logging.info("* " + pmb.chroot.other.kernel_flavor_installed(chroot))
|
||||
|
||||
|
||||
def rootfs(device: str, deviceinfo: Dict[str, str], method: str):
|
||||
def rootfs(deviceinfo: Deviceinfo, method: str):
|
||||
# Generate rootfs, install flasher
|
||||
suffix = ".img"
|
||||
if pmb.config.flashers.get(method, {}).get("split", False):
|
||||
suffix = "-root.img"
|
||||
|
||||
img_path = Chroot.native() / "home/pmos/rootfs" / f"{device}{suffix}"
|
||||
img_path = Chroot.native() / "home/pmos/rootfs" / f"{deviceinfo.codename}{suffix}"
|
||||
if not img_path.exists():
|
||||
raise RuntimeError("The rootfs has not been generated yet, please run"
|
||||
" 'pmbootstrap install' first.")
|
||||
|
||||
# Do not flash if using fastboot & image is too large
|
||||
if method.startswith("fastboot") \
|
||||
and deviceinfo["flash_fastboot_max_size"]:
|
||||
and deviceinfo.flash_fastboot_max_size:
|
||||
img_size = img_path.stat().st_size / 1024**2
|
||||
max_size = int(deviceinfo["flash_fastboot_max_size"])
|
||||
max_size = int(deviceinfo.flash_fastboot_max_size)
|
||||
if img_size > max_size:
|
||||
raise RuntimeError("The rootfs is too large for fastboot to"
|
||||
" flash.")
|
||||
|
||||
# Run the flasher
|
||||
logging.info("(native) flash rootfs image")
|
||||
pmb.flasher.run(device, deviceinfo, "flash_rootfs")
|
||||
pmb.flasher.run(deviceinfo, method, "flash_rootfs")
|
||||
|
||||
|
||||
def list_devices(device, deviceinfo):
|
||||
pmb.flasher.run(device, deviceinfo, "list_devices")
|
||||
def list_devices(deviceinfo: Deviceinfo, method: str):
|
||||
pmb.flasher.run(deviceinfo, method, "list_devices")
|
||||
|
||||
|
||||
def sideload(device: str, deviceinfo: Dict[str, str]):
|
||||
def sideload(deviceinfo: Deviceinfo, method: str):
|
||||
# Install depends
|
||||
pmb.flasher.install_depends()
|
||||
pmb.flasher.install_depends(method)
|
||||
|
||||
# Mount the buildroot
|
||||
chroot = Chroot.buildroot(deviceinfo["arch"])
|
||||
chroot = Chroot.buildroot(deviceinfo.arch)
|
||||
mountpoint = "/mnt/" / chroot
|
||||
pmb.helpers.mount.bind(chroot.path,
|
||||
Chroot.native().path / mountpoint)
|
||||
|
||||
# Missing recovery zip error
|
||||
if not (Chroot.native() / mountpoint / "/var/lib/postmarketos-android-recovery-installer"
|
||||
/ f"pmos-{device}.zip").exists():
|
||||
/ f"pmos-{deviceinfo.codename}.zip").exists():
|
||||
raise RuntimeError("The recovery zip has not been generated yet,"
|
||||
" please run 'pmbootstrap install' with the"
|
||||
" '--android-recovery-zip' parameter first!")
|
||||
|
||||
pmb.flasher.run(device, deviceinfo, "sideload")
|
||||
pmb.flasher.run(deviceinfo, method, "sideload")
|
||||
|
||||
|
||||
def flash_lk2nd(device: str, deviceinfo: Dict[str, str], method: str):
|
||||
def flash_lk2nd(deviceinfo: Deviceinfo, method: str):
|
||||
if method == "fastboot":
|
||||
# In the future this could be expanded to use "fastboot flash lk2nd $img"
|
||||
# which reflashes/updates lk2nd from itself. For now let the user handle this
|
||||
# manually since supporting the codepath with heimdall requires more effort.
|
||||
pmb.flasher.init(device)
|
||||
pmb.flasher.init(deviceinfo.codename, method)
|
||||
logging.info("(native) checking current fastboot product")
|
||||
output = pmb.chroot.root(["fastboot", "getvar", "product"],
|
||||
output="interactive", output_return=True)
|
||||
|
@ -114,7 +114,7 @@ def flash_lk2nd(device: str, deviceinfo: Dict[str, str], method: str):
|
|||
" bootloader mode to re-flash lk2nd.")
|
||||
|
||||
# Get the lk2nd package (which is a dependency of the device package)
|
||||
device_pkg = f"device-{device}"
|
||||
device_pkg = f"device-{deviceinfo.codename}"
|
||||
apkbuild = pmb.helpers.pmaports.get(device_pkg)
|
||||
lk2nd_pkg = None
|
||||
for dep in apkbuild["depends"]:
|
||||
|
@ -125,11 +125,11 @@ def flash_lk2nd(device: str, deviceinfo: Dict[str, str], method: str):
|
|||
if not lk2nd_pkg:
|
||||
raise RuntimeError(f"{device_pkg} does not depend on any lk2nd package")
|
||||
|
||||
suffix = Chroot(ChrootType.ROOTFS, device)
|
||||
suffix = Chroot(ChrootType.ROOTFS, deviceinfo.codename)
|
||||
pmb.chroot.apk.install([lk2nd_pkg], suffix)
|
||||
|
||||
logging.info("(native) flash lk2nd image")
|
||||
pmb.flasher.run(device, deviceinfo, "flash_lk2nd")
|
||||
pmb.flasher.run(deviceinfo, method, "flash_lk2nd")
|
||||
|
||||
|
||||
def frontend(args: PmbArgs):
|
||||
|
@ -137,7 +137,7 @@ def frontend(args: PmbArgs):
|
|||
action = args.action_flasher
|
||||
device = context.device
|
||||
deviceinfo = pmb.parse.deviceinfo()
|
||||
method = args.flash_method or deviceinfo["flash_method"]
|
||||
method = args.flash_method or deviceinfo.flash_method or "none"
|
||||
|
||||
if method == "none" and action in ["boot", "flash_kernel", "flash_rootfs",
|
||||
"flash_lk2nd"]:
|
||||
|
@ -145,20 +145,20 @@ def frontend(args: PmbArgs):
|
|||
return
|
||||
|
||||
if action in ["boot", "flash_kernel"]:
|
||||
kernel(device, deviceinfo)
|
||||
kernel(deviceinfo, method)
|
||||
elif action == "flash_rootfs":
|
||||
rootfs(device, deviceinfo, method)
|
||||
rootfs(deviceinfo, method)
|
||||
elif action == "flash_vbmeta":
|
||||
logging.info("(native) flash vbmeta.img with verity disabled flag")
|
||||
pmb.flasher.run(device, deviceinfo, "flash_vbmeta")
|
||||
pmb.flasher.run(deviceinfo, method, "flash_vbmeta")
|
||||
elif action == "flash_dtbo":
|
||||
logging.info("(native) flash dtbo image")
|
||||
pmb.flasher.run(device, deviceinfo, "flash_dtbo")
|
||||
pmb.flasher.run(deviceinfo, method, "flash_dtbo")
|
||||
elif action == "flash_lk2nd":
|
||||
flash_lk2nd(device, deviceinfo, method)
|
||||
flash_lk2nd(deviceinfo, method)
|
||||
elif action == "list_flavors":
|
||||
list_flavors(device)
|
||||
elif action == "list_devices":
|
||||
list_devices(device, deviceinfo)
|
||||
pmb.flasher.run(deviceinfo, method, "list_devices")
|
||||
elif action == "sideload":
|
||||
sideload(device, deviceinfo)
|
||||
sideload(deviceinfo, method)
|
||||
|
|
|
@ -10,14 +10,7 @@ from pmb.helpers.mount import mount_device_rootfs
|
|||
from pmb.core import Chroot, ChrootType
|
||||
|
||||
|
||||
def install_depends() -> None:
|
||||
args: PmbArgs = pmb.helpers.args.please_i_really_need_args()
|
||||
if hasattr(args, 'flash_method'):
|
||||
method = args.flash_method
|
||||
|
||||
if not method:
|
||||
method = pmb.parse.deviceinfo()["flash_method"]
|
||||
|
||||
def install_depends(method: str) -> None:
|
||||
if method not in pmb.config.flashers:
|
||||
raise RuntimeError(f"Flash method {method} is not supported by the"
|
||||
" current configuration. However, adding a new"
|
||||
|
@ -46,8 +39,8 @@ def install_depends() -> None:
|
|||
pmb.chroot.apk.install(depends, Chroot.native())
|
||||
|
||||
|
||||
def init(device: str):
|
||||
install_depends()
|
||||
def init(device: str, method: str):
|
||||
install_depends(method)
|
||||
|
||||
# Mount folders from host system
|
||||
for folder in pmb.config.flash_mount_bind:
|
||||
|
|
|
@ -1,31 +1,28 @@
|
|||
# Copyright 2023 Oliver Smith
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
from typing import Dict
|
||||
from pmb.parse.deviceinfo import Deviceinfo
|
||||
from pmb.types import PmbArgs
|
||||
import pmb.flasher
|
||||
import pmb.chroot.initfs
|
||||
import pmb.helpers.args
|
||||
|
||||
|
||||
def check_partition_blacklist(args: PmbArgs, deviceinfo: Dict[str, str], key, value):
|
||||
def check_partition_blacklist(deviceinfo: Deviceinfo, key, value):
|
||||
if not key.startswith("$PARTITION_"):
|
||||
return
|
||||
|
||||
name = deviceinfo["name"]
|
||||
if value in deviceinfo["partition_blacklist"].split(","):
|
||||
name = deviceinfo.name
|
||||
if value in (deviceinfo.partition_blacklist or "").split(","):
|
||||
raise RuntimeError("'" + value + "'" + " partition is blacklisted " +
|
||||
"from being flashed! See the " + name + " device " +
|
||||
"wiki page for more information.")
|
||||
|
||||
|
||||
def run(device: str, deviceinfo: Dict[str, str], action, flavor=None):
|
||||
pmb.flasher.init(device)
|
||||
|
||||
# FIXME: handle argparsing and pass in only the args we need.
|
||||
args = pmb.helpers.args.please_i_really_need_args()
|
||||
def run(deviceinfo: Deviceinfo, method: str, action: str, flavor=None):
|
||||
pmb.flasher.init(deviceinfo.codename, method)
|
||||
|
||||
# Verify action
|
||||
method = args.flash_method or deviceinfo["flash_method"]
|
||||
cfg = pmb.config.flashers[method]
|
||||
if not isinstance(cfg["actions"], dict):
|
||||
raise TypeError(f"Flashers misconfigured! {method} key 'actions' should be a dictionary")
|
||||
|
@ -38,6 +35,8 @@ def run(device: str, deviceinfo: Dict[str, str], action, flavor=None):
|
|||
"Deviceinfo_flash_methods>")
|
||||
|
||||
# Variable setup
|
||||
# FIXME: handle argparsing and pass in only the args we need.
|
||||
args = pmb.helpers.args.please_i_really_need_args()
|
||||
fvars = pmb.flasher.variables(args, flavor, method)
|
||||
|
||||
# vbmeta flasher requires vbmeta partition to be explicitly specified
|
||||
|
@ -79,7 +78,7 @@ def run(device: str, deviceinfo: Dict[str, str], action, flavor=None):
|
|||
" but the value for this variable"
|
||||
" is None! Is that missing in your"
|
||||
" deviceinfo?")
|
||||
check_partition_blacklist(args, deviceinfo, key, value)
|
||||
check_partition_blacklist(deviceinfo, key, value)
|
||||
command[i] = command[i].replace(key, value)
|
||||
|
||||
# Remove empty strings
|
||||
|
|
|
@ -9,11 +9,11 @@ from pmb.types import PmbArgs
|
|||
def variables(args: PmbArgs, flavor, method):
|
||||
device = get_context().config.device
|
||||
deviceinfo = pmb.parse.deviceinfo()
|
||||
_cmdline = deviceinfo["kernel_cmdline"] or ""
|
||||
_cmdline = deviceinfo.kernel_cmdline or ""
|
||||
if "cmdline" in args and args.cmdline:
|
||||
_cmdline = args.cmdline
|
||||
|
||||
flash_pagesize = deviceinfo['flash_pagesize']
|
||||
flash_pagesize = deviceinfo.flash_pagesize
|
||||
|
||||
# TODO Remove _partition_system deviceinfo support once pmaports has been
|
||||
# updated and minimum pmbootstrap version bumped.
|
||||
|
@ -23,39 +23,39 @@ def variables(args: PmbArgs, flavor, method):
|
|||
_partition_rootfs: Optional[str]
|
||||
|
||||
if method.startswith("fastboot"):
|
||||
_partition_kernel = deviceinfo["flash_fastboot_partition_kernel"]\
|
||||
_partition_kernel = deviceinfo.flash_fastboot_partition_kernel\
|
||||
or "boot"
|
||||
_partition_rootfs = deviceinfo["flash_fastboot_partition_rootfs"]\
|
||||
or deviceinfo["flash_fastboot_partition_system"] or "userdata"
|
||||
_partition_vbmeta = deviceinfo["flash_fastboot_partition_vbmeta"]\
|
||||
_partition_rootfs = deviceinfo.flash_fastboot_partition_rootfs\
|
||||
or deviceinfo.flash_fastboot_partition_system or "userdata"
|
||||
_partition_vbmeta = deviceinfo.flash_fastboot_partition_vbmeta\
|
||||
or None
|
||||
_partition_dtbo = deviceinfo["flash_fastboot_partition_dtbo"]\
|
||||
_partition_dtbo = deviceinfo.flash_fastboot_partition_dtbo\
|
||||
or None
|
||||
# Require that the partitions are specified in deviceinfo for now
|
||||
elif method.startswith("rkdeveloptool"):
|
||||
_partition_kernel = deviceinfo["flash_rk_partition_kernel"]\
|
||||
_partition_kernel = deviceinfo.flash_rk_partition_kernel\
|
||||
or None
|
||||
_partition_rootfs = deviceinfo["flash_rk_partition_rootfs"]\
|
||||
or deviceinfo["flash_rk_partition_system"] or None
|
||||
_partition_rootfs = deviceinfo.flash_rk_partition_rootfs\
|
||||
or deviceinfo.flash_rk_partition_system or None
|
||||
_partition_vbmeta = None
|
||||
_partition_dtbo = None
|
||||
elif method.startswith("mtkclient"):
|
||||
_partition_kernel = deviceinfo["flash_mtkclient_partition_kernel"]\
|
||||
_partition_kernel = deviceinfo.flash_mtkclient_partition_kernel\
|
||||
or "boot"
|
||||
_partition_rootfs = deviceinfo["flash_mtkclient_partition_rootfs"]\
|
||||
_partition_rootfs = deviceinfo.flash_mtkclient_partition_rootfs\
|
||||
or "userdata"
|
||||
_partition_vbmeta = deviceinfo["flash_mtkclient_partition_vbmeta"]\
|
||||
_partition_vbmeta = deviceinfo.flash_mtkclient_partition_vbmeta\
|
||||
or None
|
||||
_partition_dtbo = deviceinfo["flash_mtkclient_partition_dtbo"]\
|
||||
_partition_dtbo = deviceinfo.flash_mtkclient_partition_dtbo\
|
||||
or None
|
||||
else:
|
||||
_partition_kernel = deviceinfo["flash_heimdall_partition_kernel"]\
|
||||
_partition_kernel = deviceinfo.flash_heimdall_partition_kernel\
|
||||
or "KERNEL"
|
||||
_partition_rootfs = deviceinfo["flash_heimdall_partition_rootfs"]\
|
||||
or deviceinfo["flash_heimdall_partition_system"] or "SYSTEM"
|
||||
_partition_vbmeta = deviceinfo["flash_heimdall_partition_vbmeta"]\
|
||||
_partition_rootfs = deviceinfo.flash_heimdall_partition_rootfs\
|
||||
or deviceinfo.flash_heimdall_partition_system or "SYSTEM"
|
||||
_partition_vbmeta = deviceinfo.flash_heimdall_partition_vbmeta\
|
||||
or None
|
||||
_partition_dtbo = deviceinfo["flash_heimdall_partition_dtbo"]\
|
||||
_partition_dtbo = deviceinfo.flash_heimdall_partition_dtbo\
|
||||
or None
|
||||
|
||||
if "partition" in args and args.partition:
|
||||
|
@ -67,7 +67,7 @@ def variables(args: PmbArgs, flavor, method):
|
|||
_partition_dtbo = args.partition
|
||||
|
||||
_dtb = ""
|
||||
if deviceinfo["append_dtb"] == "true":
|
||||
if deviceinfo.append_dtb == "true":
|
||||
_dtb = "-dtb"
|
||||
|
||||
_no_reboot = ""
|
||||
|
@ -86,16 +86,15 @@ def variables(args: PmbArgs, flavor, method):
|
|||
"$IMAGE": "/home/pmos/rootfs/" + device + ".img",
|
||||
"$KERNEL_CMDLINE": _cmdline,
|
||||
"$PARTITION_KERNEL": _partition_kernel,
|
||||
"$PARTITION_INITFS": deviceinfo[
|
||||
"flash_heimdall_partition_initfs"] or "RECOVERY",
|
||||
"$PARTITION_INITFS": deviceinfo.flash_heimdall_partition_initfs or "RECOVERY",
|
||||
"$PARTITION_ROOTFS": _partition_rootfs,
|
||||
"$PARTITION_VBMETA": _partition_vbmeta,
|
||||
"$PARTITION_DTBO": _partition_dtbo,
|
||||
"$FLASH_PAGESIZE": flash_pagesize,
|
||||
"$RECOVERY_ZIP": "/mnt/buildroot_" + deviceinfo["arch"] +
|
||||
"$RECOVERY_ZIP": "/mnt/buildroot_" + deviceinfo.arch +
|
||||
"/var/lib/postmarketos-android-recovery-installer"
|
||||
"/pmos-" + device + ".zip",
|
||||
"$UUU_SCRIPT": "/mnt/rootfs_" + deviceinfo["codename"] +
|
||||
"$UUU_SCRIPT": "/mnt/rootfs_" + deviceinfo.codename +
|
||||
"/usr/share/uuu/flash_script.lst",
|
||||
"$NO_REBOOT": _no_reboot,
|
||||
"$RESUME": _resume
|
||||
|
|
|
@ -99,7 +99,7 @@ def init(args: PmbArgs) -> PmbArgs:
|
|||
pmb.config.pmaports.read_config()
|
||||
pmb.helpers.git.parse_channels_cfg(config.aports)
|
||||
deviceinfo = pmb.parse.deviceinfo()
|
||||
context.device_arch = deviceinfo["arch"]
|
||||
context.device_arch = deviceinfo.arch
|
||||
|
||||
# Remove attributes from args so they don't get used by mistake
|
||||
delattr(args, "timeout")
|
||||
|
|
|
@ -65,7 +65,7 @@ def _parse_suffix(args: PmbArgs) -> Chroot:
|
|||
return Chroot(ChrootType.ROOTFS, get_context().config.device)
|
||||
elif args.buildroot:
|
||||
if args.buildroot == "device":
|
||||
return Chroot.buildroot(pmb.parse.deviceinfo()["arch"])
|
||||
return Chroot.buildroot(pmb.parse.deviceinfo().arch)
|
||||
else:
|
||||
return Chroot.buildroot(args.buildroot)
|
||||
elif args.suffix:
|
||||
|
@ -118,14 +118,14 @@ def build(args: PmbArgs):
|
|||
|
||||
# Ensure repo_bootstrap is done for all arches we intend to build for
|
||||
for package in args.packages:
|
||||
arch_package = args.arch or pmb.build.autodetect.arch(args, package)
|
||||
arch_package = args.arch or pmb.build.autodetect.arch(package)
|
||||
pmb.helpers.repo_bootstrap.require_bootstrap(arch_package,
|
||||
f"build {package} for {arch_package}")
|
||||
|
||||
context = get_context()
|
||||
# Build all packages
|
||||
for package in args.packages:
|
||||
arch_package = args.arch or pmb.build.autodetect.arch(args, package)
|
||||
arch_package = args.arch or pmb.build.autodetect.arch(package)
|
||||
if not pmb.build.package(context, package, arch_package, force,
|
||||
args.strict, src=src):
|
||||
logging.info("NOTE: Package '" + package + "' is up to date. Use"
|
||||
|
@ -215,7 +215,9 @@ def config(args: PmbArgs):
|
|||
logging.info("NOTE: Valid config keys: " + ", ".join(keys))
|
||||
raise RuntimeError("Invalid config key: " + args.name)
|
||||
|
||||
config = pmb.config.load(args)
|
||||
# Reload the config because get_context().config has been overwritten
|
||||
# by any rogue cmdline arguments.
|
||||
config = pmb.config.load(args.config)
|
||||
if args.reset:
|
||||
if args.name is None:
|
||||
raise RuntimeError("config --reset requires a name to be given.")
|
||||
|
@ -242,7 +244,7 @@ def config(args: PmbArgs):
|
|||
|
||||
|
||||
def repo_bootstrap(args: PmbArgs):
|
||||
pmb.helpers.repo_bootstrap.main(args)
|
||||
pmb.helpers.repo_bootstrap.main(args.arch, args.repository)
|
||||
|
||||
|
||||
def repo_missing(args: PmbArgs):
|
||||
|
@ -272,8 +274,8 @@ def install(args: PmbArgs):
|
|||
raise ValueError("Installation using rsync"
|
||||
" is not currently supported on btrfs filesystem.")
|
||||
|
||||
pmb.helpers.repo_bootstrap.require_bootstrap(deviceinfo["arch"],
|
||||
f"do 'pmbootstrap install' for {deviceinfo['arch']}"
|
||||
pmb.helpers.repo_bootstrap.require_bootstrap(deviceinfo.arch,
|
||||
f"do 'pmbootstrap install' for {deviceinfo.arch}"
|
||||
" (deviceinfo_arch)")
|
||||
|
||||
# On-device installer checks
|
||||
|
@ -297,7 +299,7 @@ def install(args: PmbArgs):
|
|||
raise ValueError("--on-device-installer cannot be combined with"
|
||||
" --filesystem")
|
||||
|
||||
if deviceinfo["cgpt_kpart"]:
|
||||
if deviceinfo.cgpt_kpart:
|
||||
raise ValueError("--on-device-installer cannot be used with"
|
||||
" ChromeOS devices")
|
||||
else:
|
||||
|
@ -324,7 +326,7 @@ def install(args: PmbArgs):
|
|||
|
||||
if not args.disk and args.split is None:
|
||||
# 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, {})
|
||||
if flasher.get("split", False):
|
||||
args.split = True
|
||||
|
||||
|
@ -567,7 +569,7 @@ def work_migrate(args: PmbArgs):
|
|||
|
||||
|
||||
def zap(args: PmbArgs):
|
||||
pmb.chroot.zap(args, dry=args.dry, http=args.http,
|
||||
pmb.chroot.zap(dry=args.dry, http=args.http,
|
||||
distfiles=args.distfiles, pkgs_local=args.pkgs_local,
|
||||
pkgs_local_mismatch=args.pkgs_local_mismatch,
|
||||
pkgs_online_mismatch=args.pkgs_online_mismatch,
|
||||
|
|
|
@ -107,7 +107,7 @@ def migrate_work_folder(args: PmbArgs):
|
|||
raise RuntimeError("Aborted.")
|
||||
|
||||
# Zap and update abuild.conf
|
||||
pmb.chroot.zap(args, False)
|
||||
pmb.chroot.zap(False)
|
||||
conf = context.config.work / "config_abuild/abuild.conf"
|
||||
if os.path.exists(conf):
|
||||
pmb.helpers.run.root(["sed", "-i",
|
||||
|
@ -145,7 +145,7 @@ def migrate_work_folder(args: PmbArgs):
|
|||
raise RuntimeError("Aborted.")
|
||||
|
||||
# Zap chroots
|
||||
pmb.chroot.zap(args, False)
|
||||
pmb.chroot.zap(False)
|
||||
|
||||
# Update version file
|
||||
migrate_success(context.config.work, 3)
|
||||
|
@ -186,7 +186,7 @@ def migrate_work_folder(args: PmbArgs):
|
|||
raise RuntimeError("Aborted.")
|
||||
|
||||
# Zap chroots
|
||||
pmb.chroot.zap(args, False)
|
||||
pmb.chroot.zap(False)
|
||||
|
||||
# Move packages to edge subdir
|
||||
edge_path = context.config.work / "packages/edge"
|
||||
|
@ -224,7 +224,7 @@ def migrate_work_folder(args: PmbArgs):
|
|||
|
||||
# Zap chroots to avoid potential "ERROR: Chroot 'native' was created
|
||||
# for the 'stable' channel, but you are on the 'v20.05' channel now."
|
||||
pmb.chroot.zap(args, False)
|
||||
pmb.chroot.zap(False)
|
||||
|
||||
# Migrate
|
||||
packages_dir = f"{context.config.work}/packages"
|
||||
|
|
|
@ -1,12 +1,13 @@
|
|||
# Copyright 2024 Oliver Smith
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
from typing import Optional
|
||||
from pmb.core.chroot import Chroot
|
||||
from pmb.helpers import logging
|
||||
import glob
|
||||
|
||||
import pmb.config.pmaports
|
||||
import pmb.helpers.repo
|
||||
from pmb.types import PmbArgs
|
||||
from pmb.types import Config
|
||||
from pmb.core import get_context
|
||||
|
||||
|
||||
|
@ -15,19 +16,15 @@ progress_total = 0
|
|||
progress_step: str
|
||||
|
||||
|
||||
def get_arch(args: PmbArgs):
|
||||
if args.arch:
|
||||
return args.arch
|
||||
|
||||
if args.build_default_device_arch:
|
||||
return pmb.parse.deviceinfo()["arch"]
|
||||
def get_arch(config: Config):
|
||||
if config.build_default_device_arch:
|
||||
return pmb.parse.deviceinfo().arch
|
||||
|
||||
return pmb.config.arch_native
|
||||
|
||||
|
||||
def check_repo_arg(args: PmbArgs):
|
||||
def check_repo_arg(repo: str):
|
||||
cfg = pmb.config.pmaports.read_config_repos()
|
||||
repo = args.repository
|
||||
|
||||
if repo in cfg:
|
||||
return
|
||||
|
@ -41,9 +38,9 @@ def check_repo_arg(args: PmbArgs):
|
|||
" current branch")
|
||||
|
||||
|
||||
def check_existing_pkgs(args: PmbArgs, arch):
|
||||
def check_existing_pkgs(config: Config, arch):
|
||||
channel = pmb.config.pmaports.read_config()["channel"]
|
||||
path = get_context().config.work / "packages" / channel / arch
|
||||
path = config.work / "packages" / channel / arch
|
||||
|
||||
if glob.glob(f"{path}/*"):
|
||||
logging.info(f"Packages path: {path}")
|
||||
|
@ -57,12 +54,12 @@ def check_existing_pkgs(args: PmbArgs, arch):
|
|||
raise RuntimeError(f"{msg}!")
|
||||
|
||||
|
||||
def get_steps(args: PmbArgs):
|
||||
def get_steps(repo: str):
|
||||
cfg = pmb.config.pmaports.read_config_repos()
|
||||
prev_step = 0
|
||||
ret = {}
|
||||
|
||||
for key, packages in cfg[args.repository].items():
|
||||
for key, packages in cfg[repo].items():
|
||||
if not key.startswith("bootstrap_"):
|
||||
continue
|
||||
|
||||
|
@ -76,7 +73,7 @@ def get_steps(args: PmbArgs):
|
|||
return ret
|
||||
|
||||
|
||||
def get_suffix(args: PmbArgs, arch):
|
||||
def get_suffix(arch):
|
||||
if pmb.parse.arch.cpu_emulation_required(arch):
|
||||
return f"buildroot_{arch}"
|
||||
return "native"
|
||||
|
@ -91,7 +88,7 @@ def get_packages(bootstrap_line):
|
|||
return ret
|
||||
|
||||
|
||||
def set_progress_total(args: PmbArgs, steps, arch):
|
||||
def set_progress_total(steps, arch):
|
||||
global progress_total
|
||||
|
||||
progress_total = 0
|
||||
|
@ -117,14 +114,14 @@ def log_progress(msg):
|
|||
progress_done += 1
|
||||
|
||||
|
||||
def run_steps(args: PmbArgs, steps, arch, chroot: Chroot):
|
||||
def run_steps(steps, arch, chroot: Chroot):
|
||||
global progress_step
|
||||
|
||||
for step, bootstrap_line in steps.items():
|
||||
progress_step = step.replace("bootstrap_", "BOOTSTRAP=")
|
||||
|
||||
log_progress("zapping")
|
||||
pmb.chroot.zap(args, confirm=False)
|
||||
pmb.chroot.zap(confirm=False)
|
||||
|
||||
usr_merge = pmb.chroot.UsrMerge.OFF
|
||||
if "[usr_merge]" in bootstrap_line:
|
||||
|
@ -148,17 +145,18 @@ def run_steps(args: PmbArgs, steps, arch, chroot: Chroot):
|
|||
log_progress("bootstrap complete!")
|
||||
|
||||
|
||||
def main(args: PmbArgs):
|
||||
check_repo_arg(args)
|
||||
def main(arch: Optional[str], repository: str): # noqa: F821
|
||||
config = get_context().config
|
||||
check_repo_arg(repository)
|
||||
|
||||
arch = get_arch(args)
|
||||
check_existing_pkgs(args, arch)
|
||||
arch = arch or get_arch(config)
|
||||
check_existing_pkgs(config, arch)
|
||||
|
||||
steps = get_steps(args)
|
||||
suffix = get_suffix(args, arch)
|
||||
steps = get_steps(repository)
|
||||
suffix = get_suffix(arch)
|
||||
|
||||
set_progress_total(args, steps, arch)
|
||||
run_steps(args, steps, arch, suffix)
|
||||
set_progress_total(steps, arch)
|
||||
run_steps(steps, arch, suffix)
|
||||
|
||||
|
||||
def require_bootstrap_error(repo, arch, trigger_str):
|
||||
|
|
|
@ -38,7 +38,7 @@ def print_device(config: Config) -> None:
|
|||
if pmb.parse._apkbuild.kernels(config.device):
|
||||
kernel = f", kernel: {config.kernel}"
|
||||
|
||||
value = f"{config.device} ({pmb.parse.deviceinfo()['arch']}{kernel})"
|
||||
value = f"{config.device} ({pmb.parse.deviceinfo().arch}{kernel})"
|
||||
print_status_line("Device", value)
|
||||
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@ import pmb.chroot.other
|
|||
import pmb.chroot.initfs
|
||||
import pmb.config
|
||||
import pmb.config.pmaports
|
||||
from pmb.parse.deviceinfo import Deviceinfo
|
||||
from pmb.types import Config, PartitionLayout, PmbArgs
|
||||
import pmb.helpers.devices
|
||||
from pmb.helpers.mount import mount_device_rootfs
|
||||
|
@ -118,7 +119,7 @@ def copy_files_from_chroot(args: PmbArgs, chroot: Chroot):
|
|||
mountpoint_outside = Chroot.native() / mountpoint
|
||||
|
||||
# Remove empty qemu-user binary stub (where the binary was bind-mounted)
|
||||
arch_qemu = pmb.parse.arch.alpine_to_qemu(pmb.parse.deviceinfo()["arch"])
|
||||
arch_qemu = pmb.parse.arch.alpine_to_qemu(pmb.parse.deviceinfo().arch)
|
||||
qemu_binary = mountpoint_outside / ("/usr/bin/qemu-" + arch_qemu + "-static")
|
||||
if os.path.exists(qemu_binary):
|
||||
pmb.helpers.run.root(["rm", qemu_binary])
|
||||
|
@ -185,7 +186,7 @@ def configure_apk(args: PmbArgs):
|
|||
pmb.helpers.run.root(["cp", key, rootfs / "etc/apk/keys/"])
|
||||
|
||||
# Copy over the corresponding APKINDEX files from cache
|
||||
index_files = pmb.helpers.repo.apkindex_files(arch=pmb.parse.deviceinfo()["arch"],
|
||||
index_files = pmb.helpers.repo.apkindex_files(arch=pmb.parse.deviceinfo().arch,
|
||||
user_repository=False)
|
||||
for f in index_files:
|
||||
pmb.helpers.run.root(["cp", f, rootfs / "var/cache/apk/"])
|
||||
|
@ -325,11 +326,11 @@ def setup_keymap(config: Config):
|
|||
Set the keymap with the setup-keymap utility if the device requires it
|
||||
"""
|
||||
chroot = Chroot(ChrootType.ROOTFS, config.device)
|
||||
info = pmb.parse.deviceinfo(device=config.device)
|
||||
if "keymaps" not in info or info["keymaps"].strip() == "":
|
||||
deviceinfo = pmb.parse.deviceinfo(device=config.device)
|
||||
if not deviceinfo.keymaps or deviceinfo.keymaps.strip() == "":
|
||||
logging.info("NOTE: No valid keymap specified for device")
|
||||
return
|
||||
options = info["keymaps"].split(' ')
|
||||
options = deviceinfo.keymaps.split(' ')
|
||||
if (config.keymap != "" and
|
||||
config.keymap is not None and
|
||||
config.keymap in options):
|
||||
|
@ -525,7 +526,7 @@ def generate_binary_list(args: PmbArgs, chroot: Chroot, step):
|
|||
"""
|
||||
binary_ranges: Dict[int, int] = {}
|
||||
binary_list = []
|
||||
binaries = pmb.parse.deviceinfo()["sd_embed_firmware"].split(",")
|
||||
binaries = pmb.parse.deviceinfo().sd_embed_firmware.split(",")
|
||||
|
||||
for binary_offset in binaries:
|
||||
binary, _offset = binary_offset.split(':')
|
||||
|
@ -541,7 +542,7 @@ def generate_binary_list(args: PmbArgs, chroot: Chroot, step):
|
|||
f"/usr/share/{binary}")
|
||||
# Insure that embedding the firmware will not overrun the
|
||||
# first partition
|
||||
boot_part_start = pmb.parse.deviceinfo()["boot_part_start"] or "2048"
|
||||
boot_part_start = pmb.parse.deviceinfo().boot_part_start or "2048"
|
||||
max_size = (int(boot_part_start) * 512) - (offset * step)
|
||||
binary_size = os.path.getsize(binary_path)
|
||||
if binary_size > max_size:
|
||||
|
@ -574,13 +575,13 @@ def embed_firmware(args: PmbArgs, suffix: Chroot):
|
|||
:param suffix: of the chroot, which holds the firmware files (either the
|
||||
rootfs_{args.device} or installer_{args.device}
|
||||
"""
|
||||
if not pmb.parse.deviceinfo()["sd_embed_firmware"]:
|
||||
if not pmb.parse.deviceinfo().sd_embed_firmware:
|
||||
return
|
||||
|
||||
step = 1024
|
||||
if pmb.parse.deviceinfo()["sd_embed_firmware_step_size"]:
|
||||
if pmb.parse.deviceinfo().sd_embed_firmware_step_size:
|
||||
try:
|
||||
step = int(pmb.parse.deviceinfo()["sd_embed_firmware_step_size"])
|
||||
step = int(pmb.parse.deviceinfo().sd_embed_firmware_step_size)
|
||||
except ValueError:
|
||||
raise RuntimeError("Value for "
|
||||
"deviceinfo_sd_embed_firmware_step_size "
|
||||
|
@ -606,7 +607,7 @@ def write_cgpt_kpart(args: PmbArgs, layout, suffix: Chroot):
|
|||
:param layout: partition layout from get_partition_layout()
|
||||
:param suffix: of the chroot, which holds the image file to be flashed
|
||||
"""
|
||||
if not pmb.parse.deviceinfo()["cgpt_kpart"] or not args.install_cgpt:
|
||||
if not pmb.parse.deviceinfo().cgpt_kpart or not args.install_cgpt:
|
||||
return
|
||||
|
||||
device_rootfs = mount_device_rootfs(suffix)
|
||||
|
@ -667,7 +668,7 @@ def sanity_check_disk_size(args: PmbArgs):
|
|||
|
||||
|
||||
def get_ondev_pkgver(args: PmbArgs):
|
||||
arch = pmb.parse.deviceinfo()["arch"]
|
||||
arch = pmb.parse.deviceinfo().arch
|
||||
package = pmb.helpers.package.get(args, "postmarketos-ondev", arch)
|
||||
return package["version"].split("-r")[0]
|
||||
|
||||
|
@ -762,7 +763,7 @@ def create_fstab(args: PmbArgs, layout, chroot: Chroot):
|
|||
else f"UUID={get_uuid(args, root_dev)}"
|
||||
|
||||
boot_options = "nodev,nosuid,noexec"
|
||||
boot_filesystem = pmb.parse.deviceinfo()["boot_filesystem"] or "ext2"
|
||||
boot_filesystem = pmb.parse.deviceinfo().boot_filesystem or "ext2"
|
||||
if boot_filesystem in ("fat16", "fat32"):
|
||||
boot_filesystem = "vfat"
|
||||
boot_options += ",umask=0077,nosymfollow,codepage=437,iocharset=ascii"
|
||||
|
@ -812,15 +813,15 @@ def install_system_image(args: PmbArgs, size_reserve, chroot: Chroot, step, step
|
|||
device = chroot.name()
|
||||
# Partition and fill image file/disk block device
|
||||
logging.info(f"*** ({step}/{steps}) PREPARE INSTALL BLOCKDEVICE ***")
|
||||
pmb.chroot.shutdown(args, True)
|
||||
pmb.chroot.shutdown(True)
|
||||
(size_boot, size_root) = get_subpartitions_size(chroot)
|
||||
layout = get_partition_layout(size_reserve, pmb.parse.deviceinfo()["cgpt_kpart"] \
|
||||
layout = get_partition_layout(size_reserve, pmb.parse.deviceinfo().cgpt_kpart \
|
||||
and args.install_cgpt)
|
||||
if not args.rsync:
|
||||
pmb.install.blockdevice.create(args, size_boot, size_root,
|
||||
size_reserve, split, disk)
|
||||
if not split:
|
||||
if pmb.parse.deviceinfo()["cgpt_kpart"] and args.install_cgpt:
|
||||
if pmb.parse.deviceinfo().cgpt_kpart and args.install_cgpt:
|
||||
pmb.install.partition_cgpt(
|
||||
args, layout, size_boot, size_reserve)
|
||||
else:
|
||||
|
@ -862,12 +863,12 @@ def install_system_image(args: PmbArgs, size_reserve, chroot: Chroot, step, step
|
|||
if disk:
|
||||
logging.info(f"Unmounting disk {disk} (this may take a while "
|
||||
"to sync, please wait)")
|
||||
pmb.chroot.shutdown(args, True)
|
||||
pmb.chroot.shutdown(True)
|
||||
|
||||
# Convert rootfs to sparse using img2simg
|
||||
sparse = args.sparse
|
||||
if sparse is None:
|
||||
sparse = pmb.parse.deviceinfo()["flash_sparse"] == "true"
|
||||
sparse = pmb.parse.deviceinfo().flash_sparse == "true"
|
||||
|
||||
if sparse and not split and not disk:
|
||||
workdir = Path("/home/pmos/rootfs")
|
||||
|
@ -881,7 +882,7 @@ def install_system_image(args: PmbArgs, size_reserve, chroot: Chroot, step, step
|
|||
working_dir=workdir)
|
||||
|
||||
# patch sparse image for Samsung devices if specified
|
||||
samsungify_strategy = pmb.parse.deviceinfo()["flash_sparse_samsung_format"]
|
||||
samsungify_strategy = pmb.parse.deviceinfo().flash_sparse_samsung_format
|
||||
if samsungify_strategy:
|
||||
logging.info("(native) convert sparse image into Samsung's sparse image format")
|
||||
pmb.chroot.apk.install(["sm-sparse-image-tool"], Chroot.native())
|
||||
|
@ -894,14 +895,14 @@ def install_system_image(args: PmbArgs, size_reserve, chroot: Chroot, step, step
|
|||
working_dir=workdir)
|
||||
|
||||
|
||||
def print_flash_info(device: str, deviceinfo: Dict[str, str], split: bool, have_disk: bool):
|
||||
def print_flash_info(device: str, deviceinfo: Deviceinfo, split: bool, have_disk: bool):
|
||||
""" Print flashing information, based on the deviceinfo data and the
|
||||
pmbootstrap arguments. """
|
||||
logging.info("") # make the note stand out
|
||||
logging.info("*** FLASHING INFORMATION ***")
|
||||
|
||||
# System flash information
|
||||
method = deviceinfo["flash_method"]
|
||||
method = deviceinfo.flash_method
|
||||
flasher = pmb.config.flashers.get(method, {})
|
||||
flasher_actions = flasher.get("actions", {})
|
||||
if not isinstance(flasher_actions, dict):
|
||||
|
@ -934,16 +935,16 @@ def print_flash_info(device: str, deviceinfo: Dict[str, str], split: bool, have_
|
|||
# if current flasher supports vbmeta and partition is explicitly specified
|
||||
# in deviceinfo
|
||||
if "flash_vbmeta" in flasher_actions and \
|
||||
(deviceinfo["flash_fastboot_partition_vbmeta"] or
|
||||
deviceinfo["flash_heimdall_partition_vbmeta"]):
|
||||
(deviceinfo.flash_fastboot_partition_vbmeta or
|
||||
deviceinfo.flash_heimdall_partition_vbmeta):
|
||||
logging.info("* pmbootstrap flasher flash_vbmeta")
|
||||
logging.info(" Flashes vbmeta image with verification disabled flag.")
|
||||
|
||||
# if current flasher supports dtbo and partition is explicitly specified
|
||||
# in deviceinfo
|
||||
if "flash_dtbo" in flasher_actions and \
|
||||
(deviceinfo["flash_fastboot_partition_dtbo"] or
|
||||
deviceinfo["flash_heimdall_partition_dtbo"]):
|
||||
(deviceinfo.flash_fastboot_partition_dtbo or
|
||||
deviceinfo.flash_heimdall_partition_dtbo):
|
||||
logging.info("* pmbootstrap flasher flash_dtbo")
|
||||
logging.info(" Flashes dtbo image.")
|
||||
|
||||
|
@ -1226,7 +1227,7 @@ def create_device_rootfs(args: PmbArgs, step, steps):
|
|||
else:
|
||||
install_packages += ["postmarketos-base-nofde"]
|
||||
|
||||
pmb.helpers.repo.update(pmb.parse.deviceinfo()["arch"])
|
||||
pmb.helpers.repo.update(pmb.parse.deviceinfo().arch)
|
||||
|
||||
# Install uninstallable "dependencies" by default
|
||||
install_packages += get_recommends(args, install_packages)
|
||||
|
@ -1235,7 +1236,7 @@ def create_device_rootfs(args: PmbArgs, step, steps):
|
|||
# dependency, in case the version increased
|
||||
if config.build_pkgs_on_install:
|
||||
for pkgname in install_packages:
|
||||
pmb.build.package(context, pkgname, pmb.parse.deviceinfo()["arch"])
|
||||
pmb.build.package(context, pkgname, pmb.parse.deviceinfo().arch)
|
||||
|
||||
# Install all packages to device rootfs chroot (and rebuild the initramfs,
|
||||
# because that doesn't always happen automatically yet, e.g. when the user
|
||||
|
@ -1296,7 +1297,7 @@ def install(args: PmbArgs):
|
|||
steps = 4
|
||||
|
||||
if args.zap:
|
||||
pmb.chroot.zap(args, False)
|
||||
pmb.chroot.zap(False)
|
||||
|
||||
# Install required programs in native chroot
|
||||
step = 1
|
||||
|
@ -1313,7 +1314,7 @@ def install(args: PmbArgs):
|
|||
if args.no_image:
|
||||
return
|
||||
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
|
||||
|
@ -1324,7 +1325,7 @@ def install(args: PmbArgs):
|
|||
|
||||
print_flash_info(device, deviceinfo, args.split, True if args.disk and args.disk.is_absolute() else False)
|
||||
print_sshd_info(args)
|
||||
print_firewall_info(args.no_firewall, deviceinfo["arch"])
|
||||
print_firewall_info(args.no_firewall, deviceinfo.arch)
|
||||
|
||||
# Leave space before 'chroot still active' note
|
||||
logging.info("")
|
||||
|
|
|
@ -23,7 +23,7 @@ def format_and_mount_boot(args: PmbArgs, device, boot_label):
|
|||
ondev-prepare-internal-storage.sh in postmarketos-ondev.git!
|
||||
"""
|
||||
mountpoint = "/mnt/install/boot"
|
||||
filesystem = pmb.parse.deviceinfo()["boot_filesystem"] or "ext2"
|
||||
filesystem = pmb.parse.deviceinfo().boot_filesystem or "ext2"
|
||||
install_fsprogs(filesystem)
|
||||
logging.info(f"(native) format {device} (boot, {filesystem}), mount to"
|
||||
f" {mountpoint}")
|
||||
|
@ -72,7 +72,7 @@ def format_luks_root(args: PmbArgs, device):
|
|||
|
||||
|
||||
def get_root_filesystem(args: PmbArgs):
|
||||
ret = args.filesystem or pmb.parse.deviceinfo()["root_filesystem"] or "ext4"
|
||||
ret = args.filesystem or pmb.parse.deviceinfo().root_filesystem or "ext4"
|
||||
pmaports_cfg = pmb.config.pmaports.read_config()
|
||||
|
||||
supported = pmaports_cfg.get("supported_root_filesystems", "ext4")
|
||||
|
|
|
@ -42,7 +42,7 @@ def mount(args: PmbArgs, img_path: Path):
|
|||
init()
|
||||
|
||||
losetup_cmd: List[PathString] = ["losetup", "-f", img_path]
|
||||
sector_size = pmb.parse.deviceinfo()["rootfs_image_sector_size"]
|
||||
sector_size = pmb.parse.deviceinfo().rootfs_image_sector_size
|
||||
if sector_size:
|
||||
losetup_cmd += ["-b", str(int(sector_size))]
|
||||
|
||||
|
|
|
@ -80,15 +80,15 @@ def partition(args: PmbArgs, layout, size_boot, size_reserve):
|
|||
logging.info(f"(native) partition /dev/install (boot: {mb_boot},"
|
||||
f" reserved: {mb_reserved}, root: the rest)")
|
||||
|
||||
filesystem = pmb.parse.deviceinfo()["boot_filesystem"] or "ext2"
|
||||
filesystem = pmb.parse.deviceinfo().boot_filesystem or "ext2"
|
||||
|
||||
# Actual partitioning with 'parted'. Using check=False, because parted
|
||||
# sometimes "fails to inform the kernel". In case it really failed with
|
||||
# partitioning, the follow-up mounting/formatting will not work, so it
|
||||
# will stop there (see #463).
|
||||
boot_part_start = pmb.parse.deviceinfo()["boot_part_start"] or "2048"
|
||||
boot_part_start = pmb.parse.deviceinfo().boot_part_start or "2048"
|
||||
|
||||
partition_type = pmb.parse.deviceinfo()["partition_type"] or "msdos"
|
||||
partition_type = pmb.parse.deviceinfo().partition_type or "msdos"
|
||||
|
||||
commands = [
|
||||
["mktable", partition_type],
|
||||
|
@ -131,8 +131,8 @@ def partition_cgpt(args: PmbArgs, layout, size_boot, size_reserve):
|
|||
pmb.chroot.apk.install(["cgpt"], Chroot.native(), build=False)
|
||||
|
||||
cgpt = {
|
||||
'kpart_start': pmb.parse.deviceinfo()["cgpt_kpart_start"],
|
||||
'kpart_size': pmb.parse.deviceinfo()["cgpt_kpart_size"],
|
||||
'kpart_start': pmb.parse.deviceinfo().cgpt_kpart_start,
|
||||
'kpart_size': pmb.parse.deviceinfo().cgpt_kpart_size,
|
||||
}
|
||||
|
||||
# Convert to MB and print info
|
||||
|
|
|
@ -20,7 +20,7 @@ def create_zip(args: PmbArgs, chroot: Chroot, device: str):
|
|||
rootfs = "/mnt/rootfs_" + device
|
||||
flavor = pmb.helpers.frontend._parse_flavor(device)
|
||||
deviceinfo = pmb.parse.deviceinfo()
|
||||
method = deviceinfo["flash_method"]
|
||||
method = deviceinfo.flash_method
|
||||
fvars = pmb.flasher.variables(args, flavor, method)
|
||||
|
||||
# Install recovery installer package in buildroot
|
||||
|
@ -30,7 +30,7 @@ def create_zip(args: PmbArgs, chroot: Chroot, device: str):
|
|||
logging.info(f"({chroot}) create recovery zip")
|
||||
|
||||
for key in fvars:
|
||||
pmb.flasher.check_partition_blacklist(args, deviceinfo, key, fvars[key])
|
||||
pmb.flasher.check_partition_blacklist(deviceinfo, key, fvars[key])
|
||||
|
||||
# Create config file for the recovery installer
|
||||
options = {
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
# Copyright 2023 Oliver Smith
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
import copy
|
||||
from typing import Dict
|
||||
from pathlib import Path
|
||||
from typing import Dict, Optional
|
||||
from pmb.core import get_context
|
||||
from pmb.helpers import logging
|
||||
import os
|
||||
|
@ -9,77 +10,12 @@ import pmb.config
|
|||
import pmb.helpers.other
|
||||
import pmb.helpers.devices
|
||||
|
||||
|
||||
def sanity_check(info, path):
|
||||
# Resolve path for more readable error messages
|
||||
path = os.path.realpath(path)
|
||||
|
||||
# Legacy errors
|
||||
if "flash_methods" in info:
|
||||
raise RuntimeError("deviceinfo_flash_methods has been renamed to"
|
||||
" deviceinfo_flash_method. Please adjust your"
|
||||
" deviceinfo file: " + path)
|
||||
if "external_disk" in info or "external_disk_install" in info:
|
||||
raise RuntimeError("Instead of deviceinfo_external_disk and"
|
||||
" deviceinfo_external_disk_install, please use the"
|
||||
" new variable deviceinfo_external_storage in your"
|
||||
" deviceinfo file: " + path)
|
||||
if "msm_refresher" in info:
|
||||
raise RuntimeError("It is enough to specify 'msm-fb-refresher' in the"
|
||||
" depends of your device's package now. Please"
|
||||
" delete the deviceinfo_msm_refresher line in: " +
|
||||
path)
|
||||
if "flash_fastboot_vendor_id" in info:
|
||||
raise RuntimeError("Fastboot doesn't allow specifying the vendor ID"
|
||||
" anymore (#1830). Try removing the"
|
||||
" 'deviceinfo_flash_fastboot_vendor_id' line in: " +
|
||||
path + " (if you are sure that you need this, then"
|
||||
" we can probably bring it back to fastboot, just"
|
||||
" let us know in the postmarketOS issues!)")
|
||||
if "nonfree" in info:
|
||||
raise RuntimeError("deviceinfo_nonfree is unused. "
|
||||
"Please delete it in: " + path)
|
||||
if "dev_keyboard" in info:
|
||||
raise RuntimeError("deviceinfo_dev_keyboard is unused. "
|
||||
"Please delete it in: " + path)
|
||||
if "date" in info:
|
||||
raise RuntimeError("deviceinfo_date was replaced by deviceinfo_year. "
|
||||
"Set it to the release year in: " + path)
|
||||
|
||||
# "codename" is required
|
||||
codename = os.path.basename(os.path.dirname(path))
|
||||
if codename.startswith("device-"):
|
||||
codename = codename[7:]
|
||||
if "codename" not in info or info["codename"] != codename:
|
||||
raise RuntimeError(f"Please add 'deviceinfo_codename=\"{codename}\"' "
|
||||
f"to: {path}")
|
||||
|
||||
# "chassis" is required
|
||||
chassis_types = pmb.config.deviceinfo_chassis_types
|
||||
if "chassis" not in info or not info["chassis"]:
|
||||
logging.info("NOTE: the most commonly used chassis types in"
|
||||
" postmarketOS are 'handset' (for phones) and 'tablet'.")
|
||||
raise RuntimeError(f"Please add 'deviceinfo_chassis' to: {path}")
|
||||
|
||||
# "arch" is required
|
||||
if "arch" not in info or not info["arch"]:
|
||||
raise RuntimeError(f"Please add 'deviceinfo_arch' to: {path}")
|
||||
|
||||
arch = info["arch"]
|
||||
if (arch != pmb.config.arch_native and
|
||||
arch not in pmb.config.build_device_architectures):
|
||||
raise ValueError("Arch '" + arch + "' is not available in"
|
||||
" postmarketOS. If you would like to add it, see:"
|
||||
" <https://postmarketos.org/newarch>")
|
||||
|
||||
# "chassis" validation
|
||||
chassis_type = info["chassis"]
|
||||
if chassis_type not in chassis_types:
|
||||
raise RuntimeError(f"Unknown chassis type '{chassis_type}', should"
|
||||
f" be one of {', '.join(chassis_types)}. Fix this"
|
||||
f" and try again: {path}")
|
||||
|
||||
|
||||
# FIXME: It feels weird to handle this at parse time.
|
||||
# we should instead have the Deviceinfo object store
|
||||
# the attributes for all kernels and require the user
|
||||
# to specify which one they're using.
|
||||
# Basically: treat Deviceinfo as a standalone type that
|
||||
# doesn't need to traverse pmaports.
|
||||
def _parse_kernel_suffix(info, device, kernel):
|
||||
"""
|
||||
Remove the kernel suffix (as selected in 'pmbootstrap init') from
|
||||
|
@ -108,7 +44,7 @@ def _parse_kernel_suffix(info, device, kernel):
|
|||
ret = copy.copy(info)
|
||||
|
||||
suffix_kernel = kernel.replace("-", "_")
|
||||
for key in pmb.config.deviceinfo_attributes:
|
||||
for key in Deviceinfo.__annotations__.keys():
|
||||
key_kernel = f"{key}_{suffix_kernel}"
|
||||
if key_kernel not in ret:
|
||||
continue
|
||||
|
@ -121,8 +57,7 @@ def _parse_kernel_suffix(info, device, kernel):
|
|||
return ret
|
||||
|
||||
|
||||
# FIXME (#2324): Make deviceinfo a type! (class!!!)
|
||||
def deviceinfo(device=None, kernel=None) -> Dict[str, str]:
|
||||
def deviceinfo(device=None, kernel=None) -> "Deviceinfo":
|
||||
"""
|
||||
:param device: defaults to args.device
|
||||
:param kernel: defaults to args.kernel
|
||||
|
@ -150,25 +85,183 @@ def deviceinfo(device=None, kernel=None) -> Dict[str, str]:
|
|||
" start a new device port or to choose another device. It may have"
|
||||
" been renamed, see <https://postmarketos.org/renamed>")
|
||||
|
||||
ret = {}
|
||||
with open(path) as handle:
|
||||
for line in handle:
|
||||
if not line.startswith("deviceinfo_"):
|
||||
continue
|
||||
if "=" not in line:
|
||||
raise SyntaxError(f"{path}: No '=' found:\n\t{line}")
|
||||
split = line.split("=", 1)
|
||||
key = split[0][len("deviceinfo_"):]
|
||||
value = split[1].replace("\"", "").replace("\n", "")
|
||||
ret[key] = value
|
||||
di = Deviceinfo(path, kernel)
|
||||
|
||||
# Assign empty string as default
|
||||
for key in pmb.config.deviceinfo_attributes:
|
||||
if key not in ret:
|
||||
ret[key] = ""
|
||||
pmb.helpers.other.cache["deviceinfo"][device] = di
|
||||
return di
|
||||
|
||||
ret = _parse_kernel_suffix(ret, device, kernel)
|
||||
sanity_check(ret, path)
|
||||
class Deviceinfo:
|
||||
"""Variables from deviceinfo. Reference: <https://postmarketos.org/deviceinfo>
|
||||
Many of these are unused in pmbootstrap, and still more that are described
|
||||
on the wiki are missing. Eventually this class and associated code should
|
||||
be moved to a separate library and become the authoritative source of truth
|
||||
for the deviceinfo format."""
|
||||
path: Path
|
||||
# general
|
||||
format_version: str
|
||||
name: str
|
||||
manufacturer: str
|
||||
codename: str
|
||||
year: str
|
||||
dtb: str
|
||||
arch: str
|
||||
|
||||
pmb.helpers.other.cache["deviceinfo"][device] = ret
|
||||
return ret
|
||||
# device
|
||||
chassis: str
|
||||
keyboard: Optional[str] = ""
|
||||
external_storage: Optional[str] = ""
|
||||
dev_touchscreen: Optional[str] = ""
|
||||
dev_touchscreen_calibration: Optional[str] = ""
|
||||
append_dtb: Optional[str] = ""
|
||||
|
||||
# bootloader
|
||||
flash_method: Optional[str] = ""
|
||||
boot_filesystem: Optional[str] = ""
|
||||
|
||||
# flash
|
||||
flash_heimdall_partition_kernel: Optional[str] = ""
|
||||
flash_heimdall_partition_initfs: Optional[str] = ""
|
||||
flash_heimdall_partition_rootfs: Optional[str] = ""
|
||||
flash_heimdall_partition_system: Optional[str] = "" # deprecated
|
||||
flash_heimdall_partition_vbmeta: Optional[str] = ""
|
||||
flash_heimdall_partition_dtbo: Optional[str] = ""
|
||||
flash_fastboot_partition_kernel: Optional[str] = ""
|
||||
flash_fastboot_partition_rootfs: Optional[str] = ""
|
||||
flash_fastboot_partition_system: Optional[str] = "" # deprecated
|
||||
flash_fastboot_partition_vbmeta: Optional[str] = ""
|
||||
flash_fastboot_partition_dtbo: Optional[str] = ""
|
||||
flash_rk_partition_kernel: Optional[str] = ""
|
||||
flash_rk_partition_rootfs: Optional[str] = ""
|
||||
flash_rk_partition_system: Optional[str] = "" # deprecated
|
||||
flash_mtkclient_partition_kernel: Optional[str] = ""
|
||||
flash_mtkclient_partition_rootfs: Optional[str] = ""
|
||||
flash_mtkclient_partition_vbmeta: Optional[str] = ""
|
||||
flash_mtkclient_partition_dtbo: Optional[str] = ""
|
||||
generate_legacy_uboot_initfs: Optional[str] = ""
|
||||
kernel_cmdline: Optional[str] = ""
|
||||
generate_bootimg: Optional[str] = ""
|
||||
header_version: Optional[str] = ""
|
||||
bootimg_qcdt: Optional[str] = ""
|
||||
bootimg_mtk_mkimage: Optional[str] = "" # deprecated
|
||||
bootimg_mtk_label_kernel: Optional[str] = ""
|
||||
bootimg_mtk_label_ramdisk: Optional[str] = ""
|
||||
bootimg_dtb_second: Optional[str] = ""
|
||||
bootimg_custom_args: Optional[str] = ""
|
||||
flash_offset_base: Optional[str] = ""
|
||||
flash_offset_dtb: Optional[str] = ""
|
||||
flash_offset_kernel: Optional[str] = ""
|
||||
flash_offset_ramdisk: Optional[str] = ""
|
||||
flash_offset_second: Optional[str] = ""
|
||||
flash_offset_tags: Optional[str] = ""
|
||||
flash_pagesize: Optional[str] = ""
|
||||
flash_fastboot_max_size: Optional[str] = ""
|
||||
flash_sparse: Optional[str] = ""
|
||||
flash_sparse_samsung_format: Optional[str] = ""
|
||||
rootfs_image_sector_size: Optional[str] = ""
|
||||
sd_embed_firmware: Optional[str] = ""
|
||||
sd_embed_firmware_step_size: Optional[str] = ""
|
||||
partition_blacklist: Optional[str] = ""
|
||||
boot_part_start: Optional[str] = ""
|
||||
partition_type: Optional[str] = ""
|
||||
root_filesystem: Optional[str] = ""
|
||||
flash_kernel_on_update: Optional[str] = ""
|
||||
cgpt_kpart: Optional[str] = ""
|
||||
cgpt_kpart_start: Optional[str] = ""
|
||||
cgpt_kpart_size: Optional[str] = ""
|
||||
|
||||
# weston
|
||||
weston_pixman_type: Optional[str] = ""
|
||||
|
||||
# keymaps
|
||||
keymaps: Optional[str] = ""
|
||||
|
||||
@staticmethod
|
||||
def __validate(info: Dict[str, str], path: Path):
|
||||
# Resolve path for more readable error messages
|
||||
path = path.resolve()
|
||||
|
||||
# Legacy errors
|
||||
if "flash_methods" in info:
|
||||
raise RuntimeError("deviceinfo_flash_methods has been renamed to"
|
||||
" deviceinfo_flash_method. Please adjust your"
|
||||
f" deviceinfo file: {path}")
|
||||
if "external_disk" in info or "external_disk_install" in info:
|
||||
raise RuntimeError("Instead of deviceinfo_external_disk and"
|
||||
" deviceinfo_external_disk_install, please use the"
|
||||
" new variable deviceinfo_external_storage in your"
|
||||
f" deviceinfo file: {path}")
|
||||
if "msm_refresher" in info:
|
||||
raise RuntimeError("It is enough to specify 'msm-fb-refresher' in the"
|
||||
" depends of your device's package now. Please"
|
||||
" delete the deviceinfo_msm_refresher line in: "
|
||||
f"{path}")
|
||||
if "flash_fastboot_vendor_id" in info:
|
||||
raise RuntimeError("Fastboot doesn't allow specifying the vendor ID"
|
||||
" anymore (#1830). Try removing the"
|
||||
" 'deviceinfo_flash_fastboot_vendor_id' line in: "
|
||||
f"{path} (if you are sure that you need this, then"
|
||||
" we can probably bring it back to fastboot, just"
|
||||
" let us know in the postmarketOS issues!)")
|
||||
if "nonfree" in info:
|
||||
raise RuntimeError("deviceinfo_nonfree is unused. "
|
||||
f"Please delete it in: {path}")
|
||||
if "dev_keyboard" in info:
|
||||
raise RuntimeError("deviceinfo_dev_keyboard is unused. "
|
||||
f"Please delete it in: {path}")
|
||||
if "date" in info:
|
||||
raise RuntimeError("deviceinfo_date was replaced by deviceinfo_year. "
|
||||
f"Set it to the release year in: {path}")
|
||||
|
||||
# "codename" is required
|
||||
codename = os.path.basename(os.path.dirname(path))[7:]
|
||||
if "codename" not in info or info["codename"] != codename:
|
||||
raise RuntimeError(f"Please add 'deviceinfo_codename=\"{codename}\"' "
|
||||
f"to: {path}")
|
||||
|
||||
# "chassis" is required
|
||||
chassis_types = pmb.config.deviceinfo_chassis_types
|
||||
if "chassis" not in info or not info["chassis"]:
|
||||
logging.info("NOTE: the most commonly used chassis types in"
|
||||
" postmarketOS are 'handset' (for phones) and 'tablet'.")
|
||||
raise RuntimeError(f"Please add 'deviceinfo_chassis' to: {path}")
|
||||
|
||||
# "arch" is required
|
||||
if "arch" not in info or not info["arch"]:
|
||||
raise RuntimeError(f"Please add 'deviceinfo_arch' to: {path}")
|
||||
|
||||
arch = info["arch"]
|
||||
if (arch != pmb.config.arch_native and
|
||||
arch not in pmb.config.build_device_architectures):
|
||||
raise ValueError("Arch '" + arch + "' is not available in"
|
||||
" postmarketOS. If you would like to add it, see:"
|
||||
" <https://postmarketos.org/newarch>")
|
||||
|
||||
# "chassis" validation
|
||||
chassis_type = info["chassis"]
|
||||
if chassis_type not in chassis_types:
|
||||
raise RuntimeError(f"Unknown chassis type '{chassis_type}', should"
|
||||
f" be one of {', '.join(chassis_types)}. Fix this"
|
||||
f" and try again: {path}")
|
||||
|
||||
|
||||
def __init__(self, path: Path, kernel: Optional[str] = None):
|
||||
ret = {}
|
||||
with open(path) as handle:
|
||||
for line in handle:
|
||||
if not line.startswith("deviceinfo_"):
|
||||
continue
|
||||
if "=" not in line:
|
||||
raise SyntaxError(f"{path}: No '=' found:\n\t{line}")
|
||||
split = line.split("=", 1)
|
||||
key = split[0][len("deviceinfo_"):]
|
||||
value = split[1].replace("\"", "").replace("\n", "")
|
||||
ret[key] = value
|
||||
|
||||
ret = _parse_kernel_suffix(ret, ret["codename"], kernel)
|
||||
Deviceinfo.__validate(ret, path)
|
||||
|
||||
for key, value in ret.items():
|
||||
# FIXME: something to turn on and fix in the future
|
||||
# if key not in Deviceinfo.__annotations__.keys():
|
||||
# logging.warning(f"deviceinfo: {key} is not a known attribute")
|
||||
setattr(self, key, value)
|
||||
|
|
|
@ -92,7 +92,7 @@ def command_qemu(args: PmbArgs, device: str, arch, img_path, img_path_2nd=None):
|
|||
"""
|
||||
Generate the full qemu command with arguments to run postmarketOS
|
||||
"""
|
||||
cmdline = pmb.parse.deviceinfo()["kernel_cmdline"]
|
||||
cmdline = pmb.parse.deviceinfo().kernel_cmdline
|
||||
if args.cmdline:
|
||||
cmdline = args.cmdline
|
||||
|
||||
|
@ -221,7 +221,7 @@ def command_qemu(args: PmbArgs, device: str, arch, img_path, img_path_2nd=None):
|
|||
"if=pflash,format=raw,readonly=on,file=/usr/share/OVMF/OVMF.fd"]
|
||||
|
||||
# Kernel Virtual Machine (KVM) support
|
||||
native = pmb.config.arch_native == pmb.parse.deviceinfo()["arch"]
|
||||
native = pmb.config.arch_native == pmb.parse.deviceinfo().arch
|
||||
if args.qemu_kvm and native and os.path.exists("/dev/kvm"):
|
||||
command += ["-enable-kvm"]
|
||||
command += ["-cpu", "host"]
|
||||
|
@ -338,7 +338,7 @@ def run(args: PmbArgs):
|
|||
raise RuntimeError("'pmbootstrap qemu' can be only used with one of "
|
||||
"the QEMU device packages. Run 'pmbootstrap init' "
|
||||
"and select the 'qemu' vendor.")
|
||||
arch = pmb.parse.arch.alpine_to_qemu(pmb.parse.deviceinfo()["arch"])
|
||||
arch = pmb.parse.arch.alpine_to_qemu(pmb.parse.deviceinfo().arch)
|
||||
|
||||
img_path = system_image(device)
|
||||
img_path_2nd = None
|
||||
|
|
|
@ -57,7 +57,6 @@ class PmbArgs(Namespace):
|
|||
cross: bool
|
||||
details: bool
|
||||
details_to_stdout: bool
|
||||
deviceinfo: Dict[str, str]
|
||||
deviceinfo_parse_kernel: str
|
||||
devices: str
|
||||
disk: Path
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue