118 lines
3.7 KiB
Nix
118 lines
3.7 KiB
Nix
{ writeTextFile
|
|
, stdenv
|
|
, createCredentials
|
|
, basePackages
|
|
|
|
# Specifies whether user changing functionality should be disabled or not
|
|
, forceDisableUserChange ? false
|
|
# Prefix that is in front of all systemd units generated by this function
|
|
, prefix ? "nix-process-"
|
|
}:
|
|
|
|
{
|
|
# A name that identifies the process instance
|
|
name
|
|
# An attribute set specifying arbitrary environment variables
|
|
, environment ? {}
|
|
# List of supervisord services that this configuration depends on.
|
|
# These properties are translated to Wants= and After= properties to ensure
|
|
# proper activation ordering and that the dependencies are started first
|
|
, dependencies ? []
|
|
# Specifies which packages need to be in the PATH
|
|
, path ? []
|
|
# Specifies which groups and users that need to be created.
|
|
, credentials ? {}
|
|
# The remainder of the parameters directly get translated to sections and properties
|
|
# See: https://www.freedesktop.org/software/systemd/man/systemd.unit.html
|
|
# and: https://www.freedesktop.org/software/systemd/man/systemd.service.html
|
|
, ...
|
|
}@args:
|
|
|
|
let
|
|
sections = removeAttrs args [ "name" "environment" "dependencies" "path" "credentials" ];
|
|
|
|
_environment = {
|
|
PATH = builtins.concatStringsSep ":" (map (package: "${package}/bin") (basePackages ++ path));
|
|
} // environment;
|
|
|
|
generateEnvironmentVariables = environment:
|
|
stdenv.lib.concatMapStrings (name:
|
|
let
|
|
value = builtins.getAttr name _environment;
|
|
in
|
|
''Environment=${name}=${toString value}
|
|
''
|
|
) (builtins.attrNames _environment);
|
|
|
|
mapDependencies = dependencies:
|
|
if dependencies == [] then ""
|
|
else
|
|
''
|
|
Wants=${toString (map (dependency: "${dependency.name}.service") dependencies)}
|
|
After=${toString (map (dependency: "${dependency.name}.service") dependencies)}
|
|
'';
|
|
|
|
generateSection = {title, properties}:
|
|
''
|
|
|
|
[${title}]
|
|
${stdenv.lib.concatMapStrings (name:
|
|
let
|
|
value = builtins.getAttr name properties;
|
|
in
|
|
if forceDisableUserChange && (name == "User" || name == "Group") then "" else # Don't change user privileges when we force it to be disabled
|
|
''${name}=${toString value}
|
|
''
|
|
) (builtins.attrNames properties)}''
|
|
+ (if title == "Service" then generateEnvironmentVariables _environment else "")
|
|
+ (if title == "Unit" then mapDependencies dependencies else "");
|
|
|
|
generateSections = sections:
|
|
stdenv.lib.concatMapStrings (title:
|
|
let
|
|
properties = builtins.getAttr title sections;
|
|
in
|
|
generateSection {
|
|
inherit title properties;
|
|
}
|
|
) (builtins.attrNames sections);
|
|
|
|
service = writeTextFile {
|
|
name = "${name}.service";
|
|
text = ''
|
|
${generateSections sections}
|
|
${stdenv.lib.optionalString (!(sections ? Service) && _environment != {}) ''
|
|
[Service]
|
|
|
|
${generateEnvironmentVariables _environment}''}
|
|
${stdenv.lib.optionalString (!(sections ? Unit) && dependencies != []) ''
|
|
|
|
[Unit]
|
|
${mapDependencies dependencies}
|
|
''}
|
|
'';
|
|
};
|
|
|
|
credentialsSpec = if credentials == {} || forceDisableUserChange then null else createCredentials credentials;
|
|
in
|
|
stdenv.mkDerivation {
|
|
name = "${prefix}${name}";
|
|
|
|
buildCommand = ''
|
|
mkdir -p $out/etc/systemd/system
|
|
ln -s ${service} $out/etc/systemd/system/${prefix}${name}.service
|
|
|
|
${stdenv.lib.optionalString (dependencies != []) ''
|
|
mkdir -p $out/etc/systemd/system/${prefix}${name}.service.wants
|
|
|
|
${stdenv.lib.concatMapStrings (dependency: ''
|
|
ln -s ${dependency}/etc/systemd/system/${dependency.name}.service $out/etc/systemd/system/${prefix}${name}.service.wants
|
|
'') dependencies}
|
|
''}
|
|
|
|
${stdenv.lib.optionalString (credentialsSpec != null) ''
|
|
ln -s ${credentialsSpec}/dysnomia-support $out/dysnomia-support
|
|
''}
|
|
'';
|
|
}
|