2024-07-01 17:49:32 +00:00
|
|
|
# Gerrit configuration for the Nixpkgs monorepo
|
|
|
|
# Inspired from TVL configuration.
|
|
|
|
{ pkgs, config, lib, ... }:
|
|
|
|
|
|
|
|
let
|
2024-07-17 13:43:22 +00:00
|
|
|
inherit (lib) mkEnableOption mkIf mkOption types head;
|
2024-07-01 17:49:32 +00:00
|
|
|
cfgGerrit = config.services.gerrit;
|
|
|
|
cfg = config.bagel.services.gerrit;
|
2024-07-08 20:30:08 +00:00
|
|
|
|
|
|
|
jdk = pkgs.openjdk21_headless;
|
2024-07-01 17:49:32 +00:00
|
|
|
in
|
|
|
|
{
|
|
|
|
options.bagel.services.gerrit = {
|
|
|
|
enable = mkEnableOption "Gerrit";
|
|
|
|
domains = mkOption {
|
|
|
|
type = types.listOf types.str;
|
|
|
|
description = "List of domains that Gerrit will answer to";
|
|
|
|
};
|
2024-07-17 13:43:22 +00:00
|
|
|
canonicalDomain = mkOption {
|
|
|
|
type = types.str;
|
|
|
|
description = "Canonical domain for this Gerrit instance";
|
|
|
|
default = head cfg.domains;
|
|
|
|
};
|
2024-07-01 17:49:32 +00:00
|
|
|
data = mkOption {
|
|
|
|
type = types.path;
|
|
|
|
default = "/var/lib/gerrit";
|
|
|
|
description = "Root of data directory for the Gerrit";
|
|
|
|
};
|
2024-07-17 13:43:22 +00:00
|
|
|
port = mkOption {
|
|
|
|
type = types.port;
|
|
|
|
default = 29418;
|
|
|
|
readOnly = true;
|
|
|
|
description = "Port for the Gerrit SSH server";
|
|
|
|
};
|
2024-07-01 17:49:32 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
imports = [
|
|
|
|
./www.nix
|
|
|
|
];
|
|
|
|
|
|
|
|
config = mkIf cfg.enable {
|
2024-07-17 13:43:22 +00:00
|
|
|
networking.firewall.allowedTCPPorts = [ cfg.port ];
|
2024-07-01 17:49:32 +00:00
|
|
|
|
2024-07-08 20:30:08 +00:00
|
|
|
environment.systemPackages = [ jdk ];
|
2024-07-04 21:08:36 +00:00
|
|
|
|
2024-07-01 17:49:32 +00:00
|
|
|
fileSystems."/var/lib/gerrit" = mkIf (cfg.data != "/var/lib/gerrit") {
|
|
|
|
device = cfg.data;
|
|
|
|
options = [ "bind" ];
|
|
|
|
};
|
|
|
|
|
|
|
|
users.users.git = {
|
|
|
|
isSystemUser = true;
|
|
|
|
group = "git";
|
|
|
|
};
|
|
|
|
users.groups.git = {};
|
|
|
|
|
|
|
|
services.gerrit = {
|
|
|
|
enable = true;
|
|
|
|
listenAddress = "[::]:4778"; # 4778 - grrt
|
|
|
|
serverId = "9e5216ad-038d-4d74-a4e8-716515834a94";
|
|
|
|
|
|
|
|
builtinPlugins = [
|
|
|
|
"gitiles"
|
|
|
|
"codemirror-editor"
|
|
|
|
"reviewnotes"
|
|
|
|
"download-commands"
|
|
|
|
"hooks"
|
|
|
|
"replication"
|
|
|
|
"webhooks"
|
|
|
|
];
|
|
|
|
|
2024-07-17 13:43:22 +00:00
|
|
|
plugins = with pkgs.gerritPlugins; [
|
2024-07-01 17:49:32 +00:00
|
|
|
oauth
|
2024-07-13 18:10:45 +00:00
|
|
|
metrics-reporter-prometheus
|
2024-07-01 17:49:32 +00:00
|
|
|
];
|
|
|
|
|
|
|
|
package = pkgs.gerrit;
|
|
|
|
|
|
|
|
jvmHeapLimit = "32g";
|
|
|
|
|
2024-07-08 20:30:08 +00:00
|
|
|
jvmPackage = jdk;
|
2024-07-01 17:49:32 +00:00
|
|
|
|
|
|
|
settings = {
|
2024-07-04 21:08:36 +00:00
|
|
|
# Performance settings
|
2024-07-01 17:49:32 +00:00
|
|
|
sshd.threads = 64;
|
|
|
|
sshd.batchThreads = 8;
|
2024-07-04 21:08:36 +00:00
|
|
|
|
|
|
|
gc.aggressive = true;
|
2024-07-01 17:49:32 +00:00
|
|
|
gc.interval = "1 day";
|
2024-07-04 21:08:36 +00:00
|
|
|
|
|
|
|
database.poolLimit = 250;
|
2024-07-01 17:49:32 +00:00
|
|
|
database.poolMaxIdle = 16;
|
2024-07-04 21:08:36 +00:00
|
|
|
|
|
|
|
httpd.maxThreads = 100;
|
|
|
|
|
2024-07-01 17:49:32 +00:00
|
|
|
receive.timeout = "4min";
|
2024-07-04 21:08:36 +00:00
|
|
|
# Default is 0, infinite.
|
|
|
|
transfer.timeout = "30min";
|
|
|
|
|
|
|
|
# We may overshoot but it's OK.
|
|
|
|
core.packedGitWindowSize = "256k";
|
|
|
|
# Sum of all current packfiles is ~1.2G
|
|
|
|
# Largest packfile is 906MB.
|
|
|
|
# Average packfile is ~5-10MB.
|
|
|
|
core.packedGitLimit = "1g";
|
|
|
|
# We have plenty of memory, let's avoid file system cache → Gerrit needless copies.
|
|
|
|
core.packedGitUseStrongRefs = true;
|
|
|
|
core.packedGitOpenFiles = 4096;
|
|
|
|
# Big files in nixpkgs are usually lockfiles or machine-generated expressions
|
|
|
|
# containing a lot of hashes, they would weigh at most ~15MB.
|
|
|
|
core.streamFileThreshold = "20m";
|
|
|
|
# `mmap()` rather than `mmap()+read()` at the risk of running out of virtual address space.
|
|
|
|
core.packedGitMmap = true;
|
|
|
|
|
|
|
|
## Takes more CPU but the transfer is smaller.
|
2024-07-09 22:21:10 +00:00
|
|
|
pack.deltacompression = true;
|
2024-07-04 21:08:36 +00:00
|
|
|
pack.threads = 8;
|
|
|
|
|
|
|
|
# FIXME(raito):
|
|
|
|
# Are we supposed to have private / hidden references?
|
|
|
|
# For a public server, that seems unlikely.
|
|
|
|
# But, we should be careful with this option.
|
|
|
|
# https://gerrit-documentation.storage.googleapis.com/Documentation/3.9.5/config-gerrit.html#receive.checkReferencedObjectsAreReachable
|
|
|
|
receive.checkReferencedObjectsAreReachable = false;
|
|
|
|
|
|
|
|
# Other settings
|
2024-07-01 17:49:32 +00:00
|
|
|
log.jsonLogging = true;
|
|
|
|
log.textLogging = false;
|
2024-07-17 13:43:22 +00:00
|
|
|
sshd.advertisedAddress = "${cfg.canonicalDomain}:${cfg.port}";
|
2024-07-01 17:49:32 +00:00
|
|
|
cache.web_sessions.maxAge = "3 months";
|
|
|
|
plugins.allowRemoteAdmin = false;
|
|
|
|
change.enableAttentionSet = true;
|
|
|
|
change.enableAssignee = false;
|
|
|
|
|
2024-07-04 21:08:36 +00:00
|
|
|
user = {
|
|
|
|
name = "ForkOS Gerrit";
|
|
|
|
email = "gerrit@forkos.org";
|
|
|
|
anonymousCoward = "ForkOS contributor";
|
|
|
|
};
|
|
|
|
|
2024-07-01 17:49:32 +00:00
|
|
|
# Configures gerrit for being reverse-proxied by nginx as per
|
|
|
|
# https://gerrit-review.googlesource.com/Documentation/config-reverseproxy.html
|
|
|
|
gerrit = {
|
2024-07-17 13:43:22 +00:00
|
|
|
canonicalWebUrl = "https://${cfg.canonicalDomain}";
|
2024-07-01 17:49:32 +00:00
|
|
|
docUrl = "/Documentation";
|
2024-07-04 21:08:36 +00:00
|
|
|
defaultBranch = "refs/heads/main";
|
2024-07-01 17:49:32 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
httpd.listenUrl = "proxy-https://${cfgGerrit.listenAddress}";
|
|
|
|
|
|
|
|
download.command = [
|
|
|
|
"checkout"
|
|
|
|
"cherry_pick"
|
|
|
|
"format_patch"
|
|
|
|
"pull"
|
|
|
|
];
|
|
|
|
|
|
|
|
# Auto-link other CLs
|
|
|
|
commentlink.gerrit = {
|
|
|
|
match = "cl/(\\d+)";
|
2024-07-17 13:43:22 +00:00
|
|
|
link = "https://${cfg.canonicalDomain}/$1";
|
2024-07-01 17:49:32 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
# Configures integration with Keycloak, which then integrates with a
|
|
|
|
# variety of backends.
|
|
|
|
auth.type = "OAUTH";
|
|
|
|
plugin.gerrit-oauth-provider-keycloak-oauth = {
|
|
|
|
root-url = "https://identity.lix.systems";
|
|
|
|
realm = "lix-project";
|
|
|
|
client-id = "raito-gerrit-testing";
|
|
|
|
# client-secret is set in /var/lib/gerrit/etc/secure.config.
|
|
|
|
};
|
|
|
|
|
|
|
|
plugin.code-owners = {
|
|
|
|
# A Code-Review +2 vote is required from a code owner.
|
|
|
|
requiredApproval = "Code-Review+2";
|
|
|
|
# The OWNERS check can be overriden using an Owners-Override vote.
|
|
|
|
overrideApproval = "Owners-Override+1";
|
|
|
|
# People implicitly approve their own changes automatically.
|
|
|
|
enableImplicitApprovals = "TRUE";
|
|
|
|
};
|
|
|
|
|
|
|
|
# Allow users to add additional email addresses to their accounts.
|
|
|
|
oauth.allowRegisterNewEmail = true;
|
|
|
|
|
|
|
|
# Use Gerrit's built-in HTTP passwords, rather than trying to use the
|
|
|
|
# password against the backing OAuth provider.
|
|
|
|
auth.gitBasicAuthPolicy = "HTTP";
|
|
|
|
|
|
|
|
# Email sending (emails are relayed via the tazj.in domain's
|
|
|
|
# GSuite currently).
|
|
|
|
#
|
|
|
|
# Note that sendemail.smtpPass is stored in
|
|
|
|
# $site_path/etc/secure.config and is *not* controlled by Nix.
|
|
|
|
#
|
|
|
|
# Receiving email is not currently supported.
|
|
|
|
sendemail.enable = false;
|
|
|
|
#sendemail = {
|
|
|
|
# enable = false;
|
|
|
|
# html = false;
|
|
|
|
# connectTimeout = "10sec";
|
|
|
|
# from = "TVL Code Review <tvlbot@tazj.in>";
|
|
|
|
# includeDiff = true;
|
|
|
|
# smtpEncryption = "none";
|
|
|
|
# smtpServer = "localhost";
|
|
|
|
# smtpServerPort = 2525;
|
|
|
|
#};
|
|
|
|
};
|
|
|
|
|
|
|
|
# Replication of the depot repository to secondary machines, for
|
|
|
|
# serving cgit/josh.
|
|
|
|
#replicationSettings = {
|
|
|
|
# gerrit.replicateOnStartup = true;
|
|
|
|
|
|
|
|
# remote.sanduny = {
|
|
|
|
# url = "depot@sanduny.tvl.su:/var/lib/depot";
|
|
|
|
# projects = "depot";
|
|
|
|
# };
|
|
|
|
#};
|
|
|
|
};
|
|
|
|
|
|
|
|
systemd.services.gerrit = {
|
|
|
|
serviceConfig = {
|
|
|
|
# There seems to be no easy way to get `DynamicUser` to play
|
|
|
|
# well with other services (e.g. by using SupplementaryGroups,
|
|
|
|
# which seem to have no effect) so we force the DynamicUser
|
|
|
|
# setting for the Gerrit service to be disabled and reuse the
|
|
|
|
# existing 'git' user.
|
|
|
|
DynamicUser = lib.mkForce false;
|
|
|
|
User = "git";
|
|
|
|
Group = "git";
|
|
|
|
};
|
2024-07-09 22:21:10 +00:00
|
|
|
environment.REVWALK_USE_PRIORITY_QUEUE = "true";
|
2024-07-01 17:49:32 +00:00
|
|
|
};
|
2024-07-13 18:11:43 +00:00
|
|
|
|
|
|
|
age.secrets.gerrit-prometheus-bearer-token.file = ../../secrets/gerrit-prometheus-bearer-token.age;
|
|
|
|
bagel.monitoring.grafana-agent.exporters.gerrit = {
|
|
|
|
port = 4778; # grrt
|
|
|
|
bearerTokenFile = config.age.secrets.gerrit-prometheus-bearer-token.path;
|
|
|
|
scrapeConfig.metrics_path = "/plugins/metrics-reporter-prometheus/metrics";
|
|
|
|
};
|
2024-07-01 17:49:32 +00:00
|
|
|
};
|
|
|
|
}
|