From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:49582) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dzHlL-0002d2-TW for guix-patches@gnu.org; Tue, 03 Oct 2017 03:37:10 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dzHlH-0007jI-2s for guix-patches@gnu.org; Tue, 03 Oct 2017 03:37:07 -0400 Received: from debbugs.gnu.org ([208.118.235.43]:36363) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1dzHlG-0007j1-SN for guix-patches@gnu.org; Tue, 03 Oct 2017 03:37:02 -0400 Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1dzHlG-0005uh-DE for guix-patches@gnu.org; Tue, 03 Oct 2017 03:37:02 -0400 Subject: [bug#28283] Status: [PATCH 1/1] gnu: services: version-control: Add cgit. Resent-Message-ID: From: Oleg Pykhalov References: <87h8wq2hxw.fsf@gmail.com> <87a82i2hur.fsf@gmail.com> <873787rh4a.fsf@gnu.org> <87d16mv0o3.fsf@gnu.org> <87efr19fms.fsf@gmail.com> <87ingasvfx.fsf@gnu.org> <87h8vuehv6.fsf@gmail.com> <87d16ibeif.fsf@gnu.org> <874lrlr46b.fsf@gmail.com> <871smmr0sb.fsf@gnu.org> <87wp4cbvjj.fsf@gmail.com> <87tvzgbv42.fsf@gmail.com> <87r2ukbse3.fsf@gmail.com> Date: Tue, 03 Oct 2017 10:36:35 +0300 In-Reply-To: <87r2ukbse3.fsf@gmail.com> (Oleg Pykhalov's message of "Tue, 03 Oct 2017 10:30:12 +0300") Message-ID: <87mv58bs3g.fsf@gmail.com> MIME-Version: 1.0 Content-Type: text/x-patch; charset=utf-8 Content-Disposition: inline; filename=0001-gnu-services-version-control-Add-cgit.patch Content-Transfer-Encoding: quoted-printable List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: guix-patches-bounces+kyle=kyleam.com@gnu.org Sender: "Guix-patches" To: Ludovic =?UTF-8?Q?Court=C3=A8s?= Cc: 28283@debbugs.gnu.org >From 984b619620046015113cc4876569f5c87dd37c79 Mon Sep 17 00:00:00 2001 From: Oleg Pykhalov Date: Thu, 28 Sep 2017 20:02:35 +0300 Subject: [PATCH] gnu: services: version-control: Add cgit. * gnu/services/version-control.scm (, ): New record types. (cgit-configuration-robots-string, cgit-activation, cgit-configuration-nginx-config): New procedures. (%cgit-configuration-nginx, cgit-service-type): New variables. * doc/guix.texi (Version Control): Document the cgit service. --- doc/guix.texi | 65 ++++++++++++++++ gnu/local.mk | 1 + gnu/services/version-control.scm | 119 ++++++++++++++++++++++++++++- gnu/tests/version-control.scm | 161 +++++++++++++++++++++++++++++++++++= ++++ 4 files changed, 345 insertions(+), 1 deletion(-) create mode 100644 gnu/tests/version-control.scm diff --git a/doc/guix.texi b/doc/guix.texi index c57c0bab6..f99257947 100644 --- a/doc/guix.texi +++ b/doc/guix.texi @@ -17000,6 +17000,71 @@ Extra options will be passed to @code{git daemon},= please run @end table @end deftp =20 +@subsubheading Cgit Service + +@cindex Cgit service +@cindex Git, web interface +@uref{https://git.zx2c4.com/cgit/, Cgit} is a web frontend for Git +repositories written in C. + +The following example will configure the service with default values. +By default, Cgit can be accessed on port 80 (@code{http://localhost:80}). + +@example +(service nginx-service-type) +(service fcgiwrap-service-type) +(service cgit-service-type) +@end example + +@deftp {Data Type} cgit-configuration +Data type representing the configuration of Cgit. +This type has the following parameters: + +@table @asis +@item @code{config-file} (default: @code{(cgit-configuration-file)}) +The configuration file to use for Cgit. This can be set to a +@dfn{cgit-configuration-file} record value, or any gexp +(@pxref{G-Expressions}). + +For example, to instead use a local file, the @code{local-file} function +can be used: + +@example +(service cgit-service-type + (cgit-configuration + (config-file (local-file "./my-cgitrc.conf")))) +@end example + +@item @code{package} (default: @code{cgit}) +The Cgit package to use. + +@end table +@end deftp + +@deftp {Data Type} cgit-configuration-file +Data type representing the configuration options for Cgit. +This type has the following parameters: + +@table @asis +@item @code{css} (default: @code{"/share/cgit/cgit.css"}) +URL which specifies the css document to include in all Cgit pages. + +@item @code{logo} (default: @code{"/share/cgit/cgit.png"}) +URL which specifies the source of an image which will be used as a logo +on all Cgit pages. + +@item @code{virtual-root} (default: @code{"/"}) +URL which, if specified, will be used as root for all Cgit links. + +@item @code{repository-directory} (default: @code{"/srv/git"}) +Name of the directory to scan for repositories. + +@item @code{robots} (default: @code{(list "noindex" "nofollow")}) +Text used as content for the ``robots'' meta-tag. + +@end table +@end deftp + @node Setuid Programs @subsection Setuid Programs =20 diff --git a/gnu/local.mk b/gnu/local.mk index edd6d8237..cceada5ae 100644 --- a/gnu/local.mk +++ b/gnu/local.mk @@ -501,6 +501,7 @@ GNU_SYSTEM_MODULES =3D \ %D%/tests/networking.scm \ %D%/tests/rsync.scm \ %D%/tests/ssh.scm \ + %D%/tests/version-control.scm \ %D%/tests/virtualization.scm \ %D%/tests/web.scm =20 diff --git a/gnu/services/version-control.scm b/gnu/services/version-contro= l.scm index 107bc8e77..e39f4411f 100644 --- a/gnu/services/version-control.scm +++ b/gnu/services/version-control.scm @@ -1,6 +1,7 @@ ;;; GNU Guix --- Functional package management for GNU ;;; Copyright =C2=A9 2016 ng0 ;;; Copyright =C2=A9 2016 Sou Bunnbu +;;; Copyright =C2=A9 2017 Oleg Pykhalov ;;; ;;; This file is part of GNU Guix. ;;; @@ -21,18 +22,40 @@ #: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) #:use-module (guix records) #:use-module (guix gexp) + #:use-module (guix store) #:use-module (srfi srfi-1) #:use-module (srfi srfi-26) #:use-module (ice-9 match) #:export (git-daemon-service git-daemon-service-type git-daemon-configuration - git-daemon-configuration?)) + git-daemon-configuration? + + + cgit-configuration-file + cgit-configuration-file? + cgit-configuration-file-css + cgit-configuration-file-logo + cgit-configuration-file-robots + cgit-configuration-file-virtual-root + cgit-configuration-file-repository-directory + + + cgit-configuration + cgit-configuration? + cgit-configuration-config-file + cgit-configuration-package + + %cgit-configuration-nginx + cgit-configuration-nginx-config + + cgit-service-type)) =20 ;;; Commentary: ;;; @@ -139,3 +162,97 @@ The optional @var{config} argument should be a @code{} object, by default it allows read-only access to exported repositories under @file{/srv/git}." (service git-daemon-service-type config)) + + +;;; +;;; Cgit +;;; + +(define-record-type* + cgit-configuration-file + make-cgit-configuration-file + cgit-configuration-file? + (css cgit-configuration-file-css ; str= ing + (default "/share/cgit/cgit.css")) + (logo cgit-configuration-file-logo ; str= ing + (default "/share/cgit/cgit.png")) + (robots cgit-configuration-file-robots ; list + (default '("noindex" "nofollow"))) + (virtual-root cgit-configuration-file-virtual-root ; str= ing + (default "/")) + (repository-directory cgit-configuration-file-repository-directory ; str= ing + (default "/srv/git"))) + +(define (cgit-configuration-robots-string robots) + (string-join robots ", ")) + +(define-gexp-compiler (cgit-configuration-file-compiler + (file ) system target) + (match file + (($ css logo + robots virtual-root repository-directory) + (apply text-file* "cgitrc" + (letrec-syntax ((option (syntax-rules () + ((_ key value) + (if value + `(,key "=3D" ,value "\n") + '())))) + (key/value (syntax-rules () + ((_ (key value) rest ...) + (append (option key value) + (key/value rest ...))) + ((_) + '())))) + (key/value ("css" css) + ("logo" logo) + ("robots" (cgit-configuration-robots-string robot= s)) + ("virtual-root" virtual-root) + ("scan-path" repository-directory))))))) + +(define %cgit-configuration-nginx + (list + (nginx-server-configuration + (root cgit) + (locations + (list + (nginx-location-configuration + (uri "@cgit") + (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")) + (https-port #f) + (ssl-certificate #f) + (ssl-certificate-key #f)))) + +(define-record-type* + cgit-configuration make-cgit-configuration + cgit-configuration? + (config-file cgit-configuration-config-file + (default (cgit-configuration-file))) + (package cgit-configuration-package + (default cgit)) + (nginx cgit-configuration-nginx + (default %cgit-configuration-nginx))) + +(define (cgit-activation config) + ;; Cgit compiled with default configuration path + #~(begin + (use-modules (guix build utils)) + (mkdir-p "/var/cache/cgit") + (copy-file #$(cgit-configuration-config-file config) "/etc/cgitrc"))) + +(define (cgit-configuration-nginx-config config) + (cgit-configuration-nginx config)) + +(define cgit-service-type + (service-type + (name 'cgit) + (extensions + (list (service-extension activation-service-type + cgit-activation) + (service-extension nginx-service-type + cgit-configuration-nginx-config))) + (default-value (cgit-configuration)))) diff --git a/gnu/tests/version-control.scm b/gnu/tests/version-control.scm new file mode 100644 index 000000000..11adb37f0 --- /dev/null +++ b/gnu/tests/version-control.scm @@ -0,0 +1,161 @@ +;;; GNU Guix --- Functional package management for GNU +;;; Copyright =C2=A9 2017 Oleg Pykhalov +;;; +;;; This file is part of GNU Guix. +;;; +;;; GNU Guix is free software; you can redistribute it and/or modify it +;;; under the terms of the GNU General Public License as published by +;;; the Free Software Foundation; either version 3 of the License, or (at +;;; your option) any later version. +;;; +;;; GNU Guix is distributed in the hope that it will be useful, but +;;; WITHOUT ANY WARRANTY; without even the implied warranty of +;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;;; GNU General Public License for more details. +;;; +;;; You should have received a copy of the GNU General Public License +;;; along with GNU Guix. If not, see . + +(define-module (gnu tests version-control) + #:use-module (gnu tests) + #:use-module (gnu system) + #:use-module (gnu system file-systems) + #:use-module (gnu system shadow) + #:use-module (gnu system vm) + #:use-module (gnu services) + #:use-module (gnu services version-control) + #:use-module (gnu services web) + #:use-module (gnu services networking) + #:use-module (gnu packages version-control) + #:use-module (guix gexp) + #:use-module (guix store) + #:export (%test-cgit)) + +(define %make-git-repository + ;; Create Git repository in /srv/git/test. + #~(begin + (mkdir-p "/srv/git/test") + (system* (string-append #$git "/bin/git") "-C" "/srv/git/test" "init= "))) + +(define %cgit-configuration-nginx + (list + (nginx-server-configuration + (root cgit) + (locations + (list + (nginx-location-configuration + (uri "@cgit") + (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")) + (http-port 19418) + (https-port #f) + (ssl-certificate #f) + (ssl-certificate-key #f)))) + +(define %cgit-os + ;; Operating system under test. + (let ((base-os + (simple-operating-system + (dhcp-client-service) + (service nginx-service-type) + (service fcgiwrap-service-type) + (service cgit-service-type + (cgit-configuration + (nginx %cgit-configuration-nginx))) + (simple-service 'make-git-repository activation-service-type + %make-git-repository)))) + (operating-system + (inherit base-os) + (packages (cons* git + (operating-system-packages base-os)))))) + +(define* (run-cgit-test #:optional (http-port 19418)) + "Run tests in %CGIT-OS, which has nginx running and listening on +HTTP-PORT." + (define os + (marionette-operating-system + %cgit-os + #:imported-modules '((gnu services herd) + (guix combinators)))) + + (define vm + (virtual-machine + (operating-system os) + (port-forwardings `((8080 . ,http-port))))) + + (define test + (with-imported-modules '((gnu build marionette)) + #~(begin + (use-modules (srfi srfi-11) (srfi srfi-64) + (gnu build marionette) + (web uri) + (web client) + (web response)) + + (define marionette + (make-marionette (list #$vm))) + + (mkdir #$output) + (chdir #$output) + + (test-begin "cgit") + + ;; Wait for nginx to be up and running. + (test-eq "service running" + 'running! + (marionette-eval + '(begin + (use-modules (gnu services herd)) + (start-service 'nginx) + 'running!) + marionette)) + + ;; Wait for fcgiwrap to be up and running. + (test-eq "service running" + 'running! + (marionette-eval + '(begin + (use-modules (gnu services herd)) + (start-service 'fcgiwrap) + 'running!) + marionette)) + + ;; Make sure the PID file is created. + (test-assert "PID file" + (marionette-eval + '(file-exists? "/var/run/nginx/pid") + marionette)) + + ;; Make sure the configuration file is created. + (test-assert "Configuration file" + (marionette-eval + '(file-exists? "/etc/cgitrc") + marionette)) + + ;; Make sure Git test repository is created. + (test-assert "Git test repository" + (marionette-eval + '(file-exists? "/srv/git/test/.git") + marionette)) + + ;; Retrieve the index.html file we put in /srv. + (test-equal "http-get" + 200 + (let-values (((response text) + (http-get "http://localhost:8080"))) + (response-code response))) + + (test-end) + (exit (=3D (test-runner-fail-count (test-runner-current)) 0))))) + + (gexp->derivation "cgit-test" test)) + +(define %test-cgit + (system-test + (name "cgit") + (description "Connect to a running CGIT server.") + (value (run-cgit-test)))) --=20 2.14.2