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