version-control.scm 12 KB

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