From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mp0 ([2001:41d0:8:6d80::]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) by ms0.migadu.com with LMTPS id wAiTF+SrXGA8gAEAgWs5BA (envelope-from ) for ; Thu, 25 Mar 2021 16:27:32 +0100 Received: from aspmx1.migadu.com ([2001:41d0:8:6d80::]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) by mp0 with LMTPS id mmZSE+SrXGD0FgAA1q6Kng (envelope-from ) for ; Thu, 25 Mar 2021 15:27:32 +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 77A6E21F90 for ; Thu, 25 Mar 2021 16:27:29 +0100 (CET) Received: from localhost ([::1]:55590 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lPRtQ-0002kC-8W for larch@yhetil.org; Thu, 25 Mar 2021 11:27:28 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:40388) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lPRt0-0002MP-Ie for guix-patches@gnu.org; Thu, 25 Mar 2021 11:27:03 -0400 Received: from debbugs.gnu.org ([209.51.188.43]:55958) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1lPRt0-0001O7-69 for guix-patches@gnu.org; Thu, 25 Mar 2021 11:27:02 -0400 Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1lPRt0-0002cg-2B for guix-patches@gnu.org; Thu, 25 Mar 2021 11:27:02 -0400 X-Loop: help-debbugs@gnu.org Subject: [bug#47392] [PATCH 2/2] services: Add Laminar. Resent-From: Christopher Baines Original-Sender: "Debbugs-submit" Resent-CC: guix-patches@gnu.org Resent-Date: Thu, 25 Mar 2021 15:27:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 47392 X-GNU-PR-Package: guix-patches X-GNU-PR-Keywords: patch To: 47392@debbugs.gnu.org Received: via spool by 47392-submit@debbugs.gnu.org id=B47392.161668598010010 (code B ref 47392); Thu, 25 Mar 2021 15:27:02 +0000 Received: (at 47392) by debbugs.gnu.org; 25 Mar 2021 15:26:20 +0000 Received: from localhost ([127.0.0.1]:39270 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1lPRsK-0002bN-2m for submit@debbugs.gnu.org; Thu, 25 Mar 2021 11:26:20 -0400 Received: from mira.cbaines.net ([212.71.252.8]:44024) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1lPRsD-0002as-VL for 47392@debbugs.gnu.org; Thu, 25 Mar 2021 11:26:15 -0400 Received: from localhost (unknown [IPv6:2a02:8010:68c1:0:8ac0:b4c7:f5c8:7caa]) by mira.cbaines.net (Postfix) with ESMTPSA id 0F29E27BC5D for <47392@debbugs.gnu.org>; Thu, 25 Mar 2021 15:26:13 +0000 (GMT) Received: from localhost (localhost [local]) by localhost (OpenSMTPD) with ESMTPA id 67645d16 for <47392@debbugs.gnu.org>; Thu, 25 Mar 2021 15:26:12 +0000 (UTC) From: Christopher Baines Date: Thu, 25 Mar 2021 15:26:12 +0000 Message-Id: <20210325152612.15321-2-mail@cbaines.net> X-Mailer: git-send-email 2.30.1 In-Reply-To: <20210325152612.15321-1-mail@cbaines.net> References: <20210325152612.15321-1-mail@cbaines.net> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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=1616686049; h=from:from:sender:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:mime-version:mime-version: content-type:content-type: content-transfer-encoding:content-transfer-encoding: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; bh=rspOOOSSdOusOloDkRA0jBIRNQDe5c6Y7SxkGEX6rrA=; b=gllEGVcQWR2UzVJXcLdyDmfOeOsVdFM/8MxXXpmLVVbBidV/4qAiOXQ1w7vn2guW89fLY8 CaAWlTJJvPlpaOt2VLJzPl8QmyTLO7aZhcD+LsWj+nN7kRthzNiTSLsJzUHvtd9io40K6n 9w0s0+a/8tz906MUvmyQgO4o2rrmjH33qsV9dVLXxj6q/+xMwEC0ySTiN4+YEjXIZf98OO 5Nqq5yBuG9rjapOXMoDsKeTtJrWZVaiNTuW/tCIYEVDMa2uGIRrZow3n2TyQGmgsVxLcZ+ S89qyHquqx4Sn5XPl3WJ6JteUyQfo9UKTu8sXE8VYjYSOe+lMbcjgH9gj170Tg== ARC-Seal: i=1; s=key1; d=yhetil.org; t=1616686049; a=rsa-sha256; cv=none; b=Nuq6kwjzMmF/LYspcZ5o4IVcSIoAsx0tQZ2vuWVcs5U7vd1Q/2wAp6eh7paiD4KxCd0Ho3 C4ccMclqvIkLi1k0AJ8tOK4P0eXISy8+rrXoj9z6ooVX/DxZvtNxoE3t0fJX4ONUXh/CiM UKHY8tSOsAAUndghA4fqGZlKKjEofOaG6Pl662QIVxqvB8e3I9JdusvI5AQZwn6xdYmEi2 GL6mt77p5UT+YQknAVqAxuvox14qFdmJ5WJKmXYncFSoYwqHde1t83l0o0HDi/eYEsiaL/ ZH5EhyB9xZQx3ePeWkaT2WEt0efpIkvwVwj7vglsi60GimEJiqDoOGN/6kw/Pg== ARC-Authentication-Results: i=1; aspmx1.migadu.com; dkim=none; dmarc=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.42 Authentication-Results: aspmx1.migadu.com; dkim=none; dmarc=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: 77A6E21F90 X-Spam-Score: -1.42 X-Migadu-Scanner: scn0.migadu.com X-TUID: vjv6keDde3ws * gnu/services/ci.scm: New file. * gnu/tests/ci.scm: New file. * doc/guix.texi (Laminar): Document the Laminar service. --- doc/guix.texi | 54 ++++++++++++++++++- gnu/services/ci.scm | 128 +++++++++++++++++++++++++++++++++++++++++++ gnu/tests/ci.scm | 129 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 309 insertions(+), 2 deletions(-) create mode 100644 gnu/services/ci.scm create mode 100644 gnu/tests/ci.scm diff --git a/doc/guix.texi b/doc/guix.texi index 74f3fbd299..bd087dae05 100644 --- a/doc/guix.texi +++ b/doc/guix.texi @@ -342,7 +342,7 @@ Services * DNS Services:: DNS daemons. * VPN Services:: VPN daemons. * Network File System:: NFS related services. -* Continuous Integration:: The Cuirass service. +* Continuous Integration:: Cuirass and Laminar services. * Power Management Services:: Extending battery life. * Audio Services:: The MPD. * Virtualization Services:: Virtualization services. @@ -14798,7 +14798,7 @@ declaration. * DNS Services:: DNS daemons. * VPN Services:: VPN daemons. * Network File System:: NFS related services. -* Continuous Integration:: The Cuirass service. +* Continuous Integration:: Cuirass and Laminar services. * Power Management Services:: Extending battery life. * Audio Services:: The MPD. * Virtualization Services:: Virtualization services. @@ -27301,6 +27301,56 @@ the store items being published. @end table @end deftp +@subsubheading Laminar + +@uref{https://laminar.ohwg.net/, Laminar} is a lightweight and modular +Continuous Integration service. It doesn't have a configuration web UI +instead uses version-controllable configuration files and scripts. + +Laminar encourages the use of existing GNU/Linux tools such as bash and +cron instead of reinventing them. + +@defvr {Scheme Procedure} laminar-service-type +The type of the Laminar service. Its value must be a +@code{laminar-configuration} object, as described below. +@end defvr + +@deftp {Data Type} laminar-configuration +Data type representing the configuration of Laminar. + +@table @asis +@item @code{laminar} (default: @code{laminar}) +The Laminar package to use. + +@item @code{home-directory} (default: @code{"/var/lib/laminar"}) +The directory for job configurations and run directories. + +@item @code{bind-http} (default: @code{"*:8080"}) +The interface/port or unix socket on which laminard should listen for +incoming connections to the web frontend. + +@item @code{bind-rpc} (default: @code{"unix-abstract:laminar"}) +The interface/port or unix socket on which laminard should listen for +incoming commands such as build triggers. + +@item @code{title} (default: @code{"Laminar"}) +The page title to show in the web frontend. + +@item @code{keep-rundirs} (default: @code{0}) +Set to an integer defining how many rundirs to keep per job. The +lowest-numbered ones will be deleted. The default is 0, meaning all run +dirs will be immediately deleted. + +@item @code{archive-url} (default: @code{#f}) +The web frontend served by laminard will use this URL to form links to +artefacts archived jobs. + +@item @code{base-url} (default: @code{#f}) +Base URL to use for links to laminar itself. + +@end table +@end deftp + @node Power Management Services @subsection Power Management Services diff --git a/gnu/services/ci.scm b/gnu/services/ci.scm new file mode 100644 index 0000000000..400980dcd4 --- /dev/null +++ b/gnu/services/ci.scm @@ -0,0 +1,128 @@ +;;; GNU Guix --- Functional package management for GNU +;;; Copyright © 2018 Christopher Baines +;;; +;;; 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 services ci) + #:use-module (guix gexp) + #:use-module (guix records) + #:use-module (gnu packages admin) + #:use-module (gnu packages ci) + #:use-module (gnu services) + #:use-module (gnu services base) + #:use-module (gnu services shepherd) + #:use-module (gnu services admin) + #:use-module (gnu system shadow) + #:use-module (ice-9 match) + #:export ( + laminar-configuration + laminar-configuration? + laminar-configuration-home-directory + laminar-configuration-bind-http + laminar-configuration-bind-rpc + laminar-configuration-title + laminar-configuration-keep-rundirs + laminar-configuration-archive-url + laminar-configuration-base-url + + laminar-service-type)) + +;;;; Commentary: +;;; +;;; This module implements a service that to run instances of Laminar, a +;;; continuous integration tool. +;;; +;;;; Code: + +(define-record-type* + laminar-configuration make-laminar-configuration + laminar-configuration? + (laminar laminars-configuration-laminar + (default laminar)) + (home-directory laminar-configuration-home-directory + (default "/var/lib/laminar")) + (bind-http laminar-configuration-bind-http + (default "*:8080")) + (bind-rpc laminar-configuration-bind-rpc + (default "unix-abstract:laminar")) + (title laminar-configuration-title + (default "Laminar")) + (keep-rundirs laminar-keep-rundirs + (default 0)) + (archive-url laminar-archive-url + (default #f)) + (base-url laminar-base-url + (default #f))) + +(define laminar-shepherd-service + (match-lambda + (($ laminar home-directory + bind-http bind-rpc + title keep-rundirs archive-url + base-url) + (list (shepherd-service + (documentation "Run Laminar.") + (provision '(laminar)) + (requirement '(networking)) + (start #~(make-forkexec-constructor + (list #$(file-append laminar "/sbin/laminard")) + #:environment-variables + `(,(string-append "LAMINAR_HOME=" + #$home-directory) + ,(string-append "LAMINAR_BIND_HTTP=" + #$bind-http) + ,(string-append "LAMINAR_TITLE=" + #$title) + ,(string-append "LAMINAR_KEEP_RUNDIRS=" + #$(number->string + keep-rundirs)) + ,@(if #$archive-url + (list + (string-append "LAMINAR_ARCHIVE_URL=" + #$archive-url)) + '()) + ,@(if #$base-url + (list + (string-append "LAMINAR_BASE_URL=" + #$base-url)) + '())) + #:user "laminar" + #:group "laminar")) + (stop #~(make-kill-destructor))))))) + +(define (laminar-account config) + "Return the user accounts and user groups for CONFIG." + (list (user-group + (name "laminar") + (system? #t)) + (user-account + (name "laminar") + (group "laminar") + (system? #t) + (comment "Laminar privilege separation user") + (home-directory (laminar-configuration-home-directory config)) + (shell #~(string-append #$shadow "/sbin/nologin"))))) + +(define laminar-service-type + (service-type + (name 'laminar) + (extensions + (list + (service-extension shepherd-root-service-type laminar-shepherd-service) + (service-extension account-service-type laminar-account))) + (default-value (laminar-configuration)) + (description + "Run the Laminar continuous integration service."))) diff --git a/gnu/tests/ci.scm b/gnu/tests/ci.scm new file mode 100644 index 0000000000..fe74e73e74 --- /dev/null +++ b/gnu/tests/ci.scm @@ -0,0 +1,129 @@ +;;; GNU Guix --- Functional package management for GNU +;;; Copyright © 2017 Ludovic Courtès +;;; Copyright © 2017 Christopher Baines +;;; Copyright © 2017, 2018 Clément Lassieur +;;; Copyright © 2018 Pierre-Antoine Rouby +;;; Copyright © 2018 Marius Bakke +;;; +;;; 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 ci) + #: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 ci) + #:use-module (gnu services web) + #:use-module (gnu services networking) + #:use-module (guix gexp) + #:use-module (guix store) + #:export (%test-laminar)) + + + +(define %laminar-os + ;; Operating system under test. + (simple-operating-system + (service dhcp-client-service-type) + (service laminar-service-type))) + +(define* (run-laminar-test #:optional (http-port 8080)) + "Run tests in %LAMINAR-OS, which has laminar running and listening on +HTTP-PORT." + (define os + (marionette-operating-system + %laminar-os + #:imported-modules '((gnu services herd) + (guix combinators)))) + + (define vm + (virtual-machine + (operating-system os) + (port-forwardings `((,http-port . 8080))))) + + (define test + (with-imported-modules '((gnu build marionette)) + #~(begin + (use-modules (srfi srfi-11) (srfi srfi-64) + (ice-9 match) + (gnu build marionette) + (web uri) + (web client) + (web response)) + + (define marionette + ;; Forward the guest's HTTP-PORT, where laminar is listening, to + ;; port 8080 in the host. + (make-marionette (list #$vm))) + + (mkdir #$output) + (chdir #$output) + + (test-begin "laminar") + + (test-assert "service running" + (marionette-eval + '(begin + (use-modules (gnu services herd)) + (start-service 'laminar)) + marionette)) + + (define* (retry-on-error f #:key times delay) + (let loop ((attempt 1)) + (match (catch + #t + (lambda () + (cons #t + (f))) + (lambda args + (cons #f + args))) + ((#t . return-value) + return-value) + ((#f . error-args) + (if (>= attempt times) + error-args + (begin + (sleep delay) + (loop (+ 1 attempt)))))))) + + (test-equal "http-get" + 200 + (retry-on-error + (lambda () + (let-values (((response text) + (http-get #$(format + #f + "http://localhost:~A/" + http-port) + ;; TODO: Why does decoding fail? + #:decode-body? #f))) + (response-code response))) + #:times 10 + #:delay 5)) + + (test-end) + (exit (= (test-runner-fail-count (test-runner-current)) 0))))) + + (gexp->derivation "laminar-test" test)) + +(define %test-laminar + (system-test + (name "laminar") + (description "Connect to a running Laminar server.") + (value (run-laminar-test)))) -- 2.30.1