Add ZNC module. Has zncConfOptions or specify full conf file.

This commit is contained in:
Alex Berg 2014-05-08 22:20:08 +02:00 committed by Alex Berg
parent 39db3547a9
commit 9af1e2ab51
3 changed files with 297 additions and 0 deletions

View file

@ -134,6 +134,7 @@
teamspeak = 124;
influxdb = 125;
nsd = 126;
znc = 127;
# When adding a uid, make sure it doesn't match an existing gid. And don't use uids above 399!
@ -242,6 +243,7 @@
teamspeak = 124;
influxdb = 125;
nsd = 126;
znc = 127;
# When adding a gid, make sure it doesn't match an existing uid. And don't use gids above 399!

View file

@ -235,6 +235,7 @@
./services/networking/wicd.nix
./services/networking/wpa_supplicant.nix
./services/networking/xinetd.nix
./services/networking/znc.nix
./services/printing/cupsd.nix
./services/scheduling/atd.nix
./services/scheduling/cron.nix

View file

@ -0,0 +1,294 @@
{ config, lib, pkgs, ...}:
with lib;
let
cfg = config.services.znc;
defaultUser = "znc"; # Default user to own process.
# Default user and pass:
# un=znc
# pw=nixospass
defaultUserName = "znc";
defaultPassBlock = "
<Pass password>
Method = sha256
Hash = e2ce303c7ea75c571d80d8540a8699b46535be6a085be3414947d638e48d9e93
Salt = l5Xryew4g*!oa(ECfX2o
</Pass>
";
confOptions = { ... }: {
options = {
modules = mkOption {
type = types.listOf types.string;
default = [ "partyline" "webadmin" "adminlog" "log" ];
example = [ "partyline" "webadmin" "adminlog" "log" ];
description = ''
A list of modules to include in the `znc.conf` file.
'';
};
userName = mkOption {
default = defaultUserName;
example = "johntron";
type = types.string;
description = ''
The user name to use when generating the `znc.conf` file.
This is the user name used by the user logging into the ZNC web admin.
'';
};
nick = mkOption {
default = "znc-user";
example = "john";
type = types.string;
description = ''
The IRC nick to use when generating the `znc.conf` file.
'';
};
passBlock = mkOption {
default = defaultPassBlock;
example = "Must be the block generated by the `znc --makepass` command.";
type = types.string;
description = ''
The pass block to use when generating the `znc.conf` file.
This is the password used by the user logging into the ZNC web admin.
This is the block generated by the `znc --makepass` command.
!!! If not specified, please change this after starting the service. !!!
'';
};
port = mkOption {
default = "5000";
example = "5000";
type = types.string;
description = ''
Specifies the port on which to listen.
'';
};
useSSL = mkOption {
default = true;
example = true;
type = types.bool;
description = ''
Indicates whether the ZNC server should use SSL when listening on the specified port.
'';
};
};
};
# Keep znc.conf in nix store, then symlink or copy into `dataDir`, depending on `mutable`.
mkZncConf = confOpts: ''
// Also check http://en.znc.in/wiki/Configuration
AnonIPLimit = 10
ConnectDelay = 5
# Add `LoadModule = x` for each module...
${concatMapStrings (n: "LoadModule = ${n}\n") confOpts.modules}
MaxBufferSize = 500
ProtectWebSessions = true
SSLCertFile = ${cfg.dataDir}/znc.pem
ServerThrottle = 30
Skin = dark-clouds
StatusPrefix = *
Version = 1.2
<Listener listener0>
AllowIRC = true
AllowWeb = true
IPv4 = true
IPv6 = false
Port = ${if confOpts.useSSL then "+" else ""}${confOpts.port}
SSL = ${if confOpts.useSSL then "true" else "false"}
</Listener>
<User ${confOpts.userName}>
Admin = true
Allow = *
AltNick = ${confOpts.nick}_
AppendTimestamp = false
AutoClearChanBuffer = false
Buffer = 150
ChanModes = +stn
DenyLoadMod = false
DenySetBindHost = false
Ident = ident
JoinTries = 10
MaxJoins = 0
MaxNetworks = 1
MultiClients = true
Nick = ${confOpts.nick}
PrependTimestamp = true
QuitMsg = Quit
RealName = ${confOpts.nick}
TimestampFormat = [%H:%M:%S]
${confOpts.passBlock}
</User>
'';
zncConfFile = pkgs.writeTextFile {
name = "znc.conf";
text = if cfg.zncConf != ""
then cfg.zncConf
else mkZncConf cfg.confOptions;
};
in
{
###### Interface
options = {
services.znc = {
enable = mkOption {
default = false;
example = true;
type = types.bool;
description = ''
Enable a ZNC service for a user.
'';
};
user = mkOption {
default = "znc";
example = "john";
type = types.string;
description = ''
The name of an existing user account to use to own the ZNC server process.
If not specified, a default user will be created to own the process.
'';
};
dataDir = mkOption {
default = "/home/${cfg.user}/.znc";
example = "/home/john/.znc";
type = types.string;
description = ''
The data directory. Used for configuration files and modules.
'';
};
zncConf = mkOption {
default = "";
example = "See: http://wiki.znc.in/Configuration";
type = types.string;
description = ''
The contents of the `znc.conf` file to use when creating it.
If specified, `confOptions` will be ignored, and this value, as-is, will be used.
If left empty, a conf file with default values will be used.
Recommended to generate with `znc --makeconf` command.
'';
};
confOptions = mkOption {
default = {};
example = {
modules = [ "log" ];
userName = "john";
nick = "johntron";
};
type = types.optionSet;
description = ''
Values to use when creating a `znc.conf` file.
'';
options = confOptions;
};
mutable = mkOption {
default = false;
example = true;
type = types.bool;
description = ''
Indicates whether to allow the contents of the `dataDir` directory to be changed
by the user at run-time.
If true, modifications to the ZNC configuration after its initial creation are not
overwritten by a NixOS system rebuild.
If false, the ZNC configuration is rebuilt by every system rebuild.
If the user wants to manage the ZNC service using the web admin interface, this value
should be set to true.
'';
};
extraFlags = mkOption {
default = "";
example = "--debug";
type = types.string;
description = ''
Extra flags to use when executing znc command.
'';
};
};
};
###### Implementation
config = mkIf cfg.enable {
systemd.services."znc-${cfg.user}" = {
description = "ZNC Server of ${cfg.user}.";
wantedBy = [ "multi-user.target" ];
after = [ "network.service" ];
path = [ pkgs.znc ];
serviceConfig = {
User = "${cfg.user}";
Restart = "always";
ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID";
ExecStop = "${pkgs.coreutils}/bin/kill -INT $MAINPID";
};
preStart = ''
${pkgs.coreutils}/bin/mkdir -p ${cfg.dataDir}
${pkgs.coreutils}/bin/chown ${cfg.user} ${cfg.dataDir} -R
${pkgs.coreutils}/bin/mkdir -p ${cfg.dataDir}/configs
# If mutable, regenerate conf file every time.
${optionalString (!cfg.mutable) ''
${pkgs.coreutils}/echo "znc-${cfg.user} is set to be system-managed. Now deleting old znc.conf file to be regenerated."
${pkgs.coreutils}/rm -f ${cfg.dataDir}/configs/znc.conf
''}
# Ensure essential files exist.
if [[ ! -f ${cfg.dataDir}/configs/znc.conf ]]; then
${pkgs.coreutils}/bin/echo "No znc.conf file found in ${cfg.dataDir}. Creating one now."
${if (!cfg.mutable)
then "${pkgs.coreutils}/bin/ln --force -s ${zncConfFile} ${cfg.dataDir}/configs/znc.conf"
else ''
${pkgs.coreutils}/bin/cp --no-clobber ${zncConfFile} ${cfg.dataDir}/configs/znc.conf
${pkgs.coreutils}/bin/chmod u+rw ${cfg.dataDir}/configs/znc.conf
${pkgs.coreutils}/bin/chown ${cfg.user} ${cfg.dataDir}/configs/znc.conf
''}
fi
if [[ ! -f ${cfg.dataDir}/znc.pem ]]; then
${pkgs.coreutils}/bin/echo "No znc.pem file found in ${cfg.dataDir}. Creating one now."
${pkgs.znc}/bin/znc --makepem
fi
'';
script = "${pkgs.znc}/bin/znc --foreground --datadir ${cfg.dataDir} ${cfg.extraFlags}";
};
users.extraUsers = optional (cfg.user == defaultUser)
{ name = defaultUser;
description = "ZNC server daemon owner";
group = defaultUser;
uid = config.ids.uids.znc;
createHome = true;
createUser = true;
};
users.extraGroups = optional (cfg.user == defaultUser)
{ name = defaultUser;
gid = config.ids.gids.znc;
members = [ defaultUser ];
};
};
}