at 21.11-pre 6.6 kB view raw
1{ config, lib, pkgs, ... }: 2 3with lib; 4let 5 cfg = config.services.gerrit; 6 7 # NixOS option type for git-like configs 8 gitIniType = with types; 9 let 10 primitiveType = either str (either bool int); 11 multipleType = either primitiveType (listOf primitiveType); 12 sectionType = lazyAttrsOf multipleType; 13 supersectionType = lazyAttrsOf (either multipleType sectionType); 14 in lazyAttrsOf supersectionType; 15 16 gerritConfig = pkgs.writeText "gerrit.conf" ( 17 lib.generators.toGitINI cfg.settings 18 ); 19 20 replicationConfig = pkgs.writeText "replication.conf" ( 21 lib.generators.toGitINI cfg.replicationSettings 22 ); 23 24 # Wrap the gerrit java with all the java options so it can be called 25 # like a normal CLI app 26 gerrit-cli = pkgs.writeShellScriptBin "gerrit" '' 27 set -euo pipefail 28 jvmOpts=( 29 ${lib.escapeShellArgs cfg.jvmOpts} 30 -Xmx${cfg.jvmHeapLimit} 31 ) 32 exec ${cfg.jvmPackage}/bin/java \ 33 "''${jvmOpts[@]}" \ 34 -jar ${cfg.package}/webapps/${cfg.package.name}.war \ 35 "$@" 36 ''; 37 38 gerrit-plugins = pkgs.runCommand 39 "gerrit-plugins" 40 { 41 buildInputs = [ gerrit-cli ]; 42 } 43 '' 44 shopt -s nullglob 45 mkdir $out 46 47 for name in ${toString cfg.builtinPlugins}; do 48 echo "Installing builtin plugin $name.jar" 49 gerrit cat plugins/$name.jar > $out/$name.jar 50 done 51 52 for file in ${toString cfg.plugins}; do 53 name=$(echo "$file" | cut -d - -f 2-) 54 echo "Installing plugin $name" 55 ln -sf "$file" $out/$name 56 done 57 ''; 58in 59{ 60 options = { 61 services.gerrit = { 62 enable = mkEnableOption "Gerrit service"; 63 64 package = mkOption { 65 type = types.package; 66 default = pkgs.gerrit; 67 description = "Gerrit package to use"; 68 }; 69 70 jvmPackage = mkOption { 71 type = types.package; 72 default = pkgs.jre_headless; 73 defaultText = "pkgs.jre_headless"; 74 description = "Java Runtime Environment package to use"; 75 }; 76 77 jvmOpts = mkOption { 78 type = types.listOf types.str; 79 default = [ 80 "-Dflogger.backend_factory=com.google.common.flogger.backend.log4j.Log4jBackendFactory#getInstance" 81 "-Dflogger.logging_context=com.google.gerrit.server.logging.LoggingContext#getInstance" 82 ]; 83 description = "A list of JVM options to start gerrit with."; 84 }; 85 86 jvmHeapLimit = mkOption { 87 type = types.str; 88 default = "1024m"; 89 description = '' 90 How much memory to allocate to the JVM heap 91 ''; 92 }; 93 94 listenAddress = mkOption { 95 type = types.str; 96 default = "[::]:8080"; 97 description = '' 98 <literal>hostname:port</literal> to listen for HTTP traffic. 99 100 This is bound using the systemd socket activation. 101 ''; 102 }; 103 104 settings = mkOption { 105 type = gitIniType; 106 default = {}; 107 description = '' 108 Gerrit configuration. This will be generated to the 109 <literal>etc/gerrit.config</literal> file. 110 ''; 111 }; 112 113 replicationSettings = mkOption { 114 type = gitIniType; 115 default = {}; 116 description = '' 117 Replication configuration. This will be generated to the 118 <literal>etc/replication.config</literal> file. 119 ''; 120 }; 121 122 plugins = mkOption { 123 type = types.listOf types.package; 124 default = []; 125 description = '' 126 List of plugins to add to Gerrit. Each derivation is a jar file 127 itself where the name of the derivation is the name of plugin. 128 ''; 129 }; 130 131 builtinPlugins = mkOption { 132 type = types.listOf (types.enum cfg.package.passthru.plugins); 133 default = []; 134 description = '' 135 List of builtins plugins to install. Those are shipped in the 136 <literal>gerrit.war</literal> file. 137 ''; 138 }; 139 140 serverId = mkOption { 141 type = types.str; 142 description = '' 143 Set a UUID that uniquely identifies the server. 144 145 This can be generated with 146 <literal>nix-shell -p util-linux --run uuidgen</literal>. 147 ''; 148 }; 149 }; 150 }; 151 152 config = mkIf cfg.enable { 153 154 assertions = [ 155 { 156 assertion = cfg.replicationSettings != {} -> elem "replication" cfg.builtinPlugins; 157 message = "Gerrit replicationSettings require enabling the replication plugin"; 158 } 159 ]; 160 161 services.gerrit.settings = { 162 cache.directory = "/var/cache/gerrit"; 163 container.heapLimit = cfg.jvmHeapLimit; 164 gerrit.basePath = lib.mkDefault "git"; 165 gerrit.serverId = cfg.serverId; 166 httpd.inheritChannel = "true"; 167 httpd.listenUrl = lib.mkDefault "http://${cfg.listenAddress}"; 168 index.type = lib.mkDefault "lucene"; 169 }; 170 171 # Add the gerrit CLI to the system to run `gerrit init` and friends. 172 environment.systemPackages = [ gerrit-cli ]; 173 174 systemd.sockets.gerrit = { 175 unitConfig.Description = "Gerrit HTTP socket"; 176 wantedBy = [ "sockets.target" ]; 177 listenStreams = [ cfg.listenAddress ]; 178 }; 179 180 systemd.services.gerrit = { 181 description = "Gerrit"; 182 183 wantedBy = [ "multi-user.target" ]; 184 requires = [ "gerrit.socket" ]; 185 after = [ "gerrit.socket" "network.target" ]; 186 187 path = [ 188 gerrit-cli 189 pkgs.bash 190 pkgs.coreutils 191 pkgs.git 192 pkgs.openssh 193 ]; 194 195 environment = { 196 GERRIT_HOME = "%S/gerrit"; 197 GERRIT_TMP = "%T"; 198 HOME = "%S/gerrit"; 199 XDG_CONFIG_HOME = "%S/gerrit/.config"; 200 }; 201 202 preStart = '' 203 set -euo pipefail 204 205 # bootstrap if nothing exists 206 if [[ ! -d git ]]; then 207 gerrit init --batch --no-auto-start 208 fi 209 210 # install gerrit.war for the plugin manager 211 rm -rf bin 212 mkdir bin 213 ln -sfv ${cfg.package}/webapps/${cfg.package.name}.war bin/gerrit.war 214 215 # copy the config, keep it mutable because Gerrit 216 ln -sfv ${gerritConfig} etc/gerrit.config 217 ln -sfv ${replicationConfig} etc/replication.config 218 219 # install the plugins 220 rm -rf plugins 221 ln -sv ${gerrit-plugins} plugins 222 '' 223 ; 224 225 serviceConfig = { 226 CacheDirectory = "gerrit"; 227 DynamicUser = true; 228 ExecStart = "${gerrit-cli}/bin/gerrit daemon --console-log"; 229 LimitNOFILE = 4096; 230 StandardInput = "socket"; 231 StandardOutput = "journal"; 232 StateDirectory = "gerrit"; 233 WorkingDirectory = "%S/gerrit"; 234 }; 235 }; 236 }; 237 238 meta.maintainers = with lib.maintainers; [ edef zimbatm ]; 239}