apk-tools issueshttps://gitlab.alpinelinux.org/alpine/apk-tools/-/issues2024-03-27T23:37:17Zhttps://gitlab.alpinelinux.org/alpine/apk-tools/-/issues/10989Question: About apk-tools-zsh-completion2024-03-27T23:37:17ZMalik NQuestion: About apk-tools-zsh-completionIt seems I have a package called apk-tools-zsh-completion, but I cant find it in the world file, not with `whereis apk-tools-zsh-completion`, and not in the aports repository. It is only visible in gnome software with the same version nu...It seems I have a package called apk-tools-zsh-completion, but I cant find it in the world file, not with `whereis apk-tools-zsh-completion`, and not in the aports repository. It is only visible in gnome software with the same version number like apk-tools 2.14.1.
What might have caused this and how I can source those files in my .zshrc?https://gitlab.alpinelinux.org/alpine/apk-tools/-/issues/10988should provider format allow `,` and `[`2024-03-27T14:51:23ZSertonixshould provider format allow `,` and `[`alpine linux includes providers that don't follow the current spec since they contain `,` and `[` characters. The question is if they should be allowed or excluded as providers.
```
cmd:[
cmd:sxmo_deviceprofile_fairphone,fp4.sh
cmd:sxmo...alpine linux includes providers that don't follow the current spec since they contain `,` and `[` characters. The question is if they should be allowed or excluded as providers.
```
cmd:[
cmd:sxmo_deviceprofile_fairphone,fp4.sh
cmd:sxmo_deviceprofile_kobo,clarahd.sh
cmd:sxmo_deviceprofile_lge,hammerhead.sh
cmd:sxmo_deviceprofile_longcheer,l8150.sh
cmd:sxmo_deviceprofile_motorola,harpia.sh
cmd:sxmo_deviceprofile_nokia,omap3-n900.sh
cmd:sxmo_deviceprofile_oneplus,cheeseburger.sh
cmd:sxmo_deviceprofile_oneplus,dumpling.sh
cmd:sxmo_deviceprofile_oneplus,enchilada.sh
cmd:sxmo_deviceprofile_oneplus,fajita.sh
cmd:sxmo_deviceprofile_pine64,pinebook-pro.sh
cmd:sxmo_deviceprofile_pine64,pinebook.sh
cmd:sxmo_deviceprofile_pine64,pinenote.sh
cmd:sxmo_deviceprofile_pine64,pinephone-1.0.sh
cmd:sxmo_deviceprofile_pine64,pinephone-1.1.sh
cmd:sxmo_deviceprofile_pine64,pinephone-1.2.sh
cmd:sxmo_deviceprofile_pine64,pinephone-pro.sh
cmd:sxmo_deviceprofile_pine64,rockpro64-v2.1.sh
cmd:sxmo_deviceprofile_purism,librem5r2.sh
cmd:sxmo_deviceprofile_purism,librem5r3.sh
cmd:sxmo_deviceprofile_purism,librem5r4.sh
cmd:sxmo_deviceprofile_qcom,msm8226-mtp.sh
cmd:sxmo_deviceprofile_samsung,a3u-eur.sh
cmd:sxmo_deviceprofile_samsung,a5u-eur.sh
cmd:sxmo_deviceprofile_samsung,coreprimevelte.sh
cmd:sxmo_deviceprofile_samsung,e5.sh
cmd:sxmo_deviceprofile_samsung,e7.sh
cmd:sxmo_deviceprofile_samsung,grandmax.sh
cmd:sxmo_deviceprofile_samsung,gt510.sh
cmd:sxmo_deviceprofile_samsung,i9300.sh
cmd:sxmo_deviceprofile_samsung,j5.sh
cmd:sxmo_deviceprofile_samsung,j5x.sh
cmd:sxmo_deviceprofile_samsung,n8010.sh
cmd:sxmo_deviceprofile_shift,axolotl.sh
cmd:sxmo_deviceprofile_wingtech,wt88047.sh
cmd:sxmo_deviceprofile_xiaomi,beryllium.sh
cmd:sxmo_deviceprofile_xiaomi,elish.sh
cmd:sxmo_deviceprofile_xiaomi,polaris.sh
cmd:uutils-[
```https://gitlab.alpinelinux.org/alpine/apk-tools/-/issues/10987apk3 fails to parse apk2 install_if2024-03-27T15:36:33ZSertonixapk3 fails to parse apk2 install_ifWhen I run `apk3 -s upgrade` on an apk2 system I get false package installation:
```
~/src/apk-tools$ output/src/apk -s upgrade
(1/4) Installing opensmtpd-openrc (7.4.0p1-r1)
(2/4) Installing opensmtpd-doc (7.4.0p1-r1)
(3/4) Installing o...When I run `apk3 -s upgrade` on an apk2 system I get false package installation:
```
~/src/apk-tools$ output/src/apk -s upgrade
(1/4) Installing opensmtpd-openrc (7.4.0p1-r1)
(2/4) Installing opensmtpd-doc (7.4.0p1-r1)
(3/4) Installing owfs-doc (3.2p4-r0)
(4/4) Installing tcptraceroute-doc (1.5b7-r4)
OK: 4855 MiB in 1366 packages
```
apk2:
```
~$ apk -s upgrade
OK: 4855 MiB in 1366 packages
```
It seems that apk3 doesn't parse the install_if field correctly in apk2 packages:
```
~/src/apk-tools$ output/src/apk info tcptraceroute-doc --install-if
tcptraceroute-doc-1.5b7-r4 has auto-install rule:
docs
```
apk2:
```
~$ apk info tcptraceroute-doc --install-if
tcptraceroute-doc-1.5b7-r4 has auto-install rule:
docs
tcptraceroute=1.5b7-r4
```
This may be related to the still undocumented `digit{letter{digit}}` format used on alpine linux (https://gitlab.alpinelinux.org/alpine/apk-tools/-/issues/10972#note_380899).https://gitlab.alpinelinux.org/alpine/apk-tools/-/issues/10985can't read --protected-paths from pipe2024-03-25T10:06:54ZSertonixcan't read --protected-paths from pipe`apk audit --protected-paths /dev/stdin` doesn't read stdin at all.
The reason seems to be that the `apk_blob_from_file` function doesn't handle pipes/fifos.`apk audit --protected-paths /dev/stdin` doesn't read stdin at all.
The reason seems to be that the `apk_blob_from_file` function doesn't handle pipes/fifos.https://gitlab.alpinelinux.org/alpine/apk-tools/-/issues/10976Conflicting unversioned providers2024-03-12T11:18:48ZSertonixConflicting unversioned providersCurrently 2 packages providing the same name without specifying a version do not conflict. (I know that this is intentional.)
The problem is that some packages providing the same name should conflict but adding a version doesn't makes s...Currently 2 packages providing the same name without specifying a version do not conflict. (I know that this is intentional.)
The problem is that some packages providing the same name should conflict but adding a version doesn't makes sense.
An example from alpine is `busybox-binsh` and `dash-binsh` (and other `*-binsh` packages). They fail to install together since they include the same file. The packages should already conflict in the resolving phase.
This would improve the error message and would allow correct simulation (`-s`).
My proposal is to allow specifying a conflict with a name provided by a package itself:
```
depends="!/bin/sh"
provides="/bin/sh"
```
Changing the resolver to ignore a conflict with a package itself should be enough to get this working. (To be tested)https://gitlab.alpinelinux.org/alpine/apk-tools/-/issues/10972package version formatting2024-03-27T16:28:48ZSertonixpackage version formattingThe issue has mutated to a discussion about the version formatting in general.
Related !144, #7100, #10816
## Old description
The version format for virtual packages (`YYYYmmdd.HHMMSS`) doesn't include a `pkgrel` like packages normall...The issue has mutated to a discussion about the version formatting in general.
Related !144, #7100, #10816
## Old description
The version format for virtual packages (`YYYYmmdd.HHMMSS`) doesn't include a `pkgrel` like packages normally have (`<pkgver>-r<pkgrel>`).
This creates ambiguity in the output of the `apk list` command. Normally it is enough the strip the last 2 dashes but that doesn't work with the version format of virtual packages:
- `<pkgname>-<pkgver>-r<pkgrel>`
- `<pkgname>-YYYYmmdd.HHMMSS`
I suggest adding `-r0` to the version of virtual packages [`app_add.c#L118`](https://gitlab.alpinelinux.org/alpine/apk-tools/-/blob/acefa1acc1ce0e1871d17b4eafe4b1888f45d4d0/src/app_add.c#L118). !132 does fix the `apk list` problem too but a consistent version format would still be better.v3.0https://gitlab.alpinelinux.org/alpine/apk-tools/-/issues/10964Provide development documentation2024-03-11T08:31:37ZSander MaijersProvide development documentation[`docs/`](docs/) contains user manuals, but short of that, development documentation seems absent.
@ariadne wrote interesting analyses such as https://ariadne.space/2021/10/31/spelunking-through-the-apk-tools-dependency-solver/, which I ...[`docs/`](docs/) contains user manuals, but short of that, development documentation seems absent.
@ariadne wrote interesting analyses such as https://ariadne.space/2021/10/31/spelunking-through-the-apk-tools-dependency-solver/, which I think deserve a more central place.
In addition, personally, I'd like to learn about `apk-tools`'s design principles and architectural requirements. For example, is `/var/cache/apk/` supposed to be data race safe in the face of parallel `apk` processes?backloghttps://gitlab.alpinelinux.org/alpine/apk-tools/-/issues/10963Parallel installation2024-02-23T12:34:40ZSander MaijersParallel installationSometimes a need for network I/O parallelism, for performance efficiency, can be avoided.
For example, repeated Alpine Linux-based container image builds can use a cache for `/var/cache/apk` across build runs.
However, installing appears...Sometimes a need for network I/O parallelism, for performance efficiency, can be avoided.
For example, repeated Alpine Linux-based container image builds can use a cache for `/var/cache/apk` across build runs.
However, installing appears to happen sequentially.
Since packages should not overlap on the filesystem, and their dependencies/integrity can be calculated, in principle, parallel installation must be possible.
On the other hand, package installation parallelism may have interactions with a transactional or more specifically atomicity-related architecturally significant requirements.https://gitlab.alpinelinux.org/alpine/apk-tools/-/issues/10960trigger on self deinstall2023-12-15T09:26:53ZSertonixtrigger on self deinstallIt would be nice to have the ability to run a trigger when the package providing the trigger is uninstalled.
This would allow trigger scripts to clean up the files they created. Eg. the mkinitfs trigger could remove the initramfs files....It would be nice to have the ability to run a trigger when the package providing the trigger is uninstalled.
This would allow trigger scripts to clean up the files they created. Eg. the mkinitfs trigger could remove the initramfs files.
The script would need to check for that case when it uses files provided by the package (eg. a command) since they won't be available in that case. To not break old scripts this could be implemented as an additional flag.https://gitlab.alpinelinux.org/alpine/apk-tools/-/issues/10959simulate package count and size2024-01-15T16:22:49ZSertonixsimulate package count and sizeAfter running things like apk add/del/upgrade there is a summary of installed packages and the current size.
When simulating the installation the reals size and count is used instead of simulating it:
```
~ $ apk -s add sudo
...
OK: 665...After running things like apk add/del/upgrade there is a summary of installed packages and the current size.
When simulating the installation the reals size and count is used instead of simulating it:
```
~ $ apk -s add sudo
...
OK: 6652 MiB in 1435 packages
~ $ doas apk add sudo
...
OK: 6654 MiB in 1437 packages
```
I assume this could be fixed in [`src/commit.c#apk_solver_commit_changeset`](https://gitlab.alpinelinux.org/alpine/apk-tools/-/blob/c8c9df1825760e558f44397500af2a2f4bca18d4/src/commit.c#L281).
The variable `size_diff` could be used to simulate the size correctly and the `changeset` for the amount of packages.
The verbose version also writes the files and dirs. I don't know if they can be simulated easily but if they can that would be nice too.https://gitlab.alpinelinux.org/alpine/apk-tools/-/issues/10958apk3: a way to pin a package in place upon installation2023-12-15T17:08:47ZDaniel Kolesaapk3: a way to pin a package in place upon installationi'm currently trying to come up with a robust approach to handle kernel packages - i need old kernels to stick around so that people have something to revert to when updating - right now i'm having kernels have a pre-upgrade hook which b...i'm currently trying to come up with a robust approach to handle kernel packages - i need old kernels to stick around so that people have something to revert to when updating - right now i'm having kernels have a pre-upgrade hook which backs things up and then restores things in place afterwards, but i don't like this approach much (it breaks atomicity and isn't exactly robust)
so i considered the idea of versioning the pkgnames (i.e. instead of `linux-lts` the package name would be e.g. `linux-lts-6.6.6-0-generic` - this would ensure that a kernel update is just a new package to install, and pruning old kernels would not need a dedicated tool, but rather would be just standard package management
however, we currently have no way to actually pin the package in place after installation, so this is not implementable; it's not realistic to require users to add every kernel's explicitly versioned name into world, so maybe a feature could be added to aid this?
ideally we'd have a kernel package with a versioned name (e.g. `linux-lts-6.6.6-0-generic`) depended on by a package with an unversioned name (`linux-lts`); the unversioned name is what one would use for initial installation, and that would:
1) depend on the latest versioned name
1) that would somehow pin the versioned name in place
2) newer version of the kernel with same provider would result in a standard upgrade by the dependency being switched, however the old package would not get purged, and the new version would get pinned again (with its full versioned name)
3) purging old versions would be a simple `apk del`, with a full choice of what would get purged
there are probably other non-kernel cases where such mechanism would help too
or perhaps somebody has an idea how to implement this or equivalent mechanism without requiring new features?
ref https://gitlab.alpinelinux.org/alpine/apk-tools/-/issues/10887https://gitlab.alpinelinux.org/alpine/apk-tools/-/issues/10956deferring chowns to unknown users until after triggers2024-01-09T09:05:37ZDaniel Kolesadeferring chowns to unknown users until after triggersI'm currently thinking of revamping the way users are handled. Ideally, I'd like to reduce usage of pre/post-install/upgrade/deinstall hooks as much as possible (the ideal amount being zero) in order to allow for fully atomic transaction...I'm currently thinking of revamping the way users are handled. Ideally, I'd like to reduce usage of pre/post-install/upgrade/deinstall hooks as much as possible (the ideal amount being zero) in order to allow for fully atomic transactions (hooks break that as they require the filesystem state to be updated). For users/groups, instead of doing it in hooks, I'd like some kind of central sysusers process (similar to systemd-sysusers) to take care of creation, and have it run from a trigger on the directory containing the configs.
Currently, user handling gets in the way of this. The apk files store ownership as usernames/groupnames, which is good as it allows uids/gids to be allocated dynamically. However, it also means that the user/group needs to exist in the passwd/group file so that it can be applied.
I gave this some thought, and had an idea - how about we simplify defer chowning the file to after triggers have completed running? Basically, every time the lookup fails, record the failure, then once triggers have run, retry the lookup and chown. Thoughts?https://gitlab.alpinelinux.org/alpine/apk-tools/-/issues/10953Request to adopt and document an offical MIME Type2023-11-22T19:28:44ZvetsinRequest to adopt and document an offical MIME TypeIt can useful, specifically in the case of [SBOMs](https://cyclonedx.org/), to associate a MIME Type with a given package.
If we presume the file `aaudit-0.7.2-r2.apk` would be also represented as `pkg:apk/aaudit@0.7.2-r2` we would als...It can useful, specifically in the case of [SBOMs](https://cyclonedx.org/), to associate a MIME Type with a given package.
If we presume the file `aaudit-0.7.2-r2.apk` would be also represented as `pkg:apk/aaudit@0.7.2-r2` we would also want a mime-type to differentiate it from an Android package (e.g. `application/vnd.android.package-archive`).
I would suggest, according to [RFC-6838](https://datatracker.ietf.org/doc/html/rfc6838), `application/vnd.alpine.package-archive` or similar and it is [registered to the IANA](http://www.iana.org/assignments/media-types)
Some examples:
* deb is `application/vnd.debian.binary-package`
* rpm is `application/x-rpm`https://gitlab.alpinelinux.org/alpine/apk-tools/-/issues/10950`apk del --purge` does not delete "apk-new" files2023-12-01T08:44:54Zqaqland`apk del --purge` does not delete "apk-new" filesI have this package with its config in `/etc`:
```
miniflux.conf
miniflux.conf.apk-new
```
Now delete this package:
```
$ doas apk del --purge miniflux
(1/3) Purging miniflux-openrc (2.0.44-r3)
(2/3) Purging miniflux-doc (2.0.44-r3)
(...I have this package with its config in `/etc`:
```
miniflux.conf
miniflux.conf.apk-new
```
Now delete this package:
```
$ doas apk del --purge miniflux
(1/3) Purging miniflux-openrc (2.0.44-r3)
(2/3) Purging miniflux-doc (2.0.44-r3)
(3/3) Purging miniflux (2.0.44-r3)
Executing busybox-1.36.1-r4.trigger
Executing mandoc-apropos-1.14.6-r8.trigger
OK: 6501 MiB in 1077 packages
```
But still have this file left
```
miniflux.conf.apk-new
```https://gitlab.alpinelinux.org/alpine/apk-tools/-/issues/10902`apk add --virtual` conflicts with tagged repositories2023-07-09T13:03:57ZDaniel Rudolf`apk add --virtual` conflicts with tagged repositoriesCurrently it's not possible to install a package from a tagged repository (`package@repository`) with a virtual package (`--virtual`/`-t`):
```
$ apk add --virtual .fetch-deps py3-pip@testing
ERROR: 'py3-pip@testing' is not a valid chil...Currently it's not possible to install a package from a tagged repository (`package@repository`) with a virtual package (`--virtual`/`-t`):
```
$ apk add --virtual .fetch-deps py3-pip@testing
ERROR: 'py3-pip@testing' is not a valid child dependency, format is name([<>~=]version)
```
It would be great if we can combine these two features.https://gitlab.alpinelinux.org/alpine/apk-tools/-/issues/10892Fuzz apk-tools2024-02-23T12:54:00ZjvoisinFuzz apk-toolsIt would be nice to have some [fuzzing]( https://en.wikipedia.org/wiki/Fuzzing ) for apk-tools, since it's doing some cryptographic operations, has a lot of privileges, parses things coming from the internet, …
I would have done it myse...It would be nice to have some [fuzzing]( https://en.wikipedia.org/wiki/Fuzzing ) for apk-tools, since it's doing some cryptographic operations, has a lot of privileges, parses things coming from the internet, …
I would have done it myself, but since apk is using a database, it's non-trivial to write proper fuzzers :/backloghttps://gitlab.alpinelinux.org/alpine/apk-tools/-/issues/10891Add an option to download the packages before upgrading/installing packages2023-09-18T13:45:05ZBart RibbersAdd an option to download the packages before upgrading/installing packagesWhen running `apk upgrade` or `apk add` the packages are downloaded and installed 1-by-1. This means that if your internet connection for some reason drops out in the middle of it, you now have a partially upgraded system. It would be gr...When running `apk upgrade` or `apk add` the packages are downloaded and installed 1-by-1. This means that if your internet connection for some reason drops out in the middle of it, you now have a partially upgraded system. It would be great to have a command line switch or environment variable to tell apk to first download all packages it's modifying before installing them, so network failures halfway through don't leave you with a partially updated system.backloghttps://gitlab.alpinelinux.org/alpine/apk-tools/-/issues/10887feature to keep old/previous package when upgrading kernel2024-02-23T12:28:43ZNatanael Copafeature to keep old/previous package when upgrading kernelTwo problems:
- when kernel package is upgraded, modprobe will stop working til machine is rebooted, because old kernel modules were deleted.
- it would be nice to keep old kernel around for a while, in case new kernel is broken. For ex...Two problems:
- when kernel package is upgraded, modprobe will stop working til machine is rebooted, because old kernel modules were deleted.
- it would be nice to keep old kernel around for a while, in case new kernel is broken. For example as `/boot/vmlinuz-lts.old`
Possible solution:
We could have a virtual `.old` or `.previous` package. When flagged packages (`linux-lts`would have a flag of some sort) apk would on upgrade transfer ownership of the old package to this virtual package. Files that would be deleted are kept, and files that would be replaced could get a `.old` suffix.
The result would be that `/lib/modules/<old-version>` are transferred to virtual `linux-lts.old`, and `/boot/vmlinuz-lts` are kept as `/boot/vmlinuz-lts.old`. User can then chose to keep this til next time linux-lts is upgraded or for example clean up .old as last step during bootup. (for example `apk del '*.old'` or similar)
This way `modprobe` will continue work after an `apk upgrade` and user can have a vmlinuz-lts.old fallback in boot loader in case new kernel is broken.
Any package could be flagged with 'keep-old' but I think it mostly makes sense for linux kernels.backloghttps://gitlab.alpinelinux.org/alpine/apk-tools/-/issues/10881slightly bizarre add/upgrade behaviour2023-03-01T12:56:16ZGhost Userslightly bizarre add/upgrade behaviouri don't have a good reproduction for this. what happens is:
- there is a prebuilt CI image that has some 'older' version of a package installed. in this case, the ncurses libraries.
- a CI run starts
- the image runs `apk update`. and t...i don't have a good reproduction for this. what happens is:
- there is a prebuilt CI image that has some 'older' version of a package installed. in this case, the ncurses libraries.
- a CI run starts
- the image runs `apk update`. and there are newer versions of the things already installed.
- the image then does `apk add` of a bunch of stuff that isn't already in `world`.
and it fails with:
```
ERROR: unable to select packages:
ncurses-terminfo-base-6.4_p20230218-r3:
breaks: libmenuw-6.4_p20230225-r0[ncurses-terminfo-base=6.4_p20230225-r0]
libformw-6.4_p20230225-r0[ncurses-terminfo-base=6.4_p20230225-r0]
satisfies: libpanelw-6.4_p20230218-r3[ncurses-terminfo-base=6.4_p20230218-r3]
libncursesw-6.4_p20230218-r3[ncurses-terminfo-base=6.4_p20230218-r3]
libncursesw-6.4_p20230218-r3:
breaks: ncurses-dev-6.4_p20230225-r0[libncursesw=6.4_p20230225-r0]
satisfies: python3-3.11.2-r0[so:libncursesw.so.6]
gettext-libs-0.21.1-r1[so:libncursesw.so.6]
libpanelw-6.4_p20230218-r3[so:libncursesw.so.6]
libmenuw-6.4_p20230225-r0[so:libncursesw.so.6]
pinentry-1.2.1-r0[so:libncursesw.so.6]
readline-8.2.001-r0[so:libncursesw.so.6]
libedit-20221030.3.1-r0[so:libncursesw.so.6]
libformw-6.4_p20230225-r0[so:libncursesw.so.6]
libpanelw-6.4_p20230218-r3:
breaks: ncurses-dev-6.4_p20230225-r0[libpanelw=6.4_p20230225-r0]
satisfies: python3-3.11.2-r0[so:libpanelw.so.6]
```
but, if the `apk add bunch of stuff` is preceded by `apk upgrade`, no errors happen. i don't know what causes this.
to be clear, i don't think there is anything invalid at all in the above packaging. the apkbuild for ncurses is [this](https://git.alpinelinux.org/aports/tree/main/ncurses/APKBUILD?id=0ad370efb53b5a388e82b62b21ec8733b34a7aad). strictly speaking, nothing actually conflicts here (between files/paths), upgrades work fine, etc. the failing CI job is https://gitlab.freedesktop.org/emersion/wlroots/-/jobs/37107011 .
once the CI image 'gets regenerated' so the already-installed packages are the same as the ones in the repositories, everything works fine. at that point, merely bumping the pkgrel with no changes on the above ncurses packages will get the same failure again, on starting the image and running `apk add some stuff`.
this /did/ work before. i think this is a regression in 2.12.11, but i can't point to anything because i don't have a good reproduction setup for this..
of course, merely running `upgrade` first fixes it, but as i understand it the mere `add` should also work?https://gitlab.alpinelinux.org/alpine/apk-tools/-/issues/10875add PURL field to apkv3 package data2024-03-08T14:45:39ZAriadne Conillariadne@ariadne.spaceadd PURL field to apkv3 package dataSecurity scanners have issues with disambiguating distribution package names (which exist in a flat namespace) verses upstream package names. In Alpine, a notable example of this would be the lua packages, e.g. `lua5.1`, `lua5.2`, etc. ...Security scanners have issues with disambiguating distribution package names (which exist in a flat namespace) verses upstream package names. In Alpine, a notable example of this would be the lua packages, e.g. `lua5.1`, `lua5.2`, etc. In these cases, scanners are unable to deduce that `lua5.1` is equivalent to upstream `lua~5.1` (e.g. lua 5.1.x).
An emergent industry standard to allow for disambiguation is the [Package URL specification](https://github.com/package-url/purl-spec). We should store this data in APKs, to help the scanners disambiguate.
(This would also require us to add PURLs where needed in our package build recipes, e.g. aports et al. But this is out of scope for here.)