summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Hood <0x6e6562@gmail.com>2009-08-03 15:04:57 +0100
committerBen Hood <0x6e6562@gmail.com>2009-08-03 15:04:57 +0100
commit609d920378d573c2870fe67bf283b7dc1df44af6 (patch)
tree20ffa098e0c3a2dd05396498d89583b416c8dea6
parenta38fe72dd70d133e0a5a86708224893227d7a26a (diff)
parent0c804d7a68581d46092bb799d4382e01b25788f5 (diff)
downloadrabbitmq-server-609d920378d573c2870fe67bf283b7dc1df44af6.tar.gz
Merged bug20539 into default
-rw-r--r--.hgignore5
-rw-r--r--ebin/rabbit.rel7
-rw-r--r--packaging/RPMS/Fedora/rabbitmq-server.spec6
-rwxr-xr-xscripts/activate-plugins47
-rw-r--r--scripts/activate-plugins.bat53
-rwxr-xr-xscripts/rabbitmq-server13
-rwxr-xr-xscripts/rabbitmq-server.bat13
-rw-r--r--src/rabbit_plugin_activator.erl198
8 files changed, 326 insertions, 16 deletions
diff --git a/.hgignore b/.hgignore
index 35607765..3323e2fc 100644
--- a/.hgignore
+++ b/.hgignore
@@ -10,6 +10,11 @@ syntax: regexp
^src/rabbit_framing.erl$
^rabbit.plt$
^ebin/rabbit.app$
+^ebin/rabbit.rel$
+^ebin/rabbit.boot$
+^ebin/rabbit.script$
+^plugins/
+^priv/plugins/
^packaging/RPMS/Fedora/(BUILD|RPMS|SOURCES|SPECS|SRPMS)$
^packaging/debs/Debian/rabbitmq-server_.*\.(dsc|(diff|tar)\.gz|deb|changes)$
diff --git a/ebin/rabbit.rel b/ebin/rabbit.rel
deleted file mode 100644
index c2d2067b..00000000
--- a/ebin/rabbit.rel
+++ /dev/null
@@ -1,7 +0,0 @@
-{release, {"rabbit", "1.1.0-alpha"}, {erts, "1.14.2"},
- [{rabbit, "1.1.0-alpha"},
- {mnesia, "4.3.4"},
- {os_mon, "2.1.2"},
- {sasl, "2.1.5"},
- {stdlib, "1.14.4"},
- {kernel, "2.11.4"}]}.
diff --git a/packaging/RPMS/Fedora/rabbitmq-server.spec b/packaging/RPMS/Fedora/rabbitmq-server.spec
index 9e7c4bfb..eb953b81 100644
--- a/packaging/RPMS/Fedora/rabbitmq-server.spec
+++ b/packaging/RPMS/Fedora/rabbitmq-server.spec
@@ -34,11 +34,7 @@ scalable implementation of an AMQP broker.
%build
cp %{S:2} %{_rabbit_wrapper}
sed -i 's|/usr/lib/|%{_libdir}/|' %{_rabbit_wrapper}
-
-# The rabbitmq build needs escript, which is missing from /usr/bin in
-# some versions of the erlang RPM. See
-# <https://bugzilla.redhat.com/show_bug.cgi?id=481302>
-PATH=%{_libdir}/erlang/bin:$PATH make %{?_smp_mflags}
+make %{?_smp_mflags}
%install
rm -rf %{buildroot}
diff --git a/scripts/activate-plugins b/scripts/activate-plugins
new file mode 100755
index 00000000..52f7ddbe
--- /dev/null
+++ b/scripts/activate-plugins
@@ -0,0 +1,47 @@
+#!/bin/sh
+## 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 Developers of the Original Code are LShift Ltd,
+## Cohesive Financial Technologies LLC, and Rabbit Technologies Ltd.
+##
+## Portions created before 22-Nov-2008 00:00:00 GMT by LShift Ltd,
+## Cohesive Financial Technologies LLC, or Rabbit Technologies Ltd
+## are Copyright (C) 2007-2008 LShift Ltd, Cohesive Financial
+## Technologies LLC, and Rabbit Technologies Ltd.
+##
+## Portions created by LShift Ltd are Copyright (C) 2007-2009 LShift
+## Ltd. Portions created by Cohesive Financial Technologies LLC are
+## Copyright (C) 2007-2009 Cohesive Financial Technologies
+## LLC. Portions created by Rabbit Technologies Ltd are Copyright
+## (C) 2007-2009 Rabbit Technologies Ltd.
+##
+## All Rights Reserved.
+##
+## Contributor(s): ______________________________________.
+##
+
+[ -f /etc/rabbitmq/rabbitmq.conf ] && . /etc/rabbitmq/rabbitmq.conf
+
+RABBITMQ_EBIN=`dirname $0`/../ebin
+[ "x" = "x$RABBITMQ_PLUGINS_DIR" ] && RABBITMQ_PLUGINS_DIR="`dirname $0`/../plugins"
+[ "x" = "x$RABBITMQ_PLUGINS_EXPAND_DIR" ] && RABBITMQ_PLUGINS_EXPAND_DIR="`dirname $0`/../priv/plugins"
+
+exec erl \
+ -pa "$RABBITMQ_EBIN" \
+ -rabbit plugins_dir "\"$RABBITMQ_PLUGINS_DIR\"" \
+ -rabbit plugins_expand_dir "\"$RABBITMQ_PLUGINS_EXPAND_DIR\"" \
+ -rabbit rabbit_ebin "\"$RABBITMQ_EBIN\"" \
+ -noinput \
+ -hidden \
+ -s rabbit_plugin_activator \
+ -extra "$@"
diff --git a/scripts/activate-plugins.bat b/scripts/activate-plugins.bat
new file mode 100644
index 00000000..8bef4ad2
--- /dev/null
+++ b/scripts/activate-plugins.bat
@@ -0,0 +1,53 @@
+@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 before 22-Nov-2008 00:00:00 GMT by LShift Ltd,
+REM Cohesive Financial Technologies LLC, or Rabbit Technologies Ltd
+REM are Copyright (C) 2007-2008 LShift Ltd, Cohesive Financial
+REM Technologies LLC, and Rabbit Technologies Ltd.
+REM
+REM Portions created by LShift Ltd are Copyright (C) 2007-2009 LShift
+REM Ltd. Portions created by Cohesive Financial Technologies LLC are
+REM Copyright (C) 2007-2009 Cohesive Financial Technologies
+REM LLC. Portions created by Rabbit Technologies Ltd are Copyright
+REM (C) 2007-2009 Rabbit Technologies Ltd.
+REM
+REM All Rights Reserved.
+REM
+REM Contributor(s): ______________________________________.
+REM
+
+if "%ERLANG_HOME%"=="" (
+ set ERLANG_HOME=%~dp0%..\..\..
+)
+
+if not exist "%ERLANG_HOME%\bin\erl.exe" (
+ echo.
+ echo ******************************
+ echo ERLANG_HOME not set correctly.
+ echo ******************************
+ echo.
+ echo Please either set ERLANG_HOME to point to your Erlang installation or place the
+ echo RabbitMQ server distribution in the Erlang lib folder.
+ echo.
+ exit /B
+)
+
+set RABBITMQ_PLUGINS_DIR="%~dp0..\plugins"
+set RABBITMQ_PLUGINS_EXPAND_DIR="%~dp0..\priv\plugins"
+set RABBITMQ_EBIN_DIR="%~dp0..\ebin"
+
+"%ERLANG_HOME%\bin\erl.exe" -pa "%~dp0..\ebin" -noinput -hidden -s rabbit_plugin_activator -rabbit plugins_dir \"%RABBITMQ_PLUGINS_DIR:\=/%\" -rabbit plugins_expand_dir \"%RABBITMQ_PLUGINS_EXPAND_DIR:\=/%\" -rabbit rabbit_ebin \"%RABBITMQ_EBIN_DIR:\=/%\" -extra %*
diff --git a/scripts/rabbitmq-server b/scripts/rabbitmq-server
index 8502d60a..40e32d3d 100755
--- a/scripts/rabbitmq-server
+++ b/scripts/rabbitmq-server
@@ -75,16 +75,25 @@ fi
RABBITMQ_START_RABBIT=
[ "x" = "x$RABBITMQ_NODE_ONLY" ] && RABBITMQ_START_RABBIT='-noinput -s rabbit'
+RABBITMQ_EBIN_ROOT="`dirname $0`/../ebin"
+if [ -f "${RABBITMQ_EBIN_ROOT}/rabbit.boot" ]; then
+ RABBITMQ_BOOT_FILE="${RABBITMQ_EBIN_ROOT}/rabbit"
+ RABBITMQ_EBIN_PATH=""
+else
+ RABBITMQ_BOOT_FILE=start_sasl
+ RABBITMQ_EBIN_PATH="-pa ${RABBITMQ_EBIN_ROOT}"
+fi
+
# we need to turn off path expansion because some of the vars, notably
# RABBITMQ_SERVER_ERL_ARGS, contain terms that look like globs and
# there is no other way of preventing their expansion.
set -f
exec erl \
- -pa "`dirname $0`/../ebin" \
+ ${RABBITMQ_EBIN_PATH} \
${RABBITMQ_START_RABBIT} \
-sname ${RABBITMQ_NODENAME} \
- -boot start_sasl \
+ -boot ${RABBITMQ_BOOT_FILE} \
+W w \
${RABBITMQ_SERVER_ERL_ARGS} \
-rabbit tcp_listeners '[{"'${RABBITMQ_NODE_IP_ADDRESS}'", '${RABBITMQ_NODE_PORT}'}]' \
diff --git a/scripts/rabbitmq-server.bat b/scripts/rabbitmq-server.bat
index 9915727b..b1932a79 100755
--- a/scripts/rabbitmq-server.bat
+++ b/scripts/rabbitmq-server.bat
@@ -104,11 +104,20 @@ set CLUSTER_CONFIG=-rabbit cluster_config \""%RABBITMQ_CLUSTER_CONFIG_FILE:\=/%"
if "%RABBITMQ_MNESIA_DIR%"=="" (
set RABBITMQ_MNESIA_DIR=%RABBITMQ_MNESIA_BASE%/%RABBITMQ_NODENAME%-mnesia
)
+set RABBITMQ_EBIN_ROOT=%~dp0..\ebin
+if exist "%RABBITMQ_EBIN_ROOT%\rabbit.boot" (
+ echo Using Custom Boot File "%RABBITMQ_EBIN_ROOT%\rabbit.boot"
+ set RABBITMQ_BOOT_FILE="%RABBITMQ_EBIN_ROOT%\rabbit"
+ set RABBITMQ_EBIN_PATH=
+) else (
+ set RABBITMQ_BOOT_FILE=start_sasl
+ set RABBITMQ_EBIN_PATH=-pa "%RABBITMQ_EBIN_ROOT%"
+)
"%ERLANG_HOME%\bin\erl.exe" ^
--pa "%~dp0..\ebin" ^
+%RABBITMQ_EBIN_PATH% ^
-noinput ^
--boot start_sasl ^
+-boot %RABBITMQ_BOOT_FILE% ^
-sname %RABBITMQ_NODENAME% ^
-s rabbit ^
+W w ^
diff --git a/src/rabbit_plugin_activator.erl b/src/rabbit_plugin_activator.erl
new file mode 100644
index 00000000..71278bfb
--- /dev/null
+++ b/src/rabbit_plugin_activator.erl
@@ -0,0 +1,198 @@
+%% 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 Developers of the Original Code are LShift Ltd,
+%% Cohesive Financial Technologies LLC, and Rabbit Technologies Ltd.
+%%
+%% Portions created before 22-Nov-2008 00:00:00 GMT by LShift Ltd,
+%% Cohesive Financial Technologies LLC, or Rabbit Technologies Ltd
+%% are Copyright (C) 2007-2008 LShift Ltd, Cohesive Financial
+%% Technologies LLC, and Rabbit Technologies Ltd.
+%%
+%% Portions created by LShift Ltd are Copyright (C) 2007-2009 LShift
+%% Ltd. Portions created by Cohesive Financial Technologies LLC are
+%% Copyright (C) 2007-2009 Cohesive Financial Technologies
+%% LLC. Portions created by Rabbit Technologies Ltd are Copyright
+%% (C) 2007-2009 Rabbit Technologies Ltd.
+%%
+%% All Rights Reserved.
+%%
+%% Contributor(s): ______________________________________.
+%%
+
+-module(rabbit_plugin_activator).
+
+-export([start/0, stop/0]).
+
+-define(DefaultPluginDir, "plugins").
+-define(DefaultUnpackedPluginDir, "priv/plugins").
+-define(DefaultRabbitEBin, "ebin").
+-define(BaseApps, [rabbit]).
+
+%%----------------------------------------------------------------------------
+
+start() ->
+ %% Ensure Rabbit is loaded so we can access it's environment
+ application:load(rabbit),
+
+ %% Determine our various directories
+ PluginDir = get_env(plugins_dir, ?DefaultPluginDir),
+ UnpackedPluginDir = get_env(plugins_expand_dir, ?DefaultUnpackedPluginDir),
+ RabbitEBin = get_env(rabbit_ebin, ?DefaultRabbitEBin),
+
+ %% Unpack any .ez plugins
+ unpack_ez_plugins(PluginDir, UnpackedPluginDir),
+
+ %% Build a list of required apps based on the fixed set, and any plugins
+ RequiredApps = ?BaseApps ++
+ find_plugins(PluginDir) ++
+ find_plugins(UnpackedPluginDir),
+
+ %% Build the entire set of dependencies - this will load the
+ %% applications along the way
+ AllApps = case catch sets:to_list(expand_dependencies(RequiredApps)) of
+ {unknown_app, {App, Err}} ->
+ io:format("ERROR: Failed to load application " ++
+ "~s: ~p~n", [App, Err]),
+ halt(1);
+ AppList ->
+ AppList
+ end,
+ AppVersions = [determine_version(App) || App <- AllApps],
+ {value, {rabbit, RabbitVersion}} = lists:keysearch(rabbit, 1, AppVersions),
+
+ %% Build the overall release descriptor
+ RDesc = {release,
+ {"rabbit", RabbitVersion},
+ {erts, erlang:system_info(version)},
+ AppVersions},
+
+ %% Write it out to ebin/rabbit.rel
+ file:write_file(RabbitEBin ++ "/rabbit.rel",
+ io_lib:format("~p.~n", [RDesc])),
+
+ %% Compile the script
+ case systools:make_script(RabbitEBin ++ "/rabbit", [local, silent]) of
+ {ok, Module, Warnings} ->
+ %% This gets lots of spurious no-source warnings when we
+ %% have .ez files, so we want to supress them to prevent
+ %% hiding real issues.
+ WarningStr = Module:format_warning(
+ [W || W <- Warnings,
+ case W of
+ {warning, {source_not_found, _}} -> false;
+ _ -> true
+ end]),
+ case length(WarningStr) of
+ 0 -> ok;
+ _ -> io:format("~s", [WarningStr])
+ end,
+ ok;
+ {error, Module, Error} ->
+ io:format("Boot file generation failed: ~s~n",
+ [Module:format_error(Error)]),
+ halt(1)
+ end,
+ halt(),
+ ok.
+
+stop() ->
+ ok.
+
+get_env(Key, Default) ->
+ case application:get_env(rabbit, Key) of
+ {ok, V} -> V;
+ _ -> Default
+ end.
+
+determine_version(App) ->
+ application:load(App),
+ {ok, Vsn} = application:get_key(App, vsn),
+ {App, Vsn}.
+
+assert_dir(Dir) ->
+ case filelib:is_dir(Dir) of
+ true -> ok;
+ false ->
+ ok = filelib:ensure_dir(Dir),
+ ok = file:make_dir(Dir)
+ end.
+delete_dir(Dir) ->
+ case filelib:is_dir(Dir) of
+ true ->
+ case file:list_dir(Dir) of
+ {ok, Files} ->
+ [case Dir ++ "/" ++ F of
+ Fn ->
+ case filelib:is_dir(Fn) and not(is_symlink(Fn)) of
+ true -> delete_dir(Fn);
+ false -> file:delete(Fn)
+ end
+ end || F <- Files]
+ end,
+ ok = file:del_dir(Dir);
+ false ->
+ ok
+ end.
+is_symlink(Name) ->
+ case file:read_link(Name) of
+ {ok, _} -> true;
+ _ -> false
+ end.
+
+unpack_ez_plugins(PluginSrcDir, PluginDestDir) ->
+ %% Eliminate the contents of the destination directory
+ delete_dir(PluginDestDir),
+
+ assert_dir(PluginDestDir),
+ [unpack_ez_plugin(PluginName, PluginDestDir) ||
+ PluginName <- filelib:wildcard(PluginSrcDir ++ "/*.ez")].
+
+unpack_ez_plugin(PluginFn, PluginDestDir) ->
+ zip:unzip(PluginFn, [{cwd, PluginDestDir}]),
+ ok.
+
+find_plugins(PluginDir) ->
+ [prepare_dir_plugin(PluginName) ||
+ PluginName <- filelib:wildcard(PluginDir ++ "/*/ebin/*.app")].
+
+prepare_dir_plugin(PluginAppDescFn) ->
+ %% Add the plugin ebin directory to the load path
+ PluginEBinDirN = filename:dirname(PluginAppDescFn),
+ code:add_path(PluginEBinDirN),
+
+ %% We want the second-last token
+ NameTokens = string:tokens(PluginAppDescFn,"/."),
+ PluginNameString = lists:nth(length(NameTokens) - 1, NameTokens),
+ list_to_atom(PluginNameString).
+
+expand_dependencies(Pending) ->
+ expand_dependencies(sets:new(), Pending).
+expand_dependencies(Current, []) ->
+ Current;
+expand_dependencies(Current, [Next|Rest]) ->
+ case sets:is_element(Next, Current) of
+ true ->
+ expand_dependencies(Current, Rest);
+ false ->
+ case application:load(Next) of
+ ok ->
+ ok;
+ {error, {already_loaded, _}} ->
+ ok;
+ X ->
+ throw({unknown_app, {Next, X}})
+ end,
+ {ok, Required} = application:get_key(Next, applications),
+ Unique = [A || A <- Required, not(sets:is_element(A, Current))],
+ expand_dependencies(sets:add_element(Next, Current), Rest ++ Unique)
+ end.