at 17.09-beta 4.4 kB view raw
1{ config, lib, pkgs, ... }: 2 3with lib; 4 5let 6 7 cfg = config.services.ejabberd; 8 9 ctlcfg = pkgs.writeText "ejabberdctl.cfg" '' 10 ERL_EPMD_ADDRESS=127.0.0.1 11 ${cfg.ctlConfig} 12 ''; 13 14 ectl = ''${cfg.package}/bin/ejabberdctl ${if cfg.configFile == null then "" else "--config ${cfg.configFile}"} --ctl-config "${ctlcfg}" --spool "${cfg.spoolDir}" --logs "${cfg.logsDir}"''; 15 16 dumps = lib.escapeShellArgs cfg.loadDumps; 17 18in { 19 20 ###### interface 21 22 options = { 23 24 services.ejabberd = { 25 26 enable = mkOption { 27 type = types.bool; 28 default = false; 29 description = "Whether to enable ejabberd server"; 30 }; 31 32 package = mkOption { 33 type = types.package; 34 default = pkgs.ejabberd; 35 defaultText = "pkgs.ejabberd"; 36 description = "ejabberd server package to use"; 37 }; 38 39 user = mkOption { 40 type = types.str; 41 default = "ejabberd"; 42 description = "User under which ejabberd is ran"; 43 }; 44 45 group = mkOption { 46 type = types.str; 47 default = "ejabberd"; 48 description = "Group under which ejabberd is ran"; 49 }; 50 51 spoolDir = mkOption { 52 type = types.path; 53 default = "/var/lib/ejabberd"; 54 description = "Location of the spooldir of ejabberd"; 55 }; 56 57 logsDir = mkOption { 58 type = types.path; 59 default = "/var/log/ejabberd"; 60 description = "Location of the logfile directory of ejabberd"; 61 }; 62 63 configFile = mkOption { 64 type = types.nullOr types.path; 65 description = "Configuration file for ejabberd in YAML format"; 66 default = null; 67 }; 68 69 ctlConfig = mkOption { 70 type = types.lines; 71 default = ""; 72 description = "Configuration of ejabberdctl"; 73 }; 74 75 loadDumps = mkOption { 76 type = types.listOf types.path; 77 default = []; 78 description = "Configuration dumps that should be loaded on the first startup"; 79 example = literalExample "[ ./myejabberd.dump ]"; 80 }; 81 82 imagemagick = mkOption { 83 type = types.bool; 84 default = false; 85 description = "Add ImageMagick to server's path; allows for image thumbnailing"; 86 }; 87 }; 88 89 }; 90 91 92 ###### implementation 93 94 config = mkIf cfg.enable { 95 environment.systemPackages = [ cfg.package ]; 96 97 users.extraUsers = optionalAttrs (cfg.user == "ejabberd") (singleton 98 { name = "ejabberd"; 99 group = cfg.group; 100 home = cfg.spoolDir; 101 createHome = true; 102 uid = config.ids.uids.ejabberd; 103 }); 104 105 users.extraGroups = optionalAttrs (cfg.group == "ejabberd") (singleton 106 { name = "ejabberd"; 107 gid = config.ids.gids.ejabberd; 108 }); 109 110 systemd.services.ejabberd = { 111 description = "ejabberd server"; 112 wantedBy = [ "multi-user.target" ]; 113 after = [ "network.target" ]; 114 path = [ pkgs.findutils pkgs.coreutils pkgs.runit ] ++ lib.optional cfg.imagemagick pkgs.imagemagick; 115 116 serviceConfig = { 117 ExecStart = ''${ectl} foreground''; 118 # FIXME: runit is used for `chpst` -- can we get rid of this? 119 ExecStop = ''${pkgs.runit}/bin/chpst -u "${cfg.user}:${cfg.group}" ${ectl} stop''; 120 ExecReload = ''${pkgs.runit}/bin/chpst -u "${cfg.user}:${cfg.group}" ${ectl} reload_config''; 121 User = cfg.user; 122 Group = cfg.group; 123 PermissionsStartOnly = true; 124 }; 125 126 preStart = '' 127 mkdir -p -m750 "${cfg.logsDir}" 128 chown "${cfg.user}:${cfg.group}" "${cfg.logsDir}" 129 130 mkdir -p -m750 "/var/lock/ejabberdctl" 131 chown "${cfg.user}:${cfg.group}" "/var/lock/ejabberdctl" 132 133 mkdir -p -m750 "${cfg.spoolDir}" 134 chown -R "${cfg.user}:${cfg.group}" "${cfg.spoolDir}" 135 136 if [ -z "$(ls -A '${cfg.spoolDir}')" ]; then 137 touch "${cfg.spoolDir}/.firstRun" 138 fi 139 ''; 140 141 postStart = '' 142 while ! ${ectl} status >/dev/null 2>&1; do 143 if ! kill -0 "$MAINPID"; then exit 1; fi 144 sleep 0.1 145 done 146 147 if [ -e "${cfg.spoolDir}/.firstRun" ]; then 148 rm "${cfg.spoolDir}/.firstRun" 149 for src in ${dumps}; do 150 find "$src" -type f | while read dump; do 151 echo "Loading configuration dump at $dump" 152 chpst -u "${cfg.user}:${cfg.group}" ${ectl} load "$dump" 153 done 154 done 155 fi 156 ''; 157 }; 158 159 security.pam.services.ejabberd = {}; 160 161 }; 162 163}