diff options
author | Alexandru Scvortov <alexandru@rabbitmq.com> | 2011-09-22 16:18:32 +0100 |
---|---|---|
committer | Alexandru Scvortov <alexandru@rabbitmq.com> | 2011-09-22 16:18:32 +0100 |
commit | a5cc5ff81ca47874418e2995029a3933c84e4ce2 (patch) | |
tree | b7339a41158ac3973272ecb0399472d3ab23e725 | |
parent | 9a1141dd17fafb6ea5071968dbb4509ab1150e0f (diff) | |
download | rabbitmq-server-a5cc5ff81ca47874418e2995029a3933c84e4ce2.tar.gz |
don't use the plugins directory
-rw-r--r-- | include/rabbit.hrl | 6 | ||||
-rwxr-xr-x | scripts/rabbitmq-plugins | 4 | ||||
-rwxr-xr-x | scripts/rabbitmq-plugins.bat | 7 | ||||
-rwxr-xr-x | scripts/rabbitmq-server | 5 | ||||
-rwxr-xr-x | scripts/rabbitmq-server.bat | 9 | ||||
-rwxr-xr-x | scripts/rabbitmq-service.bat | 9 | ||||
-rw-r--r-- | src/rabbit_plugins.erl | 171 | ||||
-rw-r--r-- | src/rabbit_prelaunch.erl | 20 |
8 files changed, 98 insertions, 133 deletions
diff --git a/include/rabbit.hrl b/include/rabbit.hrl index ac6399c6..9c79fbed 100644 --- a/include/rabbit.hrl +++ b/include/rabbit.hrl @@ -75,6 +75,12 @@ -record(message_properties, {expiry, needs_confirming = false}). +-record(plugin, {name, %% atom() + version, %% string() + description, %% string() + dependencies, %% [{atom(), string()}] + location}). %% string() + %%---------------------------------------------------------------------------- -define(COPYRIGHT_MESSAGE, "Copyright (C) 2007-2011 VMware, Inc."). diff --git a/scripts/rabbitmq-plugins b/scripts/rabbitmq-plugins index ca2d3caa..b3137a32 100755 --- a/scripts/rabbitmq-plugins +++ b/scripts/rabbitmq-plugins @@ -17,7 +17,7 @@ . `dirname $0`/rabbitmq-env -[ "x" = "x$RABBITMQ_PLUGINS_DIR" ] && RABBITMQ_PLUGINS_DIR="${RABBITMQ_HOME}/plugins" +[ "x" = "x$RABBITMQ_ENABLED_PLUGINS_FILE" ] && RABBITMQ_ENABLED_PLUGINS_FILE=/etc/rabbitmq/enabled_plugins [ "x" = "x$RABBITMQ_PLUGINS_DIST_DIR" ] && RABBITMQ_PLUGINS_DIST_DIR="${RABBITMQ_HOME}/plugins-dist" @@ -27,6 +27,6 @@ exec erl \ -hidden \ -sname rabbitmq-plugins$$ \ -s rabbit_plugins \ - -plugins_dir "$RABBITMQ_PLUGINS_DIR" \ + -enabled_plugins_file "$RABBITMQ_ENABLED_PLUGINS_FILE" \ -plugins_dist_dir "$RABBITMQ_PLUGINS_DIST_DIR" \ -extra "$@" diff --git a/scripts/rabbitmq-plugins.bat b/scripts/rabbitmq-plugins.bat index 8400d7e9..8455a7dc 100755 --- a/scripts/rabbitmq-plugins.bat +++ b/scripts/rabbitmq-plugins.bat @@ -35,10 +35,13 @@ if not exist "!ERLANG_HOME!\bin\erl.exe" ( exit /B
)
-set RABBITMQ_PLUGINS_DIR=!TDP0!..\plugins
+if "!RABBITMQ_ENABLED_PLUGINS_FILE!"=="" (
+ set RABBITMQ_ENABLED_PLUGINS_FILE=!RABBITMQ_BASE!\enabled_plugins
+)
+
set RABBITMQ_PLUGINS_DIST_DIR=!TDP0!..\plugins-dist
-"!ERLANG_HOME!\bin\erl.exe" -pa "!TDP0!..\ebin" -noinput -hidden -sname rabbitmq-plugins!RANDOM! -s rabbit_plugins -plugins_dir "!RABBITMQ_PLUGINS_DIR:\=/!" -plugins_dist_dir "!RABBITMQ_PLUGINS_DIST_DIR:\=/!" -extra !STAR!
+"!ERLANG_HOME!\bin\erl.exe" -pa "!TDP0!..\ebin" -noinput -hidden -sname rabbitmq-plugins!RANDOM! -s rabbit_plugins -enabled_plugins_file "!RABBITMQ_ENABLED_PLUGINS_FILE!" -plugins_dist_dir "!RABBITMQ_PLUGINS_DIST_DIR:\=/!" -extra !STAR!
endlocal
endlocal
diff --git a/scripts/rabbitmq-server b/scripts/rabbitmq-server index 7176d801..302eb92f 100755 --- a/scripts/rabbitmq-server +++ b/scripts/rabbitmq-server @@ -52,7 +52,8 @@ fi [ "x" = "x$RABBITMQ_PLUGINS_EXPAND_DIR" ] && RABBITMQ_PLUGINS_EXPAND_DIR=${PLUGINS_EXPAND_DIR} [ "x" = "x$RABBITMQ_PLUGINS_EXPAND_DIR" ] && RABBITMQ_PLUGINS_EXPAND_DIR=${RABBITMQ_MNESIA_BASE}/${RABBITMQ_NODENAME}-plugins-expand -[ "x" = "x$RABBITMQ_PLUGINS_DIR" ] && RABBITMQ_PLUGINS_DIR="${RABBITMQ_HOME}/plugins" +[ "x" = "x$RABBITMQ_ENABLED_PLUGINS_FILE" ] && RABBITMQ_ENABLED_PLUGINS_FILE=/etc/rabbitmq/enabled_plugins +[ "x" = "x$RABBITMQ_PLUGINS_DIST_DIR" ] && RABBITMQ_PLUGINS_DIST_DIR="${RABBITMQ_HOME}/plugins-dist" ## Log rotation [ "x" = "x$RABBITMQ_LOGS" ] && RABBITMQ_LOGS=${LOGS} @@ -79,7 +80,7 @@ if [ "x" = "x$RABBITMQ_NODE_ONLY" ]; then -hidden \ -s rabbit_prelaunch \ -sname rabbitmqprelaunch$$ \ - -extra "$RABBITMQ_PLUGINS_DIR" "${RABBITMQ_PLUGINS_EXPAND_DIR}" "${RABBITMQ_NODENAME}" + -extra "$RABBITMQ_ENABLED_PLUGINS_FILE" "$RABBITMQ_PLUGINS_DIST_DIR" "${RABBITMQ_PLUGINS_EXPAND_DIR}" "${RABBITMQ_NODENAME}" then RABBITMQ_BOOT_FILE="${RABBITMQ_PLUGINS_EXPAND_DIR}/rabbit" RABBITMQ_EBIN_PATH="" diff --git a/scripts/rabbitmq-server.bat b/scripts/rabbitmq-server.bat index 84d24c45..df380138 100755 --- a/scripts/rabbitmq-server.bat +++ b/scripts/rabbitmq-server.bat @@ -93,7 +93,11 @@ if "!RABBITMQ_PLUGINS_EXPAND_DIR!"=="" ( set RABBITMQ_PLUGINS_EXPAND_DIR=!RABBITMQ_MNESIA_BASE!/!RABBITMQ_NODENAME!-plugins-expand
)
-set RABBITMQ_PLUGINS_DIR=!TDP0!..\plugins
+if "!RABBITMQ_ENABLED_PLUGINS_FILE!"=="" (
+ set RABBITMQ_ENABLED_PLUGINS_FILE=!RABBITMQ_BASE!\enabled_plugins
+)
+
+set RABBITMQ_PLUGINS_DIST_DIR=!TDP0!..\plugins-dist
set RABBITMQ_EBIN_ROOT=!TDP0!..\ebin
"!ERLANG_HOME!\bin\erl.exe" ^
@@ -101,7 +105,8 @@ set RABBITMQ_EBIN_ROOT=!TDP0!..\ebin -noinput -hidden ^
-s rabbit_prelaunch ^
-sname rabbitmqprelaunch!RANDOM! ^
--extra "!RABBITMQ_PLUGINS_DIR:\=/!" ^
+-extra "!RABBITMQ_ENABLED_PLUGINS_FILE!" ^
+ "!RABBITMQ_PLUGINS_DIST_DIR:\=/!" ^
"!RABBITMQ_PLUGINS_EXPAND_DIR:\=/!" ^
"!RABBITMQ_NODENAME!"
diff --git a/scripts/rabbitmq-service.bat b/scripts/rabbitmq-service.bat index 60697d0b..295a7d70 100755 --- a/scripts/rabbitmq-service.bat +++ b/scripts/rabbitmq-service.bat @@ -162,14 +162,19 @@ if errorlevel 1 ( echo !RABBITMQ_SERVICENAME! service is already present - only updating service parameters
)
-set RABBITMQ_PLUGINS_DIR=!TDP0!..\plugins
+if "!RABBITMQ_ENABLED_PLUGINS_FILE!"=="" (
+ set RABBITMQ_ENABLED_PLUGINS_FILE=!RABBITMQ_BASE!\enabled_plugins
+)
+
+set RABBITMQ_PLUGINS_DIST_DIR=!TDP0!..\plugins-dist
set RABBITMQ_EBIN_ROOT=!TDP0!..\ebin
"!ERLANG_HOME!\bin\erl.exe" ^
-pa "!RABBITMQ_EBIN_ROOT!" ^
-noinput -hidden ^
-s rabbit_prelaunch ^
--extra "!RABBITMQ_PLUGINS_DIR:\=/!" ^
+-extra "!RABBITMQ_ENABLED_PLUGINS_FILE!" ^
+ "!RABBITMQ_PLUGINS_DIST_DIR:\=/!" ^
"!RABBITMQ_PLUGINS_EXPAND_DIR:\=/!" ^
""
diff --git a/src/rabbit_plugins.erl b/src/rabbit_plugins.erl index 570791d9..69523c0c 100644 --- a/src/rabbit_plugins.erl +++ b/src/rabbit_plugins.erl @@ -17,16 +17,11 @@ -module(rabbit_plugins). -include("rabbit.hrl"). --export([start/0, stop/0]). +-export([start/0, stop/0, find_plugins/1, read_enabled_plugins/1, + lookup_plugins/2, calculate_required_plugins/2]). -define(COMPACT_OPT, "-c"). --record(plugin, {name, %% atom() - version, %% string() - description, %% string() - dependencies, %% [{atom(), string()}] - location}). %% string() - %%---------------------------------------------------------------------------- -ifdef(use_specs). @@ -39,8 +34,10 @@ %%---------------------------------------------------------------------------- start() -> - {ok, [[PluginsDir|_]|_]} = init:get_argument(plugins_dir), + {ok, [[EnabledPluginsFile|_]|_]} = init:get_argument(enabled_plugins_file), + put(enabled_plugins_file, EnabledPluginsFile), {ok, [[PluginsDistDir|_]|_]} = init:get_argument(plugins_dist_dir), + put(plugins_dist_dir, PluginsDistDir), {[Command0 | Args], Opts} = case rabbit_misc:get_options([{flag, ?COMPACT_OPT}], init:get_plain_arguments()) of @@ -49,7 +46,7 @@ start() -> end, Command = list_to_atom(Command0), - case catch action(Command, Args, Opts, PluginsDir, PluginsDistDir) of + case catch action(Command, Args, Opts) of ok -> rabbit_misc:quit(0); {'EXIT', {function_clause, [{?MODULE, action, _} | _]}} -> @@ -76,16 +73,14 @@ usage() -> %%---------------------------------------------------------------------------- -action(list, [], Opts, PluginsDir, PluginsDistDir) -> - action(list, [".*"], Opts, PluginsDir, PluginsDistDir); -action(list, [Pattern], Opts, PluginsDir, PluginsDistDir) -> - format_plugins(PluginsDir, PluginsDistDir, Pattern, - proplists:get_bool(?COMPACT_OPT, Opts)); +action(list, [], Opts) -> + action(list, [".*"], Opts); +action(list, [Pat], Opts) -> + format_plugins(Pat, proplists:get_bool(?COMPACT_OPT, Opts)); -action(enable, ToEnable0, _Opts, PluginsDir, PluginsDistDir) -> - AllPlugins = find_plugins(PluginsDistDir), - Enabled = read_enabled_plugins(PluginsDir), - EnabledPlugins = lookup_plugins(Enabled, AllPlugins), +action(enable, ToEnable0, _Opts) -> + AllPlugins = find_plugins(), + EnabledPlugins = lookup_plugins(read_enabled_plugins(), AllPlugins), ToEnable = [list_to_atom(Name) || Name <- ToEnable0], ToEnablePlugins = lookup_plugins(ToEnable, AllPlugins), Missing = ToEnable -- plugin_names(ToEnablePlugins), @@ -95,59 +90,36 @@ action(enable, ToEnable0, _Opts, PluginsDir, PluginsDistDir) -> [Missing]) end, NewEnabledPlugins = merge_plugin_lists(EnabledPlugins, ToEnablePlugins), - EnableOrder = calculate_required_plugins(plugin_names(NewEnabledPlugins), - AllPlugins), - EnableOrder1 = EnableOrder -- plugin_names(find_plugins(PluginsDir)), - case EnableOrder1 of - [] -> io:format("No plugins to enable.~n"); - _ -> io:format("Will enable: ~p~n", [EnableOrder1]), - ok = lists:foldl( - fun (Plugin, ok) -> enable_one_plugin(Plugin, PluginsDir) end, - ok, lookup_plugins(EnableOrder1, AllPlugins)) - end, - update_enabled_plugins(PluginsDir, plugin_names(NewEnabledPlugins)), - prune(PluginsDir, PluginsDistDir); + update_enabled_plugins(plugin_names(NewEnabledPlugins)); -action(disable, ToDisable0, _Opts, PluginsDir, PluginsDistDir) -> +action(disable, ToDisable0, _Opts) -> ToDisable = [list_to_atom(Name) || Name <- ToDisable0], - EnabledPlugins = find_plugins(PluginsDir), - ToDisablePlugins = lookup_plugins(ToDisable, EnabledPlugins), - Missing = ToDisable -- plugin_names(ToDisablePlugins), + Enabled = read_enabled_plugins(), + AllPlugins = find_plugins(), + Missing = ToDisable -- plugin_names(AllPlugins), case Missing of [] -> ok; _ -> io:format("Warning: the following plugins could not be found: ~p~n", [Missing]) end, - ExplicitlyEnabled = read_enabled_plugins(PluginsDir), - DisableOrder = calculate_requires_plugins(plugin_names(ToDisablePlugins), - EnabledPlugins), - ExplicitlyDisabled = sets:to_list( - sets:intersection(sets:from_list(DisableOrder), - sets:from_list(ExplicitlyEnabled))), - io:format("Will disable: ~p~n", [ExplicitlyDisabled]), - update_enabled_plugins(PluginsDir, ExplicitlyEnabled -- DisableOrder), - prune(PluginsDir, PluginsDistDir). + ToDisable1 = ToDisable -- Missing, + ToDisable2 = calculate_dependencies(true, ToDisable1, AllPlugins), + AlsoDisabled = sets:to_list( + sets:intersection(sets:from_list(ToDisable2 -- ToDisable1), + sets:from_list(Enabled))), + case AlsoDisabled of + [] -> ok; + _ -> io:format("Warning: the following plugins will also be disabled " + "because their dependencies are no longer met: ~p~n", + [AlsoDisabled]) + end, + update_enabled_plugins(Enabled -- ToDisable2). %%---------------------------------------------------------------------------- -prune(PluginsDir, PluginsDistDir) -> - ExplicitlyEnabledPlugins = read_enabled_plugins(PluginsDir), - AllPlugins = find_plugins(PluginsDistDir), - Required = calculate_required_plugins(ExplicitlyEnabledPlugins, AllPlugins), - AllEnabledPlugins = find_plugins(PluginsDir), - ToDisablePlugins = - AllEnabledPlugins -- lookup_plugins(Required, AllEnabledPlugins), - case ToDisablePlugins of - [] -> - io:format("No unnecessary plugins found.~n"); - _ -> - io:format("Disabling unnecessary plugins: ~p~n", - [plugin_names(ToDisablePlugins)]), - ok = lists:foldl(fun (Plugin, ok) -> disable_one_plugin(Plugin) end, - ok, ToDisablePlugins) - end. - -%% Get the #plugin{}s from the .ezs in the given directory. +%% Get the #plugin{}s ready to be enabled. +find_plugins() -> + find_plugins(get(plugins_dist_dir)). find_plugins(PluginsDistDir) -> EZs = filelib:wildcard("*.ez", PluginsDistDir), {Plugins, Problems} = @@ -211,15 +183,15 @@ parse_binary(Bin) -> end. %% Pretty print a list of plugins. -format_plugins(PluginsDir, PluginsDistDir, Pattern, Compact) -> - AvailablePlugins = find_plugins(PluginsDistDir), - EnabledExplicitly = read_enabled_plugins(PluginsDir), - EnabledPlugins = find_plugins(PluginsDir), - EnabledImplicitly = plugin_names(EnabledPlugins) -- EnabledExplicitly, +format_plugins(Pattern, Compact) -> + AvailablePlugins = find_plugins(), + EnabledExplicitly = read_enabled_plugins(), + EnabledImplicitly = + calculate_required_plugins(EnabledExplicitly, AvailablePlugins) -- + EnabledExplicitly, {ok, RE} = re:compile(Pattern), [ format_plugin(P, EnabledExplicitly, EnabledImplicitly, Compact) - || P = #plugin{name = Name} <- usort_plugins(EnabledPlugins ++ - AvailablePlugins), + || P = #plugin{name = Name} <- AvailablePlugins, re:run(atom_to_list(Name), RE, [{capture, none}]) =:= match], ok. @@ -287,8 +259,10 @@ lookup_plugins(Names, AllPlugins) -> [P || P = #plugin{name = Name} <- AllPlugins1, lists:member(Name, Names)]. %% Read the enabled plugin names from disk. -read_enabled_plugins(PluginsDir) -> - FileName = enabled_plugins_filename(PluginsDir), +read_enabled_plugins() -> + read_enabled_plugins(get(enabled_plugins_file)). + +read_enabled_plugins(FileName) -> case rabbit_file:read_term_file(FileName) of {ok, [Plugins]} -> Plugins; {error, enoent} -> []; @@ -297,64 +271,27 @@ read_enabled_plugins(PluginsDir) -> end. %% Update the enabled plugin names on disk. -update_enabled_plugins(PluginsDir, Plugins) -> - FileName = enabled_plugins_filename(PluginsDir), +update_enabled_plugins(Plugins) -> + FileName = get(enabled_plugins_file), case rabbit_file:write_term_file(FileName, [Plugins]) of ok -> ok; {error, Reason} -> throw({error, {cannot_write_enabled_plugins_file, FileName, Reason}}) end. -enabled_plugins_filename(PluginsDir) -> - filename:join([PluginsDir, "enabled_plugins"]). +calculate_required_plugins(Sources, AllPlugins) -> + calculate_dependencies(false, Sources, AllPlugins). -%% Return a list of plugins that must be enabled when enabling the -%% ones in ToEnable. I.e. calculates dependencies. -calculate_required_plugins(ToEnable, AllPlugins) -> +calculate_dependencies(Reverse, Sources, AllPlugins) -> AllPlugins1 = filter_duplicates(usort_plugins(AllPlugins)), {ok, G} = rabbit_misc:build_acyclic_graph( fun (App, _Deps) -> [{App, App}] end, fun (App, Deps) -> [{App, Dep} || Dep <- Deps] end, [{Name, Deps} || #plugin{name = Name, dependencies = Deps} <- AllPlugins1]), - EnableOrder = digraph_utils:reachable(ToEnable, G), - true = digraph:delete(G), - EnableOrder. - -%% Return a list of plugins that must be disabled when disabling the -%% ones in ToDisable. I.e. calculates *reverse* dependencies. -calculate_requires_plugins(ToDisable, AllPlugins) -> - AllPlugins1 = filter_duplicates(usort_plugins(AllPlugins)), - {ok, G} = rabbit_misc:build_acyclic_graph( - fun (App, _Deps) -> [{App, App}] end, - fun (App, Deps) -> [{Dep, App} || Dep <- Deps] end, - [{Name, Deps} - || #plugin{name = Name, dependencies = Deps} <- AllPlugins1]), - DisableOrder = digraph_utils:reachable(ToDisable, G), + Dests = case Reverse of + false -> digraph_utils:reachable(Sources, G); + true -> digraph_utils:reaching(Sources, G) + end, true = digraph:delete(G), - DisableOrder. - -%% Enable one plugin by copying it to the PluginsDir. -enable_one_plugin(#plugin{name = Name, version = Version, location = Path}, - PluginsDir) -> - io:format("Enabling ~w-~s~n", [Name, Version]), - TargetPath = filename:join(PluginsDir, filename:basename(Path)), - ok = rabbit_file:ensure_parent_dirs_exist(TargetPath), - case file:copy(Path, TargetPath) of - {ok, _Bytes} -> ok; - {error, Err} -> io:format("Error enabling ~p (~p)~n", - [Name, {cannot_enable_plugin, - Path, TargetPath, Err}]), - rabbit_misc:quit(2) - end. - -%% Disable the given plugin by deleting it. -disable_one_plugin(#plugin{name = Name, version = Version, location = Path}) -> - io:format("Disabling ~w-~s~n", [Name, Version]), - case file:delete(Path) of - ok -> ok; - {error, enoent} -> ok; - {error, Err} -> io:format("Error disabling ~p (~p)~n", - [Name, {cannot_delete_plugin, Path, Err}]), - rabbit_misc:quit(2) - end. + Dests. diff --git a/src/rabbit_prelaunch.erl b/src/rabbit_prelaunch.erl index cd0c322b..c67404f3 100644 --- a/src/rabbit_prelaunch.erl +++ b/src/rabbit_prelaunch.erl @@ -18,6 +18,8 @@ -export([start/0, stop/0]). +-include("rabbit.hrl"). + -define(BaseApps, [rabbit]). -define(ERROR_CODE, 1). @@ -41,14 +43,15 @@ start() -> io:format("Activating RabbitMQ plugins ...~n"), %% Determine our various directories - [PluginDir, UnpackedPluginDir, NodeStr] = init:get_plain_arguments(), + [EnabledPluginsFile, PluginsDistDir, UnpackedPluginDir, NodeStr] = + init:get_plain_arguments(), RootName = UnpackedPluginDir ++ "/rabbit", %% Unpack any .ez plugins - unpack_ez_plugins(PluginDir, UnpackedPluginDir), + unpack_ez_plugins(EnabledPluginsFile, PluginsDistDir, UnpackedPluginDir), %% Build a list of required apps based on the fixed set, and any plugins - PluginApps = find_plugins(PluginDir) ++ find_plugins(UnpackedPluginDir), + PluginApps = find_plugins(UnpackedPluginDir), RequiredApps = ?BaseApps ++ PluginApps, %% Build the entire set of dependencies - this will load the @@ -145,7 +148,11 @@ delete_recursively(Fn) -> Error -> Error end. -unpack_ez_plugins(SrcDir, DestDir) -> +unpack_ez_plugins(EnabledPluginsFile, PluginsDistDir, DestDir) -> + AllPlugins = rabbit_plugins:find_plugins(PluginsDistDir), + Enabled = rabbit_plugins:read_enabled_plugins(EnabledPluginsFile), + ToUnpack = rabbit_plugins:calculate_required_plugins(Enabled, AllPlugins), + %% Eliminate the contents of the destination directory case delete_recursively(DestDir) of ok -> ok; @@ -155,8 +162,9 @@ unpack_ez_plugins(SrcDir, DestDir) -> ok -> ok; {error, E2} -> terminate("Could not create dir ~s (~p)", [DestDir, E2]) end, - [unpack_ez_plugin(PluginName, DestDir) || - PluginName <- filelib:wildcard(SrcDir ++ "/*.ez")]. + [unpack_ez_plugin(PluginLocation, DestDir) || + #plugin{location = PluginLocation} <- + rabbit_plugins:lookup_plugins(ToUnpack, AllPlugins)]. unpack_ez_plugin(PluginFn, PluginDestDir) -> zip:unzip(PluginFn, [{cwd, PluginDestDir}]), |