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
wip/yesman
Alexey Lebedeff 6 years ago committed by Profpatsch
parent a6ff5865d1
commit afa2be4464
  1. 90
      nixos/modules/services/amqp/rabbitmq.nix

@ -4,14 +4,18 @@ with lib;
let
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 {
###### interface
options = {
services.rabbitmq = {
enable = mkOption {
default = false;
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 {
default = "127.0.0.1";
example = "";
@ -30,6 +43,10 @@ in {
<literal>guest</literal> with password
<literal>guest</literal> by default, so you should delete
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;
};
@ -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 {
default = "";
type = types.str;
description = ''
Verbatim configuration file contents.
Verbatim advanced configuration file contents.
Prefered way is to use configItems.
See http://www.rabbitmq.com/configure.html
'';
};
@ -74,6 +109,12 @@ in {
type = types.listOf types.str;
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
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 = {
description = "RabbitMQ server user";
@ -93,44 +137,54 @@ in {
users.groups.rabbitmq.gid = config.ids.gids.rabbitmq;
services.rabbitmq.configItems = {
"listeners.tcp.1" = mkDefault "${cfg.listenAddress}:${toString cfg.port}";
};
systemd.services.rabbitmq = {
description = "RabbitMQ Server";
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 = {
RABBITMQ_MNESIA_BASE = "${cfg.dataDir}/mnesia";
RABBITMQ_NODE_IP_ADDRESS = cfg.listenAddress;
RABBITMQ_NODE_PORT = toString cfg.port;
RABBITMQ_LOGS = "-";
RABBITMQ_SASL_LOGS = "-";
RABBITMQ_PID_FILE = "${cfg.dataDir}/pid";
SYS_PREFIX = "";
RABBITMQ_CONFIG_FILE = config_file;
RABBITMQ_PLUGINS_DIR = concatStringsSep ":" cfg.pluginDirs;
RABBITMQ_ENABLED_PLUGINS_FILE = pkgs.writeText "enabled_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 = {
ExecStart = "${pkgs.rabbitmq_server}/sbin/rabbitmq-server";
ExecStop = "${pkgs.rabbitmq_server}/sbin/rabbitmqctl stop";
PermissionsStartOnly = true; # preStart must be run as root
ExecStart = "${cfg.package}/sbin/rabbitmq-server";
ExecStop = "${cfg.package}/sbin/rabbitmqctl shutdown";
User = "rabbitmq";
Group = "rabbitmq";
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 = ''
${optionalString (cfg.cookie != "") ''
echo -n ${cfg.cookie} > ${cfg.dataDir}/.erlang.cookie
chown rabbitmq:rabbitmq ${cfg.dataDir}/.erlang.cookie
chmod 600 ${cfg.dataDir}/.erlang.cookie
''}
mkdir -p /var/log/rabbitmq
chown rabbitmq:rabbitmq /var/log/rabbitmq
'';
};

Loading…
Cancel
Save