taskserver: Pass configuration via command line

Putting an include directive in the configuration file referencing a
store path with the real configuration file has the disavantage that
once we change the real configuration file the store path is also a
different one.

So we would have to replace that include directive with the new
configuration file, which is very much error-prone, because whenever
taskd modifies the configuration file on its own it generates a new one
with *only* the key/value options and without any include directives.

Another problem is that we only added the include directive on the first
initalization, so whenever there is *any* configuration change, it won't
affect anything.

We're now passing all the configuration options via command line,
because taskd treats everything in the form of --<name>=<value> to be a
configuration directive.

This also has the effect that we now no longer have extraConfig, because
configuration isn't a file anymore.

Instead we now have an attribute set that is mapped down to
configuration options.

Unfortunately this isn't so easy with the way taskd is configured,
because there is an option called "server" and also other options like
"server.cert", "server.key" and so on, which do not map very well to
attribute sets.

So we have an exception for the "server" option, which is now called
"server.listen", because it specifies the listening address.

Signed-off-by: aszlig <aszlig@redmoonstudios.org>
Fixes: #22705
This commit is contained in:
aszlig 2017-02-17 19:18:04 +01:00
parent 78fe00da7c
commit c7bbb93878
No known key found for this signature in database
GPG Key ID: 1DE8E48E57DB5436

View File

@ -94,44 +94,6 @@ let
in flatten (mapAttrsToList mkSublist attrs);
in all isNull (findPkiDefinitions [] manualPkiOptions);
configFile = pkgs.writeText "taskdrc" (''
# systemd related
daemon = false
log = -
# logging
${mkConfLine "debug" cfg.debug}
${mkConfLine "ip.log" cfg.ipLog}
# general
${mkConfLine "ciphers" cfg.ciphers}
${mkConfLine "confirmation" cfg.confirmation}
${mkConfLine "extensions" cfg.extensions}
${mkConfLine "queue.size" cfg.queueSize}
${mkConfLine "request.limit" cfg.requestLimit}
# client
${mkConfLine "client.allow" cfg.allowedClientIDs}
${mkConfLine "client.deny" cfg.disallowedClientIDs}
# server
server = ${cfg.listenHost}:${toString cfg.listenPort}
${mkConfLine "trust" cfg.trust}
# PKI options
${if needToCreateCA then ''
ca.cert = ${cfg.dataDir}/keys/ca.cert
server.cert = ${cfg.dataDir}/keys/server.cert
server.key = ${cfg.dataDir}/keys/server.key
server.crl = ${cfg.dataDir}/keys/server.crl
'' else ''
ca.cert = ${cfg.pki.manual.ca.cert}
server.cert = ${cfg.pki.manual.server.cert}
server.key = ${cfg.pki.manual.server.key}
server.crl = ${cfg.pki.manual.server.crl}
''}
'' + cfg.extraConfig);
orgOptions = { name, ... }: {
options.users = mkOption {
type = types.uniq (types.listOf types.str);
@ -365,17 +327,54 @@ in {
pki.manual = manualPkiOptions;
pki.auto = autoPkiOptions;
extraConfig = mkOption {
type = types.lines;
default = "";
example = "client.cert = /tmp/debugging.cert";
config = mkOption {
type = types.attrs;
example.client.cert = "/tmp/debugging.cert";
description = ''
Extra lines to append to the taskdrc configuration file.
Configuration options to pass to Taskserver.
The options here are the same as described in <citerefentry>
<refentrytitle>taskdrc</refentrytitle>
<manvolnum>5</manvolnum>
</citerefentry>, but with one difference:
The <literal>server</literal> option is
<literal>server.listen</literal> here, because the
<literal>server</literal> option would collide with other options
like <literal>server.cert</literal> and we would run in a type error
(attribute set versus string).
Nix types like integers or booleans are automatically converted to
the right values Taskserver would expect.
'';
apply = let
mkKey = path: if path == ["server" "listen"] then "server"
else concatStringsSep "." path;
recurse = path: attrs: let
mapper = name: val: let
newPath = path ++ [ name ];
scalar = if val == true then "true"
else if val == false then "false"
else toString val;
in if isAttrs val then recurse newPath val
else [ "${mkKey newPath}=${scalar}" ];
in concatLists (mapAttrsToList mapper attrs);
in recurse [];
};
};
};
imports = [
(mkRemovedOptionModule ["services" "taskserver" "extraConfig"] ''
This option was removed in favor of `services.taskserver.config` with
different semantics (it's now a list of attributes instead of lines).
Please look up the documentation of `services.taskserver.config' to get
more information about the new way to pass additional configuration
options.
'')
];
config = mkMerge [
(mkIf cfg.enable {
environment.systemPackages = [ pkgs.taskserver nixos-taskserver ];
@ -392,6 +391,44 @@ in {
gid = config.ids.gids.taskd;
};
services.taskserver.config = {
# systemd related
daemon = false;
log = "-";
# logging
debug = cfg.debug;
ip.log = cfg.ipLog;
# general
ciphers = cfg.ciphers;
confirmation = cfg.confirmation;
extensions = cfg.extensions;
queue.size = cfg.queueSize;
request.limit = cfg.requestLimit;
# client
client.allow = cfg.allowedClientIDs;
client.deny = cfg.disallowedClientIDs;
# server
trust = cfg.trust;
server = {
listen = "${cfg.listenHost}:${toString cfg.listenPort}";
} // (if needToCreateCA then {
cert = "${cfg.dataDir}/keys/server.cert";
key = "${cfg.dataDir}/keys/server.key";
crl = "${cfg.dataDir}/keys/server.crl";
} else {
cert = "${cfg.pki.manual.server.cert}";
key = "${cfg.pki.manual.server.key}";
crl = "${cfg.pki.manual.server.crl}";
});
ca.cert = if needToCreateCA then "${cfg.dataDir}/keys/ca.cert"
else "${cfg.pki.manual.ca.cert}";
};
systemd.services.taskserver-init = {
wantedBy = [ "taskserver.service" ];
before = [ "taskserver.service" ];
@ -404,7 +441,6 @@ in {
script = ''
${taskd} init
echo "include ${configFile}" > "${cfg.dataDir}/config"
touch "${cfg.dataDir}/.is_initialized"
'';
@ -436,7 +472,10 @@ in {
in "${helperTool} process-json '${jsonFile}'";
serviceConfig = {
ExecStart = "@${taskd} taskd server";
ExecStart = let
mkCfgFlag = flag: escapeShellArg "--${flag}";
cfgFlags = concatMapStringsSep " " mkCfgFlag cfg.config;
in "@${taskd} taskd server ${cfgFlags}";
ExecReload = "${pkgs.coreutils}/bin/kill -USR1 $MAINPID";
Restart = "on-failure";
PermissionsStartOnly = true;