grace/dots

dotfiles/nix configs

git clone https://git.gae.moe/grace/dots

Grace Yoderi gotta stop doing these massive changesb70d9f9

main
5.5 KiB179 linesraw
1{ lib, pkgs, ... }:
2
3let
4  gitDir = "/mnt/ext/git";
5  sorcery = import ../pkgs/sorcery.nix { inherit pkgs; };
6  auth = import ./nginx-auth.nix { };
7  instances = {
8    public = {
9      domain = "git.gae.moe";
10      exports = "${gitDir}/srv/public";
11      repositories = {
12        grace = "${gitDir}/grace";
13      };
14    };
15    private = {
16      domain = "i.git.gae.moe";
17      exports = "${gitDir}/srv/private";
18      repositories = {
19        private = "${gitDir}/private";
20        classes = "${gitDir}/classes";
21        mirror-gyoder = "${gitDir}/mirrors/gyoder";
22        mirror-very-old = "${gitDir}/mirrors/very_old/gyoder";
23        mirror-autonomous = "${gitDir}/mirrors/Autonomous-Motorsports-Purdue";
24      };
25    };
26  };
27  sshCommand = pkgs.writeShellScript "sorcery-ssh-command" ''
28    export PATH=${pkgs.git}/bin:$PATH
29    export SORCERY_REPOSITORIES=${instances.public.exports}
30    export SORCERY_INSTANCE_NAME=git.gae.moe
31    export SORCERY_CLONE_URL_BASE=https://git.gae.moe
32    umask 0007
33    exec ${sorcery.sshPackage}/bin/sorcery-ssh
34  '';
35
36  mkService = name: instance: {
37    description = "Sorcery ${name} Git server";
38    wantedBy = [ "multi-user.target" ];
39    after = [ "systemd-tmpfiles-setup.service" ];
40    unitConfig.RequiresMountsFor = gitDir;
41    path = [
42      pkgs.git
43      pkgs.coreutils
44    ];
45    environment = {
46      SORCERY_REPOSITORIES = "/run/sorcery-${name}/repositories";
47      SORCERY_CACHE = "/var/cache/sorcery-${name}";
48      SORCERY_SOCKET = "/run/sorcery-${name}/sock";
49      SORCERY_INSTANCE_NAME = instance.domain;
50      SORCERY_CLONE_URL_BASE = "https://${instance.domain}";
51    };
52    preStart = ''
53      mkdir -p /var/cache/sorcery-${name}/.arborium/${sorcery.grammarVersion}
54      cp -L --remove-destination ${sorcery.grammars}/*.wasm /var/cache/sorcery-${name}/.arborium/${sorcery.grammarVersion}/
55    '';
56    serviceConfig = {
57      ExecStart = "${sorcery.package}/bin/sorceryd";
58      User = "git";
59      Group = "git";
60      UMask = "0007";
61      RuntimeDirectory = "sorcery-${name}";
62      RuntimeDirectoryMode = "0750";
63      CacheDirectory = "sorcery-${name}";
64      CacheDirectoryMode = "0750";
65      BindPaths = lib.mapAttrsToList (
66        namespace: path: "-${path}:/run/sorcery-${name}/repositories/${namespace}"
67      ) instance.repositories;
68      Restart = "on-failure";
69      RestartSec = 2;
70      NoNewPrivileges = true;
71      PrivateTmp = true;
72      ProtectSystem = "strict";
73      ProtectHome = "read-only";
74    };
75  };
76
77  mkHost = name: instance: {
78    locations =
79      (lib.optionalAttrs (name == "private") auth.locations)
80      // {
81        "/" = {
82          proxyPass = "http://unix:/run/sorcery-${name}/sock";
83          extraConfig = lib.optionalString (name == "private") auth.browser;
84        };
85        "~ ^/_sorcery/(.+/(?:refs|ref/.+/blob/.+))$".extraConfig = ''
86          internal;
87          auth_request off;
88          alias /var/cache/sorcery-${name}/$1;
89          types { }
90          default_type text/html;
91        '';
92        "/_sorcery/".extraConfig = ''
93          internal;
94          auth_request off;
95          alias /var/cache/sorcery-${name}/;
96        '';
97        "/_sorcery-git/".extraConfig = ''
98          internal;
99          auth_request off;
100          alias ${instance.exports}/;
101        '';
102      }
103      // lib.optionalAttrs (name == "private") {
104        "~ ^/[^/]+/[^/]+/(info/refs|git-upload-pack)$" = {
105          proxyPass = "http://unix:/run/sorcery-private/sock";
106          extraConfig = auth.git;
107        };
108      };
109  };
110in
111{
112
113  imports = [ ./githooks.nix ];
114  programs.git = {
115    enable = true;
116    config.init.defaultBranch = "main";
117  };
118  users.groups.git = { };
119  users.users.git = {
120    isSystemUser = true;
121    group = "git";
122    home = gitDir;
123    shell = pkgs.bashInteractive;
124  };
125  users.users.nginx.extraGroups = [ "git" ];
126
127  environment.etc."ssh/git-user-ca.pub".source = ../ssh-ca.pub;
128  environment.etc."ssh/git-principals".text = ''
129    t:dev
130    u:grace
131    u:root
132  '';
133  environment.etc."ssh/git-principals".mode = "0644";
134  environment.etc."ssh/git-authorized-keys".text = ''
135    restrict sk-ssh-ed25519@openssh.com AAAAGnNrLXNzaC1lZDI1NTE5QG9wZW5zc2guY29tAAAAIA6Eq2yVsZrCH8so7f3ygH0UWp6WkOxbhLNFC9QewKwoAAAABHNzaDo= grace_yoder@outlook.com
136  '';
137  environment.etc."ssh/git-authorized-keys".mode = "0644";
138  services.openssh = {
139    enable = true;
140    extraConfig = ''
141      Match User git
142        TrustedUserCAKeys /etc/ssh/git-user-ca.pub
143        AuthorizedPrincipalsFile /etc/ssh/git-principals
144        AuthorizedKeysFile /etc/ssh/git-authorized-keys
145        ForceCommand ${sshCommand}
146        PubkeyAuthentication yes
147        PasswordAuthentication no
148        KbdInteractiveAuthentication no
149        DisableForwarding yes
150        PermitTTY no
151        PermitUserRC no
152        X11Forwarding no
153    '';
154  };
155
156  systemd.tmpfiles.rules = [
157    "d ${gitDir} 0750 git git -"
158    "d ${gitDir}/mirrors 0750 git git -"
159    "d ${gitDir}/mirrors/very_old 0750 git git -"
160    "d ${gitDir}/srv 0750 git git -"
161  ]
162  ++ lib.concatLists (
163    lib.mapAttrsToList (
164      _: instance:
165      [ "d ${instance.exports} 0750 git git -" ]
166      ++ lib.mapAttrsToList (_: path: "d ${path} 0750 git git -") instance.repositories
167      ++ lib.mapAttrsToList (
168        namespace: path: "L+ ${instance.exports}/${namespace} - - - - ${path}"
169      ) instance.repositories
170    ) instances
171  );
172
173  systemd.services = lib.mapAttrs' (
174    name: instance: lib.nameValuePair "sorcery-${name}" (mkService name instance)
175  ) instances;
176  services.nginx.virtualHosts = lib.mapAttrs' (
177    name: instance: lib.nameValuePair instance.domain (mkHost name instance)
178  ) instances;
179}