From fc18ca9c57d51ed47f0ad5dd1e9e911583b1597d Mon Sep 17 00:00:00 2001 From: Philip Kuryloski Date: Tue, 21 Apr 2020 10:17:56 +0200 Subject: Correct a dependency of rabbit_prelaunch on rabbit apps/rabbit_prelaunch should not depend on rabbit, since rabbit already depends on apps/rabbit_prelaunch. So, rabbit_plugins:maybe_migrate_enabled_plugins_file/1 becomes rabbit_prelaunch_plugins:maybe_migrate_enabled_plugins_file/1. --- apps/rabbitmq_prelaunch/src/rabbit_prelaunch.erl | 2 +- .../src/rabbit_prelaunch_plugins.erl | 40 +++++ src/rabbit_plugins.erl | 40 +---- test/rabbit_plugins_SUITE.erl | 188 --------------------- test/rabbit_prelaunch_plugins_SUITE.erl | 188 +++++++++++++++++++++ 5 files changed, 230 insertions(+), 228 deletions(-) create mode 100644 apps/rabbitmq_prelaunch/src/rabbit_prelaunch_plugins.erl delete mode 100644 test/rabbit_plugins_SUITE.erl create mode 100644 test/rabbit_prelaunch_plugins_SUITE.erl diff --git a/apps/rabbitmq_prelaunch/src/rabbit_prelaunch.erl b/apps/rabbitmq_prelaunch/src/rabbit_prelaunch.erl index b9c4e06258..7ac19237b3 100644 --- a/apps/rabbitmq_prelaunch/src/rabbit_prelaunch.erl +++ b/apps/rabbitmq_prelaunch/src/rabbit_prelaunch.erl @@ -93,7 +93,7 @@ do_run() -> Context2 = rabbit_env:get_context_after_reloading_env(Context1), %% Migrate the enabled_plugins file to the new location if necessary - Context3 = rabbit_plugins:maybe_migrate_enabled_plugins_file(Context2), + Context3 = rabbit_prelaunch_plugins:maybe_migrate_enabled_plugins_file(Context2), ?assertMatch(#{}, Context3), store_context(Context3), diff --git a/apps/rabbitmq_prelaunch/src/rabbit_prelaunch_plugins.erl b/apps/rabbitmq_prelaunch/src/rabbit_prelaunch_plugins.erl new file mode 100644 index 0000000000..efb849382b --- /dev/null +++ b/apps/rabbitmq_prelaunch/src/rabbit_prelaunch_plugins.erl @@ -0,0 +1,40 @@ +-module(rabbit_prelaunch_plugins). + +-include_lib("kernel/include/file.hrl"). + +-export([maybe_migrate_enabled_plugins_file/1]). + +-define(ENABLED_PLUGINS_FILENAME, "enabled_plugins"). + +-spec maybe_migrate_enabled_plugins_file(map()) -> map(). +maybe_migrate_enabled_plugins_file(#{enabled_plugins_file := EnabledPluginsFile} = Context) + when EnabledPluginsFile =/= undefined -> + Context; +maybe_migrate_enabled_plugins_file(#{os_type := {unix, _}, + config_base_dir := ConfigBaseDir, + data_dir := DataDir} = Context) -> + ModernLocation = filename:join(DataDir, ?ENABLED_PLUGINS_FILENAME), + LegacyLocation = filename:join(ConfigBaseDir, ?ENABLED_PLUGINS_FILENAME), + case {filelib:is_regular(ModernLocation), + file:read_file_info(LegacyLocation)} of + {false, {ok, #file_info{access = read_write}}} -> + rabbit_log_prelaunch:info("NOTICE: Using 'enabled_plugins' file" + " from ~p. Please migrate this file" + " to its new location, ~p, as the" + " previous location is deprecated.", + [LegacyLocation, ModernLocation]), + Context#{enabled_plugins_file := LegacyLocation}; + {false, {ok, #file_info{access = read}}} -> + {ok, _} = file:copy(LegacyLocation, ModernLocation), + rabbit_log_prelaunch:info("NOTICE: An 'enabled_plugins' file was" + " found at ~p but was not read and" + " writable. It has been copied to its" + " new location at ~p and any changes" + " to plugin status will be reflected" + " there.", [LegacyLocation, ModernLocation]), + Context#{enabled_plugins_file := ModernLocation}; + _ -> + Context#{enabled_plugins_file := ModernLocation} + end; +maybe_migrate_enabled_plugins_file(#{data_dir := DataDir} = Context) -> + Context#{enabled_plugins_file := filename:join(DataDir, ?ENABLED_PLUGINS_FILENAME)}. diff --git a/src/rabbit_plugins.erl b/src/rabbit_plugins.erl index 6d09f8c76a..17790c0f6c 100644 --- a/src/rabbit_plugins.erl +++ b/src/rabbit_plugins.erl @@ -23,18 +23,13 @@ -export([ensure/1]). -export([validate_plugins/1, format_invalid_plugins/1]). -export([is_strictly_plugin/1, strictly_plugins/2, strictly_plugins/1]). --export([plugins_dir/0, plugin_names/1, plugins_expand_dir/0, enabled_plugins_file/0, - maybe_migrate_enabled_plugins_file/1]). +-export([plugins_dir/0, plugin_names/1, plugins_expand_dir/0, enabled_plugins_file/0]). % Export for testing purpose. -export([is_version_supported/2, validate_plugins/2]). %%---------------------------------------------------------------------------- --define(ENABLED_PLUGINS_FILENAME, "enabled_plugins"). - -%%---------------------------------------------------------------------------- - -type plugin_name() :: atom(). %%---------------------------------------------------------------------------- @@ -113,39 +108,6 @@ enabled_plugins_file() -> filename:join([rabbit_mnesia:dir(), "enabled_plugins"]) end. --spec maybe_migrate_enabled_plugins_file(map()) -> map(). -maybe_migrate_enabled_plugins_file(#{enabled_plugins_file := EnabledPluginsFile} = Context) - when EnabledPluginsFile =/= undefined -> - Context; -maybe_migrate_enabled_plugins_file(#{os_type := {unix, _}, - config_base_dir := ConfigBaseDir, - data_dir := DataDir} = Context) -> - ModernLocation = filename:join(DataDir, ?ENABLED_PLUGINS_FILENAME), - LegacyLocation = filename:join(ConfigBaseDir, ?ENABLED_PLUGINS_FILENAME), - case {filelib:is_regular(ModernLocation), - file:read_file_info(LegacyLocation)} of - {false, {ok, #file_info{access = read_write}}} -> - rabbit_log_prelaunch:info("NOTICE: Using 'enabled_plugins' file" - " from ~p. Please migrate this file" - " to its new location, ~p, as the" - " previous location is deprecated.", - [LegacyLocation, ModernLocation]), - Context#{enabled_plugins_file := LegacyLocation}; - {false, {ok, #file_info{access = read}}} -> - {ok, _} = file:copy(LegacyLocation, ModernLocation), - rabbit_log_prelaunch:info("NOTICE: An 'enabled_plugins' file was" - " found at ~p but was not read and" - " writable. It has been copied to its" - " new location at ~p and any changes" - " to plugin status will be reflected" - " there.", [LegacyLocation, ModernLocation]), - Context#{enabled_plugins_file := ModernLocation}; - _ -> - Context#{enabled_plugins_file := ModernLocation} - end; -maybe_migrate_enabled_plugins_file(#{data_dir := DataDir} = Context) -> - Context#{enabled_plugins_file := filename:join(DataDir, ?ENABLED_PLUGINS_FILENAME)}. - -spec enabled_plugins() -> [atom()]. enabled_plugins() -> case application:get_env(rabbit, enabled_plugins_file) of diff --git a/test/rabbit_plugins_SUITE.erl b/test/rabbit_plugins_SUITE.erl deleted file mode 100644 index f362caf415..0000000000 --- a/test/rabbit_plugins_SUITE.erl +++ /dev/null @@ -1,188 +0,0 @@ -%% 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 -%% https://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 Developer of the Original Code is GoPivotal, Inc. -%% Copyright (c) 2019-2020 VMware, Inc. or its affiliates. All rights reserved. -%% - --module(rabbit_plugins_SUITE). - --include_lib("common_test/include/ct.hrl"). --include_lib("eunit/include/eunit.hrl"). --include_lib("kernel/include/file.hrl"). - --compile(export_all). - --export([all/0, - suite/0, - groups/0, - init_per_group/2, - end_per_group/2, - init_per_testcase/2, - end_per_testcase/2, - check_enabled_plugins_file_passthrough/1, - check_enabled_plugins_file_modern/1, - check_enabled_plugins_file_default/1, - check_enabled_plugins_file_legacy/1, - check_enabled_plugins_file_copy/1]). - -all() -> - [ - {group, maybe_migrate_enabled_plugins_file_tests} - ]. - -suite() -> - [{timetrap, {seconds, 10}}]. - -groups() -> - [ - {maybe_migrate_enabled_plugins_file_tests, [], - [ - check_enabled_plugins_file_passthrough, - check_enabled_plugins_file_modern, - check_enabled_plugins_file_default, - check_enabled_plugins_file_legacy, - check_enabled_plugins_file_copy - ]} - ]. - -init_per_group(maybe_migrate_enabled_plugins_file_tests, Config) -> - case os:type() of - {unix, _} -> - PrivDir = proplists:get_value(priv_dir, Config), - RabbitConfigBaseDir = filename:join([PrivDir, "etc", "rabbitmq"]), - LegacyFile = filename:join(RabbitConfigBaseDir, "enabled_plugins"), - RabbitDataDir = filename:join([PrivDir, "var", "lib", "rabbitmq"]), - ModernFile = filename:join(RabbitDataDir, "enabled_plugins"), - [{rabbit_config_base_dir, RabbitConfigBaseDir}, - {rabbit_data_dir, RabbitDataDir}, - {legacy_file, LegacyFile}, - {modern_file, ModernFile} | Config]; - _ -> - {skip, "enabled_plugins file fallback behavior does not apply to Windows"} - end; -init_per_group(_, Config) -> - Config. - -end_per_group(_, Config) -> - Config. - -init_per_testcase(check_enabled_plugins_file_modern, Config) -> - ok = cleanup_enabled_plugins_files(Config), - RabbitDataDir = proplists:get_value(rabbit_data_dir, Config), - create_enabled_plugins_file(Config, RabbitDataDir, 8#600); -init_per_testcase(check_enabled_plugins_file_default, Config) -> - ok = cleanup_enabled_plugins_files(Config), - Config; -init_per_testcase(check_enabled_plugins_file_legacy, Config) -> - ok = cleanup_enabled_plugins_files(Config), - RabbitConfigBaseDir = proplists:get_value(rabbit_config_base_dir, Config), - create_enabled_plugins_file(Config, RabbitConfigBaseDir, 8#600); -init_per_testcase(check_enabled_plugins_file_copy, Config) -> - ok = cleanup_enabled_plugins_files(Config), - RabbitConfigBaseDir = proplists:get_value(rabbit_config_base_dir, Config), - create_enabled_plugins_file(Config, RabbitConfigBaseDir, 8#400); -init_per_testcase(_, Config) -> - Config. - -end_per_testcase(_, Config) -> - Config. - -check_enabled_plugins_file_passthrough(_) -> - Context = #{enabled_plugins_file => "/some/dir/enabled_plugins"}, - ?assertMatch(#{enabled_plugins_file := "/some/dir/enabled_plugins"}, - rabbit_plugins:maybe_migrate_enabled_plugins_file(Context)). - -check_enabled_plugins_file_modern(Config) -> - DataDir = proplists:get_value(rabbit_data_dir, Config), - ConfigBaseDir = proplists:get_value(rabbit_config_base_dir, Config), - ExpectedLocation = filename:join(DataDir, "enabled_plugins"), - true = filelib:is_regular(ExpectedLocation), - - Context = #{os_type => {unix, linux}, - config_base_dir => ConfigBaseDir, - data_dir => DataDir, - enabled_plugins_file => undefined}, - ?assertMatch(#{enabled_plugins_file := ExpectedLocation}, - rabbit_plugins:maybe_migrate_enabled_plugins_file(Context)). - -check_enabled_plugins_file_default(Config) -> - DataDir = proplists:get_value(rabbit_data_dir, Config), - ConfigBaseDir = proplists:get_value(rabbit_config_base_dir, Config), - ExpectedLocation = filename:join(DataDir, "enabled_plugins"), - false = filelib:is_regular(ExpectedLocation), - false = filelib:is_regular(filename:join(ConfigBaseDir, "enabled_plugins")), - - Context = #{os_type => {unix, linux}, - config_base_dir => ConfigBaseDir, - data_dir => DataDir, - enabled_plugins_file => undefined}, - ?assertMatch(#{enabled_plugins_file := ExpectedLocation}, - rabbit_plugins:maybe_migrate_enabled_plugins_file(Context)). - -check_enabled_plugins_file_legacy(Config) -> - DataDir = proplists:get_value(rabbit_data_dir, Config), - ConfigBaseDir = proplists:get_value(rabbit_config_base_dir, Config), - false = filelib:is_regular(filename:join(DataDir, "enabled_plugins")), - ExpectedLocation = filename:join(ConfigBaseDir, "enabled_plugins"), - {ok, #file_info{access = read_write}} = file:read_file_info(ExpectedLocation), - - Context = #{os_type => {unix, linux}, - config_base_dir => ConfigBaseDir, - data_dir => DataDir, - enabled_plugins_file => undefined}, - ?assertMatch(#{enabled_plugins_file := ExpectedLocation}, - rabbit_plugins:maybe_migrate_enabled_plugins_file(Context)). - -check_enabled_plugins_file_copy(Config) -> - DataDir = proplists:get_value(rabbit_data_dir, Config), - ConfigBaseDir = proplists:get_value(rabbit_config_base_dir, Config), - ExpectedLocation = filename:join(DataDir, "enabled_plugins"), - false = filelib:is_regular(ExpectedLocation), - {ok, #file_info{access = read}} = file:read_file_info( - filename:join(ConfigBaseDir, - "enabled_plugins")), - - Context = #{os_type => {unix, linux}, - config_base_dir => ConfigBaseDir, - data_dir => DataDir, - enabled_plugins_file => undefined}, - ?assertMatch(#{enabled_plugins_file := ExpectedLocation}, - rabbit_plugins:maybe_migrate_enabled_plugins_file(Context)), - {ok, File} = file:read_file(ExpectedLocation), - ?assertEqual("[rabbitmq_management].", unicode:characters_to_list(File)). - -create_enabled_plugins_file(Config, Location, Perm) -> - EnabledPluginsFile = filename:join(Location, "enabled_plugins"), - FileContent = io_lib:format("[rabbitmq_management].", []), - ok = file:write_file(EnabledPluginsFile, FileContent), - ok = file:change_mode(EnabledPluginsFile, Perm), - [{enabled_plugins_file, EnabledPluginsFile} | Config]. - -cleanup_enabled_plugins_files(Config) -> - LegacyFile = proplists:get_value(legacy_file, Config), - ok = delete_if_present(LegacyFile), - ok = filelib:ensure_dir(LegacyFile), - ModernFile = proplists:get_value(modern_file, Config), - ok = delete_if_present(ModernFile), - ok = filelib:ensure_dir(ModernFile), - ok. - -delete_if_present(Filename) -> - case file:read_file_info(Filename) of - {ok, #file_info{type = regular}} -> - file:delete(Filename); - {ok, _} -> - {error, not_regular_file}; - _ -> - ok - end. diff --git a/test/rabbit_prelaunch_plugins_SUITE.erl b/test/rabbit_prelaunch_plugins_SUITE.erl new file mode 100644 index 0000000000..de9e02980f --- /dev/null +++ b/test/rabbit_prelaunch_plugins_SUITE.erl @@ -0,0 +1,188 @@ +%% 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 +%% https://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 Developer of the Original Code is GoPivotal, Inc. +%% Copyright (c) 2019-2020 VMware, Inc. or its affiliates. All rights reserved. +%% + +-module(rabbit_prelaunch_plugins_SUITE). + +-include_lib("common_test/include/ct.hrl"). +-include_lib("eunit/include/eunit.hrl"). +-include_lib("kernel/include/file.hrl"). + +-compile(export_all). + +-export([all/0, + suite/0, + groups/0, + init_per_group/2, + end_per_group/2, + init_per_testcase/2, + end_per_testcase/2, + check_enabled_plugins_file_passthrough/1, + check_enabled_plugins_file_modern/1, + check_enabled_plugins_file_default/1, + check_enabled_plugins_file_legacy/1, + check_enabled_plugins_file_copy/1]). + +all() -> + [ + {group, maybe_migrate_enabled_plugins_file_tests} + ]. + +suite() -> + [{timetrap, {seconds, 10}}]. + +groups() -> + [ + {maybe_migrate_enabled_plugins_file_tests, [], + [ + check_enabled_plugins_file_passthrough, + check_enabled_plugins_file_modern, + check_enabled_plugins_file_default, + check_enabled_plugins_file_legacy, + check_enabled_plugins_file_copy + ]} + ]. + +init_per_group(maybe_migrate_enabled_plugins_file_tests, Config) -> + case os:type() of + {unix, _} -> + PrivDir = proplists:get_value(priv_dir, Config), + RabbitConfigBaseDir = filename:join([PrivDir, "etc", "rabbitmq"]), + LegacyFile = filename:join(RabbitConfigBaseDir, "enabled_plugins"), + RabbitDataDir = filename:join([PrivDir, "var", "lib", "rabbitmq"]), + ModernFile = filename:join(RabbitDataDir, "enabled_plugins"), + [{rabbit_config_base_dir, RabbitConfigBaseDir}, + {rabbit_data_dir, RabbitDataDir}, + {legacy_file, LegacyFile}, + {modern_file, ModernFile} | Config]; + _ -> + {skip, "enabled_plugins file fallback behavior does not apply to Windows"} + end; +init_per_group(_, Config) -> + Config. + +end_per_group(_, Config) -> + Config. + +init_per_testcase(check_enabled_plugins_file_modern, Config) -> + ok = cleanup_enabled_plugins_files(Config), + RabbitDataDir = proplists:get_value(rabbit_data_dir, Config), + create_enabled_plugins_file(Config, RabbitDataDir, 8#600); +init_per_testcase(check_enabled_plugins_file_default, Config) -> + ok = cleanup_enabled_plugins_files(Config), + Config; +init_per_testcase(check_enabled_plugins_file_legacy, Config) -> + ok = cleanup_enabled_plugins_files(Config), + RabbitConfigBaseDir = proplists:get_value(rabbit_config_base_dir, Config), + create_enabled_plugins_file(Config, RabbitConfigBaseDir, 8#600); +init_per_testcase(check_enabled_plugins_file_copy, Config) -> + ok = cleanup_enabled_plugins_files(Config), + RabbitConfigBaseDir = proplists:get_value(rabbit_config_base_dir, Config), + create_enabled_plugins_file(Config, RabbitConfigBaseDir, 8#400); +init_per_testcase(_, Config) -> + Config. + +end_per_testcase(_, Config) -> + Config. + +check_enabled_plugins_file_passthrough(_) -> + Context = #{enabled_plugins_file => "/some/dir/enabled_plugins"}, + ?assertMatch(#{enabled_plugins_file := "/some/dir/enabled_plugins"}, + rabbit_prelaunch_plugins:maybe_migrate_enabled_plugins_file(Context)). + +check_enabled_plugins_file_modern(Config) -> + DataDir = proplists:get_value(rabbit_data_dir, Config), + ConfigBaseDir = proplists:get_value(rabbit_config_base_dir, Config), + ExpectedLocation = filename:join(DataDir, "enabled_plugins"), + true = filelib:is_regular(ExpectedLocation), + + Context = #{os_type => {unix, linux}, + config_base_dir => ConfigBaseDir, + data_dir => DataDir, + enabled_plugins_file => undefined}, + ?assertMatch(#{enabled_plugins_file := ExpectedLocation}, + rabbit_prelaunch_plugins:maybe_migrate_enabled_plugins_file(Context)). + +check_enabled_plugins_file_default(Config) -> + DataDir = proplists:get_value(rabbit_data_dir, Config), + ConfigBaseDir = proplists:get_value(rabbit_config_base_dir, Config), + ExpectedLocation = filename:join(DataDir, "enabled_plugins"), + false = filelib:is_regular(ExpectedLocation), + false = filelib:is_regular(filename:join(ConfigBaseDir, "enabled_plugins")), + + Context = #{os_type => {unix, linux}, + config_base_dir => ConfigBaseDir, + data_dir => DataDir, + enabled_plugins_file => undefined}, + ?assertMatch(#{enabled_plugins_file := ExpectedLocation}, + rabbit_prelaunch_plugins:maybe_migrate_enabled_plugins_file(Context)). + +check_enabled_plugins_file_legacy(Config) -> + DataDir = proplists:get_value(rabbit_data_dir, Config), + ConfigBaseDir = proplists:get_value(rabbit_config_base_dir, Config), + false = filelib:is_regular(filename:join(DataDir, "enabled_plugins")), + ExpectedLocation = filename:join(ConfigBaseDir, "enabled_plugins"), + {ok, #file_info{access = read_write}} = file:read_file_info(ExpectedLocation), + + Context = #{os_type => {unix, linux}, + config_base_dir => ConfigBaseDir, + data_dir => DataDir, + enabled_plugins_file => undefined}, + ?assertMatch(#{enabled_plugins_file := ExpectedLocation}, + rabbit_prelaunch_plugins:maybe_migrate_enabled_plugins_file(Context)). + +check_enabled_plugins_file_copy(Config) -> + DataDir = proplists:get_value(rabbit_data_dir, Config), + ConfigBaseDir = proplists:get_value(rabbit_config_base_dir, Config), + ExpectedLocation = filename:join(DataDir, "enabled_plugins"), + false = filelib:is_regular(ExpectedLocation), + {ok, #file_info{access = read}} = file:read_file_info( + filename:join(ConfigBaseDir, + "enabled_plugins")), + + Context = #{os_type => {unix, linux}, + config_base_dir => ConfigBaseDir, + data_dir => DataDir, + enabled_plugins_file => undefined}, + ?assertMatch(#{enabled_plugins_file := ExpectedLocation}, + rabbit_prelaunch_plugins:maybe_migrate_enabled_plugins_file(Context)), + {ok, File} = file:read_file(ExpectedLocation), + ?assertEqual("[rabbitmq_management].", unicode:characters_to_list(File)). + +create_enabled_plugins_file(Config, Location, Perm) -> + EnabledPluginsFile = filename:join(Location, "enabled_plugins"), + FileContent = io_lib:format("[rabbitmq_management].", []), + ok = file:write_file(EnabledPluginsFile, FileContent), + ok = file:change_mode(EnabledPluginsFile, Perm), + [{enabled_plugins_file, EnabledPluginsFile} | Config]. + +cleanup_enabled_plugins_files(Config) -> + LegacyFile = proplists:get_value(legacy_file, Config), + ok = delete_if_present(LegacyFile), + ok = filelib:ensure_dir(LegacyFile), + ModernFile = proplists:get_value(modern_file, Config), + ok = delete_if_present(ModernFile), + ok = filelib:ensure_dir(ModernFile), + ok. + +delete_if_present(Filename) -> + case file:read_file_info(Filename) of + {ok, #file_info{type = regular}} -> + file:delete(Filename); + {ok, _} -> + {error, not_regular_file}; + _ -> + ok + end. -- cgit v1.2.1