diff options
author | Wladimir J. van der Laan <laanwj@gmail.com> | 2018-05-09 06:31:11 +0200 |
---|---|---|
committer | Wladimir J. van der Laan <laanwj@gmail.com> | 2018-05-09 06:36:54 +0200 |
commit | 7b966d9e6e30f39731ef511cfa3255652543b55d (patch) | |
tree | 6a586fa13c4e10f06628f232f012b03eaabd6a03 /src | |
parent | 6b824c090f53d0a56833930fd38c41bcaec8ff4a (diff) | |
parent | 25b7ab9c02f691be6c1aa71a9cf51ac1a6ea9db4 (diff) |
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
Diffstat (limited to 'src')
-rw-r--r-- | src/bitcoin-cli.cpp | 2 | ||||
-rw-r--r-- | src/bitcoind.cpp | 2 | ||||
-rw-r--r-- | src/init.cpp | 1 | ||||
-rw-r--r-- | src/interfaces/node.cpp | 2 | ||||
-rw-r--r-- | src/interfaces/node.h | 2 | ||||
-rw-r--r-- | src/qt/bitcoin.cpp | 2 | ||||
-rw-r--r-- | src/util.cpp | 35 | ||||
-rw-r--r-- | src/util.h | 2 |
8 files changed, 41 insertions, 7 deletions
diff --git a/src/bitcoin-cli.cpp b/src/bitcoin-cli.cpp index 34472a0e61..05a5079a5a 100644 --- a/src/bitcoin-cli.cpp +++ b/src/bitcoin-cli.cpp @@ -107,7 +107,7 @@ static int AppInitRPC(int argc, char* argv[]) return EXIT_FAILURE; } try { - gArgs.ReadConfigFile(gArgs.GetArg("-conf", BITCOIN_CONF_FILENAME)); + gArgs.ReadConfigFiles(); } catch (const std::exception& e) { fprintf(stderr,"Error reading configuration file: %s\n", e.what()); return EXIT_FAILURE; diff --git a/src/bitcoind.cpp b/src/bitcoind.cpp index 69de1a1666..32b67cabb9 100644 --- a/src/bitcoind.cpp +++ b/src/bitcoind.cpp @@ -92,7 +92,7 @@ static bool AppInit(int argc, char* argv[]) } try { - gArgs.ReadConfigFile(gArgs.GetArg("-conf", BITCOIN_CONF_FILENAME)); + gArgs.ReadConfigFiles(); } catch (const std::exception& e) { fprintf(stderr,"Error reading configuration file: %s\n", e.what()); return false; diff --git a/src/init.cpp b/src/init.cpp index 7d8f462ef1..010174bbdc 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -376,6 +376,7 @@ std::string HelpMessage(HelpMessageMode mode) strUsage += HelpMessageOpt("-debuglogfile=<file>", strprintf(_("Specify location of debug log file. Relative paths will be prefixed by a net-specific datadir location. (default: %s)"), DEFAULT_DEBUGLOGFILE)); if (showDebug) strUsage += HelpMessageOpt("-feefilter", strprintf("Tell other nodes to filter invs to us by our mempool min fee (default: %u)", DEFAULT_FEEFILTER)); + strUsage += HelpMessageOpt("-includeconf=<file>", _("Specify additional configuration file, relative to the -datadir path (only useable from configuration file, not command line)")); strUsage += HelpMessageOpt("-loadblock=<file>", _("Imports blocks from external blk000??.dat file on startup")); strUsage += HelpMessageOpt("-maxmempool=<n>", strprintf(_("Keep the transaction memory pool below <n> megabytes (default: %u)"), DEFAULT_MAX_MEMPOOL_SIZE)); strUsage += HelpMessageOpt("-maxorphantx=<n>", strprintf(_("Keep at most <n> unconnectable transactions in memory (default: %u)"), DEFAULT_MAX_ORPHAN_TRANSACTIONS)); diff --git a/src/interfaces/node.cpp b/src/interfaces/node.cpp index 53d2359caf..7f90a38483 100644 --- a/src/interfaces/node.cpp +++ b/src/interfaces/node.cpp @@ -52,7 +52,7 @@ class NodeImpl : public Node { gArgs.ParseParameters(argc, argv); } - void readConfigFile(const std::string& conf_path) override { gArgs.ReadConfigFile(conf_path); } + void readConfigFiles() override { gArgs.ReadConfigFiles(); } bool softSetArg(const std::string& arg, const std::string& value) override { return gArgs.SoftSetArg(arg, value); } bool softSetBoolArg(const std::string& arg, bool value) override { return gArgs.SoftSetBoolArg(arg, value); } void selectParams(const std::string& network) override { SelectParams(network); } diff --git a/src/interfaces/node.h b/src/interfaces/node.h index 3cebe53eb0..d9a48e2563 100644 --- a/src/interfaces/node.h +++ b/src/interfaces/node.h @@ -48,7 +48,7 @@ public: virtual bool softSetBoolArg(const std::string& arg, bool value) = 0; //! Load settings from configuration file. - virtual void readConfigFile(const std::string& conf_path) = 0; + virtual void readConfigFiles() = 0; //! Choose network parameters. virtual void selectParams(const std::string& network) = 0; diff --git a/src/qt/bitcoin.cpp b/src/qt/bitcoin.cpp index 57fe4552a1..c0fb641b1c 100644 --- a/src/qt/bitcoin.cpp +++ b/src/qt/bitcoin.cpp @@ -616,7 +616,7 @@ int main(int argc, char *argv[]) return EXIT_FAILURE; } try { - node->readConfigFile(gArgs.GetArg("-conf", BITCOIN_CONF_FILENAME)); + node->readConfigFiles(); } catch (const std::exception& e) { QMessageBox::critical(0, QObject::tr(PACKAGE_NAME), QObject::tr("Error: Cannot parse configuration file: %1. Only use key=value syntax.").arg(e.what())); diff --git a/src/util.cpp b/src/util.cpp index b4d0a61ab2..b8723f83c6 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -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: diff --git a/src/util.h b/src/util.h index 2da8023285..186245c94a 100644 --- a/src/util.h +++ b/src/util.h @@ -140,7 +140,7 @@ public: void SelectConfigNetwork(const std::string& network); void ParseParameters(int argc, const char*const argv[]); - void ReadConfigFile(const std::string& confPath); + void ReadConfigFiles(); /** * Log warnings for options in m_section_only_args when |