diff options
| author | Michael Klishin <michael@novemberain.com> | 2016-03-24 00:29:04 +0300 |
|---|---|---|
| committer | Michael Klishin <michael@novemberain.com> | 2016-03-24 00:29:04 +0300 |
| commit | 117a20bc2383d6ee841547468fb615f34e4916f5 (patch) | |
| tree | 3c3c3f43ec6506980334d0180cff8fa6a70e79e8 | |
| parent | a5a24d32733e80e0ab1b5383d17bb405bd58d743 (diff) | |
| parent | 2b9b292de4e2f31f49fc9b9e99396aa47c1c8d53 (diff) | |
| download | rabbitmq-server-git-117a20bc2383d6ee841547468fb615f34e4916f5.tar.gz | |
Merge pull request #575 from rabbitmq/rabbitmq-server-550
Support new configuration format
| -rw-r--r-- | Makefile | 11 | ||||
| -rw-r--r-- | docs/advanced.config.example | 109 | ||||
| -rw-r--r-- | docs/rabbitmq.conf.example | 736 | ||||
| -rw-r--r-- | packaging/RPMS/Fedora/rabbitmq-server.spec | 2 | ||||
| -rw-r--r-- | packaging/debs/Debian/debian/postinst | 2 | ||||
| -rw-r--r-- | packaging/windows-exe/rabbitmq_nsi.in | 14 | ||||
| -rw-r--r-- | priv/schema/.gitignore | 4 | ||||
| -rw-r--r-- | priv/schema/rabbitmq.schema | 961 | ||||
| -rw-r--r-- | rabbitmq.conf.d/ldap.conf | 138 | ||||
| -rw-r--r-- | rabbitmq.conf.d/rabbitmq.conf | 726 | ||||
| -rwxr-xr-x | scripts/cuttlefish | bin | 0 -> 430306 bytes | |||
| -rw-r--r-- | scripts/rabbitmq-defaults | 3 | ||||
| -rw-r--r-- | scripts/rabbitmq-defaults.bat | 3 | ||||
| -rw-r--r-- | scripts/rabbitmq-env | 6 | ||||
| -rw-r--r-- | scripts/rabbitmq-env.bat | 29 | ||||
| -rwxr-xr-x | scripts/rabbitmq-server | 24 | ||||
| -rw-r--r-- | scripts/rabbitmq-server.bat | 24 | ||||
| -rw-r--r-- | scripts/rabbitmq-service.bat | 31 | ||||
| -rw-r--r-- | src/rabbit.erl | 42 | ||||
| -rw-r--r-- | src/rabbit_config.erl | 179 | ||||
| -rw-r--r-- | src/rabbit_plugins.erl | 47 | ||||
| -rw-r--r-- | src/rabbit_prelaunch.erl | 12 |
22 files changed, 3058 insertions, 45 deletions
@@ -337,7 +337,8 @@ SCRIPTS = rabbitmq-defaults \ rabbitmq-env \ rabbitmq-server \ rabbitmqctl \ - rabbitmq-plugins + rabbitmq-plugins \ + cuttlefish WINDOWS_SCRIPTS = rabbitmq-defaults.bat \ rabbitmq-echopid.bat \ @@ -345,7 +346,8 @@ WINDOWS_SCRIPTS = rabbitmq-defaults.bat \ rabbitmq-plugins.bat \ rabbitmq-server.bat \ rabbitmq-service.bat \ - rabbitmqctl.bat + rabbitmqctl.bat \ + cuttlefish UNIX_TO_DOS ?= todos @@ -356,7 +358,7 @@ install: install-erlapp install-scripts install-erlapp: dist $(verbose) mkdir -p $(DESTDIR)$(RMQ_ERLAPP_DIR) - $(inst_verbose) cp -r include ebin plugins LICENSE* INSTALL \ + $(inst_verbose) cp -r include ebin plugins priv LICENSE* INSTALL \ $(DESTDIR)$(RMQ_ERLAPP_DIR) $(verbose) echo "Put your EZs here and use rabbitmq-plugins to enable them." \ > $(DESTDIR)$(RMQ_ERLAPP_DIR)/plugins/README @@ -397,7 +399,7 @@ install-windows: install-windows-erlapp install-windows-scripts install-windows- install-windows-erlapp: dist $(verbose) mkdir -p $(DESTDIR)$(WINDOWS_PREFIX) - $(inst_verbose) cp -r include ebin plugins LICENSE* INSTALL \ + $(inst_verbose) cp -r include ebin plugins priv LICENSE* INSTALL \ $(DESTDIR)$(WINDOWS_PREFIX) $(verbose) echo "Put your EZs here and use rabbitmq-plugins.bat to enable them." \ > $(DESTDIR)$(WINDOWS_PREFIX)/plugins/README.txt @@ -450,3 +452,4 @@ package-rpm-suse package-windows package-standalone-macosx \ package-generic-unix: $(PACKAGES_SOURCE_DIST_FILE) $(verbose) $(MAKE) -C packaging $@ \ SOURCE_DIST_FILE=$(abspath $(PACKAGES_SOURCE_DIST_FILE)) + diff --git a/docs/advanced.config.example b/docs/advanced.config.example new file mode 100644 index 0000000000..82a1c000e1 --- /dev/null +++ b/docs/advanced.config.example @@ -0,0 +1,109 @@ +[ + + + %% ---------------------------------------------------------------------------- + %% Advanced Erlang Networking/Clustering Options. + %% + %% See http://www.rabbitmq.com/clustering.html for details + %% ---------------------------------------------------------------------------- + %% Sets the net_kernel tick time. + %% Please see http://erlang.org/doc/man/kernel_app.html and + %% http://www.rabbitmq.com/nettick.html for further details. + %% + %% {kernel, [{net_ticktime, 60}]}, + %% ---------------------------------------------------------------------------- + %% RabbitMQ Shovel Plugin + %% + %% See http://www.rabbitmq.com/shovel.html for details + %% ---------------------------------------------------------------------------- + + {rabbitmq_shovel, + [{shovels, + [%% A named shovel worker. + %% {my_first_shovel, + %% [ + + %% List the source broker(s) from which to consume. + %% + %% {sources, + %% [%% URI(s) and pre-declarations for all source broker(s). + %% {brokers, ["amqp://user:password@host.domain/my_vhost"]}, + %% {declarations, []} + %% ]}, + + %% List the destination broker(s) to publish to. + %% {destinations, + %% [%% A singular version of the 'brokers' element. + %% {broker, "amqp://"}, + %% {declarations, []} + %% ]}, + + %% Name of the queue to shovel messages from. + %% + %% {queue, <<"your-queue-name-goes-here">>}, + + %% Optional prefetch count. + %% + %% {prefetch_count, 10}, + + %% when to acknowledge messages: + %% - no_ack: never (auto) + %% - on_publish: after each message is republished + %% - on_confirm: when the destination broker confirms receipt + %% + %% {ack_mode, on_confirm}, + + %% Overwrite fields of the outbound basic.publish. + %% + %% {publish_fields, [{exchange, <<"my_exchange">>}, + %% {routing_key, <<"from_shovel">>}]}, + + %% Static list of basic.properties to set on re-publication. + %% + %% {publish_properties, [{delivery_mode, 2}]}, + + %% The number of seconds to wait before attempting to + %% reconnect in the event of a connection failure. + %% + %% {reconnect_delay, 2.5} + + %% ]} %% End of my_first_shovel + ]} + %% Rather than specifying some values per-shovel, you can specify + %% them for all shovels here. + %% + %% {defaults, [{prefetch_count, 0}, + %% {ack_mode, on_confirm}, + %% {publish_fields, []}, + %% {publish_properties, [{delivery_mode, 2}]}, + %% {reconnect_delay, 2.5}]} + ]}, + + {rabbitmq_auth_backend_ldap, [ + %% + %% Authorisation + %% ============= + %% + + %% The LDAP plugin can perform a variety of queries against your + %% LDAP server to determine questions of authorisation. See + %% http://www.rabbitmq.com/ldap.html#authorisation for more + %% information. + + %% Set the query to use when determining vhost access + %% + %% {vhost_access_query, {in_group, + %% "ou=${vhost}-users,ou=vhosts,dc=example,dc=com"}}, + + %% Set the query to use when determining resource (e.g., queue) access + %% + %% {resource_access_query, {constant, true}}, + + %% Set queries to determine which tags a user has + %% + %% {tag_queries, []} + ]} +]. + + + diff --git a/docs/rabbitmq.conf.example b/docs/rabbitmq.conf.example new file mode 100644 index 0000000000..5c92165f73 --- /dev/null +++ b/docs/rabbitmq.conf.example @@ -0,0 +1,736 @@ +# ====================================== +# RabbbitMQ broker section +# ====================================== + +## Network Connectivity +## ==================== +## +## By default, RabbitMQ will listen on all interfaces, using +## the standard (reserved) AMQP port. +## +# listeners.tcp.default = 5672 + + +## To listen on a specific interface, provide an IP address with port. +## For example, to listen only on localhost for both IPv4 and IPv6: +## +# IPv4 +# listeners.tcp.local = 127.0.0.1:5672 +# IPv6 +# listeners.tcp.local_v6 = ::1:5672 + +## You can define multiple listeners using listener names +# listeners.tcp.other_port = 5673 +# listeners.tcp.other_ip = 10.10.10.10:5672 + + +## SSL listeners are configured in the same fashion as TCP listeners, +## including the option to control the choice of interface. +## +# listeners.ssl.default = 5671 + +## Number of Erlang processes that will accept connections for the TCP +## and SSL listeners. +## +# num_acceptors.tcp = 10 +# num_acceptors.ssl = 1 + + +## Maximum time for AMQP 0-8/0-9/0-9-1 handshake (after socket connection +## and SSL handshake), in milliseconds. +## +# handshake_timeout = 10000 + +## Set to 'true' to perform reverse DNS lookups when accepting a +## connection. Hostnames will then be shown instead of IP addresses +## in rabbitmqctl and the management plugin. +## +# reverse_dns_lookups = true + +## +## Security / AAA +## ============== +## + +## The default "guest" user is only permitted to access the server +## via a loopback interface (e.g. localhost). +## {loopback_users, [<<"guest">>]}, +## +# loopback_users.guest = true + +## Uncomment the following line if you want to allow access to the +## guest user from anywhere on the network. +# loopback_users.guest = false + +## Configuring SSL. +## See http://www.rabbitmq.com/ssl.html for full documentation. +## +# ssl_options.verify = verify_peer +# ssl_options.fail_if_no_peer_cert = false +# ssl_options.cacertfile = /path/to/cacert.pem +# ssl_options.certfile = /path/to/cert.pem +# ssl_options.keyfile = /path/to/key.pem + +## Select an authentication/authorisation backend to use. +## +## Alternative backends are provided by plugins, such as rabbitmq-auth-backend-ldap. +## +## NB: These settings require certain plugins to be enabled. +## See http://www.rabbitmq.com/plugins.html and http://rabbitmq.com/access-control.html +## for details. + +# auth_backends.1 = rabbit_auth_backend_internal + +## uses separate backends for authentication and authorisation, +## see below. +# auth_backends.1.authn = rabbit_auth_backend_ldap +# auth_backends.1.authz = rabbit_auth_backend_internal + +## The rabbitmq_auth_backend_ldap plugin allows the broker to +## perform authentication and authorisation by deferring to an +## external LDAP server. +## +## For more information about configuring the LDAP backend, see +## http://www.rabbitmq.com/ldap.html and http://rabbitmq.com/access-control.html. +## +## uses LDAP for both authentication and authorisation +# auth_backends.1 = rabbit_auth_backend_ldap + +## uses HTTP service for both authentication and +## authorisation +# auth_backends.1 = rabbit_auth_backend_http + +## uses two backends in a chain: HTTP first, then internal +# auth_backends.1 = rabbit_auth_backend_http +# auth_backends.2 = rabbit_auth_backend_internal + +## Authentication +## The built-in mechanisms are 'PLAIN', +## 'AMQPLAIN', and 'EXTERNAL' Additional mechanisms can be added via +## plugins. +## +## See http://www.rabbitmq.com/authentication.html for more details. +## +# auth_mechanisms.1 = PLAIN +# auth_mechanisms.2 = AMQPLAIN + +## The rabbitmq-auth-mechanism-ssl plugin makes it possible to +## authenticate a user based on the client's x509 (TLS) certificate. +## See http://www.rabbitmq.com/authentication.html for more info. +## +## To use auth-mechanism-ssl, the EXTERNAL mechanism should +## be enabled: +## +# auth_mechanisms.1 = PLAIN +# auth_mechanisms.2 = AMQPLAIN +# auth_mechanisms.3 = EXTERNAL + +## To force x509 certificate-based authentication on all clients, +## exclude all other mechanisms (note: this will disable password-based +## authentication even for the management UI!): +## +# auth_mechanisms.1 = EXTERNAL + +## This pertains to both the rabbitmq-auth-mechanism-ssl plugin and +## STOMP ssl_cert_login configurations. See the rabbitmq_stomp +## configuration section later in this file and the README in +## https://github.com/rabbitmq/rabbitmq-auth-mechanism-ssl for further +## details. +## +## To use the SSL cert's CN instead of its DN as the username +## +# ssl_cert_login_from = common_name + +## SSL handshake timeout, in milliseconds. +## +# ssl_handshake_timeout = 5000 + + +## Password hashing implementation. Will only affect newly +## created users. To recalculate hash for an existing user +## it's necessary to update her password. +## +## To use SHA-512, set to rabbit_password_hashing_sha512. +## +# password_hashing_module = rabbit_password_hashing_sha256 + +## When importing definitions exported from versions earlier +## than 3.6.0, it is possible to go back to MD5 (only do this +## as a temporary measure!) by setting this to rabbit_password_hashing_md5. +## +# password_hashing_module = rabbit_password_hashing_md5 + +## +## Default User / VHost +## ==================== +## + +## On first start RabbitMQ will create a vhost and a user. These +## config items control what gets created. See +## http://www.rabbitmq.com/access-control.html for further +## information about vhosts and access control. +## +# default_vhost = / +# default_user = guest +# default_pass = guest + +# default_permissions.configure = .* +# default_permissions.read = .* +# default_permissions.write = .* + +## Tags for default user +## +## For more details about tags, see the documentation for the +## Management Plugin at http://www.rabbitmq.com/management.html. +## +# default_user_tags.administrator = true + +## Define other tags like this: +# default_user_tags.management = true +# default_user_tags.custom_tag = true + +## +## Additional network and protocol related configuration +## ===================================================== +## + +## Set the default AMQP 0-9-1 heartbeat interval (in seconds). +## See http://rabbitmq.com/heartbeats.html for more details. +## +# heartbeat = 600 + +## Set the max permissible size of an AMQP frame (in bytes). +## +# frame_max = 131072 + +## Set the max frame size the server will accept before connection +## tuning occurs +## +# initial_frame_max = 4096 + +## Set the max permissible number of channels per connection. +## 0 means "no limit". +## +# channel_max = 128 + +## Customising Socket Options. +## +## See (http://www.erlang.org/doc/man/inet.html#setopts-2) for +## further documentation. +## + +# tcp_listen_options.backlog = 128 +# tcp_listen_options.nodelay = true +# tcp_listen_options.exit_on_close = false + +## +## Resource Limits & Flow Control +## ============================== +## +## See http://www.rabbitmq.com/memory.html for full details. + +## Memory-based Flow Control threshold. +## +# vm_memory_high_watermark.relative = 0.4 + +## Alternatively, we can set a limit (in bytes) of RAM used by the node. +## +# vm_memory_high_watermark.absolute = 1073741824 + +## Or you can set absolute value using memory units (with RabbitMQ 3.6.0+). +## Absolute watermark will be ignored if relative is defined! +## +# vm_memory_high_watermark.absolute = 2GB +## +## Supported units suffixes: +## +## kb, KB: kibibytes (2^10 bytes) +## mb, MB: mebibytes (2^20) +## gb, GB: gibibytes (2^30) + + + +## Fraction of the high watermark limit at which queues start to +## page message out to disc in order to free up memory. +## +## Values greater than 0.9 can be dangerous and should be used carefully. +## +# vm_memory_high_watermark_paging_ratio = 0.5 + +## Interval (in milliseconds) at which we perform the check of the memory +## levels against the watermarks. +## +# memory_monitor_interval = 2500 + +## Set disk free limit (in bytes). Once free disk space reaches this +## lower bound, a disk alarm will be set - see the documentation +## listed above for more details. +## +## Absolute watermark will be ignored if relative is defined! +# disk_free_limit.absolute = 50000 + +## Or you can set it using memory units (same as in vm_memory_high_watermark) +## with RabbitMQ 3.6.0+. +# disk_free_limit.absolute = 500KB +# disk_free_limit.absolute = 50mb +# disk_free_limit.absolute = 5GB + +## Alternatively, we can set a limit relative to total available RAM. +## +## Values lower than 1.0 can be dangerous and should be used carefully. +# disk_free_limit.relative = 2.0 + +## +## Clustering +## ===================== +## +# cluster_partition_handling = ignore + +## pause_if_all_down strategy require additional configuration +# cluster_partition_handling = pause_if_all_down + +## Recover strategy. Can be either 'autoheal' or 'ignore' +# cluster_partition_handling.pause_if_all_down.recover = ignore + +## Node names to check +# cluster_partition_handling.pause_if_all_down.nodes.1 = rabbit@localhost +# cluster_partition_handling.pause_if_all_down.nodes.2 = hare@localhost + +## Mirror sync batch size, in messages. Increasing this will speed +## up syncing but total batch size in bytes must not exceed 2 GiB. +## Available in RabbitMQ 3.6.0 or later. +## +# mirroring_sync_batch_size = 4096 + +## Make clustering happen *automatically* at startup - only applied +## to nodes that have just been reset or started for the first time. +## See http://www.rabbitmq.com/clustering.html#auto-config for +## further details. +## +# cluster_nodes.disc.rabbit = rabbit@my.host.com + +## You can define multiple nodes +# cluster_nodes.disc.hare = hare@my.host.com + +## There can be also ram nodes. +## Ram nodes should not be defined together with disk nodes +# cluster_nodes.ram.rabbit = rabbit@my.host.com + +## Interval (in milliseconds) at which we send keepalive messages +## to other cluster members. Note that this is not the same thing +## as net_ticktime; missed keepalive messages will not cause nodes +## to be considered down. +## +# cluster_keepalive_interval = 10000 + +## +## Statistics Collection +## ===================== +## + +## Set (internal) statistics collection granularity. +## +## Can be none, coarse or fine +# collect_statistics = none + +# collect_statistics = coarse + +## Statistics collection interval (in milliseconds). Increasing +## this will reduce the load on management database. +## +# collect_statistics_interval = 5000 + +## +## Misc/Advanced Options +## ===================== +## +## NB: Change these only if you understand what you are doing! +## + +## Explicitly enable/disable hipe compilation. +## +# hipe_compile = false + +## Timeout used when waiting for Mnesia tables in a cluster to +## become available. +## +# mnesia_table_loading_timeout = 30000 + +## Size in bytes below which to embed messages in the queue index. See +## http://www.rabbitmq.com/persistence-conf.html +## +# queue_index_embed_msgs_below = 4096 + +## You can also set this size in memory units +## +# queue_index_embed_msgs_below = 4kb + +## ---------------------------------------------------------------------------- +## Advanced Erlang Networking/Clustering Options. +## +## See http://www.rabbitmq.com/clustering.html for details +## ---------------------------------------------------------------------------- + +# ====================================== +# Kernel section +# ====================================== + +# kernel.net_ticktime = 60 + +## ---------------------------------------------------------------------------- +## RabbitMQ Management Plugin +## +## See http://www.rabbitmq.com/management.html for details +## ---------------------------------------------------------------------------- + +# ======================================= +# Management section +# ======================================= + +## Pre-Load schema definitions from the following JSON file. See +## http://www.rabbitmq.com/management.html#load-definitions +## +# management.load_definitions = /path/to/schema.json + +## Log all requests to the management HTTP API to a file. +## +# management.http_log_dir = /path/to/access.log + +## Change the port on which the HTTP listener listens, +## specifying an interface for the web server to bind to. +## Also set the listener to use SSL and provide SSL options. +## + +# QA: Maybe use IP type like in tcp_listener? +# management.listeners.port = 12345 +# management.listeners.ip = 127.0.0.1 +# management.listeners.ssl = true + +# management.listeners.ssl_opts.cacertfile = /path/to/cacert.pem +# management.listeners.ssl_opts.certfile = /path/to/cert.pem +# management.listeners.ssl_opts.keyfile = /path/to/key.pem + +## One of 'basic', 'detailed' or 'none'. See +## http://www.rabbitmq.com/management.html#fine-stats for more details. +# management.rates_mode = basic + +## Configure how long aggregated data (such as message rates and queue +## lengths) is retained. Please read the plugin's documentation in +## http://www.rabbitmq.com/management.html#configuration for more +## details. +## Your can use 'minute', 'hour' and '24hours' keys or integer key (in seconds) +# management.sample_retention_policies.global.minute = 5 +# management.sample_retention_policies.global.hour = 60 +# management.sample_retention_policies.global.24hours = 1200 + +# management.sample_retention_policies.basic.minute = 5 +# management.sample_retention_policies.basic.hour = 60 + +# management.sample_retention_policies.detailed.10 = 5 + +## ---------------------------------------------------------------------------- +## RabbitMQ Shovel Plugin +## +## See http://www.rabbitmq.com/shovel.html for details +## ---------------------------------------------------------------------------- + +## Shovel plugin config example is defined in additional.config file + + +## ---------------------------------------------------------------------------- +## RabbitMQ Stomp Adapter +## +## See http://www.rabbitmq.com/stomp.html for details +## ---------------------------------------------------------------------------- + +# ======================================= +# STOMP section +# ======================================= + +## Network Configuration - the format is generally the same as for the broker +## +# stomp.listeners.tcp.default = 61613 + +## Same for ssl listeners +## +# stomp.listeners.ssl.default = 61614 + +## Number of Erlang processes that will accept connections for the TCP +## and SSL listeners. +## +# stomp.num_acceptors.tcp = 10 +# stomp.num_acceptors.ssl = 1 + +## Additional SSL options + +## Extract a name from the client's certificate when using SSL. +## +# stomp.ssl_cert_login = true + +## Set a default user name and password. This is used as the default login +## whenever a CONNECT frame omits the login and passcode headers. +## +## Please note that setting this will allow clients to connect without +## authenticating! +## +# stomp.default_user = guest +# stomp.default_pass = guest + +## If a default user is configured, or you have configured use SSL client +## certificate based authentication, you can choose to allow clients to +## omit the CONNECT frame entirely. If set to true, the client is +## automatically connected as the default user or user supplied in the +## SSL certificate whenever the first frame sent on a session is not a +## CONNECT frame. +## +# stomp.implicit_connect = true + +## ---------------------------------------------------------------------------- +## RabbitMQ MQTT Adapter +## +## See https://github.com/rabbitmq/rabbitmq-mqtt/blob/stable/README.md +## for details +## ---------------------------------------------------------------------------- + +# ======================================= +# MQTT section +# ======================================= + +## Set the default user name and password. Will be used as the default login +## if a connecting client provides no other login details. +## +## Please note that setting this will allow clients to connect without +## authenticating! +## +# mqtt.default_user = guest +# mqtt.default_pass = guest + +## Enable anonymous access. If this is set to false, clients MUST provide +## login information in order to connect. See the default_user/default_pass +## configuration elements for managing logins without authentication. +## +# mqtt.allow_anonymous = true + +## If you have multiple chosts, specify the one to which the +## adapter connects. +## +# mqtt.vhost = / + +## Specify the exchange to which messages from MQTT clients are published. +## +# mqtt.exchange = amq.topic + +## Specify TTL (time to live) to control the lifetime of non-clean sessions. +## +# mqtt.subscription_ttl = 1800000 + +## Set the prefetch count (governing the maximum number of unacknowledged +## messages that will be delivered). +## +# mqtt.prefetch = 10 + +## TCP/SSL Configuration (as per the broker configuration). +## +# mqtt.listeners.tcp.default = 1883 + +## Same for ssl listener +## +# mqtt.listeners.ssl.default = 1884 + +## Number of Erlang processes that will accept connections for the TCP +## and SSL listeners. +## +# mqtt.num_acceptors.tcp = 10 +# mqtt.num_acceptors.ssl = 1 + +## TCP/Socket options (as per the broker configuration). +## +# mqtt.tcp_listen_options.backlog = 128 +# mqtt.tcp_listen_options.nodelay = true + +## ---------------------------------------------------------------------------- +## RabbitMQ AMQP 1.0 Support +## +## See https://github.com/rabbitmq/rabbitmq-amqp1.0/blob/stable/README.md +## for details +## ---------------------------------------------------------------------------- + +# ======================================= +# AMQP_1 section +# ======================================= + + +## Connections that are not authenticated with SASL will connect as this +## account. See the README for more information. +## +## Please note that setting this will allow clients to connect without +## authenticating! +## +# amqp1_0.default_user = guest + +## Enable protocol strict mode. See the README for more information. +## +# amqp1_0.protocol_strict_mode = false + +## Lager controls logging. +## See https://github.com/basho/lager for more documentation +## +## Log direcrory, taken from the RABBITMQ_LOG_BASE env variable by default. +## +# log.dir = /var/log/rabbitmq + +## Logging to console (can be true or false) +## +# log.console = false + +## Loglevel to log to console +## +# log.console.level = info + +## Logging to file. Can be false or filename. +## Default: +# log.file = rabbit.log + +## To turn off: +# log.file = false + +## Loglevel to log to file +## +# log.file.level = info + +## File rotation config. No rotation by defualt. +## DO NOT SET rotation date to ''. Leave unset if require "" value +# log.file.rotation.date = $D0 +# log.file.rotation.size = 0 + + +## QA: Config for syslog logging +# log.syslog = false +# log.syslog.identity = rabbitmq +# log.syslog.level = info +# log.syslog.facility = daemon + + +## ---------------------------------------------------------------------------- +## RabbitMQ LDAP Plugin +## +## See http://www.rabbitmq.com/ldap.html for details. +## +## ---------------------------------------------------------------------------- + +# ======================================= +# LDAP section +# ======================================= + +## +## Connecting to the LDAP server(s) +## ================================ +## + +## Specify servers to bind to. You *must* set this in order for the plugin +## to work properly. +## +# ldap.servers.1 = your-server-name-goes-here + +## You can define multiple servers +# ldap.servers.2 = your-other-server + +## Connect to the LDAP server using SSL +## +# ldap.use_ssl = false + +## Specify the LDAP port to connect to +## +# ldap.port = 389 + +## LDAP connection timeout, in milliseconds or 'infinity' +## +# ldap.timeout = infinity + +## Or number +# ldap.timeout = 500 + +## Enable logging of LDAP queries. +## One of +## - false (no logging is performed) +## - true (verbose logging of the logic used by the plugin) +## - network (as true, but additionally logs LDAP network traffic) +## +## Defaults to false. +## +# ldap.log = false + +## Also can be true or network +# ldap.log = true +# ldap.log = network + +## +## Authentication +## ============== +## + +## Pattern to convert the username given through AMQP to a DN before +## binding +## +# ldap.user_dn_pattern = cn=${username},ou=People,dc=example,dc=com + +## Alternatively, you can convert a username to a Distinguished +## Name via an LDAP lookup after binding. See the documentation for +## full details. + +## When converting a username to a dn via a lookup, set these to +## the name of the attribute that represents the user name, and the +## base DN for the lookup query. +## +# ldap.dn_lookup_attribute = userPrincipalName +# ldap.dn_lookup_base = DC=gopivotal,DC=com + +## Controls how to bind for authorisation queries and also to +## retrieve the details of users logging in without presenting a +## password (e.g., SASL EXTERNAL). +## One of +## - as_user (to bind as the authenticated user - requires a password) +## - anon (to bind anonymously) +## - {UserDN, Password} (to bind with a specified user name and password) +## +## Defaults to 'as_user'. +## +# ldap.other_bind = as_user + +## Or can be more complex: +# ldap.other_bind.user_dn = User +# ldap.other_bind.password = Password + +## If user_dn and password defined - other options is ignored. + +# ----------------------------- +# Too complex section of LDAP +# ----------------------------- + +## +## Authorisation +## ============= +## + +## The LDAP plugin can perform a variety of queries against your +## LDAP server to determine questions of authorisation. See +## http://www.rabbitmq.com/ldap.html#authorisation for more +## information. + +## Following configuration should be defined in additional.config file +## DO NOT UNCOMMENT THIS LINES! + +## Set the query to use when determining vhost access +## +## {vhost_access_query, {in_group, +## "ou=${vhost}-users,ou=vhosts,dc=example,dc=com"}}, + +## Set the query to use when determining resource (e.g., queue) access +## +## {resource_access_query, {constant, true}}, + +## Set queries to determine which tags a user has +## +## {tag_queries, []} +# ]}, +# ----------------------------- diff --git a/packaging/RPMS/Fedora/rabbitmq-server.spec b/packaging/RPMS/Fedora/rabbitmq-server.spec index dc389f22b2..d3d33aa985 100644 --- a/packaging/RPMS/Fedora/rabbitmq-server.spec +++ b/packaging/RPMS/Fedora/rabbitmq-server.spec @@ -95,6 +95,8 @@ fi /sbin/chkconfig --add %{name} if [ -f %{_sysconfdir}/rabbitmq/rabbitmq.conf ] && [ ! -f %{_sysconfdir}/rabbitmq/rabbitmq-env.conf ]; then mv %{_sysconfdir}/rabbitmq/rabbitmq.conf %{_sysconfdir}/rabbitmq/rabbitmq-env.conf +else + touch %{_sysconfdir}/rabbitmq/rabbitmq-env.conf fi chmod -R o-rwx,g-w %{_localstatedir}/lib/rabbitmq/mnesia diff --git a/packaging/debs/Debian/debian/postinst b/packaging/debs/Debian/debian/postinst index c83881e6ba..2439612c42 100644 --- a/packaging/debs/Debian/debian/postinst +++ b/packaging/debs/Debian/debian/postinst @@ -40,6 +40,8 @@ case "$1" in if [ -f /etc/rabbitmq/rabbitmq.conf ] && \ [ ! -f /etc/rabbitmq/rabbitmq-env.conf ]; then mv /etc/rabbitmq/rabbitmq.conf /etc/rabbitmq/rabbitmq-env.conf + else + touch /etc/rabbitmq/rabbitmq-env.conf fi ;; diff --git a/packaging/windows-exe/rabbitmq_nsi.in b/packaging/windows-exe/rabbitmq_nsi.in index e66d2a99ed..ae1585c372 100644 --- a/packaging/windows-exe/rabbitmq_nsi.in +++ b/packaging/windows-exe/rabbitmq_nsi.in @@ -137,6 +137,20 @@ Section "RabbitMQ Server (required)" Rabbit ; Set output path to the user's data directory SetOutPath $APPDATA\RabbitMQ + IfFileExists advanced.config 0 +2 + Goto config_written + IfFileExists rabbitmq.config 0 +3 + Rename rabbitmq.config advanced.config + Goto config_written + ClearErrors + FileOpen $0 advanced.config w + IfErrors config_written + FileWrite $0 "[]." + FileClose $0 + config_written: + + + ; ...And put the example config file there File "rabbitmq_server-%%VERSION%%\etc\rabbitmq.config.example" diff --git a/priv/schema/.gitignore b/priv/schema/.gitignore new file mode 100644 index 0000000000..68e5b59a44 --- /dev/null +++ b/priv/schema/.gitignore @@ -0,0 +1,4 @@ +# plugin schemas are extracted +# into this directory: this is a Cuttlefish +# requirement. So we ignore them. +rabbitmq_*.schema diff --git a/priv/schema/rabbitmq.schema b/priv/schema/rabbitmq.schema new file mode 100644 index 0000000000..19040da409 --- /dev/null +++ b/priv/schema/rabbitmq.schema @@ -0,0 +1,961 @@ +% ============================== +% Rabbit app section +% ============================== + +%% +%% Network Connectivity +%% ==================== +%% + +%% By default, RabbitMQ will listen on all interfaces, using +%% the standard (reserved) AMQP port. +%% +%% {tcp_listeners, [5672]}, +%% To listen on a specific interface, provide a tuple of {IpAddress, Port}. +%% For example, to listen only on localhost for both IPv4 and IPv6: +%% +%% {tcp_listeners, [{"127.0.0.1", 5672}, +%% {"[::1]", 5672}]}, + +{mapping, "listeners.tcp", "rabbit.tcp_listeners",[ + {datatype, {enum, [none]}} +]}. + +{mapping, "listeners.tcp.$name", "rabbit.tcp_listeners",[ + {datatype, [integer, ip]} +]}. + +{translation, "rabbit.tcp_listeners", +fun(Conf) -> + case cuttlefish:conf_get("listeners.tcp", Conf, undefined) of + none -> []; + _ -> + Settings = cuttlefish_variable:filter_by_prefix("listeners.tcp", Conf), + [ V || {_, V} <- Settings ] + end +end}. + +%% SSL listeners are configured in the same fashion as TCP listeners, +%% including the option to control the choice of interface. +%% +%% {ssl_listeners, [5671]}, + +{mapping, "listeners.ssl", "rabbit.ssl_listeners",[ + {datatype, {enum, [none]}} +]}. + +{mapping, "listeners.ssl.$name", "rabbit.ssl_listeners",[ + {datatype, [integer, ip]} +]}. + +{translation, "rabbit.ssl_listeners", +fun(Conf) -> + case cuttlefish:conf_get("listeners.ssl", Conf, undefined) of + none -> []; + _ -> + Settings = cuttlefish_variable:filter_by_prefix("listeners.ssl", Conf), + [ V || {_, V} <- Settings ] + end +end}. + +%% Number of Erlang processes that will accept connections for the TCP +%% and SSL listeners. +%% +%% {num_tcp_acceptors, 10}, +%% {num_ssl_acceptors, 1}, + +{mapping, "num_acceptors.ssl", "rabbit.num_ssl_acceptors", [ + {datatype, integer} +]}. + +{mapping, "num_acceptors.tcp", "rabbit.num_tcp_acceptors", [ + {datatype, integer} +]}. + + +%% Maximum time for AMQP 0-8/0-9/0-9-1 handshake (after socket connection +%% and SSL handshake), in milliseconds. +%% +%% {handshake_timeout, 10000}, + +{mapping, "handshake_timeout", "rabbit.handshake_timeout", [ + {datatype, integer} +]}. + +%% Set to 'true' to perform reverse DNS lookups when accepting a +%% connection. Hostnames will then be shown instead of IP addresses +%% in rabbitmqctl and the management plugin. +%% +%% {reverse_dns_lookups, true}, + +{mapping, "reverse_dns_lookups", "rabbit.reverse_dns_lookups", [ + {datatype, {enum, [true, false]}} +]}. + +{mapping, "erlang.K", "vm_args.+K", [ + {default, "true"}, + {level, advanced} +]}. + +%% +%% Security / AAA +%% ============== +%% + +%% The default "guest" user is only permitted to access the server +%% via a loopback interface (e.g. localhost). +%% {loopback_users, [<<"guest">>]}, +%% +%% Uncomment the following line if you want to allow access to the +%% guest user from anywhere on the network. +%% {loopback_users, []}, + +{mapping, "loopback_users", "rabbit.loopback_users", [ + {datatype, {enum, [none]}} +]}. + +{mapping, "loopback_users.$user", "rabbit.loopback_users", [ + {datatype, atom} +]}. + +{translation, "rabbit.loopback_users", +fun(Conf) -> + None = cuttlefish:conf_get("loopback_users", Conf, undefined), + case None of + none -> []; + _ -> + Settings = cuttlefish_variable:filter_by_prefix("loopback_users", Conf), + [ list_to_binary(U) || {["loopback_users", U], V} <- Settings, V == true ] + end +end}. + +%% Configuring SSL. +%% See http://www.rabbitmq.com/ssl.html for full documentation. +%% +%% {ssl_options, [{cacertfile, "/path/to/testca/cacert.pem"}, +%% {certfile, "/path/to/server/cert.pem"}, +%% {keyfile, "/path/to/server/key.pem"}, +%% {verify, verify_peer}, +%% {fail_if_no_peer_cert, false}]}, + +%% SSL options section ======================================================== + +{mapping, "ssl_allow_poodle_attack", "rabbit.ssl_allow_poodle_attack", +[{datatype, {enum, [true, false]}}]}. + +{mapping, "ssl_options", "rabbit.ssl_options", [ + {datatype, {enum, [none]}} +]}. + +{translation, "rabbit.ssl_options", +fun(Conf) -> + case cuttlefish:conf_get("ssl_options", Conf, undefined) of + none -> []; + _ -> cuttlefish:invalid("Invalid ssl_options") + end +end}. + +{mapping, "ssl_options.verify", "rabbit.ssl_options.verify", [ + {datatype, {enum, [verify_peer, verify_none]}}]}. + +{mapping, "ssl_options.fail_if_no_peer_cert", "rabbit.ssl_options.fail_if_no_peer_cert", [ + {datatype, {enum, [true, false]}}]}. + +{mapping, "ssl_options.cacertfile", "rabbit.ssl_options.cacertfile", + [{datatype, string}, {validators, ["file_accessible"]}]}. + +{mapping, "ssl_options.certfile", "rabbit.ssl_options.certfile", + [{datatype, string}, {validators, ["file_accessible"]}]}. + +{mapping, "ssl_options.cacerts.$name", "rabbit.ssl_options.cacerts", + [{datatype, string}]}. + +{translation, "rabbit.ssl_options.cacerts", +fun(Conf) -> + Settings = cuttlefish_variable:filter_by_prefix("ssl_options.cacerts", Conf), + [ list_to_binary(V) || {_, V} <- Settings ] +end}. + +{mapping, "ssl_options.cert", "rabbit.ssl_options.cert", + [{datatype, string}]}. + +{translation, "rabbit.ssl_options.cert", +fun(Conf) -> + list_to_binary(cuttlefish:conf_get("ssl_options.cert", Conf)) +end}. + +{mapping, "ssl_options.client_renegotiation", "rabbit.ssl_options.client_renegotiation", + [{datatype, {enum, [true, false]}}]}. + +{mapping, "ssl_options.crl_check", "rabbit.ssl_options.crl_check", + [{datatype, [{enum, [true, false, peer, best_effort]}]}]}. + +{mapping, "ssl_options.depth", "rabbit.ssl_options.depth", + [{datatype, integer}, {validators, ["byte"]}]}. + +{mapping, "ssl_options.dh", "rabbit.ssl_options.dh", + [{datatype, string}]}. + +{translation, "rabbit.ssl_options.dh", +fun(Conf) -> + list_to_binary(cuttlefish:conf_get("ssl_options.dh", Conf)) +end}. + +{mapping, "ssl_options.dhfile", "rabbit.ssl_options.dhfile", + [{datatype, string}, {validators, ["file_accessible"]}]}. + +{mapping, "ssl_options.honor_cipher_order", "rabbit.ssl_options.honor_cipher_order", + [{datatype, {enum, [true, false]}}]}. + +{mapping, "ssl_options.key.RSAPrivateKey", "rabbit.ssl_options.key", + [{datatype, string}]}. + +{mapping, "ssl_options.key.DSAPrivateKey", "rabbit.ssl_options.key", + [{datatype, string}]}. + +{mapping, "ssl_options.key.PrivateKeyInfo", "rabbit.ssl_options.key", + [{datatype, string}]}. + +{translation, "rabbit.ssl_options.key", +fun(Conf) -> + case cuttlefish_variable:filter_by_prefix("ssl_options.key", Conf) of + [{[_,_,Key], Val}|_] -> {list_to_atom(Key), list_to_binary(Val)}; + _ -> undefined + end +end}. + +{mapping, "ssl_options.keyfile", "rabbit.ssl_options.keyfile", + [{datatype, string}, {validators, ["file_accessible"]}]}. + +{mapping, "ssl_options.log_alert", "rabbit.ssl_options.log_alert", + [{datatype, {enum, [true, false]}}]}. + +{mapping, "ssl_options.password", "rabbit.ssl_options.password", + [{datatype, string}]}. + +{mapping, "ssl_options.psk_identity", "rabbit.ssl_options.psk_identity", + [{datatype, string}]}. + +{mapping, "ssl_options.reuse_sessions", "rabbit.ssl_options.reuse_sessions", + [{datatype, {enum, [true, false]}}]}. + +{mapping, "ssl_options.secure_renegotiate", "rabbit.ssl_options.secure_renegotiate", + [{datatype, {enum, [true, false]}}]}. + +{mapping, "ssl_options.versions.$version", "rabbit.ssl_options.versions", + [{datatype, atom}]}. + +{translation, "rabbit.ssl_options.versions", +fun(Conf) -> + Settings = cuttlefish_variable:filter_by_prefix("ssl_options.versions", Conf), + [ V || {_, V} <- Settings ] +end}. + +%% =========================================================================== + +%% Choose the available SASL mechanism(s) to expose. +%% The two default (built in) mechanisms are 'PLAIN' and +%% 'AMQPLAIN'. Additional mechanisms can be added via +%% plugins. +%% +%% See http://www.rabbitmq.com/authentication.html for more details. +%% +%% {auth_mechanisms, ['PLAIN', 'AMQPLAIN']}, + +{mapping, "auth_mechanisms.$name", "rabbit.auth_mechanisms", [ + {datatype, atom}]}. + +{translation, "rabbit.auth_mechanisms", +fun(Conf) -> + Settings = cuttlefish_variable:filter_by_prefix("auth_mechanisms", Conf), + [ V || {_, V} <- Settings ] +end}. + + +%% Select an authentication backend to use. RabbitMQ provides an +%% internal backend in the core. +%% +%% {auth_backends, [rabbit_auth_backend_internal]}, + +{translation, "rabbit.auth_backends", +fun(Conf) -> + Settings = cuttlefish_variable:filter_by_prefix("auth_backends", Conf), + BackendModule = fun + (internal) -> rabbit_auth_backend_internal; + (ldap) -> rabbit_auth_backend_ldap; + (http) -> rabbit_auth_backend_http; + (amqp) -> rabbit_auth_backend_amqp; + (dummy) -> rabbit_auth_backend_dummy; + (Other) when is_atom(Other) -> Other; + (_) -> cuttlefish:invalid("Unknown/unsupported auth backend") + end, + AuthBackends = [{Num, {default, BackendModule(V)}} || {["auth_backends", Num], V} <- Settings], + AuthNBackends = [{Num, {authn, BackendModule(V)}} || {["auth_backends", Num, "authn"], V} <- Settings], + AuthZBackends = [{Num, {authz, BackendModule(V)}} || {["auth_backends", Num, "authz"], V} <- Settings], + Backends = lists:foldl( + fun({NumStr, {Type, V}}, Acc) -> + Num = case catch list_to_integer(NumStr) of + N when is_integer(N) -> N; + Err -> + cuttlefish:invalid( + iolist_to_binary(io_lib:format( + "Auth backend position in the chain should be an integer ~p", [Err]))) + end, + NewVal = case dict:find(Num, Acc) of + {ok, {AuthN, AuthZ}} -> + case {Type, AuthN, AuthZ} of + {authn, undefined, _} -> + {V, AuthZ}; + {authz, _, undefined} -> + {AuthN, V}; + _ -> + cuttlefish:invalid( + iolist_to_binary( + io_lib:format( + "Auth backend already defined for the ~pth ~p backend", + [Num, Type]))) + end; + error -> + case Type of + authn -> {V, undefined}; + authz -> {undefined, V}; + default -> {V, V} + end + end, + dict:store(Num, NewVal, Acc) + end, + dict:new(), + AuthBackends ++ AuthNBackends ++ AuthZBackends), + lists:map( + fun + ({Num, {undefined, AuthZ}}) -> + cuttlefish:warn( + io_lib:format( + "Auth backend undefined for the ~pth authz backend. Using ~p", + [Num, AuthZ])), + {AuthZ, AuthZ}; + ({Num, {AuthN, undefined}}) -> + cuttlefish:warn( + io_lib:format( + "Authz backend undefined for the ~pth authn backend. Using ~p", + [Num, AuthN])), + {AuthN, AuthN}; + ({_Num, {Auth, Auth}}) -> Auth; + ({_Num, {AuthN, AuthZ}}) -> {AuthN, AuthZ} + end, + lists:keysort(1, dict:to_list(Backends))) +end}. + +{mapping, "auth_backends.$num", "rabbit.auth_backends", [ + {datatype, atom} +]}. + +{mapping, "auth_backends.$num.authn", "rabbit.auth_backends",[ + {datatype, atom} +]}. + +{mapping, "auth_backends.$num.authz", "rabbit.auth_backends",[ + {datatype, atom} +]}. + +%% This pertains to both the rabbitmq_auth_mechanism_ssl plugin and +%% STOMP ssl_cert_login configurations. See the rabbitmq_stomp +%% configuration section later in this file and the README in +%% https://github.com/rabbitmq/rabbitmq-auth-mechanism-ssl for further +%% details. +%% +%% To use the SSL cert's CN instead of its DN as the username +%% +%% {ssl_cert_login_from, common_name}, + +{mapping, "ssl_cert_login_from", "rabbit.ssl_cert_login_from", [ + {datatype, {enum, [distinguished_name, common_name]}} +]}. + +%% SSL handshake timeout, in milliseconds. +%% +%% {ssl_handshake_timeout, 5000}, + +{mapping, "ssl_handshake_timeout", "rabbit.ssl_handshake_timeout", [ + {datatype, integer} +]}. + +%% Password hashing implementation. Will only affect newly +%% created users. To recalculate hash for an existing user +%% it's necessary to update her password. +%% +%% When importing definitions exported from versions earlier +%% than 3.6.0, it is possible to go back to MD5 (only do this +%% as a temporary measure!) by setting this to rabbit_password_hashing_md5. +%% +%% To use SHA-512, set to rabbit_password_hashing_sha512. +%% +%% {password_hashing_module, rabbit_password_hashing_sha256}, + +{mapping, "password_hashing_module", "rabbit.password_hashing_module", [ + {datatype, atom} +]}. + +%% +%% Default User / VHost +%% ==================== +%% + +%% On first start RabbitMQ will create a vhost and a user. These +%% config items control what gets created. See +%% http://www.rabbitmq.com/access-control.html for further +%% information about vhosts and access control. +%% +%% {default_vhost, <<"/">>}, +%% {default_user, <<"guest">>}, +%% {default_pass, <<"guest">>}, +%% {default_permissions, [<<".*">>, <<".*">>, <<".*">>]}, + +{mapping, "default_vhost", "rabbit.default_vhost", [ + {datatype, string} +]}. + +{translation, "rabbit.default_vhost", +fun(Conf) -> + list_to_binary(cuttlefish:conf_get("default_vhost", Conf)) +end}. + +{mapping, "default_user", "rabbit.default_user", [ + {datatype, string} +]}. + +{translation, "rabbit.default_user", +fun(Conf) -> + list_to_binary(cuttlefish:conf_get("default_user", Conf)) +end}. + +{mapping, "default_pass", "rabbit.default_pass", [ + {datatype, string} +]}. + +{translation, "rabbit.default_pass", +fun(Conf) -> + list_to_binary(cuttlefish:conf_get("default_pass", Conf)) +end}. + +{mapping, "default_permissions.configure", "rabbit.default_permissions", [ + {datatype, string} +]}. + +{mapping, "default_permissions.read", "rabbit.default_permissions", [ + {datatype, string} +]}. + +{mapping, "default_permissions.write", "rabbit.default_permissions", [ + {datatype, string} +]}. + +{translation, "rabbit.default_permissions", +fun(Conf) -> + Settings = cuttlefish_variable:filter_by_prefix("default_permissions", Conf), + Configure = proplists:get_value(["default_permissions", "configure"], Settings), + Read = proplists:get_value(["default_permissions", "read"], Settings), + Write = proplists:get_value(["default_permissions", "write"], Settings), + [list_to_binary(Configure), list_to_binary(Read), list_to_binary(Write)] +end}. + +%% Tags for default user +%% +%% For more details about tags, see the documentation for the +%% Management Plugin at http://www.rabbitmq.com/management.html. +%% +%% {default_user_tags, [administrator]}, + +{mapping, "default_user_tags.$tag", "rabbit.default_user_tags", + [{datatype, {enum, [true, false]}}]}. + +{translation, "rabbit.default_user_tags", +fun(Conf) -> + Settings = cuttlefish_variable:filter_by_prefix("default_user_tags", Conf), + [ list_to_atom(Key) || {[_,Key], Val} <- Settings, Val == true ] +end}. + +%% +%% Additional network and protocol related configuration +%% ===================================================== +%% + +%% Set the default AMQP heartbeat delay (in seconds). +%% +%% {heartbeat, 600}, + +{mapping, "heartbeat", "rabbit.heartbeat", [{datatype, integer}]}. + +%% Set the max permissible size of an AMQP frame (in bytes). +%% +%% {frame_max, 131072}, + +{mapping, "frame_max", "rabbit.frame_max", [{datatype, bytesize}]}. + +%% Set the max frame size the server will accept before connection +%% tuning occurs +%% +%% {initial_frame_max, 4096}, + +{mapping, "initial_frame_max", "rabbit.initial_frame_max", [{datatype, bytesize}]}. + +%% Set the max permissible number of channels per connection. +%% 0 means "no limit". +%% +%% {channel_max, 128}, + +{mapping, "channel_max", "rabbit.channel_max", [{datatype, integer}]}. + +%% Customising Socket Options. +%% +%% See (http://www.erlang.org/doc/man/inet.html#setopts-2) for +%% further documentation. +%% +%% {tcp_listen_options, [{backlog, 128}, +%% {nodelay, true}, +%% {exit_on_close, false}]}, + +%% TCP listener section ====================================================== + +{mapping, "tcp_listen_options", "rabbit.tcp_listen_options", [ + {datatype, {enum, [none]}}]}. + +{translation, "rabbit.tcp_listen_options", +fun(Conf) -> + case cuttlefish:conf_get("tcp_listen_options", undefined) of + none -> []; + _ -> cuttlefish:invalid("Invalid tcp_listen_options") + end +end}. + +{mapping, "tcp_listen_options.backlog", "rabbit.tcp_listen_options.backlog", [ + {datatype, integer} +]}. + +{mapping, "tcp_listen_options.nodelay", "rabbit.tcp_listen_options.nodelay", [ + {datatype, {enum, [true, false]}} +]}. + +{mapping, "tcp_listen_options.buffer", "rabbit.tcp_listen_options.buffer", + [{datatype, integer}]}. + +{mapping, "tcp_listen_options.delay_send", "rabbit.tcp_listen_options.delay_send", + [{datatype, {enum, [true, false]}}]}. + +{mapping, "tcp_listen_options.dontroute", "rabbit.tcp_listen_options.dontroute", + [{datatype, {enum, [true, false]}}]}. + +{mapping, "tcp_listen_options.exit_on_close", "rabbit.tcp_listen_options.exit_on_close", + [{datatype, {enum, [true, false]}}]}. + +{mapping, "tcp_listen_options.fd", "rabbit.tcp_listen_options.fd", + [{datatype, integer}]}. + +{mapping, "tcp_listen_options.high_msgq_watermark", "rabbit.tcp_listen_options.high_msgq_watermark", + [{datatype, integer}]}. + +{mapping, "tcp_listen_options.high_watermark", "rabbit.tcp_listen_options.high_watermark", + [{datatype, integer}]}. + +{mapping, "tcp_listen_options.keepalive", "rabbit.tcp_listen_options.keepalive", + [{datatype, {enum, [true, false]}}]}. + +{mapping, "tcp_listen_options.low_msgq_watermark", "rabbit.tcp_listen_options.low_msgq_watermark", + [{datatype, integer}]}. + +{mapping, "tcp_listen_options.low_watermark", "rabbit.tcp_listen_options.low_watermark", + [{datatype, integer}]}. + +{mapping, "tcp_listen_options.port", "rabbit.tcp_listen_options.port", + [{datatype, integer}, {validators, ["port"]}]}. + +{mapping, "tcp_listen_options.priority", "rabbit.tcp_listen_options.priority", + [{datatype, integer}]}. + +{mapping, "tcp_listen_options.recbuf", "rabbit.tcp_listen_options.recbuf", + [{datatype, integer}]}. + +{mapping, "tcp_listen_options.send_timeout", "rabbit.tcp_listen_options.send_timeout", + [{datatype, integer}]}. + +{mapping, "tcp_listen_options.send_timeout_close", "rabbit.tcp_listen_options.send_timeout_close", + [{datatype, {enum, [true, false]}}]}. + +{mapping, "tcp_listen_options.sndbuf", "rabbit.tcp_listen_options.sndbuf", + [{datatype, integer}]}. + +{mapping, "tcp_listen_options.tos", "rabbit.tcp_listen_options.tos", + [{datatype, integer}]}. + +%% ========================================================================== + +%% +%% Resource Limits & Flow Control +%% ============================== +%% +%% See http://www.rabbitmq.com/memory.html for full details. + +%% Memory-based Flow Control threshold. +%% +%% {vm_memory_high_watermark, 0.4}, + +%% Alternatively, we can set a limit (in bytes) of RAM used by the node. +%% +%% {vm_memory_high_watermark, {absolute, 1073741824}}, +%% +%% Or you can set absolute value using memory units (with RabbitMQ 3.6.0+). +%% +%% {vm_memory_high_watermark, {absolute, "1024M"}}, +%% +%% Supported units suffixes: +%% +%% kb, KB: kibibytes (2^10 bytes) +%% mb, MB: mebibytes (2^20) +%% gb, GB: gibibytes (2^30) + +{mapping, "vm_memory_high_watermark.relative", "rabbit.vm_memory_high_watermark", [ + {datatype, float}]}. + +{mapping, "vm_memory_high_watermark.absolute", "rabbit.vm_memory_high_watermark", [ + {datatype, [integer, string]}]}. + + +{translation, "rabbit.vm_memory_high_watermark", +fun(Conf) -> + Settings = cuttlefish_variable:filter_by_prefix("vm_memory_high_watermark", Conf), + Absolute = proplists:get_value(["vm_memory_high_watermark", "absolute"], Settings), + Relative = proplists:get_value(["vm_memory_high_watermark", "relative"], Settings), + case {Absolute, Relative} of + {undefined, undefined} -> cuttlefish:invalid("No vm watermark defined"); + {_, undefined} -> {absolute, Absolute}; + _ -> Relative + end +end}. + +%% Fraction of the high watermark limit at which queues start to +%% page message out to disc in order to free up memory. +%% +%% Values greater than 0.9 can be dangerous and should be used carefully. +%% +%% {vm_memory_high_watermark_paging_ratio, 0.5}, + +{mapping, "vm_memory_high_watermark_paging_ratio", + "rabbit.vm_memory_high_watermark_paging_ratio", + [{datatype, float}, {validators, ["less_than_1"]}]}. + +%% Interval (in milliseconds) at which we perform the check of the memory +%% levels against the watermarks. +%% +%% {memory_monitor_interval, 2500}, + +{mapping, "memory_monitor_interval", "rabbit.memory_monitor_interval", + [{datatype, integer}]}. + +%% Set disk free limit (in bytes). Once free disk space reaches this +%% lower bound, a disk alarm will be set - see the documentation +%% listed above for more details. +%% +%% {disk_free_limit, 50000000}, +%% +%% Or you can set it using memory units (same as in vm_memory_high_watermark) +%% with RabbitMQ 3.6.0+. +%% {disk_free_limit, "50MB"}, +%% {disk_free_limit, "50000kB"}, +%% {disk_free_limit, "2GB"}, + +%% Alternatively, we can set a limit relative to total available RAM. +%% +%% Values lower than 1.0 can be dangerous and should be used carefully. +%% {disk_free_limit, {mem_relative, 2.0}}, + +{mapping, "disk_free_limit.relative", "rabbit.disk_free_limit", [ + {datatype, float}]}. + +{mapping, "disk_free_limit.absolute", "rabbit.disk_free_limit", [ + {datatype, [integer, string]}]}. + + +{translation, "rabbit.disk_free_limit", +fun(Conf) -> + Settings = cuttlefish_variable:filter_by_prefix("disk_free_limit", Conf), + Absolute = proplists:get_value(["disk_free_limit", "absolute"], Settings), + Relative = proplists:get_value(["disk_free_limit", "relative"], Settings), + case {Absolute, Relative} of + {undefined, undefined} -> cuttlefish:invalid("No disk limit defined"); + {_, undefined} -> Absolute; + _ -> {mem_relative, Relative} + end +end}. + +%% +%% Clustering +%% ===================== +%% + +%% How to respond to cluster partitions. +%% See http://www.rabbitmq.com/partitions.html for further details. +%% +%% {cluster_partition_handling, ignore}, + +{mapping, "cluster_partition_handling", "rabbit.cluster_partition_handling", + [{datatype, {enum, [ignore, pause_minority, autoheal, pause_if_all_down]}}]}. + +{mapping, "cluster_partition_handling.pause_if_all_down.recover", + "rabbit.cluster_partition_handling", + [{datatype, {enum, [ignore, autoheal]}}]}. + +{mapping, "cluster_partition_handling.pause_if_all_down.nodes.$name", + "rabbit.cluster_partition_handling", + [{datatype, atom}]}. + +{translation, "rabbit.cluster_partition_handling", +fun(Conf) -> + case cuttlefish:conf_get("cluster_partition_handling", Conf) of + pause_if_all_down -> + PauseIfAllDownNodes = cuttlefish_variable:filter_by_prefix( + "cluster_partition_handling.pause_if_all_down.nodes", + Conf), + case PauseIfAllDownNodes of + [] -> + cuttlefish:invalid("Nodes required for pause_if_all_down"); + _ -> + Nodes = [ V || {K,V} <- PauseIfAllDownNodes ], + PauseIfAllDownRecover = cuttlefish:conf_get( + "cluster_partition_handling.pause_if_all_down.recover", + Conf), + case PauseIfAllDownRecover of + Recover when Recover == ignore; Recover == autoheal -> + {pause_if_all_down, Nodes, Recover}; + Invalid -> + cuttlefish:invalid("Recover strategy required for pause_if_all_down") + end + end; + Other -> Other + end +end}. + +%% Mirror sync batch size, in messages. Increasing this will speed +%% up syncing but total batch size in bytes must not exceed 2 GiB. +%% Available in RabbitMQ 3.6.0 or later. +%% +%% {mirroring_sync_batch_size, 4096}, + +{mapping, "mirroring_sync_batch_size", "rabbit.mirroring_sync_batch_size", + [{datatype, bytesize}, {validators, ["size_less_than_2G"]}]}. + +%% Make clustering happen *automatically* at startup - only applied +%% to nodes that have just been reset or started for the first time. +%% See http://www.rabbitmq.com/clustering.html#auto-config for +%% further details. +%% +%% {cluster_nodes, {['rabbit@my.host.com'], disc}}, + +{mapping, "cluster_nodes.disc.$node", "rabbit.cluster_nodes", + [{datatype, atom}]}. + +{mapping, "cluster_nodes.ram.$node", "rabbit.cluster_nodes", + [{datatype, atom}]}. + +{translation, "rabbit.cluster_nodes", +fun(Conf) -> + DiskNodes = [ V || {_, V} <- cuttlefish_variable:filter_by_prefix("cluster_nodes.disc", Conf)], + RamNodes = [ V || {_, V} <- cuttlefish_variable:filter_by_prefix("cluster_nodes.ram", Conf)], + + case {DiskNodes, RamNodes} of + {_, []} -> {DiskNodes, disc}; + {[], _} -> {RamNodes, ram} + end +end}. + + +%% Interval (in milliseconds) at which we send keepalive messages +%% to other cluster members. Note that this is not the same thing +%% as net_ticktime; missed keepalive messages will not cause nodes +%% to be considered down. +%% +%% {cluster_keepalive_interval, 10000}, + +{mapping, "cluster_keepalive_interval", "rabbit.cluster_keepalive_interval", + [{datatype, integer}]}. + + +{mapping, "queue_master_locator", "rabbit.queue_master_locator", + [{datatype, string}]}. + +{translation, "rabbit.queue_master_locator", +fun(Conf) -> + list_to_binary(cuttlefish:conf_get("queue_master_locator", Conf)) +end}. + +%% +%% Statistics Collection +%% ===================== +%% + +%% Set (internal) statistics collection granularity. +%% +%% {collect_statistics, none}, + +{mapping, "collect_statistics", "rabbit.collect_statistics", + [{datatype, {enum, [none, coarse, fine]}}]}. + +%% Statistics collection interval (in milliseconds). Increasing +%% this will reduce the load on management database. +%% +%% {collect_statistics_interval, 5000}, + +{mapping, "collect_statistics_interval", "rabbit.collect_statistics_interval", + [{datatype, integer}]}. + +%% +%% Misc/Advanced Options +%% ===================== +%% +%% NB: Change these only if you understand what you are doing! +%% + +%% Explicitly enable/disable hipe compilation. +%% +%% {hipe_compile, true}, + +{mapping, "hipe_compile", "rabbit.hipe_compile", + [{datatype, {enum, [true, false]}}]}. + +%% Timeout used when waiting for Mnesia tables in a cluster to +%% become available. +%% +%% {mnesia_table_loading_timeout, 30000}, + +{mapping, "mnesia_table_loading_timeout", "rabbit.mnesia_table_loading_timeout", + [{datatype, integer}]}. + +%% Size in bytes below which to embed messages in the queue index. See +%% http://www.rabbitmq.com/persistence-conf.html +%% +%% {queue_index_embed_msgs_below, 4096} + +{mapping, "queue_index_embed_msgs_below", "rabbit.queue_index_embed_msgs_below", + [{datatype, bytesize}]}. + +% ========================== +% Lager section +% ========================== + +{mapping, "log.dir", "lager.log_root", [ + {datatype, string}, + {validators, ["dir_writable"]}]}. + +{mapping, "log.console", "lager.handlers", [ + {datatype, {enum, [true, false]}} +]}. + +{mapping, "log.syslog", "lager.handlers", [ + {datatype, {enum, [true, false]}} +]}. +{mapping, "log.file", "lager.handlers", [ + {datatype, [{enum, [false]}, string]} +]}. + +{mapping, "log.file.level", "lager.handlers", [ + {datatype, {enum, [debug, info, warning, error]}} +]}. +{mapping, "log.$handler.level", "lager.handlers", [ + {datatype, {enum, [debug, info, warning, error]}} +]}. +{mapping, "log.file.rotation.date", "lager.handlers", [ + {datatype, string} +]}. +{mapping, "log.file.rotation.size", "lager.handlers", [ + {datatype, integer} +]}. +{mapping, "log.file.rotation.count", "lager.handlers", [ + {datatype, integer} +]}. + +{mapping, "log.syslog.identity", "lager.handlers", [ + {datatype, string} +]}. +{mapping, "log.syslog.facility", "lager.handlers", [ + {datatype, atom} +]}. + +{translation, "lager.handlers", +fun(Conf) -> + ConsoleHandler = case cuttlefish:conf_get("log.console", Conf, false) of + true -> + ConsoleLevel = cuttlefish:conf_get("log.console.level", Conf, info), + [{lager_console_backend, ConsoleLevel}]; + false -> [] + end, + FileHandler = case cuttlefish:conf_get("log.file", Conf, false) of + false -> []; + File -> + FileLevel = cuttlefish:conf_get("log.file.level", Conf, info), + RotationDate = cuttlefish:conf_get("log.file.rotation.date", Conf, ""), + RotationSize = cuttlefish:conf_get("log.file.rotation.size", Conf, 0), + RotationCount = cuttlefish:conf_get("log.file.rotation.count", Conf, 10), + [{lager_file_backend, [{file, File}, + {level, FileLevel}, + {date, RotationDate}, + {size, RotationSize}, + {count, RotationCount}]}] + end, + SyslogHandler = case cuttlefish:conf_get("log.syslog", Conf, false) of + false -> []; + true -> + SyslogLevel = cuttlefish:conf_get("log.syslog.level", Conf, info), + Identity = cuttlefish:conf_get("log.syslog.identity", Conf), + Facility = cuttlefish:conf_get("log.syslog.facility", Conf), + [{lager_syslog_backend, [Identity, Facility, SyslogLevel]}] + end, + case ConsoleHandler ++ FileHandler ++ SyslogHandler of + [] -> undefined; + Other -> Other + end +end}. + + +% =============================== +% Validators +% =============================== + +{validator, "size_less_than_2G", "Byte size should be less than 2G and greater than 0", +fun(Size) when is_integer(Size) -> + Size > 0 andalso Size < 2147483648 +end}. + +{validator, "less_than_1", "Flooat is not beetween 0 and 1", +fun(Float) when is_float(Float) -> + Float > 0 andalso Float < 1 +end}. + +{validator, "port", "Invalid port number", +fun(Port) when is_integer(Port) -> + Port > 0 andalso Port < 65535 +end}. + +{validator, "byte", "Integer is not 0<i<255", +fun(Int) when is_integer(Int) -> + Int > 0 andalso Int < 255 +end}. + +{validator, "dir_writable", "Cannot create file in dir", +fun(Dir) -> + TestFile = filename:join(Dir, "test_file"), + file:delete(TestFile), + Res = ok == file:write_file(TestFile, <<"test">>), + file:delete(TestFile), + Res +end}. + +{validator, "file_accessible", "file doesnt exist or unaccessible", +fun(File) -> + ReadFile = file:read_file_info(File), + element(1, ReadFile) == ok +end}. + +{validator, "is_ip", "string is a valid IP address", +fun(IpStr) -> + Res = inet:parse_address(IpStr), + element(1, Res) == ok +end}. diff --git a/rabbitmq.conf.d/ldap.conf b/rabbitmq.conf.d/ldap.conf new file mode 100644 index 0000000000..2f51cbb409 --- /dev/null +++ b/rabbitmq.conf.d/ldap.conf @@ -0,0 +1,138 @@ +# ## ---------------------------------------------------------------------------- +# ## RabbitMQ LDAP Plugin +# ## +# ## See http://www.rabbitmq.com/ldap.html for details. +# ## +# ## ---------------------------------------------------------------------------- + + +# ======================================= +# LDAP section +# ======================================= + +# Should be defined in additional.conf maybe? + +# {rabbitmq_auth_backend_ldap, +# [## +# ## Connecting to the LDAP server(s) +# ## ================================ +# ## + +# ## Specify servers to bind to. You *must* set this in order for the plugin +# ## to work properly. +# ## +# ## {servers, ["your-server-name-goes-here"]}, + +ldap.servers.myserver = your-server-name-goes-here + +# ## Connect to the LDAP server using SSL +# ## +# ## {use_ssl, false}, + +ldap.use_ssl = false + +# ## Specify the LDAP port to connect to +# ## +# ## {port, 389}, + +ldap.port = 389 + +# ## LDAP connection timeout, in milliseconds or 'infinity' +# ## +# ## {timeout, infinity}, + +ldap.timeout = infinity + +# Or number +# ldap.timeout = 500 + +# ## Enable logging of LDAP queries. +# ## One of +# ## - false (no logging is performed) +# ## - true (verbose logging of the logic used by the plugin) +# ## - network (as true, but additionally logs LDAP network traffic) +# ## +# ## Defaults to false. +# ## +# ## {log, false}, + +ldap.log = false + +# Also can be true or network +# ldap.log = true +# ldap.log = network + +# ## +# ## Authentication +# ## ============== +# ## + +# ## Pattern to convert the username given through AMQP to a DN before +# ## binding +# ## +# ## {user_dn_pattern, "cn=${username},ou=People,dc=example,dc=com"}, + +ldap.user_dn_pattern = cn=${username},ou=People,dc=example,dc=com + +# ## Alternatively, you can convert a username to a Distinguished +# ## Name via an LDAP lookup after binding. See the documentation for +# ## full details. + +# ## When converting a username to a dn via a lookup, set these to +# ## the name of the attribute that represents the user name, and the +# ## base DN for the lookup query. +# ## +# ## {dn_lookup_attribute, "userPrincipalName"}, +# ## {dn_lookup_base, "DC=gopivotal,DC=com"}, + +ldap.dn_lookup_attribute = userPrincipalName +ldap.dn_lookup_base = DC=gopivotal,DC=com + +# ## Controls how to bind for authorisation queries and also to +# ## retrieve the details of users logging in without presenting a +# ## password (e.g., SASL EXTERNAL). +# ## One of +# ## - as_user (to bind as the authenticated user - requires a password) +# ## - anon (to bind anonymously) +# ## - {UserDN, Password} (to bind with a specified user name and password) +# ## +# ## Defaults to 'as_user'. +# ## +# ## {other_bind, as_user}, + +ldap.other_bind = as_user + +# Or can be more complex: +# ldap.other_bind.user_dn = User +# ldap.other_bind.password = Password +# If user_dn and password defined - other options is ignored. + +# ----------------------------- +# Too complex section of LDAP +# ----------------------------- + +# ## +# ## Authorisation +# ## ============= +# ## + +# ## The LDAP plugin can perform a variety of queries against your +# ## LDAP server to determine questions of authorisation. See +# ## http://www.rabbitmq.com/ldap.html#authorisation for more +# ## information. + +# ## Set the query to use when determining vhost access +# ## +# ## {vhost_access_query, {in_group, +# ## "ou=${vhost}-users,ou=vhosts,dc=example,dc=com"}}, + +# ## Set the query to use when determining resource (e.g., queue) access +# ## +# ## {resource_access_query, {constant, true}}, + +# ## Set queries to determine which tags a user has +# ## +# ## {tag_queries, []} +# ]}, +# ----------------------------- + diff --git a/rabbitmq.conf.d/rabbitmq.conf b/rabbitmq.conf.d/rabbitmq.conf new file mode 100644 index 0000000000..e702ec08b4 --- /dev/null +++ b/rabbitmq.conf.d/rabbitmq.conf @@ -0,0 +1,726 @@ +# ====================================== +# RabbbitMQ broker section +# ====================================== + +## Network Connectivity +## ==================== +## +## By default, RabbitMQ will listen on all interfaces, using +## the standard (reserved) AMQP port. +## +listener.tcp.default = 5672 + + +## To listen on a specific interface, provide an IP address with port. +## For example, to listen only on localhost for both IPv4 and IPv6: +## +# IPv4 +# listener.tcp.local = 127.0.0.1:5672 +# IPv6 +# listener.tcp.local_v6 = ::1:5672 + +## You can define multiple listeners using listener names +# listener.tcp.other_port = 5673 +# listener.tcp.other_ip = 10.10.10.10:5672 + + +## SSL listeners are configured in the same fashion as TCP listeners, +## including the option to control the choice of interface. +## +# listener.ssl.default = 5671 + +## Number of Erlang processes that will accept connections for the TCP +## and SSL listeners. +## +num_acceptors.tcp = 10 +num_acceptors.ssl = 1 + + +## Maximum time for AMQP 0-8/0-9/0-9-1 handshake (after socket connection +## and SSL handshake), in milliseconds. +## +handshake_timeout = 10000 + +## Set to 'true' to perform reverse DNS lookups when accepting a +## connection. Hostnames will then be shown instead of IP addresses +## in rabbitmqctl and the management plugin. +## +reverse_dns_lookups = true + +## +## Security / AAA +## ============== +## + +## The default "guest" user is only permitted to access the server +## via a loopback interface (e.g. localhost). +## {loopback_users, [<<"guest">>]}, +## +loopback_user.guest = true + +## Uncomment the following line if you want to allow access to the +## guest user from anywhere on the network. +# loopback_user.guest = false + +## Configuring SSL. +## See http://www.rabbitmq.com/ssl.html for full documentation. +## +ssl_option.verify = verify_peer +ssl_option.fail_if_no_peer_cert = false +# ssl_option.cacertfile = /path/to/rabbitmq.crt +# ssl_option.certfile = /path/to/rabbitmq.crt +# ssl_option.keyfile = /path/to/rabbitmq.key + +## Choose the available SASL mechanism(s) to expose. +## The two default (built in) mechanisms are 'PLAIN' and +## 'AMQPLAIN'. Additional mechanisms can be added via +## plugins. +## +## See http://www.rabbitmq.com/authentication.html for more details. +## +auth_mechanism.plain = PLAIN +auth_mechanism.amqplain = AMQPLAIN + +## Select an authentication database to use. RabbitMQ comes bundled +## with a built-in auth-database, based on mnesia. +## +auth_backends.1 = internal + +auth_backends.2.authn = ldap +auth_backends.2.authz = internal + +auth_backends.3.authz = rabbit_auth_backend_uaa + +## Configurations supporting the rabbitmq_auth_mechanism_ssl and +## rabbitmq_auth_backend_ldap plugins. +## +## NB: These options require that the relevant plugin is enabled. +## See http://www.rabbitmq.com/plugins.html for further details. + + +## The RabbitMQ-auth-mechanism-ssl plugin makes it possible to +## authenticate a user based on the client's SSL certificate. +## +## To use auth-mechanism-ssl, add to or replace the auth_mechanisms +## with EXTERNAL value. +## +#auth_mechanism.external = EXTERNAL + +## The rabbitmq_auth_backend_ldap plugin allows the broker to +## perform authentication and authorisation by deferring to an +## external LDAP server. +## +## For more information about configuring the LDAP backend, see +## http://www.rabbitmq.com/ldap.html. +## +## Enable the LDAP auth backend by adding to or replacing the +## auth_backends entry: +## +# auth_backends.2 = rabbit_auth_backend_ldap + +## Add another backend +# auth_backend.3 = rabbit_auth_backend_http + + +## This pertains to both the rabbitmq_auth_mechanism_ssl plugin and +## STOMP ssl_cert_login configurations. See the rabbitmq_stomp +## configuration section later in this file and the README in +## https://github.com/rabbitmq/rabbitmq-auth-mechanism-ssl for further +## details. +## +## To use the SSL cert's CN instead of its DN as the username +## +# ssl_cert_login_from = common_name + +## SSL handshake timeout, in milliseconds. +## +# ssl_handshake_timeout = 5000 + + +## Password hashing implementation. Will only affect newly +## created users. To recalculate hash for an existing user +## it's necessary to update her password. +## +## To use SHA-512, set to rabbit_password_hashing_sha512. +## +password_hashing_module = rabbit_password_hashing_sha256 + +## When importing definitions exported from versions earlier +## than 3.6.0, it is possible to go back to MD5 (only do this +## as a temporary measure!) by setting this to rabbit_password_hashing_md5. +## +# password_hashing_module = rabbit_password_hashing_md5 + +## +## Default User / VHost +## ==================== +## + +## On first start RabbitMQ will create a vhost and a user. These +## config items control what gets created. See +## http://www.rabbitmq.com/access-control.html for further +## information about vhosts and access control. +## +default_vhost = / +default_user = guest +default_pass = guest + +default_permissions.configure = .* +default_permissions.read = .* +default_permissions.write = .* + +## Tags for default user +## +## For more details about tags, see the documentation for the +## Management Plugin at http://www.rabbitmq.com/management.html. +## +default_user_tags.administrator = true + +## Define other tags like this: +# default_user_tags.management = true +# default_user_tags.custom_tag = true + +## +## Additional network and protocol related configuration +## ===================================================== +## + +## Set the default AMQP heartbeat delay (in seconds). +## +heartbeat = 600 + +## Set the max permissible size of an AMQP frame (in bytes). +## +frame_max = 131072 + +## Set the max frame size the server will accept before connection +## tuning occurs +## +initial_frame_max = 4096 + +## Set the max permissible number of channels per connection. +## 0 means "no limit". +## +channel_max = 128 + +## Customising Socket Options. +## +## See (http://www.erlang.org/doc/man/inet.html#setopts-2) for +## further documentation. +## + +tcp_listen_option.backlog = 128 +tcp_listen_option.nodelay = true +tcp_listen_option.exit_on_close = false + +## +## Resource Limits & Flow Control +## ============================== +## +## See http://www.rabbitmq.com/memory.html for full details. + +## Memory-based Flow Control threshold. +## +vm_memory_high_watermark.relative = 0.4 + +## Alternatively, we can set a limit (in bytes) of RAM used by the node. +## +# vm_memory_high_watermark.absolute = 1073741824 + +## Or you can set absolute value using memory units (with RabbitMQ 3.6.0+). +## Absolute watermark will be ignored if relative is defined! +## +# vm_memory_high_watermark.absolute = 2GB +## +## Supported units suffixes: +## +## kb, KB: kibibytes (2^10 bytes) +## mb, MB: mebibytes (2^20) +## gb, GB: gibibytes (2^30) + + + +## Fraction of the high watermark limit at which queues start to +## page message out to disc in order to free up memory. +## +## Values greater than 0.9 can be dangerous and should be used carefully. +## +vm_memory_high_watermark_paging_ratio = 0.5 + +## Interval (in milliseconds) at which we perform the check of the memory +## levels against the watermarks. +## +memory_monitor_interval = 2500 + +## Set disk free limit (in bytes). Once free disk space reaches this +## lower bound, a disk alarm will be set - see the documentation +## listed above for more details. +## +## Absolute watermark will be ignored if relative is defined! +disk_free_limit.absolute = 50000 + +## Or you can set it using memory units (same as in vm_memory_high_watermark) +## with RabbitMQ 3.6.0+. +# disk_free_limit.absolute = 500KB +# disk_free_limit.absolute = 50mb +# disk_free_limit.absolute = 5GB + +## Alternatively, we can set a limit relative to total available RAM. +## +## Values lower than 1.0 can be dangerous and should be used carefully. +disk_free_limit.relative = 2.0 + +## +## Clustering +## ===================== +## +cluster_partition_handling = ignore + +## pause_if_all_down strategy require additional configuration +# cluster_partition_handling = pause_if_all_down + +## Recover strategy. Can be either 'autoheal' or 'ignore' +# cluster_partition_handling.pause_if_all_down.recover = ignore + +## Node names to check +# cluster_partition_handling.pause_if_all_down.node.rabbit = rabbit@localhost +# cluster_partition_handling.pause_if_all_down.node.hare = hare@localhost + +## Mirror sync batch size, in messages. Increasing this will speed +## up syncing but total batch size in bytes must not exceed 2 GiB. +## Available in RabbitMQ 3.6.0 or later. +## +mirroring_sync_batch_size = 4096 + +## Make clustering happen *automatically* at startup - only applied +## to nodes that have just been reset or started for the first time. +## See http://www.rabbitmq.com/clustering.html#auto-config for +## further details. +## +# cluster_nodes.disc.1 = rabbit@my.host.com + +## You can define multiple nodes +# cluster_nodes.disc.2 = hare@my.host.com + +## There can be also ram nodes. +## Ram nodes should not be defined together with disk nodes +# cluster_nodes.ram.1 = rabbit@my.host.com + +## Interval (in milliseconds) at which we send keepalive messages +## to other cluster members. Note that this is not the same thing +## as net_ticktime; missed keepalive messages will not cause nodes +## to be considered down. +## +# cluster_keepalive_interval = 10000 + +## +## Statistics Collection +## ===================== +## + +## Set (internal) statistics collection granularity. +## +## Can be none, coarse or fine +collect_statistics = none + +# collect_statistics = coarse + +## Statistics collection interval (in milliseconds). Increasing +## this will reduce the load on management database. +## +collect_statistics_interval = 5000 + +## +## Misc/Advanced Options +## ===================== +## +## NB: Change these only if you understand what you are doing! +## + +## Explicitly enable/disable hipe compilation. +## +hipe_compile = false + +## Timeout used when waiting for Mnesia tables in a cluster to +## become available. +## +mnesia_table_loading_timeout = 30000 + +## Size in bytes below which to embed messages in the queue index. See +## http://www.rabbitmq.com/persistence-conf.html +## +queue_index_embed_msgs_below = 4096 + +## You can also set this size in memory units +## +queue_index_embed_msgs_below = 4kb + +## ---------------------------------------------------------------------------- +## Advanced Erlang Networking/Clustering Options. +## +## See http://www.rabbitmq.com/clustering.html for details +## ---------------------------------------------------------------------------- + +# ====================================== +# Kernel section +# ====================================== + +# kernel.net_ticktime = 60 + +## ---------------------------------------------------------------------------- +## RabbitMQ Management Plugin +## +## See http://www.rabbitmq.com/management.html for details +## ---------------------------------------------------------------------------- + +# ======================================= +# Management section +# ======================================= + +## Pre-Load schema definitions from the following JSON file. See +## http://www.rabbitmq.com/management.html#load-definitions +## +# management.load_definitions = /path/to/schema.json + +## Log all requests to the management HTTP API to a file. +## +# management.http_log_dir = /path/to/access.log + +## Change the port on which the HTTP listener listens, +## specifying an interface for the web server to bind to. +## Also set the listener to use SSL and provide SSL options. +## + +# QA: Maybe use IP type like in tcp_listener? +management.listener.port = 12345 +management.listener.ip = 127.0.0.1 +# management.listener.ssl = true + +# management.listener.ssl_opts.cacertfile = /path/to/cacert.pem +# management.listener.ssl_opts.certfile = /path/to/cert.pem +# management.listener.ssl_opts.keyfile = /path/to/key.pem + +## One of 'basic', 'detailed' or 'none'. See +## http://www.rabbitmq.com/management.html#fine-stats for more details. +management.rates_mode = basic + +## Configure how long aggregated data (such as message rates and queue +## lengths) is retained. Please read the plugin's documentation in +## http://www.rabbitmq.com/management.html#configuration for more +## details. +## Your can use 'minute', 'hour' and '24hours' keys or integer key (in seconds) +management.sample_retention_policies.global.minute = 5 +management.sample_retention_policies.global.hour = 60 +management.sample_retention_policies.global.day = 1200 + +management.sample_retention_policies.basic.minute = 5 +management.sample_retention_policies.basic.hour = 60 + +management.sample_retention_policies.detailed.10 = 5 + +## ---------------------------------------------------------------------------- +## RabbitMQ Shovel Plugin +## +## See http://www.rabbitmq.com/shovel.html for details +## ---------------------------------------------------------------------------- + +## Shovel plugin config example is defined in additional.config file + + +## ---------------------------------------------------------------------------- +## RabbitMQ Stomp Adapter +## +## See http://www.rabbitmq.com/stomp.html for details +## ---------------------------------------------------------------------------- + +# ======================================= +# STOMP section +# ======================================= + +## Network Configuration - the format is generally the same as for the broker +## +stomp.listener.tcp.default = 61613 + +## Same for ssl listeners +## +# stomp.listener.ssl.default = 61614 + +## Number of Erlang processes that will accept connections for the TCP +## and SSL listeners. +## +stomp.num_acceptors.tcp = 10 +stomp.num_acceptors.ssl = 1 + +## Additional SSL options + +## Extract a name from the client's certificate when using SSL. +## +stomp.ssl_cert_login = true + +## Set a default user name and password. This is used as the default login +## whenever a CONNECT frame omits the login and passcode headers. +## +## Please note that setting this will allow clients to connect without +## authenticating! +## +# stomp.default_user = guest +# stomp.default_pass = guest + +## If a default user is configured, or you have configured use SSL client +## certificate based authentication, you can choose to allow clients to +## omit the CONNECT frame entirely. If set to true, the client is +## automatically connected as the default user or user supplied in the +## SSL certificate whenever the first frame sent on a session is not a +## CONNECT frame. +## +# stomp.implicit_connect = true + +## ---------------------------------------------------------------------------- +## RabbitMQ MQTT Adapter +## +## See https://github.com/rabbitmq/rabbitmq-mqtt/blob/stable/README.md +## for details +## ---------------------------------------------------------------------------- + +# ======================================= +# MQTT section +# ======================================= + +## Set the default user name and password. Will be used as the default login +## if a connecting client provides no other login details. +## +## Please note that setting this will allow clients to connect without +## authenticating! +## +# mqtt.default_user = guest +# mqtt.default_pass = guest + +## Enable anonymous access. If this is set to false, clients MUST provide +## login information in order to connect. See the default_user/default_pass +## configuration elements for managing logins without authentication. +## +# mqtt.allow_anonymous = true + +## If you have multiple chosts, specify the one to which the +## adapter connects. +## +mqtt.vhost = / + +## Specify the exchange to which messages from MQTT clients are published. +## +mqtt.exchange = amq.topic + +## Specify TTL (time to live) to control the lifetime of non-clean sessions. +## +# mqtt.subscription_ttl = 1800000 + +## Set the prefetch count (governing the maximum number of unacknowledged +## messages that will be delivered). +## +mqtt.prefetch = 10 + +## TCP/SSL Configuration (as per the broker configuration). +## +mqtt.listener.tcp.default = 1883 + +## Same for ssl listener +## +# mqtt.listener.ssl.default = 1884 + +## Number of Erlang processes that will accept connections for the TCP +## and SSL listeners. +## +mqtt.num_acceptors.tcp = 10 +mqtt.num_acceptors.ssl = 1 + +## TCP/Socket options (as per the broker configuration). +## +# mqtt.tcp_listen_option.backlog = 128 +# mqtt.tcp_listen_option.nodelay = true + +## ---------------------------------------------------------------------------- +## RabbitMQ AMQP 1.0 Support +## +## See https://github.com/rabbitmq/rabbitmq-amqp1.0/blob/stable/README.md +## for details +## ---------------------------------------------------------------------------- + +# ======================================= +# AMQP_1 section +# ======================================= + + +## Connections that are not authenticated with SASL will connect as this +## account. See the README for more information. +## +## Please note that setting this will allow clients to connect without +## authenticating! +## +amqp1_0.default_user = guest + +## Enable protocol strict mode. See the README for more information. +## +amqp1_0.protocol_strict_mode = false + +## Lager controls logging. +## See https://github.com/basho/lager for more documentation +## +## Log direcrory, taken from the RABBITMQ_LOG_BASE env variable by default. +## +# log.dir = /var/log/rabbitmq + +## Logging to console (can be true or false) +## +# log.console = false + +## Loglevel to log to console +## +# log.console.level = info + +## Logging to file. Can be false or filename. +## Default: +# log.file = rabbit.log + +## To turn off: +# log.file = false + +## Loglevel to log to file +## +# log.file.level = info + +## File rotation config. No rotation by defualt. +## DO NOT SET rotation date to ''. Leave unset if require "" value +# log.file.rotation.date = $D0 +# log.file.rotation.size = 0 + + +## QA: Config for syslog logging +# log.syslog = false +# log.syslog.identity = rabbitmq +# log.syslog.level = info +# log.syslog.facility = daemon + + +## ---------------------------------------------------------------------------- +## RabbitMQ LDAP Plugin +## +## See http://www.rabbitmq.com/ldap.html for details. +## +## ---------------------------------------------------------------------------- + +# ======================================= +# LDAP section +# ======================================= + +## +## Connecting to the LDAP server(s) +## ================================ +## + +## Specify servers to bind to. You *must* set this in order for the plugin +## to work properly. +## +# ldap.servers.1 = your-server-name-goes-here + +## You can define multiple servers +# ldap.servers.2 = your-other-server + +## Connect to the LDAP server using SSL +## +# ldap.use_ssl = false + +## Specify the LDAP port to connect to +## +# ldap.port = 389 + +## LDAP connection timeout, in milliseconds or 'infinity' +## +# ldap.timeout = infinity + +## Or number +# ldap.timeout = 500 + +## Enable logging of LDAP queries. +## One of +## - false (no logging is performed) +## - true (verbose logging of the logic used by the plugin) +## - network (as true, but additionally logs LDAP network traffic) +## +## Defaults to false. +## +# ldap.log = false + +## Also can be true or network +# ldap.log = true +# ldap.log = network + +## +## Authentication +## ============== +## + +## Pattern to convert the username given through AMQP to a DN before +## binding +## +# ldap.user_dn_pattern = cn=${username},ou=People,dc=example,dc=com + +## Alternatively, you can convert a username to a Distinguished +## Name via an LDAP lookup after binding. See the documentation for +## full details. + +## When converting a username to a dn via a lookup, set these to +## the name of the attribute that represents the user name, and the +## base DN for the lookup query. +## +# ldap.dn_lookup_attribute = userPrincipalName +# ldap.dn_lookup_base = DC=gopivotal,DC=com + +## Controls how to bind for authorisation queries and also to +## retrieve the details of users logging in without presenting a +## password (e.g., SASL EXTERNAL). +## One of +## - as_user (to bind as the authenticated user - requires a password) +## - anon (to bind anonymously) +## - {UserDN, Password} (to bind with a specified user name and password) +## +## Defaults to 'as_user'. +## +# ldap.other_bind = as_user + +## Or can be more complex: +# ldap.other_bind.user_dn = User +# ldap.other_bind.password = Password + +## If user_dn and password defined - other options is ignored. + +# ----------------------------- +# Too complex section of LDAP +# ----------------------------- + +## +## Authorisation +## ============= +## + +## The LDAP plugin can perform a variety of queries against your +## LDAP server to determine questions of authorisation. See +## http://www.rabbitmq.com/ldap.html#authorisation for more +## information. + +## Following configuration should be defined in additional.config file +## DO NOT UNCOMMENT THIS LINES! + +## Set the query to use when determining vhost access +## +## {vhost_access_query, {in_group, +## "ou=${vhost}-users,ou=vhosts,dc=example,dc=com"}}, + +## Set the query to use when determining resource (e.g., queue) access +## +## {resource_access_query, {constant, true}}, + +## Set queries to determine which tags a user has +## +## {tag_queries, []} +# ]}, +# ----------------------------- diff --git a/scripts/cuttlefish b/scripts/cuttlefish Binary files differnew file mode 100755 index 0000000000..6c1e4bbb89 --- /dev/null +++ b/scripts/cuttlefish diff --git a/scripts/rabbitmq-defaults b/scripts/rabbitmq-defaults index c5d87822a2..bccd0d7435 100644 --- a/scripts/rabbitmq-defaults +++ b/scripts/rabbitmq-defaults @@ -38,6 +38,9 @@ CONFIG_FILE=${SYS_PREFIX}/etc/rabbitmq/rabbitmq LOG_BASE=${SYS_PREFIX}/var/log/rabbitmq MNESIA_BASE=${SYS_PREFIX}/var/lib/rabbitmq/mnesia ENABLED_PLUGINS_FILE=${SYS_PREFIX}/etc/rabbitmq/enabled_plugins +GENERATED_CONFIG_DIR=${SYS_PREFIX}/var/lib/rabbitmq/config +ADVANCED_CONFIG_FILE=${SYS_PREFIX}/etc/rabbitmq/advanced +SCHEMA_DIR=${RABBITMQ_HOME}/priv/schema PLUGINS_DIR="${RABBITMQ_HOME}/plugins" IO_THREAD_POOL_SIZE=64 diff --git a/scripts/rabbitmq-defaults.bat b/scripts/rabbitmq-defaults.bat index 27edd0d11e..5612af967a 100644 --- a/scripts/rabbitmq-defaults.bat +++ b/scripts/rabbitmq-defaults.bat @@ -41,6 +41,9 @@ set CONFIG_FILE=!RABBITMQ_BASE!\rabbitmq set LOG_BASE=!RABBITMQ_BASE!\log
set MNESIA_BASE=!RABBITMQ_BASE!\db
set ENABLED_PLUGINS_FILE=!RABBITMQ_BASE!\enabled_plugins
+set GENERATED_CONFIG_DIR=!RABBITMQ_BASE!\config
+set ADVANCED_CONFIG_FILE=!RABBITMQ_BASE!\advanced
+set SCHEMA_DIR=!RABBITMQ_HOME!\priv\schema
REM PLUGINS_DIR="${RABBITMQ_HOME}/plugins"
for /f "delims=" %%F in ("!TDP0!..\plugins") do set PLUGINS_DIR=%%~dpsF%%~nF%%~xF
diff --git a/scripts/rabbitmq-env b/scripts/rabbitmq-env index 2a0d48085b..8ceb8c94f2 100644 --- a/scripts/rabbitmq-env +++ b/scripts/rabbitmq-env @@ -184,6 +184,9 @@ DEFAULT_NODE_PORT=5672 [ "x" = "x$RABBITMQ_SERVER_ADDITIONAL_ERL_ARGS" ] && RABBITMQ_SERVER_ADDITIONAL_ERL_ARGS=${SERVER_ADDITIONAL_ERL_ARGS} [ "x" = "x$RABBITMQ_MNESIA_DIR" ] && RABBITMQ_MNESIA_DIR=${MNESIA_DIR} [ "x" = "x$RABBITMQ_MNESIA_DIR" ] && RABBITMQ_MNESIA_DIR=${RABBITMQ_MNESIA_BASE}/${RABBITMQ_NODENAME} +[ "x" = "x$RABBITMQ_GENERATED_CONFIG_DIR" ] && RABBITMQ_GENERATED_CONFIG_DIR=${GENERATED_CONFIG_DIR} +[ "x" = "x$RABBITMQ_ADVANCED_CONFIG_FILE" ] && RABBITMQ_ADVANCED_CONFIG_FILE=${ADVANCED_CONFIG_FILE} +[ "x" = "x$RABBITMQ_SCHEMA_DIR" ] && RABBITMQ_SCHEMA_DIR=${SCHEMA_DIR} rmq_normalize_path_var \ RABBITMQ_CONFIG_FILE \ @@ -258,7 +261,8 @@ if [ "${RABBITMQ_DEV_ENV}" ]; then RABBITMQ_ENABLED_PLUGINS_FILE="${enabled_plugins_file}" fi fi - + + if [ -d "${RABBITMQ_PLUGINS_DIR}" ]; then # RabbitMQ was started with "make run-broker" from its own # source tree. Take rabbit_common from the plugins directory. diff --git a/scripts/rabbitmq-env.bat b/scripts/rabbitmq-env.bat index 2cb3a985de..430395accf 100644 --- a/scripts/rabbitmq-env.bat +++ b/scripts/rabbitmq-env.bat @@ -77,8 +77,8 @@ if "!RABBITMQ_NODENAME!"=="" ( if "!NODENAME!"=="" (
REM We use Erlang to query the local hostname because
REM !COMPUTERNAME! and Erlang may return different results.
- REM Start erl with -sname to make sure epmd is started.
- call "%ERLANG_HOME%\bin\erl.exe" -A0 -noinput -boot start_clean -sname rabbit-prelaunch-epmd -eval "init:stop()." >nul 2>&1
+ REM Start erl with -sname to make sure epmd is started.
+ call "%ERLANG_HOME%\bin\erl.exe" -A0 -noinput -boot start_clean -sname rabbit-prelaunch-epmd -eval "init:stop()." >nul 2>&1
for /f "delims=" %%F in ('call "%ERLANG_HOME%\bin\erl.exe" -A0 -noinput -boot start_clean -eval "net_kernel:start([list_to_atom(""rabbit-gethostname-"" ++ os:getpid()), %NAMETYPE%]), [_, H] = string:tokens(atom_to_list(node()), ""@""), io:format(""~s~n"", [H]), init:stop()."') do @set HOSTNAME=%%F
set RABBITMQ_NODENAME=rabbit@!HOSTNAME!
set HOSTNAME=
@@ -158,6 +158,31 @@ if "!RABBITMQ_CONFIG_FILE!"=="" ( )
)
+if "!RABBITMQ_GENERATED_CONFIG_DIR!"=="" (
+ if "!GENERATED_CONFIG_DIR!"=="" (
+ set RABBITMQ_GENERATED_CONFIG_DIR=!RABBITMQ_BASE!\config
+ ) else (
+ set RABBITMQ_GENERATED_CONFIG_DIR=!GENERATED_CONFIG_DIR!
+ )
+)
+
+if "!RABBITMQ_ADVANCED_CONFIG_FILE!"=="" (
+ if "!ADVANCED_CONFIG_FILE!"=="" (
+ set RABBITMQ_ADVANCED_CONFIG_FILE=!RABBITMQ_BASE!\advanced
+ ) else (
+ set RABBITMQ_ADVANCED_CONFIG_FILE=!GENERATED_CONFIG_DIR!
+ )
+)
+
+if "!RABBITMQ_SCHEMA_DIR!" == "" (
+ if "!SCHEMA_DIR!"=="" (
+ set RABBITMQ_SCHEMA_DIR=!RABBITMQ_HOME!\priv\schema
+ ) else (
+ set RABBITMQ_SCHEMA_DIR=!SCHEMA_DIR!
+ )
+)
+
+
REM [ "x" = "x$RABBITMQ_LOG_BASE" ] && RABBITMQ_LOG_BASE=${LOG_BASE}
if "!RABBITMQ_LOG_BASE!"=="" (
if "!LOG_BASE!"=="" (
diff --git a/scripts/rabbitmq-server b/scripts/rabbitmq-server index cb341dc09c..0e3f06baf9 100755 --- a/scripts/rabbitmq-server +++ b/scripts/rabbitmq-server @@ -73,8 +73,11 @@ RABBITMQ_DIST_PORT=$RABBITMQ_DIST_PORT \ -hidden \ -s rabbit_prelaunch \ ${RABBITMQ_NAME_TYPE} rabbitmqprelaunch$$ \ + -conf_advanced "${RABBITMQ_ADVANCED_CONFIG_FILE}" \ + -rabbit enabled_plugins_file "\"$RABBITMQ_ENABLED_PLUGINS_FILE\"" \ + -rabbit plugins_dir "\"$RABBITMQ_PLUGINS_DIR\"" \ -extra "${RABBITMQ_NODENAME}" - + PRELAUNCH_RESULT=$? if [ ${PRELAUNCH_RESULT} = 2 ] ; then # dist port is mentioned in config, so do not set it @@ -86,10 +89,25 @@ else exit ${PRELAUNCH_RESULT} fi +if [ ! -f "${RABBITMQ_SCHEMA_DIR}/rabbitmq.schema" ]; then + cp "${RABBITMQ_HOME}/priv/schema/rabbitmq.schema" "${RABBITMQ_SCHEMA_DIR}" +fi + set -e -RABBITMQ_CONFIG_ARG= -[ -f "${RABBITMQ_CONFIG_FILE}.config" ] && RABBITMQ_CONFIG_ARG="-config ${RABBITMQ_CONFIG_FILE}" +if [ -f "${RABBITMQ_CONFIG_FILE}.config" ]; then + RABBITMQ_CONFIG_ARG="-config ${RABBITMQ_CONFIG_FILE}" +elif [ -f "${RABBITMQ_CONFIG_FILE}.conf" ]; then + RABBITMQ_CONFIG_ARG="-conf ${RABBITMQ_CONFIG_FILE} \ + -conf_dir ${RABBITMQ_GENERATED_CONFIG_DIR} \ + -conf_script_dir `dirname $0` \ + -conf_schema_dir ${RABBITMQ_SCHEMA_DIR}" + if [ -f "${RABBITMQ_ADVANCED_CONFIG_FILE}.config" ]; then + RABBITMQ_CONFIG_ARG="${RABBITMQ_CONFIG_ARG} \ + -conf_advanced ${RABBITMQ_ADVANCED_CONFIG_FILE} \ + -config ${RABBITMQ_ADVANCED_CONFIG_FILE}" + fi +fi RABBITMQ_LISTEN_ARG= [ "x" != "x$RABBITMQ_NODE_PORT" ] && [ "x" != "x$RABBITMQ_NODE_IP_ADDRESS" ] && RABBITMQ_LISTEN_ARG="-rabbit tcp_listeners [{\""${RABBITMQ_NODE_IP_ADDRESS}"\","${RABBITMQ_NODE_PORT}"}]" diff --git a/scripts/rabbitmq-server.bat b/scripts/rabbitmq-server.bat index 428f319bfa..33e316a07f 100644 --- a/scripts/rabbitmq-server.bat +++ b/scripts/rabbitmq-server.bat @@ -21,6 +21,7 @@ rem Preserve values that might contain exclamation marks before rem enabling delayed expansion
set TDP0=%~dp0
set STAR=%*
+set CONF_SCRIPT_DIR="%~dp0"
setlocal enabledelayedexpansion
REM Get default settings with user overrides for (RABBITMQ_)<var_name>
@@ -41,11 +42,16 @@ if not exist "!ERLANG_HOME!\bin\erl.exe" ( set RABBITMQ_EBIN_ROOT=!RABBITMQ_HOME!\ebin
+set RABBITMQ_CONFIG_FILE="!RABBITMQ_CONFIG_FILE!"
+
"!ERLANG_HOME!\bin\erl.exe" ^
-pa "!RABBITMQ_EBIN_ROOT!" ^
-noinput -hidden ^
-s rabbit_prelaunch ^
!RABBITMQ_NAME_TYPE! rabbitmqprelaunch!RANDOM!!TIME:~9! ^
+ -conf_advanced "!RABBITMQ_ADVANCED_CONFIG_FILE!" ^
+ -rabbit enabled_plugins_file "!RABBITMQ_ENABLED_PLUGINS_FILE!" ^
+ -rabbit plugins_dir "!$RABBITMQ_PLUGINS_DIR!" ^
-extra "!RABBITMQ_NODENAME!"
if ERRORLEVEL 2 (
@@ -56,13 +62,25 @@ if ERRORLEVEL 2 ( set RABBITMQ_DIST_ARG=-kernel inet_dist_listen_min !RABBITMQ_DIST_PORT! -kernel inet_dist_listen_max !RABBITMQ_DIST_PORT!
)
+if not exist "!RABBITMQ_SCHEMA_DIR!\rabbitmq.schema" (
+ copy "!RABBITMQ_HOME!\priv\schema\rabbitmq.schema" "!RABBITMQ_SCHEMA_DIR!\rabbitmq.schema"
+)
+
set RABBITMQ_EBIN_PATH="-pa !RABBITMQ_EBIN_ROOT!"
if exist "!RABBITMQ_CONFIG_FILE!.config" (
set RABBITMQ_CONFIG_ARG=-config "!RABBITMQ_CONFIG_FILE!"
-) else (
- set RABBITMQ_CONFIG_ARG=
-)
+) else if exist "!RABBITMQ_CONFIG_FILE!.conf" (
+ set RABBITMQ_CONFIG_ARG=-conf "!RABBITMQ_CONFIG_FILE!" ^
+ -conf_dir !RABBITMQ_GENERATED_CONFIG_DIR! ^
+ -conf_script_dir !CONF_SCRIPT_DIR:\=/! ^
+ -conf_schema_dir !RABBITMQ_SCHEMA_DIR!
+ if exist "!RABBITMQ_ADVANCED_CONFIG_FILE!.config" (
+ set RABBITMQ_CONFIG_ARG=!RABBITMQ_CONFIG_ARG! ^
+ -conf_advanced "!RABBITMQ_ADVANCED_CONFIG_FILE!" ^
+ -config "!RABBITMQ_ADVANCED_CONFIG_FILE!"
+ )
+)
set RABBITMQ_LISTEN_ARG=
if not "!RABBITMQ_NODE_IP_ADDRESS!"=="" (
diff --git a/scripts/rabbitmq-service.bat b/scripts/rabbitmq-service.bat index 762360bafc..f302087f91 100644 --- a/scripts/rabbitmq-service.bat +++ b/scripts/rabbitmq-service.bat @@ -21,6 +21,7 @@ rem Preserve values that might contain exclamation marks before rem enabling delayed expansion
set TN0=%~n0
set TDP0=%~dp0
+set CONF_SCRIPT_DIR="%~dp0"
set P1=%1
setlocal enabledelayedexpansion
@@ -123,10 +124,16 @@ if errorlevel 1 ( set RABBITMQ_EBIN_ROOT=!RABBITMQ_HOME!\ebin
+set RABBITMQ_CONFIG_FILE="!RABBITMQ_CONFIG_FILE!"
+
+
"!ERLANG_HOME!\bin\erl.exe" ^
-pa "!RABBITMQ_EBIN_ROOT!" ^
-noinput -hidden ^
-s rabbit_prelaunch ^
+ -conf_advanced "!RABBITMQ_ADVANCED_CONFIG_FILE!" ^
+ -rabbit enabled_plugins_file "!RABBITMQ_ENABLED_PLUGINS_FILE!" ^
+ -rabbit plugins_dir "!$RABBITMQ_PLUGINS_DIR!" ^
!RABBITMQ_NAME_TYPE! rabbitmqprelaunch!RANDOM!!TIME:~9!
if ERRORLEVEL 3 (
@@ -141,16 +148,28 @@ if ERRORLEVEL 3 ( set RABBITMQ_DIST_ARG=-kernel inet_dist_listen_min !RABBITMQ_DIST_PORT! -kernel inet_dist_listen_max !RABBITMQ_DIST_PORT!
)
- REM Try to create config file, if it doesn't exist
- REM It still can fail to be created, but at least not for default install
-if not exist "!RABBITMQ_CONFIG_FILE!.config" (
- echo []. > !RABBITMQ_CONFIG_FILE!.config
+if not exist "!RABBITMQ_SCHEMA_DIR!\rabbitmq.schema" (
+ copy "!RABBITMQ_HOME!\priv\schema\rabbitmq.schema" "!RABBITMQ_SCHEMA_DIR!\rabbitmq.schema"
+ REM Try to create config file, if it doesn't exist + REM It still can fail to be created, but at least not for default install +if not exist "!RABBITMQ_CONFIG_FILE!.config" ( + echo []. > !RABBITMQ_CONFIG_FILE!.config )
if exist "!RABBITMQ_CONFIG_FILE!.config" (
set RABBITMQ_CONFIG_ARG=-config "!RABBITMQ_CONFIG_FILE!"
) else (
- set RABBITMQ_CONFIG_ARG=
+ rem Always specify generated config arguments, we cannot
+ rem assume .conf file is available
+ set RABBITMQ_CONFIG_ARG=-conf "!RABBITMQ_CONFIG_FILE!" ^
+ -conf_dir !RABBITMQ_GENERATED_CONFIG_DIR! ^
+ -conf_script_dir !CONF_SCRIPT_DIR:\=/! ^
+ -conf_schema_dir !RABBITMQ_SCHEMA_DIR!
+ if exist "!RABBITMQ_ADVANCED_CONFIG_FILE!.config" (
+ set RABBITMQ_CONFIG_ARG=!RABBITMQ_CONFIG_ARG! ^
+ -conf_advanced "!RABBITMQ_ADVANCED_CONFIG_FILE!" ^
+ -config "!RABBITMQ_ADVANCED_CONFIG_FILE!"
+ )
)
set RABBITMQ_LISTEN_ARG=
@@ -207,6 +226,8 @@ set ERLANG_SERVICE_ARGUMENTS= ^ !RABBITMQ_DIST_ARG! ^
!STARVAR!
+echo "!ERLANG_SERVICE_ARGUMENTS!" > "!RABBITMQ_CONFIG_FILE!.txt"
+
set ERLANG_SERVICE_ARGUMENTS=!ERLANG_SERVICE_ARGUMENTS:\=\\!
set ERLANG_SERVICE_ARGUMENTS=!ERLANG_SERVICE_ARGUMENTS:"=\"!
diff --git a/src/rabbit.erl b/src/rabbit.erl index 3dbee29543..7816cd53aa 100644 --- a/src/rabbit.erl +++ b/src/rabbit.erl @@ -272,6 +272,7 @@ start() -> boot() -> start_it(fun() -> + ensure_config(), ok = ensure_application_loaded(), HipeResult = rabbit_hipe:maybe_hipe_compile(), ok = start_logger(), @@ -285,6 +286,20 @@ boot() -> broker_start() end). +ensure_config() -> + case rabbit_config:prepare_and_use_config() of + {error, Reason} -> + {Format, Arg} = case Reason of + {generation_error, Error} -> {"~s", [Error]}; + Other -> {"~p", [Other]} + end, + log_boot_error_and_exit(generate_config_file, + "~nConfig file generation failed "++Format, + Arg); + ok -> ok + end. + + broker_start() -> Plugins = rabbit_plugins:setup(), ToBeLoaded = Plugins ++ ?APPS, @@ -902,32 +917,7 @@ home_dir() -> end. config_files() -> - Abs = fun (F) -> - filename:absname(filename:rootname(F, ".config") ++ ".config") - end, - case init:get_argument(config) of - {ok, Files} -> [Abs(File) || [File] <- Files]; - error -> case config_setting() of - none -> []; - File -> [Abs(File) ++ " (not found)"] - end - end. - -%% This is a pain. We want to know where the config file is. But we -%% can't specify it on the command line if it is missing or the VM -%% will fail to start, so we need to find it by some mechanism other -%% than init:get_arguments/0. We can look at the environment variable -%% which is responsible for setting it... but that doesn't work for a -%% Windows service since the variable can change and the service not -%% be reinstalled, so in that case we add a magic application env. -config_setting() -> - case application:get_env(rabbit, windows_service_config) of - {ok, File1} -> File1; - undefined -> case os:getenv("RABBITMQ_CONFIG_FILE") of - false -> none; - File2 -> File2 - end - end. + rabbit_config:config_files(). %% We don't want this in fhc since it references rabbit stuff. And we can't put %% this in the bootstep directly. diff --git a/src/rabbit_config.erl b/src/rabbit_config.erl new file mode 100644 index 0000000000..67e7523ec0 --- /dev/null +++ b/src/rabbit_config.erl @@ -0,0 +1,179 @@ +-module(rabbit_config). + +-export([ + generate_config_file/5, + prepare_and_use_config/0, + prepare_config/1, + update_app_config/1, + schema_dir/0, + config_files/0, + get_advanced_config/0 + ]). + +prepare_and_use_config() -> + case legacy_erlang_term_config_used() of + true -> + %% Use .config file + ok; + false -> + case prepare_config(get_confs()) of + ok -> + %% No .conf to generate from + ok; + {ok, GeneratedConfigFile} -> + %% Generated config file + update_app_config(GeneratedConfigFile); + {error, Err} -> + {error, Err} + end + end. + +%% we support both the classic Erlang term +%% config file (rabbitmq.config) as well as rabbitmq.conf +legacy_erlang_term_config_used() -> + case init:get_argument(config) of + error -> false; + {ok, [Config | _]} -> + ConfigFile = Config ++ ".config", + rabbit_file:is_file(ConfigFile) + andalso + get_advanced_config() == none + end. + +get_confs() -> + case init:get_argument(conf) of + {ok, Configs} -> Configs; + _ -> [] + end. + +prepare_config(Configs) -> + case {init:get_argument(conf_dir), init:get_argument(conf_script_dir)} of + {{ok, ConfDir}, {ok, ScriptDir}} -> + ConfFiles = [Config ++ ".conf" || [Config] <- Configs, + rabbit_file:is_file(Config ++ + ".conf")], + case ConfFiles of + [] -> ok; + _ -> + case generate_config_file(ConfFiles, ConfDir, ScriptDir) of + {ok, GeneratedConfigFile} -> + {ok, GeneratedConfigFile}; + {error, Reason} -> + {error, Reason} + end + end; + _ -> ok + end. + +update_app_config(ConfigFile) -> + ok = application_controller:change_application_data([], [ConfigFile]). + +generate_config_file(ConfFiles, ConfDir, ScriptDir) -> + generate_config_file(ConfFiles, ConfDir, ScriptDir, + schema_dir(), get_advanced_config()). + + +generate_config_file(ConfFiles, ConfDir, ScriptDir, SchemaDir, Advanced) -> + prepare_plugin_schemas(SchemaDir), + % SchemaFile = filename:join([ScriptDir, "rabbitmq.schema"]), + Cuttlefish = filename:join([ScriptDir, "cuttlefish"]), + GeneratedDir = filename:join([ConfDir, "generated"]), + + AdvancedConfigArg = case check_advanced_config(Advanced) of + {ok, FileName} -> [" -a ", FileName]; + none -> [] + end, + rabbit_file:recursive_delete([GeneratedDir]), + Command = lists:concat(["escript ", "\"", Cuttlefish, "\"", + " -f rabbitmq -s ", "\"", SchemaDir, "\"", + " -e ", "\"", ConfDir, "\"", + [[" -c ", ConfFile] || ConfFile <- ConfFiles], + AdvancedConfigArg]), + Result = rabbit_misc:os_cmd(Command), + case string:str(Result, " -config ") of + 0 -> {error, {generation_error, Result}}; + _ -> + [OutFile] = rabbit_file:wildcard("rabbitmq.*.config", GeneratedDir), + ResultFile = filename:join([GeneratedDir, "rabbitmq.config"]), + rabbit_file:rename(filename:join([GeneratedDir, OutFile]), + ResultFile), + {ok, ResultFile} + end. + +schema_dir() -> + case init:get_argument(conf_schema_dir) of + {ok, SchemaDir} -> SchemaDir; + _ -> + case code:priv_dir(rabbit) of + {error, bad_name} -> filename:join([".", "priv", "schema"]); + PrivDir -> filename:join([PrivDir, "schema"]) + end + end. + +check_advanced_config(none) -> none; +check_advanced_config(ConfigName) -> + case rabbit_file:is_file(ConfigName) of + true -> {ok, ConfigName}; + false -> none + end. + +get_advanced_config() -> + case init:get_argument(conf_advanced) of + %% There can be only one advanced.config + {ok, [FileName | _]} -> + ConfigName = FileName ++ ".config", + case rabbit_file:is_file(ConfigName) of + true -> ConfigName; + false -> none + end; + _ -> none + end. + + +prepare_plugin_schemas(SchemaDir) -> + case rabbit_file:is_dir(SchemaDir) of + true -> rabbit_plugins:extract_schemas(SchemaDir); + false -> ok + end. + + +config_files() -> + Abs = fun (F, Ex) -> filename:absname(filename:rootname(F, Ex) ++ Ex) end, + case legacy_erlang_term_config_used() of + true -> + case init:get_argument(config) of + {ok, Files} -> [Abs(File, ".config") || [File] <- Files]; + error -> case config_setting() of + none -> []; + File -> [Abs(File, ".config") + ++ + " (not found)"] + end + end; + false -> + ConfFiles = [Abs(File, ".conf") || File <- get_confs()], + AdvancedFiles = case get_advanced_config() of + none -> []; + FileName -> [Abs(FileName, ".config")] + end, + AdvancedFiles ++ ConfFiles + + end. + + +%% This is a pain. We want to know where the config file is. But we +%% can't specify it on the command line if it is missing or the VM +%% will fail to start, so we need to find it by some mechanism other +%% than init:get_arguments/0. We can look at the environment variable +%% which is responsible for setting it... but that doesn't work for a +%% Windows service since the variable can change and the service not +%% be reinstalled, so in that case we add a magic application env. +config_setting() -> + case application:get_env(rabbit, windows_service_config) of + {ok, File1} -> File1; + undefined -> case os:getenv("RABBITMQ_CONFIG_FILE") of + false -> none; + File2 -> File2 + end + end. + diff --git a/src/rabbit_plugins.erl b/src/rabbit_plugins.erl index c7f5d501bf..2f084ed28a 100644 --- a/src/rabbit_plugins.erl +++ b/src/rabbit_plugins.erl @@ -16,9 +16,11 @@ -module(rabbit_plugins). -include("rabbit.hrl"). +-include_lib("stdlib/include/zip.hrl"). -export([setup/0, active/0, read_enabled/1, list/1, list/2, dependencies/3]). -export([ensure/1]). +-export([extract_schemas/1]). %%---------------------------------------------------------------------------- @@ -46,6 +48,7 @@ ensure(FileJustChanged0) -> FileJustChanged -> Enabled = read_enabled(OurFile), Wanted = prepare_plugins(Enabled), + rabbit_config:prepare_and_use_config(), Current = active(), Start = Wanted -- Current, Stop = Current -- Wanted, @@ -79,6 +82,50 @@ setup() -> Enabled = read_enabled(EnabledFile), prepare_plugins(Enabled). +extract_schemas(SchemaDir) -> + application:load(rabbit), + {ok, EnabledFile} = application:get_env(rabbit, enabled_plugins_file), + Enabled = read_enabled(EnabledFile), + + {ok, PluginsDistDir} = application:get_env(rabbit, plugins_dir), + + AllPlugins = list(PluginsDistDir), + Wanted = dependencies(false, Enabled, AllPlugins), + WantedPlugins = lookup_plugins(Wanted, AllPlugins), + [ extract_schema(Plugin, SchemaDir) || Plugin <- WantedPlugins ], + application:unload(rabbit), + ok. + +extract_schema(#plugin{type = ez, location = Location}, SchemaDir) -> + {ok, Files} = zip:extract(Location, + [memory, {file_filter, + fun(#zip_file{name = Name}) -> + string:str(Name, "priv/schema") > 0 + end}]), + lists:foreach( + fun({FileName, Content}) -> + ok = file:write_file(filename:join([SchemaDir, + filename:basename(FileName)]), + Content) + end, + Files), + ok; +extract_schema(#plugin{type = dir, location = Location}, SchemaDir) -> + PluginSchema = filename:join([Location, + "priv", + "schema"]), + case rabbit_file:is_dir(PluginSchema) of + false -> ok; + true -> + PluginSchemaFiles = + [ filename:join(PluginSchema, FileName) + || FileName <- rabbit_file:wildcard(".*\\.schema", + PluginSchema) ], + [ file:copy(SchemaFile, SchemaDir) + || SchemaFile <- PluginSchemaFiles ] + end. + + %% @doc Lists the plugins which are currently running. active() -> {ok, ExpandDir} = application:get_env(rabbit, plugins_expand_dir), diff --git a/src/rabbit_prelaunch.erl b/src/rabbit_prelaunch.erl index 5ecdd75acc..3f83a153ea 100644 --- a/src/rabbit_prelaunch.erl +++ b/src/rabbit_prelaunch.erl @@ -83,7 +83,7 @@ dist_port_set_check() -> false -> ok; File -> - case file:consult(File ++ ".config") of + case get_config(File) of {ok, [Config]} -> Kernel = pget(kernel, Config, []), case {pget(inet_dist_listen_min, Kernel, none), @@ -98,6 +98,16 @@ dist_port_set_check() -> end end. +get_config(File) -> + case rabbit_file:is_file(File ++ ".config") of + true -> file:consult(File ++ ".config"); + false -> + case rabbit_config:get_advanced_config() of + none -> {error, enoent}; + FileName -> file:consult(FileName) + end + end. + dist_port_range_check() -> case os:getenv("RABBITMQ_DIST_PORT") of false -> ok; |
