@@ -67,15 +67,22 @@ ensure(FileJustChanged0) ->
67
67
{error , {enabled_plugins_mismatch , FileJustChanged , OurFile }}
68
68
end .
69
69
70
- % % @doc Prepares the file system and installs all enabled plugins.
71
70
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
79
86
end ,
80
87
81
88
{ok , EnabledFile } = application :get_env (rabbit , enabled_plugins_file ),
@@ -128,10 +135,56 @@ extract_schema(#plugin{type = dir, location = Location}, SchemaDir) ->
128
135
129
136
% % @doc Lists the plugins which are currently running.
130
137
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 ()),
133
139
[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 .
135
188
136
189
% % @doc Get the list of plugins which are ready to be enabled.
137
190
list (PluginsPath ) ->
@@ -221,25 +274,19 @@ running_plugins() ->
221
274
% %----------------------------------------------------------------------------
222
275
223
276
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 (),
228
278
Wanted = dependencies (false , Enabled , AllPlugins ),
229
279
WantedPlugins = lookup_plugins (Wanted , AllPlugins ),
230
280
{ValidPlugins , Problems } = validate_plugins (WantedPlugins ),
231
281
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 ],
238
282
239
- [prepare_dir_plugin (PluginAppDescPath ) ||
240
- PluginAppDescPath <- filelib :wildcard (ExpandDir ++ " /*/ebin/*.app" )],
283
+ [prepare_dir_plugin (ValidPlugin ) || ValidPlugin <- ValidPlugins ],
241
284
Wanted .
242
285
286
+ installed_plugins () ->
287
+ {ok , PluginsDistDir } = application :get_env (rabbit , plugins_dir ),
288
+ list (PluginsDistDir ).
289
+
243
290
maybe_warn_about_invalid_plugins ([]) ->
244
291
ok ;
245
292
maybe_warn_about_invalid_plugins (InvalidPlugins ) ->
@@ -352,40 +399,60 @@ is_version_supported(Version, ExpectedVersions) ->
352
399
end .
353
400
354
401
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 ].
357
403
358
- clean_plugin (Plugin , ExpandDir ) ->
404
+ clean_plugin (Plugin ) ->
359
405
{ok , Mods } = application :get_key (Plugin , modules ),
406
+ PluginEbinDir = code :lib_dir (Plugin , ebin ),
407
+
360
408
application :unload (Plugin ),
361
409
[begin
362
410
code :soft_purge (Mod ),
363
411
code :delete (Mod ),
364
412
false = code :is_loaded (Mod )
365
413
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
+ [] ->
379
438
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 })
389
456
end .
390
457
391
458
% %----------------------------------------------------------------------------
@@ -396,12 +463,6 @@ delete_recursively(Fn) ->
396
463
{error , {Path , E }} -> {error , {cannot_delete , Path , E }}
397
464
end .
398
465
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
-
405
466
plugin_info ({ez , EZ }) ->
406
467
case read_app_file (EZ ) of
407
468
{application , Name , Props } -> mkplugin (Name , Props , ez , EZ );
@@ -428,21 +489,29 @@ mkplugin(Name, Props, Type, Location) ->
428
489
broker_version_requirements = BrokerVersions ,
429
490
dependency_version_requirements = DepsVersions }.
430
491
431
- read_app_file (EZ ) ->
492
+ find_app_path_in_ez (EZ ) ->
432
493
case zip :list_dir (EZ ) of
433
494
{ok , [_ |ZippedFiles ]} ->
434
495
case find_app_files (ZippedFiles ) of
435
496
[AppPath |_ ] ->
436
- {ok , [{AppPath , AppFile }]} =
437
- zip :extract (EZ , [{file_list , [AppPath ]}, memory ]),
438
- parse_binary (AppFile );
497
+ {ok , AppPath };
439
498
[] ->
440
499
{error , no_app_file }
441
500
end ;
442
501
{error , Reason } ->
443
502
{error , {invalid_ez , Reason }}
444
503
end .
445
504
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
+
446
515
find_app_files (ZippedFiles ) ->
447
516
{ok , RE } = re :compile (" ^.*/ebin/.*.app$" ),
448
517
[Path || {zip_file , Path , _ , _ , _ , _ } <- ZippedFiles ,
@@ -544,7 +613,10 @@ maybe_keep_required_deps(false, Plugins) ->
544
613
% % instance.
545
614
application :load (rabbit ),
546
615
{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 ) ->
548
620
not lists :member (Name , RabbitDeps )
549
621
end ,
550
622
Plugins ).
0 commit comments