From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mp1 ([2001:41d0:8:6d80::]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) by ms0.migadu.com with LMTPS id QNpfJty2JmGe8AAAgWs5BA (envelope-from ) for ; Wed, 25 Aug 2021 23:32:12 +0200 Received: from aspmx1.migadu.com ([2001:41d0:8:6d80::]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) by mp1 with LMTPS id gRDuIdy2JmFGAwAAbx9fmQ (envelope-from ) for ; Wed, 25 Aug 2021 21:32:12 +0000 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by aspmx1.migadu.com (Postfix) with ESMTPS id 8956A2F0C3 for ; Wed, 25 Aug 2021 23:32:11 +0200 (CEST) Received: from localhost ([::1]:50908 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1mJ0VG-0005AL-6A for larch@yhetil.org; Wed, 25 Aug 2021 17:32:10 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:38218) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mJ0VA-0005A3-1h for guix-patches@gnu.org; Wed, 25 Aug 2021 17:32:04 -0400 Received: from debbugs.gnu.org ([209.51.188.43]:36424) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1mJ0V8-00070M-VQ for guix-patches@gnu.org; Wed, 25 Aug 2021 17:32:03 -0400 Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1mJ0V8-0001gW-Gx for guix-patches@gnu.org; Wed, 25 Aug 2021 17:32:02 -0400 X-Loop: help-debbugs@gnu.org Subject: [bug#49886] [PATCH v2] Add gitile and gitile service Resent-From: Julien Lepiller Original-Sender: "Debbugs-submit" Resent-CC: guix-patches@gnu.org Resent-Date: Wed, 25 Aug 2021 21:32:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 49886 X-GNU-PR-Package: guix-patches X-GNU-PR-Keywords: patch To: Ludovic =?UTF-8?Q?Court=C3=A8s?= Cc: 49886@debbugs.gnu.org Received: via spool by 49886-submit@debbugs.gnu.org id=B49886.16299271206468 (code B ref 49886); Wed, 25 Aug 2021 21:32:02 +0000 Received: (at 49886) by debbugs.gnu.org; 25 Aug 2021 21:32:00 +0000 Received: from localhost ([127.0.0.1]:47970 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1mJ0Ux-0001g7-Pq for submit@debbugs.gnu.org; Wed, 25 Aug 2021 17:32:00 -0400 Received: from lepiller.eu ([89.234.186.109]:56088) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1mJ0Ur-0001fs-BE for 49886@debbugs.gnu.org; Wed, 25 Aug 2021 17:31:50 -0400 Received: from lepiller.eu (localhost [127.0.0.1]) by lepiller.eu (OpenSMTPD) with ESMTP id 1d9e604a; Wed, 25 Aug 2021 21:31:42 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed; d=lepiller.eu; h=date:from :to:cc:subject:message-id:in-reply-to:references:mime-version :content-type; s=dkim; bh=VZ1SZtfQB8OyvngUB02GnmkPeixH2R5GVc3usO pWTdE=; b=fJoQhPoR8Sv28XUGH0cMskW8U0pZ7ifYq5/8FQuj3CuHI5fFcSghv6 OC9uBbR5BSAwg2BJpmxwUcgtd6fg0LSQsG8D8l8iw63fLYjFlB2vVCHyg6Lt6FRi SoSrFSuZeRlIMccIRwAWw3s58y9cNjdiHga5cb1bismDVN+/eCCTIx33GVnvmWea mg7oSgm0VPLCktID3lPvYKZ47OUc34pyu8OoBgF4P2MqPtoZjP6yMnjlts48NMrC bQBnS54JfjGSyDphoJXO3bkv7MSbf+4FHSABPFua5GIk6wP1h0uHXKEONoG+6YWI 2G2Q4rtxIb5g+1eNsvocKJ+xgAUXJiRQ== Received: by lepiller.eu (OpenSMTPD) with ESMTPSA id 18c5a835 (TLSv1.3:AEAD-AES256-GCM-SHA384:256:NO); Wed, 25 Aug 2021 21:31:42 +0000 (UTC) Date: Wed, 25 Aug 2021 23:31:36 +0200 From: Julien Lepiller Message-ID: <20210825233136.450d778b@tachikoma.lepiller.eu> In-Reply-To: <87lf59shyi.fsf@gnu.org> References: <20210805035159.3959e01e@tachikoma.lepiller.eu> <87lf59shyi.fsf@gnu.org> X-Mailer: Claws Mail 3.18.0 (GTK+ 2.24.32; x86_64-pc-linux-gnu) MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="MP_/WGaDyAVP._GKgThuzA.bXh4" X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-BeenThere: guix-patches@gnu.org List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: guix-patches-bounces+larch=yhetil.org@gnu.org Sender: "Guix-patches" X-Migadu-Flow: FLOW_IN ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=yhetil.org; s=key1; t=1629927132; h=from:from:sender:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type:resent-cc:resent-from:resent-sender: resent-message-id:in-reply-to:in-reply-to:references:references: list-id:list-help:list-unsubscribe:list-subscribe:list-post: dkim-signature; bh=/dh6UQWh8kNpFU/5pcqjp1mNcuRapdp2jUaLlZU5vMs=; b=mYe0fpzWWRgodtyKYK9KWFBJc1BPKD+VJ9dltTKoANS1572wp7+YJpsQIA02lf3f/+Ronm f5bTo7X6Qza8xtkvuLxpi/Lu9nElMojTB3EiA/ZlZxxkYYpumpS7DIjV/rz+V8pid2v9bj WrPuxnqGKboNtMCQXXD4F5YW4541CqLRrK8B8BVo8I1FEQXe7PmVgpgo4iMdU/zoVKoG0P gNMlSolL2E3s/9f3Drwecl4Ybj2P8LwXw6kvqMS2onXyQMnOwp0p+xIJwmrhJPGT9LeyJP fzhr6VM1W0Zi68ZsRz21xMSxG7LxpBa8WhSK/+rUw3I0BgcWQEdDTgsMcyXCGw== ARC-Seal: i=1; s=key1; d=yhetil.org; t=1629927132; a=rsa-sha256; cv=none; b=iwFjsxHlTPNYcq/ZoUpZYr7vgO0hwGIfTAHMXHNO03wmGpjYtBZzOeydl6PSWrTxAtQcKn Ebzv+kUykrBJ8dpJl/l8OGc3EYZO13WJpbxf8EV3Xds4XdWYIfo57k4BDZlVEQ9/I0dXgC 9ElWilvPsy5uU8ZdYeVnk+mBN3HO2w1y9vjKH8g7SmQl1V3MN4ms6CnKaGv+CGMSMVlAfO 1RKHNGfZ8s1Sn79oyfnZ5kHgNn1JUQLXz1k6TFiI4npLDCEk8s92kumctcsKcroExz4bRO VCsijChxCV/0AUfUnZ7iBSC8zjiI3nIJXgPdZTvauCneprYeR2K6AfVomf0GlA== ARC-Authentication-Results: i=1; aspmx1.migadu.com; dkim=fail ("headers rsa verify failed") header.d=lepiller.eu header.s=dkim header.b=fJoQhPoR; dmarc=fail reason="SPF not aligned (relaxed)" header.from=lepiller.eu (policy=none); spf=pass (aspmx1.migadu.com: domain of guix-patches-bounces@gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=guix-patches-bounces@gnu.org X-Migadu-Spam-Score: -1.33 Authentication-Results: aspmx1.migadu.com; dkim=fail ("headers rsa verify failed") header.d=lepiller.eu header.s=dkim header.b=fJoQhPoR; dmarc=fail reason="SPF not aligned (relaxed)" header.from=lepiller.eu (policy=none); spf=pass (aspmx1.migadu.com: domain of guix-patches-bounces@gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=guix-patches-bounces@gnu.org X-Migadu-Queue-Id: 8956A2F0C3 X-Spam-Score: -1.33 X-Migadu-Scanner: scn0.migadu.com X-TUID: gaSqaV00uXy+ --MP_/WGaDyAVP._GKgThuzA.bXh4 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit Content-Disposition: inline Thanks for the feedback! attached is a v2 of the series. I added a small change to gitolite that allows changing UNSAFE_PATT (a regex that matches configuration values that contain unsafe characters). I wanted to link to it and to the nginx configuration sections in the manual, but I don't know how to create that link? I see the @subsubheading NGINX for instance, but I can't @ref{NGINX}. I had to update gitile for the tests to pass and had a few false starts, but now the tests pass and gitile is working even better than before :) --MP_/WGaDyAVP._GKgThuzA.bXh4 Content-Type: text/x-patch Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename=0001-gnu-Add-gitile.patch =46rom d43a77241defdea7848ab4596b427c33675f050e Mon Sep 17 00:00:00 2001 From: Julien Lepiller Date: Thu, 5 Aug 2021 02:57:32 +0200 Subject: [PATCH 1/3] gnu: Add gitile. * gnu/packages/version-control.scm (gitile): New variable. --- gnu/packages/version-control.scm | 109 +++++++++++++++++++++++++++++++ 1 file changed, 109 insertions(+) diff --git a/gnu/packages/version-control.scm b/gnu/packages/version-contro= l.scm index ac61b97f59..c378ff5bca 100644 --- a/gnu/packages/version-control.scm +++ b/gnu/packages/version-control.scm @@ -39,6 +39,7 @@ ;;; Copyright =C2=A9 2021 LibreMiami ;;; Copyright =C2=A9 2021 Xinglu Chen ;;; Copyright =C2=A9 2021 Fran=C3=A7ois J. +;;; Copyright =C2=A9 2021 Julien Lepiller ;;; ;;; This file is part of GNU Guix. ;;; @@ -93,6 +94,7 @@ #:use-module (gnu packages golang) #:use-module (gnu packages groff) #:use-module (gnu packages guile) + #:use-module (gnu packages guile-xyz) #:use-module (gnu packages image) #:use-module (gnu packages linux) #:use-module (gnu packages mail) @@ -114,6 +116,7 @@ #:use-module (gnu packages readline) #:use-module (gnu packages rsync) #:use-module (gnu packages sqlite) + #:use-module (gnu packages texinfo) #:use-module (gnu packages admin) #:use-module (gnu packages xml) #:use-module (gnu packages emacs) @@ -1517,6 +1520,112 @@ also walk each side of a merge and test those chang= es individually.") control to Git repositories.") (license license:gpl2))) =20 +;; gitile requires a more recent version than the latest release. +(define guile-syntax-highlight-for-gitile + (let ((commit "897fa5156ff41588e0d281eb00e4e94de63ccd8a") + (revision "0")) + (package + (inherit guile-syntax-highlight) + (version (git-version "0.1" revision commit)) + (source (origin + (method git-fetch) + (uri (git-reference + (url "https://git.dthompson.us/guile-syntax-highlig= ht.git") + (commit commit))) + (file-name (git-file-name "guile-syntax-highlight" version= )) + (sha256 + (base32 + "18zlg4mkgd3swgv2ggfz91ivnnzc0zhvc9ybgrxg1y762va9hyvj"))= )) + (native-inputs + `(("autoconf" ,autoconf) + ("automake" ,automake) + ("texinfo" ,texinfo) + ,@(package-native-inputs guile-syntax-highlight)))))) + +(define-public gitile + (package + (name "gitile") + (version "0.1.3") + (source + (origin + (method git-fetch) + (uri (git-reference + (url "https://git.lepiller.eu/git/gitile") + (commit version))) + (file-name (git-file-name name version)) + (sha256 + (base32 "1fnmgrrsdc24mvicj2gkv3vasag7h5x27xc12w55i0id9vw7k9sw")))) + (build-system gnu-build-system) + (arguments + `(#:modules ((guix build utils) + (guix build gnu-build-system) + (ice-9 rdelim) + (ice-9 popen)) + #:make-flags (list "GUILE_AUTO_COMPILE=3D0") + #:phases + (modify-phases %standard-phases + (add-after 'install 'install-assets + (lambda* (#:key outputs #:allow-other-keys) + (let ((assets (string-append (assoc-ref outputs "out") + "/share/gitile/assets"))) + (mkdir-p assets) + (copy-recursively "assets" assets)))) + (add-after 'install 'install-bin + (lambda* (#:key outputs #:allow-other-keys) + (install-file "scripts/gitile" + (string-append (assoc-ref outputs "out") + "/bin")))) + (add-after 'install-bin 'wrap-program + (lambda* (#:key inputs outputs #:allow-other-keys) + ;; Wrap the 'cuirass' command to refer to the right modules. + (let* ((out (assoc-ref outputs "out")) + (commonmark (assoc-ref inputs "guile-commonmark")) + (git (assoc-ref inputs "guile-git")) + (bytes (assoc-ref inputs "guile-bytestructures")) + (fibers (assoc-ref inputs "guile-fibers")) + (gcrypt (assoc-ref inputs "guile-gcrypt")) + (syntax-highlight (assoc-ref inputs "guile-syntax-high= light")) + (deps (list out commonmark git bytes fibers gcrypt + syntax-highlight)) + (guile (assoc-ref inputs "guile")) + (effective (read-line + (open-pipe* OPEN_READ + (string-append guile "/bin/gui= le") + "-c" "(display (effective-vers= ion))"))) + (mods (string-drop-right ;drop trailing colon + (string-join deps + (string-append "/share/guile/sit= e/" + effective ":") + 'suffix) + 1)) + (objs (string-drop-right + (string-join deps + (string-append "/lib/guile/" eff= ective + "/site-ccache:") + 'suffix) + 1))) + (wrap-program (string-append out "/bin/gitile") + `("GUILE_LOAD_PATH" ":" prefix (,mods)) + `("GUILE_LOAD_COMPILED_PATH" ":" prefix (,objs))))))))) + (native-inputs + `(("autoconf" ,autoconf) + ("automake" ,automake) + ("guile" ,guile-3.0) + ("pkg-config" ,pkg-config))) + (inputs + `(("guile" ,guile-3.0) + ("guile-commonmark" ,guile-commonmark) + ("guile-fibers" ,guile-fibers) + ("guile-gcrypt" ,guile-gcrypt) + ("guile-git" ,guile-git) + ("guile-syntax-highlight" ,guile-syntax-highlight-for-gitile) + ("gnutls" ,gnutls))) + (home-page "https://git.lepiller.eu/gitile") + (synopsis "Simple Git forge written in Guile") + (description "Gitile is a Git forge written in Guile that lets you +visualize your public Git repositories on a web interface.") + (license license:agpl3+))) + (define-public pre-commit (package (name "pre-commit") --=20 2.32.0 --MP_/WGaDyAVP._GKgThuzA.bXh4 Content-Type: text/x-patch Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename=0002-gnu-gitolite-Add-unsafe-patt-configuration-option.patch >From 2652e5515c84505c63072309f3b3e7837649cdb9 Mon Sep 17 00:00:00 2001 From: Julien Lepiller Date: Wed, 25 Aug 2021 03:00:44 +0200 Subject: [PATCH 2/3] gnu: gitolite: Add unsafe-patt configuration option. * gnu/services/version-control.scm (gitolite-rc-file): Add unsafe-patt field. (gitolite-rc-file-compiler): Write it. * doc/guix.texi (Version Control Services): Document it. --- doc/guix.texi | 9 +++++++++ gnu/services/version-control.scm | 8 +++++++- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/doc/guix.texi b/doc/guix.texi index a826171f34..29a2fffdfd 100644 --- a/doc/guix.texi +++ b/doc/guix.texi @@ -31426,6 +31426,15 @@ A value like @code{#o0027} will give read access to the group used by Gitolite (by default: @code{git}). This is necessary when using Gitolite with software like cgit or gitweb. +@item @code{unsafe-patt} (default: @code{#f}) +An optional pattern for catching unsafe configurations in the configuration +file. See +@uref{https://gitolite.com/gitolite/git-config.html#compensating-for-unsafe_patt, +Gitolite's documentation} for more information. + +When the value is not @code{#f}, it should be a string containing a Perl +regular expression, such as @samp{"[`~#\$\&()|;<>]"}. + @item @code{git-config-keys} (default: @code{""}) Gitolite allows you to set git config values using the @samp{config} keyword. This setting allows control over the config keys to accept. diff --git a/gnu/services/version-control.scm b/gnu/services/version-control.scm index 8cb5633165..d0ac2e4a18 100644 --- a/gnu/services/version-control.scm +++ b/gnu/services/version-control.scm @@ -54,6 +54,7 @@ gitolite-rc-file gitolite-rc-file-umask + gitolite-rc-file-unsafe-patt gitolite-rc-file-git-config-keys gitolite-rc-file-roles gitolite-rc-file-enable @@ -226,6 +227,8 @@ access to exported repositories under @file{/srv/git}." gitolite-rc-file? (umask gitolite-rc-file-umask (default #o0077)) + (unsafe-patt gitolite-rc-file-unsafe-patt + (default #f)) (git-config-keys gitolite-rc-file-git-config-keys (default "")) (roles gitolite-rc-file-roles @@ -245,7 +248,7 @@ access to exported repositories under @file{/srv/git}." (define-gexp-compiler (gitolite-rc-file-compiler (file ) system target) (match file - (($ umask git-config-keys roles enable) + (($ umask unsafe-patt git-config-keys roles enable) (apply text-file* "gitolite.rc" `("%RC = (\n" " UMASK => " ,(format #f "~4,'0o" umask) ",\n" @@ -264,6 +267,9 @@ access to exported repositories under @file{/srv/git}." " ],\n" ");\n" "\n" + ,(if unsafe-patt + (string-append "$UNSAFE_PATT = qr(" unsafe-patt ");") + "") "1;\n"))))) (define-record-type* -- 2.32.0 --MP_/WGaDyAVP._GKgThuzA.bXh4 Content-Type: text/x-patch Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename=0003-gnu-version-control-Add-gitile-service.patch =46rom a80c856fce646eee7257239e4c05e67ac292b5fc Mon Sep 17 00:00:00 2001 From: Julien Lepiller Date: Thu, 5 Aug 2021 03:46:40 +0200 Subject: [PATCH 3/3] gnu: version-control: Add gitile service. * gnu/services/version-control.scm (gitile-service-type): New variable. * doc/guix.texi (Version Control Services): Document it. * gnu/tests/version-control.scm (%test-gitile): New variable. --- doc/guix.texi | 128 ++++++++++++++++++++++++++++ gnu/services/version-control.scm | 128 +++++++++++++++++++++++++++- gnu/tests/version-control.scm | 138 ++++++++++++++++++++++++++++++- 3 files changed, 391 insertions(+), 3 deletions(-) diff --git a/doc/guix.texi b/doc/guix.texi index 29a2fffdfd..94d9301238 100644 --- a/doc/guix.texi +++ b/doc/guix.texi @@ -31449,6 +31449,134 @@ This setting controls the commands and features t= o enable within Gitolite. @end deftp =20 =20 +@subsubheading Gitile Service + +@cindex Gitile service +@cindex Git, forge +@uref{https://git.lepiller.eu/gitile, Gitile} is a Git forge for viewing +public git repository contents from a web browser. + +Gitile works best in collaboration with Gitolite, and will serve the public +repositories from Gitolite by default. The service should listen only on +a local port, and a webserver should be configured to serve static resourc= es. +The gitile service provides an easy way to extend the Nginx service. + +The following example will configure Gitile to serve repositories from a +custom location, with some default messages for the home page and the +footers. + +@lisp +(service gitile-service-type + (gitile-configuration + (repositories "/srv/git") + (base-git-url "https://myweb.site/git") + (index-title "My git repositories") + (intro '((p "This is all my public work!"))) + (footer '((p "This is the end"))) + (nginx-server-block + (nginx-server-configuration + (ssl-certificate + "/etc/letsencrypt/live/myweb.site/fullchain.pem") + (ssl-certificate-key + "/etc/letsencrypt/live/myweb.site/privkey.pem") + (listen '("443 ssl http2" "[::]:443 ssl http2")) + (locations + (list + ;; Allow for https anonymous fetch on /git/ urls. + (git-http-nginx-location-configuration + (git-http-configuration + (uri-path "/git/") + (git-root "/var/lib/gitolite/repositories"))))))))) +@end lisp + +In addition to the configuration record, you should configure your git +repositories to contain some optional information. First, your public +repositories need to contain the @file{.git-daemon-export-ok} magic file +that allows Git to export the repository. Gitile uses the presence of this +file to detect public repositories it should make accessible. To do so wi= th +Gitolite for instance, modify your @file{conf/gitolite.conf} to include +this in the repositories you want to make public: + +@example +repo foo + R =3D daemon +@end example + +In addition, Gitile can read the repository configuration to display more +infomation on the repository. Gitile uses the gitweb namespace for its +configuration. As an example, you can use the following in your +@file{conf/gitolite.conf}: + +@example +repo foo + R =3D daemon + desc =3D A long description, optionally with HTML, shown on the= index page + config gitweb.name =3D The Foo Project + config gitweb.synopsis =3D A short description, shown on the main page= of the project +@end example + +Do not forget to commit and push these changes once you are satisfied. You +may need to change your gitolite configuration to allow the previous +configuration options to be set. One way to do that is to add the +following service definition: + +@lisp +(service gitolite-service-type + (gitolite-configuration + (admin-pubkey (local-file "key.pub")) + (rc-file + (gitolite-rc-file + (umask #o0027) + (git-config-keys ".*") + (unsafe-patt "^$"))))) +@end lisp + +@deftp {Data Type} gitile-configuration +Data type representing the configuration for @code{gitile-service-type}. + +@table @asis +@item @code{package} (default: @var{gitile}) +Gitile package to use. + +@item @code{host} (default: @code{"localhost"}) +The host on which gitile is listening. + +@item @code{port} (default: @code{8080}) +The port on which gitile is listening. + +@item @code{database} (default: @code{"/var/lib/gitile/gitile-db.sql"}) +The location of the database. + +@item @code{repositories} (default: @code{"/var/lib/gitolite/repositories"= }) +The location of the repositories. Note that only public repositories will +be shown by Gitile. To make a repository public, add an empty +@file{git-daemon-export-ok} file at the root of that repository. + +@item @code{base-git-url} +The base git url that will be used to show clone commands. + +@item @code{index-title} (default: @code{"Index"}) +The page title for the index page that lists all the available repositorie= s. + +@item @code{intro} (default: @code{'()}) +The intro content, as a list of sxml expressions. This is shown above the= list +of repositories, on the index page. + +@item @code{footer} (default: @code{'()}) +The footer content, as a list of sxml expressions. This is shown on every +page served by Gitile. + +@item @code{nginx-server-block} +An nginx server block that will be extended and used as a reverse proxy by +Gitile to serve its pages, and as a normal web server to serve its assets. + +You can use this block to add more custom URLs to your domain, such as a +@code{/git/} URL for anonymous clones, or serving any other files you would +like to serve. +@end table +@end deftp + + @node Game Services @subsection Game Services =20 diff --git a/gnu/services/version-control.scm b/gnu/services/version-contro= l.scm index d0ac2e4a18..4cb648eb3e 100644 --- a/gnu/services/version-control.scm +++ b/gnu/services/version-control.scm @@ -4,6 +4,7 @@ ;;; Copyright =C2=A9 2017 Oleg Pykhalov ;;; Copyright =C2=A9 2017 Cl=C3=A9ment Lassieur ;;; Copyright =C2=A9 2018 Christopher Baines +;;; Copyright =C2=A9 2021 Julien Lepiller ;;; ;;; This file is part of GNU Guix. ;;; @@ -59,7 +60,21 @@ gitolite-rc-file-roles gitolite-rc-file-enable =20 - gitolite-service-type)) + gitolite-service-type + + gitile-configuration + gitile-configuration-package + gitile-configuration-host + gitile-configuration-port + gitile-configuration-database + gitile-configuration-repositories + gitile-configuration-git-base-url + gitile-configuration-index-title + gitile-configuration-intro + gitile-configuration-footer + gitile-configuration-nginx + + gitile-service-type)) =20 ;;; Commentary: ;;; @@ -386,3 +401,114 @@ access to exported repositories under @file{/srv/git}= ." By default, the @code{git} user is used, but this is configurable. Additionally, Gitolite can integrate with with tools like gitweb or cgit to provide a web interface to view selected repositories."))) + +;;; +;;; Gitile +;;; + +(define-record-type* + gitile-configuration make-gitile-configuration gitile-configuration? + (package gitile-configuration-package + (default gitile)) + (host gitile-configuration-host + (default "127.0.0.1")) + (port gitile-configuration-port + (default 8080)) + (database gitile-configuration-database + (default "/var/lib/gitile/gitile-db.sql")) + (repositories gitile-configuration-repositories + (default "/var/lib/gitolite/repositories")) + (base-git-url gitile-configuration-base-git-url) + (index-title gitile-configuration-index-title + (default "Index")) + (intro gitile-configuration-intro + (default '())) + (footer gitile-configuration-footer + (default '())) + (nginx gitile-configuration-nginx)) + +(define (gitile-config-file host port database repositories base-git-url + index-title intro footer) + (define build + #~(write `(config + (port #$port) + (host #$host) + (database #$database) + (repositories #$repositories) + (base-git-url #$base-git-url) + (index-title #$index-title) + (intro #$intro) + (footer #$footer)) + (open-output-file #$output))) + + (computed-file "gitile.conf" build)) + +(define gitile-nginx-server-block + (match-lambda + (($ package host port database repositories + base-git-url index-title intro footer nginx) + (list (nginx-server-configuration + (inherit nginx) + (locations + (append + (list + (nginx-location-configuration + (uri "/") + (body + (list + #~(string-append "proxy_pass http://" #$ho= st + ":" (number->string #$por= t) + "/;"))))) + (map + (lambda (loc) + (nginx-location-configuration + (uri loc) + (body + (list + #~(string-append "root " #$package "/share/giti= le/assets;"))))) + '("/css" "/js" "/images")) + (nginx-server-configuration-locations nginx)))))))) + +(define gitile-shepherd-service + (match-lambda + (($ package host port database repositories + base-git-url index-title intro footer nginx) + (list (shepherd-service + (provision '(gitile)) + (requirement '(loopback)) + (documentation "gitile") + (start (let ((gitile (file-append package "/bin/gitile"))) + #~(make-forkexec-constructor + `(,#$gitile "-c" #$(gitile-config-file + host port database + repositories + base-git-url index-title + intro footer)) + #:user "gitile" + #:group "git"))) + (stop #~(make-kill-destructor))))))) + +(define %gitile-accounts + (list (user-group + (name "git") + (system? #t)) + (user-account + (name "gitile") + (group "git") + (system? #t) + (comment "Gitile user") + (home-directory "/var/empty") + (shell (file-append shadow "/sbin/nologin"))))) + +(define gitile-service-type + (service-type + (name 'gitile) + (description "Run Gitile, a small Git forge. Expose public repositori= es +on the web.") + (extensions + (list (service-extension account-service-type + (const %gitile-accounts)) + (service-extension shepherd-root-service-type + gitile-shepherd-service) + (service-extension nginx-service-type + gitile-nginx-server-block))))) diff --git a/gnu/tests/version-control.scm b/gnu/tests/version-control.scm index d3cf19c913..a7cde1f163 100644 --- a/gnu/tests/version-control.scm +++ b/gnu/tests/version-control.scm @@ -38,7 +38,8 @@ #:use-module (guix modules) #:export (%test-cgit %test-git-http - %test-gitolite)) + %test-gitolite + %test-gitile)) =20 (define README-contents "Hello! This is what goes inside the 'README' file.") @@ -63,7 +64,10 @@ (invoke git "commit" "-m" "That's a commit.")) =20 (mkdir-p "/srv/git") - (rename-file "/tmp/test-repo/.git" "/srv/git/test"))))) + (rename-file "/tmp/test-repo/.git" "/srv/git/test") + (with-output-to-file "/srv/git/test/git-daemon-export-ok" + (lambda _ + (display ""))))))) =20 (define %test-repository-service ;; Service that creates /srv/git/test. @@ -416,3 +420,133 @@ HTTP-PORT." (name "gitolite") (description "Clone the Gitolite admin repository.") (value (run-gitolite-test)))) + +;;; +;;; Gitile. +;;; + +(define %gitile-configuration-nginx + (nginx-server-configuration + (root "/does/not/exists") + (try-files (list "$uri" "=3D404")) + (listen '("19418")) + (ssl-certificate #f) + (ssl-certificate-key #f))) + +(define %gitile-os + ;; Operating system under test. + (simple-operating-system + (service dhcp-client-service-type) + (simple-service 'srv-git activation-service-type + #~(mkdir-p "/srv/git")) + (service gitile-service-type + (gitile-configuration + (base-git-url "http://localhost") + (repositories "/srv/git") + (nginx %gitile-configuration-nginx))) + %test-repository-service)) + +(define* (run-gitile-test #:optional (http-port 19418)) + "Run tests in %GITOLITE-OS, which has nginx running and listening on +HTTP-PORT." + (define os + (marionette-operating-system + %gitile-os + #:imported-modules '((gnu services herd) + (guix combinators)))) + + (define vm + (virtual-machine + (operating-system os) + (port-forwardings `((8081 . ,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 "gitile") + + ;; XXX: Shepherd reads the config file *before* binding its cont= rol + ;; socket, so /var/run/shepherd/socket might not exist yet when = the + ;; 'marionette' service is started. + (test-assert "shepherd socket ready" + (marionette-eval + `(begin + (use-modules (gnu services herd)) + (let loop ((i 10)) + (cond ((file-exists? (%shepherd-socket-file)) + #t) + ((> i 0) + (sleep 1) + (loop (- i 1))) + (else + 'failure)))) + marionette)) + + ;; Wait for nginx to be up and running. + (test-assert "nginx running" + (marionette-eval + '(begin + (use-modules (gnu services herd)) + (start-service 'nginx)) + marionette)) + + ;; Make sure the PID file is created. + (test-assert "PID file" + (marionette-eval + '(file-exists? "/var/run/nginx/pid") + marionette)) + + ;; Make sure Git test repository is created. + (test-assert "Git test repository" + (marionette-eval + '(file-exists? "/srv/git/test") + marionette)) + + (sleep 2) + + ;; Make sure we can access pages that correspond to our reposito= ry. + (letrec-syntax ((test-url + (syntax-rules () + ((_ path code) + (test-equal (string-append "GET " path) + code + (let-values (((response body) + (http-get (string-append + "http://localhost= :8081" + path)))) + (response-code response)))) + ((_ path) + (test-url path 200))))) + (test-url "/") + (test-url "/css/gitile.css") + (test-url "/test") + (test-url "/test/commits") + (test-url "/test/tree" 404) + (test-url "/test/tree/-") + (test-url "/test/tree/-/README") + (test-url "/test/does-not-exist" 404) + (test-url "/test/tree/-/does-not-exist" 404) + (test-url "/does-not-exist" 404)) + + (test-end) + (exit (=3D (test-runner-fail-count (test-runner-current)) 0))))) + + (gexp->derivation "gitile-test" test)) + +(define %test-gitile + (system-test + (name "gitile") + (description "Connect to a running Gitile server.") + (value (run-gitile-test)))) --=20 2.32.0 --MP_/WGaDyAVP._GKgThuzA.bXh4--