about summary refs log tree commit diff
path: root/nixpkgs/nixos/modules/services/misc/gitea.nix
diff options
context:
space:
mode:
Diffstat (limited to 'nixpkgs/nixos/modules/services/misc/gitea.nix')
-rw-r--r--nixpkgs/nixos/modules/services/misc/gitea.nix267
1 files changed, 131 insertions, 136 deletions
diff --git a/nixpkgs/nixos/modules/services/misc/gitea.nix b/nixpkgs/nixos/modules/services/misc/gitea.nix
index bc7bb663ee00..048ff3211654 100644
--- a/nixpkgs/nixos/modules/services/misc/gitea.nix
+++ b/nixpkgs/nixos/modules/services/misc/gitea.nix
@@ -10,6 +10,7 @@ let
   useMysql = cfg.database.type == "mysql";
   usePostgresql = cfg.database.type == "postgres";
   useSqlite = cfg.database.type == "sqlite3";
+  format = pkgs.formats.ini { };
   configFile = pkgs.writeText "app.ini" ''
     APP_NAME = ${cfg.appName}
     RUN_USER = ${cfg.user}
@@ -22,51 +23,47 @@ let
 in
 
 {
+  imports = [
+    (mkRenamedOptionModule [ "services" "gitea" "cookieSecure" ] [ "services" "gitea" "settings" "session" "COOKIE_SECURE" ])
+    (mkRenamedOptionModule [ "services" "gitea" "disableRegistration" ] [ "services" "gitea" "settings" "service" "DISABLE_REGISTRATION" ])
+    (mkRenamedOptionModule [ "services" "gitea" "log" "level" ] [ "services" "gitea" "settings" "log" "LEVEL" ])
+    (mkRenamedOptionModule [ "services" "gitea" "log" "rootPath" ] [ "services" "gitea" "settings" "log" "ROOT_PATH" ])
+    (mkRenamedOptionModule [ "services" "gitea" "ssh" "clonePort" ] [ "services" "gitea" "settings" "server" "SSH_PORT" ])
+
+    (mkRemovedOptionModule [ "services" "gitea" "ssh" "enable" ] "services.gitea.ssh.enable has been migrated into freeform setting services.gitea.settings.server.DISABLE_SSH. Keep in mind that the setting is inverted")
+  ];
+
   options = {
     services.gitea = {
       enable = mkOption {
         default = false;
         type = types.bool;
-        description = "Enable Gitea Service.";
+        description = lib.mdDoc "Enable Gitea Service.";
       };
 
       package = mkOption {
         default = pkgs.gitea;
         type = types.package;
         defaultText = literalExpression "pkgs.gitea";
-        description = "gitea derivation to use";
+        description = lib.mdDoc "gitea derivation to use";
       };
 
       useWizard = mkOption {
         default = false;
         type = types.bool;
-        description = "Do not generate a configuration and use gitea' installation wizard instead. The first registered user will be administrator.";
+        description = lib.mdDoc "Do not generate a configuration and use gitea' installation wizard instead. The first registered user will be administrator.";
       };
 
       stateDir = mkOption {
         default = "/var/lib/gitea";
         type = types.str;
-        description = "gitea data directory.";
-      };
-
-      log = {
-        rootPath = mkOption {
-          default = "${cfg.stateDir}/log";
-          defaultText = literalExpression ''"''${config.${opt.stateDir}}/log"'';
-          type = types.str;
-          description = "Root path for log files.";
-        };
-        level = mkOption {
-          default = "Info";
-          type = types.enum [ "Trace" "Debug" "Info" "Warn" "Error" "Critical" ];
-          description = "General log level.";
-        };
+        description = lib.mdDoc "gitea data directory.";
       };
 
       user = mkOption {
         type = types.str;
         default = "gitea";
-        description = "User account under which gitea runs.";
+        description = lib.mdDoc "User account under which gitea runs.";
       };
 
       database = {
@@ -74,45 +71,45 @@ in
           type = types.enum [ "sqlite3" "mysql" "postgres" ];
           example = "mysql";
           default = "sqlite3";
-          description = "Database engine to use.";
+          description = lib.mdDoc "Database engine to use.";
         };
 
         host = mkOption {
           type = types.str;
           default = "127.0.0.1";
-          description = "Database host address.";
+          description = lib.mdDoc "Database host address.";
         };
 
         port = mkOption {
           type = types.port;
-          default = (if !usePostgresql then 3306 else pg.port);
+          default = if !usePostgresql then 3306 else pg.port;
           defaultText = literalExpression ''
             if config.${opt.database.type} != "postgresql"
             then 3306
             else config.${options.services.postgresql.port}
           '';
-          description = "Database host port.";
+          description = lib.mdDoc "Database host port.";
         };
 
         name = mkOption {
           type = types.str;
           default = "gitea";
-          description = "Database name.";
+          description = lib.mdDoc "Database name.";
         };
 
         user = mkOption {
           type = types.str;
           default = "gitea";
-          description = "Database user.";
+          description = lib.mdDoc "Database user.";
         };
 
         password = mkOption {
           type = types.str;
           default = "";
-          description = ''
-            The password corresponding to <option>database.user</option>.
+          description = lib.mdDoc ''
+            The password corresponding to {option}`database.user`.
             Warning: this is stored in cleartext in the Nix store!
-            Use <option>database.passwordFile</option> instead.
+            Use {option}`database.passwordFile` instead.
           '';
         };
 
@@ -120,9 +117,9 @@ in
           type = types.nullOr types.path;
           default = null;
           example = "/run/keys/gitea-dbpassword";
-          description = ''
+          description = lib.mdDoc ''
             A file containing the password corresponding to
-            <option>database.user</option>.
+            {option}`database.user`.
           '';
         };
 
@@ -131,20 +128,20 @@ in
           default = if (cfg.database.createDatabase && usePostgresql) then "/run/postgresql" else if (cfg.database.createDatabase && useMysql) then "/run/mysqld/mysqld.sock" else null;
           defaultText = literalExpression "null";
           example = "/run/mysqld/mysqld.sock";
-          description = "Path to the unix socket file to use for authentication.";
+          description = lib.mdDoc "Path to the unix socket file to use for authentication.";
         };
 
         path = mkOption {
           type = types.str;
           default = "${cfg.stateDir}/data/gitea.db";
           defaultText = literalExpression ''"''${config.${opt.stateDir}}/data/gitea.db"'';
-          description = "Path to the sqlite3 database file.";
+          description = lib.mdDoc "Path to the sqlite3 database file.";
         };
 
         createDatabase = mkOption {
           type = types.bool;
           default = true;
-          description = "Whether to create a local database automatically.";
+          description = lib.mdDoc "Whether to create a local database automatically.";
         };
       };
 
@@ -152,7 +149,7 @@ in
         enable = mkOption {
           type = types.bool;
           default = false;
-          description = ''
+          description = lib.mdDoc ''
             Enable a timer that runs gitea dump to generate backup-files of the
             current gitea database and repositories.
           '';
@@ -162,12 +159,11 @@ in
           type = types.str;
           default = "04:31";
           example = "hourly";
-          description = ''
+          description = lib.mdDoc ''
             Run a gitea dump at this interval. Runs by default at 04:31 every day.
 
             The format is described in
-            <citerefentry><refentrytitle>systemd.time</refentrytitle>
-            <manvolnum>7</manvolnum></citerefentry>.
+            {manpage}`systemd.time(7)`.
           '';
         };
 
@@ -175,13 +171,13 @@ in
           type = types.str;
           default = "${cfg.stateDir}/dump";
           defaultText = literalExpression ''"''${config.${opt.stateDir}}/dump"'';
-          description = "Path to the dump files.";
+          description = lib.mdDoc "Path to the dump files.";
         };
 
         type = mkOption {
           type = types.enum [ "zip" "rar" "tar" "sz" "tar.gz" "tar.xz" "tar.bz2" "tar.br" "tar.lz4" ];
           default = "zip";
-          description = "Archive format used to store the dump file.";
+          description = lib.mdDoc "Archive format used to store the dump file.";
         };
 
         file = mkOption {
@@ -192,90 +188,62 @@ in
         };
       };
 
-      ssh = {
-        enable = mkOption {
-          type = types.bool;
-          default = true;
-          description = "Enable external SSH feature.";
-        };
-
-        clonePort = mkOption {
-          type = types.int;
-          default = 22;
-          example = 2222;
-          description = ''
-            SSH port displayed in clone URL.
-            The option is required to configure a service when the external visible port
-            differs from the local listening port i.e. if port forwarding is used.
-          '';
-        };
-      };
-
       lfs = {
         enable = mkOption {
           type = types.bool;
           default = false;
-          description = "Enables git-lfs support.";
+          description = lib.mdDoc "Enables git-lfs support.";
         };
 
         contentDir = mkOption {
           type = types.str;
           default = "${cfg.stateDir}/data/lfs";
           defaultText = literalExpression ''"''${config.${opt.stateDir}}/data/lfs"'';
-          description = "Where to store LFS files.";
+          description = lib.mdDoc "Where to store LFS files.";
         };
       };
 
       appName = mkOption {
         type = types.str;
         default = "gitea: Gitea Service";
-        description = "Application name.";
+        description = lib.mdDoc "Application name.";
       };
 
       repositoryRoot = mkOption {
         type = types.str;
         default = "${cfg.stateDir}/repositories";
         defaultText = literalExpression ''"''${config.${opt.stateDir}}/repositories"'';
-        description = "Path to the git repositories.";
+        description = lib.mdDoc "Path to the git repositories.";
       };
 
       domain = mkOption {
         type = types.str;
         default = "localhost";
-        description = "Domain name of your server.";
+        description = lib.mdDoc "Domain name of your server.";
       };
 
       rootUrl = mkOption {
         type = types.str;
         default = "http://localhost:3000/";
-        description = "Full public URL of gitea server.";
+        description = lib.mdDoc "Full public URL of gitea server.";
       };
 
       httpAddress = mkOption {
         type = types.str;
         default = "0.0.0.0";
-        description = "HTTP listen address.";
+        description = lib.mdDoc "HTTP listen address.";
       };
 
       httpPort = mkOption {
         type = types.int;
         default = 3000;
-        description = "HTTP listen port.";
+        description = lib.mdDoc "HTTP listen port.";
       };
 
       enableUnixSocket = mkOption {
         type = types.bool;
         default = false;
-        description = "Configure Gitea to listen on a unix socket instead of the default TCP port.";
-      };
-
-      cookieSecure = mkOption {
-        type = types.bool;
-        default = false;
-        description = ''
-          Marks session cookies as "secure" as a hint for browsers to only send
-          them via HTTPS. This option is recommend, if gitea is being served over HTTPS.
-        '';
+        description = lib.mdDoc "Configure Gitea to listen on a unix socket instead of the default TCP port.";
       };
 
       staticRootPath = mkOption {
@@ -283,33 +251,20 @@ in
         default = gitea.data;
         defaultText = literalExpression "package.data";
         example = "/var/lib/gitea/data";
-        description = "Upper level of template and static files path.";
+        description = lib.mdDoc "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.
-          This can be disabled by using this option.
-
-          <emphasis>Note:</emphasis> please keep in mind that this should be added after the initial
-          deploy unless <link linkend="opt-services.gitea.useWizard">services.gitea.useWizard</link>
-          is <literal>true</literal> as the first registered user will be the administrator if
-          no install wizard is used.
-        '';
+        description = lib.mdDoc "Path to a file containing the SMTP password.";
       };
 
       settings = mkOption {
-        type = with types; attrsOf (attrsOf (oneOf [ bool int str ]));
         default = {};
-        description = ''
-          Gitea configuration. Refer to <link xlink:href="https://docs.gitea.io/en-us/config-cheat-sheet/"/>
+        description = lib.mdDoc ''
+          Gitea configuration. Refer to <https://docs.gitea.io/en-us/config-cheat-sheet/>
           for details on supported values.
         '';
         example = literalExpression ''
@@ -330,12 +285,74 @@ in
             };
           }
         '';
+        type = with types; submodule {
+          freeformType = format.type;
+          options = {
+            log = {
+              ROOT_PATH = mkOption {
+                default = "${cfg.stateDir}/log";
+                defaultText = literalExpression ''"''${config.${opt.stateDir}}/log"'';
+                type = types.str;
+                description = "Root path for log files.";
+              };
+              LEVEL = mkOption {
+                default = "Info";
+                type = types.enum [ "Trace" "Debug" "Info" "Warn" "Error" "Critical" ];
+                description = "General log level.";
+              };
+            };
+
+            server = {
+              DISABLE_SSH = mkOption {
+                type = types.bool;
+                default = false;
+                description = "Disable external SSH feature.";
+              };
+
+              SSH_PORT = mkOption {
+                type = types.int;
+                default = 22;
+                example = 2222;
+                description = ''
+                  SSH port displayed in clone URL.
+                  The option is required to configure a service when the external visible port
+                  differs from the local listening port i.e. if port forwarding is used.
+                '';
+              };
+            };
+
+            service = {
+              DISABLE_REGISTRATION = mkEnableOption "the registration lock" // {
+                description = ''
+                  By default any user can create an account on this <literal>gitea</literal> instance.
+                  This can be disabled by using this option.
+
+                  <emphasis>Note:</emphasis> please keep in mind that this should be added after the initial
+                  deploy unless <link linkend="opt-services.gitea.useWizard">services.gitea.useWizard</link>
+                  is <literal>true</literal> as the first registered user will be the administrator if
+                  no install wizard is used.
+                '';
+              };
+            };
+
+            session = {
+              COOKIE_SECURE = mkOption {
+                type = types.bool;
+                default = false;
+                description = ''
+                  Marks session cookies as "secure" as a hint for browsers to only send
+                  them via HTTPS. This option is recommend, if gitea is being served over HTTPS.
+                '';
+              };
+            };
+          };
+        };
       };
 
       extraConfig = mkOption {
         type = with types; nullOr str;
         default = null;
-        description = "Configuration lines appended to the generated gitea configuration file.";
+        description = lib.mdDoc "Configuration lines appended to the generated gitea configuration file.";
       };
     };
   };
@@ -385,13 +402,6 @@ in
           HTTP_ADDR = cfg.httpAddress;
           HTTP_PORT = cfg.httpPort;
         })
-        (mkIf cfg.ssh.enable {
-          DISABLE_SSH = false;
-          SSH_PORT = cfg.ssh.clonePort;
-        })
-        (mkIf (!cfg.ssh.enable) {
-          DISABLE_SSH = true;
-        })
         (mkIf cfg.lfs.enable {
           LFS_START_SERVER = true;
           LFS_CONTENT_PATH = cfg.lfs.contentDir;
@@ -400,8 +410,7 @@ in
       ];
 
       session = {
-        COOKIE_NAME = "session";
-        COOKIE_SECURE = cfg.cookieSecure;
+        COOKIE_NAME = lib.mkDefault "session";
       };
 
       security = {
@@ -410,15 +419,6 @@ in
         INSTALL_LOCK = true;
       };
 
-      log = {
-        ROOT_PATH = cfg.log.rootPath;
-        LEVEL = cfg.log.level;
-      };
-
-      service = {
-        DISABLE_REGISTRATION = cfg.disableRegistration;
-      };
-
       mailer = mkIf (cfg.mailerPasswordFile != null) {
         PASSWD = "#mailerpass#";
       };
@@ -499,50 +499,45 @@ in
         oldLfsJwtSecret = "${cfg.stateDir}/custom/conf/jwt_secret"; # old file for LFS_JWT_SECRET
         lfsJwtSecret = "${cfg.stateDir}/custom/conf/lfs_jwt_secret"; # new file for LFS_JWT_SECRET
         internalToken = "${cfg.stateDir}/custom/conf/internal_token";
+        replaceSecretBin = "${pkgs.replace-secret}/bin/replace-secret";
       in ''
         # copy custom configuration and generate a random secret key if needed
-        ${optionalString (cfg.useWizard == false) ''
+        ${optionalString (!cfg.useWizard) ''
           function gitea_setup {
             cp -f ${configFile} ${runConfig}
 
-            if [ ! -e ${secretKey} ]; then
+            if [ ! -s ${secretKey} ]; then
                 ${gitea}/bin/gitea generate secret SECRET_KEY > ${secretKey}
             fi
 
             # Migrate LFS_JWT_SECRET filename
-            if [[ -e ${oldLfsJwtSecret} && ! -e ${lfsJwtSecret} ]]; then
+            if [[ -s ${oldLfsJwtSecret} && ! -s ${lfsJwtSecret} ]]; then
                 mv ${oldLfsJwtSecret} ${lfsJwtSecret}
             fi
 
-            if [ ! -e ${oauth2JwtSecret} ]; then
+            if [ ! -s ${oauth2JwtSecret} ]; then
                 ${gitea}/bin/gitea generate secret JWT_SECRET > ${oauth2JwtSecret}
             fi
 
-            if [ ! -e ${lfsJwtSecret} ]; then
+            if [ ! -s ${lfsJwtSecret} ]; then
                 ${gitea}/bin/gitea generate secret LFS_JWT_SECRET > ${lfsJwtSecret}
             fi
 
-            if [ ! -e ${internalToken} ]; then
+            if [ ! -s ${internalToken} ]; then
                 ${gitea}/bin/gitea generate secret INTERNAL_TOKEN > ${internalToken}
             fi
 
-            SECRETKEY="$(head -n1 ${secretKey})"
-            DBPASS="$(head -n1 ${cfg.database.passwordFile})"
-            OAUTH2JWTSECRET="$(head -n1 ${oauth2JwtSecret})"
-            LFSJWTSECRET="$(head -n1 ${lfsJwtSecret})"
-            INTERNALTOKEN="$(head -n1 ${internalToken})"
-            ${if (cfg.mailerPasswordFile == null) then ''
-              MAILERPASSWORD="#mailerpass#"
-            '' else ''
-              MAILERPASSWORD="$(head -n1 ${cfg.mailerPasswordFile} || :)"
+            chmod u+w '${runConfig}'
+            ${replaceSecretBin} '#secretkey#' '${secretKey}' '${runConfig}'
+            ${replaceSecretBin} '#dbpass#' '${cfg.database.passwordFile}' '${runConfig}'
+            ${replaceSecretBin} '#oauth2jwtsecret#' '${oauth2JwtSecret}' '${runConfig}'
+            ${replaceSecretBin} '#lfsjwtsecret#' '${lfsJwtSecret}' '${runConfig}'
+            ${replaceSecretBin} '#internaltoken#' '${internalToken}' '${runConfig}'
+
+            ${lib.optionalString (cfg.mailerPasswordFile != null) ''
+              ${replaceSecretBin} '#mailerpass#' '${cfg.mailerPasswordFile}' '${runConfig}'
             ''}
-            sed -e "s,#secretkey#,$SECRETKEY,g" \
-                -e "s,#dbpass#,$DBPASS,g" \
-                -e "s,#oauth2jwtsecret#,$OAUTH2JWTSECRET,g" \
-                -e "s,#lfsjwtsecret#,$LFSJWTSECRET,g" \
-                -e "s,#internaltoken#,$INTERNALTOKEN,g" \
-                -e "s,#mailerpass#,$MAILERPASSWORD,g" \
-                -i ${runConfig}
+            chmod u-w '${runConfig}'
           }
           (umask 027; gitea_setup)
         ''}
@@ -627,10 +622,10 @@ in
 
     # Create database passwordFile default when password is configured.
     services.gitea.database.passwordFile =
-      (mkDefault (toString (pkgs.writeTextFile {
+      mkDefault (toString (pkgs.writeTextFile {
         name = "gitea-database-password";
         text = cfg.database.password;
-      })));
+      }));
 
     systemd.services.gitea-dump = mkIf cfg.dump.enable {
        description = "gitea dump";