1{
2 config,
3 lib,
4 options,
5 pkgs,
6 ...
7}:
8
9with lib;
10
11let
12 cfg = config.services.quassel;
13 opt = options.services.quassel;
14 quassel = cfg.package;
15 user = if cfg.user != null then cfg.user else "quassel";
16in
17
18{
19
20 ###### interface
21
22 options = {
23
24 services.quassel = {
25
26 enable = mkEnableOption "the Quassel IRC client daemon";
27
28 certificateFile = mkOption {
29 type = types.nullOr types.str;
30 default = null;
31 description = ''
32 Path to the certificate used for SSL connections with clients.
33 '';
34 };
35
36 requireSSL = mkOption {
37 type = types.bool;
38 default = false;
39 description = ''
40 Require SSL for connections from clients.
41 '';
42 };
43
44 package = mkPackageOption pkgs "quasselDaemon" { };
45
46 interfaces = mkOption {
47 type = types.listOf types.str;
48 default = [ "127.0.0.1" ];
49 description = ''
50 The interfaces the Quassel daemon will be listening to. If `[ 127.0.0.1 ]`,
51 only clients on the local host can connect to it; if `[ 0.0.0.0 ]`, clients
52 can access it from any network interface.
53 '';
54 };
55
56 portNumber = mkOption {
57 type = types.port;
58 default = 4242;
59 description = ''
60 The port number the Quassel daemon will be listening to.
61 '';
62 };
63
64 dataDir = mkOption {
65 default = "/home/${user}/.config/quassel-irc.org";
66 defaultText = literalExpression ''
67 "/home/''${config.${opt.user}}/.config/quassel-irc.org"
68 '';
69 type = types.str;
70 description = ''
71 The directory holding configuration files, the SQlite database and the SSL Cert.
72 '';
73 };
74
75 user = mkOption {
76 default = null;
77 type = types.nullOr types.str;
78 description = ''
79 The existing user the Quassel daemon should run as. If left empty, a default "quassel" user will be created.
80 '';
81 };
82
83 };
84
85 };
86
87 ###### implementation
88
89 config = mkIf cfg.enable {
90 assertions = [
91 {
92 assertion = cfg.requireSSL -> cfg.certificateFile != null;
93 message = "Quassel needs a certificate file in order to require SSL";
94 }
95 ];
96
97 users.users = optionalAttrs (cfg.user == null) {
98 quassel = {
99 name = "quassel";
100 description = "Quassel IRC client daemon";
101 group = "quassel";
102 uid = config.ids.uids.quassel;
103 };
104 };
105
106 users.groups = optionalAttrs (cfg.user == null) {
107 quassel = {
108 name = "quassel";
109 gid = config.ids.gids.quassel;
110 };
111 };
112
113 systemd.tmpfiles.rules = [
114 "d '${cfg.dataDir}' - ${user} - - -"
115 ];
116
117 systemd.services.quassel = {
118 description = "Quassel IRC client daemon";
119
120 wantedBy = [ "multi-user.target" ];
121 after =
122 [ "network.target" ]
123 ++ optional config.services.postgresql.enable "postgresql.service"
124 ++ optional config.services.mysql.enable "mysql.service";
125
126 serviceConfig = {
127 ExecStart = concatStringsSep " " (
128 [
129 "${quassel}/bin/quasselcore"
130 "--listen=${concatStringsSep "," cfg.interfaces}"
131 "--port=${toString cfg.portNumber}"
132 "--configdir=${cfg.dataDir}"
133 ]
134 ++ optional cfg.requireSSL "--require-ssl"
135 ++ optional (cfg.certificateFile != null) "--ssl-cert=${cfg.certificateFile}"
136 );
137 User = user;
138 };
139 };
140
141 };
142
143}