You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@apisix.apache.org by to...@apache.org on 2021/06/01 10:43:50 UTC
[apisix] branch master updated: fix(ext-plugin): pass environment
variables (#4349)
This is an automated email from the ASF dual-hosted git repository.
tokers pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/apisix.git
The following commit(s) were added to refs/heads/master by this push:
new 5ebc4f6 fix(ext-plugin): pass environment variables (#4349)
5ebc4f6 is described below
commit 5ebc4f65c14362a145c1bf83120cce0f01e58511
Author: 罗泽轩 <sp...@gmail.com>
AuthorDate: Tue Jun 1 18:43:42 2021 +0800
fix(ext-plugin): pass environment variables (#4349)
Signed-off-by: spacewander <sp...@gmail.com>
---
apisix/core.lua | 1 +
apisix/core/os.lua | 55 +++++++++++++++++++++++++++++
apisix/plugins/ext-plugin/init.lua | 15 +++++---
docs/en/latest/external-plugin.md | 18 ++++++++--
t/core/os.t | 72 ++++++++++++++++++++++++++++++++++++++
t/plugin/ext-plugin/runner.sh | 1 +
t/plugin/ext-plugin/sanity.t | 14 ++++++++
7 files changed, 170 insertions(+), 6 deletions(-)
diff --git a/apisix/core.lua b/apisix/core.lua
index 0ef6ae9..4b5bc2b 100644
--- a/apisix/core.lua
+++ b/apisix/core.lua
@@ -49,5 +49,6 @@ return {
etcd = require("apisix.core.etcd"),
tablepool = require("tablepool"),
resolver = require("apisix.core.resolver"),
+ os = require("apisix.core.os"),
empty_tab = {},
}
diff --git a/apisix/core/os.lua b/apisix/core/os.lua
new file mode 100644
index 0000000..b8476ec
--- /dev/null
+++ b/apisix/core/os.lua
@@ -0,0 +1,55 @@
+--
+-- 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.
+--
+local ffi = require("ffi")
+local ffi_str = ffi.string
+local ffi_errno = ffi.errno
+local C = ffi.C
+local tostring = tostring
+local type = type
+
+
+local _M = {}
+
+
+ffi.cdef[[
+ int setenv(const char *name, const char *value, int overwrite);
+ char *strerror(int errnum);
+]]
+
+
+local function err()
+ return ffi_str(C.strerror(ffi_errno()))
+end
+
+
+-- setenv sets the value of the environment variable
+function _M.setenv(name, value)
+ local tv = type(value)
+ if type(name) ~= "string" or (tv ~= "string" and tv ~= "number") then
+ return false, "invalid argument"
+ end
+
+ value = tostring(value)
+ local ok = C.setenv(name, value, 1) == 0
+ if not ok then
+ return false, err()
+ end
+ return true
+end
+
+
+return _M
diff --git a/apisix/plugins/ext-plugin/init.lua b/apisix/plugins/ext-plugin/init.lua
index 9f83bf4..c227be0 100644
--- a/apisix/plugins/ext-plugin/init.lua
+++ b/apisix/plugins/ext-plugin/init.lua
@@ -547,13 +547,20 @@ local function create_lrucache()
end
+local function must_set(env, value)
+ local ok, err = core.os.setenv(env, value)
+ if not ok then
+ error(str_format("failed to set %s: %s", env, err), 2)
+ end
+end
+
+
local function spawn_proc(cmd)
+ must_set("APISIX_CONF_EXPIRE_TIME", helper.get_conf_token_cache_time())
+ must_set("APISIX_LISTEN_ADDRESS", helper.get_path())
+
local opt = {
merge_stderr = true,
- environ = {
- "APISIX_CONF_EXPIRE_TIME=" .. helper.get_conf_token_cache_time(),
- "APISIX_LISTEN_ADDRESS=" .. helper.get_path(),
- },
}
local proc, err = ngx_pipe.spawn(cmd, opt)
if not proc then
diff --git a/docs/en/latest/external-plugin.md b/docs/en/latest/external-plugin.md
index 0eea264..318e38e 100644
--- a/docs/en/latest/external-plugin.md
+++ b/docs/en/latest/external-plugin.md
@@ -63,8 +63,7 @@ ext-plugin:
Then APISIX will manage the runner as its subprocess.
-Note: APISIX can't manage the runner on the Mac. It is fine, we can run the runner by ourselves
-during development.
+Note: APISIX can't manage the runner on the Mac in `v2.6`.
During development, we want to run the runner separately so that we can restart it without
restarting APISIX first.
@@ -89,3 +88,18 @@ ext-plugin:
In the prod environment, `path_for_test` should not be used and the unix socket
path will be generated dynamically.
+
+## FAQ
+
+### When managing by APISIX, the runner can't access my environment variable
+
+Since `v2.7`, APISIX can pass environment to the runner.
+
+However, Nginx will hide all environment variables by default. So you need to
+declare your variable first in the `conf/config.yaml`:
+
+```yaml
+nginx_config:
+ envs:
+ - MY_ENV_VAR
+```
diff --git a/t/core/os.t b/t/core/os.t
new file mode 100644
index 0000000..dff6c8b
--- /dev/null
+++ b/t/core/os.t
@@ -0,0 +1,72 @@
+#
+# 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';
+
+add_block_preprocessor(sub {
+ my ($block) = @_;
+
+ if (!$block->request) {
+ $block->set_value("request", "GET /t");
+ }
+
+ if (!$block->no_error_log && !$block->error_log) {
+ $block->set_value("no_error_log", "[error]\n[alert]");
+ }
+});
+
+run_tests;
+
+__DATA__
+
+=== TEST 1: setenv
+--- config
+ location /t {
+ content_by_lua_block {
+ local core = require("apisix.core")
+
+ core.os.setenv("TEST", "A")
+ ngx.say(os.getenv("TEST"))
+ core.os.setenv("TEST", 1)
+ ngx.say(os.getenv("TEST"))
+ }
+ }
+--- response_body
+A
+1
+
+
+
+=== TEST 2: setenv, bad arguments
+--- config
+ location /t {
+ content_by_lua_block {
+ local core = require("apisix.core")
+
+ for _, c in ipairs({
+ {name = "A"},
+ {value = "A"},
+ {name = 1, value = "A"},
+ }) do
+ local ok = core.os.setenv(c.name, c.value)
+ ngx.say(ok)
+ end
+ }
+ }
+--- response_body
+false
+false
+false
diff --git a/t/plugin/ext-plugin/runner.sh b/t/plugin/ext-plugin/runner.sh
index 5b87852..056aa4f 100755
--- a/t/plugin/ext-plugin/runner.sh
+++ b/t/plugin/ext-plugin/runner.sh
@@ -18,5 +18,6 @@
echo "LISTEN $APISIX_LISTEN_ADDRESS"
echo "EXPIRE $APISIX_CONF_EXPIRE_TIME"
+echo "MY_ENV_VAR $MY_ENV_VAR"
sleep "$1"
exit 111
diff --git a/t/plugin/ext-plugin/sanity.t b/t/plugin/ext-plugin/sanity.t
index 905215e..ac21eeb 100644
--- a/t/plugin/ext-plugin/sanity.t
+++ b/t/plugin/ext-plugin/sanity.t
@@ -337,3 +337,17 @@ GET /hello
--- error_code: 503
--- error_log
failed to receive RPC_PREPARE_CONF: bad request
+
+
+
+=== TEST 12: runner can access the environment variable
+--- main_config
+env MY_ENV_VAR=foo;
+--- ext_plugin_cmd
+["t/plugin/ext-plugin/runner.sh", "3600"]
+--- config
+ location /t {
+ return 200;
+ }
+--- error_log
+MY_ENV_VAR foo