diff --git a/maintainers/maintainer-list.nix b/maintainers/maintainer-list.nix
index 1d6d772e7e95..1800c6d8f49a 100644
--- a/maintainers/maintainer-list.nix
+++ b/maintainers/maintainer-list.nix
@@ -23,6 +23,11 @@
github = "a1russell";
name = "Adam Russell";
};
+ aanderse = {
+ email = "aaron@fosslib.net";
+ github = "aanderse";
+ name = "Aaron Andersen";
+ };
aaronschif = {
email = "aaronschif@gmail.com";
github = "aaronschif";
diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix
index 6bad54d6d433..93e6050e1dde 100644
--- a/nixos/modules/module-list.nix
+++ b/nixos/modules/module-list.nix
@@ -421,6 +421,7 @@
./services/monitoring/graphite.nix
./services/monitoring/hdaps.nix
./services/monitoring/heapster.nix
+ ./services/monitoring/incron.nix
./services/monitoring/longview.nix
./services/monitoring/monit.nix
./services/monitoring/munin.nix
diff --git a/nixos/modules/services/monitoring/incron.nix b/nixos/modules/services/monitoring/incron.nix
new file mode 100644
index 000000000000..1789fd9f2051
--- /dev/null
+++ b/nixos/modules/services/monitoring/incron.nix
@@ -0,0 +1,98 @@
+
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+
+ cfg = config.services.incron;
+
+in
+
+{
+ options = {
+
+ services.incron = {
+
+ enable = mkOption {
+ type = types.bool;
+ default = false;
+ description = ''
+ Whether to enable the incron daemon.
+
+ Note that commands run under incrontab only support common Nix profiles for the PATH provided variable.
+ '';
+ };
+
+ allow = mkOption {
+ type = types.nullOr (types.listOf types.str);
+ default = null;
+ description = ''
+ Users allowed to use incrontab.
+
+ If empty then no user will be allowed to have their own incrontab.
+ If null then will defer to .
+ If both and are null
+ then all users will be allowed to have their own incrontab.
+ '';
+ };
+
+ deny = mkOption {
+ type = types.nullOr (types.listOf types.str);
+ default = null;
+ description = "Users forbidden from using incrontab.";
+ };
+
+ systab = mkOption {
+ type = types.lines;
+ default = "";
+ description = "The system incrontab contents.";
+ example = ''
+ /var/mail IN_CLOSE_WRITE abc $@/$#
+ /tmp IN_ALL_EVENTS efg $@/$# $&
+ '';
+ };
+
+ extraPackages = mkOption {
+ type = types.listOf types.package;
+ default = [];
+ example = literalExample "[ pkgs.rsync ]";
+ description = "Extra packages available to the system incrontab.";
+ };
+
+ };
+
+ };
+
+ config = mkIf cfg.enable {
+
+ warnings = optional (cfg.allow != null && cfg.deny != null)
+ ''If `services.incron.allow` is set then `services.incron.deny` will be ignored.'';
+
+ environment.systemPackages = [ pkgs.incron ];
+
+ security.wrappers.incrontab.source = "${pkgs.incron}/bin/incrontab";
+
+ # incron won't read symlinks
+ environment.etc."incron.d/system" = {
+ mode = "0444";
+ text = cfg.systab;
+ };
+ environment.etc."incron.allow" = mkIf (cfg.allow != null) {
+ text = concatStringsSep "\n" cfg.allow;
+ };
+ environment.etc."incron.deny" = mkIf (cfg.deny != null) {
+ text = concatStringsSep "\n" cfg.deny;
+ };
+
+ systemd.services.incron = {
+ description = "File System Events Scheduler";
+ wantedBy = [ "multi-user.target" ];
+ path = cfg.extraPackages;
+ serviceConfig.PIDFile = "/run/incrond.pid";
+ serviceConfig.ExecStartPre = "${pkgs.coreutils}/bin/mkdir -m 710 -p /var/spool/incron";
+ serviceConfig.ExecStart = "${pkgs.incron}/bin/incrond --foreground";
+ };
+ };
+
+}
diff --git a/pkgs/tools/system/incron/default.nix b/pkgs/tools/system/incron/default.nix
new file mode 100644
index 000000000000..2afbed2f9bb2
--- /dev/null
+++ b/pkgs/tools/system/incron/default.nix
@@ -0,0 +1,36 @@
+{ stdenv, fetchFromGitHub, bash }:
+
+stdenv.mkDerivation rec {
+ name = "incron-0.5.12";
+ src = fetchFromGitHub {
+ owner = "ar-";
+ repo = "incron";
+ rev = name;
+ sha256 = "11d5f98cjafiv9h9zzzrw2s06s2fvdg8gp64km7mdprd2xmy6dih";
+ };
+
+ patches = [ ./default_path.patch ];
+
+ prePatch = ''
+ sed -i "s|/bin/bash|${bash}/bin/bash|g" usertable.cpp
+ '';
+
+ installFlags = [ "PREFIX=$(out)" ];
+ installTargets = [ "install-man" ];
+
+ preInstall = ''
+ mkdir -p $out/bin
+
+ # make install doesn't work because setuid and permissions
+ # just manually install the binaries instead
+ cp incrond incrontab $out/bin/
+ '';
+
+ meta = with stdenv.lib; {
+ description = "A cron-like daemon which handles filesystem events.";
+ homepage = https://github.com/ar-/incron;
+ license = licenses.gpl2;
+ maintainers = [ maintainers.aanderse ];
+ platforms = platforms.linux;
+ };
+}
diff --git a/pkgs/tools/system/incron/default_path.patch b/pkgs/tools/system/incron/default_path.patch
new file mode 100644
index 000000000000..ae173ea29e62
--- /dev/null
+++ b/pkgs/tools/system/incron/default_path.patch
@@ -0,0 +1,36 @@
+diff --git usertable.cpp usertable.cpp
+index 11fd04b..a8681bd 100644
+--- a/usertable.cpp
++++ b/usertable.cpp
+@@ -43,9 +43,6 @@
+ #define DONT_FOLLOW(mask) (false)
+ #endif // IN_DONT_FOLLOW
+
+-// this is not enough, but...
+-#define DEFAULT_PATH "/usr/local/bin:/usr/bin:/bin:/usr/X11R6/bin"
+-
+
+ PROC_MAP UserTable::s_procMap;
+
+@@ -597,12 +594,20 @@ void UserTable::RunAsUser(std::string cmd) const
+ if (clearenv() != 0)
+ goto failed;
+
++ // try to recreate the user path as best as possible
++ std::string DEFAULT_PATH;
++ DEFAULT_PATH += "/run/wrappers/bin:";
++ DEFAULT_PATH += pwd->pw_dir;
++ DEFAULT_PATH += "/.nix-profile/bin:/nix/var/nix/profiles/default/bin:/run/current-system/sw/bin:/etc/profiles/per-user/";
++ DEFAULT_PATH += pwd->pw_name;
++ DEFAULT_PATH += "/bin";
++
+ if ( setenv("LOGNAME", pwd->pw_name, 1) != 0
+ || setenv("USER", pwd->pw_name, 1) != 0
+ || setenv("USERNAME", pwd->pw_name, 1) != 0
+ || setenv("HOME", pwd->pw_dir, 1) != 0
+ || setenv("SHELL", pwd->pw_shell, 1) != 0
+- || setenv("PATH", DEFAULT_PATH, 1) != 0)
++ || setenv("PATH", DEFAULT_PATH.c_str(), 1) != 0)
+ {
+ goto failed;
+ }
diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix
index 60147e724ee5..915239c7d2fa 100644
--- a/pkgs/top-level/all-packages.nix
+++ b/pkgs/top-level/all-packages.nix
@@ -3267,6 +3267,8 @@ with pkgs;
inboxer = callPackage ../applications/networking/mailreaders/inboxer { };
+ incron = callPackage ../tools/system/incron { };
+
inetutils = callPackage ../tools/networking/inetutils { };
infiniband-diags = callPackage ../tools/networking/infiniband-diags { };