Merge remote-tracking branch 'upstream/master' into fix-cross-jobs
This commit is contained in:
@@ -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"];
|
||||
}
|
||||
''
|
||||
|
||||
@@ -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";
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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" />
|
||||
|
||||
@@ -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>
|
||||
@@ -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 =
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
}
|
||||
@@ -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;
|
||||
};
|
||||
}
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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; };
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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";
|
||||
|
||||
@@ -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" ];
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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";
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -10,4 +10,10 @@
|
||||
password = "demo";
|
||||
uid = 1000;
|
||||
};
|
||||
|
||||
services.xserver.displayManager.sddm.autoLogin = {
|
||||
enable = true;
|
||||
relogin = true;
|
||||
user = "demo";
|
||||
};
|
||||
}
|
||||
|
||||
@@ -126,7 +126,7 @@ in
|
||||
programs.bash = {
|
||||
|
||||
shellInit = ''
|
||||
. ${config.system.build.setEnvironment}
|
||||
${config.system.build.setEnvironment.text}
|
||||
|
||||
${cfge.shellInit}
|
||||
'';
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 -"];
|
||||
};
|
||||
|
||||
}
|
||||
@@ -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}
|
||||
'';
|
||||
|
||||
@@ -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}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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";
|
||||
};
|
||||
|
||||
@@ -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 ];
|
||||
});
|
||||
}
|
||||
@@ -18,7 +18,7 @@ let
|
||||
hooksDir = let
|
||||
mkHookEntry = name: value: ''
|
||||
cat > $out/${name} <<EOF
|
||||
#! ${pkgs.stdenv.shell}
|
||||
#! ${pkgs.runtimeShell}
|
||||
set -e
|
||||
${value}
|
||||
EOF
|
||||
|
||||
@@ -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}
|
||||
'';
|
||||
|
||||
|
||||
@@ -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;
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
{
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 = ''
|
||||
|
||||
@@ -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()
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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 = {
|
||||
|
||||
@@ -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\"";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
@@ -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 \
|
||||
|
||||
@@ -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; } ''
|
||||
|
||||
@@ -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)"
|
||||
|
||||
@@ -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";;
|
||||
|
||||
@@ -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}"
|
||||
'';
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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}'
|
||||
'';
|
||||
|
||||
|
||||
@@ -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'
|
||||
'';
|
||||
};
|
||||
|
||||
@@ -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}";
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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";
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
'';
|
||||
};
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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";
|
||||
|
||||
@@ -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}"} \
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
-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
|
||||
${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 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 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 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 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 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 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 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
|
||||
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
|
||||
# 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)}
|
||||
|
||||
''
|
||||
) cfg.virtualHosts) }
|
||||
${optionalString cfg.axis2.enable ''
|
||||
# Copy the Axis2 web application
|
||||
cp -av ${pkgs.axis2}/webapps/axis2 ${cfg.baseDir}/webapps
|
||||
|
||||
# Create a work/ directory
|
||||
mkdir -p ${cfg.baseDir}/work
|
||||
chown ${cfg.user}:${cfg.group} ${cfg.baseDir}/work
|
||||
# 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
|
||||
|
||||
${if cfg.axis2.enable then
|
||||
''
|
||||
# Copy the Axis2 web application
|
||||
cp -av ${pkgs.axis2}/webapps/axis2 ${cfg.baseDir}/webapps
|
||||
# Modify permissions on the Axis2 application
|
||||
chown -R ${cfg.user}:${cfg.group} ${cfg.baseDir}/webapps/axis2
|
||||
|
||||
# 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
|
||||
# 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
|
||||
|
||||
# Modify permissions on the Axis2 application
|
||||
chown -R ${cfg.user}:${cfg.group} ${cfg.baseDir}/webapps/axis2
|
||||
for j in $i/webapps/axis2/WEB-INF/services/*; do
|
||||
ln -sfn $j ${cfg.baseDir}/webapps/axis2/WEB-INF/services/`basename $j`
|
||||
done
|
||||
|
||||
# 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
|
||||
# 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";
|
||||
};
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -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=$!
|
||||
'';
|
||||
}];
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -12,6 +12,7 @@ in
|
||||
./afterstep.nix
|
||||
./bspwm.nix
|
||||
./dwm.nix
|
||||
./evilwm.nix
|
||||
./exwm.nix
|
||||
./fluxbox.nix
|
||||
./fvwm.nix
|
||||
|
||||
@@ -61,7 +61,7 @@ in
|
||||
apply = set: {
|
||||
script =
|
||||
''
|
||||
#! ${pkgs.stdenv.shell}
|
||||
#! ${pkgs.runtimeShell}
|
||||
|
||||
systemConfig=@out@
|
||||
|
||||
|
||||
@@ -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"
|
||||
'';
|
||||
};
|
||||
|
||||
}
|
||||
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"
|
||||
'';
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
@@ -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} $@
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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";
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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}
|
||||
'';
|
||||
})
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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}"}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
let
|
||||
script = ''
|
||||
#!${pkgs.stdenv.shell} -eu
|
||||
#!${pkgs.runtimeShell} -eu
|
||||
|
||||
echo "attempting to fetch configuration from EC2 user data..."
|
||||
|
||||
|
||||
@@ -47,7 +47,7 @@ let
|
||||
};
|
||||
|
||||
provisionedHook = pkgs.writeScript "provisioned-hook" ''
|
||||
#!${pkgs.stdenv.shell}
|
||||
#!${pkgs.runtimeShell}
|
||||
${config.systemd.package}/bin/systemctl start provisioned.target
|
||||
'';
|
||||
|
||||
|
||||
@@ -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"
|
||||
'';
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
'';
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"}
|
||||
'';
|
||||
};
|
||||
|
||||
@@ -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)
|
||||
|
||||
+26
-21
@@ -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 {};
|
||||
|
||||
+152
-11
@@ -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
|
||||
};
|
||||
|
||||
'';
|
||||
})
|
||||
|
||||
@@ -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 ];
|
||||
|
||||
@@ -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 ];
|
||||
};
|
||||
|
||||
@@ -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");
|
||||
'';
|
||||
})
|
||||
|
||||
@@ -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/");
|
||||
'';
|
||||
})
|
||||
|
||||
+1
-32
@@ -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 ($) {
|
||||
|
||||
@@ -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/");
|
||||
|
||||
@@ -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');
|
||||
'';
|
||||
})
|
||||
|
||||
@@ -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";
|
||||
|
||||
@@ -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");
|
||||
'';
|
||||
})
|
||||
Reference in New Issue
Block a user