Skip to content

Commit bc1011d

Browse files
authored
Merge pull request #1064 from rabbitmq/do-not-expand-plugins
Do not expand plugins
2 parents 6caabb8 + bc64ac1 commit bc1011d

File tree

6 files changed

+131
-81
lines changed

6 files changed

+131
-81
lines changed

scripts/rabbitmq-env

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -220,10 +220,6 @@ rmq_normalize_path_var RABBITMQ_PID_FILE
220220

221221
[ "x" = "x$RABBITMQ_BOOT_MODULE" ] && RABBITMQ_BOOT_MODULE=${BOOT_MODULE}
222222

223-
[ "x" = "x$RABBITMQ_PLUGINS_EXPAND_DIR" ] && RABBITMQ_PLUGINS_EXPAND_DIR=${PLUGINS_EXPAND_DIR}
224-
[ "x" = "x$RABBITMQ_PLUGINS_EXPAND_DIR" ] && RABBITMQ_PLUGINS_EXPAND_DIR=${RABBITMQ_MNESIA_BASE}/${RABBITMQ_NODENAME}-plugins-expand
225-
rmq_normalize_path_var RABBITMQ_PLUGINS_EXPAND_DIR
226-
227223
[ "x" != "x$RABBITMQ_ENABLED_PLUGINS_FILE" ] && RABBITMQ_ENABLED_PLUGINS_FILE_source=environment
228224
[ "x" = "x$RABBITMQ_ENABLED_PLUGINS_FILE" ] && RABBITMQ_ENABLED_PLUGINS_FILE=${ENABLED_PLUGINS_FILE}
229225
rmq_normalize_path_var RABBITMQ_ENABLED_PLUGINS_FILE
@@ -251,7 +247,6 @@ rmq_check_if_shared_with_mnesia \
251247
RABBITMQ_CONFIG_FILE \
252248
RABBITMQ_LOG_BASE \
253249
RABBITMQ_PID_FILE \
254-
RABBITMQ_PLUGINS_EXPAND_DIR \
255250
RABBITMQ_ENABLED_PLUGINS_FILE \
256251
RABBITMQ_PLUGINS_DIR \
257252
RABBITMQ_LOGS

scripts/rabbitmq-env.bat

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -262,20 +262,6 @@ if "!RABBITMQ_BOOT_MODULE!"=="" (
262262
)
263263
)
264264

265-
REM [ "x" = "x$RABBITMQ_PLUGINS_EXPAND_DIR" ] && RABBITMQ_PLUGINS_EXPAND_DIR=${PLUGINS_EXPAND_DIR}
266-
REM [ "x" = "x$RABBITMQ_PLUGINS_EXPAND_DIR" ] && RABBITMQ_PLUGINS_EXPAND_DIR=${RABBITMQ_MNESIA_BASE}/${RABBITMQ_NODENAME}-plugins-expand
267-
if "!RABBITMQ_PLUGINS_EXPAND_DIR!"=="" (
268-
if "!PLUGINS_EXPAND_DIR!"=="" (
269-
set RABBITMQ_PLUGINS_EXPAND_DIR=!RABBITMQ_MNESIA_BASE!\!RABBITMQ_NODENAME!-plugins-expand
270-
) else (
271-
set RABBITMQ_PLUGINS_EXPAND_DIR=!PLUGINS_EXPAND_DIR!
272-
)
273-
)
274-
REM FIXME: RabbitMQ removes and recreates RABBITMQ_PLUGINS_EXPAND_DIR
275-
REM itself. Therefore we can't create it here in advance and escape the
276-
REM directory name, and RABBITMQ_PLUGINS_EXPAND_DIR must not contain
277-
REM non-US-ASCII characters.
278-
279265
REM [ "x" = "x$RABBITMQ_ENABLED_PLUGINS_FILE" ] && RABBITMQ_ENABLED_PLUGINS_FILE=${ENABLED_PLUGINS_FILE}
280266
if "!RABBITMQ_ENABLED_PLUGINS_FILE!"=="" (
281267
if "!ENABLED_PLUGINS_FILE!"=="" (

scripts/rabbitmq-server

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -218,7 +218,6 @@ start_rabbitmq_server() {
218218
-rabbit lager_handler "$RABBIT_LAGER_HANDLER" \
219219
-rabbit enabled_plugins_file "\"$RABBITMQ_ENABLED_PLUGINS_FILE\"" \
220220
-rabbit plugins_dir "\"$RABBITMQ_PLUGINS_DIR\"" \
221-
-rabbit plugins_expand_dir "\"$RABBITMQ_PLUGINS_EXPAND_DIR\"" \
222221
-os_mon start_cpu_sup false \
223222
-os_mon start_disksup false \
224223
-os_mon start_memsup false \

scripts/rabbitmq-server.bat

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,6 @@ if "!ENV_OK!"=="false" (
174174
-rabbit lager_handler !RABBIT_LAGER_HANDLER! ^
175175
-rabbit enabled_plugins_file \""!RABBITMQ_ENABLED_PLUGINS_FILE:\=/!"\" ^
176176
-rabbit plugins_dir \""!RABBITMQ_PLUGINS_DIR:\=/!"\" ^
177-
-rabbit plugins_expand_dir \""!RABBITMQ_PLUGINS_EXPAND_DIR:\=/!"\" ^
178177
-os_mon start_cpu_sup false ^
179178
-os_mon start_disksup false ^
180179
-os_mon start_memsup false ^

scripts/rabbitmq-service.bat

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -251,7 +251,6 @@ set ERLANG_SERVICE_ARGUMENTS= ^
251251
-rabbit lager_handler !RABBIT_LAGER_HANDLER! ^
252252
-rabbit enabled_plugins_file \""!RABBITMQ_ENABLED_PLUGINS_FILE:\=/!"\" ^
253253
-rabbit plugins_dir \""!RABBITMQ_PLUGINS_DIR:\=/!"\" ^
254-
-rabbit plugins_expand_dir \""!RABBITMQ_PLUGINS_EXPAND_DIR:\=/!"\" ^
255254
-rabbit windows_service_config \""!RABBITMQ_CONFIG_FILE:\=/!"\" ^
256255
-os_mon start_cpu_sup false ^
257256
-os_mon start_disksup false ^

src/rabbit_plugins.erl

Lines changed: 131 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -67,15 +67,22 @@ ensure(FileJustChanged0) ->
6767
{error, {enabled_plugins_mismatch, FileJustChanged, OurFile}}
6868
end.
6969

70-
%% @doc Prepares the file system and installs all enabled plugins.
7170
setup() ->
72-
{ok, ExpandDir} = application:get_env(rabbit, plugins_expand_dir),
73-
74-
%% Eliminate the contents of the destination directory
75-
case delete_recursively(ExpandDir) of
76-
ok -> ok;
77-
{error, E1} -> throw({error, {cannot_delete_plugins_expand_dir,
78-
[ExpandDir, E1]}})
71+
case application:get_env(rabbit, plugins_expand_dir) of
72+
{ok, ExpandDir} ->
73+
case filelib:is_dir(ExpandDir) of
74+
true ->
75+
rabbit_log:info(
76+
"\"~s\" is no longer used to expand plugins.~n"
77+
"RabbitMQ still manages this directory "
78+
"but will stop doing so in the future.", [ExpandDir]),
79+
80+
_ = delete_recursively(ExpandDir);
81+
false ->
82+
ok
83+
end;
84+
undefined ->
85+
ok
7986
end,
8087

8188
{ok, EnabledFile} = application:get_env(rabbit, enabled_plugins_file),
@@ -128,10 +135,56 @@ extract_schema(#plugin{type = dir, location = Location}, SchemaDir) ->
128135

129136
%% @doc Lists the plugins which are currently running.
130137
active() ->
131-
{ok, ExpandDir} = application:get_env(rabbit, plugins_expand_dir),
132-
InstalledPlugins = plugin_names(list(ExpandDir)),
138+
LoadedPluginNames = maybe_keep_required_deps(false, loaded_plugin_names()),
133139
[App || {App, _, _} <- rabbit_misc:which_applications(),
134-
lists:member(App, InstalledPlugins)].
140+
lists:member(App, LoadedPluginNames)].
141+
142+
loaded_plugin_names() ->
143+
{ok, PluginsDir} = application:get_env(rabbit, plugins_dir),
144+
PluginsDirComponents = filename:split(PluginsDir),
145+
loaded_plugin_names(code:get_path(), PluginsDirComponents, []).
146+
147+
loaded_plugin_names([Path | OtherPaths], PluginsDirComponents, PluginNames) ->
148+
case lists:sublist(filename:split(Path), length(PluginsDirComponents)) of
149+
PluginsDirComponents ->
150+
case build_plugin_name_from_code_path(Path) of
151+
undefined ->
152+
loaded_plugin_names(
153+
OtherPaths, PluginsDirComponents, PluginNames);
154+
PluginName ->
155+
loaded_plugin_names(
156+
OtherPaths, PluginsDirComponents,
157+
[list_to_atom(PluginName) | PluginNames])
158+
end;
159+
_ ->
160+
loaded_plugin_names(OtherPaths, PluginsDirComponents, PluginNames)
161+
end;
162+
loaded_plugin_names([], _, PluginNames) ->
163+
PluginNames.
164+
165+
build_plugin_name_from_code_path(Path) ->
166+
AppPath = case filelib:is_dir(Path) of
167+
true ->
168+
case filelib:wildcard(filename:join(Path, "*.app")) of
169+
[AP | _] -> AP;
170+
[] -> undefined
171+
end;
172+
false ->
173+
EZ = filename:dirname(filename:dirname(Path)),
174+
case filelib:is_regular(EZ) of
175+
true ->
176+
case find_app_path_in_ez(EZ) of
177+
{ok, AP} -> AP;
178+
_ -> undefined
179+
end;
180+
_ ->
181+
undefined
182+
end
183+
end,
184+
case AppPath of
185+
undefined -> undefined;
186+
_ -> filename:basename(AppPath, ".app")
187+
end.
135188

136189
%% @doc Get the list of plugins which are ready to be enabled.
137190
list(PluginsPath) ->
@@ -221,25 +274,19 @@ running_plugins() ->
221274
%%----------------------------------------------------------------------------
222275

223276
prepare_plugins(Enabled) ->
224-
{ok, PluginsDistDir} = application:get_env(rabbit, plugins_dir),
225-
{ok, ExpandDir} = application:get_env(rabbit, plugins_expand_dir),
226-
227-
AllPlugins = list(PluginsDistDir),
277+
AllPlugins = installed_plugins(),
228278
Wanted = dependencies(false, Enabled, AllPlugins),
229279
WantedPlugins = lookup_plugins(Wanted, AllPlugins),
230280
{ValidPlugins, Problems} = validate_plugins(WantedPlugins),
231281
maybe_warn_about_invalid_plugins(Problems),
232-
case filelib:ensure_dir(ExpandDir ++ "/") of
233-
ok -> ok;
234-
{error, E2} -> throw({error, {cannot_create_plugins_expand_dir,
235-
[ExpandDir, E2]}})
236-
end,
237-
[prepare_plugin(Plugin, ExpandDir) || Plugin <- ValidPlugins],
238282

239-
[prepare_dir_plugin(PluginAppDescPath) ||
240-
PluginAppDescPath <- filelib:wildcard(ExpandDir ++ "/*/ebin/*.app")],
283+
[prepare_dir_plugin(ValidPlugin) || ValidPlugin <- ValidPlugins],
241284
Wanted.
242285

286+
installed_plugins() ->
287+
{ok, PluginsDistDir} = application:get_env(rabbit, plugins_dir),
288+
list(PluginsDistDir).
289+
243290
maybe_warn_about_invalid_plugins([]) ->
244291
ok;
245292
maybe_warn_about_invalid_plugins(InvalidPlugins) ->
@@ -352,40 +399,60 @@ is_version_supported(Version, ExpectedVersions) ->
352399
end.
353400

354401
clean_plugins(Plugins) ->
355-
{ok, ExpandDir} = application:get_env(rabbit, plugins_expand_dir),
356-
[clean_plugin(Plugin, ExpandDir) || Plugin <- Plugins].
402+
[clean_plugin(Plugin) || Plugin <- Plugins].
357403

358-
clean_plugin(Plugin, ExpandDir) ->
404+
clean_plugin(Plugin) ->
359405
{ok, Mods} = application:get_key(Plugin, modules),
406+
PluginEbinDir = code:lib_dir(Plugin, ebin),
407+
360408
application:unload(Plugin),
361409
[begin
362410
code:soft_purge(Mod),
363411
code:delete(Mod),
364412
false = code:is_loaded(Mod)
365413
end || Mod <- Mods],
366-
delete_recursively(rabbit_misc:format("~s/~s", [ExpandDir, Plugin])).
367-
368-
prepare_dir_plugin(PluginAppDescPath) ->
369-
PluginEbinDir = filename:dirname(PluginAppDescPath),
370-
Plugin = filename:basename(PluginAppDescPath, ".app"),
371-
code:add_patha(PluginEbinDir),
372-
case filelib:wildcard(PluginEbinDir++ "/*.beam") of
373-
[] ->
374-
ok;
375-
[BeamPath | _] ->
376-
Module = list_to_atom(filename:basename(BeamPath, ".beam")),
377-
case code:ensure_loaded(Module) of
378-
{module, _} ->
414+
415+
code:del_path(PluginEbinDir).
416+
417+
plugin_ebin_dir(#plugin{type = ez, location = Location}) ->
418+
case find_app_path_in_ez(Location) of
419+
{ok, AppPath} ->
420+
filename:join(Location, filename:dirname(AppPath));
421+
{error, Reason} ->
422+
{error, Reason}
423+
end;
424+
plugin_ebin_dir(#plugin{type = dir, location = Location}) ->
425+
filename:join(Location, "ebin").
426+
427+
prepare_dir_plugin(#plugin{name = Name} = Plugin) ->
428+
PluginEbinDir = case plugin_ebin_dir(Plugin) of
429+
{error, Reason} ->
430+
throw({plugin_ebin_dir_not_found, Name, Reason});
431+
Dir ->
432+
Dir
433+
end,
434+
case code:add_patha(PluginEbinDir) of
435+
true ->
436+
case filelib:wildcard(PluginEbinDir++ "/*.beam") of
437+
[] ->
379438
ok;
380-
{error, badfile} ->
381-
rabbit_log:error("Failed to enable plugin \"~s\": "
382-
"it may have been built with an "
383-
"incompatible (more recent?) "
384-
"version of Erlang~n", [Plugin]),
385-
throw({plugin_built_with_incompatible_erlang, Plugin});
386-
Error ->
387-
throw({plugin_module_unloadable, Plugin, Error})
388-
end
439+
[BeamPath | _] ->
440+
Module = list_to_atom(filename:basename(BeamPath, ".beam")),
441+
case code:ensure_loaded(Module) of
442+
{module, _} ->
443+
ok;
444+
{error, badfile} ->
445+
rabbit_log:error("Failed to enable plugin \"~s\": "
446+
"it may have been built with an "
447+
"incompatible (more recent?) "
448+
"version of Erlang~n", [Name]),
449+
throw({plugin_built_with_incompatible_erlang, Name});
450+
Error ->
451+
throw({plugin_module_unloadable, Name, Error})
452+
end
453+
end;
454+
{error, bad_directory} ->
455+
throw({plugin_ebin_path_incorrect, Name, PluginEbinDir})
389456
end.
390457

391458
%%----------------------------------------------------------------------------
@@ -396,12 +463,6 @@ delete_recursively(Fn) ->
396463
{error, {Path, E}} -> {error, {cannot_delete, Path, E}}
397464
end.
398465

399-
prepare_plugin(#plugin{type = ez, location = Location}, ExpandDir) ->
400-
zip:unzip(Location, [{cwd, ExpandDir}]);
401-
prepare_plugin(#plugin{type = dir, name = Name, location = Location},
402-
ExpandDir) ->
403-
rabbit_file:recursive_copy(Location, filename:join([ExpandDir, Name])).
404-
405466
plugin_info({ez, EZ}) ->
406467
case read_app_file(EZ) of
407468
{application, Name, Props} -> mkplugin(Name, Props, ez, EZ);
@@ -428,21 +489,29 @@ mkplugin(Name, Props, Type, Location) ->
428489
broker_version_requirements = BrokerVersions,
429490
dependency_version_requirements = DepsVersions}.
430491

431-
read_app_file(EZ) ->
492+
find_app_path_in_ez(EZ) ->
432493
case zip:list_dir(EZ) of
433494
{ok, [_|ZippedFiles]} ->
434495
case find_app_files(ZippedFiles) of
435496
[AppPath|_] ->
436-
{ok, [{AppPath, AppFile}]} =
437-
zip:extract(EZ, [{file_list, [AppPath]}, memory]),
438-
parse_binary(AppFile);
497+
{ok, AppPath};
439498
[] ->
440499
{error, no_app_file}
441500
end;
442501
{error, Reason} ->
443502
{error, {invalid_ez, Reason}}
444503
end.
445504

505+
read_app_file(EZ) ->
506+
case find_app_path_in_ez(EZ) of
507+
{ok, AppPath} ->
508+
{ok, [{AppPath, AppFile}]} =
509+
zip:extract(EZ, [{file_list, [AppPath]}, memory]),
510+
parse_binary(AppFile);
511+
{error, Reason} ->
512+
{error, Reason}
513+
end.
514+
446515
find_app_files(ZippedFiles) ->
447516
{ok, RE} = re:compile("^.*/ebin/.*.app$"),
448517
[Path || {zip_file, Path, _, _, _, _} <- ZippedFiles,
@@ -544,7 +613,10 @@ maybe_keep_required_deps(false, Plugins) ->
544613
%% instance.
545614
application:load(rabbit),
546615
{ok, RabbitDeps} = application:get_key(rabbit, applications),
547-
lists:filter(fun(#plugin{name = Name}) ->
616+
lists:filter(fun
617+
(#plugin{name = Name}) ->
618+
not lists:member(Name, RabbitDeps);
619+
(Name) when is_atom(Name) ->
548620
not lists:member(Name, RabbitDeps)
549621
end,
550622
Plugins).

0 commit comments

Comments
 (0)