Package Management - Present and (hopefully near) Future

Blog post by zooey on Tue, 2011-02-01 14:27

One month has passed (too fast), so it's time to summarize the developments
in the fields of package management for Haiku.

Where we are now

Implementation has been started, the following is a list of more or less
working elements of the package kit and accompanying tools:

  • infrastructure classes for translating package management requests into individual jobs and execution support for those jobs
  • request- and job-classes for managing package repositories (adding, updating, removing)
  • classes maintaining and representing package-specific information (package-provides & -requires, package-versions, ...)
  • pkgman - a (console-)binary implementing package management on top of the package kit
  • support for parsing ".PackageInfo" configuration files during package creation, a .PackageInfo file looks like this:
    name = mytool
    version = 0.9.8i-1
    architecture = x86
    summary = "mytool is cool"
    description = "the mytool package
    is a very nice package"
    packager = "me"
    vendor = "my company"
    copyrights = [ "(C) 2010, My Company PLC" ]
    licenses = [ "GPL v2", MIT ]
    
    provides = [
        lib:libmytool = 0.8.5,
        cmd:mytool
    ]
    
    requires = [
        haiku >= r1,
        libssl == 0.9.8
    ]
    

Filesystem structure

Following is the current version of the filesystem structure as it would be with package management active:

+-boot
  |
  +-apps ->             [symlink to /boot/common/pkg-tree/apps]
  |
  +-common
  | |
  | +-cache
  | |
  | +-packages          [dropping a package here will activate it system-wide,
  | | |                  most packages' contents will appear in 
  | | |                  /boot/common/pkg-tree, but specially marked system
  | | |                  packages will appear in /boot/system]
  | | |
  | | +-history         [contains info required for rolling back in time, used
  | | |                  by package manager]
  | | |
  | | +-jailed          [dropping a package here will make its contents appear
  | |                    in a package-specific folder under pkg-tree (a 'jail'),
  | |                    from where only packages that were marked as depending
  | |                    on this one specifically will be able to access it]
  | |
  | +-pkg-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
  | | |
  | | +-bin
  | | |
  | | +-boot
  | | |
  | | +-data            [+ what used to be in 'share']
  | | |
  | | +-documentation
  | | |
  | | +-include
  | | |
  | | +-lib
  | |
  | +-settings          [+ what used to be in 'etc']
  | | |
  | | +-backup          [room for setting backups - used by package manager
  | |                    to backup settings during an upgrade]
  | |
  | +-var
  |
  +-home
  | |
  | +-config
  | | |
  | | +-packages        [dropping a package here will activate it for user]
  | | | |
  | | | +-history       [contains info required for rolling back in time]
  | | | |
  | | | +-jailed        [dropping a package here will activate it jailed for 
  | | |                  user]
  | | |
  | | +-pkg-tree        [mountpoint of user package-fs, contents of the 
  | | | |                packages in /boot/home/packages appear here]
  | | | |  
  | | | +- ...
  | | |
  | | |
  | | +-settings
  | |   |
  | |   +-backup        [room for setting backups ...]
  | |
  | +-mail
  | |
  | +-people
  |
  +-system              [any system-packages found in /boot/common/packages
    |                    will appear here - those contain either a complete
    |                    "system" or small, sequential "system-fix" updates]
    |
    +-develop           [moved here from /boot/develop (except for the 'tools'
    |                    folder), as it depends on the current system - the
    |                    tools subfolder (gcc & binutils) will be spread out
    |                    over /boot/common/pkg-tree]
    |
    +-optional          [moved here from /boot/optional, as the contents depend
                         on the system]

In contrast to the last one presented in my blog, there no more is a separate "ports" tree, ported packages will just be treated as haiku-native packages (the line between these two classifications is too hard to draw). As a result, ports would have to follow some set of Haiku policies, defining where any package may (and may not!) put files. There will be a tool that will check any package against these policies and only packages complying with them will be made part of the official Haiku repositories.

Bits and Pieces

Package "Jailing"

One concept for dealing with ABI incompatibilities is to allow packages to be "jailed": a jailed package will not be activated in the usual manner, but its contents will appear completely separate somewhere in a folder specific to that package. Jailed packages will not take part in package management at all, i.e. the will usually be other (newer) versions of jailed packaged installed on the system.

Now if an update of a (supposedly compatible) library package is found to break one or more applications, the package manager can be asked to jail the last working version of that library package. Additionally, an attribute would have to be added to broken application(s) referring to the jailed version of the library. Upon activation of the application package(s), the package-fs would create links in a package-local 'lib' folder to the jailed library.

What's left to do?

A lot ;-), I'm afraid [in planned implementation order]:

  • the 'package' tool parses .PackageInfo, but doesn't actually write any of these package attributes to the package file yet (I plan to to work on that later today)
  • the repository format needs to be defined and implemented. It's pretty clear that the repository format will follow the example set by Ingo's hpkg format, i.e. it will contain package-attributes in a very compact format that's fast to read.
  • tools for setting up a package building environment need to be created, which will basically setup a chroot environment containing just the packages required for building a specific target package, enter the chroot, build the software and package it.
  • Haiku's package policies (rules about where files of specific types have to go) need to be defined and a tool needs to be implemented that checks hpkg files against those policies.
  • supporting tools for creating a package repository from a set of packages (and uploading that repository to some server) need to be implemented
  • the package-fs needs to support an ioctl that returns information (package attributes) about the currently active packages - this is required by the package kit's solver when it needs to compute the required actions for any package action request.
  • the package kit's solver needs to be implemented, which basically means collecting package attributes from active packages and all repositories and passing them to libsatsolver (the same solver library that's used by openSUSE's zypper).
  • the package kit (and pkgman) needs to gain more requests and jobs, implementing addition, update and removal of packages
  • the bootloader needs support for package-fs, in order to be able to actually find the system (as that's contained in packages, too)
  • a caching mechanism should be added to the package-fs, such that it doesn't need to parse all the hpkg files individually, but instead can store its state and restore it after a reboot (unless the state of packages has been altered, of course).
  • support for package jailing needs to be implemented in the package kit
  • [ probably some more stuff I forgot ]
  • finally, when the package kit itself is working as intended, a graphical package management tool would be cool

That's it for now - I'll try to continue working on this stuff during the next weeks ...

Comments

Re: Deleting packages, deleting dependencies

Thanks for the clarification zooey, I'd missed the part about apps having both private apps /app/lib and access to the public tree imagining it all like a massive heap. It's a nice solution.

I'm curious about whether/how manually installed bundle apps (dropped into /apps) will have access to any package installed libs or will they be required to provide all libs themselves. And a sort of vice versa, will packaged apps be able to access system libs not in the tree? In the first instance watching for new app bundles and providing libs via package install might be a nice middle ground for bundle purists, but with package managed libraries?

Finally about deleting. As apps can arrive via two routes how will it handle removal? Will the user need to remember how they installed an app to remove it? Or is there some magic here?

Thanks again for all your hard work. I'm not nitpicking just genuinely interested in how this fits together, and its clear you've put a lot of thought into this. All the best

Re: Deleting packages, deleting dependencies

mfitzp wrote:

Thanks for the clarification zooey, I'd missed the part about apps having both private apps /app/lib and access to the public tree imagining it all like a massive heap. It's a nice solution.

I'm curious about whether/how manually installed bundle apps (dropped into /apps) will have access to any package installed libs or will they be required to provide all libs themselves. And a sort of vice versa, will packaged apps be able to access system libs not in the tree? In the first instance watching for new app bundles and providing libs via package install might be a nice middle ground for bundle purists, but with package managed libraries?

Manually installed (activated) apps have access to package installed libs, just as any non-activated apps (which live anywhere and can be started via double-click on the package file) have. All that applies here is that the runtime-loader needs to find the library in one of the usual lib-folders. It's not the case the other way around, though. Each package (whether activated or not) will only ever find libraries that have been activated (i.e. that live in one of the lib folders in /boot/system, /boot/common or /boot/home/config). The reason is basically the same: if the libs live somewhere else, the runtime loader won't find them.

mfitzp wrote:

Finally about deleting. As apps can arrive via two routes how will it handle removal? Will the user need to remember how they installed an app to remove it? Or is there some magic here?

No magic, really, all you need to do in order to remove an app is to drag the respective package file into Trash or remove it via the package manager. Basically, the system doesn't need to bother where a package came from in order to remove it. If the package has been installed via package manager and pulled along other dependencies, the package manager will notice next time you start it and ask you if any no longer required dependencies should now be removed, too.

Re: Package Management - Present and (hopefully near) Future

As I understand right package-fs just union archives in one mount folder.
1) What happend when 2 or more packages have libraries with same name but with completly diffrent functions?
For example:

Package App1
App1
lib
  libruntime.so
Package App2
App2
lib
  libruntime.so

2) Does package-fs slow down access to package files?

Re: Package Management - Present and (hopefully near) Future

X512 wrote:

As I understand right package-fs just union archives in one mount folder.
1) What happend when 2 or more packages have libraries with same name but with completly diffrent functions?
For example:

Package App1
App1
lib
  libruntime.so
Package App2
App2
lib
  libruntime.so

With the current package-fs, I think whatever libruntime.so is found first will win (i.e. the other will be invisible). In any case (no matter if those libraries provide different or the same functions), this is a situation that should be avoided by the package manager, of course.

I have planned to add support for "levels" to package-fs, such that you can declare a package to be on a higher level than "normal" packages in order to let all it's files win over any other conflicting files from other packages. During standard system use, this should not be necessary, though (but it might be interesting during development).

X512 wrote:

2) Does package-fs slow down access to package files?

That depends on the access pattern: packages are compressed, so the contents need to be decompressed on-the-fly. Decompression is a bit of a slowdown, but since the files are smaller, less disk blocks have to be read (and disk access is much slower than decompression). So overall it is difficult to say if there will be any noticeable performance difference when accessing package files.

However, one thing that is going to be noticeable (at least before we start to implement caching), is the time it takes to populate the package-fs from all the packages contained in the mounted packages-folder. It really depends on the amount and size of packages, but when I tested with more than 1000 installed packages (2.4 GB compressed size!), it took around 16 seconds to populate the pkg-tree folder after a reboot and 3 s on second try (i.e. with packages coming from the file cache). That needs to be improved of course, but before that really becomes a problem, there have to be at least 100 real Haiku packages available, so I suppose there's enough time ... ;-)

Re: Package Management - Present and (hopefully near) Future

I would like to know how, or if, I can keep my applications on another partition, have my applications unaffected if I reinstall Haiku, not having to reinstall any libraries afterwards, while sticking with the proposed package management.

If that is not possible, then you're making things a hassle. I will have to make sure my system partition is always very big (If I install too many apps I will have to reinstall Haiku on another partition to make it fit), reinstalling Haiku will involve doing a lot more than just installing Haiku; I have to first make a list of all my apps, save their settings somewhere and then reinstall every app I used and its dependencies.

Re: Package Management - Present and (hopefully near) Future

I think in this case maybe is a problem of the Haiku installer, for now as it is very simple it permits to install Haiku on a partition only, you can't for example put all Haiku System in the first partition and for example the user's home (that contains your installed packages) in an another... if you can and the home is installed in the chosen partition and Haiku knows it has to mount this partition as your home, then all should work after re-installation, too...

Re: Package Management - Present and (hopefully near) Future

So the applications and their dependencies will be installed to the home directory? I didn't know that, thanks.

Re: Package Management - Present and (hopefully near) Future

sparklewind wrote:

So the applications and their dependencies will be installed to the home directory? I didn't know that, thanks.

It depends... there are 3 types of applications:

  1. System: (part of Haiku, modified only on system updates/upgrades I suppose)
  2. Common: when Haiku will became multiuser where will be shared application
  3. they will be in /home/config/packages those are the application that you've installed, for yourself

So, if you're in a multiuser environment the common applications can be put in a separate partition too, and mounted in common as are the home(s)... but as I said this a future thing... for now installer and bootman not support multiple partition environment!

Re: Package Management - Present and (hopefully near) Future

Is there support to run postinstall, pre-install, post-remove and pre-remove script/code? If not, there should be a complete facility for doing every possible thing a package might have to do in these phases, for e.g. install drivers, patch files, bring up network interfaces etc.

Also "checkinstall" where a package can refuse installation. Scenario: There is a running application which prevents unloading of certain other applications all part of the base package. Now if one tries to install the package while they are still running parts of the application, the package should refuse installation. (eg; VirtualBox will refuse to install a new copy of VirtualBox if there are Virtual Machines being run by the current user as it doesn't want different binaries on disk and memory).

All these should be taken into account while designing a package management system early on :)

Package management is something that needs to be designed right very early otherwise it causes too much frustration to end users, so I hope the community comes forward and helps the design process early on.

Hope that helps.

Re: Package Management - Present and (hopefully near) Future

Even though i love Linux i wish that installing and managing programs would be easier. I like the whole "one folder per program" approach. A single klick/drag 'n drop/copying install where you copy the relevant files to a single folder and you uninstall the program by simply deleting the program folder.

The way Linux works now is that programs get exploded all over the file system, into many folders, full of files from other programs, and a bunch of symbolic links, no thanks.