summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthias Radestock <matthias@lshift.net>2008-11-28 21:51:16 +0000
committerMatthias Radestock <matthias@lshift.net>2008-11-28 21:51:16 +0000
commit0833b811241a9332828e1bbf7368a42b1012bd7a (patch)
tree884ce6de999c089b00563ccc529fcfa76d2a7fb0
parent1d48d102808e18875633192e2c78e36d006d1121 (diff)
parentc5ff9a6c96c40835f19a7fba47c9594a0ddc91b0 (diff)
downloadrabbitmq-server-0833b811241a9332828e1bbf7368a42b1012bd7a.tar.gz
merge bug19852 into default
-rw-r--r--include/rabbit.hrl4
-rw-r--r--packaging/RPMS/Fedora/Makefile3
-rw-r--r--packaging/RPMS/Fedora/rabbitmq-server.spec12
-rw-r--r--packaging/debs/Debian/debian/dirs1
-rw-r--r--packaging/debs/Debian/debian/init.d4
-rw-r--r--packaging/debs/Debian/debian/rabbitmqctl_wrapper2
-rw-r--r--packaging/debs/Debian/debian/rules9
-rw-r--r--packaging/windows/Makefile3
-rw-r--r--packaging/windows/rabbitmq-service.pod138
-rwxr-xr-x[-rw-r--r--]scripts/rabbitmq-server.bat0
-rwxr-xr-xscripts/rabbitmq-service.bat189
-rw-r--r--src/rabbit.erl4
-rw-r--r--src/rabbit_amqqueue.erl2
-rw-r--r--src/rabbit_control.erl138
-rw-r--r--src/rabbit_load.erl6
-rw-r--r--src/rabbit_log.erl14
-rw-r--r--src/rabbit_misc.erl2
-rw-r--r--src/rabbit_mnesia.erl4
-rw-r--r--src/rabbit_networking.erl4
-rw-r--r--src/rabbit_sasl_report_file_h.erl5
-rw-r--r--src/rabbit_tests.erl2
21 files changed, 453 insertions, 93 deletions
diff --git a/include/rabbit.hrl b/include/rabbit.hrl
index 706a92af..42bc8fa9 100644
--- a/include/rabbit.hrl
+++ b/include/rabbit.hrl
@@ -63,7 +63,7 @@
-include("rabbit_framing_spec.hrl").
-type(maybe(T) :: T | 'none').
--type(node() :: atom()).
+-type(erlang_node() :: atom()).
-type(socket() :: port()).
-type(thunk(T) :: fun(() -> T)).
@@ -123,7 +123,7 @@
-type(msg_id() :: non_neg_integer()).
-type(msg() :: {queue_name(), pid(), msg_id(), bool(), message()}).
-type(listener() ::
- #listener{node :: node(),
+ #listener{node :: erlang_node(),
protocol :: atom(),
host :: string() | atom(),
port :: non_neg_integer()}).
diff --git a/packaging/RPMS/Fedora/Makefile b/packaging/RPMS/Fedora/Makefile
index 33032f11..f6d8dde8 100644
--- a/packaging/RPMS/Fedora/Makefile
+++ b/packaging/RPMS/Fedora/Makefile
@@ -20,7 +20,8 @@ prepare:
cp rabbitmq-server.logrotate SOURCES/rabbitmq-server.logrotate
server: prepare
- rpmbuild -ba SPECS/rabbitmq-server.spec $(DEFINES) --target noarch
+ rpmbuild -ba SPECS/rabbitmq-server.spec $(DEFINES) --target i386
+ rpmbuild -ba SPECS/rabbitmq-server.spec $(DEFINES) --target x86_64
clean:
rm -rf SOURCES SPECS RPMS SRPMS BUILD tmp
diff --git a/packaging/RPMS/Fedora/rabbitmq-server.spec b/packaging/RPMS/Fedora/rabbitmq-server.spec
index ae2f2d2b..23ebecef 100644
--- a/packaging/RPMS/Fedora/rabbitmq-server.spec
+++ b/packaging/RPMS/Fedora/rabbitmq-server.spec
@@ -15,7 +15,7 @@ BuildRequires: erlang, python-json
%endif
Requires: erlang, logrotate
Packager: Hubert Plociniczak <hubert@lshift.net>
-BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root
+BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-%{_arch}-root
Summary: The RabbitMQ server
Requires(post): chkconfig
Requires(pre): chkconfig initscripts
@@ -25,11 +25,14 @@ RabbitMQ is an implementation of AMQP, the emerging standard for high
performance enterprise messaging. The RabbitMQ server is a robust and
scalable implementation of an AMQP broker.
+%ifarch x86_64
+ %define _erllibdir /usr/lib64/erlang/lib
+%else
+ %define _erllibdir /usr/lib/erlang/lib
+%endif
-%define _erllibdir %(erl -noshell -eval "io:format('~s~n', [code:lib_dir()]), halt().")
%define _maindir %{buildroot}%{_erllibdir}/rabbitmq_server-%{version}
-
%pre
if [ $1 -gt 1 ]; then
#Upgrade - stop and remove previous instance of rabbitmq-server init.d script
@@ -67,6 +70,8 @@ cp %{buildroot}%{_mandir}/man1/rabbitmqctl.1.gz %{buildroot}%{_mandir}/man1/rabb
mkdir -p %{buildroot}/etc/logrotate.d
install %SOURCE3 %{buildroot}/etc/logrotate.d/rabbitmq-server
+rm %{_maindir}/LICENSE %{_maindir}/LICENSE-MPL-RabbitMQ %{_maindir}/INSTALL
+
%post
# create rabbitmq group
if ! getent group rabbitmq >/dev/null; then
@@ -110,6 +115,7 @@ fi
/var/log/rabbitmq/
/etc/rc.d/init.d/rabbitmq-server
%config(noreplace) /etc/logrotate.d/rabbitmq-server
+%doc LICENSE LICENSE-MPL-RabbitMQ INSTALL
%clean
rm -rf %{buildroot}
diff --git a/packaging/debs/Debian/debian/dirs b/packaging/debs/Debian/debian/dirs
index 74f86314..1a707bc1 100644
--- a/packaging/debs/Debian/debian/dirs
+++ b/packaging/debs/Debian/debian/dirs
@@ -1,3 +1,4 @@
+usr/lib/rabbitmq/bin
usr/lib/erlang/lib
usr/sbin
usr/share/man
diff --git a/packaging/debs/Debian/debian/init.d b/packaging/debs/Debian/debian/init.d
index a93f3066..ace474c5 100644
--- a/packaging/debs/Debian/debian/init.d
+++ b/packaging/debs/Debian/debian/init.d
@@ -10,7 +10,7 @@
### END INIT INFO
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
-DAEMON=/usr/sbin/rabbitmq-multi
+DAEMON=/usr/lib/rabbitmq/bin/rabbitmq-multi
NAME=rabbitmq-server
DESC=rabbitmq-server
USER=rabbitmq
@@ -51,7 +51,7 @@ start_rabbitmq () {
stop_rabbitmq () {
set +e
status_rabbitmq quiet
- if [ $RETVAL == 0 ] ; then
+ if [ $RETVAL = 0 ] ; then
su $USER -s /bin/sh -c "$DAEMON stop_all" > /var/log/rabbitmq/shutdown_log 2> /var/log/rabbitmq/shutdown_err
RETVAL=$?
if [ $RETVAL != 0 ] ; then
diff --git a/packaging/debs/Debian/debian/rabbitmqctl_wrapper b/packaging/debs/Debian/debian/rabbitmqctl_wrapper
index c484bb27..75b37c0d 100644
--- a/packaging/debs/Debian/debian/rabbitmqctl_wrapper
+++ b/packaging/debs/Debian/debian/rabbitmqctl_wrapper
@@ -10,5 +10,5 @@ for arg in "$@" ; do
done
cd /
-su rabbitmq -s /bin/sh -c "/usr/sbin/rabbitmqctl_real ${CMDLINE}"
+su rabbitmq -s /bin/sh -c "/usr/lib/rabbitmq/bin/rabbitmqctl ${CMDLINE}"
diff --git a/packaging/debs/Debian/debian/rules b/packaging/debs/Debian/debian/rules
index 39af711c..fa4cb855 100644
--- a/packaging/debs/Debian/debian/rules
+++ b/packaging/debs/Debian/debian/rules
@@ -3,17 +3,16 @@
include /usr/share/cdbs/1/rules/debhelper.mk
include /usr/share/cdbs/1/class/makefile.mk
-RABBIT_LIB=$(DEB_DESTDIR)usr/lib/erlang/lib/rabbitmq_server-$(DEB_UPSTREAM_VERSION)
+RABBIT_LIB=$(DEB_DESTDIR)usr/lib/erlang/lib/rabbitmq_server-$(DEB_UPSTREAM_VERSION)/
+RABBIT_BIN=$(DEB_DESTDIR)usr/lib/rabbitmq/bin/
-DEB_MAKE_INSTALL_TARGET := install TARGET_DIR=$(RABBIT_LIB)/ SBIN_DIR=$(DEB_DESTDIR)usr/sbin MAN_DIR=$(DEB_DESTDIR)usr/share/man
+DEB_MAKE_INSTALL_TARGET := install TARGET_DIR=$(RABBIT_LIB) SBIN_DIR=$(RABBIT_BIN) MAN_DIR=$(DEB_DESTDIR)usr/share/man/
DOCDIR=$(DEB_DESTDIR)usr/share/doc/rabbitmq-server/
install/rabbitmq-server::
mkdir -p $(DOCDIR)
- rm $(RABBIT_LIB)/LICENSE*
- mv $(DEB_DESTDIR)usr/sbin/rabbitmqctl $(DEB_DESTDIR)usr/sbin/rabbitmqctl_real
+ rm $(RABBIT_LIB)LICENSE*
cp debian/rabbitmqctl_wrapper $(DEB_DESTDIR)usr/sbin/rabbitmqctl
cp debian/rabbitmq-server.logrotate $(DEB_DESTDIR)etc/logrotate.d/rabbitmq-server
- cp $(DEB_DESTDIR)usr/share/man/man1/rabbitmqctl.1.gz $(DEB_DESTDIR)usr/share/man/man1/rabbitmqctl_real.1.gz
chmod a+x $(DEB_DESTDIR)usr/sbin/rabbitmqctl
diff --git a/packaging/windows/Makefile b/packaging/windows/Makefile
index f9437da7..9d16fd9f 100644
--- a/packaging/windows/Makefile
+++ b/packaging/windows/Makefile
@@ -10,6 +10,7 @@ dist:
mkdir $(SOURCE_DIR)/sbin
mv $(SOURCE_DIR)/scripts/rabbitmq-server.bat $(SOURCE_DIR)/sbin
+ mv $(SOURCE_DIR)/scripts/rabbitmq-service.bat $(SOURCE_DIR)/sbin
mv $(SOURCE_DIR)/scripts/rabbitmqctl.bat $(SOURCE_DIR)/sbin
mv $(SOURCE_DIR)/scripts/rabbitmq-multi.bat $(SOURCE_DIR)/sbin
rm -rf $(SOURCE_DIR)/scripts
@@ -18,6 +19,8 @@ dist:
rm -rf $(SOURCE_DIR)/docs
mv $(SOURCE_DIR) $(TARGET_DIR)
+ pod2text --loose rabbitmq-service.pod $(TARGET_DIR)/readme-service.txt
+ unix2dos $(TARGET_DIR)/readme-service.txt
zip -r $(TARGET_ZIP).zip $(TARGET_DIR)
rm -rf $(TARGET_DIR)
diff --git a/packaging/windows/rabbitmq-service.pod b/packaging/windows/rabbitmq-service.pod
new file mode 100644
index 00000000..6a97c435
--- /dev/null
+++ b/packaging/windows/rabbitmq-service.pod
@@ -0,0 +1,138 @@
+=head1 NAME
+
+rabbitmq-service - manage RabbitMQ AMQP service
+
+=head1 SYNOPSIS
+
+rabbitmq-service.bat command
+
+=head1 DESCRIPTION
+
+RabbitMQ is an implementation of AMQP, the emerging standard for high
+performance enterprise messaging. The RabbitMQ server is a robust and
+scalable implementation of an AMQP broker.
+
+Running B<rabbitmq-service> allows the RabbitMQ broker to be run as a
+service on NT/2000/2003/XP/Vista® environments. The RabbitMQ broker
+service can be started and stopped using the Windows® services
+applet.
+
+By default the service will run in the authentication context of the
+local system account. It is therefore necessary to synchronise Erlang
+cookies between the local system account (typically
+C<C:\WINDOWS\.erlang.cookie> and the account that will be used to
+run B<rabbitmqctl>.
+
+=head1 COMMANDS
+
+=head2 help
+
+Display usage information.
+
+=head2 install
+
+Install the service. The service will not be started.
+Subsequent invocations will update the service parameters if
+relevant environment variables were modified.
+
+=head2 remove
+
+Remove the service. If the service is running then it will
+automatically be stopped before being removed. No files will be
+deleted as a consequence and B<rabbitmq-server> will remain operable.
+
+=head2 start
+
+Start the service. The service must have been correctly installed
+beforehand.
+
+=head2 stop
+
+Stop the service. The service must be running for this command to
+have any effect.
+
+=head2 disable
+
+Disable the service. This is the equivalent of setting the startup
+type to B<Disabled> using the service control panel.
+
+=head2 enable
+
+Enable the service. This is the equivalent of setting the startup
+type to B<Automatic> using the service control panel.
+
+=head1 ENVIRONMENT
+
+=head2 SERVICENAME
+
+Defaults to RabbitMQ.
+This is the location of log and database directories.
+
+=head2 RABBITMQ_BASE
+
+Defaults to the application data directory of the current user.
+This is the location of log and database directories.
+
+=head2 NODENAME
+
+Defaults to "rabbit". This can be useful if you want to run more
+than one node per machine - B<NODENAME> should be unique per
+erlang-node-and-machine combination. See clustering on a single
+machine guide
+at L<http://www.rabbitmq.com/clustering.html#single-machine> for
+details.
+
+=head2 NODE_IP_ADDRESS
+
+Defaults to "0.0.0.0". This can be changed if you only want to bind
+to one network interface.
+
+=head2 NODE_PORT
+
+Defaults to 5672.
+
+=head2 ERLANG_SERVICE_MANAGER_PATH
+
+Defaults to F<C:\Program Files\erl5.5.5\erts-5.5.5\bin>. This is
+the installation location of the Erlang service manager.
+
+=head2 CLUSTER_CONFIG_FILE
+
+If this file is present it is used by the server to
+auto-configure a RabbitMQ cluster. See the clustering guide
+at L<http://www.rabbitmq.com/clustering.html> for details.
+
+=head2 CONSOLE_LOG
+
+Set this varable to B<new> or B<reuse> to have the console
+output from the server redirected to a file named B<SERVICENAME>.debug
+in the application data directory of the user that installed the service.
+Under Vista this will be F<C:\Documents and Settings\User\AppData\username\SERVICENAME>.
+Under previous versions of Windows this will be
+F<C:\Documents and Settings\username\Application Data\SERVICENAME>.
+If B<CONSOLE_LOG> is set to B<new> then a new file will be created
+each time the service starts. If B<CONSOLE_LOG> is set to B<reuse>
+then the file will be overwritten each time the service starts.
+The default behaviour when B<CONSOLE_LOG> is not set or set to a
+value other than B<new> or B<reuse> is to discard the server output.
+
+=head1 EXAMPLES
+
+Start a previously-installed RabbitMQ AMQP service:
+
+ rabbitmq-service start
+
+=head1 AUTHOR
+
+Originally written by The RabbitMQ Team <info@lshift.net>
+
+=head1 COPYRIGHT
+
+This package, the RabbitMQ server is licensed under the MPL.
+
+If you have any questions regarding licensing, please contact us at
+info@rabbitmq.com.
+
+=head1 REFERENCES
+
+RabbitMQ Web Site: http://www.rabbitmq.com
diff --git a/scripts/rabbitmq-server.bat b/scripts/rabbitmq-server.bat
index b21c2739..b21c2739 100644..100755
--- a/scripts/rabbitmq-server.bat
+++ b/scripts/rabbitmq-server.bat
diff --git a/scripts/rabbitmq-service.bat b/scripts/rabbitmq-service.bat
new file mode 100755
index 00000000..4b9cc452
--- /dev/null
+++ b/scripts/rabbitmq-service.bat
@@ -0,0 +1,189 @@
+@echo off
+REM The contents of this file are subject to the Mozilla Public License
+REM Version 1.1 (the "License"); you may not use this file except in
+REM compliance with the License. You may obtain a copy of the License at
+REM http://www.mozilla.org/MPL/
+REM
+REM Software distributed under the License is distributed on an "AS IS"
+REM basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
+REM License for the specific language governing rights and limitations
+REM under the License.
+REM
+REM The Original Code is RabbitMQ.
+REM
+REM The Initial Developers of the Original Code are LShift Ltd.,
+REM Cohesive Financial Technologies LLC., and Rabbit Technologies Ltd.
+REM
+REM Portions created by LShift Ltd., Cohesive Financial Technologies
+REM LLC., and Rabbit Technologies Ltd. are Copyright (C) 2007-2008
+REM LShift Ltd., Cohesive Financial Technologies LLC., and Rabbit
+REM Technologies Ltd.;
+REM
+REM All Rights Reserved.
+REM
+REM Contributor(s): ______________________________________.
+REM
+
+if "%SERVICENAME%"=="" (
+ set SERVICENAME=RabbitMQ
+)
+
+if "%RABBITMQ_BASE%"=="" (
+ set RABBITMQ_BASE=%APPDATA%\%SERVICENAME%
+)
+
+if "%NODENAME%"=="" (
+ set NODENAME=rabbit
+)
+
+if "%NODE_IP_ADDRESS%"=="" (
+ set NODE_IP_ADDRESS=0.0.0.0
+)
+
+if "%NODE_PORT%"=="" (
+ set NODE_PORT=5672
+)
+
+if "%ERLANG_SERVICE_MANAGER_PATH%"=="" (
+ set ERLANG_SERVICE_MANAGER_PATH=C:\Program Files\erl5.5.5\erts-5.5.5\bin
+)
+
+set CONSOLE_FLAG=
+set CONSOLE_LOG_VALID=
+for %%i in (new reuse) do if "%%i" == "%CONSOLE_LOG%" set CONSOLE_LOG_VALID=TRUE
+if "%CONSOLE_LOG_VALID%" == "TRUE" (
+ set CONSOLE_FLAG=-debugtype %CONSOLE_LOG%
+)
+
+rem *** End of configuration ***
+
+if not exist "%ERLANG_SERVICE_MANAGER_PATH%\erlsrv.exe" (
+ echo.
+ echo **********************************************
+ echo ERLANG_SERVICE_MANAGER_PATH not set correctly.
+ echo **********************************************
+ echo.
+ echo %ERLANG_SERVICE_MANAGER_PATH%\erlsrv.exe not found!
+ echo Please set ERLANG_SERVICE_MANAGER_PATH to the folder containing "erlsrv.exe".
+ echo.
+ exit /B 1
+)
+
+rem erlang prefers forwardslash as separator in paths
+set RABBITMQ_BASE_UNIX=%RABBITMQ_BASE:\=/%
+set MNESIA_BASE=%RABBITMQ_BASE_UNIX%/db
+set LOG_BASE=%RABBITMQ_BASE_UNIX%/log
+
+
+rem We save the previous logs in their respective backup
+rem Log management (rotation, filtering based on size...) is left as an exercise for the user.
+
+set BACKUP_EXTENSION=.1
+
+set LOGS="%RABBITMQ_BASE%\log\%NODENAME%.log"
+set SASL_LOGS="%RABBITMQ_BASE%\log\%NODENAME%-sasl.log"
+
+set LOGS_BACKUP="%RABBITMQ_BASE%\log\%NODENAME%.log%BACKUP_EXTENSION%"
+set SASL_LOGS_BACKUP="%RABBITMQ_BASE%\log\%NODENAME%-sasl.log%BACKUP_EXTENSION%"
+
+if exist %LOGS% (
+ type %LOGS% >> %LOGS_BACKUP%
+)
+if exist %SASL_LOGS% (
+ type %SASL_LOGS% >> %SASL_LOGS_BACKUP%
+)
+
+rem End of log management
+
+
+set CLUSTER_CONFIG_FILE=%RABBITMQ_BASE%\rabbitmq_cluster.config
+set CLUSTER_CONFIG=
+if not exist "%CLUSTER_CONFIG_FILE%" GOTO L1
+set CLUSTER_CONFIG=-rabbit cluster_config \""%CLUSTER_CONFIG_FILE:\=/%"\"
+:L1
+
+set MNESIA_DIR=%MNESIA_BASE%/%NODENAME%-mnesia
+
+
+if "%1" == "install" goto INSTALL_SERVICE
+for %%i in (start stop disable enable list remove) do if "%%i" == "%1" goto MODIFY_SERVICE
+
+echo.
+echo *********************
+echo Service control usage
+echo *********************
+echo.
+echo %~n0 help - Display this help
+echo %~n0 install - Install the %SERVICENAME% service
+echo %~n0 remove - Remove the %SERVICENAME% service
+echo.
+echo The following actions can also be accomplished by using
+echo Windows Services Management Console (services.msc):
+echo.
+echo %~n0 start - Start the %SERVICENAME% service
+echo %~n0 stop - Stop the %SERVICENAME% service
+echo %~n0 disable - Disable the %SERVICENAME% service
+echo %~n0 enable - Enable the %SERVICENAME% service
+echo.
+exit /B
+
+
+:INSTALL_SERVICE
+
+if not exist "%RABBITMQ_BASE%" (
+ echo Creating base directory %RABBITMQ_BASE% & md "%RABBITMQ_BASE%"
+)
+
+"%ERLANG_SERVICE_MANAGER_PATH%\erlsrv" list %SERVICENAME% 2>NUL 1>NUL
+if errorlevel 1 (
+ "%ERLANG_SERVICE_MANAGER_PATH%\erlsrv" add %SERVICENAME%
+) else (
+ echo %SERVICENAME% service is already present - only updating service parameters
+)
+
+set RABBIT_EBIN=%~dp0..\ebin
+
+set ERLANG_SERVICE_ARGUMENTS= ^
+-pa "%RABBIT_EBIN%" ^
+-boot start_sasl ^
+-s rabbit ^
++W w ^
++A30 ^
+-kernel inet_default_listen_options "[{nodelay,true},{sndbuf,16384},{recbuf,4096}]" ^
+-kernel inet_default_connect_options "[{nodelay,true}]" ^
+-rabbit tcp_listeners "[{\"%NODE_IP_ADDRESS%\",%NODE_PORT%}]" ^
+-kernel error_logger {file,\""%LOG_BASE%/%NODENAME%.log"\"} ^
+-sasl errlog_type error ^
+-sasl sasl_error_logger {file,\""%LOG_BASE%/%NODENAME%-sasl.log"\"} ^
+-os_mon start_cpu_sup true ^
+-os_mon start_disksup false ^
+-os_mon start_memsup true ^
+-os_mon start_os_sup false ^
+-os_mon memsup_system_only true ^
+-os_mon system_memory_high_watermark 0.95 ^
+-mnesia dir \""%MNESIA_DIR%"\" ^
+%CLUSTER_CONFIG% ^
+%RABBIT_ARGS% ^
+%*
+
+set ERLANG_SERVICE_ARGUMENTS=%ERLANG_SERVICE_ARGUMENTS:\=\\%
+set ERLANG_SERVICE_ARGUMENTS=%ERLANG_SERVICE_ARGUMENTS:"=\"%
+
+"%ERLANG_SERVICE_MANAGER_PATH%\erlsrv" set %SERVICENAME% ^
+-machine "%ERLANG_SERVICE_MANAGER_PATH%\erl.exe" ^
+-env ERL_CRASH_DUMP="%RABBITMQ_BASE_UNIX%/log" ^
+-workdir "%RABBITMQ_BASE%" ^
+-stopaction "rabbit:stop_and_halt()." ^
+-sname %NODENAME% ^
+%CONSOLE_FLAG% ^
+-args "%ERLANG_SERVICE_ARGUMENTS%" > NUL
+goto END
+
+
+:MODIFY_SERVICE
+
+"%ERLANG_SERVICE_MANAGER_PATH%\erlsrv" %1 %SERVICENAME%
+goto END
+
+
+:END \ No newline at end of file
diff --git a/src/rabbit.erl b/src/rabbit.erl
index a33c5b7b..195dd729 100644
--- a/src/rabbit.erl
+++ b/src/rabbit.erl
@@ -57,8 +57,8 @@
-spec(rotate_logs/1 :: (file_suffix()) -> 'ok' | {'error', any()}).
-spec(status/0 :: () ->
[{running_applications, [{atom(), string(), string()}]} |
- {nodes, [node()]} |
- {running_nodes, [node()]}]).
+ {nodes, [erlang_node()]} |
+ {running_nodes, [erlang_node()]}]).
-spec(log_location/1 :: ('sasl' | 'kernel') -> log_location()).
-endif.
diff --git a/src/rabbit_amqqueue.erl b/src/rabbit_amqqueue.erl
index 56d2c35d..4b318eeb 100644
--- a/src/rabbit_amqqueue.erl
+++ b/src/rabbit_amqqueue.erl
@@ -89,7 +89,7 @@
-spec(basic_cancel/4 :: (amqqueue(), pid(), ctag(), any()) -> 'ok').
-spec(notify_sent/2 :: (pid(), pid()) -> 'ok').
-spec(internal_delete/1 :: (queue_name()) -> 'ok' | not_found()).
--spec(on_node_down/1 :: (node()) -> 'ok').
+-spec(on_node_down/1 :: (erlang_node()) -> 'ok').
-spec(pseudo_queue/2 :: (binary(), pid()) -> amqqueue()).
-endif.
diff --git a/src/rabbit_control.erl b/src/rabbit_control.erl
index bc588279..2f7e58e0 100644
--- a/src/rabbit_control.erl
+++ b/src/rabbit_control.erl
@@ -26,43 +26,50 @@
-module(rabbit_control).
-include("rabbit.hrl").
--export([start/0, stop/0, action/3]).
+-export([start/0, stop/0, action/4]).
+
+-record(params, {quiet, node, command, args}).
-define(RPC_TIMEOUT, 30000).
start() ->
- case init:get_plain_arguments() of
- [] ->
+ FullCommand = init:get_plain_arguments(),
+ #params{quiet = Quiet, node = Node, command = Command, args = Args} =
+ parse_args(FullCommand, #params{quiet = false, node = rabbit_misc:localnode(rabbit)}),
+ Inform = case Quiet of
+ true -> fun(_Format, _Data) -> ok end;
+ false -> fun io:format/2
+ end,
+ case catch action(Command, Node, Args, Inform) of
+ ok ->
+ Inform("done.~n", []),
+ init:stop();
+ {'EXIT', {function_clause, [{?MODULE, action, _} | _]}} ->
+ io:format("Error~nInvalid command ~p~n", [FullCommand]),
usage();
- FullCommand ->
- {Node, Command, Args} = parse_args(FullCommand),
- case catch action(Command, Node, Args) of
- ok ->
- io:format("done.~n"),
- init:stop();
- {'EXIT', {function_clause, [{?MODULE, action, _} | _]}} ->
- io:format("Invalid command ~p~n", [FullCommand]),
- usage();
- Other ->
- io:format("~nrabbit_control action ~p failed:~n~p~n", [Command, Other]),
- halt(2)
- end
+ Other ->
+ io:format("Error~nrabbit_control action ~p failed:~n~p~n", [Command, Other]),
+ halt(2)
end.
-parse_args(["-n", NodeS, Command | Args]) ->
+parse_args(["-n", NodeS | Args], Params) ->
Node = case lists:member($@, NodeS) of
true -> list_to_atom(NodeS);
false -> rabbit_misc:localnode(list_to_atom(NodeS))
end,
- {Node, list_to_atom(Command), Args};
-parse_args([Command | Args]) ->
- {rabbit_misc:localnode(rabbit), list_to_atom(Command), Args}.
+ parse_args(Args, Params#params{node = Node});
+parse_args(["-q" | Args], Params) ->
+ parse_args(Args, Params#params{quiet = true});
+parse_args([Command | Args], Params) ->
+ Params#params{command = list_to_atom(Command), args = Args};
+parse_args([], _) ->
+ usage().
stop() ->
ok.
usage() ->
- io:format("Usage: rabbitmqctl [-n <node>] <command> [<arg> ...]
+ io:format("Usage: rabbitmqctl [-q] [-n <node>] <command> [<arg> ...]
Available commands:
@@ -89,6 +96,9 @@ Available commands:
list_user_vhosts <UserName>
list_vhost_users <VHostPath>
+Quiet output mode is selected with the \"-q\" flag. Informational messages
+are suppressed when quiet mode is in effect.
+
<node> should be the name of the master node of the RabbitMQ cluster. It
defaults to the node named \"rabbit\" on the local host. On a host named
\"server.example.com\", the master node will usually be rabbit@server (unless
@@ -98,95 +108,95 @@ output of hostname -s is usually the correct suffix to use after the \"@\" sign.
"),
halt(1).
-action(stop, Node, []) ->
- io:format("Stopping and halting node ~p ...", [Node]),
+action(stop, Node, [], Inform) ->
+ Inform("Stopping and halting node ~p ...~n", [Node]),
call(Node, {rabbit, stop_and_halt, []});
-action(stop_app, Node, []) ->
- io:format("Stopping node ~p ...", [Node]),
+action(stop_app, Node, [], Inform) ->
+ Inform("Stopping node ~p ...~n", [Node]),
call(Node, {rabbit, stop, []});
-action(start_app, Node, []) ->
- io:format("Starting node ~p ...", [Node]),
+action(start_app, Node, [], Inform) ->
+ Inform("Starting node ~p ...~n", [Node]),
call(Node, {rabbit, start, []});
-action(reset, Node, []) ->
- io:format("Resetting node ~p ...", [Node]),
+action(reset, Node, [], Inform) ->
+ Inform("Resetting node ~p ...~n", [Node]),
call(Node, {rabbit_mnesia, reset, []});
-action(force_reset, Node, []) ->
- io:format("Forcefully resetting node ~p ...", [Node]),
+action(force_reset, Node, [], Inform) ->
+ Inform("Forcefully resetting node ~p ...~n", [Node]),
call(Node, {rabbit_mnesia, force_reset, []});
-action(cluster, Node, ClusterNodeSs) ->
+action(cluster, Node, ClusterNodeSs, Inform) ->
ClusterNodes = lists:map(fun list_to_atom/1, ClusterNodeSs),
- io:format("Clustering node ~p with ~p ...",
+ Inform("Clustering node ~p with ~p ...~n",
[Node, ClusterNodes]),
rpc_call(Node, rabbit_mnesia, cluster, [ClusterNodes]);
-action(status, Node, []) ->
- io:format("Status of node ~p ...", [Node]),
+action(status, Node, [], Inform) ->
+ Inform("Status of node ~p ...~n", [Node]),
Res = call(Node, {rabbit, status, []}),
- io:format("~n~p~n", [Res]),
+ io:format("~p~n", [Res]),
ok;
-action(rotate_logs, Node, []) ->
- io:format("Reopening logs for node ~p ...", [Node]),
+action(rotate_logs, Node, [], Inform) ->
+ Inform("Reopening logs for node ~p ...~n", [Node]),
call(Node, {rabbit, rotate_logs, [""]});
-action(rotate_logs, Node, Args = [Suffix]) ->
- io:format("Rotating logs to files with suffix ~p ...", [Suffix]),
+action(rotate_logs, Node, Args = [Suffix], Inform) ->
+ Inform("Rotating logs to files with suffix ~p ...~n", [Suffix]),
call(Node, {rabbit, rotate_logs, Args});
-action(add_user, Node, Args = [Username, _Password]) ->
- io:format("Creating user ~p ...", [Username]),
+action(add_user, Node, Args = [Username, _Password], Inform) ->
+ Inform("Creating user ~p ...~n", [Username]),
call(Node, {rabbit_access_control, add_user, Args});
-action(delete_user, Node, Args = [_Username]) ->
- io:format("Deleting user ~p ...", Args),
+action(delete_user, Node, Args = [_Username], Inform) ->
+ Inform("Deleting user ~p ...~n", Args),
call(Node, {rabbit_access_control, delete_user, Args});
-action(change_password, Node, Args = [Username, _Newpassword]) ->
- io:format("Changing password for user ~p ...", [Username]),
+action(change_password, Node, Args = [Username, _Newpassword], Inform) ->
+ Inform("Changing password for user ~p ...~n", [Username]),
call(Node, {rabbit_access_control, change_password, Args});
-action(list_users, Node, []) ->
- io:format("Listing users ..."),
+action(list_users, Node, [], Inform) ->
+ Inform("Listing users ...~n", []),
display_list(call(Node, {rabbit_access_control, list_users, []}));
-action(add_vhost, Node, Args = [_VHostPath]) ->
- io:format("Creating vhost ~p ...", Args),
+action(add_vhost, Node, Args = [_VHostPath], Inform) ->
+ Inform("Creating vhost ~p ...~n", Args),
call(Node, {rabbit_access_control, add_vhost, Args});
-action(delete_vhost, Node, Args = [_VHostPath]) ->
- io:format("Deleting vhost ~p ...", Args),
+action(delete_vhost, Node, Args = [_VHostPath], Inform) ->
+ Inform("Deleting vhost ~p ...~n", Args),
call(Node, {rabbit_access_control, delete_vhost, Args});
-action(list_vhosts, Node, []) ->
- io:format("Listing vhosts ..."),
+action(list_vhosts, Node, [], Inform) ->
+ Inform("Listing vhosts ...~n", []),
display_list(call(Node, {rabbit_access_control, list_vhosts, []}));
-action(map_user_vhost, Node, Args = [_Username, _VHostPath]) ->
- io:format("Mapping user ~p to vhost ~p ...", Args),
+action(map_user_vhost, Node, Args = [_Username, _VHostPath], Inform) ->
+ Inform("Mapping user ~p to vhost ~p ...~n", Args),
call(Node, {rabbit_access_control, map_user_vhost, Args});
-action(unmap_user_vhost, Node, Args = [_Username, _VHostPath]) ->
- io:format("Unmapping user ~p from vhost ~p ...", Args),
+action(unmap_user_vhost, Node, Args = [_Username, _VHostPath], Inform) ->
+ Inform("Unmapping user ~p from vhost ~p ...~n", Args),
call(Node, {rabbit_access_control, unmap_user_vhost, Args});
-action(list_user_vhosts, Node, Args = [_Username]) ->
- io:format("Listing vhosts for user ~p...", Args),
+action(list_user_vhosts, Node, Args = [_Username], Inform) ->
+ Inform("Listing vhosts for user ~p...~n", Args),
display_list(call(Node, {rabbit_access_control, list_user_vhosts, Args}));
-action(list_vhost_users, Node, Args = [_VHostPath]) ->
- io:format("Listing users for vhosts ~p...", Args),
+action(list_vhost_users, Node, Args = [_VHostPath], Inform) ->
+ Inform("Listing users for vhosts ~p...~n", Args),
display_list(call(Node, {rabbit_access_control, list_vhost_users, Args})).
display_list(L) when is_list(L) ->
lists:foreach(fun (I) ->
- io:format("~n~s", [binary_to_list(I)])
+ io:format("~s~n", [binary_to_list(I)])
end,
lists:sort(L)),
- io:nl();
+ ok;
display_list(Other) -> Other.
call(Node, {Mod, Fun, Args}) ->
diff --git a/src/rabbit_load.erl b/src/rabbit_load.erl
index 8deec8eb..2154bf72 100644
--- a/src/rabbit_load.erl
+++ b/src/rabbit_load.erl
@@ -34,11 +34,11 @@
-ifdef(use_specs).
--type(node() :: atom()).
--type(load() :: {{non_neg_integer(), float()}, node()}).
+-type(erlang_node() :: atom()).
+-type(load() :: {{non_neg_integer(), float()}, erlang_node()}).
-spec(local_load/0 :: () -> load()).
-spec(remote_loads/0 :: () -> [load()]).
--spec(pick/0 :: () -> node()).
+-spec(pick/0 :: () -> erlang_node()).
-endif.
diff --git a/src/rabbit_log.erl b/src/rabbit_log.erl
index a8f839f0..b4729230 100644
--- a/src/rabbit_log.erl
+++ b/src/rabbit_log.erl
@@ -32,7 +32,7 @@
-export([init/1, handle_call/3, handle_cast/2, handle_info/2,
terminate/2, code_change/3]).
--export([debug/1, debug/2, info/1, info/2,
+-export([debug/1, debug/2, message/4, info/1, info/2,
warning/1, warning/2, error/1, error/2]).
-import(io).
@@ -67,6 +67,10 @@ debug(Fmt) ->
debug(Fmt, Args) when is_list(Args) ->
gen_server:cast(?SERVER, {debug, Fmt, Args}).
+message(Direction, Channel, MethodRecord, Content) ->
+ gen_server:cast(?SERVER,
+ {message, Direction, Channel, MethodRecord, Content}).
+
info(Fmt) ->
gen_server:cast(?SERVER, {info, Fmt}).
@@ -100,6 +104,14 @@ handle_cast({debug, Fmt, Args}, State) ->
io:format("debug:: "), io:format(Fmt, Args),
error_logger:info_msg("debug:: " ++ Fmt, Args),
{noreply, State};
+handle_cast({message, Direction, Channel, MethodRecord, Content}, State) ->
+ io:format("~s ch~p ~p~n",
+ [case Direction of
+ in -> "-->";
+ out -> "<--" end,
+ Channel,
+ {MethodRecord, Content}]),
+ {noreply, State};
handle_cast({info, Fmt}, State) ->
error_logger:info_msg(Fmt),
{noreply, State};
diff --git a/src/rabbit_misc.erl b/src/rabbit_misc.erl
index 7638af58..c1c643d3 100644
--- a/src/rabbit_misc.erl
+++ b/src/rabbit_misc.erl
@@ -85,7 +85,7 @@
-spec(with_user_and_vhost/3 :: (username(), vhost(), thunk(A)) -> A).
-spec(execute_mnesia_transaction/1 :: (thunk(A)) -> A).
-spec(ensure_ok/2 :: ('ok' | {'error', any()}, atom()) -> 'ok').
--spec(localnode/1 :: (atom()) -> node()).
+-spec(localnode/1 :: (atom()) -> erlang_node()).
-spec(tcp_name/3 :: (atom(), ip_address(), ip_port()) -> atom()).
-spec(intersperse/2 :: (A, [A]) -> [A]).
-spec(upmap/2 :: (fun ((A) -> B), [A]) -> [B]).
diff --git a/src/rabbit_mnesia.erl b/src/rabbit_mnesia.erl
index 9b67135d..8d34d285 100644
--- a/src/rabbit_mnesia.erl
+++ b/src/rabbit_mnesia.erl
@@ -40,11 +40,11 @@
-ifdef(use_specs).
--spec(status/0 :: () -> [{'nodes' | 'running_nodes', [node()]}]).
+-spec(status/0 :: () -> [{'nodes' | 'running_nodes', [erlang_node()]}]).
-spec(ensure_mnesia_dir/0 :: () -> 'ok').
-spec(init/0 :: () -> 'ok').
-spec(is_db_empty/0 :: () -> bool()).
--spec(cluster/1 :: ([node()]) -> 'ok').
+-spec(cluster/1 :: ([erlang_node()]) -> 'ok').
-spec(reset/0 :: () -> 'ok').
-spec(force_reset/0 :: () -> 'ok').
-spec(create_tables/0 :: () -> 'ok').
diff --git a/src/rabbit_networking.erl b/src/rabbit_networking.erl
index 79c927cb..a91602ab 100644
--- a/src/rabbit_networking.erl
+++ b/src/rabbit_networking.erl
@@ -45,8 +45,8 @@
-spec(start_tcp_listener/2 :: (host(), ip_port()) -> 'ok').
-spec(stop_tcp_listener/2 :: (host(), ip_port()) -> 'ok').
-spec(active_listeners/0 :: () -> [listener()]).
--spec(node_listeners/1 :: (node()) -> [listener()]).
--spec(on_node_down/1 :: (node()) -> 'ok').
+-spec(node_listeners/1 :: (erlang_node()) -> [listener()]).
+-spec(on_node_down/1 :: (erlang_node()) -> 'ok').
-spec(check_tcp_listener_address/3 :: (atom(), host(), ip_port()) ->
{ip_address(), atom()}).
diff --git a/src/rabbit_sasl_report_file_h.erl b/src/rabbit_sasl_report_file_h.erl
index 3374d63d..10e2ee6e 100644
--- a/src/rabbit_sasl_report_file_h.erl
+++ b/src/rabbit_sasl_report_file_h.erl
@@ -71,8 +71,9 @@ handle_call(Event, State) ->
terminate(Reason, State) ->
sasl_report_file_h:terminate(Reason, State).
-code_change(OldVsn, State, Extra) ->
- sasl_report_file_h:code_change(OldVsn, State, Extra).
+code_change(_OldVsn, State, _Extra) ->
+ %% There is no sasl_report_file_h:code_change/3
+ {ok, State}.
%%----------------------------------------------------------------------
diff --git a/src/rabbit_tests.erl b/src/rabbit_tests.erl
index fff02d73..db78bbcc 100644
--- a/src/rabbit_tests.erl
+++ b/src/rabbit_tests.erl
@@ -465,7 +465,7 @@ test_user_management() ->
control_action(Command, Args) -> control_action(Command, node(), Args).
control_action(Command, Node, Args) ->
- case catch rabbit_control:action(Command, Node, Args) of
+ case catch rabbit_control:action(Command, Node, Args, fun io:format/2) of
ok ->
io:format("done.~n"),
ok;