List, while working on updating my haproxy-auth-request [1] to make use of haproxy-lua-http [2] instead of the crappy lua-socket [3] I realized that it would be difficult for the administrator to use the script afterwards.
The reason is that `require` in Lua attempts to search the modules either in the current working directory (which is different from the filename of the script executing the `require` and which most likely is not anywhere near HAProxy's configuration folder) or within Lua's library path which is compiled into Lua (in my case this is something like `/usr/share/lua/5.3/`). Add a `lua-prepend-path` configuration option that prepend the given string to Lua's path, allowing scripts loaded with `lua-load` to find libraries within that path. Example configuration: global lua-prepend-path /etc/haproxy/lua-modules/?/init.lua lua-prepend-path /etc/haproxy/lua-modules/?.lua lua-load /etc/haproxy/lua-modules/auth-request.lua would result in something like this: [ALERT] 007/225248 (6638) : parsing [./haproxy.cfg:5] : Lua runtime error: auth-request.lua:23: module 'haproxy-lua-http' not found: no field package.preload['haproxy-lua-http'] no file '/etc/haproxy/lua-modules/haproxy-lua-http.lua' no file '/etc/haproxy/lua-modules/haproxy-lua-http/init.lua' no file '/usr/local/share/lua/5.3/haproxy-lua-http.lua' no file '/usr/local/share/lua/5.3/haproxy-lua-http/init.lua' no file '/usr/local/lib/lua/5.3/haproxy-lua-http.lua' no file '/usr/local/lib/lua/5.3/haproxy-lua-http/init.lua' no file '/usr/share/lua/5.3/haproxy-lua-http.lua' no file '/usr/share/lua/5.3/haproxy-lua-http/init.lua' no file './haproxy-lua-http.lua' no file './haproxy-lua-http/init.lua' no file '/usr/local/lib/lua/5.3/haproxy-lua-http.so' no file '/usr/lib/x86_64-linux-gnu/lua/5.3/haproxy-lua-http.so' no file '/usr/lib/lua/5.3/haproxy-lua-http.so' no file '/usr/local/lib/lua/5.3/loadall.so' no file './haproxy-lua-http.so' I'd appreciate if we could backport this to 2.1. It should be fairly self-contained. Best regards Tim Düsterhus [1] https://github.com/TimWolla/haproxy-auth-request [2] https://github.com/haproxytech/haproxy-lua-http [3] https://github.com/TimWolla/haproxy-auth-request/issues/4 Apply with `git am --scissors` to automatically cut the commit message. -- >8 -- Subject: [PATCH] MINOR: lua: Add lua-prepend-path configuration option lua-prepend-path allows the administrator to specify a custom Lua library path to load custom Lua modules that are useful within the context of HAProxy without polluting the global Lua library folder. --- doc/configuration.txt | 6 ++++++ src/hlua.c | 16 ++++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/doc/configuration.txt b/doc/configuration.txt index d0bb97415..47a4db344 100644 --- a/doc/configuration.txt +++ b/doc/configuration.txt @@ -603,6 +603,7 @@ The following keywords are supported in the "global" section : - log-tag - log-send-hostname - lua-load + - lua-prepend-path - mworker-max-reloads - nbproc - nbthread @@ -1080,6 +1081,11 @@ lua-load <file> This global directive loads and executes a Lua file. This directive can be used multiple times. +lua-prepend-path <string> + Prepends the given string followed by a semicolon to Lua's search path. + + see: https://www.lua.org/pil/8.1.html + master-worker [no-exit-on-failure] Master-worker mode. It is equivalent to the command line "-W" argument. This mode will launch a "master" which will monitor the "workers". Using diff --git a/src/hlua.c b/src/hlua.c index 37f786687..4f39755b3 100644 --- a/src/hlua.c +++ b/src/hlua.c @@ -7458,8 +7458,24 @@ static int hlua_load(char **args, int section_type, struct proxy *curpx, return 0; } +static int hlua_prepend_path(char **args, int section_type, struct proxy *curpx, + struct proxy *defpx, const char *file, int line, + char **err) +{ + lua_getglobal(gL.T, "package"); /* push package */ + lua_pushstring(gL.T, args[1]); /* push given path */ + lua_pushstring(gL.T, ";"); /* push semicolon */ + lua_getfield(gL.T, -3, "path"); /* push old path */ + lua_concat(gL.T, 3); /* concatenate to new path */ + lua_setfield(gL.T, -2, "path"); /* store new path */ + lua_pop(gL.T, 1); /* pop package */ + + return 0; +} + /* configuration keywords declaration */ static struct cfg_kw_list cfg_kws = {{ },{ + { CFG_GLOBAL, "lua-prepend-path", hlua_prepend_path }, { CFG_GLOBAL, "lua-load", hlua_load }, { CFG_GLOBAL, "tune.lua.session-timeout", hlua_session_timeout }, { CFG_GLOBAL, "tune.lua.task-timeout", hlua_task_timeout }, -- 2.24.1