chroot: put built packages into channel subdir (MR 1912)

Migrate to workdir version 5 and move already built packages into the edge
channel subdir, for example:
	$WORK/packages/x86_64/hello-world-1-r5.apk
to:
	$WORK/packages/edge/x86_64/hello-world-1-r5.apk

The build.postmarketos.org code has already been adjusted to find built
packages in either directory structure.
This commit is contained in:
Oliver Smith 2020-04-10 15:21:23 +02:00
parent d3dc3b2c98
commit 7f60a6d782
No known key found for this signature in database
GPG Key ID: 5AE7F5513E0885CB
10 changed files with 72 additions and 19 deletions

View File

@ -453,15 +453,16 @@ def finish(args, apkbuild, arch, output, strict=False, suffix="native"):
Various finishing tasks that need to be done after a build.
"""
# Verify output file
path = args.work + "/packages/" + output
channel = pmb.config.pmaports.read_config(args)["channel"]
path = f"{args.work}/packages/{channel}/{output}"
if not os.path.exists(path):
raise RuntimeError("Package not found after build: " + path)
# Clear APKINDEX cache (we only parse APKINDEX files once per session and
# cache the result for faster dependency resolving, but after we built a
# package we need to parse it again)
pmb.parse.apkindex.clear_cache(args, args.work + "/packages/" +
arch + "/APKINDEX.tar.gz")
pmb.parse.apkindex.clear_cache(args, f"{args.work}/packages/{channel}"
f"/{arch}/APKINDEX.tar.gz")
# Uninstall build dependencies (strict mode)
if strict or "pmb:strict" in apkbuild["options"]:

View File

@ -93,10 +93,11 @@ def index_repo(args, arch=None):
"""
pmb.build.init(args)
channel = pmb.config.pmaports.read_config(args)["channel"]
if arch:
paths = [args.work + "/packages/" + arch]
paths = [f"{args.work}/packages/{channel}/{arch}"]
else:
paths = glob.glob(args.work + "/packages/*")
paths = glob.glob(f"{args.work}/packages/{channel}/*")
for path in paths:
if os.path.isdir(path):

View File

@ -79,10 +79,12 @@ def mount(args, suffix="native"):
# Get all mountpoints
arch = pmb.parse.arch.from_chroot_suffix(args, suffix)
channel = pmb.config.pmaports.read_config(args)["channel"]
mountpoints = {}
for source, target in pmb.config.chroot_mount_bind.items():
source = source.replace("$WORK", args.work)
source = source.replace("$ARCH", arch)
source = source.replace("$CHANNEL", channel)
mountpoints[source] = target
# Mount if necessary

View File

@ -6,6 +6,7 @@ import math
import os
import pmb.chroot
import pmb.config.pmaports
import pmb.config.workdir
import pmb.helpers.pmaports
import pmb.helpers.run
@ -89,14 +90,18 @@ def zap(args, confirm=True, dry=False, pkgs_local=False, http=False,
def zap_pkgs_local_mismatch(args, confirm=True, dry=False):
if not os.path.exists(args.work + "/packages/"):
channel = pmb.config.pmaports.read_config(args)["channel"]
if not os.path.exists(f"{args.work}/packages/{channel}"):
return
if confirm and not pmb.helpers.cli.confirm(args, "Remove packages that are newer than"
" the corresponding package in aports?"):
question = "Remove binary packages that are newer than the corresponding" \
f" pmaports (channel '{channel}')?"
if confirm and not pmb.helpers.cli.confirm(args, question):
return
reindex = False
for apkindex_path in glob.glob(args.work + "/packages/*/APKINDEX.tar.gz"):
pattern = f"{args.work}/packages/{channel}/*/APKINDEX.tar.gz"
for apkindex_path in glob.glob(pattern):
# Delete packages without same version in aports
blocks = pmb.parse.apkindex.parse_blocks(args, apkindex_path)
for block in blocks:
@ -107,7 +112,7 @@ def zap_pkgs_local_mismatch(args, confirm=True, dry=False):
# Apk path
apk_path_short = arch + "/" + pkgname + "-" + version + ".apk"
apk_path = args.work + "/packages/" + apk_path_short
apk_path = f"{args.work}/packages/{channel}/{apk_path_short}"
if not os.path.exists(apk_path):
logging.info("WARNING: Package mentioned in index not"
" found: " + apk_path_short)

View File

@ -29,7 +29,7 @@ pmaports_min_version = "7"
# Version of the work folder (as asked during 'pmbootstrap init'). Increase
# this number, whenever migration is required and provide the migration code,
# see migrate_work_folder()).
work_version = 4
work_version = 5
# Programs that pmbootstrap expects to be available from the host system. Keep
# in sync with README.md, and try to keep the list as small as possible. The
@ -118,6 +118,7 @@ chroot_host_path = os.environ["PATH"] + ":/usr/sbin/"
# Folders, that get mounted inside the chroot
# $WORK gets replaced with args.work
# $ARCH gets replaced with the chroot architecture (eg. x86_64, armhf)
# $CHANNEL gets replaced with the release channel (e.g. edge, stable)
chroot_mount_bind = {
"/proc": "/proc",
"$WORK/cache_apk_$ARCH": "/var/cache/apk",
@ -127,7 +128,7 @@ chroot_mount_bind = {
"$WORK/cache_rust": "/mnt/pmbootstrap-rust",
"$WORK/config_abuild": "/mnt/pmbootstrap-abuild-config",
"$WORK/config_apk_keys": "/etc/apk/keys",
"$WORK/packages": "/mnt/pmbootstrap-packages",
"$WORK/packages/$CHANNEL": "/mnt/pmbootstrap-packages",
}
# Building chroots (all chroots, except for the rootfs_ chroot) get symlinks in

View File

@ -176,6 +176,9 @@ def switch_to_channel_branch(args, channel_new):
logging.info(f"Switching to branch '{branch_new}' on channel"
f" '{channel_new}'...")
# Make sure we don't have mounts related to the old channel
pmb.chroot.shutdown(args)
# 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(args, ["git", "checkout", branch_new],

View File

@ -164,6 +164,39 @@ def migrate_work_folder(args):
migrate_success(args, 4)
current = 4
if current == 4:
# Ask for confirmation
logging.info("Changelog:")
logging.info("* packages built by pmbootstrap are in a channel subdir")
logging.info("Migration will do the following:")
logging.info("* Move existing packages to edge subdir (if any)")
logging.info("* Zap your chroots")
if not pmb.helpers.cli.confirm(args):
raise RuntimeError("Aborted.")
# Zap chroots
pmb.chroot.zap(args, False)
# Move packages to edge subdir
edge_path = f"{args.work}/packages/edge"
pmb.helpers.run.root(args, ["mkdir", "-p", edge_path])
for arch in pmb.config.build_device_architectures:
old_path = f"{args.work}/packages/{arch}"
new_path = f"{edge_path}/{arch}"
if os.path.exists(old_path):
if os.path.exists(new_path):
raise RuntimeError(f"Won't move '{old_path}' to"
f" '{new_path}', destination already"
" exists! Consider 'pmbootstrap zap -p'"
f" to delete '{args.work}/packages'.")
pmb.helpers.run.root(args, ["mv", old_path, new_path])
pmb.helpers.run.root(args, ["chown", pmb.config.chroot_uid_user,
edge_path])
# Update version file
migrate_success(args, 5)
current = 5
# Can't migrate, user must delete it
if current != required:
raise RuntimeError("Sorry, we can't migrate that automatically. Please"

View File

@ -101,7 +101,8 @@ def apkindex_files(args, arch=None, user_repository=True, pmos=True,
ret = []
# Local user repository (for packages compiled with pmbootstrap)
if user_repository:
ret = [args.work + "/packages/" + arch + "/APKINDEX.tar.gz"]
channel = pmb.config.pmaports.read_config(args)["channel"]
ret = [f"{args.work}/packages/{channel}/{arch}/APKINDEX.tar.gz"]
# Resolve the APKINDEX.$HASH.tar.gz files
for url in urls(args, False, pmos, alpine):

View File

@ -351,8 +351,9 @@ def test_build_depends_high_level(args, monkeypatch):
fake_build_is_necessary)
# Build hello-world to get its full output path
channel = pmb.config.pmaports.read_config(args)["channel"]
output_hello = pmb.build.package(args, "hello-world")
output_hello_outside = args.work + "/packages/" + output_hello
output_hello_outside = f"{args.work}/packages/{channel}/{output_hello}"
assert os.path.exists(output_hello_outside)
# Make sure the wrapper exists
@ -411,9 +412,10 @@ def test_build_local_source_high_level(args, tmpdir):
pmb.helpers.run.root(args, ["chmod", "500", unreadable])
# Test native arch and foreign arch chroot
channel = pmb.config.pmaports.read_config(args)["channel"]
for arch in [args.arch_native, "armhf"]:
# Delete all hello-world --src packages
pattern = args.work + "/packages/" + arch + "/hello-world-*_p*.apk"
pattern = f"{args.work}/packages/{channel}/{arch}/hello-world-*_p*.apk"
for path in glob.glob(pattern):
pmb.helpers.run.root(args, ["rm", path])
assert len(glob.glob(pattern)) == 0

View File

@ -93,8 +93,10 @@ def setup_work(args, tmpdir):
"/_aports"])
# Empty packages folder
pmb.helpers.run.user(args, ["mkdir", "-p", tmpdir + "/packages"])
pmb.helpers.run.user(args, ["chmod", "777", tmpdir + "/packages"])
channel = pmb.config.pmaports.read_config(args)["channel"]
packages_path = f"{tmpdir}/packages/{channel}"
pmb.helpers.run.user(args, ["mkdir", "-p", packages_path])
pmb.helpers.run.user(args, ["chmod", "777", packages_path])
# Copy over the pmbootstrap config
pmb.helpers.run.user(args, ["cp", args.config, tmpdir +
@ -138,8 +140,10 @@ def test_pkgrel_bump_high_level(args, tmpdir):
verify_pkgrels(args, tmpdir, 1, 0, 0)
# Delete package with previous soname (--auto-dry exits with >0 now)
pmb.helpers.run.root(args, ["rm", tmpdir + "/packages/" +
args.arch_native + "/testlib-1.0-r0.apk"])
channel = pmb.config.pmaports.read_config(args)["channel"]
arch = args.arch_native
apk_path = f"{tmpdir}/packages/{channel}/{arch}/testlib-1.0-r0.apk"
pmb.helpers.run.root(args, ["rm", apk_path])
pmbootstrap(args, tmpdir, ["index"])
pmbootstrap(args, tmpdir, ["pkgrel_bump", "--dry", "--auto"], False)
verify_pkgrels(args, tmpdir, 1, 0, 0)