Simplified scheme of components and their interaction.
1. Implementation of libapk-qt
libapk-qt was supposed to be very simplified level of abstraction on top of apk-tools API which is hidden inside libapk.so (part of Alpine's apk-tools package). It should provide easy-to use, C++/Qt style methods to query packages database, add/remove packages and preform system upgrade.
First problem was that apk-tools does not have "stable API" and even libapk.so is not installed by apk-tools (no apk-tools-dev). So the solution for this was to use apk-tools as git submodule and embed apk.so into libapk-qt.so as static lib. Turned out that it also contains libfetch (from FreeBSD?) to perform network I/O ops.
Second problem is that apk headers are not supposed to be used from C++, so they cause compile errors (for example, some function parameters are named "new", which is reserved keyword in C++). I also have to apply this patch on top of apk-tools checkout just to make it compile.
Actually embedding apk.so into libapk-qt helped development a lot, I could use code navigation in QtCreator inside apk-tools to study its sources, and use source-level debugging with breakpoints.
2. Implementation of discover's APK backend
This turned out to be a larger task, and although I could create a simple proof-of-concept relatively quickly, there were many problems left.
First problem is that some package actions require root permissions to modify apk package database. So I had to additionally Use KAuth framework for that purpose. I added privileged kauth helper executable that is invoked by framework (internally using DBus) that actually performs package management tasks. So the picture above should be even more complicated, because now kauth helper actually uses libapk-qt, not discover apk backend itself.
Second problem is that Discover UI has various progress bars to inform user about progress of ongoing tasks, and libapk-qt interface was designed to be synchronous. For example you call system upgrade action API that corresponds to "apk upgrade" and function does not return until upgrade is finished. Discover was initially designed to interact with PackageKit, via PackageKit-Qt5 library, that is simple wrapper on top of packagekitd DBus interface:
So, by nature this DBus interface is asynchronous: you start operation (Transaction), receive progress updates, and then a signal when operation is finished. All communication over DBus, all hard work is done inside packagekitd by one of its backends.
apk has support for writing operations' progress into special pipe file (progress_fd), but I couldn't use it due to synchronous nature of libapk-qt API. So, to properly implement progress updates, new asynchronous API has to be designed in libapk-qt. It will run operations in background thread and will support Qt's signals/slots and progress updates!
With removal of alpinelinux-appstream-data from Alpine I'm not sure if this beautiful thingie is possble anymore (except on 3.12)
Alexey Min restore previous generator tooCogitri Then we'd still have to maintain that, have a separate URL, have the storage and CPU time to run it etc.I'd rather have Discover be able to download appstream data, the plugin for GNOME Software which does that is only a few hundred LoCCogitri more like only storage tbhCogitri https://gitlab.gnome.org/GNOME/gnome-software/-/blob/master/plugins/external-appstream/gs-plugin-external-appstream.cYup, the appstream data should be saved to $DIR/app-info/xmls/$FILEWhere DIR can be /usr/share or /var/cache or probably other things too in XDG_DATA_DIRSGNOME Software installs it to /var/cache
So what about the suggestion of making Discover able to download the appstream data? I don't know the codebase, but from distance it sounds pretty feasible.
DiscoverNotifier support is not implmented yet (needs a backend plugin for that thing too), but this should provide "new distro release" notification, see #943 (comment 492514457)