about summary refs log tree commit diff
path: root/modules/services/gitolite/default.nix
diff options
context:
space:
mode:
Diffstat (limited to 'modules/services/gitolite/default.nix')
-rw-r--r--modules/services/gitolite/default.nix108
1 files changed, 108 insertions, 0 deletions
diff --git a/modules/services/gitolite/default.nix b/modules/services/gitolite/default.nix
new file mode 100644
index 0000000..c2eb975
--- /dev/null
+++ b/modules/services/gitolite/default.nix
@@ -0,0 +1,108 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+let
+  cfg = config.modules.services.gitolite;
+in
+{
+  options.modules.services.gitolite = {
+    enable = mkEnableOption "gitolite server";
+    adminPubkey = mkOption { type = types.str; };
+  };
+  config = mkIf cfg.enable {
+    services.openssh.enable = true;
+
+    services.gitolite = {
+      enable = true;
+      user = "git";
+      group = "git";
+      adminPubkey = cfg.adminPubkey;
+      extraGitoliteRc = ''
+        $RC{UMASK} = 0027;
+        $RC{GIT_CONFIG_KEYS} = '.*';
+        $RC{ROLES}{OWNERS} = 1;
+        $RC{OWNER_ROLENAME} = 'OWNERS';
+        # For some unknown reason, $ENV{HOME} doesn't get resolved to the correct
+        # directory.
+        # $RC{LOCAL_CODE} = '$ENV{HOME}/local';
+        $RC{LOCAL_CODE} = '/var/lib/gitolite/local';
+        push(@{$RC{ENABLE}}, 'D');
+        push(@{$RC{ENABLE}}, 'symbolic-ref');
+        push(@{$RC{ENABLE}}, 'rename');
+        push(@{$RC{POST_GIT}}, 'fix-refs');
+        # push(@{$RC{ENABLE}}, 'set-default-roles');
+        # push(@{$RC{ENABLE}}, 'create');
+        # push(@{$RC{ENABLE}}, 'fork');
+
+      '';
+    };
+
+    environment.persistence."/persist".directories = [
+      "/var/lib/gitolite"
+    ];
+
+    system.activationScripts.gitolite-create-local = ''
+      mkdir -p /var/lib/gitolite/local/triggers
+      mkdir -p /var/lib/gitolite/local/commands
+      chown -R git:git /var/lib/gitolite/local
+    '';
+
+    systemd.tmpfiles.rules = [
+      # https://groups.google.com/g/gitolite/c/NwZ1-hq9-9E/m/mDbiKyAvDwAJ
+      "C /var/lib/gitolite/local/triggers/fix-refs 755 - - - ${./fix-refs}"
+      "C /var/lib/gitolite/local/commands/rename 755 - - - ${./rename}"
+    ];
+
+
+    systemd.timers."gitolite-trash-cleanup" = {
+      wantedBy = [ "timers.target" ];
+      timerConfig = {
+        OnCalendar = "*-*-* 00:00:00";
+        Unit = "gitolite-trash-cleanup.service";
+      };
+    };
+
+    systemd.services."gitolite-trash-cleanup" = {
+      script = ''
+        set -euo pipefail
+        if [ ! -d "Trash" ] ; then
+          echo Trash directory is nonexistent!
+          echo No operations to perform. Exiting.
+          exit 0
+        fi
+
+        match=$(find Trash -type d -regextype posix-extended -regex ".*/[0-9]{4}-[0-9]{2}-[0-9]{2}_[0-9]{2}:[0-9]{2}:[0-9]{2}$")
+        processed_entry=0
+        removed_entry=0
+
+        for dir in $match
+        do
+          system_timestamp=$(date +%s)
+          trash_timestamp=$(basename $dir | sed -e "s/_/ /g" | date -f - +%s)
+          age=$(( $system_timestamp - $trash_timestamp ))
+          # Wipe trashes older than 2w
+          if [[ age -gt 1209600 ]] ; then
+            echo "Removing '$dir' (age $age)"
+            rm -rf $dir
+            ((removed_entry+=1))
+          fi
+          ((processed_entry+=1))
+        done
+
+        echo "Directories that needs cleanup:"
+        find Trash -type d -empty -print -delete
+        echo "Cleaned empty directories."
+
+        echo "Done! Removed $removed_entry/$processed_entry"
+      '';
+
+      path = with pkgs; [ bash util-linux coreutils ];
+
+      serviceConfig = {
+        Type = "oneshot";
+        User = "git";
+        WorkingDirectory = "/var/lib/gitolite/repositories";
+      };
+    };
+  };
+}