2 * lua-lxc: lua bindings for lxc
4 * Copyright © 2012 Oracle.
7 * Dwight Engen <dwight.engen@oracle.com>
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
32 #include <lxc/lxccontainer.h>
33 #include "lxc/commands.h"
35 #if LUA_VERSION_NUM < 502
36 #define luaL_newlib(L,l) (lua_newtable(L), luaL_register(L,NULL,l))
37 #define luaL_setfuncs(L,l,n) (assert(n==0), luaL_register(L,NULL,l))
38 #define luaL_checkunsigned(L,n) luaL_checknumber(L,n)
41 #if LUA_VERSION_NUM >= 503
42 #ifndef luaL_checkunsigned
43 #define luaL_checkunsigned(L,n) ((lua_Unsigned)luaL_checkinteger(L,n))
48 #define checkudata(L,i,tname) lua_touserdata(L, i)
50 #define checkudata(L,i,tname) luaL_checkudata(L, i, tname)
53 #define lua_boxpointer(L,u) \
54 (*(void **) (lua_newuserdata(L, sizeof(void *))) = (u))
56 #define lua_unboxpointer(L,i,tname) \
57 (*(void **) (checkudata(L, i, tname)))
59 #define CONTAINER_TYPENAME "lxc.container"
61 /* Max Lua arguments for function */
64 static int container_new(lua_State
*L
)
66 struct lxc_container
*c
;
67 const char *name
= luaL_checkstring(L
, 1);
68 const char *configpath
= NULL
;
69 int argc
= lua_gettop(L
);
72 configpath
= luaL_checkstring(L
, 2);
74 c
= lxc_container_new(name
, configpath
);
77 luaL_getmetatable(L
, CONTAINER_TYPENAME
);
78 lua_setmetatable(L
, -2);
85 static int container_gc(lua_State
*L
)
87 struct lxc_container
*c
= lua_unboxpointer(L
, 1, CONTAINER_TYPENAME
);
89 /* XXX what to do if this fails? */
94 static int container_config_file_name(lua_State
*L
)
96 struct lxc_container
*c
= lua_unboxpointer(L
, 1, CONTAINER_TYPENAME
);
97 char *config_file_name
;
99 config_file_name
= c
->config_file_name(c
);
100 lua_pushstring(L
, config_file_name
);
101 free(config_file_name
);
105 static int container_defined(lua_State
*L
)
107 struct lxc_container
*c
= lua_unboxpointer(L
, 1, CONTAINER_TYPENAME
);
109 lua_pushboolean(L
, !!c
->is_defined(c
));
113 static int container_name(lua_State
*L
)
115 struct lxc_container
*c
= lua_unboxpointer(L
, 1, CONTAINER_TYPENAME
);
117 lua_pushstring(L
, c
->name
);
121 static int container_create(lua_State
*L
)
123 struct lxc_container
*c
= lua_unboxpointer(L
, 1, CONTAINER_TYPENAME
);
124 char *template_name
= strdupa(luaL_checkstring(L
, 2));
125 int argc
= lua_gettop(L
);
129 argv
= alloca((argc
+1) * sizeof(char *));
130 for (i
= 0; i
< argc
-2; i
++)
131 argv
[i
] = strdupa(luaL_checkstring(L
, i
+3));
134 lua_pushboolean(L
, !!c
->create(c
, template_name
, NULL
, NULL
, 0, argv
));
138 static int container_destroy(lua_State
*L
)
140 struct lxc_container
*c
= lua_unboxpointer(L
, 1, CONTAINER_TYPENAME
);
142 lua_pushboolean(L
, !!c
->destroy(c
));
146 /* container state */
147 static int container_start(lua_State
*L
)
149 struct lxc_container
*c
= lua_unboxpointer(L
, 1, CONTAINER_TYPENAME
);
150 int argc
= lua_gettop(L
);
156 argv
= alloca((argc
+1) * sizeof(char *));
157 for (i
= 0, j
= 0; i
< argc
-1; i
++) {
158 const char *arg
= luaL_checkstring(L
, i
+2);
160 if (!strcmp(arg
, "useinit"))
163 argv
[j
++] = strdupa(arg
);
168 c
->want_daemonize(c
, true);
169 lua_pushboolean(L
, !!c
->start(c
, useinit
, argv
));
173 static int container_stop(lua_State
*L
)
175 struct lxc_container
*c
= lua_unboxpointer(L
, 1, CONTAINER_TYPENAME
);
177 lua_pushboolean(L
, !!c
->stop(c
));
181 static int container_shutdown(lua_State
*L
)
183 struct lxc_container
*c
= lua_unboxpointer(L
, 1, CONTAINER_TYPENAME
);
184 int timeout
= luaL_checkinteger(L
, 2);
186 lua_pushboolean(L
, !!c
->shutdown(c
, timeout
));
190 static int container_wait(lua_State
*L
)
192 struct lxc_container
*c
= lua_unboxpointer(L
, 1, CONTAINER_TYPENAME
);
193 const char *state
= luaL_checkstring(L
, 2);
194 int timeout
= luaL_checkinteger(L
, 3);
196 lua_pushboolean(L
, !!c
->wait(c
, state
, timeout
));
200 static int container_rename(lua_State
*L
)
202 struct lxc_container
*c
= lua_unboxpointer(L
, 1, CONTAINER_TYPENAME
);
203 const char *new_name
;
204 int argc
= lua_gettop(L
);
207 new_name
= luaL_checkstring(L
, 2);
208 lua_pushboolean(L
, !!c
->rename(c
, new_name
));
214 static int container_freeze(lua_State
*L
)
216 struct lxc_container
*c
= lua_unboxpointer(L
, 1, CONTAINER_TYPENAME
);
218 lua_pushboolean(L
, !!c
->freeze(c
));
222 static int container_unfreeze(lua_State
*L
)
224 struct lxc_container
*c
= lua_unboxpointer(L
, 1, CONTAINER_TYPENAME
);
226 lua_pushboolean(L
, !!c
->unfreeze(c
));
230 static int container_running(lua_State
*L
)
232 struct lxc_container
*c
= lua_unboxpointer(L
, 1, CONTAINER_TYPENAME
);
234 lua_pushboolean(L
, !!c
->is_running(c
));
238 static int container_state(lua_State
*L
)
240 struct lxc_container
*c
= lua_unboxpointer(L
, 1, CONTAINER_TYPENAME
);
242 lua_pushstring(L
, c
->state(c
));
246 static int container_init_pid(lua_State
*L
)
248 struct lxc_container
*c
= lua_unboxpointer(L
, 1, CONTAINER_TYPENAME
);
250 lua_pushinteger(L
, c
->init_pid(c
));
254 /* configuration file methods */
255 static int container_load_config(lua_State
*L
)
257 struct lxc_container
*c
= lua_unboxpointer(L
, 1, CONTAINER_TYPENAME
);
258 int arg_cnt
= lua_gettop(L
);
259 const char *alt_path
= NULL
;
262 alt_path
= luaL_checkstring(L
, 2);
264 lua_pushboolean(L
, !!c
->load_config(c
, alt_path
));
268 static int container_save_config(lua_State
*L
)
270 struct lxc_container
*c
= lua_unboxpointer(L
, 1, CONTAINER_TYPENAME
);
271 int arg_cnt
= lua_gettop(L
);
272 const char *alt_path
= NULL
;
275 alt_path
= luaL_checkstring(L
, 2);
277 lua_pushboolean(L
, !!c
->save_config(c
, alt_path
));
281 static int container_get_config_path(lua_State
*L
)
283 struct lxc_container
*c
= lua_unboxpointer(L
, 1, CONTAINER_TYPENAME
);
284 const char *config_path
;
286 config_path
= c
->get_config_path(c
);
287 lua_pushstring(L
, config_path
);
291 static int container_set_config_path(lua_State
*L
)
293 struct lxc_container
*c
= lua_unboxpointer(L
, 1, CONTAINER_TYPENAME
);
294 const char *config_path
= luaL_checkstring(L
, 2);
296 lua_pushboolean(L
, !!c
->set_config_path(c
, config_path
));
300 static int container_clear_config_item(lua_State
*L
)
302 struct lxc_container
*c
= lua_unboxpointer(L
, 1, CONTAINER_TYPENAME
);
303 const char *key
= luaL_checkstring(L
, 2);
305 lua_pushboolean(L
, !!c
->clear_config_item(c
, key
));
309 static int container_get_cgroup_item(lua_State
*L
)
311 struct lxc_container
*c
= lua_unboxpointer(L
, 1, CONTAINER_TYPENAME
);
312 const char *key
= luaL_checkstring(L
, 2);
316 len
= c
->get_cgroup_item(c
, key
, NULL
, 0);
320 value
= alloca(sizeof(char)*len
+ 1);
321 if (c
->get_cgroup_item(c
, key
, value
, len
+ 1) != len
)
324 lua_pushstring(L
, value
);
332 static int container_get_config_item(lua_State
*L
)
334 struct lxc_container
*c
= lua_unboxpointer(L
, 1, CONTAINER_TYPENAME
);
335 const char *key
= luaL_checkstring(L
, 2);
339 len
= c
->get_config_item(c
, key
, NULL
, 0);
343 value
= alloca(sizeof(char)*len
+ 1);
344 if (c
->get_config_item(c
, key
, value
, len
+ 1) != len
)
347 lua_pushstring(L
, value
);
355 static int container_set_cgroup_item(lua_State
*L
)
357 struct lxc_container
*c
= lua_unboxpointer(L
, 1, CONTAINER_TYPENAME
);
358 const char *key
= luaL_checkstring(L
, 2);
359 const char *value
= luaL_checkstring(L
, 3);
361 lua_pushboolean(L
, !!c
->set_cgroup_item(c
, key
, value
));
365 static int container_set_config_item(lua_State
*L
)
367 struct lxc_container
*c
= lua_unboxpointer(L
, 1, CONTAINER_TYPENAME
);
368 const char *key
= luaL_checkstring(L
, 2);
369 const char *value
= luaL_checkstring(L
, 3);
371 lua_pushboolean(L
, !!c
->set_config_item(c
, key
, value
));
375 static int container_get_keys(lua_State
*L
)
377 struct lxc_container
*c
= lua_unboxpointer(L
, 1, CONTAINER_TYPENAME
);
378 const char *key
= NULL
;
381 int arg_cnt
= lua_gettop(L
);
384 key
= luaL_checkstring(L
, 2);
386 len
= c
->get_keys(c
, key
, NULL
, 0);
390 value
= alloca(sizeof(char)*len
+ 1);
391 if (c
->get_keys(c
, key
, value
, len
+ 1) != len
)
394 lua_pushstring(L
, value
);
402 static int container_attach(lua_State
*L
)
404 struct lxc_container
*c
= lua_unboxpointer(L
, 1, CONTAINER_TYPENAME
);
405 int argc
= lua_gettop(L
);
410 argv
= alloca((argc
+1) * sizeof(char *));
411 for (i
= 0; i
< argc
-1; i
++) {
412 const char *arg
= luaL_checkstring(L
, i
+2);
413 argv
[i
] = strdupa(arg
);
423 lua_pushboolean(L
, !(c
->attach_run_wait(c
, NULL
, argv
[0], (const char**)argv
)));
427 static int container_get_interfaces(lua_State
*L
)
429 struct lxc_container
*c
= lua_unboxpointer(L
, 1, CONTAINER_TYPENAME
);
433 ifaces
= c
->get_interfaces(c
);
440 for (i
= 0; ifaces
[i
]; i
++);
442 /* protect LUA stack form overflow */
443 if (i
> MAXVARS
|| !lua_checkstack(L
, i
)){
444 for (i
= 0; ifaces
[i
]; i
++)
449 for (i
= 0; ifaces
[i
]; i
++){
450 lua_pushstring(L
, ifaces
[i
]);
456 static int container_get_ips(lua_State
*L
)
458 struct lxc_container
*c
= lua_unboxpointer(L
, 1, CONTAINER_TYPENAME
);
459 int argc
= lua_gettop(L
);
461 char *iface
= NULL
, *family
= NULL
;
465 iface
= (char *)luaL_checkstring(L
, 2);
467 family
= (char *)luaL_checkstring(L
, 3);
469 scope
= luaL_checkinteger(L
, 4);
471 addresses
= c
->get_ips(c
, iface
, family
, scope
);
478 for (i
= 0; addresses
[i
]; i
++);
480 /* protect LUA stack form overflow */
481 if (i
> MAXVARS
|| !lua_checkstack(L
, i
)){
482 for (i
= 0; addresses
[i
]; i
++)
487 for (i
= 0; addresses
[i
]; i
++){
488 lua_pushstring(L
, addresses
[i
]);
494 static luaL_Reg lxc_container_methods
[] =
496 {"attach", container_attach
},
497 {"create", container_create
},
498 {"defined", container_defined
},
499 {"destroy", container_destroy
},
500 {"init_pid", container_init_pid
},
501 {"name", container_name
},
502 {"running", container_running
},
503 {"state", container_state
},
504 {"freeze", container_freeze
},
505 {"unfreeze", container_unfreeze
},
506 {"start", container_start
},
507 {"stop", container_stop
},
508 {"shutdown", container_shutdown
},
509 {"wait", container_wait
},
510 {"rename", container_rename
},
512 {"config_file_name", container_config_file_name
},
513 {"load_config", container_load_config
},
514 {"save_config", container_save_config
},
515 {"get_cgroup_item", container_get_cgroup_item
},
516 {"set_cgroup_item", container_set_cgroup_item
},
517 {"get_config_path", container_get_config_path
},
518 {"set_config_path", container_set_config_path
},
519 {"get_config_item", container_get_config_item
},
520 {"set_config_item", container_set_config_item
},
521 {"clear_config_item", container_clear_config_item
},
522 {"get_keys", container_get_keys
},
523 {"get_interfaces", container_get_interfaces
},
524 {"get_ips", container_get_ips
},
528 static int lxc_version_get(lua_State
*L
) {
529 lua_pushstring(L
, VERSION
);
533 static int lxc_default_config_path_get(lua_State
*L
) {
534 const char *lxcpath
= lxc_get_global_config_item("lxc.lxcpath");
536 lua_pushstring(L
, lxcpath
);
540 static int cmd_get_config_item(lua_State
*L
)
542 int arg_cnt
= lua_gettop(L
);
543 const char *name
= luaL_checkstring(L
, 1);
544 const char *key
= luaL_checkstring(L
, 2);
545 const char *lxcpath
= NULL
;
549 lxcpath
= luaL_checkstring(L
, 3);
551 value
= lxc_cmd_get_config_item(name
, key
, lxcpath
);
555 lua_pushstring(L
, value
);
563 /* utility functions */
564 static int lxc_util_usleep(lua_State
*L
) {
565 usleep((useconds_t
)luaL_checkunsigned(L
, 1));
569 static int lxc_util_dirname(lua_State
*L
) {
570 char *path
= strdupa(luaL_checkstring(L
, 1));
571 lua_pushstring(L
, dirname(path
));
575 static luaL_Reg lxc_lib_methods
[] = {
576 {"version_get", lxc_version_get
},
577 {"default_config_path_get", lxc_default_config_path_get
},
578 {"cmd_get_config_item", cmd_get_config_item
},
579 {"container_new", container_new
},
580 {"usleep", lxc_util_usleep
},
581 {"dirname", lxc_util_dirname
},
585 static int lxc_lib_uninit(lua_State
*L
) {
587 /* this is where we would fini liblxc.so if we needed to */
591 LUALIB_API
int luaopen_lxc_core(lua_State
*L
) {
592 /* this is where we would initialize liblxc.so if we needed to */
594 luaL_newlib(L
, lxc_lib_methods
);
596 lua_newuserdata(L
, 0);
597 lua_newtable(L
); /* metatable */
598 lua_pushvalue(L
, -1);
599 lua_pushliteral(L
, "__gc");
600 lua_pushcfunction(L
, lxc_lib_uninit
);
602 lua_setmetatable(L
, -3);
605 luaL_newmetatable(L
, CONTAINER_TYPENAME
);
606 luaL_setfuncs(L
, lxc_container_methods
, 0);
607 lua_pushvalue(L
, -1); /* push metatable */
608 lua_pushstring(L
, "__gc");
609 lua_pushcfunction(L
, container_gc
);
611 lua_setfield(L
, -2, "__index"); /* metatable.__index = metatable */