]> git.proxmox.com Git - mirror_lxc.git/blame - src/lua-lxc/core.c
lxc-alpine: create /dev/shm before mounting
[mirror_lxc.git] / src / lua-lxc / core.c
CommitLineData
f080ffd7
DE
1/*
2 * lua-lxc: lua bindings for lxc
3 *
4 * Copyright © 2012 Oracle.
5 *
6 * Authors:
7 * Dwight Engen <dwight.engen@oracle.com>
8 *
c66e9b01
SH
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.
13
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.
18
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
f080ffd7
DE
22 */
23
24#define LUA_LIB
25#define _GNU_SOURCE
26#include <lua.h>
27#include <lauxlib.h>
44a80d67 28#include <assert.h>
f080ffd7 29#include <string.h>
ac825528 30#include <unistd.h>
c25c2970 31#include <libgen.h>
f080ffd7 32#include <lxc/lxccontainer.h>
f2363e38 33#include "lxc/commands.h"
f080ffd7 34
44a80d67
NC
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))
ac825528 38#define luaL_checkunsigned(L,n) luaL_checknumber(L,n)
44a80d67
NC
39#endif
40
67f69573
TM
41#if LUA_VERSION_NUM >= 503
42#define luaL_checkunsigned(L,n) ((lua_Unsigned)luaL_checkinteger(L,n))
43#endif
44
f080ffd7
DE
45#ifdef NO_CHECK_UDATA
46#define checkudata(L,i,tname) lua_touserdata(L, i)
47#else
48#define checkudata(L,i,tname) luaL_checkudata(L, i, tname)
49#endif
50
51#define lua_boxpointer(L,u) \
52 (*(void **) (lua_newuserdata(L, sizeof(void *))) = (u))
53
54#define lua_unboxpointer(L,i,tname) \
55 (*(void **) (checkudata(L, i, tname)))
56
57#define CONTAINER_TYPENAME "lxc.container"
58
59static int container_new(lua_State *L)
60{
83c98d82 61 struct lxc_container *c;
f080ffd7 62 const char *name = luaL_checkstring(L, 1);
83c98d82
DE
63 const char *configpath = NULL;
64 int argc = lua_gettop(L);
65
66 if (argc > 1)
67 configpath = luaL_checkstring(L, 2);
f080ffd7 68
83c98d82 69 c = lxc_container_new(name, configpath);
f080ffd7
DE
70 if (c) {
71 lua_boxpointer(L, c);
72 luaL_getmetatable(L, CONTAINER_TYPENAME);
73 lua_setmetatable(L, -2);
74 } else {
75 lua_pushnil(L);
76 }
77 return 1;
78}
79
80static int container_gc(lua_State *L)
81{
82 struct lxc_container *c = lua_unboxpointer(L, 1, CONTAINER_TYPENAME);
83
84 /* XXX what to do if this fails? */
85 lxc_container_put(c);
86 return 0;
87}
88
89static int container_config_file_name(lua_State *L)
90{
91 struct lxc_container *c = lua_unboxpointer(L, 1, CONTAINER_TYPENAME);
92 char *config_file_name;
93
94 config_file_name = c->config_file_name(c);
95 lua_pushstring(L, config_file_name);
96 free(config_file_name);
97 return 1;
98}
99
100static int container_defined(lua_State *L)
101{
102 struct lxc_container *c = lua_unboxpointer(L, 1, CONTAINER_TYPENAME);
103
104 lua_pushboolean(L, !!c->is_defined(c));
105 return 1;
106}
107
108static int container_name(lua_State *L)
109{
110 struct lxc_container *c = lua_unboxpointer(L, 1, CONTAINER_TYPENAME);
111
112 lua_pushstring(L, c->name);
113 return 1;
114}
115
116static int container_create(lua_State *L)
117{
118 struct lxc_container *c = lua_unboxpointer(L, 1, CONTAINER_TYPENAME);
119 char *template_name = strdupa(luaL_checkstring(L, 2));
120 int argc = lua_gettop(L);
121 char **argv;
122 int i;
123
124 argv = alloca((argc+1) * sizeof(char *));
125 for (i = 0; i < argc-2; i++)
126 argv[i] = strdupa(luaL_checkstring(L, i+3));
127 argv[i] = NULL;
128
dc23c1c8 129 lua_pushboolean(L, !!c->create(c, template_name, NULL, NULL, 0, argv));
f080ffd7
DE
130 return 1;
131}
132
133static int container_destroy(lua_State *L)
134{
135 struct lxc_container *c = lua_unboxpointer(L, 1, CONTAINER_TYPENAME);
136
137 lua_pushboolean(L, !!c->destroy(c));
138 return 1;
139}
140
141/* container state */
142static int container_start(lua_State *L)
143{
144 struct lxc_container *c = lua_unboxpointer(L, 1, CONTAINER_TYPENAME);
145 int argc = lua_gettop(L);
146 char **argv = NULL;
147 int i,j;
148 int useinit = 0;
149
150 if (argc > 1) {
151 argv = alloca((argc+1) * sizeof(char *));
152 for (i = 0, j = 0; i < argc-1; i++) {
153 const char *arg = luaL_checkstring(L, i+2);
154
155 if (!strcmp(arg, "useinit"))
156 useinit = 1;
157 else
158 argv[j++] = strdupa(arg);
159 }
160 argv[j] = NULL;
161 }
162
540f932a 163 c->want_daemonize(c, true);
f080ffd7
DE
164 lua_pushboolean(L, !!c->start(c, useinit, argv));
165 return 1;
166}
167
168static int container_stop(lua_State *L)
169{
170 struct lxc_container *c = lua_unboxpointer(L, 1, CONTAINER_TYPENAME);
171
172 lua_pushboolean(L, !!c->stop(c));
173 return 1;
174}
175
176static int container_shutdown(lua_State *L)
177{
178 struct lxc_container *c = lua_unboxpointer(L, 1, CONTAINER_TYPENAME);
179 int timeout = luaL_checkinteger(L, 2);
180
181 lua_pushboolean(L, !!c->shutdown(c, timeout));
182 return 1;
183}
184
185static int container_wait(lua_State *L)
186{
187 struct lxc_container *c = lua_unboxpointer(L, 1, CONTAINER_TYPENAME);
188 const char *state = luaL_checkstring(L, 2);
189 int timeout = luaL_checkinteger(L, 3);
190
191 lua_pushboolean(L, !!c->wait(c, state, timeout));
192 return 1;
193}
194
195static int container_freeze(lua_State *L)
196{
197 struct lxc_container *c = lua_unboxpointer(L, 1, CONTAINER_TYPENAME);
198
199 lua_pushboolean(L, !!c->freeze(c));
200 return 1;
201}
202
203static int container_unfreeze(lua_State *L)
204{
205 struct lxc_container *c = lua_unboxpointer(L, 1, CONTAINER_TYPENAME);
206
207 lua_pushboolean(L, !!c->unfreeze(c));
208 return 1;
209}
210
211static int container_running(lua_State *L)
212{
213 struct lxc_container *c = lua_unboxpointer(L, 1, CONTAINER_TYPENAME);
214
215 lua_pushboolean(L, !!c->is_running(c));
216 return 1;
217}
218
219static int container_state(lua_State *L)
220{
221 struct lxc_container *c = lua_unboxpointer(L, 1, CONTAINER_TYPENAME);
222
223 lua_pushstring(L, c->state(c));
224 return 1;
225}
226
227static int container_init_pid(lua_State *L)
228{
229 struct lxc_container *c = lua_unboxpointer(L, 1, CONTAINER_TYPENAME);
230
231 lua_pushinteger(L, c->init_pid(c));
232 return 1;
233}
234
235/* configuration file methods */
236static int container_load_config(lua_State *L)
237{
238 struct lxc_container *c = lua_unboxpointer(L, 1, CONTAINER_TYPENAME);
239 int arg_cnt = lua_gettop(L);
240 const char *alt_path = NULL;
241
242 if (arg_cnt > 1)
243 alt_path = luaL_checkstring(L, 2);
244
245 lua_pushboolean(L, !!c->load_config(c, alt_path));
246 return 1;
247}
248
249static int container_save_config(lua_State *L)
250{
251 struct lxc_container *c = lua_unboxpointer(L, 1, CONTAINER_TYPENAME);
252 int arg_cnt = lua_gettop(L);
253 const char *alt_path = NULL;
254
255 if (arg_cnt > 1)
256 alt_path = luaL_checkstring(L, 2);
257
258 lua_pushboolean(L, !!c->save_config(c, alt_path));
259 return 1;
260}
261
83c98d82
DE
262static int container_get_config_path(lua_State *L)
263{
264 struct lxc_container *c = lua_unboxpointer(L, 1, CONTAINER_TYPENAME);
265 const char *config_path;
266
267 config_path = c->get_config_path(c);
268 lua_pushstring(L, config_path);
269 return 1;
270}
271
272static int container_set_config_path(lua_State *L)
273{
274 struct lxc_container *c = lua_unboxpointer(L, 1, CONTAINER_TYPENAME);
275 const char *config_path = luaL_checkstring(L, 2);
276
277 lua_pushboolean(L, !!c->set_config_path(c, config_path));
278 return 1;
279}
280
f080ffd7
DE
281static int container_clear_config_item(lua_State *L)
282{
283 struct lxc_container *c = lua_unboxpointer(L, 1, CONTAINER_TYPENAME);
284 const char *key = luaL_checkstring(L, 2);
285
286 lua_pushboolean(L, !!c->clear_config_item(c, key));
287 return 1;
288}
289
80ee2228
DE
290static int container_get_cgroup_item(lua_State *L)
291{
292 struct lxc_container *c = lua_unboxpointer(L, 1, CONTAINER_TYPENAME);
293 const char *key = luaL_checkstring(L, 2);
294 int len;
295 char *value;
296
297 len = c->get_cgroup_item(c, key, NULL, 0);
298 if (len <= 0)
299 goto not_found;
300
301 value = alloca(sizeof(char)*len + 1);
302 if (c->get_cgroup_item(c, key, value, len + 1) != len)
303 goto not_found;
304
305 lua_pushstring(L, value);
306 return 1;
307
308not_found:
309 lua_pushnil(L);
310 return 1;
311}
312
f080ffd7
DE
313static int container_get_config_item(lua_State *L)
314{
315 struct lxc_container *c = lua_unboxpointer(L, 1, CONTAINER_TYPENAME);
316 const char *key = luaL_checkstring(L, 2);
317 int len;
318 char *value;
319
320 len = c->get_config_item(c, key, NULL, 0);
321 if (len <= 0)
322 goto not_found;
323
324 value = alloca(sizeof(char)*len + 1);
325 if (c->get_config_item(c, key, value, len + 1) != len)
326 goto not_found;
327
328 lua_pushstring(L, value);
329 return 1;
330
331not_found:
332 lua_pushnil(L);
333 return 1;
334}
335
80ee2228
DE
336static int container_set_cgroup_item(lua_State *L)
337{
338 struct lxc_container *c = lua_unboxpointer(L, 1, CONTAINER_TYPENAME);
339 const char *key = luaL_checkstring(L, 2);
340 const char *value = luaL_checkstring(L, 3);
341
342 lua_pushboolean(L, !!c->set_cgroup_item(c, key, value));
343 return 1;
344}
345
f080ffd7
DE
346static int container_set_config_item(lua_State *L)
347{
348 struct lxc_container *c = lua_unboxpointer(L, 1, CONTAINER_TYPENAME);
349 const char *key = luaL_checkstring(L, 2);
350 const char *value = luaL_checkstring(L, 3);
351
352 lua_pushboolean(L, !!c->set_config_item(c, key, value));
353 return 1;
354}
355
356static int container_get_keys(lua_State *L)
357{
358 struct lxc_container *c = lua_unboxpointer(L, 1, CONTAINER_TYPENAME);
359 const char *key = NULL;
360 int len;
361 char *value;
362 int arg_cnt = lua_gettop(L);
363
364 if (arg_cnt > 1)
365 key = luaL_checkstring(L, 2);
366
367 len = c->get_keys(c, key, NULL, 0);
368 if (len <= 0)
369 goto not_found;
370
371 value = alloca(sizeof(char)*len + 1);
372 if (c->get_keys(c, key, value, len + 1) != len)
373 goto not_found;
374
375 lua_pushstring(L, value);
376 return 1;
377
378not_found:
379 lua_pushnil(L);
380 return 1;
381}
382
ed70d078
P
383static int container_attach(lua_State *L)
384{
385 struct lxc_container *c = lua_unboxpointer(L, 1, CONTAINER_TYPENAME);
386 int argc = lua_gettop(L);
387 char **argv = NULL;
2f64d631 388 int i;
ed70d078
P
389
390 if (argc > 1) {
391 argv = alloca((argc+1) * sizeof(char *));
2f64d631 392 for (i = 0; i < argc-1; i++) {
393 const char *arg = luaL_checkstring(L, i+2);
394 argv[i] = strdupa(arg);
ed70d078 395 }
2f64d631 396 argv[i] = NULL;
397 }
398 else
399 {
400 lua_pushnil(L);
401 return 1;
402 }
ed70d078 403
4086cea5 404 lua_pushboolean(L, !(c->attach_run_wait(c, NULL, argv[0], (const char**)argv)));
ed70d078
P
405 return 1;
406}
407
f080ffd7
DE
408static luaL_Reg lxc_container_methods[] =
409{
ed70d078 410 {"attach", container_attach},
f080ffd7
DE
411 {"create", container_create},
412 {"defined", container_defined},
413 {"destroy", container_destroy},
414 {"init_pid", container_init_pid},
415 {"name", container_name},
416 {"running", container_running},
417 {"state", container_state},
418 {"freeze", container_freeze},
419 {"unfreeze", container_unfreeze},
420 {"start", container_start},
421 {"stop", container_stop},
422 {"shutdown", container_shutdown},
423 {"wait", container_wait},
424
425 {"config_file_name", container_config_file_name},
426 {"load_config", container_load_config},
427 {"save_config", container_save_config},
80ee2228
DE
428 {"get_cgroup_item", container_get_cgroup_item},
429 {"set_cgroup_item", container_set_cgroup_item},
83c98d82
DE
430 {"get_config_path", container_get_config_path},
431 {"set_config_path", container_set_config_path},
f080ffd7
DE
432 {"get_config_item", container_get_config_item},
433 {"set_config_item", container_set_config_item},
434 {"clear_config_item", container_clear_config_item},
435 {"get_keys", container_get_keys},
436 {NULL, NULL}
437};
438
439static int lxc_version_get(lua_State *L) {
440 lua_pushstring(L, VERSION);
441 return 1;
442}
443
83c98d82 444static int lxc_default_config_path_get(lua_State *L) {
593e8478 445 const char *lxcpath = lxc_get_global_config_item("lxc.lxcpath");
2a59a681 446
2a59a681 447 lua_pushstring(L, lxcpath);
f080ffd7
DE
448 return 1;
449}
450
8585f204
DE
451static int cmd_get_config_item(lua_State *L)
452{
453 int arg_cnt = lua_gettop(L);
454 const char *name = luaL_checkstring(L, 1);
455 const char *key = luaL_checkstring(L, 2);
456 const char *lxcpath = NULL;
457 char *value;
458
459 if (arg_cnt > 2)
460 lxcpath = luaL_checkstring(L, 3);
461
462 value = lxc_cmd_get_config_item(name, key, lxcpath);
463 if (!value)
464 goto not_found;
465
466 lua_pushstring(L, value);
467 return 1;
468
469not_found:
470 lua_pushnil(L);
471 return 1;
472}
473
ac825528
NC
474/* utility functions */
475static int lxc_util_usleep(lua_State *L) {
476 usleep((useconds_t)luaL_checkunsigned(L, 1));
477 return 0;
478}
479
c25c2970
NC
480static int lxc_util_dirname(lua_State *L) {
481 char *path = strdupa(luaL_checkstring(L, 1));
482 lua_pushstring(L, dirname(path));
483 return 1;
484}
485
f080ffd7
DE
486static luaL_Reg lxc_lib_methods[] = {
487 {"version_get", lxc_version_get},
83c98d82 488 {"default_config_path_get", lxc_default_config_path_get},
8585f204 489 {"cmd_get_config_item", cmd_get_config_item},
f080ffd7 490 {"container_new", container_new},
ac825528 491 {"usleep", lxc_util_usleep},
c25c2970 492 {"dirname", lxc_util_dirname},
f080ffd7
DE
493 {NULL, NULL}
494};
495
496static int lxc_lib_uninit(lua_State *L) {
497 (void) L;
498 /* this is where we would fini liblxc.so if we needed to */
499 return 0;
500}
501
502LUALIB_API int luaopen_lxc_core(lua_State *L) {
503 /* this is where we would initialize liblxc.so if we needed to */
504
44a80d67 505 luaL_newlib(L, lxc_lib_methods);
f080ffd7
DE
506
507 lua_newuserdata(L, 0);
508 lua_newtable(L); /* metatable */
509 lua_pushvalue(L, -1);
510 lua_pushliteral(L, "__gc");
511 lua_pushcfunction(L, lxc_lib_uninit);
512 lua_rawset(L, -3);
513 lua_setmetatable(L, -3);
514 lua_rawset(L, -3);
515
516 luaL_newmetatable(L, CONTAINER_TYPENAME);
44a80d67 517 luaL_setfuncs(L, lxc_container_methods, 0);
f080ffd7
DE
518 lua_pushvalue(L, -1); /* push metatable */
519 lua_pushstring(L, "__gc");
520 lua_pushcfunction(L, container_gc);
521 lua_settable(L, -3);
522 lua_setfield(L, -2, "__index"); /* metatable.__index = metatable */
f080ffd7
DE
523 lua_pop(L, 1);
524 return 1;
525}