1 { config, lib, pkgs, ... }:
5 cfg = config.services.sourcehut;
8 statePath = "/var/lib/sourcehut/gitsrht";
10 rcfg = config.services.redis;
11 drv = pkgs.sourcehut.gitsrht;
14 options.services.sourcehut.git = {
30 Port on which the "git" module should listen.
36 default = "git.sr.ht";
38 PostgreSQL database name for git.sr.ht.
45 example = literalExample "pkgs.gitFull";
47 Git package for git.sr.ht. This can help silence collisions.
52 config = with scfg; lib.mkIf (cfg.enable && elem "git" cfg.services) {
53 # sshd refuses to run with `Unsafe AuthorizedKeysCommand ... bad ownership or modes for directory /nix/store`
54 environment.etc."ssh/gitsrht-dispatch" = {
57 #! ${pkgs.stdenv.shell}
58 ${cfg.python}/bin/gitsrht-dispatch "$@"
62 # Needs this in the $PATH when sshing into the server
63 environment.systemPackages = [ cfg.git.package ];
70 # https://stackoverflow.com/questions/22314298/git-push-results-in-fatal-protocol-error-bad-line-length-character-this
71 # Probably could use gitsrht-shell if output is restricted to just parameters...
73 description = "git.sr.ht user";
83 cron.systemCronJobs = [ "*/20 * * * * ${cfg.python}/bin/gitsrht-periodic" ];
84 fcgiwrap.enable = true;
86 openssh.authorizedKeysCommand = ''/etc/ssh/gitsrht-dispatch "%u" "%h" "%t" "%k"'';
87 openssh.authorizedKeysCommandUser = "root";
88 openssh.extraConfig = ''
89 PermitUserEnvironment SRHT_*
94 local ${database} ${user} trust
96 ensureDatabases = [ database ];
100 ensurePermissions = { "DATABASE \"${database}\"" = "ALL PRIVILEGES"; };
108 # /var/log is owned by root
109 "f /var/log/git-srht-shell 0644 ${user} ${user} -"
111 "d ${cfg.settings."${iniKey}".repos} 2755 ${user} ${user} -"
115 gitsrht = import ./service.nix { inherit config pkgs lib; } scfg drv iniKey {
116 after = [ "redis.service" "postgresql.service" "network.target" ];
117 requires = [ "redis.service" "postgresql.service" ];
118 wantedBy = [ "multi-user.target" ];
120 # Needs internally to create repos at the very least
122 description = "git.sr.ht website service";
124 serviceConfig.ExecStart = "${cfg.python}/bin/gunicorn ${drv.pname}.app:app -b ${cfg.address}:${toString port}";
128 after = [ "postgresql.service" "network.target" ];
129 requires = [ "postgresql.service" ];
130 wantedBy = [ "multi-user.target" ];
132 description = "git.sr.ht webhooks service";
139 serviceConfig.ExecStart = "${cfg.python}/bin/celery -A ${drv.pname}.webhooks worker --loglevel INFO --pool eventlet";
144 services.sourcehut.settings = {
145 # The authorized keys hook uses this to dispatch to various handlers
146 # The format is a program to exec into as the key, and the user to match as the
147 # value. When someone tries to log in as this user, this program is executed
148 # and is expected to omit an AuthorizedKeys file.
150 # Discard of the string context is in order to allow derivation-derived strings.
151 # This is safe if the relevant package is installed which will be the case if the setting is utilized.
152 "git.sr.ht::dispatch".${builtins.unsafeDiscardStringContext "${pkgs.sourcehut.gitsrht}/bin/gitsrht-keys"} = mkDefault "${user}:${user}";
155 services.nginx.virtualHosts."git.${cfg.originBase}" = {
157 locations."/".proxyPass = "http://${cfg.address}:${toString port}";
158 locations."/query".proxyPass = cfgIni."meta.sr.ht".api-origin;
159 locations."/static".root = "${pkgs.sourcehut.gitsrht}/${pkgs.sourcehut.python.sitePackages}/gitsrht";
161 location = /authorize {
162 proxy_pass http://${cfg.address}:${toString port};
163 proxy_pass_request_body off;
164 proxy_set_header Content-Length "";
165 proxy_set_header X-Original-URI $request_uri;
167 location ~ ^/([^/]+)/([^/]+)/(HEAD|info/refs|objects/info/.*|git-upload-pack).*$ {
168 auth_request /authorize;
170 fastcgi_pass unix:/run/fcgiwrap.sock;
171 fastcgi_param SCRIPT_FILENAME ${pkgs.git}/bin/git-http-backend;
172 fastcgi_param PATH_INFO $uri;
173 fastcgi_param GIT_PROJECT_ROOT $document_root;
174 fastcgi_read_timeout 500s;
175 include ${pkgs.nginx}/conf/fastcgi_params;