Merge pull request #123828 from Lassulus/solanum2

nixos/solanum: init

authored by Martin Weinelt and committed by GitHub 71fb79ee 454255ee

+195
+1
nixos/modules/module-list.nix
··· 806 ./services/networking/smartdns.nix 807 ./services/networking/smokeping.nix 808 ./services/networking/softether.nix 809 ./services/networking/spacecookie.nix 810 ./services/networking/spiped.nix 811 ./services/networking/squid.nix
··· 806 ./services/networking/smartdns.nix 807 ./services/networking/smokeping.nix 808 ./services/networking/softether.nix 809 + ./services/networking/solanum.nix 810 ./services/networking/spacecookie.nix 811 ./services/networking/spiped.nix 812 ./services/networking/squid.nix
+104
nixos/modules/services/networking/solanum.nix
···
··· 1 + { config, lib, pkgs, ... }: 2 + 3 + let 4 + inherit (lib) mkEnableOption mkIf mkOption types; 5 + inherit (pkgs) solanum; 6 + cfg = config.services.solanum; 7 + 8 + configFile = pkgs.writeText "solanum.conf" cfg.config; 9 + in 10 + 11 + { 12 + 13 + ###### interface 14 + 15 + options = { 16 + 17 + services.solanum = { 18 + 19 + enable = mkEnableOption "Solanum IRC daemon"; 20 + 21 + config = mkOption { 22 + type = types.str; 23 + default = '' 24 + serverinfo { 25 + name = "irc.example.com"; 26 + sid = "1ix"; 27 + description = "irc!"; 28 + 29 + vhost = "0.0.0.0"; 30 + vhost6 = "::"; 31 + }; 32 + 33 + listen { 34 + host = "0.0.0.0"; 35 + port = 6667; 36 + }; 37 + 38 + auth { 39 + user = "*@*"; 40 + class = "users"; 41 + flags = exceed_limit; 42 + }; 43 + channel { 44 + default_split_user_count = 0; 45 + }; 46 + ''; 47 + description = '' 48 + Solanum IRC daemon configuration file. 49 + check <link xlink:href="https://github.com/solanum-ircd/solanum/blob/main/doc/reference.conf"/> for all options. 50 + ''; 51 + }; 52 + 53 + openFilesLimit = mkOption { 54 + type = types.int; 55 + default = 1024; 56 + description = '' 57 + Maximum number of open files. Limits the clients and server connections. 58 + ''; 59 + }; 60 + 61 + motd = mkOption { 62 + type = types.nullOr types.lines; 63 + default = null; 64 + description = '' 65 + Solanum MOTD text. 66 + 67 + Solanum will read its MOTD from <literal>/etc/solanum/ircd.motd</literal>. 68 + If set, the value of this option will be written to this path. 69 + ''; 70 + }; 71 + 72 + }; 73 + 74 + }; 75 + 76 + 77 + ###### implementation 78 + 79 + config = mkIf cfg.enable (lib.mkMerge [ 80 + { 81 + systemd.services.solanum = { 82 + description = "Solanum IRC daemon"; 83 + after = [ "network.target" ]; 84 + wantedBy = [ "multi-user.target" ]; 85 + environment = { 86 + BANDB_DBPATH = "/var/lib/solanum/ban.db"; 87 + }; 88 + serviceConfig = { 89 + ExecStart = "${solanum}/bin/solanum -foreground -logfile /dev/stdout -configfile ${configFile} -pidfile /run/solanum/ircd.pid"; 90 + DynamicUser = true; 91 + User = "solanum"; 92 + StateDirectory = "solanum"; 93 + RuntimeDirectory = "solanum"; 94 + LimitNOFILE = "${toString cfg.openFilesLimit}"; 95 + }; 96 + }; 97 + 98 + } 99 + 100 + (mkIf (cfg.motd != null) { 101 + environment.etc."solanum/ircd.motd".text = cfg.motd; 102 + }) 103 + ]); 104 + }
+1
nixos/tests/all-tests.nix
··· 384 snapcast = handleTest ./snapcast.nix {}; 385 snapper = handleTest ./snapper.nix {}; 386 sogo = handleTest ./sogo.nix {}; 387 solr = handleTest ./solr.nix {}; 388 sonarr = handleTest ./sonarr.nix {}; 389 spacecookie = handleTest ./spacecookie.nix {};
··· 384 snapcast = handleTest ./snapcast.nix {}; 385 snapper = handleTest ./snapper.nix {}; 386 sogo = handleTest ./sogo.nix {}; 387 + solanum = handleTest ./solanum.nix {}; 388 solr = handleTest ./solr.nix {}; 389 sonarr = handleTest ./sonarr.nix {}; 390 spacecookie = handleTest ./spacecookie.nix {};
+89
nixos/tests/solanum.nix
···
··· 1 + let 2 + clients = [ 3 + "ircclient1" 4 + "ircclient2" 5 + ]; 6 + server = "solanum"; 7 + ircPort = 6667; 8 + channel = "nixos-cat"; 9 + iiDir = "/tmp/irc"; 10 + in 11 + 12 + import ./make-test-python.nix ({ pkgs, lib, ... }: { 13 + name = "solanum"; 14 + nodes = { 15 + "${server}" = { 16 + networking.firewall.allowedTCPPorts = [ ircPort ]; 17 + services.solanum = { 18 + enable = true; 19 + }; 20 + }; 21 + } // lib.listToAttrs (builtins.map (client: lib.nameValuePair client { 22 + imports = [ 23 + ./common/user-account.nix 24 + ]; 25 + 26 + systemd.services.ii = { 27 + requires = [ "network.target" ]; 28 + wantedBy = [ "default.target" ]; 29 + 30 + serviceConfig = { 31 + Type = "simple"; 32 + ExecPreStartPre = "mkdir -p ${iiDir}"; 33 + ExecStart = '' 34 + ${lib.getBin pkgs.ii}/bin/ii -n ${client} -s ${server} -i ${iiDir} 35 + ''; 36 + User = "alice"; 37 + }; 38 + }; 39 + }) clients); 40 + 41 + testScript = 42 + let 43 + msg = client: "Hello, my name is ${client}"; 44 + clientScript = client: [ 45 + '' 46 + ${client}.wait_for_unit("network.target") 47 + ${client}.systemctl("start ii") 48 + ${client}.wait_for_unit("ii") 49 + ${client}.wait_for_file("${iiDir}/${server}/out") 50 + '' 51 + # wait until first PING from server arrives before joining, 52 + # so we don't try it too early 53 + '' 54 + ${client}.wait_until_succeeds("grep 'PING' ${iiDir}/${server}/out") 55 + '' 56 + # join ${channel} 57 + '' 58 + ${client}.succeed("echo '/j #${channel}' > ${iiDir}/${server}/in") 59 + ${client}.wait_for_file("${iiDir}/${server}/#${channel}/in") 60 + '' 61 + # send a greeting 62 + '' 63 + ${client}.succeed( 64 + "echo '${msg client}' > ${iiDir}/${server}/#${channel}/in" 65 + ) 66 + '' 67 + # check that all greetings arrived on all clients 68 + ] ++ builtins.map (other: '' 69 + ${client}.succeed( 70 + "grep '${msg other}$' ${iiDir}/${server}/#${channel}/out" 71 + ) 72 + '') clients; 73 + 74 + # foldl', but requires a non-empty list instead of a start value 75 + reduce = f: list: 76 + builtins.foldl' f (builtins.head list) (builtins.tail list); 77 + in '' 78 + start_all() 79 + ${server}.systemctl("status solanum") 80 + ${server}.wait_for_open_port(${toString ircPort}) 81 + 82 + # run clientScript for all clients so that every list 83 + # entry is executed by every client before advancing 84 + # to the next one. 85 + '' + lib.concatStrings 86 + (reduce 87 + (lib.zipListsWith (cs: c: cs + c)) 88 + (builtins.map clientScript clients)); 89 + })