From: Christian Brauner Date: Wed, 14 Feb 2018 10:48:20 +0000 (+0100) Subject: tree-wide: remove lua bindings X-Git-Tag: lxc-3.0.0.beta1~3^2~9 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b52a5bef6fa56481a6d817f4c73cb91ed012fe2c;p=thirdparty%2Flxc.git tree-wide: remove lua bindings Signed-off-by: Christian Brauner --- diff --git a/.travis.yml b/.travis.yml index d078b0222..ca354ccc0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -18,7 +18,7 @@ before_install: - echo -n | openssl s_client -connect scan.coverity.com:443 | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' | sudo tee -a /etc/ssl/certs/ca- - sudo add-apt-repository ppa:ubuntu-lxc/daily -y - sudo apt-get update -qq - - sudo apt-get install -qq libapparmor-dev libcap-dev libseccomp-dev python3-dev python3-setuptools docbook2x libgnutls-dev liblua5.2-dev libselinux1-dev + - sudo apt-get install -qq libapparmor-dev libcap-dev libseccomp-dev python3-dev python3-setuptools docbook2x libgnutls-dev libselinux1-dev script: - ./autogen.sh - rm -Rf build diff --git a/Makefile.am b/Makefile.am index 4071ec929..14712bc43 100644 --- a/Makefile.am +++ b/Makefile.am @@ -13,10 +13,6 @@ EXTRA_DIST = \ RPMARGS = -if ENABLE_LUA -RPMARGS += --with lua -endif - if ENABLE_PYTHON RPMARGS += --with python endif diff --git a/configure.ac b/configure.ac index 6da315952..8c1f806aa 100644 --- a/configure.ac +++ b/configure.ac @@ -416,53 +416,6 @@ m4_ifdef([PKG_CHECK_VAR], [], ])# PKG_CHECK_VAR ]) -# Lua module and scripts -AC_ARG_ENABLE([lua], - [AC_HELP_STRING([--enable-lua], [enable lua binding [default=auto]])], - [], [enable_lua=auto]) - -AC_ARG_WITH([lua-pc], - [AS_HELP_STRING( - [--with-lua-pc=PKG], - [Specify pkg-config package name for lua] - )], [], [with_lua_pc=no]) - -if test "x$enable_lua" = "xyes" -a "x$with_lua_pc" != "xno"; then - # exit with error if not found - PKG_CHECK_MODULES([LUA], [$with_lua_pc], [LUAPKGCONFIG=$with_lua_pc]) -fi - -if test "x$enable_lua" = "xauto" -a "x$with_lua_pc" != "xno"; then - PKG_CHECK_MODULES([LUA], [$with_lua_pc], - [LUAPKGCONFIG=$with_lua_pc - enable_lua=yes], - [enable_lua=no]) -fi - -if test "x$enable_lua" != "xno"; then - PKG_CHECK_MODULES([LUA], [lua], [LUAPKGCONFIG=lua], - [PKG_CHECK_MODULES([LUA], [lua5.2], [LUAPKGCONFIG=lua5.2], - [PKG_CHECK_MODULES([LUA], [lua5.1], [LUAPKGCONFIG=lua5.1], - [AS_IF([test "x$enable_lua" = "xyes"], - [AC_MSG_ERROR([Lua not found. Please use --with-lua-pc=PKG])], - [enable_lua=no])] - )] - )]) - AS_IF([test "x$LUAPKGCONFIG" != "x"], [enable_lua=yes]) -fi - -AM_CONDITIONAL([ENABLE_LUA], - [test "x$enable_lua" = "xyes"]) - -AM_COND_IF([ENABLE_LUA], - [AC_MSG_CHECKING([Lua version]) - PKG_CHECK_VAR([LUA_VERSION], [$LUAPKGCONFIG], [V],, - [PKG_CHECK_VAR([LUA_VERSION], [$LUAPKGCONFIG], [major_version])]) - AC_MSG_RESULT([$LUA_VERSION]) - AC_SUBST([LUA_LIBDIR], [$libdir/lua/$LUA_VERSION]) - AC_SUBST([LUA_SHAREDIR], [$datadir/lua/$LUA_VERSION]) - ]) - # Optional bash integration AC_ARG_ENABLE([bash], [AC_HELP_STRING([--enable-bash], [build bash integration [default=yes]])], @@ -943,8 +896,6 @@ AC_CONFIG_FILES([ src/lxc/version.h src/python-lxc/Makefile - src/lua-lxc/Makefile - src/tests/Makefile src/tests/lxc-test-usernic ]) @@ -1007,7 +958,6 @@ PAM: - cgroup PAM module: $pamdir Bindings: - - lua: $enable_lua - python3: $enable_python Documentation: diff --git a/lxc.spec.in b/lxc.spec.in index 9aa7dd4c8..f750b1e18 100644 --- a/lxc.spec.in +++ b/lxc.spec.in @@ -21,7 +21,6 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA %global with_python %{?_with_python: 1} %{?!_with_python: 0} -%global with_lua %{?_with_lua: 1} %{?!_with_lua: 0} # Set with_systemd on distros that use it, so we can install the service # file, otherwise the sysvinit script will be installed @@ -124,23 +123,10 @@ Requires: %{name} = %{version}-%{release}, pkgconfig The %{name}-devel package contains header files and library needed for development of the Linux containers. -%if %{with_lua} -%package lua -Summary: Lua bindings for %{name} -Group: System Environment/Libraries -Requires: lua-filesystem lua-alt-getopt -BuildRequires: lua-devel -%description lua -The %{name}-lua package contains %{name} bindings for lua. -%endif - %prep %setup -q -n %{name}-%{version}%{?beta_dot} %build PATH=$PATH:/usr/sbin:/sbin %configure $args \ -%if %{with_lua} - --enable-lua \ -%endif %if %{with_python} --enable-python \ %endif @@ -284,13 +270,6 @@ fi %{python3_sitearch}/* %endif -%if %{with_lua} -%files lua -%defattr(-,root,root) -%{_datadir}/lua -%{_libdir}/lua -%endif - %files devel %defattr(-,root,root) %{_includedir}/%{name}/* diff --git a/src/Makefile.am b/src/Makefile.am index c96cbe79f..4e4d66b5e 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1 +1 @@ -SUBDIRS = lxc tests python-lxc lua-lxc +SUBDIRS = lxc tests python-lxc diff --git a/src/lua-lxc/Makefile.am b/src/lua-lxc/Makefile.am deleted file mode 100644 index 348de8d38..000000000 --- a/src/lua-lxc/Makefile.am +++ /dev/null @@ -1,38 +0,0 @@ -if ENABLE_LUA - -luasharedir=$(LUA_SHAREDIR) -lualibdir=$(LUA_LIBDIR) -luadir=$(luasharedir) -sodir=$(lualibdir)/lxc - -lua_DATA=lxc.lua - -lib_LTLIBRARIES = libcore.la -libcore_la_SOURCES = core.c - -AM_CFLAGS=-I$(top_builddir)/src -I$(top_srcdir)/src $(LUA_CFLAGS) -DVERSION=\"$(VERSION)\" -DLXCPATH=\"$(LXCPATH)\" - -libcore_la_CFLAGS = -fPIC -DPIC $(AM_CFLAGS) - -libcore_la_LDFLAGS = \ - -shared \ - -L$(top_builddir)/src/lxc \ - -Wl,-soname,core.so.$(firstword $(subst ., ,$(VERSION))) - -libcore_la_LIBADD = -llxc - -install-exec-local: install-libLTLIBRARIES - mkdir -p $(DESTDIR)$(lualibdir)/lxc/ - mv $(DESTDIR)$(libdir)/libcore.so.0.0.0 $(DESTDIR)$(lualibdir)/lxc/core.so - rm $(DESTDIR)$(libdir)/libcore.* - -uninstall-local: - $(RM) $(DESTDIR)$(lualibdir)/lxc/core.so* - -lxc.lua: - -endif - -EXTRA_DIST= \ - lxc.lua \ - test/apitest.lua diff --git a/src/lua-lxc/core.c b/src/lua-lxc/core.c deleted file mode 100644 index 3fb915ba4..000000000 --- a/src/lua-lxc/core.c +++ /dev/null @@ -1,614 +0,0 @@ -/* - * lua-lxc: lua bindings for lxc - * - * Copyright © 2012 Oracle. - * - * Authors: - * Dwight Engen - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#define LUA_LIB -#define _GNU_SOURCE -#include -#include -#include -#include -#include -#include -#include -#include "lxc/commands.h" - -#if LUA_VERSION_NUM < 502 -#define luaL_newlib(L,l) (lua_newtable(L), luaL_register(L,NULL,l)) -#define luaL_setfuncs(L,l,n) (assert(n==0), luaL_register(L,NULL,l)) -#define luaL_checkunsigned(L,n) luaL_checknumber(L,n) -#endif - -#if LUA_VERSION_NUM >= 503 -#ifndef luaL_checkunsigned -#define luaL_checkunsigned(L,n) ((lua_Unsigned)luaL_checkinteger(L,n)) -#endif -#endif - -#ifdef NO_CHECK_UDATA -#define checkudata(L,i,tname) lua_touserdata(L, i) -#else -#define checkudata(L,i,tname) luaL_checkudata(L, i, tname) -#endif - -#define lua_boxpointer(L,u) \ - (*(void **) (lua_newuserdata(L, sizeof(void *))) = (u)) - -#define lua_unboxpointer(L,i,tname) \ - (*(void **) (checkudata(L, i, tname))) - -#define CONTAINER_TYPENAME "lxc.container" - -/* Max Lua arguments for function */ -#define MAXVARS 200 - -static int container_new(lua_State *L) -{ - struct lxc_container *c; - const char *name = luaL_checkstring(L, 1); - const char *configpath = NULL; - int argc = lua_gettop(L); - - if (argc > 1) - configpath = luaL_checkstring(L, 2); - - c = lxc_container_new(name, configpath); - if (c) { - lua_boxpointer(L, c); - luaL_getmetatable(L, CONTAINER_TYPENAME); - lua_setmetatable(L, -2); - } else { - lua_pushnil(L); - } - return 1; -} - -static int container_gc(lua_State *L) -{ - struct lxc_container *c = lua_unboxpointer(L, 1, CONTAINER_TYPENAME); - - /* XXX what to do if this fails? */ - lxc_container_put(c); - return 0; -} - -static int container_config_file_name(lua_State *L) -{ - struct lxc_container *c = lua_unboxpointer(L, 1, CONTAINER_TYPENAME); - char *config_file_name; - - config_file_name = c->config_file_name(c); - lua_pushstring(L, config_file_name); - free(config_file_name); - return 1; -} - -static int container_defined(lua_State *L) -{ - struct lxc_container *c = lua_unboxpointer(L, 1, CONTAINER_TYPENAME); - - lua_pushboolean(L, !!c->is_defined(c)); - return 1; -} - -static int container_name(lua_State *L) -{ - struct lxc_container *c = lua_unboxpointer(L, 1, CONTAINER_TYPENAME); - - lua_pushstring(L, c->name); - return 1; -} - -static int container_create(lua_State *L) -{ - struct lxc_container *c = lua_unboxpointer(L, 1, CONTAINER_TYPENAME); - char *template_name = strdupa(luaL_checkstring(L, 2)); - int argc = lua_gettop(L); - char **argv; - int i; - - argv = alloca((argc+1) * sizeof(char *)); - for (i = 0; i < argc-2; i++) - argv[i] = strdupa(luaL_checkstring(L, i+3)); - argv[i] = NULL; - - lua_pushboolean(L, !!c->create(c, template_name, NULL, NULL, 0, argv)); - return 1; -} - -static int container_destroy(lua_State *L) -{ - struct lxc_container *c = lua_unboxpointer(L, 1, CONTAINER_TYPENAME); - - lua_pushboolean(L, !!c->destroy(c)); - return 1; -} - -/* container state */ -static int container_start(lua_State *L) -{ - struct lxc_container *c = lua_unboxpointer(L, 1, CONTAINER_TYPENAME); - int argc = lua_gettop(L); - char **argv = NULL; - int i,j; - int useinit = 0; - - if (argc > 1) { - argv = alloca((argc+1) * sizeof(char *)); - for (i = 0, j = 0; i < argc-1; i++) { - const char *arg = luaL_checkstring(L, i+2); - - if (!strcmp(arg, "useinit")) - useinit = 1; - else - argv[j++] = strdupa(arg); - } - argv[j] = NULL; - } - - c->want_daemonize(c, true); - lua_pushboolean(L, !!c->start(c, useinit, argv)); - return 1; -} - -static int container_stop(lua_State *L) -{ - struct lxc_container *c = lua_unboxpointer(L, 1, CONTAINER_TYPENAME); - - lua_pushboolean(L, !!c->stop(c)); - return 1; -} - -static int container_shutdown(lua_State *L) -{ - struct lxc_container *c = lua_unboxpointer(L, 1, CONTAINER_TYPENAME); - int timeout = luaL_checkinteger(L, 2); - - lua_pushboolean(L, !!c->shutdown(c, timeout)); - return 1; -} - -static int container_wait(lua_State *L) -{ - struct lxc_container *c = lua_unboxpointer(L, 1, CONTAINER_TYPENAME); - const char *state = luaL_checkstring(L, 2); - int timeout = luaL_checkinteger(L, 3); - - lua_pushboolean(L, !!c->wait(c, state, timeout)); - return 1; -} - -static int container_rename(lua_State *L) -{ - struct lxc_container *c = lua_unboxpointer(L, 1, CONTAINER_TYPENAME); - const char *new_name; - int argc = lua_gettop(L); - - if (argc > 1) { - new_name = luaL_checkstring(L, 2); - lua_pushboolean(L, !!c->rename(c, new_name)); - } else - lua_pushnil(L); - return 1; -} - -static int container_freeze(lua_State *L) -{ - struct lxc_container *c = lua_unboxpointer(L, 1, CONTAINER_TYPENAME); - - lua_pushboolean(L, !!c->freeze(c)); - return 1; -} - -static int container_unfreeze(lua_State *L) -{ - struct lxc_container *c = lua_unboxpointer(L, 1, CONTAINER_TYPENAME); - - lua_pushboolean(L, !!c->unfreeze(c)); - return 1; -} - -static int container_running(lua_State *L) -{ - struct lxc_container *c = lua_unboxpointer(L, 1, CONTAINER_TYPENAME); - - lua_pushboolean(L, !!c->is_running(c)); - return 1; -} - -static int container_state(lua_State *L) -{ - struct lxc_container *c = lua_unboxpointer(L, 1, CONTAINER_TYPENAME); - - lua_pushstring(L, c->state(c)); - return 1; -} - -static int container_init_pid(lua_State *L) -{ - struct lxc_container *c = lua_unboxpointer(L, 1, CONTAINER_TYPENAME); - - lua_pushinteger(L, c->init_pid(c)); - return 1; -} - -/* configuration file methods */ -static int container_load_config(lua_State *L) -{ - struct lxc_container *c = lua_unboxpointer(L, 1, CONTAINER_TYPENAME); - int arg_cnt = lua_gettop(L); - const char *alt_path = NULL; - - if (arg_cnt > 1) - alt_path = luaL_checkstring(L, 2); - - lua_pushboolean(L, !!c->load_config(c, alt_path)); - return 1; -} - -static int container_save_config(lua_State *L) -{ - struct lxc_container *c = lua_unboxpointer(L, 1, CONTAINER_TYPENAME); - int arg_cnt = lua_gettop(L); - const char *alt_path = NULL; - - if (arg_cnt > 1) - alt_path = luaL_checkstring(L, 2); - - lua_pushboolean(L, !!c->save_config(c, alt_path)); - return 1; -} - -static int container_get_config_path(lua_State *L) -{ - struct lxc_container *c = lua_unboxpointer(L, 1, CONTAINER_TYPENAME); - const char *config_path; - - config_path = c->get_config_path(c); - lua_pushstring(L, config_path); - return 1; -} - -static int container_set_config_path(lua_State *L) -{ - struct lxc_container *c = lua_unboxpointer(L, 1, CONTAINER_TYPENAME); - const char *config_path = luaL_checkstring(L, 2); - - lua_pushboolean(L, !!c->set_config_path(c, config_path)); - return 1; -} - -static int container_clear_config_item(lua_State *L) -{ - struct lxc_container *c = lua_unboxpointer(L, 1, CONTAINER_TYPENAME); - const char *key = luaL_checkstring(L, 2); - - lua_pushboolean(L, !!c->clear_config_item(c, key)); - return 1; -} - -static int container_get_cgroup_item(lua_State *L) -{ - struct lxc_container *c = lua_unboxpointer(L, 1, CONTAINER_TYPENAME); - const char *key = luaL_checkstring(L, 2); - int len; - char *value; - - len = c->get_cgroup_item(c, key, NULL, 0); - if (len <= 0) - goto not_found; - - value = alloca(sizeof(char)*len + 1); - if (c->get_cgroup_item(c, key, value, len + 1) != len) - goto not_found; - - lua_pushstring(L, value); - return 1; - -not_found: - lua_pushnil(L); - return 1; -} - -static int container_get_config_item(lua_State *L) -{ - struct lxc_container *c = lua_unboxpointer(L, 1, CONTAINER_TYPENAME); - const char *key = luaL_checkstring(L, 2); - int len; - char *value; - - len = c->get_config_item(c, key, NULL, 0); - if (len <= 0) - goto not_found; - - value = alloca(sizeof(char)*len + 1); - if (c->get_config_item(c, key, value, len + 1) != len) - goto not_found; - - lua_pushstring(L, value); - return 1; - -not_found: - lua_pushnil(L); - return 1; -} - -static int container_set_cgroup_item(lua_State *L) -{ - struct lxc_container *c = lua_unboxpointer(L, 1, CONTAINER_TYPENAME); - const char *key = luaL_checkstring(L, 2); - const char *value = luaL_checkstring(L, 3); - - lua_pushboolean(L, !!c->set_cgroup_item(c, key, value)); - return 1; -} - -static int container_set_config_item(lua_State *L) -{ - struct lxc_container *c = lua_unboxpointer(L, 1, CONTAINER_TYPENAME); - const char *key = luaL_checkstring(L, 2); - const char *value = luaL_checkstring(L, 3); - - lua_pushboolean(L, !!c->set_config_item(c, key, value)); - return 1; -} - -static int container_get_keys(lua_State *L) -{ - struct lxc_container *c = lua_unboxpointer(L, 1, CONTAINER_TYPENAME); - const char *key = NULL; - int len; - char *value; - int arg_cnt = lua_gettop(L); - - if (arg_cnt > 1) - key = luaL_checkstring(L, 2); - - len = c->get_keys(c, key, NULL, 0); - if (len <= 0) - goto not_found; - - value = alloca(sizeof(char)*len + 1); - if (c->get_keys(c, key, value, len + 1) != len) - goto not_found; - - lua_pushstring(L, value); - return 1; - -not_found: - lua_pushnil(L); - return 1; -} - -static int container_attach(lua_State *L) -{ - struct lxc_container *c = lua_unboxpointer(L, 1, CONTAINER_TYPENAME); - int argc = lua_gettop(L); - char **argv = NULL; - int i; - - if (argc > 1) { - argv = alloca((argc+1) * sizeof(char *)); - for (i = 0; i < argc-1; i++) { - const char *arg = luaL_checkstring(L, i+2); - argv[i] = strdupa(arg); - } - argv[i] = NULL; - } - else - { - lua_pushnil(L); - return 1; - } - - lua_pushboolean(L, !(c->attach_run_wait(c, NULL, argv[0], (const char**)argv))); - return 1; -} - -static int container_get_interfaces(lua_State *L) -{ - struct lxc_container *c = lua_unboxpointer(L, 1, CONTAINER_TYPENAME); - char **ifaces; - int i; - - ifaces = c->get_interfaces(c); - - if (!ifaces){ - lua_pushnil(L); - return 1; - } - - for (i = 0; ifaces[i]; i++); - - /* protect LUA stack form overflow */ - if (i > MAXVARS || !lua_checkstack(L, i)){ - for (i = 0; ifaces[i]; i++) - free(ifaces[i]); - lua_pushnil(L); - return 1; - } - for (i = 0; ifaces[i]; i++){ - lua_pushstring(L, ifaces[i]); - free(ifaces[i]); - } - return i; -} - -static int container_get_ips(lua_State *L) -{ - struct lxc_container *c = lua_unboxpointer(L, 1, CONTAINER_TYPENAME); - int argc = lua_gettop(L); - char **addresses; - char *iface = NULL, *family = NULL; - int i, scope = 0; - - if (argc > 1) - iface = (char *)luaL_checkstring(L, 2); - if (argc > 2) - family = (char *)luaL_checkstring(L, 3); - if (argc > 3) - scope = luaL_checkinteger(L, 4); - - addresses = c->get_ips(c, iface, family, scope); - - if (!addresses){ - lua_pushnil(L); - return 1; - } - - for (i = 0; addresses[i]; i++); - - /* protect LUA stack form overflow */ - if (i > MAXVARS || !lua_checkstack(L, i)){ - for (i = 0; addresses[i]; i++) - free(addresses[i]); - lua_pushnil(L); - return 1; - } - for (i = 0; addresses[i]; i++){ - lua_pushstring(L, addresses[i]); - free(addresses[i]); - } - return i; -} - -static luaL_Reg lxc_container_methods[] = -{ - {"attach", container_attach}, - {"create", container_create}, - {"defined", container_defined}, - {"destroy", container_destroy}, - {"init_pid", container_init_pid}, - {"name", container_name}, - {"running", container_running}, - {"state", container_state}, - {"freeze", container_freeze}, - {"unfreeze", container_unfreeze}, - {"start", container_start}, - {"stop", container_stop}, - {"shutdown", container_shutdown}, - {"wait", container_wait}, - {"rename", container_rename}, - - {"config_file_name", container_config_file_name}, - {"load_config", container_load_config}, - {"save_config", container_save_config}, - {"get_cgroup_item", container_get_cgroup_item}, - {"set_cgroup_item", container_set_cgroup_item}, - {"get_config_path", container_get_config_path}, - {"set_config_path", container_set_config_path}, - {"get_config_item", container_get_config_item}, - {"set_config_item", container_set_config_item}, - {"clear_config_item", container_clear_config_item}, - {"get_keys", container_get_keys}, - {"get_interfaces", container_get_interfaces}, - {"get_ips", container_get_ips}, - {NULL, NULL} -}; - -static int lxc_version_get(lua_State *L) { - lua_pushstring(L, VERSION); - return 1; -} - -static int lxc_default_config_path_get(lua_State *L) { - const char *lxcpath = lxc_get_global_config_item("lxc.lxcpath"); - - lua_pushstring(L, lxcpath); - return 1; -} - -static int cmd_get_config_item(lua_State *L) -{ - int arg_cnt = lua_gettop(L); - const char *name = luaL_checkstring(L, 1); - const char *key = luaL_checkstring(L, 2); - const char *lxcpath = NULL; - char *value; - - if (arg_cnt > 2) - lxcpath = luaL_checkstring(L, 3); - - value = lxc_cmd_get_config_item(name, key, lxcpath); - if (!value) - goto not_found; - - lua_pushstring(L, value); - return 1; - -not_found: - lua_pushnil(L); - return 1; -} - -/* utility functions */ -static int lxc_util_usleep(lua_State *L) { - usleep((useconds_t)luaL_checkunsigned(L, 1)); - return 0; -} - -static int lxc_util_dirname(lua_State *L) { - char *path = strdupa(luaL_checkstring(L, 1)); - lua_pushstring(L, dirname(path)); - return 1; -} - -static luaL_Reg lxc_lib_methods[] = { - {"version_get", lxc_version_get}, - {"default_config_path_get", lxc_default_config_path_get}, - {"cmd_get_config_item", cmd_get_config_item}, - {"container_new", container_new}, - {"usleep", lxc_util_usleep}, - {"dirname", lxc_util_dirname}, - {NULL, NULL} -}; - -static int lxc_lib_uninit(lua_State *L) { - (void) L; - /* this is where we would fini liblxc.so if we needed to */ - return 0; -} - -LUALIB_API int luaopen_lxc_core(lua_State *L) { - /* this is where we would initialize liblxc.so if we needed to */ - - luaL_newlib(L, lxc_lib_methods); - - lua_newuserdata(L, 0); - lua_newtable(L); /* metatable */ - lua_pushvalue(L, -1); - lua_pushliteral(L, "__gc"); - lua_pushcfunction(L, lxc_lib_uninit); - lua_rawset(L, -3); - lua_setmetatable(L, -3); - lua_rawset(L, -3); - - luaL_newmetatable(L, CONTAINER_TYPENAME); - luaL_setfuncs(L, lxc_container_methods, 0); - lua_pushvalue(L, -1); /* push metatable */ - lua_pushstring(L, "__gc"); - lua_pushcfunction(L, container_gc); - lua_settable(L, -3); - lua_setfield(L, -2, "__index"); /* metatable.__index = metatable */ - lua_pop(L, 1); - return 1; -} diff --git a/src/lua-lxc/lxc.lua b/src/lua-lxc/lxc.lua deleted file mode 100755 index 3d1de1014..000000000 --- a/src/lua-lxc/lxc.lua +++ /dev/null @@ -1,421 +0,0 @@ --- --- lua lxc module --- --- Copyright © 2012 Oracle. --- --- Authors: --- Dwight Engen --- --- This library is free software; you can redistribute it and/or --- modify it under the terms of the GNU Lesser General Public --- License as published by the Free Software Foundation; either --- version 2.1 of the License, or (at your option) any later version. --- --- This library is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU --- Lesser General Public License for more details. --- --- You should have received a copy of the GNU Lesser General Public --- License along with this library; if not, write to the Free Software --- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA --- - -local core = require("lxc.core") -local lfs = require("lfs") -local table = require("table") -local string = require("string") -local io = require("io") -module("lxc", package.seeall) - -local lxc_path -local log_level = 3 - --- lua 5.1 compat -if table.unpack == nil then - table.unpack = unpack -end - --- the following two functions can be useful for debugging -function printf(...) - local function wrapper(...) io.write(string.format(...)) end - local status, result = pcall(wrapper, ...) - if not status then - error(result, 2) - end -end - -function log(level, ...) - if (log_level >= level) then - printf(os.date("%Y-%m-%d %T ")) - printf(...) - end -end - -function string:split(delim, max_cols) - local cols = {} - local start = 1 - local nextc - repeat - nextc = string.find(self, delim, start) - if (nextc and #cols ~= max_cols - 1) then - table.insert(cols, string.sub(self, start, nextc-1)) - start = nextc + #delim - else - table.insert(cols, string.sub(self, start, string.len(self))) - nextc = nil - end - until nextc == nil or start > #self - return cols -end - --- container class -container = {} -container_mt = {} -container_mt.__index = container - -function container:new(lname, config) - local lcore - local lnetcfg = {} - local lstats = {} - - if lname then - if config then - lcore = core.container_new(lname, config) - else - lcore = core.container_new(lname) - end - end - - return setmetatable({ctname = lname, core = lcore, netcfg = lnetcfg, stats = lstats}, container_mt) -end - --- methods interfacing to core functionality -function container:attach(what, ...) - return self.core:attach(what, ...) -end - -function container:config_file_name() - return self.core:config_file_name() -end - -function container:defined() - return self.core:defined() -end - -function container:init_pid() - return self.core:init_pid() -end - -function container:name() - return self.core:name() -end - -function container:start() - return self.core:start() -end - -function container:stop() - return self.core:stop() -end - -function container:shutdown(timeout) - return self.core:shutdown(timeout) -end - -function container:wait(state, timeout) - return self.core:wait(state, timeout) -end - -function container:freeze() - return self.core:freeze() -end - -function container:unfreeze() - return self.core:unfreeze() -end - -function container:running() - return self.core:running() -end - -function container:state() - return self.core:state() -end - -function container:create(template, ...) - return self.core:create(template, ...) -end - -function container:destroy() - return self.core:destroy() -end - --- return nil if name missing -function container:rename(name) - return self.core:rename(name) -end - -function container:get_config_path() - return self.core:get_config_path() -end - -function container:set_config_path(path) - return self.core:set_config_path(path) -end - -function container:append_config_item(key, value) - return self.core:set_config_item(key, value) -end - -function container:clear_config_item(key) - return self.core:clear_config_item(key) -end - -function container:get_cgroup_item(key) - return self.core:get_cgroup_item(key) -end - -function container:get_config_item(key) - local value - local vals = {} - - value = self.core:get_config_item(key) - - -- check if it is a single item - if (not value or not string.find(value, "\n")) then - return value - end - - -- it must be a list type item, make a table of it - vals = value:split("\n", 1000) - -- make it a "mixed" table, ie both dictionary and list for ease of use - for _,v in ipairs(vals) do - vals[v] = true - end - return vals -end - -function container:set_cgroup_item(key, value) - return self.core:set_cgroup_item(key, value) -end - -function container:set_config_item(key, value) - return self.core:set_config_item(key, value) -end - -function container:get_keys(base) - local ktab = {} - local keys - - if (base) then - keys = self.core:get_keys(base) - base = base .. "." - else - keys = self.core:get_keys() - base = "" - end - if (keys == nil) then - return nil - end - keys = keys:split("\n", 1000) - for _,v in ipairs(keys) do - local config_item = base .. v - ktab[v] = self.core:get_config_item(config_item) - end - return ktab -end - --- return nil or more args -function container:get_interfaces() - return self.core:get_interfaces() -end - --- return nil or more args -function container:get_ips(...) - return self.core:get_ips(...) -end - -function container:load_config(alt_path) - if (alt_path) then - return self.core:load_config(alt_path) - else - return self.core:load_config() - end -end - -function container:save_config(alt_path) - if (alt_path) then - return self.core:save_config(alt_path) - else - return self.core:save_config() - end -end - --- methods for stats collection from various cgroup files --- read integers at given coordinates from a cgroup file -function container:stat_get_ints(item, coords) - local lines = {} - local result = {} - local flines = self:get_cgroup_item(item) - - if (flines == nil) then - for k,c in ipairs(coords) do - table.insert(result, 0) - end - else - for line in flines:gmatch("[^\r\n]+") do - table.insert(lines, line) - end - for k,c in ipairs(coords) do - local col - - col = lines[c[1]]:split(" ", 80) - local val = tonumber(col[c[2]]) - table.insert(result, val) - end - end - return table.unpack(result) -end - --- read an integer from a cgroup file -function container:stat_get_int(item) - local line = self:get_cgroup_item(item) - -- if line is nil (on an error like Operation not supported because - -- CONFIG_MEMCG_SWAP_ENABLED isn't enabled) return 0 - return tonumber(line) or 0 -end - -function container:stat_match_get_int(item, match, column) - local val - local lines = self:get_cgroup_item(item) - - if (lines == nil) then - return 0 - end - - for line in lines:gmatch("[^\r\n]+") do - if (string.find(line, match)) then - local col - - col = line:split(" ", 80) - val = tonumber(col[column]) or 0 - end - end - - return val -end - -function container:stats_get(total) - local stat = {} - stat.mem_used = self:stat_get_int("memory.usage_in_bytes") - stat.mem_limit = self:stat_get_int("memory.limit_in_bytes") - stat.memsw_used = self:stat_get_int("memory.memsw.usage_in_bytes") - stat.memsw_limit = self:stat_get_int("memory.memsw.limit_in_bytes") - stat.kmem_used = self:stat_get_int("memory.kmem.usage_in_bytes") - stat.kmem_limit = self:stat_get_int("memory.kmem.limit_in_bytes") - stat.cpu_use_nanos = self:stat_get_int("cpuacct.usage") - stat.cpu_use_user, - stat.cpu_use_sys = self:stat_get_ints("cpuacct.stat", {{1, 2}, {2, 2}}) - stat.blkio = self:stat_match_get_int("blkio.throttle.io_service_bytes", "Total", 2) - - if (total) then - total.mem_used = total.mem_used + stat.mem_used - total.mem_limit = total.mem_limit + stat.mem_limit - total.memsw_used = total.memsw_used + stat.memsw_used - total.memsw_limit = total.memsw_limit + stat.memsw_limit - total.kmem_used = total.kmem_used + stat.kmem_used - total.kmem_limit = total.kmem_limit + stat.kmem_limit - total.cpu_use_nanos = total.cpu_use_nanos + stat.cpu_use_nanos - total.cpu_use_user = total.cpu_use_user + stat.cpu_use_user - total.cpu_use_sys = total.cpu_use_sys + stat.cpu_use_sys - total.blkio = total.blkio + stat.blkio - end - return stat -end - -local M = { container = container } - -function M.stats_clear(stat) - stat.mem_used = 0 - stat.mem_limit = 0 - stat.memsw_used = 0 - stat.memsw_limit = 0 - stat.kmem_used = 0 - stat.kmem_limit = 0 - stat.cpu_use_nanos = 0 - stat.cpu_use_user = 0 - stat.cpu_use_sys = 0 - stat.blkio = 0 -end - --- return configured containers found in LXC_PATH directory -function M.containers_configured(names_only) - local containers = {} - - for dir in lfs.dir(lxc_path) do - if (dir ~= "." and dir ~= "..") - then - local cfgfile = lxc_path .. "/" .. dir .. "/config" - local cfgattr = lfs.attributes(cfgfile) - - if (cfgattr and cfgattr.mode == "file") then - if (names_only) then - -- note, this is a "mixed" table, ie both dictionary and list - containers[dir] = true - table.insert(containers, dir) - else - local ct = container:new(dir) - -- note, this is a "mixed" table, ie both dictionary and list - containers[dir] = ct - table.insert(containers, dir) - end - end - end - end - table.sort(containers, function (a,b) return (a < b) end) - return containers -end - --- return running containers found in cgroup fs -function M.containers_running(names_only) - local containers = {} - local names = M.containers_configured(true) - - for _,name in ipairs(names) do - local ct = container:new(name) - if ct:running() then - -- note, this is a "mixed" table, ie both dictionary and list - table.insert(containers, name) - if (names_only) then - containers[name] = true - ct = nil - else - containers[name] = ct - end - end - end - - table.sort(containers, function (a,b) return (a < b) end) - return containers -end - -function M.version_get() - return core.version_get() -end - -function M.default_config_path_get() - return core.default_config_path_get() -end - -function M.cmd_get_config_item(name, item, lxcpath) - if (lxcpath) then - return core.cmd_get_config_item(name, item, lxcpath) - else - return core.cmd_get_config_item(name, item) - end -end - -lxc_path = core.default_config_path_get() - -return M diff --git a/src/lua-lxc/test/apitest.lua b/src/lua-lxc/test/apitest.lua deleted file mode 100755 index 99cded75b..000000000 --- a/src/lua-lxc/test/apitest.lua +++ /dev/null @@ -1,353 +0,0 @@ -#!/usr/bin/env lua --- --- test the lxc lua api --- --- Copyright © 2012 Oracle. --- --- Authors: --- Dwight Engen --- --- This library is free software; you can redistribute it and/or modify --- it under the terms of the GNU General Public License version 2, as --- published by the Free Software Foundation. --- --- This program is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU General Public License for more details. --- --- You should have received a copy of the GNU General Public License along --- with this program; if not, write to the Free Software Foundation, Inc., --- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. --- - -local lxc = require("lxc") -local lfs = require("lfs") -local getopt = require("alt_getopt") - -local LXC_PATH = lxc.default_config_path_get() - -local container -local cfg_containers = {} -local optarg = {} -local optind = {} - -function printf(...) - local function wrapper(...) io.write(string.format(...)) end - local status, result = pcall(wrapper, ...) - if not status then - error(result, 2) - end -end - -function log(level, ...) - if (optarg["v"] >= level) then - printf(os.date("%Y-%m-%d %T ")) - printf(...) - printf("\n") - end -end - -function die(...) - printf(...) - os.exit(1) -end - -function test_global_info() - local cfg_containers - local run_containers - - log(0, "%-20s %s", "LXC version:", lxc.version_get()) - log(0, "%-20s %s", "Container name:", optarg["n"]) - if (optarg["c"]) then - log(0, "%-20s %s", "Creating container:", "yes") - log(0, "%-20s %s", "With template:", optarg["t"]) - end - log(0, "%-20s %s", "Containers path:", LXC_PATH) - - cfg_containers = lxc.containers_configured() - log(0, "%-20s", "Containers configured:") - for _,v in ipairs(cfg_containers) do - log(0, " %s", v) - end - - run_containers = lxc.containers_running(true) - log(0, "%-20s", "Containers running:") - for _,v in ipairs(run_containers) do - log(0, " %s", v) - end -end - -function test_container_new() - container = lxc.container:new(optarg["n"]) - assert(container ~= nil) - assert(container:config_file_name() == string.format("%s/%s/config", LXC_PATH, optarg["n"])) -end - -function test_container_config_path() - local cfgcontainer - local cfgpath = "/tmp/" .. optarg["n"] - local cfgname = cfgpath .. "/config" - - log(0, "Test container config path...") - - -- create a config file in the new location from container's config - assert(lfs.mkdir(cfgpath)) - assert(container:save_config(cfgname)) - cfgcontainer = lxc.container:new(optarg["n"], "/tmp") - assert(cfgcontainer ~= nil) - log(0, "cfgname:%s cfgpath:%s", cfgcontainer:config_file_name(), cfgcontainer:get_config_path()) - assert(cfgcontainer:config_file_name() == cfgname) - assert(cfgcontainer:get_config_path() == "/tmp") - assert(cfgcontainer:set_config_path(LXC_PATH)) - assert(cfgcontainer:get_config_path() == LXC_PATH) - - assert(os.remove(cfgname)) - assert(lfs.rmdir(cfgpath)) -end - -function test_container_create() - if (optarg["c"]) then - log(0, "%-20s %s", "Destroy existing container:", optarg["n"]) - container:destroy() - assert(container:defined() == false) - else - local cfg_containers = lxc.containers_configured() - if (cfg_containers[optarg["n"]]) then - log(0, "%-20s %s", "Use existing container:", optarg["n"]) - return - end - end - log(0, "%-20s %s", "Creating rootfs using:", optarg["t"]) - assert(container:create(optarg["t"]) == true) - assert(container:defined() == true) - assert(container:name() == optarg["n"]) -end - -function test_container_started() - local now_running - log(2, "state:%s pid:%d\n", container:state(), container:init_pid()) - assert(container:init_pid() > 1) - assert(container:running() == true) - assert(container:state() == "RUNNING") - now_running = lxc.containers_running(true) - assert(now_running[optarg["n"]] ~= nil) - log(1, "%-20s %s", "Running, init pid:", container:init_pid()) -end - -function test_container_stopped() - local now_running - assert(container:init_pid() == -1) - assert(container:running() == false) - assert(container:state() == "STOPPED") - now_running = lxc.containers_running(true) - assert(now_running[optarg["n"]] == nil) -end - -function test_container_frozen() - local now_running - assert(container:init_pid() > 1) - assert(container:running() == true) - assert(container:state() == "FROZEN") - now_running = lxc.containers_running(true) - assert(now_running[optarg["n"]] ~= nil) -end - -function test_container_start() - log(0, "Starting...") - if (not container:start()) then - log(1, "Start returned failure, waiting another 10 seconds...") - container:wait("RUNNING", 10) - end - container:wait("RUNNING", 1) -end - -function test_container_stop() - log(0, "Stopping...") - if (not container:stop()) then - log(1, "Stop returned failure, waiting another 10 seconds...") - container:wait("STOPPED", 10) - end - container:wait("STOPPED", 1) -end - -function test_container_freeze() - log(0, "Freezing...") - if (not container:freeze()) then - log(1, "Freeze returned failure, waiting another 10 seconds...") - container:wait("FROZEN", 10) - end -end - -function test_container_unfreeze() - log(0, "Unfreezing...") - if (not container:unfreeze()) then - log(1, "Unfreeze returned failure, waiting another 10 seconds...") - container:wait("RUNNING", 10) - end -end - -function test_container_shutdown() - log(0, "Shutting down...") - container:shutdown(5) - - if (container:running()) then - test_container_stop() - end -end - -function test_container_in_cfglist(should_find) - local cfg_containers = lxc.containers_configured() - - if (should_find) then - assert(cfg_containers[container:name()] ~= nil) - else - assert(cfg_containers[container:name()] == nil) - end -end - -function test_container_attach() - log(0, "Test attach...") - assert(container:running() == true) - assert(container:attach("/bin/ps") == true) -end - -function test_container_cgroup() - log(0, "Test get/set cgroup items...") - - max_mem = container:get_cgroup_item("memory.max_usage_in_bytes") - saved_limit = container:get_cgroup_item("memory.limit_in_bytes") - assert(saved_limit ~= max_mem) - assert(container:set_cgroup_item("memory.limit_in_bytes", max_mem)) - assert(container:get_cgroup_item("memory.limit_in_bytes") ~= saved_limit) - assert(container:set_cgroup_item("memory.limit_in_bytes", "-1")) -end - -function test_container_cmd() - log(0, "Test get config from running container...") - veth_pair = lxc.cmd_get_config_item(optarg["n"], "lxc.net.0.veth.pair") - log(0, " veth.pair:%s", veth_pair) -end - -function test_config_items() - log(0, "Test set/clear configuration items...") - - -- test setting a 'single type' item - assert(container:get_config_item("lxc.uts.name") == optarg["n"]) - container:set_config_item("lxc.uts.name", "foobar") - assert(container:get_config_item("lxc.uts.name") == "foobar") - container:set_config_item("lxc.uts.name", optarg["n"]) - assert(container:get_config_item("lxc.uts.name") == optarg["n"]) - - -- test clearing/setting a 'list type' item - container:clear_config_item("lxc.cap.drop") - container:set_config_item("lxc.cap.drop", "new_cap1") - container:set_config_item("lxc.cap.drop", "new_cap2") - local cap_drop = container:get_config_item("lxc.cap.drop") - assert(cap_drop["new_cap1"] ~= nil) - assert(cap_drop["new_cap2"] ~= nil) - -- note: clear_config_item only works on list type items - container:clear_config_item("lxc.cap.drop") - assert(container:get_config_item("lxc.cap.drop") == nil) - - local altname = "/tmp/" .. optarg["n"] .. ".altconfig" - log(0, "Test saving to an alternate (%s) config file...", altname) - assert(container:save_config(altname)) - assert(os.remove(altname)) -end - -function test_config_mount_entries() - local mntents - - -- mount entries are a list type item - mntents = container:get_config_item("lxc.mount.entry") - log(0, "Mount entries:") - for _,v in ipairs(mntents) do - log(0, " %s", v) - end -end - -function test_config_keys() - local keys - - keys = container:get_keys() - log(0, "Top level keys:") - for k,v in pairs(keys) do - log(0, " %s = %s", k, v or "") - end -end - -function test_config_network(net_nr) - log(0, "Test network %d config...", net_nr) - local netcfg - - netcfg = container:get_keys("lxc.net." .. net_nr) - if (netcfg == nil) then - return - end - for k,v in pairs(netcfg) do - log(0, " %s = %s", k, v or "") - end - assert(netcfg["flags"] == "up") - assert(container:get_config_item("lxc.net."..net_nr..".type") == "veth") -end - - -function usage() - die("Usage: apitest \n" .. - " -v|--verbose increase verbosity with each -v\n" .. - " -h|--help print help message\n" .. - " -n|--name name of container to use for testing\n" .. - " -c|--create create the test container anew\n" .. - " -l|--login do interactive login test\n" .. - " -t|--template template to use when creating test container\n" - ) -end - -local long_opts = { - verbose = "v", - help = "h", - name = "n", - create = "c", - template = "t", -} - -optarg,optind = alt_getopt.get_opts (arg, "hvn:ct:", long_opts) -optarg["v"] = tonumber(optarg["v"]) or 0 -optarg["n"] = optarg["n"] or "lua-apitest" -optarg["c"] = optarg["c"] or nil -optarg["t"] = optarg["t"] or "busybox" -if (optarg["h"] ~= nil) then - usage() -end - -test_global_info() -test_container_new() -test_container_create() -test_container_stopped() -test_container_in_cfglist(true) -test_container_config_path() - -test_config_items() -test_config_keys() -test_config_mount_entries() -test_config_network(0) - -test_container_start() -test_container_started() - -test_container_attach() -test_container_cgroup() -test_container_cmd() - -test_container_freeze() -test_container_frozen() -test_container_unfreeze() -test_container_started() - -test_container_shutdown() -test_container_stopped() -container:destroy() -test_container_in_cfglist(false) - -log(0, "All tests passed")