at 23.11-pre 7.9 kB view raw
1{ config, lib, options, pkgs, ... }: 2 3with lib; 4 5let 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 12 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} 20 21 [repository] 22 ROOT = ${cfg.repositoryRoot} 23 24 [server] 25 DOMAIN = ${cfg.domain} 26 HTTP_ADDR = ${cfg.httpAddress} 27 HTTP_PORT = ${toString cfg.httpPort} 28 ROOT_URL = ${cfg.rootUrl} 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 [log] 39 ROOT_PATH = ${cfg.stateDir}/log 40 41 ${cfg.extraConfig} 42 ''; 43in 44 45{ 46 options = { 47 services.gogs = { 48 enable = mkOption { 49 default = false; 50 type = types.bool; 51 description = lib.mdDoc "Enable Go Git Service."; 52 }; 53 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 }; 59 60 stateDir = mkOption { 61 default = "/var/lib/gogs"; 62 type = types.str; 63 description = lib.mdDoc "Gogs data directory."; 64 }; 65 66 user = mkOption { 67 type = types.str; 68 default = "gogs"; 69 description = lib.mdDoc "User account under which Gogs runs."; 70 }; 71 72 group = mkOption { 73 type = types.str; 74 default = "gogs"; 75 description = lib.mdDoc "Group account under which Gogs runs."; 76 }; 77 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 }; 85 86 host = mkOption { 87 type = types.str; 88 default = "127.0.0.1"; 89 description = lib.mdDoc "Database host address."; 90 }; 91 92 port = mkOption { 93 type = types.port; 94 default = 3306; 95 description = lib.mdDoc "Database host port."; 96 }; 97 98 name = mkOption { 99 type = types.str; 100 default = "gogs"; 101 description = lib.mdDoc "Database name."; 102 }; 103 104 user = mkOption { 105 type = types.str; 106 default = "gogs"; 107 description = lib.mdDoc "Database user."; 108 }; 109 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 }; 119 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 }; 129 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 }; 137 138 appName = mkOption { 139 type = types.str; 140 default = "Gogs: Go Git Service"; 141 description = lib.mdDoc "Application name."; 142 }; 143 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 }; 150 151 domain = mkOption { 152 type = types.str; 153 default = "localhost"; 154 description = lib.mdDoc "Domain name of your server."; 155 }; 156 157 rootUrl = mkOption { 158 type = types.str; 159 default = "http://localhost:3000/"; 160 description = lib.mdDoc "Full public URL of Gogs server."; 161 }; 162 163 httpAddress = mkOption { 164 type = types.str; 165 default = "0.0.0.0"; 166 description = lib.mdDoc "HTTP listen address."; 167 }; 168 169 httpPort = mkOption { 170 type = types.port; 171 default = 3000; 172 description = lib.mdDoc "HTTP listen port."; 173 }; 174 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 }; 183 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 }; 191 192 config = mkIf cfg.enable { 193 194 systemd.services.gogs = { 195 description = "Gogs (Go Git Service)"; 196 after = [ "network.target" ]; 197 wantedBy = [ "multi-user.target" ]; 198 path = [ pkgs.gogs ]; 199 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} 205 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} 210 211 if [ ! -e ${secretKey} ]; then 212 head -c 16 /dev/urandom | base64 > ${secretKey} 213 fi 214 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 ''} 222 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 ''; 234 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 }; 243 244 environment = { 245 USER = cfg.user; 246 HOME = cfg.stateDir; 247 GOGS_WORK_DIR = cfg.stateDir; 248 }; 249 }; 250 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 }; 262 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.''; 266 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 }; 274}