[Nix-dev] Re: [Zero-install-devel] Nix

Eelco Dolstra eelco at cs.uu.nl
Tue Apr 3 00:57:06 CEST 2007


Hi Thomas,

Thomas Leonard wrote:

> On 4/1/07, Eric Wasylishen <ericwa at users.sourceforge.net> wrote:
>> I just came across this today, and it sounds pretty cool, with many of
>> the same features as Zeroinstall.
>> http://nix.cs.uu.nl/about.html
> 
> I've added a link on the Links page, with a short comparison:
> 
>  http://0install.net/links.html
> 
> I only had a short look, so it might be a bit inaccurate. I've CC'd
> the Nix list so they can complain if so ;-)
> 
> Hopefully they'll link to us too.

Thanks (also for your piece on OSNews), we should definitely add a links page :-)

> - Can users share packages safely? The manual says "A setuid
> installation should only by used if the users in the Nix group are
> mutually trusted, since any user in that group has the ability to
> change anything in the Nix store", which sounds like a "No".

The manual is out of date, it doesn't yet describe the multi-user support (which
NixOS uses) in the upcoming Nix 0.11.  In NixOS, any user can install from
source (i.e., from arbitrary Nix expressions) and you get sharing if multiple
users install from the same Nix expression (since the store paths would be the
same).  So we basically have multi-user Gentoo ;-)

We get security by making sure that users cannot influence the build result,
e.g., Alice starting a build of Firefox and then modifying some source or object
files halfway through the build.  This is done by letting a daemon perform the
build on behalf of the user under a temporary UID that's not being used by any
other build at the same time.  (So you can't start another build to mess with
the first.)

This is described in Section 3 of this paper:

http://www.cs.uu.nl/~eelco/pubs/secsharing-ase2005-final.pdf

The main result of that paper was actually how you can also do sharing of
binaries (the problem being that you have to trust that a binary really is the
result of a specific Nix expression), but that still hasn't been merged with the
trunk.  Right now in NixOS, only root can do a nix-pull to register the
availability of pre-built binaries, but once root has done so, all users
benefit.  (I.e., if a non-root user installs a package for which a binary is
known to be available, it will be used instead of building from source.)

The note on your links page that "the Nix hash is a hash of the inputs used to
build the package" is exactly true for the current Nix implementation.  The ASE
paper describes another model more like Zero Install where the hash is the hash
of the binary contents.  The tricky part is that you cannot know the hash in
advance but you do need to provide it as a --prefix, which the paper solves by
filling in a temporary "hash" and rewriting it later on with the actual hash
(and amazingly, this actually works ;-) ).

> - How are channels secured? I had a look at a MANIFEST file, but
> didn't see any kind of signature. I was never prompted about keys,
> etc.

They aren't secured right now - and they really should be, of course.  Actually,
I recently added some code for securely sharing binaries between machines
(necessary for our build farm), which uses OpenSSL for signing.  So the code is
mostly there, we should just have nix-pull check for a signature on the manifests.

> - Are packages namespaced? Dependencies seem to have short names (like
> "perl"). Presumably there's a central authority that assigns names?

There are actually two different kinds of "names".  There is the "name"
attribute of each packages (e.g., `name = "firefox-2.0.0.3"') which is what we
present to the user.  And then there are the *variable* (attribute) names in
files like pkgs/top-level/all-packages.nix, which really only live during the
evaluation of the Nix expression.  For example, all-packages.nix has two attributes

  utillinux = import ../os-specific/linux/util-linux {
    inherit fetchurl stdenv;
  };

  utillinuxStatic = import ../os-specific/linux/util-linux {
    inherit fetchurl;
    stdenv = makeStaticBinaries stdenv;
  };

Those two attributes both build a package named "util-linux-2.13-pre7", but one
is dynamically linked and the other statically.  The package name isn't unique,
but the attribute names are.  So you can refer uniquely to either variant:

  hotplug = import ../os-specific/linux/hotplug {
    inherit fetchurl stdenv ... module_init_tools;
  };

(Don't think we use hotplug anymore, now that I think about it...)

But the attribute names are really kind of irrelevant, just like variable names
in a programming language.  Instead of "utillinux" and "utillinuxStatic" we
could have named those attributes "a" and "b", it just wouldn't be very helpful
:-)  And since they're only relevant in the local lexical scope or to other Nix
expressions that import the attribute set, they in fact *don't* assume a
centrally-controlled repository.  For instance, multiple channels don't collide
with each other, and anybody can make a channel.

> They seem to have a working garbage collector. We need one of these ;-)
> 
>> It seems like the main difference between it and Zeroinstall is that
>> it's designed to manage the entire distribution, and as well has some
>> other things like configuration managment.

Well, Nix is really a kind of Make at a higher level, namely the level of
packages.  The original focus was plain package management, but Nix doesn't care
what those Nix expressions build.  So once you can build packages you can also
build configuration files and boot scripts and so on, and then you have a whole
OS distribution :-)

-- 
Eelco Dolstra | http://www.cs.uu.nl/~eelco





More information about the nix-dev mailing list