From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mp1 ([2001:41d0:2:4a6f::]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) by ms11 with LMTPS id 4D9ZCRIPZV/uBgAA0tVLHw (envelope-from ) for ; Fri, 18 Sep 2020 19:48:34 +0000 Received: from aspmx1.migadu.com ([2001:41d0:2:4a6f::]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) by mp1 with LMTPS id 4O4/BRIPZV8oUAAAbx9fmQ (envelope-from ) for ; Fri, 18 Sep 2020 19:48:34 +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 B32E7940664 for ; Fri, 18 Sep 2020 19:48:33 +0000 (UTC) Received: from localhost ([::1]:36156 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kJMMy-0007OZ-N3 for larch@yhetil.org; Fri, 18 Sep 2020 15:48:32 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:49360) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kJLJf-0002Jb-QF for guix-patches@gnu.org; Fri, 18 Sep 2020 14:41:03 -0400 Received: from debbugs.gnu.org ([209.51.188.43]:32858) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1kJLJf-0007an-GR for guix-patches@gnu.org; Fri, 18 Sep 2020 14:41:03 -0400 Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1kJLJf-0003QX-EX for guix-patches@gnu.org; Fri, 18 Sep 2020 14:41:03 -0400 X-Loop: help-debbugs@gnu.org Subject: [bug#43494] [PATCH 2/4] services: guix: Add guix-build-coordinator-service-type. Resent-From: Christopher Baines Original-Sender: "Debbugs-submit" Resent-CC: guix-patches@gnu.org Resent-Date: Fri, 18 Sep 2020 18:41:03 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 43494 X-GNU-PR-Package: guix-patches X-GNU-PR-Keywords: patch To: 43494@debbugs.gnu.org Received: via spool by 43494-submit@debbugs.gnu.org id=B43494.160045444913125 (code B ref 43494); Fri, 18 Sep 2020 18:41:03 +0000 Received: (at 43494) by debbugs.gnu.org; 18 Sep 2020 18:40:49 +0000 Received: from localhost ([127.0.0.1]:44401 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1kJLJQ-0003Pa-Qz for submit@debbugs.gnu.org; Fri, 18 Sep 2020 14:40:49 -0400 Received: from mira.cbaines.net ([212.71.252.8]:35120) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1kJLJN-0003Oo-FC for 43494@debbugs.gnu.org; Fri, 18 Sep 2020 14:40:46 -0400 Received: from localhost (unknown [46.237.174.246]) by mira.cbaines.net (Postfix) with ESMTPSA id 850CC27BBE8 for <43494@debbugs.gnu.org>; Fri, 18 Sep 2020 19:40:44 +0100 (BST) Received: from localhost (localhost [local]) by localhost (OpenSMTPD) with ESMTPA id 5dee5f60 for <43494@debbugs.gnu.org>; Fri, 18 Sep 2020 18:40:42 +0000 (UTC) From: Christopher Baines Date: Fri, 18 Sep 2020 19:40:40 +0100 Message-Id: <20200918184042.22660-2-mail@cbaines.net> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20200918184042.22660-1-mail@cbaines.net> References: <20200918184042.22660-1-mail@cbaines.net> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Score: 0.0 (/) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-Spam-Score: -1.0 (-) 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-Scanner: scn0 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-Spam-Score: 3.99 X-TUID: kxYxqur6YYRD * gnu/services/guix.scm (): New record type. (guix-build-coordinator-configuration, guix-build-coordinator-configuration?, guix-build-coordinator-configuration-package, guix-build-coordinator-configuration-user, guix-build-coordinator-configuration-group, guix-build-coordinator-configuration-datastore-uri-string, guix-build-coordinator-configuration-agent-communication-uri-string, guix-build-coordinator-configuration-client-communication-uri-string, guix-build-coordinator-configuration-allocation-strategy, guix-build-coordinator-configuration-hooks, guix-build-coordinator-configuration-guile, make-guix-build-coordinator-start-script, guix-build-coordinator-shepherd-services, guix-build-coordinator-activation, guix-build-coordinator-account): New procedures. (guix-build-coordinator-service-type): New variable. * gnu/tests/guix.scm (%test-guix-build-coordinator): New variable. * doc/guix.texi (Guix Services): Document it. --- doc/guix.texi | 55 ++++++++++++ gnu/services/guix.scm | 204 +++++++++++++++++++++++++++++++++++++++++- gnu/tests/guix.scm | 75 +++++++++++++++- 3 files changed, 330 insertions(+), 4 deletions(-) diff --git a/doc/guix.texi b/doc/guix.texi index 88128a4b3a..e83008c177 100644 --- a/doc/guix.texi +++ b/doc/guix.texi @@ -27486,6 +27486,61 @@ The complete list of possible options can be found in the man page for @node Guix Services @subsection Guix Services +@subsubheading Guix Build Coordinator +The @uref{https://git.cbaines.net/guix/build-coordinator/,Guix Build +Coordinator} aids in building derivations. The Guix Daemon is still +used to build the derivations, but the Guix Build Coordinator provides +ways of performing builds across many machines and working with the +results of builds. + +There is a script to run the coordinator component of the Guix Build +Coordinator, but the Guix service uses a custom Guile script instead, to +provide better integration with G-expressions used in the configuration. + +@defvar {Scheme Variable} guix-build-coordinator-service-type +Service type for the Guix Build Coordinator. Its value must be a +@code{guix-build-coordinator-configuration} object. +@end defvar + +@deftp {Data Type} guix-build-coordinator-configuration +Data type representing the configuration of the Guix Build Coordinator. + +@table @asis +@item @code{package} (default: @code{guix-build-coordinator}) +The Guix Build Coordinator package to use. + +@item @code{user} (default: @code{"guix-build-coordinator"}) +The system user to run the service as. + +@item @code{group} (default: @code{"guix-build-coordinator"}) +The system group to run the service as. + +@item @code{database-uri-string} (default: @code{"sqlite:///var/lib/guix-build-coordinator/guix_build_coordinator.db"}) +The URI to use for the database. + +@item @code{agent-communication-uri} (default: @code{"http://0.0.0.0:8745"}) +The URI describing how to listen to requests from agent processes. + +@item @code{client-communication-uri} (default: @code{"http://127.0.0.1:8746"}) +The URI describing how to listen to requests from clients. The client +API allows submitting builds and currently isn't authenticated, so take +care when configuring this value. + +@item @code{allocation-strategy} (default: @code{#~basic-build-allocation-strategy}) +A G-expression for the allocation strategy to be used. This is a +procedure that takes the datastore as an argument and populates the +allocation plan in the database. + +@item @code{hooks} (default: @var{'()}) +An association list of hooks. These provide a way to execute arbitrary +code upon certian events, like a build result being processed. + +@item @code{guile} (default: @code{guile-3.0-latest}) +The Guile package with which to run the Guix Build Coordinator. + +@end table +@end deftp + @subsubheading Guix Data Service The @uref{http://data.guix.gnu.org,Guix Data Service} processes, stores and provides data about GNU Guix. This includes information about diff --git a/gnu/services/guix.scm b/gnu/services/guix.scm index 10a8581a62..de14fcadb2 100644 --- a/gnu/services/guix.scm +++ b/gnu/services/guix.scm @@ -17,20 +17,40 @@ ;;; along with GNU Guix. If not, see . (define-module (gnu services guix) + #:use-module (srfi srfi-1) #:use-module (ice-9 match) #:use-module (guix gexp) #:use-module (guix records) + #:use-module (guix packages) #:use-module ((gnu packages base) #:select (glibc-utf8-locales)) #:use-module (gnu packages admin) + #:use-module (gnu packages databases) #:use-module (gnu packages web) + #:use-module (gnu packages guile) + #:use-module (gnu packages guile-xyz) + #:use-module (gnu packages package-management) #:use-module (gnu services) #:use-module (gnu services base) #:use-module (gnu services admin) #:use-module (gnu services shepherd) #:use-module (gnu services getmail) #:use-module (gnu system shadow) - #:export ( + #:export (guix-build-coordinator-configuration + guix-build-coordinator-configuration? + guix-build-coordinator-configuration-package + guix-build-coordinator-configuration-user + guix-build-coordinator-configuration-group + guix-build-coordinator-configuration-datastore-uri-string + guix-build-coordinator-configuration-agent-communication-uri-string + guix-build-coordinator-configuration-client-communication-uri-string + guix-build-coordinator-configuration-allocation-strategy + guix-build-coordinator-configuration-hooks + guix-build-coordinator-configuration-guile + + guix-build-coordinator-service-type + + guix-data-service-configuration guix-data-service-configuration? guix-data-service-package @@ -45,11 +65,189 @@ ;;;; Commentary: ;;; -;;; This module implements a service that to run instances of the Guix Data -;;; Service, which provides data about Guix over time. +;;; Services specifically related to GNU Guix. ;;; ;;;; Code: +(define-record-type* + guix-build-coordinator-configuration make-guix-build-coordinator-configuration + guix-build-coordinator-configuration? + (package guix-build-coordinator-configuration-package + (default guix-build-coordinator)) + (user guix-build-coordinator-configuration-user + (default "guix-build-coordinator")) + (group guix-build-coordinator-configuration-group + (default "guix-build-coordinator")) + (database-uri-string + guix-build-coordinator-configuration-datastore-uri-string + (default "sqlite:///var/lib/guix-build-coordinator/guix_build_coordinator.db")) + (agent-communication-uri-string + guix-build-coordinator-configuration-agent-communication-uri-string + (default "http://0.0.0.0:8745")) + (client-communication-uri-string + guix-build-coordinator-configuration-client-communication-uri-string + (default "http://127.0.0.1:8746")) + (allocation-strategy + guix-build-coordinator-configuration-allocation-strategy + (default #~basic-build-allocation-strategy)) + (hooks guix-build-coordinator-configuration-hooks + (default '())) + (guile guix-build-coordinator-configuration-guile + (default guile-3.0-latest))) + +(define* (make-guix-build-coordinator-start-script database-uri-string + allocation-strategy + pid-file + guix-build-coordinator-package + #:key + agent-communication-uri-string + client-communication-uri-string + (hooks '()) + (guile guile-3.0)) + (program-file + "start-guix-build-coordinator" + (with-extensions (cons guix-build-coordinator-package + ;; This is a poorly constructed Guile load path, + ;; since it contains things that aren't Guile + ;; libraries, but it means that the Guile libraries + ;; needed for the Guix Build Coordinator don't need + ;; to be individually specified here. + (map second (package-inputs + guix-build-coordinator-package))) + #~(begin + (use-modules (srfi srfi-1) + (ice-9 match) + (web uri) + (prometheus) + (guix-build-coordinator hooks) + (guix-build-coordinator datastore) + (guix-build-coordinator build-allocator) + (guix-build-coordinator coordinator)) + + ;; Otherwise sqitch can't use SQlite + (setenv "PERL5LIB" + #$(file-append perl-dbd-sqlite "/lib/perl5/site_perl")) + + (let* ((metrics-registry (make-metrics-registry + #:namespace + "guixbuildcoordinator_")) + (datastore (database-uri->datastore + #$database-uri-string + #:metrics-registry metrics-registry)) + (hooks + (list #$@(map (match-lambda + ((name . hook-gexp) + #~(cons name #$hook-gexp))) + hooks))) + (hooks-with-defaults + `(,@hooks + ,@(remove (match-lambda + ((name . _) (assq-ref hooks name))) + %default-hooks))) + (build-coordinator (make-build-coordinator + #:datastore datastore + #:hooks hooks-with-defaults + #:metrics-registry metrics-registry + #:allocation-strategy #$allocation-strategy))) + + (run-coordinator-service + build-coordinator + #:update-datastore? #t + #:pid-file #$pid-file + #:agent-communication-uri (string->uri + #$agent-communication-uri-string) + #:client-communication-uri (string->uri + #$client-communication-uri-string))))) + #:guile guile)) + +(define (guix-build-coordinator-shepherd-services config) + (match-record config + (package user group database-uri-string + agent-communication-uri-string + client-communication-uri-string + allocation-strategy + hooks + guile) + (list + (shepherd-service + (documentation "Guix Build Coordinator") + (provision '(guix-build-coordinator)) + (requirement '(networking)) + (start #~(make-forkexec-constructor + (list #$(make-guix-build-coordinator-start-script + database-uri-string + allocation-strategy + "/var/run/guix-build-coordinator/pid" + package + #:agent-communication-uri-string + agent-communication-uri-string + #:client-communication-uri-string + client-communication-uri-string + #:hooks hooks + #:guile guile)) + #:user #$user + #:group #$group + #:pid-file "/var/run/guix-build-coordinator/pid" + ;; Allow time for migrations to run + #:pid-file-timeout 60 + #:environment-variables + `(,(string-append + "GUIX_LOCPATH=" #$glibc-utf8-locales "/lib/locale") + "LC_ALL=en_US.utf8") + #:log-file "/var/log/guix-build-coordinator/coordinator.log")) + (stop #~(make-kill-destructor)))))) + +(define (guix-build-coordinator-activation config) + #~(begin + (use-modules (guix build utils)) + + (define %user (getpw "guix-build-coordinator")) + + (chmod "/var/lib/guix-build-coordinator" #o755) + + (mkdir-p "/var/log/guix-build-coordinator") + + ;; Allow writing the PID file + (mkdir-p "/var/run/guix-build-coordinator") + (chown "/var/run/guix-build-coordinator" + (passwd:uid %user) + (passwd:gid %user)))) + +(define (guix-build-coordinator-account config) + (match-record config + (user group) + (list (user-group + (name group) + (system? #t)) + (user-account + (name user) + (group group) + (system? #t) + (comment "Guix Build Coordinator user") + (home-directory "/var/lib/guix-build-coordinator") + (shell (file-append shadow "/sbin/nologin")))))) + +(define guix-build-coordinator-service-type + (service-type + (name 'guix-build-coordinator) + (extensions + (list + (service-extension shepherd-root-service-type + guix-build-coordinator-shepherd-services) + (service-extension activation-service-type + guix-build-coordinator-activation) + (service-extension account-service-type + guix-build-coordinator-account))) + (default-value + (guix-build-coordinator-configuration)) + (description + "Run an instance of the Guix Build Coordinator."))) + + +;;; +;;; Guix Data Service +;;; + (define-record-type* guix-data-service-configuration make-guix-data-service-configuration guix-data-service-configuration? diff --git a/gnu/tests/guix.scm b/gnu/tests/guix.scm index 6139e31cf0..20b67d55d3 100644 --- a/gnu/tests/guix.scm +++ b/gnu/tests/guix.scm @@ -35,7 +35,80 @@ #:use-module (guix store) #:use-module (guix utils) #:use-module (ice-9 match) - #:export (%test-guix-data-service)) + #:export (%test-guix-build-coordinator + %test-guix-data-service)) + +;;; +;;; Guix Build Coordinator +;;; + +(define %guix-build-coordinator-os + (simple-operating-system + (service dhcp-client-service-type) + (service guix-build-coordinator-service-type))) + +(define (run-guix-build-coordinator-test) + (define os + (marionette-operating-system + %guix-build-coordinator-os + #:imported-modules '((gnu services herd) + (guix combinators)))) + + (define forwarded-port 8745) + + (define vm + (virtual-machine + (operating-system os) + (memory-size 1024) + (port-forwardings `((,forwarded-port . 8745))))) + + (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 "guix-build-coordinator") + + (test-assert "service running" + (marionette-eval + '(begin + (use-modules (gnu services herd)) + (match (start-service 'guix-build-coordinator) + (#f #f) + (('service response-parts ...) + (match (assq-ref response-parts 'running) + ((pid) (number? pid)))))) + marionette)) + + (test-equal "http-get" + 200 + (let-values + (((response text) + (http-get #$(simple-format + #f "http://localhost:~A/metrics" forwarded-port) + #:decode-body? #t))) + (response-code response))) + + (test-end) + (exit (= (test-runner-fail-count (test-runner-current)) 0))))) + + (gexp->derivation "guix-build-coordinator-test" test)) + +(define %test-guix-build-coordinator + (system-test + (name "guix-build-coordinator") + (description "Connect to a running Guix Build Coordinator.") + (value (run-guix-build-coordinator-test)))) ;;; -- 2.28.0