all repos — nix-packages @ main

My personal collection of packages for nix

modules/nixos/git-pr.nix (view raw)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
{
  config,
  lib,
  pkgs,
  ...
}:
with lib;
let
  cfg = config.services.git-pr;

  settingsFormat = pkgs.formats.toml { };
in
{
  options.services.git-pr = {
    enable = mkEnableOption "A pastebin supercharged for git collaboration.";

    package = mkPackageOption pkgs "git-pr" { };

    user = mkOption {
      type = types.str;
      default = "git-pr";
      description = "The user to use for git-pr.";
    };

    group = mkOption {
      type = types.str;
      default = "git-pr";
      description = "The group to use for git-pr.";
    };

    homeDir = mkOption {
      type = types.path;
      default = "/var/lib/git-pr";
      description = "The home directory for git-pr.";
    };

    settings = mkOption {
      default = { };

      description = ''
        Additional settings for git-pr.

        See https://github.com/picosh/git-pr/blob/main/git-pr.toml
      '';

      type = types.submodule {
        freeformType = settingsFormat.type;
        options = {
          url = mkOption {
            type = types.str;
            default = "localhost";
            description = "Used for help commands, exclude protocol.";
          };

          host = mkOption {
            type = types.str;
            default = "0.0.0.0";
            description = "Host to listen (web and ssh).";
          };

          ssh_port = mkOption {
            type = types.port;
            default = 2222;
            description = "Port to listen for ssh connections.";
          };

          web_port = mkOption {
            type = types.port;
            default = 3000;
            description = "Port to listen for web connections.";
          };

          data_dir = mkOption {
            type = types.path;
            default = "${cfg.homeDir}/data";
            description = "Where we store the sqlite db, this toml file, and ssh host keys.";
          };

          admins = mkOption {
            type = types.listOf (types.str);
            default = [ ];
            description = "List of admin ssh pubkeys, authorised to submit review and other admin permissions.";
          };

          time_format = mkOption {
            type = types.str;
            default = "2006-01-02";
            description = "Set datetime format for our clients. See https://pkg.go.dev/time#pkg-constants for explanation.";
          };

          create_repo = mkOption {
            type = types.enum [
              "admin"
              "user"
            ];
            default = "admin";
            description = "Who can create new repos?";
          };

          desc = mkOption {
            type = types.str;
            default = "";
            description = "Add a description box to the top of the index page, supports HTML.";
          };

          theme = mkOption {
            type = types.str;
            default = "dracula";
            description = "Set the theme for the web interface.";
          };
        };
      };
    };
  };

  config = mkIf cfg.enable {
    users.users = optionalAttrs (cfg.user == "git-pr") {
      git-pr = {
        inherit (cfg) group;
        isSystemUser = true;
        home = cfg.homeDir;
        createHome = true;
      };
    };
    users.groups = optionalAttrs (cfg.group == "git-pr") {
      git-pr = { };
    };

    systemd.services.git-pr = {
      description = "A pastebin supercharged for git collaboration.";
      after = [ "network.target" ];
      wantedBy = [ "multi-user.target" ];

      serviceConfig =
        let
          configFile = settingsFormat.generate "git-pr-config.toml" cfg.settings;
        in
        {
          User = cfg.user;
          Group = cfg.group;
          WorkingDirectory = cfg.homeDir;
          ExecStart = "${cfg.package}/bin/git-pr --config ${configFile}";
          ExecStartPre = "${pkgs.coreutils}/bin/install -d -m 755 ${cfg.homeDir}/data";
          Restart = "always";

          RestrictAddressFamilies = [
            "AF_UNIX"
            "AF_INET"
            "AF_INET6"
          ];
        }
        // lib.optionalAttrs (cfg.settings.web_port < 1024 || cfg.settings.ssh_port < 1024) {
          AmbientCapabilities = [ "CAP_NET_BIND_SERVICE" ];
          CapabilityBoundingSet = [ "CAP_NET_BIND_SERVICE" ];
        };
    };
  };
}