Description: python: Lots of fixes in C extension
 Fixes a lot of issues found by a code review done by Barry Warsaw.
 .
 Those include:
  - Wrong signature for getters
  - Various memory leaks
  - Various optimizations
  - More consistent return values
  - Proper exception handling
 .
 Also cherry-pick the fixes to lxc-start-ephemeral and the python overlay.
Author: Stéphane Graber <stgraber@ubuntu.com>
Origin: upstream
Forwarded: not-needed

Index: raring-lxc/src/lxc/lxc-start-ephemeral.in
===================================================================
--- raring-lxc.orig/src/lxc/lxc-start-ephemeral.in	2013-04-18 22:26:44.219658989 +0200
+++ raring-lxc/src/lxc/lxc-start-ephemeral.in	2013-04-18 22:26:44.211658989 +0200
@@ -134,7 +134,9 @@
 dest.load_config(orig.config_file_name)
 dest.set_config_item("lxc.utsname", dest.name)
 dest.set_config_item("lxc.rootfs", os.path.join(dest_path, "rootfs"))
-dest.set_config_item("lxc.network.hwaddr", randomMAC())
+for nic in dest.network:
+    if hasattr(nic, 'hwaddr'):
+        nic.hwaddr = randomMAC()
 
 overlay_dirs = [(orig.get_config_item("lxc.rootfs"), "%s/rootfs/" % dest_path)]
 
@@ -287,7 +289,7 @@
     cmd += ["-l", args.user]
 
 if args.key:
-    cmd += ["-k", args.key]
+    cmd += ["-i", args.key]
 
 for ip in ips:
     ssh_cmd = cmd + [ip] + args.command
Index: raring-lxc/src/python-lxc/lxc.c
===================================================================
--- raring-lxc.orig/src/python-lxc/lxc.c	2013-04-18 22:26:44.219658989 +0200
+++ raring-lxc/src/python-lxc/lxc.c	2013-04-18 22:26:44.211658989 +0200
@@ -1,7 +1,7 @@
 /*
  * python-lxc: Python bindings for LXC
  *
- * (C) Copyright Canonical Ltd. 2012
+ * (C) Copyright Canonical Ltd. 2012-2013
  *
  * Authors:
  * Stéphane Graber <stgraber@ubuntu.com>
@@ -34,24 +34,40 @@
 
 char**
 convert_tuple_to_char_pointer_array(PyObject *argv) {
-    int argc = PyTuple_Size(argv);
+    int argc = PyTuple_GET_SIZE(argv);
     int i;
 
     char **result = (char**) malloc(sizeof(char*)*argc + 1);
 
+    if (result == NULL) {
+        PyErr_SetNone(PyExc_MemoryError);
+        return NULL;
+    }
+
     for (i = 0; i < argc; i++) {
-        PyObject *pyobj = PyTuple_GetItem(argv, i);
+        PyObject *pyobj = PyTuple_GET_ITEM(argv, i);
+        assert(pyobj != NULL);
 
         char *str = NULL;
-        PyObject *pystr;
+        PyObject *pystr = NULL;
         if (!PyUnicode_Check(pyobj)) {
             PyErr_SetString(PyExc_ValueError, "Expected a string");
+            free(result);
             return NULL;
         }
 
         pystr = PyUnicode_AsUTF8String(pyobj);
+        if (pystr == NULL) {
+            PyErr_SetString(PyExc_ValueError, "Unable to convert to UTF-8");
+            free(result);
+            return NULL;
+        }
+
         str = PyBytes_AsString(pystr);
+        assert(str != NULL);
+
         memcpy((char *) &result[i], (char *) &str, sizeof(str));
+        Py_DECREF(pystr);
     }
 
     result[argc] = NULL;
@@ -62,6 +78,7 @@
 static void
 Container_dealloc(Container* self)
 {
+    lxc_container_put(self->container);
     Py_TYPE(self)->tp_free((PyObject*)self);
 }
 
@@ -80,18 +97,27 @@
 {
     static char *kwlist[] = {"name", "config_path", NULL};
     char *name = NULL;
+    PyObject *fs_config_path = NULL;
     char *config_path = NULL;
 
-    if (!PyArg_ParseTupleAndKeywords(args, kwds, "s|s", kwlist,
-                                      &name, &config_path))
+    if (!PyArg_ParseTupleAndKeywords(args, kwds, "s|O&", kwlist,
+                                      &name,
+                                      PyUnicode_FSConverter, &fs_config_path))
         return -1;
 
+    if (fs_config_path != NULL) {
+        config_path = PyBytes_AS_STRING(fs_config_path);
+        assert(config_path != NULL);
+    }
+
     self->container = lxc_container_new(name, config_path);
     if (!self->container) {
-        fprintf(stderr, "%d: error creating lxc_container %s\n", __LINE__, name);
+        Py_XDECREF(fs_config_path);
+        fprintf(stderr, "%d: error creating container %s\n", __LINE__, name);
         return -1;
     }
 
+    Py_XDECREF(fs_config_path);
     return 0;
 }
 
@@ -109,13 +135,14 @@
 
 // Container properties
 static PyObject *
-Container_config_file_name(Container *self, PyObject *args, PyObject *kwds)
+Container_config_file_name(Container *self, void *closure)
 {
-    return PyUnicode_FromString(self->container->config_file_name(self->container));
+    return PyUnicode_FromString(
+                self->container->config_file_name(self->container));
 }
 
 static PyObject *
-Container_defined(Container *self, PyObject *args, PyObject *kwds)
+Container_defined(Container *self, void *closure)
 {
     if (self->container->is_defined(self->container)) {
         Py_RETURN_TRUE;
@@ -125,19 +152,19 @@
 }
 
 static PyObject *
-Container_init_pid(Container *self, PyObject *args, PyObject *kwds)
+Container_init_pid(Container *self, void *closure)
 {
-    return Py_BuildValue("i", self->container->init_pid(self->container));
+    return PyLong_FromLong(self->container->init_pid(self->container));
 }
 
 static PyObject *
-Container_name(Container *self, PyObject *args, PyObject *kwds)
+Container_name(Container *self, void *closure)
 {
     return PyUnicode_FromString(self->container->name);
 }
 
 static PyObject *
-Container_running(Container *self, PyObject *args, PyObject *kwds)
+Container_running(Container *self, void *closure)
 {
     if (self->container->is_running(self->container)) {
         Py_RETURN_TRUE;
@@ -147,7 +174,7 @@
 }
 
 static PyObject *
-Container_state(Container *self, PyObject *args, PyObject *kwds)
+Container_state(Container *self, void *closure)
 {
     return PyUnicode_FromString(self->container->state(self->container));
 }
@@ -159,9 +186,9 @@
     static char *kwlist[] = {"key", NULL};
     char *key = NULL;
 
-    if (! PyArg_ParseTupleAndKeywords(args, kwds, "s|", kwlist,
+    if (! PyArg_ParseTupleAndKeywords(args, kwds, "s", kwlist,
                                       &key))
-        Py_RETURN_FALSE;
+        return NULL;
 
     if (self->container->clear_config_item(self->container, key)) {
         Py_RETURN_TRUE;
@@ -175,25 +202,40 @@
 {
     char* template_name = NULL;
     char** create_args = {NULL};
-    PyObject *vargs = NULL;
+    PyObject *retval = NULL, *vargs = NULL;
     static char *kwlist[] = {"template", "args", NULL};
 
     if (! PyArg_ParseTupleAndKeywords(args, kwds, "s|O", kwlist,
                                       &template_name, &vargs))
-        Py_RETURN_FALSE;
+        return NULL;
 
-    if (vargs && PyTuple_Check(vargs)) {
-        create_args = convert_tuple_to_char_pointer_array(vargs);
-        if (!create_args) {
+    if (vargs) {
+        if (PyTuple_Check(vargs)) {
+            create_args = convert_tuple_to_char_pointer_array(vargs);
+            if (!create_args) {
+                return NULL;
+            }
+        }
+        else {
+            PyErr_SetString(PyExc_ValueError, "args needs to be a tuple");
             return NULL;
         }
     }
 
-    if (self->container->create(self->container, template_name, create_args)) {
-        Py_RETURN_TRUE;
+    if (self->container->create(self->container, template_name, create_args))
+        retval = Py_True;
+    else
+        retval = Py_False;
+
+    if (vargs) {
+        /* We cannot have gotten here unless vargs was given and create_args
+         * was successfully allocated.
+         */
+        free(create_args);
     }
 
-    Py_RETURN_FALSE;
+    Py_INCREF(retval);
+    return retval;
 }
 
 static PyObject *
@@ -222,23 +264,33 @@
     static char *kwlist[] = {"key", NULL};
     char* key = NULL;
     int len = 0;
+    PyObject *ret = NULL;
 
-    if (! PyArg_ParseTupleAndKeywords(args, kwds, "s|", kwlist,
+    if (! PyArg_ParseTupleAndKeywords(args, kwds, "s", kwlist,
                                       &key))
-        Py_RETURN_FALSE;
+        return NULL;
 
     len = self->container->get_cgroup_item(self->container, key, NULL, 0);
 
-    if (len <= 0) {
-        Py_RETURN_FALSE;
+    if (len < 0) {
+        PyErr_SetString(PyExc_KeyError, "Invalid cgroup entry");
+        return NULL;
     }
 
     char* value = (char*) malloc(sizeof(char)*len + 1);
-    if (self->container->get_cgroup_item(self->container, key, value, len + 1) != len) {
-        Py_RETURN_FALSE;
+    if (value == NULL)
+        return PyErr_NoMemory();
+
+    if (self->container->get_cgroup_item(self->container,
+                                            key, value, len + 1) != len) {
+        PyErr_SetString(PyExc_ValueError, "Unable to read config value");
+        free(value);
+        return NULL;
     }
 
-    return PyUnicode_FromString(value);
+    ret = PyUnicode_FromString(value);
+    free(value);
+    return ret;
 }
 
 static PyObject *
@@ -247,29 +299,40 @@
     static char *kwlist[] = {"key", NULL};
     char* key = NULL;
     int len = 0;
+    PyObject *ret = NULL;
 
     if (! PyArg_ParseTupleAndKeywords(args, kwds, "s|", kwlist,
                                       &key))
-        Py_RETURN_FALSE;
+        return NULL;
 
     len = self->container->get_config_item(self->container, key, NULL, 0);
 
-    if (len <= 0) {
-        Py_RETURN_FALSE;
+    if (len < 0) {
+        PyErr_SetString(PyExc_KeyError, "Invalid configuration key");
+        return NULL;
     }
 
     char* value = (char*) malloc(sizeof(char)*len + 1);
-    if (self->container->get_config_item(self->container, key, value, len + 1) != len) {
-        Py_RETURN_FALSE;
+    if (value == NULL)
+        return PyErr_NoMemory();
+
+    if (self->container->get_config_item(self->container,
+                                            key, value, len + 1) != len) {
+        PyErr_SetString(PyExc_ValueError, "Unable to read config value");
+        free(value);
+        return NULL;
     }
 
-    return PyUnicode_FromString(value);
+    ret = PyUnicode_FromString(value);
+    free(value);
+    return ret;
 }
 
 static PyObject *
 Container_get_config_path(Container *self, PyObject *args, PyObject *kwds)
 {
-    return PyUnicode_FromString(self->container->get_config_path(self->container));
+    return PyUnicode_FromString(
+                self->container->get_config_path(self->container));
 }
 
 static PyObject *
@@ -278,39 +341,57 @@
     static char *kwlist[] = {"key", NULL};
     char* key = NULL;
     int len = 0;
+    PyObject *ret = NULL;
 
     if (! PyArg_ParseTupleAndKeywords(args, kwds, "|s", kwlist,
                                       &key))
-        Py_RETURN_FALSE;
+        return NULL;
 
     len = self->container->get_keys(self->container, key, NULL, 0);
 
-    if (len <= 0) {
-        Py_RETURN_FALSE;
+    if (len < 0) {
+        PyErr_SetString(PyExc_KeyError, "Invalid configuration key");
+        return NULL;
     }
 
     char* value = (char*) malloc(sizeof(char)*len + 1);
-    if (self->container->get_keys(self->container, key, value, len + 1) != len) {
-        Py_RETURN_FALSE;
+    if (value == NULL)
+        return PyErr_NoMemory();
+
+    if (self->container->get_keys(self->container,
+                                    key, value, len + 1) != len) {
+        PyErr_SetString(PyExc_ValueError, "Unable to read config keys");
+        free(value);
+        return NULL;
     }
 
-    return PyUnicode_FromString(value);
+    ret = PyUnicode_FromString(value);
+    free(value);
+    return ret;
 }
 
 static PyObject *
 Container_load_config(Container *self, PyObject *args, PyObject *kwds)
 {
     static char *kwlist[] = {"path", NULL};
+    PyObject *fs_path = NULL;
     char* path = NULL;
 
-    if (! PyArg_ParseTupleAndKeywords(args, kwds, "|s", kwlist,
-                                      &path))
-        Py_RETURN_FALSE;
+    if (! PyArg_ParseTupleAndKeywords(args, kwds, "|O&", kwlist,
+                                      PyUnicode_FSConverter, &fs_path))
+        return NULL;
+
+    if (fs_path != NULL) {
+        path = PyBytes_AS_STRING(fs_path);
+        assert(path != NULL);
+    }
 
     if (self->container->load_config(self->container, path)) {
+        Py_XDECREF(fs_path);
         Py_RETURN_TRUE;
     }
 
+    Py_XDECREF(fs_path);
     Py_RETURN_FALSE;
 }
 
@@ -318,16 +399,24 @@
 Container_save_config(Container *self, PyObject *args, PyObject *kwds)
 {
     static char *kwlist[] = {"path", NULL};
+    PyObject *fs_path = NULL;
     char* path = NULL;
 
-    if (! PyArg_ParseTupleAndKeywords(args, kwds, "|s", kwlist,
-                                      &path))
-        Py_RETURN_FALSE;
+    if (! PyArg_ParseTupleAndKeywords(args, kwds, "|O&", kwlist,
+                                      PyUnicode_FSConverter, &fs_path))
+        return NULL;
+
+    if (fs_path != NULL) {
+        path = PyBytes_AS_STRING(fs_path);
+        assert(path != NULL);
+    }
 
     if (self->container->save_config(self->container, path)) {
+        Py_XDECREF(fs_path);
         Py_RETURN_TRUE;
     }
 
+    Py_XDECREF(fs_path);
     Py_RETURN_FALSE;
 }
 
@@ -338,9 +427,9 @@
     char *key = NULL;
     char *value = NULL;
 
-    if (! PyArg_ParseTupleAndKeywords(args, kwds, "ss|", kwlist,
+    if (! PyArg_ParseTupleAndKeywords(args, kwds, "ss", kwlist,
                                       &key, &value))
-        Py_RETURN_FALSE;
+        return NULL;
 
     if (self->container->set_cgroup_item(self->container, key, value)) {
         Py_RETURN_TRUE;
@@ -356,9 +445,9 @@
     char *key = NULL;
     char *value = NULL;
 
-    if (! PyArg_ParseTupleAndKeywords(args, kwds, "ss|", kwlist,
+    if (! PyArg_ParseTupleAndKeywords(args, kwds, "ss", kwlist,
                                       &key, &value))
-        Py_RETURN_FALSE;
+        return NULL;
 
     if (self->container->set_config_item(self->container, key, value)) {
         Py_RETURN_TRUE;
@@ -373,9 +462,9 @@
     static char *kwlist[] = {"path", NULL};
     char *path = NULL;
 
-    if (! PyArg_ParseTupleAndKeywords(args, kwds, "s|", kwlist,
+    if (! PyArg_ParseTupleAndKeywords(args, kwds, "s", kwlist,
                                       &path))
-        Py_RETURN_FALSE;
+        return NULL;
 
     if (self->container->set_config_path(self->container, path)) {
         Py_RETURN_TRUE;
@@ -392,7 +481,7 @@
 
     if (! PyArg_ParseTupleAndKeywords(args, kwds, "|i", kwlist,
                                       &timeout))
-        Py_RETURN_FALSE;
+        return NULL;
 
     if (self->container->shutdown(self->container, timeout)) {
         Py_RETURN_TRUE;
@@ -405,13 +494,13 @@
 Container_start(Container *self, PyObject *args, PyObject *kwds)
 {
     char** init_args = {NULL};
-    PyObject *useinit = NULL, *vargs = NULL;
+    PyObject *useinit = NULL, *retval = NULL, *vargs = NULL;
     int init_useinit = 0;
     static char *kwlist[] = {"useinit", "cmd", NULL};
 
     if (! PyArg_ParseTupleAndKeywords(args, kwds, "|OO", kwlist,
                                       &useinit, &vargs))
-        Py_RETURN_FALSE;
+        return NULL;
 
     if (useinit && useinit == Py_True) {
         init_useinit = 1;
@@ -426,11 +515,20 @@
 
     self->container->want_daemonize(self->container);
 
-    if (self->container->start(self->container, init_useinit, init_args)) {
-        Py_RETURN_TRUE;
+    if (self->container->start(self->container, init_useinit, init_args))
+        retval = Py_True;
+    else
+        retval = Py_False;
+
+    if (vargs) {
+        /* We cannot have gotten here unless vargs was given and create_args
+         * was successfully allocated.
+         */
+        free(init_args);
     }
 
-    Py_RETURN_FALSE;
+    Py_INCREF(retval);
+    return retval;
 }
 
 static PyObject *
@@ -462,7 +560,7 @@
 
     if (! PyArg_ParseTupleAndKeywords(args, kwds, "s|i", kwlist,
                                       &state, &timeout))
-        Py_RETURN_FALSE;
+        return NULL;
 
     if (self->container->wait(self->container, state, timeout)) {
         Py_RETURN_TRUE;
@@ -473,125 +571,143 @@
 
 static PyGetSetDef Container_getseters[] = {
     {"config_file_name",
-     (getter)Container_config_file_name, 0,
+     (getter)Container_config_file_name, NULL,
      "Path to the container configuration",
      NULL},
     {"defined",
-     (getter)Container_defined, 0,
+     (getter)Container_defined, NULL,
      "Boolean indicating whether the container configuration exists",
      NULL},
     {"init_pid",
-     (getter)Container_init_pid, 0,
+     (getter)Container_init_pid, NULL,
      "PID of the container's init process in the host's PID namespace",
      NULL},
     {"name",
-     (getter)Container_name, 0,
+     (getter)Container_name, NULL,
      "Container name",
      NULL},
     {"running",
-     (getter)Container_running, 0,
+     (getter)Container_running, NULL,
      "Boolean indicating whether the container is running or not",
      NULL},
     {"state",
-     (getter)Container_state, 0,
+     (getter)Container_state, NULL,
      "Container state",
      NULL},
     {NULL, NULL, NULL, NULL, NULL}
 };
 
 static PyMethodDef Container_methods[] = {
-    {"clear_config_item", (PyCFunction)Container_clear_config_item, METH_VARARGS | METH_KEYWORDS,
+    {"clear_config_item", (PyCFunction)Container_clear_config_item,
+     METH_VARARGS|METH_KEYWORDS,
      "clear_config_item(key) -> boolean\n"
      "\n"
      "Clear the current value of a config key."
     },
-    {"create", (PyCFunction)Container_create, METH_VARARGS | METH_KEYWORDS,
+    {"create", (PyCFunction)Container_create,
+     METH_VARARGS|METH_KEYWORDS,
      "create(template, args = (,)) -> boolean\n"
      "\n"
      "Create a new rootfs for the container, using the given template "
      "and passing some optional arguments to it."
     },
-    {"destroy", (PyCFunction)Container_destroy, METH_NOARGS,
+    {"destroy", (PyCFunction)Container_destroy,
+     METH_NOARGS,
      "destroy() -> boolean\n"
      "\n"
      "Destroys the container."
     },
-    {"freeze", (PyCFunction)Container_freeze, METH_NOARGS,
+    {"freeze", (PyCFunction)Container_freeze,
+     METH_NOARGS,
      "freeze() -> boolean\n"
      "\n"
      "Freezes the container and returns its return code."
     },
-    {"get_cgroup_item", (PyCFunction)Container_get_cgroup_item, METH_VARARGS | METH_KEYWORDS,
+    {"get_cgroup_item", (PyCFunction)Container_get_cgroup_item,
+     METH_VARARGS|METH_KEYWORDS,
      "get_cgroup_item(key) -> string\n"
      "\n"
      "Get the current value of a cgroup entry."
     },
-    {"get_config_item", (PyCFunction)Container_get_config_item, METH_VARARGS | METH_KEYWORDS,
+    {"get_config_item", (PyCFunction)Container_get_config_item,
+     METH_VARARGS|METH_KEYWORDS,
      "get_config_item(key) -> string\n"
      "\n"
      "Get the current value of a config key."
     },
-    {"get_config_path", (PyCFunction)Container_get_config_path, METH_NOARGS,
+    {"get_config_path", (PyCFunction)Container_get_config_path,
+     METH_NOARGS,
      "get_config_path() -> string\n"
      "\n"
      "Return the LXC config path (where the containers are stored)."
     },
-    {"get_keys", (PyCFunction)Container_get_keys, METH_VARARGS | METH_KEYWORDS,
+    {"get_keys", (PyCFunction)Container_get_keys,
+     METH_VARARGS|METH_KEYWORDS,
      "get_keys(key) -> string\n"
      "\n"
      "Get a list of valid sub-keys for a key."
     },
-    {"load_config", (PyCFunction)Container_load_config, METH_VARARGS | METH_KEYWORDS,
+    {"load_config", (PyCFunction)Container_load_config,
+     METH_VARARGS|METH_KEYWORDS,
      "load_config(path = DEFAULT) -> boolean\n"
      "\n"
      "Read the container configuration from its default "
      "location or from an alternative location if provided."
     },
-    {"save_config", (PyCFunction)Container_save_config, METH_VARARGS | METH_KEYWORDS,
+    {"save_config", (PyCFunction)Container_save_config,
+     METH_VARARGS|METH_KEYWORDS,
      "save_config(path = DEFAULT) -> boolean\n"
      "\n"
      "Save the container configuration to its default "
      "location or to an alternative location if provided."
     },
-    {"set_cgroup_item", (PyCFunction)Container_set_cgroup_item, METH_VARARGS | METH_KEYWORDS,
+    {"set_cgroup_item", (PyCFunction)Container_set_cgroup_item,
+     METH_VARARGS|METH_KEYWORDS,
      "set_cgroup_item(key, value) -> boolean\n"
      "\n"
      "Set a cgroup entry to the provided value."
     },
-    {"set_config_item", (PyCFunction)Container_set_config_item, METH_VARARGS | METH_KEYWORDS,
+    {"set_config_item", (PyCFunction)Container_set_config_item,
+     METH_VARARGS|METH_KEYWORDS,
      "set_config_item(key, value) -> boolean\n"
      "\n"
      "Set a config key to the provided value."
     },
-    {"set_config_path", (PyCFunction)Container_set_config_path, METH_VARARGS | METH_KEYWORDS,
+    {"set_config_path", (PyCFunction)Container_set_config_path,
+     METH_VARARGS|METH_KEYWORDS,
      "set_config_path(path) -> boolean\n"
      "\n"
      "Set the LXC config path (where the containers are stored)."
     },
-    {"shutdown", (PyCFunction)Container_shutdown, METH_VARARGS | METH_KEYWORDS,
+    {"shutdown", (PyCFunction)Container_shutdown,
+     METH_VARARGS|METH_KEYWORDS,
      "shutdown(timeout = -1) -> boolean\n"
      "\n"
      "Sends SIGPWR to the container and wait for it to shutdown "
      "unless timeout is set to a positive value, in which case "
      "the container will be killed when the timeout is reached."
     },
-    {"start", (PyCFunction)Container_start, METH_VARARGS | METH_KEYWORDS,
+    {"start", (PyCFunction)Container_start,
+     METH_VARARGS|METH_KEYWORDS,
      "start(useinit = False, cmd = (,)) -> boolean\n"
      "\n"
      "Start the container, optionally using lxc-init and "
      "an alternate init command, then returns its return code."
     },
-    {"stop", (PyCFunction)Container_stop, METH_NOARGS,
+    {"stop", (PyCFunction)Container_stop,
+     METH_NOARGS,
      "stop() -> boolean\n"
      "\n"
      "Stop the container and returns its return code."
     },
-    {"unfreeze", (PyCFunction)Container_unfreeze, METH_NOARGS,
+    {"unfreeze", (PyCFunction)Container_unfreeze,
+     METH_NOARGS,
      "unfreeze() -> boolean\n"
      "\n"
      "Unfreezes the container and returns its return code."
     },
-    {"wait", (PyCFunction)Container_wait, METH_VARARGS | METH_KEYWORDS,
+    {"wait", (PyCFunction)Container_wait,
+     METH_VARARGS|METH_KEYWORDS,
      "wait(state, timeout = -1) -> boolean\n"
      "\n"
      "Wait for the container to reach a given state or timeout."
Index: raring-lxc/src/python-lxc/lxc/__init__.py
===================================================================
--- raring-lxc.orig/src/python-lxc/lxc/__init__.py	2013-04-18 22:26:44.219658989 +0200
+++ raring-lxc/src/python-lxc/lxc/__init__.py	2013-04-18 22:26:44.215658989 +0200
@@ -412,7 +412,10 @@
             Set a config key to a provided value.
             The value can be a list for the keys supporting multiple values.
         """
-        old_value = self.get_config_item(key)
+        try:
+            old_value = self.get_config_item(key)
+        except KeyError:
+            old_value = None
 
         # Check if it's a list
         def set_key(key, value):
