Search code examples
luahaproxyluasocket

Using Lua package (LuaSocket) with HAProxy


I have installed HAProxy with Lua 5.3.1, and also LuaSocket.

I have LUA_PATH and LUA_CPATH defined:

export LUA_PATH="/usr/local/share/lua/5.3/?.lua;?.lua"
export LUA_CPATH="/usr/local/lib/lua/5.3/?.so;?.so"

and I'm using LuaSocket in my .lua file

core.register_fetches("myfunc", function(txn)

    ...
    local http = require("socket.http")    
    r, e = http.request("http://localhost:5001/api/Registry/")

however I can see from journalctl -xe that it isn't working

Dec 11 23:27:33 ip-172-31-5-92 haproxy[16731]: [ALERT] 344/232733 (16734) : Lua sample-fetch 'myfunc': runtime error: /home/ubuntu/haproxy-mapping.lua:12: module 'socket.http' not found:
Dec 11 23:27:33 ip-172-31-5-92 haproxy[16731]:         no field package.preload['socket.http']
Dec 11 23:27:33 ip-172-31-5-92 haproxy[16731]:         no file '/usr/local/share/lua/5.3/socket/http.lua'
Dec 11 23:27:33 ip-172-31-5-92 haproxy[16731]:         no file '/usr/local/share/lua/5.3/socket/http/init.lua'
Dec 11 23:27:33 ip-172-31-5-92 haproxy[16731]:         no file '/usr/local/lib/lua/5.3/socket/http.lua'
Dec 11 23:27:33 ip-172-31-5-92 haproxy[16731]:         no file '/usr/local/lib/lua/5.3/socket/http/init.lua'
Dec 11 23:27:33 ip-172-31-5-92 haproxy[16731]:         no file './socket/http.lua'
Dec 11 23:27:33 ip-172-31-5-92 haproxy[16731]:         no file './socket/http/init.lua'
Dec 11 23:27:33 ip-172-31-5-92 haproxy[16731]:         no file '/usr/local/lib/lua/5.3/socket/http.so'
Dec 11 23:27:33 ip-172-31-5-92 haproxy[16731]:         no file '/usr/local/lib/lua/5.3/loadall.so'
Dec 11 23:27:33 ip-172-31-5-92 haproxy[16731]:         no file './socket/http.so'
Dec 11 23:27:33 ip-172-31-5-92 haproxy[16731]:         no file '/usr/local/lib/lua/5.3/socket.so'
Dec 11 23:27:33 ip-172-31-5-92 haproxy[16731]:         no file '/usr/local/lib/lua/5.3/loadall.so'
Dec 11 23:27:33 ip-172-31-5-92 haproxy[16731]:         no file './socket.so' from [C] global 'require', /home/ubuntu/haproxy-mapping.lua:12 C function line 4.

I'm surprised that it cannot find /usr/local/share/lua/5.3/socket/http.lua because it's there:

me$ ls -l /usr/local/share/lua/5.3/socket
total 56
-rw-r--r-- 1 root root 10640 Dec 11 21:31 ftp.lua
-rw-r--r-- 1 root root  3698 Dec 11 21:31 headers.lua
-rw-r--r-- 1 root root 14588 Dec 11 21:31 http.lua
-rw-r--r-- 1 root root  8074 Dec 11 21:31 smtp.lua
-rw-r--r-- 1 root root  3766 Dec 11 21:31 tp.lua
-rw-r--r-- 1 root root 11675 Dec 11 21:31 url.lua

It is saying

  no file './socket.so' from [C] global 'require', /home/ubuntu/haproxy-mapping.lua:12 C function line 4.

is that the core of the issue? There is no socket.so on the machine

Update: forgot to mention that I can use LuaSocket from Lua directly, just not when it's embedded in HAProxy.

Update 2: I suspect permissions. I ran strace on it and found

open("/usr/local/share/lua/5.3/socket/http.lua", O_RDONLY) = -1 ENOENT (No such file or directory)

and I know that haproxy is running as the user haproxy

me   :/usr/local/share/lua/5.3/socket$ ps -o user= -p 3273
haproxy

and yet if I switch user to haproxy I can read the file

me   :/usr/local/share/lua/5.3/socket$ su - haproxy
Password:
No directory, logging in with HOME=/
$ more /usr/local/share/lua/5.3/socket/http.lua
...listing...

and I also changed owner of the http.lua file to haproxy and it still can't open the file.


Solution

  • I can only assume this is something to do with the context that the Lua function runs with-in when it is called, because changing the code to

    local http = require("socket.http")    
    core.register_fetches("myfunc", function(txn)
        ...
    

    worked.

    UPDATE: according to this https://www.arpalert.org/src/haproxy-lua-api/1.7/index.html during initialization you can DNS lookups but in runtime mode you cannot. It doesn't say anything about files but it seems reasonable to believe you can't do files either.