nix-rehash/nix-services/supervisord.nix
wmertens 73d784337a supervisord: shell wrapper improvements
- Quote arguments properly
- Copy scripts instead of linking, reducing number of store paths
- Convert tabs to spaces
2014-12-03 12:17:41 +01:00

177 lines
4.5 KiB
Nix

{ config, pkgs, ... }:
with pkgs.lib;
let
serviceOpts = { name, config, ...}: {
options = {
command = mkOption {
description = "The command to execute";
};
directory = mkOption {
default = "/";
description = "Current directory when running the command";
};
environment = mkOption {
default = {};
example = {
PATH = "/some/path";
};
};
path = mkOption {
default = [];
description = "Current directory when running the command";
};
stopsignal = mkOption {
default = "TERM";
};
startsecs = mkOption {
default = 1;
example = 0;
};
pidfile = mkOption {
default = null;
};
};
};
services = config.supervisord.services;
supervisor = config.supervisord.package;
supervisordWrapper = pkgs.writeScript "supervisord-wrapper" ''
#!${pkgs.stdenv.shell}
extraFlags=""
if [ -n "$STATEDIR" ]; then
extraFlags="-j $STATEDIR/run/supervisord.pid -d $STATEDIR -q $STATEDIR/log/ -l $STATEDIR/log/supervisord.log"
mkdir -p "$STATEDIR"/{run,log}
else
mkdir -p "${config.supervisord.stateDir}"/{run,log}
fi
export PATH="${pkgs.coreutils}/bin"
# Run start scripts first
"${config.userNix.startScript}"
# Run supervisord
exec ${supervisor}/bin/supervisord -c "${config.supervisord.configFile}" $extraFlags "$@"
'';
supervisorctlWrapper = pkgs.writeScript "supervisorctl-wrapper" ''
#!${pkgs.stdenv.shell}
exec ${supervisor}/bin/supervisorctl -c "${config.supervisord.configFile}" "$@"
'';
in {
options = {
supervisord = {
enable = mkOption {
default = true;
type = types.bool;
};
port = mkOption {
default = 65123;
type = types.int;
};
package = mkOption {
default = pkgs.pythonPackages.supervisor;
type = types.package;
description = ''
Supervisord package to use.
'';
};
services = mkOption {
default = {};
type = types.loaOf types.optionSet;
description = ''
Supervisord services to start.
'';
options = [ serviceOpts ];
};
stateDir = mkOption {
default = "./var";
type = types.str;
description = ''
Supervisord state directory.
'';
};
tailLogs = mkOption {
default = false;
type = types.bool;
description = ''
Whether or not to tail all logs to standard out.
'';
};
configFile = mkOption {
internal = true;
};
bin = mkOption {
internal = true;
};
};
};
config = mkIf config.supervisord.enable {
supervisord.configFile = pkgs.writeText "supervisord.conf" ''
[supervisord]
pidfile=${config.supervisord.stateDir}/run/supervisord.pid
childlogdir=${config.supervisord.stateDir}/log/
logfile=${config.supervisord.stateDir}/log/supervisord.log
[supervisorctl]
serverurl = http://localhost:${toString config.supervisord.port}
[inet_http_server]
port = 127.0.0.1:${toString config.supervisord.port}
[rpcinterface:supervisor]
supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface
${concatMapStrings (name:
let
cfg = getAttr name services;
path = if isList cfg.path then concatStringsSep ":" cfg.path else cfg.path;
in
''
[program:${name}]
command=${if cfg.pidfile == null then cfg.command else "${supervisor}/bin/pidproxy ${cfg.pidfile} ${cfg.command}"}
environment=${concatStrings
(mapAttrsToList (name: value: "${name}=\"${value}\",") (
cfg.environment // { PATH = concatStringsSep ":"
[("%(ENV_PATH)s") (path) (maybeAttr "PATH" "" cfg.environment)];
}
)
)}
directory=${cfg.directory}
redirect_stderr=true
startsecs=${toString cfg.startsecs}
stopsignal=${cfg.stopsignal}
stopasgroup=true
''
) (attrNames services)
}
'';
supervisord.bin = pkgs.stdenv.mkDerivation {
name = "${supervisor.name}-wrapper";
phases = [ "installPhase" ];
installPhase = ''
mkdir -p $out/bin/
cp ${supervisordWrapper} $out/bin/supervisord
cp ${supervisorctlWrapper} $out/bin/supervisorctl
'';
};
};
}