{ config, lib, inputs, pkgs, ... }: let inherit (lib) pipe flatten concatMapAttrs mapAttrsToList ; inherit (import ../../lib/caddy.nix { inherit lib; }) security-headers; hostname = config.networking.hostName; domain = "alin.ovh"; ts-domain = "fin-marlin.ts.net"; serverName = "git.${domain}"; gitoliteCfg = config.services.gitolite; repos = "${gitoliteCfg.dataDir}/repositories"; mirrors = { sourcehut = { hostname = "git.sr.ht"; username = "~alinnow"; }; codeberg = { hostname = "codeberg.org"; username = "alinnow"; }; github = { hostname = "github.com"; username = "alinnow"; }; gitlab = { hostname = "gitlab.com"; username = "alinnow"; }; }; repoMirrors = { nixfiles = [ "sourcehut" "codeberg" ]; searchix = [ "sourcehut" "codeberg" ]; website = [ "sourcehut" ]; homestead = [ "sourcehut" ]; htmlformat = [ "codeberg" "github" ]; legit = [ "github" ]; elgit = [ "codeberg" ]; gomponents = [ "sourcehut" "github" ]; nix-packages = [ "sourcehut" "codeberg" "github" ]; zola-bearblog = [ "sourcehut" "codeberg" "gitlab" ]; scriptura = [ "sourcehut" "codeberg" ]; }; createMirrorService = name: { hostname, username }: { "mirror-to-${name}@" = { path = with pkgs; [ config.programs.git.package openssh ]; serviceConfig = { Type = "oneshot"; User = "gitolite"; WorkingDirectory = "${repos}/%i.git"; ExecStart = "${config.programs.git.package}/bin/git push --mirror git@${hostname}:${username}/%i"; }; unitConfig = { # only mirror public repositories ConditionPathExists = "${repos}/%i.git/git-daemon-export-ok"; }; }; }; createMirrorPath = name: { ... }: { "mirror-to-${name}@" = { pathConfig = { PathChanged = "${repos}/%i.git/refs/heads"; StartLimitIntervalSec = "1h"; StartLimitBurst = 5; }; }; }; mkMirrorWants = repo: map (target: "mirror-to-${target}@${repo}.path"); in { imports = [ inputs.elgit.nixosModules.elgit ]; nixpkgs.overlays = [ inputs.elgit.overlays.default ]; services.gitolite = { enable = true; adminPubkey = "ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBENXbdPPOq0mA+9bPklpUkikvIXjCEKE5IRwNPNMr5/Ta1J/ND737fexCjEb7YPoAJtaf0gD/JThQQi/RxDTvy4= alin@alin.ovh"; extraGitoliteRc = '' $RC{UMASK} = 0027; $RC{LOG_EXTRA} = 0; $RC{HOSTNAME} = "${config.networking.hostName}"; $RC{LOCAL_CODE} = "$rc{GL_ADMIN_BASE}/local"; push( @{$RC{ENABLE}}, 'D' ); push( @{$RC{ENABLE}}, 'Shell alan' ); push( @{$RC{ENABLE}}, 'cgit' ); push( @{$RC{ENABLE}}, 'repo-specific-hooks' ); ''; }; services.elgit = { enable = true; group = gitoliteCfg.group; settings = { server = { name = serverName; host = "::1"; }; repo = { root = gitoliteCfg.dataDir; }; dirs.static = "/srv/http/elgit/static"; }; }; services.gitDaemon = { enable = true; # used for CI user = "gitolite"; group = gitoliteCfg.group; basePath = repos; }; programs.git.config = { uploadPack = { allowAnySHA1InWant = true; }; }; services.caddy.virtualHosts = { "${serverName}" = let settings = config.services.elgit.settings; server = settings.server; in { extraConfig = '' encode zstd gzip ${security-headers { overrides.content-security-policy = { default-src = [ "none" ]; base-uri = [ "none" ]; style-src = [ "self" ]; script-src = [ "none" ]; form-action = [ "self" ]; connect-src = [ "self" ]; img-src = [ "https:" ]; object-src = [ "none" ]; }; }} reverse_proxy [${server.host}]:${toString server.port} ''; }; "git.alanpearce.eu" = { extraConfig = '' redir https://${serverName}{uri} 301 permanent ''; }; }; systemd.paths = concatMapAttrs createMirrorPath mirrors; systemd.targets.git-mirroring = { wantedBy = [ "multi-user.target" ]; wants = pipe repoMirrors [ (mapAttrsToList mkMirrorWants) flatten ]; }; systemd.services = (concatMapAttrs createMirrorService mirrors) // { backup-gitolite = { startAt = "daily"; path = with pkgs; [ openssh ]; serviceConfig = { Type = "oneshot"; ExecStart = "${lib.getExe pkgs.rdiff-backup} --api-version 201 backup ${config.services.gitolite.dataDir} ${hostname}@r5.${ts-domain}::gitolite"; ExecStartPost = "-${lib.getExe pkgs.rdiff-backup} --api-version 201 remove increments --older-than 3M ${hostname}@r5.${ts-domain}::gitolite"; }; }; }; networking.firewall.allowedTCPPorts = [ 9418 ]; }