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