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