diff options
author | John Ericson <John.Ericson@Obsidian.Systems> | 2018-03-19 21:47:56 -0400 |
---|---|---|
committer | John Ericson <John.Ericson@Obsidian.Systems> | 2018-03-19 21:47:56 -0400 |
commit | b9a720c524908aaef0788697edf7eb2d8a75e53b (patch) | |
tree | 85e8c7a7c13bca63582a8defd209688d9e803135 /nixos | |
parent | 192f4144b282a7f04695fcb79d84e8278ee6af8c (diff) | |
parent | 5675f17b0ed8be07752dedb1a9c42a20142f07e9 (diff) | |
download | nixpkgs-b9a720c524908aaef0788697edf7eb2d8a75e53b.tar nixpkgs-b9a720c524908aaef0788697edf7eb2d8a75e53b.tar.gz nixpkgs-b9a720c524908aaef0788697edf7eb2d8a75e53b.tar.bz2 nixpkgs-b9a720c524908aaef0788697edf7eb2d8a75e53b.tar.lz nixpkgs-b9a720c524908aaef0788697edf7eb2d8a75e53b.tar.xz nixpkgs-b9a720c524908aaef0788697edf7eb2d8a75e53b.tar.zst nixpkgs-b9a720c524908aaef0788697edf7eb2d8a75e53b.zip |
Merge remote-tracking branch 'upstream/master' into fix-cross-jobs
Diffstat (limited to 'nixos')
93 files changed, 1508 insertions, 413 deletions
diff --git a/nixos/doc/manual/default.nix b/nixos/doc/manual/default.nix index 6098b057a37..3b01f4fed35 100644 --- a/nixos/doc/manual/default.nix +++ b/nixos/doc/manual/default.nix @@ -87,7 +87,7 @@ let echo "for hints about the offending path)." exit 1 fi - ${libxslt.bin}/bin/xsltproc \ + ${buildPackages.libxslt.bin}/bin/xsltproc \ --stringparam revision '${revision}' \ -o $out ${./options-to-docbook.xsl} $optionsXML ''; @@ -139,7 +139,7 @@ let manual-combined = runCommand "nixos-manual-combined" { inherit sources; - buildInputs = [ libxml2 libxslt ]; + nativeBuildInputs = [ buildPackages.libxml2 buildPackages.libxslt ]; meta.description = "The NixOS manual as plain docbook XML"; } '' @@ -194,7 +194,7 @@ let olinkDB = runCommand "manual-olinkdb" { inherit sources; - buildInputs = [ libxml2 libxslt ]; + nativeBuildInputs = [ buildPackages.libxml2 buildPackages.libxslt ]; } '' xsltproc \ @@ -244,7 +244,7 @@ in rec { # Generate the NixOS manual. manual = runCommand "nixos-manual" { inherit sources; - buildInputs = [ libxml2 libxslt ]; + nativeBuildInputs = [ buildPackages.libxml2 buildPackages.libxslt ]; meta.description = "The NixOS manual in HTML format"; allowedReferences = ["out"]; } @@ -302,7 +302,7 @@ in rec { # Generate the NixOS manpages. manpages = runCommand "nixos-manpages" { inherit sources; - buildInputs = [ libxml2 libxslt ]; + nativeBuildInputs = [ buildPackages.libxml2 buildPackages.libxslt ]; allowedReferences = ["out"]; } '' diff --git a/nixos/doc/manual/development/option-types.xml b/nixos/doc/manual/development/option-types.xml index ec940d5d2b8..13fa8d1e114 100644 --- a/nixos/doc/manual/development/option-types.xml +++ b/nixos/doc/manual/development/option-types.xml @@ -282,8 +282,8 @@ options.mod = mkOption { option set (<xref linkend='ex-submodule-listof-definition' />).</para> -<example xml:id='ex-submodule-listof-declaration'><title>Declaration of a list - nof submodules</title> +<example xml:id='ex-submodule-listof-declaration'><title>Declaration of a list + of submodules</title> <screen> options.mod = mkOption { description = "submodule example"; diff --git a/nixos/doc/manual/installation/installing-from-other-distro.xml b/nixos/doc/manual/installation/installing-from-other-distro.xml index 55623898827..ecd020a067a 100644 --- a/nixos/doc/manual/installation/installing-from-other-distro.xml +++ b/nixos/doc/manual/installation/installing-from-other-distro.xml @@ -227,6 +227,18 @@ $ sudo groupdel nixbld</screen> line)</para></listitem> </itemizedlist> + <note><para>Support for <literal>NIXOS_LUSTRATE</literal> was added + in NixOS 16.09. The act of "lustrating" refers to the + wiping of the existing distribution. Creating + <literal>/etc/NIXOS_LUSTRATE</literal> can also be used on + NixOS to remove all mutable files from your root partition + (anything that's not in <literal>/nix</literal> or + <literal>/boot</literal> gets "lustrated" on the next + boot.</para> + <para>lustrate /ˈlʌstreɪt/ verb.</para> + <para>purify by expiatory sacrifice, ceremonial washing, or + some other ritual action.</para></note> + <para>Let's create the files:</para> <screen> diff --git a/nixos/doc/manual/release-notes/release-notes.xml b/nixos/doc/manual/release-notes/release-notes.xml index 5ed56bde665..b7f9fab44f3 100644 --- a/nixos/doc/manual/release-notes/release-notes.xml +++ b/nixos/doc/manual/release-notes/release-notes.xml @@ -9,6 +9,7 @@ <para>This section lists the release notes for each stable version of NixOS and current unstable revision.</para> +<xi:include href="rl-1809.xml" /> <xi:include href="rl-1803.xml" /> <xi:include href="rl-1709.xml" /> <xi:include href="rl-1703.xml" /> diff --git a/nixos/doc/manual/release-notes/rl-1809.xml b/nixos/doc/manual/release-notes/rl-1809.xml new file mode 100644 index 00000000000..959bd86759b --- /dev/null +++ b/nixos/doc/manual/release-notes/rl-1809.xml @@ -0,0 +1,82 @@ +<section xmlns="http://docbook.org/ns/docbook" + xmlns:xlink="http://www.w3.org/1999/xlink" + xmlns:xi="http://www.w3.org/2001/XInclude" + version="5.0" + xml:id="sec-release-18.09"> + +<title>Release 18.09 (“Jellyfish”, 2018/09/??)</title> + +<section xmlns="http://docbook.org/ns/docbook" + xmlns:xlink="http://www.w3.org/1999/xlink" + xmlns:xi="http://www.w3.org/2001/XInclude" + version="5.0" + xml:id="sec-release-18.09-highlights"> + +<title>Highlights</title> + +<para>In addition to numerous new and upgraded packages, this release +has the following highlights: </para> + +<itemizedlist> + <listitem> + <para> + TODO + </para> + </listitem> + +</itemizedlist> + +</section> +<section xmlns="http://docbook.org/ns/docbook" + xmlns:xlink="http://www.w3.org/1999/xlink" + xmlns:xi="http://www.w3.org/2001/XInclude" + version="5.0" + xml:id="sec-release-18.09-new-services"> + +<title>New Services</title> + +<para>The following new services were added since the last release:</para> + +<itemizedlist> + <listitem> + <para></para> + </listitem> +</itemizedlist> + +</section> +<section xmlns="http://docbook.org/ns/docbook" + xmlns:xlink="http://www.w3.org/1999/xlink" + xmlns:xi="http://www.w3.org/2001/XInclude" + version="5.0" + xml:id="sec-release-18.09-incompatibilities"> + +<title>Backward Incompatibilities</title> + +<para>When upgrading from a previous release, please be aware of the +following incompatible changes:</para> + +<itemizedlist> + <listitem> + <para> + </para> + </listitem> +</itemizedlist> + +</section> +<section xmlns="http://docbook.org/ns/docbook" + xmlns:xlink="http://www.w3.org/1999/xlink" + xmlns:xi="http://www.w3.org/2001/XInclude" + version="5.0" + xml:id="sec-release-18.09-notable-changes"> + +<title>Other Notable Changes</title> + +<itemizedlist> + <listitem> + <para> + </para> + </listitem> +</itemizedlist> + +</section> +</section> diff --git a/nixos/lib/testing.nix b/nixos/lib/testing.nix index efcafbaa555..d990a5f8b6a 100644 --- a/nixos/lib/testing.nix +++ b/nixos/lib/testing.nix @@ -3,7 +3,11 @@ with import ./build-vms.nix { inherit system minimal config; }; with pkgs; -rec { +let + jquery-ui = callPackage ./testing/jquery-ui.nix { }; + jquery = callPackage ./testing/jquery.nix { }; + +in rec { inherit pkgs; @@ -143,8 +147,8 @@ rec { test = passMeta (runTests driver); report = passMeta (releaseTools.gcovReport { coverageRuns = [ test ]; }); - in (if makeCoverageReport then report else test) // { - inherit nodes driver test; + in (if makeCoverageReport then report else test) // { + inherit nodes driver test; }; runInMachine = diff --git a/nixos/lib/testing/jquery-ui.nix b/nixos/lib/testing/jquery-ui.nix new file mode 100644 index 00000000000..e65107a3c2f --- /dev/null +++ b/nixos/lib/testing/jquery-ui.nix @@ -0,0 +1,24 @@ +{ stdenv, fetchurl, unzip }: + +stdenv.mkDerivation rec { + name = "jquery-ui-1.11.4"; + + src = fetchurl { + url = "http://jqueryui.com/resources/download/${name}.zip"; + sha256 = "0ciyaj1acg08g8hpzqx6whayq206fvf4whksz2pjgxlv207lqgjh"; + }; + + buildInputs = [ unzip ]; + + installPhase = + '' + mkdir -p "$out/js" + cp -rv . "$out/js" + ''; + + meta = { + homepage = http://jqueryui.com/; + description = "A library of JavaScript widgets and effects"; + platforms = stdenv.lib.platforms.all; + }; +} diff --git a/nixos/lib/testing/jquery.nix b/nixos/lib/testing/jquery.nix new file mode 100644 index 00000000000..103721cadc3 --- /dev/null +++ b/nixos/lib/testing/jquery.nix @@ -0,0 +1,36 @@ +{ stdenv, fetchurl, compressed ? true }: + +with stdenv.lib; + +stdenv.mkDerivation rec { + name = "jquery-1.11.3"; + + src = if compressed then + fetchurl { + url = "http://code.jquery.com/${name}.min.js"; + sha256 = "1f4glgxxn3jnvry3dpzmazj3207baacnap5w20gr2xlk789idfgc"; + } + else + fetchurl { + url = "http://code.jquery.com/${name}.js"; + sha256 = "1v956yf5spw0156rni5z77hzqwmby7ajwdcd6mkhb6zvl36awr90"; + }; + + unpackPhase = "true"; + + installPhase = + '' + mkdir -p "$out/js" + cp -v "$src" "$out/js/jquery.js" + ${optionalString compressed '' + (cd "$out/js" && ln -s jquery.js jquery.min.js) + ''} + ''; + + meta = with stdenv.lib; { + description = "JavaScript library designed to simplify the client-side scripting of HTML"; + homepage = http://jquery.com/; + license = licenses.mit; + platforms = platforms.all; + }; +} diff --git a/nixos/modules/config/i18n.nix b/nixos/modules/config/i18n.nix index 46b22fc1285..6bf8c653e11 100644 --- a/nixos/modules/config/i18n.nix +++ b/nixos/modules/config/i18n.nix @@ -10,7 +10,7 @@ with lib; i18n = { glibcLocales = mkOption { type = types.path; - default = pkgs.glibcLocales.override { + default = pkgs.buildPackages.glibcLocales.override { allLocales = any (x: x == "all") config.i18n.supportedLocales; locales = config.i18n.supportedLocales; }; diff --git a/nixos/modules/config/no-x-libs.nix b/nixos/modules/config/no-x-libs.nix index d8980944adc..b9d5b2b903e 100644 --- a/nixos/modules/config/no-x-libs.nix +++ b/nixos/modules/config/no-x-libs.nix @@ -36,6 +36,7 @@ with lib; networkmanager-vpnc = pkgs.networkmanager-vpnc.override { withGnome = false; }; networkmanager-iodine = pkgs.networkmanager-iodine.override { withGnome = false; }; pinentry = pkgs.pinentry_ncurses; + gobjectIntrospection = pkgs.gobjectIntrospection.override { x11Support = false; }; }; }; } diff --git a/nixos/modules/config/zram.nix b/nixos/modules/config/zram.nix index ad41ad4f3d7..ae1b0a6c8e1 100644 --- a/nixos/modules/config/zram.nix +++ b/nixos/modules/config/zram.nix @@ -93,7 +93,7 @@ in serviceConfig = { Type = "oneshot"; RemainAfterExit = true; - ExecStop = "${pkgs.stdenv.shell} -c 'echo 1 > /sys/class/block/${dev}/reset'"; + ExecStop = "${pkgs.runtimeShell} -c 'echo 1 > /sys/class/block/${dev}/reset'"; }; script = '' set -u diff --git a/nixos/modules/hardware/video/amdgpu-pro.nix b/nixos/modules/hardware/video/amdgpu-pro.nix index 5cc96d8bd07..50af022b93c 100644 --- a/nixos/modules/hardware/video/amdgpu-pro.nix +++ b/nixos/modules/hardware/video/amdgpu-pro.nix @@ -15,13 +15,19 @@ let opengl = config.hardware.opengl; + kernel = pkgs.linux_4_9.override { + extraConfig = '' + KALLSYMS_ALL y + ''; + }; + in { config = mkIf enabled { - nixpkgs.config.xorg.abiCompat = "1.18"; + nixpkgs.config.xorg.abiCompat = "1.19"; services.xserver.drivers = singleton { name = "amdgpu"; modules = [ package ]; libPath = [ package ]; }; @@ -31,6 +37,9 @@ in boot.extraModulePackages = [ package ]; + boot.kernelPackages = + pkgs.recurseIntoAttrs (pkgs.linuxPackagesFor kernel); + boot.blacklistedKernelModules = [ "radeon" ]; hardware.firmware = [ package ]; @@ -38,10 +47,15 @@ in system.activationScripts.setup-amdgpu-pro = '' mkdir -p /run/lib ln -sfn ${package}/lib ${package.libCompatDir} + ln -sfn ${package} /run/amdgpu-pro '' + optionalString opengl.driSupport32Bit '' ln -sfn ${package32}/lib ${package32.libCompatDir} ''; + system.requiredKernelConfig = with config.lib.kernelConfig; [ + (isYes "KALLSYMS_ALL") + ]; + environment.etc = { "amd/amdrc".source = package + "/etc/amd/amdrc"; "amd/amdapfxx.blb".source = package + "/etc/amd/amdapfxx.blb"; diff --git a/nixos/modules/hardware/video/nvidia.nix b/nixos/modules/hardware/video/nvidia.nix index 50c085dd7ee..eafc9869315 100644 --- a/nixos/modules/hardware/video/nvidia.nix +++ b/nixos/modules/hardware/video/nvidia.nix @@ -75,10 +75,10 @@ in # Create /dev/nvidia-uvm when the nvidia-uvm module is loaded. services.udev.extraRules = '' - KERNEL=="nvidia", RUN+="${pkgs.stdenv.shell} -c 'mknod -m 666 /dev/nvidiactl c $(grep nvidia-frontend /proc/devices | cut -d \ -f 1) 255'" - KERNEL=="nvidia_modeset", RUN+="${pkgs.stdenv.shell} -c 'mknod -m 666 /dev/nvidia-modeset c $(grep nvidia-frontend /proc/devices | cut -d \ -f 1) 254'" - KERNEL=="card*", SUBSYSTEM=="drm", DRIVERS=="nvidia", RUN+="${pkgs.stdenv.shell} -c 'mknod -m 666 /dev/nvidia%n c $(grep nvidia-frontend /proc/devices | cut -d \ -f 1) %n'" - KERNEL=="nvidia_uvm", RUN+="${pkgs.stdenv.shell} -c 'mknod -m 666 /dev/nvidia-uvm c $(grep nvidia-uvm /proc/devices | cut -d \ -f 1) 0'" + KERNEL=="nvidia", RUN+="${pkgs.runtimeShell} -c 'mknod -m 666 /dev/nvidiactl c $(grep nvidia-frontend /proc/devices | cut -d \ -f 1) 255'" + KERNEL=="nvidia_modeset", RUN+="${pkgs.runtimeShell} -c 'mknod -m 666 /dev/nvidia-modeset c $(grep nvidia-frontend /proc/devices | cut -d \ -f 1) 254'" + KERNEL=="card*", SUBSYSTEM=="drm", DRIVERS=="nvidia", RUN+="${pkgs.runtimeShell} -c 'mknod -m 666 /dev/nvidia%n c $(grep nvidia-frontend /proc/devices | cut -d \ -f 1) %n'" + KERNEL=="nvidia_uvm", RUN+="${pkgs.runtimeShell} -c 'mknod -m 666 /dev/nvidia-uvm c $(grep nvidia-uvm /proc/devices | cut -d \ -f 1) 0'" ''; boot.blacklistedKernelModules = [ "nouveau" "nvidiafb" ]; diff --git a/nixos/modules/installer/tools/nixos-rebuild.sh b/nixos/modules/installer/tools/nixos-rebuild.sh index 9ede74a54cd..2af73519bc5 100644 --- a/nixos/modules/installer/tools/nixos-rebuild.sh +++ b/nixos/modules/installer/tools/nixos-rebuild.sh @@ -382,6 +382,6 @@ fi if [ "$action" = build-vm ]; then cat >&2 <<EOF -Done. The virtual machine can be started by running $(echo $pathToConfig/bin/run-*-vm). +Done. The virtual machine can be started by running $(echo $pathToConfig/bin/run-*-vm) EOF fi diff --git a/nixos/modules/installer/virtualbox-demo.nix b/nixos/modules/installer/virtualbox-demo.nix index 5316cfce906..13a0d7f4f6e 100644 --- a/nixos/modules/installer/virtualbox-demo.nix +++ b/nixos/modules/installer/virtualbox-demo.nix @@ -19,4 +19,6 @@ with lib; # Add some more video drivers to give X11 a shot at working in # VMware and QEMU. services.xserver.videoDrivers = mkOverride 40 [ "virtualbox" "vmware" "cirrus" "vesa" "modesetting" ]; + + powerManagement.enable = false; } diff --git a/nixos/modules/misc/nixpkgs.nix b/nixos/modules/misc/nixpkgs.nix index 11bd148d5de..9217250eec2 100644 --- a/nixos/modules/misc/nixpkgs.nix +++ b/nixos/modules/misc/nixpkgs.nix @@ -61,7 +61,7 @@ in inherit (config.nixpkgs) config overlays system; } ''; - default = import ../../.. { inherit (cfg) config overlays system; }; + default = import ../../.. { inherit (cfg) config overlays system crossSystem; }; type = pkgsType; example = literalExample ''import <nixpkgs> {}''; description = '' @@ -130,6 +130,18 @@ in ''; }; + crossSystem = mkOption { + type = types.nullOr types.attrs; + default = null; + description = '' + The description of the system we're cross-compiling to, or null + if this isn't a cross-compile. See the description of the + crossSystem argument in the nixpkgs manual. + + Ignored when <code>nixpkgs.pkgs</code> is set. + ''; + }; + system = mkOption { type = types.str; example = "i686-linux"; diff --git a/nixos/modules/misc/version.nix b/nixos/modules/misc/version.nix index 6af584250a7..b8f0a223c91 100644 --- a/nixos/modules/misc/version.nix +++ b/nixos/modules/misc/version.nix @@ -85,8 +85,8 @@ in revision = mkIf (pathIsDirectory gitRepo) (mkDefault gitCommitId); versionSuffix = mkIf (pathIsDirectory gitRepo) (mkDefault (".git." + gitCommitId)); - # Note: code names must only increase in alphabetical order. - codeName = "Impala"; + # Note: the first letter is bumped on every release. It's an animal. + codeName = "Jellyfish"; }; # Generate /etc/os-release. See diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index e7f28c670be..e0c0ec2711b 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -104,6 +104,7 @@ ./programs/shadow.nix ./programs/shell.nix ./programs/spacefm.nix + ./programs/singularity.nix ./programs/ssh.nix ./programs/ssmtp.nix ./programs/sysdig.nix @@ -159,6 +160,7 @@ ./services/audio/ympd.nix ./services/backup/almir.nix ./services/backup/bacula.nix + ./services/backup/borgbackup.nix ./services/backup/crashplan.nix ./services/backup/crashplan-small-business.nix ./services/backup/mysql-backup.nix diff --git a/nixos/modules/profiles/demo.nix b/nixos/modules/profiles/demo.nix index ef6fd77b5f8..c3ee6e98371 100644 --- a/nixos/modules/profiles/demo.nix +++ b/nixos/modules/profiles/demo.nix @@ -10,4 +10,10 @@ password = "demo"; uid = 1000; }; + + services.xserver.displayManager.sddm.autoLogin = { + enable = true; + relogin = true; + user = "demo"; + }; } diff --git a/nixos/modules/programs/bash/bash.nix b/nixos/modules/programs/bash/bash.nix index 1a62f04972d..c0967316c0c 100644 --- a/nixos/modules/programs/bash/bash.nix +++ b/nixos/modules/programs/bash/bash.nix @@ -126,7 +126,7 @@ in programs.bash = { shellInit = '' - . ${config.system.build.setEnvironment} + ${config.system.build.setEnvironment.text} ${cfge.shellInit} ''; diff --git a/nixos/modules/programs/rootston.nix b/nixos/modules/programs/rootston.nix index 1946b1db657..842d9e6cfb4 100644 --- a/nixos/modules/programs/rootston.nix +++ b/nixos/modules/programs/rootston.nix @@ -6,7 +6,7 @@ let cfg = config.programs.rootston; rootstonWrapped = pkgs.writeScriptBin "rootston" '' - #! ${pkgs.stdenv.shell} + #! ${pkgs.runtimeShell} if [[ "$#" -ge 1 ]]; then exec ${pkgs.rootston}/bin/rootston "$@" else diff --git a/nixos/modules/programs/singularity.nix b/nixos/modules/programs/singularity.nix new file mode 100644 index 00000000000..86153d93385 --- /dev/null +++ b/nixos/modules/programs/singularity.nix @@ -0,0 +1,20 @@ +{ config, pkgs, lib, ... }: + +with lib; +let + cfg = config.programs.singularity; +in { + options.programs.singularity = { + enable = mkEnableOption "Singularity"; + }; + + config = mkIf cfg.enable { + environment.systemPackages = [ pkgs.singularity ]; + systemd.tmpfiles.rules = [ "d /var/singularity/mnt/session 0770 root root -" + "d /var/singularity/mnt/final 0770 root root -" + "d /var/singularity/mnt/overlay 0770 root root -" + "d /var/singularity/mnt/container 0770 root root -" + "d /var/singularity/mnt/source 0770 root root -"]; + }; + +} diff --git a/nixos/modules/programs/ssh.nix b/nixos/modules/programs/ssh.nix index 0935bf0cae7..36289080a82 100644 --- a/nixos/modules/programs/ssh.nix +++ b/nixos/modules/programs/ssh.nix @@ -13,7 +13,7 @@ let askPasswordWrapper = pkgs.writeScript "ssh-askpass-wrapper" '' - #! ${pkgs.stdenv.shell} -e + #! ${pkgs.runtimeShell} -e export DISPLAY="$(systemctl --user show-environment | ${pkgs.gnused}/bin/sed 's/^DISPLAY=\(.*\)/\1/; t; d')" exec ${askPassword} ''; diff --git a/nixos/modules/programs/zsh/zsh.nix b/nixos/modules/programs/zsh/zsh.nix index 5102bfef032..f689250dc61 100644 --- a/nixos/modules/programs/zsh/zsh.nix +++ b/nixos/modules/programs/zsh/zsh.nix @@ -108,7 +108,7 @@ in if [ -n "$__ETC_ZSHENV_SOURCED" ]; then return; fi export __ETC_ZSHENV_SOURCED=1 - . ${config.system.build.setEnvironment} + ${config.system.build.setEnvironment.text} ${cfge.shellInit} diff --git a/nixos/modules/security/audit.nix b/nixos/modules/security/audit.nix index 7ac21fd9650..2b22bdd9f0a 100644 --- a/nixos/modules/security/audit.nix +++ b/nixos/modules/security/audit.nix @@ -13,7 +13,7 @@ let }; disableScript = pkgs.writeScript "audit-disable" '' - #!${pkgs.stdenv.shell} -eu + #!${pkgs.runtimeShell} -eu # Explicitly disable everything, as otherwise journald might start it. auditctl -D auditctl -e 0 -a task,never @@ -23,7 +23,7 @@ let # put in the store like this. At the same time, it doesn't feel like a huge deal and working # around that is a pain so I'm leaving it like this for now. startScript = pkgs.writeScript "audit-start" '' - #!${pkgs.stdenv.shell} -eu + #!${pkgs.runtimeShell} -eu # Clear out any rules we may start with auditctl -D @@ -43,7 +43,7 @@ let ''; stopScript = pkgs.writeScript "audit-stop" '' - #!${pkgs.stdenv.shell} -eu + #!${pkgs.runtimeShell} -eu # Clear the rules auditctl -D diff --git a/nixos/modules/security/sudo.nix b/nixos/modules/security/sudo.nix index a57f14bb5ae..24283e1d616 100644 --- a/nixos/modules/security/sudo.nix +++ b/nixos/modules/security/sudo.nix @@ -47,8 +47,8 @@ in default = true; description = '' - Whether users of the <code>wheel</code> group can execute - commands as super user without entering a password. + Whether users of the <code>wheel</code> group must + provide a password to run commands as super user via <command>sudo</command>. ''; }; @@ -215,7 +215,7 @@ in { src = pkgs.writeText "sudoers-in" cfg.configFile; } # Make sure that the sudoers file is syntactically valid. # (currently disabled - NIXOS-66) - "${pkgs.sudo}/sbin/visudo -f $src -c && cp $src $out"; + "${pkgs.buildPackages.sudo}/sbin/visudo -f $src -c && cp $src $out"; target = "sudoers"; mode = "0440"; }; diff --git a/nixos/modules/services/backup/borgbackup.nix b/nixos/modules/services/backup/borgbackup.nix new file mode 100644 index 00000000000..1b730e0c2b7 --- /dev/null +++ b/nixos/modules/services/backup/borgbackup.nix @@ -0,0 +1,580 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + + isLocalPath = x: + builtins.substring 0 1 x == "/" # absolute path + || builtins.substring 0 1 x == "." # relative path + || builtins.match "[.*:.*]" == null; # not machine:path + + mkExcludeFile = cfg: + # Write each exclude pattern to a new line + pkgs.writeText "excludefile" (concatStringsSep "\n" cfg.exclude); + + mkKeepArgs = cfg: + # If cfg.prune.keep e.g. has a yearly attribute, + # its content is passed on as --keep-yearly + concatStringsSep " " + (mapAttrsToList (x: y: "--keep-${x}=${toString y}") cfg.prune.keep); + + mkBackupScript = cfg: '' + on_exit() + { + exitStatus=$? + # Reset the EXIT handler, or else we're called again on 'exit' below + trap - EXIT + ${cfg.postHook} + exit $exitStatus + } + trap 'on_exit' INT TERM QUIT EXIT + + archiveName="${cfg.archiveBaseName}-$(date ${cfg.dateFormat})" + archiveSuffix="${optionalString cfg.appendFailedSuffix ".failed"}" + ${cfg.preHook} + '' + optionalString cfg.doInit '' + # Run borg init if the repo doesn't exist yet + if ! borg list > /dev/null; then + borg init \ + --encryption ${cfg.encryption.mode} \ + $extraInitArgs + ${cfg.postInit} + fi + '' + '' + borg create \ + --compression ${cfg.compression} \ + --exclude-from ${mkExcludeFile cfg} \ + $extraCreateArgs \ + "::$archiveName$archiveSuffix" \ + ${escapeShellArgs cfg.paths} + '' + optionalString cfg.appendFailedSuffix '' + borg rename "::$archiveName$archiveSuffix" "$archiveName" + '' + '' + ${cfg.postCreate} + '' + optionalString (cfg.prune.keep != { }) '' + borg prune \ + ${mkKeepArgs cfg} \ + --prefix ${escapeShellArg cfg.prune.prefix} \ + $extraPruneArgs + ${cfg.postPrune} + ''; + + mkPassEnv = cfg: with cfg.encryption; + if passCommand != null then + { BORG_PASSCOMMAND = passCommand; } + else if passphrase != null then + { BORG_PASSPHRASE = passphrase; } + else { }; + + mkBackupService = name: cfg: + let + userHome = config.users.users.${cfg.user}.home; + in nameValuePair "borgbackup-job-${name}" { + description = "BorgBackup job ${name}"; + path = with pkgs; [ + borgbackup openssh + ]; + script = mkBackupScript cfg; + serviceConfig = { + User = cfg.user; + Group = cfg.group; + # Only run when no other process is using CPU or disk + CPUSchedulingPolicy = "idle"; + IOSchedulingClass = "idle"; + ProtectSystem = "strict"; + ReadWritePaths = + [ "${userHome}/.config/borg" "${userHome}/.cache/borg" ] + # Borg needs write access to repo if it is not remote + ++ optional (isLocalPath cfg.repo) cfg.repo; + PrivateTmp = true; + }; + environment = { + BORG_REPO = cfg.repo; + inherit (cfg) extraInitArgs extraCreateArgs extraPruneArgs; + } // (mkPassEnv cfg) // cfg.environment; + inherit (cfg) startAt; + }; + + # Paths listed in ReadWritePaths must exist before service is started + mkActivationScript = name: cfg: + let + install = "install -o ${cfg.user} -g ${cfg.group}"; + in + nameValuePair "borgbackup-job-${name}" (stringAfter [ "users" ] ('' + # Eensure that the home directory already exists + # We can't assert createHome == true because that's not the case for root + cd "${config.users.users.${cfg.user}.home}" + ${install} -d .config/borg + ${install} -d .cache/borg + '' + optionalString (isLocalPath cfg.repo) '' + ${install} -d ${escapeShellArg cfg.repo} + '')); + + mkPassAssertion = name: cfg: { + assertion = with cfg.encryption; + mode != "none" -> passCommand != null || passphrase != null; + message = + "passCommand or passphrase has to be specified because" + + '' borgbackup.jobs.${name}.encryption != "none"''; + }; + + mkRepoService = name: cfg: + nameValuePair "borgbackup-repo-${name}" { + description = "Create BorgBackup repository ${name} directory"; + script = '' + mkdir -p ${escapeShellArg cfg.path} + chown ${cfg.user}:${cfg.group} ${escapeShellArg cfg.path} + ''; + serviceConfig = { + # The service's only task is to ensure that the specified path exists + Type = "oneshot"; + }; + wantedBy = [ "multi-user.target" ]; + }; + + mkAuthorizedKey = cfg: appendOnly: key: + let + # Because of the following line, clients do not need to specify an absolute repo path + cdCommand = "cd ${escapeShellArg cfg.path}"; + restrictedArg = "--restrict-to-${if cfg.allowSubRepos then "path" else "repository"} ."; + appendOnlyArg = optionalString appendOnly "--append-only"; + quotaArg = optionalString (cfg.quota != null) "--storage-quota ${cfg.quota}"; + serveCommand = "borg serve ${restrictedArg} ${appendOnlyArg} ${quotaArg}"; + in + ''command="${cdCommand} && ${serveCommand}",restrict ${key}''; + + mkUsersConfig = name: cfg: { + users.${cfg.user} = { + openssh.authorizedKeys.keys = + (map (mkAuthorizedKey cfg false) cfg.authorizedKeys + ++ map (mkAuthorizedKey cfg true) cfg.authorizedKeysAppendOnly); + useDefaultShell = true; + }; + groups.${cfg.group} = { }; + }; + + mkKeysAssertion = name: cfg: { + assertion = cfg.authorizedKeys != [ ] || cfg.authorizedKeysAppendOnly != [ ]; + message = + "borgbackup.repos.${name} does not make sense" + + " without at least one public key"; + }; + +in { + meta.maintainers = with maintainers; [ dotlambda ]; + + ###### interface + + options.services.borgbackup.jobs = mkOption { + description = "Deduplicating backups using BorgBackup."; + default = { }; + example = literalExample '' + { + rootBackup = { + paths = "/"; + exclude = [ "/nix" ]; + repo = "/path/to/local/repo"; + encryption = { + mode = "repokey"; + passphrase = "secret"; + }; + compression = "auto,lzma"; + startAt = "weekly"; + }; + } + ''; + type = types.attrsOf (types.submodule (let globalConfig = config; in + { name, config, ... }: { + options = { + + paths = mkOption { + type = with types; either path (nonEmptyListOf path); + description = "Path(s) to back up."; + example = "/home/user"; + apply = x: if isList x then x else [ x ]; + }; + + repo = mkOption { + type = types.str; + description = "Remote or local repository to back up to."; + example = "user@machine:/path/to/repo"; + }; + + archiveBaseName = mkOption { + type = types.strMatching "[^/{}]+"; + default = "${globalConfig.networking.hostName}-${name}"; + defaultText = "\${config.networking.hostName}-<name>"; + description = '' + How to name the created archives. A timestamp, whose format is + determined by <option>dateFormat</option>, will be appended. The full + name can be modified at runtime (<literal>$archiveName</literal>). + Placeholders like <literal>{hostname}</literal> must not be used. + ''; + }; + + dateFormat = mkOption { + type = types.str; + description = '' + Arguments passed to <command>date</command> + to create a timestamp suffix for the archive name. + ''; + default = "+%Y-%m-%dT%H:%M:%S"; + example = "-u +%s"; + }; + + startAt = mkOption { + type = with types; either str (listOf str); + default = "daily"; + description = '' + When or how often the backup should run. + Must be in the format described in + <citerefentry><refentrytitle>systemd.time</refentrytitle> + <manvolnum>7</manvolnum></citerefentry>. + If you do not want the backup to start + automatically, use <literal>[ ]</literal>. + ''; + }; + + user = mkOption { + type = types.str; + description = '' + The user <command>borg</command> is run as. + User or group need read permission + for the specified <option>paths</option>. + ''; + default = "root"; + }; + + group = mkOption { + type = types.str; + description = '' + The group borg is run as. User or group needs read permission + for the specified <option>paths</option>. + ''; + default = "root"; + }; + + encryption.mode = mkOption { + type = types.enum [ + "repokey" "keyfile" + "repokey-blake2" "keyfile-blake2" + "authenticated" "authenticated-blake2" + "none" + ]; + description = '' + Encryption mode to use. Setting a mode + other than <literal>"none"</literal> requires + you to specify a <option>passCommand</option> + or a <option>passphrase</option>. + ''; + }; + + encryption.passCommand = mkOption { + type = with types; nullOr str; + description = '' + A command which prints the passphrase to stdout. + Mutually exclusive with <option>passphrase</option>. + ''; + default = null; + example = "cat /path/to/passphrase_file"; + }; + + encryption.passphrase = mkOption { + type = with types; nullOr str; + description = '' + The passphrase the backups are encrypted with. + Mutually exclusive with <option>passCommand</option>. + If you do not want the passphrase to be stored in the + world-readable Nix store, use <option>passCommand</option>. + ''; + default = null; + }; + + compression = mkOption { + # "auto" is optional, + # compression mode must be given, + # compression level is optional + type = types.strMatching "none|(auto,)?(lz4|zstd|zlib|lzma)(,[[:digit:]]{1,2})?"; + description = '' + Compression method to use. Refer to + <command>borg help compression</command> + for all available options. + ''; + default = "lz4"; + example = "auto,lzma"; + }; + + exclude = mkOption { + type = with types; listOf str; + description = '' + Exclude paths matching any of the given patterns. See + <command>borg help patterns</command> for pattern syntax. + ''; + default = [ ]; + example = [ + "/home/*/.cache" + "/nix" + ]; + }; + + doInit = mkOption { + type = types.bool; + description = '' + Run <command>borg init</command> if the + specified <option>repo</option> does not exist. + You should set this to <literal>false</literal> + if the repository is located on an external drive + that might not always be mounted. + ''; + default = true; + }; + + appendFailedSuffix = mkOption { + type = types.bool; + description = '' + Append a <literal>.failed</literal> suffix + to the archive name, which is only removed if + <command>borg create</command> has a zero exit status. + ''; + default = true; + }; + + prune.keep = mkOption { + # Specifying e.g. `prune.keep.yearly = -1` + # means there is no limit of yearly archives to keep + # The regex is for use with e.g. --keep-within 1y + type = with types; attrsOf (either int (strMatching "[[:digit:]]+[Hdwmy]")); + description = '' + Prune a repository by deleting all archives not matching any of the + specified retention options. See <command>borg help prune</command> + for the available options. + ''; + default = { }; + example = literalExample '' + { + within = "1d"; # Keep all archives from the last day + daily = 7; + weekly = 4; + monthly = -1; # Keep at least one archive for each month + } + ''; + }; + + prune.prefix = mkOption { + type = types.str; + description = '' + Only consider archive names starting with this prefix for pruning. + By default, only archives created by this job are considered. + Use <literal>""</literal> to consider all archives. + ''; + default = config.archiveBaseName; + defaultText = "\${archiveBaseName}"; + }; + + environment = mkOption { + type = with types; attrsOf str; + description = '' + Environment variables passed to the backup script. + You can for example specify which SSH key to use. + ''; + default = { }; + example = { BORG_RSH = "ssh -i /path/to/key"; }; + }; + + preHook = mkOption { + type = types.lines; + description = '' + Shell commands to run before the backup. + This can for example be used to mount file systems. + ''; + default = ""; + example = '' + # To add excluded paths at runtime + extraCreateArgs="$extraCreateArgs --exclude /some/path" + ''; + }; + + postInit = mkOption { + type = types.lines; + description = '' + Shell commands to run after <command>borg init</command>. + ''; + default = ""; + }; + + postCreate = mkOption { + type = types.lines; + description = '' + Shell commands to run after <command>borg create</command>. The name + of the created archive is stored in <literal>$archiveName</literal>. + ''; + default = ""; + }; + + postPrune = mkOption { + type = types.lines; + description = '' + Shell commands to run after <command>borg prune</command>. + ''; + default = ""; + }; + + postHook = mkOption { + type = types.lines; + description = '' + Shell commands to run just before exit. They are executed + even if a previous command exits with a non-zero exit code. + The latter is available as <literal>$exitStatus</literal>. + ''; + default = ""; + }; + + extraInitArgs = mkOption { + type = types.str; + description = '' + Additional arguments for <command>borg init</command>. + Can also be set at runtime using <literal>$extraInitArgs</literal>. + ''; + default = ""; + example = "--append-only"; + }; + + extraCreateArgs = mkOption { + type = types.str; + description = '' + Additional arguments for <command>borg create</command>. + Can also be set at runtime using <literal>$extraCreateArgs</literal>. + ''; + default = ""; + example = "--stats --checkpoint-interval 600"; + }; + + extraPruneArgs = mkOption { + type = types.str; + description = '' + Additional arguments for <command>borg prune</command>. + Can also be set at runtime using <literal>$extraPruneArgs</literal>. + ''; + default = ""; + example = "--save-space"; + }; + + }; + } + )); + }; + + options.services.borgbackup.repos = mkOption { + description = '' + Serve BorgBackup repositories to given public SSH keys, + restricting their access to the repository only. + Also, clients do not need to specify the absolute path when accessing the repository, + i.e. <literal>user@machine:.</literal> is enough. (Note colon and dot.) + ''; + default = { }; + type = types.attrsOf (types.submodule ( + { name, config, ... }: { + options = { + + path = mkOption { + type = types.path; + description = '' + Where to store the backups. Note that the directory + is created automatically, with correct permissions. + ''; + default = "/var/lib/borgbackup"; + }; + + user = mkOption { + type = types.str; + description = '' + The user <command>borg serve</command> is run as. + User or group needs write permission + for the specified <option>path</option>. + ''; + default = "borg"; + }; + + group = mkOption { + type = types.str; + description = '' + The group <command>borg serve</command> is run as. + User or group needs write permission + for the specified <option>path</option>. + ''; + default = "borg"; + }; + + authorizedKeys = mkOption { + type = with types; listOf str; + description = '' + Public SSH keys that are given full write access to this repository. + You should use a different SSH key for each repository you write to, because + the specified keys are restricted to running <command>borg serve</command> + and can only access this single repository. + ''; + default = [ ]; + }; + + authorizedKeysAppendOnly = mkOption { + type = with types; listOf str; + description = '' + Public SSH keys that can only be used to append new data (archives) to the repository. + Note that archives can still be marked as deleted and are subsequently removed from disk + upon accessing the repo with full write access, e.g. when pruning. + ''; + default = [ ]; + }; + + allowSubRepos = mkOption { + type = types.bool; + description = '' + Allow clients to create repositories in subdirectories of the + specified <option>path</option>. These can be accessed using + <literal>user@machine:path/to/subrepo</literal>. Note that a + <option>quota</option> applies to repositories independently. + Therefore, if this is enabled, clients can create multiple + repositories and upload an arbitrary amount of data. + ''; + default = false; + }; + + quota = mkOption { + # See the definition of parse_file_size() in src/borg/helpers/parseformat.py + type = with types; nullOr (strMatching "[[:digit:].]+[KMGTP]?"); + description = '' + Storage quota for the repository. This quota is ensured for all + sub-repositories if <option>allowSubRepos</option> is enabled + but not for the overall storage space used. + ''; + default = null; + example = "100G"; + }; + + }; + } + )); + }; + + ###### implementation + + config = mkIf (with config.services.borgbackup; jobs != { } || repos != { }) + (with config.services.borgbackup; { + assertions = + mapAttrsToList mkPassAssertion jobs + ++ mapAttrsToList mkKeysAssertion repos; + + system.activationScripts = mapAttrs' mkActivationScript jobs; + + systemd.services = + # A job named "foo" is mapped to systemd.services.borgbackup-job-foo + mapAttrs' mkBackupService jobs + # A repo named "foo" is mapped to systemd.services.borgbackup-repo-foo + // mapAttrs' mkRepoService repos; + + users = mkMerge (mapAttrsToList mkUsersConfig repos); + + environment.systemPackages = with pkgs; [ borgbackup ]; + }); +} diff --git a/nixos/modules/services/continuous-integration/buildkite-agent.nix b/nixos/modules/services/continuous-integration/buildkite-agent.nix index 0a0c9f665d2..03af9a7859e 100644 --- a/nixos/modules/services/continuous-integration/buildkite-agent.nix +++ b/nixos/modules/services/continuous-integration/buildkite-agent.nix @@ -18,7 +18,7 @@ let hooksDir = let mkHookEntry = name: value: '' cat > $out/${name} <<EOF - #! ${pkgs.stdenv.shell} + #! ${pkgs.runtimeShell} set -e ${value} EOF diff --git a/nixos/modules/services/continuous-integration/jenkins/default.nix b/nixos/modules/services/continuous-integration/jenkins/default.nix index 54047a50caa..c2f4e9c0c5a 100644 --- a/nixos/modules/services/continuous-integration/jenkins/default.nix +++ b/nixos/modules/services/continuous-integration/jenkins/default.nix @@ -145,6 +145,11 @@ in { }; config = mkIf cfg.enable { + # server references the dejavu fonts + environment.systemPackages = [ + pkgs.dejavu_fonts + ]; + users.extraGroups = optional (cfg.group == "jenkins") { name = "jenkins"; gid = config.ids.gids.jenkins; @@ -200,10 +205,12 @@ in { ${replacePlugins} ''; + # For reference: https://wiki.jenkins.io/display/JENKINS/JenkinsLinuxStartupScript script = '' ${pkgs.jdk}/bin/java ${concatStringsSep " " cfg.extraJavaOptions} -jar ${cfg.package}/webapps/jenkins.war --httpListenAddress=${cfg.listenAddress} \ --httpPort=${toString cfg.port} \ --prefix=${cfg.prefix} \ + -Djava.awt.headless=true \ ${concatStringsSep " " cfg.extraOptions} ''; diff --git a/nixos/modules/services/databases/4store-endpoint.nix b/nixos/modules/services/databases/4store-endpoint.nix index 906cb320df9..d528355671f 100644 --- a/nixos/modules/services/databases/4store-endpoint.nix +++ b/nixos/modules/services/databases/4store-endpoint.nix @@ -2,7 +2,7 @@ let cfg = config.services.fourStoreEndpoint; endpointUser = "fourstorehttp"; - run = "${pkgs.su}/bin/su -s ${pkgs.stdenv.shell} ${endpointUser} -c"; + run = "${pkgs.su}/bin/su -s ${pkgs.runtimeShell} ${endpointUser} -c"; in with lib; { diff --git a/nixos/modules/services/databases/4store.nix b/nixos/modules/services/databases/4store.nix index 62856822f90..abb62e1f263 100644 --- a/nixos/modules/services/databases/4store.nix +++ b/nixos/modules/services/databases/4store.nix @@ -3,7 +3,7 @@ let cfg = config.services.fourStore; stateDir = "/var/lib/4store"; fourStoreUser = "fourstore"; - run = "${pkgs.su}/bin/su -s ${pkgs.stdenv.shell} ${fourStoreUser}"; + run = "${pkgs.su}/bin/su -s ${pkgs.runtimeShell} ${fourStoreUser}"; in with lib; { diff --git a/nixos/modules/services/editors/emacs.nix b/nixos/modules/services/editors/emacs.nix index 2c5a0c4849e..bbc9bcf3dae 100644 --- a/nixos/modules/services/editors/emacs.nix +++ b/nixos/modules/services/editors/emacs.nix @@ -7,7 +7,7 @@ let cfg = config.services.emacs; editorScript = pkgs.writeScriptBin "emacseditor" '' - #!${pkgs.stdenv.shell} + #!${pkgs.runtimeShell} if [ -z "$1" ]; then exec ${cfg.package}/bin/emacsclient --create-frame --alternate-editor ${cfg.package}/bin/emacs else diff --git a/nixos/modules/services/hardware/udev.nix b/nixos/modules/services/hardware/udev.nix index 9f42f9e59ad..7bfc3bb6487 100644 --- a/nixos/modules/services/hardware/udev.nix +++ b/nixos/modules/services/hardware/udev.nix @@ -146,7 +146,7 @@ let echo "Generating hwdb database..." # hwdb --update doesn't return error code even on errors! - res="$(${udev}/bin/udevadm hwdb --update --root=$(pwd) 2>&1)" + res="$(${pkgs.buildPackages.udev}/bin/udevadm hwdb --update --root=$(pwd) 2>&1)" echo "$res" [ -z "$(echo "$res" | egrep '^Error')" ] mv etc/udev/hwdb.bin $out diff --git a/nixos/modules/services/misc/folding-at-home.nix b/nixos/modules/services/misc/folding-at-home.nix index 053e7e95635..164221cbab7 100644 --- a/nixos/modules/services/misc/folding-at-home.nix +++ b/nixos/modules/services/misc/folding-at-home.nix @@ -57,7 +57,7 @@ in { chown ${fahUser} ${stateDir} cp -f ${pkgs.writeText "client.cfg" cfg.config} ${stateDir}/client.cfg ''; - script = "${pkgs.su}/bin/su -s ${pkgs.stdenv.shell} ${fahUser} -c 'cd ${stateDir}; ${pkgs.foldingathome}/bin/fah6'"; + script = "${pkgs.su}/bin/su -s ${pkgs.runtimeShell} ${fahUser} -c 'cd ${stateDir}; ${pkgs.foldingathome}/bin/fah6'"; }; services.foldingAtHome.config = '' diff --git a/nixos/modules/services/misc/geoip-updater.nix b/nixos/modules/services/misc/geoip-updater.nix index 760fa66e80d..e0b9df96f8e 100644 --- a/nixos/modules/services/misc/geoip-updater.nix +++ b/nixos/modules/services/misc/geoip-updater.nix @@ -14,7 +14,7 @@ let # ExecStart= command with '@' doesn't work because we start a shell (new # process) that creates a new argv[0].) geoip-updater = pkgs.writeScriptBin "geoip-updater" '' - #!${pkgs.stdenv.shell} + #!${pkgs.runtimeShell} skipExisting=0 debug() { diff --git a/nixos/modules/services/misc/gitea.nix b/nixos/modules/services/misc/gitea.nix index f0b44b7bede..63e976ae566 100644 --- a/nixos/modules/services/misc/gitea.nix +++ b/nixos/modules/services/misc/gitea.nix @@ -4,6 +4,8 @@ with lib; let cfg = config.services.gitea; + pg = config.services.postgresql; + usePostgresql = cfg.database.type == "postgres"; configFile = pkgs.writeText "app.ini" '' APP_NAME = ${cfg.appName} RUN_USER = ${cfg.user} @@ -16,6 +18,9 @@ let USER = ${cfg.database.user} PASSWD = #dbpass# PATH = ${cfg.database.path} + ${optionalString usePostgresql '' + SSL_MODE = disable + ''} [repository] ROOT = ${cfg.repositoryRoot} @@ -35,6 +40,10 @@ let SECRET_KEY = #secretkey# INSTALL_LOCK = true + [log] + ROOT_PATH = ${cfg.log.rootPath} + LEVEL = ${cfg.log.level} + ${cfg.extraConfig} ''; in @@ -60,6 +69,19 @@ in description = "gitea data directory."; }; + log = { + rootPath = mkOption { + default = "${cfg.stateDir}/log"; + type = types.str; + description = "Root path for log files."; + }; + level = mkOption { + default = "Trace"; + type = types.enum [ "Trace" "Debug" "Info" "Warn" "Error" "Critical" ]; + description = "General log level."; + }; + }; + user = mkOption { type = types.str; default = "gitea"; @@ -82,7 +104,7 @@ in port = mkOption { type = types.int; - default = 3306; + default = (if !usePostgresql then 3306 else pg.port); description = "Database host port."; }; @@ -123,6 +145,15 @@ in default = "${cfg.stateDir}/data/gitea.db"; description = "Path to the sqlite3 database file."; }; + + createDatabase = mkOption { + type = types.bool; + default = true; + description = '' + Whether to create a local postgresql database automatically. + This only applies if database type "postgres" is selected. + ''; + }; }; appName = mkOption { @@ -186,10 +217,11 @@ in }; config = mkIf cfg.enable { + services.postgresql.enable = mkIf usePostgresql (mkDefault true); systemd.services.gitea = { description = "gitea"; - after = [ "network.target" ]; + after = [ "network.target" "postgresql.service" ]; wantedBy = [ "multi-user.target" ]; path = [ pkgs.gitea.bin ]; @@ -231,12 +263,31 @@ in mkdir -p ${cfg.stateDir}/conf cp -r ${pkgs.gitea.out}/locale ${cfg.stateDir}/conf/locale fi + '' + optionalString (usePostgresql && cfg.database.createDatabase) '' + if ! test -e "${cfg.stateDir}/db-created"; then + echo "CREATE ROLE ${cfg.database.user} + WITH ENCRYPTED PASSWORD '$(head -n1 ${cfg.database.passwordFile})' + NOCREATEDB NOCREATEROLE LOGIN" | + ${pkgs.sudo}/bin/sudo -u ${pg.superUser} ${pg.package}/bin/psql + ${pkgs.sudo}/bin/sudo -u ${pg.superUser} \ + ${pg.package}/bin/createdb \ + --owner=${cfg.database.user} \ + --encoding=UTF8 \ + --lc-collate=C \ + --lc-ctype=C \ + --template=template0 \ + ${cfg.database.name} + touch "${cfg.stateDir}/db-created" + fi + '' + '' + chown ${cfg.user} -R ${cfg.stateDir} ''; serviceConfig = { Type = "simple"; User = cfg.user; WorkingDirectory = cfg.stateDir; + PermissionsStartOnly = true; ExecStart = "${pkgs.gitea.bin}/bin/gitea web"; Restart = "always"; }; @@ -253,6 +304,7 @@ in description = "Gitea Service"; home = cfg.stateDir; createHome = true; + useDefaultShell = true; }; }; diff --git a/nixos/modules/services/misc/gitit.nix b/nixos/modules/services/misc/gitit.nix index 44880ebeda1..94a98e0335d 100644 --- a/nixos/modules/services/misc/gitit.nix +++ b/nixos/modules/services/misc/gitit.nix @@ -17,7 +17,7 @@ let gititSh = hsPkgs: extras: with pkgs; let env = gititWithPkgs hsPkgs extras; in writeScript "gitit" '' - #!${stdenv.shell} + #!${runtimeShell} cd $HOME export NIX_GHC="${env}/bin/ghc" export NIX_GHCPKG="${env}/bin/ghc-pkg" diff --git a/nixos/modules/services/misc/home-assistant.nix b/nixos/modules/services/misc/home-assistant.nix index cc60a143fa6..ac37c11106e 100644 --- a/nixos/modules/services/misc/home-assistant.nix +++ b/nixos/modules/services/misc/home-assistant.nix @@ -104,7 +104,6 @@ in { config = mkIf cfg.enable { systemd.services.home-assistant = { description = "Home Assistant"; - wantedBy = [ "multi-user.target" ]; after = [ "network.target" ]; preStart = lib.optionalString (cfg.config != null) '' rm -f ${cfg.configDir}/configuration.yaml @@ -121,6 +120,16 @@ in { ReadWritePaths = "${cfg.configDir}"; PrivateTmp = true; }; + path = [ + "/run/wrappers" # needed for ping + ]; + }; + + systemd.targets.home-assistant = rec { + description = "Home Assistant"; + wantedBy = [ "multi-user.target" ]; + wants = [ "home-assistant.service" ]; + after = wants; }; users.extraUsers.hass = { diff --git a/nixos/modules/services/misc/ihaskell.nix b/nixos/modules/services/misc/ihaskell.nix index e07a4a44613..6da9cc8c47e 100644 --- a/nixos/modules/services/misc/ihaskell.nix +++ b/nixos/modules/services/misc/ihaskell.nix @@ -55,7 +55,7 @@ in serviceConfig = { User = config.users.extraUsers.ihaskell.name; Group = config.users.extraGroups.ihaskell.name; - ExecStart = "${pkgs.stdenv.shell} -c \"cd $HOME;${ihaskell}/bin/ihaskell-notebook\""; + ExecStart = "${pkgs.runtimeShell} -c \"cd $HOME;${ihaskell}/bin/ihaskell-notebook\""; }; }; }; diff --git a/nixos/modules/services/misc/mesos-slave.nix b/nixos/modules/services/misc/mesos-slave.nix index 47be10274d3..12485141e21 100644 --- a/nixos/modules/services/misc/mesos-slave.nix +++ b/nixos/modules/services/misc/mesos-slave.nix @@ -188,7 +188,7 @@ in { description = "Mesos Slave"; wantedBy = [ "multi-user.target" ]; after = [ "network.target" ]; - path = [ pkgs.stdenv.shellPackage ]; + path = [ pkgs.runtimeShellPackage ]; serviceConfig = { ExecStart = '' ${pkgs.mesos}/bin/mesos-slave \ diff --git a/nixos/modules/services/misc/nix-daemon.nix b/nixos/modules/services/misc/nix-daemon.nix index 72b70b28c80..484079ed62d 100644 --- a/nixos/modules/services/misc/nix-daemon.nix +++ b/nixos/modules/services/misc/nix-daemon.nix @@ -30,7 +30,7 @@ let # /bin/sh in the sandbox as a bind-mount to bash. This means we # also need to include the entire closure of bash. Nix >= 2.0 # provides a /bin/sh by default. - sh = pkgs.stdenv.shell; + sh = pkgs.runtimeShell; binshDeps = pkgs.writeReferencesToFile sh; in pkgs.runCommand "nix.conf" { extraOptions = cfg.extraOptions; } '' diff --git a/nixos/modules/services/misc/nixos-manual.nix b/nixos/modules/services/misc/nixos-manual.nix index 5d0f2abd13a..b8253956d54 100644 --- a/nixos/modules/services/misc/nixos-manual.nix +++ b/nixos/modules/services/misc/nixos-manual.nix @@ -43,7 +43,7 @@ let helpScript = pkgs.writeScriptBin "nixos-help" '' - #! ${pkgs.stdenv.shell} -e + #! ${pkgs.runtimeShell} -e browser="$BROWSER" if [ -z "$browser" ]; then browser="$(type -P xdg-open || true)" diff --git a/nixos/modules/services/misc/ssm-agent.nix b/nixos/modules/services/misc/ssm-agent.nix index a57fbca86fb..e951a4c7ffa 100644 --- a/nixos/modules/services/misc/ssm-agent.nix +++ b/nixos/modules/services/misc/ssm-agent.nix @@ -8,7 +8,7 @@ let # in nixpkgs doesn't seem to work properly on NixOS, so let's just fake the two fields SSM # looks for. See https://github.com/aws/amazon-ssm-agent/issues/38 for upstream fix. fake-lsb-release = pkgs.writeScriptBin "lsb_release" '' - #!${pkgs.stdenv.shell} + #!${pkgs.runtimeShell} case "$1" in -i) echo "nixos";; diff --git a/nixos/modules/services/monitoring/apcupsd.nix b/nixos/modules/services/monitoring/apcupsd.nix index 9abd6e9ab64..839116de626 100644 --- a/nixos/modules/services/monitoring/apcupsd.nix +++ b/nixos/modules/services/monitoring/apcupsd.nix @@ -38,7 +38,7 @@ let ]; shellCmdsForEventScript = eventname: commands: '' - echo "#!${pkgs.stdenv.shell}" > "$out/${eventname}" + echo "#!${pkgs.runtimeShell}" > "$out/${eventname}" echo '${commands}' >> "$out/${eventname}" chmod a+x "$out/${eventname}" ''; diff --git a/nixos/modules/services/monitoring/grafana.nix b/nixos/modules/services/monitoring/grafana.nix index 921be23f368..a5b6dbab157 100644 --- a/nixos/modules/services/monitoring/grafana.nix +++ b/nixos/modules/services/monitoring/grafana.nix @@ -25,6 +25,7 @@ let DATABASE_USER = cfg.database.user; DATABASE_PASSWORD = cfg.database.password; DATABASE_PATH = cfg.database.path; + DATABASE_CONN_MAX_LIFETIME = cfg.database.connMaxLifetime; SECURITY_ADMIN_USER = cfg.security.adminUser; SECURITY_ADMIN_PASSWORD = cfg.security.adminPassword; @@ -143,6 +144,15 @@ in { default = "${cfg.dataDir}/data/grafana.db"; type = types.path; }; + + connMaxLifetime = mkOption { + description = '' + Sets the maximum amount of time (in seconds) a connection may be reused. + For MySQL this setting should be shorter than the `wait_timeout' variable. + ''; + default = 14400; + type = types.int; + }; }; security = { @@ -241,7 +251,9 @@ in { description = "Grafana Service Daemon"; wantedBy = ["multi-user.target"]; after = ["networking.target"]; - environment = mapAttrs' (n: v: nameValuePair "GF_${n}" (toString v)) envOptions; + environment = { + QT_QPA_PLATFORM = "offscreen"; + } // mapAttrs' (n: v: nameValuePair "GF_${n}" (toString v)) envOptions; serviceConfig = { ExecStart = "${cfg.package.bin}/bin/grafana-server -homepath ${cfg.dataDir}"; WorkingDirectory = cfg.dataDir; diff --git a/nixos/modules/services/monitoring/smartd.nix b/nixos/modules/services/monitoring/smartd.nix index b8d9e58a5a8..fecae4ca1b3 100644 --- a/nixos/modules/services/monitoring/smartd.nix +++ b/nixos/modules/services/monitoring/smartd.nix @@ -14,7 +14,7 @@ let nx = cfg.notifications.x11; smartdNotify = pkgs.writeScript "smartd-notify.sh" '' - #! ${pkgs.stdenv.shell} + #! ${pkgs.runtimeShell} ${optionalString nm.enable '' { ${pkgs.coreutils}/bin/cat << EOF diff --git a/nixos/modules/services/network-filesystems/xtreemfs.nix b/nixos/modules/services/network-filesystems/xtreemfs.nix index 0c6714563d8..95d7641e8b5 100644 --- a/nixos/modules/services/network-filesystems/xtreemfs.nix +++ b/nixos/modules/services/network-filesystems/xtreemfs.nix @@ -11,7 +11,7 @@ let home = cfg.homeDir; startupScript = class: configPath: pkgs.writeScript "xtreemfs-osd.sh" '' - #! ${pkgs.stdenv.shell} + #! ${pkgs.runtimeShell} JAVA_HOME="${pkgs.jdk}" JAVADIR="${xtreemfs}/share/java" JAVA_CALL="$JAVA_HOME/bin/java -ea -cp $JAVADIR/XtreemFS.jar:$JAVADIR/BabuDB.jar:$JAVADIR/Flease.jar:$JAVADIR/protobuf-java-2.5.0.jar:$JAVADIR/Foundation.jar:$JAVADIR/jdmkrt.jar:$JAVADIR/jdmktk.jar:$JAVADIR/commons-codec-1.3.jar" diff --git a/nixos/modules/services/network-filesystems/yandex-disk.nix b/nixos/modules/services/network-filesystems/yandex-disk.nix index 4de20664133..44b0edf6201 100644 --- a/nixos/modules/services/network-filesystems/yandex-disk.nix +++ b/nixos/modules/services/network-filesystems/yandex-disk.nix @@ -99,10 +99,10 @@ in exit 1 fi - ${pkgs.su}/bin/su -s ${pkgs.stdenv.shell} ${u} \ + ${pkgs.su}/bin/su -s ${pkgs.runtimeShell} ${u} \ -c '${pkgs.yandex-disk}/bin/yandex-disk token -p ${cfg.password} ${cfg.username} ${dir}/token' - ${pkgs.su}/bin/su -s ${pkgs.stdenv.shell} ${u} \ + ${pkgs.su}/bin/su -s ${pkgs.runtimeShell} ${u} \ -c '${pkgs.yandex-disk}/bin/yandex-disk start --no-daemon -a ${dir}/token -d ${cfg.directory} --exclude-dirs=${cfg.excludes}' ''; diff --git a/nixos/modules/services/networking/amuled.nix b/nixos/modules/services/networking/amuled.nix index fc7d56a24fa..9898f164c5c 100644 --- a/nixos/modules/services/networking/amuled.nix +++ b/nixos/modules/services/networking/amuled.nix @@ -68,7 +68,7 @@ in ''; script = '' - ${pkgs.su}/bin/su -s ${pkgs.stdenv.shell} ${user} \ + ${pkgs.su}/bin/su -s ${pkgs.runtimeShell} ${user} \ -c 'HOME="${cfg.dataDir}" ${pkgs.amuleDaemon}/bin/amuled' ''; }; diff --git a/nixos/modules/services/networking/firewall.nix b/nixos/modules/services/networking/firewall.nix index bce48c8f65e..20c0b0acf16 100644 --- a/nixos/modules/services/networking/firewall.nix +++ b/nixos/modules/services/networking/firewall.nix @@ -54,7 +54,7 @@ let ''; writeShScript = name: text: let dir = pkgs.writeScriptBin name '' - #! ${pkgs.stdenv.shell} -e + #! ${pkgs.runtimeShell} -e ${text} ''; in "${dir}/bin/${name}"; diff --git a/nixos/modules/services/networking/flashpolicyd.nix b/nixos/modules/services/networking/flashpolicyd.nix index 5ba85178179..5b83ce13138 100644 --- a/nixos/modules/services/networking/flashpolicyd.nix +++ b/nixos/modules/services/networking/flashpolicyd.nix @@ -22,7 +22,7 @@ let flashpolicydWrapper = pkgs.writeScriptBin "flashpolicyd" '' - #! ${pkgs.stdenv.shell} + #! ${pkgs.runtimeShell} exec ${flashpolicyd}/Perl_xinetd/in.flashpolicyd.pl \ --file=${pkgs.writeText "flashpolixy.xml" cfg.policy} \ 2> /dev/null diff --git a/nixos/modules/services/networking/nftables.nix b/nixos/modules/services/networking/nftables.nix index 56b94205414..ad7c013a544 100644 --- a/nixos/modules/services/networking/nftables.nix +++ b/nixos/modules/services/networking/nftables.nix @@ -116,7 +116,7 @@ in include "${cfg.rulesetFile}" ''; checkScript = pkgs.writeScript "nftables-check" '' - #! ${pkgs.stdenv.shell} -e + #! ${pkgs.runtimeShell} -e if $(${pkgs.kmod}/bin/lsmod | grep -q ip_tables); then echo "Unload ip_tables before using nftables!" 1>&2 exit 1 diff --git a/nixos/modules/services/networking/nix-serve.nix b/nixos/modules/services/networking/nix-serve.nix index 3e865e3b76a..8499e7c0f7c 100644 --- a/nixos/modules/services/networking/nix-serve.nix +++ b/nixos/modules/services/networking/nix-serve.nix @@ -55,6 +55,8 @@ in environment.NIX_SECRET_KEY_FILE = cfg.secretKeyFile; serviceConfig = { + Restart = "always"; + RestartSec = "5s"; ExecStart = "${pkgs.nix-serve}/bin/nix-serve " + "--listen ${cfg.bindAddress}:${toString cfg.port} ${cfg.extraParams}"; User = "nix-serve"; diff --git a/nixos/modules/services/networking/rdnssd.nix b/nixos/modules/services/networking/rdnssd.nix index 95833d31e99..a102242eae7 100644 --- a/nixos/modules/services/networking/rdnssd.nix +++ b/nixos/modules/services/networking/rdnssd.nix @@ -6,7 +6,7 @@ with lib; let mergeHook = pkgs.writeScript "rdnssd-merge-hook" '' - #! ${pkgs.stdenv.shell} -e + #! ${pkgs.runtimeShell} -e ${pkgs.openresolv}/bin/resolvconf -u ''; in diff --git a/nixos/modules/services/networking/resilio.nix b/nixos/modules/services/networking/resilio.nix index d1c4101f80b..2956a5ecbc0 100644 --- a/nixos/modules/services/networking/resilio.nix +++ b/nixos/modules/services/networking/resilio.nix @@ -50,12 +50,7 @@ in description = '' If enabled, start the Resilio Sync daemon. Once enabled, you can interact with the service through the Web UI, or configure it in your - NixOS configuration. Enabling the <literal>resilio</literal> service - also installs a systemd user unit which can be used to start - user-specific copies of the daemon. Once installed, you can use - <literal>systemctl --user start resilio</literal> as your user to start - the daemon using the configuration file located at - <literal>$HOME/.config/resilio-sync/config.json</literal>. + NixOS configuration. ''; }; diff --git a/nixos/modules/services/printing/cupsd.nix b/nixos/modules/services/printing/cupsd.nix index 4c7f58d1d8b..ecab8cfc7df 100644 --- a/nixos/modules/services/printing/cupsd.nix +++ b/nixos/modules/services/printing/cupsd.nix @@ -124,7 +124,7 @@ in listenAddresses = mkOption { type = types.listOf types.str; - default = [ "127.0.0.1:631" ]; + default = [ "localhost:631" ]; example = [ "*:631" ]; description = '' A list of addresses and ports on which to listen. @@ -321,7 +321,10 @@ in ''} ''; - serviceConfig.PrivateTmp = true; + serviceConfig = { + PrivateTmp = true; + RuntimeDirectory = [ "cups" ]; + }; }; systemd.services.cups-browsed = mkIf avahiEnabled diff --git a/nixos/modules/services/security/torify.nix b/nixos/modules/services/security/torify.nix index a29cb3f33da..08da726437e 100644 --- a/nixos/modules/services/security/torify.nix +++ b/nixos/modules/services/security/torify.nix @@ -7,7 +7,7 @@ let torify = pkgs.writeTextFile { name = "tsocks"; text = '' - #!${pkgs.stdenv.shell} + #!${pkgs.runtimeShell} TSOCKS_CONF_FILE=${pkgs.writeText "tsocks.conf" cfg.tsocks.config} LD_PRELOAD="${pkgs.tsocks}/lib/libtsocks.so $LD_PRELOAD" "$@" ''; executable = true; diff --git a/nixos/modules/services/security/torsocks.nix b/nixos/modules/services/security/torsocks.nix index 1b5a05b21e7..c60c745443b 100644 --- a/nixos/modules/services/security/torsocks.nix +++ b/nixos/modules/services/security/torsocks.nix @@ -23,7 +23,7 @@ let wrapTorsocks = name: server: pkgs.writeTextFile { name = name; text = '' - #!${pkgs.stdenv.shell} + #!${pkgs.runtimeShell} TORSOCKS_CONF_FILE=${pkgs.writeText "torsocks.conf" (configFile server)} ${pkgs.torsocks}/bin/torsocks "$@" ''; executable = true; diff --git a/nixos/modules/services/torrent/transmission.nix b/nixos/modules/services/torrent/transmission.nix index dd6b585b7e2..4911a64c95d 100644 --- a/nixos/modules/services/torrent/transmission.nix +++ b/nixos/modules/services/torrent/transmission.nix @@ -90,7 +90,7 @@ in # 1) Only the "transmission" user and group have access to torrents. # 2) Optionally update/force specific fields into the configuration file. serviceConfig.ExecStartPre = '' - ${pkgs.stdenv.shell} -c "mkdir -p ${homeDir} ${settingsDir} ${fullSettings.download-dir} ${fullSettings.incomplete-dir} && chmod 770 ${homeDir} ${settingsDir} ${fullSettings.download-dir} ${fullSettings.incomplete-dir} && rm -f ${settingsDir}/settings.json && cp -f ${settingsFile} ${settingsDir}/settings.json" + ${pkgs.runtimeShell} -c "mkdir -p ${homeDir} ${settingsDir} ${fullSettings.download-dir} ${fullSettings.incomplete-dir} && chmod 770 ${homeDir} ${settingsDir} ${fullSettings.download-dir} ${fullSettings.incomplete-dir} && rm -f ${settingsDir}/settings.json && cp -f ${settingsFile} ${settingsDir}/settings.json" ''; serviceConfig.ExecStart = "${pkgs.transmission}/bin/transmission-daemon -f --port ${toString config.services.transmission.port}"; serviceConfig.ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID"; diff --git a/nixos/modules/services/web-apps/tt-rss.nix b/nixos/modules/services/web-apps/tt-rss.nix index c784f4756d1..8f7a56189a0 100644 --- a/nixos/modules/services/web-apps/tt-rss.nix +++ b/nixos/modules/services/web-apps/tt-rss.nix @@ -505,7 +505,7 @@ let ${cfg.database.name}'' else if cfg.database.type == "mysql" then '' - echo '${e}' | ${pkgs.mysql}/bin/mysql \ + echo '${e}' | ${pkgs.sudo}/bin/sudo -u ${cfg.user} ${config.services.mysql.package}/bin/mysql \ -u ${cfg.database.user} \ ${optionalString (cfg.database.password != null) "-p${cfg.database.password}"} \ ${optionalString (cfg.database.host != null) "-h ${cfg.database.host} -P ${toString dbPort}"} \ diff --git a/nixos/modules/services/web-servers/apache-httpd/owncloud.nix b/nixos/modules/services/web-servers/apache-httpd/owncloud.nix index cfddab2f504..82b8bf3e30d 100644 --- a/nixos/modules/services/web-servers/apache-httpd/owncloud.nix +++ b/nixos/modules/services/web-servers/apache-httpd/owncloud.nix @@ -346,7 +346,7 @@ let postgresql = serverInfo.fullConfig.services.postgresql.package; setupDb = pkgs.writeScript "setup-owncloud-db" '' - #!${pkgs.stdenv.shell} + #!${pkgs.runtimeShell} PATH="${postgresql}/bin" createuser --no-superuser --no-createdb --no-createrole "${config.dbUser}" || true createdb "${config.dbName}" -O "${config.dbUser}" || true diff --git a/nixos/modules/services/web-servers/tomcat.nix b/nixos/modules/services/web-servers/tomcat.nix index 0b2e5c0b69d..aa94e0e976c 100644 --- a/nixos/modules/services/web-servers/tomcat.nix +++ b/nixos/modules/services/web-servers/tomcat.nix @@ -19,11 +19,7 @@ in options = { services.tomcat = { - - enable = mkOption { - default = false; - description = "Whether to enable Apache Tomcat"; - }; + enable = mkEnableOption "Apache Tomcat"; package = mkOption { type = types.package; @@ -36,10 +32,30 @@ in }; baseDir = mkOption { + type = lib.types.path; default = "/var/tomcat"; description = "Location where Tomcat stores configuration files, webapplications and logfiles"; }; + logDirs = mkOption { + default = []; + type = types.listOf types.path; + description = "Directories to create in baseDir/logs/"; + }; + + extraConfigFiles = mkOption { + default = []; + type = types.listOf types.path; + description = "Extra configuration files to pull into the tomcat conf directory"; + }; + + extraEnvironment = mkOption { + type = types.listOf types.str; + default = []; + example = [ "ENVIRONMENT=production" ]; + description = "Environment Variables to pass to the tomcat service"; + }; + extraGroups = mkOption { default = []; example = [ "users" ]; @@ -47,31 +63,46 @@ in }; user = mkOption { + type = types.str; default = "tomcat"; description = "User account under which Apache Tomcat runs."; }; group = mkOption { + type = types.str; default = "tomcat"; description = "Group account under which Apache Tomcat runs."; }; javaOpts = mkOption { + type = types.either (types.listOf types.str) types.str; default = ""; description = "Parameters to pass to the Java Virtual Machine which spawns Apache Tomcat"; }; catalinaOpts = mkOption { + type = types.either (types.listOf types.str) types.str; default = ""; description = "Parameters to pass to the Java Virtual Machine which spawns the Catalina servlet container"; }; sharedLibs = mkOption { + type = types.listOf types.str; default = []; description = "List containing JAR files or directories with JAR files which are libraries shared by the web applications"; }; + serverXml = mkOption { + type = types.lines; + default = ""; + description = " + Verbatim server.xml configuration. + This is mutually exclusive with the virtualHosts options. + "; + }; + commonLibs = mkOption { + type = types.listOf types.str; default = []; description = "List containing JAR files or directories with JAR files which are libraries shared by the web applications and the servlet container"; }; @@ -84,11 +115,21 @@ in }; virtualHosts = mkOption { + type = types.listOf (types.submodule { + options = { + name = mkOption { + type = types.listOf types.str; + description = "name of the virtualhost"; + default = []; + }; + }; + }); default = []; description = "List consisting of a virtual host name and a list of web applications to deploy on each virtual host"; }; logPerVirtualHost = mkOption { + type = types.bool; default = false; description = "Whether to enable logging per virtual host."; }; @@ -104,11 +145,13 @@ in enable = mkOption { default = false; + type = types.bool; description = "Whether to enable an Apache Axis2 container"; }; services = mkOption { default = []; + type = types.listOf types.str; description = "List containing AAR files or directories with AAR files which are web services to be deployed on Axis2"; }; @@ -140,130 +183,104 @@ in description = "Apache Tomcat server"; wantedBy = [ "multi-user.target" ]; after = [ "network.target" ]; - serviceConfig.Type = "oneshot"; - serviceConfig.RemainAfterExit = true; preStart = '' # Create the base directory - mkdir -p ${cfg.baseDir} + mkdir -p \ + ${cfg.baseDir}/{conf,virtualhosts,logs,temp,lib,shared/lib,webapps,work} + chown ${cfg.user}:${cfg.group} \ + ${cfg.baseDir}/{conf,virtualhosts,logs,temp,lib,shared/lib,webapps,work} # Create a symlink to the bin directory of the tomcat component ln -sfn ${tomcat}/bin ${cfg.baseDir}/bin - # Create a conf/ directory - mkdir -p ${cfg.baseDir}/conf - chown ${cfg.user}:${cfg.group} ${cfg.baseDir}/conf - # Symlink the config files in the conf/ directory (except for catalina.properties and server.xml) - for i in $(ls ${tomcat}/conf | grep -v catalina.properties | grep -v server.xml) - do - ln -sfn ${tomcat}/conf/$i ${cfg.baseDir}/conf/`basename $i` + for i in $(ls ${tomcat}/conf | grep -v catalina.properties | grep -v server.xml); do + ln -sfn ${tomcat}/conf/$i ${cfg.baseDir}/conf/`basename $i` done - # Create subdirectory for virtual hosts - mkdir -p ${cfg.baseDir}/virtualhosts + ${if cfg.extraConfigFiles != [] then '' + for i in ${toString cfg.extraConfigFiles}; do + ln -sfn $i ${cfg.baseDir}/conf/`basename $i` + done + '' else ""} # Create a modified catalina.properties file # Change all references from CATALINA_HOME to CATALINA_BASE and add support for shared libraries sed -e 's|''${catalina.home}|''${catalina.base}|g' \ - -e 's|shared.loader=|shared.loader=''${catalina.base}/shared/lib/*.jar|' \ - ${tomcat}/conf/catalina.properties > ${cfg.baseDir}/conf/catalina.properties - - # Create a modified server.xml which also includes all virtual hosts - sed -e "/<Engine name=\"Catalina\" defaultHost=\"localhost\">/a\ ${ - toString (map (virtualHost: ''<Host name=\"${virtualHost.name}\" appBase=\"virtualhosts/${virtualHost.name}/webapps\" unpackWARs=\"true\" autoDeploy=\"true\" xmlValidation=\"false\" xmlNamespaceAware=\"false\" >${if cfg.logPerVirtualHost then ''<Valve className=\"org.apache.catalina.valves.AccessLogValve\" directory=\"logs/${virtualHost.name}\" prefix=\"${virtualHost.name}_access_log.\" pattern=\"combined\" resolveHosts=\"false\"/>'' else ""}</Host>'') cfg.virtualHosts)}" \ - ${tomcat}/conf/server.xml > ${cfg.baseDir}/conf/server.xml - - # Create a logs/ directory - mkdir -p ${cfg.baseDir}/logs - chown ${cfg.user}:${cfg.group} ${cfg.baseDir}/logs - ${if cfg.logPerVirtualHost then - toString (map (h: '' - mkdir -p ${cfg.baseDir}/logs/${h.name} - chown ${cfg.user}:${cfg.group} ${cfg.baseDir}/logs/${h.name} - '') cfg.virtualHosts) else ''''} - - # Create a temp/ directory - mkdir -p ${cfg.baseDir}/temp - chown ${cfg.user}:${cfg.group} ${cfg.baseDir}/temp - - # Create a lib/ directory - mkdir -p ${cfg.baseDir}/lib - chown ${cfg.user}:${cfg.group} ${cfg.baseDir}/lib - - # Create a shared/lib directory - mkdir -p ${cfg.baseDir}/shared/lib - chown ${cfg.user}:${cfg.group} ${cfg.baseDir}/shared/lib - - # Create a webapps/ directory - mkdir -p ${cfg.baseDir}/webapps - chown ${cfg.user}:${cfg.group} ${cfg.baseDir}/webapps + -e 's|shared.loader=|shared.loader=''${catalina.base}/shared/lib/*.jar|' \ + ${tomcat}/conf/catalina.properties > ${cfg.baseDir}/conf/catalina.properties + + ${if cfg.serverXml != "" then '' + cp -f ${pkgs.writeTextDir "server.xml" cfg.serverXml}/* ${cfg.baseDir}/conf/ + '' else '' + # Create a modified server.xml which also includes all virtual hosts + sed -e "/<Engine name=\"Catalina\" defaultHost=\"localhost\">/a\ ${toString (map (virtualHost: ''<Host name=\"${virtualHost.name}\" appBase=\"virtualhosts/${virtualHost.name}/webapps\" unpackWARs=\"true\" autoDeploy=\"true\" xmlValidation=\"false\" xmlNamespaceAware=\"false\" >${if cfg.logPerVirtualHost then ''<Valve className=\"org.apache.catalina.valves.AccessLogValve\" directory=\"logs/${virtualHost.name}\" prefix=\"${virtualHost.name}_access_log.\" pattern=\"combined\" resolveHosts=\"false\"/>'' else ""}</Host>'') cfg.virtualHosts)}" \ + ${tomcat}/conf/server.xml > ${cfg.baseDir}/conf/server.xml + '' + } + ${optionalString (cfg.logDirs != []) '' + for i in ${toString cfg.logDirs}; do + mkdir -p ${cfg.baseDir}/logs/$i + chown ${cfg.user}:${cfg.group} ${cfg.baseDir}/logs/$i + done + ''} + ${optionalString cfg.logPerVirtualHost (toString (map (h: '' + mkdir -p ${cfg.baseDir}/logs/${h.name} + chown ${cfg.user}:${cfg.group} ${cfg.baseDir}/logs/${h.name} + '') cfg.virtualHosts))} # Symlink all the given common libs files or paths into the lib/ directory - for i in ${tomcat} ${toString cfg.commonLibs} - do - if [ -f $i ] - then - # If the given web application is a file, symlink it into the common/lib/ directory - ln -sfn $i ${cfg.baseDir}/lib/`basename $i` - elif [ -d $i ] - then - # If the given web application is a directory, then iterate over the files - # in the special purpose directories and symlink them into the tomcat tree - - for j in $i/lib/* - do - ln -sfn $j ${cfg.baseDir}/lib/`basename $j` - done - fi + for i in ${tomcat} ${toString cfg.commonLibs}; do + if [ -f $i ]; then + # If the given web application is a file, symlink it into the common/lib/ directory + ln -sfn $i ${cfg.baseDir}/lib/`basename $i` + elif [ -d $i ]; then + # If the given web application is a directory, then iterate over the files + # in the special purpose directories and symlink them into the tomcat tree + + for j in $i/lib/*; do + ln -sfn $j ${cfg.baseDir}/lib/`basename $j` + done + fi done # Symlink all the given shared libs files or paths into the shared/lib/ directory - for i in ${toString cfg.sharedLibs} - do - if [ -f $i ] - then - # If the given web application is a file, symlink it into the common/lib/ directory - ln -sfn $i ${cfg.baseDir}/shared/lib/`basename $i` - elif [ -d $i ] - then - # If the given web application is a directory, then iterate over the files - # in the special purpose directories and symlink them into the tomcat tree - - for j in $i/shared/lib/* - do - ln -sfn $j ${cfg.baseDir}/shared/lib/`basename $j` - done - fi + for i in ${toString cfg.sharedLibs}; do + if [ -f $i ]; then + # If the given web application is a file, symlink it into the common/lib/ directory + ln -sfn $i ${cfg.baseDir}/shared/lib/`basename $i` + elif [ -d $i ]; then + # If the given web application is a directory, then iterate over the files + # in the special purpose directories and symlink them into the tomcat tree + + for j in $i/shared/lib/*; do + ln -sfn $j ${cfg.baseDir}/shared/lib/`basename $j` + done + fi done # Symlink all the given web applications files or paths into the webapps/ directory - for i in ${toString cfg.webapps} - do - if [ -f $i ] - then - # If the given web application is a file, symlink it into the webapps/ directory - ln -sfn $i ${cfg.baseDir}/webapps/`basename $i` - elif [ -d $i ] - then - # If the given web application is a directory, then iterate over the files - # in the special purpose directories and symlink them into the tomcat tree - - for j in $i/webapps/* - do - ln -sfn $j ${cfg.baseDir}/webapps/`basename $j` - done + for i in ${toString cfg.webapps}; do + if [ -f $i ]; then + # If the given web application is a file, symlink it into the webapps/ directory + ln -sfn $i ${cfg.baseDir}/webapps/`basename $i` + elif [ -d $i ]; then + # If the given web application is a directory, then iterate over the files + # in the special purpose directories and symlink them into the tomcat tree + + for j in $i/webapps/*; do + ln -sfn $j ${cfg.baseDir}/webapps/`basename $j` + done - # Also symlink the configuration files if they are included - if [ -d $i/conf/Catalina ] - then - for j in $i/conf/Catalina/* - do - mkdir -p ${cfg.baseDir}/conf/Catalina/localhost - ln -sfn $j ${cfg.baseDir}/conf/Catalina/localhost/`basename $j` - done - fi + # Also symlink the configuration files if they are included + if [ -d $i/conf/Catalina ]; then + for j in $i/conf/Catalina/*; do + mkdir -p ${cfg.baseDir}/conf/Catalina/localhost + ln -sfn $j ${cfg.baseDir}/conf/Catalina/localhost/`basename $j` + done fi + fi done ${toString (map (virtualHost: '' @@ -275,94 +292,79 @@ in # Symlink all the given web applications files or paths into the webapps/ directory # of this virtual host - for i in "${if virtualHost ? webapps then toString virtualHost.webapps else ""}" - do - if [ -f $i ] - then - # If the given web application is a file, symlink it into the webapps/ directory - ln -sfn $i ${cfg.baseDir}/virtualhosts/${virtualHost.name}/webapps/`basename $i` - elif [ -d $i ] - then - # If the given web application is a directory, then iterate over the files - # in the special purpose directories and symlink them into the tomcat tree - - for j in $i/webapps/* - do - ln -sfn $j ${cfg.baseDir}/virtualhosts/${virtualHost.name}/webapps/`basename $j` - done - - # Also symlink the configuration files if they are included - if [ -d $i/conf/Catalina ] - then - for j in $i/conf/Catalina/* - do - mkdir -p ${cfg.baseDir}/conf/Catalina/${virtualHost.name} - ln -sfn $j ${cfg.baseDir}/conf/Catalina/${virtualHost.name}/`basename $j` - done - fi + for i in "${if virtualHost ? webapps then toString virtualHost.webapps else ""}"; do + if [ -f $i ]; then + # If the given web application is a file, symlink it into the webapps/ directory + ln -sfn $i ${cfg.baseDir}/virtualhosts/${virtualHost.name}/webapps/`basename $i` + elif [ -d $i ]; then + # If the given web application is a directory, then iterate over the files + # in the special purpose directories and symlink them into the tomcat tree + + for j in $i/webapps/*; do + ln -sfn $j ${cfg.baseDir}/virtualhosts/${virtualHost.name}/webapps/`basename $j` + done + + # Also symlink the configuration files if they are included + if [ -d $i/conf/Catalina ]; then + for j in $i/conf/Catalina/*; do + mkdir -p ${cfg.baseDir}/conf/Catalina/${virtualHost.name} + ln -sfn $j ${cfg.baseDir}/conf/Catalina/${virtualHost.name}/`basename $j` + done fi + fi done - - '' - ) cfg.virtualHosts) } - - # Create a work/ directory - mkdir -p ${cfg.baseDir}/work - chown ${cfg.user}:${cfg.group} ${cfg.baseDir}/work - - ${if cfg.axis2.enable then - '' - # Copy the Axis2 web application - cp -av ${pkgs.axis2}/webapps/axis2 ${cfg.baseDir}/webapps - - # Turn off addressing, which causes many errors - sed -i -e 's%<module ref="addressing"/>%<!-- <module ref="addressing"/> -->%' ${cfg.baseDir}/webapps/axis2/WEB-INF/conf/axis2.xml - - # Modify permissions on the Axis2 application - chown -R ${cfg.user}:${cfg.group} ${cfg.baseDir}/webapps/axis2 - - # Symlink all the given web service files or paths into the webapps/axis2/WEB-INF/services directory - for i in ${toString cfg.axis2.services} - do - if [ -f $i ] - then - # If the given web service is a file, symlink it into the webapps/axis2/WEB-INF/services - ln -sfn $i ${cfg.baseDir}/webapps/axis2/WEB-INF/services/`basename $i` - elif [ -d $i ] - then - # If the given web application is a directory, then iterate over the files - # in the special purpose directories and symlink them into the tomcat tree - - for j in $i/webapps/axis2/WEB-INF/services/* - do - ln -sfn $j ${cfg.baseDir}/webapps/axis2/WEB-INF/services/`basename $j` - done - - # Also symlink the configuration files if they are included - if [ -d $i/conf/Catalina ] - then - for j in $i/conf/Catalina/* - do - ln -sfn $j ${cfg.baseDir}/conf/Catalina/localhost/`basename $j` - done - fi - fi - done - '' - else ""} - ''; - - script = '' - ${pkgs.su}/bin/su -s ${pkgs.bash}/bin/sh ${cfg.user} -c 'CATALINA_BASE=${cfg.baseDir} JAVA_HOME=${cfg.jdk} JAVA_OPTS="${cfg.javaOpts}" CATALINA_OPTS="${cfg.catalinaOpts}" ${tomcat}/bin/startup.sh' - ''; - - preStop = '' - echo "Stopping tomcat..." - CATALINA_BASE=${cfg.baseDir} JAVA_HOME=${cfg.jdk} ${pkgs.su}/bin/su -s ${pkgs.bash}/bin/sh ${cfg.user} -c ${tomcat}/bin/shutdown.sh + '') cfg.virtualHosts)} + + ${optionalString cfg.axis2.enable '' + # Copy the Axis2 web application + cp -av ${pkgs.axis2}/webapps/axis2 ${cfg.baseDir}/webapps + + # Turn off addressing, which causes many errors + sed -i -e 's%<module ref="addressing"/>%<!-- <module ref="addressing"/> -->%' ${cfg.baseDir}/webapps/axis2/WEB-INF/conf/axis2.xml + + # Modify permissions on the Axis2 application + chown -R ${cfg.user}:${cfg.group} ${cfg.baseDir}/webapps/axis2 + + # Symlink all the given web service files or paths into the webapps/axis2/WEB-INF/services directory + for i in ${toString cfg.axis2.services}; do + if [ -f $i ]; then + # If the given web service is a file, symlink it into the webapps/axis2/WEB-INF/services + ln -sfn $i ${cfg.baseDir}/webapps/axis2/WEB-INF/services/`basename $i` + elif [ -d $i ]; then + # If the given web application is a directory, then iterate over the files + # in the special purpose directories and symlink them into the tomcat tree + + for j in $i/webapps/axis2/WEB-INF/services/*; do + ln -sfn $j ${cfg.baseDir}/webapps/axis2/WEB-INF/services/`basename $j` + done + + # Also symlink the configuration files if they are included + if [ -d $i/conf/Catalina ]; then + for j in $i/conf/Catalina/*; do + ln -sfn $j ${cfg.baseDir}/conf/Catalina/localhost/`basename $j` + done + fi + fi + done + ''} ''; + serviceConfig = { + Type = "forking"; + PermissionsStartOnly = true; + PIDFile="/run/tomcat/tomcat.pid"; + RuntimeDirectory = "tomcat"; + User = cfg.user; + Environment=[ + "CATALINA_BASE=${cfg.baseDir}" + "CATALINA_PID=/run/tomcat/tomcat.pid" + "JAVA_HOME='${cfg.jdk}'" + "JAVA_OPTS='${builtins.toString cfg.javaOpts}'" + "CATALINA_OPTS='${builtins.toString cfg.catalinaOpts}'" + ] ++ cfg.extraEnvironment; + ExecStart = "${tomcat}/bin/startup.sh"; + ExecStop = "${tomcat}/bin/shutdown.sh"; + }; }; - }; - } diff --git a/nixos/modules/services/x11/desktop-managers/xfce.nix b/nixos/modules/services/x11/desktop-managers/xfce.nix index 489bffbee91..7dcc600d266 100644 --- a/nixos/modules/services/x11/desktop-managers/xfce.nix +++ b/nixos/modules/services/x11/desktop-managers/xfce.nix @@ -128,7 +128,7 @@ in # Set GTK_DATA_PREFIX so that GTK+ can find the Xfce themes. export GTK_DATA_PREFIX=${config.system.path} - ${pkgs.stdenv.shell} ${pkgs.xfce.xinitrc} & + ${pkgs.runtimeShell} ${pkgs.xfce.xinitrc} & waitPID=$! ''; }]; diff --git a/nixos/modules/services/x11/display-managers/slim.nix b/nixos/modules/services/x11/display-managers/slim.nix index 0c4dd1973b5..f645a5c2f07 100644 --- a/nixos/modules/services/x11/display-managers/slim.nix +++ b/nixos/modules/services/x11/display-managers/slim.nix @@ -14,7 +14,7 @@ let default_xserver ${dmcfg.xserverBin} xserver_arguments ${toString dmcfg.xserverArgs} sessiondir ${dmcfg.session.desktops} - login_cmd exec ${pkgs.stdenv.shell} ${dmcfg.session.script} "%session" + login_cmd exec ${pkgs.runtimeShell} ${dmcfg.session.script} "%session" halt_cmd ${config.systemd.package}/sbin/shutdown -h now reboot_cmd ${config.systemd.package}/sbin/shutdown -r now logfile /dev/stderr diff --git a/nixos/modules/services/x11/window-managers/default.nix b/nixos/modules/services/x11/window-managers/default.nix index 25ba95fccd7..bc420831ad8 100644 --- a/nixos/modules/services/x11/window-managers/default.nix +++ b/nixos/modules/services/x11/window-managers/default.nix @@ -12,6 +12,7 @@ in ./afterstep.nix ./bspwm.nix ./dwm.nix + ./evilwm.nix ./exwm.nix ./fluxbox.nix ./fvwm.nix diff --git a/nixos/modules/system/activation/activation-script.nix b/nixos/modules/system/activation/activation-script.nix index 8c9b35fe524..c563614caaa 100644 --- a/nixos/modules/system/activation/activation-script.nix +++ b/nixos/modules/system/activation/activation-script.nix @@ -61,7 +61,7 @@ in apply = set: { script = '' - #! ${pkgs.stdenv.shell} + #! ${pkgs.runtimeShell} systemConfig=@out@ diff --git a/nixos/modules/system/boot/kexec.nix b/nixos/modules/system/boot/kexec.nix index b7821f9509f..14ebe66e632 100644 --- a/nixos/modules/system/boot/kexec.nix +++ b/nixos/modules/system/boot/kexec.nix @@ -1,21 +1,22 @@ -{ config, pkgs, ... }: +{ config, pkgs, lib, ... }: { - environment.systemPackages = [ pkgs.kexectools ]; + config = lib.mkIf (pkgs.kexectools != null) { + environment.systemPackages = [ pkgs.kexectools ]; - systemd.services."prepare-kexec" = - { description = "Preparation for kexec"; - wantedBy = [ "kexec.target" ]; - before = [ "systemd-kexec.service" ]; - unitConfig.DefaultDependencies = false; - serviceConfig.Type = "oneshot"; - path = [ pkgs.kexectools ]; - script = - '' - p=$(readlink -f /nix/var/nix/profiles/system) - if ! [ -d $p ]; then exit 1; fi - exec kexec --load $p/kernel --initrd=$p/initrd --append="$(cat $p/kernel-params) init=$p/init" - ''; - }; - -} \ No newline at end of file + systemd.services."prepare-kexec" = + { description = "Preparation for kexec"; + wantedBy = [ "kexec.target" ]; + before = [ "systemd-kexec.service" ]; + unitConfig.DefaultDependencies = false; + serviceConfig.Type = "oneshot"; + path = [ pkgs.kexectools ]; + script = + '' + p=$(readlink -f /nix/var/nix/profiles/system) + if ! [ -d $p ]; then exit 1; fi + exec kexec --load $p/kernel --initrd=$p/initrd --append="$(cat $p/kernel-params) init=$p/init" + ''; + }; + }; +} diff --git a/nixos/modules/system/boot/loader/grub/grub.nix b/nixos/modules/system/boot/loader/grub/grub.nix index 0d83391de89..e2cff1c1bd9 100644 --- a/nixos/modules/system/boot/loader/grub/grub.nix +++ b/nixos/modules/system/boot/loader/grub/grub.nix @@ -40,7 +40,7 @@ let { splashImage = f cfg.splashImage; grub = f grub; grubTarget = f (grub.grubTarget or ""); - shell = "${pkgs.stdenv.shell}"; + shell = "${pkgs.runtimeShell}"; fullName = (builtins.parseDrvName realGrub.name).name; fullVersion = (builtins.parseDrvName realGrub.name).version; grubEfi = f grubEfi; @@ -536,9 +536,9 @@ in btrfsprogs = pkgs.btrfs-progs; }; in pkgs.writeScript "install-grub.sh" ('' - #!${pkgs.stdenv.shell} + #!${pkgs.runtimeShell} set -e - export PERL5LIB=${makePerlPath (with pkgs.perlPackages; [ FileSlurp XMLLibXML XMLSAX ListCompare ])} + export PERL5LIB=${makePerlPath (with pkgs.perlPackages; [ FileSlurp XMLLibXML XMLSAX XMLSAXBase ListCompare ])} ${optionalString cfg.enableCryptodisk "export GRUB_ENABLE_CRYPTODISK=y"} '' + flip concatMapStrings cfg.mirroredBoots (args: '' ${pkgs.perl}/bin/perl ${install-grub-pl} ${grubConfig args} $@ diff --git a/nixos/modules/system/boot/loader/grub/install-grub.pl b/nixos/modules/system/boot/loader/grub/install-grub.pl index cc03e54ead6..8bd203106f5 100644 --- a/nixos/modules/system/boot/loader/grub/install-grub.pl +++ b/nixos/modules/system/boot/loader/grub/install-grub.pl @@ -182,7 +182,7 @@ sub GrubFs { # Based on the type pull in the identifier from the system my ($status, @devInfo) = runCommand("@utillinux@/bin/blkid -o export @{[$fs->device]}"); if ($status != 0) { - die "Failed to get blkid info for @{[$fs->mount]} on @{[$fs->device]}"; + die "Failed to get blkid info (returned $status) for @{[$fs->mount]} on @{[$fs->device]}"; } my @matches = join("", @devInfo) =~ m/@{[uc $fsIdentifier]}=([^\n]*)/; if ($#matches != 0) { diff --git a/nixos/modules/system/boot/stage-1.nix b/nixos/modules/system/boot/stage-1.nix index df450be8c40..55bb6d3449c 100644 --- a/nixos/modules/system/boot/stage-1.nix +++ b/nixos/modules/system/boot/stage-1.nix @@ -30,6 +30,50 @@ let # mounting `/`, like `/` on a loopback). fileSystems = filter utils.fsNeededForBoot config.system.build.fileSystems; + # A utility for enumerating the shared-library dependencies of a program + findLibs = pkgs.writeShellScriptBin "find-libs" '' + set -euo pipefail + + declare -A seen + declare -a left + + patchelf="${pkgs.buildPackages.patchelf}/bin/patchelf" + + function add_needed { + rpath="$($patchelf --print-rpath $1)" + dir="$(dirname $1)" + for lib in $($patchelf --print-needed $1); do + left+=("$lib" "$rpath" "$dir") + done + } + + add_needed $1 + + while [ ''${#left[@]} -ne 0 ]; do + next=''${left[0]} + rpath=''${left[1]} + ORIGIN=''${left[2]} + left=("''${left[@]:3}") + if [ -z ''${seen[$next]+x} ]; then + seen[$next]=1 + IFS=: read -ra paths <<< $rpath + res= + for path in "''${paths[@]}"; do + path=$(eval "echo $path") + if [ -f "$path/$next" ]; then + res="$path/$next" + echo "$res" + add_needed "$res" + break + fi + done + if [ -z "$res" ]; then + echo "Couldn't satisfy dependency $next" >&2 + exit 1 + fi + fi + done + ''; # Some additional utilities needed in stage 1, like mount, lvm, fsck # etc. We don't want to bring in all of those packages, so we just @@ -37,7 +81,7 @@ let # we just copy what we need from Glibc and use patchelf to make it # work. extraUtils = pkgs.runCommandCC "extra-utils" - { buildInputs = [pkgs.nukeReferences]; + { nativeBuildInputs = [pkgs.buildPackages.nukeReferences]; allowedReferences = [ "out" ]; # prevent accidents like glibc being included in the initrd } '' @@ -103,9 +147,7 @@ let # Copy all of the needed libraries find $out/bin $out/lib -type f | while read BIN; do echo "Copying libs for executable $BIN" - LDD="$(ldd $BIN)" || continue - LIBS="$(echo "$LDD" | awk '{print $3}' | sed '/^$/d')" - for LIB in $LIBS; do + for LIB in $(${findLibs}/bin/find-libs $BIN); do TGT="$out/lib/$(basename $LIB)" if [ ! -f "$TGT" ]; then SRC="$(readlink -e $LIB)" @@ -132,6 +174,7 @@ let fi done + if [ -z "${toString pkgs.stdenv.isCross}" ]; then # Make sure that the patchelf'ed binaries still work. echo "testing patched programs..." $out/bin/ash -c 'echo hello world' | grep "hello world" @@ -144,6 +187,7 @@ let $out/bin/mdadm --version ${config.boot.initrd.extraUtilsCommandsTest} + fi ''; # */ @@ -245,7 +289,7 @@ let { src = "${pkgs.kmod-blacklist-ubuntu}/modprobe.conf"; } '' target=$out - ${pkgs.perl}/bin/perl -0pe 's/## file: iwlwifi.conf(.+?)##/##/s;' $src > $out + ${pkgs.buildPackages.perl}/bin/perl -0pe 's/## file: iwlwifi.conf(.+?)##/##/s;' $src > $out ''; symlink = "/etc/modprobe.d/ubuntu.conf"; } diff --git a/nixos/modules/system/boot/stage-2.nix b/nixos/modules/system/boot/stage-2.nix index 8db6d2d2f73..78afbd8dbc1 100644 --- a/nixos/modules/system/boot/stage-2.nix +++ b/nixos/modules/system/boot/stage-2.nix @@ -10,6 +10,7 @@ let bootStage2 = pkgs.substituteAll { src = ./stage-2-init.sh; shellDebug = "${pkgs.bashInteractive}/bin/bash"; + shell = "${pkgs.bash}/bin/bash"; isExecutable = true; inherit (config.nix) readOnlyStore; inherit (config.networking) useHostResolvConf; diff --git a/nixos/modules/system/boot/systemd.nix b/nixos/modules/system/boot/systemd.nix index aff46ea861a..92c9ee0c469 100644 --- a/nixos/modules/system/boot/systemd.nix +++ b/nixos/modules/system/boot/systemd.nix @@ -241,37 +241,37 @@ let } (mkIf (config.preStart != "") { serviceConfig.ExecStartPre = makeJobScript "${name}-pre-start" '' - #! ${pkgs.stdenv.shell} -e + #! ${pkgs.runtimeShell} -e ${config.preStart} ''; }) (mkIf (config.script != "") { serviceConfig.ExecStart = makeJobScript "${name}-start" '' - #! ${pkgs.stdenv.shell} -e + #! ${pkgs.runtimeShell} -e ${config.script} '' + " " + config.scriptArgs; }) (mkIf (config.postStart != "") { serviceConfig.ExecStartPost = makeJobScript "${name}-post-start" '' - #! ${pkgs.stdenv.shell} -e + #! ${pkgs.runtimeShell} -e ${config.postStart} ''; }) (mkIf (config.reload != "") { serviceConfig.ExecReload = makeJobScript "${name}-reload" '' - #! ${pkgs.stdenv.shell} -e + #! ${pkgs.runtimeShell} -e ${config.reload} ''; }) (mkIf (config.preStop != "") { serviceConfig.ExecStop = makeJobScript "${name}-pre-stop" '' - #! ${pkgs.stdenv.shell} -e + #! ${pkgs.runtimeShell} -e ${config.preStop} ''; }) (mkIf (config.postStop != "") { serviceConfig.ExecStopPost = makeJobScript "${name}-post-stop" '' - #! ${pkgs.stdenv.shell} -e + #! ${pkgs.runtimeShell} -e ${config.postStop} ''; }) diff --git a/nixos/modules/tasks/kbd.nix b/nixos/modules/tasks/kbd.nix index 7fb3cbc5c1b..fbe42b8e8f0 100644 --- a/nixos/modules/tasks/kbd.nix +++ b/nixos/modules/tasks/kbd.nix @@ -13,7 +13,7 @@ let isUnicode = hasSuffix "UTF-8" (toUpper config.i18n.defaultLocale); optimizedKeymap = pkgs.runCommand "keymap" { - nativeBuildInputs = [ pkgs.kbd ]; + nativeBuildInputs = [ pkgs.buildPackages.kbd ]; LOADKEYS_KEYMAP_PATH = "${kbdEnv}/share/keymaps/**"; } '' loadkeys -b ${optionalString isUnicode "-u"} "${config.i18n.consoleKeyMap}" > $out diff --git a/nixos/modules/tasks/network-interfaces.nix b/nixos/modules/tasks/network-interfaces.nix index 5036b701bd8..a2d2eb1c311 100644 --- a/nixos/modules/tasks/network-interfaces.nix +++ b/nixos/modules/tasks/network-interfaces.nix @@ -26,7 +26,7 @@ let executable = true; destination = "/bin/bridge-stp"; text = '' - #!${pkgs.stdenv.shell} -e + #!${pkgs.runtimeShell} -e export PATH="${pkgs.mstpd}/bin" BRIDGES=(${concatStringsSep " " (attrNames rstpBridges)}) @@ -64,7 +64,7 @@ let # udev script that configures a physical wlan device and adds virtual interfaces wlanDeviceUdevScript = device: interfaceList: pkgs.writeScript "wlan-${device}-udev-script" '' - #!${pkgs.stdenv.shell} + #!${pkgs.runtimeShell} # Change the wireless phy device to a predictable name. if [ -e "/sys/class/net/${device}/phy80211/name" ]; then @@ -142,7 +142,7 @@ let default = { }; example = { mtu = "1492"; window = "524288"; }; description = '' - Other route options. See the symbol <literal>OPTION</literal> + Other route options. See the symbol <literal>OPTIONS</literal> in the <literal>ip-route(8)</literal> manual page for the details. ''; }; @@ -191,7 +191,7 @@ let preferTempAddress = mkOption { type = types.bool; default = cfg.enableIPv6; - defaultText = literalExample "config.networking.enableIpv6"; + defaultText = literalExample "config.networking.enableIPv6"; description = '' When using SLAAC prefer a temporary (IPv6) address over the EUI-64 address for originating connections. This is used to reduce tracking. @@ -489,7 +489,7 @@ in networking.interfaces = mkOption { default = {}; example = - { eth0.ipv4 = [ { + { eth0.ipv4.addresses = [ { address = "131.211.84.78"; prefixLength = 25; } ]; @@ -1158,7 +1158,7 @@ in # The script creates the required, new WLAN interfaces interfaces and configures the # existing, default interface. curInterfaceScript = device: current: new: pkgs.writeScript "udev-run-script-wlan-interfaces-${device}.sh" '' - #!${pkgs.stdenv.shell} + #!${pkgs.runtimeShell} # Change the wireless phy device to a predictable name. ${pkgs.iw}/bin/iw phy `${pkgs.coreutils}/bin/cat /sys/class/net/$INTERFACE/phy80211/name` set name ${device} @@ -1177,7 +1177,7 @@ in # Udev script to execute for a new WLAN interface. The script configures the new WLAN interface. newInterfaceScript = device: new: pkgs.writeScript "udev-run-script-wlan-interfaces-${new._iName}.sh" '' - #!${pkgs.stdenv.shell} + #!${pkgs.runtimeShell} # Configure the new interface ${pkgs.iw}/bin/iw dev ${new._iName} set type ${new.type} ${optionalString (new.type == "mesh" && new.meshID!=null) "${pkgs.iw}/bin/iw dev ${device} set meshid ${new.meshID}"} diff --git a/nixos/modules/virtualisation/amazon-init.nix b/nixos/modules/virtualisation/amazon-init.nix index a7362423eb4..8032b2c6d7c 100644 --- a/nixos/modules/virtualisation/amazon-init.nix +++ b/nixos/modules/virtualisation/amazon-init.nix @@ -2,7 +2,7 @@ let script = '' - #!${pkgs.stdenv.shell} -eu + #!${pkgs.runtimeShell} -eu echo "attempting to fetch configuration from EC2 user data..." diff --git a/nixos/modules/virtualisation/azure-agent.nix b/nixos/modules/virtualisation/azure-agent.nix index 6817eb837a0..201d5f71ba3 100644 --- a/nixos/modules/virtualisation/azure-agent.nix +++ b/nixos/modules/virtualisation/azure-agent.nix @@ -47,7 +47,7 @@ let }; provisionedHook = pkgs.writeScript "provisioned-hook" '' - #!${pkgs.stdenv.shell} + #!${pkgs.runtimeShell} ${config.systemd.package}/bin/systemctl start provisioned.target ''; diff --git a/nixos/modules/virtualisation/containers.nix b/nixos/modules/virtualisation/containers.nix index 4038454b2d2..e54a5fe7d40 100644 --- a/nixos/modules/virtualisation/containers.nix +++ b/nixos/modules/virtualisation/containers.nix @@ -33,7 +33,7 @@ let in pkgs.writeScript "container-init" '' - #! ${pkgs.stdenv.shell} -e + #! ${pkgs.runtimeShell} -e # Initialise the container side of the veth pair. if [ "$PRIVATE_NETWORK" = 1 ]; then @@ -223,7 +223,7 @@ let serviceDirectives = cfg: { ExecReload = pkgs.writeScript "reload-container" '' - #! ${pkgs.stdenv.shell} -e + #! ${pkgs.runtimeShell} -e ${pkgs.nixos-container}/bin/nixos-container run "$INSTANCE" -- \ bash --login -c "''${SYSTEM_PATH:-/nix/var/nix/profiles/system}/bin/switch-to-configuration test" ''; diff --git a/nixos/modules/virtualisation/libvirtd.nix b/nixos/modules/virtualisation/libvirtd.nix index a369b7ddbe1..024db7f87c2 100644 --- a/nixos/modules/virtualisation/libvirtd.nix +++ b/nixos/modules/virtualisation/libvirtd.nix @@ -119,18 +119,10 @@ in { after = [ "systemd-udev-settle.service" ] ++ optional vswitch.enable "vswitchd.service"; - environment = { - LIBVIRTD_ARGS = ''--config "${configFile}" ${concatStringsSep " " cfg.extraOptions}''; - }; + environment.LIBVIRTD_ARGS = ''--config "${configFile}" ${concatStringsSep " " cfg.extraOptions}''; - path = with pkgs; [ - bridge-utils - dmidecode - dnsmasq - ebtables - cfg.qemuPackage # libvirtd requires qemu-img to manage disk images - ] - ++ optional vswitch.enable vswitch.package; + path = [ cfg.qemuPackage ] # libvirtd requires qemu-img to manage disk images + ++ optional vswitch.enable vswitch.package; preStart = '' mkdir -p /var/log/libvirt/qemu -m 755 diff --git a/nixos/modules/virtualisation/openvswitch.nix b/nixos/modules/virtualisation/openvswitch.nix index 4218a3840fc..38b138e0632 100644 --- a/nixos/modules/virtualisation/openvswitch.nix +++ b/nixos/modules/virtualisation/openvswitch.nix @@ -169,7 +169,7 @@ in { mkdir -p ${runDir}/ipsec/{etc/racoon,etc/init.d/,usr/sbin/} ln -fs ${pkgs.ipsecTools}/bin/setkey ${runDir}/ipsec/usr/sbin/setkey ln -fs ${pkgs.writeScript "racoon-restart" '' - #!${pkgs.stdenv.shell} + #!${pkgs.runtimeShell} /var/run/current-system/sw/bin/systemctl $1 racoon ''} ${runDir}/ipsec/etc/init.d/racoon ''; diff --git a/nixos/modules/virtualisation/qemu-vm.nix b/nixos/modules/virtualisation/qemu-vm.nix index 13d0eb7de5c..ee327ed805b 100644 --- a/nixos/modules/virtualisation/qemu-vm.nix +++ b/nixos/modules/virtualisation/qemu-vm.nix @@ -30,7 +30,7 @@ let # Shell script to start the VM. startVM = '' - #! ${pkgs.stdenv.shell} + #! ${pkgs.runtimeShell} NIX_DISK_IMAGE=$(readlink -f ''${NIX_DISK_IMAGE:-${config.virtualisation.diskImage}}) @@ -319,8 +319,8 @@ in networkingOptions = mkOption { default = [ - "-net nic,vlan=0,model=virtio" - "-net user,vlan=0\${QEMU_NET_OPTS:+,$QEMU_NET_OPTS}" + "-net nic,netdev=user.0,model=virtio" + "-netdev user,id=user.0\${QEMU_NET_OPTS:+,$QEMU_NET_OPTS}" ]; type = types.listOf types.str; description = '' @@ -434,9 +434,11 @@ in virtualisation.pathsInNixDB = [ config.system.build.toplevel ]; - # FIXME: Figure out how to make this work on non-x86 - virtualisation.qemu.options = - mkIf (pkgs.stdenv.isi686 || pkgs.stdenv.isx86_64) [ "-vga std" "-usbdevice tablet" ]; + # FIXME: Consolidate this one day. + virtualisation.qemu.options = mkMerge [ + (mkIf (pkgs.stdenv.isi686 || pkgs.stdenv.isx86_64) [ "-vga std" "-usb" "-device usb-tablet,bus=usb-bus.0" ]) + (mkIf (pkgs.stdenv.isArm || pkgs.stdenv.isAarch64) [ "-device virtio-gpu-pci" "-device usb-ehci,id=usb0" "-device usb-kbd" "-device usb-tablet" ]) + ]; # Mount the host filesystem via 9P, and bind-mount the Nix store # of the host into our own filesystem. We use mkVMOverride to diff --git a/nixos/modules/virtualisation/xen-dom0.nix b/nixos/modules/virtualisation/xen-dom0.nix index afc5a42f8b4..cf57868acef 100644 --- a/nixos/modules/virtualisation/xen-dom0.nix +++ b/nixos/modules/virtualisation/xen-dom0.nix @@ -241,6 +241,12 @@ in ''; target = "default/xendomains"; } + ] + ++ lib.optionals (builtins.compareVersions cfg.package.version "4.10" >= 0) [ + # in V 4.10 oxenstored requires /etc/xen/oxenstored.conf to start + { source = "${cfg.package}/etc/xen/oxenstored.conf"; + target = "xen/oxenstored.conf"; + } ]; # Xen provides udev rules. @@ -262,7 +268,7 @@ in mkdir -p /var/lib/xen # so we create them here unconditionally. grep -q control_d /proc/xen/capabilities ''; - serviceConfig = if cfg.package.version < "4.8" then + serviceConfig = if (builtins.compareVersions cfg.package.version "4.8" < 0) then { ExecStart = '' ${cfg.stored}${optionalString cfg.trace " -T /var/log/xen/xenstored-trace.log"} --no-fork ''; @@ -275,7 +281,7 @@ in NotifyAccess = "all"; }; postStart = '' - ${optionalString (cfg.package.version < "4.8") '' + ${optionalString (builtins.compareVersions cfg.package.version "4.8" < 0) '' time=0 timeout=30 # Wait for xenstored to actually come up, timing out after 30 seconds @@ -320,7 +326,7 @@ in serviceConfig = { ExecStart = '' ${cfg.package}/bin/xenconsoled\ - ${optionalString ((cfg.package.version >= "4.8")) " -i"}\ + ${optionalString ((builtins.compareVersions cfg.package.version "4.8" >= 0)) " -i"}\ ${optionalString cfg.trace " --log=all --log-dir=/var/log/xen"} ''; }; diff --git a/nixos/release-combined.nix b/nixos/release-combined.nix index 9d4a551a958..e010b532a68 100644 --- a/nixos/release-combined.nix +++ b/nixos/release-combined.nix @@ -52,17 +52,17 @@ in rec { (all nixos.dummy) (all nixos.manual) - nixos.iso_minimal.x86_64-linux - nixos.iso_minimal.i686-linux - nixos.iso_graphical.x86_64-linux - nixos.ova.x86_64-linux + nixos.iso_minimal.x86_64-linux or [] + nixos.iso_minimal.i686-linux or [] + nixos.iso_graphical.x86_64-linux or [] + nixos.ova.x86_64-linux or [] #(all nixos.tests.containers) - nixos.tests.chromium.x86_64-linux + nixos.tests.chromium.x86_64-linux or [] (all nixos.tests.firefox) (all nixos.tests.firewall) (all nixos.tests.gnome3) - nixos.tests.installer.zfsroot.x86_64-linux # ZFS is 64bit only + nixos.tests.installer.zfsroot.x86_64-linux or [] # ZFS is 64bit only (all nixos.tests.installer.lvm) (all nixos.tests.installer.luksroot) (all nixos.tests.installer.separateBoot) @@ -81,7 +81,7 @@ in rec { (all nixos.tests.boot.uefiUsb) (all nixos.tests.boot-stage1) (all nixos.tests.hibernate) - nixos.tests.docker.x86_64-linux + nixos.tests.docker.x86_64-linux or [] (all nixos.tests.ecryptfs) (all nixos.tests.env) (all nixos.tests.ipv6) diff --git a/nixos/release.nix b/nixos/release.nix index a7d373d1f7c..0b8d7318cd8 100644 --- a/nixos/release.nix +++ b/nixos/release.nix @@ -1,4 +1,4 @@ -{ nixpkgs ? { outPath = (import ../lib).cleanSource ./..; revCount = 56789; shortRev = "gfedcba"; } +{ nixpkgs ? { outPath = (import ../lib).cleanSource ./..; revCount = 130979; shortRev = "gfedcba"; } , stableBranch ? false , supportedSystems ? [ "x86_64-linux" "aarch64-linux" ] }: @@ -16,11 +16,15 @@ let inherit system; } // args); - callTestOnTheseSystems = systems: fn: args: forMatchingSystems systems (system: hydraJob (importTest fn args system)); - callTest = callTestOnTheseSystems supportedSystems; + # Note: only supportedSystems are considered. + callTestOnMatchingSystems = systems: fn: args: + forMatchingSystems + (intersectLists supportedSystems systems) + (system: hydraJob (importTest fn args system)); + callTest = callTestOnMatchingSystems supportedSystems; - callSubTests = callSubTestsOnTheseSystems supportedSystems; - callSubTestsOnTheseSystems = systems: fn: args: let + callSubTests = callSubTestsOnMatchingSystems supportedSystems; + callSubTestsOnMatchingSystems = systems: fn: args: let discover = attrs: let subTests = filterAttrs (const (hasAttr "test")) attrs; in mapAttrs (const (t: hydraJob t.test)) subTests; @@ -229,9 +233,9 @@ in rec { tests.boot-stage1 = callTest tests/boot-stage1.nix {}; tests.borgbackup = callTest tests/borgbackup.nix {}; tests.buildbot = callTest tests/buildbot.nix {}; - tests.cadvisor = callTestOnTheseSystems ["x86_64-linux"] tests/cadvisor.nix {}; - tests.ceph = callTestOnTheseSystems ["x86_64-linux"] tests/ceph.nix {}; - tests.chromium = (callSubTestsOnTheseSystems ["x86_64-linux"] tests/chromium.nix {}).stable; + tests.cadvisor = callTestOnMatchingSystems ["x86_64-linux"] tests/cadvisor.nix {}; + tests.ceph = callTestOnMatchingSystems ["x86_64-linux"] tests/ceph.nix {}; + tests.chromium = (callSubTestsOnMatchingSystems ["x86_64-linux"] tests/chromium.nix {}).stable or {}; tests.cjdns = callTest tests/cjdns.nix {}; tests.cloud-init = callTest tests/cloud-init.nix {}; tests.containers-ipv4 = callTest tests/containers-ipv4.nix {}; @@ -245,21 +249,21 @@ in rec { tests.containers-hosts = callTest tests/containers-hosts.nix {}; tests.containers-macvlans = callTest tests/containers-macvlans.nix {}; tests.couchdb = callTest tests/couchdb.nix {}; - tests.docker = callTestOnTheseSystems ["x86_64-linux"] tests/docker.nix {}; - tests.docker-tools = callTestOnTheseSystems ["x86_64-linux"] tests/docker-tools.nix {}; - tests.docker-edge = callTestOnTheseSystems ["x86_64-linux"] tests/docker-edge.nix {}; + tests.docker = callTestOnMatchingSystems ["x86_64-linux"] tests/docker.nix {}; + tests.docker-tools = callTestOnMatchingSystems ["x86_64-linux"] tests/docker-tools.nix {}; + tests.docker-edge = callTestOnMatchingSystems ["x86_64-linux"] tests/docker-edge.nix {}; tests.dovecot = callTest tests/dovecot.nix {}; - tests.dnscrypt-proxy = callTestOnTheseSystems ["x86_64-linux"] tests/dnscrypt-proxy.nix {}; + tests.dnscrypt-proxy = callTestOnMatchingSystems ["x86_64-linux"] tests/dnscrypt-proxy.nix {}; tests.ecryptfs = callTest tests/ecryptfs.nix {}; - tests.etcd = callTestOnTheseSystems ["x86_64-linux"] tests/etcd.nix {}; - tests.ec2-nixops = (callSubTestsOnTheseSystems ["x86_64-linux"] tests/ec2.nix {}).boot-ec2-nixops; - tests.ec2-config = (callSubTestsOnTheseSystems ["x86_64-linux"] tests/ec2.nix {}).boot-ec2-config; - tests.elk = callSubTestsOnTheseSystems ["x86_64-linux"] tests/elk.nix {}; + tests.etcd = callTestOnMatchingSystems ["x86_64-linux"] tests/etcd.nix {}; + tests.ec2-nixops = (callSubTestsOnMatchingSystems ["x86_64-linux"] tests/ec2.nix {}).boot-ec2-nixops or {}; + tests.ec2-config = (callSubTestsOnMatchingSystems ["x86_64-linux"] tests/ec2.nix {}).boot-ec2-config or {}; + tests.elk = callSubTestsOnMatchingSystems ["x86_64-linux"] tests/elk.nix {}; tests.env = callTest tests/env.nix {}; tests.ferm = callTest tests/ferm.nix {}; tests.firefox = callTest tests/firefox.nix {}; tests.firewall = callTest tests/firewall.nix {}; - tests.fleet = callTestOnTheseSystems ["x86_64-linux"] tests/fleet.nix {}; + tests.fleet = callTestOnMatchingSystems ["x86_64-linux"] tests/fleet.nix {}; tests.fwupd = callTest tests/fwupd.nix {}; #tests.gitlab = callTest tests/gitlab.nix {}; tests.gitolite = callTest tests/gitolite.nix {}; @@ -292,7 +296,7 @@ in rec { tests.kernel-copperhead = callTest tests/kernel-copperhead.nix {}; tests.kernel-latest = callTest tests/kernel-latest.nix {}; tests.kernel-lts = callTest tests/kernel-lts.nix {}; - tests.kubernetes = hydraJob (import tests/kubernetes/default.nix { system = "x86_64-linux"; }); + tests.kubernetes = callSubTestsOnMatchingSystems ["x86_64-linux"] tests/kubernetes/default.nix {}; tests.latestKernel.login = callTest tests/login.nix { latestKernel = true; }; tests.ldap = callTest tests/ldap.nix {}; #tests.lightdm = callTest tests/lightdm.nix {}; @@ -322,14 +326,14 @@ in rec { tests.nginx = callTest tests/nginx.nix { }; tests.nghttpx = callTest tests/nghttpx.nix { }; tests.nix-ssh-serve = callTest tests/nix-ssh-serve.nix { }; - tests.novacomd = callTestOnTheseSystems ["x86_64-linux"] tests/novacomd.nix { }; + tests.novacomd = callTestOnMatchingSystems ["x86_64-linux"] tests/novacomd.nix { }; tests.leaps = callTest tests/leaps.nix { }; tests.nsd = callTest tests/nsd.nix {}; tests.openssh = callTest tests/openssh.nix {}; tests.openldap = callTest tests/openldap.nix {}; tests.owncloud = callTest tests/owncloud.nix {}; tests.pam-oath-login = callTest tests/pam-oath-login.nix {}; - #tests.panamax = callTestOnTheseSystems ["x86_64-linux"] tests/panamax.nix {}; + #tests.panamax = callTestOnMatchingSystems ["x86_64-linux"] tests/panamax.nix {}; tests.peerflix = callTest tests/peerflix.nix {}; tests.php-pcre = callTest tests/php-pcre.nix {}; tests.postgresql = callSubTests tests/postgresql.nix {}; @@ -362,8 +366,9 @@ in rec { tests.tomcat = callTest tests/tomcat.nix {}; tests.udisks2 = callTest tests/udisks2.nix {}; tests.vault = callTest tests/vault.nix {}; - tests.virtualbox = callSubTestsOnTheseSystems ["x86_64-linux"] tests/virtualbox.nix {}; + tests.virtualbox = callSubTestsOnMatchingSystems ["x86_64-linux"] tests/virtualbox.nix {}; tests.wordpress = callTest tests/wordpress.nix {}; + tests.xautolock = callTest tests/xautolock.nix {}; tests.xfce = callTest tests/xfce.nix {}; tests.xmonad = callTest tests/xmonad.nix {}; tests.xrdp = callTest tests/xrdp.nix {}; diff --git a/nixos/tests/borgbackup.nix b/nixos/tests/borgbackup.nix index 123b02be725..36731773de2 100644 --- a/nixos/tests/borgbackup.nix +++ b/nixos/tests/borgbackup.nix @@ -1,21 +1,162 @@ -import ./make-test.nix ({ pkgs, ...}: { +import ./make-test.nix ({ pkgs, ... }: + +let + passphrase = "supersecret"; + dataDir = "/ran:dom/data"; + excludeFile = "not_this_file"; + keepFile = "important_file"; + keepFileData = "important_data"; + localRepo = "/root/back:up"; + archiveName = "my_archive"; + remoteRepo = "borg@server:."; # No need to specify path + privateKey = pkgs.writeText "id_ed25519" '' + -----BEGIN OPENSSH PRIVATE KEY----- + b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW + QyNTUxOQAAACBx8UB04Q6Q/fwDFjakHq904PYFzG9pU2TJ9KXpaPMcrwAAAJB+cF5HfnBe + RwAAAAtzc2gtZWQyNTUxOQAAACBx8UB04Q6Q/fwDFjakHq904PYFzG9pU2TJ9KXpaPMcrw + AAAEBN75NsJZSpt63faCuaD75Unko0JjlSDxMhYHAPJk2/xXHxQHThDpD9/AMWNqQer3Tg + 9gXMb2lTZMn0pelo8xyvAAAADXJzY2h1ZXR6QGt1cnQ= + -----END OPENSSH PRIVATE KEY----- + ''; + publicKey = '' + ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHHxQHThDpD9/AMWNqQer3Tg9gXMb2lTZMn0pelo8xyv root@client + ''; + privateKeyAppendOnly = pkgs.writeText "id_ed25519" '' + -----BEGIN OPENSSH PRIVATE KEY----- + b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW + QyNTUxOQAAACBacZuz1ELGQdhI7PF6dGFafCDlvh8pSEc4cHjkW0QjLwAAAJC9YTxxvWE8 + cQAAAAtzc2gtZWQyNTUxOQAAACBacZuz1ELGQdhI7PF6dGFafCDlvh8pSEc4cHjkW0QjLw + AAAEAAhV7wTl5dL/lz+PF/d4PnZXuG1Id6L/mFEiGT1tZsuFpxm7PUQsZB2Ejs8Xp0YVp8 + IOW+HylIRzhweORbRCMvAAAADXJzY2h1ZXR6QGt1cnQ= + -----END OPENSSH PRIVATE KEY----- + ''; + publicKeyAppendOnly = '' + ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFpxm7PUQsZB2Ejs8Xp0YVp8IOW+HylIRzhweORbRCMv root@client + ''; + +in { name = "borgbackup"; - meta = with pkgs.stdenv.lib.maintainers; { - maintainers = [ mic92 ]; + meta = with pkgs.stdenv.lib; { + maintainers = with maintainers; [ dotlambda ]; }; nodes = { - machine = { config, pkgs, ... }: { - environment.systemPackages = [ pkgs.borgbackup ]; + client = { config, pkgs, ... }: { + services.borgbackup.jobs = { + + local = rec { + paths = dataDir; + repo = localRepo; + preHook = '' + # Don't append a timestamp + archiveName="${archiveName}" + ''; + encryption = { + mode = "repokey"; + inherit passphrase; + }; + compression = "auto,zlib,9"; + prune.keep = { + within = "1y"; + yearly = 5; + }; + exclude = [ "*/${excludeFile}" ]; + postHook = "echo post"; + startAt = [ ]; # Do not run automatically + }; + + remote = { + paths = dataDir; + repo = remoteRepo; + encryption.mode = "none"; + startAt = [ ]; + environment.BORG_RSH = "ssh -oStrictHostKeyChecking=no -i /root/id_ed25519"; + }; + + remoteAppendOnly = { + paths = dataDir; + repo = remoteRepo; + encryption.mode = "none"; + startAt = [ ]; + environment.BORG_RSH = "ssh -oStrictHostKeyChecking=no -i /root/id_ed25519.appendOnly"; + }; + + }; + }; + + server = { config, pkgs, ... }: { + services.openssh = { + enable = true; + passwordAuthentication = false; + challengeResponseAuthentication = false; + }; + + services.borgbackup.repos.repo1 = { + authorizedKeys = [ publicKey ]; + path = "/data/borgbackup"; + }; + + # Second repo to make sure the authorizedKeys options are merged correctly + services.borgbackup.repos.repo2 = { + authorizedKeysAppendOnly = [ publicKeyAppendOnly ]; + path = "/data/borgbackup"; + quota = ".5G"; + }; }; }; testScript = '' - my $borg = "BORG_PASSPHRASE=supersecret borg"; - $machine->succeed("$borg init --encryption=repokey /tmp/backup"); - $machine->succeed("mkdir /tmp/data/ && echo 'data' >/tmp/data/file"); - $machine->succeed("$borg create --stats /tmp/backup::test /tmp/data"); - $machine->succeed("$borg extract /tmp/backup::test"); - $machine->succeed('c=$(cat data/file) && echo "c = $c" >&2 && [[ "$c" == "data" ]]'); + startAll; + + $client->fail('test -d "${remoteRepo}"'); + + $client->succeed("cp ${privateKey} /root/id_ed25519"); + $client->succeed("chmod 0600 /root/id_ed25519"); + $client->succeed("cp ${privateKeyAppendOnly} /root/id_ed25519.appendOnly"); + $client->succeed("chmod 0600 /root/id_ed25519.appendOnly"); + + $client->succeed("mkdir -p ${dataDir}"); + $client->succeed("touch ${dataDir}/${excludeFile}"); + $client->succeed("echo '${keepFileData}' > ${dataDir}/${keepFile}"); + + subtest "local", sub { + my $borg = "BORG_PASSPHRASE='${passphrase}' borg"; + $client->systemctl("start --wait borgbackup-job-local"); + $client->fail("systemctl is-failed borgbackup-job-local"); + # Make sure exactly one archive has been created + $client->succeed("c=\$($borg list '${localRepo}' | wc -l) && [[ \$c == '1' ]]"); + # Make sure excludeFile has been excluded + $client->fail("$borg list '${localRepo}::${archiveName}' | grep -qF '${excludeFile}'"); + # Make sure keepFile has the correct content + $client->succeed("$borg extract '${localRepo}::${archiveName}'"); + $client->succeed('c=$(cat ${dataDir}/${keepFile}) && [[ "$c" == "${keepFileData}" ]]'); + }; + + subtest "remote", sub { + my $borg = "BORG_RSH='ssh -oStrictHostKeyChecking=no -i /root/id_ed25519' borg"; + $server->waitForUnit("sshd.service"); + $client->waitForUnit("network.target"); + $client->systemctl("start --wait borgbackup-job-remote"); + $client->fail("systemctl is-failed borgbackup-job-remote"); + + # Make sure we can't access repos other than the specified one + $client->fail("$borg list borg\@server:wrong"); + + #TODO: Make sure that data is actually deleted + }; + + subtest "remoteAppendOnly", sub { + my $borg = "BORG_RSH='ssh -oStrictHostKeyChecking=no -i /root/id_ed25519.appendOnly' borg"; + $server->waitForUnit("sshd.service"); + $client->waitForUnit("network.target"); + $client->systemctl("start --wait borgbackup-job-remoteAppendOnly"); + $client->fail("systemctl is-failed borgbackup-job-remoteAppendOnly"); + + # Make sure we can't access repos other than the specified one + $client->fail("$borg list borg\@server:wrong"); + + #TODO: Make sure that data is not actually deleted + }; + ''; }) diff --git a/nixos/tests/common/letsencrypt.nix b/nixos/tests/common/letsencrypt.nix index 9b53d9d61a1..10cde45d18a 100644 --- a/nixos/tests/common/letsencrypt.nix +++ b/nixos/tests/common/letsencrypt.nix @@ -138,8 +138,8 @@ let boulder = let owner = "letsencrypt"; repo = "boulder"; - rev = "9866abab8962a591f06db457a4b84c518cc88243"; - version = "20170510"; + rev = "9c6a1f2adc4c26d925588f5ae366cfd4efb7813a"; + version = "20180129"; in pkgs.buildGoPackage rec { name = "${repo}-${version}"; @@ -147,7 +147,7 @@ let src = pkgs.fetchFromGitHub { name = "${name}-src"; inherit rev owner repo; - sha256 = "170m5cjngbrm36wi7wschqw8jzs7kxpcyzmshq3pcrmcpigrhna1"; + sha256 = "09kszswrifm9rc6idfaq0p1mz5w21as2qbc8gd5pphrq9cf9pn55"; }; postPatch = '' @@ -168,6 +168,18 @@ let cat "${snakeOilCa}/ca.pem" > test/test-ca.pem ''; + # Until vendored pkcs11 is go 1.9 compatible + preBuild = '' + rm -r go/src/github.com/letsencrypt/boulder/vendor/github.com/miekg/pkcs11 + ''; + + extraSrcs = map mkGoDep [ + { goPackagePath = "github.com/miekg/pkcs11"; + rev = "6dbd569b952ec150d1425722dbbe80f2c6193f83"; + sha256 = "1m8g6fx7df6hf6q6zsbyw1icjmm52dmsx28rgb0h930wagvngfwb"; + } + ]; + goPackagePath = "github.com/${owner}/${repo}"; buildInputs = [ pkgs.libtool ]; }; @@ -284,7 +296,11 @@ let ocsp-updater.after = [ "boulder-publisher" ]; ocsp-responder.args = "--config ${cfgDir}/ocsp-responder.json"; ct-test-srv = {}; - mail-test-srv.args = "--closeFirst 5"; + mail-test-srv.args = let + key = "${boulderSource}/test/mail-test-srv/minica-key.pem"; + crt = "${boulderSource}/test/mail-test-srv/minica.pem"; + in + "--closeFirst 5 --cert ${crt} --key ${key}"; }; commonPath = [ softhsm pkgs.mariadb goose boulder ]; diff --git a/nixos/tests/containers-tmpfs.nix b/nixos/tests/containers-tmpfs.nix index 564831fa273..873dd364369 100644 --- a/nixos/tests/containers-tmpfs.nix +++ b/nixos/tests/containers-tmpfs.nix @@ -1,7 +1,7 @@ # Test for NixOS' container support. import ./make-test.nix ({ pkgs, ...} : { - name = "containers-bridge"; + name = "containers-tmpfs"; meta = with pkgs.stdenv.lib.maintainers; { maintainers = [ ckampka ]; }; diff --git a/nixos/tests/docker-tools.nix b/nixos/tests/docker-tools.nix index e52a4c3f884..9135bca0f4f 100644 --- a/nixos/tests/docker-tools.nix +++ b/nixos/tests/docker-tools.nix @@ -10,7 +10,7 @@ import ./make-test.nix ({ pkgs, ... }: { docker = { config, pkgs, ... }: { virtualisation = { - diskSize = 1024; + diskSize = 2048; docker.enable = true; }; }; @@ -21,19 +21,29 @@ import ./make-test.nix ({ pkgs, ... }: { $docker->waitForUnit("sockets.target"); $docker->succeed("docker load --input='${pkgs.dockerTools.examples.bash}'"); - $docker->succeed("docker run ${pkgs.dockerTools.examples.bash.imageName} /bin/bash --version"); + $docker->succeed("docker run --rm ${pkgs.dockerTools.examples.bash.imageName} /bin/bash --version"); + $docker->succeed("docker rmi ${pkgs.dockerTools.examples.bash.imageName}"); + # Check if the nix store is correctly initialized by listing dependencies of the installed Nix binary $docker->succeed("docker load --input='${pkgs.dockerTools.examples.nix}'"); - $docker->succeed("docker run ${pkgs.dockerTools.examples.nix.imageName} /bin/nix-store -qR ${pkgs.nix}"); + $docker->succeed("docker run --rm ${pkgs.dockerTools.examples.nix.imageName} /bin/nix-store -qR ${pkgs.nix}"); + $docker->succeed("docker rmi ${pkgs.dockerTools.examples.nix.imageName}"); # To test the pullImage tool $docker->succeed("docker load --input='${pkgs.dockerTools.examples.nixFromDockerHub}'"); - $docker->succeed("docker run nixos/nix:1.11 nix-store --version"); + $docker->succeed("docker run --rm nixos/nix:1.11 nix-store --version"); + $docker->succeed("docker rmi nixos/nix:1.11"); # To test runAsRoot and entry point $docker->succeed("docker load --input='${pkgs.dockerTools.examples.nginx}'"); $docker->succeed("docker run --name nginx -d -p 8000:80 ${pkgs.dockerTools.examples.nginx.imageName}"); $docker->waitUntilSucceeds('curl http://localhost:8000/'); $docker->succeed("docker rm --force nginx"); + $docker->succeed("docker rmi '${pkgs.dockerTools.examples.nginx.imageName}'"); + + # An pulled image can be used as base image + $docker->succeed("docker load --input='${pkgs.dockerTools.examples.onTopOfPulledImage}'"); + $docker->succeed("docker run --rm ontopofpulledimage hello"); + $docker->succeed("docker rmi ontopofpulledimage"); ''; }) diff --git a/nixos/tests/grafana.nix b/nixos/tests/grafana.nix index 16b8181498a..d45776c3ee2 100644 --- a/nixos/tests/grafana.nix +++ b/nixos/tests/grafana.nix @@ -20,6 +20,6 @@ import ./make-test.nix ({ lib, ... }: $machine->start; $machine->waitForUnit("grafana.service"); $machine->waitForOpenPort(3000); - $machine->succeed("curl -sS http://127.0.0.1:3000/"); + $machine->succeed("curl -sSfL http://127.0.0.1:3000/"); ''; }) diff --git a/nixos/tests/keymap.nix b/nixos/tests/keymap.nix index eec674e227d..caa5f7107c2 100644 --- a/nixos/tests/keymap.nix +++ b/nixos/tests/keymap.nix @@ -50,38 +50,7 @@ let machine.i18n.consoleKeyMap = mkOverride 900 layout; machine.services.xserver.layout = mkOverride 900 layout; machine.imports = [ ./common/x11.nix extraConfig ]; - machine.services.xserver.displayManager.slim = { - enable = true; - - # Use a custom theme in order to get best OCR results - theme = pkgs.runCommand "slim-theme-ocr" { - nativeBuildInputs = [ pkgs.imagemagick ]; - } '' - mkdir "$out" - convert -size 1x1 xc:white "$out/background.jpg" - convert -size 200x100 xc:white "$out/panel.jpg" - cat > "$out/slim.theme" <<EOF - background_color #ffffff - background_style tile - - input_fgcolor #000000 - msg_color #000000 - - session_color #000000 - session_font Verdana:size=16:bold - - username_msg Username: - username_font Verdana:size=16:bold - username_color #000000 - username_x 50% - username_y 40% - - password_msg Password: - password_x 50% - password_y 40% - EOF - ''; - }; + machine.services.xserver.displayManager.slim.enable = true; testScript = '' sub waitCatAndDelete ($) { diff --git a/nixos/tests/printing.nix b/nixos/tests/printing.nix index 2d3ecaf94cf..98900883061 100644 --- a/nixos/tests/printing.nix +++ b/nixos/tests/printing.nix @@ -39,7 +39,9 @@ import ./make-test.nix ({pkgs, ... }: { $client->waitForUnit("cups.service"); $client->sleep(10); # wait until cups is fully initialized $client->succeed("lpstat -r") =~ /scheduler is running/ or die; - $client->succeed("lpstat -H") =~ "localhost:631" or die; + # Test that UNIX socket is used for connections. + $client->succeed("lpstat -H") =~ "/var/run/cups/cups.sock" or die; + # Test that HTTP server is available too. $client->succeed("curl --fail http://localhost:631/"); $client->succeed("curl --fail http://server:631/"); $server->fail("curl --fail --connect-timeout 2 http://client:631/"); diff --git a/nixos/tests/vault.nix b/nixos/tests/vault.nix index 2c08d06f286..515d5c8bac2 100644 --- a/nixos/tests/vault.nix +++ b/nixos/tests/vault.nix @@ -17,7 +17,7 @@ import ./make-test.nix ({ pkgs, ... }: $machine->waitForUnit('multi-user.target'); $machine->waitForUnit('vault.service'); $machine->waitForOpenPort(8200); - $machine->succeed('vault init'); - $machine->succeed('vault status | grep "Sealed: true"'); + $machine->succeed('vault operator init'); + $machine->succeed('vault status | grep Sealed | grep true'); ''; }) diff --git a/nixos/tests/virtualbox.nix b/nixos/tests/virtualbox.nix index 5574293ba37..249571fcede 100644 --- a/nixos/tests/virtualbox.nix +++ b/nixos/tests/virtualbox.nix @@ -43,6 +43,9 @@ let "init=${pkgs.writeScript "mini-init.sh" miniInit}" ]; + # XXX: Remove this once TSS location detection has been fixed in VirtualBox + boot.kernelPackages = pkgs.linuxPackages_4_9; + fileSystems."/" = { device = "vboxshare"; fsType = "vboxsf"; diff --git a/nixos/tests/xautolock.nix b/nixos/tests/xautolock.nix new file mode 100644 index 00000000000..ee46d9e05b0 --- /dev/null +++ b/nixos/tests/xautolock.nix @@ -0,0 +1,24 @@ +import ./make-test.nix ({ pkgs, lib, ... }: + +with lib; + +{ + name = "xautolock"; + meta.maintainers = with pkgs.stdenv.lib.maintainers; [ ma27 ]; + + nodes.machine = { + imports = [ ./common/x11.nix ./common/user-account.nix ]; + + services.xserver.displayManager.auto.user = "bob"; + services.xserver.xautolock.enable = true; + services.xserver.xautolock.time = 1; + }; + + testScript = '' + $machine->start; + $machine->waitForX; + $machine->mustFail("pgrep xlock"); + $machine->sleep(120); + $machine->mustSucceed("pgrep xlock"); + ''; +}) |