diff options
Diffstat (limited to 'nixos')
161 files changed, 3054 insertions, 1283 deletions
diff --git a/nixos/default.nix b/nixos/default.nix index 5f3e2ae081cc..0e45a1cd75e2 100644 --- a/nixos/default.nix +++ b/nixos/default.nix @@ -37,7 +37,4 @@ in vm = vmConfig.system.build.vm; vmWithBootLoader = vmWithBootLoaderConfig.system.build.vm; - - # The following are used by nixos-rebuild. - nixFallback = pkgs.nixUnstable.out; } diff --git a/nixos/doc/manual/configuration/modularity.xml b/nixos/doc/manual/configuration/modularity.xml index 30da064ac579..5420c7f88385 100644 --- a/nixos/doc/manual/configuration/modularity.xml +++ b/nixos/doc/manual/configuration/modularity.xml @@ -37,7 +37,7 @@ latter might look like this: { services.xserver.enable = true; services.xserver.displayManager.sddm.enable = true; - services.xserver.desktopManager.kde5.enable = true; + services.xserver.desktopManager.plasma5.enable = true; } </programlisting> diff --git a/nixos/doc/manual/configuration/network-manager.xml b/nixos/doc/manual/configuration/network-manager.xml index dafbcfcb1e5b..b4808e74ff9d 100644 --- a/nixos/doc/manual/configuration/network-manager.xml +++ b/nixos/doc/manual/configuration/network-manager.xml @@ -27,7 +27,11 @@ users.extraUsers.youruser.extraGroups = [ "networkmanager" ]; <para>NetworkManager is controlled using either <command>nmcli</command> or <command>nmtui</command> (curses-based terminal user interface). See their manual pages for details on their usage. Some desktop environments (GNOME, KDE) -have their own configuration tools for NetworkManager.</para> +have their own configuration tools for NetworkManager. On XFCE, there is no +configuration tool for NetworkManager by default: by adding +<code>networkmanagerapplet</code> to the list of system packages, the graphical +applet will be installed and will launch automatically when XFCE is starting +(and will show in the status tray).</para> <note><para><code>networking.networkmanager</code> and <code>networking.wireless</code> (WPA Supplicant) cannot be enabled at the same diff --git a/nixos/doc/manual/configuration/x-windows.xml b/nixos/doc/manual/configuration/x-windows.xml index 93d10d19b208..4a73695e0942 100644 --- a/nixos/doc/manual/configuration/x-windows.xml +++ b/nixos/doc/manual/configuration/x-windows.xml @@ -25,19 +25,23 @@ Otherwise, you can only log into a plain undecorated <command>xterm</command> window. Thus you should pick one or more of the following lines: <programlisting> -services.xserver.desktopManager.kde5.enable = true; +services.xserver.desktopManager.plasma5.enable = true; services.xserver.desktopManager.xfce.enable = true; +services.xserver.desktopManager.gnome3.enable = true; services.xserver.windowManager.xmonad.enable = true; services.xserver.windowManager.twm.enable = true; services.xserver.windowManager.icewm.enable = true; +services.xserver.windowManager.i3.enable = true; </programlisting> </para> <para>NixOS’s default <emphasis>display manager</emphasis> (the program that provides a graphical login prompt and manages the X -server) is SLiM. You can select KDE’s <command>sddm</command> instead: +server) is SLiM. You can select an alternative one by picking one +of the following lines: <programlisting> services.xserver.displayManager.sddm.enable = true; +services.xserver.displayManager.lightdm.enable = true; </programlisting> </para> diff --git a/nixos/doc/manual/configuration/xfce.xml b/nixos/doc/manual/configuration/xfce.xml index af6278e9c920..21c7a85e19cc 100644 --- a/nixos/doc/manual/configuration/xfce.xml +++ b/nixos/doc/manual/configuration/xfce.xml @@ -9,10 +9,10 @@ <para> To enable the Xfce Desktop Environment, set <programlisting> - services.xserver.desktopManager = { - xfce.enable = true; - default = "xfce"; - }; +services.xserver.desktopManager = { + xfce.enable = true; + default = "xfce"; +}; </programlisting> </para> @@ -20,13 +20,13 @@ Optionally, <emphasis>compton</emphasis> can be enabled for nice graphical effects, some example settings: <programlisting> - services.compton = { - enable = true; - fade = true; - inactiveOpacity = "0.9"; - shadow = true; - fadeDelta = 4; - }; +services.compton = { + enable = true; + fade = true; + inactiveOpacity = "0.9"; + shadow = true; + fadeDelta = 4; +}; </programlisting> </para> @@ -34,16 +34,16 @@ Some Xfce programs are not installed automatically. To install them manually (system wide), put them into your <literal>environment.systemPackages</literal>. - </para> + </para> <para> - NixOS’s default <emphasis>display manager</emphasis>is SLiM. - (DM is the program that provides a graphical login prompt - and manages the X server.) - You can, for example, select KDE’s + NixOS’s default <emphasis>display manager</emphasis> is SLiM. + (DM is the program that provides a graphical login prompt + and manages the X server.) + You can, for example, select KDE’s <command>sddm</command> instead: <programlisting> - services.xserver.displayManager.sddm.enable = true; +services.xserver.displayManager.sddm.enable = true; </programlisting> </para> @@ -55,7 +55,7 @@ <emphasis>Thunar</emphasis> volume support, put <programlisting> - services.xserver.desktopManager.xfce.enable = true; +services.xserver.desktopManager.xfce.enable = true; </programlisting> into your <emphasis>configuration.nix</emphasis>. </para> @@ -84,10 +84,10 @@ Thunar and/or the desktop takes time to show up. Thunar will spit out this kind of message on start - (look at journalctl --user -b). + (look at <command>journalctl --user -b</command>). <programlisting> - Thunar:2410): GVFS-RemoteVolumeMonitor-WARNING **: remote volume monitor with dbus name org.gtk.Private.UDisks2VolumeMonitor is not supported +Thunar:2410): GVFS-RemoteVolumeMonitor-WARNING **: remote volume monitor with dbus name org.gtk.Private.UDisks2VolumeMonitor is not supported </programlisting> This is caused by some needed GNOME services not running. @@ -95,7 +95,7 @@ the Advanced tab of the Session and Startup settings panel. Alternatively, you can run this command to do the same thing. <programlisting> - $ xfconf-query -c xfce4-session -p /compat/LaunchGNOME -s true +$ xfconf-query -c xfce4-session -p /compat/LaunchGNOME -s true </programlisting> A log-out and re-log will be needed for this to take effect. </para> diff --git a/nixos/doc/manual/development/replace-modules.xml b/nixos/doc/manual/development/replace-modules.xml new file mode 100644 index 000000000000..cc0539ec5109 --- /dev/null +++ b/nixos/doc/manual/development/replace-modules.xml @@ -0,0 +1,75 @@ +<section xmlns="http://docbook.org/ns/docbook" + xmlns:xlink="http://www.w3.org/1999/xlink" + xmlns:xi="http://www.w3.org/2001/XInclude" + version="5.0" + xml:id="sec-replace-modules"> + +<title>Replace Modules</title> + +<para>Modules that are imported can also be disabled. The option + declarations and config implementation of a disabled module will be + ignored, allowing another to take it's place. This can be used to + import a set of modules from another channel while keeping the rest + of the system on a stable release.</para> +<para><literal>disabledModules</literal> is a top level attribute like + <literal>imports</literal>, <literal>options</literal> and + <literal>config</literal>. It contains a list of modules that will + be disabled. This can either be the full path to the module or a + string with the filename relative to the modules path + (eg. <nixpkgs/nixos/modules> for nixos). + </para> + +<para>This example will replace the existing postgresql module with + the version defined in the nixos-unstable channel while keeping the + rest of the modules and packages from the original nixos channel. + This only overrides the module definition, this won't use postgresql + from nixos-unstable unless explicitly configured to do so.</para> + +<programlisting> +{ config, lib, pkgs, ... }: + +{ + disabledModules = [ "services/databases/postgresql.nix" ]; + + imports = + [ # Use postgresql service from nixos-unstable channel. + # sudo nix-channel --add http://nixos.org/channels/nixos-unstable nixos-unstable + <nixos-unstable/nixos/modules/services/databases/postgresql.nix> + ]; + + services.postgresql.enable = true; +} +</programlisting> + +<para>This example shows how to define a custom module as a + replacement for an existing module. Importing this module will + disable the original module without having to know it's + implementation details.</para> + +<programlisting> +{ config, lib, pkgs, ... }: + +with lib; + +let + cfg = config.programs.man; +in + +{ + disabledModules = [ "services/programs/man.nix" ]; + + options = { + programs.man.enable = mkOption { + type = types.bool; + default = true; + description = "Whether to enable manual pages."; + }; + }; + + config = mkIf cfg.enabled { + warnings = [ "disabled manpages for production deployments." ]; + }; +} +</programlisting> + +</section> diff --git a/nixos/doc/manual/development/writing-modules.xml b/nixos/doc/manual/development/writing-modules.xml index ef6920160e6d..5bdcad5ceb57 100644 --- a/nixos/doc/manual/development/writing-modules.xml +++ b/nixos/doc/manual/development/writing-modules.xml @@ -179,5 +179,6 @@ in { <xi:include href="option-types.xml" /> <xi:include href="option-def.xml" /> <xi:include href="meta-attributes.xml" /> +<xi:include href="replace-modules.xml" /> </chapter> diff --git a/nixos/doc/manual/installation/changing-config.xml b/nixos/doc/manual/installation/changing-config.xml index 43b591a1cae9..75df307a1b7c 100644 --- a/nixos/doc/manual/installation/changing-config.xml +++ b/nixos/doc/manual/installation/changing-config.xml @@ -7,7 +7,7 @@ <para>The file <filename>/etc/nixos/configuration.nix</filename> contains the current configuration of your machine. Whenever you’ve -changed something to that file, you should do +<link linkend="ch-configuration">changed something</link> in that file, you should do <screen> # nixos-rebuild switch</screen> diff --git a/nixos/doc/manual/release-notes/release-notes.xml b/nixos/doc/manual/release-notes/release-notes.xml index 20d3f74f94b4..6065a86f60d8 100644 --- a/nixos/doc/manual/release-notes/release-notes.xml +++ b/nixos/doc/manual/release-notes/release-notes.xml @@ -9,6 +9,7 @@ <para>This section lists the release notes for each stable version of NixOS and current unstable revision.</para> +<xi:include href="rl-1709.xml" /> <xi:include href="rl-1703.xml" /> <xi:include href="rl-1609.xml" /> <xi:include href="rl-1603.xml" /> diff --git a/nixos/doc/manual/release-notes/rl-1703.xml b/nixos/doc/manual/release-notes/rl-1703.xml index 8f9694bad8bd..fda46217144c 100644 --- a/nixos/doc/manual/release-notes/rl-1703.xml +++ b/nixos/doc/manual/release-notes/rl-1703.xml @@ -30,6 +30,14 @@ has the following highlights: </para> <listitem> <para>PHP now defaults to PHP 7.1</para> </listitem> + + <listitem> + <para>Packages in nixpkgs can be marked as insecure through listed + vulnerabilities. See the <link + xlink:href="https://nixos.org/nixpkgs/manual/#sec-allow-insecure">Nixpkgs + manual</link> for more information.</para> + </listitem> + </itemizedlist> <para>The following new services were added since the last release:</para> @@ -217,6 +225,18 @@ following incompatible changes:</para> </para> </listitem> + <listitem> + <para> + Iputils no longer provide ping6 and traceroute6. The functionality of + these tools have been integrated into ping and traceroute respectively. To + enforce an address family the new flags <literal>-4</literal> and + <literal>-6</literal> have been added. One notable incompatibility is that + specifying an interface (for link-local IPv6 for instance) is no longer done + with the <literal>-I</literal> flag, but by encoding the interface into the + address (<literal>ping fe80::1%eth0</literal>). + </para> + </listitem> + </itemizedlist> @@ -241,6 +261,16 @@ following incompatible changes:</para> </para> </listitem> + <listitem> + <para> + Python 2.7, 3.5 and 3.6 are now built deterministically and 3.4 mostly. + Minor modifications had to be made to the interpreters in order to generate + deterministic bytecode. This has security implications and is relevant for + those using Python in a <literal>nix-shell</literal>. See the Nixpkgs manual + for details. + </para> + </listitem> + </itemizedlist> diff --git a/nixos/doc/manual/release-notes/rl-1709.xml b/nixos/doc/manual/release-notes/rl-1709.xml new file mode 100644 index 000000000000..3705fd468f61 --- /dev/null +++ b/nixos/doc/manual/release-notes/rl-1709.xml @@ -0,0 +1,55 @@ +<section xmlns="http://docbook.org/ns/docbook" + xmlns:xlink="http://www.w3.org/1999/xlink" + xmlns:xi="http://www.w3.org/2001/XInclude" + version="5.0" + xml:id="sec-release-17.09"> + +<title>Release 17.09 (“Hummingbird”, 2017/09/??)</title> + +<para>In addition to numerous new and upgraded packages, this release +has the following highlights: </para> + +<itemizedlist> + <listitem> + <para></para> + </listitem> + +</itemizedlist> + +<para>The following new services were added since the last release:</para> + +<itemizedlist> + <listitem> + <para></para> + </listitem> +</itemizedlist> + + +<para>When upgrading from a previous release, please be aware of the +following incompatible changes:</para> + +<itemizedlist> + <listitem> + <para> + </para> + </listitem> +</itemizedlist> + + +<para>Other notable improvements:</para> + +<itemizedlist> + + <listitem> + <para> + Modules can now be disabled by using <link + xlink:href="https://nixos.org/nixpkgs/manual/#sec-replace-modules"> + disabledModules</link>, allowing another to take it's place. This can be + used to import a set of modules from another channel while keeping the + rest of the system on a stable release. + </para> + </listitem> + +</itemizedlist> + +</section> diff --git a/nixos/lib/make-disk-image.nix b/nixos/lib/make-disk-image.nix index e279803f2ea0..8c5de22f30ff 100644 --- a/nixos/lib/make-disk-image.nix +++ b/nixos/lib/make-disk-image.nix @@ -7,6 +7,12 @@ , # The size of the disk, in megabytes. diskSize + # The files and directories to be placed in the target file system. + # This is a list of attribute sets {source, target} where `source' + # is the file system object (regular file or directory) to be + # grafted in the file system at path `target'. +, contents ? [] + , # Whether the disk should be partitioned (with a single partition # containing the root filesystem) or contain the root filesystem # directly. @@ -45,7 +51,14 @@ pkgs.vmTools.runInLinuxVM ( ${pkgs.vmTools.qemu}/bin/qemu-img create -f ${format} $diskImage "${toString diskSize}M" mv closure xchg/ ''; - buildInputs = [ pkgs.utillinux pkgs.perl pkgs.e2fsprogs pkgs.parted ]; + buildInputs = with pkgs; [ utillinux perl e2fsprogs parted rsync ]; + + # I'm preserving the line below because I'm going to search for it across nixpkgs to consolidate + # image building logic. The comment right below this now appears in 4 different places in nixpkgs :) + # !!! should use XML. + sources = map (x: x.source) contents; + targets = map (x: x.target) contents; + exportReferencesGraph = [ "closure" config.system.build.toplevel ]; inherit postVM; @@ -98,11 +111,45 @@ pkgs.vmTools.runInLinuxVM ( # Remove /etc/machine-id so that each machine cloning this image will get its own id rm -f /mnt/etc/machine-id + # Copy arbitrary other files into the image + # Semi-shamelessly copied from make-etc.sh. I (@copumpkin) shall factor this stuff out as part of + # https://github.com/NixOS/nixpkgs/issues/23052. + set -f + sources_=($sources) + targets_=($targets) + set +f + + for ((i = 0; i < ''${#targets_[@]}; i++)); do + source="''${sources_[$i]}" + target="''${targets_[$i]}" + + if [[ "$source" =~ '*' ]]; then + + # If the source name contains '*', perform globbing. + mkdir -p /mnt/$target + for fn in $source; do + rsync -a --no-o --no-g "$fn" /mnt/$target/ + done + + else + + mkdir -p /mnt/$(dirname $target) + if ! [ -e /mnt/$target ]; then + rsync -a --no-o --no-g $source /mnt/$target + else + echo "duplicate entry $target -> $source" + exit 1 + fi + fi + done + umount /mnt - # Make sure resize2fs works + # Make sure resize2fs works. Note that resize2fs has stricter criteria for resizing than a normal + # mount, so the `-c 0` and `-i 0` don't affect it. Setting it to `now` doesn't produce deterministic + # output, of course, but we can fix that when/if we start making images deterministic. ${optionalString (fsType == "ext4") '' - tune2fs -c 0 -i 0 $rootDisk + tune2fs -T now -c 0 -i 0 $rootDisk ''} '' ) diff --git a/nixos/lib/test-driver/Machine.pm b/nixos/lib/test-driver/Machine.pm index 85bc376f67fa..30664406b26d 100644 --- a/nixos/lib/test-driver/Machine.pm +++ b/nixos/lib/test-driver/Machine.pm @@ -607,7 +607,8 @@ sub waitForWindow { sub copyFileFromHost { my ($self, $from, $to) = @_; my $s = `cat $from` or die; - $self->mustSucceed("echo '$s' > $to"); # !!! escaping + $s =~ s/'/'\\''/g; + $self->mustSucceed("echo '$s' > $to"); } diff --git a/nixos/maintainers/scripts/ec2/amazon-image.nix b/nixos/maintainers/scripts/ec2/amazon-image.nix index bfa4f4b3ca59..b4190df8335b 100644 --- a/nixos/maintainers/scripts/ec2/amazon-image.nix +++ b/nixos/maintainers/scripts/ec2/amazon-image.nix @@ -2,15 +2,34 @@ with lib; -{ +let + cfg = config.amazonImage; +in { imports = [ ../../../modules/installer/cd-dvd/channel.nix ../../../modules/virtualisation/amazon-image.nix ]; - system.build.amazonImage = import ../../../lib/make-disk-image.nix { + options.amazonImage = { + contents = mkOption { + example = literalExample '' + [ { source = pkgs.memtest86 + "/memtest.bin"; + target = "boot/memtest.bin"; + } + ] + ''; + default = []; + description = '' + This option lists files to be copied to fixed locations in the + generated image. Glob patterns work. + ''; + }; + }; + + config.system.build.amazonImage = import ../../../lib/make-disk-image.nix { inherit lib config; + inherit (cfg) contents; pkgs = import ../../../.. { inherit (pkgs) system; }; # ensure we use the regular qemu-kvm package partitioned = config.ec2.hvm; diskSize = if config.ec2.hvm then 2048 else 8192; diff --git a/nixos/maintainers/scripts/ec2/create-amis.sh b/nixos/maintainers/scripts/ec2/create-amis.sh index 7cceac8cbf5a..1e397b0f1761 100755 --- a/nixos/maintainers/scripts/ec2/create-amis.sh +++ b/nixos/maintainers/scripts/ec2/create-amis.sh @@ -19,7 +19,7 @@ rm -f ec2-amis.nix types="hvm pv" stores="ebs s3" -regions="eu-west-1 eu-west-2 eu-central-1 us-east-1 us-east-2 us-west-1 us-west-2 ap-southeast-1 ap-southeast-2 ap-northeast-1 ap-northeast-2 sa-east-1 ap-south-1" +regions="eu-west-1 eu-west-2 eu-central-1 us-east-1 us-east-2 us-west-1 us-west-2 ca-central-1 ap-southeast-1 ap-southeast-2 ap-northeast-1 ap-northeast-2 sa-east-1 ap-south-1" for type in $types; do link=$stateDir/$type diff --git a/nixos/maintainers/scripts/openstack/nova-image.nix b/nixos/maintainers/scripts/openstack/nova-image.nix new file mode 100644 index 000000000000..fa9cfb74bd6c --- /dev/null +++ b/nixos/maintainers/scripts/openstack/nova-image.nix @@ -0,0 +1,24 @@ +{ config, lib, pkgs, ... }: + +with lib; + +{ + imports = + [ ../../../modules/installer/cd-dvd/channel.nix + ../../../modules/virtualisation/nova-config.nix + ]; + + system.build.novaImage = import ../../../lib/make-disk-image.nix { + inherit lib config; + pkgs = import ../../../.. { inherit (pkgs) system; }; # ensure we use the regular qemu-kvm package + diskSize = 8192; + format = "qcow2"; + configFile = pkgs.writeText "configuration.nix" + '' + { + imports = [ <nixpkgs/nixos/modules/virtualisation/nova-config.nix> ]; + } + ''; + }; + +} diff --git a/nixos/modules/config/fonts/fontconfig-ultimate.nix b/nixos/modules/config/fonts/fontconfig-ultimate.nix index a3f52fbd9199..ed6429dda085 100644 --- a/nixos/modules/config/fonts/fontconfig-ultimate.nix +++ b/nixos/modules/config/fonts/fontconfig-ultimate.nix @@ -8,61 +8,6 @@ let fcBool = x: if x then "<bool>true</bool>" else "<bool>false</bool>"; latestVersion = pkgs.fontconfig.configVersion; - # fontconfig ultimate main configuration file - # priority 52 - fontconfigUltimateConf = pkgs.writeText "fc-52-fontconfig-ultimate.conf" '' - <?xml version="1.0"?> - <!DOCTYPE fontconfig SYSTEM "fonts.dtd"> - <fontconfig> - - ${optionalString (!cfg.allowBitmaps) '' - <!-- Reject bitmap fonts --> - <selectfont> - <rejectfont> - <pattern> - <patelt name="scalable"><bool>false</bool></patelt> - </pattern> - </rejectfont> - </selectfont> - ''} - - ${optionalString cfg.allowType1 '' - <!-- Reject Type 1 fonts --> - <selectfont> - <rejectfont> - <pattern> - <patelt name="fontformat"> - <string>Type 1</string> - </patelt> - </pattern> - </rejectfont> - </selectfont> - ''} - - <!-- Use embedded bitmaps in fonts like Calibri? --> - <match target="font"> - <edit name="embeddedbitmap" mode="assign"> - ${fcBool cfg.useEmbeddedBitmaps} - </edit> - </match> - - <!-- Force autohint always --> - <match target="font"> - <edit name="force_autohint" mode="assign"> - ${fcBool cfg.forceAutohint} - </edit> - </match> - - <!-- Render some monospace TTF fonts as bitmaps --> - <match target="pattern"> - <edit name="bitmap_monospace" mode="assign"> - ${fcBool cfg.renderMonoTTFAsBitmap} - </edit> - </match> - - </fontconfig> - ''; - # The configuration to be included in /etc/font/ confPkg = pkgs.runCommand "font-ultimate-conf" {} '' support_folder=$out/etc/fonts/conf.d @@ -71,12 +16,6 @@ let fcBool = x: if x then "<bool>true</bool>" else "<bool>false</bool>"; mkdir -p $support_folder mkdir -p $latest_folder - # 52-fontconfig-ultimate.conf - ln -s ${fontconfigUltimateConf} \ - $support_folder/52-fontconfig-ultimate.conf - ln -s ${fontconfigUltimateConf} \ - $latest_folder/52-fontconfig-ultimate.conf - # fontconfig ultimate substitutions ${optionalString (cfg.substitutions != "none") '' ln -s ${pkgs.fontconfig-ultimate}/etc/fonts/presets/${cfg.substitutions}/*.conf \ @@ -113,45 +52,6 @@ in ''; }; - allowBitmaps = mkOption { - type = types.bool; - default = true; - description = '' - Allow bitmap fonts. Set to <literal>false</literal> to ban all - bitmap fonts. - ''; - }; - - allowType1 = mkOption { - type = types.bool; - default = false; - description = '' - Allow Type-1 fonts. Default is <literal>false</literal> because of - poor rendering. - ''; - }; - - useEmbeddedBitmaps = mkOption { - type = types.bool; - default = false; - description = ''Use embedded bitmaps in fonts like Calibri.''; - }; - - forceAutohint = mkOption { - type = types.bool; - default = false; - description = '' - Force use of the TrueType Autohinter. Useful for debugging or - free-software purists. - ''; - }; - - renderMonoTTFAsBitmap = mkOption { - type = types.bool; - default = false; - description = ''Render some monospace TTF fonts as bitmaps.''; - }; - substitutions = mkOption { type = types.nullOr (types.enum ["free" "combi" "ms"]); default = "free"; diff --git a/nixos/modules/config/fonts/fontconfig.nix b/nixos/modules/config/fonts/fontconfig.nix index 52ad1e714fb9..5648b7b1d027 100644 --- a/nixos/modules/config/fonts/fontconfig.nix +++ b/nixos/modules/config/fonts/fontconfig.nix @@ -41,11 +41,11 @@ let cfg = config.fonts.fontconfig; # priority 0 cacheConfSupport = makeCacheConf { version = supportVersion; }; cacheConfLatest = makeCacheConf {}; - + # generate the font cache setting file for a fontconfig version # use latest when no version is passed makeCacheConf = { version ? null }: - let + let fcPackage = if builtins.isNull version then "fontconfig" else "fontconfig_${version}"; @@ -104,6 +104,13 @@ let cfg = config.fonts.fontconfig; </match> ''} + <!-- Force autohint always --> + <match target="font"> + <edit name="force_autohint" mode="assign"> + ${fcBool cfg.forceAutohint} + </edit> + </match> + </fontconfig> ''; @@ -113,7 +120,7 @@ let cfg = config.fonts.fontconfig; # default fonts configuration file # priority 52 - defaultFontsConf = + defaultFontsConf = let genDefault = fonts: name: optionalString (fonts != []) '' <alias> @@ -142,7 +149,61 @@ let cfg = config.fonts.fontconfig; </fontconfig> ''; - # fontconfig configuration package + # bitmap font options + # priority 53 + rejectBitmaps = pkgs.writeText "fc-53-nixos-bitmaps.conf" '' + <?xml version="1.0"?> + <!DOCTYPE fontconfig SYSTEM "fonts.dtd"> + <fontconfig> + + ${optionalString (!cfg.allowBitmaps) '' + <!-- Reject bitmap fonts --> + <selectfont> + <rejectfont> + <pattern> + <patelt name="scalable"><bool>false</bool></patelt> + </pattern> + </rejectfont> + </selectfont> + ''} + + <!-- Use embedded bitmaps in fonts like Calibri? --> + <match target="font"> + <edit name="embeddedbitmap" mode="assign"> + ${fcBool cfg.useEmbeddedBitmaps} + </edit> + </match> + + <!-- Render some monospace TTF fonts as bitmaps --> + <match target="pattern"> + <edit name="bitmap_monospace" mode="assign"> + ${fcBool cfg.renderMonoTTFAsBitmap} + </edit> + </match> + + </fontconfig> + ''; + + # reject Type 1 fonts + # priority 53 + rejectType1 = pkgs.writeText "fc-53-nixos-reject-type1.conf" '' + <?xml version="1.0"?> + <!DOCTYPE fontconfig SYSTEM "fonts.dtd"> + <fontconfig> + + <!-- Reject Type 1 fonts --> + <selectfont> + <rejectfont> + <pattern> + <patelt name="fontformat"><string>Type 1</string></patelt> + </pattern> + </rejectfont> + </selectfont> + + </fontconfig> + ''; + + # fontconfig configuration package confPkg = pkgs.runCommand "fontconfig-conf" {} '' support_folder=$out/etc/fonts latest_folder=$out/etc/fonts/${latestVersion} @@ -166,7 +227,7 @@ let cfg = config.fonts.fontconfig; substitute ${latestPkg.out}/etc/fonts/conf.d/51-local.conf \ $latest_folder/conf.d/51-local.conf \ - --replace local.conf /etc/fonts/${latestVersion}/local.conf + --replace local.conf /etc/fonts/${latestVersion}/local.conf # 00-nixos-cache.conf ln -s ${cacheConfSupport} \ @@ -192,6 +253,16 @@ let cfg = config.fonts.fontconfig; # 52-nixos-default-fonts.conf ln -s ${defaultFontsConf} $support_folder/conf.d/52-nixos-default-fonts.conf ln -s ${defaultFontsConf} $latest_folder/conf.d/52-nixos-default-fonts.conf + + # 53-nixos-bitmaps.conf + ln -s ${rejectBitmaps} $support_folder/conf.d/53-nixos-bitmaps.conf + ln -s ${rejectBitmaps} $latest_folder/conf.d/53-nixos-bitmaps.conf + + ${optionalString (! cfg.allowType1) '' + # 53-nixos-reject-type1.conf + ln -s ${rejectType1} $support_folder/conf.d/53-nixos-reject-type1.conf + ln -s ${rejectType1} $latest_folder/conf.d/53-nixos-reject-type1.conf + ''} ''; # Package with configuration files @@ -349,6 +420,45 @@ in ''; }; + allowBitmaps = mkOption { + type = types.bool; + default = true; + description = '' + Allow bitmap fonts. Set to <literal>false</literal> to ban all + bitmap fonts. + ''; + }; + + allowType1 = mkOption { + type = types.bool; + default = false; + description = '' + Allow Type-1 fonts. Default is <literal>false</literal> because of + poor rendering. + ''; + }; + + useEmbeddedBitmaps = mkOption { + type = types.bool; + default = false; + description = ''Use embedded bitmaps in fonts like Calibri.''; + }; + + forceAutohint = mkOption { + type = types.bool; + default = false; + description = '' + Force use of the TrueType Autohinter. Useful for debugging or + free-software purists. + ''; + }; + + renderMonoTTFAsBitmap = mkOption { + type = types.bool; + default = false; + description = ''Render some monospace TTF fonts as bitmaps.''; + }; + }; }; diff --git a/nixos/modules/config/networking.nix b/nixos/modules/config/networking.nix index 426aaa34885c..4431dfb40859 100644 --- a/nixos/modules/config/networking.nix +++ b/nixos/modules/config/networking.nix @@ -251,11 +251,6 @@ in # Install the proxy environment variables environment.sessionVariables = cfg.proxy.envVars; - # The ‘ip-up’ target is kept for backwards compatibility. - # New services should use systemd upstream targets: - # See https://www.freedesktop.org/wiki/Software/systemd/NetworkTarget/ - systemd.targets.ip-up.description = "Services Requiring IP Connectivity (deprecated)"; - # This is needed when /etc/resolv.conf is being overriden by networkd # and other configurations. If the file is destroyed by an environment # activation then it must be rebuilt so that applications which interface diff --git a/nixos/modules/config/pulseaudio.nix b/nixos/modules/config/pulseaudio.nix index eee8db376c84..bf66994b5022 100644 --- a/nixos/modules/config/pulseaudio.nix +++ b/nixos/modules/config/pulseaudio.nix @@ -274,6 +274,8 @@ in { RestartSec = "500ms"; }; }; + + environment.variables.PULSE_COOKIE = "${stateDir}/.config/pulse/cookie"; }) ]; diff --git a/nixos/modules/config/update-users-groups.pl b/nixos/modules/config/update-users-groups.pl index cbbe216e5a17..4ca8a83554ad 100644 --- a/nixos/modules/config/update-users-groups.pl +++ b/nixos/modules/config/update-users-groups.pl @@ -177,7 +177,7 @@ foreach my $u (@{$spec->{users}}) { } # Create a home directory. - if ($u->{createHome} && ! -e $u->{home}) { + if ($u->{createHome}) { make_path($u->{home}, { mode => 0700 }) if ! -e $u->{home}; chown $u->{uid}, $u->{gid}, $u->{home}; } diff --git a/nixos/modules/hardware/cpu/amd-microcode.nix b/nixos/modules/hardware/cpu/amd-microcode.nix index d44f01a49590..621c7066bfe1 100644 --- a/nixos/modules/hardware/cpu/amd-microcode.nix +++ b/nixos/modules/hardware/cpu/amd-microcode.nix @@ -22,7 +22,8 @@ with lib; ###### implementation config = mkIf config.hardware.cpu.amd.updateMicrocode { - boot.initrd.prepend = [ "${pkgs.microcodeAmd}/amd-ucode.img" ]; + # Microcode updates must be the first item prepended in the initrd + boot.initrd.prepend = mkOrder 1 [ "${pkgs.microcodeAmd}/amd-ucode.img" ]; }; } diff --git a/nixos/modules/hardware/cpu/intel-microcode.nix b/nixos/modules/hardware/cpu/intel-microcode.nix index 89ae4f45806c..acce565fd808 100644 --- a/nixos/modules/hardware/cpu/intel-microcode.nix +++ b/nixos/modules/hardware/cpu/intel-microcode.nix @@ -22,7 +22,8 @@ with lib; ###### implementation config = mkIf config.hardware.cpu.intel.updateMicrocode { - boot.initrd.prepend = [ "${pkgs.microcodeIntel}/intel-ucode.img" ]; + # Microcode updates must be the first item prepended in the initrd + boot.initrd.prepend = mkOrder 1 [ "${pkgs.microcodeIntel}/intel-ucode.img" ]; }; } diff --git a/nixos/modules/hardware/mcelog.nix b/nixos/modules/hardware/mcelog.nix new file mode 100644 index 000000000000..e4ac7d39053f --- /dev/null +++ b/nixos/modules/hardware/mcelog.nix @@ -0,0 +1,37 @@ +{ config, lib, pkgs, ... }: + +with lib; + +{ + meta.maintainers = [ maintainers.grahamc ]; + options = { + + hardware.mcelog = { + enable = mkOption { + type = types.bool; + default = false; + description = '' + Enable the Machine Check Exception logger. + ''; + }; + }; + + }; + + config = mkIf config.hardware.mcelog.enable { + systemd.services.mcelog = { + description = "Machine Check Exception Logging Daemon"; + wantedBy = [ "multi-user.target" ]; + + serviceConfig = { + ExecStart = "${pkgs.mcelog}/bin/mcelog --daemon --foreground"; + SuccessExitStatus = [ 0 15 ]; + + ProtectHome = true; + PrivateNetwork = true; + PrivateTmp = true; + }; + }; + }; + +} diff --git a/nixos/modules/hardware/sensor/iio.nix b/nixos/modules/hardware/sensor/iio.nix new file mode 100644 index 000000000000..a8bc18800021 --- /dev/null +++ b/nixos/modules/hardware/sensor/iio.nix @@ -0,0 +1,30 @@ +{ config, lib, pkgs, ... }: + +with lib; + +{ + ###### interface + + options = { + hardware.sensor.iio = { + enable = mkOption { + description = "Enable this option to support IIO sensors."; + type = types.bool; + default = false; + }; + }; + }; + + ###### implementation + + config = mkIf config.hardware.sensor.iio.enable { + + boot.initrd.availableKernelModules = [ "hid-sensor-hub" ]; + + environment.systemPackages = with pkgs; [ iio-sensor-proxy ]; + + services.dbus.packages = with pkgs; [ iio-sensor-proxy ]; + services.udev.packages = with pkgs; [ iio-sensor-proxy ]; + systemd.packages = with pkgs; [ iio-sensor-proxy ]; + }; +} diff --git a/nixos/modules/hardware/usb-wwan.nix b/nixos/modules/hardware/usb-wwan.nix new file mode 100644 index 000000000000..2d20421586a7 --- /dev/null +++ b/nixos/modules/hardware/usb-wwan.nix @@ -0,0 +1,26 @@ +{ config, lib, pkgs, ... }: + +with lib; + +{ + ###### interface + + options = { + + hardware.usbWwan = { + enable = mkOption { + type = types.bool; + default = false; + description = '' + Enable this option to support USB WWAN adapters. + ''; + }; + }; + }; + + ###### implementation + + config = mkIf config.hardware.usbWwan.enable { + services.udev.packages = with pkgs; [ usb-modeswitch-data ]; + }; +} diff --git a/nixos/modules/hardware/video/bumblebee.nix b/nixos/modules/hardware/video/bumblebee.nix index 3967137fcf8b..2278c7b40611 100644 --- a/nixos/modules/hardware/video/bumblebee.nix +++ b/nixos/modules/hardware/video/bumblebee.nix @@ -13,7 +13,7 @@ let useDisplayDevice = cfg.connectDisplay; }; - useBbswitch = cfg.pmMethod == "bbswitch"; + useBbswitch = cfg.pmMethod == "bbswitch" || cfg.pmMethod == "auto" && useNvidia; primus = pkgs.primus.override { inherit useNvidia; @@ -65,7 +65,7 @@ in pmMethod = mkOption { default = "auto"; - type = types.enum [ "auto" "bbswitch" "nouveau" "switcheroo" "none" ]; + type = types.enum [ "auto" "bbswitch" "switcheroo" "none" ]; description = '' Set preferred power management method for unused card. ''; diff --git a/nixos/modules/hardware/video/capture/mwprocapture.nix b/nixos/modules/hardware/video/capture/mwprocapture.nix new file mode 100644 index 000000000000..aee15dcec6e5 --- /dev/null +++ b/nixos/modules/hardware/video/capture/mwprocapture.nix @@ -0,0 +1,61 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + + cfg = config.hardware.mwProCapture; + + kernelPackages = config.boot.kernelPackages; + +in + +{ + + options.hardware.mwProCapture.enable = mkEnableOption "Magewell Pro Capture family kernel module"; + + config = mkIf cfg.enable { + + assertions = singleton { + assertion = versionAtLeast kernelPackages.kernel.version "3.2"; + message = "Magewell Pro Capture family module is not supported for kernels older than 3.2"; + }; + + boot.kernelModules = [ "ProCapture" ]; + + environment.systemPackages = [ kernelPackages.mwprocapture ]; + + boot.extraModulePackages = [ kernelPackages.mwprocapture ]; + + boot.extraModprobeConfig = '' + # Set the png picture to be displayed when no input signal is detected. + options ProCapture nosignal_file=${kernelPackages.mwprocapture}/res/NoSignal.png + + # Set the png picture to be displayed when an unsupported input signal is detected. + options ProCapture unsupported_file=${kernelPackages.mwprocapture}/res/Unsupported.png + + # Set the png picture to be displayed when an loking input signal is detected. + options ProCapture locking_file=${kernelPackages.mwprocapture}/res/Locking.png + + # Message signaled interrupts switch + #options ProCapture disable_msi=0 + + # Set the debug level + #options ProCapture debug_level=0 + + # Force init switch eeprom + #options ProCapture init_switch_eeprom=0 + + # Min frame interval for VIDIOC_ENUM_FRAMEINTERVALS (default: 166666(100ns)) + #options ProCapture enum_frameinterval_min=166666 + + # VIDIOC_ENUM_FRAMESIZES type (1: DISCRETE; 2: STEPWISE; otherwise: CONTINUOUS ) + #options ProCapture enum_framesizes_type=0 + + # Parameters for internal usage + #options ProCapture internal_params="" + ''; + + }; + +} diff --git a/nixos/modules/hardware/video/nvidia.nix b/nixos/modules/hardware/video/nvidia.nix index cf723d53269b..161ed9457af9 100644 --- a/nixos/modules/hardware/video/nvidia.nix +++ b/nixos/modules/hardware/video/nvidia.nix @@ -49,6 +49,10 @@ in Option "RandRRotation" "on" ''; + environment.etc."nvidia/nvidia-application-profiles-rc" = mkIf nvidia_x11.useProfiles { + source = "${nvidia_x11.bin}/share/nvidia/nvidia-application-profiles-rc"; + }; + hardware.opengl.package = nvidiaPackage nvidia_x11 pkgs; hardware.opengl.package32 = nvidiaPackage nvidia_libs32 pkgs_i686; diff --git a/nixos/modules/i18n/input-method/ibus.nix b/nixos/modules/i18n/input-method/ibus.nix index a5bbe6bcb559..f8e021f551e8 100644 --- a/nixos/modules/i18n/input-method/ibus.nix +++ b/nixos/modules/i18n/input-method/ibus.nix @@ -44,7 +44,7 @@ in panel = mkOption { type = with types; nullOr path; default = null; - example = literalExample "''${pkgs.kde5.plasma-desktop}/lib/libexec/kimpanel-ibus-panel"; + example = literalExample "''${pkgs.plasma5.plasma-desktop}/lib/libexec/kimpanel-ibus-panel"; description = "Replace the IBus panel with another panel."; }; }; diff --git a/nixos/modules/installer/cd-dvd/installation-cd-graphical-kde.nix b/nixos/modules/installer/cd-dvd/installation-cd-graphical-kde.nix index c44dff3bb60d..63227d573495 100644 --- a/nixos/modules/installer/cd-dvd/installation-cd-graphical-kde.nix +++ b/nixos/modules/installer/cd-dvd/installation-cd-graphical-kde.nix @@ -18,7 +18,7 @@ with lib; autoLogin = true; }; - desktopManager.kde5 = { + desktopManager.plasma5 = { enable = true; enableQt4Support = false; }; @@ -66,7 +66,7 @@ with lib; in '' mkdir -p /root/Desktop ln -sfT ${desktopFile} /root/Desktop/nixos-manual.desktop - ln -sfT ${pkgs.kde5.konsole}/share/applications/org.kde.konsole.desktop /root/Desktop/org.kde.konsole.desktop + ln -sfT ${pkgs.konsole}/share/applications/org.kde.konsole.desktop /root/Desktop/org.kde.konsole.desktop ln -sfT ${pkgs.gparted}/share/applications/gparted.desktop /root/Desktop/gparted.desktop ''; diff --git a/nixos/modules/installer/cd-dvd/iso-image.nix b/nixos/modules/installer/cd-dvd/iso-image.nix index 93dba0d882b8..85163305c1ef 100644 --- a/nixos/modules/installer/cd-dvd/iso-image.nix +++ b/nixos/modules/installer/cd-dvd/iso-image.nix @@ -280,7 +280,7 @@ in options = [ "allow_other" "cow" "nonempty" "chroot=/mnt-root" "max_files=32768" "hide_meta_files" "dirs=/nix/.rw-store=rw:/nix/.ro-store=ro" ]; }; - boot.initrd.availableKernelModules = [ "squashfs" "iso9660" "usb-storage" ]; + boot.initrd.availableKernelModules = [ "squashfs" "iso9660" "usb-storage" "uas" ]; boot.blacklistedKernelModules = [ "nouveau" ]; diff --git a/nixos/modules/installer/scan/detected.nix b/nixos/modules/installer/scan/detected.nix index f350cd986afa..e72c78532943 100644 --- a/nixos/modules/installer/scan/detected.nix +++ b/nixos/modules/installer/scan/detected.nix @@ -1,4 +1,4 @@ -# List all devices which are detected by nixos-hardware-scan. +# List all devices which are detected by nixos-generate-config. # Common devices are enabled by default. { config, lib, pkgs, ... }: diff --git a/nixos/modules/installer/scan/not-detected.nix b/nixos/modules/installer/scan/not-detected.nix index b30c569ed2a7..e1a3052ba957 100644 --- a/nixos/modules/installer/scan/not-detected.nix +++ b/nixos/modules/installer/scan/not-detected.nix @@ -1,4 +1,4 @@ -# List all devices which are _not_ detected by nixos-hardware-scan. +# List all devices which are _not_ detected by nixos-generate-config. # Common devices are enabled by default. { config, lib, pkgs, ... }: diff --git a/nixos/modules/installer/tools/nix-fallback-paths.nix b/nixos/modules/installer/tools/nix-fallback-paths.nix index d73d67ef4728..07623fd591de 100644 --- a/nixos/modules/installer/tools/nix-fallback-paths.nix +++ b/nixos/modules/installer/tools/nix-fallback-paths.nix @@ -1,5 +1,5 @@ { - x86_64-linux = "/nix/store/qdkzm17csr24snk247a1s0c47ikq5sl6-nix-1.11.6"; - i686-linux = "/nix/store/hiwp53747lxlniqy5wpbql5izjrs8z0z-nix-1.11.6"; - x86_64-darwin = "/nix/store/hca2hqcvwncf23hiqyqgwbsdy8vvl9xv-nix-1.11.6"; + x86_64-linux = "/nix/store/4ssykr786d0wp7y6m4xd4qwqs4nrry1z-nix-1.11.7"; + i686-linux = "/nix/store/61ggxx2072y2g877m01asy0lsn7xpn06-nix-1.11.7"; + x86_64-darwin = "/nix/store/pxf5ri5kdbfqkhd10sw4lpj8sn385ks5-nix-1.11.7"; } diff --git a/nixos/modules/installer/tools/nixos-generate-config.pl b/nixos/modules/installer/tools/nixos-generate-config.pl index b72db1f6f503..29b447912e70 100644 --- a/nixos/modules/installer/tools/nixos-generate-config.pl +++ b/nixos/modules/installer/tools/nixos-generate-config.pl @@ -607,7 +607,7 @@ $bootLoaderConfig # Enable the KDE Desktop Environment. # services.xserver.displayManager.sddm.enable = true; - # services.xserver.desktopManager.kde5.enable = true; + # services.xserver.desktopManager.plasma5.enable = true; # Define a user account. Don't forget to set a password with ‘passwd’. # users.extraUsers.guest = { diff --git a/nixos/modules/installer/tools/nixos-rebuild.sh b/nixos/modules/installer/tools/nixos-rebuild.sh index 4f73865dad6a..4b5e7b3230c8 100644 --- a/nixos/modules/installer/tools/nixos-rebuild.sh +++ b/nixos/modules/installer/tools/nixos-rebuild.sh @@ -278,24 +278,22 @@ if [ -n "$buildNix" ]; then echo "building Nix..." >&2 nixDrv= if ! nixDrv="$(nix-instantiate '<nixpkgs/nixos>' --add-root $tmpDir/nix.drv --indirect -A config.nix.package.out "${extraBuildFlags[@]}")"; then - if ! nixDrv="$(nix-instantiate '<nixpkgs/nixos>' --add-root $tmpDir/nix.drv --indirect -A nixFallback "${extraBuildFlags[@]}")"; then - if ! nixDrv="$(nix-instantiate '<nixpkgs>' --add-root $tmpDir/nix.drv --indirect -A nix "${extraBuildFlags[@]}")"; then - nixStorePath="$(prebuiltNix "$(uname -m)")" - if ! nix-store -r $nixStorePath --add-root $tmpDir/nix --indirect \ - --option extra-binary-caches https://cache.nixos.org/; then + if ! nixDrv="$(nix-instantiate '<nixpkgs>' --add-root $tmpDir/nix.drv --indirect -A nix "${extraBuildFlags[@]}")"; then + nixStorePath="$(prebuiltNix "$(uname -m)")" + if ! nix-store -r $nixStorePath --add-root $tmpDir/nix --indirect \ + --option extra-binary-caches https://cache.nixos.org/; then + echo "warning: don't know how to get latest Nix" >&2 + fi + # Older version of nix-store -r don't support --add-root. + [ -e $tmpDir/nix ] || ln -sf $nixStorePath $tmpDir/nix + if [ -n "$buildHost" ]; then + remoteNixStorePath="$(prebuiltNix "$(buildHostCmd uname -m)")" + remoteNix="$remoteNixStorePath/bin" + if ! buildHostCmd nix-store -r $remoteNixStorePath \ + --option extra-binary-caches https://cache.nixos.org/ >/dev/null; then + remoteNix= echo "warning: don't know how to get latest Nix" >&2 fi - # Older version of nix-store -r don't support --add-root. - [ -e $tmpDir/nix ] || ln -sf $nixStorePath $tmpDir/nix - if [ -n "$buildHost" ]; then - remoteNixStorePath="$(prebuiltNix "$(buildHostCmd uname -m)")" - remoteNix="$remoteNixStorePath/bin" - if ! buildHostCmd nix-store -r $remoteNixStorePath \ - --option extra-binary-caches https://cache.nixos.org/ >/dev/null; then - remoteNix= - echo "warning: don't know how to get latest Nix" >&2 - fi - fi fi fi fi diff --git a/nixos/modules/misc/ids.nix b/nixos/modules/misc/ids.nix index d51b29b99dae..feecee3225be 100644 --- a/nixos/modules/misc/ids.nix +++ b/nixos/modules/misc/ids.nix @@ -288,6 +288,7 @@ kresd = 270; rpc = 271; geoip = 272; + fcron = 273; # When adding a uid, make sure it doesn't match an existing gid. And don't use uids above 399! @@ -545,6 +546,7 @@ kresd = 270; #rpc = 271; # unused #geoip = 272; # unused + fcron = 273; # When adding a gid, make sure it doesn't match an existing # uid. Users and groups with the same name should have equal diff --git a/nixos/modules/misc/locate.nix b/nixos/modules/misc/locate.nix index 089f354f6119..6d9bc915ba03 100644 --- a/nixos/modules/misc/locate.nix +++ b/nixos/modules/misc/locate.nix @@ -104,13 +104,13 @@ in { users.extraGroups = mkIf isMLocate { mlocate = {}; }; security.wrappers = mkIf isMLocate { - mlocate = { + locate = { group = "mlocate"; owner = "root"; permissions = "u+rx,g+x,o+x"; setgid = true; setuid = false; - program = "locate"; + source = "${cfg.locate}/bin/locate"; }; }; diff --git a/nixos/modules/misc/version.nix b/nixos/modules/misc/version.nix index 70cd3fb9766a..315c33a462c6 100644 --- a/nixos/modules/misc/version.nix +++ b/nixos/modules/misc/version.nix @@ -95,7 +95,7 @@ in nixosVersionSuffix = mkIf (pathIsDirectory gitRepo) (mkDefault (".git." + gitCommitId)); # Note: code names must only increase in alphabetical order. - nixosCodeName = "Gorilla"; + nixosCodeName = "Hummingbird"; }; # Generate /etc/os-release. See @@ -106,9 +106,12 @@ in NAME=NixOS ID=nixos VERSION="${config.system.nixosVersion} (${config.system.nixosCodeName})" + VERSION_CODENAME=${toLower config.system.nixosCodeName} VERSION_ID="${config.system.nixosVersion}" PRETTY_NAME="NixOS ${config.system.nixosVersion} (${config.system.nixosCodeName})" - HOME_URL="http://nixos.org/" + HOME_URL="https://nixos.org/" + SUPPORT_URL="https://nixos.org/nixos/support.html" + BUG_REPORT_URL="https://github.com/NixOS/nixpkgs/issues" ''; }; diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index 81597d91d89a..627807edb900 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -29,7 +29,9 @@ ./hardware/ckb.nix ./hardware/cpu/amd-microcode.nix ./hardware/cpu/intel-microcode.nix + ./hardware/sensor/iio.nix ./hardware/ksm.nix + ./hardware/mcelog.nix ./hardware/network/b43.nix ./hardware/network/intel-2100bg.nix ./hardware/network/intel-2200bg.nix @@ -38,9 +40,11 @@ ./hardware/network/rtl8192c.nix ./hardware/opengl.nix ./hardware/pcmcia.nix + ./hardware/usb-wwan.nix ./hardware/video/amdgpu.nix ./hardware/video/amdgpu-pro.nix ./hardware/video/ati.nix + ./hardware/video/capture/mwprocapture.nix ./hardware/video/bumblebee.nix ./hardware/video/displaylink.nix ./hardware/video/nvidia.nix @@ -80,6 +84,7 @@ ./programs/light.nix ./programs/man.nix ./programs/mosh.nix + ./programs/mtr.nix ./programs/nano.nix ./programs/oblogout.nix ./programs/screen.nix @@ -91,6 +96,7 @@ ./programs/tmux.nix ./programs/venus.nix ./programs/vim.nix + ./programs/wireshark.nix ./programs/wvdial.nix ./programs/xfs_quota.nix ./programs/xonsh.nix @@ -102,6 +108,7 @@ ./security/audit.nix ./security/ca.nix ./security/chromium-suid-sandbox.nix + ./security/dhparams.nix ./security/duosec.nix ./security/grsecurity.nix ./security/hidepid.nix @@ -322,6 +329,7 @@ ./services/monitoring/prometheus/default.nix ./services/monitoring/prometheus/alertmanager.nix ./services/monitoring/prometheus/blackbox-exporter.nix + ./services/monitoring/prometheus/fritzbox-exporter.nix ./services/monitoring/prometheus/json-exporter.nix ./services/monitoring/prometheus/nginx-exporter.nix ./services/monitoring/prometheus/node-exporter.nix @@ -422,6 +430,7 @@ ./services/networking/namecoind.nix ./services/networking/nat.nix ./services/networking/networkmanager.nix + ./services/networking/nftables.nix ./services/networking/ngircd.nix ./services/networking/nix-serve.nix ./services/networking/nntp-proxy.nix @@ -564,6 +573,7 @@ ./services/x11/display-managers/lightdm.nix ./services/x11/display-managers/sddm.nix ./services/x11/display-managers/slim.nix + ./services/x11/display-managers/xpra.nix ./services/x11/hardware/libinput.nix ./services/x11/hardware/multitouch.nix ./services/x11/hardware/synaptics.nix diff --git a/nixos/modules/profiles/graphical.nix b/nixos/modules/profiles/graphical.nix index 73dd2d4bc9f7..e23375375188 100644 --- a/nixos/modules/profiles/graphical.nix +++ b/nixos/modules/profiles/graphical.nix @@ -1,5 +1,5 @@ -# This module defines a NixOS configuration that contains X11 and -# KDE 4. It's used by the graphical installation CD. +# This module defines a NixOS configuration with the Plasma 5 desktop. +# It's used by the graphical installation CD. { config, pkgs, ... }: @@ -7,7 +7,7 @@ services.xserver = { enable = true; displayManager.sddm.enable = true; - desktopManager.kde5.enable = true; + desktopManager.plasma5.enable = true; synaptics.enable = true; # for touchpad support on many laptops }; diff --git a/nixos/modules/programs/mtr.nix b/nixos/modules/programs/mtr.nix new file mode 100644 index 000000000000..927fe68be875 --- /dev/null +++ b/nixos/modules/programs/mtr.nix @@ -0,0 +1,27 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + cfg = config.programs.mtr; +in { + options = { + programs.mtr = { + enable = mkOption { + type = types.bool; + default = false; + description = '' + Whether to add mtr to the global environment and configure a + setcap wrapper for it. + ''; + }; + }; + }; + + config = mkIf cfg.enable { + security.wrappers.mtr = { + source = "${pkgs.mtr}/bin/mtr"; + capabilities = "cap_net_raw+p"; + }; + }; +} diff --git a/nixos/modules/programs/wireshark.nix b/nixos/modules/programs/wireshark.nix new file mode 100644 index 000000000000..710d223b6f59 --- /dev/null +++ b/nixos/modules/programs/wireshark.nix @@ -0,0 +1,42 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + cfg = config.programs.wireshark; + wireshark = cfg.package; +in { + options = { + programs.wireshark = { + enable = mkOption { + type = types.bool; + default = false; + description = '' + Whether to add Wireshark to the global environment and configure a + setcap wrapper for 'dumpcap' for users in the 'wireshark' group. + ''; + }; + package = mkOption { + type = types.package; + default = pkgs.wireshark-cli; + defaultText = "pkgs.wireshark-cli"; + description = '' + Which Wireshark package to install in the global environment. + ''; + }; + }; + }; + + config = mkIf cfg.enable { + environment.systemPackages = [ wireshark ]; + users.extraGroups.wireshark = {}; + + security.wrappers.dumpcap = { + source = "${wireshark}/bin/dumpcap"; + capabilities = "cap_net_raw+p"; + owner = "root"; + group = "wireshark"; + permissions = "u+rx,g+x"; + }; + }; +} diff --git a/nixos/modules/rename.nix b/nixos/modules/rename.nix index ee68f8bff81a..af8b34b5e5cb 100644 --- a/nixos/modules/rename.nix +++ b/nixos/modules/rename.nix @@ -103,9 +103,6 @@ with lib; (mkRenamedOptionModule [ "services" "xserver" "windowManager" "xbmc" ] [ "services" "xserver" "desktopManager" "kodi" ]) (mkRenamedOptionModule [ "services" "xserver" "desktopManager" "xbmc" ] [ "services" "xserver" "desktopManager" "kodi" ]) - # DNSCrypt-proxy - (mkRenamedOptionModule [ "services" "dnscrypt-proxy" "port" ] [ "services" "dnscrypt-proxy" "localPort" ]) - (mkRenamedOptionModule [ "services" "hostapd" "extraCfg" ] [ "services" "hostapd" "extraConfig" ]) # Enlightenment @@ -178,6 +175,16 @@ with lib; (mkRenamedOptionModule [ "services" "nfs" "lockdPort" ] [ "services" "nfs" "server" "lockdPort" ]) (mkRenamedOptionModule [ "services" "nfs" "statdPort" ] [ "services" "nfs" "server" "statdPort" ]) + # KDE Plasma 5 + (mkRenamedOptionModule [ "services" "xserver" "desktopManager" "kde5" ] [ "services" "xserver" "desktopManager" "plasma5" ]) + + # Fontconfig + (mkRenamedOptionModule [ "config" "fonts" "fontconfig" "ultimate" "allowBitmaps" ] [ "config" "fonts" "fontconfig" "allowBitmaps" ]) + (mkRenamedOptionModule [ "config" "fonts" "fontconfig" "ultimate" "allowType1" ] [ "config" "fonts" "fontconfig" "allowType1" ]) + (mkRenamedOptionModule [ "config" "fonts" "fontconfig" "ultimate" "useEmbeddedBitmaps" ] [ "config" "fonts" "fontconfig" "useEmbeddedBitmaps" ]) + (mkRenamedOptionModule [ "config" "fonts" "fontconfig" "ultimate" "forceAutohint" ] [ "config" "fonts" "fontconfig" "forceAutohint" ]) + (mkRenamedOptionModule [ "config" "fonts" "fontconfig" "ultimate" "renderMonoTTFAsBitmap" ] [ "config" "fonts" "fontconfig" "renderMonoTTFAsBitmap" ]) + # Options that are obsolete and have no replacement. (mkRemovedOptionModule [ "boot" "initrd" "luks" "enable" ] "") (mkRemovedOptionModule [ "programs" "bash" "enable" ] "") diff --git a/nixos/modules/security/acme.nix b/nixos/modules/security/acme.nix index 4e7c966a463a..78bd09441f83 100644 --- a/nixos/modules/security/acme.nix +++ b/nixos/modules/security/acme.nix @@ -129,7 +129,7 @@ in certs = mkOption { default = { }; - type = with types; loaOf (submodule certOpts); + type = with types; attrsOf (submodule certOpts); description = '' Attribute set of certificates to get signed and renewed. ''; diff --git a/nixos/modules/security/dhparams.nix b/nixos/modules/security/dhparams.nix new file mode 100644 index 000000000000..c16cd2fafef4 --- /dev/null +++ b/nixos/modules/security/dhparams.nix @@ -0,0 +1,90 @@ +{ config, lib, pkgs, ... }: + +with lib; +let + cfg = config.security.dhparams; +in +{ + options = { + security.dhparams = { + params = mkOption { + description = + '' + Diffie-Hellman parameters to generate. + + The value is the size (in bits) of the DH params to generate. The + generated DH params path can be found in + <filename><replaceable>security.dhparams.path</replaceable>/<replaceable>name</replaceable>.pem</filename>. + + Note: The name of the DH params is taken as being the name of the + service it serves: the params will be generated before the said + service is started. + ''; + type = with types; attrsOf int; + default = {}; + example = { nginx = 3072; }; + }; + + path = mkOption { + description = + '' + Path to the directory in which Diffie-Hellman parameters will be + stored. + ''; + type = types.str; + default = "/var/lib/dhparams"; + }; + }; + }; + + config.systemd.services = { + dhparams-init = { + description = "Cleanup old Diffie-Hellman parameters"; + wantedBy = [ "multi-user.target" ]; # Clean up even when no DH params is set + serviceConfig.Type = "oneshot"; + script = + # Create directory + '' + if [ ! -d ${cfg.path} ]; then + mkdir -p ${cfg.path} + fi + '' + + # Remove old dhparams + '' + for file in ${cfg.path}/*; do + if [ ! -f "$file" ]; then + continue + fi + '' + concatStrings (mapAttrsToList (name: value: + '' + if [ "$file" == "${cfg.path}/${name}.pem" ] && \ + ${pkgs.openssl}/bin/openssl dhparam -in "$file" -text | head -n 1 | grep "(${toString value} bit)" > /dev/null; then + continue + fi + '' + ) cfg.params) + + '' + rm $file + done + + # TODO: Ideally this would be removing the *former* cfg.path, though this + # does not seem really important + rmdir -p --ignore-fail-on-non-empty ${cfg.path} + ''; + }; + } // + mapAttrs' (name: value: nameValuePair "dhparams-gen-${name}" { + description = "Generate Diffie-Hellman parameters for ${name} if they don't exist yet"; + after = [ "dhparams-init.service" ]; + before = [ "${name}.service" ]; + wantedBy = [ "multi-user.target" ]; + serviceConfig.Type = "oneshot"; + script = + '' + mkdir -p ${cfg.path} + if [ ! -f ${cfg.path}/${name}.pem ]; then + ${pkgs.openssl}/bin/openssl dhparam -out ${cfg.path}/${name}.pem ${toString value} + fi + ''; + }) cfg.params; +} diff --git a/nixos/modules/security/grsecurity.xml b/nixos/modules/security/grsecurity.xml index ef0aab4a3f13..620e8f653f99 100644 --- a/nixos/modules/security/grsecurity.xml +++ b/nixos/modules/security/grsecurity.xml @@ -214,8 +214,8 @@ GRKERNSEC_CONFIG_SERVER y GRKERNSEC_CONFIG_SECURITY y ''; - }; - } + }; + }; </programlisting> </para> @@ -312,7 +312,7 @@ Overflows in boot critical code (e.g., the root filesystem module) can render the system unbootable. Work around by setting <programlisting> - boot.kernel.kernelParams = [ "pax_size_overflow_report_only" ]; + boot.kernelParams = [ "pax_size_overflow_report_only" ]; </programlisting> </para></listitem> diff --git a/nixos/modules/security/pam.nix b/nixos/modules/security/pam.nix index b51c8b4996be..5632500df2e0 100644 --- a/nixos/modules/security/pam.nix +++ b/nixos/modules/security/pam.nix @@ -280,8 +280,8 @@ let ${optionalString cfg.pamMount "auth optional ${pkgs.pam_mount}/lib/security/pam_mount.so"} ${optionalString cfg.enableKwallet - ("auth optional ${pkgs.kde5.kwallet-pam}/lib/security/pam_kwallet5.so" + - " kwalletd=${pkgs.kde5.kwallet}/bin/kwalletd5")} + ("auth optional ${pkgs.plasma5.kwallet-pam}/lib/security/pam_kwallet5.so" + + " kwalletd=${pkgs.libsForQt5.kwallet}/bin/kwalletd5")} '') + '' ${optionalString cfg.unixAuth "auth sufficient pam_unix.so ${optionalString cfg.allowNullPassword "nullok"} likeauth try_first_pass"} @@ -349,8 +349,8 @@ let ${optionalString (cfg.enableAppArmor && config.security.apparmor.enable) "session optional ${pkgs.apparmor-pam}/lib/security/pam_apparmor.so order=user,group,default debug"} ${optionalString (cfg.enableKwallet) - ("session optional ${pkgs.kde5.kwallet-pam}/lib/security/pam_kwallet5.so" + - " kwalletd=${pkgs.kde5.kwallet}/bin/kwalletd5")} + ("session optional ${pkgs.plasma5.kwallet-pam}/lib/security/pam_kwallet5.so" + + " kwalletd=${pkgs.libsForQt5.kwallet}/bin/kwalletd5")} ''); }; diff --git a/nixos/modules/security/polkit.nix b/nixos/modules/security/polkit.nix index 419abb8b086d..8d9d53480630 100644 --- a/nixos/modules/security/polkit.nix +++ b/nixos/modules/security/polkit.nix @@ -84,7 +84,7 @@ in security.pam.services.polkit-1 = {}; security.wrappers = { - pkexec.source = "${pkgs.polkit.out}/bin/pkexec"; + pkexec.source = "${pkgs.polkit.bin}/bin/pkexec"; "polkit-agent-helper-1".source = "${pkgs.polkit.out}/lib/polkit-1/polkit-agent-helper-1"; }; diff --git a/nixos/modules/security/wrappers/default.nix b/nixos/modules/security/wrappers/default.nix index 861ce225257d..65d875c3a375 100644 --- a/nixos/modules/security/wrappers/default.nix +++ b/nixos/modules/security/wrappers/default.nix @@ -3,6 +3,8 @@ let inherit (config.security) wrapperDir wrappers; + parentWrapperDir = dirOf wrapperDir; + programs = (lib.mapAttrsToList (n: v: (if v ? "program" then v else v // {program=n;})) @@ -15,8 +17,7 @@ let hardeningEnable = [ "pie" ]; installPhase = '' mkdir -p $out/bin - parentWrapperDir=$(dirname ${wrapperDir}) - gcc -Wall -O2 -DWRAPPER_DIR=\"$parentWrapperDir\" \ + gcc -Wall -O2 -DWRAPPER_DIR=\"${parentWrapperDir}\" \ -lcap-ng -lcap ${./wrapper.c} -o $out/bin/security-wrapper ''; }; @@ -28,6 +29,7 @@ let , source , owner ? "nobody" , group ? "nogroup" + , permissions ? "u+rx,g+x,o+x" , ... }: assert (lib.versionAtLeast (lib.getVersion config.boot.kernelPackages.kernel) "4.3"); @@ -45,7 +47,7 @@ let ${pkgs.libcap.out}/bin/setcap "cap_setpcap,${capabilities}" $wrapperDir/${program} # Set the executable bit - chmod u+rx,g+x,o+x $wrapperDir/${program} + chmod ${permissions} $wrapperDir/${program} ''; ###### Activation script for the setuid wrappers @@ -155,6 +157,11 @@ in security.wrappers.fusermount.source = "${pkgs.fuse}/bin/fusermount"; + boot.specialFileSystems.${parentWrapperDir} = { + fsType = "tmpfs"; + options = [ "nodev" ]; + }; + # Make sure our wrapperDir exports to the PATH env variable when # initializing the shell environment.extraInit = '' @@ -182,19 +189,15 @@ in # Remove the old /run/setuid-wrappers-dir path from the # system as well... # - # TDOO: this is only necessary for ugprades 16.09 => 17.x; + # TODO: this is only necessary for ugprades 16.09 => 17.x; # this conditional removal block needs to be removed after # the release. if [ -d /run/setuid-wrapper-dirs ]; then rm -rf /run/setuid-wrapper-dirs fi - # Get the "/run/wrappers" path, we want to place the tmpdirs - # for the wrappers there - parentWrapperDir="$(dirname ${wrapperDir})" - - mkdir -p "$parentWrapperDir" - wrapperDir=$(mktemp --directory --tmpdir="$parentWrapperDir" wrappers.XXXXXXXXXX) + # We want to place the tmpdirs for the wrappers to the parent dir. + wrapperDir=$(mktemp --directory --tmpdir="${parentWrapperDir}" wrappers.XXXXXXXXXX) chmod a+rx $wrapperDir ${lib.concatStringsSep "\n" mkWrappedPrograms} @@ -206,13 +209,6 @@ in ln --symbolic --force --no-dereference $wrapperDir ${wrapperDir}-tmp mv --no-target-directory ${wrapperDir}-tmp ${wrapperDir} rm --force --recursive $old - elif [ -d ${wrapperDir} ]; then - # Compatibility with old state, just remove the folder and symlink - rm -f ${wrapperDir}/* - # if it happens to be a tmpfs - ${pkgs.utillinux}/bin/umount ${wrapperDir} || true - rm -d ${wrapperDir} - ln -d --symbolic $wrapperDir ${wrapperDir} else # For initial setup ln --symbolic $wrapperDir ${wrapperDir} diff --git a/nixos/modules/services/audio/mpd.nix b/nixos/modules/services/audio/mpd.nix index a89215d73828..56af8fe152e0 100644 --- a/nixos/modules/services/audio/mpd.nix +++ b/nixos/modules/services/audio/mpd.nix @@ -4,6 +4,8 @@ with lib; let + name = "mpd"; + uid = config.ids.uids.mpd; gid = config.ids.gids.mpd; cfg = config.services.mpd; @@ -54,13 +56,14 @@ in { description = '' Extra directives added to to the end of MPD's configuration file, mpd.conf. Basic configuration like file location and uid/gid - is added automatically to the beginning of the file. + is added automatically to the beginning of the file. For available + options see <literal>man 5 mpd.conf</literal>'. ''; }; dataDir = mkOption { type = types.path; - default = "/var/lib/mpd"; + default = "/var/lib/${name}"; description = '' The directory where MPD stores its state, tag cache, playlists etc. @@ -69,13 +72,13 @@ in { user = mkOption { type = types.str; - default = "mpd"; + default = name; description = "User account under which MPD runs."; }; group = mkOption { type = types.str; - default = "mpd"; + default = name; description = "Group account under which MPD runs."; }; @@ -131,17 +134,17 @@ in { }; }; - users.extraUsers = optionalAttrs (cfg.user == "mpd") (singleton { + users.extraUsers = optionalAttrs (cfg.user == name) (singleton { inherit uid; - name = "mpd"; + inherit name; group = cfg.group; extraGroups = [ "audio" ]; description = "Music Player Daemon user"; home = "${cfg.dataDir}"; }); - users.extraGroups = optionalAttrs (cfg.group == "mpd") (singleton { - name = "mpd"; + users.extraGroups = optionalAttrs (cfg.group == name) (singleton { + inherit name; gid = gid; }); }; diff --git a/nixos/modules/services/cluster/kubernetes.nix b/nixos/modules/services/cluster/kubernetes.nix index a82802c32662..9ccc7295019a 100644 --- a/nixos/modules/services/cluster/kubernetes.nix +++ b/nixos/modules/services/cluster/kubernetes.nix @@ -76,6 +76,7 @@ in { description = "Kubernetes package to use."; type = types.package; default = pkgs.kubernetes; + defaultText = "pkgs.kubernetes"; }; verbose = mkOption { diff --git a/nixos/modules/services/continuous-integration/buildbot/master.nix b/nixos/modules/services/continuous-integration/buildbot/master.nix index 512e09eb8041..533751734fa5 100644 --- a/nixos/modules/services/continuous-integration/buildbot/master.nix +++ b/nixos/modules/services/continuous-integration/buildbot/master.nix @@ -28,7 +28,7 @@ let ${cfg.extraConfig} '' - else pkgs.writeText "master.cfg" cfg.masterCfg; + else cfg.masterCfg; in { options = { @@ -66,13 +66,10 @@ in { }; masterCfg = mkOption { - type = types.str; - description = '' - Optionally pass raw master.cfg file as string. - Other options in this configuration will be ignored. - ''; + type = types.nullOr types.path; + description = "Optionally pass master.cfg path. Other options in this configuration will be ignored."; default = null; - example = "BuildmasterConfig = c = {}"; + example = "/etc/nixos/buildbot/master.cfg"; }; schedulers = mkOption { @@ -88,7 +85,7 @@ in { type = types.listOf types.str; description = "List of Builders."; default = [ - "util.BuilderConfig(name='runtests',workernames=['default-worker'],factory=factory)" + "util.BuilderConfig(name='runtests',workernames=['example-worker'],factory=factory)" ]; }; @@ -121,7 +118,7 @@ in { extraGroups = mkOption { type = types.listOf types.str; - default = [ "nixbld" ]; + default = []; description = "List of extra groups that the buildbot user should be a part of."; }; @@ -183,16 +180,14 @@ in { package = mkOption { type = types.package; default = pkgs.buildbot-ui; - description = '' - Package to use for buildbot. - <literal>buildbot-full</literal> is required in order to use local workers. - ''; - example = pkgs.buildbot-full; + defaultText = "pkgs.buildbot-ui"; + description = "Package to use for buildbot."; + example = literalExample "pkgs.buildbot-full"; }; packages = mkOption { default = [ ]; - example = [ pkgs.git ]; + example = literalExample "[ pkgs.git ]"; type = types.listOf types.package; description = "Packages to add to PATH for the buildbot process."; }; @@ -222,11 +217,11 @@ in { path = cfg.packages; serviceConfig = { - Type = "forking"; + Type = "simple"; User = cfg.user; Group = cfg.group; WorkingDirectory = cfg.home; - ExecStart = "${cfg.package}/bin/buildbot start ${cfg.buildbotDir}"; + ExecStart = "${cfg.package}/bin/buildbot start --nodaemon ${cfg.buildbotDir}"; }; preStart = '' diff --git a/nixos/modules/services/continuous-integration/buildbot/worker.nix b/nixos/modules/services/continuous-integration/buildbot/worker.nix index 430fd4e53f1c..e4ee4dd861ef 100644 --- a/nixos/modules/services/continuous-integration/buildbot/worker.nix +++ b/nixos/modules/services/continuous-integration/buildbot/worker.nix @@ -31,7 +31,7 @@ in { extraGroups = mkOption { type = types.listOf types.str; - default = [ "nixbld" ]; + default = []; description = "List of extra groups that the Buildbot Worker user should be a part of."; }; @@ -68,13 +68,14 @@ in { package = mkOption { type = types.package; default = pkgs.buildbot-worker; + defaultText = "pkgs.buildbot-worker"; description = "Package to use for buildbot worker."; - example = pkgs.buildbot-worker; + example = literalExample "pkgs.buildbot-worker"; }; packages = mkOption { default = [ ]; - example = [ pkgs.git ]; + example = literalExample "[ pkgs.git ]"; type = types.listOf types.package; description = "Packages to add to PATH for the buildbot process."; }; @@ -100,24 +101,21 @@ in { systemd.services.buildbot-worker = { description = "Buildbot Worker."; - after = [ "network.target" ]; + after = [ "network.target" "buildbot-master.service" ]; wantedBy = [ "multi-user.target" ]; - wants = [ "buildbot-master.service" ]; path = cfg.packages; preStart = '' - # NOTE: ensure master has time to start in case running on localhost - ${pkgs.coreutils}/bin/sleep 4 ${pkgs.coreutils}/bin/mkdir -vp ${cfg.buildbotDir} ${cfg.package}/bin/buildbot-worker create-worker ${cfg.buildbotDir} ${cfg.masterUrl} ${cfg.workerUser} ${cfg.workerPass} ''; serviceConfig = { - Type = "forking"; + Type = "simple"; User = cfg.user; Group = cfg.group; WorkingDirectory = cfg.home; - ExecStart = "${cfg.package}/bin/buildbot-worker start ${cfg.buildbotDir}"; + ExecStart = "${cfg.package}/bin/buildbot-worker start --nodaemon ${cfg.buildbotDir}"; }; }; diff --git a/nixos/modules/services/continuous-integration/jenkins/job-builder.nix b/nixos/modules/services/continuous-integration/jenkins/job-builder.nix index 7b1fe6269fe9..861b46a2d642 100644 --- a/nixos/modules/services/continuous-integration/jenkins/job-builder.nix +++ b/nixos/modules/services/continuous-integration/jenkins/job-builder.nix @@ -29,6 +29,22 @@ in { ''; }; + accessUser = mkOption { + default = ""; + type = types.str; + description = '' + User id in Jenkins used to reload config. + ''; + }; + + accessToken = mkOption { + default = ""; + type = types.str; + description = '' + User token in Jenkins used to reload config. + ''; + }; + yamlJobs = mkOption { default = ""; type = types.lines; @@ -110,6 +126,11 @@ in { # Stamp file is placed in $JENKINS_HOME/jobs/$JOB_NAME/ to indicate # ownership. Enables tracking and removal of stale jobs. ownerStamp = ".config-xml-managed-by-nixos-jenkins-job-builder"; + reloadScript = '' + echo "Asking Jenkins to reload config" + CRUMB=$(curl -s 'http://${cfg.accessUser}:${cfg.accessToken}@${jenkinsCfg.listenAddress}:${toString jenkinsCfg.port}${jenkinsCfg.prefix}/crumbIssuer/api/xml?xpath=concat(//crumbRequestField,":",//crumb)') + curl --silent -X POST -H "$CRUMB" http://${cfg.accessUser}:${cfg.accessToken}@${jenkinsCfg.listenAddress}:${toString jenkinsCfg.port}${jenkinsCfg.prefix}/reload + ''; in '' rm -rf ${jobBuilderOutputDir} @@ -142,10 +163,7 @@ in { echo "Deleting stale job \"$jobname\"" rm -rf "$jobdir" done - - echo "Asking Jenkins to reload config" - curl --silent -X POST http://${jenkinsCfg.listenAddress}:${toString jenkinsCfg.port}${jenkinsCfg.prefix}/reload - ''; + '' + (if cfg.accessUser != "" then reloadScript else ""); serviceConfig = { User = jenkinsCfg.user; RuntimeDirectory = "jenkins-job-builder"; diff --git a/nixos/modules/services/databases/neo4j.nix b/nixos/modules/services/databases/neo4j.nix index 7b51f1af6899..cbba9c2a691c 100644 --- a/nixos/modules/services/databases/neo4j.nix +++ b/nixos/modules/services/databases/neo4j.nix @@ -30,9 +30,16 @@ let ''; wrapperConfig = pkgs.writeText "neo4j-wrapper.conf" '' + # Default JVM parameters from neo4j.conf + dbms.jvm.additional=-XX:+UseG1GC + dbms.jvm.additional=-XX:-OmitStackTraceInFastThrow + dbms.jvm.additional=-XX:+AlwaysPreTouch + dbms.jvm.additional=-XX:+UnlockExperimentalVMOptions + dbms.jvm.additional=-XX:+TrustFinalNonStaticFields + dbms.jvm.additional=-XX:+DisableExplicitGC + dbms.jvm.additional=-Djdk.tls.ephemeralDHKeySize=2048 + dbms.jvm.additional=-Dunsupported.dbms.udc.source=tarball - dbms.jvm.additional=-XX:+UseConcMarkSweepGC - dbms.jvm.additional=-XX:+CMSClassUnloadingEnabled ''; in { diff --git a/nixos/modules/services/databases/openldap.nix b/nixos/modules/services/databases/openldap.nix index b8e6c0cec3dc..d76859bf3eb6 100644 --- a/nixos/modules/services/databases/openldap.nix +++ b/nixos/modules/services/databases/openldap.nix @@ -68,10 +68,10 @@ in "; 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 + include ${pkgs.openldap.out}/etc/schema/core.schema + include ${pkgs.openldap.out}/etc/schema/cosine.schema + include ${pkgs.openldap.out}/etc/schema/inetorgperson.schema + include ${pkgs.openldap.out}/etc/schema/nis.schema database bdb suffix dc=example,dc=org diff --git a/nixos/modules/services/databases/stanchion.nix b/nixos/modules/services/databases/stanchion.nix index f2dbb78b5c4b..a4597cac3cd6 100644 --- a/nixos/modules/services/databases/stanchion.nix +++ b/nixos/modules/services/databases/stanchion.nix @@ -76,14 +76,6 @@ in ''; }; - stanchionSsl = mkOption { - type = types.bool; - default = true; - description = '' - Tell stanchion to use SSL. - ''; - }; - distributedCookie = mkOption { type = types.str; default = "riak"; @@ -148,8 +140,6 @@ in distributed_cookie = ${cfg.distributedCookie} - stanchion_ssl=${if cfg.stanchionSsl then "on" else "off"} - ${cfg.extraConfig} ''; diff --git a/nixos/modules/services/hardware/bluetooth.nix b/nixos/modules/services/hardware/bluetooth.nix index de0d48032113..71b3a93a2e0d 100644 --- a/nixos/modules/services/hardware/bluetooth.nix +++ b/nixos/modules/services/hardware/bluetooth.nix @@ -1,8 +1,11 @@ { config, lib, pkgs, ... }: with lib; + let bluez-bluetooth = pkgs.bluez; + cfg = config.hardware.bluetooth; + in { @@ -11,33 +14,53 @@ in options = { - hardware.bluetooth.enable = mkOption { - type = types.bool; - default = false; - description = "Whether to enable support for Bluetooth."; + hardware.bluetooth.enable = mkEnableOption "support for Bluetooth."; + + hardware.bluetooth.powerOnBoot = mkOption { + type = types.bool; + default = true; + description = "Whether to power up the default Bluetooth controller on boot."; }; }; ###### implementation - config = mkIf config.hardware.bluetooth.enable { + config = mkIf cfg.enable { environment.systemPackages = [ bluez-bluetooth pkgs.openobex pkgs.obexftp ]; services.udev.packages = [ bluez-bluetooth ]; - services.dbus.packages = [ bluez-bluetooth ]; + systemd.packages = [ bluez-bluetooth ]; + + services.udev.extraRules = optionalString cfg.powerOnBoot '' + ACTION=="add", KERNEL=="hci[0-9]*", ENV{SYSTEMD_WANTS}="bluetooth-power@%k.service" + ''; + + systemd.services = { + bluetooth = { + wantedBy = [ "bluetooth.target" ]; + aliases = [ "dbus-org.bluez.service" ]; + }; + + "bluetooth-power@" = mkIf cfg.powerOnBoot { + description = "Power up bluetooth controller"; + after = [ + "bluetooth.service" + "suspend.target" + "sys-subsystem-bluetooth-devices-%i.device" + ]; + wantedBy = [ "suspend.target" ]; + + serviceConfig.Type = "oneshot"; + serviceConfig.ExecStart = "${pkgs.bluez.out}/bin/hciconfig %i up"; + }; - systemd.packages = [ bluez-bluetooth ]; - - systemd.services.bluetooth = { - wantedBy = [ "bluetooth.target" ]; - aliases = [ "dbus-org.bluez.service" ]; }; - systemd.user.services.obex = { - aliases = [ "dbus-org.bluez.obex.service" ]; + systemd.user.services = { + obex.aliases = [ "dbus-org.bluez.obex.service" ]; }; }; diff --git a/nixos/modules/services/logging/fluentd.nix b/nixos/modules/services/logging/fluentd.nix index e56a9a4e9afb..9fbec2457371 100644 --- a/nixos/modules/services/logging/fluentd.nix +++ b/nixos/modules/services/logging/fluentd.nix @@ -25,6 +25,7 @@ in { package = mkOption { type = types.path; default = pkgs.fluentd; + defaultText = "pkgs.fluentd"; description = "The fluentd package to use."; }; }; diff --git a/nixos/modules/services/logging/graylog.nix b/nixos/modules/services/logging/graylog.nix index a7785decd19a..95283096662e 100644 --- a/nixos/modules/services/logging/graylog.nix +++ b/nixos/modules/services/logging/graylog.nix @@ -17,9 +17,16 @@ let elasticsearch_discovery_zen_ping_unicast_hosts = ${cfg.elasticsearchDiscoveryZenPingUnicastHosts} message_journal_dir = ${cfg.messageJournalDir} mongodb_uri = ${cfg.mongodbUri} + plugin_dir = /var/lib/graylog/plugins ${cfg.extraConfig} ''; + + glPlugins = pkgs.buildEnv { + name = "graylog-plugins"; + paths = cfg.plugins; + }; + in { @@ -121,6 +128,12 @@ in description = "Any other configuration options you might want to add"; }; + plugins = mkOption { + description = "Extra graylog plugins"; + default = [ ]; + type = types.listOf types.package; + }; + }; }; @@ -146,6 +159,16 @@ in path = [ pkgs.openjdk8 pkgs.which pkgs.procps ]; preStart = '' mkdir -p /var/lib/graylog -m 755 + + rm -rf /var/lib/graylog/plugins || true + mkdir -p /var/lib/graylog/plugins -m 755 + + for declarativeplugin in `ls ${glPlugins}/bin/`; do + ln -sf ${glPlugins}/bin/$declarativeplugin /var/lib/graylog/plugins/$declarativeplugin + done + for includedplugin in `ls ${cfg.package}/plugin/`; do + ln -s ${cfg.package}/plugin/$includedplugin /var/lib/graylog/plugins/$includedplugin || true + done chown -R ${cfg.user} /var/lib/graylog mkdir -p ${cfg.messageJournalDir} -m 755 diff --git a/nixos/modules/services/logging/logcheck.nix b/nixos/modules/services/logging/logcheck.nix index 72925b95cae4..2a8ac414720b 100644 --- a/nixos/modules/services/logging/logcheck.nix +++ b/nixos/modules/services/logging/logcheck.nix @@ -184,7 +184,7 @@ in description = '' This option defines extra ignore rules. ''; - type = with types; loaOf (submodule ignoreOptions); + type = with types; attrsOf (submodule ignoreOptions); }; ignoreCron = mkOption { @@ -192,7 +192,7 @@ in description = '' This option defines extra ignore rules for cronjobs. ''; - type = with types; loaOf (submodule ignoreCronOptions); + type = with types; attrsOf (submodule ignoreCronOptions); }; extraGroups = mkOption { diff --git a/nixos/modules/services/mail/mlmmj.nix b/nixos/modules/services/mail/mlmmj.nix index e2b37522cb16..4a01745eb8b6 100644 --- a/nixos/modules/services/mail/mlmmj.nix +++ b/nixos/modules/services/mail/mlmmj.nix @@ -18,7 +18,7 @@ let footer = domain: list: "To unsubscribe send a mail to ${list}+unsubscribe@${domain}"; createList = d: l: '' ${pkgs.coreutils}/bin/mkdir -p ${listCtl d l} - echo ${listAddress d l} > ${listCtl d l}/listadress + echo ${listAddress d l} > ${listCtl d l}/listaddress echo "${lib.concatStringsSep "\n" (customHeaders d l)}" > ${listCtl d l}/customheaders echo ${footer d l} > ${listCtl d l}/footer echo ${subjectPrefix l} > ${listCtl d l}/prefix diff --git a/nixos/modules/services/misc/apache-kafka.nix b/nixos/modules/services/misc/apache-kafka.nix index cff053396885..82fa1cc2e7e5 100644 --- a/nixos/modules/services/misc/apache-kafka.nix +++ b/nixos/modules/services/misc/apache-kafka.nix @@ -19,13 +19,8 @@ let ${toString cfg.extraProperties} ''; - configDir = pkgs.buildEnv { - name = "apache-kafka-conf"; - paths = [ - (pkgs.writeTextDir "server.properties" serverProperties) - (pkgs.writeTextDir "log4j.properties" cfg.log4jProperties) - ]; - }; + serverConfig = pkgs.writeText "server.properties" serverProperties; + logConfig = pkgs.writeText "log4j.properties" cfg.log4jProperties; in { @@ -143,10 +138,11 @@ in { serviceConfig = { ExecStart = '' ${pkgs.jre}/bin/java \ - -cp "${cfg.package}/libs/*:${configDir}" \ + -cp "${cfg.package}/libs/*" \ + -Dlog4j.configuration=file:${logConfig} \ ${toString cfg.jvmOptions} \ kafka.Kafka \ - ${configDir}/server.properties + ${serverConfig} ''; User = "apache-kafka"; PermissionsStartOnly = true; diff --git a/nixos/modules/services/misc/nix-daemon.nix b/nixos/modules/services/misc/nix-daemon.nix index 7101cadfeed2..5088c4e60691 100644 --- a/nixos/modules/services/misc/nix-daemon.nix +++ b/nixos/modules/services/misc/nix-daemon.nix @@ -8,6 +8,8 @@ let nix = cfg.package.out; + isNix112 = versionAtLeast (getVersion nix) "1.12pre4997"; + makeNixBuildUser = nr: { name = "nixbld${toString nr}"; description = "Nix build user ${toString nr}"; @@ -162,22 +164,23 @@ in buildMachines = mkOption { type = types.listOf types.attrs; default = []; - example = [ - { hostName = "voila.labs.cs.uu.nl"; - sshUser = "nix"; - sshKey = "/root/.ssh/id_buildfarm"; - system = "powerpc-darwin"; - maxJobs = 1; - } - { hostName = "linux64.example.org"; - sshUser = "buildfarm"; - sshKey = "/root/.ssh/id_buildfarm"; - system = "x86_64-linux"; - maxJobs = 2; - supportedFeatures = [ "kvm" ]; - mandatoryFeatures = [ "perf" ]; - } - ]; + example = literalExample '' + [ { hostName = "voila.labs.cs.uu.nl"; + sshUser = "nix"; + sshKey = "/root/.ssh/id_buildfarm"; + system = "powerpc-darwin"; + maxJobs = 1; + } + { hostName = "linux64.example.org"; + sshUser = "buildfarm"; + sshKey = "/root/.ssh/id_buildfarm"; + system = "x86_64-linux"; + maxJobs = 2; + supportedFeatures = [ "kvm" ]; + mandatoryFeatures = [ "perf" ]; + } + ] + ''; description = '' This option lists the machines to be used if distributed builds are enabled (see @@ -380,7 +383,9 @@ in nix.envVars = { NIX_CONF_DIR = "/etc/nix"; + } + // optionalAttrs (!isNix112) { # Enable the copy-from-other-stores substituter, which allows # builds to be sped up by copying build results from remote # Nix stores. To do this, mount the remote file system on a @@ -389,9 +394,11 @@ in } // optionalAttrs cfg.distributedBuilds { - NIX_BUILD_HOOK = "${nix}/libexec/nix/build-remote.pl"; - NIX_REMOTE_SYSTEMS = "/etc/nix/machines"; - NIX_CURRENT_LOAD = "/run/nix/current-load"; + NIX_BUILD_HOOK = + if isNix112 then + "${nix}/libexec/nix/build-remote" + else + "${nix}/libexec/nix/build-remote.pl"; }; # Set up the environment variables for running Nix. diff --git a/nixos/modules/services/misc/nixos-manual.nix b/nixos/modules/services/misc/nixos-manual.nix index 306ee346523d..622607f3b32d 100644 --- a/nixos/modules/services/misc/nixos-manual.nix +++ b/nixos/modules/services/misc/nixos-manual.nix @@ -41,7 +41,7 @@ let entry = "${manual.manual}/share/doc/nixos/index.html"; - help = pkgs.writeScriptBin "nixos-help" + helpScript = pkgs.writeScriptBin "nixos-help" '' #! ${pkgs.stdenv.shell} -e browser="$BROWSER" @@ -58,6 +58,15 @@ let exec "$browser" ${entry} ''; + desktopItem = pkgs.makeDesktopItem { + name = "nixos-manual"; + desktopName = "NixOS Manual"; + genericName = "View NixOS documentation in a web browser"; + # TODO: find a better icon (Nix logo + help overlay?) + icon = "system-help"; + exec = "${helpScript}/bin/nixos-help"; + categories = "System"; + }; in { @@ -105,7 +114,8 @@ in system.build.manual = manual; environment.systemPackages = - [ manual.manual help ] + [ manual.manual helpScript ] + ++ optional config.services.xserver.enable desktopItem ++ optional config.programs.man.enable manual.manpages; boot.extraTTYs = mkIf cfg.showManual ["tty${toString cfg.ttyNumber}"]; diff --git a/nixos/modules/services/misc/octoprint.nix b/nixos/modules/services/misc/octoprint.nix index c2b3f63be7d4..8faad46a49f1 100644 --- a/nixos/modules/services/misc/octoprint.nix +++ b/nixos/modules/services/misc/octoprint.nix @@ -7,7 +7,7 @@ let cfg = config.services.octoprint; baseConfig = { - plugins.cura.cura_engine = "${pkgs.curaengine}/bin/CuraEngine"; + plugins.cura.cura_engine = "${pkgs.curaengine_stable}/bin/CuraEngine"; server.host = cfg.host; server.port = cfg.port; webcam.ffmpeg = "${pkgs.ffmpeg.bin}/bin/ffmpeg"; diff --git a/nixos/modules/services/misc/ssm-agent.nix b/nixos/modules/services/misc/ssm-agent.nix index b04959a9686a..c1e1f0903539 100644 --- a/nixos/modules/services/misc/ssm-agent.nix +++ b/nixos/modules/services/misc/ssm-agent.nix @@ -23,6 +23,7 @@ in { type = types.path; description = "The SSM agent package to use"; default = pkgs.ssm-agent; + defaultText = "pkgs.ssm-agent"; }; }; diff --git a/nixos/modules/services/misc/taskserver/default.nix b/nixos/modules/services/misc/taskserver/default.nix index d28c5dc7af85..826f463bbd75 100644 --- a/nixos/modules/services/misc/taskserver/default.nix +++ b/nixos/modules/services/misc/taskserver/default.nix @@ -94,44 +94,6 @@ let in flatten (mapAttrsToList mkSublist attrs); in all isNull (findPkiDefinitions [] manualPkiOptions); - configFile = pkgs.writeText "taskdrc" ('' - # systemd related - daemon = false - log = - - - # logging - ${mkConfLine "debug" cfg.debug} - ${mkConfLine "ip.log" cfg.ipLog} - - # general - ${mkConfLine "ciphers" cfg.ciphers} - ${mkConfLine "confirmation" cfg.confirmation} - ${mkConfLine "extensions" cfg.extensions} - ${mkConfLine "queue.size" cfg.queueSize} - ${mkConfLine "request.limit" cfg.requestLimit} - - # client - ${mkConfLine "client.allow" cfg.allowedClientIDs} - ${mkConfLine "client.deny" cfg.disallowedClientIDs} - - # server - server = ${cfg.listenHost}:${toString cfg.listenPort} - ${mkConfLine "trust" cfg.trust} - - # PKI options - ${if needToCreateCA then '' - ca.cert = ${cfg.dataDir}/keys/ca.cert - server.cert = ${cfg.dataDir}/keys/server.cert - server.key = ${cfg.dataDir}/keys/server.key - server.crl = ${cfg.dataDir}/keys/server.crl - '' else '' - ca.cert = ${cfg.pki.manual.ca.cert} - server.cert = ${cfg.pki.manual.server.cert} - server.key = ${cfg.pki.manual.server.key} - server.crl = ${cfg.pki.manual.server.crl} - ''} - '' + cfg.extraConfig); - orgOptions = { name, ... }: { options.users = mkOption { type = types.uniq (types.listOf types.str); @@ -154,9 +116,8 @@ let certtool = "${pkgs.gnutls.bin}/bin/certtool"; - nixos-taskserver = pkgs.pythonPackages.buildPythonPackage { + nixos-taskserver = pkgs.pythonPackages.buildPythonApplication { name = "nixos-taskserver"; - namePrefix = ""; src = pkgs.runCommand "nixos-taskserver-src" {} '' mkdir -p "$out" @@ -167,6 +128,7 @@ let certBits = cfg.pki.auto.bits; clientExpiration = cfg.pki.auto.expiration.client; crlExpiration = cfg.pki.auto.expiration.crl; + isAutoConfig = if needToCreateCA then "True" else "False"; }}" > "$out/main.py" cat > "$out/setup.py" <<EOF from setuptools import setup @@ -365,20 +327,57 @@ in { pki.manual = manualPkiOptions; pki.auto = autoPkiOptions; - extraConfig = mkOption { - type = types.lines; - default = ""; - example = "client.cert = /tmp/debugging.cert"; + config = mkOption { + type = types.attrs; + example.client.cert = "/tmp/debugging.cert"; description = '' - Extra lines to append to the taskdrc configuration file. + Configuration options to pass to Taskserver. + + The options here are the same as described in <citerefentry> + <refentrytitle>taskdrc</refentrytitle> + <manvolnum>5</manvolnum> + </citerefentry>, but with one difference: + + The <literal>server</literal> option is + <literal>server.listen</literal> here, because the + <literal>server</literal> option would collide with other options + like <literal>server.cert</literal> and we would run in a type error + (attribute set versus string). + + Nix types like integers or booleans are automatically converted to + the right values Taskserver would expect. ''; + apply = let + mkKey = path: if path == ["server" "listen"] then "server" + else concatStringsSep "." path; + recurse = path: attrs: let + mapper = name: val: let + newPath = path ++ [ name ]; + scalar = if val == true then "true" + else if val == false then "false" + else toString val; + in if isAttrs val then recurse newPath val + else [ "${mkKey newPath}=${scalar}" ]; + in concatLists (mapAttrsToList mapper attrs); + in recurse []; }; }; }; + imports = [ + (mkRemovedOptionModule ["services" "taskserver" "extraConfig"] '' + This option was removed in favor of `services.taskserver.config` with + different semantics (it's now a list of attributes instead of lines). + + Please look up the documentation of `services.taskserver.config' to get + more information about the new way to pass additional configuration + options. + '') + ]; + config = mkMerge [ (mkIf cfg.enable { - environment.systemPackages = [ pkgs.taskserver nixos-taskserver ]; + environment.systemPackages = [ nixos-taskserver ]; users.users = optional (cfg.user == "taskd") { name = "taskd"; @@ -392,6 +391,44 @@ in { gid = config.ids.gids.taskd; }; + services.taskserver.config = { + # systemd related + daemon = false; + log = "-"; + + # logging + debug = cfg.debug; + ip.log = cfg.ipLog; + + # general + ciphers = cfg.ciphers; + confirmation = cfg.confirmation; + extensions = cfg.extensions; + queue.size = cfg.queueSize; + request.limit = cfg.requestLimit; + + # client + client.allow = cfg.allowedClientIDs; + client.deny = cfg.disallowedClientIDs; + + # server + trust = cfg.trust; + server = { + listen = "${cfg.listenHost}:${toString cfg.listenPort}"; + } // (if needToCreateCA then { + cert = "${cfg.dataDir}/keys/server.cert"; + key = "${cfg.dataDir}/keys/server.key"; + crl = "${cfg.dataDir}/keys/server.crl"; + } else { + cert = "${cfg.pki.manual.server.cert}"; + key = "${cfg.pki.manual.server.key}"; + crl = "${cfg.pki.manual.server.crl}"; + }); + + ca.cert = if needToCreateCA then "${cfg.dataDir}/keys/ca.cert" + else "${cfg.pki.manual.ca.cert}"; + }; + systemd.services.taskserver-init = { wantedBy = [ "taskserver.service" ]; before = [ "taskserver.service" ]; @@ -404,7 +441,6 @@ in { script = '' ${taskd} init - echo "include ${configFile}" > "${cfg.dataDir}/config" touch "${cfg.dataDir}/.is_initialized" ''; @@ -436,7 +472,10 @@ in { in "${helperTool} process-json '${jsonFile}'"; serviceConfig = { - ExecStart = "@${taskd} taskd server"; + ExecStart = let + mkCfgFlag = flag: escapeShellArg "--${flag}"; + cfgFlags = concatMapStringsSep " " mkCfgFlag cfg.config; + in "@${taskd} taskd server ${cfgFlags}"; ExecReload = "${pkgs.coreutils}/bin/kill -USR1 $MAINPID"; Restart = "on-failure"; PermissionsStartOnly = true; diff --git a/nixos/modules/services/misc/taskserver/doc.xml b/nixos/modules/services/misc/taskserver/doc.xml index 48591129264a..6d4d2a9b488c 100644 --- a/nixos/modules/services/misc/taskserver/doc.xml +++ b/nixos/modules/services/misc/taskserver/doc.xml @@ -136,9 +136,9 @@ $ ssh server nixos-taskserver user export my-company alice | sh <para> If you set any options within - <option>service.taskserver.pki.manual.*</option>, the automatic user and - CA management by the <command>nixos-taskserver</command> is disabled and - you need to create certificates and keys by yourself. + <option>service.taskserver.pki.manual.*</option>, + <command>nixos-taskserver</command> won't issue certificates, but you can + still use it for adding or removing user accounts. </para> </section> </chapter> diff --git a/nixos/modules/services/misc/taskserver/helper-tool.py b/nixos/modules/services/misc/taskserver/helper-tool.py index 03e7cdf8987a..b97bc1df74f7 100644 --- a/nixos/modules/services/misc/taskserver/helper-tool.py +++ b/nixos/modules/services/misc/taskserver/helper-tool.py @@ -13,6 +13,7 @@ from tempfile import NamedTemporaryFile import click +IS_AUTO_CONFIG = @isAutoConfig@ # NOQA CERTTOOL_COMMAND = "@certtool@" CERT_BITS = "@certBits@" CLIENT_EXPIRATION = "@clientExpiration@" @@ -149,6 +150,12 @@ def create_template(contents): def generate_key(org, user): + if not IS_AUTO_CONFIG: + msg = "Automatic PKI handling is disabled, you need to " \ + "manually issue a client certificate for user {}.\n" + sys.stderr.write(msg.format(user)) + return + basedir = os.path.join(TASKD_DATA_DIR, "keys", org, user) if os.path.exists(basedir): raise OSError("Keyfile directory for {} already exists.".format(user)) @@ -243,26 +250,32 @@ class User(object): self.key = key def export(self): - pubcert = getkey(self.__org, self.name, "public.cert") - privkey = getkey(self.__org, self.name, "private.key") - cacert = getkey("ca.cert") - - keydir = "${TASKDATA:-$HOME/.task}/keys" - credentials = '/'.join([self.__org, self.name, self.key]) allow_unquoted = string.ascii_letters + string.digits + "/-_." if not all((c in allow_unquoted) for c in credentials): credentials = "'" + credentials.replace("'", r"'\''") + "'" - script = [ - "umask 0077", - 'mkdir -p "{}"'.format(keydir), - mktaskkey("certificate", os.path.join(keydir, "public.cert"), - pubcert), - mktaskkey("key", os.path.join(keydir, "private.key"), privkey), - mktaskkey("ca", os.path.join(keydir, "ca.cert"), cacert), + script = [] + + if IS_AUTO_CONFIG: + pubcert = getkey(self.__org, self.name, "public.cert") + privkey = getkey(self.__org, self.name, "private.key") + cacert = getkey("ca.cert") + + keydir = "${TASKDATA:-$HOME/.task}/keys" + + script += [ + "umask 0077", + 'mkdir -p "{}"'.format(keydir), + mktaskkey("certificate", os.path.join(keydir, "public.cert"), + pubcert), + mktaskkey("key", os.path.join(keydir, "private.key"), privkey), + mktaskkey("ca", os.path.join(keydir, "ca.cert"), cacert) + ] + + script.append( "task config taskd.credentials -- {}".format(credentials) - ] + ) return "\n".join(script) + "\n" @@ -526,7 +539,7 @@ def export_user(organisation, user): userobj = organisation.get_user(user) if userobj is None: msg = "User {} doesn't exist in organisation {}." - sys.exit(msg.format(userobj.name, organisation.name)) + sys.exit(msg.format(user, organisation.name)) sys.stdout.write(userobj.export()) diff --git a/nixos/modules/services/monitoring/das_watchdog.nix b/nixos/modules/services/monitoring/das_watchdog.nix index 6e2653836d5e..88ca3a9227d2 100644 --- a/nixos/modules/services/monitoring/das_watchdog.nix +++ b/nixos/modules/services/monitoring/das_watchdog.nix @@ -25,7 +25,7 @@ in { wantedBy = [ "multi-user.target" ]; serviceConfig = { User = "root"; - Type = "oneshot"; + Type = "simple"; ExecStart = "${das_watchdog}/bin/das_watchdog"; RemainAfterExit = true; }; diff --git a/nixos/modules/services/monitoring/munin.nix b/nixos/modules/services/monitoring/munin.nix index 6d2ce5383687..364f18e7543d 100644 --- a/nixos/modules/services/monitoring/munin.nix +++ b/nixos/modules/services/monitoring/munin.nix @@ -76,6 +76,7 @@ let # wrapped plugins by makeWrapper being with dots ignore_file ^\. + allow ^::1$ allow ^127\.0\.0\.1$ ${nodeCfg.extraConfig} diff --git a/nixos/modules/services/monitoring/prometheus/default.nix b/nixos/modules/services/monitoring/prometheus/default.nix index a07445ce167c..cf9deccbffe2 100644 --- a/nixos/modules/services/monitoring/prometheus/default.nix +++ b/nixos/modules/services/monitoring/prometheus/default.nix @@ -134,6 +134,7 @@ let }; }); default = null; + apply = x: if x == null then null else _filter x; description = '' Optional http login credentials for metrics scraping. ''; diff --git a/nixos/modules/services/monitoring/prometheus/fritzbox-exporter.nix b/nixos/modules/services/monitoring/prometheus/fritzbox-exporter.nix new file mode 100644 index 000000000000..6da39b6519cb --- /dev/null +++ b/nixos/modules/services/monitoring/prometheus/fritzbox-exporter.nix @@ -0,0 +1,76 @@ +{ config, pkgs, lib, ... }: + +with lib; + +let + cfg = config.services.prometheus.fritzboxExporter; +in { + options = { + services.prometheus.fritzboxExporter = { + enable = mkEnableOption "prometheus fritzbox exporter"; + + port = mkOption { + type = types.int; + default = 9133; + description = '' + Port to listen on. + ''; + }; + + gatewayAddress = mkOption { + type = types.str; + default = "fritz.box"; + description = '' + The hostname or IP of the FRITZ!Box. + ''; + }; + + gatewayPort = mkOption { + type = types.int; + default = 49000; + description = '' + The port of the FRITZ!Box UPnP service. + ''; + }; + + extraFlags = mkOption { + type = types.listOf types.str; + default = []; + description = '' + Extra commandline options when launching the fritzbox exporter. + ''; + }; + + openFirewall = mkOption { + type = types.bool; + default = false; + description = '' + Open port in firewall for incoming connections. + ''; + }; + }; + }; + + config = mkIf cfg.enable { + networking.firewall.allowedTCPPorts = optional cfg.openFirewall cfg.port; + + systemd.services.prometheus-fritzbox-exporter = { + description = "Prometheus exporter for FRITZ!Box via UPnP"; + unitConfig.Documentation = "https://github.com/ndecker/fritzbox_exporter"; + wantedBy = [ "multi-user.target" ]; + serviceConfig = { + User = "nobody"; + Restart = "always"; + PrivateTmp = true; + WorkingDirectory = /tmp; + ExecStart = '' + ${pkgs.prometheus-fritzbox-exporter}/bin/fritzbox_exporter \ + -listen-address :${toString cfg.port} \ + -gateway-address ${cfg.gatewayAddress} \ + -gateway-port ${toString cfg.gatewayPort} \ + ${concatStringsSep " \\\n " cfg.extraFlags} + ''; + }; + }; + }; +} diff --git a/nixos/modules/services/monitoring/vnstat.nix b/nixos/modules/services/monitoring/vnstat.nix index f6be7c7fd34a..ca56e4a7b958 100644 --- a/nixos/modules/services/monitoring/vnstat.nix +++ b/nixos/modules/services/monitoring/vnstat.nix @@ -32,7 +32,7 @@ in { preStart = "chmod 755 /var/lib/vnstat"; serviceConfig = { ExecStart = "${pkgs.vnstat}/bin/vnstatd -n"; - ExecReload = "kill -HUP $MAINPID"; + ExecReload = "${pkgs.procps}/bin/kill -HUP $MAINPID"; ProtectHome = true; PrivateDevices = true; PrivateTmp = true; diff --git a/nixos/modules/services/network-filesystems/samba.nix b/nixos/modules/services/network-filesystems/samba.nix index 09a11585bc92..6ae5292fc303 100644 --- a/nixos/modules/services/network-filesystems/samba.nix +++ b/nixos/modules/services/network-filesystems/samba.nix @@ -91,6 +91,26 @@ in ''; }; + enableNmbd = mkOption { + type = types.bool; + default = true; + description = '' + Whether to enable Samba's nmbd, which replies to NetBIOS over IP name + service requests. It also participates in the browsing protocols + which make up the Windows "Network Neighborhood" view. + ''; + }; + + enableWinbindd = mkOption { + type = types.bool; + default = true; + description = '' + Whether to enable Samba's winbindd, which provides a number of services + to the Name Service Switch capability found in most modern C libraries, + to arbitrary applications via PAM and ntlm_auth and to Samba itself. + ''; + }; + package = mkOption { type = types.package; default = pkgs.samba; @@ -185,7 +205,12 @@ in ###### implementation config = mkMerge - [ { # Always provide a smb.conf to shut up programs like smbclient and smbspool. + [ { assertions = + [ { assertion = cfg.nsswins -> cfg.enableWinbindd; + message = "If samba.nsswins is enabled, then samba.enableWinbindd must also be enabled"; + } + ]; + # Always provide a smb.conf to shut up programs like smbclient and smbspool. environment.etc = singleton { source = if cfg.enable then configFile @@ -194,7 +219,7 @@ in }; } - (mkIf config.services.samba.enable { + (mkIf cfg.enable { system.nssModules = optional cfg.nsswins samba; @@ -207,9 +232,9 @@ in }; services = { - "samba-nmbd" = daemonService "nmbd" "-F"; "samba-smbd" = daemonService "smbd" "-F"; - "samba-winbindd" = daemonService "winbindd" "-F"; + "samba-nmbd" = mkIf cfg.enableNmbd (daemonService "nmbd" "-F"); + "samba-winbindd" = mkIf cfg.enableWinbindd (daemonService "winbindd" "-F"); "samba-setup" = { description = "Samba Setup Task"; script = setupScript; diff --git a/nixos/modules/services/network-filesystems/tahoe.nix b/nixos/modules/services/network-filesystems/tahoe.nix index f63f641d00be..3d78ac096a2b 100644 --- a/nixos/modules/services/network-filesystems/tahoe.nix +++ b/nixos/modules/services/network-filesystems/tahoe.nix @@ -8,7 +8,7 @@ in options.services.tahoe = { introducers = mkOption { default = {}; - type = with types; loaOf (submodule { + type = with types; attrsOf (submodule { options = { nickname = mkOption { type = types.str; @@ -49,7 +49,7 @@ in }; nodes = mkOption { default = {}; - type = with types; loaOf (submodule { + type = with types; attrsOf (submodule { options = { nickname = mkOption { type = types.str; diff --git a/nixos/modules/services/networking/btsync.nix b/nixos/modules/services/networking/btsync.nix index 572a7387316b..92e9fa7be419 100644 --- a/nixos/modules/services/networking/btsync.nix +++ b/nixos/modules/services/networking/btsync.nix @@ -208,7 +208,6 @@ in storagePath = mkOption { type = types.path; default = "/var/lib/btsync/"; - example = "/var/lib/btsync/"; description = '' Where BitTorrent Sync will store it's database files (containing things like username info and licenses). Generally, you should not diff --git a/nixos/modules/services/networking/ddclient.nix b/nixos/modules/services/networking/ddclient.nix index 5928203368d2..28c96a9baefc 100644 --- a/nixos/modules/services/networking/ddclient.nix +++ b/nixos/modules/services/networking/ddclient.nix @@ -7,7 +7,7 @@ let stateDir = "/var/spool/ddclient"; ddclientUser = "ddclient"; - ddclientFlags = "-foreground -verbose -noquiet -file ${config.services.ddclient.configFile}"; + ddclientFlags = "-foreground -file ${config.services.ddclient.configFile}"; ddclientPIDFile = "${stateDir}/ddclient.pid"; in @@ -102,6 +102,22 @@ in Method to determine the IP address to send to the dynamic DNS provider. ''; }; + + verbose = mkOption { + default = true; + type = bool; + description = '' + Print verbose information. + ''; + }; + + quiet = mkOption { + default = false; + type = bool; + description = '' + Print no messages for unnecessary updates. + ''; + }; }; }; @@ -136,6 +152,8 @@ in lib.optionalString (server != "") "server=${server}"} ssl=${if config.services.ddclient.ssl then "yes" else "no"} wildcard=YES + quiet=${if config.services.ddclient.quiet then "yes" else "no"} + verbose=${if config.services.ddclient.verbose then "yes" else "no"} ${config.services.ddclient.domain} ${config.services.ddclient.extraConfig} ''; diff --git a/nixos/modules/services/networking/dhcpcd.nix b/nixos/modules/services/networking/dhcpcd.nix index 87c0aa50a1ff..7eeceb7407c6 100644 --- a/nixos/modules/services/networking/dhcpcd.nix +++ b/nixos/modules/services/networking/dhcpcd.nix @@ -157,7 +157,7 @@ in systemd.services.dhcpcd = { description = "DHCP Client"; - wantedBy = [ "multi-user.target" ]; + wantedBy = [ "network-online.target" ]; after = [ "network.target" ]; wants = [ "network.target" ]; @@ -173,7 +173,7 @@ in serviceConfig = { Type = "forking"; PIDFile = "/run/dhcpcd.pid"; - ExecStart = "@${dhcpcd}/sbin/dhcpcd dhcpcd --quiet ${optionalString cfg.persistent "--persistent"} --config ${dhcpcdConf}"; + ExecStart = "@${dhcpcd}/sbin/dhcpcd dhcpcd -w --quiet ${optionalString cfg.persistent "--persistent"} --config ${dhcpcdConf}"; ExecReload = "${dhcpcd}/sbin/dhcpcd --rebind"; Restart = "always"; }; diff --git a/nixos/modules/services/networking/dhcpd.nix b/nixos/modules/services/networking/dhcpd.nix index 86bcaa96f345..2eac6dfec5b7 100644 --- a/nixos/modules/services/networking/dhcpd.nix +++ b/nixos/modules/services/networking/dhcpd.nix @@ -60,8 +60,9 @@ let }; }; - machineOpts = {...}: { - config = { + machineOpts = { ... }: { + + options = { hostName = mkOption { type = types.str; @@ -156,7 +157,7 @@ let }; machines = mkOption { - type = types.listOf (types.submodule machineOpts); + type = with types; listOf (submodule machineOpts); default = []; example = [ { hostName = "foo"; diff --git a/nixos/modules/services/networking/dnscrypt-proxy.nix b/nixos/modules/services/networking/dnscrypt-proxy.nix index 462039803f80..d382fa8c9cb2 100644 --- a/nixos/modules/services/networking/dnscrypt-proxy.nix +++ b/nixos/modules/services/networking/dnscrypt-proxy.nix @@ -2,12 +2,9 @@ with lib; let - apparmorEnabled = config.security.apparmor.enable; - dnscrypt-proxy = pkgs.dnscrypt-proxy; cfg = config.services.dnscrypt-proxy; - stateDirectory = "/var/lib/dnscrypt-proxy"; - localAddress = "${cfg.localAddress}:${toString cfg.localPort}"; + stateDirectory = "/var/lib/dnscrypt-proxy"; # The minisign public key used to sign the upstream resolver list. # This is somewhat more flexible than preloading the key as an @@ -17,31 +14,33 @@ let sha256 = "18lnp8qr6ghfc2sd46nn1rhcpr324fqlvgsp4zaigw396cd7vnnh"; }; - # Internal flag indicating whether the upstream resolver list is used - useUpstreamResolverList = cfg.resolverList == null && cfg.customResolver == null; - - resolverList = - if (cfg.resolverList != null) - then cfg.resolverList - else "${stateDirectory}/dnscrypt-resolvers.csv"; - - resolverArgs = if (cfg.customResolver != null) - then - [ "--resolver-address=${cfg.customResolver.address}:${toString cfg.customResolver.port}" - "--provider-name=${cfg.customResolver.name}" - "--provider-key=${cfg.customResolver.key}" - ] - else - [ "--resolvers-list=${resolverList}" - "--resolver-name=${cfg.resolverName}" - ]; - - # The final command line arguments passed to the daemon + # Internal flag indicating whether the upstream resolver list is used. + useUpstreamResolverList = cfg.customResolver == null; + + # The final local address. + localAddress = "${cfg.localAddress}:${toString cfg.localPort}"; + + # The final resolvers list path. + resolverList = "${stateDirectory}/dnscrypt-resolvers.csv"; + + # Build daemon command line + + resolverArgs = + if (cfg.customResolver == null) + then + [ "-L ${resolverList}" + "-R ${cfg.resolverName}" + ] + else with cfg.customResolver; + [ "-N ${name}" + "-k ${key}" + "-r ${address}:${toString port}" + ]; + daemonArgs = - [ "--local-address=${localAddress}" ] - ++ optional cfg.tcpOnly "--tcp-only" - ++ optional cfg.ephemeralKeys "-E" - ++ resolverArgs; + [ "-a ${localAddress}" ] + ++ resolverArgs + ++ cfg.extraArgs; in { @@ -51,6 +50,9 @@ in }; options = { + # Before adding another option, consider whether it could + # equally well be passed via extraArgs. + services.dnscrypt-proxy = { enable = mkOption { default = false; @@ -83,19 +85,11 @@ in default = "dnscrypt.eu-nl"; type = types.nullOr types.str; description = '' - The name of the upstream DNSCrypt resolver to use, taken from - <filename>${resolverList}</filename>. The default resolver is - located in Holland, supports DNS security extensions, and - <emphasis>claims</emphasis> to not keep logs. - ''; - }; - - resolverList = mkOption { - default = null; - type = types.nullOr types.path; - description = '' - List of DNSCrypt resolvers. The default is to use the list of - public resolvers provided by upstream. + The name of the DNSCrypt resolver to use, taken from + <filename>${resolverList}</filename>. The default + resolver is located in Holland, supports DNS security + extensions, and <emphasis>claims</emphasis> to not + keep logs. ''; }; @@ -121,7 +115,7 @@ in name = mkOption { type = types.str; description = "Fully qualified domain name"; - example = "2.dnscrypt-cert.opendns.com"; + example = "2.dnscrypt-cert.example.com"; }; key = mkOption { @@ -132,39 +126,72 @@ in }; })); }; - tcpOnly = mkOption { - default = false; - type = types.bool; - description = '' - Force sending encrypted DNS queries to the upstream resolver over - TCP instead of UDP (on port 443). Use only if the UDP port is blocked. - ''; - }; - - ephemeralKeys = mkOption { - default = false; - type = types.bool; + extraArgs = mkOption { + default = []; + type = types.listOf types.str; description = '' - Compute a new key pair for every query. Enabling this option - increases CPU usage, but makes it more difficult for the upstream - resolver to track your usage of their service across IP addresses. - The default is to re-use the public key pair for all queries, making - tracking trivial. + Additional command-line arguments passed verbatim to the daemon. + See <citerefentry><refentrytitle>dnscrypt-proxy</refentrytitle> + <manvolnum>8</manvolnum></citerefentry> for details. ''; + example = [ "-X libdcplugin_example_cache.so,--min-ttl=60" ]; }; }; }; - config = mkIf cfg.enable { - + config = mkIf cfg.enable (mkMerge [{ assertions = [ { assertion = (cfg.customResolver != null) || (cfg.resolverName != null); message = "please configure upstream DNSCrypt resolver"; } ]; - security.apparmor.profiles = optional apparmorEnabled (pkgs.writeText "apparmor-dnscrypt-proxy" '' - ${dnscrypt-proxy}/bin/dnscrypt-proxy { + users.users.dnscrypt-proxy = { + description = "dnscrypt-proxy daemon user"; + isSystemUser = true; + group = "dnscrypt-proxy"; + }; + users.groups.dnscrypt-proxy = {}; + + systemd.sockets.dnscrypt-proxy = { + description = "dnscrypt-proxy listening socket"; + documentation = [ "man:dnscrypt-proxy(8)" ]; + + wantedBy = [ "sockets.target" ]; + + socketConfig = { + ListenStream = localAddress; + ListenDatagram = localAddress; + }; + }; + + systemd.services.dnscrypt-proxy = { + description = "dnscrypt-proxy daemon"; + documentation = [ "man:dnscrypt-proxy(8)" ]; + + before = [ "nss-lookup.target" ]; + after = [ "network.target" ]; + requires = [ "dnscrypt-proxy.socket "]; + + serviceConfig = { + NonBlocking = "true"; + ExecStart = "${pkgs.dnscrypt-proxy}/bin/dnscrypt-proxy ${toString daemonArgs}"; + ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID"; + + User = "dnscrypt-proxy"; + + PrivateTmp = true; + PrivateDevices = true; + ProtectHome = true; + }; + }; + } + + (mkIf config.security.apparmor.enable { + systemd.services.dnscrypt-proxy.after = [ "apparmor.service" ]; + + security.apparmor.profiles = singleton (pkgs.writeText "apparmor-dnscrypt-proxy" '' + ${pkgs.dnscrypt-proxy}/bin/dnscrypt-proxy { /dev/null rw, /dev/urandom r, @@ -180,6 +207,8 @@ in network inet dgram, network inet6 dgram, + ${getLib pkgs.dnscrypt-proxy}/lib/dnscrypt-proxy/libdcplugin*.so mr, + ${getLib pkgs.gcc.cc}/lib/libssp.so.* mr, ${getLib pkgs.libsodium}/lib/libsodium.so.* mr, ${getLib pkgs.systemd}/lib/libsystemd.so.* mr, @@ -188,102 +217,104 @@ in ${getLib pkgs.libgpgerror}/lib/libgpg-error.so.* mr, ${getLib pkgs.libcap}/lib/libcap.so.* mr, ${getLib pkgs.lz4}/lib/liblz4.so.* mr, - ${getLib pkgs.attr}/lib/libattr.so.* mr, + ${getLib pkgs.attr}/lib/libattr.so.* mr, # */ ${resolverList} r, } ''); + }) - users.users.dnscrypt-proxy = { - description = "dnscrypt-proxy daemon user"; - isSystemUser = true; - group = "dnscrypt-proxy"; - }; - users.groups.dnscrypt-proxy = {}; - - systemd.services.init-dnscrypt-proxy-statedir = optionalAttrs useUpstreamResolverList { + (mkIf useUpstreamResolverList { + systemd.services.init-dnscrypt-proxy-statedir = { description = "Initialize dnscrypt-proxy state directory"; + + wantedBy = [ "dnscrypt-proxy.service" ]; + before = [ "dnscrypt-proxy.service" ]; + script = '' mkdir -pv ${stateDirectory} chown -c dnscrypt-proxy:dnscrypt-proxy ${stateDirectory} - cp --preserve=timestamps -uv \ + cp -uv \ ${pkgs.dnscrypt-proxy}/share/dnscrypt-proxy/dnscrypt-resolvers.csv \ ${stateDirectory} ''; + serviceConfig = { Type = "oneshot"; RemainAfterExit = true; }; }; - systemd.services.update-dnscrypt-resolvers = optionalAttrs useUpstreamResolverList { + systemd.services.update-dnscrypt-resolvers = { description = "Update list of DNSCrypt resolvers"; requires = [ "init-dnscrypt-proxy-statedir.service" ]; after = [ "init-dnscrypt-proxy-statedir.service" ]; - path = with pkgs; [ curl minisign ]; + path = with pkgs; [ curl diffutils dnscrypt-proxy minisign ]; script = '' cd ${stateDirectory} - curl -fSsL -o dnscrypt-resolvers.csv.tmp \ - https://download.dnscrypt.org/dnscrypt-proxy/dnscrypt-resolvers.csv - curl -fSsL -o dnscrypt-resolvers.csv.minisig.tmp \ - https://download.dnscrypt.org/dnscrypt-proxy/dnscrypt-resolvers.csv.minisig + domain=raw.githubusercontent.com + get="curl -fSs --resolve $domain:443:$(hostip -r 8.8.8.8 $domain | head -1)" + $get -o dnscrypt-resolvers.csv.tmp \ + https://$domain/jedisct1/dnscrypt-proxy/master/dnscrypt-resolvers.csv + $get -o dnscrypt-resolvers.csv.minisig.tmp \ + https://$domain/jedisct1/dnscrypt-proxy/master/dnscrypt-resolvers.csv.minisig mv dnscrypt-resolvers.csv.minisig{.tmp,} - minisign -q -V -p ${upstreamResolverListPubKey} \ - -m dnscrypt-resolvers.csv.tmp -x dnscrypt-resolvers.csv.minisig + if ! minisign -q -V -p ${upstreamResolverListPubKey} \ + -m dnscrypt-resolvers.csv.tmp -x dnscrypt-resolvers.csv.minisig ; then + echo "failed to verify resolver list!" >&2 + exit 1 + fi + [[ -f dnscrypt-resolvers.csv ]] && mv dnscrypt-resolvers.csv{,.old} mv dnscrypt-resolvers.csv{.tmp,} + if cmp dnscrypt-resolvers.csv{,.old} ; then + echo "no change" + else + echo "resolver list updated" + fi ''; serviceConfig = { PrivateTmp = true; PrivateDevices = true; ProtectHome = true; - ProtectSystem = true; + ProtectSystem = "strict"; + ReadWritePaths = "${dirOf stateDirectory} ${stateDirectory}"; + SystemCallFilter = "~@mount"; }; }; - systemd.timers.update-dnscrypt-resolvers = optionalAttrs useUpstreamResolverList { + systemd.timers.update-dnscrypt-resolvers = { + wantedBy = [ "timers.target" ]; timerConfig = { OnBootSec = "5min"; OnUnitActiveSec = "6h"; }; - wantedBy = [ "timers.target" ]; - }; - - systemd.sockets.dnscrypt-proxy = { - description = "dnscrypt-proxy listening socket"; - socketConfig = { - ListenStream = localAddress; - ListenDatagram = localAddress; - }; - wantedBy = [ "sockets.target" ]; }; - - systemd.services.dnscrypt-proxy = { - description = "dnscrypt-proxy daemon"; - - before = [ "nss-lookup.target" ]; - - after = [ "network.target" ] - ++ optional apparmorEnabled "apparmor.service" - ++ optional useUpstreamResolverList "init-dnscrypt-proxy-statedir.service"; - - requires = [ "dnscrypt-proxy.socket "] - ++ optional apparmorEnabled "apparmor.service" - ++ optional useUpstreamResolverList "init-dnscrypt-proxy-statedir.service"; - - serviceConfig = { - Type = "simple"; - NonBlocking = "true"; - ExecStart = "${dnscrypt-proxy}/bin/dnscrypt-proxy ${toString daemonArgs}"; - - User = "dnscrypt-proxy"; - - PrivateTmp = true; - PrivateDevices = true; - ProtectHome = true; - }; - }; - }; + }) + ]); + + imports = [ + (mkRenamedOptionModule [ "services" "dnscrypt-proxy" "port" ] [ "services" "dnscrypt-proxy" "localPort" ]) + + (mkChangedOptionModule + [ "services" "dnscrypt-proxy" "tcpOnly" ] + [ "services" "dnscrypt-proxy" "extraArgs" ] + (config: + let val = getAttrFromPath [ "services" "dnscrypt-proxy" "tcpOnly" ] config; in + optional val "-T")) + + (mkChangedOptionModule + [ "services" "dnscrypt-proxy" "ephemeralKeys" ] + [ "services" "dnscrypt-proxy" "extraArgs" ] + (config: + let val = getAttrFromPath [ "services" "dnscrypt-proxy" "ephemeralKeys" ] config; in + optional val "-E")) + + (mkRemovedOptionModule [ "services" "dnscrypt-proxy" "resolverList" ] '' + The current resolver listing from upstream is always used + unless a custom resolver is specified. + '') + ]; } diff --git a/nixos/modules/services/networking/dnscrypt-proxy.xml b/nixos/modules/services/networking/dnscrypt-proxy.xml index 982961833ad2..555c6df4d551 100644 --- a/nixos/modules/services/networking/dnscrypt-proxy.xml +++ b/nixos/modules/services/networking/dnscrypt-proxy.xml @@ -31,15 +31,12 @@ </sect1> - <sect1><title>As a forwarder for a caching DNS client</title> + <sect1><title>As a forwarder for another DNS client</title> <para> - By default, DNSCrypt proxy acts as a transparent proxy for the - system stub resolver. Because the client does not cache lookups, this - setup can significantly slow down e.g., web browsing. The recommended - configuration is to run DNSCrypt proxy as a forwarder for a caching DNS - client. To achieve this, change the default proxy listening port to - a non-standard value and point the caching client to it: + To run the DNSCrypt proxy client as a forwarder for another + DNS client, change the default proxy listening port to a + non-standard value and point the other client to it: <programlisting> services.dnscrypt-proxy.localPort = 43; </programlisting> @@ -60,7 +57,6 @@ <para> <programlisting> { - networking.nameservers = [ "127.0.0.1" ]; services.unbound.enable = true; services.unbound.forwardAddresses = [ "127.0.0.1@43" ]; } diff --git a/nixos/modules/services/networking/networkmanager.nix b/nixos/modules/services/networking/networkmanager.nix index c11d4434c206..7255ffc5af4b 100644 --- a/nixos/modules/services/networking/networkmanager.nix +++ b/nixos/modules/services/networking/networkmanager.nix @@ -24,6 +24,8 @@ let [connection] ipv6.ip6-privacy=2 + ethernet.cloned-mac-address=${cfg.ethernet.macAddress} + wifi.cloned-mac-address=${cfg.wifi.macAddress} ''; /* @@ -73,6 +75,19 @@ let "pre-down" = "pre-down.d/"; }; + macAddressOpt = mkOption { + type = types.either types.str (types.enum ["permanent" "preserve" "random" "stable"]); + default = "preserve"; + example = "00:11:22:33:44:55"; + description = '' + "XX:XX:XX:XX:XX:XX": MAC address of the interface. + <literal>permanent</literal>: use the permanent MAC address of the device. + <literal>preserve</literal>: don’t change the MAC address of the device upon activation. + <literal>random</literal>: generate a randomized value upon each connect. + <literal>stable</literal>: generate a stable, hashed MAC address. + ''; + }; + in { ###### interface @@ -140,6 +155,9 @@ in { ''; }; + ethernet.macAddress = macAddressOpt; + wifi.macAddress = macAddressOpt; + dispatcherScripts = mkOption { type = types.listOf (types.submodule { options = { @@ -229,6 +247,7 @@ in { systemd.services."network-manager" = { wantedBy = [ "network.target" ]; + restartTriggers = [ configFile ]; preStart = '' mkdir -m 700 -p /etc/NetworkManager/system-connections diff --git a/nixos/modules/services/networking/nftables.nix b/nixos/modules/services/networking/nftables.nix new file mode 100644 index 000000000000..029c3df89932 --- /dev/null +++ b/nixos/modules/services/networking/nftables.nix @@ -0,0 +1,125 @@ +{ config, pkgs, lib, ... }: +with lib; +let + cfg = config.networking.nftables; +in +{ + ###### interface + + options = { + networking.nftables.enable = mkOption { + type = types.bool; + default = false; + description = + '' + Whether to enable nftables. nftables is a Linux-based packet + filtering framework intended to replace frameworks like iptables. + + This conflicts with the standard networking firewall, so make sure to + disable it before using nftables. + ''; + }; + networking.nftables.ruleset = mkOption { + type = types.lines; + example = '' + # Check out https://wiki.nftables.org/ for better documentation. + # Table for both IPv4 and IPv6. + table inet filter { + # Block all incomming connections traffic except SSH and "ping". + chain input { + type filter hook input priority 0; + + # accept any localhost traffic + iifname lo accept + + # accept traffic originated from us + ct state {established, related} accept + + # ICMP + # routers may also want: mld-listener-query, nd-router-solicit + ip6 nexthdr icmpv6 icmpv6 type { destination-unreachable, packet-too-big, time-exceeded, parameter-problem, nd-router-advert, nd-neighbor-solicit, nd-neighbor-advert } accept + ip protocol icmp icmp type { destination-unreachable, router-advertisement, time-exceeded, parameter-problem } accept + + # allow "ping" + ip6 nexthdr icmp icmpv6 type echo-request accept + ip protocol icmp icmp type echo-request accept + + # accept SSH connections (required for a server) + tcp dport 22 accept + + # count and drop any other traffic + counter drop + } + + # Allow all outgoing connections. + chain output { + type filter hook output priority 0; + accept + } + + chain forward { + type filter hook forward priority 0; + accept + } + } + ''; + description = + '' + The ruleset to be used with nftables. Should be in a format that + can be loaded using "/bin/nft -f". The ruleset is updated atomically. + ''; + }; + networking.nftables.rulesetFile = mkOption { + type = types.path; + default = pkgs.writeTextFile { + name = "nftables-rules"; + text = cfg.ruleset; + }; + description = + '' + The ruleset file to be used with nftables. Should be in a format that + can be loaded using "nft -f". The ruleset is updated atomically. + ''; + }; + }; + + ###### implementation + + config = mkIf cfg.enable { + assertions = [{ + assertion = config.networking.firewall.enable == false; + message = "You can not use nftables with services.networking.firewall."; + }]; + boot.blacklistedKernelModules = [ "ip_tables" ]; + environment.systemPackages = [ pkgs.nftables ]; + systemd.services.nftables = { + description = "nftables firewall"; + before = [ "network-pre.target" ]; + wants = [ "network-pre.target" ]; + wantedBy = [ "multi-user.target" ]; + reloadIfChanged = true; + serviceConfig = let + rulesScript = pkgs.writeScript "nftables-rules" '' + #! ${pkgs.nftables}/bin/nft -f + flush ruleset + include "${cfg.rulesetFile}" + ''; + checkScript = pkgs.writeScript "nftables-check" '' + #! ${pkgs.stdenv.shell} -e + if $(${pkgs.kmod}/bin/lsmod | grep -q ip_tables); then + echo "Unload ip_tables before using nftables!" 1>&2 + exit 1 + else + ${rulesScript} + fi + ''; + in { + Type = "oneshot"; + RemainAfterExit = true; + ExecStart = checkScript; + ExecReload = checkScript; + ExecStop = "${pkgs.nftables}/bin/nft flush ruleset"; + }; + }; + }; +} diff --git a/nixos/modules/services/networking/openntpd.nix b/nixos/modules/services/networking/openntpd.nix index 13a1b5258ce0..4bb9da54fe09 100644 --- a/nixos/modules/services/networking/openntpd.nix +++ b/nixos/modules/services/networking/openntpd.nix @@ -11,6 +11,9 @@ let ${concatStringsSep "\n" (map (s: "server ${s}") cfg.servers)} ${cfg.extraConfig} ''; + + pidFile = "/run/openntpd.pid"; + in { ###### interface @@ -67,7 +70,11 @@ in wants = [ "network-online.target" "time-sync.target" ]; before = [ "time-sync.target" ]; after = [ "dnsmasq.service" "bind.service" "network-online.target" ]; - serviceConfig.ExecStart = "${package}/sbin/ntpd -d -f ${cfgFile} ${cfg.extraOptions}"; + serviceConfig = { + ExecStart = "${package}/sbin/ntpd -f ${cfgFile} -p ${pidFile} ${cfg.extraOptions}"; + Type = "forking"; + PIDFile = pidFile; + }; }; }; } diff --git a/nixos/modules/services/networking/prosody.nix b/nixos/modules/services/networking/prosody.nix index 5682b506344c..feaa007de15e 100644 --- a/nixos/modules/services/networking/prosody.nix +++ b/nixos/modules/services/networking/prosody.nix @@ -265,7 +265,8 @@ in systemd.services.prosody = { description = "Prosody XMPP server"; - after = [ "network.target" ]; + after = [ "network-online.target" ]; + wants = [ "network-online.target" ]; wantedBy = [ "multi-user.target" ]; serviceConfig = { User = "prosody"; diff --git a/nixos/modules/services/networking/searx.nix b/nixos/modules/services/networking/searx.nix index b852e4e6dc86..3520c6d3f7da 100644 --- a/nixos/modules/services/networking/searx.nix +++ b/nixos/modules/services/networking/searx.nix @@ -19,6 +19,7 @@ in services.searx = { enable = mkOption { + type = types.bool; default = false; description = " Whether to enable the Searx server. See https://github.com/asciimoo/searx @@ -26,6 +27,7 @@ in }; configFile = mkOption { + type = types.path; default = ""; description = " The path of the Searx server configuration file. If no file @@ -35,7 +37,9 @@ in }; package = mkOption { + type = types.package; default = pkgs.pythonPackages.searx; + defaultText = "pkgs.pythonPackages.searx"; description = "searx package to use."; }; diff --git a/nixos/modules/services/networking/tinc.nix b/nixos/modules/services/networking/tinc.nix index f8e68fda7fc2..6cb40185274d 100644 --- a/nixos/modules/services/networking/tinc.nix +++ b/nixos/modules/services/networking/tinc.nix @@ -18,7 +18,7 @@ in networks = mkOption { default = { }; - type = with types; loaOf (submodule { + type = with types; attrsOf (submodule { options = { extraConfig = mkOption { @@ -59,7 +59,7 @@ in hosts = mkOption { default = { }; - type = types.loaOf types.lines; + type = types.attrsOf types.lines; description = '' The name of the host in the network as well as the configuration for that host. This name should only contain alphanumerics and underscores. diff --git a/nixos/modules/services/networking/znc.nix b/nixos/modules/services/networking/znc.nix index 76ba78ff366f..0d41e3ea92ce 100644 --- a/nixos/modules/services/networking/znc.nix +++ b/nixos/modules/services/networking/znc.nix @@ -208,7 +208,7 @@ in networks = mkOption { default = { }; - type = with types; loaOf (submodule networkOpts); + type = with types; attrsOf (submodule networkOpts); description = '' IRC networks to connect the user to. ''; diff --git a/nixos/modules/services/scheduling/fcron.nix b/nixos/modules/services/scheduling/fcron.nix index e4ada2768715..bd1ecb40969b 100644 --- a/nixos/modules/services/scheduling/fcron.nix +++ b/nixos/modules/services/scheduling/fcron.nix @@ -23,7 +23,8 @@ let allowdeny = target: users: { source = pkgs.writeText "fcron.${target}" (concatStringsSep "\n" users); target = "fcron.${target}"; - mode = "600"; # fcron has some security issues.. So I guess this is most safe + mode = "644"; + gid = config.ids.gids.fcron; }; in @@ -89,7 +90,7 @@ in [ (allowdeny "allow" (cfg.allow)) (allowdeny "deny" cfg.deny) # see man 5 fcron.conf - { source = pkgs.writeText "fcon.conf" '' + { source = pkgs.writeText "fcron.conf" '' fcrontabs = /var/spool/fcron pidfile = /var/run/fcron.pid fifofile = /var/run/fcron.fifo @@ -97,16 +98,40 @@ in fcrondeny = /etc/fcron.deny shell = /bin/sh sendmail = /run/wrappers/bin/sendmail - editor = /run/current-system/sw/bin/vi + editor = ${pkgs.vim}/bin/vim ''; target = "fcron.conf"; - mode = "0600"; # max allowed is 644 + gid = config.ids.gids.fcron; + mode = "0644"; } ]; environment.systemPackages = [ pkgs.fcron ]; - - security.wrappers.fcrontab.source = "${pkgs.fcron.out}/bin/fcrontab"; + users.extraUsers.fcron = { + uid = config.ids.uids.fcron; + home = "/var/spool/fcron"; + group = "fcron"; + }; + users.groups.fcron.gid = config.ids.gids.fcron; + + security.wrappers = { + fcrontab = { + source = "${pkgs.fcron}/bin/fcrontab"; + owner = "fcron"; + group = "fcron"; + setgid = true; + }; + fcrondyn = { + source = "${pkgs.fcron}/bin/fcrondyn"; + owner = "fcron"; + group = "fcron"; + setgid = true; + }; + fcronsighup = { + source = "${pkgs.fcron}/bin/fcronsighup"; + group = "fcron"; + }; + }; systemd.services.fcron = { description = "fcron daemon"; after = [ "local-fs.target" ]; @@ -118,14 +143,17 @@ in }; preStart = '' - ${pkgs.coreutils}/bin/mkdir -m 0700 -p /var/spool/fcron + ${pkgs.coreutils}/bin/mkdir -m 0770 -p /var/spool/fcron + ${pkgs.coreutils}/bin/chown -R fcron:fcron /var/spool/fcron # load system crontab file - ${pkgs.fcron}/bin/fcrontab -u systab ${pkgs.writeText "systab" cfg.systab} + set -x + #${pkgs.fcron}/bin/fcrontab -u systab ${pkgs.writeText "systab" cfg.systab} ''; - serviceConfig.Type = "forking"; - - script = "${pkgs.fcron}/sbin/fcron -m ${toString cfg.maxSerialJobs} ${queuelen}"; + serviceConfig = { + Type = "forking"; + ExecStart = "${pkgs.fcron}/sbin/fcron -m ${toString cfg.maxSerialJobs} ${queuelen}"; + }; }; }; } diff --git a/nixos/modules/services/security/physlock.nix b/nixos/modules/services/security/physlock.nix index 34d0be3b1beb..0881483967c6 100644 --- a/nixos/modules/services/security/physlock.nix +++ b/nixos/modules/services/security/physlock.nix @@ -26,17 +26,7 @@ in This will switch to a new virtual terminal, turn off console switching and disable SysRq mechanism (when <option>services.physlock.disableSysRq</option> is set) - until the root or <option>services.physlock.user</option> - password is given. - ''; - }; - - user = mkOption { - type = types.nullOr types.str; - default = null; - description = '' - User whose password will be used to unlock the screen on par - with the root password. + until the root or user password is given. ''; }; @@ -105,7 +95,7 @@ in ++ cfg.lockOn.extraTargets; serviceConfig.Type = "forking"; script = '' - ${pkgs.physlock}/bin/physlock -d${optionalString cfg.disableSysRq "s"}${optionalString (cfg.user != null) " -u ${cfg.user}"} + ${pkgs.physlock}/bin/physlock -d${optionalString cfg.disableSysRq "s"} ''; }; diff --git a/nixos/modules/services/system/dbus-session-local.conf.in b/nixos/modules/services/system/dbus-session-local.conf.in deleted file mode 100644 index 5fd6f80a3539..000000000000 --- a/nixos/modules/services/system/dbus-session-local.conf.in +++ /dev/null @@ -1,5 +0,0 @@ -<!DOCTYPE busconfig PUBLIC "-//freedesktop//DTD D-Bus Bus Configuration 1.0//EN" - "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd"> -<busconfig> - @extra@ -</busconfig> diff --git a/nixos/modules/services/system/dbus-system-local.conf.in b/nixos/modules/services/system/dbus-system-local.conf.in deleted file mode 100644 index edbb476f585a..000000000000 --- a/nixos/modules/services/system/dbus-system-local.conf.in +++ /dev/null @@ -1,6 +0,0 @@ -<!DOCTYPE busconfig PUBLIC "-//freedesktop//DTD D-Bus Bus Configuration 1.0//EN" - "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd"> -<busconfig> - <servicehelper>@servicehelper@</servicehelper> - @extra@ -</busconfig> diff --git a/nixos/modules/services/system/dbus.nix b/nixos/modules/services/system/dbus.nix index 33bc890a78c8..643bec188142 100644 --- a/nixos/modules/services/system/dbus.nix +++ b/nixos/modules/services/system/dbus.nix @@ -10,32 +10,10 @@ let homeDir = "/run/dbus"; - systemExtraxml = concatStrings (flip concatMap cfg.packages (d: [ - "<servicedir>${d}/share/dbus-1/system-services</servicedir>" - "<includedir>${d}/etc/dbus-1/system.d</includedir>" - ])); - - sessionExtraxml = concatStrings (flip concatMap cfg.packages (d: [ - "<servicedir>${d}/share/dbus-1/services</servicedir>" - "<includedir>${d}/etc/dbus-1/session.d</includedir>" - ])); - - configDir = pkgs.runCommand "dbus-conf" - { preferLocalBuild = true; - allowSubstitutes = false; - } - '' - mkdir -p $out - - sed '${./dbus-system-local.conf.in}' \ - -e 's,@servicehelper@,${config.security.wrapperDir}/dbus-daemon-launch-helper,g' \ - -e 's,@extra@,${systemExtraxml},' \ - > "$out/system-local.conf" - - sed '${./dbus-session-local.conf.in}' \ - -e 's,@extra@,${sessionExtraxml},' \ - > "$out/session-local.conf" - ''; + configDir = pkgs.makeDBusConf { + suidHelper = "${config.security.wrapperDir}/dbus-daemon-launch-helper"; + serviceDirectories = cfg.packages; + }; in diff --git a/nixos/modules/services/ttys/kmscon.nix b/nixos/modules/services/ttys/kmscon.nix index ba25f9128445..8bad42927e3f 100644 --- a/nixos/modules/services/ttys/kmscon.nix +++ b/nixos/modules/services/ttys/kmscon.nix @@ -76,7 +76,7 @@ in { ln -s ${config.systemd.units."kmsconvt@.service".unit}/kmsconvt@.service $out/autovt@.service ''; - systemd.services.systemd-vconsole-setup.restartIfChanged = false; + systemd.services.systemd-vconsole-setup.enable = false; services.kmscon.extraConfig = mkIf cfg.hwRender '' drm diff --git a/nixos/modules/services/web-apps/mattermost.nix b/nixos/modules/services/web-apps/mattermost.nix index bf3a8eed6004..8e6baf6a17e3 100644 --- a/nixos/modules/services/web-apps/mattermost.nix +++ b/nixos/modules/services/web-apps/mattermost.nix @@ -202,6 +202,7 @@ in ExecStart = "${pkgs.mattermost}/bin/mattermost-platform"; WorkingDirectory = "${cfg.statePath}"; PrivateTmp = true; + JoinsNamespaceOf = mkIf cfg.localDatabaseCreate "postgresql.service"; Restart = "always"; RestartSec = "10"; LimitNOFILE = "49152"; diff --git a/nixos/modules/services/web-apps/pump.io-configure.js b/nixos/modules/services/web-apps/pump.io-configure.js new file mode 100644 index 000000000000..1fbf346a34c4 --- /dev/null +++ b/nixos/modules/services/web-apps/pump.io-configure.js @@ -0,0 +1,23 @@ +var fs = require('fs'); + +var opts = JSON.parse(fs.readFileSync("/dev/stdin").toString()); +var config = opts.config; + +var readSecret = function(filename) { + return fs.readFileSync(filename).toString().trim(); +}; + +if (opts.secretFile) { + config.secret = readSecret(opts.secretFile); +} +if (opts.dbPasswordFile) { + config.params.dbpass = readSecret(opts.dbPasswordFile); +} +if (opts.smtpPasswordFile) { + config.smtppass = readSecret(opts.smtpPasswordFile); +} +if (opts.spamClientSecretFile) { + config.spamclientsecret = readSecret(opts.opts.spamClientSecretFile); +} + +fs.writeFileSync(opts.outputFile, JSON.stringify(config)); diff --git a/nixos/modules/services/web-apps/pump.io.nix b/nixos/modules/services/web-apps/pump.io.nix index b7c64bc6940b..27ae68516367 100644 --- a/nixos/modules/services/web-apps/pump.io.nix +++ b/nixos/modules/services/web-apps/pump.io.nix @@ -5,71 +5,74 @@ with lib; let cfg = config.services.pumpio; dataDir = "/var/lib/pump.io"; + runDir = "/run/pump.io"; user = "pumpio"; + optionalSet = condition: value: if condition then value else {}; + + configScript = ./pump.io-configure.js; configOptions = { - driver = if cfg.driver == "disk" then null else cfg.driver; - params = ({ } // - (if cfg.driver == "disk" then { - dir = dataDir; - } else { }) // - (if cfg.driver == "mongodb" || cfg.driver == "redis" then { - host = cfg.dbHost; - port = cfg.dbPort; - dbname = cfg.dbName; - dbuser = cfg.dbUser; - dbpass = cfg.dbPassword; - } else { }) // - (if cfg.driver == "memcached" then { - host = cfg.dbHost; - port = cfg.dbPort; - } else { }) // - cfg.driverParams); - - secret = cfg.secret; - - address = cfg.address; - port = cfg.port; - - noweb = false; - urlPort = cfg.urlPort; - hostname = cfg.hostname; - favicon = cfg.favicon; - - site = cfg.site; - owner = cfg.owner; - ownerURL = cfg.ownerURL; - - key = cfg.sslKey; - cert = cfg.sslCert; - bounce = false; - - spamhost = cfg.spamHost; - spamclientid = cfg.spamClientId; - spamclientsecret = cfg.spamClientSecret; - - requireEmail = cfg.requireEmail; - smtpserver = cfg.smtpHost; - smtpport = cfg.smtpPort; - smtpuser = cfg.smtpUser; - smtppass = cfg.smtpPassword; - smtpusessl = cfg.smtpUseSSL; - smtpfrom = cfg.smtpFrom; - - nologger = false; - uploaddir = "${dataDir}/uploads"; - debugClient = false; - firehose = cfg.firehose; - disableRegistration = cfg.disableRegistration; - } // - (if cfg.port < 1024 then { - serverUser = user; # have pump.io listen then drop privileges - } else { }) // - cfg.extraConfig; - -in - -{ + outputFile = "${runDir}/config.json"; + config = + (optionalSet (cfg.driver != "disk") { + driver = cfg.driver; + }) // + { + params = (optionalSet (cfg.driver == "disk") { dir = dataDir; }) // + (optionalSet (cfg.driver == "mongodb" || cfg.driver == "redis") { + host = cfg.dbHost; + port = cfg.dbPort; + dbname = cfg.dbName; + dbuser = cfg.dbUser; + dbpass = cfg.dbPassword; + }) // + (optionalSet (cfg.driver == "memcached") { + host = cfg.dbHost; + port = cfg.dbPort; + }) // cfg.driverParams; + secret = cfg.secret; + + address = cfg.address; + port = cfg.port; + + noweb = false; + urlPort = cfg.urlPort; + hostname = cfg.hostname; + favicon = cfg.favicon; + + site = cfg.site; + owner = cfg.owner; + ownerURL = cfg.ownerURL; + + key = cfg.sslKey; + cert = cfg.sslCert; + bounce = false; + + spamhost = cfg.spamHost; + spamclientid = cfg.spamClientId; + spamclientsecret = cfg.spamClientSecret; + + requireEmail = cfg.requireEmail; + smtpserver = cfg.smtpHost; + smtpport = cfg.smtpPort; + smtpuser = cfg.smtpUser; + smtppass = cfg.smtpPassword; + smtpusessl = cfg.smtpUseSSL; + smtpfrom = cfg.smtpFrom; + + nologger = false; + enableUploads = cfg.enableUploads; + datadir = dataDir; + debugClient = false; + firehose = cfg.firehose; + disableRegistration = cfg.disableRegistration; + + inherit (cfg) secretFile dbPasswordFile smtpPasswordFile spamClientSecretFile; + } // + (optionalSet (cfg.port < 1024) { + serverUser = user; # have pump.io listen then drop privileges + }) // cfg.extraConfig; +}; in { options = { services.pumpio = { @@ -77,7 +80,8 @@ in enable = mkEnableOption "Pump.io social streams server"; secret = mkOption { - type = types.str; + type = types.nullOr types.str; + default = null; example = "my dog has fleas"; description = '' A session-generating secret, server-wide password. Warning: @@ -85,6 +89,16 @@ in ''; }; + secretFile = mkOption { + type = types.nullOr types.path; + default = null; + example = "/run/keys/pump.io-secret"; + description = '' + A file containing the session-generating secret, + server-wide password. + ''; + }; + site = mkOption { type = types.str; example = "Awesome Sauce"; @@ -125,7 +139,7 @@ in hostname = mkOption { type = types.nullOr types.str; - default = null; + default = "localhost"; description = '' The hostname of the server, used for generating URLs. Defaults to "localhost" which doesn't do much for you. @@ -152,6 +166,15 @@ in ''; }; + enableUploads = mkOption { + type = types.bool; + default = true; + description = '' + If you want to disable file uploads, set this to false. Uploaded files will be stored + in ${dataDir}/uploads. + ''; + }; + sslKey = mkOption { type = types.path; example = "${dataDir}/myserver.key"; @@ -253,6 +276,15 @@ in ''; }; + dbPasswordFile = mkOption { + type = types.nullOr types.path; + default = null; + example = "/run/keys/pump.io-dbpassword"; + description = '' + A file containing the password corresponding to dbUser. + ''; + }; + smtpHost = mkOption { type = types.nullOr types.str; default = null; @@ -291,6 +323,17 @@ in ''; }; + smtpPasswordFile = mkOption { + type = types.nullOr types.path; + default = null; + example = "/run/keys/pump.io-smtppassword"; + description = '' + A file containing the password used to connect to SMTP + server. Might not be necessary for some servers. + ''; + }; + + smtpUseSSL = mkOption { type = types.bool; default = false; @@ -332,24 +375,55 @@ in stored in cleartext in the Nix store! ''; }; + spamClientSecretFile = mkOption { + type = types.nullOr types.path; + default = null; + example = "/run/keys/pump.io-spamclientsecret"; + description = '' + A file containing the OAuth key for the spam server. + ''; + }; }; }; config = mkIf cfg.enable { + warnings = let warn = k: optional (cfg.${k} != null) + "config.services.pumpio.${k} is insecure. Use ${k}File instead."; + in concatMap warn [ "secret" "dbPassword" "smtpPassword" "spamClientSecret" ]; + + assertions = [ + { assertion = !(isNull cfg.secret && isNull cfg.secretFile); + message = "pump.io needs a secretFile configured"; + } + ]; + systemd.services."pump.io" = - { description = "pump.io social network stream server"; + { description = "Pump.io - stream server that does most of what people really want from a social network"; after = [ "network.target" ]; wantedBy = [ "multi-user.target" ]; - serviceConfig.ExecStart = "${pkgs.pumpio}/bin/pump -c /etc/pump.io.json"; - serviceConfig.User = if cfg.port < 1024 then "root" else user; - serviceConfig.Group = user; - }; - environment.etc."pump.io.json" = { - mode = "0440"; - gid = config.ids.gids.pumpio; - text = builtins.toJSON configOptions; + preStart = '' + mkdir -p ${dataDir}/uploads + mkdir -p ${runDir} + chown pumpio:pumpio ${dataDir}/uploads ${runDir} + chmod 770 ${dataDir}/uploads ${runDir} + + ${pkgs.nodejs}/bin/node ${configScript} <<EOF + ${builtins.toJSON configOptions} + EOF + + chgrp pumpio ${configOptions.outputFile} + chmod 640 ${configOptions.outputFile} + ''; + + serviceConfig = { + ExecStart = "${pkgs.pumpio}/bin/pump -c ${configOptions.outputFile}"; + PermissionsStartOnly = true; + User = if cfg.port < 1024 then "root" else user; + Group = user; + }; + environment = { NODE_ENV = "production"; }; }; users.extraGroups.pumpio.gid = config.ids.gids.pumpio; diff --git a/nixos/modules/services/web-servers/apache-httpd/wordpress.nix b/nixos/modules/services/web-servers/apache-httpd/wordpress.nix index a5b6548d3c53..b94ec14308be 100644 --- a/nixos/modules/services/web-servers/apache-httpd/wordpress.nix +++ b/nixos/modules/services/web-servers/apache-httpd/wordpress.nix @@ -4,11 +4,6 @@ with lib; let - - # Upgrading? We have a test! nix-build ./nixos/tests/wordpress.nix - version = "4.7.2"; - fullversion = "${version}"; - # Our bare-bones wp-config.php file using the above settings wordpressConfig = pkgs.writeText "wp-config.php" '' <?php @@ -71,12 +66,7 @@ let # The wordpress package itself wordpressRoot = pkgs.stdenv.mkDerivation rec { name = "wordpress"; - src = pkgs.fetchFromGitHub { - owner = "WordPress"; - repo = "WordPress"; - rev = "${fullversion}"; - sha256 = "0vph12708drf8ww0xd05hpdvbyy7n5gj9ca598lhdhy2i1j6wy32"; - }; + src = config.package; installPhase = '' mkdir -p $out # copy all the wordpress files we downloaded @@ -122,6 +112,14 @@ in enablePHP = true; options = { + package = mkOption { + type = types.path; + default = pkgs.wordpress; + description = '' + Path to the wordpress sources. + Upgrading? We have a test! nix-build ./nixos/tests/wordpress.nix + ''; + }; dbHost = mkOption { default = "localhost"; description = "The location of the database server."; diff --git a/nixos/modules/services/web-servers/jboss/default.nix b/nixos/modules/services/web-servers/jboss/default.nix index 583fe56eb5e2..d28724281a83 100644 --- a/nixos/modules/services/web-servers/jboss/default.nix +++ b/nixos/modules/services/web-servers/jboss/default.nix @@ -25,7 +25,7 @@ in enable = mkOption { default = false; - description = "Whether to enable jboss"; + description = "Whether to enable JBoss. WARNING : this package is outdated and is known to have vulnerabilities."; }; tempDir = mkOption { diff --git a/nixos/modules/services/web-servers/nginx/default.nix b/nixos/modules/services/web-servers/nginx/default.nix index 9e93e56b9c2c..6bc7192963d1 100644 --- a/nixos/modules/services/web-servers/nginx/default.nix +++ b/nixos/modules/services/web-servers/nginx/default.nix @@ -5,13 +5,16 @@ with lib; let cfg = config.services.nginx; virtualHosts = mapAttrs (vhostName: vhostConfig: - vhostConfig // { + let serverName = if vhostConfig.serverName != null then vhostConfig.serverName else vhostName; + in + vhostConfig // { + inherit serverName; } // (optionalAttrs vhostConfig.enableACME { - sslCertificate = "/var/lib/acme/${vhostName}/fullchain.pem"; - sslCertificateKey = "/var/lib/acme/${vhostName}/key.pem"; + sslCertificate = "/var/lib/acme/${serverName}/fullchain.pem"; + sslCertificateKey = "/var/lib/acme/${serverName}/key.pem"; }) ) cfg.virtualHosts; enableIPv6 = config.networking.enableIPv6; @@ -382,6 +385,7 @@ in description = "Nginx Web Server"; after = [ "network.target" ]; wantedBy = [ "multi-user.target" ]; + stopIfChanged = false; preStart = '' mkdir -p ${cfg.stateDir}/logs diff --git a/nixos/modules/services/web-servers/phpfpm/default.nix b/nixos/modules/services/web-servers/phpfpm/default.nix index ed537e7122a2..efb721c5773f 100644 --- a/nixos/modules/services/web-servers/phpfpm/default.nix +++ b/nixos/modules/services/web-servers/phpfpm/default.nix @@ -4,30 +4,35 @@ with lib; let cfg = config.services.phpfpm; + enabled = cfg.poolConfigs != {} || cfg.pools != {}; stateDir = "/run/phpfpm"; + poolConfigs = cfg.poolConfigs // mapAttrs mkPool cfg.pools; + mkPool = n: p: '' - [${n}] listen = ${p.listen} ${p.extraConfig} ''; - cfgFile = pkgs.writeText "phpfpm.conf" '' + fpmCfgFile = pool: poolConfig: pkgs.writeText "phpfpm-${pool}.conf" '' [global] error_log = syslog daemonize = no ${cfg.extraConfig} - ${concatStringsSep "\n" (mapAttrsToList mkPool cfg.pools)} - - ${concatStringsSep "\n" (mapAttrsToList (n: v: "[${n}]\n${v}") cfg.poolConfigs)} + [${pool}] + ${poolConfig} ''; - phpIni = pkgs.writeText "php.ini" '' - ${readFile "${cfg.phpPackage}/etc/php.ini"} - - ${cfg.phpOptions} + phpIni = pkgs.runCommand "php.ini" { + inherit (cfg) phpPackage phpOptions; + nixDefaults = '' + sendmail_path = "/run/wrappers/bin/sendmail -t -i" + ''; + passAsFile = [ "nixDefaults" "phpOptions" ]; + } '' + cat $phpPackage/etc/php.ini $nixDefaultsPath $phpOptionsPath > $out ''; in { @@ -118,18 +123,41 @@ in { }; }; - config = mkIf (cfg.pools != {} || cfg.poolConfigs != {}) { + config = mkIf enabled { + + systemd.slices.phpfpm = { + description = "PHP FastCGI Process manager pools slice"; + }; - systemd.services.phpfpm = { + systemd.targets.phpfpm = { + description = "PHP FastCGI Process manager pools target"; wantedBy = [ "multi-user.target" ]; - preStart = '' - mkdir -p "${stateDir}" - ''; - serviceConfig = { - Type = "notify"; - ExecStart = "${cfg.phpPackage}/bin/php-fpm -y ${cfgFile} -c ${phpIni}"; - ExecReload = "${pkgs.coreutils}/bin/kill -USR2 $MAINPID"; - }; }; + + systemd.services = flip mapAttrs' poolConfigs (pool: poolConfig: + nameValuePair "phpfpm-${pool}" { + description = "PHP FastCGI Process Manager service for pool ${pool}"; + after = [ "network.target" ]; + wantedBy = [ "phpfpm.target" ]; + partOf = [ "phpfpm.target" ]; + preStart = '' + mkdir -p ${stateDir} + ''; + serviceConfig = let + cfgFile = fpmCfgFile pool poolConfig; + in { + Slice = "phpfpm.slice"; + PrivateTmp = true; + PrivateDevices = true; + ProtectSystem = "full"; + ProtectHome = true; + NoNewPrivileges = true; + RestrictAddressFamilies = "AF_UNIX AF_INET AF_INET6"; + Type = "notify"; + ExecStart = "${cfg.phpPackage}/bin/php-fpm -y ${cfgFile} -c ${phpIni}"; + ExecReload = "${pkgs.coreutils}/bin/kill -USR2 $MAINPID"; + }; + } + ); }; } diff --git a/nixos/modules/services/web-servers/zope2.nix b/nixos/modules/services/web-servers/zope2.nix index 8a453e015577..496e34db4a96 100644 --- a/nixos/modules/services/web-servers/zope2.nix +++ b/nixos/modules/services/web-servers/zope2.nix @@ -74,7 +74,7 @@ in services.zope2.instances = mkOption { default = {}; - type = with types; loaOf (submodule zope2Opts); + type = with types; attrsOf (submodule zope2Opts); example = literalExample '' { plone01 = { diff --git a/nixos/modules/services/x11/desktop-managers/default.nix b/nixos/modules/services/x11/desktop-managers/default.nix index 1f7a925ed054..af01f6acad18 100644 --- a/nixos/modules/services/x11/desktop-managers/default.nix +++ b/nixos/modules/services/x11/desktop-managers/default.nix @@ -16,9 +16,9 @@ in { # Note: the order in which desktop manager modules are imported here # determines the default: later modules (if enabled) are preferred. - # E.g., if KDE is enabled, it supersedes xterm. + # E.g., if Plasma 5 is enabled, it supersedes xterm. imports = [ - ./none.nix ./xterm.nix ./xfce.nix ./kde5.nix ./lumina.nix + ./none.nix ./xterm.nix ./xfce.nix ./plasma5.nix ./lumina.nix ./lxqt.nix ./enlightenment.nix ./gnome3.nix ./kodi.nix ]; diff --git a/nixos/modules/services/x11/desktop-managers/kde5.nix b/nixos/modules/services/x11/desktop-managers/kde5.nix deleted file mode 100644 index 1b44b9e42c81..000000000000 --- a/nixos/modules/services/x11/desktop-managers/kde5.nix +++ /dev/null @@ -1,255 +0,0 @@ -{ config, lib, pkgs, ... }: - -with lib; - -let - - xcfg = config.services.xserver; - cfg = xcfg.desktopManager.kde5; - xorg = pkgs.xorg; - - kde5 = pkgs.kde5; - -in - -{ - options = { - - services.xserver.desktopManager.kde5 = { - enable = mkOption { - type = types.bool; - default = false; - description = "Enable the Plasma 5 (KDE 5) desktop environment."; - }; - - enableQt4Support = mkOption { - type = types.bool; - default = true; - description = '' - Enable support for Qt 4-based applications. Particularly, install the - Qt 4 version of the Breeze theme and a default backend for Phonon. - ''; - }; - - extraPackages = mkOption { - type = types.listOf types.package; - default = []; - description = '' - KDE packages that need to be installed system-wide. - ''; - }; - - }; - - }; - - - config = mkMerge [ - (mkIf (cfg.extraPackages != []) { - environment.systemPackages = [ (kde5.kdeWrapper cfg.extraPackages) ]; - }) - - (mkIf (xcfg.enable && cfg.enable) { - services.xserver.desktopManager.session = singleton { - name = "kde5"; - bgSupport = true; - start = '' - # Load PulseAudio module for routing support. - # See http://colin.guthr.ie/2009/10/so-how-does-the-kde-pulseaudio-support-work-anyway/ - ${optionalString config.hardware.pulseaudio.enable '' - ${getBin config.hardware.pulseaudio.package}/bin/pactl load-module module-device-manager "do_routing=1" - ''} - - exec "${kde5.startkde}" - ''; - }; - - security.wrappers = { - kcheckpass.source = "${kde5.plasma-workspace.out}/lib/libexec/kcheckpass"; - "start_kdeinit".source = "${kde5.kinit.out}/lib/libexec/kf5/start_kdeinit"; - }; - - environment.systemPackages = - [ - kde5.frameworkintegration - kde5.kactivities - kde5.kauth - kde5.kcmutils - kde5.kconfig - kde5.kconfigwidgets - kde5.kcoreaddons - kde5.kdbusaddons - kde5.kdeclarative - kde5.kded - kde5.kdesu - kde5.kdnssd - kde5.kemoticons - kde5.kfilemetadata - kde5.kglobalaccel - kde5.kguiaddons - kde5.kiconthemes - kde5.kidletime - kde5.kimageformats - kde5.kinit - kde5.kio - kde5.kjobwidgets - kde5.knewstuff - kde5.knotifications - kde5.knotifyconfig - kde5.kpackage - kde5.kparts - kde5.kpeople - kde5.krunner - kde5.kservice - kde5.ktextwidgets - kde5.kwallet - kde5.kwallet-pam - kde5.kwalletmanager - kde5.kwayland - kde5.kwidgetsaddons - kde5.kxmlgui - kde5.kxmlrpcclient - kde5.plasma-framework - kde5.solid - kde5.sonnet - kde5.threadweaver - - kde5.breeze-qt5 - kde5.kactivitymanagerd - kde5.kde-cli-tools - kde5.kdecoration - kde5.kdeplasma-addons - kde5.kgamma5 - kde5.khotkeys - kde5.kinfocenter - kde5.kmenuedit - kde5.kscreen - kde5.kscreenlocker - kde5.ksysguard - kde5.kwayland - kde5.kwin - kde5.kwrited - kde5.libkscreen - kde5.libksysguard - kde5.milou - kde5.plasma-integration - kde5.polkit-kde-agent - kde5.systemsettings - - kde5.plasma-desktop - kde5.plasma-workspace - kde5.plasma-workspace-wallpapers - - kde5.dolphin-plugins - kde5.ffmpegthumbs - kde5.kdegraphics-thumbnailers - kde5.kio-extras - kde5.print-manager - - # Install Breeze icons if available - (kde5.breeze-icons or kde5.oxygen-icons5 or kde5.oxygen-icons) - pkgs.hicolor_icon_theme - - kde5.kde-gtk-config kde5.breeze-gtk - - pkgs.qt5.phonon-backend-gstreamer - ] - - # Plasma 5.5 and later has a Breeze GTK theme. - # If it is not available, Orion is very similar to Breeze. - ++ lib.optional (!(lib.hasAttr "breeze-gtk" kde5)) pkgs.orion - - # 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 - - ++ lib.optionals cfg.enableQt4Support [ kde5.breeze-qt4 pkgs.phonon-backend-gstreamer ] - - # Optional hardware support features - ++ lib.optional config.hardware.bluetooth.enable kde5.bluedevil - ++ lib.optional config.networking.networkmanager.enable kde5.plasma-nm - ++ lib.optional config.hardware.pulseaudio.enable kde5.plasma-pa - ++ lib.optional config.powerManagement.enable kde5.powerdevil - ++ lib.optional config.services.colord.enable pkgs.colord-kde - ++ lib.optionals config.services.samba.enable [ kde5.kdenetwork-filesharing pkgs.samba ]; - - services.xserver.desktopManager.kde5.extraPackages = - [ - kde5.khelpcenter - kde5.oxygen - - kde5.dolphin - kde5.konsole - ]; - - environment.pathsToLink = [ "/share" ]; - - environment.etc = singleton { - source = "${pkgs.xkeyboard_config}/etc/X11/xkb"; - target = "X11/xkb"; - }; - - environment.variables = - { - # Enable GTK applications to load SVG icons - GST_PLUGIN_SYSTEM_PATH_1_0 = - lib.makeSearchPath "/lib/gstreamer-1.0" - (builtins.map (pkg: pkg.out) (with pkgs.gst_all_1; [ - gstreamer - gst-plugins-base - gst-plugins-good - gst-plugins-ugly - gst-plugins-bad - gst-libav # for mp3 playback - ])); - } - // (if (lib.hasAttr "breeze-icons" kde5) - then { GDK_PIXBUF_MODULE_FILE = "${pkgs.librsvg.out}/lib/gdk-pixbuf-2.0/2.10.0/loaders.cache"; } - else { }); - - fonts.fonts = [ (kde5.oxygen-fonts or pkgs.noto-fonts) ]; - - programs.ssh.askPassword = "${kde5.ksshaskpass.out}/bin/ksshaskpass"; - - # Enable helpful DBus services. - services.udisks2.enable = true; - services.upower.enable = config.powerManagement.enable; - services.dbus.packages = - mkIf config.services.printing.enable [ pkgs.system-config-printer ]; - - # Extra UDEV rules used by Solid - services.udev.packages = [ - pkgs.libmtp - pkgs.media-player-info - ]; - - services.xserver.displayManager.sddm = { - theme = "breeze"; - themes = [ - kde5.ecm # for the setup-hook - kde5.plasma-workspace - kde5.breeze-icons - ]; - }; - - security.pam.services.kde = { allowNullPassword = true; }; - - # Doing these one by one seems silly, but we currently lack a better - # construct for handling common pam configs. - security.pam.services.gdm.enableKwallet = true; - security.pam.services.kdm.enableKwallet = true; - security.pam.services.lightdm.enableKwallet = true; - security.pam.services.sddm.enableKwallet = true; - security.pam.services.slim.enableKwallet = true; - - # use kimpanel as the default IBus panel - i18n.inputMethod.ibus.panel = - lib.mkDefault - "${pkgs.kde5.plasma-desktop}/lib/libexec/kimpanel-ibus-panel"; - - }) - ]; - -} diff --git a/nixos/modules/services/x11/desktop-managers/lumina.nix b/nixos/modules/services/x11/desktop-managers/lumina.nix index f0b31a2acb01..ed5ad4a2a001 100644 --- a/nixos/modules/services/x11/desktop-managers/lumina.nix +++ b/nixos/modules/services/x11/desktop-managers/lumina.nix @@ -32,8 +32,8 @@ in environment.systemPackages = [ pkgs.fluxbox - pkgs.kde5.kwindowsystem - pkgs.kde5.oxygen-icons5 + pkgs.qt5.kwindowsystem + pkgs.qt5.oxygen-icons5 pkgs.lumina pkgs.numlockx pkgs.qt5.qtsvg diff --git a/nixos/modules/services/x11/desktop-managers/plasma5.nix b/nixos/modules/services/x11/desktop-managers/plasma5.nix new file mode 100644 index 000000000000..bc6e728169b4 --- /dev/null +++ b/nixos/modules/services/x11/desktop-managers/plasma5.nix @@ -0,0 +1,236 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + + xcfg = config.services.xserver; + cfg = xcfg.desktopManager.plasma5; + + inherit (pkgs) kdeWrapper kdeApplications plasma5 libsForQt5 qt5 xorg; + +in + +{ + options = { + + services.xserver.desktopManager.plasma5 = { + enable = mkOption { + type = types.bool; + default = false; + description = "Enable the Plasma 5 (KDE 5) desktop environment."; + }; + + enableQt4Support = mkOption { + type = types.bool; + default = true; + description = '' + Enable support for Qt 4-based applications. Particularly, install the + Qt 4 version of the Breeze theme and a default backend for Phonon. + ''; + }; + + extraPackages = mkOption { + type = types.listOf types.package; + default = []; + description = '' + KDE packages that need to be installed system-wide. + ''; + }; + + }; + + }; + + + config = mkMerge [ + (mkIf (cfg.extraPackages != []) { + environment.systemPackages = [ (kdeWrapper cfg.extraPackages) ]; + }) + + (mkIf (xcfg.enable && cfg.enable) { + services.xserver.desktopManager.session = singleton { + name = "plasma5"; + bgSupport = true; + start = '' + # Load PulseAudio module for routing support. + # See http://colin.guthr.ie/2009/10/so-how-does-the-kde-pulseaudio-support-work-anyway/ + ${optionalString config.hardware.pulseaudio.enable '' + ${getBin config.hardware.pulseaudio.package}/bin/pactl load-module module-device-manager "do_routing=1" + ''} + + exec "${plasma5.startkde}" + ''; + }; + + security.wrappers = { + kcheckpass.source = "${plasma5.plasma-workspace.out}/lib/libexec/kcheckpass"; + "start_kdeinit".source = "${pkgs.kinit.out}/lib/libexec/kf5/start_kdeinit"; + }; + + environment.systemPackages = with pkgs; with qt5; with libsForQt5; with plasma5; with kdeApplications; + [ + frameworkintegration + kactivities + kauth + kcmutils + kconfig + kconfigwidgets + kcoreaddons + kdbusaddons + kdeclarative + kded + kdesu + kdnssd + kemoticons + kfilemetadata + kglobalaccel + kguiaddons + kiconthemes + kidletime + kimageformats + kinit + kio + kjobwidgets + knewstuff + knotifications + knotifyconfig + kpackage + kparts + kpeople + krunner + kservice + ktextwidgets + kwallet + kwallet-pam + kwalletmanager + kwayland + kwidgetsaddons + kxmlgui + kxmlrpcclient + plasma-framework + solid + sonnet + threadweaver + + breeze-qt5 + kactivitymanagerd + kde-cli-tools + kdecoration + kdeplasma-addons + kgamma5 + khotkeys + kinfocenter + kmenuedit + kscreen + kscreenlocker + ksysguard + kwayland + kwin + kwrited + libkscreen + libksysguard + milou + plasma-integration + polkit-kde-agent + systemsettings + + plasma-desktop + plasma-workspace + plasma-workspace-wallpapers + + dolphin-plugins + ffmpegthumbs + kdegraphics-thumbnailers + kio-extras + print-manager + + breeze-icons + pkgs.hicolor_icon_theme + + kde-gtk-config breeze-gtk + + phonon-backend-gstreamer + ] + + ++ lib.optionals cfg.enableQt4Support [ breeze-qt4 pkgs.phonon-backend-gstreamer ] + + # Optional hardware support features + ++ lib.optional config.hardware.bluetooth.enable bluedevil + ++ lib.optional config.networking.networkmanager.enable plasma-nm + ++ lib.optional config.hardware.pulseaudio.enable plasma-pa + ++ lib.optional config.powerManagement.enable powerdevil + ++ lib.optional config.services.colord.enable colord-kde + ++ lib.optionals config.services.samba.enable [ kdenetwork-filesharing pkgs.samba ]; + + services.xserver.desktopManager.plasma5.extraPackages = + with kdeApplications; with plasma5; + [ + khelpcenter + oxygen + + dolphin + konsole + ]; + + environment.pathsToLink = [ "/share" ]; + + environment.etc = singleton { + source = "${pkgs.xkeyboard_config}/etc/X11/xkb"; + target = "X11/xkb"; + }; + + environment.variables = { + # Enable GTK applications to load SVG icons + GDK_PIXBUF_MODULE_FILE = "${pkgs.librsvg.out}/lib/gdk-pixbuf-2.0/2.10.0/loaders.cache"; + }; + + fonts.fonts = with pkgs; [ noto-fonts hack-font ]; + fonts.fontconfig.defaultFonts = { + monospace = [ "Hack" "Noto Mono" ]; + sansSerif = [ "Noto Sans" ]; + serif = [ "Noto Serif" ]; + }; + + programs.ssh.askPassword = "${plasma5.ksshaskpass.out}/bin/ksshaskpass"; + + # Enable helpful DBus services. + services.udisks2.enable = true; + services.upower.enable = config.powerManagement.enable; + services.dbus.packages = + mkIf config.services.printing.enable [ pkgs.system-config-printer ]; + + # Extra UDEV rules used by Solid + services.udev.packages = [ + pkgs.libmtp + pkgs.media-player-info + ]; + + services.xserver.displayManager.sddm = { + theme = "breeze"; + themes = [ + pkgs.extra-cmake-modules # for the setup-hook + plasma5.plasma-workspace + pkgs.breeze-icons + ]; + }; + + security.pam.services.kde = { allowNullPassword = true; }; + + # Doing these one by one seems silly, but we currently lack a better + # construct for handling common pam configs. + security.pam.services.gdm.enableKwallet = true; + security.pam.services.kdm.enableKwallet = true; + security.pam.services.lightdm.enableKwallet = true; + security.pam.services.sddm.enableKwallet = true; + security.pam.services.slim.enableKwallet = true; + + # use kimpanel as the default IBus panel + i18n.inputMethod.ibus.panel = + lib.mkDefault + "${plasma5.plasma-desktop}/lib/libexec/kimpanel-ibus-panel"; + + }) + ]; + +} diff --git a/nixos/modules/services/x11/desktop-managers/xfce.nix b/nixos/modules/services/x11/desktop-managers/xfce.nix index 530468be5f96..9c42dc8781b9 100644 --- a/nixos/modules/services/x11/desktop-managers/xfce.nix +++ b/nixos/modules/services/x11/desktop-managers/xfce.nix @@ -41,6 +41,18 @@ in Shell commands executed just before XFCE is started. ''; }; + + enableXfwm = mkOption { + type = types.bool; + default = true; + description = "Enable the XFWM (default) window manager."; + }; + + screenLock = mkOption { + type = types.enum [ "xscreensaver" "xlockmore" "slock" ]; + default = "xlockmore"; + description = "Application used by XFCE to lock the screen."; + }; }; }; @@ -74,6 +86,7 @@ in pkgs.tango-icon-theme pkgs.shared_mime_info pkgs.which # Needed by the xfce's xinitrc script. + pkgs."${cfg.screenLock}" pkgs.xfce.exo pkgs.xfce.gtk_xfce_engine pkgs.xfce.mousepad @@ -87,7 +100,6 @@ in pkgs.xfce.xfce4volumed pkgs.xfce.xfce4-screenshooter pkgs.xfce.xfconf - pkgs.xfce.xfwm4 # This supplies some "abstract" icons such as # "utilities-terminal" and "accessories-text-editor". pkgs.gnome3.defaultIconTheme @@ -99,6 +111,7 @@ in pkgs.xfce.xfce4_appfinder pkgs.xfce.tumbler # found via dbus ] + ++ optional cfg.enableXfwm pkgs.xfce.xfwm4 ++ optional config.powerManagement.enable pkgs.xfce.xfce4_power_manager ++ optional config.networking.networkmanager.enable pkgs.networkmanagerapplet ++ optionals (!cfg.noDesktop) diff --git a/nixos/modules/services/x11/display-managers/lightdm.nix b/nixos/modules/services/x11/display-managers/lightdm.nix index 4afef32aaa47..82b9a2fce5ab 100644 --- a/nixos/modules/services/x11/display-managers/lightdm.nix +++ b/nixos/modules/services/x11/display-managers/lightdm.nix @@ -46,15 +46,13 @@ let [Seat:*] xserver-command = ${xserverWrapper} session-wrapper = ${dmcfg.session.script} - ${optionalString (elem defaultSessionName dmcfg.session.names) '' - user-session = ${defaultSessionName} - ''} ${optionalString cfg.greeter.enable '' greeter-session = ${cfg.greeter.name} ''} ${optionalString cfg.autoLogin.enable '' autologin-user = ${cfg.autoLogin.user} autologin-user-timeout = ${toString cfg.autoLogin.timeout} + autologin-session = ${defaultSessionName} ''} ${cfg.extraSeatDefaults} ''; diff --git a/nixos/modules/services/x11/display-managers/xpra.nix b/nixos/modules/services/x11/display-managers/xpra.nix new file mode 100644 index 000000000000..e60dd8765264 --- /dev/null +++ b/nixos/modules/services/x11/display-managers/xpra.nix @@ -0,0 +1,249 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + cfg = config.services.xserver.displayManager.xpra; + dmcfg = config.services.xserver.displayManager; + +in + +{ + ###### interface + + options = { + services.xserver.displayManager.xpra = { + enable = mkOption { + type = types.bool; + default = false; + description = "Whether to enable xpra as display manager."; + }; + + bindTcp = mkOption { + default = "127.0.0.1:10000"; + example = "0.0.0.0:10000"; + type = types.nullOr types.str; + description = "Bind xpra to TCP"; + }; + + auth = mkOption { + type = types.str; + default = "pam"; + example = "password:value=mysecret"; + description = "Authentication to use when connecting to xpra"; + }; + + pulseaudio = mkEnableOption "pulseaudio audio streaming."; + }; + }; + + ###### implementation + + config = mkIf cfg.enable { + services.xserver.videoDrivers = ["dummy"]; + + services.xserver.monitorSection = '' + HorizSync 1.0 - 2000.0 + VertRefresh 1.0 - 200.0 + #To add your own modes here, use a modeline calculator, like: + # cvt: + # http://www.x.org/archive/X11R7.5/doc/man/man1/cvt.1.html + # xtiming: + # http://xtiming.sourceforge.net/cgi-bin/xtiming.pl + # gtf: + # http://gtf.sourceforge.net/ + #This can be used to get a specific DPI, but only for the default resolution: + #DisplaySize 508 317 + #NOTE: the highest modes will not work without increasing the VideoRam + # for the dummy video card. + #Modeline "16000x15000" 300.00 16000 16408 18000 20000 15000 15003 15013 15016 + #Modeline "15000x15000" 281.25 15000 15376 16872 18744 15000 15003 15013 15016 + #Modeline "16384x8192" 167.75 16384 16800 18432 20480 8192 8195 8205 8208 + #Modeline "15360x8640" 249.00 15360 15752 17280 19200 8640 8643 8648 8651 + Modeline "8192x4096" 193.35 8192 8224 8952 8984 4096 4196 4200 4301 + Modeline "7680x4320" 208.00 7680 7880 8640 9600 4320 4323 4328 4335 + Modeline "6400x4096" 151.38 6400 6432 7000 7032 4096 4196 4200 4301 + Modeline "6400x2560" 91.59 6400 6432 6776 6808 2560 2623 2626 2689 + Modeline "6400x2160" 160.51 6400 6432 7040 7072 2160 2212 2216 2269 + Modeline "5760x2160" 149.50 5760 5768 6320 6880 2160 2161 2164 2173 + Modeline "5680x1440" 142.66 5680 5712 6248 6280 1440 1474 1478 1513 + Modeline "5496x1200" 199.13 5496 5528 6280 6312 1200 1228 1233 1261 + Modeline "5280x2560" 75.72 5280 5312 5592 5624 2560 2623 2626 2689 + Modeline "5280x1920" 56.04 5280 5312 5520 5552 1920 1967 1969 2017 + Modeline "5280x1200" 191.40 5280 5312 6032 6064 1200 1228 1233 1261 + Modeline "5280x1080" 169.96 5280 5312 5952 5984 1080 1105 1110 1135 + Modeline "5120x3200" 199.75 5120 5152 5904 5936 3200 3277 3283 3361 + Modeline "5120x2560" 73.45 5120 5152 5424 5456 2560 2623 2626 2689 + Modeline "5120x2880" 185.50 5120 5256 5760 6400 2880 2883 2888 2899 + Modeline "4800x1200" 64.42 4800 4832 5072 5104 1200 1229 1231 1261 + Modeline "4720x3840" 227.86 4720 4752 5616 5648 3840 3933 3940 4033 + Modeline "4400x2560" 133.70 4400 4432 4936 4968 2560 2622 2627 2689 + Modeline "4480x1440" 72.94 4480 4512 4784 4816 1440 1475 1478 1513 + Modeline "4240x1440" 69.09 4240 4272 4528 4560 1440 1475 1478 1513 + Modeline "4160x1440" 67.81 4160 4192 4448 4480 1440 1475 1478 1513 + Modeline "4096x2304" 249.25 4096 4296 4720 5344 2304 2307 2312 2333 + Modeline "4096x2160" 111.25 4096 4200 4608 5120 2160 2163 2173 2176 + Modeline "4000x1660" 170.32 4000 4128 4536 5072 1660 1661 1664 1679 + Modeline "4000x1440" 145.00 4000 4088 4488 4976 1440 1441 1444 1457 + Modeline "3904x1440" 63.70 3904 3936 4176 4208 1440 1475 1478 1513 + Modeline "3840x2880" 133.43 3840 3872 4376 4408 2880 2950 2955 3025 + Modeline "3840x2560" 116.93 3840 3872 4312 4344 2560 2622 2627 2689 + Modeline "3840x2160" 104.25 3840 3944 4320 4800 2160 2163 2168 2175 + Modeline "3840x2048" 91.45 3840 3872 4216 4248 2048 2097 2101 2151 + Modeline "3840x1200" 108.89 3840 3872 4280 4312 1200 1228 1232 1261 + Modeline "3840x1080" 100.38 3840 3848 4216 4592 1080 1081 1084 1093 + Modeline "3864x1050" 94.58 3864 3896 4248 4280 1050 1074 1078 1103 + Modeline "3600x1200" 106.06 3600 3632 3984 4368 1200 1201 1204 1214 + Modeline "3600x1080" 91.02 3600 3632 3976 4008 1080 1105 1109 1135 + Modeline "3520x1196" 99.53 3520 3552 3928 3960 1196 1224 1228 1256 + Modeline "3360x2560" 102.55 3360 3392 3776 3808 2560 2622 2627 2689 + Modeline "3360x1050" 293.75 3360 3576 3928 4496 1050 1053 1063 1089 + Modeline "3288x1080" 39.76 3288 3320 3464 3496 1080 1106 1108 1135 + Modeline "3200x1800" 233.00 3200 3384 3720 4240 1800 1803 1808 1834 + Modeline "3200x1080" 236.16 3200 3232 4128 4160 1080 1103 1112 1135 + Modeline "3120x2560" 95.36 3120 3152 3512 3544 2560 2622 2627 2689 + Modeline "3120x1050" 272.75 3120 3320 3648 4176 1050 1053 1063 1089 + Modeline "3072x2560" 93.92 3072 3104 3456 3488 2560 2622 2627 2689 + Modeline "3008x1692" 130.93 3008 3112 3416 3824 1692 1693 1696 1712 + Modeline "3000x2560" 91.77 3000 3032 3376 3408 2560 2622 2627 2689 + Modeline "2880x1620" 396.25 2880 3096 3408 3936 1620 1623 1628 1679 + Modeline "2728x1680" 148.02 2728 2760 3320 3352 1680 1719 1726 1765 + Modeline "2560x2240" 151.55 2560 2688 2952 3344 2240 2241 2244 2266 + Modeline "2560x1600" 47.12 2560 2592 2768 2800 1600 1639 1642 1681 + Modeline "2560x1440" 42.12 2560 2592 2752 2784 1440 1475 1478 1513 + Modeline "2560x1400" 267.86 2560 2592 3608 3640 1400 1429 1441 1471 + Modeline "2048x2048" 49.47 2048 2080 2264 2296 2048 2097 2101 2151 + Modeline "2048x1536" 80.06 2048 2104 2312 2576 1536 1537 1540 1554 + Modeline "2048x1152" 197.97 2048 2184 2408 2768 1152 1153 1156 1192 + Modeline "2048x1152" 165.92 2048 2080 2704 2736 1152 1176 1186 1210 + Modeline "1920x1440" 69.47 1920 1960 2152 2384 1440 1441 1444 1457 + Modeline "1920x1200" 26.28 1920 1952 2048 2080 1200 1229 1231 1261 + Modeline "1920x1080" 23.53 1920 1952 2040 2072 1080 1106 1108 1135 + Modeline "1728x1520" 205.42 1728 1760 2536 2568 1520 1552 1564 1597 + Modeline "1680x1050" 20.08 1680 1712 1784 1816 1050 1075 1077 1103 + Modeline "1600x1200" 22.04 1600 1632 1712 1744 1200 1229 1231 1261 + Modeline "1600x900" 33.92 1600 1632 1760 1792 900 921 924 946 + Modeline "1440x900" 30.66 1440 1472 1584 1616 900 921 924 946 + Modeline "1400x900" 103.50 1400 1480 1624 1848 900 903 913 934 + ModeLine "1366x768" 72.00 1366 1414 1446 1494 768 771 777 803 + Modeline "1360x768" 24.49 1360 1392 1480 1512 768 786 789 807 + Modeline "1280x1024" 31.50 1280 1312 1424 1456 1024 1048 1052 1076 + Modeline "1280x800" 24.15 1280 1312 1400 1432 800 819 822 841 + Modeline "1280x768" 23.11 1280 1312 1392 1424 768 786 789 807 + Modeline "1280x720" 59.42 1280 1312 1536 1568 720 735 741 757 + Modeline "1024x768" 18.71 1024 1056 1120 1152 768 786 789 807 + Modeline "1024x640" 41.98 1024 1056 1208 1240 640 653 659 673 + Modeline "1024x576" 46.50 1024 1064 1160 1296 576 579 584 599 + Modeline "768x1024" 19.50 768 800 872 904 1024 1048 1052 1076 + Modeline "960x540" 40.75 960 992 1088 1216 540 543 548 562 + Modeline "864x486" 32.50 864 888 968 1072 486 489 494 506 + Modeline "720x405" 22.50 720 744 808 896 405 408 413 422 + Modeline "640x360" 14.75 640 664 720 800 360 363 368 374 + #common resolutions for android devices (both orientations): + Modeline "800x1280" 25.89 800 832 928 960 1280 1310 1315 1345 + Modeline "1280x800" 24.15 1280 1312 1400 1432 800 819 822 841 + Modeline "720x1280" 30.22 720 752 864 896 1280 1309 1315 1345 + Modeline "1280x720" 27.41 1280 1312 1416 1448 720 737 740 757 + Modeline "768x1024" 24.93 768 800 888 920 1024 1047 1052 1076 + Modeline "1024x768" 23.77 1024 1056 1144 1176 768 785 789 807 + Modeline "600x1024" 19.90 600 632 704 736 1024 1047 1052 1076 + Modeline "1024x600" 18.26 1024 1056 1120 1152 600 614 617 631 + Modeline "536x960" 16.74 536 568 624 656 960 982 986 1009 + Modeline "960x536" 15.23 960 992 1048 1080 536 548 551 563 + Modeline "600x800" 15.17 600 632 688 720 800 818 822 841 + Modeline "800x600" 14.50 800 832 880 912 600 614 617 631 + Modeline "480x854" 13.34 480 512 560 592 854 873 877 897 + Modeline "848x480" 12.09 848 880 920 952 480 491 493 505 + Modeline "480x800" 12.43 480 512 552 584 800 818 822 841 + Modeline "800x480" 11.46 800 832 872 904 480 491 493 505 + #resolutions for android devices (both orientations) + #minus the status bar + #38px status bar (and width rounded up) + Modeline "800x1242" 25.03 800 832 920 952 1242 1271 1275 1305 + Modeline "1280x762" 22.93 1280 1312 1392 1424 762 780 783 801 + Modeline "720x1242" 29.20 720 752 856 888 1242 1271 1276 1305 + Modeline "1280x682" 25.85 1280 1312 1408 1440 682 698 701 717 + Modeline "768x986" 23.90 768 800 888 920 986 1009 1013 1036 + Modeline "1024x730" 22.50 1024 1056 1136 1168 730 747 750 767 + Modeline "600x986" 19.07 600 632 704 736 986 1009 1013 1036 + Modeline "1024x562" 17.03 1024 1056 1120 1152 562 575 578 591 + Modeline "536x922" 16.01 536 568 624 656 922 943 947 969 + Modeline "960x498" 14.09 960 992 1040 1072 498 509 511 523 + Modeline "600x762" 14.39 600 632 680 712 762 779 783 801 + Modeline "800x562" 13.52 800 832 880 912 562 575 578 591 + Modeline "480x810" 12.59 480 512 552 584 810 828 832 851 + Modeline "848x442" 11.09 848 880 920 952 442 452 454 465 + Modeline "480x762" 11.79 480 512 552 584 762 779 783 801 + ''; + + services.xserver.resolutions = [ + {x="8192"; y="4096";} + {x="5120"; y="3200";} + {x="3840"; y="2880";} + {x="3840"; y="2560";} + {x="3840"; y="2048";} + {x="3840"; y="2160";} + {x="2048"; y="2048";} + {x="2560"; y="1600";} + {x="1920"; y="1440";} + {x="1920"; y="1200";} + {x="1920"; y="1080";} + {x="1600"; y="1200";} + {x="1680"; y="1050";} + {x="1600"; y="900";} + {x="1400"; y="1050";} + {x="1440"; y="900";} + {x="1280"; y="1024";} + {x="1366"; y="768";} + {x="1280"; y="800";} + {x="1024"; y="768";} + {x="1024"; y="600";} + {x="800"; y="600";} + {x="320"; y="200";} + ]; + + services.xserver.serverFlagsSection = '' + Option "DontVTSwitch" "true" + Option "PciForceNone" "true" + Option "AutoEnableDevices" "false" + Option "AutoAddDevices" "false" + ''; + + services.xserver.deviceSection = '' + VideoRam 192000 + ''; + + services.xserver.displayManager.job = { + logsXsession = true; + + execCmd = '' + ${optionalString (cfg.pulseaudio) + "export PULSE_COOKIE=/var/run/pulse/.config/pulse/cookie"} + exec ${pkgs.xpra}/bin/xpra start \ + --daemon=off \ + --log-dir=/var/log \ + --log-file=xpra.log \ + --opengl=on \ + --clipboard=on \ + --notifications=on \ + --speaker=yes \ + --mdns=no \ + --pulseaudio=no \ + ${optionalString (cfg.pulseaudio) "--sound-source=pulse"} \ + --socket-dirs=/var/run/xpra \ + --xvfb="xpra_Xdummy ${concatStringsSep " " dmcfg.xserverArgs}" \ + ${optionalString (cfg.bindTcp != null) "--bind-tcp=${cfg.bindTcp}"} \ + --auth=${cfg.auth} + ''; + }; + + services.xserver.terminateOnReset = false; + + environment.systemPackages = [pkgs.xpra]; + + virtualisation.virtualbox.guest.x11 = false; + hardware.pulseaudio.enable = mkDefault cfg.pulseaudio; + hardware.pulseaudio.systemWide = mkDefault cfg.pulseaudio; + }; + +} diff --git a/nixos/modules/services/x11/window-managers/herbstluftwm.nix b/nixos/modules/services/x11/window-managers/herbstluftwm.nix index 829935fa432b..e3ea61cb9a6b 100644 --- a/nixos/modules/services/x11/window-managers/herbstluftwm.nix +++ b/nixos/modules/services/x11/window-managers/herbstluftwm.nix @@ -8,15 +8,30 @@ in { options = { - services.xserver.windowManager.herbstluftwm.enable = mkEnableOption "herbstluftwm"; + services.xserver.windowManager.herbstluftwm = { + enable = mkEnableOption "herbstluftwm"; + + configFile = mkOption { + default = null; + type = with types; nullOr path; + description = '' + Path to the herbstluftwm configuration file. If left at the + default value, $XDG_CONFIG_HOME/herbstluftwm/autostart will + be used. + ''; + }; + }; }; config = mkIf cfg.enable { services.xserver.windowManager.session = singleton { name = "herbstluftwm"; - start = " - ${pkgs.herbstluftwm}/bin/herbstluftwm - "; + start = + let configFileClause = optionalString + (cfg.configFile != null) + ''-c "${cfg.configFile}"'' + ; + in "${pkgs.herbstluftwm}/bin/herbstluftwm ${configFileClause}"; }; environment.systemPackages = [ pkgs.herbstluftwm ]; }; diff --git a/nixos/modules/services/x11/xserver.nix b/nixos/modules/services/x11/xserver.nix index 7ac776571a01..8438e6dcc702 100644 --- a/nixos/modules/services/x11/xserver.nix +++ b/nixos/modules/services/x11/xserver.nix @@ -435,6 +435,14 @@ in by default. ''; }; + + terminateOnReset = mkOption { + type = types.bool; + default = true; + description = '' + Whether to terminate X upon server reset. + ''; + }; }; }; @@ -550,8 +558,7 @@ in }; services.xserver.displayManager.xserverArgs = - [ "-terminate" - "-config ${configFile}" + [ "-config ${configFile}" "-xkbdir" "${cfg.xkbDir}" # Log at the default verbosity level to stderr rather than /var/log/X.*.log. "-verbose" "3" "-logfile" "/dev/null" @@ -560,7 +567,8 @@ in ++ optional (cfg.dpi != null) "-dpi ${toString cfg.dpi}" ++ optional (!cfg.enableTCP) "-nolisten tcp" ++ optional (cfg.autoRepeatDelay != null) "-ardelay ${toString cfg.autoRepeatDelay}" - ++ optional (cfg.autoRepeatInterval != null) "-arinterval ${toString cfg.autoRepeatInterval}"; + ++ optional (cfg.autoRepeatInterval != null) "-arinterval ${toString cfg.autoRepeatInterval}" + ++ optional cfg.terminateOnReset "-terminate"; services.xserver.modules = concatLists (catAttrs "modules" cfg.drivers) ++ diff --git a/nixos/modules/system/activation/activation-script.nix b/nixos/modules/system/activation/activation-script.nix index dcf105eb7844..c2ac731d433d 100644 --- a/nixos/modules/system/activation/activation-script.nix +++ b/nixos/modules/system/activation/activation-script.nix @@ -19,6 +19,7 @@ let glibc # needed for getent shadow nettools # needed for hostname + utillinux # needed for mount and mountpoint ]; in @@ -168,12 +169,12 @@ in local options="$3" local fsType="$4" - if ${pkgs.utillinux}/bin/mountpoint -q "$mountPoint"; then + if mountpoint -q "$mountPoint"; then local options="remount,$options" else mkdir -m 0755 -p "$mountPoint" fi - ${pkgs.utillinux}/bin/mount -t "$fsType" -o "$options" "$device" "$mountPoint" + mount -t "$fsType" -o "$options" "$device" "$mountPoint" } source ${config.system.build.earlyMountScript} ''; diff --git a/nixos/modules/system/activation/switch-to-configuration.pl b/nixos/modules/system/activation/switch-to-configuration.pl index 8747c1e3d4ac..88e7847cf8c8 100644 --- a/nixos/modules/system/activation/switch-to-configuration.pl +++ b/nixos/modules/system/activation/switch-to-configuration.pl @@ -41,7 +41,7 @@ if ($action eq "switch" || $action eq "boot") { } # Just in case the new configuration hangs the system, do a sync now. -system("@coreutils@/bin/sync") unless ($ENV{"NIXOS_NO_SYNC"} // "") eq "1"; +system("@coreutils@/bin/sync", "-f", "/nix/store") unless ($ENV{"NIXOS_NO_SYNC"} // "") eq "1"; exit 0 if $action eq "boot"; @@ -383,6 +383,10 @@ system("@systemd@/bin/systemctl", "reset-failed"); # Make systemd reload its units. system("@systemd@/bin/systemctl", "daemon-reload") == 0 or $res = 3; +# Set the new tmpfiles +print STDERR "setting up tmpfiles\n"; +system("@systemd@/bin/systemd-tmpfiles", "--create", "--remove", "--exclude-prefix=/dev") == 0 or $res = 3; + # Reload units that need it. This includes remounting changed mount # units. if (scalar(keys %unitsToReload) > 0) { diff --git a/nixos/modules/system/boot/kernel.nix b/nixos/modules/system/boot/kernel.nix index e751ff141f70..cf70a891c0ca 100644 --- a/nixos/modules/system/boot/kernel.nix +++ b/nixos/modules/system/boot/kernel.nix @@ -176,7 +176,7 @@ in boot.initrd.availableKernelModules = [ # Note: most of these (especially the SATA/PATA modules) - # shouldn't be included by default since nixos-hardware-scan + # shouldn't be included by default since nixos-generate-config # detects them, but I'm keeping them for now for backwards # compatibility. diff --git a/nixos/modules/system/boot/loader/grub/grub.nix b/nixos/modules/system/boot/loader/grub/grub.nix index 23b970186a39..5ab2d0775518 100644 --- a/nixos/modules/system/boot/loader/grub/grub.nix +++ b/nixos/modules/system/boot/loader/grub/grub.nix @@ -54,7 +54,7 @@ let inherit (efi) canTouchEfiVariables; inherit (cfg) version extraConfig extraPerEntryConfig extraEntries forceInstall useOSProber - extraEntriesBeforeNixOS extraPrepareConfig configurationLimit copyKernels + extraEntriesBeforeNixOS extraPrepareConfig extraInitrd configurationLimit copyKernels default fsIdentifier efiSupport efiInstallAsRemovable gfxmodeEfi gfxmodeBios; path = (makeBinPath ([ pkgs.coreutils pkgs.gnused pkgs.gnugrep pkgs.findutils pkgs.diffutils pkgs.btrfs-progs @@ -267,6 +267,19 @@ in ''; }; + extraInitrd = mkOption { + type = types.nullOr types.path; + default = null; + example = "/boot/extra_initrafms.gz"; + description = '' + The path to a second initramfs to be supplied to the kernel. + This ramfs will not be copied to the store, so that it can + contain secrets such as LUKS keyfiles or ssh keys. + This implies that rolling back to a previous configuration + won't rollback the state of this file. + ''; + }; + useOSProber = mkOption { default = false; type = types.bool; diff --git a/nixos/modules/system/boot/loader/grub/install-grub.pl b/nixos/modules/system/boot/loader/grub/install-grub.pl index c9a51288747b..c7559cd634a2 100644 --- a/nixos/modules/system/boot/loader/grub/install-grub.pl +++ b/nixos/modules/system/boot/loader/grub/install-grub.pl @@ -49,6 +49,7 @@ my $extraPrepareConfig = get("extraPrepareConfig"); my $extraPerEntryConfig = get("extraPerEntryConfig"); my $extraEntries = get("extraEntries"); my $extraEntriesBeforeNixOS = get("extraEntriesBeforeNixOS") eq "true"; +my $extraInitrd = get("extraInitrd"); my $splashImage = get("splashImage"); my $configurationLimit = int(get("configurationLimit")); my $copyKernels = get("copyKernels") eq "true"; @@ -226,6 +227,13 @@ my $grubStore; if ($copyKernels == 0) { $grubStore = GrubFs($storePath); } +my $extraInitrdPath; +if ($extraInitrd) { + if (! -f $extraInitrd) { + print STDERR "Warning: the specified extraInitrd " . $extraInitrd . " doesn't exist. Your system won't boot without it.\n"; + } + $extraInitrdPath = GrubFs($extraInitrd); +} # Generate the header. my $conf .= "# Automatically generated. DO NOT EDIT THIS FILE!\n"; @@ -336,6 +344,9 @@ sub addEntry { my $kernel = copyToKernelsDir(Cwd::abs_path("$path/kernel")); my $initrd = copyToKernelsDir(Cwd::abs_path("$path/initrd")); + if ($extraInitrd) { + $initrd .= " " .$extraInitrdPath->path; + } my $xen = -e "$path/xen.gz" ? copyToKernelsDir(Cwd::abs_path("$path/xen.gz")) : undef; # FIXME: $confName @@ -358,6 +369,9 @@ sub addEntry { if ($copyKernels == 0) { $conf .= $grubStore->search . "\n"; } + if ($extraInitrd) { + $conf .= $extraInitrdPath->search . "\n"; + } $conf .= " $extraPerEntryConfig\n" if $extraPerEntryConfig; $conf .= " multiboot $xen $xenParams\n" if $xen; $conf .= " " . ($xen ? "module" : "linux") . " $kernel $kernelParams\n"; diff --git a/nixos/modules/system/boot/loader/systemd-boot/systemd-boot-builder.py b/nixos/modules/system/boot/loader/systemd-boot/systemd-boot-builder.py index b91d64bb0a7f..04cf17c1b0b4 100644 --- a/nixos/modules/system/boot/loader/systemd-boot/systemd-boot-builder.py +++ b/nixos/modules/system/boot/loader/systemd-boot/systemd-boot-builder.py @@ -101,11 +101,27 @@ def main(): parser.add_argument('default_config', metavar='DEFAULT-CONFIG', help='The default NixOS config to boot') args = parser.parse_args() + try: + with open("/etc/machine-id") as machine_file: + machine_id = machine_file.readlines()[0] + except IOError as e: + if e.errno != errno.ENOENT: + raise + # Since systemd version 232 a machine ID is required and it might not + # be there on newly installed systems, so let's generate one so that + # bootctl can find it and we can also pass it to write_entry() later. + cmd = ["@systemd@/bin/systemd-machine-id-setup", "--print"] + machine_id = subprocess.check_output(cmd).rstrip() + if os.getenv("NIXOS_INSTALL_GRUB") == "1": warnings.warn("NIXOS_INSTALL_GRUB env var deprecated, use NIXOS_INSTALL_BOOTLOADER", DeprecationWarning) os.environ["NIXOS_INSTALL_BOOTLOADER"] = "1" if os.getenv("NIXOS_INSTALL_BOOTLOADER") == "1": + # bootctl uses fopen() with modes "wxe" and fails if the file exists. + if os.path.exists("@efiSysMountPoint@/loader/loader.conf"): + os.unlink("@efiSysMountPoint@/loader/loader.conf") + if "@canTouchEfiVariables@" == "1": subprocess.check_call(["@systemd@/bin/bootctl", "--path=@efiSysMountPoint@", "install"]) else: @@ -113,13 +129,6 @@ def main(): mkdir_p("@efiSysMountPoint@/efi/nixos") mkdir_p("@efiSysMountPoint@/loader/entries") - try: - with open("/etc/machine-id") as machine_file: - machine_id = machine_file.readlines()[0] - except IOError as e: - if e.errno != errno.ENOENT: - raise - machine_id = None gens = get_generations("system") remove_old_entries(gens) diff --git a/nixos/modules/system/boot/luksroot.nix b/nixos/modules/system/boot/luksroot.nix index 1f412fe2d8f2..8978b73749b7 100644 --- a/nixos/modules/system/boot/luksroot.nix +++ b/nixos/modules/system/boot/luksroot.nix @@ -434,8 +434,8 @@ in chmod +x $out/bin/cryptsetup-askpass ${optionalString luks.yubikeySupport '' - copy_bin_and_libs ${pkgs.ykpers}/bin/ykchalresp - copy_bin_and_libs ${pkgs.ykpers}/bin/ykinfo + copy_bin_and_libs ${pkgs.yubikey-personalization}/bin/ykchalresp + copy_bin_and_libs ${pkgs.yubikey-personalization}/bin/ykinfo copy_bin_and_libs ${pkgs.openssl.bin}/bin/openssl cc -O3 -I${pkgs.openssl.dev}/include -L${pkgs.openssl.out}/lib ${./pbkdf2-sha512.c} -o pbkdf2-sha512 -lcrypto diff --git a/nixos/modules/system/boot/systemd.nix b/nixos/modules/system/boot/systemd.nix index 904404e1e472..bff6739db616 100644 --- a/nixos/modules/system/boot/systemd.nix +++ b/nixos/modules/system/boot/systemd.nix @@ -329,7 +329,7 @@ let ${let env = cfg.globalEnvironment // def.environment; in concatMapStrings (n: let s = optionalString (env."${n}" != null) - "Environment=\"${n}=${env.${n}}\"\n"; + "Environment=${builtins.toJSON "${n}=${env.${n}}"}\n"; in if stringLength s >= 2048 then throw "The value of the environment variable ‘${n}’ in systemd service ‘${name}.service’ is too long." else s) (attrNames env)} ${if def.reloadIfChanged then '' X-ReloadIfChanged=true @@ -842,6 +842,7 @@ in systemd.services.systemd-journald.stopIfChanged = false; systemd.targets.local-fs.unitConfig.X-StopOnReconfiguration = true; systemd.targets.remote-fs.unitConfig.X-StopOnReconfiguration = true; + systemd.targets.network-online.wantedBy = [ "multi-user.target" ]; systemd.services.systemd-binfmt.wants = [ "proc-sys-fs-binfmt_misc.automount" ]; # Don't bother with certain units in containers. diff --git a/nixos/modules/tasks/filesystems.nix b/nixos/modules/tasks/filesystems.nix index 8a4299113f2b..9f30eb611466 100644 --- a/nixos/modules/tasks/filesystems.nix +++ b/nixos/modules/tasks/filesystems.nix @@ -291,7 +291,7 @@ in # Sync mount options with systemd's src/core/mount-setup.c: mount_table. boot.specialFileSystems = { "/proc" = { fsType = "proc"; options = [ "nosuid" "noexec" "nodev" ]; }; - "/run" = { fsType = "tmpfs"; options = [ "nodev" "strictatime" "mode=755" "size=${config.boot.runSize}" ]; }; + "/run" = { fsType = "tmpfs"; options = [ "nosuid" "nodev" "strictatime" "mode=755" "size=${config.boot.runSize}" ]; }; "/dev" = { fsType = "devtmpfs"; options = [ "nosuid" "strictatime" "mode=755" "size=${config.boot.devSize}" ]; }; "/dev/shm" = { fsType = "tmpfs"; options = [ "nosuid" "nodev" "strictatime" "mode=1777" "size=${config.boot.devShmSize}" ]; }; "/dev/pts" = { fsType = "devpts"; options = [ "nosuid" "noexec" "mode=620" "gid=${toString config.ids.gids.tty}" ]; }; diff --git a/nixos/modules/tasks/filesystems/f2fs.nix b/nixos/modules/tasks/filesystems/f2fs.nix index 430ac630a885..d103ff1a57b5 100644 --- a/nixos/modules/tasks/filesystems/f2fs.nix +++ b/nixos/modules/tasks/filesystems/f2fs.nix @@ -10,7 +10,7 @@ in system.fsPackages = [ pkgs.f2fs-tools ]; - boot.initrd.availableKernelModules = mkIf inInitrd [ "f2fs" ]; + boot.initrd.availableKernelModules = mkIf inInitrd [ "f2fs" "crc32" ]; boot.initrd.extraUtilsCommands = mkIf inInitrd '' copy_bin_and_libs ${pkgs.f2fs-tools}/sbin/fsck.f2fs diff --git a/nixos/modules/tasks/filesystems/zfs.nix b/nixos/modules/tasks/filesystems/zfs.nix index 045cbeb7cff8..c8fa6c21a4f6 100644 --- a/nixos/modules/tasks/filesystems/zfs.nix +++ b/nixos/modules/tasks/filesystems/zfs.nix @@ -13,12 +13,14 @@ let cfgZfs = config.boot.zfs; cfgSnapshots = config.services.zfs.autoSnapshot; cfgSnapFlags = cfgSnapshots.flags; + cfgScrub = config.services.zfs.autoScrub; inInitrd = any (fs: fs == "zfs") config.boot.initrd.supportedFilesystems; inSystem = any (fs: fs == "zfs") config.boot.supportedFilesystems; enableAutoSnapshots = cfgSnapshots.enable; - enableZfs = inInitrd || inSystem || enableAutoSnapshots; + enableAutoScrub = cfgScrub.enable; + enableZfs = inInitrd || inSystem || enableAutoSnapshots || enableAutoScrub; kernel = config.boot.kernelPackages; @@ -217,6 +219,37 @@ in ''; }; }; + + services.zfs.autoScrub = { + enable = mkOption { + default = false; + type = types.bool; + description = '' + Enables periodic scrubbing of ZFS pools. + ''; + }; + + interval = mkOption { + default = "Sun, 02:00"; + type = types.str; + example = "daily"; + description = '' + Systemd calendar expression when to scrub ZFS pools. See + <citerefentry><refentrytitle>systemd.time</refentrytitle> + <manvolnum>5</manvolnum></citerefentry>. + ''; + }; + + pools = mkOption { + default = []; + type = types.listOf types.str; + example = [ "tank" ]; + description = '' + List of ZFS pools to periodically scrub. If empty, all pools + will be scrubbed. + ''; + }; + }; }; ###### implementation @@ -282,7 +315,7 @@ in zfsSupport = true; }; - environment.etc."zfs/zed.d".source = "${packages.zfsUser}/etc/zfs/zed.d/*"; + environment.etc."zfs/zed.d".source = "${packages.zfsUser}/etc/zfs/zed.d/"; system.fsPackages = [ packages.zfsUser ]; # XXX: needed? zfs doesn't have (need) a fsck environment.systemPackages = [ packages.zfsUser ] @@ -391,5 +424,31 @@ in }; }) snapshotNames); }) + + (mkIf enableAutoScrub { + systemd.services.zfs-scrub = { + description = "ZFS pools scrubbing"; + after = [ "zfs-import.target" ]; + serviceConfig = { + Type = "oneshot"; + }; + script = '' + ${packages.zfsUser}/bin/zpool scrub ${ + if cfgScrub.pools != [] then + (concatStringsSep " " cfgScrub.pools) + else + "$(${packages.zfsUser}/bin/zpool list -H -o name)" + } + ''; + }; + + systemd.timers.zfs-scrub = { + wantedBy = [ "timers.target" ]; + timerConfig = { + OnCalendar = cfgScrub.interval; + Persistent = "yes"; + }; + }; + }) ]; } diff --git a/nixos/modules/tasks/network-interfaces-scripted.nix b/nixos/modules/tasks/network-interfaces-scripted.nix index d94d9db54ca5..3571e00d04ec 100644 --- a/nixos/modules/tasks/network-interfaces-scripted.nix +++ b/nixos/modules/tasks/network-interfaces-scripted.nix @@ -60,21 +60,18 @@ let let deviceDependency = dev: - if (config.boot.isContainer == false) - then - # Trust udev when not in the container - optional (dev != null) (subsystemDevice dev) - else - # When in the container, check whether the interface is built from other definitions - if (hasAttr dev cfg.bridges) || - (hasAttr dev cfg.bonds) || - (hasAttr dev cfg.macvlans) || - (hasAttr dev cfg.sits) || - (hasAttr dev cfg.vlans) || - (hasAttr dev cfg.vswitches) || - (hasAttr dev cfg.wlanInterfaces) - then [ "${dev}-netdev.service" ] - else []; + # Use systemd service if we manage device creation, else + # trust udev when not in a container + if (hasAttr dev (filterAttrs (k: v: v.virtual) cfg.interfaces)) || + (hasAttr dev cfg.bridges) || + (hasAttr dev cfg.bonds) || + (hasAttr dev cfg.macvlans) || + (hasAttr dev cfg.sits) || + (hasAttr dev cfg.vlans) || + (hasAttr dev cfg.vswitches) || + (hasAttr dev cfg.wlanInterfaces) + then [ "${dev}-netdev.service" ] + else optional (dev != null && !config.boot.isContainer) (subsystemDevice dev); networkLocalCommands = { after = [ "network-setup.service" ]; @@ -211,7 +208,7 @@ let user "${i.virtualOwner}" ''; postStop = '' - ip link del ${i.name} + ip link del ${i.name} || true ''; }; @@ -223,7 +220,7 @@ let wantedBy = [ "network-setup.service" (subsystemDevice n) ]; bindsTo = deps ++ optional v.rstp "mstpd.service"; partOf = [ "network-setup.service" ] ++ optional v.rstp "mstpd.service"; - after = [ "network-pre.target" "mstpd.service" ] ++ deps + after = [ "network-pre.target" ] ++ deps ++ optional v.rstp "mstpd.service" ++ concatMap (i: [ "network-addresses-${i}.service" "network-link-${i}.service" ]) v.interfaces; before = [ "network-setup.service" (subsystemDevice n) ]; serviceConfig.Type = "oneshot"; @@ -349,7 +346,7 @@ let ip link set "${n}" up ''; postStop = '' - ip link delete "${n}" + ip link delete "${n}" || true ''; }); @@ -377,7 +374,7 @@ let ip link set "${n}" up ''; postStop = '' - ip link delete "${n}" + ip link delete "${n}" || true ''; }); @@ -401,7 +398,7 @@ let ip link set "${n}" up ''; postStop = '' - ip link delete "${n}" + ip link delete "${n}" || true ''; }); diff --git a/nixos/modules/tasks/network-interfaces-systemd.nix b/nixos/modules/tasks/network-interfaces-systemd.nix index 736292400fd4..8b85ff0057f9 100644 --- a/nixos/modules/tasks/network-interfaces-systemd.nix +++ b/nixos/modules/tasks/network-interfaces-systemd.nix @@ -126,7 +126,7 @@ in ms = trans (v: v + "ms"); in { Mode = simp "mode"; - TransmitHashPolixy = simp "xmit_hash_policy"; + TransmitHashPolicy = simp "xmit_hash_policy"; LACPTransmitRate = simp "lacp_rate"; MIIMonitorSec = ms "miimon"; UpDelaySec = ms "updelay"; diff --git a/nixos/modules/tasks/network-interfaces.nix b/nixos/modules/tasks/network-interfaces.nix index 898207ef7a3c..6467259766ea 100644 --- a/nixos/modules/tasks/network-interfaces.nix +++ b/nixos/modules/tasks/network-interfaces.nix @@ -358,7 +358,7 @@ in default = null; example = { address = "131.211.84.1"; - device = "enp3s0"; + interface = "enp3s0"; }; type = types.nullOr (types.coercedTo types.str gatewayCoerce (types.submodule gatewayOpts)); description = '' @@ -371,7 +371,7 @@ in default = null; example = { address = "2001:4d0:1e04:895::1"; - device = "enp3s0"; + interface = "enp3s0"; }; type = types.nullOr (types.coercedTo types.str gatewayCoerce (types.submodule gatewayOpts)); description = '' @@ -560,101 +560,102 @@ in }; - networking.bonds = mkOption { - default = { }; - example = literalExample { - bond0 = { - interfaces = [ "eth0" "wlan0" ]; - miimon = 100; + networking.bonds = + let + driverOptionsExample = { + miimon = "100"; mode = "active-backup"; }; - fatpipe.interfaces = [ "enp4s0f0" "enp4s0f1" "enp5s0f0" "enp5s0f1" ]; - }; - description = '' - This option allows you to define bond devices that aggregate multiple, - underlying networking interfaces together. The value of this option is - an attribute set. Each attribute specifies a bond, with the attribute - name specifying the name of the bond's network interface - ''; + in mkOption { + default = { }; + example = literalExample { + bond0 = { + interfaces = [ "eth0" "wlan0" ]; + driverOptions = driverOptionsExample; + }; + anotherBond.interfaces = [ "enp4s0f0" "enp4s0f1" "enp5s0f0" "enp5s0f1" ]; + }; + description = '' + This option allows you to define bond devices that aggregate multiple, + underlying networking interfaces together. The value of this option is + an attribute set. Each attribute specifies a bond, with the attribute + name specifying the name of the bond's network interface + ''; - type = with types; attrsOf (submodule { + type = with types; attrsOf (submodule { - options = { + options = { - interfaces = mkOption { - example = [ "enp4s0f0" "enp4s0f1" "wlan0" ]; - type = types.listOf types.str; - description = "The interfaces to bond together"; - }; + interfaces = mkOption { + example = [ "enp4s0f0" "enp4s0f1" "wlan0" ]; + type = types.listOf types.str; + description = "The interfaces to bond together"; + }; + + driverOptions = mkOption { + type = types.attrsOf types.str; + default = {}; + example = literalExample driverOptionsExample; + description = '' + Options for the bonding driver. + Documentation can be found in + <link xlink:href="https://www.kernel.org/doc/Documentation/networking/bonding.txt" /> + ''; - driverOptions = mkOption { - type = types.attrsOf types.str; - default = {}; - example = literalExample { - interfaces = [ "eth0" "wlan0" ]; - miimon = 100; - mode = "active-backup"; }; - description = '' - Options for the bonding driver. - Documentation can be found in - <link xlink:href="https://www.kernel.org/doc/Documentation/networking/bonding.txt" /> - ''; - }; + lacp_rate = mkOption { + default = null; + example = "fast"; + type = types.nullOr types.str; + description = '' + DEPRECATED, use `driverOptions`. + Option specifying the rate in which we'll ask our link partner + to transmit LACPDU packets in 802.3ad mode. + ''; + }; - lacp_rate = mkOption { - default = null; - example = "fast"; - type = types.nullOr types.str; - description = '' - DEPRECATED, use `driverOptions`. - Option specifying the rate in which we'll ask our link partner - to transmit LACPDU packets in 802.3ad mode. - ''; - }; + miimon = mkOption { + default = null; + example = 100; + type = types.nullOr types.int; + description = '' + DEPRECATED, use `driverOptions`. + Miimon is the number of millisecond in between each round of polling + by the device driver for failed links. By default polling is not + enabled and the driver is trusted to properly detect and handle + failure scenarios. + ''; + }; - miimon = mkOption { - default = null; - example = 100; - type = types.nullOr types.int; - description = '' - DEPRECATED, use `driverOptions`. - Miimon is the number of millisecond in between each round of polling - by the device driver for failed links. By default polling is not - enabled and the driver is trusted to properly detect and handle - failure scenarios. - ''; - }; + mode = mkOption { + default = null; + example = "active-backup"; + type = types.nullOr types.str; + description = '' + DEPRECATED, use `driverOptions`. + The mode which the bond will be running. The default mode for + the bonding driver is balance-rr, optimizing for throughput. + More information about valid modes can be found at + https://www.kernel.org/doc/Documentation/networking/bonding.txt + ''; + }; - mode = mkOption { - default = null; - example = "active-backup"; - type = types.nullOr types.str; - description = '' - DEPRECATED, use `driverOptions`. - The mode which the bond will be running. The default mode for - the bonding driver is balance-rr, optimizing for throughput. - More information about valid modes can be found at - https://www.kernel.org/doc/Documentation/networking/bonding.txt - ''; - }; + xmit_hash_policy = mkOption { + default = null; + example = "layer2+3"; + type = types.nullOr types.str; + description = '' + DEPRECATED, use `driverOptions`. + Selects the transmit hash policy to use for slave selection in + balance-xor, 802.3ad, and tlb modes. + ''; + }; - xmit_hash_policy = mkOption { - default = null; - example = "layer2+3"; - type = types.nullOr types.str; - description = '' - DEPRECATED, use `driverOptions`. - Selects the transmit hash policy to use for slave selection in - balance-xor, 802.3ad, and tlb modes. - ''; }; - }; - - }); - }; + }); + }; networking.macvlans = mkOption { default = { }; @@ -960,14 +961,8 @@ in source = "${pkgs.iputils.out}/bin/ping"; capabilities = "cap_net_raw+p"; }; - - ping6 = { - source = "${pkgs.iputils.out}/bin/ping6"; - capabilities = "cap_net_raw+p"; - }; } else { ping.source = "${pkgs.iputils.out}/bin/ping"; - "ping6".source = "${pkgs.iputils.out}/bin/ping6"; }; # Set the host and domain names in the activation script. Don't diff --git a/nixos/modules/virtualisation/amazon-init.nix b/nixos/modules/virtualisation/amazon-init.nix index 5797d9db4362..a7362423eb46 100644 --- a/nixos/modules/virtualisation/amazon-init.nix +++ b/nixos/modules/virtualisation/amazon-init.nix @@ -45,9 +45,8 @@ in { inherit script; description = "Reconfigure the system from EC2 userdata on startup"; - wantedBy = [ "sshd.service" ]; - before = [ "sshd.service" ]; - after = [ "network-online.target" ]; + wantedBy = [ "multi-user.target" ]; + after = [ "multi-user.target" ]; requires = [ "network-online.target" ]; restartIfChanged = false; diff --git a/nixos/modules/virtualisation/ec2-amis.nix b/nixos/modules/virtualisation/ec2-amis.nix index 0753e2ce9948..d592a23c303f 100644 --- a/nixos/modules/virtualisation/ec2-amis.nix +++ b/nixos/modules/virtualisation/ec2-amis.nix @@ -156,6 +156,10 @@ let self = { "16.09".ap-southeast-2.hvm-s3 = "ami-87f4f0e4"; "16.09".ap-southeast-2.pv-ebs = "ami-d8ede9bb"; "16.09".ap-southeast-2.pv-s3 = "ami-a6ebefc5"; + "16.09".ca-central-1.hvm-ebs = "ami-9f863bfb"; + "16.09".ca-central-1.hvm-s3 = "ami-ea85388e"; + "16.09".ca-central-1.pv-ebs = "ami-ce8a37aa"; + "16.09".ca-central-1.pv-s3 = "ami-448a3720"; "16.09".eu-central-1.hvm-ebs = "ami-1b884774"; "16.09".eu-central-1.hvm-s3 = "ami-b08c43df"; "16.09".eu-central-1.pv-ebs = "ami-888946e7"; diff --git a/nixos/modules/virtualisation/ecs-agent.nix b/nixos/modules/virtualisation/ecs-agent.nix index 18e45e0b8457..fc51b159579e 100644 --- a/nixos/modules/virtualisation/ecs-agent.nix +++ b/nixos/modules/virtualisation/ecs-agent.nix @@ -12,6 +12,7 @@ in { type = types.path; description = "The ECS agent package to use"; default = pkgs.ecs-agent; + defaultText = "pkgs.ecs-agent"; }; extra-environment = mkOption { diff --git a/nixos/modules/virtualisation/google-compute-image.nix b/nixos/modules/virtualisation/google-compute-image.nix index 0e6825c3f5da..556454c6b5f8 100644 --- a/nixos/modules/virtualisation/google-compute-image.nix +++ b/nixos/modules/virtualisation/google-compute-image.nix @@ -23,7 +23,7 @@ in postVM = '' - PATH=$PATH:${stdenv.lib.makeBinPath [ pkgs.gnutar pkgs.gzip ]} + PATH=$PATH:${pkgs.stdenv.lib.makeBinPath [ pkgs.gnutar pkgs.gzip ]} pushd $out mv $diskImageBase disk.raw tar -Szcf $diskImageBase.tar.gz disk.raw diff --git a/nixos/modules/virtualisation/libvirtd.nix b/nixos/modules/virtualisation/libvirtd.nix index 5f669dee7545..101ea9a4f51b 100644 --- a/nixos/modules/virtualisation/libvirtd.nix +++ b/nixos/modules/virtualisation/libvirtd.nix @@ -13,6 +13,9 @@ let auth_unix_rw = "none" ${cfg.extraConfig} ''; + qemuConfigFile = pkgs.writeText "qemu.conf" '' + ${cfg.qemuVerbatimConfig} + ''; in { @@ -48,6 +51,18 @@ in { ''; }; + virtualisation.libvirtd.qemuVerbatimConfig = mkOption { + type = types.lines; + default = '' + namespaces = [] + ''; + description = '' + Contents written to the qemu configuration file, qemu.conf. + Make sure to include a proper namespace configuration when + supplying custom configuration. + ''; + }; + virtualisation.libvirtd.extraOptions = mkOption { type = types.listOf types.str; default = [ ]; @@ -119,6 +134,9 @@ in { cp -npd ${pkgs.libvirt}/var/lib/$i /var/lib/$i done + # Copy generated qemu config to libvirt directory + cp -f ${qemuConfigFile} /var/lib/libvirt/qemu.conf + # libvirtd puts the full path of the emulator binary in the machine # config file. But this path can unfortunately be garbage collected # while still being used by the virtual machine. So update the diff --git a/nixos/modules/virtualisation/lxc.nix b/nixos/modules/virtualisation/lxc.nix index 6759ff0f2fe9..2310fe984325 100644 --- a/nixos/modules/virtualisation/lxc.nix +++ b/nixos/modules/virtualisation/lxc.nix @@ -71,6 +71,7 @@ in environment.etc."lxc/lxc.conf".text = cfg.systemConfig; environment.etc."lxc/lxc-usernet".text = cfg.usernetConfig; environment.etc."lxc/default.conf".text = cfg.defaultConfig; + systemd.tmpfiles.rules = [ "d /var/lib/lxc/rootfs 0755 root root -" ]; security.apparmor.packages = [ pkgs.lxc ]; security.apparmor.profiles = [ "${pkgs.lxc}/etc/apparmor.d/lxc-containers" ]; diff --git a/nixos/modules/virtualisation/nova-config.nix b/nixos/modules/virtualisation/nova-config.nix new file mode 100644 index 000000000000..aac11ec8a178 --- /dev/null +++ b/nixos/modules/virtualisation/nova-config.nix @@ -0,0 +1,57 @@ +{ config, lib, pkgs, ... }: + +with lib; + +{ + imports = [ + ../profiles/qemu-guest.nix + ../profiles/headless.nix + ./grow-partition.nix + ]; + + config = { + fileSystems."/" = { + device = "/dev/disk/by-label/nixos"; + autoResize = true; + }; + + virtualisation.growPartition = true; + + boot.kernelParams = [ "console=ttyS0" ]; + boot.loader.grub.device = "/dev/vda"; + boot.loader.timeout = 0; + + # Allow root logins + services.openssh.enable = true; + services.openssh.permitRootLogin = "prohibit-password"; + + # Put /tmp and /var on /ephemeral0, which has a lot more space. + # Unfortunately we can't do this with the `fileSystems' option + # because it has no support for creating the source of a bind + # mount. Also, "move" /nix to /ephemeral0 by layering a unionfs-fuse + # mount on top of it so we have a lot more space for Nix operations. + + /* + boot.initrd.postMountCommands = + '' + mkdir -m 1777 -p $targetRoot/ephemeral0/tmp + mkdir -m 1777 -p $targetRoot/tmp + mount --bind $targetRoot/ephemeral0/tmp $targetRoot/tmp + + mkdir -m 755 -p $targetRoot/ephemeral0/var + mkdir -m 755 -p $targetRoot/var + mount --bind $targetRoot/ephemeral0/var $targetRoot/var + + mkdir -p /unionfs-chroot/ro-nix + mount --rbind $targetRoot/nix /unionfs-chroot/ro-nix + + mkdir -p /unionfs-chroot/rw-nix + mkdir -m 755 -p $targetRoot/ephemeral0/nix + mount --rbind $targetRoot/ephemeral0/nix /unionfs-chroot/rw-nix + unionfs -o allow_other,cow,nonempty,chroot=/unionfs-chroot,max_files=32768 /rw-nix=RW:/ro-nix=RO $targetRoot/nix + ''; + + boot.initrd.supportedFilesystems = [ "unionfs-fuse" ]; + */ + }; +} diff --git a/nixos/modules/virtualisation/nova-image.nix b/nixos/modules/virtualisation/nova-image.nix deleted file mode 100644 index e253c77ebb4f..000000000000 --- a/nixos/modules/virtualisation/nova-image.nix +++ /dev/null @@ -1,65 +0,0 @@ -# Usage: -# $ NIXOS_CONFIG=`pwd`/nixos/modules/virtualisation/nova-image.nix nix-build '<nixpkgs/nixos>' -A config.system.build.novaImage - -{ config, lib, pkgs, ... }: - -with lib; - -{ - system.build.novaImage = import ../../lib/make-disk-image.nix { - inherit pkgs lib config; - partitioned = true; - diskSize = 1 * 1024; - configFile = pkgs.writeText "configuration.nix" - '' - { - imports = [ <nixpkgs/nixos/modules/virtualisation/nova-image.nix> ]; - } - ''; - }; - - imports = [ - ../profiles/qemu-guest.nix - ../profiles/headless.nix - ]; - - fileSystems."/".device = "/dev/disk/by-label/nixos"; - - boot.kernelParams = [ "console=ttyS0" ]; - boot.loader.grub.device = "/dev/vda"; - boot.loader.timeout = 0; - - # Allow root logins - services.openssh.enable = true; - services.openssh.permitRootLogin = "prohibit-password"; - - # Put /tmp and /var on /ephemeral0, which has a lot more space. - # Unfortunately we can't do this with the `fileSystems' option - # because it has no support for creating the source of a bind - # mount. Also, "move" /nix to /ephemeral0 by layering a unionfs-fuse - # mount on top of it so we have a lot more space for Nix operations. - - /* - boot.initrd.postMountCommands = - '' - mkdir -m 1777 -p $targetRoot/ephemeral0/tmp - mkdir -m 1777 -p $targetRoot/tmp - mount --bind $targetRoot/ephemeral0/tmp $targetRoot/tmp - - mkdir -m 755 -p $targetRoot/ephemeral0/var - mkdir -m 755 -p $targetRoot/var - mount --bind $targetRoot/ephemeral0/var $targetRoot/var - - mkdir -p /unionfs-chroot/ro-nix - mount --rbind $targetRoot/nix /unionfs-chroot/ro-nix - - mkdir -p /unionfs-chroot/rw-nix - mkdir -m 755 -p $targetRoot/ephemeral0/nix - mount --rbind $targetRoot/ephemeral0/nix /unionfs-chroot/rw-nix - unionfs -o allow_other,cow,nonempty,chroot=/unionfs-chroot,max_files=32768 /rw-nix=RW:/ro-nix=RO $targetRoot/nix - ''; - - boot.initrd.supportedFilesystems = [ "unionfs-fuse" ]; - */ - -} diff --git a/nixos/modules/virtualisation/openstack/glance.nix b/nixos/modules/virtualisation/openstack/glance.nix index 4d85718e369c..7862409a65ec 100644 --- a/nixos/modules/virtualisation/openstack/glance.nix +++ b/nixos/modules/virtualisation/openstack/glance.nix @@ -43,7 +43,7 @@ in { package = mkOption { type = types.package; default = pkgs.glance; - example = literalExample "pkgs.glance"; + defaultText = "pkgs.glance"; description = '' Glance package to use. ''; diff --git a/nixos/modules/virtualisation/qemu-vm.nix b/nixos/modules/virtualisation/qemu-vm.nix index 56a05028b1d1..1933f11d1fff 100644 --- a/nixos/modules/virtualisation/qemu-vm.nix +++ b/nixos/modules/virtualisation/qemu-vm.nix @@ -136,15 +136,17 @@ let else "-nographic -serial pty"; } '' - # Create a /boot EFI partition with 40M - ${pkgs.gptfdisk}/bin/sgdisk -G /dev/vda - ${pkgs.gptfdisk}/bin/sgdisk -a 1 -n 1:34:2047 -c 1:"BIOS Boot Partition" -t 1:ef02 /dev/vda - ${pkgs.gptfdisk}/bin/sgdisk -a 512 -N 2 -c 2:"EFI System" -t 2:ef00 /dev/vda - ${pkgs.gptfdisk}/bin/sgdisk -A 1:set:1 /dev/vda - ${pkgs.gptfdisk}/bin/sgdisk -A 2:set:2 /dev/vda - ${pkgs.gptfdisk}/bin/sgdisk -h 2 /dev/vda - ${pkgs.gptfdisk}/bin/sgdisk -C /dev/vda - ${pkgs.utillinux}/bin/sfdisk /dev/vda -A 2 + # Create a /boot EFI partition with 40M and arbitrary but fixed GUIDs for reproducibility + ${pkgs.gptfdisk}/bin/sgdisk \ + --set-alignment=1 --new=1:34:2047 --change-name=1:BIOSBootPartition --typecode=1:ef02 \ + --set-alignment=512 --largest-new=2 --change-name=2:EFISystem --typecode=2:ef00 \ + --attributes=1:set:1 \ + --attributes=2:set:2 \ + --disk-guid=97FD5997-D90B-4AA3-8D16-C1723AEA73C1 \ + --partition-guid=1:1C06F03B-704E-4657-B9CD-681A087A2FDC \ + --partition-guid=2:970C694F-AFD0-4B99-B750-CDB7A329AB6F \ + --hybrid 2 \ + --recompute-chs /dev/vda . /sys/class/block/vda2/uevent mknod /dev/vda2 b $MAJOR $MINOR . /sys/class/block/vda/uevent diff --git a/nixos/modules/virtualisation/virtualbox-guest.nix b/nixos/modules/virtualisation/virtualbox-guest.nix index d253e9eab62b..5da4b7e3bafd 100644 --- a/nixos/modules/virtualisation/virtualbox-guest.nix +++ b/nixos/modules/virtualisation/virtualbox-guest.nix @@ -15,18 +15,27 @@ in ###### interface - options.virtualisation.virtualbox.guest.enable = mkOption { - default = false; - description = "Whether to enable the VirtualBox service and other guest additions."; + options.virtualisation.virtualbox.guest = { + enable = mkOption { + default = false; + type = types.bool; + description = "Whether to enable the VirtualBox service and other guest additions."; + }; + + x11 = mkOption { + default = true; + type = types.bool; + description = "Whether to enable x11 graphics"; + }; }; ###### implementation - config = mkIf cfg.enable { - assertions = [ { + config = mkIf cfg.enable (mkMerge [{ + assertions = [{ assertion = pkgs.stdenv.isi686 || pkgs.stdenv.isx86_64; message = "Virtualbox not currently supported on ${pkgs.stdenv.system}"; - } ]; + }]; environment.systemPackages = [ kernel.virtualboxGuestAdditions ]; @@ -49,6 +58,16 @@ in serviceConfig.ExecStart = "@${kernel.virtualboxGuestAdditions}/bin/VBoxService VBoxService --foreground"; }; + services.udev.extraRules = + '' + # /dev/vboxuser is necessary for VBoxClient to work. Maybe we + # should restrict this to logged-in users. + KERNEL=="vboxuser", OWNER="root", GROUP="root", MODE="0666" + + # Allow systemd dependencies on vboxguest. + SUBSYSTEM=="misc", KERNEL=="vboxguest", TAG+="systemd" + ''; + } (mkIf cfg.x11 { services.xserver.videoDrivers = mkOverride 50 [ "virtualbox" "modesetting" ]; services.xserver.config = @@ -69,16 +88,6 @@ in PATH=${makeBinPath [ pkgs.gnugrep pkgs.which pkgs.xorg.xorgserver.out ]}:$PATH \ ${kernel.virtualboxGuestAdditions}/bin/VBoxClient-all ''; - - services.udev.extraRules = - '' - # /dev/vboxuser is necessary for VBoxClient to work. Maybe we - # should restrict this to logged-in users. - KERNEL=="vboxuser", OWNER="root", GROUP="root", MODE="0666" - - # Allow systemd dependencies on vboxguest. - SUBSYSTEM=="misc", KERNEL=="vboxguest", TAG+="systemd" - ''; - }; + })]); } diff --git a/nixos/modules/virtualisation/xen-dom0.nix b/nixos/modules/virtualisation/xen-dom0.nix index 67eef0ec1e4c..57487f704519 100644 --- a/nixos/modules/virtualisation/xen-dom0.nix +++ b/nixos/modules/virtualisation/xen-dom0.nix @@ -27,6 +27,36 @@ in ''; }; + virtualisation.xen.package = mkOption { + type = types.package; + default = pkgs.xen; + defaultText = "pkgs.xen"; + example = literalExample "pkgs.xen-light"; + description = '' + The package used for Xen binary. + ''; + }; + + virtualisation.xen.qemu = mkOption { + type = types.path; + default = "${pkgs.xen}/lib/xen/bin/qemu-system-i386"; + defaultText = "\${pkgs.xen}/lib/xen/bin/qemu-system-i386"; + example = literalExample "''${pkgs.qemu_xen-light}/bin/qemu-system-i386"; + description = '' + The qemu binary to use for Dom-0 backend. + ''; + }; + + virtualisation.xen.qemu-package = mkOption { + type = types.package; + default = pkgs.xen; + defaultText = "pkgs.xen"; + example = literalExample "pkgs.qemu_xen-light"; + description = '' + The package with qemu binaries for xendomains. + ''; + }; + virtualisation.xen.bootParams = mkOption { default = ""; @@ -106,9 +136,9 @@ in message = "Xen currently does not support EFI boot"; } ]; - virtualisation.xen.stored = mkDefault "${pkgs.xen}/bin/oxenstored"; + virtualisation.xen.stored = mkDefault "${cfg.package}/bin/oxenstored"; - environment.systemPackages = [ pkgs.xen ]; + environment.systemPackages = [ cfg.package ]; # Make sure Domain 0 gets the required configuration #boot.kernelPackages = pkgs.boot.kernelPackages.override { features={xen_dom0=true;}; }; @@ -144,7 +174,7 @@ in system.extraSystemBuilderCmds = '' - ln -s ${pkgs.xen}/boot/xen.gz $out/xen.gz + ln -s ${cfg.package}/boot/xen.gz $out/xen.gz echo "${toString cfg.bootParams}" > $out/xen-params ''; @@ -180,19 +210,19 @@ in environment.etc = - [ { source = "${pkgs.xen}/etc/xen/xl.conf"; + [ { source = "${cfg.package}/etc/xen/xl.conf"; target = "xen/xl.conf"; } - { source = "${pkgs.xen}/etc/xen/scripts"; + { source = "${cfg.package}/etc/xen/scripts"; target = "xen/scripts"; } - { source = "${pkgs.xen}/etc/default/xendomains"; + { source = "${cfg.package}/etc/default/xendomains"; target = "default/xendomains"; } ]; # Xen provides udev rules. - services.udev.packages = [ pkgs.xen ]; + services.udev.packages = [ cfg.package ]; services.udev.path = [ pkgs.bridge-utils pkgs.iproute ]; @@ -217,7 +247,7 @@ in time=0 timeout=30 # Wait for xenstored to actually come up, timing out after 30 seconds - while [ $time -lt $timeout ] && ! `${pkgs.xen}/bin/xenstore-read -s / >/dev/null 2>&1` ; do + while [ $time -lt $timeout ] && ! `${cfg.package}/bin/xenstore-read -s / >/dev/null 2>&1` ; do time=$(($time+1)) sleep 1 done @@ -228,8 +258,8 @@ in exit 1 fi - ${pkgs.xen}/bin/xenstore-write "/local/domain/0/name" "Domain-0" - ${pkgs.xen}/bin/xenstore-write "/local/domain/0/domid" 0 + ${cfg.package}/bin/xenstore-write "/local/domain/0/name" "Domain-0" + ${cfg.package}/bin/xenstore-write "/local/domain/0/domid" 0 ''; }; @@ -256,7 +286,7 @@ in ''; serviceConfig = { ExecStart = '' - ${pkgs.xen}/bin/xenconsoled${optionalString cfg.trace " --log=all --log-dir=/var/log/xen"} + ${cfg.package}/bin/xenconsoled${optionalString cfg.trace " --log=all --log-dir=/var/log/xen"} ''; }; }; @@ -267,8 +297,8 @@ in wantedBy = [ "multi-user.target" ]; after = [ "xen-console.service" ]; serviceConfig.ExecStart = '' - ${pkgs.xen}/lib/xen/bin/qemu-system-i386 -xen-domid 0 -xen-attach -name dom0 -nographic -M xenpv \ - -monitor /dev/null -serial /dev/null -parallel /dev/null + ${cfg.qemu} -xen-attach -xen-domid 0 -name dom0 -M xenpv \ + -nographic -monitor /dev/null -serial /dev/null -parallel /dev/null ''; }; @@ -277,7 +307,7 @@ in description = "Xen Watchdog Daemon"; wantedBy = [ "multi-user.target" ]; after = [ "xen-qemu.service" ]; - serviceConfig.ExecStart = "${pkgs.xen}/bin/xenwatchdogd 30 15"; + serviceConfig.ExecStart = "${cfg.package}/bin/xenwatchdogd 30 15"; serviceConfig.Type = "forking"; serviceConfig.RestartSec = "1"; serviceConfig.Restart = "on-failure"; @@ -366,11 +396,11 @@ in before = [ "dhcpd.service" ]; restartIfChanged = false; serviceConfig.RemainAfterExit = "yes"; - path = [ pkgs.xen ]; - environment.XENDOM_CONFIG = "${pkgs.xen}/etc/sysconfig/xendomains"; + path = [ cfg.package cfg.qemu-package ]; + environment.XENDOM_CONFIG = "${cfg.package}/etc/sysconfig/xendomains"; preStart = "mkdir -p /var/lock/subsys -m 755"; - serviceConfig.ExecStart = "${pkgs.xen}/etc/init.d/xendomains start"; - serviceConfig.ExecStop = "${pkgs.xen}/etc/init.d/xendomains stop"; + serviceConfig.ExecStart = "${cfg.package}/etc/init.d/xendomains start"; + serviceConfig.ExecStop = "${cfg.package}/etc/init.d/xendomains stop"; }; }; diff --git a/nixos/modules/virtualisation/xen-domU.nix b/nixos/modules/virtualisation/xen-domU.nix index 8dd0d1dbfd2c..b46002c10b54 100644 --- a/nixos/modules/virtualisation/xen-domU.nix +++ b/nixos/modules/virtualisation/xen-domU.nix @@ -3,11 +3,8 @@ { config, pkgs, ... }: { - # We're being booted using pv-grub, which means that we need to - # generate a GRUB 1 menu without actually installing GRUB. - boot.loader.grub.version = 1; + boot.loader.grub.version = 2; boot.loader.grub.device = "nodev"; - boot.loader.grub.extraPerEntryConfig = "root (hd0)"; boot.initrd.kernelModules = [ "xen-blkfront" "xen-tpmfront" "xen-kbdfront" "xen-fbfront" diff --git a/nixos/release-combined.nix b/nixos/release-combined.nix index 6c048e8a0aca..1953fd1a26a7 100644 --- a/nixos/release-combined.nix +++ b/nixos/release-combined.nix @@ -4,7 +4,7 @@ { nixpkgs ? { outPath = ./..; revCount = 56789; shortRev = "gfedcba"; } , stableBranch ? false -, supportedSystems ? [ "x86_64-linux" "i686-linux" ] +, supportedSystems ? [ "x86_64-linux" "i686-linux" "aarch64-linux" ] }: let @@ -68,11 +68,11 @@ in rec { (all nixos.tests.boot.uefiCdrom) (all nixos.tests.boot.uefiUsb) (all nixos.tests.boot-stage1) - (all nixos.tests.hibernate) + nixos.tests.hibernate.x86_64-linux # i686 is flaky, see #23107 (all nixos.tests.ecryptfs) (all nixos.tests.ipv6) (all nixos.tests.i3wm) - (all nixos.tests.kde5) + (all nixos.tests.plasma5) #(all nixos.tests.lightdm) (all nixos.tests.login) (all nixos.tests.misc) diff --git a/nixos/release.nix b/nixos/release.nix index 0f93deddf263..0359d0907cca 100644 --- a/nixos/release.nix +++ b/nixos/release.nix @@ -1,6 +1,6 @@ { nixpkgs ? { outPath = ./..; revCount = 56789; shortRev = "gfedcba"; } , stableBranch ? false -, supportedSystems ? [ "x86_64-linux" "i686-linux" ] +, supportedSystems ? [ "x86_64-linux" "i686-linux" "aarch64-linux" ] }: with import ../lib; @@ -255,7 +255,7 @@ in rec { tests.influxdb = callTest tests/influxdb.nix {}; tests.ipv6 = callTest tests/ipv6.nix {}; tests.jenkins = callTest tests/jenkins.nix {}; - tests.kde5 = callTest tests/kde5.nix {}; + tests.plasma5 = callTest tests/plasma5.nix {}; tests.keymap = callSubTests tests/keymap.nix {}; tests.initrdNetwork = callTest tests/initrd-network.nix {}; tests.keystone = callTest tests/keystone.nix {}; @@ -286,6 +286,7 @@ in rec { tests.pam-oath-login = callTest tests/pam-oath-login.nix {}; #tests.panamax = hydraJob (import tests/panamax.nix { system = "x86_64-linux"; }); tests.peerflix = callTest tests/peerflix.nix {}; + tests.pgjwt = callTest tests/pgjwt.nix {}; tests.postgresql = callTest tests/postgresql.nix {}; tests.printing = callTest tests/printing.nix {}; tests.proxy = callTest tests/proxy.nix {}; @@ -326,7 +327,7 @@ in rec { kde = makeClosure ({ pkgs, ... }: { services.xserver.enable = true; services.xserver.displayManager.sddm.enable = true; - services.xserver.desktopManager.kde5.enable = true; + services.xserver.desktopManager.plasma5.enable = true; }); xfce = makeClosure ({ pkgs, ... }: diff --git a/nixos/tests/buildbot.nix b/nixos/tests/buildbot.nix new file mode 100644 index 000000000000..13a162e6c6e8 --- /dev/null +++ b/nixos/tests/buildbot.nix @@ -0,0 +1,46 @@ +# Test ensures buildbot master comes up correctly and workers can connect + +import ./make-test.nix ({ pkgs, ... } : { + name = "buildbot"; + + nodes = { + bbmaster = { config, pkgs, nodes, ... }: { + services.buildbot-master = { + enable = true; + factorySteps = [ + "steps.Git(repourl='git://github.com/buildbot/pyflakes.git', mode='incremental')" + "steps.ShellCommand(command=['trial', 'pyflakes'])" + ]; + changeSource = [ + "changes.GitPoller('git://github.com/buildbot/pyflakes.git', workdir='gitpoller-workdir', branch='master', pollinterval=300)" + ]; + }; + networking.firewall.allowedTCPPorts = [ 8010 9989 ]; + }; + + bbworker = { config, pkgs, ... }: { + services.buildbot-worker = { + enable = true; + masterUrl = "bbmaster:9989"; + }; + }; + }; + + testScript = '' + + $bbmaster->waitForUnit("network.target"); + $bbworker->waitForUnit("network.target"); + + # Additional tests to be added + #$bbmaster->waitForUnit("buildbot-master.service"); + #$bbmaster->waitUntilSucceeds("curl -s --head http://bbmaster:8010") =~ /200 OK/ or die; + #$bbworker->waitForUnit("buildbot-worker.service"); + #$bbworker->waitUntilSucceeds("tail -10 /home/bbworker/worker/twistd.log") =~ /success/ or die; + + ''; + + meta = with pkgs.stdenv.lib.maintainers; { + maintainers = [ nand0p ]; + }; + +}) diff --git a/nixos/tests/cjdns.nix b/nixos/tests/cjdns.nix index f32ec52dfc26..466663799241 100644 --- a/nixos/tests/cjdns.nix +++ b/nixos/tests/cjdns.nix @@ -109,14 +109,14 @@ import ./make-test.nix ({ pkgs, ...} : { # ping a few times each to let the routing table establish itself - $alice->succeed("ping6 -c 4 $carolIp6"); - $bob->succeed("ping6 -c 4 $carolIp6"); + $alice->succeed("ping -c 4 $carolIp6"); + $bob->succeed("ping -c 4 $carolIp6"); - $carol->succeed("ping6 -c 4 $aliceIp6"); - $carol->succeed("ping6 -c 4 $bobIp6"); + $carol->succeed("ping -c 4 $aliceIp6"); + $carol->succeed("ping -c 4 $bobIp6"); - $alice->succeed("ping6 -c 4 $bobIp6"); - $bob->succeed("ping6 -c 4 $aliceIp6"); + $alice->succeed("ping -c 4 $bobIp6"); + $bob->succeed("ping -c 4 $aliceIp6"); $alice->waitForUnit("httpd.service"); diff --git a/nixos/tests/containers-bridge.nix b/nixos/tests/containers-bridge.nix index bb32d852a6f5..598abd22e61b 100644 --- a/nixos/tests/containers-bridge.nix +++ b/nixos/tests/containers-bridge.nix @@ -66,7 +66,7 @@ import ./make-test.nix ({ pkgs, ...} : { "${containerIp6}" =~ /([^\/]+)\/([0-9+])/; my $ip6 = $1; chomp $ip6; - $machine->succeed("ping6 -n -c 1 $ip6"); + $machine->succeed("ping -n -c 1 $ip6"); $machine->succeed("curl --fail http://[$ip6]/ > /dev/null"); # Stop the container. diff --git a/nixos/tests/containers-extra_veth.nix b/nixos/tests/containers-extra_veth.nix index 2a54b1d961c8..6339c8c558b9 100644 --- a/nixos/tests/containers-extra_veth.nix +++ b/nixos/tests/containers-extra_veth.nix @@ -84,7 +84,7 @@ import ./make-test.nix ({ pkgs, ...} : { # Ping on main veth $machine->succeed("ping -n -c 1 192.168.0.100"); - $machine->succeed("ping6 -n -c 1 fc00::2"); + $machine->succeed("ping -n -c 1 fc00::2"); # Ping on the first extra veth $machine->succeed("ping -n -c 1 192.168.1.100 >&2"); diff --git a/nixos/tests/containers-ipv6.nix b/nixos/tests/containers-ipv6.nix index 320465ebb95b..f676ed122bb3 100644 --- a/nixos/tests/containers-ipv6.nix +++ b/nixos/tests/containers-ipv6.nix @@ -47,7 +47,7 @@ import ./make-test.nix ({ pkgs, ...} : { # multi-user.target, we should now be able to access it. my $ip = "${localIp}"; chomp $ip; - $machine->succeed("ping6 -n -c 1 $ip"); + $machine->succeed("ping -n -c 1 $ip"); $machine->succeed("curl --fail http://[$ip]/ > /dev/null"); # Stop the container. diff --git a/nixos/tests/ec2.nix b/nixos/tests/ec2.nix index e1f7143e3a95..4ec7e56cc6cb 100644 --- a/nixos/tests/ec2.nix +++ b/nixos/tests/ec2.nix @@ -25,8 +25,13 @@ let # access. Mostly copied from # modules/profiles/installation-device.nix. system.extraDependencies = - [ pkgs.stdenv pkgs.busybox pkgs.perlPackages.ArchiveCpio - pkgs.unionfs-fuse pkgs.mkinitcpio-nfs-utils + with pkgs; [ + stdenv busybox perlPackages.ArchiveCpio unionfs-fuse mkinitcpio-nfs-utils + + # These are used in the configure-from-userdata tests for EC2. Httpd and valgrind are requested + # directly by the configuration we set, and libxslt.bin is used indirectly as a build dependency + # of the derivation for dbus configuration files. + apacheHttpd valgrind.doc libxslt.bin ]; } ]; @@ -137,6 +142,8 @@ in { # ### http://nixos.org/channels/nixos-unstable nixos userData = '' + { pkgs, ... }: + { imports = [ <nixpkgs/nixos/modules/virtualisation/amazon-image.nix> @@ -146,12 +153,22 @@ in { environment.etc.testFile = { text = "whoa"; }; + + services.httpd = { + enable = true; + adminAddr = "test@example.org"; + documentRoot = "${pkgs.valgrind.doc}/share/doc/valgrind/html"; + }; + networking.firewall.allowedTCPPorts = [ 80 ]; } ''; script = '' $machine->start; $machine->waitForFile("/etc/testFile"); $machine->succeed("cat /etc/testFile | grep -q 'whoa'"); + + $machine->waitForUnit("httpd.service"); + $machine->succeed("curl http://localhost | grep Valgrind"); ''; }; } diff --git a/nixos/tests/ipv6.nix b/nixos/tests/ipv6.nix index 4e2e6379cad3..060f63216796 100644 --- a/nixos/tests/ipv6.nix +++ b/nixos/tests/ipv6.nix @@ -54,22 +54,22 @@ import ./make-test.nix ({ pkgs, ...} : { } subtest "loopback address", sub { - $client->succeed("ping6 -c 1 ::1 >&2"); - $client->fail("ping6 -c 1 ::2 >&2"); + $client->succeed("ping -c 1 ::1 >&2"); + $client->fail("ping -c 1 ::2 >&2"); }; subtest "local link addressing", sub { my $clientIp = waitForAddress $client, "eth1", "link"; my $serverIp = waitForAddress $server, "eth1", "link"; - $client->succeed("ping6 -c 1 -I eth1 $clientIp >&2"); - $client->succeed("ping6 -c 1 -I eth1 $serverIp >&2"); + $client->succeed("ping -c 1 $clientIp%eth1 >&2"); + $client->succeed("ping -c 1 $serverIp%eth1 >&2"); }; subtest "global addressing", sub { my $clientIp = waitForAddress $client, "eth1", "global"; my $serverIp = waitForAddress $server, "eth1", "global"; - $client->succeed("ping6 -c 1 $clientIp >&2"); - $client->succeed("ping6 -c 1 $serverIp >&2"); + $client->succeed("ping -c 1 $clientIp >&2"); + $client->succeed("ping -c 1 $serverIp >&2"); $client->succeed("curl --fail -g http://[$serverIp]"); $client->fail("curl --fail -g http://[$clientIp]"); }; diff --git a/nixos/tests/leaps.nix b/nixos/tests/leaps.nix index 3c390e1a1691..6163fed56b6f 100644 --- a/nixos/tests/leaps.nix +++ b/nixos/tests/leaps.nix @@ -24,6 +24,7 @@ import ./make-test.nix ({ pkgs, ... }: '' startAll; $server->waitForOpenPort(6666); - $client->succeed("curl http://server:6666/leaps/ | grep -i 'leaps'"); + $client->waitForUnit("network.target"); + $client->succeed("${pkgs.curl}/bin/curl http://server:6666/leaps/ | grep -i 'leaps'"); ''; }) diff --git a/nixos/tests/networking.nix b/nixos/tests/networking.nix index 8b573869c157..6a7e628d8ef1 100644 --- a/nixos/tests/networking.nix +++ b/nixos/tests/networking.nix @@ -1,4 +1,6 @@ -{ system ? builtins.currentSystem, networkd }: +{ system ? builtins.currentSystem +# bool: whether to use networkd in the tests +, networkd }: with import ../lib/testing.nix { inherit system; }; with pkgs.lib; @@ -166,24 +168,24 @@ let # Test vlan 1 $client->waitUntilSucceeds("ping -c 1 192.168.1.1"); $client->waitUntilSucceeds("ping -c 1 192.168.1.2"); - $client->waitUntilSucceeds("ping6 -c 1 fd00:1234:5678:1::1"); - $client->waitUntilSucceeds("ping6 -c 1 fd00:1234:5678:1::2"); + $client->waitUntilSucceeds("ping -c 1 fd00:1234:5678:1::1"); + $client->waitUntilSucceeds("ping -c 1 fd00:1234:5678:1::2"); $router->waitUntilSucceeds("ping -c 1 192.168.1.1"); $router->waitUntilSucceeds("ping -c 1 192.168.1.2"); - $router->waitUntilSucceeds("ping6 -c 1 fd00:1234:5678:1::1"); - $router->waitUntilSucceeds("ping6 -c 1 fd00:1234:5678:1::2"); + $router->waitUntilSucceeds("ping -c 1 fd00:1234:5678:1::1"); + $router->waitUntilSucceeds("ping -c 1 fd00:1234:5678:1::2"); # Test vlan 2 $client->waitUntilSucceeds("ping -c 1 192.168.2.1"); $client->waitUntilSucceeds("ping -c 1 192.168.2.2"); - $client->waitUntilSucceeds("ping6 -c 1 fd00:1234:5678:2::1"); - $client->waitUntilSucceeds("ping6 -c 1 fd00:1234:5678:2::2"); + $client->waitUntilSucceeds("ping -c 1 fd00:1234:5678:2::1"); + $client->waitUntilSucceeds("ping -c 1 fd00:1234:5678:2::2"); $router->waitUntilSucceeds("ping -c 1 192.168.2.1"); $router->waitUntilSucceeds("ping -c 1 192.168.2.2"); - $router->waitUntilSucceeds("ping6 -c 1 fd00:1234:5678:2::1"); - $router->waitUntilSucceeds("ping6 -c 1 fd00:1234:5678:2::2"); + $router->waitUntilSucceeds("ping -c 1 fd00:1234:5678:2::1"); + $router->waitUntilSucceeds("ping -c 1 fd00:1234:5678:2::2"); ''; }; dhcpOneIf = { @@ -390,11 +392,11 @@ let $client2->succeed("ip addr >&2"); # Test ipv6 - $client1->waitUntilSucceeds("ping6 -c 1 fc00::1"); - $client1->waitUntilSucceeds("ping6 -c 1 fc00::2"); + $client1->waitUntilSucceeds("ping -c 1 fc00::1"); + $client1->waitUntilSucceeds("ping -c 1 fc00::2"); - $client2->waitUntilSucceeds("ping6 -c 1 fc00::1"); - $client2->waitUntilSucceeds("ping6 -c 1 fc00::2"); + $client2->waitUntilSucceeds("ping -c 1 fc00::1"); + $client2->waitUntilSucceeds("ping -c 1 fc00::2"); ''; }; vlan = let diff --git a/nixos/tests/pgjwt.nix b/nixos/tests/pgjwt.nix new file mode 100644 index 000000000000..2cf2963ae316 --- /dev/null +++ b/nixos/tests/pgjwt.nix @@ -0,0 +1,42 @@ +import ./make-test.nix ({ pkgs, ...} : +let + test = pkgs.writeText "test.sql" '' + CREATE EXTENSION pgcrypto; + CREATE EXTENSION pgjwt; + select sign('{"sub":"1234567890","name":"John Doe","admin":true}', 'secret'); + select * from verify('eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ', 'secret'); + ''; +in +{ + name = "pgjwt"; + meta = with pkgs.stdenv.lib.maintainers; { + maintainers = [ spinus ]; + }; + + nodes = { + master = + { pkgs, config, ... }: + + { + services.postgresql = let mypg = pkgs.postgresql95; in { + enable = true; + package = mypg; + extraPlugins =[pkgs.pgjwt]; + initialScript = pkgs.writeText "postgresql-init.sql" + '' + CREATE ROLE postgres WITH superuser login createdb; + ''; + }; + }; + }; + + testScript = '' + startAll; + $master->waitForUnit("postgresql"); + $master->succeed("timeout 10 bash -c 'while ! psql postgres -c \"SELECT 1;\";do sleep 1;done;'"); + $master->succeed("cat ${test} | psql postgres"); + # I can't make original test working :[ + # $master->succeed("${pkgs.perlPackages.TAPParserSourceHandlerpgTAP}/bin/pg_prove -d postgres ${pkgs.pgjwt.src}/test.sql"); + + ''; +}) diff --git a/nixos/tests/phabricator.nix b/nixos/tests/phabricator.nix index 85faafd56899..fdc39393faea 100644 --- a/nixos/tests/phabricator.nix +++ b/nixos/tests/phabricator.nix @@ -54,7 +54,7 @@ import ./make-test.nix ({ pkgs, ... }: { client = { config, pkgs, ... }: { imports = [ ./common/x11.nix ]; - services.xserver.desktopManager.kde5.enable = true; + services.xserver.desktopManager.plasma5.enable = true; }; }; diff --git a/nixos/tests/kde5.nix b/nixos/tests/plasma5.nix index 2b61d6f3f0a1..ca787e9c7b9b 100644 --- a/nixos/tests/kde5.nix +++ b/nixos/tests/plasma5.nix @@ -1,7 +1,7 @@ import ./make-test.nix ({ pkgs, ...} : { - name = "kde5"; + name = "plasma5"; meta = with pkgs.stdenv.lib.maintainers; { maintainers = [ ttuegel ]; }; @@ -17,7 +17,8 @@ import ./make-test.nix ({ pkgs, ...} : user = "alice"; }; }; - services.xserver.desktopManager.kde5.enable = true; + services.xserver.desktopManager.plasma5.enable = true; + services.xserver.desktopManager.default = "plasma5"; virtualisation.writableStore = false; # FIXME }; diff --git a/nixos/tests/pump.io.nix b/nixos/tests/pump.io.nix index 18da52b5134b..0991ed3fce1f 100644 --- a/nixos/tests/pump.io.nix +++ b/nixos/tests/pump.io.nix @@ -51,16 +51,6 @@ import ./make-test.nix ({ pkgs, ...} : let Vd5WD2HJhLb9u0UxVp9vfWIUDgydopV5ZmWCQ5YvNepb1w== -----END CERTIFICATE----- ''; - - makePump = { opts ? { } }: - { - enable = true; - sslCert = pkgs.writeText "snakeoil.cert" snakeOilCert; - sslKey = pkgs.writeText "snakeoil.pem" snakeOilKey; - secret = "test"; - site = "test"; - } // opts; - in { name = "pumpio"; meta = with pkgs.stdenv.lib.maintainers; { @@ -72,9 +62,14 @@ in { { config, pkgs, ... }: { services = { - pumpio = makePump { opts = { + pumpio = { port = 443; - }; }; + enable = true; + sslCert = pkgs.writeText "snakeoil.cert" snakeOilCert; + sslKey = pkgs.writeText "snakeoil.pem" snakeOilKey; + secretFile = pkgs.writeText "secretFile" "test123"; + site = "test"; + }; mongodb.enable = true; mongodb.extraConfig = '' storage.journal.enabled: false diff --git a/nixos/tests/samba.nix b/nixos/tests/samba.nix index d6658ef0400b..e446284fc0ef 100644 --- a/nixos/tests/samba.nix +++ b/nixos/tests/samba.nix @@ -37,12 +37,11 @@ import ./make-test.nix ({ pkgs, ... }: testScript = '' $server->start; - $server->waitForUnit("samba-smbd"); - $server->waitForUnit("samba-nmbd"); + $server->waitForUnit("samba.target"); $server->succeed("mkdir -p /public; echo bar > /public/foo"); $client->start; - $client->waitForUnit("network.target"); + $client->waitForUnit("remote-fs.target"); $client->succeed("[[ \$(cat /public/foo) = bar ]]"); ''; }) diff --git a/nixos/tests/taskserver.nix b/nixos/tests/taskserver.nix index d770b20a7757..cdccb11d8887 100644 --- a/nixos/tests/taskserver.nix +++ b/nixos/tests/taskserver.nix @@ -1,4 +1,62 @@ -import ./make-test.nix { +import ./make-test.nix ({ pkgs, ... }: let + snakeOil = pkgs.runCommand "snakeoil-certs" { + outputs = [ "out" "cacert" "cert" "key" "crl" ]; + buildInputs = [ pkgs.gnutls.bin ]; + caTemplate = pkgs.writeText "snakeoil-ca.template" '' + cn = server + expiration_days = -1 + cert_signing_key + ca + ''; + certTemplate = pkgs.writeText "snakeoil-cert.template" '' + cn = server + expiration_days = -1 + tls_www_server + encryption_key + signing_key + ''; + crlTemplate = pkgs.writeText "snakeoil-crl.template" '' + expiration_days = -1 + ''; + userCertTemplace = pkgs.writeText "snakoil-user-cert.template" '' + organization = snakeoil + cn = server + expiration_days = -1 + tls_www_client + encryption_key + signing_key + ''; + } '' + certtool -p --bits 4096 --outfile ca.key + certtool -s --template "$caTemplate" --load-privkey ca.key \ + --outfile "$cacert" + certtool -p --bits 4096 --outfile "$key" + certtool -c --template "$certTemplate" \ + --load-ca-privkey ca.key \ + --load-ca-certificate "$cacert" \ + --load-privkey "$key" \ + --outfile "$cert" + certtool --generate-crl --template "$crlTemplate" \ + --load-ca-privkey ca.key \ + --load-ca-certificate "$cacert" \ + --outfile "$crl" + + mkdir "$out" + + # Stripping key information before the actual PEM-encoded values is solely + # to make test output a bit less verbose when copying the client key to the + # actual client. + certtool -p --bits 4096 | sed -n \ + -e '/^----* *BEGIN/,/^----* *END/p' > "$out/alice.key" + + certtool -c --template "$userCertTemplace" \ + --load-privkey "$out/alice.key" \ + --load-ca-privkey ca.key \ + --load-ca-certificate "$cacert" \ + --outfile "$out/alice.cert" + ''; + +in { name = "taskserver"; nodes = rec { @@ -12,6 +70,23 @@ import ./make-test.nix { }; }; + # New generation of the server with manual config + newServer = { lib, nodes, ... }: { + imports = [ server ]; + services.taskserver.pki.manual = { + ca.cert = snakeOil.cacert; + server.cert = snakeOil.cert; + server.key = snakeOil.key; + server.crl = snakeOil.crl; + }; + # This is to avoid assigning a different network address to the new + # generation. + networking = lib.mapAttrs (lib.const lib.mkForce) { + inherit (nodes.server.config.networking) + hostName interfaces primaryIPAddress extraHosts; + }; + }; + client1 = { pkgs, ... }: { environment.systemPackages = [ pkgs.taskwarrior pkgs.gnutls ]; users.users.alice.isNormalUser = true; @@ -26,6 +101,8 @@ import ./make-test.nix { testScript = { nodes, ... }: let cfg = nodes.server.config.services.taskserver; portStr = toString cfg.listenPort; + newServerSystem = nodes.newServer.config.system.build.toplevel; + switchToNewServer = "${newServerSystem}/bin/switch-to-configuration test"; in '' sub su ($$) { my ($user, $cmd) = @_; @@ -33,8 +110,8 @@ import ./make-test.nix { return "su - $user -c '$esc'"; } - sub setupClientsFor ($$) { - my ($org, $user) = @_; + sub setupClientsFor ($$;$) { + my ($org, $user, $extraInit) = @_; for my $client ($client1, $client2) { $client->nest("initialize client for user $user", sub { @@ -58,6 +135,8 @@ import ./make-test.nix { } }); + eval { &$extraInit($client, $org, $user) }; + $client->succeed(su $user, "task config taskd.server server:${portStr} >&2" ); @@ -104,7 +183,10 @@ import ./make-test.nix { return su $user, $cmd; } - startAll; + # Explicitly start the VMs so that we don't accidentally start newServer + $server->start; + $client1->start; + $client2->start; $server->waitForUnit("taskserver.service"); @@ -162,5 +244,42 @@ import ./make-test.nix { restartServer; testSync "bar"; }; + + subtest "check manual configuration", sub { + $server->succeed('${switchToNewServer} >&2'); + $server->waitForUnit("taskserver.service"); + $server->waitForOpenPort(${portStr}); + + $server->succeed( + "nixos-taskserver org add manualOrg", + "nixos-taskserver user add manualOrg alice" + ); + + setupClientsFor "manualOrg", "alice", sub { + my ($client, $org, $user) = @_; + my $cfgpath = "/home/$user/.task"; + + $client->copyFileFromHost("${snakeOil.cacert}", "$cfgpath/ca.cert"); + for my $file ('alice.key', 'alice.cert') { + $client->copyFileFromHost("${snakeOil}/$file", "$cfgpath/$file"); + } + + for my $file ("$user.key", "$user.cert") { + $client->copyFileFromHost( + "${snakeOil}/$file", "$cfgpath/$file" + ); + } + $client->copyFileFromHost( + "${snakeOil.cacert}", "$cfgpath/ca.cert" + ); + $client->succeed( + (su "alice", "task config taskd.ca $cfgpath/ca.cert"), + (su "alice", "task config taskd.key $cfgpath/$user.key"), + (su $user, "task config taskd.certificate $cfgpath/$user.cert") + ); + }; + + testSync "alice"; + }; ''; -} +}) diff --git a/nixos/tests/trac.nix b/nixos/tests/trac.nix index 0d56c564e182..d426bbde68d2 100644 --- a/nixos/tests/trac.nix +++ b/nixos/tests/trac.nix @@ -45,7 +45,7 @@ import ./make-test.nix ({ pkgs, ... }: { client = { config, pkgs, ... }: { imports = [ ./common/x11.nix ]; - services.xserver.desktopManager.kde5.enable = true; + services.xserver.desktopManager.plasma5.enable = true; }; }; diff --git a/nixos/tests/wordpress.nix b/nixos/tests/wordpress.nix index afee1f7f6dd4..c51306a8c7a0 100644 --- a/nixos/tests/wordpress.nix +++ b/nixos/tests/wordpress.nix @@ -10,14 +10,10 @@ import ./make-test.nix ({ pkgs, ... }: { web = { config, pkgs, ... }: { - services.mysql.enable = true; - services.mysql.package = pkgs.mysql; - services.mysql.initialScript = pkgs.writeText "start.sql" '' - CREATE DATABASE wordpress; - CREATE USER 'wordpress'@'localhost' IDENTIFIED BY 'wordpress'; - GRANT ALL on wordpress.* TO 'wordpress'@'localhost'; - ''; - + services.mysql = { + enable = true; + package = pkgs.mysql; + }; services.httpd = { enable = true; logPerVirtualHost = true; |