summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Jones <pauljones23@gmail.com>2009-07-22 15:48:50 +0100
committerPaul Jones <pauljones23@gmail.com>2009-07-22 15:48:50 +0100
commit31e0c44c728751a00195785979e24898a238ed35 (patch)
treeb6e8d889fc1126e665e8c7cc144a79b1b51dfb68
parente7d9f77b67da410faefce10edbfb48458be6c26e (diff)
downloadrabbitmq-server-31e0c44c728751a00195785979e24898a238ed35.tar.gz
Added a rabbit_plugin_activator to generate a .boot file for Rabbit; changed startup script to use this file if available
-rw-r--r--.hgignore3
-rwxr-xr-xscripts/activate-plugins46
-rwxr-xr-xscripts/rabbitmq-server8
-rw-r--r--src/rabbit_plugin_activator.erl156
4 files changed, 212 insertions, 1 deletions
diff --git a/.hgignore b/.hgignore
index b759a9d9..7925f07a 100644
--- a/.hgignore
+++ b/.hgignore
@@ -11,6 +11,9 @@ syntax: regexp
^rabbit.plt$
^ebin/rabbit.app$
^ebin/rabbit.rel$
+^ebin/rabbit.boot$
+^ebin/rabbit.script$
+^plugins/
^packaging/RPMS/Fedora/(BUILD|RPMS|SOURCES|SPECS|SRPMS)$
^packaging/debs/Debian/rabbitmq-server_.*\.(dsc|(diff|tar)\.gz|deb|changes)$
diff --git a/scripts/activate-plugins b/scripts/activate-plugins
new file mode 100755
index 00000000..daa5e99f
--- /dev/null
+++ b/scripts/activate-plugins
@@ -0,0 +1,46 @@
+#!/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
+
+[ "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 "`dirname $0`/../ebin" \
+ -rabbit plugins_dir "\"$RABBITMQ_PLUGINS_DIR\"" \
+ -rabbit plugins_expand_dir "\"$RABBITMQ_PLUGINS_EXPAND_DIR\"" \
+ -rabbit rabbit_ebin "\"`dirname $0`/../ebin\"" \
+ -noinput \
+ -hidden \
+ -s rabbit_plugin_activator \
+ -extra "$@"
diff --git a/scripts/rabbitmq-server b/scripts/rabbitmq-server
index 8502d60a..40d66411 100755
--- a/scripts/rabbitmq-server
+++ b/scripts/rabbitmq-server
@@ -75,6 +75,12 @@ fi
RABBITMQ_START_RABBIT=
[ "x" = "x$RABBITMQ_NODE_ONLY" ] && RABBITMQ_START_RABBIT='-noinput -s rabbit'
+if [ -f "`dirname $0`/../ebin/rabbit.boot" ]; then
+ RABBITMQ_BOOT_FILE="`dirname $0`/../ebin/rabbit"
+else
+ RABBITMQ_BOOT_FILE=start_sasl
+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.
@@ -84,7 +90,7 @@ exec erl \
-pa "`dirname $0`/../ebin" \
${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/src/rabbit_plugin_activator.erl b/src/rabbit_plugin_activator.erl
new file mode 100644
index 00000000..7a34e967
--- /dev/null
+++ b/src/rabbit_plugin_activator.erl
@@ -0,0 +1,156 @@
+%% 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, [kernel, stdlib, sasl, mnesia, os_mon, rabbit]).
+
+%%----------------------------------------------------------------------------
+
+start() ->
+ % Ensure Rabbit is loaded so we can access it's environment
+ application:load(rabbit),
+
+ % Determine our various directories
+ PluginDir = get_env_or_default(plugins_dir, ?DefaultPluginDir),
+ UnpackedPluginDir = get_env_or_default(plugins_expand_dir, ?DefaultUnpackedPluginDir),
+ RabbitEBin = get_env_or_default(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 = sets:to_list(fold_dependencies(undefined, RequiredApps)),
+
+ 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
+ io:format("Generated rabbit.rel: ~p.~n", [RDesc]),
+ 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_or_default(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.
+
+unpack_ez_plugins(PluginSrcDir, 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).
+
+fold_dependencies(App, []) ->
+ sets:from_list([App]);
+fold_dependencies(App, AppList) ->
+ lists:foldl(fun(ChildApp, AccSet) ->
+ case application:load(ChildApp) of
+ ok -> ok;
+ {error, {already_loaded, _}} -> ok;
+ X -> io:format("Failed to load ~p: ~p~n", [ChildApp, X])
+ end,
+ {ok, Required} = application:get_key(ChildApp, applications),
+ DepSet = fold_dependencies(ChildApp, Required),
+ sets:union(AccSet, DepSet)
+ end,
+ case App of
+ undefined -> sets:new();
+ _ -> sets:from_list([App])
+ end,
+ AppList). \ No newline at end of file