nixpkgs/nixos/modules/services/networking/nghttpx/default.nix
2019-10-12 22:25:28 +02:00

119 lines
3.4 KiB
Nix

{config, pkgs, lib, ...}:
let
cfg = config.services.nghttpx;
# renderHost :: Either ServerOptions Path -> String
renderHost = server:
if builtins.isString server
then "unix://${server}"
else "${server.host},${builtins.toString server.port}";
# Filter out submodule parameters whose value is null or false or is
# the key _module.
#
# filterParams :: ParamsSubmodule -> ParamsSubmodule
filterParams = p:
lib.filterAttrs
(n: v: ("_module" != n) && (null != v) && (false != v))
(lib.optionalAttrs (null != p) p);
# renderBackend :: BackendSubmodule -> String
renderBackend = backend:
let
host = renderHost backend.server;
patterns = lib.concatStringsSep ":" backend.patterns;
# Render a set of backend parameters, this is somewhat
# complicated because nghttpx backend patterns can be entirely
# omitted and the params may be given as a mixed collection of
# 'key=val' pairs or atoms (e.g: 'proto=h2;tls')
params =
lib.mapAttrsToList
(n: v:
if builtins.isBool v
then n
else if builtins.isString v
then "${n}=${v}"
else "${n}=${builtins.toString v}")
(filterParams backend.params);
# NB: params are delimited by a ";" which is the same delimiter
# to separate the host;[pattern];[params] sections of a backend
sections =
builtins.filter (e: "" != e) ([
host
patterns
]++params);
formattedSections = lib.concatStringsSep ";" sections;
in
"backend=${formattedSections}";
# renderFrontend :: FrontendSubmodule -> String
renderFrontend = frontend:
let
host = renderHost frontend.server;
params0 =
lib.mapAttrsToList
(n: v: if builtins.isBool v then n else v)
(filterParams frontend.params);
# NB: nghttpx doesn't accept "tls", you must omit "no-tls" for
# the default behavior of turning on TLS.
params1 = lib.remove "tls" params0;
sections = [ host] ++ params1;
formattedSections = lib.concatStringsSep ";" sections;
in
"frontend=${formattedSections}";
configurationFile = pkgs.writeText "nghttpx.conf" ''
${lib.optionalString (null != cfg.tls) ("private-key-file="+cfg.tls.key)}
${lib.optionalString (null != cfg.tls) ("certificate-file="+cfg.tls.crt)}
user=nghttpx
${lib.concatMapStringsSep "\n" renderFrontend cfg.frontends}
${lib.concatMapStringsSep "\n" renderBackend cfg.backends}
backlog=${builtins.toString cfg.backlog}
backend-address-family=${cfg.backend-address-family}
workers=${builtins.toString cfg.workers}
rlimit-nofile=${builtins.toString cfg.rlimit-nofile}
${lib.optionalString cfg.single-thread "single-thread=yes"}
${lib.optionalString cfg.single-process "single-process=yes"}
${cfg.extraConfig}
'';
in
{ imports = [
./nghttpx-options.nix
];
config = lib.mkIf cfg.enable {
users.groups.nghttpx = { };
users.users.nghttpx = {
group = config.users.groups.nghttpx.name;
isSystemUser = true;
};
systemd.services = {
nghttpx = {
wantedBy = [ "multi-user.target" ];
after = [ "network.target" ];
script = ''
${pkgs.nghttp2}/bin/nghttpx --conf=${configurationFile}
'';
serviceConfig = {
Restart = "on-failure";
RestartSec = 60;
};
};
};
};
}