diff options
author | Nicolas B. Pierron <nicolas.b.pierron@gmail.com> | 2014-12-11 23:49:19 +0100 |
---|---|---|
committer | Nicolas B. Pierron <nicolas.b.pierron@gmail.com> | 2014-12-11 23:49:19 +0100 |
commit | 0570a08b83e4a3594c13be250f55aed7da51a328 (patch) | |
tree | ab75b71b3dea3bb57d4b616996725cfbf532ca8f /nixos | |
parent | 01886aef225a5fb03dc1ee08fb606899d87f6dcf (diff) | |
parent | 786a0c92c657c18515cbcc5f9e0f4afbff15ce75 (diff) | |
download | nixpkgs-0570a08b83e4a3594c13be250f55aed7da51a328.tar nixpkgs-0570a08b83e4a3594c13be250f55aed7da51a328.tar.gz nixpkgs-0570a08b83e4a3594c13be250f55aed7da51a328.tar.bz2 nixpkgs-0570a08b83e4a3594c13be250f55aed7da51a328.tar.lz nixpkgs-0570a08b83e4a3594c13be250f55aed7da51a328.tar.xz nixpkgs-0570a08b83e4a3594c13be250f55aed7da51a328.tar.zst nixpkgs-0570a08b83e4a3594c13be250f55aed7da51a328.zip |
Merge remote-tracking branch 'origin/master' into syncserver
Diffstat (limited to 'nixos')
62 files changed, 1519 insertions, 555 deletions
diff --git a/nixos/doc/manual/administration/network-problems.xml b/nixos/doc/manual/administration/network-problems.xml index 5ba1bfd5ac9..3af9cc59742 100644 --- a/nixos/doc/manual/administration/network-problems.xml +++ b/nixos/doc/manual/administration/network-problems.xml @@ -12,9 +12,9 @@ pre-built binary. That is, whenever a command like <command>nixos-rebuild</command> needs a path in the Nix store, Nix will try to download that path from the Internet rather than build it from source. The default binary cache is -<uri>http://cache.nixos.org/</uri>. If this cache is unreachable, Nix -operations may take a long time due to HTTP connection timeouts. You -can disable the use of the binary cache by adding <option>--option +<uri>https://cache.nixos.org/</uri>. If this cache is unreachable, +Nix operations may take a long time due to HTTP connection timeouts. +You can disable the use of the binary cache by adding <option>--option use-binary-caches false</option>, e.g. <screen> @@ -30,4 +30,4 @@ $ nixos-rebuild switch --option binary-caches http://my-cache.example.org/ </para> -</section> \ No newline at end of file +</section> diff --git a/nixos/doc/manual/installation/obtaining.xml b/nixos/doc/manual/installation/obtaining.xml index ceeeb5c0ac0..540f19c3201 100644 --- a/nixos/doc/manual/installation/obtaining.xml +++ b/nixos/doc/manual/installation/obtaining.xml @@ -8,9 +8,14 @@ <para>NixOS ISO images can be downloaded from the <link xlink:href="http://nixos.org/nixos/download.html">NixOS -homepage</link>. These can be burned onto a CD. It is also possible -to copy them onto a USB stick and install NixOS from there. For -details, see the <link +homepage</link>. There are a number of installation options. If +you happen to have an optical drive and a spare CD, burning the +image to CD and booting from that is probably the easiest option. +Most people will need to prepare a USB stick to boot from. +Unetbootin is recommended and the process is described in brief below. +Note that systems which use UEFI require some additional manual steps. +If you run into difficulty a number of alternative methods are presented +in the <link xlink:href="https://nixos.org/wiki/Installing_NixOS_from_a_USB_stick">NixOS Wiki</link>.</para> diff --git a/nixos/doc/manual/release-notes/release-notes.xml b/nixos/doc/manual/release-notes/release-notes.xml index 9034dba1fb5..231a3b4c2e2 100644 --- a/nixos/doc/manual/release-notes/release-notes.xml +++ b/nixos/doc/manual/release-notes/release-notes.xml @@ -10,7 +10,7 @@ <para>This section lists the release notes for each stable version of NixOS.</para> </partintro> -<xi:include href="rl-1411.xml" /> +<xi:include href="rl-1412.xml" /> <xi:include href="rl-1404.xml" /> <xi:include href="rl-1310.xml" /> diff --git a/nixos/doc/manual/release-notes/rl-1411.xml b/nixos/doc/manual/release-notes/rl-1412.xml index f26cfee7a2c..35115f900c1 100644 --- a/nixos/doc/manual/release-notes/rl-1411.xml +++ b/nixos/doc/manual/release-notes/rl-1412.xml @@ -2,9 +2,9 @@ xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xi="http://www.w3.org/2001/XInclude" version="5.0" - xml:id="sec-release-14.11"> + xml:id="sec-release-14.12"> -<title>Release 14.11 (“Caterpillar”, 2014/11/??)</title> +<title>Release 14.12 (“Caterpillar”, 2014/12/??)</title> <para>When upgrading from a previous release, please be aware of the following incompatible changes: @@ -24,6 +24,11 @@ services.httpd.package = pkgs.apacheHttpd_2_2; </para></listitem> + <listitem><para>PHP 5.3 has been removed because it is no longer + supported by the PHP project. A <link + xlink:href="http://php.net/migration54">migration guide</link> is + available.</para></listitem> + <listitem><para>The host side of a container virtual Ethernet pair is now called <literal>ve-<replaceable>container-name</replaceable></literal> rather than <literal>c-<replaceable>container-name</replaceable></literal>.</para></listitem> diff --git a/nixos/lib/make-system-tarball.nix b/nixos/lib/make-system-tarball.nix index 3bd891fdbc2..a2a0340a6bd 100644 --- a/nixos/lib/make-system-tarball.nix +++ b/nixos/lib/make-system-tarball.nix @@ -16,6 +16,9 @@ # symlink to `object' that will be added to the tarball. storeContents ? [] + # Extra commands to be executed before archiving files +, extraCommands ? "" + # Extra tar arguments , extraArgs ? "" }: @@ -25,7 +28,7 @@ stdenv.mkDerivation { builder = ./make-system-tarball.sh; buildInputs = [perl xz]; - inherit fileName pathsFromGraph extraArgs; + inherit fileName pathsFromGraph extraArgs extraCommands; # !!! should use XML. sources = map (x: x.source) contents; diff --git a/nixos/lib/make-system-tarball.sh b/nixos/lib/make-system-tarball.sh index 2eb668115a6..e04455e889b 100644 --- a/nixos/lib/make-system-tarball.sh +++ b/nixos/lib/make-system-tarball.sh @@ -33,7 +33,7 @@ for i in $storePaths; do done -# TODO tar ruxo +# TODO tar ruxo # Also include a manifest of the closures in a format suitable for # nix-store --load-db. printRegistration=1 perl $pathsFromGraph closure-* > nix-path-registration @@ -48,6 +48,8 @@ for ((n = 0; n < ${#objects[*]}; n++)); do fi done +$extraCommands + mkdir -p $out/tarball tar cvJf $out/tarball/$fileName.tar.xz * $extraArgs diff --git a/nixos/modules/config/fonts/fontconfig-ultimate.nix b/nixos/modules/config/fonts/fontconfig-ultimate.nix new file mode 100644 index 00000000000..408d49053dd --- /dev/null +++ b/nixos/modules/config/fonts/fontconfig-ultimate.nix @@ -0,0 +1,193 @@ +{ config, pkgs, ... }: + +with pkgs.lib; + +let fcBool = x: if x then "<bool>true</bool>" else "<bool>false</bool>"; +in +{ + + options = { + + fonts = { + + fontconfig = { + + ultimate = { + enable = mkOption { + type = types.bool; + default = true; + description = '' + Enable fontconfig-ultimate settings (formerly known as + Infinality). Besides the customizable settings in this NixOS + module, fontconfig-ultimate also provides many font-specific + rendering tweaks. + ''; + }; + + allowBitmaps = mkOption { + type = types.bool; + default = true; + description = '' + Allow bitmap fonts. Set to <literal>false</literal> to ban all + bitmap fonts. + ''; + }; + + allowType1 = mkOption { + type = types.bool; + default = false; + description = '' + Allow Type-1 fonts. Default is <literal>false</literal> because of + poor rendering. + ''; + }; + + useEmbeddedBitmaps = mkOption { + type = types.bool; + default = false; + description = ''Use embedded bitmaps in fonts like Calibri.''; + }; + + forceAutohint = mkOption { + type = types.bool; + default = false; + description = '' + Force use of the TrueType Autohinter. Useful for debugging or + free-software purists. + ''; + }; + + renderMonoTTFAsBitmap = mkOption { + type = types.bool; + default = false; + description = ''Render some monospace TTF fonts as bitmaps.''; + }; + + substitutions = mkOption { + type = types.str // { + check = flip elem ["none" "free" "combi" "ms"]; + }; + default = "free"; + description = '' + Font substitutions to replace common Type 1 fonts with nicer + TrueType fonts. <literal>free</literal> uses free fonts, + <literal>ms</literal> uses Microsoft fonts, + <literal>combi</literal> uses a combination, and + <literal>none</literal> disables the substitutions. + ''; + }; + + rendering = mkOption { + type = types.attrs; + default = pkgs.fontconfig-ultimate.rendering.ultimate; + description = '' + FreeType rendering settings presets. The default is + <literal>pkgs.fontconfig-ultimate.rendering.ultimate</literal>. + The other available styles are: + <literal>ultimate-lighter</literal>, + <literal>ultimate-darker</literal>, + <literal>ultimate-lightest</literal>, + <literal>ultimate-darkest</literal>, + <literal>default</literal> (the original Infinality default), + <literal>osx</literal>, + <literal>ipad</literal>, + <literal>ubuntu</literal>, + <literal>linux</literal>, + <literal>winxplight</literal>, + <literal>win7light</literal>, + <literal>winxp</literal>, + <literal>win7</literal>, + <literal>vanilla</literal>, + <literal>classic</literal>, + <literal>nudge</literal>, + <literal>push</literal>, + <literal>shove</literal>, + <literal>sharpened</literal>, + <literal>infinality</literal>. Any of the presets may be + customized by editing the attributes. To disable, set this option + to the empty attribute set <literal>{}</literal>. + ''; + }; + }; + }; + }; + + }; + + + config = + let ultimate = config.fonts.fontconfig.ultimate; + fontconfigUltimateConf = '' + <?xml version="1.0"?> + <!DOCTYPE fontconfig SYSTEM "fonts.dtd"> + <fontconfig> + + ${optionalString ultimate.allowBitmaps '' + <!-- Reject bitmap fonts --> + <selectfont> + <rejectfont> + <pattern> + <patelt name="scalable"><bool>false</bool></patelt> + </pattern> + </rejectfont> + </selectfont> + ''} + + ${optionalString ultimate.allowType1 '' + <!-- Reject Type 1 fonts --> + <selectfont> + <rejectfont> + <pattern> + <patelt name="fontformat"> + <string>Type 1</string> + </patelt> + </pattern> + </rejectfont> + </selectfont> + ''} + + <!-- Use embedded bitmaps in fonts like Calibri? --> + <match target="font"> + <edit name="embeddedbitmap" mode="assign"> + ${fcBool ultimate.useEmbeddedBitmaps} + </edit> + </match> + + <!-- Force autohint always --> + <match target="font"> + <edit name="force_autohint" mode="assign"> + ${fcBool ultimate.forceAutohint} + </edit> + </match> + + <!-- Render some monospace TTF fonts as bitmaps --> + <match target="pattern"> + <edit name="bitmap_monospace" mode="assign"> + ${fcBool ultimate.renderMonoTTFAsBitmap} + </edit> + </match> + + ${optionalString (ultimate.substitutions != "none") '' + <!-- Type 1 font substitutions --> + <include ignore_missing="yes">${pkgs.fontconfig-ultimate.confd}/etc/fonts/presets/${ultimate.substitutions}</include> + ''} + + <include ignore_missing="yes">${pkgs.fontconfig-ultimate.confd}/etc/fonts/conf.d</include> + + </fontconfig> + ''; + in mkIf (config.fonts.fontconfig.enable && ultimate.enable) { + + environment.etc."fonts/conf.d/52-fontconfig-ultimate.conf" = { + text = fontconfigUltimateConf; + }; + + environment.etc."fonts/${pkgs.fontconfig.configVersion}/conf.d/52-fontconfig-ultimate.conf" = { + text = fontconfigUltimateConf; + }; + + environment.variables = ultimate.rendering; + + }; + +} diff --git a/nixos/modules/config/fonts/fontconfig.nix b/nixos/modules/config/fonts/fontconfig.nix index 4b6f9325fda..793b0a250ac 100644 --- a/nixos/modules/config/fonts/fontconfig.nix +++ b/nixos/modules/config/fonts/fontconfig.nix @@ -8,72 +8,250 @@ with lib; fonts = { - enableFontConfig = mkOption { # !!! should be enableFontconfig - type = types.bool; - default = true; - description = '' - If enabled, a Fontconfig configuration file will be built - pointing to a set of default fonts. If you don't care about - running X11 applications or any other program that uses - Fontconfig, you can turn this option off and prevent a - dependency on all those fonts. - ''; + fontconfig = { + enable = mkOption { + type = types.bool; + default = true; + description = '' + If enabled, a Fontconfig configuration file will be built + pointing to a set of default fonts. If you don't care about + running X11 applications or any other program that uses + Fontconfig, you can turn this option off and prevent a + dependency on all those fonts. + ''; + }; + + antialias = mkOption { + type = types.bool; + default = true; + description = "Enable font antialiasing."; + }; + + dpi = mkOption { + type = types.int; + default = 0; + description = '' + Force DPI setting. Setting to <literal>0</literal> disables DPI + forcing; the DPI detected for the display will be used. + ''; + }; + + defaultFonts = { + monospace = mkOption { + type = types.listOf types.str; + default = ["DejaVu Sans Mono"]; + description = '' + System-wide default monospace font(s). Multiple fonts may be + listed in case multiple languages must be supported. + ''; + }; + + sansSerif = mkOption { + type = types.listOf types.str; + default = ["DejaVu Sans"]; + description = '' + System-wide default sans serif font(s). Multiple fonts may be + listed in case multiple languages must be supported. + ''; + }; + + serif = mkOption { + type = types.listOf types.str; + default = ["DejaVu Serif"]; + description = '' + System-wide default serif font(s). Multiple fonts may be listed + in case multiple languages must be supported. + ''; + }; + }; + + hinting = { + enable = mkOption { + type = types.bool; + default = true; + description = "Enable TrueType hinting."; + }; + + autohint = mkOption { + type = types.bool; + default = true; + description = '' + Enable the autohinter, which provides hinting for otherwise + un-hinted fonts. The results are usually lower quality than + correctly-hinted fonts. + ''; + }; + + style = mkOption { + type = types.str // { + check = flip elem ["none" "slight" "medium" "full"]; + }; + default = "full"; + description = '' + TrueType hinting style, one of <literal>none</literal>, + <literal>slight</literal>, <literal>medium</literal>, or + <literal>full</literal>. + ''; + }; + }; + + includeUserConf = mkOption { + type = types.bool; + default = true; + description = '' + Include the user configuration from + <filename>~/.config/fontconfig/fonts.conf</filename> or + <filename>~/.config/fontconfig/conf.d</filename>. + ''; + }; + + subpixel = { + + rgba = mkOption { + type = types.string // { + check = flip elem ["rgb" "bgr" "vrgb" "vbgr" "none"]; + }; + default = "rgb"; + description = '' + Subpixel order, one of <literal>none</literal>, + <literal>rgb</literal>, <literal>bgr</literal>, + <literal>vrgb</literal>, or <literal>vbgr</literal>. + ''; + }; + + lcdfilter = mkOption { + type = types.str // { + check = flip elem ["none" "default" "light" "legacy"]; + }; + default = "default"; + description = '' + FreeType LCD filter, one of <literal>none</literal>, + <literal>default</literal>, <literal>light</literal>, or + <literal>legacy</literal>. + ''; + }; + + }; + }; }; }; + config = + let fontconfig = config.fonts.fontconfig; + fcBool = x: "<bool>" + (if x then "true" else "false") + "</bool>"; + nixosConf = '' + <?xml version='1.0'?> + <!DOCTYPE fontconfig SYSTEM 'fonts.dtd'> + <fontconfig> - config = mkIf config.fonts.enableFontConfig { + <!-- Default rendering settings --> + <match target="font"> + <edit mode="assign" name="hinting"> + ${fcBool fontconfig.hinting.enable} + </edit> + <edit mode="assign" name="autohint"> + ${fcBool fontconfig.hinting.autohint} + </edit> + <edit mode="assign" name="hintstyle"> + <const>hint${fontconfig.hinting.style}</const> + </edit> + <edit mode="assign" name="antialias"> + ${fcBool fontconfig.antialias} + </edit> + <edit mode="assign" name="rgba"> + <const>${fontconfig.subpixel.rgba}</const> + </edit> + <edit mode="assign" name="lcdfilter"> + <const>lcd${fontconfig.subpixel.lcdfilter}</const> + </edit> + </match> - # Fontconfig 2.10 backward compatibility + <!-- Default fonts --> + ${optionalString (fontconfig.defaultFonts.sansSerif != []) '' + <alias> + <family>sans-serif</family> + <prefer> + ${concatStringsSep "\n" + (map (font: "<family>${font}</family>") + fontconfig.defaultFonts.sansSerif)} + </prefer> + </alias> + ''} + ${optionalString (fontconfig.defaultFonts.serif != []) '' + <alias> + <family>serif</family> + <prefer> + ${concatStringsSep "\n" + (map (font: "<family>${font}</family>") + fontconfig.defaultFonts.serif)} + </prefer> + </alias> + ''} + ${optionalString (fontconfig.defaultFonts.monospace != []) '' + <alias> + <family>monospace</family> + <prefer> + ${concatStringsSep "\n" + (map (font: "<family>${font}</family>") + fontconfig.defaultFonts.monospace)} + </prefer> + </alias> + ''} - # Bring in the default (upstream) fontconfig configuration, only for fontconfig 2.10 - environment.etc."fonts/fonts.conf".source = - pkgs.makeFontsConf { fontconfig = pkgs.fontconfig_210; fontDirectories = config.fonts.fonts; }; + ${optionalString (fontconfig.dpi != 0) '' + <match target="pattern"> + <edit name="dpi" mode="assign"> + <double>${fontconfig.dpi}</double> + </edit> + </match> + ''} - environment.etc."fonts/conf.d/00-nixos.conf".text = - '' - <?xml version='1.0'?> - <!DOCTYPE fontconfig SYSTEM 'fonts.dtd'> - <fontconfig> + </fontconfig> + ''; + in mkIf fontconfig.enable { - <!-- Set the default hinting style to "slight". --> - <match target="font"> - <edit mode="assign" name="hintstyle"> - <const>hintslight</const> - </edit> - </match> + # Fontconfig 2.10 backward compatibility - </fontconfig> - ''; + # Bring in the default (upstream) fontconfig configuration, only for fontconfig 2.10 + environment.etc."fonts/fonts.conf".source = + pkgs.makeFontsConf { fontconfig = pkgs.fontconfig_210; fontDirectories = config.fonts.fonts; }; - # Versioned fontconfig > 2.10. Take shared fonts.conf from fontconfig. - # Otherwise specify only font directories. - environment.etc."fonts/${pkgs.fontconfig.configVersion}/fonts.conf".source = - "${pkgs.fontconfig}/etc/fonts/fonts.conf"; - environment.etc."fonts/${pkgs.fontconfig.configVersion}/conf.d/00-nixos.conf".text = - '' - <?xml version='1.0'?> - <!DOCTYPE fontconfig SYSTEM 'fonts.dtd'> - <fontconfig> + environment.etc."fonts/conf.d/98-nixos.conf".text = nixosConf; - <!-- Set the default hinting style to "slight". --> - <match target="font"> - <edit mode="assign" name="hintstyle"> - <const>hintslight</const> - </edit> - </match> + # Versioned fontconfig > 2.10. Take shared fonts.conf from fontconfig. + # Otherwise specify only font directories. + environment.etc."fonts/${pkgs.fontconfig.configVersion}/fonts.conf".source = + "${pkgs.fontconfig}/etc/fonts/fonts.conf"; - <!-- Font directories --> - ${concatStringsSep "\n" (map (font: "<dir>${font}</dir>") config.fonts.fonts)} + environment.etc."fonts/${pkgs.fontconfig.configVersion}/conf.d/00-nixos.conf".text = + '' + <?xml version='1.0'?> + <!DOCTYPE fontconfig SYSTEM 'fonts.dtd'> + <fontconfig> + <!-- Font directories --> + ${concatStringsSep "\n" (map (font: "<dir>${font}</dir>") config.fonts.fonts)} + </fontconfig> + ''; - </fontconfig> - ''; + environment.etc."fonts/${pkgs.fontconfig.configVersion}/conf.d/98-nixos.conf".text = nixosConf; - environment.systemPackages = [ pkgs.fontconfig ]; + environment.etc."fonts/${pkgs.fontconfig.configVersion}/conf.d/99-user.conf" = { + enable = fontconfig.includeUserConf; + text = '' + <?xml version="1.0"?> + <!DOCTYPE fontconfig SYSTEM "fonts.dtd"> + <fontconfig> + <include ignore_missing="yes" prefix="xdg">fontconfig/conf.d</include> + <include ignore_missing="yes" prefix="xdg">fontconfig/fonts.conf</include> + </fontconfig> + ''; + }; - }; + environment.systemPackages = [ pkgs.fontconfig ]; + + }; } diff --git a/nixos/modules/config/fonts/fonts.nix b/nixos/modules/config/fonts/fonts.nix index baf5b7713f5..a3fa4bd9778 100644 --- a/nixos/modules/config/fonts/fonts.nix +++ b/nixos/modules/config/fonts/fonts.nix @@ -25,7 +25,7 @@ with lib; [ pkgs.xorg.fontbhttf pkgs.xorg.fontbhlucidatypewriter100dpi pkgs.xorg.fontbhlucidatypewriter75dpi - pkgs.ttf_bitstream_vera + pkgs.dejavu_fonts pkgs.freefont_ttf pkgs.liberation_ttf pkgs.xorg.fontbh100dpi diff --git a/nixos/modules/config/no-x-libs.nix b/nixos/modules/config/no-x-libs.nix index f91dbb4cc28..47393c9d3f5 100644 --- a/nixos/modules/config/no-x-libs.nix +++ b/nixos/modules/config/no-x-libs.nix @@ -24,7 +24,7 @@ with lib; programs.ssh.setXAuthLocation = false; security.pam.services.su.forwardXAuth = lib.mkForce false; - fonts.enableFontConfig = false; + fonts.fontconfig.enable = false; nixpkgs.config.packageOverrides = pkgs: { dbus = pkgs.dbus.override { useX11 = false; }; }; diff --git a/nixos/modules/hardware/all-firmware.nix b/nixos/modules/hardware/all-firmware.nix index 3820a95b12e..37a9f4d0d31 100644 --- a/nixos/modules/hardware/all-firmware.nix +++ b/nixos/modules/hardware/all-firmware.nix @@ -12,7 +12,8 @@ with lib; default = false; type = types.bool; description = '' - Turn on this option if you want to enable all the firmware shipped with Debian/Ubuntu. + Turn on this option if you want to enable all the firmware shipped with Debian/Ubuntu + and iwlwifi. ''; }; @@ -22,7 +23,11 @@ with lib; ###### implementation config = mkIf config.hardware.enableAllFirmware { - hardware.firmware = [ "${pkgs.firmwareLinuxNonfree}/lib/firmware" ]; + hardware.firmware = [ + "${pkgs.firmwareLinuxNonfree}/lib/firmware" + "${pkgs.iwlegacy}/lib/firmware" + "${pkgs.iwlwifi}/lib/firmware" + ]; }; } diff --git a/nixos/modules/installer/tools/nixos-rebuild.sh b/nixos/modules/installer/tools/nixos-rebuild.sh index 5daa9ff9457..93f258f54e3 100644 --- a/nixos/modules/installer/tools/nixos-rebuild.sh +++ b/nixos/modules/installer/tools/nixos-rebuild.sh @@ -156,7 +156,7 @@ if [ -n "$buildNix" ]; then exit 1 fi if ! nix-store -r $nixStorePath --add-root $tmpDir/nix --indirect \ - --option extra-binary-caches http://cache.nixos.org/; then + --option extra-binary-caches https://cache.nixos.org/; then echo "warning: don't know how to get latest Nix" >&2 fi # Older version of nix-store -r don't support --add-root. diff --git a/nixos/modules/misc/ids.nix b/nixos/modules/misc/ids.nix index f7b8737fa4d..bdaf85a03ce 100644 --- a/nixos/modules/misc/ids.nix +++ b/nixos/modules/misc/ids.nix @@ -170,6 +170,8 @@ scollector = 160; bosun = 161; kubernetes = 162; + peerflix = 163; + chronos = 164; # When adding a uid, make sure it doesn't match an existing gid. And don't use uids above 399! @@ -210,6 +212,7 @@ privoxy = 32; disnix = 33; osgi = 34; + tor = 35; ghostOne = 40; git = 41; fourstore = 42; @@ -304,6 +307,7 @@ scollector = 156; bosun = 157; kubernetes = 158; + fleet = 159; # 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 cbf42d44df6..cbd5ac6a7ef 100755 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -1,6 +1,7 @@ [ ./config/fonts/corefonts.nix ./config/fonts/fontconfig.nix + ./config/fonts/fontconfig-ultimate.nix ./config/fonts/fontdir.nix ./config/fonts/fonts.nix ./config/fonts/ghostscript.nix @@ -101,6 +102,8 @@ ./services/backup/rsnapshot.nix ./services/backup/sitecopy-backup.nix ./services/backup/tarsnap.nix + ./services/cluster/fleet.nix + ./services/cluster/kubernetes.nix ./services/computing/torque/server.nix ./services/computing/torque/mom.nix ./services/continuous-integration/jenkins/default.nix @@ -293,6 +296,7 @@ ./services/networking/znc.nix ./services/printing/cupsd.nix ./services/scheduling/atd.nix + ./services/scheduling/chronos.nix ./services/scheduling/cron.nix ./services/scheduling/fcron.nix ./services/search/elasticsearch.nix @@ -302,7 +306,6 @@ ./services/security/fprot.nix ./services/security/frandom.nix ./services/security/haveged.nix - ./services/security/torify.nix ./services/security/tor.nix ./services/security/torsocks.nix ./services/system/dbus.nix @@ -310,6 +313,7 @@ ./services/system/nscd.nix ./services/system/uptimed.nix ./services/torrent/deluge.nix + ./services/torrent/peerflix.nix ./services/torrent/transmission.nix ./services/ttys/agetty.nix ./services/ttys/gpm.nix @@ -358,6 +362,7 @@ ./system/boot/loader/efi.nix ./system/boot/loader/generations-dir/generations-dir.nix ./system/boot/loader/grub/grub.nix + ./system/boot/loader/grub/ipxe.nix ./system/boot/loader/grub/memtest.nix ./system/boot/loader/gummiboot/gummiboot.nix ./system/boot/loader/init-script/init-script.nix @@ -398,7 +403,6 @@ ./virtualisation/container-config.nix ./virtualisation/containers.nix ./virtualisation/docker.nix - ./virtualisation/kubernetes.nix ./virtualisation/libvirtd.nix ./virtualisation/lxc.nix #./virtualisation/nova.nix diff --git a/nixos/modules/profiles/container.nix b/nixos/modules/profiles/container.nix new file mode 100644 index 00000000000..5b531e5c3df --- /dev/null +++ b/nixos/modules/profiles/container.nix @@ -0,0 +1,57 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + pkgs2storeContents = l : map (x: { object = x; symlink = "none"; }) l; + +in { + # Docker image config. + imports = [ + ../installer/cd-dvd/channel.nix + ./minimal.nix + ./clone-config.nix + ]; + + # Create the tarball + system.build.tarball = import ../../lib/make-system-tarball.nix { + inherit (pkgs) stdenv perl xz pathsFromGraph; + + contents = []; + extraArgs = "--owner=0"; + + # Some container managers like lxc need these + extraCommands = "mkdir -p proc sys dev"; + + # Add init script to image + storeContents = [ + { object = config.system.build.toplevel + "/init"; + symlink = "/init"; + } + ] ++ (pkgs2storeContents [ pkgs.stdenv ]); + }; + + boot.postBootCommands = + '' + # After booting, register the contents of the Nix store in the Nix + # database. + if [ -f /nix-path-registration ]; then + ${config.nix.package}/bin/nix-store --load-db < /nix-path-registration && + rm /nix-path-registration + fi + + # nixos-rebuild also requires a "system" profile and an + # /etc/NIXOS tag. + touch /etc/NIXOS + ${config.nix.package}/bin/nix-env -p /nix/var/nix/profiles/system --set /run/current-system + ''; + + boot.isContainer = true; + + # Disable some features that are not useful in a container. + sound.enable = mkDefault false; + services.udisks2.enable = mkDefault false; + + # Shut up warnings about not having a boot loader. + system.build.installBootLoader = "${pkgs.coreutils}/bin/true"; +} diff --git a/nixos/modules/programs/bash/bash.nix b/nixos/modules/programs/bash/bash.nix index c5c0f9d0121..03899425da5 100644 --- a/nixos/modules/programs/bash/bash.nix +++ b/nixos/modules/programs/bash/bash.nix @@ -105,7 +105,7 @@ in }; enableCompletion = mkOption { - default = false; + default = true; description = '' Enable Bash completion for all interactive bash shells. ''; diff --git a/nixos/modules/rename.nix b/nixos/modules/rename.nix index b29a3d0354c..cb1b92e78d6 100644 --- a/nixos/modules/rename.nix +++ b/nixos/modules/rename.nix @@ -74,6 +74,7 @@ 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" ] ++ obsolete [ "security" "extraSetuidPrograms" ] [ "security" "setuidPrograms" ] diff --git a/nixos/modules/security/ca.nix b/nixos/modules/security/ca.nix index e17ad448f40..f430a5a6339 100644 --- a/nixos/modules/security/ca.nix +++ b/nixos/modules/security/ca.nix @@ -16,6 +16,8 @@ with lib; { SSL_CERT_FILE = "/etc/ssl/certs/ca-bundle.crt"; # FIXME: unneeded - remove eventually. OPENSSL_X509_CERT_FILE = "/etc/ssl/certs/ca-bundle.crt"; + # FIXME: unneeded - remove eventually. + GIT_SSL_CAINFO = "/etc/ssl/certs/ca-bundle.crt"; }; }; diff --git a/nixos/modules/services/backup/almir.nix b/nixos/modules/services/backup/almir.nix index 5ce215c5c4b..ec39a997028 100644 --- a/nixos/modules/services/backup/almir.nix +++ b/nixos/modules/services/backup/almir.nix @@ -109,6 +109,7 @@ in { }; sqlalchemy_engine_url = mkOption { + default = "postgresql:///bacula"; example = '' postgresql://bacula:bacula@localhost:5432/bacula mysql+mysqlconnector://<user>:<password>@<hostname>/<database>' diff --git a/nixos/modules/services/cluster/fleet.nix b/nixos/modules/services/cluster/fleet.nix new file mode 100644 index 00000000000..04d95fbf186 --- /dev/null +++ b/nixos/modules/services/cluster/fleet.nix @@ -0,0 +1,150 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + cfg = config.services.fleet; + +in { + + ##### Interface + options.services.fleet = { + enable = mkOption { + type = types.bool; + default = false; + description = '' + Whether to enable fleet service. + ''; + }; + + listen = mkOption { + type = types.listOf types.str; + default = [ "/var/run/fleet.sock" ]; + example = [ "/var/run/fleet.sock" "127.0.0.1:49153" ]; + description = '' + Fleet listening addresses. + ''; + }; + + etcdServers = mkOption { + type = types.listOf types.str; + default = [ "http://127.0.0.1:4001" ]; + description = '' + Fleet list of etcd endpoints to use. + ''; + }; + + publicIp = mkOption { + type = types.nullOr types.str; + default = ""; + description = '' + Fleet IP address that should be published with the local Machine's + state and any socket information. If not set, fleetd will attempt + to detect the IP it should publish based on the machine's IP + routing information. + ''; + }; + + etcdCafile = mkOption { + type = types.nullOr types.path; + default = null; + description = '' + Fleet TLS ca file when SSL certificate authentication is enabled + in etcd endpoints. + ''; + }; + + etcdKeyfile = mkOption { + type = types.nullOr types.path; + default = null; + description = '' + Fleet TLS key file when SSL certificate authentication is enabled + in etcd endpoints. + ''; + }; + + etcdCertfile = mkOption { + type = types.nullOr types.path; + default = null; + description = '' + Fleet TLS cert file when SSL certificate authentication is enabled + in etcd endpoints. + ''; + }; + + metadata = mkOption { + type = types.attrsOf types.str; + default = {}; + apply = attrs: concatMapStringsSep "," (n: "${n}=${attrs."${n}"}") (attrNames attrs); + example = literalExample '' + { + region = "us-west"; + az = "us-west-1"; + } + ''; + description = '' + Key/value pairs that are published with the local to the fleet registry. + This data can be used directly by a client of fleet to make scheduling decisions. + ''; + }; + + extraConfig = mkOption { + type = types.attrsOf types.str; + apply = mapAttrs' (n: v: nameValuePair ("ETCD_" + n) v); + default = {}; + example = literalExample '' + { + VERBOSITY = 1; + ETCD_REQUEST_TIMEOUT = "2.0"; + AGENT_TTL = "40s"; + } + ''; + description = '' + Fleet extra config. See + <link xlink:href="https://github.com/coreos/fleet/blob/master/Documentation/deployment-and-configuration.md"/> + for configuration options. + ''; + }; + + }; + + ##### Implementation + config = mkIf cfg.enable { + systemd.services.fleet = { + description = "Fleet Init System Daemon"; + wantedBy = [ "multi-user.target" ]; + after = [ "network.target" "fleet.socket" "etcd.service" "docker.service" ]; + requires = [ "fleet.socket" ]; + environment = { + FLEET_ETCD_SERVERS = concatStringsSep "," cfg.etcdServers; + FLEET_PUBLIC_IP = cfg.publicIp; + FLEET_ETCD_CAFILE = cfg.etcdCafile; + FLEET_ETCD_KEYFILE = cfg.etcdKeyfile; + FEELT_ETCD_CERTFILE = cfg.etcdCertfile; + FLEET_METADATA = cfg.metadata; + } // cfg.extraConfig; + serviceConfig = { + ExecStart = "${pkgs.fleet}/bin/fleetd"; + Group = "fleet"; + }; + }; + + systemd.sockets.fleet = { + description = "Fleet Socket for the API"; + wantedBy = [ "sockets.target" ]; + listenStreams = cfg.listen; + socketConfig = { + ListenStream = "/var/run/fleet.sock"; + SocketMode = "0660"; + SocketUser = "root"; + SocketGroup = "fleet"; + }; + }; + + services.etcd.enable = mkDefault true; + virtualisation.docker.enable = mkDefault true; + + environment.systemPackages = [ pkgs.fleet ]; + users.extraGroups.fleet.gid = config.ids.gids.fleet; + }; +} diff --git a/nixos/modules/virtualisation/kubernetes.nix b/nixos/modules/services/cluster/kubernetes.nix index 50388cf2e12..7fd2d77aa82 100644 --- a/nixos/modules/virtualisation/kubernetes.nix +++ b/nixos/modules/services/cluster/kubernetes.nix @@ -3,16 +3,15 @@ with lib; let - cfg = config.virtualisation.kubernetes; + cfg = config.services.kubernetes; in { ###### interface - options.virtualisation.kubernetes = { + options.services.kubernetes = { package = mkOption { description = "Kubernetes package to use."; - default = pkgs.kubernetes; type = types.package; }; @@ -421,15 +420,15 @@ in { }) (mkIf (any (el: el == "master") cfg.roles) { - virtualisation.kubernetes.apiserver.enable = mkDefault true; - virtualisation.kubernetes.scheduler.enable = mkDefault true; - virtualisation.kubernetes.controllerManager.enable = mkDefault true; + services.kubernetes.apiserver.enable = mkDefault true; + services.kubernetes.scheduler.enable = mkDefault true; + services.kubernetes.controllerManager.enable = mkDefault true; }) (mkIf (any (el: el == "node") cfg.roles) { virtualisation.docker.enable = mkDefault true; - virtualisation.kubernetes.kubelet.enable = mkDefault true; - virtualisation.kubernetes.proxy.enable = mkDefault true; + services.kubernetes.kubelet.enable = mkDefault true; + services.kubernetes.proxy.enable = mkDefault true; }) (mkIf (any (el: el == "node" || el == "master") cfg.roles) { @@ -443,6 +442,8 @@ in { cfg.kubelet.enable || cfg.proxy.enable ) { + services.kubernetes.package = mkDefault pkgs.kubernetes; + environment.systemPackages = [ cfg.package ]; users.extraUsers = singleton { diff --git a/nixos/modules/services/desktops/gnome3/gvfs.nix b/nixos/modules/services/desktops/gnome3/gvfs.nix index 7e1382b161e..c4f41a6125c 100644 --- a/nixos/modules/services/desktops/gnome3/gvfs.nix +++ b/nixos/modules/services/desktops/gnome3/gvfs.nix @@ -1,6 +1,6 @@ # gvfs backends -{ config, lib, ... }: +{ config, lib, pkgs, ... }: with lib; @@ -37,6 +37,8 @@ in services.dbus.packages = [ gnome3.gvfs ]; + services.udev.packages = [ pkgs.libmtp ]; + }; } diff --git a/nixos/modules/services/hardware/80-net-name-slot.rules b/nixos/modules/services/hardware/80-net-setup-link.rules index 18547f170a3..18547f170a3 100644 --- a/nixos/modules/services/hardware/80-net-name-slot.rules +++ b/nixos/modules/services/hardware/80-net-setup-link.rules diff --git a/nixos/modules/services/hardware/udev.nix b/nixos/modules/services/hardware/udev.nix index 2a6f4cfb4e3..39180f4d37e 100644 --- a/nixos/modules/services/hardware/udev.nix +++ b/nixos/modules/services/hardware/udev.nix @@ -88,7 +88,7 @@ let done ${optionalString config.networking.usePredictableInterfaceNames '' - cp ${./80-net-name-slot.rules} $out/80-net-name-slot.rules + cp ${./80-net-setup-link.rules} $out/80-net-setup-link.rules ''} # If auto-configuration is disabled, then remove diff --git a/nixos/modules/services/misc/autofs.nix b/nixos/modules/services/misc/autofs.nix index e645bd25a66..f4a1059d09f 100644 --- a/nixos/modules/services/misc/autofs.nix +++ b/nixos/modules/services/misc/autofs.nix @@ -84,7 +84,7 @@ in startOn = "started network-interfaces"; stopOn = "stopping network-interfaces"; - path = [ pkgs.nfsUtils pkgs.sshfsFuse ]; + path = [ pkgs.nfs-utils pkgs.sshfsFuse ]; preStop = '' diff --git a/nixos/modules/services/misc/mesos-master.nix b/nixos/modules/services/misc/mesos-master.nix index bdf88d427c5..5609cf75bb5 100644 --- a/nixos/modules/services/misc/mesos-master.nix +++ b/nixos/modules/services/misc/mesos-master.nix @@ -4,11 +4,11 @@ with lib; let cfg = config.services.mesos.master; - + in { options.services.mesos = { - + master = { enable = mkOption { description = "Whether to enable the Mesos Master."; @@ -31,36 +31,36 @@ in { ''; type = types.str; }; - + workDir = mkOption { description = "The Mesos work directory."; default = "/var/lib/mesos/master"; type = types.str; }; - + extraCmdLineOptions = mkOption { description = '' Extra command line options for Mesos Master. - + See https://mesos.apache.org/documentation/latest/configuration/ ''; default = [ "" ]; type = types.listOf types.string; example = [ "--credentials=VALUE" ]; }; - + quorum = mkOption { description = '' The size of the quorum of replicas when using 'replicated_log' based registry. It is imperative to set this value to be a majority of masters i.e., quorum > (number of masters)/2. - + If 0 will fall back to --registry=in_memory. ''; default = 0; type = types.int; }; - + logLevel = mkOption { description = '' The logging level used. Possible values: @@ -86,11 +86,12 @@ in { ${pkgs.mesos}/bin/mesos-master \ --port=${toString cfg.port} \ --zk=${cfg.zk} \ - ${if cfg.quorum == 0 then "--registry=in_memory" else "--registry=replicated_log --quorum=${cfg.quorum}"} \ + ${if cfg.quorum == 0 then "--registry=in_memory" else "--registry=replicated_log --quorum=${toString cfg.quorum}"} \ --work_dir=${cfg.workDir} \ --logging_level=${cfg.logLevel} \ ${toString cfg.extraCmdLineOptions} ''; + Restart = "on-failure"; PermissionsStartOnly = true; }; preStart = '' @@ -98,6 +99,6 @@ in { ''; }; }; - + } diff --git a/nixos/modules/services/misc/mesos-slave.nix b/nixos/modules/services/misc/mesos-slave.nix index e9a89816716..d89531f7e90 100644 --- a/nixos/modules/services/misc/mesos-slave.nix +++ b/nixos/modules/services/misc/mesos-slave.nix @@ -4,7 +4,7 @@ with lib; let cfg = config.services.mesos.slave; - + in { options.services.mesos = { @@ -29,30 +29,30 @@ in { ''; type = types.str; }; - + withHadoop = mkOption { description = "Add the HADOOP_HOME to the slave."; default = false; type = types.bool; }; - + workDir = mkOption { description = "The Mesos work directory."; default = "/var/lib/mesos/slave"; type = types.str; }; - + extraCmdLineOptions = mkOption { description = '' Extra command line options for Mesos Slave. - + See https://mesos.apache.org/documentation/latest/configuration/ ''; default = [ "" ]; type = types.listOf types.string; example = [ "--gc_delay=3days" ]; }; - + logLevel = mkOption { description = '' The logging level used. Possible values: @@ -72,6 +72,7 @@ in { description = "Mesos Slave"; wantedBy = [ "multi-user.target" ]; after = [ "network-interfaces.target" ]; + environment.MESOS_CONTAINERIZERS = "docker,mesos"; serviceConfig = { ExecStart = '' ${pkgs.mesos}/bin/mesos-slave \ @@ -80,6 +81,7 @@ in { ${optionalString cfg.withHadoop "--hadoop-home=${pkgs.hadoop}"} \ --work_dir=${cfg.workDir} \ --logging_level=${cfg.logLevel} \ + --docker=${pkgs.docker}/libexec/docker/docker \ ${toString cfg.extraCmdLineOptions} ''; PermissionsStartOnly = true; @@ -89,5 +91,5 @@ in { ''; }; }; - -} \ No newline at end of file + +} diff --git a/nixos/modules/services/misc/nix-daemon.nix b/nixos/modules/services/misc/nix-daemon.nix index d041c5664ef..e9aa1018178 100644 --- a/nixos/modules/services/misc/nix-daemon.nix +++ b/nixos/modules/services/misc/nix-daemon.nix @@ -225,7 +225,7 @@ in binaryCaches = mkOption { type = types.listOf types.str; - default = [ http://cache.nixos.org/ ]; + default = [ https://cache.nixos.org/ ]; description = '' List of binary cache URLs used to obtain pre-built binaries of Nix packages. diff --git a/nixos/modules/services/misc/synergy.nix b/nixos/modules/services/misc/synergy.nix index 5338b25715c..271968f48b8 100644 --- a/nixos/modules/services/misc/synergy.nix +++ b/nixos/modules/services/misc/synergy.nix @@ -81,27 +81,26 @@ in ###### implementation - config = { - - systemd.services."synergy-client" = { - enable = cfgC.enable; - after = [ "network.target" ]; - description = "Synergy client"; - 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}''; - }; - - systemd.services."synergy-server" = { - enable = cfgS.enable; - after = [ "network.target" ]; - description = "Synergy server"; - 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}" }''; - }; - - }; + config = mkMerge [ + (mkIf cfgC.enable { + systemd.services."synergy-client" = { + after = [ "network.target" ]; + description = "Synergy client"; + wantedBy = [ "multi-user.target" ]; + path = [ pkgs.synergy ]; + serviceConfig.ExecStart = ''${pkgs.synergy}/bin/synergyc -f ${optionalString (cfgC.screenName != "") "-n ${cfgC.screenName}"} ${cfgC.serverAddress}''; + }; + }) + (mkIf cfgS.enable { + systemd.services."synergy-server" = { + after = [ "network.target" ]; + description = "Synergy server"; + wantedBy = [ "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}" }''; + }; + }) + ]; } diff --git a/nixos/modules/services/monitoring/bosun.nix b/nixos/modules/services/monitoring/bosun.nix index 067c826f4e4..7a53ce17454 100644 --- a/nixos/modules/services/monitoring/bosun.nix +++ b/nixos/modules/services/monitoring/bosun.nix @@ -30,7 +30,6 @@ in { package = mkOption { type = types.package; - default = pkgs.bosun; example = literalExample "pkgs.bosun"; description = '' bosun binary to use. @@ -94,8 +93,9 @@ in { }; - config = mkIf config.services.bosun.enable { - + config = mkIf cfg.enable { + + services.bosun.package = mkDefault pkgs.bosun; systemd.services.bosun = { description = "bosun metrics collector (part of Bosun)"; diff --git a/nixos/modules/services/network-filesystems/nfsd.nix b/nixos/modules/services/network-filesystems/nfsd.nix index 893df51fc1f..9b317e96884 100644 --- a/nixos/modules/services/network-filesystems/nfsd.nix +++ b/nixos/modules/services/network-filesystems/nfsd.nix @@ -86,7 +86,7 @@ in boot.supportedFilesystems = [ "nfs" ]; # needed for statd and idmapd - environment.systemPackages = [ pkgs.nfsUtils ]; + environment.systemPackages = [ pkgs.nfs-utils ]; environment.etc = singleton { source = exports; @@ -104,7 +104,7 @@ in after = [ "rpcbind.service" "mountd.service" "idmapd.service" ]; before = [ "statd.service" ]; - path = [ pkgs.nfsUtils ]; + path = [ pkgs.nfs-utils ]; script = '' @@ -131,7 +131,7 @@ in requires = [ "rpcbind.service" ]; after = [ "rpcbind.service" ]; - path = [ pkgs.nfsUtils pkgs.sysvtools pkgs.utillinux ]; + path = [ pkgs.nfs-utils pkgs.sysvtools pkgs.utillinux ]; preStart = '' @@ -157,7 +157,7 @@ in serviceConfig.Type = "forking"; serviceConfig.ExecStart = '' - @${pkgs.nfsUtils}/sbin/rpc.mountd rpc.mountd \ + @${pkgs.nfs-utils}/sbin/rpc.mountd rpc.mountd \ ${if cfg.mountdPort != null then "-p ${toString cfg.mountdPort}" else ""} ''; serviceConfig.Restart = "always"; diff --git a/nixos/modules/services/networking/consul.nix b/nixos/modules/services/networking/consul.nix index ebc83681408..c5f5bd79c1a 100644 --- a/nixos/modules/services/networking/consul.nix +++ b/nixos/modules/services/networking/consul.nix @@ -8,7 +8,6 @@ let configOptions = { data_dir = dataDir; - rejoin_after_leave = true; } // (if cfg.webUi then { ui_dir = "${pkgs.consul.ui}"; } else { }) // cfg.extraConfig; @@ -41,6 +40,35 @@ in ''; }; + leaveOnStop = mkOption { + type = types.bool; + default = false; + description = '' + If enabled, causes a leave action to be sent when closing consul. + This allows a clean termination of the node, but permanently removes + it from the cluster. You probably don't want this option unless you + are running a node which going offline in a permanent / semi-permanent + fashion. + ''; + }; + + joinNodes = mkOption { + type = types.listOf types.str; + default = [ ]; + description = '' + A list of addresses of nodes which should be joined at startup if the + current node is in a left state. + ''; + }; + + joinRetries = mkOption { + type = types.int; + default = 10; + description = '' + The number of times to retry connecting to the join nodes. + ''; + }; + interface = { advertise = mkOption { @@ -119,13 +147,14 @@ in 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; - }; + } // (optionalAttrs (cfg.leaveOnStop) { + ExecStop = "${pkgs.consul}/bin/consul leave"; + }); - path = with pkgs; [ iproute gnugrep gawk ]; + path = with pkgs; [ iproute gnugrep gawk consul ]; preStart = '' mkdir -m 0700 -p ${dataDir} chown -R consul ${dataDir} @@ -160,6 +189,18 @@ in echo " \"\": \"\"" >> /etc/consul-addrs.json echo "}" >> /etc/consul-addrs.json ''; + postStart = '' + # Issues joins to nodes which we statically connect to + ${flip concatMapStrings cfg.joinNodes (addr: '' + for i in {0..${toString cfg.joinRetries}}; do + # Try to join the other nodes ${toString cfg.joinRetries} times before failing + consul join "${addr}" && break + sleep 1 + done & + '')} + wait + exit 0 + ''; }; }; diff --git a/nixos/modules/services/networking/firewall.nix b/nixos/modules/services/networking/firewall.nix index 51e1679ce4d..b129727087a 100644 --- a/nixos/modules/services/networking/firewall.nix +++ b/nixos/modules/services/networking/firewall.nix @@ -458,8 +458,9 @@ in systemd.services.firewall = { description = "Firewall"; - wantedBy = [ "network.target" ]; - after = [ "network-interfaces.target" "systemd-modules-load.service" ]; + wantedBy = [ "network-pre.target" ]; + before = [ "network-pre.target" ]; + after = [ "systemd-modules-load.service" ]; path = [ pkgs.iptables ]; diff --git a/nixos/modules/services/networking/tcpcrypt.nix b/nixos/modules/services/networking/tcpcrypt.nix index 1359006aef4..fbd581cc4b4 100644 --- a/nixos/modules/services/networking/tcpcrypt.nix +++ b/nixos/modules/services/networking/tcpcrypt.nix @@ -44,6 +44,8 @@ in path = [ pkgs.iptables pkgs.tcpcrypt pkgs.procps ]; preStart = '' + mkdir -p /var/run/tcpcryptd + chown tcpcryptd /var/run/tcpcryptd sysctl -n net.ipv4.tcp_ecn >/run/pre-tcpcrypt-ecn-state sysctl -w net.ipv4.tcp_ecn=0 diff --git a/nixos/modules/services/networking/unifi.nix b/nixos/modules/services/networking/unifi.nix index 71dd38a3f47..8905ff1598b 100644 --- a/nixos/modules/services/networking/unifi.nix +++ b/nixos/modules/services/networking/unifi.nix @@ -48,6 +48,7 @@ in systemd.mounts = map ({ what, where }: { bindsTo = [ "unifi.service" ]; partOf = [ "unifi.service" ]; + unitConfig.RequiresMountsFor = stateDir; options = "bind"; what = what; where = where; @@ -59,6 +60,7 @@ in after = [ "network.target" ] ++ systemdMountPoints; partOf = systemdMountPoints; bindsTo = systemdMountPoints; + unitConfig.RequiresMountsFor = stateDir; preStart = '' # Ensure privacy of state diff --git a/nixos/modules/services/scheduling/chronos.nix b/nixos/modules/services/scheduling/chronos.nix new file mode 100644 index 00000000000..277cdd63280 --- /dev/null +++ b/nixos/modules/services/scheduling/chronos.nix @@ -0,0 +1,54 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + cfg = config.services.chronos; + +in { + + ###### interface + + options.services.chronos = { + enable = mkOption { + description = "Whether to enable graphite web frontend."; + default = false; + type = types.uniq types.bool; + }; + + httpPort = mkOption { + description = "Chronos listening port"; + default = 8080; + type = types.int; + }; + + master = mkOption { + description = "Chronos mesos master zookeeper address"; + default = "zk://${head cfg.zookeeperHosts}/mesos"; + type = types.str; + }; + + zookeeperHosts = mkOption { + description = "Chronos mesos zookepper addresses"; + default = [ "localhost:2181" ]; + type = types.listOf types.str; + }; + }; + + ###### implementation + + config = mkIf cfg.enable { + systemd.services.chronos = { + description = "Chronos Service"; + wantedBy = [ "multi-user.target" ]; + after = [ "network-interfaces.target" "zookeeper.service" ]; + + serviceConfig = { + ExecStart = "${pkgs.chronos}/bin/chronos --master ${cfg.master} --zk_hosts ${concatStringsSep "," cfg.zookeeperHosts} --http_port ${toString cfg.httpPort}"; + User = "chronos"; + }; + }; + + users.extraUsers.chronos.uid = config.ids.uids.chronos; + }; +} diff --git a/nixos/modules/services/security/tor.nix b/nixos/modules/services/security/tor.nix index 582dd124c29..2b4132cb568 100644 --- a/nixos/modules/services/security/tor.nix +++ b/nixos/modules/services/security/tor.nix @@ -3,120 +3,116 @@ with lib; let - - inherit (pkgs) tor privoxy; - - stateDir = "/var/lib/tor"; - privoxyDir = stateDir+"/privoxy"; - cfg = config.services.tor; - - torUser = "tor"; - - opt = name: value: if value != "" then "${name} ${value}" else ""; - optint = name: value: if value != 0 then "${name} ${toString value}" else ""; - + torDirectory = "/var/lib/tor"; + + opt = name: value: optionalString (value != null) "${name} ${value}"; + optint = name: value: optionalString (value != 0) "${name} ${toString value}"; + + torRc = '' + User tor + DataDirectory ${torDirectory} + + ${optint "ControlPort" cfg.controlPort} + '' + # Client connection config + + optionalString cfg.client.enable '' + SOCKSPort ${cfg.client.socksListenAddress} + ${opt "SocksPolicy" cfg.client.socksPolicy} + '' + # Relay config + + optionalString cfg.relay.enable '' + ORPort ${cfg.relay.portSpec} + ${opt "Nickname" cfg.relay.nickname} + ${opt "ContactInfo" cfg.relay.contactInfo} + + ${optint "RelayBandwidthRate" cfg.relay.bandwidthRate} + ${optint "RelayBandwidthBurst" cfg.relay.bandwidthBurst} + ${opt "AccountingMax" cfg.relay.accountingMax} + ${opt "AccountingStart" cfg.relay.accountingStart} + + ${if cfg.relay.isExit then + opt "ExitPolicy" cfg.relay.exitPolicy + else + "ExitPolicy reject *:*"} + + ${optionalString cfg.relay.isBridge '' + BridgeRelay 1 + ServerTransportPlugin obfs2,obfs3 exec ${pkgs.pythonPackages.obfsproxy}/bin/obfsproxy managed + ''} + '' + + cfg.extraConfig; + + torRcFile = pkgs.writeText "torrc" torRc; in - { - - ###### interface - options = { - services.tor = { + enable = mkOption { + type = types.bool; + default = false; + description = '' + Enable the Tor daemon. By default, the daemon is run without + relay, exit, bridge or client connectivity. + ''; + }; - config = mkOption { + extraConfig = mkOption { + type = types.lines; default = ""; description = '' Extra configuration. Contents will be added verbatim to the - configuration file. + configuration file at the end. ''; }; - client = { + controlPort = mkOption { + type = types.int; + default = 0; + example = 9051; + description = '' + If set, Tor will accept connections on the specified port + and allow them to control the tor process. + ''; + }; + client = { enable = mkOption { + type = types.bool; default = false; description = '' - Whether to enable Tor daemon to route application connections. - You might want to disable this if you plan running a dedicated Tor relay. + Whether to enable Tor daemon to route application + connections. You might want to disable this if you plan + running a dedicated Tor relay. ''; }; socksListenAddress = mkOption { + type = types.str; default = "127.0.0.1:9050"; example = "192.168.0.1:9100"; description = '' - Bind to this address to listen for connections from Socks-speaking - applications. - ''; - }; - - socksListenAddressFaster = mkOption { - default = "127.0.0.1:9063"; - description = '' - Same as socksListenAddress but uses weaker circuit isolation to provide - performance suitable for a web browser. + Bind to this address to listen for connections from + Socks-speaking applications. ''; }; socksPolicy = mkOption { - default = ""; + type = types.nullOr types.str; + default = null; example = "accept 192.168.0.0/16, reject *"; description = '' - Entry policies to allow/deny SOCKS requests based on IP address. - First entry that matches wins. If no SocksPolicy is set, we accept - all (and only) requests from SocksListenAddress. + Entry policies to allow/deny SOCKS requests based on IP + address. First entry that matches wins. If no SocksPolicy + is set, we accept all (and only) requests from + SocksListenAddress. ''; }; - - privoxy = { - - enable = mkOption { - default = true; - description = '' - Whether to enable a special instance of privoxy dedicated to Tor. - To have anonymity, protocols need to be scrubbed of identifying - information. - Most people using Tor want to anonymize their web traffic, so by - default we enable an special instance of privoxy specifically for - Tor. - However, if you are only going to use Tor only for other kinds of - traffic then you can disable this option. - ''; - }; - - listenAddress = mkOption { - default = "127.0.0.1:8118"; - description = '' - Address that Tor's instance of privoxy is listening to. - *This does not configure the standard NixOS instance of privoxy.* - This is for Tor connections only! - See services.privoxy.listenAddress to configure the standard NixOS - instace of privoxy. - ''; - }; - - config = mkOption { - default = ""; - description = '' - Extra configuration for Tor's instance of privoxy. Contents will be - added verbatim to the configuration file. - *This does not configure the standard NixOS instance of privoxy.* - This is for Tor connections only! - See services.privoxy.extraConfig to configure the standard NixOS - instace of privoxy. - ''; - }; - - }; - }; relay = { - enable = mkOption { + type = types.bool; default = false; description = '' Whether to enable relaying TOR traffic for others. @@ -126,16 +122,19 @@ in }; isBridge = mkOption { + type = types.bool; default = false; description = '' - Bridge relays (or "bridges" ) are Tor relays that aren't listed in the - main directory. Since there is no complete public list of them, even if an - ISP is filtering connections to all the known Tor relays, they probably + Bridge relays (or "bridges") are Tor relays that aren't + listed in the main directory. Since there is no complete + public list of them, even if an ISP is filtering + connections to all the known Tor relays, they probably won't be able to block all the bridges. A bridge relay can't be an exit relay. - You need to set relay.enable to true for this option to take effect. + You need to set relay.enable to true for this option to + take effect. The bridge is set up with an obfuscated transport proxy. @@ -144,25 +143,72 @@ in }; isExit = mkOption { + type = types.bool; default = false; description = '' - An exit relay allows Tor users to access regular Internet services. + An exit relay allows Tor users to access regular Internet + services. - Unlike running a non-exit relay, running an exit relay may expose - you to abuse complaints. See https://www.torproject.org/faq.html.en#ExitPolicies for more info. + Unlike running a non-exit relay, running an exit relay may + expose you to abuse complaints. See + https://www.torproject.org/faq.html.en#ExitPolicies for + more info. - You can specify which services Tor users may access via your exit relay using exitPolicy option. + You can specify which services Tor users may access via + your exit relay using exitPolicy option. ''; }; nickname = mkOption { + type = types.str; default = "anonymous"; description = '' A unique handle for your TOR relay. ''; }; + contactInfo = mkOption { + type = types.nullOr types.str; + default = null; + example = "admin@relay.com"; + description = '' + Contact information for the relay owner (e.g. a mail + address and GPG key ID). + ''; + }; + + accountingMax = mkOption { + type = types.nullOr types.str; + default = null; + example = "450 GBytes"; + description = '' + Specify maximum bandwidth allowed during an accounting + period. This allows you to limit overall tor bandwidth + over some time period. See the + <literal>AccountingMax</literal> option by looking at the + tor manual (<literal>man tor</literal>) for more. + + Note this limit applies individually to upload and + download; if you specify <literal>"500 GBytes"</literal> + here, then you may transfer up to 1 TBytes of overall + bandwidth (500 GB upload, 500 GB download). + ''; + }; + + accountingStart = mkOption { + type = types.nullOr types.str; + default = null; + example = "month 1 1:00"; + description = '' + Specify length of an accounting period. This allows you to + limit overall tor bandwidth over some time period. See the + <literal>AccountingStart</literal> option by looking at + the tor manual (<literal>man tor</literal>) for more. + ''; + }; + bandwidthRate = mkOption { + type = types.int; default = 0; example = 100; description = '' @@ -172,6 +218,7 @@ in }; bandwidthBurst = mkOption { + type = types.int; default = cfg.relay.bandwidthRate; example = 200; description = '' @@ -181,143 +228,99 @@ in ''; }; - port = mkOption { - default = 9001; + portSpec = mkOption { + type = types.str; + example = "143"; description = '' - What port to advertise for Tor connections. - ''; - }; - - listenAddress = mkOption { - default = ""; - example = "0.0.0.0:9090"; - description = '' - Set this if you need to listen on a port other than the one advertised - in relayPort (e.g. to advertise 443 but bind to 9090). You'll need to do - ipchains or other port forwsarding yourself to make this work. + What port to advertise for Tor connections. This corresponds + to the <literal>ORPort</literal> section in the Tor manual; see + <literal>man tor</literal> for more details. + + At a minimum, you should just specify the port for the + relay to listen on; a common one like 143, 22, 80, or 443 + to help Tor users who may have very restrictive port-based + firewalls. ''; }; exitPolicy = mkOption { - default = ""; + type = types.nullOr types.str; + default = null; example = "accept *:6660-6667,reject *:*"; description = '' - A comma-separated list of exit policies. They're considered first - to last, and the first match wins. If you want to _replace_ - the default exit policy, end this with either a reject *:* or an - accept *:*. Otherwise, you're _augmenting_ (prepending to) the - default exit policy. Leave commented to just use the default, which is - available in the man page or at https://www.torproject.org/documentation.html + A comma-separated list of exit policies. They're + considered first to last, and the first match wins. If you + want to _replace_ the default exit policy, end this with + either a reject *:* or an accept *:*. Otherwise, you're + _augmenting_ (prepending to) the default exit + policy. Leave commented to just use the default, which is + available in the man page or at + https://www.torproject.org/documentation.html Look at https://www.torproject.org/faq-abuse.html#TypicalAbuses for issues you might encounter if you use the default exit policy. - If certain IPs and ports are blocked externally, e.g. by your firewall, - you should update your exit policy to reflect this -- otherwise Tor - users will be told that those destinations are down. + If certain IPs and ports are blocked externally, e.g. by + your firewall, you should update your exit policy to + reflect this -- otherwise Tor users will be told that + those destinations are down. ''; }; - }; - }; - }; - - ###### implementation - - config = mkIf (cfg.client.enable || cfg.relay.enable) { - + config = mkIf cfg.enable { assertions = singleton - { assertion = cfg.relay.enable -> !(cfg.relay.isBridge && cfg.relay.isExit); - message = "Can't be both an exit and a bridge relay at the same time"; + { message = "Can't be both an exit and a bridge relay at the same time"; + assertion = + cfg.relay.enable -> !(cfg.relay.isBridge && cfg.relay.isExit); }; - users.extraUsers = singleton - { name = torUser; - uid = config.ids.uids.tor; - description = "Tor daemon user"; - home = stateDir; + users.extraGroups.tor.gid = config.ids.gids.tor; + users.extraUsers.tor = + { description = "Tor Daemon User"; + createHome = true; + home = torDirectory; + group = "tor"; + uid = config.ids.uids.tor; }; - jobs = { - tor = { name = "tor"; - - startOn = "started network-interfaces"; - stopOn = "stopping network-interfaces"; - - preStart = '' - mkdir -m 0755 -p ${stateDir} - chown ${torUser} ${stateDir} - ''; - exec = "${tor}/bin/tor -f ${pkgs.writeText "torrc" cfg.config}"; - }; } - // optionalAttrs (cfg.client.privoxy.enable && cfg.client.enable) { - torPrivoxy = { name = "tor-privoxy"; - - startOn = "started network-interfaces"; - stopOn = "stopping network-interfaces"; - - preStart = '' - mkdir -m 0755 -p ${privoxyDir} - chown ${torUser} ${privoxyDir} - ''; - exec = "${privoxy}/sbin/privoxy --no-daemon --user ${torUser} ${pkgs.writeText "torPrivoxy.conf" cfg.client.privoxy.config}"; - }; }; - - services.tor.config = '' - DataDirectory ${stateDir} - User ${torUser} - '' - + optionalString cfg.client.enable '' - SOCKSPort ${cfg.client.socksListenAddress} IsolateDestAddr - SOCKSPort ${cfg.client.socksListenAddressFaster} - ${opt "SocksPolicy" cfg.client.socksPolicy} - '' - + optionalString cfg.relay.enable '' - ORPort ${toString cfg.relay.port} - ${opt "ORListenAddress" cfg.relay.listenAddress } - ${opt "Nickname" cfg.relay.nickname} - ${optint "RelayBandwidthRate" cfg.relay.bandwidthRate} - ${optint "RelayBandwidthBurst" cfg.relay.bandwidthBurst} - ${if cfg.relay.isExit then opt "ExitPolicy" cfg.relay.exitPolicy else "ExitPolicy reject *:*"} - ${if cfg.relay.isBridge then '' - BridgeRelay 1 - ServerTransportPlugin obfs2,obfs3 exec ${pkgs.pythonPackages.obfsproxy}/bin/obfsproxy managed - '' else ""} - ''; - - services.tor.client.privoxy.config = '' - # Generally, this file goes in /etc/privoxy/config - # - # Tor listens as a SOCKS4a proxy here: - forward-socks4a / ${cfg.client.socksListenAddressFaster} . - confdir ${privoxy}/etc - logdir ${privoxyDir} - # actionsfile standard # Internal purpose, recommended - actionsfile default.action # Main actions file - actionsfile user.action # User customizations - filterfile default.filter - - # Don't log interesting things, only startup messages, warnings and errors - logfile logfile - #jarfile jarfile - #debug 0 # show each GET/POST/CONNECT request - debug 4096 # Startup banner and warnings - debug 8192 # Errors - *we highly recommended enabling this* - - user-manual ${privoxy}/doc/privoxy/user-manual - listen-address ${cfg.client.privoxy.listenAddress} - toggle 1 - enable-remote-toggle 0 - enable-edit-actions 0 - enable-remote-http-toggle 0 - buffer-limit 4096 - - # Extra config goes here - ''; + systemd.services.tor = + { description = "Tor Daemon"; + path = [ pkgs.tor ]; + + wantedBy = [ "multi-user.target" ]; + after = [ "network.target" ]; + restartTriggers = [ torRcFile ]; + + # Translated from the upstream contrib/dist/tor.service.in + serviceConfig = + { Type = "simple"; + ExecStartPre = "${pkgs.tor}/bin/tor -f ${torRcFile} --verify-config"; + ExecStart = "${pkgs.tor}/bin/tor -f ${torRcFile} --RunAsDaemon 0"; + ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID"; + KillSignal = "SIGINT"; + TimeoutSec = 30; + Restart = "on-failure"; + LimitNOFILE = 32768; + + # Hardening + # Note: DevicePolicy is set to 'closed', although the + # minimal permissions are really: + # DeviceAllow /dev/null rw + # DeviceAllow /dev/urandom r + # .. but we can't specify DeviceAllow multiple times. 'closed' + # is close enough. + PrivateTmp = "yes"; + DevicePolicy = "closed"; + InaccessibleDirectories = "/home"; + ReadOnlyDirectories = "/"; + ReadWriteDirectories = torDirectory; + NoNewPrivileges = "yes"; + }; + }; + environment.systemPackages = [ pkgs.tor ]; }; - } diff --git a/nixos/modules/services/security/torify.nix b/nixos/modules/services/security/torify.nix deleted file mode 100644 index 53f48a714b4..00000000000 --- a/nixos/modules/services/security/torify.nix +++ /dev/null @@ -1,69 +0,0 @@ -{ config, lib, pkgs, ... }: -with lib; -let - - cfg = config.services.tor; - - torify = pkgs.writeTextFile { - name = "torify"; - text = '' - #!${pkgs.stdenv.shell} - TSOCKS_CONF_FILE=${pkgs.writeText "tsocks.conf" cfg.torify.config} LD_PRELOAD="${pkgs.tsocks}/lib/libtsocks.so $LD_PRELOAD" "$@" - ''; - executable = true; - destination = "/bin/torify"; - }; - -in - -{ - - ###### interface - - options = { - - services.tor.torify = { - - enable = mkOption { - default = cfg.client.enable; - description = '' - Whether to build torify scipt to relay application traffic via TOR. - ''; - }; - - server = mkOption { - default = "localhost:9050"; - example = "192.168.0.20"; - description = '' - IP address of TOR client to use. - ''; - }; - - config = mkOption { - default = ""; - description = '' - Extra configuration. Contents will be added verbatim to TSocks - configuration file. - ''; - }; - - }; - - }; - - ###### implementation - - config = mkIf cfg.torify.enable { - - environment.systemPackages = [ torify ]; # expose it to the users - - services.tor.torify.config = '' - server = ${toString(head (splitString ":" cfg.torify.server))} - server_port = ${toString(tail (splitString ":" cfg.torify.server))} - - local = 127.0.0.0/255.128.0.0 - local = 127.128.0.0/255.192.0.0 - ''; - }; - -} diff --git a/nixos/modules/services/security/torsocks.nix b/nixos/modules/services/security/torsocks.nix index ede6c983677..5361d924ebe 100644 --- a/nixos/modules/services/security/torsocks.nix +++ b/nixos/modules/services/security/torsocks.nix @@ -1,85 +1,100 @@ { config, lib, pkgs, ... }: + with lib; -let - cfg = config.services.tor; +let + cfg = config.services.tor.torsocks; + optionalNullStr = b: v: optionalString (b != null) v; - makeConfig = server: '' - server = ${toString(head (splitString ":" server))} - server_port = ${toString(tail (splitString ":" server))} + configFile = '' + TorAddress ${toString (head (splitString ":" cfg.server))} + TorPort ${toString (tail (splitString ":" cfg.server))} - local = 127.0.0.0/255.128.0.0 - local = 127.128.0.0/255.192.0.0 - local = 169.254.0.0/255.255.0.0 - local = 172.16.0.0/255.240.0.0 - local = 192.168.0.0/255.255.0.0 + OnionAddrRange ${cfg.onionAddrRange} - ${cfg.torsocks.config} - ''; - makeTorsocks = name: server: pkgs.writeTextFile { - name = name; - text = '' - #!${pkgs.stdenv.shell} - TORSOCKS_CONF_FILE=${pkgs.writeText "torsocks.conf" (makeConfig server)} LD_PRELOAD="${pkgs.torsocks}/lib/torsocks/libtorsocks.so $LD_PRELOAD" "$@" - ''; - executable = true; - destination = "/bin/${name}"; - }; + ${optionalNullStr cfg.socks5Username + "SOCKS5Username ${cfg.socks5Username}"} + ${optionalNullStr cfg.socks5Password + "SOCKS5Password ${cfg.socks5Password}"} - torsocks = makeTorsocks "torsocks" cfg.torsocks.server; - torsocksFaster = makeTorsocks "torsocks-faster" cfg.torsocks.serverFaster; + AllowInbound ${if cfg.allowInbound then "1" else "0"} + ''; in - { - - ###### interface - options = { - services.tor.torsocks = { - enable = mkOption { - default = cfg.client.enable; + type = types.bool; + default = false; description = '' - Whether to build torsocks scipt to relay application traffic via TOR. + Whether to build <literal>/etc/tor/torsocks.conf</literal> + containing the specified global torsocks configuration. ''; }; server = mkOption { - default = cfg.client.socksListenAddress; - example = "192.168.0.20:9050"; + type = types.str; + default = "127.0.0.1:9050"; + example = "192.168.0.20:1234"; description = '' - IP address of TOR client to use. + IP/Port of the Tor SOCKS server. Currently, hostnames are + NOT supported by torsocks. ''; }; - serverFaster = mkOption { - default = cfg.client.socksListenAddressFaster; - example = "192.168.0.20:9063"; + onionAddrRange = mkOption { + type = types.str; + default = "127.42.42.0/24"; description = '' - IP address of TOR client to use for applications like web browsers which - need less circuit isolation to achive satisfactory performance. + Tor hidden sites do not have real IP addresses. This + specifies what range of IP addresses will be handed to the + application as "cookies" for .onion names. Of course, you + should pick a block of addresses which you aren't going to + ever need to actually connect to. This is similar to the + MapAddress feature of the main tor daemon. ''; }; - config = mkOption { - default = ""; + socks5Username = mkOption { + type = types.nullOr types.str; + default = null; + example = "bob"; description = '' - Extra configuration. Contents will be added verbatim to torsocks - configuration file. + SOCKS5 username. The <literal>TORSOCKS_USERNAME</literal> + environment variable overrides this option if it is set. ''; }; - }; - - }; + socks5Password = mkOption { + type = types.nullOr types.str; + default = null; + example = "sekret"; + description = '' + SOCKS5 password. The <literal>TORSOCKS_PASSWORD</literal> + environment variable overrides this option if it is set. + ''; + }; - ###### implementation + allowInbound = mkOption { + type = types.bool; + default = false; + description = '' + Set Torsocks to accept inbound connections. If set to + <literal>true</literal>, listen() and accept() will be + allowed to be used with non localhost address. + ''; + }; - config = mkIf cfg.torsocks.enable { + }; + }; - environment.systemPackages = [ torsocks torsocksFaster ]; # expose it to the users + config = mkIf cfg.enable { + environment.systemPackages = [ pkgs.torsocks ]; + environment.etc = + [ { source = pkgs.writeText "torsocks.conf" configFile; + target = "tor/torsocks.conf"; + } + ]; }; - } diff --git a/nixos/modules/services/torrent/peerflix.nix b/nixos/modules/services/torrent/peerflix.nix new file mode 100644 index 00000000000..0360deac08b --- /dev/null +++ b/nixos/modules/services/torrent/peerflix.nix @@ -0,0 +1,63 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + cfg = config.services.peerflix; + + configFile = pkgs.writeText "peerflix-config.json" '' + { + "connections": 50, + "tmp": "${cfg.downloadDir}" + } + ''; + +in { + + ###### interface + + options.services.peerflix = { + enable = mkOption { + description = "Whether to enable peerflix service."; + default = false; + type = types.uniq types.bool; + }; + + stateDir = mkOption { + description = "Peerflix state directory."; + default = "/var/lib/peerflix"; + type = types.path; + }; + + downloadDir = mkOption { + description = "Peerflix temporary download directory."; + default = "${cfg.stateDir}/torrents"; + type = types.path; + }; + }; + + ###### implementation + + config = mkIf cfg.enable { + systemd.services.peerflix = { + description = "Peerflix Daemon"; + wantedBy = [ "multi-user.target" ]; + after = [ "network-interfaces.target" ]; + environment.HOME = cfg.stateDir; + + preStart = '' + mkdir -p "${cfg.stateDir}"/{torrents,.config/peerflix-server} + if [ "$(id -u)" = 0 ]; then chown -R peerflix "${cfg.stateDir}"; fi + ln -fs "${configFile}" "${cfg.stateDir}/.config/peerflix-server/config.json" + ''; + + serviceConfig = { + ExecStart = "${pkgs.nodePackages.peerflix-server}/bin/peerflix-server"; + PermissionsStartOnly = true; + User = "peerflix"; + }; + }; + + users.extraUsers.peerflix.uid = config.ids.uids.peerflix; + }; +} diff --git a/nixos/modules/services/web-servers/nginx/default.nix b/nixos/modules/services/web-servers/nginx/default.nix index 7c2d3a42973..0af1b58b7ca 100644 --- a/nixos/modules/services/web-servers/nginx/default.nix +++ b/nixos/modules/services/web-servers/nginx/default.nix @@ -23,6 +23,7 @@ in services.nginx = { enable = mkOption { default = false; + type = types.bool; description = " Enable the nginx Web Server. "; @@ -70,11 +71,13 @@ in }; user = mkOption { + type = types.str; default = "nginx"; description = "User account under which nginx runs."; }; group = mkOption { + type = types.str; default = "nginx"; description = "Group account under which nginx runs."; }; diff --git a/nixos/modules/services/x11/display-managers/default.nix b/nixos/modules/services/x11/display-managers/default.nix index 6b01cde9e2b..8bc8175f88f 100644 --- a/nixos/modules/services/x11/display-managers/default.nix +++ b/nixos/modules/services/x11/display-managers/default.nix @@ -23,6 +23,17 @@ let pathsToLink = [ "/" ]; }; + fontconfig = config.fonts.fontconfig; + xresourcesXft = pkgs.writeText "Xresources-Xft" '' + ${optionalString (fontconfig.dpi != 0) ''Xft.dpi: ${fontconfig.dpi}''} + Xft.antialias: ${if fontconfig.antialias then "1" else "0"} + Xft.rgba: ${fontconfig.subpixel.rgba} + Xft.lcdfilter: lcd${fontconfig.subpixel.lcdfilter} + Xft.hinting: ${if fontconfig.hinting.enable then "1" else "0"} + Xft.autohint: ${if fontconfig.hinting.autohint then "1" else "0"} + Xft.hintstyle: hint${fontconfig.hinting.style} + ''; + # file provided by services.xserver.displayManager.session.script xsession = wm: dm: pkgs.writeScript "xsession" '' @@ -79,6 +90,7 @@ let ''} # Load X defaults. + ${xorg.xrdb}/bin/xrdb -merge ${xresourcesXft} if test -e ~/.Xresources; then ${xorg.xrdb}/bin/xrdb -merge ~/.Xresources elif test -e ~/.Xdefaults; then diff --git a/nixos/modules/system/boot/loader/grub/install-grub.pl b/nixos/modules/system/boot/loader/grub/install-grub.pl index 981b60c004c..ffee0271e93 100644 --- a/nixos/modules/system/boot/loader/grub/install-grub.pl +++ b/nixos/modules/system/boot/loader/grub/install-grub.pl @@ -341,8 +341,9 @@ addEntry("NixOS - Default", $defaultConfig); $conf .= "$extraEntries\n" unless $extraEntriesBeforeNixOS; +my $grubBootPath = $grubBoot->path; # extraEntries could refer to @bootRoot@, which we have to substitute -$conf =~ s/\@bootRoot\@/$grubBoot->path/g; +$conf =~ s/\@bootRoot\@/$grubBootPath/g; # Emit submenus for all system profiles. sub addProfile { diff --git a/nixos/modules/system/boot/loader/grub/ipxe.nix b/nixos/modules/system/boot/loader/grub/ipxe.nix new file mode 100644 index 00000000000..9b5097a4cfd --- /dev/null +++ b/nixos/modules/system/boot/loader/grub/ipxe.nix @@ -0,0 +1,64 @@ +# This module adds a scripted iPXE entry to the GRUB boot menu. + +{ config, lib, pkgs, ... }: + +with lib; + +let + scripts = builtins.attrNames config.boot.loader.grub.ipxe; + + grubEntry = name: + '' + menuentry "iPXE - ${name}" { + linux16 @bootRoot@/ipxe.lkrn + initrd16 @bootRoot@/${name}.ipxe + } + + ''; + + scriptFile = name: + let + value = builtins.getAttr name config.boot.loader.grub.ipxe; + in + if builtins.typeOf value == "path" then value + else builtins.toFile "${name}.ipxe" value; +in +{ + options = + { boot.loader.grub.ipxe = mkOption { + type = types.attrsOf (types.either types.path types.str); + description = + '' + Set of iPXE scripts available for + booting from the GRUB boot menu. + ''; + default = { }; + example = literalExample '' + { demo = ''' + #!ipxe + dhcp + chain http://boot.ipxe.org/demo/boot.php + '''; + }; + ''; + }; + }; + + config = mkIf (builtins.length scripts != 0) { + + boot.loader.grub.extraEntries = + if config.boot.loader.grub.version == 2 then + toString (map grubEntry scripts) + else + throw "iPXE is not supported with GRUB 1."; + + boot.loader.grub.extraFiles = + { "ipxe.lkrn" = "${pkgs.ipxe}/ipxe.lkrn"; } + // + builtins.listToAttrs ( map + (name: { name = name+".ipxe"; value = scriptFile name; }) + scripts + ); + }; + +} diff --git a/nixos/modules/system/boot/systemd.nix b/nixos/modules/system/boot/systemd.nix index 97cbc507e03..05f8c8009bf 100644 --- a/nixos/modules/system/boot/systemd.nix +++ b/nixos/modules/system/boot/systemd.nix @@ -36,6 +36,7 @@ let "graphical.target" "multi-user.target" "network.target" + "network-pre.target" "network-online.target" "nss-lookup.target" "nss-user-lookup.target" @@ -347,7 +348,8 @@ let [Service] ${let env = cfg.globalEnvironment // def.environment; in concatMapStrings (n: - let s = "Environment=\"${n}=${env.${n}}\"\n"; + let s = optionalString (env."${n}" != null) + "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 @@ -947,6 +949,16 @@ in systemd.targets.network-online.after = [ "ip-up.target" ]; + systemd.targets.network-pre = { + wantedBy = [ "network.target" ]; + before = [ "network.target" ]; + }; + + systemd.targets.remote-fs-pre = { + wantedBy = [ "remote-fs.target" ]; + before = [ "remote-fs.target" ]; + }; + systemd.units = mapAttrs' (n: v: nameValuePair "${n}.target" (targetToUnit n v)) cfg.targets // mapAttrs' (n: v: nameValuePair "${n}.service" (serviceToUnit n v)) cfg.services @@ -986,6 +998,15 @@ in users.extraUsers.systemd-journal-gateway.uid = config.ids.uids.systemd-journal-gateway; users.extraGroups.systemd-journal-gateway.gid = config.ids.gids.systemd-journal-gateway; + users.extraUsers.systemd-network.uid = config.ids.uids.systemd-network; + users.extraGroups.systemd-network.gid = config.ids.gids.systemd-network; + + users.extraUsers.systemd-resolve.uid = config.ids.uids.systemd-resolve; + users.extraGroups.systemd-resolve.gid = config.ids.gids.systemd-resolve; + + users.extraUsers.systemd-timesync.uid = config.ids.uids.systemd-timesync; + users.extraGroups.systemd-timesync.gid = config.ids.gids.systemd-timesync; + # Generate timer units for all services that have a ‘startAt’ value. systemd.timers = mapAttrs (name: service: @@ -1021,9 +1042,6 @@ in } (mkIf config.systemd.network.enable { - users.extraUsers.systemd-network.uid = config.ids.uids.systemd-network; - users.extraGroups.systemd-network.gid = config.ids.gids.systemd-network; - systemd.services.systemd-networkd = { wantedBy = [ "multi-user.target" ]; before = [ "network-interfaces.target" ]; @@ -1051,9 +1069,6 @@ in services.timesyncd.enable = mkDefault config.services.ntp.enable; }) (mkIf config.services.resolved.enable { - users.extraUsers.systemd-resolve.uid = config.ids.uids.systemd-resolve; - users.extraGroups.systemd-resolve.gid = config.ids.gids.systemd-resolve; - systemd.services.systemd-resolved = { wantedBy = [ "multi-user.target" ]; restartTriggers = [ config.environment.etc."systemd/resolved.conf".source ]; @@ -1065,9 +1080,6 @@ in ''; }) (mkIf config.services.timesyncd.enable { - users.extraUsers.systemd-timesync.uid = config.ids.uids.systemd-timesync; - users.extraGroups.systemd-timesync.gid = config.ids.gids.systemd-timesync; - systemd.services.systemd-timesyncd = { wantedBy = [ "sysinit.target" ]; restartTriggers = [ config.environment.etc."systemd/timesyncd.conf".source ]; diff --git a/nixos/modules/tasks/filesystems/nfs.nix b/nixos/modules/tasks/filesystems/nfs.nix index 45c1119215e..75c4f93c691 100644 --- a/nixos/modules/tasks/filesystems/nfs.nix +++ b/nixos/modules/tasks/filesystems/nfs.nix @@ -58,7 +58,7 @@ in services.rpcbind.enable = true; - system.fsPackages = [ pkgs.nfsUtils ]; + system.fsPackages = [ pkgs.nfs-utils ]; boot.extraModprobeConfig = mkIf (cfg.lockdPort != null) '' options lockd nlm_udpport=${toString cfg.lockdPort} nlm_tcpport=${toString cfg.lockdPort} @@ -71,11 +71,12 @@ in systemd.services.statd = { description = "NFSv3 Network Status Monitor"; - path = [ pkgs.nfsUtils pkgs.sysvtools pkgs.utillinux ]; + path = [ pkgs.nfs-utils pkgs.sysvtools pkgs.utillinux ]; - wantedBy = [ "multi-user.target" ]; + wantedBy = [ "remote-fs-pre.target" ]; + before = [ "remote-fs-pre.target" ]; requires = [ "basic.target" "rpcbind.service" ]; - after = [ "basic.target" "rpcbind.service" "network.target" ]; + after = [ "basic.target" "rpcbind.service" ]; unitConfig.DefaultDependencies = false; # don't stop during shutdown @@ -88,7 +89,7 @@ in serviceConfig.Type = "forking"; serviceConfig.ExecStart = '' - @${pkgs.nfsUtils}/sbin/rpc.statd rpc.statd --no-notify \ + @${pkgs.nfs-utils}/sbin/rpc.statd rpc.statd --no-notify \ ${if cfg.statdPort != null then "-p ${toString statdPort}" else ""} ''; serviceConfig.Restart = "always"; @@ -99,7 +100,8 @@ in path = [ pkgs.sysvtools pkgs.utillinux ]; - wantedBy = [ "multi-user.target" ]; + wantedBy = [ "remote-fs-pre.target" ]; + before = [ "remote-fs-pre.target" ]; requires = [ "rpcbind.service" ]; after = [ "rpcbind.service" ]; @@ -115,7 +117,7 @@ in ''; serviceConfig.Type = "forking"; - serviceConfig.ExecStart = "@${pkgs.nfsUtils}/sbin/rpc.idmapd rpc.idmapd -c ${idmapdConfFile}"; + serviceConfig.ExecStart = "@${pkgs.nfs-utils}/sbin/rpc.idmapd rpc.idmapd -c ${idmapdConfFile}"; serviceConfig.Restart = "always"; }; diff --git a/nixos/modules/tasks/network-interfaces-scripted.nix b/nixos/modules/tasks/network-interfaces-scripted.nix index 34f0cbabc3b..310527667d7 100644 --- a/nixos/modules/tasks/network-interfaces-scripted.nix +++ b/nixos/modules/tasks/network-interfaces-scripted.nix @@ -1,7 +1,7 @@ { config, lib, pkgs, utils, ... }: -with lib; with utils; +with lib; let @@ -54,7 +54,7 @@ in networkSetup = { description = "Networking Setup"; - after = [ "network-interfaces.target" ]; + after = [ "network-interfaces.target" "network-pre.target" ]; before = [ "network.target" ]; wantedBy = [ "network.target" ]; @@ -66,7 +66,7 @@ in serviceConfig.RemainAfterExit = true; script = - (optionalString (!config.services.resolved.enable) '' + '' # Set the static DNS configuration, if given. ${pkgs.openresolv}/sbin/resolvconf -m 1 -a static <<EOF ${optionalString (cfg.nameservers != [] && cfg.domain != null) '' @@ -77,9 +77,9 @@ in nameserver ${ns} '')} EOF - '') + '' + # Set the default gateway. - ${optionalString (cfg.defaultGateway != null) '' + ${optionalString (cfg.defaultGateway != null && cfg.defaultGateway != "") '' # FIXME: get rid of "|| true" (necessary to make it idempotent). ip route add default via "${cfg.defaultGateway}" ${ optionalString (cfg.defaultGatewayWindowSize != null) @@ -105,7 +105,7 @@ in wantedBy = [ "network-interfaces.target" ]; before = [ "network-interfaces.target" ]; bindsTo = [ (subsystemDevice i.name) ]; - after = [ (subsystemDevice i.name) ]; + after = [ (subsystemDevice i.name) "network-pre.target" ]; serviceConfig.Type = "oneshot"; serviceConfig.RemainAfterExit = true; path = [ pkgs.iproute ]; @@ -155,7 +155,7 @@ in createTunDevice = i: nameValuePair "${i.name}-netdev" { description = "Virtual Network Interface ${i.name}"; requires = [ "dev-net-tun.device" ]; - after = [ "dev-net-tun.device" ]; + after = [ "dev-net-tun.device" "network-pre.target" ]; wantedBy = [ "network.target" (subsystemDevice i.name) ]; before = [ "network-interfaces.target" (subsystemDevice i.name) ]; path = [ pkgs.iproute ]; @@ -180,7 +180,8 @@ in { description = "Bridge Interface ${n}"; wantedBy = [ "network.target" (subsystemDevice n) ]; bindsTo = deps; - after = deps ++ concatMap (i: [ "network-addresses-${i}.service" "network-link-${i}.service" ]) v.interfaces; + after = [ "network-pre.target" ] ++ deps + ++ concatMap (i: [ "network-addresses-${i}.service" "network-link-${i}.service" ]) v.interfaces; before = [ "network-interfaces.target" (subsystemDevice n) ]; serviceConfig.Type = "oneshot"; serviceConfig.RemainAfterExit = true; @@ -214,7 +215,8 @@ in { description = "Bond Interface ${n}"; wantedBy = [ "network.target" (subsystemDevice n) ]; bindsTo = deps; - after = deps ++ concatMap (i: [ "network-addresses-${i}.service" "network-link-${i}.service" ]) v.interfaces; + after = [ "network-pre.target" ] ++ deps + ++ concatMap (i: [ "network-addresses-${i}.service" "network-link-${i}.service" ]) v.interfaces; before = [ "network-interfaces.target" (subsystemDevice n) ]; serviceConfig.Type = "oneshot"; serviceConfig.RemainAfterExit = true; @@ -250,7 +252,7 @@ in { description = "Vlan Interface ${n}"; wantedBy = [ "network.target" (subsystemDevice n) ]; bindsTo = deps; - after = deps; + after = [ "network-pre.target" ] ++ deps; before = [ "network-interfaces.target" (subsystemDevice n) ]; serviceConfig.Type = "oneshot"; serviceConfig.RemainAfterExit = true; @@ -274,7 +276,7 @@ in { description = "6-to-4 Tunnel Interface ${n}"; wantedBy = [ "network.target" (subsystemDevice n) ]; bindsTo = deps; - after = deps; + after = [ "network-pre.target" ] ++ deps; before = [ "network-interfaces.target" (subsystemDevice n) ]; serviceConfig.Type = "oneshot"; serviceConfig.RemainAfterExit = true; @@ -301,7 +303,7 @@ in { description = "Vlan Interface ${n}"; wantedBy = [ "network.target" (subsystemDevice n) ]; bindsTo = deps; - after = deps; + after = [ "network-pre.target" ] ++ deps; before = [ "network-interfaces.target" (subsystemDevice n) ]; serviceConfig.Type = "oneshot"; serviceConfig.RemainAfterExit = true; diff --git a/nixos/modules/tasks/network-interfaces-systemd.nix b/nixos/modules/tasks/network-interfaces-systemd.nix index ee3efbbc9ff..10185c7709b 100644 --- a/nixos/modules/tasks/network-interfaces-systemd.nix +++ b/nixos/modules/tasks/network-interfaces-systemd.nix @@ -1,7 +1,7 @@ { config, lib, pkgs, utils, ... }: -with lib; with utils; +with lib; let diff --git a/nixos/modules/tasks/network-interfaces.nix b/nixos/modules/tasks/network-interfaces.nix index e4b200ed534..9c6c71a1dbb 100644 --- a/nixos/modules/tasks/network-interfaces.nix +++ b/nixos/modules/tasks/network-interfaces.nix @@ -669,6 +669,7 @@ in { description = "All Network Interfaces"; wantedBy = [ "network.target" ]; before = [ "network.target" ]; + after = [ "network-pre.target" ]; unitConfig.X-StopOnReconfiguration = true; }; @@ -677,6 +678,7 @@ in description = "Extra networking commands."; before = [ "network.target" ]; wantedBy = [ "network.target" ]; + after = [ "network-pre.target" ]; unitConfig.ConditionCapability = "CAP_NET_ADMIN"; path = [ pkgs.iproute ]; serviceConfig.Type = "oneshot"; @@ -692,7 +694,7 @@ in wantedBy = [ "network-interfaces.target" ]; before = [ "network-interfaces.target" ]; bindsTo = [ (subsystemDevice i.name) ]; - after = [ (subsystemDevice i.name) ]; + after = [ (subsystemDevice i.name) "network-pre.target" ]; path = [ pkgs.iproute ]; serviceConfig = { Type = "oneshot"; diff --git a/nixos/modules/virtualisation/docker-image.nix b/nixos/modules/virtualisation/docker-image.nix index cabb1712b6c..0195ca5c6dc 100644 --- a/nixos/modules/virtualisation/docker-image.nix +++ b/nixos/modules/virtualisation/docker-image.nix @@ -1,67 +1,19 @@ -{ config, lib, pkgs, ... }: +{ config, pkgs, ... }: -with lib; - -let - pkgs2storeContents = l : map (x: { object = x; symlink = "none"; }) l; - -in { - # Create the tarball - system.build.dockerImage = import ../../lib/make-system-tarball.nix { - inherit (pkgs) stdenv perl xz pathsFromGraph; - - contents = []; - extraArgs = "--owner=0"; - storeContents = [ - { object = config.system.build.toplevel + "/init"; - symlink = "/bin/init"; - } - ] ++ (pkgs2storeContents [ pkgs.stdenv ]); - }; +{ + imports = [ + ../profiles/container.nix + ]; boot.postBootCommands = '' - # After booting, register the contents of the Nix store in the Nix - # database. - if [ -f /nix-path-registration ]; then - ${config.nix.package}/bin/nix-store --load-db < /nix-path-registration && - rm /nix-path-registration - fi - - # nixos-rebuild also requires a "system" profile and an - # /etc/NIXOS tag. - touch /etc/NIXOS - ${config.nix.package}/bin/nix-env -p /nix/var/nix/profiles/system --set /run/current-system - # Set virtualisation to docker - echo "docker" > /run/systemd/container + echo "docker" > /run/systemd/container ''; - - # Docker image config. - imports = [ - ../installer/cd-dvd/channel.nix - ../profiles/minimal.nix - ../profiles/clone-config.nix - ]; - - boot.isContainer = true; - # Iptables do not work in Docker. networking.firewall.enable = false; - services.openssh.enable = true; - # Socket activated ssh presents problem in Docker. services.openssh.startWhenNeeded = false; - - # Allow the user to login as root without password. - users.extraUsers.root.initialHashedPassword = mkOverride 150 ""; - - # Some more help text. - services.mingetty.helpLine = - '' - - Log in as "root" with an empty password. - ''; } diff --git a/nixos/modules/virtualisation/docker.nix b/nixos/modules/virtualisation/docker.nix index 9ae9624fd48..5be76b2682f 100644 --- a/nixos/modules/virtualisation/docker.nix +++ b/nixos/modules/virtualisation/docker.nix @@ -7,8 +7,8 @@ with lib; let cfg = config.virtualisation.docker; - pro = config.nix.proxy; - proxy_env = optionalAttrs (pro != "") { Environment = "\"http_proxy=${pro}\""; }; + pro = config.networking.proxy.default; + proxy_env = optionalAttrs (pro != null) { Environment = "\"http_proxy=${pro}\""; }; in diff --git a/nixos/modules/virtualisation/lxc-container.nix b/nixos/modules/virtualisation/lxc-container.nix new file mode 100644 index 00000000000..2fa749d542e --- /dev/null +++ b/nixos/modules/virtualisation/lxc-container.nix @@ -0,0 +1,26 @@ +{ config, pkgs, lib, ... }: + +with lib; + +{ + imports = [ + ../profiles/container.nix + ]; + + # Allow the user to login as root without password. + users.extraUsers.root.initialHashedPassword = mkOverride 150 ""; + + # Some more help text. + services.mingetty.helpLine = + '' + + Log in as "root" with an empty password. + ''; + + # Containers should be light-weight, so start sshd on demand. + services.openssh.enable = mkDefault true; + services.openssh.startWhenNeeded = mkDefault true; + + # Allow ssh connections + networking.firewall.allowedTCPPorts = [ 22 ]; +} diff --git a/nixos/release.nix b/nixos/release.nix index ff97b956a2e..efc49adce46 100644 --- a/nixos/release.nix +++ b/nixos/release.nix @@ -213,6 +213,12 @@ in rec { inherit system; }); + # Provide container tarball for lxc, libvirt-lxc, docker-lxc, ... + container_tarball = forAllSystems (system: makeSystemTarball { + module = ./modules/virtualisation/lxc-container.nix; + inherit system; + }); + /* system_tarball_fuloong2f = assert builtins.currentSystem == "mips64-linux"; @@ -239,10 +245,12 @@ in rec { tests.chromium = callTest tests/chromium.nix {}; tests.cjdns = callTest tests/cjdns.nix {}; tests.containers = callTest tests/containers.nix {}; + tests.docker = scrubDrv (import tests/docker.nix { system = "x86_64-linux"; }); tests.dockerRegistry = scrubDrv (import tests/docker-registry.nix { system = "x86_64-linux"; }); tests.etcd = scrubDrv (import tests/etcd.nix { system = "x86_64-linux"; }); tests.firefox = callTest tests/firefox.nix {}; tests.firewall = callTest tests/firewall.nix {}; + tests.fleet = scrubDrv (import tests/fleet.nix { system = "x86_64-linux"; }); tests.gnome3 = callTest tests/gnome3.nix {}; tests.installer.grub1 = forAllSystems (system: scrubDrv (import tests/installer.nix { inherit system; }).grub1.test); tests.installer.lvm = forAllSystems (system: scrubDrv (import tests/installer.nix { inherit system; }).lvm.test); @@ -290,6 +298,7 @@ in rec { tests.nfs3 = callTest tests/nfs.nix { version = 3; }; tests.nsd = callTest tests/nsd.nix {}; tests.openssh = callTest tests/openssh.nix {}; + tests.peerflix = callTest tests/peerflix.nix {}; tests.printing = callTest tests/printing.nix {}; tests.proxy = callTest tests/proxy.nix {}; tests.quake3 = callTest tests/quake3.nix {}; diff --git a/nixos/tests/bittorrent.nix b/nixos/tests/bittorrent.nix index 3500ad8ccc3..0d0f00212a0 100644 --- a/nixos/tests/bittorrent.nix +++ b/nixos/tests/bittorrent.nix @@ -81,7 +81,7 @@ in # Create the torrent. $tracker->succeed("mkdir /tmp/data"); $tracker->succeed("cp ${file} /tmp/data/test.tar.bz2"); - $tracker->succeed("transmission-create /tmp/data/test.tar.bz2 -t http://${(pkgs.lib.head nodes.tracker.config.networking.interfaces.eth1.ip4).address}:6969/announce -o /tmp/test.torrent"); + $tracker->succeed("transmission-create /tmp/data/test.tar.bz2 -p -t http://${(pkgs.lib.head nodes.tracker.config.networking.interfaces.eth1.ip4).address}:6969/announce -o /tmp/test.torrent"); $tracker->succeed("chmod 644 /tmp/test.torrent"); # Start the tracker. !!! use a less crappy tracker diff --git a/nixos/tests/docker.nix b/nixos/tests/docker.nix new file mode 100644 index 00000000000..63c909ff294 --- /dev/null +++ b/nixos/tests/docker.nix @@ -0,0 +1,24 @@ +# This test runs docker and checks if simple container starts + +import ./make-test.nix { + name = "docker"; + + nodes = { + docker = + { config, pkgs, ... }: + { + virtualisation.docker.enable = true; + }; + }; + + testScript = '' + startAll; + + $docker->waitForUnit("docker.service"); + $docker->succeed("tar cv --files-from /dev/null | docker import - scratch"); + $docker->succeed("docker run -d --name=sleeping -v /nix/store:/nix/store -v /run/current-system/sw/bin:/bin scratch /bin/sleep 10"); + $docker->succeed("docker ps | grep sleeping"); + $docker->succeed("docker stop sleeping"); + ''; + +} diff --git a/nixos/tests/fleet.nix b/nixos/tests/fleet.nix new file mode 100644 index 00000000000..c60f596b6f5 --- /dev/null +++ b/nixos/tests/fleet.nix @@ -0,0 +1,73 @@ +import ./make-test.nix rec { + name = "simple"; + + nodes = { + node1 = + { config, pkgs, ... }: + { + services = { + etcd = { + enable = true; + listenPeerUrls = ["http://0.0.0.0:7001"]; + initialAdvertisePeerUrls = ["http://node1:7001"]; + initialCluster = ["node1=http://node1:7001" "node2=http://node2:7001"]; + }; + }; + + services.fleet = { + enable = true; + metadata.name = "node1"; + }; + + networking.firewall.allowedTCPPorts = [ 7001 ]; + }; + + node2 = + { config, pkgs, ... }: + { + services = { + etcd = { + enable = true; + listenPeerUrls = ["http://0.0.0.0:7001"]; + initialAdvertisePeerUrls = ["http://node2:7001"]; + initialCluster = ["node1=http://node1:7001" "node2=http://node2:7001"]; + }; + }; + + services.fleet = { + enable = true; + metadata.name = "node2"; + }; + + networking.firewall.allowedTCPPorts = [ 7001 ]; + }; + }; + + service = builtins.toFile "hello.service" '' + [Unit] + Description=Hello World + + [Service] + ExecStart=/bin/sh -c "while true; do echo \"Hello, world\"; /var/run/current-system/sw/bin/sleep 1; done" + + [X-Fleet] + MachineMetadata=name=node2 + ''; + + testScript = + '' + startAll; + $node1->waitForUnit("fleet.service"); + $node2->waitForUnit("fleet.service"); + + $node2->waitUntilSucceeds("fleetctl list-machines | grep node1"); + $node1->waitUntilSucceeds("fleetctl list-machines | grep node2"); + + $node1->succeed("cp ${service} hello.service && fleetctl submit hello.service"); + $node1->succeed("fleetctl list-unit-files | grep hello"); + $node1->succeed("fleetctl start hello.service"); + $node1->waitUntilSucceeds("fleetctl list-units | grep running"); + $node1->succeed("fleetctl stop hello.service"); + $node1->succeed("fleetctl destroy hello.service"); + ''; +} diff --git a/nixos/tests/installer.nix b/nixos/tests/installer.nix index 4ee0e064c10..641ff924e14 100644 --- a/nixos/tests/installer.nix +++ b/nixos/tests/installer.nix @@ -29,6 +29,10 @@ let pkgs.unionfs-fuse pkgs.gummiboot ]; + + # Don't use https://cache.nixos.org since the fake + # cache.nixos.org doesn't do https. + nix.binaryCaches = [ http://cache.nixos.org/ ]; } ]; }).config.system.build.isoImage; @@ -38,7 +42,7 @@ let makeConfig = { testChannel, grubVersion, grubDevice, grubIdentifier , readOnly ? true, forceGrubReinstallCount ? 0 }: pkgs.writeText "configuration.nix" '' - { config, pkgs, modulesPath, ... }: + { config, lib, pkgs, modulesPath, ... }: { imports = [ ./hardware-configuration.nix @@ -59,6 +63,8 @@ let ${optionalString (!readOnly) "nix.readOnlyStore = false;"} environment.systemPackages = [ ${optionalString testChannel "pkgs.rlwrap"} ]; + + nix.binaryCaches = [ http://cache.nixos.org/ ]; } ''; @@ -66,7 +72,7 @@ let # Configuration of a web server that simulates the Nixpkgs channel # distribution server. webserver = - { config, pkgs, ... }: + { config, lib, pkgs, ... }: { services.httpd.enable = true; services.httpd.adminAddr = "foo@example.org"; @@ -185,8 +191,9 @@ let $machine->succeed("test -e /boot/grub"); # Did the swap device get activated? - $machine->waitForUnit("swap.target"); - $machine->succeed("cat /proc/swaps | grep -q /dev"); + # uncomment once https://bugs.freedesktop.org/show_bug.cgi?id=86930 is resolved + #$machine->waitForUnit("swap.target"); + $machine->waitUntilSucceeds("cat /proc/swaps | grep -q /dev"); # Check whether the channel works. $machine->succeed("nix-env -i coreutils >&2"); diff --git a/nixos/tests/kde4.nix b/nixos/tests/kde4.nix index fcc5101feb3..dd2574fd02a 100644 --- a/nixos/tests/kde4.nix +++ b/nixos/tests/kde4.nix @@ -41,8 +41,7 @@ import ./make-test.nix ({ pkgs, ... }: { ]; }; - testScript = - '' + testScript = '' $machine->waitUntilSucceeds("pgrep plasma-desktop"); $machine->waitForWindow(qr/plasma-desktop/); @@ -60,7 +59,7 @@ import ./make-test.nix ({ pkgs, ... }: { $machine->sleep(10); - $machine->screenshot("screen"); + $machine->screenshot("screen"); ''; }) diff --git a/nixos/tests/kubernetes.nix b/nixos/tests/kubernetes.nix index e5fe8d2b879..1ca6153bcb9 100644 --- a/nixos/tests/kubernetes.nix +++ b/nixos/tests/kubernetes.nix @@ -45,10 +45,10 @@ import ./make-test.nix rec { nodes = { master = - { config, pkgs, nodes, ... }: + { config, pkgs, lib, nodes, ... }: { virtualisation.memorySize = 512; - virtualisation.kubernetes = { + services.kubernetes = { roles = ["master" "node"]; controllerManager.machines = ["master" "node"]; kubelet.extraOpts = "-network_container_image=master:5000/pause"; @@ -75,6 +75,7 @@ import ./make-test.nix rec { ipAddress = "10.10.0.1"; prefixLength = 24; }; + eth2.ip4 = lib.mkOverride 0 [ ]; }; networking.localCommands = '' ip route add 10.10.0.0/16 dev cbr0 @@ -89,9 +90,9 @@ import ./make-test.nix rec { }; node = - { config, pkgs, nodes, ... }: + { config, pkgs, lib, nodes, ... }: { - virtualisation.kubernetes = { + services.kubernetes = { roles = ["node"]; kubelet.extraOpts = "-network_container_image=master:5000/pause"; verbose = true; @@ -112,6 +113,7 @@ import ./make-test.nix rec { ipAddress = "10.10.1.1"; prefixLength = 24; }; + eth2.ip4 = lib.mkOverride 0 [ ]; }; networking.localCommands = '' ip route add 10.10.0.0/16 dev cbr0 diff --git a/nixos/tests/mesos.nix b/nixos/tests/mesos.nix new file mode 100644 index 00000000000..4fc02d1cd3f --- /dev/null +++ b/nixos/tests/mesos.nix @@ -0,0 +1,25 @@ +import ./make-test.nix { + name = "simple"; + + machine = { config, pkgs, ... }: { + services.zookeeper.enable = true; + virtualisation.docker.enable = true; + services.mesos = { + slave = { + enable = true; + master = "zk://localhost:2181/mesos"; + }; + master = { + enable = true; + zk = "zk://localhost:2181/mesos"; + }; + }; + }; + + testScript = + '' + startAll; + $machine->waitForUnit("mesos-master.service"); + $machine->waitForUnit("mesos-slave.service"); + ''; +} diff --git a/nixos/tests/nfs.nix b/nixos/tests/nfs.nix index 61b2431c04c..5ed805a1695 100644 --- a/nixos/tests/nfs.nix +++ b/nixos/tests/nfs.nix @@ -38,7 +38,8 @@ in testScript = '' $server->waitForUnit("nfsd"); - $server->waitForUnit("network.target"); + $server->succeed("systemctl start network-online.target"); + $server->waitForUnit("network-online.target"); startAll; diff --git a/nixos/tests/peerflix.nix b/nixos/tests/peerflix.nix new file mode 100644 index 00000000000..739936a10b2 --- /dev/null +++ b/nixos/tests/peerflix.nix @@ -0,0 +1,21 @@ +# This test runs peerflix and checks if peerflix starts + +import ./make-test.nix { + name = "peerflix"; + + nodes = { + peerflix = + { config, pkgs, ... }: + { + services.peerflix.enable = true; + }; + }; + + testScript = '' + startAll; + + $peerflix->waitForUnit("peerflix.service"); + $peerflix->waitUntilSucceeds("curl localhost:9000"); + ''; + +} |