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