From: Stéphane Graber Date: Wed, 27 Nov 2013 23:27:27 +0000 (-0500) Subject: python3: Add clone() to the binding X-Git-Tag: lxc-1.0.0.beta1~76 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=1314b689ec0c03a820367d1960fe2422893d6309;p=thirdparty%2Flxc.git python3: Add clone() to the binding Signed-off-by: Stéphane Graber Acked-by: Serge E. Hallyn --- diff --git a/src/python-lxc/lxc.c b/src/python-lxc/lxc.c index 8c863239e..e9a3455f2 100644 --- a/src/python-lxc/lxc.c +++ b/src/python-lxc/lxc.c @@ -599,6 +599,61 @@ Container_clear_config_item(Container *self, PyObject *args, PyObject *kwds) Py_RETURN_FALSE; } +static PyObject * +Container_clone(Container *self, PyObject *args, PyObject *kwds) +{ + char *newname = NULL; + char *config_path = NULL; + int flags = 0; + char *bdevtype = NULL; + char *bdevdata = NULL; + unsigned long newsize = 0; + char **hookargs = NULL; + + PyObject *py_hookargs = NULL; + struct lxc_container *new_container = NULL; + int i = 0; + + static char *kwlist[] = {"newname", "config_path", "flags", "bdevtype", + "bdevdata", "newsize", "hookargs", NULL}; + if (! PyArg_ParseTupleAndKeywords(args, kwds, "s|sisskO", kwlist, + &newname, &config_path, &flags, + &bdevtype, &bdevdata, &newsize, + &py_hookargs)) + return NULL; + + if (py_hookargs) { + if (PyTuple_Check(py_hookargs)) { + hookargs = convert_tuple_to_char_pointer_array(py_hookargs); + if (!hookargs) { + return NULL; + } + } + else { + PyErr_SetString(PyExc_ValueError, "hookargs needs to be a tuple"); + return NULL; + } + } + + new_container = self->container->clone(self->container, newname, + config_path, flags, bdevtype, + bdevdata, newsize, hookargs); + + if (hookargs) { + for (i = 0; i < PyTuple_GET_SIZE(py_hookargs); i++) + free(hookargs[i]); + free(hookargs); + } + + if (new_container == NULL) { + Py_RETURN_FALSE; + } + + lxc_container_put(new_container); + + Py_RETURN_TRUE; +} + static PyObject * Container_console(Container *self, PyObject *args, PyObject *kwds) { @@ -1220,6 +1275,13 @@ static PyMethodDef Container_methods[] = { "\n" "Attach to container's console." }, + {"clone", (PyCFunction)Container_clone, + METH_VARARGS|METH_KEYWORDS, + "clone(newname, config_path, flags, bdevtype, bdevdata, newsize, " + "hookargs) -> boolean\n" + "\n" + "Create a new container based on the current one." + }, {"create", (PyCFunction)Container_create, METH_VARARGS|METH_KEYWORDS, "create(template, args = (,)) -> boolean\n" @@ -1468,6 +1530,12 @@ PyInit__lxc(void) PYLXC_EXPORT_CONST(LXC_ATTACH_REMOUNT_PROC_SYS); PYLXC_EXPORT_CONST(LXC_ATTACH_SET_PERSONALITY); + /* clone: clone flags */ + PYLXC_EXPORT_CONST(LXC_CLONE_COPYHOOKS); + PYLXC_EXPORT_CONST(LXC_CLONE_KEEPMACADDR); + PYLXC_EXPORT_CONST(LXC_CLONE_KEEPNAME); + PYLXC_EXPORT_CONST(LXC_CLONE_SNAPSHOT); + #undef PYLXC_EXPORT_CONST return m; diff --git a/src/python-lxc/lxc/__init__.py b/src/python-lxc/lxc/__init__.py index e0d4b5116..b900c753d 100644 --- a/src/python-lxc/lxc/__init__.py +++ b/src/python-lxc/lxc/__init__.py @@ -22,7 +22,6 @@ # import _lxc -import glob import os import subprocess import stat @@ -247,29 +246,29 @@ class Container(_lxc.Container): return _lxc.Container.create(self, template, tuple(template_args)) - def clone(self, container): + def clone(self, newname, config_path=None, flags=0, bdevtype=None, + bdevdata=None, newsize=0, hookargs=()): """ - Clone an existing container into a new one. + Clone the current container. """ - if self.defined: - return False - - if isinstance(container, Container): - source = container + args = {} + args['newname'] = newname + args['flags'] = 0 + args['newsize'] = 0 + args['hookargs'] = hookargs + if config_path: + args['config_path'] = config_path + if bdevtype: + args['bdevtype'] = bdevtype + if bdevdata: + args['bdevdata'] = bdevdata + + if _lxc.Container.clone(self, **args): + return Container(newname, config_path=config_path) else: - source = Container(container) - - if not source.defined: return False - if subprocess.call(["lxc-clone", "-o", source.name, "-n", self.name], - universal_newlines=True) != 0: - return False - - self.load_config() - return True - def console(self, ttynum=-1, stdinfd=0, stdoutfd=1, stderrfd=2, escape=1): """ Attach to console of running container.