guix-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

04/04: gnu: Add Git HTTP(S) service support.


From: Andy Wingo
Subject: 04/04: gnu: Add Git HTTP(S) service support.
Date: Thu, 27 Apr 2017 09:25:14 -0400 (EDT)

wingo pushed a commit to branch wip-git-https
in repository guix.

commit 04f21ffc1c35da6cb2ca902d470d4ad63a25f744
Author: Andy Wingo <address@hidden>
Date:   Thu Apr 27 15:02:19 2017 +0200

    gnu: Add Git HTTP(S) service support.
    
    * doc/guix.texi (Version Control Services): Add documentation on the HTTP
    backend for git.
    * gnu/services/version-control.scm (<git-http-configuration>): New data 
type.
    (git-http-nginx-location-configuration): New helper function.
---
 doc/guix.texi                    | 80 +++++++++++++++++++++++++++++++++++++++-
 gnu/services/version-control.scm | 55 ++++++++++++++++++++++++++-
 2 files changed, 133 insertions(+), 2 deletions(-)

diff --git a/doc/guix.texi b/doc/guix.texi
index cae497d..8523584 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -14645,7 +14645,11 @@ Defaults to @samp{#f}.
 @subsubsection Version Control Services
 
 The @code{(gnu services version-control)} module provides a service to
-allow remote access to local Git repositories.
+allow remote access to local Git repositories.  There are two options:
+the @code{git-daemon-service}, which provides access to repositories via
+the @code{git://} unsecured TCP-based protocol, or extending the
address@hidden web server to proxy some requests to
address@hidden
 
 @deffn {Scheme Procedure} git-daemon-service [#:config 
(git-daemon-configuration)]
 
@@ -14702,6 +14706,80 @@ Extra options will be passed to @code{git daemon}, 
please run
 @end table
 @end deftp
 
+The @code{git://} protocol lacks authentication.  When you pull from a
+repository fetched via @code{git://}, you don't know that the data you
+receive was modified in transit or not.  It's better to use an
+authenticated transport, such as @code{https}.  Although Git allows you
+to serve repositories using unsophisticated file-based web servers,
+there is a faster protocol implemented by the @code{git-http-backend}
+program.  This program is the back-end of a proper Git web service.  It
+is designed to sit behind a FastCGI proxy.  @xref{Web Services}, for more
+on running the necessary @code{fcgiwrap} daemon.
+
+Guix has a separate configuration data type for serving Git repositories
+over HTTP.
+
address@hidden {Data Type} git-http-configuration
+Data type representing the configuration for @code{git-http-service}.
+
address@hidden @asis
address@hidden @code{package} (default: @var{git})
+Package object of the Git distributed version control system.
+
address@hidden @code{git-root} (default: @file{/srv/git})
+Directory containing the Git repositories to expose to the world.
+
address@hidden @code{export-all?} (default: @var{#f})
+Whether to expose access for all Git repositories in @var{git-root},
+even if they do not have the @file{git-daemon-export-ok} file.
+
address@hidden @code{uri-path} (default: @file{/git/})
+Path prefix for Git access.  With the default @code{/git/} prefix, this
+will map @code{http://@var{server}/git/@var{repo}.git} to
address@hidden/srv/git/@var{repo}.git}.  Requests whose URI paths do not begin
+with this prefix are not passed on to this Git instance.
+
address@hidden @code{fcgiwrap-socket} (default: @code{127.0.0.1:9000})
+The socket on which the @code{fcgiwrap} daemon is listening.  @xref{Web
+Services}.
address@hidden table
address@hidden deftp
+
+There is no @code{git-http-service-type}, currently; instead you can
+create an @code{nginx-location-configuration} from a
address@hidden and then add that location to a web
+server.
+
address@hidden {Scheme Procedure} git-http-nginx-location-configuration @
+       [config=(git-http-configuration)] Compute an
address@hidden the corresponds with the given Git
+http configuration.  An example nginx service definition to serve the
+default @file{/srv/git} over HTTPS might be:
+
address@hidden
+(service nginx-service-type
+         (nginx-configuration
+          (server-blocks
+           (list
+            (nginx-server-configuration
+             (http-port #f)
+             (server-name "git.my-host.org")
+             (ssl-certificate
+              "/etc/letsencrypt/live/git.my-host.org/fullchain.pem")
+             (ssl-certificate-key
+              "/etc/letsencrypt/live/git.my-host.org/privkey.pem")
+             (locations
+              (list
+               (git-http-nginx-location-configuration
+                (git-http-configuration (uri-path "/"))))))))))
address@hidden example
+
+This example assumes that you are using Let's Encrypt to get your TLS
+certificate.  @xref{Certificate Services}.  The default @code{certbot}
+service will redirect all HTTP traffic on @code{git.my-host.org} to
+HTTPS.  You will also need to add an @code{fcgiwrap} proxy to your
+system services.  @xref{Web Services}.
address@hidden deffn
 
 @node Miscellaneous Services
 @subsubsection Miscellaneous Services
diff --git a/gnu/services/version-control.scm b/gnu/services/version-control.scm
index 107bc8e..900098e 100644
--- a/gnu/services/version-control.scm
+++ b/gnu/services/version-control.scm
@@ -21,6 +21,7 @@
   #:use-module (gnu services)
   #:use-module (gnu services base)
   #:use-module (gnu services shepherd)
+  #:use-module (gnu services web)
   #:use-module (gnu system shadow)
   #:use-module (gnu packages version-control)
   #:use-module (gnu packages admin)
@@ -32,7 +33,11 @@
   #:export (git-daemon-service
             git-daemon-service-type
             git-daemon-configuration
-            git-daemon-configuration?))
+            git-daemon-configuration?
+
+            git-http-configuration
+            git-http-configuration?
+            git-http-nginx-location-configuration))
 
 ;;; Commentary:
 ;;;
@@ -139,3 +144,51 @@ The optional @var{config} argument should be a
 @code{<git-daemon-configuration>} object, by default it allows read-only
 access to exported repositories under @file{/srv/git}."
   (service git-daemon-service-type config))
+
+
+
+;;;
+;;; HTTP access.  Add the result of calling
+;;; git-http-nginx-location-configuration to an nginx-server-configuration's
+;;; "locations" field.
+;;;
+
+(define-record-type* <git-http-configuration>
+  git-http-configuration
+  make-git-http-configuration
+  git-http-configuration?
+  (package          git-http-configuration-package        ;package
+                    (default git))
+  (git-root         git-http-configuration-git-root       ;string
+                    (default "/srv/git"))
+  (export-all?      git-http-configuration-export-all?    ;boolean
+                    (default #f))
+  (uri-path         git-http-configuration-uri-path       ;string
+                    (default "/git/"))
+  (fcgiwrap-socket  git-http-configuration-fcgiwrap-socket ;string
+                    (default "127.0.0.1:9000")))
+
+(define* (git-http-nginx-location-configuration #:optional
+                                                (config
+                                                 (git-http-configuration)))
+  (match config
+    (($ <git-http-configuration> package git-root export-all?
+                                 uri-path fcgiwrap-socket)
+     (nginx-location-configuration
+      (uri (string-append "~ /" (string-trim-both uri-path #\/) "(/.*)"))
+      (body
+       (list
+        (string-append "fastcgi_pass " fcgiwrap-socket ";")
+        (string-append "fastcgi_param SCRIPT_FILENAME "
+                       (file-append package
+                                    "/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;"
+        (if export-all?
+            "fastcgi_param GIT_HTTP_EXPORT_ALL \"\";"
+            "")
+        (string-append "fastcgi_param GIT_PROJECT_ROOT " git-root ";")
+        "fastcgi_param PATH_INFO $1;"))))))



reply via email to

[Prev in Thread] Current Thread [Next in Thread]