From patchwork Sun Feb 14 18:57:31 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Alexandru-Sergiu Marton X-Patchwork-Id: 27057 Return-Path: X-Original-To: patchwork@mira.cbaines.net Delivered-To: patchwork@mira.cbaines.net Received: by mira.cbaines.net (Postfix, from userid 113) id 6F89327BC45; Sun, 14 Feb 2021 19:25:54 +0000 (GMT) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on mira.cbaines.net X-Spam-Level: X-Spam-Status: No, score=-2.8 required=5.0 tests=BAYES_00,DKIM_SIGNED, MAILING_LIST_MULTI,RCVD_IN_MSPIKE_H4,RCVD_IN_MSPIKE_WL,SPF_HELO_PASS, T_DKIM_INVALID,URIBL_BLOCKED autolearn=unavailable autolearn_force=no version=3.4.2 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mira.cbaines.net (Postfix) with ESMTPS id 47BDD27BC2E for ; Sun, 14 Feb 2021 19:25:53 +0000 (GMT) Received: from localhost ([::1]:54488 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lBN1k-0006HJ-F1 for patchwork@mira.cbaines.net; Sun, 14 Feb 2021 14:25:52 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:46696) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lBMar-0002UH-6B for guix-patches@gnu.org; Sun, 14 Feb 2021 13:58:05 -0500 Received: from debbugs.gnu.org ([209.51.188.43]:53418) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1lBMaq-0000KK-Sc for guix-patches@gnu.org; Sun, 14 Feb 2021 13:58:04 -0500 Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1lBMaq-0003wi-SA for guix-patches@gnu.org; Sun, 14 Feb 2021 13:58:04 -0500 X-Loop: help-debbugs@gnu.org Subject: [bug#46513] [PATCH 6/6] services: Add agate web service. Resent-From: Alexandru-Sergiu Marton Original-Sender: "Debbugs-submit" Resent-CC: guix-patches@gnu.org Resent-Date: Sun, 14 Feb 2021 18:58:04 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 46513 X-GNU-PR-Package: guix-patches X-GNU-PR-Keywords: patch To: 46513@debbugs.gnu.org Cc: Alexandru-Sergiu Marton Received: via spool by 46513-submit@debbugs.gnu.org id=B46513.161332907515116 (code B ref 46513); Sun, 14 Feb 2021 18:58:04 +0000 Received: (at 46513) by debbugs.gnu.org; 14 Feb 2021 18:57:55 +0000 Received: from localhost ([127.0.0.1]:36726 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1lBMah-0003ve-4o for submit@debbugs.gnu.org; Sun, 14 Feb 2021 13:57:55 -0500 Received: from mout02.posteo.de ([185.67.36.66]:46949) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1lBMaZ-0003uQ-S8 for 46513@debbugs.gnu.org; Sun, 14 Feb 2021 13:57:48 -0500 Received: from submission (posteo.de [89.146.220.130]) by mout02.posteo.de (Postfix) with ESMTPS id 18E402400FB for <46513@debbugs.gnu.org>; Sun, 14 Feb 2021 19:57:42 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=posteo.ro; s=2017; t=1613329062; bh=4qCcdPtLwa0iOgfOMMnNmmIg2GKFBn3Sn65khFfEjt8=; h=From:To:Cc:Subject:Date:From; b=TuqMmUdMEG5vggoG30HrCZwXwcVgcdcih+2s7/QB+IjO+YCpS+az0Q7O5wrdHMzAj vRJ0DT9ws2POTuoHFdConwgVyLUitBpn/EcfEAGk2uXpAKhFwBYLTUxafyl66+5DEj md8fYqzgs2D5XyKXFtlvU8mamaVxcVvYxwGgWnbIhzz1zP7mHy22qLBqNUA9ZqcoPj AIbXBZmefYtIoeh3QwTMxoZ7F5oeuaQMQhupKniJ0C8lbLHyfogW3eBuKYs+VdpZlS wpGTvmXyaWO0+I2scpAn9Xy05TAoBjjt/ihB2THI0EIDuExd0PihiH3wy15FpJUoUi tdBL2UKa/weaQ== Received: from customer (localhost [127.0.0.1]) by submission (posteo.de) with ESMTPSA id 4DdxLs4m6pz9rxR; Sun, 14 Feb 2021 19:57:41 +0100 (CET) From: Alexandru-Sergiu Marton Date: Sun, 14 Feb 2021 20:57:31 +0200 Message-Id: <20210214185731.31197-6-brown121407@posteo.ro> X-Mailer: git-send-email 2.30.0 In-Reply-To: <20210214185731.31197-1-brown121407@posteo.ro> References: <20210214185104.30887-1-brown121407@posteo.ro> <20210214185731.31197-1-brown121407@posteo.ro> MIME-Version: 1.0 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+patchwork=mira.cbaines.net@gnu.org Sender: "Guix-patches" X-getmail-retrieved-from-mailbox: Patches * gnu/services/web.scm (): New record type. (agate-accounts, agate-shepherd-service): New procedures. (agate-service-type): New variable. * doc/guix.texi (Web Services): Document it. --- doc/guix.texi | 89 +++++++++++++++++++++++++++++++++- gnu/services/web.scm | 112 ++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 198 insertions(+), 3 deletions(-) diff --git a/doc/guix.texi b/doc/guix.texi index 68abb968b0..c10d6877e2 100644 --- a/doc/guix.texi +++ b/doc/guix.texi @@ -81,7 +81,7 @@ Copyright @copyright{} 2020 R Veera Kumar@* Copyright @copyright{} 2020 Pierre Langlois@* Copyright @copyright{} 2020 pinoaffe@* Copyright @copyright{} 2020 André Batista@* -Copyright @copyright{} 2020 Alexandru-Sergiu Marton@* +Copyright @copyright{} 2020, 2021 Alexandru-Sergiu Marton@* Copyright @copyright{} 2020 raingloom@* Copyright @copyright{} 2020 Daniel Brooks@* Copyright @copyright{} 2020 John Soo@* @@ -25316,6 +25316,93 @@ gmnisrv} and @command{man gmnisrv.ini}. @end table @end deftp +@subsubheading agate + +@cindex agate +The @uref{gemini://qwertqwefsday.eu/agate.gmi, Agate} +(@uref{https://github.com/mbrubeck/agate, GitHub page over HTTPS}) +program is a simple @uref{https://gemini.circumlunar.space/, Gemini} +protocol server written in Rust. + +@deffn {Scheme Variable} agate-service-type +This is the type of the agate service, whose value should be an +@code{agate-service-type} object, as in this example: + +@lisp +(service agate-service-type + (agate-configuration + (content "/srv/gemini") + (cert "/srv/cert.pem") + (key "/srv/key.rsa"))) +@end lisp + +The example above represents the minimal tweaking necessary to get Agate +up and running. Specifying the path to the certificate and key is always +necessary, as the Gemini protocol requires TLS by default. + +To obtain a certificate and a key, you could, for example, use OpenSSL, +running a command similar to the following example: + +@example +openssl req -x509 -newkey rsa:4096 -keyout key.rsa -out cert.pem \ + -days 3650 -nodes -subj "/CN=example.com" +@end example + +Of course, you'll have to replace @i{example.com} with your own domain +name, and then point the Agate configuration towards the path of the +generated key and certificate. + +@end deffn + +@deftp {Data Type} agate-configuration +Data type representing the configuration of Agate. + +@table @asis +@item @code{package} (default: @var{agate}) +The package object of the Agate server. + +@item @code{content} (default: @code{"/srv/gemini"}) +The path of the directory from which Agate will serve files. + +@item @code{cert} (default: @code{#f}) +The path to the TLS certificate PEM file to be used for encrypted +connections. Must be filled in with a value from the user. + +@item @code{key} (default: @code{#f}) +The path to the PKCS8 private key file to be used for encrypted +connections. Must be filled in with a value from the user. + +@item @code{addr} (default: @code{'("0.0.0.0:1965" "[::]:1965")}) +A list of the addresses to listen on. + +@item @code{hostname} (default: @code{#f}) +The domain name of this Gemini server. Optional. + +@item @code{lang} (default: @code{#f}) +RFC 4646 Language code(s) for text/gemini documents. Optional. + +@item @code{silent?} (default: @code{#f}) +Set to @code{#t} to disable logging output. + +@item @code{serve-secret?} (default: @code{#f}) +Set to @code{#t} to serve secret files (files/directories starting with +a dot). + +@item @code{log-ip?} (default: @code{#t}) +Whether or not to output IP addresses when logging. + +@item @code{user} (default: @code{"agate"}) +Owner of the @code{agate} process. + +@item @code{group} (default: @code{"agate"}) +Owner's group of the @code{agate} process. + +@item @code{log-file} (default: @code{"/var/log/agate.log"}) +The path of the file which should store the logging output of Agate. + +@end table +@end deftp + @node Certificate Services @subsection Certificate Services diff --git a/gnu/services/web.scm b/gnu/services/web.scm index ff7b262b6a..aa688a4328 100644 --- a/gnu/services/web.scm +++ b/gnu/services/web.scm @@ -14,7 +14,7 @@ ;;; Copyright © 2020 Tobias Geerinckx-Rice ;;; Copyright © 2020 Arun Isaac ;;; Copyright © 2020 Oleg Pykhalov -;;; Copyright © 2020 Alexandru-Sergiu Marton +;;; Copyright © 2020, 2021 Alexandru-Sergiu Marton ;;; ;;; This file is part of GNU Guix. ;;; @@ -50,6 +50,7 @@ #:use-module (gnu packages guile) #:use-module (gnu packages logging) #:use-module (gnu packages mail) + #:use-module (gnu packages rust-apps) #:use-module (guix packages) #:use-module (guix records) #:use-module (guix modules) @@ -263,7 +264,25 @@ gmnisrv-configuration-package gmnisrv-configuration-config-file - gmnisrv-service-type)) + gmnisrv-service-type + + agate-configuration + agate-configuration? + agate-configuration-package + agate-configuration-content + agate-configuration-cert + agate-configuration-key + agate-configuration-addr + agate-configuration-hostname + agate-configuration-lang + agate-configuration-silent + agate-configuration-serve-secret + agate-configuration-log-ip + agate-configuration-user + agate-configuration-group + agate-configuration-log-file + + agate-service-type)) ;;; Commentary: ;;; @@ -1885,3 +1904,92 @@ root=/srv/gemini "Run the gmnisrv Gemini server.") (default-value (gmnisrv-configuration)))) + +(define-record-type* + agate-configuration make-agate-configuration + agate-configuration? + (package agate-configuration-package + (default agate)) + (content agate-configuration-content + (default "/srv/gemini")) + (cert agate-configuration-cert + (default #f)) + (key agate-configuration-key + (default #f)) + (addr agate-configuration-addr + (default '("0.0.0.0:1965" "[::]:1965"))) + (hostname agate-configuration-hostname + (default #f)) + (lang agate-configuration-lang + (default #f)) + (silent? agate-configuration-silent + (default #f)) + (serve-secret? agate-configuration-serve-secret + (default #f)) + (log-ip? agate-configuration-log-ip + (default #t)) + (user agate-configuration-user + (default "agate")) + (group agate-configuration-group + (default "agate")) + (log-file agate-configuration-log + (default "/var/log/agate.log"))) + +(define agate-shepherd-service + (match-lambda + (($ package content cert key addr + hostname lang silent? serve-secret? + log-ip? user group log-file) + (list (shepherd-service + (provision '(agate)) + (requirement '(networking)) + (documentation "Run the agate Gemini server.") + (start (let ((agate (file-append package "/bin/agate"))) + #~(make-forkexec-constructor + (list #$agate + "--content" #$content + "--cert" #$cert + "--key" #$key + "--addr" #$@addr + #$@(if lang + (list "--lang" lang) + '()) + #$@(if hostname + (list "--hostname" hostname) + '()) + #$@(if silent? '("--silent") '()) + #$@(if serve-secret? '("--serve-secret") '()) + #$@(if log-ip? '("--log-ip") '())) + #:user #$user #:group #$group + #:log-file #$log-file))) + (stop #~(make-kill-destructor))))))) + +(define agate-accounts + (match-lambda + (($ _ _ _ _ _ + _ _ _ _ + _ user group _) + `(,@(if (equal? group "agate") + '() + (list (user-group (name "agate") (system? #t)))) + ,(user-group + (name group) + (system? #t)) + ,(user-account + (name user) + (group group) + (supplementary-groups '("agate")) + (system? #t) + (comment "agate server user") + (home-directory "/var/empty") + (shell (file-append shadow "/sbin/nologin"))))))) + +(define agate-service-type + (service-type + (name 'guix) + (extensions + (list (service-extension account-service-type + agate-accounts) + (service-extension shepherd-root-service-type + agate-shepherd-service))) + (default-value (agate-configuration))))