mirror of
https://github.com/NixOS/nix-pills
synced 2024-09-19 04:00:13 -04:00
commit
a566880956
|
@ -4,5 +4,385 @@
|
|||
version="5.0"
|
||||
xml:id="enter-environment">
|
||||
|
||||
<title>enter environment</title>
|
||||
<title>enter environment</title>
|
||||
|
||||
<para>
|
||||
Welcome to the third Nix pill. In the previous <link
|
||||
linkend="install-on-your-running-system">second pill</link> we have
|
||||
installed Nix on our running system. Now we can finally play with it a
|
||||
little, things also apply to NixOS users.
|
||||
</para>
|
||||
|
||||
<section>
|
||||
<title>Enter the environment</title>
|
||||
|
||||
<para>
|
||||
In the previous pill we created a nix user, so let's start by switching
|
||||
user with <literal>su - nix</literal>. If your
|
||||
<literal>~/.profile</literal> got evaluated, then your should now be able
|
||||
to run commands like <literal>nix-env</literal> and
|
||||
<literal>nix-store</literal>.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
If that's not the case:
|
||||
</para>
|
||||
|
||||
<screen><xi:include href="./03/source-nix.txt" parse="text" /></screen>
|
||||
|
||||
<para>
|
||||
I remind you, <literal>~/.nix-profile/etc</literal> points to the nix-1.7
|
||||
derivation. At this point, we are in our nix user profile.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>Install something</title>
|
||||
|
||||
<para>
|
||||
Finally something practical! Installation in the nix environment is an
|
||||
interesting process. Let's install nix-repl, a simple command line tool
|
||||
for playing with the Nix language. Yes, Nix is a <link xlink:href="http://nixos.org/nix/manual/#idm47361539226272">
|
||||
pure, lazy, functional language</link>, not only a set of tools to
|
||||
manage derivations.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Back to the installation:
|
||||
</para>
|
||||
|
||||
<screen><xi:include href="./03/install-repl.txt" parse="text" /></screen>
|
||||
|
||||
<para>
|
||||
Now you can run nix-repl. Things to notice:
|
||||
</para>
|
||||
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
We did install software as user, only for the nix user.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
It created a new user environment. That's a new generation of our
|
||||
nix user profile.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
The <link
|
||||
xlink:href="http://nixos.org/nix/manual/#sec-nix-env">nix-env</link>
|
||||
tool manages environments, profiles and their generations.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
We installed nix-repl by derivation name minus the version. I repeat:
|
||||
we did specify the <emphasis role="bold">derivation name</emphasis>
|
||||
(minus the version) to install.
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
|
||||
<para>
|
||||
We can list generations without walking through the /nix hierarchy:
|
||||
</para>
|
||||
|
||||
<screen><xi:include href="./03/list-generations.txt" parse="text" /></screen>
|
||||
|
||||
<para>
|
||||
List installed derivations:
|
||||
</para>
|
||||
|
||||
<screen><xi:include href="./03/list-installed-derivations.txt" parse="text" /></screen>
|
||||
|
||||
<para>
|
||||
So, where did nix-repl really get installed?
|
||||
<literal>which nix-repl</literal> is
|
||||
<literal>~/.nix-profile.bin.nix-repl</literal> which points to the store.
|
||||
We can also list the derivation paths with nix-env -q --out-path. So
|
||||
that's how those derivation paths are called: the
|
||||
<emphasis role="bold">output</emphasis> of a build.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>Path merging</title>
|
||||
|
||||
<para>
|
||||
At this point you sure have the necessity to run "man". Even if you
|
||||
already have man system-wide outside of the nix environment, you can
|
||||
install and use it within nix with <literal>nix-env -i man</literal>. As
|
||||
usual, a new generation will be created, and ~/.nix-profile will point to
|
||||
it.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Lets inspect the <link
|
||||
xlink:href="http://nixos.org/nix/manual/#sec-profiles">profile</link>
|
||||
a bit:
|
||||
</para>
|
||||
|
||||
<screen><xi:include href="./03/ls-nix-profile.txt" parse="text" /></screen>
|
||||
|
||||
<para>
|
||||
Now that's interesting. When only nix-1.7 was installed, bin/ was a
|
||||
symlink to nix-1.7. Now it's a real directory, no symlink.
|
||||
</para>
|
||||
|
||||
<screen><xi:include href="./03/ls-profile-bin.txt" parse="text" /></screen>
|
||||
|
||||
<para>
|
||||
All clear. nix-env merged the paths from the installed derivations.
|
||||
<literal>which man</literal> points to the nix profile, rather than the
|
||||
system man, because <literal>~/.nix-profile/bin</literal> is at the head
|
||||
of <literal>$PATH</literal>.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>Rollback / switch generation</title>
|
||||
|
||||
<para>
|
||||
The last command installed "man". We should be at generation #3, unless
|
||||
you changed something in the middle. Let's say we want to rollback to the
|
||||
old generation:
|
||||
</para>
|
||||
|
||||
<screen><xi:include href="./03/rollback.txt" parse="text" /></screen>
|
||||
|
||||
<para>
|
||||
Now <literal>nix-env -q</literal> does not list "man" anymore.
|
||||
<literal>ls -l `which man`</literal> should now be your system installed
|
||||
one.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Enough with the joke, let's go back to the last generation:
|
||||
</para>
|
||||
|
||||
<screen><xi:include href="./03/generation-3.txt" parse="text" /></screen>
|
||||
|
||||
<para>
|
||||
I invite you to read the manpage of nix-env. nix-env requires an operation
|
||||
to perform, then there are common options for all operations, and there
|
||||
are options specific to an operation.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
You can of course also <link
|
||||
xlink:href="http://nixos.org/nix/manual/#idm47361539520832">
|
||||
delete and upgrade packages</link>.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>Querying the store</title>
|
||||
|
||||
<para>
|
||||
So far we learned how to query and manipulate the environment. But all
|
||||
of the environment components point to the store.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
To query and manipulate the store, there's the
|
||||
<literal>nix-store</literal> command. We can do neat things, but we'll
|
||||
only see some queries for now.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Show direct runtime dependencies of nix-repl:
|
||||
</para>
|
||||
|
||||
<screen><xi:include href="./03/references.txt" parse="text" /></screen>
|
||||
|
||||
<para>
|
||||
The argument to nix-store can be anything as long as it points to the
|
||||
nix store. It will follow symlinks.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
It may not make sense for you right now, but let's print reverse
|
||||
dependencies of nix-repl:
|
||||
</para>
|
||||
|
||||
<screen><xi:include href="./03/referrers.txt" parse="text" /></screen>
|
||||
|
||||
<para>
|
||||
Did you expect it? Our environments depend upon nix-repl. Yes, the
|
||||
environments are in the store, and since there are symlinks to nix-repl,
|
||||
therefore the environment depends upon nix-repl
|
||||
</para>
|
||||
|
||||
<para>
|
||||
It lists two environments, generation 2 and generation 3.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The manifest.nix file contains metadata about the environment, such as
|
||||
which derivations are installed. So that nix-env can list them, upgrade
|
||||
or remove them. Guess what, the current manifest.nix can be found in
|
||||
<literal>~/.nix-profile/manifest.nix</literal>.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>Closures</title>
|
||||
|
||||
<para>
|
||||
The closures of a derivation is a list of all dependencies, recursively,
|
||||
down to the bare minimum necessary to use that derivation.
|
||||
</para>
|
||||
|
||||
<screen><xi:include href="./03/nix-store.txt" parse="text" /></screen>
|
||||
|
||||
<para>
|
||||
Copying all those derivations to the nix store of another machine makes
|
||||
you able to run "man" out of the box on that other machine. That's the
|
||||
base of nix deployment, you can already foresee the potential when
|
||||
deploying software in the cloud (hint:
|
||||
<literal>nix-copy-closures</literal> and
|
||||
<literal>nix-store --export</literal>).
|
||||
</para>
|
||||
|
||||
<para>
|
||||
A nicer view of the closure:
|
||||
</para>
|
||||
|
||||
<screen><xi:include href="./03/nix-store-tree.txt" parse="text" /></screen>
|
||||
|
||||
<para>
|
||||
With the above command, you can know exactly why a
|
||||
<emphasis role="bold">runtime</emphasis> dependency, being it direct or
|
||||
indirect, has been picked for a given derivation.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Same applies to environments of course. As an exercise run
|
||||
<literal>nix-store -qR --tree ~/.nix-profile</literal>, see that the
|
||||
first children are direct dependencies of the user environment:
|
||||
the installed derivations, and the manifest.nix.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>Dependency resolution</title>
|
||||
|
||||
<para>
|
||||
There isn't anything like apt which solves a SAT problem in order to
|
||||
satisfy dependencies with lower and upper bounds on versions. Because
|
||||
there's no need. A derivation X depends on derivation Y, always.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>Fancy disrupt</title>
|
||||
|
||||
<screen><xi:include href="./03/uninstall-all.txt" parse="text" /></screen>
|
||||
|
||||
<para>
|
||||
Ops, that uninstalled all derivations from the environment, including
|
||||
nix. We are not able to run nix-env, what now?
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Environments are a convenience for the user, but Nix is still there, in
|
||||
the store!
|
||||
</para>
|
||||
|
||||
<para>
|
||||
First pick one nix-1.7 derivation:
|
||||
<literal>ls /nix/store/*nix-1.7</literal>, say
|
||||
/nix/store/g21di262aql6xskx15z3qiw3zh3wmjlb-nix-1.7.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The first possibility is to rollback:
|
||||
</para>
|
||||
|
||||
<screen><xi:include href="./03/nix-env-rollback.txt" parse="text" /></screen>
|
||||
|
||||
<para>
|
||||
The second possibility is to install nix, thus creating a new generation:
|
||||
</para>
|
||||
|
||||
<screen><xi:include href="./03/install.txt" parse="text" /></screen>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>Channels</title>
|
||||
|
||||
<para>
|
||||
So where are we getting packages from? We said something already in
|
||||
<link linkend="install-on-your-running-system">pill 2</link>.
|
||||
There's a list of channels from which we get packages, usually we use a
|
||||
single channel. The tool to manage channels is
|
||||
<link xlink:href="http://nixos.org/nix/manual/#sec-nix-channel">nix-channel</link>.
|
||||
</para>
|
||||
|
||||
<screen><xi:include href="./03/channel-list.txt" parse="text" /></screen>
|
||||
|
||||
<para>
|
||||
That's basically the contents of <literal>~/.nix-channels</literal>.
|
||||
Note: <literal>~/.nix-channels</literal> is not a symlink to the
|
||||
nix store!
|
||||
</para>
|
||||
|
||||
<para>
|
||||
To update the channel run <literal>nix-channel --update</literal>.
|
||||
It will download the new nix expressions (descriptions of the packages),
|
||||
create a new generation of the channels profile and unpack under
|
||||
<literal>~/.nix-defexpr/channels</literal>.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
That's much similar to apt-get update.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>Conclusion</title>
|
||||
|
||||
<para>
|
||||
We learned how to query the user environment and to manipulate it by
|
||||
installing and uninstalling software. Upgrading software is as straight
|
||||
as it gets by reading
|
||||
<link xlink:href="http://nixos.org/nix/manual/#idm47361539520832">the manual</link>
|
||||
(<literal>nix-env -u '*'</literal> will upgrade all packages in the
|
||||
environment).
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Everytime we change the environment, a new generation gets created.
|
||||
Switching between generations is easy and immediate.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Then we queried the store. We inspected the dependencies and reverse
|
||||
dependencies of store paths.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
We still see symlinks to compose paths from the nix store, our lovely
|
||||
trick.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Quick analogy with programming languages. You have the heap with all the
|
||||
objects, that's the nix store. You have objects that point to other
|
||||
objects, those are the derivations. Will be this the right path?
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>Next pill</title>
|
||||
|
||||
<para>
|
||||
...we will learn the basics of the Nix language. The Nix language is used
|
||||
to describe how to build derivations, and it's the base for everything
|
||||
else including NixOS. Therefore it's very important to understand the
|
||||
syntax and the semantics.
|
||||
</para>
|
||||
</section>
|
||||
</chapter>
|
||||
|
|
2
pills/03/channel-list.txt
Normal file
2
pills/03/channel-list.txt
Normal file
|
@ -0,0 +1,2 @@
|
|||
$ nix-channel --list
|
||||
nixpkgs http://nixos.org/channels/nixpkgs-unstable
|
2
pills/03/generation-3.txt
Normal file
2
pills/03/generation-3.txt
Normal file
|
@ -0,0 +1,2 @@
|
|||
$ nix-env -G 3
|
||||
switching from generation 2 to 3
|
6
pills/03/install-repl.txt
Normal file
6
pills/03/install-repl.txt
Normal file
|
@ -0,0 +1,6 @@
|
|||
$ nix-env -i nix-repl
|
||||
installing `nix-repl-1.7-1734e8a'
|
||||
these paths will be fetched (18.61 MiB download, 69.53 MiB unpacked):
|
||||
[...]
|
||||
building path(s) `/nix/store/f01lfzbw7n0yzhsjd33xfj77li9raljv-user-environment'
|
||||
created 24 symlinks in user environment
|
1
pills/03/install.txt
Normal file
1
pills/03/install.txt
Normal file
|
@ -0,0 +1 @@
|
|||
$ /nix/store/g21di262aql6xskx15z3qiw3zh3wmjlb-nix-1.7/bin/nix-env -i /nix/store/g21di262aql6xskx15z3qiw3zh3wmjlb-nix-1.7
|
3
pills/03/list-generations.txt
Normal file
3
pills/03/list-generations.txt
Normal file
|
@ -0,0 +1,3 @@
|
|||
$ nix-env --list-generations
|
||||
1 2014-07-24 09:23:30
|
||||
2 2014-07-25 08:45:01 (current)
|
3
pills/03/list-installed-derivations.txt
Normal file
3
pills/03/list-installed-derivations.txt
Normal file
|
@ -0,0 +1,3 @@
|
|||
$ nix-env -q
|
||||
nix-1.7
|
||||
nix-repl-1.7-1734e8a
|
4
pills/03/ls-nix-profile.txt
Normal file
4
pills/03/ls-nix-profile.txt
Normal file
|
@ -0,0 +1,4 @@
|
|||
$ ls -l ~/.nix-profile/
|
||||
dr-xr-xr-x 2 nix nix 4096 Jan 1 1970 bin
|
||||
lrwxrwxrwx 1 nix nix 55 Jan 1 1970 etc -> /nix/store/clnpynyac3hx3a6z5lsy893p7b4rwnyf-nix-1.7/etc
|
||||
[...]
|
8
pills/03/ls-profile-bin.txt
Normal file
8
pills/03/ls-profile-bin.txt
Normal file
|
@ -0,0 +1,8 @@
|
|||
$ ls -l ~/.nix-profile/bin/
|
||||
[...]
|
||||
man -> /nix/store/83cn9ing5sc6644h50dqzzfxcs07r2jn-man-1.6g/bin/man
|
||||
[...]
|
||||
nix-env -> /nix/store/clnpynyac3hx3a6z5lsy893p7b4rwnyf-nix-1.7/bin/nix-env
|
||||
[...]
|
||||
nix-repl -> /nix/store/0fcl92chxbbs8axb994rg12vxddg1ivs-nix-repl-1.7-1734e8a/bin/nix-repl
|
||||
[...]
|
1
pills/03/nix-env-rollback.txt
Normal file
1
pills/03/nix-env-rollback.txt
Normal file
|
@ -0,0 +1 @@
|
|||
$ /nix/store/g21di262aql6xskx15z3qiw3zh3wmjlb-nix-1.7/bin/nix-env --rollback
|
2
pills/03/nix-store-tree.txt
Normal file
2
pills/03/nix-store-tree.txt
Normal file
|
@ -0,0 +1,2 @@
|
|||
$ nix-store -qR --tree `which man`
|
||||
[...]
|
2
pills/03/nix-store.txt
Normal file
2
pills/03/nix-store.txt
Normal file
|
@ -0,0 +1,2 @@
|
|||
$ nix-store -qR `which man`
|
||||
[...]
|
6
pills/03/references.txt
Normal file
6
pills/03/references.txt
Normal file
|
@ -0,0 +1,6 @@
|
|||
$ nix-store -q --references `which nix-repl`
|
||||
/nix/store/94n64qy99ja0vgbkf675nyk39g9b978n-glibc-2.19
|
||||
/nix/store/8jm0wksask7cpf85miyakihyfch1y21q-gcc-4.8.3
|
||||
/nix/store/25lg5iqy68k25hdv17yac72kcnwlh4lm-boehm-gc-7.2d
|
||||
/nix/store/g21di262aql6xskx15z3qiw3zh3wmjlb-nix-1.7
|
||||
/nix/store/jxs2k83npdin18ysnd104xm4sy29m8xp-readline-6.2
|
5
pills/03/referrers.txt
Normal file
5
pills/03/referrers.txt
Normal file
|
@ -0,0 +1,5 @@
|
|||
$ nix-store -q --referrers `which nix-repl`
|
||||
/nix/store/8rj57vahlndqwg4q095x5qvfa1g4rmvr-env-manifest.nix
|
||||
/nix/store/9c8ak2h7c6vbr9kqk8i2n96bwg55br7y-env-manifest.nix
|
||||
/nix/store/dr1y2saask2k4y2wrmxw443302pp02z2-user-environment
|
||||
/nix/store/f01lfzbw7n0yzhsjd33xfj77li9raljv-user-environment
|
2
pills/03/rollback.txt
Normal file
2
pills/03/rollback.txt
Normal file
|
@ -0,0 +1,2 @@
|
|||
$ nix-env --rollback
|
||||
switching from generation 3 to 2
|
1
pills/03/source-nix.txt
Normal file
1
pills/03/source-nix.txt
Normal file
|
@ -0,0 +1 @@
|
|||
$ source ~/.nix-profile/etc/profile.d/nix.sh
|
5
pills/03/uninstall-all.txt
Normal file
5
pills/03/uninstall-all.txt
Normal file
|
@ -0,0 +1,5 @@
|
|||
$ nix-env -e '*'
|
||||
uninstalling `man-1.6g'
|
||||
uninstalling `nix-repl-1.7-1734e8a'
|
||||
uninstalling `nix-1.7'
|
||||
[...]
|
Loading…
Reference in a new issue