Merge #10267: New -includeconf argument for including external configuration files

25b7ab9 doc: Add release notes for -includeconf (Karl-Johan Alm)
0f0badd test: Test includeconf parameter. (Karl-Johan Alm)
629ff8c -includeconf=<path> support in config handler, for including external configuration files (Karl-Johan Alm)

Pull request description:

  Fixes: #10071.

  Done:
  - adds `-includeconf=<path>`, where `<path>` is relative to `datadir` or to the path of the file being read, if in a file
  - protects against circular includes
  - updates help docs

  ~~~Thoughts:~~~
  - ~~~I am not sure how to test this in a neat manner. Feedback on this would be nice. Will dig/think though.~~~

Tree-SHA512: cb31f1b2f69fbc0890d264948eb2e501ac05cf12f5e06a5942f9c1539eb15ea8dc3cae817f4073aecb2fcc21d0386747f14f89d990772003a76e2a6d25642553
This commit is contained in:
Wladimir J. van der Laan
2018-05-09 06:31:11 +02:00
11 changed files with 133 additions and 7 deletions

View File

@@ -445,6 +445,17 @@ void ArgsManager::ParseParameters(int argc, const char* const argv[])
m_override_args[key].push_back(val);
}
}
// we do not allow -includeconf from command line, so we clear it here
auto it = m_override_args.find("-includeconf");
if (it != m_override_args.end()) {
if (it->second.size() > 0) {
for (const auto& ic : it->second) {
fprintf(stderr, "warning: -includeconf cannot be used from commandline; ignoring -includeconf=%s\n", ic.c_str());
}
m_override_args.erase(it);
}
}
}
std::vector<std::string> ArgsManager::GetArgs(const std::string& strArg) const
@@ -706,18 +717,40 @@ void ArgsManager::ReadConfigStream(std::istream& stream)
}
}
void ArgsManager::ReadConfigFile(const std::string& confPath)
void ArgsManager::ReadConfigFiles()
{
{
LOCK(cs_args);
m_config_args.clear();
}
const std::string confPath = GetArg("-conf", BITCOIN_CONF_FILENAME);
fs::ifstream stream(GetConfigFile(confPath));
// ok to not have a config file
if (stream.good()) {
ReadConfigStream(stream);
// if there is an -includeconf in the override args, but it is empty, that means the user
// passed '-noincludeconf' on the command line, in which case we should not include anything
if (m_override_args.count("-includeconf") == 0) {
std::vector<std::string> includeconf(GetArgs("-includeconf"));
{
// We haven't set m_network yet (that happens in SelectParams()), so manually check
// for network.includeconf args.
std::vector<std::string> includeconf_net(GetArgs(std::string("-") + GetChainName() + ".includeconf"));
includeconf.insert(includeconf.end(), includeconf_net.begin(), includeconf_net.end());
}
for (const std::string& to_include : includeconf) {
fs::ifstream include_config(GetConfigFile(to_include));
if (include_config.good()) {
ReadConfigStream(include_config);
LogPrintf("Included configuration file %s\n", to_include.c_str());
} else {
fprintf(stderr, "Failed to include configuration file %s\n", to_include.c_str());
}
}
}
}
// If datadir is changed in .conf file: