summary refs log tree commit diff
path: root/nixos
diff options
context:
space:
mode:
Diffstat (limited to 'nixos')
-rw-r--r--nixos/doc/manual/administration/cleaning-store.xml4
-rw-r--r--nixos/doc/manual/administration/container-networking.xml4
-rw-r--r--nixos/doc/manual/administration/imperative-containers.xml24
-rw-r--r--nixos/doc/manual/administration/maintenance-mode.xml4
-rw-r--r--nixos/doc/manual/administration/network-problems.xml4
-rw-r--r--nixos/doc/manual/administration/rebooting.xml8
-rw-r--r--nixos/doc/manual/administration/rollback.xml8
-rw-r--r--nixos/doc/manual/administration/service-mgmt.xml6
-rw-r--r--nixos/doc/manual/administration/store-corruption.xml6
-rw-r--r--nixos/doc/manual/administration/user-sessions.xml4
-rw-r--r--nixos/doc/manual/configuration/adding-custom-packages.xml2
-rw-r--r--nixos/doc/manual/configuration/linux-kernel.xml2
-rw-r--r--nixos/doc/manual/configuration/luks-file-systems.xml6
-rw-r--r--nixos/doc/manual/configuration/user-mgmt.xml8
-rw-r--r--nixos/doc/manual/configuration/wireless.xml4
-rw-r--r--nixos/doc/manual/configuration/x-windows.xml13
-rw-r--r--nixos/doc/manual/development/building-nixos.xml4
-rw-r--r--nixos/doc/manual/development/building-parts.xml6
-rw-r--r--nixos/doc/manual/development/sources.xml2
-rw-r--r--nixos/doc/manual/development/testing-installer.xml8
-rw-r--r--nixos/doc/manual/installation/changing-config.xml8
-rw-r--r--nixos/doc/manual/installation/installing-uefi.xml6
-rw-r--r--nixos/doc/manual/installation/installing.xml38
-rw-r--r--nixos/doc/manual/installation/upgrading.xml12
-rw-r--r--nixos/doc/manual/man-configuration.xml4
-rw-r--r--nixos/doc/manual/man-nixos-build-vms.xml8
-rw-r--r--nixos/doc/manual/man-nixos-option.xml4
-rw-r--r--nixos/doc/manual/manual.xml5
-rw-r--r--nixos/doc/manual/options-to-docbook.xsl3
-rw-r--r--nixos/doc/manual/release-notes/rl-1609.xml4
-rw-r--r--nixos/modules/hardware/video/ati.nix2
-rw-r--r--nixos/modules/installer/cd-dvd/iso-image.nix2
-rw-r--r--nixos/modules/installer/tools/nixos-generate-config.pl4
-rw-r--r--nixos/modules/misc/version.nix4
-rw-r--r--nixos/modules/module-list.nix5
-rw-r--r--nixos/modules/programs/unity3d.nix25
-rw-r--r--nixos/modules/security/acme.nix180
-rw-r--r--nixos/modules/security/acme.xml28
-rw-r--r--nixos/modules/services/continuous-integration/hydra/default.nix418
-rw-r--r--nixos/modules/services/databases/openldap.nix12
-rw-r--r--nixos/modules/services/hardware/pcscd.nix55
-rw-r--r--nixos/modules/services/networking/dnscrypt-proxy.nix4
-rw-r--r--nixos/modules/services/networking/openvpn.nix22
-rw-r--r--nixos/modules/services/security/oauth2_proxy.nix523
-rw-r--r--nixos/modules/services/x11/desktop-managers/gnome3.nix1
-rw-r--r--nixos/modules/services/x11/desktop-managers/kde5.nix5
-rw-r--r--nixos/modules/services/x11/xserver.nix12
-rw-r--r--nixos/modules/system/boot/loader/efi.nix7
-rw-r--r--nixos/modules/system/boot/loader/grub/grub.nix2
-rw-r--r--nixos/modules/system/boot/loader/systemd-boot/systemd-boot-builder.py (renamed from nixos/modules/system/boot/loader/gummiboot/gummiboot-builder.py)6
-rw-r--r--nixos/modules/system/boot/loader/systemd-boot/systemd-boot.nix (renamed from nixos/modules/system/boot/loader/gummiboot/gummiboot.nix)19
-rw-r--r--nixos/modules/system/boot/stage-2-init.sh2
-rw-r--r--nixos/modules/virtualisation/virtualbox-guest.nix2
-rw-r--r--nixos/tests/gnome3_20-gdm.nix41
-rw-r--r--nixos/tests/gnome3_20.nix38
-rw-r--r--nixos/tests/installer.nix15
-rw-r--r--nixos/tests/sddm-kde5.nix41
57 files changed, 1475 insertions, 219 deletions
diff --git a/nixos/doc/manual/administration/cleaning-store.xml b/nixos/doc/manual/administration/cleaning-store.xml
index 41dc65795b68..4cf62947f528 100644
--- a/nixos/doc/manual/administration/cleaning-store.xml
+++ b/nixos/doc/manual/administration/cleaning-store.xml
@@ -21,7 +21,7 @@ Alternatively, you can use a systemd unit that does the same in the
 background:
 
 <screen>
-$ systemctl start nix-gc.service
+# systemctl start nix-gc.service
 </screen>
 
 You can tell NixOS in <filename>configuration.nix</filename> to run
@@ -59,4 +59,4 @@ $ nix-store --optimise
 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
+</chapter>
diff --git a/nixos/doc/manual/administration/container-networking.xml b/nixos/doc/manual/administration/container-networking.xml
index adea3e69840d..1b1576d3babe 100644
--- a/nixos/doc/manual/administration/container-networking.xml
+++ b/nixos/doc/manual/administration/container-networking.xml
@@ -13,7 +13,7 @@ create</literal>, it gets it own private IPv4 address in the range
 address as follows:
 
 <screen>
-$ nixos-container show-ip foo
+# nixos-container show-ip foo
 10.233.4.2
 
 $ ping -c1 10.233.4.2
@@ -47,4 +47,4 @@ 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
+</section>
diff --git a/nixos/doc/manual/administration/imperative-containers.xml b/nixos/doc/manual/administration/imperative-containers.xml
index 6131d4e04ea8..3a52658436ac 100644
--- a/nixos/doc/manual/administration/imperative-containers.xml
+++ b/nixos/doc/manual/administration/imperative-containers.xml
@@ -11,7 +11,7 @@
 identifier <literal>foo</literal> as follows:
 
 <screen>
-$ nixos-container create foo
+# nixos-container create foo
 </screen>
 
 This creates the container’s root directory in
@@ -25,7 +25,7 @@ line. For instance, to create a container that has
 <literal>root</literal>:
 
 <screen>
-$ nixos-container create foo --config 'services.openssh.enable = true; \
+# nixos-container create foo --config 'services.openssh.enable = true; \
   users.extraUsers.root.openssh.authorizedKeys.keys = ["ssh-dss AAAAB3N…"];'
 </screen>
 
@@ -35,7 +35,7 @@ $ nixos-container create foo --config 'services.openssh.enable = true; \
 run:
 
 <screen>
-$ nixos-container start foo
+# nixos-container start foo
 </screen>
 
 This command will return as soon as the container has booted and has
@@ -46,7 +46,7 @@ Thus, if something went wrong, you can get status info using
 <command>systemctl</command>:
 
 <screen>
-$ systemctl status container@foo
+# systemctl status container@foo
 </screen>
 
 </para>
@@ -55,7 +55,7 @@ $ systemctl status container@foo
 root using the <command>root-login</command> operation:
 
 <screen>
-$ nixos-container root-login foo
+# nixos-container root-login foo
 [root@foo:~]#
 </screen>
 
@@ -65,7 +65,7 @@ authentication).  You can also get a regular login prompt using the
 the host:
 
 <screen>
-$ nixos-container login foo
+# nixos-container login foo
 foo login: alice
 Password: ***
 </screen>
@@ -74,7 +74,7 @@ With <command>nixos-container run</command>, you can execute arbitrary
 commands in the container:
 
 <screen>
-$ nixos-container run foo -- uname -a
+# 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>
 
@@ -86,17 +86,17 @@ container. First, on the host, you can edit
 and run
 
 <screen>
-$ nixos-container update foo
+# 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; \
+# nixos-container update foo --config 'services.httpd.enable = true; \
   services.httpd.adminAddr = "foo@example.org";'
 
-$ curl http://$(nixos-container show-ip foo)/
+# curl http://$(nixos-container show-ip foo)/
 &lt;!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">…
 </screen>
 
@@ -116,9 +116,9 @@ start</literal>, respectively, or by using
 destroy a container, including its file system, do
 
 <screen>
-$ nixos-container destroy foo
+# nixos-container destroy foo
 </screen>
 
 </para>
 
-</section>
\ No newline at end of file
+</section>
diff --git a/nixos/doc/manual/administration/maintenance-mode.xml b/nixos/doc/manual/administration/maintenance-mode.xml
index 15c1f902da79..17a1609e5579 100644
--- a/nixos/doc/manual/administration/maintenance-mode.xml
+++ b/nixos/doc/manual/administration/maintenance-mode.xml
@@ -9,10 +9,10 @@
 <para>You can enter rescue mode by running:
 
 <screen>
-$ systemctl rescue</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
+</section>
diff --git a/nixos/doc/manual/administration/network-problems.xml b/nixos/doc/manual/administration/network-problems.xml
index 3af9cc59742f..91f9eb4e22c6 100644
--- a/nixos/doc/manual/administration/network-problems.xml
+++ b/nixos/doc/manual/administration/network-problems.xml
@@ -18,14 +18,14 @@ 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
+# 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/
+# nixos-rebuild switch --option binary-caches http://my-cache.example.org/
 </screen>
 
 </para>
diff --git a/nixos/doc/manual/administration/rebooting.xml b/nixos/doc/manual/administration/rebooting.xml
index d1db7b141cf2..23f3a3219c6a 100644
--- a/nixos/doc/manual/administration/rebooting.xml
+++ b/nixos/doc/manual/administration/rebooting.xml
@@ -10,7 +10,7 @@
 doing:
 
 <screen>
-$ shutdown
+# shutdown
 </screen>
 
 This is equivalent to running <command>systemctl
@@ -19,7 +19,7 @@ poweroff</command>.</para>
 <para>To reboot the system, run
 
 <screen>
-$ reboot
+# reboot
 </screen>
 
 which is equivalent to <command>systemctl reboot</command>.
@@ -28,7 +28,7 @@ Alternatively, you can quickly reboot the system using
 the new kernel into memory:
 
 <screen>
-$ systemctl kexec
+# systemctl kexec
 </screen>
 
 </para>
@@ -41,4 +41,4 @@ $ systemctl kexec
 i.e. on a virtual console or in X11; otherwise, the user is asked for
 authentication.</para>
 
-</chapter>
\ No newline at end of file
+</chapter>
diff --git a/nixos/doc/manual/administration/rollback.xml b/nixos/doc/manual/administration/rollback.xml
index 23a3ece7c070..ae621f33de2c 100644
--- a/nixos/doc/manual/administration/rollback.xml
+++ b/nixos/doc/manual/administration/rollback.xml
@@ -19,7 +19,7 @@ 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>
+# /run/current-system/bin/switch-to-configuration boot</screen>
 
 </para>
 
@@ -27,12 +27,12 @@ $ /run/current-system/bin/switch-to-configuration boot</screen>
 system:
 
 <screen>
-$ nixos-rebuild switch --rollback</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>
+# /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:
@@ -45,4 +45,4 @@ lrwxrwxrwx 1 root root 78 Aug 12 13:54 /nix/var/nix/profiles/system-268-link ->
 
 </para>
 
-</section>
\ No newline at end of file
+</section>
diff --git a/nixos/doc/manual/administration/service-mgmt.xml b/nixos/doc/manual/administration/service-mgmt.xml
index c0940a42f307..1627c7a2fdeb 100644
--- a/nixos/doc/manual/administration/service-mgmt.xml
+++ b/nixos/doc/manual/administration/service-mgmt.xml
@@ -66,9 +66,9 @@ messages from the service.
 <para>Units can be stopped, started or restarted:
 
 <screen>
-$ systemctl stop postgresql.service
-$ systemctl start postgresql.service
-$ systemctl restart postgresql.service
+# systemctl stop postgresql.service
+# systemctl start postgresql.service
+# systemctl restart postgresql.service
 </screen>
 
 These operations are synchronous: they wait until the service has
diff --git a/nixos/doc/manual/administration/store-corruption.xml b/nixos/doc/manual/administration/store-corruption.xml
index 0160cb45358b..9f567042b727 100644
--- a/nixos/doc/manual/administration/store-corruption.xml
+++ b/nixos/doc/manual/administration/store-corruption.xml
@@ -18,7 +18,7 @@ you may be able to fix it automatically.</para>
 system configuration, you can fix it by doing
 
 <screen>
-$ nixos-rebuild switch --repair
+# nixos-rebuild switch --repair
 </screen>
 
 This will cause Nix to check every path in the closure, and if its
@@ -28,10 +28,10 @@ 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
+# 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
+</section>
diff --git a/nixos/doc/manual/administration/user-sessions.xml b/nixos/doc/manual/administration/user-sessions.xml
index 05e2c1a9b29f..0a7eb8cd123c 100644
--- a/nixos/doc/manual/administration/user-sessions.xml
+++ b/nixos/doc/manual/administration/user-sessions.xml
@@ -45,9 +45,9 @@ 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
+# loginctl terminate-session c3
 </screen>
 
 </para>
 
-</chapter>
\ No newline at end of file
+</chapter>
diff --git a/nixos/doc/manual/configuration/adding-custom-packages.xml b/nixos/doc/manual/configuration/adding-custom-packages.xml
index c1789fcbc041..ab3665bae504 100644
--- a/nixos/doc/manual/configuration/adding-custom-packages.xml
+++ b/nixos/doc/manual/configuration/adding-custom-packages.xml
@@ -31,7 +31,7 @@ and you run <command>nixos-rebuild</command>, specifying your own
 Nixpkgs tree:
 
 <screen>
-$ nixos-rebuild switch -I nixpkgs=/path/to/my/nixpkgs</screen>
+# nixos-rebuild switch -I nixpkgs=/path/to/my/nixpkgs</screen>
 
 </para>
 
diff --git a/nixos/doc/manual/configuration/linux-kernel.xml b/nixos/doc/manual/configuration/linux-kernel.xml
index b008baaa66c9..52be26d6024a 100644
--- a/nixos/doc/manual/configuration/linux-kernel.xml
+++ b/nixos/doc/manual/configuration/linux-kernel.xml
@@ -82,7 +82,7 @@ $ nix-shell '<nixpkgs>' -A linuxPackages.kernel
 $ unpackPhase
 $ cd linux-*
 $ make -C $dev/lib/modules/*/build M=$(pwd)/drivers/net/ethernet/mellanox modules
-$ sudo insmod ./drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.ko
+# insmod ./drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.ko
 ]]></screen>
 
 </section>
diff --git a/nixos/doc/manual/configuration/luks-file-systems.xml b/nixos/doc/manual/configuration/luks-file-systems.xml
index 88b506d5323d..2062456703f7 100644
--- a/nixos/doc/manual/configuration/luks-file-systems.xml
+++ b/nixos/doc/manual/configuration/luks-file-systems.xml
@@ -12,7 +12,7 @@ here is how you create an encrypted Ext4 file system on the device
 <filename>/dev/disk/by-uuid/3f6b0024-3a44-4fde-a43a-767b872abe5d</filename>:
 
 <screen>
-$ cryptsetup luksFormat /dev/disk/by-uuid/3f6b0024-3a44-4fde-a43a-767b872abe5d
+# cryptsetup luksFormat /dev/disk/by-uuid/3f6b0024-3a44-4fde-a43a-767b872abe5d
 
 WARNING!
 ========
@@ -22,10 +22,10 @@ Are you sure? (Type uppercase yes): YES
 Enter LUKS passphrase: ***
 Verify passphrase: ***
 
-$ cryptsetup luksOpen /dev/disk/by-uuid/3f6b0024-3a44-4fde-a43a-767b872abe5d crypted
+# cryptsetup luksOpen /dev/disk/by-uuid/3f6b0024-3a44-4fde-a43a-767b872abe5d crypted
 Enter passphrase for /dev/disk/by-uuid/3f6b0024-3a44-4fde-a43a-767b872abe5d: ***
 
-$ mkfs.ext4 /dev/mapper/crypted
+# mkfs.ext4 /dev/mapper/crypted
 </screen>
 
 To ensure that this file system is automatically mounted at boot time
diff --git a/nixos/doc/manual/configuration/user-mgmt.xml b/nixos/doc/manual/configuration/user-mgmt.xml
index 631742059278..829e5b9ea842 100644
--- a/nixos/doc/manual/configuration/user-mgmt.xml
+++ b/nixos/doc/manual/configuration/user-mgmt.xml
@@ -63,14 +63,14 @@ commands such as <command>useradd</command>,
 account named <literal>alice</literal>:
 
 <screen>
-$ useradd -m alice</screen>
+# useradd -m alice</screen>
 
 To make all nix tools available to this new user use `su - USER` which 
 opens a login shell (==shell that loads the profile) for given user. 
 This will create the ~/.nix-defexpr symlink. So run:
 
 <screen>
-$ su - alice -c "true"</screen>
+# su - alice -c "true"</screen>
 
 
 The flag <option>-m</option> causes the creation of a home directory
@@ -79,7 +79,7 @@ have an initial password and therefore cannot log in.  A password can
 be set using the <command>passwd</command> utility:
 
 <screen>
-$ passwd alice
+# passwd alice
 Enter new UNIX password: ***
 Retype new UNIX password: ***
 </screen>
@@ -87,7 +87,7 @@ Retype new UNIX password: ***
 A user can be deleted using <command>userdel</command>:
 
 <screen>
-$ userdel -r alice</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
diff --git a/nixos/doc/manual/configuration/wireless.xml b/nixos/doc/manual/configuration/wireless.xml
index e4560f2da36b..1868380dcbfa 100644
--- a/nixos/doc/manual/configuration/wireless.xml
+++ b/nixos/doc/manual/configuration/wireless.xml
@@ -41,13 +41,13 @@ 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>
+# 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>
+# 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
index 7f43acab2c38..3040839861c1 100644
--- a/nixos/doc/manual/configuration/x-windows.xml
+++ b/nixos/doc/manual/configuration/x-windows.xml
@@ -5,7 +5,7 @@
          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>
@@ -48,7 +48,7 @@ services.xserver.autorun = false;
 </programlisting>
 The X server can then be started manually:
 <screen>
-$ systemctl start display-manager.service
+# systemctl start display-manager.service
 </screen>
 </para>
 
@@ -115,5 +115,14 @@ services.xserver.synaptics.twoFingerScroll = true;
 
 </simplesect>
 
+<simplesect><title>GTK/Qt themes</title>
+
+<para>GTK themes can be installed either to user profile or system-wide (via
+<literal>system.environmentPackages</literal>). To make Qt 5 applications look similar
+to GTK2 ones, you can install <literal>qt5.qtbase.gtk</literal> package into your
+system environment. It should work for all Qt 5 library versions.
+</para>
+
+</simplesect>
 
 </chapter>
diff --git a/nixos/doc/manual/development/building-nixos.xml b/nixos/doc/manual/development/building-nixos.xml
index 21c5bfe6a5b1..150fa1d7017e 100644
--- a/nixos/doc/manual/development/building-nixos.xml
+++ b/nixos/doc/manual/development/building-nixos.xml
@@ -25,8 +25,8 @@ $ nix-build -A config.system.build.isoImage -I nixos-config=modules/installer/cd
 suggested by the following command:
 
 <screen>
-$ mount -o loop -t iso9660 ./result/iso/cd.iso /mnt/iso</screen>
+# mount -o loop -t iso9660 ./result/iso/cd.iso /mnt/iso</screen>
 
 </para>
 
-</chapter>
\ No newline at end of file
+</chapter>
diff --git a/nixos/doc/manual/development/building-parts.xml b/nixos/doc/manual/development/building-parts.xml
index cb8dee039c8e..09a40114f02e 100644
--- a/nixos/doc/manual/development/building-parts.xml
+++ b/nixos/doc/manual/development/building-parts.xml
@@ -94,8 +94,8 @@ $ nix-build -A 'config.systemd.units."httpd.service".unit'
 <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
+# systemctl daemon-reload
+# systemctl start tmp-httpd.service
 </screen>
 
       Note that the unit must not have the same name as any unit in
@@ -110,4 +110,4 @@ $ systemctl start tmp-httpd.service
 
 </para>
 
-</chapter>
\ No newline at end of file
+</chapter>
diff --git a/nixos/doc/manual/development/sources.xml b/nixos/doc/manual/development/sources.xml
index fd0b0109b322..7cd5ce0002c2 100644
--- a/nixos/doc/manual/development/sources.xml
+++ b/nixos/doc/manual/development/sources.xml
@@ -70,7 +70,7 @@ 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
+# nixos-rebuild switch -I nixpkgs=<replaceable>/my/sources</replaceable>/nixpkgs
 </screen>
 
 </para>
diff --git a/nixos/doc/manual/development/testing-installer.xml b/nixos/doc/manual/development/testing-installer.xml
index 87e40e326171..20c8d51815ad 100644
--- a/nixos/doc/manual/development/testing-installer.xml
+++ b/nixos/doc/manual/development/testing-installer.xml
@@ -12,16 +12,16 @@ properly:
 
 <screen>
 $ nix-build -A config.system.build.nixos-install
-$ mount -t tmpfs none /mnt
-$ ./result/bin/nixos-install</screen>
+# 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
+# ./result/bin/nixos-install --chroot
 </screen>
 
 </para>
 
-</chapter>
\ No newline at end of file
+</chapter>
diff --git a/nixos/doc/manual/installation/changing-config.xml b/nixos/doc/manual/installation/changing-config.xml
index aa31742434e4..43b591a1cae9 100644
--- a/nixos/doc/manual/installation/changing-config.xml
+++ b/nixos/doc/manual/installation/changing-config.xml
@@ -10,7 +10,7 @@ contains the current configuration of your machine.  Whenever you’ve
 changed something to that file, you should do
 
 <screen>
-$ nixos-rebuild switch</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
@@ -23,7 +23,7 @@ either run them from a root shell or by prefixing them with
 <para>You can also do
 
 <screen>
-$ nixos-rebuild test</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
@@ -33,7 +33,7 @@ configuration.</para>
 <para>There is also
 
 <screen>
-$ nixos-rebuild boot</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
@@ -44,7 +44,7 @@ of the GRUB 2 boot screen by giving it a different <emphasis>profile
 name</emphasis>, e.g.
 
 <screen>
-$ nixos-rebuild switch -p test </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 -
diff --git a/nixos/doc/manual/installation/installing-uefi.xml b/nixos/doc/manual/installation/installing-uefi.xml
index 90d18695447c..927648febc50 100644
--- a/nixos/doc/manual/installation/installing-uefi.xml
+++ b/nixos/doc/manual/installation/installing-uefi.xml
@@ -5,7 +5,7 @@
          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:
@@ -26,7 +26,7 @@ changes:
     <literal>vfat</literal> filesystem.</para>
   </listitem>
   <listitem>
-    <para>You must set <option>boot.loader.gummiboot.enable</option> to
+    <para>You must set <option>boot.loader.systemd-boot.enable</option> to
     <literal>true</literal>. <command>nixos-generate-config</command>
     should do this automatically for new configurations when booted in
     UEFI mode.</para>
@@ -38,7 +38,7 @@ changes:
   </listitem>
   <listitem>
     <para>You may want to look at the options starting with
-    <option>boot.loader.efi</option> and <option>boot.loader.gummiboot</option>
+    <option>boot.loader.efi</option> and <option>boot.loader.systemd-boot</option>
     as well.</para>
   </listitem>
 </itemizedlist>
diff --git a/nixos/doc/manual/installation/installing.xml b/nixos/doc/manual/installation/installing.xml
index 3e53062c3e84..2f118d27b1a5 100644
--- a/nixos/doc/manual/installation/installing.xml
+++ b/nixos/doc/manual/installation/installing.xml
@@ -54,7 +54,7 @@
     changes.  For example:
 
 <screen>
-$ mkfs.ext4 -L nixos /dev/sda1</screen>
+# mkfs.ext4 -L nixos /dev/sda1</screen>
 
     </para></listitem>
 
@@ -66,10 +66,10 @@ $ mkfs.ext4 -L nixos /dev/sda1</screen>
     <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>
+# 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>
 
@@ -84,7 +84,7 @@ $ lvcreate --size 1G --name smalldisk MyVolGroup</screen>
   be installed on <filename>/mnt</filename>, e.g.
 
 <screen>
-$ mount /dev/disk/by-label/nixos /mnt
+# mount /dev/disk/by-label/nixos /mnt
 </screen>
 
   </para></listitem>
@@ -113,14 +113,14 @@ $ mount /dev/disk/by-label/nixos /mnt
     generate an initial configuration file for you:
 
 <screen>
-$ nixos-generate-config --root /mnt</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
+# nano /mnt/etc/nixos/configuration.nix
 </screen>
 
     If you’re using the graphical ISO image, other editors may be
@@ -162,7 +162,7 @@ $ nano /mnt/etc/nixos/configuration.nix
   <listitem><para>Do the installation:
 
 <screen>
-$ nixos-install</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
@@ -186,7 +186,7 @@ Retype new UNIX password: ***
   <listitem><para>If everything went well:
 
 <screen>
-$ reboot</screen>
+# reboot</screen>
 
   </para></listitem>
 
@@ -235,15 +235,15 @@ drive (here <filename>/dev/sda</filename>).  <xref linkend="ex-config"
 
 <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>
+# 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>
diff --git a/nixos/doc/manual/installation/upgrading.xml b/nixos/doc/manual/installation/upgrading.xml
index c4812cc637c3..65d395b0c88e 100644
--- a/nixos/doc/manual/installation/upgrading.xml
+++ b/nixos/doc/manual/installation/upgrading.xml
@@ -60,33 +60,33 @@ the <literal>nixos-14.12</literal> channel.  To see which NixOS
 channel you’re subscribed to, run the following as root:
 
 <screen>
-$ nix-channel --list | grep nixos
+# 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 https://nixos.org/channels/<replaceable>channel-name</replaceable> nixos
+# nix-channel --add https://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.12 stable channel:
 
 <screen>
-$ nix-channel --add https://nixos.org/channels/nixos-14.12 nixos
+# nix-channel --add https://nixos.org/channels/nixos-14.12 nixos
 </screen>
 
 If you have a server, you may want to use the “small” channel instead:
 
 <screen>
-$ nix-channel --add https://nixos.org/channels/nixos-14.12-small nixos
+# nix-channel --add https://nixos.org/channels/nixos-14.12-small nixos
 </screen>
 
 And if you want to live on the bleeding edge:
 
 <screen>
-$ nix-channel --add https://nixos.org/channels/nixos-unstable nixos
+# nix-channel --add https://nixos.org/channels/nixos-unstable nixos
 </screen>
 
 </para>
@@ -95,7 +95,7 @@ $ nix-channel --add https://nixos.org/channels/nixos-unstable nixos
 channel by running
 
 <screen>
-$ nixos-rebuild switch --upgrade
+# nixos-rebuild switch --upgrade
 </screen>
 
 which is equivalent to the more verbose <literal>nix-channel --update
diff --git a/nixos/doc/manual/man-configuration.xml b/nixos/doc/manual/man-configuration.xml
index d49369d2c584..05531b3909a3 100644
--- a/nixos/doc/manual/man-configuration.xml
+++ b/nixos/doc/manual/man-configuration.xml
@@ -1,7 +1,7 @@
 <refentry xmlns="http://docbook.org/ns/docbook"
           xmlns:xlink="http://www.w3.org/1999/xlink"
           xmlns:xi="http://www.w3.org/2001/XInclude">
-  
+
 <refmeta>
   <refentrytitle><filename>configuration.nix</filename></refentrytitle>
   <manvolnum>5</manvolnum>
@@ -34,5 +34,5 @@ therein.</para>
 <xi:include href="options-db.xml" />
 
 </refsection>
-  
+
 </refentry>
diff --git a/nixos/doc/manual/man-nixos-build-vms.xml b/nixos/doc/manual/man-nixos-build-vms.xml
index f37677629d0c..878ebee05273 100644
--- a/nixos/doc/manual/man-nixos-build-vms.xml
+++ b/nixos/doc/manual/man-nixos-build-vms.xml
@@ -1,7 +1,7 @@
 <refentry xmlns="http://docbook.org/ns/docbook"
           xmlns:xlink="http://www.w3.org/1999/xlink"
           xmlns:xi="http://www.w3.org/2001/XInclude">
-  
+
 <refmeta>
   <refentrytitle><command>nixos-build-vms</command></refentrytitle>
   <manvolnum>8</manvolnum>
@@ -42,10 +42,10 @@ points to the generated virtual network.
       services.openssh.enable = true;
       nixpkgs.system = "i686-linux";
       deployment.targetHost = "test1.example.net";
-      
+
       # Other NixOS options
     };
-    
+
   test2 = {pkgs, config, ...}:
     {
       services.openssh.enable = true;
@@ -53,7 +53,7 @@ points to the generated virtual network.
       environment.systemPackages = [ pkgs.lynx ];
       nixpkgs.system = "x86_64-linux";
       deployment.targetHost = "test2.example.net";
-      
+
       # Other NixOS options
     };
 }
diff --git a/nixos/doc/manual/man-nixos-option.xml b/nixos/doc/manual/man-nixos-option.xml
index 2875336c67e5..6be8bc780f13 100644
--- a/nixos/doc/manual/man-nixos-option.xml
+++ b/nixos/doc/manual/man-nixos-option.xml
@@ -1,7 +1,7 @@
 <refentry xmlns="http://docbook.org/ns/docbook"
           xmlns:xlink="http://www.w3.org/1999/xlink"
           xmlns:xi="http://www.w3.org/2001/XInclude">
-  
+
 <refmeta>
   <refentrytitle><command>nixos-option</command></refentrytitle>
   <manvolnum>8</manvolnum>
@@ -64,7 +64,7 @@ $ nixos-option boot.loader.grub.enable
 Value:
 true
 
-Default: 
+Default:
 true
 
 Description:
diff --git a/nixos/doc/manual/manual.xml b/nixos/doc/manual/manual.xml
index 736d1d4eff71..2c28dd448016 100644
--- a/nixos/doc/manual/manual.xml
+++ b/nixos/doc/manual/manual.xml
@@ -3,7 +3,7 @@
       xmlns:xi="http://www.w3.org/2001/XInclude"
       version="5.0"
       xml:id="book-nixos-manual">
-  
+
   <info>
     <title>NixOS Manual</title>
     <subtitle>Version <xi:include href="version" parse="text" /></subtitle>
@@ -26,6 +26,9 @@
     xlink:href="https://github.com/NixOS/nixpkgs/issues">NixOS’ GitHub
     issue tracker</link>.</para>
 
+    <note><para>Commands prefixed with <literal>#</literal> have to be run as
+    root, either requiring to login as root user or temporarily switching
+    to it using <literal>sudo</literal> for example.</para></note>
   </preface>
 
   <xi:include href="installation/installation.xml" />
diff --git a/nixos/doc/manual/options-to-docbook.xsl b/nixos/doc/manual/options-to-docbook.xsl
index cd30ae36ae59..5387546b5982 100644
--- a/nixos/doc/manual/options-to-docbook.xsl
+++ b/nixos/doc/manual/options-to-docbook.xsl
@@ -11,6 +11,7 @@
   <xsl:output method='xml' encoding="UTF-8" />
 
   <xsl:param name="revision" />
+  <xsl:param name="program" />
 
 
   <xsl:template match="/expr/list">
@@ -188,7 +189,7 @@
                 </xsl:otherwise>
               </xsl:choose>
             </xsl:when>
-            <xsl:when test="$revision != 'local' and contains(@value, 'nixops') and contains(@value, '/nix/')">
+            <xsl:when test="$revision != 'local' and $program = 'nixops' and contains(@value, '/nix/')">
               <xsl:attribute name="xlink:href">https://github.com/NixOS/nixops/blob/<xsl:value-of select="$revision"/>/nix/<xsl:value-of select="substring-after(@value, '/nix/')"/></xsl:attribute>
             </xsl:when>
             <xsl:otherwise>
diff --git a/nixos/doc/manual/release-notes/rl-1609.xml b/nixos/doc/manual/release-notes/rl-1609.xml
index b08688a66959..be175a54c232 100644
--- a/nixos/doc/manual/release-notes/rl-1609.xml
+++ b/nixos/doc/manual/release-notes/rl-1609.xml
@@ -16,6 +16,10 @@ has the following highlights: </para>
     See <xref linkend="sec-booting-from-pxe" /> for documentation.</para>
   </listitem>
 
+  <listitem>
+    <para>Xorg-server-1.18.*. If you choose <literal>"ati_unfree"</literal> driver,
+    1.17.* is still used due to ABI incompatibility.</para>
+  </listitem>
 </itemizedlist>
 
 <para>The following new services were added since the last release:</para>
diff --git a/nixos/modules/hardware/video/ati.nix b/nixos/modules/hardware/video/ati.nix
index 033e49d2233e..bf91bcf0776b 100644
--- a/nixos/modules/hardware/video/ati.nix
+++ b/nixos/modules/hardware/video/ati.nix
@@ -18,6 +18,8 @@ in
 
   config = mkIf enabled {
 
+    nixpkgs.config.xorg.fglrxCompat = true;
+
     services.xserver.drivers = singleton
       { name = "fglrx"; modules = [ ati_x11 ]; libPath = [ "${ati_x11}/lib" ]; };
 
diff --git a/nixos/modules/installer/cd-dvd/iso-image.nix b/nixos/modules/installer/cd-dvd/iso-image.nix
index bdb3c227ecc8..4fc8bf5428f8 100644
--- a/nixos/modules/installer/cd-dvd/iso-image.nix
+++ b/nixos/modules/installer/cd-dvd/iso-image.nix
@@ -64,7 +64,7 @@ let
   # The EFI boot image.
   efiDir = pkgs.runCommand "efi-directory" {} ''
     mkdir -p $out/EFI/boot
-    cp -v ${pkgs.gummiboot}/lib/gummiboot/gummiboot${targetArch}.efi $out/EFI/boot/boot${targetArch}.efi
+    cp -v ${pkgs.systemd}/lib/systemd/boot/efi/systemd-boot${targetArch}.efi $out/EFI/boot/boot${targetArch}.efi
     mkdir -p $out/loader/entries
 
     echo "title NixOS Live CD" > $out/loader/entries/nixos-livecd.conf
diff --git a/nixos/modules/installer/tools/nixos-generate-config.pl b/nixos/modules/installer/tools/nixos-generate-config.pl
index ca7fb71ba9b8..5e576367eb2f 100644
--- a/nixos/modules/installer/tools/nixos-generate-config.pl
+++ b/nixos/modules/installer/tools/nixos-generate-config.pl
@@ -518,8 +518,8 @@ if ($showHardwareConfig) {
         my $bootLoaderConfig = "";
         if (-e "/sys/firmware/efi/efivars") {
             $bootLoaderConfig = <<EOF;
-  # Use the gummiboot efi boot loader.
-  boot.loader.gummiboot.enable = true;
+  # Use the systemd-boot EFI boot loader.
+  boot.loader.systemd-boot.enable = true;
   boot.loader.efi.canTouchEfiVariables = true;
 EOF
         } elsif ($virt ne "systemd-nspawn") {
diff --git a/nixos/modules/misc/version.nix b/nixos/modules/misc/version.nix
index fd7cadf76cc1..9a37f5950930 100644
--- a/nixos/modules/misc/version.nix
+++ b/nixos/modules/misc/version.nix
@@ -104,8 +104,8 @@ in
       # changing them would not rebuild the manual
       nixosLabel   = mkDefault (maybeEnv "NIXOS_LABEL" cfg.nixosVersion);
       nixosVersion = mkDefault (maybeEnv "NIXOS_VERSION" (cfg.nixosRelease + cfg.nixosVersionSuffix));
-      nixosRevision      = mkIf (pathExists gitRepo) (mkDefault            gitCommitId);
-      nixosVersionSuffix = mkIf (pathExists gitRepo) (mkDefault (".git." + gitCommitId));
+      nixosRevision      = mkIf (pathIsDirectory gitRepo) (mkDefault            gitCommitId);
+      nixosVersionSuffix = mkIf (pathIsDirectory gitRepo) (mkDefault (".git." + gitCommitId));
 
       # Note: code names must only increase in alphabetical order.
       nixosCodeName = "Flounder";
diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix
index 1d0cfbb4f663..37a200c09588 100644
--- a/nixos/modules/module-list.nix
+++ b/nixos/modules/module-list.nix
@@ -79,6 +79,7 @@
   ./programs/ssh.nix
   ./programs/ssmtp.nix
   ./programs/tmux.nix
+  ./programs/unity3d.nix
   ./programs/venus.nix
   ./programs/wvdial.nix
   ./programs/xfs_quota.nix
@@ -127,6 +128,7 @@
   ./services/continuous-integration/jenkins/default.nix
   ./services/continuous-integration/jenkins/slave.nix
   ./services/continuous-integration/jenkins/job-builder.nix
+  ./services/continuous-integration/hydra/default.nix
   ./services/databases/4store-endpoint.nix
   ./services/databases/4store.nix
   ./services/databases/couchdb.nix
@@ -428,6 +430,7 @@
   ./services/security/haveged.nix
   ./services/security/hologram.nix
   ./services/security/munge.nix
+  ./services/security/oauth2_proxy.nix
   ./services/security/physlock.nix
   ./services/security/torify.nix
   ./services/security/tor.nix
@@ -503,10 +506,10 @@
   ./system/boot/loader/grub/grub.nix
   ./system/boot/loader/grub/ipxe.nix
   ./system/boot/loader/grub/memtest.nix
-  ./system/boot/loader/gummiboot/gummiboot.nix
   ./system/boot/loader/init-script/init-script.nix
   ./system/boot/loader/loader.nix
   ./system/boot/loader/raspberrypi/raspberrypi.nix
+  ./system/boot/loader/systemd-boot/systemd-boot.nix
   ./system/boot/luksroot.nix
   ./system/boot/modprobe.nix
   ./system/boot/networkd.nix
diff --git a/nixos/modules/programs/unity3d.nix b/nixos/modules/programs/unity3d.nix
new file mode 100644
index 000000000000..3c0ea26d9d56
--- /dev/null
+++ b/nixos/modules/programs/unity3d.nix
@@ -0,0 +1,25 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let cfg = config.programs.unity3d;
+in {
+
+  options = {
+    programs.unity3d.enable = mkEnableOption "Unity3D, a game development tool";
+  };
+
+  config = mkIf cfg.enable {
+    security.setuidOwners = [{
+      program = "unity-chrome-sandbox";
+      source = "${pkgs.unity3d.sandbox}/bin/unity-chrome-sandbox";
+      owner = "root";
+      #group = "root";
+      setuid = true;
+      #setgid = true;
+    }];
+
+    environment.systemPackages = [ pkgs.unity3d ];
+  };
+
+}
diff --git a/nixos/modules/security/acme.nix b/nixos/modules/security/acme.nix
index cb5410a5f15d..ef6da788e619 100644
--- a/nixos/modules/security/acme.nix
+++ b/nixos/modules/security/acme.nix
@@ -114,6 +114,19 @@ in
         '';
       };
 
+      preliminarySelfsigned = mkOption {
+        type = types.bool;
+        default = true;
+        description = ''
+          Whether a preliminary self-signed certificate should be generated before
+          doing ACME requests. This can be useful when certificates are required in
+          a webserver, but ACME needs the webserver to make its requests.
+
+          With preliminary self-signed certificate the webserver can be started and
+          can later reload the correct ACME certificates.
+        '';
+      };
+
       certs = mkOption {
         default = { };
         type = types.loaOf types.optionSet;
@@ -140,54 +153,126 @@ in
   config = mkMerge [
     (mkIf (cfg.certs != { }) {
 
-      systemd.services = flip mapAttrs' cfg.certs (cert: data:
-        let
-          cpath = "${cfg.directory}/${cert}";
-          rights = if data.allowKeysForGroup then "750" else "700";
-          cmdline = [ "-v" "-d" cert "--default_root" data.webroot "--valid_min" cfg.validMin ]
-                    ++ optionals (data.email != null) [ "--email" data.email ]
-                    ++ concatMap (p: [ "-f" p ]) data.plugins
-                    ++ concatLists (mapAttrsToList (name: root: [ "-d" (if root == null then name else "${name}:${root}")]) data.extraDomains);
+      systemd.services = let
+          services = concatLists servicesLists;
+          servicesLists = mapAttrsToList certToServices cfg.certs;
+          certToServices = cert: data:
+              let
+                cpath = "${cfg.directory}/${cert}";
+                rights = if data.allowKeysForGroup then "750" else "700";
+                cmdline = [ "-v" "-d" cert "--default_root" data.webroot "--valid_min" cfg.validMin ]
+                          ++ optionals (data.email != null) [ "--email" data.email ]
+                          ++ concatMap (p: [ "-f" p ]) data.plugins
+                          ++ concatLists (mapAttrsToList (name: root: [ "-d" (if root == null then name else "${name}:${root}")]) data.extraDomains);
+                acmeService = {
+                  description = "Renew ACME Certificate for ${cert}";
+                  after = [ "network.target" ];
+                  serviceConfig = {
+                    Type = "oneshot";
+                    SuccessExitStatus = [ "0" "1" ];
+                    PermissionsStartOnly = true;
+                    User = data.user;
+                    Group = data.group;
+                    PrivateTmp = true;
+                  };
+                  path = [ pkgs.simp_le ];
+                  preStart = ''
+                    mkdir -p '${cfg.directory}'
+                    if [ ! -d '${cpath}' ]; then
+                      mkdir '${cpath}'
+                    fi
+                    chmod ${rights} '${cpath}'
+                    chown -R '${data.user}:${data.group}' '${cpath}'
+                  '';
+                  script = ''
+                    cd '${cpath}'
+                    set +e
+                    simp_le ${concatMapStringsSep " " (arg: escapeShellArg (toString arg)) cmdline}
+                    EXITCODE=$?
+                    set -e
+                    echo "$EXITCODE" > /tmp/lastExitCode
+                    exit "$EXITCODE"
+                  '';
+                  postStop = ''
+                    if [ -e /tmp/lastExitCode ] && [ "$(cat /tmp/lastExitCode)" = "0" ]; then
+                      echo "Executing postRun hook..."
+                      ${data.postRun}
+                    fi
+                  '';
 
-        in nameValuePair
-        ("acme-${cert}")
-        ({
-          description = "Renew ACME Certificate for ${cert}";
-          after = [ "network.target" ];
-          serviceConfig = {
-            Type = "oneshot";
-            SuccessExitStatus = [ "0" "1" ];
-            PermissionsStartOnly = true;
-            User = data.user;
-            Group = data.group;
-            PrivateTmp = true;
+                  before = [ "acme-certificates.target" ];
+                  wantedBy = [ "acme-certificates.target" ];
+                };
+                selfsignedService = {
+                  description = "Create preliminary self-signed certificate for ${cert}";
+                  preStart = ''
+                      if [ ! -d '${cpath}' ]
+                      then
+                        mkdir -p '${cpath}'
+                        chmod ${rights} '${cpath}'
+                        chown '${data.user}:${data.group}' '${cpath}'
+                      fi
+                  '';
+                  script = 
+                    ''
+                      # Create self-signed key
+                      workdir="/run/acme-selfsigned-${cert}"
+                      ${pkgs.openssl.bin}/bin/openssl genrsa -des3 -passout pass:x -out $workdir/server.pass.key 2048
+                      ${pkgs.openssl.bin}/bin/openssl rsa -passin pass:x -in $workdir/server.pass.key -out $workdir/server.key
+                      ${pkgs.openssl.bin}/bin/openssl req -new -key $workdir/server.key -out $workdir/server.csr \
+                        -subj "/C=UK/ST=Warwickshire/L=Leamington/O=OrgName/OU=IT Department/CN=example.com"
+                      ${pkgs.openssl.bin}/bin/openssl x509 -req -days 1 -in $workdir/server.csr -signkey $workdir/server.key -out $workdir/server.crt
+
+                      # Move key to destination
+                      mv $workdir/server.key ${cpath}/key.pem
+                      mv $workdir/server.crt ${cpath}/fullchain.pem
+
+                      # Clean up working directory
+                      rm $workdir/server.csr
+                      rm $workdir/server.pass.key
+
+                      # Give key acme permissions
+                      chmod ${rights} '${cpath}/key.pem'
+                      chown '${data.user}:${data.group}' '${cpath}/key.pem'
+                      chmod ${rights} '${cpath}/fullchain.pem'
+                      chown '${data.user}:${data.group}' '${cpath}/fullchain.pem'
+                    '';
+                  serviceConfig = {
+                    Type = "oneshot";
+                    RuntimeDirectory = "acme-selfsigned-${cert}";
+                    PermissionsStartOnly = true;
+                    User = data.user;
+                    Group = data.group;
+                  };
+                  unitConfig = {
+                    # Do not create self-signed key when key already exists
+                    ConditionPathExists = "!${cpath}/key.pem";
+                  };
+                  before = [
+                    "acme-selfsigned-certificates.target"
+                  ];
+                  wantedBy = [
+                    "acme-selfsigned-certificates.target"
+                  ];
+                };
+              in (
+                [ { name = "acme-${cert}"; value = acmeService; } ]
+                ++
+                (if cfg.preliminarySelfsigned
+                  then [ { name = "acme-selfsigned-${cert}"; value = selfsignedService; } ]
+                  else []
+                )
+              );
+          servicesAttr = listToAttrs services;
+          nginxAttr = {
+            nginx = {
+              after = [ "acme-selfsigned-certificates.target" ];
+              wants = [ "acme-selfsigned-certificates.target" "acme-certificates.target" ];
+            };
           };
-          path = [ pkgs.simp_le ];
-          preStart = ''
-            mkdir -p '${cfg.directory}'
-            if [ ! -d '${cpath}' ]; then
-              mkdir '${cpath}'
-            fi
-            chmod ${rights} '${cpath}'
-            chown -R '${data.user}:${data.group}' '${cpath}'
-          '';
-          script = ''
-            cd '${cpath}'
-            set +e
-            simp_le ${concatMapStringsSep " " (arg: escapeShellArg (toString arg)) cmdline}
-            EXITCODE=$?
-            set -e
-            echo "$EXITCODE" > /tmp/lastExitCode
-            exit "$EXITCODE"
-          '';
-          postStop = ''
-            if [ -e /tmp/lastExitCode ] && [ "$(cat /tmp/lastExitCode)" = "0" ]; then
-              echo "Executing postRun hook..."
-              ${data.postRun}
-            fi
-          '';
-        })
-      );
+        in
+          servicesAttr //
+          (if config.services.nginx.enable then nginxAttr else {});
 
       systemd.timers = flip mapAttrs' cfg.certs (cert: data: nameValuePair
         ("acme-${cert}")
@@ -200,6 +285,9 @@ in
           };
         })
       );
+
+      systemd.targets."acme-selfsigned-certificates" = mkIf cfg.preliminarySelfsigned {};
+      systemd.targets."acme-certificates" = {};
     })
 
     { meta.maintainers = with lib.maintainers; [ abbradar fpletz globin ];
diff --git a/nixos/modules/security/acme.xml b/nixos/modules/security/acme.xml
index e32fa72c9393..15ed4c04a23d 100644
--- a/nixos/modules/security/acme.xml
+++ b/nixos/modules/security/acme.xml
@@ -66,4 +66,32 @@ options for the <literal>security.acme</literal> module.</para>
 
 </section>
 
+<section><title>Using ACME certificates in Nginx</title>
+<para>In practice ACME is mostly used for retrieval and renewal of
+  certificates that will be used in a webserver like Nginx. A configuration for
+  Nginx that uses the certificates from ACME for
+  <literal>foo.example.com</literal> will look similar to:
+</para>
+
+<programlisting>
+services.nginx.httpConfig = ''
+  server {
+    server_name foo.example.com;
+    listen 443 ssl;
+    ssl_certificate     ${config.security.acme.directory}/foo.example.com/fullchain.pem;
+    ssl_certificate_key ${config.security.acme.directory}/foo.example.com/key.pem;
+    root /var/www/foo.example.com/;
+  }
+'';
+</programlisting>
+
+<para>Now Nginx will try to use the certificates that will be retrieved by ACME.
+  ACME needs Nginx (or any other webserver) to function and Nginx needs
+  the certificates to actually start. For this reason the ACME module
+  automatically generates self-signed certificates that will be used by Nginx to
+  start. After that Nginx is used by ACME to retrieve the actual ACME
+  certificates. <literal>security.acme.preliminarySelfsigned</literal> can be
+  used to control whether to generate the self-signed certificates.
+</para>
+</section>
 </chapter>
diff --git a/nixos/modules/services/continuous-integration/hydra/default.nix b/nixos/modules/services/continuous-integration/hydra/default.nix
new file mode 100644
index 000000000000..c8edfaf18537
--- /dev/null
+++ b/nixos/modules/services/continuous-integration/hydra/default.nix
@@ -0,0 +1,418 @@
+{ config, pkgs, lib, ... }:
+
+with lib;
+
+let
+
+  cfg = config.services.hydra;
+
+  baseDir = "/var/lib/hydra";
+
+  hydraConf = pkgs.writeScript "hydra.conf" cfg.extraConfig;
+
+  hydraEnv =
+    { HYDRA_DBI = cfg.dbi;
+      HYDRA_CONFIG = "${baseDir}/hydra.conf";
+      HYDRA_DATA = "${baseDir}";
+    };
+
+  env =
+    { NIX_REMOTE = "daemon";
+      SSL_CERT_FILE = "/etc/ssl/certs/ca-certificates.crt"; # Remove in 16.03
+      PGPASSFILE = "${baseDir}/pgpass";
+      NIX_REMOTE_SYSTEMS = concatStringsSep ":" cfg.buildMachinesFiles;
+    } // optionalAttrs (cfg.smtpHost != null) {
+      EMAIL_SENDER_TRANSPORT = "SMTP";
+      EMAIL_SENDER_TRANSPORT_host = cfg.smtpHost;
+    } // hydraEnv // cfg.extraEnv;
+
+  serverEnv = env //
+    { HYDRA_TRACKER = cfg.tracker;
+      COLUMNS = "80";
+      PGPASSFILE = "${baseDir}/pgpass-www"; # grrr
+    } // (optionalAttrs cfg.debugServer { DBIC_TRACE = "1"; });
+
+  localDB = "dbi:Pg:dbname=hydra;user=hydra;";
+
+  haveLocalDB = cfg.dbi == localDB;
+
+in
+
+{
+  ###### interface
+  options = {
+
+    services.hydra = rec {
+
+      enable = mkOption {
+        type = types.bool;
+        default = false;
+        description = ''
+          Whether to run Hydra services.
+        '';
+      };
+
+      dbi = mkOption {
+        type = types.str;
+        default = localDB;
+        example = "dbi:Pg:dbname=hydra;host=postgres.example.org;user=foo;";
+        description = ''
+          The DBI string for Hydra database connection.
+        '';
+      };
+
+      package = mkOption {
+        type = types.path;
+        default = pkgs.hydra;
+        defaultText = "pkgs.hydra";
+        description = "The Hydra package.";
+      };
+
+      hydraURL = mkOption {
+        type = types.str;
+        description = ''
+          The base URL for the Hydra webserver instance. Used for links in emails.
+        '';
+      };
+
+      listenHost = mkOption {
+        type = types.str;
+        default = "*";
+        example = "localhost";
+        description = ''
+          The hostname or address to listen on or <literal>*</literal> to listen
+          on all interfaces.
+        '';
+      };
+
+      port = mkOption {
+        type = types.int;
+        default = 3000;
+        description = ''
+          TCP port the web server should listen to.
+        '';
+      };
+
+      minimumDiskFree = mkOption {
+        type = types.int;
+        default = 0;
+        description = ''
+          Threshold of minimum disk space (GiB) to determine if the queue runner should run or not.
+        '';
+      };
+
+      minimumDiskFreeEvaluator = mkOption {
+        type = types.int;
+        default = 0;
+        description = ''
+          Threshold of minimum disk space (GiB) to determine if the evaluator should run or not.
+        '';
+      };
+
+      notificationSender = mkOption {
+        type = types.str;
+        description = ''
+          Sender email address used for email notifications.
+        '';
+      };
+
+      smtpHost = mkOption {
+        type = types.nullOr types.str;
+        default = null;
+        example = ["localhost"];
+        description = ''
+          Hostname of the SMTP server to use to send email.
+        '';
+      };
+
+      tracker = mkOption {
+        type = types.str;
+        default = "";
+        description = ''
+          Piece of HTML that is included on all pages.
+        '';
+      };
+
+      logo = mkOption {
+        type = types.nullOr types.path;
+        default = null;
+        description = ''
+          Path to a file containing the logo of your Hydra instance.
+        '';
+      };
+
+      debugServer = mkOption {
+        type = types.bool;
+        default = false;
+        description = "Whether to run the server in debug mode.";
+      };
+
+      extraConfig = mkOption {
+        type = types.lines;
+        description = "Extra lines for the Hydra configuration.";
+      };
+
+      extraEnv = mkOption {
+        type = types.attrsOf types.str;
+        default = {};
+        description = "Extra environment variables for Hydra.";
+      };
+
+      gcRootsDir = mkOption {
+        type = types.path;
+        default = "/nix/var/nix/gcroots/hydra";
+        description = "Directory that holds Hydra garbage collector roots.";
+      };
+
+      buildMachinesFiles = mkOption {
+        type = types.listOf types.path;
+        default = [];
+        example = [ "/etc/nix/machines" "/var/lib/hydra/provisioner/machines" ];
+        description = "List of files containing build machines.";
+      };
+
+      useSubstitutes = mkOption {
+        type = types.bool;
+        default = false;
+        description = ''
+          Whether to use binary caches for downloading store paths. Note that
+          binary substitutions trigger (a potentially large number of) additional
+          HTTP requests that slow down the queue monitor thread significantly.
+          Also, this Hydra instance will serve those downloaded store paths to
+          its users with its own signature attached as if it had built them
+          itself, so don't enable this feature unless your active binary caches
+          are absolute trustworthy.
+        '';
+      };
+    };
+
+  };
+
+
+  ###### implementation
+
+  config = mkIf cfg.enable {
+
+    users.extraGroups.hydra = { };
+
+    users.extraUsers.hydra =
+      { description = "Hydra";
+        group = "hydra";
+        createHome = true;
+        home = baseDir;
+        useDefaultShell = true;
+      };
+
+    users.extraUsers.hydra-queue-runner =
+      { description = "Hydra queue runner";
+        group = "hydra";
+        useDefaultShell = true;
+        home = "${baseDir}/queue-runner"; # really only to keep SSH happy
+      };
+
+    users.extraUsers.hydra-www =
+      { description = "Hydra web server";
+        group = "hydra";
+        useDefaultShell = true;
+      };
+
+    nix.trustedUsers = [ "hydra-queue-runner" ];
+
+    services.hydra.extraConfig =
+      ''
+        using_frontend_proxy 1
+        base_uri ${cfg.hydraURL}
+        notification_sender ${cfg.notificationSender}
+        max_servers 25
+        ${optionalString (cfg.logo != null) ''
+          hydra_logo ${cfg.logo}
+        ''}
+        gc_roots_dir ${cfg.gcRootsDir}
+      '';
+
+    environment.systemPackages = [ cfg.package ];
+
+    environment.variables = hydraEnv;
+
+    nix.extraOptions = ''
+      gc-keep-outputs = true
+      gc-keep-derivations = true
+
+      # The default (`true') slows Nix down a lot since the build farm
+      # has so many GC roots.
+      gc-check-reachability = false
+    '';
+
+    systemd.services.hydra-init =
+      { wantedBy = [ "multi-user.target" ];
+        requires = optional haveLocalDB "postgresql.service";
+        after = optional haveLocalDB "postgresql.service";
+        environment = env;
+        preStart = ''
+          mkdir -p ${baseDir}
+          chown hydra.hydra ${baseDir}
+          chmod 0750 ${baseDir}
+
+          ln -sf ${hydraConf} ${baseDir}/hydra.conf
+
+          mkdir -m 0700 -p ${baseDir}/www
+          chown hydra-www.hydra ${baseDir}/www
+
+          mkdir -m 0700 -p ${baseDir}/queue-runner
+          mkdir -m 0750 -p ${baseDir}/build-logs
+          chown hydra-queue-runner.hydra ${baseDir}/queue-runner ${baseDir}/build-logs
+
+          ${optionalString haveLocalDB ''
+            if ! [ -e ${baseDir}/.db-created ]; then
+              ${config.services.postgresql.package}/bin/createuser hydra
+              ${config.services.postgresql.package}/bin/createdb -O hydra hydra
+              touch ${baseDir}/.db-created
+            fi
+          ''}
+
+          if [ ! -e ${cfg.gcRootsDir} ]; then
+
+            # Move legacy roots directory.
+            if [ -e /nix/var/nix/gcroots/per-user/hydra/hydra-roots ]; then
+              mv /nix/var/nix/gcroots/per-user/hydra/hydra-roots ${cfg.gcRootsDir}
+            fi
+
+            mkdir -p ${cfg.gcRootsDir}
+          fi
+
+          # Move legacy hydra-www roots.
+          if [ -e /nix/var/nix/gcroots/per-user/hydra-www/hydra-roots ]; then
+            find /nix/var/nix/gcroots/per-user/hydra-www/hydra-roots/ -type f \
+              | xargs -r mv -f -t ${cfg.gcRootsDir}/
+            rmdir /nix/var/nix/gcroots/per-user/hydra-www/hydra-roots
+          fi
+
+          chown hydra.hydra ${cfg.gcRootsDir}
+          chmod 2775 ${cfg.gcRootsDir}
+        '';
+        serviceConfig.ExecStart = "${cfg.package}/bin/hydra-init";
+        serviceConfig.PermissionsStartOnly = true;
+        serviceConfig.User = "hydra";
+        serviceConfig.Type = "oneshot";
+        serviceConfig.RemainAfterExit = true;
+      };
+
+    systemd.services.hydra-server =
+      { wantedBy = [ "multi-user.target" ];
+        requires = [ "hydra-init.service" ];
+        after = [ "hydra-init.service" ];
+        environment = serverEnv;
+        serviceConfig =
+          { ExecStart =
+              "@${cfg.package}/bin/hydra-server hydra-server -f -h '${cfg.listenHost}' "
+              + "-p ${toString cfg.port} --max_spare_servers 5 --max_servers 25 "
+              + "--max_requests 100 ${optionalString cfg.debugServer "-d"}";
+            User = "hydra-www";
+            PermissionsStartOnly = true;
+            Restart = "always";
+          };
+      };
+
+    systemd.services.hydra-queue-runner =
+      { wantedBy = [ "multi-user.target" ];
+        requires = [ "hydra-init.service" ];
+        after = [ "hydra-init.service" "network.target" ];
+        path = [ cfg.package pkgs.nettools pkgs.openssh pkgs.bzip2 config.nix.package ];
+        environment = env // {
+          PGPASSFILE = "${baseDir}/pgpass-queue-runner"; # grrr
+          IN_SYSTEMD = "1"; # to get log severity levels
+        };
+        serviceConfig =
+          { ExecStart = "@${cfg.package}/bin/hydra-queue-runner hydra-queue-runner -v --option build-use-substitutes ${if cfg.useSubstitutes then "true" else "false"}";
+            ExecStopPost = "${cfg.package}/bin/hydra-queue-runner --unlock";
+            User = "hydra-queue-runner";
+            Restart = "always";
+
+            # Ensure we can get core dumps.
+            LimitCORE = "infinity";
+            WorkingDirectory = "${baseDir}/queue-runner";
+          };
+      };
+
+    systemd.services.hydra-evaluator =
+      { wantedBy = [ "multi-user.target" ];
+        requires = [ "hydra-init.service" ];
+        after = [ "hydra-init.service" "network.target" ];
+        path = [ pkgs.nettools ];
+        environment = env;
+        serviceConfig =
+          { ExecStart = "@${cfg.package}/bin/hydra-evaluator hydra-evaluator";
+            User = "hydra";
+            Restart = "always";
+            WorkingDirectory = baseDir;
+          };
+      };
+
+    systemd.services.hydra-update-gc-roots =
+      { requires = [ "hydra-init.service" ];
+        after = [ "hydra-init.service" ];
+        environment = env;
+        serviceConfig =
+          { ExecStart = "@${cfg.package}/bin/hydra-update-gc-roots hydra-update-gc-roots";
+            User = "hydra";
+          };
+        startAt = "2,14:15";
+      };
+
+    systemd.services.hydra-send-stats =
+      { wantedBy = [ "multi-user.target" ];
+        after = [ "hydra-init.service" ];
+        environment = env;
+        serviceConfig =
+          { ExecStart = "@${cfg.package}/bin/hydra-send-stats hydra-send-stats";
+            User = "hydra";
+          };
+      };
+
+    # If there is less than a certain amount of free disk space, stop
+    # the queue/evaluator to prevent builds from failing or aborting.
+    systemd.services.hydra-check-space =
+      { script =
+          ''
+            if [ $(($(stat -f -c '%a' /nix/store) * $(stat -f -c '%S' /nix/store))) -lt $((${toString cfg.minimumDiskFree} * 1024**3)) ]; then
+                echo "stopping Hydra queue runner due to lack of free space..."
+                systemctl stop hydra-queue-runner
+            fi
+            if [ $(($(stat -f -c '%a' /nix/store) * $(stat -f -c '%S' /nix/store))) -lt $((${toString cfg.minimumDiskFreeEvaluator} * 1024**3)) ]; then
+                echo "stopping Hydra evaluator due to lack of free space..."
+                systemctl stop hydra-evaluator
+            fi
+          '';
+        startAt = "*:0/5";
+      };
+
+    # Periodically compress build logs. The queue runner compresses
+    # logs automatically after a step finishes, but this doesn't work
+    # if the queue runner is stopped prematurely.
+    systemd.services.hydra-compress-logs =
+      { path = [ pkgs.bzip2 ];
+        script =
+          ''
+            find /var/lib/hydra/build-logs -type f -name "*.drv" -mtime +3 -size +0c | xargs -r bzip2 -v -f
+          '';
+        startAt = "Sun 01:45";
+      };
+
+    services.postgresql.enable = mkIf haveLocalDB true;
+
+    services.postgresql.identMap = optionalString haveLocalDB
+      ''
+        hydra-users hydra hydra
+        hydra-users hydra-queue-runner hydra
+        hydra-users hydra-www hydra
+        hydra-users root hydra
+      '';
+
+    services.postgresql.authentication = optionalString haveLocalDB
+      ''
+        local hydra all ident map=hydra-users
+      '';
+
+  };
+
+}
diff --git a/nixos/modules/services/databases/openldap.nix b/nixos/modules/services/databases/openldap.nix
index 9e86559dda04..cbdc676d47bd 100644
--- a/nixos/modules/services/databases/openldap.nix
+++ b/nixos/modules/services/databases/openldap.nix
@@ -52,11 +52,12 @@ in
         description = "
           sldapd.conf configuration
         ";
-        example = ''
-            include ''${pkgs.openldap}/etc/openldap/schema/core.schema
-            include ''${pkgs.openldap}/etc/openldap/schema/cosine.schema
-            include ''${pkgs.openldap}/etc/openldap/schema/inetorgperson.schema
-            include ''${pkgs.openldap}/etc/openldap/schema/nis.schema
+        example = literalExample ''
+            '''
+            include ${pkgs.openldap.out}/etc/openldap/schema/core.schema
+            include ${pkgs.openldap.out}/etc/openldap/schema/cosine.schema
+            include ${pkgs.openldap.out}/etc/openldap/schema/inetorgperson.schema
+            include ${pkgs.openldap.out}/etc/openldap/schema/nis.schema
 
             database bdb 
             suffix dc=example,dc=org 
@@ -64,6 +65,7 @@ in
             # NOTE: change after first start
             rootpw secret
             directory /var/db/openldap
+            '''
           '';
       };
     };
diff --git a/nixos/modules/services/hardware/pcscd.nix b/nixos/modules/services/hardware/pcscd.nix
index 6e30dfb752d2..fa97e8bf746b 100644
--- a/nixos/modules/services/hardware/pcscd.nix
+++ b/nixos/modules/services/hardware/pcscd.nix
@@ -1,29 +1,51 @@
 { config, lib, pkgs, ... }:
 
+with lib;
+
 let
-  cfgFile = pkgs.writeText "reader.conf" "";
-in
+  cfgFile = pkgs.writeText "reader.conf" config.services.pcscd.readerConfig;
 
-with lib;
+  pluginEnv = pkgs.buildEnv {
+    name = "pcscd-plugins";
+    paths = map (p: "${p}/pcsc/drivers") config.services.pcscd.plugins;
+  };
 
-{
+in {
 
   ###### interface
 
   options = {
 
     services.pcscd = {
-
-      enable = mkOption {
-        default = false;
-        description = "Whether to enable the PCSC-Lite daemon.";
+      enable = mkEnableOption "PCSC-Lite daemon";
+
+      plugins = mkOption {
+        type = types.listOf types.package;
+        default = [ pkgs.ccid ];
+        defaultText = "[ pkgs.ccid ]";
+        example = literalExample "[ pkgs.pcsc-cyberjack ]";
+        description = "Plugin packages to be used for PCSC-Lite.";
       };
 
+      readerConfig = mkOption {
+        type = types.lines;
+        default = "";
+        example = ''
+          FRIENDLYNAME      "Some serial reader"
+          DEVICENAME        /dev/ttyS0
+          LIBPATH           /path/to/serial_reader.so
+          CHANNELID         1
+        '';
+        description = ''
+          Configuration for devices that aren't hotpluggable.
+
+          See <citerefentry><refentrytitle>reader.conf</refentrytitle>
+          <manvolnum>5</manvolnum></citerefentry> for valid options.
+        '';
+      };
     };
-
   };
 
-
   ###### implementation
 
   config = mkIf config.services.pcscd.enable {
@@ -37,18 +59,11 @@ with lib;
 
     systemd.services.pcscd = {
       description = "PCSC-Lite daemon";
-      preStart = ''
-          mkdir -p /var/lib/pcsc
-          rm -Rf /var/lib/pcsc/drivers
-          ln -s ${pkgs.ccid}/pcsc/drivers /var/lib/pcsc/
-      '';
+      environment.PCSCLITE_HP_DROPDIR = pluginEnv;
       serviceConfig = {
-        Type = "forking";
-        ExecStart = "${pkgs.pcsclite}/sbin/pcscd --auto-exit -c ${cfgFile}";
-        ExecReload = "${pkgs.pcsclite}/sbin/pcscd --hotplug";
+        ExecStart = "${pkgs.pcsclite}/sbin/pcscd -f -x -c ${cfgFile}";
+        ExecReload = "${pkgs.pcsclite}/sbin/pcscd -H";
       };
     };
-
   };
-
 }
diff --git a/nixos/modules/services/networking/dnscrypt-proxy.nix b/nixos/modules/services/networking/dnscrypt-proxy.nix
index 2a6161ee873a..227e38acc4a6 100644
--- a/nixos/modules/services/networking/dnscrypt-proxy.nix
+++ b/nixos/modules/services/networking/dnscrypt-proxy.nix
@@ -89,8 +89,8 @@ in
         '';
         example = literalExample "${pkgs.dnscrypt-proxy}/share/dnscrypt-proxy/dnscrypt-resolvers.csv";
         default = pkgs.fetchurl {
-          url = "https://raw.githubusercontent.com/jedisct1/dnscrypt-proxy/master/dnscrypt-resolvers.csv";
-          sha256 = "0lac20qhcgjxxiiz8jzcn3hkqj4ywl58hahp5n2i6vf9akfyqp7c";
+          url = https://raw.githubusercontent.com/jedisct1/dnscrypt-proxy/master/dnscrypt-resolvers.csv;
+          sha256 = "171zvdqcqqvcw3zr7wl9h1wmdmk6m3h55xr4gq2z1j7a0x0ba2in";
         };
         defaultText = "pkgs.fetchurl { url = ...; sha256 = ...; }";
       };
diff --git a/nixos/modules/services/networking/openvpn.nix b/nixos/modules/services/networking/openvpn.nix
index a96888dec864..82173a841a3f 100644
--- a/nixos/modules/services/networking/openvpn.nix
+++ b/nixos/modules/services/networking/openvpn.nix
@@ -29,21 +29,27 @@ let
         done
 
         ${cfg.up}
+        ${optionalString cfg.updateResolvConf
+           "${pkgs.update-resolv-conf}/libexec/openvpn/update-resolv-conf"}
       '';
 
       downScript = ''
         #! /bin/sh
         export PATH=${path}
+        ${optionalString cfg.updateResolvConf
+           "${pkgs.update-resolv-conf}/libexec/openvpn/update-resolv-conf"}
         ${cfg.down}
       '';
 
       configFile = pkgs.writeText "openvpn-config-${name}"
         ''
           errors-to-stderr
-          ${optionalString (cfg.up != "" || cfg.down != "") "script-security 2"}
+          ${optionalString (cfg.up != "" || cfg.down != "" || cfg.updateResolvConf) "script-security 2"}
           ${cfg.config}
-          ${optionalString (cfg.up != "") "up ${pkgs.writeScript "openvpn-${name}-up" upScript}"}
-          ${optionalString (cfg.down != "") "down ${pkgs.writeScript "openvpn-${name}-down" downScript}"}
+          ${optionalString (cfg.up != "" || cfg.updateResolvConf)
+              "up ${pkgs.writeScript "openvpn-${name}-up" upScript}"}
+          ${optionalString (cfg.down != "" || cfg.updateResolvConf)
+              "down ${pkgs.writeScript "openvpn-${name}-down" downScript}"}
         '';
 
     in {
@@ -145,6 +151,16 @@ in
           description = "Whether this OpenVPN instance should be started automatically.";
         };
 
+        updateResolvConf = mkOption {
+          default = false;
+          type = types.bool;
+          description = ''
+            Use the script from the update-resolv-conf package to automatically
+            update resolv.conf with the DNS information provided by openvpn. The
+            script will be run after the "up" commands and before the "down" commands.
+          '';
+        };
+
       };
 
     };
diff --git a/nixos/modules/services/security/oauth2_proxy.nix b/nixos/modules/services/security/oauth2_proxy.nix
new file mode 100644
index 000000000000..b149373076a6
--- /dev/null
+++ b/nixos/modules/services/security/oauth2_proxy.nix
@@ -0,0 +1,523 @@
+# NixOS module for oauth2_proxy.
+
+{ config, lib, pkgs, ... }:
+
+with lib;
+let
+  cfg = config.services.oauth2_proxy;
+
+  # Use like:
+  #   repeatedArgs (arg: "--arg=${arg}") args
+  repeatedArgs = concatMapStringsSep " ";
+
+  # 'toString' doesn't quite do what we want for bools.
+  fromBool = x: if x then "true" else "false";
+
+  # oauth2_proxy provides many options that are only relevant if you are using
+  # a certain provider. This set maps from provider name to a function that
+  # takes the configuration and returns a string that can be inserted into the
+  # command-line to launch oauth2_proxy.
+  providerSpecificOptions = {
+    azure = cfg: ''
+      --azure-tenant=${cfg.azure.tenant} \
+      --resource=${cfg.azure.resource} \
+    '';
+
+    github = cfg: ''
+      $(optionalString (!isNull cfg.github.org) "--github-org=${cfg.github.org}") \
+      $(optionalString (!isNull cfg.github.team) "--github-org=${cfg.github.team}") \
+    '';
+
+    google = cfg: ''
+      --google-admin-email=${cfg.google.adminEmail} \
+      --google-service-account=${cfg.google.serviceAccountJSON} \
+      $(repeatedArgs (group: "--google-group=${group}") cfg.google.groups) \
+    '';
+  };
+
+  authenticatedEmailsFile = pkgs.writeText "authenticated-emails" cfg.email.addresses;
+
+  getProviderOptions = cfg: provider:
+    if providerSpecificOptions ? provider then providerSpecificOptions.provider cfg else "";
+
+  mkCommandLine = cfg: ''
+    --provider='${cfg.provider}' \
+    ${optionalString (!isNull cfg.email.addresses) "--authenticated-emails-file='${authenticatedEmailsFile}'"} \
+    --approval-prompt='${cfg.approvalPrompt}' \
+    ${optionalString (cfg.passBasicAuth && !isNull cfg.basicAuthPassword) "--basic-auth-password='${cfg.basicAuthPassword}'"} \
+    --client-id='${cfg.clientID}' \
+    --client-secret='${cfg.clientSecret}' \
+    ${optionalString (!isNull cfg.cookie.domain) "--cookie-domain='${cfg.cookie.domain}'"} \
+    --cookie-expire='${cfg.cookie.expire}' \
+    --cookie-httponly=${fromBool cfg.cookie.httpOnly} \
+    --cookie-name='${cfg.cookie.name}' \
+    --cookie-secret='${cfg.cookie.secret}' \
+    --cookie-secure=${fromBool cfg.cookie.secure} \
+    ${optionalString (!isNull cfg.cookie.refresh) "--cookie-refresh='${cfg.cookie.refresh}'"} \
+    ${optionalString (!isNull cfg.customTemplatesDir) "--custom-templates-dir='${cfg.customTemplatesDir}'"} \
+    ${repeatedArgs (x: "--email-domain='${x}'") cfg.email.domains} \
+    --http-address='${cfg.httpAddress}' \
+    ${optionalString (!isNull cfg.htpasswd.file) "--htpasswd-file='${cfg.htpasswd.file}' --display-htpasswd-form=${fromBool cfg.htpasswd.displayForm}"} \
+    ${optionalString (!isNull cfg.loginURL) "--login-url='${cfg.loginURL}'"} \
+    --pass-access-token=${fromBool cfg.passAccessToken} \
+    --pass-basic-auth=${fromBool cfg.passBasicAuth} \
+    --pass-host-header=${fromBool cfg.passHostHeader} \
+    --proxy-prefix='${cfg.proxyPrefix}' \
+    ${optionalString (!isNull cfg.profileURL) "--profile-url='${cfg.profileURL}'"} \
+    ${optionalString (!isNull cfg.redeemURL) "--redeem-url='${cfg.redeemURL}'"} \
+    ${optionalString (!isNull cfg.redirectURL) "--redirect-url='${cfg.redirectURL}'"} \
+    --request-logging=${fromBool cfg.requestLogging} \
+    ${optionalString (!isNull cfg.scope) "--scope='${cfg.scope}'"} \
+    ${repeatedArgs (x: "--skip-auth-regex='${x}'") cfg.skipAuthRegexes} \
+    ${optionalString (!isNull cfg.signatureKey) "--signature-key='${cfg.signatureKey}'"} \
+    --upstream='${cfg.upstream}' \
+    ${optionalString (!isNull cfg.validateURL) "--validate-url='${cfg.validateURL}'"} \
+    ${optionalString cfg.tls.enable "--tls-cert='${cfg.tls.certificate}' --tls-key='${cfg.tls.key}' --https-address='${cfg.tls.httpsAddress}'"} \
+  '' + getProviderOptions cfg cfg.provider;
+in
+{
+  options.services.oauth2_proxy = {
+    enable = mkEnableOption "oauth2_proxy";
+
+    package = mkOption {
+      type = types.package;
+      default = pkgs.oauth2_proxy;
+      defaultText = "pkgs.oauth2_proxy";
+      description = ''
+        The package that provides oauth2_proxy.
+      '';
+    };
+
+    ##############################################
+    # PROVIDER configuration
+    provider = mkOption {
+      type = types.enum [
+        "google"
+        "github"
+        "azure"
+        "gitlab"
+        "linkedin"
+        "myusa"
+      ];
+      default = "google";
+      description = ''
+        OAuth provider.
+      '';
+    };
+
+    approvalPrompt = mkOption {
+      type = types.enum ["force" "auto"];
+      default = "force";
+      description = ''
+        OAuth approval_prompt.
+      '';
+    };
+
+    clientID = mkOption {
+      type = types.str;
+      description = ''
+        The OAuth Client ID.
+      '';
+      example = "123456.apps.googleusercontent.com";
+    };
+
+    clientSecret = mkOption {
+      type = types.str;
+      description = ''
+        The OAuth Client Secret.
+      '';
+    };
+
+    skipAuthRegexes = mkOption {
+     type = types.listOf types.str;
+     default = [];
+     description = ''
+       Skip authentication for requests matching any of these regular
+       expressions.
+     '';
+    };
+
+    # XXX: Not clear whether these two options are mutually exclusive or not.
+    email = {
+      domains = mkOption {
+        type = types.listOf types.str;
+        default = [];
+        description = ''
+          Authenticate emails with the specified domains. Use
+          <literal>*</literal> to authenticate any email.
+        '';
+      };
+
+      addresses = mkOption {
+        type = types.nullOr types.lines;
+        default = null;
+        description = ''
+          Line-separated email addresses that are allowed to authenticate.
+        '';
+      };
+    };
+
+    loginURL = mkOption {
+      type = types.nullOr types.str;
+      default = null;
+      description = ''
+        Authentication endpoint.
+
+        You only need to set this if you are using a self-hosted provider (e.g.
+        Github Enterprise). If you're using a publicly hosted provider
+        (e.g github.com), then the default works.
+      '';
+      example = "https://provider.example.com/oauth/authorize";
+    };
+
+    redeemURL = mkOption {
+      type = types.nullOr types.str;
+      default = null;
+      description = ''
+        Token redemption endpoint.
+
+        You only need to set this if you are using a self-hosted provider (e.g.
+        Github Enterprise). If you're using a publicly hosted provider
+        (e.g github.com), then the default works.
+      '';
+      example = "https://provider.example.com/oauth/token";
+    };
+
+    validateURL = mkOption {
+      type = types.nullOr types.str;
+      default = null;
+      description = ''
+        Access token validation endpoint.
+
+        You only need to set this if you are using a self-hosted provider (e.g.
+        Github Enterprise). If you're using a publicly hosted provider
+        (e.g github.com), then the default works.
+      '';
+      example = "https://provider.example.com/user/emails";
+    };
+
+    redirectURL = mkOption {
+      # XXX: jml suspects this is always necessary, but the command-line
+      # doesn't require it so making it optional.
+      type = types.nullOr types.str;
+      default = null;
+      description = ''
+        The OAuth2 redirect URL.
+      '';
+      example = "https://internalapp.yourcompany.com/oauth2/callback";
+    };
+
+    azure = {
+      tenant = mkOption {
+        type = types.str;
+        default = "common";
+        description = ''
+          Go to a tenant-specific or common (tenant-independent) endpoint.
+        '';
+      };
+
+      resource = mkOption {
+        type = types.str;
+        description = ''
+          The resource that is protected.
+        '';
+      };
+    };
+
+    google = {
+      adminEmail = mkOption {
+        type = types.str;
+        description = ''
+          The Google Admin to impersonate for API calls.
+
+          Only users with access to the Admin APIs can access the Admin SDK
+          Directory API, thus the service account needs to impersonate one of
+          those users to access the Admin SDK Directory API.
+
+          See <link xlink:href="https://developers.google.com/admin-sdk/directory/v1/guides/delegation#delegate_domain-wide_authority_to_your_service_account" />.
+        '';
+      };
+
+      groups = mkOption {
+        type = types.listOf types.str;
+        default = [];
+        description = ''
+          Restrict logins to members of these Google groups.
+        '';
+      };
+
+      serviceAccountJSON = mkOption {
+        type = types.path;
+        description = ''
+          The path to the service account JSON credentials.
+        '';
+      };
+    };
+
+    github = {
+      org = mkOption {
+        type = types.nullOr types.str;
+        default = null;
+        description = ''
+          Restrict logins to members of this organisation.
+        '';
+      };
+
+      team = mkOption {
+        type = types.nullOr types.str;
+        default = null;
+        description = ''
+          Restrict logins to members of this team.
+        '';
+      };
+    };
+
+
+    ####################################################
+    # UPSTREAM Configuration
+    upstream = mkOption {
+      type = types.commas;
+      description = ''
+        The http url(s) of the upstream endpoint or <literal>file://</literal>
+        paths for static files. Routing is based on the path.
+      '';
+    };
+
+    passAccessToken = mkOption {
+      type = types.bool;
+      default = false;
+      description = ''
+        Pass OAuth access_token to upstream via X-Forwarded-Access-Token header.
+      '';
+    };
+
+    passBasicAuth = mkOption {
+      type = types.bool;
+      default = true;
+      description = ''
+        Pass HTTP Basic Auth, X-Forwarded-User and X-Forwarded-Email information to upstream.
+      '';
+    };
+
+    basicAuthPassword = mkOption {
+      type = types.nullOr types.str;
+      default = null;
+      description = ''
+        The password to set when passing the HTTP Basic Auth header.
+      '';
+    };
+
+    passHostHeader = mkOption {
+      type = types.bool;
+      default = true;
+      description = ''
+        Pass the request Host Header to upstream.
+      '';
+    };
+
+    signatureKey = mkOption {
+      type = types.nullOr types.str;
+      default = null;
+      description = ''
+        GAP-Signature request signature key.
+      '';
+      example = "sha1:secret0";
+    };
+
+    cookie = {
+      domain = mkOption {
+        type = types.nullOr types.str;
+        default = null;
+        description = ''
+          An optional cookie domain to force cookies to.
+        '';
+        example = ".yourcompany.com";
+      };
+
+      expire = mkOption {
+        type = types.str;
+        default = "168h0m0s";
+        description = ''
+          Expire timeframe for cookie.
+        '';
+      };
+
+      httpOnly = mkOption {
+        type = types.bool;
+        default = true;
+        description = ''
+          Set HttpOnly cookie flag.
+        '';
+      };
+
+      name = mkOption {
+        type = types.str;
+        default = "_oauth2_proxy";
+        description = ''
+          The name of the cookie that the oauth_proxy creates.
+        '';
+      };
+
+      refresh = mkOption {
+        # XXX: Unclear what the behavior is when this is not specified.
+        type = types.nullOr types.str;
+        default = null;
+        description = ''
+          Refresh the cookie after this duration; 0 to disable.
+        '';
+        example = "168h0m0s";
+      };
+
+      secret = mkOption {
+        type = types.str;
+        description = ''
+          The seed string for secure cookies.
+        '';
+      };
+
+      secure = mkOption {
+        type = types.bool;
+        default = true;
+        description = ''
+          Set secure (HTTPS) cookie flag.
+        '';
+      };
+    };
+
+    ####################################################
+    # OAUTH2 PROXY configuration
+
+    httpAddress = mkOption {
+      type = types.str;
+      default = "127.0.0.1:4180";
+      description = ''
+        HTTPS listening address.  This module does not expose the port by
+        default. If you want this URL to be accessible to other machines, please
+        add the port to <literal>networking.firewall.allowedTCPPorts</literal>.
+      '';
+    };
+
+    htpasswd = {
+      file = mkOption {
+        type = types.nullOr types.path;
+        default = null;
+        description = ''
+          Additionally authenticate against a htpasswd file. Entries must be
+          created with <literal>htpasswd -s</literal> for SHA encryption.
+        '';
+      };
+
+      displayForm = mkOption {
+        type = types.bool;
+        default = true;
+        description = ''
+          Display username / password login form if an htpasswd file is provided.
+        '';
+      };
+    };
+
+    customTemplatesDir = mkOption {
+      type = types.nullOr types.path;
+      default = null;
+      description = ''
+        Path to custom HTML templates.
+      '';
+    };
+
+    proxyPrefix = mkOption {
+      type = types.str;
+      default = "/oauth2";
+      description = ''
+        The url root path that this proxy should be nested under.
+      '';
+    };
+
+    tls = {
+      enable = mkOption {
+        type = types.bool;
+        default = false;
+        description = ''
+          Whether to serve over TLS.
+        '';
+      };
+
+      certificate = mkOption {
+        type = types.path;
+        description = ''
+          Path to certificate file.
+        '';
+      };
+
+      key = mkOption {
+        type = types.path;
+        description = ''
+          Path to private key file.
+        '';
+      };
+
+      httpsAddress = mkOption {
+        type = types.str;
+        default = ":443";
+        description = ''
+          <literal>addr:port</literal> to listen on for HTTPS clients.
+
+          Remember to add <literal>port</literal> to
+          <literal>allowedTCPPorts</literal> if you want other machines to be
+          able to connect to it.
+        '';
+      };
+    };
+
+    requestLogging = mkOption {
+      type = types.bool;
+      default = true;
+      description = ''
+        Log requests to stdout.
+      '';
+    };
+
+    ####################################################
+    # UNKNOWN
+
+    # XXX: Is this mandatory? Is it part of another group? Is it part of the provider specification?
+    scope = mkOption {
+      # XXX: jml suspects this is always necessary, but the command-line
+      # doesn't require it so making it optional.
+      type = types.nullOr types.str;
+      default = null;
+      description = ''
+        OAuth scope specification.
+      '';
+    };
+
+    profileURL = mkOption {
+      type = types.nullOr types.str;
+      default = null;
+      description = ''
+      	Profile access endpoint.
+      '';
+    };
+
+  };
+
+  config = mkIf cfg.enable {
+
+    users.extraUsers.oauth2_proxy = {
+      description = "OAuth2 Proxy";
+    };
+
+    systemd.services.oauth2_proxy = {
+      description = "OAuth2 Proxy";
+      path = [ cfg.package ];
+      wantedBy = [ "multi-user.target" ];
+      after = [ "network-interfaces.target" ];
+
+      serviceConfig = {
+        User = "oauth2_proxy";
+        Restart = "always";
+        ExecStart = "${cfg.package}/bin/oauth2_proxy ${mkCommandLine cfg}";
+      };
+    };
+
+  };
+}
diff --git a/nixos/modules/services/x11/desktop-managers/gnome3.nix b/nixos/modules/services/x11/desktop-managers/gnome3.nix
index b8d19eb80c85..91601f387cbe 100644
--- a/nixos/modules/services/x11/desktop-managers/gnome3.nix
+++ b/nixos/modules/services/x11/desktop-managers/gnome3.nix
@@ -81,7 +81,6 @@ in {
     };  
 
     environment.gnome3.packageSet = mkOption {
-      type = types.nullOr types.package;
       default = null;
       example = literalExample "pkgs.gnome3_18";
       description = "Which GNOME 3 package set to use.";
diff --git a/nixos/modules/services/x11/desktop-managers/kde5.nix b/nixos/modules/services/x11/desktop-managers/kde5.nix
index 2e9183da970a..060dda1a70a8 100644
--- a/nixos/modules/services/x11/desktop-managers/kde5.nix
+++ b/nixos/modules/services/x11/desktop-managers/kde5.nix
@@ -117,6 +117,9 @@ in
       # Install activity manager if available
       ++ lib.optional (lib.hasAttr "kactivitymanagerd" kde5) kde5.kactivitymanagerd
 
+      # frameworkintegration was split with plasma-integration in Plasma 5.6
+      ++ lib.optional (lib.hasAttr "plasma-integration" kde5) kde5.plasma-integration
+
       # Optional hardware support features
       ++ lib.optional config.hardware.bluetooth.enable kde5.bluedevil
       ++ lib.optional config.networking.networkmanager.enable kde5.plasma-nm
@@ -167,7 +170,9 @@ in
     services.xserver.displayManager.sddm = {
       theme = "breeze";
       themes = [
+        kde5.extra-cmake-modules # for the setup-hook
         kde5.plasma-workspace
+        kde5.breeze-icons
         (kde5.oxygen-icons or kde5.oxygen-icons5)
       ];
     };
diff --git a/nixos/modules/services/x11/xserver.nix b/nixos/modules/services/x11/xserver.nix
index 82d3e31e2a01..35816c3a16dd 100644
--- a/nixos/modules/services/x11/xserver.nix
+++ b/nixos/modules/services/x11/xserver.nix
@@ -463,7 +463,14 @@ in
           { source = "${cfg.xkbDir}";
             target = "X11/xkb";
           }
-        ]);
+        ])
+      # Needed since 1.18; see https://bugs.freedesktop.org/show_bug.cgi?id=89023#c5
+      ++ (let cfgPath = "/X11/xorg.conf.d/10-evdev.conf"; in
+        [{
+          source = xorg.xf86inputevdev.out + "/share" + cfgPath;
+          target = cfgPath;
+        }]
+      );
 
     environment.systemPackages =
       [ xorg.xorgserver.out
@@ -479,6 +486,7 @@ in
         xorg.xauth
         pkgs.xterm
         pkgs.xdg_utils
+        xorg.xf86inputevdev.out # get evdev.4 man page
       ]
       ++ optional (elem "virtualbox" cfg.videoDrivers) xorg.xrefresh;
 
@@ -538,7 +546,7 @@ in
     services.xserver.modules =
       concatLists (catAttrs "modules" cfg.drivers) ++
       [ xorg.xorgserver.out
-        xorg.xf86inputevdev
+        xorg.xf86inputevdev.out
       ];
 
     services.xserver.xkbDir = mkDefault "${pkgs.xkeyboard_config}/etc/X11/xkb";
diff --git a/nixos/modules/system/boot/loader/efi.nix b/nixos/modules/system/boot/loader/efi.nix
index 726634e664d7..6043c904c450 100644
--- a/nixos/modules/system/boot/loader/efi.nix
+++ b/nixos/modules/system/boot/loader/efi.nix
@@ -4,19 +4,16 @@ with lib;
 
 {
   options.boot.loader.efi = {
+
     canTouchEfiVariables = mkOption {
       default = false;
-
       type = types.bool;
-
-      description = "Whether or not the installation process should modify efi boot variables.";
+      description = "Whether the installation process is allowed to modify EFI boot variables.";
     };
 
     efiSysMountPoint = mkOption {
       default = "/boot";
-
       type = types.str;
-
       description = "Where the EFI System Partition is mounted.";
     };
   };
diff --git a/nixos/modules/system/boot/loader/grub/grub.nix b/nixos/modules/system/boot/loader/grub/grub.nix
index cf1a32bb1ef4..ab32e112936c 100644
--- a/nixos/modules/system/boot/loader/grub/grub.nix
+++ b/nixos/modules/system/boot/loader/grub/grub.nix
@@ -488,7 +488,7 @@ in
         }
         {
           assertion = if args.efiSysMountPoint == null then true else hasPrefix "/" args.efiSysMountPoint;
-          message = "Efi paths must be absolute, not ${args.efiSysMountPoint}";
+          message = "EFI paths must be absolute, not ${args.efiSysMountPoint}";
         }
       ] ++ flip map args.devices (device: {
         assertion = device == "nodev" || hasPrefix "/" device;
diff --git a/nixos/modules/system/boot/loader/gummiboot/gummiboot-builder.py b/nixos/modules/system/boot/loader/systemd-boot/systemd-boot-builder.py
index ef431a7732e1..c38af1b67f17 100644
--- a/nixos/modules/system/boot/loader/gummiboot/gummiboot-builder.py
+++ b/nixos/modules/system/boot/loader/systemd-boot/systemd-boot-builder.py
@@ -88,16 +88,16 @@ def remove_old_entries(gens):
         if not path in known_paths:
             os.unlink(path)
 
-parser = argparse.ArgumentParser(description='Update NixOS-related gummiboot files')
+parser = argparse.ArgumentParser(description='Update NixOS-related systemd-boot files')
 parser.add_argument('default_config', metavar='DEFAULT-CONFIG', help='The default NixOS config to boot')
 args = parser.parse_args()
 
 # We deserve our own env var!
 if os.getenv("NIXOS_INSTALL_GRUB") == "1":
     if "@canTouchEfiVariables@" == "1":
-        subprocess.check_call(["@gummiboot@/bin/gummiboot", "--path=@efiSysMountPoint@", "install"])
+        subprocess.check_call(["@systemd@/bin/bootctl", "--path=@efiSysMountPoint@", "install"])
     else:
-        subprocess.check_call(["@gummiboot@/bin/gummiboot", "--path=@efiSysMountPoint@", "--no-variables", "install"])
+        subprocess.check_call(["@systemd@/bin/bootctl", "--path=@efiSysMountPoint@", "--no-variables", "install"])
 
 mkdir_p("@efiSysMountPoint@/efi/nixos")
 mkdir_p("@efiSysMountPoint@/loader/entries")
diff --git a/nixos/modules/system/boot/loader/gummiboot/gummiboot.nix b/nixos/modules/system/boot/loader/systemd-boot/systemd-boot.nix
index aec697da4a1a..a778a4f539c9 100644
--- a/nixos/modules/system/boot/loader/gummiboot/gummiboot.nix
+++ b/nixos/modules/system/boot/loader/systemd-boot/systemd-boot.nix
@@ -3,16 +3,18 @@
 with lib;
 
 let
-  cfg = config.boot.loader.gummiboot;
+  cfg = config.boot.loader.systemd-boot;
 
   efi = config.boot.loader.efi;
 
   gummibootBuilder = pkgs.substituteAll {
-    src = ./gummiboot-builder.py;
+    src = ./systemd-boot-builder.py;
 
     isExecutable = true;
 
-    inherit (pkgs) python gummiboot;
+    inherit (pkgs) python;
+
+    systemd = config.systemd.package;
 
     nix = config.nix.package.out;
 
@@ -21,13 +23,18 @@ let
     inherit (efi) efiSysMountPoint canTouchEfiVariables;
   };
 in {
-  options.boot.loader.gummiboot = {
+
+  imports =
+    [ (mkRenamedOptionModule [ "boot" "loader" "gummiboot" "enable" ] [ "boot" "loader" "systemd-boot" "enable" ])
+    ];
+
+  options.boot.loader.systemd-boot = {
     enable = mkOption {
       default = false;
 
       type = types.bool;
 
-      description = "Whether to enable the gummiboot UEFI boot manager";
+      description = "Whether to enable the systemd-boot (formerly gummiboot) EFI boot manager";
     };
   };
 
@@ -45,7 +52,7 @@ in {
     system = {
       build.installBootLoader = gummibootBuilder;
 
-      boot.loader.id = "gummiboot";
+      boot.loader.id = "systemd-boot";
 
       requiredKernelConfig = with config.lib.kernelConfig; [
         (isYes "EFI_STUB")
diff --git a/nixos/modules/system/boot/stage-2-init.sh b/nixos/modules/system/boot/stage-2-init.sh
index 1b5b22c2005a..4a7f073ea8ad 100644
--- a/nixos/modules/system/boot/stage-2-init.sh
+++ b/nixos/modules/system/boot/stage-2-init.sh
@@ -41,6 +41,8 @@ if [ ! -e /proc/1 ]; then
     mount -n -t proc proc /proc
     mkdir -m 0755 -p /dev
     mount -t devtmpfs devtmpfs /dev
+    mkdir -m 0755 -p /sys
+    mount -t sysfs sysfs /sys
 fi
 
 
diff --git a/nixos/modules/virtualisation/virtualbox-guest.nix b/nixos/modules/virtualisation/virtualbox-guest.nix
index 3a10871ce840..59bac24a7537 100644
--- a/nixos/modules/virtualisation/virtualbox-guest.nix
+++ b/nixos/modules/virtualisation/virtualbox-guest.nix
@@ -77,7 +77,7 @@ in
         KERNEL=="vboxuser",  OWNER="root", GROUP="root", MODE="0666"
 
         # Allow systemd dependencies on vboxguest.
-        KERNEL=="vboxguest", TAG+="systemd"
+        SUBSYSTEM=="misc", KERNEL=="vboxguest", TAG+="systemd"
       '';
   };
 
diff --git a/nixos/tests/gnome3_20-gdm.nix b/nixos/tests/gnome3_20-gdm.nix
new file mode 100644
index 000000000000..8b1e9afedfb9
--- /dev/null
+++ b/nixos/tests/gnome3_20-gdm.nix
@@ -0,0 +1,41 @@
+import ./make-test.nix ({ pkgs, ...} : {
+  name = "gnome3-gdm";
+  meta = with pkgs.stdenv.lib.maintainers; {
+    maintainers = [ lethalman ];
+  };
+
+  machine =
+    { config, pkgs, ... }:
+
+    { imports = [ ./common/user-account.nix ];
+
+      services.xserver.enable = true;
+
+      services.xserver.displayManager.gdm = {
+        enable = true;
+        autoLogin = {
+          enable = true;
+          user = "alice";
+        };
+      };
+      services.xserver.desktopManager.gnome3.enable = true;
+      environment.gnome3.packageSet = pkgs.gnome3_20;
+
+      virtualisation.memorySize = 512;
+    };
+
+  testScript =
+    ''
+      $machine->waitForX;
+      $machine->sleep(15);
+
+      # Check that logging in has given the user ownership of devices.
+      $machine->succeed("getfacl /dev/snd/timer | grep -q alice");
+
+      $machine->succeed("su - alice -c 'DISPLAY=:0.0 gnome-terminal &'");
+      $machine->succeed("xauth merge ~alice/.Xauthority");
+      $machine->waitForWindow(qr/Terminal/);
+      $machine->sleep(20);
+      $machine->screenshot("screen");
+    '';
+})
diff --git a/nixos/tests/gnome3_20.nix b/nixos/tests/gnome3_20.nix
new file mode 100644
index 000000000000..51c83a4e3129
--- /dev/null
+++ b/nixos/tests/gnome3_20.nix
@@ -0,0 +1,38 @@
+import ./make-test.nix ({ pkgs, ...} : {
+  name = "gnome3";
+  meta = with pkgs.stdenv.lib.maintainers; {
+    maintainers = [ domenkozar eelco chaoflow lethalman ];
+  };
+
+  machine =
+    { config, pkgs, ... }:
+
+    { imports = [ ./common/user-account.nix ];
+
+      services.xserver.enable = true;
+
+      services.xserver.displayManager.auto.enable = true;
+      services.xserver.displayManager.auto.user = "alice";
+      services.xserver.desktopManager.gnome3.enable = true;
+
+      environment.gnome3.packageSet = pkgs.gnome3_20;
+
+      virtualisation.memorySize = 512;
+    };
+
+  testScript =
+    ''
+      $machine->waitForX;
+      $machine->sleep(15);
+
+      # Check that logging in has given the user ownership of devices.
+      $machine->succeed("getfacl /dev/snd/timer | grep -q alice");
+
+      $machine->succeed("su - alice -c 'DISPLAY=:0.0 gnome-terminal &'");
+      $machine->succeed("xauth merge ~alice/.Xauthority");
+      $machine->waitForWindow(qr/Terminal/);
+      $machine->mustSucceed("timeout 900 bash -c 'journalctl -f|grep -m 1 \"GNOME Shell started\"'");
+      $machine->sleep(10);
+      $machine->screenshot("screen");
+    '';
+})
diff --git a/nixos/tests/installer.nix b/nixos/tests/installer.nix
index 3fdf6510953e..4a30cc18b021 100644
--- a/nixos/tests/installer.nix
+++ b/nixos/tests/installer.nix
@@ -30,8 +30,8 @@ let
           boot.loader.grub.configurationLimit = 100 + ${toString forceGrubReinstallCount};
         ''}
 
-        ${optionalString (bootLoader == "gummiboot") ''
-          boot.loader.gummiboot.enable = true;
+        ${optionalString (bootLoader == "systemd-boot") ''
+          boot.loader.systemd-boot.enable = true;
         ''}
 
         hardware.enableAllFirmware = lib.mkForce false;
@@ -57,7 +57,7 @@ let
         (if system == "x86_64-linux" then "-m 768 " else "-m 512 ") +
         (optionalString (system == "x86_64-linux") "-cpu kvm64 ");
       hdFlags = ''hda => "vm-state-machine/machine.qcow2", hdaInterface => "${iface}", ''
-        + optionalString (bootLoader == "gummiboot") ''bios => "${pkgs.OVMF}/FV/OVMF.fd", '';
+        + optionalString (bootLoader == "systemd-boot") ''bios => "${pkgs.OVMF}/FV/OVMF.fd", '';
     in
     ''
       $machine->start;
@@ -159,7 +159,7 @@ let
 
   makeInstallerTest = name:
     { createPartitions, preBootCommands ? "", extraConfig ? ""
-    , bootLoader ? "grub" # either "grub" or "gummiboot"
+    , bootLoader ? "grub" # either "grub" or "systemd-boot"
     , grubVersion ? 2, grubDevice ? "/dev/vda", grubIdentifier ? "uuid"
     , enableOCR ? false, meta ? {}
     }:
@@ -195,7 +195,7 @@ let
             virtualisation.qemu.diskInterface =
               if grubVersion == 1 then "scsi" else "virtio";
 
-            boot.loader.gummiboot.enable = mkIf (bootLoader == "gummiboot") true;
+            boot.loader.systemd-boot.enable = mkIf (bootLoader == "systemd-boot") true;
 
             hardware.enableAllFirmware = mkForce false;
 
@@ -208,7 +208,6 @@ let
                 pkgs.unionfs-fuse
                 pkgs.ntp
                 pkgs.nixos-artwork
-                pkgs.gummiboot
                 pkgs.perlPackages.XMLLibXML
                 pkgs.perlPackages.ListCompare
               ]
@@ -250,7 +249,7 @@ in {
         '';
     };
 
-  # Simple GPT/UEFI configuration using Gummiboot with 3 partitions: ESP, swap & root filesystem
+  # Simple GPT/UEFI configuration using systemd-boot with 3 partitions: ESP, swap & root filesystem
   simpleUefiGummiboot = makeInstallerTest "simpleUefiGummiboot"
     { createPartitions =
         ''
@@ -270,7 +269,7 @@ in {
               "mount LABEL=BOOT /mnt/boot",
           );
         '';
-        bootLoader = "gummiboot";
+        bootLoader = "systemd-boot";
     };
 
   # Same as the previous, but now with a separate /boot partition.
diff --git a/nixos/tests/sddm-kde5.nix b/nixos/tests/sddm-kde5.nix
index f97a6d12b63c..0247d267aaa4 100644
--- a/nixos/tests/sddm-kde5.nix
+++ b/nixos/tests/sddm-kde5.nix
@@ -1,4 +1,6 @@
-import ./make-test.nix ({ pkgs, ...} : {
+import ./make-test.nix ({ pkgs, ...} :
+
+{
   name = "sddm";
   meta = with pkgs.stdenv.lib.maintainers; {
     maintainers = [ ttuegel ];
@@ -6,6 +8,7 @@ import ./make-test.nix ({ pkgs, ...} : {
 
   machine = { lib, ... }: {
     imports = [ ./common/user-account.nix ];
+    virtualisation.memorySize = 1024;
     services.xserver.enable = true;
     services.xserver.displayManager.sddm = {
       enable = true;
@@ -14,18 +17,38 @@ import ./make-test.nix ({ pkgs, ...} : {
         user = "alice";
       };
     };
-    services.xserver.windowManager.default = "icewm";
-    services.xserver.windowManager.icewm.enable = true;
-    services.xserver.desktopManager.default = "none";
     services.xserver.desktopManager.kde5.enable = true;
   };
 
   enableOCR = true;
 
-  testScript = { nodes, ... }: ''
-    startAll;
-    $machine->waitForFile("/home/alice/.Xauthority");
-    $machine->succeed("xauth merge ~alice/.Xauthority");
-    $machine->waitForWindow("^IceWM ");
+  testScript = { nodes, ... }:
+  let xdo = "${pkgs.xdotool}/bin/xdotool"; in
+   ''     
+    sub krunner {
+      my ($win,) = @_;
+      $machine->execute("${xdo} key Alt+F2 sleep 1 type $win");
+      $machine->execute("${xdo} search --sync --onlyvisible --class krunner sleep 5 key Return");
+    }
+
+    $machine->waitUntilSucceeds("pgrep plasmashell");
+    $machine->succeed("xauth merge ~alice/.Xauthority");    
+    $machine->waitForWindow(qr/Desktop.*/);
+
+    # Check that logging in has given the user ownership of devices.
+    $machine->succeed("getfacl /dev/snd/timer | grep -q alice");
+    
+    krunner("dolphin");
+    $machine->waitForWindow(qr/.*Dolphin/);
+    
+    krunner("konsole");
+    $machine->waitForWindow(qr/.*Konsole/);
+    
+    krunner("systemsettings5");
+    $machine->waitForWindow(qr/.*Settings/);
+    $machine->sleep(20);
+
+    $machine->execute("${xdo} key Alt+F1 sleep 10");
+    $machine->screenshot("screen");
   '';
 })