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