Chunk NixOS manual

[Squashed commits to make git blame etc. more likely to work. -ED]

+65
nixos/doc/manual/administration/boot-problems.xml
···
···
+
<section xmlns="http://docbook.org/ns/docbook"
+
xmlns:xlink="http://www.w3.org/1999/xlink"
+
xmlns:xi="http://www.w3.org/2001/XInclude"
+
version="5.0"
+
xml:id="sec-boot-problems">
+
+
<title>Boot Problems</title>
+
+
<para>If NixOS fails to boot, there are a number of kernel command
+
line parameters that may help you to identify or fix the issue. You
+
can add these parameters in the GRUB boot menu by pressing “e” to
+
modify the selected boot entry and editing the line starting with
+
<literal>linux</literal>. The following are some useful kernel command
+
line parameters that are recognised by the NixOS boot scripts or by
+
systemd:
+
+
<variablelist>
+
+
<varlistentry><term><literal>boot.shell_on_fail</literal></term>
+
<listitem><para>Start a root shell if something goes wrong in
+
stage 1 of the boot process (the initial ramdisk). This is
+
disabled by default because there is no authentication for the
+
root shell.</para></listitem>
+
</varlistentry>
+
+
<varlistentry><term><literal>boot.debug1</literal></term>
+
<listitem><para>Start an interactive shell in stage 1 before
+
anything useful has been done. That is, no modules have been
+
loaded and no file systems have been mounted, except for
+
<filename>/proc</filename> and
+
<filename>/sys</filename>.</para></listitem>
+
</varlistentry>
+
+
<varlistentry><term><literal>boot.trace</literal></term>
+
<listitem><para>Print every shell command executed by the stage 1
+
and 2 boot scripts.</para></listitem>
+
</varlistentry>
+
+
<varlistentry><term><literal>single</literal></term>
+
<listitem><para>Boot into rescue mode (a.k.a. single user mode).
+
This will cause systemd to start nothing but the unit
+
<literal>rescue.target</literal>, which runs
+
<command>sulogin</command> to prompt for the root password and
+
start a root login shell. Exiting the shell causes the system to
+
continue with the normal boot process.</para></listitem>
+
</varlistentry>
+
+
<varlistentry><term><literal>systemd.log_level=debug systemd.log_target=console</literal></term>
+
<listitem><para>Make systemd very verbose and send log messages to
+
the console instead of the journal.</para></listitem>
+
</varlistentry>
+
+
</variablelist>
+
+
For more parameters recognised by systemd, see
+
<citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>.</para>
+
+
<para>If no login prompts or X11 login screens appear (e.g. due to
+
hanging dependencies), you can press Alt+ArrowUp. If you’re lucky,
+
this will start rescue mode (described above). (Also note that since
+
most units have a 90-second timeout before systemd gives up on them,
+
the <command>agetty</command> login prompts should appear eventually
+
unless something is very wrong.)</para>
+
+
</section>
+62
nixos/doc/manual/administration/cleaning-store.xml
···
···
+
<chapter xmlns="http://docbook.org/ns/docbook"
+
xmlns:xlink="http://www.w3.org/1999/xlink"
+
xmlns:xi="http://www.w3.org/2001/XInclude"
+
version="5.0"
+
xml:id="sec-nix-gc">
+
+
<title>Cleaning the Nix Store</title>
+
+
<para>Nix has a purely functional model, meaning that packages are
+
never upgraded in place. Instead new versions of packages end up in a
+
different location in the Nix store (<filename>/nix/store</filename>).
+
You should periodically run Nix’s <emphasis>garbage
+
collector</emphasis> to remove old, unreferenced packages. This is
+
easy:
+
+
<screen>
+
$ nix-collect-garbage
+
</screen>
+
+
Alternatively, you can use a systemd unit that does the same in the
+
background:
+
+
<screen>
+
$ systemctl start nix-gc.service
+
</screen>
+
+
You can tell NixOS in <filename>configuration.nix</filename> to run
+
this unit automatically at certain points in time, for instance, every
+
night at 03:15:
+
+
<programlisting>
+
nix.gc.automatic = true;
+
nix.gc.dates = "03:15";
+
</programlisting>
+
+
</para>
+
+
<para>The commands above do not remove garbage collector roots, such
+
as old system configurations. Thus they do not remove the ability to
+
roll back to previous configurations. The following command deletes
+
old roots, removing the ability to roll back to them:
+
<screen>
+
$ nix-collect-garbage -d
+
</screen>
+
You can also do this for specific profiles, e.g.
+
<screen>
+
$ nix-env -p /nix/var/nix/profiles/per-user/eelco/profile --delete-generations old
+
</screen>
+
Note that NixOS system configurations are stored in the profile
+
<filename>/nix/var/nix/profiles/system</filename>.</para>
+
+
<para>Another way to reclaim disk space (often as much as 40% of the
+
size of the Nix store) is to run Nix’s store optimiser, which seeks
+
out identical files in the store and replaces them with hard links to
+
a single copy.
+
<screen>
+
$ nix-store --optimise
+
</screen>
+
Since this command needs to read the entire Nix store, it can take
+
quite a while to finish.</para>
+
+
</chapter>
+50
nixos/doc/manual/administration/container-networking.xml
···
···
+
<section xmlns="http://docbook.org/ns/docbook"
+
xmlns:xlink="http://www.w3.org/1999/xlink"
+
xmlns:xi="http://www.w3.org/2001/XInclude"
+
version="5.0"
+
xml:id="sec-container-networking">
+
+
+
<title>Container Networking</title>
+
+
<para>When you create a container using <literal>nixos-container
+
create</literal>, it gets it own private IPv4 address in the range
+
<literal>10.233.0.0/16</literal>. You can get the container’s IPv4
+
address as follows:
+
+
<screen>
+
$ nixos-container show-ip foo
+
10.233.4.2
+
+
$ ping -c1 10.233.4.2
+
64 bytes from 10.233.4.2: icmp_seq=1 ttl=64 time=0.106 ms
+
</screen>
+
+
</para>
+
+
<para>Networking is implemented using a pair of virtual Ethernet
+
devices. The network interface in the container is called
+
<literal>eth0</literal>, while the matching interface in the host is
+
called <literal>ve-<replaceable>container-name</replaceable></literal>
+
(e.g., <literal>ve-foo</literal>). The container has its own network
+
namespace and the <literal>CAP_NET_ADMIN</literal> capability, so it
+
can perform arbitrary network configuration such as setting up
+
firewall rules, without affecting or having access to the host’s
+
network.</para>
+
+
<para>By default, containers cannot talk to the outside network. If
+
you want that, you should set up Network Address Translation (NAT)
+
rules on the host to rewrite container traffic to use your external
+
IP address. This can be accomplished using the following configuration
+
on the host:
+
+
<programlisting>
+
networking.nat.enable = true;
+
networking.nat.internalInterfaces = ["ve-+"];
+
networking.nat.externalInterface = "eth0";
+
</programlisting>
+
where <literal>eth0</literal> should be replaced with the desired
+
external interface. Note that <literal>ve-+</literal> is a wildcard
+
that matches all container interfaces.</para>
+
+
</section>
+34
nixos/doc/manual/administration/containers.xml
···
···
+
<chapter xmlns="http://docbook.org/ns/docbook"
+
xmlns:xlink="http://www.w3.org/1999/xlink"
+
xmlns:xi="http://www.w3.org/2001/XInclude"
+
version="5.0"
+
xml:id="ch-containers">
+
+
<title>Container Management</title>
+
+
<para>NixOS allows you to easily run other NixOS instances as
+
<emphasis>containers</emphasis>. Containers are a light-weight
+
approach to virtualisation that runs software in the container at the
+
same speed as in the host system. NixOS containers share the Nix store
+
of the host, making container creation very efficient.</para>
+
+
<warning><para>Currently, NixOS containers are not perfectly isolated
+
from the host system. This means that a user with root access to the
+
container can do things that affect the host. So you should not give
+
container root access to untrusted users.</para></warning>
+
+
<para>NixOS containers can be created in two ways: imperatively, using
+
the command <command>nixos-container</command>, and declaratively, by
+
specifying them in your <filename>configuration.nix</filename>. The
+
declarative approach implies that containers get upgraded along with
+
your host system when you run <command>nixos-rebuild</command>, which
+
is often not what you want. By contrast, in the imperative approach,
+
containers are configured and updated independently from the host
+
system.</para>
+
+
<xi:include href="imperative-containers.xml" />
+
<xi:include href="declarative-containers.xml" />
+
<xi:include href="container-networking.xml" />
+
+
</chapter>
+
+75
nixos/doc/manual/administration/control-groups.xml
···
···
+
<chapter xmlns="http://docbook.org/ns/docbook"
+
xmlns:xlink="http://www.w3.org/1999/xlink"
+
xmlns:xi="http://www.w3.org/2001/XInclude"
+
version="5.0"
+
xml:id="sec-cgroups">
+
+
<title>Control Groups</title>
+
+
<para>To keep track of the processes in a running system, systemd uses
+
<emphasis>control groups</emphasis> (cgroups). A control group is a
+
set of processes used to allocate resources such as CPU, memory or I/O
+
bandwidth. There can be multiple control group hierarchies, allowing
+
each kind of resource to be managed independently.</para>
+
+
<para>The command <command>systemd-cgls</command> lists all control
+
groups in the <literal>systemd</literal> hierarchy, which is what
+
systemd uses to keep track of the processes belonging to each service
+
or user session:
+
+
<screen>
+
$ systemd-cgls
+
├─user
+
│ └─eelco
+
│ └─c1
+
│ ├─ 2567 -:0
+
│ ├─ 2682 kdeinit4: kdeinit4 Running...
+
│ ├─ <replaceable>...</replaceable>
+
│ └─10851 sh -c less -R
+
└─system
+
├─httpd.service
+
│ ├─2444 httpd -f /nix/store/3pyacby5cpr55a03qwbnndizpciwq161-httpd.conf -DNO_DETACH
+
│ └─<replaceable>...</replaceable>
+
├─dhcpcd.service
+
│ └─2376 dhcpcd --config /nix/store/f8dif8dsi2yaa70n03xir8r653776ka6-dhcpcd.conf
+
└─ <replaceable>...</replaceable>
+
</screen>
+
+
Similarly, <command>systemd-cgls cpu</command> shows the cgroups in
+
the CPU hierarchy, which allows per-cgroup CPU scheduling priorities.
+
By default, every systemd service gets its own CPU cgroup, while all
+
user sessions are in the top-level CPU cgroup. This ensures, for
+
instance, that a thousand run-away processes in the
+
<literal>httpd.service</literal> cgroup cannot starve the CPU for one
+
process in the <literal>postgresql.service</literal> cgroup. (By
+
contrast, it they were in the same cgroup, then the PostgreSQL process
+
would get 1/1001 of the cgroup’s CPU time.) You can limit a service’s
+
CPU share in <filename>configuration.nix</filename>:
+
+
<programlisting>
+
systemd.services.httpd.serviceConfig.CPUShares = 512;
+
</programlisting>
+
+
By default, every cgroup has 1024 CPU shares, so this will halve the
+
CPU allocation of the <literal>httpd.service</literal> cgroup.</para>
+
+
<para>There also is a <literal>memory</literal> hierarchy that
+
controls memory allocation limits; by default, all processes are in
+
the top-level cgroup, so any service or session can exhaust all
+
available memory. Per-cgroup memory limits can be specified in
+
<filename>configuration.nix</filename>; for instance, to limit
+
<literal>httpd.service</literal> to 512 MiB of RAM (excluding swap)
+
and 640 MiB of RAM (including swap):
+
+
<programlisting>
+
systemd.services.httpd.serviceConfig.MemoryLimit = "512M";
+
systemd.services.httpd.serviceConfig.ControlGroupAttribute = [ "memory.memsw.limit_in_bytes 640M" ];
+
</programlisting>
+
+
</para>
+
+
<para>The command <command>systemd-cgtop</command> shows a
+
continuously updated list of all cgroups with their CPU and memory
+
usage.</para>
+
+
</chapter>
+52
nixos/doc/manual/administration/declarative-containers.xml
···
···
+
<section xmlns="http://docbook.org/ns/docbook"
+
xmlns:xlink="http://www.w3.org/1999/xlink"
+
xmlns:xi="http://www.w3.org/2001/XInclude"
+
version="5.0"
+
xml:id="sec-declarative-containers">
+
+
<title>Declarative Container Specification</title>
+
+
<para>You can also specify containers and their configuration in the
+
host’s <filename>configuration.nix</filename>. For example, the
+
following specifies that there shall be a container named
+
<literal>database</literal> running PostgreSQL:
+
+
<programlisting>
+
containers.database =
+
{ config =
+
{ config, pkgs, ... }:
+
{ services.postgresql.enable = true;
+
services.postgresql.package = pkgs.postgresql92;
+
};
+
};
+
</programlisting>
+
+
If you run <literal>nixos-rebuild switch</literal>, the container will
+
be built and started. If the container was already running, it will be
+
updated in place, without rebooting.</para>
+
+
<para>By default, declarative containers share the network namespace
+
of the host, meaning that they can listen on (privileged)
+
ports. However, they cannot change the network configuration. You can
+
give a container its own network as follows:
+
+
<programlisting>
+
containers.database =
+
{ privateNetwork = true;
+
hostAddress = "192.168.100.10";
+
localAddress = "192.168.100.11";
+
};
+
</programlisting>
+
+
This gives the container a private virtual Ethernet interface with IP
+
address <literal>192.168.100.11</literal>, which is hooked up to a
+
virtual Ethernet interface on the host with IP address
+
<literal>192.168.100.10</literal>. (See the next section for details
+
on container networking.)</para>
+
+
<para>To disable the container, just remove it from
+
<filename>configuration.nix</filename> and run <literal>nixos-rebuild
+
switch</literal>. Note that this will not delete the root directory of
+
the container in <literal>/var/lib/containers</literal>.</para>
+
+
</section>
+124
nixos/doc/manual/administration/imperative-containers.xml
···
···
+
<section xmlns="http://docbook.org/ns/docbook"
+
xmlns:xlink="http://www.w3.org/1999/xlink"
+
xmlns:xi="http://www.w3.org/2001/XInclude"
+
version="5.0"
+
xml:id="sec-imperative-containers">
+
+
<title>Imperative Container Management</title>
+
+
<para>We’ll cover imperative container management using
+
<command>nixos-container</command> first. You create a container with
+
identifier <literal>foo</literal> as follows:
+
+
<screen>
+
$ nixos-container create foo
+
</screen>
+
+
This creates the container’s root directory in
+
<filename>/var/lib/containers/foo</filename> and a small configuration
+
file in <filename>/etc/containers/foo.conf</filename>. It also builds
+
the container’s initial system configuration and stores it in
+
<filename>/nix/var/nix/profiles/per-container/foo/system</filename>. You
+
can modify the initial configuration of the container on the command
+
line. For instance, to create a container that has
+
<command>sshd</command> running, with the given public key for
+
<literal>root</literal>:
+
+
<screen>
+
$ nixos-container create foo --config 'services.openssh.enable = true; \
+
users.extraUsers.root.openssh.authorizedKeys.keys = ["ssh-dss AAAAB3N…"];'
+
</screen>
+
+
</para>
+
+
<para>Creating a container does not start it. To start the container,
+
run:
+
+
<screen>
+
$ nixos-container start foo
+
</screen>
+
+
This command will return as soon as the container has booted and has
+
reached <literal>multi-user.target</literal>. On the host, the
+
container runs within a systemd unit called
+
<literal>container@<replaceable>container-name</replaceable>.service</literal>.
+
Thus, if something went wrong, you can get status info using
+
<command>systemctl</command>:
+
+
<screen>
+
$ systemctl status container@foo
+
</screen>
+
+
</para>
+
+
<para>If the container has started succesfully, you can log in as
+
root using the <command>root-login</command> operation:
+
+
<screen>
+
$ nixos-container root-login foo
+
[root@foo:~]#
+
</screen>
+
+
Note that only root on the host can do this (since there is no
+
authentication). You can also get a regular login prompt using the
+
<command>login</command> operation, which is available to all users on
+
the host:
+
+
<screen>
+
$ nixos-container login foo
+
foo login: alice
+
Password: ***
+
</screen>
+
+
With <command>nixos-container run</command>, you can execute arbitrary
+
commands in the container:
+
+
<screen>
+
$ nixos-container run foo -- uname -a
+
Linux foo 3.4.82 #1-NixOS SMP Thu Mar 20 14:44:05 UTC 2014 x86_64 GNU/Linux
+
</screen>
+
+
</para>
+
+
<para>There are several ways to change the configuration of the
+
container. First, on the host, you can edit
+
<literal>/var/lib/container/<replaceable>name</replaceable>/etc/nixos/configuration.nix</literal>,
+
and run
+
+
<screen>
+
$ nixos-container update foo
+
</screen>
+
+
This will build and activate the new configuration. You can also
+
specify a new configuration on the command line:
+
+
<screen>
+
$ nixos-container update foo --config 'services.httpd.enable = true; \
+
services.httpd.adminAddr = "foo@example.org";'
+
+
$ curl http://$(nixos-container show-ip foo)/
+
&lt;!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">…
+
</screen>
+
+
However, note that this will overwrite the container’s
+
<filename>/etc/nixos/configuration.nix</filename>.</para>
+
+
<para>Alternatively, you can change the configuration from within the
+
container itself by running <command>nixos-rebuild switch</command>
+
inside the container. Note that the container by default does not have
+
a copy of the NixOS channel, so you should run <command>nix-channel
+
--update</command> first.</para>
+
+
<para>Containers can be stopped and started using
+
<literal>nixos-container stop</literal> and <literal>nixos-container
+
start</literal>, respectively, or by using
+
<command>systemctl</command> on the container’s service unit. To
+
destroy a container, including its file system, do
+
+
<screen>
+
$ nixos-container destroy foo
+
</screen>
+
+
</para>
+
+
</section>
+52
nixos/doc/manual/administration/logging.xml
···
···
+
<chapter xmlns="http://docbook.org/ns/docbook"
+
xmlns:xlink="http://www.w3.org/1999/xlink"
+
xmlns:xi="http://www.w3.org/2001/XInclude"
+
version="5.0"
+
xml:id="sec-logging">
+
+
<title>Logging</title>
+
+
<para>System-wide logging is provided by systemd’s
+
<emphasis>journal</emphasis>, which subsumes traditional logging
+
daemons such as syslogd and klogd. Log entries are kept in binary
+
files in <filename>/var/log/journal/</filename>. The command
+
<literal>journalctl</literal> allows you to see the contents of the
+
journal. For example,
+
+
<screen>
+
$ journalctl -b
+
</screen>
+
+
shows all journal entries since the last reboot. (The output of
+
<command>journalctl</command> is piped into <command>less</command> by
+
default.) You can use various options and match operators to restrict
+
output to messages of interest. For instance, to get all messages
+
from PostgreSQL:
+
+
<screen>
+
$ journalctl -u postgresql.service
+
-- Logs begin at Mon, 2013-01-07 13:28:01 CET, end at Tue, 2013-01-08 01:09:57 CET. --
+
...
+
Jan 07 15:44:14 hagbard postgres[2681]: [2-1] LOG: database system is shut down
+
-- Reboot --
+
Jan 07 15:45:10 hagbard postgres[2532]: [1-1] LOG: database system was shut down at 2013-01-07 15:44:14 CET
+
Jan 07 15:45:13 hagbard postgres[2500]: [1-1] LOG: database system is ready to accept connections
+
</screen>
+
+
Or to get all messages since the last reboot that have at least a
+
“critical” severity level:
+
+
<screen>
+
$ journalctl -b -p crit
+
Dec 17 21:08:06 mandark sudo[3673]: pam_unix(sudo:auth): auth could not identify password for [alice]
+
Dec 29 01:30:22 mandark kernel[6131]: [1053513.909444] CPU6: Core temperature above threshold, cpu clock throttled (total events = 1)
+
</screen>
+
+
</para>
+
+
<para>The system journal is readable by root and by users in the
+
<literal>wheel</literal> and <literal>systemd-journal</literal>
+
groups. All users have a private journal that can be read using
+
<command>journalctl</command>.</para>
+
+
</chapter>
+18
nixos/doc/manual/administration/maintenance-mode.xml
···
···
+
<section xmlns="http://docbook.org/ns/docbook"
+
xmlns:xlink="http://www.w3.org/1999/xlink"
+
xmlns:xi="http://www.w3.org/2001/XInclude"
+
version="5.0"
+
xml:id="sec-maintenance-mode">
+
+
<title>Maintenance Mode</title>
+
+
<para>You can enter rescue mode by running:
+
+
<screen>
+
$ systemctl rescue</screen>
+
+
This will eventually give you a single-user root shell. Systemd will
+
stop (almost) all system services. To get out of maintenance mode,
+
just exit from the rescue shell.</para>
+
+
</section>
+33
nixos/doc/manual/administration/network-problems.xml
···
···
+
<section xmlns="http://docbook.org/ns/docbook"
+
xmlns:xlink="http://www.w3.org/1999/xlink"
+
xmlns:xi="http://www.w3.org/2001/XInclude"
+
version="5.0"
+
xml:id="sec-nix-network-issues">
+
+
<title>Network Problems</title>
+
+
<para>Nix uses a so-called <emphasis>binary cache</emphasis> to
+
optimise building a package from source into downloading it as a
+
pre-built binary. That is, whenever a command like
+
<command>nixos-rebuild</command> needs a path in the Nix store, Nix
+
will try to download that path from the Internet rather than build it
+
from source. The default binary cache is
+
<uri>http://cache.nixos.org/</uri>. If this cache is unreachable, Nix
+
operations may take a long time due to HTTP connection timeouts. You
+
can disable the use of the binary cache by adding <option>--option
+
use-binary-caches false</option>, e.g.
+
+
<screen>
+
$ nixos-rebuild switch --option use-binary-caches false
+
</screen>
+
+
If you have an alternative binary cache at your disposal, you can use
+
it instead:
+
+
<screen>
+
$ nixos-rebuild switch --option binary-caches http://my-cache.example.org/
+
</screen>
+
+
</para>
+
+
</section>
+44
nixos/doc/manual/administration/rebooting.xml
···
···
+
<chapter xmlns="http://docbook.org/ns/docbook"
+
xmlns:xlink="http://www.w3.org/1999/xlink"
+
xmlns:xi="http://www.w3.org/2001/XInclude"
+
version="5.0"
+
xml:id="sec-rebooting">
+
+
<title>Rebooting and Shutting Down</title>
+
+
<para>The system can be shut down (and automatically powered off) by
+
doing:
+
+
<screen>
+
$ shutdown
+
</screen>
+
+
This is equivalent to running <command>systemctl
+
poweroff</command>.</para>
+
+
<para>To reboot the system, run
+
+
<screen>
+
$ reboot
+
</screen>
+
+
which is equivalent to <command>systemctl reboot</command>.
+
Alternatively, you can quickly reboot the system using
+
<literal>kexec</literal>, which bypasses the BIOS by directly loading
+
the new kernel into memory:
+
+
<screen>
+
$ systemctl kexec
+
</screen>
+
+
</para>
+
+
<para>The machine can be suspended to RAM (if supported) using
+
<command>systemctl suspend</command>, and suspended to disk using
+
<command>systemctl hibernate</command>.</para>
+
+
<para>These commands can be run by any user who is logged in locally,
+
i.e. on a virtual console or in X11; otherwise, the user is asked for
+
authentication.</para>
+
+
</chapter>
+48
nixos/doc/manual/administration/rollback.xml
···
···
+
<section xmlns="http://docbook.org/ns/docbook"
+
xmlns:xlink="http://www.w3.org/1999/xlink"
+
xmlns:xi="http://www.w3.org/2001/XInclude"
+
version="5.0"
+
xml:id="sec-rollback">
+
+
<title>Rolling Back Configuration Changes</title>
+
+
<para>After running <command>nixos-rebuild</command> to switch to a
+
new configuration, you may find that the new configuration doesn’t
+
work very well. In that case, there are several ways to return to a
+
previous configuration.</para>
+
+
<para>First, the GRUB boot manager allows you to boot into any
+
previous configuration that hasn’t been garbage-collected. These
+
configurations can be found under the GRUB submenu “NixOS - All
+
configurations”. This is especially useful if the new configuration
+
fails to boot. After the system has booted, you can make the selected
+
configuration the default for subsequent boots:
+
+
<screen>
+
$ /run/current-system/bin/switch-to-configuration boot</screen>
+
+
</para>
+
+
<para>Second, you can switch to the previous configuration in a running
+
system:
+
+
<screen>
+
$ nixos-rebuild switch --rollback</screen>
+
+
This is equivalent to running:
+
+
<screen>
+
$ /nix/var/nix/profiles/system-<replaceable>N</replaceable>-link/bin/switch-to-configuration switch</screen>
+
+
where <replaceable>N</replaceable> is the number of the NixOS system
+
configuration. To get a list of the available configurations, do:
+
+
<screen>
+
$ ls -l /nix/var/nix/profiles/system-*-link
+
<replaceable>...</replaceable>
+
lrwxrwxrwx 1 root root 78 Aug 12 13:54 /nix/var/nix/profiles/system-268-link -> /nix/store/202b...-nixos-13.07pre4932_5a676e4-4be1055
+
</screen>
+
+
</para>
+
+
</section>
+24
nixos/doc/manual/administration/running.xml
···
···
+
<part xmlns="http://docbook.org/ns/docbook"
+
xmlns:xlink="http://www.w3.org/1999/xlink"
+
xmlns:xi="http://www.w3.org/2001/XInclude"
+
version="5.0"
+
xml:id="ch-running">
+
+
<title>Administration</title>
+
+
<partintro>
+
<para>This chapter describes various aspects of managing a running
+
NixOS system, such as how to use the <command>systemd</command>
+
service manager.</para>
+
</partintro>
+
+
<xi:include href="service-mgmt.xml" />
+
<xi:include href="rebooting.xml" />
+
<xi:include href="user-sessions.xml" />
+
<xi:include href="control-groups.xml" />
+
<xi:include href="logging.xml" />
+
<xi:include href="cleaning-store.xml" />
+
<xi:include href="containers.xml" />
+
<xi:include href="troubleshooting.xml" />
+
+
</part>
+83
nixos/doc/manual/administration/service-mgmt.xml
···
···
+
<chapter xmlns="http://docbook.org/ns/docbook"
+
xmlns:xlink="http://www.w3.org/1999/xlink"
+
xmlns:xi="http://www.w3.org/2001/XInclude"
+
version="5.0"
+
xml:id="sec-systemctl">
+
+
<title>Service Management</title>
+
+
<para>In NixOS, all system services are started and monitored using
+
the systemd program. Systemd is the “init” process of the system
+
(i.e. PID 1), the parent of all other processes. It manages a set of
+
so-called “units”, which can be things like system services
+
(programs), but also mount points, swap files, devices, targets
+
(groups of units) and more. Units can have complex dependencies; for
+
instance, one unit can require that another unit must be successfully
+
started before the first unit can be started. When the system boots,
+
it starts a unit named <literal>default.target</literal>; the
+
dependencies of this unit cause all system services to be started,
+
file systems to be mounted, swap files to be activated, and so
+
on.</para>
+
+
<para>The command <command>systemctl</command> is the main way to
+
interact with <command>systemd</command>. Without any arguments, it
+
shows the status of active units:
+
+
<screen>
+
$ systemctl
+
-.mount loaded active mounted /
+
swapfile.swap loaded active active /swapfile
+
sshd.service loaded active running SSH Daemon
+
graphical.target loaded active active Graphical Interface
+
<replaceable>...</replaceable>
+
</screen>
+
+
</para>
+
+
<para>You can ask for detailed status information about a unit, for
+
instance, the PostgreSQL database service:
+
+
<screen>
+
$ systemctl status postgresql.service
+
postgresql.service - PostgreSQL Server
+
Loaded: loaded (/nix/store/pn3q73mvh75gsrl8w7fdlfk3fq5qm5mw-unit/postgresql.service)
+
Active: active (running) since Mon, 2013-01-07 15:55:57 CET; 9h ago
+
Main PID: 2390 (postgres)
+
CGroup: name=systemd:/system/postgresql.service
+
├─2390 postgres
+
├─2418 postgres: writer process
+
├─2419 postgres: wal writer process
+
├─2420 postgres: autovacuum launcher process
+
├─2421 postgres: stats collector process
+
└─2498 postgres: zabbix zabbix [local] idle
+
+
Jan 07 15:55:55 hagbard postgres[2394]: [1-1] LOG: database system was shut down at 2013-01-07 15:55:05 CET
+
Jan 07 15:55:57 hagbard postgres[2390]: [1-1] LOG: database system is ready to accept connections
+
Jan 07 15:55:57 hagbard postgres[2420]: [1-1] LOG: autovacuum launcher started
+
Jan 07 15:55:57 hagbard systemd[1]: Started PostgreSQL Server.
+
</screen>
+
+
Note that this shows the status of the unit (active and running), all
+
the processes belonging to the service, as well as the most recent log
+
messages from the service.
+
+
</para>
+
+
<para>Units can be stopped, started or restarted:
+
+
<screen>
+
$ systemctl stop postgresql.service
+
$ systemctl start postgresql.service
+
$ systemctl restart postgresql.service
+
</screen>
+
+
These operations are synchronous: they wait until the service has
+
finished starting or stopping (or has failed). Starting a unit will
+
cause the dependencies of that unit to be started as well (if
+
necessary).</para>
+
+
<!-- - cgroups: each service and user session is a cgroup
+
+
- cgroup resource management -->
+
+
</chapter>
+37
nixos/doc/manual/administration/store-corruption.xml
···
···
+
<section xmlns="http://docbook.org/ns/docbook"
+
xmlns:xlink="http://www.w3.org/1999/xlink"
+
xmlns:xi="http://www.w3.org/2001/XInclude"
+
version="5.0"
+
xml:id="sec-nix-store-corruption">
+
+
<title>Nix Store Corruption</title>
+
+
<para>After a system crash, it’s possible for files in the Nix store
+
to become corrupted. (For instance, the Ext4 file system has the
+
tendency to replace un-synced files with zero bytes.) NixOS tries
+
hard to prevent this from happening: it performs a
+
<command>sync</command> before switching to a new configuration, and
+
Nix’s database is fully transactional. If corruption still occurs,
+
you may be able to fix it automatically.</para>
+
+
<para>If the corruption is in a path in the closure of the NixOS
+
system configuration, you can fix it by doing
+
+
<screen>
+
$ nixos-rebuild switch --repair
+
</screen>
+
+
This will cause Nix to check every path in the closure, and if its
+
cryptographic hash differs from the hash recorded in Nix’s database,
+
the path is rebuilt or redownloaded.</para>
+
+
<para>You can also scan the entire Nix store for corrupt paths:
+
+
<screen>
+
$ nix-store --verify --check-contents --repair
+
</screen>
+
+
Any corrupt paths will be redownloaded if they’re available in a
+
binary cache; otherwise, they cannot be repaired.</para>
+
+
</section>
+18
nixos/doc/manual/administration/troubleshooting.xml
···
···
+
<chapter xmlns="http://docbook.org/ns/docbook"
+
xmlns:xlink="http://www.w3.org/1999/xlink"
+
xmlns:xi="http://www.w3.org/2001/XInclude"
+
version="5.0"
+
xml:id="ch-troubleshooting">
+
+
<title>Troubleshooting</title>
+
+
<para>This chapter describes solutions to common problems you might
+
encounter when you manage your NixOS system.</para>
+
+
<xi:include href="boot-problems.xml" />
+
<xi:include href="maintenance-mode.xml" />
+
<xi:include href="rollback.xml" />
+
<xi:include href="store-corruption.xml" />
+
<xi:include href="network-problems.xml" />
+
+
</chapter>
+53
nixos/doc/manual/administration/user-sessions.xml
···
···
+
<chapter xmlns="http://docbook.org/ns/docbook"
+
xmlns:xlink="http://www.w3.org/1999/xlink"
+
xmlns:xi="http://www.w3.org/2001/XInclude"
+
version="5.0"
+
xml:id="sec-user-sessions">
+
+
<title>User Sessions</title>
+
+
<para>Systemd keeps track of all users who are logged into the system
+
(e.g. on a virtual console or remotely via SSH). The command
+
<command>loginctl</command> allows querying and manipulating user
+
sessions. For instance, to list all user sessions:
+
+
<screen>
+
$ loginctl
+
SESSION UID USER SEAT
+
c1 500 eelco seat0
+
c3 0 root seat0
+
c4 500 alice
+
</screen>
+
+
This shows that two users are logged in locally, while another is
+
logged in remotely. (“Seats” are essentially the combinations of
+
displays and input devices attached to the system; usually, there is
+
only one seat.) To get information about a session:
+
+
<screen>
+
$ loginctl session-status c3
+
c3 - root (0)
+
Since: Tue, 2013-01-08 01:17:56 CET; 4min 42s ago
+
Leader: 2536 (login)
+
Seat: seat0; vc3
+
TTY: /dev/tty3
+
Service: login; type tty; class user
+
State: online
+
CGroup: name=systemd:/user/root/c3
+
├─ 2536 /nix/store/10mn4xip9n7y9bxqwnsx7xwx2v2g34xn-shadow-4.1.5.1/bin/login --
+
├─10339 -bash
+
└─10355 w3m nixos.org
+
</screen>
+
+
This shows that the user is logged in on virtual console 3. It also
+
lists the processes belonging to this session. Since systemd keeps
+
track of this, you can terminate a session in a way that ensures that
+
all the session’s processes are gone:
+
+
<screen>
+
$ loginctl terminate-session c3
+
</screen>
+
+
</para>
+
+
</chapter>
-1563
nixos/doc/manual/configuration.xml
···
-
<chapter xmlns="http://docbook.org/ns/docbook"
-
xmlns:xlink="http://www.w3.org/1999/xlink"
-
xml:id="ch-configuration">
-
-
<title>Configuring NixOS</title>
-
-
<para>This chapter describes how to configure various aspects of a
-
NixOS machine through the configuration file
-
<filename>/etc/nixos/configuration.nix</filename>. As described in
-
<xref linkend="sec-changing-config" />, changes to this file only take
-
effect after you run <command>nixos-rebuild</command>.</para>
-
-
-
<!--===============================================================-->
-
-
<section xml:id="sec-configuration-syntax"><title>Configuration syntax</title>
-
-
<section><title>The basics</title>
-
-
<para>The NixOS configuration file
-
<filename>/etc/nixos/configuration.nix</filename> is actually a
-
<emphasis>Nix expression</emphasis>, which is the Nix package
-
manager’s purely functional language for describing how to build
-
packages and configurations. This means you have all the expressive
-
power of that language at your disposal, including the ability to
-
abstract over common patterns, which is very useful when managing
-
complex systems. The syntax and semantics of the Nix language are
-
fully described in the <link
-
xlink:href="http://nixos.org/nix/manual/#chap-writing-nix-expressions">Nix
-
manual</link>, but here we give a short overview of the most important
-
constructs useful in NixOS configuration files.</para>
-
-
<para>The NixOS configuration file generally looks like this:
-
-
<programlisting>
-
{ config, pkgs, ... }:
-
-
{ <replaceable>option definitions</replaceable>
-
}
-
</programlisting>
-
-
The first line (<literal>{ config, pkgs, ... }:</literal>) denotes
-
that this is actually a function that takes at least the two arguments
-
<varname>config</varname> and <varname>pkgs</varname>. (These are
-
explained later.) The function returns a <emphasis>set</emphasis> of
-
option definitions (<literal>{ <replaceable>...</replaceable> }</literal>). These definitions have the
-
form <literal><replaceable>name</replaceable> =
-
<replaceable>value</replaceable></literal>, where
-
<replaceable>name</replaceable> is the name of an option and
-
<replaceable>value</replaceable> is its value. For example,
-
-
<programlisting>
-
{ config, pkgs, ... }:
-
-
{ services.httpd.enable = true;
-
services.httpd.adminAddr = "alice@example.org";
-
services.httpd.documentRoot = "/webroot";
-
}
-
</programlisting>
-
-
defines a configuration with three option definitions that together
-
enable the Apache HTTP Server with <filename>/webroot</filename> as
-
the document root.</para>
-
-
<para>Sets can be nested, and in fact dots in option names are
-
shorthand for defining a set containing another set. For instance,
-
<option>services.httpd.enable</option> defines a set named
-
<varname>services</varname> that contains a set named
-
<varname>httpd</varname>, which in turn contains an option definition
-
named <varname>enable</varname> with value <literal>true</literal>.
-
This means that the example above can also be written as:
-
-
<programlisting>
-
{ config, pkgs, ... }:
-
-
{ services = {
-
httpd = {
-
enable = true;
-
adminAddr = "alice@example.org";
-
documentRoot = "/webroot";
-
};
-
};
-
}
-
</programlisting>
-
-
which may be more convenient if you have lots of option definitions
-
that share the same prefix (such as
-
<literal>services.httpd</literal>).</para>
-
-
<para>NixOS checks your option definitions for correctness. For
-
instance, if you try to define an option that doesn’t exist (that is,
-
doesn’t have a corresponding <emphasis>option declaration</emphasis>),
-
<command>nixos-rebuild</command> will give an error like:
-
<screen>
-
The option `services.httpd.enabl' defined in `/etc/nixos/configuration.nix' does not exist.
-
</screen>
-
Likewise, values in option definitions must have a correct type. For
-
instance, <option>services.httpd.enable</option> must be a Boolean
-
(<literal>true</literal> or <literal>false</literal>). Trying to give
-
it a value of another type, such as a string, will cause an error:
-
<screen>
-
The option value `services.httpd.enable' in `/etc/nixos/configuration.nix' is not a boolean.
-
</screen>
-
-
</para>
-
-
<para>Options have various types of values. The most important are:
-
-
<variablelist>
-
<varlistentry>
-
<term>Strings</term>
-
<listitem>
-
<para>Strings are enclosed in double quotes, e.g.
-
-
<programlisting>
-
networking.hostName = "dexter";
-
</programlisting>
-
-
Special characters can be escaped by prefixing them with a
-
backslash (e.g. <literal>\"</literal>).</para>
-
-
<para>Multi-line strings can be enclosed in <emphasis>double
-
single quotes</emphasis>, e.g.
-
-
<programlisting>
-
networking.extraHosts =
-
''
-
127.0.0.2 other-localhost
-
10.0.0.1 server
-
'';
-
</programlisting>
-
-
The main difference is that preceding whitespace is
-
automatically stripped from each line, and that characters like
-
<literal>"</literal> and <literal>\</literal> are not special
-
(making it more convenient for including things like shell
-
code).</para>
-
</listitem>
-
</varlistentry>
-
-
<varlistentry>
-
<term>Booleans</term>
-
<listitem>
-
<para>These can be <literal>true</literal> or
-
<literal>false</literal>, e.g.
-
-
<programlisting>
-
networking.firewall.enable = true;
-
networking.firewall.allowPing = false;
-
</programlisting>
-
</para>
-
</listitem>
-
</varlistentry>
-
-
<varlistentry>
-
<term>Integers</term>
-
<listitem>
-
<para>For example,
-
-
<programlisting>
-
boot.kernel.sysctl."net.ipv4.tcp_keepalive_time" = 60;
-
</programlisting>
-
-
(Note that here the attribute name
-
<literal>net.ipv4.tcp_keepalive_time</literal> is enclosed in
-
quotes to prevent it from being interpreted as a set named
-
<literal>net</literal> containing a set named
-
<literal>ipv4</literal>, and so on. This is because it’s not a
-
NixOS option but the literal name of a Linux kernel
-
setting.)</para>
-
</listitem>
-
</varlistentry>
-
-
<varlistentry>
-
<term>Sets</term>
-
<listitem>
-
<para>Sets were introduced above. They are name/value pairs
-
enclosed in braces, as in the option definition
-
-
<programlisting>
-
fileSystems."/boot" =
-
{ device = "/dev/sda1";
-
fsType = "ext4";
-
options = "rw,data=ordered,relatime";
-
};
-
</programlisting>
-
</para>
-
</listitem>
-
</varlistentry>
-
-
<varlistentry>
-
<term>Lists</term>
-
<listitem>
-
<para>The important thing to note about lists is that list
-
elements are separated by whitespace, like this:
-
-
<programlisting>
-
boot.kernelModules = [ "fuse" "kvm-intel" "coretemp" ];
-
</programlisting>
-
-
List elements can be any other type, e.g. sets:
-
-
<programlisting>
-
swapDevices = [ { device = "/dev/disk/by-label/swap"; } ];
-
</programlisting>
-
</para>
-
</listitem>
-
</varlistentry>
-
-
<varlistentry>
-
<term>Packages</term>
-
<listitem>
-
<para>Usually, the packages you need are already part of the Nix
-
Packages collection, which is a set that can be accessed through
-
the function argument <varname>pkgs</varname>. Typical uses:
-
-
<programlisting>
-
environment.systemPackages =
-
[ pkgs.thunderbird
-
pkgs.emacs
-
];
-
-
postgresql.package = pkgs.postgresql90;
-
</programlisting>
-
-
The latter option definition changes the default PostgreSQL
-
package used by NixOS’s PostgreSQL service to 9.0. For more
-
information on packages, including how to add new ones, see
-
<xref linkend="sec-custom-packages"/>.</para>
-
</listitem>
-
</varlistentry>
-
-
</variablelist>
-
-
</para>
-
-
</section>
-
-
-
<section xml:id="sec-module-abstractions"><title>Abstractions</title>
-
-
<para>If you find yourself repeating yourself over and over, it’s time
-
to abstract. Take, for instance, this Apache HTTP Server configuration:
-
-
<programlisting>
-
{
-
services.httpd.virtualHosts =
-
[ { hostName = "example.org";
-
documentRoot = "/webroot";
-
adminAddr = "alice@example.org";
-
enableUserDir = true;
-
}
-
{ hostName = "example.org";
-
documentRoot = "/webroot";
-
adminAddr = "alice@example.org";
-
enableUserDir = true;
-
enableSSL = true;
-
sslServerCert = "/root/ssl-example-org.crt";
-
sslServerKey = "/root/ssl-example-org.key";
-
}
-
];
-
}
-
</programlisting>
-
-
It defines two virtual hosts with nearly identical configuration; the
-
only difference is that the second one has SSL enabled. To prevent
-
this duplication, we can use a <literal>let</literal>:
-
-
<programlisting>
-
let
-
exampleOrgCommon =
-
{ hostName = "example.org";
-
documentRoot = "/webroot";
-
adminAddr = "alice@example.org";
-
enableUserDir = true;
-
};
-
in
-
{
-
services.httpd.virtualHosts =
-
[ exampleOrgCommon
-
(exampleOrgCommon // {
-
enableSSL = true;
-
sslServerCert = "/root/ssl-example-org.crt";
-
sslServerKey = "/root/ssl-example-org.key";
-
})
-
];
-
}
-
</programlisting>
-
-
The <literal>let exampleOrgCommon =
-
<replaceable>...</replaceable></literal> defines a variable named
-
<literal>exampleOrgCommon</literal>. The <literal>//</literal>
-
operator merges two attribute sets, so the configuration of the second
-
virtual host is the set <literal>exampleOrgCommon</literal> extended
-
with the SSL options.</para>
-
-
<para>You can write a <literal>let</literal> wherever an expression is
-
allowed. Thus, you also could have written:
-
-
<programlisting>
-
{
-
services.httpd.virtualHosts =
-
let exampleOrgCommon = <replaceable>...</replaceable>; in
-
[ exampleOrgCommon
-
(exampleOrgCommon // { <replaceable>...</replaceable> })
-
];
-
}
-
</programlisting>
-
-
but not <literal>{ let exampleOrgCommon =
-
<replaceable>...</replaceable>; in <replaceable>...</replaceable>;
-
}</literal> since attributes (as opposed to attribute values) are not
-
expressions.</para>
-
-
<para><emphasis>Functions</emphasis> provide another method of
-
abstraction. For instance, suppose that we want to generate lots of
-
different virtual hosts, all with identical configuration except for
-
the host name. This can be done as follows:
-
-
<programlisting>
-
{
-
services.httpd.virtualHosts =
-
let
-
makeVirtualHost = name:
-
{ hostName = name;
-
documentRoot = "/webroot";
-
adminAddr = "alice@example.org";
-
};
-
in
-
[ (makeVirtualHost "example.org")
-
(makeVirtualHost "example.com")
-
(makeVirtualHost "example.gov")
-
(makeVirtualHost "example.nl")
-
];
-
}
-
</programlisting>
-
-
Here, <varname>makeVirtualHost</varname> is a function that takes a
-
single argument <literal>name</literal> and returns the configuration
-
for a virtual host. That function is then called for several names to
-
produce the list of virtual host configurations.</para>
-
-
<para>We can further improve on this by using the function
-
<varname>map</varname>, which applies another function to every
-
element in a list:
-
-
<programlisting>
-
{
-
services.httpd.virtualHosts =
-
let
-
makeVirtualHost = <replaceable>...</replaceable>;
-
in map makeVirtualHost
-
[ "example.org" "example.com" "example.gov" "example.nl" ];
-
}
-
</programlisting>
-
-
(The function <literal>map</literal> is called a
-
<emphasis>higher-order function</emphasis> because it takes another
-
function as an argument.)</para>
-
-
<para>What if you need more than one argument, for instance, if we
-
want to use a different <literal>documentRoot</literal> for each
-
virtual host? Then we can make <varname>makeVirtualHost</varname> a
-
function that takes a <emphasis>set</emphasis> as its argument, like this:
-
-
<programlisting>
-
{
-
services.httpd.virtualHosts =
-
let
-
makeVirtualHost = { name, root }:
-
{ hostName = name;
-
documentRoot = root;
-
adminAddr = "alice@example.org";
-
};
-
in map makeVirtualHost
-
[ { name = "example.org"; root = "/sites/example.org"; }
-
{ name = "example.com"; root = "/sites/example.com"; }
-
{ name = "example.gov"; root = "/sites/example.gov"; }
-
{ name = "example.nl"; root = "/sites/example.nl"; }
-
];
-
}
-
</programlisting>
-
-
But in this case (where every root is a subdirectory of
-
<filename>/sites</filename> named after the virtual host), it would
-
have been shorter to define <varname>makeVirtualHost</varname> as
-
<programlisting>
-
makeVirtualHost = name:
-
{ hostName = name;
-
documentRoot = "/sites/${name}";
-
adminAddr = "alice@example.org";
-
};
-
</programlisting>
-
-
Here, the construct
-
<literal>${<replaceable>...</replaceable>}</literal> allows the result
-
of an expression to be spliced into a string.</para>
-
-
</section>
-
-
-
<section xml:id="sec-modularity"><title>Modularity</title>
-
-
<para>The NixOS configuration mechanism is modular. If your
-
<filename>configuration.nix</filename> becomes too big, you can split
-
it into multiple files. Likewise, if you have multiple NixOS
-
configurations (e.g. for different computers) with some commonality,
-
you can move the common configuration into a shared file.</para>
-
-
<para>Modules have exactly the same syntax as
-
<filename>configuration.nix</filename>. In fact,
-
<filename>configuration.nix</filename> is itself a module. You can
-
use other modules by including them from
-
<filename>configuration.nix</filename>, e.g.:
-
-
<programlisting>
-
{ config, pkgs, ... }:
-
-
{ imports = [ ./vpn.nix ./kde.nix ];
-
services.httpd.enable = true;
-
environment.systemPackages = [ pkgs.emacs ];
-
<replaceable>...</replaceable>
-
}
-
</programlisting>
-
-
Here, we include two modules from the same directory,
-
<filename>vpn.nix</filename> and <filename>kde.nix</filename>. The
-
latter might look like this:
-
-
<programlisting>
-
{ config, pkgs, ... }:
-
-
{ services.xserver.enable = true;
-
services.xserver.displayManager.kdm.enable = true;
-
services.xserver.desktopManager.kde4.enable = true;
-
environment.systemPackages = [ pkgs.kde4.kscreensaver ];
-
}
-
</programlisting>
-
-
Note that both <filename>configuration.nix</filename> and
-
<filename>kde.nix</filename> define the option
-
<option>environment.systemPackages</option>. When multiple modules
-
define an option, NixOS will try to <emphasis>merge</emphasis> the
-
definitions. In the case of
-
<option>environment.systemPackages</option>, that’s easy: the lists of
-
packages can simply be concatenated. The value in
-
<filename>configuration.nix</filename> is merged last, so for
-
list-type options, it will appear at the end of the merged list. If
-
you want it to appear first, you can use <varname>mkBefore</varname>:
-
-
<programlisting>
-
boot.kernelModules = mkBefore [ "kvm-intel" ];
-
</programlisting>
-
-
This causes the <literal>kvm-intel</literal> kernel module to be
-
loaded before any other kernel modules.</para>
-
-
<para>For other types of options, a merge may not be possible. For
-
instance, if two modules define
-
<option>services.httpd.adminAddr</option>,
-
<command>nixos-rebuild</command> will give an error:
-
-
<screen>
-
The unique option `services.httpd.adminAddr' is defined multiple times, in `/etc/nixos/httpd.nix' and `/etc/nixos/configuration.nix'.
-
</screen>
-
-
When that happens, it’s possible to force one definition take
-
precedence over the others:
-
-
<programlisting>
-
services.httpd.adminAddr = pkgs.lib.mkForce "bob@example.org";
-
</programlisting>
-
-
</para>
-
-
<para>When using multiple modules, you may need to access
-
configuration values defined in other modules. This is what the
-
<varname>config</varname> function argument is for: it contains the
-
complete, merged system configuration. That is,
-
<varname>config</varname> is the result of combining the
-
configurations returned by every module<footnote><para>If you’re
-
wondering how it’s possible that the (indirect)
-
<emphasis>result</emphasis> of a function is passed as an
-
<emphasis>input</emphasis> to that same function: that’s because Nix
-
is a “lazy” language — it only computes values when they are needed.
-
This works as long as no individual configuration value depends on
-
itself.</para></footnote>. For example, here is a module that adds
-
some packages to <option>environment.systemPackages</option> only if
-
<option>services.xserver.enable</option> is set to
-
<literal>true</literal> somewhere else:
-
-
<programlisting>
-
{ config, pkgs, ... }:
-
-
{ environment.systemPackages =
-
if config.services.xserver.enable then
-
[ pkgs.firefox
-
pkgs.thunderbird
-
]
-
else
-
[ ];
-
}
-
</programlisting>
-
-
</para>
-
-
<para>With multiple modules, it may not be obvious what the final
-
value of a configuration option is. The command
-
<option>nixos-option</option> allows you to find out:
-
-
<screen>
-
$ nixos-option services.xserver.enable
-
true
-
-
$ nixos-option boot.kernelModules
-
[ "tun" "ipv6" "loop" <replaceable>...</replaceable> ]
-
</screen>
-
-
Interactive exploration of the configuration is possible using
-
<command
-
xlink:href="https://github.com/edolstra/nix-repl">nix-repl</command>,
-
a read-eval-print loop for Nix expressions. It’s not installed by
-
default; run <literal>nix-env -i nix-repl</literal> to get it. A
-
typical use:
-
-
<screen>
-
$ nix-repl '&lt;nixos>'
-
-
nix-repl> config.networking.hostName
-
"mandark"
-
-
nix-repl> map (x: x.hostName) config.services.httpd.virtualHosts
-
[ "example.org" "example.gov" ]
-
</screen>
-
-
</para>
-
-
</section>
-
-
-
<section xml:id="sec-nix-syntax-summary"><title>Syntax summary</title>
-
-
<para>Below is a summary of the most important syntactic constructs in
-
the Nix expression language. It’s not complete. In particular, there
-
are many other built-in functions. See the <link
-
xlink:href="http://nixos.org/nix/manual/#chap-writing-nix-expressions">Nix
-
manual</link> for the rest.</para>
-
-
<informaltable frame='none'>
-
<tgroup cols='2'>
-
<colspec colname='c1' rowsep='1' colsep='1' />
-
<colspec colname='c2' rowsep='1' />
-
<thead>
-
<row>
-
<entry>Example</entry>
-
<entry>Description</entry>
-
</row>
-
</thead>
-
<tbody>
-
-
<row>
-
<entry namest="c1" nameend="c2"><emphasis>Basic values</emphasis></entry>
-
</row>
-
<row>
-
<entry><literal>"Hello world"</literal></entry>
-
<entry>A string</entry>
-
</row>
-
<row>
-
<entry><literal>"${pkgs.bash}/bin/sh"</literal></entry>
-
<entry>A string containing an expression (expands to <literal>"/nix/store/<replaceable>hash</replaceable>-bash-<replaceable>version</replaceable>/bin/sh"</literal>)</entry>
-
</row>
-
<row>
-
<entry><literal>true</literal>, <literal>false</literal></entry>
-
<entry>Booleans</entry>
-
</row>
-
<row>
-
<entry><literal>123</literal></entry>
-
<entry>An integer</entry>
-
</row>
-
<row>
-
<entry><literal>./foo.png</literal></entry>
-
<entry>A path (relative to the containing Nix expression)</entry>
-
</row>
-
-
<row>
-
<entry namest="c1" nameend="c2"><emphasis>Compound values</emphasis></entry>
-
</row>
-
<row>
-
<entry><literal>{ x = 1; y = 2; }</literal></entry>
-
<entry>An set with attributes names <literal>x</literal> and <literal>y</literal></entry>
-
</row>
-
<row>
-
<entry><literal>{ foo.bar = 1; }</literal></entry>
-
<entry>A nested set, equivalent to <literal>{ foo = { bar = 1; }; }</literal></entry>
-
</row>
-
<row>
-
<entry><literal>rec { x = "bla"; y = x + "bar"; }</literal></entry>
-
<entry>A recursive set, equivalent to <literal>{ x = "foo"; y = "foobar"; }</literal></entry>
-
</row>
-
<row>
-
<entry><literal>[ "foo" "bar" ]</literal></entry>
-
<entry>A list with two elements</entry>
-
</row>
-
-
<row>
-
<entry namest="c1" nameend="c2"><emphasis>Operators</emphasis></entry>
-
</row>
-
<row>
-
<entry><literal>"foo" + "bar"</literal></entry>
-
<entry>String concatenation</entry>
-
</row>
-
<row>
-
<entry><literal>1 + 2</literal></entry>
-
<entry>Integer addition</entry>
-
</row>
-
<row>
-
<entry><literal>"foo" == "f" + "oo"</literal></entry>
-
<entry>Equality test (evaluates to <literal>true</literal>)</entry>
-
</row>
-
<row>
-
<entry><literal>"foo" != "bar"</literal></entry>
-
<entry>Inequality test (evaluates to <literal>true</literal>)</entry>
-
</row>
-
<row>
-
<entry><literal>!true</literal></entry>
-
<entry>Boolean negation</entry>
-
</row>
-
<row>
-
<entry><literal>{ x = 1; y = 2; }.x</literal></entry>
-
<entry>Attribute selection (evaluates to <literal>1</literal>)</entry>
-
</row>
-
<row>
-
<entry><literal>{ x = 1; y = 2; }.z or 3</literal></entry>
-
<entry>Attribute selection with default (evaluates to <literal>3</literal>)</entry>
-
</row>
-
<row>
-
<entry><literal>{ x = 1; y = 2; } // { z = 3; }</literal></entry>
-
<entry>Merge two sets (attributes in the right-hand set taking precedence)</entry>
-
</row>
-
-
<row>
-
<entry namest="c1" nameend="c2"><emphasis>Control structures</emphasis></entry>
-
</row>
-
<row>
-
<entry><literal>if 1 + 1 == 2 then "yes!" else "no!"</literal></entry>
-
<entry>Conditional expression</entry>
-
</row>
-
<row>
-
<entry><literal>assert 1 + 1 == 2; "yes!"</literal></entry>
-
<entry>Assertion check (evaluates to <literal>"yes!"</literal>)</entry>
-
</row>
-
<row>
-
<entry><literal>let x = "foo"; y = "bar"; in x + y</literal></entry>
-
<entry>Variable definition</entry>
-
</row>
-
<row>
-
<entry><literal>with pkgs.lib; head [ 1 2 3 ]</literal></entry>
-
<entry>Add all attributes from the given set to the scope
-
(evaluates to <literal>1</literal>)</entry>
-
</row>
-
-
<row>
-
<entry namest="c1" nameend="c2"><emphasis>Functions (lambdas)</emphasis></entry>
-
</row>
-
<row>
-
<entry><literal>x: x + 1</literal></entry>
-
<entry>A function that expects an integer and returns it increased by 1</entry>
-
</row>
-
<row>
-
<entry><literal>(x: x + 1) 100</literal></entry>
-
<entry>A function call (evaluates to 101)</entry>
-
</row>
-
<row>
-
<entry><literal>let inc = x: x + 1; in inc (inc (inc 100))</literal></entry>
-
<entry>A function bound to a variable and subsequently called by name (evaluates to 103)</entry>
-
</row>
-
<row>
-
<entry><literal>{ x, y }: x + y</literal></entry>
-
<entry>A function that expects a set with required attributes
-
<literal>x</literal> and <literal>y</literal> and concatenates
-
them</entry>
-
</row>
-
<row>
-
<entry><literal>{ x, y ? "bar" }: x + y</literal></entry>
-
<entry>A function that expects a set with required attribute
-
<literal>x</literal> and optional <literal>y</literal>, using
-
<literal>"bar"</literal> as default value for
-
<literal>y</literal></entry>
-
</row>
-
<row>
-
<entry><literal>{ x, y, ... }: x + y</literal></entry>
-
<entry>A function that expects a set with required attributes
-
<literal>x</literal> and <literal>y</literal> and ignores any
-
other attributes</entry>
-
</row>
-
<row>
-
<entry><literal>{ x, y } @ args: x + y</literal></entry>
-
<entry>A function that expects a set with required attributes
-
<literal>x</literal> and <literal>y</literal>, and binds the
-
whole set to <literal>args</literal></entry>
-
</row>
-
-
<row>
-
<entry namest="c1" nameend="c2"><emphasis>Built-in functions</emphasis></entry>
-
</row>
-
<row>
-
<entry><literal>import ./foo.nix</literal></entry>
-
<entry>Load and return Nix expression in given file</entry>
-
</row>
-
<row>
-
<entry><literal>map (x: x + x) [ 1 2 3 ]</literal></entry>
-
<entry>Apply a function to every element of a list (evaluates to <literal>[ 2 4 6 ]</literal>)</entry>
-
</row>
-
<!--
-
<row>
-
<entry><literal>throw "Urgh"</literal></entry>
-
<entry>Raise an error condition</entry>
-
</row>
-
-->
-
-
</tbody>
-
</tgroup>
-
</informaltable>
-
-
</section>
-
-
-
</section>
-
-
-
<!--===============================================================-->
-
-
<section xml:id="sec-package-management"><title>Package management</title>
-
-
<para>This section describes how to add additional packages to your
-
system. NixOS has two distinct styles of package management:
-
-
<itemizedlist>
-
-
<listitem><para><emphasis>Declarative</emphasis>, where you declare
-
what packages you want in your
-
<filename>configuration.nix</filename>. Every time you run
-
<command>nixos-rebuild</command>, NixOS will ensure that you get a
-
consistent set of binaries corresponding to your
-
specification.</para></listitem>
-
-
<listitem><para><emphasis>Ad hoc</emphasis>, where you install,
-
upgrade and uninstall packages via the <command>nix-env</command>
-
command. This style allows mixing packages from different Nixpkgs
-
versions. It’s the only choice for non-root
-
users.</para></listitem>
-
-
</itemizedlist>
-
-
</para>
-
-
<para>The next two sections describe these two styles.</para>
-
-
-
<section><title>Declarative package management</title>
-
-
<para>With declarative package management, you specify which packages
-
you want on your system by setting the option
-
<option>environment.systemPackages</option>. For instance, adding the
-
following line to <filename>configuration.nix</filename> enables the
-
Mozilla Thunderbird email application:
-
-
<programlisting>
-
environment.systemPackages = [ pkgs.thunderbird ];
-
</programlisting>
-
-
The effect of this specification is that the Thunderbird package from
-
Nixpkgs will be built or downloaded as part of the system when you run
-
<command>nixos-rebuild switch</command>.</para>
-
-
<para>You can get a list of the available packages as follows:
-
<screen>
-
$ nix-env -qaP '*' --description
-
nixos.pkgs.firefox firefox-23.0 Mozilla Firefox - the browser, reloaded
-
<replaceable>...</replaceable>
-
</screen>
-
-
The first column in the output is the <emphasis>attribute
-
name</emphasis>, such as
-
<literal>nixos.pkgs.thunderbird</literal>. (The
-
<literal>nixos</literal> prefix allows distinguishing between
-
different channels that you might have.)</para>
-
-
<para>To “uninstall” a package, simply remove it from
-
<option>environment.systemPackages</option> and run
-
<command>nixos-rebuild switch</command>.</para>
-
-
-
<section xml:id="sec-customising-packages"><title>Customising packages</title>
-
-
<para>Some packages in Nixpkgs have options to enable or disable
-
optional functionality or change other aspects of the package. For
-
instance, the Firefox wrapper package (which provides Firefox with a
-
set of plugins such as the Adobe Flash player) has an option to enable
-
the Google Talk plugin. It can be set in
-
<filename>configuration.nix</filename> as follows:
-
-
<filename>
-
nixpkgs.config.firefox.enableGoogleTalkPlugin = true;
-
</filename>
-
</para>
-
-
<warning><para>Unfortunately, Nixpkgs currently lacks a way to query
-
available configuration options.</para></warning>
-
-
<para>Apart from high-level options, it’s possible to tweak a package
-
in almost arbitrary ways, such as changing or disabling dependencies
-
of a package. For instance, the Emacs package in Nixpkgs by default
-
has a dependency on GTK+ 2. If you want to build it against GTK+ 3,
-
you can specify that as follows:
-
-
<programlisting>
-
environment.systemPackages = [ (pkgs.emacs.override { gtk = pkgs.gtk3; }) ];
-
</programlisting>
-
-
The function <varname>override</varname> performs the call to the Nix
-
function that produces Emacs, with the original arguments amended by
-
the set of arguments specified by you. So here the function argument
-
<varname>gtk</varname> gets the value <literal>pkgs.gtk3</literal>,
-
causing Emacs to depend on GTK+ 3. (The parentheses are necessary
-
because in Nix, function application binds more weakly than list
-
construction, so without them,
-
<literal>environment.systemPackages</literal> would be a list with two
-
elements.)</para>
-
-
<para>Even greater customisation is possible using the function
-
<varname>overrideDerivation</varname>. While the
-
<varname>override</varname> mechanism above overrides the arguments of
-
a package function, <varname>overrideDerivation</varname> allows
-
changing the <emphasis>result</emphasis> of the function. This
-
permits changing any aspect of the package, such as the source code.
-
For instance, if you want to override the source code of Emacs, you
-
can say:
-
-
<programlisting>
-
environment.systemPackages =
-
[ (pkgs.lib.overrideDerivation pkgs.emacs (attrs: {
-
name = "emacs-25.0-pre";
-
src = /path/to/my/emacs/tree;
-
}))
-
];
-
</programlisting>
-
-
Here, <varname>overrideDerivation</varname> takes the Nix derivation
-
specified by <varname>pkgs.emacs</varname> and produces a new
-
derivation in which the original’s <literal>name</literal> and
-
<literal>src</literal> attribute have been replaced by the given
-
values. The original attributes are accessible via
-
<varname>attrs</varname>.</para>
-
-
<para>The overrides shown above are not global. They do not affect
-
the original package; other packages in Nixpkgs continue to depend on
-
the original rather than the customised package. This means that if
-
another package in your system depends on the original package, you
-
end up with two instances of the package. If you want to have
-
everything depend on your customised instance, you can apply a
-
<emphasis>global</emphasis> override as follows:
-
-
<screen>
-
nixpkgs.config.packageOverrides = pkgs:
-
{ emacs = pkgs.emacs.override { gtk = pkgs.gtk3; };
-
};
-
</screen>
-
-
The effect of this definition is essentially equivalent to modifying
-
the <literal>emacs</literal> attribute in the Nixpkgs source tree.
-
Any package in Nixpkgs that depends on <literal>emacs</literal> will
-
be passed your customised instance. (However, the value
-
<literal>pkgs.emacs</literal> in
-
<varname>nixpkgs.config.packageOverrides</varname> refers to the
-
original rather than overridden instance, to prevent an infinite
-
recursion.)</para>
-
-
</section>
-
-
<section xml:id="sec-custom-packages"><title>Adding custom packages</title>
-
-
<para>It’s possible that a package you need is not available in NixOS.
-
In that case, you can do two things. First, you can clone the Nixpkgs
-
repository, add the package to your clone, and (optionally) submit a
-
patch or pull request to have it accepted into the main Nixpkgs
-
repository. This is described in detail in the <link
-
xlink:href="http://nixos.org/nixpkgs/manual">Nixpkgs manual</link>.
-
In short, you clone Nixpkgs:
-
-
<screen>
-
$ git clone git://github.com/NixOS/nixpkgs.git
-
$ cd nixpkgs
-
</screen>
-
-
Then you write and test the package as described in the Nixpkgs
-
manual. Finally, you add it to
-
<literal>environment.systemPackages</literal>, e.g.
-
-
<programlisting>
-
environment.systemPackages = [ pkgs.my-package ];
-
</programlisting>
-
-
and you run <command>nixos-rebuild</command>, specifying your own
-
Nixpkgs tree:
-
-
<screen>
-
$ nixos-rebuild switch -I nixpkgs=/path/to/my/nixpkgs</screen>
-
-
</para>
-
-
<para>The second possibility is to add the package outside of the
-
Nixpkgs tree. For instance, here is how you specify a build of the
-
<link xlink:href="http://www.gnu.org/software/hello/">GNU Hello</link>
-
package directly in <filename>configuration.nix</filename>:
-
-
<programlisting>
-
environment.systemPackages =
-
let
-
my-hello = with pkgs; stdenv.mkDerivation rec {
-
name = "hello-2.8";
-
src = fetchurl {
-
url = "mirror://gnu/hello/${name}.tar.gz";
-
sha256 = "0wqd8sjmxfskrflaxywc7gqw7sfawrfvdxd9skxawzfgyy0pzdz6";
-
};
-
};
-
in
-
[ my-hello ];
-
</programlisting>
-
-
Of course, you can also move the definition of
-
<literal>my-hello</literal> into a separate Nix expression, e.g.
-
<programlisting>
-
environment.systemPackages = [ (import ./my-hello.nix) ];
-
</programlisting>
-
where <filename>my-hello.nix</filename> contains:
-
<programlisting>
-
with import &lt;nixpkgs> {}; # bring all of Nixpkgs into scope
-
-
stdenv.mkDerivation rec {
-
name = "hello-2.8";
-
src = fetchurl {
-
url = "mirror://gnu/hello/${name}.tar.gz";
-
sha256 = "0wqd8sjmxfskrflaxywc7gqw7sfawrfvdxd9skxawzfgyy0pzdz6";
-
};
-
}
-
</programlisting>
-
-
This allows testing the package easily:
-
<screen>
-
$ nix-build my-hello.nix
-
$ ./result/bin/hello
-
Hello, world!
-
</screen>
-
-
</para>
-
-
</section>
-
-
</section>
-
-
-
<section><title>Ad hoc package management</title>
-
-
<para>With the command <command>nix-env</command>, you can install and
-
uninstall packages from the command line. For instance, to install
-
Mozilla Thunderbird:
-
-
<screen>
-
$ nix-env -iA nixos.pkgs.thunderbird</screen>
-
-
If you invoke this as root, the package is installed in the Nix
-
profile <filename>/nix/var/nix/profiles/default</filename> and visible
-
to all users of the system; otherwise, the package ends up in
-
<filename>/nix/var/nix/profiles/per-user/<replaceable>username</replaceable>/profile</filename>
-
and is not visible to other users. The <option>-A</option> flag
-
specifies the package by its attribute name; without it, the package
-
is installed by matching against its package name
-
(e.g. <literal>thunderbird</literal>). The latter is slower because
-
it requires matching against all available Nix packages, and is
-
ambiguous if there are multiple matching packages.</para>
-
-
<para>Packages come from the NixOS channel. You typically upgrade a
-
package by updating to the latest version of the NixOS channel:
-
<screen>
-
$ nix-channel --update nixos
-
</screen>
-
and then running <literal>nix-env -i</literal> again. Other packages
-
in the profile are <emphasis>not</emphasis> affected; this is the
-
crucial difference with the declarative style of package management,
-
where running <command>nixos-rebuild switch</command> causes all
-
packages to be updated to their current versions in the NixOS channel.
-
You can however upgrade all packages for which there is a newer
-
version by doing:
-
<screen>
-
$ nix-env -u '*'
-
</screen>
-
</para>
-
-
<para>A package can be uninstalled using the <option>-e</option>
-
flag:
-
<screen>
-
$ nix-env -e thunderbird
-
</screen>
-
</para>
-
-
<para>Finally, you can roll back an undesirable
-
<command>nix-env</command> action:
-
<screen>
-
$ nix-env --rollback
-
</screen>
-
</para>
-
-
<para><command>nix-env</command> has many more flags. For details,
-
see the
-
<citerefentry><refentrytitle>nix-env</refentrytitle><manvolnum>1</manvolnum></citerefentry>
-
manpage or the Nix manual.</para>
-
-
</section>
-
-
-
</section>
-
-
-
<!--===============================================================-->
-
-
<section xml:id="sec-user-management"><title>User management</title>
-
-
<para>NixOS supports both declarative and imperative styles of user
-
management. In the declarative style, users are specified in
-
<filename>configuration.nix</filename>. For instance, the following
-
states that a user account named <literal>alice</literal> shall exist:
-
-
<programlisting>
-
users.extraUsers.alice =
-
{ createHome = true;
-
home = "/home/alice";
-
description = "Alice Foobar";
-
extraGroups = [ "wheel" "networkmanager" ];
-
useDefaultShell = true;
-
openssh.authorizedKeys.keys = [ "ssh-dss AAAAB3Nza... alice@foobar" ];
-
};
-
</programlisting>
-
-
Note that <literal>alice</literal> is a member of the
-
<literal>wheel</literal> and <literal>networkmanager</literal> groups,
-
which allows her to use <command>sudo</command> to execute commands as
-
<literal>root</literal> and to configure the network, respectively.
-
Also note the SSH public key that allows remote logins with the
-
corresponding private key. Users created in this way do not have a
-
password by default, so they cannot log in via mechanisms that require
-
a password. However, you can use the <command>passwd</command> program
-
to set a password, which is retained across invocations of
-
<command>nixos-rebuild</command>.</para>
-
-
<para>If you set users.mutableUsers to false, then the contents of /etc/passwd
-
and /etc/group will be congruent to your NixOS configuration. For instance,
-
if you remove a user from users.extraUsers and run nixos-rebuild, the user
-
account will cease to exist. Also, imperative commands for managing users
-
and groups, such as useradd, are no longer available.</para>
-
-
<para>A user ID (uid) is assigned automatically. You can also specify
-
a uid manually by adding
-
-
<programlisting>
-
uid = 1000;
-
</programlisting>
-
-
to the user specification.</para>
-
-
<para>Groups can be specified similarly. The following states that a
-
group named <literal>students</literal> shall exist:
-
-
<programlisting>
-
users.extraGroups.students.gid = 1000;
-
</programlisting>
-
-
As with users, the group ID (gid) is optional and will be assigned
-
automatically if it’s missing.</para>
-
-
<warning><para>Currently declarative user management is not perfect:
-
<command>nixos-rebuild</command> does not know how to realise certain
-
configuration changes. This includes removing a user or group, and
-
removing group membership from a user.</para></warning>
-
-
<para>In the imperative style, users and groups are managed by
-
commands such as <command>useradd</command>,
-
<command>groupmod</command> and so on. For instance, to create a user
-
account named <literal>alice</literal>:
-
-
<screen>
-
$ useradd -m alice</screen>
-
-
The flag <option>-m</option> causes the creation of a home directory
-
for the new user, which is generally what you want. The user does not
-
have an initial password and therefore cannot log in. A password can
-
be set using the <command>passwd</command> utility:
-
-
<screen>
-
$ passwd alice
-
Enter new UNIX password: ***
-
Retype new UNIX password: ***
-
</screen>
-
-
A user can be deleted using <command>userdel</command>:
-
-
<screen>
-
$ userdel -r alice</screen>
-
-
The flag <option>-r</option> deletes the user’s home directory.
-
Accounts can be modified using <command>usermod</command>. Unix
-
groups can be managed using <command>groupadd</command>,
-
<command>groupmod</command> and <command>groupdel</command>.</para>
-
-
</section>
-
-
-
<!--===============================================================-->
-
-
<section><title>File systems</title>
-
-
<para>You can define file systems using the
-
<option>fileSystems</option> configuration option. For instance, the
-
following definition causes NixOS to mount the Ext4 file system on
-
device <filename>/dev/disk/by-label/data</filename> onto the mount
-
point <filename>/data</filename>:
-
-
<programlisting>
-
fileSystems."/data" =
-
{ device = "/dev/disk/by-label/data";
-
fsType = "ext4";
-
};
-
</programlisting>
-
-
Mount points are created automatically if they don’t already exist.
-
For <option>device</option>, it’s best to use the topology-independent
-
device aliases in <filename>/dev/disk/by-label</filename> and
-
<filename>/dev/disk/by-uuid</filename>, as these don’t change if the
-
topology changes (e.g. if a disk is moved to another IDE
-
controller).</para>
-
-
<para>You can usually omit the file system type
-
(<option>fsType</option>), since <command>mount</command> can usually
-
detect the type and load the necessary kernel module automatically.
-
However, if the file system is needed at early boot (in the initial
-
ramdisk) and is not <literal>ext2</literal>, <literal>ext3</literal>
-
or <literal>ext4</literal>, then it’s best to specify
-
<option>fsType</option> to ensure that the kernel module is
-
available.</para>
-
-
<section><title>LUKS-encrypted file systems</title>
-
-
<para>NixOS supports file systems that are encrypted using
-
<emphasis>LUKS</emphasis> (Linux Unified Key Setup). For example,
-
here is how you create an encrypted Ext4 file system on the device
-
<filename>/dev/sda2</filename>:
-
-
<screen>
-
$ cryptsetup luksFormat /dev/sda2
-
-
WARNING!
-
========
-
This will overwrite data on /dev/sda2 irrevocably.
-
-
Are you sure? (Type uppercase yes): YES
-
Enter LUKS passphrase: ***
-
Verify passphrase: ***
-
-
$ cryptsetup luksOpen /dev/sda2 crypted
-
Enter passphrase for /dev/sda2: ***
-
-
$ mkfs.ext4 /dev/mapper/crypted
-
</screen>
-
-
To ensure that this file system is automatically mounted at boot time
-
as <filename>/</filename>, add the following to
-
<filename>configuration.nix</filename>:
-
-
<programlisting>
-
boot.initrd.luks.devices = [ { device = "/dev/sda2"; name = "crypted"; } ];
-
fileSystems."/".device = "/dev/mapper/crypted";
-
</programlisting>
-
-
</para>
-
-
</section>
-
-
</section>
-
-
-
<!--===============================================================-->
-
-
<section xml:id="sec-x11"><title>X Window System</title>
-
-
<para>The X Window System (X11) provides the basis of NixOS’ graphical
-
user interface. It can be enabled as follows:
-
<programlisting>
-
services.xserver.enable = true;
-
</programlisting>
-
The X server will automatically detect and use the appropriate video
-
driver from a set of X.org drivers (such as <literal>vesa</literal>
-
and <literal>intel</literal>). You can also specify a driver
-
manually, e.g.
-
<programlisting>
-
services.xserver.videoDrivers = [ "r128" ];
-
</programlisting>
-
to enable X.org’s <literal>xf86-video-r128</literal> driver.</para>
-
-
<para>You also need to enable at least one desktop or window manager.
-
Otherwise, you can only log into a plain undecorated
-
<command>xterm</command> window. Thus you should pick one or more of
-
the following lines:
-
<programlisting>
-
services.xserver.desktopManager.kde4.enable = true;
-
services.xserver.desktopManager.xfce.enable = true;
-
services.xserver.windowManager.xmonad.enable = true;
-
services.xserver.windowManager.twm.enable = true;
-
services.xserver.windowManager.icewm.enable = true;
-
</programlisting>
-
</para>
-
-
<para>NixOS’s default <emphasis>display manager</emphasis> (the
-
program that provides a graphical login prompt and manages the X
-
server) is SLiM. You can select KDE’s <command>kdm</command> instead:
-
<programlisting>
-
services.xserver.displayManager.kdm.enable = true;
-
</programlisting>
-
</para>
-
-
<para>The X server is started automatically at boot time. If you
-
don’t want this to happen, you can set:
-
<programlisting>
-
services.xserver.autorun = false;
-
</programlisting>
-
The X server can then be started manually:
-
<screen>
-
$ systemctl start display-manager.service
-
</screen>
-
</para>
-
-
-
<section><title>NVIDIA graphics cards</title>
-
-
<para>NVIDIA provides a proprietary driver for its graphics cards that
-
has better 3D performance than the X.org drivers. It is not enabled
-
by default because it’s not free software. You can enable it as follows:
-
<programlisting>
-
services.xserver.videoDrivers = [ "nvidia" ];
-
</programlisting>
-
You may need to reboot after enabling this driver to prevent a clash
-
with other kernel modules.</para>
-
-
<para>On 64-bit systems, if you want full acceleration for 32-bit
-
programs such as Wine, you should also set the following:
-
<programlisting>
-
services.xserver.driSupport32Bit = true;
-
</programlisting>
-
</para>
-
-
</section>
-
-
-
<section><title>Touchpads</title>
-
-
<para>Support for Synaptics touchpads (found in many laptops such as
-
the Dell Latitude series) can be enabled as follows:
-
<programlisting>
-
services.xserver.synaptics.enable = true;
-
</programlisting>
-
The driver has many options (see <xref linkend="ch-options"/>). For
-
instance, the following enables two-finger scrolling:
-
<programlisting>
-
services.xserver.synaptics.twoFingerScroll = true;
-
</programlisting>
-
</para>
-
-
</section>
-
-
-
</section>
-
-
-
<!--===============================================================-->
-
-
<section xml:id="sec-networking"><title>Networking</title>
-
-
<section xml:id="sec-networkmanager"><title>NetworkManager</title>
-
-
<para>To facilitate network configuration, some desktop environments
-
use NetworkManager. You can enable NetworkManager by setting:
-
-
<programlisting>
-
services.networkmanager.enable = true;
-
</programlisting>
-
-
Some desktop managers (e.g., GNOME) enable NetworkManager
-
automatically for you.</para>
-
-
<para>All users that should have permission to change network settings
-
must belong to the <code>networkmanager</code> group.</para>
-
-
<note><para><code>services.networkmanager</code> and
-
<code>services.wireless</code> can not be enabled at the same time:
-
you can still connect to the wireless networks using
-
NetworkManager.</para></note>
-
-
</section>
-
-
<section xml:id="sec-ssh"><title>Secure shell access</title>
-
-
<para>Secure shell (SSH) access to your machine can be enabled by
-
setting:
-
-
<programlisting>
-
services.openssh.enable = true;
-
</programlisting>
-
-
By default, root logins using a password are disallowed. They can be
-
disabled entirely by setting
-
<literal>services.openssh.permitRootLogin</literal> to
-
<literal>"no"</literal>.</para>
-
-
<para>You can declaratively specify authorised RSA/DSA public keys for
-
a user as follows:
-
-
<!-- FIXME: this might not work if the user is unmanaged. -->
-
<programlisting>
-
users.extraUsers.alice.openssh.authorizedKeys.keys =
-
[ "ssh-dss AAAAB3NzaC1kc3MAAACBAPIkGWVEt4..." ];
-
</programlisting>
-
-
</para>
-
-
</section>
-
-
-
<section xml:id="sec-ipv4"><title>IPv4 configuration</title>
-
-
<para>By default, NixOS uses DHCP (specifically,
-
<command>dhcpcd</command>) to automatically configure network
-
interfaces. However, you can configure an interface manually as
-
follows:
-
-
<programlisting>
-
networking.interfaces.eth0 = { ipAddress = "192.168.1.2"; prefixLength = 24; };
-
</programlisting>
-
-
(The network prefix can also be specified using the option
-
<literal>subnetMask</literal>,
-
e.g. <literal>"255.255.255.0"</literal>, but this is deprecated.)
-
Typically you’ll also want to set a default gateway and set of name
-
servers:
-
-
<programlisting>
-
networking.defaultGateway = "192.168.1.1";
-
networking.nameservers = [ "8.8.8.8" ];
-
</programlisting>
-
-
</para>
-
-
<note><para>Statically configured interfaces are set up by the systemd
-
service
-
<replaceable>interface-name</replaceable><literal>-cfg.service</literal>.
-
The default gateway and name server configuration is performed by
-
<literal>network-setup.service</literal>.</para></note>
-
-
<para>The host name is set using <option>networking.hostName</option>:
-
-
<programlisting>
-
networking.hostName = "cartman";
-
</programlisting>
-
-
The default host name is <literal>nixos</literal>. Set it to the
-
empty string (<literal>""</literal>) to allow the DHCP server to
-
provide the host name.</para>
-
-
</section>
-
-
-
<section xml:id="sec-ipv6"><title>IPv6 configuration</title>
-
-
<para>IPv6 is enabled by default. Stateless address autoconfiguration
-
is used to automatically assign IPv6 addresses to all interfaces. You
-
can disable IPv6 support globally by setting:
-
-
<programlisting>
-
networking.enableIPv6 = false;
-
</programlisting>
-
-
</para>
-
-
</section>
-
-
-
<section xml:id="sec-firewall"><title>Firewall</title>
-
-
<para>NixOS has a simple stateful firewall that blocks incoming
-
connections and other unexpected packets. The firewall applies to
-
both IPv4 and IPv6 traffic. It is enabled by default. It can be
-
disabled as follows:
-
-
<programlisting>
-
networking.firewall.enable = false;
-
</programlisting>
-
-
If the firewall is enabled, you can open specific TCP ports to the
-
outside world:
-
-
<programlisting>
-
networking.firewall.allowedTCPPorts = [ 80 443 ];
-
</programlisting>
-
-
Note that TCP port 22 (ssh) is opened automatically if the SSH daemon
-
is enabled (<option>services.openssh.enable = true</option>). UDP
-
ports can be opened through
-
<option>networking.firewall.allowedUDPPorts</option>. Also of
-
interest is
-
-
<programlisting>
-
networking.firewall.allowPing = true;
-
</programlisting>
-
-
to allow the machine to respond to ping requests. (ICMPv6 pings are
-
always allowed.)</para>
-
-
</section>
-
-
-
<section xml:id="sec-wireless"><title>Wireless networks</title>
-
-
<para>For a desktop installation using NetworkManager (e.g., GNOME),
-
you just have to make sure the user is in the
-
<code>networkmanager</code> group and you can skip the rest of this
-
section on wireless networks.</para>
-
-
<para>
-
NixOS will start wpa_supplicant for you if you enable this setting:
-
-
<programlisting>
-
networking.wireless.enable = true;
-
</programlisting>
-
-
NixOS currently does not generate wpa_supplicant's
-
configuration file, <literal>/etc/wpa_supplicant.conf</literal>. You should edit this file
-
yourself to define wireless networks, WPA keys and so on (see
-
wpa_supplicant.conf(5)).
-
</para>
-
-
<para>
-
If you are using WPA2 the <command>wpa_passphrase</command> tool might be useful
-
to generate the <literal>wpa_supplicant.conf</literal>.
-
-
<screen>
-
$ wpa_passphrase ESSID PSK > /etc/wpa_supplicant.conf</screen>
-
-
After you have edited the <literal>wpa_supplicant.conf</literal>,
-
you need to restart the wpa_supplicant service.
-
-
<screen>
-
$ systemctl restart wpa_supplicant.service</screen>
-
</para>
-
-
-
</section>
-
-
-
<section><title>Ad-hoc configuration</title>
-
-
<para>You can use <option>networking.localCommands</option> to specify
-
shell commands to be run at the end of
-
<literal>network-setup.service</literal>. This is useful for doing
-
network configuration not covered by the existing NixOS modules. For
-
instance, to statically configure an IPv6 address:
-
-
<programlisting>
-
networking.localCommands =
-
''
-
ip -6 addr add 2001:610:685:1::1/64 dev eth0
-
'';
-
</programlisting>
-
-
</para>
-
-
</section>
-
-
-
<!-- TODO: OpenVPN, NAT -->
-
-
-
</section>
-
-
-
<!--===============================================================-->
-
-
<section xml:id="sec-kernel-config"><title>Linux kernel</title>
-
-
<para>You can override the Linux kernel and associated packages using
-
the option <option>boot.kernelPackages</option>. For instance, this
-
selects the Linux 3.10 kernel:
-
<programlisting>
-
boot.kernelPackages = pkgs.linuxPackages_3_10;
-
</programlisting>
-
Note that this not only replaces the kernel, but also packages that
-
are specific to the kernel version, such as the NVIDIA video drivers.
-
This ensures that driver packages are consistent with the
-
kernel.</para>
-
-
<para>The default Linux kernel configuration should be fine for most users. You can see the configuration of your current kernel with the following command:
-
<programlisting>
-
cat /proc/config.gz | gunzip
-
</programlisting>
-
If you want to change the kernel configuration, you can use the
-
<option>packageOverrides</option> feature (see <xref
-
linkend="sec-customising-packages" />). For instance, to enable
-
support for the kernel debugger KGDB:
-
-
<programlisting>
-
nixpkgs.config.packageOverrides = pkgs:
-
{ linux_3_4 = pkgs.linux_3_4.override {
-
extraConfig =
-
''
-
KGDB y
-
'';
-
};
-
};
-
</programlisting>
-
-
<varname>extraConfig</varname> takes a list of Linux kernel
-
configuration options, one per line. The name of the option should
-
not include the prefix <literal>CONFIG_</literal>. The option value
-
is typically <literal>y</literal>, <literal>n</literal> or
-
<literal>m</literal> (to build something as a kernel module).</para>
-
-
<para>Kernel modules for hardware devices are generally loaded
-
automatically by <command>udev</command>. You can force a module to
-
be loaded via <option>boot.kernelModules</option>, e.g.
-
<programlisting>
-
boot.kernelModules = [ "fuse" "kvm-intel" "coretemp" ];
-
</programlisting>
-
If the module is required early during the boot (e.g. to mount the
-
root file system), you can use
-
<option>boot.initrd.extraKernelModules</option>:
-
<programlisting>
-
boot.initrd.extraKernelModules = [ "cifs" ];
-
</programlisting>
-
This causes the specified modules and their dependencies to be added
-
to the initial ramdark.</para>
-
-
<para>Kernel runtime parameters can be set through
-
<option>boot.kernel.sysctl</option>, e.g.
-
<programlisting>
-
boot.kernel.sysctl."net.ipv4.tcp_keepalive_time" = 120;
-
</programlisting>
-
sets the kernel’s TCP keepalive time to 120 seconds. To see the
-
available parameters, run <command>sysctl -a</command>.</para>
-
-
</section>
-
-
-
<!-- Apache; libvirtd virtualisation -->
-
-
-
</chapter>
···
+42
nixos/doc/manual/configuration/LUKS-file-systems.xml
···
···
+
<section xmlns="http://docbook.org/ns/docbook"
+
xmlns:xlink="http://www.w3.org/1999/xlink"
+
xmlns:xi="http://www.w3.org/2001/XInclude"
+
version="5.0"
+
xml:id="sec-luks-file-systems">
+
+
<title>LUKS-Encrypted File Systems</title>
+
+
<para>NixOS supports file systems that are encrypted using
+
<emphasis>LUKS</emphasis> (Linux Unified Key Setup). For example,
+
here is how you create an encrypted Ext4 file system on the device
+
<filename>/dev/sda2</filename>:
+
+
<screen>
+
$ cryptsetup luksFormat /dev/sda2
+
+
WARNING!
+
========
+
This will overwrite data on /dev/sda2 irrevocably.
+
+
Are you sure? (Type uppercase yes): YES
+
Enter LUKS passphrase: ***
+
Verify passphrase: ***
+
+
$ cryptsetup luksOpen /dev/sda2 crypted
+
Enter passphrase for /dev/sda2: ***
+
+
$ mkfs.ext4 /dev/mapper/crypted
+
</screen>
+
+
To ensure that this file system is automatically mounted at boot time
+
as <filename>/</filename>, add the following to
+
<filename>configuration.nix</filename>:
+
+
<programlisting>
+
boot.initrd.luks.devices = [ { device = "/dev/sda2"; name = "crypted"; } ];
+
fileSystems."/".device = "/dev/mapper/crypted";
+
</programlisting>
+
+
</para>
+
+
</section>
+166
nixos/doc/manual/configuration/abstractions.xml
···
···
+
<section xmlns="http://docbook.org/ns/docbook"
+
xmlns:xlink="http://www.w3.org/1999/xlink"
+
xmlns:xi="http://www.w3.org/2001/XInclude"
+
version="5.0"
+
xml:id="sec-module-abstractions">
+
+
<title>Abstractions</title>
+
+
<para>If you find yourself repeating yourself over and over, it’s time
+
to abstract. Take, for instance, this Apache HTTP Server configuration:
+
+
<programlisting>
+
{
+
services.httpd.virtualHosts =
+
[ { hostName = "example.org";
+
documentRoot = "/webroot";
+
adminAddr = "alice@example.org";
+
enableUserDir = true;
+
}
+
{ hostName = "example.org";
+
documentRoot = "/webroot";
+
adminAddr = "alice@example.org";
+
enableUserDir = true;
+
enableSSL = true;
+
sslServerCert = "/root/ssl-example-org.crt";
+
sslServerKey = "/root/ssl-example-org.key";
+
}
+
];
+
}
+
</programlisting>
+
+
It defines two virtual hosts with nearly identical configuration; the
+
only difference is that the second one has SSL enabled. To prevent
+
this duplication, we can use a <literal>let</literal>:
+
+
<programlisting>
+
let
+
exampleOrgCommon =
+
{ hostName = "example.org";
+
documentRoot = "/webroot";
+
adminAddr = "alice@example.org";
+
enableUserDir = true;
+
};
+
in
+
{
+
services.httpd.virtualHosts =
+
[ exampleOrgCommon
+
(exampleOrgCommon // {
+
enableSSL = true;
+
sslServerCert = "/root/ssl-example-org.crt";
+
sslServerKey = "/root/ssl-example-org.key";
+
})
+
];
+
}
+
</programlisting>
+
+
The <literal>let exampleOrgCommon =
+
<replaceable>...</replaceable></literal> defines a variable named
+
<literal>exampleOrgCommon</literal>. The <literal>//</literal>
+
operator merges two attribute sets, so the configuration of the second
+
virtual host is the set <literal>exampleOrgCommon</literal> extended
+
with the SSL options.</para>
+
+
<para>You can write a <literal>let</literal> wherever an expression is
+
allowed. Thus, you also could have written:
+
+
<programlisting>
+
{
+
services.httpd.virtualHosts =
+
let exampleOrgCommon = <replaceable>...</replaceable>; in
+
[ exampleOrgCommon
+
(exampleOrgCommon // { <replaceable>...</replaceable> })
+
];
+
}
+
</programlisting>
+
+
but not <literal>{ let exampleOrgCommon =
+
<replaceable>...</replaceable>; in <replaceable>...</replaceable>;
+
}</literal> since attributes (as opposed to attribute values) are not
+
expressions.</para>
+
+
<para><emphasis>Functions</emphasis> provide another method of
+
abstraction. For instance, suppose that we want to generate lots of
+
different virtual hosts, all with identical configuration except for
+
the host name. This can be done as follows:
+
+
<programlisting>
+
{
+
services.httpd.virtualHosts =
+
let
+
makeVirtualHost = name:
+
{ hostName = name;
+
documentRoot = "/webroot";
+
adminAddr = "alice@example.org";
+
};
+
in
+
[ (makeVirtualHost "example.org")
+
(makeVirtualHost "example.com")
+
(makeVirtualHost "example.gov")
+
(makeVirtualHost "example.nl")
+
];
+
}
+
</programlisting>
+
+
Here, <varname>makeVirtualHost</varname> is a function that takes a
+
single argument <literal>name</literal> and returns the configuration
+
for a virtual host. That function is then called for several names to
+
produce the list of virtual host configurations.</para>
+
+
<para>We can further improve on this by using the function
+
<varname>map</varname>, which applies another function to every
+
element in a list:
+
+
<programlisting>
+
{
+
services.httpd.virtualHosts =
+
let
+
makeVirtualHost = <replaceable>...</replaceable>;
+
in map makeVirtualHost
+
[ "example.org" "example.com" "example.gov" "example.nl" ];
+
}
+
</programlisting>
+
+
(The function <literal>map</literal> is called a
+
<emphasis>higher-order function</emphasis> because it takes another
+
function as an argument.)</para>
+
+
<para>What if you need more than one argument, for instance, if we
+
want to use a different <literal>documentRoot</literal> for each
+
virtual host? Then we can make <varname>makeVirtualHost</varname> a
+
function that takes a <emphasis>set</emphasis> as its argument, like this:
+
+
<programlisting>
+
{
+
services.httpd.virtualHosts =
+
let
+
makeVirtualHost = { name, root }:
+
{ hostName = name;
+
documentRoot = root;
+
adminAddr = "alice@example.org";
+
};
+
in map makeVirtualHost
+
[ { name = "example.org"; root = "/sites/example.org"; }
+
{ name = "example.com"; root = "/sites/example.com"; }
+
{ name = "example.gov"; root = "/sites/example.gov"; }
+
{ name = "example.nl"; root = "/sites/example.nl"; }
+
];
+
}
+
</programlisting>
+
+
But in this case (where every root is a subdirectory of
+
<filename>/sites</filename> named after the virtual host), it would
+
have been shorter to define <varname>makeVirtualHost</varname> as
+
<programlisting>
+
makeVirtualHost = name:
+
{ hostName = name;
+
documentRoot = "/sites/${name}";
+
adminAddr = "alice@example.org";
+
};
+
</programlisting>
+
+
Here, the construct
+
<literal>${<replaceable>...</replaceable>}</literal> allows the result
+
of an expression to be spliced into a string.</para>
+
+
</section>
+24
nixos/doc/manual/configuration/ad-hoc-network-config.xml
···
···
+
<section xmlns="http://docbook.org/ns/docbook"
+
xmlns:xlink="http://www.w3.org/1999/xlink"
+
xmlns:xi="http://www.w3.org/2001/XInclude"
+
version="5.0"
+
xml:id="ad-hoc-network-config">
+
+
<title>Ad-Hoc Configuration</title>
+
+
<para>You can use <option>networking.localCommands</option> to specify
+
shell commands to be run at the end of
+
<literal>network-setup.service</literal>. This is useful for doing
+
network configuration not covered by the existing NixOS modules. For
+
instance, to statically configure an IPv6 address:
+
+
<programlisting>
+
networking.localCommands =
+
''
+
ip -6 addr add 2001:610:685:1::1/64 dev eth0
+
'';
+
</programlisting>
+
+
</para>
+
+
</section>
+63
nixos/doc/manual/configuration/ad-hoc-packages.xml
···
···
+
<section xmlns="http://docbook.org/ns/docbook"
+
xmlns:xlink="http://www.w3.org/1999/xlink"
+
xmlns:xi="http://www.w3.org/2001/XInclude"
+
version="5.0"
+
xml:id="sec-ad-hoc-packages">
+
+
<title>Ad-Hoc Package Management</title>
+
+
<para>With the command <command>nix-env</command>, you can install and
+
uninstall packages from the command line. For instance, to install
+
Mozilla Thunderbird:
+
+
<screen>
+
$ nix-env -iA nixos.pkgs.thunderbird</screen>
+
+
If you invoke this as root, the package is installed in the Nix
+
profile <filename>/nix/var/nix/profiles/default</filename> and visible
+
to all users of the system; otherwise, the package ends up in
+
<filename>/nix/var/nix/profiles/per-user/<replaceable>username</replaceable>/profile</filename>
+
and is not visible to other users. The <option>-A</option> flag
+
specifies the package by its attribute name; without it, the package
+
is installed by matching against its package name
+
(e.g. <literal>thunderbird</literal>). The latter is slower because
+
it requires matching against all available Nix packages, and is
+
ambiguous if there are multiple matching packages.</para>
+
+
<para>Packages come from the NixOS channel. You typically upgrade a
+
package by updating to the latest version of the NixOS channel:
+
<screen>
+
$ nix-channel --update nixos
+
</screen>
+
and then running <literal>nix-env -i</literal> again. Other packages
+
in the profile are <emphasis>not</emphasis> affected; this is the
+
crucial difference with the declarative style of package management,
+
where running <command>nixos-rebuild switch</command> causes all
+
packages to be updated to their current versions in the NixOS channel.
+
You can however upgrade all packages for which there is a newer
+
version by doing:
+
<screen>
+
$ nix-env -u '*'
+
</screen>
+
</para>
+
+
<para>A package can be uninstalled using the <option>-e</option>
+
flag:
+
<screen>
+
$ nix-env -e thunderbird
+
</screen>
+
</para>
+
+
<para>Finally, you can roll back an undesirable
+
<command>nix-env</command> action:
+
<screen>
+
$ nix-env --rollback
+
</screen>
+
</para>
+
+
<para><command>nix-env</command> has many more flags. For details,
+
see the
+
<citerefentry><refentrytitle>nix-env</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+
manpage or the Nix manual.</para>
+
+
</section>
+84
nixos/doc/manual/configuration/adding-custom-packages.xml
···
···
+
<section xmlns="http://docbook.org/ns/docbook"
+
xmlns:xlink="http://www.w3.org/1999/xlink"
+
xmlns:xi="http://www.w3.org/2001/XInclude"
+
version="5.0"
+
xml:id="sec-custom-packages">
+
+
<title>Adding Custom Packages</title>
+
+
<para>It’s possible that a package you need is not available in NixOS.
+
In that case, you can do two things. First, you can clone the Nixpkgs
+
repository, add the package to your clone, and (optionally) submit a
+
patch or pull request to have it accepted into the main Nixpkgs
+
repository. This is described in detail in the <link
+
xlink:href="http://nixos.org/nixpkgs/manual">Nixpkgs manual</link>.
+
In short, you clone Nixpkgs:
+
+
<screen>
+
$ git clone git://github.com/NixOS/nixpkgs.git
+
$ cd nixpkgs
+
</screen>
+
+
Then you write and test the package as described in the Nixpkgs
+
manual. Finally, you add it to
+
<literal>environment.systemPackages</literal>, e.g.
+
+
<programlisting>
+
environment.systemPackages = [ pkgs.my-package ];
+
</programlisting>
+
+
and you run <command>nixos-rebuild</command>, specifying your own
+
Nixpkgs tree:
+
+
<screen>
+
$ nixos-rebuild switch -I nixpkgs=/path/to/my/nixpkgs</screen>
+
+
</para>
+
+
<para>The second possibility is to add the package outside of the
+
Nixpkgs tree. For instance, here is how you specify a build of the
+
<link xlink:href="http://www.gnu.org/software/hello/">GNU Hello</link>
+
package directly in <filename>configuration.nix</filename>:
+
+
<programlisting>
+
environment.systemPackages =
+
let
+
my-hello = with pkgs; stdenv.mkDerivation rec {
+
name = "hello-2.8";
+
src = fetchurl {
+
url = "mirror://gnu/hello/${name}.tar.gz";
+
sha256 = "0wqd8sjmxfskrflaxywc7gqw7sfawrfvdxd9skxawzfgyy0pzdz6";
+
};
+
};
+
in
+
[ my-hello ];
+
</programlisting>
+
+
Of course, you can also move the definition of
+
<literal>my-hello</literal> into a separate Nix expression, e.g.
+
<programlisting>
+
environment.systemPackages = [ (import ./my-hello.nix) ];
+
</programlisting>
+
where <filename>my-hello.nix</filename> contains:
+
<programlisting>
+
with import &lt;nixpkgs> {}; # bring all of Nixpkgs into scope
+
+
stdenv.mkDerivation rec {
+
name = "hello-2.8";
+
src = fetchurl {
+
url = "mirror://gnu/hello/${name}.tar.gz";
+
sha256 = "0wqd8sjmxfskrflaxywc7gqw7sfawrfvdxd9skxawzfgyy0pzdz6";
+
};
+
}
+
</programlisting>
+
+
This allows testing the package easily:
+
<screen>
+
$ nix-build my-hello.nix
+
$ ./result/bin/hello
+
Hello, world!
+
</screen>
+
+
</para>
+
+
</section>
+213
nixos/doc/manual/configuration/config-file.xml
···
···
+
<section xmlns="http://docbook.org/ns/docbook"
+
xmlns:xlink="http://www.w3.org/1999/xlink"
+
xmlns:xi="http://www.w3.org/2001/XInclude"
+
version="5.0"
+
xml:id="sec-configuration-file">
+
+
<title>NixOS Configuration File</title>
+
+
<para>The NixOS configuration file generally looks like this:
+
+
<programlisting>
+
{ config, pkgs, ... }:
+
+
{ <replaceable>option definitions</replaceable>
+
}
+
</programlisting>
+
+
The first line (<literal>{ config, pkgs, ... }:</literal>) denotes
+
that this is actually a function that takes at least the two arguments
+
<varname>config</varname> and <varname>pkgs</varname>. (These are
+
explained later.) The function returns a <emphasis>set</emphasis> of
+
option definitions (<literal>{ <replaceable>...</replaceable> }</literal>). These definitions have the
+
form <literal><replaceable>name</replaceable> =
+
<replaceable>value</replaceable></literal>, where
+
<replaceable>name</replaceable> is the name of an option and
+
<replaceable>value</replaceable> is its value. For example,
+
+
<programlisting>
+
{ config, pkgs, ... }:
+
+
{ services.httpd.enable = true;
+
services.httpd.adminAddr = "alice@example.org";
+
services.httpd.documentRoot = "/webroot";
+
}
+
</programlisting>
+
+
defines a configuration with three option definitions that together
+
enable the Apache HTTP Server with <filename>/webroot</filename> as
+
the document root.</para>
+
+
<para>Sets can be nested, and in fact dots in option names are
+
shorthand for defining a set containing another set. For instance,
+
<option>services.httpd.enable</option> defines a set named
+
<varname>services</varname> that contains a set named
+
<varname>httpd</varname>, which in turn contains an option definition
+
named <varname>enable</varname> with value <literal>true</literal>.
+
This means that the example above can also be written as:
+
+
<programlisting>
+
{ config, pkgs, ... }:
+
+
{ services = {
+
httpd = {
+
enable = true;
+
adminAddr = "alice@example.org";
+
documentRoot = "/webroot";
+
};
+
};
+
}
+
</programlisting>
+
+
which may be more convenient if you have lots of option definitions
+
that share the same prefix (such as
+
<literal>services.httpd</literal>).</para>
+
+
<para>NixOS checks your option definitions for correctness. For
+
instance, if you try to define an option that doesn’t exist (that is,
+
doesn’t have a corresponding <emphasis>option declaration</emphasis>),
+
<command>nixos-rebuild</command> will give an error like:
+
<screen>
+
The option `services.httpd.enabl' defined in `/etc/nixos/configuration.nix' does not exist.
+
</screen>
+
Likewise, values in option definitions must have a correct type. For
+
instance, <option>services.httpd.enable</option> must be a Boolean
+
(<literal>true</literal> or <literal>false</literal>). Trying to give
+
it a value of another type, such as a string, will cause an error:
+
<screen>
+
The option value `services.httpd.enable' in `/etc/nixos/configuration.nix' is not a boolean.
+
</screen>
+
+
</para>
+
+
<para>Options have various types of values. The most important are:
+
+
<variablelist>
+
<varlistentry>
+
<term>Strings</term>
+
<listitem>
+
<para>Strings are enclosed in double quotes, e.g.
+
+
<programlisting>
+
networking.hostName = "dexter";
+
</programlisting>
+
+
Special characters can be escaped by prefixing them with a
+
backslash (e.g. <literal>\"</literal>).</para>
+
+
<para>Multi-line strings can be enclosed in <emphasis>double
+
single quotes</emphasis>, e.g.
+
+
<programlisting>
+
networking.extraHosts =
+
''
+
127.0.0.2 other-localhost
+
10.0.0.1 server
+
'';
+
</programlisting>
+
+
The main difference is that preceding whitespace is
+
automatically stripped from each line, and that characters like
+
<literal>"</literal> and <literal>\</literal> are not special
+
(making it more convenient for including things like shell
+
code).</para>
+
</listitem>
+
</varlistentry>
+
+
<varlistentry>
+
<term>Booleans</term>
+
<listitem>
+
<para>These can be <literal>true</literal> or
+
<literal>false</literal>, e.g.
+
+
<programlisting>
+
networking.firewall.enable = true;
+
networking.firewall.allowPing = false;
+
</programlisting>
+
</para>
+
</listitem>
+
</varlistentry>
+
+
<varlistentry>
+
<term>Integers</term>
+
<listitem>
+
<para>For example,
+
+
<programlisting>
+
boot.kernel.sysctl."net.ipv4.tcp_keepalive_time" = 60;
+
</programlisting>
+
+
(Note that here the attribute name
+
<literal>net.ipv4.tcp_keepalive_time</literal> is enclosed in
+
quotes to prevent it from being interpreted as a set named
+
<literal>net</literal> containing a set named
+
<literal>ipv4</literal>, and so on. This is because it’s not a
+
NixOS option but the literal name of a Linux kernel
+
setting.)</para>
+
</listitem>
+
</varlistentry>
+
+
<varlistentry>
+
<term>Sets</term>
+
<listitem>
+
<para>Sets were introduced above. They are name/value pairs
+
enclosed in braces, as in the option definition
+
+
<programlisting>
+
fileSystems."/boot" =
+
{ device = "/dev/sda1";
+
fsType = "ext4";
+
options = "rw,data=ordered,relatime";
+
};
+
</programlisting>
+
</para>
+
</listitem>
+
</varlistentry>
+
+
<varlistentry>
+
<term>Lists</term>
+
<listitem>
+
<para>The important thing to note about lists is that list
+
elements are separated by whitespace, like this:
+
+
<programlisting>
+
boot.kernelModules = [ "fuse" "kvm-intel" "coretemp" ];
+
</programlisting>
+
+
List elements can be any other type, e.g. sets:
+
+
<programlisting>
+
swapDevices = [ { device = "/dev/disk/by-label/swap"; } ];
+
</programlisting>
+
</para>
+
</listitem>
+
</varlistentry>
+
+
<varlistentry>
+
<term>Packages</term>
+
<listitem>
+
<para>Usually, the packages you need are already part of the Nix
+
Packages collection, which is a set that can be accessed through
+
the function argument <varname>pkgs</varname>. Typical uses:
+
+
<programlisting>
+
environment.systemPackages =
+
[ pkgs.thunderbird
+
pkgs.emacs
+
];
+
+
postgresql.package = pkgs.postgresql90;
+
</programlisting>
+
+
The latter option definition changes the default PostgreSQL
+
package used by NixOS’s PostgreSQL service to 9.0. For more
+
information on packages, including how to add new ones, see
+
<xref linkend="sec-custom-packages"/>.</para>
+
</listitem>
+
</varlistentry>
+
+
</variablelist>
+
+
</para>
+
+
</section>
+27
nixos/doc/manual/configuration/config-syntax.xml
···
···
+
<chapter xmlns="http://docbook.org/ns/docbook"
+
xmlns:xlink="http://www.w3.org/1999/xlink"
+
xmlns:xi="http://www.w3.org/2001/XInclude"
+
version="5.0"
+
xml:id="sec-configuration-syntax">
+
+
<title>Configuration Syntax</title>
+
+
<para>The NixOS configuration file
+
<filename>/etc/nixos/configuration.nix</filename> is actually a
+
<emphasis>Nix expression</emphasis>, which is the Nix package
+
manager’s purely functional language for describing how to build
+
packages and configurations. This means you have all the expressive
+
power of that language at your disposal, including the ability to
+
abstract over common patterns, which is very useful when managing
+
complex systems. The syntax and semantics of the Nix language are
+
fully described in the <link
+
xlink:href="http://nixos.org/nix/manual/#chap-writing-nix-expressions">Nix
+
manual</link>, but here we give a short overview of the most important
+
constructs useful in NixOS configuration files.</para>
+
+
<xi:include href="config-file.xml" />
+
<xi:include href="abstractions.xml" />
+
<xi:include href="modularity.xml" />
+
<xi:include href="summary.xml" />
+
+
</chapter>
+29
nixos/doc/manual/configuration/configuration.xml
···
···
+
<part xmlns="http://docbook.org/ns/docbook"
+
xmlns:xlink="http://www.w3.org/1999/xlink"
+
xmlns:xi="http://www.w3.org/2001/XInclude"
+
version="5.0"
+
xml:id="ch-configuration">
+
+
<title>Configuration</title>
+
+
<partintro>
+
+
<para>This chapter describes how to configure various aspects of a
+
NixOS machine through the configuration file
+
<filename>/etc/nixos/configuration.nix</filename>. As described in
+
<xref linkend="sec-changing-config" />, changes to this file only take
+
effect after you run <command>nixos-rebuild</command>.</para>
+
+
</partintro>
+
+
<xi:include href="config-syntax.xml" />
+
<xi:include href="package-mgmt.xml" />
+
<xi:include href="user-mgmt.xml" />
+
<xi:include href="file-systems.xml" />
+
<xi:include href="x-windows.xml" />
+
<xi:include href="networking.xml" />
+
<xi:include href="linux-kernel.xml" />
+
+
<!-- Apache; libvirtd virtualisation -->
+
+
</part>
+92
nixos/doc/manual/configuration/customizing-packages.xml
···
···
+
<section xmlns="http://docbook.org/ns/docbook"
+
xmlns:xlink="http://www.w3.org/1999/xlink"
+
xmlns:xi="http://www.w3.org/2001/XInclude"
+
version="5.0"
+
xml:id="sec-customising-packages">
+
+
<title>Customising Packages</title>
+
+
<para>Some packages in Nixpkgs have options to enable or disable
+
optional functionality or change other aspects of the package. For
+
instance, the Firefox wrapper package (which provides Firefox with a
+
set of plugins such as the Adobe Flash player) has an option to enable
+
the Google Talk plugin. It can be set in
+
<filename>configuration.nix</filename> as follows:
+
+
<filename>
+
nixpkgs.config.firefox.enableGoogleTalkPlugin = true;
+
</filename>
+
</para>
+
+
<warning><para>Unfortunately, Nixpkgs currently lacks a way to query
+
available configuration options.</para></warning>
+
+
<para>Apart from high-level options, it’s possible to tweak a package
+
in almost arbitrary ways, such as changing or disabling dependencies
+
of a package. For instance, the Emacs package in Nixpkgs by default
+
has a dependency on GTK+ 2. If you want to build it against GTK+ 3,
+
you can specify that as follows:
+
+
<programlisting>
+
environment.systemPackages = [ (pkgs.emacs.override { gtk = pkgs.gtk3; }) ];
+
</programlisting>
+
+
The function <varname>override</varname> performs the call to the Nix
+
function that produces Emacs, with the original arguments amended by
+
the set of arguments specified by you. So here the function argument
+
<varname>gtk</varname> gets the value <literal>pkgs.gtk3</literal>,
+
causing Emacs to depend on GTK+ 3. (The parentheses are necessary
+
because in Nix, function application binds more weakly than list
+
construction, so without them,
+
<literal>environment.systemPackages</literal> would be a list with two
+
elements.)</para>
+
+
<para>Even greater customisation is possible using the function
+
<varname>overrideDerivation</varname>. While the
+
<varname>override</varname> mechanism above overrides the arguments of
+
a package function, <varname>overrideDerivation</varname> allows
+
changing the <emphasis>result</emphasis> of the function. This
+
permits changing any aspect of the package, such as the source code.
+
For instance, if you want to override the source code of Emacs, you
+
can say:
+
+
<programlisting>
+
environment.systemPackages =
+
[ (pkgs.lib.overrideDerivation pkgs.emacs (attrs: {
+
name = "emacs-25.0-pre";
+
src = /path/to/my/emacs/tree;
+
}))
+
];
+
</programlisting>
+
+
Here, <varname>overrideDerivation</varname> takes the Nix derivation
+
specified by <varname>pkgs.emacs</varname> and produces a new
+
derivation in which the original’s <literal>name</literal> and
+
<literal>src</literal> attribute have been replaced by the given
+
values. The original attributes are accessible via
+
<varname>attrs</varname>.</para>
+
+
<para>The overrides shown above are not global. They do not affect
+
the original package; other packages in Nixpkgs continue to depend on
+
the original rather than the customised package. This means that if
+
another package in your system depends on the original package, you
+
end up with two instances of the package. If you want to have
+
everything depend on your customised instance, you can apply a
+
<emphasis>global</emphasis> override as follows:
+
+
<screen>
+
nixpkgs.config.packageOverrides = pkgs:
+
{ emacs = pkgs.emacs.override { gtk = pkgs.gtk3; };
+
};
+
</screen>
+
+
The effect of this definition is essentially equivalent to modifying
+
the <literal>emacs</literal> attribute in the Nixpkgs source tree.
+
Any package in Nixpkgs that depends on <literal>emacs</literal> will
+
be passed your customised instance. (However, the value
+
<literal>pkgs.emacs</literal> in
+
<varname>nixpkgs.config.packageOverrides</varname> refers to the
+
original rather than overridden instance, to prevent an infinite
+
recursion.)</para>
+
+
</section>
+43
nixos/doc/manual/configuration/declarative-packages.xml
···
···
+
<section xmlns="http://docbook.org/ns/docbook"
+
xmlns:xlink="http://www.w3.org/1999/xlink"
+
xmlns:xi="http://www.w3.org/2001/XInclude"
+
version="5.0"
+
xml:id="sec-declarative-package-mgmt">
+
+
<title>Declarative Package Management</title>
+
+
<para>With declarative package management, you specify which packages
+
you want on your system by setting the option
+
<option>environment.systemPackages</option>. For instance, adding the
+
following line to <filename>configuration.nix</filename> enables the
+
Mozilla Thunderbird email application:
+
+
<programlisting>
+
environment.systemPackages = [ pkgs.thunderbird ];
+
</programlisting>
+
+
The effect of this specification is that the Thunderbird package from
+
Nixpkgs will be built or downloaded as part of the system when you run
+
<command>nixos-rebuild switch</command>.</para>
+
+
<para>You can get a list of the available packages as follows:
+
<screen>
+
$ nix-env -qaP '*' --description
+
nixos.pkgs.firefox firefox-23.0 Mozilla Firefox - the browser, reloaded
+
<replaceable>...</replaceable>
+
</screen>
+
+
The first column in the output is the <emphasis>attribute
+
name</emphasis>, such as
+
<literal>nixos.pkgs.thunderbird</literal>. (The
+
<literal>nixos</literal> prefix allows distinguishing between
+
different channels that you might have.)</para>
+
+
<para>To “uninstall” a package, simply remove it from
+
<option>environment.systemPackages</option> and run
+
<command>nixos-rebuild switch</command>.</para>
+
+
<xi:include href="customizing-packages.xml" />
+
<xi:include href="adding-custom-packages.xml" />
+
+
</section>
+40
nixos/doc/manual/configuration/file-systems.xml
···
···
+
<chapter xmlns="http://docbook.org/ns/docbook"
+
xmlns:xlink="http://www.w3.org/1999/xlink"
+
xmlns:xi="http://www.w3.org/2001/XInclude"
+
version="5.0"
+
xml:id="ch-file-systems">
+
+
<title>File Systems</title>
+
+
<para>You can define file systems using the
+
<option>fileSystems</option> configuration option. For instance, the
+
following definition causes NixOS to mount the Ext4 file system on
+
device <filename>/dev/disk/by-label/data</filename> onto the mount
+
point <filename>/data</filename>:
+
+
<programlisting>
+
fileSystems."/data" =
+
{ device = "/dev/disk/by-label/data";
+
fsType = "ext4";
+
};
+
</programlisting>
+
+
Mount points are created automatically if they don’t already exist.
+
For <option>device</option>, it’s best to use the topology-independent
+
device aliases in <filename>/dev/disk/by-label</filename> and
+
<filename>/dev/disk/by-uuid</filename>, as these don’t change if the
+
topology changes (e.g. if a disk is moved to another IDE
+
controller).</para>
+
+
<para>You can usually omit the file system type
+
(<option>fsType</option>), since <command>mount</command> can usually
+
detect the type and load the necessary kernel module automatically.
+
However, if the file system is needed at early boot (in the initial
+
ramdisk) and is not <literal>ext2</literal>, <literal>ext3</literal>
+
or <literal>ext4</literal>, then it’s best to specify
+
<option>fsType</option> to ensure that the kernel module is
+
available.</para>
+
+
<xi:include href="LUKS-file-systems.xml" />
+
+
</chapter>
+38
nixos/doc/manual/configuration/firewall.xml
···
···
+
<section xmlns="http://docbook.org/ns/docbook"
+
xmlns:xlink="http://www.w3.org/1999/xlink"
+
xmlns:xi="http://www.w3.org/2001/XInclude"
+
version="5.0"
+
xml:id="sec-firewall">
+
+
<title>Firewall</title>
+
+
<para>NixOS has a simple stateful firewall that blocks incoming
+
connections and other unexpected packets. The firewall applies to
+
both IPv4 and IPv6 traffic. It is enabled by default. It can be
+
disabled as follows:
+
+
<programlisting>
+
networking.firewall.enable = false;
+
</programlisting>
+
+
If the firewall is enabled, you can open specific TCP ports to the
+
outside world:
+
+
<programlisting>
+
networking.firewall.allowedTCPPorts = [ 80 443 ];
+
</programlisting>
+
+
Note that TCP port 22 (ssh) is opened automatically if the SSH daemon
+
is enabled (<option>services.openssh.enable = true</option>). UDP
+
ports can be opened through
+
<option>networking.firewall.allowedUDPPorts</option>. Also of
+
interest is
+
+
<programlisting>
+
networking.firewall.allowPing = true;
+
</programlisting>
+
+
to allow the machine to respond to ping requests. (ICMPv6 pings are
+
always allowed.)</para>
+
+
</section>
+47
nixos/doc/manual/configuration/ipv4-config.xml
···
···
+
<section xmlns="http://docbook.org/ns/docbook"
+
xmlns:xlink="http://www.w3.org/1999/xlink"
+
xmlns:xi="http://www.w3.org/2001/XInclude"
+
version="5.0"
+
xml:id="sec-ipv4">
+
+
<title>IPv4 Configuration</title>
+
+
<para>By default, NixOS uses DHCP (specifically,
+
<command>dhcpcd</command>) to automatically configure network
+
interfaces. However, you can configure an interface manually as
+
follows:
+
+
<programlisting>
+
networking.interfaces.eth0 = { ipAddress = "192.168.1.2"; prefixLength = 24; };
+
</programlisting>
+
+
(The network prefix can also be specified using the option
+
<literal>subnetMask</literal>,
+
e.g. <literal>"255.255.255.0"</literal>, but this is deprecated.)
+
Typically you’ll also want to set a default gateway and set of name
+
servers:
+
+
<programlisting>
+
networking.defaultGateway = "192.168.1.1";
+
networking.nameservers = [ "8.8.8.8" ];
+
</programlisting>
+
+
</para>
+
+
<note><para>Statically configured interfaces are set up by the systemd
+
service
+
<replaceable>interface-name</replaceable><literal>-cfg.service</literal>.
+
The default gateway and name server configuration is performed by
+
<literal>network-setup.service</literal>.</para></note>
+
+
<para>The host name is set using <option>networking.hostName</option>:
+
+
<programlisting>
+
networking.hostName = "cartman";
+
</programlisting>
+
+
The default host name is <literal>nixos</literal>. Set it to the
+
empty string (<literal>""</literal>) to allow the DHCP server to
+
provide the host name.</para>
+
+
</section>
+19
nixos/doc/manual/configuration/ipv6-config.xml
···
···
+
<section xmlns="http://docbook.org/ns/docbook"
+
xmlns:xlink="http://www.w3.org/1999/xlink"
+
xmlns:xi="http://www.w3.org/2001/XInclude"
+
version="5.0"
+
xml:id="sec-ipv6">
+
+
<title>IPv6 Configuration</title>
+
+
<para>IPv6 is enabled by default. Stateless address autoconfiguration
+
is used to automatically assign IPv6 addresses to all interfaces. You
+
can disable IPv6 support globally by setting:
+
+
<programlisting>
+
networking.enableIPv6 = false;
+
</programlisting>
+
+
</para>
+
+
</section>
+69
nixos/doc/manual/configuration/linux-kernel.xml
···
···
+
<chapter xmlns="http://docbook.org/ns/docbook"
+
xmlns:xlink="http://www.w3.org/1999/xlink"
+
xmlns:xi="http://www.w3.org/2001/XInclude"
+
version="5.0"
+
xml:id="sec-kernel-config">
+
+
<title>Linux Kernel</title>
+
+
<para>You can override the Linux kernel and associated packages using
+
the option <option>boot.kernelPackages</option>. For instance, this
+
selects the Linux 3.10 kernel:
+
<programlisting>
+
boot.kernelPackages = pkgs.linuxPackages_3_10;
+
</programlisting>
+
Note that this not only replaces the kernel, but also packages that
+
are specific to the kernel version, such as the NVIDIA video drivers.
+
This ensures that driver packages are consistent with the
+
kernel.</para>
+
+
<para>The default Linux kernel configuration should be fine for most users. You can see the configuration of your current kernel with the following command:
+
<programlisting>
+
cat /proc/config.gz | gunzip
+
</programlisting>
+
If you want to change the kernel configuration, you can use the
+
<option>packageOverrides</option> feature (see <xref
+
linkend="sec-customising-packages" />). For instance, to enable
+
support for the kernel debugger KGDB:
+
+
<programlisting>
+
nixpkgs.config.packageOverrides = pkgs:
+
{ linux_3_4 = pkgs.linux_3_4.override {
+
extraConfig =
+
''
+
KGDB y
+
'';
+
};
+
};
+
</programlisting>
+
+
<varname>extraConfig</varname> takes a list of Linux kernel
+
configuration options, one per line. The name of the option should
+
not include the prefix <literal>CONFIG_</literal>. The option value
+
is typically <literal>y</literal>, <literal>n</literal> or
+
<literal>m</literal> (to build something as a kernel module).</para>
+
+
<para>Kernel modules for hardware devices are generally loaded
+
automatically by <command>udev</command>. You can force a module to
+
be loaded via <option>boot.kernelModules</option>, e.g.
+
<programlisting>
+
boot.kernelModules = [ "fuse" "kvm-intel" "coretemp" ];
+
</programlisting>
+
If the module is required early during the boot (e.g. to mount the
+
root file system), you can use
+
<option>boot.initrd.extraKernelModules</option>:
+
<programlisting>
+
boot.initrd.extraKernelModules = [ "cifs" ];
+
</programlisting>
+
This causes the specified modules and their dependencies to be added
+
to the initial ramdark.</para>
+
+
<para>Kernel runtime parameters can be set through
+
<option>boot.kernel.sysctl</option>, e.g.
+
<programlisting>
+
boot.kernel.sysctl."net.ipv4.tcp_keepalive_time" = 120;
+
</programlisting>
+
sets the kernel’s TCP keepalive time to 120 seconds. To see the
+
available parameters, run <command>sysctl -a</command>.</para>
+
+
</chapter>
+143
nixos/doc/manual/configuration/modularity.xml
···
···
+
<section xmlns="http://docbook.org/ns/docbook"
+
xmlns:xlink="http://www.w3.org/1999/xlink"
+
xmlns:xi="http://www.w3.org/2001/XInclude"
+
version="5.0"
+
xml:id="sec-modularity">
+
+
<title>Modularity</title>
+
+
<para>The NixOS configuration mechanism is modular. If your
+
<filename>configuration.nix</filename> becomes too big, you can split
+
it into multiple files. Likewise, if you have multiple NixOS
+
configurations (e.g. for different computers) with some commonality,
+
you can move the common configuration into a shared file.</para>
+
+
<para>Modules have exactly the same syntax as
+
<filename>configuration.nix</filename>. In fact,
+
<filename>configuration.nix</filename> is itself a module. You can
+
use other modules by including them from
+
<filename>configuration.nix</filename>, e.g.:
+
+
<programlisting>
+
{ config, pkgs, ... }:
+
+
{ imports = [ ./vpn.nix ./kde.nix ];
+
services.httpd.enable = true;
+
environment.systemPackages = [ pkgs.emacs ];
+
<replaceable>...</replaceable>
+
}
+
</programlisting>
+
+
Here, we include two modules from the same directory,
+
<filename>vpn.nix</filename> and <filename>kde.nix</filename>. The
+
latter might look like this:
+
+
<programlisting>
+
{ config, pkgs, ... }:
+
+
{ services.xserver.enable = true;
+
services.xserver.displayManager.kdm.enable = true;
+
services.xserver.desktopManager.kde4.enable = true;
+
environment.systemPackages = [ pkgs.kde4.kscreensaver ];
+
}
+
</programlisting>
+
+
Note that both <filename>configuration.nix</filename> and
+
<filename>kde.nix</filename> define the option
+
<option>environment.systemPackages</option>. When multiple modules
+
define an option, NixOS will try to <emphasis>merge</emphasis> the
+
definitions. In the case of
+
<option>environment.systemPackages</option>, that’s easy: the lists of
+
packages can simply be concatenated. The value in
+
<filename>configuration.nix</filename> is merged last, so for
+
list-type options, it will appear at the end of the merged list. If
+
you want it to appear first, you can use <varname>mkBefore</varname>:
+
+
<programlisting>
+
boot.kernelModules = mkBefore [ "kvm-intel" ];
+
</programlisting>
+
+
This causes the <literal>kvm-intel</literal> kernel module to be
+
loaded before any other kernel modules.</para>
+
+
<para>For other types of options, a merge may not be possible. For
+
instance, if two modules define
+
<option>services.httpd.adminAddr</option>,
+
<command>nixos-rebuild</command> will give an error:
+
+
<screen>
+
The unique option `services.httpd.adminAddr' is defined multiple times, in `/etc/nixos/httpd.nix' and `/etc/nixos/configuration.nix'.
+
</screen>
+
+
When that happens, it’s possible to force one definition take
+
precedence over the others:
+
+
<programlisting>
+
services.httpd.adminAddr = pkgs.lib.mkForce "bob@example.org";
+
</programlisting>
+
+
</para>
+
+
<para>When using multiple modules, you may need to access
+
configuration values defined in other modules. This is what the
+
<varname>config</varname> function argument is for: it contains the
+
complete, merged system configuration. That is,
+
<varname>config</varname> is the result of combining the
+
configurations returned by every module<footnote><para>If you’re
+
wondering how it’s possible that the (indirect)
+
<emphasis>result</emphasis> of a function is passed as an
+
<emphasis>input</emphasis> to that same function: that’s because Nix
+
is a “lazy” language — it only computes values when they are needed.
+
This works as long as no individual configuration value depends on
+
itself.</para></footnote>. For example, here is a module that adds
+
some packages to <option>environment.systemPackages</option> only if
+
<option>services.xserver.enable</option> is set to
+
<literal>true</literal> somewhere else:
+
+
<programlisting>
+
{ config, pkgs, ... }:
+
+
{ environment.systemPackages =
+
if config.services.xserver.enable then
+
[ pkgs.firefox
+
pkgs.thunderbird
+
]
+
else
+
[ ];
+
}
+
</programlisting>
+
+
</para>
+
+
<para>With multiple modules, it may not be obvious what the final
+
value of a configuration option is. The command
+
<option>nixos-option</option> allows you to find out:
+
+
<screen>
+
$ nixos-option services.xserver.enable
+
true
+
+
$ nixos-option boot.kernelModules
+
[ "tun" "ipv6" "loop" <replaceable>...</replaceable> ]
+
</screen>
+
+
Interactive exploration of the configuration is possible using
+
<command
+
xlink:href="https://github.com/edolstra/nix-repl">nix-repl</command>,
+
a read-eval-print loop for Nix expressions. It’s not installed by
+
default; run <literal>nix-env -i nix-repl</literal> to get it. A
+
typical use:
+
+
<screen>
+
$ nix-repl '&lt;nixos>'
+
+
nix-repl> config.networking.hostName
+
"mandark"
+
+
nix-repl> map (x: x.hostName) config.services.httpd.virtualHosts
+
[ "example.org" "example.gov" ]
+
</screen>
+
+
</para>
+
+
</section>
+27
nixos/doc/manual/configuration/network-manager.xml
···
···
+
<section xmlns="http://docbook.org/ns/docbook"
+
xmlns:xlink="http://www.w3.org/1999/xlink"
+
xmlns:xi="http://www.w3.org/2001/XInclude"
+
version="5.0"
+
xml:id="sec-networkmanager">
+
+
<title>NetworkManager</title>
+
+
<para>To facilitate network configuration, some desktop environments
+
use NetworkManager. You can enable NetworkManager by setting:
+
+
<programlisting>
+
services.networkmanager.enable = true;
+
</programlisting>
+
+
Some desktop managers (e.g., GNOME) enable NetworkManager
+
automatically for you.</para>
+
+
<para>All users that should have permission to change network settings
+
must belong to the <code>networkmanager</code> group.</para>
+
+
<note><para><code>services.networkmanager</code> and
+
<code>services.wireless</code> can not be enabled at the same time:
+
you can still connect to the wireless networks using
+
NetworkManager.</para></note>
+
+
</section>
+22
nixos/doc/manual/configuration/networking.xml
···
···
+
<chapter xmlns="http://docbook.org/ns/docbook"
+
xmlns:xlink="http://www.w3.org/1999/xlink"
+
xmlns:xi="http://www.w3.org/2001/XInclude"
+
version="5.0"
+
xml:id="sec-networking">
+
+
<title>Networking</title>
+
+
<para>This section describes how to configure networking components on
+
your NixOS machine.</para>
+
+
<xi:include href="network-manager.xml" />
+
<xi:include href="ssh.xml" />
+
<xi:include href="ipv4-config.xml" />
+
<xi:include href="ipv6-config.xml" />
+
<xi:include href="firewall.xml" />
+
<xi:include href="wireless.xml" />
+
<xi:include href="ad-hoc-network-config.xml" />
+
+
<!-- TODO: OpenVPN, NAT -->
+
+
</chapter>
+34
nixos/doc/manual/configuration/package-mgmt.xml
···
···
+
<chapter xmlns="http://docbook.org/ns/docbook"
+
xmlns:xlink="http://www.w3.org/1999/xlink"
+
xmlns:xi="http://www.w3.org/2001/XInclude"
+
version="5.0"
+
xml:id="sec-package-management">
+
+
<title>Package Management</title>
+
+
<para>This section describes how to add additional packages to your
+
system. NixOS has two distinct styles of package management:
+
+
<itemizedlist>
+
+
<listitem><para><emphasis>Declarative</emphasis>, where you declare
+
what packages you want in your
+
<filename>configuration.nix</filename>. Every time you run
+
<command>nixos-rebuild</command>, NixOS will ensure that you get a
+
consistent set of binaries corresponding to your
+
specification.</para></listitem>
+
+
<listitem><para><emphasis>Ad hoc</emphasis>, where you install,
+
upgrade and uninstall packages via the <command>nix-env</command>
+
command. This style allows mixing packages from different Nixpkgs
+
versions. It’s the only choice for non-root
+
users.</para></listitem>
+
+
</itemizedlist>
+
+
</para>
+
+
<xi:include href="declarative-packages.xml" />
+
<xi:include href="ad-hoc-packages.xml" />
+
+
</chapter>
+32
nixos/doc/manual/configuration/ssh.xml
···
···
+
<section xmlns="http://docbook.org/ns/docbook"
+
xmlns:xlink="http://www.w3.org/1999/xlink"
+
xmlns:xi="http://www.w3.org/2001/XInclude"
+
version="5.0"
+
xml:id="sec-ssh">
+
+
<title>Secure Shell Access</title>
+
+
<para>Secure shell (SSH) access to your machine can be enabled by
+
setting:
+
+
<programlisting>
+
services.openssh.enable = true;
+
</programlisting>
+
+
By default, root logins using a password are disallowed. They can be
+
disabled entirely by setting
+
<literal>services.openssh.permitRootLogin</literal> to
+
<literal>"no"</literal>.</para>
+
+
<para>You can declaratively specify authorised RSA/DSA public keys for
+
a user as follows:
+
+
<!-- FIXME: this might not work if the user is unmanaged. -->
+
<programlisting>
+
users.extraUsers.alice.openssh.authorizedKeys.keys =
+
[ "ssh-dss AAAAB3NzaC1kc3MAAACBAPIkGWVEt4..." ];
+
</programlisting>
+
+
</para>
+
+
</section>
+191
nixos/doc/manual/configuration/summary.xml
···
···
+
<section xmlns="http://docbook.org/ns/docbook"
+
xmlns:xlink="http://www.w3.org/1999/xlink"
+
xmlns:xi="http://www.w3.org/2001/XInclude"
+
version="5.0"
+
xml:id="sec-nix-syntax-summary">
+
+
<title>Syntax Summary</title>
+
+
<para>Below is a summary of the most important syntactic constructs in
+
the Nix expression language. It’s not complete. In particular, there
+
are many other built-in functions. See the <link
+
xlink:href="http://nixos.org/nix/manual/#chap-writing-nix-expressions">Nix
+
manual</link> for the rest.</para>
+
+
<informaltable frame='none'>
+
<tgroup cols='2'>
+
<colspec colname='c1' rowsep='1' colsep='1' />
+
<colspec colname='c2' rowsep='1' />
+
<thead>
+
<row>
+
<entry>Example</entry>
+
<entry>Description</entry>
+
</row>
+
</thead>
+
<tbody>
+
+
<row>
+
<entry namest="c1" nameend="c2"><emphasis>Basic values</emphasis></entry>
+
</row>
+
<row>
+
<entry><literal>"Hello world"</literal></entry>
+
<entry>A string</entry>
+
</row>
+
<row>
+
<entry><literal>"${pkgs.bash}/bin/sh"</literal></entry>
+
<entry>A string containing an expression (expands to <literal>"/nix/store/<replaceable>hash</replaceable>-bash-<replaceable>version</replaceable>/bin/sh"</literal>)</entry>
+
</row>
+
<row>
+
<entry><literal>true</literal>, <literal>false</literal></entry>
+
<entry>Booleans</entry>
+
</row>
+
<row>
+
<entry><literal>123</literal></entry>
+
<entry>An integer</entry>
+
</row>
+
<row>
+
<entry><literal>./foo.png</literal></entry>
+
<entry>A path (relative to the containing Nix expression)</entry>
+
</row>
+
+
<row>
+
<entry namest="c1" nameend="c2"><emphasis>Compound values</emphasis></entry>
+
</row>
+
<row>
+
<entry><literal>{ x = 1; y = 2; }</literal></entry>
+
<entry>An set with attributes names <literal>x</literal> and <literal>y</literal></entry>
+
</row>
+
<row>
+
<entry><literal>{ foo.bar = 1; }</literal></entry>
+
<entry>A nested set, equivalent to <literal>{ foo = { bar = 1; }; }</literal></entry>
+
</row>
+
<row>
+
<entry><literal>rec { x = "bla"; y = x + "bar"; }</literal></entry>
+
<entry>A recursive set, equivalent to <literal>{ x = "foo"; y = "foobar"; }</literal></entry>
+
</row>
+
<row>
+
<entry><literal>[ "foo" "bar" ]</literal></entry>
+
<entry>A list with two elements</entry>
+
</row>
+
+
<row>
+
<entry namest="c1" nameend="c2"><emphasis>Operators</emphasis></entry>
+
</row>
+
<row>
+
<entry><literal>"foo" + "bar"</literal></entry>
+
<entry>String concatenation</entry>
+
</row>
+
<row>
+
<entry><literal>1 + 2</literal></entry>
+
<entry>Integer addition</entry>
+
</row>
+
<row>
+
<entry><literal>"foo" == "f" + "oo"</literal></entry>
+
<entry>Equality test (evaluates to <literal>true</literal>)</entry>
+
</row>
+
<row>
+
<entry><literal>"foo" != "bar"</literal></entry>
+
<entry>Inequality test (evaluates to <literal>true</literal>)</entry>
+
</row>
+
<row>
+
<entry><literal>!true</literal></entry>
+
<entry>Boolean negation</entry>
+
</row>
+
<row>
+
<entry><literal>{ x = 1; y = 2; }.x</literal></entry>
+
<entry>Attribute selection (evaluates to <literal>1</literal>)</entry>
+
</row>
+
<row>
+
<entry><literal>{ x = 1; y = 2; }.z or 3</literal></entry>
+
<entry>Attribute selection with default (evaluates to <literal>3</literal>)</entry>
+
</row>
+
<row>
+
<entry><literal>{ x = 1; y = 2; } // { z = 3; }</literal></entry>
+
<entry>Merge two sets (attributes in the right-hand set taking precedence)</entry>
+
</row>
+
+
<row>
+
<entry namest="c1" nameend="c2"><emphasis>Control structures</emphasis></entry>
+
</row>
+
<row>
+
<entry><literal>if 1 + 1 == 2 then "yes!" else "no!"</literal></entry>
+
<entry>Conditional expression</entry>
+
</row>
+
<row>
+
<entry><literal>assert 1 + 1 == 2; "yes!"</literal></entry>
+
<entry>Assertion check (evaluates to <literal>"yes!"</literal>)</entry>
+
</row>
+
<row>
+
<entry><literal>let x = "foo"; y = "bar"; in x + y</literal></entry>
+
<entry>Variable definition</entry>
+
</row>
+
<row>
+
<entry><literal>with pkgs.lib; head [ 1 2 3 ]</literal></entry>
+
<entry>Add all attributes from the given set to the scope
+
(evaluates to <literal>1</literal>)</entry>
+
</row>
+
+
<row>
+
<entry namest="c1" nameend="c2"><emphasis>Functions (lambdas)</emphasis></entry>
+
</row>
+
<row>
+
<entry><literal>x: x + 1</literal></entry>
+
<entry>A function that expects an integer and returns it increased by 1</entry>
+
</row>
+
<row>
+
<entry><literal>(x: x + 1) 100</literal></entry>
+
<entry>A function call (evaluates to 101)</entry>
+
</row>
+
<row>
+
<entry><literal>let inc = x: x + 1; in inc (inc (inc 100))</literal></entry>
+
<entry>A function bound to a variable and subsequently called by name (evaluates to 103)</entry>
+
</row>
+
<row>
+
<entry><literal>{ x, y }: x + y</literal></entry>
+
<entry>A function that expects a set with required attributes
+
<literal>x</literal> and <literal>y</literal> and concatenates
+
them</entry>
+
</row>
+
<row>
+
<entry><literal>{ x, y ? "bar" }: x + y</literal></entry>
+
<entry>A function that expects a set with required attribute
+
<literal>x</literal> and optional <literal>y</literal>, using
+
<literal>"bar"</literal> as default value for
+
<literal>y</literal></entry>
+
</row>
+
<row>
+
<entry><literal>{ x, y, ... }: x + y</literal></entry>
+
<entry>A function that expects a set with required attributes
+
<literal>x</literal> and <literal>y</literal> and ignores any
+
other attributes</entry>
+
</row>
+
<row>
+
<entry><literal>{ x, y } @ args: x + y</literal></entry>
+
<entry>A function that expects a set with required attributes
+
<literal>x</literal> and <literal>y</literal>, and binds the
+
whole set to <literal>args</literal></entry>
+
</row>
+
+
<row>
+
<entry namest="c1" nameend="c2"><emphasis>Built-in functions</emphasis></entry>
+
</row>
+
<row>
+
<entry><literal>import ./foo.nix</literal></entry>
+
<entry>Load and return Nix expression in given file</entry>
+
</row>
+
<row>
+
<entry><literal>map (x: x + x) [ 1 2 3 ]</literal></entry>
+
<entry>Apply a function to every element of a list (evaluates to <literal>[ 2 4 6 ]</literal>)</entry>
+
</row>
+
<!--
+
<row>
+
<entry><literal>throw "Urgh"</literal></entry>
+
<entry>Raise an error condition</entry>
+
</row>
+
-->
+
+
</tbody>
+
</tgroup>
+
</informaltable>
+
+
</section>
+95
nixos/doc/manual/configuration/user-mgmt.xml
···
···
+
<chapter xmlns="http://docbook.org/ns/docbook"
+
xmlns:xlink="http://www.w3.org/1999/xlink"
+
xmlns:xi="http://www.w3.org/2001/XInclude"
+
version="5.0"
+
xml:id="sec-user-management">
+
+
<title>User Management</title>
+
+
<para>NixOS supports both declarative and imperative styles of user
+
management. In the declarative style, users are specified in
+
<filename>configuration.nix</filename>. For instance, the following
+
states that a user account named <literal>alice</literal> shall exist:
+
+
<programlisting>
+
users.extraUsers.alice =
+
{ createHome = true;
+
home = "/home/alice";
+
description = "Alice Foobar";
+
extraGroups = [ "wheel" "networkmanager" ];
+
useDefaultShell = true;
+
openssh.authorizedKeys.keys = [ "ssh-dss AAAAB3Nza... alice@foobar" ];
+
};
+
</programlisting>
+
+
Note that <literal>alice</literal> is a member of the
+
<literal>wheel</literal> and <literal>networkmanager</literal> groups,
+
which allows her to use <command>sudo</command> to execute commands as
+
<literal>root</literal> and to configure the network, respectively.
+
Also note the SSH public key that allows remote logins with the
+
corresponding private key. Users created in this way do not have a
+
password by default, so they cannot log in via mechanisms that require
+
a password. However, you can use the <command>passwd</command> program
+
to set a password, which is retained across invocations of
+
<command>nixos-rebuild</command>.</para>
+
+
<para>If you set users.mutableUsers to false, then the contents of /etc/passwd
+
and /etc/group will be congruent to your NixOS configuration. For instance,
+
if you remove a user from users.extraUsers and run nixos-rebuild, the user
+
account will cease to exist. Also, imperative commands for managing users
+
and groups, such as useradd, are no longer available.</para>
+
+
<para>A user ID (uid) is assigned automatically. You can also specify
+
a uid manually by adding
+
+
<programlisting>
+
uid = 1000;
+
</programlisting>
+
+
to the user specification.</para>
+
+
<para>Groups can be specified similarly. The following states that a
+
group named <literal>students</literal> shall exist:
+
+
<programlisting>
+
users.extraGroups.students.gid = 1000;
+
</programlisting>
+
+
As with users, the group ID (gid) is optional and will be assigned
+
automatically if it’s missing.</para>
+
+
<warning><para>Currently declarative user management is not perfect:
+
<command>nixos-rebuild</command> does not know how to realise certain
+
configuration changes. This includes removing a user or group, and
+
removing group membership from a user.</para></warning>
+
+
<para>In the imperative style, users and groups are managed by
+
commands such as <command>useradd</command>,
+
<command>groupmod</command> and so on. For instance, to create a user
+
account named <literal>alice</literal>:
+
+
<screen>
+
$ useradd -m alice</screen>
+
+
The flag <option>-m</option> causes the creation of a home directory
+
for the new user, which is generally what you want. The user does not
+
have an initial password and therefore cannot log in. A password can
+
be set using the <command>passwd</command> utility:
+
+
<screen>
+
$ passwd alice
+
Enter new UNIX password: ***
+
Retype new UNIX password: ***
+
</screen>
+
+
A user can be deleted using <command>userdel</command>:
+
+
<screen>
+
$ userdel -r alice</screen>
+
+
The flag <option>-r</option> deletes the user’s home directory.
+
Accounts can be modified using <command>usermod</command>. Unix
+
groups can be managed using <command>groupadd</command>,
+
<command>groupmod</command> and <command>groupdel</command>.</para>
+
+
</chapter>
+41
nixos/doc/manual/configuration/wireless.xml
···
···
+
<section xmlns="http://docbook.org/ns/docbook"
+
xmlns:xlink="http://www.w3.org/1999/xlink"
+
xmlns:xi="http://www.w3.org/2001/XInclude"
+
version="5.0"
+
xml:id="sec-wireless">
+
+
<title>Wireless Networks</title>
+
+
<para>For a desktop installation using NetworkManager (e.g., GNOME),
+
you just have to make sure the user is in the
+
<code>networkmanager</code> group and you can skip the rest of this
+
section on wireless networks.</para>
+
+
<para>
+
NixOS will start wpa_supplicant for you if you enable this setting:
+
+
<programlisting>
+
networking.wireless.enable = true;
+
</programlisting>
+
+
NixOS currently does not generate wpa_supplicant's
+
configuration file, <literal>/etc/wpa_supplicant.conf</literal>. You should edit this file
+
yourself to define wireless networks, WPA keys and so on (see
+
wpa_supplicant.conf(5)).
+
</para>
+
+
<para>
+
If you are using WPA2 the <command>wpa_passphrase</command> tool might be useful
+
to generate the <literal>wpa_supplicant.conf</literal>.
+
+
<screen>
+
$ wpa_passphrase ESSID PSK > /etc/wpa_supplicant.conf</screen>
+
+
After you have edited the <literal>wpa_supplicant.conf</literal>,
+
you need to restart the wpa_supplicant service.
+
+
<screen>
+
$ systemctl restart wpa_supplicant.service</screen>
+
</para>
+
+
</section>
+94
nixos/doc/manual/configuration/x-windows.xml
···
···
+
<chapter xmlns="http://docbook.org/ns/docbook"
+
xmlns:xlink="http://www.w3.org/1999/xlink"
+
xmlns:xi="http://www.w3.org/2001/XInclude"
+
version="5.0"
+
xml:id="sec-x11">
+
+
<title>X Window System</title>
+
+
<para>The X Window System (X11) provides the basis of NixOS’ graphical
+
user interface. It can be enabled as follows:
+
<programlisting>
+
services.xserver.enable = true;
+
</programlisting>
+
The X server will automatically detect and use the appropriate video
+
driver from a set of X.org drivers (such as <literal>vesa</literal>
+
and <literal>intel</literal>). You can also specify a driver
+
manually, e.g.
+
<programlisting>
+
services.xserver.videoDrivers = [ "r128" ];
+
</programlisting>
+
to enable X.org’s <literal>xf86-video-r128</literal> driver.</para>
+
+
<para>You also need to enable at least one desktop or window manager.
+
Otherwise, you can only log into a plain undecorated
+
<command>xterm</command> window. Thus you should pick one or more of
+
the following lines:
+
<programlisting>
+
services.xserver.desktopManager.kde4.enable = true;
+
services.xserver.desktopManager.xfce.enable = true;
+
services.xserver.windowManager.xmonad.enable = true;
+
services.xserver.windowManager.twm.enable = true;
+
services.xserver.windowManager.icewm.enable = true;
+
</programlisting>
+
</para>
+
+
<para>NixOS’s default <emphasis>display manager</emphasis> (the
+
program that provides a graphical login prompt and manages the X
+
server) is SLiM. You can select KDE’s <command>kdm</command> instead:
+
<programlisting>
+
services.xserver.displayManager.kdm.enable = true;
+
</programlisting>
+
</para>
+
+
<para>The X server is started automatically at boot time. If you
+
don’t want this to happen, you can set:
+
<programlisting>
+
services.xserver.autorun = false;
+
</programlisting>
+
The X server can then be started manually:
+
<screen>
+
$ systemctl start display-manager.service
+
</screen>
+
</para>
+
+
+
<simplesect><title>NVIDIA Graphics Cards</title>
+
+
<para>NVIDIA provides a proprietary driver for its graphics cards that
+
has better 3D performance than the X.org drivers. It is not enabled
+
by default because it’s not free software. You can enable it as follows:
+
<programlisting>
+
services.xserver.videoDrivers = [ "nvidia" ];
+
</programlisting>
+
You may need to reboot after enabling this driver to prevent a clash
+
with other kernel modules.</para>
+
+
<para>On 64-bit systems, if you want full acceleration for 32-bit
+
programs such as Wine, you should also set the following:
+
<programlisting>
+
services.xserver.driSupport32Bit = true;
+
</programlisting>
+
</para>
+
+
</simplesect>
+
+
+
<simplesect><title>Touchpads</title>
+
+
<para>Support for Synaptics touchpads (found in many laptops such as
+
the Dell Latitude series) can be enabled as follows:
+
<programlisting>
+
services.xserver.synaptics.enable = true;
+
</programlisting>
+
The driver has many options (see <xref linkend="ch-options"/>). For
+
instance, the following enables two-finger scrolling:
+
<programlisting>
+
services.xserver.synaptics.twoFingerScroll = true;
+
</programlisting>
+
</para>
+
+
</simplesect>
+
+
+
</chapter>
-242
nixos/doc/manual/containers.xml
···
-
<chapter xmlns="http://docbook.org/ns/docbook"
-
xmlns:xlink="http://www.w3.org/1999/xlink"
-
xml:id="ch-containers">
-
-
<title>Containers</title>
-
-
<para>NixOS allows you to easily run other NixOS instances as
-
<emphasis>containers</emphasis>. Containers are a light-weight
-
approach to virtualisation that runs software in the container at the
-
same speed as in the host system. NixOS containers share the Nix store
-
of the host, making container creation very efficient.</para>
-
-
<warning><para>Currently, NixOS containers are not perfectly isolated
-
from the host system. This means that a user with root access to the
-
container can do things that affect the host. So you should not give
-
container root access to untrusted users.</para></warning>
-
-
<para>NixOS containers can be created in two ways: imperatively, using
-
the command <command>nixos-container</command>, and declaratively, by
-
specifying them in your <filename>configuration.nix</filename>. The
-
declarative approach implies that containers get upgraded along with
-
your host system when you run <command>nixos-rebuild</command>, which
-
is often not what you want. By contrast, in the imperative approach,
-
containers are configured and updated independently from the host
-
system.</para>
-
-
-
<section><title>Imperative container management</title>
-
-
<para>We’ll cover imperative container management using
-
<command>nixos-container</command> first. You create a container with
-
identifier <literal>foo</literal> as follows:
-
-
<screen>
-
$ nixos-container create foo
-
</screen>
-
-
This creates the container’s root directory in
-
<filename>/var/lib/containers/foo</filename> and a small configuration
-
file in <filename>/etc/containers/foo.conf</filename>. It also builds
-
the container’s initial system configuration and stores it in
-
<filename>/nix/var/nix/profiles/per-container/foo/system</filename>. You
-
can modify the initial configuration of the container on the command
-
line. For instance, to create a container that has
-
<command>sshd</command> running, with the given public key for
-
<literal>root</literal>:
-
-
<screen>
-
$ nixos-container create foo --config 'services.openssh.enable = true; \
-
users.extraUsers.root.openssh.authorizedKeys.keys = ["ssh-dss AAAAB3N…"];'
-
</screen>
-
-
</para>
-
-
<para>Creating a container does not start it. To start the container,
-
run:
-
-
<screen>
-
$ nixos-container start foo
-
</screen>
-
-
This command will return as soon as the container has booted and has
-
reached <literal>multi-user.target</literal>. On the host, the
-
container runs within a systemd unit called
-
<literal>container@<replaceable>container-name</replaceable>.service</literal>.
-
Thus, if something went wrong, you can get status info using
-
<command>systemctl</command>:
-
-
<screen>
-
$ systemctl status container@foo
-
</screen>
-
-
</para>
-
-
<para>If the container has started succesfully, you can log in as
-
root using the <command>root-login</command> operation:
-
-
<screen>
-
$ nixos-container root-login foo
-
[root@foo:~]#
-
</screen>
-
-
Note that only root on the host can do this (since there is no
-
authentication). You can also get a regular login prompt using the
-
<command>login</command> operation, which is available to all users on
-
the host:
-
-
<screen>
-
$ nixos-container login foo
-
foo login: alice
-
Password: ***
-
</screen>
-
-
With <command>nixos-container run</command>, you can execute arbitrary
-
commands in the container:
-
-
<screen>
-
$ nixos-container run foo -- uname -a
-
Linux foo 3.4.82 #1-NixOS SMP Thu Mar 20 14:44:05 UTC 2014 x86_64 GNU/Linux
-
</screen>
-
-
</para>
-
-
<para>There are several ways to change the configuration of the
-
container. First, on the host, you can edit
-
<literal>/var/lib/container/<replaceable>name</replaceable>/etc/nixos/configuration.nix</literal>,
-
and run
-
-
<screen>
-
$ nixos-container update foo
-
</screen>
-
-
This will build and activate the new configuration. You can also
-
specify a new configuration on the command line:
-
-
<screen>
-
$ nixos-container update foo --config 'services.httpd.enable = true; \
-
services.httpd.adminAddr = "foo@example.org";'
-
-
$ curl http://$(nixos-container show-ip foo)/
-
&lt;!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">…
-
</screen>
-
-
However, note that this will overwrite the container’s
-
<filename>/etc/nixos/configuration.nix</filename>.</para>
-
-
<para>Alternatively, you can change the configuration from within the
-
container itself by running <command>nixos-rebuild switch</command>
-
inside the container. Note that the container by default does not have
-
a copy of the NixOS channel, so you should run <command>nix-channel
-
--update</command> first.</para>
-
-
<para>Containers can be stopped and started using
-
<literal>nixos-container stop</literal> and <literal>nixos-container
-
start</literal>, respectively, or by using
-
<command>systemctl</command> on the container’s service unit. To
-
destroy a container, including its file system, do
-
-
<screen>
-
$ nixos-container destroy foo
-
</screen>
-
-
</para>
-
-
</section>
-
-
-
<section><title>Declarative container specification</title>
-
-
<para>You can also specify containers and their configuration in the
-
host’s <filename>configuration.nix</filename>. For example, the
-
following specifies that there shall be a container named
-
<literal>database</literal> running PostgreSQL:
-
-
<programlisting>
-
containers.database =
-
{ config =
-
{ config, pkgs, ... }:
-
{ services.postgresql.enable = true;
-
services.postgresql.package = pkgs.postgresql92;
-
};
-
};
-
</programlisting>
-
-
If you run <literal>nixos-rebuild switch</literal>, the container will
-
be built and started. If the container was already running, it will be
-
updated in place, without rebooting.</para>
-
-
<para>By default, declarative containers share the network namespace
-
of the host, meaning that they can listen on (privileged)
-
ports. However, they cannot change the network configuration. You can
-
give a container its own network as follows:
-
-
<programlisting>
-
containers.database =
-
{ privateNetwork = true;
-
hostAddress = "192.168.100.10";
-
localAddress = "192.168.100.11";
-
};
-
</programlisting>
-
-
This gives the container a private virtual Ethernet interface with IP
-
address <literal>192.168.100.11</literal>, which is hooked up to a
-
virtual Ethernet interface on the host with IP address
-
<literal>192.168.100.10</literal>. (See the next section for details
-
on container networking.)</para>
-
-
<para>To disable the container, just remove it from
-
<filename>configuration.nix</filename> and run <literal>nixos-rebuild
-
switch</literal>. Note that this will not delete the root directory of
-
the container in <literal>/var/lib/containers</literal>.</para>
-
-
</section>
-
-
-
<section><title>Networking</title>
-
-
<para>When you create a container using <literal>nixos-container
-
create</literal>, it gets it own private IPv4 address in the range
-
<literal>10.233.0.0/16</literal>. You can get the container’s IPv4
-
address as follows:
-
-
<screen>
-
$ nixos-container show-ip foo
-
10.233.4.2
-
-
$ ping -c1 10.233.4.2
-
64 bytes from 10.233.4.2: icmp_seq=1 ttl=64 time=0.106 ms
-
</screen>
-
-
</para>
-
-
<para>Networking is implemented using a pair of virtual Ethernet
-
devices. The network interface in the container is called
-
<literal>eth0</literal>, while the matching interface in the host is
-
called <literal>ve-<replaceable>container-name</replaceable></literal>
-
(e.g., <literal>ve-foo</literal>). The container has its own network
-
namespace and the <literal>CAP_NET_ADMIN</literal> capability, so it
-
can perform arbitrary network configuration such as setting up
-
firewall rules, without affecting or having access to the host’s
-
network.</para>
-
-
<para>By default, containers cannot talk to the outside network. If
-
you want that, you should set up Network Address Translation (NAT)
-
rules on the host to rewrite container traffic to use your external
-
IP address. This can be accomplished using the following configuration
-
on the host:
-
-
<programlisting>
-
networking.nat.enable = true;
-
networking.nat.internalInterfaces = ["ve-+"];
-
networking.nat.externalInterface = "eth0";
-
</programlisting>
-
where <literal>eth0</literal> should be replaced with the desired
-
external interface. Note that <literal>ve-+</literal> is a wildcard
-
that matches all container interfaces.</para>
-
-
</section>
-
-
-
</chapter>
-
···
-1119
nixos/doc/manual/development.xml
···
-
<chapter xmlns="http://docbook.org/ns/docbook"
-
xmlns:xlink="http://www.w3.org/1999/xlink"
-
xml:id="ch-development">
-
-
<title>Development</title>
-
-
<para>This chapter describes how you can modify and extend
-
NixOS.</para>
-
-
-
<!--===============================================================-->
-
-
<section xml:id="sec-getting-sources">
-
-
<title>Getting the sources</title>
-
-
<para>By default, NixOS’s <command>nixos-rebuild</command> command
-
uses the NixOS and Nixpkgs sources provided by the
-
<literal>nixos-unstable</literal> channel (kept in
-
<filename>/nix/var/nix/profiles/per-user/root/channels/nixos</filename>).
-
To modify NixOS, however, you should check out the latest sources from
-
Git. This is done using the following command:
-
-
<screen>
-
$ nixos-checkout <replaceable>/my/sources</replaceable>
-
</screen>
-
-
or
-
-
<screen>
-
$ mkdir -p <replaceable>/my/sources</replaceable>
-
$ cd <replaceable>/my/sources</replaceable>
-
$ nix-env -i git
-
$ git clone git://github.com/NixOS/nixpkgs.git
-
</screen>
-
-
This will check out the latest NixOS sources to
-
<filename><replaceable>/my/sources</replaceable>/nixpkgs/nixos</filename>
-
and the Nixpkgs sources to
-
<filename><replaceable>/my/sources</replaceable>/nixpkgs</filename>.
-
(The NixOS source tree lives in a subdirectory of the Nixpkgs
-
repository.)</para>
-
-
<para>It’s often inconvenient to develop directly on the master
-
branch, since if somebody has just committed (say) a change to GCC,
-
then the binary cache may not have caught up yet and you’ll have to
-
rebuild everything from source. So you may want to create a local
-
branch based on your current NixOS version:
-
-
<screen>
-
$ nixos-version
-
14.04.273.ea1952b (Baboon)
-
-
$ git checkout -b local ea1952b
-
</screen>
-
-
Or, to base your local branch on the latest version available in the
-
NixOS channel:
-
-
<screen>
-
$ curl -sI http://nixos.org/channels/nixos-unstable/ | grep Location
-
Location: http://releases.nixos.org/nixos/unstable/nixos-14.10pre43986.acaf4a6/
-
-
$ git checkout -b local acaf4a6
-
</screen>
-
-
You can then use <command>git rebase</command> to sync your local
-
branch with the upstream branch, and use <command>git
-
cherry-pick</command> to copy commits from your local branch to the
-
upstream branch.</para>
-
-
<para>If you want to rebuild your system using your (modified)
-
sources, you need to tell <command>nixos-rebuild</command> about them
-
using the <option>-I</option> flag:
-
-
<screen>
-
$ nixos-rebuild switch -I nixpkgs=<replaceable>/my/sources</replaceable>/nixpkgs
-
</screen>
-
-
</para>
-
-
<para>If you want <command>nix-env</command> to use the expressions in
-
<replaceable>/my/sources</replaceable>, use <command>nix-env -f
-
<replaceable>/my/sources</replaceable>/nixpkgs</command>, or change
-
the default by adding a symlink in
-
<filename>~/.nix-defexpr</filename>:
-
-
<screen>
-
$ ln -s <replaceable>/my/sources</replaceable>/nixpkgs ~/.nix-defexpr/nixpkgs
-
</screen>
-
-
You may want to delete the symlink
-
<filename>~/.nix-defexpr/channels_root</filename> to prevent root’s
-
NixOS channel from clashing with your own tree.</para>
-
-
<!-- FIXME: not sure what this means.
-
<para>You should not pass the base directory
-
<filename><replaceable>/my/sources</replaceable></filename>
-
to <command>nix-env</command>, as it will break after interpreting expressions
-
in <filename>nixos/</filename> as packages.</para>
-
-->
-
-
</section>
-
-
-
<!--===============================================================-->
-
-
<section xml:id="sec-writing-modules">
-
-
<title>Writing NixOS modules</title>
-
-
<para>NixOS has a modular system for declarative configuration. This
-
system combines multiple <emphasis>modules</emphasis> to produce the
-
full system configuration. One of the modules that constitute the
-
configuration is <filename>/etc/nixos/configuration.nix</filename>.
-
Most of the others live in the <link
-
xlink:href="https://github.com/NixOS/nixpkgs/tree/master/nixos/modules"><filename>nixos/modules</filename></link>
-
subdirectory of the Nixpkgs tree.</para>
-
-
<para>Each NixOS module is a file that handles one logical aspect of
-
the configuration, such as a specific kind of hardware, a service, or
-
network settings. A module configuration does not have to handle
-
everything from scratch; it can use the functionality provided by
-
other modules for its implementation. Thus a module can
-
<emphasis>declare</emphasis> options that can be used by other
-
modules, and conversely can <emphasis>define</emphasis> options
-
provided by other modules in its own implementation. For example, the
-
module <link
-
xlink:href="https://github.com/NixOS/nixpkgs/blob/master/nixos/modules/security/pam.nix"><filename>pam.nix</filename></link>
-
declares the option <option>security.pam.services</option> that allows
-
other modules (e.g. <link
-
xlink:href="https://github.com/NixOS/nixpkgs/blob/master/nixos/modules/services/networking/ssh/sshd.nix"><filename>sshd.nix</filename></link>)
-
to define PAM services; and it defines the option
-
<option>environment.etc</option> (declared by <link
-
xlink:href="https://github.com/NixOS/nixpkgs/blob/master/nixos/modules/system/etc/etc.nix"><filename>etc.nix</filename></link>)
-
to cause files to be created in
-
<filename>/etc/pam.d</filename>.</para>
-
-
<para xml:id="para-module-syn">In <xref
-
linkend="sec-configuration-syntax"/>, we saw the following structure
-
of NixOS modules:
-
-
<programlisting>
-
{ config, pkgs, ... }:
-
-
{ <replaceable>option definitions</replaceable>
-
}
-
</programlisting>
-
-
This is actually an <emphasis>abbreviated</emphasis> form of module
-
that only defines options, but does not declare any. The structure of
-
full NixOS modules is shown in <xref linkend='ex-module-syntax' />.</para>
-
-
<example xml:id='ex-module-syntax'><title>Structure of NixOS modules</title>
-
<programlisting>
-
{ config, pkgs, ... }: <co xml:id='module-syntax-1' />
-
-
{
-
imports =
-
[ <replaceable>paths of other modules</replaceable> <co xml:id='module-syntax-2' />
-
];
-
-
options = {
-
<replaceable>option declarations</replaceable> <co xml:id='module-syntax-3' />
-
};
-
-
config = {
-
<replaceable>option definitions</replaceable> <co xml:id='module-syntax-4' />
-
};
-
}</programlisting>
-
</example>
-
-
<para>The meaning of each part is as follows.
-
-
<calloutlist>
-
<callout arearefs='module-syntax-1'>
-
<para>This line makes the current Nix expression a function. The
-
variable <varname>pkgs</varname> contains Nixpkgs, while
-
<varname>config</varname> contains the full system configuration.
-
This line can be omitted if there is no reference to
-
<varname>pkgs</varname> and <varname>config</varname> inside the
-
module.</para>
-
</callout>
-
-
<callout arearefs='module-syntax-2'>
-
<para>This list enumerates the paths to other NixOS modules that
-
should be included in the evaluation of the system configuration.
-
A default set of modules is defined in the file
-
<filename>modules/module-list.nix</filename>. These don't need to
-
be added in the import list.</para>
-
</callout>
-
-
<callout arearefs='module-syntax-3'>
-
<para>The attribute <varname>options</varname> is a nested set of
-
<emphasis>option declarations</emphasis> (described below).</para>
-
</callout>
-
-
<callout arearefs='module-syntax-4'>
-
<para>The attribute <varname>config</varname> is a nested set of
-
<emphasis>option definitions</emphasis> (also described
-
below).</para>
-
</callout>
-
</calloutlist>
-
-
</para>
-
-
<para><xref linkend='locate-example' /> shows a module that handles
-
the regular update of the “locate” database, an index of all files in
-
the file system. This module declares two options that can be defined
-
by other modules (typically the user’s
-
<filename>configuration.nix</filename>):
-
<option>services.locate.enable</option> (whether the database should
-
be updated) and <option>services.locate.period</option> (when the
-
update should be done). It implements its functionality by defining
-
two options declared by other modules:
-
<option>systemd.services</option> (the set of all systemd services)
-
and <option>services.cron.systemCronJobs</option> (the list of
-
commands to be executed periodically by <command>cron</command>).</para>
-
-
<example xml:id='locate-example'><title>NixOS module for the “locate” service</title>
-
<programlisting>
-
{ config, lib, pkgs, ... }:
-
-
with lib;
-
-
let locatedb = "/var/cache/locatedb"; in
-
-
{
-
options = {
-
-
services.locate = {
-
-
enable = mkOption {
-
type = types.bool;
-
default = false;
-
description = ''
-
If enabled, NixOS will periodically update the database of
-
files used by the <command>locate</command> command.
-
'';
-
};
-
-
period = mkOption {
-
type = types.str;
-
default = "15 02 * * *";
-
description = ''
-
This option defines (in the format used by cron) when the
-
locate database is updated. The default is to update at
-
02:15 at night every day.
-
'';
-
};
-
-
};
-
-
};
-
-
config = {
-
-
systemd.services.update-locatedb =
-
{ description = "Update Locate Database";
-
path = [ pkgs.su ];
-
script =
-
''
-
mkdir -m 0755 -p $(dirname ${locatedb})
-
exec updatedb --localuser=nobody --output=${locatedb} --prunepaths='/tmp /var/tmp /media /run'
-
'';
-
};
-
-
services.cron.systemCronJobs = optional config.services.locate.enable
-
"${config.services.locate.period} root ${config.systemd.package}/bin/systemctl start update-locatedb.service";
-
-
};
-
}</programlisting>
-
</example>
-
-
<section><title>Option declarations</title>
-
-
<para>An option declaration specifies the name, type and description
-
of a NixOS configuration option. It is illegal to define an option
-
that hasn’t been declared in any module. A option declaration
-
generally looks like this:
-
-
<programlisting>
-
options = {
-
<replaceable>name</replaceable> = mkOption {
-
type = <replaceable>type specification</replaceable>;
-
default = <replaceable>default value</replaceable>;
-
example = <replaceable>example value</replaceable>;
-
description = "<replaceable>Description for use in the NixOS manual.</replaceable>";
-
};
-
};
-
</programlisting>
-
-
</para>
-
-
<para>The function <varname>mkOption</varname> accepts the following arguments.
-
-
<variablelist>
-
-
<varlistentry>
-
<term><varname>type</varname></term>
-
<listitem>
-
<para>The type of the option (see below). It may be omitted,
-
but that’s not advisable since it may lead to errors that are
-
hard to diagnose.</para>
-
</listitem>
-
</varlistentry>
-
-
<varlistentry>
-
<term><varname>default</varname></term>
-
<listitem>
-
<para>The default value used if no value is defined by any
-
module. A default is not required; in that case, if the option
-
value is ever used, an error will be thrown.</para>
-
</listitem>
-
</varlistentry>
-
-
<varlistentry>
-
<term><varname>example</varname></term>
-
<listitem>
-
<para>An example value that will be shown in the NixOS manual.</para>
-
</listitem>
-
</varlistentry>
-
-
<varlistentry>
-
<term><varname>description</varname></term>
-
<listitem>
-
<para>A textual description of the option, in DocBook format,
-
that will be included in the NixOS manual.</para>
-
</listitem>
-
</varlistentry>
-
-
</variablelist>
-
-
</para>
-
-
<para>Here is a non-exhaustive list of option types:
-
-
<variablelist>
-
-
<varlistentry>
-
<term><varname>types.bool</varname></term>
-
<listitem>
-
<para>A Boolean.</para>
-
</listitem>
-
</varlistentry>
-
-
<varlistentry>
-
<term><varname>types.int</varname></term>
-
<listitem>
-
<para>An integer.</para>
-
</listitem>
-
</varlistentry>
-
-
<varlistentry>
-
<term><varname>types.str</varname></term>
-
<listitem>
-
<para>A string.</para>
-
</listitem>
-
</varlistentry>
-
-
<varlistentry>
-
<term><varname>types.lines</varname></term>
-
<listitem>
-
<para>A string. If there are multiple definitions, they are
-
concatenated, with newline characters in between.</para>
-
</listitem>
-
</varlistentry>
-
-
<varlistentry>
-
<term><varname>types.path</varname></term>
-
<listitem>
-
<para>A path, defined as anything that, when coerced to a
-
string, starts with a slash. This includes derivations.</para>
-
</listitem>
-
</varlistentry>
-
-
<varlistentry>
-
<term><varname>types.listOf</varname> <replaceable>t</replaceable></term>
-
<listitem>
-
<para>A list of elements of type <replaceable>t</replaceable>
-
(e.g., <literal>types.listOf types.str</literal> is a list of
-
strings). Multiple definitions are concatenated together.</para>
-
</listitem>
-
</varlistentry>
-
-
<varlistentry>
-
<term><varname>types.attrsOf</varname> <replaceable>t</replaceable></term>
-
<listitem>
-
<para>A set of elements of type <replaceable>t</replaceable>
-
(e.g., <literal>types.attrsOf types.int</literal> is a set of
-
name/value pairs, the values being integers).</para>
-
</listitem>
-
</varlistentry>
-
-
<varlistentry>
-
<term><varname>types.nullOr</varname> <replaceable>t</replaceable></term>
-
<listitem>
-
<para>Either the value <literal>null</literal> or something of
-
type <replaceable>t</replaceable>.</para>
-
</listitem>
-
</varlistentry>
-
-
</variablelist>
-
-
You can also create new types using the function
-
<varname>mkOptionType</varname>. See
-
<filename>lib/types.nix</filename> in Nixpkgs for details.</para>
-
-
</section>
-
-
-
<section><title>Option definitions</title>
-
-
<para>Option definitions are generally straight-forward bindings of values to option names, like
-
-
<programlisting>
-
config = {
-
services.httpd.enable = true;
-
};
-
</programlisting>
-
-
However, sometimes you need to wrap an option definition or set of
-
option definitions in a <emphasis>property</emphasis> to achieve
-
certain effects:</para>
-
-
<simplesect><title>Delaying conditionals</title>
-
-
<para>If a set of option definitions is conditional on the value of
-
another option, you may need to use <varname>mkIf</varname>.
-
Consider, for instance:
-
-
<programlisting>
-
config = if config.services.httpd.enable then {
-
environment.systemPackages = [ <replaceable>...</replaceable> ];
-
<replaceable>...</replaceable>
-
} else {};
-
</programlisting>
-
-
This definition will cause Nix to fail with an “infinite recursion”
-
error. Why? Because the value of
-
<option>config.services.httpd.enable</option> depends on the value
-
being constructed here. After all, you could also write the clearly
-
circular and contradictory:
-
<programlisting>
-
config = if config.services.httpd.enable then {
-
services.httpd.enable = false;
-
} else {
-
services.httpd.enable = true;
-
};
-
</programlisting>
-
-
The solution is to write:
-
-
<programlisting>
-
config = mkIf config.services.httpd.enable {
-
environment.systemPackages = [ <replaceable>...</replaceable> ];
-
<replaceable>...</replaceable>
-
};
-
</programlisting>
-
-
The special function <varname>mkIf</varname> causes the evaluation of
-
the conditional to be “pushed down” into the individual definitions,
-
as if you had written:
-
-
<programlisting>
-
config = {
-
environment.systemPackages = if config.services.httpd.enable then [ <replaceable>...</replaceable> ] else [];
-
<replaceable>...</replaceable>
-
};
-
</programlisting>
-
-
</para>
-
-
</simplesect>
-
-
<simplesect><title>Setting priorities</title>
-
-
<para>A module can override the definitions of an option in other
-
modules by setting a <emphasis>priority</emphasis>. All option
-
definitions that do not have the lowest priority value are discarded.
-
By default, option definitions have priority 1000. You can specify an
-
explicit priority by using <varname>mkOverride</varname>, e.g.
-
-
<programlisting>
-
services.openssh.enable = mkOverride 10 false;
-
</programlisting>
-
-
This definition causes all other definitions with priorities above 10
-
to be discarded. The function <varname>mkForce</varname> is
-
equal to <varname>mkOverride 50</varname>.</para>
-
-
</simplesect>
-
-
<simplesect><title>Merging configurations</title>
-
-
<para>In conjunction with <literal>mkIf</literal>, it is sometimes
-
useful for a module to return multiple sets of option definitions, to
-
be merged together as if they were declared in separate modules. This
-
can be done using <varname>mkMerge</varname>:
-
-
<programlisting>
-
config = mkMerge
-
[ # Unconditional stuff.
-
{ environment.systemPackages = [ <replaceable>...</replaceable> ];
-
}
-
# Conditional stuff.
-
(mkIf config.services.bla.enable {
-
environment.systemPackages = [ <replaceable>...</replaceable> ];
-
})
-
];
-
</programlisting>
-
-
</para>
-
-
</simplesect>
-
-
</section>
-
-
-
<section><title>Important options</title>
-
-
<para>NixOS has many options, but some are of particular importance to
-
module writers.</para>
-
-
<variablelist>
-
-
<varlistentry>
-
<term><option>environment.etc</option></term>
-
<listitem>
-
<para>This set defines files in <filename>/etc</filename>. A
-
typical use is:
-
<programlisting>
-
environment.etc."os-release".text =
-
''
-
NAME=NixOS
-
<replaceable>...</replaceable>
-
'';
-
</programlisting>
-
which causes a file named <filename>/etc/os-release</filename>
-
to be created with the given contents.</para>
-
</listitem>
-
</varlistentry>
-
-
<varlistentry>
-
<term><option>system.activationScripts</option></term>
-
<listitem>
-
<para>A set of shell script fragments that must be executed
-
whenever the configuration is activated (i.e., at boot time, or
-
after running <command>nixos-rebuild switch</command>). For instance,
-
<programlisting>
-
system.activationScripts.media =
-
''
-
mkdir -m 0755 -p /media
-
'';
-
</programlisting>
-
causes the directory <filename>/media</filename> to be created.
-
Activation scripts must be idempotent. They should not start
-
background processes such as daemons; use
-
<option>systemd.services</option> for that.</para>
-
</listitem>
-
</varlistentry>
-
-
<varlistentry>
-
<term><option>systemd.services</option></term>
-
<listitem>
-
<para>This is the set of systemd services. Example:
-
<programlisting>
-
systemd.services.dhcpcd =
-
{ description = "DHCP Client";
-
wantedBy = [ "multi-user.target" ];
-
after = [ "systemd-udev-settle.service" ];
-
path = [ dhcpcd pkgs.nettools pkgs.openresolv ];
-
serviceConfig =
-
{ Type = "forking";
-
PIDFile = "/run/dhcpcd.pid";
-
ExecStart = "${dhcpcd}/sbin/dhcpcd --config ${dhcpcdConf}";
-
Restart = "always";
-
};
-
};
-
</programlisting>
-
which creates the systemd unit
-
<literal>dhcpcd.service</literal>. The option
-
<option>wantedBy</option> determined which other units pull this
-
one in; <literal>multi-user.target</literal> is the default
-
target of the system, so <literal>dhcpcd.service</literal> will
-
always be started. The option
-
<option>serviceConfig.ExecStart</option> provides the main
-
command for the service; it’s also possible to provide pre-start
-
actions, stop scripts, and so on.</para>
-
</listitem>
-
</varlistentry>
-
-
<varlistentry>
-
<term><option>users.extraUsers</option></term>
-
<term><option>users.extraGroups</option></term>
-
<listitem>
-
<para>If your service requires special UIDs or GIDs, you can
-
define them with these options. See <xref
-
linkend="sec-user-management"/> for details.</para>
-
</listitem>
-
</varlistentry>
-
-
</variablelist>
-
-
</section>
-
-
-
</section>
-
-
-
<!--===============================================================-->
-
-
<section xml:id="sec-building-parts">
-
-
<title>Building specific parts of NixOS</title>
-
-
<para>With the command <command>nix-build</command>, you can build
-
specific parts of your NixOS configuration. This is done as follows:
-
-
<screen>
-
$ cd <replaceable>/path/to/nixpkgs/nixos</replaceable>
-
$ nix-build -A config.<replaceable>option</replaceable></screen>
-
-
where <replaceable>option</replaceable> is a NixOS option with type
-
“derivation” (i.e. something that can be built). Attributes of
-
interest include:
-
-
<variablelist>
-
-
<varlistentry>
-
<term><varname>system.build.toplevel</varname></term>
-
<listitem>
-
<para>The top-level option that builds the entire NixOS system.
-
Everything else in your configuration is indirectly pulled in by
-
this option. This is what <command>nixos-rebuild</command>
-
builds and what <filename>/run/current-system</filename> points
-
to afterwards.</para>
-
-
<para>A shortcut to build this is:
-
-
<screen>
-
$ nix-build -A system</screen>
-
</para>
-
</listitem>
-
</varlistentry>
-
-
<varlistentry>
-
<term><varname>system.build.manual.manual</varname></term>
-
<listitem><para>The NixOS manual.</para></listitem>
-
</varlistentry>
-
-
<varlistentry>
-
<term><varname>system.build.etc</varname></term>
-
<listitem><para>A tree of symlinks that form the static parts of
-
<filename>/etc</filename>.</para></listitem>
-
</varlistentry>
-
-
<varlistentry>
-
<term><varname>system.build.initialRamdisk</varname></term>
-
<term><varname>system.build.kernel</varname></term>
-
<listitem>
-
<para>The initial ramdisk and kernel of the system. This allows
-
a quick way to test whether the kernel and the initial ramdisk
-
boot correctly, by using QEMU’s <option>-kernel</option> and
-
<option>-initrd</option> options:
-
-
<screen>
-
$ nix-build -A config.system.build.initialRamdisk -o initrd
-
$ nix-build -A config.system.build.kernel -o kernel
-
$ qemu-system-x86_64 -kernel ./kernel/bzImage -initrd ./initrd/initrd -hda /dev/null
-
</screen>
-
-
</para>
-
</listitem>
-
</varlistentry>
-
-
<varlistentry>
-
<term><varname>system.build.nixos-rebuild</varname></term>
-
<term><varname>system.build.nixos-install</varname></term>
-
<term><varname>system.build.nixos-generate-config</varname></term>
-
<listitem>
-
<para>These build the corresponding NixOS commands.</para>
-
</listitem>
-
</varlistentry>
-
-
<varlistentry>
-
<term><varname>systemd.units.<replaceable>unit-name</replaceable>.unit</varname></term>
-
<listitem>
-
<para>This builds the unit with the specified name. Note that
-
since unit names contain dots
-
(e.g. <literal>httpd.service</literal>), you need to put them
-
between quotes, like this:
-
-
<screen>
-
$ nix-build -A 'config.systemd.units."httpd.service".unit'
-
</screen>
-
-
You can also test individual units, without rebuilding the whole
-
system, by putting them in
-
<filename>/run/systemd/system</filename>:
-
-
<screen>
-
$ cp $(nix-build -A 'config.systemd.units."httpd.service".unit')/httpd.service \
-
/run/systemd/system/tmp-httpd.service
-
$ systemctl daemon-reload
-
$ systemctl start tmp-httpd.service
-
</screen>
-
-
Note that the unit must not have the same name as any unit in
-
<filename>/etc/systemd/system</filename> since those take
-
precedence over <filename>/run/systemd/system</filename>.
-
That’s why the unit is installed as
-
<filename>tmp-httpd.service</filename> here.</para>
-
</listitem>
-
</varlistentry>
-
-
</variablelist>
-
-
</para>
-
-
</section>
-
-
-
<!--===============================================================-->
-
-
<section xml:id="sec-building-cd">
-
-
<title>Building your own NixOS CD</title>
-
-
<para>Building a NixOS CD is as easy as configuring your own computer. The
-
idea is to use another module which will replace
-
your <filename>configuration.nix</filename> to configure the system that
-
would be installed on the CD.</para>
-
-
<para>Default CD/DVD configurations are available
-
inside <filename>nixos/modules/installer/cd-dvd</filename>. To build them
-
you have to set <envar>NIXOS_CONFIG</envar> before
-
running <command>nix-build</command> to build the ISO.
-
-
<screen>
-
$ nix-build -A config.system.build.isoImage -I nixos-config=modules/installer/cd-dvd/installation-cd-minimal.nix</screen>
-
-
</para>
-
-
<para>Before burning your CD/DVD, you can check the content of the image by mounting anywhere like
-
suggested by the following command:
-
-
<screen>
-
$ mount -o loop -t iso9660 ./result/iso/cd.iso /mnt/iso</screen>
-
-
</para>
-
-
</section>
-
-
-
<!--===============================================================-->
-
-
<section>
-
-
<title>Testing the installer</title>
-
-
<para>Building, burning, and booting from an installation CD is rather
-
tedious, so here is a quick way to see if the installer works
-
properly:
-
-
<screen>
-
$ nix-build -A config.system.build.nixos-install
-
$ mount -t tmpfs none /mnt
-
$ ./result/bin/nixos-install</screen>
-
-
To start a login shell in the new NixOS installation in
-
<filename>/mnt</filename>:
-
-
<screen>
-
$ ./result/bin/nixos-install --chroot
-
</screen>
-
-
</para>
-
-
</section>
-
-
-
-
<!--===============================================================-->
-
-
<section xml:id="sec-nixos-tests">
-
-
<title>NixOS tests</title>
-
-
<para>When you add some feature to NixOS, you should write a test for
-
it. NixOS tests are kept in the directory <filename
-
xlink:href="https://github.com/NixOS/nixpkgs/tree/master/nixos/tests">nixos/tests</filename>,
-
and are executed (using Nix) by a testing framework that automatically
-
starts one or more virtual machines containing the NixOS system(s)
-
required for the test.</para>
-
-
<simplesect><title>Writing tests</title>
-
-
<para>A NixOS test is a Nix expression that has the following structure:
-
-
<programlisting>
-
import ./make-test.nix {
-
-
# Either the configuration of a single machine:
-
machine =
-
{ config, pkgs, ... }:
-
{ <replaceable>configuration…</replaceable>
-
};
-
-
# Or a set of machines:
-
nodes =
-
{ <replaceable>machine1</replaceable> =
-
{ config, pkgs, ... }: { <replaceable>…</replaceable> };
-
<replaceable>machine2</replaceable> =
-
{ config, pkgs, ... }: { <replaceable>…</replaceable> };
-
-
};
-
-
testScript =
-
''
-
<replaceable>Perl code…</replaceable>
-
'';
-
}
-
</programlisting>
-
-
The attribute <literal>testScript</literal> is a bit of Perl code that
-
executes the test (described below). During the test, it will start
-
one or more virtual machines, the configuration of which is described
-
by the attribute <literal>machine</literal> (if you need only one
-
machine in your test) or by the attribute <literal>nodes</literal> (if
-
you need multiple machines). For instance, <filename
-
xlink:href="https://github.com/NixOS/nixpkgs/blob/master/nixos/tests/login.nix">login.nix</filename>
-
only needs a single machine to test whether users can log in on the
-
virtual console, whether device ownership is correctly maintained when
-
switching between consoles, and so on. On the other hand, <filename
-
xlink:href="https://github.com/NixOS/nixpkgs/blob/master/nixos/tests/nfs.nix">nfs.nix</filename>,
-
which tests NFS client and server functionality in the Linux kernel
-
(including whether locks are maintained across server crashes),
-
requires three machines: a server and two clients.</para>
-
-
<para>There are a few special NixOS configuration options for test
-
VMs:
-
-
<!-- FIXME: would be nice to generate this automatically. -->
-
-
<variablelist>
-
-
<varlistentry>
-
<term><option>virtualisation.memorySize</option></term>
-
<listitem><para>The memory of the VM in
-
megabytes.</para></listitem>
-
</varlistentry>
-
-
<varlistentry>
-
<term><option>virtualisation.vlans</option></term>
-
<listitem><para>The virtual networks to which the VM is
-
connected. See <filename
-
xlink:href="https://github.com/NixOS/nixpkgs/blob/master/nixos/tests/nat.nix">nat.nix</filename>
-
for an example.</para></listitem>
-
</varlistentry>
-
-
<varlistentry>
-
<term><option>virtualisation.writableStore</option></term>
-
<listitem><para>By default, the Nix store in the VM is not
-
writable. If you enable this option, a writable union file system
-
is mounted on top of the Nix store to make it appear
-
writable. This is necessary for tests that run Nix operations that
-
modify the store.</para></listitem>
-
</varlistentry>
-
-
</variablelist>
-
-
For more options, see the module <filename
-
xlink:href="https://github.com/NixOS/nixpkgs/blob/master/nixos/modules/virtualisation/qemu-vm.nix">qemu-vm.nix</filename>.</para>
-
-
<para>The test script is a sequence of Perl statements that perform
-
various actions, such as starting VMs, executing commands in the VMs,
-
and so on. Each virtual machine is represented as an object stored in
-
the variable <literal>$<replaceable>name</replaceable></literal>,
-
where <replaceable>name</replaceable> is the identifier of the machine
-
(which is just <literal>machine</literal> if you didn’t specify
-
multiple machines using the <literal>nodes</literal> attribute). For
-
instance, the following starts the machine, waits until it has
-
finished booting, then executes a command and checks that the output
-
is more-or-less correct:
-
-
<programlisting>
-
$machine->start;
-
$machine->waitForUnit("default.target");
-
$machine->succeed("uname") =~ /Linux/;
-
</programlisting>
-
-
The first line is actually unnecessary; machines are implicitly
-
started when you first execute an action on them (such as
-
<literal>waitForUnit</literal> or <literal>succeed</literal>). If you
-
have multiple machines, you can speed up the test by starting them in
-
parallel:
-
-
<programlisting>
-
startAll;
-
</programlisting>
-
-
</para>
-
-
<para>The following methods are available on machine objects:
-
-
<variablelist>
-
-
<varlistentry>
-
<term><methodname>start</methodname></term>
-
<listitem><para>Start the virtual machine. This method is
-
asynchronous — it does not wait for the machine to finish
-
booting.</para></listitem>
-
</varlistentry>
-
-
<varlistentry>
-
<term><methodname>shutdown</methodname></term>
-
<listitem><para>Shut down the machine, waiting for the VM to
-
exit.</para></listitem>
-
</varlistentry>
-
-
<varlistentry>
-
<term><methodname>crash</methodname></term>
-
<listitem><para>Simulate a sudden power failure, by telling the VM
-
to exit immediately.</para></listitem>
-
</varlistentry>
-
-
<varlistentry>
-
<term><methodname>block</methodname></term>
-
<listitem><para>Simulate unplugging the Ethernet cable that
-
connects the machine to the other machines.</para></listitem>
-
</varlistentry>
-
-
<varlistentry>
-
<term><methodname>unblock</methodname></term>
-
<listitem><para>Undo the effect of
-
<methodname>block</methodname>.</para></listitem>
-
</varlistentry>
-
-
<varlistentry>
-
<term><methodname>screenshot</methodname></term>
-
<listitem><para>Take a picture of the display of the virtual
-
machine, in PNG format. The screenshot is linked from the HTML
-
log.</para></listitem>
-
</varlistentry>
-
-
<varlistentry>
-
<term><methodname>sendMonitorCommand</methodname></term>
-
<listitem><para>Send a command to the QEMU monitor. This is rarely
-
used, but allows doing stuff such as attaching virtual USB disks
-
to a running machine.</para></listitem>
-
</varlistentry>
-
-
<varlistentry>
-
<term><methodname>sendKeys</methodname></term>
-
<listitem><para>Simulate pressing keys on the virtual keyboard,
-
e.g., <literal>sendKeys("ctrl-alt-delete")</literal>.</para></listitem>
-
</varlistentry>
-
-
<varlistentry>
-
<term><methodname>sendChars</methodname></term>
-
<listitem><para>Simulate typing a sequence of characters on the
-
virtual keyboard, e.g., <literal>sendKeys("foobar\n")</literal>
-
will type the string <literal>foobar</literal> followed by the
-
Enter key.</para></listitem>
-
</varlistentry>
-
-
<varlistentry>
-
<term><methodname>execute</methodname></term>
-
<listitem><para>Execute a shell command, returning a list
-
<literal>(<replaceable>status</replaceable>,
-
<replaceable>stdout</replaceable>)</literal>.</para></listitem>
-
</varlistentry>
-
-
<varlistentry>
-
<term><methodname>succeed</methodname></term>
-
<listitem><para>Execute a shell command, raising an exception if
-
the exit status is not zero, otherwise returning the standard
-
output.</para></listitem>
-
</varlistentry>
-
-
<varlistentry>
-
<term><methodname>fail</methodname></term>
-
<listitem><para>Like <methodname>succeed</methodname>, but raising
-
an exception if the command returns a zero status.</para></listitem>
-
</varlistentry>
-
-
<varlistentry>
-
<term><methodname>waitUntilSucceeds</methodname></term>
-
<listitem><para>Repeat a shell command with 1-second intervals
-
until it succeeds.</para></listitem>
-
</varlistentry>
-
-
<varlistentry>
-
<term><methodname>waitUntilFails</methodname></term>
-
<listitem><para>Repeat a shell command with 1-second intervals
-
until it fails.</para></listitem>
-
</varlistentry>
-
-
<varlistentry>
-
<term><methodname>waitForUnit</methodname></term>
-
<listitem><para>Wait until the specified systemd unit has reached
-
the “active” state.</para></listitem>
-
</varlistentry>
-
-
<varlistentry>
-
<term><methodname>waitForFile</methodname></term>
-
<listitem><para>Wait until the specified file
-
exists.</para></listitem>
-
</varlistentry>
-
-
<varlistentry>
-
<term><methodname>waitForOpenPort</methodname></term>
-
<listitem><para>Wait until a process is listening on the given TCP
-
port (on <literal>localhost</literal>, at least).</para></listitem>
-
</varlistentry>
-
-
<varlistentry>
-
<term><methodname>waitForClosedPort</methodname></term>
-
<listitem><para>Wait until nobody is listening on the given TCP
-
port.</para></listitem>
-
</varlistentry>
-
-
<varlistentry>
-
<term><methodname>waitForX</methodname></term>
-
<listitem><para>Wait until the X11 server is accepting
-
connections.</para></listitem>
-
</varlistentry>
-
-
<varlistentry>
-
<term><methodname>waitForWindow</methodname></term>
-
<listitem><para>Wait until an X11 window has appeared whose name
-
matches the given regular expression, e.g.,
-
<literal>waitForWindow(qr/Terminal/)</literal>.</para></listitem>
-
</varlistentry>
-
-
</variablelist>
-
-
</para>
-
-
</simplesect>
-
-
-
<simplesect><title>Running tests</title>
-
-
<para>You can run tests using <command>nix-build</command>. For
-
example, to run the test <filename
-
xlink:href="https://github.com/NixOS/nixpkgs/blob/master/nixos/tests/login.nix">login.nix</filename>,
-
you just do:
-
-
<screen>
-
$ nix-build '&lt;nixpkgs/nixos/tests/login.nix>'
-
</screen>
-
-
or, if you don’t want to rely on <envar>NIX_PATH</envar>:
-
-
<screen>
-
$ cd /my/nixpkgs/nixos/tests
-
$ nix-build login.nix
-
-
running the VM test script
-
machine: QEMU running (pid 8841)
-
-
6 out of 6 tests succeeded
-
</screen>
-
-
After building/downloading all required dependencies, this will
-
perform a build that starts a QEMU/KVM virtual machine containing a
-
NixOS system. The virtual machine mounts the Nix store of the host;
-
this makes VM creation very fast, as no disk image needs to be
-
created. Afterwards, you can view a pretty-printed log of the test:
-
-
<screen>
-
$ firefox result/log.html
-
</screen>
-
-
</para>
-
-
<para>It is also possible to run the test environment interactively,
-
allowing you to experiment with the VMs. For example:
-
-
<screen>
-
$ nix-build login.nix -A driver
-
$ ./result/bin/nixos-run-vms
-
</screen>
-
-
The script <command>nixos-run-vms</command> starts the virtual
-
machines defined by test. The root file system of the VMs is created
-
on the fly and kept across VM restarts in
-
<filename>./</filename><varname>hostname</varname><filename>.qcow2</filename>.</para>
-
-
<para>Finally, the test itself can be run interactively. This is
-
particularly useful when developing or debugging a test:
-
-
<screen>
-
$ nix-build tests/ -A nfs.driver
-
$ ./result/bin/nixos-test-driver
-
starting VDE switch for network 1
-
&gt;
-
</screen>
-
-
You can then take any Perl statement, e.g.
-
-
<screen>
-
&gt; startAll
-
&gt; $machine->succeed("touch /tmp/foo")
-
</screen>
-
-
The function <command>testScript</command> executes the entire test
-
script and drops you back into the test driver command line upon its
-
completion. This allows you to inspect the state of the VMs after the
-
test (e.g. to debug the test script).</para>
-
-
</simplesect>
-
-
</section>
-
-
-
</chapter>
···
+32
nixos/doc/manual/development/building-nixos.xml
···
···
+
<chapter xmlns="http://docbook.org/ns/docbook"
+
xmlns:xlink="http://www.w3.org/1999/xlink"
+
xmlns:xi="http://www.w3.org/2001/XInclude"
+
version="5.0"
+
xml:id="sec-building-cd">
+
+
<title>Building Your Own NixOS CD</title>
+
+
<para>Building a NixOS CD is as easy as configuring your own computer. The
+
idea is to use another module which will replace
+
your <filename>configuration.nix</filename> to configure the system that
+
would be installed on the CD.</para>
+
+
<para>Default CD/DVD configurations are available
+
inside <filename>nixos/modules/installer/cd-dvd</filename>. To build them
+
you have to set <envar>NIXOS_CONFIG</envar> before
+
running <command>nix-build</command> to build the ISO.
+
+
<screen>
+
$ nix-build -A config.system.build.isoImage -I nixos-config=modules/installer/cd-dvd/installation-cd-minimal.nix</screen>
+
+
</para>
+
+
<para>Before burning your CD/DVD, you can check the content of the image by mounting anywhere like
+
suggested by the following command:
+
+
<screen>
+
$ mount -o loop -t iso9660 ./result/iso/cd.iso /mnt/iso</screen>
+
+
</para>
+
+
</chapter>
+113
nixos/doc/manual/development/building-parts.xml
···
···
+
<chapter xmlns="http://docbook.org/ns/docbook"
+
xmlns:xlink="http://www.w3.org/1999/xlink"
+
xmlns:xi="http://www.w3.org/2001/XInclude"
+
version="5.0"
+
xml:id="sec-building-parts">
+
+
<title>Building Specific Parts of NixOS</title>
+
+
<para>With the command <command>nix-build</command>, you can build
+
specific parts of your NixOS configuration. This is done as follows:
+
+
<screen>
+
$ cd <replaceable>/path/to/nixpkgs/nixos</replaceable>
+
$ nix-build -A config.<replaceable>option</replaceable></screen>
+
+
where <replaceable>option</replaceable> is a NixOS option with type
+
“derivation” (i.e. something that can be built). Attributes of
+
interest include:
+
+
<variablelist>
+
+
<varlistentry>
+
<term><varname>system.build.toplevel</varname></term>
+
<listitem>
+
<para>The top-level option that builds the entire NixOS system.
+
Everything else in your configuration is indirectly pulled in by
+
this option. This is what <command>nixos-rebuild</command>
+
builds and what <filename>/run/current-system</filename> points
+
to afterwards.</para>
+
+
<para>A shortcut to build this is:
+
+
<screen>
+
$ nix-build -A system</screen>
+
</para>
+
</listitem>
+
</varlistentry>
+
+
<varlistentry>
+
<term><varname>system.build.manual.manual</varname></term>
+
<listitem><para>The NixOS manual.</para></listitem>
+
</varlistentry>
+
+
<varlistentry>
+
<term><varname>system.build.etc</varname></term>
+
<listitem><para>A tree of symlinks that form the static parts of
+
<filename>/etc</filename>.</para></listitem>
+
</varlistentry>
+
+
<varlistentry>
+
<term><varname>system.build.initialRamdisk</varname></term>
+
<term><varname>system.build.kernel</varname></term>
+
<listitem>
+
<para>The initial ramdisk and kernel of the system. This allows
+
a quick way to test whether the kernel and the initial ramdisk
+
boot correctly, by using QEMU’s <option>-kernel</option> and
+
<option>-initrd</option> options:
+
+
<screen>
+
$ nix-build -A config.system.build.initialRamdisk -o initrd
+
$ nix-build -A config.system.build.kernel -o kernel
+
$ qemu-system-x86_64 -kernel ./kernel/bzImage -initrd ./initrd/initrd -hda /dev/null
+
</screen>
+
+
</para>
+
</listitem>
+
</varlistentry>
+
+
<varlistentry>
+
<term><varname>system.build.nixos-rebuild</varname></term>
+
<term><varname>system.build.nixos-install</varname></term>
+
<term><varname>system.build.nixos-generate-config</varname></term>
+
<listitem>
+
<para>These build the corresponding NixOS commands.</para>
+
</listitem>
+
</varlistentry>
+
+
<varlistentry>
+
<term><varname>systemd.units.<replaceable>unit-name</replaceable>.unit</varname></term>
+
<listitem>
+
<para>This builds the unit with the specified name. Note that
+
since unit names contain dots
+
(e.g. <literal>httpd.service</literal>), you need to put them
+
between quotes, like this:
+
+
<screen>
+
$ nix-build -A 'config.systemd.units."httpd.service".unit'
+
</screen>
+
+
You can also test individual units, without rebuilding the whole
+
system, by putting them in
+
<filename>/run/systemd/system</filename>:
+
+
<screen>
+
$ cp $(nix-build -A 'config.systemd.units."httpd.service".unit')/httpd.service \
+
/run/systemd/system/tmp-httpd.service
+
$ systemctl daemon-reload
+
$ systemctl start tmp-httpd.service
+
</screen>
+
+
Note that the unit must not have the same name as any unit in
+
<filename>/etc/systemd/system</filename> since those take
+
precedence over <filename>/run/systemd/system</filename>.
+
That’s why the unit is installed as
+
<filename>tmp-httpd.service</filename> here.</para>
+
</listitem>
+
</varlistentry>
+
+
</variablelist>
+
+
</para>
+
+
</chapter>
+20
nixos/doc/manual/development/development.xml
···
···
+
<part xmlns="http://docbook.org/ns/docbook"
+
xmlns:xlink="http://www.w3.org/1999/xlink"
+
xmlns:xi="http://www.w3.org/2001/XInclude"
+
version="5.0"
+
xml:id="ch-development">
+
+
<title>Development</title>
+
+
<partintro>
+
<para>This chapter describes how you can modify and extend
+
NixOS.</para>
+
</partintro>
+
+
<xi:include href="sources.xml" />
+
<xi:include href="writing-modules.xml" />
+
<xi:include href="building-parts.xml" />
+
<xi:include href="building-nixos.xml" />
+
<xi:include href="testing-installer.xml" />
+
+
</part>
+19
nixos/doc/manual/development/nixos-tests.xml
···
···
+
<chapter xmlns="http://docbook.org/ns/docbook"
+
xmlns:xlink="http://www.w3.org/1999/xlink"
+
xmlns:xi="http://www.w3.org/2001/XInclude"
+
version="5.0"
+
xml:id="sec-nixos-tests">
+
+
<title>NixOS Tests</title>
+
+
<para>When you add some feature to NixOS, you should write a test for
+
it. NixOS tests are kept in the directory <filename
+
xlink:href="https://github.com/NixOS/nixpkgs/tree/master/nixos/tests">nixos/tests</filename>,
+
and are executed (using Nix) by a testing framework that automatically
+
starts one or more virtual machines containing the NixOS system(s)
+
required for the test.</para>
+
+
<xi:include href="writing-nixos-tests.xml" />
+
<xi:include href="running-nixos-tests.xml" />
+
+
</chapter>
+141
nixos/doc/manual/development/option-declarations.xml
···
···
+
<section xmlns="http://docbook.org/ns/docbook"
+
xmlns:xlink="http://www.w3.org/1999/xlink"
+
xmlns:xi="http://www.w3.org/2001/XInclude"
+
version="5.0"
+
xml:id="sec-option-declarations">
+
+
<title>Option Declarations</title>
+
+
<para>An option declaration specifies the name, type and description
+
of a NixOS configuration option. It is illegal to define an option
+
that hasn’t been declared in any module. A option declaration
+
generally looks like this:
+
+
<programlisting>
+
options = {
+
<replaceable>name</replaceable> = mkOption {
+
type = <replaceable>type specification</replaceable>;
+
default = <replaceable>default value</replaceable>;
+
example = <replaceable>example value</replaceable>;
+
description = "<replaceable>Description for use in the NixOS manual.</replaceable>";
+
};
+
};
+
</programlisting>
+
+
</para>
+
+
<para>The function <varname>mkOption</varname> accepts the following arguments.
+
+
<variablelist>
+
+
<varlistentry>
+
<term><varname>type</varname></term>
+
<listitem>
+
<para>The type of the option (see below). It may be omitted,
+
but that’s not advisable since it may lead to errors that are
+
hard to diagnose.</para>
+
</listitem>
+
</varlistentry>
+
+
<varlistentry>
+
<term><varname>default</varname></term>
+
<listitem>
+
<para>The default value used if no value is defined by any
+
module. A default is not required; in that case, if the option
+
value is ever used, an error will be thrown.</para>
+
</listitem>
+
</varlistentry>
+
+
<varlistentry>
+
<term><varname>example</varname></term>
+
<listitem>
+
<para>An example value that will be shown in the NixOS manual.</para>
+
</listitem>
+
</varlistentry>
+
+
<varlistentry>
+
<term><varname>description</varname></term>
+
<listitem>
+
<para>A textual description of the option, in DocBook format,
+
that will be included in the NixOS manual.</para>
+
</listitem>
+
</varlistentry>
+
+
</variablelist>
+
+
</para>
+
+
<para>Here is a non-exhaustive list of option types:
+
+
<variablelist>
+
+
<varlistentry>
+
<term><varname>types.bool</varname></term>
+
<listitem>
+
<para>A Boolean.</para>
+
</listitem>
+
</varlistentry>
+
+
<varlistentry>
+
<term><varname>types.int</varname></term>
+
<listitem>
+
<para>An integer.</para>
+
</listitem>
+
</varlistentry>
+
+
<varlistentry>
+
<term><varname>types.str</varname></term>
+
<listitem>
+
<para>A string.</para>
+
</listitem>
+
</varlistentry>
+
+
<varlistentry>
+
<term><varname>types.lines</varname></term>
+
<listitem>
+
<para>A string. If there are multiple definitions, they are
+
concatenated, with newline characters in between.</para>
+
</listitem>
+
</varlistentry>
+
+
<varlistentry>
+
<term><varname>types.path</varname></term>
+
<listitem>
+
<para>A path, defined as anything that, when coerced to a
+
string, starts with a slash. This includes derivations.</para>
+
</listitem>
+
</varlistentry>
+
+
<varlistentry>
+
<term><varname>types.listOf</varname> <replaceable>t</replaceable></term>
+
<listitem>
+
<para>A list of elements of type <replaceable>t</replaceable>
+
(e.g., <literal>types.listOf types.str</literal> is a list of
+
strings). Multiple definitions are concatenated together.</para>
+
</listitem>
+
</varlistentry>
+
+
<varlistentry>
+
<term><varname>types.attrsOf</varname> <replaceable>t</replaceable></term>
+
<listitem>
+
<para>A set of elements of type <replaceable>t</replaceable>
+
(e.g., <literal>types.attrsOf types.int</literal> is a set of
+
name/value pairs, the values being integers).</para>
+
</listitem>
+
</varlistentry>
+
+
<varlistentry>
+
<term><varname>types.nullOr</varname> <replaceable>t</replaceable></term>
+
<listitem>
+
<para>Either the value <literal>null</literal> or something of
+
type <replaceable>t</replaceable>.</para>
+
</listitem>
+
</varlistentry>
+
+
</variablelist>
+
+
You can also create new types using the function
+
<varname>mkOptionType</varname>. See
+
<filename>lib/types.nix</filename> in Nixpkgs for details.</para>
+
+
</section>
+112
nixos/doc/manual/development/option-def.xml
···
···
+
<section xmlns="http://docbook.org/ns/docbook"
+
xmlns:xlink="http://www.w3.org/1999/xlink"
+
xmlns:xi="http://www.w3.org/2001/XInclude"
+
version="5.0"
+
xml:id="sec-option-definitions">
+
+
<title>Option Definitions</title>
+
+
<para>Option definitions are generally straight-forward bindings of values to option names, like
+
+
<programlisting>
+
config = {
+
services.httpd.enable = true;
+
};
+
</programlisting>
+
+
However, sometimes you need to wrap an option definition or set of
+
option definitions in a <emphasis>property</emphasis> to achieve
+
certain effects:</para>
+
+
<simplesect><title>Delaying Conditionals</title>
+
+
<para>If a set of option definitions is conditional on the value of
+
another option, you may need to use <varname>mkIf</varname>.
+
Consider, for instance:
+
+
<programlisting>
+
config = if config.services.httpd.enable then {
+
environment.systemPackages = [ <replaceable>...</replaceable> ];
+
<replaceable>...</replaceable>
+
} else {};
+
</programlisting>
+
+
This definition will cause Nix to fail with an “infinite recursion”
+
error. Why? Because the value of
+
<option>config.services.httpd.enable</option> depends on the value
+
being constructed here. After all, you could also write the clearly
+
circular and contradictory:
+
<programlisting>
+
config = if config.services.httpd.enable then {
+
services.httpd.enable = false;
+
} else {
+
services.httpd.enable = true;
+
};
+
</programlisting>
+
+
The solution is to write:
+
+
<programlisting>
+
config = mkIf config.services.httpd.enable {
+
environment.systemPackages = [ <replaceable>...</replaceable> ];
+
<replaceable>...</replaceable>
+
};
+
</programlisting>
+
+
The special function <varname>mkIf</varname> causes the evaluation of
+
the conditional to be “pushed down” into the individual definitions,
+
as if you had written:
+
+
<programlisting>
+
config = {
+
environment.systemPackages = if config.services.httpd.enable then [ <replaceable>...</replaceable> ] else [];
+
<replaceable>...</replaceable>
+
};
+
</programlisting>
+
+
</para>
+
+
</simplesect>
+
+
<simplesect><title>Setting Priorities</title>
+
+
<para>A module can override the definitions of an option in other
+
modules by setting a <emphasis>priority</emphasis>. All option
+
definitions that do not have the lowest priority value are discarded.
+
By default, option definitions have priority 1000. You can specify an
+
explicit priority by using <varname>mkOverride</varname>, e.g.
+
+
<programlisting>
+
services.openssh.enable = mkOverride 10 false;
+
</programlisting>
+
+
This definition causes all other definitions with priorities above 10
+
to be discarded. The function <varname>mkForce</varname> is
+
equal to <varname>mkOverride 50</varname>.</para>
+
+
</simplesect>
+
+
<simplesect><title>Merging Configurations</title>
+
+
<para>In conjunction with <literal>mkIf</literal>, it is sometimes
+
useful for a module to return multiple sets of option definitions, to
+
be merged together as if they were declared in separate modules. This
+
can be done using <varname>mkMerge</varname>:
+
+
<programlisting>
+
config = mkMerge
+
[ # Unconditional stuff.
+
{ environment.systemPackages = [ <replaceable>...</replaceable> ];
+
}
+
# Conditional stuff.
+
(mkIf config.services.bla.enable {
+
environment.systemPackages = [ <replaceable>...</replaceable> ];
+
})
+
];
+
</programlisting>
+
+
</para>
+
+
</simplesect>
+
+
</section>
+77
nixos/doc/manual/development/running-nixos-tests.xml
···
···
+
<section xmlns="http://docbook.org/ns/docbook"
+
xmlns:xlink="http://www.w3.org/1999/xlink"
+
xmlns:xi="http://www.w3.org/2001/XInclude"
+
version="5.0"
+
xml:id="sec-running-nixos-tests">
+
+
<title>Running Tests</title>
+
+
<para>You can run tests using <command>nix-build</command>. For
+
example, to run the test <filename
+
xlink:href="https://github.com/NixOS/nixpkgs/blob/master/nixos/tests/login.nix">login.nix</filename>,
+
you just do:
+
+
<screen>
+
$ nix-build '&lt;nixpkgs/nixos/tests/login.nix>'
+
</screen>
+
+
or, if you don’t want to rely on <envar>NIX_PATH</envar>:
+
+
<screen>
+
$ cd /my/nixpkgs/nixos/tests
+
$ nix-build login.nix
+
+
running the VM test script
+
machine: QEMU running (pid 8841)
+
+
6 out of 6 tests succeeded
+
</screen>
+
+
After building/downloading all required dependencies, this will
+
perform a build that starts a QEMU/KVM virtual machine containing a
+
NixOS system. The virtual machine mounts the Nix store of the host;
+
this makes VM creation very fast, as no disk image needs to be
+
created. Afterwards, you can view a pretty-printed log of the test:
+
+
<screen>
+
$ firefox result/log.html
+
</screen>
+
+
</para>
+
+
<para>It is also possible to run the test environment interactively,
+
allowing you to experiment with the VMs. For example:
+
+
<screen>
+
$ nix-build login.nix -A driver
+
$ ./result/bin/nixos-run-vms
+
</screen>
+
+
The script <command>nixos-run-vms</command> starts the virtual
+
machines defined by test. The root file system of the VMs is created
+
on the fly and kept across VM restarts in
+
<filename>./</filename><varname>hostname</varname><filename>.qcow2</filename>.</para>
+
+
<para>Finally, the test itself can be run interactively. This is
+
particularly useful when developing or debugging a test:
+
+
<screen>
+
$ nix-build tests/ -A nfs.driver
+
$ ./result/bin/nixos-test-driver
+
starting VDE switch for network 1
+
&gt;
+
</screen>
+
+
You can then take any Perl statement, e.g.
+
+
<screen>
+
&gt; startAll
+
&gt; $machine->succeed("touch /tmp/foo")
+
</screen>
+
+
The function <command>testScript</command> executes the entire test
+
script and drops you back into the test driver command line upon its
+
completion. This allows you to inspect the state of the VMs after the
+
test (e.g. to debug the test script).</para>
+
+
</section>
+95
nixos/doc/manual/development/sources.xml
···
···
+
<chapter xmlns="http://docbook.org/ns/docbook"
+
xmlns:xlink="http://www.w3.org/1999/xlink"
+
xmlns:xi="http://www.w3.org/2001/XInclude"
+
version="5.0"
+
xml:id="sec-getting-sources">
+
+
<title>Getting the Sources</title>
+
+
<para>By default, NixOS’s <command>nixos-rebuild</command> command
+
uses the NixOS and Nixpkgs sources provided by the
+
<literal>nixos-unstable</literal> channel (kept in
+
<filename>/nix/var/nix/profiles/per-user/root/channels/nixos</filename>).
+
To modify NixOS, however, you should check out the latest sources from
+
Git. This is done using the following command:
+
+
<screen>
+
$ nixos-checkout <replaceable>/my/sources</replaceable>
+
</screen>
+
+
or
+
+
<screen>
+
$ mkdir -p <replaceable>/my/sources</replaceable>
+
$ cd <replaceable>/my/sources</replaceable>
+
$ nix-env -i git
+
$ git clone git://github.com/NixOS/nixpkgs.git
+
</screen>
+
+
This will check out the latest NixOS sources to
+
<filename><replaceable>/my/sources</replaceable>/nixpkgs/nixos</filename>
+
and the Nixpkgs sources to
+
<filename><replaceable>/my/sources</replaceable>/nixpkgs</filename>.
+
(The NixOS source tree lives in a subdirectory of the Nixpkgs
+
repository.)</para>
+
+
<para>It’s often inconvenient to develop directly on the master
+
branch, since if somebody has just committed (say) a change to GCC,
+
then the binary cache may not have caught up yet and you’ll have to
+
rebuild everything from source. So you may want to create a local
+
branch based on your current NixOS version:
+
+
<screen>
+
$ nixos-version
+
14.04.273.ea1952b (Baboon)
+
+
$ git checkout -b local ea1952b
+
</screen>
+
+
Or, to base your local branch on the latest version available in the
+
NixOS channel:
+
+
<screen>
+
$ curl -sI http://nixos.org/channels/nixos-unstable/ | grep Location
+
Location: http://releases.nixos.org/nixos/unstable/nixos-14.10pre43986.acaf4a6/
+
+
$ git checkout -b local acaf4a6
+
</screen>
+
+
You can then use <command>git rebase</command> to sync your local
+
branch with the upstream branch, and use <command>git
+
cherry-pick</command> to copy commits from your local branch to the
+
upstream branch.</para>
+
+
<para>If you want to rebuild your system using your (modified)
+
sources, you need to tell <command>nixos-rebuild</command> about them
+
using the <option>-I</option> flag:
+
+
<screen>
+
$ nixos-rebuild switch -I nixpkgs=<replaceable>/my/sources</replaceable>/nixpkgs
+
</screen>
+
+
</para>
+
+
<para>If you want <command>nix-env</command> to use the expressions in
+
<replaceable>/my/sources</replaceable>, use <command>nix-env -f
+
<replaceable>/my/sources</replaceable>/nixpkgs</command>, or change
+
the default by adding a symlink in
+
<filename>~/.nix-defexpr</filename>:
+
+
<screen>
+
$ ln -s <replaceable>/my/sources</replaceable>/nixpkgs ~/.nix-defexpr/nixpkgs
+
</screen>
+
+
You may want to delete the symlink
+
<filename>~/.nix-defexpr/channels_root</filename> to prevent root’s
+
NixOS channel from clashing with your own tree.</para>
+
+
<!-- FIXME: not sure what this means.
+
<para>You should not pass the base directory
+
<filename><replaceable>/my/sources</replaceable></filename>
+
to <command>nix-env</command>, as it will break after interpreting expressions
+
in <filename>nixos/</filename> as packages.</para>
+
-->
+
+
</chapter>
+27
nixos/doc/manual/development/testing-installer.xml
···
···
+
<chapter xmlns="http://docbook.org/ns/docbook"
+
xmlns:xlink="http://www.w3.org/1999/xlink"
+
xmlns:xi="http://www.w3.org/2001/XInclude"
+
version="5.0"
+
xml:id="ch-testing-installer">
+
+
<title>Testing the Installer</title>
+
+
<para>Building, burning, and booting from an installation CD is rather
+
tedious, so here is a quick way to see if the installer works
+
properly:
+
+
<screen>
+
$ nix-build -A config.system.build.nixos-install
+
$ mount -t tmpfs none /mnt
+
$ ./result/bin/nixos-install</screen>
+
+
To start a login shell in the new NixOS installation in
+
<filename>/mnt</filename>:
+
+
<screen>
+
$ ./result/bin/nixos-install --chroot
+
</screen>
+
+
</para>
+
+
</chapter>
+175
nixos/doc/manual/development/writing-modules.xml
···
···
+
<chapter xmlns="http://docbook.org/ns/docbook"
+
xmlns:xlink="http://www.w3.org/1999/xlink"
+
xmlns:xi="http://www.w3.org/2001/XInclude"
+
version="5.0"
+
xml:id="sec-writing-modules">
+
+
<title>Writing NixOS Modules</title>
+
+
<para>NixOS has a modular system for declarative configuration. This
+
system combines multiple <emphasis>modules</emphasis> to produce the
+
full system configuration. One of the modules that constitute the
+
configuration is <filename>/etc/nixos/configuration.nix</filename>.
+
Most of the others live in the <link
+
xlink:href="https://github.com/NixOS/nixpkgs/tree/master/nixos/modules"><filename>nixos/modules</filename></link>
+
subdirectory of the Nixpkgs tree.</para>
+
+
<para>Each NixOS module is a file that handles one logical aspect of
+
the configuration, such as a specific kind of hardware, a service, or
+
network settings. A module configuration does not have to handle
+
everything from scratch; it can use the functionality provided by
+
other modules for its implementation. Thus a module can
+
<emphasis>declare</emphasis> options that can be used by other
+
modules, and conversely can <emphasis>define</emphasis> options
+
provided by other modules in its own implementation. For example, the
+
module <link
+
xlink:href="https://github.com/NixOS/nixpkgs/blob/master/nixos/modules/security/pam.nix"><filename>pam.nix</filename></link>
+
declares the option <option>security.pam.services</option> that allows
+
other modules (e.g. <link
+
xlink:href="https://github.com/NixOS/nixpkgs/blob/master/nixos/modules/services/networking/ssh/sshd.nix"><filename>sshd.nix</filename></link>)
+
to define PAM services; and it defines the option
+
<option>environment.etc</option> (declared by <link
+
xlink:href="https://github.com/NixOS/nixpkgs/blob/master/nixos/modules/system/etc/etc.nix"><filename>etc.nix</filename></link>)
+
to cause files to be created in
+
<filename>/etc/pam.d</filename>.</para>
+
+
<para xml:id="para-module-syn">In <xref
+
linkend="sec-configuration-syntax"/>, we saw the following structure
+
of NixOS modules:
+
+
<programlisting>
+
{ config, pkgs, ... }:
+
+
{ <replaceable>option definitions</replaceable>
+
}
+
</programlisting>
+
+
This is actually an <emphasis>abbreviated</emphasis> form of module
+
that only defines options, but does not declare any. The structure of
+
full NixOS modules is shown in <xref linkend='ex-module-syntax' />.</para>
+
+
<example xml:id='ex-module-syntax'><title>Structure of NixOS Modules</title>
+
<programlisting>
+
{ config, pkgs, ... }: <co xml:id='module-syntax-1' />
+
+
{
+
imports =
+
[ <replaceable>paths of other modules</replaceable> <co xml:id='module-syntax-2' />
+
];
+
+
options = {
+
<replaceable>option declarations</replaceable> <co xml:id='module-syntax-3' />
+
};
+
+
config = {
+
<replaceable>option definitions</replaceable> <co xml:id='module-syntax-4' />
+
};
+
}</programlisting>
+
</example>
+
+
<para>The meaning of each part is as follows.
+
+
<calloutlist>
+
<callout arearefs='module-syntax-1'>
+
<para>This line makes the current Nix expression a function. The
+
variable <varname>pkgs</varname> contains Nixpkgs, while
+
<varname>config</varname> contains the full system configuration.
+
This line can be omitted if there is no reference to
+
<varname>pkgs</varname> and <varname>config</varname> inside the
+
module.</para>
+
</callout>
+
+
<callout arearefs='module-syntax-2'>
+
<para>This list enumerates the paths to other NixOS modules that
+
should be included in the evaluation of the system configuration.
+
A default set of modules is defined in the file
+
<filename>modules/module-list.nix</filename>. These don't need to
+
be added in the import list.</para>
+
</callout>
+
+
<callout arearefs='module-syntax-3'>
+
<para>The attribute <varname>options</varname> is a nested set of
+
<emphasis>option declarations</emphasis> (described below).</para>
+
</callout>
+
+
<callout arearefs='module-syntax-4'>
+
<para>The attribute <varname>config</varname> is a nested set of
+
<emphasis>option definitions</emphasis> (also described
+
below).</para>
+
</callout>
+
</calloutlist>
+
+
</para>
+
+
<para><xref linkend='locate-example' /> shows a module that handles
+
the regular update of the “locate” database, an index of all files in
+
the file system. This module declares two options that can be defined
+
by other modules (typically the user’s
+
<filename>configuration.nix</filename>):
+
<option>services.locate.enable</option> (whether the database should
+
be updated) and <option>services.locate.period</option> (when the
+
update should be done). It implements its functionality by defining
+
two options declared by other modules:
+
<option>systemd.services</option> (the set of all systemd services)
+
and <option>services.cron.systemCronJobs</option> (the list of
+
commands to be executed periodically by <command>cron</command>).</para>
+
+
<example xml:id='locate-example'><title>NixOS Module for the “locate” Service</title>
+
<programlisting>
+
{ config, lib, pkgs, ... }:
+
+
with lib;
+
+
let locatedb = "/var/cache/locatedb"; in
+
+
{
+
options = {
+
+
services.locate = {
+
+
enable = mkOption {
+
type = types.bool;
+
default = false;
+
description = ''
+
If enabled, NixOS will periodically update the database of
+
files used by the <command>locate</command> command.
+
'';
+
};
+
+
period = mkOption {
+
type = types.str;
+
default = "15 02 * * *";
+
description = ''
+
This option defines (in the format used by cron) when the
+
locate database is updated. The default is to update at
+
02:15 at night every day.
+
'';
+
};
+
+
};
+
+
};
+
+
config = {
+
+
systemd.services.update-locatedb =
+
{ description = "Update Locate Database";
+
path = [ pkgs.su ];
+
script =
+
''
+
mkdir -m 0755 -p $(dirname ${locatedb})
+
exec updatedb --localuser=nobody --output=${locatedb} --prunepaths='/tmp /var/tmp /media /run'
+
'';
+
};
+
+
services.cron.systemCronJobs = optional config.services.locate.enable
+
"${config.services.locate.period} root ${config.systemd.package}/bin/systemctl start update-locatedb.service";
+
+
};
+
}</programlisting>
+
</example>
+
+
<xi:include href="option-declarations.xml" />
+
<xi:include href="option-def.xml" />
+
+
</chapter>
+251
nixos/doc/manual/development/writing-nixos-tests.xml
···
···
+
<section xmlns="http://docbook.org/ns/docbook"
+
xmlns:xlink="http://www.w3.org/1999/xlink"
+
xmlns:xi="http://www.w3.org/2001/XInclude"
+
version="5.0"
+
xml:id="sec-writing-nixos-tests">
+
+
<title>Writing Tests</title>
+
+
<para>A NixOS test is a Nix expression that has the following structure:
+
+
<programlisting>
+
import ./make-test.nix {
+
+
# Either the configuration of a single machine:
+
machine =
+
{ config, pkgs, ... }:
+
{ <replaceable>configuration…</replaceable>
+
};
+
+
# Or a set of machines:
+
nodes =
+
{ <replaceable>machine1</replaceable> =
+
{ config, pkgs, ... }: { <replaceable>…</replaceable> };
+
<replaceable>machine2</replaceable> =
+
{ config, pkgs, ... }: { <replaceable>…</replaceable> };
+
+
};
+
+
testScript =
+
''
+
<replaceable>Perl code…</replaceable>
+
'';
+
}
+
</programlisting>
+
+
The attribute <literal>testScript</literal> is a bit of Perl code that
+
executes the test (described below). During the test, it will start
+
one or more virtual machines, the configuration of which is described
+
by the attribute <literal>machine</literal> (if you need only one
+
machine in your test) or by the attribute <literal>nodes</literal> (if
+
you need multiple machines). For instance, <filename
+
xlink:href="https://github.com/NixOS/nixpkgs/blob/master/nixos/tests/login.nix">login.nix</filename>
+
only needs a single machine to test whether users can log in on the
+
virtual console, whether device ownership is correctly maintained when
+
switching between consoles, and so on. On the other hand, <filename
+
xlink:href="https://github.com/NixOS/nixpkgs/blob/master/nixos/tests/nfs.nix">nfs.nix</filename>,
+
which tests NFS client and server functionality in the Linux kernel
+
(including whether locks are maintained across server crashes),
+
requires three machines: a server and two clients.</para>
+
+
<para>There are a few special NixOS configuration options for test
+
VMs:
+
+
<!-- FIXME: would be nice to generate this automatically. -->
+
+
<variablelist>
+
+
<varlistentry>
+
<term><option>virtualisation.memorySize</option></term>
+
<listitem><para>The memory of the VM in
+
megabytes.</para></listitem>
+
</varlistentry>
+
+
<varlistentry>
+
<term><option>virtualisation.vlans</option></term>
+
<listitem><para>The virtual networks to which the VM is
+
connected. See <filename
+
xlink:href="https://github.com/NixOS/nixpkgs/blob/master/nixos/tests/nat.nix">nat.nix</filename>
+
for an example.</para></listitem>
+
</varlistentry>
+
+
<varlistentry>
+
<term><option>virtualisation.writableStore</option></term>
+
<listitem><para>By default, the Nix store in the VM is not
+
writable. If you enable this option, a writable union file system
+
is mounted on top of the Nix store to make it appear
+
writable. This is necessary for tests that run Nix operations that
+
modify the store.</para></listitem>
+
</varlistentry>
+
+
</variablelist>
+
+
For more options, see the module <filename
+
xlink:href="https://github.com/NixOS/nixpkgs/blob/master/nixos/modules/virtualisation/qemu-vm.nix">qemu-vm.nix</filename>.</para>
+
+
<para>The test script is a sequence of Perl statements that perform
+
various actions, such as starting VMs, executing commands in the VMs,
+
and so on. Each virtual machine is represented as an object stored in
+
the variable <literal>$<replaceable>name</replaceable></literal>,
+
where <replaceable>name</replaceable> is the identifier of the machine
+
(which is just <literal>machine</literal> if you didn’t specify
+
multiple machines using the <literal>nodes</literal> attribute). For
+
instance, the following starts the machine, waits until it has
+
finished booting, then executes a command and checks that the output
+
is more-or-less correct:
+
+
<programlisting>
+
$machine->start;
+
$machine->waitForUnit("default.target");
+
$machine->succeed("uname") =~ /Linux/;
+
</programlisting>
+
+
The first line is actually unnecessary; machines are implicitly
+
started when you first execute an action on them (such as
+
<literal>waitForUnit</literal> or <literal>succeed</literal>). If you
+
have multiple machines, you can speed up the test by starting them in
+
parallel:
+
+
<programlisting>
+
startAll;
+
</programlisting>
+
+
</para>
+
+
<para>The following methods are available on machine objects:
+
+
<variablelist>
+
+
<varlistentry>
+
<term><methodname>start</methodname></term>
+
<listitem><para>Start the virtual machine. This method is
+
asynchronous — it does not wait for the machine to finish
+
booting.</para></listitem>
+
</varlistentry>
+
+
<varlistentry>
+
<term><methodname>shutdown</methodname></term>
+
<listitem><para>Shut down the machine, waiting for the VM to
+
exit.</para></listitem>
+
</varlistentry>
+
+
<varlistentry>
+
<term><methodname>crash</methodname></term>
+
<listitem><para>Simulate a sudden power failure, by telling the VM
+
to exit immediately.</para></listitem>
+
</varlistentry>
+
+
<varlistentry>
+
<term><methodname>block</methodname></term>
+
<listitem><para>Simulate unplugging the Ethernet cable that
+
connects the machine to the other machines.</para></listitem>
+
</varlistentry>
+
+
<varlistentry>
+
<term><methodname>unblock</methodname></term>
+
<listitem><para>Undo the effect of
+
<methodname>block</methodname>.</para></listitem>
+
</varlistentry>
+
+
<varlistentry>
+
<term><methodname>screenshot</methodname></term>
+
<listitem><para>Take a picture of the display of the virtual
+
machine, in PNG format. The screenshot is linked from the HTML
+
log.</para></listitem>
+
</varlistentry>
+
+
<varlistentry>
+
<term><methodname>sendMonitorCommand</methodname></term>
+
<listitem><para>Send a command to the QEMU monitor. This is rarely
+
used, but allows doing stuff such as attaching virtual USB disks
+
to a running machine.</para></listitem>
+
</varlistentry>
+
+
<varlistentry>
+
<term><methodname>sendKeys</methodname></term>
+
<listitem><para>Simulate pressing keys on the virtual keyboard,
+
e.g., <literal>sendKeys("ctrl-alt-delete")</literal>.</para></listitem>
+
</varlistentry>
+
+
<varlistentry>
+
<term><methodname>sendChars</methodname></term>
+
<listitem><para>Simulate typing a sequence of characters on the
+
virtual keyboard, e.g., <literal>sendKeys("foobar\n")</literal>
+
will type the string <literal>foobar</literal> followed by the
+
Enter key.</para></listitem>
+
</varlistentry>
+
+
<varlistentry>
+
<term><methodname>execute</methodname></term>
+
<listitem><para>Execute a shell command, returning a list
+
<literal>(<replaceable>status</replaceable>,
+
<replaceable>stdout</replaceable>)</literal>.</para></listitem>
+
</varlistentry>
+
+
<varlistentry>
+
<term><methodname>succeed</methodname></term>
+
<listitem><para>Execute a shell command, raising an exception if
+
the exit status is not zero, otherwise returning the standard
+
output.</para></listitem>
+
</varlistentry>
+
+
<varlistentry>
+
<term><methodname>fail</methodname></term>
+
<listitem><para>Like <methodname>succeed</methodname>, but raising
+
an exception if the command returns a zero status.</para></listitem>
+
</varlistentry>
+
+
<varlistentry>
+
<term><methodname>waitUntilSucceeds</methodname></term>
+
<listitem><para>Repeat a shell command with 1-second intervals
+
until it succeeds.</para></listitem>
+
</varlistentry>
+
+
<varlistentry>
+
<term><methodname>waitUntilFails</methodname></term>
+
<listitem><para>Repeat a shell command with 1-second intervals
+
until it fails.</para></listitem>
+
</varlistentry>
+
+
<varlistentry>
+
<term><methodname>waitForUnit</methodname></term>
+
<listitem><para>Wait until the specified systemd unit has reached
+
the “active” state.</para></listitem>
+
</varlistentry>
+
+
<varlistentry>
+
<term><methodname>waitForFile</methodname></term>
+
<listitem><para>Wait until the specified file
+
exists.</para></listitem>
+
</varlistentry>
+
+
<varlistentry>
+
<term><methodname>waitForOpenPort</methodname></term>
+
<listitem><para>Wait until a process is listening on the given TCP
+
port (on <literal>localhost</literal>, at least).</para></listitem>
+
</varlistentry>
+
+
<varlistentry>
+
<term><methodname>waitForClosedPort</methodname></term>
+
<listitem><para>Wait until nobody is listening on the given TCP
+
port.</para></listitem>
+
</varlistentry>
+
+
<varlistentry>
+
<term><methodname>waitForX</methodname></term>
+
<listitem><para>Wait until the X11 server is accepting
+
connections.</para></listitem>
+
</varlistentry>
+
+
<varlistentry>
+
<term><methodname>waitForWindow</methodname></term>
+
<listitem><para>Wait until an X11 window has appeared whose name
+
matches the given regular expression, e.g.,
+
<literal>waitForWindow(qr/Terminal/)</literal>.</para></listitem>
+
</varlistentry>
+
+
</variablelist>
+
+
</para>
+
+
</section>
-570
nixos/doc/manual/installation.xml
···
-
<chapter xmlns="http://docbook.org/ns/docbook"
-
xmlns:xlink="http://www.w3.org/1999/xlink"
-
xml:id="ch-installation">
-
-
<title>Installing NixOS</title>
-
-
-
<!--===============================================================-->
-
-
<section xml:id="sec-obtaining">
-
-
<title>Obtaining NixOS</title>
-
-
<para>NixOS ISO images can be downloaded from the <link
-
xlink:href="http://nixos.org/nixos/download.html">NixOS
-
homepage</link>. These can be burned onto a CD. It is also possible
-
to copy them onto a USB stick and install NixOS from there. For
-
details, see the <link
-
xlink:href="https://nixos.org/wiki/Installing_NixOS_from_a_USB_stick">NixOS
-
Wiki</link>.</para>
-
-
<para>As an alternative to installing NixOS yourself, you can get a
-
running NixOS system through several other means:
-
-
<itemizedlist>
-
<listitem>
-
<para>Using virtual appliances in Open Virtualization Format (OVF)
-
that can be imported into VirtualBox. These are available from
-
the <link xlink:href="http://nixos.org/nixos/download.html">NixOS
-
homepage</link>.</para>
-
</listitem>
-
<listitem>
-
<para>Using AMIs for Amazon’s EC2. To find one for your region
-
and instance type, please refer to the <link
-
xlink:href="https://github.com/NixOS/nixops/blob/master/nix/ec2-amis.nix">list
-
of most recent AMIs</link>.</para>
-
</listitem>
-
<listitem>
-
<para>Using NixOps, the NixOS-based cloud deployment tool, which
-
allows you to provision VirtualBox and EC2 NixOS instances from
-
declarative specifications. Check out the <link
-
xlink:href="https://github.com/NixOS/nixops">NixOps
-
homepage</link> for details.</para>
-
</listitem>
-
</itemizedlist>
-
-
</para>
-
-
</section>
-
-
-
<!--===============================================================-->
-
-
<section xml:id="sec-installation">
-
-
<title>Installation</title>
-
-
<orderedlist>
-
-
<listitem><para>Boot from the CD.</para></listitem>
-
-
<listitem><para>The CD contains a basic NixOS installation. (It
-
also contains Memtest86+, useful if you want to test new hardware.)
-
When it’s finished booting, it should have detected most of your
-
hardware and brought up networking (check
-
<command>ifconfig</command>). Networking is necessary for the
-
installer, since it will download lots of stuff (such as source
-
tarballs or Nixpkgs channel binaries). It’s best if you have a DHCP
-
server on your network. Otherwise configure networking manually
-
using <command>ifconfig</command>.</para></listitem>
-
-
<listitem><para>The NixOS manual is available on virtual console 8
-
(press Alt+F8 to access).</para></listitem>
-
-
<listitem><para>Login as <literal>root</literal> and the empty
-
password.</para></listitem>
-
-
<listitem><para>If you downloaded the graphical ISO image, you can
-
run <command>start display-manager</command> to start KDE.</para></listitem>
-
-
<listitem><para>The NixOS installer doesn’t do any partitioning or
-
formatting yet, so you need to that yourself. Use the following
-
commands:
-
-
<itemizedlist>
-
-
<listitem><para>For partitioning:
-
<command>fdisk</command>.</para></listitem>
-
-
<listitem><para>For initialising Ext4 partitions:
-
<command>mkfs.ext4</command>. It is recommended that you assign a
-
unique symbolic label to the file system using the option
-
<option>-L <replaceable>label</replaceable></option>, since this
-
makes the file system configuration independent from device
-
changes. For example:
-
-
<screen>
-
$ mkfs.ext4 -L nixos /dev/sda1</screen>
-
-
</para></listitem>
-
-
<listitem><para>For creating swap partitions:
-
<command>mkswap</command>. Again it’s recommended to assign a
-
label to the swap partition: <option>-L
-
<replaceable>label</replaceable></option>.</para></listitem>
-
-
<listitem><para>For creating LVM volumes, the LVM commands, e.g.,
-
-
<screen>
-
$ pvcreate /dev/sda1 /dev/sdb1
-
$ vgcreate MyVolGroup /dev/sda1 /dev/sdb1
-
$ lvcreate --size 2G --name bigdisk MyVolGroup
-
$ lvcreate --size 1G --name smalldisk MyVolGroup</screen>
-
-
</para></listitem>
-
-
<listitem><para>For creating software RAID devices, use
-
<command>mdadm</command>.</para></listitem>
-
-
</itemizedlist>
-
-
</para></listitem>
-
-
<listitem><para>Mount the target file system on which NixOS should
-
be installed on <filename>/mnt</filename>, e.g.
-
-
<screen>
-
$ mount /dev/disk/by-label/nixos /mnt
-
</screen>
-
-
</para></listitem>
-
-
<listitem><para>If your machine has a limited amount of memory, you
-
may want to activate swap devices now (<command>swapon
-
<replaceable>device</replaceable></command>). The installer (or
-
rather, the build actions that it may spawn) may need quite a bit of
-
RAM, depending on your configuration.</para></listitem>
-
-
<listitem>
-
-
<para>You now need to create a file
-
<filename>/mnt/etc/nixos/configuration.nix</filename> that
-
specifies the intended configuration of the system. This is
-
because NixOS has a <emphasis>declarative</emphasis> configuration
-
model: you create or edit a description of the desired
-
configuration of your system, and then NixOS takes care of making
-
it happen. The syntax of the NixOS configuration file is
-
described in <xref linkend="sec-configuration-syntax"/>, while a
-
list of available configuration options appears in <xref
-
linkend="ch-options"/>. A minimal example is shown in <xref
-
linkend="ex-config"/>.</para>
-
-
<para>The command <command>nixos-generate-config</command> can
-
generate an initial configuration file for you:
-
-
<screen>
-
$ nixos-generate-config --root /mnt</screen>
-
-
You should then edit
-
<filename>/mnt/etc/nixos/configuration.nix</filename> to suit your
-
needs:
-
-
<screen>
-
$ nano /mnt/etc/nixos/configuration.nix
-
</screen>
-
-
The <command>vim</command> text editor is also available.</para>
-
-
<para>You <emphasis>must</emphasis> set the option
-
<option>boot.loader.grub.device</option> to specify on which disk
-
the GRUB boot loader is to be installed. Without it, NixOS cannot
-
boot.</para>
-
-
<para>Another critical option is <option>fileSystems</option>,
-
specifying the file systems that need to be mounted by NixOS.
-
However, you typically don’t need to set it yourself, because
-
<command>nixos-generate-config</command> sets it automatically in
-
<filename>/mnt/etc/nixos/hardware-configuration.nix</filename>
-
from your currently mounted file systems. (The configuration file
-
<filename>hardware-configuration.nix</filename> is included from
-
<filename>configuration.nix</filename> and will be overwritten by
-
future invocations of <command>nixos-generate-config</command>;
-
thus, you generally should not modify it.)</para>
-
-
<note><para>Depending on your hardware configuration or type of
-
file system, you may need to set the option
-
<option>boot.initrd.kernelModules</option> to include the kernel
-
modules that are necessary for mounting the root file system,
-
otherwise the installed system will not be able to boot. (If this
-
happens, boot from the CD again, mount the target file system on
-
<filename>/mnt</filename>, fix
-
<filename>/mnt/etc/nixos/configuration.nix</filename> and rerun
-
<filename>nixos-install</filename>.) In most cases,
-
<command>nixos-generate-config</command> will figure out the
-
required modules.</para></note>
-
-
<para>Examples of real-world NixOS configuration files can be
-
found at <link
-
xlink:href="https://nixos.org/repos/nix/configurations/trunk/"/>.</para>
-
-
</listitem>
-
-
<listitem><para>Do the installation:
-
-
<screen>
-
$ nixos-install</screen>
-
-
Cross fingers. If this fails due to a temporary problem (such as
-
a network issue while downloading binaries from the NixOS binary
-
cache), you can just re-run <command>nixos-install</command>.
-
Otherwise, fix your <filename>configuration.nix</filename> and
-
then re-run <command>nixos-install</command>.</para>
-
-
<para>As the last step, <command>nixos-install</command> will ask
-
you to set the password for the <literal>root</literal> user, e.g.
-
-
<screen>
-
setting root password...
-
Enter new UNIX password: ***
-
Retype new UNIX password: ***
-
</screen>
-
-
</para>
-
-
</listitem>
-
-
<listitem><para>If everything went well:
-
-
<screen>
-
$ reboot</screen>
-
-
</para></listitem>
-
-
<listitem>
-
-
<para>You should now be able to boot into the installed NixOS.
-
The GRUB boot menu shows a list of <emphasis>available
-
configurations</emphasis> (initially just one). Every time you
-
change the NixOS configuration (see <xref
-
linkend="sec-changing-config" />), a new item appears in the menu.
-
This allows you to easily roll back to another configuration if
-
something goes wrong.</para>
-
-
<para>You should log in and change the <literal>root</literal>
-
password with <command>passwd</command>.</para>
-
-
<para>You’ll probably want to create some user accounts as well,
-
which can be done with <command>useradd</command>:
-
-
<screen>
-
$ useradd -c 'Eelco Dolstra' -m eelco
-
$ passwd eelco</screen>
-
-
</para>
-
-
<para>You may also want to install some software. For instance,
-
-
<screen>
-
$ nix-env -qa \*</screen>
-
-
shows what packages are available, and
-
-
<screen>
-
$ nix-env -i w3m</screen>
-
-
install the <literal>w3m</literal> browser.</para>
-
-
</listitem>
-
-
</orderedlist>
-
-
<para>To summarise, <xref linkend="ex-install-sequence" /> shows a
-
typical sequence of commands for installing NixOS on an empty hard
-
drive (here <filename>/dev/sda</filename>). <xref linkend="ex-config"
-
/> shows a corresponding configuration Nix expression.</para>
-
-
<example xml:id='ex-install-sequence'><title>Commands for installing NixOS on <filename>/dev/sda</filename></title>
-
<screen>
-
$ fdisk /dev/sda # <lineannotation>(or whatever device you want to install on)</lineannotation>
-
$ mkfs.ext4 -L nixos /dev/sda1
-
$ mkswap -L swap /dev/sda2
-
$ swapon /dev/sda2
-
$ mount /dev/disk/by-label/nixos /mnt
-
$ nixos-generate-config --root /mnt
-
$ nano /mnt/etc/nixos/configuration.nix
-
$ nixos-install
-
$ reboot</screen>
-
</example>
-
-
<example xml:id='ex-config'><title>NixOS configuration</title>
-
<screen>
-
{ config, pkgs, ... }:
-
-
{
-
imports =
-
[ # Include the results of the hardware scan.
-
./hardware-configuration.nix
-
];
-
-
boot.loader.grub.device = "/dev/sda";
-
-
# Note: setting fileSystems is generally not
-
# necessary, since nixos-generate-config figures them out
-
# automatically in hardware-configuration.nix.
-
#fileSystems."/".device = "/dev/disk/by-label/nixos";
-
-
# Enable the OpenSSH server.
-
services.sshd.enable = true;
-
}</screen>
-
</example>
-
-
<section xml:id="sec-uefi-installation">
-
-
<title>UEFI Installation</title>
-
-
<para>NixOS can also be installed on UEFI systems. The procedure
-
is by and large the same as a BIOS installation, with the following
-
changes:
-
-
<itemizedlist>
-
<listitem>
-
<para>You should boot the live CD in UEFI mode (consult your
-
specific hardware's documentation for instructions). You may find
-
the <link
-
xlink:href="http://www.rodsbooks.com/refind">rEFInd
-
boot manager</link> useful.</para>
-
</listitem>
-
<listitem>
-
<para>Instead of <command>fdisk</command>, you should use
-
<command>gdisk</command> to partition your disks. You will need to
-
have a separate partition for <filename>/boot</filename> with
-
partition code EF00, and it should be formatted as a
-
<literal>vfat</literal> filesystem.</para>
-
</listitem>
-
<listitem>
-
<para>You must set <option>boot.loader.gummiboot.enable</option> to
-
<literal>true</literal>. <command>nixos-generate-config</command>
-
should do this automatically for new configurations when booted in
-
UEFI mode.</para>
-
</listitem>
-
<listitem>
-
<para>After having mounted your installation partition to
-
<code>/mnt</code>, you must mount the <code>boot</code> partition
-
to <code>/mnt/boot</code>.</para>
-
</listitem>
-
<listitem>
-
<para>You may want to look at the options starting with
-
<option>boot.loader.efi</option> and <option>boot.loader.gummiboot</option>
-
as well.</para>
-
</listitem>
-
<listitem>
-
<para>To see console messages during early boot, add <literal>"fbcon"</literal>
-
to your <option>boot.initrd.kernelModules</option>.</para>
-
</listitem>
-
</itemizedlist>
-
</para>
-
-
</section>
-
-
<section>
-
-
<title xml:id="sec-booting-from-usb">Booting from a USB stick</title>
-
-
<para>For systems without CD drive, the NixOS livecd can be booted from
-
a usb stick. For non-UEFI installations,
-
<link xlink:href="http://unetbootin.sourceforge.net/">unetbootin</link>
-
will work. For UEFI installations, you should mount the ISO, copy its contents
-
verbatim to your drive, then either:
-
-
<itemizedlist>
-
<listitem>
-
<para>Change the label of the disk partition to the label of the ISO
-
(visible with the blkid command), or</para>
-
</listitem>
-
<listitem>
-
<para>Edit <filename>loader/entries/nixos-livecd.conf</filename> on the drive
-
and change the <literal>root=</literal> field in the <literal>options</literal>
-
line to point to your drive (see the documentation on <literal>root=</literal>
-
in <link xlink:href="https://www.kernel.org/doc/Documentation/kernel-parameters.txt">
-
the kernel documentation</link> for more details).</para>
-
</listitem>
-
</itemizedlist>
-
</para>
-
</section>
-
-
</section>
-
-
-
<!--===============================================================-->
-
-
<section xml:id="sec-changing-config">
-
-
<title>Changing the configuration</title>
-
-
<para>The file <filename>/etc/nixos/configuration.nix</filename>
-
contains the current configuration of your machine. Whenever you’ve
-
changed something to that file, you should do
-
-
<screen>
-
$ nixos-rebuild switch</screen>
-
-
to build the new configuration, make it the default configuration for
-
booting, and try to realise the configuration in the running system
-
(e.g., by restarting system services).</para>
-
-
<warning><para>These commands must be executed as root, so you should
-
either run them from a root shell or by prefixing them with
-
<literal>sudo -i</literal>.</para></warning>
-
-
<para>You can also do
-
-
<screen>
-
$ nixos-rebuild test</screen>
-
-
to build the configuration and switch the running system to it, but
-
without making it the boot default. So if (say) the configuration
-
locks up your machine, you can just reboot to get back to a working
-
configuration.</para>
-
-
<para>There is also
-
-
<screen>
-
$ nixos-rebuild boot</screen>
-
-
to build the configuration and make it the boot default, but not
-
switch to it now (so it will only take effect after the next
-
reboot).</para>
-
-
<para>You can make your configuration show up in a different submenu
-
of the GRUB 2 boot screen by giving it a different <emphasis>profile
-
name</emphasis>, e.g.
-
-
<screen>
-
$ nixos-rebuild switch -p test </screen>
-
-
which causes the new configuration (and previous ones created using
-
<literal>-p test</literal>) to show up in the GRUB submenu “NixOS -
-
Profile 'test'”. This can be useful to separate test configurations
-
from “stable” configurations.</para>
-
-
<para>Finally, you can do
-
-
<screen>
-
$ nixos-rebuild build</screen>
-
-
to build the configuration but nothing more. This is useful to see
-
whether everything compiles cleanly.</para>
-
-
<para>If you have a machine that supports hardware virtualisation, you
-
can also test the new configuration in a sandbox by building and
-
running a QEMU <emphasis>virtual machine</emphasis> that contains the
-
desired configuration. Just do
-
-
<screen>
-
$ nixos-rebuild build-vm
-
$ ./result/bin/run-*-vm
-
</screen>
-
-
The VM does not have any data from your host system, so your existing
-
user accounts and home directories will not be available. You can
-
forward ports on the host to the guest. For instance, the following
-
will forward host port 2222 to guest port 22 (SSH):
-
-
<screen>
-
$ QEMU_NET_OPTS="hostfwd=tcp::2222-:22" ./result/bin/run-*-vm
-
</screen>
-
-
allowing you to log in via SSH (assuming you have set the appropriate
-
passwords or SSH authorized keys):
-
-
<screen>
-
$ ssh -p 2222 localhost
-
</screen>
-
-
</para>
-
-
</section>
-
-
-
<!--===============================================================-->
-
-
<section xml:id="sec-upgrading">
-
-
<title>Upgrading NixOS</title>
-
-
<para>The best way to keep your NixOS installation up to date is to
-
use one of the NixOS <emphasis>channels</emphasis>. A channel is a
-
Nix mechanism for distributing Nix expressions and associated
-
binaries. The NixOS channels are updated automatically from NixOS’s
-
Git repository after certain tests have passed and all packages have
-
been built. These channels are:
-
-
<itemizedlist>
-
<listitem>
-
<para>Stable channels, such as <literal
-
xlink:href="http://nixos.org/channels/nixos-14.04">nixos-14.04</literal>.
-
These only get conservative bug fixes and package upgrades. For
-
instance, a channel update may cause the Linux kernel on your
-
system to be upgraded from 3.4.66 to 3.4.67 (a minor bug fix), but
-
not from 3.4.<replaceable>x</replaceable> to
-
3.11.<replaceable>x</replaceable> (a major change that has the
-
potential to break things). Stable channels are generally
-
maintained until the next stable branch is created.</para>
-
</listitem>
-
<listitem>
-
<para>The unstable channel, <literal
-
xlink:href="http://nixos.org/channels/nixos-unstable">nixos-unstable</literal>.
-
This corresponds to NixOS’s main development branch, and may thus
-
see radical changes between channel updates. It’s not recommended
-
for production systems.</para>
-
</listitem>
-
</itemizedlist>
-
-
To see what channels are available, go to <link
-
xlink:href="http://nixos.org/channels"/>. (Note that the URIs of the
-
various channels redirect to a directory that contains the channel’s
-
latest version and includes ISO images and VirtualBox
-
appliances.)</para>
-
-
<para>When you first install NixOS, you’re automatically subscribed to
-
the NixOS channel that corresponds to your installation source. For
-
instance, if you installed from a 14.04 ISO, you will be subscribed to
-
the <literal>nixos-14.04</literal> channel. To see which NixOS
-
channel you’re subscribed to, run the following as root:
-
-
<screen>
-
$ nix-channel --list | grep nixos
-
nixos https://nixos.org/channels/nixos-unstable
-
</screen>
-
-
To switch to a different NixOS channel, do
-
-
<screen>
-
$ nix-channel --add http://nixos.org/channels/<replaceable>channel-name</replaceable> nixos
-
</screen>
-
-
(Be sure to include the <literal>nixos</literal> parameter at the
-
end.) For instance, to use the NixOS 14.04 stable channel:
-
-
<screen>
-
$ nix-channel --add http://nixos.org/channels/nixos-14.04 nixos
-
</screen>
-
-
But it you want to live on the bleeding edge:
-
-
<screen>
-
$ nix-channel --add http://nixos.org/channels/nixos-unstable nixos
-
</screen>
-
-
</para>
-
-
<para>You can then upgrade NixOS to the latest version in your chosen
-
channel by running
-
-
<screen>
-
$ nixos-rebuild switch --upgrade
-
</screen>
-
-
which is equivalent to the more verbose <literal>nix-channel --update
-
nixos; nixos-rebuild switch</literal>.</para>
-
-
<warning><para>It is generally safe to switch back and forth between
-
channels. The only exception is that a newer NixOS may also have a
-
newer Nix version, which may involve an upgrade of Nix’s database
-
schema. This cannot be undone easily, so in that case you will not be
-
able to go back to your original channel.</para></warning>
-
-
</section>
-
-
</chapter>
···
+90
nixos/doc/manual/installation/changing-config.xml
···
···
+
<chapter xmlns="http://docbook.org/ns/docbook"
+
xmlns:xlink="http://www.w3.org/1999/xlink"
+
version="5.0"
+
xml:id="sec-changing-config">
+
+
<title>Changing the Configuration</title>
+
+
<para>The file <filename>/etc/nixos/configuration.nix</filename>
+
contains the current configuration of your machine. Whenever you’ve
+
changed something to that file, you should do
+
+
<screen>
+
$ nixos-rebuild switch</screen>
+
+
to build the new configuration, make it the default configuration for
+
booting, and try to realise the configuration in the running system
+
(e.g., by restarting system services).</para>
+
+
<warning><para>These commands must be executed as root, so you should
+
either run them from a root shell or by prefixing them with
+
<literal>sudo -i</literal>.</para></warning>
+
+
<para>You can also do
+
+
<screen>
+
$ nixos-rebuild test</screen>
+
+
to build the configuration and switch the running system to it, but
+
without making it the boot default. So if (say) the configuration
+
locks up your machine, you can just reboot to get back to a working
+
configuration.</para>
+
+
<para>There is also
+
+
<screen>
+
$ nixos-rebuild boot</screen>
+
+
to build the configuration and make it the boot default, but not
+
switch to it now (so it will only take effect after the next
+
reboot).</para>
+
+
<para>You can make your configuration show up in a different submenu
+
of the GRUB 2 boot screen by giving it a different <emphasis>profile
+
name</emphasis>, e.g.
+
+
<screen>
+
$ nixos-rebuild switch -p test </screen>
+
+
which causes the new configuration (and previous ones created using
+
<literal>-p test</literal>) to show up in the GRUB submenu “NixOS -
+
Profile 'test'”. This can be useful to separate test configurations
+
from “stable” configurations.</para>
+
+
<para>Finally, you can do
+
+
<screen>
+
$ nixos-rebuild build</screen>
+
+
to build the configuration but nothing more. This is useful to see
+
whether everything compiles cleanly.</para>
+
+
<para>If you have a machine that supports hardware virtualisation, you
+
can also test the new configuration in a sandbox by building and
+
running a QEMU <emphasis>virtual machine</emphasis> that contains the
+
desired configuration. Just do
+
+
<screen>
+
$ nixos-rebuild build-vm
+
$ ./result/bin/run-*-vm
+
</screen>
+
+
The VM does not have any data from your host system, so your existing
+
user accounts and home directories will not be available. You can
+
forward ports on the host to the guest. For instance, the following
+
will forward host port 2222 to guest port 22 (SSH):
+
+
<screen>
+
$ QEMU_NET_OPTS="hostfwd=tcp::2222-:22" ./result/bin/run-*-vm
+
</screen>
+
+
allowing you to log in via SSH (assuming you have set the appropriate
+
passwords or SSH authorized keys):
+
+
<screen>
+
$ ssh -p 2222 localhost
+
</screen>
+
+
</para>
+
+
</chapter>
+21
nixos/doc/manual/installation/installation.xml
···
···
+
<part xmlns="http://docbook.org/ns/docbook"
+
xmlns:xlink="http://www.w3.org/1999/xlink"
+
xmlns:xi="http://www.w3.org/2001/XInclude"
+
version="5.0"
+
xml:id="ch-installation">
+
+
<title>Installation</title>
+
+
<partintro>
+
+
<para>This section describes how to obtain, install, and configure
+
NixOS for first-time use.</para>
+
+
</partintro>
+
+
<xi:include href="obtaining.xml" />
+
<xi:include href="installing.xml" />
+
<xi:include href="changing-config.xml" />
+
<xi:include href="upgrading.xml" />
+
+
</part>
+51
nixos/doc/manual/installation/installing-UEFI.xml
···
···
+
<section xmlns="http://docbook.org/ns/docbook"
+
xmlns:xlink="http://www.w3.org/1999/xlink"
+
xmlns:xi="http://www.w3.org/2001/XInclude"
+
version="5.0"
+
xml:id="sec-uefi-installation">
+
+
<title>UEFI Installation</title>
+
+
<para>NixOS can also be installed on UEFI systems. The procedure
+
is by and large the same as a BIOS installation, with the following
+
changes:
+
+
<itemizedlist>
+
<listitem>
+
<para>You should boot the live CD in UEFI mode (consult your
+
specific hardware's documentation for instructions). You may find
+
the <link
+
xlink:href="http://www.rodsbooks.com/refind">rEFInd
+
boot manager</link> useful.</para>
+
</listitem>
+
<listitem>
+
<para>Instead of <command>fdisk</command>, you should use
+
<command>gdisk</command> to partition your disks. You will need to
+
have a separate partition for <filename>/boot</filename> with
+
partition code EF00, and it should be formatted as a
+
<literal>vfat</literal> filesystem.</para>
+
</listitem>
+
<listitem>
+
<para>You must set <option>boot.loader.gummiboot.enable</option> to
+
<literal>true</literal>. <command>nixos-generate-config</command>
+
should do this automatically for new configurations when booted in
+
UEFI mode.</para>
+
</listitem>
+
<listitem>
+
<para>After having mounted your installation partition to
+
<code>/mnt</code>, you must mount the <code>boot</code> partition
+
to <code>/mnt/boot</code>.</para>
+
</listitem>
+
<listitem>
+
<para>You may want to look at the options starting with
+
<option>boot.loader.efi</option> and <option>boot.loader.gummiboot</option>
+
as well.</para>
+
</listitem>
+
<listitem>
+
<para>To see console messages during early boot, add <literal>"fbcon"</literal>
+
to your <option>boot.initrd.kernelModules</option>.</para>
+
</listitem>
+
</itemizedlist>
+
</para>
+
+
</section>
+30
nixos/doc/manual/installation/installing-USB.xml
···
···
+
<section xmlns="http://docbook.org/ns/docbook"
+
xmlns:xlink="http://www.w3.org/1999/xlink"
+
xmlns:xi="http://www.w3.org/2001/XInclude"
+
version="5.0"
+
xml:id="sec-booting-from-usb">
+
+
<title>Booting from a USB Drive</title>
+
+
<para>For systems without CD drive, the NixOS livecd can be booted from
+
a usb stick. For non-UEFI installations,
+
<link xlink:href="http://unetbootin.sourceforge.net/">unetbootin</link>
+
will work. For UEFI installations, you should mount the ISO, copy its contents
+
verbatim to your drive, then either:
+
+
<itemizedlist>
+
<listitem>
+
<para>Change the label of the disk partition to the label of the ISO
+
(visible with the blkid command), or</para>
+
</listitem>
+
<listitem>
+
<para>Edit <filename>loader/entries/nixos-livecd.conf</filename> on the drive
+
and change the <literal>root=</literal> field in the <literal>options</literal>
+
line to point to your drive (see the documentation on <literal>root=</literal>
+
in <link xlink:href="https://www.kernel.org/doc/Documentation/kernel-parameters.txt">
+
the kernel documentation</link> for more details).</para>
+
</listitem>
+
</itemizedlist>
+
</para>
+
+
</section>
+264
nixos/doc/manual/installation/installing.xml
···
···
+
<chapter xmlns="http://docbook.org/ns/docbook"
+
xmlns:xlink="http://www.w3.org/1999/xlink"
+
xmlns:xi="http://www.w3.org/2001/XInclude"
+
version="5.0"
+
xml:id="sec-installation">
+
+
<title>Installing NixOS</title>
+
+
<orderedlist>
+
+
<listitem><para>Boot from the CD.</para></listitem>
+
+
<listitem><para>The CD contains a basic NixOS installation. (It
+
also contains Memtest86+, useful if you want to test new hardware.)
+
When it’s finished booting, it should have detected most of your
+
hardware and brought up networking (check
+
<command>ifconfig</command>). Networking is necessary for the
+
installer, since it will download lots of stuff (such as source
+
tarballs or Nixpkgs channel binaries). It’s best if you have a DHCP
+
server on your network. Otherwise configure networking manually
+
using <command>ifconfig</command>.</para></listitem>
+
+
<listitem><para>The NixOS manual is available on virtual console 8
+
(press Alt+F8 to access).</para></listitem>
+
+
<listitem><para>Login as <literal>root</literal> and the empty
+
password.</para></listitem>
+
+
<listitem><para>If you downloaded the graphical ISO image, you can
+
run <command>start display-manager</command> to start KDE.</para></listitem>
+
+
<listitem><para>The NixOS installer doesn’t do any partitioning or
+
formatting yet, so you need to that yourself. Use the following
+
commands:
+
+
<itemizedlist>
+
+
<listitem><para>For partitioning:
+
<command>fdisk</command>.</para></listitem>
+
+
<listitem><para>For initialising Ext4 partitions:
+
<command>mkfs.ext4</command>. It is recommended that you assign a
+
unique symbolic label to the file system using the option
+
<option>-L <replaceable>label</replaceable></option>, since this
+
makes the file system configuration independent from device
+
changes. For example:
+
+
<screen>
+
$ mkfs.ext4 -L nixos /dev/sda1</screen>
+
+
</para></listitem>
+
+
<listitem><para>For creating swap partitions:
+
<command>mkswap</command>. Again it’s recommended to assign a
+
label to the swap partition: <option>-L
+
<replaceable>label</replaceable></option>.</para></listitem>
+
+
<listitem><para>For creating LVM volumes, the LVM commands, e.g.,
+
+
<screen>
+
$ pvcreate /dev/sda1 /dev/sdb1
+
$ vgcreate MyVolGroup /dev/sda1 /dev/sdb1
+
$ lvcreate --size 2G --name bigdisk MyVolGroup
+
$ lvcreate --size 1G --name smalldisk MyVolGroup</screen>
+
+
</para></listitem>
+
+
<listitem><para>For creating software RAID devices, use
+
<command>mdadm</command>.</para></listitem>
+
+
</itemizedlist>
+
+
</para></listitem>
+
+
<listitem><para>Mount the target file system on which NixOS should
+
be installed on <filename>/mnt</filename>, e.g.
+
+
<screen>
+
$ mount /dev/disk/by-label/nixos /mnt
+
</screen>
+
+
</para></listitem>
+
+
<listitem><para>If your machine has a limited amount of memory, you
+
may want to activate swap devices now (<command>swapon
+
<replaceable>device</replaceable></command>). The installer (or
+
rather, the build actions that it may spawn) may need quite a bit of
+
RAM, depending on your configuration.</para></listitem>
+
+
<listitem>
+
+
<para>You now need to create a file
+
<filename>/mnt/etc/nixos/configuration.nix</filename> that
+
specifies the intended configuration of the system. This is
+
because NixOS has a <emphasis>declarative</emphasis> configuration
+
model: you create or edit a description of the desired
+
configuration of your system, and then NixOS takes care of making
+
it happen. The syntax of the NixOS configuration file is
+
described in <xref linkend="sec-configuration-syntax"/>, while a
+
list of available configuration options appears in <xref
+
linkend="ch-options"/>. A minimal example is shown in <xref
+
linkend="ex-config"/>.</para>
+
+
<para>The command <command>nixos-generate-config</command> can
+
generate an initial configuration file for you:
+
+
<screen>
+
$ nixos-generate-config --root /mnt</screen>
+
+
You should then edit
+
<filename>/mnt/etc/nixos/configuration.nix</filename> to suit your
+
needs:
+
+
<screen>
+
$ nano /mnt/etc/nixos/configuration.nix
+
</screen>
+
+
The <command>vim</command> text editor is also available.</para>
+
+
<para>You <emphasis>must</emphasis> set the option
+
<option>boot.loader.grub.device</option> to specify on which disk
+
the GRUB boot loader is to be installed. Without it, NixOS cannot
+
boot.</para>
+
+
<para>Another critical option is <option>fileSystems</option>,
+
specifying the file systems that need to be mounted by NixOS.
+
However, you typically don’t need to set it yourself, because
+
<command>nixos-generate-config</command> sets it automatically in
+
<filename>/mnt/etc/nixos/hardware-configuration.nix</filename>
+
from your currently mounted file systems. (The configuration file
+
<filename>hardware-configuration.nix</filename> is included from
+
<filename>configuration.nix</filename> and will be overwritten by
+
future invocations of <command>nixos-generate-config</command>;
+
thus, you generally should not modify it.)</para>
+
+
<note><para>Depending on your hardware configuration or type of
+
file system, you may need to set the option
+
<option>boot.initrd.kernelModules</option> to include the kernel
+
modules that are necessary for mounting the root file system,
+
otherwise the installed system will not be able to boot. (If this
+
happens, boot from the CD again, mount the target file system on
+
<filename>/mnt</filename>, fix
+
<filename>/mnt/etc/nixos/configuration.nix</filename> and rerun
+
<filename>nixos-install</filename>.) In most cases,
+
<command>nixos-generate-config</command> will figure out the
+
required modules.</para></note>
+
+
<para>Examples of real-world NixOS configuration files can be
+
found at <link
+
xlink:href="https://nixos.org/repos/nix/configurations/trunk/"/>.</para>
+
+
</listitem>
+
+
<listitem><para>Do the installation:
+
+
<screen>
+
$ nixos-install</screen>
+
+
Cross fingers. If this fails due to a temporary problem (such as
+
a network issue while downloading binaries from the NixOS binary
+
cache), you can just re-run <command>nixos-install</command>.
+
Otherwise, fix your <filename>configuration.nix</filename> and
+
then re-run <command>nixos-install</command>.</para>
+
+
<para>As the last step, <command>nixos-install</command> will ask
+
you to set the password for the <literal>root</literal> user, e.g.
+
+
<screen>
+
setting root password...
+
Enter new UNIX password: ***
+
Retype new UNIX password: ***
+
</screen>
+
+
</para>
+
+
</listitem>
+
+
<listitem><para>If everything went well:
+
+
<screen>
+
$ reboot</screen>
+
+
</para></listitem>
+
+
<listitem>
+
+
<para>You should now be able to boot into the installed NixOS. The GRUB boot menu shows a list
+
of <emphasis>available configurations</emphasis> (initially just one). Every time
+
you change the NixOS configuration (see<link linkend="sec-changing-config">Changing
+
Configuration</link> ), a new item appears in the menu. This allows you to
+
easily roll back to another configuration if something goes wrong.</para>
+
+
<para>You should log in and change the <literal>root</literal>
+
password with <command>passwd</command>.</para>
+
+
<para>You’ll probably want to create some user accounts as well,
+
which can be done with <command>useradd</command>:
+
+
<screen>
+
$ useradd -c 'Eelco Dolstra' -m eelco
+
$ passwd eelco</screen>
+
+
</para>
+
+
<para>You may also want to install some software. For instance,
+
+
<screen>
+
$ nix-env -qa \*</screen>
+
+
shows what packages are available, and
+
+
<screen>
+
$ nix-env -i w3m</screen>
+
+
install the <literal>w3m</literal> browser.</para>
+
+
</listitem>
+
+
</orderedlist>
+
+
<para>To summarise, <xref linkend="ex-install-sequence" /> shows a
+
typical sequence of commands for installing NixOS on an empty hard
+
drive (here <filename>/dev/sda</filename>). <xref linkend="ex-config"
+
/> shows a corresponding configuration Nix expression.</para>
+
+
<example xml:id='ex-install-sequence'><title>Commands for Installing NixOS on <filename>/dev/sda</filename></title>
+
<screen>
+
$ fdisk /dev/sda # <lineannotation>(or whatever device you want to install on)</lineannotation>
+
$ mkfs.ext4 -L nixos /dev/sda1
+
$ mkswap -L swap /dev/sda2
+
$ swapon /dev/sda2
+
$ mount /dev/disk/by-label/nixos /mnt
+
$ nixos-generate-config --root /mnt
+
$ nano /mnt/etc/nixos/configuration.nix
+
$ nixos-install
+
$ reboot</screen>
+
</example>
+
+
<example xml:id='ex-config'><title>NixOS Configuration</title>
+
<screen>
+
{ config, pkgs, ... }:
+
+
{
+
imports =
+
[ # Include the results of the hardware scan.
+
./hardware-configuration.nix
+
];
+
+
boot.loader.grub.device = "/dev/sda";
+
+
# Note: setting fileSystems is generally not
+
# necessary, since nixos-generate-config figures them out
+
# automatically in hardware-configuration.nix.
+
#fileSystems."/".device = "/dev/disk/by-label/nixos";
+
+
# Enable the OpenSSH server.
+
services.sshd.enable = true;
+
}</screen>
+
</example>
+
+
<xi:include href="installing-UEFI.xml" />
+
<xi:include href="installing-USB.xml" />
+
+
</chapter>
+44
nixos/doc/manual/installation/obtaining.xml
···
···
+
<chapter xmlns="http://docbook.org/ns/docbook"
+
xmlns:xlink="http://www.w3.org/1999/xlink"
+
xmlns:xi="http://www.w3.org/2001/XInclude"
+
version="5.0"
+
xml:id="sec-obtaining">
+
+
<title>Obtaining NixOS</title>
+
+
<para>NixOS ISO images can be downloaded from the <link
+
xlink:href="http://nixos.org/nixos/download.html">NixOS
+
homepage</link>. These can be burned onto a CD. It is also possible
+
to copy them onto a USB stick and install NixOS from there. For
+
details, see the <link
+
xlink:href="https://nixos.org/wiki/Installing_NixOS_from_a_USB_stick">NixOS
+
Wiki</link>.</para>
+
+
<para>As an alternative to installing NixOS yourself, you can get a
+
running NixOS system through several other means:
+
+
<itemizedlist>
+
<listitem>
+
<para>Using virtual appliances in Open Virtualization Format (OVF)
+
that can be imported into VirtualBox. These are available from
+
the <link xlink:href="http://nixos.org/nixos/download.html">NixOS
+
homepage</link>.</para>
+
</listitem>
+
<listitem>
+
<para>Using AMIs for Amazon’s EC2. To find one for your region
+
and instance type, please refer to the <link
+
xlink:href="https://github.com/NixOS/nixops/blob/master/nix/ec2-amis.nix">list
+
of most recent AMIs</link>.</para>
+
</listitem>
+
<listitem>
+
<para>Using NixOps, the NixOS-based cloud deployment tool, which
+
allows you to provision VirtualBox and EC2 NixOS instances from
+
declarative specifications. Check out the <link
+
xlink:href="https://github.com/NixOS/nixops">NixOps
+
homepage</link> for details.</para>
+
</listitem>
+
</itemizedlist>
+
+
</para>
+
+
</chapter>
+90
nixos/doc/manual/installation/upgrading.xml
···
···
+
<chapter xmlns="http://docbook.org/ns/docbook"
+
xmlns:xlink="http://www.w3.org/1999/xlink"
+
version="5.0"
+
xml:id="sec-upgrading">
+
+
<title>Upgrading NixOS</title>
+
+
<para>The best way to keep your NixOS installation up to date is to
+
use one of the NixOS <emphasis>channels</emphasis>. A channel is a
+
Nix mechanism for distributing Nix expressions and associated
+
binaries. The NixOS channels are updated automatically from NixOS’s
+
Git repository after certain tests have passed and all packages have
+
been built. These channels are:
+
+
<itemizedlist>
+
<listitem>
+
<para>Stable channels, such as <literal
+
xlink:href="http://nixos.org/channels/nixos-14.04">nixos-14.04</literal>.
+
These only get conservative bug fixes and package upgrades. For
+
instance, a channel update may cause the Linux kernel on your
+
system to be upgraded from 3.4.66 to 3.4.67 (a minor bug fix), but
+
not from 3.4.<replaceable>x</replaceable> to
+
3.11.<replaceable>x</replaceable> (a major change that has the
+
potential to break things). Stable channels are generally
+
maintained until the next stable branch is created.</para>
+
</listitem>
+
<listitem>
+
<para>The unstable channel, <literal
+
xlink:href="http://nixos.org/channels/nixos-unstable">nixos-unstable</literal>.
+
This corresponds to NixOS’s main development branch, and may thus
+
see radical changes between channel updates. It’s not recommended
+
for production systems.</para>
+
</listitem>
+
</itemizedlist>
+
+
To see what channels are available, go to <link
+
xlink:href="http://nixos.org/channels"/>. (Note that the URIs of the
+
various channels redirect to a directory that contains the channel’s
+
latest version and includes ISO images and VirtualBox
+
appliances.)</para>
+
+
<para>When you first install NixOS, you’re automatically subscribed to
+
the NixOS channel that corresponds to your installation source. For
+
instance, if you installed from a 14.04 ISO, you will be subscribed to
+
the <literal>nixos-14.04</literal> channel. To see which NixOS
+
channel you’re subscribed to, run the following as root:
+
+
<screen>
+
$ nix-channel --list | grep nixos
+
nixos https://nixos.org/channels/nixos-unstable
+
</screen>
+
+
To switch to a different NixOS channel, do
+
+
<screen>
+
$ nix-channel --add http://nixos.org/channels/<replaceable>channel-name</replaceable> nixos
+
</screen>
+
+
(Be sure to include the <literal>nixos</literal> parameter at the
+
end.) For instance, to use the NixOS 14.04 stable channel:
+
+
<screen>
+
$ nix-channel --add http://nixos.org/channels/nixos-14.04 nixos
+
</screen>
+
+
But it you want to live on the bleeding edge:
+
+
<screen>
+
$ nix-channel --add http://nixos.org/channels/nixos-unstable nixos
+
</screen>
+
+
</para>
+
+
<para>You can then upgrade NixOS to the latest version in your chosen
+
channel by running
+
+
<screen>
+
$ nixos-rebuild switch --upgrade
+
</screen>
+
+
which is equivalent to the more verbose <literal>nix-channel --update
+
nixos; nixos-rebuild switch</literal>.</para>
+
+
<warning><para>It is generally safe to switch back and forth between
+
channels. The only exception is that a newer NixOS may also have a
+
newer Nix version, which may involve an upgrade of Nix’s database
+
schema. This cannot be undone easily, so in that case you will not be
+
able to go back to your original channel.</para></warning>
+
+
</chapter>
+9 -15
nixos/doc/manual/manual.xml
···
<book xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink"
-
xmlns:xi="http://www.w3.org/2001/XInclude">
-
<info>
-
<title>NixOS Manual</title>
<subtitle>Version <xi:include href="version" parse="text" /></subtitle>
-
</info>
-
<preface>
<title>Preface</title>
···
</preface>
-
-
<xi:include href="installation.xml" />
-
<xi:include href="configuration.xml" />
-
<xi:include href="running.xml" />
<!-- <xi:include href="userconfiguration.xml" /> -->
-
<xi:include href="troubleshooting.xml" />
-
<xi:include href="containers.xml" />
-
<xi:include href="development.xml" />
-
-
<xi:include href="release-notes.xml" />
<appendix xml:id="ch-options">
-
<title>Configuration options</title>
<xi:include href="options-db.xml" />
</appendix>
···
<book xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink"
+
xmlns:xi="http://www.w3.org/2001/XInclude"
+
version="5.0"
+
xml:id="NixOSManual">
+
<info>
<title>NixOS Manual</title>
<subtitle>Version <xi:include href="version" parse="text" /></subtitle>
</info>
<preface>
<title>Preface</title>
···
</preface>
+
<xi:include href="installation/installation.xml" />
+
<xi:include href="configuration/configuration.xml" />
+
<xi:include href="administration/running.xml" />
<!-- <xi:include href="userconfiguration.xml" /> -->
+
<xi:include href="release-notes/release-notes.xml" />
<appendix xml:id="ch-options">
+
<title>Configuration Options</title>
<xi:include href="options-db.xml" />
</appendix>
+6 -44
nixos/doc/manual/release-notes.xml nixos/doc/manual/release-notes/rl-1404.xml
···
-
<appendix xmlns="http://docbook.org/ns/docbook"
-
xmlns:xlink="http://www.w3.org/1999/xlink"
-
xml:id="ch-release-notes">
-
-
<title>Release notes</title>
-
-
<!--==================================================================-->
-
-
<section xml:id="sec-release-14.10">
-
-
<title>Release 14.10 (“Caterpillar”, 2014/10/??)</title>
-
-
<para>When upgrading from a previous release, please be aware of the
-
following incompatible changes:
-
-
<itemizedlist>
-
-
<listitem><para>The host side of a container virtual Ethernet pair
-
is now called <literal>ve-<replaceable>container-name</replaceable></literal>
-
rather than <literal>c-<replaceable>container-name</replaceable></literal>.</para></listitem>
-
-
</itemizedlist>
-
-
</para>
-
-
</section>
-
-
-
<!--==================================================================-->
-
-
<section xml:id="sec-release-14.04">
<title>Release 14.04 (“Baboon”, 2014/04/30)</title>
···
</para>
-
</section>
-
-
<!--==================================================================-->
-
-
<section xml:id="sec-release-13.10">
-
-
<title>Release 13.10 (“Aardvark”, 2013/10/31)</title>
-
-
<para>This is the first stable release branch of NixOS.</para>
-
-
</section>
-
-
</appendix>
···
+
<chapter xmlns="http://docbook.org/ns/docbook"
+
xmlns:xlink="http://www.w3.org/1999/xlink"
+
xmlns:xi="http://www.w3.org/2001/XInclude"
+
version="5.0"
+
xml:id="sec-release-14.04">
<title>Release 14.04 (“Baboon”, 2014/04/30)</title>
···
</para>
+
</chapter>
+17
nixos/doc/manual/release-notes/release-notes.xml
···
···
+
<part xmlns="http://docbook.org/ns/docbook"
+
xmlns:xlink="http://www.w3.org/1999/xlink"
+
xmlns:xi="http://www.w3.org/2001/XInclude"
+
version="5.0"
+
xml:id="ch-release-notes">
+
+
<title>Release Notes</title>
+
+
<partintro>
+
<para>This section lists the release notes for each stable version of NixOS.</para>
+
</partintro>
+
+
<xi:include href="rl-1410.xml" />
+
<xi:include href="rl-1404.xml" />
+
<xi:include href="rl-1310.xml" />
+
+
</part>
+11
nixos/doc/manual/release-notes/rl-1310.xml
···
···
+
<chapter xmlns="http://docbook.org/ns/docbook"
+
xmlns:xlink="http://www.w3.org/1999/xlink"
+
xmlns:xi="http://www.w3.org/2001/XInclude"
+
version="5.0"
+
xml:id="sec-release-13.10">
+
+
<title>Release 13.10 (“Aardvark”, 2013/10/31)</title>
+
+
<para>This is the first stable release branch of NixOS.</para>
+
+
</chapter>
+22
nixos/doc/manual/release-notes/rl-1410.xml
···
···
+
<chapter xmlns="http://docbook.org/ns/docbook"
+
xmlns:xlink="http://www.w3.org/1999/xlink"
+
xmlns:xi="http://www.w3.org/2001/XInclude"
+
version="5.0"
+
xml:id="sec-release-14.10">
+
+
<title>Release 14.10 (“Caterpillar”, 2014/10/??)</title>
+
+
<para>When upgrading from a previous release, please be aware of the
+
following incompatible changes:
+
+
<itemizedlist>
+
+
<listitem><para>The host side of a container virtual Ethernet pair
+
is now called <literal>ve-<replaceable>container-name</replaceable></literal>
+
rather than <literal>c-<replaceable>container-name</replaceable></literal>.</para></listitem>
+
+
</itemizedlist>
+
+
</para>
+
+
</chapter>
-369
nixos/doc/manual/running.xml
···
-
<chapter xmlns="http://docbook.org/ns/docbook"
-
xmlns:xlink="http://www.w3.org/1999/xlink"
-
xml:id="ch-running">
-
-
<title>Running NixOS</title>
-
-
<para>This chapter describes various aspects of managing a running
-
NixOS system, such as how to use the <command>systemd</command>
-
service manager.</para>
-
-
-
<!--===============================================================-->
-
-
<section xml:id="sec-systemctl"><title>Service management</title>
-
-
<para>In NixOS, all system services are started and monitored using
-
the systemd program. Systemd is the “init” process of the system
-
(i.e. PID 1), the parent of all other processes. It manages a set of
-
so-called “units”, which can be things like system services
-
(programs), but also mount points, swap files, devices, targets
-
(groups of units) and more. Units can have complex dependencies; for
-
instance, one unit can require that another unit must be successfully
-
started before the first unit can be started. When the system boots,
-
it starts a unit named <literal>default.target</literal>; the
-
dependencies of this unit cause all system services to be started,
-
file systems to be mounted, swap files to be activated, and so
-
on.</para>
-
-
<para>The command <command>systemctl</command> is the main way to
-
interact with <command>systemd</command>. Without any arguments, it
-
shows the status of active units:
-
-
<screen>
-
$ systemctl
-
-.mount loaded active mounted /
-
swapfile.swap loaded active active /swapfile
-
sshd.service loaded active running SSH Daemon
-
graphical.target loaded active active Graphical Interface
-
<replaceable>...</replaceable>
-
</screen>
-
-
</para>
-
-
<para>You can ask for detailed status information about a unit, for
-
instance, the PostgreSQL database service:
-
-
<screen>
-
$ systemctl status postgresql.service
-
postgresql.service - PostgreSQL Server
-
Loaded: loaded (/nix/store/pn3q73mvh75gsrl8w7fdlfk3fq5qm5mw-unit/postgresql.service)
-
Active: active (running) since Mon, 2013-01-07 15:55:57 CET; 9h ago
-
Main PID: 2390 (postgres)
-
CGroup: name=systemd:/system/postgresql.service
-
├─2390 postgres
-
├─2418 postgres: writer process
-
├─2419 postgres: wal writer process
-
├─2420 postgres: autovacuum launcher process
-
├─2421 postgres: stats collector process
-
└─2498 postgres: zabbix zabbix [local] idle
-
-
Jan 07 15:55:55 hagbard postgres[2394]: [1-1] LOG: database system was shut down at 2013-01-07 15:55:05 CET
-
Jan 07 15:55:57 hagbard postgres[2390]: [1-1] LOG: database system is ready to accept connections
-
Jan 07 15:55:57 hagbard postgres[2420]: [1-1] LOG: autovacuum launcher started
-
Jan 07 15:55:57 hagbard systemd[1]: Started PostgreSQL Server.
-
</screen>
-
-
Note that this shows the status of the unit (active and running), all
-
the processes belonging to the service, as well as the most recent log
-
messages from the service.
-
-
</para>
-
-
<para>Units can be stopped, started or restarted:
-
-
<screen>
-
$ systemctl stop postgresql.service
-
$ systemctl start postgresql.service
-
$ systemctl restart postgresql.service
-
</screen>
-
-
These operations are synchronous: they wait until the service has
-
finished starting or stopping (or has failed). Starting a unit will
-
cause the dependencies of that unit to be started as well (if
-
necessary).</para>
-
-
<!-- - cgroups: each service and user session is a cgroup
-
-
- cgroup resource management -->
-
-
</section>
-
-
-
<!--===============================================================-->
-
-
<section xml:id="sec-rebooting"><title>Rebooting and shutting down</title>
-
-
<para>The system can be shut down (and automatically powered off) by
-
doing:
-
-
<screen>
-
$ shutdown
-
</screen>
-
-
This is equivalent to running <command>systemctl
-
poweroff</command>.</para>
-
-
<para>To reboot the system, run
-
-
<screen>
-
$ reboot
-
</screen>
-
-
which is equivalent to <command>systemctl reboot</command>.
-
Alternatively, you can quickly reboot the system using
-
<literal>kexec</literal>, which bypasses the BIOS by directly loading
-
the new kernel into memory:
-
-
<screen>
-
$ systemctl kexec
-
</screen>
-
-
</para>
-
-
<para>The machine can be suspended to RAM (if supported) using
-
<command>systemctl suspend</command>, and suspended to disk using
-
<command>systemctl hibernate</command>.</para>
-
-
<para>These commands can be run by any user who is logged in locally,
-
i.e. on a virtual console or in X11; otherwise, the user is asked for
-
authentication.</para>
-
-
</section>
-
-
-
<!--===============================================================-->
-
-
<section xml:id="sec-user-sessions"><title>User sessions</title>
-
-
<para>Systemd keeps track of all users who are logged into the system
-
(e.g. on a virtual console or remotely via SSH). The command
-
<command>loginctl</command> allows querying and manipulating user
-
sessions. For instance, to list all user sessions:
-
-
<screen>
-
$ loginctl
-
SESSION UID USER SEAT
-
c1 500 eelco seat0
-
c3 0 root seat0
-
c4 500 alice
-
</screen>
-
-
This shows that two users are logged in locally, while another is
-
logged in remotely. (“Seats” are essentially the combinations of
-
displays and input devices attached to the system; usually, there is
-
only one seat.) To get information about a session:
-
-
<screen>
-
$ loginctl session-status c3
-
c3 - root (0)
-
Since: Tue, 2013-01-08 01:17:56 CET; 4min 42s ago
-
Leader: 2536 (login)
-
Seat: seat0; vc3
-
TTY: /dev/tty3
-
Service: login; type tty; class user
-
State: online
-
CGroup: name=systemd:/user/root/c3
-
├─ 2536 /nix/store/10mn4xip9n7y9bxqwnsx7xwx2v2g34xn-shadow-4.1.5.1/bin/login --
-
├─10339 -bash
-
└─10355 w3m nixos.org
-
</screen>
-
-
This shows that the user is logged in on virtual console 3. It also
-
lists the processes belonging to this session. Since systemd keeps
-
track of this, you can terminate a session in a way that ensures that
-
all the session’s processes are gone:
-
-
<screen>
-
$ loginctl terminate-session c3
-
</screen>
-
-
</para>
-
-
</section>
-
-
-
<!--===============================================================-->
-
-
<section xml:id="sec-cgroups"><title>Control groups</title>
-
-
<para>To keep track of the processes in a running system, systemd uses
-
<emphasis>control groups</emphasis> (cgroups). A control group is a
-
set of processes used to allocate resources such as CPU, memory or I/O
-
bandwidth. There can be multiple control group hierarchies, allowing
-
each kind of resource to be managed independently.</para>
-
-
<para>The command <command>systemd-cgls</command> lists all control
-
groups in the <literal>systemd</literal> hierarchy, which is what
-
systemd uses to keep track of the processes belonging to each service
-
or user session:
-
-
<screen>
-
$ systemd-cgls
-
├─user
-
│ └─eelco
-
│ └─c1
-
│ ├─ 2567 -:0
-
│ ├─ 2682 kdeinit4: kdeinit4 Running...
-
│ ├─ <replaceable>...</replaceable>
-
│ └─10851 sh -c less -R
-
└─system
-
├─httpd.service
-
│ ├─2444 httpd -f /nix/store/3pyacby5cpr55a03qwbnndizpciwq161-httpd.conf -DNO_DETACH
-
│ └─<replaceable>...</replaceable>
-
├─dhcpcd.service
-
│ └─2376 dhcpcd --config /nix/store/f8dif8dsi2yaa70n03xir8r653776ka6-dhcpcd.conf
-
└─ <replaceable>...</replaceable>
-
</screen>
-
-
Similarly, <command>systemd-cgls cpu</command> shows the cgroups in
-
the CPU hierarchy, which allows per-cgroup CPU scheduling priorities.
-
By default, every systemd service gets its own CPU cgroup, while all
-
user sessions are in the top-level CPU cgroup. This ensures, for
-
instance, that a thousand run-away processes in the
-
<literal>httpd.service</literal> cgroup cannot starve the CPU for one
-
process in the <literal>postgresql.service</literal> cgroup. (By
-
contrast, it they were in the same cgroup, then the PostgreSQL process
-
would get 1/1001 of the cgroup’s CPU time.) You can limit a service’s
-
CPU share in <filename>configuration.nix</filename>:
-
-
<programlisting>
-
systemd.services.httpd.serviceConfig.CPUShares = 512;
-
</programlisting>
-
-
By default, every cgroup has 1024 CPU shares, so this will halve the
-
CPU allocation of the <literal>httpd.service</literal> cgroup.</para>
-
-
<para>There also is a <literal>memory</literal> hierarchy that
-
controls memory allocation limits; by default, all processes are in
-
the top-level cgroup, so any service or session can exhaust all
-
available memory. Per-cgroup memory limits can be specified in
-
<filename>configuration.nix</filename>; for instance, to limit
-
<literal>httpd.service</literal> to 512 MiB of RAM (excluding swap)
-
and 640 MiB of RAM (including swap):
-
-
<programlisting>
-
systemd.services.httpd.serviceConfig.MemoryLimit = "512M";
-
systemd.services.httpd.serviceConfig.ControlGroupAttribute = [ "memory.memsw.limit_in_bytes 640M" ];
-
</programlisting>
-
-
</para>
-
-
<para>The command <command>systemd-cgtop</command> shows a
-
continuously updated list of all cgroups with their CPU and memory
-
usage.</para>
-
-
</section>
-
-
-
<!--===============================================================-->
-
-
<section xml:id="sec-logging"><title>Logging</title>
-
-
<para>System-wide logging is provided by systemd’s
-
<emphasis>journal</emphasis>, which subsumes traditional logging
-
daemons such as syslogd and klogd. Log entries are kept in binary
-
files in <filename>/var/log/journal/</filename>. The command
-
<literal>journalctl</literal> allows you to see the contents of the
-
journal. For example,
-
-
<screen>
-
$ journalctl -b
-
</screen>
-
-
shows all journal entries since the last reboot. (The output of
-
<command>journalctl</command> is piped into <command>less</command> by
-
default.) You can use various options and match operators to restrict
-
output to messages of interest. For instance, to get all messages
-
from PostgreSQL:
-
-
<screen>
-
$ journalctl -u postgresql.service
-
-- Logs begin at Mon, 2013-01-07 13:28:01 CET, end at Tue, 2013-01-08 01:09:57 CET. --
-
...
-
Jan 07 15:44:14 hagbard postgres[2681]: [2-1] LOG: database system is shut down
-
-- Reboot --
-
Jan 07 15:45:10 hagbard postgres[2532]: [1-1] LOG: database system was shut down at 2013-01-07 15:44:14 CET
-
Jan 07 15:45:13 hagbard postgres[2500]: [1-1] LOG: database system is ready to accept connections
-
</screen>
-
-
Or to get all messages since the last reboot that have at least a
-
“critical” severity level:
-
-
<screen>
-
$ journalctl -b -p crit
-
Dec 17 21:08:06 mandark sudo[3673]: pam_unix(sudo:auth): auth could not identify password for [alice]
-
Dec 29 01:30:22 mandark kernel[6131]: [1053513.909444] CPU6: Core temperature above threshold, cpu clock throttled (total events = 1)
-
</screen>
-
-
</para>
-
-
<para>The system journal is readable by root and by users in the
-
<literal>wheel</literal> and <literal>systemd-journal</literal>
-
groups. All users have a private journal that can be read using
-
<command>journalctl</command>.</para>
-
-
</section>
-
-
-
<!--===============================================================-->
-
-
<section xml:id="sec-nix-gc"><title>Cleaning up the Nix store</title>
-
-
<para>Nix has a purely functional model, meaning that packages are
-
never upgraded in place. Instead new versions of packages end up in a
-
different location in the Nix store (<filename>/nix/store</filename>).
-
You should periodically run Nix’s <emphasis>garbage
-
collector</emphasis> to remove old, unreferenced packages. This is
-
easy:
-
-
<screen>
-
$ nix-collect-garbage
-
</screen>
-
-
Alternatively, you can use a systemd unit that does the same in the
-
background:
-
-
<screen>
-
$ systemctl start nix-gc.service
-
</screen>
-
-
You can tell NixOS in <filename>configuration.nix</filename> to run
-
this unit automatically at certain points in time, for instance, every
-
night at 03:15:
-
-
<programlisting>
-
nix.gc.automatic = true;
-
nix.gc.dates = "03:15";
-
</programlisting>
-
-
</para>
-
-
<para>The commands above do not remove garbage collector roots, such
-
as old system configurations. Thus they do not remove the ability to
-
roll back to previous configurations. The following command deletes
-
old roots, removing the ability to roll back to them:
-
<screen>
-
$ nix-collect-garbage -d
-
</screen>
-
You can also do this for specific profiles, e.g.
-
<screen>
-
$ nix-env -p /nix/var/nix/profiles/per-user/eelco/profile --delete-generations old
-
</screen>
-
Note that NixOS system configurations are stored in the profile
-
<filename>/nix/var/nix/profiles/system</filename>.</para>
-
-
<para>Another way to reclaim disk space (often as much as 40% of the
-
size of the Nix store) is to run Nix’s store optimiser, which seeks
-
out identical files in the store and replaces them with hard links to
-
a single copy.
-
<screen>
-
$ nix-store --optimise
-
</screen>
-
Since this command needs to read the entire Nix store, it can take
-
quite a while to finish.</para>
-
-
</section>
-
-
-
</chapter>
···
-199
nixos/doc/manual/troubleshooting.xml
···
-
<chapter xmlns="http://docbook.org/ns/docbook"
-
xmlns:xlink="http://www.w3.org/1999/xlink"
-
xml:id="ch-troubleshooting">
-
-
<title>Troubleshooting</title>
-
-
-
<!--===============================================================-->
-
-
<section xml:id="sec-boot-problems"><title>Boot problems</title>
-
-
<para>If NixOS fails to boot, there are a number of kernel command
-
line parameters that may help you to identify or fix the issue. You
-
can add these parameters in the GRUB boot menu by pressing “e” to
-
modify the selected boot entry and editing the line starting with
-
<literal>linux</literal>. The following are some useful kernel command
-
line parameters that are recognised by the NixOS boot scripts or by
-
systemd:
-
-
<variablelist>
-
-
<varlistentry><term><literal>boot.shell_on_fail</literal></term>
-
<listitem><para>Start a root shell if something goes wrong in
-
stage 1 of the boot process (the initial ramdisk). This is
-
disabled by default because there is no authentication for the
-
root shell.</para></listitem>
-
</varlistentry>
-
-
<varlistentry><term><literal>boot.debug1</literal></term>
-
<listitem><para>Start an interactive shell in stage 1 before
-
anything useful has been done. That is, no modules have been
-
loaded and no file systems have been mounted, except for
-
<filename>/proc</filename> and
-
<filename>/sys</filename>.</para></listitem>
-
</varlistentry>
-
-
<varlistentry><term><literal>boot.trace</literal></term>
-
<listitem><para>Print every shell command executed by the stage 1
-
and 2 boot scripts.</para></listitem>
-
</varlistentry>
-
-
<varlistentry><term><literal>single</literal></term>
-
<listitem><para>Boot into rescue mode (a.k.a. single user mode).
-
This will cause systemd to start nothing but the unit
-
<literal>rescue.target</literal>, which runs
-
<command>sulogin</command> to prompt for the root password and
-
start a root login shell. Exiting the shell causes the system to
-
continue with the normal boot process.</para></listitem>
-
</varlistentry>
-
-
<varlistentry><term><literal>systemd.log_level=debug systemd.log_target=console</literal></term>
-
<listitem><para>Make systemd very verbose and send log messages to
-
the console instead of the journal.</para></listitem>
-
</varlistentry>
-
-
</variablelist>
-
-
For more parameters recognised by systemd, see
-
<citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>.</para>
-
-
<para>If no login prompts or X11 login screens appear (e.g. due to
-
hanging dependencies), you can press Alt+ArrowUp. If you’re lucky,
-
this will start rescue mode (described above). (Also note that since
-
most units have a 90-second timeout before systemd gives up on them,
-
the <command>agetty</command> login prompts should appear eventually
-
unless something is very wrong.)</para>
-
-
</section>
-
-
-
<!--===============================================================-->
-
-
<section xml:id="sec-maintenance-mode"><title>Maintenance mode</title>
-
-
<para>You can enter rescue mode by running:
-
-
<screen>
-
$ systemctl rescue</screen>
-
-
This will eventually give you a single-user root shell. Systemd will
-
stop (almost) all system services. To get out of maintenance mode,
-
just exit from the rescue shell.</para>
-
-
</section>
-
-
-
<!--===============================================================-->
-
-
<section xml:id="sec-rollback"><title>Rolling back configuration changes</title>
-
-
<para>After running <command>nixos-rebuild</command> to switch to a
-
new configuration, you may find that the new configuration doesn’t
-
work very well. In that case, there are several ways to return to a
-
previous configuration.</para>
-
-
<para>First, the GRUB boot manager allows you to boot into any
-
previous configuration that hasn’t been garbage-collected. These
-
configurations can be found under the GRUB submenu “NixOS - All
-
configurations”. This is especially useful if the new configuration
-
fails to boot. After the system has booted, you can make the selected
-
configuration the default for subsequent boots:
-
-
<screen>
-
$ /run/current-system/bin/switch-to-configuration boot</screen>
-
-
</para>
-
-
<para>Second, you can switch to the previous configuration in a running
-
system:
-
-
<screen>
-
$ nixos-rebuild switch --rollback</screen>
-
-
This is equivalent to running:
-
-
<screen>
-
$ /nix/var/nix/profiles/system-<replaceable>N</replaceable>-link/bin/switch-to-configuration switch</screen>
-
-
where <replaceable>N</replaceable> is the number of the NixOS system
-
configuration. To get a list of the available configurations, do:
-
-
<screen>
-
$ ls -l /nix/var/nix/profiles/system-*-link
-
<replaceable>...</replaceable>
-
lrwxrwxrwx 1 root root 78 Aug 12 13:54 /nix/var/nix/profiles/system-268-link -> /nix/store/202b...-nixos-13.07pre4932_5a676e4-4be1055
-
</screen>
-
-
</para>
-
-
</section>
-
-
-
<!--===============================================================-->
-
-
<section xml:id="sec-nix-store-corruption"><title>Nix store corruption</title>
-
-
<para>After a system crash, it’s possible for files in the Nix store
-
to become corrupted. (For instance, the Ext4 file system has the
-
tendency to replace un-synced files with zero bytes.) NixOS tries
-
hard to prevent this from happening: it performs a
-
<command>sync</command> before switching to a new configuration, and
-
Nix’s database is fully transactional. If corruption still occurs,
-
you may be able to fix it automatically.</para>
-
-
<para>If the corruption is in a path in the closure of the NixOS
-
system configuration, you can fix it by doing
-
-
<screen>
-
$ nixos-rebuild switch --repair
-
</screen>
-
-
This will cause Nix to check every path in the closure, and if its
-
cryptographic hash differs from the hash recorded in Nix’s database,
-
the path is rebuilt or redownloaded.</para>
-
-
<para>You can also scan the entire Nix store for corrupt paths:
-
-
<screen>
-
$ nix-store --verify --check-contents --repair
-
</screen>
-
-
Any corrupt paths will be redownloaded if they’re available in a
-
binary cache; otherwise, they cannot be repaired.</para>
-
-
</section>
-
-
-
<!--===============================================================-->
-
-
<section xml:id="sec-nix-network-issues"><title>Nix network issues</title>
-
-
<para>Nix uses a so-called <emphasis>binary cache</emphasis> to
-
optimise building a package from source into downloading it as a
-
pre-built binary. That is, whenever a command like
-
<command>nixos-rebuild</command> needs a path in the Nix store, Nix
-
will try to download that path from the Internet rather than build it
-
from source. The default binary cache is
-
<uri>http://cache.nixos.org/</uri>. If this cache is unreachable, Nix
-
operations may take a long time due to HTTP connection timeouts. You
-
can disable the use of the binary cache by adding <option>--option
-
use-binary-caches false</option>, e.g.
-
-
<screen>
-
$ nixos-rebuild switch --option use-binary-caches false
-
</screen>
-
-
If you have an alternative binary cache at your disposal, you can use
-
it instead:
-
-
<screen>
-
$ nixos-rebuild switch --option binary-caches http://my-cache.example.org/
-
</screen>
-
-
</para>
-
-
</section>
-
-
-
</chapter>
···