about summary refs log tree commit diff
path: root/overlays/git-daemon-module.nix
blob: 76b395ecca29266ffa53d6025537da59f05f352a (plain)
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
{ config, lib, pkgs, ... }:
with lib;
let

  cfg = config.services.gitDaemon;

in
{

  ###### interface

  options = {
    services.gitDaemon = {

      enable = mkOption {
        type = types.bool;
        default = false;
        description = lib.mdDoc ''
          Enable Git daemon, which allows public hosting of git repositories
          without any access controls. This is mostly intended for read-only access.

          You can allow write access by setting daemon.receivepack configuration
          item of the repository to true. This is solely meant for a closed LAN setting
          where everybody is friendly.

          If you need any access controls, use something else.
        '';
      };

      basePath = mkOption {
        type = types.str;
        default = "";
        example = "/srv/git/";
        description = lib.mdDoc ''
          Remap all the path requests as relative to the given path. For example,
          if you set base-path to /srv/git, then if you later try to pull
          git://example.com/hello.git, Git daemon will interpret the path as /srv/git/hello.git.
        '';
      };

      exportAll = mkOption {
        type = types.bool;
        default = false;
        description = lib.mdDoc ''
          Publish all directories that look like Git repositories (have the objects
          and refs subdirectories), even if they do not have the git-daemon-export-ok file.

          If disabled, you need to touch .git/git-daemon-export-ok in each repository
          you want the daemon to publish.

          Warning: enabling this without a repository whitelist or basePath
          publishes every git repository you have.
        '';
      };

      repositories = mkOption {
        type = types.listOf types.str;
        default = [ ];
        example = [ "/srv/git" "/home/user/git/repo2" ];
        description = lib.mdDoc ''
          A whitelist of paths of git repositories, or directories containing repositories
          all of which would be published. Paths must not end in "/".

          Warning: leaving this empty and enabling exportAll publishes all
          repositories in your filesystem or basePath if specified.
        '';
      };

      listenAddress = mkOption {
        type = types.str;
        default = "";
        example = "example.com";
        description = lib.mdDoc "Listen on a specific IP address or hostname.";
      };

      port = mkOption {
        type = types.port;
        default = 9418;
        description = lib.mdDoc "Port to listen on.";
      };

      options = mkOption {
        type = types.str;
        default = "";
        description = lib.mdDoc "Extra configuration options to be passed to Git daemon.";
      };

      user = mkOption {
        type = types.str;
        default = "git";
        description = lib.mdDoc "User under which Git daemon would be running.";
      };

      group = mkOption {
        type = types.str;
        default = "git";
        description = lib.mdDoc "Group under which Git daemon would be running.";
      };

      createUserAndGroup = mkOption {
        type = types.bool;
        default = true;
        description = lib.mdDoc ''
          Create the specified group and user.
          Disable this option if you want to use the existing user
        '';
      };
    };
  };

  ###### implementation

  config = mkIf cfg.enable {

    users.users.${cfg.user} = optionalAttrs (cfg.createUserAndGroup == true) {
      uid = config.ids.uids.git;
      group = cfg.group;
      description = "Git daemon user";
    };

    users.groups.${cfg.group} = optionalAttrs (cfg.createUserAndGroup == true) {
      gid = config.ids.gids.git;
    };

    systemd.services.git-daemon = {
      after = [ "network.target" ];
      wantedBy = [ "multi-user.target" ];
      script = "${pkgs.git}/bin/git daemon --reuseaddr "
        + (optionalString (cfg.basePath != "") "--base-path=${cfg.basePath} ")
        + (optionalString (cfg.listenAddress != "") "--listen=${cfg.listenAddress} ")
        + "--port=${toString cfg.port} --user=${cfg.user} --group=${cfg.group} ${cfg.options} "
        + "--verbose " + (optionalString cfg.exportAll "--export-all ") + concatStringsSep " " cfg.repositories;
    };

  };

}