summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMichael Klishin <michael@novemberain.com>2016-03-24 00:29:04 +0300
committerMichael Klishin <michael@novemberain.com>2016-03-24 00:29:04 +0300
commit117a20bc2383d6ee841547468fb615f34e4916f5 (patch)
tree3c3c3f43ec6506980334d0180cff8fa6a70e79e8 /src
parenta5a24d32733e80e0ab1b5383d17bb405bd58d743 (diff)
parent2b9b292de4e2f31f49fc9b9e99396aa47c1c8d53 (diff)
downloadrabbitmq-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.erl42
-rw-r--r--src/rabbit_config.erl179
-rw-r--r--src/rabbit_plugins.erl47
-rw-r--r--src/rabbit_prelaunch.erl12
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;