summaryrefslogtreecommitdiff
path: root/gnu/services/version-control.scm
diff options
context:
space:
mode:
authorChristopher Baines <mail@cbaines.net>2018-07-13 20:39:46 +0100
committerChristopher Baines <mail@cbaines.net>2018-10-02 08:11:17 +0100
commitf8e710684e5c3f866413dff825ba17bdffceac5d (patch)
tree5b8fd628c1df930945645729140ff18bd6ace5a9 /gnu/services/version-control.scm
parent6c6c03fa00db33703002fa8845716f50f649d201 (diff)
services: Add Gitolite.
* gnu/services/version-control.scm (<gitolite-configuration>, <gitolite-rc-file>): New record types. (gitolite-accounts, gitolite-activation): New procedures. (gitolite-service-type): New variables. * gnu/tests/version-control.scm (%gitolite-test-admin-keypair, %gitolite-os, %test-gitolite): New variables. (run-gitolite-test): New procedure. * doc/guix.texi (Version Control): Document the gitolite service.
Diffstat (limited to 'gnu/services/version-control.scm')
-rw-r--r--gnu/services/version-control.scm180
1 files changed, 179 insertions, 1 deletions
diff --git a/gnu/services/version-control.scm b/gnu/services/version-control.scm
index 58274c8beed..13669925ab0 100644
--- a/gnu/services/version-control.scm
+++ b/gnu/services/version-control.scm
@@ -3,6 +3,7 @@
3;;; Copyright © 2016 Sou Bunnbu <iyzsong@member.fsf.org> 3;;; Copyright © 2016 Sou Bunnbu <iyzsong@member.fsf.org>
4;;; Copyright © 2017 Oleg Pykhalov <go.wigust@gmail.com> 4;;; Copyright © 2017 Oleg Pykhalov <go.wigust@gmail.com>
5;;; Copyright © 2017 Clément Lassieur <clement@lassieur.org> 5;;; Copyright © 2017 Clément Lassieur <clement@lassieur.org>
6;;; Copyright © 2018 Christopher Baines <mail@cbaines.net>
6;;; 7;;;
7;;; This file is part of GNU Guix. 8;;; This file is part of GNU Guix.
8;;; 9;;;
@@ -32,6 +33,7 @@
32 #:use-module (guix store) 33 #:use-module (guix store)
33 #:use-module (srfi srfi-1) 34 #:use-module (srfi srfi-1)
34 #:use-module (srfi srfi-26) 35 #:use-module (srfi srfi-26)
36 #:use-module (ice-9 format)
35 #:use-module (ice-9 match) 37 #:use-module (ice-9 match)
36 #:export (git-daemon-service 38 #:export (git-daemon-service
37 git-daemon-service-type 39 git-daemon-service-type
@@ -40,7 +42,23 @@
40 42
41 git-http-configuration 43 git-http-configuration
42 git-http-configuration? 44 git-http-configuration?
43 git-http-nginx-location-configuration)) 45 git-http-nginx-location-configuration
46
47 <gitolite-configuration>
48 gitolite-configuration
49 gitolite-configuration-package
50 gitolite-configuration-user
51 gitolite-configuration-rc-file
52 gitolite-configuration-admin-pubkey
53
54 <gitolite-rc-file>
55 gitolite-rc-file
56 gitolite-rc-file-umask
57 gitolite-rc-file-git-config-keys
58 gitolite-rc-file-roles
59 gitolite-rc-file-enable
60
61 gitolite-service-type))
44 62
45;;; Commentary: 63;;; Commentary:
46;;; 64;;;
@@ -197,3 +215,163 @@ access to exported repositories under @file{/srv/git}."
197 "") 215 "")
198 (list "fastcgi_param GIT_PROJECT_ROOT " git-root ";") 216 (list "fastcgi_param GIT_PROJECT_ROOT " git-root ";")
199 "fastcgi_param PATH_INFO $1;")))))) 217 "fastcgi_param PATH_INFO $1;"))))))
218
219
220;;;
221;;; Gitolite
222;;;
223
224(define-record-type* <gitolite-rc-file>
225 gitolite-rc-file make-gitolite-rc-file
226 gitolite-rc-file?
227 (umask gitolite-rc-file-umask
228 (default #o0077))
229 (git-config-keys gitolite-rc-file-git-config-keys
230 (default ""))
231 (roles gitolite-rc-file-roles
232 (default '(("READERS" . 1)
233 ("WRITERS" . 1))))
234 (enable gitolite-rc-file-enable
235 (default '("help"
236 "desc"
237 "info"
238 "perms"
239 "writable"
240 "ssh-authkeys"
241 "git-config"
242 "daemon"
243 "gitweb"))))
244
245(define-gexp-compiler (gitolite-rc-file-compiler
246 (file <gitolite-rc-file>) system target)
247 (match file
248 (($ <gitolite-rc-file> umask git-config-keys roles enable)
249 (apply text-file* "gitolite.rc"
250 `("%RC = (\n"
251 " UMASK => " ,(format #f "~4,'0o" umask) ",\n"
252 " GIT_CONFIG_KEYS => '" ,git-config-keys "',\n"
253 " ROLES => {\n"
254 ,@(map (match-lambda
255 ((role . value)
256 (simple-format #f " ~A => ~A,\n" role value)))
257 roles)
258 " },\n"
259 "\n"
260 " ENABLE => [\n"
261 ,@(map (lambda (value)
262 (simple-format #f " '~A',\n" value))
263 enable)
264 " ],\n"
265 ");\n"
266 "\n"
267 "1;\n")))))
268
269(define-record-type* <gitolite-configuration>
270 gitolite-configuration make-gitolite-configuration
271 gitolite-configuration?
272 (package gitolite-configuration-package
273 (default gitolite))
274 (user gitolite-configuration-user
275 (default "git"))
276 (group gitolite-configuration-group
277 (default "git"))
278 (home-directory gitolite-configuration-home-directory
279 (default "/var/lib/gitolite"))
280 (rc-file gitolite-configuration-rc-file
281 (default (gitolite-rc-file)))
282 (admin-pubkey gitolite-configuration-admin-pubkey))
283
284(define gitolite-accounts
285 (match-lambda
286 (($ <gitolite-configuration> package user group home-directory
287 rc-file admin-pubkey)
288 ;; User group and account to run Gitolite.
289 (list (user-group (name user) (system? #t))
290 (user-account
291 (name user)
292 (group group)
293 (system? #t)
294 (comment "Gitolite user")
295 (home-directory home-directory))))))
296
297(define gitolite-activation
298 (match-lambda
299 (($ <gitolite-configuration> package user group home
300 rc-file admin-pubkey)
301 #~(begin
302 (use-modules (ice-9 match)
303 (guix build utils))
304
305 (let* ((user-info (getpwnam #$user))
306 (admin-pubkey #$admin-pubkey)
307 (pubkey-file (string-append
308 #$home "/"
309 (basename
310 (strip-store-file-name admin-pubkey)))))
311
312 (simple-format #t "guix: gitolite: installing ~A\n" #$rc-file)
313 (copy-file #$rc-file #$(string-append home "/.gitolite.rc"))
314
315 ;; The key must be writable, so copy it from the store
316 (copy-file admin-pubkey pubkey-file)
317
318 (chmod pubkey-file #o500)
319 (chown pubkey-file
320 (passwd:uid user-info)
321 (passwd:gid user-info))
322
323 ;; Set the git configuration, to avoid gitolite trying to use
324 ;; the hostname command, as the network might not be up yet
325 (with-output-to-file #$(string-append home "/.gitconfig")
326 (lambda ()
327 (display "[user]
328 name = GNU Guix
329 email = guix@localhost
330")))
331 ;; Run Gitolite setup, as this updates the hooks and include the
332 ;; admin pubkey if specified. The admin pubkey is required for
333 ;; initial setup, and will replace the previous key if run after
334 ;; initial setup
335 (match (primitive-fork)
336 (0
337 ;; Exit with a non-zero status code if an exception is thrown.
338 (dynamic-wind
339 (const #t)
340 (lambda ()
341 (setenv "HOME" (passwd:dir user-info))
342 (setenv "USER" #$user)
343 (setgid (passwd:gid user-info))
344 (setuid (passwd:uid user-info))
345 (primitive-exit
346 (system* #$(file-append package "/bin/gitolite")
347 "setup"
348 "-m" "gitolite setup by GNU Guix"
349 "-pk" pubkey-file)))
350 (lambda ()
351 (primitive-exit 1))))
352 (pid (waitpid pid)))
353
354 (when (file-exists? pubkey-file)
355 (delete-file pubkey-file)))))))
356
357(define gitolite-service-type
358 (service-type
359 (name 'gitolite)
360 (extensions
361 (list (service-extension activation-service-type
362 gitolite-activation)
363 (service-extension account-service-type
364 gitolite-accounts)
365 (service-extension profile-service-type
366 ;; The Gitolite package in Guix uses
367 ;; gitolite-shell in the authorized_keys file, so
368 ;; gitolite-shell needs to be on the PATH for
369 ;; gitolite to work.
370 (lambda (config)
371 (list
372 (gitolite-configuration-package config))))))
373 (description
374 "Setup @command{gitolite}, a Git hosting tool providing access over SSH..
375By default, the @code{git} user is used, but this is configurable.
376Additionally, Gitolite can integrate with with tools like gitweb or cgit to
377provide a web interface to view selected repositories.")))