rabbitmq module: modernize after package upgrade

- Use socket-activated epmd - that way there won't be any trouble when
  more than one erlang system is used within a single host.
- Use new automation-friendly configuration file format
- Use systemd notifications instead of buggy 'rabbitmqctl wait' for
  confirming successful server startup.
  'wait' bug: https://github.com/rabbitmq/rabbitmq-server/issues/463
- Use 'rabbitmqctl shutdown' instead of 'stop', because it's not
  pid-file based
- Use sane systemd unit defaults from RabbitMQ repo:
  https://github.com/rabbitmq/rabbitmq-server/blob/master/docs/rabbitmq-server.service.example
- Support for external plugins
This commit is contained in:
Alexey Lebedeff 2018-09-24 15:31:16 +02:00 committed by Profpatsch
parent a6ff5865d1
commit afa2be4464

View File

@ -4,14 +4,18 @@ with lib;
let let
cfg = config.services.rabbitmq; cfg = config.services.rabbitmq;
config_file = pkgs.writeText "rabbitmq.config" cfg.config;
config_file_wo_suffix = builtins.substring 0 ((builtins.stringLength config_file) - 7) config_file; inherit (builtins) concatStringsSep;
config_file_content = lib.generators.toKeyValue {} cfg.configItems;
config_file = pkgs.writeText "rabbitmq.conf" config_file_content;
advanced_config_file = pkgs.writeText "advanced.config" cfg.config;
in { in {
###### interface ###### interface
options = { options = {
services.rabbitmq = { services.rabbitmq = {
enable = mkOption { enable = mkOption {
default = false; default = false;
description = '' description = ''
@ -20,6 +24,15 @@ in {
''; '';
}; };
package = mkOption {
default = pkgs.rabbitmq-server;
type = types.package;
defaultText = "pkgs.rabbitmq-server";
description = ''
Which rabbitmq package to use.
'';
};
listenAddress = mkOption { listenAddress = mkOption {
default = "127.0.0.1"; default = "127.0.0.1";
example = ""; example = "";
@ -30,6 +43,10 @@ in {
<literal>guest</literal> with password <literal>guest</literal> with password
<literal>guest</literal> by default, so you should delete <literal>guest</literal> by default, so you should delete
this user if you intend to allow external access. this user if you intend to allow external access.
Together with 'port' setting it's mostly an alias for
configItems."listeners.tcp.1" and it's left for backwards
compatibility with previous version of this module.
''; '';
type = types.str; type = types.str;
}; };
@ -60,11 +77,29 @@ in {
''; '';
}; };
configItems = mkOption {
default = {};
type = types.attrsOf types.str;
example = ''
{
"auth_backends.1.authn" = "rabbit_auth_backend_ldap";
"auth_backends.1.authz" = "rabbit_auth_backend_internal";
}
'';
description = ''
New style config options.
See http://www.rabbitmq.com/configure.html
'';
};
config = mkOption { config = mkOption {
default = ""; default = "";
type = types.str; type = types.str;
description = '' description = ''
Verbatim configuration file contents. Verbatim advanced configuration file contents.
Prefered way is to use configItems.
See http://www.rabbitmq.com/configure.html See http://www.rabbitmq.com/configure.html
''; '';
}; };
@ -74,6 +109,12 @@ in {
type = types.listOf types.str; type = types.listOf types.str;
description = "The names of plugins to enable"; description = "The names of plugins to enable";
}; };
pluginDirs = mkOption {
default = [];
type = types.listOf types.path;
description = "The list of directories containing external plugins";
};
}; };
}; };
@ -81,7 +122,10 @@ in {
###### implementation ###### implementation
config = mkIf cfg.enable { config = mkIf cfg.enable {
environment.systemPackages = [ pkgs.rabbitmq_server ]; # This is needed so we will have 'rabbitmqctl' in our PATH
environment.systemPackages = [ cfg.package ];
services.epmd.enable = true;
users.users.rabbitmq = { users.users.rabbitmq = {
description = "RabbitMQ server user"; description = "RabbitMQ server user";
@ -93,44 +137,54 @@ in {
users.groups.rabbitmq.gid = config.ids.gids.rabbitmq; users.groups.rabbitmq.gid = config.ids.gids.rabbitmq;
services.rabbitmq.configItems = {
"listeners.tcp.1" = mkDefault "${cfg.listenAddress}:${toString cfg.port}";
};
systemd.services.rabbitmq = { systemd.services.rabbitmq = {
description = "RabbitMQ Server"; description = "RabbitMQ Server";
wantedBy = [ "multi-user.target" ]; wantedBy = [ "multi-user.target" ];
after = [ "network.target" ]; after = [ "network.target" "epmd.socket" ];
wants = [ "network.target" "epmd.socket" ];
path = [ pkgs.rabbitmq_server pkgs.procps ]; path = [ cfg.package pkgs.procps ];
environment = { environment = {
RABBITMQ_MNESIA_BASE = "${cfg.dataDir}/mnesia"; RABBITMQ_MNESIA_BASE = "${cfg.dataDir}/mnesia";
RABBITMQ_NODE_IP_ADDRESS = cfg.listenAddress;
RABBITMQ_NODE_PORT = toString cfg.port;
RABBITMQ_LOGS = "-"; RABBITMQ_LOGS = "-";
RABBITMQ_SASL_LOGS = "-";
RABBITMQ_PID_FILE = "${cfg.dataDir}/pid";
SYS_PREFIX = ""; SYS_PREFIX = "";
RABBITMQ_CONFIG_FILE = config_file;
RABBITMQ_PLUGINS_DIR = concatStringsSep ":" cfg.pluginDirs;
RABBITMQ_ENABLED_PLUGINS_FILE = pkgs.writeText "enabled_plugins" '' RABBITMQ_ENABLED_PLUGINS_FILE = pkgs.writeText "enabled_plugins" ''
[ ${concatStringsSep "," cfg.plugins} ]. [ ${concatStringsSep "," cfg.plugins} ].
''; '';
} // optionalAttrs (cfg.config != "") { RABBITMQ_CONFIG_FILE = config_file_wo_suffix; }; } // optionalAttrs (cfg.config != "") { RABBITMQ_ADVANCED_CONFIG_FILE = advanced_config_file; };
serviceConfig = { serviceConfig = {
ExecStart = "${pkgs.rabbitmq_server}/sbin/rabbitmq-server"; PermissionsStartOnly = true; # preStart must be run as root
ExecStop = "${pkgs.rabbitmq_server}/sbin/rabbitmqctl stop"; ExecStart = "${cfg.package}/sbin/rabbitmq-server";
ExecStop = "${cfg.package}/sbin/rabbitmqctl shutdown";
User = "rabbitmq"; User = "rabbitmq";
Group = "rabbitmq"; Group = "rabbitmq";
WorkingDirectory = cfg.dataDir; WorkingDirectory = cfg.dataDir;
Type = "notify";
NotifyAccess = "all";
UMask = "0027";
LimitNOFILE = "100000";
Restart = "on-failure";
RestartSec = "10";
TimeoutStartSec = "3600";
}; };
postStart = ''
rabbitmqctl wait ${cfg.dataDir}/pid
'';
preStart = '' preStart = ''
${optionalString (cfg.cookie != "") '' ${optionalString (cfg.cookie != "") ''
echo -n ${cfg.cookie} > ${cfg.dataDir}/.erlang.cookie echo -n ${cfg.cookie} > ${cfg.dataDir}/.erlang.cookie
chown rabbitmq:rabbitmq ${cfg.dataDir}/.erlang.cookie
chmod 600 ${cfg.dataDir}/.erlang.cookie chmod 600 ${cfg.dataDir}/.erlang.cookie
''} ''}
mkdir -p /var/log/rabbitmq
chown rabbitmq:rabbitmq /var/log/rabbitmq
''; '';
}; };