From 1255fb9aaaec91fbc53751ad21b4c35298839b20 Mon Sep 17 00:00:00 2001 From: David Thompson Date: Thu, 21 Sep 2023 21:24:22 -0400 Subject: takemi: Use "smart" Git HTTP protocol. This sucked to figure out. --- takemi-os.scm | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 56 insertions(+), 10 deletions(-) (limited to 'takemi-os.scm') diff --git a/takemi-os.scm b/takemi-os.scm index bd24040..21497a0 100644 --- a/takemi-os.scm +++ b/takemi-os.scm @@ -1,11 +1,19 @@ -(use-modules (gnu)) -(use-service-modules certbot cgit networking ssh version-control web) +(use-modules (gnu) + (gnu packages version-control) + (gnu services certbot) + (gnu services cgit) + (gnu services networking) + (gnu services ssh) + (gnu services version-control) + (gnu services web)) (define letsencrypt-cert "/etc/letsencrypt/live/dthompson.us/fullchain.pem") (define letsencrypt-cert-key "/etc/letsencrypt/live/dthompson.us/privkey.pem") (define dave-pub-key (local-file "keys/dave.pub")) +(define git-root "/var/lib/gitolite") +(define fcgiwrap-socket "127.0.0.1:9000") (define nginx-accounts (list (user-group (name "nginx") (system? #t)) @@ -155,7 +163,8 @@ (fcgiwrap-configuration ;; Use git group for read-only access to gitolite ;; repos. - (group "git"))) + (group "git") + (socket (string-append "tcp:" fcgiwrap-socket)))) (let ((cgit (specification->package "cgit"))) (service (service-type (inherit cgit-service-type) @@ -170,16 +179,23 @@ extension)) (service-type-extensions cgit-service-type)))) (cgit-configuration - (project-list "/var/lib/gitolite/projects.list") - (repository-directory "/var/lib/gitolite/repositories") - (root-desc "all i wanted was a pepsi") + (project-list (string-append git-root "/projects.list")) + (repository-directory (string-append git-root "/repositories")) + (root-desc "all i wanted was a pepsi") ; just one pepsi (enable-git-config? #t) + ;; Cgit only supports the old HTTP "dumb" + ;; protocol, which notably libgit2 won't even + ;; entertain supporting. So, we'll disable + ;; that and use Git itself to provide the HTTP + ;; "smart" protocol instead. + (enable-http-clone? #f) (enable-index-links? #t) (enable-index-owner? #f) (enable-commit-graph? #t) (enable-log-filecount? #t) (enable-log-linecount? #t) - (clone-url '("https://git.dthompson.us/$CGIT_REPO_URL")) + (remove-suffix? #t) + (clone-url '("https://git.dthompson.us/$CGIT_REPO_URL.git")) ;; Is there a way to avoid this wrapper script? (source-filter (program-file "cgit-syntax-highlight" @@ -193,14 +209,44 @@ (root cgit) (locations (list + ;; URI paths ending in .git are + ;; handled by Git's "smart" HTTP + ;; protocol. + (nginx-location-configuration + (uri "~ (/.*\\.git.*)") + (body + `(("fastcgi_pass " ,fcgiwrap-socket ";") + ("fastcgi_param SCRIPT_FILENAME " + ,git "/libexec/git-core/git-http-backend;") + "fastcgi_param QUERY_STRING $query_string;" + "fastcgi_param REQUEST_METHOD $request_method;" + "fastcgi_param CONTENT_TYPE $content_type;" + "fastcgi_param CONTENT_LENGTH $content_length;" + ("fastcgi_param GIT_PROJECT_ROOT " + ,git-root "/repositories;") + "fastcgi_param PATH_INFO $1;"))) + ;; Redirect old URLs to .git pages to + ;; the new .git-less URL. This + ;; doesn't handle deeper links but + ;; that's okay. + (nginx-location-configuration + (uri "~ (/.*)\\.git") + (body + `("return 301 $1;"))) + ;; Serve a static file if one exists, + ;; otherwise send the request to + ;; cgit. + (nginx-location-configuration + (uri "/") + (body + '("try_files $uri @cgit;"))) (nginx-location-configuration (uri "@cgit") - (body '("fastcgi_param SCRIPT_FILENAME $document_root/lib/cgit/cgit.cgi;" + (body `("fastcgi_param SCRIPT_FILENAME $document_root/lib/cgit/cgit.cgi;" "fastcgi_param PATH_INFO $uri;" "fastcgi_param QUERY_STRING $args;" "fastcgi_param HTTP_HOST $server_name;" - "fastcgi_pass 127.0.0.1:9000;"))))) - (try-files (list "$uri" "@cgit")) + ("fastcgi_pass " ,fcgiwrap-socket ";")))))) (ssl-certificate letsencrypt-cert) (ssl-certificate-key letsencrypt-cert-key)))))))) (map (lambda (s) -- cgit v1.2.3