diff options
author | wrobell <wrobell@riseup.net> | 2025-06-18 21:41:36 +0100 |
---|---|---|
committer | Sharlatan Hellseher <sharlatanus@gmail.com> | 2025-07-19 01:47:50 +0100 |
commit | c65da197cfb21ef1d2cb16c78c737a814fb1e43c (patch) | |
tree | b2ff16fb32d3ce3b3a58eadac2e473b36eb73bec | |
parent | 27c3c7c4ed6c2ad027d0a45c1a8cd77abe984f41 (diff) |
services: Add rabbitmq service.
* gnu/services/high-availability.scm (<rabbitmq-configuration>): New record.
(rabbitmq-shepherd-service): New procedure.
(rabbitmq-service-type): New variable.
* gnu/tests/high-availability.scm (run-rabbitmq-test): New procedure.
(%rabbitmq-os, %tests-rabbitmq): New variables.
* doc/gnu.texi (High Availability Services): Document it.
Change-Id: I53e9f2881b6340e1ed314785e4c5529b81381a3b
Co-authored-by: Christopher Baines <mail@cbaines.net>
Reviewed-by: Ludovic Courtès <ludo@gnu.org>
Signed-off-by: Sharlatan Hellseher <sharlatanus@gmail.com>
-rw-r--r-- | doc/guix.texi | 64 | ||||
-rw-r--r-- | gnu/local.mk | 2 | ||||
-rw-r--r-- | gnu/services/high-availability.scm | 146 | ||||
-rw-r--r-- | gnu/tests/high-availability.scm | 105 |
4 files changed, 317 insertions, 0 deletions
diff --git a/doc/guix.texi b/doc/guix.texi index 6136971693..283d24af97 100644 --- a/doc/guix.texi +++ b/doc/guix.texi @@ -141,6 +141,7 @@ Copyright @copyright{} 2025 Zacchaeus@* Copyright @copyright{} 2025 Sergio Pastor Pérez@* Copyright @copyright{} 2024 Evgeny Pisemsky@* Copyright @copyright{} 2025 jgart@* +Copyright @copyright{} 2025 Artur Wroblewski@* Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.3 or @@ -420,6 +421,7 @@ Services * Kerberos Services:: Kerberos services. * LDAP Services:: LDAP services. * Web Services:: Web servers. +* High Availability Services:: High availability services. * Certificate Services:: TLS certificates via Let's Encrypt. * DNS Services:: DNS daemons. * VNC Services:: VNC daemons. @@ -19508,6 +19510,7 @@ declaration. * Kerberos Services:: Kerberos services. * LDAP Services:: LDAP services. * Web Services:: Web servers. +* High Availability Services:: High availability services. * Certificate Services:: TLS certificates via Let's Encrypt. * DNS Services:: DNS daemons. * VNC Services:: VNC daemons. @@ -35664,6 +35667,67 @@ The file which should store the logging output of Agate. @end table @end deftp +@node High Availability Services +@subsection High Availability Services + +@cindex Message broker +@cindex Message streaming +The @code{(gnu services high-availability)} module provides RabbitMQ +message broker service. + +@anchor{RabbitMQ} +@subsubheading RabbitMQ + +@defvar rabbitmq-service-type +Service type for the @uref{https://www.rabbitmq.com/,RabbitMQ} web server. +The value for this service type is a @code{<rabbitmq-configuration>} record. + +A simple example configuration is given below. + +@lisp +(service rabbitmq-service-type + (rabbitmq-configuration + (rabbitmq-configuration + (plugins '("rabbitmq_stream" + "rabbitmq_management" + "rabbitmq_prometheus"))))) +@end lisp +@end defvar + +At startup, RabbitMQ broker logs its initialization messages into +@file{/var/log/messages} file. Once running, the logging messages can be +found in a logging file of a RabbitMQ node in @file{/var/log/rabbitmq} +directory. + +@quotation Note +The default configuration of the RabbitMQ service enables the RabbitMQ +broker to accept connections only on loopback interfaces. However, +enabling certain plugins may open ports on all network interfaces. See +also @url{https://www.rabbitmq.com/docs/networking#ports, RabbitMQ Port Access}. +@end quotation + +@deftp {Data Type} rabbitmq-configuration +This data type represents the configuration for RabbitMQ. + +@table @asis +@item @code{rabbitmq} (default: @code{rabbitmq}) +The RabbitMQ package to use. + +@item @code{config-file} (default: @code{%default-rabbitmq-config-file}) +Configuration file for the RabbitMQ broker. See also +@url{https://www.rabbitmq.com/docs/configure, RabbitMQ Configuration}. + +@item @code{data-directory} (default: @code{"/var/lib/rabbitmq/data"}) +Directory with RabbitMQ broker data - a schema database, message stores, +cluster member information, and other persistent node state. + +@item @code{plugins} (default: @code{'()}) +A list of RabbitMQ plugins to enable. View all available plugins using +the @command{rabbitmq-plugins list} command. + +@end table +@end deftp + @node Certificate Services @subsection Certificate Services diff --git a/gnu/local.mk b/gnu/local.mk index da69d6c6c1..bae630ff60 100644 --- a/gnu/local.mk +++ b/gnu/local.mk @@ -784,6 +784,7 @@ GNU_SYSTEM_MODULES = \ %D%/services/sound.scm \ %D%/services/herd.scm \ %D%/services/pm.scm \ + %D%/services/high-availability.scm \ %D%/services/rsync.scm \ %D%/services/samba.scm \ %D%/services/sddm.scm \ @@ -868,6 +869,7 @@ GNU_SYSTEM_MODULES = \ %D%/tests/ganeti.scm \ %D%/tests/gdm.scm \ %D%/tests/guix.scm \ + %D%/tests/high-availability.scm \ %D%/tests/monitoring.scm \ %D%/tests/nfs.scm \ %D%/tests/image.scm \ diff --git a/gnu/services/high-availability.scm b/gnu/services/high-availability.scm new file mode 100644 index 0000000000..0bca111144 --- /dev/null +++ b/gnu/services/high-availability.scm @@ -0,0 +1,146 @@ +;;; GNU Guix --- Functional package management for GNU +;;; Copyright © 2018 Christopher Baines <mail@cbaines.net> +;;; Copyright © 2025 Artur Wroblewski <wrobell@riseup.net> +;;; +;;; 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 <http://www.gnu.org/licenses/>. + +(define-module (gnu services high-availability) + #:use-module (gnu packages admin) + #:use-module (gnu packages high-availability) + #:use-module (gnu services) + #:use-module (gnu services shepherd) + #:use-module (gnu system shadow) + #:use-module (guix gexp) + #:use-module (guix modules) + #:use-module (guix records) + #:use-module (ice-9 match) + #:use-module (ice-9 format) + + #:export (rabbitmq-configuration rabbitmq-configuration? + rabbitmq-configuration-rabbitmq + rabbitmq-configuration-config-file + rabbitmq-configuration-plugins + rabbitmq-service-type)) + +;; By default, start on local ipv4 and ipv6 interfaces only, see also: +;; +;; https://www.rabbitmq.com/docs/networking +;; +;; NOTE: How to enable plugins to listen on localhost only? +(define %default-rabbitmq-config-file + (plain-file "rabbitmq.conf" " +listeners.tcp.1 = 127.0.0.1:5672 +listeners.tcp.2 = ::1:5672 +")) + +(define-record-type* <rabbitmq-configuration> rabbitmq-configuration + make-rabbitmq-configuration + rabbitmq-configuration? + (rabbitmq rabbitmq-configuration-rabbitmq + (default rabbitmq)) + (config-file rabbitmq-configuration-config-file + (default %default-rabbitmq-config-file)) + ;; It can be a mnesia database or a khepri database, so use "data" instead + ;; of the traditional "mnesia". + (data-directory rabbitmq-configuration-data-directory + (default "/var/lib/rabbitmq/data")) + (plugins rabbitmq-configuration-plugins + (default '()))) + +(define %rabbitmq-accounts + (list (user-group + (name "rabbitmq") + (system? #t)) + (user-account + (name "rabbitmq") + (group "rabbitmq") + (system? #t) + (comment "RabbitMQ server user") + (home-directory "/var/lib/rabbitmq") + (shell (file-append shadow "/sbin/nologin"))))) + +(define (rabbitmq-activation config) + (let* ((data-directory (rabbitmq-configuration-data-directory config)) + (plugins (string-join (rabbitmq-configuration-plugins config) ","))) + (with-imported-modules '((guix build utils)) + #~(begin + (use-modules (guix build utils)) + (let ((user (getpwnam "rabbitmq")) + (srv-directories (list + "/var/lib/rabbitmq" + "/var/log/rabbitmq" + "/var/run/rabbitmq" + #$data-directory))) + (for-each (lambda (directory) + (mkdir-p directory) + (chown directory + (passwd:uid user) + (passwd:gid user))) + srv-directories) + + ;; Create file with the enabled plugins. + (with-output-to-file (string-append #$data-directory + "/enabled_plugins") + (lambda () (display (format #f "[~a]." #$plugins)))) + (chown (string-append #$data-directory "/enabled_plugins") + (passwd:uid user) + (passwd:gid user))))))) + +(define (rabbitmq-shepherd-service config) + (match-record config <rabbitmq-configuration> + (rabbitmq data-directory config-file plugins) + (with-imported-modules + (source-module-closure '((gnu build shepherd))) + (list + (shepherd-service + (provision '(rabbitmq)) + (documentation "Run the RabbitMQ daemon.") + (requirement '(user-processes loopback)) + (modules '((gnu build shepherd))) + (start + #~(make-forkexec-constructor + `(#$(file-append rabbitmq "/sbin/rabbitmq-server")) + #:pid-file "/var/run/rabbitmq/pid" + #:user "rabbitmq" + #:group "rabbitmq" + #:environment-variables + (append + (list + (string-append "RABBITMQ_CONFIG_FILE=" #$config-file) + "RABBITMQ_PID_FILE=/var/run/rabbitmq/pid" + "RABBITMQ_CONF_ENV_FILE=/run/current-system/profile/etc/rabbitmq/rabbitmq-env.conf" + (string-append + "RABBITMQ_ENABLED_PLUGINS_FILE=" + #$data-directory + "/enabled_plugins") + (string-append + "RABBITMQ_MNESIA_BASE=" + #$data-directory) + "RABBITMQ_LOG_BASE=/var/log/rabbitmq") + (environ)))) + (stop #~(make-kill-destructor))))))) + +(define rabbitmq-service-type + (service-type (name 'rabbitmq) + (description "Run the RabbitMQ message broker service.") + (extensions (list (service-extension + shepherd-root-service-type + rabbitmq-shepherd-service) + (service-extension activation-service-type + rabbitmq-activation) + (service-extension account-service-type + (const %rabbitmq-accounts)))) + (default-value (rabbitmq-configuration)))) diff --git a/gnu/tests/high-availability.scm b/gnu/tests/high-availability.scm new file mode 100644 index 0000000000..591e5f5bc2 --- /dev/null +++ b/gnu/tests/high-availability.scm @@ -0,0 +1,105 @@ +;;; GNU Guix --- Functional package management for GNU +;;; Copyright © 2017 Christopher Baines <mail@cbaines.net> +;;; Copyright © 2025 Artur Wroblewski <wrobell@riseup.net> +;;; +;;; 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 <http://www.gnu.org/licenses/>. + +(define-module (gnu tests high-availability) + #: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 high-availability) + #:use-module (gnu services networking) + #:use-module (guix gexp) + #:use-module (guix store) + #:export (%test-rabbitmq)) + +(define %rabbitmq-config-file + (plain-file "rabbitmq.conf" " +listeners.tcp.1 = 127.0.0.1:15672 +listeners.tcp.2 = ::1:15672 +")) + +(define %rabbitmq-os + (simple-operating-system + (service rabbitmq-service-type + (rabbitmq-configuration (config-file %rabbitmq-config-file))))) + +(define* (run-rabbitmq-test #:key (rabbitmq-port 15672)) + "Run tests in %RABBITMQ-OS, forwarding PORT." + (define os + (marionette-operating-system + %rabbitmq-os + #:imported-modules '((gnu services herd) + (guix combinators)))) + + (define forwarded-port 15672) + + (define vm + (virtual-machine + (operating-system os) + (memory-size 512) + (port-forwardings `((,rabbitmq-port . ,forwarded-port))))) + + (define test + (with-imported-modules '((gnu build marionette)) + #~(begin + (use-modules (srfi srfi-64) + (gnu build marionette) + (ice-9 rdelim)) + + (define marionette + (make-marionette (list #$vm))) + + (mkdir #$output) + (chdir #$output) + + (test-runner-current (system-test-runner #$output)) + (test-begin "rabbitmq") + + ;; Wait for RabbitMQ broker to be up and running. + (test-assert "service running" + (marionette-eval + '(begin + (use-modules (gnu services herd)) + (match (start-service 'rabbitmq) + (#f #f) + (('service response-parts ...) + (match (assq-ref response-parts 'running) + ((#t) #t) + ((pid) pid))))) + marionette)) + + (test-assert "RabbitMQ port ready" + (wait-for-tcp-port #$forwarded-port marionette)) + + (test-assert "RabbitMQ log file exists" + (marionette-eval + '(file-exists? "/var/log/rabbitmq/rabbit@komputilo.log") + marionette)) + + (test-end)))) + + (gexp->derivation "rabbitmq-test" test)) + +(define %test-rabbitmq + (system-test + (name "rabbitmq") + (description "Connect to a running RABBITMQ server.") + (value (run-rabbitmq-test)))) |