From afa2be4464f3dd17577523487cc09f5f411863bc Mon Sep 17 00:00:00 2001 From: Alexey Lebedeff Date: Mon, 24 Sep 2018 15:31:16 +0200 Subject: 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 --- nixos/modules/services/amqp/rabbitmq.nix | 90 +++++++++++++++++++++++++------- 1 file changed, 72 insertions(+), 18 deletions(-) (limited to 'nixos') diff --git a/nixos/modules/services/amqp/rabbitmq.nix b/nixos/modules/services/amqp/rabbitmq.nix index bb6fc0a104df..c6878dd67dbf 100644 --- a/nixos/modules/services/amqp/rabbitmq.nix +++ b/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 { guest with password guest 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 ''; }; -- cgit 1.4.1