Commit 1314b689 by Stéphane Graber

python3: Add clone() to the binding

parent 7ed86e44
...@@ -600,6 +600,61 @@ Container_clear_config_item(Container *self, PyObject *args, PyObject *kwds) ...@@ -600,6 +600,61 @@ Container_clear_config_item(Container *self, PyObject *args, PyObject *kwds)
} }
static PyObject * 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) Container_console(Container *self, PyObject *args, PyObject *kwds)
{ {
static char *kwlist[] = {"ttynum", "stdinfd", "stdoutfd", "stderrfd", static char *kwlist[] = {"ttynum", "stdinfd", "stdoutfd", "stderrfd",
...@@ -1220,6 +1275,13 @@ static PyMethodDef Container_methods[] = { ...@@ -1220,6 +1275,13 @@ static PyMethodDef Container_methods[] = {
"\n" "\n"
"Attach to container's console." "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, {"create", (PyCFunction)Container_create,
METH_VARARGS|METH_KEYWORDS, METH_VARARGS|METH_KEYWORDS,
"create(template, args = (,)) -> boolean\n" "create(template, args = (,)) -> boolean\n"
...@@ -1468,6 +1530,12 @@ PyInit__lxc(void) ...@@ -1468,6 +1530,12 @@ PyInit__lxc(void)
PYLXC_EXPORT_CONST(LXC_ATTACH_REMOUNT_PROC_SYS); PYLXC_EXPORT_CONST(LXC_ATTACH_REMOUNT_PROC_SYS);
PYLXC_EXPORT_CONST(LXC_ATTACH_SET_PERSONALITY); 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 #undef PYLXC_EXPORT_CONST
return m; return m;
......
...@@ -22,7 +22,6 @@ ...@@ -22,7 +22,6 @@
# #
import _lxc import _lxc
import glob
import os import os
import subprocess import subprocess
import stat import stat
...@@ -247,29 +246,29 @@ class Container(_lxc.Container): ...@@ -247,29 +246,29 @@ class Container(_lxc.Container):
return _lxc.Container.create(self, template, tuple(template_args)) 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: args = {}
return False args['newname'] = newname
args['flags'] = 0
if isinstance(container, Container): args['newsize'] = 0
source = container 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: else:
source = Container(container)
if not source.defined:
return False 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): def console(self, ttynum=-1, stdinfd=0, stdoutfd=1, stderrfd=2, escape=1):
""" """
Attach to console of running container. Attach to console of running container.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment