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)
{
"\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"
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;
#
import _lxc
-import glob
import os
import subprocess
import stat
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.