diff options
author | Nikolay Amiantov <ab@fmap.me> | 2016-02-19 17:02:14 +0300 |
---|---|---|
committer | Nikolay Amiantov <ab@fmap.me> | 2016-02-19 18:09:26 +0300 |
commit | e48c991131b4f75445e79b4da8871ae721339ae2 (patch) | |
tree | bc0f9870449cdb391f4f7091092b783d1d90893c | |
parent | d39d87bb812fcd63a551b207bb0c66022048aed9 (diff) | |
download | nixlib-e48c991131b4f75445e79b4da8871ae721339ae2.tar nixlib-e48c991131b4f75445e79b4da8871ae721339ae2.tar.gz nixlib-e48c991131b4f75445e79b4da8871ae721339ae2.tar.bz2 nixlib-e48c991131b4f75445e79b4da8871ae721339ae2.tar.lz nixlib-e48c991131b4f75445e79b4da8871ae721339ae2.tar.xz nixlib-e48c991131b4f75445e79b4da8871ae721339ae2.tar.zst nixlib-e48c991131b4f75445e79b4da8871ae721339ae2.zip |
uwsgi service: refactor, throw more errors and drop simultaneous Python 2/3 in path
-rw-r--r-- | nixos/modules/services/web-servers/uwsgi.nix | 110 |
1 files changed, 76 insertions, 34 deletions
diff --git a/nixos/modules/services/web-servers/uwsgi.nix b/nixos/modules/services/web-servers/uwsgi.nix index 3e18a6f0e986..39f7047af2da 100644 --- a/nixos/modules/services/web-servers/uwsgi.nix +++ b/nixos/modules/services/web-servers/uwsgi.nix @@ -5,43 +5,85 @@ with lib; let cfg = config.services.uwsgi; - python2Pkgs = pkgs.python2Packages.override { - python = pkgs.uwsgi.python2; - self = python2Pkgs; + uwsgi = pkgs.uwsgi.override { + plugins = cfg.plugins; }; - python3Pkgs = pkgs.python3Packages.override { - python = pkgs.uwsgi.python3; - self = python3Pkgs; - }; + buildCfg = name: c: + let + plugins = + if any (n: !any (m: m == n) cfg.plugins) (c.plugins or []) + then throw "`plugins` attribute in UWSGI configuration contains plugins not in config.services.uwsgi.plugins" + else c.plugins or cfg.plugins; + + hasPython = v: filter (n: n == "python${v}") plugins != []; + hasPython2 = hasPython "2"; + hasPython3 = hasPython "3"; + + python = + if hasPython2 && hasPython3 then + throw "`plugins` attribute in UWSGI configuration shouldn't contain both python2 and python3" + else if hasPython2 then uwsgi.python2 + else if hasPython3 then uwsgi.python3 + else null; + + pythonPackages = pkgs.pythonPackages.override { + inherit python; + self = pythonPackages; + }; - 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'"; - }; + json = builtins.toJSON { + uwsgi = + if c.type == "normal" + then { + inherit plugins; + } // removeAttrs c [ "type" "pythonPackages" ] + // optionalAttrs (python != null) { + pythonpath = "@PYTHONPATH@"; + env = (c.env or {}) // { + PATH = optionalString (c ? env.PATH) "${c.env.PATH}:" + "@PATH@"; + }; + } + else if c.type == "emperor" + then { + emperor = if builtins.typeOf c.vassals != "set" then c.vassals + else pkgs.buildEnv { + name = "vassals"; + paths = mapAttrsToList buildCfg c.vassals; + }; + } // removeAttrs c [ "type" "vassals" ] + else throw "`type` attribute in UWSGI configuration should be either 'normal' or 'emperor'"; + }; - uwsgi = pkgs.uwsgi.override { - plugins = cfg.plugins; - }; + in + if python == null || c.type != "normal" + then pkgs.writeTextDir "${name}.json" json + else pkgs.stdenv.mkDerivation { + name = "uwsgi-config"; + inherit json; + passAsFile = [ "json" ]; + nativeBuildInputs = [ pythonPackages.wrapPython ]; + pythonInputs = (c.pythonPackages or (self: [])) pythonPackages; + + buildCommand = '' + mkdir $out + declare -A pythonPathsSeen=() + program_PYTHONPATH= + program_PATH= + if [ -n "$pythonInputs" ]; then + for i in $pythonInputs; do + _addToPythonPath $i + done + fi + # A hack to replace "@PYTHONPATH@" with a JSON list + if [ -n "$program_PYTHONPATH" ]; then + program_PYTHONPATH="\"''${program_PYTHONPATH//:/\",\"}\"" + fi + substitute $jsonPath $out/${name}.json \ + --replace '"@PYTHONPATH@"' "[$program_PYTHONPATH]" \ + --subst-var-by PATH "$program_PATH" + ''; + }; in { @@ -118,7 +160,7 @@ in { ''; serviceConfig = { Type = "notify"; - ExecStart = "${uwsgi}/bin/uwsgi --uid ${cfg.user} --gid ${cfg.group} --json ${pkgs.writeText "uwsgi.json" (buildCfg cfg.instance)}"; + ExecStart = "${uwsgi}/bin/uwsgi --uid ${cfg.user} --gid ${cfg.group} --json ${buildCfg "server" cfg.instance}/server.json"; ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID"; ExecStop = "${pkgs.coreutils}/bin/kill -INT $MAINPID"; NotifyAccess = "main"; |