* Overview of nix-env. Recommended reading. :-)
This commit is contained in:
parent
62d9b31d0a
commit
7b0e29b4dc
1 changed files with 220 additions and 4 deletions
|
@ -9,18 +9,234 @@
|
|||
<title>Basic package management</title>
|
||||
|
||||
<para>
|
||||
Let's start from the perspective of an end-user. Common operations at
|
||||
Let's start from the perspective of an end user. Common operations at
|
||||
this level are to install and remove packages, ask what packages are
|
||||
installed or available for installation, and so on.
|
||||
installed or available for installation, and so on. These are operations
|
||||
on the <emphasis>user environment</emphasis>: the set of packages that a
|
||||
user <quote>sees</quote>. In a command line Unix environment, this means
|
||||
the set of programs that are available through the
|
||||
<literal>PATH</literal> environment variable. (In other environments it
|
||||
might mean the set of programs available on the desktop, through the
|
||||
start menu, and so on.)
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The terms <quote>installation</quote> and <quote>uninstallation</quote>
|
||||
are used in this context to denote the act of adding or removing packages
|
||||
from the user environment. In Nix, these operations are dissociated from
|
||||
the physical copying or deleting of files. Installation requires that
|
||||
the files constituting the package are present, but they may be present
|
||||
beforehand. Likewise, uninstallation does not actually delete any files;
|
||||
this is done automatically by running a garbage collector.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
User environments are manipulated through the <command>nix-env</command>
|
||||
command. The query operation can be used to see what packages are
|
||||
currently installed.
|
||||
</para>
|
||||
|
||||
<screen>
|
||||
$ nix-env -q
|
||||
MozillaFirebird-0.7
|
||||
sylpheed-0.9.7
|
||||
pan-0.14.2</screen>
|
||||
|
||||
<para>
|
||||
(<option>-q</option> is actually short for <option>--query
|
||||
--installed</option>.) The package names are symbolic: they don't have
|
||||
any particular significance to Nix (as they shouldn't, since they are not
|
||||
unique—there can be many derivations with the same name). Note that
|
||||
these packages have many dependencies (e.g., Mozilla uses the
|
||||
<literal>gtk+</literal> package) but these have not been installed in the
|
||||
user environment, though they are present on the system. Generally,
|
||||
there is no need to install such packages; only packages containing
|
||||
programs should be installed.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
To install packages, a <emphasis>Nix expression</emphasis> is required
|
||||
that tells Nix how to build that package. There is a <ulink
|
||||
url='https://svn.cs.uu.nl:12443/dist/trace/trace-nixpkgs-trunk.tar.bz2'>standard
|
||||
distribution of Nix expressions</ulink> for many common packages.
|
||||
url='https://svn.cs.uu.nl:12443/dist/trace/trace-nixpkgs-trunk.tar.bz2'>set
|
||||
of standard of Nix expressions</ulink> for many common packages.
|
||||
Assuming that you have downloaded and unpacked these, you can view the
|
||||
set of available packages:
|
||||
</para>
|
||||
|
||||
<screen>
|
||||
$ nix-env -qf pkgs/system/i686-suse-linux.nix
|
||||
gettext-0.12.1
|
||||
sylpheed-0.9.7
|
||||
aterm-2.0
|
||||
gtk+-1.2.10
|
||||
apache-httpd-2.0.48
|
||||
pan-0.14.2
|
||||
...</screen>
|
||||
|
||||
<para>
|
||||
The Nix expression in the file <filename>i686-suse-linux.nix</filename>
|
||||
yields the set of packages for a SuSE Linux system running on x86
|
||||
hardware. For other platforms, copy and modify this file for your
|
||||
platform as appropriate. [TODO: improve this]
|
||||
</para>
|
||||
|
||||
<para>
|
||||
It is also possible to see the <emphasis>status</emphasis> of available
|
||||
packages, i.e., whether they are installed into the user environment
|
||||
and/or present in the system:
|
||||
</para>
|
||||
|
||||
<screen>
|
||||
$ nix-env -qf pkgs/system/i686-suse-linux.nix
|
||||
-P gettext-0.12.1
|
||||
IP sylpheed-0.9.7
|
||||
-- aterm-2.0
|
||||
-P gtk+-1.2.10</screen>
|
||||
|
||||
<para>
|
||||
This reveals that the <literal>sylpheed</literal> package is already
|
||||
installed, or more precisely, that exactly the same instantiation of
|
||||
<literal>sylpheed</literal> is installed. This guarantees that the
|
||||
available package is exactly the same as the installed package with
|
||||
regard to sources, dependencies, build flags, and so on. Similarly, we
|
||||
see that the <literal>gettext</literal> and <literal>gtk+</literal>
|
||||
packages are present but not installed in the user environment, while the
|
||||
<literal>aterm</literal> package is not installed or present at all (so,
|
||||
if we were to install it, it would have to be built or downloaded first).
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The install operation is used install available packages from a Nix
|
||||
environment. To install the <literal>pan</literal> package (a
|
||||
newsreader), you would do:
|
||||
</para>
|
||||
|
||||
<screen>
|
||||
$ nix-env -i pkgs/system/i686-suse-linux.nix pan-0.14.2</screen>
|
||||
|
||||
<para>
|
||||
Since installation may take a long time, depending on whether any
|
||||
packages need to be built or downloaded, it's a good idea to make
|
||||
<command>nix-env</command> run verbosely by using the <option>-v</option>
|
||||
(<option>--verbose</option>) option. This option may be repeated to
|
||||
increase the level of verbosity. A good value is 3
|
||||
(<option>-vvv</option>).
|
||||
</para>
|
||||
|
||||
<para>
|
||||
In fact, if you run this command verbosely you will observe that Nix
|
||||
starts to build many packages, including large and fundamental ones such
|
||||
as <literal>glibc</literal> and <literal>gcc</literal>. I.e., you are
|
||||
performing a source installation. This is generally undesirable, since
|
||||
installation from sources may require large amounts of disk and CPU
|
||||
resources. Therefore a <quote>binary</quote> installation is generally
|
||||
preferable.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Rather than provide different mechanisms to create and perform
|
||||
the installation of binary packages, Nix supports binary deployment
|
||||
<emphasis>transparently</emphasis> through a generic mechanism of
|
||||
<emphasis>substitute expressions</emphasis>. If an request is made to
|
||||
build some Nix expression, Nix will first try to build any substitutes
|
||||
for that expression. These substitutes presumably perform an identical
|
||||
build operation with respect to the result, but require less resources.
|
||||
For instance, a substitute that downloads a pre-built package from the
|
||||
network requires less CPU and disk resources, and possibly less time.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Nix's use of cryptographic hashes makes this entirely safe. It is not
|
||||
possible, for instance, to accidentally substitute a build of some
|
||||
package for a Solaris or Windows system for a build on a SuSE/x86 system.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
While the substitute mechanism is a generic mechanism, Nix provides two
|
||||
standard tools called <command>nix-push</command> and
|
||||
<command>nix-push</command> that maintain and use a shared cache of
|
||||
prebuilt derivations on some network site (reachable through HTTP). If
|
||||
you attempt to install some package that someone else has previously
|
||||
built and <quote>pushed</quote> into the cache, and you have done a
|
||||
<quote>pull</quote> to register substitutes that download these prebuilt
|
||||
packages, then the installation will automatically use these.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
For example, to pull from our <ulink
|
||||
url='http://losser.st-lab.cs.uu.nl/~eelco/nix-dist/'>cache</ulink> of
|
||||
prebuilt packages (at the time of writing, for SuSE Linux/x86), use the
|
||||
following command:
|
||||
</para>
|
||||
|
||||
<screen>
|
||||
$ nix-pull http://losser.st-lab.cs.uu.nl/~eelco/nix-dist/
|
||||
obtaining list of Nix archives at http://losser.st-lab.cs.uu.nl/~eelco/nix-dist...
|
||||
...</screen>
|
||||
|
||||
<para>
|
||||
If <command>nix-pull</command> is run without any arguments, it will pull
|
||||
from the URLs specified in the file
|
||||
<filename><replaceable>prefix</replaceable>/etc/nix/prebuilts.conf</filename>.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Assuming that the <literal>pan</literal> installation produced no errors,
|
||||
it can be used immediately, that is, it now appears in a directory in the
|
||||
<literal>PATH</literal> environment variable. Specifically,
|
||||
<literal>PATH</literal> includes the entry
|
||||
<filename><replaceable>prefix</replaceable>/var/nix/links/current/bin</filename>,
|
||||
where
|
||||
<filename><replaceable>prefix</replaceable>/var/nix/links/current</filename>
|
||||
is just a symlink to the current user environment:
|
||||
</para>
|
||||
|
||||
<screen>
|
||||
$ ls -l /nix/var/nix/links/
|
||||
...
|
||||
lrwxrwxrwx 1 eelco ... 15 -> /nix/store/1871...12b0-user-environment
|
||||
lrwxrwxrwx 1 eelco ... 16 -> /nix/store/59ba...df6b-user-environment
|
||||
lrwxrwxrwx 1 eelco ... current -> /nix/var/nix/links/16</screen>
|
||||
|
||||
<para>
|
||||
That is, <filename>current</filename> in this example is a link to
|
||||
<filename>16</filename>, which is the current user environment. Before
|
||||
the installation, it pointed to <filename>15</filename>. Note that this
|
||||
means that you can atomically roll-back to the previous user environment
|
||||
by pointing the symlink <filename>current</filename> at
|
||||
<filename>15</filename> again. This also shows that operations such as
|
||||
installation are atomic in the Nix system: any arbitrarily complex
|
||||
set of installation, uninstallation, or upgrade actions eventually boil
|
||||
down to the single operation of pointing a symlink somewhere else (which
|
||||
can be implemented atomically in Unix).
|
||||
</para>
|
||||
|
||||
<para>
|
||||
What's in a user environment? It's just a set of symlinks to the files
|
||||
that constitute the installed packages. For instance:
|
||||
</para>
|
||||
|
||||
<screen>
|
||||
$ ls -l /nix/var/nix/links/16/bin
|
||||
lrwxrwxrwx 1 eelco ... MozillaFirebird -> /nix/store/35f8...4ae6-MozillaFirebird-0.7/bin/MozillaFirebird
|
||||
lrwxrwxrwx 1 eelco ... svn -> /nix/store/3829...fb5d-subversion-0.32.1/bin/svn
|
||||
...</screen>
|
||||
|
||||
<para>
|
||||
Note that, e.g., <filename>svn</filename> =
|
||||
<filename>/nix/var/nix/links/current/bin/svn</filename> =
|
||||
<filename>/nix/var/nix/links/16/bin/svn</filename> =
|
||||
<filename>/nix/store/59ba...df6b-user-environment/bin/svn</filename> =
|
||||
<filename>/nix/store/3829...fb5d-subversion-0.32.1/bin/svn</filename>.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Naturally, packages can also be uninstalled:
|
||||
</para>
|
||||
|
||||
<screen>
|
||||
$ nix-env -u pan-0.14.2</screen>
|
||||
|
||||
</sect1>
|
||||
|
||||
</chapter>
|
||||
|
|
Loading…
Reference in a new issue