diff options
Diffstat (limited to 'nixos')
101 files changed, 1382 insertions, 596 deletions
diff --git a/nixos/doc/manual/development/sources.xml b/nixos/doc/manual/development/sources.xml index 0b2528e9a77..a2896cd7a13 100644 --- a/nixos/doc/manual/development/sources.xml +++ b/nixos/doc/manual/development/sources.xml @@ -8,7 +8,7 @@ <para>By default, NixOS’s <command>nixos-rebuild</command> command uses the NixOS and Nixpkgs sources provided by the -<literal>nixos-unstable</literal> channel (kept in +<literal>nixos</literal> channel (kept in <filename>/nix/var/nix/profiles/per-user/root/channels/nixos</filename>). To modify NixOS, however, you should check out the latest sources from Git. This is as follows: @@ -41,7 +41,7 @@ branch based on your current NixOS version: $ nixos-version 17.09pre104379.6e0b727 (Hummingbird) -$ git checkout -b local e3938c8 +$ git checkout -b local 6e0b727 </screen> Or, to base your local branch on the latest version available in a @@ -87,7 +87,11 @@ $ ln -s <replaceable>/my/sources</replaceable>/nixpkgs ~/.nix-defexpr/nixpkgs You may want to delete the symlink <filename>~/.nix-defexpr/channels_root</filename> to prevent root’s -NixOS channel from clashing with your own tree.</para> +NixOS channel from clashing with your own tree (this may break the +command-not-found utility though). If you want to go back to the default +state, you may just remove the <filename>~/.nix-defexpr</filename> +directory completely, log out and log in again and it should have been +recreated with a link to the root channels.</para> <!-- FIXME: not sure what this means. <para>You should not pass the base directory diff --git a/nixos/doc/manual/release-notes/rl-1703.xml b/nixos/doc/manual/release-notes/rl-1703.xml index 639b23b229b..28c573e6d23 100644 --- a/nixos/doc/manual/release-notes/rl-1703.xml +++ b/nixos/doc/manual/release-notes/rl-1703.xml @@ -501,6 +501,14 @@ following incompatible changes:</para> necessary to pull in all of <literal>bind</literal> to use them. </para> </listitem> + + <listitem> + <para> + Per-user configuration was moved from <filename>~/.nixpkgs</filename> to + <filename>~/.config/nixpkgs</filename>. The former is still valid for + <filename>config.nix</filename> for backwards compatibility. + </para> + </listitem> </itemizedlist> </section> </section> diff --git a/nixos/doc/manual/release-notes/rl-1709.xml b/nixos/doc/manual/release-notes/rl-1709.xml index bd999b60013..5fba4c34ec8 100644 --- a/nixos/doc/manual/release-notes/rl-1709.xml +++ b/nixos/doc/manual/release-notes/rl-1709.xml @@ -35,6 +35,8 @@ following incompatible changes:</para> <itemizedlist> <listitem> <para> + Top-level <literal>idea</literal> package collection was renamed. + All JetBrains IDEs are now at <literal>jetbrains</literal>. </para> </listitem> </itemizedlist> diff --git a/nixos/lib/test-driver/Machine.pm b/nixos/lib/test-driver/Machine.pm index 30664406b26..c619264eb94 100644 --- a/nixos/lib/test-driver/Machine.pm +++ b/nixos/lib/test-driver/Machine.pm @@ -542,16 +542,20 @@ sub getScreenText { $self->nest("performing optical character recognition", sub { my $tmpbase = Cwd::abs_path(".")."/ocr"; my $tmpin = $tmpbase."in.ppm"; - my $tmpout = "$tmpbase.ppm"; $self->sendMonitorCommand("screendump $tmpin"); - system("ppmtopgm $tmpin | pamscale 4 -filter=lanczos > $tmpout") == 0 - or die "cannot scale screenshot"; + + my $magickArgs = "-filter Catrom -density 72 -resample 300 " + . "-contrast -normalize -despeckle -type grayscale " + . "-sharpen 1 -posterize 3 -negate -gamma 100 " + . "-blur 1x65535"; + my $tessArgs = "-c debug_file=/dev/null --psm 11 --oem 2"; + + $text = `convert $magickArgs $tmpin tiff:- | tesseract - - $tessArgs`; + my $status = $? >> 8; unlink $tmpin; - system("tesseract $tmpout $tmpbase") == 0 or die "OCR failed"; - unlink $tmpout; - $text = read_file("$tmpbase.txt"); - unlink "$tmpbase.txt"; + + die "OCR failed with exit code $status" if $status != 0; }); return $text; } diff --git a/nixos/lib/testing.nix b/nixos/lib/testing.nix index 8539fef0a19..58c447c76db 100644 --- a/nixos/lib/testing.nix +++ b/nixos/lib/testing.nix @@ -93,7 +93,7 @@ rec { vms = map (m: m.config.system.build.vm) (lib.attrValues nodes); - ocrProg = tesseract; + ocrProg = tesseract_4.override { enableLanguages = [ "eng" ]; }; # Generate onvenience wrappers for running the test driver # interactively with the specified network, and for starting the @@ -111,7 +111,8 @@ rec { vms=($(for i in ${toString vms}; do echo $i/bin/run-*-vm; done)) wrapProgram $out/bin/nixos-test-driver \ --add-flags "''${vms[*]}" \ - ${lib.optionalString enableOCR "--prefix PATH : '${ocrProg}/bin'"} \ + ${lib.optionalString enableOCR + "--prefix PATH : '${ocrProg}/bin:${imagemagick}/bin'"} \ --run "testScript=\"\$(cat $out/test-script)\"" \ --set testScript '$testScript' \ --set VLANS '${toString vlans}' diff --git a/nixos/maintainers/scripts/ec2/create-amis.sh b/nixos/maintainers/scripts/ec2/create-amis.sh index 1e397b0f176..24ced8da531 100755 --- a/nixos/maintainers/scripts/ec2/create-amis.sh +++ b/nixos/maintainers/scripts/ec2/create-amis.sh @@ -3,21 +3,20 @@ # To start with do: nix-shell -p awscli --run "aws configure" - +set -e set -o pipefail -#set -x - -stateDir=${TMPDIR:-/tmp}/ec2-image -echo "keeping state in $stateDir" -mkdir -p $stateDir version=$(nix-instantiate --eval --strict '<nixpkgs>' -A lib.nixpkgsVersion | sed s/'"'//g) major=${version:0:5} echo "NixOS version is $version ($major)" +stateDir=/var/tmp/ec2-image-$version +echo "keeping state in $stateDir" +mkdir -p $stateDir + rm -f ec2-amis.nix -types="hvm pv" +types="hvm" stores="ebs s3" regions="eu-west-1 eu-west-2 eu-central-1 us-east-1 us-east-2 us-west-1 us-west-2 ca-central-1 ap-southeast-1 ap-southeast-2 ap-northeast-1 ap-northeast-2 sa-east-1 ap-south-1" @@ -206,7 +205,7 @@ for type in $types; do # Register the AMI. if [ $type = pv ]; then - kernel=$(aws ec2 describe-images --owner amazon --filters "Name=name,Values=pv-grub-hd0_1.04-$arch.gz" | jq -r .Images[0].ImageId) + kernel=$(aws ec2 describe-images --owner amazon --filters "Name=name,Values=pv-grub-hd0_1.05-$arch.gz" | jq -r .Images[0].ImageId) if [ "$kernel" = null ]; then break; fi echo "using PV-GRUB kernel $kernel" extraFlags+=" --virtualization-type paravirtual --kernel $kernel" diff --git a/nixos/maintainers/scripts/gce/create-gce.sh b/nixos/maintainers/scripts/gce/create-gce.sh index 7f8a0d23027..ef1801fe54b 100755 --- a/nixos/maintainers/scripts/gce/create-gce.sh +++ b/nixos/maintainers/scripts/gce/create-gce.sh @@ -1,15 +1,23 @@ -#! /bin/sh -e +#!/usr/bin/env nix-shell +#! nix-shell -i bash -p google-cloud-sdk -BUCKET_NAME=${BUCKET_NAME:-nixos-images} -export NIX_PATH=nixpkgs=../../../.. -export NIXOS_CONFIG=$(dirname $(readlink -f $0))/../../../modules/virtualisation/google-compute-image.nix -export TIMESTAMP=$(date +%Y%m%d%H%M) +set -euo pipefail + +BUCKET_NAME="${BUCKET_NAME:-nixos-images}" +TIMESTAMP="$(date +%Y%m%d%H%M)" +export TIMESTAMP nix-build '<nixpkgs/nixos>' \ - -A config.system.build.googleComputeImage --argstr system x86_64-linux -o gce --option extra-binary-caches http://hydra.nixos.org -j 10 + -A config.system.build.googleComputeImage \ + --arg configuration "{ imports = [ <nixpkgs/nixos/modules/virtualisation/google-compute-image.nix> ]; }" \ + --argstr system x86_64-linux \ + -o gce \ + -j 10 -img=$(echo gce/*.tar.gz) -if ! gsutil ls gs://${BUCKET_NAME}/$(basename $img); then - gsutil cp $img gs://${BUCKET_NAME}/$(basename $img) +img_path=$(echo gce/*.tar.gz) +img_name=$(basename "$img_path") +img_id=$(echo "$img_name" | sed 's|.raw.tar.gz$||;s|\.|-|g;s|_|-|g') +if ! gsutil ls "gs://${BUCKET_NAME}/$img_name"; then + gsutil cp "$img_path" "gs://${BUCKET_NAME}/$img_name" fi -gcloud compute images create $(basename $img .raw.tar.gz | sed 's|\.|-|' | sed 's|_|-|') --source-uri gs://${BUCKET_NAME}/$(basename $img) +gcloud compute images create "$img_id" --source-uri "gs://${BUCKET_NAME}/$img_name" diff --git a/nixos/modules/config/fonts/fontconfig-penultimate.nix b/nixos/modules/config/fonts/fontconfig-penultimate.nix index 8e41d342117..3e163b8ec51 100644 --- a/nixos/modules/config/fonts/fontconfig-penultimate.nix +++ b/nixos/modules/config/fonts/fontconfig-penultimate.nix @@ -3,23 +3,236 @@ with lib; let - cfg = config.fonts.fontconfig.penultimate; + cfg = config.fonts.fontconfig; + fcBool = x: "<bool>" + (boolToString x) + "</bool>"; + + # back-supported fontconfig version and package + # version is used for font cache generation + supportVersion = "210"; + supportPkg = pkgs."fontconfig_${supportVersion}"; + + # latest fontconfig version and package + # version is used for configuration folder name, /etc/fonts/VERSION/ + # note: format differs from supportVersion and can not be used with makeCacheConf latestVersion = pkgs.fontconfig.configVersion; + latestPkg = pkgs.fontconfig; + + # supported version fonts.conf + supportFontsConf = pkgs.makeFontsConf { fontconfig = supportPkg; fontDirectories = config.fonts.fonts; }; + + # configuration file to read fontconfig cache + # version dependent + # priority 0 + cacheConfSupport = makeCacheConf { version = supportVersion; }; + cacheConfLatest = makeCacheConf {}; + + # generate the font cache setting file for a fontconfig version + # use latest when no version is passed + makeCacheConf = { version ? null }: + let + fcPackage = if builtins.isNull version + then "fontconfig" + else "fontconfig_${version}"; + makeCache = fontconfig: pkgs.makeFontsCache { inherit fontconfig; fontDirectories = config.fonts.fonts; }; + cache = makeCache pkgs."${fcPackage}"; + cache32 = makeCache pkgs.pkgsi686Linux."${fcPackage}"; + in + pkgs.writeText "fc-00-nixos-cache.conf" '' + <?xml version='1.0'?> + <!DOCTYPE fontconfig SYSTEM 'fonts.dtd'> + <fontconfig> + <!-- Font directories --> + ${concatStringsSep "\n" (map (font: "<dir>${font}</dir>") config.fonts.fonts)} + <!-- Pre-generated font caches --> + <cachedir>${cache}</cachedir> + ${optionalString (pkgs.stdenv.isx86_64 && cfg.cache32Bit) '' + <cachedir>${cache32}</cachedir> + ''} + </fontconfig> + ''; # The configuration to be included in /etc/font/ - confPkg = pkgs.runCommand "font-penultimate-conf" {} '' + penultimateConf = pkgs.runCommand "font-penultimate-conf" {} '' support_folder=$out/etc/fonts/conf.d latest_folder=$out/etc/fonts/${latestVersion}/conf.d mkdir -p $support_folder mkdir -p $latest_folder - # fontconfig ultimate various configuration files + ln -s ${supportFontsConf} $support_folder/../fonts.conf + ln -s ${latestPkg.out}/etc/fonts/fonts.conf \ + $latest_folder/../fonts.conf + + # fontconfig-penultimate various configuration files ln -s ${pkgs.fontconfig-penultimate}/etc/fonts/conf.d/*.conf \ $support_folder ln -s ${pkgs.fontconfig-penultimate}/etc/fonts/conf.d/*.conf \ $latest_folder + + ln -s ${cacheConfSupport} $support_folder/00-nixos-cache.conf + ln -s ${cacheConfLatest} $latest_folder/00-nixos-cache.conf + + rm $support_folder/10-antialias.conf $latest_folder/10-antialias.conf + ln -s ${antialiasConf} $support_folder/10-antialias.conf + ln -s ${antialiasConf} $latest_folder/10-antialias.conf + + rm $support_folder/10-hinting.conf $latest_folder/10-hinting.conf + ln -s ${hintingConf} $support_folder/10-hinting.conf + ln -s ${hintingConf} $latest_folder/10-hinting.conf + + ${optionalString cfg.useEmbeddedBitmaps '' + rm $support_folder/10-no-embedded-bitmaps.conf + rm $latest_folder/10-no-embedded-bitmaps.conf + ''} + + rm $support_folder/10-subpixel.conf $latest_folder/10-subpixel.conf + ln -s ${subpixelConf} $support_folder/10-subpixel.conf + ln -s ${subpixelConf} $latest_folder/10-subpixel.conf + + ${optionalString (cfg.dpi != 0) '' + ln -s ${dpiConf} $support_folder/11-dpi.conf + ln -s ${dpiConf} $latest_folder/11-dpi.conf + ''} + + ${optionalString (!cfg.includeUserConf) '' + rm $support_folder/50-user.conf + rm $latest_folder/50-user.conf + ''} + + # 51-local.conf + rm $latest_folder/51-local.conf + substitute \ + ${pkgs.fontconfig-penultimate}/etc/fonts/conf.d/51-local.conf \ + $latest_folder/51-local.conf \ + --replace local.conf /etc/fonts/${latestVersion}/local.conf + + ln -s ${defaultFontsConf} $support_folder/52-default-fonts.conf + ln -s ${defaultFontsConf} $latest_folder/52-default-fonts.conf + + ${optionalString cfg.allowBitmaps '' + rm $support_folder/53-no-bitmaps.conf + rm $latest_folder/53-no-bitmaps.conf + ''} + + ${optionalString (!cfg.allowType1) '' + ln -s ${rejectType1} $support_folder/53-no-type1.conf + ln -s ${rejectType1} $latest_folder/53-no-type1.conf + ''} + ''; + + hintingConf = pkgs.writeText "fc-10-hinting.conf" '' + <?xml version='1.0'?> + <!DOCTYPE fontconfig SYSTEM 'fonts.dtd'> + <fontconfig> + + <!-- Default rendering settings --> + <match target="pattern"> + <edit mode="append" name="hinting"> + ${fcBool cfg.hinting.enable} + </edit> + <edit mode="append" name="autohint"> + ${fcBool cfg.hinting.autohint} + </edit> + <edit mode="append" name="hintstyle"> + <const>hintslight</const> + </edit> + </match> + + </fontconfig> + ''; + + antialiasConf = pkgs.writeText "fc-10-antialias.conf" '' + <?xml version='1.0'?> + <!DOCTYPE fontconfig SYSTEM 'fonts.dtd'> + <fontconfig> + + <!-- Default rendering settings --> + <match target="pattern"> + <edit mode="append" name="antialias"> + ${fcBool cfg.antialias} + </edit> + </match> + + </fontconfig> + ''; + + subpixelConf = pkgs.writeText "fc-10-subpixel.conf" '' + <?xml version='1.0'?> + <!DOCTYPE fontconfig SYSTEM 'fonts.dtd'> + <fontconfig> + + <!-- Default rendering settings --> + <match target="pattern"> + <edit mode="append" name="rgba"> + <const>${cfg.subpixel.rgba}</const> + </edit> + <edit mode="append" name="lcdfilter"> + <const>lcd${cfg.subpixel.lcdfilter}</const> + </edit> + </match> + + </fontconfig> + ''; + + dpiConf = pkgs.writeText "fc-11-dpi.conf" '' + <?xml version='1.0'?> + <!DOCTYPE fontconfig SYSTEM 'fonts.dtd'> + <fontconfig> + + <match target="pattern"> + <edit name="dpi" mode="assign"> + <double>${toString cfg.dpi}</double> + </edit> + </match> + + </fontconfig> + ''; + + defaultFontsConf = + let genDefault = fonts: name: + optionalString (fonts != []) '' + <alias> + <family>${name}</family> + <prefer> + ${concatStringsSep "" + (map (font: '' + <family>${font}</family> + '') fonts)} + </prefer> + </alias> + ''; + in + pkgs.writeText "fc-52-nixos-default-fonts.conf" '' + <?xml version='1.0'?> + <!DOCTYPE fontconfig SYSTEM 'fonts.dtd'> + <fontconfig> + + <!-- Default fonts --> + ${genDefault cfg.defaultFonts.sansSerif "sans-serif"} + + ${genDefault cfg.defaultFonts.serif "serif"} + + ${genDefault cfg.defaultFonts.monospace "monospace"} + + </fontconfig> + ''; + + rejectType1 = pkgs.writeText "fc-53-no-type1.conf" '' + <?xml version="1.0"?> + <!DOCTYPE fontconfig SYSTEM "fonts.dtd"> + <fontconfig> + + <!-- Reject Type 1 fonts --> + <selectfont> + <rejectfont> + <pattern> + <patelt name="fontformat"><string>Type 1</string></patelt> + </pattern> + </rejectfont> + </selectfont> + + </fontconfig> ''; in @@ -50,7 +263,7 @@ in config = mkIf (config.fonts.fontconfig.enable && cfg.enable) { - fonts.fontconfig.confPackages = [ confPkg ]; + fonts.fontconfig.confPackages = [ penultimateConf ]; }; diff --git a/nixos/modules/config/fonts/fontconfig-ultimate.nix b/nixos/modules/config/fonts/fontconfig-ultimate.nix index e412146a039..1bf9fdb1984 100644 --- a/nixos/modules/config/fonts/fontconfig-ultimate.nix +++ b/nixos/modules/config/fonts/fontconfig-ultimate.nix @@ -63,6 +63,15 @@ in <literal>none</literal> disables the substitutions. ''; }; + + preset = mkOption { + type = types.enum ["ultimate1" "ultimate2" "ultimate3" "ultimate4" "ultimate5" "osx" "windowsxp"]; + default = "ultimate3"; + description = '' + FreeType rendering settings preset. Any of the presets may be + customized by setting environment variables. + ''; + }; }; }; }; @@ -72,6 +81,7 @@ in config = mkIf (config.fonts.fontconfig.enable && cfg.enable) { fonts.fontconfig.confPackages = [ confPkg ]; + environment.variables."INFINALITY_FT" = cfg.preset; }; diff --git a/nixos/modules/config/fonts/fontconfig.nix b/nixos/modules/config/fonts/fontconfig.nix index 4d3cc26365f..12f5ca2e799 100644 --- a/nixos/modules/config/fonts/fontconfig.nix +++ b/nixos/modules/config/fonts/fontconfig.nix @@ -20,7 +20,7 @@ with lib; let cfg = config.fonts.fontconfig; - fcBool = x: "<bool>" + (if x then "true" else "false") + "</bool>"; + fcBool = x: "<bool>" + (boolToString x) + "</bool>"; # back-supported fontconfig version and package # version is used for font cache generation @@ -104,13 +104,6 @@ let cfg = config.fonts.fontconfig; </match> ''} - <!-- Force autohint always --> - <match target="font"> - <edit name="force_autohint" mode="assign"> - ${fcBool cfg.forceAutohint} - </edit> - </match> - </fontconfig> ''; @@ -174,13 +167,6 @@ let cfg = config.fonts.fontconfig; </edit> </match> - <!-- Render some monospace TTF fonts as bitmaps --> - <match target="pattern"> - <edit name="bitmap_monospace" mode="assign"> - ${fcBool cfg.renderMonoTTFAsBitmap} - </edit> - </match> - </fontconfig> ''; @@ -372,11 +358,11 @@ in autohint = mkOption { type = types.bool; - default = true; + default = false; description = '' - Enable the autohinter, which provides hinting for otherwise - un-hinted fonts. The results are usually lower quality than - correctly-hinted fonts. + Enable the autohinter in place of the default interpreter. + The results are usually lower quality than correctly-hinted + fonts, but better than unhinted fonts. ''; }; }; @@ -453,31 +439,19 @@ in 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.''; - }; - }; }; }; - config = mkIf cfg.enable { - fonts.fontconfig.confPackages = [ confPkg ]; - - environment.systemPackages = [ pkgs.fontconfig ]; - environment.etc.fonts.source = "${fontconfigEtc}/etc/fonts/"; - }; + config = mkMerge [ + (mkIf cfg.enable { + environment.systemPackages = [ pkgs.fontconfig ]; + environment.etc.fonts.source = "${fontconfigEtc}/etc/fonts/"; + }) + (mkIf (cfg.enable && !cfg.penultimate.enable) { + fonts.fontconfig.confPackages = [ confPkg ]; + }) + ]; } diff --git a/nixos/modules/config/fonts/fonts.nix b/nixos/modules/config/fonts/fonts.nix index af3d93fc1bc..0dd01df9da7 100644 --- a/nixos/modules/config/fonts/fonts.nix +++ b/nixos/modules/config/fonts/fonts.nix @@ -37,6 +37,7 @@ with lib; pkgs.xorg.fontbhlucidatypewriter75dpi pkgs.dejavu_fonts pkgs.freefont_ttf + pkgs.gyre-fonts # TrueType substitutes for standard PostScript fonts pkgs.liberation_ttf pkgs.xorg.fontbh100dpi pkgs.xorg.fontmiscmisc diff --git a/nixos/modules/config/shells-environment.nix b/nixos/modules/config/shells-environment.nix index 8a7b3ea0bfd..152493151fd 100644 --- a/nixos/modules/config/shells-environment.nix +++ b/nixos/modules/config/shells-environment.nix @@ -168,9 +168,6 @@ in ${cfg.extraInit} - # The setuid/setcap wrappers override other bin directories. - export PATH="${config.security.wrapperDir}:$PATH" - # ~/bin if it exists overrides other bin directories. export PATH="$HOME/bin:$PATH" ''; diff --git a/nixos/modules/hardware/all-firmware.nix b/nixos/modules/hardware/all-firmware.nix index fb8e1ccab66..bc82bfd066c 100644 --- a/nixos/modules/hardware/all-firmware.nix +++ b/nixos/modules/hardware/all-firmware.nix @@ -26,6 +26,7 @@ with lib; firmwareLinuxNonfree intel2200BGFirmware rtl8723bs-firmware + rtl8192su-firmware ]; }; diff --git a/nixos/modules/installer/tools/nixos-install.sh b/nixos/modules/installer/tools/nixos-install.sh index 57bc249360e..e2ae2ee9fdf 100644 --- a/nixos/modules/installer/tools/nixos-install.sh +++ b/nixos/modules/installer/tools/nixos-install.sh @@ -87,38 +87,6 @@ if ! test -e "$mountPoint"; then exit 1 fi - -# Mount some stuff in the target root directory. -mkdir -m 0755 -p $mountPoint/dev $mountPoint/proc $mountPoint/sys $mountPoint/etc $mountPoint/run $mountPoint/home -mkdir -m 01777 -p $mountPoint/tmp -mkdir -m 0755 -p $mountPoint/tmp/root -mkdir -m 0755 -p $mountPoint/var -mkdir -m 0700 -p $mountPoint/root -mount --rbind /dev $mountPoint/dev -mount --rbind /proc $mountPoint/proc -mount --rbind /sys $mountPoint/sys -mount --rbind / $mountPoint/tmp/root -mount -t tmpfs -o "mode=0755" none $mountPoint/run -rm -rf $mountPoint/var/run -ln -s /run $mountPoint/var/run -for f in /etc/resolv.conf /etc/hosts; do rm -f $mountPoint/$f; [ -f "$f" ] && cp -Lf $f $mountPoint/etc/; done -for f in /etc/passwd /etc/group; do touch $mountPoint/$f; [ -f "$f" ] && mount --rbind -o ro $f $mountPoint/$f; done - -cp -Lf "@cacert@" "$mountPoint/tmp/ca-cert.crt" -export SSL_CERT_FILE=/tmp/ca-cert.crt -# For Nix 1.7 -export CURL_CA_BUNDLE=/tmp/ca-cert.crt - -if [ -n "$runChroot" ]; then - if ! [ -L $mountPoint/nix/var/nix/profiles/system ]; then - echo "$0: installation not finished; cannot chroot into installation directory" - exit 1 - fi - ln -s /nix/var/nix/profiles/system $mountPoint/run/current-system - exec chroot $mountPoint "${chrootCommand[@]}" -fi - - # Get the path of the NixOS configuration file. if test -z "$NIXOS_CONFIG"; then NIXOS_CONFIG=/etc/nixos/configuration.nix @@ -130,121 +98,60 @@ if [ ! -e "$mountPoint/$NIXOS_CONFIG" ] && [ -z "$closure" ]; then fi -# Create the necessary Nix directories on the target device, if they -# don't already exist. -mkdir -m 0755 -p \ - $mountPoint/nix/var/nix/gcroots \ - $mountPoint/nix/var/nix/temproots \ - $mountPoint/nix/var/nix/userpool \ - $mountPoint/nix/var/nix/profiles \ - $mountPoint/nix/var/nix/db \ - $mountPoint/nix/var/log/nix/drvs - -mkdir -m 1775 -p $mountPoint/nix/store -chown @root_uid@:@nixbld_gid@ $mountPoint/nix/store - - -# There is no daemon in the chroot. -unset NIX_REMOTE - - -# We don't have locale-archive in the chroot, so clear $LANG. -export LANG= -export LC_ALL= -export LC_TIME= - - # Builds will use users that are members of this group extraBuildFlags+=(--option "build-users-group" "$buildUsersGroup") - # Inherit binary caches from the host +# TODO: will this still work with Nix 1.12 now that it has no perl? Probably not... binary_caches="$(@perl@/bin/perl -I @nix@/lib/perl5/site_perl/*/* -e 'use Nix::Config; Nix::Config::readConfig; print $Nix::Config::config{"binary-caches"};')" extraBuildFlags+=(--option "binary-caches" "$binary_caches") +nixpkgs="$(readlink -f "$(nix-instantiate --find-file nixpkgs)")" +export NIX_PATH="nixpkgs=$nixpkgs:nixos-config=$mountPoint/$NIXOS_CONFIG" +unset NIXOS_CONFIG -# Copy Nix to the Nix store on the target device, unless it's already there. -if ! NIX_DB_DIR=$mountPoint/nix/var/nix/db nix-store --check-validity @nix@ 2> /dev/null; then - echo "copying Nix to $mountPoint...." - for i in $(@perl@/bin/perl @pathsFromGraph@ @nixClosure@); do - echo " $i" - chattr -R -i $mountPoint/$i 2> /dev/null || true # clear immutable bit - @rsync@/bin/rsync -a $i $mountPoint/nix/store/ - done - - # Register the paths in the Nix closure as valid. This is necessary - # to prevent them from being deleted the first time we install - # something. (I.e., Nix will see that, e.g., the glibc path is not - # valid, delete it to get it out of the way, but as a result nothing - # will work anymore.) - chroot $mountPoint @nix@/bin/nix-store --register-validity < @nixClosure@ -fi - - -# Create the required /bin/sh symlink; otherwise lots of things -# (notably the system() function) won't work. -mkdir -m 0755 -p $mountPoint/bin -# !!! assuming that @shell@ is in the closure -ln -sf @shell@ $mountPoint/bin/sh +# TODO: do I need to set NIX_SUBSTITUTERS here or is the --option binary-caches above enough? -# Build hooks likely won't function correctly in the minimal chroot; just disable them. -unset NIX_BUILD_HOOK +# A place to drop temporary closures +trap "rm -rf $tmpdir" EXIT +tmpdir="$(mktemp -d)" -# Make the build below copy paths from the CD if possible. Note that -# /tmp/root in the chroot is the root of the CD. -export NIX_OTHER_STORES=/tmp/root/nix:$NIX_OTHER_STORES - -p=@nix@/libexec/nix/substituters -export NIX_SUBSTITUTERS=$p/copy-from-other-stores.pl:$p/download-from-binary-cache.pl +# Build a closure (on the host; we then copy it into the guest) +function closure() { + nix-build "${extraBuildFlags[@]}" --no-out-link -E "with import <nixpkgs> {}; runCommand \"closure\" { exportReferencesGraph = [ \"x\" (buildEnv { name = \"env\"; paths = [ ($1) stdenv ]; }) ]; } \"cp x \$out\"" +} +system_closure="$tmpdir/system.closure" if [ -z "$closure" ]; then - # Get the absolute path to the NixOS/Nixpkgs sources. - nixpkgs="$(readlink -f $(nix-instantiate --find-file nixpkgs))" - - nixEnvAction="-f <nixpkgs/nixos> --set -A system" + expr="(import <nixpkgs/nixos> {}).system" + system_root="$(nix-build -E "$expr")" + system_closure="$(closure "$expr")" else - nixpkgs="" - nixEnvAction="--set $closure" + system_root=$closure + # Create a temporary file ending in .closure (so nixos-prepare-root knows to --import it) to transport the store closure + # to the filesytem we're preparing. Also delete it on exit! + nix-store --export $(nix-store -qR $closure) > $system_closure fi -# Build the specified Nix expression in the target store and install -# it into the system configuration profile. -echo "building the system configuration..." -NIX_PATH="nixpkgs=/tmp/root/$nixpkgs:nixos-config=$NIXOS_CONFIG" NIXOS_CONFIG= \ - chroot $mountPoint @nix@/bin/nix-env \ - "${extraBuildFlags[@]}" -p /nix/var/nix/profiles/system $nixEnvAction +channel_root="$(nix-env -p /nix/var/nix/profiles/per-user/root/channels -q nixos --no-name --out-path 2>/dev/null || echo -n "")" +channel_closure="$tmpdir/channel.closure" +nix-store --export $channel_root > $channel_closure +# Populate the target root directory with the basics +@prepare_root@/bin/nixos-prepare-root $mountPoint $channel_root $system_root @nixClosure@ $system_closure $channel_closure -# Copy the NixOS/Nixpkgs sources to the target as the initial contents -# of the NixOS channel. -mkdir -m 0755 -p $mountPoint/nix/var/nix/profiles -mkdir -m 1777 -p $mountPoint/nix/var/nix/profiles/per-user -mkdir -m 0755 -p $mountPoint/nix/var/nix/profiles/per-user/root -srcs=$(nix-env "${extraBuildFlags[@]}" -p /nix/var/nix/profiles/per-user/root/channels -q nixos --no-name --out-path 2>/dev/null || echo -n "") -if [ -z "$noChannelCopy" ] && [ -n "$srcs" ]; then - echo "copying NixOS/Nixpkgs sources..." - chroot $mountPoint @nix@/bin/nix-env \ - "${extraBuildFlags[@]}" -p /nix/var/nix/profiles/per-user/root/channels -i "$srcs" --quiet -fi -mkdir -m 0700 -p $mountPoint/root/.nix-defexpr -ln -sfn /nix/var/nix/profiles/per-user/root/channels $mountPoint/root/.nix-defexpr/channels - - -# Get rid of the /etc bind mounts. -for f in /etc/passwd /etc/group; do [ -f "$f" ] && umount $mountPoint/$f; done +# nixos-prepare-root doesn't currently do anything with file ownership, so we set it up here instead +chown @root_uid@:@nixbld_gid@ $mountPoint/nix/store +mount --rbind /dev $mountPoint/dev +mount --rbind /proc $mountPoint/proc +mount --rbind /sys $mountPoint/sys # Grub needs an mtab. ln -sfn /proc/mounts $mountPoint/etc/mtab - -# Mark the target as a NixOS installation, otherwise -# switch-to-configuration will chicken out. -touch $mountPoint/etc/NIXOS - - # Switch to the new system configuration. This will install Grub with # a menu default pointing at the kernel/initrd/etc of the new # configuration. diff --git a/nixos/modules/installer/tools/nixos-prepare-root.sh b/nixos/modules/installer/tools/nixos-prepare-root.sh new file mode 100644 index 00000000000..c374330f846 --- /dev/null +++ b/nixos/modules/installer/tools/nixos-prepare-root.sh @@ -0,0 +1,105 @@ +#! @shell@ + +# This script's goal is to perform all "static" setup of a filesystem structure from pre-built store paths. Everything +# in here should run in a non-root context and inside a Nix builder. It's designed primarily to be called from image- +# building scripts and from nixos-install, but because it makes very few assumptions about the context in which it runs, +# it could be useful in other contexts as well. +# +# Current behavior: +# - set up basic filesystem structure +# - make Nix store etc. +# - copy Nix, system, channel, and misceallaneous closures to target Nix store +# - register validity of all paths in the target store +# - set up channel and system profiles + +# Ensure a consistent umask. +umask 0022 + +set -e + +mountPoint="$1" +channel="$2" +system="$3" +shift 3 +closures="$@" + +PATH="@coreutils@/bin:@nix@/bin:@perl@/bin:@utillinux@/bin:@rsync@/bin" + +if ! test -e "$mountPoint"; then + echo "mount point $mountPoint doesn't exist" + exit 1 +fi + +# Create a few of the standard directories in the target root directory. +mkdir -m 0755 -p $mountPoint/dev $mountPoint/proc $mountPoint/sys $mountPoint/etc $mountPoint/run $mountPoint/home +mkdir -m 01777 -p $mountPoint/tmp +mkdir -m 0755 -p $mountPoint/tmp/root +mkdir -m 0755 -p $mountPoint/var +mkdir -m 0700 -p $mountPoint/root + +ln -s /run $mountPoint/var/run + +# Create the necessary Nix directories on the target device +mkdir -m 0755 -p \ + $mountPoint/nix/var/nix/gcroots \ + $mountPoint/nix/var/nix/temproots \ + $mountPoint/nix/var/nix/userpool \ + $mountPoint/nix/var/nix/profiles \ + $mountPoint/nix/var/nix/db \ + $mountPoint/nix/var/log/nix/drvs + +mkdir -m 1775 -p $mountPoint/nix/store + +# All Nix operations below should operate on our target store, not /nix/store. +# N.B: this relies on Nix 1.12 or higher +export NIX_REMOTE=local?root=$mountPoint + +# Copy our closures to the Nix store on the target mount point, unless they're already there. +for i in $closures; do + # We support closures both in the format produced by `nix-store --export` and by `exportReferencesGraph`, + # mostly because there doesn't seem to be a single format that can be produced outside of a nix build and + # inside one. See https://github.com/NixOS/nix/issues/1242 for more discussion. + if [[ "$i" =~ \.closure$ ]]; then + echo "importing serialized closure $i to $mountPoint..." + nix-store --import < $i + else + # There has to be a better way to do this, right? + echo "copying closure $i to $mountPoint..." + for j in $(perl @pathsFromGraph@ $i); do + echo " $j... " + rsync -a $j $mountPoint/nix/store/ + done + + nix-store --register-validity < $i + fi +done + +# Create the required /bin/sh symlink; otherwise lots of things +# (notably the system() function) won't work. +if [ ! -x $mountPoint/@shell@ ]; then + echo "Error: @shell@ wasn't included in the closure" >&2 + exit 1 +fi +mkdir -m 0755 -p $mountPoint/bin +ln -sf @shell@ $mountPoint/bin/sh + +echo "setting the system closure to '$system'..." +nix-env "${extraBuildFlags[@]}" -p $mountPoint/nix/var/nix/profiles/system --set "$system" + +ln -sfn /nix/var/nix/profiles/system $mountPoint/run/current-system + +# Copy the NixOS/Nixpkgs sources to the target as the initial contents of the NixOS channel. +mkdir -m 0755 -p $mountPoint/nix/var/nix/profiles +mkdir -m 1777 -p $mountPoint/nix/var/nix/profiles/per-user +mkdir -m 0755 -p $mountPoint/nix/var/nix/profiles/per-user/root + +if [ -z "$noChannelCopy" ] && [ -n "$channel" ]; then + echo "copying channel..." + nix-env --option build-use-substitutes false "${extraBuildFlags[@]}" -p $mountPoint/nix/var/nix/profiles/per-user/root/channels --set "$channel" --quiet +fi +mkdir -m 0700 -p $mountPoint/root/.nix-defexpr +ln -sfn /nix/var/nix/profiles/per-user/root/channels $mountPoint/root/.nix-defexpr/channels + +# Mark the target as a NixOS installation, otherwise switch-to-configuration will chicken out. +touch $mountPoint/etc/NIXOS + diff --git a/nixos/modules/installer/tools/tools.nix b/nixos/modules/installer/tools/tools.nix index a35f6ad8ae5..a3bae78c0ff 100644 --- a/nixos/modules/installer/tools/tools.nix +++ b/nixos/modules/installer/tools/tools.nix @@ -4,7 +4,6 @@ { config, pkgs, modulesPath, ... }: let - cfg = config.installer; makeProg = args: pkgs.substituteAll (args // { @@ -17,6 +16,14 @@ let src = ./nixos-build-vms/nixos-build-vms.sh; }; + nixos-prepare-root = makeProg { + name = "nixos-prepare-root"; + src = ./nixos-prepare-root.sh; + + nix = pkgs.nixUnstable; + inherit (pkgs) perl pathsFromGraph rsync utillinux coreutils; + }; + nixos-install = makeProg { name = "nixos-install"; src = ./nixos-install.sh; @@ -26,6 +33,7 @@ let cacert = "${pkgs.cacert}/etc/ssl/certs/ca-bundle.crt"; root_uid = config.ids.uids.root; nixbld_gid = config.ids.gids.nixbld; + prepare_root = nixos-prepare-root; nixClosure = pkgs.runCommand "closure" { exportReferencesGraph = ["refs" config.nix.package.out]; } @@ -69,6 +77,7 @@ in environment.systemPackages = [ nixos-build-vms + nixos-prepare-root nixos-install nixos-rebuild nixos-generate-config @@ -77,7 +86,7 @@ in ]; system.build = { - inherit nixos-install nixos-generate-config nixos-option nixos-rebuild; + inherit nixos-install nixos-prepare-root nixos-generate-config nixos-option nixos-rebuild; }; }; diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index 0035368273c..52de4b23370 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -89,6 +89,7 @@ ./programs/nano.nix ./programs/oblogout.nix ./programs/screen.nix + ./programs/slock.nix ./programs/shadow.nix ./programs/shell.nix ./programs/spacefm.nix @@ -130,6 +131,7 @@ ./services/audio/liquidsoap.nix ./services/audio/mpd.nix ./services/audio/mopidy.nix + ./services/audio/slimserver.nix ./services/audio/squeezelite.nix ./services/audio/ympd.nix ./services/backup/almir.nix @@ -247,6 +249,7 @@ ./services/mail/rmilter.nix ./services/misc/apache-kafka.nix ./services/misc/autofs.nix + ./services/misc/autorandr.nix ./services/misc/bepasty.nix ./services/misc/canto-daemon.nix ./services/misc/calibre-server.nix @@ -529,6 +532,7 @@ ./services/system/cgmanager.nix ./services/system/cloud-init.nix ./services/system/dbus.nix + ./services/system/earlyoom.nix ./services/system/kerberos.nix ./services/system/nscd.nix ./services/system/uptimed.nix @@ -656,6 +660,7 @@ ./tasks/scsi-link-power-management.nix ./tasks/swraid.nix ./tasks/trackpoint.nix + ./tasks/powertop.nix ./testing/service-runner.nix ./virtualisation/container-config.nix ./virtualisation/containers.nix diff --git a/nixos/modules/programs/command-not-found/command-not-found.nix b/nixos/modules/programs/command-not-found/command-not-found.nix index 9741aa7ca53..6fb926fe1d5 100644 --- a/nixos/modules/programs/command-not-found/command-not-found.nix +++ b/nixos/modules/programs/command-not-found/command-not-found.nix @@ -8,13 +8,14 @@ with lib; let - + cfg = config.programs.command-not-found; commandNotFound = pkgs.substituteAll { name = "command-not-found"; dir = "bin"; src = ./command-not-found.pl; isExecutable = true; inherit (pkgs) perl; + inherit (cfg) dbPath; perlFlags = concatStrings (map (path: "-I ${path}/lib/perl5/site_perl ") [ pkgs.perlPackages.DBI pkgs.perlPackages.DBDSQLite pkgs.perlPackages.StringShellQuote ]); }; @@ -22,50 +23,66 @@ let in { + options.programs.command-not-found = { + + enable = mkEnableOption "command-not-found hook for interactive shell"; + + dbPath = mkOption { + default = "/nix/var/nix/profiles/per-user/root/channels/nixos/programs.sqlite" ; + description = '' + Absolute path to programs.sqlite. + + By default this file will be provided by your channel + (nixexprs.tar.xz). + ''; + type = types.path; + }; + }; - programs.bash.interactiveShellInit = - '' - # This function is called whenever a command is not found. - command_not_found_handle() { - local p=/run/current-system/sw/bin/command-not-found - if [ -x $p -a -f /nix/var/nix/profiles/per-user/root/channels/nixos/programs.sqlite ]; then - # Run the helper program. - $p "$@" - # Retry the command if we just installed it. - if [ $? = 126 ]; then - "$@" + config = mkIf cfg.enable { + programs.bash.interactiveShellInit = + '' + # This function is called whenever a command is not found. + command_not_found_handle() { + local p=${commandNotFound} + if [ -x $p -a -f ${cfg.dbPath} ]; then + # Run the helper program. + $p "$@" + # Retry the command if we just installed it. + if [ $? = 126 ]; then + "$@" + else + return 127 + fi else + echo "$1: command not found" >&2 return 127 fi - else - echo "$1: command not found" >&2 - return 127 - fi - } - ''; + } + ''; - programs.zsh.interactiveShellInit = - '' - # This function is called whenever a command is not found. - command_not_found_handler() { - local p=/run/current-system/sw/bin/command-not-found - if [ -x $p -a -f /nix/var/nix/profiles/per-user/root/channels/nixos/programs.sqlite ]; then - # Run the helper program. - $p "$@" + programs.zsh.interactiveShellInit = + '' + # This function is called whenever a command is not found. + command_not_found_handler() { + local p=${commandNotFound} + if [ -x $p -a -f ${cfg.dbPath} ]; then + # Run the helper program. + $p "$@" - # Retry the command if we just installed it. - if [ $? = 126 ]; then - "$@" + # Retry the command if we just installed it. + if [ $? = 126 ]; then + "$@" + fi + else + # Indicate than there was an error so ZSH falls back to its default handler + echo "$1: command not found" >&2 + return 127 fi - else - # Indicate than there was an error so ZSH falls back to its default handler - return 127 - fi - } - ''; + } + ''; - environment.systemPackages = [ commandNotFound ]; - - # TODO: tab completion for uninstalled commands! :-) + environment.systemPackages = [ commandNotFound ]; + }; } diff --git a/nixos/modules/programs/command-not-found/command-not-found.pl b/nixos/modules/programs/command-not-found/command-not-found.pl index 5bdda26592e..ab7aa204653 100644 --- a/nixos/modules/programs/command-not-found/command-not-found.pl +++ b/nixos/modules/programs/command-not-found/command-not-found.pl @@ -8,7 +8,7 @@ use Config; my $program = $ARGV[0]; -my $dbPath = "/nix/var/nix/profiles/per-user/root/channels/nixos/programs.sqlite"; +my $dbPath = "@dbPath@"; my $dbh = DBI->connect("dbi:SQLite:dbname=$dbPath", "", "") or die "cannot open database `$dbPath'"; diff --git a/nixos/modules/programs/slock.nix b/nixos/modules/programs/slock.nix new file mode 100644 index 00000000000..0e1281e62cd --- /dev/null +++ b/nixos/modules/programs/slock.nix @@ -0,0 +1,26 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + cfg = config.programs.slock; + +in +{ + options = { + programs.slock = { + enable = mkOption { + default = false; + type = types.bool; + description = '' + Whether to install slock screen locker with setuid wrapper. + ''; + }; + }; + }; + + config = mkIf cfg.enable { + environment.systemPackages = [ pkgs.slock ]; + security.wrappers.slock.source = "${pkgs.slock.out}/bin/slock"; + }; +} diff --git a/nixos/modules/programs/ssmtp.nix b/nixos/modules/programs/ssmtp.nix index 7d0cb332099..44756171b74 100644 --- a/nixos/modules/programs/ssmtp.nix +++ b/nixos/modules/programs/ssmtp.nix @@ -39,7 +39,8 @@ in example = "mail.example.org"; description = '' The host name of the default mail server to use to deliver - e-mail. + e-mail. Can also contain a port number (ex: mail.example.org:587), + defaults to port 25 if no port is given. ''; }; @@ -95,9 +96,28 @@ in example = "correctHorseBatteryStaple"; description = '' Password used for SMTP auth. (STORED PLAIN TEXT, WORLD-READABLE IN NIX STORE) + + It's recommended to use <option>authPassFile</option> + which takes precedence over <option>authPass</option>. + ''; + }; + + authPassFile = mkOption { + type = types.nullOr types.str; + default = null; + example = "/run/keys/ssmtp-authpass"; + description = '' + Path to a file that contains the password used for SMTP auth. The file + should not contain a trailing newline, if the password does not contain one. + This file should be readable by the users that need to execute ssmtp. + + <option>authPassFile</option> takes precedence over <option>authPass</option>. + + Warning: when <option>authPass</option> is non-empty <option>authPassFile</option> + defaults to a file in the WORLD-READABLE Nix store containing that password. ''; }; - + setSendmail = mkOption { type = types.bool; default = true; @@ -111,21 +131,28 @@ in config = mkIf cfg.directDelivery { + networking.defaultMailServer.authPassFile = mkIf (cfg.authPass != "") + (mkDefault (toString (pkgs.writeTextFile { + name = "ssmtp-authpass"; + text = cfg.authPass; + }))); + environment.etc."ssmtp/ssmtp.conf".text = + let yesNo = yes : if yes then "YES" else "NO"; in '' MailHub=${cfg.hostName} FromLineOverride=YES - ${if cfg.root != "" then "root=${cfg.root}" else ""} - ${if cfg.domain != "" then "rewriteDomain=${cfg.domain}" else ""} - UseTLS=${if cfg.useTLS then "YES" else "NO"} - UseSTARTTLS=${if cfg.useSTARTTLS then "YES" else "NO"} + ${optionalString (cfg.root != "") "root=${cfg.root}"} + ${optionalString (cfg.domain != "") "rewriteDomain=${cfg.domain}"} + UseTLS=${yesNo cfg.useTLS} + UseSTARTTLS=${yesNo cfg.useSTARTTLS} #Debug=YES - ${if cfg.authUser != "" then "AuthUser=${cfg.authUser}" else ""} - ${if cfg.authPass != "" then "AuthPass=${cfg.authPass}" else ""} + ${optionalString (cfg.authUser != "") "AuthUser=${cfg.authUser}"} + ${optionalString (!isNull cfg.authPassFile) "AuthPassFile=${cfg.authPassFile}"} ''; environment.systemPackages = [pkgs.ssmtp]; - + services.mail.sendmailSetuidWrapper = mkIf cfg.setSendmail { program = "sendmail"; source = "${pkgs.ssmtp}/bin/sendmail"; diff --git a/nixos/modules/rename.nix b/nixos/modules/rename.nix index 54433e20597..0174fe544e3 100644 --- a/nixos/modules/rename.nix +++ b/nixos/modules/rename.nix @@ -202,5 +202,7 @@ with lib; (mkRemovedOptionModule [ "fonts" "fontconfig" "hinting" "style" ] "") (mkRemovedOptionModule [ "services" "xserver" "displayManager" "sddm" "themes" ] "Set the option `services.xserver.displayManager.sddm.package' instead.") + (mkRemovedOptionModule [ "fonts" "fontconfig" "forceAutohint" ] "") + (mkRemovedOptionModule [ "fonts" "fontconfig" "renderMonoTTFAsBitmap" ] "") ]; } diff --git a/nixos/modules/security/acme.nix b/nixos/modules/security/acme.nix index ada198e0e58..5301ac14805 100644 --- a/nixos/modules/security/acme.nix +++ b/nixos/modules/security/acme.nix @@ -19,6 +19,12 @@ let ''; }; + domain = mkOption { + type = types.nullOr types.str; + default = null; + description = "Domain to fetch certificate for (defaults to the entry name)"; + }; + email = mkOption { type = types.nullOr types.str; default = null; @@ -157,9 +163,10 @@ in servicesLists = mapAttrsToList certToServices cfg.certs; certToServices = cert: data: let + domain = if data.domain != null then data.domain else cert; cpath = "${cfg.directory}/${cert}"; rights = if data.allowKeysForGroup then "750" else "700"; - cmdline = [ "-v" "-d" cert "--default_root" data.webroot "--valid_min" cfg.validMin ] + cmdline = [ "-v" "-d" domain "--default_root" data.webroot "--valid_min" cfg.validMin ] ++ optionals (data.email != null) [ "--email" data.email ] ++ concatMap (p: [ "-f" p ]) data.plugins ++ concatLists (mapAttrsToList (name: root: [ "-d" (if root == null then name else "${name}:${root}")]) data.extraDomains); diff --git a/nixos/modules/security/polkit.nix b/nixos/modules/security/polkit.nix index 8d9d5348063..7e59408a5b0 100644 --- a/nixos/modules/security/polkit.nix +++ b/nixos/modules/security/polkit.nix @@ -64,7 +64,7 @@ in systemd.packages = [ pkgs.polkit.out ]; systemd.services.polkit.restartTriggers = [ config.system.path ]; - systemd.services.polkit.unitConfig.X-StopIfChanged = false; + systemd.services.polkit.stopIfChanged = false; # The polkit daemon reads action/rule files environment.pathsToLink = [ "/share/polkit-1" ]; diff --git a/nixos/modules/services/audio/slimserver.nix b/nixos/modules/services/audio/slimserver.nix new file mode 100644 index 00000000000..7d661dd6040 --- /dev/null +++ b/nixos/modules/services/audio/slimserver.nix @@ -0,0 +1,69 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + + cfg = config.services.slimserver; + +in { + options = { + + services.slimserver = { + + enable = mkOption { + type = types.bool; + default = false; + description = '' + Whether to enable slimserver. + ''; + }; + + package = mkOption { + type = types.package; + default = pkgs.slimserver; + defaultText = "pkgs.slimserver"; + description = "Slimserver package to use."; + }; + + dataDir = mkOption { + type = types.path; + default = "/var/lib/slimserver"; + description = '' + The directory where slimserver stores its state, tag cache, + playlists etc. + ''; + }; + }; + }; + + + ###### implementation + + config = mkIf cfg.enable { + + systemd.services.slimserver = { + after = [ "network.target" ]; + description = "Slim Server for Logitech Squeezebox Players"; + wantedBy = [ "multi-user.target" ]; + + preStart = "mkdir -p ${cfg.dataDir} && chown -R slimserver:slimserver ${cfg.dataDir}"; + serviceConfig = { + User = "slimserver"; + PermissionsStartOnly = true; + ExecStart = "${cfg.package}/slimserver.pl --logdir ${cfg.dataDir}/logs --prefsdir ${cfg.dataDir}/prefs --cachedir ${cfg.dataDir}/cache"; + }; + }; + + users = { + users.slimserver = { + description = "Slimserver daemon user"; + home = cfg.dataDir; + group = "slimserver"; + }; + groups.slimserver = {}; + }; + }; + +} + diff --git a/nixos/modules/services/cluster/kubernetes.nix b/nixos/modules/services/cluster/kubernetes.nix index 9ccc7295019..f58306ab63e 100644 --- a/nixos/modules/services/cluster/kubernetes.nix +++ b/nixos/modules/services/cluster/kubernetes.nix @@ -45,7 +45,7 @@ let cniConfig = pkgs.buildEnv { name = "kubernetes-cni-config"; paths = imap (i: entry: - pkgs.writeTextDir "${10+i}-${entry.type}.conf" (builtins.toJSON entry) + pkgs.writeTextDir "${toString (10+i)}-${entry.type}.conf" (builtins.toJSON entry) ) cfg.kubelet.cni.config; }; @@ -597,7 +597,7 @@ in { (mkIf cfg.kubelet.enable { systemd.services.kubelet = { description = "Kubernetes Kubelet Service"; - wantedBy = [ "multi-user.target" ]; + wantedBy = [ "kubernetes.target" ]; after = [ "network.target" "docker.service" "kube-apiserver.service" ]; path = with pkgs; [ gitMinimal openssh docker utillinux iproute ethtool thin-provisioning-tools iptables ]; preStart = '' @@ -606,14 +606,15 @@ in { ${concatMapStringsSep "\n" (p: "ln -fs ${p.plugins}/* /opt/cni/bin") cfg.kubelet.cni.packages} ''; serviceConfig = { + Slice = "kubernetes.slice"; ExecStart = ''${cfg.package}/bin/kubelet \ --pod-manifest-path=${manifests} \ --kubeconfig=${kubeconfig} \ --require-kubeconfig \ --address=${cfg.kubelet.address} \ --port=${toString cfg.kubelet.port} \ - --register-node=${if cfg.kubelet.registerNode then "true" else "false"} \ - --register-schedulable=${if cfg.kubelet.registerSchedulable then "true" else "false"} \ + --register-node=${boolToString cfg.kubelet.registerNode} \ + --register-schedulable=${boolToString cfg.kubelet.registerSchedulable} \ ${optionalString (cfg.kubelet.tlsCertFile != null) "--tls-cert-file=${cfg.kubelet.tlsCertFile}"} \ ${optionalString (cfg.kubelet.tlsKeyFile != null) @@ -621,7 +622,7 @@ in { --healthz-bind-address=${cfg.kubelet.healthz.bind} \ --healthz-port=${toString cfg.kubelet.healthz.port} \ --hostname-override=${cfg.kubelet.hostname} \ - --allow-privileged=${if cfg.kubelet.allowPrivileged then "true" else "false"} \ + --allow-privileged=${boolToString cfg.kubelet.allowPrivileged} \ --root-dir=${cfg.dataDir} \ --cadvisor_port=${toString cfg.kubelet.cadvisorPort} \ ${optionalString (cfg.kubelet.clusterDns != "") @@ -655,9 +656,10 @@ in { (mkIf cfg.apiserver.enable { systemd.services.kube-apiserver = { description = "Kubernetes Kubelet Service"; - wantedBy = [ "multi-user.target" ]; + wantedBy = [ "kubernetes.target" ]; after = [ "network.target" "docker.service" ]; serviceConfig = { + Slice = "kubernetes.slice"; ExecStart = ''${cfg.package}/bin/kube-apiserver \ --etcd-servers=${concatStringsSep "," cfg.etcd.servers} \ ${optionalString (cfg.etcd.caFile != null) @@ -670,14 +672,14 @@ in { --bind-address=0.0.0.0 \ ${optionalString (cfg.apiserver.advertiseAddress != null) "--advertise-address=${cfg.apiserver.advertiseAddress}"} \ - --allow-privileged=${if cfg.apiserver.allowPrivileged then "true" else "false"} \ + --allow-privileged=${boolToString cfg.apiserver.allowPrivileged}\ ${optionalString (cfg.apiserver.tlsCertFile != null) "--tls-cert-file=${cfg.apiserver.tlsCertFile}"} \ ${optionalString (cfg.apiserver.tlsKeyFile != null) "--tls-private-key-file=${cfg.apiserver.tlsKeyFile}"} \ ${optionalString (cfg.apiserver.tokenAuth != null) "--token-auth-file=${cfg.apiserver.tokenAuth}"} \ - --kubelet-https=${if cfg.apiserver.kubeletHttps then "true" else "false"} \ + --kubelet-https=${boolToString cfg.apiserver.kubeletHttps} \ ${optionalString (cfg.apiserver.kubeletClientCaFile != null) "--kubelet-certificate-authority=${cfg.apiserver.kubeletClientCaFile}"} \ ${optionalString (cfg.apiserver.kubeletClientCertFile != null) @@ -713,13 +715,14 @@ in { (mkIf cfg.scheduler.enable { systemd.services.kube-scheduler = { description = "Kubernetes Scheduler Service"; - wantedBy = [ "multi-user.target" ]; + wantedBy = [ "kubernetes.target" ]; after = [ "kube-apiserver.service" ]; serviceConfig = { + Slice = "kubernetes.slice"; ExecStart = ''${cfg.package}/bin/kube-scheduler \ --address=${cfg.scheduler.address} \ --port=${toString cfg.scheduler.port} \ - --leader-elect=${if cfg.scheduler.leaderElect then "true" else "false"} \ + --leader-elect=${boolToString cfg.scheduler.leaderElect} \ --kubeconfig=${kubeconfig} \ ${optionalString cfg.verbose "--v=6"} \ ${optionalString cfg.verbose "--log-flush-frequency=1s"} \ @@ -735,16 +738,17 @@ in { (mkIf cfg.controllerManager.enable { systemd.services.kube-controller-manager = { description = "Kubernetes Controller Manager Service"; - wantedBy = [ "multi-user.target" ]; + wantedBy = [ "kubernetes.target" ]; after = [ "kube-apiserver.service" ]; serviceConfig = { RestartSec = "30s"; Restart = "on-failure"; + Slice = "kubernetes.slice"; ExecStart = ''${cfg.package}/bin/kube-controller-manager \ --address=${cfg.controllerManager.address} \ --port=${toString cfg.controllerManager.port} \ --kubeconfig=${kubeconfig} \ - --leader-elect=${if cfg.controllerManager.leaderElect then "true" else "false"} \ + --leader-elect=${boolToString cfg.controllerManager.leaderElect} \ ${if (cfg.controllerManager.serviceAccountKeyFile!=null) then "--service-account-private-key-file=${cfg.controllerManager.serviceAccountKeyFile}" else "--service-account-private-key-file=/var/run/kubernetes/apiserver.key"} \ @@ -767,10 +771,11 @@ in { (mkIf cfg.proxy.enable { systemd.services.kube-proxy = { description = "Kubernetes Proxy Service"; - wantedBy = [ "multi-user.target" ]; + wantedBy = [ "kubernetes.target" ]; after = [ "kube-apiserver.service" ]; path = [pkgs.iptables]; serviceConfig = { + Slice = "kubernetes.slice"; ExecStart = ''${cfg.package}/bin/kube-proxy \ --kubeconfig=${kubeconfig} \ --bind-address=${cfg.proxy.address} \ @@ -786,9 +791,10 @@ in { (mkIf cfg.dns.enable { systemd.services.kube-dns = { description = "Kubernetes Dns Service"; - wantedBy = [ "multi-user.target" ]; + wantedBy = [ "kubernetes.target" ]; after = [ "kube-apiserver.service" ]; serviceConfig = { + Slice = "kubernetes.slice"; ExecStart = ''${cfg.package}/bin/kube-dns \ --kubecfg-file=${kubeconfig} \ --dns-port=${toString cfg.dns.port} \ @@ -836,6 +842,11 @@ in { cfg.proxy.enable || cfg.dns.enable ) { + systemd.targets.kubernetes = { + description = "Kubernetes"; + wantedBy = [ "multi-user.target" ]; + }; + systemd.tmpfiles.rules = [ "d /opt/cni/bin 0755 root root -" "d /var/run/kubernetes 0755 kubernetes kubernetes -" diff --git a/nixos/modules/services/continuous-integration/hydra/default.nix b/nixos/modules/services/continuous-integration/hydra/default.nix index fa550f68b33..57f592a2e55 100644 --- a/nixos/modules/services/continuous-integration/hydra/default.nix +++ b/nixos/modules/services/continuous-integration/hydra/default.nix @@ -328,7 +328,7 @@ in IN_SYSTEMD = "1"; # to get log severity levels }; serviceConfig = - { ExecStart = "@${cfg.package}/bin/hydra-queue-runner hydra-queue-runner -v --option build-use-substitutes ${if cfg.useSubstitutes then "true" else "false"}"; + { ExecStart = "@${cfg.package}/bin/hydra-queue-runner hydra-queue-runner -v --option build-use-substitutes ${boolToString cfg.useSubstitutes}"; ExecStopPost = "${cfg.package}/bin/hydra-queue-runner --unlock"; User = "hydra-queue-runner"; Restart = "always"; diff --git a/nixos/modules/services/databases/cassandra.nix b/nixos/modules/services/databases/cassandra.nix index 5df4ae57f80..1e5cd8f5413 100644 --- a/nixos/modules/services/databases/cassandra.nix +++ b/nixos/modules/services/databases/cassandra.nix @@ -21,8 +21,8 @@ let cassandraConf = '' cluster_name: ${cfg.clusterName} num_tokens: 256 - auto_bootstrap: ${if cfg.autoBootstrap then "true" else "false"} - hinted_handoff_enabled: ${if cfg.hintedHandOff then "true" else "false"} + auto_bootstrap: ${boolToString cfg.autoBootstrap} + hinted_handoff_enabled: ${boolToString cfg.hintedHandOff} hinted_handoff_throttle_in_kb: ${builtins.toString cfg.hintedHandOffThrottle} max_hints_delivery_threads: 2 max_hint_window_in_ms: 10800000 # 3 hours @@ -62,7 +62,7 @@ let rpc_keepalive: true rpc_server_type: sync thrift_framed_transport_size_in_mb: 15 - incremental_backups: ${if cfg.incrementalBackups then "true" else "false"} + incremental_backups: ${boolToString cfg.incrementalBackups} snapshot_before_compaction: false auto_snapshot: true column_index_size_in_kb: 64 @@ -89,7 +89,7 @@ let truststore: ${cfg.trustStorePath} truststore_password: ${cfg.trustStorePassword} client_encryption_options: - enabled: ${if cfg.clientEncryption then "true" else "false"} + enabled: ${boolToString cfg.clientEncryption} keystore: ${cfg.keyStorePath} keystore_password: ${cfg.keyStorePassword} internode_compression: all diff --git a/nixos/modules/services/databases/mongodb.nix b/nixos/modules/services/databases/mongodb.nix index 38e46a0c6ef..c56564f57f3 100644 --- a/nixos/modules/services/databases/mongodb.nix +++ b/nixos/modules/services/databases/mongodb.nix @@ -4,8 +4,6 @@ with lib; let - b2s = x: if x then "true" else "false"; - cfg = config.services.mongodb; mongodb = cfg.package; diff --git a/nixos/modules/services/hardware/bluetooth.nix b/nixos/modules/services/hardware/bluetooth.nix index f1fcb436934..4a8cd86b0b1 100644 --- a/nixos/modules/services/hardware/bluetooth.nix +++ b/nixos/modules/services/hardware/bluetooth.nix @@ -6,9 +6,7 @@ let bluez-bluetooth = pkgs.bluez; cfg = config.hardware.bluetooth; -in - -{ +in { ###### interface @@ -32,6 +30,8 @@ in ''; description = '' Set additional configuration for system-wide bluetooth (/etc/bluetooth/main.conf). + + NOTE: We already include [Policy], so any configuration under the Policy group should come first. ''; }; }; @@ -45,7 +45,12 @@ in environment.systemPackages = [ bluez-bluetooth pkgs.openobex pkgs.obexftp ]; environment.etc = singleton { - source = pkgs.writeText "main.conf" cfg.extraConfig; + source = pkgs.writeText "main.conf" '' + [Policy] + AutoEnable=${lib.boolToString cfg.powerOnBoot} + + ${cfg.extraConfig} + ''; target = "bluetooth/main.conf"; }; @@ -53,29 +58,11 @@ in services.dbus.packages = [ bluez-bluetooth ]; systemd.packages = [ bluez-bluetooth ]; - services.udev.extraRules = optionalString cfg.powerOnBoot '' - ACTION=="add", KERNEL=="hci[0-9]*", ENV{SYSTEMD_WANTS}="bluetooth-power@%k.service" - ''; - systemd.services = { bluetooth = { wantedBy = [ "bluetooth.target" ]; aliases = [ "dbus-org.bluez.service" ]; }; - - "bluetooth-power@" = mkIf cfg.powerOnBoot { - description = "Power up bluetooth controller"; - after = [ - "bluetooth.service" - "suspend.target" - "sys-subsystem-bluetooth-devices-%i.device" - ]; - wantedBy = [ "suspend.target" ]; - - serviceConfig.Type = "oneshot"; - serviceConfig.ExecStart = "${pkgs.bluez.out}/bin/hciconfig %i up"; - }; - }; systemd.user.services = { diff --git a/nixos/modules/services/hardware/tlp.nix b/nixos/modules/services/hardware/tlp.nix index f36a9e7b459..3b108c87edd 100644 --- a/nixos/modules/services/hardware/tlp.nix +++ b/nixos/modules/services/hardware/tlp.nix @@ -58,6 +58,9 @@ in powerManagement.cpuFreqGovernor = null; systemd.services = { + "systemd-rfkill@".enable = false; + "systemd-rfkill".enable = false; + tlp = { description = "TLP system startup/shutdown"; diff --git a/nixos/modules/services/logging/graylog.nix b/nixos/modules/services/logging/graylog.nix index 95283096662..9f0fb11f025 100644 --- a/nixos/modules/services/logging/graylog.nix +++ b/nixos/modules/services/logging/graylog.nix @@ -4,16 +4,15 @@ with lib; let cfg = config.services.graylog; - configBool = b: if b then "true" else "false"; confFile = pkgs.writeText "graylog.conf" '' - is_master = ${configBool cfg.isMaster} + is_master = ${boolToString cfg.isMaster} node_id_file = ${cfg.nodeIdFile} password_secret = ${cfg.passwordSecret} root_username = ${cfg.rootUsername} root_password_sha2 = ${cfg.rootPasswordSha2} elasticsearch_cluster_name = ${cfg.elasticsearchClusterName} - elasticsearch_discovery_zen_ping_multicast_enabled = ${configBool cfg.elasticsearchDiscoveryZenPingMulticastEnabled} + elasticsearch_discovery_zen_ping_multicast_enabled = ${boolToString cfg.elasticsearchDiscoveryZenPingMulticastEnabled} elasticsearch_discovery_zen_ping_unicast_hosts = ${cfg.elasticsearchDiscoveryZenPingUnicastHosts} message_journal_dir = ${cfg.messageJournalDir} mongodb_uri = ${cfg.mongodbUri} diff --git a/nixos/modules/services/misc/autorandr.nix b/nixos/modules/services/misc/autorandr.nix new file mode 100644 index 00000000000..6746f3fec69 --- /dev/null +++ b/nixos/modules/services/misc/autorandr.nix @@ -0,0 +1,43 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + + cfg = config.services.autorandr; + +in { + + options = { + + services.autorandr = { + enable = mkEnableOption "handling of hotplug and sleep events by autorandr"; + }; + + }; + + config = mkIf cfg.enable { + + services.udev.packages = [ pkgs.autorandr ]; + + environment.systemPackages = [ pkgs.autorandr ]; + + # systemd.unitPackages = [ pkgs.autorandr ]; + systemd.services.autorandr = { + unitConfig = { + Description = "autorandr execution hook"; + After = [ "sleep.target" ]; + StartLimitInterval = "5"; + StartLimitBurst = "1"; + }; + serviceConfig = { + ExecStart = "${pkgs.autorandr}/bin/autorandr --batch --change --default default"; + Type = "oneshot"; + RemainAfterExit = false; + }; + wantedBy = [ "sleep.target" ]; + }; + + }; + +} diff --git a/nixos/modules/services/misc/cgminer.nix b/nixos/modules/services/misc/cgminer.nix index 5f97cc03414..d5071d8ff76 100644 --- a/nixos/modules/services/misc/cgminer.nix +++ b/nixos/modules/services/misc/cgminer.nix @@ -6,7 +6,7 @@ let cfg = config.services.cgminer; convType = with builtins; - v: if isBool v then (if v then "true" else "false") else toString v; + v: if isBool v then boolToString v else toString v; mergedHwConfig = mapAttrsToList (n: v: ''"${n}": "${(concatStringsSep "," (map convType v))}"'') (foldAttrs (n: a: [n] ++ a) [] cfg.hardware); diff --git a/nixos/modules/services/misc/confd.nix b/nixos/modules/services/misc/confd.nix index fe13013286b..8e9bec15dd4 100755 --- a/nixos/modules/services/misc/confd.nix +++ b/nixos/modules/services/misc/confd.nix @@ -12,7 +12,7 @@ let nodes = [ ${concatMapStringsSep "," (s: ''"${s}"'') cfg.nodes}, ] prefix = "${cfg.prefix}" log-level = "${cfg.logLevel}" - watch = ${if cfg.watch then "true" else "false"} + watch = ${boolToString cfg.watch} ''; in { diff --git a/nixos/modules/services/misc/etcd.nix b/nixos/modules/services/misc/etcd.nix index 1de02d76ba0..7c91462883f 100644 --- a/nixos/modules/services/misc/etcd.nix +++ b/nixos/modules/services/misc/etcd.nix @@ -119,7 +119,7 @@ in { extraConf = mkOption { description = '' Etcd extra configuration. See - <link xlink:href='https://github.com/coreos/etcd/blob/master/Documentation/configuration.md#environment-variables' /> + <link xlink:href='https://github.com/coreos/etcd/blob/master/Documentation/op-guide/configuration.md#configuration-flags' /> ''; type = types.attrsOf types.str; default = {}; diff --git a/nixos/modules/services/misc/matrix-synapse.nix b/nixos/modules/services/misc/matrix-synapse.nix index 4a1bea50c14..ae9826968b1 100644 --- a/nixos/modules/services/misc/matrix-synapse.nix +++ b/nixos/modules/services/misc/matrix-synapse.nix @@ -5,9 +5,8 @@ with lib; let cfg = config.services.matrix-synapse; logConfigFile = pkgs.writeText "log_config.yaml" cfg.logConfig; - mkResource = r: ''{names: ${builtins.toJSON r.names}, compress: ${fromBool r.compress}}''; - mkListener = l: ''{port: ${toString l.port}, bind_address: "${l.bind_address}", type: ${l.type}, tls: ${fromBool l.tls}, x_forwarded: ${fromBool l.x_forwarded}, resources: [${concatStringsSep "," (map mkResource l.resources)}]}''; - fromBool = x: if x then "true" else "false"; + mkResource = r: ''{names: ${builtins.toJSON r.names}, compress: ${boolToString r.compress}}''; + mkListener = l: ''{port: ${toString l.port}, bind_address: "${l.bind_address}", type: ${l.type}, tls: ${boolToString l.tls}, x_forwarded: ${boolToString l.x_forwarded}, resources: [${concatStringsSep "," (map mkResource l.resources)}]}''; configFile = pkgs.writeText "homeserver.yaml" '' ${optionalString (cfg.tls_certificate_path != null) '' tls_certificate_path: "${cfg.tls_certificate_path}" @@ -18,7 +17,7 @@ tls_private_key_path: "${cfg.tls_private_key_path}" ${optionalString (cfg.tls_dh_params_path != null) '' tls_dh_params_path: "${cfg.tls_dh_params_path}" ''} -no_tls: ${fromBool cfg.no_tls} +no_tls: ${boolToString cfg.no_tls} ${optionalString (cfg.bind_port != null) '' bind_port: ${toString cfg.bind_port} ''} @@ -30,7 +29,7 @@ bind_host: "${cfg.bind_host}" ''} server_name: "${cfg.server_name}" pid_file: "/var/run/matrix-synapse.pid" -web_client: ${fromBool cfg.web_client} +web_client: ${boolToString cfg.web_client} ${optionalString (cfg.public_baseurl != null) '' public_baseurl: "${cfg.public_baseurl}" ''} @@ -58,8 +57,8 @@ media_store_path: "/var/lib/matrix-synapse/media" uploads_path: "/var/lib/matrix-synapse/uploads" max_upload_size: "${cfg.max_upload_size}" max_image_pixels: "${cfg.max_image_pixels}" -dynamic_thumbnails: ${fromBool cfg.dynamic_thumbnails} -url_preview_enabled: ${fromBool cfg.url_preview_enabled} +dynamic_thumbnails: ${boolToString cfg.dynamic_thumbnails} +url_preview_enabled: ${boolToString cfg.url_preview_enabled} ${optionalString (cfg.url_preview_enabled == true) '' url_preview_ip_range_blacklist: ${builtins.toJSON cfg.url_preview_ip_range_blacklist} url_preview_ip_range_whitelist: ${builtins.toJSON cfg.url_preview_ip_range_whitelist} @@ -67,10 +66,10 @@ url_preview_url_blacklist: ${builtins.toJSON cfg.url_preview_url_blacklist} ''} recaptcha_private_key: "${cfg.recaptcha_private_key}" recaptcha_public_key: "${cfg.recaptcha_public_key}" -enable_registration_captcha: ${fromBool cfg.enable_registration_captcha} +enable_registration_captcha: ${boolToString cfg.enable_registration_captcha} turn_uris: ${builtins.toJSON cfg.turn_uris} turn_shared_secret: "${cfg.turn_shared_secret}" -enable_registration: ${fromBool cfg.enable_registration} +enable_registration: ${boolToString cfg.enable_registration} ${optionalString (cfg.registration_shared_secret != null) '' registration_shared_secret: "${cfg.registration_shared_secret}" ''} @@ -78,15 +77,15 @@ recaptcha_siteverify_api: "https://www.google.com/recaptcha/api/siteverify" turn_user_lifetime: "${cfg.turn_user_lifetime}" user_creation_max_duration: ${cfg.user_creation_max_duration} bcrypt_rounds: ${cfg.bcrypt_rounds} -allow_guest_access: ${fromBool cfg.allow_guest_access} +allow_guest_access: ${boolToString cfg.allow_guest_access} trusted_third_party_id_servers: ${builtins.toJSON cfg.trusted_third_party_id_servers} room_invite_state_types: ${builtins.toJSON cfg.room_invite_state_types} ${optionalString (cfg.macaroon_secret_key != null) '' macaroon_secret_key: "${cfg.macaroon_secret_key}" ''} -expire_access_token: ${fromBool cfg.expire_access_token} -enable_metrics: ${fromBool cfg.enable_metrics} -report_stats: ${fromBool cfg.report_stats} +expire_access_token: ${boolToString cfg.expire_access_token} +enable_metrics: ${boolToString cfg.enable_metrics} +report_stats: ${boolToString cfg.report_stats} signing_key_path: "/var/lib/matrix-synapse/homeserver.signing.key" key_refresh_interval: "${cfg.key_refresh_interval}" perspectives: diff --git a/nixos/modules/services/misc/nix-daemon.nix b/nixos/modules/services/misc/nix-daemon.nix index 4fe89838e29..bf1304ee7ac 100644 --- a/nixos/modules/services/misc/nix-daemon.nix +++ b/nixos/modules/services/misc/nix-daemon.nix @@ -41,12 +41,12 @@ let build-users-group = nixbld build-max-jobs = ${toString (cfg.maxJobs)} build-cores = ${toString (cfg.buildCores)} - build-use-sandbox = ${if (builtins.isBool cfg.useSandbox) then (if cfg.useSandbox then "true" else "false") else cfg.useSandbox} + build-use-sandbox = ${if (builtins.isBool cfg.useSandbox) then boolToString cfg.useSandbox else cfg.useSandbox} build-sandbox-paths = ${toString cfg.sandboxPaths} /bin/sh=${sh} $(echo $extraPaths) binary-caches = ${toString cfg.binaryCaches} trusted-binary-caches = ${toString cfg.trustedBinaryCaches} binary-cache-public-keys = ${toString cfg.binaryCachePublicKeys} - auto-optimise-store = ${if cfg.autoOptimiseStore then "true" else "false"} + auto-optimise-store = ${boolToString cfg.autoOptimiseStore} ${optionalString cfg.requireSignedBinaryCaches '' signed-binary-caches = * ''} diff --git a/nixos/modules/services/misc/plex.nix b/nixos/modules/services/misc/plex.nix index f6bf2dee986..9c0bea8d3bf 100644 --- a/nixos/modules/services/misc/plex.nix +++ b/nixos/modules/services/misc/plex.nix @@ -93,7 +93,9 @@ in # why this is done. test -d "${cfg.dataDir}/.skeleton" || mkdir "${cfg.dataDir}/.skeleton" for db in "com.plexapp.plugins.library.db"; do - cp "${cfg.package}/usr/lib/plexmediaserver/Resources/base_$db" "${cfg.dataDir}/.skeleton/$db" + if [ ! -e "${cfg.dataDir}/.skeleton/$db" ]; then + cp "${cfg.package}/usr/lib/plexmediaserver/Resources/base_$db" "${cfg.dataDir}/.skeleton/$db" + fi chmod u+w "${cfg.dataDir}/.skeleton/$db" chown ${cfg.user}:${cfg.group} "${cfg.dataDir}/.skeleton/$db" done @@ -136,6 +138,7 @@ in Group = cfg.group; PermissionsStartOnly = "true"; ExecStart = "/bin/sh -c ${cfg.package}/usr/lib/plexmediaserver/Plex\\ Media\\ Server"; + KillSignal = "SIGQUIT"; Restart = "on-failure"; }; environment = { diff --git a/nixos/modules/services/misc/taskserver/default.nix b/nixos/modules/services/misc/taskserver/default.nix index ba9f52f1904..ab9a6ce32f4 100644 --- a/nixos/modules/services/misc/taskserver/default.nix +++ b/nixos/modules/services/misc/taskserver/default.nix @@ -128,7 +128,7 @@ let certBits = cfg.pki.auto.bits; clientExpiration = cfg.pki.auto.expiration.client; crlExpiration = cfg.pki.auto.expiration.crl; - isAutoConfig = if needToCreateCA then "True" else "False"; + isAutoConfig = boolToString needToCreateCA; }}" > "$out/main.py" cat > "$out/setup.py" <<EOF from setuptools import setup diff --git a/nixos/modules/services/monitoring/collectd.nix b/nixos/modules/services/monitoring/collectd.nix index 641da60e9ad..79a8a1ff5ae 100644 --- a/nixos/modules/services/monitoring/collectd.nix +++ b/nixos/modules/services/monitoring/collectd.nix @@ -8,7 +8,7 @@ let conf = pkgs.writeText "collectd.conf" '' BaseDir "${cfg.dataDir}" PIDFile "${cfg.pidFile}" - AutoLoadPlugin ${if cfg.autoLoadPlugin then "true" else "false"} + AutoLoadPlugin ${boolToString cfg.autoLoadPlugin} Hostname "${config.networking.hostName}" LoadPlugin syslog diff --git a/nixos/modules/services/monitoring/grafana.nix b/nixos/modules/services/monitoring/grafana.nix index 97806d5d83e..4fbacef788f 100644 --- a/nixos/modules/services/monitoring/grafana.nix +++ b/nixos/modules/services/monitoring/grafana.nix @@ -5,8 +5,6 @@ with lib; let cfg = config.services.grafana; - b2s = val: if val then "true" else "false"; - envOptions = { PATHS_DATA = cfg.dataDir; PATHS_PLUGINS = "${cfg.dataDir}/plugins"; @@ -32,16 +30,16 @@ let SECURITY_ADMIN_PASSWORD = cfg.security.adminPassword; SECURITY_SECRET_KEY = cfg.security.secretKey; - USERS_ALLOW_SIGN_UP = b2s cfg.users.allowSignUp; - USERS_ALLOW_ORG_CREATE = b2s cfg.users.allowOrgCreate; - USERS_AUTO_ASSIGN_ORG = b2s cfg.users.autoAssignOrg; + USERS_ALLOW_SIGN_UP = boolToString cfg.users.allowSignUp; + USERS_ALLOW_ORG_CREATE = boolToString cfg.users.allowOrgCreate; + USERS_AUTO_ASSIGN_ORG = boolToString cfg.users.autoAssignOrg; USERS_AUTO_ASSIGN_ORG_ROLE = cfg.users.autoAssignOrgRole; - AUTH_ANONYMOUS_ENABLED = b2s cfg.auth.anonymous.enable; + AUTH_ANONYMOUS_ENABLED = boolToString cfg.auth.anonymous.enable; AUTH_ANONYMOUS_ORG_NAME = cfg.auth.anonymous.org_name; AUTH_ANONYMOUS_ORG_ROLE = cfg.auth.anonymous.org_role; - ANALYTICS_REPORTING_ENABLED = b2s cfg.analytics.reporting.enable; + ANALYTICS_REPORTING_ENABLED = boolToString cfg.analytics.reporting.enable; } // cfg.extraOptions; in { diff --git a/nixos/modules/services/monitoring/graphite.nix b/nixos/modules/services/monitoring/graphite.nix index c5352e5887d..98931e65bb5 100644 --- a/nixos/modules/services/monitoring/graphite.nix +++ b/nixos/modules/services/monitoring/graphite.nix @@ -4,7 +4,7 @@ with lib; let cfg = config.services.graphite; - writeTextOrNull = f: t: if t == null then null else pkgs.writeTextDir f t; + writeTextOrNull = f: t: mapNullable (pkgs.writeTextDir f) t; dataDir = cfg.dataDir; diff --git a/nixos/modules/services/monitoring/prometheus/default.nix b/nixos/modules/services/monitoring/prometheus/default.nix index cf9deccbffe..b9435c02b1d 100644 --- a/nixos/modules/services/monitoring/prometheus/default.nix +++ b/nixos/modules/services/monitoring/prometheus/default.nix @@ -116,6 +116,13 @@ let The URL scheme with which to fetch metrics from targets. ''; }; + params = mkOption { + type = types.attrsOf (types.listOf types.str); + default = {}; + description = '' + Optional HTTP URL parameters. + ''; + }; basic_auth = mkOption { type = types.nullOr (types.submodule { options = { @@ -134,7 +141,7 @@ let }; }); default = null; - apply = x: if x == null then null else _filter x; + apply = x: mapNullable _filter x; description = '' Optional http login credentials for metrics scraping. ''; diff --git a/nixos/modules/services/network-filesystems/netatalk.nix b/nixos/modules/services/network-filesystems/netatalk.nix index bff54406a2b..1dd869043f0 100644 --- a/nixos/modules/services/network-filesystems/netatalk.nix +++ b/nixos/modules/services/network-filesystems/netatalk.nix @@ -9,7 +9,7 @@ let extmapFile = pkgs.writeText "extmap.conf" cfg.extmap; afpToString = x: if builtins.typeOf x == "bool" - then (if x then "true" else "false") + then boolToString x else toString x; volumeConfig = name: diff --git a/nixos/modules/services/network-filesystems/samba.nix b/nixos/modules/services/network-filesystems/samba.nix index 6ae5292fc30..87c4f7a8ebc 100644 --- a/nixos/modules/services/network-filesystems/samba.nix +++ b/nixos/modules/services/network-filesystems/samba.nix @@ -5,7 +5,7 @@ with lib; let smbToString = x: if builtins.typeOf x == "bool" - then (if x then "true" else "false") + then boolToString x else toString x; cfg = config.services.samba; diff --git a/nixos/modules/services/network-filesystems/tahoe.nix b/nixos/modules/services/network-filesystems/tahoe.nix index 3d78ac096a2..9815a5434ee 100644 --- a/nixos/modules/services/network-filesystems/tahoe.nix +++ b/nixos/modules/services/network-filesystems/tahoe.nix @@ -290,14 +290,14 @@ in shares.total = ${toString settings.client.shares.total} [storage] - enabled = ${if settings.storage.enable then "true" else "false"} + enabled = ${boolToString settings.storage.enable} reserved_space = ${settings.storage.reservedSpace} [helper] - enabled = ${if settings.helper.enable then "true" else "false"} + enabled = ${boolToString settings.helper.enable} [sftpd] - enabled = ${if settings.sftpd.enable then "true" else "false"} + enabled = ${boolToString settings.sftpd.enable} ${optionalString (settings.sftpd.port != null) "port = ${toString settings.sftpd.port}"} ${optionalString (settings.sftpd.hostPublicKeyFile != null) diff --git a/nixos/modules/services/networking/aiccu.nix b/nixos/modules/services/networking/aiccu.nix index aeb0910d624..ac755270951 100644 --- a/nixos/modules/services/networking/aiccu.nix +++ b/nixos/modules/services/networking/aiccu.nix @@ -5,7 +5,6 @@ with lib; let cfg = config.services.aiccu; - showBool = b: if b then "true" else "false"; notNull = a: ! isNull a; configFile = pkgs.writeText "aiccu.conf" '' ${if notNull cfg.username then "username " + cfg.username else ""} @@ -13,16 +12,16 @@ let protocol ${cfg.protocol} server ${cfg.server} ipv6_interface ${cfg.interfaceName} - verbose ${showBool cfg.verbose} + verbose ${boolToString cfg.verbose} daemonize true - automatic ${showBool cfg.automatic} - requiretls ${showBool cfg.requireTLS} + automatic ${boolToString cfg.automatic} + requiretls ${boolToString cfg.requireTLS} pidfile ${cfg.pidFile} - defaultroute ${showBool cfg.defaultRoute} + defaultroute ${boolToString cfg.defaultRoute} ${if notNull cfg.setupScript then cfg.setupScript else ""} - makebeats ${showBool cfg.makeHeartBeats} - noconfigure ${showBool cfg.noConfigure} - behindnat ${showBool cfg.behindNAT} + makebeats ${boolToString cfg.makeHeartBeats} + noconfigure ${boolToString cfg.noConfigure} + behindnat ${boolToString cfg.behindNAT} ${if cfg.localIPv4Override then "local_ipv4_override" else ""} ''; diff --git a/nixos/modules/services/networking/avahi-daemon.nix b/nixos/modules/services/networking/avahi-daemon.nix index 6a786e75bbc..3985f8561d3 100644 --- a/nixos/modules/services/networking/avahi-daemon.nix +++ b/nixos/modules/services/networking/avahi-daemon.nix @@ -7,31 +7,32 @@ let cfg = config.services.avahi; + yesNo = yes : if yes then "yes" else "no"; + avahiDaemonConf = with cfg; pkgs.writeText "avahi-daemon.conf" '' [server] ${# Users can set `networking.hostName' to the empty string, when getting # a host name from DHCP. In that case, let Avahi take whatever the # current host name is; setting `host-name' to the empty string in # `avahi-daemon.conf' would be invalid. - if hostName != "" - then "host-name=${hostName}" - else ""} + optionalString (hostName != "") "host-name=${hostName}"} browse-domains=${concatStringsSep ", " browseDomains} - use-ipv4=${if ipv4 then "yes" else "no"} - use-ipv6=${if ipv6 then "yes" else "no"} + use-ipv4=${yesNo ipv4} + use-ipv6=${yesNo ipv6} ${optionalString (interfaces!=null) "allow-interfaces=${concatStringsSep "," interfaces}"} ${optionalString (domainName!=null) "domain-name=${domainName}"} + allow-point-to-point=${yesNo allowPointToPoint} [wide-area] - enable-wide-area=${if wideArea then "yes" else "no"} + enable-wide-area=${yesNo wideArea} [publish] - disable-publishing=${if publish.enable then "no" else "yes"} - disable-user-service-publishing=${if publish.userServices then "no" else "yes"} - publish-addresses=${if publish.userServices || publish.addresses then "yes" else "no"} - publish-hinfo=${if publish.hinfo then "yes" else "no"} - publish-workstation=${if publish.workstation then "yes" else "no"} - publish-domain=${if publish.domain then "yes" else "no"} + disable-publishing=${yesNo (!publish.enable)} + disable-user-service-publishing=${yesNo (!publish.userServices)} + publish-addresses=${yesNo (publish.userServices || publish.addresses)} + publish-hinfo=${yesNo publish.hinfo} + publish-workstation=${yesNo publish.workstation} + publish-domain=${yesNo publish.domain} ''; in @@ -98,6 +99,15 @@ in ''; }; + allowPointToPoint = mkOption { + default = false; + description= '' + Whether to use POINTTOPOINT interfaces. Might make mDNS unreliable due to usually large + latencies with such links and opens a potential security hole by allowing mDNS access from Internet + connections. Use with care and YMMV! + ''; + }; + wideArea = mkOption { default = true; description = ''Whether to enable wide-area service discovery.''; diff --git a/nixos/modules/services/networking/btsync.nix b/nixos/modules/services/networking/btsync.nix index 92e9fa7be41..6e479a5860a 100644 --- a/nixos/modules/services/networking/btsync.nix +++ b/nixos/modules/services/networking/btsync.nix @@ -9,7 +9,6 @@ let listenAddr = cfg.httpListenAddr + ":" + (toString cfg.httpListenPort); - boolStr = x: if x then "true" else "false"; optionalEmptyStr = b: v: optionalString (b != "") v; webUIConfig = optionalString cfg.enableWebUI @@ -31,7 +30,7 @@ let sharedFoldersRecord = concatStringsSep "," (map (entry: let helper = attr: v: - if (entry ? attr) then boolStr entry.attr else boolStr v; + if (entry ? attr) then boolToString entry.attr else boolToString v; in '' { @@ -65,11 +64,11 @@ let "listening_port": ${toString cfg.listeningPort}, "use_gui": false, - "check_for_updates": ${boolStr cfg.checkForUpdates}, - "use_upnp": ${boolStr cfg.useUpnp}, + "check_for_updates": ${boolToString cfg.checkForUpdates}, + "use_upnp": ${boolToString cfg.useUpnp}, "download_limit": ${toString cfg.downloadLimit}, "upload_limit": ${toString cfg.uploadLimit}, - "lan_encrypt_data": ${boolStr cfg.encryptLAN}, + "lan_encrypt_data": ${boolToString cfg.encryptLAN}, ${webUIConfig} ${sharedFoldersConfig} diff --git a/nixos/modules/services/networking/dhcpcd.nix b/nixos/modules/services/networking/dhcpcd.nix index 7eeceb7407c..cdba14be21f 100644 --- a/nixos/modules/services/networking/dhcpcd.nix +++ b/nixos/modules/services/networking/dhcpcd.nix @@ -71,8 +71,7 @@ let # anything ever again ("couldn't resolve ..., giving up on # it"), so we silently lose time synchronisation. This also # applies to openntpd. - ${config.systemd.package}/bin/systemctl try-restart ntpd.service - ${config.systemd.package}/bin/systemctl try-restart openntpd.service + ${config.systemd.package}/bin/systemctl try-reload-or-restart ntpd.service openntpd.service || true fi ${cfg.runHook} diff --git a/nixos/modules/services/networking/firefox/sync-server.nix b/nixos/modules/services/networking/firefox/sync-server.nix index 5c14ceff6a0..3a95b9c4ec9 100644 --- a/nixos/modules/services/networking/firefox/sync-server.nix +++ b/nixos/modules/services/networking/firefox/sync-server.nix @@ -19,7 +19,7 @@ let [syncserver] public_url = ${cfg.publicUrl} ${optionalString (cfg.sqlUri != "") "sqluri = ${cfg.sqlUri}"} - allow_new_users = ${if cfg.allowNewUsers then "true" else "false"} + allow_new_users = ${boolToString cfg.allowNewUsers} [browserid] backend = tokenserver.verifiers.LocalVerifier diff --git a/nixos/modules/services/networking/i2pd.nix b/nixos/modules/services/networking/i2pd.nix index c5b27350b3c..24a3196bed4 100644 --- a/nixos/modules/services/networking/i2pd.nix +++ b/nixos/modules/services/networking/i2pd.nix @@ -10,8 +10,6 @@ let extip = "EXTIP=\$(${pkgs.curl.bin}/bin/curl -sLf \"http://jsonip.com\" | ${pkgs.gawk}/bin/awk -F'\"' '{print $4}')"; - toYesNo = b: if b then "true" else "false"; - mkEndpointOpt = name: addr: port: { enable = mkEnableOption name; name = mkOption { @@ -76,10 +74,10 @@ let i2pdConf = pkgs.writeText "i2pd.conf" '' - ipv4 = ${toYesNo cfg.enableIPv4} - ipv6 = ${toYesNo cfg.enableIPv6} - notransit = ${toYesNo cfg.notransit} - floodfill = ${toYesNo cfg.floodfill} + ipv4 = ${boolToString cfg.enableIPv4} + ipv6 = ${boolToString cfg.enableIPv6} + notransit = ${boolToString cfg.notransit} + floodfill = ${boolToString cfg.floodfill} netid = ${toString cfg.netid} ${if isNull cfg.bandwidth then "" else "bandwidth = ${toString cfg.bandwidth}" } ${if isNull cfg.port then "" else "port = ${toString cfg.port}"} @@ -88,14 +86,14 @@ let transittunnels = ${toString cfg.limits.transittunnels} [upnp] - enabled = ${toYesNo cfg.upnp.enable} + enabled = ${boolToString cfg.upnp.enable} name = ${cfg.upnp.name} [precomputation] - elgamal = ${toYesNo cfg.precomputation.elgamal} + elgamal = ${boolToString cfg.precomputation.elgamal} [reseed] - verify = ${toYesNo cfg.reseed.verify} + verify = ${boolToString cfg.reseed.verify} file = ${cfg.reseed.file} urls = ${builtins.concatStringsSep "," cfg.reseed.urls} @@ -107,11 +105,11 @@ let (proto: let portStr = toString proto.port; in '' [${proto.name}] - enabled = ${toYesNo proto.enable} + enabled = ${boolToString proto.enable} address = ${proto.address} port = ${toString proto.port} ${if proto ? keys then "keys = ${proto.keys}" else ""} - ${if proto ? auth then "auth = ${toYesNo proto.auth}" else ""} + ${if proto ? auth then "auth = ${boolToString proto.auth}" else ""} ${if proto ? user then "user = ${proto.user}" else ""} ${if proto ? pass then "pass = ${proto.pass}" else ""} ${if proto ? outproxy then "outproxy = ${proto.outproxy}" else ""} diff --git a/nixos/modules/services/networking/ircd-hybrid/default.nix b/nixos/modules/services/networking/ircd-hybrid/default.nix index ede57c5046d..bd583fb020e 100644 --- a/nixos/modules/services/networking/ircd-hybrid/default.nix +++ b/nixos/modules/services/networking/ircd-hybrid/default.nix @@ -12,7 +12,7 @@ let substFiles = [ "=>/conf" ./ircd.conf ]; inherit (pkgs) ircdHybrid coreutils su iproute gnugrep procps; - ipv6Enabled = if config.networking.enableIPv6 then "true" else "false"; + ipv6Enabled = boolToString config.networking.enableIPv6; inherit (cfg) serverName sid description adminEmail extraPort; diff --git a/nixos/modules/services/networking/mosquitto.nix b/nixos/modules/services/networking/mosquitto.nix index 2325424ff3c..5451500b56f 100644 --- a/nixos/modules/services/networking/mosquitto.nix +++ b/nixos/modules/services/networking/mosquitto.nix @@ -16,7 +16,7 @@ let pid_file /run/mosquitto/pid acl_file ${aclFile} persistence true - allow_anonymous ${if cfg.allowAnonymous then "true" else "false"} + allow_anonymous ${boolToString cfg.allowAnonymous} bind_address ${cfg.host} port ${toString cfg.port} ${listenerConf} diff --git a/nixos/modules/services/networking/murmur.nix b/nixos/modules/services/networking/murmur.nix index 81f968ae9fe..13d7c3254f9 100644 --- a/nixos/modules/services/networking/murmur.nix +++ b/nixos/modules/services/networking/murmur.nix @@ -26,21 +26,21 @@ let textmessagelength=${toString cfg.textMsgLength} imagemessagelength=${toString cfg.imgMsgLength} - allowhtml=${if cfg.allowHtml then "true" else "false"} + allowhtml=${boolToString cfg.allowHtml} logdays=${toString cfg.logDays} - bonjour=${if cfg.bonjour then "true" else "false"} - sendversion=${if cfg.sendVersion then "true" else "false"} + bonjour=${boolToString cfg.bonjour} + sendversion=${boolToString cfg.sendVersion} ${if cfg.registerName == "" then "" else "registerName="+cfg.registerName} ${if cfg.registerPassword == "" then "" else "registerPassword="+cfg.registerPassword} ${if cfg.registerUrl == "" then "" else "registerUrl="+cfg.registerUrl} ${if cfg.registerHostname == "" then "" else "registerHostname="+cfg.registerHostname} - certrequired=${if cfg.clientCertRequired then "true" else "false"} + certrequired=${boolToString cfg.clientCertRequired} ${if cfg.sslCert == "" then "" else "sslCert="+cfg.sslCert} ${if cfg.sslKey == "" then "" else "sslKey="+cfg.sslKey} ${if cfg.sslCa == "" then "" else "sslCA="+cfg.sslCa} - + ${cfg.extraConfig} ''; in diff --git a/nixos/modules/services/networking/networkmanager.nix b/nixos/modules/services/networking/networkmanager.nix index 7255ffc5af4..220107a2411 100644 --- a/nixos/modules/services/networking/networkmanager.nix +++ b/nixos/modules/services/networking/networkmanager.nix @@ -162,9 +162,9 @@ in { type = types.listOf (types.submodule { options = { source = mkOption { - type = types.str; + type = types.path; description = '' - A script source. + A script. ''; }; @@ -224,7 +224,7 @@ in { target = "NetworkManager/dispatcher.d/02overridedns"; } ++ lib.imap (i: s: { - text = s.source; + inherit (s) source; target = "NetworkManager/dispatcher.d/${dispatcherTypesSubdirMap.${s.type}}03userscript${lib.fixedWidthNumber 4 i}"; }) cfg.dispatcherScripts; @@ -241,6 +241,7 @@ in { users.extraUsers = [{ name = "nm-openvpn"; uid = config.ids.uids.nm-openvpn; + extraGroups = [ "networkmanager" ]; }]; systemd.packages = cfg.packages; diff --git a/nixos/modules/services/networking/prosody.nix b/nixos/modules/services/networking/prosody.nix index feaa007de15..fb9c9dc67f2 100644 --- a/nixos/modules/services/networking/prosody.nix +++ b/nixos/modules/services/networking/prosody.nix @@ -219,7 +219,7 @@ in data_path = "/var/lib/prosody" - allow_registration = ${ if cfg.allowRegistration then "true" else "false" }; + allow_registration = ${boolToString cfg.allowRegistration}; ${ optionalString cfg.modules.console "console_enabled = true;" } @@ -244,7 +244,7 @@ in ${ lib.concatStringsSep "\n" (lib.mapAttrsToList (n: v: '' VirtualHost "${v.domain}" - enabled = ${if v.enabled then "true" else "false"}; + enabled = ${boolToString v.enabled}; ${ optionalString (v.ssl != null) (createSSLOptsStr v.ssl) } ${ v.extraConfig } '') cfg.virtualHosts) } diff --git a/nixos/modules/services/networking/searx.nix b/nixos/modules/services/networking/searx.nix index 3520c6d3f7d..e0eef9ed96f 100644 --- a/nixos/modules/services/networking/searx.nix +++ b/nixos/modules/services/networking/searx.nix @@ -18,17 +18,12 @@ in services.searx = { - enable = mkOption { - type = types.bool; - default = false; - description = " - Whether to enable the Searx server. See https://github.com/asciimoo/searx - "; - }; + enable = mkEnableOption + "the searx server. See https://github.com/asciimoo/searx"; configFile = mkOption { - type = types.path; - default = ""; + type = types.nullOr types.path; + default = null; description = " The path of the Searx server configuration file. If no file is specified, a default file is used (default config file has @@ -72,7 +67,7 @@ in User = "searx"; ExecStart = "${cfg.package}/bin/searx-run"; }; - } // (optionalAttrs (configFile != "") { + } // (optionalAttrs (configFile != null) { environment.SEARX_SETTINGS_PATH = configFile; }); diff --git a/nixos/modules/services/networking/smokeping.nix b/nixos/modules/services/networking/smokeping.nix index bac79474527..c5c131cb4c5 100644 --- a/nixos/modules/services/networking/smokeping.nix +++ b/nixos/modules/services/networking/smokeping.nix @@ -288,8 +288,11 @@ in }; systemd.services.smokeping = { wantedBy = [ "multi-user.target"]; - serviceConfig.User = cfg.user; - serviceConfig.PermissionsStartOnly = true; + serviceConfig = { + User = cfg.user; + PermissionsStartOnly = true; + Restart = "on-failure"; + }; preStart = '' mkdir -m 0755 -p ${smokepingHome}/cache ${smokepingHome}/data rm -f ${smokepingHome}/cropper diff --git a/nixos/modules/services/networking/ssh/sshd.nix b/nixos/modules/services/networking/ssh/sshd.nix index 42b50d0426a..bebf4e145ca 100644 --- a/nixos/modules/services/networking/ssh/sshd.nix +++ b/nixos/modules/services/networking/ssh/sshd.nix @@ -316,8 +316,6 @@ in UsePAM yes - UsePrivilegeSeparation sandbox - AddressFamily ${if config.networking.enableIPv6 then "any" else "inet"} ${concatMapStrings (port: '' Port ${toString port} diff --git a/nixos/modules/services/networking/sslh.nix b/nixos/modules/services/networking/sslh.nix index bd584a3a85d..e3d65c49fbf 100644 --- a/nixos/modules/services/networking/sslh.nix +++ b/nixos/modules/services/networking/sslh.nix @@ -5,7 +5,7 @@ with lib; let cfg = config.services.sslh; configFile = pkgs.writeText "sslh.conf" '' - verbose: ${if cfg.verbose then "true" else "false"}; + verbose: ${boolToString cfg.verbose}; foreground: true; inetd: false; numeric: false; diff --git a/nixos/modules/services/networking/znc.nix b/nixos/modules/services/networking/znc.nix index 6d68b790e86..1c63d800e26 100644 --- a/nixos/modules/services/networking/znc.nix +++ b/nixos/modules/services/networking/znc.nix @@ -35,7 +35,7 @@ let Port = ${toString confOpts.port} IPv4 = true IPv6 = true - SSL = ${if confOpts.useSSL then "true" else "false"} + SSL = ${boolToString confOpts.useSSL} </Listener> <User ${confOpts.userName}> diff --git a/nixos/modules/services/scheduling/fcron.nix b/nixos/modules/services/scheduling/fcron.nix index bd1ecb40969..bc631bdd044 100644 --- a/nixos/modules/services/scheduling/fcron.nix +++ b/nixos/modules/services/scheduling/fcron.nix @@ -143,10 +143,12 @@ in }; preStart = '' - ${pkgs.coreutils}/bin/mkdir -m 0770 -p /var/spool/fcron - ${pkgs.coreutils}/bin/chown -R fcron:fcron /var/spool/fcron + install \ + --mode 0770 \ + --owner fcron \ + --group fcron \ + --directory /var/spool/fcron # load system crontab file - set -x #${pkgs.fcron}/bin/fcrontab -u systab ${pkgs.writeText "systab" cfg.systab} ''; diff --git a/nixos/modules/services/security/oauth2_proxy.nix b/nixos/modules/services/security/oauth2_proxy.nix index caa7d9d5081..e292fd9851e 100644 --- a/nixos/modules/services/security/oauth2_proxy.nix +++ b/nixos/modules/services/security/oauth2_proxy.nix @@ -10,9 +10,6 @@ let # repeatedArgs (arg: "--arg=${arg}") args repeatedArgs = concatMapStringsSep " "; - # 'toString' doesn't quite do what we want for bools. - fromBool = x: if x then "true" else "false"; - # oauth2_proxy provides many options that are only relevant if you are using # a certain provider. This set maps from provider name to a function that # takes the configuration and returns a string that can be inserted into the @@ -49,24 +46,24 @@ let --client-secret='${cfg.clientSecret}' \ ${optionalString (!isNull cfg.cookie.domain) "--cookie-domain='${cfg.cookie.domain}'"} \ --cookie-expire='${cfg.cookie.expire}' \ - --cookie-httponly=${fromBool cfg.cookie.httpOnly} \ + --cookie-httponly=${boolToString cfg.cookie.httpOnly} \ --cookie-name='${cfg.cookie.name}' \ --cookie-secret='${cfg.cookie.secret}' \ - --cookie-secure=${fromBool cfg.cookie.secure} \ + --cookie-secure=${boolToString cfg.cookie.secure} \ ${optionalString (!isNull cfg.cookie.refresh) "--cookie-refresh='${cfg.cookie.refresh}'"} \ ${optionalString (!isNull cfg.customTemplatesDir) "--custom-templates-dir='${cfg.customTemplatesDir}'"} \ ${repeatedArgs (x: "--email-domain='${x}'") cfg.email.domains} \ --http-address='${cfg.httpAddress}' \ - ${optionalString (!isNull cfg.htpasswd.file) "--htpasswd-file='${cfg.htpasswd.file}' --display-htpasswd-form=${fromBool cfg.htpasswd.displayForm}"} \ + ${optionalString (!isNull cfg.htpasswd.file) "--htpasswd-file='${cfg.htpasswd.file}' --display-htpasswd-form=${boolToString cfg.htpasswd.displayForm}"} \ ${optionalString (!isNull cfg.loginURL) "--login-url='${cfg.loginURL}'"} \ - --pass-access-token=${fromBool cfg.passAccessToken} \ - --pass-basic-auth=${fromBool cfg.passBasicAuth} \ - --pass-host-header=${fromBool cfg.passHostHeader} \ + --pass-access-token=${boolToString cfg.passAccessToken} \ + --pass-basic-auth=${boolToString cfg.passBasicAuth} \ + --pass-host-header=${boolToString cfg.passHostHeader} \ --proxy-prefix='${cfg.proxyPrefix}' \ ${optionalString (!isNull cfg.profileURL) "--profile-url='${cfg.profileURL}'"} \ ${optionalString (!isNull cfg.redeemURL) "--redeem-url='${cfg.redeemURL}'"} \ ${optionalString (!isNull cfg.redirectURL) "--redirect-url='${cfg.redirectURL}'"} \ - --request-logging=${fromBool cfg.requestLogging} \ + --request-logging=${boolToString cfg.requestLogging} \ ${optionalString (!isNull cfg.scope) "--scope='${cfg.scope}'"} \ ${repeatedArgs (x: "--skip-auth-regex='${x}'") cfg.skipAuthRegexes} \ ${optionalString (!isNull cfg.signatureKey) "--signature-key='${cfg.signatureKey}'"} \ diff --git a/nixos/modules/services/system/earlyoom.nix b/nixos/modules/services/system/earlyoom.nix new file mode 100644 index 00000000000..daa46838bfa --- /dev/null +++ b/nixos/modules/services/system/earlyoom.nix @@ -0,0 +1,96 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + ecfg = config.services.earlyoom; +in +{ + options = { + services.earlyoom = { + + enable = mkOption { + type = types.bool; + default = false; + description = '' + Enable early out of memory killing. + ''; + }; + + freeMemThreshold = mkOption { + type = types.int; + default = 10; + description = '' + Minimum of availabe memory (in percent). + If the free memory falls below this threshold and the analog is true for + <option>services.earlyoom.freeSwapThreshold</option> + the killing begins. + ''; + }; + + freeSwapThreshold = mkOption { + type = types.int; + default = 10; + description = '' + Minimum of availabe swap space (in percent). + If the available swap space falls below this threshold and the analog + is true for <option>services.earlyoom.freeMemThreshold</option> + the killing begins. + ''; + }; + + useKernelOOMKiller= mkOption { + type = types.bool; + default = false; + description = '' + Use kernel OOM killer instead of own user-space implementation. + ''; + }; + + ignoreOOMScoreAdjust = mkOption { + type = types.bool; + default = false; + description = '' + Ignore oom_score_adjust values of processes. + User-space implementation only. + ''; + }; + + enableDebugInfo = mkOption { + type = types.bool; + default = false; + description = '' + Enable debugging messages. + ''; + }; + }; + }; + + config = mkIf ecfg.enable { + assertions = [ + { assertion = ecfg.freeMemThreshold > 0 && ecfg.freeMemThreshold <= 100; + message = "Needs to be a positive percentage"; } + { assertion = ecfg.freeSwapThreshold > 0 && ecfg.freeSwapThreshold <= 100; + message = "Needs to be a positive percentage"; } + { assertion = !ecfg.useKernelOOMKiller || !ecfg.ignoreOOMScoreAdjust; + message = "Both options in conjunction do not make sense"; } + ]; + + systemd.services.earlyoom = { + description = "Early OOM Daemon for Linux"; + wantedBy = [ "multi-user.target" ]; + serviceConfig = { + StandardOutput = "null"; + StandardError = "syslog"; + ExecStart = '' + ${pkgs.earlyoom}/bin/earlyoom \ + -m ${toString ecfg.freeMemThreshold} \ + -s ${toString ecfg.freeSwapThreshold} \ + ${optionalString ecfg.useKernelOOMKiller "-k"} \ + ${optionalString ecfg.ignoreOOMScoreAdjust "-i"} \ + ${optionalString ecfg.enableDebugInfo "-d"} + ''; + }; + }; + }; +} diff --git a/nixos/modules/services/torrent/transmission.nix b/nixos/modules/services/torrent/transmission.nix index 5b2e4ca1606..1f319df794b 100644 --- a/nixos/modules/services/torrent/transmission.nix +++ b/nixos/modules/services/torrent/transmission.nix @@ -15,8 +15,7 @@ let # Strings must be quoted, ints and bools must not (for settings.json). toOption = x: - if x == true then "true" - else if x == false then "false" + if isBool x then boolToString x else if isInt x then toString x else toString ''"${x}"''; diff --git a/nixos/modules/services/web-apps/atlassian/crowd.nix b/nixos/modules/services/web-apps/atlassian/crowd.nix index 7ff7dc4e574..b54c91d7de9 100644 --- a/nixos/modules/services/web-apps/atlassian/crowd.nix +++ b/nixos/modules/services/web-apps/atlassian/crowd.nix @@ -137,7 +137,7 @@ in sed -e 's,port="8095",port="${toString cfg.listenPort}" address="${cfg.listenAddress}",' \ '' + (lib.optionalString cfg.proxy.enable '' - -e 's,compression="on",compression="off" protocol="HTTP/1.1" proxyName="${cfg.proxy.name}" proxyPort="${toString cfg.proxy.port}" scheme="${cfg.proxy.scheme}" secure="${toString cfg.proxy.secure}",' \ + -e 's,compression="on",compression="off" protocol="HTTP/1.1" proxyName="${cfg.proxy.name}" proxyPort="${toString cfg.proxy.port}" scheme="${cfg.proxy.scheme}" secure="${boolToString cfg.proxy.secure}",' \ '') + '' ${pkg}/apache-tomcat/conf/server.xml.dist > ${cfg.home}/server.xml ''; diff --git a/nixos/modules/services/web-apps/quassel-webserver.nix b/nixos/modules/services/web-apps/quassel-webserver.nix index d19e4bc5827..2ba5698d6cb 100644 --- a/nixos/modules/services/web-apps/quassel-webserver.nix +++ b/nixos/modules/services/web-apps/quassel-webserver.nix @@ -12,11 +12,11 @@ let port: ${toString cfg.quasselCorePort}, // quasselcore port initialBacklogLimit: ${toString cfg.initialBacklogLimit}, // Amount of backlogs to fetch per buffer on connection backlogLimit: ${toString cfg.backlogLimit}, // Amount of backlogs to fetch per buffer after first retrieval - securecore: ${if cfg.secureCore then "true" else "false"}, // Connect to the core using SSL + securecore: ${boolToString cfg.secureCore}, // Connect to the core using SSL theme: '${cfg.theme}' // Default UI theme }, themes: ['default', 'darksolarized'], // Available themes - forcedefault: ${if cfg.forceHostAndPort then "true" else "false"}, // Will force default host and port to be used, and will hide the corresponding fields in the UI + forcedefault: ${boolToString cfg.forceHostAndPort}, // Will force default host and port to be used, and will hide the corresponding fields in the UI prefixpath: '${cfg.prefixPath}' // Configure this if you use a reverse proxy }; ''; diff --git a/nixos/modules/services/web-apps/tt-rss.nix b/nixos/modules/services/web-apps/tt-rss.nix index 5193814da72..76b0ee6da96 100644 --- a/nixos/modules/services/web-apps/tt-rss.nix +++ b/nixos/modules/services/web-apps/tt-rss.nix @@ -6,8 +6,6 @@ let configVersion = 26; - boolToString = b: if b then "true" else "false"; - cacheDir = "cache"; lockDir = "lock"; feedIconsDir = "feed-icons"; diff --git a/nixos/modules/services/web-servers/lighttpd/gitweb.nix b/nixos/modules/services/web-servers/lighttpd/gitweb.nix index f12cc973446..c8d9836b0b6 100644 --- a/nixos/modules/services/web-servers/lighttpd/gitweb.nix +++ b/nixos/modules/services/web-servers/lighttpd/gitweb.nix @@ -60,7 +60,8 @@ in "/gitweb/" => "${pkgs.git}/share/gitweb/gitweb.cgi" ) setenv.add-environment = ( - "GITWEB_CONFIG" => "${gitwebConfigFile}" + "GITWEB_CONFIG" => "${gitwebConfigFile}", + "HOME" => "${cfg.projectroot}" ) } ''; diff --git a/nixos/modules/services/x11/compton.nix b/nixos/modules/services/x11/compton.nix index d1f7f164e64..d75d24830f8 100644 --- a/nixos/modules/services/x11/compton.nix +++ b/nixos/modules/services/x11/compton.nix @@ -83,7 +83,7 @@ in { "focused = 1" ]; description = '' - List of condition of windows that should have no shadow. + List of conditions of windows that should not be faded. See <literal>compton(1)</literal> man page for more examples. ''; }; @@ -123,7 +123,7 @@ in { "focused = 1" ]; description = '' - List of condition of windows that should have no shadow. + List of conditions of windows that should have no shadow. See <literal>compton(1)</literal> man page for more examples. ''; }; diff --git a/nixos/modules/services/x11/display-managers/default.nix b/nixos/modules/services/x11/display-managers/default.nix index 4e2c0e01ca0..543fd939914 100644 --- a/nixos/modules/services/x11/display-managers/default.nix +++ b/nixos/modules/services/x11/display-managers/default.nix @@ -32,8 +32,14 @@ let '' #! ${pkgs.bash}/bin/bash - # Handle being called by SDDM. - if test "''${1:0:1}" = / ; then eval exec $1 $2 ; fi + # SDDM splits "Exec" line in .desktop file by whitespace and pass script path as $1 + if [[ "$0" = "$1" ]]; then + # remove superfluous $1 again + shift + # join arguments again and evaluate them in a shell context + # to interpret shell quoting + eval exec "$0" "$@" + fi ${optionalString cfg.displayManager.logToJournal '' if [ -z "$_DID_SYSTEMD_CAT" ]; then diff --git a/nixos/modules/services/x11/display-managers/sddm.nix b/nixos/modules/services/x11/display-managers/sddm.nix index affc1261d19..99c03ca81c2 100644 --- a/nixos/modules/services/x11/display-managers/sddm.nix +++ b/nixos/modules/services/x11/display-managers/sddm.nix @@ -59,7 +59,7 @@ let [Autologin] User=${cfg.autoLogin.user} Session=${defaultSessionName}.desktop - Relogin=${if cfg.autoLogin.relogin then "true" else "false"} + Relogin=${boolToString cfg.autoLogin.relogin} ''} ${cfg.extraConfig} diff --git a/nixos/modules/services/x11/hardware/multitouch.nix b/nixos/modules/services/x11/hardware/multitouch.nix index 0e9eb021494..c03bb3b494f 100644 --- a/nixos/modules/services/x11/hardware/multitouch.nix +++ b/nixos/modules/services/x11/hardware/multitouch.nix @@ -74,7 +74,7 @@ in { MatchIsTouchpad "on" Identifier "Touchpads" Driver "mtrack" - Option "IgnorePalm" "${if cfg.ignorePalm then "true" else "false"}" + Option "IgnorePalm" "${boolToString cfg.ignorePalm}" Option "ClickFinger1" "${builtins.elemAt cfg.buttonsMap 0}" Option "ClickFinger2" "${builtins.elemAt cfg.buttonsMap 1}" Option "ClickFinger3" "${builtins.elemAt cfg.buttonsMap 2}" diff --git a/nixos/modules/services/x11/window-managers/default.nix b/nixos/modules/services/x11/window-managers/default.nix index 42785b25158..32ef34bdad2 100644 --- a/nixos/modules/services/x11/window-managers/default.nix +++ b/nixos/modules/services/x11/window-managers/default.nix @@ -15,6 +15,7 @@ in ./dwm.nix ./exwm.nix ./fluxbox.nix + ./fvwm.nix ./herbstluftwm.nix ./i3.nix ./jwm.nix diff --git a/nixos/modules/services/x11/window-managers/fvwm.nix b/nixos/modules/services/x11/window-managers/fvwm.nix new file mode 100644 index 00000000000..9a51b9cd660 --- /dev/null +++ b/nixos/modules/services/x11/window-managers/fvwm.nix @@ -0,0 +1,41 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + cfg = config.services.xserver.windowManager.fvwm; + fvwm = pkgs.fvwm.override { gestures = cfg.gestures; }; +in + +{ + + ###### interface + + options = { + services.xserver.windowManager.fvwm = { + enable = mkEnableOption "Fvwm window manager"; + + gestures = mkOption { + default = false; + type = types.bool; + description = "Whether or not to enable libstroke for gesture support"; + }; + }; + }; + + + ###### implementation + + config = mkIf cfg.enable { + services.xserver.windowManager.session = singleton + { name = "fvwm"; + start = + '' + ${fvwm}/bin/fvwm & + waitPID=$! + ''; + }; + + environment.systemPackages = [ fvwm ]; + }; +} diff --git a/nixos/modules/system/activation/top-level.nix b/nixos/modules/system/activation/top-level.nix index 84c23bed3e3..e9897cc01b6 100644 --- a/nixos/modules/system/activation/top-level.nix +++ b/nixos/modules/system/activation/top-level.nix @@ -53,6 +53,8 @@ let ln -s ${config.system.build.initialRamdisk}/initrd $out/initrd + ln -s ${config.system.build.initialRamdiskSecretAppender}/bin/append-initrd-secrets $out + ln -s ${config.hardware.firmware}/lib/firmware $out/firmware ''} diff --git a/nixos/modules/system/boot/initrd-ssh.nix b/nixos/modules/system/boot/initrd-ssh.nix index 59ecaf8d5a6..d78775c2758 100644 --- a/nixos/modules/system/boot/initrd-ssh.nix +++ b/nixos/modules/system/boot/initrd-ssh.nix @@ -44,9 +44,10 @@ in description = '' RSA SSH private key file in the Dropbear format. - WARNING: This key is contained insecurely in the global Nix store. Do NOT - use your regular SSH host private keys for this purpose or you'll expose - them to regular users! + WARNING: Unless your bootloader supports initrd secrets, this key is + contained insecurely in the global Nix store. Do NOT use your regular + SSH host private keys for this purpose or you'll expose them to + regular users! ''; }; @@ -56,9 +57,10 @@ in description = '' DSS SSH private key file in the Dropbear format. - WARNING: This key is contained insecurely in the global Nix store. Do NOT - use your regular SSH host private keys for this purpose or you'll expose - them to regular users! + WARNING: Unless your bootloader supports initrd secrets, this key is + contained insecurely in the global Nix store. Do NOT use your regular + SSH host private keys for this purpose or you'll expose them to + regular users! ''; }; @@ -68,9 +70,10 @@ in description = '' ECDSA SSH private key file in the Dropbear format. - WARNING: This key is contained insecurely in the global Nix store. Do NOT - use your regular SSH host private keys for this purpose or you'll expose - them to regular users! + WARNING: Unless your bootloader supports initrd secrets, this key is + contained insecurely in the global Nix store. Do NOT use your regular + SSH host private keys for this purpose or you'll expose them to + regular users! ''; }; @@ -97,10 +100,6 @@ in boot.initrd.extraUtilsCommands = '' copy_bin_and_libs ${pkgs.dropbear}/bin/dropbear cp -pv ${pkgs.glibc.out}/lib/libnss_files.so.* $out/lib - - ${optionalString (cfg.hostRSAKey != null) "install -D ${cfg.hostRSAKey} $out/etc/dropbear/dropbear_rsa_host_key"} - ${optionalString (cfg.hostDSSKey != null) "install -D ${cfg.hostDSSKey} $out/etc/dropbear/dropbear_dss_host_key"} - ${optionalString (cfg.hostECDSAKey != null) "install -D ${cfg.hostECDSAKey} $out/etc/dropbear/dropbear_ecdsa_host_key"} ''; boot.initrd.extraUtilsCommandsTest = '' @@ -116,9 +115,6 @@ in touch /var/log/lastlog mkdir -p /etc/dropbear - ${optionalString (cfg.hostRSAKey != null) "ln -s $extraUtils/etc/dropbear/dropbear_rsa_host_key /etc/dropbear/dropbear_rsa_host_key"} - ${optionalString (cfg.hostDSSKey != null) "ln -s $extraUtils/etc/dropbear/dropbear_dss_host_key /etc/dropbear/dropbear_dss_host_key"} - ${optionalString (cfg.hostECDSAKey != null) "ln -s $extraUtils/etc/dropbear/dropbear_ecdsa_host_key /etc/dropbear/dropbear_ecdsa_host_key"} mkdir -p /root/.ssh ${concatStrings (map (key: '' @@ -128,6 +124,11 @@ in dropbear -s -j -k -E -m -p ${toString cfg.port} ''; + boot.initrd.secrets = + (optionalAttrs (cfg.hostRSAKey != null) { "/etc/dropbear/dropbear_rsa_host_key" = cfg.hostRSAKey; }) // + (optionalAttrs (cfg.hostDSSKey != null) { "/etc/dropbear/dropbear_dss_host_key" = cfg.hostDSSKey; }) // + (optionalAttrs (cfg.hostECDSAKey != null) { "/etc/dropbear/dropbear_ecdsa_host_key" = cfg.hostECDSAKey; }); + }; } diff --git a/nixos/modules/system/boot/loader/systemd-boot/systemd-boot-builder.py b/nixos/modules/system/boot/loader/systemd-boot/systemd-boot-builder.py index 04cf17c1b0b..d5e00129a82 100644 --- a/nixos/modules/system/boot/loader/systemd-boot/systemd-boot-builder.py +++ b/nixos/modules/system/boot/loader/systemd-boot/systemd-boot-builder.py @@ -32,8 +32,11 @@ def write_loader_conf(generation): f.write("editor 0"); os.rename("@efiSysMountPoint@/loader/loader.conf.tmp", "@efiSysMountPoint@/loader/loader.conf") +def profile_path(generation, name): + return os.readlink("%s/%s" % (system_dir(generation), name)) + def copy_from_profile(generation, name, dry_run=False): - store_file_path = os.readlink("%s/%s" % (system_dir(generation), name)) + store_file_path = profile_path(generation, name) suffix = os.path.basename(store_file_path) store_dir = os.path.basename(os.path.dirname(store_file_path)) efi_file_path = "/efi/nixos/%s-%s.efi" % (store_dir, suffix) @@ -44,6 +47,11 @@ def copy_from_profile(generation, name, dry_run=False): def write_entry(generation, machine_id): kernel = copy_from_profile(generation, "kernel") initrd = copy_from_profile(generation, "initrd") + try: + append_initrd_secrets = profile_path(generation, "append-initrd-secrets") + subprocess.check_call([append_initrd_secrets, "@efiSysMountPoint@%s" % (initrd)]) + except FileNotFoundError: + pass entry_file = "@efiSysMountPoint@/loader/entries/nixos-generation-%d.conf" % (generation) generation_dir = os.readlink(system_dir(generation)) tmp_path = "%s.tmp" % (entry_file) diff --git a/nixos/modules/system/boot/loader/systemd-boot/systemd-boot.nix b/nixos/modules/system/boot/loader/systemd-boot/systemd-boot.nix index ec02f73cada..a5a88a99be8 100644 --- a/nixos/modules/system/boot/loader/systemd-boot/systemd-boot.nix +++ b/nixos/modules/system/boot/loader/systemd-boot/systemd-boot.nix @@ -65,6 +65,8 @@ in { boot.loader.grub.enable = mkDefault false; + boot.loader.supportsInitrdSecrets = true; + system = { build.installBootLoader = gummibootBuilder; diff --git a/nixos/modules/system/boot/luksroot.nix b/nixos/modules/system/boot/luksroot.nix index 8978b73749b..6e867b67439 100644 --- a/nixos/modules/system/boot/luksroot.nix +++ b/nixos/modules/system/boot/luksroot.nix @@ -6,29 +6,38 @@ let luks = config.boot.initrd.luks; openCommand = name': { name, device, header, keyFile, keyFileSize, allowDiscards, yubikey, ... }: assert name' == name; '' - # Wait for luksRoot to appear, e.g. if on a usb drive. - # XXX: copied and adapted from stage-1-init.sh - should be - # available as a function. - if ! test -e ${device}; then - echo -n "waiting 10 seconds for device ${device} to appear..." - for try in $(seq 10); do - sleep 1 - if test -e ${device}; then break; fi - echo -n . - done - echo "ok" - fi + + # Wait for a target (e.g. device, keyFile, header, ...) to appear. + wait_target() { + local name="$1" + local target="$2" + + if [ ! -e $target ]; then + echo -n "Waiting 10 seconds for $name $target to appear" + local success=false; + for try in $(seq 10); do + echo -n "." + sleep 1 + if [ -e $target ]; then success=true break; fi + done + if [ $success = true ]; then + echo " - success"; + else + echo " - failure"; + fi + fi + } + + # Wait for luksRoot (and optionally keyFile and/or header) to appear, e.g. + # if on a USB drive. + wait_target "device" ${device} ${optionalString (keyFile != null) '' - if ! test -e ${keyFile}; then - echo -n "waiting 10 seconds for key file ${keyFile} to appear..." - for try in $(seq 10); do - sleep 1 - if test -e ${keyFile}; then break; fi - echo -n . - done - echo "ok" - fi + wait_target "key file" ${keyFile} + ''} + + ${optionalString (header != null) '' + wait_target "header" ${header} ''} open_normally() { diff --git a/nixos/modules/system/boot/readonly-mountpoint.c b/nixos/modules/system/boot/readonly-mountpoint.c deleted file mode 100644 index 27b66687382..00000000000 --- a/nixos/modules/system/boot/readonly-mountpoint.c +++ /dev/null @@ -1,20 +0,0 @@ -#include <sys/statvfs.h> -#include <stdio.h> -#include <stdlib.h> - -int main(int argc, char ** argv) { - struct statvfs stat; - if (argc != 2) { - fprintf(stderr, "Usage: %s PATH", argv[0]); - exit(2); - } - if (statvfs(argv[1], &stat) != 0) { - perror("statvfs"); - exit(3); - } - if (stat.f_flag & ST_RDONLY) - exit(0); - else - exit(1); -} - diff --git a/nixos/modules/system/boot/stage-1-init.sh b/nixos/modules/system/boot/stage-1-init.sh index f0699ad9832..c75e637124a 100644 --- a/nixos/modules/system/boot/stage-1-init.sh +++ b/nixos/modules/system/boot/stage-1-init.sh @@ -8,6 +8,14 @@ export LD_LIBRARY_PATH=@extraUtils@/lib export PATH=@extraUtils@/bin ln -s @extraUtils@/bin /bin +# Copy the secrets to their needed location +if [ -d "@extraUtils@/secrets" ]; then + for secret in $(cd "@extraUtils@/secrets"; find . -type f); do + mkdir -p $(dirname "/$secret") + ln -s "@extraUtils@/secrets/$secret" "$secret" + done +fi + # Stop LVM complaining about fd3 export LVM_SUPPRESS_FD_WARNINGS=true diff --git a/nixos/modules/system/boot/stage-1.nix b/nixos/modules/system/boot/stage-1.nix index 61def24efd8..e3a3b6f88cf 100644 --- a/nixos/modules/system/boot/stage-1.nix +++ b/nixos/modules/system/boot/stage-1.nix @@ -82,6 +82,17 @@ let copy_bin_and_libs ${pkgs.e2fsprogs}/sbin/resize2fs ''} + # Copy secrets if needed. + ${optionalString (!config.boot.loader.supportsInitrdSecrets) + (concatStringsSep "\n" (mapAttrsToList (dest: source: + let source' = if source == null then dest else source; in + '' + mkdir -p $(dirname "$out/secrets/${dest}") + cp -a ${source'} "$out/secrets/${dest}" + '' + ) config.boot.initrd.secrets)) + } + ${config.boot.initrd.extraUtilsCommands} # Copy ld manually since it isn't detected correctly @@ -242,6 +253,52 @@ let ]; }; + # Script to add secret files to the initrd at bootloader update time + initialRamdiskSecretAppender = + pkgs.writeScriptBin "append-initrd-secrets" + '' + #!${pkgs.bash}/bin/bash -e + function usage { + echo "USAGE: $0 INITRD_FILE" >&2 + echo "Appends this configuration's secrets to INITRD_FILE" >&2 + } + + if [ $# -ne 1 ]; then + usage + exit 1 + fi + + if [ "$1"x = "--helpx" ]; then + usage + exit 0 + fi + + ${lib.optionalString (config.boot.initrd.secrets == {}) + "exit 0"} + + export PATH=${pkgs.coreutils}/bin:${pkgs.cpio}/bin:${pkgs.gzip}/bin:${pkgs.findutils}/bin + + function cleanup { + if [ -n "$tmp" -a -d "$tmp" ]; then + rm -fR "$tmp" + fi + } + trap cleanup EXIT + + tmp=$(mktemp -d initrd-secrets.XXXXXXXXXX) + + ${lib.concatStringsSep "\n" (mapAttrsToList (dest: source: + let source' = if source == null then dest else toString source; in + '' + mkdir -p $(dirname "$tmp/${dest}") + cp -a ${source'} "$tmp/${dest}" + '' + ) config.boot.initrd.secrets) + } + + (cd "$tmp" && find . | cpio -H newc -o) | gzip >>"$1" + ''; + in { @@ -370,6 +427,25 @@ in example = "xz"; }; + boot.initrd.secrets = mkOption + { internal = true; + default = {}; + type = types.attrsOf (types.nullOr types.path); + description = + '' + Secrets to append to the initrd. The attribute name is the + path the secret should have inside the initrd, the value + is the path it should be copied from (or null for the same + path inside and out). + ''; + example = literalExample + '' + { "/etc/dropbear/dropbear_rsa_host_key" = + ./secret-dropbear-key; + } + ''; + }; + boot.initrd.supportedFilesystems = mkOption { default = [ ]; example = [ "btrfs" ]; @@ -377,6 +453,18 @@ in description = "Names of supported filesystem types in the initial ramdisk."; }; + boot.loader.supportsInitrdSecrets = mkOption + { internal = true; + default = false; + type = types.bool; + description = + '' + Whether the bootloader setup runs append-initrd-secrets. + If not, any needed secrets must be copied into the initrd + and thus added to the store. + ''; + }; + fileSystems = mkOption { options.neededForBoot = mkOption { default = false; @@ -404,9 +492,8 @@ in } ]; - system.build.bootStage1 = bootStage1; - system.build.initialRamdisk = initialRamdisk; - system.build.extraUtils = extraUtils; + system.build = + { inherit bootStage1 initialRamdisk initialRamdiskSecretAppender extraUtils; }; system.requiredKernelConfig = with config.lib.kernelConfig; [ (isYes "TMPFS") diff --git a/nixos/modules/system/boot/stage-2-init.sh b/nixos/modules/system/boot/stage-2-init.sh index f827e530f87..46aed44bf10 100644 --- a/nixos/modules/system/boot/stage-2-init.sh +++ b/nixos/modules/system/boot/stage-2-init.sh @@ -2,7 +2,22 @@ systemConfig=@systemConfig@ -export HOME=/root +export HOME=/root PATH="@path@" + + +# Process the kernel command line. +for o in $(</proc/cmdline); do + case $o in + boot.debugtrace) + # Show each command. + set -x + ;; + resume=*) + set -- $(IFS==; echo $o) + resumeDevice=$2 + ;; + esac +done # Print a greeting. @@ -11,21 +26,6 @@ echo -e "\e[1;32m<<< NixOS Stage 2 >>>\e[0m" echo -# Set the PATH. -setPath() { - local dirs="$1" - export PATH=/empty - for i in $dirs; do - PATH=$PATH:$i/bin - if test -e $i/sbin; then - PATH=$PATH:$i/sbin - fi - done -} - -setPath "@path@" - - # Normally, stage 1 mounts the root filesystem read/writable. # However, in some environments, stage 2 is executed directly, and the # root is read-only. So make it writable here. @@ -61,7 +61,9 @@ echo "booting system configuration $systemConfig" > /dev/kmsg chown -f 0:30000 /nix/store chmod -f 1775 /nix/store if [ -n "@readOnlyStore@" ]; then - if ! readonly-mountpoint /nix/store; then + if ! [[ "$(findmnt --noheadings --output OPTIONS /nix/store)" =~ ro(,|$) ]]; then + # FIXME when linux < 4.5 is EOL, switch to atomic bind mounts + #mount /nix/store /nix/store -o bind,remount,ro mount --bind /nix/store /nix/store mount -o remount,ro,bind /nix/store fi @@ -75,31 +77,12 @@ rm -f /etc/mtab* # not that we care about stale locks ln -s /proc/mounts /etc/mtab -# Process the kernel command line. -for o in $(cat /proc/cmdline); do - case $o in - boot.debugtrace) - # Show each command. - set -x - ;; - resume=*) - set -- $(IFS==; echo $o) - resumeDevice=$2 - ;; - esac -done - - # More special file systems, initialise required directories. [ -e /proc/bus/usb ] && mount -t usbfs usbfs /proc/bus/usb # UML doesn't have USB by default mkdir -m 01777 -p /tmp -mkdir -m 0755 -p /var /var/log /var/lib /var/db -mkdir -m 0755 -p /nix/var -mkdir -m 0700 -p /root -chmod 0700 /root -mkdir -m 0755 -p /bin # for the /bin/sh symlink -mkdir -m 0755 -p /home -mkdir -m 0755 -p /etc/nixos +mkdir -m 0755 -p /var/{log,lib,db} /nix/var /etc/nixos/ \ + /run/lock /home /bin # for the /bin/sh symlink +install -m 0700 -d /root # Miscellaneous boot time cleanup. @@ -111,9 +94,6 @@ rm -f /etc/{group,passwd,shadow}.lock rm -rf /nix/var/nix/gcroots/tmp /nix/var/nix/temproots -mkdir -m 0755 -p /run/lock - - # For backwards compatibility, symlink /var/run to /run, and /var/lock # to /run/lock. ln -s /run /var/run @@ -127,8 +107,8 @@ fi # Use /etc/resolv.conf supplied by systemd-nspawn, if applicable. -if [ -n "@useHostResolvConf@" -a -e /etc/resolv.conf ]; then - cat /etc/resolv.conf | resolvconf -m 1000 -a host +if [ -n "@useHostResolvConf@" ] && [ -e /etc/resolv.conf ]; then + resolvconf -m 1000 -a host </etc/resolv.conf fi # Log the script output to /dev/kmsg or /run/log/stage-2-init.log. diff --git a/nixos/modules/system/boot/stage-2.nix b/nixos/modules/system/boot/stage-2.nix index 7e4ec2a4a67..8db6d2d2f73 100644 --- a/nixos/modules/system/boot/stage-2.nix +++ b/nixos/modules/system/boot/stage-2.nix @@ -7,15 +7,6 @@ let kernel = config.boot.kernelPackages.kernel; activateConfiguration = config.system.activationScripts.script; - readonlyMountpoint = pkgs.stdenv.mkDerivation { - name = "readonly-mountpoint"; - unpackPhase = "true"; - installPhase = '' - mkdir -p $out/bin - cc -O3 ${./readonly-mountpoint.c} -o $out/bin/readonly-mountpoint - ''; - }; - bootStage2 = pkgs.substituteAll { src = ./stage-2-init.sh; shellDebug = "${pkgs.bashInteractive}/bin/bash"; @@ -23,11 +14,11 @@ let inherit (config.nix) readOnlyStore; inherit (config.networking) useHostResolvConf; inherit (config.system.build) earlyMountScript; - path = - [ pkgs.coreutils - pkgs.utillinux - pkgs.openresolv - ] ++ optional config.nix.readOnlyStore readonlyMountpoint; + path = lib.makeBinPath [ + pkgs.coreutils + pkgs.utillinux + pkgs.openresolv + ]; postBootCommands = pkgs.writeText "local-cmds" '' ${config.boot.postBootCommands} diff --git a/nixos/modules/system/boot/systemd-lib.nix b/nixos/modules/system/boot/systemd-lib.nix index 7dbf3b25cdb..7c01f8ea9b7 100644 --- a/nixos/modules/system/boot/systemd-lib.nix +++ b/nixos/modules/system/boot/systemd-lib.nix @@ -10,7 +10,7 @@ rec { makeUnit = name: unit: let - pathSafeName = lib.replaceChars ["@" ":" "\\"] ["-" "-" "-"] name; + pathSafeName = lib.replaceChars ["@" ":" "\\" "[" "]"] ["-" "-" "-" "" ""] name; in if unit.enable then pkgs.runCommand "unit-${pathSafeName}" diff --git a/nixos/modules/system/boot/systemd.nix b/nixos/modules/system/boot/systemd.nix index bff6739db61..f798862513c 100644 --- a/nixos/modules/system/boot/systemd.nix +++ b/nixos/modules/system/boot/systemd.nix @@ -829,7 +829,8 @@ in # Some overrides to upstream units. systemd.services."systemd-backlight@".restartIfChanged = false; - systemd.services."systemd-rfkill@".restartIfChanged = false; + systemd.services."systemd-fsck@".restartIfChanged = false; + systemd.services."systemd-fsck@".path = [ config.system.path ]; systemd.services."user@".restartIfChanged = false; systemd.services.systemd-journal-flush.restartIfChanged = false; systemd.services.systemd-random-seed.restartIfChanged = false; diff --git a/nixos/modules/tasks/filesystems.nix b/nixos/modules/tasks/filesystems.nix index 9f30eb61146..3951d617f6f 100644 --- a/nixos/modules/tasks/filesystems.nix +++ b/nixos/modules/tasks/filesystems.nix @@ -221,7 +221,7 @@ in environment.etc.fstab.text = let - fsToSkipCheck = [ "none" "btrfs" "zfs" "tmpfs" "nfs" "vboxsf" "glusterfs" ]; + fsToSkipCheck = [ "none" "bindfs" "btrfs" "zfs" "tmpfs" "nfs" "vboxsf" "glusterfs" ]; skipCheck = fs: fs.noCheck || fs.device == "none" || builtins.elem fs.fsType fsToSkipCheck; in '' # This is a generated file. Do not edit! diff --git a/nixos/modules/tasks/network-interfaces-scripted.nix b/nixos/modules/tasks/network-interfaces-scripted.nix index f30906b84a2..f6f104ce7a6 100644 --- a/nixos/modules/tasks/network-interfaces-scripted.nix +++ b/nixos/modules/tasks/network-interfaces-scripted.nix @@ -120,7 +120,7 @@ let optionalString (cfg.defaultGatewayWindowSize != null) "window ${toString cfg.defaultGatewayWindowSize}"} ${ optionalString (cfg.defaultGateway.interface != null) - "dev ${cfg.defaultGateway.interface}"} || true + "dev ${cfg.defaultGateway.interface}"} proto static || true ''} ${optionalString (cfg.defaultGateway6 != null && cfg.defaultGateway6.address != "") '' # FIXME: get rid of "|| true" (necessary to make it idempotent). @@ -130,7 +130,7 @@ let optionalString (cfg.defaultGatewayWindowSize != null) "window ${toString cfg.defaultGatewayWindowSize}"} ${ optionalString (cfg.defaultGateway6.interface != null) - "dev ${cfg.defaultGateway6.interface}"} || true + "dev ${cfg.defaultGateway6.interface}"} proto static || true ''} ''; }; @@ -159,35 +159,42 @@ let after = [ "network-pre.target" ] ++ (deviceDependency i.name); serviceConfig.Type = "oneshot"; serviceConfig.RemainAfterExit = true; + # Restart rather than stop+start this unit to prevent the + # network from dying during switch-to-configuration. + stopIfChanged = false; path = [ pkgs.iproute ]; script = '' + # FIXME: shouldn't this be done in network-link? echo "bringing up interface..." ip link set "${i.name}" up - restart_network_interfaces=false + state="/run/nixos/network/addresses/${i.name}" + + mkdir -p $(dirname "$state") + '' + flip concatMapStrings (ips) (ip: let address = "${ip.address}/${toString ip.prefixLength}"; in '' - echo "checking ip ${address}..." + echo "${address}" >> $state if out=$(ip addr add "${address}" dev "${i.name}" 2>&1); then - echo "added ip ${address}..." + echo "added ip ${address}" elif ! echo "$out" | grep "File exists" >/dev/null 2>&1; then echo "failed to add ${address}" exit 1 fi ''); - preStop = flip concatMapStrings (ips) (ip: - let - address = "${ip.address}/${toString ip.prefixLength}"; - in - '' - echo -n "deleting ${address}..." - ip addr del "${address}" dev "${i.name}" >/dev/null 2>&1 || echo -n " Failed" - echo "" - ''); + preStop = '' + state="/run/nixos/network/addresses/${i.name}" + while read address; do + echo -n "deleting $address..." + ip addr del "$address" dev "${i.name}" >/dev/null 2>&1 || echo -n " Failed" + echo "" + done < "$state" + rm -f "$state" + ''; }; createTunDevice = i: nameValuePair "${i.name}-netdev" diff --git a/nixos/modules/tasks/powertop.nix b/nixos/modules/tasks/powertop.nix new file mode 100644 index 00000000000..6f57f5f5c25 --- /dev/null +++ b/nixos/modules/tasks/powertop.nix @@ -0,0 +1,27 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + cfg = config.powerManagment.powertop; +in { + ###### interface + + options.powerManagment.powertop.enable = mkEnableOption "powertop auto tuning on startup"; + + ###### implementation + + config = mkIf (cfg.enable) { + systemd.services = { + powertop = { + wantedBy = [ "multi-user.target" ]; + description = "Powertop tunings"; + serviceConfig = { + Type = "oneshot"; + RemainAfterExit = "yes"; + ExecStart = "${pkgs.powertop}/bin/powertop --auto-tune"; + }; + }; + }; + }; +} diff --git a/nixos/modules/virtualisation/amazon-image.nix b/nixos/modules/virtualisation/amazon-image.nix index 80e481d79b9..3e47710361a 100644 --- a/nixos/modules/virtualisation/amazon-image.nix +++ b/nixos/modules/virtualisation/amazon-image.nix @@ -15,6 +15,12 @@ let cfg = config.ec2; in config = { + assertions = [ + { assertion = cfg.hvm; + message = "Paravirtualized EC2 instances are no longer supported."; + } + ]; + virtualisation.growPartition = cfg.hvm; fileSystems."/" = { diff --git a/nixos/modules/virtualisation/amazon-options.nix b/nixos/modules/virtualisation/amazon-options.nix index 34a50dcab16..349fd3adfc9 100644 --- a/nixos/modules/virtualisation/amazon-options.nix +++ b/nixos/modules/virtualisation/amazon-options.nix @@ -3,7 +3,7 @@ options = { ec2 = { hvm = lib.mkOption { - default = false; + default = lib.versionAtLeast config.system.stateVersion "17.03"; internal = true; description = '' Whether the EC2 instance is a HVM instance. @@ -11,6 +11,4 @@ }; }; }; - - config = {}; } diff --git a/nixos/modules/virtualisation/docker.nix b/nixos/modules/virtualisation/docker.nix index 4b30a38f832..f1101d7ea66 100644 --- a/nixos/modules/virtualisation/docker.nix +++ b/nixos/modules/virtualisation/docker.nix @@ -126,7 +126,17 @@ in path = [ pkgs.kmod ] ++ (optional (cfg.storageDriver == "zfs") pkgs.zfs); }; - systemd.sockets.docker.socketConfig.ListenStream = cfg.listenOptions; + + systemd.sockets.docker = { + description = "Docker Socket for the API"; + wantedBy = [ "sockets.target" ]; + socketConfig = { + ListenStream = cfg.listenOptions; + SocketMode = "0660"; + SocketUser = "root"; + SocketGroup = "docker"; + }; + }; } ]); diff --git a/nixos/modules/virtualisation/ec2-amis.nix b/nixos/modules/virtualisation/ec2-amis.nix index d592a23c303..745518f8597 100644 --- a/nixos/modules/virtualisation/ec2-amis.nix +++ b/nixos/modules/virtualisation/ec2-amis.nix @@ -193,5 +193,35 @@ let self = { "16.09".us-west-2.pv-ebs = "ami-6d4af60d"; "16.09".us-west-2.pv-s3 = "ami-de48f4be"; - latest = self."16.09"; + # 17.03.885.6024dd4067 + "17.03".ap-northeast-1.hvm-ebs = "ami-dbd0f7bc"; + "17.03".ap-northeast-1.hvm-s3 = "ami-7cdff81b"; + "17.03".ap-northeast-2.hvm-ebs = "ami-c59a48ab"; + "17.03".ap-northeast-2.hvm-s3 = "ami-0b944665"; + "17.03".ap-south-1.hvm-ebs = "ami-4f413220"; + "17.03".ap-south-1.hvm-s3 = "ami-864033e9"; + "17.03".ap-southeast-1.hvm-ebs = "ami-e08c3383"; + "17.03".ap-southeast-1.hvm-s3 = "ami-c28f30a1"; + "17.03".ap-southeast-2.hvm-ebs = "ami-fca9a69f"; + "17.03".ap-southeast-2.hvm-s3 = "ami-3daaa55e"; + "17.03".ca-central-1.hvm-ebs = "ami-9b00bdff"; + "17.03".ca-central-1.hvm-s3 = "ami-e800bd8c"; + "17.03".eu-central-1.hvm-ebs = "ami-5450803b"; + "17.03".eu-central-1.hvm-s3 = "ami-6e2efe01"; + "17.03".eu-west-1.hvm-ebs = "ami-10754c76"; + "17.03".eu-west-1.hvm-s3 = "ami-11734a77"; + "17.03".eu-west-2.hvm-ebs = "ami-ff1d099b"; + "17.03".eu-west-2.hvm-s3 = "ami-fe1d099a"; + "17.03".sa-east-1.hvm-ebs = "ami-d95d3eb5"; + "17.03".sa-east-1.hvm-s3 = "ami-fca2c190"; + "17.03".us-east-1.hvm-ebs = "ami-0940c61f"; + "17.03".us-east-1.hvm-s3 = "ami-674fc971"; + "17.03".us-east-2.hvm-ebs = "ami-afc2e6ca"; + "17.03".us-east-2.hvm-s3 = "ami-a1cde9c4"; + "17.03".us-west-1.hvm-ebs = "ami-587b2138"; + "17.03".us-west-1.hvm-s3 = "ami-70411b10"; + "17.03".us-west-2.hvm-ebs = "ami-a93daac9"; + "17.03".us-west-2.hvm-s3 = "ami-5139ae31"; + + latest = self."17.03"; }; in self diff --git a/nixos/modules/virtualisation/google-compute-image.nix b/nixos/modules/virtualisation/google-compute-image.nix index a3dd3bd55d1..5673d55b339 100644 --- a/nixos/modules/virtualisation/google-compute-image.nix +++ b/nixos/modules/virtualisation/google-compute-image.nix @@ -2,10 +2,10 @@ with lib; let - diskSize = "100G"; + diskSize = "1G"; in { - imports = [ ../profiles/headless.nix ../profiles/qemu-guest.nix ]; + imports = [ ../profiles/headless.nix ../profiles/qemu-guest.nix ./grow-partition.nix ]; # https://cloud.google.com/compute/docs/tutorials/building-images networking.firewall.enable = mkDefault false; @@ -94,7 +94,10 @@ in '' ); - fileSystems."/".label = "nixos"; + fileSystems."/" = { + device = "/dev/disk/by-label/nixos"; + autoResize = true; + }; boot.kernelParams = [ "console=ttyS0" "panic=1" "boot.panic_on_fail" ]; boot.initrd.kernelModules = [ "virtio_scsi" ]; diff --git a/nixos/release.nix b/nixos/release.nix index 5f9a5b0e064..95b284cb705 100644 --- a/nixos/release.nix +++ b/nixos/release.nix @@ -288,8 +288,8 @@ in rec { tests.pam-oath-login = callTest tests/pam-oath-login.nix {}; #tests.panamax = hydraJob (import tests/panamax.nix { system = "x86_64-linux"; }); tests.peerflix = callTest tests/peerflix.nix {}; + tests.postgresql = callSubTests tests/postgresql.nix {}; tests.pgjwt = callTest tests/pgjwt.nix {}; - tests.postgresql = callTest tests/postgresql.nix {}; tests.printing = callTest tests/printing.nix {}; tests.proxy = callTest tests/proxy.nix {}; tests.pumpio = callTest tests/pump.io.nix {}; diff --git a/nixos/tests/docker.nix b/nixos/tests/docker.nix index 1b57a94a05d..9096a5868f6 100644 --- a/nixos/tests/docker.nix +++ b/nixos/tests/docker.nix @@ -11,6 +11,21 @@ import ./make-test.nix ({ pkgs, ...} : { { config, pkgs, ... }: { virtualisation.docker.enable = true; + + users.users = { + noprivs = { + isNormalUser = true; + description = "Can't access the docker daemon"; + password = "foobar"; + }; + + hasprivs = { + isNormalUser = true; + description = "Can access the docker daemon"; + password = "foobar"; + extraGroups = [ "docker" ]; + }; + }; }; }; @@ -21,6 +36,8 @@ import ./make-test.nix ({ pkgs, ...} : { $docker->succeed("tar cv --files-from /dev/null | docker import - scratchimg"); $docker->succeed("docker run -d --name=sleeping -v /nix/store:/nix/store -v /run/current-system/sw/bin:/bin scratchimg /bin/sleep 10"); $docker->succeed("docker ps | grep sleeping"); + $docker->succeed("sudo -u hasprivs docker ps"); + $docker->fail("sudo -u noprivs docker ps"); $docker->succeed("docker stop sleeping"); ''; }) diff --git a/nixos/tests/installer.nix b/nixos/tests/installer.nix index 35dd00fe630..3ab3c1bac48 100644 --- a/nixos/tests/installer.nix +++ b/nixos/tests/installer.nix @@ -34,6 +34,12 @@ let boot.loader.systemd-boot.enable = true; ''} + users.extraUsers.alice = { + isNormalUser = true; + home = "/home/alice"; + description = "Alice Foobar"; + }; + hardware.enableAllFirmware = lib.mkForce false; ${replaceChars ["\n"] ["\n "] extraConfig} @@ -96,7 +102,7 @@ let $machine->shutdown; # Now see if we can boot the installation. - $machine = createMachine({ ${hdFlags} qemuFlags => "${qemuFlags}" }); + $machine = createMachine({ ${hdFlags} qemuFlags => "${qemuFlags}", name => "boot-after-install" }); # For example to enter LUKS passphrase. ${preBootCommands} @@ -118,11 +124,17 @@ let $machine->waitForUnit("swap.target"); $machine->succeed("cat /proc/swaps | grep -q /dev"); + # Check that the store is in good shape + $machine->succeed("nix-store --verify --check-contents >&2"); + # Check whether the channel works. $machine->succeed("nix-env -iA nixos.procps >&2"); $machine->succeed("type -tP ps | tee /dev/stderr") =~ /.nix-profile/ or die "nix-env failed"; + # Check that the daemon works, and that non-root users can run builds (this will build a new profile generation through the daemon) + $machine->succeed("su alice -l -c 'nix-env -iA nixos.procps' >&2"); + # We need to a writable nix-store on next boot. $machine->copyFileFromHost( "${ makeConfig { inherit bootLoader grubVersion grubDevice grubIdentifier extraConfig; forceGrubReinstallCount = 1; } }", @@ -139,7 +151,7 @@ let $machine->shutdown; # Check whether a writable store build works - $machine = createMachine({ ${hdFlags} qemuFlags => "${qemuFlags}" }); + $machine = createMachine({ ${hdFlags} qemuFlags => "${qemuFlags}", name => "rebuild-switch" }); ${preBootCommands} $machine->waitForUnit("multi-user.target"); $machine->copyFileFromHost( @@ -150,7 +162,7 @@ let # And just to be sure, check that the machine still boots after # "nixos-rebuild switch". - $machine = createMachine({ ${hdFlags} qemuFlags => "${qemuFlags}" }); + $machine = createMachine({ ${hdFlags} qemuFlags => "${qemuFlags}", "boot-after-rebuild-switch" }); ${preBootCommands} $machine->waitForUnit("network.target"); $machine->shutdown; diff --git a/nixos/tests/postgresql.nix b/nixos/tests/postgresql.nix index f17384b44ba..1f4f43a2666 100644 --- a/nixos/tests/postgresql.nix +++ b/nixos/tests/postgresql.nix @@ -1,26 +1,46 @@ -import ./make-test.nix ({ pkgs, ...} : { - name = "postgresql"; - meta = with pkgs.stdenv.lib.maintainers; { - maintainers = [ zagy ]; - }; - - nodes = { - master = - { pkgs, config, ... }: +{ system ? builtins.currentSystem }: +with import ../lib/testing.nix { inherit system; }; +with pkgs.lib; +let + postgresql-versions = pkgs.callPackages ../../pkgs/servers/sql/postgresql { }; + test-sql = pkgs.writeText "postgresql-test" '' + CREATE EXTENSION pgcrypto; -- just to check if lib loading works + CREATE TABLE sth ( + id int + ); + INSERT INTO sth (id) VALUES (1); + INSERT INTO sth (id) VALUES (1); + INSERT INTO sth (id) VALUES (1); + INSERT INTO sth (id) VALUES (1); + INSERT INTO sth (id) VALUES (1); + ''; + make-postgresql-test = postgresql-name: postgresql-package: { + name = postgresql-name; + meta = with pkgs.stdenv.lib.maintainers; { + maintainers = [ zagy ]; + }; + machine = {pkgs, config, ...}: { + services.postgresql.package=postgresql-package; services.postgresql.enable = true; - services.postgresql.initialScript = pkgs.writeText "postgresql-init.sql" - '' - CREATE ROLE postgres WITH superuser login createdb; - ''; }; - }; - testScript = '' - startAll; - $master->waitForUnit("postgresql"); - $master->sleep(10); # Hopefully this is long enough!! - $master->succeed("echo 'select 1' | sudo -u postgres psql"); - ''; -}) + testScript = '' + $machine->start; + $machine->waitForUnit("postgresql"); + # postgresql should be available just after unit start + $machine->succeed("cat ${test-sql} | psql postgres"); + $machine->shutdown; # make sure that postgresql survive restart (bug #1735) + sleep(2); + $machine->start; + $machine->waitForUnit("postgresql"); + $machine->fail('test $(psql postgres -tAc "SELECT * FROM sth;"|wc -l) -eq 3'); + $machine->succeed('test $(psql postgres -tAc "SELECT * FROM sth;"|wc -l) -eq 5'); + $machine->fail('test $(psql postgres -tAc "SELECT * FROM sth;"|wc -l) -eq 4'); + $machine->shutdown; + ''; + + }; +in + mapAttrs' (p-name: p-package: {name=p-name; value=make-postgresql-test p-name p-package;}) postgresql-versions |