1
0
Fork 0
mirror of https://github.com/NixOS/nix-pills synced 2024-09-19 04:00:13 -04:00

Merge pull request #1 from ankhers/pill-3

Port pill #3
This commit is contained in:
Graham Christensen 2017-08-13 09:03:40 -04:00 committed by GitHub
commit a566880956
17 changed files with 434 additions and 1 deletions

View file

@ -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>

View file

@ -0,0 +1,2 @@
$ nix-channel --list
nixpkgs http://nixos.org/channels/nixpkgs-unstable

View file

@ -0,0 +1,2 @@
$ nix-env -G 3
switching from generation 2 to 3

View 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
View file

@ -0,0 +1 @@
$ /nix/store/g21di262aql6xskx15z3qiw3zh3wmjlb-nix-1.7/bin/nix-env -i /nix/store/g21di262aql6xskx15z3qiw3zh3wmjlb-nix-1.7

View file

@ -0,0 +1,3 @@
$ nix-env --list-generations
1 2014-07-24 09:23:30
2 2014-07-25 08:45:01 (current)

View file

@ -0,0 +1,3 @@
$ nix-env -q
nix-1.7
nix-repl-1.7-1734e8a

View 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
[...]

View 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
[...]

View file

@ -0,0 +1 @@
$ /nix/store/g21di262aql6xskx15z3qiw3zh3wmjlb-nix-1.7/bin/nix-env --rollback

View file

@ -0,0 +1,2 @@
$ nix-store -qR --tree `which man`
[...]

2
pills/03/nix-store.txt Normal file
View file

@ -0,0 +1,2 @@
$ nix-store -qR `which man`
[...]

6
pills/03/references.txt Normal file
View 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
View 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
View file

@ -0,0 +1,2 @@
$ nix-env --rollback
switching from generation 3 to 2

1
pills/03/source-nix.txt Normal file
View file

@ -0,0 +1 @@
$ source ~/.nix-profile/etc/profile.d/nix.sh

View file

@ -0,0 +1,5 @@
$ nix-env -e '*'
uninstalling `man-1.6g'
uninstalling `nix-repl-1.7-1734e8a'
uninstalling `nix-1.7'
[...]