* Profiles section.

This commit is contained in:
Eelco Dolstra 2004-11-01 12:02:44 +00:00
parent b05a596d61
commit cbe8de592d
3 changed files with 164 additions and 15 deletions

View file

@ -106,7 +106,7 @@ these files (and <filename>fetchurl.nix</filename> checks
them).</para></listitem>
<listitem><para>We should switch away from MD5, since it has been
cracked. We don't currently depend very much on the
more-or-less cracked. We don't currently depend very much on the
collision-resistance of MD5, but we will once we start sharing build
results between users.</para></listitem>

View file

@ -204,7 +204,7 @@ variables is to include the file
in your <filename>~/.bashrc</filename> (or similar), like this:</para>
<screen>
. <replaceable>prefix</replaceable>/etc/profile.d/nix.sh</screen>
source <replaceable>prefix</replaceable>/etc/profile.d/nix.sh</screen>
</sect1>

View file

@ -131,8 +131,8 @@ defined by some pretty much arbitrary rules regarding ordering of
version numbers (which generally do what you'd expect of them). To
just unconditionally replace Subversion with whatever version is in
the Nix expressions, use <parameter>-i</parameter> instead of
<parameter>-u</parameter> <parameter>-i</parameter> will
remove whatever version is already installed.</para>
<parameter>-u</parameter>; <parameter>-i</parameter> will remove
whatever version is already installed.</para>
<para>You can also upgrade all components for which there are newer
versions:
@ -142,7 +142,21 @@ $ nix-env -f nixpkgs-<replaceable>version</replaceable> -u '*'</screen>
</para>
<para>If you grow tired of specifying the Nix expressions using
<para>Sometimes it's useful to be able to ask what
<command>nix-env</command> would do, without actually doing it. For
instance, to find out what packages would be upgraded by
<literal>nix-env -u '*'</literal>, you can do
<screen>
$ nix-env ... -u '*' --dry-run
(dry run; not doing anything)
upgrading `libxslt-1.1.0' to `libxslt-1.1.10'
upgrading `graphviz-1.10' to `graphviz-1.12'
upgrading `coreutils-5.0' to `coreutils-5.2.1'</screen>
</para>
<para>If you grow bored of specifying the Nix expressions using
<parameter>-f</parameter> all the time, you can set a default
location:
@ -162,14 +176,30 @@ set.</para></footnote></para>
<sect1><title>Profiles</title>
<para>In Nix, operations such as upgrading or removing components
never overwrite or remove the files of those components, and they
don't even touch the user environments that point to them. Rather,
they cause a <emphasis>new</emphasis> user environment to be
constructed based on the old one. This is illustrated in Figure
bla.</para>
<para>Profiles and user environments are Nix's mechanism for
implementing the ability to allow differens users to have different
configurations, and to do atomic upgrades and rollbacks. To
understand how they work, it's useful to know a bit about how Nix
works. In Nix, components are stored in unique locations in the
<emphasis>Nix store</emphasis> (typically,
<filename>/nix/store</filename>). For instance, a particular version
of the Subversion component might be stored in a directory
<filename>/nix/store/eeeeaf42e56b...-subversion-0.32.1/</filename>,
while another version might be stored in
<filename>/nix/store/58823d558a6a...-subversion-0.34/</filename>. The
long hexadecimal numbers prefixed to the directory names are
cryptographic hashes<footnote><para>128 bit MD5 hashes, to be
precise.</para></footnote> of <emphasis>all</emphasis> inputs involved
in building the component — sources, dependencies, compiler flags, and
so on. So if two components differ in any way, they end up in
different locations in the file system, so they don't interfere with
each other. <xref linkend='fig-user-environments'
/><footnote><para>TODO: the figure isn't entirely up to date. It
should show multiple profiles and
<filename>~/.nix-profile</filename>.</para></footnote> shows a part of
a typical Nix store.</para>
<figure><title>User environments</title>
<figure id='fig-user-environments'><title>User environments</title>
<mediaobject>
<imageobject>
<imagedata fileref='figures/user-environments.png' format='PNG' />
@ -177,20 +207,139 @@ bla.</para>
</mediaobject>
</figure>
<para>Of course, you wouldn't want to type
<screen>
$ /nix/store/eeeeaf42e56b...-subversion-0.32.1/bin/svn</screen>
every time you want to run Subversion. Of course we could set up the
<envar>PATH</envar> environment variable to include the
<filename>bin</filename> directory of every component we want to use,
but this is not very convenient since changing <envar>PATH</envar>
doesn't take effect for already existing processes. The solution Nix
uses is to create directory trees of symlinks to
<emphasis>activated</emphasis> components. These are called
<emphasis>user environments</emphasis> and they are components
themselves (though automatically generated by
<command>nix-env</command>), so they too reside in the Nix store. For
instance, in <xref linkend='fig-user-environments' /> the user
environment <filename>/nix/store/068150f63831...-user-env</filename>
contains a symlink to just Subversion 0.32.1 (arrows in the figure
indicate symlinks). This would be what we would obtain if we had done
<screen>
$ nix-env -i subversion</screen>
on a set of Nix expressions that contained Subversion 0.32.1.</para>
<para>This doesn't in itself solve the problem, of course; you
wouldn't want to type
<filename>/nix/store/068150f63831...-user-env/bin/svn</filename>
either. Therefore there are symlinks outside of the store that point
to the user environments in the store; for instance, the symlinks
<filename>42</filename> and <filename>43</filename> in the example.
These are called <emphasis>generations</emphasis> since every time you
perform a <command>nix-env</command> operation, a new user environment
is generated based on the current one. For instance, generation 43
was created from generation 42 when we did
<screen>
$ nix-env -i subversion mozilla</screen>
on a set of Nix expressions that contained Mozilla and a new version
of Subversion.</para>
<para>Generations are grouped together into
<emphasis>profiles</emphasis> so that different users don't interfere
with each other if they don't want to. For example:
<screen>
$ ls -l /nix/var/nix/profiles/
...
lrwxrwxrwx 1 eelco ... default-42-link -> /nix/store/068150f63831...-user-env
lrwxrwxrwx 1 eelco ... default-43-link -> /nix/store/84c85f89ddbf...-user-env
lrwxrwxrwx 1 eelco ... default -> default-43-link</screen>
This shows a profile called <filename>default</filename>. The file
<filename>default</filename> itself is actually a symlink that point
to the current generation. When we do a <command>nix-env</command>
operation, a new user environment and generation link are created
based on the current one, and finally the <filename>default</filename>
symlink is made to point at the new generation. This last step is
atomic on Unix, which explains how we can do atomic upgrades. (Note
that the building/installing of new components doesn't interfere in
any way with old components, since they are stored in different
locations in the Nix store.)</para>
<para>If you find that you want to undo a <command>nix-env</command>
operation, you can just do
<screen>
$ nix-env --rollback</screen>
which will just make the current generation link point at the previous
link. E.g., <filename>default</filename> would be made to point at
<filename>default-42-link</filename>. You can also switch to a
specific generation:
<screen>
$ nix-env --switch-generation 43</screen>
which in this example would roll forward to generation 43 again. You
can also see all available generations:
<screen>
$ nix-env --list-generations</screen></para>
<para>Actually, there is another level of indirection not shown in the
figure above. You generally wouldn't have
<filename>/nix/var/nix/profiles/<replaceable>some-profile</replaceable>/bin</filename>
in your <envar>PATH</envar>. Rather, there is a symlink
<filename>~/.nix-profile</filename> that point to your current
profile. This means that you should put
<filename>~/.nix-profile/bin</filename> in your <envar>PATH</envar>
(and indeed, that's what the initialisation script
<filename>/nix/etc/profile.d/nix.sh</filename> does). This makes it
easier to switch to a different profile, which is exactly what the
command <command>nix-env --switch-profile</command> does:
<screen>
$ nix-env --switch-profile /nix/var/nix/profiles/my-profile
$ nix-env --switch-profile /nix/var/nix/profiles/default</screen>
These commands switch to the <filename>my-profile</filename> and
default profile, respectively. If the profile doesn't exist, it will
be created automatically. You should be careful about storing a
profile in another location that the <filename>profiles</filename>
directory, since otherwise it might not be used as a root to the
garbage collection (see section <xref linkend='sec-garbage-collection'
/>).</para>
<para>All <command>nix-env</command> operations work on the profile
pointed to by <command>~/.nix-profile</command>, but you can override
this on using the <option>--profile</option> option (abbreviation
<option>-p</option>):
<screen>
$ nix-env -p /nix/var/nix/profiles/other-profile -i subversion</screen>
This will <emphasis>not</emphasis> change the
<command>~/.nix-profile</command> symlink.</para>
</sect1>
<sect1><title>Garbage collection</title>
<sect1 id='sec-garbage-collection'><title>Garbage collection</title>
<para>Bla</para>
<para>TODO</para>
</sect1>
<sect1><title>Channels</title>
<para>Bla</para>
<para>TODO</para>
</sect1>