in apisix/cli/etcd.lua [288:393]
function _M.init(env, args)
local yaml_conf, err = file.read_yaml_conf(env.apisix_home)
if not yaml_conf then
util.die("failed to read local yaml config of apisix: ", err)
end
if not yaml_conf.apisix then
util.die("failed to read `apisix` field from yaml file when init etcd")
end
if yaml_conf.deployment.config_provider ~= "etcd" then
return true
end
if not yaml_conf.etcd then
util.die("failed to read `etcd` field from yaml file when init etcd")
end
if type(yaml_conf.etcd.host) == "string" then
yaml_conf.etcd.host = {yaml_conf.etcd.host}
end
local host_count = #(yaml_conf.etcd.host)
local scheme
for i = 1, host_count do
local host = yaml_conf.etcd.host[i]
local fields = util.split(host, "://")
if not fields then
util.die("malformed etcd endpoint: ", host, "\n")
end
if not scheme then
scheme = fields[1]
elseif scheme ~= fields[1] then
print([[WARNING: mixed protocols among etcd endpoints]])
end
end
local etcd_healthy_hosts = {}
for index, host in ipairs(yaml_conf.etcd.host) do
local version_url = host .. "/version"
local errmsg
local res, err
local retry_time = 0
local etcd = yaml_conf.etcd
local max_retry = tonumber(etcd.startup_retry) or 2
while retry_time < max_retry do
res, err = request(version_url, yaml_conf)
if res then
break
end
retry_time = retry_time + 1
print(str_format("Warning! Request etcd endpoint \'%s\' error, %s, retry time=%s",
version_url, err, retry_time))
end
if res then
local body, _, err = dkjson.decode(res)
if err or (body and not body["etcdcluster"]) then
errmsg = str_format("got malformed version message: \"%s\" from etcd \"%s\"\n", res,
version_url)
util.die(errmsg)
end
local cluster_version = body["etcdcluster"]
if compare_semantic_version(cluster_version, env.min_etcd_version) then
util.die("etcd cluster version ", cluster_version,
" is less than the required version ", env.min_etcd_version,
", please upgrade your etcd cluster\n")
end
table_insert(etcd_healthy_hosts, host)
else
io_stderr:write(str_format("request etcd endpoint \'%s\' error, %s\n", version_url,
err))
end
end
if #etcd_healthy_hosts <= 0 then
util.die("all etcd nodes are unavailable\n")
end
if (#etcd_healthy_hosts / host_count * 100) <= 50 then
util.die("the etcd cluster needs at least 50% and above healthy nodes\n")
end
local etcd_ok = false
for index, host in ipairs(etcd_healthy_hosts) do
if prepare_dirs(yaml_conf, args, index, host, host_count) then
etcd_ok = true
break
end
end
if not etcd_ok then
util.die("none of the configured etcd works well\n")
end
end