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