diff --git a/nixos/doc/manual/from_md/release-notes/rl-2111.section.xml b/nixos/doc/manual/from_md/release-notes/rl-2111.section.xml
index 7193429601bf..b5a3e27ab91e 100644
--- a/nixos/doc/manual/from_md/release-notes/rl-2111.section.xml
+++ b/nixos/doc/manual/from_md/release-notes/rl-2111.section.xml
@@ -479,6 +479,16 @@
RandomX benchmark.
+
+
+ Auto nice daemons
+ ananicy
+ and
+ ananicy-cpp.
+ Available as
+ services.ananicy.
+
+
diff --git a/nixos/doc/manual/release-notes/rl-2111.section.md b/nixos/doc/manual/release-notes/rl-2111.section.md
index d8807e85a68a..d4ff576fecf0 100644
--- a/nixos/doc/manual/release-notes/rl-2111.section.md
+++ b/nixos/doc/manual/release-notes/rl-2111.section.md
@@ -139,6 +139,8 @@ In addition to numerous new and upgraded packages, this release has the followin
- [xmrig](https://github.com/xmrig/xmrig), a high performance, open source, cross platform RandomX, KawPow, CryptoNight and AstroBWT unified CPU/GPU miner and RandomX benchmark.
+- Auto nice daemons [ananicy](https://github.com/Nefelim4ag/Ananicy) and [ananicy-cpp](https://gitlab.com/ananicy-cpp/ananicy-cpp/). Available as [services.ananicy](#opt-services.ananicy.enable).
+
## Backward Incompatibilities {#sec-release-21.11-incompatibilities}
- The NixOS VM test framework, `pkgs.nixosTest`/`make-test-python.nix`, now requires detaching commands such as `succeed("foo &")` and `succeed("foo | xclip -i")` to close stdout.
diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix
index c5f0b211ff84..c19dcd3293b6 100644
--- a/nixos/modules/module-list.nix
+++ b/nixos/modules/module-list.nix
@@ -485,6 +485,7 @@
./services/mail/roundcube.nix
./services/mail/sympa.nix
./services/mail/nullmailer.nix
+ ./services/misc/ananicy.nix
./services/misc/airsonic.nix
./services/misc/ankisyncd.nix
./services/misc/apache-kafka.nix
diff --git a/nixos/modules/services/misc/ananicy.nix b/nixos/modules/services/misc/ananicy.nix
new file mode 100644
index 000000000000..f76f534fb450
--- /dev/null
+++ b/nixos/modules/services/misc/ananicy.nix
@@ -0,0 +1,107 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+ cfg = config.services.ananicy;
+ configFile = pkgs.writeText "ananicy.conf" (generators.toKeyValue { } cfg.settings);
+ extraRules = pkgs.writeText "extraRules" cfg.extraRules;
+ servicename = if ((lib.getName cfg.package) == (lib.getName pkgs.ananicy-cpp)) then "ananicy-cpp" else "ananicy";
+in
+{
+ options = {
+ services.ananicy = {
+ enable = mkEnableOption "Ananicy, an auto nice daemon";
+
+ package = mkOption {
+ type = types.package;
+ default = pkgs.ananicy;
+ defaultText = literalExpression "pkgs.ananicy";
+ example = literalExpression "pkgs.ananicy-cpp";
+ description = ''
+ Which ananicy package to use.
+ '';
+ };
+
+ settings = mkOption {
+ type = with types; attrsOf (oneOf [ int bool str ]);
+ default = { };
+ example = {
+ apply_nice = false;
+ };
+ description = ''
+ See
+ '';
+ };
+
+ extraRules = mkOption {
+ type = types.str;
+ default = "";
+ description = ''
+ Extra rules in json format on separate lines. See:
+
+
+ '';
+ example = literalExpression ''
+ '''
+ { "name": "eog", "type": "Image-View" }
+ { "name": "fdupes", "type": "BG_CPUIO" }
+ '''
+ '';
+
+ };
+ };
+ };
+
+ config = mkIf cfg.enable {
+ environment = {
+ systemPackages = [ cfg.package ];
+ etc."ananicy.d".source = pkgs.runCommandLocal "ananicyfiles" { } ''
+ mkdir -p $out
+ # ananicy-cpp does not include rules or settings on purpose
+ cp -r ${pkgs.ananicy}/etc/ananicy.d/* $out
+ rm $out/ananicy.conf
+ cp ${configFile} $out/ananicy.conf
+ ${optionalString (cfg.extraRules != "") "cp ${extraRules} $out/nixRules.rules"}
+ '';
+ };
+
+ # ananicy and ananicy-cpp have different default settings
+ services.ananicy.settings =
+ let
+ mkOD = mkOptionDefault;
+ in
+ {
+ cgroup_load = mkOD true;
+ type_load = mkOD true;
+ rule_load = mkOD true;
+ apply_nice = mkOD true;
+ apply_ioclass = mkOD true;
+ apply_ionice = mkOD true;
+ apply_sched = mkOD true;
+ apply_oom_score_adj = mkOD true;
+ apply_cgroup = mkOD true;
+ } // (if ((lib.getName cfg.package) == (lib.getName pkgs.ananicy-cpp)) then {
+ # https://gitlab.com/ananicy-cpp/ananicy-cpp/-/blob/master/src/config.cpp#L12
+ loglevel = mkOD "warn"; # default is info but its spammy
+ cgroup_realtime_workaround = mkOD true;
+ } else {
+ # https://github.com/Nefelim4ag/Ananicy/blob/master/ananicy.d/ananicy.conf
+ check_disks_schedulers = mkOD true;
+ check_freq = mkOD 5;
+ });
+
+ systemd = {
+ # https://gitlab.com/ananicy-cpp/ananicy-cpp/#cgroups applies to both ananicy and -cpp
+ enableUnifiedCgroupHierarchy = mkDefault false;
+ packages = [ cfg.package ];
+ services."${servicename}" = {
+ wantedBy = [ "default.target" ];
+ };
+ };
+ };
+
+ meta = {
+ maintainers = with maintainers; [ artturin ];
+ };
+}
diff --git a/pkgs/misc/ananicy-cpp/default.nix b/pkgs/misc/ananicy-cpp/default.nix
new file mode 100644
index 000000000000..25bcaec13267
--- /dev/null
+++ b/pkgs/misc/ananicy-cpp/default.nix
@@ -0,0 +1,46 @@
+{ lib
+, gcc11Stdenv
+, fetchFromGitLab
+, makeWrapper
+, cmake
+, spdlog
+, nlohmann_json
+, systemd
+}:
+
+gcc11Stdenv.mkDerivation rec {
+ pname = "ananicy-cpp";
+ version = "unstable-2021-10-13";
+
+ src = fetchFromGitLab {
+ owner = "ananicy-cpp";
+ repo = "ananicy-cpp";
+ rev = "6a14fe7353221c89347eddbbcafb35cf5fee4758";
+ sha256 = "sha256-V0QPXC17ZD2c4MK3DAkzoPgKOU5V5BjfQKUk7I6f8WM=";
+ };
+
+ nativeBuildInputs = [
+ makeWrapper
+ cmake
+ ];
+
+ buildInputs = [
+ spdlog
+ nlohmann_json
+ systemd
+ ];
+
+ cmakeFlags = [
+ "-DUSE_EXTERNAL_JSON=yON"
+ "-DUSE_EXTERNAL_SPDLOG=ON"
+ "-DUSE_EXTERNAL_FMTLIB=ON"
+ ];
+
+ meta = with lib; {
+ homepage = "https://gitlab.com/ananicy-cpp/ananicy-cpp";
+ description = "Rewrite of ananicy in c++ for lower cpu and memory usage";
+ license = licenses.gpl3Only;
+ platforms = platforms.linux;
+ maintainers = with maintainers; [ artturin ];
+ };
+}
diff --git a/pkgs/misc/ananicy/default.nix b/pkgs/misc/ananicy/default.nix
new file mode 100644
index 000000000000..3c2392df731d
--- /dev/null
+++ b/pkgs/misc/ananicy/default.nix
@@ -0,0 +1,58 @@
+{ lib, stdenv, python3, fetchFromGitHub, makeWrapper, schedtool, sysctl, util-linux, fetchpatch }:
+
+stdenv.mkDerivation rec {
+ pname = "ananicy";
+ version = "unstable-2021-11-05";
+
+ src = fetchFromGitHub {
+ owner = "nefelim4ag";
+ repo = "ananicy";
+ rev = "b8968e9b32b0e4e6a01dc2314e43de8fee9da691";
+ sha256 = "sha256-tlPY81xdUpZrDYdApXooZ0Mst0n7ARVHyUrmymqg0rk=";
+ };
+
+ patches = [
+ # https://github.com/Nefelim4ag/Ananicy/pull/437
+ # fix makefile destinations
+ (fetchpatch {
+ url = "https://github.com/Nefelim4ag/Ananicy/commit/dbda0f50670de3f249991706ef1cc107c5197a2f.patch";
+ sha256 = "sha256-vMcJxekg2QUbm253CLAv3tmo5kedSlw+/PI/LamNWwc=";
+ # only used for debian packaging. lets exclude it so the patch applies even when that file is changed
+ excludes = [ "package.sh" ];
+ })
+ # https://github.com/Nefelim4ag/Ananicy/pull/439
+ # fix syntax error
+ (fetchpatch {
+ url = "https://github.com/Nefelim4ag/Ananicy/commit/0f8b809298ccfd88d0e2ab952d6e4131865246da.patch";
+ sha256 = "sha256-PWE4F0G97gecgc9HnG7ScA78+QVc8u8aF9u74qVChX0=";
+ })
+ ];
+
+ nativeBuildInputs = [ makeWrapper ];
+ buildInputs = [ python3 ];
+
+ makeFlags = [
+ "PREFIX=$(out)"
+ "SYSCONFDIR=${placeholder "out"}/etc"
+ ];
+
+ dontConfigure = true;
+ dontBuild = true;
+
+ postInstall = ''
+ wrapProgram $out/bin/ananicy \
+ --prefix PATH : ${lib.makeBinPath [ schedtool util-linux ]}
+
+ substituteInPlace $out/lib/systemd/system/ananicy.service \
+ --replace "/sbin/sysctl" "${sysctl}/bin/sysctl" \
+ --replace "/usr/bin/ananicy" "$out/bin/ananicy"
+ '';
+
+ meta = with lib; {
+ homepage = "https://github.com/Nefelim4ag/Ananicy";
+ description = "Another auto nice daemon, with community rules support";
+ license = licenses.gpl3Only;
+ platforms = platforms.linux;
+ maintainers = with maintainers; [ artturin ];
+ };
+}
diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix
index 23dc8bcbca14..3dba1b7796df 100644
--- a/pkgs/top-level/all-packages.nix
+++ b/pkgs/top-level/all-packages.nix
@@ -22791,6 +22791,10 @@ with pkgs;
anarchism = callPackage ../data/documentation/anarchism { };
+ ananicy = callPackage ../misc/ananicy { };
+
+ ananicy-cpp = callPackage ../misc/ananicy-cpp { };
+
andagii = callPackage ../data/fonts/andagii { };
andika = callPackage ../data/fonts/andika { };