A better way to install software

Update, December 2006: ZeroInstall seems to be moving on, and I've also been pointed to klik, which has the all-important presentation required to get this sort of thing off the ground. Both systems attack problems I don't, in particular klik's idea of having an application as a single file that can be copied around. klik's author has written a lucid presentation on the topic.

Thinking about Zero Install, Debian-stable-vs-unstable pain, and the annoyance of living on several computers, it struck me recently that it couldn't be too hard to arrange for the following desirable combination of properties:

  1. A read-only VFS like Zero Install's that lets you run apps without having to install them…
  2. …that lets you use existing distributions (Debian unstable and Gentoo portage being obvious choices for getting random stuff to run).
  3. …and that therefore doesn't necessarily rely on simply having files available on the 'net, but downloads, compiles and installs as necessary. The user will want to be warned about having to wait.
  4. …and does all this in an isolated filespace, so it doesn't interfere with the OS. Bye-bye buggy sprawling installs, hello simple, small, securable OS (kernel, drivers and daemons only) and leave the buggy sprawl in the VFS where it can only harm users.
  5. …and replicates across multiple machines, so that I can use any of them and find (up to constraints such as "doesn't build on this OS/arch" or "no room on the disk") the same software.

For want of a name, I'll call the system try. ("Do you have ruby installed? No, I'll try it…")

Here's how it works:

  1. I say try "deb unstable main non-free contrib", and try basically does apt-get install apt under /try/ It then adds some directories to my PATH.
  2. I find a program I'd like to run using

These two steps might reasonably occur in either order.

  1. I run blobwars.
  2. The VFS finds /try/debian-unstable/usr/games/blobwars when asked to search /try/debian-unstable/usr/games, which is on my PATH, and returns an installer script, which says "This program isn't installed. Shall I install and run it?". I say "Y". The installer does dpkg -S /usr/games/blobwars, apt-get install blobwars, and then blobwars, having done a suitable chroot and messed with LD_LIBRARY_PATH as necessary in the jailed APT repo under /try/debian-unstable.
  3. While I'm busy massacring evil aliens and rescuing innocent blobs, try executes the same install commands (as me) on $TRY_HOSTS using ssh.

Cool, huh?

I've tried to keep the above short, putting in just enough detail so you don't start writing your ranting reply before you get to the end. Now to address a few of the many extra points that occur:

  1. Installing to offline computers: try can batch up install commands for later execution (try sync <machine>?).
  2. It might be nice to have a unified searching mechanism for all the repos at your command; the great thing is you don't have to.
  3. Mostly useful on a single-user machine (?), a way of prioritising packages, so having idly installed the latest mega-game and then rushed off to Malawi the next morning, you don't suddenly discover all your latest development libraries have been kicked out of the cache. You could do this by name, or perhaps by category (using the distribution's categories, of course).
  4. "But I'll get a copy of glibc, gtk &c. for every distro I try!" And? You've got a 100Gb disk and a 1Mbps broadband connection. Hardware and bandwidth are cheaper than time and brain cycles.
  5. "How do I deinstall?" You don't. It's a cache. You can wipe it; if you try to install a conflicting package, your package manager will remove the conflicts automatically (maybe you want to be asked about that).
  6. "A command can't add things to PATH!" No, with bash you need to source a script to fiddle with your environment. You can hack around this (?) and/or have try start a nested shell with the right PATH and/or have an option to make it feed you the stuff you need to add to your path so you can go export PATH=try debian-unstable:$PATH.
  7. It would be nice to have short names for common repos. This is just an /etc/aliases file by another name, nothing fancy.
  8. "What about the users' security?" No worse than at present; we can take advantage of distros that use signing and other measures. Using the sort of security mechanisms provided by SELinux, better things are possible, e.g. to trust apps being try'd less than apps that are part of the "native" distro.
  9. You'd typically want your home directory mounted in the chrooted environment, and maybe other bits of the original filesystem.

Most importantly, "How much code is this going to take?" Not much:

  1. A kernel module to turn file names into commands. Zero Install's might do it, or something running on LUFS or FUSE. For a given file, all it needs to know is what packaging system it's dealing with, and hence which scripts to use.
  2. For each packaging system you need a script to turn a file name into a package, and one to turn a package into a series of commands to install it, without user intervention (possibly with, if you're the owner of the /try hierarchy in question), in some sort of jail (chroot? fakeroot?). Neither of these will be more than a few lines. You also need a parser for repo specifications. It might be necessary to use a -type flag to try to disambiguate repo specifications. Finally, you need a "bare-bones install" script. This could be a little tricky for repos that are actually distros (as it's a bit like doing a bare-bones install of the distro) but still shouldn't be too hard.
  3. A single "installer" script that asks the user what they want to do, and sorts out PATH.

Dare I suggest <1000 lines of new code including support for apt, yum, rpm and portage? I think that's generous…

I'd emphasise, finally, that unlike most other schemes I can think of, this requires zero cooperation from existing packaging systems and the associated infrastructure.

Please do comment on these ideas.

Reuben Thomas, December 2004

Last updated 2006/12/12