Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: support reading configuration form xds(mvp) #6614

Merged
merged 33 commits into from
Mar 22, 2022
Merged
Show file tree
Hide file tree
Changes from 25 commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
079eefb
feat: support reading configuration form shdict(mvp)
tzssangglass Mar 15, 2022
808bd6e
ci
tzssangglass Mar 15, 2022
5ffd2bf
fix code lint
tzssangglass Mar 15, 2022
815074d
fix code lint
tzssangglass Mar 15, 2022
1ca0254
fix CI
tzssangglass Mar 15, 2022
dd1315e
Merge branch 'master' into cgtf
tzssangglass Mar 15, 2022
6fa5a6b
fix code review
tzssangglass Mar 15, 2022
3123d81
replace amesh mock method
tzssangglass Mar 15, 2022
ede18da
revert amesh initial function
tzssangglass Mar 15, 2022
5b8726f
fix test cases lib name
tzssangglass Mar 15, 2022
d4c8c19
fix CI error
tzssangglass Mar 16, 2022
ed3fa36
fix CI error
tzssangglass Mar 16, 2022
87e97c1
fix CI error
tzssangglass Mar 16, 2022
519a823
fix CI error
tzssangglass Mar 16, 2022
3345a31
revert test cases changed in traffic-split
tzssangglass Mar 16, 2022
a80954b
Merge branch 'master' of https://github.com/apache/apisix into cgtf
tzssangglass Mar 17, 2022
9a4cb1f
fix code review
tzssangglass Mar 17, 2022
62190bc
fix code review
tzssangglass Mar 17, 2022
82fbcdc
revert config.yaml
tzssangglass Mar 17, 2022
b0fa534
resolve code review
tzssangglass Mar 17, 2022
39cca64
rename
tzssangglass Mar 17, 2022
add82f7
rename
tzssangglass Mar 17, 2022
7465395
resolve code review
tzssangglass Mar 17, 2022
3123324
fix CI
tzssangglass Mar 17, 2022
8a2a67d
resolve code review
tzssangglass Mar 17, 2022
f1fee3b
resolve code review
tzssangglass Mar 18, 2022
a9c9ba0
fix CI error
tzssangglass Mar 18, 2022
9b31b34
rename test cases names
tzssangglass Mar 18, 2022
0166d0a
Merge branch 'master' into cgtf
tzssangglass Mar 21, 2022
513c2b3
resolve code review
tzssangglass Mar 21, 2022
57c88d1
resolve code review
tzssangglass Mar 21, 2022
41abb0a
Merge branch 'master' into cgtf
tzssangglass Mar 21, 2022
aee463f
Merge branch 'master' into cgtf
tzssangglass Mar 21, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ jobs:
test_dir:
- t/plugin
- t/admin t/cli t/config-center-yaml t/control t/core t/debug t/discovery t/error_page t/misc
- t/node t/router t/script t/stream-node t/utils t/wasm
- t/node t/router t/script t/stream-node t/utils t/wasm t/xds-library

runs-on: ${{ matrix.platform }}
timeout-minutes: 90
Expand Down Expand Up @@ -90,6 +90,11 @@ jobs:
sudo dpkg -i tinygo_${TINYGO_VER}_amd64.deb
cd t/wasm && find . -type f -name "*.go" | xargs -Ip tinygo build -o p.wasm -scheduler=none -target=wasi p

- name: Build xDS library
run: |
cd t/xds-library
go build -o libxds.so -buildmode=c-shared main.go

- name: Linux Before install
run: sudo ./ci/${{ matrix.os_name }}_runner.sh before_install

Expand Down
4 changes: 4 additions & 0 deletions apisix/cli/ngx_tpl.lua
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,10 @@ http {
lua_shared_dict ext-plugin {* http.lua_shared_dict["ext-plugin"] *}; # cache for ext-plugin
{% end %}

{% if config_center == "xds" then %}
lua_shared_dict router-config 10m;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
lua_shared_dict router-config 10m;
lua_shared_dict xds-route-config 10m;

would that be better?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

updated

{% end %}

# for custom shared dict
{% if http.custom_lua_shared_dict then %}
{% for cache_key, cache_size in pairs(http.custom_lua_shared_dict) do %}
Expand Down
2 changes: 1 addition & 1 deletion apisix/cli/schema.lua
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ local config_schema = {
apisix = {
properties = {
config_center = {
enum = {"etcd", "yaml"},
enum = {"etcd", "yaml", "xds"},
},
lua_module_hook = {
pattern = "^[a-zA-Z._-]+$",
Expand Down
120 changes: 120 additions & 0 deletions apisix/core/config_xds.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
--
-- Licensed to the Apache Software Foundation (ASF) under one or more
-- contributor license agreements. See the NOTICE file distributed with
-- this work for additional information regarding copyright ownership.
-- The ASF licenses this file to You under the Apache License, Version 2.0
-- (the "License"); you may not use this file except in compliance with
-- the License. You may obtain a copy of the License at
--
-- http://www.apache.org/licenses/LICENSE-2.0
--
-- Unless required by applicable law or agreed to in writing, software
-- distributed under the License is distributed on an "AS IS" BASIS,
-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-- See the License for the specific language governing permissions and
-- limitations under the License.
--

--- Get configuration form ngx.shared.DICT.
--
-- @module core.config_xds

local base = require("resty.core.base")
local config_local = require("apisix.core.config_local")
local table = table
local error = error
local is_http = ngx.config.subsystem == "http"
local io = io
local io_open = io.open
local io_close = io.close
local package = package
local new_tab = base.new_tab
local ffi = require ("ffi")
local C = ffi.C
local router_config = ngx.shared["router-config"]
Copy link
Member

@spacewander spacewander Mar 20, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is not configuration for router, but for route.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

updated

local ngx_re_match = ngx.re.match
local ngx_re_gmatch = ngx.re.gmatch

local xds_lib_name = "libxds.so"


local process
if is_http then
process = require("ngx.process")
end


ffi.cdef[[
extern void initial(void* router_zone_ptr);
]]


local _M = {
version = 0.1,
local_conf = config_local.local_conf,
}


-- todo: refactor this function in chash.lua and radixtree.lua
local function load_shared_lib(lib_name)
local cpath = package.cpath
local tried_paths = new_tab(32, 0)
local i = 1

local iter, err = ngx_re_gmatch(cpath, "[^;]+", "jo")
if not iter then
error("failed to gmatch: " .. err)
end

while true do
local it = iter()
local fpath
fpath, err = ngx_re_match(it[0], "(.*/)", "jo")
if err then
error("failed to match: " .. err)
end
local spath = fpath[0] .. lib_name

local f = io_open(spath)
if f ~= nil then
io_close(f)
return ffi.load(spath)
end
tried_paths[i] = spath
i = i + 1

if not it then
break
end
end

return nil, tried_paths
end


local function load_libxds(lib_name)
local xdsagent, tried_paths = load_shared_lib(lib_name)

if not xdsagent then
tried_paths[#tried_paths + 1] = 'tried above paths but can not load ' .. lib_name
error("can not load Amesh library, tried paths: " ..
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
error("can not load Amesh library, tried paths: " ..
error("can not load xds library, tried paths: " ..

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

updated

table.concat(tried_paths, '\r\n', 1, #tried_paths))
end

local router_zone = C.ngx_http_lua_ffi_shdict_udata_to_zone(router_config[1])
local router_shd_cdata = ffi.cast("void*", router_zone)
xdsagent.initial(router_shd_cdata)
end



function _M.init_worker()
if process.type() == "privileged agent" then
load_libxds(xds_lib_name)
end

return true
end


return _M
5 changes: 5 additions & 0 deletions apisix/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,11 @@ function _M.http_init_worker()
end
require("apisix.balancer").init_worker()
load_balancer = require("apisix.balancer")

if core.config == require("apisix.core.config_xds") then
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can call it like:

if core.config.init then

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

updated

core.config.init_worker()
end

require("apisix.admin.init").init_worker()

require("apisix.timers").init_worker()
Expand Down
3 changes: 2 additions & 1 deletion t/APISIX.pm
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,7 @@ apisix:
_EOC_
}

my $lua_deps_path = <<_EOC_;
my $lua_deps_path = $block->lua_deps_path // <<_EOC_;
lua_package_path "$apisix_home/?.lua;$apisix_home/?/init.lua;$apisix_home/deps/share/lua/5.1/?/init.lua;$apisix_home/deps/share/lua/5.1/?.lua;$apisix_home/apisix/?.lua;$apisix_home/t/?.lua;;";
lua_package_cpath "$apisix_home/?.so;$apisix_home/deps/lib/lua/5.1/?.so;$apisix_home/deps/lib64/lua/5.1/?.so;;";
_EOC_
Expand Down Expand Up @@ -507,6 +507,7 @@ _EOC_
lua_capture_error_log 1m; # plugin error-log-logger
lua_shared_dict etcd-cluster-health-check 10m; # etcd health check
lua_shared_dict ext-plugin 1m;
lua_shared_dict router-config 1m;

proxy_ssl_name \$upstream_host;
proxy_ssl_server_name on;
Expand Down
104 changes: 104 additions & 0 deletions t/xds-library/config_xds.t
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
#
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
use t::APISIX 'no_plan';

use Cwd qw(cwd);
my $apisix_home = $ENV{APISIX_HOME} || cwd();

repeat_each(1);
no_long_string();
no_root_location();
log_level("info");

add_block_preprocessor(sub {
my ($block) = @_;

if (!$block->request) {
$block->set_value("request", "GET /t");
}

if (!$block->no_error_log) {
$block->set_value("no_error_log", "[error]\n[alert]");
}

my $lua_deps_path = $block->lua_deps_path // <<_EOC_;
lua_package_path "$apisix_home/?.lua;$apisix_home/?/init.lua;$apisix_home/deps/share/lua/5.1/?/init.lua;$apisix_home/deps/share/lua/5.1/?.lua;$apisix_home/apisix/?.lua;$apisix_home/t/?.lua;;";
lua_package_cpath "$apisix_home/?.so;$apisix_home/t/xds-library/?.so;$apisix_home/deps/lib/lua/5.1/?.so;$apisix_home/deps/lib64/lua/5.1/?.so;;";
_EOC_

$block->set_value("lua_deps_path", $lua_deps_path);

my $extra_init_by_lua = <<_EOC_;
--
local config_xds = require("apisix.core.config_xds")

local inject = function(mod, name)
local old_f = mod[name]
mod[name] = function (...)
ngx.log(ngx.WARN, "config_xds run ", name)
return { true }
end
end

inject(config_xds, "new")

_EOC_

$block->set_value("extra_init_by_lua", $extra_init_by_lua);
});

run_tests;

__DATA__

=== TEST 1: load Amesh library so successfully
--- yaml_config
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's set the yaml_config in the file level?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

updated

apisix:
node_listen: 1984
config_center: xds
enable_admin: false
--- config
location /t {
content_by_lua_block {
ngx.say("ok")
}
}
--- no_error_log eval
qr/can not load xDS library/



=== TEST 2: read data form shdict that wirted by Amesh library
--- yaml_config
apisix:
node_listen: 1984
config_center: xds
enable_admin: false
--- config
location /t {
content_by_lua_block {
-- wait for Amesh library sync data
ngx.sleep(1.5)
local core = require("apisix.core")
local value = ngx.shared["router-config"]:get("/apisix/routes/1")
local route_conf, err = core.json.decode(value)
local json_encode = require("toolkit.json").encode
ngx.say(json_encode(route_conf))
}
}
--- response_body
{"create_time":1646972532,"id":"1","priority":0,"status":1,"update_time":1647250524,"upstream":{"hash_on":"vars","nodes":[{"host":"127.0.0.1","port":80,"priority":0,"weight":1}],"pass_host":"pass","scheme":"http","type":"roundrobin"},"uri":"/hello"}
92 changes: 92 additions & 0 deletions t/xds-library/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package main

/*
#cgo LDFLAGS: -shared
#include <stdlib.h>

extern void ngx_http_lua_ffi_shdict_store(void *zone, int op,
const unsigned char *key, size_t key_len,
int value_type,
const unsigned char *str_value_buf, size_t str_value_len,
double num_value, long exptime, int user_flags, char **errmsg,
int *forcible);
*/
import "C"

import (
"fmt"
"time"
"unsafe"
)

func main() {
}


//export initial
func initial(zone unsafe.Pointer) {
time.Sleep(time.Second)
value := fmt.Sprintf(`{
"status": 1,
"update_time": 1647250524,
"create_time": 1646972532,
"uri": "/hello",
"priority": 0,
"id": "1",
"upstream": {
"nodes": [
{
"port": 80,
"priority": 0,
"host": "127.0.0.1",
"weight": 1
}
],
"type": "roundrobin",
"hash_on": "vars",
"pass_host": "pass",
"scheme": "http"
}
}`)

write_route(zone, "/apisix/routes/1", value)
}

func write_route(zone unsafe.Pointer, key, value string) {
var keyCStr = C.CString(key)
defer C.free(unsafe.Pointer(keyCStr))
var keyLen = C.size_t(len(key))

var valueCStr = C.CString(value)
defer C.free(unsafe.Pointer(valueCStr))
var valueLen = C.size_t(len(value))

errMsgBuf := make([]*C.char, 1)
var forcible = 0

C.ngx_http_lua_ffi_shdict_store(zone, 0x0004,
(*C.uchar)(unsafe.Pointer(keyCStr)), keyLen,
4,
(*C.uchar)(unsafe.Pointer(valueCStr)), valueLen,
0, 0, 0,
(**C.char)(unsafe.Pointer(&errMsgBuf[0])),
(*C.int)(unsafe.Pointer(&forcible)),
)
}