- 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
RPMARGS =
-if ENABLE_LUA
-RPMARGS += --with lua
-endif
-
if ENABLE_PYTHON
RPMARGS += --with python
endif
])# 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]])],
src/lxc/version.h
src/python-lxc/Makefile
- src/lua-lxc/Makefile
-
src/tests/Makefile
src/tests/lxc-test-usernic
])
- cgroup PAM module: $pamdir
Bindings:
- - lua: $enable_lua
- python3: $enable_python
Documentation:
# 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
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
%{python3_sitearch}/*
%endif
-%if %{with_lua}
-%files lua
-%defattr(-,root,root)
-%{_datadir}/lua
-%{_libdir}/lua
-%endif
-
%files devel
%defattr(-,root,root)
%{_includedir}/%{name}/*
-SUBDIRS = lxc tests python-lxc lua-lxc
+SUBDIRS = lxc tests python-lxc
+++ /dev/null
-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
+++ /dev/null
-/*
- * lua-lxc: lua bindings for lxc
- *
- * Copyright © 2012 Oracle.
- *
- * Authors:
- * Dwight Engen <dwight.engen@oracle.com>
- *
- * 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 <lua.h>
-#include <lauxlib.h>
-#include <assert.h>
-#include <string.h>
-#include <unistd.h>
-#include <libgen.h>
-#include <lxc/lxccontainer.h>
-#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;
-}
+++ /dev/null
---
--- lua lxc module
---
--- Copyright © 2012 Oracle.
---
--- Authors:
--- Dwight Engen <dwight.engen@oracle.com>
---
--- 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
+++ /dev/null
-#!/usr/bin/env lua
---
--- test the lxc lua api
---
--- Copyright © 2012 Oracle.
---
--- Authors:
--- Dwight Engen <dwight.engen@oracle.com>
---
--- 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 <options>\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")