From f08abb15f11c029aec2d934056115e638e109375 Mon Sep 17 00:00:00 2001 From: Nikolay Amiantov Date: Wed, 10 Dec 2014 04:41:02 +0300 Subject: [PATCH 1/2] uwsgi: add package --- pkgs/servers/uwsgi/default.nix | 76 +++++++++++++++++++++++++++++++++ pkgs/servers/uwsgi/nixos.ini | 5 +++ pkgs/top-level/all-packages.nix | 4 ++ 3 files changed, 85 insertions(+) create mode 100644 pkgs/servers/uwsgi/default.nix create mode 100644 pkgs/servers/uwsgi/nixos.ini diff --git a/pkgs/servers/uwsgi/default.nix b/pkgs/servers/uwsgi/default.nix new file mode 100644 index 000000000000..60903314bf13 --- /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 000000000000..454eb51893fc --- /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 04a592a7e566..f3d670d6cc1b 100644 --- a/pkgs/top-level/all-packages.nix +++ b/pkgs/top-level/all-packages.nix @@ -2730,6 +2730,10 @@ let usbmuxd = callPackage ../tools/misc/usbmuxd {}; + uwsgi = callPackage ../servers/uwsgi { + plugins = []; + }; + vacuum = callPackage ../applications/networking/instant-messengers/vacuum {}; volatility = callPackage ../tools/security/volatility { }; From 51681449da1a44b49073445592804d846c1da8b1 Mon Sep 17 00:00:00 2001 From: Nikolay Amiantov Date: Wed, 10 Dec 2014 04:41:25 +0300 Subject: [PATCH 2/2] uwsgi: add nixos module --- nixos/modules/module-list.nix | 1 + nixos/modules/services/web-servers/uwsgi.nix | 112 +++++++++++++++++++ 2 files changed, 113 insertions(+) create mode 100644 nixos/modules/services/web-servers/uwsgi.nix diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index b949fef6bab7..96db850deb68 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -340,6 +340,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 000000000000..6e454a2dacd7 --- /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"; + }; + + }; + }; +}