From 1eab8b2d6a34a9063931b5c0752a1479db7bc740 Mon Sep 17 00:00:00 2001 From: lassulus Date: Wed, 12 Jan 2022 20:35:25 +0100 Subject: [PATCH 1/3] ergochat: init at 2.9.1 --- pkgs/servers/irc/ergochat/default.nix | 24 ++++++++++++++++++++++++ pkgs/top-level/all-packages.nix | 2 ++ 2 files changed, 26 insertions(+) create mode 100644 pkgs/servers/irc/ergochat/default.nix diff --git a/pkgs/servers/irc/ergochat/default.nix b/pkgs/servers/irc/ergochat/default.nix new file mode 100644 index 000000000000..03042df9a31e --- /dev/null +++ b/pkgs/servers/irc/ergochat/default.nix @@ -0,0 +1,24 @@ +{ buildGo117Module, fetchFromGitHub, lib }: + +buildGo117Module rec { + pname = "ergo"; + version = "2.9.1"; + + src = fetchFromGitHub { + owner = "ergochat"; + repo = "ergo"; + rev = "v${version}"; + sha256 = "sha256-RxsmkTfHymferS/FRW0sLnstKfvGXkW6cEb/JbeS4lc="; + }; + + vendorSha256 = null; + + meta = { + changelog = "https://github.com/ergochat/ergo/blob/v${version}/CHANGELOG.md"; + description = "A modern IRC server (daemon/ircd) written in Go"; + homepage = "https://github.com/ergochat/ergo"; + license = lib.licenses.mit; + maintainers = with lib.maintainers; [ lassulus tv ]; + platforms = lib.platforms.linux; + }; +} diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix index de8a3228ea57..6f215af0d80b 100644 --- a/pkgs/top-level/all-packages.nix +++ b/pkgs/top-level/all-packages.nix @@ -20932,6 +20932,8 @@ with pkgs; gn = gn1924; }; + ergochat = callPackage ../servers/irc/ergochat { }; + etcd = etcd_3_3; etcd_3_3 = callPackage ../servers/etcd/3.3.nix { }; etcd_3_4 = callPackage ../servers/etcd/3.4.nix { }; From eaf8890a6c665801d0fddb0d0285fed242be8b0d Mon Sep 17 00:00:00 2001 From: lassulus Date: Wed, 12 Jan 2022 21:40:43 +0100 Subject: [PATCH 2/3] nixos/ergochat: init --- .../from_md/release-notes/rl-2205.section.xml | 7 + .../manual/release-notes/rl-2205.section.md | 2 + nixos/modules/module-list.nix | 1 + .../modules/services/networking/ergochat.nix | 155 ++++++++++++++++++ 4 files changed, 165 insertions(+) create mode 100644 nixos/modules/services/networking/ergochat.nix diff --git a/nixos/doc/manual/from_md/release-notes/rl-2205.section.xml b/nixos/doc/manual/from_md/release-notes/rl-2205.section.xml index dd8266ef1ba6..d195c1c22fcb 100644 --- a/nixos/doc/manual/from_md/release-notes/rl-2205.section.xml +++ b/nixos/doc/manual/from_md/release-notes/rl-2205.section.xml @@ -82,6 +82,13 @@ services.heisenbridge. + + + ergochat, a modern + IRC with IRCv3 features. Available as + services.ergochat. + + PowerDNS-Admin, diff --git a/nixos/doc/manual/release-notes/rl-2205.section.md b/nixos/doc/manual/release-notes/rl-2205.section.md index 7af73dbaf5a2..a656b0b28601 100644 --- a/nixos/doc/manual/release-notes/rl-2205.section.md +++ b/nixos/doc/manual/release-notes/rl-2205.section.md @@ -27,6 +27,8 @@ In addition to numerous new and upgraded packages, this release has the followin - [heisenbridge](https://github.com/hifi/heisenbridge), a bouncer-style Matrix IRC bridge. Available as [services.heisenbridge](options.html#opt-services.heisenbridge.enable). +- [ergochat](https://ergo.chat), a modern IRC with IRCv3 features. Available as [services.ergochat](options.html#opt-services.ergochat.enable). + - [PowerDNS-Admin](https://github.com/ngoduykhanh/PowerDNS-Admin), a web interface for the PowerDNS server. Available at [services.powerdns-admin](options.html#opt-services.powerdns-admin.enable). - [maddy](https://maddy.email), a composable all-in-one mail server. Available as [services.maddy](options.html#opt-services.maddy.enable). diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index e67496c185d7..db1d014bcc1b 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -739,6 +739,7 @@ ./services/networking/ejabberd.nix ./services/networking/epmd.nix ./services/networking/ergo.nix + ./services/networking/ergochat.nix ./services/networking/eternal-terminal.nix ./services/networking/fakeroute.nix ./services/networking/ferm.nix diff --git a/nixos/modules/services/networking/ergochat.nix b/nixos/modules/services/networking/ergochat.nix new file mode 100644 index 000000000000..cfaf69fc6139 --- /dev/null +++ b/nixos/modules/services/networking/ergochat.nix @@ -0,0 +1,155 @@ +{ config, lib, options, pkgs, ... }: let + cfg = config.services.ergochat; +in { + options = { + services.ergochat = { + + enable = lib.mkEnableOption "Ergo IRC daemon"; + + openFilesLimit = lib.mkOption { + type = lib.types.int; + default = 1024; + description = '' + Maximum number of open files. Limits the clients and server connections. + ''; + }; + + configFile = lib.mkOption { + type = lib.types.path; + default = (pkgs.formats.yaml {}).generate "ergo.conf" cfg.settings; + defaultText = "generated config file from .settings"; + description = '' + Path to configuration file. + Setting this will skip any configuration done via .settings + ''; + }; + + settings = lib.mkOption { + type = (pkgs.formats.yaml {}).type; + description = '' + Ergo IRC daemon configuration file. + https://raw.githubusercontent.com/ergochat/ergo/master/default.yaml + ''; + default = { + network = { + name = "testnetwork"; + }; + server = { + name = "example.com"; + listeners = { + ":6667" = {}; + }; + casemapping = "permissive"; + enforce-utf = true; + lookup-hostnames = false; + ip-cloaking = { + enabled = false; + }; + forward-confirm-hostnames = false; + check-ident = false; + relaymsg = { + enabled = false; + }; + max-sendq = "1M"; + ip-limits = { + count = false; + throttle = false; + }; + }; + datastore = { + autoupgrade = true; + # this points to the StateDirectory of the systemd service + path = "/var/lib/ergo/ircd.db"; + }; + accounts = { + authentication-enabled = true; + registration = { + enabled = true; + allow-before-connect = true; + throttling = { + enabled = true; + duration = "10m"; + max-attempts = 30; + }; + bcrypt-cost = 4; + email-verification.enabled = false; + }; + multiclient = { + enabled = true; + allowed-by-default = true; + always-on = "opt-out"; + auto-away = "opt-out"; + }; + }; + channels = { + default-modes = "+ntC"; + registration = { + enabled = true; + }; + }; + limits = { + nicklen = 32; + identlen = 20; + channellen = 64; + awaylen = 390; + kicklen = 390; + topiclen = 390; + }; + history = { + enabled = true; + channel-length = 2048; + client-length = 256; + autoresize-window = "3d"; + autoreplay-on-join = 0; + chathistory-maxmessages = 100; + znc-maxmessages = 2048; + restrictions = { + expire-time = "1w"; + query-cutoff = "none"; + grace-period = "1h"; + }; + retention = { + allow-individual-delete = false; + enable-account-indexing = false; + }; + tagmsg-storage = { + default = false; + whitelist = [ + "+draft/react" + "+react" + ]; + }; + }; + }; + }; + + }; + }; + config = lib.mkIf cfg.enable { + + environment.etc."ergo.yaml".source = cfg.configFile; + + # merge configured values with default values + services.ergochat.settings = + lib.mapAttrsRecursive (_: lib.mkDefault) options.services.ergochat.settings.default; + + systemd.services.ergochat = { + description = "Ergo IRC daemon"; + wantedBy = [ "multi-user.target" ]; + # reload is not applying the changed config. further investigation is needed + # at some point this should be enabled, since we don't want to restart for + # every config change + # reloadIfChanged = true; + restartTriggers = [ cfg.configFile ]; + serviceConfig = { + ExecStart = "${pkgs.ergochat}/bin/ergo run --conf /etc/ergo.yaml"; + ExecReload = "${pkgs.util-linux}/bin/kill -HUP $MAINPID"; + DynamicUser = true; + StateDirectory = "ergo"; + LimitNOFILE = toString cfg.openFilesLimit; + }; + }; + + }; + meta.maintainers = with lib.maintainers; [ lassulus tv ]; +} From 6b55249a5d0490fb4c00a8f0db677869ac643311 Mon Sep 17 00:00:00 2001 From: lassulus Date: Wed, 12 Jan 2022 21:47:27 +0100 Subject: [PATCH 3/3] nixos/tests/ergochat: init --- nixos/tests/all-tests.nix | 1 + nixos/tests/ergochat.nix | 97 +++++++++++++++++++++++++++ pkgs/servers/irc/ergochat/default.nix | 4 +- 3 files changed, 101 insertions(+), 1 deletion(-) create mode 100644 nixos/tests/ergochat.nix diff --git a/nixos/tests/all-tests.nix b/nixos/tests/all-tests.nix index 1282d62272e1..21e52a3da374 100644 --- a/nixos/tests/all-tests.nix +++ b/nixos/tests/all-tests.nix @@ -125,6 +125,7 @@ in enlightenment = handleTest ./enlightenment.nix {}; env = handleTest ./env.nix {}; ergo = handleTest ./ergo.nix {}; + ergochat = handleTest ./ergochat.nix {}; etcd = handleTestOn ["x86_64-linux"] ./etcd.nix {}; etcd-cluster = handleTestOn ["x86_64-linux"] ./etcd-cluster.nix {}; etebase-server = handleTest ./etebase-server.nix {}; diff --git a/nixos/tests/ergochat.nix b/nixos/tests/ergochat.nix new file mode 100644 index 000000000000..2e9dc55e648e --- /dev/null +++ b/nixos/tests/ergochat.nix @@ -0,0 +1,97 @@ +let + clients = [ + "ircclient1" + "ircclient2" + ]; + server = "ergochat"; + ircPort = 6667; + channel = "nixos-cat"; + iiDir = "/tmp/irc"; +in + +import ./make-test-python.nix ({ pkgs, lib, ... }: { + name = "ergochat"; + nodes = { + "${server}" = { + networking.firewall.allowedTCPPorts = [ ircPort ]; + services.ergochat = { + enable = true; + settings.server.motd = pkgs.writeText "ergo.motd" '' + The default MOTD doesn't contain the word "nixos" in it. + This one does. + ''; + }; + }; + } // 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") + '' + # look for the custom text in the MOTD. + '' + ${client}.wait_until_succeeds("grep 'nixos' ${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 ergochat") + ${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)); +}) diff --git a/pkgs/servers/irc/ergochat/default.nix b/pkgs/servers/irc/ergochat/default.nix index 03042df9a31e..1aa5f5158aa8 100644 --- a/pkgs/servers/irc/ergochat/default.nix +++ b/pkgs/servers/irc/ergochat/default.nix @@ -1,4 +1,4 @@ -{ buildGo117Module, fetchFromGitHub, lib }: +{ buildGo117Module, fetchFromGitHub, lib, nixosTests }: buildGo117Module rec { pname = "ergo"; @@ -13,6 +13,8 @@ buildGo117Module rec { vendorSha256 = null; + passthru.tests.ergochat = nixosTests.ergochat; + meta = { changelog = "https://github.com/ergochat/ergo/blob/v${version}/CHANGELOG.md"; description = "A modern IRC server (daemon/ircd) written in Go";