| 
									
										
										
										
											2016-10-09 19:04:42 +02:00
										 |  |  | { config, lib, pkgs, ... }: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | with lib; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | let | 
					
						
							|  |  |  |   cfg = config.services.gogs; | 
					
						
							|  |  |  |   configFile = pkgs.writeText "app.ini" ''
 | 
					
						
							|  |  |  |     APP_NAME = ${cfg.appName} | 
					
						
							|  |  |  |     RUN_USER = ${cfg.user} | 
					
						
							|  |  |  |     RUN_MODE = prod | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     [database] | 
					
						
							|  |  |  |     DB_TYPE = ${cfg.database.type} | 
					
						
							|  |  |  |     HOST = ${cfg.database.host}:${toString cfg.database.port} | 
					
						
							|  |  |  |     NAME = ${cfg.database.name} | 
					
						
							|  |  |  |     USER = ${cfg.database.user} | 
					
						
							| 
									
										
										
										
											2017-04-22 17:03:07 +01:00
										 |  |  |     PASSWD = #dbpass# | 
					
						
							| 
									
										
										
										
											2016-10-09 19:04:42 +02:00
										 |  |  |     PATH = ${cfg.database.path} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     [repository] | 
					
						
							|  |  |  |     ROOT = ${cfg.repositoryRoot} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     [server] | 
					
						
							|  |  |  |     DOMAIN = ${cfg.domain} | 
					
						
							|  |  |  |     HTTP_ADDR = ${cfg.httpAddress} | 
					
						
							|  |  |  |     HTTP_PORT = ${toString cfg.httpPort} | 
					
						
							|  |  |  |     ROOT_URL = ${cfg.rootUrl} | 
					
						
							| 
									
										
										
										
											2017-10-02 21:04:32 +02:00
										 |  |  |     STATIC_ROOT_PATH = ${cfg.staticRootPath} | 
					
						
							| 
									
										
										
										
											2016-10-09 19:04:42 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-23 16:26:56 +01:00
										 |  |  |     [session] | 
					
						
							|  |  |  |     COOKIE_NAME = session | 
					
						
							|  |  |  |     COOKIE_SECURE = ${boolToString cfg.cookieSecure} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-09 19:04:42 +02:00
										 |  |  |     [security] | 
					
						
							|  |  |  |     SECRET_KEY = #secretkey# | 
					
						
							|  |  |  |     INSTALL_LOCK = true | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-29 21:17:02 +02:00
										 |  |  |     [log] | 
					
						
							|  |  |  |     ROOT_PATH = ${cfg.stateDir}/log | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-09 19:04:42 +02:00
										 |  |  |     ${cfg.extraConfig} | 
					
						
							|  |  |  |   '';
 | 
					
						
							|  |  |  | in | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   options = { | 
					
						
							|  |  |  |     services.gogs = { | 
					
						
							|  |  |  |       enable = mkOption { | 
					
						
							|  |  |  |         default = false; | 
					
						
							|  |  |  |         type = types.bool; | 
					
						
							|  |  |  |         description = "Enable Go Git Service."; | 
					
						
							|  |  |  |       }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       useWizard = mkOption { | 
					
						
							|  |  |  |         default = false; | 
					
						
							|  |  |  |         type = types.bool; | 
					
						
							|  |  |  |         description = "Do not generate a configuration and use Gogs' installation wizard instead. The first registered user will be administrator."; | 
					
						
							|  |  |  |       }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       stateDir = mkOption { | 
					
						
							|  |  |  |         default = "/var/lib/gogs"; | 
					
						
							|  |  |  |         type = types.str; | 
					
						
							|  |  |  |         description = "Gogs data directory."; | 
					
						
							|  |  |  |       }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       user = mkOption { | 
					
						
							|  |  |  |         type = types.str; | 
					
						
							|  |  |  |         default = "gogs"; | 
					
						
							|  |  |  |         description = "User account under which Gogs runs."; | 
					
						
							|  |  |  |       }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       group = mkOption { | 
					
						
							|  |  |  |         type = types.str; | 
					
						
							|  |  |  |         default = "gogs"; | 
					
						
							|  |  |  |         description = "Group account under which Gogs runs."; | 
					
						
							|  |  |  |       }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       database = { | 
					
						
							|  |  |  |         type = mkOption { | 
					
						
							|  |  |  |           type = types.enum [ "sqlite3" "mysql" "postgres" ]; | 
					
						
							|  |  |  |           example = "mysql"; | 
					
						
							|  |  |  |           default = "sqlite3"; | 
					
						
							|  |  |  |           description = "Database engine to use."; | 
					
						
							|  |  |  |         }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         host = mkOption { | 
					
						
							|  |  |  |           type = types.str; | 
					
						
							|  |  |  |           default = "127.0.0.1"; | 
					
						
							|  |  |  |           description = "Database host address."; | 
					
						
							|  |  |  |         }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         port = mkOption { | 
					
						
							|  |  |  |           type = types.int; | 
					
						
							|  |  |  |           default = 3306; | 
					
						
							|  |  |  |           description = "Database host port."; | 
					
						
							|  |  |  |         }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         name = mkOption { | 
					
						
							|  |  |  |           type = types.str; | 
					
						
							|  |  |  |           default = "gogs"; | 
					
						
							|  |  |  |           description = "Database name."; | 
					
						
							|  |  |  |         }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         user = mkOption { | 
					
						
							|  |  |  |           type = types.str; | 
					
						
							|  |  |  |           default = "gogs"; | 
					
						
							|  |  |  |           description = "Database user."; | 
					
						
							|  |  |  |         }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         password = mkOption { | 
					
						
							|  |  |  |           type = types.str; | 
					
						
							|  |  |  |           default = ""; | 
					
						
							| 
									
										
										
										
											2017-04-22 17:03:07 +01:00
										 |  |  |           description = ''
 | 
					
						
							|  |  |  |             The password corresponding to <option>database.user</option>. | 
					
						
							|  |  |  |             Warning: this is stored in cleartext in the Nix store! | 
					
						
							|  |  |  |             Use <option>database.passwordFile</option> instead. | 
					
						
							|  |  |  |           '';
 | 
					
						
							|  |  |  |         }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         passwordFile = mkOption { | 
					
						
							|  |  |  |           type = types.nullOr types.path; | 
					
						
							|  |  |  |           default = null; | 
					
						
							|  |  |  |           example = "/run/keys/gogs-dbpassword"; | 
					
						
							|  |  |  |           description = ''
 | 
					
						
							|  |  |  |             A file containing the password corresponding to | 
					
						
							|  |  |  |             <option>database.user</option>. | 
					
						
							|  |  |  |           '';
 | 
					
						
							| 
									
										
										
										
											2016-10-09 19:04:42 +02:00
										 |  |  |         }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         path = mkOption { | 
					
						
							|  |  |  |           type = types.str; | 
					
						
							|  |  |  |           default = "${cfg.stateDir}/data/gogs.db"; | 
					
						
							|  |  |  |           description = "Path to the sqlite3 database file."; | 
					
						
							|  |  |  |         }; | 
					
						
							|  |  |  |       }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       appName = mkOption { | 
					
						
							|  |  |  |         type = types.str; | 
					
						
							|  |  |  |         default = "Gogs: Go Git Service"; | 
					
						
							|  |  |  |         description = "Application name."; | 
					
						
							|  |  |  |       }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       repositoryRoot = mkOption { | 
					
						
							|  |  |  |         type = types.str; | 
					
						
							|  |  |  |         default = "${cfg.stateDir}/repositories"; | 
					
						
							|  |  |  |         description = "Path to the git repositories."; | 
					
						
							|  |  |  |       }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       domain = mkOption { | 
					
						
							|  |  |  |         type = types.str; | 
					
						
							|  |  |  |         default = "localhost"; | 
					
						
							|  |  |  |         description = "Domain name of your server."; | 
					
						
							|  |  |  |       }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       rootUrl = mkOption { | 
					
						
							|  |  |  |         type = types.str; | 
					
						
							|  |  |  |         default = "http://localhost:3000/"; | 
					
						
							|  |  |  |         description = "Full public URL of Gogs server."; | 
					
						
							|  |  |  |       }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       httpAddress = mkOption { | 
					
						
							|  |  |  |         type = types.str; | 
					
						
							|  |  |  |         default = "0.0.0.0"; | 
					
						
							|  |  |  |         description = "HTTP listen address."; | 
					
						
							|  |  |  |       }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       httpPort = mkOption { | 
					
						
							|  |  |  |         type = types.int; | 
					
						
							|  |  |  |         default = 3000; | 
					
						
							|  |  |  |         description = "HTTP listen port."; | 
					
						
							|  |  |  |       }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-23 16:26:56 +01:00
										 |  |  |       cookieSecure = mkOption { | 
					
						
							|  |  |  |         type = types.bool; | 
					
						
							|  |  |  |         default = false; | 
					
						
							|  |  |  |         description = ''
 | 
					
						
							| 
									
										
										
										
											2017-05-01 11:37:12 +02:00
										 |  |  |           Marks session cookies as "secure" as a hint for browsers to only send | 
					
						
							|  |  |  |           them via HTTPS. This option is recommend, if Gogs is being served over HTTPS. | 
					
						
							| 
									
										
										
										
											2017-04-23 16:26:56 +01:00
										 |  |  |         '';
 | 
					
						
							|  |  |  |       }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-02 21:04:32 +02:00
										 |  |  |       staticRootPath = mkOption { | 
					
						
							|  |  |  |         type = types.str; | 
					
						
							|  |  |  |         default = "${pkgs.gogs.data}"; | 
					
						
							|  |  |  |         example = "/var/lib/gogs/data"; | 
					
						
							|  |  |  |         description = "Upper level of template and static files path."; | 
					
						
							|  |  |  |       }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-09 19:04:42 +02:00
										 |  |  |       extraConfig = mkOption { | 
					
						
							|  |  |  |         type = types.str; | 
					
						
							|  |  |  |         default = ""; | 
					
						
							|  |  |  |         description = "Configuration lines appended to the generated Gogs configuration file."; | 
					
						
							|  |  |  |       }; | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   config = mkIf cfg.enable { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     systemd.services.gogs = { | 
					
						
							|  |  |  |       description = "Gogs (Go Git Service)"; | 
					
						
							|  |  |  |       after = [ "network.target" ]; | 
					
						
							|  |  |  |       wantedBy = [ "multi-user.target" ]; | 
					
						
							|  |  |  |       path = [ pkgs.gogs.bin ]; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-22 17:51:04 +01:00
										 |  |  |       preStart = let | 
					
						
							|  |  |  |         runConfig = "${cfg.stateDir}/custom/conf/app.ini"; | 
					
						
							| 
									
										
										
										
											2017-04-23 15:02:08 +01:00
										 |  |  |         secretKey = "${cfg.stateDir}/custom/conf/secret_key"; | 
					
						
							| 
									
										
										
										
											2017-04-22 17:51:04 +01:00
										 |  |  |       in ''
 | 
					
						
							| 
									
										
										
										
											2017-10-02 21:04:32 +02:00
										 |  |  |         mkdir -p ${cfg.stateDir} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-09 19:04:42 +02:00
										 |  |  |         # copy custom configuration and generate a random secret key if needed | 
					
						
							|  |  |  |         ${optionalString (cfg.useWizard == false) ''
 | 
					
						
							|  |  |  |           mkdir -p ${cfg.stateDir}/custom/conf | 
					
						
							| 
									
										
										
										
											2017-04-22 17:51:04 +01:00
										 |  |  |           cp -f ${configFile} ${runConfig} | 
					
						
							| 
									
										
										
										
											2017-04-23 15:02:08 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |           if [ ! -e ${secretKey} ]; then | 
					
						
							|  |  |  |               head -c 16 /dev/urandom | base64 > ${secretKey} | 
					
						
							|  |  |  |           fi | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           KEY=$(head -n1 ${secretKey}) | 
					
						
							| 
									
										
										
										
											2017-04-22 17:03:07 +01:00
										 |  |  |           DBPASS=$(head -n1 ${cfg.database.passwordFile}) | 
					
						
							|  |  |  |           sed -e "s,#secretkey#,$KEY,g" \ | 
					
						
							|  |  |  |               -e "s,#dbpass#,$DBPASS,g" \ | 
					
						
							| 
									
										
										
										
											2017-04-22 17:51:04 +01:00
										 |  |  |               -i ${runConfig} | 
					
						
							| 
									
										
										
										
											2017-04-23 15:02:08 +01:00
										 |  |  |           chmod 440 ${runConfig} ${secretKey} | 
					
						
							| 
									
										
										
										
											2016-10-09 19:04:42 +02:00
										 |  |  |         ''}
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         mkdir -p ${cfg.repositoryRoot} | 
					
						
							|  |  |  |         # update all hooks' binary paths | 
					
						
							|  |  |  |         HOOKS=$(find ${cfg.repositoryRoot} -mindepth 4 -maxdepth 4 -type f -wholename "*git/hooks/*") | 
					
						
							|  |  |  |         if [ "$HOOKS" ] | 
					
						
							|  |  |  |         then | 
					
						
							|  |  |  |           sed -ri 's,/nix/store/[a-z0-9.-]+/bin/gogs,${pkgs.gogs.bin}/bin/gogs,g' $HOOKS | 
					
						
							|  |  |  |           sed -ri 's,/nix/store/[a-z0-9.-]+/bin/env,${pkgs.coreutils}/bin/env,g' $HOOKS | 
					
						
							|  |  |  |           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 | 
					
						
							|  |  |  |       '';
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       serviceConfig = { | 
					
						
							|  |  |  |         Type = "simple"; | 
					
						
							|  |  |  |         User = cfg.user; | 
					
						
							|  |  |  |         Group = cfg.group; | 
					
						
							|  |  |  |         WorkingDirectory = cfg.stateDir; | 
					
						
							|  |  |  |         ExecStart = "${pkgs.gogs.bin}/bin/gogs web"; | 
					
						
							|  |  |  |         Restart = "always"; | 
					
						
							|  |  |  |       }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       environment = { | 
					
						
							|  |  |  |         USER = cfg.user; | 
					
						
							|  |  |  |         HOME = cfg.stateDir; | 
					
						
							|  |  |  |         GOGS_WORK_DIR = cfg.stateDir; | 
					
						
							|  |  |  |       }; | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-02 15:53:30 +02:00
										 |  |  |     users = mkIf (cfg.user == "gogs") { | 
					
						
							| 
									
										
										
										
											2016-10-09 19:04:42 +02:00
										 |  |  |       extraUsers.gogs = { | 
					
						
							|  |  |  |         description = "Go Git Service"; | 
					
						
							|  |  |  |         uid = config.ids.uids.gogs; | 
					
						
							|  |  |  |         group = "gogs"; | 
					
						
							|  |  |  |         home = cfg.stateDir; | 
					
						
							|  |  |  |         createHome = true; | 
					
						
							| 
									
										
										
										
											2017-02-04 12:16:37 +01:00
										 |  |  |         shell = pkgs.bash; | 
					
						
							| 
									
										
										
										
											2016-10-09 19:04:42 +02:00
										 |  |  |       }; | 
					
						
							|  |  |  |       extraGroups.gogs.gid = config.ids.gids.gogs; | 
					
						
							|  |  |  |     }; | 
					
						
							| 
									
										
										
										
											2017-04-22 17:03:07 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     warnings = optional (cfg.database.password != "") | 
					
						
							|  |  |  |       ''config.services.gogs.database.password will be stored as plaintext
 | 
					
						
							|  |  |  |         in the Nix store. Use database.passwordFile instead.'';
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Create database passwordFile default when password is configured. | 
					
						
							| 
									
										
										
										
											2017-09-13 01:12:26 +01:00
										 |  |  |     services.gogs.database.passwordFile = | 
					
						
							| 
									
										
										
										
											2017-04-22 17:03:07 +01:00
										 |  |  |       (mkDefault (toString (pkgs.writeTextFile { | 
					
						
							|  |  |  |         name = "gogs-database-password"; | 
					
						
							|  |  |  |         text = cfg.database.password; | 
					
						
							|  |  |  |       }))); | 
					
						
							| 
									
										
										
										
											2016-10-09 19:04:42 +02:00
										 |  |  |   }; | 
					
						
							|  |  |  | } |