diff options
Diffstat (limited to 'nixos')
79 files changed, 1754 insertions, 561 deletions
diff --git a/nixos/doc/manual/administration/container-networking.xml b/nixos/doc/manual/administration/container-networking.xml index 1b1576d3babe..d89d262eff4e 100644 --- a/nixos/doc/manual/administration/container-networking.xml +++ b/nixos/doc/manual/administration/container-networking.xml @@ -47,4 +47,12 @@ where <literal>eth0</literal> should be replaced with the desired external interface. Note that <literal>ve-+</literal> is a wildcard that matches all container interfaces.</para> +<para>If you are using Network Manager, you need to explicitly prevent +it from managing container interfaces: + +<programlisting> +networking.networkmanager.unmanaged = [ "interface-name:ve-*" ]; +</programlisting> +</para> + </section> diff --git a/nixos/doc/manual/configuration/customizing-packages.xml b/nixos/doc/manual/configuration/customizing-packages.xml index 6ee7a95dc6fa..8aa01fb57a09 100644 --- a/nixos/doc/manual/configuration/customizing-packages.xml +++ b/nixos/doc/manual/configuration/customizing-packages.xml @@ -42,29 +42,30 @@ construction, so without them, elements.)</para> <para>Even greater customisation is possible using the function -<varname>overrideDerivation</varname>. While the +<varname>overrideAttrs</varname>. While the <varname>override</varname> mechanism above overrides the arguments of -a package function, <varname>overrideDerivation</varname> allows -changing the <emphasis>result</emphasis> of the function. This -permits changing any aspect of the package, such as the source code. +a package function, <varname>overrideAttrs</varname> allows +changing the <emphasis>attributes</emphasis> passed to <literal>mkDerivation</literal>. +This permits changing any aspect of the package, such as the source code. For instance, if you want to override the source code of Emacs, you can say: <programlisting> -environment.systemPackages = - [ (pkgs.lib.overrideDerivation pkgs.emacs (attrs: { - name = "emacs-25.0-pre"; - src = /path/to/my/emacs/tree; - })) - ]; +environment.systemPackages = [ + (pkgs.emacs.overrideAttrs (oldAttrs: { + name = "emacs-25.0-pre"; + src = /path/to/my/emacs/tree; + })) +]; </programlisting> -Here, <varname>overrideDerivation</varname> takes the Nix derivation +Here, <varname>overrideAttrs</varname> takes the Nix derivation specified by <varname>pkgs.emacs</varname> and produces a new derivation in which the original’s <literal>name</literal> and <literal>src</literal> attribute have been replaced by the given -values. The original attributes are accessible via -<varname>attrs</varname>.</para> +values by re-calling <literal>stdenv.mkDerivation</literal>. +The original attributes are accessible via the function argument, +which is conventionally named <varname>oldAttrs</varname>.</para> <para>The overrides shown above are not global. They do not affect the original package; other packages in Nixpkgs continue to depend on diff --git a/nixos/doc/manual/development/option-declarations.xml b/nixos/doc/manual/development/option-declarations.xml index 7be5e9d51d46..ce432a7fa6ca 100644 --- a/nixos/doc/manual/development/option-declarations.xml +++ b/nixos/doc/manual/development/option-declarations.xml @@ -65,4 +65,92 @@ options = { </para> +<section xml:id="sec-option-declarations-eot"><title>Extensible Option + Types</title> + + <para>Extensible option types is a feature that allow to extend certain types + declaration through multiple module files. + This feature only work with a restricted set of types, namely + <literal>enum</literal> and <literal>submodules</literal> and any composed + forms of them.</para> + + <para>Extensible option types can be used for <literal>enum</literal> options + that affects multiple modules, or as an alternative to related + <literal>enable</literal> options.</para> + + <para>As an example, we will take the case of display managers. There is a + central display manager module for generic display manager options and a + module file per display manager backend (slim, kdm, gdm ...). + </para> + + <para>There are two approach to this module structure: + + <itemizedlist> + <listitem><para>Managing the display managers independently by adding an + enable option to every display manager module backend. (NixOS)</para> + </listitem> + <listitem><para>Managing the display managers in the central module by + adding an option to select which display manager backend to use.</para> + </listitem> + </itemizedlist> + </para> + + <para>Both approachs have problems.</para> + + <para>Making backends independent can quickly become hard to manage. For + display managers, there can be only one enabled at a time, but the type + system can not enforce this restriction as there is no relation between + each backend <literal>enable</literal> option. As a result, this restriction + has to be done explicitely by adding assertions in each display manager + backend module.</para> + + <para>On the other hand, managing the display managers backends in the + central module will require to change the central module option every time + a new backend is added or removed.</para> + + <para>By using extensible option types, it is possible to create a placeholder + option in the central module (<xref linkend='ex-option-declaration-eot-service' + />), and to extend it in each backend module (<xref + linkend='ex-option-declaration-eot-backend-slim' />, <xref + linkend='ex-option-declaration-eot-backend-kdm' />).</para> + + <para>As a result, <literal>displayManager.enable</literal> option values can + be added without changing the main service module file and the type system + automatically enforce that there can only be a single display manager + enabled.</para> + +<example xml:id='ex-option-declaration-eot-service'><title>Extensible type + placeholder in the service module</title> +<screen> +services.xserver.displayManager.enable = mkOption { + description = "Display manager to use"; + type = with types; nullOr (enum [ ]); +};</screen></example> + +<example xml:id='ex-option-declaration-eot-backend-slim'><title>Extending + <literal>services.xserver.displayManager.enable</literal> in the + <literal>slim</literal> module</title> +<screen> +services.xserver.displayManager.enable = mkOption { + type = with types; nullOr (enum [ "slim" ]); +};</screen></example> + +<example xml:id='ex-option-declaration-eot-backend-kdm'><title>Extending + <literal>services.foo.backend</literal> in the <literal>kdm</literal> + module</title> +<screen> +services.xserver.displayManager.enable = mkOption { + type = with types; nullOr (enum [ "kdm" ]); +};</screen></example> + +<para>The placeholder declaration is a standard <literal>mkOption</literal> + declaration, but it is important that extensible option declarations only use + the <literal>type</literal> argument.</para> + +<para>Extensible option types work with any of the composed variants of + <literal>enum</literal> such as + <literal>with types; nullOr (enum [ "foo" "bar" ])</literal> + or <literal>with types; listOf (enum [ "foo" "bar" ])</literal>.</para> + +</section> </section> diff --git a/nixos/doc/manual/development/option-types.xml b/nixos/doc/manual/development/option-types.xml index 8871b02cebf1..8e6ac53ad480 100644 --- a/nixos/doc/manual/development/option-types.xml +++ b/nixos/doc/manual/development/option-types.xml @@ -62,23 +62,45 @@ <listitem><para>A string. Multiple definitions are concatenated with a collon <literal>":"</literal>.</para></listitem> </varlistentry> +</variablelist> + + </section> + + <section><title>Value Types</title> + + <para>Value types are type that take a value parameter. The only value type + in the library is <literal>enum</literal>.</para> + +<variablelist> <varlistentry> - <term><varname>types.separatedString</varname> + <term><varname>types.enum</varname> <replaceable>l</replaceable></term> + <listitem><para>One element of the list <replaceable>l</replaceable>, e.g. + <literal>types.enum [ "left" "right" ]</literal>. Multiple definitions + cannot be merged.</para></listitem> + </varlistentry> + <varlistentry> + <term><varname>types.separatedString</varname> <replaceable>sep</replaceable></term> - <listitem><para>A string with a custom separator - <replaceable>sep</replaceable>, e.g. <literal>types.separatedString + <listitem><para>A string with a custom separator + <replaceable>sep</replaceable>, e.g. <literal>types.separatedString "|"</literal>.</para></listitem> </varlistentry> + <varlistentry> + <term><varname>types.submodule</varname> <replaceable>o</replaceable></term> + <listitem><para>A set of sub options <replaceable>o</replaceable>. + <replaceable>o</replaceable> can be an attribute set or a function + returning an attribute set. Submodules are used in composed types to + create modular options. Submodule are detailed in <xref + linkend='section-option-types-submodule' />.</para></listitem> + </varlistentry> </variablelist> - </section> <section><title>Composed Types</title> - <para>Composed types allow to create complex types by taking another type(s) - or value(s) as parameter(s). - It is possible to compose types multiple times, e.g. <literal>with types; - nullOr (enum [ "left" "right" ])</literal>.</para> + <para>Composed types are types that take a type as parameter. <literal>listOf + int</literal> and <literal>either int str</literal> are examples of + composed types.</para> <variablelist> <varlistentry> @@ -100,12 +122,6 @@ value.</para></listitem> </varlistentry> <varlistentry> - <term><varname>types.loeOf</varname> <replaceable>t</replaceable></term> - <listitem><para>A list or an element of <replaceable>t</replaceable> type. - Multiple definitions are merged according to the - values.</para></listitem> - </varlistentry> - <varlistentry> <term><varname>types.nullOr</varname> <replaceable>t</replaceable></term> <listitem><para><literal>null</literal> or type <replaceable>t</replaceable>. Multiple definitions are merged according @@ -118,12 +134,6 @@ once.</para></listitem> </varlistentry> <varlistentry> - <term><varname>types.enum</varname> <replaceable>l</replaceable></term> - <listitem><para>One element of the list <replaceable>l</replaceable>, e.g. - <literal>types.enum [ "left" "right" ]</literal>. Multiple definitions - cannot be merged</para></listitem> - </varlistentry> - <varlistentry> <term><varname>types.either</varname> <replaceable>t1</replaceable> <replaceable>t2</replaceable></term> <listitem><para>Type <replaceable>t1</replaceable> or type @@ -131,14 +141,6 @@ str</literal>. Multiple definitions cannot be merged.</para></listitem> </varlistentry> - <varlistentry> - <term><varname>types.submodule</varname> <replaceable>o</replaceable></term> - <listitem><para>A set of sub options <replaceable>o</replaceable>. - <replaceable>o</replaceable> can be an attribute set or a function - returning an attribute set. Submodules are used in composed types to - create modular options. Submodule are detailed in <xref - linkend='section-option-types-submodule' />.</para></listitem> - </varlistentry> </variablelist> </section> @@ -197,7 +199,6 @@ options.mod = mkOption { type = with types; listOf (submodule modOptions); };</screen></example> - <section><title>Composed with <literal>listOf</literal></title> <para>When composed with <literal>listOf</literal>, submodule allows multiple @@ -323,9 +324,13 @@ code before creating a new type.</para> <variablelist> <varlistentry> <term><varname>name</varname></term> - <listitem><para>A string representation of the type function name, name - usually changes accordingly parameters passed to - types.</para></listitem> + <listitem><para>A string representation of the type function + name.</para></listitem> + </varlistentry> + <varlistentry> + <term><varname>definition</varname></term> + <listitem><para>Description of the type used in documentation. Give + information of the type and any of its arguments.</para></listitem> </varlistentry> <varlistentry> <term><varname>check</varname></term> @@ -388,6 +393,53 @@ code before creating a new type.</para> type parameter, this function should be defined as <literal>m: composedType (elemType.substSubModules m)</literal>.</para></listitem> </varlistentry> + <varlistentry> + <term><varname>typeMerge</varname></term> + <listitem><para>A function to merge multiple type declarations. Takes the + type to merge <literal>functor</literal> as parameter. A + <literal>null</literal> return value means that type cannot be + merged.</para> + <variablelist> + <varlistentry> + <term><replaceable>f</replaceable></term> + <listitem><para>The type to merge + <literal>functor</literal>.</para></listitem> + </varlistentry> + </variablelist> + <para>Note: There is a generic <literal>defaultTypeMerge</literal> that + work with most of value and composed types.</para> + </listitem> + </varlistentry> + <varlistentry> + <term><varname>functor</varname></term> + <listitem><para>An attribute set representing the type. It is used for type + operations and has the following keys:</para> + <variablelist> + <varlistentry> + <term><varname>type</varname></term> + <listitem><para>The type function.</para></listitem> + </varlistentry> + <varlistentry> + <term><varname>wrapped</varname></term> + <listitem><para>Holds the type parameter for composed types.</para> + </listitem> + </varlistentry> + <varlistentry> + <term><varname>payload</varname></term> + <listitem><para>Holds the value parameter for value types. + The types that have a <literal>payload</literal> are the + <literal>enum</literal>, <literal>separatedString</literal> and + <literal>submodule</literal> types.</para></listitem> + </varlistentry> + <varlistentry> + <term><varname>binOp</varname></term> + <listitem><para>A binary operation that can merge the payloads of two + same types. Defined as a function that take two payloads as + parameters and return the payloads merged.</para></listitem> + </varlistentry> + </variablelist> + </listitem> + </varlistentry> </variablelist> </section> diff --git a/nixos/doc/manual/installation/obtaining.xml b/nixos/doc/manual/installation/obtaining.xml index f6e8b218e2b3..20a4838be880 100644 --- a/nixos/doc/manual/installation/obtaining.xml +++ b/nixos/doc/manual/installation/obtaining.xml @@ -32,7 +32,7 @@ running NixOS system through several other means: <listitem> <para>Using AMIs for Amazon’s EC2. To find one for your region and instance type, please refer to the <link - xlink:href="https://github.com/NixOS/nixops/blob/master/nix/ec2-amis.nix">list + xlink:href="https://github.com/NixOS/nixpkgs/blob/master/nixos/modules/virtualisation/ec2-amis.nix">list of most recent AMIs</link>.</para> </listitem> <listitem> diff --git a/nixos/doc/manual/release-notes/rl-1703.xml b/nixos/doc/manual/release-notes/rl-1703.xml index efff8b895a1a..a133630e1464 100644 --- a/nixos/doc/manual/release-notes/rl-1703.xml +++ b/nixos/doc/manual/release-notes/rl-1703.xml @@ -68,6 +68,15 @@ following incompatible changes:</para> that may be in /etc. </para> </listitem> + + <listitem> + <para> + Parsoid service now uses YAML configuration format. + <literal>service.parsoid.interwikis</literal> is now called + <literal>service.parsoid.wikis</literal> and is a list of either API URLs + or attribute sets as specified in parsoid's documentation. + </para> + </listitem> </itemizedlist> @@ -75,7 +84,10 @@ following incompatible changes:</para> <itemizedlist> <listitem> - <para></para> + <para>Module type system have a new extensible option types feature that + allow to extend certain types, such as enum, through multiple option + declarations of the same option across multiple modules. + </para> </listitem> </itemizedlist> diff --git a/nixos/maintainers/scripts/ec2/create-amis.sh b/nixos/maintainers/scripts/ec2/create-amis.sh index e26caa191643..8b7db7b30a64 100755 --- a/nixos/maintainers/scripts/ec2/create-amis.sh +++ b/nixos/maintainers/scripts/ec2/create-amis.sh @@ -1,4 +1,8 @@ -#! /bin/sh -e +#!/usr/bin/env nix-shell +#! nix-shell -i bash -p qemu awscli ec2_ami_tools jq + +# To start with do: nix-shell -p awscli --run "aws configure" + set -o pipefail #set -x diff --git a/nixos/modules/config/debug-info.nix b/nixos/modules/config/debug-info.nix index 671a59f52f6d..49991d22a933 100644 --- a/nixos/modules/config/debug-info.nix +++ b/nixos/modules/config/debug-info.nix @@ -17,12 +17,10 @@ with lib; where tools such as <command>gdb</command> can find them. If you need debug symbols for a package that doesn't provide them by default, you can enable them as follows: - <!-- FIXME: ugly, see #10721 --> <programlisting> nixpkgs.config.packageOverrides = pkgs: { - hello = pkgs.lib.overrideDerivation pkgs.hello (attrs: { - outputs = attrs.outputs or ["out"] ++ ["debug"]; - buildInputs = attrs.buildInputs ++ [<nixpkgs/pkgs/build-support/setup-hooks/separate-debug-info.sh>]; + hello = pkgs.hello.overrideAttrs (oldAttrs: { + separateDebugInfo = true; }); }; </programlisting> diff --git a/nixos/modules/config/fonts/fontconfig.nix b/nixos/modules/config/fonts/fontconfig.nix index 770c3a03f9d8..52ad1e714fb9 100644 --- a/nixos/modules/config/fonts/fontconfig.nix +++ b/nixos/modules/config/fonts/fontconfig.nix @@ -301,9 +301,7 @@ in }; style = mkOption { - type = types.str // { - check = flip elem ["none" "slight" "medium" "full"]; - }; + type = types.enum ["none" "slight" "medium" "full"]; default = "full"; description = '' TrueType hinting style, one of <literal>none</literal>, @@ -329,9 +327,7 @@ in default = "rgb"; type = types.enum ["rgb" "bgr" "vrgb" "vbgr" "none"]; description = '' - Subpixel order, one of <literal>none</literal>, - <literal>rgb</literal>, <literal>bgr</literal>, - <literal>vrgb</literal>, or <literal>vbgr</literal>. + Subpixel order. ''; }; @@ -339,9 +335,7 @@ in default = "default"; type = types.enum ["none" "default" "light" "legacy"]; description = '' - FreeType LCD filter, one of <literal>none</literal>, - <literal>default</literal>, <literal>light</literal>, or - <literal>legacy</literal>. + FreeType LCD filter. ''; }; diff --git a/nixos/modules/config/shells-environment.nix b/nixos/modules/config/shells-environment.nix index f458bc39adaa..8147fed39d09 100644 --- a/nixos/modules/config/shells-environment.nix +++ b/nixos/modules/config/shells-environment.nix @@ -41,7 +41,7 @@ in strings. The latter is concatenated, interspersed with colon characters. ''; - type = types.attrsOf (types.loeOf types.str); + type = with types; attrsOf (either str (listOf str)); apply = mapAttrs (n: v: if isList v then concatStringsSep ":" v else v); }; diff --git a/nixos/modules/config/system-environment.nix b/nixos/modules/config/system-environment.nix index 3362400326d2..6011e354ece4 100644 --- a/nixos/modules/config/system-environment.nix +++ b/nixos/modules/config/system-environment.nix @@ -23,7 +23,7 @@ in strings. The latter is concatenated, interspersed with colon characters. ''; - type = types.attrsOf (types.loeOf types.str); + type = with types; attrsOf (either str (listOf str)); apply = mapAttrs (n: v: if isList v then concatStringsSep ":" v else v); }; diff --git a/nixos/modules/config/system-path.nix b/nixos/modules/config/system-path.nix index 775d0c39c4fa..3ac5f634c7a6 100644 --- a/nixos/modules/config/system-path.nix +++ b/nixos/modules/config/system-path.nix @@ -118,6 +118,7 @@ in "/share/terminfo" "/share/themes" "/share/vim-plugins" + "/share/vulkan" ]; system.path = pkgs.buildEnv { diff --git a/nixos/modules/hardware/opengl.nix b/nixos/modules/hardware/opengl.nix index bef500e30c0b..c4fad9a66725 100644 --- a/nixos/modules/hardware/opengl.nix +++ b/nixos/modules/hardware/opengl.nix @@ -135,6 +135,12 @@ in environment.sessionVariables.LD_LIBRARY_PATH = [ "/run/opengl-driver/lib" "/run/opengl-driver-32/lib" ]; + environment.extraInit = '' + export XDG_DATA_DIRS=$XDG_DATA_DIRS:/run/opengl-driver/share + '' + optionalString cfg.driSupport32Bit '' + export XDG_DATA_DIRS=$XDG_DATA_DIRS:/run/opengl-driver-32/share + ''; + hardware.opengl.package = mkDefault (makePackage pkgs); hardware.opengl.package32 = mkDefault (makePackage pkgs_i686); diff --git a/nixos/modules/hardware/video/amdgpu-pro.nix b/nixos/modules/hardware/video/amdgpu-pro.nix index 3723d7690dc6..979810abf90a 100644 --- a/nixos/modules/hardware/video/amdgpu-pro.nix +++ b/nixos/modules/hardware/video/amdgpu-pro.nix @@ -45,10 +45,8 @@ in "amd/amdapfxx.blb".source = package + "/etc/amd/amdapfxx.blb"; "gbm/gbm.conf".source = package + "/etc/gbm/gbm.conf"; "OpenCL/vendors/amdocl64.icd".source = package + "/etc/OpenCL/vendors/amdocl64.icd"; - "vulkan/icd.d/amd_icd64.json".source = package + "/etc/vulkan/icd.d/amd_icd64.json"; } // optionalAttrs opengl.driSupport32Bit { "OpenCL/vendors/amdocl32.icd".source = package32 + "/etc/OpenCL/vendors/amdocl32.icd"; - "vulkan/icd.d/amd_icd32.json".source = package32 + "/etc/vulkan/icd.d/amd_icd32.json"; }; }; diff --git a/nixos/modules/hardware/video/bumblebee.nix b/nixos/modules/hardware/video/bumblebee.nix index 69db518ab21c..76d122ab2124 100644 --- a/nixos/modules/hardware/video/bumblebee.nix +++ b/nixos/modules/hardware/video/bumblebee.nix @@ -62,7 +62,7 @@ in }; config = mkIf config.hardware.bumblebee.enable { - boot.blacklistedKernelModules = [ "nouveau" "nvidia" ]; + boot.blacklistedKernelModules = [ "nvidia-drm" "nvidia" "nouveau" ]; boot.kernelModules = [ "bbswitch" ]; boot.extraModulePackages = [ kernel.bbswitch ] ++ optional useNvidia kernel.nvidia_x11; 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 b5ee57d9e22e..c44dff3bb60d 100644 --- a/nixos/modules/installer/cd-dvd/installation-cd-graphical-kde.nix +++ b/nixos/modules/installer/cd-dvd/installation-cd-graphical-kde.nix @@ -1,20 +1,41 @@ # This module defines a NixOS installation CD that contains X11 and -# KDE 4. +# KDE 5. { config, lib, pkgs, ... }: with lib; { - imports = [ ./installation-cd-base.nix ../../profiles/graphical.nix ]; + imports = [ ./installation-cd-base.nix ]; - # Provide wicd for easy wireless configuration. - #networking.wicd.enable = true; + services.xserver = { + enable = true; + + # Automatically login as root. + displayManager.slim = { + enable = true; + defaultUser = "root"; + autoLogin = true; + }; + + desktopManager.kde5 = { + enable = true; + enableQt4Support = false; + }; + + # Enable touchpad support for many laptops. + synaptics.enable = true; + }; environment.systemPackages = - [ # Include gparted for partitioning disks. + [ pkgs.glxinfo + + # Include gparted for partitioning disks. pkgs.gparted + # Firefox for reading the manual. + pkgs.firefox + # Include some editors. pkgs.vim pkgs.bvi # binary editor @@ -32,80 +53,21 @@ with lib; # Don't start the X server by default. services.xserver.autorun = mkForce false; - # Auto-login as root. - services.xserver.displayManager.kdm.extraConfig = - '' - [X-*-Core] - AllowRootLogin=true - AutoLoginEnable=true - AutoLoginUser=root - AutoLoginPass="" - ''; - - # Custom kde-workspace adding some icons on the desktop - system.activationScripts.installerDesktop = let - openManual = pkgs.writeScript "nixos-manual.sh" '' - #!${pkgs.stdenv.shell} - cd ${config.system.build.manual.manual}/share/doc/nixos/ - konqueror ./index.html - ''; - desktopFile = pkgs.writeText "nixos-manual.desktop" '' [Desktop Entry] Version=1.0 Type=Application Name=NixOS Manual - Exec=${openManual} - Icon=konqueror + Exec=firefox ${config.system.build.manual.manual}/share/doc/nixos/index.html + Icon=text-html ''; in '' mkdir -p /root/Desktop ln -sfT ${desktopFile} /root/Desktop/nixos-manual.desktop - ln -sfT ${pkgs.kde4.konsole}/share/applications/kde4/konsole.desktop /root/Desktop/konsole.desktop + ln -sfT ${pkgs.kde5.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 ''; - services.xserver.desktopManager.kde4.kdeWorkspacePackage = let - pkg = pkgs.kde4.kde_workspace; - - plasmaInit = pkgs.writeText "00-defaultLayout.js" '' - loadTemplate("org.kde.plasma-desktop.defaultPanel") - - for (var i = 0; i < screenCount; ++i) { - var desktop = new Activity - desktop.name = i18n("Desktop") - desktop.screen = i - desktop.wallpaperPlugin = 'image' - desktop.wallpaperMode = 'SingleImage' - - var folderview = desktop.addWidget("folderview"); - folderview.writeConfig("url", "desktop:/"); - - //Create more panels for other screens - if (i > 0){ - var panel = new Panel - panel.screen = i - panel.location = 'bottom' - panel.height = screenGeometry(i).height > 1024 ? 35 : 27 - var tasks = panel.addWidget("tasks") - tasks.writeConfig("showOnlyCurrentScreen", true); - } - } - ''; - - in - pkgs.runCommand pkg.name - { inherit (pkg) meta; } - '' - mkdir -p $out - cp -prf ${pkg}/* $out/ - chmod a+w $out/share/apps/plasma-desktop/init - cp -f ${plasmaInit} $out/share/apps/plasma-desktop/init/00-defaultLayout.js - ''; - - # Disable large stuff that's not very useful on the installation CD. - services.xserver.desktopManager.kde4.enablePIM = false; - } diff --git a/nixos/modules/installer/tools/nixos-option.sh b/nixos/modules/installer/tools/nixos-option.sh index 17c17d05e288..27eacda48a87 100644 --- a/nixos/modules/installer/tools/nixos-option.sh +++ b/nixos/modules/installer/tools/nixos-option.sh @@ -256,7 +256,7 @@ if isOption opt then // optionalAttrs (opt ? default) { inherit (opt) default; } // optionalAttrs (opt ? example) { inherit (opt) example; } // optionalAttrs (opt ? description) { inherit (opt) description; } - // optionalAttrs (opt ? type) { typename = opt.type.name; } + // optionalAttrs (opt ? type) { typename = opt.type.description; } // optionalAttrs (opt ? options) { inherit (opt) options; } // { # to disambiguate the xml output. diff --git a/nixos/modules/installer/virtualbox-demo.nix b/nixos/modules/installer/virtualbox-demo.nix index 49ec08996104..5316cfce906b 100644 --- a/nixos/modules/installer/virtualbox-demo.nix +++ b/nixos/modules/installer/virtualbox-demo.nix @@ -18,5 +18,5 @@ with lib; # Add some more video drivers to give X11 a shot at working in # VMware and QEMU. - services.xserver.videoDrivers = mkOverride 40 [ "virtualbox" "vmware" "cirrus" "vesa" ]; + services.xserver.videoDrivers = mkOverride 40 [ "virtualbox" "vmware" "cirrus" "vesa" "modesetting" ]; } diff --git a/nixos/modules/misc/ids.nix b/nixos/modules/misc/ids.nix index 8c0f0c2624b1..b61c1f4799ec 100644 --- a/nixos/modules/misc/ids.nix +++ b/nixos/modules/misc/ids.nix @@ -84,7 +84,7 @@ spamd = 56; #networkmanager = 57; # unused nslcd = 58; - #scanner = 59; # unused + scanner = 59; nginx = 60; chrony = 61; #systemd-journal = 62; # unused @@ -277,6 +277,10 @@ gitlab-runner = 257; postgrey = 258; hound = 259; + leaps = 260; + ipfs = 261; + stanchion = 262; + riak-cs = 263; # When adding a uid, make sure it doesn't match an existing gid. And don't use uids above 399! @@ -524,6 +528,10 @@ gitlab-runner = 257; postgrey = 258; hound = 259; + leaps = 260; + ipfs = 261; + stanchion = 262; + riak-cs = 263; # 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/module-list.nix b/nixos/modules/module-list.nix index 08d739704080..d82f1fbc54fd 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -159,6 +159,8 @@ ./services/databases/postgresql.nix ./services/databases/redis.nix ./services/databases/riak.nix + ./services/databases/riak-cs.nix + ./services/databases/stanchion.nix ./services/databases/virtuoso.nix ./services/desktops/accountsservice.nix ./services/desktops/geoclue2.nix @@ -251,6 +253,7 @@ ./services/misc/gitolite.nix ./services/misc/gpsd.nix ./services/misc/ihaskell.nix + ./services/misc/leaps.nix ./services/misc/mantisbt.nix ./services/misc/mathics.nix ./services/misc/matrix-synapse.nix @@ -317,6 +320,7 @@ ./services/monitoring/zabbix-server.nix ./services/network-filesystems/cachefilesd.nix ./services/network-filesystems/drbd.nix + ./services/network-filesystems/ipfs.nix ./services/network-filesystems/netatalk.nix ./services/network-filesystems/nfsd.nix ./services/network-filesystems/openafs-client/default.nix @@ -537,7 +541,6 @@ ./services/x11/window-managers/fluxbox.nix ./services/x11/window-managers/icewm.nix ./services/x11/window-managers/bspwm.nix - ./services/x11/window-managers/bspwm-unstable.nix ./services/x11/window-managers/metacity.nix ./services/x11/window-managers/none.nix ./services/x11/window-managers/twm.nix diff --git a/nixos/modules/rename.nix b/nixos/modules/rename.nix index 44e07f4618de..a89ce2c743d4 100644 --- a/nixos/modules/rename.nix +++ b/nixos/modules/rename.nix @@ -30,6 +30,8 @@ with lib; (mkRenamedOptionModule [ "services" "gitlab" "stateDir" ] [ "services" "gitlab" "statePath" ]) (mkRemovedOptionModule [ "services" "gitlab" "satelliteDir" ] "") + (mkRenamedOptionModule [ "services" "clamav" "updater" "config" ] [ "services" "clamav" "updater" "extraConfig" ]) + # Old Grub-related options. (mkRenamedOptionModule [ "boot" "initrd" "extraKernelModules" ] [ "boot" "initrd" "kernelModules" ]) (mkRenamedOptionModule [ "boot" "extraKernelParams" ] [ "boot" "kernelParams" ]) @@ -142,6 +144,12 @@ with lib; # murmur (mkRenamedOptionModule [ "services" "murmur" "welcome" ] [ "services" "murmur" "welcometext" ]) + # parsoid + (mkRemovedOptionModule [ "services" "parsoid" "interwikis" ] [ "services" "parsoid" "wikis" ]) + + # tarsnap + (mkRemovedOptionModule [ "services" "tarsnap" "cachedir" ] "Use services.tarsnap.archives.<name>.cachedir") + # Options that are obsolete and have no replacement. (mkRemovedOptionModule [ "boot" "initrd" "luks" "enable" ] "") (mkRemovedOptionModule [ "programs" "bash" "enable" ] "") diff --git a/nixos/modules/security/duosec.nix b/nixos/modules/security/duosec.nix index 0e3a54325cad..97e2d39dc076 100644 --- a/nixos/modules/security/duosec.nix +++ b/nixos/modules/security/duosec.nix @@ -73,7 +73,7 @@ in }; failmode = mkOption { - type = types.str; + type = types.enum [ "safe" "enum" ]; default = "safe"; description = '' On service or configuration errors that prevent Duo @@ -115,7 +115,7 @@ in }; prompts = mkOption { - type = types.int; + type = types.enum [ 1 2 3 ]; default = 3; description = '' If a user fails to authenticate with a second factor, Duo @@ -181,13 +181,7 @@ in config = mkIf (cfg.ssh.enable || cfg.pam.enable) { assertions = - [ { assertion = cfg.failmode == "safe" || cfg.failmode == "secure"; - message = "Invalid value for failmode (must be safe or secure)."; - } - { assertion = cfg.prompts == 1 || cfg.prompts == 2 || cfg.prompts == 3; - message = "Invalid value for prompts (must be 1, 2, or 3)."; - } - { assertion = !cfg.pam.enable; + [ { assertion = !cfg.pam.enable; message = "PAM support is currently not implemented."; } ]; diff --git a/nixos/modules/security/grsecurity.nix b/nixos/modules/security/grsecurity.nix index 53c2ace784ef..ea245ecc5b6a 100644 --- a/nixos/modules/security/grsecurity.nix +++ b/nixos/modules/security/grsecurity.nix @@ -6,14 +6,6 @@ let cfg = config.security.grsecurity; grsecLockPath = "/proc/sys/kernel/grsecurity/grsec_lock"; - # Ascertain whether ZFS is required for booting the system; grsecurity is - # currently incompatible with ZFS, rendering the system unbootable. - zfsNeededForBoot = filter - (fs: (fs.neededForBoot - || elem fs.mountPoint [ "/" "/nix" "/nix/store" "/var" "/var/log" "/var/lib" "/etc" ]) - && fs.fsType == "zfs") - config.system.build.fileSystems != []; - # Ascertain whether NixOS container support is required containerSupportRequired = config.boot.enableContainers && config.containers != {}; @@ -27,7 +19,14 @@ in options.security.grsecurity = { - enable = mkEnableOption "grsecurity/PaX"; + enable = mkOption { + type = types.bool; + example = true; + default = false; + description = '' + Enable grsecurity/PaX. + ''; + }; lockTunables = mkOption { type = types.bool; @@ -58,20 +57,10 @@ in config = mkIf cfg.enable { - # Allow the user to select a different package set, subject to the stated - # required kernel config boot.kernelPackages = mkDefault pkgs.linuxPackages_grsec_nixos; boot.kernelParams = optional cfg.disableEfiRuntimeServices "noefi"; - system.requiredKernelConfig = with config.lib.kernelConfig; - [ (isEnabled "GRKERNSEC") - (isEnabled "PAX") - (isYes "GRKERNSEC_SYSCTL") - (isYes "GRKERNSEC_SYSCTL_DISTRO") - (isNo "GRKERNSEC_NO_RBAC") - ]; - nixpkgs.config.grsecurity = true; # Install PaX related utillities into the system profile. @@ -135,11 +124,5 @@ in "kernel.grsecurity.chroot_caps" = mkForce 0; }; - assertions = [ - { assertion = !zfsNeededForBoot; - message = "grsecurity is currently incompatible with ZFS"; - } - ]; - }; } diff --git a/nixos/modules/security/grsecurity.xml b/nixos/modules/security/grsecurity.xml index 37314bdba8a5..6f9884336b1e 100644 --- a/nixos/modules/security/grsecurity.xml +++ b/nixos/modules/security/grsecurity.xml @@ -225,11 +225,9 @@ </para> <para> - The NixOS module makes several assumptions about the kernel and so may be - incompatible with your customised kernel. Most of these assumptions are - encoded as assertions — mismatches should ideally result in a build - failure. Currently, the only way to work around incompatibilities is to - eschew the NixOS module and do all configuration yourself. + The NixOS module makes several assumptions about the kernel and so + may be incompatible with your customised kernel. Currently, the only way + to work around incompatibilities is to eschew the NixOS module. </para> </sect1> diff --git a/nixos/modules/services/backup/crashplan.nix b/nixos/modules/services/backup/crashplan.nix index 38cf8eb72fb8..d0af2e416b63 100644 --- a/nixos/modules/services/backup/crashplan.nix +++ b/nixos/modules/services/backup/crashplan.nix @@ -49,7 +49,7 @@ with lib; ensureDir ${crashplan.vardir}/backupArchives 700 ensureDir ${crashplan.vardir}/log 777 cp -avn ${crashplan}/conf.template/* ${crashplan.vardir}/conf - for x in app.asar bin EULA.txt install.vars lang lib libjniwrap64.so libjniwrap.so libjtux64.so libjtux.so libmd564.so libmd5.so share skin upgrade; do + for x in app.asar bin install.vars lang lib libc42archive64.so libc52archive.so libjniwrap64.so libjniwrap.so libjtux64.so libjtux.so libleveldb64.so libleveldb.so libmd564.so libmd5.so share skin upgrade; do rm -f ${crashplan.vardir}/$x; ln -sf ${crashplan}/$x ${crashplan.vardir}/$x; done diff --git a/nixos/modules/services/backup/tarsnap.nix b/nixos/modules/services/backup/tarsnap.nix index 24892a2a59a1..67112343c335 100644 --- a/nixos/modules/services/backup/tarsnap.nix +++ b/nixos/modules/services/backup/tarsnap.nix @@ -1,25 +1,25 @@ -{ config, lib, pkgs, ... }: +{ config, lib, pkgs, utils, ... }: with lib; let - cfg = config.services.tarsnap; + gcfg = config.services.tarsnap; configFile = name: cfg: '' - cachedir ${config.services.tarsnap.cachedir}/${name} - keyfile ${cfg.keyfile} + keyfile ${cfg.keyfile} + ${optionalString (cfg.cachedir != null) "cachedir ${cfg.cachedir}"} ${optionalString cfg.nodump "nodump"} ${optionalString cfg.printStats "print-stats"} ${optionalString cfg.printStats "humanize-numbers"} ${optionalString (cfg.checkpointBytes != null) ("checkpoint-bytes "+cfg.checkpointBytes)} ${optionalString cfg.aggressiveNetworking "aggressive-networking"} - ${concatStringsSep "\n" (map (v: "exclude "+v) cfg.excludes)} - ${concatStringsSep "\n" (map (v: "include "+v) cfg.includes)} + ${concatStringsSep "\n" (map (v: "exclude ${v}") cfg.excludes)} + ${concatStringsSep "\n" (map (v: "include ${v}") cfg.includes)} ${optionalString cfg.lowmem "lowmem"} ${optionalString cfg.verylowmem "verylowmem"} - ${optionalString (cfg.maxbw != null) ("maxbw "+toString cfg.maxbw)} - ${optionalString (cfg.maxbwRateUp != null) ("maxbw-rate-up "+toString cfg.maxbwRateUp)} - ${optionalString (cfg.maxbwRateDown != null) ("maxbw-rate-down "+toString cfg.maxbwRateDown)} + ${optionalString (cfg.maxbw != null) "maxbw ${toString cfg.maxbw}"} + ${optionalString (cfg.maxbwRateUp != null) "maxbw-rate-up ${toString cfg.maxbwRateUp}"} + ${optionalString (cfg.maxbwRateDown != null) "maxbw-rate-down ${toString cfg.maxbwRateDown}"} ''; in { @@ -60,34 +60,13 @@ in ''; }; - cachedir = mkOption { - type = types.nullOr types.path; - default = "/var/cache/tarsnap"; - description = '' - The cache allows tarsnap to identify previously stored data - blocks, reducing archival time and bandwidth usage. - - Should the cache become desynchronized or corrupted, tarsnap - will refuse to run until you manually rebuild the cache with - <command>tarsnap --fsck</command>. - - Note that each individual archive (specified below) has its own cache - directory specified under <literal>cachedir</literal>; this is because - tarsnap locks the cache during backups, meaning multiple services - archives cannot be backed up concurrently or overlap with a shared - cache. - - Set to <literal>null</literal> to disable caching. - ''; - }; - archives = mkOption { - type = types.attrsOf (types.submodule ( + type = types.attrsOf (types.submodule ({ config, ... }: { options = { keyfile = mkOption { type = types.str; - default = config.services.tarsnap.keyfile; + default = gcfg.keyfile; description = '' Set a specific keyfile for this archive. This defaults to <literal>"/root/tarsnap.key"</literal> if left unspecified. @@ -107,6 +86,21 @@ in ''; }; + cachedir = mkOption { + type = types.nullOr types.path; + default = "/var/cache/tarsnap/${utils.escapeSystemdPath config.keyfile}"; + description = '' + The cache allows tarsnap to identify previously stored data + blocks, reducing archival time and bandwidth usage. + + Should the cache become desynchronized or corrupted, tarsnap + will refuse to run until you manually rebuild the cache with + <command>tarsnap --fsck</command>. + + Set to <literal>null</literal> to disable caching. + ''; + }; + nodump = mkOption { type = types.bool; default = true; @@ -249,7 +243,7 @@ in }; gamedata = - { directories = [ "/var/lib/minecraft "]; + { directories = [ "/var/lib/minecraft" ]; period = "*:30"; }; } @@ -262,8 +256,8 @@ in archive names are suffixed by a 1 second resolution timestamp. For each member of the set is created a timer which triggers the - instanced <literal>tarsnap@</literal> service unit. You may use - <command>systemctl start tarsnap@archive-name</command> to + instanced <literal>tarsnap-archive-name</literal> service unit. You may use + <command>systemctl start tarsnap-archive-name</command> to manually trigger creation of <literal>archive-name</literal> at any time. ''; @@ -271,63 +265,73 @@ in }; }; - config = mkIf cfg.enable { + config = mkIf gcfg.enable { assertions = (mapAttrsToList (name: cfg: { assertion = cfg.directories != []; message = "Must specify paths for tarsnap to back up"; - }) cfg.archives) ++ + }) gcfg.archives) ++ (mapAttrsToList (name: cfg: { assertion = !(cfg.lowmem && cfg.verylowmem); message = "You cannot set both lowmem and verylowmem"; - }) cfg.archives); - - systemd.services."tarsnap@" = { - description = "Tarsnap archive '%i'"; - requires = [ "network-online.target" ]; - after = [ "network-online.target" ]; - - path = [ pkgs.iputils pkgs.tarsnap pkgs.coreutils ]; - - # In order for the persistent tarsnap timer to work reliably, we have to - # make sure that the tarsnap server is reachable after systemd starts up - # the service - therefore we sleep in a loop until we can ping the - # endpoint. - preStart = "while ! ping -q -c 1 v1-0-0-server.tarsnap.com &> /dev/null; do sleep 3; done"; - scriptArgs = "%i"; - script = '' - mkdir -p -m 0755 ${dirOf cfg.cachedir} - mkdir -p -m 0700 ${cfg.cachedir} - chown root:root ${cfg.cachedir} - chmod 0700 ${cfg.cachedir} - mkdir -p -m 0700 ${cfg.cachedir}/$1 - DIRS=`cat /etc/tarsnap/$1.dirs` - exec tarsnap --configfile /etc/tarsnap/$1.conf -c -f $1-$(date +"%Y%m%d%H%M%S") $DIRS - ''; - - serviceConfig = { - IOSchedulingClass = "idle"; - NoNewPrivileges = "true"; - CapabilityBoundingSet = "CAP_DAC_READ_SEARCH"; - PermissionsStartOnly = "true"; - }; - }; + }) gcfg.archives); + + systemd.services = + mapAttrs' (name: cfg: nameValuePair "tarsnap-${name}" { + description = "Tarsnap archive '${name}'"; + requires = [ "network-online.target" ]; + after = [ "network-online.target" ]; + + path = [ pkgs.iputils pkgs.tarsnap pkgs.utillinux ]; + + # In order for the persistent tarsnap timer to work reliably, we have to + # make sure that the tarsnap server is reachable after systemd starts up + # the service - therefore we sleep in a loop until we can ping the + # endpoint. + preStart = '' + while ! ping -q -c 1 v1-0-0-server.tarsnap.com &> /dev/null; do sleep 3; done + ''; + + script = + let run = ''tarsnap --configfile "/etc/tarsnap/${name}.conf" -c -f "${name}-$(date +"%Y%m%d%H%M%S")" ${concatStringsSep " " cfg.directories}''; + in if (cfg.cachedir != null) then '' + mkdir -p ${cfg.cachedir} + chmod 0700 ${cfg.cachedir} + + ( flock 9 + if [ ! -e ${cfg.cachedir}/firstrun ]; then + ( flock 10 + flock -u 9 + tarsnap --configfile "/etc/tarsnap/${name}.conf" --fsck + flock 9 + ) 10>${cfg.cachedir}/firstrun + fi + ) 9>${cfg.cachedir}/lockf + + exec flock ${cfg.cachedir}/firstrun ${run} + '' else "exec ${run}"; + + serviceConfig = { + Type = "oneshot"; + IOSchedulingClass = "idle"; + NoNewPrivileges = "true"; + CapabilityBoundingSet = [ "CAP_DAC_READ_SEARCH" ]; + PermissionsStartOnly = "true"; + }; + }) gcfg.archives; # Note: the timer must be Persistent=true, so that systemd will start it even # if e.g. your laptop was asleep while the latest interval occurred. - systemd.timers = mapAttrs' (name: cfg: nameValuePair "tarsnap@${name}" + systemd.timers = mapAttrs' (name: cfg: nameValuePair "tarsnap-${name}" { timerConfig.OnCalendar = cfg.period; timerConfig.Persistent = "true"; wantedBy = [ "timers.target" ]; - }) cfg.archives; + }) gcfg.archives; environment.etc = - (mapAttrs' (name: cfg: nameValuePair "tarsnap/${name}.conf" + mapAttrs' (name: cfg: nameValuePair "tarsnap/${name}.conf" { text = configFile name cfg; - }) cfg.archives) // - (mapAttrs' (name: cfg: nameValuePair "tarsnap/${name}.dirs" - { text = concatStringsSep " " cfg.directories; - }) cfg.archives); + }) gcfg.archives; environment.systemPackages = [ pkgs.tarsnap ]; }; diff --git a/nixos/modules/services/cluster/fleet.nix b/nixos/modules/services/cluster/fleet.nix index 78d4ea93c491..ec03be395948 100644 --- a/nixos/modules/services/cluster/fleet.nix +++ b/nixos/modules/services/cluster/fleet.nix @@ -28,7 +28,7 @@ in { etcdServers = mkOption { type = types.listOf types.str; - default = [ "http://127.0.0.1:4001" ]; + default = [ "http://127.0.0.1:2379" ]; description = '' Fleet list of etcd endpoints to use. ''; diff --git a/nixos/modules/services/cluster/kubernetes.nix b/nixos/modules/services/cluster/kubernetes.nix index 4bdd7f95f774..19303e97a706 100644 --- a/nixos/modules/services/cluster/kubernetes.nix +++ b/nixos/modules/services/cluster/kubernetes.nix @@ -23,7 +23,7 @@ in { etcdServers = mkOption { description = "Kubernetes list of etcd servers to watch."; - default = [ "127.0.0.1:4001" ]; + default = [ "127.0.0.1:2379" ]; type = types.listOf types.str; }; diff --git a/nixos/modules/services/cluster/panamax.nix b/nixos/modules/services/cluster/panamax.nix index b47ff744fc27..4475e8d8c24b 100644 --- a/nixos/modules/services/cluster/panamax.nix +++ b/nixos/modules/services/cluster/panamax.nix @@ -46,7 +46,7 @@ in { fleetctlEndpoint = mkOption { type = types.str; - default = "http://127.0.0.1:4001"; + default = "http://127.0.0.1:2379"; description = '' Panamax fleetctl endpoint. ''; diff --git a/nixos/modules/services/databases/riak-cs.nix b/nixos/modules/services/databases/riak-cs.nix new file mode 100644 index 000000000000..198efc29222a --- /dev/null +++ b/nixos/modules/services/databases/riak-cs.nix @@ -0,0 +1,202 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + + cfg = config.services.riak-cs; + +in + +{ + + ###### interface + + options = { + + services.riak-cs = { + + enable = mkEnableOption "riak-cs"; + + package = mkOption { + type = types.package; + default = pkgs.riak-cs; + defaultText = "pkgs.riak-cs"; + example = literalExample "pkgs.riak-cs"; + description = '' + Riak package to use. + ''; + }; + + nodeName = mkOption { + type = types.str; + default = "riak-cs@127.0.0.1"; + description = '' + Name of the Erlang node. + ''; + }; + + anonymousUserCreation = mkOption { + type = types.bool; + default = false; + description = '' + Anonymous user creation. + ''; + }; + + riakHost = mkOption { + type = types.str; + default = "127.0.0.1:8087"; + description = '' + Name of riak hosting service. + ''; + }; + + listener = mkOption { + type = types.str; + default = "127.0.0.1:8080"; + description = '' + Name of Riak CS listening service. + ''; + }; + + stanchionHost = mkOption { + type = types.str; + default = "127.0.0.1:8085"; + description = '' + Name of stanchion hosting service. + ''; + }; + + stanchionSsl = mkOption { + type = types.bool; + default = true; + description = '' + Tell stanchion to use SSL. + ''; + }; + + distributedCookie = mkOption { + type = types.str; + default = "riak"; + description = '' + Cookie for distributed node communication. All nodes in the + same cluster should use the same cookie or they will not be able to + communicate. + ''; + }; + + dataDir = mkOption { + type = types.path; + default = "/var/db/riak-cs"; + description = '' + Data directory for Riak CS. + ''; + }; + + logDir = mkOption { + type = types.path; + default = "/var/log/riak-cs"; + description = '' + Log directory for Riak CS. + ''; + }; + + extraConfig = mkOption { + type = types.lines; + default = ""; + description = '' + Additional text to be appended to <filename>riak-cs.conf</filename>. + ''; + }; + + extraAdvancedConfig = mkOption { + type = types.lines; + default = ""; + description = '' + Additional text to be appended to <filename>advanced.config</filename>. + ''; + }; + }; + + }; + + ###### implementation + + config = mkIf cfg.enable { + + environment.systemPackages = [ cfg.package ]; + environment.etc."riak-cs/riak-cs.conf".text = '' + nodename = ${cfg.nodeName} + distributed_cookie = ${cfg.distributedCookie} + + platform_log_dir = ${cfg.logDir} + + riak_host = ${cfg.riakHost} + listener = ${cfg.listener} + stanchion_host = ${cfg.stanchionHost} + + anonymous_user_creation = ${if cfg.anonymousUserCreation then "on" else "off"} + + ${cfg.extraConfig} + ''; + + environment.etc."riak-cs/advanced.config".text = '' + ${cfg.extraAdvancedConfig} + ''; + + users.extraUsers.riak-cs = { + name = "riak-cs"; + uid = config.ids.uids.riak-cs; + group = "riak"; + description = "Riak CS server user"; + }; + + systemd.services.riak-cs = { + description = "Riak CS Server"; + + wantedBy = [ "multi-user.target" ]; + after = [ "network.target" ]; + + path = [ + pkgs.utillinux # for `logger` + pkgs.bash + ]; + + environment.HOME = "${cfg.dataDir}"; + environment.RIAK_CS_DATA_DIR = "${cfg.dataDir}"; + environment.RIAK_CS_LOG_DIR = "${cfg.logDir}"; + environment.RIAK_CS_ETC_DIR = "/etc/riak"; + + preStart = '' + if ! test -e ${cfg.logDir}; then + mkdir -m 0755 -p ${cfg.logDir} + chown -R riak-cs ${cfg.logDir} + fi + + if ! test -e ${cfg.dataDir}; then + mkdir -m 0700 -p ${cfg.dataDir} + chown -R riak-cs ${cfg.dataDir} + fi + ''; + + serviceConfig = { + ExecStart = "${cfg.package}/bin/riak-cs console"; + ExecStop = "${cfg.package}/bin/riak-cs stop"; + StandardInput = "tty"; + User = "riak-cs"; + Group = "riak-cs"; + PermissionsStartOnly = true; + # Give Riak a decent amount of time to clean up. + TimeoutStopSec = 120; + LimitNOFILE = 65536; + }; + + unitConfig.RequiresMountsFor = [ + "${cfg.dataDir}" + "${cfg.logDir}" + "/etc/riak" + ]; + }; + }; +} diff --git a/nixos/modules/services/databases/riak.nix b/nixos/modules/services/databases/riak.nix index 4477904f78c6..d592d2e8ffdd 100644 --- a/nixos/modules/services/databases/riak.nix +++ b/nixos/modules/services/databases/riak.nix @@ -20,6 +20,8 @@ in package = mkOption { type = types.package; + default = pkgs.riak; + defaultText = "pkgs.riak"; example = literalExample "pkgs.riak"; description = '' Riak package to use. diff --git a/nixos/modules/services/databases/stanchion.nix b/nixos/modules/services/databases/stanchion.nix new file mode 100644 index 000000000000..f2dbb78b5c4b --- /dev/null +++ b/nixos/modules/services/databases/stanchion.nix @@ -0,0 +1,212 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + + cfg = config.services.stanchion; + +in + +{ + + ###### interface + + options = { + + services.stanchion = { + + enable = mkEnableOption "stanchion"; + + package = mkOption { + type = types.package; + default = pkgs.stanchion; + defaultText = "pkgs.stanchion"; + example = literalExample "pkgs.stanchion"; + description = '' + Stanchion package to use. + ''; + }; + + nodeName = mkOption { + type = types.str; + default = "stanchion@127.0.0.1"; + description = '' + Name of the Erlang node. + ''; + }; + + adminKey = mkOption { + type = types.str; + default = ""; + description = '' + Name of admin user. + ''; + }; + + adminSecret = mkOption { + type = types.str; + default = ""; + description = '' + Name of admin secret + ''; + }; + + riakHost = mkOption { + type = types.str; + default = "127.0.0.1:8087"; + description = '' + Name of riak hosting service. + ''; + }; + + listener = mkOption { + type = types.str; + default = "127.0.0.1:8085"; + description = '' + Name of Riak CS listening service. + ''; + }; + + stanchionHost = mkOption { + type = types.str; + default = "127.0.0.1:8085"; + description = '' + Name of stanchion hosting service. + ''; + }; + + stanchionSsl = mkOption { + type = types.bool; + default = true; + description = '' + Tell stanchion to use SSL. + ''; + }; + + distributedCookie = mkOption { + type = types.str; + default = "riak"; + description = '' + Cookie for distributed node communication. All nodes in the + same cluster should use the same cookie or they will not be able to + communicate. + ''; + }; + + dataDir = mkOption { + type = types.path; + default = "/var/db/stanchion"; + description = '' + Data directory for Stanchion. + ''; + }; + + logDir = mkOption { + type = types.path; + default = "/var/log/stanchion"; + description = '' + Log directory for Stanchino. + ''; + }; + + extraConfig = mkOption { + type = types.lines; + default = ""; + description = '' + Additional text to be appended to <filename>stanchion.conf</filename>. + ''; + }; + }; + }; + + ###### implementation + + config = mkIf cfg.enable { + + environment.systemPackages = [ cfg.package ]; + + environment.etc."stanchion/advanced.config".text = '' + [{stanchion, []}]. + ''; + + environment.etc."stanchion/stanchion.conf".text = '' + listener = ${cfg.listener} + + riak_host = ${cfg.riakHost} + + ${optionalString (cfg.adminKey == "") "#"} admin.key=${optionalString (cfg.adminKey != "") cfg.adminKey} + ${optionalString (cfg.adminSecret == "") "#"} admin.secret=${optionalString (cfg.adminSecret != "") cfg.adminSecret} + + platform_bin_dir = ${pkgs.stanchion}/bin + platform_data_dir = ${cfg.dataDir} + platform_etc_dir = /etc/stanchion + platform_lib_dir = ${pkgs.stanchion}/lib + platform_log_dir = ${cfg.logDir} + + nodename = ${cfg.nodeName} + + distributed_cookie = ${cfg.distributedCookie} + + stanchion_ssl=${if cfg.stanchionSsl then "on" else "off"} + + ${cfg.extraConfig} + ''; + + users.extraUsers.stanchion = { + name = "stanchion"; + uid = config.ids.uids.stanchion; + group = "stanchion"; + description = "Stanchion server user"; + }; + + users.extraGroups.stanchion.gid = config.ids.gids.stanchion; + + systemd.services.stanchion = { + description = "Stanchion Server"; + + wantedBy = [ "multi-user.target" ]; + after = [ "network.target" ]; + + path = [ + pkgs.utillinux # for `logger` + pkgs.bash + ]; + + environment.HOME = "${cfg.dataDir}"; + environment.STANCHION_DATA_DIR = "${cfg.dataDir}"; + environment.STANCHION_LOG_DIR = "${cfg.logDir}"; + environment.STANCHION_ETC_DIR = "/etc/stanchion"; + + preStart = '' + if ! test -e ${cfg.logDir}; then + mkdir -m 0755 -p ${cfg.logDir} + chown -R stanchion:stanchion ${cfg.logDir} + fi + + if ! test -e ${cfg.dataDir}; then + mkdir -m 0700 -p ${cfg.dataDir} + chown -R stanchion:stanchion ${cfg.dataDir} + fi + ''; + + serviceConfig = { + ExecStart = "${cfg.package}/bin/stanchion console"; + ExecStop = "${cfg.package}/bin/stanchion stop"; + StandardInput = "tty"; + User = "stanchion"; + Group = "stanchion"; + PermissionsStartOnly = true; + # Give Stanchion a decent amount of time to clean up. + TimeoutStopSec = 120; + LimitNOFILE = 65536; + }; + + unitConfig.RequiresMountsFor = [ + "${cfg.dataDir}" + "${cfg.logDir}" + "/etc/stanchion" + ]; + }; + }; +} diff --git a/nixos/modules/services/editors/emacs.xml b/nixos/modules/services/editors/emacs.xml index bcaa8b8df3d8..e03f6046de8e 100644 --- a/nixos/modules/services/editors/emacs.xml +++ b/nixos/modules/services/editors/emacs.xml @@ -356,14 +356,14 @@ https://nixos.org/nixpkgs/manual/#sec-modify-via-packageOverrides <programlisting><![CDATA[ { pkgs ? import <nixpkgs> {} }: let - myEmacs = pkgs.lib.overrideDerivation (pkgs.emacs.override { + myEmacs = (pkgs.emacs.override { # Use gtk3 instead of the default gtk2 withGTK3 = true; withGTK2 = false; - }) (attrs: { + }).overrideAttrs (attrs: { # I don't want emacs.desktop file because I only use # emacsclient. - postInstall = attrs.postInstall + '' + postInstall = (attrs.postInstall or "") + '' rm $out/share/applications/emacs.desktop ''; }); diff --git a/nixos/modules/services/games/ghost-one.nix b/nixos/modules/services/games/ghost-one.nix index 5762148df2bb..71ff6bb2f3f0 100644 --- a/nixos/modules/services/games/ghost-one.nix +++ b/nixos/modules/services/games/ghost-one.nix @@ -21,8 +21,7 @@ in language = mkOption { default = "English"; - type = types.addCheck types.str - (lang: elem lang [ "English" "Spanish" "Russian" "Serbian" "Turkish" ]); + type = types.enum [ "English" "Spanish" "Russian" "Serbian" "Turkish" ]; description = "The language of bot messages: English, Spanish, Russian, Serbian or Turkish."; }; diff --git a/nixos/modules/services/hardware/sane.nix b/nixos/modules/services/hardware/sane.nix index a34037403123..8ddb9ef9c53b 100644 --- a/nixos/modules/services/hardware/sane.nix +++ b/nixos/modules/services/hardware/sane.nix @@ -7,9 +7,35 @@ let pkg = if config.hardware.sane.snapshot then pkgs.sane-backends-git else pkgs.sane-backends; - backends = [ pkg ] ++ config.hardware.sane.extraBackends; + + sanedConf = pkgs.writeTextFile { + name = "saned.conf"; + destination = "/etc/sane.d/saned.conf"; + text = '' + localhost + ${config.services.saned.extraConfig} + ''; + }; + + netConf = pkgs.writeTextFile { + name = "net.conf"; + destination = "/etc/sane.d/net.conf"; + text = '' + ${lib.optionalString config.services.saned.enable "localhost"} + ${config.hardware.sane.netConf} + ''; + }; + + env = { + SANE_CONFIG_DIR = config.hardware.sane.configDir; + LD_LIBRARY_PATH = [ "${saneConfig}/lib/sane" ]; + }; + + backends = [ pkg netConf ] ++ optional config.services.saned.enable sanedConf ++ config.hardware.sane.extraBackends; saneConfig = pkgs.mkSaneConfig { paths = backends; }; + enabled = config.hardware.sane.enable || config.services.saned.enable; + in { @@ -51,27 +77,86 @@ in hardware.sane.configDir = mkOption { type = types.string; + internal = true; description = "The value of SANE_CONFIG_DIR."; }; - }; + hardware.sane.netConf = mkOption { + type = types.lines; + default = ""; + example = "192.168.0.16"; + description = '' + Network hosts that should be probed for remote scanners. + ''; + }; + services.saned.enable = mkOption { + type = types.bool; + default = false; + description = '' + Enable saned network daemon for remote connection to scanners. - ###### implementation + saned would be runned from <literal>scanner</literal> user; to allow + access to hardware that doesn't have <literal>scanner</literal> group + you should add needed groups to this user. + ''; + }; - config = mkIf config.hardware.sane.enable { + services.saned.extraConfig = mkOption { + type = types.lines; + default = ""; + example = "192.168.0.0/24"; + description = '' + Extra saned configuration lines. + ''; + }; - hardware.sane.configDir = mkDefault "${saneConfig}/etc/sane.d"; + }; - environment.systemPackages = backends; - environment.sessionVariables = { - SANE_CONFIG_DIR = config.hardware.sane.configDir; - LD_LIBRARY_PATH = [ "${saneConfig}/lib/sane" ]; - }; - services.udev.packages = backends; - users.extraGroups."scanner".gid = config.ids.gids.scanner; + ###### implementation - }; + config = mkMerge [ + (mkIf enabled { + hardware.sane.configDir = mkDefault "${saneConfig}/etc/sane.d"; + + environment.systemPackages = backends; + environment.sessionVariables = env; + services.udev.packages = backends; + + users.extraGroups."scanner".gid = config.ids.gids.scanner; + }) + + (mkIf config.services.saned.enable { + networking.firewall.connectionTrackingModules = [ "sane" ]; + + systemd.services."saned@" = { + description = "Scanner Service"; + environment = mapAttrs (name: val: toString val) env; + serviceConfig = { + User = "scanner"; + Group = "scanner"; + ExecStart = "${pkg}/bin/saned"; + }; + }; + + systemd.sockets.saned = { + description = "saned incoming socket"; + wantedBy = [ "sockets.target" ]; + listenStreams = [ "0.0.0.0:6566" "[::]:6566" ]; + socketConfig = { + # saned needs to distinguish between IPv4 and IPv6 to open matching data sockets. + BindIPv6Only = "ipv6-only"; + Accept = true; + MaxConnections = 1; + }; + }; + + users.extraUsers."scanner" = { + uid = config.ids.uids.scanner; + group = "scanner"; + }; + }) + ]; } diff --git a/nixos/modules/services/logging/logcheck.nix b/nixos/modules/services/logging/logcheck.nix index a8a214b21550..27ed5374f561 100644 --- a/nixos/modules/services/logging/logcheck.nix +++ b/nixos/modules/services/logging/logcheck.nix @@ -55,9 +55,9 @@ let levelOption = mkOption { default = "server"; - type = types.str; + type = types.enum [ "workstation" "server" "paranoid" ]; description = '' - Set the logcheck level. Either "workstation", "server", or "paranoid". + Set the logcheck level. ''; }; diff --git a/nixos/modules/services/misc/errbot.nix b/nixos/modules/services/misc/errbot.nix index f573be69925c..427cb7c546d0 100644 --- a/nixos/modules/services/misc/errbot.nix +++ b/nixos/modules/services/misc/errbot.nix @@ -8,7 +8,7 @@ let name = "errbot-plugins"; paths = plugins; }; - mkConfigFile = instanceCfg: dataDir: pkgs.writeText "errbot-config.py" '' + mkConfigDir = instanceCfg: dataDir: pkgs.writeTextDir "config.py" '' import logging BACKEND = '${instanceCfg.backend}' BOT_DATA_DIR = '${dataDir}' @@ -93,7 +93,7 @@ in { serviceConfig = { User = "errbot"; Restart = "on-failure"; - ExecStart = "${pkgs.errbot}/bin/errbot -c ${mkConfigFile instanceCfg dataDir}"; + ExecStart = "${pkgs.errbot}/bin/errbot -c ${mkConfigDir instanceCfg dataDir}/config.py"; PermissionsStartOnly = true; }; })) cfg.instances; diff --git a/nixos/modules/services/misc/leaps.nix b/nixos/modules/services/misc/leaps.nix new file mode 100644 index 000000000000..b92cf27f58dc --- /dev/null +++ b/nixos/modules/services/misc/leaps.nix @@ -0,0 +1,62 @@ +{ config, pkgs, lib, ... } @ args: + +with lib; + +let + cfg = config.services.leaps; + stateDir = "/var/lib/leaps/"; +in +{ + options = { + services.leaps = { + enable = mkEnableOption "leaps"; + port = mkOption { + type = types.int; + default = 8080; + description = "A port where leaps listens for incoming http requests"; + }; + address = mkOption { + default = ""; + type = types.str; + example = "127.0.0.1"; + description = "Hostname or IP-address to listen to. By default it will listen on all interfaces."; + }; + path = mkOption { + default = "/"; + type = types.path; + description = "Subdirectory used for reverse proxy setups"; + }; + }; + }; + + config = mkIf cfg.enable { + users = { + users.leaps = { + uid = config.ids.uids.leaps; + description = "Leaps server user"; + group = "leaps"; + home = stateDir; + createHome = true; + }; + + groups.leaps = { + gid = config.ids.gids.leaps; + }; + }; + + systemd.services.leaps = { + description = "leaps service"; + wantedBy = [ "multi-user.target" ]; + after = [ "network.target" ]; + + serviceConfig = { + User = "leaps"; + Group = "leaps"; + Restart = "on-failure"; + WorkingDirectory = stateDir; + PrivateTmp = true; + ExecStart = "${pkgs.leaps.bin}/bin/leaps -path ${toString cfg.path} -address ${cfg.address}:${toString cfg.port}"; + }; + }; + }; +} diff --git a/nixos/modules/services/misc/nix-daemon.nix b/nixos/modules/services/misc/nix-daemon.nix index 333782d15bcb..e2bbd4b01aa1 100644 --- a/nixos/modules/services/misc/nix-daemon.nix +++ b/nixos/modules/services/misc/nix-daemon.nix @@ -172,8 +172,8 @@ in sshKey = "/root/.ssh/id_buildfarm"; system = "x86_64-linux"; maxJobs = 2; - supportedFeatures = "kvm"; - mandatoryFeatures = "perf"; + supportedFeatures = [ "kvm" ]; + mandatoryFeatures = [ "perf" ]; } ]; description = '' diff --git a/nixos/modules/services/misc/parsoid.nix b/nixos/modules/services/misc/parsoid.nix index 0844190a5490..ae3f84333d2d 100644 --- a/nixos/modules/services/misc/parsoid.nix +++ b/nixos/modules/services/misc/parsoid.nix @@ -6,20 +6,21 @@ let cfg = config.services.parsoid; - conf = '' - exports.setup = function( parsoidConfig ) { - ${toString (mapAttrsToList (name: str: "parsoidConfig.setInterwiki('${name}', '${str}');") cfg.interwikis)} - - parsoidConfig.serverInterface = "${cfg.interface}"; - parsoidConfig.serverPort = ${toString cfg.port}; - - parsoidConfig.useSelser = true; - - ${cfg.extraConfig} - }; - ''; + confTree = { + worker_heartbeat_timeout = 300000; + logging = { level = "info"; }; + services = [{ + module = "lib/index.js"; + entrypoint = "apiServiceWorker"; + conf = { + mwApis = map (x: if isAttrs x then x else { uri = x; }) cfg.wikis; + serverInterface = cfg.interface; + serverPort = cfg.port; + }; + }]; + }; - confFile = builtins.toFile "localsettings.js" conf; + confFile = pkgs.writeText "config.yml" (builtins.toJSON (recursiveUpdate confTree cfg.extraConfig)); in { @@ -38,9 +39,9 @@ in ''; }; - interwikis = mkOption { - type = types.attrsOf types.str; - example = { localhost = "http://localhost/api.php"; }; + wikis = mkOption { + type = types.listOf (types.either types.str types.attrs); + example = [ "http://localhost/api.php" ]; description = '' Used MediaWiki API endpoints. ''; @@ -71,8 +72,8 @@ in }; extraConfig = mkOption { - type = types.lines; - default = ""; + type = types.attrs; + default = {}; description = '' Extra configuration to add to parsoid configuration. ''; @@ -91,7 +92,8 @@ in wantedBy = [ "multi-user.target" ]; after = [ "network.target" ]; serviceConfig = { - ExecStart = "${pkgs.nodePackages.parsoid}/lib/node_modules/parsoid/api/server.js -c ${confFile} -n ${toString cfg.workers}"; + User = "nobody"; + ExecStart = "${pkgs.nodePackages.parsoid}/lib/node_modules/parsoid/bin/server.js -c ${confFile} -n ${toString cfg.workers}"; }; }; diff --git a/nixos/modules/services/misc/taskserver/default.nix b/nixos/modules/services/misc/taskserver/default.nix index 233c47684b7d..ca82a733f6fc 100644 --- a/nixos/modules/services/misc/taskserver/default.nix +++ b/nixos/modules/services/misc/taskserver/default.nix @@ -292,7 +292,7 @@ in { }; allowedClientIDs = mkOption { - type = with types; loeOf (either (enum ["all" "none"]) str); + type = with types; either str (listOf str); default = []; example = [ "[Tt]ask [2-9]+" ]; description = '' @@ -306,7 +306,7 @@ in { }; disallowedClientIDs = mkOption { - type = with types; loeOf (either (enum ["all" "none"]) str); + type = with types; either str (listOf str); default = []; example = [ "[Tt]ask [2-9]+" ]; description = '' diff --git a/nixos/modules/services/network-filesystems/ipfs.nix b/nixos/modules/services/network-filesystems/ipfs.nix new file mode 100644 index 000000000000..c26a70737033 --- /dev/null +++ b/nixos/modules/services/network-filesystems/ipfs.nix @@ -0,0 +1,111 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + inherit (pkgs) ipfs; + + cfg = config.services.ipfs; + + ipfsFlags = ''${if cfg.autoMigrate then "--migrate" else ""} ${if cfg.enableGC then "--enable-gc" else ""} ${toString cfg.extraFlags}''; + +in + +{ + + ###### interface + + options = { + + services.ipfs = { + + enable = mkEnableOption "Interplanetary File System"; + + user = mkOption { + type = types.str; + default = "ipfs"; + description = "User under which the IPFS daemon runs"; + }; + + group = mkOption { + type = types.str; + default = "ipfs"; + description = "Group under which the IPFS daemon runs"; + }; + + dataDir = mkOption { + type = types.str; + default = "/var/lib/ipfs"; + description = "The data dir for IPFS"; + }; + + autoMigrate = mkOption { + type = types.bool; + default = false; + description = '' + Whether IPFS should try to migrate the file system automatically. + ''; + }; + + enableGC = mkOption { + type = types.bool; + default = false; + description = '' + Whether to enable automatic garbage collection. + ''; + }; + + extraFlags = mkOption { + type = types.listOf types.str; + description = "Extra flags passed to the IPFS daemon"; + default = []; + }; + }; + }; + + ###### implementation + + config = mkIf cfg.enable { + environment.systemPackages = [ pkgs.ipfs ]; + + users.extraUsers = mkIf (cfg.user == "ipfs") { + ipfs = { + group = cfg.group; + home = cfg.dataDir; + createHome = false; + uid = config.ids.uids.ipfs; + description = "IPFS daemon user"; + }; + }; + + users.extraGroups = mkIf (cfg.group == "ipfs") { + ipfs = { + gid = config.ids.gids.ipfs; + }; + }; + + systemd.services.ipfs = { + description = "IPFS Daemon"; + + wantedBy = [ "multi-user.target" ]; + after = [ "network.target" "local-fs.target" ]; + path = [ pkgs.ipfs pkgs.su pkgs.bash ]; + + preStart = + '' + install -m 0755 -o ${cfg.user} -g ${cfg.group} -d ${cfg.dataDir} + if [[ ! -d ${cfg.dataDir}/.ipfs ]]; then + cd ${cfg.dataDir} + ${pkgs.su}/bin/su -s ${pkgs.bash}/bin/sh ${cfg.user} -c "${ipfs}/bin/ipfs init" + fi + ''; + + serviceConfig = { + ExecStart = "${ipfs}/bin/ipfs daemon ${ipfsFlags}"; + User = cfg.user; + Group = cfg.group; + PermissionsStartOnly = true; + }; + }; + }; +} diff --git a/nixos/modules/services/network-filesystems/tahoe.nix b/nixos/modules/services/network-filesystems/tahoe.nix index f1846b963252..f91827c379de 100644 --- a/nixos/modules/services/network-filesystems/tahoe.nix +++ b/nixos/modules/services/network-filesystems/tahoe.nix @@ -138,6 +138,45 @@ in ''; }; helper.enable = mkEnableOption "helper service"; + sftpd.enable = mkEnableOption "SFTP service"; + sftpd.port = mkOption { + default = null; + type = types.nullOr types.int; + description = '' + The port on which the SFTP server will listen. + + This is the correct setting to tweak if you want Tahoe's SFTP + daemon to listen on a different port. + ''; + }; + sftpd.hostPublicKeyFile = mkOption { + default = null; + type = types.nullOr types.path; + description = '' + Path to the SSH host public key. + ''; + }; + sftpd.hostPrivateKeyFile = mkOption { + default = null; + type = types.nullOr types.path; + description = '' + Path to the SSH host private key. + ''; + }; + sftpd.accounts.file = mkOption { + default = null; + type = types.nullOr types.path; + description = '' + Path to the accounts file. + ''; + }; + sftpd.accounts.url = mkOption { + default = null; + type = types.nullOr types.str; + description = '' + URL of the accounts server. + ''; + }; package = mkOption { default = pkgs.tahoelafs; defaultText = "pkgs.tahoelafs"; @@ -256,6 +295,19 @@ in [helper] enabled = ${if settings.helper.enable then "true" else "false"} + + [sftpd] + enabled = ${if settings.sftpd.enable then "true" else "false"} + ${optionalString (settings.sftpd.port != null) + "port = ${toString settings.sftpd.port}"} + ${optionalString (settings.sftpd.hostPublicKeyFile != null) + "host_pubkey_file = ${settings.sftpd.hostPublicKeyFile}"} + ${optionalString (settings.sftpd.hostPrivateKeyFile != null) + "host_privkey_file = ${settings.sftpd.hostPrivateKeyFile}"} + ${optionalString (settings.sftpd.accounts.file != null) + "accounts.file = ${settings.sftpd.accounts.file}"} + ${optionalString (settings.sftpd.accounts.url != null) + "accounts.url = ${settings.sftpd.accounts.url}"} ''; }); # Actually require Tahoe, so that we will have it installed. diff --git a/nixos/modules/services/network-filesystems/yandex-disk.nix b/nixos/modules/services/network-filesystems/yandex-disk.nix index 982b6ca5ea7b..4de206641331 100644 --- a/nixos/modules/services/network-filesystems/yandex-disk.nix +++ b/nixos/modules/services/network-filesystems/yandex-disk.nix @@ -55,6 +55,15 @@ in description = "The directory to use for Yandex.Disk storage"; }; + excludes = mkOption { + default = ""; + type = types.string; + example = "data,backup"; + description = '' + Comma-separated list of directories which are excluded from synchronization. + ''; + }; + }; }; @@ -86,7 +95,7 @@ in chown ${u} ${dir} if ! test -d "${cfg.directory}" ; then - mkdir -p -m 755 ${cfg.directory} || + (mkdir -p -m 755 ${cfg.directory} && chown ${u} ${cfg.directory}) || exit 1 fi @@ -94,7 +103,7 @@ in -c '${pkgs.yandex-disk}/bin/yandex-disk token -p ${cfg.password} ${cfg.username} ${dir}/token' ${pkgs.su}/bin/su -s ${pkgs.stdenv.shell} ${u} \ - -c '${pkgs.yandex-disk}/bin/yandex-disk start --no-daemon -a ${dir}/token -d ${cfg.directory}' + -c '${pkgs.yandex-disk}/bin/yandex-disk start --no-daemon -a ${dir}/token -d ${cfg.directory} --exclude-dirs=${cfg.excludes}' ''; }; diff --git a/nixos/modules/services/networking/bitlbee.nix b/nixos/modules/services/networking/bitlbee.nix index 5e6847097a94..e72ea20cccee 100644 --- a/nixos/modules/services/networking/bitlbee.nix +++ b/nixos/modules/services/networking/bitlbee.nix @@ -7,11 +7,6 @@ let cfg = config.services.bitlbee; bitlbeeUid = config.ids.uids.bitlbee; - authModeCheck = v: - v == "Open" || - v == "Closed" || - v == "Registered"; - bitlbeeConfig = pkgs.writeText "bitlbee.conf" '' [settings] @@ -67,7 +62,7 @@ in authMode = mkOption { default = "Open"; - type = types.addCheck types.str authModeCheck; + type = types.enum [ "Open" "Closed" "Registered" ]; description = '' The following authentication modes are available: Open -- Accept connections from anyone, use NickServ for user authentication. diff --git a/nixos/modules/services/networking/cjdns.nix b/nixos/modules/services/networking/cjdns.nix index 5e15e40ea0c1..f50dae2ab7be 100644 --- a/nixos/modules/services/networking/cjdns.nix +++ b/nixos/modules/services/networking/cjdns.nix @@ -19,30 +19,21 @@ let type = types.str; description = "Public key at the opposite end of the tunnel."; }; - hostname = mkOption { - default = ""; - example = "foobar.hype"; - type = types.str; - description = "Optional hostname to add to /etc/hosts; prevents reverse lookup failures."; - }; }; }; - # Additional /etc/hosts entries for peers with an associated hostname - cjdnsExtraHosts = import (pkgs.runCommand "cjdns-hosts" {} - # Generate a builder that produces an output usable as a Nix string value - '' - exec >$out - echo \'\' - ${concatStringsSep "\n" (mapAttrsToList (k: v: - optionalString (v.hostname != "") - "echo $(${pkgs.cjdns}/bin/publictoip6 ${x.key}) ${x.host}") - (cfg.ETHInterface.connectTo // cfg.UDPInterface.connectTo))} - echo \'\' - ''); - - parseModules = x: - x // { connectTo = mapAttrs (name: value: { inherit (value) password publicKey; }) x.connectTo; }; + # check for the required attributes, otherwise + # permit attributes not undefined here + checkPeers = x: + x // { + connectTo = mapAttrs + (name: value: + if !hasAttr "publicKey" value then abort "cjdns peer ${name} missing a publicKey" else + if !hasAttr "password" value then abort "cjdns peer ${name} missing a password" else + value + ) + x.connectTo; + }; # would be nice to merge 'cfg' with a //, # but the json nesting is wacky. @@ -53,8 +44,8 @@ let }; authorizedPasswords = map (p: { password = p; }) cfg.authorizedPasswords; interfaces = { - ETHInterface = if (cfg.ETHInterface.bind != "") then [ (parseModules cfg.ETHInterface) ] else [ ]; - UDPInterface = if (cfg.UDPInterface.bind != "") then [ (parseModules cfg.UDPInterface) ] else [ ]; + ETHInterface = if (cfg.ETHInterface.bind != "") then [ (checkPeers cfg.ETHInterface) ] else [ ]; + UDPInterface = if (cfg.UDPInterface.bind != "") then [ (checkPeers cfg.UDPInterface) ] else [ ]; }; privateKey = "@CJDNS_PRIVATE_KEY@"; @@ -134,12 +125,12 @@ in ''; }; connectTo = mkOption { - type = types.attrsOf ( types.submodule ( connectToSubmodule ) ); + type = types.attrsOf (types.attrsOf types.str); default = { }; example = { "192.168.1.1:27313" = { - hostname = "homer.hype"; - password = "5kG15EfpdcKNX3f2GSQ0H1HC7yIfxoCoImnO5FHM"; + user = "foobar"; + password = "5kG15EfpdcKNX3f2GSQ0H1HC7yIfxoCoImnO5FHM"; publicKey = "371zpkgs8ss387tmr81q04mp0hg1skb51hw34vk1cq644mjqhup0.k"; }; }; @@ -179,12 +170,12 @@ in }; connectTo = mkOption { - type = types.attrsOf ( types.submodule ( connectToSubmodule ) ); + type = types.attrsOf (types.attrsOf types.str); default = { }; example = { "01:02:03:04:05:06" = { - hostname = "homer.hype"; - password = "5kG15EfpdcKNX3f2GSQ0H1HC7yIfxoCoImnO5FHM"; + user = "foobar"; + password = "5kG15EfpdcKNX3f2GSQ0H1HC7yIfxoCoImnO5FHM"; publicKey = "371zpkgs8ss387tmr81q04mp0hg1skb51hw34vk1cq644mjqhup0.k"; }; }; @@ -245,14 +236,15 @@ in serviceConfig = { Type = "forking"; Restart = "on-failure"; - + CapabilityBoundingSet = "CAP_NET_ADMIN CAP_NET_RAW"; + AmbientCapabilities = "CAP_NET_ADMIN CAP_NET_RAW"; + ProtectSystem = "full"; + MemoryDenyWriteExecute = true; ProtectHome = true; PrivateTmp = true; }; }; - networking.extraHosts = cjdnsExtraHosts; - assertions = [ { assertion = ( cfg.ETHInterface.bind != "" || cfg.UDPInterface.bind != "" || cfg.confFile != null ); message = "Neither cjdns.ETHInterface.bind nor cjdns.UDPInterface.bind defined."; diff --git a/nixos/modules/services/networking/dnscrypt-proxy.nix b/nixos/modules/services/networking/dnscrypt-proxy.nix index 5a24db8ccba0..82bf178f4cb7 100644 --- a/nixos/modules/services/networking/dnscrypt-proxy.nix +++ b/nixos/modules/services/networking/dnscrypt-proxy.nix @@ -5,15 +5,25 @@ 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}"; - daemonArgs = - [ "--local-address=${localAddress}" - (optionalString cfg.tcpOnly "--tcp-only") - (optionalString cfg.ephemeralKeys "-E") - ] - ++ resolverArgs; + # The minisign public key used to sign the upstream resolver list. + # This is somewhat more flexible than preloading the key as an + # embedded string. + upstreamResolverListPubKey = pkgs.fetchurl { + url = https://raw.githubusercontent.com/jedisct1/dnscrypt-proxy/master/minisign.pub; + 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 @@ -22,9 +32,16 @@ let "--provider-key=${cfg.customResolver.key}" ] else - [ "--resolvers-list=${cfg.resolverList}" - "--resolver-name=${toString cfg.resolverName}" + [ "--resolvers-list=${resolverList}" + "--resolver-name=${cfg.resolverName}" ]; + + # The final command line arguments passed to the daemon + daemonArgs = + [ "--local-address=${localAddress}" ] + ++ optional cfg.tcpOnly "--tcp-only" + ++ optional cfg.ephemeralKeys "-E" + ++ resolverArgs; in { @@ -66,24 +83,20 @@ in default = "dnscrypt.eu-nl"; type = types.nullOr types.str; description = '' - The name of the upstream DNSCrypt resolver to use, taken from the - list named in the <literal>resolverList</literal> option. - The default resolver is located in Holland, supports DNS security - extensions, and claims to not keep logs. + 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 = '' - The list of upstream DNSCrypt resolvers. By default, we use the most - recent list published by upstream. + List of DNSCrypt resolvers. The default is to use the list of + public resolvers provided by upstream. ''; - example = literalExample "${pkgs.dnscrypt-proxy}/share/dnscrypt-proxy/dnscrypt-resolvers.csv"; - default = pkgs.fetchurl { - url = https://raw.githubusercontent.com/jedisct1/dnscrypt-proxy/master/dnscrypt-resolvers.csv; - sha256 = "1i9wzw4zl052h5nyp28bwl8d66cgj0awvjhw5wgwz0warkjl1g8g"; - }; - defaultText = "pkgs.fetchurl { url = ...; sha256 = ...; }"; }; customResolver = mkOption { @@ -150,7 +163,7 @@ in } ]; - security.apparmor.profiles = mkIf apparmorEnabled (singleton (pkgs.writeText "apparmor-dnscrypt-proxy" '' + security.apparmor.profiles = optional apparmorEnabled (pkgs.writeText "apparmor-dnscrypt-proxy" '' ${dnscrypt-proxy}/bin/dnscrypt-proxy { /dev/null rw, /dev/urandom r, @@ -177,9 +190,9 @@ in ${getLib pkgs.lz4}/lib/liblz4.so.* mr, ${getLib pkgs.attr}/lib/libattr.so.* mr, - ${cfg.resolverList} r, + ${resolverList} r, } - '')); + ''); users.users.dnscrypt-proxy = { description = "dnscrypt-proxy daemon user"; @@ -188,11 +201,61 @@ in }; users.groups.dnscrypt-proxy = {}; + systemd.services.init-dnscrypt-proxy-statedir = optionalAttrs useUpstreamResolverList { + description = "Initialize dnscrypt-proxy state directory"; + script = '' + mkdir -pv ${stateDirectory} + chown -c dnscrypt-proxy:dnscrypt-proxy ${stateDirectory} + cp --preserve=timestamps -uv \ + ${pkgs.dnscrypt-proxy}/share/dnscrypt-proxy/dnscrypt-resolvers.csv \ + ${stateDirectory} + ''; + serviceConfig = { + Type = "oneshot"; + RemainAfterExit = true; + }; + }; + + systemd.services.update-dnscrypt-resolvers = optionalAttrs useUpstreamResolverList { + description = "Update list of DNSCrypt resolvers"; + + requires = [ "init-dnscrypt-proxy-statedir.service" ]; + after = [ "init-dnscrypt-proxy-statedir.service" ]; + + path = with pkgs; [ curl 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 + mv dnscrypt-resolvers.csv.minisig{.tmp,} + minisign -q -V -p ${upstreamResolverListPubKey} \ + -m dnscrypt-resolvers.csv.tmp -x dnscrypt-resolvers.csv.minisig + mv dnscrypt-resolvers.csv{.tmp,} + ''; + + serviceConfig = { + PrivateTmp = true; + PrivateDevices = true; + ProtectHome = true; + ProtectSystem = true; + }; + }; + + systemd.timers.update-dnscrypt-resolvers = optionalAttrs useUpstreamResolverList { + timerConfig = { + OnBootSec = "5min"; + OnUnitActiveSec = "6h"; + }; + wantedBy = [ "timers.target" ]; + }; + systemd.sockets.dnscrypt-proxy = { description = "dnscrypt-proxy listening socket"; socketConfig = { - ListenStream = "${localAddress}"; - ListenDatagram = "${localAddress}"; + ListenStream = localAddress; + ListenDatagram = localAddress; }; wantedBy = [ "sockets.target" ]; }; @@ -200,8 +263,13 @@ in systemd.services.dnscrypt-proxy = { description = "dnscrypt-proxy daemon"; - after = [ "network.target" ] ++ optional apparmorEnabled "apparmor.service"; - requires = [ "dnscrypt-proxy.socket "] ++ optional apparmorEnabled "apparmor.service"; + 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"; diff --git a/nixos/modules/services/networking/hostapd.nix b/nixos/modules/services/networking/hostapd.nix index 51f95af48029..fd4545e88e2d 100644 --- a/nixos/modules/services/networking/hostapd.nix +++ b/nixos/modules/services/networking/hostapd.nix @@ -86,7 +86,7 @@ in hwMode = mkOption { default = "g"; - type = types.string; + type = types.enum [ "a" "b" "g" ]; description = '' Operation mode. (a = IEEE 802.11a, b = IEEE 802.11b, g = IEEE 802.11g). @@ -152,9 +152,6 @@ in config = mkIf cfg.enable { assertions = [ - { assertion = (cfg.hwMode == "a" || cfg.hwMode == "b" || cfg.hwMode == "g"); - message = "hwMode must be a/b/g"; - } { assertion = (cfg.channel >= 1 && cfg.channel <= 13); message = "channel must be between 1 and 13"; }]; diff --git a/nixos/modules/services/networking/i2pd.nix b/nixos/modules/services/networking/i2pd.nix index 926857a0ff4e..578376764eba 100644 --- a/nixos/modules/services/networking/i2pd.nix +++ b/nixos/modules/services/networking/i2pd.nix @@ -10,7 +10,7 @@ let extip = "EXTIP=\$(${pkgs.curl.bin}/bin/curl -sf \"http://jsonip.com\" | ${pkgs.gawk}/bin/awk -F'\"' '{print $4}')"; - toYesNo = b: if b then "yes" else "no"; + toYesNo = b: if b then "true" else "false"; mkEndpointOpt = name: addr: port: { enable = mkEnableOption name; @@ -31,6 +31,17 @@ let }; }; + mkKeyedEndpointOpt = name: addr: port: keyFile: + (mkEndpointOpt name addr port) // { + keys = mkOption { + type = types.str; + default = ""; + description = '' + File to persist ${lib.toUpper name} keys. + ''; + }; + }; + commonTunOpts = let i2cpOpts = { length = mkOption { @@ -63,19 +74,49 @@ let }; } // mkEndpointOpt name "127.0.0.1" 0; - i2pdConf = pkgs.writeText "i2pd.conf" '' - ipv6 = ${toYesNo cfg.enableIPv6} - notransit = ${toYesNo cfg.notransit} - floodfill = ${toYesNo cfg.floodfill} - ${if isNull cfg.port then "" else "port = ${toString cfg.port}"} - ${flip concatMapStrings - (collect (proto: proto ? port && proto ? address && proto ? name) cfg.proto) - (proto: let portStr = toString proto.port; in '' - [${proto.name}] - address = ${proto.address} - port = ${toString proto.port} - enabled = ${toYesNo proto.enable} - '') + i2pdConf = pkgs.writeText "i2pd.conf" + '' + ipv4 = ${toYesNo cfg.enableIPv4} + ipv6 = ${toYesNo cfg.enableIPv6} + notransit = ${toYesNo cfg.notransit} + floodfill = ${toYesNo cfg.floodfill} + netid = ${toString cfg.netid} + ${if isNull cfg.bandwidth then "" else "bandwidth = ${toString cfg.bandwidth}" } + ${if isNull cfg.port then "" else "port = ${toString cfg.port}"} + + [limits] + transittunnels = ${toString cfg.limits.transittunnels} + + [upnp] + enabled = ${toYesNo cfg.upnp.enable} + name = ${cfg.upnp.name} + + [precomputation] + elgamal = ${toYesNo cfg.precomputation.elgamal} + + [reseed] + verify = ${toYesNo cfg.reseed.verify} + file = ${cfg.reseed.file} + urls = ${builtins.concatStringsSep "," cfg.reseed.urls} + + [addressbook] + defaulturl = ${cfg.addressbook.defaulturl} + subscriptions = ${builtins.concatStringsSep "," cfg.addressbook.subscriptions} + ${flip concatMapStrings + (collect (proto: proto ? port && proto ? address && proto ? name) cfg.proto) + (proto: let portStr = toString proto.port; in + '' + [${proto.name}] + enabled = ${toYesNo proto.enable} + address = ${proto.address} + port = ${toString proto.port} + ${if proto ? keys then "keys = ${proto.keys}" else ""} + ${if proto ? auth then "auth = ${toYesNo proto.auth}" else ""} + ${if proto ? user then "user = ${proto.user}" else ""} + ${if proto ? pass then "pass = ${proto.pass}" else ""} + ${if proto ? outproxy then "outproxy = ${proto.outproxy}" else ""} + ${if proto ? outproxyPort then "outproxyport = ${toString proto.outproxyPort}" else ""} + '') } ''; @@ -114,7 +155,7 @@ let i2pdSh = pkgs.writeScriptBin "i2pd" '' #!/bin/sh ${if isNull cfg.extIp then extip else ""} - ${pkgs.i2pd}/bin/i2pd --log=1 \ + ${pkgs.i2pd}/bin/i2pd \ --host=${if isNull cfg.extIp then "$EXTIP" else cfg.extIp} \ --conf=${i2pdConf} \ --tunconf=${i2pdTunnelConf} @@ -135,6 +176,8 @@ in default = false; description = '' Enables I2Pd as a running service upon activation. + Please read http://i2pd.readthedocs.io/en/latest/ for further + configuration help. ''; }; @@ -162,6 +205,22 @@ in ''; }; + netid = mkOption { + type = types.int; + default = 2; + description = '' + I2P overlay netid. + ''; + }; + + bandwidth = mkOption { + type = with types; nullOr int; + default = null; + description = '' + Set a router bandwidth limit integer in kbps or letters: L (32), O (256), P (2048), X (>9000) + ''; + }; + port = mkOption { type = with types; nullOr int; default = null; @@ -170,6 +229,14 @@ in ''; }; + enableIPv4 = mkOption { + type = types.bool; + default = true; + description = '' + Enables IPv4 connectivity. Enabled by default. + ''; + }; + enableIPv6 = mkOption { type = types.bool; default = false; @@ -178,16 +245,141 @@ in ''; }; - proto.http = mkEndpointOpt "http" "127.0.0.1" 7070; + upnp = { + enable = mkOption { + type = types.bool; + default = false; + description = '' + Enables UPnP. + ''; + }; + + name = mkOption { + type = types.str; + default = "I2Pd"; + description = '' + Name i2pd appears in UPnP forwardings list. + ''; + }; + }; + + precomputation.elgamal = mkOption { + type = types.bool; + default = false; + description = '' + Use ElGamal precomputated tables. + ''; + }; + + reseed = { + verify = mkOption { + type = types.bool; + default = false; + description = '' + Request SU3 signature verification + ''; + }; + + file = mkOption { + type = types.str; + default = ""; + description = '' + Full path to SU3 file to reseed from + ''; + }; + + urls = mkOption { + type = with types; listOf str; + default = [ + "https://reseed.i2p-project.de/" + "https://i2p.mooo.com/netDb/" + "https://netdb.i2p2.no/" + "https://us.reseed.i2p2.no:444/" + "https://uk.reseed.i2p2.no:444/" + "https://i2p.manas.ca:8443/" + ]; + description = '' + Reseed URLs + ''; + }; + }; + + addressbook = { + defaulturl = mkOption { + type = types.str; + default = "http://joajgazyztfssty4w2on5oaqksz6tqoxbduy553y34mf4byv6gpq.b32.i2p/export/alive-hosts.txt"; + description = '' + AddressBook subscription URL for initial setup + ''; + }; + subscriptions = mkOption { + type = with types; listOf str; + default = [ + "http://inr.i2p/export/alive-hosts.txt" + "http://i2p-projekt.i2p/hosts.txt" + "http://stats.i2p/cgi-bin/newhosts.txt" + ]; + description = '' + AddressBook subscription URLs + ''; + }; + }; + + limits.transittunnels = mkOption { + type = types.int; + default = 2500; + description = '' + Maximum number of active transit sessions + ''; + }; + + proto.http = (mkEndpointOpt "http" "127.0.0.1" 7070) // { + auth = mkOption { + type = types.bool; + default = false; + description = '' + Enable authentication for webconsole. + ''; + }; + user = mkOption { + type = types.str; + default = "i2pd"; + description = '' + Username for webconsole access + ''; + }; + pass = mkOption { + type = types.str; + default = "i2pd"; + description = '' + Password for webconsole access. + ''; + }; + }; + + proto.httpProxy = mkKeyedEndpointOpt "httpproxy" "127.0.0.1" 4446 ""; + proto.socksProxy = (mkKeyedEndpointOpt "socksproxy" "127.0.0.1" 4447 "") + // { + outproxy = mkOption { + type = types.str; + default = "127.0.0.1"; + description = "Upstream outproxy bind address."; + }; + outproxyPort = mkOption { + type = types.int; + default = 4444; + description = "Upstream outproxy bind port."; + }; + }; + proto.sam = mkEndpointOpt "sam" "127.0.0.1" 7656; proto.bob = mkEndpointOpt "bob" "127.0.0.1" 2827; + proto.i2cp = mkEndpointOpt "i2cp" "127.0.0.1" 7654; proto.i2pControl = mkEndpointOpt "i2pcontrol" "127.0.0.1" 7650; - proto.httpProxy = mkEndpointOpt "httpproxy" "127.0.0.1" 4446; - proto.socksProxy = mkEndpointOpt "socksproxy" "127.0.0.1" 4447; outTunnels = mkOption { default = {}; - type = with types; loaOf (submodule ( + type = with types; loaOf (submodule ( { name, config, ... }: { options = commonTunOpts name; config = { diff --git a/nixos/modules/services/networking/nntp-proxy.nix b/nixos/modules/services/networking/nntp-proxy.nix index dca8ccac7627..7eebecb23b00 100644 --- a/nixos/modules/services/networking/nntp-proxy.nix +++ b/nixos/modules/services/networking/nntp-proxy.nix @@ -148,11 +148,11 @@ in }; verbosity = mkOption { - type = types.str; + type = types.enum [ "error" "warning" "notice" "info" "debug" ]; default = "info"; example = "error"; description = '' - Verbosity level (error, warning, notice, info, debug) + Verbosity level ''; }; diff --git a/nixos/modules/services/networking/nsd.nix b/nixos/modules/services/networking/nsd.nix index 6af1dd736431..481e267f6c38 100644 --- a/nixos/modules/services/networking/nsd.nix +++ b/nixos/modules/services/networking/nsd.nix @@ -118,8 +118,8 @@ let ''; yesOrNo = b: if b then "yes" else "no"; - maybeString = prefix: x: if x == null then "" else ''${prefix} "${s}"''; - maybeToString = prefix: x: if x == null then "" else ''${prefix} ${toString s}''; + maybeString = prefix: x: if x == null then "" else ''${prefix} "${x}"''; + maybeToString = prefix: x: if x == null then "" else ''${prefix} ${toString x}''; forEach = pre: l: concatMapStrings (x: pre + x + "\n") l; @@ -345,12 +345,10 @@ let }; rrlWhitelist = mkOption { - type = types.listOf types.str; + type = with types; listOf (enum [ "nxdomain" "error" "referral" "any" "rrsig" "wildcard" "nodata" "dnskey" "positive" "all" ]); default = []; description = '' Whitelists the given rrl-types. - The RRL classification types are: nxdomain, error, referral, any, - rrsig, wildcard, nodata, dnskey, positive, all ''; }; diff --git a/nixos/modules/services/networking/quassel.nix b/nixos/modules/services/networking/quassel.nix index 99269c49e8f1..3f0906fdb80d 100644 --- a/nixos/modules/services/networking/quassel.nix +++ b/nixos/modules/services/networking/quassel.nix @@ -3,8 +3,8 @@ with lib; let - quassel = pkgs.kde4.quasselDaemon; cfg = config.services.quassel; + quassel = cfg.package; user = if cfg.user != null then cfg.user else "quassel"; in @@ -23,6 +23,15 @@ in ''; }; + package = mkOption { + type = types.package; + default = pkgs.kde4.quasselDaemon; + description = '' + The package of the quassel daemon. + ''; + example = pkgs.quasselDaemon; + }; + interfaces = mkOption { default = [ "127.0.0.1" ]; description = '' diff --git a/nixos/modules/services/networking/skydns.nix b/nixos/modules/services/networking/skydns.nix index ba913482e3cb..6ad18bb22403 100644 --- a/nixos/modules/services/networking/skydns.nix +++ b/nixos/modules/services/networking/skydns.nix @@ -11,7 +11,7 @@ in { etcd = { machines = mkOption { - default = [ "http://localhost:4001" ]; + default = [ "http://127.0.0.1:2379" ]; type = types.listOf types.str; description = "Skydns list of etcd endpoints to connect to."; }; diff --git a/nixos/modules/services/networking/smokeping.nix b/nixos/modules/services/networking/smokeping.nix index 6084dbdbf78f..005655f111a1 100644 --- a/nixos/modules/services/networking/smokeping.nix +++ b/nixos/modules/services/networking/smokeping.nix @@ -221,7 +221,7 @@ in type = types.string; default = '' + FPing - binary = ${pkgs.fping}/bin/fping + binary = ${config.security.wrapperDir}/fping ''; description = "Probe configuration"; }; diff --git a/nixos/modules/services/networking/tinc.nix b/nixos/modules/services/networking/tinc.nix index b26d30597b1f..f8e68fda7fc2 100644 --- a/nixos/modules/services/networking/tinc.nix +++ b/nixos/modules/services/networking/tinc.nix @@ -68,7 +68,7 @@ in interfaceType = mkOption { default = "tun"; - type = types.addCheck types.str (n: n == "tun" || n == "tap"); + type = types.enum [ "tun" "tap" ]; description = '' The type of virtual interface used for the network connection ''; diff --git a/nixos/modules/services/search/hound.nix b/nixos/modules/services/search/hound.nix index 708f57a5eb7c..1226cba682ec 100644 --- a/nixos/modules/services/search/hound.nix +++ b/nixos/modules/services/search/hound.nix @@ -116,7 +116,7 @@ in { " -conf ${pkgs.writeText "hound.json" cfg.config}"; }; - path = [ pkgs.git ]; + path = [ pkgs.git pkgs.mercurial pkgs.openssh ]; }; }; diff --git a/nixos/modules/services/security/clamav.nix b/nixos/modules/services/security/clamav.nix index e4e5c1253b77..b045e140546d 100644 --- a/nixos/modules/services/security/clamav.nix +++ b/nixos/modules/services/security/clamav.nix @@ -3,26 +3,37 @@ with lib; let clamavUser = "clamav"; stateDir = "/var/lib/clamav"; - runDir = "/var/run/clamav"; - logDir = "/var/log/clamav"; + runDir = "/run/clamav"; clamavGroup = clamavUser; cfg = config.services.clamav; + pkg = pkgs.clamav; + clamdConfigFile = pkgs.writeText "clamd.conf" '' DatabaseDirectory ${stateDir} LocalSocket ${runDir}/clamd.ctl - LogFile ${logDir}/clamav.log PidFile ${runDir}/clamd.pid + TemporaryDirectory /tmp User clamav + Foreground yes ${cfg.daemon.extraConfig} ''; - pkg = pkgs.clamav.override { freshclamConf = cfg.updater.config; }; + + freshclamConfigFile = pkgs.writeText "freshclam.conf" '' + DatabaseDirectory ${stateDir} + Foreground yes + Checks ${toString cfg.updater.frequency} + + ${cfg.updater.extraConfig} + + DatabaseMirror database.clamav.net + ''; in { options = { services.clamav = { daemon = { - enable = mkEnableOption "clamd daemon"; + enable = mkEnableOption "ClamAV clamd daemon"; extraConfig = mkOption { type = types.lines; @@ -34,16 +45,27 @@ in }; }; updater = { - enable = mkEnableOption "freshclam updater"; + enable = mkEnableOption "ClamAV freshclam updater"; frequency = mkOption { + type = types.int; default = 12; description = '' Number of database checks per day. ''; }; - config = mkOption { + interval = mkOption { + type = types.str; + default = "hourly"; + description = '' + How often freshclam is invoked. See systemd.time(7) for more + information about the format. + ''; + }; + + extraConfig = mkOption { + type = types.lines; default = ""; description = '' Extra configuration for freshclam. Contents will be added verbatim to the @@ -68,50 +90,53 @@ in gid = config.ids.gids.clamav; }; - services.clamav.updater.config = mkIf cfg.updater.enable '' - DatabaseDirectory ${stateDir} - Foreground yes - Checks ${toString cfg.updater.frequency} - DatabaseMirror database.clamav.net - ''; + environment.etc."clamav/freshclam.conf".source = freshclamConfigFile; + environment.etc."clamav/clamd.conf".source = clamdConfigFile; - systemd.services.clamd = mkIf cfg.daemon.enable { + systemd.services.clamav-daemon = mkIf cfg.daemon.enable { description = "ClamAV daemon (clamd)"; - path = [ pkg ]; - after = [ "network.target" "freshclam.service" ]; - requires = [ "freshclam.service" ]; + after = mkIf cfg.updater.enable [ "clamav-freshclam.service" ]; + requires = mkIf cfg.updater.enable [ "clamav-freshclam.service" ]; wantedBy = [ "multi-user.target" ]; + restartTriggers = [ clamdConfigFile ]; + preStart = '' - mkdir -m 0755 -p ${logDir} mkdir -m 0755 -p ${runDir} - chown ${clamavUser}:${clamavGroup} ${logDir} chown ${clamavUser}:${clamavGroup} ${runDir} ''; + serviceConfig = { - ExecStart = "${pkg}/bin/clamd --config-file=${clamdConfigFile}"; - Type = "forking"; - ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID"; - Restart = "on-failure"; - RestartSec = "10s"; - StartLimitInterval = "1min"; + ExecStart = "${pkg}/bin/clamd"; + ExecReload = "${pkgs.coreutils}/bin/kill -USR2 $MAINPID"; + PrivateTmp = "yes"; + PrivateDevices = "yes"; + PrivateNetwork = "yes"; }; }; - systemd.services.freshclam = mkIf cfg.updater.enable { - description = "ClamAV updater (freshclam)"; - after = [ "network.target" ]; - wantedBy = [ "multi-user.target" ]; - path = [ pkg ]; + systemd.timers.clamav-freshclam = mkIf cfg.updater.enable { + description = "Timer for ClamAV virus database updater (freshclam)"; + wantedBy = [ "timers.target" ]; + timerConfig = { + OnCalendar = cfg.updater.interval; + Unit = "clamav-freshclam.service"; + }; + }; + + systemd.services.clamav-freshclam = mkIf cfg.updater.enable { + description = "ClamAV virus database updater (freshclam)"; + restartTriggers = [ freshclamConfigFile ]; + preStart = '' mkdir -m 0755 -p ${stateDir} chown ${clamavUser}:${clamavGroup} ${stateDir} ''; + serviceConfig = { - ExecStart = "${pkg}/bin/freshclam --daemon --config-file=${pkgs.writeText "freshclam.conf" cfg.updater.config}"; - ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID"; - Restart = "on-failure"; - RestartSec = "10s"; - StartLimitInterval = "1min"; + Type = "oneshot"; + ExecStart = "${pkg}/bin/freshclam"; + PrivateTmp = "yes"; + PrivateDevices = "yes"; }; }; }; diff --git a/nixos/modules/services/web-servers/fcgiwrap.nix b/nixos/modules/services/web-servers/fcgiwrap.nix index 2c5e433003c8..a64a187255a4 100644 --- a/nixos/modules/services/web-servers/fcgiwrap.nix +++ b/nixos/modules/services/web-servers/fcgiwrap.nix @@ -21,7 +21,7 @@ in { }; socketType = mkOption { - type = types.addCheck types.str (t: t == "unix" || t == "tcp" || t == "tcp6"); + type = types.enum [ "unix" "tcp" "tcp6" ]; default = "unix"; description = "Socket type: 'unix', 'tcp' or 'tcp6'."; }; diff --git a/nixos/modules/services/web-servers/nginx/default.nix b/nixos/modules/services/web-servers/nginx/default.nix index 166e5a6b2cea..698d37133d74 100644 --- a/nixos/modules/services/web-servers/nginx/default.nix +++ b/nixos/modules/services/web-servers/nginx/default.nix @@ -138,7 +138,7 @@ let server_name ${serverName} ${concatStringsSep " " vhost.serverAliases}; ${acmeLocation} location / { - return 301 https://$host${optionalString (port != 443) ":${port}"}$request_uri; + return 301 https://$host${optionalString (port != 443) ":${toString port}"}$request_uri; } } ''} diff --git a/nixos/modules/services/x11/desktop-managers/default.nix b/nixos/modules/services/x11/desktop-managers/default.nix index 31412ae70142..144e4aada277 100644 --- a/nixos/modules/services/x11/desktop-managers/default.nix +++ b/nixos/modules/services/x11/desktop-managers/default.nix @@ -19,7 +19,8 @@ in # E.g., if KDE is enabled, it supersedes xterm. imports = [ ./none.nix ./xterm.nix ./xfce.nix ./kde4.nix ./kde5.nix - ./lxqt.nix ./enlightenment.nix ./gnome3.nix ./kodi.nix + ./lumina.nix ./lxqt.nix ./enlightenment.nix ./gnome3.nix + ./kodi.nix ]; options = { diff --git a/nixos/modules/services/x11/desktop-managers/kde5.nix b/nixos/modules/services/x11/desktop-managers/kde5.nix index bc010d1ce1cf..9b51b92faa4d 100644 --- a/nixos/modules/services/x11/desktop-managers/kde5.nix +++ b/nixos/modules/services/x11/desktop-managers/kde5.nix @@ -22,6 +22,15 @@ in 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. + ''; + }; + }; }; @@ -105,7 +114,7 @@ in kde5.sonnet kde5.threadweaver - kde5.breeze + kde5.breeze-qt5 kde5.kactivitymanagerd kde5.kde-cli-tools kde5.kdecoration @@ -141,13 +150,12 @@ in kde5.konsole kde5.print-manager - # Oxygen icons moved to KDE Frameworks 5.16 and later. - (kde5.oxygen-icons or kde5.oxygen-icons5) + # 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.kde-gtk-config kde5.breeze-gtk - pkgs.phonon-backend-gstreamer pkgs.qt5.phonon-backend-gstreamer ] @@ -155,15 +163,14 @@ in # If it is not available, Orion is very similar to Breeze. ++ lib.optional (!(lib.hasAttr "breeze-gtk" kde5)) pkgs.orion - # Install Breeze icons if available - ++ lib.optional (lib.hasAttr "breeze-icons" kde5) kde5.breeze-icons - # 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 @@ -217,7 +224,6 @@ in kde5.ecm # for the setup-hook kde5.plasma-workspace kde5.breeze-icons - (kde5.oxygen-icons or kde5.oxygen-icons5) ]; }; diff --git a/nixos/modules/services/x11/desktop-managers/lumina.nix b/nixos/modules/services/x11/desktop-managers/lumina.nix new file mode 100644 index 000000000000..f0b31a2acb01 --- /dev/null +++ b/nixos/modules/services/x11/desktop-managers/lumina.nix @@ -0,0 +1,52 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + + xcfg = config.services.xserver; + cfg = xcfg.desktopManager.lumina; + +in + +{ + options = { + + services.xserver.desktopManager.lumina.enable = mkOption { + type = types.bool; + default = false; + description = "Enable the Lumina desktop manager"; + }; + + }; + + + config = mkIf (xcfg.enable && cfg.enable) { + + services.xserver.desktopManager.session = singleton { + name = "lumina"; + start = '' + exec ${pkgs.lumina}/bin/start-lumina-desktop + ''; + }; + + environment.systemPackages = [ + pkgs.fluxbox + pkgs.kde5.kwindowsystem + pkgs.kde5.oxygen-icons5 + pkgs.lumina + pkgs.numlockx + pkgs.qt5.qtsvg + pkgs.xscreensaver + ]; + + # Link some extra directories in /run/current-system/software/share + environment.pathsToLink = [ + "/share/desktop-directories" + "/share/icons" + "/share/lumina" + "/share" + ]; + + }; +} diff --git a/nixos/modules/services/x11/desktop-managers/lxqt.nix b/nixos/modules/services/x11/desktop-managers/lxqt.nix index d13b7352c95e..c385e74dbb2f 100644 --- a/nixos/modules/services/x11/desktop-managers/lxqt.nix +++ b/nixos/modules/services/x11/desktop-managers/lxqt.nix @@ -25,6 +25,7 @@ in services.xserver.desktopManager.session = singleton { name = "lxqt"; + bgSupport = true; start = '' exec ${pkgs.lxqt.lxqt-common}/bin/startlxqt ''; diff --git a/nixos/modules/services/x11/display-managers/sddm.nix b/nixos/modules/services/x11/display-managers/sddm.nix index 36daf55a36a5..dda8d0f7629e 100644 --- a/nixos/modules/services/x11/display-managers/sddm.nix +++ b/nixos/modules/services/x11/display-managers/sddm.nix @@ -27,7 +27,6 @@ let ${cfg.stopScript} ''; - cfgFile = pkgs.writeText "sddm.conf" '' [General] HaltCommand=${pkgs.systemd}/bin/systemctl poweroff @@ -47,7 +46,7 @@ let HideShells=/run/current-system/sw/bin/nologin [X11] - MinimumVT=${toString xcfg.tty} + MinimumVT=${toString (if xcfg.tty != null then xcfg.tty else 7)} ServerPath=${xserverWrapper} XephyrPath=${pkgs.xorg.xorgserver.out}/bin/Xephyr SessionCommand=${dmcfg.session.script} @@ -254,5 +253,10 @@ in users.extraGroups.sddm.gid = config.ids.gids.sddm; + services.dbus.packages = [ sddm.unwrapped ]; + + # To enable user switching, allow sddm to allocate TTYs/displays dynamically. + services.xserver.tty = null; + services.xserver.display = null; }; } diff --git a/nixos/modules/services/x11/window-managers/bspwm-unstable.nix b/nixos/modules/services/x11/window-managers/bspwm-unstable.nix deleted file mode 100644 index 3282e0d0851f..000000000000 --- a/nixos/modules/services/x11/window-managers/bspwm-unstable.nix +++ /dev/null @@ -1,48 +0,0 @@ -{ config, lib, pkgs, ... }: - -with lib; - -let - cfg = config.services.xserver.windowManager.bspwm-unstable; -in - -{ - options = { - services.xserver.windowManager.bspwm-unstable = { - enable = mkEnableOption "bspwm-unstable"; - startThroughSession = mkOption { - type = with types; bool; - default = false; - description = " - Start the window manager through the script defined in - sessionScript. Defaults to the the bspwm-session script - provided by bspwm - "; - }; - sessionScript = mkOption { - default = "${pkgs.bspwm-unstable}/bin/bspwm-session"; - defaultText = "(pkgs.bspwm-unstable)/bin/bspwm-session"; - description = " - The start-session script to use. Defaults to the - provided bspwm-session script from the bspwm package. - - Does nothing unless `bspwm.startThroughSession` is enabled - "; - }; - }; - }; - - config = mkIf cfg.enable { - services.xserver.windowManager.session = singleton { - name = "bspwm-unstable"; - start = if cfg.startThroughSession - then cfg.sessionScript - else '' - export _JAVA_AWT_WM_NONREPARENTING=1 - SXHKD_SHELL=/bin/sh ${pkgs.sxhkd-unstable}/bin/sxhkd -f 100 & - ${pkgs.bspwm-unstable}/bin/bspwm - ''; - }; - environment.systemPackages = [ pkgs.bspwm-unstable ]; - }; -} diff --git a/nixos/modules/services/x11/window-managers/bspwm.nix b/nixos/modules/services/x11/window-managers/bspwm.nix index 03a1b7a72e88..6783ac3479e6 100644 --- a/nixos/modules/services/x11/window-managers/bspwm.nix +++ b/nixos/modules/services/x11/window-managers/bspwm.nix @@ -9,40 +9,69 @@ in { options = { services.xserver.windowManager.bspwm = { - enable = mkEnableOption "bspwm"; - startThroughSession = mkOption { - type = with types; bool; - default = false; - description = " - Start the window manager through the script defined in - sessionScript. Defaults to the the bspwm-session script - provided by bspwm - "; - }; - sessionScript = mkOption { - default = "${pkgs.bspwm}/bin/bspwm-session"; - defaultText = "(pkgs.bspwm)/bin/bspwm-session"; - description = " - The start-session script to use. Defaults to the - provided bspwm-session script from the bspwm package. + enable = mkEnableOption "bspwm"; + + package = mkOption { + type = types.package; + default = pkgs.bspwm; + defaultText = "pkgs.bspwm"; + example = "pkgs.bspwm-unstable"; + description = '' + bspwm package to use. + ''; + }; + configFile = mkOption { + type = with types; nullOr path; + example = "${pkgs.bspwm}/share/doc/bspwm/examples/bspwmrc"; + default = null; + description = '' + Path to the bspwm configuration file. + If null, $HOME/.config/bspwm/bspwmrc will be used. + ''; + }; - Does nothing unless `bspwm.startThroughSession` is enabled - "; + sxhkd = { + package = mkOption { + type = types.package; + default = pkgs.sxhkd; + defaultText = "pkgs.sxhkd"; + example = "pkgs.sxhkd-unstable"; + description = '' + sxhkd package to use. + ''; }; + configFile = mkOption { + type = with types; nullOr path; + example = "${pkgs.bspwm}/share/doc/bspwm/examples/sxhkdrc"; + default = null; + description = '' + Path to the sxhkd configuration file. + If null, $HOME/.config/sxhkd/sxhkdrc will be used. + ''; + }; + }; }; }; config = mkIf cfg.enable { services.xserver.windowManager.session = singleton { - name = "bspwm"; - start = if cfg.startThroughSession - then cfg.sessionScript - else '' - export _JAVA_AWT_WM_NONREPARENTING=1 - SXHKD_SHELL=/bin/sh ${pkgs.sxhkd}/bin/sxhkd -f 100 & - ${pkgs.bspwm}/bin/bspwm - ''; + name = "bspwm"; + start = '' + export _JAVA_AWT_WM_NONREPARENTING=1 + SXHKD_SHELL=/bin/sh ${cfg.sxhkd.package}/bin/sxhkd ${optionalString (cfg.sxhkd.configFile != null) "-c \"${cfg.sxhkd.configFile}\""} & + ${cfg.package}/bin/bspwm ${optionalString (cfg.configFile != null) "-c \"${cfg.configFile}\""} + waitPID=$! + ''; }; - environment.systemPackages = [ pkgs.bspwm ]; + environment.systemPackages = [ cfg.package ]; }; + + imports = [ + (mkRemovedOptionModule [ "services" "xserver" "windowManager" "bspwm-unstable" "enable" ] + "Use services.xserver.windowManager.bspwm.enable and set services.xserver.windowManager.bspwm.package to pkgs.bspwm-unstable to use the unstable version of bspwm.") + (mkRemovedOptionModule [ "services" "xserver" "windowManager" "bspwm" "startThroughSession" ] + "bspwm package does not provide bspwm-session anymore.") + (mkRemovedOptionModule [ "services" "xserver" "windowManager" "bspwm" "sessionScript" ] + "bspwm package does not provide bspwm-session anymore.") + ]; } diff --git a/nixos/modules/services/x11/window-managers/default.nix b/nixos/modules/services/x11/window-managers/default.nix index dabe2c26a72f..f005decfa33c 100644 --- a/nixos/modules/services/x11/window-managers/default.nix +++ b/nixos/modules/services/x11/window-managers/default.nix @@ -10,7 +10,6 @@ in imports = [ ./afterstep.nix ./bspwm.nix - ./bspwm-unstable.nix ./compiz.nix ./dwm.nix ./exwm.nix diff --git a/nixos/modules/system/boot/initrd-ssh.nix b/nixos/modules/system/boot/initrd-ssh.nix index a8c7d4b3ee5e..59ecaf8d5a6d 100644 --- a/nixos/modules/system/boot/initrd-ssh.nix +++ b/nixos/modules/system/boot/initrd-ssh.nix @@ -122,7 +122,7 @@ in mkdir -p /root/.ssh ${concatStrings (map (key: '' - echo -n ${escapeShellArg key} >> /root/.ssh/authorized_keys + echo ${escapeShellArg key} >> /root/.ssh/authorized_keys '') cfg.authorizedKeys)} dropbear -s -j -k -E -m -p ${toString cfg.port} diff --git a/nixos/modules/system/boot/loader/grub/grub.nix b/nixos/modules/system/boot/loader/grub/grub.nix index 588e54a9d3a0..294fc1988e9f 100644 --- a/nixos/modules/system/boot/loader/grub/grub.nix +++ b/nixos/modules/system/boot/loader/grub/grub.nix @@ -324,8 +324,7 @@ in fsIdentifier = mkOption { default = "uuid"; - type = types.addCheck types.str - (type: type == "uuid" || type == "label" || type == "provided"); + type = types.enum [ "uuid" "label" "provided" ]; description = '' Determines how GRUB will identify devices when generating the configuration file. A value of uuid / label signifies that grub diff --git a/nixos/modules/system/boot/loader/raspberrypi/raspberrypi.nix b/nixos/modules/system/boot/loader/raspberrypi/raspberrypi.nix index b7400e333e21..eb8ea6130972 100644 --- a/nixos/modules/system/boot/loader/raspberrypi/raspberrypi.nix +++ b/nixos/modules/system/boot/loader/raspberrypi/raspberrypi.nix @@ -33,7 +33,7 @@ in boot.loader.raspberryPi.version = mkOption { default = 2; - type = types.int; + type = types.enum [ 1 2 ]; description = '' ''; }; @@ -44,10 +44,5 @@ in system.build.installBootLoader = builder; system.boot.loader.id = "raspberrypi"; system.boot.loader.kernelFile = platform.kernelTarget; - assertions = [ - { assertion = (cfg.version == 1 || cfg.version == 2); - message = "loader.raspberryPi.version should be 1 or 2"; - } - ]; }; } diff --git a/nixos/modules/tasks/network-interfaces.nix b/nixos/modules/tasks/network-interfaces.nix index aae4dc5fdadf..aaa78daeb3a3 100644 --- a/nixos/modules/tasks/network-interfaces.nix +++ b/nixos/modules/tasks/network-interfaces.nix @@ -245,7 +245,7 @@ let virtualType = mkOption { default = null; - type = types.nullOr (types.addCheck types.str (v: v == "tun" || v == "tap")); + type = with types; nullOr (enum [ "tun" "tap" ]); description = '' The explicit type of interface to create. Accepts tun or tap strings. Also accepts null to implicitly detect the type of device. @@ -782,13 +782,12 @@ in }; type = mkOption { - type = types.string; + type = types.enum [ "managed" "ibss" "monitor" "mesh" "wds" ]; default = "managed"; example = "ibss"; description = '' - The type of the WLAN interface. The type has to be either <literal>managed</literal>, - <literal>ibss</literal>, <literal>monitor</literal>, <literal>mesh</literal> or <literal>wds</literal>. - Also, the type has to be supported by the underlying hardware of the device. + The type of the WLAN interface. + The type has to be supported by the underlying hardware of the device. ''; }; @@ -799,17 +798,11 @@ in }; flags = mkOption { - type = types.nullOr types.string; + type = with types; nullOr (enum [ "none" "fcsfail" "control" "otherbss" "cook" "active" ]); default = null; example = "control"; description = '' - Flags for interface of type <literal>monitor</literal>. The valid flags are: - none: no special flags - fcsfail: show frames with FCS errors - control: show control frames - otherbss: show frames from other BSSes - cook: use cooked mode - active: use active mode (ACK incoming unicast packets) + Flags for interface of type <literal>monitor</literal>. ''; }; diff --git a/nixos/modules/virtualisation/grow-partition.nix b/nixos/modules/virtualisation/grow-partition.nix index abc2e766959e..5039118d78ee 100644 --- a/nixos/modules/virtualisation/grow-partition.nix +++ b/nixos/modules/virtualisation/grow-partition.nix @@ -24,7 +24,7 @@ with lib; copy_bin_and_libs ${pkgs.gnused}/bin/sed copy_bin_and_libs ${pkgs.utillinux}/sbin/sfdisk copy_bin_and_libs ${pkgs.utillinux}/sbin/lsblk - cp -v ${pkgs.cloud-utils}/bin/growpart $out/bin/growpart + cp -v ${pkgs.cloud-utils}/bin/.growpart-wrapped $out/bin/growpart ln -s sed $out/bin/gnused ''; diff --git a/nixos/modules/virtualisation/libvirtd.nix b/nixos/modules/virtualisation/libvirtd.nix index ea503a9526f8..5f669dee7545 100644 --- a/nixos/modules/virtualisation/libvirtd.nix +++ b/nixos/modules/virtualisation/libvirtd.nix @@ -123,7 +123,7 @@ in { # config file. But this path can unfortunately be garbage collected # while still being used by the virtual machine. So update the # emulator path on each startup to something valid (re-scan $PATH). - for file in /etc/libvirt/qemu/*.xml /etc/libvirt/lxc/*.xml; do + for file in /var/lib/libvirt/qemu/*.xml /var/lib/libvirt/lxc/*.xml; do test -f "$file" || continue # get (old) emulator path from config file emulator=$(grep "^[[:space:]]*<emulator>" "$file" | sed 's,^[[:space:]]*<emulator>\(.*\)</emulator>.*,\1,') diff --git a/nixos/modules/virtualisation/vmware-guest.nix b/nixos/modules/virtualisation/vmware-guest.nix index b9a4f3b11dc1..ac5f87817fe9 100644 --- a/nixos/modules/virtualisation/vmware-guest.nix +++ b/nixos/modules/virtualisation/vmware-guest.nix @@ -5,6 +5,7 @@ with lib; let cfg = config.services.vmwareGuest; open-vm-tools = pkgs.open-vm-tools; + xf86inputvmmouse = pkgs.xorg.xf86inputvmmouse; in { options = { @@ -29,18 +30,17 @@ in services.xserver = { videoDrivers = mkOverride 50 [ "vmware" ]; + modules = [ xf86inputvmmouse ]; config = '' - Section "InputDevice" + Section "InputClass" Identifier "VMMouse" + MatchDevicePath "/dev/input/event*" + MatchProduct "ImPS/2 Generic Wheel Mouse" Driver "vmmouse" EndSection ''; - serverLayoutSection = '' - InputDevice "VMMouse" - ''; - displayManager.sessionCommands = '' ${open-vm-tools}/bin/vmware-user-suid-wrapper ''; diff --git a/nixos/release.nix b/nixos/release.nix index fbd3efd16ff0..639ee45b38d6 100644 --- a/nixos/release.nix +++ b/nixos/release.nix @@ -275,6 +275,7 @@ in rec { tests.networkingProxy = callTest tests/networking-proxy.nix {}; tests.nfs3 = callTest tests/nfs.nix { version = 3; }; tests.nfs4 = callTest tests/nfs.nix { version = 4; }; + tests.leaps = callTest tests/leaps.nix { }; tests.nsd = callTest tests/nsd.nix {}; tests.openssh = callTest tests/openssh.nix {}; #tests.panamax = hydraJob (import tests/panamax.nix { system = "x86_64-linux"; }); diff --git a/nixos/tests/chromium.nix b/nixos/tests/chromium.nix index 9a6414f81c39..55b1fb5a7222 100644 --- a/nixos/tests/chromium.nix +++ b/nixos/tests/chromium.nix @@ -118,7 +118,7 @@ mapAttrs (channel: chromiumPkg: makeTest rec { "ulimit -c unlimited; ". "chromium $args \"$url\" & disown" ); - $machine->waitForText(qr/Type to search or enter a URL to navigate/); + $machine->waitForText(qr/startup done/); $machine->waitUntilSucceeds("${xdo "check-startup" '' search --sync --onlyvisible --name "startup done" # close first start help popup diff --git a/nixos/tests/cjdns.nix b/nixos/tests/cjdns.nix index f61c82b916ad..f32ec52dfc26 100644 --- a/nixos/tests/cjdns.nix +++ b/nixos/tests/cjdns.nix @@ -54,7 +54,7 @@ import ./make-test.nix ({ pkgs, ...} : { services.cjdns = { UDPInterface = { bind = "0.0.0.0:1024"; - connectTo."192.168.0.1:1024}" = + connectTo."192.168.0.1:1024" = { password = carolPassword; publicKey = carolPubKey; }; diff --git a/nixos/tests/dnscrypt-proxy.nix b/nixos/tests/dnscrypt-proxy.nix index b686e9582a7d..26409949ec62 100644 --- a/nixos/tests/dnscrypt-proxy.nix +++ b/nixos/tests/dnscrypt-proxy.nix @@ -22,8 +22,6 @@ import ./make-test.nix ({ pkgs, ... }: { }; testScript = '' - $client->start; - $client->waitForUnit("sockets.target"); $client->waitForUnit("dnsmasq"); # The daemon is socket activated; sending a single ping should activate it. diff --git a/nixos/tests/leaps.nix b/nixos/tests/leaps.nix new file mode 100644 index 000000000000..3c390e1a1691 --- /dev/null +++ b/nixos/tests/leaps.nix @@ -0,0 +1,29 @@ +import ./make-test.nix ({ pkgs, ... }: + +{ + name = "leaps"; + meta = with pkgs.stdenv.lib.maintainers; { + maintainers = [ qknight ]; + }; + + nodes = + { + client = { }; + + server = + { services.leaps = { + enable = true; + port = 6666; + path = "/leaps/"; + }; + networking.firewall.enable = false; + }; + }; + + testScript = + '' + startAll; + $server->waitForOpenPort(6666); + $client->succeed("curl http://server:6666/leaps/ | grep -i 'leaps'"); + ''; +}) |