diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix
index dc97e7203ba..023a053cf9b 100644
--- a/nixos/modules/module-list.nix
+++ b/nixos/modules/module-list.nix
@@ -342,6 +342,7 @@
./services/web-servers/nginx/default.nix
./services/web-servers/phpfpm.nix
./services/web-servers/tomcat.nix
+ ./services/web-servers/uwsgi.nix
./services/web-servers/varnish/default.nix
./services/web-servers/winstone.nix
./services/web-servers/zope2.nix
diff --git a/nixos/modules/services/web-servers/uwsgi.nix b/nixos/modules/services/web-servers/uwsgi.nix
new file mode 100644
index 00000000000..6e454a2dacd
--- /dev/null
+++ b/nixos/modules/services/web-servers/uwsgi.nix
@@ -0,0 +1,112 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+ cfg = config.services.uwsgi;
+
+ python2Pkgs = pkgs.python2Packages.override {
+ python = pkgs.uwsgi.python2;
+ self = python2Pkgs;
+ };
+
+ python3Pkgs = pkgs.python3Packages.override {
+ python = pkgs.uwsgi.python3;
+ self = python3Pkgs;
+ };
+
+ buildCfg = c: if builtins.typeOf c != "set" then builtins.readFile c else builtins.toJSON {
+ uwsgi =
+ if c.type == "normal"
+ then {
+ pythonpath =
+ (if c ? python2Packages
+ then builtins.map (x: "${x}/${pkgs.uwsgi.python2.sitePackages}") (c.python2Packages python2Pkgs)
+ else [])
+ ++ (if c ? python3Packages
+ then builtins.map (x: "${x}/${pkgs.uwsgi.python3.sitePackages}") (c.python3Packages python3Pkgs)
+ else []);
+ plugins = cfg.plugins;
+ } // removeAttrs c [ "type" "python2Packages" "python3Packages" ]
+ else if c.type == "emperor"
+ then {
+ emperor = if builtins.typeOf c.vassals != "set" then c.vassals
+ else pkgs.buildEnv {
+ name = "vassals";
+ paths = mapAttrsToList (n: c: pkgs.writeTextDir "${n}.json" (buildCfg c)) c.vassals;
+ };
+ } // removeAttrs c [ "type" "vassals" ]
+ else abort "type should be either 'normal' or 'emperor'";
+ };
+
+ uwsgi = pkgs.uwsgi.override {
+ plugins = cfg.plugins;
+ };
+
+in {
+
+ options = {
+ services.uwsgi = {
+
+ enable = mkOption {
+ type = types.bool;
+ default = false;
+ description = "Enable uWSGI";
+ };
+
+ instance = mkOption {
+ type = types.attrs;
+ default = {
+ type = "normal";
+ };
+ example = literalExample ''
+ {
+ type = "emperor";
+ vassals = {
+ moin = {
+ type = "normal";
+ python2Packages = self: with self; [ moinmoin ];
+ socket = "/run/uwsgi.sock";
+ };
+ };
+ }
+ '';
+ description = ''
+ uWSGI configuration. This awaits either a path to file or a set which will be made into one.
+ If given a set, it awaits an attribute type which can be either normal
+ or emperor.
+
+ For normal mode you can specify python2Packages and
+ python3Packages as functions from libraries set into lists of libraries.
+ For emperor mode, you should use vassals attribute
+ which should be either a set of names and configurations or a path to a directory.
+ '';
+ };
+
+ plugins = mkOption {
+ type = types.listOf types.str;
+ default = [];
+ description = "Plugins used with uWSGI";
+ };
+
+ };
+
+ };
+
+ config = mkIf cfg.enable {
+
+ systemd.services.uwsgi = {
+ wantedBy = [ "multi-user.target" ];
+
+ serviceConfig = {
+ Type = "notify";
+ ExecStart = "${uwsgi}/bin/uwsgi --json ${pkgs.writeText "uwsgi.json" (buildCfg cfg.instance)}";
+ ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID";
+ ExecStop = "${pkgs.coreutils}/bin/kill -INT $MAINPID";
+ NotifyAccess = "main";
+ KillSignal = "SIGQUIT";
+ };
+
+ };
+ };
+}
diff --git a/pkgs/servers/uwsgi/default.nix b/pkgs/servers/uwsgi/default.nix
new file mode 100644
index 00000000000..60903314bf1
--- /dev/null
+++ b/pkgs/servers/uwsgi/default.nix
@@ -0,0 +1,76 @@
+{ stdenv, lib, fetchurl, pkgconfig, jansson
+, plugins
+, pam, withPAM ? stdenv.isLinux
+, systemd, withSystemd ? stdenv.isLinux
+, python2, python3, ncurses
+}:
+
+let pythonPlugin = pkg : { name = "python${if pkg ? isPy2 then "2" else "3"}";
+ interpreter = pkg;
+ path = "plugins/python";
+ deps = [ pkg ncurses ];
+ install = ''
+ install -Dm644 uwsgidecorators.py $out/${pkg.sitePackages}/uwsgidecorators.py
+ ${pkg.executable} -m compileall $out/${pkg.sitePackages}/
+ ${pkg.executable} -O -m compileall $out/${pkg.sitePackages}/
+ '';
+ };
+ available = [ (pythonPlugin python2)
+ (pythonPlugin python3)
+ ];
+ needed = builtins.filter (x: lib.any (y: x.name == y) plugins) available;
+in
+
+assert builtins.filter (x: lib.all (y: y.name != x) available) plugins == [];
+
+stdenv.mkDerivation rec {
+ name = "uwsgi-2.0.9";
+
+ src = fetchurl {
+ url = "http://projects.unbit.it/downloads/${name}.tar.gz";
+ sha256 = "15c2j5myx1s54a1f6a7pjblvk7v96mz2kqlbj19mdfd8l2y8j17y";
+ };
+
+ nativeBuildInputs = [ python3 pkgconfig ];
+
+ buildInputs = with stdenv.lib;
+ [ jansson ]
+ ++ optional withPAM pam
+ ++ optional withSystemd systemd
+ ++ lib.concatMap (x: x.deps) needed
+ ;
+
+ basePlugins = with stdenv.lib;
+ concatStringsSep ","
+ ( optional withPAM "pam"
+ ++ optional withSystemd "systemd_logger"
+ );
+
+ passthru = {
+ inherit python2 python3;
+ };
+
+ configurePhase = ''
+ export pluginDir=$out/lib/uwsgi
+ substituteAll ${./nixos.ini} buildconf/nixos.ini
+ '';
+
+ buildPhase = ''
+ mkdir -p $pluginDir
+ python3 uwsgiconfig.py --build nixos
+ ${lib.concatMapStringsSep ";" (x: "${x.interpreter.interpreter} uwsgiconfig.py --plugin ${x.path} nixos ${x.name}") needed}
+ '';
+
+ installPhase = ''
+ install -Dm755 uwsgi $out/bin/uwsgi
+ #cp *_plugin.so $pluginDir || true
+ ${lib.concatMapStringsSep "\n" (x: x.install) needed}
+ '';
+
+ meta = with stdenv.lib; {
+ homepage = http://uwsgi-docs.readthedocs.org/en/latest/;
+ description = "A fast, self-healing and developer/sysadmin-friendly application container server coded in pure C";
+ license = licenses.gpl2;
+ maintainers = with maintainers; [ abbradar ];
+ };
+}
diff --git a/pkgs/servers/uwsgi/nixos.ini b/pkgs/servers/uwsgi/nixos.ini
new file mode 100644
index 00000000000..454eb51893f
--- /dev/null
+++ b/pkgs/servers/uwsgi/nixos.ini
@@ -0,0 +1,5 @@
+[uwsgi]
+plugin_dir = @pluginDir@
+main_plugin = @basePlugins@
+json = true
+inherit = base
diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix
index 3e700a80855..4ac6232575d 100644
--- a/pkgs/top-level/all-packages.nix
+++ b/pkgs/top-level/all-packages.nix
@@ -2736,6 +2736,10 @@ let
usbmuxd = callPackage ../tools/misc/usbmuxd {};
+ uwsgi = callPackage ../servers/uwsgi {
+ plugins = [];
+ };
+
vacuum = callPackage ../applications/networking/instant-messengers/vacuum {};
volatility = callPackage ../tools/security/volatility { };