Mirror of https://git.jolheiser.com/ugit
2
fork

Configure Feed

Select the types of activity you want to include in your feed.

multiple nix module instances

+134 -99
+1
cmd/ugitd/args.go
··· 101 101 }) 102 102 fs.BoolVar(&c.Log.JSON, "log.json", c.Log.JSON, "Print logs in JSON(L) format") 103 103 fs.StringVar(&c.RepoDir, "repo-dir", c.RepoDir, "Path to directory containing repositories") 104 + fs.BoolVar(&c.ShowPrivate, "show-private", c.ShowPrivate, "Show private repos in web interface") 104 105 fs.BoolVar(&c.SSH.Enable, "ssh.enable", c.SSH.Enable, "Enable SSH server") 105 106 fs.StringVar(&c.SSH.AuthorizedKeys, "ssh.authorized-keys", c.SSH.AuthorizedKeys, "Path to authorized_keys") 106 107 fs.StringVar(&c.SSH.CloneURL, "ssh.clone-url", c.SSH.CloneURL, "SSH clone URL base")
+133 -99
nix/module.nix
··· 8 8 cfg = config.services.ugit; 9 9 pkg = pkgs.callPackage ./pkg.nix { inherit pkgs; }; 10 10 yamlFormat = pkgs.formats.yaml { }; 11 - configFile = pkgs.writeText "ugit.yaml" ( 12 - builtins.readFile (yamlFormat.generate "ugit-yaml" cfg.config) 13 - ); 14 - authorizedKeysFile = pkgs.writeText "ugit_keys" (builtins.concatStringsSep "\n" cfg.authorizedKeys); 15 - in 16 - { 17 - options = 11 + instanceOptions = 12 + { name, config, ... }: 18 13 let 19 14 inherit (lib) mkEnableOption mkOption types; 20 15 in 21 16 { 22 - services.ugit = { 17 + options = { 23 18 enable = mkEnableOption "Enable ugit"; 24 19 25 20 package = mkOption { ··· 28 23 default = pkg; 29 24 }; 30 25 26 + homeDir = mkOption { 27 + type = types.str; 28 + description = "ugit home directory"; 29 + default = "/var/lib/${name}"; 30 + }; 31 + 31 32 repoDir = mkOption { 32 33 type = types.str; 33 34 description = "where ugit stores repositories"; 34 - default = "/var/lib/ugit/repos"; 35 + default = "/var/lib/${name}/repos"; 35 36 }; 36 37 37 38 authorizedKeys = mkOption { ··· 43 44 authorizedKeysFile = mkOption { 44 45 type = types.str; 45 46 description = "path to authorized_keys file ugit uses for auth"; 46 - default = "/var/lib/ugit/authorized_keys"; 47 + default = "/var/lib/${name}/authorized_keys"; 47 48 }; 48 49 49 50 hostKeyFile = mkOption { 50 51 type = types.str; 51 52 description = "path to host key file (will be created if it doesn't exist)"; 52 - default = "/var/lib/ugit/ugit_ed25519"; 53 + default = "/var/lib/${name}/ugit_ed25519"; 53 54 }; 54 55 55 56 config = mkOption { ··· 60 61 61 62 user = mkOption { 62 63 type = types.str; 63 - default = "ugit"; 64 + default = "ugit-${name}"; 64 65 description = "User account under which ugit runs"; 65 66 }; 66 67 67 68 group = mkOption { 68 69 type = types.str; 69 - default = "ugit"; 70 + default = "ugit-${name}"; 70 71 description = "Group account under which ugit runs"; 71 72 }; 72 73 73 - openFirewall = mkOption { 74 - type = types.bool; 75 - default = false; 76 - }; 77 - 78 74 hooks = mkOption { 79 75 type = types.listOf ( 80 76 types.submodule { ··· 95 91 }; 96 92 }; 97 93 }; 98 - config = lib.mkIf cfg.enable { 99 - users.users."${cfg.user}" = { 100 - home = "/var/lib/ugit"; 101 - createHome = true; 102 - group = "${cfg.group}"; 103 - isSystemUser = true; 104 - isNormalUser = false; 105 - description = "user for ugit service"; 106 - }; 107 - users.groups."${cfg.group}" = { }; 108 - networking.firewall = lib.mkIf cfg.openFirewall { 109 - allowedTCPPorts = [ 110 - 8448 111 - 8449 112 - ]; 94 + in 95 + { 96 + options = { 97 + services.ugit = lib.mkOption { 98 + type = lib.types.attrsOf (lib.types.submodule instanceOptions); 99 + default = { }; 100 + description = "Attribute set of ugit instances"; 113 101 }; 102 + }; 103 + config = lib.mkIf (cfg != { }) { 104 + users.users = lib.mapAttrs' ( 105 + name: instanceCfg: 106 + lib.nameValuePair instanceCfg.user { 107 + home = instanceCfg.homeDir; 108 + createHome = true; 109 + group = instanceCfg.group; 110 + isSystemUser = true; 111 + isNormalUser = false; 112 + description = "user for ugit ${name} service"; 113 + } 114 + ) (lib.filterAttrs (name: instanceCfg: instanceCfg.enable) cfg); 114 115 115 - systemd.services = { 116 - ugit = { 117 - enable = true; 118 - script = 119 - let 120 - authorizedKeysPath = 121 - if (builtins.length cfg.authorizedKeys) > 0 then authorizedKeysFile else cfg.authorizedKeysFile; 122 - args = [ 123 - "--config=${configFile}" 124 - "--repo-dir=${cfg.repoDir}" 125 - "--ssh.authorized-keys=${authorizedKeysPath}" 126 - "--ssh.host-key=${cfg.hostKeyFile}" 116 + users.groups = lib.mapAttrs' (name: instanceCfg: lib.nameValuePair instanceCfg.group { }) ( 117 + lib.filterAttrs (name: instanceCfg: instanceCfg.enable) cfg 118 + ); 119 + 120 + systemd.services = lib.foldl' ( 121 + acc: name: 122 + let 123 + instanceCfg = cfg.${name}; 124 + in 125 + lib.recursiveUpdate acc ( 126 + lib.optionalAttrs instanceCfg.enable { 127 + "ugit-${name}" = { 128 + enable = true; 129 + description = "ugit instance ${name}"; 130 + wantedBy = [ "multi-user.target" ]; 131 + after = [ "network.target" ]; 132 + path = [ 133 + instanceCfg.package 134 + pkgs.git 135 + pkgs.bash 127 136 ]; 128 - in 129 - "${cfg.package}/bin/ugitd ${builtins.concatStringsSep " " args}"; 130 - wantedBy = [ "multi-user.target" ]; 131 - after = [ "network.target" ]; 132 - path = [ 133 - cfg.package 134 - pkgs.git 135 - pkgs.bash 136 - ]; 137 - serviceConfig = { 138 - User = cfg.user; 139 - Group = cfg.group; 140 - Restart = "always"; 141 - RestartSec = "15"; 142 - WorkingDirectory = "/var/lib/ugit"; 143 - }; 144 - }; 145 - ugit-hooks = { 146 - wantedBy = [ "multi-user.target" ]; 147 - after = [ "ugit.service" ]; 148 - requires = [ "ugit.service" ]; 149 - serviceConfig = { 150 - Type = "oneshot"; 151 - ExecStart = 152 - let 153 - script = pkgs.writeShellScript "ugit-hooks-link" ( 154 - builtins.concatStringsSep "\n" ( 155 - map ( 137 + serviceConfig = { 138 + User = instanceCfg.user; 139 + Group = instanceCfg.group; 140 + Restart = "always"; 141 + RestartSec = "15"; 142 + WorkingDirectory = instanceCfg.homeDir; 143 + ExecStart = 144 + let 145 + configFile = pkgs.writeText "ugit-${name}.yaml" ( 146 + builtins.readFile (yamlFormat.generate "ugit-${name}-yaml" instanceCfg.config) 147 + ); 148 + authorizedKeysFile = pkgs.writeText "ugit_${name}_keys" ( 149 + builtins.concatStringsSep "\n" instanceCfg.authorizedKeys 150 + ); 151 + 152 + authorizedKeysPath = 153 + if (builtins.length instanceCfg.authorizedKeys) > 0 then 154 + authorizedKeysFile 155 + else 156 + instanceCfg.authorizedKeysFile; 157 + args = [ 158 + "--config=${configFile}" 159 + "--repo-dir=${instanceCfg.repoDir}" 160 + "--ssh.authorized-keys=${authorizedKeysPath}" 161 + "--ssh.host-key=${instanceCfg.hostKeyFile}" 162 + ]; 163 + in 164 + "${instanceCfg.package}/bin/ugitd ${builtins.concatStringsSep " " args}"; 165 + }; 166 + }; 167 + 168 + "ugit-${name}-hooks" = { 169 + description = "Setup hooks for ugit instance ${name}"; 170 + wantedBy = [ "multi-user.target" ]; 171 + after = [ "ugit-${name}.service" ]; 172 + requires = [ "ugit-${name}.service" ]; 173 + serviceConfig = { 174 + Type = "oneshot"; 175 + RemainAfterExit = true; 176 + User = instanceCfg.user; 177 + Group = instanceCfg.group; 178 + ExecStart = 179 + let 180 + hookDir = "${instanceCfg.repoDir}/hooks/pre-receive.d"; 181 + mkHookScript = 156 182 hook: 157 183 let 158 - script = pkgs.writeShellScript hook.name hook.content; 159 - path = "${cfg.repoDir}/hooks/pre-receive.d/${hook.name}"; 184 + script = pkgs.writeShellScript "ugit-${name}-${hook.name}" hook.content; 160 185 in 161 - "ln -s ${script} ${path}" 162 - ) cfg.hooks 163 - ) 164 - ); 165 - in 166 - "${script}"; 167 - }; 168 - }; 169 - }; 170 - 171 - systemd.tmpfiles.settings.ugit = builtins.listToAttrs ( 172 - map ( 173 - hook: 174 - let 175 - script = pkgs.writeShellScript hook.name hook.content; 176 - path = "${cfg.repoDir}/hooks/pre-receive.d/${hook.name}"; 177 - in 178 - { 179 - name = path; 180 - value = { 181 - "L" = { 182 - argument = "${script}"; 186 + '' 187 + mkdir -p ${hookDir} 188 + ln -sf ${script} ${hookDir}/${hook.name} 189 + ''; 190 + in 191 + pkgs.writeShellScript "ugit-${name}-hooks-setup" '' 192 + ${builtins.concatStringsSep "\n" (map mkHookScript instanceCfg.hooks)} 193 + ''; 183 194 }; 184 195 }; 185 196 } 186 - ) cfg.hooks 187 - ); 197 + ) 198 + ) { } (builtins.attrNames cfg); 199 + 200 + systemd.tmpfiles.settings = lib.mapAttrs' ( 201 + name: instanceCfg: 202 + lib.nameValuePair "ugit-${name}" ( 203 + builtins.listToAttrs ( 204 + map ( 205 + hook: 206 + let 207 + script = pkgs.writeShellScript hook.name hook.content; 208 + path = "${instanceCfg.repoDir}/hooks/pre-receive.d/${hook.name}"; 209 + in 210 + { 211 + name = path; 212 + value = { 213 + "L" = { 214 + argument = "${script}"; 215 + }; 216 + }; 217 + } 218 + ) instanceCfg.hooks 219 + ) 220 + ) 221 + ) (lib.filterAttrs (name: instanceCfg: instanceCfg.enable) cfg); 188 222 }; 189 223 }