From 4d8423b4b3cf540a289be9e3be92325e365394b3 Mon Sep 17 00:00:00 2001 From: jolheiser Date: Thu, 13 Feb 2025 18:23:25 -0600 Subject: [PATCH] multiple nix module instances --- nix/module.nix | 179 +++++++++++++++++++++++++++---------------------- 1 file changed, 99 insertions(+), 80 deletions(-) diff --git a/nix/module.nix b/nix/module.nix index d544007..66ffd9b 100644 --- a/nix/module.nix +++ b/nix/module.nix @@ -8,18 +8,12 @@ let cfg = config.services.ugit; pkg = pkgs.callPackage ./pkg.nix { inherit pkgs; }; yamlFormat = pkgs.formats.yaml { }; - configFile = pkgs.writeText "ugit.yaml" ( - builtins.readFile (yamlFormat.generate "ugit-yaml" cfg.config) - ); - authorizedKeysFile = pkgs.writeText "ugit_keys" (builtins.concatStringsSep "\n" cfg.authorizedKeys); -in -{ - options = + instanceOptions = let inherit (lib) mkEnableOption mkOption types; in { - services.ugit = { + options = { enable = mkEnableOption "Enable ugit"; package = mkOption { @@ -28,6 +22,12 @@ in default = pkg; }; + homeDir = mkOption { + type = types.str; + description = "ugit home directory"; + default = "/var/lib/ugit"; + }; + repoDir = mkOption { type = types.str; description = "where ugit stores repositories"; @@ -70,11 +70,6 @@ in description = "Group account under which ugit runs"; }; - openFirewall = mkOption { - type = types.bool; - default = false; - }; - hooks = mkOption { type = types.listOf ( types.submodule { @@ -95,78 +90,102 @@ in }; }; }; - config = lib.mkIf cfg.enable { - users.users."${cfg.user}" = { - home = "/var/lib/ugit"; - createHome = true; - group = "${cfg.group}"; - isSystemUser = true; - isNormalUser = false; - description = "user for ugit service"; - }; - users.groups."${cfg.group}" = { }; - networking.firewall = lib.mkIf cfg.openFirewall { - allowedTCPPorts = [ - 8448 - 8449 - ]; +in +{ + options = { + services.ugit = lib.mkOption { + type = lib.types.attrsOf (lib.types.submodule instanceOptions); + default = { }; + description = "Attribute set of ugit instances"; }; + }; + config = lib.mkIf (cfg != { }) { + users.users = lib.mapAttrs' ( + name: instanceCfg: + lib.nameValuePair instanceCfg.user { + home = instanceCfg.homeDir; + createHome = true; + group = instanceCfg.group; + isSystemUser = true; + isNormalUser = false; + description = "user for ugit ${name} service"; + } + ) (lib.filterAttrs (name: instanceCfg: instanceCfg.enable) cfg); - systemd.services = { - ugit = { - enable = true; - script = + users.groups = lib.mapAttrs' (name: instanceCfg: lib.nameValuePair instanceCfg.group { }) ( + lib.filterAttrs (name: instanceCfg: instanceCfg.enable) cfg + ); + + systemd.services = lib.mapAttrs' ( + name: instanceCfg: + lib.nameValuePair "ugit-${name}" { + ugit = let - authorizedKeysPath = - if (builtins.length cfg.authorizedKeys) > 0 then authorizedKeysFile else cfg.authorizedKeysFile; - args = [ - "--config=${configFile}" - "--repo-dir=${cfg.repoDir}" - "--ssh.authorized-keys=${authorizedKeysPath}" - "--ssh.host-key=${cfg.hostKeyFile}" - ]; + configFile = pkgs.writeText "ugit.yaml" ( + builtins.readFile (yamlFormat.generate "ugit-yaml" instanceCfg.config) + ); + authorizedKeysFile = pkgs.writeText "ugit_keys" ( + builtins.concatStringsSep "\n" instanceCfg.authorizedKeys + ); in - "${cfg.package}/bin/ugitd ${builtins.concatStringsSep " " args}"; - wantedBy = [ "multi-user.target" ]; - after = [ "network.target" ]; - path = [ - cfg.package - pkgs.git - pkgs.bash - ]; - serviceConfig = { - User = cfg.user; - Group = cfg.group; - Restart = "always"; - RestartSec = "15"; - WorkingDirectory = "/var/lib/ugit"; + { + enable = true; + script = + let + authorizedKeysPath = + if (builtins.length instanceCfg.authorizedKeys) > 0 then + authorizedKeysFile + else + instanceCfg.authorizedKeysFile; + args = [ + "--config=${configFile}" + "--repo-dir=${instanceCfg.repoDir}" + "--ssh.authorized-keys=${authorizedKeysPath}" + "--ssh.host-key=${instanceCfg.hostKeyFile}" + ]; + in + "${instanceCfg.package}/bin/ugitd ${builtins.concatStringsSep " " args}"; + wantedBy = [ "multi-user.target" ]; + after = [ "network.target" ]; + path = [ + instanceCfg.package + pkgs.git + pkgs.bash + ]; + serviceConfig = { + User = instanceCfg.user; + Group = instanceCfg.group; + Restart = "always"; + RestartSec = "15"; + WorkingDirectory = instanceCfg.homeDir; + }; + }; + ugit-hooks = { + wantedBy = [ "multi-user.target" ]; + after = [ "ugit.service" ]; + requires = [ "ugit.service" ]; + serviceConfig = { + Type = "oneshot"; + ExecStart = + let + script = pkgs.writeShellScript "ugit-hooks-link" ( + builtins.concatStringsSep "\n" ( + map ( + hook: + let + script = pkgs.writeShellScript hook.name hook.content; + path = "${instanceCfg.repoDir}/hooks/pre-receive.d/${hook.name}"; + in + "ln -s ${script} ${path}" + ) instanceCfg.hooks + ) + ); + in + "${script}"; + }; }; - }; - ugit-hooks = { - wantedBy = [ "multi-user.target" ]; - after = [ "ugit.service" ]; - requires = [ "ugit.service" ]; - serviceConfig = { - Type = "oneshot"; - ExecStart = - let - script = pkgs.writeShellScript "ugit-hooks-link" ( - builtins.concatStringsSep "\n" ( - map ( - hook: - let - script = pkgs.writeShellScript hook.name hook.content; - path = "${cfg.repoDir}/hooks/pre-receive.d/${hook.name}"; - in - "ln -s ${script} ${path}" - ) cfg.hooks - ) - ); - in - "${script}"; - }; - }; - }; + } + ) (lib.filterAttrs (name: instanceCfg: instanceCfg.enable) cfg); systemd.tmpfiles.settings.ugit = builtins.listToAttrs ( map (