python3Packages.orjson: Disable failing tests on 32 bit
[NixPkgs.git] / nixos / modules / services / misc / gogs.nix
blobfa172ed277dc4e0de369fa69f7c034079291a878
1 { config, lib, options, pkgs, ... }:
3 with lib;
5 let
6   cfg = config.services.gogs;
7   opt = options.services.gogs;
8   configFile = pkgs.writeText "app.ini" ''
9     APP_NAME = ${cfg.appName}
10     RUN_USER = ${cfg.user}
11     RUN_MODE = prod
13     [database]
14     DB_TYPE = ${cfg.database.type}
15     HOST = ${cfg.database.host}:${toString cfg.database.port}
16     NAME = ${cfg.database.name}
17     USER = ${cfg.database.user}
18     PASSWD = #dbpass#
19     PATH = ${cfg.database.path}
21     [repository]
22     ROOT = ${cfg.repositoryRoot}
24     [server]
25     DOMAIN = ${cfg.domain}
26     HTTP_ADDR = ${cfg.httpAddress}
27     HTTP_PORT = ${toString cfg.httpPort}
28     ROOT_URL = ${cfg.rootUrl}
30     [session]
31     COOKIE_NAME = session
32     COOKIE_SECURE = ${boolToString cfg.cookieSecure}
34     [security]
35     SECRET_KEY = #secretkey#
36     INSTALL_LOCK = true
38     [log]
39     ROOT_PATH = ${cfg.stateDir}/log
41     ${cfg.extraConfig}
42   '';
46   options = {
47     services.gogs = {
48       enable = mkOption {
49         default = false;
50         type = types.bool;
51         description = lib.mdDoc "Enable Go Git Service.";
52       };
54       useWizard = mkOption {
55         default = false;
56         type = types.bool;
57         description = lib.mdDoc "Do not generate a configuration and use Gogs' installation wizard instead. The first registered user will be administrator.";
58       };
60       stateDir = mkOption {
61         default = "/var/lib/gogs";
62         type = types.str;
63         description = lib.mdDoc "Gogs data directory.";
64       };
66       user = mkOption {
67         type = types.str;
68         default = "gogs";
69         description = lib.mdDoc "User account under which Gogs runs.";
70       };
72       group = mkOption {
73         type = types.str;
74         default = "gogs";
75         description = lib.mdDoc "Group account under which Gogs runs.";
76       };
78       database = {
79         type = mkOption {
80           type = types.enum [ "sqlite3" "mysql" "postgres" ];
81           example = "mysql";
82           default = "sqlite3";
83           description = lib.mdDoc "Database engine to use.";
84         };
86         host = mkOption {
87           type = types.str;
88           default = "127.0.0.1";
89           description = lib.mdDoc "Database host address.";
90         };
92         port = mkOption {
93           type = types.port;
94           default = 3306;
95           description = lib.mdDoc "Database host port.";
96         };
98         name = mkOption {
99           type = types.str;
100           default = "gogs";
101           description = lib.mdDoc "Database name.";
102         };
104         user = mkOption {
105           type = types.str;
106           default = "gogs";
107           description = lib.mdDoc "Database user.";
108         };
110         password = mkOption {
111           type = types.str;
112           default = "";
113           description = lib.mdDoc ''
114             The password corresponding to {option}`database.user`.
115             Warning: this is stored in cleartext in the Nix store!
116             Use {option}`database.passwordFile` instead.
117           '';
118         };
120         passwordFile = mkOption {
121           type = types.nullOr types.path;
122           default = null;
123           example = "/run/keys/gogs-dbpassword";
124           description = lib.mdDoc ''
125             A file containing the password corresponding to
126             {option}`database.user`.
127           '';
128         };
130         path = mkOption {
131           type = types.str;
132           default = "${cfg.stateDir}/data/gogs.db";
133           defaultText = literalExpression ''"''${config.${opt.stateDir}}/data/gogs.db"'';
134           description = lib.mdDoc "Path to the sqlite3 database file.";
135         };
136       };
138       appName = mkOption {
139         type = types.str;
140         default = "Gogs: Go Git Service";
141         description = lib.mdDoc "Application name.";
142       };
144       repositoryRoot = mkOption {
145         type = types.str;
146         default = "${cfg.stateDir}/repositories";
147         defaultText = literalExpression ''"''${config.${opt.stateDir}}/repositories"'';
148         description = lib.mdDoc "Path to the git repositories.";
149       };
151       domain = mkOption {
152         type = types.str;
153         default = "localhost";
154         description = lib.mdDoc "Domain name of your server.";
155       };
157       rootUrl = mkOption {
158         type = types.str;
159         default = "http://localhost:3000/";
160         description = lib.mdDoc "Full public URL of Gogs server.";
161       };
163       httpAddress = mkOption {
164         type = types.str;
165         default = "0.0.0.0";
166         description = lib.mdDoc "HTTP listen address.";
167       };
169       httpPort = mkOption {
170         type = types.port;
171         default = 3000;
172         description = lib.mdDoc "HTTP listen port.";
173       };
175       cookieSecure = mkOption {
176         type = types.bool;
177         default = false;
178         description = lib.mdDoc ''
179           Marks session cookies as "secure" as a hint for browsers to only send
180           them via HTTPS. This option is recommend, if Gogs is being served over HTTPS.
181         '';
182       };
184       extraConfig = mkOption {
185         type = types.str;
186         default = "";
187         description = lib.mdDoc "Configuration lines appended to the generated Gogs configuration file.";
188       };
189     };
190   };
192   config = mkIf cfg.enable {
194     systemd.services.gogs = {
195       description = "Gogs (Go Git Service)";
196       after = [ "network.target" ];
197       wantedBy = [ "multi-user.target" ];
198       path = [ pkgs.gogs ];
200       preStart = let
201         runConfig = "${cfg.stateDir}/custom/conf/app.ini";
202         secretKey = "${cfg.stateDir}/custom/conf/secret_key";
203       in ''
204         mkdir -p ${cfg.stateDir}
206         # copy custom configuration and generate a random secret key if needed
207         ${optionalString (cfg.useWizard == false) ''
208           mkdir -p ${cfg.stateDir}/custom/conf
209           cp -f ${configFile} ${runConfig}
211           if [ ! -e ${secretKey} ]; then
212               head -c 16 /dev/urandom | base64 > ${secretKey}
213           fi
215           KEY=$(head -n1 ${secretKey})
216           DBPASS=$(head -n1 ${cfg.database.passwordFile})
217           sed -e "s,#secretkey#,$KEY,g" \
218               -e "s,#dbpass#,$DBPASS,g" \
219               -i ${runConfig}
220           chmod 440 ${runConfig} ${secretKey}
221         ''}
223         mkdir -p ${cfg.repositoryRoot}
224         # update all hooks' binary paths
225         HOOKS=$(find ${cfg.repositoryRoot} -mindepth 4 -maxdepth 4 -type f -wholename "*git/hooks/*")
226         if [ "$HOOKS" ]
227         then
228           sed -ri 's,/nix/store/[a-z0-9.-]+/bin/gogs,${pkgs.gogs}/bin/gogs,g' $HOOKS
229           sed -ri 's,/nix/store/[a-z0-9.-]+/bin/env,${pkgs.coreutils}/bin/env,g' $HOOKS
230           sed -ri 's,/nix/store/[a-z0-9.-]+/bin/bash,${pkgs.bash}/bin/bash,g' $HOOKS
231           sed -ri 's,/nix/store/[a-z0-9.-]+/bin/perl,${pkgs.perl}/bin/perl,g' $HOOKS
232         fi
233       '';
235       serviceConfig = {
236         Type = "simple";
237         User = cfg.user;
238         Group = cfg.group;
239         WorkingDirectory = cfg.stateDir;
240         ExecStart = "${pkgs.gogs}/bin/gogs web";
241         Restart = "always";
242       };
244       environment = {
245         USER = cfg.user;
246         HOME = cfg.stateDir;
247         GOGS_WORK_DIR = cfg.stateDir;
248       };
249     };
251     users = mkIf (cfg.user == "gogs") {
252       users.gogs = {
253         description = "Go Git Service";
254         uid = config.ids.uids.gogs;
255         group = "gogs";
256         home = cfg.stateDir;
257         createHome = true;
258         shell = pkgs.bash;
259       };
260       groups.gogs.gid = config.ids.gids.gogs;
261     };
263     warnings = optional (cfg.database.password != "")
264       ''config.services.gogs.database.password will be stored as plaintext
265         in the Nix store. Use database.passwordFile instead.'';
267     # Create database passwordFile default when password is configured.
268     services.gogs.database.passwordFile =
269       (mkDefault (toString (pkgs.writeTextFile {
270         name = "gogs-database-password";
271         text = cfg.database.password;
272       })));
273   };