Skip to content

Commit

Permalink
change: check etcd cluster version when init_etcd
Browse files Browse the repository at this point in the history
Signed-off-by: tokers <zchao1995@gmail.com>
  • Loading branch information
tokers committed Sep 15, 2020
1 parent 98da870 commit 8f43ad7
Showing 1 changed file with 108 additions and 12 deletions.
120 changes: 108 additions & 12 deletions bin/apisix
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@ local function trim(s)
return (s:gsub("^%s*(.-)%s*$", "%1"))
end

-- Note: The `excute_cmd` return value will have a line break at the end,
-- Note: The `execute_cmd` return value will have a line break at the end,
-- it is recommended to use the `trim` function to handle the return value.
local function excute_cmd(cmd)
local function execute_cmd(cmd)
local t, err = io.popen(cmd)
if not t then
return nil, "failed to execute command: " .. cmd .. ", error info:" .. err
Expand All @@ -33,7 +33,7 @@ local function excute_cmd(cmd)
return data
end

excute_cmd("install -d -m 777 /tmp/apisix_cores/")
execute_cmd("install -d -m 777 /tmp/apisix_cores/")

local pkg_cpath_org = package.cpath
local pkg_path_org = package.path
Expand All @@ -42,12 +42,14 @@ local apisix_home = "/usr/local/apisix"
local pkg_cpath = apisix_home .. "/deps/lib64/lua/5.1/?.so;"
.. apisix_home .. "/deps/lib/lua/5.1/?.so;;"
local pkg_path = apisix_home .. "/deps/share/lua/5.1/?.lua;;"
local min_etcd_version = "3.4.0"


-- only for developer, use current folder as working space
local is_root_path = false
local script_path = arg[0]
if script_path:sub(1, 2) == './' then
apisix_home = trim(excute_cmd("pwd"))
apisix_home = trim(execute_cmd("pwd"))
if not apisix_home then
error("failed to fetch current path")
end
Expand Down Expand Up @@ -640,16 +642,17 @@ local function read_yaml_conf()
return default_conf
end


local function get_openresty_version()
local str = "nginx version: openresty/"
local ret = excute_cmd("openresty -v 2>&1")
local ret = execute_cmd("openresty -v 2>&1")
local pos = string.find(ret,str)
if pos then
return string.sub(ret, pos + string.len(str))
end

str = "nginx version: nginx/"
ret = excute_cmd("openresty -v 2>&1")
ret = execute_cmd("openresty -v 2>&1")
pos = string.find(ret, str)
if pos then
return string.sub(ret, pos + string.len(str))
Expand All @@ -658,23 +661,82 @@ local function get_openresty_version()
return nil
end


local function is_32bit_arch()
local ok, ffi = pcall(require, "ffi")
if ok then
-- LuaJIT
return ffi.abi("32bit")
end
local ret = excute_cmd("getconf LONG_BIT")
local ret = execute_cmd("getconf LONG_BIT")
local bits = tonumber(ret)
return bits <= 32
end


local function split(self, sep)
local sep, fields = sep or ":", {}
local pattern = string.format("([^%s]+)", sep)
self:gsub(pattern, function(c) fields[#fields + 1] = c end)
return fields
end
end


local function parse_semantic_version(ver)
local errmsg = "invalid semantic version: " .. ver

local parts = split(ver, "-")
if #parts > 2 then
return nil, errmsg
end

if #parts == 2 then
ver = parts[1]
end

local fields = split(ver, ".")
if #fields ~= 3 then
return nil, errmsg
end

local major = tonumber(fields[1])
local minor = tonumber(fields[2])
local patch = tonumber(fields[3])

if not (major and minor and patch) then
return nil, errmsg
end

return {
major = major,
minor = minor,
patch = patch,
}
end


local function compare_semantic_version(v1, v2)
local ver1, err = parse_semantic_version(v1)
if not ver1 then
return nil, err
end

local ver2, err = parse_semantic_version(v2)
if not ver2 then
return nil, err
end

if ver1.major ~= ver2.major then
return ver1.major < ver2.major
end

if ver1.minor ~= ver2.minor then
return ver1.minor < ver2.minor
end

return ver1.patch < ver2.patch
end


local function check_or_version(cur_ver_s, need_ver_s)
local cur_vers = split(cur_ver_s, [[.]])
Expand Down Expand Up @@ -744,7 +806,7 @@ local function init()
end
-- print("etcd: ", yaml_conf.etcd.host)

local or_ver = excute_cmd("openresty -V 2>&1")
local or_ver = execute_cmd("openresty -V 2>&1")
local with_module_status = true
if or_ver and not or_ver:find("http_stub_status_module", 1, true) then
io.stderr:write("'http_stub_status_module' module is missing in ",
Expand All @@ -766,7 +828,7 @@ local function init()
local sys_conf = {
lua_path = pkg_path_org,
lua_cpath = pkg_cpath_org,
os_name = trim(excute_cmd("uname")),
os_name = trim(execute_cmd("uname")),
apisix_lua_home = apisix_home,
with_module_status = with_module_status,
error_log = {level = "warn"},
Expand Down Expand Up @@ -871,13 +933,47 @@ local function init_etcd(show_output)
yaml_conf.etcd.host = {yaml_conf.etcd.host}
end

local cluster_version
local host_count = #(yaml_conf.etcd.host)
-- check the etcd cluster version
for index, host in ipairs(yaml_conf.etcd.host) do
uri = host .. "/version"
local cmd = string.format("curl -s -m %d %s | sed -e 's/[{}]/''/g'", timeout * 2, uri)
local res = execute_cmd(cmd)
local m = split(res, [[%s*,%s*]])
local errmsg = string.format("got malformed version message: \"%s\" from etcd", res)

for i = 1, #m do
local mm = split(m[i], [[%s*:%s*]])
if #mm ~= 2 then
io.stderr:write(errmsg)
return
end

if mm[1] == "\"etcdcluster\"" then
cluster_version = string.sub(mm[2], 2, -2)
break
end
end

if not cluster_version then
io.stderr:write(errmsg)
return
end

if compare_semantic_version(cluster_version, min_etcd_version) then
io.stderr:write(string.format("etcd cluster version \"%s\" is less than the required version \"%s\", please upgrade your etcd cluster", cluster_version, min_etcd_version))
return
end

break
end

-- check whether the user has enabled etcd v2 protocol
for index, host in ipairs(yaml_conf.etcd.host) do
uri = host .. "/v2/keys"
local cmd = "curl -i -m ".. timeout * 2 .. " -o /dev/null -s -w %{http_code} " .. uri
local res = excute_cmd(cmd)
local res = execute_cmd(cmd)
if res == "404" then
io.stderr:write(string.format("failed: please make sure that you have enabled the v2 protocol of etcd on %s.\n", host))
return
Expand All @@ -899,7 +995,7 @@ local function init_etcd(show_output)
.. "--connect-timeout " .. timeout
.. " --max-time " .. timeout * 2 .. " --retry 1 2>&1"

local res = excute_cmd(cmd)
local res = execute_cmd(cmd)
if not res:find("index", 1, true)
and not res:find("createdIndex", 1, true) then
is_success = false
Expand Down

0 comments on commit 8f43ad7

Please sign in to comment.