summary refs log tree commit diff
path: root/nixos/doc/manual
diff options
context:
space:
mode:
authorMikey Ariel <mariel@redhat.com>2014-08-24 19:18:18 +0200
committerEelco Dolstra <eelco.dolstra@logicblox.com>2014-08-26 19:03:49 +0200
commita099ca45054940b63b1615920de158ebafb25ea8 (patch)
tree52907df9dc996cbab14885c8eab72b473086126a /nixos/doc/manual
parent8707a070baca84d881a7e03e04a44374d8cc05e1 (diff)
downloadnixpkgs-a099ca45054940b63b1615920de158ebafb25ea8.tar
nixpkgs-a099ca45054940b63b1615920de158ebafb25ea8.tar.gz
nixpkgs-a099ca45054940b63b1615920de158ebafb25ea8.tar.bz2
nixpkgs-a099ca45054940b63b1615920de158ebafb25ea8.tar.lz
nixpkgs-a099ca45054940b63b1615920de158ebafb25ea8.tar.xz
nixpkgs-a099ca45054940b63b1615920de158ebafb25ea8.tar.zst
nixpkgs-a099ca45054940b63b1615920de158ebafb25ea8.zip
Chunk NixOS manual
[Squashed commits to make git blame etc. more likely to work. -ED]
Diffstat (limited to 'nixos/doc/manual')
-rw-r--r--nixos/doc/manual/administration/boot-problems.xml65
-rw-r--r--nixos/doc/manual/administration/cleaning-store.xml62
-rw-r--r--nixos/doc/manual/administration/container-networking.xml50
-rw-r--r--nixos/doc/manual/administration/containers.xml34
-rw-r--r--nixos/doc/manual/administration/control-groups.xml75
-rw-r--r--nixos/doc/manual/administration/declarative-containers.xml52
-rw-r--r--nixos/doc/manual/administration/imperative-containers.xml124
-rw-r--r--nixos/doc/manual/administration/logging.xml52
-rw-r--r--nixos/doc/manual/administration/maintenance-mode.xml18
-rw-r--r--nixos/doc/manual/administration/network-problems.xml33
-rw-r--r--nixos/doc/manual/administration/rebooting.xml44
-rw-r--r--nixos/doc/manual/administration/rollback.xml48
-rw-r--r--nixos/doc/manual/administration/running.xml24
-rw-r--r--nixos/doc/manual/administration/service-mgmt.xml83
-rw-r--r--nixos/doc/manual/administration/store-corruption.xml37
-rw-r--r--nixos/doc/manual/administration/troubleshooting.xml18
-rw-r--r--nixos/doc/manual/administration/user-sessions.xml53
-rw-r--r--nixos/doc/manual/configuration.xml1563
-rw-r--r--nixos/doc/manual/configuration/LUKS-file-systems.xml42
-rw-r--r--nixos/doc/manual/configuration/abstractions.xml166
-rw-r--r--nixos/doc/manual/configuration/ad-hoc-network-config.xml24
-rw-r--r--nixos/doc/manual/configuration/ad-hoc-packages.xml63
-rw-r--r--nixos/doc/manual/configuration/adding-custom-packages.xml84
-rw-r--r--nixos/doc/manual/configuration/config-file.xml213
-rw-r--r--nixos/doc/manual/configuration/config-syntax.xml27
-rw-r--r--nixos/doc/manual/configuration/configuration.xml29
-rw-r--r--nixos/doc/manual/configuration/customizing-packages.xml92
-rw-r--r--nixos/doc/manual/configuration/declarative-packages.xml43
-rw-r--r--nixos/doc/manual/configuration/file-systems.xml40
-rw-r--r--nixos/doc/manual/configuration/firewall.xml38
-rw-r--r--nixos/doc/manual/configuration/ipv4-config.xml47
-rw-r--r--nixos/doc/manual/configuration/ipv6-config.xml19
-rw-r--r--nixos/doc/manual/configuration/linux-kernel.xml69
-rw-r--r--nixos/doc/manual/configuration/modularity.xml143
-rw-r--r--nixos/doc/manual/configuration/network-manager.xml27
-rw-r--r--nixos/doc/manual/configuration/networking.xml22
-rw-r--r--nixos/doc/manual/configuration/package-mgmt.xml34
-rw-r--r--nixos/doc/manual/configuration/ssh.xml32
-rw-r--r--nixos/doc/manual/configuration/summary.xml191
-rw-r--r--nixos/doc/manual/configuration/user-mgmt.xml95
-rw-r--r--nixos/doc/manual/configuration/wireless.xml41
-rw-r--r--nixos/doc/manual/configuration/x-windows.xml94
-rw-r--r--nixos/doc/manual/containers.xml242
-rw-r--r--nixos/doc/manual/development.xml1119
-rw-r--r--nixos/doc/manual/development/building-nixos.xml32
-rw-r--r--nixos/doc/manual/development/building-parts.xml113
-rw-r--r--nixos/doc/manual/development/development.xml20
-rw-r--r--nixos/doc/manual/development/nixos-tests.xml19
-rw-r--r--nixos/doc/manual/development/option-declarations.xml141
-rw-r--r--nixos/doc/manual/development/option-def.xml112
-rw-r--r--nixos/doc/manual/development/running-nixos-tests.xml77
-rw-r--r--nixos/doc/manual/development/sources.xml95
-rw-r--r--nixos/doc/manual/development/testing-installer.xml27
-rw-r--r--nixos/doc/manual/development/writing-modules.xml175
-rw-r--r--nixos/doc/manual/development/writing-nixos-tests.xml251
-rw-r--r--nixos/doc/manual/installation.xml570
-rw-r--r--nixos/doc/manual/installation/changing-config.xml90
-rw-r--r--nixos/doc/manual/installation/installation.xml21
-rw-r--r--nixos/doc/manual/installation/installing-UEFI.xml51
-rw-r--r--nixos/doc/manual/installation/installing-USB.xml30
-rw-r--r--nixos/doc/manual/installation/installing.xml264
-rw-r--r--nixos/doc/manual/installation/obtaining.xml44
-rw-r--r--nixos/doc/manual/installation/upgrading.xml90
-rw-r--r--nixos/doc/manual/manual.xml24
-rw-r--r--nixos/doc/manual/release-notes/release-notes.xml17
-rw-r--r--nixos/doc/manual/release-notes/rl-1310.xml11
-rw-r--r--nixos/doc/manual/release-notes/rl-1404.xml (renamed from nixos/doc/manual/release-notes.xml)50
-rw-r--r--nixos/doc/manual/release-notes/rl-1410.xml22
-rw-r--r--nixos/doc/manual/running.xml369
-rw-r--r--nixos/doc/manual/troubleshooting.xml199
70 files changed, 4264 insertions, 4121 deletions
diff --git a/nixos/doc/manual/administration/boot-problems.xml b/nixos/doc/manual/administration/boot-problems.xml
new file mode 100644
index 00000000000..be6ff3aac0f
--- /dev/null
+++ b/nixos/doc/manual/administration/boot-problems.xml
@@ -0,0 +1,65 @@
+<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>
\ No newline at end of file
diff --git a/nixos/doc/manual/administration/cleaning-store.xml b/nixos/doc/manual/administration/cleaning-store.xml
new file mode 100644
index 00000000000..41dc65795b6
--- /dev/null
+++ b/nixos/doc/manual/administration/cleaning-store.xml
@@ -0,0 +1,62 @@
+<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>
\ No newline at end of file
diff --git a/nixos/doc/manual/administration/container-networking.xml b/nixos/doc/manual/administration/container-networking.xml
new file mode 100644
index 00000000000..adea3e69840
--- /dev/null
+++ b/nixos/doc/manual/administration/container-networking.xml
@@ -0,0 +1,50 @@
+<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>
\ No newline at end of file
diff --git a/nixos/doc/manual/administration/containers.xml b/nixos/doc/manual/administration/containers.xml
new file mode 100644
index 00000000000..4cd2c8ae556
--- /dev/null
+++ b/nixos/doc/manual/administration/containers.xml
@@ -0,0 +1,34 @@
+<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>
+
diff --git a/nixos/doc/manual/administration/control-groups.xml b/nixos/doc/manual/administration/control-groups.xml
new file mode 100644
index 00000000000..86c684cdfe5
--- /dev/null
+++ b/nixos/doc/manual/administration/control-groups.xml
@@ -0,0 +1,75 @@
+<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>
\ No newline at end of file
diff --git a/nixos/doc/manual/administration/declarative-containers.xml b/nixos/doc/manual/administration/declarative-containers.xml
new file mode 100644
index 00000000000..177ebdd8db1
--- /dev/null
+++ b/nixos/doc/manual/administration/declarative-containers.xml
@@ -0,0 +1,52 @@
+<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>
\ No newline at end of file
diff --git a/nixos/doc/manual/administration/imperative-containers.xml b/nixos/doc/manual/administration/imperative-containers.xml
new file mode 100644
index 00000000000..6131d4e04ea
--- /dev/null
+++ b/nixos/doc/manual/administration/imperative-containers.xml
@@ -0,0 +1,124 @@
+<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>
\ No newline at end of file
diff --git a/nixos/doc/manual/administration/logging.xml b/nixos/doc/manual/administration/logging.xml
new file mode 100644
index 00000000000..1d5df7770e2
--- /dev/null
+++ b/nixos/doc/manual/administration/logging.xml
@@ -0,0 +1,52 @@
+<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>
\ No newline at end of file
diff --git a/nixos/doc/manual/administration/maintenance-mode.xml b/nixos/doc/manual/administration/maintenance-mode.xml
new file mode 100644
index 00000000000..15c1f902da7
--- /dev/null
+++ b/nixos/doc/manual/administration/maintenance-mode.xml
@@ -0,0 +1,18 @@
+<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>
\ No newline at end of file
diff --git a/nixos/doc/manual/administration/network-problems.xml b/nixos/doc/manual/administration/network-problems.xml
new file mode 100644
index 00000000000..5ba1bfd5ac9
--- /dev/null
+++ b/nixos/doc/manual/administration/network-problems.xml
@@ -0,0 +1,33 @@
+<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>
\ No newline at end of file
diff --git a/nixos/doc/manual/administration/rebooting.xml b/nixos/doc/manual/administration/rebooting.xml
new file mode 100644
index 00000000000..d1db7b141cf
--- /dev/null
+++ b/nixos/doc/manual/administration/rebooting.xml
@@ -0,0 +1,44 @@
+<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>
\ No newline at end of file
diff --git a/nixos/doc/manual/administration/rollback.xml b/nixos/doc/manual/administration/rollback.xml
new file mode 100644
index 00000000000..23a3ece7c07
--- /dev/null
+++ b/nixos/doc/manual/administration/rollback.xml
@@ -0,0 +1,48 @@
+<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>
\ No newline at end of file
diff --git a/nixos/doc/manual/administration/running.xml b/nixos/doc/manual/administration/running.xml
new file mode 100644
index 00000000000..9091511ed52
--- /dev/null
+++ b/nixos/doc/manual/administration/running.xml
@@ -0,0 +1,24 @@
+<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>
diff --git a/nixos/doc/manual/administration/service-mgmt.xml b/nixos/doc/manual/administration/service-mgmt.xml
new file mode 100644
index 00000000000..c0940a42f30
--- /dev/null
+++ b/nixos/doc/manual/administration/service-mgmt.xml
@@ -0,0 +1,83 @@
+<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>
diff --git a/nixos/doc/manual/administration/store-corruption.xml b/nixos/doc/manual/administration/store-corruption.xml
new file mode 100644
index 00000000000..0160cb45358
--- /dev/null
+++ b/nixos/doc/manual/administration/store-corruption.xml
@@ -0,0 +1,37 @@
+<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>
\ No newline at end of file
diff --git a/nixos/doc/manual/administration/troubleshooting.xml b/nixos/doc/manual/administration/troubleshooting.xml
new file mode 100644
index 00000000000..351fb188331
--- /dev/null
+++ b/nixos/doc/manual/administration/troubleshooting.xml
@@ -0,0 +1,18 @@
+<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>
diff --git a/nixos/doc/manual/administration/user-sessions.xml b/nixos/doc/manual/administration/user-sessions.xml
new file mode 100644
index 00000000000..05e2c1a9b29
--- /dev/null
+++ b/nixos/doc/manual/administration/user-sessions.xml
@@ -0,0 +1,53 @@
+<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>
\ No newline at end of file
diff --git a/nixos/doc/manual/configuration.xml b/nixos/doc/manual/configuration.xml
deleted file mode 100644
index 64372f3bbf1..00000000000
--- a/nixos/doc/manual/configuration.xml
+++ /dev/null
@@ -1,1563 +0,0 @@
-<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>
diff --git a/nixos/doc/manual/configuration/LUKS-file-systems.xml b/nixos/doc/manual/configuration/LUKS-file-systems.xml
new file mode 100644
index 00000000000..45475dbcd44
--- /dev/null
+++ b/nixos/doc/manual/configuration/LUKS-file-systems.xml
@@ -0,0 +1,42 @@
+<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>
diff --git a/nixos/doc/manual/configuration/abstractions.xml b/nixos/doc/manual/configuration/abstractions.xml
new file mode 100644
index 00000000000..cbd54bca62f
--- /dev/null
+++ b/nixos/doc/manual/configuration/abstractions.xml
@@ -0,0 +1,166 @@
+<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>
diff --git a/nixos/doc/manual/configuration/ad-hoc-network-config.xml b/nixos/doc/manual/configuration/ad-hoc-network-config.xml
new file mode 100644
index 00000000000..26a572ba1fb
--- /dev/null
+++ b/nixos/doc/manual/configuration/ad-hoc-network-config.xml
@@ -0,0 +1,24 @@
+<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>
diff --git a/nixos/doc/manual/configuration/ad-hoc-packages.xml b/nixos/doc/manual/configuration/ad-hoc-packages.xml
new file mode 100644
index 00000000000..e237e20c4ff
--- /dev/null
+++ b/nixos/doc/manual/configuration/ad-hoc-packages.xml
@@ -0,0 +1,63 @@
+<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>
diff --git a/nixos/doc/manual/configuration/adding-custom-packages.xml b/nixos/doc/manual/configuration/adding-custom-packages.xml
new file mode 100644
index 00000000000..c1789fcbc04
--- /dev/null
+++ b/nixos/doc/manual/configuration/adding-custom-packages.xml
@@ -0,0 +1,84 @@
+<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>
diff --git a/nixos/doc/manual/configuration/config-file.xml b/nixos/doc/manual/configuration/config-file.xml
new file mode 100644
index 00000000000..2a58ff25941
--- /dev/null
+++ b/nixos/doc/manual/configuration/config-file.xml
@@ -0,0 +1,213 @@
+<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>
diff --git a/nixos/doc/manual/configuration/config-syntax.xml b/nixos/doc/manual/configuration/config-syntax.xml
new file mode 100644
index 00000000000..87847f8451e
--- /dev/null
+++ b/nixos/doc/manual/configuration/config-syntax.xml
@@ -0,0 +1,27 @@
+<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>
diff --git a/nixos/doc/manual/configuration/configuration.xml b/nixos/doc/manual/configuration/configuration.xml
new file mode 100644
index 00000000000..e15c700017c
--- /dev/null
+++ b/nixos/doc/manual/configuration/configuration.xml
@@ -0,0 +1,29 @@
+<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>
diff --git a/nixos/doc/manual/configuration/customizing-packages.xml b/nixos/doc/manual/configuration/customizing-packages.xml
new file mode 100644
index 00000000000..6ee7a95dc6f
--- /dev/null
+++ b/nixos/doc/manual/configuration/customizing-packages.xml
@@ -0,0 +1,92 @@
+<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>
diff --git a/nixos/doc/manual/configuration/declarative-packages.xml b/nixos/doc/manual/configuration/declarative-packages.xml
new file mode 100644
index 00000000000..6de38b452e2
--- /dev/null
+++ b/nixos/doc/manual/configuration/declarative-packages.xml
@@ -0,0 +1,43 @@
+<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>
diff --git a/nixos/doc/manual/configuration/file-systems.xml b/nixos/doc/manual/configuration/file-systems.xml
new file mode 100644
index 00000000000..52ad6d62f13
--- /dev/null
+++ b/nixos/doc/manual/configuration/file-systems.xml
@@ -0,0 +1,40 @@
+<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>
diff --git a/nixos/doc/manual/configuration/firewall.xml b/nixos/doc/manual/configuration/firewall.xml
new file mode 100644
index 00000000000..87406c28c2f
--- /dev/null
+++ b/nixos/doc/manual/configuration/firewall.xml
@@ -0,0 +1,38 @@
+<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>
diff --git a/nixos/doc/manual/configuration/ipv4-config.xml b/nixos/doc/manual/configuration/ipv4-config.xml
new file mode 100644
index 00000000000..e2c51518349
--- /dev/null
+++ b/nixos/doc/manual/configuration/ipv4-config.xml
@@ -0,0 +1,47 @@
+<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>
diff --git a/nixos/doc/manual/configuration/ipv6-config.xml b/nixos/doc/manual/configuration/ipv6-config.xml
new file mode 100644
index 00000000000..592bf20e545
--- /dev/null
+++ b/nixos/doc/manual/configuration/ipv6-config.xml
@@ -0,0 +1,19 @@
+<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>
diff --git a/nixos/doc/manual/configuration/linux-kernel.xml b/nixos/doc/manual/configuration/linux-kernel.xml
new file mode 100644
index 00000000000..8fe2f5255df
--- /dev/null
+++ b/nixos/doc/manual/configuration/linux-kernel.xml
@@ -0,0 +1,69 @@
+<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>
diff --git a/nixos/doc/manual/configuration/modularity.xml b/nixos/doc/manual/configuration/modularity.xml
new file mode 100644
index 00000000000..d95091bd162
--- /dev/null
+++ b/nixos/doc/manual/configuration/modularity.xml
@@ -0,0 +1,143 @@
+<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>
diff --git a/nixos/doc/manual/configuration/network-manager.xml b/nixos/doc/manual/configuration/network-manager.xml
new file mode 100644
index 00000000000..e65060021b4
--- /dev/null
+++ b/nixos/doc/manual/configuration/network-manager.xml
@@ -0,0 +1,27 @@
+<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>
diff --git a/nixos/doc/manual/configuration/networking.xml b/nixos/doc/manual/configuration/networking.xml
new file mode 100644
index 00000000000..5f08bc1f127
--- /dev/null
+++ b/nixos/doc/manual/configuration/networking.xml
@@ -0,0 +1,22 @@
+<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>
diff --git a/nixos/doc/manual/configuration/package-mgmt.xml b/nixos/doc/manual/configuration/package-mgmt.xml
new file mode 100644
index 00000000000..73c1722da02
--- /dev/null
+++ b/nixos/doc/manual/configuration/package-mgmt.xml
@@ -0,0 +1,34 @@
+<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>
diff --git a/nixos/doc/manual/configuration/ssh.xml b/nixos/doc/manual/configuration/ssh.xml
new file mode 100644
index 00000000000..7c928baaf89
--- /dev/null
+++ b/nixos/doc/manual/configuration/ssh.xml
@@ -0,0 +1,32 @@
+<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>
diff --git a/nixos/doc/manual/configuration/summary.xml b/nixos/doc/manual/configuration/summary.xml
new file mode 100644
index 00000000000..9bb5e35e16b
--- /dev/null
+++ b/nixos/doc/manual/configuration/summary.xml
@@ -0,0 +1,191 @@
+<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>
diff --git a/nixos/doc/manual/configuration/user-mgmt.xml b/nixos/doc/manual/configuration/user-mgmt.xml
new file mode 100644
index 00000000000..40dc687d03b
--- /dev/null
+++ b/nixos/doc/manual/configuration/user-mgmt.xml
@@ -0,0 +1,95 @@
+<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>
diff --git a/nixos/doc/manual/configuration/wireless.xml b/nixos/doc/manual/configuration/wireless.xml
new file mode 100644
index 00000000000..373a9168cc8
--- /dev/null
+++ b/nixos/doc/manual/configuration/wireless.xml
@@ -0,0 +1,41 @@
+<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>
diff --git a/nixos/doc/manual/configuration/x-windows.xml b/nixos/doc/manual/configuration/x-windows.xml
new file mode 100644
index 00000000000..bc58bb1f066
--- /dev/null
+++ b/nixos/doc/manual/configuration/x-windows.xml
@@ -0,0 +1,94 @@
+<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>
diff --git a/nixos/doc/manual/containers.xml b/nixos/doc/manual/containers.xml
deleted file mode 100644
index 2530d519521..00000000000
--- a/nixos/doc/manual/containers.xml
+++ /dev/null
@@ -1,242 +0,0 @@
-<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>
-
diff --git a/nixos/doc/manual/development.xml b/nixos/doc/manual/development.xml
deleted file mode 100644
index 2f0c2a7aa8d..00000000000
--- a/nixos/doc/manual/development.xml
+++ /dev/null
@@ -1,1119 +0,0 @@
-<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>
diff --git a/nixos/doc/manual/development/building-nixos.xml b/nixos/doc/manual/development/building-nixos.xml
new file mode 100644
index 00000000000..21c5bfe6a5b
--- /dev/null
+++ b/nixos/doc/manual/development/building-nixos.xml
@@ -0,0 +1,32 @@
+<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>
\ No newline at end of file
diff --git a/nixos/doc/manual/development/building-parts.xml b/nixos/doc/manual/development/building-parts.xml
new file mode 100644
index 00000000000..cb8dee039c8
--- /dev/null
+++ b/nixos/doc/manual/development/building-parts.xml
@@ -0,0 +1,113 @@
+<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>
\ No newline at end of file
diff --git a/nixos/doc/manual/development/development.xml b/nixos/doc/manual/development/development.xml
new file mode 100644
index 00000000000..747159c4427
--- /dev/null
+++ b/nixos/doc/manual/development/development.xml
@@ -0,0 +1,20 @@
+<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>
diff --git a/nixos/doc/manual/development/nixos-tests.xml b/nixos/doc/manual/development/nixos-tests.xml
new file mode 100644
index 00000000000..a98da993330
--- /dev/null
+++ b/nixos/doc/manual/development/nixos-tests.xml
@@ -0,0 +1,19 @@
+<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>
\ No newline at end of file
diff --git a/nixos/doc/manual/development/option-declarations.xml b/nixos/doc/manual/development/option-declarations.xml
new file mode 100644
index 00000000000..6d93dc5c009
--- /dev/null
+++ b/nixos/doc/manual/development/option-declarations.xml
@@ -0,0 +1,141 @@
+<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>
\ No newline at end of file
diff --git a/nixos/doc/manual/development/option-def.xml b/nixos/doc/manual/development/option-def.xml
new file mode 100644
index 00000000000..4e267ecfd1e
--- /dev/null
+++ b/nixos/doc/manual/development/option-def.xml
@@ -0,0 +1,112 @@
+<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>
\ No newline at end of file
diff --git a/nixos/doc/manual/development/running-nixos-tests.xml b/nixos/doc/manual/development/running-nixos-tests.xml
new file mode 100644
index 00000000000..d9be761eb01
--- /dev/null
+++ b/nixos/doc/manual/development/running-nixos-tests.xml
@@ -0,0 +1,77 @@
+<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>
\ No newline at end of file
diff --git a/nixos/doc/manual/development/sources.xml b/nixos/doc/manual/development/sources.xml
new file mode 100644
index 00000000000..992a07af981
--- /dev/null
+++ b/nixos/doc/manual/development/sources.xml
@@ -0,0 +1,95 @@
+<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>
\ No newline at end of file
diff --git a/nixos/doc/manual/development/testing-installer.xml b/nixos/doc/manual/development/testing-installer.xml
new file mode 100644
index 00000000000..87e40e32617
--- /dev/null
+++ b/nixos/doc/manual/development/testing-installer.xml
@@ -0,0 +1,27 @@
+<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>
\ No newline at end of file
diff --git a/nixos/doc/manual/development/writing-modules.xml b/nixos/doc/manual/development/writing-modules.xml
new file mode 100644
index 00000000000..9cf29e5dc57
--- /dev/null
+++ b/nixos/doc/manual/development/writing-modules.xml
@@ -0,0 +1,175 @@
+<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>
\ No newline at end of file
diff --git a/nixos/doc/manual/development/writing-nixos-tests.xml b/nixos/doc/manual/development/writing-nixos-tests.xml
new file mode 100644
index 00000000000..bbb655eed2a
--- /dev/null
+++ b/nixos/doc/manual/development/writing-nixos-tests.xml
@@ -0,0 +1,251 @@
+<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>
\ No newline at end of file
diff --git a/nixos/doc/manual/installation.xml b/nixos/doc/manual/installation.xml
deleted file mode 100644
index 4cbfcc229fa..00000000000
--- a/nixos/doc/manual/installation.xml
+++ /dev/null
@@ -1,570 +0,0 @@
-<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>
diff --git a/nixos/doc/manual/installation/changing-config.xml b/nixos/doc/manual/installation/changing-config.xml
new file mode 100644
index 00000000000..aa31742434e
--- /dev/null
+++ b/nixos/doc/manual/installation/changing-config.xml
@@ -0,0 +1,90 @@
+<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>
diff --git a/nixos/doc/manual/installation/installation.xml b/nixos/doc/manual/installation/installation.xml
new file mode 100644
index 00000000000..ee61bedc418
--- /dev/null
+++ b/nixos/doc/manual/installation/installation.xml
@@ -0,0 +1,21 @@
+<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>
diff --git a/nixos/doc/manual/installation/installing-UEFI.xml b/nixos/doc/manual/installation/installing-UEFI.xml
new file mode 100644
index 00000000000..dbd5606c4a5
--- /dev/null
+++ b/nixos/doc/manual/installation/installing-UEFI.xml
@@ -0,0 +1,51 @@
+<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>
diff --git a/nixos/doc/manual/installation/installing-USB.xml b/nixos/doc/manual/installation/installing-USB.xml
new file mode 100644
index 00000000000..97e3d2eaa1c
--- /dev/null
+++ b/nixos/doc/manual/installation/installing-USB.xml
@@ -0,0 +1,30 @@
+<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>
diff --git a/nixos/doc/manual/installation/installing.xml b/nixos/doc/manual/installation/installing.xml
new file mode 100644
index 00000000000..793b503ad97
--- /dev/null
+++ b/nixos/doc/manual/installation/installing.xml
@@ -0,0 +1,264 @@
+<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>
diff --git a/nixos/doc/manual/installation/obtaining.xml b/nixos/doc/manual/installation/obtaining.xml
new file mode 100644
index 00000000000..ceeeb5c0ac0
--- /dev/null
+++ b/nixos/doc/manual/installation/obtaining.xml
@@ -0,0 +1,44 @@
+<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>
diff --git a/nixos/doc/manual/installation/upgrading.xml b/nixos/doc/manual/installation/upgrading.xml
new file mode 100644
index 00000000000..ed71a7e23a3
--- /dev/null
+++ b/nixos/doc/manual/installation/upgrading.xml
@@ -0,0 +1,90 @@
+<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>
diff --git a/nixos/doc/manual/manual.xml b/nixos/doc/manual/manual.xml
index f51a04cdf25..a3ad76209ac 100644
--- a/nixos/doc/manual/manual.xml
+++ b/nixos/doc/manual/manual.xml
@@ -1,15 +1,14 @@
 <book xmlns="http://docbook.org/ns/docbook"
       xmlns:xlink="http://www.w3.org/1999/xlink"
-      xmlns:xi="http://www.w3.org/2001/XInclude">
-
+      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>
 
@@ -29,19 +28,14 @@
 
   </preface>
 
-
-  <xi:include href="installation.xml" />
-  <xi:include href="configuration.xml" />
-  <xi:include href="running.xml" />
+  <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="troubleshooting.xml" />
-  <xi:include href="containers.xml" />
-  <xi:include href="development.xml" />
-
-  <xi:include href="release-notes.xml" />
+  <xi:include href="release-notes/release-notes.xml" />
 
   <appendix xml:id="ch-options">
-    <title>Configuration options</title>
+    <title>Configuration Options</title>
     <xi:include href="options-db.xml" />
   </appendix>
 
diff --git a/nixos/doc/manual/release-notes/release-notes.xml b/nixos/doc/manual/release-notes/release-notes.xml
new file mode 100644
index 00000000000..fb82d5adcef
--- /dev/null
+++ b/nixos/doc/manual/release-notes/release-notes.xml
@@ -0,0 +1,17 @@
+<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>
diff --git a/nixos/doc/manual/release-notes/rl-1310.xml b/nixos/doc/manual/release-notes/rl-1310.xml
new file mode 100644
index 00000000000..234fb5a643f
--- /dev/null
+++ b/nixos/doc/manual/release-notes/rl-1310.xml
@@ -0,0 +1,11 @@
+<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>
\ No newline at end of file
diff --git a/nixos/doc/manual/release-notes.xml b/nixos/doc/manual/release-notes/rl-1404.xml
index 52e88bb4c86..74af1ed1274 100644
--- a/nixos/doc/manual/release-notes.xml
+++ b/nixos/doc/manual/release-notes/rl-1404.xml
@@ -1,34 +1,8 @@
-<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">
+<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>
 
@@ -183,16 +157,4 @@ networking.firewall.enable = false;
 
 </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>
\ No newline at end of file
diff --git a/nixos/doc/manual/release-notes/rl-1410.xml b/nixos/doc/manual/release-notes/rl-1410.xml
new file mode 100644
index 00000000000..09da15ce236
--- /dev/null
+++ b/nixos/doc/manual/release-notes/rl-1410.xml
@@ -0,0 +1,22 @@
+<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>
\ No newline at end of file
diff --git a/nixos/doc/manual/running.xml b/nixos/doc/manual/running.xml
deleted file mode 100644
index e1a358df2aa..00000000000
--- a/nixos/doc/manual/running.xml
+++ /dev/null
@@ -1,369 +0,0 @@
-<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>
diff --git a/nixos/doc/manual/troubleshooting.xml b/nixos/doc/manual/troubleshooting.xml
deleted file mode 100644
index c7d65112b64..00000000000
--- a/nixos/doc/manual/troubleshooting.xml
+++ /dev/null
@@ -1,199 +0,0 @@
-<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>