default.nix (4250B)
1 { 2 lib, 3 options, 4 config, 5 pkgs, 6 ... 7 }: 8 { 9 imports = [ 10 ./daemon 11 ]; 12 13 options.modules.git = { 14 enable = lib.mkOption { 15 description = "Whether to set up a Git server."; 16 default = false; 17 type = lib.types.bool; 18 }; 19 directory = lib.mkOption { 20 description = '' 21 The directory where specified bare repositories are created. 22 ''; 23 default = "/srv/git"; 24 readOnly = true; 25 type = lib.types.uniq lib.types.path; 26 }; 27 repositories = lib.mkOption { 28 description = "For each bare repository name, its configuration."; 29 default = { }; 30 type = 31 lib.types.submodule { 32 options = { 33 additionalFiles = lib.mkOption { 34 description = '' 35 For each additional file to add to the repository directory, 36 its content. 37 ''; 38 default = { }; 39 type = lib.types.attrsOf lib.types.str; 40 }; 41 hooks = { 42 preReceive = lib.mkOption { 43 description = "The pre-receive hook script."; 44 default = "${pkgs.writeShellScriptBin "script" ""}/bin/script"; 45 type = lib.types.uniq lib.types.path; 46 }; 47 update = lib.mkOption { 48 description = "The update hook script."; 49 default = "${pkgs.writeShellScriptBin "script" ""}/bin/script"; 50 type = lib.types.uniq lib.types.path; 51 }; 52 postReceive = lib.mkOption { 53 description = "The post-receive hook script."; 54 default = "${pkgs.writeShellScriptBin "script" ""}/bin/script"; 55 type = lib.types.uniq lib.types.path; 56 }; 57 }; 58 }; 59 } 60 |> lib.types.attrsOf; 61 }; 62 }; 63 64 config = lib.mkIf config.modules.git.enable { 65 users = { 66 users = { 67 git = { 68 hashedPassword = "!"; 69 isSystemUser = true; 70 group = "git"; 71 createHome = true; 72 home = config.modules.git.directory; 73 shell = "${pkgs.git}/bin/git-shell"; 74 }; 75 }; 76 groups = { 77 git = { }; 78 }; 79 }; 80 81 programs.git = { 82 enable = true; 83 package = pkgs.git; 84 }; 85 86 systemd = { 87 services = { 88 git-repositories = { 89 enable = true; 90 wantedBy = [ "multi-user.target" ]; 91 serviceConfig = 92 let 93 inherit (config.modules.git) repositories directory; 94 script = 95 repositories 96 |> builtins.mapAttrs ( 97 name: 98 { 99 additionalFiles, 100 hooks, 101 }: 102 '' 103 ${pkgs.git}/bin/git init -q --bare -b master \ 104 ${directory}/${name} 105 106 ${ 107 ( 108 additionalFiles 109 |> builtins.mapAttrs ( 110 fileName: content: '' 111 ${pkgs.sbase}/bin/echo "${content}" > \ 112 ${directory}/${name}/${fileName} 113 '' 114 ) 115 |> builtins.attrValues 116 |> builtins.concatStringsSep "\n" 117 ) 118 } 119 120 ${pkgs.sbase}/bin/mkdir -p ${directory}/${name}/hooks 121 122 ${pkgs.sbase}/bin/ln -sf ${hooks.preReceive} \ 123 ${directory}/${name}/hooks/pre-receive 124 125 ${pkgs.sbase}/bin/ln -sf ${hooks.update} \ 126 ${directory}/${name}/hooks/update 127 128 ${pkgs.sbase}/bin/ln -sf ${hooks.postReceive} \ 129 ${directory}/${name}/hooks/post-receive 130 '' 131 ) 132 |> builtins.attrValues 133 |> builtins.concatStringsSep "\n" 134 |> pkgs.writeShellScriptBin "script"; 135 in 136 { 137 User = "git"; 138 Group = "git"; 139 Type = "oneshot"; 140 ExecStart = "${script}/bin/script"; 141 }; 142 }; 143 }; 144 }; 145 }; 146 }