diff options
| author | Michael Klishin <michael@novemberain.com> | 2016-03-24 00:29:04 +0300 |
|---|---|---|
| committer | Michael Klishin <michael@novemberain.com> | 2016-03-24 00:29:04 +0300 |
| commit | 117a20bc2383d6ee841547468fb615f34e4916f5 (patch) | |
| tree | 3c3c3f43ec6506980334d0180cff8fa6a70e79e8 /src | |
| parent | a5a24d32733e80e0ab1b5383d17bb405bd58d743 (diff) | |
| parent | 2b9b292de4e2f31f49fc9b9e99396aa47c1c8d53 (diff) | |
| download | rabbitmq-server-git-117a20bc2383d6ee841547468fb615f34e4916f5.tar.gz | |
Merge pull request #575 from rabbitmq/rabbitmq-server-550
Support new configuration format
Diffstat (limited to 'src')
| -rw-r--r-- | src/rabbit.erl | 42 | ||||
| -rw-r--r-- | src/rabbit_config.erl | 179 | ||||
| -rw-r--r-- | src/rabbit_plugins.erl | 47 | ||||
| -rw-r--r-- | src/rabbit_prelaunch.erl | 12 |
4 files changed, 253 insertions, 27 deletions
diff --git a/src/rabbit.erl b/src/rabbit.erl index 3dbee29543..7816cd53aa 100644 --- a/src/rabbit.erl +++ b/src/rabbit.erl @@ -272,6 +272,7 @@ start() -> boot() -> start_it(fun() -> + ensure_config(), ok = ensure_application_loaded(), HipeResult = rabbit_hipe:maybe_hipe_compile(), ok = start_logger(), @@ -285,6 +286,20 @@ boot() -> broker_start() end). +ensure_config() -> + case rabbit_config:prepare_and_use_config() of + {error, Reason} -> + {Format, Arg} = case Reason of + {generation_error, Error} -> {"~s", [Error]}; + Other -> {"~p", [Other]} + end, + log_boot_error_and_exit(generate_config_file, + "~nConfig file generation failed "++Format, + Arg); + ok -> ok + end. + + broker_start() -> Plugins = rabbit_plugins:setup(), ToBeLoaded = Plugins ++ ?APPS, @@ -902,32 +917,7 @@ home_dir() -> end. config_files() -> - Abs = fun (F) -> - filename:absname(filename:rootname(F, ".config") ++ ".config") - end, - case init:get_argument(config) of - {ok, Files} -> [Abs(File) || [File] <- Files]; - error -> case config_setting() of - none -> []; - File -> [Abs(File) ++ " (not found)"] - end - end. - -%% This is a pain. We want to know where the config file is. But we -%% can't specify it on the command line if it is missing or the VM -%% will fail to start, so we need to find it by some mechanism other -%% than init:get_arguments/0. We can look at the environment variable -%% which is responsible for setting it... but that doesn't work for a -%% Windows service since the variable can change and the service not -%% be reinstalled, so in that case we add a magic application env. -config_setting() -> - case application:get_env(rabbit, windows_service_config) of - {ok, File1} -> File1; - undefined -> case os:getenv("RABBITMQ_CONFIG_FILE") of - false -> none; - File2 -> File2 - end - end. + rabbit_config:config_files(). %% We don't want this in fhc since it references rabbit stuff. And we can't put %% this in the bootstep directly. diff --git a/src/rabbit_config.erl b/src/rabbit_config.erl new file mode 100644 index 0000000000..67e7523ec0 --- /dev/null +++ b/src/rabbit_config.erl @@ -0,0 +1,179 @@ +-module(rabbit_config). + +-export([ + generate_config_file/5, + prepare_and_use_config/0, + prepare_config/1, + update_app_config/1, + schema_dir/0, + config_files/0, + get_advanced_config/0 + ]). + +prepare_and_use_config() -> + case legacy_erlang_term_config_used() of + true -> + %% Use .config file + ok; + false -> + case prepare_config(get_confs()) of + ok -> + %% No .conf to generate from + ok; + {ok, GeneratedConfigFile} -> + %% Generated config file + update_app_config(GeneratedConfigFile); + {error, Err} -> + {error, Err} + end + end. + +%% we support both the classic Erlang term +%% config file (rabbitmq.config) as well as rabbitmq.conf +legacy_erlang_term_config_used() -> + case init:get_argument(config) of + error -> false; + {ok, [Config | _]} -> + ConfigFile = Config ++ ".config", + rabbit_file:is_file(ConfigFile) + andalso + get_advanced_config() == none + end. + +get_confs() -> + case init:get_argument(conf) of + {ok, Configs} -> Configs; + _ -> [] + end. + +prepare_config(Configs) -> + case {init:get_argument(conf_dir), init:get_argument(conf_script_dir)} of + {{ok, ConfDir}, {ok, ScriptDir}} -> + ConfFiles = [Config ++ ".conf" || [Config] <- Configs, + rabbit_file:is_file(Config ++ + ".conf")], + case ConfFiles of + [] -> ok; + _ -> + case generate_config_file(ConfFiles, ConfDir, ScriptDir) of + {ok, GeneratedConfigFile} -> + {ok, GeneratedConfigFile}; + {error, Reason} -> + {error, Reason} + end + end; + _ -> ok + end. + +update_app_config(ConfigFile) -> + ok = application_controller:change_application_data([], [ConfigFile]). + +generate_config_file(ConfFiles, ConfDir, ScriptDir) -> + generate_config_file(ConfFiles, ConfDir, ScriptDir, + schema_dir(), get_advanced_config()). + + +generate_config_file(ConfFiles, ConfDir, ScriptDir, SchemaDir, Advanced) -> + prepare_plugin_schemas(SchemaDir), + % SchemaFile = filename:join([ScriptDir, "rabbitmq.schema"]), + Cuttlefish = filename:join([ScriptDir, "cuttlefish"]), + GeneratedDir = filename:join([ConfDir, "generated"]), + + AdvancedConfigArg = case check_advanced_config(Advanced) of + {ok, FileName} -> [" -a ", FileName]; + none -> [] + end, + rabbit_file:recursive_delete([GeneratedDir]), + Command = lists:concat(["escript ", "\"", Cuttlefish, "\"", + " -f rabbitmq -s ", "\"", SchemaDir, "\"", + " -e ", "\"", ConfDir, "\"", + [[" -c ", ConfFile] || ConfFile <- ConfFiles], + AdvancedConfigArg]), + Result = rabbit_misc:os_cmd(Command), + case string:str(Result, " -config ") of + 0 -> {error, {generation_error, Result}}; + _ -> + [OutFile] = rabbit_file:wildcard("rabbitmq.*.config", GeneratedDir), + ResultFile = filename:join([GeneratedDir, "rabbitmq.config"]), + rabbit_file:rename(filename:join([GeneratedDir, OutFile]), + ResultFile), + {ok, ResultFile} + end. + +schema_dir() -> + case init:get_argument(conf_schema_dir) of + {ok, SchemaDir} -> SchemaDir; + _ -> + case code:priv_dir(rabbit) of + {error, bad_name} -> filename:join([".", "priv", "schema"]); + PrivDir -> filename:join([PrivDir, "schema"]) + end + end. + +check_advanced_config(none) -> none; +check_advanced_config(ConfigName) -> + case rabbit_file:is_file(ConfigName) of + true -> {ok, ConfigName}; + false -> none + end. + +get_advanced_config() -> + case init:get_argument(conf_advanced) of + %% There can be only one advanced.config + {ok, [FileName | _]} -> + ConfigName = FileName ++ ".config", + case rabbit_file:is_file(ConfigName) of + true -> ConfigName; + false -> none + end; + _ -> none + end. + + +prepare_plugin_schemas(SchemaDir) -> + case rabbit_file:is_dir(SchemaDir) of + true -> rabbit_plugins:extract_schemas(SchemaDir); + false -> ok + end. + + +config_files() -> + Abs = fun (F, Ex) -> filename:absname(filename:rootname(F, Ex) ++ Ex) end, + case legacy_erlang_term_config_used() of + true -> + case init:get_argument(config) of + {ok, Files} -> [Abs(File, ".config") || [File] <- Files]; + error -> case config_setting() of + none -> []; + File -> [Abs(File, ".config") + ++ + " (not found)"] + end + end; + false -> + ConfFiles = [Abs(File, ".conf") || File <- get_confs()], + AdvancedFiles = case get_advanced_config() of + none -> []; + FileName -> [Abs(FileName, ".config")] + end, + AdvancedFiles ++ ConfFiles + + end. + + +%% This is a pain. We want to know where the config file is. But we +%% can't specify it on the command line if it is missing or the VM +%% will fail to start, so we need to find it by some mechanism other +%% than init:get_arguments/0. We can look at the environment variable +%% which is responsible for setting it... but that doesn't work for a +%% Windows service since the variable can change and the service not +%% be reinstalled, so in that case we add a magic application env. +config_setting() -> + case application:get_env(rabbit, windows_service_config) of + {ok, File1} -> File1; + undefined -> case os:getenv("RABBITMQ_CONFIG_FILE") of + false -> none; + File2 -> File2 + end + end. + diff --git a/src/rabbit_plugins.erl b/src/rabbit_plugins.erl index c7f5d501bf..2f084ed28a 100644 --- a/src/rabbit_plugins.erl +++ b/src/rabbit_plugins.erl @@ -16,9 +16,11 @@ -module(rabbit_plugins). -include("rabbit.hrl"). +-include_lib("stdlib/include/zip.hrl"). -export([setup/0, active/0, read_enabled/1, list/1, list/2, dependencies/3]). -export([ensure/1]). +-export([extract_schemas/1]). %%---------------------------------------------------------------------------- @@ -46,6 +48,7 @@ ensure(FileJustChanged0) -> FileJustChanged -> Enabled = read_enabled(OurFile), Wanted = prepare_plugins(Enabled), + rabbit_config:prepare_and_use_config(), Current = active(), Start = Wanted -- Current, Stop = Current -- Wanted, @@ -79,6 +82,50 @@ setup() -> Enabled = read_enabled(EnabledFile), prepare_plugins(Enabled). +extract_schemas(SchemaDir) -> + application:load(rabbit), + {ok, EnabledFile} = application:get_env(rabbit, enabled_plugins_file), + Enabled = read_enabled(EnabledFile), + + {ok, PluginsDistDir} = application:get_env(rabbit, plugins_dir), + + AllPlugins = list(PluginsDistDir), + Wanted = dependencies(false, Enabled, AllPlugins), + WantedPlugins = lookup_plugins(Wanted, AllPlugins), + [ extract_schema(Plugin, SchemaDir) || Plugin <- WantedPlugins ], + application:unload(rabbit), + ok. + +extract_schema(#plugin{type = ez, location = Location}, SchemaDir) -> + {ok, Files} = zip:extract(Location, + [memory, {file_filter, + fun(#zip_file{name = Name}) -> + string:str(Name, "priv/schema") > 0 + end}]), + lists:foreach( + fun({FileName, Content}) -> + ok = file:write_file(filename:join([SchemaDir, + filename:basename(FileName)]), + Content) + end, + Files), + ok; +extract_schema(#plugin{type = dir, location = Location}, SchemaDir) -> + PluginSchema = filename:join([Location, + "priv", + "schema"]), + case rabbit_file:is_dir(PluginSchema) of + false -> ok; + true -> + PluginSchemaFiles = + [ filename:join(PluginSchema, FileName) + || FileName <- rabbit_file:wildcard(".*\\.schema", + PluginSchema) ], + [ file:copy(SchemaFile, SchemaDir) + || SchemaFile <- PluginSchemaFiles ] + end. + + %% @doc Lists the plugins which are currently running. active() -> {ok, ExpandDir} = application:get_env(rabbit, plugins_expand_dir), diff --git a/src/rabbit_prelaunch.erl b/src/rabbit_prelaunch.erl index 5ecdd75acc..3f83a153ea 100644 --- a/src/rabbit_prelaunch.erl +++ b/src/rabbit_prelaunch.erl @@ -83,7 +83,7 @@ dist_port_set_check() -> false -> ok; File -> - case file:consult(File ++ ".config") of + case get_config(File) of {ok, [Config]} -> Kernel = pget(kernel, Config, []), case {pget(inet_dist_listen_min, Kernel, none), @@ -98,6 +98,16 @@ dist_port_set_check() -> end end. +get_config(File) -> + case rabbit_file:is_file(File ++ ".config") of + true -> file:consult(File ++ ".config"); + false -> + case rabbit_config:get_advanced_config() of + none -> {error, enoent}; + FileName -> file:consult(FileName) + end + end. + dist_port_range_check() -> case os:getenv("RABBITMQ_DIST_PORT") of false -> ok; |
