]> git.proxmox.com Git - mirror_lxc.git/blame - src/lua-lxc/core.c
Move container creation fully into the api
[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 *
9 * This library is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2, as
11 * published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 */
22
23#define LUA_LIB
24#define _GNU_SOURCE
25#include <lua.h>
26#include <lauxlib.h>
27#include <string.h>
28#include <lxc/lxccontainer.h>
29
30#ifdef NO_CHECK_UDATA
31#define checkudata(L,i,tname) lua_touserdata(L, i)
32#else
33#define checkudata(L,i,tname) luaL_checkudata(L, i, tname)
34#endif
35
36#define lua_boxpointer(L,u) \
37 (*(void **) (lua_newuserdata(L, sizeof(void *))) = (u))
38
39#define lua_unboxpointer(L,i,tname) \
40 (*(void **) (checkudata(L, i, tname)))
41
42#define CONTAINER_TYPENAME "lxc.container"
43
44static int container_new(lua_State *L)
45{
83c98d82 46 struct lxc_container *c;
f080ffd7 47 const char *name = luaL_checkstring(L, 1);
83c98d82
DE
48 const char *configpath = NULL;
49 int argc = lua_gettop(L);
50
51 if (argc > 1)
52 configpath = luaL_checkstring(L, 2);
f080ffd7 53
83c98d82 54 c = lxc_container_new(name, configpath);
f080ffd7
DE
55 if (c) {
56 lua_boxpointer(L, c);
57 luaL_getmetatable(L, CONTAINER_TYPENAME);
58 lua_setmetatable(L, -2);
59 } else {
60 lua_pushnil(L);
61 }
62 return 1;
63}
64
65static int container_gc(lua_State *L)
66{
67 struct lxc_container *c = lua_unboxpointer(L, 1, CONTAINER_TYPENAME);
68
69 /* XXX what to do if this fails? */
70 lxc_container_put(c);
71 return 0;
72}
73
74static int container_config_file_name(lua_State *L)
75{
76 struct lxc_container *c = lua_unboxpointer(L, 1, CONTAINER_TYPENAME);
77 char *config_file_name;
78
79 config_file_name = c->config_file_name(c);
80 lua_pushstring(L, config_file_name);
81 free(config_file_name);
82 return 1;
83}
84
85static int container_defined(lua_State *L)
86{
87 struct lxc_container *c = lua_unboxpointer(L, 1, CONTAINER_TYPENAME);
88
89 lua_pushboolean(L, !!c->is_defined(c));
90 return 1;
91}
92
93static int container_name(lua_State *L)
94{
95 struct lxc_container *c = lua_unboxpointer(L, 1, CONTAINER_TYPENAME);
96
97 lua_pushstring(L, c->name);
98 return 1;
99}
100
101static int container_create(lua_State *L)
102{
103 struct lxc_container *c = lua_unboxpointer(L, 1, CONTAINER_TYPENAME);
104 char *template_name = strdupa(luaL_checkstring(L, 2));
105 int argc = lua_gettop(L);
106 char **argv;
107 int i;
108
109 argv = alloca((argc+1) * sizeof(char *));
110 for (i = 0; i < argc-2; i++)
111 argv[i] = strdupa(luaL_checkstring(L, i+3));
112 argv[i] = NULL;
113
1897e3bc 114 lua_pushboolean(L, !!c->create(c, template_name, NULL, NULL, argv));
f080ffd7
DE
115 return 1;
116}
117
118static int container_destroy(lua_State *L)
119{
120 struct lxc_container *c = lua_unboxpointer(L, 1, CONTAINER_TYPENAME);
121
122 lua_pushboolean(L, !!c->destroy(c));
123 return 1;
124}
125
126/* container state */
127static int container_start(lua_State *L)
128{
129 struct lxc_container *c = lua_unboxpointer(L, 1, CONTAINER_TYPENAME);
130 int argc = lua_gettop(L);
131 char **argv = NULL;
132 int i,j;
133 int useinit = 0;
134
135 if (argc > 1) {
136 argv = alloca((argc+1) * sizeof(char *));
137 for (i = 0, j = 0; i < argc-1; i++) {
138 const char *arg = luaL_checkstring(L, i+2);
139
140 if (!strcmp(arg, "useinit"))
141 useinit = 1;
142 else
143 argv[j++] = strdupa(arg);
144 }
145 argv[j] = NULL;
146 }
147
148 c->want_daemonize(c);
149 lua_pushboolean(L, !!c->start(c, useinit, argv));
150 return 1;
151}
152
153static int container_stop(lua_State *L)
154{
155 struct lxc_container *c = lua_unboxpointer(L, 1, CONTAINER_TYPENAME);
156
157 lua_pushboolean(L, !!c->stop(c));
158 return 1;
159}
160
161static int container_shutdown(lua_State *L)
162{
163 struct lxc_container *c = lua_unboxpointer(L, 1, CONTAINER_TYPENAME);
164 int timeout = luaL_checkinteger(L, 2);
165
166 lua_pushboolean(L, !!c->shutdown(c, timeout));
167 return 1;
168}
169
170static int container_wait(lua_State *L)
171{
172 struct lxc_container *c = lua_unboxpointer(L, 1, CONTAINER_TYPENAME);
173 const char *state = luaL_checkstring(L, 2);
174 int timeout = luaL_checkinteger(L, 3);
175
176 lua_pushboolean(L, !!c->wait(c, state, timeout));
177 return 1;
178}
179
180static int container_freeze(lua_State *L)
181{
182 struct lxc_container *c = lua_unboxpointer(L, 1, CONTAINER_TYPENAME);
183
184 lua_pushboolean(L, !!c->freeze(c));
185 return 1;
186}
187
188static int container_unfreeze(lua_State *L)
189{
190 struct lxc_container *c = lua_unboxpointer(L, 1, CONTAINER_TYPENAME);
191
192 lua_pushboolean(L, !!c->unfreeze(c));
193 return 1;
194}
195
196static int container_running(lua_State *L)
197{
198 struct lxc_container *c = lua_unboxpointer(L, 1, CONTAINER_TYPENAME);
199
200 lua_pushboolean(L, !!c->is_running(c));
201 return 1;
202}
203
204static int container_state(lua_State *L)
205{
206 struct lxc_container *c = lua_unboxpointer(L, 1, CONTAINER_TYPENAME);
207
208 lua_pushstring(L, c->state(c));
209 return 1;
210}
211
212static int container_init_pid(lua_State *L)
213{
214 struct lxc_container *c = lua_unboxpointer(L, 1, CONTAINER_TYPENAME);
215
216 lua_pushinteger(L, c->init_pid(c));
217 return 1;
218}
219
220/* configuration file methods */
221static int container_load_config(lua_State *L)
222{
223 struct lxc_container *c = lua_unboxpointer(L, 1, CONTAINER_TYPENAME);
224 int arg_cnt = lua_gettop(L);
225 const char *alt_path = NULL;
226
227 if (arg_cnt > 1)
228 alt_path = luaL_checkstring(L, 2);
229
230 lua_pushboolean(L, !!c->load_config(c, alt_path));
231 return 1;
232}
233
234static int container_save_config(lua_State *L)
235{
236 struct lxc_container *c = lua_unboxpointer(L, 1, CONTAINER_TYPENAME);
237 int arg_cnt = lua_gettop(L);
238 const char *alt_path = NULL;
239
240 if (arg_cnt > 1)
241 alt_path = luaL_checkstring(L, 2);
242
243 lua_pushboolean(L, !!c->save_config(c, alt_path));
244 return 1;
245}
246
83c98d82
DE
247static int container_get_config_path(lua_State *L)
248{
249 struct lxc_container *c = lua_unboxpointer(L, 1, CONTAINER_TYPENAME);
250 const char *config_path;
251
252 config_path = c->get_config_path(c);
253 lua_pushstring(L, config_path);
254 return 1;
255}
256
257static int container_set_config_path(lua_State *L)
258{
259 struct lxc_container *c = lua_unboxpointer(L, 1, CONTAINER_TYPENAME);
260 const char *config_path = luaL_checkstring(L, 2);
261
262 lua_pushboolean(L, !!c->set_config_path(c, config_path));
263 return 1;
264}
265
f080ffd7
DE
266static int container_clear_config_item(lua_State *L)
267{
268 struct lxc_container *c = lua_unboxpointer(L, 1, CONTAINER_TYPENAME);
269 const char *key = luaL_checkstring(L, 2);
270
271 lua_pushboolean(L, !!c->clear_config_item(c, key));
272 return 1;
273}
274
275static int container_get_config_item(lua_State *L)
276{
277 struct lxc_container *c = lua_unboxpointer(L, 1, CONTAINER_TYPENAME);
278 const char *key = luaL_checkstring(L, 2);
279 int len;
280 char *value;
281
282 len = c->get_config_item(c, key, NULL, 0);
283 if (len <= 0)
284 goto not_found;
285
286 value = alloca(sizeof(char)*len + 1);
287 if (c->get_config_item(c, key, value, len + 1) != len)
288 goto not_found;
289
290 lua_pushstring(L, value);
291 return 1;
292
293not_found:
294 lua_pushnil(L);
295 return 1;
296}
297
298static int container_set_config_item(lua_State *L)
299{
300 struct lxc_container *c = lua_unboxpointer(L, 1, CONTAINER_TYPENAME);
301 const char *key = luaL_checkstring(L, 2);
302 const char *value = luaL_checkstring(L, 3);
303
304 lua_pushboolean(L, !!c->set_config_item(c, key, value));
305 return 1;
306}
307
308static int container_get_keys(lua_State *L)
309{
310 struct lxc_container *c = lua_unboxpointer(L, 1, CONTAINER_TYPENAME);
311 const char *key = NULL;
312 int len;
313 char *value;
314 int arg_cnt = lua_gettop(L);
315
316 if (arg_cnt > 1)
317 key = luaL_checkstring(L, 2);
318
319 len = c->get_keys(c, key, NULL, 0);
320 if (len <= 0)
321 goto not_found;
322
323 value = alloca(sizeof(char)*len + 1);
324 if (c->get_keys(c, key, value, len + 1) != len)
325 goto not_found;
326
327 lua_pushstring(L, value);
328 return 1;
329
330not_found:
331 lua_pushnil(L);
332 return 1;
333}
334
335static luaL_Reg lxc_container_methods[] =
336{
337 {"create", container_create},
338 {"defined", container_defined},
339 {"destroy", container_destroy},
340 {"init_pid", container_init_pid},
341 {"name", container_name},
342 {"running", container_running},
343 {"state", container_state},
344 {"freeze", container_freeze},
345 {"unfreeze", container_unfreeze},
346 {"start", container_start},
347 {"stop", container_stop},
348 {"shutdown", container_shutdown},
349 {"wait", container_wait},
350
351 {"config_file_name", container_config_file_name},
352 {"load_config", container_load_config},
353 {"save_config", container_save_config},
83c98d82
DE
354 {"get_config_path", container_get_config_path},
355 {"set_config_path", container_set_config_path},
f080ffd7
DE
356 {"get_config_item", container_get_config_item},
357 {"set_config_item", container_set_config_item},
358 {"clear_config_item", container_clear_config_item},
359 {"get_keys", container_get_keys},
360 {NULL, NULL}
361};
362
363static int lxc_version_get(lua_State *L) {
364 lua_pushstring(L, VERSION);
365 return 1;
366}
367
83c98d82 368static int lxc_default_config_path_get(lua_State *L) {
67e571de 369 const char *lxcpath = lxc_get_default_config_path();
2a59a681 370
2a59a681 371 lua_pushstring(L, lxcpath);
f080ffd7
DE
372 return 1;
373}
374
375static luaL_Reg lxc_lib_methods[] = {
376 {"version_get", lxc_version_get},
83c98d82 377 {"default_config_path_get", lxc_default_config_path_get},
f080ffd7
DE
378 {"container_new", container_new},
379 {NULL, NULL}
380};
381
382static int lxc_lib_uninit(lua_State *L) {
383 (void) L;
384 /* this is where we would fini liblxc.so if we needed to */
385 return 0;
386}
387
388LUALIB_API int luaopen_lxc_core(lua_State *L) {
389 /* this is where we would initialize liblxc.so if we needed to */
390
391 luaL_register(L, "lxc", lxc_lib_methods);
392
393 lua_newuserdata(L, 0);
394 lua_newtable(L); /* metatable */
395 lua_pushvalue(L, -1);
396 lua_pushliteral(L, "__gc");
397 lua_pushcfunction(L, lxc_lib_uninit);
398 lua_rawset(L, -3);
399 lua_setmetatable(L, -3);
400 lua_rawset(L, -3);
401
402 luaL_newmetatable(L, CONTAINER_TYPENAME);
403 lua_pushvalue(L, -1); /* push metatable */
404 lua_pushstring(L, "__gc");
405 lua_pushcfunction(L, container_gc);
406 lua_settable(L, -3);
407 lua_setfield(L, -2, "__index"); /* metatable.__index = metatable */
408 luaL_register(L, NULL, lxc_container_methods);
409 lua_pop(L, 1);
410 return 1;
411}