Unverified Commit b4878419 authored by NotAShelf's avatar NotAShelf
Browse files

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.
parent 876b1c2d
Loading
Loading
Loading
Loading
+75 −5
Original line number Diff line number Diff line
@@ -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
  ];
}