diff options
author | Eelco Dolstra <eelco.dolstra@logicblox.com> | 2014-10-07 00:09:37 +0200 |
---|---|---|
committer | Eelco Dolstra <eelco.dolstra@logicblox.com> | 2014-10-07 00:09:37 +0200 |
commit | a85dcf4a00c1ac354eda3b84209b8fa6b2133259 (patch) | |
tree | 16bbf46e3cd5d7ea259783ee8b1ea8d5c7048e0d /nixos | |
parent | 4b2ce84872a0903b9800d3ed23915f48ecedc565 (diff) | |
parent | 46a9e805efeee40d360605fa5987866ca45fed23 (diff) | |
download | nixlib-a85dcf4a00c1ac354eda3b84209b8fa6b2133259.tar nixlib-a85dcf4a00c1ac354eda3b84209b8fa6b2133259.tar.gz nixlib-a85dcf4a00c1ac354eda3b84209b8fa6b2133259.tar.bz2 nixlib-a85dcf4a00c1ac354eda3b84209b8fa6b2133259.tar.lz nixlib-a85dcf4a00c1ac354eda3b84209b8fa6b2133259.tar.xz nixlib-a85dcf4a00c1ac354eda3b84209b8fa6b2133259.tar.zst nixlib-a85dcf4a00c1ac354eda3b84209b8fa6b2133259.zip |
Merge remote-tracking branch 'origin/master' into staging
Conflicts: pkgs/development/libraries/libav/default.nix pkgs/shells/bash/bash-4.2-patches.nix pkgs/stdenv/generic/default.nix
Diffstat (limited to 'nixos')
49 files changed, 1016 insertions, 234 deletions
diff --git a/nixos/doc/manual/configuration/x-windows.xml b/nixos/doc/manual/configuration/x-windows.xml index 4008e89fceac..95e66f0c70c0 100644 --- a/nixos/doc/manual/configuration/x-windows.xml +++ b/nixos/doc/manual/configuration/x-windows.xml @@ -73,6 +73,25 @@ hardware.opengl.driSupport32Bit = true; </simplesect> +<simplesect><title>AMD Graphics Cards</title> + +<para>AMD provides a proprietary driver for its graphics cards that +has better 3D performance than the X.org drivers. It is not enabled +by default because it’s not free software. You can enable it as follows: +<programlisting> +services.xserver.videoDrivers = [ "ati_unfree" ]; +</programlisting> +You will need to reboot after enabling this driver to prevent a clash +with other kernel modules.</para> + +<para>On 64-bit systems, if you want full acceleration for 32-bit +programs such as Wine, you should also set the following: +<programlisting> +hardware.opengl.driSupport32Bit = true; +</programlisting> +</para> + +</simplesect> <simplesect><title>Touchpads</title> diff --git a/nixos/lib/test-driver/Machine.pm b/nixos/lib/test-driver/Machine.pm index e2bd3393d872..85c2bfa88e1a 100644 --- a/nixos/lib/test-driver/Machine.pm +++ b/nixos/lib/test-driver/Machine.pm @@ -482,7 +482,7 @@ sub screenshot { my $name = basename($filename); $self->nest("making screenshot ‘$name’", sub { $self->sendMonitorCommand("screendump $tmp"); - system("convert $tmp ${filename}") == 0 + system("pnmtopng $tmp > ${filename}") == 0 or die "cannot convert screenshot"; unlink $tmp; }, { image => $name } ); diff --git a/nixos/lib/testing.nix b/nixos/lib/testing.nix index 75e9c3977763..73b55ed6c060 100644 --- a/nixos/lib/testing.nix +++ b/nixos/lib/testing.nix @@ -27,7 +27,7 @@ rec { cp ${./test-driver/Logger.pm} $libDir/Logger.pm wrapProgram $out/bin/nixos-test-driver \ - --prefix PATH : "${pkgs.qemu_kvm}/bin:${pkgs.vde2}/bin:${imagemagick}/bin:${coreutils}/bin" \ + --prefix PATH : "${qemu_kvm}/bin:${vde2}/bin:${netpbm}/bin:${coreutils}/bin" \ --prefix PERL5LIB : "${lib.makePerlPath [ perlPackages.TermReadLineGnu perlPackages.XMLWriter perlPackages.IOTty ]}:$out/lib/perl5/site_perl" ''; }; @@ -41,7 +41,7 @@ rec { requiredSystemFeatures = [ "kvm" "nixos-test" ]; - buildInputs = [ pkgs.libxslt ]; + buildInputs = [ libxslt ]; buildCommand = '' @@ -153,7 +153,7 @@ rec { startAll; $client->waitForUnit("multi-user.target"); ${preBuild} - $client->succeed("env -i ${pkgs.bash}/bin/bash ${buildrunner} /tmp/xchg/saved-env >&2"); + $client->succeed("env -i ${bash}/bin/bash ${buildrunner} /tmp/xchg/saved-env >&2"); ${postBuild} $client->succeed("sync"); # flush all data before pulling the plug ''; diff --git a/nixos/modules/config/fonts/fontconfig.nix b/nixos/modules/config/fonts/fontconfig.nix index cf70ca264d6a..7516d7ddf1a6 100644 --- a/nixos/modules/config/fonts/fontconfig.nix +++ b/nixos/modules/config/fonts/fontconfig.nix @@ -47,11 +47,6 @@ with lib; </fontconfig> ''; - # FIXME: This variable is no longer needed, but we'll keep it - # around for a while for applications linked against old - # fontconfig builds. - environment.variables.FONTCONFIG_FILE = "/etc/fonts/fonts.conf"; - environment.systemPackages = [ pkgs.fontconfig ]; }; diff --git a/nixos/modules/config/pulseaudio.nix b/nixos/modules/config/pulseaudio.nix index 297b3a82d6c1..737f0abc52f0 100644 --- a/nixos/modules/config/pulseaudio.nix +++ b/nixos/modules/config/pulseaudio.nix @@ -1,4 +1,4 @@ -{ config, lib, pkgs, ... }: +{ config, lib, pkgs, pkgs_i686, ... }: with pkgs; with lib; @@ -10,6 +10,10 @@ let systemWide = cfg.enable && cfg.systemWide; nonSystemWide = cfg.enable && !cfg.systemWide; + # Forces 32bit pulseaudio and alsaPlugins to be built/supported for apps + # using 32bit alsa on 64bit linux. + enable32BitAlsaPlugins = stdenv.isx86_64 && (pkgs_i686.alsaLib != null); + ids = config.ids; uid = ids.uids.pulseaudio; @@ -28,21 +32,25 @@ let # Write an /etc/asound.conf that causes all ALSA applications to # be re-routed to the PulseAudio server through ALSA's Pulse # plugin. - alsaConf = writeText "asound.conf" '' + alsaConf = writeText "asound.conf" ('' pcm_type.pulse { - lib ${alsaPlugins}/lib/alsa-lib/libasound_module_pcm_pulse.so + libs.native = ${pkgs.alsaPlugins}/lib/alsa-lib/libasound_module_pcm_pulse.so ; + ${lib.optionalString enable32BitAlsaPlugins + "libs.32Bit = ${pkgs_i686.alsaPlugins}/lib/alsa-lib/libasound_module_pcm_pulse.so ;"} } pcm.!default { type pulse hint.description "Default Audio Device (via PulseAudio)" } ctl_type.pulse { - lib ${alsaPlugins}/lib/alsa-lib/libasound_module_ctl_pulse.so + libs.native = ${alsaPlugins}/lib/alsa-lib/libasound_module_ctl_pulse.so ; + ${lib.optionalString enable32BitAlsaPlugins + "libs.32Bit = ${pkgs_i686.alsaPlugins}/lib/alsa-lib/libasound_module_ctl_pulse.so ;"} } ctl.!default { type pulse } - ''; + ''); in { @@ -116,7 +124,10 @@ in { } (mkIf cfg.enable { - environment.systemPackages = [ cfg.package ]; + environment.systemPackages = [ + cfg.package + (lib.optional enable32BitAlsaPlugins pkgs_i686.pulseaudio) + ]; environment.etc = singleton { target = "asound.conf"; diff --git a/nixos/modules/config/users-groups.nix b/nixos/modules/config/users-groups.nix index 7d0498c10cc5..0d3273fe0539 100644 --- a/nixos/modules/config/users-groups.nix +++ b/nixos/modules/config/users-groups.nix @@ -310,9 +310,9 @@ let }) cfg.extraUsers; groups = mapAttrsToList (n: g: { inherit (g) name gid; - members = mapAttrsToList (n: u: u.name) ( + members = g.members ++ (mapAttrsToList (n: u: u.name) ( filterAttrs (n: u: elem g.name u.extraGroups) cfg.extraUsers - ); + )); }) cfg.extraGroups; }); diff --git a/nixos/modules/hardware/opengl.nix b/nixos/modules/hardware/opengl.nix index f894c830eb6c..1777c200dd11 100644 --- a/nixos/modules/hardware/opengl.nix +++ b/nixos/modules/hardware/opengl.nix @@ -46,7 +46,8 @@ in description = '' On 64-bit systems, whether to support Direct Rendering for 32-bit applications (such as Wine). This is currently only - supported for the <literal>nvidia</literal> driver and for + supported for the <literal>nvidia</literal> and + <literal>ati_unfree</literal> drivers, as well as <literal>Mesa</literal>. ''; }; @@ -104,22 +105,9 @@ in environment.sessionVariables.LD_LIBRARY_PATH = [ "/run/opengl-driver/lib" "/run/opengl-driver-32/lib" ]; - # FIXME: move this into card-specific modules. - hardware.opengl.package = mkDefault - (if elem "ati_unfree" videoDrivers then - kernelPackages.ati_drivers_x11 - else - makePackage pkgs); - + hardware.opengl.package = mkDefault (makePackage pkgs); hardware.opengl.package32 = mkDefault (makePackage pkgs_i686); - boot.extraModulePackages = - optional (elem "virtualbox" videoDrivers) kernelPackages.virtualboxGuestAdditions ++ - optional (elem "ati_unfree" videoDrivers) kernelPackages.ati_drivers_x11; - - environment.etc = - optionalAttrs (elem "ati_unfree" videoDrivers) { - "ati".source = "${kernelPackages.ati_drivers_x11}/etc/ati"; - }; + boot.extraModulePackages = optional (elem "virtualbox" videoDrivers) kernelPackages.virtualboxGuestAdditions; }; } diff --git a/nixos/modules/hardware/video/ati.nix b/nixos/modules/hardware/video/ati.nix new file mode 100644 index 000000000000..033e49d2233e --- /dev/null +++ b/nixos/modules/hardware/video/ati.nix @@ -0,0 +1,37 @@ +# This module provides the proprietary ATI X11 / OpenGL drivers. + +{ config, lib, pkgs, pkgs_i686, ... }: + +with lib; + +let + + drivers = config.services.xserver.videoDrivers; + + enabled = elem "ati_unfree" drivers; + + ati_x11 = config.boot.kernelPackages.ati_drivers_x11; + +in + +{ + + config = mkIf enabled { + + services.xserver.drivers = singleton + { name = "fglrx"; modules = [ ati_x11 ]; libPath = [ "${ati_x11}/lib" ]; }; + + hardware.opengl.package = ati_x11; + hardware.opengl.package32 = pkgs_i686.linuxPackages.ati_drivers_x11.override { libsOnly = true; kernel = null; }; + + environment.systemPackages = [ ati_x11 ]; + + boot.extraModulePackages = [ ati_x11 ]; + + boot.blacklistedKernelModules = [ "radeon" ]; + + environment.etc."ati".source = "${ati_x11}/etc/ati"; + + }; + +} diff --git a/nixos/modules/misc/ids.nix b/nixos/modules/misc/ids.nix index cdce7d1a893e..fa51f831481a 100644 --- a/nixos/modules/misc/ids.nix +++ b/nixos/modules/misc/ids.nix @@ -82,7 +82,7 @@ statsd = 69; transmission = 70; postgres = 71; - smbguest = 74; + smbguest = 74; # unused varnish = 75; datadog = 76; lighttpd = 77; @@ -150,8 +150,10 @@ zookeeper = 140; dnsmasq = 141; uhub = 142; - yandexdisk=143; - collectd=144; + yandexdisk = 143; + collectd = 144; + consul = 145; + mailpile = 146; # When adding a uid, make sure it doesn't match an existing gid. And don't use uids above 399! @@ -220,7 +222,7 @@ postgres = 71; vboxusers = 72; vboxsf = 73; - smbguest = 74; + smbguest = 74; # unused varnish = 75; datadog = 76; lighttpd = 77; @@ -272,6 +274,7 @@ riemann = 137; riemanndash = 138; uhub = 142; + mailpile = 146; # When adding a gid, make sure it doesn't match an existing uid. And don't use gids above 399! diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index 25827656608d..3db44a4d8de5 100755 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -38,6 +38,7 @@ ./hardware/pcmcia.nix ./hardware/video/bumblebee.nix ./hardware/video/nvidia.nix + ./hardware/video/ati.nix ./installer/tools/nixos-checkout.nix ./installer/tools/tools.nix ./misc/assertions.nix @@ -142,6 +143,7 @@ ./services/hardware/udev.nix ./services/hardware/udisks2.nix ./services/hardware/upower.nix + ./services/hardware/thermald.nix ./services/logging/klogd.nix ./services/logging/logcheck.nix ./services/logging/logrotate.nix @@ -157,6 +159,7 @@ ./services/mail/postfix.nix ./services/mail/spamassassin.nix #./services/misc/autofs.nix + ./services/misc/cpuminer-cryptonight.nix ./services/misc/cgminer.nix ./services/misc/dictd.nix ./services/misc/disnix.nix @@ -211,6 +214,7 @@ ./services/networking/cjdns.nix ./services/networking/cntlm.nix ./services/networking/connman.nix + ./services/networking/consul.nix ./services/networking/ddclient.nix ./services/networking/dhcpcd.nix ./services/networking/dhcpd.nix @@ -229,6 +233,7 @@ ./services/networking/iodined.nix ./services/networking/ircd-hybrid/default.nix ./services/networking/kippo.nix + ./services/networking/mailpile.nix ./services/networking/minidlna.nix ./services/networking/murmur.nix ./services/networking/nat.nix diff --git a/nixos/modules/programs/environment.nix b/nixos/modules/programs/environment.nix index 623a428fc1a6..d79aff5dc553 100644 --- a/nixos/modules/programs/environment.nix +++ b/nixos/modules/programs/environment.nix @@ -45,7 +45,6 @@ in PKG_CONFIG_PATH = [ "/lib/pkgconfig" ]; TERMINFO_DIRS = [ "/share/terminfo" ]; PERL5LIB = [ "/lib/perl5/site_perl" ]; - ALSA_PLUGIN_DIRS = [ "/lib/alsa-lib" ]; KDEDIRS = [ "" ]; STRIGI_PLUGIN_PATH = [ "/lib/strigi/" ]; QT_PLUGIN_PATH = [ "/lib/qt4/plugins" "/lib/kde4/plugins" ]; diff --git a/nixos/modules/programs/uim.nix b/nixos/modules/programs/uim.nix index 237da3415dc3..fc25ba6f9694 100644 --- a/nixos/modules/programs/uim.nix +++ b/nixos/modules/programs/uim.nix @@ -1,6 +1,6 @@ -{ config, pkgs, ... }: +{ config, pkgs, lib, ... }: -with pkgs.lib; +with lib; let cfg = config.uim; diff --git a/nixos/modules/rename.nix b/nixos/modules/rename.nix index 0ee2caa28ea4..019fbc721b17 100644 --- a/nixos/modules/rename.nix +++ b/nixos/modules/rename.nix @@ -129,5 +129,6 @@ in zipModules ([] ++ obsolete' [ "boot" "loader" "grub" "bootDevice" ] ++ obsolete' [ "boot" "initrd" "luks" "enable" ] ++ obsolete' [ "programs" "bash" "enable" ] +++ obsolete' [ "services" "samba" "defaultShare" ] ) diff --git a/nixos/modules/services/audio/mpd.nix b/nixos/modules/services/audio/mpd.nix index 53542e34b14b..e6b525c4b1ba 100644 --- a/nixos/modules/services/audio/mpd.nix +++ b/nixos/modules/services/audio/mpd.nix @@ -16,52 +16,76 @@ let sticker_file "${cfg.dataDir}/sticker.sql" log_file "syslog" user "mpd" + ${if cfg.network.host != "any" then + "bind_to_address ${cfg.network.host}" else ""} + ${if cfg.network.port != 6600 then + "port ${toString cfg.network.port}" else ""} ${cfg.extraConfig} - ''; + ''; in { ###### interface - options = { + options = { - services.mpd = { + services.mpd = { enable = mkOption { default = false; description = '' Whether to enable MPD, the music player daemon. - ''; - }; + ''; + }; musicDirectory = mkOption { default = "${cfg.dataDir}/music"; description = '' Extra configuration added to the end of MPD's configuration file, mpd.conf. - ''; - }; + ''; + }; extraConfig = mkOption { - default = ""; + default = ""; description = '' Extra directives added to to the end of MPD's configuration file, mpd.conf. Basic configuration like file location and uid/gid is added automatically to the beginning of the file. - ''; - }; + ''; + }; dataDir = mkOption { default = "/var/lib/mpd"; description = '' The directory where MPD stores its state, tag cache, playlists etc. - ''; - }; - - }; + ''; + }; + + network = { + + host = mkOption { + default = "any"; + description = '' + This setting sets the address for the daemon to listen on. Careful attention + should be paid if this is assigned to anything other then the default, any. + This setting can deny access to control of the daemon. + ''; + }; + + port = mkOption { + default = 6600; + description = '' + This setting is the TCP port that is desired for the daemon to get assigned + to. + ''; + }; + + }; + }; - }; + }; ###### implementation diff --git a/nixos/modules/services/databases/postgresql.nix b/nixos/modules/services/databases/postgresql.nix index 01c55479b2b4..de14c56f7971 100644 --- a/nixos/modules/services/databases/postgresql.nix +++ b/nixos/modules/services/databases/postgresql.nix @@ -225,14 +225,14 @@ in # Wait for PostgreSQL to be ready to accept connections. postStart = '' - while ! psql postgres -c "" 2> /dev/null; do + while ! psql --port=${toString cfg.port} postgres -c "" 2> /dev/null; do if ! kill -0 "$MAINPID"; then exit 1; fi sleep 0.1 done if test -e "${cfg.dataDir}/.first_startup"; then ${optionalString (cfg.initialScript != null) '' - cat "${cfg.initialScript}" | psql postgres + cat "${cfg.initialScript}" | psql --port=${toString cfg.port} postgres ''} rm -f "${cfg.dataDir}/.first_startup" fi diff --git a/nixos/modules/services/misc/cpuminer-cryptonight.nix b/nixos/modules/services/misc/cpuminer-cryptonight.nix new file mode 100644 index 000000000000..f31526f8d107 --- /dev/null +++ b/nixos/modules/services/misc/cpuminer-cryptonight.nix @@ -0,0 +1,66 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + cfg = config.services.cpuminer-cryptonight; + + json = builtins.toJSON ( + cfg // { + enable = null; + threads = + if cfg.threads == 0 then null else toString cfg.threads; + } + ); + + confFile = builtins.toFile "cpuminer.json" json; +in +{ + + options = { + + services.cpuminer-cryptonight = { + enable = mkOption { + type = types.bool; + default = false; + description = '' + Whether to enable the cpuminer cryptonight miner. + ''; + }; + url = mkOption { + type = types.string; + description = "URL of mining server"; + }; + user = mkOption { + type = types.string; + description = "Username for mining server"; + }; + pass = mkOption { + type = types.string; + default = "x"; + description = "Password for mining server"; + }; + threads = mkOption { + type = types.int; + default = 0; + description = "Number of miner threads, defaults to available processors"; + }; + }; + + }; + + config = mkIf config.services.cpuminer-cryptonight.enable { + + systemd.services.cpuminer-cryptonight = { + description = "Cryptonight cpuminer"; + wantedBy = [ "multi-user.target" ]; + after = [ "network.target" ]; + serviceConfig = { + ExecStart = "${pkgs.cpuminer-multi}/bin/minerd --syslog --config=${confFile}"; + User = "nobody"; + }; + }; + + }; + +} \ No newline at end of file diff --git a/nixos/modules/services/misc/gitolite.nix b/nixos/modules/services/misc/gitolite.nix index 84435f92c11d..961af48e0f86 100644 --- a/nixos/modules/services/misc/gitolite.nix +++ b/nixos/modules/services/misc/gitolite.nix @@ -5,6 +5,7 @@ with lib; let cfg = config.services.gitolite; pubkeyFile = pkgs.writeText "gitolite-admin.pub" cfg.adminPubkey; + hooks = lib.concatMapStrings (hook: "${hook} ") cfg.commonHooks; in { options = { @@ -30,6 +31,14 @@ in once, upon the first initialization of the Gitolite user. ''; }; + + commonHooks = mkOption { + type = types.listOf types.path; + default = []; + description = '' + A list of custom git hooks that get copied to <literal>~/.gitolite/hooks/common</literal>. + ''; + }; }; }; @@ -57,6 +66,10 @@ in if [ ! -d repositories ]; then gitolite setup -pk ${pubkeyFile} fi + if [ -n "${hooks}" ]; then + cp ${hooks} .gitolite/hooks/common/ + chmod +x .gitolite/hooks/common/* + fi gitolite setup # Upgrade if needed ''; }; diff --git a/nixos/modules/services/network-filesystems/samba.nix b/nixos/modules/services/network-filesystems/samba.nix index 4218b965cd9e..fd1e83d9f3e7 100644 --- a/nixos/modules/services/network-filesystems/samba.nix +++ b/nixos/modules/services/network-filesystems/samba.nix @@ -6,9 +6,6 @@ let cfg = config.services.samba; - user = "smbguest"; - group = "smbguest"; - logDir = "/var/log/samba"; privateDir = "/var/samba/private"; @@ -16,12 +13,6 @@ let setupScript = '' - if ! test -d /home/smbd ; then - mkdir -p /home/smbd - chown ${user} /home/smbd - chmod a+rwx /home/smbd - fi - if ! test -d /var/samba ; then mkdir -p /var/samba/locks /var/samba/cores/nmbd /var/samba/cores/smbd /var/samba/cores/winbindd fi @@ -37,21 +28,15 @@ let ''; configFile = pkgs.writeText "smb.conf" + (if cfg.configText != null then cfg.configText else '' [ global ] log file = ${logDir}/log.%m private dir = ${privateDir} ${optionalString cfg.syncPasswordsByPam "pam password change = true"} - ${if cfg.defaultShare.enable then '' - [default] - path = /home/smbd - read only = ${if cfg.defaultShare.writeable then "no" else "yes"} - guest ok = ${if cfg.defaultShare.guest then "yes" else "no"} - ''else ""} - ${cfg.extraConfig} - ''; + ''); # This may include nss_ldap, needed for samba if it has to use ldap. nssModulesPath = config.system.nssModules.path; @@ -149,19 +134,13 @@ in "; }; - defaultShare = { - enable = mkOption { - description = "Whether to share /home/smbd as 'default'."; - default = false; - }; - writeable = mkOption { - description = "Whether to allow write access to default share."; - default = false; - }; - guest = mkOption { - description = "Whether to allow guest access to default share."; - default = true; - }; + configText = mkOption { + type = types.nullOr types.lines; + default = null; + description = " + Verbatim contents of smb.conf. If null (default), use the + autogenerated file from NixOS instead. + "; }; securityType = mkOption { @@ -199,14 +178,6 @@ in (mkIf config.services.samba.enable { - users.extraUsers.smbguest = { - description = "Samba service user"; - group = group; - uid = config.ids.uids.smbguest; - }; - - users.extraGroups.smbguest.gid = config.ids.uids.smbguest; - system.nssModules = optional cfg.nsswins samba; systemd = { @@ -224,7 +195,7 @@ in "samba-setup" = { description = "Samba Setup Task"; script = setupScript; - unitConfig.RequiresMountsFor = "/home/smbd /var/samba /var/log/samba"; + unitConfig.RequiresMountsFor = "/var/samba /var/log/samba"; }; }; }; diff --git a/nixos/modules/services/network-filesystems/yandex-disk.nix b/nixos/modules/services/network-filesystems/yandex-disk.nix index df9626d17c92..982b6ca5ea7b 100644 --- a/nixos/modules/services/network-filesystems/yandex-disk.nix +++ b/nixos/modules/services/network-filesystems/yandex-disk.nix @@ -1,6 +1,6 @@ -{ config, pkgs, ... }: +{ config, pkgs, lib, ... }: -with pkgs.lib; +with lib; let diff --git a/nixos/modules/services/networking/atftpd.nix b/nixos/modules/services/networking/atftpd.nix index ab9f8650f0f8..47465ba948a9 100644 --- a/nixos/modules/services/networking/atftpd.nix +++ b/nixos/modules/services/networking/atftpd.nix @@ -1,8 +1,8 @@ # NixOS module for atftpd TFTP server -{ config, pkgs, ... }: +{ config, pkgs, lib, ... }: -with pkgs.lib; +with lib; let diff --git a/nixos/modules/services/networking/btsync.nix b/nixos/modules/services/networking/btsync.nix index 5d0e17c293e3..7ddc9e1045e4 100644 --- a/nixos/modules/services/networking/btsync.nix +++ b/nixos/modules/services/networking/btsync.nix @@ -57,7 +57,7 @@ let '' { "device_name": "${cfg.deviceName}", - "storage_path": "/var/lib/btsync", + "storage_path": "/var/lib/btsync/", "listening_port": ${toString cfg.listeningPort}, "use_gui": false, diff --git a/nixos/modules/services/networking/cjdns.nix b/nixos/modules/services/networking/cjdns.nix index 0519172db914..7192b8b7a0e0 100644 --- a/nixos/modules/services/networking/cjdns.nix +++ b/nixos/modules/services/networking/cjdns.nix @@ -190,7 +190,7 @@ in echo '${cjdrouteConf}' | sed \ -e "s/@CJDNS_ADMIN_PASSWORD@/$CJDNS_ADMIN_PASSWORD/g" \ -e "s/@CJDNS_PRIVATE_KEY@/$CJDNS_PRIVATE_KEY/g" \ - | ${pkgs.cjdns}/sbin/cjdroute + | ${pkgs.cjdns}/bin/cjdroute ''; serviceConfig = { @@ -201,7 +201,7 @@ in system.activationScripts.cjdns = '' grep -q "CJDNS_PRIVATE_KEY=" /etc/cjdns.keys || \ - echo "CJDNS_PRIVATE_KEY=$(${pkgs.cjdns}/sbin/makekey)" \ + echo "CJDNS_PRIVATE_KEY=$(${pkgs.cjdns}/bin/makekey)" \ >> /etc/cjdns.keys grep -q "CJDNS_ADMIN_PASSWORD=" /etc/cjdns.keys || \ diff --git a/nixos/modules/services/networking/consul.nix b/nixos/modules/services/networking/consul.nix new file mode 100644 index 000000000000..ebc836814089 --- /dev/null +++ b/nixos/modules/services/networking/consul.nix @@ -0,0 +1,166 @@ +{ config, lib, pkgs, utils, ... }: + +with lib; +let + + dataDir = "/var/lib/consul"; + cfg = config.services.consul; + + configOptions = { + data_dir = dataDir; + rejoin_after_leave = true; + } + // (if cfg.webUi then { ui_dir = "${pkgs.consul.ui}"; } else { }) + // cfg.extraConfig; + + configFiles = [ "/etc/consul.json" "/etc/consul-addrs.json" ] + ++ cfg.extraConfigFiles; + + devices = attrValues (filterAttrs (_: i: i != null) cfg.interface); + systemdDevices = flip map devices + (i: "sys-subsystem-net-devices-${utils.escapeSystemdPath i}.device"); +in +{ + options = { + + services.consul = { + + enable = mkOption { + type = types.bool; + default = false; + description = '' + Enables the consul daemon. + ''; + }; + + webUi = mkOption { + type = types.bool; + default = false; + description = '' + Enables the web interface on the consul http port. + ''; + }; + + interface = { + + advertise = mkOption { + type = types.nullOr types.str; + default = null; + description = '' + The name of the interface to pull the advertise_addr from. + ''; + }; + + bind = mkOption { + type = types.nullOr types.str; + default = null; + description = '' + The name of the interface to pull the bind_addr from. + ''; + }; + + }; + + forceIpv4 = mkOption { + type = types.bool; + default = false; + description = '' + Whether we should force the interfaces to only pull ipv4 addresses. + ''; + }; + + dropPrivileges = mkOption { + type = types.bool; + default = true; + description = '' + Whether the consul agent should be run as a non-root consul user. + ''; + }; + + extraConfig = mkOption { + default = { }; + description = '' + Extra configuration options which are serialized to json and added + to the config.json file. + ''; + }; + + extraConfigFiles = mkOption { + default = [ ]; + type = types.listOf types.str; + description = '' + Additional configuration files to pass to consul + NOTE: These will not trigger the service to be restarted when altered. + ''; + }; + + }; + + }; + + config = mkIf cfg.enable { + + users.extraUsers."consul" = { + description = "Consul agent daemon user"; + uid = config.ids.uids.consul; + }; + + environment = { + etc."consul.json".text = builtins.toJSON configOptions; + systemPackages = with pkgs; [ consul ]; + }; + + systemd.services.consul = { + wantedBy = [ "multi-user.target" ]; + after = [ "network.target" ] ++ systemdDevices; + bindsTo = systemdDevices; + restartTriggers = [ config.environment.etc."consul.json".source ]; + + serviceConfig = { + ExecStart = "@${pkgs.consul}/bin/consul consul agent" + + concatMapStrings (n: " -config-file ${n}") configFiles; + ExecStop = "${pkgs.consul}/bin/consul leave"; + ExecReload = "${pkgs.consul}/bin/consul reload"; + PermissionsStartOnly = true; + User = if cfg.dropPrivileges then "consul" else null; + }; + + path = with pkgs; [ iproute gnugrep gawk ]; + preStart = '' + mkdir -m 0700 -p ${dataDir} + chown -R consul ${dataDir} + + # Determine interface addresses + getAddrOnce () { + ip addr show dev "$1" \ + | grep 'inet${optionalString (cfg.forceIpv4) " "}.*scope global' \ + | awk -F '[ /\t]*' '{print $3}' | head -n 1 + } + getAddr () { + ADDR="$(getAddrOnce $1)" + LEFT=60 # Die after 1 minute + while [ -z "$ADDR" ]; do + sleep 1 + LEFT=$(expr $LEFT - 1) + if [ "$LEFT" -eq "0" ]; then + echo "Address lookup timed out" + exit 1 + fi + ADDR="$(getAddrOnce $1)" + done + echo "$ADDR" + } + echo "{" > /etc/consul-addrs.json + '' + + concatStrings (flip mapAttrsToList cfg.interface (name: i: + optionalString (i != null) '' + echo " \"${name}_addr\": \"$(getAddr "${i}")\"," >> /etc/consul-addrs.json + '')) + + '' + echo " \"\": \"\"" >> /etc/consul-addrs.json + echo "}" >> /etc/consul-addrs.json + ''; + }; + + }; +} diff --git a/nixos/modules/services/networking/mailpile.nix b/nixos/modules/services/networking/mailpile.nix new file mode 100644 index 000000000000..e164d41483c7 --- /dev/null +++ b/nixos/modules/services/networking/mailpile.nix @@ -0,0 +1,76 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + + cfg = config.services.mailpile; + + hostname = cfg.hostname; + port = cfg.port; + +in + +{ + + ###### interface + + options = { + + services.mailpile = { + enable = mkOption { + default = false; + description = " + Whether to enable Mailpile the mail client. + "; + }; + hostname = mkOption { + default = "localhost"; + description = "Listen to this hostname or ip."; + }; + port = mkOption { + default = "33411"; + description = "Listen on this port."; + }; + }; + + }; + + + ###### implementation + + config = mkIf config.services.mailpile.enable { + + users.extraUsers.mailpile = + { uid = config.ids.uids.mailpile; + description = "Mailpile user"; + createHome = true; + home = "/var/lib/mailpile"; + }; + + users.extraGroups.mailpile = + { gid = config.ids.gids.mailpile; + }; + + systemd.services.mailpile = + { + description = "Mailpile server."; + after = [ "network.target" ]; + wantedBy = [ "multi-user.target" ]; + serviceConfig = { + User = "mailpile"; + ExecStart = "${pkgs.mailpile}/bin/mailpile --www ${hostname}:${port} --wait"; + # mixed - first send SIGINT to main process, + # then after 2min send SIGKILL to whole group if neccessary + KillMode = "mixed"; + KillSignal = "SIGINT"; # like Ctrl+C - safe mailpile shutdown + TimeoutSec = 120; # wait 2min untill SIGKILL + }; + environment.MAILPILE_HOME = "/var/lib/mailpile/.local/share/Mailpile"; + }; + + environment.systemPackages = [ pkgs.mailpile ]; + + }; + +} diff --git a/nixos/modules/services/networking/nat.nix b/nixos/modules/services/networking/nat.nix index 35e376e7b3a6..bdb79ce2a901 100644 --- a/nixos/modules/services/networking/nat.nix +++ b/nixos/modules/services/networking/nat.nix @@ -13,38 +13,49 @@ let dest = if cfg.externalIP == null then "-j MASQUERADE" else "-j SNAT --to-source ${cfg.externalIP}"; flushNat = '' - iptables -w -t nat -F PREROUTING - iptables -w -t nat -F POSTROUTING - iptables -w -t nat -X + iptables -w -t nat -D PREROUTING -j nixos-nat-pre 2>/dev/null|| true + iptables -w -t nat -F nixos-nat-pre 2>/dev/null || true + iptables -w -t nat -X nixos-nat-pre 2>/dev/null || true + iptables -w -t nat -D POSTROUTING -j nixos-nat-post 2>/dev/null || true + iptables -w -t nat -F nixos-nat-post 2>/dev/null || true + iptables -w -t nat -X nixos-nat-post 2>/dev/null || true ''; setupNat = '' + # Create subchain where we store rules + iptables -w -t nat -N nixos-nat-pre + iptables -w -t nat -N nixos-nat-post + # We can't match on incoming interface in POSTROUTING, so # mark packets coming from the external interfaces. ${concatMapStrings (iface: '' - iptables -w -t nat -A PREROUTING \ + iptables -w -t nat -A nixos-nat-pre \ -i '${iface}' -j MARK --set-mark 1 '') cfg.internalInterfaces} # NAT the marked packets. ${optionalString (cfg.internalInterfaces != []) '' - iptables -w -t nat -A POSTROUTING -m mark --mark 1 \ + iptables -w -t nat -A nixos-nat-post -m mark --mark 1 \ -o ${cfg.externalInterface} ${dest} ''} # NAT packets coming from the internal IPs. ${concatMapStrings (range: '' - iptables -w -t nat -A POSTROUTING \ + iptables -w -t nat -A nixos-nat-post \ -s '${range}' -o ${cfg.externalInterface} ${dest} '') cfg.internalIPs} # NAT from external ports to internal ports. ${concatMapStrings (fwd: '' - iptables -w -t nat -A PREROUTING \ + iptables -w -t nat -A nixos-nat-pre \ -i ${cfg.externalInterface} -p tcp \ --dport ${builtins.toString fwd.sourcePort} \ -j DNAT --to-destination ${fwd.destination} '') cfg.forwardPorts} + + # Append our chains to the nat tables + iptables -w -t nat -A PREROUTING -j nixos-nat-pre + iptables -w -t nat -A POSTROUTING -j nixos-nat-post ''; in @@ -157,7 +168,7 @@ in extraStopCommands = flushNat; }; - systemd.services = mkIf (!config.networking.firewall.enable) { nat = { + systemd.services = mkIf (!config.networking.firewall.enable) { nat = { description = "Network Address Translation"; wantedBy = [ "network.target" ]; after = [ "network-interfaces.target" "systemd-modules-load.service" ]; diff --git a/nixos/modules/services/web-servers/lighttpd/cgit.nix b/nixos/modules/services/web-servers/lighttpd/cgit.nix index d4663781fd84..34b2fa600ad9 100644 --- a/nixos/modules/services/web-servers/lighttpd/cgit.nix +++ b/nixos/modules/services/web-servers/lighttpd/cgit.nix @@ -44,6 +44,9 @@ in # make the cgitrc manpage available environment.systemPackages = [ pkgs.cgit ]; + # declare module dependencies + services.lighttpd.enableModules = [ "mod_cgi" "mod_alias" "mod_setenv" ]; + services.lighttpd.extraConfig = '' $HTTP["url"] =~ "^/cgit" { cgi.assign = ( diff --git a/nixos/modules/services/web-servers/lighttpd/default.nix b/nixos/modules/services/web-servers/lighttpd/default.nix index fc9487ab4859..06f310eeb933 100644 --- a/nixos/modules/services/web-servers/lighttpd/default.nix +++ b/nixos/modules/services/web-servers/lighttpd/default.nix @@ -8,12 +8,54 @@ let cfg = config.services.lighttpd; - needModRedirect = cfg.gitweb.enable; - needModAlias = cfg.cgit.enable || cfg.gitweb.enable; - needModSetenv = cfg.cgit.enable || cfg.gitweb.enable; - needModCgi = cfg.cgit.enable || cfg.gitweb.enable; - needModStatus = cfg.mod_status; - needModUserdir = cfg.mod_userdir; + # List of known lighttpd modules, ordered by how the lighttpd documentation + # recommends them being imported: + # http://redmine.lighttpd.net/projects/1/wiki/Server_modulesDetails + # + # Some modules are always imported and should not appear in the config: + # disallowedModules = [ "mod_indexfile" "mod_dirlisting" "mod_staticfile" ]; + # + # Get full module list: "ls -1 $lighttpd/lib/*.so" + allKnownModules = [ + "mod_rewrite" + "mod_redirect" + "mod_alias" + "mod_access" + "mod_auth" + "mod_status" + "mod_simple_vhost" + "mod_evhost" + "mod_userdir" + "mod_secdownload" + "mod_fastcgi" + "mod_proxy" + "mod_cgi" + "mod_ssi" + "mod_compress" + "mod_usertrack" + "mod_expire" + "mod_rrdtool" + "mod_accesslog" + # Remaining list of modules, order assumed to be unimportant. + "mod_cml" + "mod_dirlisting" + "mod_evasive" + "mod_extforward" + "mod_flv_streaming" + "mod_magnet" + "mod_mysql_vhost" + "mod_rewrite" + "mod_scgi" + "mod_setenv" + "mod_trigger_b4_dl" + "mod_webdav" + ]; + + maybeModuleString = moduleName: + if elem moduleName cfg.enableModules then ''"${moduleName}"'' else ""; + + modulesIncludeString = concatStringsSep ",\n" + (filter (x: x != "") (map maybeModuleString allKnownModules)); configFile = if cfg.configText != "" then pkgs.writeText "lighttpd.conf" '' @@ -38,13 +80,7 @@ let # been loaded already. So if two services were to put the same module in # server.modules += (), that would break the lighttpd configuration. server.modules = ( - ${optionalString needModRedirect ''"mod_redirect",''} - ${optionalString needModAlias ''"mod_alias",''} - ${optionalString needModSetenv ''"mod_setenv",''} - ${optionalString needModCgi ''"mod_cgi",''} - ${optionalString needModStatus ''"mod_status",''} - ${optionalString needModUserdir ''"mod_userdir",''} - "mod_accesslog" + ${modulesIncludeString} ) # Logging (logs end up in systemd journal) @@ -117,6 +153,19 @@ in ''; }; + enableModules = mkOption { + type = types.listOf types.str; + default = [ ]; + example = [ "mod_cgi" "mod_status" ]; + description = '' + List of lighttpd modules to enable. Sub-services take care of + enabling modules as needed, so this option is mainly for when you + want to add custom stuff to + <option>services.lighttpd.extraConfig</option> that depends on a + certain module. + ''; + }; + mod_status = mkOption { default = false; type = types.uniq types.bool; @@ -152,6 +201,26 @@ in config = mkIf cfg.enable { + assertions = [ + { assertion = all (x: elem x allKnownModules) cfg.enableModules; + message = '' + One (or more) modules in services.lighttpd.enableModules are + unrecognized. + + Known modules: ${toString allKnownModules} + + services.lighttpd.enableModules: ${toString cfg.enableModules} + ''; + } + ]; + + services.lighttpd.enableModules = mkMerge + [ (mkIf cfg.mod_status [ "mod_status" ]) + (mkIf cfg.mod_userdir [ "mod_userdir" ]) + # always load mod_accesslog so that we can log to the journal + [ "mod_accesslog" ] + ]; + systemd.services.lighttpd = { description = "Lighttpd Web Server"; after = [ "network.target" ]; diff --git a/nixos/modules/services/web-servers/lighttpd/gitweb.nix b/nixos/modules/services/web-servers/lighttpd/gitweb.nix index c407a1d89778..ef7072ecba3a 100644 --- a/nixos/modules/services/web-servers/lighttpd/gitweb.nix +++ b/nixos/modules/services/web-servers/lighttpd/gitweb.nix @@ -44,6 +44,9 @@ in config = mkIf cfg.enable { + # declare module dependencies + services.lighttpd.enableModules = [ "mod_cgi" "mod_redirect" "mod_alias" "mod_setenv" ]; + services.lighttpd.extraConfig = '' $HTTP["url"] =~ "^/gitweb" { cgi.assign = ( diff --git a/nixos/modules/services/x11/desktop-managers/default.nix b/nixos/modules/services/x11/desktop-managers/default.nix index ebdb2ad06491..43e04a3076c6 100644 --- a/nixos/modules/services/x11/desktop-managers/default.nix +++ b/nixos/modules/services/x11/desktop-managers/default.nix @@ -18,7 +18,7 @@ in # determines the default: later modules (if enabled) are preferred. # E.g., if KDE is enabled, it supersedes xterm. imports = [ - ./none.nix ./xterm.nix ./xfce.nix ./kde4.nix + ./none.nix ./xterm.nix ./xfce.nix ./kde4.nix ./kde4_next.nix ./e17.nix ./e18.nix ./e19.nix ./gnome3.nix ./xbmc.nix ]; diff --git a/nixos/modules/services/x11/desktop-managers/kde4_next.nix b/nixos/modules/services/x11/desktop-managers/kde4_next.nix new file mode 100644 index 000000000000..568094358ba0 --- /dev/null +++ b/nixos/modules/services/x11/desktop-managers/kde4_next.nix @@ -0,0 +1,163 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + + xcfg = config.services.xserver; + cfg = xcfg.desktopManager.kde4_next; + xorg = pkgs.xorg; + kde = pkgs.kde4_next; + + # Disable Nepomuk and Strigi by default. As of KDE 4.7, they don't + # really work very well (e.g. searching files often fails to find + # files), segfault sometimes and consume significant resources. + # They can be re-enabled in the KDE System Settings under "Desktop + # Search". + nepomukConfig = pkgs.writeTextFile + { name = "nepomuk-config"; + destination = "/share/config/nepomukserverrc"; + text = + '' + [Basic Settings] + Start Nepomuk=false + + [Service-nepomukstrigiservice] + autostart=false + ''; + }; + + phononBackends = { + gstreamer = [ + pkgs.phonon_backend_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.gst_all.gstreamer # needed? + ]; + + vlc = [pkgs.phonon_backend_vlc]; + }; + + phononBackendPackages = flip concatMap cfg.phononBackends + (name: attrByPath [name] (throw "unknown phonon backend `${name}'") phononBackends); + +in + +{ + options = { + + services.xserver.desktopManager.kde4_next = { + enable = mkOption { + type = types.bool; + default = false; + description = "Enable the KDE 4 desktop environment."; + }; + + phononBackends = mkOption { + type = types.listOf types.str; + default = ["gstreamer"]; + example = ["gstreamer" "vlc"]; + description = "Which phonon multimedia backend kde should use"; + }; + }; + + }; + + + config = mkIf (xcfg.enable && cfg.enable) { + + # If KDE 4 is enabled, make it the default desktop manager (unless + # overridden by the user's configuration). + # !!! doesn't work yet ("Multiple definitions. Only one is allowed + # for this option.") + # services.xserver.desktopManager.default = mkOverride 900 "kde4"; + + services.xserver.desktopManager.session = singleton + { name = "kde4_next"; + bgSupport = true; + start = + '' + # The KDE icon cache is supposed to update itself + # automatically, but it uses the timestamp on the icon + # theme directory as a trigger. Since in Nix the + # timestamp is always the same, this doesn't work. So as + # a workaround, nuke the icon cache on login. This isn't + # perfect, since it may require logging out after + # installing new applications to update the cache. + # See http://lists-archives.org/kde-devel/26175-what-when-will-icon-cache-refresh.html + rm -fv $HOME/.kde/cache-*/icon-cache.kcache + + # Qt writes a weird ‘libraryPath’ line to + # ~/.config/Trolltech.conf that causes the KDE plugin + # paths of previous KDE invocations to be searched. + # Obviously using mismatching KDE libraries is potentially + # disastrous, so here we nuke references to the Nix store + # in Trolltech.conf. A better solution would be to stop + # Qt from doing this wackiness in the first place. + if [ -e $HOME/.config/Trolltech.conf ]; then + sed -e '/nix\\store\|nix\/store/ d' -i $HOME/.config/Trolltech.conf + fi + + # Start KDE. + exec ${kde.kdebase_workspace}/bin/startkde + ''; + }; + + security.setuidOwners = singleton + { program = "kcheckpass"; + source = "${kde.kdebase_workspace}/lib/kde4/libexec/kcheckpass"; + owner = "root"; + group = "root"; + setuid = true; + }; + + environment.systemPackages = + [ kde.kdelibs + + kde.kde_baseapps # Splitted kdebase + kde.kde_workspace + kde.kde_runtime + kde.konsole + kde.kate + + kde.kde_wallpapers # contains kdm's default background + kde.oxygen_icons + pkgs.virtuoso # to enable Nepomuk to find Virtuoso + + # Starts KDE's Polkit authentication agent. + kde.polkit_kde_agent + + # Miscellaneous runtime dependencies. + kde.qt4 # needed for qdbus + pkgs.shared_mime_info + xorg.xmessage # so that startkde can show error messages + xorg.xset # used by startkde, non-essential + xorg.xauth # used by kdesu + pkgs.shared_desktop_ontologies # used by nepomuk + pkgs.strigi # used by nepomuk + pkgs.mysql # used by akonadi + ] + ++ lib.optional config.hardware.pulseaudio.enable kde.kmix # Perhaps this should always be enabled + ++ lib.optional config.hardware.bluetooth.enable kde.bluedevil + ++ lib.optional config.networking.networkmanager.enable kde.networkmanagement + ++ [ nepomukConfig ] ++ phononBackendPackages; + + environment.pathsToLink = [ "/share" ]; + + environment.etc = singleton + { source = "${pkgs.xkeyboard_config}/etc/X11/xkb"; + target = "X11/xkb"; + }; + + # Enable helpful DBus services. + services.udisks2.enable = true; + services.upower.enable = config.powerManagement.enable; + + security.pam.services.kde = { allowNullPassword = true; }; + + }; + +} diff --git a/nixos/modules/services/x11/display-managers/lightdm.nix b/nixos/modules/services/x11/display-managers/lightdm.nix index f8ce06738fee..98e3fd6d6a5d 100644 --- a/nixos/modules/services/x11/display-managers/lightdm.nix +++ b/nixos/modules/services/x11/display-managers/lightdm.nix @@ -28,11 +28,10 @@ let buildCommand = '' mkdir -p $out/gtk-3.0/ - # This wrapper ensures that we actually get fonts + # This wrapper ensures that we actually get ?? (fonts should be OK now) makeWrapper ${pkgs.lightdm_gtk_greeter}/sbin/lightdm-gtk-greeter \ $out/greeter \ --set XDG_DATA_DIRS ${pkgs.gnome2.gnome_icon_theme}/share \ - --set FONTCONFIG_FILE /etc/fonts/fonts.conf \ --set XDG_CONFIG_HOME $out/ # We need this to ensure that it actually tries to find icons from gnome-icon-theme diff --git a/nixos/modules/services/x11/window-managers/afterstep.nix b/nixos/modules/services/x11/window-managers/afterstep.nix new file mode 100644 index 000000000000..395dabb86b5e --- /dev/null +++ b/nixos/modules/services/x11/window-managers/afterstep.nix @@ -0,0 +1,28 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + cfg = config.services.xserver.windowManager.afterstep; +in +{ + ###### interface + options = { + services.xserver.windowManager.afterstep.enable = mkOption { + default = false; + description = "Enable the Afterstep window manager."; + }; + }; + + ###### implementation + config = mkIf cfg.enable { + services.xserver.windowManager.session = singleton { + name = "afterstep"; + start = '' + ${pkgs.afterstep}/bin/afterstep & + waitPID=$! + ''; + }; + environment.systemPackages = [ pkgs.afterstep ]; + }; +} diff --git a/nixos/modules/services/x11/window-managers/ratpoison.nix b/nixos/modules/services/x11/window-managers/ratpoison.nix new file mode 100644 index 000000000000..c203c35cd1b7 --- /dev/null +++ b/nixos/modules/services/x11/window-managers/ratpoison.nix @@ -0,0 +1,28 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + cfg = config.services.xserver.windowManager.ratpoison; +in +{ + ###### interface + options = { + services.xserver.windowManager.ratpoison.enable = mkOption { + default = false; + description = "Enable the Ratpoison window manager."; + }; + }; + + ###### implementation + config = mkIf cfg.enable { + services.xserver.windowManager.session = singleton { + name = "ratpoison"; + start = '' + ${pkgs.ratpoison}/bin/ratpoison & + waitPID=$! + ''; + }; + environment.systemPackages = [ pkgs.ratpoison ]; + }; +} diff --git a/nixos/modules/services/x11/window-managers/windowmaker.nix b/nixos/modules/services/x11/window-managers/windowmaker.nix new file mode 100644 index 000000000000..27cedb7da0ca --- /dev/null +++ b/nixos/modules/services/x11/window-managers/windowmaker.nix @@ -0,0 +1,28 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + cfg = config.services.xserver.windowManager.windowmaker; +in +{ + ###### interface + options = { + services.xserver.windowManager.windowmaker.enable = mkOption { + default = false; + description = "Enable the Windowmaker window manager."; + }; + }; + + ###### implementation + config = mkIf cfg.enable { + services.xserver.windowManager.session = singleton { + name = "windowmaker"; + start = '' + ${pkgs.windowmaker}/bin/wmaker & + waitPID=$! + ''; + }; + environment.systemPackages = [ pkgs.windowmaker ]; + }; +} diff --git a/nixos/modules/services/x11/xserver.nix b/nixos/modules/services/x11/xserver.nix index 21eaf6bb6b76..f911d3c81f90 100644 --- a/nixos/modules/services/x11/xserver.nix +++ b/nixos/modules/services/x11/xserver.nix @@ -13,7 +13,6 @@ let # Map video driver names to driver packages. FIXME: move into card-specific modules. knownVideoDrivers = { - ati_unfree = { modules = [ kernelPackages.ati_drivers_x11 ]; driverName = "fglrx"; }; nouveau = { modules = [ pkgs.xf86_video_nouveau ]; }; unichrome = { modules = [ pkgs.xorgVideoUnichrome ]; }; virtualbox = { modules = [ kernelPackages.virtualboxGuestAdditions ]; driverName = "vboxvideo"; }; @@ -400,8 +399,8 @@ in services.xserver.drivers = flip concatMap cfg.videoDrivers (name: let driver = attrByPath [name] - (if (hasAttr ("xf86video" + name) xorg) - then { modules = [(getAttr ("xf86video" + name) xorg) ]; } + (if xorg ? ${"xf86video" + name} + then { modules = [xorg.${"xf86video" + name}]; } else null) knownVideoDrivers; in optional (driver != null) ({ inherit name; driverName = name; } // driver)); @@ -444,8 +443,7 @@ in pkgs.xterm pkgs.xdg_utils ] - ++ optional (elem "virtualbox" cfg.videoDrivers) xorg.xrefresh - ++ optional (elem "ati_unfree" cfg.videoDrivers) kernelPackages.ati_drivers_x11; + ++ optional (elem "virtualbox" cfg.videoDrivers) xorg.xrefresh; environment.pathsToLink = [ "/etc/xdg" "/share/xdg" "/share/applications" "/share/icons" "/share/pixmaps" ]; @@ -460,13 +458,11 @@ in restartIfChanged = false; environment = - { FONTCONFIG_FILE = "/etc/fonts/fonts.conf"; # !!! cleanup + { XKB_BINDIR = "${xorg.xkbcomp}/bin"; # Needed for the Xkb extension. XORG_DRI_DRIVER_PATH = "/run/opengl-driver/lib/dri"; # !!! Depends on the driver selected at runtime. LD_LIBRARY_PATH = concatStringsSep ":" ( [ "${xorg.libX11}/lib" "${xorg.libXext}/lib" ] - ++ optionals (elem "ati_unfree" cfg.videoDrivers) - [ "${kernelPackages.ati_drivers_x11}/lib" "${kernelPackages.ati_drivers_x11}/X11R6/lib64/modules/linux" ] ++ concatLists (catAttrs "libPath" cfg.drivers)); } // cfg.displayManager.job.environment; diff --git a/nixos/modules/system/boot/loader/grub/grub.nix b/nixos/modules/system/boot/loader/grub/grub.nix index c46b3ba705ad..3ea00e40c3b3 100644 --- a/nixos/modules/system/boot/loader/grub/grub.nix +++ b/nixos/modules/system/boot/loader/grub/grub.nix @@ -234,6 +234,15 @@ in ''; }; + enableCryptodisk = mkOption { + default = false; + type = types.bool; + description = '' + Enable support for encrypted partitions. Grub should automatically + unlock the correct encrypted partition and look for filesystems. + ''; + }; + }; }; @@ -261,6 +270,7 @@ in throw "You must set the option ‘boot.loader.grub.device’ to make the system bootable." else "PERL5LIB=${makePerlPath (with pkgs.perlPackages; [ FileSlurp XMLLibXML XMLSAX ])} " + + (if cfg.enableCryptodisk then "GRUB_ENABLE_CRYPTODISK=y " else "") + "${pkgs.perl}/bin/perl ${./install-grub.pl} ${grubConfig}"; system.build.grub = grub; diff --git a/nixos/modules/system/boot/loader/grub/install-grub.pl b/nixos/modules/system/boot/loader/grub/install-grub.pl index eef81d81484e..981b60c004c2 100644 --- a/nixos/modules/system/boot/loader/grub/install-grub.pl +++ b/nixos/modules/system/boot/loader/grub/install-grub.pl @@ -199,7 +199,10 @@ sub GrubFs { return Grub->new(path => $path, search => $search); } my $grubBoot = GrubFs("/boot"); -my $grubStore = GrubFs("/nix/store"); +my $grubStore; +if ($copyKernels == 0) { + $grubStore = GrubFs("/nix/store"); +} # Generate the header. my $conf .= "# Automatically generated. DO NOT EDIT THIS FILE!\n"; diff --git a/nixos/modules/system/boot/stage-1-init.sh b/nixos/modules/system/boot/stage-1-init.sh index 73fc6ce543cf..f14f105ef239 100644 --- a/nixos/modules/system/boot/stage-1-init.sh +++ b/nixos/modules/system/boot/stage-1-init.sh @@ -168,9 +168,24 @@ if test -e /sys/power/tuxonice/resume; then fi fi -if test -n "@resumeDevice@" -a -e /sys/power/resume -a -e /sys/power/disk; then - echo "@resumeDevice@" > /sys/power/resume 2> /dev/null || echo "failed to resume..." - echo shutdown > /sys/power/disk +if test -e /sys/power/resume -a -e /sys/power/disk; then + if test -n "@resumeDevice@"; then + resumeDev="@resumeDevice@" + else + for sd in @resumeDevices@; do + # Try to detect resume device. According to Ubuntu bug: + # https://bugs.launchpad.net/ubuntu/+source/pm-utils/+bug/923326/comments/1 + # When there are multiple swap devices, we can't know where will hibernate + # image reside. We can check all of them for swsuspend blkid. + if [ "$(udevadm info -q property "$sd" | sed -n 's/^ID_FS_TYPE=//p')" = "swsuspend" ]; then + resumeDev="$sd" + break + fi + done + fi + if test -n "$resumeDev"; then + echo "$resumeDev" > /sys/power/resume 2> /dev/null || echo "failed to resume..." + fi fi diff --git a/nixos/modules/system/boot/stage-1.nix b/nixos/modules/system/boot/stage-1.nix index 6977880fa284..1ec11e70e845 100644 --- a/nixos/modules/system/boot/stage-1.nix +++ b/nixos/modules/system/boot/stage-1.nix @@ -181,6 +181,9 @@ let inherit (config.boot.initrd) checkJournalingFS 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); + fsInfo = let f = fs: [ fs.mountPoint (if fs.device != null then fs.device else "/dev/disk/by-label/${fs.label}") fs.fsType fs.options ]; in pkgs.writeText "initrd-fsinfo" (concatStringsSep "\n" (concatMap f fileSystems)); @@ -220,13 +223,14 @@ in options = { boot.resumeDevice = mkOption { - type = types.nullOr types.str; - default = null; - example = "8:2"; + type = types.str; + default = ""; + example = "/dev/sda3"; description = '' - Device for manual resume attempt during boot, specified using - the device's major and minor number as - <literal><replaceable>major</replaceable>:<replaceable>minor</replaceable></literal>. + Device for manual resume attempt during boot. This should be used primarily + if you want to resume from file. Specify here the device where the file + resides. You should also use <varname>boot.kernelParams</varname> to specify + <literal><replaceable>resume_offset</replaceable></literal>. ''; }; diff --git a/nixos/modules/system/boot/systemd-unit-options.nix b/nixos/modules/system/boot/systemd-unit-options.nix index 48c3564ba078..07f3cb9e952c 100644 --- a/nixos/modules/system/boot/systemd-unit-options.nix +++ b/nixos/modules/system/boot/systemd-unit-options.nix @@ -6,8 +6,8 @@ let checkService = v: let assertValueOneOf = name: values: attr: - let val = getAttr name attr; - in optional ( hasAttr name attr && !elem val values) "Systemd service field `${name}' cannot have value `${val}'."; + let val = attr.${name}; + in optional (attr ? ${name} && !elem val values) "Systemd service field `${name}' cannot have value `${val}'."; checkType = assertValueOneOf "Type" ["simple" "forking" "oneshot" "dbus" "notify" "idle"]; checkRestart = assertValueOneOf "Restart" ["no" "on-success" "on-failure" "on-abort" "always"]; errors = concatMap (c: c v) [checkType checkRestart]; diff --git a/nixos/modules/system/boot/systemd.nix b/nixos/modules/system/boot/systemd.nix index 13d6c6d7990a..e39f71cb7f7c 100644 --- a/nixos/modules/system/boot/systemd.nix +++ b/nixos/modules/system/boot/systemd.nix @@ -322,7 +322,7 @@ let [Service] ${let env = cfg.globalEnvironment // def.environment; in concatMapStrings (n: - let s = "Environment=\"${n}=${getAttr n env}\"\n"; + let s = "Environment=\"${n}=${env.${n}}\"\n"; in if stringLength s >= 2048 then throw "The value of the environment variable ‘${n}’ in systemd service ‘${name}.service’ is too long." else s) (attrNames env)} ${if def.reloadIfChanged then '' X-ReloadIfChanged=true diff --git a/nixos/modules/tasks/network-interfaces.nix b/nixos/modules/tasks/network-interfaces.nix index 97b37b0714cd..6f6000cf3397 100644 --- a/nixos/modules/tasks/network-interfaces.nix +++ b/nixos/modules/tasks/network-interfaces.nix @@ -345,10 +345,20 @@ in interfaces = mkOption { example = [ "enp4s0f0" "enp4s0f1" "wlan0" ]; - type = types.listOf types.string; + type = types.listOf types.str; description = "The interfaces to bond together"; }; + lacp_rate = mkOption { + default = null; + example = "fast"; + type = types.nullOr types.str; + description = '' + Option specifying the rate in which we'll ask our link partner + to transmit LACPDU packets in 802.3ad mode. + ''; + }; + miimon = mkOption { default = null; example = 100; @@ -364,7 +374,7 @@ in mode = mkOption { default = null; example = "active-backup"; - type = types.nullOr types.string; + type = types.nullOr types.str; description = '' The mode which the bond will be running. The default mode for the bonding driver is balance-rr, optimizing for throughput. @@ -373,6 +383,16 @@ in ''; }; + xmit_hash_policy = mkOption { + default = null; + example = "layer2+3"; + type = types.nullOr types.str; + description = '' + Selects the transmit hash policy to use for slave selection in + balance-xor, 802.3ad, and tlb modes. + ''; + }; + }; }; @@ -758,9 +778,11 @@ in path = [ pkgs.ifenslave pkgs.iproute ]; script = '' # Remove Dead Interfaces - ip link show "${n}" >/dev/null 2>&1 && ip link delete "${n}" + ip link set "${n}" down >/dev/null 2>&1 || true + ifenslave -d "${n}" >/dev/null 2>&1 || true + ip link del "${n}" >/dev/null 2>&1 || true - ip link add "${n}" type bond + ip link add name "${n}" type bond # !!! There must be a better way to wait for the interface while [ ! -d /sys/class/net/${n} ]; do sleep 0.1; done; @@ -770,17 +792,21 @@ in "echo ${toString v.miimon} > /sys/class/net/${n}/bonding/miimon"} ${optionalString (v.mode != null) "echo \"${v.mode}\" > /sys/class/net/${n}/bonding/mode"} + ${optionalString (v.lacp_rate != null) + "echo \"${v.lacp_rate}\" > /sys/class/net/${n}/bonding/lacp_rate"} + ${optionalString (v.xmit_hash_policy != null) + "echo \"${v.xmit_hash_policy}\" > /sys/class/net/${n}/bonding/xmit_hash_policy"} - # Bring up the bridge and enslave the specified interfaces + # Bring up the bond and enslave the specified interfaces ip link set "${n}" up ${flip concatMapStrings v.interfaces (i: '' ifenslave "${n}" "${i}" '')} ''; postStop = '' - ip link set "${n}" down - ifenslave -d "${n}" - ip link delete "${n}" + ip link set "${n}" down >dev/null 2>&1 || true + ifenslave -d "${n}" >/dev/null 2>&1 || true + ip link del "${n}" >/dev/null 2>&1 || true ''; }); @@ -798,7 +824,7 @@ in script = '' # Remove Dead Interfaces ip link show "${n}" >/dev/null 2>&1 && ip link delete "${n}" - ip link add "${n}" type sit \ + ip link add name "${n}" type sit \ ${optionalString (v.remote != null) "remote \"${v.remote}\""} \ ${optionalString (v.local != null) "local \"${v.local}\""} \ ${optionalString (v.ttl != null) "ttl ${toString v.ttl}"} \ @@ -824,7 +850,7 @@ in script = '' # Remove Dead Interfaces ip link show "${n}" >/dev/null 2>&1 && ip link delete "${n}" - ip link add link "${v.interface}" "${n}" type vlan id "${toString v.id}" + ip link add link "${v.interface}" name "${n}" type vlan id "${toString v.id}" ip link set "${n}" up ''; postStop = '' diff --git a/nixos/release-combined.nix b/nixos/release-combined.nix index 3a458f5e860b..ca7ca2afb65f 100644 --- a/nixos/release-combined.nix +++ b/nixos/release-combined.nix @@ -1,3 +1,7 @@ +# This jobset defines the main NixOS channels (such as nixos-unstable +# and nixos-14.04). The channel is updated every time the ‘tested’ job +# succeeds, and all other jobs have finished (they may fail). + { nixpkgs ? { outPath = ./..; revCount = 56789; shortRev = "gfedcba"; } , stableBranch ? false , supportedSystems ? [ "x86_64-linux" "i686-linux" ] @@ -18,7 +22,7 @@ let in rec { nixos = removeMaintainers (import ./release.nix { - inherit stableBranch; + inherit stableBranch supportedSystems; nixpkgs = nixpkgsSrc; }); @@ -30,12 +34,13 @@ in rec { tested = pkgs.releaseTools.aggregate { name = "nixos-${nixos.channel.version}"; meta = { - description = "Release-critical builds for the NixOS unstable channel"; - maintainers = [ pkgs.lib.maintainers.eelco pkgs.lib.maintainers.shlevy ]; + description = "Release-critical builds for the NixOS channel"; + maintainers = [ pkgs.lib.maintainers.eelco ]; }; constituents = - let all = x: map (p: x.${p}) supportedSystems; in + let all = x: map (system: x.${system}) supportedSystems; in [ nixos.channel + (all nixos.dummy) (all nixos.manual) (all nixos.iso_minimal) @@ -61,7 +66,8 @@ in rec { (all nixos.tests.kde4) (all nixos.tests.login) (all nixos.tests.misc) - (all nixos.tests.nat) + (all nixos.tests.nat.firewall) + (all nixos.tests.nat.standalone) (all nixos.tests.nfs3) (all nixos.tests.openssh) (all nixos.tests.printing) diff --git a/nixos/release.nix b/nixos/release.nix index b3039afb18c1..7337ad7e3f45 100644 --- a/nixos/release.nix +++ b/nixos/release.nix @@ -11,7 +11,7 @@ let forAllSystems = pkgs.lib.genAttrs supportedSystems; - scrubDrv = drv: let res = { inherit (drv) drvPath outPath type name; outputName = "out"; out = res; }; in res; + scrubDrv = drv: let res = { inherit (drv) drvPath outPath type name system meta; outputName = "out"; out = res; }; in res; callTest = fn: args: forAllSystems (system: scrubDrv (import fn ({ inherit system; } // args))); @@ -186,6 +186,16 @@ in rec { ); + # Ensure that all packages used by the minimal NixOS config end up in the channel. + dummy = forAllSystems (system: pkgs.runCommand "dummy" + { propagatedBuildInputs = (import lib/eval-config.nix { + inherit system; + modules = lib.singleton ({ config, pkgs, ... }: { }); + }).config.environment.systemPackages; + } + "mkdir $out; fixupPhase"); + + # Provide a tarball that can be unpacked into an SD card, and easily # boot that system from uboot (like for the sheevaplug). # The pc variant helps preparing the expression for the system tarball @@ -244,7 +254,8 @@ in rec { tests.munin = callTest tests/munin.nix {}; tests.mysql = callTest tests/mysql.nix {}; tests.mysqlReplication = callTest tests/mysql-replication.nix {}; - tests.nat = callTest tests/nat.nix {}; + tests.nat.firewall = callTest tests/nat.nix { withFirewall = true; }; + tests.nat.standalone = callTest tests/nat.nix { withFirewall = false; }; tests.nfs3 = callTest tests/nfs.nix { version = 3; }; tests.nsd = callTest tests/nsd.nix {}; tests.openssh = callTest tests/openssh.nix {}; diff --git a/nixos/tests/installer.nix b/nixos/tests/installer.nix index 3e29bc2a45b0..138a81ad8075 100644 --- a/nixos/tests/installer.nix +++ b/nixos/tests/installer.nix @@ -6,13 +6,13 @@ with pkgs.lib; let - # Build the ISO. This is the regular installation CD but with test - # instrumentation. + # Build the ISO. This is the regular minimal installation CD but + # with test instrumentation. iso = (import ../lib/eval-config.nix { inherit system; modules = - [ ../modules/installer/cd-dvd/installation-cd-graphical.nix + [ ../modules/installer/cd-dvd/installation-cd-minimal.nix ../modules/testing/test-instrumentation.nix { key = "serial"; boot.loader.grub.timeout = mkOverride 0 0; @@ -43,6 +43,7 @@ let { imports = [ ./hardware-configuration.nix <nixpkgs/nixos/modules/testing/test-instrumentation.nix> + <nixpkgs/nixos/modules/profiles/minimal.nix> ]; ${if useEFI then '' diff --git a/nixos/tests/jenkins.nix b/nixos/tests/jenkins.nix index f0d3139d902c..3f4a197ebcc4 100644 --- a/nixos/tests/jenkins.nix +++ b/nixos/tests/jenkins.nix @@ -17,7 +17,7 @@ import ./make-test.nix { users.extraUsers.jenkins.extraGroups = [ "users" ]; - systemd.services.jenkins.unitConfig.TimeoutSec = 240; + systemd.services.jenkins.serviceConfig.TimeoutStartSec = "3min"; }; slave = diff --git a/nixos/tests/kde4.nix b/nixos/tests/kde4.nix index 90c37397821e..fcc5101feb3d 100644 --- a/nixos/tests/kde4.nix +++ b/nixos/tests/kde4.nix @@ -32,7 +32,7 @@ import ./make-test.nix ({ pkgs, ... }: { pkgs.kde4.kdegraphics pkgs.kde4.kdeutils pkgs.kde4.kdegames - pkgs.kde4.kdeedu + #pkgs.kde4.kdeedu pkgs.kde4.kdeaccessibility pkgs.kde4.kdeadmin pkgs.kde4.kdenetwork diff --git a/nixos/tests/munin.nix b/nixos/tests/munin.nix index d18abd68ee0e..1e51453df83b 100644 --- a/nixos/tests/munin.nix +++ b/nixos/tests/munin.nix @@ -18,7 +18,7 @@ import ./make-test.nix { ''; }; }; - systemd.services.munin-node.unitConfig.TimeoutSec = 240; + systemd.services.munin-node.serviceConfig.TimeoutStartSec = "3min"; }; }; diff --git a/nixos/tests/nat.nix b/nixos/tests/nat.nix index 87ed974edad3..c4d2614f7852 100644 --- a/nixos/tests/nat.nix +++ b/nixos/tests/nat.nix @@ -3,77 +3,81 @@ # client on the inside network, a server on the outside network, and a # router connected to both that performs Network Address Translation # for the client. +import ./make-test.nix ({ withFirewall, ... }: + let + unit = if withFirewall then "firewall" else "nat"; + in + { + name = "nat${if withFirewall then "WithFirewall" else "Standalone"}"; -import ./make-test.nix { - name = "nat"; + nodes = + { client = + { config, pkgs, nodes, ... }: + { virtualisation.vlans = [ 1 ]; + networking.firewall.allowPing = true; + networking.defaultGateway = + (pkgs.lib.head nodes.router.config.networking.interfaces.eth2.ip4).address; + }; - nodes = - { client = - { config, pkgs, nodes, ... }: - { virtualisation.vlans = [ 1 ]; - networking.firewall.allowPing = true; - networking.defaultGateway = - (pkgs.lib.head nodes.router.config.networking.interfaces.eth2.ip4).address; - }; + router = + { config, pkgs, ... }: + { virtualisation.vlans = [ 2 1 ]; + networking.firewall.enable = withFirewall; + networking.firewall.allowPing = true; + networking.nat.enable = true; + networking.nat.internalIPs = [ "192.168.1.0/24" ]; + networking.nat.externalInterface = "eth1"; + }; - router = - { config, pkgs, ... }: - { virtualisation.vlans = [ 2 1 ]; - networking.firewall.allowPing = true; - networking.nat.enable = true; - networking.nat.internalIPs = [ "192.168.1.0/24" ]; - networking.nat.externalInterface = "eth1"; - }; + server = + { config, pkgs, ... }: + { virtualisation.vlans = [ 2 ]; + networking.firewall.enable = false; + services.httpd.enable = true; + services.httpd.adminAddr = "foo@example.org"; + services.vsftpd.enable = true; + services.vsftpd.anonymousUser = true; + }; + }; - server = - { config, pkgs, ... }: - { virtualisation.vlans = [ 2 ]; - networking.firewall.enable = false; - services.httpd.enable = true; - services.httpd.adminAddr = "foo@example.org"; - services.vsftpd.enable = true; - services.vsftpd.anonymousUser = true; - }; - }; + testScript = + { nodes, ... }: + '' + startAll; - testScript = - { nodes, ... }: - '' - startAll; + # The router should have access to the server. + $server->waitForUnit("network.target"); + $server->waitForUnit("httpd"); + $router->waitForUnit("network.target"); + $router->succeed("curl --fail http://server/ >&2"); - # The router should have access to the server. - $server->waitForUnit("network.target"); - $server->waitForUnit("httpd"); - $router->waitForUnit("network.target"); - $router->succeed("curl --fail http://server/ >&2"); + # The client should be also able to connect via the NAT router. + $router->waitForUnit("${unit}"); + $client->waitForUnit("network.target"); + $client->succeed("curl --fail http://server/ >&2"); + $client->succeed("ping -c 1 server >&2"); - # The client should be also able to connect via the NAT router. - $router->waitForUnit("nat"); - $client->waitForUnit("network.target"); - $client->succeed("curl --fail http://server/ >&2"); - $client->succeed("ping -c 1 server >&2"); + # Test whether passive FTP works. + $server->waitForUnit("vsftpd"); + $server->succeed("echo Hello World > /home/ftp/foo.txt"); + $client->succeed("curl -v ftp://server/foo.txt >&2"); - # Test whether passive FTP works. - $server->waitForUnit("vsftpd"); - $server->succeed("echo Hello World > /home/ftp/foo.txt"); - $client->succeed("curl -v ftp://server/foo.txt >&2"); + # Test whether active FTP works. + $client->succeed("curl -v -P - ftp://server/foo.txt >&2"); - # Test whether active FTP works. - $client->succeed("curl -v -P - ftp://server/foo.txt >&2"); + # Test ICMP. + $client->succeed("ping -c 1 router >&2"); + $router->succeed("ping -c 1 client >&2"); - # Test ICMP. - $client->succeed("ping -c 1 router >&2"); - $router->succeed("ping -c 1 client >&2"); + # If we turn off NAT, the client shouldn't be able to reach the server. + $router->succeed("iptables -t nat -D PREROUTING -j nixos-nat-pre"); + $router->succeed("iptables -t nat -D POSTROUTING -j nixos-nat-post"); + $client->fail("curl --fail --connect-timeout 5 http://server/ >&2"); + $client->fail("ping -c 1 server >&2"); - # If we turn off NAT, the client shouldn't be able to reach the server. - $router->stopJob("nat"); - $client->fail("curl --fail --connect-timeout 5 http://server/ >&2"); - $client->fail("ping -c 1 server >&2"); - - # And make sure that restarting the NAT job works. - $router->succeed("systemctl start nat"); - $client->succeed("curl --fail http://server/ >&2"); - $client->succeed("ping -c 1 server >&2"); - ''; - -} + # And make sure that reloading the NAT job works. + $router->succeed("systemctl restart ${unit}"); + $client->succeed("curl --fail http://server/ >&2"); + $client->succeed("ping -c 1 server >&2"); + ''; + }) |