-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy pathcreate-systemd-service.nix
128 lines (108 loc) · 3.94 KB
/
create-systemd-service.nix
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
{ writeTextFile
, stdenv
, lib
, 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 ? {}
, unitType ? "service"
# 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 ? {}
# Arbitrary commands executed after generating the configuration files
, postInstall ? ""
# 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
util = import ../util {
inherit lib;
};
sections = removeAttrs args [ "unitType" "name" "environment" "dependencies" "path" "credentials" "postInstall" ];
_environment = util.appendPathToEnvironment {
inherit environment;
path = basePackages ++ path;
};
generateEnvironmentVariables = environment:
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}.${dependency.unitType}") dependencies)}
After=${toString (map (dependency: "${dependency.name}.${dependency.unitType}") dependencies)}
'';
generateSection = {title, properties}:
''
[${title}]
${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
''${if builtins.isList value then lib.strings.concatMapStringsSep "\n" (x: "${name}=${toString x}") value else "${name}=${toString value}"}
''
) (builtins.attrNames properties)}''
+ (if title == "Service" then generateEnvironmentVariables _environment else "")
+ (if title == "Unit" then mapDependencies dependencies else "");
generateSections = sections:
lib.concatMapStrings (title:
let
properties = builtins.getAttr title sections;
in
generateSection {
inherit title properties;
}
) (builtins.attrNames sections);
systemdFile = writeTextFile {
name = "${name}.${unitType}";
text = ''
${generateSections sections}
${lib.optionalString (!(sections ? Service) && _environment != {} && unitType == "service") ''
[Service]
${generateEnvironmentVariables _environment}''}
${lib.optionalString (!(sections ? Unit) && dependencies != []) ''
[Unit]
${mapDependencies dependencies}
''}
'';
};
credentialsSpec = createCredentials credentials;
in
stdenv.mkDerivation {
name = "${prefix}${name}";
inherit unitType;
buildCommand = ''
mkdir -p $out/etc/systemd/system
ln -s ${systemdFile} $out/etc/systemd/system/${prefix}${name}.${unitType}
${lib.optionalString (dependencies != []) ''
mkdir -p $out/etc/systemd/system/${prefix}${name}.${unitType}.wants
${lib.concatMapStrings (dependency: ''
ln -s ${dependency}/etc/systemd/system/${dependency.name}.${dependency.unitType} $out/etc/systemd/system/${prefix}${name}.${unitType}.wants
'') dependencies}
''}
ln -s ${credentialsSpec}/dysnomia-support $out/dysnomia-support
${postInstall}
'';
}