1{ config, lib, pkgs, ... }:
2
3with lib;
4let
5 cfg = config.services.galene;
6 defaultstateDir = "/var/lib/galene";
7 defaultrecordingsDir = "${cfg.stateDir}/recordings";
8 defaultgroupsDir = "${cfg.stateDir}/groups";
9 defaultdataDir = "${cfg.stateDir}/data";
10in
11{
12 options = {
13 services.galene = {
14 enable = mkEnableOption "Galene Service.";
15
16 stateDir = mkOption {
17 default = defaultstateDir;
18 type = types.str;
19 description = ''
20 The directory where Galene stores its internal state. If left as the default
21 value this directory will automatically be created before the Galene server
22 starts, otherwise the sysadmin is responsible for ensuring the directory
23 exists with appropriate ownership and permissions.
24 '';
25 };
26
27 user = mkOption {
28 type = types.str;
29 default = "galene";
30 description = "User account under which galene runs.";
31 };
32
33 group = mkOption {
34 type = types.str;
35 default = "galene";
36 description = "Group under which galene runs.";
37 };
38
39 insecure = mkOption {
40 type = types.bool;
41 default = false;
42 description = ''
43 Whether Galene should listen in http or in https. If left as the default
44 value (false), Galene needs to be fed a private key and a certificate.
45 '';
46 };
47
48 certFile = mkOption {
49 type = types.nullOr types.str;
50 default = null;
51 example = "/path/to/your/cert.pem";
52 description = ''
53 Path to the server's certificate. The file is copied at runtime to
54 Galene's data directory where it needs to reside.
55 '';
56 };
57
58 keyFile = mkOption {
59 type = types.nullOr types.str;
60 default = null;
61 example = "/path/to/your/key.pem";
62 description = ''
63 Path to the server's private key. The file is copied at runtime to
64 Galene's data directory where it needs to reside.
65 '';
66 };
67
68 httpAddress = mkOption {
69 type = types.str;
70 default = "";
71 description = "HTTP listen address for galene.";
72 };
73
74 httpPort = mkOption {
75 type = types.port;
76 default = 8443;
77 description = "HTTP listen port.";
78 };
79
80 staticDir = mkOption {
81 type = types.str;
82 default = "${cfg.package.static}/static";
83 example = "/var/lib/galene/static";
84 description = "Web server directory.";
85 };
86
87 recordingsDir = mkOption {
88 type = types.str;
89 default = defaultrecordingsDir;
90 example = "/var/lib/galene/recordings";
91 description = "Recordings directory.";
92 };
93
94 dataDir = mkOption {
95 type = types.str;
96 default = defaultdataDir;
97 example = "/var/lib/galene/data";
98 description = "Data directory.";
99 };
100
101 groupsDir = mkOption {
102 type = types.str;
103 default = defaultgroupsDir;
104 example = "/var/lib/galene/groups";
105 description = "Web server directory.";
106 };
107
108 package = mkOption {
109 default = pkgs.galene;
110 defaultText = "pkgs.galene";
111 type = types.package;
112 description = ''
113 Package for running Galene.
114 '';
115 };
116 };
117 };
118
119 config = mkIf cfg.enable {
120 assertions = [
121 {
122 assertion = cfg.insecure || (cfg.certFile != null && cfg.keyFile != null);
123 message = ''
124 Galene needs both certFile and keyFile defined for encryption, or
125 the insecure flag.
126 '';
127 }
128 ];
129
130 systemd.services.galene = {
131 description = "galene";
132 after = [ "network.target" ];
133 wantedBy = [ "multi-user.target" ];
134
135 preStart = ''
136 ${optionalString (cfg.insecure != true) ''
137 install -m 700 -o '${cfg.user}' -g '${cfg.group}' ${cfg.certFile} ${cfg.dataDir}/cert.pem
138 install -m 700 -o '${cfg.user}' -g '${cfg.group}' ${cfg.keyFile} ${cfg.dataDir}/key.pem
139 ''}
140 '';
141
142 serviceConfig = mkMerge [
143 {
144 Type = "simple";
145 User = cfg.user;
146 Group = cfg.group;
147 WorkingDirectory = cfg.stateDir;
148 ExecStart = ''${cfg.package}/bin/galene \
149 ${optionalString (cfg.insecure) "-insecure"} \
150 -data ${cfg.dataDir} \
151 -groups ${cfg.groupsDir} \
152 -recordings ${cfg.recordingsDir} \
153 -static ${cfg.staticDir}'';
154 Restart = "always";
155 # Upstream Requirements
156 LimitNOFILE = 65536;
157 StateDirectory = [ ] ++
158 optional (cfg.stateDir == defaultstateDir) "galene" ++
159 optional (cfg.dataDir == defaultdataDir) "galene/data" ++
160 optional (cfg.groupsDir == defaultgroupsDir) "galene/groups" ++
161 optional (cfg.recordingsDir == defaultrecordingsDir) "galene/recordings";
162 }
163 ];
164 };
165
166 users.users = mkIf (cfg.user == "galene")
167 {
168 galene = {
169 description = "galene Service";
170 group = cfg.group;
171 isSystemUser = true;
172 };
173 };
174
175 users.groups = mkIf (cfg.group == "galene") {
176 galene = { };
177 };
178 };
179 meta.maintainers = with lib.maintainers; [ rgrunbla ];
180}