5.6 KiB
- Outline
- Demos
Outline
Package management is a good idea
easy to install, upgrade, remove software
dependency resolution
centrally maintained
so no need to scour the Internet for installers or sources
Problems
But with traditional means there are still annoyances probably many of us have run into:
outdated packages
The application you want to use is too old in the official repositories.
version conflicts
You can't have two versions of an application installed at the same time. Most package systems won't accomodate this need for arbitrary versions.
changes affect all users
On a shared system a package upgrade affects everyone on the system. It happened often that I would accidentally break the system for other users on the same machine after an upgrade even though everything worked fine for me. It would have been nice if I could have only updated the applications I was using. These problems get a lot worse in big shared environments like clusters.
potentially dangerous
When a package is installed, system files are overwritten one by one. When this process is aborted you end up with a system in an inconsistent state.
There is also another potential danger: binary packages are inscrutable blobs. Reproducible builds are near-impossible with binary maintainer uploads. How can we really trust?
Partial solutions
third-party repositories
They may solve the problem of outdated packages, but sufficiently large repositories such as EPEL may aggravate version conflicts. They all share the problem of trust.
manual compilation
You say you don't want to trust other people's binary packages so you compile software manually. This is not very practical as we lose all the benefits of package management: no more easy upgrades, no easy removal, no dependency tracking.
language-specific package systems
This just dilutes the problem and makes it all the more challenging to properly manage software. These package systems often don't even have feature parity with established system package managers as they aren't made for general package management.
build your own system package
This is rather hard for users because of arcane description languages and package formats, special build tools and directory structures, etc. It is uncomfortable even when you are trained to do this and do it somewhat regularly.
meta-package managers
The frustration with traditional packaging procedures has resulted in the rise of meta-package managers that generate low-quality but installable RPMs, debs or gems. Using them may simplify getting software installed and tracked by the system package manager, but it does not solve any of the other problems and is actually equal to admitting that packaging is hard.
giving up
You could also just shrug and deploy software by downloading an "appliance" or by using disk snapshots. There are very popular variations on this theme now but they all have in common that they are rather blunt and undisciplined. They ignore the problem and abstract it away with another level of binary indirection.
Guix
Another approach is functional package management, and GNU Guix is my functional package manager of choice. What is functional package management?
Functional?
Well, what is a function? This slide shows a pure function g that takes red discs and outputs green stars. That's all it can do. It cannot turn off the lights or eat all your candy. This means it has no side-effects.
It performs its task no matter the environment in which it operates. It does not depend on anything except the red disc, its input.
Given a certain input it always returns the same output; the result is immutable.
Functional packages
Mapping this to package management, we want the output of a package recipe to be solely determined by its inputs, i.e. its bag of dependencies. These inputs may be development headers, compilers and other build tools, and libraries, and their dependencies as well. The output is an immutable package.
Functional package management
We want a package definition to behave like a pure function; nothing in the environment (no other installed libraries, applications or headers) should affect it. It should only depend on declared and inherited inputs.
This leads to reproducible results, so we can cache results and even offload the build process to other machines.
The output should be immutable. It may not be changed by any other package evaluation. Any package built must be side-effect free.
Build process
In the case of Guix these properties are achieved by isolating each build. An unprivileged user communicates with the build daemon to make it build software. Each build is performed by one of the unprivileged build users in a chroot in which only the declared inputs are available. The results of each build are placed in their own, separate, unique directory in a cache called the store.
Demos
preparation
cd ./demo-home ./start.sh
installing a package
which hello # does not exist guix package -i hello guix package –list-installed # shows hello in store which hello # shows hello in PATH
switch to other user, show that "hello" only exists
profiles
guix package -i guile guile –version
guix package -i python -r guile guix package –list-generations guix package –roll-back
guix package -p old-times -i guile-1.8.8 ./old-times/bin/guile –version
reusing recipes for testing pre-releases or custom modifications
tar xf $(guix build -S hello) && \ sed -i -e 's/Welt/Open Tech Summit/' hello-2.10/po/de.gmo && \ tar czf hello-3.tar.gz hello-2.10 && \ guix build --with-source=$HOME/hello-3.tar.gz hello