diff options
Diffstat (limited to 'nixos/modules')
65 files changed, 1607 insertions, 558 deletions
diff --git a/nixos/modules/config/debug-info.nix b/nixos/modules/config/debug-info.nix new file mode 100644 index 000000000000..a096a9809cee --- /dev/null +++ b/nixos/modules/config/debug-info.nix @@ -0,0 +1,46 @@ +{ config, lib, ... }: + +with lib; + +{ + + options = { + + environment.enableDebugInfo = mkOption { + type = types.bool; + default = false; + description = '' + Some NixOS packages provide debug symbols. However, these are + not included in the system closure by default to save disk + space. Enabling this option causes the debug symbols to appear + in <filename>/run/current-system/sw/lib/debug/.build-id</filename>, + where tools such as <command>gdb</command> can find them. + If you need debug symbols for a package that doesn't + provide them by default, you can enable them as follows: + <!-- FIXME: ugly, see #10721 --> + <programlisting> + nixpkgs.config.packageOverrides = pkgs: { + hello = overrideDerivation pkgs.hello (attrs: { + outputs = attrs.outputs or ["out"] ++ ["debug"]; + buildInputs = attrs.buildInputs ++ [<nixpkgs/pkgs/build-support/setup-hooks/separate-debug-info.sh>]; + }); + }; + </programlisting> + ''; + }; + + }; + + + config = { + + # FIXME: currently disabled because /lib is already in + # environment.pathsToLink, and we can't have both. + #environment.pathsToLink = [ "/lib/debug/.build-id" ]; + + environment.outputsToLink = + optional config.environment.enableDebugInfo "debug"; + + }; + +} diff --git a/nixos/modules/config/i18n.nix b/nixos/modules/config/i18n.nix index f58e540a6e5c..b20fac6ad3e2 100644 --- a/nixos/modules/config/i18n.nix +++ b/nixos/modules/config/i18n.nix @@ -74,6 +74,23 @@ in ''; }; + consoleColors = mkOption { + type = types.listOf types.str; + default = []; + example = [ + "002b36" "dc322f" "859900" "b58900" + "268bd2" "d33682" "2aa198" "eee8d5" + "002b36" "cb4b16" "586e75" "657b83" + "839496" "6c71c4" "93a1a1" "fdf6e3" + ]; + description = '' + The 16 colors palette used by the virtual consoles. + Leave empty to use the default colors. + Colors must be in hexadecimal format and listed in + order from color 0 to color 15. + ''; + }; + }; }; diff --git a/nixos/modules/config/power-management.nix b/nixos/modules/config/power-management.nix index 32a7987617ad..dedc8a3f6793 100644 --- a/nixos/modules/config/power-management.nix +++ b/nixos/modules/config/power-management.nix @@ -98,6 +98,7 @@ in after = [ "suspend.target" "hibernate.target" "hybrid-sleep.target" ]; script = '' + ${config.systemd.package}/bin/systemctl try-restart post-resume.target ${cfg.resumeCommands} ${cfg.powerUpCommands} ''; diff --git a/nixos/modules/config/swap.nix b/nixos/modules/config/swap.nix index 1dc7ebb96aff..9a5d6a9fc333 100644 --- a/nixos/modules/config/swap.nix +++ b/nixos/modules/config/swap.nix @@ -3,6 +3,84 @@ with utils; with lib; +let + + swapCfg = {config, options, ...}: { + + options = { + + device = mkOption { + example = "/dev/sda3"; + type = types.str; + description = "Path of the device."; + }; + + label = mkOption { + example = "swap"; + type = types.str; + description = '' + Label of the device. Can be used instead of <varname>device</varname>. + ''; + }; + + size = mkOption { + default = null; + example = 2048; + type = types.nullOr types.int; + description = '' + If this option is set, ‘device’ is interpreted as the + path of a swapfile that will be created automatically + with the indicated size (in megabytes) if it doesn't + exist. + ''; + }; + + priority = mkOption { + default = null; + example = 2048; + type = types.nullOr types.int; + description = '' + Specify the priority of the swap device. Priority is a value between 0 and 32767. + Higher numbers indicate higher priority. + null lets the kernel choose a priority, which will show up as a negative value. + ''; + }; + + randomEncryption = mkOption { + default = false; + type = types.bool; + description = '' + Encrypt swap device with a random key. This way you won't have a persistent swap device. + + WARNING: Don't try to hibernate when you have at least one swap partition with + this option enabled! We have no way to set the partition into which hibernation image + is saved, so if your image ends up on an encrypted one you would lose it! + ''; + }; + + deviceName = mkOption { + type = types.str; + internal = true; + }; + + realDevice = mkOption { + type = types.path; + internal = true; + }; + + }; + + config = rec { + device = mkIf options.label.isDefined + "/dev/disk/by-label/${config.label}"; + deviceName = escapeSystemdPath config.device; + realDevice = if config.randomEncryption then "/dev/mapper/${deviceName}" else config.device; + }; + + }; + +in + { ###### interface @@ -26,58 +104,7 @@ with lib; recommended. ''; - type = types.listOf types.optionSet; - - options = {config, options, ...}: { - - options = { - - device = mkOption { - example = "/dev/sda3"; - type = types.str; - description = "Path of the device."; - }; - - label = mkOption { - example = "swap"; - type = types.str; - description = '' - Label of the device. Can be used instead of <varname>device</varname>. - ''; - }; - - size = mkOption { - default = null; - example = 2048; - type = types.nullOr types.int; - description = '' - If this option is set, ‘device’ is interpreted as the - path of a swapfile that will be created automatically - with the indicated size (in megabytes) if it doesn't - exist. - ''; - }; - - priority = mkOption { - default = null; - example = 2048; - type = types.nullOr types.int; - description = '' - Specify the priority of the swap device. Priority is a value between 0 and 32767. - Higher numbers indicate higher priority. - null lets the kernel choose a priority, which will show up as a negative value. - ''; - }; - - }; - - config = { - device = mkIf options.label.isDefined - "/dev/disk/by-label/${config.label}"; - }; - - }; - + type = types.listOf (types.submodule swapCfg); }; }; @@ -95,27 +122,37 @@ with lib; createSwapDevice = sw: assert sw.device != ""; - let device' = escapeSystemdPath sw.device; in - nameValuePair "mkswap-${escapeSystemdPath sw.device}" - { description = "Initialisation of Swapfile ${sw.device}"; - wantedBy = [ "${device'}.swap" ]; - before = [ "${device'}.swap" ]; - path = [ pkgs.utillinux ]; + let realDevice' = escapeSystemdPath sw.realDevice; + in nameValuePair "mkswap-${sw.deviceName}" + { description = "Initialisation of swap device ${sw.device}"; + wantedBy = [ "${realDevice'}.swap" ]; + before = [ "${realDevice'}.swap" ]; + path = [ pkgs.utillinux ] ++ optional sw.randomEncryption pkgs.cryptsetup; script = '' - if [ ! -e "${sw.device}" ]; then - fallocate -l ${toString sw.size}M "${sw.device}" || - dd if=/dev/zero of="${sw.device}" bs=1M count=${toString sw.size} - chmod 0600 ${sw.device} - mkswap ${sw.device} - fi + ${optionalString (sw.size != null) '' + if [ ! -e "${sw.device}" ]; then + fallocate -l ${toString sw.size}M "${sw.device}" || + dd if=/dev/zero of="${sw.device}" bs=1M count=${toString sw.size} + chmod 0600 ${sw.device} + ${optionalString (!sw.randomEncryption) "mkswap ${sw.realDevice}"} + fi + ''} + ${optionalString sw.randomEncryption '' + echo "secretkey" | cryptsetup luksFormat --batch-mode ${sw.device} + echo "secretkey" | cryptsetup luksOpen ${sw.device} ${sw.deviceName} + cryptsetup luksErase --batch-mode ${sw.device} + mkswap ${sw.realDevice} + ''} ''; unitConfig.RequiresMountsFor = [ "${dirOf sw.device}" ]; unitConfig.DefaultDependencies = false; # needed to prevent a cycle serviceConfig.Type = "oneshot"; + serviceConfig.RemainAfterExit = sw.randomEncryption; + serviceConfig.ExecStop = optionalString sw.randomEncryption "cryptsetup luksClose ${sw.deviceName}"; }; - in listToAttrs (map createSwapDevice (filter (sw: sw.size != null) config.swapDevices)); + in listToAttrs (map createSwapDevice (filter (sw: sw.size != null || sw.randomEncryption) config.swapDevices)); }; diff --git a/nixos/modules/config/system-path.nix b/nixos/modules/config/system-path.nix index 26f4ba5fd706..da558a25d99b 100644 --- a/nixos/modules/config/system-path.nix +++ b/nixos/modules/config/system-path.nix @@ -7,12 +7,6 @@ with lib; let - extraManpages = pkgs.runCommand "extra-manpages" { buildInputs = [ pkgs.help2man ]; } - '' - mkdir -p $out/share/man/man1 - help2man ${pkgs.gnutar}/bin/tar > $out/share/man/man1/tar.1 - ''; - requiredPackages = [ config.nix.package pkgs.acl @@ -34,7 +28,6 @@ let pkgs.xz pkgs.less pkgs.libcap - pkgs.man pkgs.nano pkgs.ncurses pkgs.netcat @@ -47,7 +40,6 @@ let pkgs.time pkgs.texinfoInteractive pkgs.utillinux - extraManpages ]; in @@ -78,8 +70,16 @@ in # to work. default = []; example = ["/"]; - description = "List of directories to be symlinked in `/run/current-system/sw'."; + description = "List of directories to be symlinked in <filename>/run/current-system/sw</filename>."; + }; + + outputsToLink = mkOption { + type = types.listOf types.str; + default = []; + example = [ "doc" ]; + description = "List of package outputs to be symlinked into <filename>/run/current-system/sw</filename>."; }; + }; system = { @@ -103,9 +103,7 @@ in [ "/bin" "/etc/xdg" "/info" - "/lib" # FIXME: remove - #"/lib/debug/.build-id" # enables GDB to find separated debug info - "/man" + "/lib" # FIXME: remove and update debug-info.nix "/sbin" "/share/applications" "/share/desktop-directories" @@ -113,7 +111,6 @@ in "/share/emacs" "/share/icons" "/share/info" - "/share/man" "/share/menus" "/share/mime" "/share/nano" @@ -126,7 +123,8 @@ in system.path = pkgs.buildEnv { name = "system-path"; paths = let - #outputs TODO: make it user-customizable? + inherit (config.environment) pathsToLink outputsToLink; + #outputs TODO: some code already merged by Eelco? make it user-customizable? pkgOutputFun = pkg: lib.filter (p: p!=null) [ (pkg.bin or (pkg.out or pkg)) (pkg.man or null) @@ -134,7 +132,6 @@ in (pkg.doc or null) ]; in lib.concatMap pkgOutputFun config.environment.systemPackages; - inherit (config.environment) pathsToLink; ignoreCollisions = true; # !!! Hacky, should modularise. postBuild = diff --git a/nixos/modules/config/users-groups.nix b/nixos/modules/config/users-groups.nix index adc014eed415..485926fb1dd0 100644 --- a/nixos/modules/config/users-groups.nix +++ b/nixos/modules/config/users-groups.nix @@ -550,4 +550,8 @@ in { }; + imports = + [ (mkAliasOptionModule [ "users" "extraUsers" ] [ "users" "users" ]) + (mkAliasOptionModule [ "users" "extraGroups" ] [ "users" "groups" ]) + ]; } 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 0ca57a4635f4..15e22fb50d48 100644 --- a/nixos/modules/installer/cd-dvd/sd-image-armv7l-multiplatform.nix +++ b/nixos/modules/installer/cd-dvd/sd-image-armv7l-multiplatform.nix @@ -22,13 +22,9 @@ in boot.loader.grub.enable = false; boot.loader.generic-extlinux-compatible.enable = true; - # FIXME: change this to linuxPackages_latest once v4.2 is out - boot.kernelPackages = pkgs.linuxPackages_testing; + boot.kernelPackages = pkgs.linuxPackages_latest; boot.kernelParams = ["console=ttyS0,115200n8" "console=ttyAMA0,115200n8" "console=tty0"]; - # FIXME: fix manual evaluation on ARM - services.nixosManual.enable = lib.mkOverride 0 false; - # FIXME: this probably should be in installation-device.nix users.extraUsers.root.initialHashedPassword = ""; diff --git a/nixos/modules/installer/cd-dvd/sd-image-raspberrypi.nix b/nixos/modules/installer/cd-dvd/sd-image-raspberrypi.nix index 199a252ad2b5..e7163f10a3c3 100644 --- a/nixos/modules/installer/cd-dvd/sd-image-raspberrypi.nix +++ b/nixos/modules/installer/cd-dvd/sd-image-raspberrypi.nix @@ -27,9 +27,6 @@ in boot.kernelPackages = pkgs.linuxPackages_rpi; - # FIXME: fix manual evaluation on ARM - services.nixosManual.enable = lib.mkOverride 0 false; - # FIXME: this probably should be in installation-device.nix users.extraUsers.root.initialHashedPassword = ""; diff --git a/nixos/modules/installer/tools/auto-upgrade.nix b/nixos/modules/installer/tools/auto-upgrade.nix index dd8663a12db8..1fa9282b909e 100644 --- a/nixos/modules/installer/tools/auto-upgrade.nix +++ b/nixos/modules/installer/tools/auto-upgrade.nix @@ -70,7 +70,7 @@ let cfg = config.system.autoUpgrade; in path = [ pkgs.gnutar pkgs.xz.bin config.nix.package ]; script = '' - ${config.system.build.nixos-rebuild}/bin/nixos-rebuild test ${toString cfg.flags} + ${config.system.build.nixos-rebuild}/bin/nixos-rebuild switch ${toString cfg.flags} ''; startAt = mkIf cfg.enable "04:40"; diff --git a/nixos/modules/installer/tools/nixos-generate-config.pl b/nixos/modules/installer/tools/nixos-generate-config.pl index 39ef4c51ba10..c590c4cde3f0 100644 --- a/nixos/modules/installer/tools/nixos-generate-config.pl +++ b/nixos/modules/installer/tools/nixos-generate-config.pl @@ -152,6 +152,22 @@ sub pciCheck { push @kernelModules, "wl"; } + # broadcom FullMac driver + # list taken from + # https://wireless.wiki.kernel.org/en/users/Drivers/brcm80211#brcmfmac + if ($vendor eq "0x14e4" && + ($device eq "0x43a3" || $device eq "0x43df" || $device eq "0x43ec" || + $device eq "0x43d3" || $device eq "0x43d9" || $device eq "0x43e9" || + $device eq "0x43ba" || $device eq "0x43bb" || $device eq "0x43bc" || + $device eq "0xaa52" || $device eq "0x43ca" || $device eq "0x43cb" || + $device eq "0x43cc" || $device eq "0x43c3" || $device eq "0x43c4" || + $device eq "0x43c5" + ) ) + { + # we need e.g. brcmfmac43602-pcie.bin + push @imports, "<nixos/modules/hardware/network/broadcom-43xx.nix>"; + } + # Can't rely on $module here, since the module may not be loaded # due to missing firmware. Ideally we would check modules.pcimap # here. @@ -217,8 +233,8 @@ foreach my $path (glob "/sys/bus/usb/devices/*") { } -# Add the modules for all block devices. -foreach my $path (glob "/sys/class/block/*") { +# Add the modules for all block and MMC devices. +foreach my $path (glob "/sys/class/{block,mmc_host}/*") { my $module; if (-e "$path/device/driver/module") { $module = basename `readlink -f $path/device/driver/module`; diff --git a/nixos/modules/installer/tools/nixos-rebuild.sh b/nixos/modules/installer/tools/nixos-rebuild.sh index af19004cbddb..6792690b4c3b 100644 --- a/nixos/modules/installer/tools/nixos-rebuild.sh +++ b/nixos/modules/installer/tools/nixos-rebuild.sh @@ -235,7 +235,7 @@ fi # default and/or activate it now. if [ "$action" = switch -o "$action" = boot -o "$action" = test -o "$action" = dry-activate ]; then if ! $pathToConfig/bin/switch-to-configuration "$action"; then - echo "warning: error(s) occured while switching to the new configuration" >&2 + echo "warning: error(s) occurred while switching to the new configuration" >&2 exit 1 fi fi diff --git a/nixos/modules/misc/ids.nix b/nixos/modules/misc/ids.nix index 0d2700a126f6..de9a318fdd24 100644 --- a/nixos/modules/misc/ids.nix +++ b/nixos/modules/misc/ids.nix @@ -234,6 +234,7 @@ #lxd = 210; # unused kibana = 211; xtreemfs = 212; + calibre-server = 213; # When adding a uid, make sure it doesn't match an existing gid. And don't use uids above 399! @@ -446,6 +447,7 @@ lxd = 210; # unused #kibana = 211; xtreemfs = 212; + calibre-server = 213; # 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 c890eac49910..034ea933a7db 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -1,7 +1,8 @@ [ + ./config/debug-info.nix ./config/fonts/corefonts.nix - ./config/fonts/fontconfig.nix ./config/fonts/fontconfig-ultimate.nix + ./config/fonts/fontconfig.nix ./config/fonts/fontdir.nix ./config/fonts/fonts.nix ./config/fonts/ghostscript.nix @@ -22,9 +23,9 @@ ./config/system-environment.nix ./config/system-path.nix ./config/timezone.nix - ./config/vpnc.nix ./config/unix-odbc-drivers.nix ./config/users-groups.nix + ./config/vpnc.nix ./config/zram.nix ./hardware/all-firmware.nix ./hardware/cpu/amd-microcode.nix @@ -61,9 +62,11 @@ ./programs/command-not-found/command-not-found.nix ./programs/dconf.nix ./programs/environment.nix + ./programs/freetds.nix ./programs/ibus.nix ./programs/kbdlight.nix ./programs/light.nix + ./programs/man.nix ./programs/nano.nix ./programs/screen.nix ./programs/shadow.nix @@ -73,7 +76,6 @@ ./programs/uim.nix ./programs/venus.nix ./programs/wvdial.nix - ./programs/freetds.nix ./programs/xfs_quota.nix ./programs/zsh/zsh.nix ./rename.nix @@ -116,6 +118,7 @@ ./services/computing/slurm/slurm.nix ./services/continuous-integration/jenkins/default.nix ./services/continuous-integration/jenkins/slave.nix + ./services/continuous-integration/jenkins/job-builder.nix ./services/databases/4store-endpoint.nix ./services/databases/4store.nix ./services/databases/couchdb.nix @@ -185,8 +188,9 @@ ./services/mail/postfix.nix ./services/mail/spamassassin.nix ./services/misc/apache-kafka.nix - #./services/misc/autofs.nix + ./services/misc/autofs.nix ./services/misc/canto-daemon.nix + ./services/misc/calibre-server.nix ./services/misc/cpuminer-cryptonight.nix ./services/misc/cgminer.nix ./services/misc/confd.nix @@ -264,6 +268,7 @@ ./services/networking/atftpd.nix ./services/networking/avahi-daemon.nix ./services/networking/bind.nix + ./services/networking/autossh.nix ./services/networking/bird.nix ./services/networking/bitlbee.nix ./services/networking/btsync.nix @@ -340,6 +345,7 @@ ./services/networking/ssh/lshd.nix ./services/networking/ssh/sshd.nix ./services/networking/strongswan.nix + ./services/networking/supplicant.nix ./services/networking/supybot.nix ./services/networking/syncthing.nix ./services/networking/tcpcrypt.nix @@ -435,6 +441,7 @@ ./system/activation/top-level.nix ./system/boot/coredump.nix ./system/boot/emergency-mode.nix + ./system/boot/initrd-network.nix ./system/boot/kernel.nix ./system/boot/kexec.nix ./system/boot/loader/efi.nix diff --git a/nixos/modules/programs/bash/bash.nix b/nixos/modules/programs/bash/bash.nix index c5c0f9d01215..75efd5e29039 100644 --- a/nixos/modules/programs/bash/bash.nix +++ b/nixos/modules/programs/bash/bash.nix @@ -90,12 +90,14 @@ in promptInit = mkOption { default = '' - # Provide a nice prompt. - PROMPT_COLOR="1;31m" - let $UID && PROMPT_COLOR="1;32m" - PS1="\n\[\033[$PROMPT_COLOR\][\u@\h:\w]\\$\[\033[0m\] " - if test "$TERM" = "xterm"; then - PS1="\[\033]2;\h:\u:\w\007\]$PS1" + if test "$TERM" != "dumb"; then + # Provide a nice prompt. + PROMPT_COLOR="1;31m" + let $UID && PROMPT_COLOR="1;32m" + PS1="\n\[\033[$PROMPT_COLOR\][\u@\h:\w]\\$\[\033[0m\] " + if test "$TERM" = "xterm"; then + PS1="\[\033]2;\h:\u:\w\007\]$PS1" + fi fi ''; description = '' diff --git a/nixos/modules/programs/environment.nix b/nixos/modules/programs/environment.nix index 52f6cc221119..a35b5cc9513e 100644 --- a/nixos/modules/programs/environment.nix +++ b/nixos/modules/programs/environment.nix @@ -38,9 +38,7 @@ in PERL5LIB = [ "/lib/perl5/site_perl" ]; KDEDIRS = [ "" ]; STRIGI_PLUGIN_PATH = [ "/lib/strigi/" ]; - QT_PLUGIN_PATH = [ "/lib/qt4/plugins" "/lib/kde4/plugins" "/lib/qt5/plugins" ]; - QML_IMPORT_PATH = [ "/lib/qt5/imports" ]; - QML2_IMPORT_PATH = [ "/lib/qt5/qml" ]; + QT_PLUGIN_PATH = [ "/lib/qt4/plugins" "/lib/kde4/plugins" ]; QTWEBKIT_PLUGIN_PATH = [ "/lib/mozilla/plugins/" ]; GTK_PATH = [ "/lib/gtk-2.0" "/lib/gtk-3.0" ]; XDG_CONFIG_DIRS = [ "/etc/xdg" ]; diff --git a/nixos/modules/programs/man.nix b/nixos/modules/programs/man.nix new file mode 100644 index 000000000000..b28506538049 --- /dev/null +++ b/nixos/modules/programs/man.nix @@ -0,0 +1,30 @@ +{ config, lib, pkgs, ... }: + +with lib; + +{ + + options = { + + programs.man.enable = mkOption { + type = types.bool; + default = true; + description = '' + Whether to enable manual pages and the <command>man</command> command. + ''; + }; + + }; + + + config = mkIf config.programs.man.enable { + + environment.systemPackages = [ pkgs.man ]; + + environment.pathsToLink = [ "/share/man" ]; + + environment.outputsToLink = [ "man" ]; + + }; + +} diff --git a/nixos/modules/rename.nix b/nixos/modules/rename.nix index 62be7dc6cae2..28ac1c3e888a 100644 --- a/nixos/modules/rename.nix +++ b/nixos/modules/rename.nix @@ -1,170 +1,88 @@ -{ config, lib, options, ... }: +{ lib, ... }: with lib; -let - - alias = from: to: rename { - inherit from to; - name = "Alias"; - use = id; - define = id; - visible = true; - }; - - # warn option was renamed - obsolete = from: to: rename { - inherit from to; - name = "Obsolete name"; - use = x: builtins.trace "Obsolete option `${showOption from}' is used. It was renamed to `${showOption to}'." x; - define = x: builtins.trace "Obsolete option `${showOption from}' is used. It was renamed to `${showOption to}'." x; - }; - - # abort if deprecated option is used - deprecated = from: to: rename { - inherit from to; - name = "Deprecated name"; - use = x: abort "Deprecated option `${showOption from}' is used. It was renamed to `${showOption to}'."; - define = x: abort "Deprecated option `${showOption from}' is used. It was renamed to `${showOption to}'."; - }; - - showOption = concatStringsSep "."; - - zipModules = list: - zipAttrsWith (n: v: - if tail v != [] then - if all (o: isAttrs o && o ? _type) v then mkMerge v - else if n == "_type" then head v - else if n == "warnings" then concatLists v - else if n == "description" || n == "apply" then - abort "Cannot rename an option to multiple options." - else zipModules v - else head v - ) list; - - rename = { from, to, name, use, define, visible ? false }: - let - setTo = setAttrByPath to; - setFrom = setAttrByPath from; - toOf = attrByPath to - (abort "Renaming error: option `${showOption to}' does not exists."); - fromOf = attrByPath from - (abort "Internal error: option `${showOption from}' should be declared."); - in - [ { options = setFrom (mkOption { - description = "${name} of <option>${showOption to}</option>."; - apply = x: use (toOf config); - inherit visible; - }); - - config = setTo (mkAliasAndWrapDefinitions define (fromOf options)); - } - ]; - - obsolete' = option: singleton - { options = setAttrByPath option (mkOption { - default = null; - visible = false; - }); - config.warnings = optional (getAttrFromPath option config != null) - "The option `${showOption option}' defined in your configuration no longer has any effect; please remove it."; - }; - -in zipModules ([] - -++ obsolete [ "environment" "x11Packages" ] [ "environment" "systemPackages" ] -++ obsolete [ "environment" "enableBashCompletion" ] [ "programs" "bash" "enableCompletion" ] -++ obsolete [ "environment" "nix" ] [ "nix" "package" ] -++ obsolete [ "fonts" "enableFontConfig" ] [ "fonts" "fontconfig" "enable" ] -++ obsolete [ "fonts" "extraFonts" ] [ "fonts" "fonts" ] -++ alias [ "users" "extraUsers" ] [ "users" "users" ] -++ alias [ "users" "extraGroups" ] [ "users" "groups" ] - -++ obsolete [ "security" "extraSetuidPrograms" ] [ "security" "setuidPrograms" ] -++ obsolete [ "networking" "enableWLAN" ] [ "networking" "wireless" "enable" ] -++ obsolete [ "networking" "enableRT73Firmware" ] [ "networking" "enableRalinkFirmware" ] - -# FIXME: Remove these eventually. -++ obsolete [ "boot" "systemd" "sockets" ] [ "systemd" "sockets" ] -++ obsolete [ "boot" "systemd" "targets" ] [ "systemd" "targets" ] -++ obsolete [ "boot" "systemd" "services" ] [ "systemd" "services" ] - -# Old Grub-related options. -++ obsolete [ "boot" "copyKernels" ] [ "boot" "loader" "grub" "copyKernels" ] -++ obsolete [ "boot" "extraGrubEntries" ] [ "boot" "loader" "grub" "extraEntries" ] -++ obsolete [ "boot" "extraGrubEntriesBeforeNixos" ] [ "boot" "loader" "grub" "extraEntriesBeforeNixOS" ] -++ obsolete [ "boot" "grubDevice" ] [ "boot" "loader" "grub" "device" ] -++ obsolete [ "boot" "bootMount" ] [ "boot" "loader" "grub" "bootDevice" ] -++ obsolete [ "boot" "grubSplashImage" ] [ "boot" "loader" "grub" "splashImage" ] - -++ obsolete [ "boot" "initrd" "extraKernelModules" ] [ "boot" "initrd" "kernelModules" ] -++ obsolete [ "boot" "extraKernelParams" ] [ "boot" "kernelParams" ] - -# smartd -++ obsolete [ "services" "smartd" "deviceOpts" ] [ "services" "smartd" "defaults" "monitored" ] - -# OpenSSH -++ obsolete [ "services" "sshd" "ports" ] [ "services" "openssh" "ports" ] -++ alias [ "services" "sshd" "enable" ] [ "services" "openssh" "enable" ] -++ obsolete [ "services" "sshd" "allowSFTP" ] [ "services" "openssh" "allowSFTP" ] -++ obsolete [ "services" "sshd" "forwardX11" ] [ "services" "openssh" "forwardX11" ] -++ obsolete [ "services" "sshd" "gatewayPorts" ] [ "services" "openssh" "gatewayPorts" ] -++ obsolete [ "services" "sshd" "permitRootLogin" ] [ "services" "openssh" "permitRootLogin" ] -++ obsolete [ "services" "xserver" "startSSHAgent" ] [ "services" "xserver" "startOpenSSHAgent" ] -++ obsolete [ "services" "xserver" "startOpenSSHAgent" ] [ "programs" "ssh" "startAgent" ] -++ alias [ "services" "openssh" "knownHosts" ] [ "programs" "ssh" "knownHosts" ] - -# VirtualBox -++ obsolete [ "services" "virtualbox" "enable" ] [ "virtualisation" "virtualbox" "guest" "enable" ] -++ obsolete [ "services" "virtualboxGuest" "enable" ] [ "virtualisation" "virtualbox" "guest" "enable" ] -++ obsolete [ "programs" "virtualbox" "enable" ] [ "virtualisation" "virtualbox" "host" "enable" ] -++ obsolete [ "programs" "virtualbox" "addNetworkInterface" ] [ "virtualisation" "virtualbox" "host" "addNetworkInterface" ] -++ obsolete [ "programs" "virtualbox" "enableHardening" ] [ "virtualisation" "virtualbox" "host" "enableHardening" ] -++ obsolete [ "services" "virtualboxHost" "enable" ] [ "virtualisation" "virtualbox" "host" "enable" ] -++ obsolete [ "services" "virtualboxHost" "addNetworkInterface" ] [ "virtualisation" "virtualbox" "host" "addNetworkInterface" ] -++ obsolete [ "services" "virtualboxHost" "enableHardening" ] [ "virtualisation" "virtualbox" "host" "enableHardening" ] - -# Tarsnap -++ obsolete [ "services" "tarsnap" "config" ] [ "services" "tarsnap" "archives" ] - -# proxy -++ obsolete [ "nix" "proxy" ] [ "networking" "proxy" "default" ] - -# KDE -++ deprecated [ "kde" "extraPackages" ] [ "environment" "systemPackages" ] -++ obsolete [ "environment" "kdePackages" ] [ "environment" "systemPackages" ] - -# Multiple efi bootloaders now -++ obsolete [ "boot" "loader" "efi" "efibootmgr" "enable" ] [ "boot" "loader" "efi" "canTouchEfiVariables" ] - -# NixOS environment changes -# !!! this hardcodes bash, could we detect from config which shell is actually used? -++ obsolete [ "environment" "promptInit" ] [ "programs" "bash" "promptInit" ] - -++ obsolete [ "services" "xserver" "driSupport" ] [ "hardware" "opengl" "driSupport" ] -++ obsolete [ "services" "xserver" "driSupport32Bit" ] [ "hardware" "opengl" "driSupport32Bit" ] -++ obsolete [ "services" "xserver" "s3tcSupport" ] [ "hardware" "opengl" "s3tcSupport" ] -++ obsolete [ "hardware" "opengl" "videoDrivers" ] [ "services" "xserver" "videoDrivers" ] - -++ obsolete [ "services" "mysql55" ] [ "services" "mysql" ] - -++ alias [ "environment" "checkConfigurationOptions" ] [ "_module" "check" ] - -# XBMC -++ obsolete [ "services" "xserver" "windowManager" "xbmc" ] [ "services" "xserver" "desktopManager" "kodi" ] -++ obsolete [ "services" "xserver" "desktopManager" "xbmc" ] [ "services" "xserver" "desktopManager" "kodi" ] - -# DNSCrypt-proxy -++ obsolete [ "services" "dnscrypt-proxy" "port" ] [ "services" "dnscrypt-proxy" "localPort" ] - -# Options that are obsolete and have no replacement. -++ obsolete' [ "boot" "loader" "grub" "bootDevice" ] -++ obsolete' [ "boot" "initrd" "luks" "enable" ] -++ obsolete' [ "programs" "bash" "enable" ] -++ obsolete' [ "services" "samba" "defaultShare" ] -++ obsolete' [ "services" "syslog-ng" "serviceName" ] -++ obsolete' [ "services" "syslog-ng" "listenToJournal" ] -++ obsolete' [ "ec2" "metadata" ] -++ obsolete' [ "services" "openvpn" "enable" ] - -) +{ + imports = [ + (mkRenamedOptionModule [ "environment" "x11Packages" ] [ "environment" "systemPackages" ]) + (mkRenamedOptionModule [ "environment" "enableBashCompletion" ] [ "programs" "bash" "enableCompletion" ]) + (mkRenamedOptionModule [ "environment" "nix" ] [ "nix" "package" ]) + (mkRenamedOptionModule [ "fonts" "enableFontConfig" ] [ "fonts" "fontconfig" "enable" ]) + (mkRenamedOptionModule [ "fonts" "extraFonts" ] [ "fonts" "fonts" ]) + + (mkRenamedOptionModule [ "security" "extraSetuidPrograms" ] [ "security" "setuidPrograms" ]) + (mkRenamedOptionModule [ "networking" "enableWLAN" ] [ "networking" "wireless" "enable" ]) + (mkRenamedOptionModule [ "networking" "enableRT73Firmware" ] [ "networking" "enableRalinkFirmware" ]) + + # Old Grub-related options. + (mkRenamedOptionModule [ "boot" "initrd" "extraKernelModules" ] [ "boot" "initrd" "kernelModules" ]) + (mkRenamedOptionModule [ "boot" "extraKernelParams" ] [ "boot" "kernelParams" ]) + + # smartd + (mkRenamedOptionModule [ "services" "smartd" "deviceOpts" ] [ "services" "smartd" "defaults" "monitored" ]) + + # OpenSSH + (mkRenamedOptionModule [ "services" "sshd" "ports" ] [ "services" "openssh" "ports" ]) + (mkAliasOptionModule [ "services" "sshd" "enable" ] [ "services" "openssh" "enable" ]) + (mkRenamedOptionModule [ "services" "sshd" "allowSFTP" ] [ "services" "openssh" "allowSFTP" ]) + (mkRenamedOptionModule [ "services" "sshd" "forwardX11" ] [ "services" "openssh" "forwardX11" ]) + (mkRenamedOptionModule [ "services" "sshd" "gatewayPorts" ] [ "services" "openssh" "gatewayPorts" ]) + (mkRenamedOptionModule [ "services" "sshd" "permitRootLogin" ] [ "services" "openssh" "permitRootLogin" ]) + (mkRenamedOptionModule [ "services" "xserver" "startSSHAgent" ] [ "services" "xserver" "startOpenSSHAgent" ]) + (mkRenamedOptionModule [ "services" "xserver" "startOpenSSHAgent" ] [ "programs" "ssh" "startAgent" ]) + (mkAliasOptionModule [ "services" "openssh" "knownHosts" ] [ "programs" "ssh" "knownHosts" ]) + + # VirtualBox + (mkRenamedOptionModule [ "services" "virtualbox" "enable" ] [ "virtualisation" "virtualbox" "guest" "enable" ]) + (mkRenamedOptionModule [ "services" "virtualboxGuest" "enable" ] [ "virtualisation" "virtualbox" "guest" "enable" ]) + (mkRenamedOptionModule [ "programs" "virtualbox" "enable" ] [ "virtualisation" "virtualbox" "host" "enable" ]) + (mkRenamedOptionModule [ "programs" "virtualbox" "addNetworkInterface" ] [ "virtualisation" "virtualbox" "host" "addNetworkInterface" ]) + (mkRenamedOptionModule [ "programs" "virtualbox" "enableHardening" ] [ "virtualisation" "virtualbox" "host" "enableHardening" ]) + (mkRenamedOptionModule [ "services" "virtualboxHost" "enable" ] [ "virtualisation" "virtualbox" "host" "enable" ]) + (mkRenamedOptionModule [ "services" "virtualboxHost" "addNetworkInterface" ] [ "virtualisation" "virtualbox" "host" "addNetworkInterface" ]) + (mkRenamedOptionModule [ "services" "virtualboxHost" "enableHardening" ] [ "virtualisation" "virtualbox" "host" "enableHardening" ]) + + # Tarsnap + (mkRenamedOptionModule [ "services" "tarsnap" "config" ] [ "services" "tarsnap" "archives" ]) + + # proxy + (mkRenamedOptionModule [ "nix" "proxy" ] [ "networking" "proxy" "default" ]) + + # KDE + (mkRenamedOptionModule [ "kde" "extraPackages" ] [ "environment" "systemPackages" ]) + (mkRenamedOptionModule [ "environment" "kdePackages" ] [ "environment" "systemPackages" ]) + + # Multiple efi bootloaders now + (mkRenamedOptionModule [ "boot" "loader" "efi" "efibootmgr" "enable" ] [ "boot" "loader" "efi" "canTouchEfiVariables" ]) + + # NixOS environment changes + # !!! this hardcodes bash, could we detect from config which shell is actually used? + (mkRenamedOptionModule [ "environment" "promptInit" ] [ "programs" "bash" "promptInit" ]) + + (mkRenamedOptionModule [ "services" "xserver" "driSupport" ] [ "hardware" "opengl" "driSupport" ]) + (mkRenamedOptionModule [ "services" "xserver" "driSupport32Bit" ] [ "hardware" "opengl" "driSupport32Bit" ]) + (mkRenamedOptionModule [ "services" "xserver" "s3tcSupport" ] [ "hardware" "opengl" "s3tcSupport" ]) + (mkRenamedOptionModule [ "hardware" "opengl" "videoDrivers" ] [ "services" "xserver" "videoDrivers" ]) + + (mkRenamedOptionModule [ "services" "mysql55" ] [ "services" "mysql" ]) + + (mkAliasOptionModule [ "environment" "checkConfigurationOptions" ] [ "_module" "check" ]) + + # XBMC + (mkRenamedOptionModule [ "services" "xserver" "windowManager" "xbmc" ] [ "services" "xserver" "desktopManager" "kodi" ]) + (mkRenamedOptionModule [ "services" "xserver" "desktopManager" "xbmc" ] [ "services" "xserver" "desktopManager" "kodi" ]) + + # DNSCrypt-proxy + (mkRenamedOptionModule [ "services" "dnscrypt-proxy" "port" ] [ "services" "dnscrypt-proxy" "localPort" ]) + + # Options that are obsolete and have no replacement. + (mkRemovedOptionModule [ "boot" "initrd" "luks" "enable" ]) + (mkRemovedOptionModule [ "programs" "bash" "enable" ]) + (mkRemovedOptionModule [ "services" "samba" "defaultShare" ]) + (mkRemovedOptionModule [ "services" "syslog-ng" "serviceName" ]) + (mkRemovedOptionModule [ "services" "syslog-ng" "listenToJournal" ]) + (mkRemovedOptionModule [ "ec2" "metadata" ]) + (mkRemovedOptionModule [ "services" "openvpn" "enable" ]) + + ]; +} diff --git a/nixos/modules/services/continuous-integration/jenkins/default.nix b/nixos/modules/services/continuous-integration/jenkins/default.nix index 31e585f211fe..0568b1af7d5c 100644 --- a/nixos/modules/services/continuous-integration/jenkins/default.nix +++ b/nixos/modules/services/continuous-integration/jenkins/default.nix @@ -65,11 +65,15 @@ in { }; environment = mkOption { - default = { NIX_REMOTE = "daemon"; }; + default = { }; type = with types; attrsOf str; description = '' Additional environment variables to be passed to the jenkins process. - The environment will always include JENKINS_HOME. + As a base environment, jenkins receives NIX_PATH, SSL_CERT_FILE and + GIT_SSL_CAINFO from <option>environment.sessionVariables</option>, + NIX_REMOTE is set to "daemon" and JENKINS_HOME is set to + the value of <option>services.jenkins.home</option>. This option has + precedence and can be used to override those mentioned variables. ''; }; @@ -106,12 +110,29 @@ in { after = [ "network.target" ]; wantedBy = [ "multi-user.target" ]; - environment = { - JENKINS_HOME = cfg.home; - } // cfg.environment; + environment = + let + selectedSessionVars = + lib.filterAttrs (n: v: builtins.elem n + [ "NIX_PATH" + "SSL_CERT_FILE" + "GIT_SSL_CAINFO" + ]) + config.environment.sessionVariables; + in + selectedSessionVars // + { JENKINS_HOME = cfg.home; + NIX_REMOTE = "daemon"; + } // + cfg.environment; path = cfg.packages; + # Force .war (re)extraction, or else we might run stale Jenkins. + preStart = '' + rm -rf ${cfg.home}/war + ''; + script = '' ${pkgs.jdk}/bin/java -jar ${pkgs.jenkins} --httpPort=${toString cfg.port} ${concatStringsSep " " cfg.extraOptions} ''; diff --git a/nixos/modules/services/continuous-integration/jenkins/job-builder.nix b/nixos/modules/services/continuous-integration/jenkins/job-builder.nix new file mode 100644 index 000000000000..ec15a6a3d706 --- /dev/null +++ b/nixos/modules/services/continuous-integration/jenkins/job-builder.nix @@ -0,0 +1,155 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + jenkinsCfg = config.services.jenkins; + cfg = config.services.jenkins.jobBuilder; + +in { + options = { + services.jenkins.jobBuilder = { + enable = mkOption { + type = types.bool; + default = false; + description = '' + Whether or not to enable the Jenkins Job Builder (JJB) service. It + allows defining jobs for Jenkins in a declarative manner. + + Jobs managed through the Jenkins WebUI (or by other means) are left + unchanged. + + Note that it really is declarative configuration; if you remove a + previously defined job, the corresponding job directory will be + deleted. + + Please see the Jenkins Job Builder documentation for more info: + <link xlink:href="http://docs.openstack.org/infra/jenkins-job-builder/"> + http://docs.openstack.org/infra/jenkins-job-builder/</link> + ''; + }; + + yamlJobs = mkOption { + default = ""; + type = types.lines; + example = '' + - job: + name: jenkins-job-test-1 + builders: + - shell: echo 'Hello world!' + ''; + description = '' + Job descriptions for Jenkins Job Builder in YAML format. + ''; + }; + + jsonJobs = mkOption { + default = [ ]; + type = types.listOf types.str; + example = literalExample '' + [ + ''' + [ { "job": + { "name": "jenkins-job-test-2", + "builders": [ "shell": "echo 'Hello world!'" ] + } + } + ] + ''' + ] + ''; + description = '' + Job descriptions for Jenkins Job Builder in JSON format. + ''; + }; + + nixJobs = mkOption { + default = [ ]; + type = types.listOf types.attrs; + example = literalExample '' + [ { job = + { name = "jenkins-job-test-3"; + builders = [ + { shell = "echo 'Hello world!'"; } + ]; + }; + } + ]; + ''; + description = '' + Job descriptions for Jenkins Job Builder in Nix format. + + This is a trivial wrapper around jsonJobs, using builtins.toJSON + behind the scene. + ''; + }; + }; + }; + + config = mkIf (jenkinsCfg.enable && cfg.enable) { + systemd.services.jenkins-job-builder = { + description = "Jenkins Job Builder Service"; + # JJB can run either before or after jenkins. We chose after, so we can + # always use curl to notify (running) jenkins to reload its config. + after = [ "jenkins.service" ]; + wantedBy = [ "multi-user.target" ]; + + path = with pkgs; [ jenkins-job-builder curl ]; + + # Q: Why manipulate files directly instead of using "jenkins-jobs upload [...]"? + # A: Because this module is for administering a local jenkins install, + # and using local file copy allows us to not worry about + # authentication. + script = + let + yamlJobsFile = builtins.toFile "jobs.yaml" cfg.yamlJobs; + jsonJobsFiles = + map (x: (builtins.toFile "jobs.json" x)) + (cfg.jsonJobs ++ [(builtins.toJSON cfg.nixJobs)]); + jobBuilderOutputDir = "/run/jenkins-job-builder/output"; + # Stamp file is placed in $JENKINS_HOME/jobs/$JOB_NAME/ to indicate + # ownership. Enables tracking and removal of stale jobs. + ownerStamp = ".config-xml-managed-by-nixos-jenkins-job-builder"; + in + '' + rm -rf ${jobBuilderOutputDir} + cur_decl_jobs=/run/jenkins-job-builder/declarative-jobs + rm -f "$cur_decl_jobs" + + # Create / update jobs + mkdir -p ${jobBuilderOutputDir} + for inputFile in ${yamlJobsFile} ${concatStringsSep " " jsonJobsFiles}; do + HOME="${jenkinsCfg.home}" "${pkgs.jenkins-job-builder}/bin/jenkins-jobs" --ignore-cache test -o "${jobBuilderOutputDir}" "$inputFile" + done + + for file in "${jobBuilderOutputDir}/"*; do + test -f "$file" || continue + jobname="$(basename $file)" + jobdir="${jenkinsCfg.home}/jobs/$jobname" + echo "Creating / updating job \"$jobname\"" + mkdir -p "$jobdir" + touch "$jobdir/${ownerStamp}" + cp "$file" "$jobdir/config.xml" + echo "$jobname" >> "$cur_decl_jobs" + done + + # Remove stale jobs + for file in "${jenkinsCfg.home}"/jobs/*/${ownerStamp}; do + test -f "$file" || continue + jobdir="$(dirname $file)" + jobname="$(basename "$jobdir")" + grep --quiet --line-regexp "$jobname" "$cur_decl_jobs" 2>/dev/null && continue + echo "Deleting stale job \"$jobname\"" + rm -rf "$jobdir" + done + + echo "Asking Jenkins to reload config" + curl --silent -X POST http://localhost:${toString jenkinsCfg.port}/reload + ''; + serviceConfig = { + User = jenkinsCfg.user; + RuntimeDirectory = "jenkins-job-builder"; + }; + }; + }; +} diff --git a/nixos/modules/services/databases/postgresql.nix b/nixos/modules/services/databases/postgresql.nix index bae088c6610e..16e3235eb2c8 100644 --- a/nixos/modules/services/databases/postgresql.nix +++ b/nixos/modules/services/databases/postgresql.nix @@ -119,7 +119,7 @@ in extraPlugins = mkOption { type = types.listOf types.path; default = []; - example = literalExample "pkgs.postgis"; + example = literalExample "[ (pkgs.postgis.override { postgresql = pkgs.postgresql94; }).v_2_1_4 ]"; description = '' When this list contains elements a new store path is created. PostgreSQL and the elments are symlinked into it. Then pg_config, @@ -202,6 +202,8 @@ in # For non-root operation. initdb fi + # See postStart! + touch "${cfg.dataDir}/.first_startup" fi ln -sfn "${configFile}" "${cfg.dataDir}/postgresql.conf" diff --git a/nixos/modules/services/hardware/actkbd.nix b/nixos/modules/services/hardware/actkbd.nix index 82de362c371b..b16a8f50a3d8 100644 --- a/nixos/modules/services/hardware/actkbd.nix +++ b/nixos/modules/services/hardware/actkbd.nix @@ -125,6 +125,9 @@ in }; }; + # For testing + environment.systemPackages = [ pkgs.actkbd ]; + }; } diff --git a/nixos/modules/services/hardware/tlp.nix b/nixos/modules/services/hardware/tlp.nix index f221c82e2eda..23b6edcefd1a 100644 --- a/nixos/modules/services/hardware/tlp.nix +++ b/nixos/modules/services/hardware/tlp.nix @@ -6,9 +6,23 @@ let cfg = config.services.tlp; -tlp = pkgs.tlp.override { kmod = config.system.sbin.modprobe; }; - -confFile = pkgs.writeText "tlp" (builtins.readFile "${tlp}/etc/default/tlp" + cfg.extraConfig); +enableRDW = config.networking.networkmanager.enable; + +tlp = pkgs.tlp.override { + inherit enableRDW; + kmod = config.system.sbin.modprobe; +}; + +# XXX: We can't use writeTextFile + readFile here because it triggers +# TLP build to get the .drv (even on --dry-run). +confFile = pkgs.runCommand "tlp" + { config = cfg.extraConfig; + passAsFile = [ "config" ]; + } + '' + cat ${tlp}/etc/default/tlp > $out + cat $configPath >> $out + ''; in @@ -81,13 +95,15 @@ in environment.etc = [{ source = confFile; target = "default/tlp"; } - ] ++ optional tlp.enableRDW { + ] ++ optional enableRDW { source = "${tlp}/etc/NetworkManager/dispatcher.d/99tlp-rdw-nm"; target = "NetworkManager/dispatcher.d/99tlp-rdw-nm"; }; environment.systemPackages = [ tlp ]; + boot.kernelModules = [ "msr" ]; + }; } diff --git a/nixos/modules/services/mail/postfix.nix b/nixos/modules/services/mail/postfix.nix index e8beba4b3586..3a9e62a02052 100644 --- a/nixos/modules/services/mail/postfix.nix +++ b/nixos/modules/services/mail/postfix.nix @@ -11,6 +11,8 @@ let mainCf = '' + compatibility_level = 2 + queue_directory = /var/postfix/queue command_directory = ${pkgs.postfix}/sbin daemon_directory = ${pkgs.postfix}/libexec/postfix @@ -31,10 +33,7 @@ let mynetworks_style = ${cfg.networksStyle} '' else - # Postfix default is subnet, but let's play safe - '' - mynetworks_style = host - '') + "") + optionalString (cfg.hostname != "") '' myhostname = ${cfg.hostname} '' @@ -89,7 +88,7 @@ let masterCf = '' # ========================================================================== # service type private unpriv chroot wakeup maxproc command + args - # (yes) (yes) (yes) (never) (100) + # (yes) (yes) (no) (never) (100) # ========================================================================== smtp inet n - n - - smtpd #submission inet n - n - - smtpd @@ -232,8 +231,7 @@ in default = null; example = ["localdomain"]; description = " - List of domains we agree to relay to. Default is the same as - destination. + List of domains we agree to relay to. Default is empty. "; }; @@ -357,32 +355,29 @@ in } ]; - jobs.postfix = - # I copy _lots_ of shipped configuration filed - # that can be left as is. I am afraid the exact - # will list slightly change in next Postfix - # release, so listing them all one-by-one in an - # accurate way is unlikely to be better. + systemd.services.postfix = { description = "Postfix mail server"; wantedBy = [ "multi-user.target" ]; after = [ "network.target" ]; - daemonType = "fork"; + serviceConfig = { + Type = "forking"; + Restart = "always"; + PIDFile = "/var/postfix/queue/pid/master.pid"; + }; preStart = '' - if ! [ -d /var/spool/postfix ]; then - ${pkgs.coreutils}/bin/mkdir -p /var/spool/mail /var/postfix/conf /var/postfix/queue - fi + ${pkgs.coreutils}/bin/mkdir -p /var/spool/mail /var/postfix/conf /var/postfix/queue ${pkgs.coreutils}/bin/chown -R ${user}:${group} /var/postfix ${pkgs.coreutils}/bin/chown -R ${user}:${setgidGroup} /var/postfix/queue ${pkgs.coreutils}/bin/chmod -R ug+rwX /var/postfix/queue ${pkgs.coreutils}/bin/chown root:root /var/spool/mail ${pkgs.coreutils}/bin/chmod a+rwxt /var/spool/mail - ${pkgs.coreutils}/bin/ln -sf /var/spool/mail /var/mail + ${pkgs.coreutils}/bin/ln -sf /var/spool/mail /var/ - ln -sf "${pkgs.postfix}/etc/postfix/"* /var/postfix/conf + ln -sf ${pkgs.postfix}/etc/postfix/postfix-files /var/postfix/conf ln -sf ${aliasesFile} /var/postfix/conf/aliases ln -sf ${virtualFile} /var/postfix/conf/virtual @@ -391,12 +386,18 @@ in ${pkgs.postfix}/sbin/postalias -c /var/postfix/conf /var/postfix/conf/aliases ${pkgs.postfix}/sbin/postmap -c /var/postfix/conf /var/postfix/conf/virtual + ''; + script = '' ${pkgs.postfix}/sbin/postfix -c /var/postfix/conf start ''; + reload = '' + ${pkgs.postfix}/sbin/postfix -c /var/postfix/conf reload + ''; + preStop = '' - ${pkgs.postfix}/sbin/postfix -c /var/postfix/conf stop + ${pkgs.postfix}/sbin/postfix -c /var/postfix/conf stop ''; }; diff --git a/nixos/modules/services/misc/autofs.nix b/nixos/modules/services/misc/autofs.nix index f4a1059d09f0..b4dae79cf8a9 100644 --- a/nixos/modules/services/misc/autofs.nix +++ b/nixos/modules/services/misc/autofs.nix @@ -71,48 +71,17 @@ in config = mkIf cfg.enable { - environment.etc = singleton - { target = "auto.master"; - source = pkgs.writeText "auto.master" cfg.autoMaster; - }; - boot.kernelModules = [ "autofs4" ]; - jobs.autofs = + systemd.services.autofs = { description = "Filesystem automounter"; + wantedBy = [ "multi-user.target" ]; + after = [ "network.target" ]; - startOn = "started network-interfaces"; - stopOn = "stopping network-interfaces"; - - path = [ pkgs.nfs-utils pkgs.sshfsFuse ]; - - preStop = - '' - set -e; while :; do pkill -TERM automount; sleep 1; done - ''; - - # automount doesn't clean up when receiving SIGKILL. - # umount -l should unmount the directories recursively when they are no longer used - # It does, but traces are left in /etc/mtab. So unmount recursively.. - postStop = - '' - PATH=${pkgs.gnused}/bin:${pkgs.coreutils}/bin - exec &> /tmp/logss - # double quote for sed: - escapeSpaces(){ sed 's/ /\\\\040/g'; } - unescapeSpaces(){ sed 's/\\040/ /g'; } - sed -n 's@^\s*\(\([^\\ ]\|\\ \)*\)\s.*@\1@p' ${autoMaster} | sed 's/[\\]//' | while read mountPoint; do - sed -n "s@[^ ]\+\s\+\($(echo "$mountPoint"| escapeSpaces)[^ ]*\).*@\1@p" /proc/mounts | sort -r | unescapeSpaces| while read smountP; do - ${pkgs.utillinux}/bin/umount -l "$smountP" || true - done - done - ''; - - script = - '' - ${if cfg.debug then "exec &> /var/log/autofs" else ""} - exec ${pkgs.autofs5}/sbin/automount ${if cfg.debug then "-d" else ""} -f -t ${builtins.toString cfg.timeout} "${autoMaster}" ${if cfg.debug then "-l7" else ""} - ''; + serviceConfig = { + ExecStart = "${pkgs.autofs5}/sbin/automount ${if cfg.debug then "-d" else ""} -f -t ${builtins.toString cfg.timeout} ${autoMaster} ${if cfg.debug then "-l7" else ""}"; + ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID"; + }; }; }; diff --git a/nixos/modules/services/misc/calibre-server.nix b/nixos/modules/services/misc/calibre-server.nix new file mode 100644 index 000000000000..a920aa22ccdf --- /dev/null +++ b/nixos/modules/services/misc/calibre-server.nix @@ -0,0 +1,63 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + + cfg = config.services.calibre-server; + +in + +{ + + ###### interface + + options = { + + services.calibre-server = { + + enable = mkEnableOption "calibre-server"; + + libraryDir = mkOption { + description = '' + The directory where the Calibre library to serve is. + ''; + type = types.path; + }; + + }; + + }; + + + ###### implementation + + config = mkIf cfg.enable { + + systemd.services.calibre-server = + { + description = "Calibre Server"; + after = [ "network.target" ]; + wantedBy = [ "multi-user.target" ]; + serviceConfig = { + User = "calibre-server"; + Restart = "always"; + ExecStart = "${pkgs.calibre}/bin/calibre-server --with-library=${cfg.libraryDir}"; + }; + + }; + + environment.systemPackages = [ pkgs.calibre ]; + + users.extraUsers.calibre-server = { + uid = config.ids.uids.calibre-server; + group = "calibre-server"; + }; + + users.extraGroups.calibre-server = { + gid = config.ids.gids.calibre-server; + }; + + }; + +} diff --git a/nixos/modules/services/misc/ihaskell.nix b/nixos/modules/services/misc/ihaskell.nix index 7f7f981de498..13c41466eab2 100644 --- a/nixos/modules/services/misc/ihaskell.nix +++ b/nixos/modules/services/misc/ihaskell.nix @@ -22,9 +22,9 @@ in }; haskellPackages = mkOption { - default = pkgs.haskellngPackages; - defaultText = "pkgs.haskellngPackages"; - example = literalExample "pkgs.haskell-ng.packages.ghc784"; + default = pkgs.haskellPackages; + defaultText = "pkgs.haskellPackages"; + example = literalExample "pkgs.haskell.packages.ghc784"; description = '' haskellPackages used to build IHaskell and other packages. This can be used to change the GHC version used to build diff --git a/nixos/modules/services/misc/nixos-manual.nix b/nixos/modules/services/misc/nixos-manual.nix index c10d8197686f..7534eb0ae6a3 100644 --- a/nixos/modules/services/misc/nixos-manual.nix +++ b/nixos/modules/services/misc/nixos-manual.nix @@ -92,7 +92,9 @@ in system.build.manual = manual; - environment.systemPackages = [ manual.manpages manual.manual help ]; + environment.systemPackages = + [ manual.manual help ] + ++ optional config.programs.man.enable manual.manpages; boot.extraTTYs = mkIf cfg.showManual ["tty${cfg.ttyNumber}"]; diff --git a/nixos/modules/services/misc/parsoid.nix b/nixos/modules/services/misc/parsoid.nix index 0844190a5490..ea97d6e30e83 100644 --- a/nixos/modules/services/misc/parsoid.nix +++ b/nixos/modules/services/misc/parsoid.nix @@ -91,7 +91,7 @@ in wantedBy = [ "multi-user.target" ]; after = [ "network.target" ]; serviceConfig = { - ExecStart = "${pkgs.nodePackages.parsoid}/lib/node_modules/parsoid/api/server.js -c ${confFile} -n ${toString cfg.workers}"; + ExecStart = "${pkgs.nodePackages_0_10.parsoid}/lib/node_modules/parsoid/api/server.js -c ${confFile} -n ${toString cfg.workers}"; }; }; diff --git a/nixos/modules/services/misc/synergy.nix b/nixos/modules/services/misc/synergy.nix index 054df965347d..7e8eadbe5f37 100644 --- a/nixos/modules/services/misc/synergy.nix +++ b/nixos/modules/services/misc/synergy.nix @@ -89,6 +89,7 @@ in wantedBy = optional cfgC.autoStart "multi-user.target"; path = [ pkgs.synergy ]; serviceConfig.ExecStart = ''${pkgs.synergy}/bin/synergyc -f ${optionalString (cfgC.screenName != "") "-n ${cfgC.screenName}"} ${cfgC.serverAddress}''; + serviceConfig.Restart = "on-failure"; }; }) (mkIf cfgS.enable { @@ -98,6 +99,7 @@ in wantedBy = optional cfgS.autoStart "multi-user.target"; path = [ pkgs.synergy ]; serviceConfig.ExecStart = ''${pkgs.synergy}/bin/synergys -c ${cfgS.configFile} -f ${optionalString (cfgS.address != "") "-a ${cfgS.address}"} ${optionalString (cfgS.screenName != "") "-n ${cfgS.screenName}" }''; + serviceConfig.Restart = "on-failure"; }; }) ]; diff --git a/nixos/modules/services/monitoring/bosun.nix b/nixos/modules/services/monitoring/bosun.nix index 7e8dea4ec024..ebe4741f01bd 100644 --- a/nixos/modules/services/monitoring/bosun.nix +++ b/nixos/modules/services/monitoring/bosun.nix @@ -9,7 +9,7 @@ let tsdbHost = ${cfg.opentsdbHost} httpListen = ${cfg.listenAddress} stateFile = ${cfg.stateFile} - checkFrequency = 5m + checkFrequency = ${cfg.checkFrequency} ${cfg.extraConfig} ''; @@ -77,6 +77,14 @@ in { ''; }; + checkFrequency = mkOption { + type = types.str; + default = "5m"; + description = '' + Bosun's check frequency + ''; + }; + extraConfig = mkOption { type = types.string; default = ""; diff --git a/nixos/modules/services/monitoring/grafana.nix b/nixos/modules/services/monitoring/grafana.nix index fa653565a67f..5302728eae91 100644 --- a/nixos/modules/services/monitoring/grafana.nix +++ b/nixos/modules/services/monitoring/grafana.nix @@ -318,7 +318,7 @@ in { wantedBy = ["multi-user.target"]; after = ["networking.target"]; serviceConfig = { - ExecStart = "${cfg.package-backend}/bin/grafana --config ${cfgFile} web"; + ExecStart = "${cfg.package}/bin/grafana --config ${cfgFile} web"; WorkingDirectory = cfg.dataDir; User = "grafana"; }; diff --git a/nixos/modules/services/monitoring/teamviewer.nix b/nixos/modules/services/monitoring/teamviewer.nix index beba5dcd1b06..533f1ea6644b 100644 --- a/nixos/modules/services/monitoring/teamviewer.nix +++ b/nixos/modules/services/monitoring/teamviewer.nix @@ -29,6 +29,7 @@ in wantedBy = [ "graphical.target" ]; after = [ "NetworkManager-wait-online.service" "network.target" ]; + preStart = "mkdir -pv /var/tmp/teamviewer10/{logs,config}"; serviceConfig = { Type = "forking"; diff --git a/nixos/modules/services/networking/asterisk.nix b/nixos/modules/services/networking/asterisk.nix index b079cb227303..13617a1b6c58 100644 --- a/nixos/modules/services/networking/asterisk.nix +++ b/nixos/modules/services/networking/asterisk.nix @@ -201,6 +201,7 @@ in for d in '${varlibdir}' '${spooldir}' '${logdir}'; do # TODO: Make exceptions for /var directories that likely should be updated if [ ! -e "$d" ]; then + mkdir -p "$d" cp --recursive ${pkgs.asterisk}/"$d" "$d" chown --recursive ${asteriskUser} "$d" find "$d" -type d | xargs chmod 0755 diff --git a/nixos/modules/services/networking/autossh.nix b/nixos/modules/services/networking/autossh.nix new file mode 100644 index 000000000000..9ea17469870d --- /dev/null +++ b/nixos/modules/services/networking/autossh.nix @@ -0,0 +1,114 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + + cfg = config.services.autossh; + +in + +{ + + ###### interface + + options = { + + services.autossh = { + + sessions = mkOption { + type = types.listOf (types.submodule { + options = { + name = mkOption { + type = types.string; + example = "socks-peer"; + description = "Name of the local AutoSSH session"; + }; + user = mkOption { + type = types.string; + example = "bill"; + description = "Name of the user the AutoSSH session should run as"; + }; + monitoringPort = mkOption { + type = types.int; + default = 0; + example = 20000; + description = '' + Port to be used by AutoSSH for peer monitoring. Note, that + AutoSSH also uses mport+1. Value of 0 disables the keep-alive + style monitoring + ''; + }; + extraArguments = mkOption { + type = types.string; + example = "-N -D4343 bill@socks.example.net"; + description = '' + Arguments to be passed to AutoSSH and retransmitted to SSH + process. Some meaningful options include -N (don't run remote + command), -D (open SOCKS proxy on local port), -R (forward + remote port), -L (forward local port), -v (Enable debug). Check + ssh manual for the complete list. + ''; + }; + }; + }); + + default = []; + description = '' + List of AutoSSH sessions to start as systemd services. Each service is + named 'autossh-{session.name}'. + ''; + + example = [ + { + name="socks-peer"; + user="bill"; + monitoringPort = 20000; + extraArguments="-N -D4343 billremote@socks.host.net"; + } + ]; + + }; + }; + + }; + + ###### implementation + + config = mkIf (cfg.sessions != []) { + + systemd.services = + + lib.fold ( s : acc : acc // + { + "autossh-${s.name}" = + let + mport = if s ? monitoringPort then s.monitoringPort else 0; + in + { + description = "AutoSSH session (" + s.name + ")"; + + after = [ "network.target" ]; + wantedBy = [ "multi-user.target" ]; + + # To be able to start the service with no network connection + environment.AUTOSSH_GATETIME="0"; + + # How often AutoSSH checks the network, in seconds + environment.AUTOSSH_POLL="30"; + + serviceConfig = { + User = "${s.user}"; + PermissionsStartOnly = true; + # AutoSSH may exit with 0 code if the SSH session was + # gracefully terminated by either local or remote side. + Restart = "on-success"; + ExecStart = "${pkgs.autossh}/bin/autossh -M ${toString mport} ${s.extraArguments}"; + }; + }; + }) {} cfg.sessions; + + environment.systemPackages = [ pkgs.autossh ]; + + }; +} diff --git a/nixos/modules/services/networking/copy-com.nix b/nixos/modules/services/networking/copy-com.nix index 69a41ab97963..ee0d043d471b 100644 --- a/nixos/modules/services/networking/copy-com.nix +++ b/nixos/modules/services/networking/copy-com.nix @@ -39,7 +39,8 @@ in systemd.services."copy-com-${cfg.user}" = { description = "Copy.com client"; - after = [ "network.target" "local-fs.target" ]; + wants = [ "network-online.target" ]; + after = [ "network-online.target" "local-fs.target" ]; wantedBy = [ "multi-user.target" ]; serviceConfig = { ExecStart = "${pkgs.copy-com}/bin/CopyConsole ${if cfg.debug then "-consoleOutput -debugToConsole=dirwatch,path-watch,csm_path,csm -debug -console" else ""}"; diff --git a/nixos/modules/services/networking/networkmanager.nix b/nixos/modules/services/networking/networkmanager.nix index 8370eca21e52..7df194fa419b 100644 --- a/nixos/modules/services/networking/networkmanager.nix +++ b/nixos/modules/services/networking/networkmanager.nix @@ -6,16 +6,18 @@ with lib; let cfg = config.networking.networkmanager; - stateDirs = "/var/lib/NetworkManager /var/lib/dhclient"; + # /var/lib/misc is for dnsmasq.leases. + stateDirs = "/var/lib/NetworkManager /var/lib/dhclient /var/lib/misc"; configFile = writeText "NetworkManager.conf" '' [main] plugins=keyfile [keyfile] - ${optionalString (config.networking.hostName != "") '' - hostname=${config.networking.hostName} - ''} + ${optionalString (config.networking.hostName != "") + ''hostname=${config.networking.hostName}''} + ${optionalString (cfg.unmanaged != []) + ''unmanaged-devices=${lib.concatStringsSep ";" cfg.unmanaged}''} [logging] level=WARN @@ -40,7 +42,6 @@ let polkit.addRule(function(action, subject) { if ( subject.isInGroup("networkmanager") - && subject.active && (action.id.indexOf("org.freedesktop.NetworkManager.") == 0 || action.id.indexOf("org.freedesktop.ModemManager") == 0 )) @@ -97,6 +98,16 @@ in { ''; }; + unmanaged = mkOption { + type = types.listOf types.string; + default = []; + description = '' + List of interfaces that will not be managed by NetworkManager. + Interface name can be specified here, but if you need more fidelity + see "Device List Format" in NetworkManager.conf man page. + ''; + }; + # Ugly hack for using the correct gnome3 packageSet basePackages = mkOption { type = types.attrsOf types.path; @@ -206,10 +217,16 @@ in { environment.systemPackages = cfg.packages; - users.extraGroups = singleton { + users.extraGroups = [{ name = "networkmanager"; gid = config.ids.gids.networkmanager; - }; + } + { + name = "nm-openvpn"; + }]; + users.extraUsers = [{ + name = "nm-openvpn"; + }]; systemd.packages = cfg.packages; diff --git a/nixos/modules/services/networking/quassel.nix b/nixos/modules/services/networking/quassel.nix index 005eb7bd7614..52c7ac8e6893 100644 --- a/nixos/modules/services/networking/quassel.nix +++ b/nixos/modules/services/networking/quassel.nix @@ -23,11 +23,11 @@ in ''; }; - interface = mkOption { - default = "127.0.0.1"; + interfaces = mkOption { + default = [ "127.0.0.1" ]; description = '' - The interface the Quassel daemon will be listening to. If `127.0.0.1', - only clients on the local host can connect to it; if `0.0.0.0', clients + The interfaces the Quassel daemon will be listening to. If `[ 127.0.0.1 ]', + only clients on the local host can connect to it; if `[ 0.0.0.0 ]', clients can access it from any network interface. ''; }; @@ -78,7 +78,8 @@ in { description = "Quassel IRC client daemon"; wantedBy = [ "multi-user.target" ]; - after = [ "network.target" ]; + after = [ "network.target" ] ++ optional config.services.postgresql.enable "postgresql.service" + ++ optional config.services.mysql.enable "mysql.service"; preStart = '' mkdir -p ${cfg.dataDir} @@ -87,7 +88,7 @@ in serviceConfig = { - ExecStart = "${quassel}/bin/quasselcore --listen=${cfg.interface} --port=${toString cfg.portNumber} --configdir=${cfg.dataDir}"; + ExecStart = "${quassel}/bin/quasselcore --listen=${concatStringsSep '','' cfg.interfaces} --port=${toString cfg.portNumber} --configdir=${cfg.dataDir}"; User = user; PermissionsStartOnly = true; }; diff --git a/nixos/modules/services/networking/supplicant.nix b/nixos/modules/services/networking/supplicant.nix new file mode 100644 index 000000000000..502a0468787f --- /dev/null +++ b/nixos/modules/services/networking/supplicant.nix @@ -0,0 +1,249 @@ +{ config, lib, utils, pkgs, ... }: + +with lib; + +let + + cfg = config.networking.supplicant; + + # We must escape interfaces due to the systemd interpretation + subsystemDevice = interface: + "sys-subsystem-net-devices-${utils.escapeSystemdPath interface}.device"; + + serviceName = iface: "supplicant-${if (iface=="WLAN") then "wlan@" else ( + if (iface=="LAN") then "lan@" else ( + if (iface=="DBUS") then "dbus" + else (replaceChars [" "] ["-"] iface)))}"; + + # TODO: Use proper privilege separation for wpa_supplicant + supplicantService = iface: suppl: + let + deps = (if (iface=="WLAN"||iface=="LAN") then ["sys-subsystem-net-devices-%i.device"] else ( + if (iface=="DBUS") then ["dbus.service"] + else (map subsystemDevice (splitString " " iface)))) + ++ optional (suppl.bridge!="") (subsystemDevice suppl.bridge); + + ifaceArg = concatStringsSep " -N " (map (i: "-i${i}") (splitString " " iface)); + driverArg = optionalString (suppl.driver != null) "-D${suppl.driver}"; + bridgeArg = optionalString (suppl.bridge!="") "-b${suppl.bridge}"; + confFileArg = optionalString (suppl.configFile.path!=null) "-c${suppl.configFile.path}"; + extraConfFile = pkgs.writeText "supplicant-extra-conf-${replaceChars [" "] ["-"] iface}" '' + ${optionalString suppl.userControlled.enable "ctrl_interface=DIR=${suppl.userControlled.socketDir} GROUP=${suppl.userControlled.group}"} + ${optionalString suppl.configFile.writable "update_config=1"} + ${suppl.extraConf} + ''; + in + { description = "Supplicant ${iface}${optionalString (iface=="WLAN"||iface=="LAN") " %I"}"; + wantedBy = [ "network.target" ]; + bindsTo = deps; + after = deps; + before = [ "network.target" ]; + # Receive restart event after resume + partOf = [ "post-resume.target" ]; + + path = [ pkgs.coreutils ]; + + preStart = '' + ${optionalString (suppl.configFile.path!=null) '' + touch -a ${suppl.configFile.path} + chmod 600 ${suppl.configFile.path} + ''} + ${optionalString suppl.userControlled.enable '' + if ! test -e ${suppl.userControlled.socketDir}; then + mkdir -m 0770 -p ${suppl.userControlled.socketDir} + chgrp ${suppl.userControlled.group} ${suppl.userControlled.socketDir} + fi + + if test "$(stat --printf '%G' ${suppl.userControlled.socketDir})" != "${suppl.userControlled.group}"; then + echo "ERROR: bad ownership on ${suppl.userControlled.socketDir}" >&2 + exit 1 + fi + ''} + ''; + + serviceConfig.ExecStart = "${pkgs.wpa_supplicant}/bin/wpa_supplicant -s ${driverArg} ${confFileArg} -I${extraConfFile} ${bridgeArg} ${suppl.extraCmdArgs} ${if (iface=="WLAN"||iface=="LAN") then "-i%I" else (if (iface=="DBUS") then "-u" else ifaceArg)}"; + + }; + + +in + +{ + + ###### interface + + options = { + + networking.supplicant = mkOption { + type = types.attrsOf types.optionSet; + + default = { }; + + example = { + "wlan0 wlan1" = { + configFile = "/etc/wpa_supplicant"; + userControlled.group = "network"; + extraConf = '' + ap_scan=1 + p2p_disabled=1 + ''; + extraCmdArgs = "-u -W"; + bridge = "br0"; + }; + }; + + description = '' + Interfaces for which to start <command>wpa_supplicant</command>. + The supplicant is used to scan for and associate with wireless networks, + or to authenticate with 802.1x capable network switches. + + The value of this option is an attribute set. Each attribute configures a + <command>wpa_supplicant</command> service, where the attribute name specifies + the name of the interface that <command>wpa_supplicant</command> operates on. + The attribute name can be a space separated list of interfaces. + The attribute names <literal>WLAN</literal>, <literal>LAN</literal> and <literal>DBUS</literal> + have a special meaning. <literal>WLAN</literal> and <literal>LAN</literal> are + configurations for universal <command>wpa_supplicant</command> service that is + started for each WLAN interface or for each LAN interface, respectively. + <literal>DBUS</literal> defines a device-unrelated <command>wpa_supplicant</command> + service that can be accessed through <literal>D-Bus</literal>. + ''; + + options = { + + configFile = { + + path = mkOption { + type = types.path; + example = "/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."; + }; + + }; + + }; + + }; + + }; + + + ###### implementation + + config = mkIf (cfg != {}) { + + environment.systemPackages = [ pkgs.wpa_supplicant ]; + + services.dbus.packages = [ pkgs.wpa_supplicant ]; + + systemd.services = mapAttrs' (n: v: nameValuePair (serviceName n) (supplicantService n v)) cfg; + + services.udev.packages = [ + (pkgs.writeTextFile { + name = "99-zzz-60-supplicant.rules"; + destination = "/etc/udev/rules.d/99-zzz-60-supplicant.rules"; + text = '' + ${flip (concatMapStringsSep "\n") (filter (n: n!="WLAN" && n!="LAN" && n!="DBUS") (attrNames cfg)) (iface: + flip (concatMapStringsSep "\n") (splitString " " iface) (i: '' + ACTION=="add", SUBSYSTEM=="net", ENV{INTERFACE}=="${i}", TAG+="systemd", ENV{SYSTEMD_WANTS}+="supplicant-${replaceChars [" "] ["-"] iface}.service", TAG+="SUPPLICANT_ASSIGNED"''))} + + ${optionalString (hasAttr "WLAN" cfg) '' + ACTION=="add", SUBSYSTEM=="net", ENV{DEVTYPE}=="wlan", TAG!="SUPPLICANT_ASSIGNED", TAG+="systemd", PROGRAM="${pkgs.systemd}/bin/systemd-escape -p %E{INTERFACE}", ENV{SYSTEMD_WANTS}+="supplicant-wlan@$result.service" + ''} + ${optionalString (hasAttr "LAN" cfg) '' + ACTION=="add", SUBSYSTEM=="net", ENV{DEVTYPE}=="lan", TAG!="SUPPLICANT_ASSIGNED", TAG+="systemd", PROGRAM="${pkgs.systemd}/bin/systemd-escape -p %E{INTERFACE}", ENV{SYSTEMD_WANTS}+="supplicant-lan@$result.service" + ''} + ''; + })]; + + }; + +} + diff --git a/nixos/modules/services/networking/tlsdated.nix b/nixos/modules/services/networking/tlsdated.nix index f2d0c9f35c9c..ff7d0178a81a 100644 --- a/nixos/modules/services/networking/tlsdated.nix +++ b/nixos/modules/services/networking/tlsdated.nix @@ -63,7 +63,7 @@ in }); default = [ { - host = "www.ptb.de"; + host = "encrypted.google.com"; port = 443; proxy = null; } diff --git a/nixos/modules/services/networking/wakeonlan.nix b/nixos/modules/services/networking/wakeonlan.nix index 11bb7e925255..ebfba263cd8f 100644 --- a/nixos/modules/services/networking/wakeonlan.nix +++ b/nixos/modules/services/networking/wakeonlan.nix @@ -40,7 +40,7 @@ in ]; description = '' Interfaces where to enable Wake-On-LAN, and how. Two methods available: - "magickey" and "password". The password has the shape of six bytes + "magicpacket" and "password". The password has the shape of six bytes in hexadecimal separated by a colon each. For more information, check the ethtool manual. ''; diff --git a/nixos/modules/services/scheduling/cron.nix b/nixos/modules/services/scheduling/cron.nix index 02d80a77da50..1b5e83173e8f 100644 --- a/nixos/modules/services/scheduling/cron.nix +++ b/nixos/modules/services/scheduling/cron.nix @@ -100,7 +100,7 @@ in environment.systemPackages = [ cronNixosPkg ]; environment.etc.crontab = - { source = pkgs.runCommand "crontabs" { inherit allFiles; } + { source = pkgs.runCommand "crontabs" { inherit allFiles; preferLocalBuild = true; } '' touch $out for i in $allFiles; do diff --git a/nixos/modules/services/web-servers/lighttpd/default.nix b/nixos/modules/services/web-servers/lighttpd/default.nix index 2c662c0aead9..171503db4eec 100644 --- a/nixos/modules/services/web-servers/lighttpd/default.nix +++ b/nixos/modules/services/web-servers/lighttpd/default.nix @@ -44,7 +44,6 @@ let "mod_flv_streaming" "mod_magnet" "mod_mysql_vhost" - "mod_rewrite" "mod_scgi" "mod_setenv" "mod_trigger_b4_dl" diff --git a/nixos/modules/services/x11/desktop-managers/gnome3.nix b/nixos/modules/services/x11/desktop-managers/gnome3.nix index 0fc255c4d64c..e32d6669b046 100644 --- a/nixos/modules/services/x11/desktop-managers/gnome3.nix +++ b/nixos/modules/services/x11/desktop-managers/gnome3.nix @@ -104,6 +104,7 @@ in { services.xserver.desktopManager.session = singleton { name = "gnome3"; + bgSupport = true; start = '' # Set GTK_DATA_PREFIX so that GTK+ can find the themes export GTK_DATA_PREFIX=${config.system.path} diff --git a/nixos/modules/services/x11/desktop-managers/kde5.nix b/nixos/modules/services/x11/desktop-managers/kde5.nix index 5061d59b7c7f..6fdd5b4fa36d 100644 --- a/nixos/modules/services/x11/desktop-managers/kde5.nix +++ b/nixos/modules/services/x11/desktop-managers/kde5.nix @@ -8,38 +8,9 @@ let cfg = xcfg.desktopManager.kde5; xorg = pkgs.xorg; - phononBackends = { - gstreamer = [ - pkgs.phonon_backend_gstreamer - pkgs.gst_all.gstreamer - pkgs.gst_all.gstPluginsBase - pkgs.gst_all.gstPluginsGood - pkgs.gst_all.gstPluginsUgly - pkgs.gst_all.gstPluginsBad - pkgs.gst_all.gstFfmpeg # for mp3 playback - pkgs.phonon_qt5_backend_gstreamer - pkgs.gst_all_1.gstreamer - pkgs.gst_all_1.gst-plugins-base - pkgs.gst_all_1.gst-plugins-good - pkgs.gst_all_1.gst-plugins-ugly - pkgs.gst_all_1.gst-plugins-bad - pkgs.gst_all_1.gst-libav # for mp3 playback - ]; - - vlc = [ - pkgs.phonon_qt5_backend_vlc - pkgs.phonon_backend_vlc - ]; - }; - - phononBackendPackages = flip concatMap cfg.phononBackends - (name: attrByPath [name] (throw "unknown phonon backend `${name}'") phononBackends); - kf5 = pkgs.kf5_stable; - - plasma5 = pkgs.plasma5_stable.override { inherit kf5; }; - - kdeApps = pkgs.kdeApps_stable.override { inherit kf5; }; + plasma5 = pkgs.plasma5_stable; + kdeApps = pkgs.kdeApps_stable; in @@ -53,14 +24,24 @@ in description = "Enable the Plasma 5 (KDE 5) desktop environment."; }; - phononBackends = mkOption { - type = types.listOf types.str; - default = ["gstreamer"]; - example = ["gstreamer" "vlc"]; - description = '' - Phonon backends to use in KDE. Only the VLC and GStreamer backends are - available. The GStreamer backend is preferred by upstream. - ''; + phonon = { + + gstreamer = { + enable = mkOption { + type = types.bool; + default = true; + description = "Enable the GStreamer Phonon backend (recommended)."; + }; + }; + + vlc = { + enable = mkOption { + type = types.bool; + default = false; + description = "Enable the VLC Phonon backend."; + }; + }; + }; }; @@ -88,23 +69,77 @@ in }; environment.systemPackages = - filter isDerivation (builtins.attrValues plasma5) - ++ filter isDerivation (builtins.attrValues kf5) - ++ [ + [ pkgs.qt4 # qtconfig is the only way to set Qt 4 theme - kdeApps.kde-baseapps - kdeApps.kde-base-artwork - kdeApps.kmix + kf5.frameworkintegration + kf5.kinit + + plasma5.breeze + plasma5.kde-cli-tools + plasma5.kdeplasma-addons + plasma5.kgamma5 + plasma5.khelpcenter + plasma5.khotkeys + plasma5.kinfocenter + plasma5.kmenuedit + plasma5.kscreen + plasma5.ksysguard + plasma5.kwayland + plasma5.kwin + plasma5.kwrited + plasma5.milou + plasma5.oxygen + plasma5.polkit-kde-agent + plasma5.systemsettings + + plasma5.plasma-desktop + plasma5.plasma-workspace + plasma5.plasma-workspace-wallpapers + + kdeApps.ark + kdeApps.dolphin + kdeApps.dolphin-plugins + kdeApps.ffmpegthumbs + kdeApps.gwenview + kdeApps.kate + kdeApps.kdegraphics-thumbnailers kdeApps.konsole - kdeApps.oxygen-icons - - kdeApps.kde-runtime + kdeApps.okular + kdeApps.print-manager + kdeApps.oxygen-icons pkgs.hicolor_icon_theme + plasma5.kde-gtk-config pkgs.orion # GTK theme, nearly identical to Breeze - ] ++ phononBackendPackages; + ] + ++ lib.optional config.hardware.bluetooth.enable plasma5.bluedevil + ++ lib.optional config.networking.networkmanager.enable plasma5.plasma-nm + ++ lib.optional config.hardware.pulseaudio.enable plasma5.plasma-pa + ++ lib.optional config.powerManagement.enable plasma5.powerdevil + ++ lib.optionals cfg.phonon.gstreamer.enable + [ + pkgs.phonon_backend_gstreamer + pkgs.gst_all.gstreamer + pkgs.gst_all.gstPluginsBase + pkgs.gst_all.gstPluginsGood + pkgs.gst_all.gstPluginsUgly + pkgs.gst_all.gstPluginsBad + pkgs.gst_all.gstFfmpeg # for mp3 playback + pkgs.phonon_qt5_backend_gstreamer + pkgs.gst_all_1.gstreamer + pkgs.gst_all_1.gst-plugins-base + pkgs.gst_all_1.gst-plugins-good + pkgs.gst_all_1.gst-plugins-ugly + pkgs.gst_all_1.gst-plugins-bad + pkgs.gst_all_1.gst-libav # for mp3 playback + ] + ++ lib.optionals cfg.phonon.vlc.enable + [ + pkgs.phonon_qt5_backend_vlc + pkgs.phonon_backend_vlc + ]; environment.pathsToLink = [ "/share" ]; @@ -114,7 +149,7 @@ in }; environment.profileRelativeEnvVars = - mkIf (lib.elem "gstreamer" cfg.phononBackends) + mkIf cfg.phonon.gstreamer.enable { GST_PLUGIN_SYSTEM_PATH = [ "/lib/gstreamer-0.10" ]; GST_PLUGIN_SYSTEM_PATH_1_0 = [ "/lib/gstreamer-1.0" ]; diff --git a/nixos/modules/services/x11/display-managers/gdm.nix b/nixos/modules/services/x11/display-managers/gdm.nix index c9a563768323..58eb6f050131 100644 --- a/nixos/modules/services/x11/display-managers/gdm.nix +++ b/nixos/modules/services/x11/display-managers/gdm.nix @@ -20,7 +20,9 @@ in enable = mkEnableOption '' GDM as the display manager. - <emphasis>GDM is very experimental and may render system unusable.</emphasis> + <emphasis>GDM in NixOS is not well-tested with desktops other + than GNOME, so use with caution, as it could render the + system unusable.</emphasis> ''; debug = mkEnableOption '' diff --git a/nixos/modules/services/x11/display-managers/sddm.nix b/nixos/modules/services/x11/display-managers/sddm.nix index 3f1d190ae66b..16a0d1b6d963 100644 --- a/nixos/modules/services/x11/display-managers/sddm.nix +++ b/nixos/modules/services/x11/display-managers/sddm.nix @@ -35,8 +35,23 @@ let SessionCommand=${dmcfg.session.script} SessionDir=${dmcfg.session.desktops} XauthPath=${pkgs.xorg.xauth}/bin/xauth + + ${optionalString cfg.autoLogin.enable '' + [Autologin] + User=${cfg.autoLogin.user} + Session=${defaultSessionName}.desktop + Relogin=${if cfg.autoLogin.relogin then "true" else "false"} + ''} + + ${cfg.extraConfig} ''; + defaultSessionName = + let + dm = xcfg.desktopManager.default; + wm = xcfg.windowManager.default; + in dm + optionalString (wm != "none") (" + " + wm); + in { options = { @@ -50,6 +65,19 @@ in ''; }; + extraConfig = mkOption { + type = types.str; + default = ""; + example = '' + [Autologin] + User=john + Session=plasma.desktop + ''; + description = '' + Extra lines appended to the configuration of SDDM. + ''; + }; + theme = mkOption { type = types.str; default = "maui"; @@ -57,12 +85,62 @@ in Greeter theme to use. ''; }; + + autoLogin = mkOption { + default = {}; + description = '' + Configuration for automatic login. + ''; + + type = types.submodule { + options = { + enable = mkOption { + type = types.bool; + default = false; + description = '' + Automatically log in as the sepecified <option>autoLogin.user</option>. + ''; + }; + + user = mkOption { + type = types.nullOr types.str; + default = null; + description = '' + User to be used for the autologin. + ''; + }; + + relogin = mkOption { + type = types.bool; + default = false; + description = '' + If true automatic login will kick in again on session exit, otherwise it + will work only the first time. + ''; + }; + }; + }; + }; + }; }; config = mkIf cfg.enable { + assertions = [ + { assertion = cfg.autoLogin.enable -> cfg.autoLogin.user != null; + message = "SDDM auto-login requires services.xserver.displayManager.sddm.autoLogin.user to be set"; + } + { assertion = cfg.autoLogin.enable -> elem defaultSessionName dmcfg.session.names; + message = '' + SDDM auto-login requires that services.xserver.desktopManager.default and + services.xserver.windowMananger.default are set to valid values. The current + default session: ${defaultSessionName} is not valid. + ''; + } + ]; + services.xserver.displayManager.slim.enable = false; services.xserver.displayManager.job = { @@ -93,6 +171,18 @@ in session optional pam_keyinit.so force revoke session optional pam_permit.so ''; + + sddm-autologin.text = '' + auth requisite pam_nologin.so + auth required pam_succeed_if.so uid >= 1000 quiet + auth required pam_permit.so + + account include sddm + + password include sddm + + session include sddm + ''; }; users.extraUsers.sddm = { diff --git a/nixos/modules/services/x11/redshift.nix b/nixos/modules/services/x11/redshift.nix index ffae22d2d670..d40373ec2e55 100644 --- a/nixos/modules/services/x11/redshift.nix +++ b/nixos/modules/services/x11/redshift.nix @@ -22,14 +22,16 @@ in { latitude = mkOption { type = types.str; description = '' - Your current latitude. + Your current latitude, between + <literal>-90.0</literal> and <literal>90.0</literal>. ''; }; longitude = mkOption { type = types.str; description = '' - Your current longitude. + Your current longitude, between + between <literal>-180.0</literal> and <literal>180.0</literal>. ''; }; @@ -38,14 +40,16 @@ in { type = types.int; default = 5500; description = '' - Colour temperature to use during the day. + Colour temperature to use during the day, between + <literal>1000</literal> and <literal>25000</literal> K. ''; }; night = mkOption { type = types.int; default = 3700; description = '' - Colour temperature to use at night. + Colour temperature to use at night, between + <literal>1000</literal> and <literal>25000</literal> K. ''; }; }; diff --git a/nixos/modules/services/x11/window-managers/clfswm.nix b/nixos/modules/services/x11/window-managers/clfswm.nix new file mode 100644 index 000000000000..9d8eecb56c77 --- /dev/null +++ b/nixos/modules/services/x11/window-managers/clfswm.nix @@ -0,0 +1,31 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + cfg = config.services.xserver.windowManager.clfswm; +in + +{ + options = { + services.xserver.windowManager.clfswm = { + enable = mkOption { + type = types.bool; + default = false; + example = true; + description = "Enable the clfswm tiling window manager."; + }; + }; + }; + + config = mkIf cfg.enable { + services.xserver.windowManager.session = singleton { + name = "clfswm"; + start = '' + ${pkgs.clfswm}/bin/clfswm & + waitPID=$! + ''; + }; + environment.systemPackages = [ pkgs.clfswm ]; + }; +} diff --git a/nixos/modules/services/x11/window-managers/default.nix b/nixos/modules/services/x11/window-managers/default.nix index 4751de07a15d..31f42f5ffb9f 100644 --- a/nixos/modules/services/x11/window-managers/default.nix +++ b/nixos/modules/services/x11/window-managers/default.nix @@ -10,6 +10,7 @@ in imports = [ ./afterstep.nix ./bspwm.nix + ./clfswm.nix ./compiz.nix ./fluxbox.nix ./herbstluftwm.nix diff --git a/nixos/modules/services/x11/window-managers/xmonad.nix b/nixos/modules/services/x11/window-managers/xmonad.nix index c922ca7848d1..288800d514d3 100644 --- a/nixos/modules/services/x11/window-managers/xmonad.nix +++ b/nixos/modules/services/x11/window-managers/xmonad.nix @@ -20,9 +20,9 @@ in }; haskellPackages = mkOption { - default = pkgs.haskellngPackages; - defaultText = "pkgs.haskellngPackages"; - example = literalExample "pkgs.haskell-ng.packages.ghc784"; + default = pkgs.haskellPackages; + defaultText = "pkgs.haskellPackages"; + example = literalExample "pkgs.haskell.packages.ghc784"; description = '' haskellPackages used to build Xmonad and other packages. This can be used to change the GHC version used to build diff --git a/nixos/modules/system/boot/initrd-network.nix b/nixos/modules/system/boot/initrd-network.nix new file mode 100644 index 000000000000..6c6e2fafad43 --- /dev/null +++ b/nixos/modules/system/boot/initrd-network.nix @@ -0,0 +1,149 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + cfg = config.boot.initrd.network; + +in +{ + + options = { + + boot.initrd.network.enable = mkOption { + type = types.bool; + default = false; + description = '' + Add network connectivity support to initrd. + + Network options are configured via <literal>ip</literal> kernel + option, according to the kernel documentation. + ''; + }; + + boot.initrd.network.ssh.enable = mkOption { + type = types.bool; + default = false; + description = '' + Start SSH service during initrd boot. It can be used to debug failing + boot on a remote server, enter pasphrase for an encrypted partition etc. + Service is killed when stage-1 boot is finished. + ''; + }; + + boot.initrd.network.ssh.port = mkOption { + type = types.int; + default = 22; + description = '' + Port on which SSH initrd service should listen. + ''; + }; + + boot.initrd.network.ssh.shell = mkOption { + type = types.str; + default = "/bin/ash"; + description = '' + Login shell of the remote user. Can be used to limit actions user can do. + ''; + }; + + boot.initrd.network.ssh.hostRSAKey = mkOption { + type = types.nullOr types.path; + default = null; + description = '' + RSA SSH private key file in the Dropbear format. + + WARNING: This key is contained insecurely in the global Nix store. Do NOT + use your regular SSH host private keys for this purpose or you'll expose + them to regular users! + ''; + }; + + boot.initrd.network.ssh.hostDSSKey = mkOption { + type = types.nullOr types.path; + default = null; + description = '' + DSS SSH private key file in the Dropbear format. + + WARNING: This key is contained insecurely in the global Nix store. Do NOT + use your regular SSH host private keys for this purpose or you'll expose + them to regular users! + ''; + }; + + boot.initrd.network.ssh.hostECDSAKey = mkOption { + type = types.nullOr types.path; + default = null; + description = '' + ECDSA SSH private key file in the Dropbear format. + + WARNING: This key is contained insecurely in the global Nix store. Do NOT + use your regular SSH host private keys for this purpose or you'll expose + them to regular users! + ''; + }; + + boot.initrd.network.ssh.authorizedKeys = mkOption { + type = types.listOf types.str; + default = config.users.extraUsers.root.openssh.authorizedKeys.keys; + description = '' + Authorized keys for the root user on initrd. + ''; + }; + + }; + + config = mkIf cfg.enable { + + boot.initrd.kernelModules = [ "af_packet" ]; + + boot.initrd.extraUtilsCommands = '' + copy_bin_and_libs ${pkgs.mkinitcpio-nfs-utils}/bin/ipconfig + '' + optionalString cfg.ssh.enable '' + copy_bin_and_libs ${pkgs.dropbear}/bin/dropbear + + cp -pv ${pkgs.glibc}/lib/libnss_files.so.* $out/lib + ''; + + boot.initrd.extraUtilsCommandsTest = optionalString cfg.ssh.enable '' + $out/bin/dropbear -V + ''; + + boot.initrd.postEarlyDeviceCommands = '' + # Search for interface definitions in command line + for o in $(cat /proc/cmdline); do + case $o in + ip=*) + ipconfig $o && hasNetwork=1 + ;; + esac + done + '' + optionalString cfg.ssh.enable '' + if [ -n "$hasNetwork" ]; then + mkdir /dev/pts + mount -t devpts devpts /dev/pts + + mkdir -p /etc + echo 'root:x:0:0:root:/root:${cfg.ssh.shell}' > /etc/passwd + echo '${cfg.ssh.shell}' > /etc/shells + echo 'passwd: files' > /etc/nsswitch.conf + + mkdir -p /var/log + touch /var/log/lastlog + + mkdir -p /etc/dropbear + ${optionalString (cfg.ssh.hostRSAKey != null) "ln -s ${cfg.ssh.hostRSAKey} /etc/dropbear/dropbear_rsa_host_key"} + ${optionalString (cfg.ssh.hostDSSKey != null) "ln -s ${cfg.ssh.hostDSSKey} /etc/dropbear/dropbear_dss_host_key"} + ${optionalString (cfg.ssh.hostECDSAKey != null) "ln -s ${cfg.ssh.hostECDSAKey} /etc/dropbear/dropbear_ecdsa_host_key"} + + mkdir -p /root/.ssh + ${concatStrings (map (key: '' + echo -n ${escapeShellArg key} >> /root/.ssh/authorized_keys + '') cfg.ssh.authorizedKeys)} + + dropbear -s -j -k -E -m -p ${toString cfg.ssh.port} + fi + ''; + + }; +} diff --git a/nixos/modules/system/boot/loader/grub/grub.nix b/nixos/modules/system/boot/loader/grub/grub.nix index 0b349749244f..5f09e937537f 100644 --- a/nixos/modules/system/boot/loader/grub/grub.nix +++ b/nixos/modules/system/boot/loader/grub/grub.nix @@ -378,6 +378,17 @@ in ''; }; + systemHasTPM = mkOption { + default = ""; + example = "YES_TPM_is_activated"; + type = types.string; + description = '' + Assertion that the target system has an activated TPM. It is a safety + check before allowing the activation of 'enableTrustedBoot'. TrustedBoot + WILL FAIL TO BOOT YOUR SYSTEM if no TPM is available. + ''; + }; + }; }; @@ -453,8 +464,8 @@ in message = "Trusted GRUB does not have ZFS support"; } { - assertion = !cfg.enableTrustedBoot; - message = "Trusted GRUB can break your system. Remove assertion if you want to test trustedGRUB nevertheless."; + assertion = !cfg.enableTrustedBoot || cfg.systemHasTPM == "YES_TPM_is_activated"; + message = "Trusted GRUB can break the system! Confirm that the system has an activated TPM by setting 'systemHasTPM'."; } ] ++ flip concatMap cfg.mirroredBoots (args: [ { @@ -477,4 +488,15 @@ in ]; + + imports = + [ (mkRemovedOptionModule [ "boot" "loader" "grub" "bootDevice" ]) + (mkRenamedOptionModule [ "boot" "copyKernels" ] [ "boot" "loader" "grub" "copyKernels" ]) + (mkRenamedOptionModule [ "boot" "extraGrubEntries" ] [ "boot" "loader" "grub" "extraEntries" ]) + (mkRenamedOptionModule [ "boot" "extraGrubEntriesBeforeNixos" ] [ "boot" "loader" "grub" "extraEntriesBeforeNixOS" ]) + (mkRenamedOptionModule [ "boot" "grubDevice" ] [ "boot" "loader" "grub" "device" ]) + (mkRenamedOptionModule [ "boot" "bootMount" ] [ "boot" "loader" "grub" "bootDevice" ]) + (mkRenamedOptionModule [ "boot" "grubSplashImage" ] [ "boot" "loader" "grub" "splashImage" ]) + ]; + } diff --git a/nixos/modules/system/boot/luksroot.nix b/nixos/modules/system/boot/luksroot.nix index 4a14ff1879c9..763703205630 100644 --- a/nixos/modules/system/boot/luksroot.nix +++ b/nixos/modules/system/boot/luksroot.nix @@ -32,9 +32,12 @@ let ''} open_normally() { - cryptsetup luksOpen ${device} ${name} ${optionalString allowDiscards "--allow-discards"} \ + echo luksOpen ${device} ${name} ${optionalString allowDiscards "--allow-discards"} \ ${optionalString (header != null) "--header=${header}"} \ - ${optionalString (keyFile != null) "--key-file=${keyFile} ${optionalString (keyFileSize != null) "--keyfile-size=${toString keyFileSize}"}"} + ${optionalString (keyFile != null) "--key-file=${keyFile} ${optionalString (keyFileSize != null) "--keyfile-size=${toString keyFileSize}"}"} \ + > /.luksopen_args + cryptsetup-askpass + rm /.luksopen_args } ${optionalString (luks.yubikeySupport && (yubikey != null)) '' @@ -418,6 +421,18 @@ in boot.initrd.extraUtilsCommands = '' copy_bin_and_libs ${pkgs.cryptsetup}/bin/cryptsetup + cat > $out/bin/cryptsetup-askpass <<EOF + #!$out/bin/sh -e + if [ -e /.luksopen_args ]; then + cryptsetup \$(cat /.luksopen_args) + killall cryptsetup + else + echo "Passphrase is not requested now" + exit 1 + fi + EOF + chmod +x $out/bin/cryptsetup-askpass + ${optionalString luks.yubikeySupport '' copy_bin_and_libs ${pkgs.ykpers}/bin/ykchalresp copy_bin_and_libs ${pkgs.ykpers}/bin/ykinfo @@ -432,6 +447,8 @@ in cat > $out/bin/openssl-wrap <<EOF #!$out/bin/sh + export OPENSSL_CONF=$out/etc/ssl/openssl.cnf + $out/bin/openssl "\$@" EOF chmod +x $out/bin/openssl-wrap ''} @@ -442,11 +459,6 @@ in ${optionalString luks.yubikeySupport '' $out/bin/ykchalresp -V $out/bin/ykinfo -V - cat > $out/bin/openssl-wrap <<EOF - #!$out/bin/sh - export OPENSSL_CONF=$out/etc/ssl/openssl.cnf - $out/bin/openssl "\$@" - EOF $out/bin/openssl-wrap version ''} ''; diff --git a/nixos/modules/system/boot/stage-1-init.sh b/nixos/modules/system/boot/stage-1-init.sh index 51828c5c090b..2b5d547353f8 100644 --- a/nixos/modules/system/boot/stage-1-init.sh +++ b/nixos/modules/system/boot/stage-1-init.sh @@ -149,6 +149,10 @@ udevadm trigger --action=add udevadm settle +# Additional devices initialization. +@postEarlyDeviceCommands@ + + # Load boot-time keymap before any LVM/LUKS initialization @extraUtils@/bin/busybox loadkmap < "@busyboxKeymap@" diff --git a/nixos/modules/system/boot/stage-1.nix b/nixos/modules/system/boot/stage-1.nix index 0759b10c00a5..0bd5387a7c0f 100644 --- a/nixos/modules/system/boot/stage-1.nix +++ b/nixos/modules/system/boot/stage-1.nix @@ -104,7 +104,7 @@ let stripDirs "lib bin" "-s" # Run patchelf to make the programs refer to the copied libraries. - for i in $out/bin/* $out/lib/*; do if ! test -L $i; then nuke-refs $i; fi; done + for i in $out/bin/* $out/lib/*; do if ! test -L $i; then nuke-refs -e $out $i; fi; done for i in $out/bin/*; do if ! test -L $i; then @@ -203,10 +203,10 @@ let inherit (config.boot) resumeDevice devSize runSize; inherit (config.boot.initrd) checkJournalingFS - preLVMCommands postDeviceCommands postMountCommands kernelModules; + postEarlyDeviceCommands preLVMCommands postDeviceCommands postMountCommands 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) config.swapDevices); + (filter (sd: (sd ? label || hasPrefix "/dev/" sd.device) && !sd.randomEncryption) config.swapDevices); fsInfo = let f = fs: [ fs.mountPoint (if fs.device != null then fs.device else "/dev/disk/by-label/${fs.label}") fs.fsType fs.options ]; @@ -313,6 +313,14 @@ in ''; }; + boot.initrd.postEarlyDeviceCommands = mkOption { + default = ""; + type = types.lines; + description = '' + Shell commands to be executed early after creation of device nodes. + ''; + }; + boot.initrd.postMountCommands = mkOption { default = ""; type = types.lines; diff --git a/nixos/modules/system/boot/systemd.nix b/nixos/modules/system/boot/systemd.nix index 34eda7247cdd..0b7647093e0f 100644 --- a/nixos/modules/system/boot/systemd.nix +++ b/nixos/modules/system/boot/systemd.nix @@ -100,7 +100,7 @@ let # Maintaining state across reboots. "systemd-random-seed.service" "systemd-backlight@.service" - "systemd-rfkill@.service" + "systemd-rfkill.service" # Hibernate / suspend. "hibernate.target" @@ -770,4 +770,11 @@ in }; + # FIXME: Remove these eventually. + imports = + [ (mkRenamedOptionModule [ "boot" "systemd" "sockets" ] [ "systemd" "sockets" ]) + (mkRenamedOptionModule [ "boot" "systemd" "targets" ] [ "systemd" "targets" ]) + (mkRenamedOptionModule [ "boot" "systemd" "services" ] [ "systemd" "services" ]) + ]; + } diff --git a/nixos/modules/tasks/filesystems.nix b/nixos/modules/tasks/filesystems.nix index 9dd250f140ce..dbe0c9c6e03a 100644 --- a/nixos/modules/tasks/filesystems.nix +++ b/nixos/modules/tasks/filesystems.nix @@ -174,7 +174,7 @@ in # Swap devices. ${flip concatMapStrings config.swapDevices (sw: - "${sw.device} none swap${prioOption sw.priority}\n" + "${sw.realDevice} none swap${prioOption sw.priority}\n" )} ''; diff --git a/nixos/modules/tasks/filesystems/nfs.nix b/nixos/modules/tasks/filesystems/nfs.nix index 79de6556f251..e454eca3a0e5 100644 --- a/nixos/modules/tasks/filesystems/nfs.nix +++ b/nixos/modules/tasks/filesystems/nfs.nix @@ -90,7 +90,7 @@ in serviceConfig.Type = "forking"; serviceConfig.ExecStart = '' @${pkgs.nfs-utils}/sbin/rpc.statd rpc.statd --no-notify \ - ${if cfg.statdPort != null then "-p ${toString statdPort}" else ""} + ${if cfg.statdPort != null then "-p ${toString cfg.statdPort}" else ""} ''; serviceConfig.Restart = "always"; }; diff --git a/nixos/modules/tasks/kbd.nix b/nixos/modules/tasks/kbd.nix index 69f004888f55..5969da7062b6 100644 --- a/nixos/modules/tasks/kbd.nix +++ b/nixos/modules/tasks/kbd.nix @@ -4,11 +4,13 @@ with lib; let + makeColor = n: value: "COLOR_${toString n}=${value}"; + vconsoleConf = pkgs.writeText "vconsole.conf" '' KEYMAP=${config.i18n.consoleKeyMap} FONT=${config.i18n.consoleFont} - ''; + '' + concatImapStringsSep "\n" makeColor config.i18n.consoleColors; in diff --git a/nixos/modules/tasks/network-interfaces-scripted.nix b/nixos/modules/tasks/network-interfaces-scripted.nix index d8b1592c36bb..80b7f718580e 100644 --- a/nixos/modules/tasks/network-interfaces-scripted.nix +++ b/nixos/modules/tasks/network-interfaces-scripted.nix @@ -222,21 +222,15 @@ in createVswitchDevice = n: v: nameValuePair "${n}-netdev" (let - managedInterfaces = filter (x: hasAttr x cfg.interfaces) v.interfaces; - managedInterfaceServices = concatMap (i: [ "network-addresses-${i}.service" "network-link-${i}.service" ]) managedInterfaces; - virtualInterfaces = filter (x: (hasAttr x cfg.interfaces) && cfg.interfaces.${x}.virtual) v.interfaces; - virtualInterfaceServices = concatMap (i: [ "${i}-netdev.service" ]) virtualInterfaces; deps = map subsystemDevice v.interfaces; ofRules = pkgs.writeText "vswitch-${n}-openFlowRules" v.openFlowRules; in { description = "Open vSwitch Interface ${n}"; - wantedBy = [ "network.target" "vswitchd.service" (subsystemDevice n) ]; - requires = optionals v.bindInterfaces (deps ++ managedInterfaceServices ++ virtualInterfaceServices); - requiredBy = optionals v.bindInterfaces (managedInterfaceServices ++ virtualInterfaceServices); - bindsTo = deps ++ [ "vswitchd.service" ]; + wantedBy = [ "network.target" "vswitchd.service" ] ++ deps; + bindsTo = [ "vswitchd.service" (subsystemDevice n) ] ++ deps; partOf = [ "vswitchd.service" ]; - after = [ "network-pre.target" "vswitchd.service" ] ++ deps ++ managedInterfaceServices ++ virtualInterfaceServices; - before = [ "network-interfaces.target" (subsystemDevice n) ]; + after = [ "network-pre.target" "vswitchd.service" ] ++ deps; + before = [ "network-interfaces.target" ]; serviceConfig.Type = "oneshot"; serviceConfig.RemainAfterExit = true; path = [ pkgs.iproute config.virtualisation.vswitch.package ]; diff --git a/nixos/modules/tasks/network-interfaces.nix b/nixos/modules/tasks/network-interfaces.nix index 03e647b1b1e7..ee21d735f959 100644 --- a/nixos/modules/tasks/network-interfaces.nix +++ b/nixos/modules/tasks/network-interfaces.nix @@ -426,8 +426,8 @@ in description = '' This option allows you to define Open vSwitches that connect - physical networks together. The value of this option is an - attribute set. Each attribute specifies a vswitch, with the + physical networks together. The value of this option is an + attribute set. Each attribute specifies a vswitch, with the attribute name specifying the name of the vswitch's network interface. ''; @@ -443,16 +443,6 @@ in "The physical network interfaces connected by the vSwitch."; }; - bindInterfaces = mkOption { - type = types.bool; - default = false; - description = '' - If true, then the interfaces of the vSwitch are brought 'up' and especially - also 'down' together with the vSwitch. That requires that every interfaces - is configured as a systemd network services. - ''; - }; - controllers = mkOption { type = types.listOf types.str; default = []; @@ -995,21 +985,78 @@ in services.udev.packages = mkIf (cfg.wlanInterfaces != {}) [ (pkgs.writeTextFile { - name = "99-zzz-wlanInterfaces-last.rules"; - destination = "/etc/udev/rules.d/99-zzz-wlanInterfaces-last.rules"; - text = '' - # If persistent udev device name is not used for an interface, then do not - # call systemd for that udev device name and only execute the script that - # modifies or prepares the WLAN interfaces. All other commands that would - # otherwise be executed when the udev device is added, like, e.g., the calling - # of systemd-sysctl or the activation of wpa_supplicant is disabled when the - # persistend udev device name is not usef for an interface. - ${flip (concatMapStringsSep "\n") (attrNames wlanDeviceInterfaces) (device: - let script = wlanDeviceUdevScript device (wlanListDeviceFirst device wlanDeviceInterfaces."${device}"); in - if hasAttr device cfg.wlanInterfaces - then ''ACTION=="add", SUBSYSTEM=="net", NAME=="${device}", ENV{DEVTYPE}=="wlan", RUN+="${script}"'' - else ''ACTION=="add", SUBSYSTEM=="net", NAME=="${device}", ENV{DEVTYPE}=="wlan", NAME="", TAG-="systemd", RUN:="${script}"'')} - ''; + name = "99-zzz-40-wlanInterfaces.rules"; + destination = "/etc/udev/rules.d/99-zzz-40-wlanInterfaces.rules"; + text = + let + # Collect all interfaces that are defined for a device + # as device:interface key:value pairs. + wlanDeviceInterfaces = + let + allDevices = unique (mapAttrsToList (_: v: v.device) cfg.wlanInterfaces); + interfacesOfDevice = d: filterAttrs (_: v: v.device == d) cfg.wlanInterfaces; + in + genAttrs allDevices (d: interfacesOfDevice d); + + # Convert device:interface key:value pairs into a list, and if it exists, + # place the interface which is named after the device at the beginning. + wlanListDeviceFirst = device: interfaces: + if hasAttr device interfaces + then mapAttrsToList (n: v: v//{_iName=n;}) (filterAttrs (n: _: n==device) interfaces) ++ mapAttrsToList (n: v: v//{_iName=n;}) (filterAttrs (n: _: n!=device) interfaces) + else mapAttrsToList (n: v: v // {_iName = n;}) interfaces; + + # Udev script to execute for the default WLAN interface with the persistend udev name. + # The script creates the required, new WLAN interfaces interfaces and configures the + # existing, default interface. + curInterfaceScript = device: current: new: pkgs.writeScript "udev-run-script-wlan-interfaces-${device}.sh" '' + #!${pkgs.stdenv.shell} + # Change the wireless phy device to a predictable name. + ${pkgs.iw}/bin/iw phy `${pkgs.coreutils}/bin/cat /sys/class/net/$INTERFACE/phy80211/name` set name ${device} + + # Add new WLAN interfaces + ${flip concatMapStrings new (i: '' + ${pkgs.iw}/bin/iw phy ${device} interface add ${i._iName} type managed + '')} + + # Configure the current interface + ${pkgs.iw}/bin/iw dev ${device} set type ${current.type} + ${optionalString (current.type == "mesh" && current.meshID!=null) "${pkgs.iw}/bin/iw dev ${device} set meshid ${current.meshID}"} + ${optionalString (current.type == "monitor" && current.flags!=null) "${pkgs.iw}/bin/iw dev ${device} set monitor ${current.flags}"} + ${optionalString (current.type == "managed" && current.fourAddr!=null) "${pkgs.iw}/bin/iw dev ${device} set 4addr ${if current.fourAddr then "on" else "off"}"} + ${optionalString (current.mac != null) "${pkgs.iproute}/bin/ip link set dev ${device} address ${current.mac}"} + ''; + + # Udev script to execute for a new WLAN interface. The script configures the new WLAN interface. + newInterfaceScript = new: pkgs.writeScript "udev-run-script-wlan-interfaces-${new._iName}.sh" '' + #!${pkgs.stdenv.shell} + # Configure the new interface + ${pkgs.iw}/bin/iw dev ${new._iName} set type ${new.type} + ${optionalString (new.type == "mesh" && new.meshID!=null) "${pkgs.iw}/bin/iw dev ${device} set meshid ${new.meshID}"} + ${optionalString (new.type == "monitor" && new.flags!=null) "${pkgs.iw}/bin/iw dev ${device} set monitor ${new.flags}"} + ${optionalString (new.type == "managed" && new.fourAddr!=null) "${pkgs.iw}/bin/iw dev ${device} set 4addr ${if new.fourAddr then "on" else "off"}"} + ${optionalString (new.mac != null) "${pkgs.iproute}/bin/ip link set dev ${device} address ${new.mac}"} + ''; + + # Udev attributes for systemd to name the device and to create a .device target. + systemdAttrs = n: ''NAME:="${n}", ENV{INTERFACE}:="${n}", ENV{SYSTEMD_ALIAS}:="/sys/subsystem/net/devices/${n}", TAG+="systemd"''; + in + flip (concatMapStringsSep "\n") (attrNames wlanDeviceInterfaces) (device: + let + interfaces = wlanListDeviceFirst device wlanDeviceInterfaces."${device}"; + curInterface = elemAt interfaces 0; + newInterfaces = drop 1 interfaces; + in '' + # It is important to have that rule first as overwriting the NAME attribute also prevents the + # next rules from matching. + ${flip (concatMapStringsSep "\n") (wlanListDeviceFirst device wlanDeviceInterfaces."${device}") (interface: + ''ACTION=="add", SUBSYSTEM=="net", ENV{DEVTYPE}=="wlan", ENV{INTERFACE}=="${interface._iName}", ${systemdAttrs interface._iName}, RUN+="${newInterfaceScript interface}"'')} + + # Add the required, new WLAN interfaces to the default WLAN interface with the + # persistent, default name as assigned by udev. + ACTION=="add", SUBSYSTEM=="net", ENV{DEVTYPE}=="wlan", NAME=="${device}", ${systemdAttrs curInterface._iName}, RUN+="${curInterfaceScript device curInterface newInterfaces}" + # Generate the same systemd events for both 'add' and 'move' udev events. + ACTION=="move", SUBSYSTEM=="net", ENV{DEVTYPE}=="wlan", NAME=="${device}", ${systemdAttrs curInterface._iName} + ''); }) ]; }; diff --git a/nixos/modules/virtualisation/docker.nix b/nixos/modules/virtualisation/docker.nix index 0115b972e80d..0c642bf3b816 100644 --- a/nixos/modules/virtualisation/docker.nix +++ b/nixos/modules/virtualisation/docker.nix @@ -46,12 +46,10 @@ in storageDriver = mkOption { type = types.enum ["aufs" "btrfs" "devicemapper" "overlay" "zfs"]; + default = "devicemapper"; description = '' This option determines which Docker storage driver to use. - It is required but lacks a default value as its most - suitable value will depend the filesystems available on the - host. ''; }; extraOptions = @@ -129,7 +127,7 @@ in LimitNPROC = 1048576; } // proxy_env; - path = [ pkgs.kmod ]; + path = [ pkgs.kmod ] ++ (optional (cfg.storageDriver == "zfs") pkgs.zfs); environment.MODULE_DIR = "/run/current-system/kernel-modules/lib/modules"; postStart = cfg.postStart; diff --git a/nixos/modules/virtualisation/nova-config.nix b/nixos/modules/virtualisation/nova-config.nix deleted file mode 100644 index f8239cdec519..000000000000 --- a/nixos/modules/virtualisation/nova-config.nix +++ /dev/null @@ -1,5 +0,0 @@ -{ config, pkgs, modulesPath, ... }: - -{ - imports = [ "${modulesPath}/virtualisation/nova-image.nix" ]; -} diff --git a/nixos/modules/virtualisation/nova-image.nix b/nixos/modules/virtualisation/nova-image.nix index 20ec6b024e91..44c83aee2732 100644 --- a/nixos/modules/virtualisation/nova-image.nix +++ b/nixos/modules/virtualisation/nova-image.nix @@ -1,90 +1,45 @@ +# Usage: +# $ NIXOS_CONFIG=`pwd`/nixos/modules/virtualisation/nova-image.nix nix-build '<nixpkgs/nixos>' -A config.system.build.novaImage + { config, lib, pkgs, ... }: with lib; { - imports = [ ../profiles/qemu-guest.nix ../profiles/headless.nix ./ec2-data.nix ]; - - system.build.novaImage = - pkgs.vmTools.runInLinuxVM ( - pkgs.runCommand "nova-image" - { preVM = - '' - mkdir $out - diskImage=$out/image - ${pkgs.vmTools.qemu}/bin/qemu-img create -f raw $diskImage "4G" - mv closure xchg/ - ''; - buildInputs = [ pkgs.utillinux pkgs.perl ]; - exportReferencesGraph = - [ "closure" config.system.build.toplevel ]; + system.build.novaImage = import ../../lib/make-disk-image.nix { + inherit pkgs lib config; + partitioned = true; + diskSize = 1 * 1024; + configFile = pkgs.writeText "configuration.nix" + '' + { + imports = [ <nixpkgs/nixos/modules/virtualisation/nova-image.nix> ]; } - '' - # Create a single / partition. - ${pkgs.parted}/sbin/parted /dev/vda mklabel msdos - ${pkgs.parted}/sbin/parted /dev/vda -- mkpart primary ext2 1M -1s - . /sys/class/block/vda1/uevent - mknod /dev/vda1 b $MAJOR $MINOR - - # Create an empty filesystem and mount it. - ${pkgs.e2fsprogs}/sbin/mkfs.ext3 -L nixos /dev/vda1 - ${pkgs.e2fsprogs}/sbin/tune2fs -c 0 -i 0 /dev/vda1 - mkdir /mnt - mount /dev/vda1 /mnt - - # The initrd expects these directories to exist. - mkdir /mnt/dev /mnt/proc /mnt/sys - mount --bind /proc /mnt/proc - mount --bind /dev /mnt/dev - mount --bind /sys /mnt/sys - - # Copy all paths in the closure to the filesystem. - storePaths=$(perl ${pkgs.pathsFromGraph} /tmp/xchg/closure) - - mkdir -p /mnt/nix/store - ${pkgs.rsync}/bin/rsync -av $storePaths /mnt/nix/store/ - - # Register the paths in the Nix database. - printRegistration=1 perl ${pkgs.pathsFromGraph} /tmp/xchg/closure | \ - chroot /mnt ${config.nix.package}/bin/nix-store --load-db --option build-users-group "" - - # Create the system profile to allow nixos-rebuild to work. - chroot /mnt ${config.nix.package}/bin/nix-env --option build-users-group "" \ - -p /nix/var/nix/profiles/system --set ${config.system.build.toplevel} - - # `nixos-rebuild' requires an /etc/NIXOS. - mkdir -p /mnt/etc - touch /mnt/etc/NIXOS - - # `switch-to-configuration' requires a /bin/sh - mkdir -p /mnt/bin - ln -s ${config.system.build.binsh}/bin/sh /mnt/bin/sh + ''; + }; - # Install a configuration.nix. - mkdir -p /mnt/etc/nixos - cp ${./nova-config.nix} /mnt/etc/nixos/configuration.nix - - # Generate the GRUB menu. - chroot /mnt ${config.system.build.toplevel}/bin/switch-to-configuration boot - - umount /mnt/proc /mnt/dev /mnt/sys - umount /mnt - '' - ); + imports = [ + ../profiles/qemu-guest.nix + ../profiles/headless.nix + ./ec2-data.nix + ]; fileSystems."/".device = "/dev/disk/by-label/nixos"; boot.kernelParams = [ "console=ttyS0" ]; - - boot.loader.grub.version = 2; boot.loader.grub.device = "/dev/vda"; boot.loader.grub.timeout = 0; + # Allow root logins + services.openssh.enable = true; + services.openssh.permitRootLogin = "without-password"; + # Put /tmp and /var on /ephemeral0, which has a lot more space. # Unfortunately we can't do this with the `fileSystems' option # because it has no support for creating the source of a bind # mount. Also, "move" /nix to /ephemeral0 by layering a unionfs-fuse # mount on top of it so we have a lot more space for Nix operations. + /* boot.initrd.postMountCommands = '' @@ -106,10 +61,6 @@ with lib; ''; boot.initrd.supportedFilesystems = [ "unionfs-fuse" ]; - */ + */ - # 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"; } diff --git a/nixos/modules/virtualisation/virtualbox-host.nix b/nixos/modules/virtualisation/virtualbox-host.nix index 00486df5c4ba..5fb472ebfc32 100644 --- a/nixos/modules/virtualisation/virtualbox-host.nix +++ b/nixos/modules/virtualisation/virtualbox-host.nix @@ -111,5 +111,8 @@ in }; networking.interfaces.vboxnet0.ip4 = [ { address = "192.168.56.1"; prefixLength = 24; } ]; + # Make sure NetworkManager won't assume this interface being up + # means we have internet access. + networking.networkmanager.unmanaged = ["vboxnet0"]; })]); } |