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