Hi,
I’ve created a custom service:
{
config,
lib,
pkgs,
utils,
...
}:
with lib;
let
cfg = config.services.gosk;
# Escape as required by: https://www.freedesktop.org/software/systemd/man/systemd.unit.html
escapeUnitName =
name:
lib.concatMapStrings (s: if lib.isList s then "-" else s) (
builtins.split "[^a-zA-Z0-9_.\\-]+" name
);
in
{
options.services.gosk = {
enable = mkEnableOption "Go Signal K service";
package = lib.mkPackageOption pkgs "gosk" { };
processors = mkOption {
type = types.attrsOf (
types.submodule (
{ name, ... }:
{
options = {
enable = mkOption {
type = types.bool;
default = true;
description = "Whether or not to enable this command.";
};
command = mkOption {
type = types.separatedString " ";
default = "";
example = "write database mapped";
description = "Command to add to this gosk command.";
};
subscribeURLs = mkOption {
type = types.listOf types.str;
default = [ ];
example = [ "tcp://127.0.0.1:6000" ];
description = "URLs to subscribe to.";
};
publishURL = mkOption {
type = types.nullOr types.str;
default = null;
example = "tcp://127.0.0.1:6000";
description = "URL to publish to.";
};
configFile = mkOption {
type = types.nullOr types.path;
default = null;
example = ./gosk.yaml;
description = "Configuration file in YAML format for this gosk command.";
};
after = mkOption {
type = types.listOf utils.systemdUtils.lib.unitNameType;
default = [ ];
example = [ "postgresql" ];
description = "Systemd services to wait for";
};
extraArgs = mkOption {
type = types.listOf types.str;
default = [ ];
example = ''
[ "--pmport" "127.0.0.1:9203" ]
'';
description = "Extra arguments for the gosk processor.";
};
extraFiles = mkOption {
type = types.listOf types.path;
default = [ ];
example = [ ./can.dbc ];
description = "Extra files that are needed for this gosk processor.";
};
};
}
)
);
default = { };
example = literalExpression ''
{
"map ais" = {
command = "map";
subscribeURLs = [ "tcp://127.0.0.1:6001" ];
publishURL = "tcp://127.0.0.1:6101";
configFile = ./gosk.yaml;
};
}
'';
description = "gosk commands to run.";
};
};
config = mkIf cfg.enable {
systemd.services = mapAttrs' (
name: c:
nameValuePair "gosk-${escapeUnitName name}" (mkMerge [
{
enable = c.enable;
description = "gosk ${name}";
wantedBy = [ "multi-user.target" ];
after = c.after;
serviceConfig = {
ExecStart = toString (
[ "${pkgs.gosk}/bin/gosk" ]
++ lib.optional (c.command != "") c.command
++ [ (concatMapStringsSep " " (url: "-s ${url}") c.subscribeURLs) ]
++ lib.optional (isString c.publishURL) "-p ${c.publishURL}"
++ lib.optional (c.configFile != null) "--config \${CREDENTIALS_DIRECTORY}/gosk.yaml"
++ c.extraArgs
);
LoadCredential = if c.configFile != null then "gosk.yaml:${c.configFile}" else "";
DynamicUser = "yes";
};
}
])
) cfg.processors;
};
meta.maintainers = with maintainers; [ munnik ];
}
For each processor
a sytemd.services.<name>
is created. The service uses a YAML config file that I can specify with the option configFile
. This config file can contain references to other (binary) files that are needed for the configuration. How can I include these other files in the service so that refer to them (maybe relative path) from the config file? I’ve created the option extraFiles
but I don’t know how to include them.
I’m also fairly new to Nix, so please feel free to also make general comments on how to improve services.gosk
.