at 23.11-pre 6.8 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 (lib.mdDoc "Gerrit service"); 63 64 package = mkOption { 65 type = types.package; 66 default = pkgs.gerrit; 67 defaultText = literalExpression "pkgs.gerrit"; 68 description = lib.mdDoc "Gerrit package to use"; 69 }; 70 71 jvmPackage = mkOption { 72 type = types.package; 73 default = pkgs.jre_headless; 74 defaultText = literalExpression "pkgs.jre_headless"; 75 description = lib.mdDoc "Java Runtime Environment package to use"; 76 }; 77 78 jvmOpts = mkOption { 79 type = types.listOf types.str; 80 default = [ 81 "-Dflogger.backend_factory=com.google.common.flogger.backend.log4j.Log4jBackendFactory#getInstance" 82 "-Dflogger.logging_context=com.google.gerrit.server.logging.LoggingContext#getInstance" 83 ]; 84 description = lib.mdDoc "A list of JVM options to start gerrit with."; 85 }; 86 87 jvmHeapLimit = mkOption { 88 type = types.str; 89 default = "1024m"; 90 description = lib.mdDoc '' 91 How much memory to allocate to the JVM heap 92 ''; 93 }; 94 95 listenAddress = mkOption { 96 type = types.str; 97 default = "[::]:8080"; 98 description = lib.mdDoc '' 99 `hostname:port` to listen for HTTP traffic. 100 101 This is bound using the systemd socket activation. 102 ''; 103 }; 104 105 settings = mkOption { 106 type = gitIniType; 107 default = {}; 108 description = lib.mdDoc '' 109 Gerrit configuration. This will be generated to the 110 `etc/gerrit.config` file. 111 ''; 112 }; 113 114 replicationSettings = mkOption { 115 type = gitIniType; 116 default = {}; 117 description = lib.mdDoc '' 118 Replication configuration. This will be generated to the 119 `etc/replication.config` file. 120 ''; 121 }; 122 123 plugins = mkOption { 124 type = types.listOf types.package; 125 default = []; 126 description = lib.mdDoc '' 127 List of plugins to add to Gerrit. Each derivation is a jar file 128 itself where the name of the derivation is the name of plugin. 129 ''; 130 }; 131 132 builtinPlugins = mkOption { 133 type = types.listOf (types.enum cfg.package.passthru.plugins); 134 default = []; 135 description = lib.mdDoc '' 136 List of builtins plugins to install. Those are shipped in the 137 `gerrit.war` file. 138 ''; 139 }; 140 141 serverId = mkOption { 142 type = types.str; 143 description = lib.mdDoc '' 144 Set a UUID that uniquely identifies the server. 145 146 This can be generated with 147 `nix-shell -p util-linux --run uuidgen`. 148 ''; 149 }; 150 }; 151 }; 152 153 config = mkIf cfg.enable { 154 155 assertions = [ 156 { 157 assertion = cfg.replicationSettings != {} -> elem "replication" cfg.builtinPlugins; 158 message = "Gerrit replicationSettings require enabling the replication plugin"; 159 } 160 ]; 161 162 services.gerrit.settings = { 163 cache.directory = "/var/cache/gerrit"; 164 container.heapLimit = cfg.jvmHeapLimit; 165 gerrit.basePath = lib.mkDefault "git"; 166 gerrit.serverId = cfg.serverId; 167 httpd.inheritChannel = "true"; 168 httpd.listenUrl = lib.mkDefault "http://${cfg.listenAddress}"; 169 index.type = lib.mkDefault "lucene"; 170 }; 171 172 # Add the gerrit CLI to the system to run `gerrit init` and friends. 173 environment.systemPackages = [ gerrit-cli ]; 174 175 systemd.sockets.gerrit = { 176 unitConfig.Description = "Gerrit HTTP socket"; 177 wantedBy = [ "sockets.target" ]; 178 listenStreams = [ cfg.listenAddress ]; 179 }; 180 181 systemd.services.gerrit = { 182 description = "Gerrit"; 183 184 wantedBy = [ "multi-user.target" ]; 185 requires = [ "gerrit.socket" ]; 186 after = [ "gerrit.socket" "network.target" ]; 187 188 path = [ 189 gerrit-cli 190 pkgs.bash 191 pkgs.coreutils 192 pkgs.git 193 pkgs.openssh 194 ]; 195 196 environment = { 197 GERRIT_HOME = "%S/gerrit"; 198 GERRIT_TMP = "%T"; 199 HOME = "%S/gerrit"; 200 XDG_CONFIG_HOME = "%S/gerrit/.config"; 201 }; 202 203 preStart = '' 204 set -euo pipefail 205 206 # bootstrap if nothing exists 207 if [[ ! -d git ]]; then 208 gerrit init --batch --no-auto-start 209 fi 210 211 # install gerrit.war for the plugin manager 212 rm -rf bin 213 mkdir bin 214 ln -sfv ${cfg.package}/webapps/${cfg.package.name}.war bin/gerrit.war 215 216 # copy the config, keep it mutable because Gerrit 217 ln -sfv ${gerritConfig} etc/gerrit.config 218 ln -sfv ${replicationConfig} etc/replication.config 219 220 # install the plugins 221 rm -rf plugins 222 ln -sv ${gerrit-plugins} plugins 223 '' 224 ; 225 226 serviceConfig = { 227 CacheDirectory = "gerrit"; 228 DynamicUser = true; 229 ExecStart = "${gerrit-cli}/bin/gerrit daemon --console-log"; 230 LimitNOFILE = 4096; 231 StandardInput = "socket"; 232 StandardOutput = "journal"; 233 StateDirectory = "gerrit"; 234 WorkingDirectory = "%S/gerrit"; 235 }; 236 }; 237 }; 238 239 meta.maintainers = with lib.maintainers; [ edef zimbatm ]; 240 # uses attributes of the linked package 241 meta.buildDocsInSandbox = false; 242}