diff options
| author | Gerhard Lazu <gerhard@users.noreply.github.com> | 2016-12-19 17:42:45 +0000 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2016-12-19 17:42:45 +0000 |
| commit | bc1011d0ea93591bb01faf105a58d05cdc1bea76 (patch) | |
| tree | 28f6f16ab2ded631a4843b862f83addda3dec0a2 | |
| parent | 6caabb89c9bd33c667f4279a27297447632e1573 (diff) | |
| parent | bc64ac16774aeb403cba87f7e48ad70329dd8b3b (diff) | |
| download | rabbitmq-server-git-bc1011d0ea93591bb01faf105a58d05cdc1bea76.tar.gz | |
Merge pull request #1064 from rabbitmq/do-not-expand-plugins
Do not expand plugins
| -rwxr-xr-x | scripts/rabbitmq-env | 5 | ||||
| -rw-r--r-- | scripts/rabbitmq-env.bat | 14 | ||||
| -rwxr-xr-x | scripts/rabbitmq-server | 1 | ||||
| -rw-r--r-- | scripts/rabbitmq-server.bat | 1 | ||||
| -rw-r--r-- | scripts/rabbitmq-service.bat | 1 | ||||
| -rw-r--r-- | src/rabbit_plugins.erl | 190 |
6 files changed, 131 insertions, 81 deletions
diff --git a/scripts/rabbitmq-env b/scripts/rabbitmq-env index d975f274b2..d3014ecd66 100755 --- a/scripts/rabbitmq-env +++ b/scripts/rabbitmq-env @@ -220,10 +220,6 @@ rmq_normalize_path_var RABBITMQ_PID_FILE [ "x" = "x$RABBITMQ_BOOT_MODULE" ] && RABBITMQ_BOOT_MODULE=${BOOT_MODULE} -[ "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 -rmq_normalize_path_var RABBITMQ_PLUGINS_EXPAND_DIR - [ "x" != "x$RABBITMQ_ENABLED_PLUGINS_FILE" ] && RABBITMQ_ENABLED_PLUGINS_FILE_source=environment [ "x" = "x$RABBITMQ_ENABLED_PLUGINS_FILE" ] && RABBITMQ_ENABLED_PLUGINS_FILE=${ENABLED_PLUGINS_FILE} rmq_normalize_path_var RABBITMQ_ENABLED_PLUGINS_FILE @@ -251,7 +247,6 @@ rmq_check_if_shared_with_mnesia \ RABBITMQ_CONFIG_FILE \ RABBITMQ_LOG_BASE \ RABBITMQ_PID_FILE \ - RABBITMQ_PLUGINS_EXPAND_DIR \ RABBITMQ_ENABLED_PLUGINS_FILE \ RABBITMQ_PLUGINS_DIR \ RABBITMQ_LOGS diff --git a/scripts/rabbitmq-env.bat b/scripts/rabbitmq-env.bat index 56b2f69b2d..9426019003 100644 --- a/scripts/rabbitmq-env.bat +++ b/scripts/rabbitmq-env.bat @@ -262,20 +262,6 @@ if "!RABBITMQ_BOOT_MODULE!"=="" ( )
)
-REM [ "x" = "x$RABBITMQ_PLUGINS_EXPAND_DIR" ] && RABBITMQ_PLUGINS_EXPAND_DIR=${PLUGINS_EXPAND_DIR}
-REM [ "x" = "x$RABBITMQ_PLUGINS_EXPAND_DIR" ] && RABBITMQ_PLUGINS_EXPAND_DIR=${RABBITMQ_MNESIA_BASE}/${RABBITMQ_NODENAME}-plugins-expand
-if "!RABBITMQ_PLUGINS_EXPAND_DIR!"=="" (
- if "!PLUGINS_EXPAND_DIR!"=="" (
- set RABBITMQ_PLUGINS_EXPAND_DIR=!RABBITMQ_MNESIA_BASE!\!RABBITMQ_NODENAME!-plugins-expand
- ) else (
- set RABBITMQ_PLUGINS_EXPAND_DIR=!PLUGINS_EXPAND_DIR!
- )
-)
-REM FIXME: RabbitMQ removes and recreates RABBITMQ_PLUGINS_EXPAND_DIR
-REM itself. Therefore we can't create it here in advance and escape the
-REM directory name, and RABBITMQ_PLUGINS_EXPAND_DIR must not contain
-REM non-US-ASCII characters.
-
REM [ "x" = "x$RABBITMQ_ENABLED_PLUGINS_FILE" ] && RABBITMQ_ENABLED_PLUGINS_FILE=${ENABLED_PLUGINS_FILE}
if "!RABBITMQ_ENABLED_PLUGINS_FILE!"=="" (
if "!ENABLED_PLUGINS_FILE!"=="" (
diff --git a/scripts/rabbitmq-server b/scripts/rabbitmq-server index 6f1e932da2..ce731516d4 100755 --- a/scripts/rabbitmq-server +++ b/scripts/rabbitmq-server @@ -218,7 +218,6 @@ start_rabbitmq_server() { -rabbit lager_handler "$RABBIT_LAGER_HANDLER" \ -rabbit enabled_plugins_file "\"$RABBITMQ_ENABLED_PLUGINS_FILE\"" \ -rabbit plugins_dir "\"$RABBITMQ_PLUGINS_DIR\"" \ - -rabbit plugins_expand_dir "\"$RABBITMQ_PLUGINS_EXPAND_DIR\"" \ -os_mon start_cpu_sup false \ -os_mon start_disksup false \ -os_mon start_memsup false \ diff --git a/scripts/rabbitmq-server.bat b/scripts/rabbitmq-server.bat index 03bf05349c..5e9b3667bc 100644 --- a/scripts/rabbitmq-server.bat +++ b/scripts/rabbitmq-server.bat @@ -174,7 +174,6 @@ if "!ENV_OK!"=="false" ( -rabbit lager_handler !RABBIT_LAGER_HANDLER! ^
-rabbit enabled_plugins_file \""!RABBITMQ_ENABLED_PLUGINS_FILE:\=/!"\" ^
-rabbit plugins_dir \""!RABBITMQ_PLUGINS_DIR:\=/!"\" ^
--rabbit plugins_expand_dir \""!RABBITMQ_PLUGINS_EXPAND_DIR:\=/!"\" ^
-os_mon start_cpu_sup false ^
-os_mon start_disksup false ^
-os_mon start_memsup false ^
diff --git a/scripts/rabbitmq-service.bat b/scripts/rabbitmq-service.bat index 5022ec020a..24a7ab128c 100644 --- a/scripts/rabbitmq-service.bat +++ b/scripts/rabbitmq-service.bat @@ -251,7 +251,6 @@ set ERLANG_SERVICE_ARGUMENTS= ^ -rabbit lager_handler !RABBIT_LAGER_HANDLER! ^
-rabbit enabled_plugins_file \""!RABBITMQ_ENABLED_PLUGINS_FILE:\=/!"\" ^
-rabbit plugins_dir \""!RABBITMQ_PLUGINS_DIR:\=/!"\" ^
--rabbit plugins_expand_dir \""!RABBITMQ_PLUGINS_EXPAND_DIR:\=/!"\" ^
-rabbit windows_service_config \""!RABBITMQ_CONFIG_FILE:\=/!"\" ^
-os_mon start_cpu_sup false ^
-os_mon start_disksup false ^
diff --git a/src/rabbit_plugins.erl b/src/rabbit_plugins.erl index b7ba3af732..40dbf91cfd 100644 --- a/src/rabbit_plugins.erl +++ b/src/rabbit_plugins.erl @@ -67,15 +67,22 @@ ensure(FileJustChanged0) -> {error, {enabled_plugins_mismatch, FileJustChanged, OurFile}} end. -%% @doc Prepares the file system and installs all enabled plugins. setup() -> - {ok, ExpandDir} = application:get_env(rabbit, plugins_expand_dir), - - %% Eliminate the contents of the destination directory - case delete_recursively(ExpandDir) of - ok -> ok; - {error, E1} -> throw({error, {cannot_delete_plugins_expand_dir, - [ExpandDir, E1]}}) + case application:get_env(rabbit, plugins_expand_dir) of + {ok, ExpandDir} -> + case filelib:is_dir(ExpandDir) of + true -> + rabbit_log:info( + "\"~s\" is no longer used to expand plugins.~n" + "RabbitMQ still manages this directory " + "but will stop doing so in the future.", [ExpandDir]), + + _ = delete_recursively(ExpandDir); + false -> + ok + end; + undefined -> + ok end, {ok, EnabledFile} = application:get_env(rabbit, enabled_plugins_file), @@ -128,10 +135,56 @@ extract_schema(#plugin{type = dir, location = Location}, SchemaDir) -> %% @doc Lists the plugins which are currently running. active() -> - {ok, ExpandDir} = application:get_env(rabbit, plugins_expand_dir), - InstalledPlugins = plugin_names(list(ExpandDir)), + LoadedPluginNames = maybe_keep_required_deps(false, loaded_plugin_names()), [App || {App, _, _} <- rabbit_misc:which_applications(), - lists:member(App, InstalledPlugins)]. + lists:member(App, LoadedPluginNames)]. + +loaded_plugin_names() -> + {ok, PluginsDir} = application:get_env(rabbit, plugins_dir), + PluginsDirComponents = filename:split(PluginsDir), + loaded_plugin_names(code:get_path(), PluginsDirComponents, []). + +loaded_plugin_names([Path | OtherPaths], PluginsDirComponents, PluginNames) -> + case lists:sublist(filename:split(Path), length(PluginsDirComponents)) of + PluginsDirComponents -> + case build_plugin_name_from_code_path(Path) of + undefined -> + loaded_plugin_names( + OtherPaths, PluginsDirComponents, PluginNames); + PluginName -> + loaded_plugin_names( + OtherPaths, PluginsDirComponents, + [list_to_atom(PluginName) | PluginNames]) + end; + _ -> + loaded_plugin_names(OtherPaths, PluginsDirComponents, PluginNames) + end; +loaded_plugin_names([], _, PluginNames) -> + PluginNames. + +build_plugin_name_from_code_path(Path) -> + AppPath = case filelib:is_dir(Path) of + true -> + case filelib:wildcard(filename:join(Path, "*.app")) of + [AP | _] -> AP; + [] -> undefined + end; + false -> + EZ = filename:dirname(filename:dirname(Path)), + case filelib:is_regular(EZ) of + true -> + case find_app_path_in_ez(EZ) of + {ok, AP} -> AP; + _ -> undefined + end; + _ -> + undefined + end + end, + case AppPath of + undefined -> undefined; + _ -> filename:basename(AppPath, ".app") + end. %% @doc Get the list of plugins which are ready to be enabled. list(PluginsPath) -> @@ -221,25 +274,19 @@ running_plugins() -> %%---------------------------------------------------------------------------- prepare_plugins(Enabled) -> - {ok, PluginsDistDir} = application:get_env(rabbit, plugins_dir), - {ok, ExpandDir} = application:get_env(rabbit, plugins_expand_dir), - - AllPlugins = list(PluginsDistDir), + AllPlugins = installed_plugins(), Wanted = dependencies(false, Enabled, AllPlugins), WantedPlugins = lookup_plugins(Wanted, AllPlugins), {ValidPlugins, Problems} = validate_plugins(WantedPlugins), maybe_warn_about_invalid_plugins(Problems), - case filelib:ensure_dir(ExpandDir ++ "/") of - ok -> ok; - {error, E2} -> throw({error, {cannot_create_plugins_expand_dir, - [ExpandDir, E2]}}) - end, - [prepare_plugin(Plugin, ExpandDir) || Plugin <- ValidPlugins], - [prepare_dir_plugin(PluginAppDescPath) || - PluginAppDescPath <- filelib:wildcard(ExpandDir ++ "/*/ebin/*.app")], + [prepare_dir_plugin(ValidPlugin) || ValidPlugin <- ValidPlugins], Wanted. +installed_plugins() -> + {ok, PluginsDistDir} = application:get_env(rabbit, plugins_dir), + list(PluginsDistDir). + maybe_warn_about_invalid_plugins([]) -> ok; maybe_warn_about_invalid_plugins(InvalidPlugins) -> @@ -352,40 +399,60 @@ is_version_supported(Version, ExpectedVersions) -> end. clean_plugins(Plugins) -> - {ok, ExpandDir} = application:get_env(rabbit, plugins_expand_dir), - [clean_plugin(Plugin, ExpandDir) || Plugin <- Plugins]. + [clean_plugin(Plugin) || Plugin <- Plugins]. -clean_plugin(Plugin, ExpandDir) -> +clean_plugin(Plugin) -> {ok, Mods} = application:get_key(Plugin, modules), + PluginEbinDir = code:lib_dir(Plugin, ebin), + application:unload(Plugin), [begin code:soft_purge(Mod), code:delete(Mod), false = code:is_loaded(Mod) end || Mod <- Mods], - delete_recursively(rabbit_misc:format("~s/~s", [ExpandDir, Plugin])). - -prepare_dir_plugin(PluginAppDescPath) -> - PluginEbinDir = filename:dirname(PluginAppDescPath), - Plugin = filename:basename(PluginAppDescPath, ".app"), - code:add_patha(PluginEbinDir), - case filelib:wildcard(PluginEbinDir++ "/*.beam") of - [] -> - ok; - [BeamPath | _] -> - Module = list_to_atom(filename:basename(BeamPath, ".beam")), - case code:ensure_loaded(Module) of - {module, _} -> + + code:del_path(PluginEbinDir). + +plugin_ebin_dir(#plugin{type = ez, location = Location}) -> + case find_app_path_in_ez(Location) of + {ok, AppPath} -> + filename:join(Location, filename:dirname(AppPath)); + {error, Reason} -> + {error, Reason} + end; +plugin_ebin_dir(#plugin{type = dir, location = Location}) -> + filename:join(Location, "ebin"). + +prepare_dir_plugin(#plugin{name = Name} = Plugin) -> + PluginEbinDir = case plugin_ebin_dir(Plugin) of + {error, Reason} -> + throw({plugin_ebin_dir_not_found, Name, Reason}); + Dir -> + Dir + end, + case code:add_patha(PluginEbinDir) of + true -> + case filelib:wildcard(PluginEbinDir++ "/*.beam") of + [] -> ok; - {error, badfile} -> - rabbit_log:error("Failed to enable plugin \"~s\": " - "it may have been built with an " - "incompatible (more recent?) " - "version of Erlang~n", [Plugin]), - throw({plugin_built_with_incompatible_erlang, Plugin}); - Error -> - throw({plugin_module_unloadable, Plugin, Error}) - end + [BeamPath | _] -> + Module = list_to_atom(filename:basename(BeamPath, ".beam")), + case code:ensure_loaded(Module) of + {module, _} -> + ok; + {error, badfile} -> + rabbit_log:error("Failed to enable plugin \"~s\": " + "it may have been built with an " + "incompatible (more recent?) " + "version of Erlang~n", [Name]), + throw({plugin_built_with_incompatible_erlang, Name}); + Error -> + throw({plugin_module_unloadable, Name, Error}) + end + end; + {error, bad_directory} -> + throw({plugin_ebin_path_incorrect, Name, PluginEbinDir}) end. %%---------------------------------------------------------------------------- @@ -396,12 +463,6 @@ delete_recursively(Fn) -> {error, {Path, E}} -> {error, {cannot_delete, Path, E}} end. -prepare_plugin(#plugin{type = ez, location = Location}, ExpandDir) -> - zip:unzip(Location, [{cwd, ExpandDir}]); -prepare_plugin(#plugin{type = dir, name = Name, location = Location}, - ExpandDir) -> - rabbit_file:recursive_copy(Location, filename:join([ExpandDir, Name])). - plugin_info({ez, EZ}) -> case read_app_file(EZ) of {application, Name, Props} -> mkplugin(Name, Props, ez, EZ); @@ -428,14 +489,12 @@ mkplugin(Name, Props, Type, Location) -> broker_version_requirements = BrokerVersions, dependency_version_requirements = DepsVersions}. -read_app_file(EZ) -> +find_app_path_in_ez(EZ) -> case zip:list_dir(EZ) of {ok, [_|ZippedFiles]} -> case find_app_files(ZippedFiles) of [AppPath|_] -> - {ok, [{AppPath, AppFile}]} = - zip:extract(EZ, [{file_list, [AppPath]}, memory]), - parse_binary(AppFile); + {ok, AppPath}; [] -> {error, no_app_file} end; @@ -443,6 +502,16 @@ read_app_file(EZ) -> {error, {invalid_ez, Reason}} end. +read_app_file(EZ) -> + case find_app_path_in_ez(EZ) of + {ok, AppPath} -> + {ok, [{AppPath, AppFile}]} = + zip:extract(EZ, [{file_list, [AppPath]}, memory]), + parse_binary(AppFile); + {error, Reason} -> + {error, Reason} + end. + find_app_files(ZippedFiles) -> {ok, RE} = re:compile("^.*/ebin/.*.app$"), [Path || {zip_file, Path, _, _, _, _} <- ZippedFiles, @@ -544,7 +613,10 @@ maybe_keep_required_deps(false, Plugins) -> %% instance. application:load(rabbit), {ok, RabbitDeps} = application:get_key(rabbit, applications), - lists:filter(fun(#plugin{name = Name}) -> + lists:filter(fun + (#plugin{name = Name}) -> + not lists:member(Name, RabbitDeps); + (Name) when is_atom(Name) -> not lists:member(Name, RabbitDeps) end, Plugins). |
