From b4878419ee2ca05c740505bacd7eb3e2b4beab24 Mon Sep 17 00:00:00 2001 From: NotAShelf Date: Wed, 11 Sep 2024 13:08:22 +0300 Subject: [PATCH] nixos/wakapi: add database options; gate db creation behind database.createLocally Currently the NixOS module for Wakapi will create the database automagically if the user has database dialect configured in the Wakapi configuration file. By all means, this is undocumented behaviour and an anti-feature. This MR adds a database.createLocally option that allows the end-user to create auto-creation behaviour, and lays out groundwork for automated database setups for different database dialects supported by Wakapi. --- nixos/modules/services/web-apps/wakapi.nix | 80 ++++++++++++++++++++-- 1 file changed, 75 insertions(+), 5 deletions(-) diff --git a/nixos/modules/services/web-apps/wakapi.nix b/nixos/modules/services/web-apps/wakapi.nix index 2dbfb6d9b3d5..b818c8083e87 100644 --- a/nixos/modules/services/web-apps/wakapi.nix +++ b/nixos/modules/services/web-apps/wakapi.nix @@ -66,6 +66,60 @@ in The path to a file containing the password for the smtp mailer used by Wakapi. ''; }; + + database = { + createLocally = mkEnableOption '' + automatic database configuration. + + ::: {.note} + Only PostgreSQL is supported for the time being. + ::: + ''; + + dialect = mkOption { + type = types.nullOr ( + types.enum [ + "postgres" + "sqlite3" + "mysql" + "cockroach" + "mssql" + ] + ); + default = cfg.settings.db.dialect or null; # handle case where dialect is not set + defaultText = '' + Database dialect from settings if {option}`services.wakatime.settings.db.dialect` + is set, or `null` otherwise. + ''; + description = '' + The database type to use for Wakapi. + ''; + }; + + name = mkOption { + type = types.str; + default = cfg.settings.db.name or "wakapi"; + defaultText = '' + Database name from settings if {option}`services.wakatime.settings.db.name` + is set, or "wakapi" otherwise. + ''; + description = '' + The name of the database to use for Wakapi. + ''; + }; + + user = mkOption { + type = types.str; + default = cfg.settings.db.user or "wakapi"; + defaultText = '' + User from settings if {option}`services.wakatime.settings.db.user` + is set, or "wakapi" otherwise. + ''; + description = '' + The name of the user to use for Wakapi. + ''; + }; + }; }; config = mkIf cfg.enable { @@ -73,10 +127,10 @@ in description = "Wakapi (self-hosted WakaTime-compatible backend)"; wants = [ "network-online.target" - ] ++ optional (cfg.settings.db.dialect == "postgres") "postgresql.service"; + ] ++ optional (cfg.database.dialect == "postgres") "postgresql.service"; after = [ "network-online.target" - ] ++ optional (cfg.settings.db.dialect == "postgres") "postgresql.service"; + ] ++ optional (cfg.database.dialect == "postgres") "postgresql.service"; wantedBy = [ "multi-user.target" ]; script = '' @@ -134,6 +188,19 @@ in assertion = cfg.smtpPassword != null -> cfg.smtpPasswordFile != null; message = "Both `services.wakapi.smtpPassword` `services.wakapi.smtpPasswordFile` should not be set at the same time."; } + { + assertion = cfg.db.createLocally -> cfg.db.dialect != null; + message = "`services.wakapi.database.createLocally` is true, but a database dialect is not set!"; + } + ]; + + warnings = [ + (lib.optionalString (cfg.db.createLocall -> cfg.db.dialect != "postgres") '' + You have enabled automatic database configuration, but the database dialect is not set to "posgres". + + The Wakapi module only supports for PostgreSQL. Please set `services.wakapi.database.createLocally` + to `false`, or switch to "postgres" as your database dialect. + '') ]; users = { @@ -145,10 +212,10 @@ in groups.wakapi = { }; }; - services.postgresql = mkIf (cfg.settings.db.dialect == "postgres") { + services.postgresql = mkIf (cfg.database.createLocally && cfg.database.dialect == "postgres") { enable = true; - ensureDatabases = singleton cfg.settings.db.name; + ensureDatabases = singleton cfg.database.name; ensureUsers = singleton { name = cfg.settings.db.user; ensureDBOwnership = true; @@ -160,5 +227,8 @@ in }; }; - meta.maintainers = with lib.maintainers; [ isabelroses ]; + meta.maintainers = with lib.maintainers; [ + isabelroses + NotAShelf + ]; }