Skip to content

Commit

Permalink
lua: add Lua bindings
Browse files Browse the repository at this point in the history
Signed-off-by: Rubicon Rowe <l1589002388@gmail.com>
  • Loading branch information
thislight committed Mar 16, 2023
1 parent 7fa6b77 commit 5ad1507
Show file tree
Hide file tree
Showing 9 changed files with 1,983 additions and 0 deletions.
9 changes: 9 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -69,3 +69,12 @@ tests/tests_*
tests/*.log
tests/*.trs
test-suite.log

# Cached files
.cache/
compile_commands.json

# LuaRocks development files
/luarocks
/lua_modules
/.luarocks
14 changes: 14 additions & 0 deletions Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,20 @@ python_crun_la_LDFLAGS = -avoid-version -module $(PYTHON_LDFLAGS)
python_crun_la_LIBADD = libcrun.la $(PYTHON_LIBS) $(FOUND_LIBS) $(maybe_libyajl.la)
endif

if LUA_BINDINGS
noinst_LTLIBRARIES = libcrun-bundled.la
luaexec_LTLIBRARIES = luacrun.la
luacrun_la_SOURCES = lua/lua_crun.c
luacrun_la_CFLAGS = -I $(abs_top_srcdir)/libocispec/src -I $(abs_top_builddir)/libocispec/src -I $(abs_top_builddir)/src $(LUA_INCLUDE)
luacrun_la_LDFLAGS = -avoid-version -module
luacrun_la_LIBADD = libcrun-bundled.la $(LUA_LIB) $(FOUND_LIBS)

libcrun_bundled_la_SOURCES = $(libcrun_SOURCES)
libcrun_bundled_la_CFLAGS = -I $(abs_top_builddir)/libocispec/src -I $(abs_top_srcdir)/libocispec/src -fvisibility=hidden
libcrun_bundled_la_LIBADD = libocispec/libocispec.la $(FOUND_LIBS) $(maybe_libyajl.la)
libcrun_bundled_la_LDFLAGS = -Wl,--version-script=$(abs_top_srcdir)/libcrun.lds
endif

crun_CFLAGS = -I $(abs_top_builddir)/libocispec/src -I $(abs_top_srcdir)/libocispec/src -D CRUN_LIBDIR="\"$(CRUN_LIBDIR)\""
crun_SOURCES = src/crun.c src/run.c src/delete.c src/kill.c src/pause.c src/unpause.c src/spec.c \
src/exec.c src/list.c src/create.c src/start.c src/state.c src/update.c src/ps.c \
Expand Down
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -176,3 +176,7 @@ $ sudo su -
# molecule converge
# molecule verify
```

## Lua bindings

A Lua binding is available. See [the README](lua/README.md) for more information.
10 changes: 10 additions & 0 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,15 @@ AS_IF([test "x$with_python_bindings" = "xyes"], [
use_fPIC=yes
])

AC_ARG_WITH([lua-bindings], AS_HELP_STRING([--with-lua-bindings], [build the Lua bindings]))

AS_IF([test "x$with_lua_bindings" = "xyes"], [
AX_PROG_LUA([5.4], [5.5], [], [AC_MSG_ERROR([*** lua interpreter not found])])
AX_LUA_HEADERS([], [AC_MSG_ERROR([*** lua headers not found])])
AX_LUA_LIBS([], [AC_MSG_ERROR([*** lua libs not found])])
use_fPIC=yes
])

AS_IF([test "x$use_fPIC" = "xyes"], [
# configure should not touch CFLAGS/LDFLAGS but we need it to propagate it
# to libocispec.
Expand Down Expand Up @@ -253,6 +262,7 @@ fi
AC_SEARCH_LIBS([argp_parse], [argp], [], [AC_MSG_ERROR([*** argp functions not found - install libargp or argp_standalone])])

AM_CONDITIONAL([PYTHON_BINDINGS], [test "x$with_python_bindings" = "xyes"])
AM_CONDITIONAL([LUA_BINDINGS], [test "x$with_lua_bindings" = "xyes"])
AM_CONDITIONAL([CRIU_SUPPORT], [test "x$have_criu" = "xyes"])
AM_CONDITIONAL([SHARED_LIBCRUN], [test "x$enable_shared" = "xyes"])

Expand Down
120 changes: 120 additions & 0 deletions lua/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
# Lua binding for libcrun

Bare libcrun interface for Lua.

There are some problems still and the API is a subject to change.

## Build

Only build static archive, to be bundled with another program:

````sh
./configure --with-lua-bindings
make && make install
````

Since the final product bundle libcrun, you don't need to link libcrun at runtime.


For the library using at runtime, add option `--enable-shared`:
````sh
./configure --with-lua-bindings --enable-shared
make && make install
````

Other options to build libcrun may affect the bundled libcrun.

## Usage

See `luacrun.d.tl`.

## Works with your LuaRocks project

You can configure the prefix as your `lua_modules` to access this library in your project.

````sh
./configure --with-lua-bindings --enable-shared --prefix $(pwd)/lua_modules
````

## Interpreter may restart?

Related issue: [#695: [Python bindings] Python interpreter restarts (?) after first import of python_crun](https://github.com/containers/crun/issues/695)

The lua interpreter may restart at the first open of the library (may not happen if statically linked into your program). It's side effect of [a protection (click for the code)](https://github.com/containers/crun/blob/923447b691dbd7c5bffbaee1427460d62d848047/src/libcrun/linux.c#L3881-L3891) to avoid attacks like [CVE-2019-5736](https://nvd.nist.gov/vuln/detail/CVE-2019-5736).

To ease the hurt, always place the `require` call at the start of your program:

````lua
-- entry point module for luabundler
require "luacrun"

return function(...) -- the entry point
print("Hello World!")
end
````

It's not required to use the library at the moment. Since it is cached, the `require()` will not open the library again.

If the entry point is at the C-side, you may use the `luaL_requiref` to open the library instead of `require()` call in Lua code.
````c
#include <lua.h>
#include <lauxlib.h>

extern int luaopen_luacrun(lua_State *S);

int main(int argc, char *argv[]) {
lua_State *S = luaL_newstate();
// Open the library before any actual logic,
// to make sure users will not notice the program have actually started twice
luaL_requiref(S, "luacrun", &luaopen_luacrun, false);
lua_pop(S, 1);
// ...your code
}
````
The protection might cause another problem in REPL:
````
$ lua
Lua 5.4.4 Copyright (C) 1994-2022 Lua.org, PUC-Rio
> luacrun = require "luacrun"
Lua 5.4.4 Copyright (C) 1994-2022 Lua.org, PUC-Rio
> luacrun
nil
>
````
When you call `require "luacrun"` at the first time, the REPL restarted and the state have been reset.
The workaround is `require "luacrun"` again and you get the library this time. The protection will not apply again if it's already applied.
````
$ lua
Lua 5.4.4 Copyright (C) 1994-2022 Lua.org, PUC-Rio
> luacrun = require "luacrun"
Lua 5.4.4 Copyright (C) 1994-2022 Lua.org, PUC-Rio
> luacrun
nil
> luacrun = require "luacrun"
> luacrun
table: 0x561edad470d0
>
````
It's safe to use luacrun in multi-state usage, the program restarts only once.
## Test
You need [busted](https://lunarmodules.github.io/busted/) and below dependencies to run tests:
- [dkjson](https://luarocks.org/modules/dhkolf/dkjson)
- [luaposix](https://luaposix.github.io)
````sh
luarocks install busted dkjson luaposix
````

The tests assume environment variable `INIT` exists. It's the `init` program compiled in `tests`.

````sh
INIT=$(pwd)/tests/init lua_modules/bin/busted lua
````
Loading

0 comments on commit 5ad1507

Please sign in to comment.