diff options
Diffstat (limited to 'nixos/modules/services/misc/gitea.nix')
-rw-r--r-- | nixos/modules/services/misc/gitea.nix | 125 |
1 files changed, 81 insertions, 44 deletions
diff --git a/nixos/modules/services/misc/gitea.nix b/nixos/modules/services/misc/gitea.nix index 6fd4183bd6b4..59c1c104b9b9 100644 --- a/nixos/modules/services/misc/gitea.nix +++ b/nixos/modules/services/misc/gitea.nix @@ -38,6 +38,7 @@ let HTTP_PORT = ${toString cfg.httpPort} ROOT_URL = ${cfg.rootUrl} STATIC_ROOT_PATH = ${cfg.staticRootPath} + LFS_JWT_SECRET = #jwtsecret# [session] COOKIE_NAME = session @@ -54,6 +55,11 @@ let [service] DISABLE_REGISTRATION = ${boolToString cfg.disableRegistration} + ${optionalString (cfg.mailerPasswordFile != null) '' + [mailer] + PASSWD = #mailerpass# + ''} + ${cfg.extraConfig} ''; in @@ -159,7 +165,8 @@ in socket = mkOption { type = types.nullOr types.path; - default = null; + default = if (cfg.database.createDatabase && usePostgresql) then "/run/postgresql" else if (cfg.database.createDatabase && useMysql) then "/run/mysqld/mysqld.sock" else null; + defaultText = "null"; example = "/run/mysqld/mysqld.sock"; description = "Path to the unix socket file to use for authentication."; }; @@ -173,10 +180,7 @@ in createDatabase = mkOption { type = types.bool; default = true; - description = '' - Whether to create a local postgresql database automatically. - This only applies if database type "postgres" is selected. - ''; + description = "Whether to create a local database automatically."; }; }; @@ -256,6 +260,13 @@ in description = "Upper level of template and static files path."; }; + mailerPasswordFile = mkOption { + type = types.nullOr types.str; + default = null; + example = "/var/lib/secrets/gitea/mailpw"; + description = "Path to a file containing the SMTP password."; + }; + disableRegistration = mkEnableOption "the registration lock" // { description = '' By default any user can create an account on this <literal>gitea</literal> instance. @@ -277,7 +288,47 @@ in }; config = mkIf cfg.enable { - services.postgresql.enable = mkIf usePostgresql (mkDefault true); + assertions = [ + { assertion = cfg.database.createDatabase -> cfg.database.user == cfg.user; + message = "services.gitea.database.user must match services.gitea.user if the database is to be automatically provisioned"; + } + ]; + + services.postgresql = optionalAttrs (usePostgresql && cfg.database.createDatabase) { + enable = mkDefault true; + + ensureDatabases = [ cfg.database.name ]; + ensureUsers = [ + { name = cfg.database.user; + ensurePermissions = { "DATABASE ${cfg.database.name}" = "ALL PRIVILEGES"; }; + } + ]; + }; + + services.mysql = optionalAttrs (useMysql && cfg.database.createDatabase) { + enable = mkDefault true; + package = mkDefault pkgs.mariadb; + + ensureDatabases = [ cfg.database.name ]; + ensureUsers = [ + { name = cfg.database.user; + ensurePermissions = { "${cfg.database.name}.*" = "ALL PRIVILEGES"; }; + } + ]; + }; + + systemd.tmpfiles.rules = [ + "d '${cfg.stateDir}' - ${cfg.user} gitea - -" + "d '${cfg.stateDir}/conf' - ${cfg.user} gitea - -" + "d '${cfg.stateDir}/custom' - ${cfg.user} gitea - -" + "d '${cfg.stateDir}/custom/conf' - ${cfg.user} gitea - -" + "d '${cfg.repositoryRoot}' - ${cfg.user} gitea - -" + "Z '${cfg.stateDir}' - ${cfg.user} gitea - -" + + # If we have a folder or symlink with gitea locales, remove it + # And symlink the current gitea locales in place + "L+ '${cfg.stateDir}/conf/locale' - - - - ${gitea.out}/locale" + ]; systemd.services.gitea = { description = "gitea"; @@ -288,28 +339,36 @@ in preStart = let runConfig = "${cfg.stateDir}/custom/conf/app.ini"; secretKey = "${cfg.stateDir}/custom/conf/secret_key"; + jwtSecret = "${cfg.stateDir}/custom/conf/jwt_secret"; in '' - # Make sure that the stateDir exists, as well as the conf dir in there - mkdir -p ${cfg.stateDir}/conf - # copy custom configuration and generate a random secret key if needed ${optionalString (cfg.useWizard == false) '' - mkdir -p ${cfg.stateDir}/custom/conf cp -f ${configFile} ${runConfig} if [ ! -e ${secretKey} ]; then - head -c 16 /dev/urandom | base64 > ${secretKey} + ${gitea.bin}/bin/gitea generate secret SECRET_KEY > ${secretKey} + fi + + if [ ! -e ${jwtSecret} ]; then + ${gitea.bin}/bin/gitea generate secret LFS_JWT_SECRET > ${jwtSecret} fi - KEY=$(head -n1 ${secretKey}) - DBPASS=$(head -n1 ${cfg.database.passwordFile}) + KEY="$(head -n1 ${secretKey})" + DBPASS="$(head -n1 ${cfg.database.passwordFile})" + JWTSECRET="$(head -n1 ${jwtSecret})" + ${if (cfg.mailerPasswordFile == null) then '' + MAILERPASSWORD="#mailerpass#" + '' else '' + MAILERPASSWORD="$(head -n1 ${cfg.mailerPasswordFile} || :)" + ''} sed -e "s,#secretkey#,$KEY,g" \ -e "s,#dbpass#,$DBPASS,g" \ + -e "s,#jwtsecet#,$JWTSECET,g" \ + -e "s,#mailerpass#,$MAILERPASSWORD,g" \ -i ${runConfig} - chmod 640 ${runConfig} ${secretKey} + chmod 640 ${runConfig} ${secretKey} ${jwtSecret} ''} - mkdir -p ${cfg.repositoryRoot} # update all hooks' binary paths HOOKS=$(find ${cfg.repositoryRoot} -mindepth 4 -maxdepth 6 -type f -wholename "*git/hooks/*") if [ "$HOOKS" ] @@ -319,43 +378,19 @@ in sed -ri 's,/nix/store/[a-z0-9.-]+/bin/bash,${pkgs.bash}/bin/bash,g' $HOOKS sed -ri 's,/nix/store/[a-z0-9.-]+/bin/perl,${pkgs.perl}/bin/perl,g' $HOOKS fi - # If we have a folder or symlink with gitea locales, remove it - if [ -e ${cfg.stateDir}/conf/locale ] - then - rm -r ${cfg.stateDir}/conf/locale - fi - # And symlink the current gitea locales in place - ln -s ${gitea.out}/locale ${cfg.stateDir}/conf/locale + # update command option in authorized_keys if [ -r ${cfg.stateDir}/.ssh/authorized_keys ] then sed -ri 's,/nix/store/[a-z0-9.-]+/bin/gitea,${gitea.bin}/bin/gitea,g' ${cfg.stateDir}/.ssh/authorized_keys fi - '' + optionalString (usePostgresql && cfg.database.createDatabase) '' - if ! test -e "${cfg.stateDir}/db-created"; then - echo "CREATE ROLE ${cfg.database.user} - WITH ENCRYPTED PASSWORD '$(head -n1 ${cfg.database.passwordFile})' - NOCREATEDB NOCREATEROLE LOGIN" | - ${pkgs.sudo}/bin/sudo -u ${pg.superUser} ${pg.package}/bin/psql - ${pkgs.sudo}/bin/sudo -u ${pg.superUser} \ - ${pg.package}/bin/createdb \ - --owner=${cfg.database.user} \ - --encoding=UTF8 \ - --lc-collate=C \ - --lc-ctype=C \ - --template=template0 \ - ${cfg.database.name} - touch "${cfg.stateDir}/db-created" - fi - '' + '' - chown ${cfg.user} -R ${cfg.stateDir} ''; serviceConfig = { Type = "simple"; User = cfg.user; + Group = "gitea"; WorkingDirectory = cfg.stateDir; - PermissionsStartOnly = true; ExecStart = "${gitea.bin}/bin/gitea web"; Restart = "always"; }; @@ -367,15 +402,17 @@ in }; }; - users = mkIf (cfg.user == "gitea") { - users.gitea = { + users.users = mkIf (cfg.user == "gitea") { + gitea = { description = "Gitea Service"; home = cfg.stateDir; - createHome = true; useDefaultShell = true; + group = "gitea"; }; }; + users.groups.gitea = {}; + warnings = optional (cfg.database.password != "") ''config.services.gitea.database.password will be stored as plaintext in the Nix store. Use database.passwordFile instead.''; |