[lxc-devel] [PATCH] python3: Add clone() to the binding

Stéphane Graber stgraber at ubuntu.com
Wed Nov 27 23:54:02 UTC 2013


Signed-off-by: Stéphane Graber <stgraber at ubuntu.com>
---
 src/python-lxc/lxc.c           | 68 ++++++++++++++++++++++++++++++++++++++++++
 src/python-lxc/lxc/__init__.py | 35 +++++++++++-----------
 2 files changed, 85 insertions(+), 18 deletions(-)

diff --git a/src/python-lxc/lxc.c b/src/python-lxc/lxc.c
index 8c86323..e9a3455 100644
--- a/src/python-lxc/lxc.c
+++ b/src/python-lxc/lxc.c
@@ -600,6 +600,61 @@ Container_clear_config_item(Container *self, PyObject *args, PyObject *kwds)
 }
 
 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)
 {
     static char *kwlist[] = {"ttynum", "stdinfd", "stdoutfd", "stderrfd",
@@ -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 e0d4b51..b900c75 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.
-- 
1.8.4.4





More information about the lxc-devel mailing list