diff options
Diffstat (limited to 'nixos')
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)/ <!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"); ''; }) |