diff options
Diffstat (limited to 'nixos/modules')
44 files changed, 1200 insertions, 320 deletions
diff --git a/nixos/modules/config/power-management.nix b/nixos/modules/config/power-management.nix index a4a4d6e1a6af..4c37e8a6208c 100644 --- a/nixos/modules/config/power-management.nix +++ b/nixos/modules/config/power-management.nix @@ -69,9 +69,6 @@ in config = mkIf cfg.enable { - # Leftover for old setups, should be set by nixos-generate-config now - powerManagement.cpuFreqGovernor = mkDefault "ondemand"; - systemd.targets.post-resume = { description = "Post-Resume Actions"; requires = [ "post-resume.service" ]; diff --git a/nixos/modules/config/shells-environment.nix b/nixos/modules/config/shells-environment.nix index 65f2e5d7af99..398660967c52 100644 --- a/nixos/modules/config/shells-environment.nix +++ b/nixos/modules/config/shells-environment.nix @@ -36,7 +36,7 @@ in default = {}; description = '' A set of environment variables used in the global environment. - These variables will be set on shell initialisation. + These variables will be set on shell initialisation (e.g. in /etc/profile). The value of each variable can be either a string or a list of strings. The latter is concatenated, interspersed with colon characters. diff --git a/nixos/modules/installer/cd-dvd/sd-image-aarch64.nix b/nixos/modules/installer/cd-dvd/sd-image-aarch64.nix index efb9ba39bcd4..3306846b7fa7 100644 --- a/nixos/modules/installer/cd-dvd/sd-image-aarch64.nix +++ b/nixos/modules/installer/cd-dvd/sd-image-aarch64.nix @@ -27,6 +27,7 @@ in boot.loader.grub.enable = false; boot.loader.generic-extlinux-compatible.enable = true; + boot.consoleLogLevel = lib.mkDefault 7; boot.kernelPackages = pkgs.linuxPackages_latest; # The serial ports listed here are: @@ -42,8 +43,17 @@ in populateBootCommands = let configTxt = pkgs.writeText "config.txt" '' kernel=u-boot-rpi3.bin + + # Boot in 64-bit mode. arm_control=0x200 + + # U-Boot used to need this to work, regardless of whether UART is actually used or not. + # TODO: check when/if this can be removed. enable_uart=1 + + # Prevent the firmware from smashing the framebuffer setup done by the mainline kernel + # when attempting to show low-voltage or overtemperature warnings. + avoid_warnings=1 ''; in '' (cd ${pkgs.raspberrypifw}/share/raspberrypi/boot && cp bootcode.bin fixup*.dat start*.elf $NIX_BUILD_TOP/boot/) diff --git a/nixos/modules/installer/cd-dvd/sd-image-armv7l-multiplatform.nix b/nixos/modules/installer/cd-dvd/sd-image-armv7l-multiplatform.nix index 880a6bf2e1e8..f23275bc16d5 100644 --- a/nixos/modules/installer/cd-dvd/sd-image-armv7l-multiplatform.nix +++ b/nixos/modules/installer/cd-dvd/sd-image-armv7l-multiplatform.nix @@ -27,6 +27,7 @@ in boot.loader.grub.enable = false; boot.loader.generic-extlinux-compatible.enable = true; + boot.consoleLogLevel = lib.mkDefault 7; boot.kernelPackages = pkgs.linuxPackages_latest; # The serial ports listed here are: # - ttyS0: for Tegra (Jetson TK1) diff --git a/nixos/modules/installer/cd-dvd/sd-image-raspberrypi.nix b/nixos/modules/installer/cd-dvd/sd-image-raspberrypi.nix index eb676eae05e8..2833b75b84d8 100644 --- a/nixos/modules/installer/cd-dvd/sd-image-raspberrypi.nix +++ b/nixos/modules/installer/cd-dvd/sd-image-raspberrypi.nix @@ -27,6 +27,7 @@ in boot.loader.grub.enable = false; boot.loader.generic-extlinux-compatible.enable = true; + boot.consoleLogLevel = lib.mkDefault 7; boot.kernelPackages = pkgs.linuxPackages_rpi; # FIXME: this probably should be in installation-device.nix diff --git a/nixos/modules/misc/ids.nix b/nixos/modules/misc/ids.nix index c6440dd906fd..28ed10a5ece6 100644 --- a/nixos/modules/misc/ids.nix +++ b/nixos/modules/misc/ids.nix @@ -301,6 +301,8 @@ pykms = 282; kodi = 283; restya-board = 284; + mighttpd2 = 285; + hass = 286; # When adding a uid, make sure it doesn't match an existing gid. And don't use uids above 399! @@ -570,6 +572,8 @@ pykms = 282; kodi = 283; restya-board = 284; + mighttpd2 = 285; + hass = 286; # When adding a gid, make sure it doesn't match an existing # uid. Users and groups with the same name should have equal diff --git a/nixos/modules/misc/nixpkgs.nix b/nixos/modules/misc/nixpkgs.nix index 1793c1447d60..c3e7ab9a666a 100644 --- a/nixos/modules/misc/nixpkgs.nix +++ b/nixos/modules/misc/nixpkgs.nix @@ -4,10 +4,10 @@ with lib; let isConfig = x: - builtins.isAttrs x || builtins.isFunction x; + builtins.isAttrs x || lib.isFunction x; optCall = f: x: - if builtins.isFunction f + if lib.isFunction f then f x else f; @@ -38,7 +38,7 @@ let overlayType = mkOptionType { name = "nixpkgs-overlay"; description = "nixpkgs overlay"; - check = builtins.isFunction; + check = lib.isFunction; merge = lib.mergeOneOption; }; @@ -69,7 +69,6 @@ in [ (self: super: { openssh = super.openssh.override { hpnSupport = true; - withKerberos = true; kerberos = self.libkrb5; }; }; diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index 8d329b5b4b25..2ec8b28c3fc4 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -84,6 +84,7 @@ ./programs/info.nix ./programs/java.nix ./programs/kbdlight.nix + ./programs/less.nix ./programs/light.nix ./programs/man.nix ./programs/mosh.nix @@ -200,6 +201,7 @@ ./services/desktops/dleyna-server.nix ./services/desktops/geoclue2.nix ./services/desktops/gnome3/at-spi2-core.nix + ./services/desktops/gnome3/chrome-gnome-shell.nix ./services/desktops/gnome3/evolution-data-server.nix ./services/desktops/gnome3/gnome-disks.nix ./services/desktops/gnome3/gnome-documents.nix @@ -225,7 +227,6 @@ ./services/games/terraria.nix ./services/hardware/acpid.nix ./services/hardware/actkbd.nix - ./services/hardware/amd-hybrid-graphics.nix ./services/hardware/bluetooth.nix ./services/hardware/brltty.nix ./services/hardware/freefall.nix @@ -314,6 +315,7 @@ ./services/misc/gogs.nix ./services/misc/gollum.nix ./services/misc/gpsd.nix + ./services/misc/home-assistant.nix ./services/misc/ihaskell.nix ./services/misc/irkerd.nix ./services/misc/jackett.nix @@ -424,6 +426,7 @@ ./services/network-filesystems/yandex-disk.nix ./services/network-filesystems/xtreemfs.nix ./services/networking/amuled.nix + ./services/networking/aria2.nix ./services/networking/asterisk.nix ./services/networking/atftpd.nix ./services/networking/avahi-daemon.nix @@ -540,6 +543,7 @@ ./services/networking/ssh/lshd.nix ./services/networking/ssh/sshd.nix ./services/networking/strongswan.nix + ./services/networking/stunnel.nix ./services/networking/supplicant.nix ./services/networking/supybot.nix ./services/networking/syncthing.nix @@ -634,6 +638,7 @@ ./services/web-servers/lighttpd/default.nix ./services/web-servers/lighttpd/gitweb.nix ./services/web-servers/lighttpd/inginious.nix + ./services/web-servers/mighttpd2.nix ./services/web-servers/minio.nix ./services/web-servers/nginx/default.nix ./services/web-servers/phpfpm/default.nix diff --git a/nixos/modules/profiles/clone-config.nix b/nixos/modules/profiles/clone-config.nix index 77d86f8d7405..5b4e68beb6a6 100644 --- a/nixos/modules/profiles/clone-config.nix +++ b/nixos/modules/profiles/clone-config.nix @@ -17,7 +17,7 @@ let # you should use files). moduleFiles = # FIXME: use typeOf (Nix 1.6.1). - filter (x: !isAttrs x && !builtins.isFunction x) modules; + filter (x: !isAttrs x && !lib.isFunction x) modules; # Partition module files because between NixOS and non-NixOS files. NixOS # files may change if the repository is updated. diff --git a/nixos/modules/programs/less.nix b/nixos/modules/programs/less.nix new file mode 100644 index 000000000000..c0283c9e6862 --- /dev/null +++ b/nixos/modules/programs/less.nix @@ -0,0 +1,118 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + + cfg = config.programs.less; + + configFile = '' + #command + ${concatStringsSep "\n" + (mapAttrsToList (command: action: "${command} ${action}") cfg.commands) + } + ${if cfg.clearDefaultCommands then "#stop" else ""} + + #line-edit + ${concatStringsSep "\n" + (mapAttrsToList (command: action: "${command} ${action}") cfg.lineEditingKeys) + } + + #env + ${concatStringsSep "\n" + (mapAttrsToList (variable: values: "${variable}=${values}") cfg.envVariables) + } + ''; + + lessKey = pkgs.runCommand "lesskey" + { src = pkgs.writeText "lessconfig" configFile; } + "${pkgs.less}/bin/lesskey -o $out $src"; + +in + +{ + options = { + + programs.less = { + + enable = mkEnableOption "less"; + + commands = mkOption { + type = types.attrsOf types.str; + default = {}; + example = { + "h" = "noaction 5\e("; + "l" = "noaction 5\e)"; + }; + description = "Defines new command keys."; + }; + + clearDefaultCommands = mkOption { + type = types.bool; + default = false; + description = '' + Clear all default commands. + You should remember to set the quit key. + Otherwise you will not be able to leave less without killing it. + ''; + }; + + lineEditingKeys = mkOption { + type = types.attrsOf types.str; + default = {}; + example = { + "\e" = "abort"; + }; + description = "Defines new line-editing keys."; + }; + + envVariables = mkOption { + type = types.attrsOf types.str; + default = {}; + example = { + LESS = "--quit-if-one-screen"; + }; + description = "Defines environment variables."; + }; + + lessopen = mkOption { + type = types.nullOr types.str; + default = "|${pkgs.lesspipe}/bin/lesspipe.sh %s"; + description = '' + Before less opens a file, it first gives your input preprocessor a chance to modify the way the contents of the file are displayed. + ''; + }; + + lessclose = mkOption { + type = types.nullOr types.str; + default = null; + description = '' + When less closes a file opened in such a way, it will call another program, called the input postprocessor, which may perform any desired clean-up action (such as deleting the replacement file created by LESSOPEN). + ''; + }; + }; + }; + + config = mkIf cfg.enable { + + environment.systemPackages = [ pkgs.less ]; + + environment.variables = { + "LESSKEY_SYSTEM" = toString lessKey; + } // optionalAttrs (cfg.lessopen != null) { + "LESSOPEN" = cfg.lessopen; + } // optionalAttrs (cfg.lessclose != null) { + "LESSCLOSE" = cfg.lessclose; + }; + + warnings = optional ( + cfg.clearDefaultCommands && (all (x: x != "quit") (attrValues cfg.commands)) + ) '' + config.programs.less.clearDefaultCommands clears all default commands of less but there is no alternative binding for exiting. + Consider adding a binding for 'quit'. + ''; + }; + + meta.maintainers = with maintainers; [ johnazoidberg ]; + +} diff --git a/nixos/modules/programs/zsh/oh-my-zsh.nix b/nixos/modules/programs/zsh/oh-my-zsh.nix index 9077643c4440..b995d390b279 100644 --- a/nixos/modules/programs/zsh/oh-my-zsh.nix +++ b/nixos/modules/programs/zsh/oh-my-zsh.nix @@ -48,6 +48,15 @@ in Name of the theme to be used by oh-my-zsh. ''; }; + + cacheDir = mkOption { + default = "$HOME/.cache/oh-my-zsh"; + type = types.str; + description = '' + Cache directory to be used by `oh-my-zsh`. + Without this option it would default to the read-only nix store. + ''; + }; }; }; @@ -74,6 +83,13 @@ in "ZSH_THEME=\"${cfg.theme}\"" } + ${optionalString (cfg.cacheDir != null) '' + if [[ ! -d "${cfg.cacheDir}" ]]; then + mkdir -p "${cfg.cacheDir}" + fi + ZSH_CACHE_DIR=${cfg.cacheDir} + ''} + source $ZSH/oh-my-zsh.sh ''; }; diff --git a/nixos/modules/programs/zsh/zsh.nix b/nixos/modules/programs/zsh/zsh.nix index 6fb1346bbb33..5102bfef0325 100644 --- a/nixos/modules/programs/zsh/zsh.nix +++ b/nixos/modules/programs/zsh/zsh.nix @@ -36,8 +36,9 @@ in shellAliases = mkOption { default = config.environment.shellAliases; description = '' - Set of aliases for zsh shell. See <option>environment.shellAliases</option> - for an option format description. + Set of aliases for zsh shell. Overrides the default value taken from + <option>environment.shellAliases</option>. + See <option>environment.shellAliases</option> for an option format description. ''; type = types.attrs; # types.attrsOf types.stringOrPath; }; diff --git a/nixos/modules/security/sudo.nix b/nixos/modules/security/sudo.nix index cfd0595e63b7..a57f14bb5ae1 100644 --- a/nixos/modules/security/sudo.nix +++ b/nixos/modules/security/sudo.nix @@ -8,6 +8,22 @@ let inherit (pkgs) sudo; + toUserString = user: if (isInt user) then "#${toString user}" else "${user}"; + toGroupString = group: if (isInt group) then "%#${toString group}" else "%${group}"; + + toCommandOptionsString = options: + "${concatStringsSep ":" options}${optionalString (length options != 0) ":"} "; + + toCommandsString = commands: + concatStringsSep ", " ( + map (command: + if (isString command) then + command + else + "${toCommandOptionsString command.options}${command.command}" + ) commands + ); + in { @@ -47,6 +63,97 @@ in ''; }; + security.sudo.extraRules = mkOption { + description = '' + Define specific rules to be in the <filename>sudoers</filename> file. + ''; + default = []; + example = [ + # Allow execution of any command by all users in group sudo, + # requiring a password. + { groups = [ "sudo" ]; commands = [ "ALL" ]; } + + # Allow execution of "/home/root/secret.sh" by user `backup`, `database` + # and the group with GID `1006` without a password. + { users = [ "backup" ]; groups = [ 1006 ]; + commands = [ { command = "/home/root/secret.sh"; options = [ "SETENV" "NOPASSWD" ]; } ]; } + + # Allow all users of group `bar` to run two executables as user `foo` + # with arguments being pre-set. + { groups = [ "bar" ]; runAs = "foo"; + commands = + [ "/home/baz/cmd1.sh hello-sudo" + { command = ''/home/baz/cmd2.sh ""''; options = [ "SETENV" ]; } ]; } + ]; + type = with types; listOf (submodule { + options = { + users = mkOption { + type = with types; listOf (either string int); + description = '' + The usernames / UIDs this rule should apply for. + ''; + default = []; + }; + + groups = mkOption { + type = with types; listOf (either string int); + description = '' + The groups / GIDs this rule should apply for. + ''; + default = []; + }; + + host = mkOption { + type = types.string; + default = "ALL"; + description = '' + For what host this rule should apply. + ''; + }; + + runAs = mkOption { + type = with types; string; + default = "ALL:ALL"; + description = '' + Under which user/group the specified command is allowed to run. + + A user can be specified using just the username: <code>"foo"</code>. + It is also possible to specify a user/group combination using <code>"foo:bar"</code> + or to only allow running as a specific group with <code>":bar"</code>. + ''; + }; + + commands = mkOption { + description = '' + The commands for which the rule should apply. + ''; + type = with types; listOf (either string (submodule { + + options = { + command = mkOption { + type = with types; string; + description = '' + A command being either just a path to a binary to allow any arguments, + the full command with arguments pre-set or with <code>""</code> used as the argument, + not allowing arguments to the command at all. + ''; + }; + + options = mkOption { + type = with types; listOf (enum [ "NOPASSWD" "PASSWD" "NOEXEC" "EXEC" "SETENV" "NOSETENV" "LOG_INPUT" "NOLOG_INPUT" "LOG_OUTPUT" "NOLOG_OUTPUT" ]); + description = '' + Options for running the command. Refer to the <a href="https://www.sudo.ws/man/1.7.10/sudoers.man.html">sudo manual</a>. + ''; + default = []; + }; + }; + + })); + }; + }; + }); + }; + security.sudo.extraConfig = mkOption { type = types.lines; default = ""; @@ -61,10 +168,16 @@ in config = mkIf cfg.enable { + security.sudo.extraRules = [ + { groups = [ "wheel" ]; + commands = [ { command = "ALL"; options = (if cfg.wheelNeedsPassword then [ "SETENV" ] else [ "NOPASSWD" "SETENV" ]); } ]; + } + ]; + security.sudo.configFile = '' # Don't edit this file. Set the NixOS options ‘security.sudo.configFile’ - # or ‘security.sudo.extraConfig’ instead. + # or ‘security.sudo.extraRules’ instead. # Keep SSH_AUTH_SOCK so that pam_ssh_agent_auth.so can do its magic. Defaults env_keep+=SSH_AUTH_SOCK @@ -72,8 +185,18 @@ in # "root" is allowed to do anything. root ALL=(ALL:ALL) SETENV: ALL - # Users in the "wheel" group can do anything. - %wheel ALL=(ALL:ALL) ${if cfg.wheelNeedsPassword then "" else "NOPASSWD: ALL, "}SETENV: ALL + # extraRules + ${concatStringsSep "\n" ( + lists.flatten ( + map ( + rule: if (length rule.commands != 0) then [ + (map (user: "${toUserString user} ${rule.host}=(${rule.runAs}) ${toCommandsString rule.commands}") rule.users) + (map (group: "${toGroupString group} ${rule.host}=(${rule.runAs}) ${toCommandsString rule.commands}") rule.groups) + ] else [] + ) cfg.extraRules + ) + )} + ${cfg.extraConfig} ''; diff --git a/nixos/modules/services/desktops/gnome3/chrome-gnome-shell.nix b/nixos/modules/services/desktops/gnome3/chrome-gnome-shell.nix new file mode 100644 index 000000000000..2740a22c7ca0 --- /dev/null +++ b/nixos/modules/services/desktops/gnome3/chrome-gnome-shell.nix @@ -0,0 +1,27 @@ +# Chrome GNOME Shell native host connector. +{ config, lib, pkgs, ... }: + +with lib; + +{ + ###### interface + options = { + services.gnome3.chrome-gnome-shell.enable = mkEnableOption '' + Chrome GNOME Shell native host connector, a DBus service + allowing to install GNOME Shell extensions from a web browser. + ''; + }; + + + ###### implementation + config = mkIf config.services.gnome3.chrome-gnome-shell.enable { + environment.etc = { + "chromium/native-messaging-hosts/org.gnome.chrome_gnome_shell.json".source = "${pkgs.chrome-gnome-shell}/etc/chromium/native-messaging-hosts/org.gnome.chrome_gnome_shell.json"; + "opt/chrome/native-messaging-hosts/org.gnome.chrome_gnome_shell.json".source = "${pkgs.chrome-gnome-shell}/etc/opt/chrome/native-messaging-hosts/org.gnome.chrome_gnome_shell.json"; + }; + + environment.systemPackages = [ pkgs.chrome-gnome-shell ]; + + services.dbus.packages = [ pkgs.chrome-gnome-shell ]; + }; +} diff --git a/nixos/modules/services/hardware/amd-hybrid-graphics.nix b/nixos/modules/services/hardware/amd-hybrid-graphics.nix deleted file mode 100644 index b0f9ff56d1b2..000000000000 --- a/nixos/modules/services/hardware/amd-hybrid-graphics.nix +++ /dev/null @@ -1,46 +0,0 @@ -{ config, pkgs, lib, ... }: - -{ - - ###### interface - - options = { - - hardware.amdHybridGraphics.disable = lib.mkOption { - default = false; - type = lib.types.bool; - description = '' - Completely disable the AMD graphics card and use the - integrated graphics processor instead. - ''; - }; - - }; - - - ###### implementation - - config = lib.mkIf config.hardware.amdHybridGraphics.disable { - systemd.services."amd-hybrid-graphics" = { - path = [ pkgs.bash ]; - description = "Disable AMD Card"; - after = [ "sys-kernel-debug.mount" ]; - before = [ "systemd-vconsole-setup.service" "display-manager.service" ]; - requires = [ "sys-kernel-debug.mount" "vgaswitcheroo.path" ]; - serviceConfig = { - Type = "oneshot"; - RemainAfterExit = true; - ExecStart = "${pkgs.bash}/bin/sh -c 'echo -e \"IGD\\nOFF\" > /sys/kernel/debug/vgaswitcheroo/switch'"; - ExecStop = "${pkgs.bash}/bin/sh -c 'echo ON >/sys/kernel/debug/vgaswitcheroo/switch'"; - }; - }; - systemd.paths."vgaswitcheroo" = { - pathConfig = { - PathExists = "/sys/kernel/debug/vgaswitcheroo/switch"; - Unit = "amd-hybrid-graphics.service"; - }; - wantedBy = ["multi-user.target"]; - }; - }; - -} diff --git a/nixos/modules/services/mail/postfix.nix b/nixos/modules/services/mail/postfix.nix index 867c0ea6761c..22af7e876af2 100644 --- a/nixos/modules/services/mail/postfix.nix +++ b/nixos/modules/services/mail/postfix.nix @@ -15,20 +15,18 @@ let haveVirtual = cfg.virtual != ""; clientAccess = - if (cfg.dnsBlacklistOverrides != "") - then [ "check_client_access hash:/etc/postfix/client_access" ] - else []; + optional (cfg.dnsBlacklistOverrides != "") + "check_client_access hash:/etc/postfix/client_access"; dnsBl = - if (cfg.dnsBlacklists != []) - then [ (concatStringsSep ", " (map (s: "reject_rbl_client " + s) cfg.dnsBlacklists)) ] - else []; + optionals (cfg.dnsBlacklists != []) + (map (s: "reject_rbl_client " + s) cfg.dnsBlacklists); clientRestrictions = concatStringsSep ", " (clientAccess ++ dnsBl); mainCf = let escape = replaceStrings ["$"] ["$$"]; - mkList = items: "\n " + concatStringsSep "\n " items; + mkList = items: "\n " + concatStringsSep ",\n " items; mkVal = value: if isList value then mkList value else " " + (if value == true then "yes" @@ -36,72 +34,9 @@ let else toString value); mkEntry = name: value: "${escape name} =${mkVal value}"; in - concatStringsSep "\n" (mapAttrsToList mkEntry (recursiveUpdate defaultConf cfg.config)) + concatStringsSep "\n" (mapAttrsToList mkEntry cfg.config) + "\n" + cfg.extraConfig; - defaultConf = { - compatibility_level = "9999"; - mail_owner = user; - default_privs = "nobody"; - - # NixOS specific locations - data_directory = "/var/lib/postfix/data"; - queue_directory = "/var/lib/postfix/queue"; - - # Default location of everything in package - meta_directory = "${pkgs.postfix}/etc/postfix"; - command_directory = "${pkgs.postfix}/bin"; - sample_directory = "/etc/postfix"; - newaliases_path = "${pkgs.postfix}/bin/newaliases"; - mailq_path = "${pkgs.postfix}/bin/mailq"; - readme_directory = false; - sendmail_path = "${pkgs.postfix}/bin/sendmail"; - daemon_directory = "${pkgs.postfix}/libexec/postfix"; - manpage_directory = "${pkgs.postfix}/share/man"; - html_directory = "${pkgs.postfix}/share/postfix/doc/html"; - shlib_directory = false; - relayhost = if cfg.relayHost == "" then "" else - if cfg.lookupMX - then "${cfg.relayHost}:${toString cfg.relayPort}" - else "[${cfg.relayHost}]:${toString cfg.relayPort}"; - - mail_spool_directory = "/var/spool/mail/"; - setgid_group = setgidGroup; - } - // optionalAttrs config.networking.enableIPv6 { inet_protocols = "all"; } - // optionalAttrs (cfg.networks != null) { mynetworks = cfg.networks; } - // optionalAttrs (cfg.networksStyle != "") { mynetworks_style = cfg.networksStyle; } - // optionalAttrs (cfg.hostname != "") { myhostname = cfg.hostname; } - // optionalAttrs (cfg.domain != "") { mydomain = cfg.domain; } - // optionalAttrs (cfg.origin != "") { myorigin = cfg.origin; } - // optionalAttrs (cfg.destination != null) { mydestination = cfg.destination; } - // optionalAttrs (cfg.relayDomains != null) { relay_domains = cfg.relayDomains; } - // optionalAttrs (cfg.recipientDelimiter != "") { recipient_delimiter = cfg.recipientDelimiter; } - // optionalAttrs haveAliases { alias_maps = "${cfg.aliasMapType}:/etc/postfix/aliases"; } - // optionalAttrs haveTransport { transport_maps = "hash:/etc/postfix/transport"; } - // optionalAttrs haveVirtual { virtual_alias_maps = "${cfg.virtualMapType}:/etc/postfix/virtual"; } - // optionalAttrs (cfg.dnsBlacklists != []) { smtpd_client_restrictions = clientRestrictions; } - // optionalAttrs cfg.useSrs { - sender_canonical_maps = "tcp:127.0.0.1:10001"; - sender_canonical_classes = "envelope_sender"; - recipient_canonical_maps = "tcp:127.0.0.1:10002"; - recipient_canonical_classes= "envelope_recipient"; - } - // optionalAttrs cfg.enableHeaderChecks { header_checks = "regexp:/etc/postfix/header_checks"; } - // optionalAttrs (cfg.sslCert != "") { - smtp_tls_CAfile = cfg.sslCACert; - smtp_tls_cert_file = cfg.sslCert; - smtp_tls_key_file = cfg.sslKey; - - smtp_use_tls = true; - - smtpd_tls_CAfile = cfg.sslCACert; - smtpd_tls_cert_file = cfg.sslCert; - smtpd_tls_key_file = cfg.sslKey; - - smtpd_use_tls = true; - }; - masterCfOptions = { options, config, name, ... }: { options = { name = mkOption { @@ -507,7 +442,6 @@ in config = mkOption { type = with types; attrsOf (either bool (either str (listOf str))); - default = defaultConf; description = '' The main.cf configuration file as key value set. ''; @@ -749,6 +683,67 @@ in ''; }; + services.postfix.config = (mapAttrs (_: v: mkDefault v) { + compatibility_level = "9999"; + mail_owner = cfg.user; + default_privs = "nobody"; + + # NixOS specific locations + data_directory = "/var/lib/postfix/data"; + queue_directory = "/var/lib/postfix/queue"; + + # Default location of everything in package + meta_directory = "${pkgs.postfix}/etc/postfix"; + command_directory = "${pkgs.postfix}/bin"; + sample_directory = "/etc/postfix"; + newaliases_path = "${pkgs.postfix}/bin/newaliases"; + mailq_path = "${pkgs.postfix}/bin/mailq"; + readme_directory = false; + sendmail_path = "${pkgs.postfix}/bin/sendmail"; + daemon_directory = "${pkgs.postfix}/libexec/postfix"; + manpage_directory = "${pkgs.postfix}/share/man"; + html_directory = "${pkgs.postfix}/share/postfix/doc/html"; + shlib_directory = false; + mail_spool_directory = "/var/spool/mail/"; + setgid_group = cfg.setgidGroup; + }) + // optionalAttrs (cfg.relayHost != "") { relayhost = if cfg.lookupMX + then "${cfg.relayHost}:${toString cfg.relayPort}" + else "[${cfg.relayHost}]:${toString cfg.relayPort}"; } + // optionalAttrs config.networking.enableIPv6 { inet_protocols = mkDefault "all"; } + // optionalAttrs (cfg.networks != null) { mynetworks = cfg.networks; } + // optionalAttrs (cfg.networksStyle != "") { mynetworks_style = cfg.networksStyle; } + // optionalAttrs (cfg.hostname != "") { myhostname = cfg.hostname; } + // optionalAttrs (cfg.domain != "") { mydomain = cfg.domain; } + // optionalAttrs (cfg.origin != "") { myorigin = cfg.origin; } + // optionalAttrs (cfg.destination != null) { mydestination = cfg.destination; } + // optionalAttrs (cfg.relayDomains != null) { relay_domains = cfg.relayDomains; } + // optionalAttrs (cfg.recipientDelimiter != "") { recipient_delimiter = cfg.recipientDelimiter; } + // optionalAttrs haveAliases { alias_maps = [ "${cfg.aliasMapType}:/etc/postfix/aliases" ]; } + // optionalAttrs haveTransport { transport_maps = [ "hash:/etc/postfix/transport" ]; } + // optionalAttrs haveVirtual { virtual_alias_maps = [ "${cfg.virtualMapType}:/etc/postfix/virtual" ]; } + // optionalAttrs (cfg.dnsBlacklists != []) { smtpd_client_restrictions = clientRestrictions; } + // optionalAttrs cfg.useSrs { + sender_canonical_maps = [ "tcp:127.0.0.1:10001" ]; + sender_canonical_classes = [ "envelope_sender" ]; + recipient_canonical_maps = [ "tcp:127.0.0.1:10002" ]; + recipient_canonical_classes = [ "envelope_recipient" ]; + } + // optionalAttrs cfg.enableHeaderChecks { header_checks = [ "regexp:/etc/postfix/header_checks" ]; } + // optionalAttrs (cfg.sslCert != "") { + smtp_tls_CAfile = cfg.sslCACert; + smtp_tls_cert_file = cfg.sslCert; + smtp_tls_key_file = cfg.sslKey; + + smtp_use_tls = true; + + smtpd_tls_CAfile = cfg.sslCACert; + smtpd_tls_cert_file = cfg.sslCert; + smtpd_tls_key_file = cfg.sslKey; + + smtpd_use_tls = true; + }; + services.postfix.masterConfig = { smtp_inet = { name = "smtp"; diff --git a/nixos/modules/services/misc/home-assistant.nix b/nixos/modules/services/misc/home-assistant.nix new file mode 100644 index 000000000000..666fa68b01ce --- /dev/null +++ b/nixos/modules/services/misc/home-assistant.nix @@ -0,0 +1,116 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + cfg = config.services.home-assistant; + + configFile = pkgs.writeText "configuration.yaml" (builtins.toJSON cfg.config); + + availableComponents = pkgs.home-assistant.availableComponents; + + # Returns whether component is used in config + useComponent = component: hasAttrByPath (splitString "." component) cfg.config; + + # List of components used in config + extraComponents = filter useComponent availableComponents; + + package = if cfg.autoExtraComponents + then (cfg.package.override { inherit extraComponents; }) + else cfg.package; + +in { + meta.maintainers = with maintainers; [ dotlambda ]; + + options.services.home-assistant = { + enable = mkEnableOption "Home Assistant"; + + configDir = mkOption { + default = "/var/lib/hass"; + type = types.path; + description = "The config directory, where your <filename>configuration.yaml</filename> is located."; + }; + + config = mkOption { + default = null; + type = with types; nullOr attrs; + example = literalExample '' + { + homeassistant = { + name = "Home"; + time_zone = "UTC"; + }; + frontend = { }; + http = { }; + feedreader.urls = [ "https://nixos.org/blogs.xml" ]; + } + ''; + description = '' + Your <filename>configuration.yaml</filename> as a Nix attribute set. + Beware that setting this option will delete your previous <filename>configuration.yaml</filename>. + ''; + }; + + package = mkOption { + default = pkgs.home-assistant; + defaultText = "pkgs.home-assistant"; + type = types.package; + example = literalExample '' + pkgs.home-assistant.override { + extraPackages = ps: with ps; [ colorlog ]; + } + ''; + description = '' + Home Assistant package to use. + Override <literal>extraPackages</literal> in order to add additional dependencies. + ''; + }; + + autoExtraComponents = mkOption { + default = true; + type = types.bool; + description = '' + If set to <literal>true</literal>, the components used in <literal>config</literal> + are set as the specified package's <literal>extraComponents</literal>. + This in turn adds all packaged dependencies to the derivation. + You might still see import errors in your log. + In this case, you will need to package the necessary dependencies yourself + or ask for someone else to package them. + If a dependency is packaged but not automatically added to this list, + you might need to specify it in <literal>extraPackages</literal>. + ''; + }; + }; + + config = mkIf cfg.enable { + systemd.services.home-assistant = { + description = "Home Assistant"; + wantedBy = [ "multi-user.target" ]; + after = [ "network.target" ]; + preStart = lib.optionalString (cfg.config != null) '' + rm -f ${cfg.configDir}/configuration.yaml + ln -s ${configFile} ${cfg.configDir}/configuration.yaml + ''; + serviceConfig = { + ExecStart = '' + ${package}/bin/hass --config "${cfg.configDir}" + ''; + User = "hass"; + Group = "hass"; + Restart = "on-failure"; + ProtectSystem = "strict"; + ReadWritePaths = "${cfg.configDir}"; + PrivateTmp = true; + }; + }; + + users.extraUsers.hass = { + home = cfg.configDir; + createHome = true; + group = "hass"; + uid = config.ids.uids.hass; + }; + + users.extraGroups.hass.gid = config.ids.gids.hass; + }; +} diff --git a/nixos/modules/services/misc/matrix-synapse.nix b/nixos/modules/services/misc/matrix-synapse.nix index 80979547d339..7e880ad09b89 100644 --- a/nixos/modules/services/misc/matrix-synapse.nix +++ b/nixos/modules/services/misc/matrix-synapse.nix @@ -4,6 +4,8 @@ with lib; let cfg = config.services.matrix-synapse; + pg = config.services.postgresql; + usePostgresql = cfg.database_type == "psycopg2"; logConfigFile = pkgs.writeText "log_config.yaml" cfg.logConfig; mkResource = r: ''{names: ${builtins.toJSON r.names}, compress: ${boolToString r.compress}}''; mkListener = l: ''{port: ${toString l.port}, bind_address: "${l.bind_address}", type: ${l.type}, tls: ${boolToString l.tls}, x_forwarded: ${boolToString l.x_forwarded}, resources: [${concatStringsSep "," (map mkResource l.resources)}]}''; @@ -38,7 +40,7 @@ database: { name: "${cfg.database_type}", args: { ${concatStringsSep ",\n " ( - mapAttrsToList (n: v: "\"${n}\": ${v}") cfg.database_args + mapAttrsToList (n: v: "\"${n}\": ${builtins.toJSON v}") cfg.database_args )} } } @@ -155,7 +157,7 @@ in { tls_certificate_path = mkOption { type = types.nullOr types.str; default = null; - example = "/var/lib/matrix-synapse/homeserver.tls.crt"; + example = "${cfg.dataDir}/homeserver.tls.crt"; description = '' PEM encoded X509 certificate for TLS. You can replace the self-signed certificate that synapse @@ -167,7 +169,7 @@ in { tls_private_key_path = mkOption { type = types.nullOr types.str; default = null; - example = "/var/lib/matrix-synapse/homeserver.tls.key"; + example = "${cfg.dataDir}/homeserver.tls.key"; description = '' PEM encoded private key for TLS. Specify null if synapse is not speaking TLS directly. @@ -176,7 +178,7 @@ in { tls_dh_params_path = mkOption { type = types.nullOr types.str; default = null; - example = "/var/lib/matrix-synapse/homeserver.tls.dh"; + example = "${cfg.dataDir}/homeserver.tls.dh"; description = '' PEM dh parameters for ephemeral keys ''; @@ -184,6 +186,7 @@ in { server_name = mkOption { type = types.str; example = "example.com"; + default = config.networking.hostName; description = '' The domain name of the server, with optional explicit port. This is used by remote servers to connect to this server, @@ -339,16 +342,39 @@ in { }; database_type = mkOption { type = types.enum [ "sqlite3" "psycopg2" ]; - default = "sqlite3"; + default = if versionAtLeast config.system.stateVersion "18.03" + then "psycopg2" + else "sqlite3"; description = '' The database engine name. Can be sqlite or psycopg2. ''; }; + create_local_database = mkOption { + type = types.bool; + default = true; + description = '' + Whether to create a local database automatically. + ''; + }; + database_name = mkOption { + type = types.str; + default = "matrix-synapse"; + description = "Database name."; + }; + database_user = mkOption { + type = types.str; + default = "matrix-synapse"; + description = "Database user name."; + }; database_args = mkOption { type = types.attrs; default = { - database = "${cfg.dataDir}/homeserver.db"; - }; + sqlite3 = { database = "${cfg.dataDir}/homeserver.db"; }; + psycopg2 = { + user = cfg.database_user; + database = cfg.database_name; + }; + }."${cfg.database_type}"; description = '' Arguments to pass to the engine. ''; @@ -623,15 +649,36 @@ in { gid = config.ids.gids.matrix-synapse; } ]; + services.postgresql.enable = mkIf usePostgresql (mkDefault true); + systemd.services.matrix-synapse = { description = "Synapse Matrix homeserver"; - after = [ "network.target" ]; + after = [ "network.target" "postgresql.service" ]; wantedBy = [ "multi-user.target" ]; preStart = '' ${cfg.package}/bin/homeserver \ --config-path ${configFile} \ --keys-directory ${cfg.dataDir} \ --generate-keys + '' + optionalString (usePostgresql && cfg.create_local_database) '' + if ! test -e "${cfg.dataDir}/db-created"; then + ${pkgs.sudo}/bin/sudo -u ${pg.superUser} \ + ${pg.package}/bin/createuser \ + --login \ + --no-createdb \ + --no-createrole \ + --encrypted \ + ${cfg.database_user} + ${pkgs.sudo}/bin/sudo -u ${pg.superUser} \ + ${pg.package}/bin/createdb \ + --owner=${cfg.database_user} \ + --encoding=UTF8 \ + --lc-collate=C \ + --lc-ctype=C \ + --template=template0 \ + ${cfg.database_name} + touch "${cfg.dataDir}/db-created" + fi ''; serviceConfig = { Type = "simple"; diff --git a/nixos/modules/services/misc/nix-daemon.nix b/nixos/modules/services/misc/nix-daemon.nix index beca820d2d60..a169b0f2c784 100644 --- a/nixos/modules/services/misc/nix-daemon.nix +++ b/nixos/modules/services/misc/nix-daemon.nix @@ -8,7 +8,7 @@ let nix = cfg.package.out; - isNix112 = versionAtLeast (getVersion nix) "1.12pre"; + isNix20 = versionAtLeast (getVersion nix) "2.0pre"; makeNixBuildUser = nr: { name = "nixbld${toString nr}"; @@ -26,32 +26,40 @@ let nixConf = let - # If we're using sandbox for builds, then provide /bin/sh in - # the sandbox as a bind-mount to bash. This means we also need to - # include the entire closure of bash. + # In Nix < 2.0, If we're using sandbox for builds, then provide + # /bin/sh in the sandbox as a bind-mount to bash. This means we + # also need to include the entire closure of bash. Nix >= 2.0 + # provides a /bin/sh by default. sh = pkgs.stdenv.shell; binshDeps = pkgs.writeReferencesToFile sh; in - pkgs.runCommand "nix.conf" {extraOptions = cfg.extraOptions; } '' - extraPaths=$(for i in $(cat ${binshDeps}); do if test -d $i; then echo $i; fi; done) + pkgs.runCommand "nix.conf" { extraOptions = cfg.extraOptions; inherit binshDeps; } '' + ${optionalString (!isNix20) '' + extraPaths=$(for i in $(cat binshDeps); do if test -d $i; then echo $i; fi; done) + ''} cat > $out <<END # WARNING: this file is generated from the nix.* options in # your NixOS configuration, typically # /etc/nixos/configuration.nix. Do not edit it! build-users-group = nixbld - build-max-jobs = ${toString (cfg.maxJobs)} - build-cores = ${toString (cfg.buildCores)} - build-use-sandbox = ${if (builtins.isBool cfg.useSandbox) then boolToString cfg.useSandbox else cfg.useSandbox} - build-sandbox-paths = ${toString cfg.sandboxPaths} /bin/sh=${sh} $(echo $extraPaths) - binary-caches = ${toString cfg.binaryCaches} - trusted-binary-caches = ${toString cfg.trustedBinaryCaches} - binary-cache-public-keys = ${toString cfg.binaryCachePublicKeys} + ${if isNix20 then "max-jobs" else "build-max-jobs"} = ${toString (cfg.maxJobs)} + ${if isNix20 then "cores" else "build-cores"} = ${toString (cfg.buildCores)} + ${if isNix20 then "sandbox" else "build-use-sandbox"} = ${if (builtins.isBool cfg.useSandbox) then boolToString cfg.useSandbox else cfg.useSandbox} + ${if isNix20 then "extra-sandbox-paths" else "build-sandbox-paths"} = ${toString cfg.sandboxPaths} ${optionalString (!isNix20) "/bin/sh=${sh} $(echo $extraPaths)"} + ${if isNix20 then "substituters" else "binary-caches"} = ${toString cfg.binaryCaches} + ${if isNix20 then "trusted-substituters" else "trusted-binary-caches"} = ${toString cfg.trustedBinaryCaches} + ${if isNix20 then "trusted-public-keys" else "binary-cache-public-keys"} = ${toString cfg.binaryCachePublicKeys} auto-optimise-store = ${boolToString cfg.autoOptimiseStore} - ${optionalString cfg.requireSignedBinaryCaches '' - signed-binary-caches = * + ${if isNix20 then '' + require-sigs = ${if cfg.requireSignedBinaryCaches then "true" else "false"} + '' else '' + signed-binary-caches = ${if cfg.requireSignedBinaryCaches then "*" else ""} ''} trusted-users = ${toString cfg.trustedUsers} allowed-users = ${toString cfg.allowedUsers} + ${optionalString (isNix20 && !cfg.distributedBuilds) '' + builders = + ''} $extraOptions END ''; @@ -377,8 +385,9 @@ in systemd.sockets.nix-daemon.wantedBy = [ "sockets.target" ]; systemd.services.nix-daemon = - { path = [ nix pkgs.openssl.bin pkgs.utillinux config.programs.ssh.package ] - ++ optionals cfg.distributedBuilds [ pkgs.gzip ]; + { path = [ nix pkgs.utillinux ] + ++ optionals cfg.distributedBuilds [ config.programs.ssh.package pkgs.gzip ] + ++ optionals (!isNix20) [ pkgs.openssl.bin ]; environment = cfg.envVars // { CURL_CA_BUNDLE = "/etc/ssl/certs/ca-certificates.crt"; } @@ -396,10 +405,9 @@ in }; nix.envVars = - { NIX_CONF_DIR = "/etc/nix"; - } + optionalAttrs (!isNix20) { + NIX_CONF_DIR = "/etc/nix"; - // optionalAttrs (!isNix112) { # Enable the copy-from-other-stores substituter, which allows # builds to be sped up by copying build results from remote # Nix stores. To do this, mount the remote file system on a @@ -407,12 +415,8 @@ in NIX_OTHER_STORES = "/run/nix/remote-stores/*/nix"; } - // optionalAttrs cfg.distributedBuilds { - NIX_BUILD_HOOK = - if isNix112 then - "${nix}/libexec/nix/build-remote" - else - "${nix}/libexec/nix/build-remote.pl"; + // optionalAttrs (cfg.distributedBuilds && !isNix20) { + NIX_BUILD_HOOK = "${nix}/libexec/nix/build-remote.pl"; }; # Set up the environment variables for running Nix. @@ -420,7 +424,7 @@ in { NIX_PATH = concatStringsSep ":" cfg.nixPath; }; - environment.extraInit = + environment.extraInit = optionalString (!isNix20) '' # Set up secure multi-user builds: non-root users build through the # Nix daemon. diff --git a/nixos/modules/services/monitoring/netdata.nix b/nixos/modules/services/monitoring/netdata.nix index e1fde4fc9500..d23b329eeb25 100644 --- a/nixos/modules/services/monitoring/netdata.nix +++ b/nixos/modules/services/monitoring/netdata.nix @@ -5,18 +5,25 @@ with lib; let cfg = config.services.netdata; - configFile = pkgs.writeText "netdata.conf" cfg.configText; + wrappedPlugins = pkgs.runCommand "wrapped-plugins" {} '' + mkdir -p $out/libexec/netdata/plugins.d + ln -s /run/wrappers/bin/apps.plugin $out/libexec/netdata/plugins.d/apps.plugin + ''; + + localConfig = { + global = { + "plugins directory" = "${wrappedPlugins}/libexec/netdata/plugins.d ${pkgs.netdata}/libexec/netdata/plugins.d"; + }; + }; + mkConfig = generators.toINI {} (recursiveUpdate localConfig cfg.config); + configFile = pkgs.writeText "netdata.conf" (if cfg.configText != null then cfg.configText else mkConfig); defaultUser = "netdata"; in { options = { services.netdata = { - enable = mkOption { - default = false; - type = types.bool; - description = "Whether to enable netdata monitoring."; - }; + enable = mkEnableOption "netdata"; user = mkOption { type = types.str; @@ -31,9 +38,9 @@ in { }; configText = mkOption { - type = types.lines; - default = ""; - description = "netdata.conf configuration."; + type = types.nullOr types.lines; + description = "Verbatim netdata.conf, cannot be combined with config."; + default = null; example = '' [global] debug log = syslog @@ -42,11 +49,29 @@ in { ''; }; + config = mkOption { + type = types.attrsOf types.attrs; + default = {}; + description = "netdata.conf configuration as nix attributes. cannot be combined with configText."; + example = literalExample '' + global = { + "debug log" = "syslog"; + "access log" = "syslog"; + "error log" = "syslog"; + }; + ''; + }; + }; }; - }; config = mkIf cfg.enable { + assertions = + [ { assertion = cfg.config != {} -> cfg.configText == null ; + message = "Cannot specify both config and configText"; + } + ]; systemd.services.netdata = { + path = with pkgs; [ gawk curl ]; description = "Real time performance monitoring"; after = [ "network.target" ]; wantedBy = [ "multi-user.target" ]; @@ -66,6 +91,15 @@ in { }; }; + security.wrappers."apps.plugin" = { + source = "${pkgs.netdata}/libexec/netdata/plugins.d/apps.plugin"; + capabilities = "cap_dac_read_search,cap_sys_ptrace+ep"; + owner = cfg.user; + group = cfg.group; + permissions = "u+rx,g+rx,o-rwx"; + }; + + users.extraUsers = optional (cfg.user == defaultUser) { name = defaultUser; }; diff --git a/nixos/modules/services/network-filesystems/samba.nix b/nixos/modules/services/network-filesystems/samba.nix index 09cd9cb22ca8..b23266e8d43a 100644 --- a/nixos/modules/services/network-filesystems/samba.nix +++ b/nixos/modules/services/network-filesystems/samba.nix @@ -54,10 +54,12 @@ let }; serviceConfig = { - ExecStart = "${samba}/sbin/${appName} ${args}"; + ExecStart = "${samba}/sbin/${appName} --foreground --no-process-group ${args}"; ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID"; LimitNOFILE = 16384; + PIDFile = "/run/${appName}.pid"; Type = "notify"; + NotifyAccess = "all"; #may not do anything... }; restartTriggers = [ configFile ]; @@ -231,11 +233,12 @@ in after = [ "samba-setup.service" "network.target" ]; wantedBy = [ "multi-user.target" ]; }; - + # Refer to https://github.com/samba-team/samba/tree/master/packaging/systemd + # for correct use with systemd services = { - "samba-smbd" = daemonService "smbd" "-F"; - "samba-nmbd" = mkIf cfg.enableNmbd (daemonService "nmbd" "-F"); - "samba-winbindd" = mkIf cfg.enableWinbindd (daemonService "winbindd" "-F"); + "samba-smbd" = daemonService "smbd" ""; + "samba-nmbd" = mkIf cfg.enableNmbd (daemonService "nmbd" ""); + "samba-winbindd" = mkIf cfg.enableWinbindd (daemonService "winbindd" ""); "samba-setup" = { description = "Samba Setup Task"; script = setupScript; diff --git a/nixos/modules/services/networking/aria2.nix b/nixos/modules/services/networking/aria2.nix index ad4ac9bf45e3..df9c92db2e54 100644 --- a/nixos/modules/services/networking/aria2.nix +++ b/nixos/modules/services/networking/aria2.nix @@ -10,9 +10,9 @@ let settingsDir = "${homeDir}"; sessionFile = "${homeDir}/aria2.session"; downloadDir = "${homeDir}/Downloads"; - + rangesToStringList = map (x: builtins.toString x.from +"-"+ builtins.toString x.to); - + settingsFile = pkgs.writeText "aria2.conf" '' dir=${cfg.downloadDir} @@ -110,12 +110,12 @@ in mkdir -m 0770 -p "${homeDir}" chown aria2:aria2 "${homeDir}" if [[ ! -d "${config.services.aria2.downloadDir}" ]] - then + then mkdir -m 0770 -p "${config.services.aria2.downloadDir}" chown aria2:aria2 "${config.services.aria2.downloadDir}" fi if [[ ! -e "${sessionFile}" ]] - then + then touch "${sessionFile}" chown aria2:aria2 "${sessionFile}" fi @@ -132,4 +132,4 @@ in }; }; }; -} \ No newline at end of file +} diff --git a/nixos/modules/services/networking/kresd.nix b/nixos/modules/services/networking/kresd.nix index 011a9b2f58ea..d0c19c4ecb71 100644 --- a/nixos/modules/services/networking/kresd.nix +++ b/nixos/modules/services/networking/kresd.nix @@ -43,7 +43,7 @@ in type = with types; listOf str; default = [ "::1" "127.0.0.1" ]; description = '' - What addresses the server should listen on. + What addresses the server should listen on. (UDP+TCP 53) ''; }; # TODO: perhaps options for more common stuff like cache size or forwarding @@ -99,9 +99,9 @@ in Restart = "on-failure"; }; + # Trust anchor goes from dns-root-data by default. script = '' - exec '${package}/bin/kresd' --config '${configFile}' \ - -k '${pkgs.dns-root-data}/root.key' + exec '${package}/bin/kresd' --config '${configFile}' --forks=1 ''; requires = [ "kresd.socket" ]; diff --git a/nixos/modules/services/networking/openvpn.nix b/nixos/modules/services/networking/openvpn.nix index 3fbf5a9f0227..7a96b673c51e 100644 --- a/nixos/modules/services/networking/openvpn.nix +++ b/nixos/modules/services/networking/openvpn.nix @@ -50,6 +50,11 @@ let "up ${pkgs.writeScript "openvpn-${name}-up" upScript}"} ${optionalString (cfg.down != "" || cfg.updateResolvConf) "down ${pkgs.writeScript "openvpn-${name}-down" downScript}"} + ${optionalString (cfg.authUserPass != null) + "auth-user-pass ${pkgs.writeText "openvpn-credentials-${name}" '' + ${cfg.authUserPass.username} + ${cfg.authUserPass.password} + ''}"} ''; in { @@ -161,6 +166,29 @@ in ''; }; + authUserPass = mkOption { + default = null; + description = '' + This option can be used to store the username / password credentials + with the "auth-user-pass" authentication method. + + WARNING: Using this option will put the credentials WORLD-READABLE in the Nix store! + ''; + type = types.nullOr (types.submodule { + + options = { + username = mkOption { + description = "The username to store inside the credentials file."; + type = types.string; + }; + + password = mkOption { + description = "The password to store inside the credentials file."; + type = types.string; + }; + }; + }); + }; }; }); diff --git a/nixos/modules/services/networking/resilio.nix b/nixos/modules/services/networking/resilio.nix index 6d2b7bdbca1b..d1c4101f80bd 100644 --- a/nixos/modules/services/networking/resilio.nix +++ b/nixos/modules/services/networking/resilio.nix @@ -17,7 +17,7 @@ let search_lan = entry.searchLAN; use_sync_trash = entry.useSyncTrash; - known_hosts = knownHosts; + known_hosts = entry.knownHosts; }) cfg.sharedFolders; configFile = pkgs.writeText "config.json" (builtins.toJSON ({ diff --git a/nixos/modules/services/networking/ssh/sshd.nix b/nixos/modules/services/networking/ssh/sshd.nix index aa9c0fa1c09f..d9b12d278160 100644 --- a/nixos/modules/services/networking/ssh/sshd.nix +++ b/nixos/modules/services/networking/ssh/sshd.nix @@ -21,7 +21,7 @@ let daemon reads in addition to the the user's authorized_keys file. You can combine the <literal>keys</literal> and <literal>keyFiles</literal> options. - Warning: If you are using <literal>NixOps</literal> then don't use this + Warning: If you are using <literal>NixOps</literal> then don't use this option since it will replace the key required for deployment via ssh. ''; }; @@ -137,6 +137,14 @@ in ''; }; + openFirewall = mkOption { + type = types.bool; + default = true; + description = '' + Whether to automatically open the specified ports in the firewall. + ''; + }; + listenAddresses = mkOption { type = with types; listOf (submodule { options = { @@ -302,7 +310,7 @@ in }; - networking.firewall.allowedTCPPorts = cfg.ports; + networking.firewall.allowedTCPPorts = if cfg.openFirewall then cfg.ports else []; security.pam.services.sshd = { startSession = true; diff --git a/nixos/modules/services/networking/stunnel.nix b/nixos/modules/services/networking/stunnel.nix new file mode 100644 index 000000000000..89a14966eca7 --- /dev/null +++ b/nixos/modules/services/networking/stunnel.nix @@ -0,0 +1,221 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + + cfg = config.services.stunnel; + yesNo = val: if val then "yes" else "no"; + + verifyChainPathAssert = n: c: { + assertion = c.verifyHostname == null || (c.verifyChain || c.verifyPeer); + message = "stunnel: \"${n}\" client configuration - hostname verification " + + "is not possible without either verifyChain or verifyPeer enabled"; + }; + + serverConfig = { + options = { + accept = mkOption { + type = types.int; + description = "On which port stunnel should listen for incoming TLS connections."; + }; + + connect = mkOption { + type = types.int; + description = "To which port the decrypted connection should be forwarded."; + }; + + cert = mkOption { + type = types.path; + description = "File containing both the private and public keys."; + }; + }; + }; + + clientConfig = { + options = { + accept = mkOption { + type = types.string; + description = "IP:Port on which connections should be accepted."; + }; + + connect = mkOption { + type = types.string; + description = "IP:Port destination to connect to."; + }; + + verifyChain = mkOption { + type = types.bool; + default = true; + description = "Check if the provided certificate has a valid certificate chain (against CAPath)."; + }; + + verifyPeer = mkOption { + type = types.bool; + default = false; + description = "Check if the provided certificate is contained in CAPath."; + }; + + CAPath = mkOption { + type = types.path; + default = "${pkgs.cacert}/etc/ssl/certs/ca-bundle.crt"; + description = "Path to a file containing certificates to validate against."; + }; + + verifyHostname = mkOption { + type = with types; nullOr string; + default = null; + description = "If set, stunnel checks if the provided certificate is valid for the given hostname."; + }; + }; + }; + + +in + +{ + + ###### interface + + options = { + + services.stunnel = { + + enable = mkOption { + type = types.bool; + default = false; + description = "Whether to enable the stunnel TLS tunneling service."; + }; + + user = mkOption { + type = with types; nullOr string; + default = "nobody"; + description = "The user under which stunnel runs."; + }; + + group = mkOption { + type = with types; nullOr string; + default = "nogroup"; + description = "The group under which stunnel runs."; + }; + + logLevel = mkOption { + type = types.enum [ "emerg" "alert" "crit" "err" "warning" "notice" "info" "debug" ]; + default = "info"; + description = "Verbosity of stunnel output."; + }; + + fipsMode = mkOption { + type = types.bool; + default = false; + description = "Enable FIPS 140-2 mode required for compliance."; + }; + + enableInsecureSSLv3 = mkOption { + type = types.bool; + default = false; + description = "Enable support for the insecure SSLv3 protocol."; + }; + + + servers = mkOption { + description = "Define the server configuations."; + type = with types; attrsOf (submodule serverConfig); + example = { + fancyWebserver = { + enable = true; + accept = 443; + connect = 8080; + cert = "/path/to/pem/file"; + }; + }; + default = { }; + }; + + clients = mkOption { + description = "Define the client configurations."; + type = with types; attrsOf (submodule clientConfig); + example = { + foobar = { + accept = "0.0.0.0:8080"; + connect = "nixos.org:443"; + verifyChain = false; + }; + }; + default = { }; + }; + }; + }; + + + ###### implementation + + config = mkIf cfg.enable { + + assertions = concatLists [ + (singleton { + assertion = (length (attrValues cfg.servers) != 0) || ((length (attrValues cfg.clients)) != 0); + message = "stunnel: At least one server- or client-configuration has to be present."; + }) + + (mapAttrsToList verifyChainPathAssert cfg.clients) + ]; + + environment.systemPackages = [ pkgs.stunnel ]; + + environment.etc."stunnel.cfg".text = '' + ${ if cfg.user != null then "setuid = ${cfg.user}" else "" } + ${ if cfg.group != null then "setgid = ${cfg.group}" else "" } + + debug = ${cfg.logLevel} + + ${ optionalString cfg.fipsMode "fips = yes" } + ${ optionalString cfg.enableInsecureSSLv3 "options = -NO_SSLv3" } + + ; ----- SERVER CONFIGURATIONS ----- + ${ lib.concatStringsSep "\n" + (lib.mapAttrsToList + (n: v: '' + [${n}] + accept = ${toString v.accept} + connect = ${toString v.connect} + cert = ${v.cert} + + '') + cfg.servers) + } + + ; ----- CLIENT CONFIGURATIONS ----- + ${ lib.concatStringsSep "\n" + (lib.mapAttrsToList + (n: v: '' + [${n}] + client = yes + accept = ${v.accept} + connect = ${v.connect} + verifyChain = ${yesNo v.verifyChain} + verifyPeer = ${yesNo v.verifyPeer} + ${optionalString (v.CAPath != null) "CApath = ${v.CAPath}"} + ${optionalString (v.verifyHostname != null) "checkHost = ${v.verifyHostname}"} + OCSPaia = yes + + '') + cfg.clients) + } + ''; + + systemd.services.stunnel = { + description = "stunnel TLS tunneling service"; + after = [ "network.target" ]; + wants = [ "network.target" ]; + wantedBy = [ "multi-user.target" ]; + restartTriggers = [ config.environment.etc."stunnel.cfg".source ]; + serviceConfig = { + ExecStart = "${pkgs.stunnel}/bin/stunnel ${config.environment.etc."stunnel.cfg".source}"; + Type = "forking"; + }; + }; + + }; + +} diff --git a/nixos/modules/services/web-servers/mighttpd2.nix b/nixos/modules/services/web-servers/mighttpd2.nix new file mode 100644 index 000000000000..a888f623616e --- /dev/null +++ b/nixos/modules/services/web-servers/mighttpd2.nix @@ -0,0 +1,132 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + cfg = config.services.mighttpd2; + configFile = pkgs.writeText "mighty-config" cfg.config; + routingFile = pkgs.writeText "mighty-routing" cfg.routing; +in { + options.services.mighttpd2 = { + enable = mkEnableOption "Mighttpd2 web server"; + + config = mkOption { + default = ""; + example = '' + # Example configuration for Mighttpd 2 + Port: 80 + # IP address or "*" + Host: * + Debug_Mode: Yes # Yes or No + # If available, "nobody" is much more secure for User:. + User: root + # If available, "nobody" is much more secure for Group:. + Group: root + Pid_File: /var/run/mighty.pid + Logging: Yes # Yes or No + Log_File: /var/log/mighty # The directory must be writable by User: + Log_File_Size: 16777216 # bytes + Log_Backup_Number: 10 + Index_File: index.html + Index_Cgi: index.cgi + Status_File_Dir: /usr/local/share/mighty/status + Connection_Timeout: 30 # seconds + Fd_Cache_Duration: 10 # seconds + # Server_Name: Mighttpd/3.x.y + Tls_Port: 443 + Tls_Cert_File: cert.pem # should change this with an absolute path + # should change this with comma-separated absolute paths + Tls_Chain_Files: chain.pem + # Currently, Tls_Key_File must not be encrypted. + Tls_Key_File: privkey.pem # should change this with an absolute path + Service: 0 # 0 is HTTP only, 1 is HTTPS only, 2 is both + ''; + type = types.lines; + description = '' + Verbatim config file to use + (see http://www.mew.org/~kazu/proj/mighttpd/en/config.html) + ''; + }; + + routing = mkOption { + default = ""; + example = '' + # Example routing for Mighttpd 2 + + # Domain lists + [localhost www.example.com] + + # Entries are looked up in the specified order + # All paths must end with "/" + + # A path to CGI scripts should be specified with "=>" + /~alice/cgi-bin/ => /home/alice/public_html/cgi-bin/ + + # A path to static files should be specified with "->" + /~alice/ -> /home/alice/public_html/ + /cgi-bin/ => /export/cgi-bin/ + + # Reverse proxy rules should be specified with ">>" + # /path >> host:port/path2 + # Either "host" or ":port" can be committed, but not both. + /app/cal/ >> example.net/calendar/ + # Yesod app in the same server + /app/wiki/ >> 127.0.0.1:3000/ + + / -> /export/www/ + ''; + type = types.lines; + description = '' + Verbatim routing file to use + (see http://www.mew.org/~kazu/proj/mighttpd/en/config.html) + ''; + }; + + cores = mkOption { + default = null; + type = types.nullOr types.int; + description = '' + How many cores to use. + If null it will be determined automatically + ''; + }; + + }; + + config = mkIf cfg.enable { + assertions = + [ { assertion = cfg.routing != ""; + message = "You need at least one rule in mighttpd2.routing"; + } + ]; + systemd.services.mighttpd2 = { + description = "Mighttpd2 web server"; + after = [ "network-online.target" ]; + wantedBy = [ "multi-user.target" ]; + serviceConfig = { + ExecStart = '' + ${pkgs.haskellPackages.mighttpd2}/bin/mighty \ + ${configFile} \ + ${routingFile} \ + +RTS -N${optionalString (cfg.cores != null) "${cfg.cores}"} + ''; + Type = "simple"; + User = "mighttpd2"; + Group = "mighttpd2"; + Restart = "on-failure"; + AmbientCapabilities = "cap_net_bind_service"; + CapabilityBoundingSet = "cap_net_bind_service"; + }; + }; + + users.extraUsers.mighttpd2 = { + group = "mighttpd2"; + uid = config.ids.uids.mighttpd2; + isSystemUser = true; + }; + + users.extraGroups.mighttpd2.gid = config.ids.gids.mighttpd2; + }; + + meta.maintainers = with lib.maintainers; [ fgaz ]; +} diff --git a/nixos/modules/services/web-servers/nginx/default.nix b/nixos/modules/services/web-servers/nginx/default.nix index 2951e63e863e..100fabf902f8 100644 --- a/nixos/modules/services/web-servers/nginx/default.nix +++ b/nixos/modules/services/web-servers/nginx/default.nix @@ -15,6 +15,9 @@ let } // (optionalAttrs vhostConfig.enableACME { sslCertificate = "/var/lib/acme/${serverName}/fullchain.pem"; sslCertificateKey = "/var/lib/acme/${serverName}/key.pem"; + }) // (optionalAttrs (vhostConfig.useACMEHost != null) { + sslCertificate = "/var/lib/acme/${vhostConfig.useACMEHost}/fullchain.pem"; + sslCertificateKey = "/var/lib/acme/${vhostConfig.useACMEHost}/key.pem"; }) ) cfg.virtualHosts; enableIPv6 = config.networking.enableIPv6; @@ -174,7 +177,7 @@ let redirectListen = filter (x: !x.ssl) defaultListen; - acmeLocation = '' + acmeLocation = optionalString (vhost.enableACME || vhost.useACMEHost != null) '' location /.well-known/acme-challenge { ${optionalString (vhost.acmeFallbackHost != null) "try_files $uri @acme-fallback;"} root ${vhost.acmeRoot}; @@ -194,7 +197,7 @@ let ${concatMapStringsSep "\n" listenString redirectListen} server_name ${vhost.serverName} ${concatStringsSep " " vhost.serverAliases}; - ${optionalString vhost.enableACME acmeLocation} + ${acmeLocation} location / { return 301 https://$host$request_uri; } @@ -204,7 +207,7 @@ let server { ${concatMapStringsSep "\n" listenString hostListen} server_name ${vhost.serverName} ${concatStringsSep " " vhost.serverAliases}; - ${optionalString vhost.enableACME acmeLocation} + ${acmeLocation} ${optionalString (vhost.root != null) "root ${vhost.root};"} ${optionalString (vhost.globalRedirect != null) '' return 301 http${optionalString hasSSL "s"}://${vhost.globalRedirect}$request_uri; @@ -555,6 +558,14 @@ in are mutually exclusive. ''; } + + { + assertion = all (conf: !(conf.enableACME && conf.useACMEHost != null)) (attrValues virtualHosts); + message = '' + Options services.nginx.service.virtualHosts.<name>.enableACME and + services.nginx.virtualHosts.<name>.useACMEHost are mutually exclusive. + ''; + } ]; systemd.services.nginx = { @@ -580,7 +591,7 @@ in security.acme.certs = filterAttrs (n: v: v != {}) ( let vhostsConfigs = mapAttrsToList (vhostName: vhostConfig: vhostConfig) virtualHosts; - acmeEnabledVhosts = filter (vhostConfig: vhostConfig.enableACME) vhostsConfigs; + acmeEnabledVhosts = filter (vhostConfig: vhostConfig.enableACME && vhostConfig.useACMEHost == null) vhostsConfigs; acmePairs = map (vhostConfig: { name = vhostConfig.serverName; value = { user = cfg.user; group = lib.mkDefault cfg.group; diff --git a/nixos/modules/services/web-servers/nginx/vhost-options.nix b/nixos/modules/services/web-servers/nginx/vhost-options.nix index 29f08cc4f307..bf18108a1a3c 100644 --- a/nixos/modules/services/web-servers/nginx/vhost-options.nix +++ b/nixos/modules/services/web-servers/nginx/vhost-options.nix @@ -48,7 +48,21 @@ with lib; enableACME = mkOption { type = types.bool; default = false; - description = "Whether to ask Let's Encrypt to sign a certificate for this vhost."; + description = '' + Whether to ask Let's Encrypt to sign a certificate for this vhost. + Alternately, you can use an existing certificate through <option>useACMEHost</option>. + ''; + }; + + useACMEHost = mkOption { + type = types.nullOr types.str; + default = null; + description = '' + A host of an existing Let's Encrypt certificate to use. + This is useful if you have many subdomains and want to avoid hitting the + <link xlink:href="https://letsencrypt.org/docs/rate-limits/">rate limit</link>. + Alternately, you can generate a certificate through <option>enableACME</option>. + ''; }; acmeRoot = mkOption { diff --git a/nixos/modules/services/x11/desktop-managers/plasma5.nix b/nixos/modules/services/x11/desktop-managers/plasma5.nix index 17a2cde3a65d..4c76ce0bb195 100644 --- a/nixos/modules/services/x11/desktop-managers/plasma5.nix +++ b/nixos/modules/services/x11/desktop-managers/plasma5.nix @@ -47,6 +47,18 @@ in ${getBin config.hardware.pulseaudio.package}/bin/pactl load-module module-device-manager "do_routing=1" ''} + if [ -f "$HOME/.config/kdeglobals" ] + then + # Remove extraneous font style names. + # See also: https://phabricator.kde.org/D9070 + ${getBin pkgs.gnused}/bin/sed -i "$HOME/.config/kdeglobals" \ + -e '/^fixed=/ s/,Regular$//' \ + -e '/^font=/ s/,Regular$//' \ + -e '/^menuFont=/ s/,Regular$//' \ + -e '/^smallestReadableFont=/ s/,Regular$//' \ + -e '/^toolBarFont=/ s/,Regular$//' + fi + exec "${getBin plasma5.plasma-workspace}/bin/startkde" ''; }; diff --git a/nixos/modules/services/x11/desktop-managers/xfce.nix b/nixos/modules/services/x11/desktop-managers/xfce.nix index 9d5d03638e04..c0c9d7ea47f7 100644 --- a/nixos/modules/services/x11/desktop-managers/xfce.nix +++ b/nixos/modules/services/x11/desktop-managers/xfce.nix @@ -3,9 +3,7 @@ with lib; let - xcfg = config.services.xserver; - pcfg = config.hardware.pulseaudio; - cfg = xcfg.desktopManager.xfce; + cfg = config.services.xserver.desktopManager.xfce; in { @@ -52,82 +50,93 @@ in description = "Application used by XFCE to lock the screen."; }; }; - }; + config = mkIf cfg.enable { + environment.systemPackages = with pkgs.xfce // pkgs; [ + # Get GTK+ themes and gtk-update-icon-cache + gtk2.out + + # Supplies some abstract icons such as: + # utilities-terminal, accessories-text-editor + gnome3.defaultIconTheme + + hicolor_icon_theme + tango-icon-theme + xfce4-icon-theme + + desktop_file_utils + shared_mime_info + + # Needed by Xfce's xinitrc script + # TODO: replace with command -v + which + + exo + garcon + gtk-xfce-engine + gvfs + libxfce4ui + tumbler + xfconf + + mousepad + ristretto + xfce4-appfinder + xfce4-screenshooter + xfce4-session + xfce4-settings + xfce4-terminal + + (thunar.override { thunarPlugins = cfg.thunarPlugins; }) + thunar-volman # TODO: drop + ] ++ (if config.hardware.pulseaudio.enable + then [ xfce4-mixer-pulse xfce4-volumed-pulse ] + else [ xfce4-mixer xfce4-volumed ]) + # TODO: NetworkManager doesn't belong here + ++ optionals config.networking.networkmanager.enable [ networkmanagerapplet ] + ++ optionals config.powerManagement.enable [ xfce4-power-manager ] + ++ optionals cfg.enableXfwm [ xfwm4 ] + ++ optionals (!cfg.noDesktop) [ + xfce4-panel + xfce4-notifyd + xfdesktop + ]; + + environment.pathsToLink = [ + "/share/xfce4" + "/share/themes" + "/share/mime" + "/share/desktop-directories" + "/share/gtksourceview-2.0" + ]; + + environment.variables = { + GDK_PIXBUF_MODULE_FILE = "${pkgs.librsvg.out}/lib/gdk-pixbuf-2.0/2.10.0/loaders.cache"; + GIO_EXTRA_MODULES = [ "${pkgs.xfce.gvfs}/lib/gio/modules" ]; + }; - config = mkIf (xcfg.enable && cfg.enable) { - - services.xserver.desktopManager.session = singleton - { name = "xfce"; - bgSupport = true; - start = - '' - ${cfg.extraSessionCommands} + services.xserver.desktopManager.session = [{ + name = "xfce"; + bgSupport = true; + start = '' + ${cfg.extraSessionCommands} - # Set GTK_PATH so that GTK+ can find the theme engines. - export GTK_PATH="${config.system.path}/lib/gtk-2.0:${config.system.path}/lib/gtk-3.0" + # Set GTK_PATH so that GTK+ can find the theme engines. + export GTK_PATH="${config.system.path}/lib/gtk-2.0:${config.system.path}/lib/gtk-3.0" - # Set GTK_DATA_PREFIX so that GTK+ can find the Xfce themes. - export GTK_DATA_PREFIX=${config.system.path} + # Set GTK_DATA_PREFIX so that GTK+ can find the Xfce themes. + export GTK_DATA_PREFIX=${config.system.path} - ${pkgs.stdenv.shell} ${pkgs.xfce.xinitrc} & - waitPID=$! - ''; - }; + ${pkgs.stdenv.shell} ${pkgs.xfce.xinitrc} & + waitPID=$! + ''; + }]; services.xserver.updateDbusEnvironment = true; - environment.systemPackages = - [ pkgs.gtk2.out # To get GTK+'s themes and gtk-update-icon-cache - pkgs.hicolor_icon_theme - pkgs.tango-icon-theme - pkgs.shared_mime_info - pkgs.which # Needed by the xfce's xinitrc script. - pkgs."${cfg.screenLock}" - pkgs.xfce.exo - pkgs.xfce.gtk_xfce_engine - pkgs.xfce.mousepad - pkgs.xfce.ristretto - pkgs.xfce.terminal - (pkgs.xfce.thunar.override { thunarPlugins = cfg.thunarPlugins; }) - pkgs.xfce.xfce4icontheme - pkgs.xfce.xfce4session - pkgs.xfce.xfce4settings - (if pcfg.enable then pkgs.xfce.xfce4mixer_pulse else pkgs.xfce.xfce4mixer) - (if pcfg.enable then pkgs.xfce.xfce4volumed_pulse else pkgs.xfce.xfce4volumed) - pkgs.xfce.xfce4-screenshooter - pkgs.xfce.xfconf - # This supplies some "abstract" icons such as - # "utilities-terminal" and "accessories-text-editor". - pkgs.gnome3.defaultIconTheme - pkgs.desktop_file_utils - pkgs.xfce.libxfce4ui - pkgs.xfce.garcon - pkgs.xfce.thunar_volman - pkgs.xfce.gvfs - pkgs.xfce.xfce4_appfinder - pkgs.xfce.tumbler # found via dbus - ] - ++ optional cfg.enableXfwm pkgs.xfce.xfwm4 - ++ optional config.powerManagement.enable pkgs.xfce.xfce4_power_manager - ++ optional config.networking.networkmanager.enable pkgs.networkmanagerapplet - ++ optionals (!cfg.noDesktop) - [ pkgs.xfce.xfce4panel - pkgs.xfce.xfdesktop - pkgs.xfce.xfce4notifyd # found via dbus - ]; - - environment.pathsToLink = - [ "/share/xfce4" "/share/themes" "/share/mime" "/share/desktop-directories" "/share/gtksourceview-2.0" ]; - - environment.variables.GIO_EXTRA_MODULES = [ "${pkgs.xfce.gvfs}/lib/gio/modules" ]; - environment.variables.GDK_PIXBUF_MODULE_FILE = "${pkgs.librsvg.out}/lib/gdk-pixbuf-2.0/2.10.0/loaders.cache"; - # Enable helpful DBus services. services.udisks2.enable = true; services.upower.enable = config.powerManagement.enable; - }; - } diff --git a/nixos/modules/services/x11/window-managers/2bwm.nix b/nixos/modules/services/x11/window-managers/2bwm.nix index e3f5ec7dbe67..fdbdf35b0f5a 100644 --- a/nixos/modules/services/x11/window-managers/2bwm.nix +++ b/nixos/modules/services/x11/window-managers/2bwm.nix @@ -25,12 +25,12 @@ in { name = "2bwm"; start = '' - ${pkgs."2bwm"}/bin/2bwm & + ${pkgs._2bwm}/bin/2bwm & waitPID=$! ''; }; - environment.systemPackages = [ pkgs."2bwm" ]; + environment.systemPackages = [ pkgs._2bwm ]; }; diff --git a/nixos/modules/system/boot/initrd-network.nix b/nixos/modules/system/boot/initrd-network.nix index 6e226c190609..4a6e1c7e56e5 100644 --- a/nixos/modules/system/boot/initrd-network.nix +++ b/nixos/modules/system/boot/initrd-network.nix @@ -40,6 +40,10 @@ in kernel documentation</link>. Otherwise, if <option>networking.useDHCP</option> is enabled, an IP address is acquired using DHCP. + + You should add the module(s) required for your network card to + boot.initrd.availableKernelModules. lspci -v -s <ethernet controller> + will tell you which. ''; }; diff --git a/nixos/modules/system/boot/kernel.nix b/nixos/modules/system/boot/kernel.nix index 90074a1ba77b..d21908f84537 100644 --- a/nixos/modules/system/boot/kernel.nix +++ b/nixos/modules/system/boot/kernel.nix @@ -206,12 +206,14 @@ in "xhci_hcd" "xhci_pci" "usbhid" - "hid_generic" "hid_lenovo" "hid_apple" "hid_roccat" "hid_logitech_hidpp" + "hid_generic" "hid_lenovo" "hid_apple" "hid_roccat" + "hid_logitech_hidpp" "hid_logitech_dj" - # Misc. keyboard stuff. + ] ++ optionals (pkgs.stdenv.isi686 || pkgs.stdenv.isx86_64) [ + # Misc. x86 keyboard stuff. "pcips2" "atkbd" "i8042" - # Needed by the stage 2 init script. + # x86 RTC needed by the stage 2 init script. "rtc_cmos" ]; diff --git a/nixos/modules/tasks/network-interfaces-scripted.nix b/nixos/modules/tasks/network-interfaces-scripted.nix index 1f424f84c6e0..63d07832d105 100644 --- a/nixos/modules/tasks/network-interfaces-scripted.nix +++ b/nixos/modules/tasks/network-interfaces-scripted.nix @@ -230,9 +230,7 @@ let RemainAfterExit = true; }; script = '' - ip tuntap add dev "${i.name}" \ - ${optionalString (i.virtualType != null) "mode ${i.virtualType}"} \ - user "${i.virtualOwner}" + ip tuntap add dev "${i.name}" mode "${i.virtualType}" user "${i.virtualOwner}" ''; postStop = '' ip link del ${i.name} || true diff --git a/nixos/modules/tasks/network-interfaces-systemd.nix b/nixos/modules/tasks/network-interfaces-systemd.nix index a365a01bfb1e..5d72ad0f1bde 100644 --- a/nixos/modules/tasks/network-interfaces-systemd.nix +++ b/nixos/modules/tasks/network-interfaces-systemd.nix @@ -74,21 +74,17 @@ in networks."99-main" = genericNetwork mkDefault; } (mkMerge (flip map interfaces (i: { - netdevs = mkIf i.virtual ( - let - devType = if i.virtualType != null then i.virtualType - else (if hasPrefix "tun" i.name then "tun" else "tap"); - in { - "40-${i.name}" = { - netdevConfig = { - Name = i.name; - Kind = devType; - }; - "${devType}Config" = optionalAttrs (i.virtualOwner != null) { - User = i.virtualOwner; - }; + netdevs = mkIf i.virtual ({ + "40-${i.name}" = { + netdevConfig = { + Name = i.name; + Kind = i.virtualType; }; - }); + "${i.virtualType}Config" = optionalAttrs (i.virtualOwner != null) { + User = i.virtualOwner; + }; + }; + }); networks."40-${i.name}" = mkMerge [ (genericNetwork mkDefault) { name = mkDefault i.name; DHCP = mkForce (dhcpStr diff --git a/nixos/modules/tasks/network-interfaces.nix b/nixos/modules/tasks/network-interfaces.nix index b7e85e402aa9..f4851988d63d 100644 --- a/nixos/modules/tasks/network-interfaces.nix +++ b/nixos/modules/tasks/network-interfaces.nix @@ -273,11 +273,13 @@ let }; virtualType = mkOption { - default = null; - type = with types; nullOr (enum [ "tun" "tap" ]); + default = if hasPrefix "tun" name then "tun" else "tap"; + defaultText = literalExample ''if hasPrefix "tun" name then "tun" else "tap"''; + type = with types; enum [ "tun" "tap" ]; description = '' - The explicit type of interface to create. Accepts tun or tap strings. - Also accepts null to implicitly detect the type of device. + The type of interface to create. + The default is TUN for an interface name starting + with "tun", otherwise TAP. ''; }; diff --git a/nixos/modules/testing/test-instrumentation.nix b/nixos/modules/testing/test-instrumentation.nix index 9b4136223c0f..41dec2af9ed4 100644 --- a/nixos/modules/testing/test-instrumentation.nix +++ b/nixos/modules/testing/test-instrumentation.nix @@ -4,13 +4,10 @@ { config, lib, pkgs, ... }: with lib; +with import ../../lib/qemu-flags.nix { inherit pkgs; }; let kernel = config.boot.kernelPackages.kernel; - # FIXME: figure out a common place for this instead of copy pasting - serialDevice = if pkgs.stdenv.isi686 || pkgs.stdenv.isx86_64 then "ttyS0" - else if pkgs.stdenv.isArm || pkgs.stdenv.isAarch64 then "ttyAMA0" - else throw "Unknown QEMU serial device for system '${pkgs.stdenv.system}'"; in { @@ -28,8 +25,8 @@ in systemd.services.backdoor = { wantedBy = [ "multi-user.target" ]; - requires = [ "dev-hvc0.device" "dev-${serialDevice}.device" ]; - after = [ "dev-hvc0.device" "dev-${serialDevice}.device" ]; + requires = [ "dev-hvc0.device" "dev-${qemuSerialDevice}.device" ]; + after = [ "dev-hvc0.device" "dev-${qemuSerialDevice}.device" ]; script = '' export USER=root @@ -46,7 +43,7 @@ in cd /tmp exec < /dev/hvc0 > /dev/hvc0 - while ! exec 2> /dev/${serialDevice}; do sleep 0.1; done + while ! exec 2> /dev/${qemuSerialDevice}; do sleep 0.1; done echo "connecting to host..." >&2 stty -F /dev/hvc0 raw -echo # prevent nl -> cr/nl conversion echo @@ -55,10 +52,10 @@ in serviceConfig.KillSignal = "SIGHUP"; }; - # Prevent agetty from being instantiated on ${serialDevice}, since it - # interferes with the backdoor (writes to ${serialDevice} will randomly fail + # Prevent agetty from being instantiated on the serial device, since it + # interferes with the backdoor (writes to it will randomly fail # with EIO). Likewise for hvc0. - systemd.services."serial-getty@${serialDevice}".enable = false; + systemd.services."serial-getty@${qemuSerialDevice}".enable = false; systemd.services."serial-getty@hvc0".enable = false; boot.initrd.preDeviceCommands = @@ -94,7 +91,7 @@ in # Panic if an error occurs in stage 1 (rather than waiting for # user intervention). boot.kernelParams = - [ "console=${serialDevice}" "panic=1" "boot.panic_on_fail" ]; + [ "console=${qemuSerialDevice}" "panic=1" "boot.panic_on_fail" ]; # `xwininfo' is used by the test driver to query open windows. environment.systemPackages = [ pkgs.xorg.xwininfo ]; diff --git a/nixos/modules/virtualisation/container-config.nix b/nixos/modules/virtualisation/container-config.nix index b4f9d8b6fc17..5e368acd6d8b 100644 --- a/nixos/modules/virtualisation/container-config.nix +++ b/nixos/modules/virtualisation/container-config.nix @@ -11,7 +11,7 @@ with lib; services.udisks2.enable = mkDefault false; powerManagement.enable = mkDefault false; - networking.useHostResolvConf = true; + networking.useHostResolvConf = mkDefault true; # Containers should be light-weight, so start sshd on demand. services.openssh.startWhenNeeded = mkDefault true; diff --git a/nixos/modules/virtualisation/google-compute-image.nix b/nixos/modules/virtualisation/google-compute-image.nix index 75717e08ab2a..2fb38059b261 100644 --- a/nixos/modules/virtualisation/google-compute-image.nix +++ b/nixos/modules/virtualisation/google-compute-image.nix @@ -212,7 +212,7 @@ in echo "Obtaining SSH keys..." mkdir -m 0700 -p /root/.ssh AUTH_KEYS=$(${mktemp}) - ${wget} -O $AUTH_KEYS http://metadata.google.internal/computeMetadata/v1/project/attributes/sshKeys + ${wget} -O $AUTH_KEYS --header="Metadata-Flavor: Google" http://metadata.google.internal/computeMetadata/v1/instance/attributes/sshKeys if [ -s $AUTH_KEYS ]; then # Read in key one by one, split in case Google decided diff --git a/nixos/modules/virtualisation/libvirtd.nix b/nixos/modules/virtualisation/libvirtd.nix index 64465ae18522..a369b7ddbe1d 100644 --- a/nixos/modules/virtualisation/libvirtd.nix +++ b/nixos/modules/virtualisation/libvirtd.nix @@ -128,6 +128,7 @@ in { dmidecode dnsmasq ebtables + cfg.qemuPackage # libvirtd requires qemu-img to manage disk images ] ++ optional vswitch.enable vswitch.package; diff --git a/nixos/modules/virtualisation/qemu-vm.nix b/nixos/modules/virtualisation/qemu-vm.nix index 26f7945a4eda..13d0eb7de5c2 100644 --- a/nixos/modules/virtualisation/qemu-vm.nix +++ b/nixos/modules/virtualisation/qemu-vm.nix @@ -10,21 +10,11 @@ { config, lib, pkgs, ... }: with lib; +with import ../../lib/qemu-flags.nix { inherit pkgs; }; let qemu = config.system.build.qemu or pkgs.qemu_test; - qemuKvm = { - "i686-linux" = "${qemu}/bin/qemu-kvm"; - "x86_64-linux" = "${qemu}/bin/qemu-kvm -cpu kvm64"; - "armv7l-linux" = "${qemu}/bin/qemu-system-arm -enable-kvm -machine virt -cpu host"; - "aarch64-linux" = "${qemu}/bin/qemu-system-aarch64 -enable-kvm -machine virt,gic-version=host -cpu host"; - }.${pkgs.stdenv.system}; - - # FIXME: figure out a common place for this instead of copy pasting - serialDevice = if pkgs.stdenv.isi686 || pkgs.stdenv.isx86_64 then "ttyS0" - else if pkgs.stdenv.isArm || pkgs.stdenv.isAarch64 then "ttyAMA0" - else throw "Unknown QEMU serial device for system '${pkgs.stdenv.system}'"; vmName = if config.networking.hostName == "" @@ -34,7 +24,7 @@ let cfg = config.virtualisation; qemuGraphics = if cfg.graphics then "" else "-nographic"; - kernelConsole = if cfg.graphics then "" else "console=${serialDevice}"; + kernelConsole = if cfg.graphics then "" else "console=${qemuSerialDevice}"; ttys = [ "tty1" "tty2" "tty3" "tty4" "tty5" "tty6" ]; # Shell script to start the VM. @@ -83,7 +73,7 @@ let '')} # Start QEMU. - exec ${qemuKvm} \ + exec ${qemuBinary qemu} \ -name ${vmName} \ -m ${toString config.virtualisation.memorySize} \ -smp ${toString config.virtualisation.cores} \ diff --git a/nixos/modules/virtualisation/virtualbox-image.nix b/nixos/modules/virtualisation/virtualbox-image.nix index 00381c426d23..a544403e6bed 100644 --- a/nixos/modules/virtualisation/virtualbox-image.nix +++ b/nixos/modules/virtualisation/virtualbox-image.nix @@ -25,7 +25,7 @@ in { name = "nixos-ova-${config.system.nixosLabel}-${pkgs.stdenv.system}"; inherit pkgs lib config; - partitioned = true; + partitionTableType = "legacy"; diskSize = cfg.baseImageSize; postVM = |