Skip to content

Commit 81a654b

Browse files
authored
Merge pull request ClickHouse#78725 from azat/extract-from-config-better-try
Ignore non existing include_from files with --try for clickhouse-extract-from-config
2 parents d34ae88 + 3d2cc20 commit 81a654b

8 files changed

+80
-28
lines changed

programs/extract-from-config/ExtractFromConfig.cpp

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ static void setupLogging(const std::string & log_level)
4141
}
4242

4343

44-
static std::vector<std::string> extactFromConfigAccordingToGlobs(DB::ConfigurationPtr configuration, const std::string & pattern, bool try_get)
44+
static std::vector<std::string> extactFromConfigAccordingToGlobs(DB::ConfigurationPtr configuration, const std::string & pattern, bool ignore_errors)
4545
{
4646
auto pattern_prefix = pattern.substr(0, pattern.find_first_of("*?{"));
4747
boost::algorithm::trim_if(pattern_prefix, [](char s){ return s == '.'; });
@@ -68,7 +68,7 @@ static std::vector<std::string> extactFromConfigAccordingToGlobs(DB::Configurati
6868
continue;
6969

7070

71-
if (try_get)
71+
if (ignore_errors)
7272
{
7373
auto value = configuration->getString(node, "");
7474
if (!value.empty())
@@ -90,9 +90,13 @@ static std::vector<std::string> extactFromConfigAccordingToGlobs(DB::Configurati
9090
}
9191

9292

93-
static DB::ConfigurationPtr get_configuration(const std::string & config_path, bool process_zk_includes)
93+
static DB::ConfigurationPtr get_configuration(const std::string & config_path, bool process_zk_includes, bool throw_on_bad_include_from)
9494
{
95-
DB::ConfigProcessor processor(config_path, /* throw_on_bad_incl = */ false, /* log_to_console = */ false);
95+
DB::ConfigProcessor processor(config_path,
96+
/* throw_on_bad_incl = */ false,
97+
/* log_to_console = */ false,
98+
/* substitutions= */ {},
99+
/* throw_on_bad_include_from= */ throw_on_bad_include_from);
96100
bool has_zk_includes;
97101
DB::XMLDocumentPtr config_xml = processor.processConfig(&has_zk_includes);
98102
if (has_zk_includes && process_zk_includes)
@@ -111,30 +115,29 @@ static DB::ConfigurationPtr get_configuration(const std::string & config_path, b
111115
}
112116

113117

114-
static std::vector<std::string> extractFromConfig(
115-
const std::string & config_path, const std::string & key, bool process_zk_includes, bool try_get = false, bool get_users = false)
118+
static std::vector<std::string> extractFromConfig(const std::string & config_path, const std::string & key, bool process_zk_includes, bool ignore_errors, bool get_users)
116119
{
117-
DB::ConfigurationPtr configuration = get_configuration(config_path, process_zk_includes);
120+
DB::ConfigurationPtr configuration = get_configuration(config_path, process_zk_includes, !ignore_errors);
118121

119122
if (get_users)
120123
{
121124
bool has_user_directories = configuration->has("user_directories");
122-
if (!has_user_directories && !try_get)
125+
if (!has_user_directories && !ignore_errors)
123126
throw DB::Exception(DB::ErrorCodes::CANNOT_LOAD_CONFIG, "Can't load config for users");
124127

125128
std::string users_config_path = configuration->getString("user_directories.users_xml.path");
126129
const auto config_dir = fs::path{config_path}.remove_filename().string();
127130
if (fs::path(users_config_path).is_relative() && fs::exists(fs::path(config_dir) / users_config_path))
128131
users_config_path = fs::path(config_dir) / users_config_path;
129-
configuration = get_configuration(users_config_path, process_zk_includes);
132+
configuration = get_configuration(users_config_path, process_zk_includes, !ignore_errors);
130133
}
131134

132135
/// Check if a key has globs.
133136
if (key.find_first_of("*?{") != std::string::npos)
134-
return extactFromConfigAccordingToGlobs(configuration, key, try_get);
137+
return extactFromConfigAccordingToGlobs(configuration, key, ignore_errors);
135138

136139
/// Do not throw exception if not found.
137-
if (try_get)
140+
if (ignore_errors)
138141
return {configuration->getString(key, "")};
139142
return {configuration->getString(key)};
140143
}
@@ -146,7 +149,7 @@ int mainEntryClickHouseExtractFromConfig(int argc, char ** argv)
146149
{
147150
bool print_stacktrace = false;
148151
bool process_zk_includes = false;
149-
bool try_get = false;
152+
bool ignore_errors = false;
150153
bool get_users = false;
151154
std::string log_level;
152155
std::string config_path;
@@ -160,7 +163,7 @@ int mainEntryClickHouseExtractFromConfig(int argc, char ** argv)
160163
("stacktrace", po::bool_switch(&print_stacktrace), "print stack traces of exceptions")
161164
("process-zk-includes", po::bool_switch(&process_zk_includes),
162165
"if there are from_zk elements in config, connect to ZooKeeper and process them")
163-
("try", po::bool_switch(&try_get), "Do not warn about missing keys")
166+
("try", po::bool_switch(&ignore_errors), "Do not warn about missing keys, missing users configurations or non existing file from include_from tag")
164167
("users", po::bool_switch(&get_users), "Return values from users.xml config")
165168
("log-level", po::value<std::string>(&log_level)->default_value("error"), "log level")
166169
("config-file,c", po::value<std::string>(&config_path)->required(), "path to config file")
@@ -175,7 +178,7 @@ int mainEntryClickHouseExtractFromConfig(int argc, char ** argv)
175178
po::variables_map options;
176179
po::store(po::command_line_parser(argc, argv).options(options_desc).positional(positional_desc).run(), options);
177180

178-
if (options.count("help"))
181+
if (options.contains("help"))
179182
{
180183
std::cerr << "Preprocess config file and extract value of the given key." << std::endl
181184
<< std::endl;
@@ -188,7 +191,7 @@ int mainEntryClickHouseExtractFromConfig(int argc, char ** argv)
188191
po::notify(options);
189192

190193
setupLogging(log_level);
191-
for (const auto & value : extractFromConfig(config_path, key, process_zk_includes, try_get, get_users))
194+
for (const auto & value : extractFromConfig(config_path, key, process_zk_includes, ignore_errors, get_users))
192195
std::cout << value << std::endl;
193196
}
194197
catch (...)

src/Common/Config/ConfigProcessor.cpp

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -68,9 +68,11 @@ ConfigProcessor::ConfigProcessor(
6868
const std::string & path_,
6969
bool throw_on_bad_incl_,
7070
bool log_to_console,
71-
const Substitutions & substitutions_)
71+
const Substitutions & substitutions_,
72+
bool throw_on_bad_include_from_)
7273
: path(path_)
7374
, throw_on_bad_incl(throw_on_bad_incl_)
75+
, throw_on_bad_include_from(throw_on_bad_include_from_)
7476
, substitutions(substitutions_)
7577
/// We need larger name pool to allow to support vast amount of users in users.xml files for ClickHouse.
7678
/// Size is prime because Poco::XML::NamePool uses bad (inefficient, low quality)
@@ -800,17 +802,24 @@ XMLDocumentPtr ConfigProcessor::processConfig(
800802
include_from_path = default_path;
801803
}
802804

803-
processIncludes(
804-
config,
805-
substitutions,
806-
include_from_path,
807-
throw_on_bad_incl,
808-
dom_parser,
809-
log,
810-
&contributing_zk_paths,
811-
&contributing_files,
812-
zk_node_cache,
813-
zk_changed_event);
805+
if (!throw_on_bad_include_from && !fs::exists(include_from_path))
806+
{
807+
LOG_WARNING(log, "File {} (from 'include_from') does not exist. Ignoring.", include_from_path);
808+
}
809+
else
810+
{
811+
processIncludes(
812+
config,
813+
substitutions,
814+
include_from_path,
815+
throw_on_bad_incl,
816+
dom_parser,
817+
log,
818+
&contributing_zk_paths,
819+
&contributing_files,
820+
zk_node_cache,
821+
zk_changed_event);
822+
}
814823
}
815824
catch (Exception & e)
816825
{

src/Common/Config/ConfigProcessor.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,8 @@ class ConfigProcessor
4444
const std::string & path,
4545
bool throw_on_bad_incl = false,
4646
bool log_to_console = false,
47-
const Substitutions & substitutions = Substitutions());
47+
const Substitutions & substitutions = Substitutions(),
48+
bool throw_on_bad_include_from = true);
4849

4950
/// Perform config includes and substitutions and return the resulting XML-document.
5051
///
@@ -146,6 +147,7 @@ class ConfigProcessor
146147
std::string preprocessed_path;
147148

148149
bool throw_on_bad_incl;
150+
bool throw_on_bad_include_from;
149151

150152
LoggerPtr log;
151153
Poco::AutoPtr<Poco::Channel> channel_ptr;
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
xml
2+
Not found: merge_tree.anything_xml
3+
4+
yaml
5+
Not found: merge_tree.anything_yaml
6+
7+
File not found: I hope such path will never exists, since it does not even contain a single slash
8+
I hope such path will never exists, since it does not even contain a single slash
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
#!/usr/bin/env bash
2+
3+
CUR_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
4+
# shellcheck source=../shell_config.sh
5+
. "$CUR_DIR"/../shell_config.sh
6+
7+
# NOTE: Cannot use CLICKHOUSE_EXTRACT_CONFIG, since it uses default config.
8+
9+
prefix=$CUR_DIR/"$(basename "${BASH_SOURCE[0]}" .sh)"
10+
11+
$CLICKHOUSE_BINARY extract-from-config --key merge_tree.comment --config $prefix.xml
12+
$CLICKHOUSE_BINARY extract-from-config --key merge_tree.anything_xml --config $prefix.xml |& grep -o 'Not found: merge_tree.anything_xml'
13+
$CLICKHOUSE_BINARY extract-from-config --key merge_tree.anything_xml --config $prefix.xml --try
14+
15+
$CLICKHOUSE_BINARY extract-from-config --key merge_tree.comment --config $prefix.yaml
16+
$CLICKHOUSE_BINARY extract-from-config --key merge_tree.anything_yaml --config $prefix.yaml |& grep -o 'Not found: merge_tree.anything_yaml'
17+
$CLICKHOUSE_BINARY extract-from-config --key merge_tree.anything_yaml --config $prefix.yaml --try
18+
19+
$CLICKHOUSE_BINARY extract-from-config --key include_from --config ${prefix}_bad_include_from.xml |& grep -o 'File not found: I hope such path will never exists, since it does not even contain a single slash'
20+
$CLICKHOUSE_BINARY extract-from-config --key include_from --config ${prefix}_bad_include_from.xml --try
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<clickhouse>
2+
<merge_tree>
3+
<comment>xml</comment>
4+
</merge_tree>
5+
</clickhouse>
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
merge_tree:
2+
comment: yaml
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
<clickhouse>
2+
<include_from>I hope such path will never exists, since it does not even contain a single slash</include_from>
3+
</clickhouse>

0 commit comments

Comments
 (0)