python3Packages.orjson: Disable failing tests on 32 bit
[NixPkgs.git] / nixos / modules / services / amqp / rabbitmq.nix
blob11dabf0b51c80ed2748e79d04f2d35b98cbd5273
1 { config, lib, pkgs, ... }:
3 with lib;
5 let
6   cfg = config.services.rabbitmq;
8   inherit (builtins) concatStringsSep;
10   config_file_content = lib.generators.toKeyValue { } cfg.configItems;
11   config_file = pkgs.writeText "rabbitmq.conf" config_file_content;
13   advanced_config_file = pkgs.writeText "advanced.config" cfg.config;
17   ###### interface
18   options = {
19     services.rabbitmq = {
20       enable = mkOption {
21         type = types.bool;
22         default = false;
23         description = lib.mdDoc ''
24           Whether to enable the RabbitMQ server, an Advanced Message
25           Queuing Protocol (AMQP) broker.
26         '';
27       };
29       package = mkOption {
30         default = pkgs.rabbitmq-server;
31         type = types.package;
32         defaultText = literalExpression "pkgs.rabbitmq-server";
33         description = lib.mdDoc ''
34           Which rabbitmq package to use.
35         '';
36       };
38       listenAddress = mkOption {
39         default = "127.0.0.1";
40         example = "";
41         description = lib.mdDoc ''
42           IP address on which RabbitMQ will listen for AMQP
43           connections.  Set to the empty string to listen on all
44           interfaces.  Note that RabbitMQ creates a user named
45           `guest` with password
46           `guest` by default, so you should delete
47           this user if you intend to allow external access.
49           Together with 'port' setting it's mostly an alias for
50           configItems."listeners.tcp.1" and it's left for backwards
51           compatibility with previous version of this module.
52         '';
53         type = types.str;
54       };
56       port = mkOption {
57         default = 5672;
58         description = lib.mdDoc ''
59           Port on which RabbitMQ will listen for AMQP connections.
60         '';
61         type = types.port;
62       };
64       dataDir = mkOption {
65         type = types.path;
66         default = "/var/lib/rabbitmq";
67         description = lib.mdDoc ''
68           Data directory for rabbitmq.
69         '';
70       };
72       cookie = mkOption {
73         default = "";
74         type = types.str;
75         description = lib.mdDoc ''
76           Erlang cookie is a string of arbitrary length which must
77           be the same for several nodes to be allowed to communicate.
78           Leave empty to generate automatically.
79         '';
80       };
82       configItems = mkOption {
83         default = { };
84         type = types.attrsOf types.str;
85         example = literalExpression ''
86           {
87             "auth_backends.1.authn" = "rabbit_auth_backend_ldap";
88             "auth_backends.1.authz" = "rabbit_auth_backend_internal";
89           }
90         '';
91         description = lib.mdDoc ''
92           Configuration options in RabbitMQ's new config file format,
93           which is a simple key-value format that can not express nested
94           data structures. This is known as the `rabbitmq.conf` file,
95           although outside NixOS that filename may have Erlang syntax, particularly
96           prior to RabbitMQ 3.7.0.
98           If you do need to express nested data structures, you can use
99           `config` option. Configuration from `config`
100           will be merged into these options by RabbitMQ at runtime to
101           form the final configuration.
103           See https://www.rabbitmq.com/configure.html#config-items
104           For the distinct formats, see https://www.rabbitmq.com/configure.html#config-file-formats
105         '';
106       };
108       config = mkOption {
109         default = "";
110         type = types.str;
111         description = lib.mdDoc ''
112           Verbatim advanced configuration file contents using the Erlang syntax.
113           This is also known as the `advanced.config` file or the old config format.
115           `configItems` is preferred whenever possible. However, nested
116           data structures can only be expressed properly using the `config` option.
118           The contents of this option will be merged into the `configItems`
119           by RabbitMQ at runtime to form the final configuration.
121           See the second table on https://www.rabbitmq.com/configure.html#config-items
122           For the distinct formats, see https://www.rabbitmq.com/configure.html#config-file-formats
123         '';
124       };
126       plugins = mkOption {
127         default = [ ];
128         type = types.listOf types.str;
129         description = lib.mdDoc "The names of plugins to enable";
130       };
132       pluginDirs = mkOption {
133         default = [ ];
134         type = types.listOf types.path;
135         description = lib.mdDoc "The list of directories containing external plugins";
136       };
138       managementPlugin = {
139         enable = mkEnableOption (lib.mdDoc "the management plugin");
140         port = mkOption {
141           default = 15672;
142           type = types.port;
143           description = lib.mdDoc ''
144             On which port to run the management plugin
145           '';
146         };
147       };
148     };
149   };
152   ###### implementation
153   config = mkIf cfg.enable {
155     # This is needed so we will have 'rabbitmqctl' in our PATH
156     environment.systemPackages = [ cfg.package ];
158     services.epmd.enable = true;
160     users.users.rabbitmq = {
161       description = "RabbitMQ server user";
162       home = "${cfg.dataDir}";
163       createHome = true;
164       group = "rabbitmq";
165       uid = config.ids.uids.rabbitmq;
166     };
168     users.groups.rabbitmq.gid = config.ids.gids.rabbitmq;
170     services.rabbitmq.configItems = {
171       "listeners.tcp.1" = mkDefault "${cfg.listenAddress}:${toString cfg.port}";
172     } // optionalAttrs cfg.managementPlugin.enable {
173       "management.tcp.port" = toString cfg.managementPlugin.port;
174       "management.tcp.ip" = cfg.listenAddress;
175     };
177     services.rabbitmq.plugins = optional cfg.managementPlugin.enable "rabbitmq_management";
179     systemd.services.rabbitmq = {
180       description = "RabbitMQ Server";
182       wantedBy = [ "multi-user.target" ];
183       after = [ "network.target" "epmd.socket" ];
184       wants = [ "network.target" "epmd.socket" ];
186       path = [
187         cfg.package
188         pkgs.coreutils # mkdir/chown/chmod for preStart
189       ];
191       environment = {
192         RABBITMQ_MNESIA_BASE = "${cfg.dataDir}/mnesia";
193         RABBITMQ_LOGS = "-";
194         SYS_PREFIX = "";
195         RABBITMQ_CONFIG_FILE = config_file;
196         RABBITMQ_PLUGINS_DIR = concatStringsSep ":" cfg.pluginDirs;
197         RABBITMQ_ENABLED_PLUGINS_FILE = pkgs.writeText "enabled_plugins" ''
198           [ ${concatStringsSep "," cfg.plugins} ].
199         '';
200       } // optionalAttrs (cfg.config != "") { RABBITMQ_ADVANCED_CONFIG_FILE = advanced_config_file; };
202       serviceConfig = {
203         ExecStart = "${cfg.package}/sbin/rabbitmq-server";
204         ExecStop = "${cfg.package}/sbin/rabbitmqctl shutdown";
205         User = "rabbitmq";
206         Group = "rabbitmq";
207         LogsDirectory = "rabbitmq";
208         WorkingDirectory = cfg.dataDir;
209         Type = "notify";
210         NotifyAccess = "all";
211         UMask = "0027";
212         LimitNOFILE = "100000";
213         Restart = "on-failure";
214         RestartSec = "10";
215         TimeoutStartSec = "3600";
216       };
218       preStart = ''
219         ${optionalString (cfg.cookie != "") ''
220             echo -n ${cfg.cookie} > ${cfg.dataDir}/.erlang.cookie
221             chmod 600 ${cfg.dataDir}/.erlang.cookie
222         ''}
223       '';
224     };
226   };