This adds a new list_containers function to the python3 binding and a matching override in __init__.py that adds the as_object parameter.
This should be compatible to the previous pure python implementation with the advantage of also listing active non-defined containers (fixing github issue #68). Signed-off-by: Stéphane Graber <stgra...@ubuntu.com> --- src/python-lxc/lxc.c | 71 ++++++++++++++++++++++++++++++++++++++++-- src/python-lxc/lxc/__init__.py | 22 +++++++------ 2 files changed, 80 insertions(+), 13 deletions(-) diff --git a/src/python-lxc/lxc.c b/src/python-lxc/lxc.c index e42ed35..9e6f9d9 100644 --- a/src/python-lxc/lxc.c +++ b/src/python-lxc/lxc.c @@ -170,6 +170,65 @@ LXC_get_version(PyObject *self, PyObject *args) return PyUnicode_FromString(lxc_get_version()); } +static PyObject * +LXC_list_containers(PyObject *self, PyObject *args, PyObject *kwds) +{ + char **names = NULL; + PyObject *list = NULL; + int list_count = 0; + + int list_active = 1; + int list_defined = 1; + + PyObject *py_list_active = NULL; + PyObject *py_list_defined = NULL; + + char* config_path = NULL; + + int i = 0; + PyObject *vargs = NULL; + static char *kwlist[] = {"active", "defined", "config_path", NULL}; + + if (! PyArg_ParseTupleAndKeywords(args, kwds, "|OOs", kwlist, + &py_list_active, + &py_list_defined, + &config_path, &vargs)) + return NULL; + + /* We default to listing everything */ + if (py_list_active && py_list_active != Py_True) { + list_active = 0; + } + + if (py_list_defined && py_list_defined != Py_True) { + list_defined = 0; + } + + /* Call the right API function based on filters */ + if (list_active == 1 && list_defined == 1) + list_count = list_all_containers(config_path, &names, NULL); + else if (list_active == 1) + list_count = list_active_containers(config_path, &names, NULL); + else if (list_defined == 1) + list_count = list_defined_containers(config_path, &names, NULL); + + /* Handle failure */ + if (list_count < 0) { + PyErr_SetString(PyExc_ValueError, "failure to list containers"); + return NULL; + } + + /* Generate the tuple */ + list = PyTuple_New(list_count); + for (i = 0; i < list_count; i++) { + PyTuple_SET_ITEM(list, i, PyUnicode_FromString(names[i])); + free(names[i]); + } + free(names); + + return list; +} + // Container properties static PyObject * Container_config_file_name(Container *self, void *closure) @@ -1219,15 +1278,21 @@ PyVarObject_HEAD_INIT(NULL, 0) static PyMethodDef LXC_methods[] = { {"attach_run_shell", (PyCFunction)LXC_attach_run_shell, METH_O, - "Starts up a shell when attaching, to use as the run parameter for attach or attach_wait"}, + "Starts up a shell when attaching, to use as the run parameter for " + "attach or attach_wait"}, {"attach_run_command", (PyCFunction)LXC_attach_run_command, METH_O, - "Runs a command when attaching, to use as the run parameter for attach or attach_wait"}, + "Runs a command when attaching, to use as the run parameter for attach " + "or attach_wait"}, {"arch_to_personality", (PyCFunction)LXC_arch_to_personality, METH_O, "Returns the process personality of the corresponding architecture"}, - {"get_default_config_path", (PyCFunction)LXC_get_default_config_path, METH_NOARGS, + {"get_default_config_path", (PyCFunction)LXC_get_default_config_path, + METH_NOARGS, "Returns the current LXC config path"}, {"get_version", (PyCFunction)LXC_get_version, METH_NOARGS, "Returns the current LXC library version"}, + {"list_containers", (PyCFunction)LXC_list_containers, + METH_VARARGS|METH_KEYWORDS, + "Returns a list of container names or objects"}, {NULL, NULL, 0, NULL} }; diff --git a/src/python-lxc/lxc/__init__.py b/src/python-lxc/lxc/__init__.py index 8ae7852..e0d4b51 100644 --- a/src/python-lxc/lxc/__init__.py +++ b/src/python-lxc/lxc/__init__.py @@ -417,21 +417,23 @@ class Container(_lxc.Container): return _lxc.Container.wait(self, state, timeout) -def list_containers(as_object=False, config_path=None): +def list_containers(active=True, defined=True, + as_object=False, config_path=None): """ List the containers on the system. """ - if not config_path: - config_path = default_config_path + if config_path: + entries = _lxc.list_containers(active=active, defined=defined, + config_path=config_path) + else: + entries = _lxc.list_containers(active=active, defined=defined) + + if as_object: + return tuple([Container(name, config_path) for name in entries]) + else: + return entries - containers = [] - for entry in glob.glob("%s/*/config" % config_path): - if as_object: - containers.append(Container(entry.split("/")[-2], config_path)) - else: - containers.append(entry.split("/")[-2]) - return containers def attach_run_command(cmd): """ -- 1.8.4.4 ------------------------------------------------------------------------------ Rapidly troubleshoot problems before they affect your business. Most IT organizations don't have a clear picture of how application performance affects their revenue. With AppDynamics, you get 100% visibility into your Java,.NET, & PHP application. Start your 15-day FREE TRIAL of AppDynamics Pro! http://pubads.g.doubleclick.net/gampad/clk?id=84349351&iu=/4140/ostg.clktrk _______________________________________________ Lxc-devel mailing list Lxc-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/lxc-devel