nixos/solanum: init
This commit is contained in:
parent
d10236eb20
commit
48c16e48aa
|
@ -806,6 +806,7 @@
|
||||||
./services/networking/smartdns.nix
|
./services/networking/smartdns.nix
|
||||||
./services/networking/smokeping.nix
|
./services/networking/smokeping.nix
|
||||||
./services/networking/softether.nix
|
./services/networking/softether.nix
|
||||||
|
./services/networking/solanum.nix
|
||||||
./services/networking/spacecookie.nix
|
./services/networking/spacecookie.nix
|
||||||
./services/networking/spiped.nix
|
./services/networking/spiped.nix
|
||||||
./services/networking/squid.nix
|
./services/networking/squid.nix
|
||||||
|
|
104
nixos/modules/services/networking/solanum.nix
Normal file
104
nixos/modules/services/networking/solanum.nix
Normal file
|
@ -0,0 +1,104 @@
|
||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
inherit (lib) mkEnableOption mkIf mkOption types;
|
||||||
|
inherit (pkgs) solanum;
|
||||||
|
cfg = config.services.solanum;
|
||||||
|
|
||||||
|
configFile = pkgs.writeText "solanum.conf" cfg.config;
|
||||||
|
in
|
||||||
|
|
||||||
|
{
|
||||||
|
|
||||||
|
###### interface
|
||||||
|
|
||||||
|
options = {
|
||||||
|
|
||||||
|
services.solanum = {
|
||||||
|
|
||||||
|
enable = mkEnableOption "Solanum IRC daemon";
|
||||||
|
|
||||||
|
config = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = ''
|
||||||
|
serverinfo {
|
||||||
|
name = "irc.example.com";
|
||||||
|
sid = "1ix";
|
||||||
|
description = "irc!";
|
||||||
|
|
||||||
|
vhost = "0.0.0.0";
|
||||||
|
vhost6 = "::";
|
||||||
|
};
|
||||||
|
|
||||||
|
listen {
|
||||||
|
host = "0.0.0.0";
|
||||||
|
port = 6667;
|
||||||
|
};
|
||||||
|
|
||||||
|
auth {
|
||||||
|
user = "*@*";
|
||||||
|
class = "users";
|
||||||
|
flags = exceed_limit;
|
||||||
|
};
|
||||||
|
channel {
|
||||||
|
default_split_user_count = 0;
|
||||||
|
};
|
||||||
|
'';
|
||||||
|
description = ''
|
||||||
|
Solanum IRC daemon configuration file.
|
||||||
|
check <link xlink:href="https://github.com/solanum-ircd/solanum/blob/main/doc/reference.conf"/> for all options.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
openFilesLimit = mkOption {
|
||||||
|
type = types.int;
|
||||||
|
default = 1024;
|
||||||
|
description = ''
|
||||||
|
Maximum number of open files. Limits the clients and server connections.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
motd = mkOption {
|
||||||
|
type = types.nullOr types.lines;
|
||||||
|
default = null;
|
||||||
|
description = ''
|
||||||
|
Solanum MOTD text.
|
||||||
|
|
||||||
|
Solanum will read its MOTD from <literal>/etc/solanum/ircd.motd</literal>.
|
||||||
|
If set, the value of this option will be written to this path.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
###### implementation
|
||||||
|
|
||||||
|
config = mkIf cfg.enable (lib.mkMerge [
|
||||||
|
{
|
||||||
|
systemd.services.solanum = {
|
||||||
|
description = "Solanum IRC daemon";
|
||||||
|
after = [ "network.target" ];
|
||||||
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
environment = {
|
||||||
|
BANDB_DBPATH = "/var/lib/solanum/ban.db";
|
||||||
|
};
|
||||||
|
serviceConfig = {
|
||||||
|
ExecStart = "${solanum}/bin/solanum -foreground -logfile /dev/stdout -configfile ${configFile} -pidfile /run/solanum/ircd.pid";
|
||||||
|
DynamicUser = true;
|
||||||
|
User = "solanum";
|
||||||
|
StateDirectory = "solanum";
|
||||||
|
RuntimeDirectory = "solanum";
|
||||||
|
LimitNOFILE = "${toString cfg.openFilesLimit}";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
(mkIf (cfg.motd != null) {
|
||||||
|
environment.etc."solanum/ircd.motd".text = cfg.motd;
|
||||||
|
})
|
||||||
|
]);
|
||||||
|
}
|
|
@ -384,6 +384,7 @@ in
|
||||||
snapcast = handleTest ./snapcast.nix {};
|
snapcast = handleTest ./snapcast.nix {};
|
||||||
snapper = handleTest ./snapper.nix {};
|
snapper = handleTest ./snapper.nix {};
|
||||||
sogo = handleTest ./sogo.nix {};
|
sogo = handleTest ./sogo.nix {};
|
||||||
|
solanum = handleTest ./solanum.nix {};
|
||||||
solr = handleTest ./solr.nix {};
|
solr = handleTest ./solr.nix {};
|
||||||
sonarr = handleTest ./sonarr.nix {};
|
sonarr = handleTest ./sonarr.nix {};
|
||||||
spacecookie = handleTest ./spacecookie.nix {};
|
spacecookie = handleTest ./spacecookie.nix {};
|
||||||
|
|
89
nixos/tests/solanum.nix
Normal file
89
nixos/tests/solanum.nix
Normal file
|
@ -0,0 +1,89 @@
|
||||||
|
let
|
||||||
|
clients = [
|
||||||
|
"ircclient1"
|
||||||
|
"ircclient2"
|
||||||
|
];
|
||||||
|
server = "solanum";
|
||||||
|
ircPort = 6667;
|
||||||
|
channel = "nixos-cat";
|
||||||
|
iiDir = "/tmp/irc";
|
||||||
|
in
|
||||||
|
|
||||||
|
import ./make-test-python.nix ({ pkgs, lib, ... }: {
|
||||||
|
name = "solanum";
|
||||||
|
nodes = {
|
||||||
|
"${server}" = {
|
||||||
|
networking.firewall.allowedTCPPorts = [ ircPort ];
|
||||||
|
services.solanum = {
|
||||||
|
enable = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
} // lib.listToAttrs (builtins.map (client: lib.nameValuePair client {
|
||||||
|
imports = [
|
||||||
|
./common/user-account.nix
|
||||||
|
];
|
||||||
|
|
||||||
|
systemd.services.ii = {
|
||||||
|
requires = [ "network.target" ];
|
||||||
|
wantedBy = [ "default.target" ];
|
||||||
|
|
||||||
|
serviceConfig = {
|
||||||
|
Type = "simple";
|
||||||
|
ExecPreStartPre = "mkdir -p ${iiDir}";
|
||||||
|
ExecStart = ''
|
||||||
|
${lib.getBin pkgs.ii}/bin/ii -n ${client} -s ${server} -i ${iiDir}
|
||||||
|
'';
|
||||||
|
User = "alice";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}) clients);
|
||||||
|
|
||||||
|
testScript =
|
||||||
|
let
|
||||||
|
msg = client: "Hello, my name is ${client}";
|
||||||
|
clientScript = client: [
|
||||||
|
''
|
||||||
|
${client}.wait_for_unit("network.target")
|
||||||
|
${client}.systemctl("start ii")
|
||||||
|
${client}.wait_for_unit("ii")
|
||||||
|
${client}.wait_for_file("${iiDir}/${server}/out")
|
||||||
|
''
|
||||||
|
# wait until first PING from server arrives before joining,
|
||||||
|
# so we don't try it too early
|
||||||
|
''
|
||||||
|
${client}.wait_until_succeeds("grep 'PING' ${iiDir}/${server}/out")
|
||||||
|
''
|
||||||
|
# join ${channel}
|
||||||
|
''
|
||||||
|
${client}.succeed("echo '/j #${channel}' > ${iiDir}/${server}/in")
|
||||||
|
${client}.wait_for_file("${iiDir}/${server}/#${channel}/in")
|
||||||
|
''
|
||||||
|
# send a greeting
|
||||||
|
''
|
||||||
|
${client}.succeed(
|
||||||
|
"echo '${msg client}' > ${iiDir}/${server}/#${channel}/in"
|
||||||
|
)
|
||||||
|
''
|
||||||
|
# check that all greetings arrived on all clients
|
||||||
|
] ++ builtins.map (other: ''
|
||||||
|
${client}.succeed(
|
||||||
|
"grep '${msg other}$' ${iiDir}/${server}/#${channel}/out"
|
||||||
|
)
|
||||||
|
'') clients;
|
||||||
|
|
||||||
|
# foldl', but requires a non-empty list instead of a start value
|
||||||
|
reduce = f: list:
|
||||||
|
builtins.foldl' f (builtins.head list) (builtins.tail list);
|
||||||
|
in ''
|
||||||
|
start_all()
|
||||||
|
${server}.systemctl("status solanum")
|
||||||
|
${server}.wait_for_open_port(${toString ircPort})
|
||||||
|
|
||||||
|
# run clientScript for all clients so that every list
|
||||||
|
# entry is executed by every client before advancing
|
||||||
|
# to the next one.
|
||||||
|
'' + lib.concatStrings
|
||||||
|
(reduce
|
||||||
|
(lib.zipListsWith (cs: c: cs + c))
|
||||||
|
(builtins.map clientScript clients));
|
||||||
|
})
|
Loading…
Reference in a new issue