提交 bfb4e8f3 编写于 作者: K KochetovNicolai 提交者: alexey-milovidov

zookeeper chroot fix (#1430)

* added root and identity section to zookeeper configuration [#CLICKHOUSE-3031]

* added root and identity section to zookeeper configuration [#CLICKHOUSE-3031]

* moved root section in zookeeper configuration [#CLICKHOUSE-3031]

* fixed root section in zookeeper configuration [#CLICKHOUSE-3031]

* added tests [#CLICKHOUSE-3031]

* replaced tabs to spaces in config files [#CLICKHOUSE-3031]

* fix build [#CLICKHOUSE-3031]

* added chech that root starts with '/' in zookeeper config file [#CLICKHOUSE-3031]

* added comments [#CLICKHOUSE-3031]

* Check if zookeeper chroot exists before start. Remove tailing slash form chroot. [#CLICKHOUSE-3400]

* added starting '/' to zookeeper path in ReplicatedMergeTree
上级 9fb4e862
......@@ -71,7 +71,8 @@ void ZooKeeper::processCallback(zhandle_t * zh, int type, int state, const char
destroyContext(context);
}
void ZooKeeper::init(const std::string & hosts_, const std::string & identity_, int32_t session_timeout_ms_)
void ZooKeeper::init(const std::string & hosts_, const std::string & identity_,
int32_t session_timeout_ms_, bool check_root_exists)
{
log = &Logger::get("ZooKeeper");
zoo_set_debug_level(ZOO_LOG_LEVEL_ERROR);
......@@ -87,7 +88,7 @@ void ZooKeeper::init(const std::string & hosts_, const std::string & identity_,
if (!identity.empty())
{
auto code = zoo_add_auth(impl, "digest", identity.c_str(), static_cast<int>(identity.size()), 0, 0);
auto code = zoo_add_auth(impl, "digest", identity.c_str(), static_cast<int>(identity.size()), nullptr, nullptr);
if (code != ZOK)
throw KeeperException("Zookeeper authentication failed. Hosts are " + hosts, code);
......@@ -97,11 +98,15 @@ void ZooKeeper::init(const std::string & hosts_, const std::string & identity_,
default_acl = &ZOO_OPEN_ACL_UNSAFE;
LOG_TRACE(log, "initialized, hosts: " << hosts);
if (check_root_exists && !exists("/"))
throw KeeperException("Zookeeper root doesn't exist. You should create root node before start.");
}
ZooKeeper::ZooKeeper(const std::string & hosts, const std::string & identity, int32_t session_timeout_ms)
ZooKeeper::ZooKeeper(const std::string & hosts, const std::string & identity,
int32_t session_timeout_ms, bool check_root_exists)
{
init(hosts, identity, session_timeout_ms);
init(hosts, identity, session_timeout_ms, check_root_exists);
}
struct ZooKeeperArgs
......@@ -115,6 +120,7 @@ struct ZooKeeperArgs
std::string root;
session_timeout_ms = DEFAULT_SESSION_TIMEOUT;
has_chroot = false;
for (const auto & key : keys)
{
if (startsWith(key, "node"))
......@@ -154,19 +160,24 @@ struct ZooKeeperArgs
{
if (root.front() != '/')
throw KeeperException(std::string("Root path in config file should start with '/', but got ") + root);
if (root.back() == '/')
root.pop_back();
hosts += root;
has_chroot = true;
}
}
std::string hosts;
std::string identity;
int session_timeout_ms;
bool has_chroot;
};
ZooKeeper::ZooKeeper(const Poco::Util::AbstractConfiguration & config, const std::string & config_name)
{
ZooKeeperArgs args(config, config_name);
init(args.hosts, args.identity, args.session_timeout_ms);
init(args.hosts, args.identity, args.session_timeout_ms, args.has_chroot);
}
WatchCallback ZooKeeper::callbackForEvent(const EventPtr & event)
......
......@@ -54,7 +54,8 @@ class ZooKeeper
public:
using Ptr = std::shared_ptr<ZooKeeper>;
ZooKeeper(const std::string & hosts, const std::string & identity = "", int32_t session_timeout_ms = DEFAULT_SESSION_TIMEOUT);
ZooKeeper(const std::string & hosts, const std::string & identity = "",
int32_t session_timeout_ms = DEFAULT_SESSION_TIMEOUT, bool check_root_exists = false);
/** Config of the form:
<zookeeper>
......@@ -357,7 +358,8 @@ private:
friend struct WatchContext;
friend class EphemeralNodeHolder;
void init(const std::string & hosts, const std::string & identity, int32_t session_timeout_ms);
void init(const std::string & hosts, const std::string & identity,
int32_t session_timeout_ms, bool check_root_exists);
void removeChildrenRecursive(const std::string & path);
void tryRemoveChildrenRecursive(const std::string & path);
......
......@@ -211,6 +211,9 @@ StorageReplicatedMergeTree::StorageReplicatedMergeTree(
{
if (!zookeeper_path.empty() && zookeeper_path.back() == '/')
zookeeper_path.resize(zookeeper_path.size() - 1);
/// If zookeeper chroot prefix is used, path should starts with '/', because chroot concatenates without it.
if (!zookeeper_path.empty() && zookeeper_path.front() != '/')
zookeeper_path = "/" + zookeeper_path;
replica_path = zookeeper_path + "/replicas/" + replica_name;
bool skip_sanity_checks = false;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册