diff options
Diffstat (limited to 'ops/modules/panettone.nix')
-rw-r--r-- | ops/modules/panettone.nix | 119 |
1 files changed, 119 insertions, 0 deletions
diff --git a/ops/modules/panettone.nix b/ops/modules/panettone.nix new file mode 100644 index 000000000000..e23dd028ab3c --- /dev/null +++ b/ops/modules/panettone.nix @@ -0,0 +1,119 @@ +{ depot, config, lib, pkgs, ... }: + +let + cfg = config.services.depot.panettone; +in +{ + options.services.depot.panettone = with lib; { + enable = mkEnableOption "Panettone issue tracker"; + + port = mkOption { + description = "Port on which Panettone should listen"; + type = types.int; + default = 7268; + }; + + dbHost = mkOption { + description = "Postgresql host to connect to for Panettone"; + type = types.str; + default = "localhost"; + }; + + dbName = mkOption { + description = "Name of the database for Panettone"; + type = types.str; + default = "panettone"; + }; + + dbUser = mkOption { + description = "Name of the database user for Panettone"; + type = types.str; + default = "panettone"; + }; + + secretsFile = mkOption { + description = '' + Path to a file containing secrets, in the format accepted + by systemd's EnvironmentFile + ''; + type = types.str; + default = config.age.secretsDir + "/panettone"; + }; + + irccatHost = mkOption { + description = "Hostname for the irccat instance"; + type = types.str; + default = "localhost"; + }; + + irccatPort = mkOption { + description = "Port for the irccat instance"; + type = types.int; + default = 4722; + }; + + irccatChannel = mkOption { + description = "IRC channels to post to via irccat"; + type = types.str; + }; + }; + + config = lib.mkIf cfg.enable { + assertions = [{ + assertion = + cfg.dbHost != "localhost" || config.services.postgresql.enable; + message = "Panettone requires a postgresql database"; + } + { + assertion = + cfg.dbHost != "localhost" || config.services.postgresql.enableTCPIP; + message = "Panettone can only connect to the postgresql database over TCP"; + } + { + assertion = + cfg.dbHost != "localhost" || (lib.any + (user: user.name == cfg.dbUser) + config.services.postgresql.ensureUsers); + message = "Panettone requires a database user"; + } + { + assertion = + cfg.dbHost != "localhost" || (lib.any + (db: db == cfg.dbName) + config.services.postgresql.ensureDatabases); + message = "Panettone requires a database"; + }]; + + systemd.services.panettone = { + wantedBy = [ "multi-user.target" ]; + script = "${depot.web.panettone}/bin/panettone"; + + serviceConfig = { + DynamicUser = true; + Restart = "always"; + EnvironmentFile = cfg.secretsFile; + }; + + environment = { + PANETTONE_PORT = toString cfg.port; + PGHOST = "localhost"; + PGUSER = cfg.dbUser; + PGDATABASE = cfg.dbName; + IRCCATHOST = cfg.irccatHost; + IRCCATPORT = toString cfg.irccatPort; + ISSUECHANNEL = cfg.irccatChannel; + }; + }; + + systemd.services.panettone-fixer = { + description = "Restart panettone regularly to work around b/225"; + wantedBy = [ "multi-user.target" ]; + script = "${pkgs.systemd}/bin/systemctl restart panettone"; + serviceConfig.Type = "oneshot"; + + # We don't exactly know how frequently this occurs, but + # _probably_ not more than hourly. + startAt = "hourly"; + }; + }; +} |