forked from Mirror/pmbootstrap
WIP: start ripping out args (MR 2252)
Cease merging pmbootstrap.cfg into args, implement a Context type to let us pull globals out of thin air (as an intermediate workaround) and rip args out of a lot of the codebase. This is just a first pass, after this we can split all the state that leaked over into Context into types with narrower scopes (like a BuildContext(), etc). Signed-off-by: Caleb Connolly <caleb@postmarketos.org>
This commit is contained in:
parent
bfea00e03a
commit
34dd9d42ba
129 changed files with 1393 additions and 1300 deletions
|
@ -63,13 +63,13 @@ they contain untrusted input):
|
|||
|
||||
```py
|
||||
# Does not work, the command does not run in a shell!
|
||||
pmb.chroot.root(args, ["echo", "test", ">", "/tmp/test"])
|
||||
pmb.chroot.root(["echo", "test", ">", "/tmp/test"])
|
||||
|
||||
# Use this instead (assuming untrusted input for text, dest)
|
||||
text = "test"
|
||||
dest = "/tmp/test"
|
||||
shell_cmd = f"echo {shutil.quote(text)} > {shutil.quote(dest)}"
|
||||
pmb.chroot.root(args, ["sh", "-c", shell_cmd])
|
||||
pmb.chroot.root(["sh", "-c", shell_cmd])
|
||||
```
|
||||
|
||||
If you need to run many commands in a shell at once, write them into a
|
||||
|
@ -83,7 +83,7 @@ the chroot. Use one of the following methods.
|
|||
|
||||
##### Short files
|
||||
```py
|
||||
pmb.chroot.user(args, ["sh", "-c", f"echo {shlex.quote(hostname)}"
|
||||
pmb.chroot.user(["sh", "-c", f"echo {shlex.quote(hostname)}"
|
||||
" > /etc/hostname"], suffix)
|
||||
```
|
||||
|
||||
|
@ -95,8 +95,8 @@ with open("tmp/somefile", "w") as handle:
|
|||
handle.write("Some long file")
|
||||
handle.write("with multiple")
|
||||
handle.write("lines here")
|
||||
pmb.chroot.root(args, ["mv", "/tmp/somefile", "/etc/somefile"])
|
||||
pmb.chroot.root(args, ["chown", "root:root", "/etc/somefile"], suffix)
|
||||
pmb.chroot.root(["mv", "/tmp/somefile", "/etc/somefile"])
|
||||
pmb.chroot.root(["chown", "root:root", "/etc/somefile"], suffix)
|
||||
```
|
||||
|
||||
### Manual testing
|
||||
|
|
|
@ -10,6 +10,7 @@ from pmb.helpers.exceptions import BuildFailedError, NonBugError
|
|||
|
||||
from . import config
|
||||
from . import parse
|
||||
from . import types
|
||||
from .config import init as config_init
|
||||
from .helpers import frontend
|
||||
from .helpers import logging
|
||||
|
@ -31,8 +32,8 @@ if version < (3, 9):
|
|||
|
||||
|
||||
def print_log_hint() -> None:
|
||||
context = get_context()
|
||||
log = context.log
|
||||
context = get_context(allow_failure=True)
|
||||
log = context.log if context else types.Config().work / "log.txt"
|
||||
# Hints about the log file (print to stdout only)
|
||||
log_hint = "Run 'pmbootstrap log' for details."
|
||||
if not os.path.exists(log):
|
||||
|
@ -50,6 +51,7 @@ def main() -> int:
|
|||
try:
|
||||
# Parse arguments, set up logging
|
||||
args = parse.arguments()
|
||||
context = get_context()
|
||||
os.umask(0o22)
|
||||
|
||||
# Store script invocation command
|
||||
|
@ -66,7 +68,7 @@ def main() -> int:
|
|||
elif not os.path.exists(args.config):
|
||||
raise RuntimeError("Please specify a config file, or run"
|
||||
" 'pmbootstrap init' to generate one.")
|
||||
elif not os.path.exists(config.work):
|
||||
elif not os.path.exists(context.config.work):
|
||||
raise RuntimeError("Work path not found, please run 'pmbootstrap"
|
||||
" init' to create it.")
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
# Copyright 2023 Oliver Smith
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
import os
|
||||
from pmb.core import get_context
|
||||
from pmb.helpers import logging
|
||||
import pmb.aportgen.busybox_static
|
||||
import pmb.aportgen.device
|
||||
|
@ -9,7 +10,7 @@ import pmb.aportgen.linux
|
|||
import pmb.aportgen.musl
|
||||
import pmb.aportgen.grub_efi
|
||||
import pmb.config
|
||||
from pmb.core.types import PmbArgs
|
||||
from pmb.types import PmbArgs
|
||||
import pmb.helpers.cli
|
||||
|
||||
|
||||
|
@ -58,7 +59,8 @@ def generate(args: PmbArgs, pkgname):
|
|||
{"confirm_overwrite": True})
|
||||
else:
|
||||
prefix, folder, options = properties(pkgname)
|
||||
path_target = args.aports / folder / pkgname
|
||||
config = get_context().config
|
||||
path_target = config.aports / folder / pkgname
|
||||
|
||||
# Confirm overwrite
|
||||
if options["confirm_overwrite"] and os.path.exists(path_target):
|
||||
|
@ -67,7 +69,7 @@ def generate(args: PmbArgs, pkgname):
|
|||
if not pmb.helpers.cli.confirm(args, "Continue and overwrite?"):
|
||||
raise RuntimeError("Aborted.")
|
||||
|
||||
aportgen = pmb.config.work / "aportgen"
|
||||
aportgen = config.work / "aportgen"
|
||||
|
||||
if os.path.exists(aportgen):
|
||||
pmb.helpers.run.user(["rm", "-r", aportgen])
|
||||
|
@ -85,6 +87,6 @@ def generate(args: PmbArgs, pkgname):
|
|||
if os.path.exists(path_target):
|
||||
pmb.helpers.run.user(["rm", "-r", path_target])
|
||||
pmb.helpers.run.user(
|
||||
args, ["mv", aportgen, path_target])
|
||||
["mv", aportgen, path_target])
|
||||
|
||||
logging.info("*** pmaport generated: " + path_target)
|
||||
|
|
|
@ -5,30 +5,31 @@ import pmb.aportgen.core
|
|||
import pmb.build
|
||||
import pmb.chroot.apk
|
||||
import pmb.chroot.apk_static
|
||||
from pmb.core.types import PmbArgs
|
||||
from pmb.types import PmbArgs
|
||||
import pmb.helpers.run
|
||||
import pmb.parse.apkindex
|
||||
from pmb.core import Chroot
|
||||
from pmb.core import Chroot, get_context
|
||||
|
||||
|
||||
def generate(args: PmbArgs, pkgname):
|
||||
arch = pkgname.split("-")[2]
|
||||
context = get_context()
|
||||
|
||||
# Parse version from APKINDEX
|
||||
package_data = pmb.parse.apkindex.package(args, "busybox")
|
||||
package_data = pmb.parse.apkindex.package("busybox")
|
||||
version = package_data["version"]
|
||||
pkgver = version.split("-r")[0]
|
||||
pkgrel = version.split("-r")[1]
|
||||
|
||||
# Prepare aportgen tempdir inside and outside of chroot
|
||||
tempdir = Path("/tmp/aportgen")
|
||||
aportgen = pmb.config.work / "aportgen"
|
||||
pmb.chroot.root(args, ["rm", "-rf", tempdir])
|
||||
aportgen = context.config.work / "aportgen"
|
||||
pmb.chroot.root(["rm", "-rf", tempdir])
|
||||
pmb.helpers.run.user(["mkdir", "-p", aportgen,
|
||||
Chroot.native() / tempdir])
|
||||
|
||||
# Write the APKBUILD
|
||||
channel_cfg = pmb.config.pmaports.read_config_channel(args)
|
||||
channel_cfg = pmb.config.pmaports.read_config_channel()
|
||||
mirrordir = channel_cfg["mirrordir_alpine"]
|
||||
apkbuild_path = Chroot.native() / tempdir / "APKBUILD"
|
||||
apk_name = f"busybox-static-$pkgver-r$pkgrel-$_arch-{mirrordir}.apk"
|
||||
|
@ -71,7 +72,7 @@ def generate(args: PmbArgs, pkgname):
|
|||
handle.write(line[12:].replace(" " * 4, "\t") + "\n")
|
||||
|
||||
# Generate checksums
|
||||
pmb.build.init_abuild_minimal(args)
|
||||
pmb.chroot.root(args, ["chown", "-R", "pmos:pmos", tempdir])
|
||||
pmb.chroot.user(args, ["abuild", "checksum"], working_dir=tempdir)
|
||||
pmb.build.init_abuild_minimal()
|
||||
pmb.chroot.root(["chown", "-R", "pmos:pmos", tempdir])
|
||||
pmb.chroot.user(["abuild", "checksum"], working_dir=tempdir)
|
||||
pmb.helpers.run.user(["cp", apkbuild_path, aportgen])
|
||||
|
|
|
@ -3,9 +3,10 @@
|
|||
import fnmatch
|
||||
from pmb.helpers import logging
|
||||
import re
|
||||
from pmb.core.types import PmbArgs
|
||||
from pmb.types import PmbArgs
|
||||
import pmb.helpers.git
|
||||
import pmb.helpers.run
|
||||
from pmb.core import get_context
|
||||
|
||||
|
||||
def indent_size(line):
|
||||
|
@ -48,7 +49,7 @@ def format_function(name, body, remove_indent=4):
|
|||
return name + "() {\n" + ret + "}\n"
|
||||
|
||||
|
||||
def rewrite(args: PmbArgs, pkgname, path_original="", fields={}, replace_pkgname=None,
|
||||
def rewrite(pkgname, path_original="", fields={}, replace_pkgname=None,
|
||||
replace_functions={}, replace_simple={}, below_header="",
|
||||
remove_indent=4):
|
||||
"""
|
||||
|
@ -93,7 +94,7 @@ def rewrite(args: PmbArgs, pkgname, path_original="", fields={}, replace_pkgname
|
|||
lines_new += line.rstrip() + "\n"
|
||||
|
||||
# Copy/modify lines, skip Maintainer/Contributor
|
||||
path = pmb.config.work / "aportgen/APKBUILD"
|
||||
path = get_context().config.work / "aportgen/APKBUILD"
|
||||
with open(path, "r+", encoding="utf-8") as handle:
|
||||
skip_in_func = False
|
||||
for line in handle.readlines():
|
||||
|
@ -165,14 +166,14 @@ def get_upstream_aport(args: PmbArgs, pkgname, arch=None):
|
|||
"""
|
||||
# APKBUILD
|
||||
pmb.helpers.git.clone("aports_upstream")
|
||||
aports_upstream_path = pmb.config.work / "cache_git/aports_upstream"
|
||||
aports_upstream_path = get_context().config.work / "cache_git/aports_upstream"
|
||||
|
||||
if getattr(args, "fork_alpine_retain_branch", False):
|
||||
logging.info("Not changing aports branch as --fork-alpine-retain-branch was "
|
||||
"used.")
|
||||
else:
|
||||
# Checkout branch
|
||||
channel_cfg = pmb.config.pmaports.read_config_channel(args)
|
||||
channel_cfg = pmb.config.pmaports.read_config_channel()
|
||||
branch = channel_cfg["branch_aports"]
|
||||
logging.info(f"Checkout aports.git branch: {branch}")
|
||||
if pmb.helpers.run.user(["git", "checkout", branch],
|
||||
|
@ -202,8 +203,8 @@ def get_upstream_aport(args: PmbArgs, pkgname, arch=None):
|
|||
split = aport_path.parts
|
||||
repo = split[-2]
|
||||
pkgname = split[-1]
|
||||
index_path = pmb.helpers.repo.alpine_apkindex_path(args, repo, arch)
|
||||
package = pmb.parse.apkindex.package(args, pkgname, indexes=[index_path])
|
||||
index_path = pmb.helpers.repo.alpine_apkindex_path(repo, arch)
|
||||
package = pmb.parse.apkindex.package(pkgname, indexes=[index_path])
|
||||
|
||||
# Compare version (return when equal)
|
||||
compare = pmb.parse.version.compare(apkbuild_version, package["version"])
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
# Copyright 2023 Oliver Smith
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
from pmb.core import get_context
|
||||
from pmb.helpers import logging
|
||||
import os
|
||||
from pmb.core.types import PmbArgs
|
||||
from pmb.types import PmbArgs
|
||||
import pmb.helpers.cli
|
||||
import pmb.helpers.run
|
||||
import pmb.aportgen.core
|
||||
|
@ -237,8 +238,9 @@ def generate_deviceinfo(args: PmbArgs, pkgname, name, manufacturer, year, arch,
|
|||
content += content_uuu
|
||||
|
||||
# Write to file
|
||||
pmb.helpers.run.user(["mkdir", "-p", pmb.config.work / "aportgen"])
|
||||
path = pmb.config.work / "aportgen/deviceinfo"
|
||||
work = get_context().config.work
|
||||
pmb.helpers.run.user(["mkdir", "-p", work / "aportgen"])
|
||||
path = work / "aportgen/deviceinfo"
|
||||
with open(path, "w", encoding="utf-8") as handle:
|
||||
for line in content.rstrip().split("\n"):
|
||||
handle.write(line.lstrip() + "\n")
|
||||
|
@ -258,8 +260,9 @@ def generate_modules_initfs(args: PmbArgs):
|
|||
"""
|
||||
|
||||
# Write to file
|
||||
pmb.helpers.run.user(["mkdir", "-p", pmb.config.work / "aportgen"])
|
||||
path = pmb.config.work / "aportgen/modules-initfs"
|
||||
work = get_context().config.work
|
||||
pmb.helpers.run.user(["mkdir", "-p", work / "aportgen"])
|
||||
path = work / "aportgen/modules-initfs"
|
||||
with open(path, "w", encoding="utf-8") as handle:
|
||||
for line in content.rstrip().split("\n"):
|
||||
handle.write(line.lstrip() + "\n")
|
||||
|
@ -308,8 +311,9 @@ def generate_apkbuild(args: PmbArgs, pkgname, name, arch, flash_method):
|
|||
"""
|
||||
|
||||
# Write the file
|
||||
pmb.helpers.run.user(["mkdir", "-p", pmb.config.work / "aportgen"])
|
||||
path = pmb.config.work / "aportgen/APKBUILD"
|
||||
work = get_context().config.work
|
||||
pmb.helpers.run.user(["mkdir", "-p", work / "aportgen"])
|
||||
path = work / "aportgen/APKBUILD"
|
||||
with open(path, "w", encoding="utf-8") as handle:
|
||||
for line in content.rstrip().split("\n"):
|
||||
handle.write(line[8:].replace(" " * 4, "\t") + "\n")
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
# Copyright 2023 Oliver Smith
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
import pmb.aportgen.core
|
||||
from pmb.core.types import PmbArgs
|
||||
from pmb.core import get_context
|
||||
from pmb.types import PmbArgs
|
||||
import pmb.helpers.git
|
||||
import pmb.helpers.run
|
||||
|
||||
|
@ -10,19 +11,20 @@ def generate(args: PmbArgs, 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)
|
||||
based_on = "main/gcc (from Alpine)"
|
||||
elif prefix == "gcc4":
|
||||
upstream = f"{args.aports}/main/gcc4"
|
||||
upstream = f"{context.config.aports}/main/gcc4"
|
||||
based_on = "main/gcc4 (from postmarketOS)"
|
||||
elif prefix == "gcc6":
|
||||
upstream = f"{args.aports}/main/gcc6"
|
||||
upstream = f"{context.config.aports}/main/gcc6"
|
||||
based_on = "main/gcc6 (from postmarketOS)"
|
||||
else:
|
||||
raise ValueError(f"Invalid prefix '{prefix}', expected gcc, gcc4 or"
|
||||
" gcc6.")
|
||||
pmb.helpers.run.user(["cp", "-r", upstream, pmb.config.work / "aportgen"])
|
||||
pmb.helpers.run.user(["cp", "-r", upstream, context.config.work / "aportgen"])
|
||||
|
||||
# Rewrite APKBUILD
|
||||
fields = {
|
||||
|
@ -88,6 +90,6 @@ def generate(args: PmbArgs, pkgname):
|
|||
'_libgcc=true*': '_libgcc=false',
|
||||
}
|
||||
|
||||
pmb.aportgen.core.rewrite(args, pkgname, based_on, fields,
|
||||
pmb.aportgen.core.rewrite(pkgname, based_on, fields,
|
||||
replace_simple=replace_simple,
|
||||
below_header=below_header)
|
||||
|
|
|
@ -5,30 +5,31 @@ import pmb.aportgen.core
|
|||
import pmb.build
|
||||
import pmb.chroot.apk
|
||||
import pmb.chroot.apk_static
|
||||
from pmb.core.types import PmbArgs
|
||||
from pmb.types import PmbArgs
|
||||
import pmb.helpers.run
|
||||
import pmb.parse.apkindex
|
||||
from pmb.core import Chroot
|
||||
from pmb.core import Chroot, get_context
|
||||
|
||||
|
||||
def generate(args: PmbArgs, pkgname):
|
||||
arch = "x86"
|
||||
if pkgname != "grub-efi-x86":
|
||||
raise RuntimeError("only grub-efi-x86 is available")
|
||||
package_data = pmb.parse.apkindex.package(args, "grub")
|
||||
package_data = pmb.parse.apkindex.package("grub")
|
||||
version = package_data["version"]
|
||||
pkgver = version.split("-r")[0]
|
||||
pkgrel = version.split("-r")[1]
|
||||
|
||||
# Prepare aportgen tempdir inside and outside of chroot
|
||||
context = get_context()
|
||||
tempdir = Path("/tmp/aportgen")
|
||||
aportgen = pmb.config.work / "aportgen"
|
||||
pmb.chroot.root(args, ["rm", "-rf", tempdir])
|
||||
aportgen = context.config.work / "aportgen"
|
||||
pmb.chroot.root(["rm", "-rf", tempdir])
|
||||
pmb.helpers.run.user(["mkdir", "-p", aportgen,
|
||||
Chroot.native() / tempdir])
|
||||
|
||||
# Write the APKBUILD
|
||||
channel_cfg = pmb.config.pmaports.read_config_channel(args)
|
||||
channel_cfg = pmb.config.pmaports.read_config_channel()
|
||||
mirrordir = channel_cfg["mirrordir_alpine"]
|
||||
apkbuild_path = Chroot.native() / tempdir / "APKBUILD"
|
||||
apk_name = f'"$srcdir/grub-efi-$pkgver-r$pkgrel-$_arch-{mirrordir}.apk"'
|
||||
|
@ -61,7 +62,7 @@ def generate(args: PmbArgs, pkgname):
|
|||
handle.write(line[12:].replace(" " * 4, "\t") + "\n")
|
||||
|
||||
# Generate checksums
|
||||
pmb.build.init_abuild_minimal(args)
|
||||
pmb.chroot.root(args, ["chown", "-R", "pmos:pmos", tempdir])
|
||||
pmb.chroot.user(args, ["abuild", "checksum"], working_dir=tempdir)
|
||||
pmb.build.init_abuild_minimal()
|
||||
pmb.chroot.root(["chown", "-R", "pmos:pmos", tempdir])
|
||||
pmb.chroot.user(["abuild", "checksum"], working_dir=tempdir)
|
||||
pmb.helpers.run.user(["cp", apkbuild_path, aportgen])
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
# Copyright 2023 Oliver Smith
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
from pmb.core.types import PmbArgs
|
||||
from pmb.core import get_context
|
||||
from pmb.types import PmbArgs
|
||||
import pmb.helpers.run
|
||||
import pmb.aportgen.core
|
||||
import pmb.parse.apkindex
|
||||
|
@ -105,17 +106,18 @@ def generate_apkbuild(args: PmbArgs, pkgname, deviceinfo, patches):
|
|||
"""
|
||||
|
||||
# Write the file
|
||||
with (pmb.config.work / "aportgen/APKBUILD").open("w", encoding="utf-8") as hndl:
|
||||
with (get_context().config.work / "aportgen/APKBUILD").open("w", encoding="utf-8") as hndl:
|
||||
for line in content.rstrip().split("\n"):
|
||||
hndl.write(line[8:].replace(" " * 4, "\t") + "\n")
|
||||
|
||||
|
||||
def generate(args: PmbArgs, pkgname):
|
||||
device = "-".join(pkgname.split("-")[1:])
|
||||
deviceinfo = pmb.parse.deviceinfo(args, device)
|
||||
deviceinfo = pmb.parse.deviceinfo(device)
|
||||
work = get_context().config.work
|
||||
|
||||
# Symlink commonly used patches
|
||||
pmb.helpers.run.user(["mkdir", "-p", pmb.config.work / "aportgen"])
|
||||
pmb.helpers.run.user(["mkdir", "-p", work / "aportgen"])
|
||||
patches = [
|
||||
"gcc7-give-up-on-ilog2-const-optimizations.patch",
|
||||
"gcc8-fix-put-user.patch",
|
||||
|
@ -125,6 +127,6 @@ def generate(args: PmbArgs, pkgname):
|
|||
for patch in patches:
|
||||
pmb.helpers.run.user(["ln", "-s",
|
||||
"../../.shared-patches/linux/" + patch,
|
||||
(pmb.config.work / "aportgen" / patch)])
|
||||
(work / "aportgen" / patch)])
|
||||
|
||||
generate_apkbuild(args, pkgname, deviceinfo, patches)
|
||||
|
|
|
@ -5,30 +5,31 @@ import pmb.aportgen.core
|
|||
import pmb.build
|
||||
import pmb.chroot.apk
|
||||
import pmb.chroot.apk_static
|
||||
from pmb.core.types import PmbArgs
|
||||
from pmb.types import PmbArgs
|
||||
import pmb.helpers.run
|
||||
import pmb.parse.apkindex
|
||||
from pmb.core import Chroot
|
||||
from pmb.core import Chroot, get_context
|
||||
|
||||
|
||||
def generate(args: PmbArgs, pkgname):
|
||||
arch = pkgname.split("-")[1]
|
||||
|
||||
# Parse musl version from APKINDEX
|
||||
package_data = pmb.parse.apkindex.package(args, "musl")
|
||||
package_data = pmb.parse.apkindex.package("musl")
|
||||
version = package_data["version"]
|
||||
pkgver = version.split("-r")[0]
|
||||
pkgrel = version.split("-r")[1]
|
||||
|
||||
# Prepare aportgen tempdir inside and outside of chroot
|
||||
work = get_context().config.work
|
||||
tempdir = Path("/tmp/aportgen")
|
||||
aportgen = pmb.config.work / "aportgen"
|
||||
pmb.chroot.root(args, ["rm", "-rf", tempdir])
|
||||
aportgen = work / "aportgen"
|
||||
pmb.chroot.root(["rm", "-rf", tempdir])
|
||||
pmb.helpers.run.user(["mkdir", "-p", aportgen,
|
||||
Chroot.native() / tempdir])
|
||||
|
||||
# Write the APKBUILD
|
||||
channel_cfg = pmb.config.pmaports.read_config_channel(args)
|
||||
channel_cfg = pmb.config.pmaports.read_config_channel()
|
||||
mirrordir = channel_cfg["mirrordir_alpine"]
|
||||
apkbuild_path = Chroot.native() / tempdir / "APKBUILD"
|
||||
apk_name = f"$srcdir/musl-$pkgver-r$pkgrel-$_arch-{mirrordir}.apk"
|
||||
|
@ -97,7 +98,7 @@ def generate(args: PmbArgs, pkgname):
|
|||
handle.write(line[12:].replace(" " * 4, "\t") + "\n")
|
||||
|
||||
# Generate checksums
|
||||
pmb.build.init_abuild_minimal(args)
|
||||
pmb.chroot.root(args, ["chown", "-R", "pmos:pmos", tempdir])
|
||||
pmb.chroot.user(args, ["abuild", "checksum"], working_dir=tempdir)
|
||||
pmb.build.init_abuild_minimal()
|
||||
pmb.chroot.root(["chown", "-R", "pmos:pmos", tempdir])
|
||||
pmb.chroot.user(["abuild", "checksum"], working_dir=tempdir)
|
||||
pmb.helpers.run.user(["cp", apkbuild_path, aportgen])
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
import datetime
|
||||
import enum
|
||||
from pmb.core.context import Context
|
||||
from pmb.helpers import logging
|
||||
from pathlib import Path
|
||||
|
||||
|
@ -9,7 +10,7 @@ import pmb.build
|
|||
import pmb.build.autodetect
|
||||
import pmb.chroot
|
||||
import pmb.chroot.apk
|
||||
from pmb.core.types import PmbArgs
|
||||
from pmb.types import PmbArgs
|
||||
import pmb.helpers.pmaports
|
||||
import pmb.helpers.repo
|
||||
import pmb.helpers.mount
|
||||
|
@ -18,7 +19,7 @@ import pmb.parse.arch
|
|||
import pmb.parse.apkindex
|
||||
from pmb.helpers.exceptions import BuildFailedError
|
||||
|
||||
from pmb.core import Chroot
|
||||
from pmb.core import Chroot, get_context
|
||||
|
||||
class BootstrapStage(enum.IntEnum):
|
||||
"""
|
||||
|
@ -48,7 +49,7 @@ def skip_already_built(pkgname, arch):
|
|||
return False
|
||||
|
||||
|
||||
def get_apkbuild(args: PmbArgs, pkgname, arch):
|
||||
def get_apkbuild(pkgname, arch):
|
||||
"""Parse the APKBUILD path for pkgname.
|
||||
|
||||
When there is none, try to find it in the binary package APKINDEX files or raise an exception.
|
||||
|
@ -57,19 +58,19 @@ def get_apkbuild(args: PmbArgs, pkgname, arch):
|
|||
:returns: None or parsed APKBUILD
|
||||
"""
|
||||
# Get existing binary package indexes
|
||||
pmb.helpers.repo.update(args, arch)
|
||||
pmb.helpers.repo.update(arch)
|
||||
|
||||
# Get pmaport, skip upstream only packages
|
||||
pmaport = pmb.helpers.pmaports.get(args, pkgname, False)
|
||||
pmaport = pmb.helpers.pmaports.get(pkgname, False)
|
||||
if pmaport:
|
||||
return pmaport
|
||||
if pmb.parse.apkindex.providers(args, pkgname, arch, False):
|
||||
if pmb.parse.apkindex.providers(pkgname, arch, False):
|
||||
return None
|
||||
raise RuntimeError("Package '" + pkgname + "': Could not find aport, and"
|
||||
" could not find this package in any APKINDEX!")
|
||||
|
||||
|
||||
def check_build_for_arch(args: PmbArgs, pkgname, arch):
|
||||
def check_build_for_arch(pkgname, arch):
|
||||
"""Check if pmaport can be built or exists as binary for a specific arch.
|
||||
|
||||
:returns: * True when it can be built
|
||||
|
@ -78,14 +79,15 @@ def check_build_for_arch(args: PmbArgs, pkgname, arch):
|
|||
:raises: RuntimeError if the package can't be built for the given arch and
|
||||
does not exist as binary package.
|
||||
"""
|
||||
context = get_context()
|
||||
# Check for pmaport with arch
|
||||
if pmb.helpers.package.check_arch(args, pkgname, arch, False):
|
||||
if pmb.helpers.package.check_arch(pkgname, arch, False):
|
||||
return True
|
||||
|
||||
# Check for binary package
|
||||
binary = pmb.parse.apkindex.package(args, pkgname, arch, False)
|
||||
binary = pmb.parse.apkindex.package(pkgname, arch, False)
|
||||
if binary:
|
||||
pmaport = pmb.helpers.pmaports.get(args, pkgname)
|
||||
pmaport = pmb.helpers.pmaports.get(pkgname)
|
||||
pmaport_version = pmaport["pkgver"] + "-r" + pmaport["pkgrel"]
|
||||
logging.debug(pkgname + ": found pmaport (" + pmaport_version + ") and"
|
||||
" binary package (" + binary["version"] + ", from"
|
||||
|
@ -95,7 +97,7 @@ def check_build_for_arch(args: PmbArgs, pkgname, arch):
|
|||
|
||||
# No binary package exists and can't build it
|
||||
logging.info("NOTE: You can edit the 'arch=' line inside the APKBUILD")
|
||||
if args.action == "build":
|
||||
if context.command == "build":
|
||||
logging.info("NOTE: Alternatively, use --arch to build for another"
|
||||
" architecture ('pmbootstrap build --arch=armhf " +
|
||||
pkgname + "')")
|
||||
|
@ -103,7 +105,7 @@ def check_build_for_arch(args: PmbArgs, pkgname, arch):
|
|||
arch)
|
||||
|
||||
|
||||
def get_depends(args: PmbArgs, apkbuild):
|
||||
def get_depends(context: Context, apkbuild):
|
||||
"""Alpine's abuild always builds/installs the "depends" and "makedepends" of a package
|
||||
before building it.
|
||||
|
||||
|
@ -116,7 +118,7 @@ def get_depends(args: PmbArgs, apkbuild):
|
|||
ret = list(apkbuild["makedepends"])
|
||||
if "!check" not in apkbuild["options"]:
|
||||
ret += apkbuild["checkdepends"]
|
||||
if "ignore_depends" not in args or not args.ignore_depends:
|
||||
if not context.ignore_depends:
|
||||
ret += apkbuild["depends"]
|
||||
ret = sorted(set(ret))
|
||||
|
||||
|
@ -130,35 +132,35 @@ def get_depends(args: PmbArgs, apkbuild):
|
|||
return ret
|
||||
|
||||
|
||||
def build_depends(args: PmbArgs, apkbuild, arch, strict):
|
||||
def build_depends(context: Context, apkbuild, arch, strict):
|
||||
"""Get and build dependencies with verbose logging messages.
|
||||
|
||||
:returns: (depends, depends_built)
|
||||
"""
|
||||
# Get dependencies
|
||||
pkgname = apkbuild["pkgname"]
|
||||
depends = get_depends(args, apkbuild)
|
||||
depends = get_depends(context, apkbuild)
|
||||
logging.verbose(pkgname + ": build/install dependencies: " +
|
||||
", ".join(depends))
|
||||
|
||||
# --no-depends: check for binary packages
|
||||
depends_built = []
|
||||
if "no_depends" in args and args.no_depends:
|
||||
pmb.helpers.repo.update(args, arch)
|
||||
if context.no_depends:
|
||||
pmb.helpers.repo.update(arch)
|
||||
for depend in depends:
|
||||
# Ignore conflicting dependencies
|
||||
if depend.startswith("!"):
|
||||
continue
|
||||
# Check if binary package is missing
|
||||
if not pmb.parse.apkindex.package(args, depend, arch, False):
|
||||
if not pmb.parse.apkindex.package(depend, arch, False):
|
||||
raise RuntimeError("Missing binary package for dependency '" +
|
||||
depend + "' of '" + pkgname + "', but"
|
||||
" pmbootstrap won't build any depends since"
|
||||
" it was started with --no-depends.")
|
||||
# Check if binary package is outdated
|
||||
apkbuild_dep = get_apkbuild(args, depend, arch)
|
||||
apkbuild_dep = get_apkbuild(depend, arch)
|
||||
if apkbuild_dep and \
|
||||
pmb.build.is_necessary(args, arch, apkbuild_dep):
|
||||
pmb.build.is_necessary(arch, apkbuild_dep):
|
||||
raise RuntimeError(f"Binary package for dependency '{depend}'"
|
||||
f" of '{pkgname}' is outdated, but"
|
||||
f" pmbootstrap won't build any depends"
|
||||
|
@ -168,7 +170,7 @@ def build_depends(args: PmbArgs, apkbuild, arch, strict):
|
|||
for depend in depends:
|
||||
if depend.startswith("!"):
|
||||
continue
|
||||
if package(args, depend, arch, strict=strict):
|
||||
if package(context, depend, arch, strict=strict):
|
||||
depends_built += [depend]
|
||||
logging.verbose(pkgname + ": build dependencies: done, built: " +
|
||||
", ".join(depends_built))
|
||||
|
@ -176,7 +178,7 @@ def build_depends(args: PmbArgs, apkbuild, arch, strict):
|
|||
return (depends, depends_built)
|
||||
|
||||
|
||||
def is_necessary_warn_depends(args: PmbArgs, apkbuild, arch, force, depends_built):
|
||||
def is_necessary_warn_depends(apkbuild, arch, force, depends_built):
|
||||
"""Check if a build is necessary, and warn if it is not, but there were dependencies built.
|
||||
|
||||
:returns: True or False
|
||||
|
@ -185,7 +187,7 @@ def is_necessary_warn_depends(args: PmbArgs, apkbuild, arch, force, depends_buil
|
|||
|
||||
# Check if necessary (this warns about binary version > aport version, so
|
||||
# call it even in force mode)
|
||||
ret = pmb.build.is_necessary(args, arch, apkbuild)
|
||||
ret = pmb.build.is_necessary(arch, apkbuild)
|
||||
if force:
|
||||
ret = True
|
||||
|
||||
|
@ -197,7 +199,7 @@ def is_necessary_warn_depends(args: PmbArgs, apkbuild, arch, force, depends_buil
|
|||
return ret
|
||||
|
||||
|
||||
def init_buildenv(args: PmbArgs, apkbuild, arch, strict=False, force=False, cross=None,
|
||||
def init_buildenv(context: Context, apkbuild, arch, strict=False, force=False, cross=None,
|
||||
chroot: Chroot = Chroot.native(), skip_init_buildenv=False, src=None):
|
||||
"""Build all dependencies.
|
||||
|
||||
|
@ -219,30 +221,30 @@ def init_buildenv(args: PmbArgs, apkbuild, arch, strict=False, force=False, cros
|
|||
depends_arch = pmb.config.arch_native
|
||||
|
||||
# Build dependencies
|
||||
depends, built = build_depends(args, apkbuild, depends_arch, strict)
|
||||
depends, built = build_depends(context, apkbuild, depends_arch, strict)
|
||||
|
||||
# Check if build is necessary
|
||||
if not is_necessary_warn_depends(args, apkbuild, arch, force, built):
|
||||
if not is_necessary_warn_depends(apkbuild, arch, force, built):
|
||||
return False
|
||||
|
||||
# Install and configure abuild, ccache, gcc, dependencies
|
||||
if not skip_init_buildenv:
|
||||
pmb.build.init(args, chroot)
|
||||
pmb.build.other.configure_abuild(args, chroot)
|
||||
if args.ccache:
|
||||
pmb.build.other.configure_ccache(args, chroot)
|
||||
pmb.build.init(chroot)
|
||||
pmb.build.other.configure_abuild(chroot)
|
||||
if context.ccache:
|
||||
pmb.build.other.configure_ccache(chroot)
|
||||
if "rust" in depends or "cargo" in depends:
|
||||
pmb.chroot.apk.install(args, ["sccache"], chroot)
|
||||
pmb.chroot.apk.install(["sccache"], chroot)
|
||||
if not strict and "pmb:strict" not in apkbuild["options"] and len(depends):
|
||||
pmb.chroot.apk.install(args, depends, chroot)
|
||||
pmb.chroot.apk.install(depends, chroot)
|
||||
if src:
|
||||
pmb.chroot.apk.install(args, ["rsync"], chroot)
|
||||
pmb.chroot.apk.install(["rsync"], chroot)
|
||||
|
||||
# Cross-compiler init
|
||||
if cross:
|
||||
pmb.build.init_compiler(args, depends, cross, arch)
|
||||
pmb.build.init_compiler(context, depends, cross, arch)
|
||||
if cross == "crossdirect":
|
||||
pmb.chroot.mount_native_into_foreign(args, chroot)
|
||||
pmb.chroot.mount_native_into_foreign(chroot)
|
||||
|
||||
return True
|
||||
|
||||
|
@ -270,7 +272,7 @@ def get_pkgver(original_pkgver, original_source=False, now=None):
|
|||
return no_suffix + new_suffix
|
||||
|
||||
|
||||
def override_source(args: PmbArgs, apkbuild, pkgver, src, chroot: Chroot=Chroot.native()):
|
||||
def override_source(apkbuild, pkgver, src, chroot: Chroot=Chroot.native()):
|
||||
"""Mount local source inside chroot and append new functions (prepare() etc.)
|
||||
to the APKBUILD to make it use the local source.
|
||||
"""
|
||||
|
@ -286,7 +288,7 @@ def override_source(args: PmbArgs, apkbuild, pkgver, src, chroot: Chroot=Chroot.
|
|||
append_path = "/tmp/APKBUILD.append"
|
||||
append_path_outside = chroot / append_path
|
||||
if append_path_outside.exists():
|
||||
pmb.chroot.root(args, ["rm", append_path], chroot)
|
||||
pmb.chroot.root(["rm", append_path], chroot)
|
||||
|
||||
# Add src path to pkgdesc, cut it off after max length
|
||||
pkgdesc = ("[" + src + "] " + apkbuild["pkgdesc"])[:127]
|
||||
|
@ -327,14 +329,14 @@ def override_source(args: PmbArgs, apkbuild, pkgver, src, chroot: Chroot=Chroot.
|
|||
with open(append_path_outside, "w", encoding="utf-8") as handle:
|
||||
for line in append.split("\n"):
|
||||
handle.write(line[13:].replace(" " * 4, "\t") + "\n")
|
||||
pmb.chroot.user(args, ["cat", append_path], chroot)
|
||||
pmb.chroot.user(["cat", append_path], chroot)
|
||||
|
||||
# Append it to the APKBUILD
|
||||
apkbuild_path = "/home/pmos/build/APKBUILD"
|
||||
shell_cmd = ("cat " + apkbuild_path + " " + append_path + " > " +
|
||||
append_path + "_")
|
||||
pmb.chroot.user(args, ["sh", "-c", shell_cmd], chroot)
|
||||
pmb.chroot.user(args, ["mv", append_path + "_", apkbuild_path], chroot)
|
||||
pmb.chroot.user(["sh", "-c", shell_cmd], chroot)
|
||||
pmb.chroot.user(["mv", append_path + "_", apkbuild_path], chroot)
|
||||
|
||||
|
||||
def mount_pmaports(destination, chroot: Chroot=Chroot.native()):
|
||||
|
@ -344,10 +346,10 @@ def mount_pmaports(destination, chroot: Chroot=Chroot.native()):
|
|||
:param destination: mount point inside the chroot
|
||||
"""
|
||||
outside_destination = chroot / destination
|
||||
pmb.helpers.mount.bind(args.aports, outside_destination, umount=True)
|
||||
pmb.helpers.mount.bind(get_context().config.aports, outside_destination, umount=True)
|
||||
|
||||
|
||||
def link_to_git_dir(args: PmbArgs, suffix):
|
||||
def link_to_git_dir(suffix):
|
||||
""" Make ``/home/pmos/build/.git`` point to the .git dir from pmaports.git, with a
|
||||
symlink so abuild does not fail (#1841).
|
||||
|
||||
|
@ -367,15 +369,15 @@ def link_to_git_dir(args: PmbArgs, suffix):
|
|||
# at that point. Use umount=True, so we don't have an old path mounted
|
||||
# (some tests change the pmaports dir).
|
||||
destination = "/mnt/pmaports"
|
||||
mount_pmaports(args, destination, suffix)
|
||||
mount_pmaports(destination, suffix)
|
||||
|
||||
# Create .git symlink
|
||||
pmb.chroot.user(args, ["mkdir", "-p", "/home/pmos/build"], suffix)
|
||||
pmb.chroot.user(args, ["ln", "-sf", destination + "/.git",
|
||||
pmb.chroot.user(["mkdir", "-p", "/home/pmos/build"], suffix)
|
||||
pmb.chroot.user(["ln", "-sf", destination + "/.git",
|
||||
"/home/pmos/build/.git"], suffix)
|
||||
|
||||
|
||||
def run_abuild(args: PmbArgs, apkbuild, arch, strict=False, force=False, cross=None,
|
||||
def run_abuild(context: Context, apkbuild, arch, strict=False, force=False, cross=None,
|
||||
suffix: Chroot=Chroot.native(), src=None, bootstrap_stage=BootstrapStage.NONE):
|
||||
"""
|
||||
Set up all environment variables and construct the abuild command (all
|
||||
|
@ -415,11 +417,11 @@ def run_abuild(args: PmbArgs, apkbuild, arch, strict=False, force=False, cross=N
|
|||
if cross == "crossdirect":
|
||||
env["PATH"] = ":".join(["/native/usr/lib/crossdirect/" + arch,
|
||||
pmb.config.chroot_path])
|
||||
if not args.ccache:
|
||||
if not context.ccache:
|
||||
env["CCACHE_DISABLE"] = "1"
|
||||
|
||||
# Use sccache without crossdirect (crossdirect uses it via rustc.sh)
|
||||
if args.ccache and cross != "crossdirect":
|
||||
if context.ccache and cross != "crossdirect":
|
||||
env["RUSTC_WRAPPER"] = "/usr/bin/sccache"
|
||||
|
||||
# Cache binary objects from go in this path (like ccache)
|
||||
|
@ -431,7 +433,7 @@ def run_abuild(args: PmbArgs, apkbuild, arch, strict=False, force=False, cross=N
|
|||
# e.g. when using --src they are not bundled, in that case it makes sense
|
||||
# to point GOMODCACHE at pmbootstrap's work dir so the modules are only
|
||||
# downloaded once.
|
||||
if args.go_mod_cache:
|
||||
if context.go_mod_cache:
|
||||
env["GOMODCACHE"] = "/home/pmos/go/pkg/mod"
|
||||
|
||||
if bootstrap_stage:
|
||||
|
@ -450,18 +452,18 @@ def run_abuild(args: PmbArgs, apkbuild, arch, strict=False, force=False, cross=N
|
|||
cmd += ["-f"]
|
||||
|
||||
# Copy the aport to the chroot and build it
|
||||
pmb.build.copy_to_buildpath(args, apkbuild["pkgname"], suffix)
|
||||
override_source(args, apkbuild, pkgver, src, suffix)
|
||||
link_to_git_dir(args, suffix)
|
||||
pmb.chroot.user(args, cmd, suffix, Path("/home/pmos/build"), env=env)
|
||||
pmb.build.copy_to_buildpath(apkbuild["pkgname"], suffix)
|
||||
override_source(apkbuild, pkgver, src, suffix)
|
||||
link_to_git_dir(suffix)
|
||||
pmb.chroot.user(cmd, suffix, Path("/home/pmos/build"), env=env)
|
||||
return (output, cmd, env)
|
||||
|
||||
|
||||
def finish(args: PmbArgs, apkbuild, arch, output: str, chroot: Chroot, strict=False):
|
||||
def finish(apkbuild, arch, output: str, chroot: Chroot, strict=False):
|
||||
"""Various finishing tasks that need to be done after a build."""
|
||||
# Verify output file
|
||||
channel: str = pmb.config.pmaports.read_config(args)["channel"]
|
||||
out_dir = (pmb.config.work / "packages" / channel)
|
||||
channel: str = pmb.config.pmaports.read_config()["channel"]
|
||||
out_dir = (get_context().config.work / "packages" / channel)
|
||||
if not (out_dir / output).exists():
|
||||
raise RuntimeError(f"Package not found after build: {(out_dir / output)}")
|
||||
|
||||
|
@ -473,14 +475,14 @@ def finish(args: PmbArgs, apkbuild, arch, output: str, chroot: Chroot, strict=Fa
|
|||
# Uninstall build dependencies (strict mode)
|
||||
if strict or "pmb:strict" in apkbuild["options"]:
|
||||
logging.info(f"({chroot}) uninstall build dependencies")
|
||||
pmb.chroot.user(args, ["abuild", "undeps"], chroot, Path("/home/pmos/build"),
|
||||
pmb.chroot.user(["abuild", "undeps"], chroot, Path("/home/pmos/build"),
|
||||
env={"SUDO_APK": "abuild-apk --no-progress"})
|
||||
# If the build depends contain postmarketos-keys or postmarketos-base,
|
||||
# abuild will have removed the postmarketOS repository key (pma#1230)
|
||||
pmb.chroot.init_keys(args)
|
||||
pmb.chroot.init_keys()
|
||||
|
||||
|
||||
def package(args: PmbArgs, pkgname, arch=None, force=False, strict=False,
|
||||
def package(context: Context, pkgname, arch=None, force=False, strict=False,
|
||||
skip_init_buildenv=False, src=None,
|
||||
bootstrap_stage=BootstrapStage.NONE):
|
||||
"""
|
||||
|
@ -515,24 +517,24 @@ def package(args: PmbArgs, pkgname, arch=None, force=False, strict=False,
|
|||
return
|
||||
|
||||
# Only build when APKBUILD exists
|
||||
apkbuild = get_apkbuild(args, pkgname, arch)
|
||||
apkbuild = get_apkbuild(pkgname, arch)
|
||||
if not apkbuild:
|
||||
return
|
||||
|
||||
# Detect the build environment (skip unnecessary builds)
|
||||
if not check_build_for_arch(args, pkgname, arch):
|
||||
if not check_build_for_arch(pkgname, arch):
|
||||
return
|
||||
chroot = pmb.build.autodetect.chroot(apkbuild, arch)
|
||||
cross = pmb.build.autodetect.crosscompile(args, apkbuild, arch, chroot)
|
||||
if not init_buildenv(args, apkbuild, arch, strict, force, cross, chroot,
|
||||
cross = pmb.build.autodetect.crosscompile(apkbuild, arch, chroot)
|
||||
if not init_buildenv(context, apkbuild, arch, strict, force, cross, chroot,
|
||||
skip_init_buildenv, src):
|
||||
return
|
||||
|
||||
# Build and finish up
|
||||
try:
|
||||
(output, cmd, env) = run_abuild(args, apkbuild, arch, strict, force, cross,
|
||||
(output, cmd, env) = run_abuild(context, apkbuild, arch, strict, force, cross,
|
||||
chroot, src, bootstrap_stage)
|
||||
except RuntimeError:
|
||||
raise BuildFailedError(f"Build for {arch}/{pkgname} failed!")
|
||||
finish(args, apkbuild, arch, output, chroot, strict)
|
||||
finish(apkbuild, arch, output, chroot, strict)
|
||||
return output
|
||||
|
|
|
@ -6,10 +6,10 @@ from typing import Dict, Optional
|
|||
|
||||
import pmb.config
|
||||
import pmb.chroot.apk
|
||||
from pmb.core.types import PmbArgs
|
||||
from pmb.types import PmbArgs
|
||||
import pmb.helpers.pmaports
|
||||
import pmb.parse.arch
|
||||
from pmb.core import Chroot, ChrootType
|
||||
from pmb.core import Chroot, ChrootType, get_context
|
||||
|
||||
|
||||
# FIXME (#2324): type hint Arch
|
||||
|
@ -31,7 +31,7 @@ def arch_from_deviceinfo(args: PmbArgs, pkgname, aport: Path) -> Optional[str]:
|
|||
|
||||
# Return its arch
|
||||
device = pkgname.split("-", 1)[1]
|
||||
arch = pmb.parse.deviceinfo(args, device)["arch"]
|
||||
arch = pmb.parse.deviceinfo(device)["arch"]
|
||||
logging.verbose(pkgname + ": arch from deviceinfo: " + arch)
|
||||
return arch
|
||||
|
||||
|
@ -47,7 +47,7 @@ def arch(args: PmbArgs, pkgname: str):
|
|||
* device arch (this will be preferred instead if build_default_device_arch is true)
|
||||
* first arch in the APKBUILD
|
||||
"""
|
||||
aport = pmb.helpers.pmaports.find(args, pkgname)
|
||||
aport = pmb.helpers.pmaports.find(pkgname)
|
||||
if not aport:
|
||||
raise FileNotFoundError(f"APKBUILD not found for {pkgname}")
|
||||
ret = arch_from_deviceinfo(args, pkgname, aport)
|
||||
|
@ -57,7 +57,7 @@ def arch(args: PmbArgs, pkgname: str):
|
|||
apkbuild = pmb.parse.apkbuild(aport)
|
||||
arches = apkbuild["arch"]
|
||||
|
||||
if args.build_default_device_arch:
|
||||
if get_context().config.build_default_device_arch:
|
||||
preferred_arch = args.deviceinfo["arch"]
|
||||
preferred_arch_2nd = pmb.config.arch_native
|
||||
else:
|
||||
|
@ -86,11 +86,11 @@ def chroot(apkbuild: Dict[str, str], arch: str) -> Chroot:
|
|||
return Chroot.buildroot(arch)
|
||||
|
||||
|
||||
def crosscompile(args: PmbArgs, apkbuild, arch, suffix: Chroot):
|
||||
def crosscompile(apkbuild, arch, suffix: Chroot):
|
||||
"""
|
||||
:returns: None, "native", "crossdirect"
|
||||
"""
|
||||
if not args.cross:
|
||||
if not get_context().cross:
|
||||
return None
|
||||
if not pmb.parse.arch.cpu_emulation_required(arch):
|
||||
return None
|
||||
|
|
|
@ -6,7 +6,7 @@ from pathlib import Path
|
|||
|
||||
import pmb.chroot
|
||||
import pmb.build
|
||||
from pmb.core.types import PmbArgs
|
||||
from pmb.types import PmbArgs
|
||||
import pmb.helpers.run
|
||||
import pmb.helpers.pmaports
|
||||
from pmb.core import Chroot
|
||||
|
@ -14,25 +14,25 @@ from pmb.core import Chroot
|
|||
|
||||
def update(args: PmbArgs, pkgname):
|
||||
"""Fetch all sources and update the checksums in the APKBUILD."""
|
||||
pmb.build.init_abuild_minimal(args)
|
||||
pmb.build.init_abuild_minimal()
|
||||
pmb.build.copy_to_buildpath(args, pkgname)
|
||||
logging.info("(native) generate checksums for " + pkgname)
|
||||
pmb.chroot.user(args, ["abuild", "checksum"],
|
||||
pmb.chroot.user(["abuild", "checksum"],
|
||||
working_dir=Path("/home/pmos/build"))
|
||||
|
||||
# Copy modified APKBUILD back
|
||||
source = Chroot.native() / "home/pmos/build/APKBUILD"
|
||||
target = f"{os.fspath(pmb.helpers.pmaports.find(args, pkgname))}/"
|
||||
target = f"{os.fspath(pmb.helpers.pmaports.find(pkgname))}/"
|
||||
pmb.helpers.run.user(["cp", source, target])
|
||||
|
||||
|
||||
def verify(args: PmbArgs, pkgname):
|
||||
"""Fetch all sources and verify their checksums."""
|
||||
pmb.build.init_abuild_minimal(args)
|
||||
pmb.build.init_abuild_minimal()
|
||||
pmb.build.copy_to_buildpath(args, pkgname)
|
||||
logging.info("(native) verify checksums for " + pkgname)
|
||||
|
||||
# Fetch and verify sources, "fetch" alone does not verify them:
|
||||
# https://github.com/alpinelinux/abuild/pull/86
|
||||
pmb.chroot.user(args, ["abuild", "fetch", "verify"],
|
||||
pmb.chroot.user(["abuild", "fetch", "verify"],
|
||||
working_dir=Path("/home/pmos/build"))
|
||||
|
|
|
@ -7,15 +7,16 @@ from pathlib import Path
|
|||
import re
|
||||
|
||||
import pmb.aportgen
|
||||
import pmb.aportgen.core
|
||||
import pmb.build
|
||||
import pmb.build.autodetect
|
||||
import pmb.chroot
|
||||
from pmb.core.types import PathString, PmbArgs
|
||||
from pmb.types import PathString, PmbArgs
|
||||
import pmb.helpers
|
||||
import pmb.helpers.mount
|
||||
import pmb.helpers.pmaports
|
||||
import pmb.parse
|
||||
from pmb.core import Chroot
|
||||
from pmb.core import Chroot, get_context
|
||||
|
||||
|
||||
def match_kbuild_out(word):
|
||||
|
@ -90,16 +91,17 @@ def find_kbuild_output_dir(function_body):
|
|||
"can't resolve it, please open an issue.")
|
||||
|
||||
|
||||
def modify_apkbuild(args: PmbArgs, pkgname: str, aport: Path):
|
||||
def modify_apkbuild(pkgname: str, aport: Path):
|
||||
"""Modify kernel APKBUILD to package build output from envkernel.sh."""
|
||||
apkbuild_path = aport + "/APKBUILD"
|
||||
work = get_context().config.work
|
||||
apkbuild_path = aport / "APKBUILD"
|
||||
apkbuild = pmb.parse.apkbuild(apkbuild_path)
|
||||
if os.path.exists(pmb.config.work / "aportgen"):
|
||||
pmb.helpers.run.user(["rm", "-r", pmb.config.work / "aportgen"])
|
||||
if os.path.exists(work / "aportgen"):
|
||||
pmb.helpers.run.user(["rm", "-r", work / "aportgen"])
|
||||
|
||||
pmb.helpers.run.user(["mkdir", pmb.config.work / "aportgen"])
|
||||
pmb.helpers.run.user(["mkdir", work / "aportgen"])
|
||||
pmb.helpers.run.user(["cp", "-r", apkbuild_path,
|
||||
pmb.config.work / "aportgen"])
|
||||
work / "aportgen"])
|
||||
|
||||
pkgver = pmb.build._package.get_pkgver(apkbuild["pkgver"],
|
||||
original_source=False)
|
||||
|
@ -108,7 +110,7 @@ def modify_apkbuild(args: PmbArgs, pkgname: str, aport: Path):
|
|||
"subpackages": "",
|
||||
"builddir": "/home/pmos/build/src"}
|
||||
|
||||
pmb.aportgen.core.rewrite(args, pkgname, apkbuild_path, fields=fields)
|
||||
pmb.aportgen.core.rewrite(pkgname, apkbuild_path, fields=fields)
|
||||
|
||||
|
||||
def run_abuild(args: PmbArgs, pkgname: str, arch: str, apkbuild_path: Path, kbuild_out):
|
||||
|
@ -140,16 +142,16 @@ def run_abuild(args: PmbArgs, pkgname: str, arch: str, apkbuild_path: Path, kbui
|
|||
"as an argument to make.")
|
||||
|
||||
# Create working directory for abuild
|
||||
pmb.build.copy_to_buildpath(args, pkgname)
|
||||
pmb.build.copy_to_buildpath(pkgname)
|
||||
|
||||
# Create symlink from abuild working directory to envkernel build directory
|
||||
if kbuild_out != "":
|
||||
if os.path.islink(chroot / "mnt/linux" / kbuild_out) and \
|
||||
os.path.lexists(chroot / "mnt/linux" / kbuild_out):
|
||||
pmb.chroot.root(args, ["rm", "/mnt/linux" / kbuild_out])
|
||||
pmb.chroot.root(args, ["ln", "-s", "/mnt/linux",
|
||||
pmb.chroot.root(["rm", "/mnt/linux" / kbuild_out])
|
||||
pmb.chroot.root(["ln", "-s", "/mnt/linux",
|
||||
build_path / "src"])
|
||||
pmb.chroot.root(args, ["ln", "-s", kbuild_out_source,
|
||||
pmb.chroot.root(["ln", "-s", kbuild_out_source,
|
||||
build_path / "src" / kbuild_out])
|
||||
|
||||
cmd: List[PathString] = ["cp", apkbuild_path, chroot / build_path / "APKBUILD"]
|
||||
|
@ -161,7 +163,7 @@ def run_abuild(args: PmbArgs, pkgname: str, arch: str, apkbuild_path: Path, kbui
|
|||
"CBUILD": pmb.config.arch_native,
|
||||
"SUDO_APK": "abuild-apk --no-progress"}
|
||||
cmd = ["abuild", "rootpkg"]
|
||||
pmb.chroot.user(args, cmd, working_dir=build_path, env=env)
|
||||
pmb.chroot.user(cmd, working_dir=build_path, env=env)
|
||||
|
||||
# Clean up bindmount
|
||||
pmb.helpers.mount.umount_all(chroot / "mnt/linux")
|
||||
|
@ -170,8 +172,8 @@ def run_abuild(args: PmbArgs, pkgname: str, arch: str, apkbuild_path: Path, kbui
|
|||
if kbuild_out != "":
|
||||
if os.path.islink(chroot / "mnt/linux" / kbuild_out) and \
|
||||
os.path.lexists(chroot / "mnt/linux" / kbuild_out):
|
||||
pmb.chroot.root(args, ["rm", "/mnt/linux" / kbuild_out])
|
||||
pmb.chroot.root(args, ["rm", build_path / "src"])
|
||||
pmb.chroot.root(["rm", "/mnt/linux" / kbuild_out])
|
||||
pmb.chroot.root(["rm", build_path / "src"])
|
||||
|
||||
|
||||
def package_kernel(args: PmbArgs):
|
||||
|
@ -181,10 +183,10 @@ def package_kernel(args: PmbArgs):
|
|||
raise RuntimeError("--envkernel needs exactly one linux-* package as "
|
||||
"argument.")
|
||||
|
||||
aport = pmb.helpers.pmaports.find(args, pkgname)
|
||||
aport = pmb.helpers.pmaports.find(pkgname)
|
||||
|
||||
modify_apkbuild(args, pkgname, aport)
|
||||
apkbuild_path = pmb.config.work / "aportgen/APKBUILD"
|
||||
modify_apkbuild(pkgname, aport)
|
||||
apkbuild_path = get_context().config.work / "aportgen/APKBUILD"
|
||||
|
||||
arch = args.deviceinfo["arch"]
|
||||
apkbuild = pmb.parse.apkbuild(apkbuild_path, check_pkgname=False)
|
||||
|
@ -201,7 +203,7 @@ def package_kernel(args: PmbArgs):
|
|||
pmb.build.init(args, chroot)
|
||||
if pmb.parse.arch.cpu_emulation_required(arch):
|
||||
depends.append("binutils-" + arch)
|
||||
pmb.chroot.apk.install(args, depends, chroot)
|
||||
pmb.chroot.apk.install(depends, chroot)
|
||||
|
||||
output = (arch + "/" + apkbuild["pkgname"] + "-" + apkbuild["pkgver"] +
|
||||
"-r" + apkbuild["pkgrel"] + ".apk")
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
# Copyright 2023 Oliver Smith
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
from pmb.core.context import Context
|
||||
from pmb.helpers import logging
|
||||
import os
|
||||
import pathlib
|
||||
|
@ -8,13 +9,13 @@ import pmb.build
|
|||
import pmb.config
|
||||
import pmb.chroot
|
||||
import pmb.chroot.apk
|
||||
from pmb.core.types import PmbArgs
|
||||
from pmb.types import PmbArgs
|
||||
import pmb.helpers.run
|
||||
import pmb.parse.arch
|
||||
from pmb.core import Chroot
|
||||
from pmb.core import Chroot, get_context
|
||||
|
||||
|
||||
def init_abuild_minimal(args: PmbArgs, chroot: Chroot=Chroot.native()):
|
||||
def init_abuild_minimal(chroot: Chroot=Chroot.native()):
|
||||
"""Initialize a minimal chroot with abuild where one can do 'abuild checksum'."""
|
||||
marker = chroot / "tmp/pmb_chroot_abuild_init_done"
|
||||
if os.path.exists(marker):
|
||||
|
@ -22,45 +23,45 @@ def init_abuild_minimal(args: PmbArgs, chroot: Chroot=Chroot.native()):
|
|||
|
||||
# pigz is multithreaded and makes compression must faster, we install it in the native
|
||||
# chroot and then symlink it into the buildroot so we aren't running it through QEMU.
|
||||
pmb.chroot.apk.install(args, ["pigz"], Chroot.native(), build=False)
|
||||
pmb.chroot.apk.install(args, ["abuild"], chroot, build=False)
|
||||
pmb.chroot.apk.install(["pigz"], Chroot.native(), build=False)
|
||||
pmb.chroot.apk.install(["abuild"], chroot, build=False)
|
||||
|
||||
# Fix permissions
|
||||
pmb.chroot.root(args, ["chown", "root:abuild",
|
||||
pmb.chroot.root(["chown", "root:abuild",
|
||||
"/var/cache/distfiles"], chroot)
|
||||
pmb.chroot.root(args, ["chmod", "g+w",
|
||||
pmb.chroot.root(["chmod", "g+w",
|
||||
"/var/cache/distfiles"], chroot)
|
||||
|
||||
# Add user to group abuild
|
||||
pmb.chroot.root(args, ["adduser", "pmos", "abuild"], chroot)
|
||||
pmb.chroot.root(["adduser", "pmos", "abuild"], chroot)
|
||||
|
||||
pathlib.Path(marker).touch()
|
||||
|
||||
|
||||
def init(args: PmbArgs, chroot: Chroot=Chroot.native()):
|
||||
def init(chroot: Chroot=Chroot.native()):
|
||||
"""Initialize a chroot for building packages with abuild."""
|
||||
marker = chroot / "tmp/pmb_chroot_build_init_done"
|
||||
if marker.exists():
|
||||
return
|
||||
|
||||
# Initialize chroot, install packages
|
||||
pmb.chroot.init(args, Chroot.native())
|
||||
pmb.chroot.init(args, chroot)
|
||||
init_abuild_minimal(args, chroot)
|
||||
pmb.chroot.init(Chroot.native())
|
||||
pmb.chroot.init(chroot)
|
||||
init_abuild_minimal(chroot)
|
||||
|
||||
pmb.chroot.apk.install(args, pmb.config.build_packages, chroot,
|
||||
pmb.chroot.apk.install(pmb.config.build_packages, chroot,
|
||||
build=False)
|
||||
|
||||
# Generate package signing keys
|
||||
if not os.path.exists(pmb.config.work / "config_abuild/abuild.conf"):
|
||||
if not os.path.exists(get_context().config.work / "config_abuild/abuild.conf"):
|
||||
logging.info(f"({chroot}) generate abuild keys")
|
||||
pmb.chroot.user(args, ["abuild-keygen", "-n", "-q", "-a"],
|
||||
pmb.chroot.user(["abuild-keygen", "-n", "-q", "-a"],
|
||||
chroot, env={"PACKAGER": "pmos <pmos@local>"})
|
||||
|
||||
# Copy package signing key to /etc/apk/keys
|
||||
for key in (chroot / "mnt/pmbootstrap/abuild-config").glob("*.pub"):
|
||||
key = key.relative_to(chroot.path)
|
||||
pmb.chroot.root(args, ["cp", key, "/etc/apk/keys/"], chroot)
|
||||
pmb.chroot.root(["cp", key, "/etc/apk/keys/"], chroot)
|
||||
|
||||
apk_arch = chroot.arch
|
||||
|
||||
|
@ -93,25 +94,25 @@ def init(args: PmbArgs, chroot: Chroot=Chroot.native()):
|
|||
for i in range(len(lines)):
|
||||
lines[i] = lines[i][16:]
|
||||
handle.write("\n".join(lines))
|
||||
pmb.chroot.root(args, ["cp", "/tmp/apk_wrapper.sh",
|
||||
pmb.chroot.root(["cp", "/tmp/apk_wrapper.sh",
|
||||
"/usr/local/bin/abuild-apk"], chroot)
|
||||
pmb.chroot.root(args, ["chmod", "+x", "/usr/local/bin/abuild-apk"], chroot)
|
||||
pmb.chroot.root(["chmod", "+x", "/usr/local/bin/abuild-apk"], chroot)
|
||||
|
||||
# abuild.conf: Don't clean the build folder after building, so we can
|
||||
# inspect it afterwards for debugging
|
||||
pmb.chroot.root(args, ["sed", "-i", "-e", "s/^CLEANUP=.*/CLEANUP=''/",
|
||||
pmb.chroot.root(["sed", "-i", "-e", "s/^CLEANUP=.*/CLEANUP=''/",
|
||||
"/etc/abuild.conf"], chroot)
|
||||
|
||||
# abuild.conf: Don't clean up installed packages in strict mode, so
|
||||
# abuild exits directly when pressing ^C in pmbootstrap.
|
||||
pmb.chroot.root(args, ["sed", "-i", "-e",
|
||||
pmb.chroot.root(["sed", "-i", "-e",
|
||||
"s/^ERROR_CLEANUP=.*/ERROR_CLEANUP=''/",
|
||||
"/etc/abuild.conf"], chroot)
|
||||
|
||||
pathlib.Path(marker).touch()
|
||||
|
||||
|
||||
def init_compiler(args: PmbArgs, depends, cross, arch):
|
||||
def init_compiler(context: Context, depends, cross, arch):
|
||||
cross_pkgs = ["ccache-cross-symlinks", "abuild"]
|
||||
if "gcc4" in depends:
|
||||
cross_pkgs += ["gcc4-" + arch]
|
||||
|
@ -124,11 +125,11 @@ def init_compiler(args: PmbArgs, depends, cross, arch):
|
|||
if cross == "crossdirect":
|
||||
cross_pkgs += ["crossdirect"]
|
||||
if "rust" in depends or "cargo" in depends:
|
||||
if args.ccache:
|
||||
if context.ccache:
|
||||
cross_pkgs += ["sccache"]
|
||||
# crossdirect for rust installs all build dependencies in the
|
||||
# native chroot too, as some of them can be required for building
|
||||
# native macros / build scripts
|
||||
cross_pkgs += depends
|
||||
|
||||
pmb.chroot.apk.install(args, cross_pkgs, Chroot.native())
|
||||
pmb.chroot.apk.install(cross_pkgs, Chroot.native())
|
||||
|
|
|
@ -11,7 +11,7 @@ import pmb.build.checksum
|
|||
import pmb.chroot
|
||||
import pmb.chroot.apk
|
||||
import pmb.chroot.other
|
||||
from pmb.core.types import PmbArgs
|
||||
from pmb.types import PmbArgs
|
||||
import pmb.helpers.pmaports
|
||||
import pmb.helpers.run
|
||||
import pmb.parse
|
||||
|
@ -65,7 +65,7 @@ def get_outputdir(args: PmbArgs, pkgname: str, apkbuild: Dict[str, Any]) -> Path
|
|||
|
||||
# New style ($builddir)
|
||||
cmd = "srcdir=/home/pmos/build/src source APKBUILD; echo $builddir"
|
||||
ret = Path(pmb.chroot.user(args, ["sh", "-c", cmd],
|
||||
ret = Path(pmb.chroot.user(["sh", "-c", cmd],
|
||||
chroot, Path("/home/pmos/build"),
|
||||
output_return=True).rstrip())
|
||||
if (chroot / ret / ".config").exists():
|
||||
|
@ -87,9 +87,9 @@ def get_outputdir(args: PmbArgs, pkgname: str, apkbuild: Dict[str, Any]) -> Path
|
|||
def extract_and_patch_sources(args: PmbArgs, pkgname: str, arch):
|
||||
pmb.build.copy_to_buildpath(args, pkgname)
|
||||
logging.info("(native) extract kernel source")
|
||||
pmb.chroot.user(args, ["abuild", "unpack"], working_dir=Path("/home/pmos/build"))
|
||||
pmb.chroot.user(["abuild", "unpack"], working_dir=Path("/home/pmos/build"))
|
||||
logging.info("(native) apply patches")
|
||||
pmb.chroot.user(args, ["abuild", "prepare"], working_dir=Path("/home/pmos/build"),
|
||||
pmb.chroot.user(["abuild", "prepare"], working_dir=Path("/home/pmos/build"),
|
||||
output="interactive", env={"CARCH": arch})
|
||||
|
||||
|
||||
|
@ -99,7 +99,7 @@ def menuconfig(args: PmbArgs, pkgname: str, use_oldconfig):
|
|||
pkgname = "linux-" + pkgname
|
||||
|
||||
# Read apkbuild
|
||||
aport = pmb.helpers.pmaports.find(args, pkgname)
|
||||
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)
|
||||
|
@ -128,7 +128,7 @@ def menuconfig(args: PmbArgs, pkgname: str, use_oldconfig):
|
|||
else:
|
||||
depends += ["ncurses-dev"]
|
||||
|
||||
pmb.chroot.apk.install(args, depends)
|
||||
pmb.chroot.apk.install(depends)
|
||||
|
||||
# Copy host's .xauthority into native
|
||||
if copy_xauth:
|
||||
|
@ -150,7 +150,7 @@ def menuconfig(args: PmbArgs, pkgname: str, use_oldconfig):
|
|||
env["CC"] = f"{hostspec}-gcc"
|
||||
if color:
|
||||
env["MENUCONFIG_COLOR"] = color
|
||||
pmb.chroot.user(args, ["make", kopt], Chroot.native(),
|
||||
pmb.chroot.user(["make", kopt], Chroot.native(),
|
||||
outputdir, output="tui", env=env)
|
||||
|
||||
# Find the updated config
|
||||
|
|
|
@ -4,12 +4,12 @@ import os
|
|||
from pmb.helpers import logging
|
||||
from pathlib import Path
|
||||
import pmb.chroot.run
|
||||
from pmb.core.types import PmbArgs
|
||||
from pmb.types import PmbArgs
|
||||
import pmb.helpers.cli
|
||||
import pmb.parse
|
||||
import pmb.build
|
||||
|
||||
from pmb.core import Chroot
|
||||
from pmb.core import Chroot, get_context
|
||||
|
||||
|
||||
def newapkbuild(args: PmbArgs, folder, args_passed, force=False):
|
||||
|
@ -18,11 +18,11 @@ def newapkbuild(args: PmbArgs, folder, args_passed, force=False):
|
|||
build = Path("/home/pmos/build")
|
||||
build_outside = Chroot.native() / build
|
||||
if build_outside.exists():
|
||||
pmb.chroot.root(args, ["rm", "-r", build])
|
||||
pmb.chroot.user(args, ["mkdir", "-p", build])
|
||||
pmb.chroot.root(["rm", "-r", build])
|
||||
pmb.chroot.user(["mkdir", "-p", build])
|
||||
|
||||
# Run newapkbuild
|
||||
pmb.chroot.user(args, ["newapkbuild"] + args_passed, working_dir=build)
|
||||
pmb.chroot.user(["newapkbuild"] + args_passed, working_dir=build)
|
||||
glob_result = list(build_outside.glob("/*/APKBUILD"))
|
||||
if not len(glob_result):
|
||||
return
|
||||
|
@ -30,13 +30,13 @@ def newapkbuild(args: PmbArgs, folder, args_passed, force=False):
|
|||
# Paths for copying
|
||||
source_apkbuild = glob_result[0]
|
||||
pkgname = pmb.parse.apkbuild(source_apkbuild, False)["pkgname"]
|
||||
target = args.aports / folder / pkgname
|
||||
target = get_context().config.aports / folder / pkgname
|
||||
|
||||
# Move /home/pmos/build/$pkgname/* to /home/pmos/build/*
|
||||
for path in build_outside.glob("/*/*"):
|
||||
path_inside = build / pkgname / os.path.basename(path)
|
||||
pmb.chroot.user(args, ["mv", path_inside, build])
|
||||
pmb.chroot.user(args, ["rmdir", build / pkgname])
|
||||
pmb.chroot.user(["mv", path_inside, build])
|
||||
pmb.chroot.user(["rmdir", build / pkgname])
|
||||
|
||||
# Overwrite confirmation
|
||||
if os.path.exists(target):
|
||||
|
|
|
@ -8,7 +8,7 @@ import datetime
|
|||
from typing import List
|
||||
|
||||
import pmb.chroot
|
||||
from pmb.core.types import PmbArgs
|
||||
from pmb.types import PmbArgs
|
||||
import pmb.helpers.file
|
||||
import pmb.helpers.git
|
||||
import pmb.helpers.pmaports
|
||||
|
@ -16,12 +16,12 @@ import pmb.helpers.run
|
|||
import pmb.parse.arch
|
||||
import pmb.parse.apkindex
|
||||
import pmb.parse.version
|
||||
from pmb.core import Chroot
|
||||
from pmb.core import Chroot, get_context
|
||||
|
||||
|
||||
def copy_to_buildpath(args: PmbArgs, package, chroot: Chroot=Chroot.native()):
|
||||
def copy_to_buildpath(package, chroot: Chroot=Chroot.native()):
|
||||
# Sanity check
|
||||
aport = pmb.helpers.pmaports.find(args, package)
|
||||
aport = pmb.helpers.pmaports.find(package)
|
||||
if not os.path.exists(aport / "APKBUILD"):
|
||||
raise ValueError(f"Path does not contain an APKBUILD file: {aport}")
|
||||
|
||||
|
@ -42,11 +42,11 @@ def copy_to_buildpath(args: PmbArgs, package, chroot: Chroot=Chroot.native()):
|
|||
continue
|
||||
pmb.helpers.run.root(["cp", "-rL", aport / file, build / file])
|
||||
|
||||
pmb.chroot.root(args, ["chown", "-R", "pmos:pmos",
|
||||
pmb.chroot.root(["chown", "-R", "pmos:pmos",
|
||||
"/home/pmos/build"], chroot)
|
||||
|
||||
|
||||
def is_necessary(args: PmbArgs, arch, apkbuild, indexes=None):
|
||||
def is_necessary(arch, apkbuild, indexes=None):
|
||||
"""Check if the package has already been built.
|
||||
|
||||
Compared to abuild's check, this check also works for different architectures.
|
||||
|
@ -61,7 +61,7 @@ def is_necessary(args: PmbArgs, arch, apkbuild, indexes=None):
|
|||
msg = "Build is necessary for package '" + package + "': "
|
||||
|
||||
# Get version from APKINDEX
|
||||
index_data = pmb.parse.apkindex.package(args, package, arch, False,
|
||||
index_data = pmb.parse.apkindex.package(package, arch, False,
|
||||
indexes)
|
||||
if not index_data:
|
||||
logging.debug(msg + "No binary package available")
|
||||
|
@ -101,8 +101,8 @@ def index_repo(args: PmbArgs, arch=None):
|
|||
"""
|
||||
pmb.build.init(args)
|
||||
|
||||
channel = pmb.config.pmaports.read_config(args)["channel"]
|
||||
pkgdir = (pmb.config.work / "packages" / channel)
|
||||
channel = pmb.config.pmaports.read_config()["channel"]
|
||||
pkgdir = (get_context().config.work / "packages" / channel)
|
||||
paths: List[Path] = []
|
||||
if arch:
|
||||
paths = [pkgdir / arch]
|
||||
|
@ -124,55 +124,57 @@ def index_repo(args: PmbArgs, arch=None):
|
|||
["mv", "APKINDEX.tar.gz_", "APKINDEX.tar.gz"]
|
||||
]
|
||||
for command in commands:
|
||||
pmb.chroot.user(args, command, working_dir=path_repo_chroot)
|
||||
pmb.chroot.user(command, working_dir=path_repo_chroot)
|
||||
else:
|
||||
logging.debug(f"NOTE: Can't build index for: {path}")
|
||||
pmb.parse.apkindex.clear_cache(path / "APKINDEX.tar.gz")
|
||||
|
||||
|
||||
def configure_abuild(args: PmbArgs, chroot: Chroot, verify=False):
|
||||
def configure_abuild(chroot: Chroot, verify=False):
|
||||
"""Set the correct JOBS count in ``abuild.conf``.
|
||||
|
||||
:param verify: internally used to test if changing the config has worked.
|
||||
"""
|
||||
jobs = get_context().config.jobs
|
||||
path = chroot / "etc/abuild.conf"
|
||||
prefix = "export JOBS="
|
||||
with path.open(encoding="utf-8") as handle:
|
||||
for line in handle:
|
||||
if not line.startswith(prefix):
|
||||
continue
|
||||
if line != (prefix + args.jobs + "\n"):
|
||||
if line != (prefix + jobs + "\n"):
|
||||
if verify:
|
||||
raise RuntimeError(f"Failed to configure abuild: {path}"
|
||||
"\nTry to delete the file"
|
||||
"(or zap the chroot).")
|
||||
pmb.chroot.root(args, ["sed", "-i", "-e",
|
||||
f"s/^{prefix}.*/{prefix}{args.jobs}/",
|
||||
pmb.chroot.root(["sed", "-i", "-e",
|
||||
f"s/^{prefix}.*/{prefix}{jobs}/",
|
||||
"/etc/abuild.conf"],
|
||||
chroot)
|
||||
configure_abuild(args, chroot, True)
|
||||
configure_abuild(chroot, True)
|
||||
return
|
||||
pmb.chroot.root(args, ["sed", "-i", f"$ a\\{prefix}{args.jobs}", "/etc/abuild.conf"], chroot)
|
||||
pmb.chroot.root(["sed", "-i", f"$ a\\{prefix}{jobs}", "/etc/abuild.conf"], chroot)
|
||||
|
||||
|
||||
def configure_ccache(args: PmbArgs, chroot: Chroot=Chroot.native(), verify=False):
|
||||
def configure_ccache(chroot: Chroot=Chroot.native(), verify=False):
|
||||
"""Set the maximum ccache size.
|
||||
|
||||
:param verify: internally used to test if changing the config has worked.
|
||||
"""
|
||||
# Check if the settings have been set already
|
||||
arch = chroot.arch
|
||||
path = pmb.config.work / f"cache_ccache_{arch}" / "ccache.conf"
|
||||
config = get_context().config
|
||||
path = config.work / f"cache_ccache_{arch}" / "ccache.conf"
|
||||
if os.path.exists(path):
|
||||
with open(path, encoding="utf-8") as handle:
|
||||
for line in handle:
|
||||
if line == ("max_size = " + args.ccache_size + "\n"):
|
||||
if line == ("max_size = " + config.ccache_size + "\n"):
|
||||
return
|
||||
if verify:
|
||||
raise RuntimeError(f"Failed to configure ccache: {path}\nTry to"
|
||||
" delete the file (or zap the chroot).")
|
||||
|
||||
# Set the size and verify
|
||||
pmb.chroot.user(args, ["ccache", "--max-size", args.ccache_size],
|
||||
pmb.chroot.user(["ccache", "--max-size", config.ccache_size],
|
||||
chroot)
|
||||
configure_ccache(args, chroot, True)
|
||||
configure_ccache(chroot, True)
|
||||
|
|
|
@ -8,9 +8,10 @@ from pmb.helpers import logging
|
|||
import shlex
|
||||
from typing import List
|
||||
|
||||
import pmb.build
|
||||
import pmb.chroot
|
||||
import pmb.config
|
||||
from pmb.core.types import PmbArgs
|
||||
from pmb.types import PmbArgs
|
||||
import pmb.helpers.apk
|
||||
import pmb.helpers.other
|
||||
import pmb.helpers.pmaports
|
||||
|
@ -23,7 +24,7 @@ import pmb.parse.version
|
|||
from pmb.core import Chroot, get_context
|
||||
|
||||
|
||||
def update_repository_list(args: PmbArgs, suffix: Chroot, postmarketos_mirror=True,
|
||||
def update_repository_list(suffix: Chroot, postmarketos_mirror=True,
|
||||
check=False):
|
||||
"""
|
||||
Update /etc/apk/repositories, if it is outdated (when the user changed the
|
||||
|
@ -52,7 +53,7 @@ def update_repository_list(args: PmbArgs, suffix: Chroot, postmarketos_mirror=Tr
|
|||
pmb.helpers.run.root(["mkdir", "-p", path.parent])
|
||||
|
||||
# Up to date: Save cache, return
|
||||
lines_new = pmb.helpers.repo.urls(args, postmarketos_mirror=postmarketos_mirror)
|
||||
lines_new = pmb.helpers.repo.urls(postmarketos_mirror=postmarketos_mirror)
|
||||
if lines_old == lines_new:
|
||||
pmb.helpers.other.cache["apk_repository_list_updated"].append(suffix)
|
||||
return
|
||||
|
@ -68,10 +69,10 @@ def update_repository_list(args: PmbArgs, suffix: Chroot, postmarketos_mirror=Tr
|
|||
for line in lines_new:
|
||||
pmb.helpers.run.root(["sh", "-c", "echo "
|
||||
f"{shlex.quote(line)} >> {path}"])
|
||||
update_repository_list(args, suffix, postmarketos_mirror, True)
|
||||
update_repository_list(suffix, postmarketos_mirror, True)
|
||||
|
||||
|
||||
def check_min_version(args: PmbArgs, chroot: Chroot=Chroot.native()):
|
||||
def check_min_version(chroot: Chroot=Chroot.native()):
|
||||
"""
|
||||
Check the minimum apk version, before running it the first time in the
|
||||
current session (lifetime of one pmbootstrap call).
|
||||
|
@ -90,7 +91,7 @@ def check_min_version(args: PmbArgs, chroot: Chroot=Chroot.native()):
|
|||
# Compare
|
||||
version_installed = installed(chroot)["apk-tools"]["version"]
|
||||
pmb.helpers.apk.check_outdated(
|
||||
args, version_installed,
|
||||
version_installed,
|
||||
"Delete your http cache and zap all chroots, then try again:"
|
||||
" 'pmbootstrap zap -hc'")
|
||||
|
||||
|
@ -98,32 +99,6 @@ def check_min_version(args: PmbArgs, chroot: Chroot=Chroot.native()):
|
|||
pmb.helpers.other.cache["apk_min_version_checked"].append(chroot.path)
|
||||
|
||||
|
||||
def install_build(args: PmbArgs, package, arch):
|
||||
"""
|
||||
Build an outdated package unless pmbootstrap was invoked with
|
||||
"pmbootstrap install" and the option to build packages during pmb install
|
||||
is disabled.
|
||||
|
||||
:param package: name of the package to build
|
||||
:param arch: architecture of the package to build
|
||||
"""
|
||||
# User may have disabled building packages during "pmbootstrap install"
|
||||
if args.action == "install" and not args.build_pkgs_on_install:
|
||||
if not pmb.parse.apkindex.package(args, package, arch, False):
|
||||
raise RuntimeError(f"{package}: no binary package found for"
|
||||
f" {arch}, and compiling packages during"
|
||||
" 'pmbootstrap install' has been disabled."
|
||||
" Consider changing this option in"
|
||||
" 'pmbootstrap init'.")
|
||||
# Use the existing binary package
|
||||
return
|
||||
|
||||
# Build the package if it's in pmaports and there is no binary package
|
||||
# with the same pkgver and pkgrel. This check is done in
|
||||
# pmb.build.is_necessary, which gets called in pmb.build.package.
|
||||
return pmb.build.package(args, package, arch)
|
||||
|
||||
|
||||
def packages_split_to_add_del(packages):
|
||||
"""
|
||||
Sort packages into "to_add" and "to_del" lists depending on their pkgname
|
||||
|
@ -145,7 +120,7 @@ def packages_split_to_add_del(packages):
|
|||
return (to_add, to_del)
|
||||
|
||||
|
||||
def packages_get_locally_built_apks(args: PmbArgs, packages, arch: str) -> List[Path]:
|
||||
def packages_get_locally_built_apks(packages, arch: str) -> List[Path]:
|
||||
"""
|
||||
Iterate over packages and if existing, get paths to locally built packages.
|
||||
This is used to force apk to upgrade packages to newer local versions, even
|
||||
|
@ -156,16 +131,16 @@ def packages_get_locally_built_apks(args: PmbArgs, packages, arch: str) -> List[
|
|||
:returns: list of apk file paths that are valid inside the chroots, e.g.
|
||||
["/mnt/pmbootstrap/packages/x86_64/hello-world-1-r6.apk", ...]
|
||||
"""
|
||||
channel: str = pmb.config.pmaports.read_config(args)["channel"]
|
||||
channel: str = pmb.config.pmaports.read_config()["channel"]
|
||||
ret: List[Path] = []
|
||||
|
||||
for package in packages:
|
||||
data_repo = pmb.parse.apkindex.package(args, package, arch, False)
|
||||
data_repo = pmb.parse.apkindex.package(package, arch, False)
|
||||
if not data_repo:
|
||||
continue
|
||||
|
||||
apk_file = f"{package}-{data_repo['version']}.apk"
|
||||
apk_path = pmb.config.work / "packages" / channel / arch / apk_file
|
||||
apk_path = get_context().config.work / "packages" / channel / arch / apk_file
|
||||
if not apk_path.exists():
|
||||
continue
|
||||
|
||||
|
@ -210,7 +185,7 @@ def install_run_apk(to_add, to_add_local, to_del, chroot: Chroot):
|
|||
# it from there.
|
||||
apk_static = Chroot.native() / "sbin/apk.static"
|
||||
arch = chroot.arch
|
||||
apk_cache = pmb.config.work / f"cache_apk_{arch}"
|
||||
apk_cache = get_context().config.work / f"cache_apk_{arch}"
|
||||
|
||||
for (i, command) in enumerate(commands):
|
||||
# --no-interactive is a parameter to `add`, so it must be appended or apk
|
||||
|
@ -233,7 +208,7 @@ def install_run_apk(to_add, to_add_local, to_del, chroot: Chroot):
|
|||
pmb.helpers.run.root([apk_static, "--no-progress"] + command)
|
||||
|
||||
|
||||
def install(args: PmbArgs, packages, chroot: Chroot, build=True):
|
||||
def install(packages, chroot: Chroot, build=True):
|
||||
"""
|
||||
Install packages from pmbootstrap's local package index or the pmOS/Alpine
|
||||
binary package mirrors. Iterate over all dependencies recursively, and
|
||||
|
@ -247,6 +222,7 @@ def install(args: PmbArgs, packages, chroot: Chroot, build=True):
|
|||
repositories, set this to False for performance optimization.
|
||||
"""
|
||||
arch = chroot.arch
|
||||
context = get_context()
|
||||
|
||||
if not packages:
|
||||
logging.verbose("pmb.chroot.apk.install called with empty packages list,"
|
||||
|
@ -254,21 +230,21 @@ def install(args: PmbArgs, packages, chroot: Chroot, build=True):
|
|||
return
|
||||
|
||||
# Initialize chroot
|
||||
check_min_version(args, chroot)
|
||||
check_min_version(chroot)
|
||||
|
||||
installed_pkgs = pmb.chroot.user(["apk", "info", "-e"] + packages, chroot, output_return=True, check=False)
|
||||
if installed_pkgs is not None and installed_pkgs.strip().split("\n") == packages:
|
||||
logging.debug(f"({chroot}) all packages already installed")
|
||||
return
|
||||
|
||||
packages_with_depends = pmb.parse.depends.recurse(args, packages, chroot)
|
||||
packages_with_depends = pmb.parse.depends.recurse(packages, chroot)
|
||||
to_add, to_del = packages_split_to_add_del(packages_with_depends)
|
||||
|
||||
if build:
|
||||
if build and context.config.build_pkgs_on_install:
|
||||
for package in to_add:
|
||||
install_build(args, package, arch)
|
||||
pmb.build.package(context, package, arch)
|
||||
|
||||
to_add_local = packages_get_locally_built_apks(args, to_add, arch)
|
||||
to_add_local = packages_get_locally_built_apks(to_add, arch)
|
||||
to_add_no_deps, _ = packages_split_to_add_del(packages)
|
||||
|
||||
logging.info(f"({chroot}) install {' '.join(to_add_no_deps)}")
|
||||
|
|
|
@ -7,7 +7,7 @@ import tarfile
|
|||
import tempfile
|
||||
import stat
|
||||
|
||||
from pmb.core.types import PmbArgs
|
||||
from pmb.types import PmbArgs
|
||||
import pmb.helpers.apk
|
||||
import pmb.helpers.run
|
||||
import pmb.config
|
||||
|
@ -15,6 +15,7 @@ import pmb.config.load
|
|||
import pmb.parse.apkindex
|
||||
import pmb.helpers.http
|
||||
import pmb.parse.version
|
||||
from pmb.core import get_context
|
||||
|
||||
|
||||
def read_signature_info(tar):
|
||||
|
@ -77,7 +78,7 @@ def extract_temp(tar, sigfilename):
|
|||
return ret
|
||||
|
||||
|
||||
def verify_signature(args: PmbArgs, files, sigkey_path):
|
||||
def verify_signature(files, sigkey_path):
|
||||
"""
|
||||
Verify the signature with openssl.
|
||||
|
||||
|
@ -99,7 +100,7 @@ def verify_signature(args: PmbArgs, files, sigkey_path):
|
|||
" delete the download and try again.")
|
||||
|
||||
|
||||
def extract(args: PmbArgs, version, apk_path):
|
||||
def extract(version, apk_path):
|
||||
"""
|
||||
Extract everything to temporary locations, verify signatures and reported
|
||||
versions. When everything is right, move the extracted apk.static to the
|
||||
|
@ -111,7 +112,7 @@ def extract(args: PmbArgs, version, apk_path):
|
|||
files = extract_temp(tar, sigfilename)
|
||||
|
||||
# Verify signature
|
||||
verify_signature(args, files, sigkey_path)
|
||||
verify_signature(files, sigkey_path)
|
||||
os.unlink(files["sig"]["temp_path"])
|
||||
temp_path = files["apk"]["temp_path"]
|
||||
|
||||
|
@ -131,45 +132,45 @@ def extract(args: PmbArgs, version, apk_path):
|
|||
" and try again.")
|
||||
|
||||
# Move it to the right path
|
||||
target_path = pmb.config.work / "apk.static"
|
||||
target_path = get_context().config.work / "apk.static"
|
||||
shutil.move(temp_path, target_path)
|
||||
|
||||
|
||||
def download(args: PmbArgs, file):
|
||||
def download(file):
|
||||
"""
|
||||
Download a single file from an Alpine mirror.
|
||||
"""
|
||||
channel_cfg = pmb.config.pmaports.read_config_channel(args)
|
||||
channel_cfg = pmb.config.pmaports.read_config_channel()
|
||||
mirrordir = channel_cfg["mirrordir_alpine"]
|
||||
base_url = f"{args.mirror_alpine}{mirrordir}/main/{pmb.config.arch_native}"
|
||||
return pmb.helpers.http.download(args, f"{base_url}/{file}", file)
|
||||
base_url = f"{get_context().config.mirror_alpine}{mirrordir}/main/{pmb.config.arch_native}"
|
||||
return pmb.helpers.http.download(f"{base_url}/{file}", file)
|
||||
|
||||
|
||||
def init(args: PmbArgs):
|
||||
def init():
|
||||
"""
|
||||
Download, verify, extract $WORK/apk.static.
|
||||
"""
|
||||
# Get and parse the APKINDEX
|
||||
apkindex = pmb.helpers.repo.alpine_apkindex_path(args, "main")
|
||||
index_data = pmb.parse.apkindex.package(args, "apk-tools-static",
|
||||
apkindex = pmb.helpers.repo.alpine_apkindex_path("main")
|
||||
index_data = pmb.parse.apkindex.package("apk-tools-static",
|
||||
indexes=[apkindex])
|
||||
version = index_data["version"]
|
||||
|
||||
# Verify the apk-tools-static version
|
||||
pmb.helpers.apk.check_outdated(
|
||||
args, version, "Run 'pmbootstrap update', then try again.")
|
||||
version, "Run 'pmbootstrap update', then try again.")
|
||||
|
||||
# Download, extract, verify apk-tools-static
|
||||
apk_name = f"apk-tools-static-{version}.apk"
|
||||
apk_static = download(args, apk_name)
|
||||
extract(args, version, apk_static)
|
||||
apk_static = download(apk_name)
|
||||
extract(version, apk_static)
|
||||
|
||||
|
||||
def run(args: PmbArgs, parameters):
|
||||
def run(parameters):
|
||||
# --no-interactive is a parameter to `add`, so it must be appended or apk
|
||||
# gets confused
|
||||
parameters += ["--no-interactive"]
|
||||
|
||||
if args.offline:
|
||||
if get_context().offline:
|
||||
parameters = ["--no-network"] + parameters
|
||||
pmb.helpers.apk.apk_with_progress([pmb.config.work / "apk.static"] + parameters)
|
||||
pmb.helpers.apk.apk_with_progress([get_context().config.work / "apk.static"] + parameters)
|
||||
|
|
|
@ -4,31 +4,33 @@ import os
|
|||
from pmb.core.chroot import Chroot
|
||||
from pmb.helpers import logging
|
||||
|
||||
from pmb.core.types import PmbArgs
|
||||
from pmb.types import PmbArgs
|
||||
import pmb.helpers.run
|
||||
import pmb.helpers.other
|
||||
import pmb.parse
|
||||
import pmb.parse.arch
|
||||
import pmb.chroot.apk
|
||||
|
||||
|
||||
def is_registered(arch_qemu):
|
||||
return os.path.exists("/proc/sys/fs/binfmt_misc/qemu-" + arch_qemu)
|
||||
|
||||
|
||||
def register(args: PmbArgs, arch):
|
||||
def register(arch):
|
||||
"""
|
||||
Get arch, magic, mask.
|
||||
"""
|
||||
arch_qemu = pmb.parse.arch.alpine_to_qemu(arch)
|
||||
chroot = Chroot.native()
|
||||
|
||||
# always make sure the qemu-<arch> binary is installed, since registering
|
||||
# may happen outside of this method (e.g. by OS)
|
||||
if f"qemu-{arch_qemu}" not in pmb.chroot.apk.installed(args):
|
||||
pmb.chroot.apk.install(args, ["qemu-" + arch_qemu], Chroot.native())
|
||||
if f"qemu-{arch_qemu}" not in pmb.chroot.apk.installed(chroot):
|
||||
pmb.chroot.apk.install(["qemu-" + arch_qemu], chroot)
|
||||
|
||||
if is_registered(arch_qemu):
|
||||
return
|
||||
pmb.helpers.other.check_binfmt_misc(args)
|
||||
pmb.helpers.other.check_binfmt_misc()
|
||||
|
||||
# Don't continue if the actions from check_binfmt_misc caused the OS to
|
||||
# automatically register the target arch
|
||||
|
|
|
@ -7,15 +7,15 @@ from pmb.helpers import logging
|
|||
import os
|
||||
|
||||
import pmb.chroot
|
||||
import pmb.chroot.binfmt
|
||||
import pmb.chroot.apk_static
|
||||
import pmb.config
|
||||
import pmb.config.workdir
|
||||
from pmb.core.types import PmbArgs
|
||||
import pmb.helpers.repo
|
||||
import pmb.helpers.run
|
||||
import pmb.helpers.other
|
||||
import pmb.parse.arch
|
||||
from pmb.core import Chroot, ChrootType
|
||||
from pmb.core import Chroot, ChrootType, get_context
|
||||
|
||||
cache_chroot_is_outdated: List[str] = []
|
||||
|
||||
|
@ -29,7 +29,7 @@ class UsrMerge(enum.Enum):
|
|||
OFF = 2
|
||||
|
||||
|
||||
def copy_resolv_conf(args: PmbArgs, chroot: Chroot):
|
||||
def copy_resolv_conf(chroot: Chroot):
|
||||
"""
|
||||
Use pythons super fast file compare function (due to caching)
|
||||
and copy the /etc/resolv.conf to the chroot, in case it is
|
||||
|
@ -45,7 +45,7 @@ def copy_resolv_conf(args: PmbArgs, chroot: Chroot):
|
|||
pmb.helpers.run.root(["touch", resolv_path])
|
||||
|
||||
|
||||
def mark_in_chroot(args: PmbArgs, chroot: Chroot=Chroot.native()):
|
||||
def mark_in_chroot(chroot: Chroot=Chroot.native()):
|
||||
"""
|
||||
Touch a flag so we can know when we're running in chroot (and
|
||||
don't accidentally flash partitions on our host). This marker
|
||||
|
@ -56,7 +56,7 @@ def mark_in_chroot(args: PmbArgs, chroot: Chroot=Chroot.native()):
|
|||
pmb.helpers.run.root(["touch", in_chroot_file])
|
||||
|
||||
|
||||
def setup_qemu_emulation(args: PmbArgs, chroot: Chroot):
|
||||
def setup_qemu_emulation(chroot: Chroot):
|
||||
arch = chroot.arch
|
||||
if not pmb.parse.arch.cpu_emulation_required(arch):
|
||||
return
|
||||
|
@ -64,13 +64,13 @@ def setup_qemu_emulation(args: PmbArgs, chroot: Chroot):
|
|||
arch_qemu = pmb.parse.arch.alpine_to_qemu(arch)
|
||||
|
||||
# mount --bind the qemu-user binary
|
||||
pmb.chroot.binfmt.register(args, arch)
|
||||
pmb.chroot.binfmt.register(arch)
|
||||
pmb.helpers.mount.bind_file(Chroot.native() / f"/usr/bin/qemu-{arch_qemu}",
|
||||
chroot / f"usr/bin/qemu-{arch_qemu}-static",
|
||||
create_folders=True)
|
||||
|
||||
|
||||
def init_keys(args: PmbArgs):
|
||||
def init_keys():
|
||||
"""
|
||||
All Alpine and postmarketOS repository keys are shipped with pmbootstrap.
|
||||
Copy them into $WORK/config_apk_keys, which gets mounted inside the various
|
||||
|
@ -81,27 +81,27 @@ def init_keys(args: PmbArgs):
|
|||
not installed yet.
|
||||
"""
|
||||
for key in pmb.config.apk_keys_path.glob("*.pub"):
|
||||
target = pmb.config.work / "config_apk_keys" / key.name
|
||||
target = get_context().config.work / "config_apk_keys" / key.name
|
||||
if not target.exists():
|
||||
# Copy as root, so the resulting files in chroots are owned by root
|
||||
pmb.helpers.run.root(["cp", key, target])
|
||||
|
||||
|
||||
def init_usr_merge(args: PmbArgs, chroot: Chroot):
|
||||
def init_usr_merge(chroot: Chroot):
|
||||
logging.info(f"({chroot}) merge /usr")
|
||||
script = f"{pmb.config.pmb_src}/pmb/data/merge-usr.sh"
|
||||
pmb.helpers.run.root(["sh", "-e", script, "CALLED_FROM_PMB",
|
||||
chroot.path])
|
||||
|
||||
|
||||
def warn_if_chroot_is_outdated(args: PmbArgs, chroot: Chroot):
|
||||
def warn_if_chroot_is_outdated(chroot: Chroot):
|
||||
global cache_chroot_is_outdated
|
||||
|
||||
# Only check / display the warning once per session
|
||||
if str(chroot) in cache_chroot_is_outdated:
|
||||
return
|
||||
|
||||
if pmb.config.workdir.chroots_outdated(args, chroot):
|
||||
if pmb.config.workdir.chroots_outdated(chroot):
|
||||
days_warn = int(pmb.config.chroot_outdated / 3600 / 24)
|
||||
logging.warning(f"WARNING: Your {chroot} chroot is older than"
|
||||
f" {days_warn} days. Consider running"
|
||||
|
@ -110,7 +110,7 @@ def warn_if_chroot_is_outdated(args: PmbArgs, chroot: Chroot):
|
|||
cache_chroot_is_outdated += [str(chroot)]
|
||||
|
||||
|
||||
def init(args: PmbArgs, chroot: Chroot=Chroot.native(), usr_merge=UsrMerge.AUTO,
|
||||
def init(chroot: Chroot=Chroot.native(), usr_merge=UsrMerge.AUTO,
|
||||
postmarketos_mirror=True):
|
||||
"""
|
||||
Initialize a chroot by copying the resolv.conf and updating
|
||||
|
@ -125,61 +125,62 @@ def init(args: PmbArgs, chroot: Chroot=Chroot.native(), usr_merge=UsrMerge.AUTO,
|
|||
# When already initialized: just prepare the chroot
|
||||
arch = chroot.arch
|
||||
|
||||
config = get_context().config
|
||||
already_setup = str(chroot) in pmb.helpers.other.cache["pmb.chroot.init"]
|
||||
if already_setup:
|
||||
logging.warning(f"({chroot}) FIXME! init() called multiple times!")
|
||||
return
|
||||
|
||||
pmb.chroot.mount(args, chroot)
|
||||
setup_qemu_emulation(args, chroot)
|
||||
mark_in_chroot(args, chroot)
|
||||
pmb.chroot.mount(chroot)
|
||||
setup_qemu_emulation(chroot)
|
||||
mark_in_chroot(chroot)
|
||||
if (chroot / "bin/sh").is_symlink():
|
||||
pmb.config.workdir.chroot_check_channel(args, chroot)
|
||||
copy_resolv_conf(args, chroot)
|
||||
pmb.chroot.apk.update_repository_list(args, chroot, postmarketos_mirror)
|
||||
warn_if_chroot_is_outdated(args, chroot)
|
||||
pmb.config.workdir.chroot_check_channel(chroot)
|
||||
copy_resolv_conf(chroot)
|
||||
pmb.chroot.apk.update_repository_list(chroot, postmarketos_mirror)
|
||||
warn_if_chroot_is_outdated(chroot)
|
||||
pmb.helpers.other.cache["pmb.chroot.init"][str(chroot)] = True
|
||||
return
|
||||
|
||||
# Require apk-tools-static
|
||||
pmb.chroot.apk_static.init(args)
|
||||
pmb.chroot.apk_static.init()
|
||||
|
||||
logging.info(f"({chroot}) install alpine-base")
|
||||
|
||||
# Initialize cache
|
||||
apk_cache = pmb.config.work / f"cache_apk_{arch}"
|
||||
apk_cache = config.work / f"cache_apk_{arch}"
|
||||
pmb.helpers.run.root(["ln", "-s", "-f", "/var/cache/apk",
|
||||
chroot / "etc/apk/cache"])
|
||||
|
||||
# Initialize /etc/apk/keys/, resolv.conf, repositories
|
||||
init_keys(args)
|
||||
copy_resolv_conf(args, chroot)
|
||||
pmb.chroot.apk.update_repository_list(args, chroot, postmarketos_mirror)
|
||||
init_keys()
|
||||
copy_resolv_conf(chroot)
|
||||
pmb.chroot.apk.update_repository_list(chroot, postmarketos_mirror)
|
||||
|
||||
pmb.config.workdir.chroot_save_init(args, chroot)
|
||||
pmb.config.workdir.chroot_save_init(chroot)
|
||||
|
||||
# Install alpine-base
|
||||
pmb.helpers.repo.update(args, arch)
|
||||
pmb.helpers.repo.update(arch)
|
||||
pkgs = ["alpine-base"]
|
||||
# install apk static in the native chroot so we can run it
|
||||
# we have a forked apk for systemd and this is the easiest
|
||||
# way to install/run it.
|
||||
if chroot.type == ChrootType.NATIVE:
|
||||
pkgs += ["apk-tools-static"]
|
||||
pmb.chroot.apk_static.run(args, ["--root", chroot.path,
|
||||
pmb.chroot.apk_static.run(["--root", chroot.path,
|
||||
"--cache-dir", apk_cache,
|
||||
"--initdb", "--arch", arch,
|
||||
"add"] + pkgs)
|
||||
|
||||
# Merge /usr
|
||||
if usr_merge is UsrMerge.AUTO and pmb.config.is_systemd_selected(args):
|
||||
if usr_merge is UsrMerge.AUTO and pmb.config.is_systemd_selected(config):
|
||||
usr_merge = UsrMerge.ON
|
||||
if usr_merge is UsrMerge.ON:
|
||||
init_usr_merge(args, chroot)
|
||||
init_usr_merge(chroot)
|
||||
|
||||
# Building chroots: create "pmos" user, add symlinks to /home/pmos
|
||||
if not chroot.type == ChrootType.ROOTFS:
|
||||
pmb.chroot.root(args, ["adduser", "-D", "pmos", "-u",
|
||||
pmb.chroot.root(["adduser", "-D", "pmos", "-u",
|
||||
pmb.config.chroot_uid_user],
|
||||
chroot)
|
||||
|
||||
|
@ -187,11 +188,11 @@ def init(args: PmbArgs, chroot: Chroot=Chroot.native(), usr_merge=UsrMerge.AUTO,
|
|||
for target, link_name in pmb.config.chroot_home_symlinks.items():
|
||||
link_dir = os.path.dirname(link_name)
|
||||
if not os.path.exists(chroot / link_dir):
|
||||
pmb.chroot.user(args, ["mkdir", "-p", link_dir], chroot)
|
||||
pmb.chroot.user(["mkdir", "-p", link_dir], chroot)
|
||||
if not os.path.exists(chroot / target):
|
||||
pmb.chroot.root(args, ["mkdir", "-p", target], chroot)
|
||||
pmb.chroot.user(args, ["ln", "-s", target, link_name], chroot)
|
||||
pmb.chroot.root(args, ["chown", "pmos:pmos", target], chroot)
|
||||
pmb.chroot.root(["mkdir", "-p", target], chroot)
|
||||
pmb.chroot.user(["ln", "-s", target, link_name], chroot)
|
||||
pmb.chroot.root(["chown", "pmos:pmos", target], chroot)
|
||||
|
||||
# Upgrade packages in the chroot, in case alpine-base, apk, etc. have been
|
||||
# built from source with pmbootstrap
|
||||
|
@ -201,6 +202,6 @@ def init(args: PmbArgs, chroot: Chroot=Chroot.native(), usr_merge=UsrMerge.AUTO,
|
|||
if os.getenv("PMB_APK_FORCE_MISSING_REPOSITORIES") == "1":
|
||||
command = ["--force-missing-repositories"] + command
|
||||
|
||||
pmb.chroot.root(args, ["apk"] + command, chroot)
|
||||
pmb.chroot.root(["apk"] + command, chroot)
|
||||
|
||||
pmb.helpers.other.cache["pmb.chroot.init"][str(chroot)]
|
||||
pmb.helpers.other.cache["pmb.chroot.init"][str(chroot)] = True
|
||||
|
|
|
@ -6,26 +6,26 @@ import pmb.chroot.initfs_hooks
|
|||
import pmb.chroot.other
|
||||
import pmb.chroot.apk
|
||||
import pmb.config.pmaports
|
||||
from pmb.core.types import PmbArgs
|
||||
from pmb.types import PmbArgs
|
||||
import pmb.helpers.cli
|
||||
from pmb.core import Chroot
|
||||
|
||||
|
||||
def build(args: PmbArgs, flavor, chroot: Chroot):
|
||||
# Update mkinitfs and hooks
|
||||
pmb.chroot.apk.install(args, ["postmarketos-mkinitfs"], chroot)
|
||||
pmb.chroot.apk.install(["postmarketos-mkinitfs"], chroot)
|
||||
pmb.chroot.initfs_hooks.update(args, chroot)
|
||||
pmaports_cfg = pmb.config.pmaports.read_config(args)
|
||||
pmaports_cfg = pmb.config.pmaports.read_config()
|
||||
|
||||
# Call mkinitfs
|
||||
logging.info(f"({chroot}) mkinitfs {flavor}")
|
||||
if pmaports_cfg.get("supported_mkinitfs_without_flavors", False):
|
||||
pmb.chroot.root(args, ["mkinitfs"], chroot)
|
||||
pmb.chroot.root(["mkinitfs"], chroot)
|
||||
else:
|
||||
release_file = (chroot / "usr/share/kernel" / flavor / "kernel.release")
|
||||
with release_file.open() as handle:
|
||||
release = handle.read().rstrip()
|
||||
pmb.chroot.root(args, ["mkinitfs", "-o",
|
||||
pmb.chroot.root(["mkinitfs", "-o",
|
||||
f"/boot/initramfs-{flavor}", release],
|
||||
chroot)
|
||||
|
||||
|
@ -38,7 +38,7 @@ def extract(args: PmbArgs, flavor, chroot: Chroot, extra=False):
|
|||
# Extraction folder
|
||||
inside = "/tmp/initfs-extracted"
|
||||
|
||||
pmaports_cfg = pmb.config.pmaports.read_config(args)
|
||||
pmaports_cfg = pmb.config.pmaports.read_config()
|
||||
if pmaports_cfg.get("supported_mkinitfs_without_flavors", False):
|
||||
initfs_file = "/boot/initramfs"
|
||||
else:
|
||||
|
@ -53,7 +53,7 @@ def extract(args: PmbArgs, flavor, chroot: Chroot, extra=False):
|
|||
" already exists."
|
||||
" Do you want to overwrite it?"):
|
||||
raise RuntimeError("Aborted!")
|
||||
pmb.chroot.root(args, ["rm", "-r", inside], chroot)
|
||||
pmb.chroot.root(["rm", "-r", inside], chroot)
|
||||
|
||||
# Extraction script (because passing a file to stdin is not allowed
|
||||
# in pmbootstrap's chroot/shell functions for security reasons)
|
||||
|
@ -71,7 +71,7 @@ def extract(args: PmbArgs, flavor, chroot: Chroot, extra=False):
|
|||
["rm", "/tmp/_extract.sh", f"{inside}/_initfs"]
|
||||
]
|
||||
for command in commands:
|
||||
pmb.chroot.root(args, command, chroot)
|
||||
pmb.chroot.root(command, chroot)
|
||||
|
||||
# Return outside path for logging
|
||||
return outside
|
||||
|
@ -82,8 +82,8 @@ def ls(args: PmbArgs, flavor, suffix, extra=False):
|
|||
if extra:
|
||||
tmp = "/tmp/initfs-extra-extracted"
|
||||
extract(args, flavor, suffix, extra)
|
||||
pmb.chroot.root(args, ["ls", "-lahR", "."], suffix, Path(tmp), "stdout")
|
||||
pmb.chroot.root(args, ["rm", "-r", tmp], suffix)
|
||||
pmb.chroot.root(["ls", "-lahR", "."], suffix, Path(tmp), "stdout")
|
||||
pmb.chroot.root(["rm", "-r", tmp], suffix)
|
||||
|
||||
|
||||
def frontend(args: PmbArgs):
|
||||
|
@ -108,12 +108,12 @@ def frontend(args: PmbArgs):
|
|||
|
||||
# Handle hook actions
|
||||
elif action == "hook_ls":
|
||||
pmb.chroot.initfs_hooks.ls(args, chroot)
|
||||
pmb.chroot.initfs_hooks.ls(chroot)
|
||||
else:
|
||||
if action == "hook_add":
|
||||
pmb.chroot.initfs_hooks.add(args, args.hook, chroot)
|
||||
pmb.chroot.initfs_hooks.add(args.hook, chroot)
|
||||
elif action == "hook_del":
|
||||
pmb.chroot.initfs_hooks.delete(args, args.hook, chroot)
|
||||
pmb.chroot.initfs_hooks.delete(args.hook, chroot)
|
||||
|
||||
# Rebuild the initfs after adding/removing a hook
|
||||
build(args, flavor, chroot)
|
||||
|
|
|
@ -6,11 +6,11 @@ from pmb.helpers import logging
|
|||
|
||||
import pmb.config
|
||||
import pmb.chroot.apk
|
||||
from pmb.core import Chroot
|
||||
from pmb.core.types import PmbArgs
|
||||
from pmb.core import Chroot, get_context
|
||||
from pmb.types import PmbArgs
|
||||
|
||||
|
||||
def list_chroot(args: PmbArgs, suffix: Chroot, remove_prefix=True):
|
||||
def list_chroot(suffix: Chroot, remove_prefix=True):
|
||||
ret = []
|
||||
prefix = pmb.config.initfs_hook_prefix
|
||||
for pkgname in pmb.chroot.apk.installed(suffix).keys():
|
||||
|
@ -22,41 +22,41 @@ def list_chroot(args: PmbArgs, suffix: Chroot, remove_prefix=True):
|
|||
return ret
|
||||
|
||||
|
||||
def list_aports(args: PmbArgs):
|
||||
def list_aports():
|
||||
ret = []
|
||||
prefix = pmb.config.initfs_hook_prefix
|
||||
for path in glob.glob(f"{args.aports}/*/{prefix}*"):
|
||||
for path in glob.glob(f"{get_context().config.aports}/*/{prefix}*"):
|
||||
ret.append(os.path.basename(path)[len(prefix):])
|
||||
return ret
|
||||
|
||||
|
||||
def ls(args: PmbArgs, suffix: Chroot):
|
||||
hooks_chroot = list_chroot(args, suffix)
|
||||
hooks_aports = list_aports(args)
|
||||
def ls(suffix: Chroot):
|
||||
hooks_chroot = list_chroot(suffix)
|
||||
hooks_aports = list_aports()
|
||||
|
||||
for hook in hooks_aports:
|
||||
line = f"* {hook} ({'' if hook in hooks_chroot else 'not '}installed)"
|
||||
logging.info(line)
|
||||
|
||||
|
||||
def add(args: PmbArgs, hook, suffix: Chroot):
|
||||
if hook not in list_aports(args):
|
||||
def add(hook, suffix: Chroot):
|
||||
if hook not in list_aports():
|
||||
raise RuntimeError("Invalid hook name!"
|
||||
" Run 'pmbootstrap initfs hook_ls'"
|
||||
" to get a list of all hooks.")
|
||||
prefix = pmb.config.initfs_hook_prefix
|
||||
pmb.chroot.apk.install(args, [f"{prefix}{hook}"], suffix)
|
||||
pmb.chroot.apk.install([f"{prefix}{hook}"], suffix)
|
||||
|
||||
|
||||
def delete(args: PmbArgs, hook, suffix: Chroot):
|
||||
if hook not in list_chroot(args, suffix):
|
||||
def delete(hook, suffix: Chroot):
|
||||
if hook not in list_chroot(suffix):
|
||||
raise RuntimeError("There is no such hook installed!")
|
||||
prefix = pmb.config.initfs_hook_prefix
|
||||
pmb.chroot.root(args, ["apk", "del", f"{prefix}{hook}"], suffix)
|
||||
pmb.chroot.root(["apk", "del", f"{prefix}{hook}"], suffix)
|
||||
|
||||
|
||||
def update(args: PmbArgs, suffix: Chroot):
|
||||
"""
|
||||
Rebuild and update all hooks that are out of date
|
||||
"""
|
||||
pmb.chroot.apk.install(args, list_chroot(args, suffix, False), suffix)
|
||||
pmb.chroot.apk.install(list_chroot(suffix, False), suffix)
|
||||
|
|
|
@ -5,13 +5,14 @@ import os
|
|||
from pathlib import Path
|
||||
from typing import Dict
|
||||
import pmb.config
|
||||
from pmb.core.types import PmbArgs
|
||||
from pmb.types import PmbArgs
|
||||
import pmb.helpers.run
|
||||
import pmb.parse
|
||||
import pmb.helpers.mount
|
||||
from pmb.core import Chroot
|
||||
from pmb.core import Chroot, get_context
|
||||
|
||||
|
||||
def create_device_nodes(args: PmbArgs, chroot: Chroot):
|
||||
def create_device_nodes(chroot: Chroot):
|
||||
"""
|
||||
Create device nodes for null, zero, full, random, urandom in the chroot.
|
||||
"""
|
||||
|
@ -48,7 +49,7 @@ def create_device_nodes(args: PmbArgs, chroot: Chroot):
|
|||
raise RuntimeError(f"Failed to create device nodes in the '{chroot}' chroot.")
|
||||
|
||||
|
||||
def mount_dev_tmpfs(args: PmbArgs, chroot: Chroot=Chroot.native()):
|
||||
def mount_dev_tmpfs(chroot: Chroot=Chroot.native()):
|
||||
"""
|
||||
Mount tmpfs inside the chroot's dev folder to make sure we can create
|
||||
device nodes, even if the filesystem of the work folder does not support
|
||||
|
@ -70,22 +71,22 @@ def mount_dev_tmpfs(args: PmbArgs, chroot: Chroot=Chroot.native()):
|
|||
pmb.helpers.run.root(["mount", "-t", "tmpfs",
|
||||
"-o", "nodev,nosuid,noexec",
|
||||
"tmpfs", dev / "shm"])
|
||||
create_device_nodes(args, chroot)
|
||||
create_device_nodes(chroot)
|
||||
|
||||
# Setup /dev/fd as a symlink
|
||||
pmb.helpers.run.root(["ln", "-sf", "/proc/self/fd", f"{dev}/"])
|
||||
|
||||
|
||||
def mount(args: PmbArgs, chroot: Chroot=Chroot.native()):
|
||||
def mount(chroot: Chroot):
|
||||
# Mount tmpfs as the chroot's /dev
|
||||
mount_dev_tmpfs(args, chroot)
|
||||
mount_dev_tmpfs(chroot)
|
||||
|
||||
# Get all mountpoints
|
||||
arch = pmb.parse.arch.from_chroot_suffix(args, chroot)
|
||||
channel = pmb.config.pmaports.read_config(args)["channel"]
|
||||
arch = chroot.arch
|
||||
channel = pmb.config.pmaports.read_config()["channel"]
|
||||
mountpoints: Dict[Path, Path] = {}
|
||||
for src_template, target_template in pmb.config.chroot_mount_bind.items():
|
||||
src_template = src_template.replace("$WORK", os.fspath(pmb.config.work))
|
||||
src_template = src_template.replace("$WORK", os.fspath(get_context().config.work))
|
||||
src_template = src_template.replace("$ARCH", arch)
|
||||
src_template = src_template.replace("$CHANNEL", channel)
|
||||
mountpoints[Path(src_template)] = Path(target_template)
|
||||
|
|
|
@ -4,7 +4,7 @@ import os
|
|||
from pmb.helpers import logging
|
||||
from pathlib import Path
|
||||
import pmb.chroot.apk
|
||||
from pmb.core.types import PmbArgs
|
||||
from pmb.types import PmbArgs
|
||||
import pmb.install
|
||||
from pmb.core import Chroot
|
||||
|
||||
|
@ -24,7 +24,7 @@ def kernel_flavor_installed(args: PmbArgs, chroot: Chroot, autoinstall=True):
|
|||
if autoinstall:
|
||||
packages = ([f"device-{args.device}"] +
|
||||
pmb.install.get_kernel_package(args, args.device))
|
||||
pmb.chroot.apk.install(args, packages, chroot)
|
||||
pmb.chroot.apk.install(packages, chroot)
|
||||
|
||||
glob_result = list((chroot / "usr/share/kernel").glob("*"))
|
||||
|
||||
|
@ -41,8 +41,8 @@ def tempfolder(args: PmbArgs, path: Path, chroot: Chroot=Chroot.native()):
|
|||
:returns: the path
|
||||
"""
|
||||
if chroot / path:
|
||||
pmb.chroot.root(args, ["rm", "-r", path])
|
||||
pmb.chroot.user(args, ["mkdir", "-p", path])
|
||||
pmb.chroot.root(["rm", "-r", path])
|
||||
pmb.chroot.user(["mkdir", "-p", path])
|
||||
return path
|
||||
|
||||
|
||||
|
@ -73,4 +73,4 @@ def copy_xauthority(args: PmbArgs):
|
|||
if os.path.exists(copy):
|
||||
pmb.helpers.run.root(["rm", copy])
|
||||
pmb.helpers.run.root(["cp", original, copy])
|
||||
pmb.chroot.root(args, ["chown", "pmos:pmos", "/home/pmos/.Xauthority"])
|
||||
pmb.chroot.root(["chown", "pmos:pmos", "/home/pmos/.Xauthority"])
|
||||
|
|
|
@ -11,7 +11,7 @@ import pmb.chroot.binfmt
|
|||
import pmb.helpers.run
|
||||
import pmb.helpers.run_core
|
||||
from pmb.core import Chroot
|
||||
from pmb.core.types import Env, PathString, PmbArgs
|
||||
from pmb.types import Env, PathString, PmbArgs
|
||||
|
||||
|
||||
def executables_absolute_path():
|
||||
|
@ -29,7 +29,7 @@ def executables_absolute_path():
|
|||
return ret
|
||||
|
||||
|
||||
def root(args: PmbArgs, cmd: Sequence[PathString], chroot: Chroot=Chroot.native(), working_dir: PurePath=PurePath("/"), output="log",
|
||||
def root(cmd: Sequence[PathString], chroot: Chroot=Chroot.native(), working_dir: PurePath=PurePath("/"), output="log",
|
||||
output_return=False, check=None, env={},
|
||||
disable_timeout=False, add_proxy_env_vars=True):
|
||||
"""
|
||||
|
@ -88,7 +88,7 @@ def root(args: PmbArgs, cmd: Sequence[PathString], chroot: Chroot=Chroot.native(
|
|||
disable_timeout)
|
||||
|
||||
|
||||
def user(args: PmbArgs, cmd, chroot: Chroot=Chroot.native(), working_dir: Path = Path("/"), output="log",
|
||||
def user(cmd, chroot: Chroot=Chroot.native(), working_dir: Path = Path("/"), output="log",
|
||||
output_return=False, check=None, env={}):
|
||||
"""
|
||||
Run a command inside a chroot as "user". We always use the BusyBox
|
||||
|
@ -109,19 +109,19 @@ def user(args: PmbArgs, cmd, chroot: Chroot=Chroot.native(), working_dir: Path =
|
|||
|
||||
flat_cmd = pmb.helpers.run_core.flat_cmd(cmd, env=env)
|
||||
cmd = ["busybox", "su", "pmos", "-c", flat_cmd]
|
||||
return pmb.chroot.root(args, cmd, chroot, working_dir, output,
|
||||
return pmb.chroot.root(cmd, chroot, working_dir, output,
|
||||
output_return, check, {},
|
||||
add_proxy_env_vars=False)
|
||||
|
||||
|
||||
def exists(args: PmbArgs, username, chroot: Chroot=Chroot.native()):
|
||||
def exists(username, chroot: Chroot=Chroot.native()):
|
||||
"""
|
||||
Checks if username exists in the system
|
||||
|
||||
:param username: User name
|
||||
:returns: bool
|
||||
"""
|
||||
output = pmb.chroot.root(args, ["getent", "passwd", username],
|
||||
output = pmb.chroot.root(["getent", "passwd", username],
|
||||
chroot, output_return=True, check=False)
|
||||
return len(output) > 0
|
||||
|
||||
|
|
|
@ -5,24 +5,24 @@ import socket
|
|||
from contextlib import closing
|
||||
|
||||
import pmb.chroot
|
||||
from pmb.core.types import PmbArgs
|
||||
from pmb.types import PmbArgs
|
||||
import pmb.helpers.mount
|
||||
import pmb.install.losetup
|
||||
import pmb.parse.arch
|
||||
from pmb.core import Chroot, ChrootType
|
||||
from pmb.core import Chroot, ChrootType, get_context
|
||||
|
||||
|
||||
def kill_adb(args: PmbArgs):
|
||||
def kill_adb():
|
||||
"""
|
||||
Kill adb daemon if it's running.
|
||||
"""
|
||||
port = 5038
|
||||
with closing(socket.socket(socket.AF_INET, socket.SOCK_STREAM)) as sock:
|
||||
if sock.connect_ex(("127.0.0.1", port)) == 0:
|
||||
pmb.chroot.root(args, ["adb", "-P", str(port), "kill-server"])
|
||||
pmb.chroot.root(["adb", "-P", str(port), "kill-server"])
|
||||
|
||||
|
||||
def kill_sccache(args: PmbArgs):
|
||||
def kill_sccache():
|
||||
"""
|
||||
Kill sccache daemon if it's running. Unlike ccache it automatically spawns
|
||||
a daemon when you call it and exits after some time of inactivity.
|
||||
|
@ -30,17 +30,17 @@ def kill_sccache(args: PmbArgs):
|
|||
port = 4226
|
||||
with closing(socket.socket(socket.AF_INET, socket.SOCK_STREAM)) as sock:
|
||||
if sock.connect_ex(("127.0.0.1", port)) == 0:
|
||||
pmb.chroot.root(args, ["sccache", "--stop-server"])
|
||||
pmb.chroot.root(["sccache", "--stop-server"])
|
||||
|
||||
|
||||
def shutdown_cryptsetup_device(args: PmbArgs, name: str):
|
||||
def shutdown_cryptsetup_device(name: str):
|
||||
"""
|
||||
:param name: cryptsetup device name, usually "pm_crypt" in pmbootstrap
|
||||
"""
|
||||
if not (Chroot.native() / "dev/mapper" / name).exists():
|
||||
return
|
||||
pmb.chroot.apk.install(args, ["cryptsetup"])
|
||||
status = pmb.chroot.root(args, ["cryptsetup", "status", name],
|
||||
pmb.chroot.apk.install(["cryptsetup"], Chroot.native())
|
||||
status = pmb.chroot.root(["cryptsetup", "status", name],
|
||||
output_return=True, check=False)
|
||||
if not status:
|
||||
logging.warning("WARNING: Failed to run cryptsetup to get the status"
|
||||
|
@ -49,31 +49,31 @@ def shutdown_cryptsetup_device(args: PmbArgs, name: str):
|
|||
return
|
||||
|
||||
if status.startswith("/dev/mapper/" + name + " is active."):
|
||||
pmb.chroot.root(args, ["cryptsetup", "luksClose", name])
|
||||
pmb.chroot.root(["cryptsetup", "luksClose", name])
|
||||
elif status.startswith("/dev/mapper/" + name + " is inactive."):
|
||||
# When "cryptsetup status" fails, the device is not mounted and we
|
||||
# have a left over file (#83)
|
||||
pmb.chroot.root(args, ["rm", "/dev/mapper/" + name])
|
||||
pmb.chroot.root(["rm", "/dev/mapper/" + name])
|
||||
else:
|
||||
raise RuntimeError("Failed to parse 'cryptsetup status' output!")
|
||||
|
||||
|
||||
def shutdown(args: PmbArgs, only_install_related=False):
|
||||
# Stop daemons
|
||||
kill_adb(args)
|
||||
kill_sccache(args)
|
||||
kill_adb()
|
||||
kill_sccache()
|
||||
|
||||
chroot = Chroot.native()
|
||||
|
||||
# Umount installation-related paths (order is important!)
|
||||
pmb.helpers.mount.umount_all(chroot / "mnt/install")
|
||||
shutdown_cryptsetup_device(args, "pm_crypt")
|
||||
shutdown_cryptsetup_device("pm_crypt")
|
||||
|
||||
# Umount all losetup mounted images
|
||||
if pmb.helpers.mount.ismount(chroot / "dev/loop-control"):
|
||||
for path_outside in (chroot / "/home/pmos/rootfs").glob("*.img"):
|
||||
path = path_outside.relative_to(chroot.path)
|
||||
pmb.install.losetup.umount(args, path)
|
||||
pmb.install.losetup.umount(path)
|
||||
|
||||
# Umount device rootfs and installer chroots
|
||||
for chroot_type in [ChrootType.ROOTFS, ChrootType.INSTALLER]:
|
||||
|
@ -86,14 +86,14 @@ def shutdown(args: PmbArgs, only_install_related=False):
|
|||
# the chroots, but we want it gone afterwards (e.g. when the chroot
|
||||
# contents get copied to a rootfs / installer image, or if creating an
|
||||
# android recovery zip from its contents).
|
||||
for marker in pmb.config.work.glob("chroot_*/in-pmbootstrap"):
|
||||
for marker in get_context().config.work.glob("chroot_*/in-pmbootstrap"):
|
||||
pmb.helpers.run.root(["rm", marker])
|
||||
|
||||
if not only_install_related:
|
||||
# Umount all folders inside work dir
|
||||
# The folders are explicitly iterated over, so folders symlinked inside
|
||||
# work dir get umounted as well (used in test_pkgrel_bump.py, #1595)
|
||||
for path in pmb.config.work.glob("*"):
|
||||
for path in get_context().config.work.glob("*"):
|
||||
pmb.helpers.mount.umount_all(path)
|
||||
|
||||
# Clean up the rest
|
||||
|
|
|
@ -7,11 +7,11 @@ import os
|
|||
import pmb.chroot
|
||||
import pmb.config.pmaports
|
||||
import pmb.config.workdir
|
||||
from pmb.core.types import PmbArgs
|
||||
from pmb.types import PmbArgs
|
||||
import pmb.helpers.pmaports
|
||||
import pmb.helpers.run
|
||||
import pmb.parse.apkindex
|
||||
from pmb.core import Chroot
|
||||
from pmb.core import Chroot, get_context
|
||||
|
||||
|
||||
def zap(args: PmbArgs, confirm=True, dry=False, pkgs_local=False, http=False,
|
||||
|
@ -32,7 +32,7 @@ def zap(args: PmbArgs, confirm=True, dry=False, pkgs_local=False, http=False,
|
|||
:param rust: Remove rust related caches
|
||||
:param netboot: Remove images for netboot
|
||||
|
||||
NOTE: This function gets called in pmb/config/init.py, with only pmb.config.work
|
||||
NOTE: This function gets called in pmb/config/init.py, with only get_context().config.work
|
||||
and args.device set!
|
||||
"""
|
||||
# Get current work folder size
|
||||
|
@ -50,7 +50,7 @@ def zap(args: PmbArgs, confirm=True, dry=False, pkgs_local=False, http=False,
|
|||
|
||||
pmb.chroot.shutdown(args)
|
||||
|
||||
# Deletion patterns for folders inside pmb.config.work
|
||||
# Deletion patterns for folders inside get_context().config.work
|
||||
patterns = list(Chroot.iter_patterns())
|
||||
if pkgs_local:
|
||||
patterns += ["packages"]
|
||||
|
@ -66,7 +66,7 @@ def zap(args: PmbArgs, confirm=True, dry=False, pkgs_local=False, http=False,
|
|||
# Delete everything matching the patterns
|
||||
for pattern in patterns:
|
||||
logging.debug(f"Deleting {pattern}")
|
||||
pattern = os.path.realpath(f"{pmb.config.work}/{pattern}")
|
||||
pattern = os.path.realpath(f"{get_context().config.work}/{pattern}")
|
||||
matches = glob.glob(pattern)
|
||||
for match in matches:
|
||||
if (not confirm or
|
||||
|
@ -87,8 +87,8 @@ def zap(args: PmbArgs, confirm=True, dry=False, pkgs_local=False, http=False,
|
|||
|
||||
|
||||
def zap_pkgs_local_mismatch(args: PmbArgs, confirm=True, dry=False):
|
||||
channel = pmb.config.pmaports.read_config(args)["channel"]
|
||||
if not os.path.exists(f"{pmb.config.work}/packages/{channel}"):
|
||||
channel = pmb.config.pmaports.read_config()["channel"]
|
||||
if not os.path.exists(f"{get_context().config.work}/packages/{channel}"):
|
||||
return
|
||||
|
||||
question = "Remove binary packages that are newer than the corresponding" \
|
||||
|
@ -97,7 +97,7 @@ def zap_pkgs_local_mismatch(args: PmbArgs, confirm=True, dry=False):
|
|||
return
|
||||
|
||||
reindex = False
|
||||
for apkindex_path in (pmb.config.work / "packages" / channel).glob("*/APKINDEX.tar.gz"):
|
||||
for apkindex_path in (get_context().config.work / "packages" / channel).glob("*/APKINDEX.tar.gz"):
|
||||
# Delete packages without same version in aports
|
||||
blocks = pmb.parse.apkindex.parse_blocks(apkindex_path)
|
||||
for block in blocks:
|
||||
|
@ -108,7 +108,7 @@ def zap_pkgs_local_mismatch(args: PmbArgs, confirm=True, dry=False):
|
|||
|
||||
# Apk path
|
||||
apk_path_short = f"{arch}/{pkgname}-{version}.apk"
|
||||
apk_path = f"{pmb.config.work}/packages/{channel}/{apk_path_short}"
|
||||
apk_path = f"{get_context().config.work}/packages/{channel}/{apk_path_short}"
|
||||
if not os.path.exists(apk_path):
|
||||
logging.info("WARNING: Package mentioned in index not"
|
||||
f" found: {apk_path_short}")
|
||||
|
@ -140,7 +140,7 @@ def zap_pkgs_local_mismatch(args: PmbArgs, confirm=True, dry=False):
|
|||
|
||||
def zap_pkgs_online_mismatch(args: PmbArgs, confirm=True, dry=False):
|
||||
# Check whether we need to do anything
|
||||
paths = glob.glob(f"{pmb.config.work}/cache_apk_*")
|
||||
paths = glob.glob(f"{get_context().config.work}/cache_apk_*")
|
||||
if not len(paths):
|
||||
return
|
||||
if (confirm and not pmb.helpers.cli.confirm(args,
|
||||
|
@ -162,4 +162,4 @@ def zap_pkgs_online_mismatch(args: PmbArgs, confirm=True, dry=False):
|
|||
# Clean the cache with apk
|
||||
logging.info(f"({suffix}) apk -v cache clean")
|
||||
if not dry:
|
||||
pmb.chroot.root(args, ["apk", "-v", "cache", "clean"], suffix)
|
||||
pmb.chroot.root(["apk", "-v", "cache", "clean"], suffix)
|
||||
|
|
|
@ -6,7 +6,7 @@ from pmb.helpers import logging
|
|||
import os
|
||||
from pathlib import Path
|
||||
import pmb.chroot
|
||||
from pmb.core.types import PmbArgs
|
||||
from pmb.types import PmbArgs
|
||||
import pmb.helpers.cli
|
||||
from pmb.core import Chroot
|
||||
|
||||
|
@ -135,9 +135,9 @@ def copy_git_repo_to_chroot(args: PmbArgs, topdir):
|
|||
f"{tarball_path}.files"], topdir)
|
||||
|
||||
ci_dir = Path("/home/pmos/ci")
|
||||
pmb.chroot.user(args, ["rm", "-rf", ci_dir])
|
||||
pmb.chroot.user(args, ["mkdir", ci_dir])
|
||||
pmb.chroot.user(args, ["tar", "-xf", "/tmp/git.tar.gz"],
|
||||
pmb.chroot.user(["rm", "-rf", ci_dir])
|
||||
pmb.chroot.user(["mkdir", ci_dir])
|
||||
pmb.chroot.user(["tar", "-xf", "/tmp/git.tar.gz"],
|
||||
working_dir=ci_dir)
|
||||
|
||||
|
||||
|
@ -178,7 +178,7 @@ def run_scripts(args: PmbArgs, topdir, scripts):
|
|||
repo_copied = True
|
||||
|
||||
env = {"TESTUSER": "pmos"}
|
||||
rc = pmb.chroot.root(args, [script_path], check=False, env=env,
|
||||
rc = pmb.chroot.root([script_path], check=False, env=env,
|
||||
working_dir=Path("/home/pmos/ci"),
|
||||
output="tui")
|
||||
if rc:
|
||||
|
|
|
@ -6,7 +6,7 @@ import enum
|
|||
from typing import Generator, Optional
|
||||
from pathlib import Path, PosixPath, PurePosixPath
|
||||
import pmb.config
|
||||
from pmb.core.types import PmbArgs
|
||||
from pmb.types import PmbArgs
|
||||
from pmb.helpers import frontend
|
||||
|
||||
from .base import Command
|
||||
|
|
|
@ -5,7 +5,7 @@ from __future__ import annotations
|
|||
from typing import Generator, List, Optional
|
||||
from pathlib import Path, PosixPath, PurePosixPath
|
||||
from pmb import commands
|
||||
from pmb.core.types import PathString
|
||||
from pmb.types import PathString
|
||||
from pmb.helpers import run
|
||||
from pmb.core import get_context
|
||||
from pmb import config
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
import multiprocessing
|
||||
import os
|
||||
from pathlib import Path
|
||||
from pmb.core.types import AportGenEntry, PathString
|
||||
from pmb.types import AportGenEntry, PathString
|
||||
import pmb.parse.arch
|
||||
import sys
|
||||
from typing import Dict, List, Sequence, TypedDict
|
||||
|
@ -14,7 +14,6 @@ from typing import Dict, List, Sequence, TypedDict
|
|||
# FIXME (#2324): this sucks, we should re-organise this and not rely on "lifting"
|
||||
# this functions this way
|
||||
from pmb.config.load import load, sanity_checks, save
|
||||
from pmb.config.merge_with_args import merge_with_args
|
||||
from pmb.config.sudo import which_sudo
|
||||
from pmb.config.other import is_systemd_selected
|
||||
|
||||
|
@ -25,7 +24,6 @@ from pmb.config.other import is_systemd_selected
|
|||
pmb_src: Path = Path(Path(__file__) / "../../..").resolve()
|
||||
apk_keys_path: Path = (pmb_src / "pmb/data/keys")
|
||||
arch_native = pmb.parse.arch.alpine_native()
|
||||
work: Path
|
||||
|
||||
# apk-tools minimum version
|
||||
# https://pkgs.alpinelinux.org/packages?name=apk-tools&branch=edge
|
||||
|
@ -77,15 +75,6 @@ def sudo(cmd: Sequence[PathString]) -> Sequence[PathString]:
|
|||
return cmd
|
||||
|
||||
|
||||
def work_dir(_work: Path) -> None:
|
||||
"""Set the work directory. This is used in the main program to set the
|
||||
work directory before any other code is run. It is not meant to be used
|
||||
anywhere else."""
|
||||
global work
|
||||
if "work" in globals():
|
||||
raise RuntimeError("work_dir() called multiple times!")
|
||||
work = _work
|
||||
|
||||
# Keys saved in the config file (mostly what we ask in 'pmbootstrap init')
|
||||
config_keys = [
|
||||
"aports",
|
||||
|
@ -116,42 +105,7 @@ config_keys = [
|
|||
"work",
|
||||
]
|
||||
|
||||
# Config file/commandline default values
|
||||
# $WORK gets replaced with the actual value for pmb.config.work (which may be
|
||||
# overridden on the commandline)
|
||||
defaults = {
|
||||
# This first chunk matches config_keys
|
||||
"aports": "$WORK/cache_git/pmaports",
|
||||
"boot_size": "256",
|
||||
"build_default_device_arch": False,
|
||||
"build_pkgs_on_install": True,
|
||||
"ccache_size": "5G",
|
||||
"device": "qemu-amd64",
|
||||
"extra_packages": "none",
|
||||
"extra_space": "0",
|
||||
"hostname": "",
|
||||
"is_default_channel": True,
|
||||
"jobs": str(multiprocessing.cpu_count() + 1),
|
||||
"kernel": "stable",
|
||||
"keymap": "",
|
||||
"locale": "en_US.UTF-8",
|
||||
# NOTE: mirrors use http by default to leverage caching
|
||||
"mirror_alpine": "http://dl-cdn.alpinelinux.org/alpine/",
|
||||
# NOTE: mirrors_postmarketos variable type is supposed to be
|
||||
# comma-separated string, not a python list or any other type!
|
||||
"mirrors_postmarketos": "http://mirror.postmarketos.org/postmarketos/",
|
||||
"qemu_redir_stdio": False,
|
||||
"ssh_key_glob": "~/.ssh/id_*.pub",
|
||||
"ssh_keys": False,
|
||||
"sudo_timer": False,
|
||||
"systemd": "default",
|
||||
"timezone": "GMT",
|
||||
"ui": "console",
|
||||
"ui_extras": False,
|
||||
"user": "user",
|
||||
"work": os.path.expanduser("~") + "/.local/var/pmbootstrap",
|
||||
|
||||
# These values are not part of config_keys
|
||||
"cipher": "aes-xts-plain64",
|
||||
"config": (os.environ.get('XDG_CONFIG_HOME') or
|
||||
os.path.expanduser("~/.config")) + "/pmbootstrap.cfg",
|
||||
|
@ -223,7 +177,7 @@ chroot_path = ":".join([
|
|||
chroot_host_path = os.environ["PATH"] + ":/usr/sbin/"
|
||||
|
||||
# Folders that get mounted inside the chroot
|
||||
# $WORK gets replaced with pmb.config.work
|
||||
# $WORK gets replaced with get_context().config.work
|
||||
# $ARCH gets replaced with the chroot architecture (eg. x86_64, armhf)
|
||||
# $CHANNEL gets replaced with the release channel (e.g. edge, v21.03)
|
||||
# Use no more than one dir after /mnt/pmbootstrap, see remove_mnt_pmbootstrap.
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
# Copyright 2023 Oliver Smith
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
from pmb.core import get_context
|
||||
from pmb.core.chroot import Chroot
|
||||
from pmb.helpers import logging
|
||||
import glob
|
||||
|
@ -11,7 +12,7 @@ from typing import Any, List
|
|||
import pmb.aportgen
|
||||
import pmb.config
|
||||
import pmb.config.pmaports
|
||||
from pmb.core.types import PmbArgs
|
||||
from pmb.types import PmbArgs
|
||||
import pmb.helpers.cli
|
||||
import pmb.helpers.devices
|
||||
import pmb.helpers.git
|
||||
|
@ -67,7 +68,7 @@ def ask_for_work_path(args: PmbArgs):
|
|||
while True:
|
||||
try:
|
||||
work = os.path.expanduser(pmb.helpers.cli.ask(
|
||||
"Work path", None, pmb.config.work, False))
|
||||
"Work path", None, get_context().config.work, False))
|
||||
work = os.path.realpath(work)
|
||||
exists = os.path.exists(work)
|
||||
|
||||
|
@ -107,7 +108,7 @@ def ask_for_channel(args: PmbArgs):
|
|||
|
||||
:returns: channel name (e.g. "edge", "v21.03")
|
||||
"""
|
||||
channels_cfg = pmb.helpers.git.parse_channels_cfg(args)
|
||||
channels_cfg = pmb.helpers.git.parse_channels_cfg(get_context().config.aports)
|
||||
count = len(channels_cfg["channels"])
|
||||
|
||||
# List channels
|
||||
|
@ -123,7 +124,7 @@ def ask_for_channel(args: PmbArgs):
|
|||
# Otherwise, if valid: channel from pmaports.cfg of current branch
|
||||
# The actual channel name is not saved in pmbootstrap.cfg, because then we
|
||||
# would need to sync it with what is checked out in pmaports.git.
|
||||
default = pmb.config.pmaports.read_config(args)["channel"]
|
||||
default = pmb.config.pmaports.read_config()["channel"]
|
||||
choices = channels_cfg["channels"].keys()
|
||||
if args.is_default_channel or default not in choices:
|
||||
default = channels_cfg["meta"]["recommended"]
|
||||
|
@ -145,7 +146,7 @@ def ask_for_ui(args: PmbArgs, info):
|
|||
if not device_is_accelerated:
|
||||
for i in reversed(range(len(ui_list))):
|
||||
pkgname = f"postmarketos-ui-{ui_list[i][0]}"
|
||||
apkbuild = pmb.helpers.pmaports.get(args, pkgname,
|
||||
apkbuild = pmb.helpers.pmaports.get(pkgname,
|
||||
subpackages=False,
|
||||
must_exist=False)
|
||||
if apkbuild and "pmb:gpu-accel" in apkbuild["options"]:
|
||||
|
@ -176,7 +177,7 @@ def ask_for_ui(args: PmbArgs, info):
|
|||
|
||||
|
||||
def ask_for_ui_extras(args: PmbArgs, ui):
|
||||
apkbuild = pmb.helpers.pmaports.get(args, f"postmarketos-ui-{ui}",
|
||||
apkbuild = pmb.helpers.pmaports.get(f"postmarketos-ui-{ui}",
|
||||
subpackages=False, must_exist=False)
|
||||
if not apkbuild:
|
||||
return False
|
||||
|
@ -193,15 +194,15 @@ def ask_for_ui_extras(args: PmbArgs, ui):
|
|||
|
||||
|
||||
def ask_for_systemd(args: PmbArgs, ui):
|
||||
if "systemd" not in pmb.config.pmaports.read_config_repos(args):
|
||||
if "systemd" not in pmb.config.pmaports.read_config_repos():
|
||||
return args.systemd
|
||||
|
||||
if pmb.helpers.ui.check_option(args, ui, "pmb:systemd-never"):
|
||||
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
|
||||
|
||||
default_is_systemd = pmb.helpers.ui.check_option(args, ui, "pmb:systemd")
|
||||
default_is_systemd = pmb.helpers.ui.check_option(ui, "pmb:systemd")
|
||||
not_str = " " if default_is_systemd else " not "
|
||||
logging.info("Based on your UI selection, 'default' will result"
|
||||
f" in{not_str}installing systemd.")
|
||||
|
@ -267,7 +268,7 @@ def ask_for_provider_select(args: PmbArgs, apkbuild, providers_cfg):
|
|||
providers. Updated with new providers after selection
|
||||
"""
|
||||
for select in apkbuild["_pmb_select"]:
|
||||
providers = pmb.helpers.pmaports.find_providers(args, select)
|
||||
providers = pmb.helpers.pmaports.find_providers(select)
|
||||
logging.info(f"Available providers for {select} ({len(providers)}):")
|
||||
|
||||
has_default = False
|
||||
|
@ -322,7 +323,7 @@ def ask_for_provider_select_pkg(args: PmbArgs, pkgname, providers_cfg):
|
|||
:param providers_cfg: the configuration section with previously selected
|
||||
providers. Updated with new providers after selection
|
||||
"""
|
||||
apkbuild = pmb.helpers.pmaports.get(args, pkgname,
|
||||
apkbuild = pmb.helpers.pmaports.get(pkgname,
|
||||
subpackages=False, must_exist=False)
|
||||
if not apkbuild:
|
||||
return
|
||||
|
@ -330,7 +331,7 @@ def ask_for_provider_select_pkg(args: PmbArgs, pkgname, providers_cfg):
|
|||
ask_for_provider_select(args, apkbuild, providers_cfg)
|
||||
|
||||
|
||||
def ask_for_device_kernel(args: PmbArgs, device):
|
||||
def ask_for_device_kernel(args: PmbArgs, device: str):
|
||||
"""Ask for the kernel that should be used with the device.
|
||||
|
||||
:param device: code name, e.g. "lg-mako"
|
||||
|
@ -341,7 +342,7 @@ def ask_for_device_kernel(args: PmbArgs, device):
|
|||
|
||||
"""
|
||||
# Get kernels
|
||||
kernels = pmb.parse._apkbuild.kernels(args, device)
|
||||
kernels = pmb.parse._apkbuild.kernels(device)
|
||||
if not kernels:
|
||||
return args.kernel
|
||||
|
||||
|
@ -383,7 +384,7 @@ def ask_for_device(args: PmbArgs):
|
|||
* device_exists: bool indicating if device port exists in repo
|
||||
* kernel: type of kernel (downstream, etc)
|
||||
"""
|
||||
vendors = sorted(pmb.helpers.devices.list_vendors(args))
|
||||
vendors = sorted(pmb.helpers.devices.list_vendors(get_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)}")
|
||||
|
@ -409,7 +410,7 @@ def ask_for_device(args: PmbArgs):
|
|||
else:
|
||||
# Archived devices can be selected, but are not displayed
|
||||
devices = sorted(pmb.helpers.devices.list_codenames(
|
||||
args, vendor, archived=False))
|
||||
get_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)}): " +
|
||||
|
@ -422,7 +423,7 @@ def ask_for_device(args: PmbArgs):
|
|||
codenames)
|
||||
|
||||
device = f"{vendor}-{codename}"
|
||||
device_path = pmb.helpers.devices.find_path(args, device, 'deviceinfo')
|
||||
device_path = pmb.helpers.devices.find_path(device, 'deviceinfo')
|
||||
if device_path is None:
|
||||
if device == args.device:
|
||||
raise RuntimeError(
|
||||
|
@ -460,7 +461,7 @@ def ask_for_additional_options(args: PmbArgs, cfg):
|
|||
f" parallel jobs: {args.jobs},"
|
||||
f" ccache per arch: {args.ccache_size},"
|
||||
f" sudo timer: {context.sudo_timer},"
|
||||
f" mirror: {','.join(args.mirrors_postmarketos)}")
|
||||
f" mirror: {','.join(context.config.mirrors_postmarketos)}")
|
||||
|
||||
if not pmb.helpers.cli.confirm(args, "Change them?",
|
||||
default=False):
|
||||
|
@ -517,7 +518,7 @@ def ask_for_additional_options(args: PmbArgs, cfg):
|
|||
# Mirrors
|
||||
# prompt for mirror change
|
||||
logging.info("Selected mirror:"
|
||||
f" {','.join(args.mirrors_postmarketos)}")
|
||||
f" {','.join(context.config.mirrors_postmarketos)}")
|
||||
if pmb.helpers.cli.confirm(args, "Change mirror?", default=False):
|
||||
mirrors = ask_for_mirror(args)
|
||||
cfg["pmbootstrap"]["mirrors_postmarketos"] = ",".join(mirrors)
|
||||
|
@ -527,7 +528,7 @@ def ask_for_mirror(args: PmbArgs):
|
|||
regex = "^[1-9][0-9]*$" # single non-zero number only
|
||||
|
||||
json_path = pmb.helpers.http.download(
|
||||
args, "https://postmarketos.org/mirrors.json", "pmos_mirrors",
|
||||
"https://postmarketos.org/mirrors.json", "pmos_mirrors",
|
||||
cache=False)
|
||||
with open(json_path, "rt") as handle:
|
||||
s = handle.read()
|
||||
|
@ -558,7 +559,7 @@ def ask_for_mirror(args: PmbArgs):
|
|||
urls.append(link_list[0])
|
||||
|
||||
mirror_indexes = []
|
||||
for mirror in args.mirrors_postmarketos:
|
||||
for mirror in get_context().config.mirrors_postmarketos:
|
||||
for i in range(len(urls)):
|
||||
if urls[i] == mirror:
|
||||
mirror_indexes.append(str(i + 1))
|
||||
|
@ -647,64 +648,64 @@ def frontend(args: PmbArgs):
|
|||
require_programs()
|
||||
|
||||
# Work folder (needs to be first, so we can create chroots early)
|
||||
cfg = pmb.config.load(args)
|
||||
work, work_exists = ask_for_work_path(args)
|
||||
cfg["pmbootstrap"]["work"] = work
|
||||
config = pmb.config.load(args)
|
||||
config.work, work_exists = ask_for_work_path(args)
|
||||
|
||||
# Update args and save config (so chroots and 'pmbootstrap log' work)
|
||||
pmb.helpers.args.update_work(args, work)
|
||||
pmb.config.save(args, cfg)
|
||||
pmb.helpers.args.update_work(args, config.work)
|
||||
pmb.config.save(args.config, config)
|
||||
|
||||
# Migrate work dir if necessary
|
||||
pmb.helpers.other.migrate_work_folder(args)
|
||||
|
||||
# Clone pmaports
|
||||
pmb.config.pmaports.init(args)
|
||||
pmb.config.pmaports.init()
|
||||
|
||||
# Choose release channel, possibly switch pmaports branch
|
||||
channel = ask_for_channel(args)
|
||||
pmb.config.pmaports.switch_to_channel_branch(args, channel)
|
||||
cfg["pmbootstrap"]["is_default_channel"] = "False"
|
||||
# FIXME: ???
|
||||
config.is_default_channel = False
|
||||
|
||||
# Copy the git hooks if master was checked out. (Don't symlink them and
|
||||
# only do it on master, so the git hooks don't change unexpectedly when
|
||||
# having a random branch checked out.)
|
||||
branch_current = pmb.helpers.git.rev_parse(args.aports,
|
||||
branch_current = pmb.helpers.git.rev_parse(get_context().config.aports,
|
||||
extra_args=["--abbrev-ref"])
|
||||
if branch_current == "master":
|
||||
logging.info("NOTE: pmaports is on master branch, copying git hooks.")
|
||||
pmb.config.pmaports.install_githooks(args)
|
||||
pmb.config.pmaports.install_githooks()
|
||||
|
||||
# Device
|
||||
device, device_exists, kernel = ask_for_device(args)
|
||||
cfg["pmbootstrap"]["device"] = device
|
||||
cfg["pmbootstrap"]["kernel"] = kernel
|
||||
config.device = device
|
||||
config.kernel = kernel
|
||||
|
||||
info = pmb.parse.deviceinfo(args, device)
|
||||
apkbuild_path = pmb.helpers.devices.find_path(args, device, 'APKBUILD')
|
||||
apkbuild_path = pmb.helpers.devices.find_path(device, 'APKBUILD')
|
||||
if apkbuild_path:
|
||||
apkbuild = pmb.parse.apkbuild(apkbuild_path)
|
||||
ask_for_provider_select(args, apkbuild, cfg["providers"])
|
||||
ask_for_provider_select(args, apkbuild, config.providers)
|
||||
|
||||
# Device keymap
|
||||
if device_exists:
|
||||
cfg["pmbootstrap"]["keymap"] = ask_for_keymaps(args, info)
|
||||
config.keymap = ask_for_keymaps(args, info)
|
||||
|
||||
cfg["pmbootstrap"]["user"] = ask_for_username(args)
|
||||
ask_for_provider_select_pkg(args, "postmarketos-base", cfg["providers"])
|
||||
ask_for_provider_select_pkg(args, "postmarketos-base-ui", cfg["providers"])
|
||||
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)
|
||||
|
||||
# UI and various build options
|
||||
ui = ask_for_ui(args, info)
|
||||
cfg["pmbootstrap"]["ui"] = ui
|
||||
cfg["pmbootstrap"]["ui_extras"] = str(ask_for_ui_extras(args, ui))
|
||||
config.ui = ui
|
||||
config.ui_extras = ask_for_ui_extras(args, ui)
|
||||
|
||||
# systemd
|
||||
cfg["pmbootstrap"]["systemd"] = ask_for_systemd(args, ui)
|
||||
config.systemd = ask_for_systemd(args, ui)
|
||||
|
||||
ask_for_provider_select_pkg(args, f"postmarketos-ui-{ui}",
|
||||
cfg["providers"])
|
||||
ask_for_additional_options(args, cfg)
|
||||
config.providers)
|
||||
ask_for_additional_options(args, config)
|
||||
|
||||
# Extra packages to be installed to rootfs
|
||||
logging.info("Additional packages that will be installed to rootfs."
|
||||
|
@ -713,29 +714,28 @@ def frontend(args: PmbArgs):
|
|||
extra = pmb.helpers.cli.ask("Extra packages", None,
|
||||
args.extra_packages,
|
||||
validation_regex=r"^([-.+\w]+)(,[-.+\w]+)*$")
|
||||
cfg["pmbootstrap"]["extra_packages"] = extra
|
||||
config.extra_packages = extra
|
||||
|
||||
# Configure timezone info
|
||||
cfg["pmbootstrap"]["timezone"] = ask_for_timezone(args)
|
||||
config.timezone = ask_for_timezone(args)
|
||||
|
||||
# Locale
|
||||
cfg["pmbootstrap"]["locale"] = ask_for_locale(args)
|
||||
config.locale = ask_for_locale(args)
|
||||
|
||||
# Hostname
|
||||
cfg["pmbootstrap"]["hostname"] = ask_for_hostname(args, device)
|
||||
config.hostname = ask_for_hostname(args, device)
|
||||
|
||||
# SSH keys
|
||||
cfg["pmbootstrap"]["ssh_keys"] = str(ask_for_ssh_keys(args))
|
||||
config.ssh_keys = ask_for_ssh_keys(args)
|
||||
|
||||
# pmaports path (if users change it with: 'pmbootstrap --aports=... init')
|
||||
cfg["pmbootstrap"]["aports"] = args.aports
|
||||
config.aports = get_context().config.aports
|
||||
|
||||
# Build outdated packages in pmbootstrap install
|
||||
cfg["pmbootstrap"]["build_pkgs_on_install"] = str(
|
||||
ask_build_pkgs_on_install(args))
|
||||
config.build_pkgs_on_install = ask_build_pkgs_on_install(args)
|
||||
|
||||
# Save config
|
||||
pmb.config.save(args, cfg)
|
||||
pmb.config.save(args.config, config)
|
||||
|
||||
# Zap existing chroots
|
||||
if (work_exists and device_exists and
|
||||
|
|
|
@ -1,15 +1,18 @@
|
|||
# Copyright 2023 Oliver Smith
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
from pathlib import Path, PosixPath
|
||||
from typing import Any, Dict
|
||||
from pmb.helpers import logging
|
||||
import configparser
|
||||
import os
|
||||
import sys
|
||||
import pmb.config
|
||||
from pmb.core.types import PmbArgs
|
||||
from pmb.types import Config
|
||||
from pmb.types import PmbArgs
|
||||
|
||||
|
||||
def sanity_check(args: PmbArgs, cfg, key, allowed, print_path):
|
||||
value = cfg["pmbootstrap"][key]
|
||||
def sanity_check(args: PmbArgs, cfg: Config, key, allowed, print_path):
|
||||
value = getattr(cfg, key)
|
||||
|
||||
if value in allowed:
|
||||
return
|
||||
|
@ -23,12 +26,14 @@ def sanity_check(args: PmbArgs, cfg, key, allowed, print_path):
|
|||
sys.exit(1)
|
||||
|
||||
|
||||
def sanity_checks(args: PmbArgs, cfg, print_path=True):
|
||||
def sanity_checks(args: PmbArgs, cfg: Config, print_path=True):
|
||||
for key, allowed in pmb.config.allowed_values.items():
|
||||
sanity_check(args, cfg, key, allowed, print_path)
|
||||
|
||||
|
||||
def load(args: PmbArgs):
|
||||
def load(args: PmbArgs) -> Config:
|
||||
config = Config()
|
||||
|
||||
cfg = configparser.ConfigParser()
|
||||
if os.path.isfile(args.config):
|
||||
cfg.read(args.config)
|
||||
|
@ -38,27 +43,47 @@ def load(args: PmbArgs):
|
|||
if "providers" not in cfg:
|
||||
cfg["providers"] = {}
|
||||
|
||||
for key in pmb.config.defaults:
|
||||
if key in pmb.config.config_keys and key not in cfg["pmbootstrap"]:
|
||||
cfg["pmbootstrap"][key] = str(pmb.config.defaults[key])
|
||||
for key in Config.__dict__.keys():
|
||||
if key == "providers":
|
||||
setattr(config, key, cfg["providers"])
|
||||
# Handle whacky type conversions
|
||||
elif key == "mirrors_postmarketos":
|
||||
config.mirrors_postmarketos = cfg["pmbootstrap"]["mirrors_postmarketos"].split(",")
|
||||
# Convert strings to paths
|
||||
elif type(getattr(Config, key)) == PosixPath:
|
||||
setattr(config, key, Path(cfg["pmbootstrap"][key]))
|
||||
elif isinstance(getattr(Config, key), bool):
|
||||
setattr(config, key, cfg["pmbootstrap"][key].lower() == "true")
|
||||
elif key in cfg["pmbootstrap"]:
|
||||
setattr(config, key, cfg["pmbootstrap"][key])
|
||||
|
||||
# We used to save default values in the config, which can *not* be
|
||||
# configured in "pmbootstrap init". That doesn't make sense, we always
|
||||
# want to use the defaults from pmb/config/__init__.py in that case,
|
||||
# not some outdated version we saved some time back (eg. aports folder,
|
||||
# postmarketOS binary packages mirror).
|
||||
if key not in pmb.config.config_keys and key in cfg["pmbootstrap"]:
|
||||
logging.debug("Ignored unconfigurable and possibly outdated"
|
||||
" default value from config:"
|
||||
f" {cfg['pmbootstrap'][key]}")
|
||||
del cfg["pmbootstrap"][key]
|
||||
sanity_checks(args, config)
|
||||
|
||||
sanity_checks(args, cfg)
|
||||
return config
|
||||
|
||||
return cfg
|
||||
def save(output: Path, config: Config):
|
||||
logging.debug(f"Save config: {output}")
|
||||
output.parent.mkdir(parents=True, exist_ok=True)
|
||||
output.touch(0o700, exist_ok=True)
|
||||
|
||||
def save(args: PmbArgs, cfg):
|
||||
logging.debug(f"Save config: {args.config}")
|
||||
os.makedirs(os.path.dirname(args.config), 0o700, True)
|
||||
with open(args.config, "w") as handle:
|
||||
cfg = configparser.ConfigParser()
|
||||
cfg["pmbootstrap"] = {}
|
||||
cfg["providers"] = {}
|
||||
|
||||
for key in Config.__dict__.keys():
|
||||
print(key)
|
||||
if key == "providers":
|
||||
cfg["providers"] = config.providers
|
||||
# Handle whacky type conversions
|
||||
elif key == "mirrors_postmarketos":
|
||||
cfg["pmbootstrap"]["mirrors_postmarketos"] = ",".join(config.mirrors_postmarketos)
|
||||
# Convert strings to paths
|
||||
elif type(getattr(Config, key)) == Path:
|
||||
cfg["pmbootstrap"][key] = str(getattr(config, key))
|
||||
elif isinstance(getattr(Config, key), bool):
|
||||
cfg["pmbootstrap"][key] = str(getattr(config, key))
|
||||
else:
|
||||
cfg["pmbootstrap"] = getattr(config, key)
|
||||
|
||||
with output.open("w") as handle:
|
||||
cfg.write(handle)
|
||||
|
|
|
@ -2,45 +2,42 @@
|
|||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
from pathlib import Path
|
||||
import pmb.config
|
||||
from pmb.core.types import PmbArgs
|
||||
from pmb.types import PmbArgs
|
||||
|
||||
|
||||
def merge_with_args(args: PmbArgs):
|
||||
"""We have the internal config (pmb/config/__init__.py) and the user config
|
||||
(usually ~/.config/pmbootstrap.cfg, can be changed with the '-c'
|
||||
parameter).
|
||||
# def merge_with_args(args: PmbArgs):
|
||||
# """We have the internal config (pmb/config/__init__.py) and the user config
|
||||
# (usually ~/.config/pmbootstrap.cfg, can be changed with the '-c'
|
||||
# parameter).
|
||||
|
||||
Args holds the variables parsed from the commandline (e.g. -j fills out
|
||||
args.jobs), and values specified on the commandline count the most.
|
||||
# Args holds the variables parsed from the commandline (e.g. -j fills out
|
||||
# args.jobs), and values specified on the commandline count the most.
|
||||
|
||||
In case it is not specified on the commandline, for the keys in
|
||||
pmb.config.config_keys, we look into the value set in the the user config.
|
||||
# In case it is not specified on the commandline, for the keys in
|
||||
# pmb.config.config_keys, we look into the value set in the the user config.
|
||||
|
||||
When that is empty as well (e.g. just before pmbootstrap init), or the key
|
||||
is not in pmb.config_keys, we use the default value from the internal
|
||||
config.
|
||||
"""
|
||||
# Use defaults from the user's config file
|
||||
cfg = pmb.config.load(args)
|
||||
for key in cfg["pmbootstrap"]:
|
||||
if key not in args or getattr(args, key) is None:
|
||||
value = cfg["pmbootstrap"][key]
|
||||
if key in pmb.config.defaults:
|
||||
default = pmb.config.defaults[key]
|
||||
if isinstance(default, bool):
|
||||
value = (value.lower() == "true")
|
||||
setattr(args, key, value)
|
||||
setattr(args, 'selected_providers', cfg['providers'])
|
||||
# When that is empty as well (e.g. just before pmbootstrap init), or the key
|
||||
# is not in pmb.config_keys, we use the default value from the internal
|
||||
# config.
|
||||
# """
|
||||
# # Use defaults from the user's config file
|
||||
# cfg = pmb.config.load(args)
|
||||
# for key in cfg["pmbootstrap"]:
|
||||
# if key not in args or getattr(args, key) is None:
|
||||
# value = cfg["pmbootstrap"][key]
|
||||
# if key in pmb.config.defaults:
|
||||
# default = pmb.config.defaults[key]
|
||||
# if isinstance(default, bool):
|
||||
# value = (value.lower() == "true")
|
||||
# setattr(args, key, value)
|
||||
# setattr(args, 'selected_providers', cfg['providers'])
|
||||
|
||||
# Use defaults from pmb.config.defaults
|
||||
for key, value in pmb.config.defaults.items():
|
||||
if key not in args or getattr(args, key) is None:
|
||||
setattr(args, key, value)
|
||||
# # Use defaults from pmb.config.defaults
|
||||
# for key, value in pmb.config.defaults.items():
|
||||
# if key not in args or getattr(args, key) is None:
|
||||
# setattr(args, key, value)
|
||||
|
||||
pmb.config.work_dir(Path(cfg["pmbootstrap"]["work"]))
|
||||
# pmb.config.work_dir(Path(cfg["pmbootstrap"]["work"]))
|
||||
|
||||
# Make sure args.aports is a Path object
|
||||
setattr(args, "aports", Path(args.aports))
|
||||
|
||||
# args.work is deprecated!
|
||||
delattr(args, "work")
|
||||
# # Make sure args.aports is a Path object
|
||||
# setattr(args, "aports", Path(args.aports))
|
||||
|
|
|
@ -1,31 +1,31 @@
|
|||
# Copyright 2024 Oliver Smith
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
from pmb.core.types import PmbArgs
|
||||
from pmb.types import Config
|
||||
import pmb.helpers.ui
|
||||
import pmb.config.pmaports
|
||||
|
||||
|
||||
def is_systemd_selected(args: PmbArgs):
|
||||
if "systemd" not in pmb.config.pmaports.read_config_repos(args):
|
||||
def is_systemd_selected(config: Config):
|
||||
if "systemd" not in pmb.config.pmaports.read_config_repos():
|
||||
return False
|
||||
if pmb.helpers.ui.check_option(args, args.ui, "pmb:systemd-never"):
|
||||
if pmb.helpers.ui.check_option(config.ui, "pmb:systemd-never"):
|
||||
return False
|
||||
if args.systemd == "always":
|
||||
if config.systemd == "always":
|
||||
return True
|
||||
if args.systemd == "never":
|
||||
if config.systemd == "never":
|
||||
return False
|
||||
return pmb.helpers.ui.check_option(args, args.ui, "pmb:systemd")
|
||||
return pmb.helpers.ui.check_option(config.ui, "pmb:systemd")
|
||||
|
||||
|
||||
def systemd_selected_str(args):
|
||||
if "systemd" not in pmb.config.pmaports.read_config_repos(args):
|
||||
def systemd_selected_str(config: Config):
|
||||
if "systemd" not in pmb.config.pmaports.read_config_repos():
|
||||
return "no", "not supported by pmaports branch"
|
||||
if pmb.helpers.ui.check_option(args, args.ui, "pmb:systemd-never"):
|
||||
if pmb.helpers.ui.check_option(config.ui, "pmb:systemd-never"):
|
||||
return "no", "not supported by selected UI"
|
||||
if args.systemd == "always":
|
||||
if config.systemd == "always":
|
||||
return "yes", "'always' selected in 'pmbootstrap init'"
|
||||
if args.systemd == "never":
|
||||
if config.systemd == "never":
|
||||
return "no", "'never' selected in 'pmbootstrap init'"
|
||||
if pmb.helpers.ui.check_option(args, args.ui, "pmb:systemd"):
|
||||
if pmb.helpers.ui.check_option(config.ui, "pmb:systemd"):
|
||||
return "yes", "default for selected UI"
|
||||
return "no", "default for selected UI"
|
||||
|
|
|
@ -1,12 +1,14 @@
|
|||
# Copyright 2023 Oliver Smith
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
import configparser
|
||||
from pathlib import Path
|
||||
from pmb.core import get_context
|
||||
from pmb.helpers import logging
|
||||
import os
|
||||
import sys
|
||||
|
||||
import pmb.config
|
||||
from pmb.core.types import PmbArgs
|
||||
from pmb.types import PmbArgs
|
||||
import pmb.helpers.git
|
||||
import pmb.helpers.pmaports
|
||||
import pmb.parse.version
|
||||
|
@ -56,7 +58,7 @@ def check_version_pmbootstrap(min_ver):
|
|||
" of pmbootstrap from git.")
|
||||
|
||||
|
||||
def read_config_repos(args: PmbArgs):
|
||||
def read_config_repos():
|
||||
""" Read the sections starting with "repo:" from pmaports.cfg. """
|
||||
# Try cache first
|
||||
cache_key = "pmb.config.pmaports.read_config_repos"
|
||||
|
@ -64,7 +66,7 @@ def read_config_repos(args: PmbArgs):
|
|||
return pmb.helpers.other.cache[cache_key]
|
||||
|
||||
cfg = configparser.ConfigParser()
|
||||
cfg.read(f"{args.aports}/pmaports.cfg")
|
||||
cfg.read(f"{get_context().config.aports}/pmaports.cfg")
|
||||
|
||||
ret = {}
|
||||
for section in cfg.keys():
|
||||
|
@ -78,21 +80,22 @@ def read_config_repos(args: PmbArgs):
|
|||
return ret
|
||||
|
||||
|
||||
def read_config(args: PmbArgs):
|
||||
def read_config():
|
||||
"""Read and verify pmaports.cfg."""
|
||||
# Try cache first
|
||||
cache_key = "pmb.config.pmaports.read_config"
|
||||
if pmb.helpers.other.cache[cache_key]:
|
||||
return pmb.helpers.other.cache[cache_key]
|
||||
|
||||
aports = get_context().config.aports
|
||||
# Migration message
|
||||
if not os.path.exists(args.aports):
|
||||
logging.error(f"ERROR: pmaports dir not found: {args.aports}")
|
||||
if not os.path.exists(aports):
|
||||
logging.error(f"ERROR: pmaports dir not found: {aports}")
|
||||
logging.error("Did you run 'pmbootstrap init'?")
|
||||
sys.exit(1)
|
||||
|
||||
# Require the config
|
||||
path_cfg = args.aports / "pmaports.cfg"
|
||||
path_cfg = aports / "pmaports.cfg"
|
||||
if not os.path.exists(path_cfg):
|
||||
raise RuntimeError("Invalid pmaports repository, could not find the"
|
||||
f" config: {path_cfg}")
|
||||
|
@ -114,7 +117,7 @@ def read_config(args: PmbArgs):
|
|||
return ret
|
||||
|
||||
|
||||
def read_config_channel(args: PmbArgs):
|
||||
def read_config_channel():
|
||||
"""Get the properties of the currently active channel in pmaports.git.
|
||||
|
||||
As specified in channels.cfg (https://postmarketos.org/channels.cfg).
|
||||
|
@ -125,18 +128,19 @@ def read_config_channel(args: PmbArgs):
|
|||
"mirrordir_alpine": ...}
|
||||
|
||||
"""
|
||||
channel = read_config(args)["channel"]
|
||||
channels_cfg = pmb.helpers.git.parse_channels_cfg(args)
|
||||
aports = get_context().config.aports
|
||||
channel = read_config()["channel"]
|
||||
channels_cfg = pmb.helpers.git.parse_channels_cfg(aports)
|
||||
|
||||
if channel in channels_cfg["channels"]:
|
||||
return channels_cfg["channels"][channel]
|
||||
|
||||
# Channel not in channels.cfg, try to be helpful
|
||||
branch = pmb.helpers.git.rev_parse(args.aports,
|
||||
branch = pmb.helpers.git.rev_parse(aports,
|
||||
extra_args=["--abbrev-ref"])
|
||||
branches_official = pmb.helpers.git.get_branches_official("pmaports")
|
||||
branches_official = pmb.helpers.git.get_branches_official(aports)
|
||||
branches_official = ", ".join(branches_official)
|
||||
remote = pmb.helpers.git.get_upstream_remote("pmaports")
|
||||
remote = pmb.helpers.git.get_upstream_remote(aports)
|
||||
logging.info("NOTE: fix the error by rebasing or cherry picking relevant"
|
||||
" commits from this branch onto a branch that is on a"
|
||||
f" supported channel: {branches_official}")
|
||||
|
@ -150,7 +154,7 @@ def read_config_channel(args: PmbArgs):
|
|||
|
||||
|
||||
def init():
|
||||
if not os.path.exists(get_context().aports):
|
||||
if not os.path.exists(get_context().config.aports):
|
||||
clone()
|
||||
read_config()
|
||||
|
||||
|
@ -163,14 +167,15 @@ def switch_to_channel_branch(args: PmbArgs, channel_new):
|
|||
:returns: True if another branch was checked out, False otherwise
|
||||
"""
|
||||
# Check current pmaports branch channel
|
||||
channel_current = read_config(args)["channel"]
|
||||
channel_current = read_config()["channel"]
|
||||
if channel_current == channel_new:
|
||||
return False
|
||||
|
||||
aports = get_context().config.aports
|
||||
# List current and new branches/channels
|
||||
channels_cfg = pmb.helpers.git.parse_channels_cfg(args)
|
||||
channels_cfg = pmb.helpers.git.parse_channels_cfg(aports)
|
||||
branch_new = channels_cfg["channels"][channel_new]["branch_pmaports"]
|
||||
branch_current = pmb.helpers.git.rev_parse(args.aports,
|
||||
branch_current = pmb.helpers.git.rev_parse(aports,
|
||||
extra_args=["--abbrev-ref"])
|
||||
logging.info(f"Currently checked out branch '{branch_current}' of"
|
||||
f" pmaports.git is on channel '{channel_current}'.")
|
||||
|
@ -183,25 +188,26 @@ def switch_to_channel_branch(args: PmbArgs, channel_new):
|
|||
# Attempt to switch branch (git gives a nice error message, mentioning
|
||||
# which files need to be committed/stashed, so just pass it through)
|
||||
if pmb.helpers.run.user(["git", "checkout", branch_new],
|
||||
args.aports, "interactive", check=False):
|
||||
aports, "interactive", check=False):
|
||||
raise RuntimeError("Failed to switch branch. Go to your pmaports and"
|
||||
" fix what git complained about, then try again: "
|
||||
f"{args.aports}")
|
||||
f"{aports}")
|
||||
|
||||
# Verify pmaports.cfg on new branch
|
||||
read_config(args)
|
||||
read_config()
|
||||
return True
|
||||
|
||||
|
||||
def install_githooks(args: PmbArgs):
|
||||
hooks_dir = os.path.join(args.aports, ".githooks")
|
||||
if not os.path.exists(hooks_dir):
|
||||
def install_githooks():
|
||||
aports = get_context().config.aports
|
||||
hooks_dir = aports / ".githooks"
|
||||
if not hooks_dir.exists():
|
||||
logging.info("No .githooks dir found")
|
||||
return
|
||||
for h in os.listdir(hooks_dir):
|
||||
src = os.path.join(hooks_dir, h)
|
||||
# Use git default hooks dir so users can ignore our hooks
|
||||
# if they dislike them by setting "core.hooksPath" git config
|
||||
dst = os.path.join(args.aports, ".git", "hooks", h)
|
||||
dst = aports / ".git/hooks" / h
|
||||
if pmb.helpers.run.user(["cp", src, dst], check=False):
|
||||
logging.warning(f"WARNING: Copying git hook failed: {dst}")
|
||||
|
|
|
@ -11,15 +11,15 @@ from typing import Optional
|
|||
|
||||
import pmb.config
|
||||
import pmb.config.pmaports
|
||||
from pmb.core import Chroot
|
||||
from pmb.core.types import PmbArgs
|
||||
from pmb.core import Chroot, get_context
|
||||
from pmb.types import PmbArgs
|
||||
|
||||
|
||||
def chroot_save_init(args: PmbArgs, suffix: Chroot):
|
||||
def chroot_save_init(suffix: Chroot):
|
||||
"""Save the chroot initialization data in $WORK/workdir.cfg."""
|
||||
# Read existing cfg
|
||||
cfg = configparser.ConfigParser()
|
||||
path = pmb.config.work / "workdir.cfg"
|
||||
path = get_context().config.work / "workdir.cfg"
|
||||
if os.path.isfile(path):
|
||||
cfg.read(path)
|
||||
|
||||
|
@ -29,7 +29,7 @@ def chroot_save_init(args: PmbArgs, suffix: Chroot):
|
|||
cfg[key] = {}
|
||||
|
||||
# Update sections
|
||||
channel = pmb.config.pmaports.read_config(args)["channel"]
|
||||
channel = pmb.config.pmaports.read_config()["channel"]
|
||||
cfg["chroot-channels"][str(suffix)] = channel
|
||||
cfg["chroot-init-dates"][str(suffix)] = str(int(time.time()))
|
||||
|
||||
|
@ -38,7 +38,7 @@ def chroot_save_init(args: PmbArgs, suffix: Chroot):
|
|||
cfg.write(handle)
|
||||
|
||||
|
||||
def chroots_outdated(args: PmbArgs, chroot: Optional[Chroot]=None):
|
||||
def chroots_outdated(chroot: Optional[Chroot]=None):
|
||||
"""Check if init dates from workdir.cfg indicate that any chroot is
|
||||
outdated.
|
||||
|
||||
|
@ -48,7 +48,7 @@ def chroots_outdated(args: PmbArgs, chroot: Optional[Chroot]=None):
|
|||
False otherwise
|
||||
"""
|
||||
# Skip if workdir.cfg doesn't exist
|
||||
path = pmb.config.work / "workdir.cfg"
|
||||
path = get_context().config.work / "workdir.cfg"
|
||||
if not os.path.exists(path):
|
||||
return False
|
||||
|
||||
|
@ -68,8 +68,8 @@ def chroots_outdated(args: PmbArgs, chroot: Optional[Chroot]=None):
|
|||
return False
|
||||
|
||||
|
||||
def chroot_check_channel(args: PmbArgs, chroot: Chroot):
|
||||
path = pmb.config.work / "workdir.cfg"
|
||||
def chroot_check_channel(chroot: Chroot):
|
||||
path = get_context().config.work / "workdir.cfg"
|
||||
msg_again = "Run 'pmbootstrap zap' to delete your chroots and try again."
|
||||
msg_unknown = ("Could not figure out on which release channel the"
|
||||
f" '{chroot}' chroot is.")
|
||||
|
@ -82,7 +82,7 @@ def chroot_check_channel(args: PmbArgs, chroot: Chroot):
|
|||
if key not in cfg or str(chroot) not in cfg[key]:
|
||||
raise RuntimeError(f"{msg_unknown} {msg_again}")
|
||||
|
||||
channel = pmb.config.pmaports.read_config(args)["channel"]
|
||||
channel = pmb.config.pmaports.read_config()["channel"]
|
||||
channel_cfg = cfg[key][str(chroot)]
|
||||
if channel != channel_cfg:
|
||||
raise RuntimeError(f"Chroot '{chroot}' was created for the"
|
||||
|
@ -98,7 +98,7 @@ def clean(args: PmbArgs):
|
|||
False if config did not change
|
||||
"""
|
||||
# Skip if workdir.cfg doesn't exist
|
||||
path = pmb.config.work / "workdir.cfg"
|
||||
path = get_context().config.work / "workdir.cfg"
|
||||
if not os.path.exists(path):
|
||||
return None
|
||||
|
||||
|
|
|
@ -1,17 +1,6 @@
|
|||
# Copyright 2024 Caleb Connolly
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
from pmb.core.chroot import Chroot, ChrootType
|
||||
from pmb.core.context import Context
|
||||
|
||||
__context: Context
|
||||
|
||||
def get_context() -> Context:
|
||||
"""Get immutable global runtime context."""
|
||||
global __context
|
||||
|
||||
# We must defer this to first call to avoid
|
||||
# circular imports.
|
||||
if "__context" not in globals():
|
||||
__context = Context()
|
||||
return __context
|
||||
from .chroot import Chroot, ChrootType
|
||||
from .context import Context, get_context, set_context
|
||||
from .config import Config
|
||||
|
|
|
@ -6,6 +6,7 @@ import enum
|
|||
from typing import Generator, Optional
|
||||
from pathlib import Path, PosixPath, PurePosixPath
|
||||
import pmb.config
|
||||
from .context import get_context
|
||||
|
||||
class ChrootType(enum.Enum):
|
||||
ROOTFS = "rootfs"
|
||||
|
@ -69,7 +70,7 @@ class Chroot:
|
|||
|
||||
@property
|
||||
def path(self) -> Path:
|
||||
return Path(pmb.config.work, self.dirname)
|
||||
return Path(get_context().config.work, self.dirname)
|
||||
|
||||
|
||||
@property
|
||||
|
@ -182,4 +183,4 @@ class Chroot:
|
|||
Glob all initialized chroot directories
|
||||
"""
|
||||
for pattern in Chroot.iter_patterns():
|
||||
yield from Path(pmb.config.work).glob(pattern)
|
||||
yield from Path(get_context().config.work).glob(pattern)
|
||||
|
|
|
@ -3,9 +3,9 @@
|
|||
|
||||
"""Global runtime context"""
|
||||
|
||||
from typing import Optional
|
||||
import pmb.config
|
||||
from typing import List, Optional
|
||||
from pathlib import Path
|
||||
from pmb.types import Config
|
||||
|
||||
|
||||
class Context():
|
||||
|
@ -17,14 +17,62 @@ class Context():
|
|||
# The architecture of the selected device
|
||||
device_arch: Optional[str]
|
||||
offline: bool
|
||||
aports: Path
|
||||
|
||||
def __init__(self):
|
||||
# Never build packages
|
||||
sdnfivnsifdvsbdf: bool
|
||||
|
||||
# The pmbootstrap subcommand
|
||||
command: str
|
||||
|
||||
## FIXME: build options, should not be here ##
|
||||
# disable cross compilation and use QEMU
|
||||
cross: bool
|
||||
no_depends: bool
|
||||
ignore_depends: bool
|
||||
ccache: bool
|
||||
go_mod_cache: bool
|
||||
|
||||
config: Config
|
||||
|
||||
def __init__(self, config: Config):
|
||||
self.details_to_stdout = False
|
||||
self.command_timeout = 0
|
||||
self.sudo_timer = False
|
||||
self.log = pmb.config.work / "log.txt"
|
||||
self.log = config.work / "log.txt"
|
||||
self.quiet = False
|
||||
self.device_arch = None
|
||||
self.offline = False
|
||||
self.aports = pmb.config.work / "cache_git" / "pmaports"
|
||||
self.config = config
|
||||
self.sdnfivnsifdvsbdf = False
|
||||
self.command = ""
|
||||
self.cross = False
|
||||
self.no_depends = False
|
||||
self.ignore_depends = False
|
||||
self.ccache = False
|
||||
self.go_mod_cache = False
|
||||
|
||||
|
||||
__context: Context
|
||||
|
||||
def get_context(allow_failure: bool=False) -> Context:
|
||||
"""Get immutable global runtime context."""
|
||||
global __context
|
||||
|
||||
# We must defer this to first call to avoid
|
||||
# circular imports.
|
||||
if "__context" not in globals():
|
||||
if allow_failure:
|
||||
return None
|
||||
raise RuntimeError("Context not loaded yet")
|
||||
return __context
|
||||
|
||||
def set_context(context: Context):
|
||||
"""Set global runtime context."""
|
||||
global __context
|
||||
|
||||
if "__context" in globals():
|
||||
raise RuntimeError("Context already loaded")
|
||||
|
||||
__context = context
|
||||
|
||||
|
||||
|
|
43
pmb/core/crosstool.py
Normal file
43
pmb/core/crosstool.py
Normal file
|
@ -0,0 +1,43 @@
|
|||
# Copyright 2024 Caleb Connolly
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
from argparse import Namespace
|
||||
import enum
|
||||
from pathlib import Path
|
||||
from typing import Dict, List, Optional, Tuple, TypedDict, Union
|
||||
|
||||
from pmb.core.chroot import ChrootType
|
||||
from pmb.types import PathString
|
||||
|
||||
class CrossToolTarget(enum.Enum):
|
||||
BUILDROOT = 0
|
||||
ROOTFS = 1
|
||||
|
||||
class CrossTool():
|
||||
__target: CrossToolTarget
|
||||
__package: str
|
||||
__paths: List[Path]
|
||||
|
||||
def __init__(self, target: CrossToolTarget, package: str, paths: List[PathString]):
|
||||
self.__target = target
|
||||
self.__package = package
|
||||
self.__paths = list(map(lambda p: Path(p) if isinstance(p, str) else p, paths))
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return f"CrossTool({self.__target}, {self.__package}, {self.__paths})"
|
||||
|
||||
@property
|
||||
def package(self) -> str:
|
||||
return self.__package
|
||||
|
||||
@property
|
||||
def paths(self) -> List[Path]:
|
||||
return self.__paths
|
||||
|
||||
def should_install(self, target: ChrootType) -> bool:
|
||||
if target == ChrootType.BUILDROOT and self.__target == CrossToolTarget.BUILDROOT:
|
||||
return True
|
||||
if target == ChrootType.ROOTFS or target == ChrootType.INSTALLER and self.__target == CrossToolTarget.ROOTFS:
|
||||
return True
|
||||
|
||||
return False
|
|
@ -1,7 +1,7 @@
|
|||
from pmb.helpers import logging
|
||||
import os
|
||||
|
||||
from pmb.core.types import PmbArgs
|
||||
from pmb.types import PmbArgs
|
||||
import pmb.helpers.run
|
||||
import pmb.helpers.frontend
|
||||
import pmb.chroot.initfs
|
||||
|
|
|
@ -6,7 +6,7 @@ from pathlib import Path
|
|||
import pmb.build
|
||||
import pmb.chroot.apk
|
||||
import pmb.config
|
||||
from pmb.core.types import PmbArgs
|
||||
from pmb.types import PmbArgs
|
||||
import pmb.flasher
|
||||
import pmb.helpers.file
|
||||
from pmb.core import Chroot, ChrootType
|
||||
|
@ -23,7 +23,7 @@ def odin(args: PmbArgs, flavor, folder: Path):
|
|||
|
||||
# Backwards compatibility with old mkinitfs (pma#660)
|
||||
suffix_flavor = f"-{flavor}"
|
||||
pmaports_cfg = pmb.config.pmaports.read_config(args)
|
||||
pmaports_cfg = pmb.config.pmaports.read_config()
|
||||
if pmaports_cfg.get("supported_mkinitfs_without_flavors", False):
|
||||
suffix_flavor = ""
|
||||
|
||||
|
@ -44,7 +44,7 @@ def odin(args: PmbArgs, flavor, folder: Path):
|
|||
# Temporary folder
|
||||
temp_folder = "/tmp/odin-flashable-tar"
|
||||
if (Chroot.native() / temp_folder).exists():
|
||||
pmb.chroot.root(args, ["rm", "-rf", temp_folder])
|
||||
pmb.chroot.root(["rm", "-rf", temp_folder])
|
||||
|
||||
# Odin flashable tar generation script
|
||||
# (because redirecting stdin/stdout is not allowed
|
||||
|
@ -86,15 +86,15 @@ def odin(args: PmbArgs, flavor, folder: Path):
|
|||
["rm", "/tmp/_odin.sh"]
|
||||
]
|
||||
for command in commands:
|
||||
pmb.chroot.root(args, command, suffix)
|
||||
pmb.chroot.root(command, suffix)
|
||||
|
||||
# Move Odin flashable tar to native chroot and cleanup temp folder
|
||||
pmb.chroot.user(args, ["mkdir", "-p", "/home/pmos/rootfs"])
|
||||
pmb.chroot.root(args, ["mv", f"/mnt/rootfs_{args.device}{temp_folder}"
|
||||
pmb.chroot.user(["mkdir", "-p", "/home/pmos/rootfs"])
|
||||
pmb.chroot.root(["mv", f"/mnt/rootfs_{args.device}{temp_folder}"
|
||||
f"/{odin_device_tar_md5}", "/home/pmos/rootfs/"]),
|
||||
pmb.chroot.root(args, ["chown", "pmos:pmos",
|
||||
pmb.chroot.root(["chown", "pmos:pmos",
|
||||
f"/home/pmos/rootfs/{odin_device_tar_md5}"])
|
||||
pmb.chroot.root(args, ["rmdir", temp_folder], suffix)
|
||||
pmb.chroot.root(["rmdir", temp_folder], suffix)
|
||||
|
||||
# Create the symlink
|
||||
file = Chroot.native() / "home/pmos/rootfs" / odin_device_tar_md5
|
||||
|
|
|
@ -8,7 +8,7 @@ import pmb.build
|
|||
import pmb.chroot.apk
|
||||
import pmb.config
|
||||
import pmb.config.pmaports
|
||||
from pmb.core.types import PmbArgs
|
||||
from pmb.types import PmbArgs
|
||||
import pmb.flasher
|
||||
import pmb.helpers.file
|
||||
from pmb.core import Chroot, ChrootType
|
||||
|
@ -21,7 +21,7 @@ def symlinks(args: PmbArgs, flavor, folder: Path):
|
|||
|
||||
# Backwards compatibility with old mkinitfs (pma#660)
|
||||
suffix = f"-{flavor}"
|
||||
pmaports_cfg = pmb.config.pmaports.read_config(args)
|
||||
pmaports_cfg = pmb.config.pmaports.read_config()
|
||||
if pmaports_cfg.get("supported_mkinitfs_without_flavors", False):
|
||||
suffix = ""
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
from pmb.helpers import logging
|
||||
|
||||
import pmb.config
|
||||
from pmb.core.types import PmbArgs
|
||||
from pmb.types import PmbArgs
|
||||
import pmb.flasher
|
||||
import pmb.install
|
||||
import pmb.chroot.apk
|
||||
|
@ -116,7 +116,7 @@ def flash_lk2nd(args: PmbArgs):
|
|||
# manually since supporting the codepath with heimdall requires more effort.
|
||||
pmb.flasher.init(args)
|
||||
logging.info("(native) checking current fastboot product")
|
||||
output = pmb.chroot.root(args, ["fastboot", "getvar", "product"],
|
||||
output = pmb.chroot.root(["fastboot", "getvar", "product"],
|
||||
output="interactive", output_return=True)
|
||||
# Variable "product" is e.g. "LK2ND_MSM8974" or "lk2nd-msm8226" depending
|
||||
# on the lk2nd version.
|
||||
|
@ -126,7 +126,7 @@ def flash_lk2nd(args: PmbArgs):
|
|||
|
||||
# Get the lk2nd package (which is a dependency of the device package)
|
||||
device_pkg = f"device-{args.device}"
|
||||
apkbuild = pmb.helpers.pmaports.get(args, device_pkg)
|
||||
apkbuild = pmb.helpers.pmaports.get(device_pkg)
|
||||
lk2nd_pkg = None
|
||||
for dep in apkbuild["depends"]:
|
||||
if dep.startswith("lk2nd"):
|
||||
|
@ -137,7 +137,7 @@ def flash_lk2nd(args: PmbArgs):
|
|||
raise RuntimeError(f"{device_pkg} does not depend on any lk2nd package")
|
||||
|
||||
suffix = Chroot(ChrootType.ROOTFS, args.device)
|
||||
pmb.chroot.apk.install(args, [lk2nd_pkg], suffix)
|
||||
pmb.chroot.apk.install([lk2nd_pkg], suffix)
|
||||
|
||||
logging.info("(native) flash lk2nd image")
|
||||
pmb.flasher.run(args, "flash_lk2nd")
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
import pmb.chroot.apk
|
||||
import pmb.config
|
||||
import pmb.config.pmaports
|
||||
from pmb.core.types import PmbArgs
|
||||
from pmb.types import PmbArgs
|
||||
import pmb.helpers.mount
|
||||
from pmb.helpers.mount import mount_device_rootfs
|
||||
from pmb.core import Chroot, ChrootType
|
||||
|
@ -28,19 +28,19 @@ def install_depends(args: PmbArgs):
|
|||
# Depends for some flash methods may be different for various pmaports
|
||||
# branches, so read them from pmaports.cfg.
|
||||
if method == "fastboot":
|
||||
pmaports_cfg = pmb.config.pmaports.read_config(args)
|
||||
pmaports_cfg = pmb.config.pmaports.read_config()
|
||||
depends = pmaports_cfg.get("supported_fastboot_depends",
|
||||
"android-tools,avbtool").split(",")
|
||||
elif method == "heimdall-bootimg":
|
||||
pmaports_cfg = pmb.config.pmaports.read_config(args)
|
||||
pmaports_cfg = pmb.config.pmaports.read_config()
|
||||
depends = pmaports_cfg.get("supported_heimdall_depends",
|
||||
"heimdall,avbtool").split(",")
|
||||
elif method == "mtkclient":
|
||||
pmaports_cfg = pmb.config.pmaports.read_config(args)
|
||||
pmaports_cfg = pmb.config.pmaports.read_config()
|
||||
depends = pmaports_cfg.get("supported_mtkclient_depends",
|
||||
"mtkclient,android-tools").split(",")
|
||||
|
||||
pmb.chroot.apk.install(args, depends, Chroot.native())
|
||||
pmb.chroot.apk.install(depends, Chroot.native())
|
||||
|
||||
|
||||
def init(args: PmbArgs):
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# Copyright 2023 Oliver Smith
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
from pmb.core.types import PmbArgs
|
||||
from pmb.types import PmbArgs
|
||||
import pmb.flasher
|
||||
import pmb.chroot.initfs
|
||||
|
||||
|
@ -80,4 +80,4 @@ def run(args: PmbArgs, action, flavor=None):
|
|||
# Remove empty strings
|
||||
command = [x for x in command if x != '']
|
||||
# Run the action
|
||||
pmb.chroot.root(args, command, output="interactive")
|
||||
pmb.chroot.root(command, output="interactive")
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
from typing import Optional
|
||||
import pmb.config.pmaports
|
||||
from pmb.core.types import PmbArgs
|
||||
from pmb.types import PmbArgs
|
||||
|
||||
|
||||
def variables(args: PmbArgs, flavor, method):
|
||||
|
@ -99,7 +99,7 @@ def variables(args: PmbArgs, flavor, method):
|
|||
}
|
||||
|
||||
# Backwards compatibility with old mkinitfs (pma#660)
|
||||
pmaports_cfg = pmb.config.pmaports.read_config(args)
|
||||
pmaports_cfg = pmb.config.pmaports.read_config()
|
||||
if pmaports_cfg.get("supported_mkinitfs_without_flavors", False):
|
||||
vars["$FLAVOR"] = ""
|
||||
else:
|
||||
|
|
|
@ -6,12 +6,12 @@ from typing import List, Sequence
|
|||
|
||||
import pmb.chroot.run
|
||||
import pmb.config.pmaports
|
||||
from pmb.core.types import PathString, PmbArgs
|
||||
from pmb.types import PathString, PmbArgs
|
||||
import pmb.helpers.cli
|
||||
import pmb.helpers.run
|
||||
import pmb.helpers.run_core
|
||||
import pmb.parse.version
|
||||
|
||||
from pmb.core import get_context
|
||||
|
||||
def _prepare_fifo():
|
||||
"""Prepare the progress fifo for reading / writing.
|
||||
|
@ -24,8 +24,8 @@ def _prepare_fifo():
|
|||
path of the fifo as needed by cat to read from it (always
|
||||
relative to the host)
|
||||
"""
|
||||
pmb.helpers.run.root(["mkdir", "-p", pmb.config.work / "tmp"])
|
||||
fifo = fifo_outside = pmb.config.work / "tmp/apk_progress_fifo"
|
||||
pmb.helpers.run.root(["mkdir", "-p", get_context().config.work / "tmp"])
|
||||
fifo = fifo_outside = get_context().config.work / "tmp/apk_progress_fifo"
|
||||
if os.path.exists(fifo_outside):
|
||||
pmb.helpers.run.root(["rm", "-f", fifo_outside])
|
||||
pmb.helpers.run.root(["mkfifo", fifo_outside])
|
||||
|
@ -88,7 +88,7 @@ def apk_with_progress(command: Sequence[PathString]):
|
|||
log_msg)
|
||||
|
||||
|
||||
def check_outdated(args: PmbArgs, version_installed, action_msg):
|
||||
def check_outdated(version_installed, action_msg):
|
||||
"""Check if the provided alpine version is outdated.
|
||||
|
||||
This depends on the alpine mirrordir (edge, v3.12, ...) related to currently checked out
|
||||
|
@ -99,7 +99,7 @@ def check_outdated(args: PmbArgs, version_installed, action_msg):
|
|||
this
|
||||
:raises: RuntimeError if the version is outdated
|
||||
"""
|
||||
channel_cfg = pmb.config.pmaports.read_config_channel(args)
|
||||
channel_cfg = pmb.config.pmaports.read_config_channel()
|
||||
mirrordir_alpine = channel_cfg["mirrordir_alpine"]
|
||||
version_min = pmb.config.apk_tools_min_version[mirrordir_alpine]
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ import re
|
|||
import urllib.parse
|
||||
from typing import Dict, Optional
|
||||
|
||||
from pmb.core.types import PmbArgs
|
||||
from pmb.types import PmbArgs
|
||||
import pmb.helpers.file
|
||||
import pmb.helpers.http
|
||||
import pmb.helpers.pmaports
|
||||
|
@ -263,7 +263,7 @@ def upgrade(args: PmbArgs, pkgname, git=True, stable=True) -> None:
|
|||
# Initialize request headers
|
||||
init_req_headers()
|
||||
|
||||
package = pmb.helpers.pmaports.get(args, pkgname)
|
||||
package = pmb.helpers.pmaports.get(pkgname)
|
||||
# Run the correct function
|
||||
if "_git" in package["pkgver"]:
|
||||
if git:
|
||||
|
|
|
@ -4,7 +4,8 @@ import copy
|
|||
import os
|
||||
from pathlib import Path
|
||||
import pmb.config
|
||||
from pmb.core.types import PmbArgs
|
||||
from pmb.core.context import Context
|
||||
from pmb.types import PmbArgs
|
||||
import pmb.helpers.git
|
||||
import pmb.helpers.args
|
||||
|
||||
|
@ -32,7 +33,7 @@ import pmb.helpers.args
|
|||
Examples:
|
||||
args.aports ("$WORK/cache_git/pmaports", override with --aports)
|
||||
args.device ("samsung-i9100", "qemu-amd64" etc.)
|
||||
pmb.config.work ("/home/user/.local/var/pmbootstrap", override with --work)
|
||||
get_context().config.work ("/home/user/.local/var/pmbootstrap", override with --work)
|
||||
|
||||
3. Parsed configs
|
||||
Similar to the cache above, specific config files get parsed and added
|
||||
|
@ -46,28 +47,6 @@ import pmb.helpers.args
|
|||
"""
|
||||
|
||||
|
||||
def fix_mirrors_postmarketos(args: PmbArgs):
|
||||
"""Fix args.mirrors_postmarketos when it is supposed to be empty or the default value.
|
||||
|
||||
In pmb/parse/arguments.py, we set the -mp/--mirror-pmOS argument to
|
||||
action="append" and start off with an empty list. That way, users can
|
||||
specify multiple custom mirrors by specifying -mp multiple times on the
|
||||
command line. Here we fix the default and no mirrors case.
|
||||
|
||||
NOTE: we don't use nargs="+", because it does not play nicely with
|
||||
subparsers: <https://bugs.python.org/issue9338>
|
||||
"""
|
||||
# -mp not specified: use default mirrors
|
||||
if not args.mirrors_postmarketos:
|
||||
cfg = pmb.config.load(args)
|
||||
args.mirrors_postmarketos = \
|
||||
cfg["pmbootstrap"]["mirrors_postmarketos"].split(",")
|
||||
|
||||
# -mp="": use no postmarketOS mirrors (build everything locally)
|
||||
if args.mirrors_postmarketos == [""]:
|
||||
args.mirrors_postmarketos = []
|
||||
|
||||
|
||||
def check_pmaports_path(args: PmbArgs):
|
||||
"""Make sure that args.aports exists when it was overridden by --aports.
|
||||
|
||||
|
@ -79,28 +58,28 @@ def check_pmaports_path(args: PmbArgs):
|
|||
f" not exist: {args.aports}")
|
||||
|
||||
|
||||
def replace_placeholders(args: PmbArgs):
|
||||
"""Replace $WORK and ~ (for path variables) in variables from any config.
|
||||
# def replace_placeholders(args: PmbArgs):
|
||||
# """Replace $WORK and ~ (for path variables) in variables from any config.
|
||||
|
||||
(user's config file, default config settings or config parameters specified on commandline)
|
||||
"""
|
||||
# Replace $WORK
|
||||
for key, value in pmb.config.defaults.items():
|
||||
if key not in args:
|
||||
continue
|
||||
old = getattr(args, key)
|
||||
if isinstance(old, str):
|
||||
setattr(args, key, old.replace("$WORK", str(pmb.config.work)))
|
||||
# (user's config file, default config settings or config parameters specified on commandline)
|
||||
# """
|
||||
# # Replace $WORK
|
||||
# for key, value in pmb.config.defaults.items():
|
||||
# if key not in args:
|
||||
# continue
|
||||
# old = getattr(args, key)
|
||||
# if isinstance(old, str):
|
||||
# setattr(args, key, old.replace("$WORK", str(get_context().config.work)))
|
||||
|
||||
# Replace ~ (path variables only)
|
||||
for key in ["aports", "config", "work"]:
|
||||
if key in args:
|
||||
setattr(args, key, Path(getattr(args, key)).expanduser())
|
||||
# # Replace ~ (path variables only)
|
||||
# for key in ["aports", "config", "work"]:
|
||||
# if key in args:
|
||||
# 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(args))
|
||||
setattr(args, "deviceinfo", pmb.parse.deviceinfo())
|
||||
arch = args.deviceinfo["arch"]
|
||||
if (arch != pmb.config.arch_native and
|
||||
arch not in pmb.config.build_device_architectures):
|
||||
|
@ -111,20 +90,28 @@ def add_deviceinfo(args: PmbArgs):
|
|||
|
||||
def init(args: PmbArgs) -> PmbArgs:
|
||||
# Basic initialization
|
||||
fix_mirrors_postmarketos(args)
|
||||
pmb.config.merge_with_args(args)
|
||||
replace_placeholders(args)
|
||||
config = pmb.config.load(args)
|
||||
# pmb.config.merge_with_args(args)
|
||||
# replace_placeholders(args)
|
||||
|
||||
# Configure runtime context
|
||||
context = pmb.core.get_context()
|
||||
context = Context(config)
|
||||
context.command_timeout = args.timeout
|
||||
context.details_to_stdout = args.details_to_stdout
|
||||
context.sudo_timer = args.sudo_timer
|
||||
context.quiet = args.quiet
|
||||
context.offline = args.offline
|
||||
context.command = args.action
|
||||
context.cross = args.cross
|
||||
if args.mirrors_postmarketos:
|
||||
context.config.mirrors_postmarketos = args.mirrors_postmarketos
|
||||
if args.mirror_alpine:
|
||||
context.config.mirror_alpine = args.mirror_alpine
|
||||
if args.aports:
|
||||
print(f"Using pmaports from: {args.aports}")
|
||||
context.aports = args.aports
|
||||
context.config.aports = args.aports
|
||||
|
||||
# Initialize context
|
||||
pmb.core.set_context(context)
|
||||
|
||||
# Initialize logs (we could raise errors below)
|
||||
pmb.helpers.logging.init(args)
|
||||
|
@ -133,19 +120,22 @@ def init(args: PmbArgs) -> PmbArgs:
|
|||
check_pmaports_path(args)
|
||||
if args.action not in ["init", "checksum", "config", "bootimg_analyze", "log",
|
||||
"pull", "shutdown", "zap"]:
|
||||
pmb.config.pmaports.read_config(args)
|
||||
pmb.config.pmaports.read_config()
|
||||
add_deviceinfo(args)
|
||||
pmb.helpers.git.parse_channels_cfg()
|
||||
pmb.helpers.git.parse_channels_cfg(config.aports)
|
||||
context.device_arch = args.deviceinfo["arch"]
|
||||
|
||||
# Remove attributes from args so they don't get used by mistake
|
||||
delattr(args, "timeout")
|
||||
delattr(args, "details_to_stdout")
|
||||
delattr(args, "sudo_timer")
|
||||
delattr(args, "log")
|
||||
delattr(args, "quiet")
|
||||
delattr(args, "offline")
|
||||
delattr(args, "aports")
|
||||
delattr(args, "mirrors_postmarketos")
|
||||
delattr(args, "mirror_alpine")
|
||||
# args.work is deprecated!
|
||||
delattr(args, "work")
|
||||
|
||||
return args
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ import readline
|
|||
import sys
|
||||
|
||||
import pmb.config
|
||||
from pmb.core.types import PmbArgs
|
||||
from pmb.types import PmbArgs
|
||||
from pmb.core import get_context
|
||||
|
||||
|
||||
|
|
|
@ -3,18 +3,17 @@
|
|||
import os
|
||||
from pathlib import Path
|
||||
from typing import Optional
|
||||
from pmb.core.types import PmbArgs
|
||||
import pmb.parse
|
||||
from pmb.core import get_context
|
||||
|
||||
|
||||
def find_path(args: PmbArgs, codename: str, file='') -> Optional[Path]:
|
||||
def find_path(codename: str, file='') -> Optional[Path]:
|
||||
"""Find path to device APKBUILD under `device/*/device-`.
|
||||
|
||||
:param codename: device codename
|
||||
:param file: file to look for (e.g. APKBUILD or deviceinfo), may be empty
|
||||
:returns: path to APKBUILD
|
||||
"""
|
||||
g = list((args.aports / "device").glob(f"*/device-{codename}/{file}"))
|
||||
g = list((get_context().config.aports / "device").glob(f"*/device-{codename}/{file}"))
|
||||
if not g:
|
||||
return None
|
||||
|
||||
|
@ -25,7 +24,7 @@ def find_path(args: PmbArgs, codename: str, file='') -> Optional[Path]:
|
|||
return g[0]
|
||||
|
||||
|
||||
def list_codenames(args: PmbArgs, vendor=None, archived=True):
|
||||
def list_codenames(aports: Path, vendor=None, archived=True):
|
||||
"""Get all devices, for which aports are available.
|
||||
|
||||
:param vendor: vendor name to choose devices from, or None for all vendors
|
||||
|
@ -33,7 +32,7 @@ def list_codenames(args: PmbArgs, vendor=None, archived=True):
|
|||
:returns: ["first-device", "second-device", ...]
|
||||
"""
|
||||
ret = []
|
||||
for path in args.aports.glob("device/*/device-*"):
|
||||
for path in aports.glob("device/*/device-*"):
|
||||
if not archived and 'archived' in path.parts:
|
||||
continue
|
||||
device = os.path.basename(path).split("-", 1)[1]
|
||||
|
@ -42,30 +41,13 @@ def list_codenames(args: PmbArgs, vendor=None, archived=True):
|
|||
return ret
|
||||
|
||||
|
||||
def list_vendors(args: PmbArgs):
|
||||
def list_vendors(aports: Path):
|
||||
"""Get all device vendors, for which aports are available.
|
||||
|
||||
:returns: {"vendor1", "vendor2", ...}
|
||||
"""
|
||||
ret = set()
|
||||
for path in (args.aports / "device").glob("*/device-*"):
|
||||
for path in (aports / "device").glob("*/device-*"):
|
||||
vendor = path.name.split("-", 2)[1]
|
||||
ret.add(vendor)
|
||||
return ret
|
||||
|
||||
|
||||
def list_apkbuilds(args: PmbArgs):
|
||||
""":returns: { "first-device": {"pkgname": ..., "pkgver": ...}, ... }"""
|
||||
ret = {}
|
||||
for device in list_codenames(args):
|
||||
apkbuild_path = next(args.aports.glob(f"device/*/device-{device}/APKBUILD"))
|
||||
ret[device] = pmb.parse.apkbuild(apkbuild_path)
|
||||
return ret
|
||||
|
||||
|
||||
def list_deviceinfos(args: PmbArgs):
|
||||
""":returns: { "first-device": {"name": ..., "screen_width": ...}, ... }"""
|
||||
ret = {}
|
||||
for device in list_codenames(args):
|
||||
ret[device] = pmb.parse.deviceinfo(args, device)
|
||||
return ret
|
||||
|
|
|
@ -5,7 +5,7 @@ import os
|
|||
from pathlib import Path
|
||||
import time
|
||||
|
||||
from pmb.core.types import PmbArgs
|
||||
from pmb.types import PmbArgs
|
||||
import pmb.helpers.run
|
||||
import pmb.helpers.pmaports
|
||||
|
||||
|
@ -30,7 +30,7 @@ def replace_apkbuild(args: PmbArgs, pkgname, key, new, in_quotes=False):
|
|||
:param in_quotes: expect the value to be in quotation marks ("")
|
||||
"""
|
||||
# Read old value
|
||||
path = pmb.helpers.pmaports.find(args, pkgname) / "APKBUILD"
|
||||
path = pmb.helpers.pmaports.find(pkgname) / "APKBUILD"
|
||||
apkbuild = pmb.parse.apkbuild(path)
|
||||
old = apkbuild[key]
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@ import pmb.chroot.initfs
|
|||
import pmb.chroot.other
|
||||
import pmb.ci
|
||||
import pmb.config
|
||||
from pmb.core.types import PathString, PmbArgs
|
||||
from pmb.types import Config, PathString, PmbArgs
|
||||
import pmb.export
|
||||
import pmb.flasher
|
||||
import pmb.helpers.aportupgrade
|
||||
|
@ -37,7 +37,7 @@ import pmb.netboot
|
|||
import pmb.parse
|
||||
import pmb.qemu
|
||||
import pmb.sideload
|
||||
from pmb.core import ChrootType, Chroot
|
||||
from pmb.core import ChrootType, Chroot, get_context
|
||||
|
||||
|
||||
def _parse_flavor(args: PmbArgs, autoinstall=True):
|
||||
|
@ -62,7 +62,7 @@ def _parse_flavor(args: PmbArgs, autoinstall=True):
|
|||
|
||||
def _parse_suffix(args: PmbArgs) -> Chroot:
|
||||
if "rootfs" in args and args.rootfs:
|
||||
return Chroot(ChrootType.ROOTFS, args.device)
|
||||
return Chroot(ChrootType.ROOTFS, get_context().config.device)
|
||||
elif args.buildroot:
|
||||
if args.buildroot == "device":
|
||||
return Chroot.buildroot(args.deviceinfo["arch"])
|
||||
|
@ -122,10 +122,11 @@ def build(args: PmbArgs):
|
|||
pmb.helpers.repo_bootstrap.require_bootstrap(args, arch_package,
|
||||
f"build {package} for {arch_package}")
|
||||
|
||||
context = get_context()
|
||||
# Build all packages
|
||||
for package in args.packages:
|
||||
arch_package = args.arch or pmb.build.autodetect.arch(args, package)
|
||||
if not pmb.build.package(args, package, arch_package, force,
|
||||
if not pmb.build.package(context, package, arch_package, force,
|
||||
args.strict, src=src):
|
||||
logging.info("NOTE: Package '" + package + "' is up to date. Use"
|
||||
" 'pmbootstrap build " + package + " --force'"
|
||||
|
@ -169,11 +170,11 @@ def chroot(args: PmbArgs):
|
|||
raise RuntimeError("--xauth is only supported for native chroot.")
|
||||
|
||||
# apk: check minimum version, install packages
|
||||
pmb.chroot.apk.check_min_version(args, suffix)
|
||||
pmb.chroot.apk.check_min_version(suffix)
|
||||
if args.add:
|
||||
pmb.chroot.apk.install(args, args.add.split(","), suffix)
|
||||
pmb.chroot.apk.install(args.add.split(","), suffix)
|
||||
|
||||
pmb.chroot.init(args, suffix)
|
||||
pmb.chroot.init(suffix)
|
||||
|
||||
# Xauthority
|
||||
env = {}
|
||||
|
@ -198,11 +199,11 @@ def chroot(args: PmbArgs):
|
|||
if args.user:
|
||||
logging.info(f"({suffix}) % su pmos -c '" +
|
||||
" ".join(args.command) + "'")
|
||||
pmb.chroot.user(args, args.command, suffix, output=args.output,
|
||||
pmb.chroot.user(args.command, suffix, output=args.output,
|
||||
env=env)
|
||||
else:
|
||||
logging.info(f"({suffix}) % " + " ".join(args.command))
|
||||
pmb.chroot.root(args, args.command, suffix, output=args.output,
|
||||
pmb.chroot.root(args.command, suffix, output=args.output,
|
||||
env=env)
|
||||
|
||||
|
||||
|
@ -212,24 +213,27 @@ def config(args: PmbArgs):
|
|||
logging.info("NOTE: Valid config keys: " + ", ".join(keys))
|
||||
raise RuntimeError("Invalid config key: " + args.name)
|
||||
|
||||
cfg = pmb.config.load(args)
|
||||
config = pmb.config.load(args)
|
||||
if args.reset:
|
||||
if args.name is None:
|
||||
raise RuntimeError("config --reset requires a name to be given.")
|
||||
value = pmb.config.defaults[args.name]
|
||||
cfg["pmbootstrap"][args.name] = value
|
||||
def_value = getattr(Config(), args.name)
|
||||
setattr(config, args.name, def_value)
|
||||
logging.info(f"Config changed to default: {args.name}='{value}'")
|
||||
pmb.config.save(args, cfg)
|
||||
pmb.config.save(args.config, config)
|
||||
elif args.value is not None:
|
||||
cfg["pmbootstrap"][args.name] = args.value
|
||||
pmb.config.sanity_checks(args, cfg, False)
|
||||
setattr(config, args.name, args.value)
|
||||
pmb.config.sanity_checks(args, config, False)
|
||||
logging.info("Config changed: " + args.name + "='" + args.value + "'")
|
||||
pmb.config.save(args, cfg)
|
||||
pmb.config.save(args.config, config)
|
||||
elif args.name:
|
||||
value = cfg["pmbootstrap"].get(args.name, "")
|
||||
if hasattr(config, args.name):
|
||||
value = getattr(config, args.name)
|
||||
else:
|
||||
value = ""
|
||||
print(value)
|
||||
else:
|
||||
cfg.write(sys.stdout)
|
||||
print(open(args.config).read())
|
||||
|
||||
# Don't write the "Done" message
|
||||
pmb.helpers.logging.disable()
|
||||
|
@ -240,7 +244,7 @@ def repo_bootstrap(args: PmbArgs):
|
|||
|
||||
|
||||
def repo_missing(args: PmbArgs):
|
||||
missing = pmb.helpers.repo_missing.generate(args, args.arch, args.overview,
|
||||
missing = pmb.helpers.repo_missing.generate(args.arch, args.overview,
|
||||
args.package, args.built)
|
||||
print(json.dumps(missing, indent=4))
|
||||
|
||||
|
@ -344,7 +348,7 @@ def install(args: PmbArgs):
|
|||
args.build_pkgs_on_install = False
|
||||
|
||||
# Safest way to avoid installing local packages is having none
|
||||
if (pmb.config.work / "packages").glob("*"):
|
||||
if (get_context().config.work / "packages").glob("*"):
|
||||
raise ValueError("--no-local-pkgs specified, but locally built"
|
||||
" packages found. Consider 'pmbootstrap zap -p'"
|
||||
" to delete them.")
|
||||
|
@ -365,7 +369,7 @@ def export(args: PmbArgs):
|
|||
|
||||
def update(args: PmbArgs):
|
||||
existing_only = not args.non_existing
|
||||
if not pmb.helpers.repo.update(args, args.arch, True, existing_only):
|
||||
if not pmb.helpers.repo.update(args.arch, True, existing_only):
|
||||
logging.info("No APKINDEX files exist, so none have been updated."
|
||||
" The pmbootstrap command downloads the APKINDEX files on"
|
||||
" demand.")
|
||||
|
@ -430,7 +434,7 @@ def kconfig(args: PmbArgs):
|
|||
else:
|
||||
packages = [args.package]
|
||||
if not args.package:
|
||||
for pkg in pmb.helpers.pmaports.get_list(args):
|
||||
for pkg in pmb.helpers.pmaports.get_list():
|
||||
if pkg.startswith("linux-"):
|
||||
packages.append(pkg.split("linux-")[1])
|
||||
|
||||
|
@ -442,7 +446,7 @@ def kconfig(args: PmbArgs):
|
|||
if not args.force:
|
||||
pkgname = package if package.startswith("linux-") \
|
||||
else "linux-" + package
|
||||
aport = pmb.helpers.pmaports.find(args, pkgname)
|
||||
aport = pmb.helpers.pmaports.find(pkgname)
|
||||
apkbuild = pmb.parse.apkbuild(aport)
|
||||
if "!pmb:kconfigcheck" in apkbuild["options"]:
|
||||
skipped += 1
|
||||
|
@ -472,13 +476,13 @@ def deviceinfo_parse(args: PmbArgs):
|
|||
# Default to all devices
|
||||
devices = args.devices
|
||||
if not devices:
|
||||
devices = pmb.helpers.devices.list_codenames(args)
|
||||
devices = pmb.helpers.devices.list_codenames(get_context().config.aports)
|
||||
|
||||
# Iterate over all devices
|
||||
kernel = args.deviceinfo_parse_kernel
|
||||
for device in devices:
|
||||
print(f"{device}, with kernel={kernel}:")
|
||||
print(json.dumps(pmb.parse.deviceinfo(args, device, kernel), indent=4,
|
||||
print(json.dumps(pmb.parse.deviceinfo(device, kernel), indent=4,
|
||||
sort_keys=True))
|
||||
|
||||
|
||||
|
@ -486,12 +490,12 @@ def apkbuild_parse(args: PmbArgs):
|
|||
# Default to all packages
|
||||
packages: Sequence[str] = args.packages
|
||||
if not packages:
|
||||
packages = pmb.helpers.pmaports.get_list(args)
|
||||
packages = pmb.helpers.pmaports.get_list()
|
||||
|
||||
# Iterate over all packages
|
||||
for package in packages:
|
||||
print(package + ":")
|
||||
aport = pmb.helpers.pmaports.find(args, package)
|
||||
aport = pmb.helpers.pmaports.find(package)
|
||||
print(json.dumps(pmb.parse.apkbuild(aport), indent=4,
|
||||
sort_keys=True))
|
||||
|
||||
|
@ -512,7 +516,7 @@ def pkgrel_bump(args: PmbArgs):
|
|||
else:
|
||||
# Each package must exist
|
||||
for package in args.packages:
|
||||
pmb.helpers.pmaports.find(args, package)
|
||||
pmb.helpers.pmaports.find(package)
|
||||
|
||||
# Increase pkgrel
|
||||
for package in args.packages:
|
||||
|
@ -529,7 +533,7 @@ def aportupgrade(args: PmbArgs):
|
|||
else:
|
||||
# Each package must exist
|
||||
for package in args.packages:
|
||||
pmb.helpers.pmaports.find(args, package)
|
||||
pmb.helpers.pmaports.find(package)
|
||||
|
||||
# Check each package for a new version
|
||||
for package in args.packages:
|
||||
|
@ -551,9 +555,9 @@ def stats(args: PmbArgs):
|
|||
chroot = Chroot.buildroot(args.arch)
|
||||
|
||||
# Install ccache and display stats
|
||||
pmb.chroot.apk.install(args, ["ccache"], chroot)
|
||||
pmb.chroot.apk.install(["ccache"], chroot)
|
||||
logging.info(f"({chroot}) % ccache -s")
|
||||
pmb.chroot.user(args, ["ccache", "-s"], chroot, output="stdout")
|
||||
pmb.chroot.user(["ccache", "-s"], chroot, output="stdout")
|
||||
|
||||
|
||||
def work_migrate(args: PmbArgs):
|
||||
|
@ -581,7 +585,7 @@ def bootimg_analyze(args: PmbArgs):
|
|||
logging.info(tmp_output)
|
||||
|
||||
|
||||
def pull(args: PmbArgs):
|
||||
def pull():
|
||||
failed = []
|
||||
for repo in pmb.config.git_repos.keys():
|
||||
if pmb.helpers.git.pull(repo) < 0:
|
||||
|
@ -610,7 +614,7 @@ def pull(args: PmbArgs):
|
|||
def lint(args: PmbArgs):
|
||||
packages: Sequence[str] = args.packages
|
||||
if not packages:
|
||||
packages = pmb.helpers.pmaports.get_list(args)
|
||||
packages = pmb.helpers.pmaports.get_list()
|
||||
|
||||
pmb.helpers.lint.check(args, packages)
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@ import pmb.helpers.pmaports
|
|||
import pmb.helpers.run
|
||||
|
||||
|
||||
def get_path(context: Context, name_repo):
|
||||
def get_path(name_repo: str):
|
||||
"""Get the path to the repository.
|
||||
|
||||
The path is either the default one in the work dir, or a user-specified one in args.
|
||||
|
@ -24,8 +24,8 @@ def get_path(context: Context, name_repo):
|
|||
:returns: full path to repository
|
||||
"""
|
||||
if name_repo == "pmaports":
|
||||
return context.aports
|
||||
return pmb.config.work / "cache_git" / name_repo
|
||||
return get_context().config.aports
|
||||
return get_context().config.work / "cache_git" / name_repo
|
||||
|
||||
|
||||
def clone(name_repo):
|
||||
|
@ -40,7 +40,7 @@ def clone(name_repo):
|
|||
if name_repo not in pmb.config.git_repos:
|
||||
raise ValueError("No git repository configured for " + name_repo)
|
||||
|
||||
path = get_path(get_context(), name_repo)
|
||||
path = get_path(name_repo)
|
||||
if not os.path.exists(path):
|
||||
# Build git command
|
||||
url = pmb.config.git_repos[name_repo][0]
|
||||
|
@ -49,7 +49,7 @@ def clone(name_repo):
|
|||
|
||||
# Create parent dir and clone
|
||||
logging.info("Clone git repository: " + url)
|
||||
os.makedirs(pmb.config.work / "cache_git", exist_ok=True)
|
||||
os.makedirs(get_context().config.work / "cache_git", exist_ok=True)
|
||||
pmb.helpers.run.user(command, output="stdout")
|
||||
|
||||
# FETCH_HEAD does not exist after initial clone. Create it, so
|
||||
|
@ -59,7 +59,7 @@ def clone(name_repo):
|
|||
open(fetch_head, "w").close()
|
||||
|
||||
|
||||
def rev_parse(path, revision="HEAD", extra_args: list = []):
|
||||
def rev_parse(path: Path, revision="HEAD", extra_args: list = []):
|
||||
"""Run "git rev-parse" in a specific repository dir.
|
||||
|
||||
:param path: to the git repository
|
||||
|
@ -84,29 +84,29 @@ def can_fast_forward(path, branch_upstream, branch="HEAD"):
|
|||
raise RuntimeError("Unexpected exit code from git: " + str(ret))
|
||||
|
||||
|
||||
def clean_worktree(path):
|
||||
def clean_worktree(path: Path):
|
||||
"""Check if there are not any modified files in the git dir."""
|
||||
command = ["git", "status", "--porcelain"]
|
||||
return pmb.helpers.run.user_output(command, path) == ""
|
||||
|
||||
|
||||
def get_upstream_remote(context: Context, name_repo):
|
||||
def get_upstream_remote(aports: Path):
|
||||
"""Find the remote, which matches the git URL from the config.
|
||||
|
||||
Usually "origin", but the user may have set up their git repository differently.
|
||||
"""
|
||||
name_repo = aports.parts[-1]
|
||||
urls = pmb.config.git_repos[name_repo]
|
||||
path = get_path(context, name_repo)
|
||||
command = ["git", "remote", "-v"]
|
||||
output = pmb.helpers.run.user_output(command, path)
|
||||
output = pmb.helpers.run.user_output(command, aports)
|
||||
for line in output.split("\n"):
|
||||
if any(u in line for u in urls):
|
||||
return line.split("\t", 1)[0]
|
||||
raise RuntimeError("{}: could not find remote name for any URL '{}' in git"
|
||||
" repository: {}".format(name_repo, urls, path))
|
||||
" repository: {}".format(name_repo, urls, aports))
|
||||
|
||||
|
||||
def parse_channels_cfg():
|
||||
def parse_channels_cfg(aports: Path):
|
||||
"""Parse channels.cfg from pmaports.git, origin/master branch.
|
||||
|
||||
Reference: https://postmarketos.org/channels.cfg
|
||||
|
@ -123,13 +123,11 @@ def parse_channels_cfg():
|
|||
if pmb.helpers.other.cache[cache_key]:
|
||||
return pmb.helpers.other.cache[cache_key]
|
||||
|
||||
context = get_context()
|
||||
|
||||
# Read with configparser
|
||||
cfg = configparser.ConfigParser()
|
||||
remote = get_upstream_remote(context, "pmaports")
|
||||
remote = get_upstream_remote(aports)
|
||||
command = ["git", "show", f"{remote}/master:channels.cfg"]
|
||||
stdout = pmb.helpers.run.user_output(command, context.aports,
|
||||
stdout = pmb.helpers.run.user_output(command, aports,
|
||||
check=False)
|
||||
try:
|
||||
cfg.read_string(stdout)
|
||||
|
@ -162,7 +160,7 @@ def parse_channels_cfg():
|
|||
return ret
|
||||
|
||||
|
||||
def get_branches_official(name_repo):
|
||||
def get_branches_official(repo: Path):
|
||||
"""Get all branches that point to official release channels.
|
||||
|
||||
:returns: list of supported branches, e.g. ["master", "3.11"]
|
||||
|
@ -170,17 +168,17 @@ def get_branches_official(name_repo):
|
|||
# This functions gets called with pmaports and aports_upstream, because
|
||||
# both are displayed in "pmbootstrap status". But it only makes sense
|
||||
# to display pmaports there, related code will be refactored soon (#1903).
|
||||
if name_repo != "pmaports":
|
||||
if repo.parts[-1] != "pmaports":
|
||||
return ["master"]
|
||||
|
||||
channels_cfg = parse_channels_cfg()
|
||||
channels_cfg = parse_channels_cfg(repo)
|
||||
ret = []
|
||||
for channel, channel_data in channels_cfg["channels"].items():
|
||||
ret.append(channel_data["branch_pmaports"])
|
||||
return ret
|
||||
|
||||
|
||||
def pull(name_repo):
|
||||
def pull(repo_name: str):
|
||||
"""Check if on official branch and essentially try ``git pull --ff-only``.
|
||||
|
||||
Instead of really doing ``git pull --ff-only``, do it in multiple steps
|
||||
|
@ -189,18 +187,17 @@ def pull(name_repo):
|
|||
|
||||
:returns: integer, >= 0 on success, < 0 on error
|
||||
"""
|
||||
branches_official = get_branches_official(name_repo)
|
||||
context = get_context()
|
||||
repo = get_path(repo_name)
|
||||
branches_official = get_branches_official(repo)
|
||||
|
||||
# Skip if repo wasn't cloned
|
||||
path = get_path(context, name_repo)
|
||||
if not os.path.exists(path):
|
||||
logging.debug(name_repo + ": repo was not cloned, skipping pull!")
|
||||
if not os.path.exists(repo):
|
||||
logging.debug(repo_name + ": repo was not cloned, skipping pull!")
|
||||
return 1
|
||||
|
||||
# Skip if not on official branch
|
||||
branch = rev_parse(path, extra_args=["--abbrev-ref"])
|
||||
msg_start = "{} (branch: {}):".format(name_repo, branch)
|
||||
branch = rev_parse(repo, extra_args=["--abbrev-ref"])
|
||||
msg_start = "{} (branch: {}):".format(repo_name, branch)
|
||||
if branch not in branches_official:
|
||||
logging.warning("{} not on one of the official branches ({}), skipping"
|
||||
" pull!"
|
||||
|
@ -208,13 +205,13 @@ def pull(name_repo):
|
|||
return -1
|
||||
|
||||
# Skip if workdir is not clean
|
||||
if not clean_worktree(path):
|
||||
if not clean_worktree(repo):
|
||||
logging.warning(msg_start + " workdir is not clean, skipping pull!")
|
||||
return -2
|
||||
|
||||
# Skip if branch is tracking different remote
|
||||
branch_upstream = get_upstream_remote(context, name_repo) + "/" + branch
|
||||
remote_ref = rev_parse(path, branch + "@{u}", ["--abbrev-ref"])
|
||||
branch_upstream = get_upstream_remote(repo) + "/" + branch
|
||||
remote_ref = rev_parse(repo, branch + "@{u}", ["--abbrev-ref"])
|
||||
if remote_ref != branch_upstream:
|
||||
logging.warning("{} is tracking unexpected remote branch '{}' instead"
|
||||
" of '{}'".format(msg_start, remote_ref,
|
||||
|
@ -223,16 +220,16 @@ def pull(name_repo):
|
|||
|
||||
# Fetch (exception on failure, meaning connection to server broke)
|
||||
logging.info(msg_start + " git pull --ff-only")
|
||||
if not context.offline:
|
||||
pmb.helpers.run.user(["git", "fetch"], path)
|
||||
if not get_context().offline:
|
||||
pmb.helpers.run.user(["git", "fetch"], repo)
|
||||
|
||||
# Skip if already up to date
|
||||
if rev_parse(path, branch) == rev_parse(path, branch_upstream):
|
||||
if rev_parse(repo, branch) == rev_parse(repo, branch_upstream):
|
||||
logging.info(msg_start + " already up to date")
|
||||
return 2
|
||||
|
||||
# Skip if we can't fast-forward
|
||||
if not can_fast_forward(path, branch_upstream):
|
||||
if not can_fast_forward(repo, branch_upstream):
|
||||
logging.warning("{} can't fast-forward to {}, looks like you changed"
|
||||
" the git history of your local branch. Skipping pull!"
|
||||
"".format(msg_start, branch_upstream))
|
||||
|
@ -241,21 +238,21 @@ def pull(name_repo):
|
|||
# Fast-forward now (should not fail due to checks above, so it's fine to
|
||||
# throw an exception on error)
|
||||
command = ["git", "merge", "--ff-only", branch_upstream]
|
||||
pmb.helpers.run.user(command, path, "stdout")
|
||||
pmb.helpers.run.user(command, repo, "stdout")
|
||||
return 0
|
||||
|
||||
|
||||
def get_topdir(path: Path):
|
||||
def get_topdir(repo: Path):
|
||||
"""Get top-dir of git repo.
|
||||
|
||||
: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"],
|
||||
path, output_return=True, check=False).rstrip()
|
||||
repo, output_return=True, check=False).rstrip()
|
||||
|
||||
|
||||
def get_files(path):
|
||||
def get_files(repo: Path):
|
||||
"""Get all files inside a git repository, that are either already in the git tree or are not in gitignore.
|
||||
|
||||
Do not list deleted files. To be used for creating a tarball of the git repository.
|
||||
|
@ -265,12 +262,12 @@ def get_files(path):
|
|||
:returns: all files in a git repository as list, relative to path
|
||||
"""
|
||||
ret = []
|
||||
files = pmb.helpers.run.user_output(["git", "ls-files"], path).split("\n")
|
||||
files = pmb.helpers.run.user_output(["git", "ls-files"], repo).split("\n")
|
||||
files += pmb.helpers.run.user_output(["git", "ls-files",
|
||||
"--exclude-standard", "--other"],
|
||||
path).split("\n")
|
||||
repo).split("\n")
|
||||
for file in files:
|
||||
if os.path.exists(f"{path}/{file}"):
|
||||
if os.path.exists(f"{repo}/{file}"):
|
||||
ret += [file]
|
||||
|
||||
return ret
|
||||
|
|
|
@ -8,7 +8,8 @@ from pathlib import Path
|
|||
import shutil
|
||||
import urllib.request
|
||||
|
||||
from pmb.core.types import PmbArgs
|
||||
from pmb.core import get_context
|
||||
from pmb.types import PmbArgs
|
||||
import pmb.helpers.run
|
||||
|
||||
def cache_file(prefix: str, url: str) -> Path:
|
||||
|
@ -16,7 +17,7 @@ def cache_file(prefix: str, url: str) -> Path:
|
|||
return Path(f"{prefix}_{hashlib.sha256(url.encode('utf-8')).hexdigest()}")
|
||||
|
||||
|
||||
def download(args: PmbArgs, url, prefix, cache=True, loglevel=logging.INFO,
|
||||
def download(url, prefix, cache=True, loglevel=logging.INFO,
|
||||
allow_404=False):
|
||||
"""Download a file to disk.
|
||||
|
||||
|
@ -34,18 +35,19 @@ def download(args: PmbArgs, url, prefix, cache=True, loglevel=logging.INFO,
|
|||
:returns: path to the downloaded file in the cache or None on 404
|
||||
"""
|
||||
# Create cache folder
|
||||
if not os.path.exists(pmb.config.work / "cache_http"):
|
||||
pmb.helpers.run.user(["mkdir", "-p", pmb.config.work / "cache_http"])
|
||||
context = get_context()
|
||||
if not os.path.exists(context.config.work / "cache_http"):
|
||||
pmb.helpers.run.user(["mkdir", "-p", context.config.work / "cache_http"])
|
||||
|
||||
# Check if file exists in cache
|
||||
path = pmb.config.work / "cache_http" / cache_file(prefix, url)
|
||||
path = context.config.work / "cache_http" / cache_file(prefix, url)
|
||||
if os.path.exists(path):
|
||||
if cache:
|
||||
return path
|
||||
pmb.helpers.run.user(["rm", path])
|
||||
|
||||
# Offline and not cached
|
||||
if args.offline:
|
||||
if context.offline:
|
||||
raise RuntimeError("File not found in cache and offline flag is"
|
||||
f" enabled: {url}")
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ import os
|
|||
import pmb.chroot
|
||||
import pmb.chroot.apk
|
||||
import pmb.build
|
||||
from pmb.core.types import PmbArgs
|
||||
from pmb.types import PmbArgs
|
||||
import pmb.helpers.run
|
||||
import pmb.helpers.pmaports
|
||||
|
||||
|
@ -17,7 +17,7 @@ def check(args: PmbArgs, pkgnames):
|
|||
|
||||
:param pkgnames: Names of the packages to lint
|
||||
"""
|
||||
pmb.chroot.apk.install(args, ["atools"])
|
||||
pmb.chroot.apk.install(["atools"])
|
||||
|
||||
# Mount pmaports.git inside the chroot so that we don't have to copy the
|
||||
# package folders
|
||||
|
@ -28,7 +28,7 @@ def check(args: PmbArgs, pkgnames):
|
|||
# root
|
||||
apkbuilds = []
|
||||
for pkgname in pkgnames:
|
||||
aport = pmb.helpers.pmaports.find(args, pkgname)
|
||||
aport = pmb.helpers.pmaports.find(pkgname)
|
||||
if not (aport / "APKBUILD").exists():
|
||||
raise ValueError(f"Path does not contain an APKBUILD file: {aport}")
|
||||
relpath = os.path.relpath(aport, args.aports)
|
||||
|
@ -40,7 +40,7 @@ def check(args: PmbArgs, pkgnames):
|
|||
pkgstr = ", ".join(pkgnames)
|
||||
logging.info(f"(native) linting {pkgstr} with apkbuild-lint")
|
||||
options = pmb.config.apkbuild_custom_valid_options
|
||||
return pmb.chroot.root(args, ["apkbuild-lint"] + apkbuilds,
|
||||
return pmb.chroot.root(["apkbuild-lint"] + apkbuilds,
|
||||
check=False, output="stdout",
|
||||
output_return=True,
|
||||
working_dir=pmaports,
|
||||
|
|
|
@ -7,7 +7,7 @@ from typing import TextIO
|
|||
import pmb.config
|
||||
from pmb.core import get_context
|
||||
from pmb.core.context import Context
|
||||
from pmb.core.types import PmbArgs
|
||||
from pmb.types import PmbArgs
|
||||
|
||||
logfd: TextIO
|
||||
|
||||
|
@ -108,7 +108,7 @@ def add_verbose_log_level():
|
|||
def init(args: PmbArgs):
|
||||
"""Set log format and add the log file descriptor to logfd, add the verbose log level."""
|
||||
global logfd
|
||||
context = pmb.core.get_context()
|
||||
context = get_context()
|
||||
# Set log file descriptor (logfd)
|
||||
if context.details_to_stdout:
|
||||
logfd = sys.stdout
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
import os
|
||||
from pathlib import Path, PurePath
|
||||
from typing import List
|
||||
from pmb.core.types import PmbArgs
|
||||
from pmb.types import PmbArgs
|
||||
import pmb.helpers
|
||||
from pmb.core import Chroot
|
||||
import pmb.helpers.run
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
# Copyright 2023 Oliver Smith
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
from pmb.core import get_context
|
||||
from pmb.helpers import logging
|
||||
import os
|
||||
from pathlib import Path
|
||||
|
@ -7,7 +8,7 @@ import re
|
|||
import pmb.chroot
|
||||
import pmb.config
|
||||
import pmb.config.init
|
||||
from pmb.core.types import PmbArgs
|
||||
from pmb.types import PmbArgs
|
||||
import pmb.helpers.pmaports
|
||||
import pmb.helpers.run
|
||||
from typing import Dict, Any
|
||||
|
@ -15,7 +16,7 @@ from typing import Dict, Any
|
|||
from typing import Any, Dict
|
||||
|
||||
|
||||
def folder_size(args: PmbArgs, path: Path):
|
||||
def folder_size(path: Path):
|
||||
"""Run `du` to calculate the size of a folder.
|
||||
|
||||
(this is less code and faster than doing the same task in pure Python)
|
||||
|
@ -47,7 +48,7 @@ def check_grsec():
|
|||
" patchset. This is not supported.")
|
||||
|
||||
|
||||
def check_binfmt_misc(args):
|
||||
def check_binfmt_misc():
|
||||
"""Check if the 'binfmt_misc' module is loaded.
|
||||
|
||||
This is done by checking, if /proc/sys/fs/binfmt_misc/ exists.
|
||||
|
@ -71,16 +72,17 @@ def check_binfmt_misc(args):
|
|||
raise RuntimeError(f"Failed to set up binfmt_misc, see: {link}")
|
||||
|
||||
|
||||
def migrate_success(args: PmbArgs, version):
|
||||
def migrate_success(work: Path, version):
|
||||
logging.info("Migration to version " + str(version) + " done")
|
||||
with open(pmb.config.work / "version", "w") as handle:
|
||||
with open(work / "version", "w") as handle:
|
||||
handle.write(str(version) + "\n")
|
||||
|
||||
|
||||
def migrate_work_folder(args: PmbArgs):
|
||||
# Read current version
|
||||
context = get_context()
|
||||
current = 0
|
||||
path = pmb.config.work / "version"
|
||||
path = context.config.work / "version"
|
||||
if os.path.exists(path):
|
||||
with open(path, "r") as f:
|
||||
current = int(f.read().rstrip())
|
||||
|
@ -100,18 +102,18 @@ def migrate_work_folder(args: PmbArgs):
|
|||
logging.info("* Building chroots have a different username (#709)")
|
||||
logging.info("Migration will do the following:")
|
||||
logging.info("* Zap your chroots")
|
||||
logging.info(f"* Adjust '{pmb.config.work / 'config_abuild/abuild.conf'}'")
|
||||
logging.info(f"* Adjust '{context.config.work / 'config_abuild/abuild.conf'}'")
|
||||
if not pmb.helpers.cli.confirm(args):
|
||||
raise RuntimeError("Aborted.")
|
||||
|
||||
# Zap and update abuild.conf
|
||||
pmb.chroot.zap(args, False)
|
||||
conf = pmb.config.work / "config_abuild/abuild.conf"
|
||||
conf = context.config.work / "config_abuild/abuild.conf"
|
||||
if os.path.exists(conf):
|
||||
pmb.helpers.run.root(["sed", "-i",
|
||||
"s./home/user/./home/pmos/.g", conf])
|
||||
# Update version file
|
||||
migrate_success(args, 1)
|
||||
migrate_success(context.config.work, 1)
|
||||
current = 1
|
||||
|
||||
# 1 => 2
|
||||
|
@ -120,7 +122,7 @@ def migrate_work_folder(args: PmbArgs):
|
|||
logging.info("Changelog:")
|
||||
logging.info("* Fix: cache_distfiles was writable for everyone")
|
||||
logging.info("Migration will do the following:")
|
||||
logging.info(f"* Fix permissions of '{pmb.config.work / 'cache_distfiles'}'")
|
||||
logging.info(f"* Fix permissions of '{context.config.work / 'cache_distfiles'}'")
|
||||
if not pmb.helpers.cli.confirm(args):
|
||||
raise RuntimeError("Aborted.")
|
||||
|
||||
|
@ -129,8 +131,8 @@ def migrate_work_folder(args: PmbArgs):
|
|||
for cmd in [["chown", "-R", "root:abuild", dir],
|
||||
["chmod", "-R", "664", dir],
|
||||
["chmod", "a+X", dir]]:
|
||||
pmb.chroot.root(args, cmd)
|
||||
migrate_success(args, 2)
|
||||
pmb.chroot.root(cmd)
|
||||
migrate_success(context.config.work, 2)
|
||||
current = 2
|
||||
|
||||
if current == 2:
|
||||
|
@ -146,12 +148,12 @@ def migrate_work_folder(args: PmbArgs):
|
|||
pmb.chroot.zap(args, False)
|
||||
|
||||
# Update version file
|
||||
migrate_success(args, 3)
|
||||
migrate_success(context.config.work, 3)
|
||||
current = 3
|
||||
|
||||
if current == 3:
|
||||
# Ask for confirmation
|
||||
path = pmb.config.work / "cache_git"
|
||||
path = context.config.work / "cache_git"
|
||||
logging.info("Changelog:")
|
||||
logging.info("* pmbootstrap clones repositories with host system's")
|
||||
logging.info(" 'git' instead of using it from an Alpine chroot")
|
||||
|
@ -170,7 +172,7 @@ def migrate_work_folder(args: PmbArgs):
|
|||
os.makedirs(path, 0o700, True)
|
||||
|
||||
# Update version file
|
||||
migrate_success(args, 4)
|
||||
migrate_success(context.config.work, 4)
|
||||
current = 4
|
||||
|
||||
if current == 4:
|
||||
|
@ -187,23 +189,23 @@ def migrate_work_folder(args: PmbArgs):
|
|||
pmb.chroot.zap(args, False)
|
||||
|
||||
# Move packages to edge subdir
|
||||
edge_path = pmb.config.work / "packages/edge"
|
||||
edge_path = context.config.work / "packages/edge"
|
||||
pmb.helpers.run.root(["mkdir", "-p", edge_path])
|
||||
for arch in pmb.config.build_device_architectures:
|
||||
old_path = pmb.config.work / "packages" / arch
|
||||
old_path = context.config.work / "packages" / arch
|
||||
new_path = edge_path / arch
|
||||
if old_path.exists():
|
||||
if new_path.exists():
|
||||
raise RuntimeError(f"Won't move '{old_path}' to"
|
||||
f" '{new_path}', destination already"
|
||||
" exists! Consider 'pmbootstrap zap -p'"
|
||||
f" to delete '{pmb.config.work}/packages'.")
|
||||
f" to delete '{context.config.work}/packages'.")
|
||||
pmb.helpers.run.root(["mv", old_path, new_path])
|
||||
pmb.helpers.run.root(["chown", pmb.config.chroot_uid_user,
|
||||
edge_path])
|
||||
|
||||
# Update version file
|
||||
migrate_success(args, 5)
|
||||
migrate_success(context.config.work, 5)
|
||||
current = 5
|
||||
|
||||
if current == 5:
|
||||
|
@ -214,7 +216,7 @@ def migrate_work_folder(args: PmbArgs):
|
|||
logging.info("Migration will do the following:")
|
||||
logging.info("* Zap your chroots")
|
||||
logging.info("* Adjust subdirs of your locally built packages dir:")
|
||||
logging.info(f" {pmb.config.work}/packages")
|
||||
logging.info(f" {context.config.work}/packages")
|
||||
logging.info(" stable => v20.05")
|
||||
logging.info(" stable-next => v21.03")
|
||||
if not pmb.helpers.cli.confirm(args):
|
||||
|
@ -225,13 +227,13 @@ def migrate_work_folder(args: PmbArgs):
|
|||
pmb.chroot.zap(args, False)
|
||||
|
||||
# Migrate
|
||||
packages_dir = f"{pmb.config.work}/packages"
|
||||
packages_dir = f"{context.config.work}/packages"
|
||||
for old, new in pmb.config.pmaports_channels_legacy.items():
|
||||
if os.path.exists(f"{packages_dir}/{old}"):
|
||||
pmb.helpers.run.root(["mv", old, new], packages_dir)
|
||||
|
||||
# Update version file
|
||||
migrate_success(args, 6)
|
||||
migrate_success(context.config.work, 6)
|
||||
current = 6
|
||||
|
||||
# Can't migrate, user must delete it
|
||||
|
@ -239,7 +241,7 @@ def migrate_work_folder(args: PmbArgs):
|
|||
raise RuntimeError("Sorry, we can't migrate that automatically. Please"
|
||||
" run 'pmbootstrap shutdown', then delete your"
|
||||
" current work folder manually ('sudo rm -rf "
|
||||
f"{pmb.config.work}') and start over with 'pmbootstrap"
|
||||
f"{context.config.work}') and start over with 'pmbootstrap"
|
||||
" init'. All your binary packages and caches will"
|
||||
" be lost.")
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@ import copy
|
|||
from typing import Any, Dict
|
||||
from pmb.helpers import logging
|
||||
|
||||
from pmb.core.types import PmbArgs
|
||||
from pmb.types import PmbArgs
|
||||
import pmb.helpers.pmaports
|
||||
import pmb.helpers.repo
|
||||
|
||||
|
@ -25,7 +25,7 @@ def remove_operators(package):
|
|||
return package
|
||||
|
||||
|
||||
def get(args: PmbArgs, pkgname, arch, replace_subpkgnames=False, must_exist=True):
|
||||
def get(pkgname, arch, replace_subpkgnames=False, must_exist=True):
|
||||
"""Find a package in pmaports, and as fallback in the APKINDEXes of the binary packages.
|
||||
|
||||
:param pkgname: package name (e.g. "hello-world")
|
||||
|
@ -59,7 +59,7 @@ def get(args: PmbArgs, pkgname, arch, replace_subpkgnames=False, must_exist=True
|
|||
|
||||
# Find in pmaports
|
||||
ret: Dict[str, Any] = {}
|
||||
pmaport = pmb.helpers.pmaports.get(args, pkgname, False)
|
||||
pmaport = pmb.helpers.pmaports.get(pkgname, False)
|
||||
if pmaport:
|
||||
ret = {"arch": pmaport["arch"],
|
||||
"depends": pmb.build._package.get_depends(args, pmaport),
|
||||
|
@ -69,8 +69,8 @@ def get(args: PmbArgs, pkgname, arch, replace_subpkgnames=False, must_exist=True
|
|||
|
||||
# Find in APKINDEX (given arch)
|
||||
if not ret or not pmb.helpers.pmaports.check_arches(ret["arch"], arch):
|
||||
pmb.helpers.repo.update(args, arch)
|
||||
ret_repo = pmb.parse.apkindex.package(args, pkgname, arch, False)
|
||||
pmb.helpers.repo.update(arch)
|
||||
ret_repo = pmb.parse.apkindex.package(pkgname, arch, False)
|
||||
|
||||
# Save as result if there was no pmaport, or if the pmaport can not be
|
||||
# built for the given arch, but there is a binary package for that arch
|
||||
|
@ -80,10 +80,10 @@ def get(args: PmbArgs, pkgname, arch, replace_subpkgnames=False, must_exist=True
|
|||
|
||||
# Find in APKINDEX (other arches)
|
||||
if not ret:
|
||||
pmb.helpers.repo.update(args)
|
||||
pmb.helpers.repo.update()
|
||||
for arch_i in pmb.config.build_device_architectures:
|
||||
if arch_i != arch:
|
||||
ret = pmb.parse.apkindex.package(args, pkgname, arch_i, False)
|
||||
ret = pmb.parse.apkindex.package(pkgname, arch_i, False)
|
||||
if ret:
|
||||
break
|
||||
|
||||
|
@ -100,7 +100,7 @@ def get(args: PmbArgs, pkgname, arch, replace_subpkgnames=False, must_exist=True
|
|||
if replace_subpkgnames:
|
||||
depends_new = []
|
||||
for depend in ret["depends"]:
|
||||
depend_data = get(args, depend, arch, must_exist=False)
|
||||
depend_data = get(depend, arch, must_exist=False)
|
||||
if not depend_data:
|
||||
logging.warning(f"WARNING: {pkgname}: failed to resolve"
|
||||
f" dependency '{depend}'")
|
||||
|
@ -131,7 +131,7 @@ def get(args: PmbArgs, pkgname, arch, replace_subpkgnames=False, must_exist=True
|
|||
" could not find this package in any APKINDEX!")
|
||||
|
||||
|
||||
def depends_recurse(args: PmbArgs, pkgname, arch):
|
||||
def depends_recurse(pkgname, arch):
|
||||
"""Recursively resolve all of the package's dependencies.
|
||||
|
||||
:param pkgname: name of the package (e.g. "device-samsung-i9100")
|
||||
|
@ -151,7 +151,7 @@ def depends_recurse(args: PmbArgs, pkgname, arch):
|
|||
ret = []
|
||||
while len(queue):
|
||||
pkgname_queue = queue.pop()
|
||||
package = get(args, pkgname_queue, arch)
|
||||
package = get(pkgname_queue, arch)
|
||||
|
||||
# Add its depends to the queue
|
||||
for depend in package["depends"]:
|
||||
|
@ -170,7 +170,7 @@ def depends_recurse(args: PmbArgs, pkgname, arch):
|
|||
return ret
|
||||
|
||||
|
||||
def check_arch(args: PmbArgs, pkgname, arch, binary=True):
|
||||
def check_arch(pkgname, arch, binary=True):
|
||||
"""Check if a package be built for a certain architecture, or is there a binary package for it.
|
||||
|
||||
:param pkgname: name of the package
|
||||
|
@ -181,7 +181,7 @@ def check_arch(args: PmbArgs, pkgname, arch, binary=True):
|
|||
:returns: True when the package can be built, or there is a binary package, False otherwise
|
||||
"""
|
||||
if binary:
|
||||
arches = get(args, pkgname, arch)["arch"]
|
||||
arches = get(pkgname, arch)["arch"]
|
||||
else:
|
||||
arches = pmb.helpers.pmaports.get(args, pkgname)["arch"]
|
||||
arches = pmb.helpers.pmaports.get(pkgname)["arch"]
|
||||
return pmb.helpers.pmaports.check_arches(arches, arch)
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
from pmb.helpers import logging
|
||||
|
||||
from pmb.core.types import PmbArgs
|
||||
from pmb.types import PmbArgs
|
||||
import pmb.helpers.file
|
||||
import pmb.helpers.pmaports
|
||||
import pmb.helpers.repo
|
||||
|
@ -18,7 +18,7 @@ def package(args: PmbArgs, pkgname, reason="", dry=False):
|
|||
:param dry: don't modify the APKBUILD, just print the message
|
||||
"""
|
||||
# Current and new pkgrel
|
||||
path = pmb.helpers.pmaports.find(args, pkgname) / "APKBUILD"
|
||||
path = pmb.helpers.pmaports.find(pkgname) / "APKBUILD"
|
||||
apkbuild = pmb.parse.apkbuild(path)
|
||||
pkgrel = int(apkbuild["pkgrel"])
|
||||
pkgrel_new = pkgrel + 1
|
||||
|
@ -84,7 +84,7 @@ def auto_apkindex_package(args: PmbArgs, arch, aport, apk, dry=False):
|
|||
# Ignore conflict-dependencies
|
||||
continue
|
||||
|
||||
providers = pmb.parse.apkindex.providers(args, depend, arch,
|
||||
providers = pmb.parse.apkindex.providers(depend, arch,
|
||||
must_exist=False)
|
||||
if providers == {}:
|
||||
# We're only interested in missing depends starting with "so:"
|
||||
|
|
|
@ -12,7 +12,7 @@ from pmb.helpers import logging
|
|||
from pathlib import Path
|
||||
from typing import Optional, Sequence, Dict
|
||||
|
||||
from pmb.core.types import PmbArgs
|
||||
from pmb.types import PmbArgs
|
||||
import pmb.parse
|
||||
|
||||
def _find_apkbuilds() -> Dict[str, Path]:
|
||||
|
@ -23,7 +23,7 @@ def _find_apkbuilds() -> Dict[str, Path]:
|
|||
return apkbuilds
|
||||
|
||||
apkbuilds = {}
|
||||
for apkbuild in glob.iglob(f"{get_context().aports}/**/*/APKBUILD", recursive=True):
|
||||
for apkbuild in glob.iglob(f"{get_context().config.aports}/**/*/APKBUILD", recursive=True):
|
||||
package = Path(apkbuild).parent.name
|
||||
if package in apkbuilds:
|
||||
raise RuntimeError(f"Package {package} found in multiple aports "
|
||||
|
@ -199,7 +199,7 @@ def find_optional(package: str) -> Optional[Path]:
|
|||
return None
|
||||
|
||||
|
||||
def get(args: PmbArgs, pkgname, must_exist=True, subpackages=True):
|
||||
def get(pkgname, must_exist=True, subpackages=True):
|
||||
"""Find and parse an APKBUILD file.
|
||||
|
||||
Run 'pmbootstrap apkbuild_parse hello-world' for a full output example.
|
||||
|
|
|
@ -9,12 +9,13 @@ See also:
|
|||
"""
|
||||
import os
|
||||
import hashlib
|
||||
from pmb.core import get_context
|
||||
from pmb.helpers import logging
|
||||
from pathlib import Path
|
||||
from typing import List
|
||||
|
||||
import pmb.config.pmaports
|
||||
from pmb.core.types import PmbArgs
|
||||
from pmb.types import PmbArgs
|
||||
import pmb.helpers.http
|
||||
import pmb.helpers.run
|
||||
import pmb.helpers.other
|
||||
|
@ -47,7 +48,7 @@ def apkindex_hash(url: str, length: int=8) -> Path:
|
|||
return Path(f"APKINDEX.{ret}.tar.gz")
|
||||
|
||||
|
||||
def urls(args: PmbArgs, user_repository=True, postmarketos_mirror=True, alpine=True):
|
||||
def urls(user_repository=True, postmarketos_mirror=True, alpine=True):
|
||||
"""Get a list of repository URLs, as they are in /etc/apk/repositories.
|
||||
|
||||
:param user_repository: add /mnt/pmbootstrap/packages
|
||||
|
@ -60,18 +61,19 @@ def urls(args: PmbArgs, user_repository=True, postmarketos_mirror=True, alpine=T
|
|||
|
||||
# Get mirrordirs from channels.cfg (postmarketOS mirrordir is the same as
|
||||
# the pmaports branch of the channel, no need to make it more complicated)
|
||||
channel_cfg = pmb.config.pmaports.read_config_channel(args)
|
||||
channel_cfg = pmb.config.pmaports.read_config_channel()
|
||||
mirrordir_pmos = channel_cfg["branch_pmaports"]
|
||||
mirrordir_alpine = channel_cfg["mirrordir_alpine"]
|
||||
|
||||
# Local user repository (for packages compiled with pmbootstrap)
|
||||
if user_repository:
|
||||
channel = pmb.config.pmaports.read_config(args)["channel"]
|
||||
ret.append(str(pmb.config.work / "packages" / channel))
|
||||
channel = pmb.config.pmaports.read_config()["channel"]
|
||||
ret.append(str(get_context().config.work / "packages" / channel))
|
||||
|
||||
context = get_context()
|
||||
# Upstream postmarketOS binary repository
|
||||
if postmarketos_mirror:
|
||||
for mirror in args.mirrors_postmarketos:
|
||||
for mirror in context.config.mirrors_postmarketos:
|
||||
# Remove "master" mirrordir to avoid breakage until bpo is adjusted
|
||||
# (build.postmarketos.org#63) and to give potential other users of
|
||||
# this flag a heads up.
|
||||
|
@ -88,12 +90,12 @@ def urls(args: PmbArgs, user_repository=True, postmarketos_mirror=True, alpine=T
|
|||
if mirrordir_alpine == "edge":
|
||||
directories.append("testing")
|
||||
for dir in directories:
|
||||
ret.append(f"{args.mirror_alpine}{mirrordir_alpine}/{dir}")
|
||||
ret.append(f"{context.config.mirror_alpine}{mirrordir_alpine}/{dir}")
|
||||
|
||||
return ret
|
||||
|
||||
|
||||
def apkindex_files(args: PmbArgs, arch=None, user_repository=True, pmos=True,
|
||||
def apkindex_files(arch=None, user_repository=True, pmos=True,
|
||||
alpine=True) -> List[Path]:
|
||||
"""Get a list of outside paths to all resolved APKINDEX.tar.gz files for a specific arch.
|
||||
|
||||
|
@ -109,17 +111,17 @@ def apkindex_files(args: PmbArgs, arch=None, user_repository=True, pmos=True,
|
|||
ret = []
|
||||
# Local user repository (for packages compiled with pmbootstrap)
|
||||
if user_repository:
|
||||
channel = pmb.config.pmaports.read_config(args)["channel"]
|
||||
ret = [pmb.config.work / "packages" / channel / arch / "APKINDEX.tar.gz"]
|
||||
channel = pmb.config.pmaports.read_config()["channel"]
|
||||
ret = [get_context().config.work / "packages" / channel / arch / "APKINDEX.tar.gz"]
|
||||
|
||||
# Resolve the APKINDEX.$HASH.tar.gz files
|
||||
for url in urls(args, False, pmos, alpine):
|
||||
ret.append(pmb.config.work / f"cache_apk_{arch}" / apkindex_hash(url))
|
||||
for url in urls(False, pmos, alpine):
|
||||
ret.append(get_context().config.work / f"cache_apk_{arch}" / apkindex_hash(url))
|
||||
|
||||
return ret
|
||||
|
||||
|
||||
def update(args: PmbArgs, arch=None, force=False, existing_only=False):
|
||||
def update(arch=None, force=False, existing_only=False):
|
||||
"""Download the APKINDEX files for all URLs depending on the architectures.
|
||||
|
||||
:param arch: * one Alpine architecture name ("x86_64", "armhf", ...)
|
||||
|
@ -132,7 +134,7 @@ def update(args: PmbArgs, arch=None, force=False, existing_only=False):
|
|||
"""
|
||||
# Skip in offline mode, only show once
|
||||
cache_key = "pmb.helpers.repo.update"
|
||||
if args.offline:
|
||||
if get_context().offline:
|
||||
if not pmb.helpers.other.cache[cache_key]["offline_msg_shown"]:
|
||||
logging.info("NOTE: skipping package index update (offline mode)")
|
||||
pmb.helpers.other.cache[cache_key]["offline_msg_shown"] = True
|
||||
|
@ -148,11 +150,11 @@ def update(args: PmbArgs, arch=None, force=False, existing_only=False):
|
|||
# outdated_arches: ["armhf", "x86_64", ... ]
|
||||
outdated = {}
|
||||
outdated_arches = []
|
||||
for url in urls(args, False):
|
||||
for url in urls(False):
|
||||
for arch in architectures:
|
||||
# APKINDEX file name from the URL
|
||||
url_full = url + "/" + arch + "/APKINDEX.tar.gz"
|
||||
cache_apk_outside = pmb.config.work / f"cache_apk_{arch}"
|
||||
cache_apk_outside = get_context().config.work / f"cache_apk_{arch}"
|
||||
apkindex = cache_apk_outside / f"APKINDEX.{apkindex_hash(url)}.tar.gz"
|
||||
|
||||
# Find update reason, possibly skip non-existing or known 404 files
|
||||
|
@ -186,8 +188,8 @@ def update(args: PmbArgs, arch=None, force=False, existing_only=False):
|
|||
|
||||
# Download and move to right location
|
||||
for (i, (url, target)) in enumerate(outdated.items()):
|
||||
pmb.helpers.cli.progress_print(args, i / len(outdated))
|
||||
temp = pmb.helpers.http.download(args, url, "APKINDEX", False,
|
||||
pmb.helpers.cli.progress_print(i / len(outdated))
|
||||
temp = pmb.helpers.http.download(url, "APKINDEX", False,
|
||||
logging.DEBUG, True)
|
||||
if not temp:
|
||||
pmb.helpers.other.cache[cache_key]["404"].append(url)
|
||||
|
@ -196,12 +198,12 @@ def update(args: PmbArgs, arch=None, force=False, existing_only=False):
|
|||
if not os.path.exists(target_folder):
|
||||
pmb.helpers.run.root(["mkdir", "-p", target_folder])
|
||||
pmb.helpers.run.root(["cp", temp, target])
|
||||
pmb.helpers.cli.progress_flush(args)
|
||||
pmb.helpers.cli.progress_flush()
|
||||
|
||||
return True
|
||||
|
||||
|
||||
def alpine_apkindex_path(args: PmbArgs, repo="main", arch=None):
|
||||
def alpine_apkindex_path(repo="main", arch=None):
|
||||
"""Get the path to a specific Alpine APKINDEX file on disk and download it if necessary.
|
||||
|
||||
:param repo: Alpine repository name (e.g. "main")
|
||||
|
@ -214,10 +216,10 @@ def alpine_apkindex_path(args: PmbArgs, repo="main", arch=None):
|
|||
|
||||
# Download the file
|
||||
arch = arch or pmb.config.arch_native
|
||||
update(args, arch)
|
||||
update(arch)
|
||||
|
||||
# Find it on disk
|
||||
channel_cfg = pmb.config.pmaports.read_config_channel(args)
|
||||
repo_link = f"{args.mirror_alpine}{channel_cfg['mirrordir_alpine']}/{repo}"
|
||||
cache_folder = pmb.config.work / (f"cache_apk_{arch}")
|
||||
channel_cfg = pmb.config.pmaports.read_config_channel()
|
||||
repo_link = f"{get_context().config.mirror_alpine}{channel_cfg['mirrordir_alpine']}/{repo}"
|
||||
cache_folder = get_context().config.work / (f"cache_apk_{arch}")
|
||||
return cache_folder / apkindex_hash(repo_link)
|
||||
|
|
|
@ -6,7 +6,8 @@ import glob
|
|||
|
||||
import pmb.config.pmaports
|
||||
import pmb.helpers.repo
|
||||
from pmb.core.types import PmbArgs
|
||||
from pmb.types import PmbArgs
|
||||
from pmb.core import get_context
|
||||
|
||||
|
||||
progress_done = 0
|
||||
|
@ -25,7 +26,7 @@ def get_arch(args: PmbArgs):
|
|||
|
||||
|
||||
def check_repo_arg(args: PmbArgs):
|
||||
cfg = pmb.config.pmaports.read_config_repos(args)
|
||||
cfg = pmb.config.pmaports.read_config_repos()
|
||||
repo = args.repository
|
||||
|
||||
if repo in cfg:
|
||||
|
@ -41,8 +42,8 @@ def check_repo_arg(args: PmbArgs):
|
|||
|
||||
|
||||
def check_existing_pkgs(args: PmbArgs, arch):
|
||||
channel = pmb.config.pmaports.read_config(args)["channel"]
|
||||
path = pmb.config.work / "packages" / channel / arch
|
||||
channel = pmb.config.pmaports.read_config()["channel"]
|
||||
path = get_context().config.work / "packages" / channel / arch
|
||||
|
||||
if glob.glob(f"{path}/*"):
|
||||
logging.info(f"Packages path: {path}")
|
||||
|
@ -57,7 +58,7 @@ def check_existing_pkgs(args: PmbArgs, arch):
|
|||
|
||||
|
||||
def get_steps(args: PmbArgs):
|
||||
cfg = pmb.config.pmaports.read_config_repos(args)
|
||||
cfg = pmb.config.pmaports.read_config_repos()
|
||||
prev_step = 0
|
||||
ret = {}
|
||||
|
||||
|
@ -132,11 +133,11 @@ def run_steps(args: PmbArgs, steps, arch, chroot: Chroot):
|
|||
if chroot != Chroot.native():
|
||||
log_progress(f"initializing native chroot (merge /usr: {usr_merge.name})")
|
||||
# Native chroot needs pmOS binary package repo for cross compilers
|
||||
pmb.chroot.init(args, Chroot.native(), usr_merge)
|
||||
pmb.chroot.init(Chroot.native(), usr_merge)
|
||||
|
||||
log_progress(f"initializing {chroot} chroot (merge /usr: {usr_merge.name})")
|
||||
# Initialize without pmOS binary package repo
|
||||
pmb.chroot.init(args, chroot, usr_merge, postmarketos_mirror=False)
|
||||
pmb.chroot.init(chroot, usr_merge, postmarketos_mirror=False)
|
||||
|
||||
for package in get_packages(bootstrap_line):
|
||||
log_progress(f"building {package}")
|
||||
|
@ -181,9 +182,9 @@ def require_bootstrap(args: PmbArgs, arch, trigger_str):
|
|||
:param arch: for which architecture
|
||||
:param trigger_str: message for the user to understand what caused this
|
||||
"""
|
||||
if pmb.config.other.is_systemd_selected(args):
|
||||
pmb.helpers.repo.update(args, arch)
|
||||
pkg = pmb.parse.apkindex.package(args, "postmarketos-base-systemd",
|
||||
if pmb.config.other.is_systemd_selected(get_context().config):
|
||||
pmb.helpers.repo.update(arch)
|
||||
pkg = pmb.parse.apkindex.package("postmarketos-base-systemd",
|
||||
arch, False)
|
||||
if not pkg:
|
||||
require_bootstrap_error("systemd", arch, trigger_str)
|
||||
|
|
|
@ -3,12 +3,12 @@
|
|||
from pmb.helpers import logging
|
||||
|
||||
import pmb.build
|
||||
from pmb.core.types import PmbArgs
|
||||
from pmb.types import PmbArgs
|
||||
import pmb.helpers.package
|
||||
import pmb.helpers.pmaports
|
||||
|
||||
|
||||
def filter_missing_packages(args: PmbArgs, arch, pkgnames):
|
||||
def filter_missing_packages(arch, pkgnames):
|
||||
"""Create a subset of pkgnames with missing or outdated binary packages.
|
||||
|
||||
:param arch: architecture (e.g. "armhf")
|
||||
|
@ -17,15 +17,15 @@ def filter_missing_packages(args: PmbArgs, arch, pkgnames):
|
|||
"""
|
||||
ret = []
|
||||
for pkgname in pkgnames:
|
||||
binary = pmb.parse.apkindex.package(args, pkgname, arch, False)
|
||||
binary = pmb.parse.apkindex.package(pkgname, arch, False)
|
||||
must_exist = False if binary else True
|
||||
pmaport = pmb.helpers.pmaports.get(args, pkgname, must_exist)
|
||||
if pmaport and pmb.build.is_necessary(args, arch, pmaport):
|
||||
pmaport = pmb.helpers.pmaports.get(pkgname, must_exist)
|
||||
if pmaport and pmb.build.is_necessary(arch, pmaport):
|
||||
ret.append(pkgname)
|
||||
return ret
|
||||
|
||||
|
||||
def filter_aport_packages(args: PmbArgs, arch, pkgnames):
|
||||
def filter_aport_packages(pkgnames):
|
||||
"""Create a subset of pkgnames where each one has an aport.
|
||||
|
||||
:param arch: architecture (e.g. "armhf")
|
||||
|
@ -34,12 +34,12 @@ def filter_aport_packages(args: PmbArgs, arch, pkgnames):
|
|||
"""
|
||||
ret = []
|
||||
for pkgname in pkgnames:
|
||||
if pmb.helpers.pmaports.find_optional(args, pkgname):
|
||||
if pmb.helpers.pmaports.find_optional(pkgname):
|
||||
ret += [pkgname]
|
||||
return ret
|
||||
|
||||
|
||||
def filter_arch_packages(args: PmbArgs, arch, pkgnames):
|
||||
def filter_arch_packages(arch, pkgnames):
|
||||
"""Create a subset of pkgnames with packages removed that can not be built for a certain arch.
|
||||
|
||||
:param arch: architecture (e.g. "armhf")
|
||||
|
@ -48,12 +48,12 @@ def filter_arch_packages(args: PmbArgs, arch, pkgnames):
|
|||
"""
|
||||
ret = []
|
||||
for pkgname in pkgnames:
|
||||
if pmb.helpers.package.check_arch(args, pkgname, arch, False):
|
||||
if pmb.helpers.package.check_arch(pkgname, arch, False):
|
||||
ret += [pkgname]
|
||||
return ret
|
||||
|
||||
|
||||
def get_relevant_packages(args: PmbArgs, arch, pkgname=None, built=False):
|
||||
def get_relevant_packages(arch, pkgname=None, built=False):
|
||||
"""Get all packages that can be built for the architecture in question.
|
||||
|
||||
:param arch: architecture (e.g. "armhf")
|
||||
|
@ -63,20 +63,20 @@ def get_relevant_packages(args: PmbArgs, arch, pkgname=None, built=False):
|
|||
["devicepkg-dev", "hello-world", "osk-sdl"]
|
||||
"""
|
||||
if pkgname:
|
||||
if not pmb.helpers.package.check_arch(args, pkgname, arch, False):
|
||||
if not pmb.helpers.package.check_arch(pkgname, arch, False):
|
||||
raise RuntimeError(pkgname + " can't be built for " + arch + ".")
|
||||
ret = pmb.helpers.package.depends_recurse(args, pkgname, arch)
|
||||
ret = pmb.helpers.package.depends_recurse(pkgname, arch)
|
||||
else:
|
||||
ret = pmb.helpers.pmaports.get_list(args)
|
||||
ret = filter_arch_packages(args, arch, ret)
|
||||
ret = pmb.helpers.pmaports.get_list()
|
||||
ret = filter_arch_packages(arch, ret)
|
||||
if built:
|
||||
ret = filter_aport_packages(args, arch, ret)
|
||||
ret = filter_aport_packages(ret)
|
||||
if not len(ret):
|
||||
logging.info("NOTE: no aport found for any package in the"
|
||||
" dependency tree, it seems they are all provided by"
|
||||
" upstream (Alpine).")
|
||||
else:
|
||||
ret = filter_missing_packages(args, arch, ret)
|
||||
ret = filter_missing_packages(arch, ret)
|
||||
if not len(ret):
|
||||
logging.info("NOTE: all relevant packages are up to date, use"
|
||||
" --built to include the ones that have already been"
|
||||
|
@ -87,7 +87,7 @@ def get_relevant_packages(args: PmbArgs, arch, pkgname=None, built=False):
|
|||
return ret
|
||||
|
||||
|
||||
def generate_output_format(args: PmbArgs, arch, pkgnames):
|
||||
def generate_output_format(arch, pkgnames):
|
||||
"""Generate the detailed output format.
|
||||
|
||||
:param arch: architecture
|
||||
|
@ -105,15 +105,15 @@ def generate_output_format(args: PmbArgs, arch, pkgnames):
|
|||
"""
|
||||
ret = []
|
||||
for pkgname in pkgnames:
|
||||
entry = pmb.helpers.package.get(args, pkgname, arch, True)
|
||||
entry = pmb.helpers.package.get(pkgname, arch, True)
|
||||
ret += [{"pkgname": entry["pkgname"],
|
||||
"repo": pmb.helpers.pmaports.get_repo(args, pkgname),
|
||||
"repo": pmb.helpers.pmaports.get_repo(pkgname),
|
||||
"version": entry["version"],
|
||||
"depends": entry["depends"]}]
|
||||
return ret
|
||||
|
||||
|
||||
def generate(args: PmbArgs, arch, overview, pkgname=None, built=False):
|
||||
def generate(arch, overview, pkgname=None, built=False):
|
||||
"""Get packages that need to be built, with all their dependencies.
|
||||
|
||||
:param arch: architecture (e.g. "armhf")
|
||||
|
@ -129,9 +129,9 @@ def generate(args: PmbArgs, arch, overview, pkgname=None, built=False):
|
|||
"".format(packages_str, arch))
|
||||
|
||||
# Order relevant packages
|
||||
ret = get_relevant_packages(args, arch, pkgname, built)
|
||||
ret = get_relevant_packages(arch, pkgname, built)
|
||||
|
||||
# Output format
|
||||
if overview:
|
||||
return ret
|
||||
return generate_output_format(args, arch, ret)
|
||||
return generate_output_format(arch, ret)
|
||||
|
|
|
@ -5,7 +5,7 @@ from pathlib import Path
|
|||
import subprocess
|
||||
import pmb.helpers.run_core
|
||||
from typing import Any, Dict, List, Optional, Sequence
|
||||
from pmb.core.types import Env, PathString, PmbArgs
|
||||
from pmb.types import Env, PathString, PmbArgs
|
||||
|
||||
|
||||
def user(cmd: Sequence[PathString], working_dir: Optional[Path] = None, output: str = "log", output_return: bool = False,
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
import fcntl
|
||||
from pmb.core import get_context
|
||||
from pmb.core.types import PathString, Env
|
||||
from pmb.types import PathString, Env
|
||||
from pmb.helpers import logging
|
||||
import os
|
||||
from pathlib import Path
|
||||
|
|
|
@ -3,7 +3,8 @@
|
|||
import pmb.config
|
||||
import pmb.config.workdir
|
||||
import pmb.helpers.git
|
||||
from pmb.core.types import PmbArgs
|
||||
from pmb.types import Config, PmbArgs
|
||||
from pmb.core import get_context
|
||||
from typing import List, Tuple
|
||||
|
||||
|
||||
|
@ -15,8 +16,8 @@ def print_status_line(key: str, value: str):
|
|||
print(f"{key.ljust(padding)} {value}")
|
||||
|
||||
|
||||
def print_channel(args: PmbArgs) -> None:
|
||||
pmaports_cfg = pmb.config.pmaports.read_config(args)
|
||||
def print_channel(config: Config) -> None:
|
||||
pmaports_cfg = pmb.config.pmaports.read_config()
|
||||
channel = pmaports_cfg["channel"]
|
||||
|
||||
# Get branch name (if on branch) or current commit
|
||||
|
@ -32,28 +33,29 @@ def print_channel(args: PmbArgs) -> None:
|
|||
print_status_line("Channel", value)
|
||||
|
||||
|
||||
def print_device(args: PmbArgs) -> None:
|
||||
def print_device(args: PmbArgs, config: Config) -> None:
|
||||
kernel = ""
|
||||
if pmb.parse._apkbuild.kernels(args, args.device):
|
||||
kernel = f", kernel: {args.kernel}"
|
||||
if pmb.parse._apkbuild.kernels(config.device):
|
||||
kernel = f", kernel: {config.kernel}"
|
||||
|
||||
value = f"{args.device} ({args.deviceinfo['arch']}{kernel})"
|
||||
value = f"{config.device} ({args.deviceinfo['arch']}{kernel})"
|
||||
print_status_line("Device", value)
|
||||
|
||||
|
||||
def print_ui(args: PmbArgs) -> None:
|
||||
print_status_line("UI", args.ui)
|
||||
def print_ui(config: Config) -> None:
|
||||
print_status_line("UI", config.ui)
|
||||
|
||||
|
||||
def print_systemd(args: PmbArgs) -> None:
|
||||
yesno, reason = pmb.config.other.systemd_selected_str(args)
|
||||
def print_systemd(config: Config) -> None:
|
||||
yesno, reason = pmb.config.other.systemd_selected_str(config)
|
||||
print_status_line("systemd", f"{yesno} ({reason})")
|
||||
|
||||
|
||||
def print_status(args: PmbArgs) -> None:
|
||||
""" :param details: if True, print each passing check instead of a summary
|
||||
:returns: True if all checks passed, False otherwise """
|
||||
print_channel(args)
|
||||
print_device(args)
|
||||
print_ui(args)
|
||||
print_systemd(args)
|
||||
config = get_context().config
|
||||
print_channel(config)
|
||||
print_device(args, config)
|
||||
print_ui(config)
|
||||
print_systemd(config)
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
import os
|
||||
import glob
|
||||
from pmb.core import get_context
|
||||
from pmb.core.types import PmbArgs
|
||||
from pmb.types import PmbArgs
|
||||
import pmb.helpers.pmaports
|
||||
import pmb.helpers.package
|
||||
import pmb.parse
|
||||
|
@ -19,7 +19,7 @@ def list_ui(args: PmbArgs, arch):
|
|||
" customization. The \"console\" UI should be selected if"
|
||||
" a graphical UI is not desired.")]
|
||||
context = get_context() # noqa: F821
|
||||
for path in sorted(context.aports.glob("main/postmarketos-ui-*")):
|
||||
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):
|
||||
|
@ -27,10 +27,10 @@ def list_ui(args: PmbArgs, arch):
|
|||
return ret
|
||||
|
||||
|
||||
def check_option(args: PmbArgs, ui, option):
|
||||
def check_option(ui, option):
|
||||
"""
|
||||
Check if an option, such as pmb:systemd, is inside an UI's APKBUILD.
|
||||
"""
|
||||
pkgname = f"postmarketos-ui-{ui}"
|
||||
apkbuild = pmb.helpers.pmaports.get(args, pkgname, subpackages=False)
|
||||
apkbuild = pmb.helpers.pmaports.get(pkgname, subpackages=False)
|
||||
return option in apkbuild["options"]
|
||||
|
|
|
@ -9,13 +9,14 @@ import sys
|
|||
from typing import Dict, List, Optional, Sequence, TypedDict
|
||||
from pathlib import Path
|
||||
|
||||
import pmb.build
|
||||
import pmb.chroot
|
||||
import pmb.chroot.apk
|
||||
import pmb.chroot.other
|
||||
import pmb.chroot.initfs
|
||||
import pmb.config
|
||||
import pmb.config.pmaports
|
||||
from pmb.core.types import PartitionLayout, PmbArgs
|
||||
from pmb.types import Config, PartitionLayout, PmbArgs
|
||||
import pmb.helpers.devices
|
||||
from pmb.helpers.mount import mount_device_rootfs
|
||||
import pmb.helpers.run
|
||||
|
@ -24,7 +25,7 @@ import pmb.install.blockdevice
|
|||
import pmb.install.recovery
|
||||
import pmb.install.ui
|
||||
import pmb.install
|
||||
from pmb.core import Chroot, ChrootType
|
||||
from pmb.core import Chroot, ChrootType, get_context
|
||||
|
||||
# Keep track of the packages we already visited in get_recommends() to avoid
|
||||
# infinite recursion
|
||||
|
@ -32,7 +33,7 @@ get_recommends_visited: List[str] = []
|
|||
get_selected_providers_visited: List[str] = []
|
||||
|
||||
|
||||
def get_subpartitions_size(args: PmbArgs, chroot: Chroot):
|
||||
def get_subpartitions_size(chroot: Chroot):
|
||||
"""
|
||||
Calculate the size of the boot and root subpartition.
|
||||
|
||||
|
@ -40,18 +41,19 @@ def get_subpartitions_size(args: PmbArgs, chroot: Chroot):
|
|||
:returns: (boot, root) the size of the boot and root
|
||||
partition as integer in MiB
|
||||
"""
|
||||
boot = int(args.boot_size)
|
||||
config = get_context().config
|
||||
boot = int(config.boot_size)
|
||||
|
||||
# Estimate root partition size, then add some free space. The size
|
||||
# calculation is not as trivial as one may think, and depending on the
|
||||
# file system etc it seems to be just impossible to get it right.
|
||||
root = pmb.helpers.other.folder_size(args, chroot.path) / 1024
|
||||
root = pmb.helpers.other.folder_size(chroot.path) / 1024
|
||||
root *= 1.20
|
||||
root += 50 + int(args.extra_space)
|
||||
root += 50 + int(config.extra_space)
|
||||
return (boot, root)
|
||||
|
||||
|
||||
def get_nonfree_packages(args: PmbArgs, device):
|
||||
def get_nonfree_packages(device):
|
||||
"""
|
||||
Get any legacy non-free subpackages in the APKBUILD.
|
||||
Also see: https://postmarketos.org/edge/2024/02/15/default-nonfree-fw/
|
||||
|
@ -60,7 +62,7 @@ def get_nonfree_packages(args: PmbArgs, device):
|
|||
["device-nokia-n900-nonfree-firmware"]
|
||||
"""
|
||||
# Read subpackages
|
||||
device_path = pmb.helpers.devices.find_path(args, device, 'APKBUILD')
|
||||
device_path = pmb.helpers.devices.find_path(device, 'APKBUILD')
|
||||
if not device_path:
|
||||
raise RuntimeError(f"Device package not found for {device}")
|
||||
|
||||
|
@ -134,15 +136,15 @@ def copy_files_from_chroot(args: PmbArgs, chroot: Chroot):
|
|||
|
||||
# Update or copy all files
|
||||
if args.rsync:
|
||||
pmb.chroot.apk.install(args, ["rsync"], Chroot.native())
|
||||
pmb.chroot.apk.install(["rsync"], Chroot.native())
|
||||
rsync_flags = "-a"
|
||||
if args.verbose:
|
||||
rsync_flags += "vP"
|
||||
pmb.chroot.root(args, ["rsync", rsync_flags, "--delete"] + folders +
|
||||
pmb.chroot.root(["rsync", rsync_flags, "--delete"] + folders +
|
||||
["/mnt/install/"], working_dir=mountpoint)
|
||||
pmb.chroot.root(args, ["rm", "-rf", "/mnt/install/home"])
|
||||
pmb.chroot.root(["rm", "-rf", "/mnt/install/home"])
|
||||
else:
|
||||
pmb.chroot.root(args, ["cp", "-a"] + folders + ["/mnt/install/"],
|
||||
pmb.chroot.root(["cp", "-a"] + folders + ["/mnt/install/"],
|
||||
working_dir=mountpoint)
|
||||
|
||||
|
||||
|
@ -174,7 +176,7 @@ def configure_apk(args: PmbArgs):
|
|||
|
||||
# Official keys + local keys
|
||||
if args.install_local_pkgs:
|
||||
keys_dir = pmb.config.work / "config_apk_keys"
|
||||
keys_dir = get_context().config.work / "config_apk_keys"
|
||||
|
||||
# Copy over keys
|
||||
rootfs = (Chroot.native() / "mnt/install")
|
||||
|
@ -194,7 +196,7 @@ def configure_apk(args: PmbArgs):
|
|||
pmb.helpers.run.user(["cat", rootfs / "etc/apk/repositories"])
|
||||
|
||||
|
||||
def set_user(args: PmbArgs):
|
||||
def set_user(config: Config):
|
||||
"""
|
||||
Create user with UID 10000 if it doesn't exist.
|
||||
Usually the ID for the first user created is 1000, but higher ID is
|
||||
|
@ -202,21 +204,21 @@ def set_user(args: PmbArgs):
|
|||
this was done to avoid conflict with Android UIDs/GIDs, but pmOS has since
|
||||
dropped support for hybris/Halium.
|
||||
"""
|
||||
chroot = Chroot.rootfs(args.device)
|
||||
if not pmb.chroot.user_exists(args, args.user, chroot):
|
||||
pmb.chroot.root(args, ["adduser", "-D", "-u", "10000", args.user],
|
||||
chroot = Chroot.rootfs(config.device)
|
||||
if not pmb.chroot.user_exists(config.user, chroot):
|
||||
pmb.chroot.root(["adduser", "-D", "-u", "10000", config.user],
|
||||
chroot)
|
||||
|
||||
pmaports_cfg = pmb.config.pmaports.read_config(args)
|
||||
pmaports_cfg = pmb.config.pmaports.read_config()
|
||||
groups = []
|
||||
groups += pmaports_cfg.get("install_user_groups",
|
||||
"audio,input,netdev,plugdev,video,wheel").split(",")
|
||||
groups += pmb.install.ui.get_groups(args)
|
||||
groups += pmb.install.ui.get_groups(config)
|
||||
|
||||
for group in groups:
|
||||
pmb.chroot.root(args, ["addgroup", "-S", group], chroot,
|
||||
pmb.chroot.root(["addgroup", "-S", group], chroot,
|
||||
check=False)
|
||||
pmb.chroot.root(args, ["addgroup", args.user, group], chroot)
|
||||
pmb.chroot.root(["addgroup", config.user, group], chroot)
|
||||
|
||||
|
||||
def setup_login_chpasswd_user_from_arg(args: PmbArgs, chroot: Chroot):
|
||||
|
@ -237,7 +239,7 @@ def setup_login_chpasswd_user_from_arg(args: PmbArgs, chroot: Chroot):
|
|||
with open(path_outside, "w", encoding="utf-8") as handle:
|
||||
handle.write(f"{args.user}:{args.password}")
|
||||
|
||||
pmb.chroot.root(args, ["sh", "-c", f"cat {shlex.quote(path)} | chpasswd"],
|
||||
pmb.chroot.root(["sh", "-c", f"cat {shlex.quote(path)} | chpasswd"],
|
||||
chroot)
|
||||
|
||||
os.unlink(path_outside)
|
||||
|
@ -251,7 +253,7 @@ def is_root_locked(args: PmbArgs, chroot: Chroot):
|
|||
|
||||
:param suffix: either rootfs_{args.device} or installer_{args.device}
|
||||
"""
|
||||
shadow_root = pmb.chroot.root(args, ["grep", "^root:!:", "/etc/shadow"],
|
||||
shadow_root = pmb.chroot.root(["grep", "^root:!:", "/etc/shadow"],
|
||||
chroot, output_return=True, check=False)
|
||||
return shadow_root.startswith("root:!:")
|
||||
|
||||
|
@ -272,7 +274,7 @@ def setup_login(args: PmbArgs, chroot: Chroot):
|
|||
else:
|
||||
while True:
|
||||
try:
|
||||
pmb.chroot.root(args, ["passwd", args.user], chroot,
|
||||
pmb.chroot.root(["passwd", args.user], chroot,
|
||||
output="interactive")
|
||||
break
|
||||
except RuntimeError:
|
||||
|
@ -284,17 +286,17 @@ def setup_login(args: PmbArgs, chroot: Chroot):
|
|||
logging.debug(f"({chroot}) root is already locked")
|
||||
else:
|
||||
logging.debug(f"({chroot}) locking root")
|
||||
pmb.chroot.root(args, ["passwd", "-l", "root"], chroot)
|
||||
pmb.chroot.root(["passwd", "-l", "root"], chroot)
|
||||
|
||||
|
||||
def copy_ssh_keys(args: PmbArgs):
|
||||
def copy_ssh_keys(config: Config):
|
||||
"""
|
||||
If requested, copy user's SSH public keys to the device if they exist
|
||||
"""
|
||||
if not args.ssh_keys:
|
||||
if not config.ssh_keys:
|
||||
return
|
||||
keys = []
|
||||
for key in glob.glob(os.path.expanduser(args.ssh_key_glob)):
|
||||
for key in glob.glob(os.path.expanduser(config.ssh_key_glob)):
|
||||
with open(key, "r") as infile:
|
||||
keys += infile.readlines()
|
||||
|
||||
|
@ -310,7 +312,7 @@ def copy_ssh_keys(args: PmbArgs):
|
|||
outfile.write("%s" % key)
|
||||
outfile.close()
|
||||
|
||||
target = Chroot.native() / "mnt/install/home/" / args.user / ".ssh"
|
||||
target = Chroot.native() / "mnt/install/home/" / config.user / ".ssh"
|
||||
pmb.helpers.run.root(["mkdir", target])
|
||||
pmb.helpers.run.root(["chmod", "700", target])
|
||||
pmb.helpers.run.root(["cp", authorized_keys, target / "authorized_keys"])
|
||||
|
@ -318,30 +320,30 @@ def copy_ssh_keys(args: PmbArgs):
|
|||
pmb.helpers.run.root(["chown", "-R", "10000:10000", target])
|
||||
|
||||
|
||||
def setup_keymap(args: PmbArgs):
|
||||
def setup_keymap(config: Config):
|
||||
"""
|
||||
Set the keymap with the setup-keymap utility if the device requires it
|
||||
"""
|
||||
chroot = Chroot(ChrootType.ROOTFS, args.device)
|
||||
info = pmb.parse.deviceinfo(args, device=args.device)
|
||||
chroot = Chroot(ChrootType.ROOTFS, config.device)
|
||||
info = pmb.parse.deviceinfo(device=config.device)
|
||||
if "keymaps" not in info or info["keymaps"].strip() == "":
|
||||
logging.info("NOTE: No valid keymap specified for device")
|
||||
return
|
||||
options = info["keymaps"].split(' ')
|
||||
if (args.keymap != "" and
|
||||
args.keymap is not None and
|
||||
args.keymap in options):
|
||||
layout, variant = args.keymap.split("/")
|
||||
pmb.chroot.root(args, ["setup-keymap", layout, variant], chroot,
|
||||
if (config.keymap != "" and
|
||||
config.keymap is not None and
|
||||
config.keymap in options):
|
||||
layout, variant = config.keymap.split("/")
|
||||
pmb.chroot.root(["setup-keymap", layout, variant], chroot,
|
||||
output="interactive")
|
||||
|
||||
# Check xorg config
|
||||
config = None
|
||||
xconfig = None
|
||||
if (chroot / "etc/X11/xorg.conf.d").exists():
|
||||
config = pmb.chroot.root(args, ["grep", "-rl", "XkbLayout",
|
||||
xconfig = pmb.chroot.root(["grep", "-rl", "XkbLayout",
|
||||
"/etc/X11/xorg.conf.d/"],
|
||||
chroot, check=False, output_return=True)
|
||||
if config:
|
||||
if xconfig:
|
||||
# Nokia n900 (RX-51) randomly merges some keymaps so we
|
||||
# have to specify a composite keymap for a few countries. See:
|
||||
# https://gitlab.freedesktop.org/xkeyboard-config/xkeyboard-config/-/blob/master/symbols/nokia_vndr/rx-51
|
||||
|
@ -352,17 +354,17 @@ def setup_keymap(args: PmbArgs):
|
|||
if variant == "rx51_pt" or variant == "rx51_es":
|
||||
layout = "ptes"
|
||||
# Multiple files can contain the keyboard layout, take last
|
||||
config = config.splitlines()[-1]
|
||||
xconfig = xconfig.splitlines()[-1]
|
||||
old_text = "Option *\\\"XkbLayout\\\" *\\\".*\\\""
|
||||
new_text = "Option \\\"XkbLayout\\\" \\\"" + layout + "\\\""
|
||||
pmb.chroot.root(args, ["sed", "-i", "s/" + old_text + "/" +
|
||||
new_text + "/", config], chroot)
|
||||
pmb.chroot.root(["sed", "-i", "s/" + old_text + "/" +
|
||||
new_text + "/", xconfig], chroot)
|
||||
else:
|
||||
logging.info("NOTE: No valid keymap specified for device")
|
||||
|
||||
|
||||
def setup_timezone(args: PmbArgs):
|
||||
suffix = Chroot(ChrootType.ROOTFS, args.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)
|
||||
|
@ -378,7 +380,7 @@ def setup_timezone(args: PmbArgs):
|
|||
if not pmb.parse.version.check_string(version, ">=3.14.0"):
|
||||
setup_tz_cmd += ["-z"]
|
||||
setup_tz_cmd += [args.timezone]
|
||||
pmb.chroot.root(args, setup_tz_cmd, suffix)
|
||||
pmb.chroot.root(setup_tz_cmd, suffix)
|
||||
|
||||
|
||||
def setup_hostname(args: PmbArgs):
|
||||
|
@ -402,12 +404,12 @@ def setup_hostname(args: PmbArgs):
|
|||
|
||||
suffix = Chroot(ChrootType.ROOTFS, args.device)
|
||||
# Generate /etc/hostname
|
||||
pmb.chroot.root(args, ["sh", "-c", "echo " + shlex.quote(hostname) +
|
||||
pmb.chroot.root(["sh", "-c", "echo " + shlex.quote(hostname) +
|
||||
" > /etc/hostname"], suffix)
|
||||
# Update /etc/hosts
|
||||
regex = (r"s/^127\.0\.0\.1.*/127.0.0.1\t" + re.escape(hostname) +
|
||||
" localhost.localdomain localhost/")
|
||||
pmb.chroot.root(args, ["sed", "-i", "-e", regex, "/etc/hosts"], suffix)
|
||||
pmb.chroot.root(["sed", "-i", "-e", regex, "/etc/hosts"], suffix)
|
||||
|
||||
|
||||
def setup_appstream(args: PmbArgs):
|
||||
|
@ -421,10 +423,10 @@ def setup_appstream(args: PmbArgs):
|
|||
if "alpine-appstream-downloader" not in installed_pkgs or args.offline:
|
||||
return
|
||||
|
||||
if not pmb.chroot.root(args, ["alpine-appstream-downloader",
|
||||
if not pmb.chroot.root(["alpine-appstream-downloader",
|
||||
"/mnt/appstream-data"], suffix, check=False):
|
||||
pmb.chroot.root(args, ["mkdir", "-p", "/var/lib/swcatalog"], suffix)
|
||||
pmb.chroot.root(args, ["cp", "-r", "/mnt/appstream-data/icons",
|
||||
pmb.chroot.root(["mkdir", "-p", "/var/lib/swcatalog"], suffix)
|
||||
pmb.chroot.root(["cp", "-r", "/mnt/appstream-data/icons",
|
||||
"/mnt/appstream-data/xml",
|
||||
"-t", "/var/lib/swcatalog"], suffix)
|
||||
|
||||
|
@ -435,7 +437,7 @@ def disable_sshd(args: PmbArgs):
|
|||
|
||||
# check=False: rc-update doesn't exit with 0 if already disabled
|
||||
chroot = Chroot(ChrootType.ROOTFS, args.device)
|
||||
pmb.chroot.root(args, ["rc-update", "del", "sshd", "default"], chroot,
|
||||
pmb.chroot.root(["rc-update", "del", "sshd", "default"], chroot,
|
||||
check=False)
|
||||
|
||||
# Verify that it's gone
|
||||
|
@ -473,7 +475,7 @@ def disable_firewall(args: PmbArgs):
|
|||
|
||||
# check=False: rc-update doesn't exit with 0 if already disabled
|
||||
chroot = Chroot(ChrootType.ROOTFS, args.device)
|
||||
pmb.chroot.root(args, ["rc-update", "del", "nftables", "default"], chroot,
|
||||
pmb.chroot.root(["rc-update", "del", "nftables", "default"], chroot,
|
||||
check=False)
|
||||
|
||||
# Verify that it's gone
|
||||
|
@ -485,7 +487,7 @@ def disable_firewall(args: PmbArgs):
|
|||
|
||||
|
||||
def print_firewall_info(args: PmbArgs):
|
||||
pmaports_cfg = pmb.config.pmaports.read_config(args)
|
||||
pmaports_cfg = pmb.config.pmaports.read_config()
|
||||
pmaports_ok = pmaports_cfg.get("supported_firewall", None) == "nftables"
|
||||
|
||||
# Find kernel pmaport (will not be found if Alpine kernel is used)
|
||||
|
@ -495,8 +497,7 @@ def print_firewall_info(args: PmbArgs):
|
|||
arch = args.deviceinfo["arch"]
|
||||
kernel = get_kernel_package(args, args.device)
|
||||
if kernel:
|
||||
kernel_apkbuild = pmb.build._package.get_apkbuild(args, kernel[0],
|
||||
arch)
|
||||
kernel_apkbuild = pmb.build._package.get_apkbuild(kernel[0], arch)
|
||||
if kernel_apkbuild:
|
||||
opts = kernel_apkbuild["options"]
|
||||
apkbuild_has_opt = "pmb:kconfigcheck-nftables" in opts
|
||||
|
@ -607,7 +608,7 @@ def embed_firmware(args: PmbArgs, suffix: Chroot):
|
|||
logging.info("Embed firmware {} in the SD card image at offset {} with"
|
||||
" step size {}".format(binary, offset, step))
|
||||
filename = os.path.join(device_rootfs, binary_file.lstrip("/"))
|
||||
pmb.chroot.root(args, ["dd", "if=" + filename, "of=/dev/install",
|
||||
pmb.chroot.root(["dd", "if=" + filename, "of=/dev/install",
|
||||
"bs=" + str(step), "seek=" + str(offset)])
|
||||
|
||||
|
||||
|
@ -627,12 +628,13 @@ def write_cgpt_kpart(args: PmbArgs, layout, suffix: Chroot):
|
|||
args, ["dd", f"if={filename}", f"of=/dev/installp{layout['kernel']}"])
|
||||
|
||||
|
||||
def sanity_check_boot_size(args: PmbArgs):
|
||||
default = pmb.config.defaults["boot_size"]
|
||||
if isinstance(default, str) and int(args.boot_size) >= int(default):
|
||||
def sanity_check_boot_size():
|
||||
default = Config().boot_size
|
||||
config = get_context().config
|
||||
if int(config.boot_size) >= int(default):
|
||||
return
|
||||
logging.error("ERROR: your pmbootstrap has a small/invalid boot_size of"
|
||||
f" {args.boot_size} configured, probably because the config"
|
||||
f" {config.boot_size} configured, probably because the config"
|
||||
" has been created with an old version.")
|
||||
logging.error("This can lead to problems later on, we recommend setting it"
|
||||
f" to {default} MiB.")
|
||||
|
@ -727,7 +729,6 @@ def get_uuid(args: PmbArgs, partition: Path):
|
|||
:param partition: block device for getting UUID from
|
||||
"""
|
||||
return pmb.chroot.root(
|
||||
args,
|
||||
[
|
||||
"blkid",
|
||||
"-s", "UUID",
|
||||
|
@ -751,7 +752,7 @@ def create_crypttab(args: PmbArgs, layout, chroot: Chroot):
|
|||
crypttab = f"root UUID={luks_uuid} none luks\n"
|
||||
|
||||
(chroot / "tmp/crypttab").open("w").write(crypttab)
|
||||
pmb.chroot.root(args, ["mv", "/tmp/crypttab", "/etc/crypttab"], chroot)
|
||||
pmb.chroot.root(["mv", "/tmp/crypttab", "/etc/crypttab"], chroot)
|
||||
|
||||
|
||||
def create_fstab(args: PmbArgs, layout, chroot: Chroot):
|
||||
|
@ -804,7 +805,7 @@ def create_fstab(args: PmbArgs, layout, chroot: Chroot):
|
|||
|
||||
with (chroot / "tmp/fstab").open("w") as f:
|
||||
f.write(fstab)
|
||||
pmb.chroot.root(args, ["mv", "/tmp/fstab", "/etc/fstab"], chroot)
|
||||
pmb.chroot.root(["mv", "/tmp/fstab", "/etc/fstab"], chroot)
|
||||
|
||||
|
||||
def install_system_image(args: PmbArgs, size_reserve, chroot: Chroot, step, steps,
|
||||
|
@ -824,7 +825,7 @@ def install_system_image(args: PmbArgs, size_reserve, chroot: Chroot, step, step
|
|||
# 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(args, chroot)
|
||||
(size_boot, size_root) = get_subpartitions_size(chroot)
|
||||
layout = get_partition_layout(size_reserve, args.deviceinfo["cgpt_kpart"] \
|
||||
and args.install_cgpt)
|
||||
if not args.rsync:
|
||||
|
@ -850,7 +851,7 @@ def install_system_image(args: PmbArgs, size_reserve, chroot: Chroot, step, step
|
|||
|
||||
# Run mkinitfs to pass UUIDs to cmdline
|
||||
logging.info(f"({chroot}) mkinitfs")
|
||||
pmb.chroot.root(args, ["mkinitfs"], chroot)
|
||||
pmb.chroot.root(["mkinitfs"], chroot)
|
||||
|
||||
# Clean up after running mkinitfs in chroot
|
||||
pmb.helpers.mount.umount_all(chroot.path)
|
||||
|
@ -883,25 +884,25 @@ def install_system_image(args: PmbArgs, size_reserve, chroot: Chroot, step, step
|
|||
if sparse and not split and not disk:
|
||||
workdir = Path("/home/pmos/rootfs")
|
||||
logging.info("(native) make sparse rootfs")
|
||||
pmb.chroot.apk.install(args, ["android-tools"], Chroot.native())
|
||||
pmb.chroot.apk.install(["android-tools"], Chroot.native())
|
||||
sys_image = args.device + ".img"
|
||||
sys_image_sparse = args.device + "-sparse.img"
|
||||
pmb.chroot.user(args, ["img2simg", sys_image, sys_image_sparse],
|
||||
pmb.chroot.user(["img2simg", sys_image, sys_image_sparse],
|
||||
working_dir=workdir)
|
||||
pmb.chroot.user(args, ["mv", "-f", sys_image_sparse, sys_image],
|
||||
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"]
|
||||
if samsungify_strategy:
|
||||
logging.info("(native) convert sparse image into Samsung's sparse image format")
|
||||
pmb.chroot.apk.install(args, ["sm-sparse-image-tool"], Chroot.native())
|
||||
pmb.chroot.apk.install(["sm-sparse-image-tool"], Chroot.native())
|
||||
sys_image = f"{args.device}.img"
|
||||
sys_image_patched = f"{args.device}-patched.img"
|
||||
pmb.chroot.user(args, ["sm_sparse_image_tool", "samsungify", "--strategy",
|
||||
pmb.chroot.user(["sm_sparse_image_tool", "samsungify", "--strategy",
|
||||
samsungify_strategy, sys_image, sys_image_patched],
|
||||
working_dir=workdir)
|
||||
pmb.chroot.user(args, ["mv", "-f", sys_image_patched, sys_image],
|
||||
pmb.chroot.user(["mv", "-f", sys_image_patched, sys_image],
|
||||
working_dir=workdir)
|
||||
|
||||
|
||||
|
@ -1016,10 +1017,10 @@ def install_on_device_installer(args: PmbArgs, step, steps):
|
|||
packages = ([f"device-{args.device}",
|
||||
"postmarketos-ondev"] +
|
||||
get_kernel_package(args, args.device) +
|
||||
get_nonfree_packages(args, args.device))
|
||||
get_nonfree_packages(args.device))
|
||||
|
||||
chroot_installer = Chroot(ChrootType.INSTALLER, args.device)
|
||||
pmb.chroot.apk.install(args, packages, chroot_installer)
|
||||
pmb.chroot.apk.install(packages, chroot_installer)
|
||||
|
||||
# Move rootfs image into installer chroot
|
||||
img_path_dest = chroot_installer / "var/lib/rootfs.img"
|
||||
|
@ -1035,7 +1036,7 @@ def install_on_device_installer(args: PmbArgs, step, steps):
|
|||
# file into another format. This can all be done without pmbootstrap
|
||||
# changes in the postmarketos-ondev package.
|
||||
logging.info(f"({chroot_installer}) ondev-prepare")
|
||||
channel = pmb.config.pmaports.read_config(args)["channel"]
|
||||
channel = pmb.config.pmaports.read_config()["channel"]
|
||||
channel_cfg = pmb.config.pmaports.read_config_channel(args)
|
||||
env = {"ONDEV_CHANNEL": channel,
|
||||
"ONDEV_CHANNEL_BRANCH_APORTS": channel_cfg["branch_aports"],
|
||||
|
@ -1045,7 +1046,7 @@ def install_on_device_installer(args: PmbArgs, step, steps):
|
|||
"ONDEV_CIPHER": args.cipher,
|
||||
"ONDEV_PMBOOTSTRAP_VERSION": pmb.__version__,
|
||||
"ONDEV_UI": args.ui}
|
||||
pmb.chroot.root(args, ["ondev-prepare"], chroot_installer, env=env)
|
||||
pmb.chroot.root(["ondev-prepare"], chroot_installer, env=env)
|
||||
|
||||
# Copy files specified with 'pmbootstrap install --ondev --cp'
|
||||
if args.ondev_cp:
|
||||
|
@ -1061,14 +1062,14 @@ def install_on_device_installer(args: PmbArgs, step, steps):
|
|||
if not args.ondev_no_rootfs:
|
||||
img_boot = f"{args.device}-boot.img"
|
||||
logging.info(f"(native) rm {img_boot}")
|
||||
pmb.chroot.root(args, ["rm", f"/home/pmos/rootfs/{img_boot}"])
|
||||
pmb.chroot.root(["rm", f"/home/pmos/rootfs/{img_boot}"])
|
||||
|
||||
# Disable root login
|
||||
setup_login(args, chroot_installer)
|
||||
|
||||
# Generate installer image
|
||||
size_reserve = round(os.path.getsize(img_path_dest) / 1024 / 1024) + 200
|
||||
pmaports_cfg = pmb.config.pmaports.read_config(args)
|
||||
pmaports_cfg = pmb.config.pmaports.read_config()
|
||||
boot_label = pmaports_cfg.get("supported_install_boot_label",
|
||||
"pmOS_inst_boot")
|
||||
install_system_image(args, size_reserve, chroot_installer, step, steps,
|
||||
|
@ -1100,12 +1101,12 @@ def get_selected_providers(args: PmbArgs, packages):
|
|||
# aren't in pmaports. This is fine, with the assumption that
|
||||
# installation will fail later in some other method if they truly don't
|
||||
# exist in any repo.
|
||||
apkbuild = pmb.helpers.pmaports.get(args, package, subpackages=False, must_exist=False)
|
||||
apkbuild = pmb.helpers.pmaports.get(package, subpackages=False, must_exist=False)
|
||||
if not apkbuild:
|
||||
continue
|
||||
for select in apkbuild['_pmb_select']:
|
||||
if select in args.selected_providers:
|
||||
ret += [args.selected_providers[select]]
|
||||
if select in get_context().config.providers:
|
||||
ret += [get_context().config.providers[select]]
|
||||
logging.debug(f"{package}: install selected_providers:"
|
||||
f" {', '.join(ret)}")
|
||||
# Also iterate through dependencies to collect any providers they have
|
||||
|
@ -1148,7 +1149,7 @@ def get_recommends(args: PmbArgs, packages) -> Sequence[str]:
|
|||
# aren't in pmaports. This is fine, with the assumption that
|
||||
# installation will fail later in some other method if they truly don't
|
||||
# exist in any repo.
|
||||
apkbuild = pmb.helpers.pmaports.get(args, package, must_exist=False)
|
||||
apkbuild = pmb.helpers.pmaports.get(package, must_exist=False)
|
||||
if not apkbuild:
|
||||
continue
|
||||
if package in apkbuild["subpackages"]:
|
||||
|
@ -1178,44 +1179,47 @@ def get_recommends(args: PmbArgs, packages) -> Sequence[str]:
|
|||
def create_device_rootfs(args: PmbArgs, step, steps):
|
||||
# List all packages to be installed (including the ones specified by --add)
|
||||
# and upgrade the installed packages/apkindexes
|
||||
logging.info(f'*** ({step}/{steps}) CREATE DEVICE ROOTFS ("{args.device}")'
|
||||
context = get_context()
|
||||
config = context.config
|
||||
device = context.config.device
|
||||
logging.info(f'*** ({step}/{steps}) CREATE DEVICE ROOTFS ("{device}")'
|
||||
' ***')
|
||||
|
||||
suffix = Chroot(ChrootType.ROOTFS, args.device)
|
||||
pmb.chroot.init(args, suffix)
|
||||
suffix = Chroot(ChrootType.ROOTFS, device)
|
||||
pmb.chroot.init(suffix)
|
||||
# Create user before installing packages, so post-install scripts of
|
||||
# pmaports can figure out the username (legacy reasons: pmaports#820)
|
||||
set_user(args)
|
||||
set_user(context.config)
|
||||
|
||||
# Fill install_packages
|
||||
install_packages = (pmb.config.install_device_packages +
|
||||
["device-" + args.device])
|
||||
["device-" + device])
|
||||
if not args.install_base:
|
||||
install_packages = [p for p in install_packages
|
||||
if p != "postmarketos-base"]
|
||||
if args.ui.lower() != "none":
|
||||
install_packages += ["postmarketos-ui-" + args.ui]
|
||||
if config.ui.lower() != "none":
|
||||
install_packages += ["postmarketos-ui-" + config.ui]
|
||||
|
||||
if pmb.config.other.is_systemd_selected(args):
|
||||
if pmb.config.other.is_systemd_selected(context.config):
|
||||
install_packages += ["postmarketos-base-systemd"]
|
||||
|
||||
# Add additional providers of base/device/UI package
|
||||
install_packages += get_selected_providers(args, install_packages)
|
||||
|
||||
install_packages += get_kernel_package(args, args.device)
|
||||
install_packages += get_nonfree_packages(args, args.device)
|
||||
if args.ui.lower() != "none":
|
||||
if args.ui_extras:
|
||||
install_packages += ["postmarketos-ui-" + args.ui + "-extras"]
|
||||
if args.extra_packages.lower() != "none":
|
||||
install_packages += args.extra_packages.split(",")
|
||||
install_packages += get_kernel_package(args, device)
|
||||
install_packages += get_nonfree_packages(device)
|
||||
if context.config.ui.lower() != "none":
|
||||
if context.config.ui_extras:
|
||||
install_packages += ["postmarketos-ui-" + config.ui + "-extras"]
|
||||
if context.config.extra_packages.lower() != "none":
|
||||
install_packages += context.config.extra_packages.split(",")
|
||||
if args.add:
|
||||
install_packages += args.add.split(",")
|
||||
locale_is_set = (args.locale != pmb.config.defaults["locale"])
|
||||
locale_is_set = (config.locale != pmb.config.defaults["locale"])
|
||||
if locale_is_set:
|
||||
install_packages += ["lang", "musl-locales"]
|
||||
|
||||
pmaports_cfg = pmb.config.pmaports.read_config(args)
|
||||
pmaports_cfg = pmb.config.pmaports.read_config()
|
||||
# postmarketos-base supports a dummy package for blocking unl0kr install
|
||||
# when not required
|
||||
if pmaports_cfg.get("supported_base_nofde", None):
|
||||
|
@ -1233,7 +1237,7 @@ def create_device_rootfs(args: PmbArgs, step, steps):
|
|||
else:
|
||||
install_packages += ["postmarketos-base-nofde"]
|
||||
|
||||
pmb.helpers.repo.update(args, args.deviceinfo["arch"])
|
||||
pmb.helpers.repo.update(args.deviceinfo["arch"])
|
||||
|
||||
# Install uninstallable "dependencies" by default
|
||||
install_packages += get_recommends(args, install_packages)
|
||||
|
@ -1242,12 +1246,12 @@ def create_device_rootfs(args: PmbArgs, step, steps):
|
|||
# dependency, in case the version increased
|
||||
if args.build_pkgs_on_install:
|
||||
for pkgname in install_packages:
|
||||
pmb.build.package(args, pkgname, args.deviceinfo["arch"])
|
||||
pmb.build.package(pkgname, args.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(args, install_packages, suffix)
|
||||
pmb.chroot.apk.install(install_packages, suffix)
|
||||
flavor = pmb.chroot.other.kernel_flavor_installed(args, suffix)
|
||||
pmb.chroot.initfs.build(args, flavor, suffix)
|
||||
|
||||
|
@ -1266,7 +1270,7 @@ def create_device_rootfs(args: PmbArgs, step, steps):
|
|||
# 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)}}}"
|
||||
pmb.chroot.root(args, ["sh", "-c", f"echo {shlex.quote(line)}"
|
||||
pmb.chroot.root(["sh", "-c", f"echo {shlex.quote(line)}"
|
||||
" > /etc/profile.d/10locale-pmos.sh"], suffix)
|
||||
|
||||
# Set the hostname as the device name
|
||||
|
@ -1280,7 +1284,7 @@ def create_device_rootfs(args: PmbArgs, step, steps):
|
|||
|
||||
def install(args: PmbArgs):
|
||||
# Sanity checks
|
||||
sanity_check_boot_size(args)
|
||||
sanity_check_boot_size()
|
||||
if not args.android_recovery_zip and args.disk:
|
||||
sanity_check_disk(args)
|
||||
sanity_check_disk_size(args)
|
||||
|
@ -1303,8 +1307,8 @@ def install(args: PmbArgs):
|
|||
# Install required programs in native chroot
|
||||
step = 1
|
||||
logging.info(f"*** ({step}/{steps}) PREPARE NATIVE CHROOT ***")
|
||||
pmb.chroot.init(args, Chroot.native())
|
||||
pmb.chroot.apk.install(args, pmb.config.install_native_packages, Chroot.native(),
|
||||
pmb.chroot.init(Chroot.native())
|
||||
pmb.chroot.apk.install(pmb.config.install_native_packages, Chroot.native(),
|
||||
build=False)
|
||||
step += 1
|
||||
|
||||
|
|
|
@ -5,12 +5,12 @@ from pmb.helpers import logging
|
|||
import os
|
||||
import glob
|
||||
from pathlib import Path
|
||||
from pmb.core.types import PmbArgs
|
||||
from pmb.types import PmbArgs
|
||||
import pmb.helpers.mount
|
||||
import pmb.install.losetup
|
||||
import pmb.helpers.cli
|
||||
import pmb.config
|
||||
from pmb.core import Chroot
|
||||
from pmb.core import Chroot, get_context
|
||||
|
||||
|
||||
def previous_install(args: PmbArgs, path: Path):
|
||||
|
@ -28,7 +28,7 @@ def previous_install(args: PmbArgs, path: Path):
|
|||
pmb.helpers.mount.bind_file(blockdevice_outside,
|
||||
Chroot.native() / blockdevice_inside)
|
||||
try:
|
||||
label = pmb.chroot.root(args, ["blkid", "-s", "LABEL",
|
||||
label = pmb.chroot.root(["blkid", "-s", "LABEL",
|
||||
"-o", "value",
|
||||
blockdevice_inside],
|
||||
output_return=True)
|
||||
|
@ -87,19 +87,19 @@ def create_and_mount_image(args: PmbArgs, size_boot, size_root, size_reserve,
|
|||
outside = chroot / img_path
|
||||
if os.path.exists(outside):
|
||||
pmb.helpers.mount.umount_all(chroot / "mnt")
|
||||
pmb.install.losetup.umount(args, img_path)
|
||||
pmb.chroot.root(args, ["rm", img_path])
|
||||
pmb.install.losetup.umount(img_path)
|
||||
pmb.chroot.root(["rm", img_path])
|
||||
|
||||
# Make sure there is enough free space
|
||||
size_mb = round(size_boot + size_reserve + size_root)
|
||||
disk_data = os.statvfs(pmb.config.work)
|
||||
disk_data = os.statvfs(get_context().config.work)
|
||||
free = round((disk_data.f_bsize * disk_data.f_bavail) / (1024**2))
|
||||
if size_mb > free:
|
||||
raise RuntimeError("Not enough free space to create rootfs image! "
|
||||
f"(free: {free}M, required: {size_mb}M)")
|
||||
|
||||
# Create empty image files
|
||||
pmb.chroot.user(args, ["mkdir", "-p", "/home/pmos/rootfs"])
|
||||
pmb.chroot.user(["mkdir", "-p", "/home/pmos/rootfs"])
|
||||
size_mb_full = str(size_mb) + "M"
|
||||
size_mb_boot = str(round(size_boot)) + "M"
|
||||
size_mb_root = str(round(size_root)) + "M"
|
||||
|
@ -110,7 +110,7 @@ def create_and_mount_image(args: PmbArgs, size_boot, size_root, size_reserve,
|
|||
for img_path, size_mb in images.items():
|
||||
logging.info(f"(native) create {img_path.name} "
|
||||
f"({size_mb})")
|
||||
pmb.chroot.root(args, ["truncate", "-s", size_mb, img_path])
|
||||
pmb.chroot.root(["truncate", "-s", size_mb, img_path])
|
||||
|
||||
# Mount to /dev/install
|
||||
mount_image_paths = {img_path_full: "/dev/install"}
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
from pmb.helpers import logging
|
||||
import pmb.chroot
|
||||
from pmb.core import Chroot
|
||||
from pmb.core.types import PmbArgs
|
||||
from pmb.types import PmbArgs
|
||||
|
||||
|
||||
def install_fsprogs(args: PmbArgs, filesystem):
|
||||
|
@ -11,7 +11,7 @@ def install_fsprogs(args: PmbArgs, filesystem):
|
|||
fsprogs = pmb.config.filesystems.get(filesystem)
|
||||
if not fsprogs:
|
||||
raise RuntimeError(f"Unsupported filesystem: {filesystem}")
|
||||
pmb.chroot.apk.install(args, [fsprogs])
|
||||
pmb.chroot.apk.install([fsprogs])
|
||||
|
||||
|
||||
def format_and_mount_boot(args: PmbArgs, device, boot_label):
|
||||
|
@ -28,21 +28,21 @@ def format_and_mount_boot(args: PmbArgs, device, boot_label):
|
|||
logging.info(f"(native) format {device} (boot, {filesystem}), mount to"
|
||||
f" {mountpoint}")
|
||||
if filesystem == "fat16":
|
||||
pmb.chroot.root(args, ["mkfs.fat", "-F", "16", "-n", boot_label,
|
||||
pmb.chroot.root(["mkfs.fat", "-F", "16", "-n", boot_label,
|
||||
device])
|
||||
elif filesystem == "fat32":
|
||||
pmb.chroot.root(args, ["mkfs.fat", "-F", "32", "-n", boot_label,
|
||||
pmb.chroot.root(["mkfs.fat", "-F", "32", "-n", boot_label,
|
||||
device])
|
||||
elif filesystem == "ext2":
|
||||
pmb.chroot.root(args, ["mkfs.ext2", "-F", "-q", "-L", boot_label,
|
||||
pmb.chroot.root(["mkfs.ext2", "-F", "-q", "-L", boot_label,
|
||||
device])
|
||||
elif filesystem == "btrfs":
|
||||
pmb.chroot.root(args, ["mkfs.btrfs", "-f", "-q", "-L", boot_label,
|
||||
pmb.chroot.root(["mkfs.btrfs", "-f", "-q", "-L", boot_label,
|
||||
device])
|
||||
else:
|
||||
raise RuntimeError("Filesystem " + filesystem + " is not supported!")
|
||||
pmb.chroot.root(args, ["mkdir", "-p", mountpoint])
|
||||
pmb.chroot.root(args, ["mount", device, mountpoint])
|
||||
pmb.chroot.root(["mkdir", "-p", mountpoint])
|
||||
pmb.chroot.root(["mount", device, mountpoint])
|
||||
|
||||
|
||||
def format_luks_root(args: PmbArgs, device):
|
||||
|
@ -56,15 +56,15 @@ def format_luks_root(args: PmbArgs, device):
|
|||
logging.info(" *** TYPE IN THE FULL DISK ENCRYPTION PASSWORD (TWICE!) ***")
|
||||
|
||||
# Avoid cryptsetup warning about missing locking directory
|
||||
pmb.chroot.root(args, ["mkdir", "-p", "/run/cryptsetup"])
|
||||
pmb.chroot.root(["mkdir", "-p", "/run/cryptsetup"])
|
||||
|
||||
pmb.chroot.root(args, ["cryptsetup", "luksFormat",
|
||||
pmb.chroot.root(["cryptsetup", "luksFormat",
|
||||
"-q",
|
||||
"--cipher", args.cipher,
|
||||
"--iter-time", args.iter_time,
|
||||
"--use-random",
|
||||
device], output="interactive")
|
||||
pmb.chroot.root(args, ["cryptsetup", "luksOpen", device, "pm_crypt"],
|
||||
pmb.chroot.root(["cryptsetup", "luksOpen", device, "pm_crypt"],
|
||||
output="interactive")
|
||||
|
||||
if not (Chroot.native() / mountpoint).exists():
|
||||
|
@ -73,7 +73,7 @@ def format_luks_root(args: PmbArgs, device):
|
|||
|
||||
def get_root_filesystem(args: PmbArgs):
|
||||
ret = args.filesystem or args.deviceinfo["root_filesystem"] or "ext4"
|
||||
pmaports_cfg = pmb.config.pmaports.read_config(args)
|
||||
pmaports_cfg = pmb.config.pmaports.read_config()
|
||||
|
||||
supported = pmaports_cfg.get("supported_root_filesystems", "ext4")
|
||||
supported_list = supported.split(",")
|
||||
|
@ -116,9 +116,9 @@ def prepare_btrfs_subvolumes(args: PmbArgs, device, mountpoint):
|
|||
["btrfs", "subvol", "set-default", f"{mountpoint}/@"])
|
||||
|
||||
# Make directories to mount subvols onto
|
||||
pmb.chroot.root(args, ["umount", mountpoint])
|
||||
pmb.chroot.root(args, ["mount", device, mountpoint])
|
||||
pmb.chroot.root(args, ["mkdir",
|
||||
pmb.chroot.root(["umount", mountpoint])
|
||||
pmb.chroot.root(["mount", device, mountpoint])
|
||||
pmb.chroot.root(["mkdir",
|
||||
f"{mountpoint}/home",
|
||||
f"{mountpoint}/root",
|
||||
f"{mountpoint}/.snapshots",
|
||||
|
@ -127,8 +127,8 @@ def prepare_btrfs_subvolumes(args: PmbArgs, device, mountpoint):
|
|||
|
||||
# snapshots contain sensitive information,
|
||||
# and should only be readable by root.
|
||||
pmb.chroot.root(args, ["chmod", "700", f"{mountpoint}/root"])
|
||||
pmb.chroot.root(args, ["chmod", "700", f"{mountpoint}/.snapshots"])
|
||||
pmb.chroot.root(["chmod", "700", f"{mountpoint}/root"])
|
||||
pmb.chroot.root(["chmod", "700", f"{mountpoint}/.snapshots"])
|
||||
|
||||
# Mount subvols
|
||||
pmb.chroot.root(args,
|
||||
|
@ -149,7 +149,7 @@ def prepare_btrfs_subvolumes(args: PmbArgs, device, mountpoint):
|
|||
|
||||
# Disable CoW for /var, to avoid write multiplication
|
||||
# and slowdown on databases, containers and VM images.
|
||||
pmb.chroot.root(args, ["chattr", "+C", f"{mountpoint}/var"])
|
||||
pmb.chroot.root(["chattr", "+C", f"{mountpoint}/var"])
|
||||
|
||||
|
||||
def format_and_mount_root(args: PmbArgs, device, root_label, disk):
|
||||
|
@ -182,13 +182,13 @@ def format_and_mount_root(args: PmbArgs, device, root_label, disk):
|
|||
|
||||
install_fsprogs(args, filesystem)
|
||||
logging.info(f"(native) format {device} (root, {filesystem})")
|
||||
pmb.chroot.root(args, mkfs_root_args + [device])
|
||||
pmb.chroot.root(mkfs_root_args + [device])
|
||||
|
||||
# Mount
|
||||
mountpoint = "/mnt/install"
|
||||
logging.info("(native) mount " + device + " to " + mountpoint)
|
||||
pmb.chroot.root(args, ["mkdir", "-p", mountpoint])
|
||||
pmb.chroot.root(args, ["mount", device, mountpoint])
|
||||
pmb.chroot.root(["mkdir", "-p", mountpoint])
|
||||
pmb.chroot.root(["mount", device, mountpoint])
|
||||
|
||||
if not args.rsync and filesystem == "btrfs":
|
||||
# Make flat btrfs subvolume layout
|
||||
|
|
|
@ -8,7 +8,7 @@ from pmb.helpers import logging
|
|||
import os
|
||||
import time
|
||||
|
||||
from pmb.core.types import PathString, PmbArgs
|
||||
from pmb.types import PathString, PmbArgs
|
||||
import pmb.helpers.mount
|
||||
import pmb.helpers.run
|
||||
import pmb.chroot
|
||||
|
@ -46,7 +46,7 @@ def mount(args: PmbArgs, img_path: Path):
|
|||
if sector_size:
|
||||
losetup_cmd += ["-b", str(int(sector_size))]
|
||||
|
||||
pmb.chroot.root(args, losetup_cmd, check=False)
|
||||
pmb.chroot.root(losetup_cmd, check=False)
|
||||
try:
|
||||
device_by_back_file(args, img_path)
|
||||
return
|
||||
|
@ -57,13 +57,13 @@ def mount(args: PmbArgs, img_path: Path):
|
|||
raise RuntimeError(f"Failed to mount loop device: {img_path}")
|
||||
|
||||
|
||||
def device_by_back_file(args: PmbArgs, back_file: Path) -> Path:
|
||||
def device_by_back_file(back_file: Path) -> Path:
|
||||
"""
|
||||
Get the /dev/loopX device that points to a specific image file.
|
||||
"""
|
||||
|
||||
# Get list from losetup
|
||||
losetup_output = pmb.chroot.root(args, ["losetup", "--json", "--list"],
|
||||
losetup_output = pmb.chroot.root(["losetup", "--json", "--list"],
|
||||
output_return=True)
|
||||
if not losetup_output:
|
||||
raise RuntimeError("losetup failed")
|
||||
|
@ -76,14 +76,14 @@ def device_by_back_file(args: PmbArgs, back_file: Path) -> Path:
|
|||
raise RuntimeError(f"Failed to find loop device for {back_file}")
|
||||
|
||||
|
||||
def umount(args: PmbArgs, img_path: Path):
|
||||
def umount(img_path: Path):
|
||||
"""
|
||||
:param img_path: Path to the img file inside native chroot.
|
||||
"""
|
||||
device: Path
|
||||
try:
|
||||
device = device_by_back_file(args, img_path)
|
||||
device = device_by_back_file(img_path)
|
||||
except RuntimeError:
|
||||
return
|
||||
logging.debug(f"(native) umount {device}")
|
||||
pmb.chroot.root(args, ["losetup", "-d", device])
|
||||
pmb.chroot.root(["losetup", "-d", device])
|
||||
|
|
|
@ -7,7 +7,7 @@ import os
|
|||
import time
|
||||
import pmb.chroot
|
||||
import pmb.config
|
||||
from pmb.core.types import PmbArgs
|
||||
from pmb.types import PmbArgs
|
||||
import pmb.install.losetup
|
||||
from pmb.core import Chroot
|
||||
|
||||
|
@ -114,7 +114,7 @@ def partition(args: PmbArgs, layout, size_boot, size_reserve):
|
|||
commands += [["set", str(layout["boot"]), "esp", "on"]]
|
||||
|
||||
for command in commands:
|
||||
pmb.chroot.root(args, ["parted", "-s", "/dev/install"] +
|
||||
pmb.chroot.root(["parted", "-s", "/dev/install"] +
|
||||
command, check=False)
|
||||
|
||||
|
||||
|
@ -128,7 +128,7 @@ 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(args, ["cgpt"], build=False)
|
||||
pmb.chroot.apk.install(["cgpt"], build=False)
|
||||
|
||||
cgpt = {
|
||||
'kpart_start': args.deviceinfo["cgpt_kpart_start"],
|
||||
|
@ -196,4 +196,4 @@ def partition_cgpt(args: PmbArgs, layout, size_boot, size_reserve):
|
|||
]
|
||||
|
||||
for command in commands:
|
||||
pmb.chroot.root(args, command, check=False)
|
||||
pmb.chroot.root(command, check=False)
|
||||
|
|
|
@ -5,7 +5,7 @@ from pmb.helpers import logging
|
|||
|
||||
import pmb.chroot
|
||||
import pmb.config.pmaports
|
||||
from pmb.core.types import PmbArgs
|
||||
from pmb.types import PmbArgs
|
||||
import pmb.flasher
|
||||
import pmb.helpers.frontend
|
||||
|
||||
|
@ -45,7 +45,7 @@ def create_zip(args: PmbArgs, suffix):
|
|||
}
|
||||
|
||||
# Backwards compatibility with old mkinitfs (pma#660)
|
||||
pmaports_cfg = pmb.config.pmaports.read_config(args)
|
||||
pmaports_cfg = pmb.config.pmaports.read_config()
|
||||
if pmaports_cfg.get("supported_mkinitfs_without_flavors", False):
|
||||
options["FLAVOR"] = ""
|
||||
else:
|
||||
|
@ -71,4 +71,4 @@ def create_zip(args: PmbArgs, suffix):
|
|||
["gzip", "-f1", "rootfs.tar"],
|
||||
["build-recovery-zip", args.device]]
|
||||
for command in commands:
|
||||
pmb.chroot.root(args, command, suffix, working_dir=zip_root)
|
||||
pmb.chroot.root(command, suffix, working_dir=zip_root)
|
||||
|
|
|
@ -3,23 +3,23 @@
|
|||
from typing import List
|
||||
from pmb.helpers import logging
|
||||
|
||||
from pmb.core.types import PmbArgs
|
||||
from pmb.types import Config
|
||||
import pmb.helpers.pmaports
|
||||
|
||||
|
||||
def get_groups(args: PmbArgs) -> List[str]:
|
||||
def get_groups(config: Config) -> List[str]:
|
||||
""" Get all groups to which the user additionally must be added.
|
||||
The list of groups are listed in _pmb_groups of the UI and
|
||||
UI-extras package.
|
||||
|
||||
:returns: list of groups, e.g. ["feedbackd", "udev"] """
|
||||
ret: List[str] = []
|
||||
if args.ui == "none":
|
||||
if config.ui == "none":
|
||||
return ret
|
||||
|
||||
# UI package
|
||||
meta = f"postmarketos-ui-{args.ui}"
|
||||
apkbuild = pmb.helpers.pmaports.get(args, meta)
|
||||
meta = f"postmarketos-ui-{config.ui}"
|
||||
apkbuild = pmb.helpers.pmaports.get(meta)
|
||||
groups = apkbuild["_pmb_groups"]
|
||||
if groups:
|
||||
logging.debug(f"{meta}: install _pmb_groups:"
|
||||
|
@ -28,7 +28,7 @@ def get_groups(args: PmbArgs) -> List[str]:
|
|||
|
||||
# UI-extras subpackage
|
||||
meta_extras = f"{meta}-extras"
|
||||
if args.ui_extras and meta_extras in apkbuild["subpackages"]:
|
||||
if config.ui_extras and meta_extras in apkbuild["subpackages"]:
|
||||
groups = apkbuild["subpackages"][meta_extras]["_pmb_groups"]
|
||||
if groups:
|
||||
logging.debug(f"{meta_extras}: install _pmb_groups:"
|
||||
|
|
|
@ -6,7 +6,7 @@ import socket
|
|||
import time
|
||||
|
||||
import pmb.chroot.run
|
||||
from pmb.core.types import PmbArgs
|
||||
from pmb.types import PmbArgs
|
||||
import pmb.helpers.run
|
||||
from pmb.core import Chroot
|
||||
|
||||
|
@ -18,7 +18,7 @@ def start_nbd_server(args: PmbArgs, ip="172.16.42.2", port=9999):
|
|||
:param port: port of nbd server
|
||||
"""
|
||||
|
||||
pmb.chroot.apk.install(args, ['nbd'])
|
||||
pmb.chroot.apk.install(['nbd'])
|
||||
|
||||
chroot = Chroot.native()
|
||||
|
||||
|
@ -34,7 +34,7 @@ def start_nbd_server(args: PmbArgs, ip="172.16.42.2", port=9999):
|
|||
f"{args.device}?"):
|
||||
return
|
||||
pmb.chroot.run(args, ["cp", rootfs_path2, rootfs_path])
|
||||
logging.info(f"NOTE: Copied device image to {pmb.config.work}"
|
||||
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.")
|
||||
|
|
|
@ -8,7 +8,7 @@ import re
|
|||
from collections import OrderedDict
|
||||
|
||||
import pmb.config
|
||||
from pmb.core.types import PmbArgs
|
||||
from pmb.types import PmbArgs
|
||||
import pmb.helpers.devices
|
||||
import pmb.parse.version
|
||||
|
||||
|
@ -330,7 +330,7 @@ def apkbuild(path: Path, check_pkgver=True, check_pkgname=True):
|
|||
path = path / "APKBUILD"
|
||||
|
||||
if not path.exists():
|
||||
raise FileNotFoundError(f"{path.relative_to(pmb.config.work)} not found!")
|
||||
raise FileNotFoundError(f"{path.relative_to(get_context().config.work)} not found!")
|
||||
|
||||
# Try to get a cached result first (we assume that the aports don't change
|
||||
# in one pmbootstrap call)
|
||||
|
@ -367,7 +367,7 @@ def apkbuild(path: Path, check_pkgver=True, check_pkgname=True):
|
|||
return ret
|
||||
|
||||
|
||||
def kernels(args: PmbArgs, device):
|
||||
def kernels(device: str):
|
||||
"""
|
||||
Get the possible kernels from a device-* APKBUILD.
|
||||
|
||||
|
@ -379,7 +379,7 @@ def kernels(args: PmbArgs, device):
|
|||
"downstream": "Downstream description"}
|
||||
"""
|
||||
# Read the APKBUILD
|
||||
apkbuild_path = pmb.helpers.devices.find_path(args, device, 'APKBUILD')
|
||||
apkbuild_path = pmb.helpers.devices.find_path(device, 'APKBUILD')
|
||||
if apkbuild_path is None:
|
||||
return None
|
||||
subpackages = apkbuild(apkbuild_path)["subpackages"]
|
||||
|
|
|
@ -6,7 +6,6 @@ from pmb.helpers import logging
|
|||
from pathlib import Path
|
||||
import tarfile
|
||||
import pmb.chroot.apk
|
||||
from pmb.core.types import PmbArgs
|
||||
import pmb.helpers.package
|
||||
import pmb.helpers.repo
|
||||
import pmb.parse.version
|
||||
|
@ -261,7 +260,7 @@ def clear_cache(path: Path):
|
|||
return False
|
||||
|
||||
|
||||
def providers(args: PmbArgs, package, arch=None, must_exist=True, indexes=None):
|
||||
def providers(package, arch=None, must_exist=True, indexes=None):
|
||||
"""
|
||||
Get all packages, which provide one package.
|
||||
|
||||
|
@ -277,7 +276,7 @@ def providers(args: PmbArgs, package, arch=None, must_exist=True, indexes=None):
|
|||
"""
|
||||
if not indexes:
|
||||
arch = arch or pmb.config.arch_native
|
||||
indexes = pmb.helpers.repo.apkindex_files(args, arch)
|
||||
indexes = pmb.helpers.repo.apkindex_files(arch)
|
||||
|
||||
package = pmb.helpers.package.remove_operators(package)
|
||||
|
||||
|
@ -353,7 +352,7 @@ def provider_shortest(providers, pkgname):
|
|||
return providers[ret]
|
||||
|
||||
|
||||
def package(args: PmbArgs, package, arch=None, must_exist=True, indexes=None):
|
||||
def package(package, arch=None, must_exist=True, indexes=None):
|
||||
"""
|
||||
Get a specific package's data from an apkindex.
|
||||
|
||||
|
@ -372,7 +371,7 @@ def package(args: PmbArgs, package, arch=None, must_exist=True, indexes=None):
|
|||
or None when the package was not found.
|
||||
"""
|
||||
# Provider with the same package
|
||||
package_providers = providers(args, package, arch, must_exist, indexes)
|
||||
package_providers = providers(package, arch, must_exist, indexes)
|
||||
if package in package_providers:
|
||||
return package_providers[package]
|
||||
|
||||
|
|
|
@ -5,9 +5,6 @@ import platform
|
|||
import pmb.config
|
||||
import pmb.parse.arch
|
||||
|
||||
from pmb.core.types import PmbArgs
|
||||
from pmb.core import Chroot, ChrootType
|
||||
|
||||
def alpine_native():
|
||||
machine = platform.machine()
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@ import os
|
|||
from pathlib import Path
|
||||
import sys
|
||||
|
||||
from pmb.core.types import PmbArgs
|
||||
from pmb.types import Config, PmbArgs
|
||||
|
||||
try:
|
||||
import argcomplete # type:ignore[import-untyped]
|
||||
|
@ -637,7 +637,8 @@ def get_parser():
|
|||
parser = argparse.ArgumentParser(prog="pmbootstrap")
|
||||
arch_native = pmb.config.arch_native
|
||||
arch_choices = set(pmb.config.build_device_architectures + [arch_native])
|
||||
mirrors_pmos_default = pmb.config.defaults["mirrors_postmarketos"]
|
||||
default_config = Config()
|
||||
mirrors_pmos_default = ",".join(default_config.mirrors_postmarketos)
|
||||
|
||||
# Other
|
||||
parser.add_argument("-V", "--version", action="version",
|
||||
|
@ -653,7 +654,7 @@ def get_parser():
|
|||
metavar="URL", action="append", default=[])
|
||||
parser.add_argument("-m", "--mirror-alpine", dest="mirror_alpine",
|
||||
help="Alpine Linux mirror, default: "
|
||||
f"{pmb.config.defaults['mirror_alpine']}",
|
||||
f"{default_config.mirror_alpine}",
|
||||
metavar="URL")
|
||||
parser.add_argument("-j", "--jobs", help="parallel jobs when compiling")
|
||||
parser.add_argument("-E", "--extra-space",
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
import os
|
||||
from pmb.helpers import logging
|
||||
from pathlib import Path
|
||||
from pmb.core.types import PmbArgs
|
||||
from pmb.types import PmbArgs
|
||||
import pmb.helpers.run
|
||||
import pmb.chroot.run
|
||||
import pmb.chroot.other
|
||||
|
@ -79,7 +79,7 @@ def bootimg(args: PmbArgs, path: Path):
|
|||
logging.info("NOTE: You will be prompted for your sudo/doas password, so"
|
||||
" we can set up a chroot to extract and analyze your"
|
||||
" boot.img file")
|
||||
pmb.chroot.apk.install(args, ["file", "unpackbootimg"], Chroot.native())
|
||||
pmb.chroot.apk.install(["file", "unpackbootimg"], Chroot.native())
|
||||
|
||||
temp_path = pmb.chroot.other.tempfolder(args, Path("/tmp/bootimg_parser"))
|
||||
bootimg_path = Chroot.native() / temp_path / "boot.img"
|
||||
|
@ -89,7 +89,7 @@ def bootimg(args: PmbArgs, path: Path):
|
|||
pmb.helpers.run.root(["cp", path, bootimg_path])
|
||||
pmb.helpers.run.root(["chmod", "a+r", bootimg_path])
|
||||
|
||||
file_output = pmb.chroot.user(args, ["file", "-b", "boot.img"],
|
||||
file_output = pmb.chroot.user(["file", "-b", "boot.img"],
|
||||
working_dir=temp_path,
|
||||
output_return=True).rstrip()
|
||||
if "android bootimg" not in file_output.lower():
|
||||
|
@ -111,7 +111,7 @@ def bootimg(args: PmbArgs, path: Path):
|
|||
file_output + ")")
|
||||
|
||||
# Extract all the files
|
||||
pmb.chroot.user(args, ["unpackbootimg", "-i", "boot.img"],
|
||||
pmb.chroot.user(["unpackbootimg", "-i", "boot.img"],
|
||||
working_dir=temp_path)
|
||||
|
||||
output = {}
|
||||
|
|
|
@ -4,20 +4,20 @@ from typing import Dict, List, Sequence, Set
|
|||
from pmb.helpers import logging
|
||||
import pmb.chroot
|
||||
import pmb.chroot.apk
|
||||
from pmb.core.types import PmbArgs
|
||||
from pmb.types import PmbArgs
|
||||
import pmb.helpers.pmaports
|
||||
import pmb.parse.apkindex
|
||||
import pmb.parse.arch
|
||||
from pmb.core import Chroot
|
||||
from pmb.core import Chroot, get_context
|
||||
|
||||
|
||||
def package_from_aports(args: PmbArgs, pkgname_depend):
|
||||
def package_from_aports(pkgname_depend):
|
||||
"""
|
||||
:returns: None when there is no aport, or a dict with the keys pkgname,
|
||||
depends, version. The version is the combined pkgver and pkgrel.
|
||||
"""
|
||||
# Get the aport
|
||||
aport = pmb.helpers.pmaports.find_optional(args, pkgname_depend)
|
||||
aport = pmb.helpers.pmaports.find_optional(pkgname_depend)
|
||||
if not aport:
|
||||
return None
|
||||
|
||||
|
@ -34,7 +34,7 @@ def package_from_aports(args: PmbArgs, pkgname_depend):
|
|||
"version": version}
|
||||
|
||||
|
||||
def package_provider(args: PmbArgs, pkgname, pkgnames_install, suffix: Chroot=Chroot.native()):
|
||||
def package_provider(pkgname, pkgnames_install, suffix: Chroot=Chroot.native()):
|
||||
"""
|
||||
:param pkgnames_install: packages to be installed
|
||||
:returns: a block from the apkindex: {"pkgname": "...", ...}
|
||||
|
@ -42,7 +42,7 @@ def package_provider(args: PmbArgs, pkgname, pkgnames_install, suffix: Chroot=Ch
|
|||
"""
|
||||
# Get all providers
|
||||
arch = suffix.arch
|
||||
providers = pmb.parse.apkindex.providers(args, pkgname, arch, False)
|
||||
providers = pmb.parse.apkindex.providers(pkgname, arch, False)
|
||||
|
||||
# 0. No provider
|
||||
if len(providers) == 0:
|
||||
|
@ -67,7 +67,7 @@ def package_provider(args: PmbArgs, pkgname, pkgnames_install, suffix: Chroot=Ch
|
|||
return provider
|
||||
|
||||
# 4. Pick a package that is already installed
|
||||
installed = pmb.chroot.apk.installed(args, suffix)
|
||||
installed = pmb.chroot.apk.installed(suffix)
|
||||
for provider_pkgname, provider in providers.items():
|
||||
if provider_pkgname in installed:
|
||||
logging.verbose(f"{pkgname}: choosing provider '{provider_pkgname}"
|
||||
|
@ -76,7 +76,7 @@ def package_provider(args: PmbArgs, pkgname, pkgnames_install, suffix: Chroot=Ch
|
|||
return provider
|
||||
|
||||
# 5. Pick an explicitly selected provider
|
||||
provider_pkgname = args.selected_providers.get(pkgname, "")
|
||||
provider_pkgname = get_context().config.providers.get(pkgname, "")
|
||||
if provider_pkgname in providers:
|
||||
logging.verbose(f"{pkgname}: choosing provider '{provider_pkgname}', "
|
||||
"because it was explicitly selected.")
|
||||
|
@ -92,7 +92,7 @@ def package_provider(args: PmbArgs, pkgname, pkgnames_install, suffix: Chroot=Ch
|
|||
return pmb.parse.apkindex.provider_shortest(providers, pkgname)
|
||||
|
||||
|
||||
def package_from_index(args: PmbArgs, pkgname_depend, pkgnames_install, package_aport,
|
||||
def package_from_index(pkgname_depend, pkgnames_install, package_aport,
|
||||
suffix: Chroot=Chroot.native()):
|
||||
"""
|
||||
:returns: None when there is no aport and no binary package, or a dict with
|
||||
|
@ -100,7 +100,7 @@ def package_from_index(args: PmbArgs, pkgname_depend, pkgnames_install, package_
|
|||
binary package provider.
|
||||
"""
|
||||
# No binary package
|
||||
provider = package_provider(args, pkgname_depend, pkgnames_install, suffix)
|
||||
provider = package_provider(pkgname_depend, pkgnames_install, suffix)
|
||||
if not provider:
|
||||
return package_aport
|
||||
|
||||
|
@ -118,7 +118,7 @@ def package_from_index(args: PmbArgs, pkgname_depend, pkgnames_install, package_
|
|||
return provider
|
||||
|
||||
|
||||
def recurse(args: PmbArgs, pkgnames, suffix: Chroot=Chroot.native()) -> Sequence[str]:
|
||||
def recurse(pkgnames, suffix: Chroot=Chroot.native()) -> Sequence[str]:
|
||||
"""
|
||||
Find all dependencies of the given pkgnames.
|
||||
|
||||
|
@ -148,8 +148,8 @@ def recurse(args: PmbArgs, pkgnames, suffix: Chroot=Chroot.native()) -> Sequence
|
|||
|
||||
# Get depends and pkgname from aports
|
||||
pkgnames_install = list(ret) + todo
|
||||
package = package_from_aports(args, pkgname_depend)
|
||||
package = package_from_index(args, pkgname_depend, pkgnames_install,
|
||||
package = package_from_aports(pkgname_depend)
|
||||
package = package_from_index(pkgname_depend, pkgnames_install,
|
||||
package, suffix)
|
||||
|
||||
# Nothing found
|
||||
|
|
|
@ -2,10 +2,11 @@
|
|||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
import copy
|
||||
from typing import Dict
|
||||
from pmb.core import get_context
|
||||
from pmb.helpers import logging
|
||||
import os
|
||||
import pmb.config
|
||||
from pmb.core.types import PmbArgs
|
||||
from pmb.types import PmbArgs
|
||||
import pmb.helpers.devices
|
||||
|
||||
|
||||
|
@ -72,7 +73,7 @@ def sanity_check(info, path):
|
|||
f" and try again: {path}")
|
||||
|
||||
|
||||
def _parse_kernel_suffix(args: PmbArgs, info, device, kernel):
|
||||
def _parse_kernel_suffix(info, device, kernel):
|
||||
"""
|
||||
Remove the kernel suffix (as selected in 'pmbootstrap init') from
|
||||
deviceinfo variables. Related:
|
||||
|
@ -92,7 +93,7 @@ def _parse_kernel_suffix(args: PmbArgs, info, device, kernel):
|
|||
# Do nothing if the configured kernel isn't available in the kernel (e.g.
|
||||
# after switching from device with multiple kernels to device with only one
|
||||
# kernel)
|
||||
kernels = pmb.parse._apkbuild.kernels(args, device)
|
||||
kernels = pmb.parse._apkbuild.kernels(device)
|
||||
if not kernels or kernel not in kernels:
|
||||
logging.verbose(f"parse_kernel_suffix: {kernel} not in {kernels}")
|
||||
return info
|
||||
|
@ -114,23 +115,25 @@ def _parse_kernel_suffix(args: PmbArgs, info, device, kernel):
|
|||
|
||||
|
||||
# FIXME (#2324): Make deviceinfo a type! (class!!!)
|
||||
def deviceinfo(args: PmbArgs, device=None, kernel=None) -> Dict[str, str]:
|
||||
def deviceinfo(device=None, kernel=None) -> Dict[str, str]:
|
||||
"""
|
||||
:param device: defaults to args.device
|
||||
:param kernel: defaults to args.kernel
|
||||
"""
|
||||
context = get_context()
|
||||
if not device:
|
||||
device = args.device
|
||||
device = context.config.device
|
||||
if not kernel:
|
||||
kernel = args.kernel
|
||||
kernel = context.config.kernel
|
||||
|
||||
if not os.path.exists(args.aports):
|
||||
logging.fatal(f"Aports directory is missing, expected: {args.aports}")
|
||||
aports = context.config.aports
|
||||
if not aports.exists():
|
||||
logging.fatal(f"Aports directory is missing, expected: {aports}")
|
||||
logging.fatal("Please provide a path to the aports directory using the"
|
||||
" -p flag")
|
||||
raise RuntimeError("Aports directory missing")
|
||||
|
||||
path = pmb.helpers.devices.find_path(args, device, 'deviceinfo')
|
||||
path = pmb.helpers.devices.find_path(device, 'deviceinfo')
|
||||
if not path:
|
||||
raise RuntimeError(
|
||||
"Device '" + device + "' not found. Run 'pmbootstrap init' to"
|
||||
|
@ -154,6 +157,6 @@ def deviceinfo(args: PmbArgs, device=None, kernel=None) -> Dict[str, str]:
|
|||
if key not in ret:
|
||||
ret[key] = ""
|
||||
|
||||
ret = _parse_kernel_suffix(args, ret, device, kernel)
|
||||
ret = _parse_kernel_suffix(ret, device, kernel)
|
||||
sanity_check(ret, path)
|
||||
return ret
|
||||
|
|
|
@ -7,7 +7,7 @@ import os
|
|||
|
||||
import pmb.build
|
||||
import pmb.config
|
||||
from pmb.core.types import PmbArgs
|
||||
from pmb.types import PmbArgs
|
||||
import pmb.parse
|
||||
import pmb.helpers.pmaports
|
||||
from pmb.helpers.exceptions import NonBugError
|
||||
|
@ -255,7 +255,7 @@ def check(args: PmbArgs, pkgname, components_list=[], details=False, must_exist=
|
|||
ret = True
|
||||
aport: Path
|
||||
try:
|
||||
aport = pmb.helpers.pmaports.find(args, "linux-" + flavor)
|
||||
aport = pmb.helpers.pmaports.find("linux-" + flavor)
|
||||
except RuntimeError as e:
|
||||
if must_exist:
|
||||
raise e
|
||||
|
|
|
@ -17,7 +17,7 @@ import pmb.chroot.other
|
|||
import pmb.chroot.initfs
|
||||
import pmb.config
|
||||
import pmb.config.pmaports
|
||||
from pmb.core.types import PathString, PmbArgs
|
||||
from pmb.types import PathString, PmbArgs
|
||||
import pmb.helpers.run
|
||||
import pmb.parse.arch
|
||||
import pmb.parse.cpuinfo
|
||||
|
@ -79,11 +79,11 @@ def create_gdk_loader_cache(args: PmbArgs) -> Path:
|
|||
if not (chroot_native / cache_path).is_file():
|
||||
raise RuntimeError(f"gdk pixbuf cache file not found: {cache_path}")
|
||||
|
||||
pmb.chroot.root(args, ["cp", cache_path, custom_cache_path])
|
||||
pmb.chroot.root(["cp", cache_path, custom_cache_path])
|
||||
cmd: Sequence[PathString] = ["sed", "-i", "-e",
|
||||
f"s@\"{gdk_cache_dir}@\"{chroot_native / gdk_cache_dir}@",
|
||||
custom_cache_path]
|
||||
pmb.chroot.root(args, cmd)
|
||||
pmb.chroot.root(cmd)
|
||||
return chroot_native / custom_cache_path
|
||||
|
||||
|
||||
|
@ -107,7 +107,7 @@ def command_qemu(args: PmbArgs, arch, img_path, img_path_2nd=None):
|
|||
flavor = pmb.chroot.other.kernel_flavor_installed(args, chroot)
|
||||
flavor_suffix = f"-{flavor}"
|
||||
# Backwards compatibility with old mkinitfs (pma#660)
|
||||
pmaports_cfg = pmb.config.pmaports.read_config(args)
|
||||
pmaports_cfg = pmb.config.pmaports.read_config()
|
||||
if pmaports_cfg.get("supported_mkinitfs_without_flavors", False):
|
||||
flavor_suffix = ""
|
||||
|
||||
|
@ -325,7 +325,7 @@ def install_depends(args: PmbArgs, arch):
|
|||
if args.efi:
|
||||
depends.append("ovmf")
|
||||
|
||||
pmb.chroot.apk.install(args, depends, Chroot.native())
|
||||
pmb.chroot.apk.install(depends, Chroot.native())
|
||||
|
||||
|
||||
def run(args: PmbArgs):
|
||||
|
|
|
@ -5,13 +5,14 @@ from typing import List
|
|||
from pmb.helpers import logging
|
||||
import shlex
|
||||
|
||||
from pmb.core.types import PathString, PmbArgs
|
||||
from pmb.types import PathString, PmbArgs
|
||||
import pmb.helpers.run
|
||||
import pmb.helpers.run_core
|
||||
import pmb.parse.apkindex
|
||||
import pmb.parse.arch
|
||||
import pmb.config.pmaports
|
||||
import pmb.build
|
||||
from pmb.core import get_context
|
||||
|
||||
|
||||
def scp_abuild_key(args: PmbArgs, user: str, host: str, port: str):
|
||||
|
@ -21,7 +22,7 @@ def scp_abuild_key(args: PmbArgs, user: str, host: str, port: str):
|
|||
:param host: target device ssh hostname
|
||||
:param port: target device ssh port """
|
||||
|
||||
keys = list((pmb.config.work / "config_abuild").glob("*.pub"))
|
||||
keys = list((get_context().config.work / "config_abuild").glob("*.pub"))
|
||||
key = keys[0]
|
||||
key_name = os.path.basename(key)
|
||||
|
||||
|
@ -91,17 +92,18 @@ def sideload(args: PmbArgs, user: str, host: str, port: str, arch: str, copy_key
|
|||
:param pkgnames: list of pkgnames to be built """
|
||||
|
||||
paths = []
|
||||
channel: str = pmb.config.pmaports.read_config(args)["channel"]
|
||||
channel: str = pmb.config.pmaports.read_config()["channel"]
|
||||
|
||||
if arch is None:
|
||||
arch = ssh_find_arch(args, user, host, port)
|
||||
|
||||
context = get_context()
|
||||
for pkgname in pkgnames:
|
||||
data_repo = pmb.parse.apkindex.package(args, pkgname, arch, True)
|
||||
data_repo = pmb.parse.apkindex.package(pkgname, arch, True)
|
||||
apk_file = f"{pkgname}-{data_repo['version']}.apk"
|
||||
host_path = pmb.config.work / "packages" / channel / arch / apk_file
|
||||
host_path = context.config.work / "packages" / channel / arch / apk_file
|
||||
if not host_path.is_file():
|
||||
pmb.build.package(args, pkgname, arch, force=True)
|
||||
pmb.build.package(context, pkgname, arch, force=True)
|
||||
|
||||
if not host_path.is_file():
|
||||
raise RuntimeError(f"The package '{pkgname}' could not be built")
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
from argparse import Namespace
|
||||
import multiprocessing
|
||||
import os
|
||||
from pathlib import Path
|
||||
from typing import Dict, List, Optional, Tuple, TypedDict, Union
|
||||
|
||||
|
@ -24,7 +26,7 @@ class AportGenEntry(TypedDict):
|
|||
|
||||
# Property list generated with:
|
||||
# $ rg --vimgrep "((^|\s)args\.\w+)" --only-matching | cut -d"." -f3 | sort | uniq
|
||||
class PmbArgs(Namespace):
|
||||
class PmbArgs():
|
||||
action_flasher: str
|
||||
action_initfs: str
|
||||
action_kconfig: str
|
||||
|
@ -52,9 +54,9 @@ class PmbArgs(Namespace):
|
|||
cmdline: str
|
||||
command: str
|
||||
config: Path
|
||||
cross: bool
|
||||
details: bool
|
||||
details_to_stdout: bool
|
||||
device: str
|
||||
deviceinfo: Dict[str, str]
|
||||
deviceinfo_parse_kernel: str
|
||||
devices: str
|
||||
|
@ -63,7 +65,6 @@ class PmbArgs(Namespace):
|
|||
efi: str
|
||||
envkernel: str
|
||||
export_folder: Path
|
||||
extra_packages: str
|
||||
extra_space: str
|
||||
fast: str
|
||||
file: str
|
||||
|
@ -148,8 +149,6 @@ class PmbArgs(Namespace):
|
|||
suffix: str
|
||||
systemd: str
|
||||
timeout: float
|
||||
ui: str
|
||||
ui_extras: str
|
||||
user: str
|
||||
value: str
|
||||
verbose: str
|
||||
|
@ -157,3 +156,39 @@ class PmbArgs(Namespace):
|
|||
work: Path
|
||||
xauth: str
|
||||
zap: str
|
||||
|
||||
|
||||
class Config():
|
||||
aports: Path = Path(os.path.expanduser("~") +
|
||||
"/.local/var/pmbootstrap/cache_git/pmaports")
|
||||
boot_size: int = 256
|
||||
build_default_device_arch: bool = False
|
||||
build_pkgs_on_install: bool = True
|
||||
ccache_size: str = "5G" # yeahhhh this one has a suffix
|
||||
device: str = "qemu-amd64"
|
||||
extra_packages: str = "none"
|
||||
extra_space: int = 0
|
||||
hostname: str = ""
|
||||
is_default_channel: bool = True
|
||||
jobs: str = str(multiprocessing.cpu_count() + 1)
|
||||
kernel: str = "stable"
|
||||
keymap: str = ""
|
||||
locale: str = "en_US.UTF-8"
|
||||
# NOTE: mirrors use http by default to leverage caching
|
||||
mirror_alpine: str = "http://dl-cdn.alpinelinux.org/alpine/"
|
||||
# NOTE: mirrors_postmarketos variable type is supposed to be
|
||||
# comma-separated string, not a python list or any other type!
|
||||
mirrors_postmarketos: List[str] = ["http://mirror.postmarketos.org/postmarketos/"]
|
||||
qemu_redir_stdio: bool = False
|
||||
ssh_key_glob: str = "~/.ssh/id_*.pub"
|
||||
ssh_keys: bool = False
|
||||
sudo_timer: bool = False
|
||||
systemd: str = "default"
|
||||
timezone: str = "GMT"
|
||||
ui: str = "console"
|
||||
ui_extras: bool = False
|
||||
user: str = "user"
|
||||
work: Path = Path(os.path.expanduser("~") + "/.local/var/pmbootstrap")
|
||||
|
||||
providers: Dict[str, str] = { }
|
||||
|
|
@ -3,11 +3,11 @@
|
|||
""" Common code for git tests """
|
||||
import os
|
||||
|
||||
from pmb.core.types import PmbArgs
|
||||
from pmb.types import PmbArgs
|
||||
import pmb.helpers.git
|
||||
import pmb.helpers.run
|
||||
import shutil
|
||||
from pmb.core.types import PmbArgs
|
||||
from pmb.types import PmbArgs
|
||||
|
||||
|
||||
def prepare_tmpdir(args: PmbArgs, monkeypatch, tmpdir):
|
||||
|
|
|
@ -5,7 +5,7 @@ from typing import List
|
|||
import pytest
|
||||
import sys
|
||||
|
||||
from pmb.core.types import PathString
|
||||
from pmb.types import PathString
|
||||
import pmb_test # noqa
|
||||
import pmb.build
|
||||
import pmb.chroot.apk
|
||||
|
@ -19,7 +19,7 @@ def args(tmpdir, request):
|
|||
import pmb.parse
|
||||
sys.argv = ["pmbootstrap.py", "init"]
|
||||
args = pmb.parse.arguments()
|
||||
args.log = pmb.config.work / "log_testsuite.txt"
|
||||
args.log = get_context().config.work / "log_testsuite.txt"
|
||||
pmb.helpers.logging.init(args)
|
||||
request.addfinalizer(pmb.helpers.logging.logfd.close)
|
||||
return args
|
||||
|
|
|
@ -13,7 +13,7 @@ import pmb.chroot.apk_static
|
|||
import pmb.config
|
||||
import pmb.parse.apkindex
|
||||
import pmb.helpers.logging
|
||||
from pmb.core.types import PmbArgs
|
||||
from pmb.types import PmbArgs
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
|
@ -21,7 +21,7 @@ def args(request):
|
|||
import pmb.parse
|
||||
sys.argv = ["pmbootstrap.py", "chroot"]
|
||||
args = pmb.parse.arguments()
|
||||
args.log = pmb.config.work / "log_testsuite.txt"
|
||||
args.log = get_context().config.work / "log_testsuite.txt"
|
||||
pmb.helpers.logging.init(args)
|
||||
request.addfinalizer(pmb.helpers.logging.logfd.close)
|
||||
return args
|
||||
|
@ -30,13 +30,13 @@ def args(request):
|
|||
def test_read_signature_info(args: PmbArgs):
|
||||
# Tempfolder inside chroot for fake apk files
|
||||
tmp_path = Path("/tmp/test_read_signature_info")
|
||||
tmp_path_outside = pmb.config.work / "chroot_native" / tmp_path
|
||||
tmp_path_outside = get_context().config.work / "chroot_native" / tmp_path
|
||||
if os.path.exists(tmp_path_outside):
|
||||
pmb.chroot.root(args, ["rm", "-r", tmp_path])
|
||||
pmb.chroot.user(args, ["mkdir", "-p", tmp_path])
|
||||
pmb.chroot.root(["rm", "-r", tmp_path])
|
||||
pmb.chroot.user(["mkdir", "-p", tmp_path])
|
||||
|
||||
# No signature found
|
||||
pmb.chroot.user(args, ["tar", "-czf", tmp_path / "no_sig.apk",
|
||||
pmb.chroot.user(["tar", "-czf", tmp_path / "no_sig.apk",
|
||||
"/etc/issue"])
|
||||
with tarfile.open(tmp_path_outside / "no_sig.apk", "r:gz") as tar:
|
||||
with pytest.raises(RuntimeError) as e:
|
||||
|
@ -44,10 +44,10 @@ def test_read_signature_info(args: PmbArgs):
|
|||
assert "Could not find signature" in str(e.value)
|
||||
|
||||
# Signature file with invalid name
|
||||
pmb.chroot.user(args, ["mkdir", "-p", tmp_path / "sbin"])
|
||||
pmb.chroot.user(args, ["cp", "/etc/issue", tmp_path /
|
||||
pmb.chroot.user(["mkdir", "-p", tmp_path / "sbin"])
|
||||
pmb.chroot.user(["cp", "/etc/issue", tmp_path /
|
||||
"sbin/apk.static.SIGN.RSA.invalid.pub"])
|
||||
pmb.chroot.user(args, ["tar", "-czf", tmp_path / "invalid_sig.apk",
|
||||
pmb.chroot.user(["tar", "-czf", tmp_path / "invalid_sig.apk",
|
||||
"sbin/apk.static.SIGN.RSA.invalid.pub"],
|
||||
working_dir=tmp_path)
|
||||
with tarfile.open(tmp_path_outside / "invalid_sig.apk", "r:gz") as tar:
|
||||
|
@ -59,10 +59,10 @@ def test_read_signature_info(args: PmbArgs):
|
|||
path = list(pmb.config.apk_keys_path.glob("/*.pub"))[0]
|
||||
name = os.path.basename(path)
|
||||
path_archive = "sbin/apk.static.SIGN.RSA." + name
|
||||
pmb.chroot.user(args, ["mv",
|
||||
pmb.chroot.user(["mv",
|
||||
tmp_path / "sbin/apk.static.SIGN.RSA.invalid.pub",
|
||||
tmp_path / path_archive])
|
||||
pmb.chroot.user(args, ["tar", "-czf", tmp_path / "realistic_name_sig.apk",
|
||||
pmb.chroot.user(["tar", "-czf", tmp_path / "realistic_name_sig.apk",
|
||||
path_archive], working_dir=tmp_path)
|
||||
with tarfile.open(tmp_path_outside / "realistic_name_sig.apk", "r:gz")\
|
||||
as tar:
|
||||
|
@ -72,23 +72,23 @@ def test_read_signature_info(args: PmbArgs):
|
|||
assert sigkey_path == path
|
||||
|
||||
# Clean up
|
||||
pmb.chroot.user(args, ["rm", "-r", tmp_path])
|
||||
pmb.chroot.user(["rm", "-r", tmp_path])
|
||||
|
||||
|
||||
def test_successful_extraction(args: PmbArgs, tmpdir):
|
||||
if os.path.exists(pmb.config.work / "apk.static"):
|
||||
os.remove(pmb.config.work / "apk.static")
|
||||
if os.path.exists(get_context().config.work / "apk.static"):
|
||||
os.remove(get_context().config.work / "apk.static")
|
||||
|
||||
pmb.chroot.apk_static.init(args)
|
||||
assert os.path.exists(pmb.config.work / "apk.static")
|
||||
os.remove(pmb.config.work / "apk.static")
|
||||
assert os.path.exists(get_context().config.work / "apk.static")
|
||||
os.remove(get_context().config.work / "apk.static")
|
||||
|
||||
|
||||
def test_signature_verification(args: PmbArgs, tmpdir):
|
||||
if os.path.exists(pmb.config.work / "apk.static"):
|
||||
os.remove(pmb.config.work / "apk.static")
|
||||
if os.path.exists(get_context().config.work / "apk.static"):
|
||||
os.remove(get_context().config.work / "apk.static")
|
||||
|
||||
version = pmb.parse.apkindex.package(args, "apk-tools-static")["version"]
|
||||
version = pmb.parse.apkindex.package("apk-tools-static")["version"]
|
||||
apk_path = pmb.chroot.apk_static.download(
|
||||
args, f"apk-tools-static-{version}.apk")
|
||||
|
||||
|
@ -119,8 +119,8 @@ def test_signature_verification(args: PmbArgs, tmpdir):
|
|||
|
||||
|
||||
def test_outdated_version(args: PmbArgs, monkeypatch):
|
||||
if os.path.exists(pmb.config.work / "apk.static"):
|
||||
os.remove(pmb.config.work / "apk.static")
|
||||
if os.path.exists(get_context().config.work / "apk.static"):
|
||||
os.remove(get_context().config.work / "apk.static")
|
||||
|
||||
# Change min version for all branches
|
||||
min_copy = copy.copy(pmb.config.apk_tools_min_version)
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
import os
|
||||
import sys
|
||||
from pmb.core.types import PmbArgs
|
||||
from pmb.types import PmbArgs
|
||||
import pytest
|
||||
import shutil
|
||||
import filecmp
|
||||
|
@ -22,7 +22,7 @@ def args(tmpdir, request):
|
|||
cfg = f"{pmb_test.const.testdata}/channels.cfg"
|
||||
sys.argv = ["pmbootstrap.py", "--config-channels", cfg, "chroot"]
|
||||
args = pmb.parse.arguments()
|
||||
args.log = pmb.config.work / "log_testsuite.txt"
|
||||
args.log = get_context().config.work / "log_testsuite.txt"
|
||||
args.fork_alpine = False
|
||||
pmb.helpers.logging.init(args)
|
||||
request.addfinalizer(pmb.helpers.logging.logfd.close)
|
||||
|
@ -85,7 +85,7 @@ def test_aportgen(args: PmbArgs, tmpdir):
|
|||
os.mkdir(tmpdir + "/cross")
|
||||
|
||||
# Create aportgen folder -> code path where it still exists
|
||||
pmb.helpers.run.user(["mkdir", "-p", pmb.config.work / "aportgen"])
|
||||
pmb.helpers.run.user(["mkdir", "-p", get_context().config.work / "aportgen"])
|
||||
|
||||
# Generate all valid packages (gcc twice -> different code path)
|
||||
pkgnames = ["musl-armv7",
|
||||
|
@ -116,7 +116,7 @@ def test_aportgen_get_upstream_aport(args: PmbArgs, monkeypatch):
|
|||
# Equal version
|
||||
func = pmb.aportgen.core.get_upstream_aport
|
||||
upstream = "gcc"
|
||||
upstream_full = pmb.config.work / "cache_git/aports_upstream/main/" + upstream
|
||||
upstream_full = get_context().config.work / "cache_git/aports_upstream/main/" + upstream
|
||||
apkbuild = {"pkgver": "2.0", "pkgrel": "0"}
|
||||
package = {"version": "2.0-r0"}
|
||||
assert func(args, upstream) == upstream_full
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
# Copyright 2023 Oliver Smith
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
from pmb.core import get_context
|
||||
from pmb.helpers import logging
|
||||
from pmb.core.types import PmbArgs
|
||||
from pmb.types import PmbArgs
|
||||
import pytest
|
||||
import sys
|
||||
import shutil
|
||||
|
@ -21,7 +22,7 @@ def args(tmpdir, request):
|
|||
sys.argv = ["pmbootstrap.py", "--config-channels", cfg, "build", "-i",
|
||||
"device-testsuite-testdevice"]
|
||||
args = pmb.parse.arguments()
|
||||
args.log = pmb.config.work / "log_testsuite.txt"
|
||||
args.log = get_context().config.work / "log_testsuite.txt"
|
||||
pmb.helpers.logging.init(args)
|
||||
request.addfinalizer(pmb.helpers.logging.logfd.close)
|
||||
|
||||
|
@ -73,9 +74,10 @@ def generate(args: PmbArgs, monkeypatch, answers):
|
|||
pmb.aportgen.generate(args, "linux-testsuite-testdevice")
|
||||
monkeypatch.undo()
|
||||
|
||||
apkbuild_path = (f"{args.aports}/device/testing/"
|
||||
aports = get_context().config.aports
|
||||
apkbuild_path = (aports / "device/testing/"
|
||||
"device-testsuite-testdevice/APKBUILD")
|
||||
apkbuild_path_linux = (args.aports + "/device/testing/"
|
||||
apkbuild_path_linux = (aports / "device/testing/"
|
||||
"linux-testsuite-testdevice/APKBUILD")
|
||||
|
||||
# The build fails if the email is not a valid email, so remove them just
|
||||
|
@ -88,11 +90,11 @@ def generate(args: PmbArgs, monkeypatch, answers):
|
|||
apkbuild = pmb.parse.apkbuild(apkbuild_path)
|
||||
apkbuild_linux = pmb.parse.apkbuild(apkbuild_path_linux,
|
||||
check_pkgver=False)
|
||||
deviceinfo = pmb.parse.deviceinfo(args, "testsuite-testdevice")
|
||||
deviceinfo = pmb.parse.deviceinfo("testsuite-testdevice")
|
||||
return (deviceinfo, apkbuild, apkbuild_linux)
|
||||
|
||||
|
||||
def remove_contributor_maintainer_lines(args: PmbArgs, path):
|
||||
def remove_contributor_maintainer_lines(path):
|
||||
with open(path, "r+", encoding="utf-8") as handle:
|
||||
lines_new = []
|
||||
for line in handle.readlines():
|
||||
|
|
|
@ -9,6 +9,7 @@ import pmb.chroot.apk_static
|
|||
import pmb.parse.apkindex
|
||||
import pmb.helpers.logging
|
||||
import pmb.parse.bootimg
|
||||
from pmb.core import get_context
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
|
@ -16,7 +17,7 @@ def args(request):
|
|||
import pmb.parse
|
||||
sys.argv = ["pmbootstrap.py", "chroot"]
|
||||
args = pmb.parse.arguments()
|
||||
args.log = pmb.config.work / "log_testsuite.txt"
|
||||
args.log = get_context().config.work / "log_testsuite.txt"
|
||||
pmb.helpers.logging.init(args)
|
||||
request.addfinalizer(pmb.helpers.logging.logfd.close)
|
||||
return args
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
import os
|
||||
import sys
|
||||
from pmb.core.types import PmbArgs
|
||||
from pmb.types import PmbArgs
|
||||
import pytest
|
||||
|
||||
import pmb_test # noqa
|
||||
|
@ -15,7 +15,7 @@ def args(request, tmpdir):
|
|||
import pmb.parse
|
||||
sys.argv = ["pmbootstrap.py", "chroot"]
|
||||
args = pmb.parse.arguments()
|
||||
args.log = pmb.config.work / "log_testsuite.txt"
|
||||
args.log = get_context().config.work / "log_testsuite.txt"
|
||||
pmb.helpers.logging.init(args)
|
||||
request.addfinalizer(pmb.helpers.logging.logfd.close)
|
||||
|
||||
|
@ -44,7 +44,7 @@ def cache_apkindex(version):
|
|||
|
||||
def test_build_is_necessary(args: PmbArgs):
|
||||
# Prepare APKBUILD and APKINDEX data
|
||||
aport = pmb.helpers.pmaports.find(args, "hello-world")
|
||||
aport = pmb.helpers.pmaports.find("hello-world")
|
||||
apkbuild = pmb.parse.apkbuild(f"{aport}/APKBUILD")
|
||||
apkbuild["pkgver"] = "1"
|
||||
apkbuild["pkgrel"] = "2"
|
||||
|
@ -73,7 +73,7 @@ def test_build_is_necessary_no_binary_available(args: PmbArgs):
|
|||
hello-world package has not been built yet.
|
||||
"""
|
||||
indexes = list(pmb.helpers.other.cache["apkindex"].keys())
|
||||
aport = pmb.helpers.pmaports.find(args, "hello-world")
|
||||
aport = pmb.helpers.pmaports.find("hello-world")
|
||||
apkbuild = pmb.parse.apkbuild(f"{aport}/APKBUILD")
|
||||
assert pmb.build.is_necessary(args, None, apkbuild, indexes) is True
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
import datetime
|
||||
import glob
|
||||
import os
|
||||
from pmb.core.types import PmbArgs
|
||||
from pmb.types import PmbArgs
|
||||
import pytest
|
||||
import shutil
|
||||
import sys
|
||||
|
@ -23,7 +23,7 @@ def args(tmpdir, request):
|
|||
import pmb.parse
|
||||
sys.argv = ["pmbootstrap", "init"]
|
||||
args = pmb.parse.arguments()
|
||||
args.log = pmb.config.work / "log_testsuite.txt"
|
||||
args.log = get_context().config.work / "log_testsuite.txt"
|
||||
pmb.helpers.logging.init(args)
|
||||
request.addfinalizer(pmb.helpers.logging.logfd.close)
|
||||
return args
|
||||
|
@ -351,9 +351,9 @@ def test_build_depends_high_level(args: PmbArgs, monkeypatch):
|
|||
fake_build_is_necessary)
|
||||
|
||||
# Build hello-world to get its full output path
|
||||
channel = pmb.config.pmaports.read_config(args)["channel"]
|
||||
channel = pmb.config.pmaports.read_config()["channel"]
|
||||
output_hello = pmb.build.package(args, "hello-world")
|
||||
output_hello_outside = pmb.config.work / "packages" / channel / output_hello
|
||||
output_hello_outside = get_context().config.work / "packages" / channel / output_hello
|
||||
assert output_hello_outside.exists()
|
||||
|
||||
# Make sure the wrapper exists
|
||||
|
@ -386,7 +386,7 @@ def test_build_local_source_high_level(args: PmbArgs, tmpdir):
|
|||
aports = tmpdir + "/aports"
|
||||
aport = aports + "/device/testing/device-" + args.device
|
||||
os.makedirs(aport)
|
||||
path_original = pmb.helpers.pmaports.find(args, f"device-{args.device}")
|
||||
path_original = pmb.helpers.pmaports.find(f"device-{args.device}")
|
||||
shutil.copy(f"{path_original}/deviceinfo", aport)
|
||||
|
||||
# aports: Add modified hello-world aport (source="", uses $builddir)
|
||||
|
@ -412,7 +412,7 @@ def test_build_local_source_high_level(args: PmbArgs, tmpdir):
|
|||
pmb.helpers.run.root(["chmod", "500", unreadable])
|
||||
|
||||
# Test native arch and foreign arch chroot
|
||||
channel = pmb.config.pmaports.read_config(args)["channel"]
|
||||
channel = pmb.config.pmaports.read_config()["channel"]
|
||||
# TODO: test disabled, seems to *only* fail on gitlab runners and nowhere else.
|
||||
# See: https://gitlab.com/postmarketOS/pmbootstrap/-/issues/2346
|
||||
# for arch in [pmb.config.arch_native, "armhf"]:
|
||||
|
@ -449,7 +449,7 @@ def test_build_abuild_leftovers(args: PmbArgs, tmpdir):
|
|||
aports = f"{tmpdir}/aports"
|
||||
aport = f"{aports}/device/testing/device-{args.device}"
|
||||
os.makedirs(aport)
|
||||
path_original = pmb.helpers.pmaports.find(args, f"device-{args.device}")
|
||||
path_original = pmb.helpers.pmaports.find(f"device-{args.device}")
|
||||
shutil.copy(f"{path_original}/deviceinfo", aport)
|
||||
|
||||
# aports: Add modified hello-world aport (source="", uses $builddir)
|
||||
|
@ -468,7 +468,7 @@ def test_build_abuild_leftovers(args: PmbArgs, tmpdir):
|
|||
f"{src}/broken-tarball-symlink.tar.gz")
|
||||
|
||||
# Delete all hello-world packages
|
||||
channel = pmb.config.pmaports.read_config(args)["channel"]
|
||||
channel = pmb.config.pmaports.read_config()["channel"]
|
||||
pattern = f"{args.work}/packages/{channel}/*/hello-world-*_p*.apk"
|
||||
for path in glob.glob(pattern):
|
||||
pmb.helpers.run.root(["rm", path])
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue