diff options
Diffstat (limited to 'nixos')
72 files changed, 1151 insertions, 340 deletions
diff --git a/nixos/doc/manual/configuration/wireless.xml b/nixos/doc/manual/configuration/wireless.xml index f7e99ff0e35..dda2193dd93 100644 --- a/nixos/doc/manual/configuration/wireless.xml +++ b/nixos/doc/manual/configuration/wireless.xml @@ -36,8 +36,25 @@ </para> <para> - If you are using WPA2 the <command>wpa_passphrase</command> tool might be - useful to generate the <literal>wpa_supplicant.conf</literal>. + If you are using WPA2 you can generate pskRaw key using + <command>wpa_passphrase</command>: +<screen> +$ wpa_passphrase ESSID PSK +network={ + ssid="echelon" + #psk="abcdefgh" + psk=dca6d6ed41f4ab5a984c9f55f6f66d4efdc720ebf66959810f4329bb391c5435 +} +</screen> +<programlisting> +<xref linkend="opt-networking.wireless.networks"/> = { + echelon = { + pskRaw = "dca6d6ed41f4ab5a984c9f55f6f66d4efdc720ebf66959810f4329bb391c5435"; + }; +} +</programlisting> + or you can use it to directly generate the + <literal>wpa_supplicant.conf</literal>: <screen> # wpa_passphrase ESSID PSK > /etc/wpa_supplicant.conf</screen> After you have edited the <literal>wpa_supplicant.conf</literal>, you need to diff --git a/nixos/doc/manual/default.nix b/nixos/doc/manual/default.nix index 02b91773f5d..4e0d486e94c 100644 --- a/nixos/doc/manual/default.nix +++ b/nixos/doc/manual/default.nix @@ -327,6 +327,7 @@ in rec { # Generate manpages. mkdir -p $out/share/man xsltproc --nonet \ + --maxdepth 6000 \ --param man.output.in.separate.dir 1 \ --param man.output.base.dir "'$out/share/man/'" \ --param man.endnotes.are.numbered 0 \ diff --git a/nixos/doc/manual/development/releases.xml b/nixos/doc/manual/development/releases.xml index d4e5ff3f431..dcedad540e1 100755 --- a/nixos/doc/manual/development/releases.xml +++ b/nixos/doc/manual/development/releases.xml @@ -62,13 +62,6 @@ </listitem> <listitem> <para> - <link xlink:href="https://github.com/NixOS/nixpkgs/settings/branches"> - Let a GitHub nixpkgs admin lock the branch on github for you. (so - developers can’t force push) </link> - </para> - </listitem> - <listitem> - <para> <link xlink:href="https://github.com/NixOS/nixpkgs/compare/bdf161ed8d21...6b63c4616790"> Bump the <literal>system.defaultChannel</literal> attribute in <literal>nixos/modules/misc/version.nix</literal> </link> diff --git a/nixos/doc/manual/installation/installing.xml b/nixos/doc/manual/installation/installing.xml index 8e94f946c5e..f4f8d470f80 100644 --- a/nixos/doc/manual/installation/installing.xml +++ b/nixos/doc/manual/installation/installing.xml @@ -378,6 +378,10 @@ the grub menu. </para> <para> + If you need to configure networking for your machine the configuration + options are described in <xref linkend="sec-networking"/>. + </para> + <para> Another critical option is <option>fileSystems</option>, specifying the file systems that need to be mounted by NixOS. However, you typically don’t need to set it yourself, because diff --git a/nixos/doc/manual/man-nixos-rebuild.xml b/nixos/doc/manual/man-nixos-rebuild.xml index b6a247286d4..654b5f4b284 100644 --- a/nixos/doc/manual/man-nixos-rebuild.xml +++ b/nixos/doc/manual/man-nixos-rebuild.xml @@ -39,6 +39,10 @@ </arg> <arg choice='plain'> + <option>edit</option> + </arg> + + <arg choice='plain'> <option>build-vm</option> </arg> @@ -190,6 +194,16 @@ $ nix-build /path/to/nixpkgs/nixos -A system </varlistentry> <varlistentry> <term> + <option>edit</option> + </term> + <listitem> + <para> + Opens <filename>configuration.nix</filename> in the default editor. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term> <option>build-vm</option> </term> <listitem> diff --git a/nixos/doc/manual/release-notes/release-notes.xml b/nixos/doc/manual/release-notes/release-notes.xml index a222bfa29d5..02b59147721 100644 --- a/nixos/doc/manual/release-notes/release-notes.xml +++ b/nixos/doc/manual/release-notes/release-notes.xml @@ -8,6 +8,7 @@ This section lists the release notes for each stable version of NixOS and current unstable revision. </para> + <xi:include href="rl-1909.xml" /> <xi:include href="rl-1903.xml" /> <xi:include href="rl-1809.xml" /> <xi:include href="rl-1803.xml" /> diff --git a/nixos/doc/manual/release-notes/rl-1903.xml b/nixos/doc/manual/release-notes/rl-1903.xml index a8e4807f238..a82724d7fb5 100644 --- a/nixos/doc/manual/release-notes/rl-1903.xml +++ b/nixos/doc/manual/release-notes/rl-1903.xml @@ -106,6 +106,23 @@ </para> </listitem> </itemizedlist> + + <itemizedlist> + <listitem> + <para> + <literal>./security/duosec.nix</literal> + </para> + </listitem> + <listitem> + <para> + The <link xlink:href="https://duo.com/docs/duounix">PAM module for Duo + Security</link> has been enabled for use. One can configure it using + the <option>security.duosec</option> options along with the + corresponding PAM option in + <option>security.pam.services.<name?>.duoSecurity.enable</option>. + </para> + </listitem> + </itemizedlist> </section> <section xmlns="http://docbook.org/ns/docbook" @@ -167,6 +184,20 @@ </listitem> <listitem> <para> + The <varname>buildPythonPackage</varname> function now sets <varname>strictDeps = true</varname> + to help distinguish between native and non-native dependencies in order to + improve cross-compilation compatibility. Note however that this may break + user expressions. + </para> + </listitem> + <listitem> + <para> + The <varname>buildPythonPackage</varname> function now sets <varname>LANG = C.UTF-8</varname> + to enable Unicode support. The <varname>glibcLocales</varname> package is no longer needed as a build input. + </para> + </listitem> + <listitem> + <para> The Syncthing state and configuration data has been moved from <varname>services.syncthing.dataDir</varname> to the newly defined <varname>services.syncthing.configDir</varname>, which default to @@ -425,8 +456,8 @@ </listitem> <listitem> <para> - Support for NixOS module system type <literal>types.optionSet</literal> and - <literal>lib.mkOption</literal> argument <literal>options</literal> is removed. + NixOS module system type <literal>types.optionSet</literal> and + <literal>lib.mkOption</literal> argument <literal>options</literal> are deprecated. Use <literal>types.submodule</literal> instead. (<link xlink:href="https://github.com/NixOS/nixpkgs/pull/54637">#54637</link>) </para> @@ -448,6 +479,11 @@ been removed. </para> </listitem> + <listitem> + <para> + <literal>graylog</literal> has been upgraded from version 2.* to 3.*. Some setups making use of extraConfig (especially those exposing Graylog via reverse proxies) need to be updated as upstream removed/replaced some settings. See <link xlink:href="http://docs.graylog.org/en/3.0/pages/upgrade/graylog-3.0.html#simplified-http-interface-configuration">Upgrading Graylog</link> for details. + </para> + </listitem> </itemizedlist> </section> @@ -541,7 +577,7 @@ but is still possible by setting <literal>zramSwap.swapDevices</literal> explicitly. </para> <para> - Default algorithm for ZRAM swap was changed to <literal>zstd</literal>. + ZRAM algorithm can be changed now. </para> <para> Changes to ZRAM algorithm are applied during <literal>nixos-rebuild switch</literal>, @@ -551,20 +587,6 @@ </listitem> <listitem> <para> - Symlinks in <filename>/etc</filename> (except <filename>/etc/static</filename>) - are now relative instead of absolute. This makes possible to examine - NixOS container's <filename>/etc</filename> directory from host system - (previously it pointed to host <filename>/etc</filename> when viewed from host, - and to container <filename>/etc</filename> when viewed from container chroot). - </para> - <para> - This also makes <filename>/etc/os-release</filename> adhere to - <link xlink:href="https://www.freedesktop.org/software/systemd/man/os-release.html">the standard</link> - for NixOS containers. - </para> - </listitem> - <listitem> - <para> Flat volumes are now disabled by default in <literal>hardware.pulseaudio</literal>. This has been done to prevent applications, which are unaware of this feature, setting their volumes to 100% on startup causing harm to your audio hardware and potentially your ears. @@ -644,6 +666,10 @@ Some OpenCL and VA-API applications might also break (Beignet seems to provide OpenCL support with <literal>modesetting</literal> driver, too). + Kernel mode setting API does not support backlight control, + so <literal>xbacklight</literal> tool will not work; + backlight level can be controlled directly via <literal>/sys/</literal> + or with <literal>brightnessctl</literal>. Users who need this functionality more than multi-output XRandR are advised to add `intel` to `videoDrivers` and report an issue (or provide additional details in an existing one) @@ -655,6 +681,14 @@ This may break some older applications that still rely on those symbols. An upgrade guide can be found <link xlink:href="https://www.open-mpi.org/faq/?category=mpi-removed">here</link>. </para> + <para> + The nginx package now relies on OpenSSL 1.1 and supports TLS 1.3 by default. You can set the protocols used by the nginx service using <xref linkend="opt-services.nginx.sslProtocols"/>. + </para> + </listitem> + <listitem> + <para> + A new subcommand <command>nixos-rebuild edit</command> was added. + </para> </listitem> </itemizedlist> </section> diff --git a/nixos/doc/manual/release-notes/rl-1909.xml b/nixos/doc/manual/release-notes/rl-1909.xml new file mode 100644 index 00000000000..f54592b6bf6 --- /dev/null +++ b/nixos/doc/manual/release-notes/rl-1909.xml @@ -0,0 +1,68 @@ +<section xmlns="http://docbook.org/ns/docbook" + xmlns:xlink="http://www.w3.org/1999/xlink" + xmlns:xi="http://www.w3.org/2001/XInclude" + version="5.0" + xml:id="sec-release-19.09"> + <title>Release 19.09 (“Loris”, 2019/09/??)</title> + + <section xmlns="http://docbook.org/ns/docbook" + xmlns:xlink="http://www.w3.org/1999/xlink" + xmlns:xi="http://www.w3.org/2001/XInclude" + version="5.0" + xml:id="sec-release-19.09-highlights"> + <title>Highlights</title> + + <para> + In addition to numerous new and upgraded packages, this release has the + following highlights: + </para> + + <itemizedlist> + <listitem> + <para /> + </listitem> + </itemizedlist> + </section> + + <section xmlns="http://docbook.org/ns/docbook" + xmlns:xlink="http://www.w3.org/1999/xlink" + xmlns:xi="http://www.w3.org/2001/XInclude" + version="5.0" + xml:id="sec-release-19.09-new-services"> + <title>New Services</title> + + <para> + The following new services were added since the last release: + </para> + + <itemizedlist> + <listitem> + <para /> + </listitem> + </itemizedlist> + </section> + + <section xmlns="http://docbook.org/ns/docbook" + xmlns:xlink="http://www.w3.org/1999/xlink" + xmlns:xi="http://www.w3.org/2001/XInclude" + version="5.0" + xml:id="sec-release-19.09-notable-changes"> + <title>Other Notable Changes</title> + + <itemizedlist> + <listitem> + <para> + The <option>documentation</option> module gained an option named + <option>documentation.nixos.includeAllModules</option> which makes the generated + <citerefentry><refentrytitle>configuration.nix</refentrytitle> + <manvolnum>5</manvolnum></citerefentry> manual page include all options from all NixOS modules + included in a given <literal>configuration.nix</literal> configuration file. Currently, it is + set to <literal>false</literal> by default as enabling it frequently prevents evaluation. But + the plan is to eventually have it set to <literal>true</literal> by default. Please set it to + <literal>true</literal> now in your <literal>configuration.nix</literal> and fix all the bugs + it uncovers. + </para> + </listitem> + </itemizedlist> + </section> +</section> diff --git a/nixos/lib/eval-config.nix b/nixos/lib/eval-config.nix index 5f05b037bdd..77490ca3762 100644 --- a/nixos/lib/eval-config.nix +++ b/nixos/lib/eval-config.nix @@ -51,7 +51,7 @@ in rec { # system configuration. inherit (lib.evalModules { inherit prefix check; - modules = modules ++ extraModules ++ baseModules ++ [ pkgsModule ]; + modules = baseModules ++ extraModules ++ [ pkgsModule ] ++ modules; args = extraArgs; specialArgs = { modulesPath = builtins.toString ../modules; } // specialArgs; @@ -60,7 +60,7 @@ in rec { # These are the extra arguments passed to every module. In # particular, Nixpkgs is passed through the "pkgs" argument. extraArgs = extraArgs_ // { - inherit modules baseModules; + inherit baseModules extraModules modules; }; inherit (config._module.args) pkgs; diff --git a/nixos/modules/config/no-x-libs.nix b/nixos/modules/config/no-x-libs.nix index 37e66c64542..9d202347702 100644 --- a/nixos/modules/config/no-x-libs.nix +++ b/nixos/modules/config/no-x-libs.nix @@ -34,7 +34,7 @@ with lib; networkmanager-openvpn = super.networkmanager-openvpn.override { withGnome = false; }; networkmanager-vpnc = super.networkmanager-vpnc.override { withGnome = false; }; networkmanager-iodine = super.networkmanager-iodine.override { withGnome = false; }; - pinentry = super.pinentry_ncurses; + pinentry = super.pinentry.override { gtk2 = null; qt = null; }; gobject-introspection = super.gobject-introspection.override { x11Support = false; }; })); }; diff --git a/nixos/modules/config/zram.nix b/nixos/modules/config/zram.nix index 925d945c081..5d411c73a56 100644 --- a/nixos/modules/config/zram.nix +++ b/nixos/modules/config/zram.nix @@ -91,13 +91,13 @@ in }; algorithm = mkOption { - default = "zstd"; - example = "lzo"; + default = "lzo"; + example = "lz4"; type = with types; either (enum [ "lzo" "lz4" "zstd" ]) str; description = '' Compression algorithm. <literal>lzo</literal> has good compression, but is slow. <literal>lz4</literal> has bad compression, but is fast. - <literal>zstd</literal> is both good compression and fast. + <literal>zstd</literal> is both good compression and fast, but requires newer kernel. You can check what other algorithms are supported by your zram device with <programlisting>cat /sys/class/block/zram*/comp_algorithm</programlisting> ''; diff --git a/nixos/modules/hardware/video/nvidia.nix b/nixos/modules/hardware/video/nvidia.nix index 6ba8130af71..80ea7bc5d5c 100644 --- a/nixos/modules/hardware/video/nvidia.nix +++ b/nixos/modules/hardware/video/nvidia.nix @@ -172,6 +172,11 @@ in environment.systemPackages = [ nvidia_x11.bin nvidia_x11.settings ] ++ lib.filter (p: p != null) [ nvidia_x11.persistenced ]; + systemd.tmpfiles.rules = optional config.virtualisation.docker.enableNvidia + "L+ /run/nvidia-docker/bin - - - - ${nvidia_x11.bin}/origBin" + ++ optional (nvidia_x11.persistenced != null && config.virtualisation.docker.enableNvidia) + "L+ /run/nvidia-docker/extras/bin/nvidia-persistenced - - - - ${nvidia_x11.persistenced}/origBin/nvidia-persistenced"; + boot.extraModulePackages = [ nvidia_x11.bin ]; # nvidia-uvm is required by CUDA applications. diff --git a/nixos/modules/installer/tools/nixos-install.sh b/nixos/modules/installer/tools/nixos-install.sh index defc46ad2a7..8685cb345e1 100644 --- a/nixos/modules/installer/tools/nixos-install.sh +++ b/nixos/modules/installer/tools/nixos-install.sh @@ -138,7 +138,18 @@ fi # Ask the user to set a root password, but only if the passwd command # exists (i.e. when mutable user accounts are enabled). if [[ -z $noRootPasswd ]] && [ -t 0 ]; then - nixos-enter --root "$mountPoint" -c '[[ -e /nix/var/nix/profiles/system/sw/bin/passwd ]] && echo "setting root password..." && /nix/var/nix/profiles/system/sw/bin/passwd' + if nixos-enter --root "$mountPoint" -c 'test -e /nix/var/nix/profiles/system/sw/bin/passwd'; then + set +e + nixos-enter --root "$mountPoint" -c 'echo "setting root password..." && /nix/var/nix/profiles/system/sw/bin/passwd' + exit_code=$? + set -e + + if [[ $exit_code != 0 ]]; then + echo "Setting a root password failed with the above printed error." + echo "You can set the root password manually by executing \`nixos-enter --root ${mountPoint@Q}\` and then running \`passwd\` in the shell of the new system." + exit $exit_code + fi + fi fi echo "installation finished!" diff --git a/nixos/modules/installer/tools/nixos-rebuild.sh b/nixos/modules/installer/tools/nixos-rebuild.sh index 361c2e49e05..6a08c9b4c6c 100644 --- a/nixos/modules/installer/tools/nixos-rebuild.sh +++ b/nixos/modules/installer/tools/nixos-rebuild.sh @@ -29,7 +29,7 @@ while [ "$#" -gt 0 ]; do --help) showSyntax ;; - switch|boot|test|build|dry-build|dry-run|dry-activate|build-vm|build-vm-with-bootloader) + switch|boot|test|build|edit|dry-build|dry-run|dry-activate|build-vm|build-vm-with-bootloader) if [ "$i" = dry-run ]; then i=dry-build; fi action="$i" ;; @@ -227,6 +227,13 @@ if [ -z "$_NIXOS_REBUILD_REEXEC" -a -n "$canRun" -a -z "$fast" ]; then fi fi +# Find configuration.nix and open editor instead of building. +if [ "$action" = edit ]; then + NIXOS_CONFIG=${NIXOS_CONFIG:-$(nix-instantiate --find-file nixos-config)} + exec "${EDITOR:-nano}" "$NIXOS_CONFIG" + exit 1 +fi + tmpDir=$(mktemp -t -d nixos-rebuild.XXXXXX) SSHOPTS="$NIX_SSHOPTS -o ControlMaster=auto -o ControlPath=$tmpDir/ssh-%n -o ControlPersist=60" @@ -260,6 +267,14 @@ if [ -n "$rollback" -o "$action" = dry-build ]; then buildNix= fi +nixSystem() { + machine="$(uname -m)" + if [[ "$machine" =~ i.86 ]]; then + machine=i686 + fi + echo $machine-linux +} + prebuiltNix() { machine="$1" if [ "$machine" = x86_64 ]; then @@ -279,7 +294,9 @@ if [ -n "$buildNix" ]; then nixDrv= if ! nixDrv="$(nix-instantiate '<nixpkgs/nixos>' --add-root $tmpDir/nix.drv --indirect -A config.nix.package.out "${extraBuildFlags[@]}")"; then if ! nixDrv="$(nix-instantiate '<nixpkgs>' --add-root $tmpDir/nix.drv --indirect -A nix "${extraBuildFlags[@]}")"; then - nixStorePath="$(prebuiltNix "$(uname -m)")" + if ! nixStorePath="$(nix-instantiate --eval '<nixpkgs/nixos/modules/installer/tools/nix-fallback-paths.nix>' -A $(nixSystem) | sed -e 's/^"//' -e 's/"$//')"; then + nixStorePath="$(prebuiltNix "$(uname -m)")" + fi if ! nix-store -r $nixStorePath --add-root $tmpDir/nix --indirect \ --option extra-binary-caches https://cache.nixos.org/; then echo "warning: don't know how to get latest Nix" >&2 diff --git a/nixos/modules/misc/documentation.nix b/nixos/modules/misc/documentation.nix index 9b2e1235b74..834ac0de912 100644 --- a/nixos/modules/misc/documentation.nix +++ b/nixos/modules/misc/documentation.nix @@ -1,4 +1,4 @@ -{ config, lib, pkgs, baseModules, ... }: +{ config, lib, pkgs, baseModules, extraModules, modules, ... }: with lib; @@ -6,6 +6,8 @@ let cfg = config.documentation; + manualModules = baseModules ++ optionals cfg.nixos.includeAllModules (extraModules ++ modules); + /* For the purpose of generating docs, evaluate options with each derivation in `pkgs` (recursively) replaced by a fake with path "\${pkgs.attribute.path}". It isn't perfect, but it seems to cover a vast majority of use cases. @@ -18,7 +20,7 @@ let options = let scrubbedEval = evalModules { - modules = [ { nixpkgs.localSystem = config.nixpkgs.localSystem; } ] ++ baseModules; + modules = [ { nixpkgs.localSystem = config.nixpkgs.localSystem; } ] ++ manualModules; args = (config._module.args) // { modules = [ ]; }; specialArgs = { pkgs = scrubDerivations "pkgs" pkgs; }; }; @@ -146,6 +148,17 @@ in ''; }; + nixos.includeAllModules = mkOption { + type = types.bool; + default = false; + description = '' + Whether the generated NixOS's documentation should include documentation for all + the options from all the NixOS modules included in the current + <literal>configuration.nix</literal>. Disabling this will make the manual + generator to ignore options defined outside of <literal>baseModules</literal>. + ''; + }; + }; }; diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index 32b3f14e82d..0accee36034 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -182,6 +182,7 @@ ./services/audio/mpd.nix ./services/audio/mopidy.nix ./services/audio/slimserver.nix + ./services/audio/snapserver.nix ./services/audio/squeezelite.nix ./services/audio/ympd.nix ./services/backup/bacula.nix @@ -189,6 +190,7 @@ ./services/backup/duplicati.nix ./services/backup/crashplan.nix ./services/backup/crashplan-small-business.nix + ./services/backup/duplicity.nix ./services/backup/mysql-backup.nix ./services/backup/postgresql-backup.nix ./services/backup/restic.nix @@ -268,6 +270,7 @@ ./services/desktops/gnome3/gnome-online-accounts.nix ./services/desktops/gnome3/gnome-remote-desktop.nix ./services/desktops/gnome3/gnome-online-miners.nix + ./services/desktops/gnome3/gnome-settings-daemon.nix ./services/desktops/gnome3/gnome-terminal-server.nix ./services/desktops/gnome3/gnome-user-share.nix ./services/desktops/gnome3/gpaste.nix @@ -424,7 +427,7 @@ ./services/misc/parsoid.nix ./services/misc/phd.nix ./services/misc/plex.nix - ./services/misc/plexpy.nix + ./services/misc/tautulli.nix ./services/misc/pykms.nix ./services/misc/radarr.nix ./services/misc/redmine.nix @@ -528,6 +531,7 @@ ./services/networking/cntlm.nix ./services/networking/connman.nix ./services/networking/consul.nix + ./services/networking/coredns.nix ./services/networking/coturn.nix ./services/networking/dante.nix ./services/networking/ddclient.nix diff --git a/nixos/modules/programs/bash/bash.nix b/nixos/modules/programs/bash/bash.nix index d22f9dfa319..d53c6b318f1 100644 --- a/nixos/modules/programs/bash/bash.nix +++ b/nixos/modules/programs/bash/bash.nix @@ -102,7 +102,7 @@ in # Emacs term mode doesn't support xterm title escape sequence (\e]0;) PS1="\n\[\033[$PROMPT_COLOR\][\u@\h:\w]\\$\[\033[0m\] " else - PS1="\n\[\033[$PROMPT_COLOR\][\[\e]0;\u@\h: \w\a\]\u@\h:\w]\$\[\033[0m\] " + PS1="\n\[\033[$PROMPT_COLOR\][\[\e]0;\u@\h: \w\a\]\u@\h:\w]\\$\[\033[0m\] " fi if test "$TERM" = "xterm"; then PS1="\[\033]2;\h:\u:\w\007\]$PS1" diff --git a/nixos/modules/programs/fish.nix b/nixos/modules/programs/fish.nix index b38af07b92c..bcb5a3f341b 100644 --- a/nixos/modules/programs/fish.nix +++ b/nixos/modules/programs/fish.nix @@ -169,6 +169,59 @@ in end ''; + programs.fish.interactiveShellInit = '' + # add completions generated by NixOS to $fish_complete_path + begin + # joins with null byte to acommodate all characters in paths, then respectively gets all paths before (exclusive) / after (inclusive) the first one including "generated_completions", + # splits by null byte, and then removes all empty lines produced by using 'string' + set -l prev (string join0 $fish_complete_path | string match --regex "^.*?(?=\x00[^\x00]*generated_completions.*)" | string split0 | string match -er ".") + set -l post (string join0 $fish_complete_path | string match --regex "[^\x00]*generated_completions.*" | string split0 | string match -er ".") + set fish_complete_path $prev "/etc/fish/generated_completions" $post + end + ''; + + environment.etc."fish/generated_completions".source = + let + patchedGenerator = pkgs.stdenv.mkDerivation { + name = "fish_patched-completion-generator"; + srcs = [ + "${pkgs.fish}/share/fish/tools/create_manpage_completions.py" + "${pkgs.fish}/share/fish/tools/deroff.py" + ]; + unpackCmd = "cp $curSrc $(basename $curSrc)"; + sourceRoot = "."; + patches = [ ./fish_completion-generator.patch ]; # to prevent collisions of identical completion files + dontBuild = true; + installPhase = '' + mkdir -p $out + cp * $out/ + ''; + preferLocalBuild = true; + allowSubstitutes = false; + }; + generateCompletions = package: pkgs.runCommand + "${package.name}_fish-completions" + ( + { + inherit package; + preferLocalBuild = true; + allowSubstitutes = false; + } + // optionalAttrs (package ? meta.priority) { meta.priority = package.meta.priority; } + ) + '' + mkdir -p $out + if [ -d $package/share/man ]; then + find $package/share/man -type f | xargs ${pkgs.python3.interpreter} ${patchedGenerator}/create_manpage_completions.py --directory $out >/dev/null + fi + ''; + in + pkgs.buildEnv { + name = "system_fish-completions"; + ignoreCollisions = true; + paths = map generateCompletions config.environment.systemPackages; + }; + # include programs that bring their own completions environment.pathsToLink = [] ++ optional cfg.vendor.config.enable "/share/fish/vendor_conf.d" diff --git a/nixos/modules/programs/fish_completion-generator.patch b/nixos/modules/programs/fish_completion-generator.patch new file mode 100644 index 00000000000..a8c797d185a --- /dev/null +++ b/nixos/modules/programs/fish_completion-generator.patch @@ -0,0 +1,11 @@ +--- a/create_manpage_completions.py ++++ b/create_manpage_completions.py +@@ -776,8 +776,6 @@ def parse_manpage_at_path(manpage_path, output_directory): + + built_command_output.insert(0, "# " + CMDNAME) + +- # Output the magic word Autogenerated so we can tell if we can overwrite this +- built_command_output.insert(1, "# Autogenerated from man page " + manpage_path) + # built_command_output.insert(2, "# using " + parser.__class__.__name__) # XXX MISATTRIBUTES THE CULPABILE PARSER! Was really using Type2 but reporting TypeDeroffManParser + + for line in built_command_output: diff --git a/nixos/modules/programs/gnupg.nix b/nixos/modules/programs/gnupg.nix index b01de9efaa5..22521280e93 100644 --- a/nixos/modules/programs/gnupg.nix +++ b/nixos/modules/programs/gnupg.nix @@ -85,11 +85,13 @@ in # SSH agent protocol doesn't support changing TTYs, so bind the agent # to every new TTY. ${pkgs.gnupg}/bin/gpg-connect-agent --quiet updatestartuptty /bye > /dev/null + ''); + environment.extraInit = mkIf cfg.agent.enableSSHSupport '' if [ -z "$SSH_AUTH_SOCK" ]; then export SSH_AUTH_SOCK=$(${pkgs.gnupg}/bin/gpgconf --list-dirs agent-ssh-socket) fi - ''); + ''; assertions = [ { assertion = cfg.agent.enableSSHSupport -> !config.programs.ssh.startAgent; diff --git a/nixos/modules/rename.nix b/nixos/modules/rename.nix index 1e6557e1f0e..7fb58a2b800 100644 --- a/nixos/modules/rename.nix +++ b/nixos/modules/rename.nix @@ -186,6 +186,9 @@ with lib; # parsoid (mkRemovedOptionModule [ "services" "parsoid" "interwikis" ] [ "services" "parsoid" "wikis" ]) + # plexpy / tautulli + (mkRenamedOptionModule [ "services" "plexpy" ] [ "services" "tautulli" ]) + # piwik was renamed to matomo (mkRenamedOptionModule [ "services" "piwik" "enable" ] [ "services" "matomo" "enable" ]) (mkRenamedOptionModule [ "services" "piwik" "webServerUser" ] [ "services" "matomo" "webServerUser" ]) diff --git a/nixos/modules/security/duosec.nix b/nixos/modules/security/duosec.nix index df6108dede7..14bf118f2d8 100644 --- a/nixos/modules/security/duosec.nix +++ b/nixos/modules/security/duosec.nix @@ -7,7 +7,7 @@ let boolToStr = b: if b then "yes" else "no"; - configFile = '' + configFilePam = '' [duo] ikey=${cfg.ikey} skey=${cfg.skey} @@ -16,21 +16,24 @@ let failmode=${cfg.failmode} pushinfo=${boolToStr cfg.pushinfo} autopush=${boolToStr cfg.autopush} - motd=${boolToStr cfg.motd} prompts=${toString cfg.prompts} - accept_env_factor=${boolToStr cfg.acceptEnvFactor} fallback_local_ip=${boolToStr cfg.fallbackLocalIP} ''; + configFileLogin = configFilePam + '' + motd=${boolToStr cfg.motd} + accept_env_factor=${boolToStr cfg.acceptEnvFactor} + ''; + loginCfgFile = optional cfg.ssh.enable - { source = pkgs.writeText "login_duo.conf" configFile; + { source = pkgs.writeText "login_duo.conf" configFileLogin; mode = "0600"; user = "sshd"; target = "duo/login_duo.conf"; }; pamCfgFile = optional cfg.pam.enable - { source = pkgs.writeText "pam_duo.conf" configFile; + { source = pkgs.writeText "pam_duo.conf" configFilePam; mode = "0600"; user = "sshd"; target = "duo/pam_duo.conf"; @@ -180,12 +183,6 @@ in }; config = mkIf (cfg.ssh.enable || cfg.pam.enable) { - assertions = - [ { assertion = !cfg.pam.enable; - message = "PAM support is currently not implemented."; - } - ]; - environment.systemPackages = [ pkgs.duo-unix ]; security.wrappers.login_duo.source = "${pkgs.duo-unix.out}/bin/login_duo"; diff --git a/nixos/modules/security/pam.nix b/nixos/modules/security/pam.nix index 206b529ed68..03d2f899f2a 100644 --- a/nixos/modules/security/pam.nix +++ b/nixos/modules/security/pam.nix @@ -131,6 +131,18 @@ let ''; }; + duoSecurity = { + enable = mkOption { + default = false; + type = types.bool; + description = '' + If set, use the Duo Security pam module + <literal>pam_duo</literal> for authentication. Requires + configuration of <option>security.duosec</option> options. + ''; + }; + }; + startSession = mkOption { default = false; type = types.bool; @@ -340,7 +352,8 @@ let || cfg.pamMount || cfg.enableKwallet || cfg.enableGnomeKeyring - || cfg.googleAuthenticator.enable)) '' + || cfg.googleAuthenticator.enable + || cfg.duoSecurity.enable)) '' auth required pam_unix.so ${optionalString cfg.allowNullPassword "nullok"} likeauth ${optionalString config.security.pam.enableEcryptfs "auth optional ${pkgs.ecryptfs}/lib/security/pam_ecryptfs.so unwrap"} @@ -350,9 +363,11 @@ let ("auth optional ${pkgs.plasma5.kwallet-pam}/lib/security/pam_kwallet5.so" + " kwalletd=${pkgs.libsForQt5.kwallet.bin}/bin/kwalletd5")} ${optionalString cfg.enableGnomeKeyring - ("auth optional ${pkgs.gnome3.gnome-keyring}/lib/security/pam_gnome_keyring.so")} + "auth optional ${pkgs.gnome3.gnome-keyring}/lib/security/pam_gnome_keyring.so"} ${optionalString cfg.googleAuthenticator.enable - "auth required ${pkgs.googleAuthenticator}/lib/security/pam_google_authenticator.so no_increment_hotp"} + "auth required ${pkgs.googleAuthenticator}/lib/security/pam_google_authenticator.so no_increment_hotp"} + ${optionalString cfg.duoSecurity.enable + "auth required ${pkgs.duo-unix}/lib/security/pam_duo.so"} '') + '' ${optionalString cfg.unixAuth "auth sufficient pam_unix.so ${optionalString cfg.allowNullPassword "nullok"} likeauth try_first_pass"} diff --git a/nixos/modules/services/audio/snapserver.nix b/nixos/modules/services/audio/snapserver.nix new file mode 100644 index 00000000000..f709dd7fe16 --- /dev/null +++ b/nixos/modules/services/audio/snapserver.nix @@ -0,0 +1,217 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + + package = "snapcast"; + name = "snapserver"; + + cfg = config.services.snapserver; + + # Using types.nullOr to inherit upstream defaults. + sampleFormat = mkOption { + type = with types; nullOr str; + default = null; + description = '' + Default sample format. + ''; + example = "48000:16:2"; + }; + + codec = mkOption { + type = with types; nullOr str; + default = null; + description = '' + Default audio compression method. + ''; + example = "flac"; + }; + + streamToOption = name: opt: + let + os = val: + optionalString (val != null) "${val}"; + os' = prefixx: val: + optionalString (val != null) (prefixx + "${val}"); + flatten = key: value: + "&${key}=${value}"; + in + "-s ${opt.type}://" + os opt.location + "?" + os' "name=" name + + concatStrings (mapAttrsToList flatten opt.query); + + optionalNull = val: ret: + optional (val != null) ret; + + optionString = concatStringsSep " " (mapAttrsToList streamToOption cfg.streams + ++ ["-p ${toString cfg.port}"] + ++ ["--controlPort ${toString cfg.controlPort}"] + ++ optionalNull cfg.sampleFormat "--sampleFormat ${cfg.sampleFormat}" + ++ optionalNull cfg.codec "-c ${cfg.codec}" + ++ optionalNull cfg.streamBuffer "--streamBuffer ${cfg.streamBuffer}" + ++ optionalNull cfg.buffer "-b ${cfg.buffer}" + ++ optional cfg.sendToMuted "--sendToMuted"); + +in { + + ###### interface + + options = { + + services.snapserver = { + + enable = mkOption { + type = types.bool; + default = false; + description = '' + Whether to enable snapserver. + ''; + }; + + port = mkOption { + type = types.port; + default = 1704; + description = '' + The port that snapclients can connect to. + ''; + }; + + controlPort = mkOption { + type = types.port; + default = 1705; + description = '' + The port for control connections (JSON-RPC). + ''; + }; + + openFirewall = mkOption { + type = types.bool; + default = true; + description = '' + Whether to automatically open the specified ports in the firewall. + ''; + }; + + inherit sampleFormat; + inherit codec; + + streams = mkOption { + type = with types; attrsOf (submodule { + options = { + location = mkOption { + type = types.path; + description = '' + The location of the pipe. + ''; + }; + type = mkOption { + type = types.enum [ "pipe" "file" "process" "spotify" "airplay" ]; + default = "pipe"; + description = '' + The type of input stream. + ''; + }; + query = mkOption { + type = attrsOf str; + default = {}; + description = '' + Key-value pairs that convey additional parameters about a stream. + ''; + example = literalExample '' + # for type == "pipe": + { + mode = "listen"; + }; + # for type == "process": + { + params = "--param1 --param2"; + logStderr = "true"; + }; + ''; + }; + inherit sampleFormat; + inherit codec; + }; + }); + default = { default = {}; }; + description = '' + The definition for an input source. + ''; + example = literalExample '' + { + mpd = { + type = "pipe"; + location = "/run/snapserver/mpd"; + sampleFormat = "48000:16:2"; + codec = "pcm"; + }; + }; + ''; + }; + + streamBuffer = mkOption { + type = with types; nullOr int; + default = null; + description = '' + Stream read (input) buffer in ms. + ''; + example = 20; + }; + + buffer = mkOption { + type = with types; nullOr int; + default = null; + description = '' + Network buffer in ms. + ''; + example = 1000; + }; + + sendToMuted = mkOption { + type = types.bool; + default = false; + description = '' + Send audio to muted clients. + ''; + }; + }; + + }; + + + ###### implementation + + config = mkIf cfg.enable { + + systemd.services.snapserver = { + after = [ "network.target" ]; + description = "Snapserver"; + wantedBy = [ "multi-user.target" ]; + before = [ "mpd.service" "mopidy.service" ]; + + serviceConfig = { + DynamicUser = true; + ExecStart = "${pkgs.snapcast}/bin/snapserver --daemon ${optionString}"; + Type = "forking"; + LimitRTPRIO = 50; + LimitRTTIME = "infinity"; + NoNewPrivileges = true; + PIDFile = "/run/${name}/pid"; + ProtectKernelTunables = true; + ProtectControlGroups = true; + ProtectKernelModules = true; + RestrictAddressFamilies = "AF_INET AF_INET6 AF_UNIX"; + RestrictNamespaces = true; + RuntimeDirectory = name; + StateDirectory = name; + }; + }; + + networking.firewall.allowedTCPPorts = optionals cfg.openFirewall [ cfg.port cfg.controlPort ]; + }; + + meta = { + maintainers = with maintainers; [ tobim ]; + }; + +} diff --git a/nixos/modules/services/backup/duplicity.nix b/nixos/modules/services/backup/duplicity.nix new file mode 100644 index 00000000000..a8d56424862 --- /dev/null +++ b/nixos/modules/services/backup/duplicity.nix @@ -0,0 +1,141 @@ +{ config, lib, pkgs, ...}: + +with lib; + +let + cfg = config.services.duplicity; + + stateDirectory = "/var/lib/duplicity"; + + localTarget = if hasPrefix "file://" cfg.targetUrl + then removePrefix "file://" cfg.targetUrl else null; + +in { + options.services.duplicity = { + enable = mkEnableOption "backups with duplicity"; + + root = mkOption { + type = types.path; + default = "/"; + description = '' + Root directory to backup. + ''; + }; + + include = mkOption { + type = types.listOf types.str; + default = []; + example = [ "/home" ]; + description = '' + List of paths to include into the backups. See the FILE SELECTION + section in <citerefentry><refentrytitle>duplicity</refentrytitle> + <manvolnum>1</manvolnum></citerefentry> for details on the syntax. + ''; + }; + + exclude = mkOption { + type = types.listOf types.str; + default = []; + description = '' + List of paths to exclude from backups. See the FILE SELECTION section in + <citerefentry><refentrytitle>duplicity</refentrytitle> + <manvolnum>1</manvolnum></citerefentry> for details on the syntax. + ''; + }; + + targetUrl = mkOption { + type = types.str; + example = "s3://host:port/prefix"; + description = '' + Target url to backup to. See the URL FORMAT section in + <citerefentry><refentrytitle>duplicity</refentrytitle> + <manvolnum>1</manvolnum></citerefentry> for supported urls. + ''; + }; + + secretFile = mkOption { + type = types.nullOr types.path; + default = null; + description = '' + Path of a file containing secrets (gpg passphrase, access key...) in + the format of EnvironmentFile as described by + <citerefentry><refentrytitle>systemd.exec</refentrytitle> + <manvolnum>5</manvolnum></citerefentry>. For example: + <programlisting> + PASSPHRASE=<replaceable>...</replaceable> + AWS_ACCESS_KEY_ID=<replaceable>...</replaceable> + AWS_SECRET_ACCESS_KEY=<replaceable>...</replaceable> + </programlisting> + ''; + }; + + frequency = mkOption { + type = types.nullOr types.str; + default = "daily"; + description = '' + Run duplicity with the given frequency (see + <citerefentry><refentrytitle>systemd.time</refentrytitle> + <manvolnum>7</manvolnum></citerefentry> for the format). + If null, do not run automatically. + ''; + }; + + extraFlags = mkOption { + type = types.listOf types.str; + default = []; + example = [ "--full-if-older-than" "1M" ]; + description = '' + Extra command-line flags passed to duplicity. See + <citerefentry><refentrytitle>duplicity</refentrytitle> + <manvolnum>1</manvolnum></citerefentry>. + ''; + }; + }; + + config = mkIf cfg.enable { + systemd = { + services.duplicity = { + description = "backup files with duplicity"; + + environment.HOME = stateDirectory; + + serviceConfig = { + ExecStart = '' + ${pkgs.duplicity}/bin/duplicity ${escapeShellArgs ( + [ + cfg.root + cfg.targetUrl + "--archive-dir" stateDirectory + ] + ++ concatMap (p: [ "--include" p ]) cfg.include + ++ concatMap (p: [ "--exclude" p ]) cfg.exclude + ++ cfg.extraFlags)} + ''; + PrivateTmp = true; + ProtectSystem = "strict"; + ProtectHome = "read-only"; + StateDirectory = baseNameOf stateDirectory; + } // optionalAttrs (localTarget != null) { + ReadWritePaths = localTarget; + } // optionalAttrs (cfg.secretFile != null) { + EnvironmentFile = cfg.secretFile; + }; + } // optionalAttrs (cfg.frequency != null) { + startAt = cfg.frequency; + }; + + tmpfiles.rules = optional (localTarget != null) "d ${localTarget} 0700 root root -"; + }; + + assertions = singleton { + # Duplicity will fail if the last file selection option is an include. It + # is not always possible to detect but this simple case can be caught. + assertion = cfg.include != [] -> cfg.exclude != [] || cfg.extraFlags != []; + message = '' + Duplicity will fail if you only specify included paths ("Because the + default is to include all files, the expression is redundant. Exiting + because this probably isn't what you meant.") + ''; + }; + }; +} diff --git a/nixos/modules/services/cluster/kubernetes/apiserver.nix b/nixos/modules/services/cluster/kubernetes/apiserver.nix index 81e45b417de..455d0239604 100644 --- a/nixos/modules/services/cluster/kubernetes/apiserver.nix +++ b/nixos/modules/services/cluster/kubernetes/apiserver.nix @@ -350,7 +350,7 @@ in listenPeerUrls = mkDefault ["https://0.0.0.0:2380"]; advertiseClientUrls = mkDefault ["https://${top.masterAddress}:2379"]; initialCluster = mkDefault ["${top.masterAddress}=https://${top.masterAddress}:2380"]; - name = top.masterAddress; + name = mkDefault top.masterAddress; initialAdvertisePeerUrls = mkDefault ["https://${top.masterAddress}:2380"]; }; diff --git a/nixos/modules/services/cluster/kubernetes/controller-manager.nix b/nixos/modules/services/cluster/kubernetes/controller-manager.nix index dff97f144d5..060fd9b78db 100644 --- a/nixos/modules/services/cluster/kubernetes/controller-manager.nix +++ b/nixos/modules/services/cluster/kubernetes/controller-manager.nix @@ -131,7 +131,7 @@ in ${optionalString (cfg.tlsCertFile!=null) "--tls-cert-file=${cfg.tlsCertFile}"} \ ${optionalString (cfg.tlsKeyFile!=null) - "--tls-key-file=${cfg.tlsKeyFile}"} \ + "--tls-private-key-file=${cfg.tlsKeyFile}"} \ ${optionalString (elem "RBAC" top.apiserver.authorizationMode) "--use-service-account-credentials"} \ ${optionalString (cfg.verbosity != null) "--v=${toString cfg.verbosity}"} \ diff --git a/nixos/modules/services/cluster/kubernetes/default.nix b/nixos/modules/services/cluster/kubernetes/default.nix index 375e33e91b5..3e53d18f8bb 100644 --- a/nixos/modules/services/cluster/kubernetes/default.nix +++ b/nixos/modules/services/cluster/kubernetes/default.nix @@ -10,7 +10,7 @@ let kind = "Config"; clusters = [{ name = "local"; - cluster.certificate-authority = cfg.caFile; + cluster.certificate-authority = conf.caFile or cfg.caFile; cluster.server = conf.server; }]; users = [{ diff --git a/nixos/modules/services/databases/openldap.nix b/nixos/modules/services/databases/openldap.nix index e996211be7d..5c302752781 100644 --- a/nixos/modules/services/databases/openldap.nix +++ b/nixos/modules/services/databases/openldap.nix @@ -146,7 +146,7 @@ in chown -R "${cfg.user}:${cfg.group}" "${cfg.dataDir}" ''; serviceConfig.ExecStart = - "${openldap.out}/libexec/slapd -d ${cfg.logLevel} " + + "${openldap.out}/libexec/slapd -d '${cfg.logLevel}' " + "-u '${cfg.user}' -g '${cfg.group}' " + "-h '${concatStringsSep " " cfg.urlList}' " + "${configOpts}"; diff --git a/nixos/modules/services/desktops/gnome3/gnome-settings-daemon.nix b/nixos/modules/services/desktops/gnome3/gnome-settings-daemon.nix new file mode 100644 index 00000000000..dbf0f4e9b11 --- /dev/null +++ b/nixos/modules/services/desktops/gnome3/gnome-settings-daemon.nix @@ -0,0 +1,45 @@ +# GNOME Settings Daemon + +{ config, lib, pkgs, ... }: + +with lib; + +let + + cfg = config.services.gnome3.gnome-settings-daemon; + +in + +{ + + ###### interface + + options = { + + services.gnome3.gnome-settings-daemon = { + + enable = mkEnableOption "GNOME Settings Daemon."; + + # There are many forks of gnome-settings-daemon + package = mkOption { + type = types.package; + default = pkgs.gnome3.gnome-settings-daemon; + description = "Which gnome-settings-daemon package to use."; + }; + + }; + + }; + + + ###### implementation + + config = mkIf cfg.enable { + + environment.systemPackages = [ cfg.package ]; + + services.udev.packages = [ cfg.package ]; + + }; + +} diff --git a/nixos/modules/services/hardware/thinkfan.nix b/nixos/modules/services/hardware/thinkfan.nix index d17121ca1c5..7c105e99ca5 100644 --- a/nixos/modules/services/hardware/thinkfan.nix +++ b/nixos/modules/services/hardware/thinkfan.nix @@ -47,6 +47,8 @@ let ${cfg.levels} ''; + thinkfan = pkgs.thinkfan.override { smartSupport = cfg.smartSupport; }; + in { options = { @@ -61,6 +63,15 @@ in { ''; }; + smartSupport = mkOption { + type = types.bool; + default = false; + description = '' + Whether to build thinkfan with SMART support to read temperatures + directly from hard disks. + ''; + }; + sensors = mkOption { type = types.lines; default = '' @@ -77,7 +88,7 @@ in { Which may be provided by any hwmon drivers (keyword hwmon) - S.M.A.R.T. (since 0.9 and requires the USE_ATASMART compilation flag) + S.M.A.R.T. (requires smartSupport to be enabled) Which reads the temperature directly from the hard disk using libatasmart (keyword atasmart) @@ -125,18 +136,17 @@ in { config = mkIf cfg.enable { - environment.systemPackages = [ pkgs.thinkfan ]; + environment.systemPackages = [ thinkfan ]; systemd.services.thinkfan = { description = "Thinkfan"; after = [ "basic.target" ]; wantedBy = [ "multi-user.target" ]; - path = [ pkgs.thinkfan ]; - serviceConfig.ExecStart = "${pkgs.thinkfan}/bin/thinkfan -n -c ${configFile}"; + path = [ thinkfan ]; + serviceConfig.ExecStart = "${thinkfan}/bin/thinkfan -n -c ${configFile}"; }; boot.extraModprobeConfig = "options thinkpad_acpi experimental=1 fan_control=1"; }; - } diff --git a/nixos/modules/services/mail/rmilter.nix b/nixos/modules/services/mail/rmilter.nix index 492c6458321..466365b6b30 100644 --- a/nixos/modules/services/mail/rmilter.nix +++ b/nixos/modules/services/mail/rmilter.nix @@ -8,7 +8,7 @@ let postfixCfg = config.services.postfix; cfg = config.services.rmilter; - inetSocket = addr: port: "inet:[${toString port}@${addr}]"; + inetSocket = addr: port: "inet:${addr}:${toString port}"; unixSocket = sock: "unix:${sock}"; systemdSocket = if cfg.bindSocket.type == "unix" then cfg.bindSocket.path @@ -97,7 +97,7 @@ in bindSocket.address = mkOption { type = types.str; - default = "::1"; + default = "[::1]"; example = "0.0.0.0"; description = '' Inet address to listen on. diff --git a/nixos/modules/services/misc/bepasty.nix b/nixos/modules/services/misc/bepasty.nix index 62835c194e4..006feca42b3 100644 --- a/nixos/modules/services/misc/bepasty.nix +++ b/nixos/modules/services/misc/bepasty.nix @@ -2,10 +2,10 @@ with lib; let - gunicorn = pkgs.pythonPackages.gunicorn; + gunicorn = pkgs.python3Packages.gunicorn; bepasty = pkgs.bepasty; - gevent = pkgs.pythonPackages.gevent; - python = pkgs.pythonPackages.python; + gevent = pkgs.python3Packages.gevent; + python = pkgs.python3Packages.python; cfg = config.services.bepasty; user = "bepasty"; group = "bepasty"; diff --git a/nixos/modules/services/misc/home-assistant.nix b/nixos/modules/services/misc/home-assistant.nix index 95a7f2ea989..7f8d31bcf0b 100644 --- a/nixos/modules/services/misc/home-assistant.nix +++ b/nixos/modules/services/misc/home-assistant.nix @@ -9,13 +9,13 @@ let configJSON = pkgs.writeText "configuration.json" (builtins.toJSON (if cfg.applyDefaultConfig then (recursiveUpdate defaultConfig cfg.config) else cfg.config)); - configFile = pkgs.runCommand "configuration.yaml" { } '' + configFile = pkgs.runCommand "configuration.yaml" { preferLocalBuild = true; } '' ${pkgs.remarshal}/bin/json2yaml -i ${configJSON} -o $out ''; lovelaceConfigJSON = pkgs.writeText "ui-lovelace.json" (builtins.toJSON cfg.lovelaceConfig); - lovelaceConfigFile = pkgs.runCommand "ui-lovelace.yaml" { } '' + lovelaceConfigFile = pkgs.runCommand "ui-lovelace.yaml" { preferLocalBuild = true; } '' ${pkgs.remarshal}/bin/json2yaml -i ${lovelaceConfigJSON} -o $out ''; @@ -29,14 +29,24 @@ let # platform = "luftdaten"; # ... # } ]; + # + # Beginning with 0.87 Home Assistant is migrating their components to the + # scheme "platform.subComponent", e.g. "hue.light" instead of "light.hue". + # See https://developers.home-assistant.io/blog/2019/02/19/the-great-migration.html. + # Hence, we also check whether we find an entry in the config when interpreting + # the first part of the path as the component. useComponentPlatform = component: let path = splitString "." component; + # old: platform is the last part of path parentConfig = attrByPath (init path) null cfg.config; platform = last path; - in isList parentConfig && any - (item: item.platform or null == platform) - parentConfig; + # new: platform is the first part of the path + parentConfig' = attrByPath (tail path) null cfg.config; + platform' = head path; + in + (isList parentConfig && any (item: item.platform or null == platform) parentConfig) + || (isList parentConfig' && any (item: item.platform or null == platform') parentConfig'); # Returns whether component is used in config useComponent = component: diff --git a/nixos/modules/services/misc/redmine.nix b/nixos/modules/services/misc/redmine.nix index 98e9c8953c8..c38138d7c97 100644 --- a/nixos/modules/services/misc/redmine.nix +++ b/nixos/modules/services/misc/redmine.nix @@ -234,10 +234,33 @@ in environment.systemPackages = [ cfg.package ]; + # create symlinks for the basic directory layout the redmine package expects + systemd.tmpfiles.rules = [ + "d '${cfg.stateDir}' 0750 ${cfg.user} ${cfg.group} - -" + "d '${cfg.stateDir}/cache' 0750 ${cfg.user} ${cfg.group} - -" + "d '${cfg.stateDir}/config' 0750 ${cfg.user} ${cfg.group} - -" + "d '${cfg.stateDir}/files' 0750 ${cfg.user} ${cfg.group} - -" + "d '${cfg.stateDir}/log' 0750 ${cfg.user} ${cfg.group} - -" + "d '${cfg.stateDir}/plugins' 0750 ${cfg.user} ${cfg.group} - -" + "d '${cfg.stateDir}/public' 0750 ${cfg.user} ${cfg.group} - -" + "d '${cfg.stateDir}/public/plugin_assets' 0750 ${cfg.user} ${cfg.group} - -" + "d '${cfg.stateDir}/public/themes' 0750 ${cfg.user} ${cfg.group} - -" + "d '${cfg.stateDir}/tmp' 0750 ${cfg.user} ${cfg.group} - -" + + "d /run/redmine - - - - -" + "d /run/redmine/public - - - - -" + "L+ /run/redmine/config - - - - ${cfg.stateDir}/config" + "L+ /run/redmine/files - - - - ${cfg.stateDir}/files" + "L+ /run/redmine/log - - - - ${cfg.stateDir}/log" + "L+ /run/redmine/plugins - - - - ${cfg.stateDir}/plugins" + "L+ /run/redmine/public/plugin_assets - - - - ${cfg.stateDir}/public/plugin_assets" + "L+ /run/redmine/public/themes - - - - ${cfg.stateDir}/public/themes" + "L+ /run/redmine/tmp - - - - ${cfg.stateDir}/tmp" + ]; + systemd.services.redmine = { after = [ "network.target" (if cfg.database.type == "mysql2" then "mysql.service" else "postgresql.service") ]; wantedBy = [ "multi-user.target" ]; - environment.HOME = "${cfg.package}/share/redmine"; environment.RAILS_ENV = "production"; environment.RAILS_CACHE = "${cfg.stateDir}/cache"; environment.REDMINE_LANG = "en"; @@ -252,28 +275,16 @@ in subversion ]; preStart = '' - # ensure cache directory exists for db:migrate command - mkdir -p "${cfg.stateDir}/cache" - - # create the basic directory layout the redmine package expects - mkdir -p /run/redmine/public - - for i in config files log plugins tmp; do - mkdir -p "${cfg.stateDir}/$i" - ln -fs "${cfg.stateDir}/$i" /run/redmine/ - done - - for i in plugin_assets themes; do - mkdir -p "${cfg.stateDir}/public/$i" - ln -fs "${cfg.stateDir}/public/$i" /run/redmine/public/ - done - + rm -rf "${cfg.stateDir}/plugins/"* + rm -rf "${cfg.stateDir}/public/themes/"* # start with a fresh config directory # the config directory is copied instead of linked as some mutable data is stored in there - rm -rf "${cfg.stateDir}/config/"* + find "${cfg.stateDir}/config" ! -name "secret_token.rb" -type f -exec rm -f {} + cp -r ${cfg.package}/share/redmine/config.dist/* "${cfg.stateDir}/config/" + chmod -R u+w "${cfg.stateDir}/config" + # link in the application configuration ln -fs ${configurationYml} "${cfg.stateDir}/config/configuration.yml" @@ -282,7 +293,6 @@ in # link in all user specified themes - rm -rf "${cfg.stateDir}/public/themes/"* for theme in ${concatStringsSep " " (mapAttrsToList unpackTheme cfg.themes)}; do ln -fs $theme/* "${cfg.stateDir}/public/themes" done @@ -292,16 +302,11 @@ in # link in all user specified plugins - rm -rf "${cfg.stateDir}/plugins/"* for plugin in ${concatStringsSep " " (mapAttrsToList unpackPlugin cfg.plugins)}; do ln -fs $plugin/* "${cfg.stateDir}/plugins/''${plugin##*-redmine-plugin-}" done - # ensure correct permissions for most files - chmod -R ug+rwX,o-rwx+x "${cfg.stateDir}/" - - # handle database.passwordFile & permissions DBPASS=$(head -n1 ${cfg.database.passwordFile}) cp -f ${databaseYml} "${cfg.stateDir}/config/database.yml" @@ -315,25 +320,13 @@ in chmod 440 "${cfg.stateDir}/config/initializers/secret_token.rb" fi - - # ensure everything is owned by ${cfg.user} - chown -R ${cfg.user}:${cfg.group} "${cfg.stateDir}" - - # execute redmine required commands prior to starting the application - # NOTE: su required in case using mysql socket authentication - /run/wrappers/bin/su -s ${pkgs.bash}/bin/bash -m -l redmine -c '${bundle} exec rake db:migrate' - /run/wrappers/bin/su -s ${pkgs.bash}/bin/bash -m -l redmine -c '${bundle} exec rake redmine:plugins:migrate' - /run/wrappers/bin/su -s ${pkgs.bash}/bin/bash -m -l redmine -c '${bundle} exec rake redmine:load_default_data' - - - # log files don't exist until after first command has been executed - # correct ownership of files generated by calling exec rake ... - chown -R ${cfg.user}:${cfg.group} "${cfg.stateDir}/log" + ${bundle} exec rake db:migrate + ${bundle} exec rake redmine:plugins:migrate + ${bundle} exec rake redmine:load_default_data ''; serviceConfig = { - PermissionsStartOnly = true; # preStart must be run as root Type = "simple"; User = cfg.user; Group = cfg.group; @@ -348,7 +341,6 @@ in { name = "redmine"; group = cfg.group; home = cfg.stateDir; - createHome = true; uid = config.ids.uids.redmine; }); diff --git a/nixos/modules/services/misc/plexpy.nix b/nixos/modules/services/misc/tautulli.nix index 2a589fdfb27..50e45036647 100644 --- a/nixos/modules/services/misc/plexpy.nix +++ b/nixos/modules/services/misc/tautulli.nix @@ -3,73 +3,69 @@ with lib; let - cfg = config.services.plexpy; + cfg = config.services.tautulli; in { options = { - services.plexpy = { - enable = mkEnableOption "PlexPy Plex Monitor"; + services.tautulli = { + enable = mkEnableOption "Tautulli Plex Monitor"; dataDir = mkOption { type = types.str; default = "/var/lib/plexpy"; - description = "The directory where PlexPy stores its data files."; + description = "The directory where Tautulli stores its data files."; }; configFile = mkOption { type = types.str; default = "/var/lib/plexpy/config.ini"; - description = "The location of PlexPy's config file."; + description = "The location of Tautulli's config file."; }; port = mkOption { type = types.int; default = 8181; - description = "TCP port where PlexPy listens."; + description = "TCP port where Tautulli listens."; }; user = mkOption { type = types.str; default = "plexpy"; - description = "User account under which PlexPy runs."; + description = "User account under which Tautulli runs."; }; group = mkOption { type = types.str; default = "nogroup"; - description = "Group under which PlexPy runs."; + description = "Group under which Tautulli runs."; }; package = mkOption { type = types.package; - default = pkgs.plexpy; - defaultText = "pkgs.plexpy"; + default = pkgs.tautulli; + defaultText = "pkgs.tautulli"; description = '' - The PlexPy package to use. + The Tautulli package to use. ''; }; }; }; config = mkIf cfg.enable { - systemd.services.plexpy = { - description = "PlexPy Plex Monitor"; + systemd.tmpfiles.rules = [ + "d '${cfg.dataDir}' - ${cfg.user} ${cfg.group} - -" + ]; + + systemd.services.tautulli = { + description = "Tautulli Plex Monitor"; after = [ "network.target" ]; wantedBy = [ "multi-user.target" ]; - preStart = '' - test -d "${cfg.dataDir}" || { - echo "Creating initial PlexPy data directory in \"${cfg.dataDir}\"." - mkdir -p "${cfg.dataDir}" - chown ${cfg.user}:${cfg.group} "${cfg.dataDir}" - } - ''; serviceConfig = { Type = "simple"; User = cfg.user; Group = cfg.group; - PermissionsStartOnly = "true"; GuessMainPID = "false"; - ExecStart = "${cfg.package}/bin/plexpy --datadir ${cfg.dataDir} --config ${cfg.configFile} --port ${toString cfg.port} --pidfile ${cfg.dataDir}/plexpy.pid --nolaunch"; + ExecStart = "${cfg.package}/bin/tautulli --datadir ${cfg.dataDir} --config ${cfg.configFile} --port ${toString cfg.port} --pidfile ${cfg.dataDir}/tautulli.pid --nolaunch"; Restart = "on-failure"; }; }; diff --git a/nixos/modules/services/misc/zoneminder.nix b/nixos/modules/services/misc/zoneminder.nix index ae7de7850d9..fb9c4c41ae2 100644 --- a/nixos/modules/services/misc/zoneminder.nix +++ b/nixos/modules/services/misc/zoneminder.nix @@ -275,14 +275,14 @@ in { }; phpfpm = lib.mkIf useNginx { - phpOptions = '' - date.timezone = "${config.time.timeZone}" - - ${lib.concatStringsSep "\n" (map (e: - "extension=${e.pkg}/lib/php/extensions/${e.name}.so") phpExtensions)} - ''; pools.zoneminder = { listen = socket; + phpOptions = '' + date.timezone = "${config.time.timeZone}" + + ${lib.concatStringsSep "\n" (map (e: + "extension=${e.pkg}/lib/php/extensions/${e.name}.so") phpExtensions)} + ''; extraConfig = '' user = ${user} group = ${group} diff --git a/nixos/modules/services/monitoring/datadog-agent.nix b/nixos/modules/services/monitoring/datadog-agent.nix index a4d29d45bac..b4ac0ca184d 100644 --- a/nixos/modules/services/monitoring/datadog-agent.nix +++ b/nixos/modules/services/monitoring/datadog-agent.nix @@ -202,7 +202,7 @@ in { }; }; config = mkIf cfg.enable { - environment.systemPackages = [ datadogPkg pkgs.sysstat pkgs.procps ]; + environment.systemPackages = [ datadogPkg pkgs.sysstat pkgs.procps pkgs.iproute ]; users.extraUsers.datadog = { description = "Datadog Agent User"; @@ -216,7 +216,7 @@ in { systemd.services = let makeService = attrs: recursiveUpdate { - path = [ datadogPkg pkgs.python pkgs.sysstat pkgs.procps ]; + path = [ datadogPkg pkgs.python pkgs.sysstat pkgs.procps pkgs.iproute ]; wantedBy = [ "multi-user.target" ]; serviceConfig = { User = "datadog"; @@ -260,7 +260,7 @@ in { path = [ ]; script = '' export DD_API_KEY=$(head -n 1 ${cfg.apiKeyFile}) - ${pkgs.datadog-trace-agent}/bin/trace-agent -config /etc/datadog-agent/datadog.yaml + ${datadogPkg}/bin/trace-agent -config /etc/datadog-agent/datadog.yaml ''; }); diff --git a/nixos/modules/services/monitoring/hdaps.nix b/nixos/modules/services/monitoring/hdaps.nix index be26c44e78d..2cad3b84d84 100644 --- a/nixos/modules/services/monitoring/hdaps.nix +++ b/nixos/modules/services/monitoring/hdaps.nix @@ -16,6 +16,7 @@ in }; config = mkIf cfg.enable { + boot.kernelModules = [ "hdapsd" ]; services.udev.packages = hdapsd; systemd.packages = hdapsd; }; diff --git a/nixos/modules/services/monitoring/prometheus/alertmanager.nix b/nixos/modules/services/monitoring/prometheus/alertmanager.nix index 43b4a41eaf3..7d790b6b590 100644 --- a/nixos/modules/services/monitoring/prometheus/alertmanager.nix +++ b/nixos/modules/services/monitoring/prometheus/alertmanager.nix @@ -106,7 +106,8 @@ in { type = types.str; default = ""; description = '' - Address to listen on for the web interface and API. + Address to listen on for the web interface and API. Empty string will listen on all interfaces. + "localhost" will listen on 127.0.0.1 (but not ::1). ''; }; diff --git a/nixos/modules/services/network-filesystems/openafs/client.nix b/nixos/modules/services/network-filesystems/openafs/client.nix index 93d2d7fcd97..79c4b7aee06 100644 --- a/nixos/modules/services/network-filesystems/openafs/client.nix +++ b/nixos/modules/services/network-filesystems/openafs/client.nix @@ -155,7 +155,7 @@ in }; programs = mkOption { default = getBin pkgs.openafs; - defaultText = "config.boot.kernelPackages.openafs"; + defaultText = "getBin pkgs.openafs"; type = types.package; description = "OpenAFS programs package. MUST match the kernel module package!"; }; diff --git a/nixos/modules/services/networking/coredns.nix b/nixos/modules/services/networking/coredns.nix new file mode 100644 index 00000000000..afb2b547a46 --- /dev/null +++ b/nixos/modules/services/networking/coredns.nix @@ -0,0 +1,50 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + cfg = config.services.coredns; + configFile = pkgs.writeText "Corefile" cfg.config; +in { + options.services.coredns = { + enable = mkEnableOption "Coredns dns server"; + + config = mkOption { + default = ""; + example = '' + . { + whoami + } + ''; + type = types.lines; + description = "Verbatim Corefile to use. See <link xlink:href=\"https://coredns.io/manual/toc/#configuration\"/> for details."; + }; + + package = mkOption { + default = pkgs.coredns; + defaultText = "pkgs.coredns"; + type = types.package; + description = "Coredns package to use."; + }; + }; + + config = mkIf cfg.enable { + systemd.services.coredns = { + description = "Coredns dns server"; + after = [ "network.target" ]; + wantedBy = [ "multi-user.target" ]; + serviceConfig = { + PermissionsStartOnly = true; + LimitNPROC = 512; + LimitNOFILE = 1048576; + CapabilityBoundingSet = "cap_net_bind_service"; + AmbientCapabilities = "cap_net_bind_service"; + NoNewPrivileges = true; + DynamicUser = true; + ExecStart = "${getBin cfg.package}/bin/coredns -conf=${configFile}"; + ExecReload = "${pkgs.coreutils}/bin/kill -SIGUSR1 $MAINPID"; + Restart = "on-failure"; + }; + }; + }; +} diff --git a/nixos/modules/services/networking/gnunet.nix b/nixos/modules/services/networking/gnunet.nix index 6a1db81413c..178a832c166 100644 --- a/nixos/modules/services/networking/gnunet.nix +++ b/nixos/modules/services/networking/gnunet.nix @@ -130,7 +130,7 @@ in group = "gnunet"; description = "GNUnet User"; home = homeDir; - createHome = true; + createHome = true; uid = config.ids.uids.gnunet; }; @@ -146,7 +146,7 @@ in wantedBy = [ "multi-user.target" ]; path = [ cfg.package pkgs.miniupnpc ]; environment.TMPDIR = "/tmp"; - serviceConfig.PrivateTemp = true; + serviceConfig.PrivateTmp = true; serviceConfig.ExecStart = "${cfg.package}/lib/gnunet/libexec/gnunet-service-arm -c ${configFile}"; serviceConfig.User = "gnunet"; serviceConfig.UMask = "0007"; diff --git a/nixos/modules/services/networking/mosquitto.nix b/nixos/modules/services/networking/mosquitto.nix index 332dc541345..9974cbd89d1 100644 --- a/nixos/modules/services/networking/mosquitto.nix +++ b/nixos/modules/services/networking/mosquitto.nix @@ -17,7 +17,6 @@ let ''; mosquittoConf = pkgs.writeText "mosquitto.conf" '' - pid_file /run/mosquitto/pid acl_file ${aclFile} persistence true allow_anonymous ${boolToString cfg.allowAnonymous} @@ -196,15 +195,15 @@ in wantedBy = [ "multi-user.target" ]; after = [ "network.target" ]; serviceConfig = { - Type = "forking"; + Type = "notify"; + NotifyAccess = "main"; User = "mosquitto"; Group = "mosquitto"; RuntimeDirectory = "mosquitto"; WorkingDirectory = cfg.dataDir; Restart = "on-failure"; - ExecStart = "${pkgs.mosquitto}/bin/mosquitto -c ${mosquittoConf} -d"; + ExecStart = "${pkgs.mosquitto}/bin/mosquitto -c ${mosquittoConf}"; ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID"; - PIDFile = "/run/mosquitto/pid"; }; preStart = '' rm -f ${cfg.dataDir}/passwd @@ -214,7 +213,7 @@ in if c.hashedPassword != null then "echo '${n}:${c.hashedPassword}' >> ${cfg.dataDir}/passwd" else optionalString (c.password != null) - "${pkgs.mosquitto}/bin/mosquitto_passwd -b ${cfg.dataDir}/passwd ${n} ${c.password}" + "${pkgs.mosquitto}/bin/mosquitto_passwd -b ${cfg.dataDir}/passwd ${n} '${c.password}'" ) cfg.users); }; diff --git a/nixos/modules/services/networking/ssh/sshd.nix b/nixos/modules/services/networking/ssh/sshd.nix index 95dc8a62a45..b9b5d40c457 100644 --- a/nixos/modules/services/networking/ssh/sshd.nix +++ b/nixos/modules/services/networking/ssh/sshd.nix @@ -400,7 +400,10 @@ in sockets.sshd = { description = "SSH Socket"; wantedBy = [ "sockets.target" ]; - socketConfig.ListenStream = cfg.ports; + socketConfig.ListenStream = if cfg.listenAddresses != [] then + map (l: "${l.addr}:${toString (if l.port != null then l.port else 22)}") cfg.listenAddresses + else + cfg.ports; socketConfig.Accept = true; }; diff --git a/nixos/modules/services/networking/strongswan-swanctl/module.nix b/nixos/modules/services/networking/strongswan-swanctl/module.nix index d770094960b..817b5ec55f7 100644 --- a/nixos/modules/services/networking/strongswan-swanctl/module.nix +++ b/nixos/modules/services/networking/strongswan-swanctl/module.nix @@ -65,9 +65,12 @@ in { after = [ "network-online.target" "keys.target" ]; wants = [ "keys.target" ]; path = with pkgs; [ kmod iproute iptables utillinux ]; - environment.STRONGSWAN_CONF = pkgs.writeTextFile { - name = "strongswan.conf"; - text = cfg.strongswan.extraConfig; + environment = { + STRONGSWAN_CONF = pkgs.writeTextFile { + name = "strongswan.conf"; + text = cfg.strongswan.extraConfig; + }; + SWANCTL_DIR = "/etc/swanctl"; }; restartTriggers = [ config.environment.etc."swanctl/swanctl.conf".source ]; serviceConfig = { diff --git a/nixos/modules/services/web-apps/icingaweb2/icingaweb2.nix b/nixos/modules/services/web-apps/icingaweb2/icingaweb2.nix index ccaa2cff1c2..50775c5262f 100644 --- a/nixos/modules/services/web-apps/icingaweb2/icingaweb2.nix +++ b/nixos/modules/services/web-apps/icingaweb2/icingaweb2.nix @@ -546,26 +546,26 @@ in { config = mkIf cfg.enable { services.phpfpm.poolConfigs = mkIf (cfg.pool == "${poolName}") { - "${poolName}" = '' - listen = "${phpfpmSocketName}" - listen.owner = nginx - listen.group = nginx - listen.mode = 0600 - user = icingaweb2 - pm = dynamic - pm.max_children = 75 - pm.start_servers = 2 - pm.min_spare_servers = 2 - pm.max_spare_servers = 10 - ''; + "${poolName}" = { + listen = phpfpmSocketName; + phpOptions = '' + extension = ${pkgs.phpPackages.imagick}/lib/php/extensions/imagick.so + date.timezone = "${cfg.timezone}" + ''; + extraConfig = '' + listen.owner = nginx + listen.group = nginx + listen.mode = 0600 + user = icingaweb2 + pm = dynamic + pm.max_children = 75 + pm.start_servers = 2 + pm.min_spare_servers = 2 + pm.max_spare_servers = 10 + ''; + }; }; - services.phpfpm.phpOptions = mkIf (cfg.pool == "${poolName}") - '' - extension = ${pkgs.phpPackages.imagick}/lib/php/extensions/imagick.so - date.timezone = "${cfg.timezone}" - ''; - systemd.services."phpfpm-${poolName}".serviceConfig.ReadWritePaths = [ "/etc/icingaweb2" ]; services.nginx = { diff --git a/nixos/modules/services/web-apps/nextcloud.nix b/nixos/modules/services/web-apps/nextcloud.nix index ee1354d6a99..5ad241ace5c 100644 --- a/nixos/modules/services/web-apps/nextcloud.nix +++ b/nixos/modules/services/web-apps/nextcloud.nix @@ -5,14 +5,18 @@ with lib; let cfg = config.services.nextcloud; + phpPackage = pkgs.php73; + phpPackages = pkgs.php73Packages; + toKeyValue = generators.toKeyValue { mkKeyValue = generators.mkKeyValueDefault {} " = "; }; phpOptionsExtensions = '' - ${optionalString cfg.caching.apcu "extension=${cfg.phpPackages.apcu}/lib/php/extensions/apcu.so"} - ${optionalString cfg.caching.redis "extension=${cfg.phpPackages.redis}/lib/php/extensions/redis.so"} - ${optionalString cfg.caching.memcached "extension=${cfg.phpPackages.memcached}/lib/php/extensions/memcached.so"} + ${optionalString cfg.caching.apcu "extension=${phpPackages.apcu}/lib/php/extensions/apcu.so"} + ${optionalString cfg.caching.redis "extension=${phpPackages.redis}/lib/php/extensions/redis.so"} + ${optionalString cfg.caching.memcached "extension=${phpPackages.memcached}/lib/php/extensions/memcached.so"} + extension=${phpPackages.imagick}/lib/php/extensions/imagick.so zend_extension = opcache.so opcache.enable = 1 ''; @@ -45,6 +49,11 @@ in { default = "/var/lib/nextcloud"; description = "Storage path of nextcloud."; }; + logLevel = mkOption { + type = types.ints.between 0 4; + default = 2; + description = "Log level value between 0 (DEBUG) and 4 (FATAL)."; + }; https = mkOption { type = types.bool; default = false; @@ -89,18 +98,6 @@ in { ''; }; - phpPackages = mkOption { - type = types.attrs; - default = pkgs.php71Packages; - defaultText = "pkgs.php71Packages"; - description = '' - Overridable attribute of the PHP packages set to use. If any caching - module is enabled, it will be taken from here. Therefore it should - match the version of PHP given to - <literal>services.phpfpm.phpPackage</literal>. - ''; - }; - phpOptions = mkOption { type = types.attrsOf types.str; default = { @@ -218,6 +215,19 @@ in { <literal>services.nextcloud.hostname</literal> here. ''; }; + + overwriteProtocol = mkOption { + type = types.nullOr (types.enum [ "http" "https" ]); + default = null; + example = "https"; + + description = '' + Force Nextcloud to always use HTTPS i.e. for link generation. Nextcloud + uses the currently used protocol by default, but when behind a reverse-proxy, + it may use <literal>http</literal> for everything although Nextcloud + may be served via HTTPS. + ''; + }; }; caching = { @@ -281,6 +291,8 @@ in { 'skeletondirectory' => '${cfg.skeletonDirectory}', ${optionalString cfg.caching.apcu "'memcache.local' => '\\OC\\Memcache\\APCu',"} 'log_type' => 'syslog', + 'log_level' => '${builtins.toString cfg.logLevel}', + ${optionalString (cfg.config.overwriteProtocol != null) "'overwriteprotocol' => '${cfg.config.overwriteProtocol}',"} ]; ''; occInstallCmd = let @@ -353,14 +365,14 @@ in { }; services.phpfpm = { - phpOptions = phpOptionsExtensions; - phpPackage = pkgs.php71; pools.nextcloud = let phpAdminValues = (toKeyValue (foldr (a: b: a // b) {} (mapAttrsToList (k: v: { "php_admin_value[${k}]" = v; }) phpOptions))); in { + phpOptions = phpOptionsExtensions; + phpPackage = phpPackage; listen = "/run/phpfpm/nextcloud"; extraConfig = '' listen.owner = nginx @@ -401,7 +413,7 @@ in { }; "/" = { priority = 200; - extraConfig = "rewrite ^ /index.php$uri;"; + extraConfig = "rewrite ^ /index.php$request_uri;"; }; "~ ^/store-apps" = { priority = 201; @@ -415,19 +427,19 @@ in { priority = 210; extraConfig = "return 301 $scheme://$host/remote.php/dav;"; }; - "~ ^/(?:build|tests|config|lib|3rdparty|templates|data)/" = { + "~ ^\\/(?:build|tests|config|lib|3rdparty|templates|data)\\/" = { priority = 300; extraConfig = "deny all;"; }; - "~ ^/(?:\\.|autotest|occ|issue|indie|db_|console)" = { + "~ ^\\/(?:\\.|autotest|occ|issue|indie|db_|console)" = { priority = 300; extraConfig = "deny all;"; }; - "~ ^/(?:index|remote|public|cron|core/ajax/update|status|ocs/v[12]|updater/.+|ocs-provider/.+)\\.php(?:$|/)" = { + "~ ^\\/(?:index|remote|public|cron|core/ajax\\/update|status|ocs\\/v[12]|updater\\/.+|ocs-provider\\/.+|ocm-provider\\/.+)\\.php(?:$|\\/)" = { priority = 500; extraConfig = '' include ${config.services.nginx.package}/conf/fastcgi.conf; - fastcgi_split_path_info ^(.+\.php)(/.*)$; + fastcgi_split_path_info ^(.+\.php)(\\/.*)$; fastcgi_param PATH_INFO $fastcgi_path_info; fastcgi_param HTTPS ${if cfg.https then "on" else "off"}; fastcgi_param modHeadersAvailable true; @@ -438,22 +450,23 @@ in { fastcgi_read_timeout 120s; ''; }; - "~ ^/(?:updater|ocs-provider)(?:$|/)".extraConfig = '' + "~ ^\\/(?:updater|ocs-provider|ocm-provider)(?:$|\\/)".extraConfig = '' try_files $uri/ =404; index index.php; ''; - "~ \\.(?:css|js|woff|svg|gif)$".extraConfig = '' - try_files $uri /index.php$uri$is_args$args; + "~ \\.(?:css|js|woff2?|svg|gif)$".extraConfig = '' + try_files $uri /index.php$request_uri; add_header Cache-Control "public, max-age=15778463"; add_header X-Content-Type-Options nosniff; add_header X-XSS-Protection "1; mode=block"; add_header X-Robots-Tag none; add_header X-Download-Options noopen; add_header X-Permitted-Cross-Domain-Policies none; + add_header Referrer-Policy no-referrer; access_log off; ''; "~ \\.(?:png|html|ttf|ico|jpg|jpeg)$".extraConfig = '' - try_files $uri /index.php$uri$is_args$args; + try_files $uri /index.php$request_uri; access_log off; ''; }; @@ -463,10 +476,12 @@ in { add_header X-Robots-Tag none; add_header X-Download-Options noopen; add_header X-Permitted-Cross-Domain-Policies none; + add_header Referrer-Policy no-referrer; error_page 403 /core/templates/403.php; error_page 404 /core/templates/404.php; client_max_body_size ${cfg.maxUploadSize}; fastcgi_buffers 64 4K; + fastcgi_hide_header X-Powered-By; gzip on; gzip_vary on; gzip_comp_level 4; diff --git a/nixos/modules/services/web-apps/restya-board.nix b/nixos/modules/services/web-apps/restya-board.nix index bc6689bdb27..b064eae248e 100644 --- a/nixos/modules/services/web-apps/restya-board.nix +++ b/nixos/modules/services/web-apps/restya-board.nix @@ -179,34 +179,35 @@ in config = mkIf cfg.enable { services.phpfpm.poolConfigs = { - "${poolName}" = '' - listen = "${phpfpmSocketName}"; - listen.owner = nginx - listen.group = nginx - listen.mode = 0600 - user = ${cfg.user} - group = ${cfg.group} - pm = dynamic - pm.max_children = 75 - pm.start_servers = 10 - pm.min_spare_servers = 5 - pm.max_spare_servers = 20 - pm.max_requests = 500 - catch_workers_output = 1 - ''; + "${poolName}" = { + listen = phpfpmSocketName; + phpOptions = '' + date.timezone = "CET" + + ${optionalString (!isNull cfg.email.server) '' + SMTP = ${cfg.email.server} + smtp_port = ${toString cfg.email.port} + auth_username = ${cfg.email.login} + auth_password = ${cfg.email.password} + ''} + ''; + extraConfig = '' + listen.owner = nginx + listen.group = nginx + listen.mode = 0600 + user = ${cfg.user} + group = ${cfg.group} + pm = dynamic + pm.max_children = 75 + pm.start_servers = 10 + pm.min_spare_servers = 5 + pm.max_spare_servers = 20 + pm.max_requests = 500 + catch_workers_output = 1 + ''; + }; }; - services.phpfpm.phpOptions = '' - date.timezone = "CET" - - ${optionalString (!isNull cfg.email.server) '' - SMTP = ${cfg.email.server} - smtp_port = ${toString cfg.email.port} - auth_username = ${cfg.email.login} - auth_password = ${cfg.email.password} - ''} - ''; - services.nginx.enable = true; services.nginx.virtualHosts."${cfg.virtualHost.serverName}" = { listen = [ { addr = cfg.virtualHost.listenHost; port = cfg.virtualHost.listenPort; } ]; diff --git a/nixos/modules/services/web-apps/youtrack.nix b/nixos/modules/services/web-apps/youtrack.nix index 6ad38028a64..691cbdc8d1d 100644 --- a/nixos/modules/services/web-apps/youtrack.nix +++ b/nixos/modules/services/web-apps/youtrack.nix @@ -121,6 +121,7 @@ in environment.YOUTRACK_JVM_OPTS = "${extraAttr}"; after = [ "network.target" ]; wantedBy = [ "multi-user.target" ]; + path = with pkgs; [ unixtools.hostname ]; serviceConfig = { Type = "simple"; User = "youtrack"; diff --git a/nixos/modules/services/web-servers/nginx/default.nix b/nixos/modules/services/web-servers/nginx/default.nix index 89dc8b3795e..1c9fbe048f8 100644 --- a/nixos/modules/services/web-servers/nginx/default.nix +++ b/nixos/modules/services/web-servers/nginx/default.nix @@ -44,7 +44,7 @@ let } '')); - awkFormat = pkgs.writeText "awkFormat-nginx.awk" '' + awkFormat = builtins.toFile "awkFormat-nginx.awk" '' awk -f {sub(/^[ \t]+/,"");idx=0} /\{/{ctx++;idx=1} @@ -52,15 +52,9 @@ let {id="";for(i=idx;i<ctx;i++)id=sprintf("%s%s", id, "\t");printf "%s%s\n", id, $0} ''; - configFile = pkgs.stdenv.mkDerivation { - name = "nginx-config"; - src = ""; - phases = [ "installPhase" ]; - installPhase = '' - mkdir $out - awk -f ${awkFormat} ${pre-configFile} | sed '/^\s*$/d' > $out/nginx.conf - ''; - }; + configFile = pkgs.runCommand "nginx.conf" {} ('' + awk -f ${awkFormat} ${pre-configFile} | sed '/^\s*$/d' > $out + ''); pre-configFile = pkgs.writeText "pre-nginx.conf" '' user ${cfg.user} ${cfg.group}; @@ -200,11 +194,12 @@ let then filter (x: x.ssl) defaultListen else defaultListen; - listenString = { addr, port, ssl, ... }: + listenString = { addr, port, ssl, extraParameters ? [], ... }: "listen ${addr}:${toString port} " + optionalString ssl "ssl " + optionalString (ssl && vhost.http2) "http2 " + optionalString vhost.default "default_server " + + optionalString (extraParameters != []) (concatStringsSep " " extraParameters) + ";"; redirectListen = filter (x: !x.ssl) defaultListen; @@ -497,8 +492,8 @@ in sslProtocols = mkOption { type = types.str; - default = "TLSv1.2"; - example = "TLSv1 TLSv1.1 TLSv1.2"; + default = "TLSv1.2 TLSv1.3"; + example = "TLSv1 TLSv1.1 TLSv1.2 TLSv1.3"; description = "Allowed TLS protocol versions."; }; @@ -656,10 +651,10 @@ in preStart = '' ${cfg.preStart} - ${cfg.package}/bin/nginx -c ${configFile}/nginx.conf -p ${cfg.stateDir} -t + ${cfg.package}/bin/nginx -c ${configFile} -p ${cfg.stateDir} -t ''; serviceConfig = { - ExecStart = "${cfg.package}/bin/nginx -c ${configFile}/nginx.conf -p ${cfg.stateDir}"; + ExecStart = "${cfg.package}/bin/nginx -c ${configFile} -p ${cfg.stateDir}"; ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID"; Restart = "always"; RestartSec = "10s"; diff --git a/nixos/modules/services/web-servers/nginx/vhost-options.nix b/nixos/modules/services/web-servers/nginx/vhost-options.nix index 6a50d8ed5cd..15b933c984a 100644 --- a/nixos/modules/services/web-servers/nginx/vhost-options.nix +++ b/nixos/modules/services/web-servers/nginx/vhost-options.nix @@ -31,6 +31,7 @@ with lib; addr = mkOption { type = str; description = "IP address."; }; port = mkOption { type = int; description = "Port number."; default = 80; }; ssl = mkOption { type = bool; description = "Enable SSL."; default = false; }; + extraParameters = mkOption { type = listOf str; description = "Extra parameters of this listen directive."; default = []; example = [ "reuseport" "deferred" ]; }; }; }); default = []; example = [ diff --git a/nixos/modules/services/x11/desktop-managers/gnome3.nix b/nixos/modules/services/x11/desktop-managers/gnome3.nix index 6255dce8276..ea01749349d 100644 --- a/nixos/modules/services/x11/desktop-managers/gnome3.nix +++ b/nixos/modules/services/x11/desktop-managers/gnome3.nix @@ -133,6 +133,7 @@ in { services.gnome3.gnome-keyring.enable = true; services.gnome3.gnome-online-accounts.enable = mkDefault true; services.gnome3.gnome-remote-desktop.enable = mkDefault true; + services.gnome3.gnome-settings-daemon.enable = true; services.gnome3.gnome-terminal-server.enable = mkDefault true; services.gnome3.gnome-user-share.enable = mkDefault true; services.gnome3.gvfs.enable = true; @@ -153,7 +154,6 @@ in { hardware.bluetooth.enable = mkDefault true; services.hardware.bolt.enable = mkDefault true; services.xserver.libinput.enable = mkDefault true; # for controlling touchpad settings via gnome control center - services.udev.packages = [ pkgs.gnome3.gnome-settings-daemon ]; systemd.packages = [ pkgs.gnome3.vino ]; services.flatpak.extraPortals = [ pkgs.xdg-desktop-portal-gtk ]; diff --git a/nixos/modules/services/x11/desktop-managers/mate.nix b/nixos/modules/services/x11/desktop-managers/mate.nix index 4d2fafd1496..bf6685ff7ea 100644 --- a/nixos/modules/services/x11/desktop-managers/mate.nix +++ b/nixos/modules/services/x11/desktop-managers/mate.nix @@ -56,9 +56,6 @@ in export XDG_MENU_PREFIX=mate- - # Find the mouse - export XCURSOR_PATH=~/.icons:${config.system.path}/share/icons - # Let caja find extensions export CAJA_EXTENSION_DIRS=$CAJA_EXTENSION_DIRS''${CAJA_EXTENSION_DIRS:+:}${config.system.path}/lib/caja/extensions-2.0 @@ -78,9 +75,6 @@ in # Add mate-control-center paths to some XDG variables because its schemas are needed by mate-settings-daemon, and mate-settings-daemon is a dependency for mate-control-center (that is, they are mutually recursive) ${addToXDGDirs pkgs.mate.mate-control-center} - # Update user dirs as described in http://freedesktop.org/wiki/Software/xdg-user-dirs/ - ${pkgs.xdg-user-dirs}/bin/xdg-user-dirs-update - ${pkgs.mate.mate-session-manager}/bin/mate-session ${optionalString cfg.debug "--debug"} & waitPID=$! ''; @@ -90,18 +84,27 @@ in pkgs.mate.basePackages ++ (pkgs.gnome3.removePackagesByName pkgs.mate.extraPackages - config.environment.mate.excludePackages); - - services.dbus.packages = [ - pkgs.gnome3.dconf - pkgs.at-spi2-core - ]; - + config.environment.mate.excludePackages) ++ + [ + pkgs.desktop-file-utils + pkgs.glib + pkgs.gtk3.out + pkgs.shared-mime-info + pkgs.xdg-user-dirs # Update user dirs as described in https://freedesktop.org/wiki/Software/xdg-user-dirs/ + ]; + + programs.dconf.enable = true; + services.gnome3.at-spi2-core.enable = true; services.gnome3.gnome-keyring.enable = true; + services.gnome3.gnome-settings-daemon.enable = true; + services.gnome3.gnome-settings-daemon.package = pkgs.mate.mate-settings-daemon; + services.gnome3.gvfs.enable = true; services.upower.enable = config.powerManagement.enable; security.pam.services."mate-screensaver".unixAuth = true; + environment.variables.GIO_EXTRA_MODULES = [ "${pkgs.gnome3.gvfs}/lib/gio/modules" ]; + environment.pathsToLink = [ "/share" ]; }; diff --git a/nixos/modules/services/x11/desktop-managers/pantheon.nix b/nixos/modules/services/x11/desktop-managers/pantheon.nix index 0f49439bf7c..31bbbd55829 100644 --- a/nixos/modules/services/x11/desktop-managers/pantheon.nix +++ b/nixos/modules/services/x11/desktop-managers/pantheon.nix @@ -117,11 +117,12 @@ in services.gnome3.file-roller.enable = true; # TODO: gnome-keyring's xdg autostarts will still be in the environment (from elementary-session-settings) if disabled forcefully services.gnome3.gnome-keyring.enable = true; + services.gnome3.gnome-settings-daemon.enable = true; + services.gnome3.gnome-settings-daemon.package = pkgs.pantheon.elementary-settings-daemon; services.gnome3.gvfs.enable = true; services.gnome3.rygel.enable = true; services.gsignond.enable = true; services.gsignond.plugins = with pkgs.gsignondPlugins; [ lastfm mail oauth ]; - services.udev.packages = [ pkgs.pantheon.elementary-settings-daemon ]; services.udisks2.enable = true; services.upower.enable = config.powerManagement.enable; services.xserver.libinput.enable = mkDefault true; diff --git a/nixos/modules/services/x11/desktop-managers/plasma5.nix b/nixos/modules/services/x11/desktop-managers/plasma5.nix index 704cc78c152..ace9dd5321b 100644 --- a/nixos/modules/services/x11/desktop-managers/plasma5.nix +++ b/nixos/modules/services/x11/desktop-managers/plasma5.nix @@ -163,6 +163,8 @@ in libsForQt56.phonon-backend-gstreamer libsForQt5.phonon-backend-gstreamer + + xdg-user-dirs # Update user dirs as described in https://freedesktop.org/wiki/Software/xdg-user-dirs/ ] ++ lib.optionals cfg.enableQt4Support [ pkgs.phonon-backend-gstreamer ] @@ -175,9 +177,9 @@ in ++ lib.optional config.services.colord.enable colord-kde ++ lib.optionals config.services.samba.enable [ kdenetwork-filesharing pkgs.samba ]; - environment.pathsToLink = [ + environment.pathsToLink = [ # FIXME: modules should link subdirs of `/share` rather than relying on this - "/share" + "/share" ]; environment.etc = singleton { diff --git a/nixos/modules/services/x11/desktop-managers/xfce.nix b/nixos/modules/services/x11/desktop-managers/xfce.nix index dabf09418da..6852154378d 100644 --- a/nixos/modules/services/x11/desktop-managers/xfce.nix +++ b/nixos/modules/services/x11/desktop-managers/xfce.nix @@ -53,7 +53,7 @@ in # Supplies some abstract icons such as: # utilities-terminal, accessories-text-editor - gnome3.defaultIconTheme + gnome3.adwaita-icon-theme hicolor-icon-theme tango-icon-theme diff --git a/nixos/modules/services/x11/display-managers/lightdm-greeters/gtk.nix b/nixos/modules/services/x11/display-managers/lightdm-greeters/gtk.nix index 772cc95e84e..5b280b02423 100644 --- a/nixos/modules/services/x11/display-managers/lightdm-greeters/gtk.nix +++ b/nixos/modules/services/x11/display-managers/lightdm-greeters/gtk.nix @@ -96,8 +96,8 @@ in package = mkOption { type = types.package; - default = pkgs.gnome3.defaultIconTheme; - defaultText = "pkgs.gnome3.defaultIconTheme"; + default = pkgs.gnome3.adwaita-icon-theme; + defaultText = "pkgs.gnome3.adwaita-icon-theme"; description = '' The package path that contains the icon theme given in the name option. ''; @@ -116,8 +116,8 @@ in cursorTheme = { package = mkOption { - default = pkgs.gnome3.defaultIconTheme; - defaultText = "pkgs.gnome3.defaultIconTheme"; + default = pkgs.gnome3.adwaita-icon-theme; + defaultText = "pkgs.gnome3.adwaita-icon-theme"; description = '' The package path that contains the cursor theme given in the name option. ''; diff --git a/nixos/modules/services/x11/xserver.nix b/nixos/modules/services/x11/xserver.nix index d84ab3ced6f..c4d5b6a9cde 100644 --- a/nixos/modules/services/x11/xserver.nix +++ b/nixos/modules/services/x11/xserver.nix @@ -61,7 +61,9 @@ let ''; description = '' Extra lines to append to the <literal>Monitor</literal> section - verbatim. + verbatim. Available options are documented in the MONITOR section in + <citerefentry><refentrytitle>xorg.conf</refentrytitle> + <manvolnum>5</manvolnum></citerefentry>. ''; }; }; @@ -633,7 +635,7 @@ in environment.pathsToLink = [ "/share/X11" ]; - xdg = { + xdg = { autostart.enable = true; menus.enable = true; mime.enable = true; diff --git a/nixos/modules/system/activation/top-level.nix b/nixos/modules/system/activation/top-level.nix index a560af5ce96..5c88d27b6c6 100644 --- a/nixos/modules/system/activation/top-level.nix +++ b/nixos/modules/system/activation/top-level.nix @@ -130,11 +130,9 @@ let failedAssertions = map (x: x.message) (filter (x: !x.assertion) config.assertions); - showWarnings = res: fold (w: x: builtins.trace "[1;31mwarning: ${w}[0m" x) res config.warnings; - baseSystemAssertWarn = if failedAssertions != [] then throw "\nFailed assertions:\n${concatStringsSep "\n" (map (x: "- ${x}") failedAssertions)}" - else showWarnings baseSystem; + else showWarnings config.warnings baseSystem; # Replace runtime dependencies system = fold ({ oldDependency, newDependency }: drv: diff --git a/nixos/modules/system/etc/make-etc.sh b/nixos/modules/system/etc/make-etc.sh index 9c0520e92fc..1ca4c3046f0 100644 --- a/nixos/modules/system/etc/make-etc.sh +++ b/nixos/modules/system/etc/make-etc.sh @@ -10,11 +10,6 @@ users_=($users) groups_=($groups) set +f -# Create relative symlinks, so that the links can be followed if -# the NixOS installation is not mounted as filesystem root. -# Absolute symlinks violate the os-release format -# at https://www.freedesktop.org/software/systemd/man/os-release.html -# and break e.g. systemd-nspawn and os-prober. for ((i = 0; i < ${#targets_[@]}; i++)); do source="${sources_[$i]}" target="${targets_[$i]}" @@ -24,14 +19,14 @@ for ((i = 0; i < ${#targets_[@]}; i++)); do # If the source name contains '*', perform globbing. mkdir -p $out/etc/$target for fn in $source; do - ln -s --relative "$fn" $out/etc/$target/ + ln -s "$fn" $out/etc/$target/ done else - + mkdir -p $out/etc/$(dirname $target) if ! [ -e $out/etc/$target ]; then - ln -s --relative $source $out/etc/$target + ln -s $source $out/etc/$target else echo "duplicate entry $target -> $source" if test "$(readlink $out/etc/$target)" != "$source"; then @@ -39,13 +34,13 @@ for ((i = 0; i < ${#targets_[@]}; i++)); do exit 1 fi fi - + if test "${modes_[$i]}" != symlink; then echo "${modes_[$i]}" > $out/etc/$target.mode echo "${users_[$i]}" > $out/etc/$target.uid echo "${groups_[$i]}" > $out/etc/$target.gid fi - + fi done diff --git a/nixos/modules/system/etc/setup-etc.pl b/nixos/modules/system/etc/setup-etc.pl index 82ef49a2a27..eed20065087 100644 --- a/nixos/modules/system/etc/setup-etc.pl +++ b/nixos/modules/system/etc/setup-etc.pl @@ -4,7 +4,6 @@ use File::Copy; use File::Path; use File::Basename; use File::Slurp; -use File::Spec; my $etc = $ARGV[0] or die; my $static = "/etc/static"; @@ -18,20 +17,6 @@ sub atomicSymlink { return 1; } -# Create relative symlinks, so that the links can be followed if -# the NixOS installation is not mounted as filesystem root. -# Absolute symlinks violate the os-release format -# at https://www.freedesktop.org/software/systemd/man/os-release.html -# and break e.g. systemd-nspawn and os-prober. -sub atomicRelativeSymlink { - my ($source, $target) = @_; - my $tmp = "$target.tmp"; - unlink $tmp; - my $rel = File::Spec->abs2rel($source, dirname $target); - symlink $rel, $tmp or return 0; - rename $tmp, $target or return 0; - return 1; -} # Atomically update /etc/static to point at the etc files of the # current configuration. @@ -118,7 +103,7 @@ sub link { if (-e "$_.mode") { my $mode = read_file("$_.mode"); chomp $mode; if ($mode eq "direct-symlink") { - atomicRelativeSymlink readlink("$static/$fn"), $target or warn; + atomicSymlink readlink("$static/$fn"), $target or warn; } else { my $uid = read_file("$_.uid"); chomp $uid; my $gid = read_file("$_.gid"); chomp $gid; @@ -132,7 +117,7 @@ sub link { push @copied, $fn; print CLEAN "$fn\n"; } elsif (-l "$_") { - atomicRelativeSymlink "$static/$fn", $target or warn; + atomicSymlink "$static/$fn", $target or warn; } } diff --git a/nixos/modules/tasks/auto-upgrade.nix b/nixos/modules/tasks/auto-upgrade.nix index d225778a387..91f4ae79ee9 100644 --- a/nixos/modules/tasks/auto-upgrade.nix +++ b/nixos/modules/tasks/auto-upgrade.nix @@ -57,7 +57,7 @@ let cfg = config.system.autoUpgrade; in }; - config = { + config = lib.mkIf cfg.enable { system.autoUpgrade.flags = [ "--no-build-output" ] @@ -84,7 +84,7 @@ let cfg = config.system.autoUpgrade; in ${config.system.build.nixos-rebuild}/bin/nixos-rebuild switch ${toString cfg.flags} ''; - startAt = optional cfg.enable cfg.dates; + startAt = cfg.dates; }; }; diff --git a/nixos/modules/virtualisation/docker.nix b/nixos/modules/virtualisation/docker.nix index a1a32c1c59a..4ee84c5268e 100644 --- a/nixos/modules/virtualisation/docker.nix +++ b/nixos/modules/virtualisation/docker.nix @@ -52,6 +52,15 @@ in ''; }; + enableNvidia = + mkOption { + type = types.bool; + default = false; + description = '' + Enable nvidia-docker wrapper, supporting NVIDIA GPUs inside docker containers. + ''; + }; + liveRestore = mkOption { type = types.bool; @@ -140,7 +149,8 @@ in ###### implementation config = mkIf cfg.enable (mkMerge [{ - environment.systemPackages = [ cfg.package ]; + environment.systemPackages = [ cfg.package ] + ++ optional cfg.enableNvidia pkgs.nvidia-docker; users.groups.docker.gid = config.ids.gids.docker; systemd.packages = [ cfg.package ]; @@ -157,6 +167,7 @@ in --log-driver=${cfg.logDriver} \ ${optionalString (cfg.storageDriver != null) "--storage-driver=${cfg.storageDriver}"} \ ${optionalString cfg.liveRestore "--live-restore" } \ + ${optionalString cfg.enableNvidia "--add-runtime nvidia=${pkgs.nvidia-docker}/bin/nvidia-container-runtime" } \ ${cfg.extraOptions} '']; ExecReload=[ @@ -165,7 +176,8 @@ in ]; }; - path = [ pkgs.kmod ] ++ (optional (cfg.storageDriver == "zfs") pkgs.zfs); + path = [ pkgs.kmod ] ++ optional (cfg.storageDriver == "zfs") pkgs.zfs + ++ optional cfg.enableNvidia pkgs.nvidia-docker; }; systemd.sockets.docker = { @@ -179,7 +191,6 @@ in }; }; - systemd.services.docker-prune = { description = "Prune docker resources"; @@ -194,7 +205,15 @@ in startAt = optional cfg.autoPrune.enable cfg.autoPrune.dates; }; + + assertions = [ + { assertion = cfg.enableNvidia -> config.hardware.opengl.driSupport32Bit or false; + message = "Option enableNvidia requires 32bit support libraries"; + }]; } + (mkIf cfg.enableNvidia { + environment.etc."nvidia-container-runtime/config.toml".source = "${pkgs.nvidia-docker}/etc/config.toml"; + }) ]); imports = [ diff --git a/nixos/tests/all-tests.nix b/nixos/tests/all-tests.nix index 65227857a38..2ddb54bcc3d 100644 --- a/nixos/tests/all-tests.nix +++ b/nixos/tests/all-tests.nix @@ -74,6 +74,7 @@ in ferm = handleTest ./ferm.nix {}; firefox = handleTest ./firefox.nix {}; firewall = handleTest ./firewall.nix {}; + fish = handleTest ./fish.nix {}; flannel = handleTestOn ["x86_64-linux"] ./flannel.nix {}; flatpak = handleTest ./flatpak.nix {}; fsck = handleTest ./fsck.nix {}; diff --git a/nixos/tests/docker-tools.nix b/nixos/tests/docker-tools.nix index 58f106314ab..399e4d4e428 100644 --- a/nixos/tests/docker-tools.nix +++ b/nixos/tests/docker-tools.nix @@ -34,8 +34,8 @@ import ./make-test.nix ({ pkgs, ... }: { # To test the pullImage tool $docker->succeed("docker load --input='${pkgs.dockerTools.examples.nixFromDockerHub}'"); - $docker->succeed("docker run --rm nixos/nix:1.11 nix-store --version"); - $docker->succeed("docker rmi nixos/nix:1.11"); + $docker->succeed("docker run --rm nixos/nix:2.2.1 nix-store --version"); + $docker->succeed("docker rmi nixos/nix:2.2.1"); # To test runAsRoot and entry point $docker->succeed("docker load --input='${pkgs.dockerTools.examples.nginx}'"); diff --git a/nixos/tests/fish.nix b/nixos/tests/fish.nix new file mode 100644 index 00000000000..97c4e8e37ac --- /dev/null +++ b/nixos/tests/fish.nix @@ -0,0 +1,21 @@ +import ./make-test.nix ({ pkgs, ... }: { + name = "fish"; + + machine = + { pkgs, ... }: + + { + programs.fish.enable = true; + environment.systemPackages = with pkgs; [ + coreutils + procps # kill collides with coreutils' to test https://github.com/NixOS/nixpkgs/issues/56432 + ]; + }; + + testScript = + '' + $machine->waitForFile("/etc/fish/generated_completions/coreutils.fish"); + $machine->waitForFile("/etc/fish/generated_completions/kill.fish"); + $machine->succeed("fish -ic 'echo \$fish_complete_path' | grep -q '/share/fish/completions /etc/fish/generated_completions /root/.local/share/fish/generated_completions\$'"); + ''; +}) diff --git a/nixos/tests/gitea.nix b/nixos/tests/gitea.nix index 28e6479e9cb..d43efc3687a 100644 --- a/nixos/tests/gitea.nix +++ b/nixos/tests/gitea.nix @@ -45,7 +45,7 @@ with pkgs.lib; { services.gitea.enable = true; services.gitea.database.type = "postgres"; - services.gitea.database.password = "secret"; + services.gitea.database.passwordFile = pkgs.writeText "db-password" "secret"; }; testScript = '' diff --git a/nixos/tests/installer.nix b/nixos/tests/installer.nix index 2553a0d116a..5e363f5d09e 100644 --- a/nixos/tests/installer.nix +++ b/nixos/tests/installer.nix @@ -273,6 +273,37 @@ let }; }; + makeLuksRootTest = name: luksFormatOpts: makeInstallerTest "luksroot-format2" + { createPartitions = '' + $machine->succeed( + "flock /dev/vda parted --script /dev/vda -- mklabel msdos" + . " mkpart primary ext2 1M 50MB" # /boot + . " mkpart primary linux-swap 50M 1024M" + . " mkpart primary 1024M -1s", # LUKS + "udevadm settle", + "mkswap /dev/vda2 -L swap", + "swapon -L swap", + "modprobe dm_mod dm_crypt", + "echo -n supersecret | cryptsetup luksFormat ${luksFormatOpts} -q /dev/vda3 -", + "echo -n supersecret | cryptsetup luksOpen --key-file - /dev/vda3 cryptroot", + "mkfs.ext3 -L nixos /dev/mapper/cryptroot", + "mount LABEL=nixos /mnt", + "mkfs.ext3 -L boot /dev/vda1", + "mkdir -p /mnt/boot", + "mount LABEL=boot /mnt/boot", + ); + ''; + extraConfig = '' + boot.kernelParams = lib.mkAfter [ "console=tty0" ]; + ''; + enableOCR = true; + preBootCommands = '' + $machine->start; + $machine->waitForText(qr/Passphrase for/); + $machine->sendChars("supersecret\n"); + ''; + }; + in { @@ -446,37 +477,14 @@ in { ''; }; - # Boot off an encrypted root partition - luksroot = makeInstallerTest "luksroot" - { createPartitions = '' - $machine->succeed( - "flock /dev/vda parted --script /dev/vda -- mklabel msdos" - . " mkpart primary ext2 1M 50MB" # /boot - . " mkpart primary linux-swap 50M 1024M" - . " mkpart primary 1024M -1s", # LUKS - "udevadm settle", - "mkswap /dev/vda2 -L swap", - "swapon -L swap", - "modprobe dm_mod dm_crypt", - "echo -n supersecret | cryptsetup luksFormat -q /dev/vda3 -", - "echo -n supersecret | cryptsetup luksOpen --key-file - /dev/vda3 cryptroot", - "mkfs.ext3 -L nixos /dev/mapper/cryptroot", - "mount LABEL=nixos /mnt", - "mkfs.ext3 -L boot /dev/vda1", - "mkdir -p /mnt/boot", - "mount LABEL=boot /mnt/boot", - ); - ''; - extraConfig = '' - boot.kernelParams = lib.mkAfter [ "console=tty0" ]; - ''; - enableOCR = true; - preBootCommands = '' - $machine->start; - $machine->waitForText(qr/Passphrase for/); - $machine->sendChars("supersecret\n"); - ''; - }; + # Boot off an encrypted root partition with the default LUKS header format + luksroot = makeLuksRootTest "luksroot-format1" ""; + + # Boot off an encrypted root partition with LUKS1 format + luksroot-format1 = makeLuksRootTest "luksroot-format1" "--type=LUKS1"; + + # Boot off an encrypted root partition with LUKS2 format + luksroot-format2 = makeLuksRootTest "luksroot-format2" "--type=LUKS2"; # Test whether opening encrypted filesystem with keyfile # Checks for regression of missing cryptsetup, when no luks device without diff --git a/nixos/tests/ndppd.nix b/nixos/tests/ndppd.nix index 9f24eb6d9d4..c53ff93a91f 100644 --- a/nixos/tests/ndppd.nix +++ b/nixos/tests/ndppd.nix @@ -37,8 +37,7 @@ import ./make-test.nix ({ pkgs, lib, ...} : { }; services.ndppd = { enable = true; - interface = "eth1"; - network = "fd42::/112"; + proxies."eth1".rules."fd42::/112" = {}; }; containers.client = { autoStart = true; diff --git a/nixos/tests/openssh.nix b/nixos/tests/openssh.nix index 219a20c5c7e..8b9e2170f15 100644 --- a/nixos/tests/openssh.nix +++ b/nixos/tests/openssh.nix @@ -34,6 +34,24 @@ in { ]; }; + server_localhost_only = + { ... }: + + { + services.openssh = { + enable = true; listenAddresses = [ { addr = "127.0.0.1"; port = 22; } ]; + }; + }; + + server_localhost_only_lazy = + { ... }: + + { + services.openssh = { + enable = true; startWhenNeeded = true; listenAddresses = [ { addr = "127.0.0.1"; port = 22; } ]; + }; + }; + client = { ... }: { }; @@ -77,5 +95,10 @@ in { " server_lazy true"); }; + + subtest "localhost-only", sub { + $server_localhost_only->succeed("ss -nlt | grep '127.0.0.1:22'"); + $server_localhost_only_lazy->succeed("ss -nlt | grep '127.0.0.1:22'"); + } ''; }) diff --git a/nixos/tests/rspamd.nix b/nixos/tests/rspamd.nix index 396cd5b67d8..0cc94728f80 100644 --- a/nixos/tests/rspamd.nix +++ b/nixos/tests/rspamd.nix @@ -52,8 +52,18 @@ in machine = { services.rspamd = { enable = true; - bindSocket = [ "/run/rspamd.sock mode=0600 user=root group=root" ]; - bindUISocket = [ "/run/rspamd-worker.sock mode=0666 user=root group=root" ]; + workers.normal.bindSockets = [{ + socket = "/run/rspamd.sock"; + mode = "0600"; + owner = "root"; + group = "root"; + }]; + workers.controller.bindSockets = [{ + socket = "/run/rspamd-worker.sock"; + mode = "0666"; + owner = "root"; + group = "root"; + }]; }; }; @@ -235,7 +245,7 @@ in services.rspamd = { enable = true; postfix.enable = true; - workers.rspamd_proxy.type = "proxy"; + workers.rspamd_proxy.type = "rspamd_proxy"; }; }; testScript = '' |