diff options
Diffstat (limited to 'nixos/modules')
115 files changed, 2953 insertions, 1676 deletions
diff --git a/nixos/modules/config/networking.nix b/nixos/modules/config/networking.nix index aab5523c6848..952f62569c93 100644 --- a/nixos/modules/config/networking.nix +++ b/nixos/modules/config/networking.nix @@ -232,7 +232,7 @@ in # and other configurations. If the file is destroyed by an environment # activation then it must be rebuilt so that applications which interface # with /etc/resolv.conf directly don't break. - system.activationScripts.resolvconf = stringAfter [ "etc" "tmpfs" "var" ] + system.activationScripts.resolvconf = stringAfter [ "etc" "specialfs" "var" ] '' # Systemd resolved controls its own resolv.conf rm -f /run/resolvconf/interfaces/systemd diff --git a/nixos/modules/config/users-groups.nix b/nixos/modules/config/users-groups.nix index d92deb85d2a5..57e4940378ba 100644 --- a/nixos/modules/config/users-groups.nix +++ b/nixos/modules/config/users-groups.nix @@ -131,13 +131,12 @@ let }; subUidRanges = mkOption { - type = types.listOf types.optionSet; + type = with types; listOf (submodule subordinateUidRange); default = []; example = [ { startUid = 1000; count = 1; } { startUid = 100001; count = 65534; } ]; - options = [ subordinateUidRange ]; description = '' Subordinate user ids that user is allowed to use. They are set into <filename>/etc/subuid</filename> and are used @@ -146,13 +145,12 @@ let }; subGidRanges = mkOption { - type = types.listOf types.optionSet; + type = with types; listOf (submodule subordinateGidRange); default = []; example = [ { startGid = 100; count = 1; } { startGid = 1001; count = 999; } ]; - options = [ subordinateGidRange ]; description = '' Subordinate group ids that user is allowed to use. They are set into <filename>/etc/subgid</filename> and are used @@ -310,32 +308,36 @@ let }; subordinateUidRange = { - startUid = mkOption { - type = types.int; - description = '' - Start of the range of subordinate user ids that user is - allowed to use. - ''; - }; - count = mkOption { - type = types.int; - default = 1; - description = ''Count of subordinate user ids''; + options = { + startUid = mkOption { + type = types.int; + description = '' + Start of the range of subordinate user ids that user is + allowed to use. + ''; + }; + count = mkOption { + type = types.int; + default = 1; + description = ''Count of subordinate user ids''; + }; }; }; subordinateGidRange = { - startGid = mkOption { - type = types.int; - description = '' - Start of the range of subordinate group ids that user is - allowed to use. - ''; - }; - count = mkOption { - type = types.int; - default = 1; - description = ''Count of subordinate group ids''; + options = { + startGid = mkOption { + type = types.int; + description = '' + Start of the range of subordinate group ids that user is + allowed to use. + ''; + }; + count = mkOption { + type = types.int; + default = 1; + description = ''Count of subordinate group ids''; + }; }; }; @@ -428,7 +430,7 @@ in { users.users = mkOption { default = {}; - type = types.loaOf types.optionSet; + type = with types; loaOf (submodule userOpts); example = { alice = { uid = 1234; @@ -444,7 +446,6 @@ in { Additional user accounts to be created automatically by the system. This can also be used to set options for root. ''; - options = [ userOpts ]; }; users.groups = mkOption { @@ -453,11 +454,10 @@ in { { students.gid = 1001; hackers = { }; }; - type = types.loaOf types.optionSet; + type = with types; loaOf (submodule groupOpts); description = '' Additional groups to be created automatically by the system. ''; - options = [ groupOpts ]; }; # FIXME: obsolete - will remove. diff --git a/nixos/modules/hardware/opengl.nix b/nixos/modules/hardware/opengl.nix index 0bc574d48190..bef500e30c0b 100644 --- a/nixos/modules/hardware/opengl.nix +++ b/nixos/modules/hardware/opengl.nix @@ -14,7 +14,7 @@ let name = "mesa-drivers+txc-${p.mesa_drivers.version}"; paths = [ p.mesa_drivers - p.mesa_noglu # mainly for libGL + p.mesa_drivers.out # mainly for libGL (if cfg.s3tcSupport then p.libtxc_dxtn else p.libtxc_dxtn_s2tc) ]; }; diff --git a/nixos/modules/i18n/input-method/default.nix b/nixos/modules/i18n/input-method/default.nix index f3e568f1dde3..7ed4a584d646 100644 --- a/nixos/modules/i18n/input-method/default.nix +++ b/nixos/modules/i18n/input-method/default.nix @@ -3,26 +3,27 @@ with lib; let cfg = config.i18n.inputMethod; - gtk2_cache = pkgs.stdenv.mkDerivation { - preferLocalBuild = true; - allowSubstitutes = false; - name = "gtk2-immodule.cache"; - buildInputs = [ pkgs.gtk cfg.package ]; - buildCommand = '' + + gtk2_cache = pkgs.runCommand "gtk2-immodule.cache" + { preferLocalBuild = true; + allowSubstitutes = false; + buildInputs = [ pkgs.gtk2 cfg.package ]; + } + '' mkdir -p $out/etc/gtk-2.0/ GTK_PATH=${cfg.package}/lib/gtk-2.0/ gtk-query-immodules-2.0 > $out/etc/gtk-2.0/immodules.cache ''; - }; - gtk3_cache = pkgs.stdenv.mkDerivation { - preferLocalBuild = true; - allowSubstitutes = false; - name = "gtk3-immodule.cache"; - buildInputs = [ pkgs.gtk3 cfg.package ]; - buildCommand = '' + + gtk3_cache = pkgs.runCommand "gtk3-immodule.cache" + { preferLocalBuild = true; + allowSubstitutes = false; + buildInputs = [ pkgs.gtk3 cfg.package ]; + } + '' mkdir -p $out/etc/gtk-3.0/ GTK_PATH=${cfg.package}/lib/gtk-3.0/ gtk-query-immodules-3.0 > $out/etc/gtk-3.0/immodules.cache ''; - }; + in { options.i18n = { diff --git a/nixos/modules/i18n/input-method/default.xml b/nixos/modules/i18n/input-method/default.xml index a32ed100df30..45d6daf068b3 100644 --- a/nixos/modules/i18n/input-method/default.xml +++ b/nixos/modules/i18n/input-method/default.xml @@ -56,8 +56,18 @@ i18n.inputMethod = { <listitem><para>Table (<literal>ibus-engines.table</literal>): An input method that load tables of input methods.</para></listitem> <listitem><para>table-others (<literal>ibus-engines.table-others</literal>): - Various table-based input methods.</para></listitem> + Various table-based input methods. To use this, and any other table-based + input methods, it must appear in the list of engines along with + <literal>table</literal>. For example: +<programlisting> +ibus.engines = with pkgs.ibus-engines; [ table table-others ]; +</programlisting> + </para></listitem> </itemizedlist> + +<para>To use any input method, the package must be added in the configuration, + as shown above, and also (after running <literal>nixos-rebuild</literal>) the + input method must be added from IBus' preference dialog.</para> </section> <section><title>Fcitx</title> diff --git a/nixos/modules/installer/cd-dvd/installation-cd-graphical-kde.nix b/nixos/modules/installer/cd-dvd/installation-cd-graphical-kde.nix index d14768bc1079..b5ee57d9e22e 100644 --- a/nixos/modules/installer/cd-dvd/installation-cd-graphical-kde.nix +++ b/nixos/modules/installer/cd-dvd/installation-cd-graphical-kde.nix @@ -96,15 +96,16 @@ with lib; ''; in - pkgs.stdenv.mkDerivation { - inherit (pkg) name meta; - - buildCommand = '' + pkgs.runCommand pkg.name + { inherit (pkg) meta; } + '' mkdir -p $out cp -prf ${pkg}/* $out/ chmod a+w $out/share/apps/plasma-desktop/init cp -f ${plasmaInit} $out/share/apps/plasma-desktop/init/00-defaultLayout.js ''; - }; + + # Disable large stuff that's not very useful on the installation CD. + services.xserver.desktopManager.kde4.enablePIM = false; } diff --git a/nixos/modules/installer/cd-dvd/system-tarball-fuloong2f.nix b/nixos/modules/installer/cd-dvd/system-tarball-fuloong2f.nix index d984cb307170..ba84cd51098f 100644 --- a/nixos/modules/installer/cd-dvd/system-tarball-fuloong2f.nix +++ b/nixos/modules/installer/cd-dvd/system-tarball-fuloong2f.nix @@ -61,7 +61,7 @@ in pkgs.cryptsetup # needed for dm-crypt volumes # Some networking tools. - pkgs.sshfsFuse + pkgs.sshfs-fuse pkgs.socat pkgs.screen pkgs.wpa_supplicant # !!! should use the wpa module diff --git a/nixos/modules/installer/cd-dvd/system-tarball-sheevaplug.nix b/nixos/modules/installer/cd-dvd/system-tarball-sheevaplug.nix index 9e733241993d..7ec09acd5919 100644 --- a/nixos/modules/installer/cd-dvd/system-tarball-sheevaplug.nix +++ b/nixos/modules/installer/cd-dvd/system-tarball-sheevaplug.nix @@ -55,7 +55,7 @@ in pkgs.cryptsetup # needed for dm-crypt volumes # Some networking tools. - pkgs.sshfsFuse + pkgs.sshfs-fuse pkgs.socat pkgs.screen pkgs.wpa_supplicant # !!! should use the wpa module diff --git a/nixos/modules/installer/tools/nixos-generate-config.pl b/nixos/modules/installer/tools/nixos-generate-config.pl index 5e576367eb2f..f1874f239778 100644 --- a/nixos/modules/installer/tools/nixos-generate-config.pl +++ b/nixos/modules/installer/tools/nixos-generate-config.pl @@ -527,8 +527,11 @@ EOF # Use the GRUB 2 boot loader. boot.loader.grub.enable = true; boot.loader.grub.version = 2; + # boot.loader.grub.efiSupport = true; + # boot.loader.grub.efiInstallAsRemovable = true; + # boot.loader.efi.efiSysMountPoint = "/boot/efi"; # Define on which hard drive you want to install Grub. - # boot.loader.grub.device = "/dev/sda"; + # boot.loader.grub.device = "/dev/sda"; # or "nodev" for efi only EOF } diff --git a/nixos/modules/installer/tools/nixos-install.sh b/nixos/modules/installer/tools/nixos-install.sh index 0a452b86018a..da28c027c563 100644 --- a/nixos/modules/installer/tools/nixos-install.sh +++ b/nixos/modules/installer/tools/nixos-install.sh @@ -259,7 +259,7 @@ chroot $mountPoint /nix/var/nix/profiles/system/activate # Ask the user to set a root password. -if [ -z "$noRootPasswd" ] && [ -x $mountPoint/var/setuid-wrappers/passwd ] && [ -t 0 ]; then +if [ -z "$noRootPasswd" ] && chroot $mountPoint [ -x /var/setuid-wrappers/passwd ] && [ -t 0 ]; then echo "setting root password..." chroot $mountPoint /var/setuid-wrappers/passwd fi diff --git a/nixos/modules/misc/ids.nix b/nixos/modules/misc/ids.nix index e31349105946..2881d843760d 100644 --- a/nixos/modules/misc/ids.nix +++ b/nixos/modules/misc/ids.nix @@ -74,7 +74,6 @@ rtkit = 45; dovecot2 = 46; dovenull2 = 47; - unbound = 48; prayer = 49; mpd = 50; clamav = 51; @@ -120,7 +119,6 @@ minidlna = 91; elasticsearch = 92; tcpcryptd = 93; # tcpcryptd uses a hard-coded uid. We patch it in Nixpkgs to match this choice. - #connman = 94; # unused firebird = 95; #keys = 96; # unused haproxy = 97; @@ -141,7 +139,7 @@ ngircd = 112; btsync = 113; minecraft = 114; - monetdb = 115; + #monetdb = 115; # unused (not packaged), removed 2016-09-19 rippled = 116; murmur = 117; foundationdb = 118; @@ -275,6 +273,9 @@ terraria = 253; mattermost = 254; prometheus = 255; + telegraf = 256; + gitlab-runner = 257; + postgrey = 258; # When adding a uid, make sure it doesn't match an existing gid. And don't use uids above 399! @@ -331,7 +332,6 @@ #rtkit = 45; # unused dovecot2 = 46; #dovenull = 47; # unused - #unbound = 48; # unused prayer = 49; mpd = 50; clamav = 51; @@ -377,7 +377,6 @@ minidlna = 91; elasticsearch = 92; #tcpcryptd = 93; # unused - connman = 94; firebird = 95; keys = 96; haproxy = 97; @@ -396,7 +395,7 @@ #ngircd = 112; # unused btsync = 113; #minecraft = 114; # unused - monetdb = 115; + #monetdb = 115; # unused (not packaged), removed 2016-09-19 #ripped = 116; # unused #murmur = 117; # unused foundationdb = 118; @@ -520,6 +519,9 @@ terraria = 253; mattermost = 254; prometheus = 255; + #telegraf = 256; # unused + gitlab-runner = 257; + postgrey = 258; # When adding a gid, make sure it doesn't match an existing # uid. Users and groups with the same name should have equal diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index 485138e1ff35..fd42d335bb82 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -70,6 +70,7 @@ ./programs/fish.nix ./programs/freetds.nix ./programs/info.nix + ./programs/java.nix ./programs/kbdlight.nix ./programs/light.nix ./programs/man.nix @@ -133,6 +134,7 @@ ./services/computing/slurm/slurm.nix ./services/continuous-integration/buildkite-agent.nix ./services/continuous-integration/hydra/default.nix + ./services/continuous-integration/gitlab-runner.nix ./services/continuous-integration/gocd-agent/default.nix ./services/continuous-integration/gocd-server/default.nix ./services/continuous-integration/jenkins/default.nix @@ -145,7 +147,6 @@ ./services/databases/hbase.nix ./services/databases/influxdb.nix ./services/databases/memcached.nix - ./services/databases/monetdb.nix ./services/databases/mongodb.nix ./services/databases/mysql.nix ./services/databases/neo4j.nix @@ -211,10 +212,12 @@ ./services/mail/freepops.nix ./services/mail/mail.nix ./services/mail/mlmmj.nix + ./services/mail/offlineimap.nix ./services/mail/opendkim.nix ./services/mail/opensmtpd.nix ./services/mail/postfix.nix ./services/mail/postsrsd.nix + ./services/mail/postgrey.nix ./services/mail/spamassassin.nix ./services/mail/rspamd.nix ./services/mail/rmilter.nix @@ -251,6 +254,7 @@ ./services/misc/mwlib.nix ./services/misc/nix-daemon.nix ./services/misc/nix-gc.nix + ./services/misc/nix-optimise.nix ./services/misc/nixos-manual.nix ./services/misc/nix-ssh-serve.nix ./services/misc/nzbget.nix @@ -289,6 +293,8 @@ ./services/monitoring/munin.nix ./services/monitoring/nagios.nix ./services/monitoring/prometheus/default.nix + ./services/monitoring/prometheus/node-exporter.nix + ./services/monitoring/prometheus/alertmanager.nix ./services/monitoring/riemann.nix ./services/monitoring/riemann-dash.nix ./services/monitoring/riemann-tools.nix @@ -297,6 +303,7 @@ ./services/monitoring/statsd.nix ./services/monitoring/systemhealth.nix ./services/monitoring/teamviewer.nix + ./services/monitoring/telegraf.nix ./services/monitoring/ups.nix ./services/monitoring/uptime.nix ./services/monitoring/zabbix-agent.nix @@ -340,6 +347,7 @@ ./services/networking/ferm.nix ./services/networking/firefox/sync-server.nix ./services/networking/firewall.nix + ./services/networking/flannel.nix ./services/networking/flashpolicyd.nix ./services/networking/freenet.nix ./services/networking/gale.nix @@ -352,6 +360,7 @@ ./services/networking/haproxy.nix ./services/networking/heyefi.nix ./services/networking/hostapd.nix + ./services/networking/htpdate.nix ./services/networking/i2pd.nix ./services/networking/i2p.nix ./services/networking/iodine.nix @@ -378,7 +387,6 @@ ./services/networking/ntopng.nix ./services/networking/ntpd.nix ./services/networking/nylon.nix - ./services/networking/offlineimap.nix ./services/networking/oidentd.nix ./services/networking/openfire.nix ./services/networking/openntpd.nix @@ -386,6 +394,7 @@ ./services/networking/ostinato.nix ./services/networking/pdnsd.nix ./services/networking/polipo.nix + ./services/networking/powerdns.nix ./services/networking/pptpd.nix ./services/networking/prayer.nix ./services/networking/privoxy.nix @@ -472,6 +481,7 @@ ./services/web-apps/mattermost.nix ./services/web-apps/pump.io.nix ./services/web-apps/tt-rss.nix + ./services/web-apps/selfoss.nix ./services/web-servers/apache-httpd/default.nix ./services/web-servers/caddy.nix ./services/web-servers/fcgiwrap.nix diff --git a/nixos/modules/profiles/base.nix b/nixos/modules/profiles/base.nix index 20a1f7f1ed8c..32bea97823ce 100644 --- a/nixos/modules/profiles/base.nix +++ b/nixos/modules/profiles/base.nix @@ -20,7 +20,7 @@ # Some networking tools. pkgs.fuse - pkgs.sshfsFuse + pkgs.sshfs-fuse pkgs.socat pkgs.screen diff --git a/nixos/modules/programs/bash/bash.nix b/nixos/modules/programs/bash/bash.nix index c09bcfb70e24..e23849d350b4 100644 --- a/nixos/modules/programs/bash/bash.nix +++ b/nixos/modules/programs/bash/bash.nix @@ -16,7 +16,7 @@ let # programmable completion. If we do, enable all modules installed in # the system (and user profile). if shopt -q progcomp &>/dev/null; then - . "${pkgs.bashCompletion}/etc/profile.d/bash_completion.sh" + . "${pkgs.bash-completion}/etc/profile.d/bash_completion.sh" nullglobStatus=$(shopt -p nullglob) shopt -s nullglob for p in $NIX_PROFILES; do diff --git a/nixos/modules/programs/java.nix b/nixos/modules/programs/java.nix new file mode 100644 index 000000000000..3292aa369d28 --- /dev/null +++ b/nixos/modules/programs/java.nix @@ -0,0 +1,57 @@ +# This module provides JAVA_HOME, with a different way to install java +# system-wide. + +{ config, lib, pkgs, ... }: + +with lib; + +let + cfg = config.programs.java; +in + +{ + + options = { + + programs.java = { + + enable = mkEnableOption "java" // { + description = '' + Install and setup the Java development kit. + <note> + <para>This adds JAVA_HOME to the global environment, by sourcing the + jdk's setup-hook on shell init. It is equivalent to starting a shell + through 'nix-shell -p jdk', or roughly the following system-wide + configuration: + </para> + <programlisting> + environment.variables.JAVA_HOME = ''${pkgs.jdk.home}/lib/openjdk; + environment.systemPackages = [ pkgs.jdk ]; + </programlisting> + </note> + ''; + }; + + package = mkOption { + default = pkgs.jdk; + description = '' + Java package to install. Typical values are pkgs.jdk or pkgs.jre. + ''; + type = types.package; + }; + + }; + + }; + + config = mkIf cfg.enable { + + environment.systemPackages = [ cfg.package ]; + + environment.shellInit = '' + test -e ${cfg.package}/nix-support/setup-hook && source ${cfg.package}/nix-support/setup-hook + ''; + + }; + +} diff --git a/nixos/modules/programs/zsh/zsh.nix b/nixos/modules/programs/zsh/zsh.nix index 91cd84416921..d81f63c2acca 100644 --- a/nixos/modules/programs/zsh/zsh.nix +++ b/nixos/modules/programs/zsh/zsh.nix @@ -102,9 +102,9 @@ in interactiveShellInit = '' # history defaults - export SAVEHIST=2000 - export HISTSIZE=2000 - export HISTFILE=$HOME/.zsh_history + SAVEHIST=2000 + HISTSIZE=2000 + HISTFILE=$HOME/.zsh_history setopt HIST_IGNORE_DUPS SHARE_HISTORY HIST_FCNTL_LOCK diff --git a/nixos/modules/rename.nix b/nixos/modules/rename.nix index 34b9724442eb..9abe7d450c93 100644 --- a/nixos/modules/rename.nix +++ b/nixos/modules/rename.nix @@ -139,6 +139,9 @@ with lib; # fontconfig-ultimate (mkRenamedOptionModule [ "fonts" "fontconfig" "ultimate" "rendering" ] [ "fonts" "fontconfig" "ultimate" "preset" ]) + # murmur + (mkRenamedOptionModule [ "services" "murmur" "welcome" ] [ "services" "murmur" "welcometext" ]) + # Options that are obsolete and have no replacement. (mkRemovedOptionModule [ "boot" "initrd" "luks" "enable" ] "") (mkRemovedOptionModule [ "programs" "bash" "enable" ] "") @@ -150,7 +153,7 @@ with lib; (mkRemovedOptionModule [ "services" "printing" "cupsFilesConf" ] "") (mkRemovedOptionModule [ "services" "printing" "cupsdConf" ] "") (mkRemovedOptionModule [ "services" "xserver" "startGnuPGAgent" ] - "See the 16.03 release notes for more information.") + "See the 16.09 release notes for more information.") (mkRemovedOptionModule [ "services" "phpfpm" "phpIni" ] "") (mkRemovedOptionModule [ "services" "dovecot2" "package" ] "") (mkRemovedOptionModule [ "services" "dockerRegistry" ] diff --git a/nixos/modules/security/acme.nix b/nixos/modules/security/acme.nix index 45e8f64046b0..1a2b8779e007 100644 --- a/nixos/modules/security/acme.nix +++ b/nixos/modules/security/acme.nix @@ -129,11 +129,10 @@ in certs = mkOption { default = { }; - type = types.loaOf types.optionSet; + type = with types; loaOf (submodule certOpts); description = '' Attribute set of certificates to get signed and renewed. ''; - options = [ certOpts ]; example = { "example.com" = { webroot = "/var/www/challenges/"; diff --git a/nixos/modules/security/hidepid.nix b/nixos/modules/security/hidepid.nix index 8f2df380cfe8..ee351eb84473 100644 --- a/nixos/modules/security/hidepid.nix +++ b/nixos/modules/security/hidepid.nix @@ -2,19 +2,19 @@ with lib; { - options = { - security.hideProcessInformation = mkEnableOption "" // { description = '' - Restrict access to process information to the owning user. Enabling - this option implies, among other things, that command-line arguments - remain private. This option is recommended for most systems, unless - there's a legitimate reason for allowing unprivileged users to inspect - the process information of other users. + meta = { + maintainers = [ maintainers.joachifm ]; + doc = ./hidepid.xml; + }; - Members of the group "proc" are exempt from process information hiding. - To allow a service to run without process information hiding, add "proc" - to its supplementary groups via - <option>systemd.services.<name?>.serviceConfig.SupplementaryGroups</option>. - ''; }; + options = { + security.hideProcessInformation = mkOption { + type = types.bool; + default = false; + description = '' + Restrict process information to the owning user. + ''; + }; }; config = mkIf config.security.hideProcessInformation { diff --git a/nixos/modules/security/hidepid.xml b/nixos/modules/security/hidepid.xml new file mode 100644 index 000000000000..5715ee7ac165 --- /dev/null +++ b/nixos/modules/security/hidepid.xml @@ -0,0 +1,33 @@ +<chapter 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-hidepid"> + + <title>Hiding process information</title> + + <para> + Setting + <programlisting> + security.hideProcessInformation = true; + </programlisting> + ensures that access to process information is restricted to the + owning user. This implies, among other things, that command-line + arguments remain private. Unless your deployment relies on unprivileged + users being able to inspect the process information of other users, this + option should be safe to enable. + </para> + + <para> + Members of the <literal>proc</literal> group are exempt from process + information hiding. + </para> + + <para> + To allow a service <replaceable>foo</replaceable> to run without process information hiding, set + <programlisting> + systemd.services.<replaceable>foo</replaceable>.serviceConfig.SupplementaryGroups = [ "proc" ]; + </programlisting> + </para> + +</chapter> diff --git a/nixos/modules/security/pam.nix b/nixos/modules/security/pam.nix index 814dd21b53de..f9aa4136c8d6 100644 --- a/nixos/modules/security/pam.nix +++ b/nixos/modules/security/pam.nix @@ -386,8 +386,7 @@ in security.pam.services = mkOption { default = []; - type = types.loaOf types.optionSet; - options = [ pamOpts ]; + type = with types; loaOf (submodule pamOpts); description = '' This option defines the PAM services. A service typically diff --git a/nixos/modules/security/rngd.nix b/nixos/modules/security/rngd.nix index b14ea7a5f276..3a1ffc55e5fe 100644 --- a/nixos/modules/security/rngd.nix +++ b/nixos/modules/security/rngd.nix @@ -18,7 +18,7 @@ with lib; config = mkIf config.security.rngd.enable { services.udev.extraRules = '' KERNEL=="random", TAG+="systemd" - SUBSYSTEM=="cpu", ENV{MODALIAS}=="x86cpu:*feature:*009E*", TAG+="systemd", ENV{SYSTEMD_WANTS}+="rngd.service" + SUBSYSTEM=="cpu", ENV{MODALIAS}=="cpu:type:x86,*feature:*009E*", TAG+="systemd", ENV{SYSTEMD_WANTS}+="rngd.service" KERNEL=="hw_random", TAG+="systemd", ENV{SYSTEMD_WANTS}+="rngd.service" ${if config.services.tcsd.enable then "" else ''KERNEL=="tpm0", TAG+="systemd", ENV{SYSTEMD_WANTS}+="rngd.service"''} ''; diff --git a/nixos/modules/security/sudo.nix b/nixos/modules/security/sudo.nix index bced2a6ed757..f5612e1b0c5d 100644 --- a/nixos/modules/security/sudo.nix +++ b/nixos/modules/security/sudo.nix @@ -74,7 +74,7 @@ in Defaults env_keep+=SSH_AUTH_SOCK # "root" is allowed to do anything. - root ALL=(ALL) SETENV: ALL + root ALL=(ALL:ALL) SETENV: ALL # Users in the "wheel" group can do anything. %wheel ALL=(ALL:ALL) ${if cfg.wheelNeedsPassword then "" else "NOPASSWD: ALL, "}SETENV: ALL diff --git a/nixos/modules/services/backup/bacula.nix b/nixos/modules/services/backup/bacula.nix index 8a26aae75fe9..ef8e5e55edef 100644 --- a/nixos/modules/services/backup/bacula.nix +++ b/nixos/modules/services/backup/bacula.nix @@ -198,8 +198,7 @@ in { description = '' This option defines director resources in Bacula File Daemon. ''; - type = types.attrsOf types.optionSet; - options = [ directorOptions ]; + type = with types; attrsOf (submodule directorOptions); }; extraClientConfig = mkOption { @@ -253,8 +252,7 @@ in { description = '' This option defines Director resources in Bacula Storage Daemon. ''; - type = types.attrsOf types.optionSet; - options = [ directorOptions ]; + type = with types; attrsOf (submodule directorOptions); }; device = mkOption { @@ -262,8 +260,7 @@ in { description = '' This option defines Device resources in Bacula Storage Daemon. ''; - type = types.attrsOf types.optionSet; - options = [ deviceOptions ]; + type = with types; attrsOf (submodule deviceOptions); }; extraStorageConfig = mkOption { diff --git a/nixos/modules/services/backup/rsnapshot.nix b/nixos/modules/services/backup/rsnapshot.nix index ce628a720363..16815bcc8605 100644 --- a/nixos/modules/services/backup/rsnapshot.nix +++ b/nixos/modules/services/backup/rsnapshot.nix @@ -7,11 +7,14 @@ let cfgfile = pkgs.writeText "rsnapshot.conf" '' config_version 1.2 cmd_cp ${pkgs.coreutils}/bin/cp + cmd_rm ${pkgs.coreutils}/bin/rm cmd_rsync ${pkgs.rsync}/bin/rsync cmd_ssh ${pkgs.openssh}/bin/ssh cmd_logger ${pkgs.inetutils}/bin/logger cmd_du ${pkgs.coreutils}/bin/du + cmd_rsnapshot_diff ${pkgs.rsnapshot}/bin/rsnapshot-diff lockfile /run/rsnapshot.pid + link_dest 1 ${cfg.extraConfig} ''; diff --git a/nixos/modules/services/continuous-integration/gitlab-runner.nix b/nixos/modules/services/continuous-integration/gitlab-runner.nix new file mode 100644 index 000000000000..1fe4d28f9f35 --- /dev/null +++ b/nixos/modules/services/continuous-integration/gitlab-runner.nix @@ -0,0 +1,51 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + cfg = config.services.gitlab-runner; + configFile = pkgs.writeText "config.toml" cfg.configText; +in +{ + options.services.gitlab-runner = { + enable = mkEnableOption "Gitlab Runner"; + + configText = mkOption { + description = "Verbatim config.toml to use"; + }; + + workDir = mkOption { + default = "/var/lib/gitlab-runner"; + type = types.path; + description = "The working directory used"; + }; + + }; + + config = mkIf cfg.enable { + systemd.services.gitlab-runner = { + description = "Gitlab Runner"; + after = [ "network.target" "docker.service" ]; + requires = [ "docker.service" ]; + wantedBy = [ "multi-user.target" ]; + serviceConfig = { + ExecStart = ''${pkgs.gitlab-runner.bin}/bin/gitlab-runner run \ + --working-directory ${cfg.workDir} \ + --config ${configFile} \ + --service gitlab-runner \ + --user gitlab-runner \ + ''; + }; + }; + + users.extraUsers.gitlab-runner = { + group = "gitlab-runner"; + extraGroups = [ "docker" ]; + uid = config.ids.uids.gitlab-runner; + home = cfg.workDir; + createHome = true; + }; + + users.extraGroups.gitlab-runner.gid = config.ids.gids.gitlab-runner; + }; +} diff --git a/nixos/modules/services/continuous-integration/gocd-agent/default.nix b/nixos/modules/services/continuous-integration/gocd-agent/default.nix index 21f319f7fcf6..d60b55e83d11 100644 --- a/nixos/modules/services/continuous-integration/gocd-agent/default.nix +++ b/nixos/modules/services/continuous-integration/gocd-agent/default.nix @@ -98,7 +98,7 @@ in { ]; description = '' Specifies startup command line arguments to pass to Go.CD agent - java process. Example contains debug and gcLog arguments. + java process. ''; }; diff --git a/nixos/modules/services/continuous-integration/gocd-server/default.nix b/nixos/modules/services/continuous-integration/gocd-server/default.nix index 2d1986301216..4bb792055d25 100644 --- a/nixos/modules/services/continuous-integration/gocd-server/default.nix +++ b/nixos/modules/services/continuous-integration/gocd-server/default.nix @@ -90,7 +90,7 @@ in { ''; }; - extraOptions = mkOption { + startupOptions = mkOption { default = [ "-Xms${cfg.initialJavaHeapSize}" "-Xmx${cfg.maxJavaHeapMemory}" @@ -103,6 +103,15 @@ in { "-Dcruise.server.port=${toString cfg.port}" "-Dcruise.server.ssl.port=${toString cfg.sslPort}" ]; + + description = '' + Specifies startup command line arguments to pass to Go.CD server + java process. + ''; + }; + + extraOptions = mkOption { + default = [ ]; example = [ "-X debug" "-Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5005" @@ -169,7 +178,8 @@ in { script = '' ${pkgs.git}/bin/git config --global --add http.sslCAinfo /etc/ssl/certs/ca-certificates.crt - ${pkgs.jre}/bin/java -server ${concatStringsSep " " cfg.extraOptions} \ + ${pkgs.jre}/bin/java -server ${concatStringsSep " " cfg.startupOptions} \ + ${concatStringsSep " " cfg.extraOptions} \ -jar ${pkgs.gocd-server}/go-server/go.jar ''; diff --git a/nixos/modules/services/databases/influxdb.nix b/nixos/modules/services/databases/influxdb.nix index ed477524d4cb..dd88624f406c 100644 --- a/nixos/modules/services/databases/influxdb.nix +++ b/nixos/modules/services/databases/influxdb.nix @@ -66,16 +66,16 @@ let enabled = false; }]; - collectd = { + collectd = [{ enabled = false; typesdb = "${pkgs.collectd}/share/collectd/types.db"; database = "collectd_db"; port = 25826; - }; + }]; - opentsdb = { + opentsdb = [{ enabled = false; - }; + }]; continuous_queries = { enabled = true; @@ -171,6 +171,11 @@ in mkdir -m 0770 -p ${cfg.dataDir} if [ "$(id -u)" = 0 ]; then chown -R ${cfg.user}:${cfg.group} ${cfg.dataDir}; fi ''; + postStart = mkBefore '' + until ${pkgs.curl.bin}/bin/curl -s -o /dev/null 'http://127.0.0.1${toString configOptions.http.bind-address}'/ping; do + sleep 1; + done + ''; }; users.extraUsers = optional (cfg.user == "influxdb") { diff --git a/nixos/modules/services/databases/monetdb.nix b/nixos/modules/services/databases/monetdb.nix deleted file mode 100644 index 9f09c71e005a..000000000000 --- a/nixos/modules/services/databases/monetdb.nix +++ /dev/null @@ -1,88 +0,0 @@ -{ config, lib, pkgs, ... }: -let - cfg = config.services.monetdb; - monetdbUser = "monetdb"; -in -with lib; -{ - - ###### interface - - options = { - - services.monetdb = { - - enable = mkOption { - type = types.bool; - default = false; - description = "Whether to enable MonetDB database server."; - }; - - package = mkOption { - type = types.path; - description = "MonetDB package to use."; - }; - - dbfarmDir = mkOption { - type = types.path; - default = "/var/lib/monetdb"; - description = '' - Specifies location of Monetdb dbfarm (keeps database and auxiliary files). - ''; - }; - - port = mkOption { - default = "50000"; - example = "50000"; - description = "Port to listen on."; - }; - }; - - }; - - - ###### implementation - - config = mkIf cfg.enable { - - users.extraUsers.monetdb = - { name = monetdbUser; - uid = config.ids.uids.monetdb; - description = "monetdb user"; - home = cfg.dbfarmDir; - }; - - users.extraGroups.monetdb.gid = config.ids.gids.monetdb; - - environment.systemPackages = [ cfg.package ]; - - systemd.services.monetdb = - { description = "MonetDB Server"; - - wantedBy = [ "multi-user.target" ]; - - after = [ "network.target" ]; - - path = [ cfg.package ]; - - preStart = - '' - # Initialise the database. - if ! test -e ${cfg.dbfarmDir}/.merovingian_properties; then - mkdir -m 0700 -p ${cfg.dbfarmDir} - chown -R ${monetdbUser} ${cfg.dbfarmDir} - ${cfg.package}/bin/monetdbd create ${cfg.dbfarmDir} - ${cfg.package}/bin/monetdbd set port=${cfg.port} ${cfg.dbfarmDir} - fi - ''; - - serviceConfig.ExecStart = "${cfg.package}/bin/monetdbd start -n ${cfg.dbfarmDir}"; - - serviceConfig.ExecStop = "${cfg.package}/bin/monetdbd stop ${cfg.dbfarmDir}"; - - unitConfig.RequiresMountsFor = "${cfg.dbfarmDir}"; - }; - - }; - -} diff --git a/nixos/modules/services/databases/mongodb.nix b/nixos/modules/services/databases/mongodb.nix index ef9bc46e4a0e..38e46a0c6ef9 100644 --- a/nixos/modules/services/databases/mongodb.nix +++ b/nixos/modules/services/databases/mongodb.nix @@ -12,13 +12,11 @@ let mongoCnf = pkgs.writeText "mongodb.conf" '' - bind_ip = ${cfg.bind_ip} - ${optionalString cfg.quiet "quiet = true"} - dbpath = ${cfg.dbpath} - syslog = true - fork = true - pidfilepath = ${cfg.pidFile} - ${optionalString (cfg.replSetName != "") "replSet = ${cfg.replSetName}"} + net.bindIp: ${cfg.bind_ip} + ${optionalString cfg.quiet "systemLog.quiet: true"} + systemLog.destination: syslog + storage.dbPath: ${cfg.dbpath} + ${optionalString (cfg.replSetName != "") "replication.replSetName: ${cfg.replSetName}"} ${cfg.extraConfig} ''; @@ -84,9 +82,9 @@ in extraConfig = mkOption { default = ""; example = '' - nojournal = true + storage.journal.enabled: false ''; - description = "MongoDB extra configuration"; + description = "MongoDB extra configuration in YAML format"; }; }; @@ -112,7 +110,7 @@ in after = [ "network.target" ]; serviceConfig = { - ExecStart = "${mongodb}/bin/mongod --quiet --config ${mongoCnf}"; + ExecStart = "${mongodb}/bin/mongod --quiet --config ${mongoCnf} --fork --pidfilepath ${cfg.pidFile}"; User = cfg.user; PIDFile = cfg.pidFile; Type = "forking"; diff --git a/nixos/modules/services/databases/riak.nix b/nixos/modules/services/databases/riak.nix index bee768fa42ae..4477904f78c6 100644 --- a/nixos/modules/services/databases/riak.nix +++ b/nixos/modules/services/databases/riak.nix @@ -20,7 +20,7 @@ in package = mkOption { type = types.package; - example = literalExample "pkgs.riak2"; + example = literalExample "pkgs.riak"; description = '' Riak package to use. ''; @@ -108,6 +108,7 @@ in pkgs.bash ]; + environment.HOME = "${cfg.dataDir}"; environment.RIAK_DATA_DIR = "${cfg.dataDir}"; environment.RIAK_LOG_DIR = "${cfg.logDir}"; environment.RIAK_ETC_DIR = "/etc/riak"; diff --git a/nixos/modules/services/editors/emacs.xml b/nixos/modules/services/editors/emacs.xml index ee8ef512bc70..618460953a17 100644 --- a/nixos/modules/services/editors/emacs.xml +++ b/nixos/modules/services/editors/emacs.xml @@ -59,17 +59,17 @@ <variablelist> <varlistentry> <term><varname>emacs</varname></term> - <term><varname>emacs24</varname></term> + <term><varname>emacs25</varname></term> <listitem> <para> - The latest stable version of Emacs 24 using the <link + The latest stable version of Emacs 25 using the <link xlink:href="http://www.gtk.org">GTK+ 2</link> widget toolkit. </para> </listitem> </varlistentry> <varlistentry> - <term><varname>emacs24-nox</varname></term> + <term><varname>emacs25-nox</varname></term> <listitem> <para> Emacs 24 built without any dependency on X11 @@ -86,15 +86,6 @@ </para> </listitem> </varlistentry> - <varlistentry> - <term><varname>emacs25pre</varname></term> - <listitem> - <para> - A pretest version of what will become the first - version of Emacs 25. - </para> - </listitem> - </varlistentry> </variablelist> </para> diff --git a/nixos/modules/services/hardware/sane_extra_backends/brscan4.nix b/nixos/modules/services/hardware/sane_extra_backends/brscan4.nix index 3ec74458cd29..1923addeb3ac 100644 --- a/nixos/modules/services/hardware/sane_extra_backends/brscan4.nix +++ b/nixos/modules/services/hardware/sane_extra_backends/brscan4.nix @@ -81,12 +81,11 @@ in { office1 = { model = "MFC-7860DW"; ip = "192.168.1.2"; }; office2 = { model = "MFC-7860DW"; nodename = "BRW0080927AFBCE"; }; }; - type = types.loaOf types.optionSet; + type = with types; loaOf (submodule netDeviceOpts); description = '' The list of network devices that will be registered against the brscan4 sane backend. ''; - options = [ netDeviceOpts ]; }; }; @@ -113,4 +112,4 @@ in ]; }; -} \ No newline at end of file +} diff --git a/nixos/modules/services/hardware/udev.nix b/nixos/modules/services/hardware/udev.nix index 7c4c93d0fcb3..14d65978c320 100644 --- a/nixos/modules/services/hardware/udev.nix +++ b/nixos/modules/services/hardware/udev.nix @@ -32,13 +32,11 @@ let ''; # Perform substitutions in all udev rules files. - udevRules = stdenv.mkDerivation { - name = "udev-rules"; - - preferLocalBuild = true; - allowSubstitutes = false; - - buildCommand = '' + udevRules = pkgs.runCommand "udev-rules" + { preferLocalBuild = true; + allowSubstitutes = false; + } + '' mkdir -p $out shopt -s nullglob set +o pipefail @@ -130,15 +128,12 @@ let ln -s /dev/null $out/80-drivers.rules ''} ''; # */ - }; - hwdbBin = stdenv.mkDerivation { - name = "hwdb.bin"; - - preferLocalBuild = true; - allowSubstitutes = false; - - buildCommand = '' + hwdbBin = pkgs.runCommand "hwdb.bin" + { preferLocalBuild = true; + allowSubstitutes = false; + } + '' mkdir -p etc/udev/hwdb.d for i in ${toString ([udev] ++ cfg.packages)}; do echo "Adding hwdb files for package $i" @@ -151,7 +146,6 @@ let ${udev}/bin/udevadm hwdb --update --root=$(pwd) mv etc/udev/hwdb.bin $out ''; - }; # Udev has a 512-character limit for ENV{PATH}, so create a symlink # tree to work around this. diff --git a/nixos/modules/services/logging/logcheck.nix b/nixos/modules/services/logging/logcheck.nix index 3a85fa60fe7a..a8a214b21550 100644 --- a/nixos/modules/services/logging/logcheck.nix +++ b/nixos/modules/services/logging/logcheck.nix @@ -62,42 +62,46 @@ let }; ignoreOptions = { - level = levelOption; + options = { + level = levelOption; - regex = mkOption { - default = ""; - type = types.str; - description = '' - Regex specifying which log lines to ignore. - ''; + regex = mkOption { + default = ""; + type = types.str; + description = '' + Regex specifying which log lines to ignore. + ''; + }; }; }; ignoreCronOptions = { - user = mkOption { - default = "root"; - type = types.str; - description = '' - User that runs the cronjob. - ''; - }; + options = { + user = mkOption { + default = "root"; + type = types.str; + description = '' + User that runs the cronjob. + ''; + }; - cmdline = mkOption { - default = ""; - type = types.str; - description = '' - Command line for the cron job. Will be turned into a regex for the logcheck ignore rule. - ''; - }; + cmdline = mkOption { + default = ""; + type = types.str; + description = '' + Command line for the cron job. Will be turned into a regex for the logcheck ignore rule. + ''; + }; - timeArgs = mkOption { - default = null; - type = types.nullOr (types.str); - example = "02 06 * * *"; - description = '' - "min hr dom mon dow" crontab time args, to auto-create a cronjob too. - Leave at null to not do this and just add a logcheck ignore rule. - ''; + timeArgs = mkOption { + default = null; + type = types.nullOr (types.str); + example = "02 06 * * *"; + description = '' + "min hr dom mon dow" crontab time args, to auto-create a cronjob too. + Leave at null to not do this and just add a logcheck ignore rule. + ''; + }; }; }; @@ -180,8 +184,7 @@ in description = '' This option defines extra ignore rules. ''; - type = types.loaOf types.optionSet; - options = [ ignoreOptions ]; + type = with types; loaOf (submodule ignoreOptions); }; ignoreCron = mkOption { @@ -189,8 +192,7 @@ in description = '' This option defines extra ignore rules for cronjobs. ''; - type = types.loaOf types.optionSet; - options = [ ignoreOptions ignoreCronOptions ]; + type = with types; loaOf (submodule ignoreCronOptions); }; extraGroups = mkOption { diff --git a/nixos/modules/services/networking/offlineimap.nix b/nixos/modules/services/mail/offlineimap.nix index daf6196d3706..85ece020905b 100644 --- a/nixos/modules/services/networking/offlineimap.nix +++ b/nixos/modules/services/mail/offlineimap.nix @@ -59,7 +59,7 @@ in { }; path = cfg.path; }; - environment.systemPackages = [ "${cfg.package}" ]; + environment.systemPackages = [ cfg.package ]; systemd.user.timers.offlineimap = { description = "offlineimap timer"; timerConfig = { diff --git a/nixos/modules/services/mail/postgrey.nix b/nixos/modules/services/mail/postgrey.nix new file mode 100644 index 000000000000..0db631868cc7 --- /dev/null +++ b/nixos/modules/services/mail/postgrey.nix @@ -0,0 +1,79 @@ +{ config, lib, pkgs, ... }: + +with lib; let + + cfg = config.services.postgrey; + +in { + + options = { + services.postgrey = with types; { + enable = mkOption { + type = bool; + default = false; + description = "Whether to run the Postgrey daemon"; + }; + inetAddr = mkOption { + type = nullOr string; + default = null; + example = "127.0.0.1"; + description = "The inet address to bind to. If none given, bind to /var/run/postgrey.sock"; + }; + inetPort = mkOption { + type = int; + default = 10030; + description = "The tcp port to bind to"; + }; + greylistText = mkOption { + type = string; + default = "Greylisted for %%s seconds"; + description = "Response status text for greylisted messages"; + }; + }; + }; + + config = mkIf cfg.enable { + + environment.systemPackages = [ pkgs.postgrey ]; + + users = { + extraUsers = { + postgrey = { + description = "Postgrey Daemon"; + uid = config.ids.uids.postgrey; + group = "postgrey"; + }; + }; + extraGroups = { + postgrey = { + gid = config.ids.gids.postgrey; + }; + }; + }; + + systemd.services.postgrey = let + bind-flag = if isNull cfg.inetAddr then + "--unix=/var/run/postgrey.sock" + else + "--inet=${cfg.inetAddr}:${cfg.inetPort}"; + in { + description = "Postfix Greylisting Service"; + wantedBy = [ "multi-user.target" ]; + before = [ "postfix.service" ]; + preStart = '' + mkdir -p /var/postgrey + chown postgrey:postgrey /var/postgrey + chmod 0770 /var/postgrey + ''; + serviceConfig = { + Type = "simple"; + ExecStart = ''${pkgs.postgrey}/bin/postgrey ${bind-flag} --pidfile=/var/run/postgrey.pid --group=postgrey --user=postgrey --dbdir=/var/postgrey --greylist-text="${cfg.greylistText}"''; + Restart = "always"; + RestartSec = 5; + TimeoutSec = 10; + }; + }; + + }; + +} diff --git a/nixos/modules/services/misc/autofs.nix b/nixos/modules/services/misc/autofs.nix index 18f0c3eb83d5..40b48f70f7ed 100644 --- a/nixos/modules/services/misc/autofs.nix +++ b/nixos/modules/services/misc/autofs.nix @@ -22,7 +22,7 @@ in default = false; description = " Mount filesystems on demand. Unmount them automatically. - You may also be interested in afuese. + You may also be interested in afuse. "; }; diff --git a/nixos/modules/services/misc/confd.nix b/nixos/modules/services/misc/confd.nix index 72ec68dee6b3..fe13013286b8 100644..100755 --- a/nixos/modules/services/misc/confd.nix +++ b/nixos/modules/services/misc/confd.nix @@ -33,7 +33,7 @@ in { nodes = mkOption { description = "Confd list of nodes to connect to."; - default = [ "http://127.0.0.1:4001" ]; + default = [ "http://127.0.0.1:2379" ]; type = types.listOf types.str; }; diff --git a/nixos/modules/services/misc/gitlab.nix b/nixos/modules/services/misc/gitlab.nix index b3f09999adba..f8881233dceb 100644 --- a/nixos/modules/services/misc/gitlab.nix +++ b/nixos/modules/services/misc/gitlab.nix @@ -449,13 +449,15 @@ in { Group = cfg.group; TimeoutSec = "300"; Restart = "on-failure"; + WorkingDirectory = gitlabEnv.HOME; ExecStart = "${cfg.packages.gitlab-workhorse}/bin/gitlab-workhorse " + "-listenUmask 0 " + "-listenNetwork unix " + "-listenAddr /run/gitlab/gitlab-workhorse.socket " + "-authSocket ${gitlabSocket} " - + "-documentRoot ${cfg.packages.gitlab}/share/gitlab/public"; + + "-documentRoot ${cfg.packages.gitlab}/share/gitlab/public " + + "-secretPath ${cfg.packages.gitlab}/share/gitlab/.gitlab_workhorse_secret"; }; }; @@ -525,17 +527,23 @@ in { psql postgres -c "CREATE ROLE gitlab WITH LOGIN NOCREATEDB NOCREATEROLE NOCREATEUSER ENCRYPTED PASSWORD '${cfg.databasePassword}'" ${config.services.postgresql.package}/bin/createdb --owner gitlab gitlab || true touch "${cfg.statePath}/db-created" - - # The gitlab:setup task is horribly broken somehow, these two tasks will do the same for setting up the initial database - ${gitlab-rake}/bin/gitlab-rake db:migrate RAILS_ENV=production - ${gitlab-rake}/bin/gitlab-rake db:seed_fu RAILS_ENV=production \ - GITLAB_ROOT_PASSWORD="${cfg.initialRootPassword}" GITLAB_ROOT_EMAIL="${cfg.initialRootEmail}"; fi fi + # enable required pg_trgm extension for gitlab + psql gitlab -c "CREATE EXTENSION IF NOT EXISTS pg_trgm" # Always do the db migrations just to be sure the database is up-to-date ${gitlab-rake}/bin/gitlab-rake db:migrate RAILS_ENV=production + # The gitlab:setup task is horribly broken somehow, the db:migrate + # task above and the db:seed_fu below will do the same for setting + # up the initial database + if ! test -e "${cfg.statePath}/db-seeded"; then + ${gitlab-rake}/bin/gitlab-rake db:seed_fu RAILS_ENV=production \ + GITLAB_ROOT_PASSWORD="${cfg.initialRootPassword}" GITLAB_ROOT_EMAIL="${cfg.initialRootEmail}" + touch "${cfg.statePath}/db-seeded" + fi + # Change permissions in the last step because some of the # intermediary scripts like to create directories as root. chown -R ${cfg.user}:${cfg.group} ${cfg.statePath} diff --git a/nixos/modules/services/misc/matrix-synapse.nix b/nixos/modules/services/misc/matrix-synapse.nix index bb8dc640f981..4145f8fa957a 100644 --- a/nixos/modules/services/misc/matrix-synapse.nix +++ b/nixos/modules/services/misc/matrix-synapse.nix @@ -5,15 +5,16 @@ with lib; let cfg = config.services.matrix-synapse; logConfigFile = pkgs.writeText "log_config.yaml" cfg.logConfig; - mkResource = r: ''{names: ${builtins.toJSON r.names}, compress: ${if r.compress then "true" else "false"}}''; - mkListener = l: ''{port: ${toString l.port}, bind_address: "${l.bind_address}", type: ${l.type}, tls: ${if l.tls then "true" else "false"}, x_forwarded: ${if l.x_forwarded then "true" else "false"}, resources: [${concatStringsSep "," (map mkResource l.resources)}]}''; + mkResource = r: ''{names: ${builtins.toJSON r.names}, compress: ${fromBool r.compress}}''; + mkListener = l: ''{port: ${toString l.port}, bind_address: "${l.bind_address}", type: ${l.type}, tls: ${fromBool l.tls}, x_forwarded: ${fromBool l.x_forwarded}, resources: [${concatStringsSep "," (map mkResource l.resources)}]}''; + fromBool = x: if x then "true" else "false"; configFile = pkgs.writeText "homeserver.yaml" '' tls_certificate_path: "${cfg.tls_certificate_path}" ${optionalString (cfg.tls_private_key_path != null) '' tls_private_key_path: "${cfg.tls_private_key_path}" ''} tls_dh_params_path: "${cfg.tls_dh_params_path}" -no_tls: ${if cfg.no_tls then "true" else "false"} +no_tls: ${fromBool cfg.no_tls} ${optionalString (cfg.bind_port != null) '' bind_port: ${toString cfg.bind_port} ''} @@ -25,7 +26,7 @@ bind_host: "${cfg.bind_host}" ''} server_name: "${cfg.server_name}" pid_file: "/var/run/matrix-synapse.pid" -web_client: ${if cfg.web_client then "true" else "false"} +web_client: ${fromBool cfg.web_client} ${optionalString (cfg.public_baseurl != null) '' public_baseurl: "${cfg.public_baseurl}" ''} @@ -53,14 +54,14 @@ media_store_path: "/var/lib/matrix-synapse/media" uploads_path: "/var/lib/matrix-synapse/uploads" max_upload_size: "${cfg.max_upload_size}" max_image_pixels: "${cfg.max_image_pixels}" -dynamic_thumbnails: ${if cfg.dynamic_thumbnails then "true" else "false"} +dynamic_thumbnails: ${fromBool cfg.dynamic_thumbnails} url_preview_enabled: False recaptcha_private_key: "${cfg.recaptcha_private_key}" recaptcha_public_key: "${cfg.recaptcha_public_key}" -enable_registration_captcha: ${if cfg.enable_registration_captcha then "true" else "false"} +enable_registration_captcha: ${fromBool cfg.enable_registration_captcha} turn_uris: ${builtins.toJSON cfg.turn_uris} turn_shared_secret: "${cfg.turn_shared_secret}" -enable_registration: ${if cfg.enable_registration then "true" else "false"} +enable_registration: ${fromBool cfg.enable_registration} ${optionalString (cfg.registration_shared_secret != null) '' registration_shared_secret: "${cfg.registration_shared_secret}" ''} @@ -68,9 +69,15 @@ recaptcha_siteverify_api: "https://www.google.com/recaptcha/api/siteverify" turn_user_lifetime: "${cfg.turn_user_lifetime}" user_creation_max_duration: ${cfg.user_creation_max_duration} bcrypt_rounds: ${cfg.bcrypt_rounds} -allow_guest_access: {if cfg.allow_guest_access then "true" else "false"} -enable_metrics: ${if cfg.enable_metrics then "true" else "false"} -report_stats: ${if cfg.report_stats then "true" else "false"} +allow_guest_access: ${fromBool cfg.allow_guest_access} +trusted_third_party_id_servers: ${builtins.toJSON cfg.trusted_third_party_id_servers} +room_invite_state_types: ${builtins.toJSON cfg.room_invite_state_types} +${optionalString (cfg.macaroon_secret_key != null) '' + macaroon_secret_key: "${cfg.macaroon_secret_key}" +''} +expire_access_token: ${fromBool cfg.expire_access_token} +enable_metrics: ${fromBool cfg.enable_metrics} +report_stats: ${fromBool cfg.report_stats} signing_key_path: "/var/lib/matrix-synapse/homeserver.signing.key" key_refresh_interval: "${cfg.key_refresh_interval}" perspectives: @@ -469,6 +476,34 @@ in { accessible to anonymous users. ''; }; + trusted_third_party_id_servers = mkOption { + type = types.listOf types.str; + default = ["matrix.org"]; + description = '' + The list of identity servers trusted to verify third party identifiers by this server. + ''; + }; + room_invite_state_types = mkOption { + type = types.listOf types.str; + default = ["m.room.join_rules" "m.room.canonical_alias" "m.room.avatar" "m.room.name"]; + description = '' + A list of event types that will be included in the room_invite_state + ''; + }; + macaroon_secret_key = mkOption { + type = types.nullOr types.str; + default = null; + description = '' + Secret key for authentication tokens + ''; + }; + expire_access_token = mkOption { + type = types.bool; + default = false; + description = '' + Whether to enable access token expiration. + ''; + }; key_refresh_interval = mkOption { type = types.str; default = "1d"; diff --git a/nixos/modules/services/misc/nix-optimise.nix b/nixos/modules/services/misc/nix-optimise.nix new file mode 100644 index 000000000000..fea322a68f8e --- /dev/null +++ b/nixos/modules/services/misc/nix-optimise.nix @@ -0,0 +1,49 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + cfg = config.nix.optimise; +in + +{ + + ###### interface + + options = { + + nix.optimise = { + + automatic = mkOption { + default = false; + type = types.bool; + description = "Automatically run the nix store optimiser at a specific time."; + }; + + dates = mkOption { + default = "03:45"; + type = types.listOf types.str; + description = '' + Specification (in the format described by + <citerefentry><refentrytitle>systemd.time</refentrytitle> + <manvolnum>5</manvolnum></citerefentry>) of the time at + which the optimiser will run. + ''; + }; + }; + }; + + + ###### implementation + + config = { + + systemd.services.nix-optimise = + { description = "Nix Store Optimiser"; + serviceConfig.ExecStart = "${config.nix.package}/bin/nix-store --optimise"; + startAt = optional cfg.automatic cfg.dates; + }; + + }; + +} diff --git a/nixos/modules/services/misc/rippled.nix b/nixos/modules/services/misc/rippled.nix index c6b67e8498ca..8bcf35a8ad38 100644 --- a/nixos/modules/services/misc/rippled.nix +++ b/nixos/modules/services/misc/rippled.nix @@ -154,43 +154,45 @@ let }; dbOptions = { - type = mkOption { - description = "Rippled database type."; - type = types.enum ["rocksdb" "nudb"]; - default = "rocksdb"; - }; + options = { + type = mkOption { + description = "Rippled database type."; + type = types.enum ["rocksdb" "nudb"]; + default = "rocksdb"; + }; - path = mkOption { - description = "Location to store the database."; - type = types.path; - default = cfg.databasePath; - }; + path = mkOption { + description = "Location to store the database."; + type = types.path; + default = cfg.databasePath; + }; - compression = mkOption { - description = "Whether to enable snappy compression."; - type = types.nullOr types.bool; - default = null; - }; + compression = mkOption { + description = "Whether to enable snappy compression."; + type = types.nullOr types.bool; + default = null; + }; - onlineDelete = mkOption { - description = "Enable automatic purging of older ledger information."; - type = types.addCheck (types.nullOr types.int) (v: v > 256); - default = cfg.ledgerHistory; - }; + onlineDelete = mkOption { + description = "Enable automatic purging of older ledger information."; + type = types.addCheck (types.nullOr types.int) (v: v > 256); + default = cfg.ledgerHistory; + }; - advisoryDelete = mkOption { - description = '' - If set, then require administrative RPC call "can_delete" - to enable online deletion of ledger records. - ''; - type = types.nullOr types.bool; - default = null; - }; + advisoryDelete = mkOption { + description = '' + If set, then require administrative RPC call "can_delete" + to enable online deletion of ledger records. + ''; + type = types.nullOr types.bool; + default = null; + }; - extraOpts = mkOption { - description = "Extra database options."; - type = types.lines; - default = ""; + extraOpts = mkOption { + description = "Extra database options."; + type = types.lines; + default = ""; + }; }; }; @@ -213,8 +215,7 @@ in ports = mkOption { description = "Ports exposed by rippled"; - type = types.attrsOf types.optionSet; - options = [portOptions]; + type = with types; attrsOf (submodule portOptions); default = { rpc = { port = 5005; @@ -238,8 +239,7 @@ in nodeDb = mkOption { description = "Rippled main database options."; - type = types.nullOr types.optionSet; - options = dbOptions; + type = with types; nullOr (submodule dbOptions); default = { type = "rocksdb"; extraOpts = '' @@ -254,15 +254,13 @@ in tempDb = mkOption { description = "Rippled temporary database options."; - type = types.nullOr types.optionSet; - options = dbOptions; + type = with types; nullOr (submodule dbOptions); default = null; }; importDb = mkOption { description = "Settings for performing a one-time import."; - type = types.nullOr types.optionSet; - options = dbOptions; + type = with types; nullOr (submodule dbOptions); default = null; }; diff --git a/nixos/modules/services/monitoring/cadvisor.nix b/nixos/modules/services/monitoring/cadvisor.nix index a67df158be47..8ae8b12056ce 100644 --- a/nixos/modules/services/monitoring/cadvisor.nix +++ b/nixos/modules/services/monitoring/cadvisor.nix @@ -90,6 +90,7 @@ in { ${optionalString cfg.storageDriverSecure "-storage_driver_secure"} ''} ''; + TimeoutStartSec=300; }; }; diff --git a/nixos/modules/services/monitoring/prometheus/alertmanager.nix b/nixos/modules/services/monitoring/prometheus/alertmanager.nix new file mode 100644 index 000000000000..a9c0ce4ed6cb --- /dev/null +++ b/nixos/modules/services/monitoring/prometheus/alertmanager.nix @@ -0,0 +1,116 @@ +{ config, pkgs, lib, ... }: + +with lib; + +let + cfg = config.services.prometheus.alertmanager; + mkConfigFile = pkgs.writeText "alertmanager.yml" (builtins.toJSON cfg.configuration); +in { + options = { + services.prometheus.alertmanager = { + enable = mkEnableOption "Prometheus Alertmanager"; + + user = mkOption { + type = types.str; + default = "nobody"; + description = '' + User name under which Alertmanager shall be run. + ''; + }; + + group = mkOption { + type = types.str; + default = "nogroup"; + description = '' + Group under which Alertmanager shall be run. + ''; + }; + + configuration = mkOption { + type = types.attrs; + default = {}; + description = '' + Alertmanager configuration as nix attribute set. + ''; + }; + + logFormat = mkOption { + type = types.nullOr types.str; + default = null; + description = '' + If set use a syslog logger or JSON logging. + ''; + }; + + logLevel = mkOption { + type = types.enum ["debug" "info" "warn" "error" "fatal"]; + default = "warn"; + description = '' + Only log messages with the given severity or above. + ''; + }; + + webExternalUrl = mkOption { + type = types.nullOr types.str; + default = null; + description = '' + The URL under which Alertmanager is externally reachable (for example, if Alertmanager is served via a reverse proxy). + Used for generating relative and absolute links back to Alertmanager itself. + If the URL has a path portion, it will be used to prefix all HTTP endoints served by Alertmanager. + If omitted, relevant URL components will be derived automatically. + ''; + }; + + listenAddress = mkOption { + type = types.nullOr types.str; + default = null; + description = '' + Address to listen on for the web interface and API. + ''; + }; + + port = mkOption { + type = types.int; + default = 9093; + description = '' + Port to listen on for the web interface and API. + ''; + }; + + openFirewall = mkOption { + type = types.bool; + default = false; + description = '' + Open port in firewall for incoming connections. + ''; + }; + }; + }; + + + config = mkIf cfg.enable { + networking.firewall.allowedTCPPorts = optional cfg.openFirewall cfg.port; + + systemd.services.alertmanager = { + wantedBy = [ "multi-user.target" ]; + after = [ "network.target" ]; + script = '' + ${pkgs.prometheus-alertmanager.bin}/bin/alertmanager \ + -config.file ${mkConfigFile} \ + -web.listen-address ${cfg.listenAddress}:${toString cfg.port} \ + -log.level ${cfg.logLevel} \ + ${optionalString (cfg.webExternalUrl != null) ''-web.external-url ${cfg.webExternalUrl} \''} + ${optionalString (cfg.logFormat != null) "-log.format ${cfg.logFormat}"} + ''; + + serviceConfig = { + User = cfg.user; + Group = cfg.group; + Restart = "always"; + PrivateTmp = true; + WorkingDirectory = "/tmp"; + ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID"; + }; + }; + }; +} diff --git a/nixos/modules/services/monitoring/prometheus/default.nix b/nixos/modules/services/monitoring/prometheus/default.nix index 31979d2660cc..e6817ee227ab 100644 --- a/nixos/modules/services/monitoring/prometheus/default.nix +++ b/nixos/modules/services/monitoring/prometheus/default.nix @@ -29,6 +29,9 @@ let "-storage.local.path=${cfg.dataDir}/metrics" "-config.file=${writePrettyJSON "prometheus.yml" promConfig}" "-web.listen-address=${cfg.listenAddress}" + "-alertmanager.notification-queue-capacity=${toString cfg.alertmanagerNotificationQueueCapacity}" + "-alertmanager.timeout=${toString cfg.alertmanagerTimeout}s" + (optionalString (cfg.alertmanagerURL != []) "-alertmanager.url=${concatStringsSep "," cfg.alertmanagerURL}") ]; promTypes.globalConfig = types.submodule { @@ -388,6 +391,30 @@ in { A list of scrape configurations. ''; }; + + alertmanagerURL = mkOption { + type = types.listOf types.str; + default = []; + description = '' + List of Alertmanager URLs to send notifications to. + ''; + }; + + alertmanagerNotificationQueueCapacity = mkOption { + type = types.int; + default = 10000; + description = '' + The capacity of the queue for pending alert manager notifications. + ''; + }; + + alertmanagerTimeout = mkOption { + type = types.int; + default = 10; + description = '' + Alert manager HTTP API timeout (in seconds). + ''; + }; }; }; diff --git a/nixos/modules/services/monitoring/prometheus/node-exporter.nix b/nixos/modules/services/monitoring/prometheus/node-exporter.nix new file mode 100644 index 000000000000..52dc14effc45 --- /dev/null +++ b/nixos/modules/services/monitoring/prometheus/node-exporter.nix @@ -0,0 +1,71 @@ +{ config, pkgs, lib, ... }: + +with lib; + +let + cfg = config.services.prometheus.nodeExporter; + cmdlineArgs = cfg.extraFlags ++ [ + "-web.listen-address=${cfg.listenAddress}" + ]; +in { + options = { + services.prometheus.nodeExporter = { + enable = mkEnableOption "prometheus node exporter"; + + port = mkOption { + type = types.int; + default = 9100; + description = '' + Port to listen on. + ''; + }; + + listenAddress = mkOption { + type = types.string; + default = "0.0.0.0"; + description = '' + Address to listen on. + ''; + }; + + enabledCollectors = mkOption { + type = types.listOf types.string; + default = []; + example = ''[ "systemd" ]''; + description = '' + Collectors to enable, additionally to the defaults. + ''; + }; + + extraFlags = mkOption { + type = types.listOf types.str; + default = []; + description = '' + Extra commandline options when launching the node exporter. + ''; + }; + }; + }; + + config = mkIf cfg.enable { + systemd.services.prometheus-node-exporter = { + description = "Prometheus exporter for machine metrics"; + unitConfig.Documentation = "https://github.com/prometheus/node_exporter"; + wantedBy = [ "multi-user.target" ]; + script = '' + exec ${pkgs.prometheus-node-exporter}/bin/node_exporter \ + ${optionalString (cfg.enabledCollectors != []) + ''-collectors.enabled ${concatStringsSep "," cfg.enabledCollectors}''} \ + -web.listen-address ${cfg.listenAddress}:${toString cfg.port} \ + ${concatStringsSep " \\\n " cfg.extraFlags} + ''; + serviceConfig = { + User = "nobody"; + Restart = "always"; + PrivateTmp = true; + WorkingDirectory = /tmp; + ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID"; + }; + }; + }; +} diff --git a/nixos/modules/services/monitoring/smartd.nix b/nixos/modules/services/monitoring/smartd.nix index 1017005226b2..f2834f288f90 100644 --- a/nixos/modules/services/monitoring/smartd.nix +++ b/nixos/modules/services/monitoring/smartd.nix @@ -197,8 +197,7 @@ in devices = mkOption { default = []; example = [ { device = "/dev/sda"; } { device = "/dev/sdb"; options = "-d sat"; } ]; - type = types.listOf types.optionSet; - options = [ smartdOpts ]; + type = with types; listOf (submodule smartdOpts); description = "List of devices to monitor."; }; diff --git a/nixos/modules/services/monitoring/telegraf.nix b/nixos/modules/services/monitoring/telegraf.nix new file mode 100644 index 000000000000..49dc9d8143e6 --- /dev/null +++ b/nixos/modules/services/monitoring/telegraf.nix @@ -0,0 +1,71 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + cfg = config.services.telegraf; + + configFile = pkgs.runCommand "config.toml" { + buildInputs = [ pkgs.remarshal ]; + } '' + remarshal -if json -of toml \ + < ${pkgs.writeText "config.json" (builtins.toJSON cfg.extraConfig)} \ + > $out + ''; +in { + ###### interface + options = { + services.telegraf = { + enable = mkEnableOption "telegraf server"; + + package = mkOption { + default = pkgs.telegraf; + defaultText = "pkgs.telegraf"; + description = "Which telegraf derivation to use"; + type = types.package; + }; + + extraConfig = mkOption { + default = {}; + description = "Extra configuration options for telegraf"; + type = types.attrs; + example = { + outputs = { + influxdb = { + urls = ["http://localhost:8086"]; + database = "telegraf"; + }; + }; + inputs = { + statsd = { + service_address = ":8125"; + delete_timings = true; + }; + }; + }; + }; + }; + }; + + + ###### implementation + config = mkIf config.services.telegraf.enable { + systemd.services.telegraf = { + description = "Telegraf Agent"; + wantedBy = [ "multi-user.target" ]; + after = [ "network-online.target" ]; + serviceConfig = { + ExecStart=''${cfg.package}/bin/telegraf -config "${configFile}"''; + ExecReload="${pkgs.coreutils}/bin/kill -HUP $MAINPID"; + User = "telegraf"; + Restart = "on-failure"; + }; + }; + + users.extraUsers = [{ + name = "telegraf"; + uid = config.ids.uids.telegraf; + description = "telegraf daemon user"; + }]; + }; +} diff --git a/nixos/modules/services/monitoring/ups.nix b/nixos/modules/services/monitoring/ups.nix index febf0c95f5bd..c4c4ed227b35 100644 --- a/nixos/modules/services/monitoring/ups.nix +++ b/nixos/modules/services/monitoring/ups.nix @@ -169,8 +169,7 @@ in monitoring directly. These are usually attached to serial ports, but USB devices are also supported. ''; - type = types.attrsOf types.optionSet; - options = [ upsOptions ]; + type = with types; attrsOf (submodule upsOptions); }; }; diff --git a/nixos/modules/services/network-filesystems/samba.nix b/nixos/modules/services/network-filesystems/samba.nix index a186982ec9c0..7de85b59e2af 100644 --- a/nixos/modules/services/network-filesystems/samba.nix +++ b/nixos/modules/services/network-filesystems/samba.nix @@ -56,6 +56,7 @@ let serviceConfig = { ExecStart = "${samba}/sbin/${appName} ${args}"; ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID"; + Type = "notify"; }; restartTriggers = [ configFile ]; @@ -167,12 +168,12 @@ in type = types.attrsOf (types.attrsOf types.unspecified); example = { public = - { path = "/srv/public"; - "read only" = true; - browseable = "yes"; - "guest ok" = "yes"; - comment = "Public samba share."; - }; + { path = "/srv/public"; + "read only" = true; + browseable = "yes"; + "guest ok" = "yes"; + comment = "Public samba share."; + }; }; }; diff --git a/nixos/modules/services/network-filesystems/tahoe.nix b/nixos/modules/services/network-filesystems/tahoe.nix index d4b6c05e9432..f1846b963252 100644 --- a/nixos/modules/services/network-filesystems/tahoe.nix +++ b/nixos/modules/services/network-filesystems/tahoe.nix @@ -8,148 +8,150 @@ in options.services.tahoe = { introducers = mkOption { default = {}; - type = types.loaOf types.optionSet; + type = with types; loaOf (submodule { + options = { + nickname = mkOption { + type = types.str; + description = '' + The nickname of this Tahoe introducer. + ''; + }; + tub.port = mkOption { + default = 3458; + type = types.int; + description = '' + The port on which the introducer will listen. + ''; + }; + tub.location = mkOption { + default = null; + type = types.nullOr types.str; + description = '' + The external location that the introducer should listen on. + + If specified, the port should be included. + ''; + }; + package = mkOption { + default = pkgs.tahoelafs; + defaultText = "pkgs.tahoelafs"; + type = types.package; + example = literalExample "pkgs.tahoelafs"; + description = '' + The package to use for the Tahoe LAFS daemon. + ''; + }; + }; + }); description = '' The Tahoe introducers. ''; - options = { - nickname = mkOption { - type = types.str; - description = '' - The nickname of this Tahoe introducer. - ''; - }; - tub.port = mkOption { - default = 3458; - type = types.int; - description = '' - The port on which the introducer will listen. - ''; - }; - tub.location = mkOption { - default = null; - type = types.nullOr types.str; - description = '' - The external location that the introducer should listen on. - - If specified, the port should be included. - ''; - }; - package = mkOption { - default = pkgs.tahoelafs; - defaultText = "pkgs.tahoelafs"; - type = types.package; - example = literalExample "pkgs.tahoelafs"; - description = '' - The package to use for the Tahoe LAFS daemon. - ''; - }; - }; }; nodes = mkOption { default = {}; - type = types.loaOf types.optionSet; - description = '' - The Tahoe nodes. - ''; - options = { - nickname = mkOption { - type = types.str; - description = '' - The nickname of this Tahoe node. - ''; - }; - tub.port = mkOption { - default = 3457; - type = types.int; - description = '' - The port on which the tub will listen. + type = with types; loaOf (submodule { + options = { + nickname = mkOption { + type = types.str; + description = '' + The nickname of this Tahoe node. + ''; + }; + tub.port = mkOption { + default = 3457; + type = types.int; + description = '' + The port on which the tub will listen. - This is the correct setting to tweak if you want Tahoe's storage - system to listen on a different port. - ''; - }; - tub.location = mkOption { - default = null; - type = types.nullOr types.str; - description = '' - The external location that the node should listen on. + This is the correct setting to tweak if you want Tahoe's storage + system to listen on a different port. + ''; + }; + tub.location = mkOption { + default = null; + type = types.nullOr types.str; + description = '' + The external location that the node should listen on. - This is the setting to tweak if there are multiple interfaces - and you want to alter which interface Tahoe is advertising. + This is the setting to tweak if there are multiple interfaces + and you want to alter which interface Tahoe is advertising. - If specified, the port should be included. - ''; - }; - web.port = mkOption { - default = 3456; - type = types.int; - description = '' - The port on which the Web server will listen. + If specified, the port should be included. + ''; + }; + web.port = mkOption { + default = 3456; + type = types.int; + description = '' + The port on which the Web server will listen. - This is the correct setting to tweak if you want Tahoe's WUI to - listen on a different port. - ''; - }; - client.introducer = mkOption { - default = null; - type = types.nullOr types.str; - description = '' - The furl for a Tahoe introducer node. + This is the correct setting to tweak if you want Tahoe's WUI to + listen on a different port. + ''; + }; + client.introducer = mkOption { + default = null; + type = types.nullOr types.str; + description = '' + The furl for a Tahoe introducer node. - Like all furls, keep this safe and don't share it. - ''; - }; - client.helper = mkOption { - default = null; - type = types.nullOr types.str; - description = '' - The furl for a Tahoe helper node. + Like all furls, keep this safe and don't share it. + ''; + }; + client.helper = mkOption { + default = null; + type = types.nullOr types.str; + description = '' + The furl for a Tahoe helper node. - Like all furls, keep this safe and don't share it. - ''; - }; - client.shares.needed = mkOption { - default = 3; - type = types.int; - description = '' - The number of shares required to reconstitute a file. - ''; - }; - client.shares.happy = mkOption { - default = 7; - type = types.int; - description = '' - The number of distinct storage nodes required to store - a file. - ''; - }; - client.shares.total = mkOption { - default = 10; - type = types.int; - description = '' - The number of shares required to store a file. - ''; - }; - storage.enable = mkEnableOption "storage service"; - storage.reservedSpace = mkOption { - default = "1G"; - type = types.str; - description = '' - The amount of filesystem space to not use for storage. - ''; - }; - helper.enable = mkEnableOption "helper service"; - package = mkOption { - default = pkgs.tahoelafs; - defaultText = "pkgs.tahoelafs"; - type = types.package; - example = literalExample "pkgs.tahoelafs"; - description = '' - The package to use for the Tahoe LAFS daemon. - ''; + Like all furls, keep this safe and don't share it. + ''; + }; + client.shares.needed = mkOption { + default = 3; + type = types.int; + description = '' + The number of shares required to reconstitute a file. + ''; + }; + client.shares.happy = mkOption { + default = 7; + type = types.int; + description = '' + The number of distinct storage nodes required to store + a file. + ''; + }; + client.shares.total = mkOption { + default = 10; + type = types.int; + description = '' + The number of shares required to store a file. + ''; + }; + storage.enable = mkEnableOption "storage service"; + storage.reservedSpace = mkOption { + default = "1G"; + type = types.str; + description = '' + The amount of filesystem space to not use for storage. + ''; + }; + helper.enable = mkEnableOption "helper service"; + package = mkOption { + default = pkgs.tahoelafs; + defaultText = "pkgs.tahoelafs"; + type = types.package; + example = literalExample "pkgs.tahoelafs"; + description = '' + The package to use for the Tahoe LAFS daemon. + ''; + }; }; - }; + }); + description = '' + The Tahoe nodes. + ''; }; }; config = mkMerge [ diff --git a/nixos/modules/services/networking/connman.nix b/nixos/modules/services/networking/connman.nix index 3fecfbb13a04..d0683b877801 100644 --- a/nixos/modules/services/networking/connman.nix +++ b/nixos/modules/services/networking/connman.nix @@ -27,6 +27,14 @@ in { ''; }; + enableVPN = mkOption { + type = types.bool; + default = true; + description = '' + Whether to enable ConnMan VPN service. + ''; + }; + extraConfig = mkOption { type = types.lines; default = '' @@ -78,7 +86,7 @@ in { }; }; - systemd.services."connman-vpn" = { + systemd.services."connman-vpn" = mkIf cfg.enableVPN { description = "ConnMan VPN service"; wantedBy = [ "multi-user.target" ]; after = [ "syslog.target" ]; @@ -91,7 +99,7 @@ in { }; }; - systemd.services."net-connman-vpn" = { + systemd.services."net-connman-vpn" = mkIf cfg.enableVPN { description = "D-BUS Service"; serviceConfig = { Name = "net.connman.vpn"; diff --git a/nixos/modules/services/networking/ddclient.nix b/nixos/modules/services/networking/ddclient.nix index 005c57dce7c7..e74d68cad902 100644 --- a/nixos/modules/services/networking/ddclient.nix +++ b/nixos/modules/services/networking/ddclient.nix @@ -7,7 +7,7 @@ let stateDir = "/var/spool/ddclient"; ddclientUser = "ddclient"; - ddclientFlags = "-foreground -verbose -noquiet -file /etc/ddclient.conf"; + ddclientFlags = "-foreground -verbose -noquiet -file ${config.services.ddclient.configFile}"; ddclientPIDFile = "${stateDir}/ddclient.pid"; in @@ -52,6 +52,17 @@ in ''; }; + configFile = mkOption { + default = "/etc/ddclient.conf"; + type = path; + description = '' + Path to configuration file. + When set to the default '/etc/ddclient.conf' it will be populated with the various other options in this module. When it is changed (for example: '/root/nixos/secrets/ddclient.conf') the file read directly to configure ddclient. This is a source of impurity. + The purpose of this is to avoid placing secrets into the store. + ''; + example = "/root/nixos/secrets/ddclient.conf"; + }; + protocol = mkOption { default = "dyndns2"; type = str; @@ -88,7 +99,7 @@ in default = "web, web=checkip.dyndns.com/, web-skip='Current IP Address: '"; type = str; description = '' - Method to determine the IP address to send to the dymanic DNS provider. + Method to determine the IP address to send to the dynamic DNS provider. ''; }; }; @@ -109,9 +120,11 @@ in }; environment.etc."ddclient.conf" = { + enable = config.services.ddclient.configFile == /etc/ddclient.conf; uid = config.ids.uids.ddclient; mode = "0600"; text = '' + # This file can be used as a template for configFile or is automatically generated by Nix options. daemon=600 cache=${stateDir}/ddclient.cache pid=${ddclientPIDFile} diff --git a/nixos/modules/services/networking/flannel.nix b/nixos/modules/services/networking/flannel.nix new file mode 100644 index 000000000000..28b6c4f657dd --- /dev/null +++ b/nixos/modules/services/networking/flannel.nix @@ -0,0 +1,153 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + cfg = config.services.flannel; + + networkConfig = filterAttrs (n: v: v != null) { + Network = cfg.network; + SubnetLen = cfg.subnetLen; + SubnetMin = cfg.subnetMin; + SubnetMax = cfg.subnetMax; + Backend = cfg.backend; + }; +in { + options.services.flannel = { + enable = mkEnableOption "flannel"; + + package = mkOption { + description = "Package to use for flannel"; + type = types.package; + default = pkgs.flannel.bin; + }; + + publicIp = mkOption { + description = '' + IP accessible by other nodes for inter-host communication. + Defaults to the IP of the interface being used for communication. + ''; + type = types.nullOr types.str; + default = null; + }; + + iface = mkOption { + description = '' + Interface to use (IP or name) for inter-host communication. + Defaults to the interface for the default route on the machine. + ''; + type = types.nullOr types.str; + default = null; + }; + + etcd = { + endpoints = mkOption { + description = "Etcd endpoints"; + type = types.listOf types.str; + default = ["http://127.0.0.1:2379"]; + }; + + prefix = mkOption { + description = "Etcd key prefix"; + type = types.str; + default = "/coreos.com/network"; + }; + + caFile = mkOption { + description = "Etcd certificate authority file"; + type = types.nullOr types.path; + default = null; + }; + + certFile = mkOption { + description = "Etcd cert file"; + type = types.nullOr types.path; + default = null; + }; + + keyFile = mkOption { + description = "Etcd key file"; + type = types.nullOr types.path; + default = null; + }; + }; + + network = mkOption { + description = " IPv4 network in CIDR format to use for the entire flannel network."; + type = types.str; + }; + + subnetLen = mkOption { + description = '' + The size of the subnet allocated to each host. Defaults to 24 (i.e. /24) + unless the Network was configured to be smaller than a /24 in which case + it is one less than the network. + ''; + type = types.int; + default = 24; + }; + + subnetMin = mkOption { + description = '' + The beginning of IP range which the subnet allocation should start with. + Defaults to the first subnet of Network. + ''; + type = types.nullOr types.str; + default = null; + }; + + subnetMax = mkOption { + description = '' + The end of IP range which the subnet allocation should start with. + Defaults to the last subnet of Network. + ''; + type = types.nullOr types.str; + default = null; + }; + + backend = mkOption { + description = "Type of backend to use and specific configurations for that backend."; + type = types.attrs; + default = { + Type = "vxlan"; + }; + }; + }; + + config = mkIf cfg.enable { + systemd.services.flannel = { + description = "Flannel Service"; + wantedBy = [ "multi-user.target" ]; + after = [ "network.target" ]; + environment = { + FLANNELD_PUBLIC_IP = cfg.publicIp; + FLANNELD_ETCD_ENDPOINTS = concatStringsSep "," cfg.etcd.endpoints; + FLANNELD_ETCD_KEYFILE = cfg.etcd.keyFile; + FLANNELD_ETCD_CERTFILE = cfg.etcd.certFile; + FLANNELD_ETCD_CAFILE = cfg.etcd.caFile; + FLANNELD_IFACE = cfg.iface; + ETCDCTL_CERT_FILE = cfg.etcd.certFile; + ETCDCTL_KEY_FILE = cfg.etcd.keyFile; + ETCDCTL_CA_FILE = cfg.etcd.caFile; + ETCDCTL_PEERS = concatStringsSep "," cfg.etcd.endpoints; + }; + preStart = '' + echo "setting network configuration" + until ${pkgs.etcdctl.bin}/bin/etcdctl set /coreos.com/network/config '${builtins.toJSON networkConfig}' + do + echo "setting network configuration, retry" + sleep 1 + done + ''; + postStart = '' + while [ ! -f /run/flannel/subnet.env ] + do + sleep 1 + done + ''; + serviceConfig.ExecStart = "${cfg.package}/bin/flannel"; + }; + + services.etcd.enable = mkDefault cfg.etcd.endpoints == ["http://127.0.0.1:2379"]; + }; +} diff --git a/nixos/modules/services/networking/htpdate.nix b/nixos/modules/services/networking/htpdate.nix new file mode 100644 index 000000000000..f5d512c7cd5a --- /dev/null +++ b/nixos/modules/services/networking/htpdate.nix @@ -0,0 +1,80 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + inherit (pkgs) htpdate; + + cfg = config.services.htpdate; +in + +{ + + ###### interface + + options = { + + services.htpdate = { + + enable = mkOption { + type = types.bool; + default = false; + description = '' + Enable htpdate daemon. + ''; + }; + + extraOptions = mkOption { + type = types.str; + default = ""; + description = '' + Additional command line arguments to pass to htpdate. + ''; + }; + + servers = mkOption { + type = types.listOf types.str; + default = [ "www.google.com" ]; + description = '' + HTTP servers to use for time synchronization. + ''; + }; + + proxy = mkOption { + type = types.str; + default = ""; + example = "127.0.0.1:8118"; + description = '' + HTTP proxy used for requests. + ''; + }; + + }; + + }; + + ###### implementation + + config = mkIf cfg.enable { + + systemd.services.htpdate = { + description = "htpdate daemon"; + wantedBy = [ "multi-user.target" ]; + serviceConfig = { + Type = "forking"; + PIDFile = "/var/run/htpdate.pid"; + ExecStart = concatStringsSep " " [ + "${htpdate}/bin/htpdate" + "-D -u nobody" + "-a -s" + "-l" + "${optionalString (cfg.proxy != "") "-P ${cfg.proxy}"}" + "${cfg.extraOptions}" + "${concatStringsSep " " cfg.servers}" + ]; + }; + }; + + }; + +} diff --git a/nixos/modules/services/networking/i2pd.nix b/nixos/modules/services/networking/i2pd.nix index 0cbf57314c4b..926857a0ff4e 100644 --- a/nixos/modules/services/networking/i2pd.nix +++ b/nixos/modules/services/networking/i2pd.nix @@ -187,44 +187,43 @@ in outTunnels = mkOption { default = {}; - type = with types; loaOf optionSet; + type = with types; loaOf (submodule ( + { name, config, ... }: { + options = commonTunOpts name; + config = { + name = mkDefault name; + }; + } + )); description = '' Connect to someone as a client and establish a local accept endpoint ''; - options = [ ({ name, config, ... }: { - options = commonTunOpts name; - config = { - name = mkDefault name; - }; - }) ]; }; inTunnels = mkOption { default = {}; - type = with types; loaOf optionSet; + type = with types; loaOf (submodule ( + { name, config, ... }: { + options = { + inPort = mkOption { + type = types.int; + default = 0; + description = "Service port. Default to the tunnel's listen port."; + }; + accessList = mkOption { + type = with types; listOf str; + default = []; + description = "I2P nodes that are allowed to connect to this service."; + }; + } // commonTunOpts name; + config = { + name = mkDefault name; + }; + } + )); description = '' Serve something on I2P network at port and delegate requests to address inPort. ''; - options = [ ({ name, config, ... }: { - - options = { - inPort = mkOption { - type = types.int; - default = 0; - description = "Service port. Default to the tunnel's listen port."; - }; - accessList = mkOption { - type = with types; listOf str; - default = []; - description = "I2P nodes that are allowed to connect to this service."; - }; - } // commonTunOpts name; - - config = { - name = mkDefault name; - }; - - }) ]; }; }; }; diff --git a/nixos/modules/services/networking/murmur.nix b/nixos/modules/services/networking/murmur.nix index 1cc19a2c9e09..134544cda681 100644 --- a/nixos/modules/services/networking/murmur.nix +++ b/nixos/modules/services/networking/murmur.nix @@ -15,7 +15,7 @@ let logfile=/var/log/murmur/murmurd.log pidfile=${cfg.pidfile} - welcome="${cfg.welcome}" + welcometext="${cfg.welcometext}" port=${toString cfg.port} ${if cfg.hostName == "" then "" else "host="+cfg.hostName} @@ -84,7 +84,7 @@ in description = "Path to PID file for Murmur daemon."; }; - welcome = mkOption { + welcometext = mkOption { type = types.str; default = ""; description = "Welcome message for connected clients."; diff --git a/nixos/modules/services/networking/nat.nix b/nixos/modules/services/networking/nat.nix index 23f1b2476ebe..08ba2fdb1646 100644 --- a/nixos/modules/services/networking/nat.nix +++ b/nixos/modules/services/networking/nat.nix @@ -122,23 +122,23 @@ in }; networking.nat.forwardPorts = mkOption { - type = types.listOf types.optionSet; + type = with types; listOf (submodule { + options = { + sourcePort = mkOption { + type = types.int; + example = 8080; + description = "Source port of the external interface"; + }; + + destination = mkOption { + type = types.str; + example = "10.0.0.1:80"; + description = "Forward tcp connection to destination ip:port"; + }; + }; + }); default = []; example = [ { sourcePort = 8080; destination = "10.0.0.1:80"; } ]; - options = { - sourcePort = mkOption { - type = types.int; - example = 8080; - description = "Source port of the external interface"; - }; - - destination = mkOption { - type = types.str; - example = "10.0.0.1:80"; - description = "Forward tcp connection to destination ip:port"; - }; - }; - description = '' List of forwarded ports from the external interface to diff --git a/nixos/modules/services/networking/nsd.nix b/nixos/modules/services/networking/nsd.nix index 333a3378c4cc..6af1dd736431 100644 --- a/nixos/modules/services/networking/nsd.nix +++ b/nixos/modules/services/networking/nsd.nix @@ -71,6 +71,7 @@ let # interfaces ${forEach " ip-address: " cfg.interfaces} + ip-freebind: ${yesOrNo cfg.ipFreebind} hide-version: ${yesOrNo cfg.hideVersion} identity: "${cfg.identity}" ip-transparent: ${yesOrNo cfg.ipTransparent} @@ -84,7 +85,7 @@ let reuseport: ${yesOrNo cfg.reuseport} round-robin: ${yesOrNo cfg.roundRobin} server-count: ${toString cfg.serverCount} - ${if cfg.statistics == null then "" else "statistics: ${toString cfg.statistics}"} + ${maybeToString "statistics: " cfg.statistics} tcp-count: ${toString cfg.tcpCount} tcp-query-count: ${toString cfg.tcpQueryCount} tcp-timeout: ${toString cfg.tcpTimeout} @@ -117,7 +118,8 @@ let ''; yesOrNo = b: if b then "yes" else "no"; - maybeString = pre: s: if s == null then "" else ''${pre} "${s}"''; + maybeString = prefix: x: if x == null then "" else ''${prefix} "${s}"''; + maybeToString = prefix: x: if x == null then "" else ''${prefix} ${toString s}''; forEach = pre: l: concatMapStrings (x: pre + x + "\n") l; @@ -146,6 +148,11 @@ let ${forEach " rrl-whitelist: " zone.rrlWhitelist} ${maybeString "zonestats: " zone.zoneStats} + ${maybeToString "max-refresh-time: " zone.maxRefreshSecs} + ${maybeToString "min-refresh-time: " zone.minRefreshSecs} + ${maybeToString "max-retry-time: " zone.maxRetrySecs} + ${maybeToString "min-retry-time: " zone.minRetrySecs} + allow-axfr-fallback: ${yesOrNo zone.allowAXFRFallback} ${forEach " allow-notify: " zone.allowNotify} ${forEach " request-xfr: " zone.requestXFR} @@ -241,6 +248,44 @@ let ''; }; + maxRefreshSecs = mkOption { + type = types.nullOr types.int; + default = null; + description = '' + Limit refresh time for secondary zones. This is the timer which + checks to see if the zone has to be refetched when it expires. + Normally the value from the SOA record is used, but this option + restricts that value. + ''; + }; + + minRefreshSecs = mkOption { + type = types.nullOr types.int; + default = null; + description = '' + Limit refresh time for secondary zones. + ''; + }; + + maxRetrySecs = mkOption { + type = types.nullOr types.int; + default = null; + description = '' + Limit retry time for secondary zones. This is the timeout after + a failed fetch attempt for the zone. Normally the value from + the SOA record is used, but this option restricts that value. + ''; + }; + + minRetrySecs = mkOption { + type = types.nullOr types.int; + default = null; + description = '' + Limit retry time for secondary zones. + ''; + }; + + notify = mkOption { type = types.listOf types.str; default = []; @@ -366,6 +411,15 @@ in ''; }; + ipFreebind = mkOption { + type = types.bool; + default = false; + description = '' + Whether to bind to nonlocal addresses and interfaces that are down. + Similar to ip-transparent. + ''; + }; + ipTransparent = mkOption { type = types.bool; default = false; diff --git a/nixos/modules/services/networking/openvpn.nix b/nixos/modules/services/networking/openvpn.nix index af3efa0464a6..3fbf5a9f0227 100644 --- a/nixos/modules/services/networking/openvpn.nix +++ b/nixos/modules/services/networking/openvpn.nix @@ -116,52 +116,54 @@ in attribute name. ''; - type = types.attrsOf types.optionSet; + type = with types; attrsOf (submodule { - options = { + options = { - config = mkOption { - type = types.lines; - description = '' - Configuration of this OpenVPN instance. See - <citerefentry><refentrytitle>openvpn</refentrytitle><manvolnum>8</manvolnum></citerefentry> - for details. - ''; - }; + config = mkOption { + type = types.lines; + description = '' + Configuration of this OpenVPN instance. See + <citerefentry><refentrytitle>openvpn</refentrytitle><manvolnum>8</manvolnum></citerefentry> + for details. + ''; + }; - up = mkOption { - default = ""; - type = types.lines; - description = '' - Shell commands executed when the instance is starting. - ''; - }; + up = mkOption { + default = ""; + type = types.lines; + description = '' + Shell commands executed when the instance is starting. + ''; + }; - down = mkOption { - default = ""; - type = types.lines; - description = '' - Shell commands executed when the instance is shutting down. - ''; - }; + down = mkOption { + default = ""; + type = types.lines; + description = '' + Shell commands executed when the instance is shutting down. + ''; + }; - autoStart = mkOption { - default = true; - type = types.bool; - description = "Whether this OpenVPN instance should be started automatically."; - }; + autoStart = mkOption { + default = true; + type = types.bool; + description = "Whether this OpenVPN instance should be started automatically."; + }; + + updateResolvConf = mkOption { + default = false; + type = types.bool; + description = '' + Use the script from the update-resolv-conf package to automatically + update resolv.conf with the DNS information provided by openvpn. The + script will be run after the "up" commands and before the "down" commands. + ''; + }; - updateResolvConf = mkOption { - default = false; - type = types.bool; - description = '' - Use the script from the update-resolv-conf package to automatically - update resolv.conf with the DNS information provided by openvpn. The - script will be run after the "up" commands and before the "down" commands. - ''; }; - }; + }); }; diff --git a/nixos/modules/services/networking/powerdns.nix b/nixos/modules/services/networking/powerdns.nix new file mode 100644 index 000000000000..ba05e15389f6 --- /dev/null +++ b/nixos/modules/services/networking/powerdns.nix @@ -0,0 +1,49 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + cfg = config.services.powerdns; + configDir = pkgs.writeTextDir "pdns.conf" "${cfg.extraConfig}"; +in { + options = { + services.powerdns = { + enable = mkEnableOption "Powerdns domain name server"; + + extraConfig = mkOption { + type = types.lines; + default = "launch=bind"; + description = '' + Extra lines to be added verbatim to pdns.conf. + Powerdns will chroot to /var/lib/powerdns. + So any file, powerdns is supposed to be read, + should be in /var/lib/powerdns and needs to specified + relative to the chroot. + ''; + }; + }; + }; + + config = mkIf config.services.powerdns.enable { + systemd.services.pdns = { + unitConfig.Documentation = "man:pdns_server(1) man:pdns_control(1)"; + description = "Powerdns name server"; + wantedBy = [ "multi-user.target" ]; + after = ["network.target" "mysql.service" "postgresql.service" "openldap.service"]; + + serviceConfig = { + Restart="on-failure"; + RestartSec="1"; + StartLimitInterval="0"; + PrivateDevices=true; + CapabilityBoundingSet="CAP_CHOWN CAP_NET_BIND_SERVICE CAP_SETGID CAP_SETUID CAP_SYS_CHROOT"; + NoNewPrivileges=true; + ExecStartPre = "${pkgs.coreutils}/bin/mkdir -p /var/lib/powerdns"; + ExecStart = "${pkgs.powerdns}/bin/pdns_server --setuid=nobody --setgid=nogroup --chroot=/var/lib/powerdns --socket-dir=/ --daemon=no --guardian=no --disable-syslog --write-pid=no --config-dir=${configDir}"; + ProtectSystem="full"; + ProtectHome=true; + RestrictAddressFamilies="AF_UNIX AF_INET AF_INET6"; + }; + }; + }; +} diff --git a/nixos/modules/services/networking/prosody.nix b/nixos/modules/services/networking/prosody.nix index f82f8bfddbb7..247c4f1efb07 100644 --- a/nixos/modules/services/networking/prosody.nix +++ b/nixos/modules/services/networking/prosody.nix @@ -164,7 +164,7 @@ in description = "Define the virtual hosts"; - type = types.loaOf types.optionSet; + type = with types; loaOf (submodule vHostOpts); example = { myhost = { @@ -180,7 +180,6 @@ in }; }; - options = [ vHostOpts ]; }; ssl = mkOption { diff --git a/nixos/modules/services/networking/radicale.nix b/nixos/modules/services/networking/radicale.nix index 4f7ed30b2a85..f9300fdabc57 100644 --- a/nixos/modules/services/networking/radicale.nix +++ b/nixos/modules/services/networking/radicale.nix @@ -33,7 +33,7 @@ in }; config = mkIf cfg.enable { - environment.systemPackages = [ pkgs.pythonPackages.radicale ]; + environment.systemPackages = [ pkgs.radicale ]; users.extraUsers = singleton { name = "radicale"; @@ -52,7 +52,7 @@ in description = "A Simple Calendar and Contact Server"; after = [ "network.target" ]; wantedBy = [ "multi-user.target" ]; - script = "${pkgs.pythonPackages.radicale}/bin/radicale -C ${confFile} -f"; + script = "${pkgs.radicale}/bin/radicale -C ${confFile} -f"; serviceConfig.User = "radicale"; serviceConfig.Group = "radicale"; }; diff --git a/nixos/modules/services/networking/ssh/sshd.nix b/nixos/modules/services/networking/ssh/sshd.nix index 1d15a1419722..3e9fae35847e 100644 --- a/nixos/modules/services/networking/ssh/sshd.nix +++ b/nixos/modules/services/networking/ssh/sshd.nix @@ -102,8 +102,8 @@ in }; permitRootLogin = mkOption { - default = "without-password"; - type = types.enum ["yes" "without-password" "forced-commands-only" "no"]; + default = "prohibit-password"; + type = types.enum ["yes" "without-password" "prohibit-password" "forced-commands-only" "no"]; description = '' Whether the root user can login using ssh. ''; @@ -129,7 +129,24 @@ in }; listenAddresses = mkOption { - type = types.listOf types.optionSet; + type = with types; listOf (submodule { + options = { + addr = mkOption { + type = types.nullOr types.str; + default = null; + description = '' + Host, IPv4 or IPv6 address to listen to. + ''; + }; + port = mkOption { + type = types.nullOr types.int; + default = null; + description = '' + Port to listen to. + ''; + }; + }; + }); default = []; example = [ { addr = "192.168.3.1"; port = 22; } { addr = "0.0.0.0"; port = 64022; } ]; description = '' @@ -140,22 +157,6 @@ in NOTE: setting this option won't automatically enable given ports in firewall configuration. ''; - options = { - addr = mkOption { - type = types.nullOr types.str; - default = null; - description = '' - Host, IPv4 or IPv6 address to listen to. - ''; - }; - port = mkOption { - type = types.nullOr types.int; - default = null; - description = '' - Port to listen to. - ''; - }; - }; }; passwordAuthentication = mkOption { diff --git a/nixos/modules/services/networking/supplicant.nix b/nixos/modules/services/networking/supplicant.nix index 16c4ee7e33bb..e433ec7c5b9b 100644 --- a/nixos/modules/services/networking/supplicant.nix +++ b/nixos/modules/services/networking/supplicant.nix @@ -34,7 +34,7 @@ let ''; in { description = "Supplicant ${iface}${optionalString (iface=="WLAN"||iface=="LAN") " %I"}"; - wantedBy = [ "network.target" ]; + wantedBy = [ "network.target" ] ++ deps; bindsTo = deps; after = deps; before = [ "network.target" ]; @@ -75,7 +75,107 @@ in options = { networking.supplicant = mkOption { - type = types.attrsOf types.optionSet; + type = with types; attrsOf (submodule { + options = { + + configFile = { + + path = mkOption { + type = types.path; + example = literalExample "/etc/wpa_supplicant.conf"; + description = '' + External <literal>wpa_supplicant.conf</literal> configuration file. + The configuration options defined declaratively within <literal>networking.supplicant</literal> have + precedence over options defined in <literal>configFile</literal>. + ''; + }; + + writable = mkOption { + type = types.bool; + default = false; + description = '' + Whether the configuration file at <literal>configFile.path</literal> should be written to by + <literal>wpa_supplicant</literal>. + ''; + }; + + }; + + extraConf = mkOption { + type = types.lines; + default = ""; + example = '' + ap_scan=1 + device_name=My-NixOS-Device + device_type=1-0050F204-1 + driver_param=use_p2p_group_interface=1 + disable_scan_offload=1 + p2p_listen_reg_class=81 + p2p_listen_channel=1 + p2p_oper_reg_class=81 + p2p_oper_channel=1 + manufacturer=NixOS + model_name=NixOS_Unstable + model_number=2015 + ''; + description = '' + Configuration options for <literal>wpa_supplicant.conf</literal>. + Options defined here have precedence over options in <literal>configFile</literal>. + NOTE: Do not write sensitive data into <literal>extraConf</literal> as it will + be world-readable in the <literal>nix-store</literal>. For sensitive information + use the <literal>configFile</literal> instead. + ''; + }; + + extraCmdArgs = mkOption { + type = types.str; + default = ""; + example = "-e/var/run/wpa_supplicant/entropy.bin"; + description = + "Command line arguments to add when executing <literal>wpa_supplicant</literal>."; + }; + + driver = mkOption { + type = types.nullOr types.str; + default = "nl80211,wext"; + description = "Force a specific wpa_supplicant driver."; + }; + + bridge = mkOption { + type = types.str; + default = ""; + description = "Name of the bridge interface that wpa_supplicant should listen at."; + }; + + userControlled = { + + enable = mkOption { + type = types.bool; + default = false; + description = '' + Allow normal users to control wpa_supplicant through wpa_gui or wpa_cli. + This is useful for laptop users that switch networks a lot and don't want + to depend on a large package such as NetworkManager just to pick nearby + access points. + ''; + }; + + socketDir = mkOption { + type = types.str; + default = "/var/run/wpa_supplicant"; + description = "Directory of sockets for controlling wpa_supplicant."; + }; + + group = mkOption { + type = types.str; + default = "wheel"; + example = "network"; + description = "Members of this group can control wpa_supplicant."; + }; + + }; + }; + }); default = { }; @@ -109,107 +209,6 @@ in service that can be accessed through <literal>D-Bus</literal>. ''; - options = { - - configFile = { - - path = mkOption { - type = types.path; - example = literalExample "/etc/wpa_supplicant.conf"; - description = '' - External <literal>wpa_supplicant.conf</literal> configuration file. - The configuration options defined declaratively within <literal>networking.supplicant</literal> have - precedence over options defined in <literal>configFile</literal>. - ''; - }; - - writable = mkOption { - type = types.bool; - default = false; - description = '' - Whether the configuration file at <literal>configFile.path</literal> should be written to by - <literal>wpa_supplicant</literal>. - ''; - }; - - }; - - extraConf = mkOption { - type = types.lines; - default = ""; - example = '' - ap_scan=1 - device_name=My-NixOS-Device - device_type=1-0050F204-1 - driver_param=use_p2p_group_interface=1 - disable_scan_offload=1 - p2p_listen_reg_class=81 - p2p_listen_channel=1 - p2p_oper_reg_class=81 - p2p_oper_channel=1 - manufacturer=NixOS - model_name=NixOS_Unstable - model_number=2015 - ''; - description = '' - Configuration options for <literal>wpa_supplicant.conf</literal>. - Options defined here have precedence over options in <literal>configFile</literal>. - NOTE: Do not write sensitive data into <literal>extraConf</literal> as it will - be world-readable in the <literal>nix-store</literal>. For sensitive information - use the <literal>configFile</literal> instead. - ''; - }; - - extraCmdArgs = mkOption { - type = types.str; - default = ""; - example = "-e/var/run/wpa_supplicant/entropy.bin"; - description = - "Command line arguments to add when executing <literal>wpa_supplicant</literal>."; - }; - - driver = mkOption { - type = types.nullOr types.str; - default = "nl80211,wext"; - description = "Force a specific wpa_supplicant driver."; - }; - - bridge = mkOption { - type = types.str; - default = ""; - description = "Name of the bridge interface that wpa_supplicant should listen at."; - }; - - userControlled = { - - enable = mkOption { - type = types.bool; - default = false; - description = '' - Allow normal users to control wpa_supplicant through wpa_gui or wpa_cli. - This is useful for laptop users that switch networks a lot and don't want - to depend on a large package such as NetworkManager just to pick nearby - access points. - ''; - }; - - socketDir = mkOption { - type = types.str; - default = "/var/run/wpa_supplicant"; - description = "Directory of sockets for controlling wpa_supplicant."; - }; - - group = mkOption { - type = types.str; - default = "wheel"; - example = "network"; - description = "Members of this group can control wpa_supplicant."; - }; - - }; - - }; - }; }; diff --git a/nixos/modules/services/networking/tinc.nix b/nixos/modules/services/networking/tinc.nix index d4fa6ad4540b..b26d30597b1f 100644 --- a/nixos/modules/services/networking/tinc.nix +++ b/nixos/modules/services/networking/tinc.nix @@ -18,94 +18,96 @@ in networks = mkOption { default = { }; - type = types.loaOf types.optionSet; + type = with types; loaOf (submodule { + options = { + + extraConfig = mkOption { + default = ""; + type = types.lines; + description = '' + Extra lines to add to the tinc service configuration file. + ''; + }; + + name = mkOption { + default = null; + type = types.nullOr types.str; + description = '' + The name of the node which is used as an identifier when communicating + with the remote nodes in the mesh. If null then the hostname of the system + is used. + ''; + }; + + ed25519PrivateKeyFile = mkOption { + default = null; + type = types.nullOr types.path; + description = '' + Path of the private ed25519 keyfile. + ''; + }; + + debugLevel = mkOption { + default = 0; + type = types.addCheck types.int (l: l >= 0 && l <= 5); + description = '' + The amount of debugging information to add to the log. 0 means little + logging while 5 is the most logging. <command>man tincd</command> for + more details. + ''; + }; + + hosts = mkOption { + default = { }; + type = types.loaOf types.lines; + description = '' + The name of the host in the network as well as the configuration for that host. + This name should only contain alphanumerics and underscores. + ''; + }; + + interfaceType = mkOption { + default = "tun"; + type = types.addCheck types.str (n: n == "tun" || n == "tap"); + description = '' + The type of virtual interface used for the network connection + ''; + }; + + listenAddress = mkOption { + default = null; + type = types.nullOr types.str; + description = '' + The ip adress to bind to. + ''; + }; + + package = mkOption { + type = types.package; + default = pkgs.tinc_pre; + defaultText = "pkgs.tinc_pre"; + description = '' + The package to use for the tinc daemon's binary. + ''; + }; + + chroot = mkOption { + default = true; + type = types.bool; + description = '' + Change process root directory to the directory where the config file is located (/etc/tinc/netname/), for added security. + The chroot is performed after all the initialization is done, after writing pid files and opening network sockets. + + Note that tinc can't run scripts anymore (such as tinc-down or host-up), unless it is setup to be runnable inside chroot environment. + ''; + }; + }; + }); + description = '' Defines the tinc networks which will be started. Each network invokes a different daemon. ''; - options = { - - extraConfig = mkOption { - default = ""; - type = types.lines; - description = '' - Extra lines to add to the tinc service configuration file. - ''; - }; - - name = mkOption { - default = null; - type = types.nullOr types.str; - description = '' - The name of the node which is used as an identifier when communicating - with the remote nodes in the mesh. If null then the hostname of the system - is used. - ''; - }; - - ed25519PrivateKeyFile = mkOption { - default = null; - type = types.nullOr types.path; - description = '' - Path of the private ed25519 keyfile. - ''; - }; - - debugLevel = mkOption { - default = 0; - type = types.addCheck types.int (l: l >= 0 && l <= 5); - description = '' - The amount of debugging information to add to the log. 0 means little - logging while 5 is the most logging. <command>man tincd</command> for - more details. - ''; - }; - - hosts = mkOption { - default = { }; - type = types.loaOf types.lines; - description = '' - The name of the host in the network as well as the configuration for that host. - This name should only contain alphanumerics and underscores. - ''; - }; - - interfaceType = mkOption { - default = "tun"; - type = types.addCheck types.str (n: n == "tun" || n == "tap"); - description = '' - The type of virtual interface used for the network connection - ''; - }; - - listenAddress = mkOption { - default = null; - type = types.nullOr types.str; - description = '' - The ip adress to bind to. - ''; - }; - - package = mkOption { - type = types.package; - default = pkgs.tinc_pre; - defaultText = "pkgs.tinc_pre"; - description = '' - The package to use for the tinc daemon's binary. - ''; - }; - - chroot = mkOption { - default = true; - type = types.bool; - description = '' - Change process root directory to the directory where the config file is located (/etc/tinc/netname/), for added security. - The chroot is performed after all the initialization is done, after writing pid files and opening network sockets. - - Note that tinc can't run scripts anymore (such as tinc-down or host-up), unless it is setup to be runnable inside chroot environment. - ''; - }; - }; }; }; diff --git a/nixos/modules/services/networking/unbound.nix b/nixos/modules/services/networking/unbound.nix index ed0744c44ccf..6375ebee3209 100644 --- a/nixos/modules/services/networking/unbound.nix +++ b/nixos/modules/services/networking/unbound.nix @@ -12,9 +12,17 @@ let interfaces = concatMapStrings (x: " interface: ${x}\n") cfg.interfaces; - forward = optionalString (length cfg.forwardAddresses != 0) - "forward-zone:\n name: .\n" + - concatMapStrings (x: " forward-addr: ${x}\n") cfg.forwardAddresses; + isLocalAddress = x: substring 0 3 x == "::1" || substring 0 9 x == "127.0.0.1"; + + forward = + optionalString (any isLocalAddress cfg.forwardAddresses) '' + do-not-query-localhost: no + '' + + optionalString (cfg.forwardAddresses != []) '' + forward-zone: + name: . + '' + + concatMapStringsSep "\n" (x: " forward-addr: ${x}") cfg.forwardAddresses; rootTrustAnchorFile = "${stateDir}/root.key"; @@ -72,7 +80,11 @@ in extraConfig = mkOption { default = ""; type = types.str; - description = "Extra lines of unbound config."; + description = '' + Extra unbound config. See + <citerefentry><refentrytitle>unbound.conf</refentrytitle><manvolnum>8 + </manvolnum></citerefentry>. + ''; }; }; @@ -84,12 +96,9 @@ in environment.systemPackages = [ pkgs.unbound ]; - users.extraUsers = singleton { - name = "unbound"; - uid = config.ids.uids.unbound; + users.users.unbound = { description = "unbound daemon user"; - home = stateDir; - createHome = true; + isSystemUser = true; }; systemd.services.unbound = { @@ -107,12 +116,16 @@ in chown unbound ${stateDir} ${rootTrustAnchorFile} ''} touch ${stateDir}/dev/random - ${pkgs.utillinux}/bin/mount --bind -n /dev/random ${stateDir}/dev/random + ${pkgs.utillinux}/bin/mount --bind -n /dev/urandom ${stateDir}/dev/random ''; serviceConfig = { ExecStart = "${pkgs.unbound}/bin/unbound -d -c ${stateDir}/unbound.conf"; ExecStopPost="${pkgs.utillinux}/bin/umount ${stateDir}/dev/random"; + + ProtectSystem = true; + ProtectHome = true; + PrivateDevices = true; }; }; diff --git a/nixos/modules/services/networking/xinetd.nix b/nixos/modules/services/networking/xinetd.nix index d27f04a180f3..270122ee659c 100644 --- a/nixos/modules/services/networking/xinetd.nix +++ b/nixos/modules/services/networking/xinetd.nix @@ -65,71 +65,73 @@ in A list of services provided by xinetd. ''; - type = types.listOf types.optionSet; + type = with types; listOf (submodule ({ + + options = { + + name = mkOption { + type = types.string; + example = "login"; + description = "Name of the service."; + }; + + protocol = mkOption { + type = types.string; + default = "tcp"; + description = + "Protocol of the service. Usually <literal>tcp</literal> or <literal>udp</literal>."; + }; + + port = mkOption { + type = types.int; + default = 0; + example = 123; + description = "Port number of the service."; + }; + + user = mkOption { + type = types.string; + default = "nobody"; + description = "User account for the service"; + }; + + server = mkOption { + type = types.string; + example = "/foo/bin/ftpd"; + description = "Path of the program that implements the service."; + }; + + serverArgs = mkOption { + type = types.string; + default = ""; + description = "Command-line arguments for the server program."; + }; + + flags = mkOption { + type = types.string; + default = ""; + description = ""; + }; + + unlisted = mkOption { + type = types.bool; + default = false; + description = '' + Whether this server is listed in + <filename>/etc/services</filename>. If so, the port + number can be omitted. + ''; + }; + + extraConfig = mkOption { + type = types.string; + default = ""; + description = "Extra configuration-lines added to the section of the service."; + }; - options = { - - name = mkOption { - type = types.string; - example = "login"; - description = "Name of the service."; - }; - - protocol = mkOption { - type = types.string; - default = "tcp"; - description = - "Protocol of the service. Usually <literal>tcp</literal> or <literal>udp</literal>."; - }; - - port = mkOption { - type = types.int; - default = 0; - example = 123; - description = "Port number of the service."; - }; - - user = mkOption { - type = types.string; - default = "nobody"; - description = "User account for the service"; - }; - - server = mkOption { - type = types.string; - example = "/foo/bin/ftpd"; - description = "Path of the program that implements the service."; - }; - - serverArgs = mkOption { - type = types.string; - default = ""; - description = "Command-line arguments for the server program."; - }; - - flags = mkOption { - type = types.string; - default = ""; - description = ""; - }; - - unlisted = mkOption { - type = types.bool; - default = false; - description = '' - Whether this server is listed in - <filename>/etc/services</filename>. If so, the port - number can be omitted. - ''; - }; - - extraConfig = mkOption { - type = types.string; - default = ""; - description = "Extra configuration-lines added to the section of the service."; }; - }; + })); }; diff --git a/nixos/modules/services/system/dbus.nix b/nixos/modules/services/system/dbus.nix index 6c4833afbe8b..a7cf74c15cc5 100644 --- a/nixos/modules/services/system/dbus.nix +++ b/nixos/modules/services/system/dbus.nix @@ -8,7 +8,7 @@ let cfg = config.services.dbus; - homeDir = "/var/run/dbus"; + homeDir = "/run/dbus"; systemExtraxml = concatStrings (flip concatMap cfg.packages (d: [ "<servicedir>${d}/share/dbus-1/system-services</servicedir>" @@ -20,15 +20,23 @@ let "<includedir>${d}/etc/dbus-1/session.d</includedir>" ])); - configDir = pkgs.stdenv.mkDerivation { - name = "dbus-conf"; + daemonArgs = "--address=systemd: --nofork --nopidfile --systemd-activation"; - preferLocalBuild = true; - allowSubstitutes = false; - - buildCommand = '' + configDir = pkgs.runCommand "dbus-conf" + { preferLocalBuild = true; + allowSubstitutes = false; + } + '' mkdir -p $out + cp ${pkgs.dbus.out}/share/dbus-1/{system,session}.conf $out + + # avoid circular includes + sed -ri 's@(<include ignore_missing="yes">/etc/dbus-1/(system|session)\.conf</include>)@<!-- \1 -->@g' $out/{system,session}.conf + + # include by full path + sed -ri "s@/etc/dbus-1/(system|session)-@$out/\1-@" $out/{system,session}.conf + sed '${./dbus-system-local.conf.in}' \ -e 's,@servicehelper@,${config.security.wrapperDir}/dbus-daemon-launch-helper,g' \ -e 's,@extra@,${systemExtraxml},' \ @@ -38,7 +46,6 @@ let -e 's,@extra@,${sessionExtraxml},' \ > "$out/session-local.conf" ''; - }; in @@ -75,11 +82,16 @@ in ''; }; + socketActivated = mkOption { + type = types.bool; + default = false; + description = '' + Make the user instance socket activated. + ''; + }; }; - }; - ###### implementation config = mkIf cfg.enable { @@ -117,13 +129,29 @@ in config.system.path ]; - # Don't restart dbus-daemon. Bad things tend to happen if we do. - systemd.services.dbus.reloadIfChanged = true; + systemd.services.dbus = { + # Don't restart dbus-daemon. Bad things tend to happen if we do. + reloadIfChanged = true; + restartTriggers = [ configDir ]; + serviceConfig.ExecStart = [ + "" + "${lib.getBin pkgs.dbus}/bin/dbus-daemon --config-file=${configDir}/system.conf ${daemonArgs}" + ]; + }; - systemd.services.dbus.restartTriggers = [ configDir ]; + systemd.user = { + services.dbus = { + # Don't restart dbus-daemon. Bad things tend to happen if we do. + reloadIfChanged = true; + restartTriggers = [ configDir ]; + serviceConfig.ExecStart = [ + "" + "${lib.getBin pkgs.dbus}/bin/dbus-daemon --config-file=${configDir}/session.conf ${daemonArgs}" + ]; + }; + sockets.dbus.wantedBy = mkIf cfg.socketActivated [ "sockets.target" ]; + }; environment.pathsToLink = [ "/etc/dbus-1" "/share/dbus-1" ]; - }; - } diff --git a/nixos/modules/services/web-apps/selfoss.nix b/nixos/modules/services/web-apps/selfoss.nix new file mode 100644 index 000000000000..5571f77334cc --- /dev/null +++ b/nixos/modules/services/web-apps/selfoss.nix @@ -0,0 +1,166 @@ +{ config, lib, pkgs, ... }: +with lib; +let + cfg = config.services.selfoss; + + poolName = "selfoss_pool"; + phpfpmSocketName = "/var/run/phpfpm/${poolName}.sock"; + + dataDir = "/var/lib/selfoss"; + + selfoss-config = + let + db_type = cfg.database.type; + default_port = if (db_type == "mysql") then 3306 else 5342; + in + pkgs.writeText "selfoss-config.ini" '' + [globals] + ${lib.optionalString (db_type != "sqlite") '' + db_type=${db_type} + db_host=${cfg.database.host} + db_database=${cfg.database.name} + db_username=${cfg.database.user} + db_password=${cfg.database.password} + db_port=${if (cfg.database.port != null) then cfg.database.port + else default_port} + '' + } + ${cfg.extraConfig} + ''; +in + { + options = { + services.selfoss = { + enable = mkEnableOption "selfoss"; + + user = mkOption { + type = types.str; + default = "nginx"; + example = "nginx"; + description = '' + User account under which both the service and the web-application run. + ''; + }; + + pool = mkOption { + type = types.str; + default = "${poolName}"; + description = '' + Name of existing phpfpm pool that is used to run web-application. + If not specified a pool will be created automatically with + default values. + ''; + }; + + database = { + type = mkOption { + type = types.enum ["pgsql" "mysql" "sqlite"]; + default = "sqlite"; + description = '' + Database to store feeds. Supported are sqlite, pgsql and mysql. + ''; + }; + + host = mkOption { + type = types.str; + default = "localhost"; + description = '' + Host of the database (has no effect if type is "sqlite"). + ''; + }; + + name = mkOption { + type = types.str; + default = "tt_rss"; + description = '' + Name of the existing database (has no effect if type is "sqlite"). + ''; + }; + + user = mkOption { + type = types.str; + default = "tt_rss"; + description = '' + The database user. The user must exist and has access to + the specified database (has no effect if type is "sqlite"). + ''; + }; + + password = mkOption { + type = types.nullOr types.str; + default = null; + description = '' + The database user's password (has no effect if type is "sqlite"). + ''; + }; + + port = mkOption { + type = types.nullOr types.int; + default = null; + description = '' + The database's port. If not set, the default ports will be + provided (5432 and 3306 for pgsql and mysql respectively) + (has no effect if type is "sqlite"). + ''; + }; + }; + extraConfig = mkOption { + type = types.lines; + default = ""; + description = '' + Extra configuration added to config.ini + ''; + }; + }; + }; + + config = mkIf cfg.enable { + + services.phpfpm.poolConfigs = mkIf (cfg.pool == "${poolName}") { + "${poolName}" = '' + listen = "${phpfpmSocketName}"; + listen.owner = nginx + listen.group = nginx + listen.mode = 0600 + user = nginx + 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 + ''; + }; + + systemd.services.selfoss-config = { + serviceConfig.Type = "oneshot"; + script = '' + mkdir -m 755 -p ${dataDir} + cd ${dataDir} + + # Delete all but the "data" folder + ls | grep -v data | while read line; do rm -rf $line; done || true + + # Create the files + cp -r "${pkgs.selfoss}/"* "${dataDir}" + ln -sf "${selfoss-config}" "${dataDir}/config.ini" + chown -R "${cfg.user}" "${dataDir}" + chmod -R 755 "${dataDir}" + ''; + wantedBy = [ "multi-user.target" ]; + }; + + systemd.services.selfoss-update = { + serviceConfig = { + ExecStart = "${pkgs.php}/bin/php ${dataDir}/cliupdate.php"; + User = "${cfg.user}"; + }; + startAt = "hourly"; + after = [ "selfoss-config.service" ]; + wantedBy = [ "multi-user.target" ]; + + }; + + }; +} diff --git a/nixos/modules/services/web-apps/tt-rss.nix b/nixos/modules/services/web-apps/tt-rss.nix index b08070f1e366..5193814da725 100644 --- a/nixos/modules/services/web-apps/tt-rss.nix +++ b/nixos/modules/services/web-apps/tt-rss.nix @@ -18,7 +18,6 @@ let poolName = "tt-rss"; phpfpmSocketName = "/var/run/phpfpm/${poolName}.sock"; - virtualHostName = "tt-rss"; tt-rss-config = pkgs.writeText "config.php" '' <?php @@ -34,10 +33,10 @@ let define('MYSQL_CHARSET', 'UTF8'); define('DB_TYPE', '${cfg.database.type}'); - define('DB_HOST', '${cfg.database.host}'); + define('DB_HOST', '${optionalString (cfg.database.host != null) cfg.database.host}'); define('DB_USER', '${cfg.database.user}'); define('DB_NAME', '${cfg.database.name}'); - define('DB_PASS', '${escape ["'" "\\"] cfg.database.password}'); + define('DB_PASS', '${optionalString (cfg.database.password != null) (escape ["'" "\\"] cfg.database.password)}'); define('DB_PORT', '${toString dbPort}'); define('AUTH_AUTO_CREATE', ${boolToString cfg.auth.autoCreate}); @@ -91,12 +90,21 @@ let enable = mkEnableOption "tt-rss"; + root = mkOption { + type = types.path; + default = "/var/lib/tt-rss"; + example = "/var/lib/tt-rss"; + description = '' + Root of the application. + ''; + }; + user = mkOption { type = types.str; default = "nginx"; example = "nginx"; description = '' - User account under which both the service and the web-application run. + User account under which both the update daemon and the web-application run. ''; }; @@ -110,17 +118,13 @@ let ''; }; - # TODO: Re-enable after https://github.com/NixOS/nixpkgs/pull/15862 is merged - - # virtualHost = mkOption { - # type = types.str; - # default = "${virtualHostName}"; - # description = '' - # Name of existing nginx virtual host that is used to run web-application. - # If not specified a host will be created automatically with - # default values. - # ''; - # }; + virtualHost = mkOption { + type = types.nullOr types.str; + default = "tt-rss"; + description = '' + Name of the nginx virtualhost to use and setup. If null, do not setup any virtualhost. + ''; + }; database = { type = mkOption { @@ -132,10 +136,10 @@ let }; host = mkOption { - type = types.str; - default = "localhost"; + type = types.nullOr types.str; + default = null; description = '' - Host of the database. + Host of the database. Leave null to use Unix domain socket. ''; }; @@ -362,7 +366,7 @@ let singleUserMode = mkOption { type = types.bool; - default = true; + default = false; description = '' Operate in single user mode, disables all functionality related to @@ -445,17 +449,15 @@ let ###### implementation - config = let - root = "/var/lib/tt-rss"; - in mkIf cfg.enable { + config = mkIf cfg.enable { - services.phpfpm.poolConfigs = if cfg.pool == "${poolName}" then { + services.phpfpm.poolConfigs = mkIf (cfg.pool == "${poolName}") { "${poolName}" = '' listen = "${phpfpmSocketName}"; listen.owner = nginx listen.group = nginx listen.mode = 0600 - user = nginx + user = ${cfg.user} pm = dynamic pm.max_children = 75 pm.start_servers = 10 @@ -464,36 +466,26 @@ let pm.max_requests = 500 catch_workers_output = 1 ''; - } else {}; - - # TODO: Re-enable after https://github.com/NixOS/nixpkgs/pull/15862 is merged - - # services.nginx.virtualHosts = if cfg.virtualHost == "${virtualHostName}" then { - # "${virtualHostName}" = { - # root = "${root}"; - # extraConfig = '' - # access_log /var/log/nginx-${virtualHostName}-access.log; - # error_log /var/log/nginx-${virtualHostName}-error.log; - # ''; - - # locations."/" = { - # extraConfig = '' - # index index.php; - # ''; - # }; - - # locations."~ \.php$" = { - # extraConfig = '' - # fastcgi_split_path_info ^(.+\.php)(/.+)$; - # fastcgi_pass unix:${phpfpmSocketName}; - # fastcgi_index index.php; - # fastcgi_param SCRIPT_FILENAME ${root}/$fastcgi_script_name; - - # include ${pkgs.nginx}/conf/fastcgi_params; - # ''; - # }; - # }; - # } else {}; + }; + + services.nginx.virtualHosts = mkIf (cfg.virtualHost != null) { + "${cfg.virtualHost}" = { + root = "${cfg.root}"; + + locations."/" = { + index = "index.php"; + }; + + locations."~ \.php$" = { + extraConfig = '' + fastcgi_split_path_info ^(.+\.php)(/.+)$; + fastcgi_pass unix:${phpfpmSocketName}; + fastcgi_index index.php; + fastcgi_param SCRIPT_FILENAME ${cfg.root}/$fastcgi_script_name; + ''; + }; + }; + }; systemd.services.tt-rss = let @@ -503,35 +495,34 @@ let description = "Tiny Tiny RSS feeds update daemon"; preStart = let - callSql = if cfg.database.type == "pgsql" then (e: '' - ${optionalString (cfg.database.password != null) - "PGPASSWORD=${cfg.database.password}"} ${pkgs.postgresql95}/bin/psql \ - -U ${cfg.database.user} \ - -h ${cfg.database.host} \ - --port ${toString dbPort} \ - -c '${e}' \ - ${cfg.database.name}'') - - else if cfg.database.type == "mysql" then (e: '' - echo '${e}' | ${pkgs.mysql}/bin/mysql \ - ${optionalString (cfg.database.password != null) - "-p${cfg.database.password}"} \ - -u ${cfg.database.user} \ - -h ${cfg.database.host} \ - -P ${toString dbPort} \ - ${cfg.database.name}'') - - else ""; + callSql = e: + if cfg.database.type == "pgsql" then '' + ${optionalString (cfg.database.password != null) "PGPASSWORD=${cfg.database.password}"} \ + ${pkgs.postgresql95}/bin/psql \ + -U ${cfg.database.user} \ + ${optionalString (cfg.database.host != null) "-h ${cfg.database.host} --port ${toString dbPort}"} \ + -c '${e}' \ + ${cfg.database.name}'' + + else if cfg.database.type == "mysql" then '' + echo '${e}' | ${pkgs.mysql}/bin/mysql \ + -u ${cfg.database.user} \ + ${optionalString (cfg.database.password != null) "-p${cfg.database.password}"} \ + ${optionalString (cfg.database.host != null) "-h ${cfg.database.host} -P ${toString dbPort}"} \ + ${cfg.database.name}'' + + else ""; in '' - rm -rf "${root}/*" - mkdir -m 755 -p "${root}" - cp -r "${pkgs.tt-rss}/"* "${root}" - ln -sf "${tt-rss-config}" "${root}/config.php" - chown -R "${cfg.user}" "${root}" - chmod -R 755 "${root}" - '' + (optionalString (cfg.database.type == "pgsql") '' - + rm -rf "${cfg.root}/*" + mkdir -m 755 -p "${cfg.root}" + cp -r "${pkgs.tt-rss}/"* "${cfg.root}" + ln -sf "${tt-rss-config}" "${cfg.root}/config.php" + chown -R "${cfg.user}" "${cfg.root}" + chmod -R 755 "${cfg.root}" + '' + + + (optionalString (cfg.database.type == "pgsql") '' exists=$(${callSql "select count(*) > 0 from pg_tables where tableowner = user"} \ | tail -n+3 | head -n-2 | sed -e 's/[ \n\t]*//') @@ -540,8 +531,9 @@ let else echo 'The database contains some data. Leaving it as it is.' fi; - '') + (optionalString (cfg.database.type == "mysql") '' + '') + + (optionalString (cfg.database.type == "mysql") '' exists=$(${callSql "select count(*) > 0 from information_schema.tables where table_schema = schema()"} \ | tail -n+2 | sed -e 's/[ \n\t]*//') @@ -554,7 +546,7 @@ let serviceConfig = { User = "${cfg.user}"; - ExecStart = "${pkgs.php}/bin/php /var/lib/tt-rss/update.php --daemon"; + ExecStart = "${pkgs.php}/bin/php ${cfg.root}/update.php --daemon"; StandardOutput = "syslog"; StandardError = "syslog"; PermissionsStartOnly = true; diff --git a/nixos/modules/services/web-servers/apache-httpd/mediawiki.nix b/nixos/modules/services/web-servers/apache-httpd/mediawiki.nix index b4b5a6fdc07e..4f9e9f52f9e0 100644 --- a/nixos/modules/services/web-servers/apache-httpd/mediawiki.nix +++ b/nixos/modules/services/web-servers/apache-httpd/mediawiki.nix @@ -83,11 +83,11 @@ let # Unpack Mediawiki and put the config file in its root directory. mediawikiRoot = pkgs.stdenv.mkDerivation rec { - name= "mediawiki-1.23.13"; + name= "mediawiki-1.27.1"; src = pkgs.fetchurl { - url = "http://download.wikimedia.org/mediawiki/1.23/${name}.tar.gz"; - sha256 = "168wpf53n4ksj2g5q5r0hxapx6238dvsfng5ff9ixk6axsn0j5d0"; + url = "http://download.wikimedia.org/mediawiki/1.27/${name}.tar.gz"; + sha256 = "0sm3ymz93qragbwhzzbwq7f127mbj29inv0afg2z6p32jb1pd9h8"; }; skins = config.skins; diff --git a/nixos/modules/services/web-servers/apache-httpd/moodle.nix b/nixos/modules/services/web-servers/apache-httpd/moodle.nix index 87b1fba5aa10..aa00e89967db 100644 --- a/nixos/modules/services/web-servers/apache-httpd/moodle.nix +++ b/nixos/modules/services/web-servers/apache-httpd/moodle.nix @@ -63,6 +63,10 @@ let cp -r * $out cp ${moodleConfig} $out/config.php ''; + # Marked as broken due to needing an update for security issues. + # See: https://github.com/NixOS/nixpkgs/issues/18856 + meta.broken = true; + }; in diff --git a/nixos/modules/services/web-servers/apache-httpd/wordpress.nix b/nixos/modules/services/web-servers/apache-httpd/wordpress.nix index 495c1abb0521..2315c4729aec 100644 --- a/nixos/modules/services/web-servers/apache-httpd/wordpress.nix +++ b/nixos/modules/services/web-servers/apache-httpd/wordpress.nix @@ -5,7 +5,8 @@ with lib; let - version = "4.3.1"; + # Upgrading? We have a test! nix-build ./nixos/tests/wordpress.nix + version = "4.6.1"; fullversion = "${version}"; # Our bare-bones wp-config.php file using the above settings @@ -74,7 +75,7 @@ let owner = "WordPress"; repo = "WordPress"; rev = "${fullversion}"; - sha256 = "1rk10vcv4z9p04hfzc0wkbilrgx7m9ssyr6c3w6vw3vl1bcgqxza"; + sha256 = "0n82xgjg1ry2p73hhgpslnkdzrma5n6hxxq76s7qskkzj0qjfvpn"; }; installPhase = '' mkdir -p $out @@ -98,7 +99,7 @@ let # symlink additional plugin(s) ${concatMapStrings (plugin: "ln -s ${plugin} $out/wp-content/plugins/${plugin.name}\n") (config.plugins) } - # symlink additional translation(s) + # symlink additional translation(s) mkdir -p $out/wp-content/languages ${concatMapStrings (language: "ln -s ${language}/*.mo ${language}/*.po $out/wp-content/languages/\n") (selectedLanguages) } ''; @@ -123,7 +124,7 @@ in options = { dbHost = mkOption { default = "localhost"; - description = "The location of the database server."; + description = "The location of the database server."; example = "localhost"; }; dbName = mkOption { @@ -252,7 +253,7 @@ in done ${pkgs.mysql}/bin/mysql -e 'CREATE DATABASE ${config.dbName};' ${pkgs.mysql}/bin/mysql -e 'GRANT ALL ON ${config.dbName}.* TO ${config.dbUser}@localhost IDENTIFIED BY "${config.dbPassword}";' - else + else echo "Good, no need to do anything database related." fi ''; diff --git a/nixos/modules/services/web-servers/nginx/default.nix b/nixos/modules/services/web-servers/nginx/default.nix index 94c442e165b7..443bd8c10000 100644 --- a/nixos/modules/services/web-servers/nginx/default.nix +++ b/nixos/modules/services/web-servers/nginx/default.nix @@ -18,9 +18,13 @@ let ${cfg.config} - ${optionalString (cfg.httpConfig == "" && cfg.config == "") '' - events {} + ${optionalString (cfg.eventsConfig != "" || cfg.config == "") '' + events { + ${cfg.eventsConfig} + } + ''} + ${optionalString (cfg.httpConfig == "" && cfg.config == "") '' http { include ${cfg.package}/conf/mime.types; include ${cfg.package}/conf/fastcgi.conf; @@ -98,7 +102,6 @@ let }''} ${optionalString (cfg.httpConfig != "") '' - events {} http { include ${cfg.package}/conf/mime.types; include ${cfg.package}/conf/fastcgi.conf; @@ -272,12 +275,20 @@ in "; }; + eventsConfig = mkOption { + type = types.lines; + default = ""; + description = '' + Configuration lines to be set inside the events block. + ''; + }; + appendHttpConfig = mkOption { type = types.lines; default = ""; description = " Configuration lines to be appended to the generated http block. - This is mutually exclusive with using config and httpConfig for + This is mutually exclusive with using config and httpConfig for specifying the whole http block verbatim. "; }; diff --git a/nixos/modules/services/web-servers/phpfpm/default.nix b/nixos/modules/services/web-servers/phpfpm/default.nix index 29cfbb8e9a08..a3a23b222fbb 100644 --- a/nixos/modules/services/web-servers/phpfpm/default.nix +++ b/nixos/modules/services/web-servers/phpfpm/default.nix @@ -42,7 +42,7 @@ in { default = ""; description = '' Extra configuration that should be put in the global section of - the PHP FPM configuration file. Do not specify the options + the PHP-FPM configuration file. Do not specify the options <literal>pid</literal>, <literal>error_log</literal> or <literal>daemonize</literal> here, since they are generated by NixOS. @@ -54,7 +54,7 @@ in { default = pkgs.php; defaultText = "pkgs.php"; description = '' - The PHP package to use for running the FPM service. + The PHP package to use for running the PHP-FPM service. ''; }; @@ -86,7 +86,7 @@ in { } ''; description = '' - A mapping between PHP FPM pool names and their configurations. + A mapping between PHP-FPM pool names and their configurations. See the documentation on <literal>php-fpm.conf</literal> for details on configuration directives. If no pools are defined, the phpfpm service is disabled. @@ -98,8 +98,24 @@ in { inherit lib; })); default = {}; + example = literalExample '' + { + mypool = { + listen = "/path/to/unix/socket"; + extraConfig = ''' + user = nobody + pm = dynamic + pm.max_children = 75 + pm.start_servers = 10 + pm.min_spare_servers = 5 + pm.max_spare_servers = 20 + pm.max_requests = 500 + '''; + } + }''; description = '' - If no pools are defined, the phpfpm service is disabled. + PHP-FPM pools. If no pools or poolConfigs are defined, the PHP-FPM + service is disabled. ''; }; }; diff --git a/nixos/modules/services/web-servers/winstone.nix b/nixos/modules/services/web-servers/winstone.nix index 6dab467b35ef..064ead5ce4bb 100644 --- a/nixos/modules/services/web-servers/winstone.nix +++ b/nixos/modules/services/web-servers/winstone.nix @@ -113,8 +113,7 @@ in { options = { services.winstone = mkOption { default = {}; - type = types.attrsOf types.optionSet; - options = [ winstoneOpts ]; + type = with types; attrsOf (submodule winstoneOpts); description = '' Defines independent Winstone services, each serving one WAR-file. ''; diff --git a/nixos/modules/services/web-servers/zope2.nix b/nixos/modules/services/web-servers/zope2.nix index ef3cffd582ee..8a453e015577 100644 --- a/nixos/modules/services/web-servers/zope2.nix +++ b/nixos/modules/services/web-servers/zope2.nix @@ -74,7 +74,7 @@ in services.zope2.instances = mkOption { default = {}; - type = types.loaOf types.optionSet; + type = with types; loaOf (submodule zope2Opts); example = literalExample '' { plone01 = { @@ -96,7 +96,6 @@ in } ''; description = "zope2 instances to be created automaticaly by the system."; - options = [ zope2Opts ]; }; }; diff --git a/nixos/modules/services/x11/desktop-managers/enlightenment.nix b/nixos/modules/services/x11/desktop-managers/enlightenment.nix index 8a03dd65b335..7ea8b30d23d1 100644 --- a/nixos/modules/services/x11/desktop-managers/enlightenment.nix +++ b/nixos/modules/services/x11/desktop-managers/enlightenment.nix @@ -32,10 +32,10 @@ in e.efl e.enlightenment e.terminology e.econnman pkgs.xorg.xauth # used by kdesu - pkgs.gtk # To get GTK+'s themes. + pkgs.gtk2 # To get GTK+'s themes. pkgs.tango-icon-theme pkgs.shared_mime_info - pkgs.gnome.gnomeicontheme + pkgs.gnome2.gnomeicontheme pkgs.xorg.xcursorthemes ]; diff --git a/nixos/modules/services/x11/desktop-managers/gnome3.nix b/nixos/modules/services/x11/desktop-managers/gnome3.nix index b3da25448029..dc71531759b8 100644 --- a/nixos/modules/services/x11/desktop-managers/gnome3.nix +++ b/nixos/modules/services/x11/desktop-managers/gnome3.nix @@ -25,9 +25,8 @@ let ''; }; - nixos-gsettings-desktop-schemas = pkgs.stdenv.mkDerivation { - name = "nixos-gsettings-desktop-schemas"; - buildCommand = '' + nixos-gsettings-desktop-schemas = pkgs.runCommand "nixos-gsettings-desktop-schemas" {} + '' mkdir -p $out/share/gsettings-schemas/nixos-gsettings-overrides/glib-2.0/schemas cp -rf ${gnome3.gsettings_desktop_schemas}/share/gsettings-schemas/gsettings-desktop-schemas*/glib-2.0/schemas/*.xml $out/share/gsettings-schemas/nixos-gsettings-overrides/glib-2.0/schemas @@ -46,7 +45,6 @@ let ${pkgs.glib.dev}/bin/glib-compile-schemas $out/share/gsettings-schemas/nixos-gsettings-overrides/glib-2.0/schemas/ ''; - }; in { diff --git a/nixos/modules/services/x11/desktop-managers/kde4.nix b/nixos/modules/services/x11/desktop-managers/kde4.nix index 1927341e45d4..3aa4821a0521 100644 --- a/nixos/modules/services/x11/desktop-managers/kde4.nix +++ b/nixos/modules/services/x11/desktop-managers/kde4.nix @@ -14,7 +14,7 @@ let # files), segfault sometimes and consume significant resources. # They can be re-enabled in the KDE System Settings under "Desktop # Search". - nepomukConfig = pkgs.writeTextFile + disableNepomuk = pkgs.writeTextFile { name = "nepomuk-config"; destination = "/share/config/nepomukserverrc"; text = @@ -70,6 +70,18 @@ in type = types.package; description = "Custom kde-workspace, used for NixOS rebranding."; }; + + enablePIM = mkOption { + type = types.bool; + default = true; + description = "Whether to enable PIM support. Note that enabling this pulls in Akonadi and MariaDB as dependencies."; + }; + + enableNepomuk = mkOption { + type = types.bool; + default = false; + description = "Whether to enable Nepomuk (deprecated)."; + }; }; }; @@ -138,7 +150,6 @@ in pkgs.kde4.kde_wallpapers # contains kdm's default background pkgs.kde4.oxygen_icons - pkgs.virtuoso # to enable Nepomuk to find Virtuoso # Starts KDE's Polkit authentication agent. pkgs.kde4.polkit_kde_agent @@ -149,20 +160,26 @@ in xorg.xmessage # so that startkde can show error messages xorg.xset # used by startkde, non-essential xorg.xauth # used by kdesu - pkgs.shared_desktop_ontologies # used by nepomuk - pkgs.strigi # used by nepomuk + ] + ++ optionals cfg.enablePIM + [ pkgs.kde4.kdepim_runtime pkgs.kde4.akonadi pkgs.mysql # used by akonadi - pkgs.kde4.kdepim_runtime ] - ++ lib.optional config.hardware.pulseaudio.enable pkgs.kde4.kmix # Perhaps this should always be enabled - ++ lib.optional config.hardware.bluetooth.enable pkgs.kde4.bluedevil - ++ lib.optional config.networking.networkmanager.enable pkgs.kde4.plasma-nm - ++ [ nepomukConfig ] ++ phononBackendPackages; + ++ (if cfg.enableNepomuk then + [ pkgs.shared_desktop_ontologies # used by nepomuk + pkgs.strigi # used by nepomuk + pkgs.virtuoso # to enable Nepomuk to find Virtuoso + ] else + [ disableNepomuk ]) + ++ optional config.hardware.pulseaudio.enable pkgs.kde4.kmix # Perhaps this should always be enabled + ++ optional config.hardware.bluetooth.enable pkgs.kde4.bluedevil + ++ optional config.networking.networkmanager.enable pkgs.kde4.plasma-nm + ++ phononBackendPackages; environment.pathsToLink = [ "/share" ]; - environment.profileRelativeEnvVars = mkIf (lib.elem "gstreamer" cfg.phononBackends) { + environment.profileRelativeEnvVars = mkIf (elem "gstreamer" cfg.phononBackends) { GST_PLUGIN_SYSTEM_PATH = [ "/lib/gstreamer-0.10" ]; }; diff --git a/nixos/modules/services/x11/desktop-managers/xfce.nix b/nixos/modules/services/x11/desktop-managers/xfce.nix index 634d2a39576a..51d7d905d587 100644 --- a/nixos/modules/services/x11/desktop-managers/xfce.nix +++ b/nixos/modules/services/x11/desktop-managers/xfce.nix @@ -69,7 +69,7 @@ in services.xserver.updateDbusEnvironment = true; environment.systemPackages = - [ pkgs.gtk # To get GTK+'s themes. + [ pkgs.gtk2 # To get GTK+'s themes. pkgs.hicolor_icon_theme pkgs.tango-icon-theme pkgs.shared_mime_info @@ -100,6 +100,7 @@ in pkgs.xfce.tumbler # found via dbus ] ++ optional config.powerManagement.enable pkgs.xfce.xfce4_power_manager + ++ optional config.networking.networkmanager.enable pkgs.networkmanagerapplet ++ optionals (!cfg.noDesktop) [ pkgs.xfce.xfce4panel pkgs.xfce.xfdesktop diff --git a/nixos/modules/services/x11/display-managers/default.nix b/nixos/modules/services/x11/display-managers/default.nix index 75d80609f73f..ce82af4ca68c 100644 --- a/nixos/modules/services/x11/display-managers/default.nix +++ b/nixos/modules/services/x11/display-managers/default.nix @@ -134,13 +134,8 @@ let (*) echo "$0: Desktop manager '$desktopManager' not found.";; esac - # FIXME: gdbus should not be in glib.dev! - ${optionalString (cfg.startDbusSession && cfg.updateDbusEnvironment) '' - ${pkgs.glib.dev}/bin/gdbus call --session \ - --dest org.freedesktop.DBus --object-path /org/freedesktop/DBus \ - --method org.freedesktop.DBus.UpdateActivationEnvironment \ - "{$(env | ${pkgs.gnused}/bin/sed "s/'/\\\\'/g; s/\([^=]*\)=\(.*\)/'\1':'\2'/" \ - | ${pkgs.coreutils}/bin/paste -sd,)}" + ${optionalString cfg.updateDbusEnvironment '' + ${lib.getBin pkgs.dbus}/bin/dbus-update-activation-environment --systemd --all ''} test -n "$waitPID" && wait "$waitPID" diff --git a/nixos/modules/services/x11/display-managers/kdm.nix b/nixos/modules/services/x11/display-managers/kdm.nix index d9f7f8f0dfc4..8b51c621e112 100644 --- a/nixos/modules/services/x11/display-managers/kdm.nix +++ b/nixos/modules/services/x11/display-managers/kdm.nix @@ -54,19 +54,17 @@ let ''} ''; - kdmrc = pkgs.stdenv.mkDerivation { - name = "kdmrc"; - config = defaultConfig + cfg.extraConfig; - preferLocalBuild = true; - buildCommand = - '' - echo "$config" > $out + kdmrc = pkgs.runCommand "kdmrc" + { config = defaultConfig + cfg.extraConfig; + preferLocalBuild = true; + } + '' + echo "$config" > $out - # The default kdmrc would add "-nolisten tcp", and we already - # have that managed by nixos. Hence the grep. - cat ${kdebase_workspace}/share/config/kdm/kdmrc | grep -v nolisten >> $out - ''; - }; + # The default kdmrc would add "-nolisten tcp", and we already + # have that managed by nixos. Hence the grep. + cat ${kdebase_workspace}/share/config/kdm/kdmrc | grep -v nolisten >> $out + ''; in 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 543dd628ce66..dfda90978b1e 100644 --- a/nixos/modules/services/x11/display-managers/lightdm-greeters/gtk.nix +++ b/nixos/modules/services/x11/display-managers/lightdm-greeters/gtk.nix @@ -16,11 +16,9 @@ let # The default greeter provided with this expression is the GTK greeter. # Again, we need a few things in the environment for the greeter to run with # fonts/icons. - wrappedGtkGreeter = stdenv.mkDerivation { - name = "lightdm-gtk-greeter"; - buildInputs = [ pkgs.makeWrapper ]; - - buildCommand = '' + wrappedGtkGreeter = pkgs.runCommand "lightdm-gtk-greeter" + { buildInputs = [ pkgs.makeWrapper ]; } + '' # This wrapper ensures that we actually get themes makeWrapper ${pkgs.lightdm_gtk_greeter}/sbin/lightdm-gtk-greeter \ $out/greeter \ @@ -40,7 +38,6 @@ let Type=Application EOF ''; - }; gtkGreeterConf = writeText "lightdm-gtk-greeter.conf" '' diff --git a/nixos/modules/services/x11/display-managers/lightdm.nix b/nixos/modules/services/x11/display-managers/lightdm.nix index 47786f0a4321..33cd51f37c68 100644 --- a/nixos/modules/services/x11/display-managers/lightdm.nix +++ b/nixos/modules/services/x11/display-managers/lightdm.nix @@ -46,13 +46,15 @@ let [Seat:*] xserver-command = ${xserverWrapper} session-wrapper = ${dmcfg.session.script} + ${optionalString (elem defaultSessionName dmcfg.session.names) '' + user-session = ${defaultSessionName} + ''} ${optionalString cfg.greeter.enable '' greeter-session = ${cfg.greeter.name} ''} ${optionalString cfg.autoLogin.enable '' autologin-user = ${cfg.autoLogin.user} autologin-user-timeout = ${toString cfg.autoLogin.timeout} - autologin-session = ${defaultSessionName} ''} ${cfg.extraSeatDefaults} ''; diff --git a/nixos/modules/services/x11/display-managers/sddm.nix b/nixos/modules/services/x11/display-managers/sddm.nix index 16d1e89e8d96..4d2ddedca1ea 100644 --- a/nixos/modules/services/x11/display-managers/sddm.nix +++ b/nixos/modules/services/x11/display-managers/sddm.nix @@ -46,7 +46,7 @@ let HideUsers=${concatStringsSep "," dmcfg.hiddenUsers} HideShells=/run/current-system/sw/bin/nologin - [XDisplay] + [X11] MinimumVT=${toString xcfg.tty} ServerPath=${xserverWrapper} XephyrPath=${pkgs.xorg.xorgserver.out}/bin/Xephyr @@ -100,7 +100,7 @@ in theme = mkOption { type = types.str; - default = "maui"; + default = ""; description = '' Greeter theme to use. ''; diff --git a/nixos/modules/services/x11/display-managers/slim.nix b/nixos/modules/services/x11/display-managers/slim.nix index ce44c9f54a31..ca2ae1a47726 100644 --- a/nixos/modules/services/x11/display-managers/slim.nix +++ b/nixos/modules/services/x11/display-managers/slim.nix @@ -26,15 +26,13 @@ let # Unpack the SLiM theme, or use the default. slimThemesDir = let - unpackedTheme = pkgs.stdenv.mkDerivation { - name = "slim-theme"; - buildCommand = '' + unpackedTheme = pkgs.runCommand "slim-theme" {} + '' mkdir -p $out cd $out unpackFile ${cfg.theme} ln -s * default ''; - }; in if cfg.theme == null then "${pkgs.slim}/share/slim/themes" else unpackedTheme; in diff --git a/nixos/modules/services/x11/window-managers/awesome.nix b/nixos/modules/services/x11/window-managers/awesome.nix index 455b3568499f..eb97449c6bd9 100644 --- a/nixos/modules/services/x11/window-managers/awesome.nix +++ b/nixos/modules/services/x11/window-managers/awesome.nix @@ -6,7 +6,7 @@ let cfg = config.services.xserver.windowManager.awesome; awesome = cfg.package; - + inherit (pkgs.luaPackages) getLuaPath getLuaCPath; in { @@ -46,10 +46,8 @@ in { name = "awesome"; start = '' - ${concatMapStrings (pkg: '' - export LUA_CPATH=$LUA_CPATH''${LUA_CPATH:+;}${pkg}/lib/lua/${awesome.lua.luaversion}/?.so - export LUA_PATH=$LUA_PATH''${LUA_PATH:+;}${pkg}/lib/lua/${awesome.lua.luaversion}/?.lua - '') cfg.luaModules} + export LUA_CPATH="${lib.concatStringsSep ";" (map getLuaCPath cfg.luaModules)}" + export LUA_PATH="${lib.concatStringsSep ";" (map getLuaPath cfg.luaModules)}" ${awesome}/bin/awesome & waitPID=$! @@ -59,5 +57,4 @@ in environment.systemPackages = [ awesome ]; }; - } diff --git a/nixos/modules/services/x11/xserver.nix b/nixos/modules/services/x11/xserver.nix index 6c6a1e79ed0e..1bd578424ee4 100644 --- a/nixos/modules/services/x11/xserver.nix +++ b/nixos/modules/services/x11/xserver.nix @@ -71,15 +71,11 @@ let monitors = reverseList (foldl mkMonitor [] xrandrHeads); in concatMapStrings (getAttr "value") monitors; - configFile = pkgs.stdenv.mkDerivation { - name = "xserver.conf"; - - xfs = optionalString (cfg.useXFS != false) - ''FontPath "${toString cfg.useXFS}"''; - - inherit (cfg) config; - - buildCommand = + configFile = pkgs.runCommand "xserver.conf" + { xfs = optionalString (cfg.useXFS != false) + ''FontPath "${toString cfg.useXFS}"''; + inherit (cfg) config; + } '' echo 'Section "Files"' >> $out echo $xfs >> $out @@ -102,7 +98,6 @@ let echo "$config" >> $out ''; # */ - }; in diff --git a/nixos/modules/system/activation/activation-script.nix b/nixos/modules/system/activation/activation-script.nix index 60298362d767..4a16a6762935 100644 --- a/nixos/modules/system/activation/activation-script.nix +++ b/nixos/modules/system/activation/activation-script.nix @@ -142,10 +142,10 @@ in # Empty, immutable home directory of many system accounts. mkdir -p /var/empty # Make sure it's really empty - ${pkgs.e2fsprogs}/bin/chattr -i /var/empty + ${pkgs.e2fsprogs}/bin/chattr -f -i /var/empty || true find /var/empty -mindepth 1 -delete chmod 0555 /var/empty - ${pkgs.e2fsprogs}/bin/chattr +i /var/empty + ${pkgs.e2fsprogs}/bin/chattr -f +i /var/empty || true ''; system.activationScripts.usrbinenv = if config.environment.usrbinenv != null @@ -159,7 +159,7 @@ in rmdir --ignore-fail-on-non-empty /usr/bin /usr ''; - system.activationScripts.tmpfs = + system.activationScripts.specialfs = '' specialMount() { local device="$1" @@ -167,7 +167,12 @@ in local options="$3" local fsType="$4" - ${pkgs.utillinux}/bin/mount -t "$fsType" -o "remount,$options" "$device" "$mountPoint" + if ${pkgs.utillinux}/bin/mountpoint -q "$mountPoint"; then + local options="remount,$options" + else + mkdir -m 0755 -p "$mountPoint" + fi + ${pkgs.utillinux}/bin/mount -t "$fsType" -o "$options" "$device" "$mountPoint" } source ${config.system.build.earlyMountScript} ''; diff --git a/nixos/modules/system/activation/switch-to-configuration.pl b/nixos/modules/system/activation/switch-to-configuration.pl index bb97d0c53a6b..8747c1e3d4ac 100644 --- a/nixos/modules/system/activation/switch-to-configuration.pl +++ b/nixos/modules/system/activation/switch-to-configuration.pl @@ -213,33 +213,30 @@ while (my ($unit, $state) = each %{$activePrev}) { elsif (!boolIsTrue($unitInfo->{'X-RestartIfChanged'} // "yes") || boolIsTrue($unitInfo->{'RefuseManualStop'} // "no") ) { $unitsToSkip{$unit} = 1; } else { - # If this unit is socket-activated, then stop the - # socket unit(s) as well, and restart the - # socket(s) instead of the service. - my $socketActivated = 0; - if ($unit =~ /\.service$/) { - my @sockets = split / /, ($unitInfo->{Sockets} // ""); - if (scalar @sockets == 0) { - @sockets = ("$baseName.socket"); - } - foreach my $socket (@sockets) { - if (defined $activePrev->{$socket}) { - $unitsToStop{$unit} = 1; - $unitsToStart{$unit} = 1; - recordUnit($startListFile, $socket); - $socketActivated = 1; - } - } - } - if (!boolIsTrue($unitInfo->{'X-StopIfChanged'} // "yes")) { - # This unit should be restarted instead of # stopped and started. $unitsToRestart{$unit} = 1; recordUnit($restartListFile, $unit); - } else { + # If this unit is socket-activated, then stop the + # socket unit(s) as well, and restart the + # socket(s) instead of the service. + my $socketActivated = 0; + if ($unit =~ /\.service$/) { + my @sockets = split / /, ($unitInfo->{Sockets} // ""); + if (scalar @sockets == 0) { + @sockets = ("$baseName.socket"); + } + foreach my $socket (@sockets) { + if (defined $activePrev->{$socket}) { + $unitsToStop{$socket} = 1; + $unitsToStart{$socket} = 1; + recordUnit($startListFile, $socket); + $socketActivated = 1; + } + } + } # If the unit is not socket-activated, record # that this unit needs to be started below. @@ -251,7 +248,6 @@ while (my ($unit, $state) = each %{$activePrev}) { } $unitsToStop{$unit} = 1; - } } } diff --git a/nixos/modules/system/boot/initrd-ssh.nix b/nixos/modules/system/boot/initrd-ssh.nix index bc899984c57d..a8c7d4b3ee5e 100644 --- a/nixos/modules/system/boot/initrd-ssh.nix +++ b/nixos/modules/system/boot/initrd-ssh.nix @@ -85,10 +85,14 @@ in }; config = mkIf (config.boot.initrd.network.enable && cfg.enable) { - assertions = [ { - assertion = cfg.hostRSAKey != null || cfg.hostDSSKey != null || cfg.hostECDSAKey != null; - message = "You should specify at least one host key for initrd SSH"; - } ]; + assertions = [ + { assertion = cfg.hostRSAKey != null || cfg.hostDSSKey != null || cfg.hostECDSAKey != null; + message = "You should specify at least one host key for initrd SSH"; + } + { assertion = cfg.authorizedKeys != []; + message = "You should specify at least one authorized key for initrd SSH"; + } + ]; boot.initrd.extraUtilsCommands = '' copy_bin_and_libs ${pkgs.dropbear}/bin/dropbear diff --git a/nixos/modules/system/boot/loader/grub/grub.nix b/nixos/modules/system/boot/loader/grub/grub.nix index 61c34cc2f034..c3be7407d592 100644 --- a/nixos/modules/system/boot/loader/grub/grub.nix +++ b/nixos/modules/system/boot/loader/grub/grub.nix @@ -55,7 +55,7 @@ let inherit (cfg) version extraConfig extraPerEntryConfig extraEntries extraEntriesBeforeNixOS extraPrepareConfig configurationLimit copyKernels - default fsIdentifier efiSupport gfxmodeEfi gfxmodeBios; + default fsIdentifier efiSupport efiInstallAsRemovable gfxmodeEfi gfxmodeBios; path = (makeBinPath ([ pkgs.coreutils pkgs.gnused pkgs.gnugrep pkgs.findutils pkgs.diffutils pkgs.btrfs-progs pkgs.utillinux ] ++ (if cfg.efiSupport && (cfg.version == 2) then [pkgs.efibootmgr ] else []) @@ -131,51 +131,51 @@ in to the respective devices corresponding to those partitions. ''; - type = types.listOf types.optionSet; + type = with types; listOf (submodule { + options = { + + path = mkOption { + example = "/boot1"; + type = types.str; + description = '' + The path to the boot directory where GRUB will be written. Generally + this boot path should double as an EFI path. + ''; + }; + + efiSysMountPoint = mkOption { + default = null; + example = "/boot1/efi"; + type = types.nullOr types.str; + description = '' + The path to the efi system mount point. Usually this is the same + partition as the above path and can be left as null. + ''; + }; + + efiBootloaderId = mkOption { + default = null; + example = "NixOS-fsid"; + type = types.nullOr types.str; + description = '' + The id of the bootloader to store in efi nvram. + The default is to name it NixOS and append the path or efiSysMountPoint. + This is only used if <literal>boot.loader.efi.canTouchEfiVariables</literal> is true. + ''; + }; + + devices = mkOption { + default = [ ]; + example = [ "/dev/sda" "/dev/sdb" ]; + type = types.listOf types.str; + description = '' + The path to the devices which will have the GRUB MBR written. + Note these are typically device paths and not paths to partitions. + ''; + }; - options = { - - path = mkOption { - example = "/boot1"; - type = types.str; - description = '' - The path to the boot directory where GRUB will be written. Generally - this boot path should double as an EFI path. - ''; - }; - - efiSysMountPoint = mkOption { - default = null; - example = "/boot1/efi"; - type = types.nullOr types.str; - description = '' - The path to the efi system mount point. Usually this is the same - partition as the above path and can be left as null. - ''; - }; - - efiBootloaderId = mkOption { - default = null; - example = "NixOS-fsid"; - type = types.nullOr types.str; - description = '' - The id of the bootloader to store in efi nvram. - The default is to name it NixOS and append the path or efiSysMountPoint. - This is only used if <literal>boot.loader.efi.canTouchEfiVariables</literal> is true. - ''; }; - - devices = mkOption { - default = [ ]; - example = [ "/dev/sda" "/dev/sdb" ]; - type = types.listOf types.str; - description = '' - The path to the devices which will have the GRUB MBR written. - Note these are typically device paths and not paths to partitions. - ''; - }; - - }; + }); }; configurationName = mkOption { @@ -357,6 +357,44 @@ in ''; }; + efiInstallAsRemovable = mkOption { + default = false; + example = true; + type = types.bool; + description = '' + Whether to invoke <literal>grub-install</literal> with + <literal>--removable</literal>.</para> + + <para>Unless you turn this on, GRUB will install itself somewhere in + <literal>boot.loader.efi.efiSysMountPoint</literal> (exactly where + depends on other config variables). If you've set + <literal>boot.loader.efi.canTouchEfiVariables</literal> *AND* you + are currently booted in UEFI mode, then GRUB will use + <literal>efibootmgr</literal> to modify the boot order in the + EFI variables of your firmware to include this location. If you are + *not* booted in UEFI mode at the time GRUB is being installed, the + NVRAM will not be modified, and your system will not find GRUB at + boot time. However, GRUB will still return success so you may miss + the warning that gets printed ("<literal>efibootmgr: EFI variables + are not supported on this system.</literal>").</para> + + <para>If you turn this feature on, GRUB will install itself in a + special location within <literal>efiSysMountPoint</literal> (namely + <literal>EFI/boot/boot$arch.efi</literal>) which the firmwares + are hardcoded to try first, regardless of NVRAM EFI variables.</para> + + <para>To summarize, turn this on if: + <itemizedlist> + <listitem><para>You are installing NixOS and want it to boot in UEFI mode, + but you are currently booted in legacy mode</para></listitem> + <listitem><para>You want to make a drive that will boot regardless of + the NVRAM state of the computer (like a USB "removable" drive)</para></listitem> + <listitem><para>You simply dislike the idea of depending on NVRAM + state to make your drive bootable</para></listitem> + </itemizedlist> + ''; + }; + enableCryptodisk = mkOption { default = false; type = types.bool; @@ -465,7 +503,7 @@ in + "'boot.loader.grub.mirroredBoots' to make the system bootable."; } { - assertion = all (c: c < 2) (mapAttrsToList (_: c: c) bootDeviceCounters); + assertion = cfg.efiSupport || all (c: c < 2) (mapAttrsToList (_: c: c) bootDeviceCounters); message = "You cannot have duplicated devices in mirroredBoots"; } { @@ -484,6 +522,14 @@ in assertion = !cfg.trustedBoot.enable || cfg.trustedBoot.systemHasTPM == "YES_TPM_is_activated"; message = "Trusted GRUB can break the system! Confirm that the system has an activated TPM by setting 'systemHasTPM'."; } + { + assertion = cfg.efiInstallAsRemovable -> cfg.efiSupport; + message = "If you wish to to use boot.loader.grub.efiInstallAsRemovable, then turn on boot.loader.grub.efiSupport"; + } + { + assertion = cfg.efiInstallAsRemovable -> !config.boot.loader.efi.canTouchEfiVariables; + message = "If you wish to to use boot.loader.grub.efiInstallAsRemovable, then turn off boot.loader.efi.canTouchEfiVariables"; + } ] ++ flip concatMap cfg.mirroredBoots (args: [ { assertion = args.devices != [ ]; diff --git a/nixos/modules/system/boot/loader/grub/install-grub.pl b/nixos/modules/system/boot/loader/grub/install-grub.pl index 06eece5025f8..b93395300b72 100644 --- a/nixos/modules/system/boot/loader/grub/install-grub.pl +++ b/nixos/modules/system/boot/loader/grub/install-grub.pl @@ -60,6 +60,7 @@ my $grubTargetEfi = get("grubTargetEfi"); my $bootPath = get("bootPath"); my $storePath = get("storePath"); my $canTouchEfiVariables = get("canTouchEfiVariables"); +my $efiInstallAsRemovable = get("efiInstallAsRemovable"); my $efiSysMountPoint = get("efiSysMountPoint"); my $gfxmodeEfi = get("gfxmodeEfi"); my $gfxmodeBios = get("gfxmodeBios"); @@ -544,13 +545,15 @@ if (($requireNewInstall != 0) && ($efiTarget eq "no" || $efiTarget eq "both")) { # install EFI GRUB if (($requireNewInstall != 0) && ($efiTarget eq "only" || $efiTarget eq "both")) { print STDERR "installing the GRUB $grubVersion EFI boot loader into $efiSysMountPoint...\n"; + my @command = ("$grubEfi/sbin/grub-install", "--recheck", "--target=$grubTargetEfi", "--boot-directory=$bootPath", "--efi-directory=$efiSysMountPoint"); if ($canTouchEfiVariables eq "true") { - system("$grubEfi/sbin/grub-install", "--recheck", "--target=$grubTargetEfi", "--boot-directory=$bootPath", "--efi-directory=$efiSysMountPoint", "--bootloader-id=$bootloaderId") == 0 - or die "$0: installation of GRUB EFI into $efiSysMountPoint failed\n"; + push @command, "--bootloader-id=$bootloaderId"; } else { - system("$grubEfi/sbin/grub-install", "--recheck", "--target=$grubTargetEfi", "--boot-directory=$bootPath", "--efi-directory=$efiSysMountPoint", "--no-nvram") == 0 - or die "$0: installation of GRUB EFI into $efiSysMountPoint failed\n"; + push @command, "--no-nvram"; + push @command, "--removable" if $efiInstallAsRemovable eq "true"; } + + (system @command) == 0 or die "$0: installation of GRUB EFI into $efiSysMountPoint failed\n"; } diff --git a/nixos/modules/system/boot/luksroot.nix b/nixos/modules/system/boot/luksroot.nix index f2755b49f88d..1f412fe2d8f2 100644 --- a/nixos/modules/system/boot/luksroot.nix +++ b/nixos/modules/system/boot/luksroot.nix @@ -236,165 +236,165 @@ in <filename>/dev/mapper/<replaceable>name</replaceable></filename>. ''; - type = types.loaOf types.optionSet; - - options = { name, ... }: { options = { - - name = mkOption { - visible = false; - default = name; - example = "luksroot"; - type = types.str; - description = "Name of the unencrypted device in <filename>/dev/mapper</filename>."; - }; - - device = mkOption { - example = "/dev/disk/by-uuid/430e9eff-d852-4f68-aa3b-2fa3599ebe08"; - type = types.str; - description = "Path of the underlying encrypted block device."; - }; - - header = mkOption { - default = null; - example = "/root/header.img"; - type = types.nullOr types.str; - description = '' - The name of the file or block device that - should be used as header for the encrypted device. - ''; - }; - - keyFile = mkOption { - default = null; - example = "/dev/sdb1"; - type = types.nullOr types.str; - description = '' - The name of the file (can be a raw device or a partition) that - should be used as the decryption key for the encrypted device. If - not specified, you will be prompted for a passphrase instead. - ''; - }; - - keyFileSize = mkOption { - default = null; - example = 4096; - type = types.nullOr types.int; - description = '' - The size of the key file. Use this if only the beginning of the - key file should be used as a key (often the case if a raw device - or partition is used as key file). If not specified, the whole - <literal>keyFile</literal> will be used decryption, instead of just - the first <literal>keyFileSize</literal> bytes. - ''; - }; - - # FIXME: get rid of this option. - preLVM = mkOption { - default = true; - type = types.bool; - description = "Whether the luksOpen will be attempted before LVM scan or after it."; - }; - - allowDiscards = mkOption { - default = false; - type = types.bool; - description = '' - Whether to allow TRIM requests to the underlying device. This option - has security implications; please read the LUKS documentation before - activating it. - ''; - }; - - yubikey = mkOption { - default = null; - type = types.nullOr types.optionSet; - description = '' - The options to use for this LUKS device in Yubikey-PBA. - If null (the default), Yubikey-PBA will be disabled for this device. - ''; + type = with types; loaOf (submodule ( + { name, ... }: { options = { + + name = mkOption { + visible = false; + default = name; + example = "luksroot"; + type = types.str; + description = "Name of the unencrypted device in <filename>/dev/mapper</filename>."; + }; - options = { - twoFactor = mkOption { - default = true; - type = types.bool; - description = "Whether to use a passphrase and a Yubikey (true), or only a Yubikey (false)."; - }; - - slot = mkOption { - default = 2; - type = types.int; - description = "Which slot on the Yubikey to challenge."; - }; - - saltLength = mkOption { - default = 16; - type = types.int; - description = "Length of the new salt in byte (64 is the effective maximum)."; - }; - - keyLength = mkOption { - default = 64; - type = types.int; - description = "Length of the LUKS slot key derived with PBKDF2 in byte."; - }; - - iterationStep = mkOption { - default = 0; - type = types.int; - description = "How much the iteration count for PBKDF2 is increased at each successful authentication."; - }; - - gracePeriod = mkOption { - default = 2; - type = types.int; - description = "Time in seconds to wait before attempting to find the Yubikey."; - }; - - ramfsMountPoint = mkOption { - default = "/crypt-ramfs"; - type = types.str; - description = "Path where the ramfs used to update the LUKS key will be mounted during early boot."; - }; - - /* TODO: Add to the documentation of the current module: - - Options related to the storing the salt. - */ - storage = { - device = mkOption { - default = "/dev/sda1"; - type = types.path; - description = '' - An unencrypted device that will temporarily be mounted in stage-1. - Must contain the current salt to create the challenge for this LUKS device. - ''; - }; + device = mkOption { + example = "/dev/disk/by-uuid/430e9eff-d852-4f68-aa3b-2fa3599ebe08"; + type = types.str; + description = "Path of the underlying encrypted block device."; + }; - fsType = mkOption { - default = "vfat"; - type = types.str; - description = "The filesystem of the unencrypted device."; - }; + header = mkOption { + default = null; + example = "/root/header.img"; + type = types.nullOr types.str; + description = '' + The name of the file or block device that + should be used as header for the encrypted device. + ''; + }; - mountPoint = mkOption { - default = "/crypt-storage"; - type = types.str; - description = "Path where the unencrypted device will be mounted during early boot."; - }; + keyFile = mkOption { + default = null; + example = "/dev/sdb1"; + type = types.nullOr types.str; + description = '' + The name of the file (can be a raw device or a partition) that + should be used as the decryption key for the encrypted device. If + not specified, you will be prompted for a passphrase instead. + ''; + }; + + keyFileSize = mkOption { + default = null; + example = 4096; + type = types.nullOr types.int; + description = '' + The size of the key file. Use this if only the beginning of the + key file should be used as a key (often the case if a raw device + or partition is used as key file). If not specified, the whole + <literal>keyFile</literal> will be used decryption, instead of just + the first <literal>keyFileSize</literal> bytes. + ''; + }; + + # FIXME: get rid of this option. + preLVM = mkOption { + default = true; + type = types.bool; + description = "Whether the luksOpen will be attempted before LVM scan or after it."; + }; + + allowDiscards = mkOption { + default = false; + type = types.bool; + description = '' + Whether to allow TRIM requests to the underlying device. This option + has security implications; please read the LUKS documentation before + activating it. + ''; + }; - path = mkOption { - default = "/crypt-storage/default"; - type = types.str; - description = '' - Absolute path of the salt on the unencrypted device with - that device's root directory as "/". - ''; + yubikey = mkOption { + default = null; + description = '' + The options to use for this LUKS device in Yubikey-PBA. + If null (the default), Yubikey-PBA will be disabled for this device. + ''; + + type = with types; nullOr (submodule { + options = { + twoFactor = mkOption { + default = true; + type = types.bool; + description = "Whether to use a passphrase and a Yubikey (true), or only a Yubikey (false)."; + }; + + slot = mkOption { + default = 2; + type = types.int; + description = "Which slot on the Yubikey to challenge."; + }; + + saltLength = mkOption { + default = 16; + type = types.int; + description = "Length of the new salt in byte (64 is the effective maximum)."; + }; + + keyLength = mkOption { + default = 64; + type = types.int; + description = "Length of the LUKS slot key derived with PBKDF2 in byte."; + }; + + iterationStep = mkOption { + default = 0; + type = types.int; + description = "How much the iteration count for PBKDF2 is increased at each successful authentication."; + }; + + gracePeriod = mkOption { + default = 2; + type = types.int; + description = "Time in seconds to wait before attempting to find the Yubikey."; + }; + + ramfsMountPoint = mkOption { + default = "/crypt-ramfs"; + type = types.str; + description = "Path where the ramfs used to update the LUKS key will be mounted during early boot."; + }; + + /* TODO: Add to the documentation of the current module: + + Options related to the storing the salt. + */ + storage = { + device = mkOption { + default = "/dev/sda1"; + type = types.path; + description = '' + An unencrypted device that will temporarily be mounted in stage-1. + Must contain the current salt to create the challenge for this LUKS device. + ''; + }; + + fsType = mkOption { + default = "vfat"; + type = types.str; + description = "The filesystem of the unencrypted device."; + }; + + mountPoint = mkOption { + default = "/crypt-storage"; + type = types.str; + description = "Path where the unencrypted device will be mounted during early boot."; + }; + + path = mkOption { + default = "/crypt-storage/default"; + type = types.str; + description = '' + Absolute path of the salt on the unencrypted device with + that device's root directory as "/". + ''; + }; + }; }; - }; + }); }; - }; - }; }; + }; })); }; boot.initrd.luks.yubikeySupport = mkOption { diff --git a/nixos/modules/system/boot/networkd.nix b/nixos/modules/system/boot/networkd.nix index d125be7c3d07..dbb9bced94cf 100644 --- a/nixos/modules/system/boot/networkd.nix +++ b/nixos/modules/system/boot/networkd.nix @@ -471,8 +471,7 @@ let addresses = mkOption { default = [ ]; - type = types.listOf types.optionSet; - options = [ addressOptions ]; + type = with types; listOf (submodule [ addressOptions ]); description = '' A list of address sections to be added to the unit. See <citerefentry><refentrytitle>systemd.network</refentrytitle> @@ -482,8 +481,7 @@ let routes = mkOption { default = [ ]; - type = types.listOf types.optionSet; - options = [ routeOptions ]; + type = with types; listOf (submodule [ routeOptions ]); description = '' A list of route sections to be added to the unit. See <citerefentry><refentrytitle>systemd.network</refentrytitle> @@ -624,35 +622,32 @@ in systemd.network.links = mkOption { default = {}; - type = types.attrsOf types.optionSet; - options = [ linkOptions ]; + type = with types; attrsOf (submodule [ linkOptions ]); description = "Definition of systemd network links."; }; systemd.network.netdevs = mkOption { default = {}; - type = types.attrsOf types.optionSet; - options = [ netdevOptions ]; + type = with types; attrsOf (submodule [ netdevOptions ]); description = "Definition of systemd network devices."; }; systemd.network.networks = mkOption { default = {}; - type = types.attrsOf types.optionSet; - options = [ networkOptions networkConfig ]; + type = with types; attrsOf (submodule [ networkOptions networkConfig ]); description = "Definition of systemd networks."; }; systemd.network.units = mkOption { description = "Definition of networkd units."; default = {}; - type = types.attrsOf types.optionSet; - options = { name, config, ... }: + type = with types; attrsOf (submodule ( + { name, config, ... }: { options = concreteUnitOptions; config = { unit = mkDefault (makeUnit name config); }; - }; + })); }; }; diff --git a/nixos/modules/system/boot/stage-1.nix b/nixos/modules/system/boot/stage-1.nix index 513c121347b1..8d02cd81e0e1 100644 --- a/nixos/modules/system/boot/stage-1.nix +++ b/nixos/modules/system/boot/stage-1.nix @@ -134,10 +134,9 @@ let ''; # */ - udevRules = pkgs.stdenv.mkDerivation { - name = "udev-rules"; - allowedReferences = [ extraUtils ]; - buildCommand = '' + udevRules = pkgs.runCommand "udev-rules" + { allowedReferences = [ extraUtils ]; } + '' mkdir -p $out echo 'ENV{LD_LIBRARY_PATH}="${extraUtils}/lib"' > $out/00-env.rules @@ -176,7 +175,6 @@ let substituteInPlace $out/60-persistent-storage.rules \ --replace ID_CDROM_MEDIA_TRACK_COUNT_DATA ID_CDROM_MEDIA ''; # */ - }; # The init script of boot stage 1 (loading kernel modules for @@ -198,9 +196,10 @@ let preLVMCommands preDeviceCommands postDeviceCommands postMountCommands preFailCommands kernelModules; resumeDevices = map (sd: if sd ? device then sd.device else "/dev/disk/by-label/${sd.label}") - (filter (sd: (sd ? label || hasPrefix "/dev/" sd.device) && !sd.randomEncryption - # Don't include zram devices - && !(hasPrefix "/dev/zram" sd.device)) config.swapDevices); + (filter (sd: hasPrefix "/dev/" sd.device && !sd.randomEncryption + # Don't include zram devices + && !(hasPrefix "/dev/zram" sd.device) + ) config.swapDevices); fsInfo = let f = fs: [ fs.mountPoint (if fs.device != null then fs.device else "/dev/disk/by-label/${fs.label}") fs.fsType (builtins.concatStringsSep "," fs.options) ]; @@ -229,16 +228,12 @@ let { object = pkgs.writeText "mdadm.conf" config.boot.initrd.mdadmConf; symlink = "/etc/mdadm.conf"; } - { object = pkgs.stdenv.mkDerivation { - name = "initrd-kmod-blacklist-ubuntu"; - builder = pkgs.writeText "builder.sh" '' - source $stdenv/setup + { object = pkgs.runCommand "initrd-kmod-blacklist-ubuntu" + { src = "${pkgs.kmod-blacklist-ubuntu}/modprobe.conf"; } + '' target=$out - ${pkgs.perl}/bin/perl -0pe 's/## file: iwlwifi.conf(.+?)##/##/s;' $src > $out ''; - src = "${pkgs.kmod-blacklist-ubuntu}/modprobe.conf"; - }; symlink = "/etc/modprobe.d/ubuntu.conf"; } { object = pkgs.kmod-debian-aliases; diff --git a/nixos/modules/system/boot/stage-2-init.sh b/nixos/modules/system/boot/stage-2-init.sh index ae88222f2780..f827e530f877 100644 --- a/nixos/modules/system/boot/stage-2-init.sh +++ b/nixos/modules/system/boot/stage-2-init.sh @@ -111,16 +111,6 @@ rm -f /etc/{group,passwd,shadow}.lock rm -rf /nix/var/nix/gcroots/tmp /nix/var/nix/temproots -# Create a ramfs on /run/keys to hold secrets that shouldn't be -# written to disk (generally used for NixOps, harmless elsewhere). -if ! mountpoint -q /run/keys; then - rm -rf /run/keys - mkdir /run/keys - mount -t ramfs ramfs /run/keys - chown 0:96 /run/keys - chmod 0750 /run/keys -fi - mkdir -m 0755 -p /run/lock diff --git a/nixos/modules/system/boot/systemd.nix b/nixos/modules/system/boot/systemd.nix index 397e9a4987b7..4a59d6474808 100644 --- a/nixos/modules/system/boot/systemd.nix +++ b/nixos/modules/system/boot/systemd.nix @@ -389,13 +389,13 @@ in systemd.units = mkOption { description = "Definition of systemd units."; default = {}; - type = types.attrsOf types.optionSet; - options = { name, config, ... }: + type = with types; attrsOf (submodule ( + { name, config, ... }: { options = concreteUnitOptions; config = { unit = mkDefault (makeUnit name config); }; - }; + })); }; systemd.packages = mkOption { @@ -406,43 +406,37 @@ in systemd.targets = mkOption { default = {}; - type = types.attrsOf types.optionSet; - options = [ targetOptions unitConfig ]; + type = with types; attrsOf (submodule [ { options = targetOptions; } unitConfig] ); description = "Definition of systemd target units."; }; systemd.services = mkOption { default = {}; - type = types.attrsOf types.optionSet; - options = [ serviceOptions unitConfig serviceConfig ]; + type = with types; attrsOf (submodule [ { options = serviceOptions; } unitConfig serviceConfig ]); description = "Definition of systemd service units."; }; systemd.sockets = mkOption { default = {}; - type = types.attrsOf types.optionSet; - options = [ socketOptions unitConfig ]; + type = with types; attrsOf (submodule [ { options = socketOptions; } unitConfig ]); description = "Definition of systemd socket units."; }; systemd.timers = mkOption { default = {}; - type = types.attrsOf types.optionSet; - options = [ timerOptions unitConfig ]; + type = with types; attrsOf (submodule [ { options = timerOptions; } unitConfig ]); description = "Definition of systemd timer units."; }; systemd.paths = mkOption { default = {}; - type = types.attrsOf types.optionSet; - options = [ pathOptions unitConfig ]; + type = with types; attrsOf (submodule [ { options = pathOptions; } unitConfig ]); description = "Definition of systemd path units."; }; systemd.mounts = mkOption { default = []; - type = types.listOf types.optionSet; - options = [ mountOptions unitConfig mountConfig ]; + type = with types; listOf (submodule [ { options = mountOptions; } unitConfig mountConfig ]); description = '' Definition of systemd mount units. This is a list instead of an attrSet, because systemd mandates the names to be derived from @@ -452,8 +446,7 @@ in systemd.automounts = mkOption { default = []; - type = types.listOf types.optionSet; - options = [ automountOptions unitConfig automountConfig ]; + type = with types; listOf (submodule [ { options = automountOptions; } unitConfig automountConfig ]); description = '' Definition of systemd automount units. This is a list instead of an attrSet, because systemd mandates the names to be derived from @@ -571,6 +564,16 @@ in ''; }; + systemd.user.extraConfig = mkOption { + default = ""; + type = types.lines; + example = "DefaultCPUAccounting=yes"; + description = '' + Extra config options for systemd user instances. See man systemd-user.conf for + available options. + ''; + }; + systemd.tmpfiles.rules = mkOption { type = types.listOf types.str; default = []; @@ -590,33 +593,30 @@ in systemd.user.units = mkOption { description = "Definition of systemd per-user units."; default = {}; - type = types.attrsOf types.optionSet; - options = { name, config, ... }: + type = with types; attrsOf (submodule ( + { name, config, ... }: { options = concreteUnitOptions; config = { unit = mkDefault (makeUnit name config); }; - }; + })); }; systemd.user.services = mkOption { default = {}; - type = types.attrsOf types.optionSet; - options = [ serviceOptions unitConfig serviceConfig ]; + type = with types; attrsOf (submodule [ { options = serviceOptions; } unitConfig serviceConfig ] ); description = "Definition of systemd per-user service units."; }; systemd.user.timers = mkOption { default = {}; - type = types.attrsOf types.optionSet; - options = [ timerOptions unitConfig ]; + type = with types; attrsOf (submodule [ { options = timerOptions; } unitConfig ] ); description = "Definition of systemd per-user timer units."; }; systemd.user.sockets = mkOption { default = {}; - type = types.attrsOf types.optionSet; - options = [ socketOptions unitConfig ]; + type = with types; attrsOf (submodule [ { options = socketOptions; } unitConfig ] ); description = "Definition of systemd per-user socket units."; }; @@ -665,6 +665,11 @@ in ${config.systemd.extraConfig} ''; + "systemd/user.conf".text = '' + [Manager] + ${config.systemd.user.extraConfig} + ''; + "systemd/journald.conf".text = '' [Journal] RateLimitInterval=${config.services.journald.rateLimitInterval} @@ -793,6 +798,8 @@ in systemd.services.systemd-user-sessions.restartIfChanged = false; # Restart kills all active sessions. systemd.services.systemd-logind.restartTriggers = [ config.environment.etc."systemd/logind.conf".source ]; systemd.services.systemd-logind.stopIfChanged = false; + systemd.services.systemd-journald.restartTriggers = [ config.environment.etc."systemd/journald.conf".source ]; + systemd.services.systemd-journald.stopIfChanged = false; systemd.targets.local-fs.unitConfig.X-StopOnReconfiguration = true; systemd.targets.remote-fs.unitConfig.X-StopOnReconfiguration = true; systemd.services.systemd-binfmt.wants = [ "proc-sys-fs-binfmt_misc.automount" ]; diff --git a/nixos/modules/system/etc/etc.nix b/nixos/modules/system/etc/etc.nix index 163f4f4106e8..dac36229408f 100644 --- a/nixos/modules/system/etc/etc.nix +++ b/nixos/modules/system/etc/etc.nix @@ -33,7 +33,6 @@ in options = { environment.etc = mkOption { - type = types.loaOf types.optionSet; default = {}; example = literalExample '' { example-configuration-file = @@ -47,7 +46,8 @@ in Set of files that have to be linked in <filename>/etc</filename>. ''; - options = singleton ({ name, config, ... }: + type = with types; loaOf (submodule ( + { name, config, ... }: { options = { enable = mkOption { @@ -117,7 +117,7 @@ in in mkDefault (pkgs.writeText name' config.text)); }; - }); + })); }; diff --git a/nixos/modules/tasks/filesystems.nix b/nixos/modules/tasks/filesystems.nix index 3c822c8716d0..49ba66ad50af 100644 --- a/nixos/modules/tasks/filesystems.nix +++ b/nixos/modules/tasks/filesystems.nix @@ -18,7 +18,7 @@ let prioOption = prio: optionalString (prio != null) " pri=${toString prio}"; - specialFSTypes = [ "proc" "sysfs" "tmpfs" "devtmpfs" "devpts" ]; + specialFSTypes = [ "proc" "sysfs" "tmpfs" "ramfs" "devtmpfs" "devpts" ]; coreFileSystemOpts = { name, config, ... }: { @@ -258,7 +258,7 @@ in let mountPoint' = "${escapeSystemdPath fs.mountPoint}.mount"; device' = escapeSystemdPath fs.device; - device'' = "${device}.device"; + device'' = "${device'}.device"; in nameValuePair "mkfs-${device'}" { description = "Initialisation of Filesystem ${fs.device}"; wantedBy = [ mountPoint' ]; @@ -290,6 +290,9 @@ in "/dev" = { fsType = "devtmpfs"; options = [ "nosuid" "strictatime" "mode=755" "size=${config.boot.devSize}" ]; }; "/dev/shm" = { fsType = "tmpfs"; options = [ "nosuid" "nodev" "strictatime" "mode=1777" "size=${config.boot.devShmSize}" ]; }; "/dev/pts" = { fsType = "devpts"; options = [ "nosuid" "noexec" "mode=620" "gid=${toString config.ids.gids.tty}" ]; }; + + # To hold secrets that shouldn't be written to disk (generally used for NixOps, harmless elsewhere) + "/run/keys" = { fsType = "ramfs"; options = [ "nosuid" "nodev" "mode=750" "gid=${toString config.ids.gids.keys}" ]; }; } // optionalAttrs (!config.boot.isContainer) { # systemd-nspawn populates /sys by itself, and remounting it causes all # kinds of weird issues (most noticeably, waiting for host disk device diff --git a/nixos/modules/tasks/network-interfaces.nix b/nixos/modules/tasks/network-interfaces.nix index 144ad10138d6..cac7e6b02eba 100644 --- a/nixos/modules/tasks/network-interfaces.nix +++ b/nixos/modules/tasks/network-interfaces.nix @@ -97,21 +97,22 @@ let addrOpts = v: assert v == 4 || v == 6; - { - address = mkOption { - type = types.str; - description = '' - IPv${toString v} address of the interface. Leave empty to configure the - interface using DHCP. - ''; - }; + { options = { + address = mkOption { + type = types.str; + description = '' + IPv${toString v} address of the interface. Leave empty to configure the + interface using DHCP. + ''; + }; - prefixLength = mkOption { - type = types.addCheck types.int (n: n >= 0 && n <= (if v == 4 then 32 else 128)); - description = '' - Subnet mask of the interface, specified as the number of - bits in the prefix (<literal>${if v == 4 then "24" else "64"}</literal>). - ''; + prefixLength = mkOption { + type = types.addCheck types.int (n: n >= 0 && n <= (if v == 4 then 32 else 128)); + description = '' + Subnet mask of the interface, specified as the number of + bits in the prefix (<literal>${if v == 4 then "24" else "64"}</literal>). + ''; + }; }; }; @@ -141,8 +142,7 @@ let { address = "10.0.0.1"; prefixLength = 16; } { address = "192.168.1.1"; prefixLength = 24; } ]; - type = types.listOf types.optionSet; - options = addrOpts 4; + type = with types; listOf (submodule (addrOpts 4)); description = '' List of IPv4 addresses that will be statically assigned to the interface. ''; @@ -154,8 +154,7 @@ let { address = "fdfd:b3f0:482::1"; prefixLength = 48; } { address = "2001:1470:fffd:2098::e006"; prefixLength = 64; } ]; - type = types.listOf types.optionSet; - options = addrOpts 6; + type = with types; listOf (submodule (addrOpts 6)); description = '' List of IPv6 addresses that will be statically assigned to the interface. ''; @@ -391,7 +390,7 @@ in }; networking.localCommands = mkOption { - type = types.str; + type = types.lines; default = ""; example = "text=anything; echo You can put $text here."; description = '' @@ -415,8 +414,7 @@ in <option>networking.useDHCP</option> is true, then every interface not listed here will be configured using DHCP. ''; - type = types.loaOf types.optionSet; - options = [ interfaceOpts ]; + type = with types; loaOf (submodule interfaceOpts); }; networking.vswitches = mkOption { @@ -434,53 +432,55 @@ in interface. ''; - type = types.attrsOf types.optionSet; + type = with types; attrsOf (submodule { - options = { + options = { - interfaces = mkOption { - example = [ "eth0" "eth1" ]; - type = types.listOf types.str; - description = - "The physical network interfaces connected by the vSwitch."; - }; + interfaces = mkOption { + example = [ "eth0" "eth1" ]; + type = types.listOf types.str; + description = + "The physical network interfaces connected by the vSwitch."; + }; - controllers = mkOption { - type = types.listOf types.str; - default = []; - example = [ "ptcp:6653:[::1]" ]; - description = '' - Specify the controller targets. For the allowed options see <literal>man 8 ovs-vsctl</literal>. - ''; - }; + controllers = mkOption { + type = types.listOf types.str; + default = []; + example = [ "ptcp:6653:[::1]" ]; + description = '' + Specify the controller targets. For the allowed options see <literal>man 8 ovs-vsctl</literal>. + ''; + }; - openFlowRules = mkOption { - type = types.lines; - default = ""; - example = '' - actions=normal - ''; - description = '' - OpenFlow rules to insert into the Open vSwitch. All <literal>openFlowRules</literal> are - loaded with <literal>ovs-ofctl</literal> within one atomic operation. - ''; - }; + openFlowRules = mkOption { + type = types.lines; + default = ""; + example = '' + actions=normal + ''; + description = '' + OpenFlow rules to insert into the Open vSwitch. All <literal>openFlowRules</literal> are + loaded with <literal>ovs-ofctl</literal> within one atomic operation. + ''; + }; + + extraOvsctlCmds = mkOption { + type = types.lines; + default = ""; + example = '' + set-fail-mode <switch_name> secure + set Bridge <switch_name> stp_enable=true + ''; + description = '' + Commands to manipulate the Open vSwitch database. Every line executed with <literal>ovs-vsctl</literal>. + All commands are bundled together with the operations for adding the interfaces + into one atomic operation. + ''; + }; - extraOvsctlCmds = mkOption { - type = types.lines; - default = ""; - example = '' - set-fail-mode <switch_name> secure - set Bridge <switch_name> stp_enable=true - ''; - description = '' - Commands to manipulate the Open vSwitch database. Every line executed with <literal>ovs-vsctl</literal>. - All commands are bundled together with the operations for adding the interfaces - into one atomic operation. - ''; }; - }; + }); }; @@ -499,25 +499,27 @@ in bridge's network interface. ''; - type = types.attrsOf types.optionSet; + type = with types; attrsOf (submodule { - options = { + options = { - interfaces = mkOption { - example = [ "eth0" "eth1" ]; - type = types.listOf types.str; - description = - "The physical network interfaces connected by the bridge."; - }; + interfaces = mkOption { + example = [ "eth0" "eth1" ]; + type = types.listOf types.str; + description = + "The physical network interfaces connected by the bridge."; + }; + + rstp = mkOption { + example = true; + default = false; + type = types.bool; + description = "Whether the bridge interface should enable rstp."; + }; - rstp = mkOption { - example = true; - default = false; - type = types.bool; - description = "Whether the bridge interface should enable rstp."; }; - }; + }); }; @@ -538,65 +540,66 @@ in name specifying the name of the bond's network interface ''; - type = types.attrsOf types.optionSet; + type = with types; attrsOf (submodule { - options = { + options = { - interfaces = mkOption { - example = [ "enp4s0f0" "enp4s0f1" "wlan0" ]; - type = types.listOf types.str; - description = "The interfaces to bond together"; - }; + interfaces = mkOption { + example = [ "enp4s0f0" "enp4s0f1" "wlan0" ]; + type = types.listOf types.str; + description = "The interfaces to bond together"; + }; - lacp_rate = mkOption { - default = null; - example = "fast"; - type = types.nullOr types.str; - description = '' - Option specifying the rate in which we'll ask our link partner - to transmit LACPDU packets in 802.3ad mode. - ''; - }; - - miimon = mkOption { - default = null; - example = 100; - type = types.nullOr types.int; - description = '' - Miimon is the number of millisecond in between each round of polling - by the device driver for failed links. By default polling is not - enabled and the driver is trusted to properly detect and handle - failure scenarios. - ''; - }; - - mode = mkOption { - default = null; - example = "active-backup"; - type = types.nullOr types.str; - description = '' - The mode which the bond will be running. The default mode for - the bonding driver is balance-rr, optimizing for throughput. - More information about valid modes can be found at - https://www.kernel.org/doc/Documentation/networking/bonding.txt - ''; - }; + lacp_rate = mkOption { + default = null; + example = "fast"; + type = types.nullOr types.str; + description = '' + Option specifying the rate in which we'll ask our link partner + to transmit LACPDU packets in 802.3ad mode. + ''; + }; + + miimon = mkOption { + default = null; + example = 100; + type = types.nullOr types.int; + description = '' + Miimon is the number of millisecond in between each round of polling + by the device driver for failed links. By default polling is not + enabled and the driver is trusted to properly detect and handle + failure scenarios. + ''; + }; + + mode = mkOption { + default = null; + example = "active-backup"; + type = types.nullOr types.str; + description = '' + The mode which the bond will be running. The default mode for + the bonding driver is balance-rr, optimizing for throughput. + More information about valid modes can be found at + https://www.kernel.org/doc/Documentation/networking/bonding.txt + ''; + }; + + xmit_hash_policy = mkOption { + default = null; + example = "layer2+3"; + type = types.nullOr types.str; + description = '' + Selects the transmit hash policy to use for slave selection in + balance-xor, 802.3ad, and tlb modes. + ''; + }; - xmit_hash_policy = mkOption { - default = null; - example = "layer2+3"; - type = types.nullOr types.str; - description = '' - Selects the transmit hash policy to use for slave selection in - balance-xor, 802.3ad, and tlb modes. - ''; }; - }; + }); }; networking.macvlans = mkOption { - type = types.attrsOf types.optionSet; default = { }; example = literalExample { wan = { @@ -608,26 +611,28 @@ in This option allows you to define macvlan interfaces which should be automatically created. ''; - options = { + type = with types; attrsOf (submodule { + options = { + + interface = mkOption { + example = "enp4s0"; + type = types.str; + description = "The interface the macvlan will transmit packets through."; + }; + + mode = mkOption { + default = null; + type = types.nullOr types.str; + example = "vepa"; + description = "The mode of the macvlan device."; + }; - interface = mkOption { - example = "enp4s0"; - type = types.str; - description = "The interface the macvlan will transmit packets through."; }; - mode = mkOption { - default = null; - type = types.nullOr types.str; - example = "vepa"; - description = "The mode of the macvlan device."; - }; - - }; + }); }; networking.sits = mkOption { - type = types.attrsOf types.optionSet; default = { }; example = literalExample { hurricane = { @@ -644,46 +649,49 @@ in description = '' This option allows you to define 6-to-4 interfaces which should be automatically created. ''; - options = { - - remote = mkOption { - type = types.nullOr types.str; - default = null; - example = "10.0.0.1"; - description = '' - The address of the remote endpoint to forward traffic over. - ''; - }; - - local = mkOption { - type = types.nullOr types.str; - default = null; - example = "10.0.0.22"; - description = '' - The address of the local endpoint which the remote - side should send packets to. - ''; - }; - - ttl = mkOption { - type = types.nullOr types.int; - default = null; - example = 255; - description = '' - The time-to-live of the connection to the remote tunnel endpoint. - ''; - }; + type = with types; attrsOf (submodule { + options = { + + remote = mkOption { + type = types.nullOr types.str; + default = null; + example = "10.0.0.1"; + description = '' + The address of the remote endpoint to forward traffic over. + ''; + }; + + local = mkOption { + type = types.nullOr types.str; + default = null; + example = "10.0.0.22"; + description = '' + The address of the local endpoint which the remote + side should send packets to. + ''; + }; + + ttl = mkOption { + type = types.nullOr types.int; + default = null; + example = 255; + description = '' + The time-to-live of the connection to the remote tunnel endpoint. + ''; + }; + + dev = mkOption { + type = types.nullOr types.str; + default = null; + example = "enp4s0f0"; + description = '' + The underlying network device on which the tunnel resides. + ''; + }; - dev = mkOption { - type = types.nullOr types.str; - default = null; - example = "enp4s0f0"; - description = '' - The underlying network device on which the tunnel resides. - ''; }; - }; + }); }; networking.vlans = mkOption { @@ -706,23 +714,26 @@ in specifying the name of the vlan interface. ''; - type = types.attrsOf types.optionSet; + type = with types; attrsOf (submodule { - options = { + options = { - id = mkOption { - example = 1; - type = types.int; - description = "The vlan identifier"; - }; + id = mkOption { + example = 1; + type = types.int; + description = "The vlan identifier"; + }; + + interface = mkOption { + example = "enp4s0"; + type = types.str; + description = "The interface the vlan will transmit packets through."; + }; - interface = mkOption { - example = "enp4s0"; - type = types.str; - description = "The interface the vlan will transmit packets through."; }; - }; + }); + }; networking.wlanInterfaces = mkOption { @@ -760,73 +771,76 @@ in would have to be created explicitly. ''; - type = types.attrsOf types.optionSet; - - options = { + type = with types; attrsOf (submodule { - device = mkOption { - type = types.string; - example = "wlp6s0"; - description = "The name of the underlying hardware WLAN device as assigned by <literal>udev</literal>."; - }; + options = { - type = mkOption { - type = types.string; - default = "managed"; - example = "ibss"; - description = '' - The type of the WLAN interface. The type has to be either <literal>managed</literal>, - <literal>ibss</literal>, <literal>monitor</literal>, <literal>mesh</literal> or <literal>wds</literal>. - Also, the type has to be supported by the underlying hardware of the device. - ''; - }; + device = mkOption { + type = types.string; + example = "wlp6s0"; + description = "The name of the underlying hardware WLAN device as assigned by <literal>udev</literal>."; + }; - meshID = mkOption { - type = types.nullOr types.string; - default = null; - description = "MeshID of interface with type <literal>mesh</literal>."; - }; - - flags = mkOption { - type = types.nullOr types.string; - default = null; - example = "control"; - description = '' - Flags for interface of type <literal>monitor</literal>. The valid flags are: - none: no special flags - fcsfail: show frames with FCS errors - control: show control frames - otherbss: show frames from other BSSes - cook: use cooked mode - active: use active mode (ACK incoming unicast packets) - ''; - }; + type = mkOption { + type = types.string; + default = "managed"; + example = "ibss"; + description = '' + The type of the WLAN interface. The type has to be either <literal>managed</literal>, + <literal>ibss</literal>, <literal>monitor</literal>, <literal>mesh</literal> or <literal>wds</literal>. + Also, the type has to be supported by the underlying hardware of the device. + ''; + }; + + meshID = mkOption { + type = types.nullOr types.string; + default = null; + description = "MeshID of interface with type <literal>mesh</literal>."; + }; + + flags = mkOption { + type = types.nullOr types.string; + default = null; + example = "control"; + description = '' + Flags for interface of type <literal>monitor</literal>. The valid flags are: + none: no special flags + fcsfail: show frames with FCS errors + control: show control frames + otherbss: show frames from other BSSes + cook: use cooked mode + active: use active mode (ACK incoming unicast packets) + ''; + }; + + fourAddr = mkOption { + type = types.nullOr types.bool; + default = null; + description = "Whether to enable <literal>4-address mode</literal> with type <literal>managed</literal>."; + }; + + mac = mkOption { + type = types.nullOr types.str; + default = null; + example = "02:00:00:00:00:01"; + description = '' + MAC address to use for the device. If <literal>null</literal>, then the MAC of the + underlying hardware WLAN device is used. + + INFO: Locally administered MAC addresses are of the form: + <itemizedlist> + <listitem><para>x2:xx:xx:xx:xx:xx</para></listitem> + <listitem><para>x6:xx:xx:xx:xx:xx</para></listitem> + <listitem><para>xA:xx:xx:xx:xx:xx</para></listitem> + <listitem><para>xE:xx:xx:xx:xx:xx</para></listitem> + </itemizedlist> + ''; + }; - fourAddr = mkOption { - type = types.nullOr types.bool; - default = null; - description = "Whether to enable <literal>4-address mode</literal> with type <literal>managed</literal>."; }; - mac = mkOption { - type = types.nullOr types.str; - default = null; - example = "02:00:00:00:00:01"; - description = '' - MAC address to use for the device. If <literal>null</literal>, then the MAC of the - underlying hardware WLAN device is used. - - INFO: Locally administered MAC addresses are of the form: - <itemizedlist> - <listitem><para>x2:xx:xx:xx:xx:xx</para></listitem> - <listitem><para>x6:xx:xx:xx:xx:xx</para></listitem> - <listitem><para>xA:xx:xx:xx:xx:xx</para></listitem> - <listitem><para>xE:xx:xx:xx:xx:xx</para></listitem> - </itemizedlist> - ''; - }; + }); - }; }; networking.useDHCP = mkOption { diff --git a/nixos/modules/virtualisation/amazon-image.nix b/nixos/modules/virtualisation/amazon-image.nix index f9c3f2e53adc..17e69b311b48 100644 --- a/nixos/modules/virtualisation/amazon-image.nix +++ b/nixos/modules/virtualisation/amazon-image.nix @@ -138,7 +138,7 @@ let cfg = config.ec2; in # Allow root logins only using the SSH key that the user specified # at instance creation time. services.openssh.enable = true; - services.openssh.permitRootLogin = "without-password"; + services.openssh.permitRootLogin = "prohibit-password"; # Force getting the hostname from EC2. networking.hostName = mkDefault ""; diff --git a/nixos/modules/virtualisation/azure-bootstrap-blobs.nix b/nixos/modules/virtualisation/azure-bootstrap-blobs.nix new file mode 100644 index 000000000000..281be9a12318 --- /dev/null +++ b/nixos/modules/virtualisation/azure-bootstrap-blobs.nix @@ -0,0 +1,3 @@ +{ + "16.03" = "https://nixos.blob.core.windows.net/images/nixos-image-16.03.847.8688c17-x86_64-linux.vhd"; +} diff --git a/nixos/modules/virtualisation/azure-common.nix b/nixos/modules/virtualisation/azure-common.nix index 70a3d752f6d1..5cd2304a2953 100644 --- a/nixos/modules/virtualisation/azure-common.nix +++ b/nixos/modules/virtualisation/azure-common.nix @@ -24,7 +24,7 @@ with lib; # Allow root logins only using the SSH key that the user specified # at instance creation time, ping client connections to avoid timeouts services.openssh.enable = true; - services.openssh.permitRootLogin = "without-password"; + services.openssh.permitRootLogin = "prohibit-password"; services.openssh.extraConfig = '' ClientAliveInterval 180 ''; diff --git a/nixos/modules/virtualisation/brightbox-image.nix b/nixos/modules/virtualisation/brightbox-image.nix index e2905913b6c5..7f45f0f34f71 100644 --- a/nixos/modules/virtualisation/brightbox-image.nix +++ b/nixos/modules/virtualisation/brightbox-image.nix @@ -103,7 +103,7 @@ in # Allow root logins only using the SSH key that the user specified # at instance creation time. services.openssh.enable = true; - services.openssh.permitRootLogin = "without-password"; + services.openssh.permitRootLogin = "prohibit-password"; # Force getting the hostname from Google Compute. networking.hostName = mkDefault ""; diff --git a/nixos/modules/virtualisation/containers.nix b/nixos/modules/virtualisation/containers.nix index 413aa94339f1..5e1cfcdfc6fb 100644 --- a/nixos/modules/virtualisation/containers.nix +++ b/nixos/modules/virtualisation/containers.nix @@ -12,21 +12,21 @@ let '' echo "Bringing ${name} up" ip link set dev ${name} up - ${optionalString (cfg . "localAddress" or null != null) '' + ${optionalString (cfg.localAddress != null) '' echo "Setting ip for ${name}" - ip addr add ${cfg . "localAddress"} dev ${name} + ip addr add ${cfg.localAddress} dev ${name} ''} - ${optionalString (cfg . "localAddress6" or null != null) '' + ${optionalString (cfg.localAddress6 != null) '' echo "Setting ip6 for ${name}" - ip -6 addr add ${cfg . "localAddress6"} dev ${name} + ip -6 addr add ${cfg.localAddress6} dev ${name} ''} - ${optionalString (cfg . "hostAddress" or null != null) '' + ${optionalString (cfg.hostAddress != null) '' echo "Setting route to host for ${name}" - ip route add ${cfg . "hostAddress"} dev ${name} + ip route add ${cfg.hostAddress} dev ${name} ''} - ${optionalString (cfg . "hostAddress6" or null != null) '' + ${optionalString (cfg.hostAddress6 != null) '' echo "Setting route6 to host for ${name}" - ip -6 route add ${cfg . "hostAddress6"} dev ${name} + ip -6 route add ${cfg.hostAddress6} dev ${name} ''} '' ); @@ -56,9 +56,7 @@ let ip -6 route add default via $HOST_ADDRESS6 fi - ${concatStringsSep "\n" (mapAttrsToList renderExtraVeth cfg . "extraVeths" or {})} - ip a - ip r + ${concatStringsSep "\n" (mapAttrsToList renderExtraVeth cfg.extraVeths)} fi # Start the regular stage 1 script. @@ -67,7 +65,8 @@ let ); nspawnExtraVethArgs = (name: cfg: "--network-veth-extra=${name}"); - startScript = (cfg: + + startScript = cfg: '' mkdir -p -m 0755 "$root/etc" "$root/var/lib" mkdir -p -m 0700 "$root/var/lib/private" "$root/root" /run/containers @@ -92,11 +91,7 @@ let fi fi - ${if cfg . "extraVeths" or null != null then - ''extraFlags+=" ${concatStringsSep " " (mapAttrsToList nspawnExtraVethArgs cfg . "extraVeths" or {})}"'' - else - ''# No extra veth pairs to create'' - } + extraFlags+=" ${concatStringsSep " " (mapAttrsToList nspawnExtraVethArgs cfg.extraVeths)}" for iface in $INTERFACES; do extraFlags+=" --network-interface=$iface" @@ -134,11 +129,13 @@ let --setenv HOST_ADDRESS6="$HOST_ADDRESS6" \ --setenv LOCAL_ADDRESS6="$LOCAL_ADDRESS6" \ --setenv PATH="$PATH" \ + ${if cfg.additionalCapabilities != null then + ''--capability="${concatStringsSep " " cfg.additionalCapabilities}"'' else "" + } \ ${containerInit cfg} "''${SYSTEM_PATH:-/nix/var/nix/profiles/system}/init" - '' - ); + ''; - preStartScript = (cfg: + preStartScript = cfg: '' # Clean up existing machined registration and interfaces. machinectl terminate "$INSTANCE" 2> /dev/null || true @@ -151,45 +148,43 @@ let ${concatStringsSep "\n" ( mapAttrsToList (name: cfg: ''ip link del dev ${name} 2> /dev/null || true '' - ) cfg . "extraVeths" or {} + ) cfg.extraVeths )} - '' - ); + ''; + postStartScript = (cfg: let - ipcall = (cfg: ipcmd: variable: attribute: - if cfg . attribute or null == null then + ipcall = cfg: ipcmd: variable: attribute: + if cfg.${attribute} == null then '' if [ -n "${variable}" ]; then ${ipcmd} add ${variable} dev $ifaceHost fi '' else - ''${ipcmd} add ${cfg . attribute} dev $ifaceHost'' - ); - renderExtraVeth = (name: cfg: - if cfg . "hostBridge" or null != null then + ''${ipcmd} add ${cfg.${attribute}} dev $ifaceHost''; + renderExtraVeth = name: cfg: + if cfg.hostBridge != null then '' # Add ${name} to bridge ${cfg.hostBridge} ip link set dev ${name} master ${cfg.hostBridge} up '' else '' - # Set IPs and routes for ${name} - ${optionalString (cfg . "hostAddress" or null != null) '' - ip addr add ${cfg . "hostAddress"} dev ${name} - ''} - ${optionalString (cfg . "hostAddress6" or null != null) '' - ip -6 addr add ${cfg . "hostAddress6"} dev ${name} - ''} - ${optionalString (cfg . "localAddress" or null != null) '' - ip route add ${cfg . "localAddress"} dev ${name} - ''} - ${optionalString (cfg . "localAddress6" or null != null) '' - ip -6 route add ${cfg . "localAddress6"} dev ${name} - ''} - '' - ); + # Set IPs and routes for ${name} + ${optionalString (cfg.hostAddress != null) '' + ip addr add ${cfg.hostAddress} dev ${name} + ''} + ${optionalString (cfg.hostAddress6 != null) '' + ip -6 addr add ${cfg.hostAddress6} dev ${name} + ''} + ${optionalString (cfg.localAddress != null) '' + ip route add ${cfg.localAddress} dev ${name} + ''} + ${optionalString (cfg.localAddress6 != null) '' + ip -6 route add ${cfg.localAddress6} dev ${name} + ''} + ''; in '' if [ "$PRIVATE_NETWORK" = 1 ]; then @@ -202,7 +197,7 @@ let ${ipcall cfg "ip route" "$LOCAL_ADDRESS" "localAddress"} ${ipcall cfg "ip -6 route" "$LOCAL_ADDRESS6" "localAddress6"} fi - ${concatStringsSep "\n" (mapAttrsToList renderExtraVeth cfg . "extraVeths" or {})} + ${concatStringsSep "\n" (mapAttrsToList renderExtraVeth cfg.extraVeths)} fi # Get the leader PID so that we can signal it in @@ -213,6 +208,41 @@ let '' ); + serviceDirectives = cfg: { + ExecReload = pkgs.writeScript "reload-container" + '' + #! ${pkgs.stdenv.shell} -e + ${pkgs.nixos-container}/bin/nixos-container run "$INSTANCE" -- \ + bash --login -c "''${SYSTEM_PATH:-/nix/var/nix/profiles/system}/bin/switch-to-configuration test" + ''; + + SyslogIdentifier = "container %i"; + + EnvironmentFile = "-/etc/containers/%i.conf"; + + Type = "notify"; + + # Note that on reboot, systemd-nspawn returns 133, so this + # unit will be restarted. On poweroff, it returns 0, so the + # unit won't be restarted. + RestartForceExitStatus = "133"; + SuccessExitStatus = "133"; + + Restart = "on-failure"; + + # Hack: we don't want to kill systemd-nspawn, since we call + # "machinectl poweroff" in preStop to shut down the + # container cleanly. But systemd requires sending a signal + # (at least if we want remaining processes to be killed + # after the timeout). So send an ignored signal. + KillMode = "mixed"; + KillSignal = "WINCH"; + + DevicePolicy = "closed"; + DeviceAllow = map (d: "${d.node} ${d.modifier}") cfg.allowedDevices; + }; + + system = config.nixpkgs.system; bindMountOpts = { name, config, ... }: { @@ -243,6 +273,27 @@ let }; + allowedDeviceOpts = { name, config, ... }: { + options = { + node = mkOption { + example = "/dev/net/tun"; + type = types.str; + description = "Path to device node"; + }; + modifier = mkOption { + example = "rw"; + type = types.str; + description = '' + Device node access modifier. Takes a combination + <literal>r</literal> (read), <literal>w</literal> (write), and + <literal>m</literal> (mknod). See the + <literal>systemd.resource-control(5)</literal> man page for more + information.''; + }; + }; + }; + + mkBindFlag = d: let flagPrefix = if d.isReadOnly then " --bind-ro=" else " --bind="; mountstr = if d.hostPath != null then "${d.hostPath}:${d.mountPoint}" else "${d.mountPoint}"; @@ -307,6 +358,17 @@ let }; + dummyConfig = + { + extraVeths = {}; + additionalCapabilities = []; + allowedDevices = []; + hostAddress = null; + hostAddress6 = null; + localAddress = null; + localAddress6 = null; + }; + in { @@ -367,6 +429,26 @@ in ''; }; + additionalCapabilities = mkOption { + type = types.listOf types.str; + default = []; + example = [ "CAP_NET_ADMIN" "CAP_MKNOD" ]; + description = '' + Grant additional capabilities to the container. See the + capabilities(7) and systemd-nspawn(1) man pages for more + information. + ''; + }; + enableTun = mkOption { + type = types.bool; + default = false; + description = '' + Allows the container to create and setup tunnel interfaces + by granting the <literal>NET_ADMIN</literal> capability and + enabling access to <literal>/dev/net/tun</literal>. + ''; + }; + privateNetwork = mkOption { type = types.bool; default = false; @@ -391,9 +473,8 @@ in }; extraVeths = mkOption { - type = types.attrsOf types.optionSet; + type = with types; attrsOf (submodule networkOptions); default = {}; - options = networkOptions; description = '' Extra veth-pairs to be created for the container ''; @@ -408,8 +489,7 @@ in }; bindMounts = mkOption { - type = types.loaOf types.optionSet; - options = [ bindMountOpts ]; + type = with types; loaOf (submodule bindMountOpts); default = {}; example = { "/home" = { hostPath = "/home/alice"; isReadOnly = false; }; @@ -421,6 +501,15 @@ in ''; }; + allowedDevices = mkOption { + type = with types; listOf (submodule allowedDeviceOpts); + default = []; + example = [ { node = "/dev/net/tun"; modifier = "rw"; } ]; + description = '' + A list of device nodes to which the containers has access to. + ''; + }; + } // networkOptions; config = mkMerge @@ -451,7 +540,7 @@ in containers. Each container appears as a service <literal>container-<replaceable>name</replaceable></literal> on the host system, allowing it to be started and stopped via - <command>systemctl</command> . + <command>systemctl</command>. ''; }; @@ -470,11 +559,11 @@ in environment.INSTANCE = "%i"; environment.root = "/var/lib/containers/%i"; - preStart = preStartScript {}; + preStart = preStartScript dummyConfig; - script = startScript {}; + script = startScript dummyConfig; - postStart = postStartScript {}; + postStart = postStartScript dummyConfig; preStop = '' @@ -487,59 +576,39 @@ in restartIfChanged = false; - serviceConfig = { - ExecReload = pkgs.writeScript "reload-container" - '' - #! ${pkgs.stdenv.shell} -e - ${pkgs.nixos-container}/bin/nixos-container run "$INSTANCE" -- \ - bash --login -c "''${SYSTEM_PATH:-/nix/var/nix/profiles/system}/bin/switch-to-configuration test" - ''; - - SyslogIdentifier = "container %i"; - - EnvironmentFile = "-/etc/containers/%i.conf"; - - Type = "notify"; - - # Note that on reboot, systemd-nspawn returns 133, so this - # unit will be restarted. On poweroff, it returns 0, so the - # unit won't be restarted. - RestartForceExitStatus = "133"; - SuccessExitStatus = "133"; - - Restart = "on-failure"; - - # Hack: we don't want to kill systemd-nspawn, since we call - # "machinectl poweroff" in preStop to shut down the - # container cleanly. But systemd requires sending a signal - # (at least if we want remaining processes to be killed - # after the timeout). So send an ignored signal. - KillMode = "mixed"; - KillSignal = "WINCH"; - - DevicePolicy = "closed"; - }; + serviceConfig = serviceDirectives dummyConfig; }; in { systemd.services = listToAttrs (filter (x: x.value != null) ( # The generic container template used by imperative containers [{ name = "container@"; value = unit; }] # declarative containers - ++ (mapAttrsToList (name: cfg: nameValuePair "container@${name}" ( - unit // { - preStart = preStartScript cfg; - script = startScript cfg; - postStart = postStartScript cfg; - } // ( - if cfg.autoStart then - { - wantedBy = [ "multi-user.target" ]; - wants = [ "network.target" ]; - after = [ "network.target" ]; - restartTriggers = [ cfg.path ]; - reloadIfChanged = true; - } - else {}) + ++ (mapAttrsToList (name: cfg: nameValuePair "container@${name}" (let + config = cfg // ( + if cfg.enableTun then + { + allowedDevices = cfg.allowedDevices + ++ [ { node = "/dev/net/tun"; modifier = "rw"; } ]; + additionalCapabilities = cfg.additionalCapabilities + ++ [ "CAP_NET_ADMIN" ]; + } + else {}); + in + unit // { + preStart = preStartScript config; + script = startScript config; + postStart = postStartScript config; + serviceConfig = serviceDirectives config; + } // ( + if config.autoStart then + { + wantedBy = [ "multi-user.target" ]; + wants = [ "network.target" ]; + after = [ "network.target" ]; + restartTriggers = [ config.path ]; + reloadIfChanged = true; + } + else {}) )) config.containers) )); diff --git a/nixos/modules/virtualisation/docker.nix b/nixos/modules/virtualisation/docker.nix index ebc2be087a5b..92fe98f3f9c2 100644 --- a/nixos/modules/virtualisation/docker.nix +++ b/nixos/modules/virtualisation/docker.nix @@ -40,13 +40,25 @@ in }; storageDriver = mkOption { - type = types.enum ["aufs" "btrfs" "devicemapper" "overlay" "zfs"]; - default = "devicemapper"; + type = types.nullOr (types.enum ["aufs" "btrfs" "devicemapper" "overlay" "overlay2" "zfs"]); + default = null; description = '' - This option determines which Docker storage driver to use. + This option determines which Docker storage driver to use. By default + it let's docker automatically choose preferred storage driver. ''; }; + + logDriver = + mkOption { + type = types.enum ["none" "json-file" "syslog" "journald" "gelf" "fluentd" "awslogs" "splunk" "etwlogs" "gcplogs"]; + default = "journald"; + description = + '' + This option determines which Docker log driver to use. + ''; + }; + extraOptions = mkOption { type = types.separatedString " "; @@ -88,7 +100,12 @@ in after = [ "network.target" ] ++ (optional cfg.socketActivation "docker.socket") ; requires = optional cfg.socketActivation "docker.socket"; serviceConfig = { - ExecStart = "${pkgs.docker}/bin/docker daemon --group=docker --storage-driver=${cfg.storageDriver} ${optionalString cfg.socketActivation "--host=fd://"} ${cfg.extraOptions}"; + ExecStart = ''${pkgs.docker}/bin/dockerd \ + --group=docker --log-driver=${cfg.logDriver} \ + ${optionalString (cfg.storageDriver != null) "--storage-driver=${cfg.storageDriver}"} \ + ${optionalString cfg.socketActivation "--host=fd://"} \ + ${cfg.extraOptions} + ''; # I'm not sure if that limits aren't too high, but it's what # goes in config bundled with docker itself LimitNOFILE = 1048576; diff --git a/nixos/modules/virtualisation/google-compute-image.nix b/nixos/modules/virtualisation/google-compute-image.nix index 489b612f1675..90dbd3b6d632 100644 --- a/nixos/modules/virtualisation/google-compute-image.nix +++ b/nixos/modules/virtualisation/google-compute-image.nix @@ -111,7 +111,7 @@ in # Allow root logins only using the SSH key that the user specified # at instance creation time. services.openssh.enable = true; - services.openssh.permitRootLogin = "without-password"; + services.openssh.permitRootLogin = "prohibit-password"; services.openssh.passwordAuthentication = mkDefault false; # Force getting the hostname from Google Compute. diff --git a/nixos/modules/virtualisation/nova-image.nix b/nixos/modules/virtualisation/nova-image.nix index 7971212b47c5..e253c77ebb4f 100644 --- a/nixos/modules/virtualisation/nova-image.nix +++ b/nixos/modules/virtualisation/nova-image.nix @@ -31,7 +31,7 @@ with lib; # Allow root logins services.openssh.enable = true; - services.openssh.permitRootLogin = "without-password"; + services.openssh.permitRootLogin = "prohibit-password"; # Put /tmp and /var on /ephemeral0, which has a lot more space. # Unfortunately we can't do this with the `fileSystems' option diff --git a/nixos/modules/virtualisation/virtualbox-host.nix b/nixos/modules/virtualisation/virtualbox-host.nix index ce4abecd6762..7214543871d6 100644 --- a/nixos/modules/virtualisation/virtualbox-host.nix +++ b/nixos/modules/virtualisation/virtualbox-host.nix @@ -4,10 +4,15 @@ with lib; let cfg = config.virtualisation.virtualbox.host; - virtualbox = config.boot.kernelPackages.virtualbox.override { + + virtualbox = pkgs.virtualbox.override { inherit (cfg) enableHardening headless; }; + kernelModules = config.boot.kernelPackages.virtualbox.override { + inherit virtualbox; + }; + in { @@ -60,7 +65,7 @@ in config = mkIf cfg.enable (mkMerge [{ boot.kernelModules = [ "vboxdrv" "vboxnetadp" "vboxnetflt" ]; - boot.extraModulePackages = [ virtualbox ]; + boot.extraModulePackages = [ kernelModules ]; environment.systemPackages = [ virtualbox ]; security.setuidOwners = let diff --git a/nixos/modules/virtualisation/virtualbox-image.nix b/nixos/modules/virtualisation/virtualbox-image.nix index b6a5b3e4788d..d68b3bb73904 100644 --- a/nixos/modules/virtualisation/virtualbox-image.nix +++ b/nixos/modules/virtualisation/virtualbox-image.nix @@ -34,7 +34,7 @@ in { postVM = '' export HOME=$PWD - export PATH=${pkgs.linuxPackages.virtualbox}/bin:$PATH + export PATH=${pkgs.virtualbox}/bin:$PATH echo "creating VirtualBox pass-through disk wrapper (no copying invovled)..." VBoxManage internalcommands createrawvmdk -filename disk.vmdk -rawdisk $diskImage |