| 1 | = Package Management Infrastructure = |
| 2 | |
| 3 | This pages gives an overview of what components belong to Haiku's package management infrastructure and how they work and interact. |
| 4 | |
| 5 | * '''package''' and '''package_repo''' are command line tools for building package and package repository files. They are discussed in [wiki:PackageManagement/BuildingPackages Building Packages]. |
| 6 | * '''packagefs''' is the file system that virtually extracts activated packages. |
| 7 | * The '''package kit''' is an API for package management related programming. |
| 8 | * The '''dependency solver''' is a part of the package kit. It solves dependencies between packages. |
| 9 | * The '''package management daemon''' is a background process that is activated whenever the user adds packages to or removes them from one of their activation locations. It verifies that all dependencies are fulfilled (prompting the user, if necessary) and performs whatever package pre-activation/post-deactivation tasks are required. |
| 10 | * The '''package manager''' provides the user interface for software installation, update, and removal. There are actually two programs, `pkgman`, a command line tool, and a GUI application. |
| 11 | |
| 12 | [[Image()]] |
| 13 | |
| 14 | == Software Installation Locations == |
| 15 | |
| 16 | In Haiku there are three places where software is installed. "/boot/system", "/boot/common", and "/boot/home/config". "/boot/system" is the place where the base system is installed. It is immutable and should not be affected by third party software. Only installing a new system release/update will change anything there. "/boot/common" is the place where third party software can be installed system-wide (i.e. for all users), while "/boot/home/config" is only for the user's software. The discrimination between those two doesn't make that much sense yet, but when Haiku supports multi-user it will (obviously each user needs their own home directory then, e.g. "/boot/home/<user>"). |
| 17 | |
| 18 | There are also the directories "/boot/apps" and "/boot/preferences" which we inherited from BeOS. With the migration to package management those will become symlinks to "/boot/common/apps" and "/boot/common/preferences" respectively, or we might even remove them completely. |
| 19 | |
| 20 | At each of the three installation locations a packagefs instance is mounted. Each instance presents a virtually extracted union of the contents of all packages in the subdirectory "packages" of that location. E.g. if one would extract the contents of all package files in "/boot/system/packages" to an actual directory, that would match exactly what is presented by packagefs in "/boot/system". With a few exceptions -- packagefs provides several additional directories. |
| 21 | |
| 22 | There are so-called shine-through directories which live on the underlying BFS volume. Normally a file system mounted at a directory would completely hide anything that is in that directory. These shine-through directories are handled specially, though; packagefs shows them just like they are on the BFS volume. One of those directories is "packages". This is necessary since otherwise it wouldn't be possible to add, remove, or update any packages. In "/boot/common" and "/boot/home/config" there are a few more shine-through directories like "settings", "cache", and "non-packaged". The latter is a place where software can be installed the "traditional", i.e. unpackaged, way. |
| 23 | |
| 24 | |
| 25 | == Software Installation == |
| 26 | |
| 27 | === Manual Installation === |
| 28 | |
| 29 | At the lowest level software can be installed by simply dropping a respective package file in a "packages" subdirectory of one of "/boot/system", "/boot/common", or "/boot/home/config". packagefs monitors the directory and, when happy with the newly added package, just presents its contents on the fly in the directory structure. The package is said to be activated. Removing a package has the opposite effect. |
| 30 | |
| 31 | Things are a bit more complicated due to the fact that packages usually have dependencies. E.g. when adding a package that has an unsatisfied dependency (e.g. needs a certain library that is not installed) it is not a good idea to activate the package nonetheless. The package contents (programs, libraries,...) might not work correctly, and, e.g. when shadowing other installed software, might even break things that worked before. |
| 32 | |
| 33 | The solution is that packagefs doesn't blindly act on its own when packages change, but first contacts the package management daemon. The daemon, a background process that sleeps most of the time, does then examine the new situation and checks whether all dependencies are fulfilled. If they are, it sends back an OK to packagefs which in turn activates/deactivates the packages as requested. In case there are issues with the dependencies, according to how it has been configured via settings, the daemon prompts the user immediately, checks remote repositories for solutions to the problem and presents the user with the possible options, or it even performs all necessary actions without bothering the user, if possible. One way or the other, in the end the problem has been solved or hasn't and the daemon reports back to packagefs with the result. |
| 34 | |
| 35 | To avoid always having to check all dependencies when booting, packagefs caches the last consistent state of package activations in a file in the "packages" subdirectory. Unless something has changed, it can just activate the previously activated package. If something has changed, it has to contact the daemon as soon as possible. |
| 36 | |
| 37 | |
| 38 | === Installation via Package Manager === |
| 39 | |
| 40 | While manual software installation is possible, the more comfortable way is to use the package manager. The package manager has a configurable list of remote software repositories. It knows what software is available in those repositories and what is installed locally. After the user has selected software packages to be installed/deinstalled, package dependencies are resolved, and packages are downloaded and moved to their installation location. |
| 41 | |
| 42 | The package manager has to synchronize its work with the package management daemon in order to avoid an inconsistent state when software is concurrently managed manually. This synchronization happens via the package kit, which communicates with the daemon. |
| 43 | |
| 44 | |
| 45 | === Application Bundles === |
| 46 | |
| 47 | Haiku also supports a concept that is commonly referred to as application bundles. An application bundle is a fully self-contained package that doesn't need to be installed anywhere. The implementation details have not yet been decided on. The basic idea is to either mount a dedicated packagefs with the content of such a package or have a special location where one of the three already mounted packagefs instances (likely the "/boot/home/config" one) shows that content. With a bit of Tracker (or even libbe) integration that will allow the mounted directory to be opened or the application to be started when such a package file has been double-clicked. |
| 48 | |
| 49 | |
| 50 | === Installation Location Order and Consistency === |
| 51 | |
| 52 | Having three separate installation locations for software requires some considerations regarding their consistency and interactions. There's a well-defined order of the installation locations: "/boot/home/config", "/boot/common", "/boot/system". This has already been the order in which on BeOS commands, libraries, and add-ons where searched (according to the environmental variables `PATH`, `LIBRARY_PATH`, and `ADDON_PATH`; with the exception that "/boot/common" was only planned but didn't exist yet). That e.g. allows a user to install a new/different version of a program in "/boot/home/config" and have it override the version in "/boot/common". |
| 53 | |
| 54 | This order also needs to be the order in which package dependencies are directed. While it shall be possible to have a library in "/boot/home/config" override one in "/boot/common" and have programs installed in the latter location use the overriding library, packages in an installation location must not have dependencies that can only be resolved to packages installed in a location that is prior according the order. E.g. a program installed in "/boot/common" must not depend on a library that is only installed in "/boot/home/config". When going multi-user that would mean the program would work for one user, but not for another one who hasn't installed the library. Similarly "/boot/system" is the fully self-contained base system. All dependencies must be resolved within it. A safe-mode boot should be possible with only the "/boot/system" packagefs being mounted. As a consequence these constraints have to be respected when software is installed or uninstalled. |
| 55 | |
| 56 | Another challenge that comes with having three installation locations is that some packages have compiled-in absolute paths to their own files (e.g. data files) or to their dependencies. The former could be solved by building three different versions of a package, but that wouldn't work with the latter and would be tedious anyway. The solution are dynamically generated symbolic links in a fixed location, "/boot/system/package-links", that for each installed package and its dependencies, refer to the respective installation location. |
| 57 | |
| 58 | For each installed package a subdirectory named like the package (package name plus version) will be generated automatically. That subdirectory contains a symlink ".self" which refers to the installation location of the package itself as well as a symlink for each of its dependencies pointing to their installation locations. E.g. for an OpenSSH package installed in "/boot/common" and OpenSSL installed in "/boot/system" the directory could look like this: |
| 59 | {{{ |
| 60 | /boot/system/package-links/openssh-5.8p2-1/ |
| 61 | .self -> ../../common |
| 62 | haiku -> ../.. |
| 63 | lib:libssl -> ../.. |
| 64 | }}} |
| 65 | Installing a different, compatible version of OpenSSL in "/boot/home/config" would automatically change the respective dependency symlink. Once supporting multi-user fully, the symlinks targets would also depend on the user ID of the process that checks them, so software installed only for the user is handled correctly. |
| 66 | |
| 67 | While it depends on the location the package has been installed in where the paths refer to, the absolute paths of the package links themselves remain stable. So they can be compiled in, when a package is built, and will work regardless of where the package is installed. |
| 68 | |
| 69 | Another problem the package links can solve are incompatible versions of the same package being installed in different locations. E.g. when a program and another program it depends on are installed in "/boot/common", installing an incompatible version of the latter in "/boot/home/config" will not break the former, since the dependency link will continue to point to the compatible version. With a bit of help from the runtime loader the same would work for libraries. In practice that's less of a problem, though, since libraries usually have a naming scheme and matching shared object names that already prevent mismatches. |
| 70 | |
| 71 | |
| 72 | == Software Repositories == |
| 73 | |
| 74 | A software repository is a collection of packages, usually accessible via the internet. Haiku's package management solution allows to refer to any number of software repositories from which packages can be downloaded and installed. The structure of the respository is very simple. It's just a set of files which can be downloaded via a common protocol (HTTP or FTP). One file is the repository index file in [wiki:PackageManagement/FileFormat#HaikuPackageRepositoryFormat HPKR format]. It lists all packages that are available in the repository together with their descriptions and dependency information. It is downloaded and cached, allowing user interfaces to show the information and the dependency solver to do the computation locally. The other files are the individual package files. |
| 75 | |
| 76 | The details of how changes are made to a repository (when packages shall be added, replaced, or removed) have not been decided on yet. Most likely the server side will be kept very simple by having the preparation been done on the client side. That means the client would compute the new repository index file, upload all new files including the index file, and finally tell the server to switch to the new index. |
| 77 | |
| 78 | |
| 79 | == The Package Kit == |
| 80 | |
| 81 | The package kit provides an API for all package management related tasks, including: |
| 82 | * Reading and writing HPKG and HPKR files. |
| 83 | * Adding, removing, and querying software repositories. |
| 84 | * Solving package dependencies. |
| 85 | * Added, removing, and updating packages. |
| 86 | |
| 87 | |
| 88 | == Localization == |
| 89 | |
| 90 | Package files and repository index files contain text strings -- e.g. the package short and long description -- that are presented to the user. Therefore translations for these strings must be available. Since it is impractical to include the translations in the package and repository index files, they must be provided in separate files. How exactly has not been decided on yet. |