summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore3
-rw-r--r--Makefile2
-rw-r--r--docs/rabbitmqctl.1.xml61
-rw-r--r--include/rabbit_cli.hrl2
-rw-r--r--packaging/RPMS/Fedora/rabbitmq-server.spec3
-rw-r--r--packaging/debs/Debian/debian/changelog6
-rwxr-xr-xscripts/rabbitmq-server22
-rwxr-xr-xscripts/rabbitmq-server-ha.ocf161
-rw-r--r--scripts/rabbitmq-server.bat23
-rw-r--r--scripts/rabbitmq-service.bat31
-rwxr-xr-xscripts/rabbitmqctl2
-rw-r--r--src/rabbit.app.src3
-rw-r--r--src/rabbit_auth_backend_dummy.erl48
-rw-r--r--src/rabbit_auth_backend_internal.erl400
-rw-r--r--src/rabbit_cli.erl10
-rw-r--r--src/rabbit_control_main.erl114
-rw-r--r--src/rabbit_hipe.erl7
-rw-r--r--src/rabbit_plugins_main.erl4
-rw-r--r--src/rabbit_types.erl168
19 files changed, 304 insertions, 766 deletions
diff --git a/.gitignore b/.gitignore
index c4375bbe48..a42a3ab53f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,6 +4,7 @@
*.beam
.erlang.mk/
cover/
+debug/
deps/
debug/
doc/
@@ -12,6 +13,8 @@ etc/
logs/
plugins/
+PACKAGES/
+
rabbit.d
# Generated sources files.
diff --git a/Makefile b/Makefile
index 25ddceac94..9241608496 100644
--- a/Makefile
+++ b/Makefile
@@ -129,7 +129,7 @@ $(TARGETS_IN_RABBITMQ_TEST): $(ERLANG_MK_RECURSIVE_TEST_DEPS_LIST) \
grep -E '^xmlto version 0\.0\.([0-9]|1[1-8])$$' >/dev/null || \
opt='--stringparam man.indent.verbatims=0' ; \
xsltproc --novalid $(DOCS_DIR)/examples-to-end.xsl $< > $<.tmp && \
- xmlto -o $(DOCS_DIR) $$opt man $< 2>&1 | (grep -v '^Note: Writing' || :) && \
+ xmlto -vv -o $(DOCS_DIR) $$opt man $< 2>&1 | (grep -v '^Note: Writing' || :) && \
test -f $@ && \
rm $<.tmp
diff --git a/docs/rabbitmqctl.1.xml b/docs/rabbitmqctl.1.xml
index a4ece7435e..55b557a81a 100644
--- a/docs/rabbitmqctl.1.xml
+++ b/docs/rabbitmqctl.1.xml
@@ -535,7 +535,7 @@
</listitem>
</varlistentry>
<varlistentry>
- <term><cmdsynopsis><command>sync_queue</command> <arg choice="req">queue</arg></cmdsynopsis>
+ <term><cmdsynopsis><command>sync_queue</command> <arg choice="opt">-p <replaceable>vhost</replaceable></arg> <arg choice="req">queue</arg></cmdsynopsis>
</term>
<listitem>
<variablelist>
@@ -564,7 +564,7 @@
</listitem>
</varlistentry>
<varlistentry>
- <term><cmdsynopsis><command>cancel_sync_queue</command> <arg choice="req">queue</arg></cmdsynopsis>
+ <term><cmdsynopsis><command>cancel_sync_queue</command> <arg choice="opt">-p <replaceable>vhost</replaceable></arg> <arg choice="req">queue</arg></cmdsynopsis>
</term>
<listitem>
<variablelist>
@@ -584,7 +584,7 @@
</listitem>
</varlistentry>
<varlistentry>
- <term><cmdsynopsis><command>purge_queue</command> <arg choice="req">queue</arg></cmdsynopsis>
+ <term><cmdsynopsis><command>purge_queue</command> <arg choice="opt">-p <replaceable>vhost</replaceable></arg> <arg choice="req">queue</arg></cmdsynopsis>
</term>
<listitem>
<variablelist>
@@ -803,11 +803,11 @@
</para>
<variablelist>
<varlistentry>
- <term><cmdsynopsis><command>add_vhost</command> <arg choice="req"><replaceable>vhostpath</replaceable></arg></cmdsynopsis></term>
+ <term><cmdsynopsis><command>add_vhost</command> <arg choice="req"><replaceable>vhost</replaceable></arg></cmdsynopsis></term>
<listitem>
<variablelist>
<varlistentry>
- <term>vhostpath</term>
+ <term>vhost</term>
<listitem><para>The name of the virtual host entry to create.</para></listitem>
</varlistentry>
</variablelist>
@@ -824,11 +824,11 @@
</varlistentry>
<varlistentry>
- <term><cmdsynopsis><command>delete_vhost</command> <arg choice="req"><replaceable>vhostpath</replaceable></arg></cmdsynopsis></term>
+ <term><cmdsynopsis><command>delete_vhost</command> <arg choice="req"><replaceable>vhost</replaceable></arg></cmdsynopsis></term>
<listitem>
<variablelist>
<varlistentry>
- <term>vhostpath</term>
+ <term>vhost</term>
<listitem><para>The name of the virtual host entry to delete.</para></listitem>
</varlistentry>
</variablelist>
@@ -885,11 +885,11 @@
</varlistentry>
<varlistentry>
- <term><cmdsynopsis><command>set_permissions</command> <arg choice="opt">-p <replaceable>vhostpath</replaceable></arg> <arg choice="req"><replaceable>user</replaceable></arg> <arg choice="req"><replaceable>conf</replaceable></arg> <arg choice="req"><replaceable>write</replaceable></arg> <arg choice="req"><replaceable>read</replaceable></arg></cmdsynopsis></term>
+ <term><cmdsynopsis><command>set_permissions</command> <arg choice="opt">-p <replaceable>vhost</replaceable></arg> <arg choice="req"><replaceable>user</replaceable></arg> <arg choice="req"><replaceable>conf</replaceable></arg> <arg choice="req"><replaceable>write</replaceable></arg> <arg choice="req"><replaceable>read</replaceable></arg></cmdsynopsis></term>
<listitem>
<variablelist>
<varlistentry>
- <term>vhostpath</term>
+ <term>vhost</term>
<listitem><para>The name of the virtual host to which to grant the user access, defaulting to <command>/</command>.</para></listitem>
</varlistentry>
<varlistentry>
@@ -925,11 +925,11 @@
</varlistentry>
<varlistentry>
- <term><cmdsynopsis><command>clear_permissions</command> <arg choice="opt">-p <replaceable>vhostpath</replaceable></arg> <arg choice="req"><replaceable>username</replaceable></arg></cmdsynopsis></term>
+ <term><cmdsynopsis><command>clear_permissions</command> <arg choice="opt">-p <replaceable>vhost</replaceable></arg> <arg choice="req"><replaceable>username</replaceable></arg></cmdsynopsis></term>
<listitem>
<variablelist>
<varlistentry>
- <term>vhostpath</term>
+ <term>vhost</term>
<listitem><para>The name of the virtual host to which to deny the user access, defaulting to <command>/</command>.</para></listitem>
</varlistentry>
<varlistentry>
@@ -951,11 +951,11 @@
</varlistentry>
<varlistentry>
- <term><cmdsynopsis><command>list_permissions</command> <arg choice="opt">-p <replaceable>vhostpath</replaceable></arg></cmdsynopsis></term>
+ <term><cmdsynopsis><command>list_permissions</command> <arg choice="opt">-p <replaceable>vhost</replaceable></arg></cmdsynopsis></term>
<listitem>
<variablelist>
<varlistentry>
- <term>vhostpath</term>
+ <term>vhost</term>
<listitem><para>The name of the virtual host for which to list the users that have been granted access to it, and their permissions. Defaults to <command>/</command>.</para></listitem>
</varlistentry>
</variablelist>
@@ -1015,7 +1015,7 @@
</para>
<variablelist>
<varlistentry>
- <term><cmdsynopsis><command>set_parameter</command> <arg choice="opt">-p <replaceable>vhostpath</replaceable></arg> <arg choice="req"><replaceable>component_name</replaceable></arg> <arg choice="req"><replaceable>name</replaceable></arg> <arg choice="req"><replaceable>value</replaceable></arg></cmdsynopsis></term>
+ <term><cmdsynopsis><command>set_parameter</command> <arg choice="opt">-p <replaceable>vhost</replaceable></arg> <arg choice="req"><replaceable>component_name</replaceable></arg> <arg choice="req"><replaceable>name</replaceable></arg> <arg choice="req"><replaceable>value</replaceable></arg></cmdsynopsis></term>
<listitem>
<para>
Sets a parameter.
@@ -1051,7 +1051,7 @@
</listitem>
</varlistentry>
<varlistentry>
- <term><cmdsynopsis><command>clear_parameter</command> <arg choice="opt">-p <replaceable>vhostpath</replaceable></arg> <arg choice="req"><replaceable>component_name</replaceable></arg> <arg choice="req"><replaceable>key</replaceable></arg></cmdsynopsis></term>
+ <term><cmdsynopsis><command>clear_parameter</command> <arg choice="opt">-p <replaceable>vhost</replaceable></arg> <arg choice="req"><replaceable>component_name</replaceable></arg> <arg choice="req"><replaceable>key</replaceable></arg></cmdsynopsis></term>
<listitem>
<para>
Clears a parameter.
@@ -1079,7 +1079,7 @@
</listitem>
</varlistentry>
<varlistentry>
- <term><cmdsynopsis><command>list_parameters</command> <arg choice="opt">-p <replaceable>vhostpath</replaceable></arg></cmdsynopsis></term>
+ <term><cmdsynopsis><command>list_parameters</command> <arg choice="opt">-p <replaceable>vhost</replaceable></arg></cmdsynopsis></term>
<listitem>
<para>
Lists all parameters for a virtual host.
@@ -1104,7 +1104,7 @@
</para>
<variablelist>
<varlistentry>
- <term><cmdsynopsis><command>set_policy</command> <arg choice="opt">-p <replaceable>vhostpath</replaceable></arg> <arg choice="opt">--priority <replaceable>priority</replaceable></arg> <arg choice="opt">--apply-to <replaceable>apply-to</replaceable></arg> <arg choice="req"><replaceable>name</replaceable></arg> <arg choice="req"><replaceable>pattern</replaceable></arg> <arg choice="req"><replaceable>definition</replaceable></arg></cmdsynopsis></term>
+ <term><cmdsynopsis><command>set_policy</command> <arg choice="opt">-p <replaceable>vhost</replaceable></arg> <arg choice="opt">--priority <replaceable>priority</replaceable></arg> <arg choice="opt">--apply-to <replaceable>apply-to</replaceable></arg> <arg choice="req"><replaceable>name</replaceable></arg> <arg choice="req"><replaceable>pattern</replaceable></arg> <arg choice="req"><replaceable>definition</replaceable></arg></cmdsynopsis></term>
<listitem>
<para>
Sets a policy.
@@ -1151,7 +1151,7 @@
</listitem>
</varlistentry>
<varlistentry>
- <term><cmdsynopsis><command>clear_policy</command> <arg choice="opt">-p <replaceable>vhostpath</replaceable></arg> <arg choice="req"><replaceable>name</replaceable></arg></cmdsynopsis></term>
+ <term><cmdsynopsis><command>clear_policy</command> <arg choice="opt">-p <replaceable>vhost</replaceable></arg> <arg choice="req"><replaceable>name</replaceable></arg></cmdsynopsis></term>
<listitem>
<para>
Clears a policy.
@@ -1172,7 +1172,7 @@
</listitem>
</varlistentry>
<varlistentry>
- <term><cmdsynopsis><command>list_policies</command> <arg choice="opt">-p <replaceable>vhostpath</replaceable></arg></cmdsynopsis></term>
+ <term><cmdsynopsis><command>list_policies</command> <arg choice="opt">-p <replaceable>vhost</replaceable></arg></cmdsynopsis></term>
<listitem>
<para>
Lists all policies for a virtual host.
@@ -1205,7 +1205,7 @@
<variablelist>
<varlistentry role="usage-has-option-list">
- <term><cmdsynopsis><command>list_queues</command> <arg choice="opt">-p <replaceable>vhostpath</replaceable></arg> <arg choice="opt" role="usage-option-list"><replaceable>queueinfoitem</replaceable> ...</arg></cmdsynopsis></term>
+ <term><cmdsynopsis><command>list_queues</command> <arg choice="opt">-p <replaceable>vhost</replaceable></arg> <arg choice="opt" role="usage-option-list"><replaceable>queueinfoitem</replaceable> ...</arg></cmdsynopsis></term>
<listitem>
<para>
Returns queue details. Queue details of the <command>/</command> virtual host
@@ -1381,7 +1381,7 @@
</varlistentry>
<varlistentry role="usage-has-option-list">
- <term><cmdsynopsis><command>list_exchanges</command> <arg choice="opt">-p <replaceable>vhostpath</replaceable></arg> <arg choice="opt" role="usage-option-list"><replaceable>exchangeinfoitem</replaceable> ...</arg></cmdsynopsis></term>
+ <term><cmdsynopsis><command>list_exchanges</command> <arg choice="opt">-p <replaceable>vhost</replaceable></arg> <arg choice="opt" role="usage-option-list"><replaceable>exchangeinfoitem</replaceable> ...</arg></cmdsynopsis></term>
<listitem>
<para>
Returns exchange details. Exchange details of the <command>/</command> virtual host
@@ -1444,7 +1444,7 @@
</varlistentry>
<varlistentry role="usage-has-option-list">
- <term><cmdsynopsis><command>list_bindings</command> <arg choice="opt">-p <replaceable>vhostpath</replaceable></arg> <arg choice="opt" role="usage-option-list"><replaceable>bindinginfoitem</replaceable> ...</arg></cmdsynopsis></term>
+ <term><cmdsynopsis><command>list_bindings</command> <arg choice="opt">-p <replaceable>vhost</replaceable></arg> <arg choice="opt" role="usage-option-list"><replaceable>bindinginfoitem</replaceable> ...</arg></cmdsynopsis></term>
<listitem>
<para>
Returns binding details. By default the bindings for
@@ -1786,7 +1786,7 @@
</varlistentry>
<varlistentry>
- <term><cmdsynopsis><command>list_consumers</command> <arg choice="opt">-p <replaceable>vhostpath</replaceable></arg></cmdsynopsis></term>
+ <term><cmdsynopsis><command>list_consumers</command> <arg choice="opt">-p <replaceable>vhost</replaceable></arg></cmdsynopsis></term>
<listitem>
<para>
List consumers, i.e. subscriptions to a queue's message
@@ -1824,6 +1824,21 @@
</varlistentry>
<varlistentry>
+ <term><cmdsynopsis><command>node_health_check</command></cmdsynopsis></term>
+ <listitem>
+ <para>
+ Health check of the RabbitMQ node. Verifies the rabbit application is
+ running, list_queues and list_channels return, and alarms are not set.
+ </para>
+ <para role="example-prefix">For example:</para>
+ <screen role="example">rabbitmqctl node_health_check -n rabbit@stringer</screen>
+ <para role="example">
+ This command performs a health check on the RabbitMQ node.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
<term><cmdsynopsis><command>environment</command></cmdsynopsis></term>
<listitem>
<para>
diff --git a/include/rabbit_cli.hrl b/include/rabbit_cli.hrl
index 2e687e2eb8..7f5db6053b 100644
--- a/include/rabbit_cli.hrl
+++ b/include/rabbit_cli.hrl
@@ -47,8 +47,6 @@
-define(OFFLINE_DEF, {?OFFLINE_OPT, flag}).
-define(ONLINE_DEF, {?ONLINE_OPT, flag}).
--define(RPC_TIMEOUT, infinity).
-
%% Subset of standartized exit codes from sysexits.h, see
%% https://github.com/rabbitmq/rabbitmq-server/issues/396 for discussion.
-define(EX_OK , 0).
diff --git a/packaging/RPMS/Fedora/rabbitmq-server.spec b/packaging/RPMS/Fedora/rabbitmq-server.spec
index 7f8519260d..2e7d0122f8 100644
--- a/packaging/RPMS/Fedora/rabbitmq-server.spec
+++ b/packaging/RPMS/Fedora/rabbitmq-server.spec
@@ -132,6 +132,9 @@ done
rm -rf %{buildroot}
%changelog
+* Tue Mar 1 2016 michael@rabbitmq.com 3.6.1-1
+- New Upstream Release
+
* Tue Dec 22 2015 michael@rabbitmq.com 3.6.0-1
- New Upstream Release
diff --git a/packaging/debs/Debian/debian/changelog b/packaging/debs/Debian/debian/changelog
index 372afa8258..adf8ce5aa5 100644
--- a/packaging/debs/Debian/debian/changelog
+++ b/packaging/debs/Debian/debian/changelog
@@ -1,3 +1,9 @@
+rabbitmq-server (3.6.1-1) unstable; urgency=low
+
+ * New Upstream Release
+
+ -- Michael Klishin <michael@rabbitmq.com> Tue, 01 Mar 2016 13:19:57 +0000
+
rabbitmq-server (3.6.0-1) unstable; urgency=low
* New Upstream Release
diff --git a/scripts/rabbitmq-server b/scripts/rabbitmq-server
index 9a4f1d5cbd..9c7b423982 100755
--- a/scripts/rabbitmq-server
+++ b/scripts/rabbitmq-server
@@ -124,7 +124,7 @@ fi
set -f
start_rabbitmq_server() {
-
+ check_start_params &&
RABBITMQ_CONFIG_FILE=$RABBITMQ_CONFIG_FILE \
exec ${ERL_DIR}erl \
-pa ${RABBITMQ_EBIN_ROOT} \
@@ -156,6 +156,7 @@ start_rabbitmq_server() {
}
stop_rabbitmq_server() {
+
RABBITMQCTL="$(dirname "$0")/rabbitmqctl"
if ${RABBITMQCTL} -n ${RABBITMQ_NODENAME} status >/dev/null 2>&1; then
@@ -163,6 +164,25 @@ stop_rabbitmq_server() {
fi
}
+check_start_params() {
+ check_not_empty RABBITMQ_BOOT_MODULE
+ check_not_empty RABBITMQ_NAME_TYPE
+ check_not_empty RABBITMQ_NODENAME
+ check_not_empty SASL_BOOT_FILE
+ check_not_empty RABBITMQ_IO_THREAD_POOL_SIZE
+}
+
+check_not_empty() {
+ local name="${1:?}"
+ local value
+ eval value=\$$name
+ if [ -z "$value" ]; then
+ echo "Error: ENV variable should be defined: $1.
+ Please check rabbitmq-env, rabbitmq-defaults, and $CONF_ENV_FILE script files"
+ exit 78
+ fi
+}
+
if [ 'x' = "x$RABBITMQ_ALLOW_INPUT" -a -z "$detached" ]; then
# When RabbitMQ runs in the foreground but the Erlang shell is
# disabled, we setup signal handlers to stop RabbitMQ properly. This
diff --git a/scripts/rabbitmq-server-ha.ocf b/scripts/rabbitmq-server-ha.ocf
index 2f57339703..c6d0e26241 100755
--- a/scripts/rabbitmq-server-ha.ocf
+++ b/scripts/rabbitmq-server-ha.ocf
@@ -45,7 +45,7 @@ OCF_RESKEY_erlang_cookie_default=false
OCF_RESKEY_erlang_cookie_file_default="/var/lib/rabbitmq/.erlang.cookie"
OCF_RESKEY_use_fqdn_default=false
OCF_RESKEY_fqdn_prefix_default=""
-OCF_RESKEY_max_rabbitmqctl_timeouts_default=1
+OCF_RESKEY_max_rabbitmqctl_timeouts_default=3
: ${HA_LOGTAG="lrmd"}
: ${HA_LOGFACILITY="daemon"}
@@ -613,7 +613,7 @@ rmq_setup_env() {
fi
done
- export LL="${OCF_RESOURCE_INSTANCE}:"
+ export LL="${OCF_RESOURCE_INSTANCE}[$$]:"
update_cookie
}
@@ -752,6 +752,31 @@ get_alive_pacemaker_nodes_but()
fi
}
+# Get current master. If a parameter is provided,
+# do not check node with that name
+get_master_name_but()
+{
+ local node
+ for node in $(get_alive_pacemaker_nodes_but "$@")
+ do
+ ocf_log info "${LH} looking if $node is master"
+
+ if is_master $node; then
+ ocf_log info "${LH} master is $node"
+ echo $node
+ break
+ fi
+ done
+}
+
+# Returns 0 if we are clustered with provideded node
+is_clustered_with()
+{
+ get_running_nodes | grep -q $(rabbit_node_name $1);
+ return $?
+}
+
+
check_need_join_to() {
local join_to
local node
@@ -929,8 +954,7 @@ unjoin_nodes_from_cluster() {
local tries=0
until [ $tries -eq 5 ]; do
tries=$((tries+1))
- if get_running_nodes | grep -q $(rabbit_node_name $nodename)
- then
+ if is_clustered_with $nodename; then
ocf_log info "${LH} the ${nodename} is alive and cannot be kicked from the cluster yet"
else
break
@@ -1262,6 +1286,7 @@ start_rmq_server_app() {
get_status() {
local what="${1:-kernel}"
local rc=$OCF_NOT_RUNNING
+ local LH="${LL} get_status():"
local body
local beam_running
@@ -1272,11 +1297,11 @@ get_status() {
beam_running=$?
# report not running only if the which_applications() reported an error AND the beam is not running
if [ $rc -ne 0 -a $beam_running -ne 0 ] ; then
- ocf_log info "get_status() failed with code ${rc}. Command output: ${body}"
+ ocf_log info "${LH} failed with code ${rc}. Command output: ${body}"
return $OCF_NOT_RUNNING
# return a generic error, if there were errors and beam is found running
elif [ $rc -ne 0 ] ; then
- ocf_log info "get_status() found the beam process running but failed with code ${rc}. Command output: ${body}"
+ ocf_log info "${LH} found the beam process running but failed with code ${rc}. Command output: ${body}"
return $OCF_ERR_GENERIC
fi
@@ -1286,7 +1311,7 @@ get_status() {
echo "$body" | grep "\{${what}," 2>&1 > /dev/null && rc=$OCF_SUCCESS
if [ $rc -ne $OCF_SUCCESS ] ; then
- ocf_log info "get_status(): app ${what} was not found in command output: ${body}"
+ ocf_log info "${LH} app ${what} was not found in command output: ${body}"
fi
fi
@@ -1323,18 +1348,18 @@ is_master() {
# separately. The second argument is used to distingush them.
check_timeouts() {
local op_rc=$1
- local timeouts_attr_name=$2
+ local crm_attr_name=$2
local op_name=$3
if [ $op_rc -ne 124 -a $op_rc -ne 137 ]; then
- ocf_run attrd_updater -p --name $timeouts_attr_name --update 0
+ ocf_run crm_attribute -N $THIS_PCMK_NODE -l reboot --name $crm_attr_name --update 0
return 0
fi
local count
- count=`attrd_updater --name $timeouts_attr_name --query 2>/dev/null`
+ count=`crm_attribute -N $THIS_PCMK_NODE -l reboot --name $crm_attr_name --query 2>/dev/null`
if [ $? -ne 0 ]; then
- # the attrd_updater exited with error. In that case most probably it printed garbage
+ # the crm_attribute exited with error. In that case most probably it printed garbage
# instead of the number we need. So defensively assume that it is zero.
count=0
@@ -1343,9 +1368,9 @@ check_timeouts() {
count=$((count+1))
# There is a slight chance that this piece of code will be executed twice simultaneously.
- # As a result, $timeouts_attr_name's value will be one less than it should be. But we don't need
+ # As a result, $crm_attr_name's value will be one less than it should be. But we don't need
# precise calculation here.
- ocf_run attrd_updater -p --name $timeouts_attr_name --update $count
+ ocf_run crm_attribute -N $THIS_PCMK_NODE -l reboot --name $crm_attr_name --update $count
if [ $count -lt $OCF_RESKEY_max_rabbitmqctl_timeouts ]; then
ocf_log warn "${LH} 'rabbitmqctl $op_name' timed out $count of max. $OCF_RESKEY_max_rabbitmqctl_timeouts time(s) in a row. Doing nothing for now."
@@ -1373,7 +1398,6 @@ get_monitor() {
local name
local node
local nodelist
- local rc_check=$OCF_SUCCESS
local max
local our_uptime
local node_uptime
@@ -1410,58 +1434,47 @@ get_monitor() {
if [ $rabbit_running -eq $OCF_SUCCESS ]
then
- ocf_log info "${LH} rabbit app is running. checking if we are the part of healthy cluster"
+ ocf_log info "${LH} rabbit app is running. checking if we are the part of healthy cluster"
+
+ if [ $rc -eq $OCF_RUNNING_MASTER ] ; then
+ # The master is always running inside of its cluster
+ ocf_log info "${LH} rabbit app is running and is master of cluster"
+
+ else
+ local master_name=$(get_master_name_but $THIS_PCMK_NODE)
+
+ if [ -z "$master_name" ]; then
+ ocf_log info "${LH} no master is elected currently. Skipping cluster health check."
+
+ elif is_clustered_with $master_name; then
+ ocf_log info "${LH} rabbit app is running and is member of healthy cluster"
- if [ $rc -eq $OCF_RUNNING_MASTER ] ; then
- # The master is always running inside of its cluster
- ocf_log info "${LH} rabbit app is running and is master of cluster"
- rc_check=$OCF_SUCCESS
else
- rc_check=$OCF_ERR_GENERIC
- nodelist=$(get_alive_pacemaker_nodes_but)
- for node in $nodelist
- do
- ocf_log info "${LH} rabbit app is running. looking for master on $node"
- is_master $node
- status_master=$?
- ocf_log info "${LH} fetched master attribute for $node. attr value is ${status_master}"
- if [ $status_master -eq 0 ] ; then
- ocf_log info "${LH} rabbit app is running. master is $node"
- if get_running_nodes | grep -q $(rabbit_node_name $node)
- then
- ocf_log info "${LH} rabbit app is running and is member of healthy cluster"
- rc_check=$OCF_SUCCESS
- break
- fi
- fi
- done
- [ $rc_check -eq $OCF_ERR_GENERIC ] && ocf_log err "${LH} rabbit node is running out of the cluster"
+ # Rabbit is running but is not connected to master
+ # Failing to avoid split brain
+ ocf_log err "${LH} rabbit node is running out of the cluster"
+ rc=$OCF_ERR_GENERIC
fi
+ fi
else
- if [ "$OCF_CHECK_LEVEL" -gt 20 ]; then
+ if [ "$OCF_CHECK_LEVEL" -gt 20 ]; then
ocf_log info "${LH} rabbit app is not running. checking if there is a master"
# Do not refetch the master status as we know it already
if [ $rc -eq $OCF_RUNNING_MASTER ]; then
ocf_log err "${LH} we are the master and rabbit app is not running. this is a failure"
exit $OCF_FAILED_MASTER
fi
- nodelist=$(get_alive_pacemaker_nodes_but $THIS_PCMK_NODE)
- rc_check=$OCF_SUCCESS
- for node in $nodelist
- do
- is_master $node
- status_master=$?
- ocf_log info "${LH} fetched master attribute for $node. attr value is ${status_master}"
- if [ $status_master -eq 0 ] ; then
- rc_check=$OCF_ERR_GENERIC
- ocf_log info "${LH} rabbit app is not running. master is $node. exiting to be restarted by pacemaker"
- break
- fi
- done
- fi
+
+ local master_name=$(get_master_name_but $THIS_PCMK_NODE)
+
+ if [ -n "$master_name" ]; then
+ ocf_log info "${LH} master exists and rabbit app is not running. Exiting to be restarted by pacemaker"
+ rc=$OCF_ERR_GENERIC
+ fi
+ fi
fi
- if [ $rc -eq $OCF_ERR_GENERIC -o $rc_check -eq $OCF_ERR_GENERIC ]; then
+ if [ $rc -eq $OCF_ERR_GENERIC ]; then
ocf_log err "${LH} get_status() returns generic error ${rc}"
ocf_log info "${LH} ensuring this slave does not get promoted."
master_score 0
@@ -1645,9 +1658,9 @@ action_start() {
return $OCF_SUCCESS
fi
- ocf_run attrd_updater -p --name 'rabbit_list_channels_timeouts' --update '0'
- ocf_run attrd_updater -p --name 'rabbit_get_alarms_timeouts' --update '0'
- ocf_run attrd_updater -p --name 'rabbit_list_queues_timeouts' --update '0'
+ ocf_run crm_attribute -N $THIS_PCMK_NODE -l reboot --name 'rabbit_list_channels_timeouts' --update '0'
+ ocf_run crm_attribute -N $THIS_PCMK_NODE -l reboot --name 'rabbit_get_alarms_timeouts' --update '0'
+ ocf_run crm_attribute -N $THIS_PCMK_NODE -l reboot --name 'rabbit_list_queues_timeouts' --update '0'
ocf_log info "${LH} Deleting start time attribute"
ocf_run crm_attribute -N $THIS_PCMK_NODE -l reboot --name 'rabbit-start-time' --delete
ocf_log info "${LH} Deleting master attribute"
@@ -1889,23 +1902,33 @@ action_notify() {
case "$OCF_RESKEY_CRM_meta_notify_operation" in
promote)
ocf_log info "${LH} post-promote begin."
+
+ rc=$OCF_SUCCESS
+
# Do nothing, if the list of nodes being promoted reported empty.
# Delegate recovery, if needed, to the "running out of the cluster" monitor's logic
if [ -z "${OCF_RESKEY_CRM_meta_notify_promote_uname}" ] ; then
- ocf_log warn "${LH} there are no nodes to join to reported on post-promote. Nothing to do."
- ocf_log info "${LH} post-promote end."
- return $OCF_SUCCESS
+ ocf_log warn "${LH} there are no nodes to join to reported on post-promote. Nothing to do."
+
+ elif my_host "${OCF_RESKEY_CRM_meta_notify_promote_uname}"; then
+ ocf_log info "${LH} ignoring post-promote of self"
+
+ elif is_clustered_with "${OCF_RESKEY_CRM_meta_notify_promote_uname}"; then
+ ocf_log info "${LH} we are already clustered with master - ${OCF_RESKEY_CRM_meta_notify_promote_uname}. Nothing to do."
+
+ else
+ # Note, this should fail when the mnesia is inconsistent.
+ # For example, when the "old" master processing the promition of the new one.
+ # Later this ex-master node will rejoin the cluster at post-start.
+ jjj_join "${OCF_RESKEY_CRM_meta_notify_promote_uname}"
+ rc=$?
+ if [ $rc -eq $OCF_ERR_GENERIC ] ; then
+ ocf_log err "${LH} Failed to join the cluster on post-promote. The resource will be restarted."
+ fi
fi
- # Note, this should fail when the mnesia is inconsistent.
- # For example, when the "old" master processing the promition of the new one.
- # Later this ex-master node will rejoin the cluster at post-start.
- jjj_join "${OCF_RESKEY_CRM_meta_notify_promote_uname}"
- rc=$?
+
ocf_log info "${LH} post-promote end."
- if [ $rc -eq $OCF_ERR_GENERIC ] ; then
- ocf_log err "${LH} Failed to join the cluster on post-promote. The resource will be restarted."
- return $OCF_ERR_GENERIC
- fi
+ return $rc
;;
start)
ocf_log info "${LH} post-start begin."
diff --git a/scripts/rabbitmq-server.bat b/scripts/rabbitmq-server.bat
index f5cad1e12c..33e316a07f 100644
--- a/scripts/rabbitmq-server.bat
+++ b/scripts/rabbitmq-server.bat
@@ -110,6 +110,18 @@ if "!RABBITMQ_NODE_ONLY!"=="" (
if "!RABBITMQ_IO_THREAD_POOL_SIZE!"=="" (
set RABBITMQ_IO_THREAD_POOL_ARG=30
+) else (
+ set RABBITMQ_IO_THREAD_POOL_ARG=!RABBITMQ_IO_THREAD_POOL_SIZE!
+)
+
+set ENV_OK=true
+CALL :check_not_empty "RABBITMQ_BOOT_MODULE" !RABBITMQ_BOOT_MODULE!
+CALL :check_not_empty "RABBITMQ_NAME_TYPE" !RABBITMQ_NAME_TYPE!
+CALL :check_not_empty "RABBITMQ_NODENAME" !RABBITMQ_NODENAME!
+
+
+if "!ENV_OK!"=="false" (
+ EXIT /b 78
)
"!ERLANG_HOME!\bin\erl.exe" ^
@@ -140,5 +152,16 @@ if "!RABBITMQ_IO_THREAD_POOL_SIZE!"=="" (
!RABBITMQ_DIST_ARG! ^
!STAR!
+EXIT /B 0
+
+:check_not_empty
+if "%~2"=="" (
+ ECHO "Error: ENV variable should be defined: %1. Please check rabbitmq-env and rabbitmq-defaults, and !RABBITMQ_CONF_ENV_FILE! script files. Check also your Environment Variables settings"
+ set ENV_OK=false
+ EXIT /B 78
+ )
+EXIT /B 0
+
endlocal
endlocal
+
diff --git a/scripts/rabbitmq-service.bat b/scripts/rabbitmq-service.bat
index 473486d8ae..f302087f91 100644
--- a/scripts/rabbitmq-service.bat
+++ b/scripts/rabbitmq-service.bat
@@ -105,6 +105,16 @@ if not exist "!RABBITMQ_BASE!" (
echo Creating base directory !RABBITMQ_BASE! & md "!RABBITMQ_BASE!"
)
+set ENV_OK=true
+CALL :check_not_empty "RABBITMQ_BOOT_MODULE" !RABBITMQ_BOOT_MODULE!
+CALL :check_not_empty "RABBITMQ_NAME_TYPE" !RABBITMQ_NAME_TYPE!
+CALL :check_not_empty "RABBITMQ_NODENAME" !RABBITMQ_NODENAME!
+
+
+if "!ENV_OK!"=="false" (
+ EXIT /b 78
+)
+
"!ERLANG_SERVICE_MANAGER_PATH!\erlsrv" list !RABBITMQ_SERVICENAME! 2>NUL 1>NUL
if errorlevel 1 (
"!ERLANG_SERVICE_MANAGER_PATH!\erlsrv" add !RABBITMQ_SERVICENAME! -internalservicename !RABBITMQ_SERVICENAME!
@@ -140,6 +150,10 @@ if ERRORLEVEL 3 (
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" (
@@ -180,6 +194,10 @@ if "!RABBITMQ_IO_THREAD_POOL_SIZE!"=="" (
set RABBITMQ_IO_THREAD_POOL_SIZE=30
)
+if "!RABBITMQ_SERVICE_RESTART!"=="" (
+ set RABBITMQ_SERVICE_RESTART=restart
+)
+
set ERLANG_SERVICE_ARGUMENTS= ^
-pa "!RABBITMQ_EBIN_ROOT!" ^
-boot start_sasl ^
@@ -213,7 +231,10 @@ echo "!ERLANG_SERVICE_ARGUMENTS!" > "!RABBITMQ_CONFIG_FILE!.txt"
set ERLANG_SERVICE_ARGUMENTS=!ERLANG_SERVICE_ARGUMENTS:\=\\!
set ERLANG_SERVICE_ARGUMENTS=!ERLANG_SERVICE_ARGUMENTS:"=\"!
+
+
"!ERLANG_SERVICE_MANAGER_PATH!\erlsrv" set !RABBITMQ_SERVICENAME! ^
+-onfail !RABBITMQ_SERVICE_RESTART! ^
-machine "!ERLANG_SERVICE_MANAGER_PATH!\erl.exe" ^
-env ERL_CRASH_DUMP="!RABBITMQ_BASE:\=/!/erl_crash.dump" ^
-env ERL_LIBS="!ERL_LIBS!" ^
@@ -235,5 +256,15 @@ goto END
:END
+EXIT /B 0
+
+:check_not_empty
+if "%~2"=="" (
+ ECHO "Error: ENV variable should be defined: %1. Please check rabbitmq-env, rabbitmq-default, and !RABBITMQ_CONF_ENV_FILE! script files. Check also your Environment Variables settings"
+ set ENV_OK=false
+ EXIT /B 78
+ )
+EXIT /B 0
+
endlocal
endlocal
diff --git a/scripts/rabbitmqctl b/scripts/rabbitmqctl
index 3705b9a979..2336c3d466 100755
--- a/scripts/rabbitmqctl
+++ b/scripts/rabbitmqctl
@@ -30,7 +30,7 @@ fi
RABBITMQ_USE_LONGNAME=${RABBITMQ_USE_LONGNAME} \
exec ${ERL_DIR}erl \
-pa "${RABBITMQ_HOME}/ebin" \
- -noinput \
+ -noinput +B \
-hidden \
${RABBITMQ_CTL_ERL_ARGS} \
-boot "${CLEAN_BOOT_FILE}" \
diff --git a/src/rabbit.app.src b/src/rabbit.app.src
index a9dd23f3b5..83e7237c80 100644
--- a/src/rabbit.app.src
+++ b/src/rabbit.app.src
@@ -99,5 +99,6 @@
%% see rabbitmq-server#143
{credit_flow_default_credit, {200, 50}},
%% see rabbitmq-server#248
- {channel_operation_timeout, 5000}
+ %% and rabbitmq-server#667
+ {channel_operation_timeout, 15000}
]}]}.
diff --git a/src/rabbit_auth_backend_dummy.erl b/src/rabbit_auth_backend_dummy.erl
deleted file mode 100644
index 0077b4c993..0000000000
--- a/src/rabbit_auth_backend_dummy.erl
+++ /dev/null
@@ -1,48 +0,0 @@
-%% The contents of this file are subject to the Mozilla Public License
-%% Version 1.1 (the "License"); you may not use this file except in
-%% compliance with the License. You may obtain a copy of the License
-%% at http://www.mozilla.org/MPL/
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and
-%% limitations under the License.
-%%
-%% The Original Code is RabbitMQ.
-%%
-%% The Initial Developer of the Original Code is GoPivotal, Inc.
-%% Copyright (c) 2007-2016 Pivotal Software, Inc. All rights reserved.
-%%
-
--module(rabbit_auth_backend_dummy).
--include("rabbit.hrl").
-
--behaviour(rabbit_authn_backend).
--behaviour(rabbit_authz_backend).
-
--export([user/0]).
--export([user_login_authentication/2, user_login_authorization/1,
- check_vhost_access/3, check_resource_access/3]).
-
--ifdef(use_specs).
-
--spec(user/0 :: () -> rabbit_types:user()).
-
--endif.
-
-%% A user to be used by the direct client when permission checks are
-%% not needed. This user can do anything AMQPish.
-user() -> #user{username = <<"none">>,
- tags = [],
- authz_backends = [{?MODULE, none}]}.
-
-%% Implementation of rabbit_auth_backend
-
-user_login_authentication(_, _) ->
- {refused, "cannot log in conventionally as dummy user", []}.
-
-user_login_authorization(_) ->
- {refused, "cannot log in conventionally as dummy user", []}.
-
-check_vhost_access(#auth_user{}, _VHostPath, _Sock) -> true.
-check_resource_access(#auth_user{}, #resource{}, _Permission) -> true.
diff --git a/src/rabbit_auth_backend_internal.erl b/src/rabbit_auth_backend_internal.erl
deleted file mode 100644
index d7705d8e7b..0000000000
--- a/src/rabbit_auth_backend_internal.erl
+++ /dev/null
@@ -1,400 +0,0 @@
-%% The contents of this file are subject to the Mozilla Public License
-%% Version 1.1 (the "License"); you may not use this file except in
-%% compliance with the License. You may obtain a copy of the License
-%% at http://www.mozilla.org/MPL/
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and
-%% limitations under the License.
-%%
-%% The Original Code is RabbitMQ.
-%%
-%% The Initial Developer of the Original Code is GoPivotal, Inc.
-%% Copyright (c) 2007-2016 Pivotal Software, Inc. All rights reserved.
-%%
-
--module(rabbit_auth_backend_internal).
--include("rabbit.hrl").
-
--behaviour(rabbit_authn_backend).
--behaviour(rabbit_authz_backend).
-
--export([user_login_authentication/2, user_login_authorization/1,
- check_vhost_access/3, check_resource_access/3]).
-
--export([add_user/2, delete_user/1, lookup_user/1,
- change_password/2, clear_password/1,
- hash_password/2, change_password_hash/2, change_password_hash/3,
- set_tags/2, set_permissions/5, clear_permissions/2]).
--export([user_info_keys/0, perms_info_keys/0,
- user_perms_info_keys/0, vhost_perms_info_keys/0,
- user_vhost_perms_info_keys/0,
- list_users/0, list_users/2, list_permissions/0,
- list_user_permissions/1, list_user_permissions/3,
- list_vhost_permissions/1, list_vhost_permissions/3,
- list_user_vhost_permissions/2]).
-
-%% for testing
--export([hashing_module_for_user/1]).
-
-%%----------------------------------------------------------------------------
-
--ifdef(use_specs).
-
--type(regexp() :: binary()).
-
--spec(add_user/2 :: (rabbit_types:username(), rabbit_types:password()) -> 'ok').
--spec(delete_user/1 :: (rabbit_types:username()) -> 'ok').
--spec(lookup_user/1 :: (rabbit_types:username())
- -> rabbit_types:ok(rabbit_types:internal_user())
- | rabbit_types:error('not_found')).
--spec(change_password/2 :: (rabbit_types:username(), rabbit_types:password())
- -> 'ok').
--spec(clear_password/1 :: (rabbit_types:username()) -> 'ok').
--spec(hash_password/2 :: (module(), rabbit_types:password())
- -> rabbit_types:password_hash()).
--spec(change_password_hash/2 :: (rabbit_types:username(),
- rabbit_types:password_hash()) -> 'ok').
--spec(set_tags/2 :: (rabbit_types:username(), [atom()]) -> 'ok').
--spec(set_permissions/5 ::(rabbit_types:username(), rabbit_types:vhost(),
- regexp(), regexp(), regexp()) -> 'ok').
--spec(clear_permissions/2 :: (rabbit_types:username(), rabbit_types:vhost())
- -> 'ok').
--spec(user_info_keys/0 :: () -> rabbit_types:info_keys()).
--spec(perms_info_keys/0 :: () -> rabbit_types:info_keys()).
--spec(user_perms_info_keys/0 :: () -> rabbit_types:info_keys()).
--spec(vhost_perms_info_keys/0 :: () -> rabbit_types:info_keys()).
--spec(user_vhost_perms_info_keys/0 :: () -> rabbit_types:info_keys()).
--spec(list_users/0 :: () -> [rabbit_types:infos()]).
--spec(list_users/2 :: (reference(), pid()) -> 'ok').
--spec(list_permissions/0 :: () -> [rabbit_types:infos()]).
--spec(list_user_permissions/1 ::
- (rabbit_types:username()) -> [rabbit_types:infos()]).
--spec(list_user_permissions/3 ::
- (rabbit_types:username(), reference(), pid()) -> 'ok').
--spec(list_vhost_permissions/1 ::
- (rabbit_types:vhost()) -> [rabbit_types:infos()]).
--spec(list_vhost_permissions/3 ::
- (rabbit_types:vhost(), reference(), pid()) -> 'ok').
--spec(list_user_vhost_permissions/2 ::
- (rabbit_types:username(), rabbit_types:vhost())
- -> [rabbit_types:infos()]).
-
--endif.
-
-%%----------------------------------------------------------------------------
-%% Implementation of rabbit_auth_backend
-
-%% Returns a password hashing module for the user record provided. If
-%% there is no information in the record, we consider it to be legacy
-%% (inserted by a version older than 3.6.0) and fall back to MD5, the
-%% now obsolete hashing function.
-hashing_module_for_user(#internal_user{
- hashing_algorithm = ModOrUndefined}) ->
- rabbit_password:hashing_mod(ModOrUndefined).
-
-user_login_authentication(Username, []) ->
- internal_check_user_login(Username, fun(_) -> true end);
-user_login_authentication(Username, [{password, Cleartext}]) ->
- internal_check_user_login(
- Username,
- fun (#internal_user{password_hash = <<Salt:4/binary, Hash/binary>>} = U) ->
- Hash =:= rabbit_password:salted_hash(
- hashing_module_for_user(U), Salt, Cleartext);
- (#internal_user{}) ->
- false
- end);
-user_login_authentication(Username, AuthProps) ->
- exit({unknown_auth_props, Username, AuthProps}).
-
-user_login_authorization(Username) ->
- case user_login_authentication(Username, []) of
- {ok, #auth_user{impl = Impl, tags = Tags}} -> {ok, Impl, Tags};
- Else -> Else
- end.
-
-internal_check_user_login(Username, Fun) ->
- Refused = {refused, "user '~s' - invalid credentials", [Username]},
- case lookup_user(Username) of
- {ok, User = #internal_user{tags = Tags}} ->
- case Fun(User) of
- true -> {ok, #auth_user{username = Username,
- tags = Tags,
- impl = none}};
- _ -> Refused
- end;
- {error, not_found} ->
- Refused
- end.
-
-check_vhost_access(#auth_user{username = Username}, VHostPath, _Sock) ->
- case mnesia:dirty_read({rabbit_user_permission,
- #user_vhost{username = Username,
- virtual_host = VHostPath}}) of
- [] -> false;
- [_R] -> true
- end.
-
-check_resource_access(#auth_user{username = Username},
- #resource{virtual_host = VHostPath, name = Name},
- Permission) ->
- case mnesia:dirty_read({rabbit_user_permission,
- #user_vhost{username = Username,
- virtual_host = VHostPath}}) of
- [] ->
- false;
- [#user_permission{permission = P}] ->
- PermRegexp = case element(permission_index(Permission), P) of
- %% <<"^$">> breaks Emacs' erlang mode
- <<"">> -> <<$^, $$>>;
- RE -> RE
- end,
- case re:run(Name, PermRegexp, [{capture, none}]) of
- match -> true;
- nomatch -> false
- end
- end.
-
-permission_index(configure) -> #permission.configure;
-permission_index(write) -> #permission.write;
-permission_index(read) -> #permission.read.
-
-%%----------------------------------------------------------------------------
-%% Manipulation of the user database
-
-add_user(Username, Password) ->
- rabbit_log:info("Creating user '~s'~n", [Username]),
- %% hash_password will pick the hashing function configured for us
- %% but we also need to store a hint as part of the record, so we
- %% retrieve it here one more time
- HashingMod = rabbit_password:hashing_mod(),
- User = #internal_user{username = Username,
- password_hash = hash_password(HashingMod, Password),
- tags = [],
- hashing_algorithm = HashingMod},
- R = rabbit_misc:execute_mnesia_transaction(
- fun () ->
- case mnesia:wread({rabbit_user, Username}) of
- [] ->
- ok = mnesia:write(rabbit_user, User, write);
- _ ->
- mnesia:abort({user_already_exists, Username})
- end
- end),
- rabbit_event:notify(user_created, [{name, Username}]),
- R.
-
-delete_user(Username) ->
- rabbit_log:info("Deleting user '~s'~n", [Username]),
- R = rabbit_misc:execute_mnesia_transaction(
- rabbit_misc:with_user(
- Username,
- fun () ->
- ok = mnesia:delete({rabbit_user, Username}),
- [ok = mnesia:delete_object(
- rabbit_user_permission, R, write) ||
- R <- mnesia:match_object(
- rabbit_user_permission,
- #user_permission{user_vhost = #user_vhost{
- username = Username,
- virtual_host = '_'},
- permission = '_'},
- write)],
- ok
- end)),
- rabbit_event:notify(user_deleted, [{name, Username}]),
- R.
-
-lookup_user(Username) ->
- rabbit_misc:dirty_read({rabbit_user, Username}).
-
-change_password(Username, Password) ->
- rabbit_log:info("Changing password for '~s'~n", [Username]),
- HashingAlgorithm = rabbit_password:hashing_mod(),
- R = change_password_hash(Username,
- hash_password(rabbit_password:hashing_mod(),
- Password),
- HashingAlgorithm),
- rabbit_event:notify(user_password_changed, [{name, Username}]),
- R.
-
-clear_password(Username) ->
- rabbit_log:info("Clearing password for '~s'~n", [Username]),
- R = change_password_hash(Username, <<"">>),
- rabbit_event:notify(user_password_cleared, [{name, Username}]),
- R.
-
-hash_password(HashingMod, Cleartext) ->
- rabbit_password:hash(HashingMod, Cleartext).
-
-change_password_hash(Username, PasswordHash) ->
- change_password_hash(Username, PasswordHash, rabbit_password:hashing_mod()).
-
-
-change_password_hash(Username, PasswordHash, HashingAlgorithm) ->
- update_user(Username, fun(User) ->
- User#internal_user{
- password_hash = PasswordHash,
- hashing_algorithm = HashingAlgorithm }
- end).
-
-set_tags(Username, Tags) ->
- rabbit_log:info("Setting user tags for user '~s' to ~p~n",
- [Username, Tags]),
- R = update_user(Username, fun(User) ->
- User#internal_user{tags = Tags}
- end),
- rabbit_event:notify(user_tags_set, [{name, Username}, {tags, Tags}]),
- R.
-
-set_permissions(Username, VHostPath, ConfigurePerm, WritePerm, ReadPerm) ->
- rabbit_log:info("Setting permissions for "
- "'~s' in '~s' to '~s', '~s', '~s'~n",
- [Username, VHostPath, ConfigurePerm, WritePerm, ReadPerm]),
- lists:map(
- fun (RegexpBin) ->
- Regexp = binary_to_list(RegexpBin),
- case re:compile(Regexp) of
- {ok, _} -> ok;
- {error, Reason} -> throw({error, {invalid_regexp,
- Regexp, Reason}})
- end
- end, [ConfigurePerm, WritePerm, ReadPerm]),
- R = rabbit_misc:execute_mnesia_transaction(
- rabbit_misc:with_user_and_vhost(
- Username, VHostPath,
- fun () -> ok = mnesia:write(
- rabbit_user_permission,
- #user_permission{user_vhost = #user_vhost{
- username = Username,
- virtual_host = VHostPath},
- permission = #permission{
- configure = ConfigurePerm,
- write = WritePerm,
- read = ReadPerm}},
- write)
- end)),
- rabbit_event:notify(permission_created, [{user, Username},
- {vhost, VHostPath},
- {configure, ConfigurePerm},
- {write, WritePerm},
- {read, ReadPerm}]),
- R.
-
-clear_permissions(Username, VHostPath) ->
- R = rabbit_misc:execute_mnesia_transaction(
- rabbit_misc:with_user_and_vhost(
- Username, VHostPath,
- fun () ->
- ok = mnesia:delete({rabbit_user_permission,
- #user_vhost{username = Username,
- virtual_host = VHostPath}})
- end)),
- rabbit_event:notify(permission_deleted, [{user, Username},
- {vhost, VHostPath}]),
- R.
-
-
-update_user(Username, Fun) ->
- rabbit_misc:execute_mnesia_transaction(
- rabbit_misc:with_user(
- Username,
- fun () ->
- {ok, User} = lookup_user(Username),
- ok = mnesia:write(rabbit_user, Fun(User), write)
- end)).
-
-%%----------------------------------------------------------------------------
-%% Listing
-
--define(PERMS_INFO_KEYS, [configure, write, read]).
--define(USER_INFO_KEYS, [user, tags]).
-
-user_info_keys() -> ?USER_INFO_KEYS.
-
-perms_info_keys() -> [user, vhost | ?PERMS_INFO_KEYS].
-vhost_perms_info_keys() -> [user | ?PERMS_INFO_KEYS].
-user_perms_info_keys() -> [vhost | ?PERMS_INFO_KEYS].
-user_vhost_perms_info_keys() -> ?PERMS_INFO_KEYS.
-
-list_users() ->
- [extract_internal_user_params(U) ||
- U <- mnesia:dirty_match_object(rabbit_user, #internal_user{_ = '_'})].
-
-list_users(Ref, AggregatorPid) ->
- rabbit_control_misc:emitting_map(
- AggregatorPid, Ref,
- fun(U) -> extract_internal_user_params(U) end,
- mnesia:dirty_match_object(rabbit_user, #internal_user{_ = '_'})).
-
-list_permissions() ->
- list_permissions(perms_info_keys(), match_user_vhost('_', '_')).
-
-list_permissions(Keys, QueryThunk) ->
- [extract_user_permission_params(Keys, U) ||
- %% TODO: use dirty ops instead
- U <- rabbit_misc:execute_mnesia_transaction(QueryThunk)].
-
-list_permissions(Keys, QueryThunk, Ref, AggregatorPid) ->
- rabbit_control_misc:emitting_map(
- AggregatorPid, Ref, fun(U) -> extract_user_permission_params(Keys, U) end,
- %% TODO: use dirty ops instead
- rabbit_misc:execute_mnesia_transaction(QueryThunk)).
-
-filter_props(Keys, Props) -> [T || T = {K, _} <- Props, lists:member(K, Keys)].
-
-list_user_permissions(Username) ->
- list_permissions(
- user_perms_info_keys(),
- rabbit_misc:with_user(Username, match_user_vhost(Username, '_'))).
-
-list_user_permissions(Username, Ref, AggregatorPid) ->
- list_permissions(
- user_perms_info_keys(),
- rabbit_misc:with_user(Username, match_user_vhost(Username, '_')),
- Ref, AggregatorPid).
-
-list_vhost_permissions(VHostPath) ->
- list_permissions(
- vhost_perms_info_keys(),
- rabbit_vhost:with(VHostPath, match_user_vhost('_', VHostPath))).
-
-list_vhost_permissions(VHostPath, Ref, AggregatorPid) ->
- list_permissions(
- vhost_perms_info_keys(),
- rabbit_vhost:with(VHostPath, match_user_vhost('_', VHostPath)),
- Ref, AggregatorPid).
-
-list_user_vhost_permissions(Username, VHostPath) ->
- list_permissions(
- user_vhost_perms_info_keys(),
- rabbit_misc:with_user_and_vhost(
- Username, VHostPath, match_user_vhost(Username, VHostPath))).
-
-extract_user_permission_params(Keys, #user_permission{
- user_vhost =
- #user_vhost{username = Username,
- virtual_host = VHostPath},
- permission = #permission{
- configure = ConfigurePerm,
- write = WritePerm,
- read = ReadPerm}}) ->
- filter_props(Keys, [{user, Username},
- {vhost, VHostPath},
- {configure, ConfigurePerm},
- {write, WritePerm},
- {read, ReadPerm}]).
-
-extract_internal_user_params(#internal_user{username = Username, tags = Tags}) ->
- [{user, Username}, {tags, Tags}].
-
-match_user_vhost(Username, VHostPath) ->
- fun () -> mnesia:match_object(
- rabbit_user_permission,
- #user_permission{user_vhost = #user_vhost{
- username = Username,
- virtual_host = VHostPath},
- permission = '_'},
- read)
- end.
diff --git a/src/rabbit_cli.erl b/src/rabbit_cli.erl
index 4aad3c0916..6679d9329e 100644
--- a/src/rabbit_cli.erl
+++ b/src/rabbit_cli.erl
@@ -255,14 +255,10 @@ print_badrpc_diagnostics(Nodes) ->
%% a timeout unless we set our ticktime to be the same. So let's do
%% that.
rpc_call(Node, Mod, Fun, Args) ->
- rpc_call(Node, Mod, Fun, Args, ?RPC_TIMEOUT).
+ rabbit_misc:rpc_call(Node, Mod, Fun, Args).
rpc_call(Node, Mod, Fun, Args, Timeout) ->
- case rpc:call(Node, net_kernel, get_net_ticktime, [], Timeout) of
- {badrpc, _} = E -> E;
- Time -> net_kernel:set_net_ticktime(Time, 0),
- rpc:call(Node, Mod, Fun, Args, Timeout)
- end.
+ rabbit_misc:rpc_call(Node, Mod, Fun, Args, Timeout).
rpc_call(Node, Mod, Fun, Args, Ref, Pid, Timeout) ->
- rpc_call(Node, Mod, Fun, Args++[Ref, Pid], Timeout).
+ rabbit_misc:rpc_call(Node, Mod, Fun, Args, Ref, Pid, Timeout).
diff --git a/src/rabbit_control_main.erl b/src/rabbit_control_main.erl
index b30ea7c636..b7a7b51242 100644
--- a/src/rabbit_control_main.erl
+++ b/src/rabbit_control_main.erl
@@ -17,12 +17,13 @@
-module(rabbit_control_main).
-include("rabbit.hrl").
-include("rabbit_cli.hrl").
+-include("rabbit_misc.hrl").
-export([start/0, stop/0, parse_arguments/2, action/5, action/6,
sync_queue/1, cancel_sync_queue/1, become/1,
purge_queue/1]).
--import(rabbit_cli, [rpc_call/4, rpc_call/5, rpc_call/7]).
+-import(rabbit_misc, [rpc_call/4, rpc_call/5, rpc_call/7]).
-define(EXTERNAL_CHECK_INTERVAL, 1000).
@@ -83,6 +84,7 @@
report,
set_cluster_name,
eval,
+ node_health_check,
close_connection,
{trace_on, [?VHOST_DEF]},
@@ -111,7 +113,7 @@
[stop, stop_app, start_app, wait, reset, force_reset, rotate_logs,
join_cluster, change_cluster_node_type, update_cluster_nodes,
forget_cluster_node, rename_cluster_node, cluster_status, status,
- environment, eval, force_boot, help]).
+ environment, eval, force_boot, help, node_health_check]).
-define(COMMANDS_WITH_TIMEOUT,
[list_user_permissions, list_policies, list_queues, list_exchanges,
@@ -544,6 +546,17 @@ action(eval, Node, [Expr], _Opts, _Inform) ->
action(help, _Node, _Args, _Opts, _Inform) ->
io:format("~s", [rabbit_ctl_usage:usage()]);
+action(node_health_check, Node, _Args, _Opts, Inform) ->
+ Inform("Checking health of node ~p", [Node]),
+ try
+ rabbit_health_check:node(Node),
+ io:format("Health check passed~n")
+ catch
+ {node_is_ko, ErrorMsg, ErrorCode} ->
+ io:format("Heath check failed:~n~s~n", [ErrorMsg]),
+ halt(ErrorCode)
+ end;
+
action(Command, Node, Args, Opts, Inform) ->
%% For backward compatibility, run commands accepting a timeout with
%% the default timeout.
@@ -567,7 +580,8 @@ action(list_permissions, Node, [], Opts, Inform, Timeout) ->
VHost = proplists:get_value(?VHOST_OPT, Opts),
Inform("Listing permissions in vhost \"~s\"", [VHost]),
call(Node, {rabbit_auth_backend_internal, list_vhost_permissions, [VHost]},
- rabbit_auth_backend_internal:vhost_perms_info_keys(), true, Timeout);
+ rabbit_auth_backend_internal:vhost_perms_info_keys(), true, Timeout,
+ true);
action(list_parameters, Node, [], Opts, Inform, Timeout) ->
VHostArg = list_to_binary(proplists:get_value(?VHOST_OPT, Opts)),
@@ -592,7 +606,8 @@ action(list_user_permissions, _Node, _Args = [], _Opts, _Inform, _Timeout) ->
action(list_user_permissions, Node, Args = [_Username], _Opts, Inform, Timeout) ->
Inform("Listing permissions for user ~p", Args),
call(Node, {rabbit_auth_backend_internal, list_user_permissions, Args},
- rabbit_auth_backend_internal:user_perms_info_keys(), true, Timeout);
+ rabbit_auth_backend_internal:user_perms_info_keys(), true, Timeout,
+ true);
action(list_queues, Node, Args, Opts, Inform, Timeout) ->
Inform("Listing queues", []),
@@ -735,20 +750,22 @@ default_if_empty(List, Default) when is_list(List) ->
true -> [list_to_atom(X) || X <- List]
end.
-display_info_message(Result, InfoItemKeys) ->
- display_row([format_info_item(
- case proplists:lookup(X, Result) of
- none when is_list(Result), length(Result) > 0 ->
- exit({error, {bad_info_key, X}});
- none -> Result;
- {X, Value} -> Value
- end) || X <- InfoItemKeys]).
+display_info_message(IsEscaped) ->
+ fun(Result, InfoItemKeys) ->
+ display_row([format_info_item(
+ case proplists:lookup(X, Result) of
+ none when is_list(Result), length(Result) > 0 ->
+ exit({error, {bad_info_key, X}});
+ none -> Result;
+ {X, Value} -> Value
+ end, IsEscaped) || X <- InfoItemKeys])
+ end.
display_info_list(Results, InfoItemKeys) when is_list(Results) ->
lists:foreach(
fun (Result) -> display_row(
- [format_info_item(proplists:get_value(X, Result)) ||
- X <- InfoItemKeys])
+ [format_info_item(proplists:get_value(X, Result), true)
+ || X <- InfoItemKeys])
end, lists:sort(Results)),
ok;
display_info_list(Other, _) ->
@@ -761,32 +778,33 @@ display_row(Row) ->
-define(IS_U8(X), (X >= 0 andalso X =< 255)).
-define(IS_U16(X), (X >= 0 andalso X =< 65535)).
-format_info_item(#resource{name = Name}) ->
- escape(Name);
-format_info_item({N1, N2, N3, N4} = Value) when
+format_info_item(#resource{name = Name}, IsEscaped) ->
+ escape(Name, IsEscaped);
+format_info_item({N1, N2, N3, N4} = Value, _IsEscaped) when
?IS_U8(N1), ?IS_U8(N2), ?IS_U8(N3), ?IS_U8(N4) ->
rabbit_misc:ntoa(Value);
-format_info_item({K1, K2, K3, K4, K5, K6, K7, K8} = Value) when
+format_info_item({K1, K2, K3, K4, K5, K6, K7, K8} = Value, _IsEscaped) when
?IS_U16(K1), ?IS_U16(K2), ?IS_U16(K3), ?IS_U16(K4),
?IS_U16(K5), ?IS_U16(K6), ?IS_U16(K7), ?IS_U16(K8) ->
rabbit_misc:ntoa(Value);
-format_info_item(Value) when is_pid(Value) ->
+format_info_item(Value, _IsEscaped) when is_pid(Value) ->
rabbit_misc:pid_to_string(Value);
-format_info_item(Value) when is_binary(Value) ->
- escape(Value);
-format_info_item(Value) when is_atom(Value) ->
- escape(atom_to_list(Value));
+format_info_item(Value, IsEscaped) when is_binary(Value) ->
+ escape(Value, IsEscaped);
+format_info_item(Value, IsEscaped) when is_atom(Value) ->
+ escape(atom_to_list(Value), IsEscaped);
format_info_item([{TableEntryKey, TableEntryType, _TableEntryValue} | _] =
- Value) when is_binary(TableEntryKey) andalso
- is_atom(TableEntryType) ->
- io_lib:format("~1000000000000p", [prettify_amqp_table(Value)]);
-format_info_item([T | _] = Value)
+ Value, IsEscaped) when is_binary(TableEntryKey) andalso
+ is_atom(TableEntryType) ->
+ io_lib:format("~1000000000000p", [prettify_amqp_table(Value, IsEscaped)]);
+format_info_item([T | _] = Value, IsEscaped)
when is_tuple(T) orelse is_pid(T) orelse is_binary(T) orelse is_atom(T) orelse
is_list(T) ->
"[" ++
lists:nthtail(2, lists:append(
- [", " ++ format_info_item(E) || E <- Value])) ++ "]";
-format_info_item(Value) ->
+ [", " ++ format_info_item(E, IsEscaped)
+ || E <- Value])) ++ "]";
+format_info_item(Value, _IsEscaped) ->
io_lib:format("~w", [Value]).
display_call_result(Node, MFA) ->
@@ -817,9 +835,12 @@ call(Node, {Mod, Fun, Args}) ->
rpc_call(Node, Mod, Fun, lists:map(fun list_to_binary_utf8/1, Args)).
call(Node, {Mod, Fun, Args}, InfoKeys, Timeout) ->
- call(Node, {Mod, Fun, Args}, InfoKeys, false, Timeout).
+ call(Node, {Mod, Fun, Args}, InfoKeys, false, Timeout, false).
call(Node, {Mod, Fun, Args}, InfoKeys, ToBinUtf8, Timeout) ->
+ call(Node, {Mod, Fun, Args}, InfoKeys, ToBinUtf8, Timeout, false).
+
+call(Node, {Mod, Fun, Args}, InfoKeys, ToBinUtf8, Timeout, IsEscaped) ->
Args0 = case ToBinUtf8 of
true -> lists:map(fun list_to_binary_utf8/1, Args);
false -> Args
@@ -839,7 +860,7 @@ call(Node, {Mod, Fun, Args}, InfoKeys, ToBinUtf8, Timeout) ->
end
end),
rabbit_control_misc:wait_for_info_messages(
- Pid, Ref, InfoKeys, fun display_info_message/2, Timeout).
+ Pid, Ref, InfoKeys, display_info_message(IsEscaped), Timeout).
list_to_binary_utf8(L) ->
B = list_to_binary(L),
@@ -852,9 +873,14 @@ list_to_binary_utf8(L) ->
%% characters. We don't escape characters above 127, since they may
%% form part of UTF-8 strings.
-escape(Atom) when is_atom(Atom) -> escape(atom_to_list(Atom));
-escape(Bin) when is_binary(Bin) -> escape(binary_to_list(Bin));
-escape(L) when is_list(L) -> escape_char(lists:reverse(L), []).
+escape(Atom, IsEscaped) when is_atom(Atom) ->
+ escape(atom_to_list(Atom), IsEscaped);
+escape(Bin, IsEscaped) when is_binary(Bin) ->
+ escape(binary_to_list(Bin), IsEscaped);
+escape(L, false) when is_list(L) ->
+ escape_char(lists:reverse(L), []);
+escape(L, true) when is_list(L) ->
+ L.
escape_char([$\\ | T], Acc) ->
escape_char(T, [$\\, $\\ | Acc]);
@@ -866,14 +892,18 @@ escape_char([X | T], Acc) ->
escape_char([], Acc) ->
Acc.
-prettify_amqp_table(Table) ->
- [{escape(K), prettify_typed_amqp_value(T, V)} || {K, T, V} <- Table].
-
-prettify_typed_amqp_value(longstr, Value) -> escape(Value);
-prettify_typed_amqp_value(table, Value) -> prettify_amqp_table(Value);
-prettify_typed_amqp_value(array, Value) -> [prettify_typed_amqp_value(T, V) ||
- {T, V} <- Value];
-prettify_typed_amqp_value(_Type, Value) -> Value.
+prettify_amqp_table(Table, IsEscaped) ->
+ [{escape(K, IsEscaped), prettify_typed_amqp_value(T, V, IsEscaped)}
+ || {K, T, V} <- Table].
+
+prettify_typed_amqp_value(longstr, Value, IsEscaped) ->
+ escape(Value, IsEscaped);
+prettify_typed_amqp_value(table, Value, IsEscaped) ->
+ prettify_amqp_table(Value, IsEscaped);
+prettify_typed_amqp_value(array, Value, IsEscaped) ->
+ [prettify_typed_amqp_value(T, V, IsEscaped) || {T, V} <- Value];
+prettify_typed_amqp_value(_Type, Value, _IsEscaped) ->
+ Value.
split_list([]) -> [];
split_list([_]) -> exit(even_list_needed);
diff --git a/src/rabbit_hipe.erl b/src/rabbit_hipe.erl
index 0302d82839..05b5f3719d 100644
--- a/src/rabbit_hipe.erl
+++ b/src/rabbit_hipe.erl
@@ -44,7 +44,8 @@ hipe_compile() ->
%% happens when RabbitMQ is stopped (just the
%% application, not the entire node) and started
%% again.
- already_hipe_compiled(HM)],
+ already_hipe_compiled(HM)
+ andalso (not compiled_with_version_support(HM))],
case HipeModules of
[] -> {ok, already_compiled};
_ -> do_hipe_compile(HipeModules)
@@ -59,6 +60,10 @@ already_hipe_compiled(Mod) ->
code:is_module_native(Mod) =:= false
end.
+compiled_with_version_support(Mod) ->
+ proplists:get_value(erlang_version_support, Mod:module_info(attributes))
+ =/= undefined.
+
do_hipe_compile(HipeModules) ->
Count = length(HipeModules),
io:format("~nHiPE compiling: |~s|~n |",
diff --git a/src/rabbit_plugins_main.erl b/src/rabbit_plugins_main.erl
index 4aeed4826c..e248989a7a 100644
--- a/src/rabbit_plugins_main.erl
+++ b/src/rabbit_plugins_main.erl
@@ -173,7 +173,7 @@ format_plugins(Node, Pattern, Opts, #cli{all = All,
EnabledImplicitly = Implicit -- Enabled,
{StatusMsg, Running} =
- case rabbit_cli:rpc_call(Node, rabbit_plugins, active, []) of
+ case rabbit_misc:rpc_call(Node, rabbit_plugins, active, []) of
{badrpc, _} -> {"[failed to contact ~s - status not shown]", []};
Active -> {"* = running on ~s", Active}
end,
@@ -279,7 +279,7 @@ sync(Node, ForceOnline, #cli{file = File}) ->
rpc_call(Node, Online, Mod, Fun, Args) ->
io:format("~nApplying plugin configuration to ~s...", [Node]),
- case rabbit_cli:rpc_call(Node, Mod, Fun, Args) of
+ case rabbit_misc:rpc_call(Node, Mod, Fun, Args) of
{ok, [], []} ->
io:format(" nothing to do.~n", []);
{ok, Start, []} ->
diff --git a/src/rabbit_types.erl b/src/rabbit_types.erl
deleted file mode 100644
index 3dcb63cbb9..0000000000
--- a/src/rabbit_types.erl
+++ /dev/null
@@ -1,168 +0,0 @@
-%% The contents of this file are subject to the Mozilla Public License
-%% Version 1.1 (the "License"); you may not use this file except in
-%% compliance with the License. You may obtain a copy of the License
-%% at http://www.mozilla.org/MPL/
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and
-%% limitations under the License.
-%%
-%% The Original Code is RabbitMQ.
-%%
-%% The Initial Developer of the Original Code is GoPivotal, Inc.
-%% Copyright (c) 2007-2016 Pivotal Software, Inc. All rights reserved.
-%%
-
--module(rabbit_types).
-
--include("rabbit.hrl").
-
--ifdef(use_specs).
-
--export_type([maybe/1, info/0, infos/0, info_key/0, info_keys/0,
- message/0, msg_id/0, basic_message/0,
- delivery/0, content/0, decoded_content/0, undecoded_content/0,
- unencoded_content/0, encoded_content/0, message_properties/0,
- vhost/0, ctag/0, amqp_error/0, r/1, r2/2, r3/3, listener/0,
- binding/0, binding_source/0, binding_destination/0,
- amqqueue/0, exchange/0,
- connection/0, protocol/0, auth_user/0, user/0, internal_user/0,
- username/0, password/0, password_hash/0,
- ok/1, error/1, ok_or_error/1, ok_or_error2/2, ok_pid_or_error/0,
- channel_exit/0, connection_exit/0, mfargs/0, proc_name/0,
- proc_type_and_name/0, timestamp/0]).
-
--type(maybe(T) :: T | 'none').
--type(timestamp() :: {non_neg_integer(), non_neg_integer(), non_neg_integer()}).
--type(vhost() :: binary()).
--type(ctag() :: binary()).
-
-%% TODO: make this more precise by tying specific class_ids to
-%% specific properties
--type(undecoded_content() ::
- #content{class_id :: rabbit_framing:amqp_class_id(),
- properties :: 'none',
- properties_bin :: binary(),
- payload_fragments_rev :: [binary()]} |
- #content{class_id :: rabbit_framing:amqp_class_id(),
- properties :: rabbit_framing:amqp_property_record(),
- properties_bin :: 'none',
- payload_fragments_rev :: [binary()]}).
--type(unencoded_content() :: undecoded_content()).
--type(decoded_content() ::
- #content{class_id :: rabbit_framing:amqp_class_id(),
- properties :: rabbit_framing:amqp_property_record(),
- properties_bin :: maybe(binary()),
- payload_fragments_rev :: [binary()]}).
--type(encoded_content() ::
- #content{class_id :: rabbit_framing:amqp_class_id(),
- properties :: maybe(rabbit_framing:amqp_property_record()),
- properties_bin :: binary(),
- payload_fragments_rev :: [binary()]}).
--type(content() :: undecoded_content() | decoded_content()).
--type(msg_id() :: rabbit_guid:guid()).
--type(basic_message() ::
- #basic_message{exchange_name :: rabbit_exchange:name(),
- routing_keys :: [rabbit_router:routing_key()],
- content :: content(),
- id :: msg_id(),
- is_persistent :: boolean()}).
--type(message() :: basic_message()).
--type(delivery() ::
- #delivery{mandatory :: boolean(),
- sender :: pid(),
- message :: message()}).
--type(message_properties() ::
- #message_properties{expiry :: pos_integer() | 'undefined',
- needs_confirming :: boolean()}).
-
--type(info_key() :: atom()).
--type(info_keys() :: [info_key()]).
-
--type(info() :: {info_key(), any()}).
--type(infos() :: [info()]).
-
--type(amqp_error() ::
- #amqp_error{name :: rabbit_framing:amqp_exception(),
- explanation :: string(),
- method :: rabbit_framing:amqp_method_name()}).
-
--type(r(Kind) ::
- r2(vhost(), Kind)).
--type(r2(VirtualHost, Kind) ::
- r3(VirtualHost, Kind, rabbit_misc:resource_name())).
--type(r3(VirtualHost, Kind, Name) ::
- #resource{virtual_host :: VirtualHost,
- kind :: Kind,
- name :: Name}).
-
--type(listener() ::
- #listener{node :: node(),
- protocol :: atom(),
- host :: rabbit_networking:hostname(),
- port :: rabbit_networking:ip_port()}).
-
--type(binding_source() :: rabbit_exchange:name()).
--type(binding_destination() :: rabbit_amqqueue:name() | rabbit_exchange:name()).
-
--type(binding() ::
- #binding{source :: rabbit_exchange:name(),
- destination :: binding_destination(),
- key :: rabbit_binding:key(),
- args :: rabbit_framing:amqp_table()}).
-
--type(amqqueue() ::
- #amqqueue{name :: rabbit_amqqueue:name(),
- durable :: boolean(),
- auto_delete :: boolean(),
- exclusive_owner :: rabbit_types:maybe(pid()),
- arguments :: rabbit_framing:amqp_table(),
- pid :: rabbit_types:maybe(pid()),
- slave_pids :: [pid()]}).
-
--type(exchange() ::
- #exchange{name :: rabbit_exchange:name(),
- type :: rabbit_exchange:type(),
- durable :: boolean(),
- auto_delete :: boolean(),
- arguments :: rabbit_framing:amqp_table()}).
-
--type(connection() :: pid()).
-
--type(protocol() :: rabbit_framing:protocol()).
-
--type(auth_user() ::
- #auth_user{username :: username(),
- tags :: [atom()],
- impl :: any()}).
-
--type(user() ::
- #user{username :: username(),
- tags :: [atom()],
- authz_backends :: [{atom(), any()}]}).
-
--type(internal_user() ::
- #internal_user{username :: username(),
- password_hash :: password_hash(),
- tags :: [atom()]}).
-
--type(username() :: binary()).
--type(password() :: binary()).
--type(password_hash() :: binary()).
-
--type(ok(A) :: {'ok', A}).
--type(error(A) :: {'error', A}).
--type(ok_or_error(A) :: 'ok' | error(A)).
--type(ok_or_error2(A, B) :: ok(A) | error(B)).
--type(ok_pid_or_error() :: ok_or_error2(pid(), any())).
-
--type(channel_exit() :: no_return()).
--type(connection_exit() :: no_return()).
-
--type(mfargs() :: {atom(), atom(), [any()]}).
-
--type(proc_name() :: term()).
--type(proc_type_and_name() :: {atom(), proc_name()}).
-
--endif. % use_specs