From 35d75e4024fc713bb6d46db7380d31379eb78c55 Mon Sep 17 00:00:00 2001 From: chaos Date: Fri, 8 Sep 2023 11:36:35 +0100 Subject: [PATCH] tidying and name changes to module --- module/backend.nix | 116 +++++++++++++++++++++++++++------------------ module/default.nix | 41 ++++++++++------ 2 files changed, 97 insertions(+), 60 deletions(-) diff --git a/module/backend.nix b/module/backend.nix index fd2be8a..47f83f7 100644 --- a/module/backend.nix +++ b/module/backend.nix @@ -3,11 +3,19 @@ lib, pkgs, ... -}: -with lib; let +}: let + inherit (lib.modules) mkIf; + inherit (lib.trivial) boolToString; + inherit (lib.attrsets) mapAttrsToList optionalAttrs; + inherit (lib.strings) coptionalString oncatStringsSep; + inherit (pkgs) writeText writeShellScript; + cfg = config.services.piped; - backend_config = + sedEscapeSlashes = "sed 's#/#\\\/#'"; + sedEscapeSingleQuotes = "sed \"s#'#\\\'#\""; + + backendConfig = { PORT = cfg.internalBackendPort; HTTP_WORKERS = cfg.httpWorkers; @@ -23,21 +31,21 @@ with lib; let DISABLE_LBRY = cfg.disableLBRYStreams; RYD_PROXY_URL = cfg.rydAPIURL; SENTRY_DSN = cfg.sentryDSN; - "hibernate.connection.url" = "jdbc:postgresql://${cfg.postgresHost}:${toString cfg.postgresPort}/${cfg.postgresDB}"; + "hibernate.connection.url" = "jdbc:postgresql://${cfg.postgresDBHost}:${toString cfg.postgresDBPort}/${cfg.postgresDBName}"; "hibernate.connection.driver_class" = "org.postgresql.Driver"; "hibernate.dialect" = "org.hibernate.dialect.PostgreSQLDialect"; - "hibernate.connection.username" = "${cfg.postgresUsername}"; + "hibernate.connection.username" = "${cfg.postgresDBUsername}"; "hibernate.connection.password" = - if cfg.postgresPasswordFile == null - then cfg.postgresPassword - else "POSTGRES_PASSWORD"; + if cfg.postgresDBPasswordFile == null + then cfg.postgresDBPassword + else "POSTGRES_PASSWORD_PLACEHOLDER"; } // (optionalAttrs cfg.enableCaptcha { CAPTCHA_API_URL = cfg.captchaAPIURL; # This is substituted in the PreStart of piped-backend.service CAPTCHA_API_KEY = if cfg.captchaAPIKeyFile != "" - then "CAPTCHA_API_KEY_FILE" + then "CAPTCHA_API_KEY_FILE_PLACEHOLDER" else cfg.captchaAPIKey; }) // (optionalAttrs cfg.enableFederation { @@ -45,20 +53,25 @@ with lib; let # also substituted MATRIX_TOKEN = if cfg.matrixTokenFile != "" - then "MATRIX_TOKEN_FILE" + then "MATRIX_TOKEN_FILE_PLACEHOLDER" else cfg.matrixToken; }); - cfgToString = v: - if builtins.isBool v - then boolToString v - else toString v; - backend_config_file = - pkgs.writeText "config.properties" - (concatStringsSep "\n" - (mapAttrsToList (n: v: "${n}:${cfgToString v}") backend_config)); + cfgValueToString = value: + if builtins.isBool value + then boolToString value + else toString value; + + cfgToLine = key: value: "${key}:${cfgValueToString value}"; + + cfgToString = config: (concatStringsSep "\n" + (mapAttrsToList cfgToLine config)); + + backendConfigFile = + writeText "config.properties" + (cfgToString backendConfig); in { - config = lib.mkIf (cfg.enable && !cfg.disableBackend) { + config = mkIf (cfg.enable && !cfg.disableBackend) { systemd.tmpfiles.rules = ["d /run/piped-backend - piped piped"]; systemd.services.piped-backend = { @@ -67,22 +80,27 @@ in { WorkingDirectory = "/run/piped-backend"; ExecStartPre = let confFile = "/run/piped-backend/config.properties"; - in "${pkgs.writeShellScript "piped-backend-init" '' - [ -f "${confFile}" ] && rm ${confFile} - cp ${backend_config_file} ${confFile} - chmod 660 ${confFile} - ${optionalString (cfg.enableCaptcha && cfg.captchaAPIKeyFile != "") '' - sed -i "s/CAPTCHA_API_KEY_FILE/$(cat ${cfg.captchaAPIKeyFile} | sed "s#/#\\\/#")/" ${confFile} - ''} - ${optionalString - (cfg.enableFederation && cfg.matrixTokenFile != "") '' - sed -i "s/MATRIX_TOKEN_FILE/$(cat ${cfg.matrixTokenFile} | sed "s#/#\\\/#")/" ${confFile} + in + writeShellScript "piped-backend-init" '' + [ -f "${confFile}" ] && rm ${confFile} + cp ${backendConfigFile} ${confFile} + chmod 660 ${confFile} + + ${optionalString (cfg.enableCaptcha && cfg.captchaAPIKeyFile != "") '' + sed -i "s/CAPTCHA_API_KEY_FILE_PLACEHOLDER/$(cat ${cfg.captchaAPIKeyFile} | ${sedEscapeSlashes})/" ${confFile} ''} - ${optionalString - (cfg.postgresPasswordFile != null) '' - sed -i "s/POSTGRES_PASSWORD/$(cat ${cfg.postgresPasswordFile} | sed "s#/#\\\/#")/" ${confFile} - ''} - ''}"; + + ${optionalString + (cfg.enableFederation && cfg.matrixTokenFile != "") '' + sed -i "s/MATRIX_TOKEN_FILE_PLACEHOLDER/$(cat ${cfg.matrixTokenFile} | ${sedEscapeSlashes})/" ${confFile} + ''} + + ${optionalString + (cfg.postgresDBPasswordFile != null) '' + sed -i "s/POSTGRES_PASSWORD_PLACEHOLDER/$(cat ${cfg.postgresDBPasswordFile} | ${sedEscapeSlashes})/" ${confFile} + ''} + ''; + ExecStart = "${pkgs.piped-backend}/bin/piped-backend"; RestartSec = "5s"; @@ -101,33 +119,39 @@ in { }; }; - systemd.services.piped-password = lib.mkIf (!cfg.disablePostgres) { - serviceConfig.Type = "oneshot"; + # Set password for piped when running postgres as piped won't run with + # passwordless authentication + systemd.services.piped-password = mkIf (!cfg.disablePostgresDB) { + serviceConfig = { + Type = "oneshot"; + User = "postgres"; + }; + wantedBy = ["piped-backend.service"]; wants = ["postgresql.service"]; after = ["postgresql.service"]; + script = '' - ${pkgs.postgresql}/bin/psql -c "ALTER USER piped WITH PASSWORD '${ - if cfg.postgresPasswordFile != null - then "$(cat ${cfg.postgresPasswordFile} | sed \"s#'#\\\'#\")" - else cfg.postgresPassword + ${config.services.postgresql.package}/bin/psql -c "ALTER USER ${cfg.postgresDBUsername} WITH PASSWORD '${ + if cfg.postgresDBPasswordFile != null + then "$(cat ${cfg.postgresDBPasswordFile} | ${sedEscapeSingleQuotes})" + else cfg.postgresDBPassword }';" ''; - serviceConfig.User = "postgres"; }; - services.postgresql = lib.mkIf (!cfg.disablePostgres) { + services.postgresql = mkIf (!cfg.disablePostgresDB) { enable = true; ensureUsers = [ { - name = "piped"; - ensurePermissions."DATABASE piped" = "ALL PRIVILEGES"; + name = cfg.postgresDBUsername; + ensurePermissions."DATABASE ${cfg.postgresDBName}" = "ALL PRIVILEGES"; } ]; - ensureDatabases = ["piped"]; + ensureDatabases = [cfg.postgresDBName]; }; - services.nginx.virtualHosts."${cfg.backendDomain}" = lib.mkIf (!cfg.disableNginx) { + services.nginx.virtualHosts."${cfg.backendDomain}" = mkIf (!cfg.disableNginx) { forceSSL = cfg.nginxForceSSL; enableACME = cfg.nginxEnableACME; locations."/" = { diff --git a/module/default.nix b/module/default.nix index 761a366..3c968b6 100644 --- a/module/default.nix +++ b/module/default.nix @@ -2,34 +2,47 @@ config, lib, ... -}: -with lib; let +}: let + inherit (lib) types; + + inherit (lib.options) mkOption mkEnableOption; + cfg = config.services.piped; in { options.services.piped = { enable = mkEnableOption "piped"; - frontendDomain = mkOption {type = types.str;}; + frontendDomain = mkOption { + type = types.str; + description = "Domain where the frontend will be displayed"; + }; + backendDomain = mkOption { type = types.nullOr types.str; - default = null; - description = "Set to null to use project default backend"; + description = "Domain where the backend will be hosted. Set to null for project's default backend"; + }; + + proxyDomain = mkOption { + type = types.str; + description = "Domain used for the proxy server"; }; - proxyDomain = mkOption {type = types.str;}; - #rydProxyDomain = mkOption { type = types.str; }; disableNginx = mkOption { type = types.bool; default = false; + description = "Turn off module's nginx servers, this means you will need to manually proxy everything"; }; nginxForceSSL = mkOption { type = types.bool; default = false; + description = "Should SSL/TLS be force enabled by nginx"; }; + nginxEnableACME = mkOption { type = types.bool; default = false; + description = "Should ACME be force enabled by nginx"; }; disableFrontend = mkOption { @@ -59,34 +72,34 @@ in { postgresHost = mkOption { type = types.str; default = "127.0.0.1"; - description = "Host postgres is on"; + description = "Host for postgres"; }; postgresPort = mkOption { type = types.number; default = 5432; - description = "Port postgres is on"; + description = "Port for postgres"; }; - postgresDB = mkOption { + postgresDBName = mkOption { type = types.str; default = "piped"; description = "Database name for piped"; }; - postgresUsername = mkOption { + postgresDBUsername = mkOption { type = types.str; default = "piped"; description = "Host postgres is on"; }; - postgresPassword = mkOption { + postgresDBPassword = mkOption { type = types.str; default = "password"; description = "Password to use for postgres"; }; - postgresPasswordFile = mkOption { + postgresDBPasswordFile = mkOption { type = types.nullOr types.str; default = null; description = "Password file to use for postgres, loaded at runtime"; @@ -95,7 +108,7 @@ in { proxyIPv4Only = mkOption { type = types.bool; default = false; - description = "Only use IPv4 querying youtube's servers for proxy"; + description = "Only use IPv4 when querying youtube's servers"; }; proxyNginxExtraConfig = mkOption {