forked from Mirror/pmbootstrap
WIP: 2024-06-05: args hacking and more (MR 2252)
Continue removing args and do some other optimisations. Signed-off-by: Caleb Connolly <caleb@postmarketos.org>
This commit is contained in:
parent
5bb2390d98
commit
de4c912692
52 changed files with 498 additions and 464 deletions
|
@ -54,7 +54,7 @@ def properties(pkgname):
|
|||
raise ValueError("No generator available for " + pkgname + "!")
|
||||
|
||||
|
||||
def generate(args: PmbArgs, pkgname, fork_alpine=False):
|
||||
def generate(pkgname, fork_alpine=False):
|
||||
if fork_alpine:
|
||||
prefix, folder, options = (pkgname, "temp",
|
||||
{"confirm_overwrite": True})
|
||||
|
@ -83,7 +83,7 @@ def generate(args: PmbArgs, pkgname, fork_alpine=False):
|
|||
else:
|
||||
# Run pmb.aportgen.PREFIX.generate()
|
||||
# FIXME: this is really bad and hacky let's not do this please
|
||||
getattr(pmb.aportgen, prefix.replace("-", "_")).generate(args, pkgname)
|
||||
getattr(pmb.aportgen, prefix.replace("-", "_")).generate(pkgname)
|
||||
|
||||
# Move to the aports folder
|
||||
if os.path.exists(path_target):
|
||||
|
|
|
@ -11,7 +11,7 @@ import pmb.parse.apkindex
|
|||
from pmb.core import Chroot, get_context
|
||||
|
||||
|
||||
def generate(args: PmbArgs, pkgname):
|
||||
def generate(pkgname):
|
||||
arch = pkgname.split("-")[2]
|
||||
context = get_context()
|
||||
|
||||
|
|
|
@ -101,7 +101,7 @@ def ask_for_flash_method():
|
|||
" pmb/config/__init__.py.")
|
||||
|
||||
|
||||
def ask_for_bootimg(args: PmbArgs):
|
||||
def ask_for_bootimg():
|
||||
logging.info("You can analyze a known working boot.img file to"
|
||||
" automatically fill out the flasher information for your"
|
||||
" deviceinfo file. Either specify the path to an image or"
|
||||
|
@ -114,7 +114,7 @@ def ask_for_bootimg(args: PmbArgs):
|
|||
if not path:
|
||||
return None
|
||||
try:
|
||||
return pmb.parse.bootimg(args, path)
|
||||
return pmb.parse.bootimg(path)
|
||||
except Exception as e:
|
||||
logging.fatal("ERROR: " + str(e) + ". Please try again.")
|
||||
|
||||
|
@ -319,7 +319,7 @@ def generate_apkbuild(pkgname, name, arch, flash_method):
|
|||
handle.write(line[8:].replace(" " * 4, "\t") + "\n")
|
||||
|
||||
|
||||
def generate(args: PmbArgs, pkgname):
|
||||
def generate(pkgname):
|
||||
arch = ask_for_architecture()
|
||||
manufacturer = ask_for_manufacturer()
|
||||
name = ask_for_name(manufacturer)
|
||||
|
@ -330,7 +330,7 @@ def generate(args: PmbArgs, pkgname):
|
|||
flash_method = ask_for_flash_method()
|
||||
bootimg = None
|
||||
if flash_method in ["fastboot", "heimdall-bootimg"]:
|
||||
bootimg = ask_for_bootimg(args)
|
||||
bootimg = ask_for_bootimg()
|
||||
|
||||
generate_deviceinfo(pkgname, name, manufacturer, year, arch,
|
||||
chassis, has_keyboard, has_external_storage,
|
||||
|
|
|
@ -2,18 +2,17 @@
|
|||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
import pmb.aportgen.core
|
||||
from pmb.core import get_context
|
||||
from pmb.types import PmbArgs
|
||||
import pmb.helpers.git
|
||||
import pmb.helpers.run
|
||||
|
||||
|
||||
def generate(args: PmbArgs, pkgname):
|
||||
def generate(pkgname):
|
||||
# Copy original aport
|
||||
prefix = pkgname.split("-")[0]
|
||||
arch = pkgname.split("-")[1]
|
||||
context = get_context()
|
||||
if prefix == "gcc":
|
||||
upstream = pmb.aportgen.core.get_upstream_aport(args, "gcc", arch)
|
||||
upstream = pmb.aportgen.core.get_upstream_aport("gcc", arch)
|
||||
based_on = "main/gcc (from Alpine)"
|
||||
elif prefix == "gcc4":
|
||||
upstream = f"{context.config.aports}/main/gcc4"
|
||||
|
|
|
@ -11,7 +11,7 @@ import pmb.parse.apkindex
|
|||
from pmb.core import Chroot, get_context
|
||||
|
||||
|
||||
def generate(args: PmbArgs, pkgname):
|
||||
def generate(pkgname):
|
||||
arch = "x86"
|
||||
if pkgname != "grub-efi-x86":
|
||||
raise RuntimeError("only grub-efi-x86 is available")
|
||||
|
|
|
@ -8,7 +8,7 @@ import pmb.parse.apkindex
|
|||
import pmb.parse.arch
|
||||
|
||||
|
||||
def generate_apkbuild(args: PmbArgs, pkgname, deviceinfo, patches):
|
||||
def generate_apkbuild(pkgname, deviceinfo, patches):
|
||||
device = "-".join(pkgname.split("-")[1:])
|
||||
carch = pmb.parse.arch.alpine_to_kernel(deviceinfo["arch"])
|
||||
|
||||
|
@ -111,7 +111,7 @@ def generate_apkbuild(args: PmbArgs, pkgname, deviceinfo, patches):
|
|||
hndl.write(line[8:].replace(" " * 4, "\t") + "\n")
|
||||
|
||||
|
||||
def generate(args: PmbArgs, pkgname):
|
||||
def generate(pkgname):
|
||||
device = "-".join(pkgname.split("-")[1:])
|
||||
deviceinfo = pmb.parse.deviceinfo(device)
|
||||
work = get_context().config.work
|
||||
|
@ -129,4 +129,4 @@ def generate(args: PmbArgs, pkgname):
|
|||
"../../.shared-patches/linux/" + patch,
|
||||
(work / "aportgen" / patch)])
|
||||
|
||||
generate_apkbuild(args, pkgname, deviceinfo, patches)
|
||||
generate_apkbuild(pkgname, deviceinfo, patches)
|
||||
|
|
|
@ -5,13 +5,12 @@ import pmb.aportgen.core
|
|||
import pmb.build
|
||||
import pmb.chroot.apk
|
||||
import pmb.chroot.apk_static
|
||||
from pmb.types import PmbArgs
|
||||
import pmb.helpers.run
|
||||
import pmb.parse.apkindex
|
||||
from pmb.core import Chroot, get_context
|
||||
|
||||
|
||||
def generate(args: PmbArgs, pkgname):
|
||||
def generate(pkgname):
|
||||
arch = pkgname.split("-")[1]
|
||||
|
||||
# Parse musl version from APKINDEX
|
||||
|
|
|
@ -56,13 +56,14 @@ def arch(args: PmbArgs, pkgname: str):
|
|||
|
||||
apkbuild = pmb.parse.apkbuild(aport)
|
||||
arches = apkbuild["arch"]
|
||||
deviceinfo = pmb.parse.deviceinfo()
|
||||
|
||||
if get_context().config.build_default_device_arch:
|
||||
preferred_arch = args.deviceinfo["arch"]
|
||||
preferred_arch = deviceinfo["arch"]
|
||||
preferred_arch_2nd = pmb.config.arch_native
|
||||
else:
|
||||
preferred_arch = pmb.config.arch_native
|
||||
preferred_arch_2nd = args.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 = args.deviceinfo["arch"]
|
||||
arch = pmb.parse.deviceinfo()["arch"]
|
||||
apkbuild = pmb.parse.apkbuild(apkbuild_path, check_pkgname=False)
|
||||
if apkbuild["_outdir"]:
|
||||
kbuild_out = apkbuild["_outdir"]
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
# Copyright 2023 Oliver Smith
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
import os
|
||||
from pmb.core.context import get_context
|
||||
from pmb.helpers import logging
|
||||
from pathlib import Path
|
||||
from typing import Any, Dict
|
||||
|
@ -84,8 +85,8 @@ def get_outputdir(args: PmbArgs, pkgname: str, apkbuild: Dict[str, Any]) -> Path
|
|||
" template with: pmbootstrap aportgen " + pkgname)
|
||||
|
||||
|
||||
def extract_and_patch_sources(args: PmbArgs, pkgname: str, arch):
|
||||
pmb.build.copy_to_buildpath(args, pkgname)
|
||||
def extract_and_patch_sources(pkgname: str, arch):
|
||||
pmb.build.copy_to_buildpath(pkgname)
|
||||
logging.info("(native) extract kernel source")
|
||||
pmb.chroot.user(["abuild", "unpack"], working_dir=Path("/home/pmos/build"))
|
||||
logging.info("(native) apply patches")
|
||||
|
@ -102,14 +103,14 @@ def menuconfig(args: PmbArgs, pkgname: str, use_oldconfig):
|
|||
aport = pmb.helpers.pmaports.find(pkgname)
|
||||
apkbuild = pmb.parse.apkbuild(aport / "APKBUILD")
|
||||
arch = args.arch or get_arch(apkbuild)
|
||||
suffix = pmb.build.autodetect.chroot(apkbuild, arch)
|
||||
cross = pmb.build.autodetect.crosscompile(args, apkbuild, arch, suffix)
|
||||
chroot = pmb.build.autodetect.chroot(apkbuild, arch)
|
||||
cross = pmb.build.autodetect.crosscompile(apkbuild, arch, chroot)
|
||||
hostspec = pmb.parse.arch.alpine_to_hostspec(arch)
|
||||
|
||||
# Set up build tools and makedepends
|
||||
pmb.build.init(args, suffix)
|
||||
pmb.build.init(chroot)
|
||||
if cross:
|
||||
pmb.build.init_compiler(args, [], cross, arch)
|
||||
pmb.build.init_compiler(get_context(), [], cross, arch)
|
||||
|
||||
depends = apkbuild["makedepends"]
|
||||
copy_xauth = False
|
||||
|
@ -128,13 +129,13 @@ def menuconfig(args: PmbArgs, pkgname: str, use_oldconfig):
|
|||
else:
|
||||
depends += ["ncurses-dev"]
|
||||
|
||||
pmb.chroot.apk.install(depends)
|
||||
pmb.chroot.apk.install(depends, Chroot.native())
|
||||
|
||||
# Copy host's .xauthority into native
|
||||
if copy_xauth:
|
||||
pmb.chroot.other.copy_xauthority(args)
|
||||
|
||||
extract_and_patch_sources(args, pkgname, arch)
|
||||
extract_and_patch_sources(pkgname, arch)
|
||||
|
||||
# Check for background color variable
|
||||
color = os.environ.get("MENUCONFIG_COLOR")
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
import os
|
||||
from pmb.helpers import logging
|
||||
from pathlib import Path
|
||||
import pmb.chroot.run
|
||||
import pmb.chroot
|
||||
from pmb.types import PmbArgs
|
||||
import pmb.helpers.cli
|
||||
import pmb.parse
|
||||
|
|
|
@ -9,6 +9,7 @@ from typing import List
|
|||
|
||||
import pmb.chroot
|
||||
from pmb.types import PmbArgs
|
||||
import pmb.build
|
||||
import pmb.helpers.file
|
||||
import pmb.helpers.git
|
||||
import pmb.helpers.pmaports
|
||||
|
@ -99,7 +100,7 @@ def index_repo(args: PmbArgs, arch=None):
|
|||
|
||||
:param arch: when not defined, re-index all repos
|
||||
"""
|
||||
pmb.build.init(args)
|
||||
pmb.build.init()
|
||||
|
||||
channel = pmb.config.pmaports.read_config()["channel"]
|
||||
pkgdir = (get_context().config.work / "packages" / channel)
|
||||
|
|
|
@ -11,10 +11,10 @@ import pmb.helpers.cli
|
|||
from pmb.core import Chroot, get_context
|
||||
|
||||
|
||||
def build(args: PmbArgs, flavor, chroot: Chroot):
|
||||
def build(flavor, chroot: Chroot):
|
||||
# Update mkinitfs and hooks
|
||||
pmb.chroot.apk.install(["postmarketos-mkinitfs"], chroot)
|
||||
pmb.chroot.initfs_hooks.update(args, chroot)
|
||||
pmb.chroot.initfs_hooks.update(chroot)
|
||||
pmaports_cfg = pmb.config.pmaports.read_config()
|
||||
|
||||
# Call mkinitfs
|
||||
|
@ -30,7 +30,7 @@ def build(args: PmbArgs, flavor, chroot: Chroot):
|
|||
chroot)
|
||||
|
||||
|
||||
def extract(args: PmbArgs, flavor, chroot: Chroot, extra=False):
|
||||
def extract(flavor, chroot: Chroot, extra=False):
|
||||
"""
|
||||
Extract the initramfs to /tmp/initfs-extracted or the initramfs-extra to
|
||||
/tmp/initfs-extra-extracted and return the outside extraction path.
|
||||
|
@ -77,11 +77,11 @@ def extract(args: PmbArgs, flavor, chroot: Chroot, extra=False):
|
|||
return outside
|
||||
|
||||
|
||||
def ls(args: PmbArgs, flavor, suffix, extra=False):
|
||||
def ls( flavor, suffix, extra=False):
|
||||
tmp = "/tmp/initfs-extracted"
|
||||
if extra:
|
||||
tmp = "/tmp/initfs-extra-extracted"
|
||||
extract(args, flavor, suffix, extra)
|
||||
extract(flavor, suffix, extra)
|
||||
pmb.chroot.root(["ls", "-lahR", "."], suffix, Path(tmp), "stdout")
|
||||
pmb.chroot.root(["rm", "-r", tmp], suffix)
|
||||
|
||||
|
@ -95,17 +95,17 @@ def frontend(args: PmbArgs):
|
|||
# Handle initfs actions
|
||||
action = args.action_initfs
|
||||
if action == "build":
|
||||
build(args, flavor, chroot)
|
||||
build(flavor, chroot)
|
||||
elif action == "extract":
|
||||
dir = extract(args, flavor, chroot)
|
||||
dir = extract(flavor, chroot)
|
||||
logging.info(f"Successfully extracted initramfs to: {dir}")
|
||||
dir_extra = extract(args, flavor, chroot, True)
|
||||
dir_extra = extract(flavor, chroot, True)
|
||||
logging.info(f"Successfully extracted initramfs-extra to: {dir_extra}")
|
||||
elif action == "ls":
|
||||
logging.info("*** initramfs ***")
|
||||
ls(args, flavor, chroot)
|
||||
ls(flavor, chroot)
|
||||
logging.info("*** initramfs-extra ***")
|
||||
ls(args, flavor, chroot, True)
|
||||
ls(flavor, chroot, True)
|
||||
|
||||
# Handle hook actions
|
||||
elif action == "hook_ls":
|
||||
|
@ -117,7 +117,7 @@ def frontend(args: PmbArgs):
|
|||
pmb.chroot.initfs_hooks.delete(args.hook, chroot)
|
||||
|
||||
# Rebuild the initfs after adding/removing a hook
|
||||
build(args, flavor, chroot)
|
||||
build(flavor, chroot)
|
||||
|
||||
if action in ["ls", "extract"]:
|
||||
link = "https://wiki.postmarketos.org/wiki/Initramfs_development"
|
||||
|
|
|
@ -55,7 +55,7 @@ def delete(hook, suffix: Chroot):
|
|||
pmb.chroot.root(["apk", "del", f"{prefix}{hook}"], suffix)
|
||||
|
||||
|
||||
def update(args: PmbArgs, suffix: Chroot):
|
||||
def update(suffix: Chroot):
|
||||
"""
|
||||
Rebuild and update all hooks that are out of date
|
||||
"""
|
||||
|
|
|
@ -5,6 +5,7 @@ import os
|
|||
from pathlib import Path
|
||||
from typing import Dict
|
||||
import pmb.config
|
||||
import pmb.chroot.apk
|
||||
from pmb.types import PmbArgs
|
||||
import pmb.helpers.run
|
||||
import pmb.parse
|
||||
|
@ -98,7 +99,7 @@ def mount(chroot: Chroot):
|
|||
pmb.helpers.mount.bind(source, target_outer)
|
||||
|
||||
|
||||
def mount_native_into_foreign(args: PmbArgs, chroot: Chroot):
|
||||
def mount_native_into_foreign(chroot: Chroot):
|
||||
source = Chroot.native().path
|
||||
target = chroot / "native"
|
||||
pmb.helpers.mount.bind(source, target)
|
||||
|
|
|
@ -115,7 +115,7 @@ def zap_pkgs_local_mismatch(args: PmbArgs, confirm=True, dry=False):
|
|||
continue
|
||||
|
||||
# Aport path
|
||||
aport_path = pmb.helpers.pmaports.find_optional(args, origin)
|
||||
aport_path = pmb.helpers.pmaports.find_optional(origin)
|
||||
if not aport_path:
|
||||
logging.info(f"% rm {apk_path_short}"
|
||||
f" ({origin} aport not found)")
|
||||
|
|
|
@ -114,7 +114,7 @@ def ask_which_scripts_to_run(scripts_available):
|
|||
return ret
|
||||
|
||||
|
||||
def copy_git_repo_to_chroot(args: PmbArgs, topdir):
|
||||
def copy_git_repo_to_chroot(topdir):
|
||||
""" Create a tarball of the git repo (including unstaged changes and new
|
||||
files) and extract it in chroot_native.
|
||||
|
||||
|
@ -122,7 +122,7 @@ def copy_git_repo_to_chroot(args: PmbArgs, topdir):
|
|||
pmb.helpers.git.get_topdir()
|
||||
|
||||
"""
|
||||
pmb.chroot.init(args)
|
||||
pmb.chroot.init()
|
||||
tarball_path = Chroot.native() / "tmp/git.tar.gz"
|
||||
files = pmb.helpers.git.get_files(topdir)
|
||||
|
||||
|
@ -141,7 +141,7 @@ def copy_git_repo_to_chroot(args: PmbArgs, topdir):
|
|||
working_dir=ci_dir)
|
||||
|
||||
|
||||
def run_scripts(args: PmbArgs, topdir, scripts):
|
||||
def run_scripts(topdir, scripts):
|
||||
""" Run one of the given scripts after another, either natively or in a
|
||||
chroot. Display a progress message and stop on error (without printing
|
||||
a python stack trace).
|
||||
|
@ -174,7 +174,7 @@ def run_scripts(args: PmbArgs, topdir, scripts):
|
|||
else:
|
||||
# Run inside pmbootstrap chroot
|
||||
if not repo_copied:
|
||||
copy_git_repo_to_chroot(args, topdir)
|
||||
copy_git_repo_to_chroot(topdir)
|
||||
repo_copied = True
|
||||
|
||||
env = {"TESTUSER": "pmos"}
|
||||
|
|
|
@ -8,7 +8,6 @@ from pmb import commands
|
|||
from pmb.types import PathString
|
||||
from pmb.helpers import run
|
||||
from pmb.core import get_context
|
||||
from pmb import config
|
||||
|
||||
class Log(commands.Command):
|
||||
clear_log: bool
|
||||
|
@ -20,7 +19,7 @@ class Log(commands.Command):
|
|||
|
||||
def run(self):
|
||||
context = get_context()
|
||||
log_testsuite = config.work / "log_testsuite.txt"
|
||||
log_testsuite = context.config.work / "log_testsuite.txt"
|
||||
|
||||
if self.clear_log:
|
||||
run.user(["truncate", "-s", "0", context.log])
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
from pmb.core import get_context
|
||||
from pmb.core.chroot import Chroot
|
||||
from pmb.core.context import Context
|
||||
from pmb.helpers import logging
|
||||
import glob
|
||||
import json
|
||||
|
@ -38,13 +39,13 @@ def require_programs():
|
|||
f" {', '.join(missing)}")
|
||||
|
||||
|
||||
def ask_for_username(args: PmbArgs):
|
||||
def ask_for_username(args: PmbArgs, default_user: str):
|
||||
"""Ask for a reasonable username for the non-root user.
|
||||
|
||||
:returns: the username
|
||||
"""
|
||||
while True:
|
||||
ret = pmb.helpers.cli.ask("Username", None, args.user, False,
|
||||
ret = pmb.helpers.cli.ask("Username", None, default_user, False,
|
||||
"[a-z_][a-z0-9_-]*")
|
||||
if ret == "root":
|
||||
logging.fatal("ERROR: don't put \"root\" here. This is about"
|
||||
|
@ -139,8 +140,8 @@ def ask_for_channel(args: PmbArgs):
|
|||
" from the list above.")
|
||||
|
||||
|
||||
def ask_for_ui(args: PmbArgs, info):
|
||||
ui_list = pmb.helpers.ui.list_ui(args, info["arch"])
|
||||
def ask_for_ui(info):
|
||||
ui_list = pmb.helpers.ui.list_ui(info["arch"])
|
||||
hidden_ui_count = 0
|
||||
device_is_accelerated = info.get("gpu_accelerated") == "true"
|
||||
if not device_is_accelerated:
|
||||
|
@ -154,7 +155,7 @@ def ask_for_ui(args: PmbArgs, info):
|
|||
hidden_ui_count += 1
|
||||
|
||||
# Get default
|
||||
default: Any = args.ui
|
||||
default: Any = get_context().config.ui
|
||||
if default not in dict(ui_list).keys():
|
||||
default = pmb.config.defaults["ui"]
|
||||
|
||||
|
@ -176,7 +177,7 @@ def ask_for_ui(args: PmbArgs, info):
|
|||
" one from the list above.")
|
||||
|
||||
|
||||
def ask_for_ui_extras(args: PmbArgs, ui):
|
||||
def ask_for_ui_extras(config: Config, ui):
|
||||
apkbuild = pmb.helpers.pmaports.get(f"postmarketos-ui-{ui}",
|
||||
subpackages=False, must_exist=False)
|
||||
if not apkbuild:
|
||||
|
@ -190,17 +191,17 @@ def ask_for_ui_extras(args: PmbArgs, ui):
|
|||
f" {extra['pkgdesc']}")
|
||||
|
||||
return pmb.helpers.cli.confirm("Enable this package?",
|
||||
default=args.ui_extras)
|
||||
default=config.ui_extras)
|
||||
|
||||
|
||||
def ask_for_systemd(args: PmbArgs, ui):
|
||||
def ask_for_systemd(config: Config, ui):
|
||||
if "systemd" not in pmb.config.pmaports.read_config_repos():
|
||||
return args.systemd
|
||||
return config.systemd
|
||||
|
||||
if pmb.helpers.ui.check_option(ui, "pmb:systemd-never"):
|
||||
logging.info("Based on your UI selection, OpenRC will be used as init"
|
||||
" system. This UI does not support systemd.")
|
||||
return args.systemd
|
||||
return config.systemd
|
||||
|
||||
default_is_systemd = pmb.helpers.ui.check_option(ui, "pmb:systemd")
|
||||
not_str = " " if default_is_systemd else " not "
|
||||
|
@ -210,7 +211,7 @@ def ask_for_systemd(args: PmbArgs, ui):
|
|||
choices = pmb.config.allowed_values["systemd"]
|
||||
answer = pmb.helpers.cli.ask("Install systemd?",
|
||||
choices,
|
||||
args.systemd,
|
||||
config.systemd,
|
||||
validation_regex=f"^({'|'.join(choices)})$",
|
||||
complete=choices)
|
||||
return answer
|
||||
|
@ -314,7 +315,7 @@ def ask_for_provider_select(apkbuild, providers_cfg):
|
|||
" one from the list above.")
|
||||
|
||||
|
||||
def ask_for_provider_select_pkg(args: PmbArgs, pkgname, providers_cfg):
|
||||
def ask_for_provider_select_pkg(pkgname, providers_cfg):
|
||||
"""Look up the APKBUILD for the specified pkgname and ask for selectable
|
||||
providers that are specified using "_pmb_select".
|
||||
|
||||
|
@ -327,10 +328,10 @@ def ask_for_provider_select_pkg(args: PmbArgs, pkgname, providers_cfg):
|
|||
if not apkbuild:
|
||||
return
|
||||
|
||||
ask_for_provider_select(args, apkbuild, providers_cfg)
|
||||
ask_for_provider_select(apkbuild, providers_cfg)
|
||||
|
||||
|
||||
def ask_for_device_kernel(args: PmbArgs, device: str):
|
||||
def ask_for_device_kernel(config: Config, device: str):
|
||||
"""Ask for the kernel that should be used with the device.
|
||||
|
||||
:param device: code name, e.g. "lg-mako"
|
||||
|
@ -343,10 +344,10 @@ def ask_for_device_kernel(args: PmbArgs, device: str):
|
|||
# Get kernels
|
||||
kernels = pmb.parse._apkbuild.kernels(device)
|
||||
if not kernels:
|
||||
return args.kernel
|
||||
return config.kernel
|
||||
|
||||
# Get default
|
||||
default = args.kernel
|
||||
default = config.kernel
|
||||
if default not in kernels:
|
||||
default = list(kernels.keys())[0]
|
||||
|
||||
|
@ -374,7 +375,7 @@ def ask_for_device_kernel(args: PmbArgs, device: str):
|
|||
return ret
|
||||
|
||||
|
||||
def ask_for_device(config: Config):
|
||||
def ask_for_device(context: Context):
|
||||
"""
|
||||
Prompt for the device vendor, model, and kernel.
|
||||
|
||||
|
@ -383,16 +384,16 @@ def ask_for_device(config: Config):
|
|||
* device_exists: bool indicating if device port exists in repo
|
||||
* kernel: type of kernel (downstream, etc)
|
||||
"""
|
||||
vendors = sorted(pmb.helpers.devices.list_vendors(get_context().config.aports))
|
||||
vendors = sorted(pmb.helpers.devices.list_vendors(context.config.aports))
|
||||
logging.info("Choose your target device vendor (either an "
|
||||
"existing one, or a new one for porting).")
|
||||
logging.info(f"Available vendors ({len(vendors)}): {', '.join(vendors)}")
|
||||
|
||||
current_vendor = None
|
||||
current_codename = None
|
||||
if config.device:
|
||||
current_vendor = config.device.split("-", 1)[0]
|
||||
current_codename = config.device.split("-", 1)[1]
|
||||
if context.config.device:
|
||||
current_vendor = context.config.device.split("-", 1)[0]
|
||||
current_codename = context.config.device.split("-", 1)[1]
|
||||
|
||||
while True:
|
||||
vendor = pmb.helpers.cli.ask("Vendor", None, current_vendor,
|
||||
|
@ -409,7 +410,7 @@ def ask_for_device(config: Config):
|
|||
else:
|
||||
# Archived devices can be selected, but are not displayed
|
||||
devices = sorted(pmb.helpers.devices.list_codenames(
|
||||
get_context().config.aports, vendor, archived=False))
|
||||
context.config.aports, vendor, archived=False))
|
||||
# Remove "vendor-" prefixes from device list
|
||||
codenames = [x.split('-', 1)[1] for x in devices]
|
||||
logging.info(f"Available codenames ({len(codenames)}): " +
|
||||
|
@ -424,7 +425,7 @@ def ask_for_device(config: Config):
|
|||
device = f"{vendor}-{codename}"
|
||||
device_path = pmb.helpers.devices.find_path(device, 'deviceinfo')
|
||||
if device_path is None:
|
||||
if device == args.devicesdhbfvhubsud:
|
||||
if device == context.device:
|
||||
raise RuntimeError(
|
||||
"This device does not exist anymore, check"
|
||||
" <https://postmarketos.org/renamed>"
|
||||
|
@ -440,14 +441,14 @@ def ask_for_device(config: Config):
|
|||
pmb.aportgen.generate(f"device-{device}")
|
||||
pmb.aportgen.generate(f"linux-{device}")
|
||||
elif any("archived" == x for x in device_path.parts):
|
||||
apkbuild = f"{device_path[:-len('deviceinfo')]}APKBUILD"
|
||||
apkbuild = device_path.parent / "APKBUILD"
|
||||
archived = pmb.parse._apkbuild.archived(apkbuild)
|
||||
logging.info(f"WARNING: {device} is archived: {archived}")
|
||||
if not pmb.helpers.cli.confirm(args):
|
||||
if not pmb.helpers.cli.confirm():
|
||||
continue
|
||||
break
|
||||
|
||||
kernel = ask_for_device_kernel(args, device)
|
||||
kernel = ask_for_device_kernel(context.config, device)
|
||||
return (device, device_path is not None, kernel)
|
||||
|
||||
|
||||
|
@ -675,7 +676,7 @@ def frontend(args: PmbArgs):
|
|||
pmb.config.pmaports.install_githooks()
|
||||
|
||||
# Device
|
||||
device, device_exists, kernel = ask_for_device(config)
|
||||
device, device_exists, kernel = ask_for_device(get_context())
|
||||
config.device = device
|
||||
config.kernel = kernel
|
||||
|
||||
|
@ -689,19 +690,19 @@ def frontend(args: PmbArgs):
|
|||
if device_exists:
|
||||
config.keymap = ask_for_keymaps(args, info)
|
||||
|
||||
config.user = ask_for_username(args)
|
||||
ask_for_provider_select_pkg(args, "postmarketos-base", config.providers)
|
||||
ask_for_provider_select_pkg(args, "postmarketos-base-ui", config.providers)
|
||||
config.user = ask_for_username(args, config.user)
|
||||
ask_for_provider_select_pkg("postmarketos-base", config.providers)
|
||||
ask_for_provider_select_pkg("postmarketos-base-ui", config.providers)
|
||||
|
||||
# UI and various build options
|
||||
ui = ask_for_ui(args, info)
|
||||
ui = ask_for_ui(info)
|
||||
config.ui = ui
|
||||
config.ui_extras = ask_for_ui_extras(args, ui)
|
||||
config.ui_extras = ask_for_ui_extras(config, ui)
|
||||
|
||||
# systemd
|
||||
config.systemd = ask_for_systemd(args, ui)
|
||||
config.systemd = ask_for_systemd(config, ui)
|
||||
|
||||
ask_for_provider_select_pkg(args, f"postmarketos-ui-{ui}",
|
||||
ask_for_provider_select_pkg(f"postmarketos-ui-{ui}",
|
||||
config.providers)
|
||||
ask_for_additional_options(args, config)
|
||||
|
||||
|
|
|
@ -13,14 +13,22 @@ class Context():
|
|||
quiet: bool = False
|
||||
command_timeout: float = 900
|
||||
sudo_timer: bool = False
|
||||
force: bool = False
|
||||
log: Path
|
||||
# The architecture of the selected device
|
||||
device_arch: Optional[str] = None
|
||||
offline: bool = False
|
||||
|
||||
# assume yes to prompts
|
||||
assume_yes: bool = False
|
||||
|
||||
# Operate offline
|
||||
offline: bool = False
|
||||
|
||||
# Device we are operating on
|
||||
# FIXME: should not be in global context, only
|
||||
# specific actions actually depend on this
|
||||
device: str = ""
|
||||
|
||||
# The pmbootstrap subcommand
|
||||
command: str = ""
|
||||
|
||||
|
@ -41,6 +49,7 @@ class Context():
|
|||
|
||||
__context: Context
|
||||
|
||||
# mypy: disable-error-code="return-value"
|
||||
def get_context(allow_failure: bool=False) -> Context:
|
||||
"""Get immutable global runtime context."""
|
||||
global __context
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
from pmb.core.context import get_context
|
||||
from pmb.helpers import logging
|
||||
import os
|
||||
|
||||
|
@ -9,7 +10,8 @@ import pmb.export
|
|||
from pmb.core import Chroot, ChrootType
|
||||
|
||||
|
||||
def frontend(args: PmbArgs):
|
||||
def frontend(args: PmbArgs): # FIXME: ARGS_REFACTOR
|
||||
context = get_context()
|
||||
# Create the export folder
|
||||
target = args.export_folder
|
||||
if not os.path.exists(target):
|
||||
|
@ -17,18 +19,18 @@ def frontend(args: PmbArgs):
|
|||
|
||||
# Rootfs image note
|
||||
chroot = Chroot.native()
|
||||
rootfs_dir = chroot / "home/pmos/rootfs" / args.devicesdhbfvhubsud
|
||||
rootfs_dir = chroot / "home/pmos/rootfs" / context.device
|
||||
if not rootfs_dir.glob("*.img"):
|
||||
logging.info("NOTE: To export the rootfs image, run 'pmbootstrap"
|
||||
" install' first (without the 'disk' parameter).")
|
||||
|
||||
# Rebuild the initramfs, just to make sure (see #69)
|
||||
flavor = pmb.helpers.frontend._parse_flavor(args, args.autoinstall)
|
||||
flavor = pmb.helpers.frontend._parse_flavor(context.device, args.autoinstall)
|
||||
if args.autoinstall:
|
||||
pmb.chroot.initfs.build(args, flavor, Chroot(ChrootType.ROOTFS, args.devicesdhbfvhubsud))
|
||||
pmb.chroot.initfs.build(flavor, Chroot(ChrootType.ROOTFS, context.device))
|
||||
|
||||
# Do the export, print all files
|
||||
logging.info(f"Export symlinks to: {target}")
|
||||
if args.odin_flashable_tar:
|
||||
pmb.export.odin(args, flavor, target)
|
||||
pmb.export.odin(context, flavor, target)
|
||||
pmb.export.symlinks(args, flavor, target)
|
||||
|
|
|
@ -1,25 +1,26 @@
|
|||
# Copyright 2023 Oliver Smith
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
from pmb.core.context import Context
|
||||
from pmb.helpers import logging
|
||||
from pathlib import Path
|
||||
|
||||
import pmb.build
|
||||
import pmb.chroot.apk
|
||||
import pmb.config
|
||||
from pmb.types import PmbArgs
|
||||
import pmb.flasher
|
||||
import pmb.helpers.file
|
||||
from pmb.core import Chroot, ChrootType
|
||||
|
||||
|
||||
def odin(args: PmbArgs, flavor, folder: Path):
|
||||
def odin(context: Context, flavor, folder: Path):
|
||||
"""
|
||||
Create Odin flashable tar file with kernel and initramfs
|
||||
for devices configured with the flasher method 'heimdall-isorec'
|
||||
and with boot.img for devices with 'heimdall-bootimg'
|
||||
"""
|
||||
pmb.flasher.init(args)
|
||||
suffix = Chroot(ChrootType.ROOTFS, args.devicesdhbfvhubsud)
|
||||
pmb.flasher.init(context.device)
|
||||
suffix = Chroot(ChrootType.ROOTFS, context.device)
|
||||
deviceinfo = pmb.parse.deviceinfo(context.device)
|
||||
|
||||
# Backwards compatibility with old mkinitfs (pma#660)
|
||||
suffix_flavor = f"-{flavor}"
|
||||
|
@ -28,7 +29,7 @@ def odin(args: PmbArgs, flavor, folder: Path):
|
|||
suffix_flavor = ""
|
||||
|
||||
# Validate method
|
||||
method = args.deviceinfo["flash_method"]
|
||||
method = deviceinfo["flash_method"]
|
||||
if not method.startswith("heimdall-"):
|
||||
raise RuntimeError("An odin flashable tar is not supported"
|
||||
f" for the flash method '{method}' specified"
|
||||
|
@ -36,10 +37,8 @@ def odin(args: PmbArgs, flavor, folder: Path):
|
|||
" Only 'heimdall' methods are supported.")
|
||||
|
||||
# Partitions
|
||||
partition_kernel = \
|
||||
args.deviceinfo["flash_heimdall_partition_kernel"] or "KERNEL"
|
||||
partition_initfs = \
|
||||
args.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"
|
||||
|
@ -49,12 +48,12 @@ def odin(args: PmbArgs, flavor, folder: Path):
|
|||
# Odin flashable tar generation script
|
||||
# (because redirecting stdin/stdout is not allowed
|
||||
# in pmbootstrap's chroot/shell functions for security reasons)
|
||||
odin_script = Chroot(ChrootType.ROOTFS, args.devicesdhbfvhubsud) / "tmp/_odin.sh"
|
||||
odin_script = Chroot(ChrootType.ROOTFS, context.device) / "tmp/_odin.sh"
|
||||
with odin_script.open("w") as handle:
|
||||
odin_kernel_md5 = f"{partition_kernel}.bin.md5"
|
||||
odin_initfs_md5 = f"{partition_initfs}.bin.md5"
|
||||
odin_device_tar = f"{args.devicesdhbfvhubsud}.tar"
|
||||
odin_device_tar_md5 = f"{args.devicesdhbfvhubsud}.tar.md5"
|
||||
odin_device_tar = f"{context.device}.tar"
|
||||
odin_device_tar_md5 = f"{context.device}.tar.md5"
|
||||
|
||||
handle.write(
|
||||
"#!/bin/sh\n"
|
||||
|
@ -90,7 +89,7 @@ def odin(args: PmbArgs, flavor, folder: Path):
|
|||
|
||||
# Move Odin flashable tar to native chroot and cleanup temp folder
|
||||
pmb.chroot.user(["mkdir", "-p", "/home/pmos/rootfs"])
|
||||
pmb.chroot.root(["mv", f"/mnt/rootfs_{args.devicesdhbfvhubsud}{temp_folder}"
|
||||
pmb.chroot.root(["mv", f"/mnt/rootfs_{context.device}{temp_folder}"
|
||||
f"/{odin_device_tar_md5}", "/home/pmos/rootfs/"]),
|
||||
pmb.chroot.root(["chown", "pmos:pmos",
|
||||
f"/home/pmos/rootfs/{odin_device_tar_md5}"])
|
||||
|
@ -99,7 +98,7 @@ def odin(args: PmbArgs, flavor, folder: Path):
|
|||
# Create the symlink
|
||||
file = Chroot.native() / "home/pmos/rootfs" / odin_device_tar_md5
|
||||
link = folder / odin_device_tar_md5
|
||||
pmb.helpers.file.symlink(args, file, link)
|
||||
pmb.helpers.file.symlink(file, link)
|
||||
|
||||
# Display a readable message
|
||||
msg = f" * {odin_device_tar_md5}"
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
# Copyright 2023 Oliver Smith
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
from pmb.core.context import get_context
|
||||
from pmb.helpers import logging
|
||||
from pathlib import Path
|
||||
from typing import List
|
||||
|
@ -18,6 +19,9 @@ def symlinks(args: PmbArgs, flavor, folder: Path):
|
|||
"""
|
||||
Create convenience symlinks to the rootfs and boot files.
|
||||
"""
|
||||
|
||||
context = get_context()
|
||||
arch = pmb.parse.deviceinfo(context.device)["arch"]
|
||||
|
||||
# Backwards compatibility with old mkinitfs (pma#660)
|
||||
suffix = f"-{flavor}"
|
||||
|
@ -35,28 +39,28 @@ def symlinks(args: PmbArgs, flavor, folder: Path):
|
|||
f"uInitrd{suffix}": "Initramfs, legacy u-boot image format",
|
||||
f"uImage{suffix}": "Kernel, legacy u-boot image format",
|
||||
f"vmlinuz{suffix}": "Linux kernel",
|
||||
f"{args.devicesdhbfvhubsud}.img": "Rootfs with partitions for /boot and /",
|
||||
f"{args.devicesdhbfvhubsud}-boot.img": "Boot partition image",
|
||||
f"{args.devicesdhbfvhubsud}-root.img": "Root partition image",
|
||||
f"pmos-{args.devicesdhbfvhubsud}.zip": "Android recovery flashable zip",
|
||||
f"{context.device}.img": "Rootfs with partitions for /boot and /",
|
||||
f"{context.device}-boot.img": "Boot partition image",
|
||||
f"{context.device}-root.img": "Root partition image",
|
||||
f"pmos-{context.device}.zip": "Android recovery flashable zip",
|
||||
"lk2nd.img": "Secondary Android bootloader",
|
||||
}
|
||||
|
||||
# Generate a list of patterns
|
||||
chroot_native = Chroot.native()
|
||||
path_boot = Chroot(ChrootType.ROOTFS, args.devicesdhbfvhubsud) / "boot"
|
||||
chroot_buildroot = Chroot.buildroot(args.deviceinfo['arch'])
|
||||
path_boot = Chroot(ChrootType.ROOTFS, context.device) / "boot"
|
||||
chroot_buildroot = Chroot.buildroot(arch)
|
||||
files: List[Path] = [
|
||||
path_boot / f"boot.img{suffix}",
|
||||
path_boot / f"uInitrd{suffix}",
|
||||
path_boot / f"uImage{suffix}",
|
||||
path_boot / f"vmlinuz{suffix}",
|
||||
path_boot / "dtbo.img",
|
||||
chroot_native / "home/pmos/rootfs" / f"{args.devicesdhbfvhubsud}.img",
|
||||
chroot_native / "home/pmos/rootfs" / f"{args.devicesdhbfvhubsud}-boot.img",
|
||||
chroot_native / "home/pmos/rootfs" / f"{args.devicesdhbfvhubsud}-root.img",
|
||||
chroot_native / "home/pmos/rootfs" / f"{context.device}.img",
|
||||
chroot_native / "home/pmos/rootfs" / f"{context.device}-boot.img",
|
||||
chroot_native / "home/pmos/rootfs" / f"{context.device}-root.img",
|
||||
chroot_buildroot / "var/libpostmarketos-android-recovery-installer" /
|
||||
f"pmos-{args.devicesdhbfvhubsud}.zip",
|
||||
f"pmos-{context.device}.zip",
|
||||
path_boot / "lk2nd.img"
|
||||
]
|
||||
|
||||
|
@ -73,4 +77,4 @@ def symlinks(args: PmbArgs, flavor, folder: Path):
|
|||
msg += " (" + info[basename] + ")"
|
||||
logging.info(msg)
|
||||
|
||||
pmb.helpers.file.symlink(args, file, link)
|
||||
pmb.helpers.file.symlink(file, link)
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
# 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
|
||||
|
@ -15,106 +17,93 @@ import pmb.parse.kconfig
|
|||
from pmb.core import Chroot, ChrootType
|
||||
|
||||
|
||||
def kernel(args: PmbArgs):
|
||||
def kernel(device: str, deviceinfo: Dict[str, str], boot: bool = False, autoinstall: bool = False):
|
||||
# Rebuild the initramfs, just to make sure (see #69)
|
||||
flavor = pmb.helpers.frontend._parse_flavor(args, args.autoinstall)
|
||||
if args.autoinstall:
|
||||
pmb.chroot.initfs.build(args, flavor, Chroot(ChrootType.ROOTFS, args.devicesdhbfvhubsud))
|
||||
flavor = pmb.helpers.frontend._parse_flavor(device, autoinstall)
|
||||
if autoinstall:
|
||||
pmb.chroot.initfs.build(flavor, Chroot(ChrootType.ROOTFS, device))
|
||||
|
||||
# Check kernel config
|
||||
pmb.parse.kconfig.check(args, flavor, must_exist=False)
|
||||
pmb.parse.kconfig.check(flavor, must_exist=False)
|
||||
|
||||
# Generate the paths and run the flasher
|
||||
if args.action_flasher == "boot":
|
||||
if boot:
|
||||
logging.info("(native) boot " + flavor + " kernel")
|
||||
pmb.flasher.run(args, "boot", flavor)
|
||||
pmb.flasher.run(device, deviceinfo, "boot", flavor)
|
||||
else:
|
||||
logging.info("(native) flash kernel " + flavor)
|
||||
pmb.flasher.run(args, "flash_kernel", flavor)
|
||||
pmb.flasher.run(device, deviceinfo, "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"
|
||||
" booted:")
|
||||
logging.info("ssh {}@{}".format(args.user, pmb.config.default_ip))
|
||||
logging.info(f"ssh {get_context().config.user}@{pmb.config.default_ip}")
|
||||
logging.info("NOTE: If you enabled full disk encryption, you should make"
|
||||
" sure that Unl0kr has been properly configured for your"
|
||||
" device")
|
||||
|
||||
|
||||
def list_flavors(args: PmbArgs):
|
||||
suffix = Chroot(ChrootType.ROOTFS, args.devicesdhbfvhubsud)
|
||||
logging.info(f"({suffix}) installed kernel flavors:")
|
||||
logging.info("* " + pmb.chroot.other.kernel_flavor_installed(suffix))
|
||||
def list_flavors(device: str):
|
||||
chroot = Chroot(ChrootType.ROOTFS, device)
|
||||
logging.info(f"({chroot}) installed kernel flavors:")
|
||||
logging.info("* " + pmb.chroot.other.kernel_flavor_installed(chroot))
|
||||
|
||||
|
||||
def rootfs(args: PmbArgs):
|
||||
method = args.flash_method or args.deviceinfo["flash_method"]
|
||||
|
||||
def rootfs(device: str, deviceinfo: Dict[str, str], 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"{args.devicesdhbfvhubsud}{suffix}"
|
||||
img_path = Chroot.native() / "home/pmos/rootfs" / f"{device}{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 args.deviceinfo["flash_fastboot_max_size"]:
|
||||
and deviceinfo["flash_fastboot_max_size"]:
|
||||
img_size = img_path.stat().st_size / 1024**2
|
||||
max_size = int(args.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(args, "flash_rootfs")
|
||||
pmb.flasher.run(device, deviceinfo, "flash_rootfs")
|
||||
|
||||
|
||||
def flash_vbmeta(args: PmbArgs):
|
||||
logging.info("(native) flash vbmeta.img with verity disabled flag")
|
||||
pmb.flasher.run(args, "flash_vbmeta")
|
||||
def list_devices(device, deviceinfo):
|
||||
pmb.flasher.run(device, deviceinfo, "list_devices")
|
||||
|
||||
|
||||
def flash_dtbo(args: PmbArgs):
|
||||
logging.info("(native) flash dtbo image")
|
||||
pmb.flasher.run(args, "flash_dtbo")
|
||||
|
||||
|
||||
def list_devices(args: PmbArgs):
|
||||
pmb.flasher.run(args, "list_devices")
|
||||
|
||||
|
||||
def sideload(args: PmbArgs):
|
||||
def sideload(device: str, deviceinfo: Dict[str, str]):
|
||||
# Install depends
|
||||
pmb.flasher.install_depends(args)
|
||||
pmb.flasher.install_depends()
|
||||
|
||||
# Mount the buildroot
|
||||
chroot = Chroot.buildroot(args.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-{args.devicesdhbfvhubsud}.zip").exists():
|
||||
/ f"pmos-{device}.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(args, "sideload")
|
||||
pmb.flasher.run(device, deviceinfo, "sideload")
|
||||
|
||||
|
||||
def flash_lk2nd(args: PmbArgs):
|
||||
method = args.flash_method or args.deviceinfo["flash_method"]
|
||||
def flash_lk2nd(device: str, deviceinfo: Dict[str, str], 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(args)
|
||||
pmb.flasher.init(device)
|
||||
logging.info("(native) checking current fastboot product")
|
||||
output = pmb.chroot.root(["fastboot", "getvar", "product"],
|
||||
output="interactive", output_return=True)
|
||||
|
@ -125,7 +114,7 @@ def flash_lk2nd(args: PmbArgs):
|
|||
" bootloader mode to re-flash lk2nd.")
|
||||
|
||||
# Get the lk2nd package (which is a dependency of the device package)
|
||||
device_pkg = f"device-{args.devicesdhbfvhubsud}"
|
||||
device_pkg = f"device-{device}"
|
||||
apkbuild = pmb.helpers.pmaports.get(device_pkg)
|
||||
lk2nd_pkg = None
|
||||
for dep in apkbuild["depends"]:
|
||||
|
@ -136,16 +125,19 @@ def flash_lk2nd(args: PmbArgs):
|
|||
if not lk2nd_pkg:
|
||||
raise RuntimeError(f"{device_pkg} does not depend on any lk2nd package")
|
||||
|
||||
suffix = Chroot(ChrootType.ROOTFS, args.devicesdhbfvhubsud)
|
||||
suffix = Chroot(ChrootType.ROOTFS, device)
|
||||
pmb.chroot.apk.install([lk2nd_pkg], suffix)
|
||||
|
||||
logging.info("(native) flash lk2nd image")
|
||||
pmb.flasher.run(args, "flash_lk2nd")
|
||||
pmb.flasher.run(device, deviceinfo, "flash_lk2nd")
|
||||
|
||||
|
||||
def frontend(args: PmbArgs):
|
||||
context = get_context()
|
||||
action = args.action_flasher
|
||||
method = args.flash_method or args.deviceinfo["flash_method"]
|
||||
device = context.device
|
||||
deviceinfo = pmb.parse.deviceinfo()
|
||||
method = args.flash_method or deviceinfo["flash_method"]
|
||||
|
||||
if method == "none" and action in ["boot", "flash_kernel", "flash_rootfs",
|
||||
"flash_lk2nd"]:
|
||||
|
@ -153,18 +145,20 @@ def frontend(args: PmbArgs):
|
|||
return
|
||||
|
||||
if action in ["boot", "flash_kernel"]:
|
||||
kernel(args)
|
||||
kernel(device, deviceinfo)
|
||||
elif action == "flash_rootfs":
|
||||
rootfs(args)
|
||||
rootfs(device, deviceinfo, method)
|
||||
elif action == "flash_vbmeta":
|
||||
flash_vbmeta(args)
|
||||
logging.info("(native) flash vbmeta.img with verity disabled flag")
|
||||
pmb.flasher.run(device, deviceinfo, "flash_vbmeta")
|
||||
elif action == "flash_dtbo":
|
||||
flash_dtbo(args)
|
||||
logging.info("(native) flash dtbo image")
|
||||
pmb.flasher.run(device, deviceinfo, "flash_dtbo")
|
||||
elif action == "flash_lk2nd":
|
||||
flash_lk2nd(args)
|
||||
flash_lk2nd(device, deviceinfo, method)
|
||||
elif action == "list_flavors":
|
||||
list_flavors(args)
|
||||
list_flavors(device)
|
||||
elif action == "list_devices":
|
||||
list_devices(args)
|
||||
list_devices(device, deviceinfo)
|
||||
elif action == "sideload":
|
||||
sideload(args)
|
||||
sideload(device, deviceinfo)
|
||||
|
|
|
@ -5,15 +5,18 @@ import pmb.config
|
|||
import pmb.config.pmaports
|
||||
from pmb.types import PmbArgs
|
||||
import pmb.helpers.mount
|
||||
import pmb.helpers.args
|
||||
from pmb.helpers.mount import mount_device_rootfs
|
||||
from pmb.core import Chroot, ChrootType
|
||||
|
||||
|
||||
def install_depends(args: PmbArgs):
|
||||
def install_depends() -> None:
|
||||
args: PmbArgs = pmb.helpers.args.please_i_really_need_args()
|
||||
if hasattr(args, 'flash_method'):
|
||||
method = args.flash_method or args.deviceinfo["flash_method"]
|
||||
else:
|
||||
method = args.deviceinfo["flash_method"]
|
||||
method = args.flash_method
|
||||
|
||||
if not method:
|
||||
method = pmb.parse.deviceinfo()["flash_method"]
|
||||
|
||||
if method not in pmb.config.flashers:
|
||||
raise RuntimeError(f"Flash method {method} is not supported by the"
|
||||
|
@ -43,12 +46,12 @@ def install_depends(args: PmbArgs):
|
|||
pmb.chroot.apk.install(depends, Chroot.native())
|
||||
|
||||
|
||||
def init(args: PmbArgs):
|
||||
install_depends(args)
|
||||
def init(device: str):
|
||||
install_depends()
|
||||
|
||||
# Mount folders from host system
|
||||
for folder in pmb.config.flash_mount_bind:
|
||||
pmb.helpers.mount.bind(folder, Chroot.native() / folder)
|
||||
|
||||
# Mount device chroot inside native chroot (required for kernel/ramdisk)
|
||||
mount_device_rootfs(args, Chroot(ChrootType.ROOTFS, args.devicesdhbfvhubsud))
|
||||
mount_device_rootfs(Chroot(ChrootType.ROOTFS, device))
|
||||
|
|
|
@ -1,26 +1,31 @@
|
|||
# Copyright 2023 Oliver Smith
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
from typing import Dict
|
||||
from pmb.types import PmbArgs
|
||||
import pmb.flasher
|
||||
import pmb.chroot.initfs
|
||||
import pmb.helpers.args
|
||||
|
||||
|
||||
def check_partition_blacklist(args: PmbArgs, key, value):
|
||||
def check_partition_blacklist(args: PmbArgs, deviceinfo: Dict[str, str], key, value):
|
||||
if not key.startswith("$PARTITION_"):
|
||||
return
|
||||
|
||||
name = args.deviceinfo["name"]
|
||||
if value in args.deviceinfo["partition_blacklist"].split(","):
|
||||
name = deviceinfo["name"]
|
||||
if value in deviceinfo["partition_blacklist"].split(","):
|
||||
raise RuntimeError("'" + value + "'" + " partition is blacklisted " +
|
||||
"from being flashed! See the " + name + " device " +
|
||||
"wiki page for more information.")
|
||||
|
||||
|
||||
def run(args: PmbArgs, action, flavor=None):
|
||||
pmb.flasher.init(args)
|
||||
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()
|
||||
|
||||
# Verify action
|
||||
method = args.flash_method or args.deviceinfo["flash_method"]
|
||||
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")
|
||||
|
@ -74,7 +79,7 @@ def run(args: PmbArgs, action, flavor=None):
|
|||
" but the value for this variable"
|
||||
" is None! Is that missing in your"
|
||||
" deviceinfo?")
|
||||
check_partition_blacklist(args, key, value)
|
||||
check_partition_blacklist(args, deviceinfo, key, value)
|
||||
command[i] = command[i].replace(key, value)
|
||||
|
||||
# Remove empty strings
|
||||
|
|
|
@ -2,15 +2,18 @@
|
|||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
from typing import Optional
|
||||
import pmb.config.pmaports
|
||||
from pmb.core.context import get_context
|
||||
from pmb.types import PmbArgs
|
||||
|
||||
|
||||
def variables(args: PmbArgs, flavor, method):
|
||||
_cmdline = args.deviceinfo["kernel_cmdline"] or ""
|
||||
device = get_context().config.device
|
||||
deviceinfo = pmb.parse.deviceinfo()
|
||||
_cmdline = deviceinfo["kernel_cmdline"] or ""
|
||||
if "cmdline" in args and args.cmdline:
|
||||
_cmdline = args.cmdline
|
||||
|
||||
flash_pagesize = args.deviceinfo['flash_pagesize']
|
||||
flash_pagesize = deviceinfo['flash_pagesize']
|
||||
|
||||
# TODO Remove _partition_system deviceinfo support once pmaports has been
|
||||
# updated and minimum pmbootstrap version bumped.
|
||||
|
@ -20,39 +23,39 @@ def variables(args: PmbArgs, flavor, method):
|
|||
_partition_rootfs: Optional[str]
|
||||
|
||||
if method.startswith("fastboot"):
|
||||
_partition_kernel = args.deviceinfo["flash_fastboot_partition_kernel"]\
|
||||
_partition_kernel = deviceinfo["flash_fastboot_partition_kernel"]\
|
||||
or "boot"
|
||||
_partition_rootfs = args.deviceinfo["flash_fastboot_partition_rootfs"]\
|
||||
or args.deviceinfo["flash_fastboot_partition_system"] or "userdata"
|
||||
_partition_vbmeta = args.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 = args.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 = args.deviceinfo["flash_rk_partition_kernel"]\
|
||||
_partition_kernel = deviceinfo["flash_rk_partition_kernel"]\
|
||||
or None
|
||||
_partition_rootfs = args.deviceinfo["flash_rk_partition_rootfs"]\
|
||||
or args.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 = args.deviceinfo["flash_mtkclient_partition_kernel"]\
|
||||
_partition_kernel = deviceinfo["flash_mtkclient_partition_kernel"]\
|
||||
or "boot"
|
||||
_partition_rootfs = args.deviceinfo["flash_mtkclient_partition_rootfs"]\
|
||||
_partition_rootfs = deviceinfo["flash_mtkclient_partition_rootfs"]\
|
||||
or "userdata"
|
||||
_partition_vbmeta = args.deviceinfo["flash_mtkclient_partition_vbmeta"]\
|
||||
_partition_vbmeta = deviceinfo["flash_mtkclient_partition_vbmeta"]\
|
||||
or None
|
||||
_partition_dtbo = args.deviceinfo["flash_mtkclient_partition_dtbo"]\
|
||||
_partition_dtbo = deviceinfo["flash_mtkclient_partition_dtbo"]\
|
||||
or None
|
||||
else:
|
||||
_partition_kernel = args.deviceinfo["flash_heimdall_partition_kernel"]\
|
||||
_partition_kernel = deviceinfo["flash_heimdall_partition_kernel"]\
|
||||
or "KERNEL"
|
||||
_partition_rootfs = args.deviceinfo["flash_heimdall_partition_rootfs"]\
|
||||
or args.deviceinfo["flash_heimdall_partition_system"] or "SYSTEM"
|
||||
_partition_vbmeta = args.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 = args.deviceinfo["flash_heimdall_partition_dtbo"]\
|
||||
_partition_dtbo = deviceinfo["flash_heimdall_partition_dtbo"]\
|
||||
or None
|
||||
|
||||
if "partition" in args and args.partition:
|
||||
|
@ -64,7 +67,7 @@ def variables(args: PmbArgs, flavor, method):
|
|||
_partition_dtbo = args.partition
|
||||
|
||||
_dtb = ""
|
||||
if args.deviceinfo["append_dtb"] == "true":
|
||||
if deviceinfo["append_dtb"] == "true":
|
||||
_dtb = "-dtb"
|
||||
|
||||
_no_reboot = ""
|
||||
|
@ -76,23 +79,23 @@ def variables(args: PmbArgs, flavor, method):
|
|||
_resume = "--resume"
|
||||
|
||||
vars = {
|
||||
"$BOOT": "/mnt/rootfs_" + args.devicesdhbfvhubsud + "/boot",
|
||||
"$BOOT": "/mnt/rootfs_" + device + "/boot",
|
||||
"$DTB": _dtb,
|
||||
"$IMAGE_SPLIT_BOOT": "/home/pmos/rootfs/" + args.devicesdhbfvhubsud + "-boot.img",
|
||||
"$IMAGE_SPLIT_ROOT": "/home/pmos/rootfs/" + args.devicesdhbfvhubsud + "-root.img",
|
||||
"$IMAGE": "/home/pmos/rootfs/" + args.devicesdhbfvhubsud + ".img",
|
||||
"$IMAGE_SPLIT_BOOT": "/home/pmos/rootfs/" + device + "-boot.img",
|
||||
"$IMAGE_SPLIT_ROOT": "/home/pmos/rootfs/" + device + "-root.img",
|
||||
"$IMAGE": "/home/pmos/rootfs/" + device + ".img",
|
||||
"$KERNEL_CMDLINE": _cmdline,
|
||||
"$PARTITION_KERNEL": _partition_kernel,
|
||||
"$PARTITION_INITFS": args.deviceinfo[
|
||||
"$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_" + args.deviceinfo["arch"] +
|
||||
"$RECOVERY_ZIP": "/mnt/buildroot_" + deviceinfo["arch"] +
|
||||
"/var/lib/postmarketos-android-recovery-installer"
|
||||
"/pmos-" + args.devicesdhbfvhubsud + ".zip",
|
||||
"$UUU_SCRIPT": "/mnt/rootfs_" + args.deviceinfo["codename"] +
|
||||
"/pmos-" + device + ".zip",
|
||||
"$UUU_SCRIPT": "/mnt/rootfs_" + deviceinfo["codename"] +
|
||||
"/usr/share/uuu/flash_script.lst",
|
||||
"$NO_REBOOT": _no_reboot,
|
||||
"$RESUME": _resume
|
||||
|
|
|
@ -4,7 +4,7 @@ import os
|
|||
from pathlib import Path
|
||||
from typing import List, Sequence
|
||||
|
||||
import pmb.chroot.run
|
||||
import pmb.chroot
|
||||
import pmb.config.pmaports
|
||||
from pmb.types import PathString, PmbArgs
|
||||
import pmb.helpers.cli
|
||||
|
|
|
@ -275,7 +275,7 @@ def upgrade(args: PmbArgs, pkgname, git=True, stable=True) -> None:
|
|||
|
||||
def upgrade_all(args: PmbArgs) -> None:
|
||||
"""Upgrade all packages, based on args.all, args.all_git and args.all_stable."""
|
||||
for pkgname in pmb.helpers.pmaports.get_list(args):
|
||||
for pkgname in pmb.helpers.pmaports.get_list():
|
||||
# Always ignore postmarketOS-specific packages that have no upstream
|
||||
# source
|
||||
skip = False
|
||||
|
|
|
@ -48,7 +48,7 @@ __args: PmbArgs = PmbArgs()
|
|||
code as well.
|
||||
|
||||
Examples:
|
||||
args.deviceinfo (e.g. {"name": "Mydevice", "arch": "armhf", ...})
|
||||
deviceinfo (e.g. {"name": "Mydevice", "arch": "armhf", ...})
|
||||
"""
|
||||
|
||||
|
||||
|
@ -82,17 +82,17 @@ def check_pmaports_path(args: PmbArgs):
|
|||
# setattr(args, key, Path(getattr(args, key)).expanduser())
|
||||
|
||||
|
||||
def add_deviceinfo(args: PmbArgs):
|
||||
"""Add and verify the deviceinfo (only after initialization)"""
|
||||
setattr(args, "deviceinfo", pmb.parse.deviceinfo())
|
||||
|
||||
|
||||
def init(args: PmbArgs) -> PmbArgs:
|
||||
global __args
|
||||
# Basic initialization
|
||||
config = pmb.config.load(args)
|
||||
# pmb.config.merge_with_args(args)
|
||||
# replace_placeholders(args)
|
||||
|
||||
for key, value in vars(args).items():
|
||||
if key.startswith("_"):
|
||||
continue
|
||||
if getattr(args, key, None) and hasattr(config, key):
|
||||
print(f"Overriding config.{key} with {value}")
|
||||
setattr(config, key, value)
|
||||
|
||||
# Configure runtime context
|
||||
context = Context(config)
|
||||
|
@ -102,6 +102,8 @@ def init(args: PmbArgs) -> PmbArgs:
|
|||
context.offline = args.offline
|
||||
context.command = args.action
|
||||
context.cross = args.cross
|
||||
context.assume_yes = getattr(args, "assume_yes", False)
|
||||
context.force = getattr(args, "force", False)
|
||||
if args.mirrors_postmarketos:
|
||||
context.config.mirrors_postmarketos = args.mirrors_postmarketos
|
||||
if args.mirror_alpine:
|
||||
|
@ -121,9 +123,9 @@ def init(args: PmbArgs) -> PmbArgs:
|
|||
if args.action not in ["init", "checksum", "config", "bootimg_analyze", "log",
|
||||
"pull", "shutdown", "zap"]:
|
||||
pmb.config.pmaports.read_config()
|
||||
add_deviceinfo(args)
|
||||
pmb.helpers.git.parse_channels_cfg(config.aports)
|
||||
context.device_arch = args.deviceinfo["arch"]
|
||||
deviceinfo = pmb.parse.deviceinfo()
|
||||
context.device_arch = deviceinfo["arch"]
|
||||
|
||||
# Remove attributes from args so they don't get used by mistake
|
||||
delattr(args, "timeout")
|
||||
|
@ -134,6 +136,10 @@ def init(args: PmbArgs) -> PmbArgs:
|
|||
delattr(args, "aports")
|
||||
delattr(args, "mirrors_postmarketos")
|
||||
delattr(args, "mirror_alpine")
|
||||
if hasattr(args, "force"):
|
||||
delattr(args, "force")
|
||||
if hasattr(args, "device"):
|
||||
delattr(args, "device")
|
||||
# args.work is deprecated!
|
||||
delattr(args, "work")
|
||||
|
||||
|
@ -142,7 +148,7 @@ def init(args: PmbArgs) -> PmbArgs:
|
|||
if not key.startswith("_") and not key == "from_argparse":
|
||||
setattr(__args, key, value)
|
||||
|
||||
print(json.dumps(__args.__dict__))
|
||||
#print(json.dumps(__args.__dict__))
|
||||
|
||||
#sys.exit(0)
|
||||
|
||||
|
|
|
@ -90,7 +90,7 @@ def is_older_than(path, seconds):
|
|||
return lastmod + seconds < time.time()
|
||||
|
||||
|
||||
def symlink(args: PmbArgs, file: Path, link: Path):
|
||||
def symlink(file: Path, link: Path):
|
||||
"""Check if the symlink is already present, otherwise create it."""
|
||||
if os.path.exists(link):
|
||||
if (os.path.islink(link) and
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# Copyright 2023 Oliver Smith
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
import json
|
||||
from typing import List, Sequence
|
||||
from typing import List, Sequence, Tuple
|
||||
from pmb.helpers import logging
|
||||
import os
|
||||
from pathlib import Path
|
||||
|
@ -40,7 +40,7 @@ import pmb.sideload
|
|||
from pmb.core import ChrootType, Chroot, get_context
|
||||
|
||||
|
||||
def _parse_flavor(args: PmbArgs, autoinstall=True):
|
||||
def _parse_flavor(device: str, autoinstall=True):
|
||||
"""Verify the flavor argument if specified, or return a default value.
|
||||
|
||||
:param autoinstall: make sure that at least one kernel flavor is installed
|
||||
|
@ -49,7 +49,7 @@ def _parse_flavor(args: PmbArgs, autoinstall=True):
|
|||
# identifier that is typically in the form
|
||||
# "postmarketos-<manufacturer>-<device/chip>", e.g.
|
||||
# "postmarketos-qcom-sdm845"
|
||||
chroot = Chroot(ChrootType.ROOTFS, args.devicesdhbfvhubsud)
|
||||
chroot = Chroot(ChrootType.ROOTFS, device)
|
||||
flavor = pmb.chroot.other.kernel_flavor_installed(
|
||||
chroot, autoinstall)
|
||||
|
||||
|
@ -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(args.deviceinfo["arch"])
|
||||
return Chroot.buildroot(pmb.parse.deviceinfo()["arch"])
|
||||
else:
|
||||
return Chroot.buildroot(args.buildroot)
|
||||
elif args.suffix:
|
||||
|
@ -76,14 +76,14 @@ def _parse_suffix(args: PmbArgs) -> Chroot:
|
|||
return Chroot(ChrootType.NATIVE)
|
||||
|
||||
|
||||
def _install_ondev_verify_no_rootfs(args: PmbArgs):
|
||||
def _install_ondev_verify_no_rootfs(device: str, ondev_cp: List[Tuple[str, str]]):
|
||||
chroot_dest = "/var/lib/rootfs.img"
|
||||
dest = Chroot(ChrootType.INSTALLER, args.devicesdhbfvhubsud) / chroot_dest
|
||||
dest = Chroot(ChrootType.INSTALLER, device) / chroot_dest
|
||||
if dest.exists():
|
||||
return
|
||||
|
||||
if args.ondev_cp:
|
||||
for _, chroot_dest_cp in args.ondev_cp:
|
||||
if ondev_cp:
|
||||
for _, chroot_dest_cp in ondev_cp:
|
||||
if chroot_dest_cp == chroot_dest:
|
||||
return
|
||||
|
||||
|
@ -112,14 +112,14 @@ def build(args: PmbArgs):
|
|||
# Set src and force
|
||||
src = os.path.realpath(os.path.expanduser(args.src[0])) \
|
||||
if args.src else None
|
||||
force = True if src else args.force
|
||||
force = True if src else get_context().force
|
||||
if src and not os.path.exists(src):
|
||||
raise RuntimeError("Invalid path specified for --src: " + src)
|
||||
|
||||
# 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)
|
||||
pmb.helpers.repo_bootstrap.require_bootstrap(args, arch_package,
|
||||
pmb.helpers.repo_bootstrap.require_bootstrap(arch_package,
|
||||
f"build {package} for {arch_package}")
|
||||
|
||||
context = get_context()
|
||||
|
@ -134,8 +134,8 @@ def build(args: PmbArgs):
|
|||
|
||||
|
||||
def build_init(args: PmbArgs):
|
||||
suffix = _parse_suffix(args)
|
||||
pmb.build.init(args, suffix)
|
||||
chroot = _parse_suffix(args)
|
||||
pmb.build.init(chroot)
|
||||
|
||||
|
||||
def checksum(args: PmbArgs):
|
||||
|
@ -148,7 +148,7 @@ def checksum(args: PmbArgs):
|
|||
|
||||
def sideload(args: PmbArgs):
|
||||
arch = args.arch
|
||||
user = args.user
|
||||
user = get_context().config.user
|
||||
host = args.host
|
||||
pmb.sideload.sideload(args, user, host, args.port, arch, args.install_key,
|
||||
args.packages)
|
||||
|
@ -156,25 +156,27 @@ def sideload(args: PmbArgs):
|
|||
|
||||
def netboot(args: PmbArgs):
|
||||
if args.action_netboot == "serve":
|
||||
pmb.netboot.start_nbd_server(args)
|
||||
device = get_context().config.device
|
||||
pmb.netboot.start_nbd_server(device, args.replace)
|
||||
|
||||
|
||||
def chroot(args: PmbArgs):
|
||||
# Suffix
|
||||
suffix = _parse_suffix(args)
|
||||
if (args.user and suffix != Chroot.native() and
|
||||
not suffix.type == ChrootType.BUILDROOT):
|
||||
chroot = _parse_suffix(args)
|
||||
user = get_context().config.user
|
||||
if (user and chroot != Chroot.native() and
|
||||
not chroot.type == ChrootType.BUILDROOT):
|
||||
raise RuntimeError("--user is only supported for native or"
|
||||
" buildroot_* chroots.")
|
||||
if args.xauth and suffix != Chroot.native():
|
||||
if args.xauth and chroot != Chroot.native():
|
||||
raise RuntimeError("--xauth is only supported for native chroot.")
|
||||
|
||||
# apk: check minimum version, install packages
|
||||
pmb.chroot.apk.check_min_version(suffix)
|
||||
pmb.chroot.apk.check_min_version(chroot)
|
||||
if args.add:
|
||||
pmb.chroot.apk.install(args.add.split(","), suffix)
|
||||
pmb.chroot.apk.install(args.add.split(","), chroot)
|
||||
|
||||
pmb.chroot.init(suffix)
|
||||
pmb.chroot.init(chroot)
|
||||
|
||||
# Xauthority
|
||||
env = {}
|
||||
|
@ -196,14 +198,14 @@ def chroot(args: PmbArgs):
|
|||
size_root, size_reserve)
|
||||
|
||||
# Run the command as user/root
|
||||
if args.user:
|
||||
logging.info(f"({suffix}) % su pmos -c '" +
|
||||
if user:
|
||||
logging.info(f"({chroot}) % su pmos -c '" +
|
||||
" ".join(args.command) + "'")
|
||||
pmb.chroot.user(args.command, suffix, output=args.output,
|
||||
pmb.chroot.user(args.command, chroot, output=args.output,
|
||||
env=env)
|
||||
else:
|
||||
logging.info(f"({suffix}) % " + " ".join(args.command))
|
||||
pmb.chroot.root(args.command, suffix, output=args.output,
|
||||
logging.info(f"({chroot}) % " + " ".join(args.command))
|
||||
pmb.chroot.root(args.command, chroot, output=args.output,
|
||||
env=env)
|
||||
|
||||
|
||||
|
@ -219,7 +221,7 @@ def config(args: PmbArgs):
|
|||
raise RuntimeError("config --reset requires a name to be given.")
|
||||
def_value = getattr(Config(), args.name)
|
||||
setattr(config, args.name, def_value)
|
||||
logging.info(f"Config changed to default: {args.name}='{value}'")
|
||||
logging.info(f"Config changed to default: {args.name}='{def_value}'")
|
||||
pmb.config.save(args.config, config)
|
||||
elif args.value is not None:
|
||||
setattr(config, args.name, args.value)
|
||||
|
@ -258,6 +260,9 @@ def initfs(args: PmbArgs):
|
|||
|
||||
|
||||
def install(args: PmbArgs):
|
||||
config = get_context().config
|
||||
device = config.device
|
||||
deviceinfo = pmb.parse.deviceinfo(device)
|
||||
if args.no_fde:
|
||||
logging.warning("WARNING: --no-fde is deprecated,"
|
||||
" as it is now the default.")
|
||||
|
@ -271,8 +276,8 @@ def install(args: PmbArgs):
|
|||
raise ValueError("Installation using rsync"
|
||||
" is not currently supported on btrfs filesystem.")
|
||||
|
||||
pmb.helpers.repo_bootstrap.require_bootstrap(args, args.deviceinfo["arch"],
|
||||
f"do 'pmbootstrap install' for {args.deviceinfo['arch']}"
|
||||
pmb.helpers.repo_bootstrap.require_bootstrap(deviceinfo["arch"],
|
||||
f"do 'pmbootstrap install' for {deviceinfo['arch']}"
|
||||
" (deviceinfo_arch)")
|
||||
|
||||
# On-device installer checks
|
||||
|
@ -296,7 +301,7 @@ def install(args: PmbArgs):
|
|||
raise ValueError("--on-device-installer cannot be combined with"
|
||||
" --filesystem")
|
||||
|
||||
if args.deviceinfo["cgpt_kpart"]:
|
||||
if deviceinfo["cgpt_kpart"]:
|
||||
raise ValueError("--on-device-installer cannot be used with"
|
||||
" ChromeOS devices")
|
||||
else:
|
||||
|
@ -306,7 +311,7 @@ def install(args: PmbArgs):
|
|||
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(args)
|
||||
_install_ondev_verify_no_rootfs(device, args.ondev_cp)
|
||||
|
||||
# On-device installer overrides
|
||||
if args.on_device_installer:
|
||||
|
@ -315,15 +320,15 @@ def install(args: PmbArgs):
|
|||
# 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 args.user != "user":
|
||||
logging.warning(f"WARNING: custom username '{args.user}' will be"
|
||||
if config.user != "user":
|
||||
logging.warning(f"WARNING: custom username '{config.user}' will be"
|
||||
" replaced with 'user' for the on-device"
|
||||
" installer.")
|
||||
args.user = "user"
|
||||
config.user = "user"
|
||||
|
||||
if not args.disk and args.split is None:
|
||||
# Default to split if the flash method requires it
|
||||
flasher = pmb.config.flashers.get(args.deviceinfo["flash_method"], {})
|
||||
flasher = pmb.config.flashers.get(deviceinfo["flash_method"], {})
|
||||
if flasher.get("split", False):
|
||||
args.split = True
|
||||
|
||||
|
@ -345,10 +350,10 @@ def install(args: PmbArgs):
|
|||
if not args.install_local_pkgs:
|
||||
# Implies that we don't build outdated packages (overriding the answer
|
||||
# in 'pmbootstrap init')
|
||||
args.build_pkgs_on_install = False
|
||||
config.build_pkgs_on_install = False
|
||||
|
||||
# Safest way to avoid installing local packages is having none
|
||||
if (get_context().config.work / "packages").glob("*"):
|
||||
if (config.work / "packages").glob("*"):
|
||||
raise ValueError("--no-local-pkgs specified, but locally built"
|
||||
" packages found. Consider 'pmbootstrap zap -p'"
|
||||
" to delete them.")
|
||||
|
@ -443,7 +448,7 @@ def kconfig(args: PmbArgs):
|
|||
skipped = 0
|
||||
packages.sort()
|
||||
for package in packages:
|
||||
if not args.force:
|
||||
if not get_context().force:
|
||||
pkgname = package if package.startswith("linux-") \
|
||||
else "linux-" + package
|
||||
aport = pmb.helpers.pmaports.find(pkgname)
|
||||
|
@ -451,7 +456,7 @@ def kconfig(args: PmbArgs):
|
|||
if "!pmb:kconfigcheck" in apkbuild["options"]:
|
||||
skipped += 1
|
||||
continue
|
||||
if not pmb.parse.kconfig.check(args, package, components_list,
|
||||
if not pmb.parse.kconfig.check(package, components_list,
|
||||
details=details):
|
||||
error = True
|
||||
|
||||
|
@ -467,7 +472,7 @@ def kconfig(args: PmbArgs):
|
|||
if args.package:
|
||||
pkgname = args.package if isinstance(args.package, str) else args.package[0]
|
||||
else:
|
||||
pkgname = args.deviceinfo["codename"]
|
||||
pkgname = get_context().config.device
|
||||
use_oldconfig = args.action_kconfig == "migrate"
|
||||
pmb.build.menuconfig(args, pkgname, use_oldconfig)
|
||||
|
||||
|
@ -577,7 +582,7 @@ def zap(args: PmbArgs):
|
|||
|
||||
|
||||
def bootimg_analyze(args: PmbArgs):
|
||||
bootimg = pmb.parse.bootimg(args, args.path)
|
||||
bootimg = pmb.parse.bootimg(args.path)
|
||||
tmp_output = "Put these variables in the deviceinfo file of your device:\n"
|
||||
for line in pmb.aportgen.device.\
|
||||
generate_deviceinfo_fastboot_content(bootimg).split("\n"):
|
||||
|
@ -667,4 +672,4 @@ def ci(args: PmbArgs):
|
|||
if not scripts_selected:
|
||||
scripts_selected = pmb.ci.ask_which_scripts_to_run(scripts_available)
|
||||
|
||||
pmb.ci.run_scripts(args, topdir, scripts_selected)
|
||||
pmb.ci.run_scripts(topdir, scripts_selected)
|
||||
|
|
|
@ -248,8 +248,11 @@ def get_topdir(repo: Path):
|
|||
:returns: a string with the top dir of the git repository,
|
||||
or an empty string if it's not a git repository.
|
||||
"""
|
||||
return pmb.helpers.run.user(["git", "rev-parse", "--show-toplevel"],
|
||||
repo, output_return=True, check=False).rstrip()
|
||||
res = pmb.helpers.run.user(["git", "rev-parse", "--show-toplevel"],
|
||||
repo, output_return=True, check=False)
|
||||
if not isinstance(res, str):
|
||||
raise RuntimeError("Not a git repository: " + str(repo))
|
||||
return res.strip()
|
||||
|
||||
|
||||
def get_files(repo: Path):
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
# Copyright 2023 Danct12 <danct12@disroot.org>
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
from pathlib import Path
|
||||
from pmb.core.chroot import Chroot
|
||||
from pmb.helpers import logging
|
||||
import os
|
||||
|
||||
|
@ -17,12 +18,13 @@ def check(args: PmbArgs, pkgnames):
|
|||
|
||||
:param pkgnames: Names of the packages to lint
|
||||
"""
|
||||
pmb.chroot.apk.install(["atools"])
|
||||
chroot = Chroot.native()
|
||||
pmb.chroot.apk.install(["atools"], chroot)
|
||||
|
||||
# Mount pmaports.git inside the chroot so that we don't have to copy the
|
||||
# package folders
|
||||
pmaports = Path("/mnt/pmaports")
|
||||
pmb.build.mount_pmaports(args, pmaports)
|
||||
pmb.build.mount_pmaports(pmaports, chroot)
|
||||
|
||||
# Locate all APKBUILDs and make the paths be relative to the pmaports
|
||||
# root
|
||||
|
|
|
@ -10,7 +10,9 @@ See also:
|
|||
"""
|
||||
import copy
|
||||
from typing import Any, Dict
|
||||
from pmb.core.context import get_context
|
||||
from pmb.helpers import logging
|
||||
import pmb.build._package
|
||||
|
||||
from pmb.types import PmbArgs
|
||||
import pmb.helpers.pmaports
|
||||
|
@ -62,7 +64,7 @@ def get(pkgname, arch, replace_subpkgnames=False, must_exist=True):
|
|||
pmaport = pmb.helpers.pmaports.get(pkgname, False)
|
||||
if pmaport:
|
||||
ret = {"arch": pmaport["arch"],
|
||||
"depends": pmb.build._package.get_depends(args, pmaport),
|
||||
"depends": pmb.build._package.get_depends(get_context(), pmaport),
|
||||
"pkgname": pmaport["pkgname"],
|
||||
"provides": pmaport["provides"],
|
||||
"version": pmaport["pkgver"] + "-r" + pmaport["pkgrel"]}
|
||||
|
|
|
@ -91,7 +91,7 @@ def auto_apkindex_package(args: PmbArgs, arch, aport, apk, dry=False):
|
|||
# (which means dynamic libraries that the package was linked
|
||||
# against) and packages for which no aport exists.
|
||||
if (depend.startswith("so:") or
|
||||
not pmb.helpers.pmaports.find_optional(args, depend)):
|
||||
not pmb.helpers.pmaports.find_optional(depend)):
|
||||
missing.append(depend)
|
||||
|
||||
# Increase pkgrel
|
||||
|
@ -116,7 +116,7 @@ def auto(args: PmbArgs, dry=False):
|
|||
logging.verbose(
|
||||
f"{pkgname}: origin '{origin}' found again")
|
||||
continue
|
||||
aport_path = pmb.helpers.pmaports.find_optional(args, origin)
|
||||
aport_path = pmb.helpers.pmaports.find_optional(origin)
|
||||
if not aport_path:
|
||||
logging.warning("{}: origin '{}' aport not found".format(
|
||||
pkgname, origin))
|
||||
|
|
|
@ -58,6 +58,7 @@ def urls(user_repository=True, postmarketos_mirror=True, alpine=True):
|
|||
"http://...", ...]
|
||||
"""
|
||||
ret: List[str] = []
|
||||
context = get_context()
|
||||
|
||||
# Get mirrordirs from channels.cfg (postmarketOS mirrordir is the same as
|
||||
# the pmaports branch of the channel, no need to make it more complicated)
|
||||
|
@ -68,9 +69,9 @@ def urls(user_repository=True, postmarketos_mirror=True, alpine=True):
|
|||
# Local user repository (for packages compiled with pmbootstrap)
|
||||
if user_repository:
|
||||
channel = pmb.config.pmaports.read_config()["channel"]
|
||||
ret.append(str(get_context().config.work / "packages" / channel))
|
||||
# FIXME: We shouldn't hardcod this here
|
||||
ret.append("/mnt/pmbootstrap/packages")
|
||||
|
||||
context = get_context()
|
||||
# Upstream postmarketOS binary repository
|
||||
if postmarketos_mirror:
|
||||
for mirror in context.config.mirrors_postmarketos:
|
||||
|
|
|
@ -20,7 +20,7 @@ def get_arch(args: PmbArgs):
|
|||
return args.arch
|
||||
|
||||
if args.build_default_device_arch:
|
||||
return args.deviceinfo["arch"]
|
||||
return pmb.parse.deviceinfo()["arch"]
|
||||
|
||||
return pmb.config.arch_native
|
||||
|
||||
|
@ -142,7 +142,7 @@ def run_steps(args: PmbArgs, steps, arch, chroot: Chroot):
|
|||
for package in get_packages(bootstrap_line):
|
||||
log_progress(f"building {package}")
|
||||
bootstrap_stage = int(step.split("bootstrap_", 1)[1])
|
||||
pmb.build.package(args, package, arch, force=True,
|
||||
pmb.build.package(package, arch, force=True,
|
||||
strict=True, bootstrap_stage=bootstrap_stage)
|
||||
|
||||
log_progress("bootstrap complete!")
|
||||
|
@ -175,7 +175,7 @@ def require_bootstrap_error(repo, arch, trigger_str):
|
|||
" and then try again.")
|
||||
|
||||
|
||||
def require_bootstrap(args: PmbArgs, arch, trigger_str):
|
||||
def require_bootstrap(arch, trigger_str):
|
||||
"""
|
||||
Check if repo_bootstrap was done, if any is needed.
|
||||
|
||||
|
|
|
@ -33,12 +33,12 @@ def print_channel(config: Config) -> None:
|
|||
print_status_line("Channel", value)
|
||||
|
||||
|
||||
def print_device(args: PmbArgs, config: Config) -> None:
|
||||
def print_device(config: Config) -> None:
|
||||
kernel = ""
|
||||
if pmb.parse._apkbuild.kernels(config.device):
|
||||
kernel = f", kernel: {config.kernel}"
|
||||
|
||||
value = f"{config.device} ({args.deviceinfo['arch']}{kernel})"
|
||||
value = f"{config.device} ({pmb.parse.deviceinfo()['arch']}{kernel})"
|
||||
print_status_line("Device", value)
|
||||
|
||||
|
||||
|
@ -56,6 +56,6 @@ def print_status(args: PmbArgs) -> None:
|
|||
:returns: True if all checks passed, False otherwise """
|
||||
config = get_context().config
|
||||
print_channel(config)
|
||||
print_device(args, config)
|
||||
print_device(config)
|
||||
print_ui(config)
|
||||
print_systemd(config)
|
||||
|
|
|
@ -9,7 +9,7 @@ import pmb.helpers.package
|
|||
import pmb.parse
|
||||
|
||||
|
||||
def list_ui(args: PmbArgs, arch):
|
||||
def list_ui(arch):
|
||||
"""Get all UIs, for which aports are available with their description.
|
||||
|
||||
:param arch: device architecture, for which the UIs must be available
|
||||
|
@ -22,7 +22,7 @@ def list_ui(args: PmbArgs, arch):
|
|||
for path in sorted(context.config.aports.glob("main/postmarketos-ui-*")):
|
||||
apkbuild = pmb.parse.apkbuild(path)
|
||||
ui = os.path.basename(path).split("-", 2)[2]
|
||||
if pmb.helpers.package.check_arch(args, apkbuild["pkgname"], arch):
|
||||
if pmb.helpers.package.check_arch(apkbuild["pkgname"], arch):
|
||||
ret.append((ui, apkbuild["pkgdesc"]))
|
||||
return ret
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@ import pmb.helpers.devices
|
|||
from pmb.helpers.mount import mount_device_rootfs
|
||||
import pmb.helpers.run
|
||||
import pmb.helpers.other
|
||||
import pmb.helpers.package
|
||||
import pmb.install.blockdevice
|
||||
import pmb.install.recovery
|
||||
import pmb.install.ui
|
||||
|
@ -113,11 +114,11 @@ def copy_files_from_chroot(args: PmbArgs, chroot: Chroot):
|
|||
"""
|
||||
# Mount the device rootfs
|
||||
logging.info(f"(native) copy {chroot} to /mnt/install/")
|
||||
mountpoint = mount_device_rootfs(args, chroot)
|
||||
mountpoint = mount_device_rootfs(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(args.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])
|
||||
|
@ -148,16 +149,16 @@ def copy_files_from_chroot(args: PmbArgs, chroot: Chroot):
|
|||
working_dir=mountpoint)
|
||||
|
||||
|
||||
def create_home_from_skel(args: PmbArgs):
|
||||
def create_home_from_skel(filesystem: str, user: str):
|
||||
"""
|
||||
Create /home/{user} from /etc/skel
|
||||
"""
|
||||
rootfs = (Chroot.native() / "mnt/install")
|
||||
# In btrfs, home subvol & home dir is created in format.py
|
||||
if args.filesystem != "btrfs":
|
||||
if filesystem != "btrfs":
|
||||
pmb.helpers.run.root(["mkdir", rootfs / "home"])
|
||||
|
||||
home = (rootfs / "home" / args.user)
|
||||
home = (rootfs / "home" / user)
|
||||
if (rootfs / "etc/skel").exists():
|
||||
pmb.helpers.run.root(["cp", "-a", (rootfs / "etc/skel"), home])
|
||||
else:
|
||||
|
@ -184,8 +185,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(args,
|
||||
arch=args.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/"])
|
||||
|
@ -221,7 +221,7 @@ def set_user(config: Config):
|
|||
pmb.chroot.root(["addgroup", config.user, group], chroot)
|
||||
|
||||
|
||||
def setup_login_chpasswd_user_from_arg(args: PmbArgs, chroot: Chroot):
|
||||
def setup_login_chpasswd_user_from_arg(args: PmbArgs, user: str, chroot: Chroot):
|
||||
"""
|
||||
Set the user's password from what the user passed as --password. Make an
|
||||
effort to not have the password end up in the log file by writing it to
|
||||
|
@ -237,7 +237,7 @@ def setup_login_chpasswd_user_from_arg(args: PmbArgs, chroot: Chroot):
|
|||
path_outside = chroot / path
|
||||
|
||||
with open(path_outside, "w", encoding="utf-8") as handle:
|
||||
handle.write(f"{args.user}:{args.password}")
|
||||
handle.write(f"{user}:{args.password}")
|
||||
|
||||
pmb.chroot.root(["sh", "-c", f"cat {shlex.quote(path)} | chpasswd"],
|
||||
chroot)
|
||||
|
@ -258,7 +258,7 @@ def is_root_locked(chroot: Chroot):
|
|||
return shadow_root.startswith("root:!:")
|
||||
|
||||
|
||||
def setup_login(args: PmbArgs, chroot: Chroot):
|
||||
def setup_login(args: PmbArgs, config: Config, chroot: Chroot):
|
||||
"""
|
||||
Loop until the password for user has been set successfully, and disable
|
||||
root login.
|
||||
|
@ -268,13 +268,13 @@ def setup_login(args: PmbArgs, chroot: Chroot):
|
|||
"""
|
||||
if not args.on_device_installer:
|
||||
# User password
|
||||
logging.info(f" *** SET LOGIN PASSWORD FOR: '{args.user}' ***")
|
||||
logging.info(f" *** SET LOGIN PASSWORD FOR: '{config.user}' ***")
|
||||
if args.password:
|
||||
setup_login_chpasswd_user_from_arg(args, chroot)
|
||||
setup_login_chpasswd_user_from_arg(args, config.user, chroot)
|
||||
else:
|
||||
while True:
|
||||
try:
|
||||
pmb.chroot.root(["passwd", args.user], chroot,
|
||||
pmb.chroot.root(["passwd", config.user], chroot,
|
||||
output="interactive")
|
||||
break
|
||||
except RuntimeError:
|
||||
|
@ -363,11 +363,9 @@ def setup_keymap(config: Config):
|
|||
logging.info("NOTE: No valid keymap specified for device")
|
||||
|
||||
|
||||
def setup_timezone(config: Config):
|
||||
suffix = Chroot(ChrootType.ROOTFS, config.device)
|
||||
|
||||
arch = args.deviceinfo["arch"]
|
||||
alpine_conf = pmb.helpers.package.get(args, "alpine-conf", arch)
|
||||
def setup_timezone(chroot: Chroot, timezone: str):
|
||||
# We don't care about the arch since it's built for all!
|
||||
alpine_conf = pmb.helpers.package.get("alpine-conf", pmb.config.arch_native)
|
||||
version = alpine_conf["version"].split("-r")[0]
|
||||
|
||||
setup_tz_cmd = ["setup-timezone"]
|
||||
|
@ -375,23 +373,22 @@ def setup_timezone(config: Config):
|
|||
# and disregard tzdata, to save space. If we actually have tzdata
|
||||
# installed, make sure that setup-timezone makes use of it, since
|
||||
# there's no space to be saved.
|
||||
if "tzdata" in pmb.chroot.apk.installed(args, suffix):
|
||||
if "tzdata" in pmb.chroot.apk.installed(chroot):
|
||||
setup_tz_cmd += ["-i"]
|
||||
if not pmb.parse.version.check_string(version, ">=3.14.0"):
|
||||
setup_tz_cmd += ["-z"]
|
||||
setup_tz_cmd += [args.timezone]
|
||||
pmb.chroot.root(setup_tz_cmd, suffix)
|
||||
setup_tz_cmd += [timezone]
|
||||
pmb.chroot.root(setup_tz_cmd, chroot)
|
||||
|
||||
|
||||
def setup_hostname(args: PmbArgs):
|
||||
def setup_hostname(device: str, hostname: Optional[str]):
|
||||
"""
|
||||
Set the hostname and update localhost address in /etc/hosts
|
||||
"""
|
||||
# Default to device name. If device name is not a valid hostname then
|
||||
# default to a static default.
|
||||
hostname = args.hostname
|
||||
if not hostname:
|
||||
hostname = args.devicesdhbfvhubsud
|
||||
hostname = device
|
||||
if not pmb.helpers.other.validate_hostname(hostname):
|
||||
# A valid host name, see:
|
||||
# https://datatracker.ietf.org/doc/html/rfc1035#section-2.3.1
|
||||
|
@ -402,7 +399,7 @@ def setup_hostname(args: PmbArgs):
|
|||
raise RuntimeError("Hostname '" + hostname + "' is not valid, please"
|
||||
" run 'pmbootstrap init' to configure it.")
|
||||
|
||||
suffix = Chroot(ChrootType.ROOTFS, args.devicesdhbfvhubsud)
|
||||
suffix = Chroot(ChrootType.ROOTFS, device)
|
||||
# Generate /etc/hostname
|
||||
pmb.chroot.root(["sh", "-c", "echo " + shlex.quote(hostname) +
|
||||
" > /etc/hostname"], suffix)
|
||||
|
@ -412,37 +409,32 @@ def setup_hostname(args: PmbArgs):
|
|||
pmb.chroot.root(["sed", "-i", "-e", regex, "/etc/hosts"], suffix)
|
||||
|
||||
|
||||
def setup_appstream(args: PmbArgs):
|
||||
def setup_appstream(offline: bool, chroot: Chroot):
|
||||
"""
|
||||
If alpine-appstream-downloader has been downloaded, execute it to have
|
||||
update AppStream data on new installs
|
||||
"""
|
||||
suffix = Chroot(ChrootType.ROOTFS, args.devicesdhbfvhubsud)
|
||||
installed_pkgs = pmb.chroot.apk.installed(args, suffix)
|
||||
installed_pkgs = pmb.chroot.apk.installed(chroot)
|
||||
|
||||
if "alpine-appstream-downloader" not in installed_pkgs or args.offline:
|
||||
if "alpine-appstream-downloader" not in installed_pkgs or offline:
|
||||
return
|
||||
|
||||
if not pmb.chroot.root(["alpine-appstream-downloader",
|
||||
"/mnt/appstream-data"], suffix, check=False):
|
||||
pmb.chroot.root(["mkdir", "-p", "/var/lib/swcatalog"], suffix)
|
||||
"/mnt/appstream-data"], chroot, check=False):
|
||||
pmb.chroot.root(["mkdir", "-p", "/var/lib/swcatalog"], chroot)
|
||||
pmb.chroot.root(["cp", "-r", "/mnt/appstream-data/icons",
|
||||
"/mnt/appstream-data/xml",
|
||||
"-t", "/var/lib/swcatalog"], suffix)
|
||||
"-t", "/var/lib/swcatalog"], chroot)
|
||||
|
||||
|
||||
def disable_sshd(args: PmbArgs):
|
||||
if not args.no_sshd:
|
||||
return
|
||||
|
||||
def disable_sshd(chroot: Chroot):
|
||||
# check=False: rc-update doesn't exit with 0 if already disabled
|
||||
chroot = Chroot(ChrootType.ROOTFS, args.devicesdhbfvhubsud)
|
||||
pmb.chroot.root(["rc-update", "del", "sshd", "default"], chroot,
|
||||
check=False)
|
||||
|
||||
# Verify that it's gone
|
||||
sshd_files = pmb.helpers.run.root(
|
||||
args, ["find", "-name", "sshd"], output_return=True,
|
||||
["find", "-name", "sshd"], output_return=True,
|
||||
working_dir=chroot / "etc/runlevels")
|
||||
if sshd_files:
|
||||
raise RuntimeError(f"Failed to disable sshd service: {sshd_files}")
|
||||
|
@ -457,7 +449,7 @@ def print_sshd_info(args: PmbArgs):
|
|||
logging.info("SSH daemon is disabled (--no-sshd).")
|
||||
else:
|
||||
logging.info("SSH daemon is enabled (disable with --no-sshd).")
|
||||
logging.info(f"Login as '{args.user}' with the password given"
|
||||
logging.info(f"Login as '{get_context().config.user}' with the password given"
|
||||
" during installation.")
|
||||
|
||||
if args.on_device_installer:
|
||||
|
@ -469,24 +461,20 @@ def print_sshd_info(args: PmbArgs):
|
|||
logging.info("More info: https://postmarketos.org/ondev-debug")
|
||||
|
||||
|
||||
def disable_firewall(args: PmbArgs):
|
||||
if not args.no_firewall:
|
||||
return
|
||||
|
||||
def disable_firewall(chroot: Chroot):
|
||||
# check=False: rc-update doesn't exit with 0 if already disabled
|
||||
chroot = Chroot(ChrootType.ROOTFS, args.devicesdhbfvhubsud)
|
||||
pmb.chroot.root(["rc-update", "del", "nftables", "default"], chroot,
|
||||
check=False)
|
||||
|
||||
# Verify that it's gone
|
||||
nftables_files = pmb.helpers.run.root(
|
||||
args, ["find", "-name", "nftables"], output_return=True,
|
||||
["find", "-name", "nftables"], output_return=True,
|
||||
working_dir=chroot / "etc/runlevels")
|
||||
if nftables_files:
|
||||
raise RuntimeError(f"Failed to disable firewall: {nftables_files}")
|
||||
|
||||
|
||||
def print_firewall_info(args: PmbArgs):
|
||||
def print_firewall_info(disabled: bool, arch: str):
|
||||
pmaports_cfg = pmb.config.pmaports.read_config()
|
||||
pmaports_ok = pmaports_cfg.get("supported_firewall", None) == "nftables"
|
||||
|
||||
|
@ -494,7 +482,6 @@ def print_firewall_info(args: PmbArgs):
|
|||
apkbuild_found = False
|
||||
apkbuild_has_opt = False
|
||||
|
||||
arch = args.deviceinfo["arch"]
|
||||
kernel = get_kernel_package(get_context().config)
|
||||
if kernel:
|
||||
kernel_apkbuild = pmb.build._package.get_apkbuild(kernel[0], arch)
|
||||
|
@ -510,7 +497,7 @@ def print_firewall_info(args: PmbArgs):
|
|||
if not pmaports_ok:
|
||||
logging.info("Firewall is not supported in checked out pmaports"
|
||||
" branch.")
|
||||
elif args.no_firewall:
|
||||
elif disabled:
|
||||
logging.info("Firewall is disabled (--no-firewall).")
|
||||
elif not apkbuild_found:
|
||||
logging.info("Firewall is enabled, but may not work (couldn't"
|
||||
|
@ -538,7 +525,7 @@ def generate_binary_list(args: PmbArgs, chroot: Chroot, step):
|
|||
"""
|
||||
binary_ranges: Dict[int, int] = {}
|
||||
binary_list = []
|
||||
binaries = args.deviceinfo["sd_embed_firmware"].split(",")
|
||||
binaries = pmb.parse.deviceinfo()["sd_embed_firmware"].split(",")
|
||||
|
||||
for binary_offset in binaries:
|
||||
binary, _offset = binary_offset.split(':')
|
||||
|
@ -554,7 +541,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 = args.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:
|
||||
|
@ -587,19 +574,19 @@ 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 args.deviceinfo["sd_embed_firmware"]:
|
||||
if not pmb.parse.deviceinfo()["sd_embed_firmware"]:
|
||||
return
|
||||
|
||||
step = 1024
|
||||
if args.deviceinfo["sd_embed_firmware_step_size"]:
|
||||
if pmb.parse.deviceinfo()["sd_embed_firmware_step_size"]:
|
||||
try:
|
||||
step = int(args.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 "
|
||||
"is not valid: {}".format(step))
|
||||
|
||||
device_rootfs = mount_device_rootfs(args, suffix)
|
||||
device_rootfs = mount_device_rootfs(suffix)
|
||||
binary_list = generate_binary_list(args, suffix, step)
|
||||
|
||||
# Write binaries to disk
|
||||
|
@ -619,13 +606,13 @@ 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 args.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(args, suffix)
|
||||
filename = f"{device_rootfs}{args.deviceinfo['cgpt_kpart']}"
|
||||
device_rootfs = mount_device_rootfs(suffix)
|
||||
filename = f"{device_rootfs}{pmb.parse.deviceinfo()['cgpt_kpart']}"
|
||||
pmb.chroot.root(
|
||||
args, ["dd", f"if={filename}", f"of=/dev/installp{layout['kernel']}"])
|
||||
["dd", f"if={filename}", f"of=/dev/installp{layout['kernel']}"])
|
||||
|
||||
|
||||
def sanity_check_boot_size():
|
||||
|
@ -680,7 +667,7 @@ def sanity_check_disk_size(args: PmbArgs):
|
|||
|
||||
|
||||
def get_ondev_pkgver(args: PmbArgs):
|
||||
arch = args.deviceinfo["arch"]
|
||||
arch = pmb.parse.deviceinfo()["arch"]
|
||||
package = pmb.helpers.package.get(args, "postmarketos-ondev", arch)
|
||||
return package["version"].split("-r")[0]
|
||||
|
||||
|
@ -775,7 +762,7 @@ def create_fstab(args: PmbArgs, layout, chroot: Chroot):
|
|||
else f"UUID={get_uuid(args, root_dev)}"
|
||||
|
||||
boot_options = "nodev,nosuid,noexec"
|
||||
boot_filesystem = args.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"
|
||||
|
@ -821,23 +808,25 @@ def install_system_image(args: PmbArgs, size_reserve, chroot: Chroot, step, step
|
|||
:param split: create separate images for boot and root partitions
|
||||
:param disk: path to disk block device (e.g. /dev/mmcblk0) or None
|
||||
"""
|
||||
config = get_context().config
|
||||
device = chroot.name()
|
||||
# Partition and fill image file/disk block device
|
||||
logging.info(f"*** ({step}/{steps}) PREPARE INSTALL BLOCKDEVICE ***")
|
||||
pmb.chroot.shutdown(args, True)
|
||||
(size_boot, size_root) = get_subpartitions_size(chroot)
|
||||
layout = get_partition_layout(size_reserve, args.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 args.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:
|
||||
pmb.install.partition(args, layout, size_boot, size_reserve)
|
||||
if not split:
|
||||
pmb.install.partitions_mount(args, layout, disk)
|
||||
pmb.install.partitions_mount(device, layout, disk)
|
||||
|
||||
pmb.install.format(args, layout, boot_label, root_label, disk)
|
||||
|
||||
|
@ -860,9 +849,9 @@ def install_system_image(args: PmbArgs, size_reserve, chroot: Chroot, step, step
|
|||
# Just copy all the files
|
||||
logging.info(f"*** ({step + 1}/{steps}) FILL INSTALL BLOCKDEVICE ***")
|
||||
copy_files_from_chroot(args, chroot)
|
||||
create_home_from_skel(args)
|
||||
create_home_from_skel(args.filesystem, config.user)
|
||||
configure_apk(args)
|
||||
copy_ssh_keys(args)
|
||||
copy_ssh_keys(config)
|
||||
|
||||
# Don't try to embed firmware and cgpt on split images since there's no
|
||||
# place to put it and it will end up in /dev of the chroot instead
|
||||
|
@ -878,26 +867,26 @@ def install_system_image(args: PmbArgs, size_reserve, chroot: Chroot, step, step
|
|||
# Convert rootfs to sparse using img2simg
|
||||
sparse = args.sparse
|
||||
if sparse is None:
|
||||
sparse = args.deviceinfo["flash_sparse"] == "true"
|
||||
sparse = pmb.parse.deviceinfo()["flash_sparse"] == "true"
|
||||
|
||||
if sparse and not split and not disk:
|
||||
workdir = Path("/home/pmos/rootfs")
|
||||
logging.info("(native) make sparse rootfs")
|
||||
pmb.chroot.apk.install(["android-tools"], Chroot.native())
|
||||
sys_image = args.devicesdhbfvhubsud + ".img"
|
||||
sys_image_sparse = args.devicesdhbfvhubsud + "-sparse.img"
|
||||
sys_image = device + ".img"
|
||||
sys_image_sparse = device + "-sparse.img"
|
||||
pmb.chroot.user(["img2simg", sys_image, sys_image_sparse],
|
||||
working_dir=workdir)
|
||||
pmb.chroot.user(["mv", "-f", sys_image_sparse, sys_image],
|
||||
working_dir=workdir)
|
||||
|
||||
# patch sparse image for Samsung devices if specified
|
||||
samsungify_strategy = args.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())
|
||||
sys_image = f"{args.devicesdhbfvhubsud}.img"
|
||||
sys_image_patched = f"{args.devicesdhbfvhubsud}-patched.img"
|
||||
sys_image = f"{device}.img"
|
||||
sys_image_patched = f"{device}-patched.img"
|
||||
pmb.chroot.user(["sm_sparse_image_tool", "samsungify", "--strategy",
|
||||
samsungify_strategy, sys_image, sys_image_patched],
|
||||
working_dir=workdir)
|
||||
|
@ -905,14 +894,14 @@ def install_system_image(args: PmbArgs, size_reserve, chroot: Chroot, step, step
|
|||
working_dir=workdir)
|
||||
|
||||
|
||||
def print_flash_info(args: PmbArgs):
|
||||
def print_flash_info(device: str, deviceinfo: Dict[str, str], 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 = args.deviceinfo["flash_method"]
|
||||
method = deviceinfo["flash_method"]
|
||||
flasher = pmb.config.flashers.get(method, {})
|
||||
flasher_actions = flasher.get("actions", {})
|
||||
if not isinstance(flasher_actions, dict):
|
||||
|
@ -929,14 +918,14 @@ def print_flash_info(args: PmbArgs):
|
|||
logging.info("Run the following to flash your installation to the"
|
||||
" target device:")
|
||||
|
||||
if "flash_rootfs" in flasher_actions and not args.disk and \
|
||||
bool(args.split) == requires_split:
|
||||
if "flash_rootfs" in flasher_actions and not have_disk and \
|
||||
bool(split) == requires_split:
|
||||
logging.info("* pmbootstrap flasher flash_rootfs")
|
||||
logging.info(" Flashes the generated rootfs image to your device:")
|
||||
if args.split:
|
||||
logging.info(f" {Chroot.native() / 'home/pmos/rootfs' / args.devicesdhbfvhubsud}-rootfs.img")
|
||||
if split:
|
||||
logging.info(f" {Chroot.native() / 'home/pmos/rootfs' / device}-rootfs.img")
|
||||
else:
|
||||
logging.info(f" {Chroot.native() / 'home/pmos/rootfs' / args.devicesdhbfvhubsud}.img")
|
||||
logging.info(f" {Chroot.native() / 'home/pmos/rootfs' / device}.img")
|
||||
logging.info(" (NOTE: This file has a partition table, which"
|
||||
" contains /boot and / subpartitions. That way we"
|
||||
" don't need to change the partition layout on your"
|
||||
|
@ -945,16 +934,16 @@ def print_flash_info(args: PmbArgs):
|
|||
# if current flasher supports vbmeta and partition is explicitly specified
|
||||
# in deviceinfo
|
||||
if "flash_vbmeta" in flasher_actions and \
|
||||
(args.deviceinfo["flash_fastboot_partition_vbmeta"] or
|
||||
args.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 \
|
||||
(args.deviceinfo["flash_fastboot_partition_dtbo"] or
|
||||
args.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.")
|
||||
|
||||
|
@ -963,14 +952,14 @@ def print_flash_info(args: PmbArgs):
|
|||
# works even when partitions are split or installing to disk. This is not
|
||||
# possible if the flash method requires split partitions.
|
||||
if "flash_kernel" in flasher_actions and \
|
||||
(not requires_split or args.split):
|
||||
(not requires_split or split):
|
||||
logging.info("* pmbootstrap flasher flash_kernel")
|
||||
logging.info(" Flashes the kernel + initramfs to your device:")
|
||||
if requires_split:
|
||||
logging.info(f" {Chroot.native()}/home/pmos/rootfs/"
|
||||
f"{args.devicesdhbfvhubsud}-boot.img")
|
||||
f"{device}-boot.img")
|
||||
else:
|
||||
logging.info(f" {Chroot(ChrootType.ROOTFS, args.devicesdhbfvhubsud)}/boot")
|
||||
logging.info(f" {Chroot(ChrootType.ROOTFS, device)}/boot")
|
||||
|
||||
if "boot" in flasher_actions:
|
||||
logging.info(" (NOTE: " + method + " also supports booting"
|
||||
|
@ -978,7 +967,7 @@ def print_flash_info(args: PmbArgs):
|
|||
" Use 'pmbootstrap flasher boot' to do that.)")
|
||||
|
||||
if "flash_lk2nd" in flasher_actions and \
|
||||
(Chroot(ChrootType.ROOTFS, args.devicesdhbfvhubsud) / "/boot/lk2nd.img").exists():
|
||||
(Chroot(ChrootType.ROOTFS, device) / "/boot/lk2nd.img").exists():
|
||||
logging.info("* Your device supports and may even require"
|
||||
" flashing lk2nd. You should flash it before"
|
||||
" flashing anything else. Use 'pmbootstrap flasher"
|
||||
|
@ -990,11 +979,11 @@ def print_flash_info(args: PmbArgs):
|
|||
" and flash outside of pmbootstrap.")
|
||||
|
||||
|
||||
def install_recovery_zip(args: PmbArgs, steps):
|
||||
def install_recovery_zip(args: PmbArgs, device: str, arch: str, steps):
|
||||
logging.info(f"*** ({steps}/{steps}) CREATING RECOVERY-FLASHABLE ZIP ***")
|
||||
suffix = "buildroot_" + args.deviceinfo["arch"]
|
||||
mount_device_rootfs(args, Chroot.rootfs(args.devicesdhbfvhubsud))
|
||||
pmb.install.recovery.create_zip(args, suffix)
|
||||
chroot = Chroot(ChrootType.BUILDROOT, arch)
|
||||
mount_device_rootfs(Chroot.rootfs(device))
|
||||
pmb.install.recovery.create_zip(args, chroot, device)
|
||||
|
||||
# Flash information
|
||||
logging.info("*** FLASHING INFORMATION ***")
|
||||
|
@ -1060,12 +1049,12 @@ def install_on_device_installer(args: PmbArgs, step, steps):
|
|||
# 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"{args.devicesdhbfvhubsud}-boot.img"
|
||||
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, chroot_installer)
|
||||
setup_login(args, config, chroot_installer)
|
||||
|
||||
# Generate installer image
|
||||
size_reserve = round(os.path.getsize(img_path_dest) / 1024 / 1024) + 200
|
||||
|
@ -1185,8 +1174,8 @@ def create_device_rootfs(args: PmbArgs, step, steps):
|
|||
logging.info(f'*** ({step}/{steps}) CREATE DEVICE ROOTFS ("{device}")'
|
||||
' ***')
|
||||
|
||||
suffix = Chroot(ChrootType.ROOTFS, device)
|
||||
pmb.chroot.init(suffix)
|
||||
chroot = Chroot(ChrootType.ROOTFS, device)
|
||||
pmb.chroot.init(chroot)
|
||||
# Create user before installing packages, so post-install scripts of
|
||||
# pmaports can figure out the username (legacy reasons: pmaports#820)
|
||||
set_user(context.config)
|
||||
|
@ -1215,7 +1204,7 @@ def create_device_rootfs(args: PmbArgs, step, steps):
|
|||
install_packages += context.config.extra_packages.split(",")
|
||||
if args.add:
|
||||
install_packages += args.add.split(",")
|
||||
locale_is_set = (config.locale != pmb.config.defaults["locale"])
|
||||
locale_is_set = (config.locale != Config().locale)
|
||||
if locale_is_set:
|
||||
install_packages += ["lang", "musl-locales"]
|
||||
|
||||
|
@ -1231,58 +1220,63 @@ def create_device_rootfs(args: PmbArgs, step, steps):
|
|||
# Pick the most suitable unlocker depending on the packages
|
||||
# selected for installation
|
||||
unlocker = pmb.parse.depends.package_provider(
|
||||
"postmarketos-fde-unlocker", install_packages, suffix)
|
||||
"postmarketos-fde-unlocker", install_packages, chroot)
|
||||
if unlocker["pkgname"] not in install_packages:
|
||||
install_packages += [unlocker["pkgname"]]
|
||||
else:
|
||||
install_packages += ["postmarketos-base-nofde"]
|
||||
|
||||
pmb.helpers.repo.update(args.deviceinfo["arch"])
|
||||
pmb.helpers.repo.update(pmb.parse.deviceinfo()["arch"])
|
||||
|
||||
# Install uninstallable "dependencies" by default
|
||||
install_packages += get_recommends(args, install_packages)
|
||||
|
||||
# Explicitly call build on the install packages, to re-build them or any
|
||||
# dependency, in case the version increased
|
||||
if args.build_pkgs_on_install:
|
||||
if config.build_pkgs_on_install:
|
||||
for pkgname in install_packages:
|
||||
pmb.build.package(context, pkgname, args.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
|
||||
# installed a hook without pmbootstrap - see #69 for more info)
|
||||
pmb.chroot.apk.install(install_packages, suffix)
|
||||
flavor = pmb.chroot.other.kernel_flavor_installed(suffix)
|
||||
pmb.chroot.initfs.build(args, flavor, suffix)
|
||||
pmb.chroot.apk.install(install_packages, chroot)
|
||||
flavor = pmb.chroot.other.kernel_flavor_installed(chroot)
|
||||
pmb.chroot.initfs.build(flavor, chroot)
|
||||
|
||||
# Set the user password
|
||||
setup_login(args, suffix)
|
||||
setup_login(args, config, chroot)
|
||||
|
||||
# Set the keymap if the device requires it
|
||||
setup_keymap(config)
|
||||
|
||||
# Set timezone
|
||||
setup_timezone(config)
|
||||
setup_timezone(chroot, config.timezone)
|
||||
|
||||
# Set locale
|
||||
if locale_is_set:
|
||||
# 10locale-pmos.sh gets sourced before 20locale.sh from
|
||||
# alpine-baselayout by /etc/profile. Since they don't override the
|
||||
# locale if it exists, it warranties we have preference
|
||||
line = f"export LANG=${{LANG:-{shlex.quote(args.locale)}}}"
|
||||
line = f"export LANG=${{LANG:-{shlex.quote(config.locale)}}}"
|
||||
pmb.chroot.root(["sh", "-c", f"echo {shlex.quote(line)}"
|
||||
" > /etc/profile.d/10locale-pmos.sh"], suffix)
|
||||
" > /etc/profile.d/10locale-pmos.sh"], chroot)
|
||||
|
||||
# Set the hostname as the device name
|
||||
setup_hostname(args)
|
||||
setup_hostname(device, config.hostname)
|
||||
|
||||
setup_appstream(args)
|
||||
setup_appstream(context.offline, chroot)
|
||||
|
||||
disable_sshd(args)
|
||||
disable_firewall(args)
|
||||
if args.no_sshd:
|
||||
disable_sshd(chroot)
|
||||
if args.no_firewall:
|
||||
disable_firewall(chroot)
|
||||
|
||||
|
||||
def install(args: PmbArgs):
|
||||
device = get_context().config.device
|
||||
chroot = Chroot(ChrootType.ROOTFS, device)
|
||||
deviceinfo = pmb.parse.deviceinfo()
|
||||
# Sanity checks
|
||||
sanity_check_boot_size()
|
||||
if not args.android_recovery_zip and args.disk:
|
||||
|
@ -1319,18 +1313,18 @@ def install(args: PmbArgs):
|
|||
if args.no_image:
|
||||
return
|
||||
elif args.android_recovery_zip:
|
||||
return install_recovery_zip(args, 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:
|
||||
install_system_image(args, 0, Chroot(ChrootType.ROOTFS, args.devicesdhbfvhubsud), step, steps,
|
||||
install_system_image(args, 0, chroot, step, steps,
|
||||
split=args.split, disk=args.disk)
|
||||
|
||||
print_flash_info(args)
|
||||
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)
|
||||
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 = args.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 args.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 = args.deviceinfo["rootfs_image_sector_size"]
|
||||
sector_size = pmb.parse.deviceinfo()["rootfs_image_sector_size"]
|
||||
if sector_size:
|
||||
losetup_cmd += ["-b", str(int(sector_size))]
|
||||
|
||||
|
|
|
@ -14,15 +14,15 @@ from pmb.core import Chroot
|
|||
|
||||
# FIXME (#2324): this function drops disk to a string because it's easier
|
||||
# to manipulate, this is probably bad.
|
||||
def partitions_mount(args: PmbArgs, layout, disk: Optional[Path]):
|
||||
def partitions_mount(device: str, layout, disk: Optional[Path]):
|
||||
"""
|
||||
Mount blockdevices of partitions inside native chroot
|
||||
:param layout: partition layout from get_partition_layout()
|
||||
:param disk: path to disk block device (e.g. /dev/mmcblk0) or None
|
||||
"""
|
||||
if not disk:
|
||||
img_path = Path("/home/pmos/rootfs") / f"{args.devicesdhbfvhubsud}.img"
|
||||
disk = pmb.install.losetup.device_by_back_file(args, img_path)
|
||||
img_path = Path("/home/pmos/rootfs") / f"{device}.img"
|
||||
disk = pmb.install.losetup.device_by_back_file(img_path)
|
||||
|
||||
logging.info(f"Mounting partitions of {disk} inside the chroot")
|
||||
|
||||
|
@ -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 = args.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 = args.deviceinfo["boot_part_start"] or "2048"
|
||||
boot_part_start = pmb.parse.deviceinfo()["boot_part_start"] or "2048"
|
||||
|
||||
partition_type = args.deviceinfo["partition_type"] or "msdos"
|
||||
partition_type = pmb.parse.deviceinfo()["partition_type"] or "msdos"
|
||||
|
||||
commands = [
|
||||
["mktable", partition_type],
|
||||
|
@ -128,11 +128,11 @@ def partition_cgpt(args: PmbArgs, layout, size_boot, size_reserve):
|
|||
:param size_reserve: empty partition between root and boot in MiB (pma#463)
|
||||
"""
|
||||
|
||||
pmb.chroot.apk.install(["cgpt"], build=False)
|
||||
pmb.chroot.apk.install(["cgpt"], Chroot.native(), build=False)
|
||||
|
||||
cgpt = {
|
||||
'kpart_start': args.deviceinfo["cgpt_kpart_start"],
|
||||
'kpart_size': args.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
|
||||
|
@ -178,7 +178,7 @@ def partition_cgpt(args: PmbArgs, layout, size_boot, size_reserve):
|
|||
]
|
||||
|
||||
dev_size = pmb.chroot.root(
|
||||
args, ["blockdev", "--getsz", "/dev/install"], output_return=True)
|
||||
["blockdev", "--getsz", "/dev/install"], output_return=True)
|
||||
# 33: Sec GPT table (32) + Sec GPT header (1)
|
||||
root_size = str(int(dev_size) - int(s_root_start) - 33)
|
||||
|
||||
|
|
|
@ -1,38 +1,40 @@
|
|||
# Copyright 2023 Attila Szollosi
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
from pathlib import Path
|
||||
from pmb.core.chroot import Chroot
|
||||
from pmb.helpers import logging
|
||||
|
||||
import pmb.chroot
|
||||
import pmb.chroot.apk
|
||||
import pmb.config.pmaports
|
||||
from pmb.types import PmbArgs
|
||||
import pmb.flasher
|
||||
import pmb.helpers.frontend
|
||||
|
||||
|
||||
def create_zip(args: PmbArgs, suffix):
|
||||
def create_zip(args: PmbArgs, chroot: Chroot, device: str):
|
||||
"""
|
||||
Create android recovery compatible installer zip.
|
||||
"""
|
||||
zip_root = Path("/var/lib/postmarketos-android-recovery-installer/")
|
||||
rootfs = "/mnt/rootfs_" + args.devicesdhbfvhubsud
|
||||
flavor = pmb.helpers.frontend._parse_flavor(args)
|
||||
method = args.deviceinfo["flash_method"]
|
||||
rootfs = "/mnt/rootfs_" + device
|
||||
flavor = pmb.helpers.frontend._parse_flavor(device)
|
||||
deviceinfo = pmb.parse.deviceinfo()
|
||||
method = deviceinfo["flash_method"]
|
||||
vars = pmb.flasher.variables(args, flavor, method)
|
||||
|
||||
# Install recovery installer package in buildroot
|
||||
pmb.chroot.apk.install(args,
|
||||
["postmarketos-android-recovery-installer"],
|
||||
suffix)
|
||||
pmb.chroot.apk.install(["postmarketos-android-recovery-installer"],
|
||||
chroot)
|
||||
|
||||
logging.info(f"({suffix}) create recovery zip")
|
||||
logging.info(f"({chroot}) create recovery zip")
|
||||
|
||||
for key in vars:
|
||||
pmb.flasher.check_partition_blacklist(args, key, vars[key])
|
||||
pmb.flasher.check_partition_blacklist(args, deviceinfo, key, vars[key])
|
||||
|
||||
# Create config file for the recovery installer
|
||||
options = {
|
||||
"DEVICE": args.devicesdhbfvhubsud,
|
||||
"DEVICE": device,
|
||||
"FLASH_KERNEL": args.recovery_flash_kernel,
|
||||
"ISOREC": method == "heimdall-isorec",
|
||||
"KERNEL_PARTLABEL": vars["$PARTITION_KERNEL"],
|
||||
|
@ -52,7 +54,7 @@ def create_zip(args: PmbArgs, suffix):
|
|||
options["FLAVOR"] = f"-{flavor}" if flavor is not None else "-"
|
||||
|
||||
# Write to a temporary file
|
||||
config_temp = suffix / "tmp/install_options"
|
||||
config_temp = chroot / "tmp/install_options"
|
||||
with config_temp.open("w") as handle:
|
||||
for key, value in options.items():
|
||||
if isinstance(value, bool):
|
||||
|
@ -69,6 +71,6 @@ def create_zip(args: PmbArgs, suffix):
|
|||
["tar", "-prf", "rootfs.tar", "-C", "/", "./etc/apk/keys"],
|
||||
# Compress with -1 for speed improvement
|
||||
["gzip", "-f1", "rootfs.tar"],
|
||||
["build-recovery-zip", args.devicesdhbfvhubsud]]
|
||||
["build-recovery-zip", device]]
|
||||
for command in commands:
|
||||
pmb.chroot.root(command, suffix, working_dir=zip_root)
|
||||
pmb.chroot.root(command, chroot, working_dir=zip_root)
|
||||
|
|
|
@ -1,45 +1,46 @@
|
|||
# Copyright 2023 Mark Hargreaves, Luca Weiss
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
from pmb.core.context import get_context
|
||||
from pmb.helpers import logging
|
||||
from pathlib import Path
|
||||
import socket
|
||||
import time
|
||||
|
||||
import pmb.chroot.run
|
||||
import pmb.chroot
|
||||
from pmb.types import PmbArgs
|
||||
import pmb.helpers.run
|
||||
from pmb.core import Chroot
|
||||
|
||||
|
||||
def start_nbd_server(args: PmbArgs, ip="172.16.42.2", port=9999):
|
||||
def start_nbd_server(device: str, replace: bool, ip="172.16.42.2", port=9999):
|
||||
"""
|
||||
Start nbd server in chroot_native with pmOS rootfs.
|
||||
:param ip: IP address to serve nbd server for
|
||||
:param port: port of nbd server
|
||||
"""
|
||||
|
||||
pmb.chroot.apk.install(['nbd'])
|
||||
pmb.chroot.apk.install(['nbd'], Chroot.native())
|
||||
|
||||
chroot = Chroot.native()
|
||||
|
||||
rootfs_path = Path("/mnt/pmbootstrap/netboot") / f"{args.devicesdhbfvhubsud}.img"
|
||||
if not (chroot / rootfs_path).exists() or args.replace:
|
||||
rootfs_path2 = Path("/home/pmos/rootfs") / f"{args.devicesdhbfvhubsud}.img"
|
||||
rootfs_path = Path("/mnt/pmbootstrap/netboot") / f"{device}.img"
|
||||
if not (chroot / rootfs_path).exists() or replace:
|
||||
rootfs_path2 = Path("/home/pmos/rootfs") / f"{device}.img"
|
||||
if not (chroot / rootfs_path2).exists():
|
||||
raise RuntimeError("The rootfs has not been generated yet, please "
|
||||
"run 'pmbootstrap install' first.")
|
||||
if args.replace and not \
|
||||
if replace and not \
|
||||
pmb.helpers.cli.confirm(f"Are you sure you want to "
|
||||
f"replace the rootfs for "
|
||||
f"{args.devicesdhbfvhubsud}?"):
|
||||
f"{device}?"):
|
||||
return
|
||||
pmb.chroot.run(args, ["cp", rootfs_path2, rootfs_path])
|
||||
pmb.chroot.root(["cp", rootfs_path2, rootfs_path])
|
||||
logging.info(f"NOTE: Copied device image to {get_context().config.work}"
|
||||
f"/images_netboot/. The image will persist \"pmbootstrap "
|
||||
f"zap\" for your convenience. Use \"pmbootstrap netboot "
|
||||
f"serve --help\" for more options.")
|
||||
|
||||
logging.info(f"Running nbd server for {args.devicesdhbfvhubsud} on {ip} port {port}.")
|
||||
logging.info(f"Running nbd server for {device} on {ip} port {port}.")
|
||||
|
||||
while True:
|
||||
logging.info("Waiting for postmarketOS device to appear...")
|
||||
|
@ -61,8 +62,7 @@ def start_nbd_server(args: PmbArgs, ip="172.16.42.2", port=9999):
|
|||
break
|
||||
|
||||
logging.info("Found postmarketOS device, serving image...")
|
||||
pmb.chroot.run(
|
||||
args, ["nbd-server", f"{ip}@{port}", rootfs_path, "-d"],
|
||||
pmb.chroot.root(["nbd-server", f"{ip}@{port}", rootfs_path, "-d"],
|
||||
check=False, disable_timeout=True)
|
||||
logging.info("nbd-server quit. Connection lost?")
|
||||
# On a reboot nbd-server will quit, but the IP address sticks around
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
# Copyright 2023 Oliver Smith
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
# mypy: disable-error-code="attr-defined"
|
||||
from pmb.core.context import get_context
|
||||
from pmb.helpers import logging
|
||||
import os
|
||||
from pathlib import Path
|
||||
|
|
|
@ -594,11 +594,8 @@ def arguments_ci(subparser):
|
|||
|
||||
|
||||
def package_completer(prefix, action, parser=None, parsed_args=None):
|
||||
args = parsed_args
|
||||
pmb.config.merge_with_args(args)
|
||||
pmb.helpers.args.replace_placeholders(args)
|
||||
packages = set(
|
||||
package for package in pmb.helpers.pmaports.get_list(args)
|
||||
package for package in pmb.helpers.pmaports.get_list()
|
||||
if package.startswith(prefix))
|
||||
return packages
|
||||
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
# Copyright 2023 Oliver Smith
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
import os
|
||||
from pmb.core.context import get_context
|
||||
from pmb.helpers import logging
|
||||
from pathlib import Path
|
||||
from pmb.types import PmbArgs
|
||||
import pmb.helpers.run
|
||||
import pmb.chroot.run
|
||||
import pmb.chroot
|
||||
import pmb.chroot.other
|
||||
import pmb.chroot.apk
|
||||
from pmb.core import Chroot
|
||||
|
@ -72,7 +73,7 @@ def get_qcdt_type(path):
|
|||
return None
|
||||
|
||||
|
||||
def bootimg(args: PmbArgs, path: Path):
|
||||
def bootimg(path: Path):
|
||||
if not path.exists():
|
||||
raise RuntimeError(f"Could not find file '{path}'")
|
||||
|
||||
|
@ -93,7 +94,7 @@ def bootimg(args: PmbArgs, path: Path):
|
|||
working_dir=temp_path,
|
||||
output_return=True).rstrip()
|
||||
if "android bootimg" not in file_output.lower():
|
||||
if "force" in args and args.force:
|
||||
if get_context().force:
|
||||
logging.warning("WARNING: boot.img file seems to be invalid, but"
|
||||
" proceeding anyway (-f specified)")
|
||||
else:
|
||||
|
@ -166,6 +167,6 @@ def bootimg(args: PmbArgs, path: Path):
|
|||
output["cmdline"] = f.read().replace('\n', '')
|
||||
|
||||
# Cleanup
|
||||
pmb.chroot.run.user(["rm", "-r", temp_path])
|
||||
pmb.chroot.user(["rm", "-r", temp_path])
|
||||
|
||||
return output
|
||||
|
|
|
@ -230,7 +230,7 @@ def check_config(config_path, config_arch, pkgver, components_list=[],
|
|||
return all(results)
|
||||
|
||||
|
||||
def check(args: PmbArgs, pkgname, components_list=[], details=False, must_exist=True):
|
||||
def check(pkgname, components_list=[], details=False, must_exist=True):
|
||||
"""
|
||||
Check for necessary kernel config options in a package.
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
import subprocess
|
||||
from typing import Sequence
|
||||
from pmb.core.context import get_context
|
||||
from pmb.helpers import logging
|
||||
import os
|
||||
from pathlib import Path
|
||||
|
@ -24,12 +25,12 @@ import pmb.parse.cpuinfo
|
|||
from pmb.core import Chroot, ChrootType
|
||||
|
||||
|
||||
def system_image(args: PmbArgs):
|
||||
def system_image(device: str):
|
||||
"""
|
||||
Returns path to rootfs for specified device. In case that it doesn't
|
||||
exist, raise and exception explaining how to generate it.
|
||||
"""
|
||||
path = Chroot.native() / "home/pmos/rootfs" / f"{args.devicesdhbfvhubsud}.img"
|
||||
path = Chroot.native() / "home/pmos/rootfs" / f"{device}.img"
|
||||
if not path.exists():
|
||||
logging.debug(f"Could not find rootfs: {path}")
|
||||
raise RuntimeError("The rootfs has not been generated yet, please "
|
||||
|
@ -37,14 +38,14 @@ def system_image(args: PmbArgs):
|
|||
return path
|
||||
|
||||
|
||||
def create_second_storage(args: PmbArgs):
|
||||
def create_second_storage(args: PmbArgs, device: str):
|
||||
"""
|
||||
Generate a second storage image if it does not exist.
|
||||
|
||||
:returns: path to the image or None
|
||||
|
||||
"""
|
||||
path = Chroot.native() / "home/pmos/rootfs" / f"{args.devicesdhbfvhubsud}-2nd.img"
|
||||
path = Chroot.native() / "home/pmos/rootfs" / f"{device}-2nd.img"
|
||||
pmb.helpers.run.root(["touch", path])
|
||||
pmb.helpers.run.root(["chmod", "a+w", path])
|
||||
resize_image(args, args.second_storage, path)
|
||||
|
@ -87,11 +88,11 @@ def create_gdk_loader_cache(args: PmbArgs) -> Path:
|
|||
return chroot_native / custom_cache_path
|
||||
|
||||
|
||||
def command_qemu(args: PmbArgs, arch, img_path, img_path_2nd=None):
|
||||
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 = args.deviceinfo["kernel_cmdline"]
|
||||
cmdline = pmb.parse.deviceinfo()["kernel_cmdline"]
|
||||
if args.cmdline:
|
||||
cmdline = args.cmdline
|
||||
|
||||
|
@ -102,9 +103,9 @@ def command_qemu(args: PmbArgs, arch, img_path, img_path_2nd=None):
|
|||
|
||||
port_ssh = str(args.port)
|
||||
|
||||
chroot = Chroot(ChrootType.ROOTFS, args.devicesdhbfvhubsud)
|
||||
chroot = Chroot(ChrootType.ROOTFS, device)
|
||||
chroot_native = Chroot.native()
|
||||
flavor = pmb.chroot.other.kernel_flavor_installed(args, chroot)
|
||||
flavor = pmb.chroot.other.kernel_flavor_installed(chroot)
|
||||
flavor_suffix = f"-{flavor}"
|
||||
# Backwards compatibility with old mkinitfs (pma#660)
|
||||
pmaports_cfg = pmb.config.pmaports.read_config()
|
||||
|
@ -220,7 +221,7 @@ def command_qemu(args: PmbArgs, 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 == args.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"]
|
||||
|
@ -315,7 +316,7 @@ def install_depends(args: PmbArgs, arch):
|
|||
]
|
||||
|
||||
# QEMU packaging isn't split up as much in 3.12
|
||||
channel_cfg = pmb.config.pmaports.read_config_channel(args)
|
||||
channel_cfg = pmb.config.pmaports.read_config_channel()
|
||||
if channel_cfg["branch_aports"] == "3.12-stable":
|
||||
depends.remove("qemu-hw-display-virtio-gpu")
|
||||
depends.remove("qemu-hw-display-virtio-gpu-pci")
|
||||
|
@ -332,22 +333,23 @@ def run(args: PmbArgs):
|
|||
"""
|
||||
Run a postmarketOS image in qemu
|
||||
"""
|
||||
if not args.devicesdhbfvhubsud.startswith("qemu-"):
|
||||
device = get_context().config.device
|
||||
if not device.startswith("qemu-"):
|
||||
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(args.deviceinfo["arch"])
|
||||
arch = pmb.parse.arch.alpine_to_qemu(pmb.parse.deviceinfo()["arch"])
|
||||
|
||||
img_path = system_image(args)
|
||||
img_path = system_image(device)
|
||||
img_path_2nd = None
|
||||
if args.second_storage:
|
||||
img_path_2nd = create_second_storage(args)
|
||||
img_path_2nd = create_second_storage(args, device)
|
||||
|
||||
if not args.host_qemu:
|
||||
install_depends(args, arch)
|
||||
logging.info("Running postmarketOS in QEMU VM (" + arch + ")")
|
||||
|
||||
qemu, env = command_qemu(args, arch, img_path, img_path_2nd)
|
||||
qemu, env = command_qemu(args, device, arch, img_path, img_path_2nd)
|
||||
|
||||
# Workaround: QEMU runs as local user and needs write permissions in the
|
||||
# rootfs, which is owned by root
|
||||
|
|
11
pmb/types.py
11
pmb/types.py
|
@ -46,7 +46,6 @@ class PmbArgs(Namespace):
|
|||
autoinstall: str
|
||||
boot_size: str
|
||||
build_default_device_arch: str
|
||||
build_pkgs_on_install: bool
|
||||
buildroot: str
|
||||
built: str
|
||||
ccache_size: str
|
||||
|
@ -72,14 +71,13 @@ class PmbArgs(Namespace):
|
|||
filesystem: str
|
||||
flash_method: str
|
||||
folder: str
|
||||
force: str
|
||||
force: bool
|
||||
fork_alpine: str
|
||||
# This is a filthy lie
|
||||
from_argparse: "PmbArgs"
|
||||
full_disk_encryption: str
|
||||
hook: str
|
||||
host: str
|
||||
hostname: str
|
||||
host_qemu: str
|
||||
image_size: str
|
||||
install_base: str
|
||||
|
@ -101,7 +99,7 @@ class PmbArgs(Namespace):
|
|||
name: str
|
||||
no_depends: str
|
||||
no_fde: str
|
||||
no_firewall: str
|
||||
no_firewall: bool
|
||||
no_image: str
|
||||
non_existing: str
|
||||
no_reboot: str
|
||||
|
@ -132,7 +130,7 @@ class PmbArgs(Namespace):
|
|||
recovery_flash_kernel: str
|
||||
recovery_install_partition: str
|
||||
ref: str
|
||||
replace: str
|
||||
replace: bool
|
||||
repository: str
|
||||
reset: str
|
||||
resume: str
|
||||
|
@ -142,7 +140,7 @@ class PmbArgs(Namespace):
|
|||
second_storage: str
|
||||
selected_providers: Dict[str, str]
|
||||
sparse: str
|
||||
split: str
|
||||
split: bool
|
||||
src: str
|
||||
ssh_keys: str
|
||||
strict: str
|
||||
|
@ -150,7 +148,6 @@ class PmbArgs(Namespace):
|
|||
suffix: str
|
||||
systemd: str
|
||||
timeout: float
|
||||
user: str
|
||||
value: str
|
||||
verbose: str
|
||||
verify: str
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue