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>
This commit is contained in:
wrobell 2025-06-18 21:41:36 +01:00 committed by Sharlatan Hellseher
parent 27c3c7c4ed
commit c65da197cf
No known key found for this signature in database
GPG key ID: 76D727BFF62CD2B5
4 changed files with 317 additions and 0 deletions

View file

@ -141,6 +141,7 @@ Copyright @copyright{} 2025 Zacchaeus@*
Copyright @copyright{} 2025 Sergio Pastor Pérez@* Copyright @copyright{} 2025 Sergio Pastor Pérez@*
Copyright @copyright{} 2024 Evgeny Pisemsky@* Copyright @copyright{} 2024 Evgeny Pisemsky@*
Copyright @copyright{} 2025 jgart@* Copyright @copyright{} 2025 jgart@*
Copyright @copyright{} 2025 Artur Wroblewski@*
Permission is granted to copy, distribute and/or modify this document Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.3 or under the terms of the GNU Free Documentation License, Version 1.3 or
@ -420,6 +421,7 @@ Services
* Kerberos Services:: Kerberos services. * Kerberos Services:: Kerberos services.
* LDAP Services:: LDAP services. * LDAP Services:: LDAP services.
* Web Services:: Web servers. * Web Services:: Web servers.
* High Availability Services:: High availability services.
* Certificate Services:: TLS certificates via Let's Encrypt. * Certificate Services:: TLS certificates via Let's Encrypt.
* DNS Services:: DNS daemons. * DNS Services:: DNS daemons.
* VNC Services:: VNC daemons. * VNC Services:: VNC daemons.
@ -19508,6 +19510,7 @@ declaration.
* Kerberos Services:: Kerberos services. * Kerberos Services:: Kerberos services.
* LDAP Services:: LDAP services. * LDAP Services:: LDAP services.
* Web Services:: Web servers. * Web Services:: Web servers.
* High Availability Services:: High availability services.
* Certificate Services:: TLS certificates via Let's Encrypt. * Certificate Services:: TLS certificates via Let's Encrypt.
* DNS Services:: DNS daemons. * DNS Services:: DNS daemons.
* VNC Services:: VNC daemons. * VNC Services:: VNC daemons.
@ -35664,6 +35667,67 @@ The file which should store the logging output of Agate.
@end table @end table
@end deftp @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 @node Certificate Services
@subsection Certificate Services @subsection Certificate Services

View file

@ -784,6 +784,7 @@ GNU_SYSTEM_MODULES = \
%D%/services/sound.scm \ %D%/services/sound.scm \
%D%/services/herd.scm \ %D%/services/herd.scm \
%D%/services/pm.scm \ %D%/services/pm.scm \
%D%/services/high-availability.scm \
%D%/services/rsync.scm \ %D%/services/rsync.scm \
%D%/services/samba.scm \ %D%/services/samba.scm \
%D%/services/sddm.scm \ %D%/services/sddm.scm \
@ -868,6 +869,7 @@ GNU_SYSTEM_MODULES = \
%D%/tests/ganeti.scm \ %D%/tests/ganeti.scm \
%D%/tests/gdm.scm \ %D%/tests/gdm.scm \
%D%/tests/guix.scm \ %D%/tests/guix.scm \
%D%/tests/high-availability.scm \
%D%/tests/monitoring.scm \ %D%/tests/monitoring.scm \
%D%/tests/nfs.scm \ %D%/tests/nfs.scm \
%D%/tests/image.scm \ %D%/tests/image.scm \

View file

@ -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))))

View file

@ -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))))