diff options
Diffstat (limited to 'nixos/modules')
120 files changed, 2472 insertions, 1549 deletions
diff --git a/nixos/modules/config/networking.nix b/nixos/modules/config/networking.nix index aab5523c6848..fdc782b0579e 100644 --- a/nixos/modules/config/networking.nix +++ b/nixos/modules/config/networking.nix @@ -29,6 +29,19 @@ in ''; }; + networking.hostConf = lib.mkOption { + type = types.lines; + default = "multi on"; + example = '' + multi on + reorder on + trim lan + ''; + description = '' + The contents of <filename>/etc/host.conf</filename>. See also <citerefentry><refentrytitle>host.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>. + ''; + }; + networking.dnsSingleRequest = lib.mkOption { type = types.bool; default = false; @@ -171,6 +184,9 @@ in ${cfg.extraHosts} ''; + # /etc/host.conf: resolver configuration file + "host.conf".text = cfg.hostConf; + # /etc/resolvconf.conf: Configuration for openresolv. "resolvconf.conf".text = '' @@ -232,7 +248,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 693e1df66c6c..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.gtk2 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/i18n/input-method/ibus.nix b/nixos/modules/i18n/input-method/ibus.nix index d64cf2f283bf..e23e28aa25ef 100644 --- a/nixos/modules/i18n/input-method/ibus.nix +++ b/nixos/modules/i18n/input-method/ibus.nix @@ -17,7 +17,7 @@ let [Desktop Entry] Name=IBus Type=Application - Exec=${ibusPackage}/bin/ibus-daemon --daemonize --xim --cache=refresh + Exec=${ibusPackage}/bin/ibus-daemon --daemonize --xim ''; }; in 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/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 13a7323e858e..2881d843760d 100644 --- a/nixos/modules/misc/ids.nix +++ b/nixos/modules/misc/ids.nix @@ -119,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; @@ -275,6 +274,8 @@ 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! @@ -376,7 +377,6 @@ minidlna = 91; elasticsearch = 92; #tcpcryptd = 93; # unused - connman = 94; firebird = 95; keys = 96; haproxy = 97; @@ -520,6 +520,8 @@ 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 07da64c63847..d1a786d8f629 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 @@ -210,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 @@ -343,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 @@ -382,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 @@ -469,6 +473,7 @@ ./services/system/uptimed.nix ./services/torrent/deluge.nix ./services/torrent/flexget.nix + ./services/torrent/opentracker.nix ./services/torrent/peerflix.nix ./services/torrent/transmission.nix ./services/ttys/agetty.nix @@ -477,6 +482,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/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..5b7d94157454 100644 --- a/nixos/modules/programs/zsh/zsh.nix +++ b/nixos/modules/programs/zsh/zsh.nix @@ -84,6 +84,14 @@ in type = types.bool; }; + enableSyntaxHighlighting = mkOption { + default = false; + description = '' + Enable zsh-syntax-highlighting + ''; + type = types.bool; + }; + }; }; @@ -102,9 +110,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 @@ -120,6 +128,10 @@ in ${if cfg.enableCompletion then "autoload -U compinit && compinit" else ""} + ${optionalString (cfg.enableSyntaxHighlighting) + "source ${pkgs.zsh-syntax-highlighting}/share/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh" + } + HELPDIR="${pkgs.zsh}/share/zsh/$ZSH_VERSION/help" ''; @@ -182,7 +194,8 @@ in environment.etc."zinputrc".source = ./zinputrc; environment.systemPackages = [ pkgs.zsh ] - ++ optional cfg.enableCompletion pkgs.nix-zsh-completions; + ++ optional cfg.enableCompletion pkgs.nix-zsh-completions + ++ optional cfg.enableSyntaxHighlighting pkgs.zsh-syntax-highlighting; environment.pathsToLink = optional cfg.enableCompletion "/share/zsh"; diff --git a/nixos/modules/rename.nix b/nixos/modules/rename.nix index e597cec6b32d..9abe7d450c93 100644 --- a/nixos/modules/rename.nix +++ b/nixos/modules/rename.nix @@ -153,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..12736e57b4a6 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/"; @@ -283,6 +282,7 @@ in timerConfig = { OnCalendar = cfg.renewInterval; Unit = "acme-${cert}.service"; + Persistent = "yes"; }; }) ); diff --git a/nixos/modules/security/grsecurity.xml b/nixos/modules/security/grsecurity.xml index 28415e89bfab..37314bdba8a5 100644 --- a/nixos/modules/security/grsecurity.xml +++ b/nixos/modules/security/grsecurity.xml @@ -149,6 +149,10 @@ <listitem><para>Trusted path execution: a desirable feature, but requires some more work to operate smoothly on NixOS.</para></listitem> + + <listitem><para>Module hardening: would break user initiated module + loading. Might enable this at some point, depending on the potential + breakage.</para></listitem> </itemizedlist> </para></listitem> @@ -208,8 +212,6 @@ let kernel = pkgs.linux_grsec_nixos.override { extraConfig = '' - GRKERNSEC y - PAX y GRKERNSEC_CONFIG_AUTO y GRKERNSEC_CONFIG_SERVER y GRKERNSEC_CONFIG_SECURITY y 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/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/cluster/kubernetes.nix b/nixos/modules/services/cluster/kubernetes.nix index 42efde36678f..4bdd7f95f774 100644 --- a/nixos/modules/services/cluster/kubernetes.nix +++ b/nixos/modules/services/cluster/kubernetes.nix @@ -421,7 +421,7 @@ in { description = "Kubernetes Api Server"; wantedBy = [ "multi-user.target" ]; requires = ["kubernetes-setup.service"]; - after = [ "network-interfaces.target" "etcd.service" ]; + after = [ "network.target" "etcd.service" "kubernetes-setup.service" ]; serviceConfig = { ExecStart = let authorizationPolicyFile = @@ -468,7 +468,7 @@ in { systemd.services.kube-scheduler = { description = "Kubernetes Scheduler Service"; wantedBy = [ "multi-user.target" ]; - after = [ "network-interfaces.target" "kubernetes-apiserver.service" ]; + after = [ "network.target" "kubernetes-apiserver.service" ]; serviceConfig = { ExecStart = ''${cfg.package}/bin/kube-scheduler \ --address=${cfg.scheduler.address} \ @@ -487,7 +487,7 @@ in { systemd.services.kube-controller-manager = { description = "Kubernetes Controller Manager Service"; wantedBy = [ "multi-user.target" ]; - after = [ "network-interfaces.target" "kubernetes-apiserver.service" ]; + after = [ "network.target" "kubernetes-apiserver.service" ]; serviceConfig = { ExecStart = ''${cfg.package}/bin/kube-controller-manager \ --address=${cfg.controllerManager.address} \ @@ -511,7 +511,7 @@ in { description = "Kubernetes Kubelet Service"; wantedBy = [ "multi-user.target" ]; requires = ["kubernetes-setup.service"]; - after = [ "network-interfaces.target" "etcd.service" "docker.service" ]; + after = [ "network.target" "etcd.service" "docker.service" "kubernetes-setup.service" ]; path = [ pkgs.gitMinimal pkgs.openssh ]; script = '' export PATH="/bin:/sbin:/usr/bin:/usr/sbin:$PATH" @@ -542,7 +542,7 @@ in { systemd.services.kube-proxy = { description = "Kubernetes Proxy Service"; wantedBy = [ "multi-user.target" ]; - after = [ "network-interfaces.target" "etcd.service" ]; + after = [ "network.target" "etcd.service" ]; serviceConfig = { ExecStart = ''${cfg.package}/bin/kube-proxy \ --master=${cfg.proxy.master} \ 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/databases/cassandra.nix b/nixos/modules/services/databases/cassandra.nix index c98af617587d..b43b448ed7e1 100644 --- a/nixos/modules/services/databases/cassandra.nix +++ b/nixos/modules/services/databases/cassandra.nix @@ -377,7 +377,7 @@ in { systemd.services.cassandra = { description = "Cassandra Daemon"; wantedBy = [ "multi-user.target" ]; - after = [ "network-interfaces.target" ]; + after = [ "network.target" ]; environment = cassandraEnvironment; restartTriggers = [ cassandraConfFile cassandraLogFile cassandraRackFile ]; serviceConfig = { diff --git a/nixos/modules/services/databases/influxdb.nix b/nixos/modules/services/databases/influxdb.nix index 11ea0e1b6b41..dd88624f406c 100644 --- a/nixos/modules/services/databases/influxdb.nix +++ b/nixos/modules/services/databases/influxdb.nix @@ -160,7 +160,7 @@ in systemd.services.influxdb = { description = "InfluxDB Server"; wantedBy = [ "multi-user.target" ]; - after = [ "network-interfaces.target" ]; + after = [ "network.target" ]; serviceConfig = { ExecStart = ''${cfg.package}/bin/influxd -config "${configFile}"''; User = "${cfg.user}"; diff --git a/nixos/modules/services/databases/neo4j.nix b/nixos/modules/services/databases/neo4j.nix index 41b960685906..146a604adb2f 100644 --- a/nixos/modules/services/databases/neo4j.nix +++ b/nixos/modules/services/databases/neo4j.nix @@ -123,7 +123,7 @@ in { systemd.services.neo4j = { description = "Neo4j Daemon"; wantedBy = [ "multi-user.target" ]; - after = [ "network-interfaces.target" ]; + after = [ "network.target" ]; environment = { NEO4J_INSTANCE = cfg.dataDir; }; serviceConfig = { ExecStart = "${cfg.package}/bin/neo4j console"; 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/apache-kafka.nix b/nixos/modules/services/misc/apache-kafka.nix index 88ce8b5a23fc..c856d3294c01 100644 --- a/nixos/modules/services/misc/apache-kafka.nix +++ b/nixos/modules/services/misc/apache-kafka.nix @@ -139,7 +139,7 @@ in { systemd.services.apache-kafka = { description = "Apache Kafka Daemon"; wantedBy = [ "multi-user.target" ]; - after = [ "network-interfaces.target" ]; + after = [ "network.target" ]; serviceConfig = { ExecStart = '' ${pkgs.jre}/bin/java \ 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/emby.nix b/nixos/modules/services/misc/emby.nix index fe872349f45e..9f290ed70c97 100644 --- a/nixos/modules/services/misc/emby.nix +++ b/nixos/modules/services/misc/emby.nix @@ -43,7 +43,7 @@ in User = cfg.user; Group = cfg.group; PermissionsStartOnly = "true"; - ExecStart = "${pkgs.mono}/bin/mono ${pkgs.emby}/bin/MediaBrowser.Server.Mono.exe"; + ExecStart = "${pkgs.emby}/bin/MediaBrowser.Server.Mono"; Restart = "on-failure"; }; }; diff --git a/nixos/modules/services/misc/etcd.nix b/nixos/modules/services/misc/etcd.nix index d30cc5fd7e89..1de02d76ba0a 100644 --- a/nixos/modules/services/misc/etcd.nix +++ b/nixos/modules/services/misc/etcd.nix @@ -143,9 +143,9 @@ in { config = mkIf cfg.enable { systemd.services.etcd = { - description = "Etcd Daemon"; + description = "etcd key-value store"; wantedBy = [ "multi-user.target" ]; - after = [ "network-interfaces.target" ]; + after = [ "network.target" ]; environment = (filterAttrs (n: v: v != null) { ETCD_NAME = cfg.name; @@ -168,12 +168,18 @@ in { ETCD_INITIAL_CLUSTER_TOKEN = cfg.initialClusterToken; }) // (mapAttrs' (n: v: nameValuePair "ETCD_${n}" v) cfg.extraConf); + unitConfig = { + Documentation = "https://github.com/coreos/etcd"; + }; + serviceConfig = { Type = "notify"; ExecStart = "${pkgs.etcd.bin}/bin/etcd"; User = "etcd"; PermissionsStartOnly = true; + LimitNOFILE = 40000; }; + preStart = '' mkdir -m 0700 -p ${cfg.dataDir} if [ "$(id -u)" = 0 ]; then chown etcd ${cfg.dataDir}; fi diff --git a/nixos/modules/services/misc/folding-at-home.nix b/nixos/modules/services/misc/folding-at-home.nix index 4f09cbfdd79b..053e7e95635f 100644 --- a/nixos/modules/services/misc/folding-at-home.nix +++ b/nixos/modules/services/misc/folding-at-home.nix @@ -50,7 +50,7 @@ in { }; systemd.services.foldingathome = { - after = [ "network-interfaces.target" ]; + after = [ "network.target" ]; wantedBy = [ "multi-user.target" ]; preStart = '' mkdir -m 0755 -p ${stateDir} diff --git a/nixos/modules/services/misc/gitlab.nix b/nixos/modules/services/misc/gitlab.nix index de90d461f527..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,11 +527,6 @@ 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 @@ -538,6 +535,15 @@ in { # 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/mesos-master.nix b/nixos/modules/services/misc/mesos-master.nix index 497646b2b418..99583ebeebd5 100644 --- a/nixos/modules/services/misc/mesos-master.nix +++ b/nixos/modules/services/misc/mesos-master.nix @@ -80,7 +80,7 @@ in { systemd.services.mesos-master = { description = "Mesos Master"; wantedBy = [ "multi-user.target" ]; - after = [ "network-interfaces.target" ]; + after = [ "network.target" ]; serviceConfig = { ExecStart = '' ${pkgs.mesos}/bin/mesos-master \ diff --git a/nixos/modules/services/misc/mesos-slave.nix b/nixos/modules/services/misc/mesos-slave.nix index 8c29734813a1..9ddecb6fe30c 100644 --- a/nixos/modules/services/misc/mesos-slave.nix +++ b/nixos/modules/services/misc/mesos-slave.nix @@ -105,7 +105,7 @@ in { systemd.services.mesos-slave = { description = "Mesos Slave"; wantedBy = [ "multi-user.target" ]; - after = [ "network-interfaces.target" ]; + after = [ "network.target" ]; environment.MESOS_CONTAINERIZERS = concatStringsSep "," containerizers; serviceConfig = { ExecStart = '' 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/misc/svnserve.nix b/nixos/modules/services/misc/svnserve.nix index c74befac749d..04a6cd7bfa9b 100644 --- a/nixos/modules/services/misc/svnserve.nix +++ b/nixos/modules/services/misc/svnserve.nix @@ -35,7 +35,7 @@ in config = mkIf cfg.enable { systemd.services.svnserve = { - after = [ "network-interfaces.target" ]; + after = [ "network.target" ]; wantedBy = [ "multi-user.target" ]; preStart = "mkdir -p ${cfg.svnBaseDir}"; script = "${pkgs.subversion.out}/bin/svnserve -r ${cfg.svnBaseDir} -d --foreground --pid-file=/var/run/svnserve.pid"; diff --git a/nixos/modules/services/misc/zookeeper.nix b/nixos/modules/services/misc/zookeeper.nix index 4ce692b6f6a5..b7bca8b56b28 100644 --- a/nixos/modules/services/misc/zookeeper.nix +++ b/nixos/modules/services/misc/zookeeper.nix @@ -113,7 +113,7 @@ in { systemd.services.zookeeper = { description = "Zookeeper Daemon"; wantedBy = [ "multi-user.target" ]; - after = [ "network-interfaces.target" ]; + after = [ "network.target" ]; environment = { ZOOCFGDIR = configDir; }; serviceConfig = { ExecStart = '' diff --git a/nixos/modules/services/monitoring/graphite.nix b/nixos/modules/services/monitoring/graphite.nix index 08fc3f04dbfc..1de3320dc42c 100644 --- a/nixos/modules/services/monitoring/graphite.nix +++ b/nixos/modules/services/monitoring/graphite.nix @@ -387,7 +387,7 @@ in { systemd.services.carbonCache = let name = "carbon-cache"; in { description = "Graphite Data Storage Backend"; wantedBy = [ "multi-user.target" ]; - after = [ "network-interfaces.target" ]; + after = [ "network.target" ]; environment = carbonEnv; serviceConfig = { ExecStart = "${pkgs.pythonPackages.twisted}/bin/twistd ${carbonOpts name}"; @@ -410,7 +410,7 @@ in { enable = cfg.carbon.enableAggregator; description = "Carbon Data Aggregator"; wantedBy = [ "multi-user.target" ]; - after = [ "network-interfaces.target" ]; + after = [ "network.target" ]; environment = carbonEnv; serviceConfig = { ExecStart = "${pkgs.pythonPackages.twisted}/bin/twistd ${carbonOpts name}"; @@ -426,7 +426,7 @@ in { systemd.services.carbonRelay = let name = "carbon-relay"; in { description = "Carbon Data Relay"; wantedBy = [ "multi-user.target" ]; - after = [ "network-interfaces.target" ]; + after = [ "network.target" ]; environment = carbonEnv; serviceConfig = { ExecStart = "${pkgs.pythonPackages.twisted}/bin/twistd ${carbonOpts name}"; @@ -448,7 +448,7 @@ in { systemd.services.graphiteWeb = { description = "Graphite Web Interface"; wantedBy = [ "multi-user.target" ]; - after = [ "network-interfaces.target" ]; + after = [ "network.target" ]; path = [ pkgs.perl ]; environment = { PYTHONPATH = let @@ -501,7 +501,7 @@ in { systemd.services.graphiteApi = { description = "Graphite Api Interface"; wantedBy = [ "multi-user.target" ]; - after = [ "network-interfaces.target" ]; + after = [ "network.target" ]; environment = { PYTHONPATH = let aenv = pkgs.python.buildEnv.override { @@ -538,7 +538,7 @@ in { systemd.services.seyren = { description = "Graphite Alerting Dashboard"; wantedBy = [ "multi-user.target" ]; - after = [ "network-interfaces.target" "mongodb.service" ]; + after = [ "network.target" "mongodb.service" ]; environment = seyrenConfig; serviceConfig = { ExecStart = "${pkgs.seyren}/bin/seyren -httpPort ${toString cfg.seyren.port}"; @@ -561,7 +561,7 @@ in { systemd.services.graphitePager = { description = "Graphite Pager Alerting Daemon"; wantedBy = [ "multi-user.target" ]; - after = [ "network-interfaces.target" "redis.service" ]; + after = [ "network.target" "redis.service" ]; environment = { REDIS_URL = cfg.pager.redisUrl; GRAPHITE_URL = cfg.pager.graphiteUrl; diff --git a/nixos/modules/services/monitoring/monit.nix b/nixos/modules/services/monitoring/monit.nix index 704693969a35..e07ffd2e8b54 100644 --- a/nixos/modules/services/monitoring/monit.nix +++ b/nixos/modules/services/monitoring/monit.nix @@ -36,11 +36,16 @@ in ]; systemd.services.monit = { - description = "Monit system watcher"; - after = [ "network-interfaces.target" ]; + description = "Pro-active monitoring utility for unix systems"; + after = [ "network.target" ]; wantedBy = [ "multi-user.target" ]; - script = "${pkgs.monit}/bin/monit -I -c /etc/monit.conf"; - serviceConfig.Restart = "always"; + serviceConfig = { + ExecStart = "${pkgs.monit}/bin/monit -I -c /etc/monit.conf"; + ExecStop = "${pkgs.monit}/bin/monit -c /etc/monit.conf quit"; + ExecReload = "${pkgs.monit}/bin/monit -c /etc/monit.conf reload"; + KillMode = "process"; + Restart = "always"; + }; }; }; } diff --git a/nixos/modules/services/monitoring/nagios.nix b/nixos/modules/services/monitoring/nagios.nix index f2f7710de9e7..4914c5db97d2 100644 --- a/nixos/modules/services/monitoring/nagios.nix +++ b/nixos/modules/services/monitoring/nagios.nix @@ -163,7 +163,7 @@ in description = "Nagios monitoring daemon"; path = [ pkgs.nagios ]; wantedBy = [ "multi-user.target" ]; - after = [ "network-interfaces.target" ]; + after = [ "network.target" ]; serviceConfig = { User = "nagios"; 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/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/openafs-client/default.nix b/nixos/modules/services/network-filesystems/openafs-client/default.nix index 891f41c8dcdc..6f51e287910a 100644 --- a/nixos/modules/services/network-filesystems/openafs-client/default.nix +++ b/nixos/modules/services/network-filesystems/openafs-client/default.nix @@ -75,7 +75,7 @@ in systemd.services.afsd = { description = "AFS client"; wantedBy = [ "multi-user.target" ]; - after = [ "network-interfaces.target" ]; + after = [ "network.target" ]; preStart = '' mkdir -p -m 0755 /afs 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/bind.nix b/nixos/modules/services/networking/bind.nix index 08afafceff24..41d7128ec31e 100644 --- a/nixos/modules/services/networking/bind.nix +++ b/nixos/modules/services/networking/bind.nix @@ -145,8 +145,8 @@ in }; systemd.services.bind = { - description = "BIND name server job"; - after = [ "network-interfaces.target" ]; + description = "BIND Domain Name Server"; + after = [ "network.target" ]; wantedBy = [ "multi-user.target" ]; preStart = '' @@ -155,6 +155,7 @@ in ''; script = "${pkgs.bind.bin}/sbin/named -u ${bindUser} ${optionalString cfg.ipv4Only "-4"} -c ${cfg.configFile} -f"; + unitConfig.Documentation = "man:named(8)"; }; }; } diff --git a/nixos/modules/services/networking/cjdns.nix b/nixos/modules/services/networking/cjdns.nix index 0495b32c6fa8..cb00139c5f1c 100644 --- a/nixos/modules/services/networking/cjdns.nix +++ b/nixos/modules/services/networking/cjdns.nix @@ -208,9 +208,9 @@ in # networking.firewall.allowedUDPPorts = ... systemd.services.cjdns = { - description = "encrypted networking for everybody"; - wantedBy = [ "network.target" ]; - after = [ "networkSetup.service" "network-interfaces.target" ]; + description = "cjdns: routing engine designed for security, scalability, speed and ease of use"; + wantedBy = [ "multi-user.target" ]; + after = [ "network.target" ]; preStart = if cfg.confFile != "" then "" else '' [ -e /etc/cjdns.keys ] && source /etc/cjdns.keys 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/dhcpcd.nix b/nixos/modules/services/networking/dhcpcd.nix index 4b0e90886510..87c0aa50a1ff 100644 --- a/nixos/modules/services/networking/dhcpcd.nix +++ b/nixos/modules/services/networking/dhcpcd.nix @@ -158,8 +158,8 @@ in { description = "DHCP Client"; wantedBy = [ "multi-user.target" ]; + after = [ "network.target" ]; wants = [ "network.target" ]; - before = [ "network.target" ]; # Stopping dhcpcd during a reconfiguration is undesirable # because it brings down the network interfaces configured by 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/gvpe.nix b/nixos/modules/services/networking/gvpe.nix index 27b64b5bb95f..3ef3548e0a08 100644 --- a/nixos/modules/services/networking/gvpe.nix +++ b/nixos/modules/services/networking/gvpe.nix @@ -105,7 +105,7 @@ in config = mkIf cfg.enable { systemd.services.gvpe = { description = "GNU Virtual Private Ethernet node"; - after = [ "network-interfaces.target" ]; + after = [ "network.target" ]; wantedBy = [ "multi-user.target" ]; preStart = '' 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/nat.nix b/nixos/modules/services/networking/nat.nix index 9d163e60d5ea..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 @@ -171,7 +171,7 @@ in systemd.services = mkIf (!config.networking.firewall.enable) { nat = { description = "Network Address Translation"; wantedBy = [ "network.target" ]; - after = [ "network-interfaces.target" "systemd-modules-load.service" ]; + after = [ "network-pre.target" "systemd-modules-load.service" ]; path = [ pkgs.iptables ]; unitConfig.ConditionCapability = "CAP_NET_ADMIN"; 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/oidentd.nix b/nixos/modules/services/networking/oidentd.nix index 651bb8e967cf..ba7acd879546 100644 --- a/nixos/modules/services/networking/oidentd.nix +++ b/nixos/modules/services/networking/oidentd.nix @@ -25,7 +25,7 @@ with lib; config = mkIf config.services.oidentd.enable { systemd.services.oidentd = { - after = [ "network-interfaces.target" ]; + after = [ "network.target" ]; wantedBy = [ "multi-user.target" ]; serviceConfig.Type = "forking"; script = "${pkgs.oidentd}/sbin/oidentd -u oidentd -g nogroup" + diff --git a/nixos/modules/services/networking/openvpn.nix b/nixos/modules/services/networking/openvpn.nix index 82173a841a3f..3fbf5a9f0227 100644 --- a/nixos/modules/services/networking/openvpn.nix +++ b/nixos/modules/services/networking/openvpn.nix @@ -56,7 +56,7 @@ let description = "OpenVPN instance ‘${name}’"; wantedBy = optional cfg.autoStart "multi-user.target"; - after = [ "network-interfaces.target" ]; + after = [ "network.target" ]; path = [ pkgs.iptables pkgs.iproute pkgs.nettools ]; @@ -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 index 91ad63b88139..ba05e15389f6 100644 --- a/nixos/modules/services/networking/powerdns.nix +++ b/nixos/modules/services/networking/powerdns.nix @@ -35,7 +35,6 @@ in { Restart="on-failure"; RestartSec="1"; StartLimitInterval="0"; - PrivateTmp=true; PrivateDevices=true; CapabilityBoundingSet="CAP_CHOWN CAP_NET_BIND_SERVICE CAP_SETGID CAP_SETUID CAP_SYS_CHROOT"; NoNewPrivileges=true; 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 d5e2e3041b49..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"; @@ -50,9 +50,9 @@ in systemd.services.radicale = { description = "A Simple Calendar and Contact Server"; - after = [ "network-interfaces.target" ]; + 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/softether.nix b/nixos/modules/services/networking/softether.nix index 5e49efc3aa3a..16530078b978 100644 --- a/nixos/modules/services/networking/softether.nix +++ b/nixos/modules/services/networking/softether.nix @@ -63,7 +63,6 @@ in ]; systemd.services."softether-init" = { description = "SoftEther VPN services initial task"; - wantedBy = [ "network-interfaces.target" ]; serviceConfig = { Type = "oneshot"; RemainAfterExit = false; @@ -84,8 +83,9 @@ in (mkIf (cfg.vpnserver.enable) { systemd.services.vpnserver = { description = "SoftEther VPN Server"; - after = [ "softether-init.service" ]; - wantedBy = [ "network-interfaces.target" ]; + after = [ "softether-init.service" "network.target" ]; + wants = [ "softether-init.service" ]; + wantedBy = [ "multi-user.target" ]; serviceConfig = { Type = "forking"; ExecStart = "${pkg}/bin/vpnserver start"; @@ -104,8 +104,9 @@ in (mkIf (cfg.vpnbridge.enable) { systemd.services.vpnbridge = { description = "SoftEther VPN Bridge"; - after = [ "softether-init.service" ]; - wantedBy = [ "network-interfaces.target" ]; + after = [ "softether-init.service" "network.target" ]; + wants = [ "softether-init.service" ]; + wantedBy = [ "multi-user.target" ]; serviceConfig = { Type = "forking"; ExecStart = "${pkg}/bin/vpnbridge start"; @@ -124,8 +125,9 @@ in (mkIf (cfg.vpnclient.enable) { systemd.services.vpnclient = { description = "SoftEther VPN Client"; - after = [ "softether-init.service" ]; - wantedBy = [ "network-interfaces.target" ]; + after = [ "softether-init.service" "network.target" ]; + wants = [ "softether-init.service" ]; + wantedBy = [ "multi-user.target" ]; serviceConfig = { Type = "forking"; ExecStart = "${pkg}/bin/vpnclient start"; diff --git a/nixos/modules/services/networking/ssh/lshd.nix b/nixos/modules/services/networking/ssh/lshd.nix index 661a6a524631..eca599afb33b 100644 --- a/nixos/modules/services/networking/ssh/lshd.nix +++ b/nixos/modules/services/networking/ssh/lshd.nix @@ -120,7 +120,7 @@ in systemd.services.lshd = { description = "GNU lshd SSH2 daemon"; - after = [ "network-interfaces.target" ]; + after = [ "network.target" ]; wantedBy = [ "multi-user.target" ]; 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/tcpcrypt.nix b/nixos/modules/services/networking/tcpcrypt.nix index 267653abce03..2f304165eb4b 100644 --- a/nixos/modules/services/networking/tcpcrypt.nix +++ b/nixos/modules/services/networking/tcpcrypt.nix @@ -39,7 +39,7 @@ in description = "tcpcrypt"; wantedBy = [ "multi-user.target" ]; - after = [ "network-interfaces.target" ]; + after = [ "network.target" ]; path = [ pkgs.iptables pkgs.tcpcrypt pkgs.procps ]; diff --git a/nixos/modules/services/networking/tinc.nix b/nixos/modules/services/networking/tinc.nix index 8da0f817ae2a..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. - ''; - }; - }; }; }; @@ -149,8 +151,8 @@ in ("tinc.${network}") ({ description = "Tinc Daemon - ${network}"; - wantedBy = [ "network.target" ]; - after = [ "network-interfaces.target" ]; + wantedBy = [ "multi-user.target" ]; + after = [ "network.target" ]; path = [ data.package ]; restartTriggers = [ config.environment.etc."tinc/${network}/tinc.conf".source ] ++ mapAttrsToList (host: _ : config.environment.etc."tinc/${network}/hosts/${host}".source) data.hosts; diff --git a/nixos/modules/services/networking/wicd.nix b/nixos/modules/services/networking/wicd.nix index 9e5a437b4856..03c6bd28aaba 100644 --- a/nixos/modules/services/networking/wicd.nix +++ b/nixos/modules/services/networking/wicd.nix @@ -26,7 +26,9 @@ with lib; environment.systemPackages = [pkgs.wicd]; systemd.services.wicd = { - after = [ "network-interfaces.target" ]; + after = [ "network-pre.target" ]; + before = [ "network.target" ]; + wants = [ "network.target" ]; wantedBy = [ "multi-user.target" ]; script = "${pkgs.wicd}/sbin/wicd -f"; }; diff --git a/nixos/modules/services/networking/wpa_supplicant.nix b/nixos/modules/services/networking/wpa_supplicant.nix index de99ce4f0260..a344d7855463 100644 --- a/nixos/modules/services/networking/wpa_supplicant.nix +++ b/nixos/modules/services/networking/wpa_supplicant.nix @@ -128,9 +128,9 @@ in { in { description = "WPA Supplicant"; - after = [ "network-interfaces.target" ] ++ lib.concatMap deviceUnit ifaces; + after = [ "network.target" ] ++ lib.concatMap deviceUnit ifaces; requires = lib.concatMap deviceUnit ifaces; - wantedBy = [ "network.target" ]; + wantedBy = [ "network-online.target" ]; path = [ pkgs.wpa_supplicant ]; diff --git a/nixos/modules/services/networking/xinetd.nix b/nixos/modules/services/networking/xinetd.nix index 08680b517808..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."; }; - }; + })); }; @@ -141,7 +143,7 @@ in config = mkIf cfg.enable { systemd.services.xinetd = { description = "xinetd server"; - after = [ "network-interfaces.target" ]; + after = [ "network.target" ]; wantedBy = [ "multi-user.target" ]; path = [ pkgs.xinetd ]; script = "xinetd -syslog daemon -dontfork -stayalive -f ${configFile}"; diff --git a/nixos/modules/services/networking/zerobin.nix b/nixos/modules/services/networking/zerobin.nix index 1c524602f8e9..274bbca53fa3 100644 --- a/nixos/modules/services/networking/zerobin.nix +++ b/nixos/modules/services/networking/zerobin.nix @@ -86,15 +86,15 @@ in systemd.services.zerobin = { enable = true; - after = [ "network-interfaces.target" ]; + after = [ "network.target" ]; wantedBy = [ "multi-user.target" ]; serviceConfig.ExecStart = "${pkgs.pythonPackages.zerobin}/bin/zerobin ${cfg.listenAddress} ${toString cfg.listenPort} false ${cfg.user} ${cfg.group} ${zerobin_config}"; serviceConfig.PrivateTmp="yes"; serviceConfig.User = cfg.user; serviceConfig.Group = cfg.group; preStart = '' - mkdir -p ${cfg.dataDir} - chown ${cfg.user} ${cfg.dataDir} + mkdir -p ${cfg.dataDir} + chown ${cfg.user} ${cfg.dataDir} ''; }; }; diff --git a/nixos/modules/services/scheduling/chronos.nix b/nixos/modules/services/scheduling/chronos.nix index db1f0f5f00c9..6c39997fec88 100644 --- a/nixos/modules/services/scheduling/chronos.nix +++ b/nixos/modules/services/scheduling/chronos.nix @@ -41,7 +41,7 @@ in { systemd.services.chronos = { description = "Chronos Service"; wantedBy = [ "multi-user.target" ]; - after = [ "network-interfaces.target" "zookeeper.service" ]; + after = [ "network.target" "zookeeper.service" ]; serviceConfig = { ExecStart = "${pkgs.chronos}/bin/chronos --master ${cfg.master} --zk_hosts ${concatStringsSep "," cfg.zookeeperHosts} --http_port ${toString cfg.httpPort}"; diff --git a/nixos/modules/services/scheduling/marathon.nix b/nixos/modules/services/scheduling/marathon.nix index 4e837c62dc11..19c9a708f21f 100644 --- a/nixos/modules/services/scheduling/marathon.nix +++ b/nixos/modules/services/scheduling/marathon.nix @@ -83,7 +83,7 @@ in { description = "Marathon Service"; environment = cfg.environment; wantedBy = [ "multi-user.target" ]; - after = [ "network-interfaces.target" "zookeeper.service" "mesos-master.service" "mesos-slave.service" ]; + after = [ "network.target" "zookeeper.service" "mesos-master.service" "mesos-slave.service" ]; serviceConfig = { ExecStart = "${pkgs.marathon}/bin/marathon --master ${cfg.master} --zk zk://${concatStringsSep "," cfg.zookeeperHosts}/marathon --http_port ${toString cfg.httpPort} ${concatStringsSep " " cfg.extraCmdLineOptions}"; diff --git a/nixos/modules/services/search/elasticsearch.nix b/nixos/modules/services/search/elasticsearch.nix index 9299aaac2f70..574f74d547a5 100644 --- a/nixos/modules/services/search/elasticsearch.nix +++ b/nixos/modules/services/search/elasticsearch.nix @@ -129,7 +129,7 @@ in { systemd.services.elasticsearch = { description = "Elasticsearch Daemon"; wantedBy = [ "multi-user.target" ]; - after = [ "network-interfaces.target" ]; + after = [ "network.target" ]; path = [ pkgs.inetutils ]; environment = { ES_HOME = cfg.dataDir; diff --git a/nixos/modules/services/search/kibana.nix b/nixos/modules/services/search/kibana.nix index 033b8139d341..d377a6feeb8e 100644 --- a/nixos/modules/services/search/kibana.nix +++ b/nixos/modules/services/search/kibana.nix @@ -138,7 +138,7 @@ in { systemd.services.kibana = { description = "Kibana Service"; wantedBy = [ "multi-user.target" ]; - after = [ "network-interfaces.target" "elasticsearch.service" ]; + after = [ "network.target" "elasticsearch.service" ]; environment = { BABEL_CACHE_PATH = "${cfg.dataDir}/.babelcache.json"; }; serviceConfig = { ExecStart = "${cfg.package}/bin/kibana --config ${cfgFile}"; diff --git a/nixos/modules/services/security/oauth2_proxy.nix b/nixos/modules/services/security/oauth2_proxy.nix index 4c20392214fc..caa7d9d50812 100644 --- a/nixos/modules/services/security/oauth2_proxy.nix +++ b/nixos/modules/services/security/oauth2_proxy.nix @@ -510,7 +510,7 @@ in description = "OAuth2 Proxy"; path = [ cfg.package ]; wantedBy = [ "multi-user.target" ]; - after = [ "network-interfaces.target" ]; + after = [ "network.target" ]; serviceConfig = { User = "oauth2_proxy"; 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/torrent/opentracker.nix b/nixos/modules/services/torrent/opentracker.nix new file mode 100644 index 000000000000..d86b9fea2d79 --- /dev/null +++ b/nixos/modules/services/torrent/opentracker.nix @@ -0,0 +1,44 @@ +{ config, lib, pkgs, ... }: + +with lib; +let + cfg = config.services.opentracker; +in { + options.services.opentracker = { + enable = mkEnableOption "opentracker"; + + package = mkOption { + type = types.package; + description = '' + opentracker package to use + ''; + default = pkgs.opentracker; + }; + + extraOptions = mkOption { + type = types.separatedString " "; + description = '' + Configuration Arguments for opentracker + See https://erdgeist.org/arts/software/opentracker/ for all params + ''; + default = ""; + }; + }; + + config = lib.mkIf cfg.enable { + + systemd.services.opentracker = { + description = "opentracker server"; + after = [ "network.target" ]; + wantedBy = [ "multi-user.target" ]; + restartIfChanged = true; + serviceConfig = { + ExecStart = "${cfg.package}/bin/opentracker ${cfg.extraOptions}"; + PrivateTmp = true; + WorkingDirectory = "/var/empty"; + # By default opentracker drops all privileges and runs in chroot after starting up as root. + }; + }; + }; +} + diff --git a/nixos/modules/services/torrent/peerflix.nix b/nixos/modules/services/torrent/peerflix.nix index 38fbd3b226cd..2e3dd9902d72 100644 --- a/nixos/modules/services/torrent/peerflix.nix +++ b/nixos/modules/services/torrent/peerflix.nix @@ -42,7 +42,7 @@ in { systemd.services.peerflix = { description = "Peerflix Daemon"; wantedBy = [ "multi-user.target" ]; - after = [ "network-interfaces.target" ]; + after = [ "network.target" ]; environment.HOME = cfg.stateDir; preStart = '' 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-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 937b2698ce9b..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 { @@ -244,7 +245,6 @@ in chown ${serverInfo.serverConfig.user} ${config.wordpressUploads} # we should use systemd dependencies here - #waitForUnit("network-interfaces.target"); if [ ! -d ${serverInfo.fullConfig.services.mysql.dataDir}/${config.dbName} ]; then echo "Need to create the database '${config.dbName}' and grant permissions to user named '${config.dbUser}'." # Wait until MySQL is up @@ -253,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/tomcat.nix b/nixos/modules/services/web-servers/tomcat.nix index fa6b4c0629d7..943415e08c64 100644 --- a/nixos/modules/services/web-servers/tomcat.nix +++ b/nixos/modules/services/web-servers/tomcat.nix @@ -139,7 +139,7 @@ in systemd.services.tomcat = { description = "Apache Tomcat server"; wantedBy = [ "multi-user.target" ]; - after = [ "network-interfaces.target" ]; + after = [ "network.target" ]; serviceConfig.Type = "oneshot"; serviceConfig.RemainAfterExit = true; 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/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/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/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/xserver.nix b/nixos/modules/services/x11/xserver.nix index 6c6a1e79ed0e..ec2f3a4f8bb1 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 @@ -154,6 +149,22 @@ in ''; }; + autoRepeatDelay = mkOption { + type = types.nullOr types.int; + default = null; + description = '' + Sets the autorepeat delay (length of time in milliseconds that a key must be depressed before autorepeat starts). + ''; + }; + + autoRepeatInterval = mkOption { + type = types.nullOr types.int; + default = null; + description = '' + Sets the autorepeat interval (length of time in milliseconds that should elapse between autorepeat-generated keystrokes). + ''; + }; + inputClassSections = mkOption { type = types.listOf types.lines; default = []; @@ -509,7 +520,6 @@ in environment = { - XKB_BINDIR = "${xorg.xkbcomp}/bin"; # Needed for the Xkb extension. XORG_DRI_DRIVER_PATH = "/run/opengl-driver/lib/dri"; # !!! Depends on the driver selected at runtime. LD_LIBRARY_PATH = concatStringsSep ":" ( [ "${xorg.libX11.out}/lib" "${xorg.libXext.out}/lib" "/run/opengl-driver/lib" ] @@ -541,7 +551,9 @@ in ] ++ optional (cfg.display != null) ":${toString cfg.display}" ++ optional (cfg.tty != null) "vt${toString cfg.tty}" ++ optional (cfg.dpi != null) "-dpi ${toString cfg.dpi}" - ++ optional (!cfg.enableTCP) "-nolisten tcp"; + ++ optional (!cfg.enableTCP) "-nolisten tcp" + ++ optional (cfg.autoRepeatDelay != null) "-ardelay ${toString cfg.autoRepeatDelay}" + ++ optional (cfg.autoRepeatInterval != null) "-arinterval ${toString cfg.autoRepeatInterval}"; services.xserver.modules = concatLists (catAttrs "modules" cfg.drivers) ++ diff --git a/nixos/modules/system/activation/activation-script.nix b/nixos/modules/system/activation/activation-script.nix index 4c3d30e346c5..4a16a6762935 100644 --- a/nixos/modules/system/activation/activation-script.nix +++ b/nixos/modules/system/activation/activation-script.nix @@ -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/loader/grub/grub.nix b/nixos/modules/system/boot/loader/grub/grub.nix index e84cdb3212ce..c3be7407d592 100644 --- a/nixos/modules/system/boot/loader/grub/grub.nix +++ b/nixos/modules/system/boot/loader/grub/grub.nix @@ -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 { @@ -503,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"; } { diff --git a/nixos/modules/system/boot/loader/systemd-boot/systemd-boot-builder.py b/nixos/modules/system/boot/loader/systemd-boot/systemd-boot-builder.py index c703a3e083ba..515136c904c5 100644 --- a/nixos/modules/system/boot/loader/systemd-boot/systemd-boot-builder.py +++ b/nixos/modules/system/boot/loader/systemd-boot/systemd-boot-builder.py @@ -1,4 +1,4 @@ -#! @python@/bin/python +#! @python3@/bin/python3 import argparse import shutil import os @@ -13,29 +13,21 @@ def copy_if_not_exists(source, dest): if not os.path.exists(dest): shutil.copyfile(source, dest) -system_dir = lambda generation: "/nix/var/nix/profiles/system-%d-link" % (generation) +def system_dir(generation): + return "/nix/var/nix/profiles/system-%d-link" % (generation) -def write_entry(generation, kernel, initrd): - entry_file = "@efiSysMountPoint@/loader/entries/nixos-generation-%d.conf" % (generation) - generation_dir = os.readlink(system_dir(generation)) - tmp_path = "%s.tmp" % (entry_file) - kernel_params = "systemConfig=%s init=%s/init " % (generation_dir, generation_dir) - with open("%s/kernel-params" % (generation_dir)) as params_file: - kernel_params = kernel_params + params_file.read() - with open(tmp_path, 'w') as f: - print >> f, "title NixOS" - print >> f, "version Generation %d" % (generation) - if machine_id is not None: print >> f, "machine-id %s" % (machine_id) - print >> f, "linux %s" % (kernel) - print >> f, "initrd %s" % (initrd) - print >> f, "options %s" % (kernel_params) - os.rename(tmp_path, entry_file) +BOOT_ENTRY = """title NixOS +version Generation {generation} +linux {kernel} +initrd {initrd} +options {kernel_params} +""" def write_loader_conf(generation): with open("@efiSysMountPoint@/loader/loader.conf.tmp", 'w') as f: if "@timeout@" != "": - print >> f, "timeout @timeout@" - print >> f, "default nixos-generation-%d" % (generation) + f.write("timeout @timeout@\n") + f.write("default nixos-generation-%d\n" % generation) os.rename("@efiSysMountPoint@/loader/loader.conf.tmp", "@efiSysMountPoint@/loader/loader.conf") def copy_from_profile(generation, name, dry_run=False): @@ -47,10 +39,23 @@ def copy_from_profile(generation, name, dry_run=False): copy_if_not_exists(store_file_path, "@efiSysMountPoint@%s" % (efi_file_path)) return efi_file_path -def add_entry(generation): - efi_kernel_path = copy_from_profile(generation, "kernel") - efi_initrd_path = copy_from_profile(generation, "initrd") - write_entry(generation, efi_kernel_path, efi_initrd_path) +def write_entry(generation, machine_id): + kernel = copy_from_profile(generation, "kernel") + initrd = copy_from_profile(generation, "initrd") + entry_file = "@efiSysMountPoint@/loader/entries/nixos-generation-%d.conf" % (generation) + generation_dir = os.readlink(system_dir(generation)) + tmp_path = "%s.tmp" % (entry_file) + kernel_params = "systemConfig=%s init=%s/init " % (generation_dir, generation_dir) + with open("%s/kernel-params" % (generation_dir)) as params_file: + kernel_params = kernel_params + params_file.read() + with open(tmp_path, 'w') as f: + f.write(BOOT_ENTRY.format(generation=generation, + kernel=kernel, + initrd=initrd, + kernel_params=kernel_params)) + if machine_id is not None: + f.write("machine-id %s\n" % machine_id) + os.rename(tmp_path, entry_file) def mkdir_p(path): try: @@ -65,8 +70,8 @@ def get_generations(profile): "--list-generations", "-p", "/nix/var/nix/profiles/%s" % (profile), - "--option", "build-users-group", "" - ]) + "--option", "build-users-group", ""], + universal_newlines=True) gen_lines = gen_list.split('\n') gen_lines.pop() return [ int(line.split()[0]) for line in gen_lines ] @@ -89,33 +94,37 @@ def remove_old_entries(gens): if not path in known_paths: os.unlink(path) -parser = argparse.ArgumentParser(description='Update NixOS-related systemd-boot files') -parser.add_argument('default_config', metavar='DEFAULT-CONFIG', help='The default NixOS config to boot') -args = parser.parse_args() +def main(): + parser = argparse.ArgumentParser(description='Update NixOS-related systemd-boot files') + parser.add_argument('default_config', metavar='DEFAULT-CONFIG', help='The default NixOS config to boot') + args = parser.parse_args() -if os.getenv("NIXOS_INSTALL_GRUB") == "1": - warnings.warn("NIXOS_INSTALL_GRUB env var deprecated, use NIXOS_INSTALL_BOOTLOADER", DeprecationWarning) - os.environ["NIXOS_INSTALL_BOOTLOADER"] = "1" + if os.getenv("NIXOS_INSTALL_GRUB") == "1": + warnings.warn("NIXOS_INSTALL_GRUB env var deprecated, use NIXOS_INSTALL_BOOTLOADER", DeprecationWarning) + os.environ["NIXOS_INSTALL_BOOTLOADER"] = "1" -if os.getenv("NIXOS_INSTALL_BOOTLOADER") == "1": - if "@canTouchEfiVariables@" == "1": - subprocess.check_call(["@systemd@/bin/bootctl", "--path=@efiSysMountPoint@", "install"]) - else: - subprocess.check_call(["@systemd@/bin/bootctl", "--path=@efiSysMountPoint@", "--no-variables", "install"]) + if os.getenv("NIXOS_INSTALL_BOOTLOADER") == "1": + if "@canTouchEfiVariables@" == "1": + subprocess.check_call(["@systemd@/bin/bootctl", "--path=@efiSysMountPoint@", "install"]) + else: + subprocess.check_call(["@systemd@/bin/bootctl", "--path=@efiSysMountPoint@", "--no-variables", "install"]) -mkdir_p("@efiSysMountPoint@/efi/nixos") -mkdir_p("@efiSysMountPoint@/loader/entries") -try: - with open("/etc/machine-id") as machine_file: - machine_id = machine_file.readlines()[0] -except IOError as e: - if e.errno != errno.ENOENT: - raise - machine_id = None + mkdir_p("@efiSysMountPoint@/efi/nixos") + mkdir_p("@efiSysMountPoint@/loader/entries") + try: + with open("/etc/machine-id") as machine_file: + machine_id = machine_file.readlines()[0] + except IOError as e: + if e.errno != errno.ENOENT: + raise + machine_id = None + + gens = get_generations("system") + remove_old_entries(gens) + for gen in gens: + write_entry(gen, machine_id) + if os.readlink(system_dir(gen)) == args.default_config: + write_loader_conf(gen) -gens = get_generations("system") -remove_old_entries(gens) -for gen in gens: - add_entry(gen) - if os.readlink(system_dir(gen)) == args.default_config: - write_loader_conf(gen) +if __name__ == '__main__': + main() diff --git a/nixos/modules/system/boot/loader/systemd-boot/systemd-boot.nix b/nixos/modules/system/boot/loader/systemd-boot/systemd-boot.nix index a778a4f539c9..cc43fb8bab4c 100644 --- a/nixos/modules/system/boot/loader/systemd-boot/systemd-boot.nix +++ b/nixos/modules/system/boot/loader/systemd-boot/systemd-boot.nix @@ -12,7 +12,7 @@ let isExecutable = true; - inherit (pkgs) python; + inherit (pkgs) python3; systemd = config.systemd.package; 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 38b4b437369d..8c139a94c0c8 100644 --- a/nixos/modules/system/boot/networkd.nix +++ b/nixos/modules/system/boot/networkd.nix @@ -296,35 +296,35 @@ let }; addressOptions = { - - addressConfig = mkOption { - default = {}; - example = { Address = "192.168.0.100/24"; }; - type = types.addCheck (types.attrsOf unitOption) checkAddress; - description = '' - Each attribute in this set specifies an option in the - <literal>[Address]</literal> section of the unit. See - <citerefentry><refentrytitle>systemd.network</refentrytitle> - <manvolnum>5</manvolnum></citerefentry> for details. - ''; + options = { + addressConfig = mkOption { + default = {}; + example = { Address = "192.168.0.100/24"; }; + type = types.addCheck (types.attrsOf unitOption) checkAddress; + description = '' + Each attribute in this set specifies an option in the + <literal>[Address]</literal> section of the unit. See + <citerefentry><refentrytitle>systemd.network</refentrytitle> + <manvolnum>5</manvolnum></citerefentry> for details. + ''; + }; }; - }; routeOptions = { - - routeConfig = mkOption { - default = {}; - example = { Gateway = "192.168.0.1"; }; - type = types.addCheck (types.attrsOf unitOption) checkRoute; - description = '' - Each attribute in this set specifies an option in the - <literal>[Route]</literal> section of the unit. See - <citerefentry><refentrytitle>systemd.network</refentrytitle> - <manvolnum>5</manvolnum></citerefentry> for details. - ''; + options = { + routeConfig = mkOption { + default = {}; + example = { Gateway = "192.168.0.1"; }; + type = types.addCheck (types.attrsOf unitOption) checkRoute; + description = '' + Each attribute in this set specifies an option in the + <literal>[Route]</literal> section of the unit. See + <citerefentry><refentrytitle>systemd.network</refentrytitle> + <manvolnum>5</manvolnum></citerefentry> for details. + ''; + }; }; - }; networkOptions = commonNetworkOptions // { @@ -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 [ { options = linkOptions; } ]); description = "Definition of systemd network links."; }; systemd.network.netdevs = mkOption { default = {}; - type = types.attrsOf types.optionSet; - options = [ netdevOptions ]; + type = with types; attrsOf (submodule [ { options = 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 [ { options = 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); }; - }; + })); }; }; @@ -672,7 +667,6 @@ in systemd.services.systemd-networkd = { wantedBy = [ "multi-user.target" ]; - before = [ "network-interfaces.target" ]; restartTriggers = [ config.environment.etc."systemd/network".source ]; }; 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-lib.nix b/nixos/modules/system/boot/systemd-lib.nix index 2e93693cbfc8..997770b8beca 100644 --- a/nixos/modules/system/boot/systemd-lib.nix +++ b/nixos/modules/system/boot/systemd-lib.nix @@ -182,7 +182,7 @@ rec { mkdir -p $out/getty.target.wants/ ln -s ../autovt@tty1.service $out/getty.target.wants/ - ln -s ../local-fs.target ../remote-fs.target ../network.target \ + ln -s ../local-fs.target ../remote-fs.target \ ../nss-lookup.target ../nss-user-lookup.target ../swap.target \ $out/multi-user.target.wants/ ''} diff --git a/nixos/modules/system/boot/systemd.nix b/nixos/modules/system/boot/systemd.nix index b2a80a7e395a..d44c2e234b0f 100644 --- a/nixos/modules/system/boot/systemd.nix +++ b/nixos/modules/system/boot/systemd.nix @@ -393,13 +393,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 { @@ -410,43 +410,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 @@ -456,8 +450,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 @@ -604,33 +597,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."; }; @@ -819,6 +809,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-scripted.nix b/nixos/modules/tasks/network-interfaces-scripted.nix index d1b62e0fd4e4..6a8f20bab5b6 100644 --- a/nixos/modules/tasks/network-interfaces-scripted.nix +++ b/nixos/modules/tasks/network-interfaces-scripted.nix @@ -54,16 +54,22 @@ in networkSetup = { description = "Networking Setup"; - after = [ "network-interfaces.target" "network-pre.target" ]; - before = [ "network.target" ]; - wantedBy = [ "network.target" ]; + after = [ "network-pre.target" "systemd-udevd.service" "systemd-sysctl.service" ]; + before = [ "network.target" "shutdown.target" ]; + wants = [ "network.target" ]; + conflicts = [ "shutdown.target" ]; + wantedBy = [ "multi-user.target" ]; unitConfig.ConditionCapability = "CAP_NET_ADMIN"; path = [ pkgs.iproute ]; - serviceConfig.Type = "oneshot"; - serviceConfig.RemainAfterExit = true; + serviceConfig = { + Type = "oneshot"; + RemainAfterExit = true; + }; + + unitConfig.DefaultDependencies = false; script = '' @@ -108,8 +114,12 @@ in in nameValuePair "network-addresses-${i.name}" { description = "Address configuration of ${i.name}"; - wantedBy = [ "network-interfaces.target" ]; - before = [ "network-interfaces.target" ]; + wantedBy = [ "network-setup.service" ]; + # propagate stop and reload from network-setup + partOf = [ "network-setup.service" ]; + # order before network-setup because the routes that are configured + # there may need ip addresses configured + before = [ "network-setup.service" ]; bindsTo = [ (subsystemDevice i.name) ]; after = [ (subsystemDevice i.name) "network-pre.target" ]; serviceConfig.Type = "oneshot"; @@ -129,20 +139,11 @@ in echo "checking ip ${address}..." if out=$(ip addr add "${address}" dev "${i.name}" 2>&1); then echo "added ip ${address}..." - restart_network_setup=true elif ! echo "$out" | grep "File exists" >/dev/null 2>&1; then echo "failed to add ${address}" exit 1 fi - '') - + optionalString (ips != [ ]) - '' - if [ "$restart_network_setup" = "true" ]; then - # Ensure that the default gateway remains set. - # (Flushing this interface may have removed it.) - ${config.systemd.package}/bin/systemctl try-restart --no-block network-setup.service - fi - ''; + ''); preStop = flip concatMapStrings (ips) (ip: let address = "${ip.address}/${toString ip.prefixLength}"; @@ -156,10 +157,11 @@ in createTunDevice = i: nameValuePair "${i.name}-netdev" { description = "Virtual Network Interface ${i.name}"; - requires = [ "dev-net-tun.device" ]; + bindsTo = [ "dev-net-tun.device" ]; after = [ "dev-net-tun.device" "network-pre.target" ]; - wantedBy = [ "network.target" (subsystemDevice i.name) ]; - before = [ "network-interfaces.target" (subsystemDevice i.name) ]; + wantedBy = [ "network-setup.service" (subsystemDevice i.name) ]; + partOf = [ "network-setup.service" ]; + before = [ "network-setup.service" (subsystemDevice i.name) ]; path = [ pkgs.iproute ]; serviceConfig = { Type = "oneshot"; @@ -180,12 +182,12 @@ in deps = map subsystemDevice v.interfaces; in { description = "Bridge Interface ${n}"; - wantedBy = [ "network.target" (subsystemDevice n) ]; + wantedBy = [ "network-setup.service" (subsystemDevice n) ]; bindsTo = deps ++ optional v.rstp "mstpd.service"; - partOf = optional v.rstp "mstpd.service"; + partOf = [ "network-setup.service" ] ++ optional v.rstp "mstpd.service"; after = [ "network-pre.target" "mstpd.service" ] ++ deps ++ concatMap (i: [ "network-addresses-${i}.service" "network-link-${i}.service" ]) v.interfaces; - before = [ "network-interfaces.target" (subsystemDevice n) ]; + before = [ "network-setup.service" (subsystemDevice n) ]; serviceConfig.Type = "oneshot"; serviceConfig.RemainAfterExit = true; path = [ pkgs.iproute ]; @@ -222,11 +224,11 @@ in ofRules = pkgs.writeText "vswitch-${n}-openFlowRules" v.openFlowRules; in { description = "Open vSwitch Interface ${n}"; - wantedBy = [ "network.target" "vswitchd.service" ] ++ deps; + wantedBy = [ "network-setup.service" "vswitchd.service" ] ++ deps; bindsTo = [ "vswitchd.service" (subsystemDevice n) ] ++ deps; - partOf = [ "vswitchd.service" ]; + partOf = [ "network-setup.service" "vswitchd.service" ]; after = [ "network-pre.target" "vswitchd.service" ] ++ deps; - before = [ "network-interfaces.target" ]; + before = [ "network-setup.service" ]; serviceConfig.Type = "oneshot"; serviceConfig.RemainAfterExit = true; path = [ pkgs.iproute config.virtualisation.vswitch.package ]; @@ -254,11 +256,12 @@ in deps = map subsystemDevice v.interfaces; in { description = "Bond Interface ${n}"; - wantedBy = [ "network.target" (subsystemDevice n) ]; + wantedBy = [ "network-setup.service" (subsystemDevice n) ]; bindsTo = deps; + partOf = [ "network-setup.service" ]; after = [ "network-pre.target" ] ++ deps ++ concatMap (i: [ "network-addresses-${i}.service" "network-link-${i}.service" ]) v.interfaces; - before = [ "network-interfaces.target" (subsystemDevice n) ]; + before = [ "network-setup.service" (subsystemDevice n) ]; serviceConfig.Type = "oneshot"; serviceConfig.RemainAfterExit = true; path = [ pkgs.iproute pkgs.gawk ]; @@ -291,10 +294,11 @@ in deps = [ (subsystemDevice v.interface) ]; in { description = "Vlan Interface ${n}"; - wantedBy = [ "network.target" (subsystemDevice n) ]; + wantedBy = [ "network-setup.service" (subsystemDevice n) ]; bindsTo = deps; + partOf = [ "network-setup.service" ]; after = [ "network-pre.target" ] ++ deps; - before = [ "network-interfaces.target" (subsystemDevice n) ]; + before = [ "network-setup.service" (subsystemDevice n) ]; serviceConfig.Type = "oneshot"; serviceConfig.RemainAfterExit = true; path = [ pkgs.iproute ]; @@ -315,10 +319,11 @@ in deps = optional (v.dev != null) (subsystemDevice v.dev); in { description = "6-to-4 Tunnel Interface ${n}"; - wantedBy = [ "network.target" (subsystemDevice n) ]; + wantedBy = [ "network-setup.service" (subsystemDevice n) ]; bindsTo = deps; + partOf = [ "network-setup.service" ]; after = [ "network-pre.target" ] ++ deps; - before = [ "network-interfaces.target" (subsystemDevice n) ]; + before = [ "network-setup.service" (subsystemDevice n) ]; serviceConfig.Type = "oneshot"; serviceConfig.RemainAfterExit = true; path = [ pkgs.iproute ]; @@ -342,10 +347,11 @@ in deps = [ (subsystemDevice v.interface) ]; in { description = "Vlan Interface ${n}"; - wantedBy = [ "network.target" (subsystemDevice n) ]; + wantedBy = [ "network-setup.service" (subsystemDevice n) ]; bindsTo = deps; + partOf = [ "network-setup.service" ]; after = [ "network-pre.target" ] ++ deps; - before = [ "network-interfaces.target" (subsystemDevice n) ]; + before = [ "network-setup.service" (subsystemDevice n) ]; serviceConfig.Type = "oneshot"; serviceConfig.RemainAfterExit = true; path = [ pkgs.iproute ]; diff --git a/nixos/modules/tasks/network-interfaces.nix b/nixos/modules/tasks/network-interfaces.nix index 9042418b7234..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. ''; @@ -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 { @@ -932,8 +946,10 @@ in ] ++ bridgeStp; + # The network-interfaces target is kept for backwards compatibility. + # New modules must NOT use it. systemd.targets."network-interfaces" = - { description = "All Network Interfaces"; + { description = "All Network Interfaces (deprecated)"; wantedBy = [ "network.target" ]; before = [ "network.target" ]; after = [ "network-pre.target" ]; 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-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 eaa4d828afb6..5e1cfcdfc6fb 100644 --- a/nixos/modules/virtualisation/containers.nix +++ b/nixos/modules/virtualisation/containers.nix @@ -129,6 +129,9 @@ 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" ''; @@ -159,7 +162,7 @@ let fi '' else - ''${ipcmd} add ${cfg.attribute} dev $ifaceHost''; + ''${ipcmd} add ${cfg.${attribute}} dev $ifaceHost''; renderExtraVeth = name: cfg: if cfg.hostBridge != null then '' @@ -205,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, ... }: { @@ -235,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}"; @@ -302,6 +361,8 @@ let dummyConfig = { extraVeths = {}; + additionalCapabilities = []; + allowedDevices = []; hostAddress = null; hostAddress6 = null; localAddress = null; @@ -368,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; @@ -392,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 ''; @@ -409,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; }; @@ -422,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 @@ -488,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/ec2-amis.nix b/nixos/modules/virtualisation/ec2-amis.nix index bdf6ed4dcd29..ffd1cbec3ce3 100644 --- a/nixos/modules/virtualisation/ec2-amis.nix +++ b/nixos/modules/virtualisation/ec2-amis.nix @@ -1,4 +1,4 @@ -{ +let self = { "14.04".ap-northeast-1.hvm-ebs = "ami-71c6f470"; "14.04".ap-northeast-1.pv-ebs = "ami-4dcbf84c"; "14.04".ap-northeast-1.pv-s3 = "ami-8fc4f68e"; @@ -134,4 +134,52 @@ "16.03".us-west-2.hvm-s3 = "ami-925c9ff2"; "16.03".us-west-2.pv-ebs = "ami-5e61a23e"; "16.03".us-west-2.pv-s3 = "ami-734c8f13"; -} + + # 16.09.666.3738950 + "16.09".ap-northeast-1.hvm-ebs = "ami-35578954"; + "16.09".ap-northeast-1.hvm-s3 = "ami-d6528cb7"; + "16.09".ap-northeast-1.pv-ebs = "ami-07548a66"; + "16.09".ap-northeast-1.pv-s3 = "ami-f1548a90"; + "16.09".ap-northeast-2.hvm-ebs = "ami-d48753ba"; + "16.09".ap-northeast-2.hvm-s3 = "ami-4c865222"; + "16.09".ap-northeast-2.pv-ebs = "ami-ca8551a4"; + "16.09".ap-northeast-2.pv-s3 = "ami-9c8551f2"; + "16.09".ap-south-1.hvm-ebs = "ami-922450fd"; + "16.09".ap-south-1.hvm-s3 = "ami-6d3a4e02"; + "16.09".ap-south-1.pv-ebs = "ami-4d394d22"; + "16.09".ap-south-1.pv-s3 = "ami-17384c78"; + "16.09".ap-southeast-1.hvm-ebs = "ami-f824809b"; + "16.09".ap-southeast-1.hvm-s3 = "ami-f924809a"; + "16.09".ap-southeast-1.pv-ebs = "ami-af2480cc"; + "16.09".ap-southeast-1.pv-s3 = "ami-5826823b"; + "16.09".ap-southeast-2.hvm-ebs = "ami-40fecd23"; + "16.09".ap-southeast-2.hvm-s3 = "ami-48fecd2b"; + "16.09".ap-southeast-2.pv-ebs = "ami-dffecdbc"; + "16.09".ap-southeast-2.pv-s3 = "ami-e0fccf83"; + "16.09".eu-central-1.hvm-ebs = "ami-1d8b7472"; + "16.09".eu-central-1.hvm-s3 = "ami-1c8b7473"; + "16.09".eu-central-1.pv-ebs = "ami-8c8d72e3"; + "16.09".eu-central-1.pv-s3 = "ami-3488775b"; + "16.09".eu-west-1.hvm-ebs = "ami-15662766"; + "16.09".eu-west-1.hvm-s3 = "ami-476b2a34"; + "16.09".eu-west-1.pv-ebs = "ami-876928f4"; + "16.09".eu-west-1.pv-s3 = "ami-70682903"; + "16.09".sa-east-1.hvm-ebs = "ami-27bc2e4b"; + "16.09".sa-east-1.hvm-s3 = "ami-e4b92b88"; + "16.09".sa-east-1.pv-ebs = "ami-4dbe2c21"; + "16.09".sa-east-1.pv-s3 = "ami-77fc6e1b"; + "16.09".us-east-1.hvm-ebs = "ami-93347684"; + "16.09".us-east-1.hvm-s3 = "ami-5e347649"; + "16.09".us-east-1.pv-ebs = "ami-b0387aa7"; + "16.09".us-east-1.pv-s3 = "ami-51357746"; + "16.09".us-west-1.hvm-ebs = "ami-06337a66"; + "16.09".us-west-1.hvm-s3 = "ami-76307916"; + "16.09".us-west-1.pv-ebs = "ami-fd327b9d"; + "16.09".us-west-1.pv-s3 = "ami-cc347dac"; + "16.09".us-west-2.hvm-ebs = "ami-49fe2729"; + "16.09".us-west-2.hvm-s3 = "ami-93fc25f3"; + "16.09".us-west-2.pv-ebs = "ami-14fe2774"; + "16.09".us-west-2.pv-s3 = "ami-74f12814"; + + latest = self."16.09"; +}; in self 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 |