services: cgit, git-daemon: Add description and default value.
[guix.git] / gnu / services / version-control.scm
blobfce2ce1c25d8ba5980772769bd3c41e5610995cf
1 ;;; GNU Guix --- Functional package management for GNU
2 ;;; Copyright © 2016 ng0 <ng0@we.make.ritual.n0.is>
3 ;;; Copyright © 2016 Sou Bunnbu <iyzsong@member.fsf.org>
4 ;;; Copyright © 2017 Oleg Pykhalov <go.wigust@gmail.com>
5 ;;;
6 ;;; This file is part of GNU Guix.
7 ;;;
8 ;;; GNU Guix is free software; you can redistribute it and/or modify it
9 ;;; under the terms of the GNU General Public License as published by
10 ;;; the Free Software Foundation; either version 3 of the License, or (at
11 ;;; your option) any later version.
12 ;;;
13 ;;; GNU Guix is distributed in the hope that it will be useful, but
14 ;;; WITHOUT ANY WARRANTY; without even the implied warranty of
15 ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 ;;; GNU General Public License for more details.
17 ;;;
18 ;;; You should have received a copy of the GNU General Public License
19 ;;; along with GNU Guix.  If not, see <http://www.gnu.org/licenses/>.
21 (define-module (gnu services version-control)
22   #:use-module (gnu services)
23   #:use-module (gnu services base)
24   #:use-module (gnu services shepherd)
25   #:use-module (gnu services web)
26   #:use-module (gnu system shadow)
27   #:use-module (gnu packages version-control)
28   #:use-module (gnu packages admin)
29   #:use-module (guix records)
30   #:use-module (guix gexp)
31   #:use-module (guix store)
32   #:use-module (srfi srfi-1)
33   #:use-module (srfi srfi-26)
34   #:use-module (ice-9 match)
35   #:export (git-daemon-service
36             git-daemon-service-type
37             git-daemon-configuration
38             git-daemon-configuration?
40             <cgit-configuration-file>
41             cgit-configuration-file
42             cgit-configuration-file?
43             cgit-configuration-file-css
44             cgit-configuration-file-logo
45             cgit-configuration-file-robots
46             cgit-configuration-file-virtual-root
47             cgit-configuration-file-repository-directory
49             <cgit-configuration>
50             cgit-configuration
51             cgit-configuration?
52             cgit-configuration-config-file
53             cgit-configuration-package
55             %cgit-configuration-nginx
56             cgit-configuration-nginx-config
58             cgit-service-type
60             git-http-configuration
61             git-http-configuration?
62             git-http-nginx-location-configuration))
64 ;;; Commentary:
65 ;;;
66 ;;; Version Control related services.
67 ;;;
68 ;;; Code:
71 ;;;
72 ;;; Git daemon.
73 ;;;
75 (define-record-type* <git-daemon-configuration>
76   git-daemon-configuration
77   make-git-daemon-configuration
78   git-daemon-configuration?
79   (package          git-daemon-configuration-package        ;package
80                     (default git))
81   (export-all?      git-daemon-configuration-export-all     ;boolean
82                     (default #f))
83   (base-path        git-daemon-configuration-base-path      ;string | #f
84                     (default "/srv/git"))
85   (user-path        git-daemon-configuration-user-path      ;string | #f
86                     (default #f))
87   (listen           git-daemon-configuration-listen         ;list of string
88                     (default '()))
89   (port             git-daemon-configuration-port           ;number | #f
90                     (default #f))
91   (whitelist        git-daemon-configuration-whitelist      ;list of string
92                     (default '()))
93   (extra-options    git-daemon-configuration-extra-options  ;list of string
94                     (default '())))
96 (define git-daemon-shepherd-service
97   (match-lambda
98     (($ <git-daemon-configuration>
99         package export-all? base-path user-path
100         listen port whitelist extra-options)
101      (let* ((git     (file-append package "/bin/git"))
102             (command `(,git
103                        "daemon" "--syslog" "--reuseaddr"
104                        ,@(if export-all?
105                              '("--export-all")
106                              '())
107                        ,@(if base-path
108                              `(,(string-append "--base-path=" base-path))
109                              '())
110                        ,@(if user-path
111                              `(,(string-append "--user-path=" user-path))
112                              '())
113                        ,@(map (cut string-append "--listen=" <>) listen)
114                        ,@(if port
115                              `(,(string-append
116                                  "--port=" (number->string port)))
117                              '())
118                        ,@extra-options
119                        ,@whitelist)))
120        (list (shepherd-service
121               (documentation "Run the git-daemon.")
122               (requirement '(networking))
123               (provision '(git-daemon))
124               (start #~(make-forkexec-constructor '#$command
125                                                   #:user "git-daemon"
126                                                   #:group "git-daemon"))
127               (stop #~(make-kill-destructor))))))))
129 (define %git-daemon-accounts
130   ;; User account and group for git-daemon.
131   (list (user-group
132          (name "git-daemon")
133          (system? #t))
134         (user-account
135          (name "git-daemon")
136          (system? #t)
137          (group "git-daemon")
138          (comment "Git daemon user")
139          (home-directory "/var/empty")
140          (shell (file-append shadow "/sbin/nologin")))))
142 (define (git-daemon-activation config)
143   "Return the activation gexp for git-daemon using CONFIG."
144   (let ((base-path (git-daemon-configuration-base-path config)))
145     #~(begin
146         (use-modules (guix build utils))
147         ;; Create the 'base-path' directory when it's not '#f'.
148         (and=> #$base-path mkdir-p))))
150 (define git-daemon-service-type
151   (service-type
152    (name 'git-daemon)
153    (extensions
154     (list (service-extension shepherd-root-service-type
155                              git-daemon-shepherd-service)
156           (service-extension account-service-type
157                              (const %git-daemon-accounts))
158           (service-extension activation-service-type
159                              git-daemon-activation)))
160    (description
161     "Expose Git respositories over the insecure @code{git://} TCP-based
162 protocol.")
163    (default-value (git-daemon-configuration))))
165 (define* (git-daemon-service #:key (config (git-daemon-configuration)))
166   "Return a service that runs @command{git daemon}, a simple TCP server to
167 expose repositories over the Git protocol for annoymous access.
169 The optional @var{config} argument should be a
170 @code{<git-daemon-configuration>} object, by default it allows read-only
171 access to exported repositories under @file{/srv/git}."
172   (service git-daemon-service-type config))
176 ;;; Cgit
179 (define-record-type* <cgit-configuration-file>
180   cgit-configuration-file
181   make-cgit-configuration-file
182   cgit-configuration-file?
183   (css                  cgit-configuration-file-css                  ; string
184                         (default "/share/cgit/cgit.css"))
185   (logo                 cgit-configuration-file-logo                 ; string
186                         (default "/share/cgit/cgit.png"))
187   (robots               cgit-configuration-file-robots               ; list
188                         (default '("noindex" "nofollow")))
189   (virtual-root         cgit-configuration-file-virtual-root         ; string
190                         (default "/"))
191   (repository-directory cgit-configuration-file-repository-directory ; string
192                         (default "/srv/git")))
194 (define (cgit-configuration-robots-string robots)
195   (string-join robots ", "))
197 (define-gexp-compiler (cgit-configuration-file-compiler
198                        (file <cgit-configuration-file>) system target)
199   (match file
200     (($ <cgit-configuration-file> css logo
201                                   robots virtual-root repository-directory)
202      (apply text-file* "cgitrc"
203             (letrec-syntax ((option (syntax-rules ()
204                                       ((_ key value)
205                                        (if value
206                                            `(,key "=" ,value "\n")
207                                            '()))))
208                             (key/value (syntax-rules ()
209                                          ((_ (key value) rest ...)
210                                           (append (option key value)
211                                                   (key/value rest ...)))
212                                          ((_)
213                                           '()))))
214               (key/value ("css" css)
215                          ("logo" logo)
216                          ("robots" (cgit-configuration-robots-string robots))
217                          ("virtual-root" virtual-root)
218                          ("scan-path" repository-directory)))))))
220 (define %cgit-configuration-nginx
221   (list
222    (nginx-server-configuration
223     (root cgit)
224     (locations
225      (list
226       (nginx-location-configuration
227        (uri "@cgit")
228        (body '("fastcgi_param SCRIPT_FILENAME $document_root/lib/cgit/cgit.cgi;"
229                "fastcgi_param PATH_INFO $uri;"
230                "fastcgi_param QUERY_STRING $args;"
231                "fastcgi_param HTTP_HOST $server_name;"
232                "fastcgi_pass 127.0.0.1:9000;")))))
233     (try-files (list "$uri" "@cgit"))
234     (https-port #f)
235     (ssl-certificate #f)
236     (ssl-certificate-key #f))))
238 (define-record-type* <cgit-configuration>
239   cgit-configuration make-cgit-configuration
240   cgit-configuration?
241   (config-file cgit-configuration-config-file
242                (default (cgit-configuration-file)))
243   (package cgit-configuration-package
244            (default cgit))
245   (nginx cgit-configuration-nginx
246          (default %cgit-configuration-nginx)))
248 (define (cgit-activation config)
249   ;; Cgit compiled with default configuration path
250   #~(begin
251       (use-modules (guix build utils))
252       (mkdir-p "/var/cache/cgit")
253       (copy-file #$(cgit-configuration-config-file config) "/etc/cgitrc")))
255 (define (cgit-configuration-nginx-config config)
256   (cgit-configuration-nginx config))
258 (define cgit-service-type
259   (service-type
260    (name 'cgit)
261    (extensions
262     (list (service-extension activation-service-type
263                              cgit-activation)
264           (service-extension nginx-service-type
265                              cgit-configuration-nginx-config)))
266    (default-value (cgit-configuration))
267    (description
268     "Run the Cgit web interface, which allows users to browse Git
269 repositories.")))
273 ;;; HTTP access.  Add the result of calling
274 ;;; git-http-nginx-location-configuration to an nginx-server-configuration's
275 ;;; "locations" field.
278 (define-record-type* <git-http-configuration>
279   git-http-configuration
280   make-git-http-configuration
281   git-http-configuration?
282   (package          git-http-configuration-package        ;package
283                     (default git))
284   (git-root         git-http-configuration-git-root       ;string
285                     (default "/srv/git"))
286   (export-all?      git-http-configuration-export-all?    ;boolean
287                     (default #f))
288   (uri-path         git-http-configuration-uri-path       ;string
289                     (default "/git/"))
290   (fcgiwrap-socket  git-http-configuration-fcgiwrap-socket ;string
291                     (default "127.0.0.1:9000")))
293 (define* (git-http-nginx-location-configuration #:optional
294                                                 (config
295                                                  (git-http-configuration)))
296   (match config
297     (($ <git-http-configuration> package git-root export-all?
298                                  uri-path fcgiwrap-socket)
299      (nginx-location-configuration
300       (uri (string-append "~ /" (string-trim-both uri-path #\/) "(/.*)"))
301       (body
302        (list
303         (list "fastcgi_pass " fcgiwrap-socket ";")
304         (list "fastcgi_param SCRIPT_FILENAME "
305               package "/libexec/git-core/git-http-backend"
306               ";")
307         "fastcgi_param QUERY_STRING $query_string;"
308         "fastcgi_param REQUEST_METHOD $request_method;"
309         "fastcgi_param CONTENT_TYPE $content_type;"
310         "fastcgi_param CONTENT_LENGTH $content_length;"
311         (if export-all?
312             "fastcgi_param GIT_HTTP_EXPORT_ALL \"\";"
313             "")
314         (list "fastcgi_param GIT_PROJECT_ROOT " git-root ";")
315         "fastcgi_param PATH_INFO $1;"))))))