2023-01-22 18:11:10 +00:00
|
|
|
# Copyright 2023 Oliver Smith
|
2020-02-20 20:07:28 +00:00
|
|
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
2020-06-22 11:40:30 +00:00
|
|
|
import glob
|
2017-07-18 19:01:11 +00:00
|
|
|
import json
|
2017-09-18 21:36:54 +00:00
|
|
|
import logging
|
|
|
|
import os
|
2017-08-14 14:25:28 +00:00
|
|
|
import sys
|
|
|
|
|
2017-07-18 19:01:11 +00:00
|
|
|
import pmb.aportgen
|
|
|
|
import pmb.build
|
2017-11-28 19:12:16 +00:00
|
|
|
import pmb.build.autodetect
|
2017-07-18 19:01:11 +00:00
|
|
|
import pmb.chroot
|
|
|
|
import pmb.chroot.initfs
|
|
|
|
import pmb.chroot.other
|
2022-10-20 19:08:42 +00:00
|
|
|
import pmb.ci
|
2019-02-09 16:58:54 +00:00
|
|
|
import pmb.config
|
2018-03-30 01:11:20 +00:00
|
|
|
import pmb.export
|
2017-07-18 19:01:11 +00:00
|
|
|
import pmb.flasher
|
2022-10-20 18:02:41 +00:00
|
|
|
import pmb.helpers.aportupgrade
|
2020-10-28 17:31:40 +00:00
|
|
|
import pmb.helpers.devices
|
2020-01-06 05:39:57 +00:00
|
|
|
import pmb.helpers.git
|
2020-02-06 12:03:02 +00:00
|
|
|
import pmb.helpers.lint
|
2017-07-18 19:01:11 +00:00
|
|
|
import pmb.helpers.logging
|
2018-01-14 01:26:42 +00:00
|
|
|
import pmb.helpers.pkgrel_bump
|
2018-11-15 07:30:49 +00:00
|
|
|
import pmb.helpers.pmaports
|
2017-11-19 15:04:08 +00:00
|
|
|
import pmb.helpers.repo
|
new action: 'pmbootstrap repo_missing'
Add a new action that lists all aports, for which no binary packages
exist. Only list packages that can be built for the relevant arch
(specified with --arch). This works recursively: when a package can be
built for a certain arch, but one of its dependencies
(or their depends) can not be built for that arch, then don't list it.
This action will be used for the new sr.ht based build infrastructure,
to figure out which packages need to be built ahead of time (so we can
trigger each of them as single build job). Determining the order of the
packages to be built is not determined with pmbootstrap, the serverside
code of build.postmarketos.org takes care of that.
For testing purposes, a single package can also be specified and the
action will list if it can be built for that arch with its
dependencies, and what needs to be built exactly.
Add pmb/helpers/package.py to hold functions that work on both pmaports
and (binary package) repos - in contrary to the existing
pmb/helpers/pmaports.py (see previous commit) and pmb/helpers/repo.py,
which only work with one of those.
Refactoring:
* pmb/helpers/pmaports.py: add a get_list() function, which lists all
aports and use it instead of writing the same glob loop over and over
* add pmb.helpers.pmaports.get(), which finds an APKBUILD and parses it
in one step.
* rename pmb.build._package.check_arch to ...check_arch_abort to
distinguish it from the other check_arch function
2018-11-15 07:36:39 +00:00
|
|
|
import pmb.helpers.repo_missing
|
2017-07-18 19:01:11 +00:00
|
|
|
import pmb.helpers.run
|
2020-02-04 20:39:53 +00:00
|
|
|
import pmb.helpers.status
|
2017-07-18 19:01:11 +00:00
|
|
|
import pmb.install
|
2020-06-04 09:19:44 +00:00
|
|
|
import pmb.install.blockdevice
|
2021-07-01 15:16:34 +00:00
|
|
|
import pmb.netboot
|
2017-07-18 19:01:11 +00:00
|
|
|
import pmb.parse
|
2017-08-09 20:26:40 +00:00
|
|
|
import pmb.qemu
|
2022-10-20 18:02:41 +00:00
|
|
|
import pmb.sideload
|
2017-07-18 19:01:11 +00:00
|
|
|
|
|
|
|
|
2020-01-22 18:30:43 +00:00
|
|
|
def _parse_flavor(args, autoinstall=True):
|
2017-09-02 03:53:58 +00:00
|
|
|
"""
|
|
|
|
Verify the flavor argument if specified, or return a default value.
|
2020-01-22 18:30:43 +00:00
|
|
|
:param autoinstall: make sure that at least one kernel flavor is installed
|
2017-09-02 03:53:58 +00:00
|
|
|
"""
|
2021-08-18 23:31:59 +00:00
|
|
|
# Install a kernel and get its "flavor", where flavor is a pmOS-specific
|
|
|
|
# identifier that is typically in the form
|
|
|
|
# "postmarketos-<manufacturer>-<device/chip>", e.g.
|
|
|
|
# "postmarketos-qcom-sdm845"
|
2017-09-02 03:53:58 +00:00
|
|
|
suffix = "rootfs_" + args.device
|
2021-08-18 23:31:59 +00:00
|
|
|
flavor = pmb.chroot.other.kernel_flavor_installed(
|
2021-05-19 18:36:24 +00:00
|
|
|
args, suffix, autoinstall)
|
2017-09-02 03:53:58 +00:00
|
|
|
|
2021-08-18 23:31:59 +00:00
|
|
|
if not flavor:
|
2017-09-02 03:53:58 +00:00
|
|
|
raise RuntimeError(
|
|
|
|
"No kernel flavors installed in chroot " + suffix + "! Please let"
|
|
|
|
" your device package depend on a package starting with 'linux-'.")
|
2021-08-18 23:31:59 +00:00
|
|
|
return flavor
|
2017-09-02 03:53:58 +00:00
|
|
|
|
|
|
|
|
2017-07-26 18:59:11 +00:00
|
|
|
def _parse_suffix(args):
|
2017-10-25 22:54:17 +00:00
|
|
|
if "rootfs" in args and args.rootfs:
|
2017-07-26 18:59:11 +00:00
|
|
|
return "rootfs_" + args.device
|
|
|
|
elif args.buildroot:
|
2017-10-28 00:45:15 +00:00
|
|
|
if args.buildroot == "device":
|
|
|
|
return "buildroot_" + args.deviceinfo["arch"]
|
|
|
|
else:
|
|
|
|
return "buildroot_" + args.buildroot
|
2017-07-26 18:59:11 +00:00
|
|
|
elif args.suffix:
|
|
|
|
return args.suffix
|
|
|
|
else:
|
|
|
|
return "native"
|
|
|
|
|
|
|
|
|
2020-10-06 09:34:19 +00:00
|
|
|
def _install_ondev_verify_no_rootfs(args):
|
|
|
|
chroot_dest = "/var/lib/rootfs.img"
|
|
|
|
dest = f"{args.work}/chroot_installer_{args.device}{chroot_dest}"
|
|
|
|
if os.path.exists(dest):
|
|
|
|
return
|
|
|
|
|
|
|
|
if args.ondev_cp:
|
|
|
|
for _, chroot_dest_cp in args.ondev_cp:
|
|
|
|
if chroot_dest_cp == chroot_dest:
|
|
|
|
return
|
|
|
|
|
|
|
|
raise ValueError(f"--no-rootfs set, but rootfs.img not found in install"
|
|
|
|
" chroot. Either run 'pmbootstrap install' without"
|
|
|
|
" --no-rootfs first to let it generate the postmarketOS"
|
|
|
|
" rootfs once, or supply a rootfs file with:"
|
|
|
|
f" --cp os.img:{chroot_dest}")
|
|
|
|
|
|
|
|
|
2017-07-18 19:01:11 +00:00
|
|
|
def aportgen(args):
|
2017-07-26 18:59:11 +00:00
|
|
|
for package in args.packages:
|
2017-10-30 19:56:38 +00:00
|
|
|
logging.info("Generate aport: " + package)
|
2017-07-26 18:59:11 +00:00
|
|
|
pmb.aportgen.generate(args, package)
|
2017-07-18 19:01:11 +00:00
|
|
|
|
|
|
|
|
|
|
|
def build(args):
|
Fix #824: Refactor pmb/build/package.py (make depends work like in abuild) (#935)
* Rename pmb/build/package.py to pmb/build/_package.py, so we can
access the functions it contains in testcases, and still use
pmb.build.package()
* Refactor the entire file. Instead of one big function that does
too many things, we have many small ones now, that are tested
in the testsuite and easier to modify
* Whenever building a package, pmbootstrap does not only build and
install the "makedepends" (like we did before), now it does the
same for the "depends". That's required to be compatible with
abuild. The old behavior can still be used with 'pmbootstrap
build --ignore-depends'.
* Because of that change, noarch packages can no longer be built in
the native chroot if we need them for a foreign chroot. A device-
package depending on a kernel would pull in the same kernel for
the native architecture otherwise.
* Running 'pmbootstrap build device-...' without '--ignore-depends'
and without a matching '--arch' displays a note that explains
this change to the user and tells how to use it instead.
* Noarch packages no longer get symlinked. That was only
implemented for packages built in the native chroot, and now that
is not always the case anymore. Symlinking these packages creates
packages with broken dependencies anyway (e.g.
device-samsung-i9100 can't be installed in x86_64, because
linux-samsung-i9100 is armhf only).
* Rename "carch" to "arch" wherever used. Naming it "carch"
sometimes is confusing with no benefit.
* Add a testcase for the aarch64 qemu workaround (because it failed
first and I needed to know for sure if it is working again).
* Improved some verbose logging, which helped with development of
this feature.
* Removed the old "build" test case (which was disabled in
testcases_fast.sh) as the new "build_package" test case covers its
functionallity.
* Only build indexes if the packages folder exists for that arch (Travis
couldn't run a test case otherwise)
2017-11-26 14:32:02 +00:00
|
|
|
# Strict mode: zap everything
|
2017-09-08 23:50:59 +00:00
|
|
|
if args.strict:
|
|
|
|
pmb.chroot.zap(args, False)
|
Fix #824: Refactor pmb/build/package.py (make depends work like in abuild) (#935)
* Rename pmb/build/package.py to pmb/build/_package.py, so we can
access the functions it contains in testcases, and still use
pmb.build.package()
* Refactor the entire file. Instead of one big function that does
too many things, we have many small ones now, that are tested
in the testsuite and easier to modify
* Whenever building a package, pmbootstrap does not only build and
install the "makedepends" (like we did before), now it does the
same for the "depends". That's required to be compatible with
abuild. The old behavior can still be used with 'pmbootstrap
build --ignore-depends'.
* Because of that change, noarch packages can no longer be built in
the native chroot if we need them for a foreign chroot. A device-
package depending on a kernel would pull in the same kernel for
the native architecture otherwise.
* Running 'pmbootstrap build device-...' without '--ignore-depends'
and without a matching '--arch' displays a note that explains
this change to the user and tells how to use it instead.
* Noarch packages no longer get symlinked. That was only
implemented for packages built in the native chroot, and now that
is not always the case anymore. Symlinking these packages creates
packages with broken dependencies anyway (e.g.
device-samsung-i9100 can't be installed in x86_64, because
linux-samsung-i9100 is armhf only).
* Rename "carch" to "arch" wherever used. Naming it "carch"
sometimes is confusing with no benefit.
* Add a testcase for the aarch64 qemu workaround (because it failed
first and I needed to know for sure if it is working again).
* Improved some verbose logging, which helped with development of
this feature.
* Removed the old "build" test case (which was disabled in
testcases_fast.sh) as the new "build_package" test case covers its
functionallity.
* Only build indexes if the packages folder exists for that arch (Travis
couldn't run a test case otherwise)
2017-11-26 14:32:02 +00:00
|
|
|
|
2018-08-22 20:28:10 +00:00
|
|
|
if args.envkernel:
|
|
|
|
pmb.build.envkernel.package_kernel(args)
|
|
|
|
return
|
|
|
|
|
2018-02-19 22:04:01 +00:00
|
|
|
# Set src and force
|
2021-05-19 18:36:24 +00:00
|
|
|
src = os.path.realpath(os.path.expanduser(args.src[0])) \
|
|
|
|
if args.src else None
|
2018-02-19 22:04:01 +00:00
|
|
|
force = True if src else args.force
|
|
|
|
if src and not os.path.exists(src):
|
|
|
|
raise RuntimeError("Invalid path specified for --src: " + src)
|
|
|
|
|
Fix #824: Refactor pmb/build/package.py (make depends work like in abuild) (#935)
* Rename pmb/build/package.py to pmb/build/_package.py, so we can
access the functions it contains in testcases, and still use
pmb.build.package()
* Refactor the entire file. Instead of one big function that does
too many things, we have many small ones now, that are tested
in the testsuite and easier to modify
* Whenever building a package, pmbootstrap does not only build and
install the "makedepends" (like we did before), now it does the
same for the "depends". That's required to be compatible with
abuild. The old behavior can still be used with 'pmbootstrap
build --ignore-depends'.
* Because of that change, noarch packages can no longer be built in
the native chroot if we need them for a foreign chroot. A device-
package depending on a kernel would pull in the same kernel for
the native architecture otherwise.
* Running 'pmbootstrap build device-...' without '--ignore-depends'
and without a matching '--arch' displays a note that explains
this change to the user and tells how to use it instead.
* Noarch packages no longer get symlinked. That was only
implemented for packages built in the native chroot, and now that
is not always the case anymore. Symlinking these packages creates
packages with broken dependencies anyway (e.g.
device-samsung-i9100 can't be installed in x86_64, because
linux-samsung-i9100 is armhf only).
* Rename "carch" to "arch" wherever used. Naming it "carch"
sometimes is confusing with no benefit.
* Add a testcase for the aarch64 qemu workaround (because it failed
first and I needed to know for sure if it is working again).
* Improved some verbose logging, which helped with development of
this feature.
* Removed the old "build" test case (which was disabled in
testcases_fast.sh) as the new "build_package" test case covers its
functionallity.
* Only build indexes if the packages folder exists for that arch (Travis
couldn't run a test case otherwise)
2017-11-26 14:32:02 +00:00
|
|
|
# Build all packages
|
2017-07-26 18:59:11 +00:00
|
|
|
for package in args.packages:
|
2017-11-28 19:12:16 +00:00
|
|
|
arch_package = args.arch or pmb.build.autodetect.arch(args, package)
|
2018-02-19 22:04:01 +00:00
|
|
|
if not pmb.build.package(args, package, arch_package, force,
|
|
|
|
args.strict, src=src):
|
2018-01-28 23:27:33 +00:00
|
|
|
logging.info("NOTE: Package '" + package + "' is up to date. Use"
|
|
|
|
" 'pmbootstrap build " + package + " --force'"
|
|
|
|
" if needed.")
|
2017-07-18 19:01:11 +00:00
|
|
|
|
|
|
|
|
|
|
|
def build_init(args):
|
2017-07-26 18:59:11 +00:00
|
|
|
suffix = _parse_suffix(args)
|
|
|
|
pmb.build.init(args, suffix)
|
2017-07-18 19:01:11 +00:00
|
|
|
|
|
|
|
|
|
|
|
def checksum(args):
|
2017-07-26 18:59:11 +00:00
|
|
|
for package in args.packages:
|
2019-05-19 20:04:55 +00:00
|
|
|
if args.verify:
|
|
|
|
pmb.build.checksum.verify(args, package)
|
|
|
|
else:
|
2019-05-24 20:41:31 +00:00
|
|
|
pmb.build.checksum.update(args, package)
|
2017-07-18 19:01:11 +00:00
|
|
|
|
|
|
|
|
2020-04-03 16:09:36 +00:00
|
|
|
def sideload(args):
|
|
|
|
arch = args.deviceinfo["arch"]
|
|
|
|
if args.arch:
|
|
|
|
arch = args.arch
|
|
|
|
user = args.user
|
|
|
|
host = args.host
|
2021-04-05 21:45:39 +00:00
|
|
|
pmb.sideload.sideload(args, user, host, args.port, arch, args.install_key,
|
|
|
|
args.packages)
|
2020-04-03 16:09:36 +00:00
|
|
|
|
|
|
|
|
2021-07-01 15:16:34 +00:00
|
|
|
def netboot(args):
|
|
|
|
if args.action_netboot == "serve":
|
|
|
|
pmb.netboot.start_nbd_server(args)
|
|
|
|
|
|
|
|
|
2017-07-18 19:01:11 +00:00
|
|
|
def chroot(args):
|
aportgen: Gracefully handle old aports_upstream (#1291)
In order to get cross-compilers, we generate a few aports (e.g.
binutils-armhf, gcc-armhf) automatically from Alpine's aports.
pmbootstrap was already able to perform a git checkout of Alpine's
aports repository. But it needed to be manually updated. Otherwise
the `pmbootstrap aportgen` command could actually downgrade the aport
instead of updating it to the current version.
After thinking about adding a dedicated pmbootstrap command for
updating git repositories, I thought it would be better to not open
that can of worms (pmbootstrap as general git wrapper? no thanks).
The solution implemented here compares the upstream aport version of
the git checkout of a certain package (e.g. gcc for gcc-armhf) with the
version in Alpine's binary package APKINDEX. When the aport version is
lower than the binary package version, it shows the user how to update
the git repository with just one command:
pmbootstrap chroot --add=git --user -- \
git -C /mnt/pmbootstrap-git/aports_upstream pull
Changes:
* `pmb.aportgen.core.get_upstream_aport()`: new function, that returns
the absolute path to the upstream aport on disk, after checking the
version of the aport against the binary package.
* Use that new function in pmb.aportgen.gcc and pmb.aportgen.binutils
* New function `pmb.helpers.repo.alpine_apkindex_path()`: updates the
APKINDEX if necessary and returns the absolute path to the APKINDEX.
This code was basically present already, but not as function, so now
we have a bit less overhead there.
* `pmbootstrap chroot`: new `--user` argument
* `pmb.parse.apkbuild`: make pkgname check optional, as it fails with
the official gcc APKBUILD before we modify it (the current APKBUILD
parser is not meant to be perfect, as this would require a full shell
parsing implementation).
* Extended `test_aportgen.py` and enabled it by default in
`testcases_fast.sh`. Previously it was disabled due to traffic
concerns (cloning the aports repo, but then again we do a full KDE
plasma mobile installation in Travis now, so that shouldn't matter
too much).
* `testcases_fast.sh`: With "test_aport_in_sync_with_git" removed
from the disabled-by-default list (left over from timestamp based
rebuilds), there were no more test cases disabled by default. I've
changed it, so now the qemu_running_processes test case is disabled,
and added an `--all` parameter to the script to disable no test
cases. Travis runs with the `--all` parameter while it's useful to
do a quick local test without `--all` in roughly 2 minutes instead of
10.
* `aports/cross/binutils-*`: Fix `_mirror` variable to point to current
default Alpine mirror (so the aportgen testcase runs through).
2018-03-11 14:18:21 +00:00
|
|
|
# Suffix
|
2017-07-26 18:59:11 +00:00
|
|
|
suffix = _parse_suffix(args)
|
aportgen: Gracefully handle old aports_upstream (#1291)
In order to get cross-compilers, we generate a few aports (e.g.
binutils-armhf, gcc-armhf) automatically from Alpine's aports.
pmbootstrap was already able to perform a git checkout of Alpine's
aports repository. But it needed to be manually updated. Otherwise
the `pmbootstrap aportgen` command could actually downgrade the aport
instead of updating it to the current version.
After thinking about adding a dedicated pmbootstrap command for
updating git repositories, I thought it would be better to not open
that can of worms (pmbootstrap as general git wrapper? no thanks).
The solution implemented here compares the upstream aport version of
the git checkout of a certain package (e.g. gcc for gcc-armhf) with the
version in Alpine's binary package APKINDEX. When the aport version is
lower than the binary package version, it shows the user how to update
the git repository with just one command:
pmbootstrap chroot --add=git --user -- \
git -C /mnt/pmbootstrap-git/aports_upstream pull
Changes:
* `pmb.aportgen.core.get_upstream_aport()`: new function, that returns
the absolute path to the upstream aport on disk, after checking the
version of the aport against the binary package.
* Use that new function in pmb.aportgen.gcc and pmb.aportgen.binutils
* New function `pmb.helpers.repo.alpine_apkindex_path()`: updates the
APKINDEX if necessary and returns the absolute path to the APKINDEX.
This code was basically present already, but not as function, so now
we have a bit less overhead there.
* `pmbootstrap chroot`: new `--user` argument
* `pmb.parse.apkbuild`: make pkgname check optional, as it fails with
the official gcc APKBUILD before we modify it (the current APKBUILD
parser is not meant to be perfect, as this would require a full shell
parsing implementation).
* Extended `test_aportgen.py` and enabled it by default in
`testcases_fast.sh`. Previously it was disabled due to traffic
concerns (cloning the aports repo, but then again we do a full KDE
plasma mobile installation in Travis now, so that shouldn't matter
too much).
* `testcases_fast.sh`: With "test_aport_in_sync_with_git" removed
from the disabled-by-default list (left over from timestamp based
rebuilds), there were no more test cases disabled by default. I've
changed it, so now the qemu_running_processes test case is disabled,
and added an `--all` parameter to the script to disable no test
cases. Travis runs with the `--all` parameter while it's useful to
do a quick local test without `--all` in roughly 2 minutes instead of
10.
* `aports/cross/binutils-*`: Fix `_mirror` variable to point to current
default Alpine mirror (so the aportgen testcase runs through).
2018-03-11 14:18:21 +00:00
|
|
|
if (args.user and suffix != "native" and
|
|
|
|
not suffix.startswith("buildroot_")):
|
|
|
|
raise RuntimeError("--user is only supported for native or"
|
|
|
|
" buildroot_* chroots.")
|
2020-06-02 21:29:33 +00:00
|
|
|
if args.xauth and suffix != "native":
|
|
|
|
raise RuntimeError("--xauth is only supported for native chroot.")
|
aportgen: Gracefully handle old aports_upstream (#1291)
In order to get cross-compilers, we generate a few aports (e.g.
binutils-armhf, gcc-armhf) automatically from Alpine's aports.
pmbootstrap was already able to perform a git checkout of Alpine's
aports repository. But it needed to be manually updated. Otherwise
the `pmbootstrap aportgen` command could actually downgrade the aport
instead of updating it to the current version.
After thinking about adding a dedicated pmbootstrap command for
updating git repositories, I thought it would be better to not open
that can of worms (pmbootstrap as general git wrapper? no thanks).
The solution implemented here compares the upstream aport version of
the git checkout of a certain package (e.g. gcc for gcc-armhf) with the
version in Alpine's binary package APKINDEX. When the aport version is
lower than the binary package version, it shows the user how to update
the git repository with just one command:
pmbootstrap chroot --add=git --user -- \
git -C /mnt/pmbootstrap-git/aports_upstream pull
Changes:
* `pmb.aportgen.core.get_upstream_aport()`: new function, that returns
the absolute path to the upstream aport on disk, after checking the
version of the aport against the binary package.
* Use that new function in pmb.aportgen.gcc and pmb.aportgen.binutils
* New function `pmb.helpers.repo.alpine_apkindex_path()`: updates the
APKINDEX if necessary and returns the absolute path to the APKINDEX.
This code was basically present already, but not as function, so now
we have a bit less overhead there.
* `pmbootstrap chroot`: new `--user` argument
* `pmb.parse.apkbuild`: make pkgname check optional, as it fails with
the official gcc APKBUILD before we modify it (the current APKBUILD
parser is not meant to be perfect, as this would require a full shell
parsing implementation).
* Extended `test_aportgen.py` and enabled it by default in
`testcases_fast.sh`. Previously it was disabled due to traffic
concerns (cloning the aports repo, but then again we do a full KDE
plasma mobile installation in Travis now, so that shouldn't matter
too much).
* `testcases_fast.sh`: With "test_aport_in_sync_with_git" removed
from the disabled-by-default list (left over from timestamp based
rebuilds), there were no more test cases disabled by default. I've
changed it, so now the qemu_running_processes test case is disabled,
and added an `--all` parameter to the script to disable no test
cases. Travis runs with the `--all` parameter while it's useful to
do a quick local test without `--all` in roughly 2 minutes instead of
10.
* `aports/cross/binutils-*`: Fix `_mirror` variable to point to current
default Alpine mirror (so the aportgen testcase runs through).
2018-03-11 14:18:21 +00:00
|
|
|
|
|
|
|
# apk: check minimum version, install packages
|
2017-07-26 18:59:11 +00:00
|
|
|
pmb.chroot.apk.check_min_version(args, suffix)
|
2018-02-20 19:52:28 +00:00
|
|
|
if args.add:
|
|
|
|
pmb.chroot.apk.install(args, args.add.split(","), suffix)
|
aportgen: Gracefully handle old aports_upstream (#1291)
In order to get cross-compilers, we generate a few aports (e.g.
binutils-armhf, gcc-armhf) automatically from Alpine's aports.
pmbootstrap was already able to perform a git checkout of Alpine's
aports repository. But it needed to be manually updated. Otherwise
the `pmbootstrap aportgen` command could actually downgrade the aport
instead of updating it to the current version.
After thinking about adding a dedicated pmbootstrap command for
updating git repositories, I thought it would be better to not open
that can of worms (pmbootstrap as general git wrapper? no thanks).
The solution implemented here compares the upstream aport version of
the git checkout of a certain package (e.g. gcc for gcc-armhf) with the
version in Alpine's binary package APKINDEX. When the aport version is
lower than the binary package version, it shows the user how to update
the git repository with just one command:
pmbootstrap chroot --add=git --user -- \
git -C /mnt/pmbootstrap-git/aports_upstream pull
Changes:
* `pmb.aportgen.core.get_upstream_aport()`: new function, that returns
the absolute path to the upstream aport on disk, after checking the
version of the aport against the binary package.
* Use that new function in pmb.aportgen.gcc and pmb.aportgen.binutils
* New function `pmb.helpers.repo.alpine_apkindex_path()`: updates the
APKINDEX if necessary and returns the absolute path to the APKINDEX.
This code was basically present already, but not as function, so now
we have a bit less overhead there.
* `pmbootstrap chroot`: new `--user` argument
* `pmb.parse.apkbuild`: make pkgname check optional, as it fails with
the official gcc APKBUILD before we modify it (the current APKBUILD
parser is not meant to be perfect, as this would require a full shell
parsing implementation).
* Extended `test_aportgen.py` and enabled it by default in
`testcases_fast.sh`. Previously it was disabled due to traffic
concerns (cloning the aports repo, but then again we do a full KDE
plasma mobile installation in Travis now, so that shouldn't matter
too much).
* `testcases_fast.sh`: With "test_aport_in_sync_with_git" removed
from the disabled-by-default list (left over from timestamp based
rebuilds), there were no more test cases disabled by default. I've
changed it, so now the qemu_running_processes test case is disabled,
and added an `--all` parameter to the script to disable no test
cases. Travis runs with the `--all` parameter while it's useful to
do a quick local test without `--all` in roughly 2 minutes instead of
10.
* `aports/cross/binutils-*`: Fix `_mirror` variable to point to current
default Alpine mirror (so the aportgen testcase runs through).
2018-03-11 14:18:21 +00:00
|
|
|
|
2020-06-02 21:29:33 +00:00
|
|
|
# Xauthority
|
|
|
|
env = {}
|
|
|
|
if args.xauth:
|
|
|
|
pmb.chroot.other.copy_xauthority(args)
|
|
|
|
env["DISPLAY"] = os.environ.get("DISPLAY")
|
|
|
|
env["XAUTHORITY"] = "/home/pmos/.Xauthority"
|
|
|
|
|
2020-06-04 09:19:44 +00:00
|
|
|
# Install blockdevice
|
|
|
|
if args.install_blockdev:
|
2020-06-06 16:39:21 +00:00
|
|
|
size_boot = 128 # 128 MiB
|
|
|
|
size_root = 4096 # 4 GiB
|
2020-06-06 17:05:11 +00:00
|
|
|
size_reserve = 2048 # 2 GiB
|
2020-06-04 09:19:44 +00:00
|
|
|
pmb.install.blockdevice.create_and_mount_image(args, size_boot,
|
2020-06-06 17:05:11 +00:00
|
|
|
size_root, size_reserve)
|
2020-06-04 09:19:44 +00:00
|
|
|
|
aportgen: Gracefully handle old aports_upstream (#1291)
In order to get cross-compilers, we generate a few aports (e.g.
binutils-armhf, gcc-armhf) automatically from Alpine's aports.
pmbootstrap was already able to perform a git checkout of Alpine's
aports repository. But it needed to be manually updated. Otherwise
the `pmbootstrap aportgen` command could actually downgrade the aport
instead of updating it to the current version.
After thinking about adding a dedicated pmbootstrap command for
updating git repositories, I thought it would be better to not open
that can of worms (pmbootstrap as general git wrapper? no thanks).
The solution implemented here compares the upstream aport version of
the git checkout of a certain package (e.g. gcc for gcc-armhf) with the
version in Alpine's binary package APKINDEX. When the aport version is
lower than the binary package version, it shows the user how to update
the git repository with just one command:
pmbootstrap chroot --add=git --user -- \
git -C /mnt/pmbootstrap-git/aports_upstream pull
Changes:
* `pmb.aportgen.core.get_upstream_aport()`: new function, that returns
the absolute path to the upstream aport on disk, after checking the
version of the aport against the binary package.
* Use that new function in pmb.aportgen.gcc and pmb.aportgen.binutils
* New function `pmb.helpers.repo.alpine_apkindex_path()`: updates the
APKINDEX if necessary and returns the absolute path to the APKINDEX.
This code was basically present already, but not as function, so now
we have a bit less overhead there.
* `pmbootstrap chroot`: new `--user` argument
* `pmb.parse.apkbuild`: make pkgname check optional, as it fails with
the official gcc APKBUILD before we modify it (the current APKBUILD
parser is not meant to be perfect, as this would require a full shell
parsing implementation).
* Extended `test_aportgen.py` and enabled it by default in
`testcases_fast.sh`. Previously it was disabled due to traffic
concerns (cloning the aports repo, but then again we do a full KDE
plasma mobile installation in Travis now, so that shouldn't matter
too much).
* `testcases_fast.sh`: With "test_aport_in_sync_with_git" removed
from the disabled-by-default list (left over from timestamp based
rebuilds), there were no more test cases disabled by default. I've
changed it, so now the qemu_running_processes test case is disabled,
and added an `--all` parameter to the script to disable no test
cases. Travis runs with the `--all` parameter while it's useful to
do a quick local test without `--all` in roughly 2 minutes instead of
10.
* `aports/cross/binutils-*`: Fix `_mirror` variable to point to current
default Alpine mirror (so the aportgen testcase runs through).
2018-03-11 14:18:21 +00:00
|
|
|
# Run the command as user/root
|
|
|
|
if args.user:
|
|
|
|
logging.info("(" + suffix + ") % su pmos -c '" +
|
|
|
|
" ".join(args.command) + "'")
|
2020-06-02 21:29:33 +00:00
|
|
|
pmb.chroot.user(args, args.command, suffix, output=args.output,
|
|
|
|
env=env)
|
aportgen: Gracefully handle old aports_upstream (#1291)
In order to get cross-compilers, we generate a few aports (e.g.
binutils-armhf, gcc-armhf) automatically from Alpine's aports.
pmbootstrap was already able to perform a git checkout of Alpine's
aports repository. But it needed to be manually updated. Otherwise
the `pmbootstrap aportgen` command could actually downgrade the aport
instead of updating it to the current version.
After thinking about adding a dedicated pmbootstrap command for
updating git repositories, I thought it would be better to not open
that can of worms (pmbootstrap as general git wrapper? no thanks).
The solution implemented here compares the upstream aport version of
the git checkout of a certain package (e.g. gcc for gcc-armhf) with the
version in Alpine's binary package APKINDEX. When the aport version is
lower than the binary package version, it shows the user how to update
the git repository with just one command:
pmbootstrap chroot --add=git --user -- \
git -C /mnt/pmbootstrap-git/aports_upstream pull
Changes:
* `pmb.aportgen.core.get_upstream_aport()`: new function, that returns
the absolute path to the upstream aport on disk, after checking the
version of the aport against the binary package.
* Use that new function in pmb.aportgen.gcc and pmb.aportgen.binutils
* New function `pmb.helpers.repo.alpine_apkindex_path()`: updates the
APKINDEX if necessary and returns the absolute path to the APKINDEX.
This code was basically present already, but not as function, so now
we have a bit less overhead there.
* `pmbootstrap chroot`: new `--user` argument
* `pmb.parse.apkbuild`: make pkgname check optional, as it fails with
the official gcc APKBUILD before we modify it (the current APKBUILD
parser is not meant to be perfect, as this would require a full shell
parsing implementation).
* Extended `test_aportgen.py` and enabled it by default in
`testcases_fast.sh`. Previously it was disabled due to traffic
concerns (cloning the aports repo, but then again we do a full KDE
plasma mobile installation in Travis now, so that shouldn't matter
too much).
* `testcases_fast.sh`: With "test_aport_in_sync_with_git" removed
from the disabled-by-default list (left over from timestamp based
rebuilds), there were no more test cases disabled by default. I've
changed it, so now the qemu_running_processes test case is disabled,
and added an `--all` parameter to the script to disable no test
cases. Travis runs with the `--all` parameter while it's useful to
do a quick local test without `--all` in roughly 2 minutes instead of
10.
* `aports/cross/binutils-*`: Fix `_mirror` variable to point to current
default Alpine mirror (so the aportgen testcase runs through).
2018-03-11 14:18:21 +00:00
|
|
|
else:
|
|
|
|
logging.info("(" + suffix + ") % " + " ".join(args.command))
|
2020-06-02 21:29:33 +00:00
|
|
|
pmb.chroot.root(args, args.command, suffix, output=args.output,
|
|
|
|
env=env)
|
2017-07-18 19:01:11 +00:00
|
|
|
|
|
|
|
|
2017-08-14 14:25:28 +00:00
|
|
|
def config(args):
|
2017-11-19 15:04:08 +00:00
|
|
|
keys = pmb.config.config_keys
|
|
|
|
if args.name and args.name not in keys:
|
|
|
|
logging.info("NOTE: Valid config keys: " + ", ".join(keys))
|
|
|
|
raise RuntimeError("Invalid config key: " + args.name)
|
2017-08-14 14:25:28 +00:00
|
|
|
|
|
|
|
cfg = pmb.config.load(args)
|
2020-04-06 13:47:13 +00:00
|
|
|
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
|
2021-05-19 18:36:24 +00:00
|
|
|
logging.info(f"Config changed to default: {args.name}='{value}'")
|
2020-04-06 13:47:13 +00:00
|
|
|
pmb.config.save(args, cfg)
|
|
|
|
elif args.value is not None:
|
2017-08-14 14:25:28 +00:00
|
|
|
cfg["pmbootstrap"][args.name] = args.value
|
2017-11-19 15:04:08 +00:00
|
|
|
logging.info("Config changed: " + args.name + "='" + args.value + "'")
|
2017-08-14 14:25:28 +00:00
|
|
|
pmb.config.save(args, cfg)
|
|
|
|
elif args.name:
|
|
|
|
value = cfg["pmbootstrap"].get(args.name, "")
|
|
|
|
print(value)
|
|
|
|
else:
|
|
|
|
cfg.write(sys.stdout)
|
|
|
|
|
2017-11-19 15:04:08 +00:00
|
|
|
# Don't write the "Done" message
|
|
|
|
pmb.helpers.logging.disable()
|
|
|
|
|
2017-08-14 14:25:28 +00:00
|
|
|
|
new action: 'pmbootstrap repo_missing'
Add a new action that lists all aports, for which no binary packages
exist. Only list packages that can be built for the relevant arch
(specified with --arch). This works recursively: when a package can be
built for a certain arch, but one of its dependencies
(or their depends) can not be built for that arch, then don't list it.
This action will be used for the new sr.ht based build infrastructure,
to figure out which packages need to be built ahead of time (so we can
trigger each of them as single build job). Determining the order of the
packages to be built is not determined with pmbootstrap, the serverside
code of build.postmarketos.org takes care of that.
For testing purposes, a single package can also be specified and the
action will list if it can be built for that arch with its
dependencies, and what needs to be built exactly.
Add pmb/helpers/package.py to hold functions that work on both pmaports
and (binary package) repos - in contrary to the existing
pmb/helpers/pmaports.py (see previous commit) and pmb/helpers/repo.py,
which only work with one of those.
Refactoring:
* pmb/helpers/pmaports.py: add a get_list() function, which lists all
aports and use it instead of writing the same glob loop over and over
* add pmb.helpers.pmaports.get(), which finds an APKBUILD and parses it
in one step.
* rename pmb.build._package.check_arch to ...check_arch_abort to
distinguish it from the other check_arch function
2018-11-15 07:36:39 +00:00
|
|
|
def repo_missing(args):
|
|
|
|
missing = pmb.helpers.repo_missing.generate(args, args.arch, args.overview,
|
|
|
|
args.package, args.built)
|
|
|
|
print(json.dumps(missing, indent=4))
|
|
|
|
|
|
|
|
|
2017-07-18 19:01:11 +00:00
|
|
|
def index(args):
|
Fix #824: Refactor pmb/build/package.py (make depends work like in abuild) (#935)
* Rename pmb/build/package.py to pmb/build/_package.py, so we can
access the functions it contains in testcases, and still use
pmb.build.package()
* Refactor the entire file. Instead of one big function that does
too many things, we have many small ones now, that are tested
in the testsuite and easier to modify
* Whenever building a package, pmbootstrap does not only build and
install the "makedepends" (like we did before), now it does the
same for the "depends". That's required to be compatible with
abuild. The old behavior can still be used with 'pmbootstrap
build --ignore-depends'.
* Because of that change, noarch packages can no longer be built in
the native chroot if we need them for a foreign chroot. A device-
package depending on a kernel would pull in the same kernel for
the native architecture otherwise.
* Running 'pmbootstrap build device-...' without '--ignore-depends'
and without a matching '--arch' displays a note that explains
this change to the user and tells how to use it instead.
* Noarch packages no longer get symlinked. That was only
implemented for packages built in the native chroot, and now that
is not always the case anymore. Symlinking these packages creates
packages with broken dependencies anyway (e.g.
device-samsung-i9100 can't be installed in x86_64, because
linux-samsung-i9100 is armhf only).
* Rename "carch" to "arch" wherever used. Naming it "carch"
sometimes is confusing with no benefit.
* Add a testcase for the aarch64 qemu workaround (because it failed
first and I needed to know for sure if it is working again).
* Improved some verbose logging, which helped with development of
this feature.
* Removed the old "build" test case (which was disabled in
testcases_fast.sh) as the new "build_package" test case covers its
functionallity.
* Only build indexes if the packages folder exists for that arch (Travis
couldn't run a test case otherwise)
2017-11-26 14:32:02 +00:00
|
|
|
pmb.build.index_repo(args)
|
2017-07-18 19:01:11 +00:00
|
|
|
|
|
|
|
|
|
|
|
def initfs(args):
|
|
|
|
pmb.chroot.initfs.frontend(args)
|
|
|
|
|
|
|
|
|
|
|
|
def install(args):
|
2019-07-01 16:42:58 +00:00
|
|
|
if args.no_fde:
|
2021-05-19 18:36:24 +00:00
|
|
|
logging.warning("WARNING: --no-fde is deprecated,"
|
|
|
|
" as it is now the default.")
|
2018-01-28 23:25:21 +00:00
|
|
|
if args.rsync and args.full_disk_encryption:
|
|
|
|
raise ValueError("Installation using rsync is not compatible with full"
|
|
|
|
" disk encryption.")
|
|
|
|
if args.rsync and not args.sdcard:
|
|
|
|
raise ValueError("Installation using rsync only works on sdcard.")
|
|
|
|
|
2020-06-06 21:38:34 +00:00
|
|
|
# On-device installer checks
|
|
|
|
# Note that this can't be in the mutually exclusive group that has most of
|
|
|
|
# the conflicting options, because then it would not work with --sdcard.
|
|
|
|
if args.on_device_installer:
|
|
|
|
if args.full_disk_encryption:
|
|
|
|
raise ValueError("--on-device-installer cannot be combined with"
|
|
|
|
" --fde. The user can choose to encrypt their"
|
|
|
|
" installation later in the on-device installer.")
|
|
|
|
if args.android_recovery_zip:
|
|
|
|
raise ValueError("--on-device-installer cannot be combined with"
|
|
|
|
" --android-recovery-zip (patches welcome)")
|
|
|
|
if args.no_image:
|
|
|
|
raise ValueError("--on-device-installer cannot be combined with"
|
|
|
|
" --no-image")
|
|
|
|
if args.rsync:
|
|
|
|
raise ValueError("--on-device-installer cannot be combined with"
|
|
|
|
" --rsync")
|
2021-03-07 13:38:37 +00:00
|
|
|
if args.filesystem:
|
|
|
|
raise ValueError("--on-device-installer cannot be combined with"
|
|
|
|
" --filesystem")
|
2022-01-28 23:52:36 +00:00
|
|
|
|
|
|
|
if args.deviceinfo["cgpt_kpart"]:
|
|
|
|
raise ValueError("--on-device-installer cannot be used with"
|
|
|
|
" ChromeOS devices")
|
2020-11-17 14:24:20 +00:00
|
|
|
else:
|
|
|
|
if args.ondev_cp:
|
|
|
|
raise ValueError("--cp can only be combined with --ondev")
|
2020-10-06 09:34:19 +00:00
|
|
|
if args.ondev_no_rootfs:
|
|
|
|
raise ValueError("--no-rootfs can only be combined with --ondev."
|
|
|
|
" Do you mean --no-image?")
|
|
|
|
if args.ondev_no_rootfs:
|
|
|
|
_install_ondev_verify_no_rootfs(args)
|
2020-06-06 21:38:34 +00:00
|
|
|
|
2020-06-29 18:54:32 +00:00
|
|
|
# On-device installer overrides
|
|
|
|
if args.on_device_installer:
|
|
|
|
# To make code for the on-device installer not needlessly complex, just
|
|
|
|
# hardcode "user" as username here. (The on-device installer will set
|
|
|
|
# a password for the user, disable SSH password authentication,
|
|
|
|
# optionally add a new user for SSH that must not have the same
|
|
|
|
# username etc.)
|
|
|
|
if args.user != "user":
|
|
|
|
logging.warning(f"WARNING: custom username '{args.user}' will be"
|
|
|
|
" replaced with 'user' for the on-device"
|
|
|
|
" installer.")
|
|
|
|
args.user = "user"
|
|
|
|
|
2020-02-04 10:30:28 +00:00
|
|
|
if not args.sdcard and args.split is None:
|
|
|
|
# Default to split if the flash method requires it
|
|
|
|
flasher = pmb.config.flashers.get(args.deviceinfo["flash_method"], {})
|
|
|
|
if flasher.get("split", False):
|
|
|
|
args.split = True
|
|
|
|
|
2021-03-07 13:38:37 +00:00
|
|
|
# Android recovery zip related
|
|
|
|
if args.android_recovery_zip and args.filesystem:
|
|
|
|
raise ValueError("--android-recovery-zip cannot be combined with"
|
|
|
|
" --filesystem (patches welcome)")
|
2020-07-08 18:06:07 +00:00
|
|
|
if args.android_recovery_zip and args.full_disk_encryption:
|
|
|
|
logging.info("WARNING: --fde is rarely used in combination with"
|
|
|
|
" --android-recovery-zip. If this does not work, consider"
|
|
|
|
" using another method (e.g. installing via netcat)")
|
|
|
|
logging.info("WARNING: the kernel of the recovery system (e.g. TWRP)"
|
|
|
|
f" must support the cryptsetup cipher '{args.cipher}'.")
|
|
|
|
logging.info("If you know what you are doing, consider setting a"
|
|
|
|
" different cipher with 'pmbootstrap install --cipher=..."
|
|
|
|
" --fde --android-recovery-zip'.")
|
|
|
|
|
2020-06-22 11:40:30 +00:00
|
|
|
# Don't install locally compiled packages and package signing keys
|
|
|
|
if not args.install_local_pkgs:
|
|
|
|
# Implies that we don't build outdated packages (overriding the answer
|
|
|
|
# in 'pmbootstrap init')
|
|
|
|
args.build_pkgs_on_install = False
|
|
|
|
|
|
|
|
# Safest way to avoid installing local packages is having none
|
|
|
|
if glob.glob(f"{args.work}/packages/*"):
|
|
|
|
raise ValueError("--no-local-pkgs specified, but locally built"
|
|
|
|
" packages found. Consider 'pmbootstrap zap -p'"
|
|
|
|
" to delete them.")
|
|
|
|
|
2021-03-19 00:30:30 +00:00
|
|
|
# Verify that the root filesystem is supported by current pmaports branch
|
|
|
|
pmb.install.get_root_filesystem(args)
|
|
|
|
|
2017-07-18 19:01:11 +00:00
|
|
|
pmb.install.install(args)
|
|
|
|
|
|
|
|
|
|
|
|
def flasher(args):
|
|
|
|
pmb.flasher.frontend(args)
|
|
|
|
|
|
|
|
|
2017-09-06 20:14:03 +00:00
|
|
|
def export(args):
|
|
|
|
pmb.export.frontend(args)
|
|
|
|
|
|
|
|
|
2017-11-19 15:04:08 +00:00
|
|
|
def update(args):
|
2018-03-04 13:44:27 +00:00
|
|
|
existing_only = not args.non_existing
|
|
|
|
if not pmb.helpers.repo.update(args, 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.")
|
|
|
|
logging.info("If you want to force downloading the APKINDEX files for"
|
|
|
|
" all architectures (not recommended), use:"
|
|
|
|
" pmbootstrap update --non-existing")
|
2017-11-19 15:04:08 +00:00
|
|
|
|
|
|
|
|
2018-01-15 22:00:11 +00:00
|
|
|
def newapkbuild(args):
|
pmbootstrap newapkbuild: Properly parse arguments (#1320)
* pmbootstrap newapkbuild: Properly parse arguments
The `pmbootstrap newapkbuild` action wraps Alpine's `newapkbuild`. We
used to directly pass all arguments to `newapkbuild` without verifying
in Python whether they make sense or not. However, as `newpakbuild`
doesn't do strict sanity checks on the arguments, it is easy to end up
with unexpected behavior when using the command for the first time.
For example, `newapkbuild` allows either specifying a PKGNAME or SRCURL
as last parameter, and also allows setting a PKGNAME with the `-n`
parameter. It only makes sense to use that option when passing a
SRCURL.
With this commit, we duplicate the optins that should be passed through
to `newapkbuild` and use argparse to fully sanitize the options and
display a help page (`pmbootstrap newapkbuild -h`) that is consistent
with the other help pages.
Details:
* The `-f` (force) flag does not get passed through anymore. Instead we
use it in Python to skip asking if an existing aport should be
overwritten (the aports are outside of the chroot, so `newapkbuild`
can't handle it in a way that makes sense for pmbootstrap).
* Output of `newapkbuild` gets redirected to the log file now, as we
don't need it to display a help page.
* Don't verify the pkgver while creating the new APKBUILD. When passing
a SRCURL, the pkgver gets extracted from the end of the URL and may
not have a valid format yet (but we want the APKBUILD anyway).
* Stored options passed through in `pmb/config/__init__.py` and use it
in both `pmb/parse/arguments.py` and `pmb/helpers/frontend.py`.
* Only allow `-n` with SRCURL
* The postmarketOS aports folder gets specified with `--folder` now.
That way the generated help page is much closer to the original one
from `newapkbuild`. The default is `main`.
* Made the package type flags (CMake, autotools, ...) exclusive so only
one of them can be specified
2018-03-15 21:42:34 +00:00
|
|
|
# Check for SRCURL usage
|
|
|
|
is_url = False
|
|
|
|
for prefix in ["http://", "https://", "ftp://"]:
|
|
|
|
if args.pkgname_pkgver_srcurl.startswith(prefix):
|
|
|
|
is_url = True
|
|
|
|
break
|
|
|
|
|
|
|
|
# Sanity check: -n is only allowed with SRCURL
|
|
|
|
if args.pkgname and not is_url:
|
|
|
|
raise RuntimeError("You can only specify a pkgname (-n) when using"
|
|
|
|
" SRCURL as last parameter.")
|
|
|
|
|
|
|
|
# Passthrough: Strings (e.g. -d "my description")
|
|
|
|
pass_through = []
|
|
|
|
for entry in pmb.config.newapkbuild_arguments_strings:
|
|
|
|
value = getattr(args, entry[1])
|
|
|
|
if value:
|
|
|
|
pass_through += [entry[0], value]
|
|
|
|
|
|
|
|
# Passthrough: Switches (e.g. -C for CMake)
|
|
|
|
for entry in (pmb.config.newapkbuild_arguments_switches_pkgtypes +
|
|
|
|
pmb.config.newapkbuild_arguments_switches_other):
|
|
|
|
if getattr(args, entry[1]) is True:
|
|
|
|
pass_through.append(entry[0])
|
|
|
|
|
|
|
|
# Passthrough: PKGNAME[-PKGVER] | SRCURL
|
|
|
|
pass_through.append(args.pkgname_pkgver_srcurl)
|
|
|
|
pmb.build.newapkbuild(args, args.folder, pass_through, args.force)
|
2018-01-15 22:00:11 +00:00
|
|
|
|
|
|
|
|
2018-06-09 06:52:24 +00:00
|
|
|
def kconfig(args):
|
|
|
|
if args.action_kconfig == "check":
|
2023-03-12 15:13:15 +00:00
|
|
|
details = args.kconfig_check_details
|
2023-03-12 15:13:10 +00:00
|
|
|
# Build the components list from cli arguments (--waydroid etc.)
|
|
|
|
components_list = []
|
|
|
|
for name in pmb.parse.kconfig.get_all_component_names():
|
|
|
|
if getattr(args, f"kconfig_check_{name}"):
|
|
|
|
components_list += [name]
|
|
|
|
|
2019-07-20 16:49:05 +00:00
|
|
|
# Handle passing a file directly
|
|
|
|
if args.file:
|
2023-03-12 15:13:10 +00:00
|
|
|
if pmb.parse.kconfig.check_file(args.package, components_list,
|
2023-03-12 15:13:15 +00:00
|
|
|
details=details):
|
2019-07-20 16:49:05 +00:00
|
|
|
logging.info("kconfig check succeeded!")
|
|
|
|
return
|
|
|
|
raise RuntimeError("kconfig check failed!")
|
|
|
|
|
2018-06-09 06:52:24 +00:00
|
|
|
# Default to all kernel packages
|
|
|
|
packages = []
|
2020-03-30 07:52:47 +00:00
|
|
|
if args.package:
|
2018-06-09 06:52:24 +00:00
|
|
|
packages = [args.package]
|
2020-03-30 07:52:47 +00:00
|
|
|
else:
|
|
|
|
for aport in pmb.helpers.pmaports.get_list(args):
|
|
|
|
if aport.startswith("linux-"):
|
|
|
|
packages.append(aport.split("linux-")[1])
|
2018-06-09 06:52:24 +00:00
|
|
|
|
|
|
|
# Iterate over all kernels
|
|
|
|
error = False
|
2019-02-11 20:46:45 +00:00
|
|
|
skipped = 0
|
2018-06-09 06:52:24 +00:00
|
|
|
packages.sort()
|
|
|
|
for package in packages:
|
2019-02-11 20:46:45 +00:00
|
|
|
if not args.force:
|
2021-05-19 18:36:24 +00:00
|
|
|
pkgname = package if package.startswith("linux-") \
|
|
|
|
else "linux-" + package
|
2020-03-14 14:49:43 +00:00
|
|
|
aport = pmb.helpers.pmaports.find(args, pkgname)
|
2021-11-09 11:52:10 +00:00
|
|
|
apkbuild = pmb.parse.apkbuild(f"{aport}/APKBUILD")
|
2019-02-11 20:46:45 +00:00
|
|
|
if "!pmb:kconfigcheck" in apkbuild["options"]:
|
|
|
|
skipped += 1
|
|
|
|
continue
|
2023-03-12 15:13:10 +00:00
|
|
|
if not pmb.parse.kconfig.check(args, package, components_list,
|
2023-03-12 15:13:15 +00:00
|
|
|
details=details):
|
2018-06-09 06:52:24 +00:00
|
|
|
error = True
|
|
|
|
|
|
|
|
# At least one failure
|
|
|
|
if error:
|
|
|
|
raise RuntimeError("kconfig check failed!")
|
|
|
|
else:
|
2019-02-11 20:46:45 +00:00
|
|
|
if skipped:
|
|
|
|
logging.info("NOTE: " + str(skipped) + " kernel(s) was skipped"
|
|
|
|
" (consider 'pmbootstrap kconfig check -f')")
|
2019-06-25 07:18:00 +00:00
|
|
|
logging.info("kconfig check succeeded!")
|
2021-09-11 08:57:47 +00:00
|
|
|
elif args.action_kconfig in ["edit", "migrate"]:
|
2020-12-01 16:11:08 +00:00
|
|
|
if args.package:
|
|
|
|
pkgname = args.package
|
|
|
|
else:
|
|
|
|
pkgname = args.deviceinfo["codename"]
|
2021-09-11 08:57:47 +00:00
|
|
|
use_oldconfig = args.action_kconfig == "migrate"
|
|
|
|
pmb.build.menuconfig(args, pkgname, use_oldconfig)
|
2017-09-18 21:36:54 +00:00
|
|
|
|
|
|
|
|
2020-10-28 17:31:40 +00:00
|
|
|
def deviceinfo_parse(args):
|
|
|
|
# Default to all devices
|
|
|
|
devices = args.devices
|
|
|
|
if not devices:
|
|
|
|
devices = pmb.helpers.devices.list_codenames(args)
|
|
|
|
|
|
|
|
# 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,
|
|
|
|
sort_keys=True))
|
|
|
|
|
|
|
|
|
2018-01-18 22:05:27 +00:00
|
|
|
def apkbuild_parse(args):
|
|
|
|
# Default to all packages
|
|
|
|
packages = args.packages
|
|
|
|
if not packages:
|
new action: 'pmbootstrap repo_missing'
Add a new action that lists all aports, for which no binary packages
exist. Only list packages that can be built for the relevant arch
(specified with --arch). This works recursively: when a package can be
built for a certain arch, but one of its dependencies
(or their depends) can not be built for that arch, then don't list it.
This action will be used for the new sr.ht based build infrastructure,
to figure out which packages need to be built ahead of time (so we can
trigger each of them as single build job). Determining the order of the
packages to be built is not determined with pmbootstrap, the serverside
code of build.postmarketos.org takes care of that.
For testing purposes, a single package can also be specified and the
action will list if it can be built for that arch with its
dependencies, and what needs to be built exactly.
Add pmb/helpers/package.py to hold functions that work on both pmaports
and (binary package) repos - in contrary to the existing
pmb/helpers/pmaports.py (see previous commit) and pmb/helpers/repo.py,
which only work with one of those.
Refactoring:
* pmb/helpers/pmaports.py: add a get_list() function, which lists all
aports and use it instead of writing the same glob loop over and over
* add pmb.helpers.pmaports.get(), which finds an APKBUILD and parses it
in one step.
* rename pmb.build._package.check_arch to ...check_arch_abort to
distinguish it from the other check_arch function
2018-11-15 07:36:39 +00:00
|
|
|
packages = pmb.helpers.pmaports.get_list(args)
|
2018-01-18 22:05:27 +00:00
|
|
|
|
|
|
|
# Iterate over all packages
|
|
|
|
for package in packages:
|
|
|
|
print(package + ":")
|
2018-11-15 07:30:49 +00:00
|
|
|
aport = pmb.helpers.pmaports.find(args, package)
|
2018-01-18 22:05:27 +00:00
|
|
|
path = aport + "/APKBUILD"
|
2021-11-09 11:52:10 +00:00
|
|
|
print(json.dumps(pmb.parse.apkbuild(path), indent=4,
|
2018-01-18 22:05:27 +00:00
|
|
|
sort_keys=True))
|
2017-07-18 19:01:11 +00:00
|
|
|
|
|
|
|
|
2018-01-18 22:05:27 +00:00
|
|
|
def apkindex_parse(args):
|
2021-11-09 11:53:59 +00:00
|
|
|
result = pmb.parse.apkindex.parse(args.apkindex_path)
|
2017-07-22 09:54:49 +00:00
|
|
|
if args.package:
|
|
|
|
if args.package not in result:
|
|
|
|
raise RuntimeError("Package not found in the APKINDEX: " +
|
|
|
|
args.package)
|
|
|
|
result = result[args.package]
|
2017-07-18 19:01:11 +00:00
|
|
|
print(json.dumps(result, indent=4))
|
|
|
|
|
|
|
|
|
2018-01-14 01:26:42 +00:00
|
|
|
def pkgrel_bump(args):
|
|
|
|
would_bump = True
|
|
|
|
if args.auto:
|
|
|
|
would_bump = pmb.helpers.pkgrel_bump.auto(args, args.dry)
|
|
|
|
else:
|
|
|
|
# Each package must exist
|
|
|
|
for package in args.packages:
|
2018-11-15 07:30:49 +00:00
|
|
|
pmb.helpers.pmaports.find(args, package)
|
2018-01-14 01:26:42 +00:00
|
|
|
|
|
|
|
# Increase pkgrel
|
|
|
|
for package in args.packages:
|
|
|
|
pmb.helpers.pkgrel_bump.package(args, package, dry=args.dry)
|
|
|
|
|
|
|
|
if args.dry and would_bump:
|
|
|
|
logging.info("Pkgrels of package(s) would have been bumped!")
|
|
|
|
sys.exit(1)
|
|
|
|
|
|
|
|
|
2019-02-09 16:58:54 +00:00
|
|
|
def aportupgrade(args):
|
|
|
|
if args.all or args.all_stable or args.all_git:
|
|
|
|
pmb.helpers.aportupgrade.upgrade_all(args)
|
|
|
|
else:
|
|
|
|
# Each package must exist
|
|
|
|
for package in args.packages:
|
|
|
|
pmb.helpers.pmaports.find(args, package)
|
|
|
|
|
|
|
|
# Check each package for a new version
|
|
|
|
for package in args.packages:
|
|
|
|
pmb.helpers.aportupgrade.upgrade(args, package)
|
|
|
|
|
|
|
|
|
2017-08-09 20:26:40 +00:00
|
|
|
def qemu(args):
|
|
|
|
pmb.qemu.run(args)
|
|
|
|
|
|
|
|
|
2017-07-18 19:01:11 +00:00
|
|
|
def shutdown(args):
|
|
|
|
pmb.chroot.shutdown(args)
|
|
|
|
|
|
|
|
|
|
|
|
def stats(args):
|
2017-12-21 16:42:29 +00:00
|
|
|
# Chroot suffix
|
|
|
|
suffix = "native"
|
2021-10-16 16:33:27 +00:00
|
|
|
if args.arch != pmb.config.arch_native:
|
2017-12-21 16:42:29 +00:00
|
|
|
suffix = "buildroot_" + args.arch
|
|
|
|
|
|
|
|
# Install ccache and display stats
|
|
|
|
pmb.chroot.apk.install(args, ["ccache"], suffix)
|
|
|
|
logging.info("(" + suffix + ") % ccache -s")
|
2018-07-14 01:13:28 +00:00
|
|
|
pmb.chroot.user(args, ["ccache", "-s"], suffix, output="stdout")
|
2017-07-18 19:01:11 +00:00
|
|
|
|
|
|
|
|
2018-04-19 21:27:38 +00:00
|
|
|
def work_migrate(args):
|
|
|
|
# do nothing (pmb/__init__.py already did the migration)
|
|
|
|
pmb.helpers.logging.disable()
|
|
|
|
|
|
|
|
|
2017-07-18 19:01:11 +00:00
|
|
|
def log(args):
|
2023-06-03 10:29:10 +00:00
|
|
|
log_testsuite = f"{args.work}/log_testsuite.txt"
|
|
|
|
|
2017-08-07 18:56:35 +00:00
|
|
|
if args.clear_log:
|
2018-07-14 01:13:28 +00:00
|
|
|
pmb.helpers.run.user(args, ["truncate", "-s", "0", args.log])
|
2023-06-03 10:29:10 +00:00
|
|
|
pmb.helpers.run.user(args, ["truncate", "-s", "0", log_testsuite])
|
2022-10-20 21:22:43 +00:00
|
|
|
|
|
|
|
cmd = ["tail", "-n", args.lines, "-F"]
|
|
|
|
|
|
|
|
# Follow the testsuite's log file too if it exists. It will be created when
|
|
|
|
# starting a test case that writes to it (git -C test grep log_testsuite).
|
|
|
|
if os.path.exists(log_testsuite):
|
|
|
|
cmd += [log_testsuite]
|
|
|
|
|
|
|
|
# tail writes the last lines of the files to the terminal. Put the regular
|
|
|
|
# log at the end, so that output is visible at the bottom (where the user
|
|
|
|
# looks for an error / what's currently going on).
|
|
|
|
cmd += [args.log]
|
|
|
|
|
|
|
|
pmb.helpers.run.user(args, cmd, output="tui")
|
2017-07-18 19:01:11 +00:00
|
|
|
|
|
|
|
|
|
|
|
def zap(args):
|
2018-03-10 12:08:02 +00:00
|
|
|
pmb.chroot.zap(args, dry=args.dry, http=args.http,
|
|
|
|
distfiles=args.distfiles, pkgs_local=args.pkgs_local,
|
|
|
|
pkgs_local_mismatch=args.pkgs_local_mismatch,
|
2020-01-02 11:41:01 +00:00
|
|
|
pkgs_online_mismatch=args.pkgs_online_mismatch,
|
2021-07-01 15:16:34 +00:00
|
|
|
rust=args.rust, netboot=args.netboot)
|
2017-11-19 14:35:23 +00:00
|
|
|
|
2018-01-31 19:34:02 +00:00
|
|
|
# Don't write the "Done" message
|
|
|
|
pmb.helpers.logging.disable()
|
|
|
|
|
2017-11-19 14:35:23 +00:00
|
|
|
|
|
|
|
def bootimg_analyze(args):
|
|
|
|
bootimg = pmb.parse.bootimg(args, args.path)
|
|
|
|
tmp_output = "Put these variables in the deviceinfo file of your device:\n"
|
2021-05-19 18:36:24 +00:00
|
|
|
for line in pmb.aportgen.device.\
|
2021-09-20 10:00:13 +00:00
|
|
|
generate_deviceinfo_fastboot_content(bootimg).split("\n"):
|
2017-11-19 14:35:23 +00:00
|
|
|
tmp_output += "\n" + line.lstrip()
|
|
|
|
logging.info(tmp_output)
|
2020-01-06 05:39:57 +00:00
|
|
|
|
|
|
|
|
|
|
|
def pull(args):
|
|
|
|
failed = []
|
|
|
|
for repo in pmb.config.git_repos.keys():
|
|
|
|
if pmb.helpers.git.pull(args, repo) < 0:
|
|
|
|
failed.append(repo)
|
|
|
|
|
|
|
|
if not failed:
|
|
|
|
return True
|
|
|
|
|
|
|
|
logging.info("---")
|
|
|
|
logging.info("WARNING: failed to update: " + ", ".join(failed))
|
|
|
|
logging.info("")
|
|
|
|
logging.info("'pmbootstrap pull' will only update the repositories, if:")
|
|
|
|
logging.info("* they are on an officially supported branch (e.g. master)")
|
|
|
|
logging.info("* the history is not conflicting (fast-forward is possible)")
|
|
|
|
logging.info("* the git workdirs are clean")
|
|
|
|
logging.info("You have changed mentioned repositories, so they don't meet")
|
|
|
|
logging.info("these conditions anymore.")
|
|
|
|
logging.info("")
|
|
|
|
logging.info("Fix and try again:")
|
|
|
|
for name_repo in failed:
|
|
|
|
logging.info("* " + pmb.helpers.git.get_path(args, name_repo))
|
|
|
|
logging.info("---")
|
|
|
|
return False
|
2020-02-06 12:03:02 +00:00
|
|
|
|
|
|
|
|
|
|
|
def lint(args):
|
|
|
|
packages = args.packages
|
|
|
|
if not packages:
|
|
|
|
packages = pmb.helpers.pmaports.get_list(args)
|
|
|
|
|
pmbootstrap lint: avoid looping and copying files (MR 2100)
Before this commit, package folders were copied into the chroot one by
one in order to run apkbuild-lint on them. This logic is replaced by
mounting pmaports.git into the chroot and using a single apkbuild-lint
invocation to lint the supplied packages.
Both of these changes result in a performance improvement, especially
when linting multiple packages at once.
Before this change:
$ time ./pmbootstrap.py -q lint $(cd ../pmaports/cross; echo *) \
> /dev/null
real 0m5,261s
user 0m7,046s
sys 0m1,842s
Using the pmaports.git mount but calling apkbuild-lint in a loop:
$ time ./pmbootstrap.py -q lint $(cd ../pmaports/cross; echo *) \
> /dev/null
real 0m4,089s
user 0m6,418s
sys 0m1,219s
After this change:
$ time ./pmbootstrap.py -q lint $(cd ../pmaports/cross; echo *) \
> /dev/null
real 0m3,518s
user 0m5,968s
sys 0m0,959s
Additionally, running apkbuild-lint from the pmaports.git mount point
has the benefit that every printed violation contains a nice source
identifier à la "./cross/grub-x86/APKBUILD". This makes it possible to
differentiate between different packages even though only a single
apkbuild-lint invocation is used.
Relates: postmarketOS/pmaports#564
2021-08-30 07:24:46 +00:00
|
|
|
pmb.helpers.lint.check(args, packages)
|
2020-02-04 20:39:53 +00:00
|
|
|
|
|
|
|
|
|
|
|
def status(args):
|
|
|
|
if not pmb.helpers.status.print_status(args, args.details):
|
|
|
|
sys.exit(1)
|
2022-10-20 19:08:42 +00:00
|
|
|
|
|
|
|
|
|
|
|
def ci(args):
|
|
|
|
topdir = pmb.helpers.git.get_topdir(args, os.getcwd())
|
|
|
|
if not os.path.exists(topdir):
|
|
|
|
logging.error("ERROR: change your current directory to a git"
|
|
|
|
" repository (e.g. pmbootstrap, pmaports) before running"
|
|
|
|
" 'pmbootstrap ci'.")
|
|
|
|
exit(1)
|
|
|
|
|
|
|
|
scripts_available = pmb.ci.get_ci_scripts(topdir)
|
|
|
|
scripts_available = pmb.ci.sort_scripts_by_speed(scripts_available)
|
|
|
|
if not scripts_available:
|
|
|
|
logging.error("ERROR: no supported CI scripts found in current git"
|
|
|
|
" repository, see https://postmarketos.org/pmb-ci")
|
|
|
|
exit(1)
|
|
|
|
|
|
|
|
scripts_selected = {}
|
|
|
|
if args.scripts:
|
2022-11-11 07:23:53 +00:00
|
|
|
if args.all:
|
|
|
|
raise RuntimeError("Combining --all with script names doesn't"
|
|
|
|
" make sense")
|
2022-10-20 19:08:42 +00:00
|
|
|
for script in args.scripts:
|
|
|
|
if script not in scripts_available:
|
|
|
|
logging.error(f"ERROR: script '{script}' not found in git"
|
|
|
|
" repository, found these:"
|
|
|
|
f" {', '.join(scripts_available.keys())}")
|
|
|
|
exit(1)
|
|
|
|
scripts_selected[script] = scripts_available[script]
|
|
|
|
elif args.all:
|
|
|
|
scripts_selected = scripts_available
|
|
|
|
|
2022-11-11 07:23:54 +00:00
|
|
|
if args.fast:
|
|
|
|
for script, script_data in scripts_available.items():
|
|
|
|
if "slow" not in script_data["options"]:
|
|
|
|
scripts_selected[script] = script_data
|
|
|
|
|
2022-10-20 19:08:42 +00:00
|
|
|
if not pmb.helpers.git.clean_worktree(args, topdir):
|
|
|
|
logging.warning("WARNING: this git repository has uncommitted changes")
|
|
|
|
|
|
|
|
if not scripts_selected:
|
|
|
|
scripts_selected = pmb.ci.ask_which_scripts_to_run(scripts_available)
|
|
|
|
|
|
|
|
pmb.ci.run_scripts(args, topdir, scripts_selected)
|