606 lines
		
	
	
	
		
			24 KiB
		
	
	
	
		
			XML
		
	
	
	
	
	
			
		
		
	
	
			606 lines
		
	
	
	
		
			24 KiB
		
	
	
	
		
			XML
		
	
	
	
	
	
| <chapter xmlns="http://docbook.org/ns/docbook"
 | ||
|          xmlns:xlink="http://www.w3.org/1999/xlink"
 | ||
|          xml:id='chap-package-management'>
 | ||
| 
 | ||
| <title>Package Management</title>
 | ||
| 
 | ||
| 
 | ||
| <para>This chapter discusses how to do package management with Nix,
 | ||
| i.e., how to obtain, install, upgrade, and erase packages.  This is
 | ||
| the “user’s” perspective of the Nix system — people
 | ||
| who want to <emphasis>create</emphasis> packages should consult
 | ||
| <xref linkend='chap-writing-nix-expressions' />.</para>
 | ||
| 
 | ||
| 
 | ||
| <section><title>Basic package management</title>
 | ||
| 
 | ||
| <para>The main command for package management is <link
 | ||
| linkend="sec-nix-env"><command>nix-env</command></link>.  You can use
 | ||
| it to install, upgrade, and erase packages, and to query what
 | ||
| packages are installed or are available for installation.</para>
 | ||
| 
 | ||
| <para>In Nix, different users can have different “views”
 | ||
| on the set of installed applications.  That is, there might be lots of
 | ||
| applications present on the system (possibly in many different
 | ||
| versions), but users can have a specific selection of those active —
 | ||
| where “active” just means that it appears in a directory
 | ||
| in the user’s <envar>PATH</envar>.  Such a view on the set of
 | ||
| installed applications is called a <emphasis>user
 | ||
| environment</emphasis>, which is just a directory tree consisting of
 | ||
| symlinks to the files of the active applications.  </para>
 | ||
| 
 | ||
| <para>Components are installed from a set of <emphasis>Nix
 | ||
| expressions</emphasis> that tell Nix how to build those packages,
 | ||
| including, if necessary, their dependencies.  There is a collection of
 | ||
| Nix expressions called the Nix Package collection that contains
 | ||
| packages ranging from basic development stuff such as GCC and Glibc,
 | ||
| to end-user applications like Mozilla Firefox.  (Nix is however not
 | ||
| tied to the Nix Package collection; you could write your own Nix
 | ||
| expressions based on it, or completely new ones.)  You can download
 | ||
| the latest version from <link
 | ||
| xlink:href='http://nixos.org/nixpkgs/download.html' />.</para>
 | ||
| 
 | ||
| <para>Assuming that you have downloaded and unpacked a release of Nix
 | ||
| Packages, you can view the set of available packages in the release:
 | ||
| 
 | ||
| <screen>
 | ||
| $ nix-env -qaf nixpkgs-<replaceable>version</replaceable> '*'
 | ||
| ant-blackdown-1.4.2
 | ||
| aterm-2.2
 | ||
| bash-3.0
 | ||
| binutils-2.15
 | ||
| bison-1.875d
 | ||
| blackdown-1.4.2
 | ||
| bzip2-1.0.2
 | ||
| ...</screen>
 | ||
| 
 | ||
| where <literal>nixpkgs-<replaceable>version</replaceable></literal> is
 | ||
| where you’ve unpacked the release.  The flag <option>-q</option>
 | ||
| specifies a query operation; <option>-a</option> means that you want
 | ||
| to show the “available” (i.e., installable) packages, as opposed to
 | ||
| the installed packages; and <option>-f</option>
 | ||
| <filename>nixpkgs-<replaceable>version</replaceable></filename>
 | ||
| specifies the source of the packages.  The argument
 | ||
| <literal>'*'</literal> shows all installable packages. (The quotes are
 | ||
| necessary to prevent shell expansion.)  You can also select specific
 | ||
| packages by name:
 | ||
| 
 | ||
| <screen>
 | ||
| $ nix-env -qaf nixpkgs-<replaceable>version</replaceable> gcc
 | ||
| gcc-3.4.6
 | ||
| gcc-4.0.3
 | ||
| gcc-4.1.1</screen>
 | ||
| 
 | ||
| </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:
 | ||
| 
 | ||
| <screen>
 | ||
| $ nix-env -qasf nixpkgs-<replaceable>version</replaceable> '*'
 | ||
| ...
 | ||
| -PS bash-3.0
 | ||
| --S binutils-2.15
 | ||
| IPS bison-1.875d
 | ||
| ...</screen>
 | ||
| 
 | ||
| The first character (<literal>I</literal>) indicates whether the
 | ||
| package is installed in your current user environment.  The second
 | ||
| (<literal>P</literal>) indicates whether it is present on your system
 | ||
| (in which case installing it into your user environment would be a
 | ||
| very quick operation).  The last one (<literal>S</literal>) indicates
 | ||
| whether there is a so-called <emphasis>substitute</emphasis> for the
 | ||
| package, which is Nix’s mechanism for doing binary deployment.  It
 | ||
| just means that Nix knows that it can fetch a pre-built package from
 | ||
| somewhere (typically a network server) instead of building it
 | ||
| locally.</para>
 | ||
| 
 | ||
| <para>So now that we have a set of Nix expressions we can build the
 | ||
| packages contained in them.  This is done using <literal>nix-env
 | ||
| -i</literal>.  For instance,
 | ||
| 
 | ||
| <screen>
 | ||
| $ nix-env -f nixpkgs-<replaceable>version</replaceable> -i subversion</screen>
 | ||
| 
 | ||
| will install the package called <literal>subversion</literal> (which
 | ||
| is, of course, the <link
 | ||
| xlink:href='http://subversion.tigris.org/'>Subversion version
 | ||
| management system</link>).</para>
 | ||
| 
 | ||
| <para>When you do this for the first time, Nix will start building
 | ||
| Subversion and all its dependencies.  This will take quite a while —
 | ||
| typically an hour or two on modern machines.  Fortunately, there is a
 | ||
| faster way (so do a Ctrl-C on that install operation!): you just need
 | ||
| to tell Nix that pre-built binaries of all those packages are
 | ||
| available somewhere.  This is done using the
 | ||
| <command>nix-pull</command> command, which must be supplied with a URL
 | ||
| containing a <emphasis>manifest</emphasis> describing what binaries
 | ||
| are available.  This URL should correspond to the Nix Packages release
 | ||
| that you’re using.  For instance, if you obtained a release from <link
 | ||
| xlink:href='http://nixos.org/releases/nixpkgs/nixpkgs-0.12pre11712-4lrp7j8x'
 | ||
| />, then you should do:
 | ||
| 
 | ||
| <screen>
 | ||
| $ nix-pull http://nixos.org/releases/nixpkgs/nixpkgs-0.12pre11712-4lrp7j8x/MANIFEST</screen>
 | ||
| 
 | ||
| If you then issue the installation command, it should start
 | ||
| downloading binaries from <systemitem
 | ||
| class='fqdomainname'>nixos.org</systemitem>, instead of building
 | ||
| them from source.  This might still take a while since all
 | ||
| dependencies must be downloaded, but on a reasonably fast connection
 | ||
| such as an DSL line it’s on the order of a few minutes.</para>
 | ||
| 
 | ||
| <para>Naturally, packages can also be uninstalled:
 | ||
| 
 | ||
| <screen>
 | ||
| $ nix-env -e subversion</screen>
 | ||
| 
 | ||
| </para>
 | ||
| 
 | ||
| <para>Upgrading to a new version is just as easy.  If you have a new
 | ||
| release of Nix Packages, you can do:
 | ||
| 
 | ||
| <screen>
 | ||
| $ nix-env -f nixpkgs-<replaceable>version</replaceable> -u subversion</screen>
 | ||
| 
 | ||
| This will <emphasis>only</emphasis> upgrade Subversion if there is a
 | ||
| “newer” version in the new set of Nix expressions, as
 | ||
| defined by some pretty 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>
 | ||
| 
 | ||
| <para>You can also upgrade all packages for which there are newer
 | ||
| versions:
 | ||
| 
 | ||
| <screen>
 | ||
| $ nix-env -f nixpkgs-<replaceable>version</replaceable> -u '*'</screen>
 | ||
| 
 | ||
| </para>
 | ||
| 
 | ||
| <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:
 | ||
| 
 | ||
| <screen>
 | ||
| $ nix-env -I nixpkgs-<replaceable>version</replaceable></screen>
 | ||
| 
 | ||
| After this you can just say, for instance, <literal>nix-env -u
 | ||
| '*'</literal>.<footnote><para>Setting a default using
 | ||
| <parameter>-I</parameter> currently clashes with using Nix channels,
 | ||
| since <literal>nix-channel --update</literal> calls <literal>nix-env
 | ||
| -I</literal> to set the default to the Nix expressions it downloaded
 | ||
| from the channel, replacing whatever default you had
 | ||
| set.</para></footnote></para>
 | ||
| 
 | ||
| </section>
 | ||
| 
 | ||
| 
 | ||
| <section xml:id="sec-profiles"><title>Profiles</title>
 | ||
| 
 | ||
| <para>Profiles and user environments are Nix’s mechanism for
 | ||
| implementing the ability to allow different 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, packages are stored in unique locations in the
 | ||
| <emphasis>Nix store</emphasis> (typically,
 | ||
| <filename>/nix/store</filename>).  For instance, a particular version
 | ||
| of the Subversion package might be stored in a directory
 | ||
| <filename>/nix/store/dpmvp969yhdqs7lm2r1a3gng7pyq6vy4-subversion-1.1.3/</filename>,
 | ||
| while another version might be stored in
 | ||
| <filename>/nix/store/5mq2jcn36ldlmh93yj1n8s9c95pj7c5s-subversion-1.1.2</filename>.
 | ||
| The long strings prefixed to the directory names are cryptographic
 | ||
| hashes<footnote><para>160-bit truncations of SHA-256 hashes encoded in
 | ||
| a base-32 notation, to be precise.</para></footnote> of
 | ||
| <emphasis>all</emphasis> inputs involved in building the package —
 | ||
| sources, dependencies, compiler flags, and so on.  So if two
 | ||
| packages 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' /> shows a part of a typical Nix
 | ||
| store.</para>
 | ||
| 
 | ||
| <figure xml:id='fig-user-environments'><title>User environments</title>
 | ||
|   <mediaobject>
 | ||
|     <imageobject>
 | ||
|       <imagedata fileref='figures/user-environments.png' format='PNG' />
 | ||
|     </imageobject>
 | ||
|   </mediaobject>
 | ||
| </figure>
 | ||
| 
 | ||
| <para>Of course, you wouldn’t want to type
 | ||
| 
 | ||
| <screen>
 | ||
| $ /nix/store/dpmvp969yhdq...-subversion-1.1.3/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 package 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> packages.  These are called
 | ||
| <emphasis>user environments</emphasis> and they are packages
 | ||
| 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/5mq2jcn36ldl...-user-env</filename>
 | ||
| contains a symlink to just Subversion 1.1.2 (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 1.1.2.</para>
 | ||
| 
 | ||
| <para>This doesn’t in itself solve the problem, of course; you
 | ||
| wouldn’t want to type
 | ||
| <filename>/nix/store/0c1p5z4kda11...-user-env/bin/svn</filename>
 | ||
| either.  That’s why there are symlinks outside of the store that point
 | ||
| to the user environments in the store; for instance, the symlinks
 | ||
| <filename>default-42-link</filename> and
 | ||
| <filename>default-43-link</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/0c1p5z4kda11...-user-env
 | ||
| lrwxrwxrwx  1 eelco ... default-43-link -> /nix/store/3aw2pdyx2jfc...-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 points
 | ||
| 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 packages doesn’t interfere in
 | ||
| any way with old packages, 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 points 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.  You can do that using the
 | ||
| command <command>nix-env --switch-profile</command>:
 | ||
| 
 | ||
| <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 than the <filename>profiles</filename>
 | ||
| directory, since otherwise it might not be used as a root of the
 | ||
| garbage collector (see <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 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>
 | ||
| 
 | ||
| </section>
 | ||
| 
 | ||
| 
 | ||
| <section xml:id='sec-garbage-collection'><title>Garbage collection</title>
 | ||
| 
 | ||
| <para><command>nix-env</command> operations such as upgrades
 | ||
| (<option>-u</option>) and uninstall (<option>-e</option>) never
 | ||
| actually delete packages from the system.  All they do (as shown
 | ||
| above) is to create a new user environment that no longer contains
 | ||
| symlinks to the “deleted” packages.</para>
 | ||
| 
 | ||
| <para>Of course, since disk space is not infinite, unused packages
 | ||
| should be removed at some point.  You can do this by running the Nix
 | ||
| garbage collector.  It will remove from the Nix store any package
 | ||
| not used (directly or indirectly) by any generation of any
 | ||
| profile.</para>
 | ||
| 
 | ||
| <para>Note however that as long as old generations reference a
 | ||
| package, it will not be deleted.  After all, we wouldn’t be able to
 | ||
| do a rollback otherwise.  So in order for garbage collection to be
 | ||
| effective, you should also delete (some) old generations.  Of course,
 | ||
| this should only be done if you are certain that you will not need to
 | ||
| roll back.</para>
 | ||
| 
 | ||
| <para>To delete all old (non-current) generations of your current
 | ||
| profile:
 | ||
| 
 | ||
| <screen>
 | ||
| $ nix-env --delete-generations old</screen>
 | ||
| 
 | ||
| Instead of <literal>old</literal> you can also specify a list of
 | ||
| generations, e.g.,
 | ||
| 
 | ||
| <screen>
 | ||
| $ nix-env --delete-generations 10 11 14</screen>
 | ||
| 
 | ||
| </para>
 | ||
| 
 | ||
| <para>After removing appropriate old generations you can run the
 | ||
| garbage collector as follows:
 | ||
| 
 | ||
| <screen>
 | ||
| $ nix-store --gc</screen>
 | ||
| 
 | ||
| If you are feeling uncertain, you can also first view what files would
 | ||
| be deleted:
 | ||
| 
 | ||
| <screen>
 | ||
| $ nix-store --gc --print-dead</screen>
 | ||
| 
 | ||
| Likewise, the option <option>--print-live</option> will show the paths
 | ||
| that <emphasis>won’t</emphasis> be deleted.</para>
 | ||
| 
 | ||
| <para>There is also a convenient little utility
 | ||
| <command>nix-collect-garbage</command>, which when invoked with the
 | ||
| <option>-d</option> (<option>--delete-old</option>) switch deletes all
 | ||
| old generations of all profiles in
 | ||
| <filename>/nix/var/nix/profiles</filename>.  So
 | ||
| 
 | ||
| <screen>
 | ||
| $ nix-collect-garbage -d</screen>
 | ||
| 
 | ||
| is a quick and easy way to clean up your system.</para>
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| <section xml:id="ssec-gc-roots"><title>Garbage collector roots</title>
 | ||
| 
 | ||
| <para>The roots of the garbage collector are all store paths to which
 | ||
| there are symlinks in the directory
 | ||
| <filename><replaceable>prefix</replaceable>/nix/var/nix/gcroots</filename>.
 | ||
| For instance, the following command makes the path
 | ||
| <filename>/nix/store/d718ef...-foo</filename> a root of the collector:
 | ||
| 
 | ||
| <screen>
 | ||
| $ ln -s /nix/store/d718ef...-foo /nix/var/nix/gcroots/bar</screen>
 | ||
| 	
 | ||
| That is, after this command, the garbage collector will not remove
 | ||
| <filename>/nix/store/d718ef...-foo</filename> or any of its
 | ||
| dependencies.</para>
 | ||
| 
 | ||
| <para>Subdirectories of
 | ||
| <filename><replaceable>prefix</replaceable>/nix/var/nix/gcroots</filename>
 | ||
| are also searched for symlinks.  Symlinks to non-store paths are
 | ||
| followed and searched for roots, but symlinks to non-store paths
 | ||
| <emphasis>inside</emphasis> the paths reached in that way are not
 | ||
| followed to prevent infinite recursion.</para>
 | ||
| 
 | ||
| </section>
 | ||
| 
 | ||
| </section>
 | ||
| 
 | ||
| 
 | ||
| <section xml:id="sec-channels"><title>Channels</title>
 | ||
| 
 | ||
| <para>If you want to stay up to date with a set of packages, it’s not
 | ||
| very convenient to manually download the latest set of Nix expressions
 | ||
| for those packages, use <command>nix-pull</command> to register
 | ||
| pre-built binaries (if available), and upgrade using
 | ||
| <command>nix-env</command>.  Fortunately, there’s a better way:
 | ||
| <emphasis>Nix channels</emphasis>.</para>
 | ||
| 
 | ||
| <para>A Nix channel is just a URL that points to a place that contains
 | ||
| a set of Nix expressions and a manifest.  Using the command <link
 | ||
| linkend="sec-nix-channel"><command>nix-channel</command></link> you
 | ||
| can automatically stay up to date with whatever is available at that
 | ||
| URL.</para>
 | ||
| 
 | ||
| <para>You can “subscribe” to a channel using
 | ||
| <command>nix-channel --add</command>, e.g.,
 | ||
| 
 | ||
| <screen>
 | ||
| $ nix-channel --add http://nixos.org/releases/nixpkgs/channels/nixpkgs-unstable</screen>
 | ||
| 
 | ||
| subscribes you to a channel that always contains that latest version
 | ||
| of the Nix Packages collection.  (Instead of
 | ||
| <literal>nixpkgs-unstable</literal> you could also subscribe to
 | ||
| <literal>nixpkgs-stable</literal>, which should have a higher level of
 | ||
| stability, but right now is just outdated.)  Subscribing really just
 | ||
| means that the URL is added to the file
 | ||
| <filename>~/.nix-channels</filename>.  Right now there is no command
 | ||
| to “unsubscribe”; you should just edit that file manually
 | ||
| and delete the offending URL.</para>
 | ||
| 
 | ||
| <para>To obtain the latest Nix expressions available in a channel, do
 | ||
| 
 | ||
| <screen>
 | ||
| $ nix-channel --update</screen>
 | ||
| 
 | ||
| This downloads the Nix expressions in every channel (downloaded from
 | ||
| <literal><replaceable>url</replaceable>/nixexprs.tar.bz2</literal>)
 | ||
| and registers any available pre-built binaries in every channel
 | ||
| (by <command>nix-pull</command>ing
 | ||
| <literal><replaceable>url</replaceable>/MANIFEST</literal>).  It also
 | ||
| makes the union of each channel’s Nix expressions the default for
 | ||
| <command>nix-env</command> operations.  Consequently, you can then say
 | ||
| 
 | ||
| <screen>
 | ||
| $ nix-env -u '*'</screen>
 | ||
| 
 | ||
| to upgrade all packages in your profile to the latest versions
 | ||
| available in the subscribed channels.</para>
 | ||
| 
 | ||
| </section>
 | ||
| 
 | ||
| 
 | ||
| <section xml:id="sec-one-click"><title>One-click installs</title>
 | ||
| 
 | ||
| <para>Often, when you want to install a specific package (e.g., from
 | ||
| the <link
 | ||
| xlink:href="http://nixos.org/nixpkgs/">Nix
 | ||
| Packages collection</link>), subscribing to a channel is a bit
 | ||
| cumbersome.  And channels don’t help you at all if you want to install
 | ||
| an older version of a package than the one provided by the current
 | ||
| contents of the channel, or a package that has been removed from the
 | ||
| channel.  That’s when <emphasis>one-click installs</emphasis> come in
 | ||
| handy: you can just go to the web page that contains the package,
 | ||
| click on it, and it will be installed with all the necessary
 | ||
| dependencies.</para>
 | ||
| 
 | ||
| <para>For instance, you can go to <link
 | ||
| xlink:href="http://hydra.nixos.org/jobset/nixpkgs/trunk/channel/latest"
 | ||
| /> and click on any link for the individual packages for your
 | ||
| platform.  The first time you do this, your browser will ask what to
 | ||
| do with <literal>application/nix-package</literal> files.  You should
 | ||
| open them with <filename>/nix/bin/nix-install-package</filename>.
 | ||
| This will open a window that asks you to confirm that you want to
 | ||
| install the package.  When you answer <literal>Y</literal>, the
 | ||
| package and all its dependencies will be installed.  This is a binary
 | ||
| deployment mechanism — you get packages pre-compiled for the selected
 | ||
| platform type.</para>
 | ||
| 
 | ||
| <para>You can also install <literal>application/nix-package</literal>
 | ||
| files from the command line directly.  See <xref
 | ||
| linkend='sec-nix-install-package' /> for details.</para>
 | ||
| 
 | ||
| </section>
 | ||
| 
 | ||
| 
 | ||
| <section xml:id="sec-sharing-packages"><title>Sharing packages between machines</title>
 | ||
| 
 | ||
| <para>Sometimes you want to copy a package from one machine to
 | ||
| another.  Or, you want to install some packages and you know that
 | ||
| another machine already has some or all of those packages or their
 | ||
| dependencies.  In that case there are mechanisms to quickly copy
 | ||
| packages between machines.</para>
 | ||
| 
 | ||
| <para>The command <command
 | ||
| linkend="sec-nix-copy-closure">nix-copy-closure</command> copies a Nix
 | ||
| store path along with all its dependencies to or from another machine
 | ||
| via the SSH protocol.  It doesn’t copy store paths that are already
 | ||
| present on the target machine.  For example, the following command
 | ||
| copies Firefox with all its dependencies:
 | ||
| 
 | ||
| <screen>
 | ||
| $ nix-copy-closure --to alice@itchy.example.org $(type -p firefox)</screen>
 | ||
| 
 | ||
| See <xref linkend='sec-nix-copy-closure' /> for details.</para>
 | ||
| 
 | ||
| <para>With <command linkend='refsec-nix-store-export'>nix-store
 | ||
| --export</command> and <command
 | ||
| linkend='refsec-nix-store-import'>nix-store --import</command> you can
 | ||
| write the closure of a store path (that is, the path and all its
 | ||
| dependencies) to a file, and then unpack that file into another Nix
 | ||
| store.  For example,
 | ||
| 
 | ||
| <screen>
 | ||
| $ nix-store --export $(type -p firefox) > firefox.closure</screen>
 | ||
| 
 | ||
| writes the closure of Firefox to a file.  You can then copy this file
 | ||
| to another machine and install the closure:
 | ||
| 
 | ||
| <screen>
 | ||
| $ nix-store --import < firefox.closure</screen>
 | ||
| 
 | ||
| Any store paths in the closure that are already present in the target
 | ||
| store are ignored.  It is also possible to pipe the export into
 | ||
| another command, e.g. to copy and install a closure directly to/on
 | ||
| another machine:
 | ||
| 
 | ||
| <screen>
 | ||
| $ nix-store --export $(type -p firefox) | bzip2 | \
 | ||
|     ssh alice@itchy.example.org "bunzip2 | nix-store --import"</screen>
 | ||
| 
 | ||
| But note that <command>nix-copy-closure</command> is generally more
 | ||
| efficient in this example because it only copies paths that are not
 | ||
| already present in the target Nix store.</para>
 | ||
| 
 | ||
| <para>Finally, if you can mount the Nix store of a remote machine in
 | ||
| your local filesystem, Nix can copy paths from the remote Nix store to
 | ||
| the local Nix store <emphasis>on demand</emphasis>.  For instance,
 | ||
| suppose that you mount a remote machine containing a Nix store via
 | ||
| <command
 | ||
| xlink:href="http://fuse.sourceforge.net/sshfs.html">sshfs</command>:
 | ||
| 
 | ||
| <screen>
 | ||
| $ sshfs alice@itchy.example.org:/ /mnt</screen>
 | ||
| 
 | ||
| You should then set the <envar>NIX_OTHER_STORES</envar> environment
 | ||
| variable to tell Nix about this remote Nix store:
 | ||
| 
 | ||
| <screen>
 | ||
| $ export NIX_OTHER_STORES=/mnt/nix</screen>
 | ||
| 
 | ||
| Then if you do any Nix operation, e.g.
 | ||
| 
 | ||
| <screen>
 | ||
| $ nix-env -i firefox</screen>
 | ||
| 
 | ||
| and Nix has to build a path that it sees is already present in
 | ||
| <filename>/mnt/nix</filename>, then it will just copy from there
 | ||
| instead of building it from source.</para>
 | ||
|  
 | ||
| 
 | ||
| </section>
 | ||
| 
 | ||
| 
 | ||
| </chapter>
 |