diff --git a/nixos/doc/manual/from_md/release-notes/rl-2205.section.xml b/nixos/doc/manual/from_md/release-notes/rl-2205.section.xml
index ce45b0d797756..a2d9204bb65e1 100644
--- a/nixos/doc/manual/from_md/release-notes/rl-2205.section.xml
+++ b/nixos/doc/manual/from_md/release-notes/rl-2205.section.xml
@@ -161,6 +161,13 @@
services.prosody-filer.
+
+
+ Swapspace,
+ dynamic swap management via swapfiles. Avaliable at
+ services.swapspace.
+
+
timetagger,
diff --git a/nixos/doc/manual/release-notes/rl-2205.section.md b/nixos/doc/manual/release-notes/rl-2205.section.md
index 25b3ada2c5630..4f1168c591565 100644
--- a/nixos/doc/manual/release-notes/rl-2205.section.md
+++ b/nixos/doc/manual/release-notes/rl-2205.section.md
@@ -49,6 +49,8 @@ In addition to numerous new and upgraded packages, this release has the followin
- [prosody-filer](https://github.com/ThomasLeister/prosody-filer), a server for handling XMPP HTTP Upload requests. Available at [services.prosody-filer](#opt-services.prosody-filer.enable).
+- [Swapspace](https://github.com/Tookmund/Swapspace), dynamic swap management via swapfiles. Avaliable at [services.swapspace](#opt-services.swapspace.enable).
+
- [timetagger](https://timetagger.app), an open source time-tracker with an intuitive user experience and powerful reporting. [services.timetagger](options.html#opt-services.timetagger.enable).
- [rstudio-server](https://www.rstudio.com/products/rstudio/#rstudio-server), a browser-based version of the RStudio IDE for the R programming language. Available as [services.rstudio-server](options.html#opt-services.rstudio-server.enable).
@@ -58,7 +60,7 @@ In addition to numerous new and upgraded packages, this release has the followin
## Backward Incompatibilities {#sec-release-22.05-incompatibilities}
- `pkgs.ghc` now refers to `pkgs.targetPackages.haskellPackages.ghc`.
- This *only* makes a difference if you are cross-compiling and will
+ This _only_ makes a difference if you are cross-compiling and will
ensure that `pkgs.ghc` always runs on the host platform and compiles
for the target platform (similar to `pkgs.gcc` for example).
`haskellPackages.ghc` still behaves as before, running on the build
@@ -158,7 +160,7 @@ In addition to numerous new and upgraded packages, this release has the followin
to allow users to make changes to the `nixos-rebuild build-vm` configuration
that do not apply to their normal system.
- The `config.system.build.vm` attribute now always exists and defaults to the
+ The `config.system.build.vm` attribute now always exists and defaults to the
value from `vmVariant`. Configurations that import the `virtualisation/qemu-vm.nix`
module themselves will override this value, such that `vmVariant` is not used.
@@ -207,8 +209,9 @@ In addition to numerous new and upgraded packages, this release has the followin
Plugins are automatically repackaged using autoPatchelf.
- The `zrepl` package has been updated from 0.4.0 to 0.5:
- * The RPC protocol version was bumped; all zrepl daemons in a setup must be updated and restarted before replication can resume.
- * A bug involving encrypt-on-receive has been fixed. Read the [zrepl documentation](https://zrepl.github.io/configuration/sendrecvoptions.html#job-recv-options-placeholder) and check the output of `zfs get -r encryption,zrepl:placeholder PATH_TO_ROOTFS` on the receiver.
+
+ - The RPC protocol version was bumped; all zrepl daemons in a setup must be updated and restarted before replication can resume.
+ - A bug involving encrypt-on-receive has been fixed. Read the [zrepl documentation](https://zrepl.github.io/configuration/sendrecvoptions.html#job-recv-options-placeholder) and check the output of `zfs get -r encryption,zrepl:placeholder PATH_TO_ROOTFS` on the receiver.
- Renamed option `services.openssh.challengeResponseAuthentication` to `services.openssh.kbdInteractiveAuthentication`.
Reason is that the old name has been deprecated upstream.
diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix
index fdf93f2e17c5d..f414088f57d6c 100644
--- a/nixos/modules/module-list.nix
+++ b/nixos/modules/module-list.nix
@@ -977,6 +977,7 @@
./services/system/nscd.nix
./services/system/saslauthd.nix
./services/system/self-deploy.nix
+ ./services/system/swapspace.nix
./services/system/uptimed.nix
./services/torrent/deluge.nix
./services/torrent/flexget.nix
diff --git a/nixos/modules/services/system/swapspace.nix b/nixos/modules/services/system/swapspace.nix
new file mode 100644
index 0000000000000..10058a5db888f
--- /dev/null
+++ b/nixos/modules/services/system/swapspace.nix
@@ -0,0 +1,87 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let cfg = config.services.swapspace;
+in {
+ ###### interface
+
+ options = {
+
+ services.swapspace = {
+ enable = mkOption {
+ type = types.bool;
+ default = false;
+ description = ''
+ Whether to create swapfiles dynamically using the SwapSpace manager.
+ Files will be added and removed based on current memory usage.
+ '';
+ };
+
+ path = mkOption {
+ type = types.path;
+ default = "/var/lib/swap";
+ description = ''
+ Location of the swap files. This directory will be restricted to root.
+ '';
+ };
+
+ cooldown = mkOption {
+ type = types.nullOr types.int;
+ default = null;
+ description = ''
+ Cooldown period between changes.
+ SwapSpace will wait at least this many seconds before an action,
+ like removing a swapfile after adding one.
+ '';
+ };
+
+ minSwapSize = mkOption {
+ type = types.nullOr types.int;
+ default = null;
+ description = ''
+ Minimum size of a swapfile.
+ '';
+ };
+
+ maxSwapSize = mkOption {
+ type = types.nullOr types.int;
+ default = null;
+ description = ''
+ Maximum size of a swapfile.
+ '';
+ };
+
+ extraArgs = mkOption {
+ type = types.str;
+ default = "";
+ description = ''
+ Any extra arguments to pass to SwapSpace.
+ '';
+ example = "-P -v -u 5";
+ };
+ };
+ };
+
+ ###### implementation
+
+ config = mkIf cfg.enable {
+ systemd.tmpfiles.rules = [ "d '${cfg.path}' 0700 - - - - " ];
+ systemd.services.swapspace = with pkgs; {
+ description = "SwapSpace Daemon";
+ serviceConfig = {
+ Type = "simple";
+ ExecStart = ''${pkgs.swapspace}/bin/swapspace --swappath="${cfg.path}"''
+ + optionalString (cfg.cooldown != null)
+ " --cooldown=${toString cfg.cooldown}"
+ + optionalString (cfg.minSwapSize != null)
+ " --min_swapsize=${toString cfg.minSwapSize}"
+ + optionalString (cfg.maxSwapSize != null)
+ " --max_swapsize=${toString cfg.maxSwapSize}" + " ${cfg.extraArgs}";
+ Restart = "always";
+ RestartSec = 30;
+ };
+ wantedBy = [ "multi-user.target" ];
+ };
+ };
+}
diff --git a/pkgs/os-specific/linux/swapspace/default.nix b/pkgs/os-specific/linux/swapspace/default.nix
new file mode 100644
index 0000000000000..48d27649cd1b4
--- /dev/null
+++ b/pkgs/os-specific/linux/swapspace/default.nix
@@ -0,0 +1,42 @@
+{ stdenv, lib, fetchFromGitHub, autoreconfHook, utillinux }:
+
+stdenv.mkDerivation rec {
+ pname = "swapspace";
+ version = "1.17";
+
+ src = fetchFromGitHub {
+ owner = "Tookmund";
+ repo = "Swapspace";
+ rev = "v${version}";
+ sha256 = "06xvmyy1fp94h00k9nn929j00ca3w12fiz07wf9az6srxa8i4ndz";
+ };
+
+ nativeBuildInputs = [ autoreconfHook ];
+
+ patchPhase = ''
+ sed -e 's@"mkswap"@"${utillinux}/bin/mkswap"@' \
+ -e 's@"/sbin/swapon"@"${utillinux}/bin/swapon"@' \
+ -e 's@"/sbin/swapoff"@"${utillinux}/bin/swapoff"@' \
+ -i src/support.c src/swaps.c
+ '';
+
+ postInstall = ''
+ mkdir $out/bin
+ mv $out/sbin/swapspace $out/bin/swapspace
+ # This should be an empty directory, fail if not
+ rmdir $out/sbin
+ rm -r $out/var
+ '';
+
+ enableParallelBuilding = true;
+
+ nativeBuildInputs = [ autoreconfHook ];
+
+ meta = with lib; {
+ homepage = "https://github.com/Tookmund/Swapspace";
+ description = "Dynamically add and remove swapfiles based on memory pressure";
+ license = licenses.gpl2;
+ maintainers = with maintainers; [ wmertens ];
+ platforms = platforms.linux;
+ };
+}