Package Management, First Draft

Blog post by zooey on Sat, 2011-01-08 19:38

The following is a first draft of how package management on Haiku could look like. I'm more than sure that there are aspects missing here, but we need to start the discussion somewhere ...

Several people have already added their ideas on package management to the wiki article. Additionally, many opinions have been stated in comments to my first blog entry.

I have tried to incorporate most ideas mentioned into this draft, but due to the sheer amount of contradicting views, some sacrifices have to be made.

HPKG and Package-FS

Haiku's package format (hpkg) has been designed explictly to support swift access to the contained file-hierarchy and -contents in order to facilitate mounting one or more folders containing such packages via Haiku's package-fs.

What happens if you mount a folder full of *.hpkg files is that the package-fs will combine all those packages to construct a (read-only) hierarchy of files and directories at the mountpoint. Moving packages into/out of the package-folder will adjust the mounted hierarchy accordingly (live).

In order to see how well this concept scales, I have experimented with two sets of hpkgs, which were converted from pacman packages: the small set had 168 packages amounting to 260 MB and the large one had 1052 packages amounting to 2.4 GB (all sizes refering to the compressed package files). On my testing machine, package-fs managed to populate the small tree in 2 seconds with an empty file cache and in 0.6s with a full cache. The large set took 16 seconds to populate after boot and 3.2s on second try. With keeping in mind that package-fs currently doesn't do any caching by itself whatsoever, these are very promising numbers. I'm pretty positive that with added caching, we could bring down the delay for mounting a large package-fs to levels which are acceptable as part of Haiku's boot process.

A modified folder hierarchy

In order to be able to support user-specific as well as system-wide activation of packages, and in order to clearly separate the cumbersome, dependency-ridden ports hierarchy from the rest of Haiku, I've found it necessary to remodel Haiku's basic folder hierarchy to some extent.

Here's my filesystem layout suggestion (please excuse the ascii-art):

/boot
|                     [/boot/apps is gone - system-wide applications now appear
|                      in /boot/common/tree/apps]
|-common
|---develop           [moved here from /boot/develop]
|---packages          [dropping a package here will activate it system-wide]
|---settings          [common settings]
|-----backup          [room for setting backups - used by package manager to backup settins during an upgrade]
|---tree              [mountpoint of system package-fs, contents of the packages in /boot/common/packages appear here, the 
|                      folders follow "Haiku filesystem hierarchy" (to be defined, an example given below)]
|-----add-ons
|-----apps
|-----boot
|-----data
|-----documentation
|-home
|---packages          [dropping a package here will activate it for user]
|---settings          [user-specific settings (N.B.: may come from apps that live in /boot/common/tree)]
|-----backup          [room for setting backups ...]
|---tree              [mountpoint of user package-fs, contents of the packages in /boot/home/packages appear here, the 
|                      folders follow "Haiku filesystem hierarchy"]
|-----add-ons
|-----apps
|-----data
|-----documentation
|-ports
|---packages          [dropping a (port) package here will activate it]
|---tree              [mountpoint of ports package-fs, contents of the packages in /boot/ports/packages appear here, the 
|                      folders follow whatever facilitates easy porting, i.e. the hierarchy basically is unixy - what's shown below
|                      is just an example]
|-----bin
|-----boot
|-----etc
|-----include
|-----lib
|-----share
|-----tmp
|-----var
|-system              [unchanged, contents can be updated via package manager by actual installing (unpacking) of either a complete
|                      "system" package or sequential "system-fix" packages]
|---optional          [moved here from /boot/optional, as the contents depend on the system]

The most obvious change is the ripping out of the ports-related stuff from /boot/common into a separate hierarchy. Basically, this means that /boot/common no longer has to contain Unixy paths like 'etc', 'share', 'var' and the like. After all, Haiku isn't Unix and we can chose our own folder layout. The ports subhierarchy can be modeled such that doing the actual porting of Unixy software is as easy at it can be.

Early during the boot process, Haiku would populate the three package-fs mountpoints and could then use all the software contained in any of them. Inter-dependencies between these the four sub-systems (/boot/sytem and the three package-fs mountpoints) are as follows:

- /boot/system does not depend on anything else.
- /boot/common/tree contains Haiku-specific applications/frameworks and may depend on anything in /boot/system, but not on anything in the /boot/ports. If any software requires Unixy components (libraries), it must bring them along as part of its own bundle.
- /boot/home/tree is the same as /boot/common/tree only for a single user
- /boot/ports/tree will most probably never depend on anything else but the POSIX-/libc-specific parts of /boot/system, i.e. libroot.so & libbsd.so. Unixy software doesn't know about Haiku kits, so it won't use them.

So how would this be used then?

Judging by the comments to my initial blog entry, it seems clear that many people do not want to have anything to do with the package management system at all. They'd like to be able to download Haiku-apps from any odd website and then start them by double-clicking the downloaded file.
Fair enough, when you invoke a package, Haiku would temporarily mount this package by means of package-fs and then start the application.

Installation of a downloaded bundle would mean to drag'n'drop it into /boot/common/packages or /boot/home/packages, depending on whether it shall be available system-wide or just for per-user.

Unixy software with dependencies on other packages demands for support by a package management tool, so if you'd like to install such software, you start that tool (either the console- or the GUI-version), search and select the software and then tell it to install it. Taking Subversion as an example, the package management tool would automatically download APR-util, Neon, LibIconv, LibXML2, OpenSSL and SQLite and place all of these packages into /boot/ports/packages. Unpacking would be done by package-fs and the 'svn' command would be available immediately (in /boot/ports/tree/bin).

Since the package-trees are immutable, you can no longer simply fiddle with any of the files. In order to change something manually, you'd have to find the hpkg containing the specific file you'd like to change, move that hpkg to some place else, unpack it, change the contents, repack it and then move it back to the .../packages folder.

System Upgrades

System upgrades would be done by the package management tool (maybe with a separate UI just for that task). A system upgrade would be executed by downloading a single package that contains the whole /boot/system folder. This package would be unpacked to /boot/system_next, /boot/system renamed to /boot/system_last and /boot/system_next to /boot/system. These renames aren't atomic, but the bootloader could surely be adjusted to cope.

For bug- & security-fixes, small "system-fix" packages could be created, which contain changed files that would be unpacked on top of the existing /boot/system folder.

The package management tool

The package management tool, as I imagine it currently, would know about all the available and installed hpkgs (by means of queries), but clearly separate Haiku applications from ports.
When updating any software, the pm-tool could zip an eventual settings folder of that software and store that in a backup folder, such that these settings can be restored when a downgrade should ever be done.

The implementation details of the actual tool are still vague (to say the least), but it is clear that it will only ever be relying on the actual hpkg files that live on the system. Any special markups like locking of specific packages (in order to keep them from being upgraded) will be done as attributes on those hpkgs. For performance reasons, it may be necessary to use some kind of cache for the info contained in all those packages and probably a service that manages the cached info and answers requests for that data to any interested party.

Many other aspects (handling of drivers, support for application-mimetypes via package-fs, writable folders in /system/ports) are explicitly not mentioned here.
First we need to settle on the general idea, so please attach your flames as comments or send them my way ;-)

Comments

Re: Package Management, First Draft

Thanks for doing this.

Some applications have special license agreements (souls, politics, whatever), and thus we need to ask the user for permission to run the application contained in the bundle. I think you might need to factor user permission in.

Not sure if you look at Charka Linux at all
Bundles
Chakra bundles are half way between the Mac OS X concept of bundles and the package-dependency concept. This is, bundles are one-click applications, auto mountable file systems which contain all the needed files to run an application which is not in the repositories and automates the installation of dependencies in the repositories if needed. Also, Chakra bundles stores bundle-related user configuration files in the bundle, which assures the user a clean home directory.

http://chakra-project.org/wiki/index.php/Bundles

Chakra has three different types of bundle: launcher, installer and setup bundles. They are all bundles of software, but they interact with the user differently.

Launcher Bundles
Launcher bundles are bundles that run when you click on them

UnionFS Chrooted Launcher Bundles
This type saves it's configuration data within itself.

Installer Bundles
Some applications have special license agreements (souls, politics, whatever), and thus we need to ask the user for permission to run the application contained in the bundle.

http://chakra-project.org/wiki/index.php/Bundle_System

I do like how you have move the unix to a ports dir. I think it's great to be able to see what's what.

Re: Package Management, First Draft

From the review in last blog post, it looks like pacman is a good choice for package management.

Chakra uses pacman isn't it?
From the Chakra project page about bundles:

Quote:

UnionFS Chrooted Launcher Bundles
This type saves it's configuration data within itself. As an example, you can tweak an application and give it tweaked to your friends. It's a regular read-write ext4 filesystem image, containing the following files:

  • apps.sqfs
    A squashfs/lzma compressed filesystem image containing every binary, library, or file needed or given by the bundled application.
  • data.ext4
    A regular read-write ext4 filesystem, that gets mounted as the chroot's '/home/default'. This is where the application saves it's configuration data. Example: GIMP saves window positions, added brushes, gradients, etc.
  • PKGINFO
  • .desktop
  • .svg

So we have a read-write image, containing a read-only image (the application) and another read-write image (the configuration)?

It looks like an unprivileged user can replace the application image. I am not sure we want to go that way?
For me it would be sufficient to store configuration in the home, and have a two-way relationship between configuration files and applications. So we can tell which application uses a specific config file and we can tell which config files a specific application uses.

Re: Package Management, First Draft

Yes Chakra uses pacman. They also have thier own official repositories and chakra community repositories. Essentially Chakra is what Ubuntu was for Debian. That is, Chakra is becoming a OS for novices while Arch Linux focuses on power users.

Re: Package Management, First Draft

My 2 cents:
Is it possible to make software purchase/install mechanism as shared library, so it can be embedded into various apps? Replicant capable maybe? or dedicated hpkg-class in Haiku API (sorry I'm not a programmer, can't say it right, but you get the idea).
For example, imagine package install engine integrated to WebPositive, or Tracker...

Re: Package Management, First Draft

Hey all, had to register for this one.

Thanks to Zooey for tackling this big task, this draft is a good starting point. Thanks also goes to everyone that commented on the matter.

After reading all the docs and comments i have some ideas cooking that might allow for a solution which would please (to some extent) both bundle and pkg management folks. I can't say any more at this point, i'd rather work out more details and test it through some use cases. I hope to publish something as soon as possible (this week).

To quote Fermat:
“I have discovered a truly remarkable proof which this margin is too small to contain.”

Re: Package Management, First Draft

I very much agree with these ideas. You really are setting yourself up for bad things when each program has its own updater.

Only assuming that you would like as large a user group as possible using Haiku, this would simplify things a lot for most people and make it much more tempting to install Haiku.

It would also be great if there was a simple way to get maybe Sun/Oracle's free virtual machine software with Haiku as a package that could easily be installed on Windows, Mac, and Linux so that people without a spare computer could easily install and play with Haiku without wiping out their current OS.

Yes I know that Haiku is not setup (or at least I don't think it is) to wipe out the hard drive on a Mac and replace OS X with Haiku. What could happen though, is if it is easy enough "even for Mac users" to install it with a virtual machine and play with it, that they would get a second computer that they could install Haiku on as the main OS. This could grow the amount of users using Haiku.

Back to the main point of this reply though is that you really should have a centralized updater instead of having each developer create their own. This would provide a consistent interface which you would have control over and know that any bugs and inefficiencies were ironed out.

Re: Package Management, First Draft

I really like your idea, and can see some really nifty gains from it. I think it is important that you are laying the foundation for the future. That said, you are creating basic tools that can be enhanced in later versions.

I can see a need for a tag in the hpkg format for use in running just anywhere. This way the system knows to mount this in the correct directory. Any hpkg that did not contain this tag would simply be run per user until it is installed under common.

The biggest need for a package management system stems from api/abi breakage from developers. It may be useful to have someone simply testing/checking for such breakage, and assigning a version to the api. You can use the library version, so libpng1.2 would be libpng1.2, but you could use any version up to the api breakage, so you may be able to use libpng1.6, but libpng1.7 becomes a new breaking point. If the package manager knows these things, then when using a ports hpkg,where this will admittedly be most useful, you could use libpng1.6 with the latest security update for all up that require libpng1.2, install a libpng1.7, and eliminate much of the problems. This would entail a lot of work, but would be useful for more than just haiku.

Also, Windows, Mac, iOS, Android, and any other widely used OS integrate the build tools into the System IDE, because this makes developers jobs so much easier. Malign some of those tools as much as you may want, but they are popular with users, and more important, developers. This should be a top priority, as this is what allows the automated building, and quick turnaround that these OSes enjoy. Please keep this in mind while developing your system, even if it means you implement much of it through Haiku's extension system.

Thanks, William.