libvirt-python-1.2.2/0000775000076400007640000000000012304641434016147 5ustar veillardveillard00000000000000libvirt-python-1.2.2/sanitytest.py0000664000076400007640000002232512263141061020727 0ustar veillardveillard00000000000000#!/usr/bin/python import sys import lxml import lxml.etree import string # Munge import path to insert build location for libvirt mod sys.path.insert(0, sys.argv[1]) import libvirt # Path to the libvirt API XML file xml = sys.argv[2] f = open(xml, "r") tree = lxml.etree.parse(f) verbose = False wantenums = [] wantfunctions = [] # Phase 1: Identify all functions and enums in public API set = tree.xpath('/api/files/file/exports[@type="function"]/@symbol') for n in set: wantfunctions.append(n) set = tree.xpath('/api/files/file/exports[@type="enum"]/@symbol') for n in set: wantenums.append(n) # Phase 2: Identify all classes and methods in the 'libvirt' python module gotenums = [] gottypes = [] gotfunctions = { "libvirt": [] } for name in dir(libvirt): if name[0] == '_': continue thing = getattr(libvirt, name) # Special-case libvirtError to deal with python 2.4 difference # in Exception class type reporting. if type(thing) == int: gotenums.append(name) elif type(thing) == type or name == "libvirtError": gottypes.append(name) gotfunctions[name] = [] elif callable(thing): gotfunctions["libvirt"].append(name) else: pass for klassname in gottypes: klassobj = getattr(libvirt, klassname) for name in dir(klassobj): if name[0] == '_': continue thing = getattr(klassobj, name) if callable(thing): gotfunctions[klassname].append(name) else: pass # Phase 3: First cut at mapping of C APIs to python classes + methods basicklassmap = {} for cname in wantfunctions: name = cname # Some virConnect APIs have stupid names if name[0:7] == "virNode" and name[0:13] != "virNodeDevice": name = "virConnect" + name[7:] if name[0:7] == "virConn" and name[0:10] != "virConnect": name = "virConnect" + name[7:] # The typed param APIs are only for internal use if name[0:14] == "virTypedParams": continue # These aren't functions, they're callback signatures if name in ["virConnectAuthCallbackPtr", "virConnectCloseFunc", "virStreamSinkFunc", "virStreamSourceFunc", "virStreamEventCallback", "virEventHandleCallback", "virEventTimeoutCallback", "virFreeCallback"]: continue if name[0:21] == "virConnectDomainEvent" and name[-8:] == "Callback": continue if name[0:22] == "virConnectNetworkEvent" and name[-8:] == "Callback": continue # virEvent APIs go into main 'libvirt' namespace not any class if name[0:8] == "virEvent": if name[-4:] == "Func": continue basicklassmap[name] = ["libvirt", name, cname] else: found = False # To start with map APIs to classes based on the # naming prefix. Mistakes will be fixed in next # loop for klassname in gottypes: klen = len(klassname) if name[0:klen] == klassname: found = True if name not in basicklassmap: basicklassmap[name] = [klassname, name[klen:], cname] elif len(basicklassmap[name]) < klen: basicklassmap[name] = [klassname, name[klen:], cname] # Anything which can't map to a class goes into the # global namespaces if not found: basicklassmap[name] = ["libvirt", name[3:], cname] # Phase 4: Deal with oh so many special cases in C -> python mapping finalklassmap = {} for name in sorted(basicklassmap): klass = basicklassmap[name][0] func = basicklassmap[name][1] cname = basicklassmap[name][2] # The object lifecycle APIs are irrelevant since they're # used inside the object constructors/destructors. if func in ["Ref", "Free", "New", "GetConnect", "GetDomain"]: if klass == "virStream" and func == "New": klass = "virConnect" func = "NewStream" else: continue # All the error handling methods need special handling if klass == "libvirt": if func in ["CopyLastError", "DefaultErrorFunc", "ErrorFunc", "FreeError", "SaveLastError", "ResetError"]: continue elif func in ["GetLastError", "GetLastErrorMessage", "ResetLastError", "Initialize"]: func = "vir" + func elif func == "SetErrorFunc": func = "RegisterErrorHandler" elif klass == "virConnect": if func in ["CopyLastError", "SetErrorFunc"]: continue elif func in ["GetLastError", "ResetLastError"]: func = "virConn" + func # Remove 'Get' prefix from most APIs, except those in virConnect # and virDomainSnapshot namespaces which stupidly used a different # convention which we now can't fix without breaking API if func[0:3] == "Get" and klass not in ["virConnect", "virDomainSnapshot", "libvirt"]: if func not in ["GetCPUStats"]: func = func[3:] # The object creation and lookup APIs all have to get re-mapped # into the parent class if func in ["CreateXML", "CreateLinux", "CreateXMLWithFiles", "DefineXML", "CreateXMLFrom", "LookupByUUID", "LookupByUUIDString", "LookupByVolume" "LookupByName", "LookupByID", "LookupByName", "LookupByKey", "LookupByPath", "LookupByMACString", "LookupByUsage", "LookupByVolume", "LookupSCSIHostByWWN", "Restore", "RestoreFlags", "SaveImageDefineXML", "SaveImageGetXMLDesc"]: if klass != "virDomain": func = klass[3:] + func if klass == "virDomainSnapshot": klass = "virDomain" func = func[6:] elif klass == "virStorageVol" and func in ["StorageVolCreateXMLFrom", "StorageVolCreateXML"]: klass = "virStoragePool" func = func[10:] elif func == "StoragePoolLookupByVolume": klass = "virStorageVol" elif func == "StorageVolLookupByName": klass = "virStoragePool" else: klass = "virConnect" # The open methods get remapped to primary namespace if klass == "virConnect" and func in ["Open", "OpenAuth", "OpenReadOnly"]: klass = "libvirt" # These are inexplicably renamed in the python API if func == "ListDomains": func = "ListDomainsID" elif func == "ListAllNodeDevices": func = "ListAllDevices" elif func == "ListNodeDevices": func = "ListDevices" # The virInterfaceChangeXXXX APIs go into virConnect. Stupidly # they have lost their 'interface' prefix in names, but we can't # fix this name if func[0:6] == "Change": klass = "virConnect" # Need to special case the snapshot APIs if klass == "virDomainSnapshot" and func in ["Current", "ListNames", "Num"]: klass = "virDomain" func = "snapshot" + func # Names should start with lowercase letter... func = func[0:1].lower() + func[1:] if func[0:8] == "nWFilter": func = "nwfilter" + func[8:] # ...except when they don't. More stupid naming # decisions we can't fix if func == "iD": func = "ID" if func == "uUID": func = "UUID" if func == "uUIDString": func = "UUIDString" if func == "oSType": func = "OSType" if func == "xMLDesc": func = "XMLDesc" if func == "mACString": func = "MACString" finalklassmap[name] = [klass, func, cname] # Phase 5: Validate sure that every C API is mapped to a python API fail = False usedfunctions = {} for name in sorted(finalklassmap): klass = finalklassmap[name][0] func = finalklassmap[name][1] if func in gotfunctions[klass]: usedfunctions["%s.%s" % (klass, func)] = 1 if verbose: print("PASS %s -> %s.%s" % (name, klass, func)) else: print("FAIL %s -> %s.%s (C API not mapped to python)" % (name, klass, func)) fail = True # Phase 6: Validate that every python API has a corresponding C API for klass in gotfunctions: if klass == "libvirtError": continue for func in sorted(gotfunctions[klass]): # These are pure python methods with no C APi if func in ["connect", "getConnect", "domain", "getDomain"]: continue key = "%s.%s" % (klass, func) if not key in usedfunctions: print("FAIL %s.%s (Python API not mapped to C)" % (klass, func)) fail = True else: if verbose: print("PASS %s.%s" % (klass, func)) # Phase 7: Validate that all the low level C APIs have binding for name in sorted(finalklassmap): cname = finalklassmap[name][2] pyname = cname if pyname == "virSetErrorFunc": pyname = "virRegisterErrorHandler" elif pyname == "virConnectListDomains": pyname = "virConnectListDomainsID" # These exist in C and exist in python, but we've got # a pure-python impl so don't check them if name in ["virStreamRecvAll", "virStreamSendAll"]: continue try: thing = getattr(libvirt.libvirtmod, pyname) except AttributeError: print("FAIL libvirt.libvirtmod.%s (C binding does not exist)" % pyname) fail = True if fail: sys.exit(1) else: sys.exit(0) libvirt-python-1.2.2/libvirt-qemu-override-api.xml0000664000076400007640000000215512245535607023710 0ustar veillardveillard00000000000000 Send an arbitrary monitor command through qemu monitor of domain Send a Guest Agent command to domain libvirt-python-1.2.2/libvirt-override.c0000664000076400007640000067711212263141061021614 0ustar veillardveillard00000000000000/* * libvir.c: this modules implements the main part of the glue of the * libvir library and the Python interpreter. It provides the * entry points where an automatically generated stub is * unpractical * * Copyright (C) 2005, 2007-2013 Red Hat, Inc. * * Daniel Veillard */ /* Horrible kludge to work around even more horrible name-space pollution via Python.h. That file includes /usr/include/python2.5/pyconfig*.h, which has over 180 autoconf-style HAVE_* definitions. Shame on them. */ #undef HAVE_PTHREAD_H /* We want to see *_LAST enums. */ #define VIR_ENUM_SENTINELS #include #include #include #include #include "typewrappers.h" #include "build/libvirt.h" #include "libvirt-utils.h" #if PY_MAJOR_VERSION > 2 # ifndef __CYGWIN__ extern PyObject *PyInit_libvirtmod(void); # else extern PyObject *PyInit_cygvirtmod(void); # endif #else # ifndef __CYGWIN__ extern void initlibvirtmod(void); # else extern void initcygvirtmod(void); # endif #endif #if 0 # define DEBUG_ERROR 1 #endif #if DEBUG_ERROR # define DEBUG(fmt, ...) \ printf(fmt, __VA_ARGS__) #else # define DEBUG(fmt, ...) \ do {} while (0) #endif /* The two-statement sequence "Py_INCREF(Py_None); return Py_None;" is so common that we encapsulate it here. Now, each use is simply return VIR_PY_NONE; */ #define VIR_PY_NONE (Py_INCREF (Py_None), Py_None) #define VIR_PY_INT_FAIL (libvirt_intWrap(-1)) #define VIR_PY_INT_SUCCESS (libvirt_intWrap(0)) static char *py_str(PyObject *obj) { PyObject *str = PyObject_Str(obj); char *ret; if (!str) { PyErr_Print(); PyErr_Clear(); return NULL; }; libvirt_charPtrUnwrap(str, &ret); return ret; } /* Helper function to convert a virTypedParameter output array into a * Python dictionary for return to the user. Return NULL on failure, * after raising a python exception. */ static PyObject * getPyVirTypedParameter(const virTypedParameter *params, int nparams) { PyObject *key, *val, *info; size_t i; if ((info = PyDict_New()) == NULL) return NULL; for (i = 0; i < nparams; i++) { switch (params[i].type) { case VIR_TYPED_PARAM_INT: val = libvirt_intWrap(params[i].value.i); break; case VIR_TYPED_PARAM_UINT: val = libvirt_intWrap(params[i].value.ui); break; case VIR_TYPED_PARAM_LLONG: val = libvirt_longlongWrap(params[i].value.l); break; case VIR_TYPED_PARAM_ULLONG: val = libvirt_ulonglongWrap(params[i].value.ul); break; case VIR_TYPED_PARAM_DOUBLE: val = PyFloat_FromDouble(params[i].value.d); break; case VIR_TYPED_PARAM_BOOLEAN: val = PyBool_FromLong(params[i].value.b); break; case VIR_TYPED_PARAM_STRING: val = libvirt_constcharPtrWrap(params[i].value.s); break; default: /* Possible if a newer server has a bug and sent stuff we * don't recognize. */ PyErr_Format(PyExc_LookupError, "Type value \"%d\" not recognized", params[i].type); val = NULL; break; } key = libvirt_constcharPtrWrap(params[i].field); if (!key || !val) goto cleanup; if (PyDict_SetItem(info, key, val) < 0) { Py_DECREF(info); goto cleanup; } Py_DECREF(key); Py_DECREF(val); } return info; cleanup: Py_XDECREF(key); Py_XDECREF(val); return NULL; } /* Allocate a new typed parameter array with the same contents and * length as info, and using the array params of length nparams as * hints on what types to use when creating the new array. The caller * must clear the array before freeing it. Return NULL on failure, * after raising a python exception. */ static virTypedParameterPtr ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) setPyVirTypedParameter(PyObject *info, const virTypedParameter *params, int nparams) { PyObject *key, *value; #if PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION <= 4 int pos = 0; #else Py_ssize_t pos = 0; #endif virTypedParameterPtr temp = NULL, ret = NULL; Py_ssize_t size; size_t i; if ((size = PyDict_Size(info)) < 0) return NULL; /* Libvirt APIs use NULL array and 0 size as a special case; * setting should have at least one parameter. */ if (size == 0) { PyErr_Format(PyExc_LookupError, "Dictionary must not be empty"); return NULL; } if (VIR_ALLOC_N(ret, size) < 0) { PyErr_NoMemory(); return NULL; } temp = &ret[0]; while (PyDict_Next(info, &pos, &key, &value)) { char *keystr = NULL; if (libvirt_charPtrUnwrap(key, &keystr) < 0 || keystr == NULL) goto cleanup; for (i = 0; i < nparams; i++) { if (STREQ(params[i].field, keystr)) break; } if (i == nparams) { PyErr_Format(PyExc_LookupError, "Attribute name \"%s\" could not be recognized", keystr); VIR_FREE(keystr); goto cleanup; } strncpy(temp->field, keystr, sizeof(*temp->field) - 1); temp->field[sizeof(*temp->field) - 1] = '\0'; temp->type = params[i].type; VIR_FREE(keystr); switch (params[i].type) { case VIR_TYPED_PARAM_INT: if (libvirt_intUnwrap(value, &temp->value.i) < 0) goto cleanup; break; case VIR_TYPED_PARAM_UINT: if (libvirt_uintUnwrap(value, &temp->value.ui) < 0) goto cleanup; break; case VIR_TYPED_PARAM_LLONG: if (libvirt_longlongUnwrap(value, &temp->value.l) < 0) goto cleanup; break; case VIR_TYPED_PARAM_ULLONG: if (libvirt_ulonglongUnwrap(value, &temp->value.ul) < 0) goto cleanup; break; case VIR_TYPED_PARAM_DOUBLE: if (libvirt_doubleUnwrap(value, &temp->value.d) < 0) goto cleanup; break; case VIR_TYPED_PARAM_BOOLEAN: { bool b; if (libvirt_boolUnwrap(value, &b) < 0) goto cleanup; temp->value.b = b; break; } case VIR_TYPED_PARAM_STRING: { char *string_val; if (libvirt_charPtrUnwrap(value, &string_val) < 0 || !string_val) goto cleanup; temp->value.s = string_val; break; } default: /* Possible if a newer server has a bug and sent stuff we * don't recognize. */ PyErr_Format(PyExc_LookupError, "Type value \"%d\" not recognized", params[i].type); goto cleanup; } temp++; } return ret; cleanup: VIR_FREE(ret); return NULL; } /* While these appeared in libvirt in 1.0.2, we only * need them in the python from 1.1.0 onwards */ #if LIBVIR_CHECK_VERSION(1, 1, 0) typedef struct { const char *name; int type; } virPyTypedParamsHint; typedef virPyTypedParamsHint *virPyTypedParamsHintPtr; /* Automatically convert dict into type parameters based on types reported * by python. All integer types are converted into LLONG (in case of a negative * value) or ULLONG (in case of a positive value). If you need different * handling, use @hints to explicitly specify what types should be used for * specific parameters. */ static int ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3) virPyDictToTypedParams(PyObject *dict, virTypedParameterPtr *ret_params, int *ret_nparams, virPyTypedParamsHintPtr hints, int nhints) { PyObject *key; PyObject *value; #if PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION <= 4 int pos = 0; #else Py_ssize_t pos = 0; #endif virTypedParameterPtr params = NULL; size_t i; int n = 0; int max = 0; int ret = -1; char *keystr = NULL; *ret_params = NULL; *ret_nparams = 0; if (PyDict_Size(dict) < 0) return -1; while (PyDict_Next(dict, &pos, &key, &value)) { int type = -1; if (libvirt_charPtrUnwrap(key, &keystr) < 0 || !keystr) goto cleanup; for (i = 0; i < nhints; i++) { if (STREQ(hints[i].name, keystr)) { type = hints[i].type; break; } } if (type == -1) { #if PY_MAJOR_VERSION > 2 if (PyUnicode_Check(value)) { #else if (PyString_Check(value)) { #endif type = VIR_TYPED_PARAM_STRING; } else if (PyBool_Check(value)) { type = VIR_TYPED_PARAM_BOOLEAN; } else if (PyLong_Check(value)) { unsigned long long ull = PyLong_AsUnsignedLongLong(value); if (ull == (unsigned long long) -1 && PyErr_Occurred()) type = VIR_TYPED_PARAM_LLONG; else type = VIR_TYPED_PARAM_ULLONG; #if PY_MAJOR_VERSION < 3 } else if (PyInt_Check(value)) { if (PyInt_AS_LONG(value) < 0) type = VIR_TYPED_PARAM_LLONG; else type = VIR_TYPED_PARAM_ULLONG; #endif } else if (PyFloat_Check(value)) { type = VIR_TYPED_PARAM_DOUBLE; } } if (type == -1) { PyErr_Format(PyExc_TypeError, "Unknown type of \"%s\" field", keystr); goto cleanup; } switch ((virTypedParameterType) type) { case VIR_TYPED_PARAM_INT: { int val; if (libvirt_intUnwrap(value, &val) < 0 || virTypedParamsAddInt(¶ms, &n, &max, keystr, val) < 0) goto cleanup; break; } case VIR_TYPED_PARAM_UINT: { unsigned int val; if (libvirt_uintUnwrap(value, &val) < 0 || virTypedParamsAddUInt(¶ms, &n, &max, keystr, val) < 0) goto cleanup; break; } case VIR_TYPED_PARAM_LLONG: { long long val; if (libvirt_longlongUnwrap(value, &val) < 0 || virTypedParamsAddLLong(¶ms, &n, &max, keystr, val) < 0) goto cleanup; break; } case VIR_TYPED_PARAM_ULLONG: { unsigned long long val; if (libvirt_ulonglongUnwrap(value, &val) < 0 || virTypedParamsAddULLong(¶ms, &n, &max, keystr, val) < 0) goto cleanup; break; } case VIR_TYPED_PARAM_DOUBLE: { double val; if (libvirt_doubleUnwrap(value, &val) < 0 || virTypedParamsAddDouble(¶ms, &n, &max, keystr, val) < 0) goto cleanup; break; } case VIR_TYPED_PARAM_BOOLEAN: { bool val; if (libvirt_boolUnwrap(value, &val) < 0 || virTypedParamsAddBoolean(¶ms, &n, &max, keystr, val) < 0) goto cleanup; break; } case VIR_TYPED_PARAM_STRING: { char *val;; if (libvirt_charPtrUnwrap(value, &val) < 0 || !val || virTypedParamsAddString(¶ms, &n, &max, keystr, val) < 0) { VIR_FREE(val); goto cleanup; } VIR_FREE(val); break; } case VIR_TYPED_PARAM_LAST: break; /* unreachable */ } VIR_FREE(keystr); } *ret_params = params; *ret_nparams = n; params = NULL; ret = 0; cleanup: VIR_FREE(keystr); virTypedParamsFree(params, n); return ret; } #endif /* LIBVIR_CHECK_VERSION(1, 1, 0) */ /* * Utility function to retrieve the number of node CPUs present. * It first tries virGetNodeCPUMap, which will return the * number reliably, if available. * As a fallback and for compatibility with backlevel libvirt * versions virGetNodeInfo will be called to calculate the * CPU number, which has the potential to return a too small * number if some host CPUs are offline. */ static int getPyNodeCPUCount(virConnectPtr conn) { int i_retval = -1; virNodeInfo nodeinfo; #if LIBVIR_CHECK_VERSION(1, 0, 0) LIBVIRT_BEGIN_ALLOW_THREADS; i_retval = virNodeGetCPUMap(conn, NULL, NULL, 0); LIBVIRT_END_ALLOW_THREADS; #endif /* LIBVIR_CHECK_VERSION(1, 0, 0) */ if (i_retval < 0) { /* fallback: use nodeinfo */ LIBVIRT_BEGIN_ALLOW_THREADS; i_retval = virNodeGetInfo(conn, &nodeinfo); LIBVIRT_END_ALLOW_THREADS; if (i_retval < 0) goto cleanup; i_retval = VIR_NODEINFO_MAXCPUS(nodeinfo); } cleanup: return i_retval; } /************************************************************************ * * * Statistics * * * ************************************************************************/ static PyObject * libvirt_virDomainBlockStats(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { virDomainPtr domain; PyObject *pyobj_domain; char * path; int c_retval; virDomainBlockStatsStruct stats; PyObject *info; if (!PyArg_ParseTuple(args, (char *)"Oz:virDomainBlockStats", &pyobj_domain, &path)) return NULL; domain = (virDomainPtr) PyvirDomain_Get(pyobj_domain); LIBVIRT_BEGIN_ALLOW_THREADS; c_retval = virDomainBlockStats(domain, path, &stats, sizeof(stats)); LIBVIRT_END_ALLOW_THREADS; if (c_retval < 0) return VIR_PY_NONE; /* convert to a Python tuple of long objects */ if ((info = PyTuple_New(5)) == NULL) return VIR_PY_NONE; PyTuple_SetItem(info, 0, libvirt_longlongWrap(stats.rd_req)); PyTuple_SetItem(info, 1, libvirt_longlongWrap(stats.rd_bytes)); PyTuple_SetItem(info, 2, libvirt_longlongWrap(stats.wr_req)); PyTuple_SetItem(info, 3, libvirt_longlongWrap(stats.wr_bytes)); PyTuple_SetItem(info, 4, libvirt_longlongWrap(stats.errs)); return info; } static PyObject * libvirt_virDomainBlockStatsFlags(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { virDomainPtr domain; PyObject *pyobj_domain; PyObject *ret = NULL; int i_retval; int nparams = 0; unsigned int flags; virTypedParameterPtr params; const char *path; if (!PyArg_ParseTuple(args, (char *)"Ozi:virDomainBlockStatsFlags", &pyobj_domain, &path, &flags)) return NULL; domain = (virDomainPtr) PyvirDomain_Get(pyobj_domain); LIBVIRT_BEGIN_ALLOW_THREADS; i_retval = virDomainBlockStatsFlags(domain, path, NULL, &nparams, flags); LIBVIRT_END_ALLOW_THREADS; if (i_retval < 0) return VIR_PY_NONE; if (!nparams) return PyDict_New(); if (VIR_ALLOC_N(params, nparams) < 0) return PyErr_NoMemory(); LIBVIRT_BEGIN_ALLOW_THREADS; i_retval = virDomainBlockStatsFlags(domain, path, params, &nparams, flags); LIBVIRT_END_ALLOW_THREADS; if (i_retval < 0) { ret = VIR_PY_NONE; goto cleanup; } ret = getPyVirTypedParameter(params, nparams); cleanup: virTypedParamsFree(params, nparams); return ret; } static PyObject * libvirt_virDomainGetCPUStats(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { virDomainPtr domain; PyObject *pyobj_domain, *totalbool; PyObject *cpu, *total; PyObject *ret = NULL; PyObject *error = NULL; int ncpus = -1, start_cpu = 0; int sumparams = 0, nparams = -1; size_t i; int i_retval; unsigned int flags; bool totalflag; virTypedParameterPtr params = NULL, cpuparams; if (!PyArg_ParseTuple(args, (char *)"OOi:virDomainGetCPUStats", &pyobj_domain, &totalbool, &flags)) return NULL; domain = (virDomainPtr) PyvirDomain_Get(pyobj_domain); if (libvirt_boolUnwrap(totalbool, &totalflag) < 0) return NULL; if ((ret = PyList_New(0)) == NULL) return NULL; if (!totalflag) { LIBVIRT_BEGIN_ALLOW_THREADS; ncpus = virDomainGetCPUStats(domain, NULL, 0, 0, 0, flags); LIBVIRT_END_ALLOW_THREADS; if (ncpus < 0) { error = VIR_PY_NONE; goto error; } LIBVIRT_BEGIN_ALLOW_THREADS; nparams = virDomainGetCPUStats(domain, NULL, 0, 0, 1, flags); LIBVIRT_END_ALLOW_THREADS; if (nparams < 0) { error = VIR_PY_NONE; goto error; } sumparams = nparams * MIN(ncpus, 128); if (VIR_ALLOC_N(params, sumparams) < 0) { error = PyErr_NoMemory(); goto error; } while (ncpus) { int queried_ncpus = MIN(ncpus, 128); if (nparams) { LIBVIRT_BEGIN_ALLOW_THREADS; i_retval = virDomainGetCPUStats(domain, params, nparams, start_cpu, queried_ncpus, flags); LIBVIRT_END_ALLOW_THREADS; if (i_retval < 0) { error = VIR_PY_NONE; goto error; } } else { i_retval = 0; } for (i = 0; i < queried_ncpus; i++) { cpuparams = ¶ms[i * nparams]; if ((cpu = getPyVirTypedParameter(cpuparams, i_retval)) == NULL) { goto error; } if (PyList_Append(ret, cpu) < 0) { Py_DECREF(cpu); goto error; } Py_DECREF(cpu); } start_cpu += queried_ncpus; ncpus -= queried_ncpus; virTypedParamsClear(params, sumparams); } } else { LIBVIRT_BEGIN_ALLOW_THREADS; nparams = virDomainGetCPUStats(domain, NULL, 0, -1, 1, flags); LIBVIRT_END_ALLOW_THREADS; if (nparams < 0) { error = VIR_PY_NONE; goto error; } if (nparams) { sumparams = nparams; if (VIR_ALLOC_N(params, nparams) < 0) { error = PyErr_NoMemory(); goto error; } LIBVIRT_BEGIN_ALLOW_THREADS; i_retval = virDomainGetCPUStats(domain, params, nparams, -1, 1, flags); LIBVIRT_END_ALLOW_THREADS; if (i_retval < 0) { error = VIR_PY_NONE; goto error; } } else { i_retval = 0; } if ((total = getPyVirTypedParameter(params, i_retval)) == NULL) { goto error; } if (PyList_Append(ret, total) < 0) { Py_DECREF(total); goto error; } Py_DECREF(total); } virTypedParamsFree(params, sumparams); return ret; error: virTypedParamsFree(params, sumparams); Py_DECREF(ret); return error; } static PyObject * libvirt_virDomainInterfaceStats(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { virDomainPtr domain; PyObject *pyobj_domain; char * path; int c_retval; virDomainInterfaceStatsStruct stats; PyObject *info; if (!PyArg_ParseTuple(args, (char *)"Oz:virDomainInterfaceStats", &pyobj_domain, &path)) return NULL; domain = (virDomainPtr) PyvirDomain_Get(pyobj_domain); LIBVIRT_BEGIN_ALLOW_THREADS; c_retval = virDomainInterfaceStats(domain, path, &stats, sizeof(stats)); LIBVIRT_END_ALLOW_THREADS; if (c_retval < 0) return VIR_PY_NONE; /* convert to a Python tuple of long objects */ if ((info = PyTuple_New(8)) == NULL) return VIR_PY_NONE; PyTuple_SetItem(info, 0, libvirt_longlongWrap(stats.rx_bytes)); PyTuple_SetItem(info, 1, libvirt_longlongWrap(stats.rx_packets)); PyTuple_SetItem(info, 2, libvirt_longlongWrap(stats.rx_errs)); PyTuple_SetItem(info, 3, libvirt_longlongWrap(stats.rx_drop)); PyTuple_SetItem(info, 4, libvirt_longlongWrap(stats.tx_bytes)); PyTuple_SetItem(info, 5, libvirt_longlongWrap(stats.tx_packets)); PyTuple_SetItem(info, 6, libvirt_longlongWrap(stats.tx_errs)); PyTuple_SetItem(info, 7, libvirt_longlongWrap(stats.tx_drop)); return info; } static PyObject * libvirt_virDomainMemoryStats(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { virDomainPtr domain; PyObject *pyobj_domain; unsigned int nr_stats; size_t i; virDomainMemoryStatStruct stats[VIR_DOMAIN_MEMORY_STAT_NR]; PyObject *info; if (!PyArg_ParseTuple(args, (char *)"O:virDomainMemoryStats", &pyobj_domain)) return NULL; domain = (virDomainPtr) PyvirDomain_Get(pyobj_domain); nr_stats = virDomainMemoryStats(domain, stats, VIR_DOMAIN_MEMORY_STAT_NR, 0); if (nr_stats == -1) return VIR_PY_NONE; /* convert to a Python dictionary */ if ((info = PyDict_New()) == NULL) return VIR_PY_NONE; for (i = 0; i < nr_stats; i++) { if (stats[i].tag == VIR_DOMAIN_MEMORY_STAT_SWAP_IN) PyDict_SetItem(info, libvirt_constcharPtrWrap("swap_in"), libvirt_ulonglongWrap(stats[i].val)); else if (stats[i].tag == VIR_DOMAIN_MEMORY_STAT_SWAP_OUT) PyDict_SetItem(info, libvirt_constcharPtrWrap("swap_out"), libvirt_ulonglongWrap(stats[i].val)); else if (stats[i].tag == VIR_DOMAIN_MEMORY_STAT_MAJOR_FAULT) PyDict_SetItem(info, libvirt_constcharPtrWrap("major_fault"), libvirt_ulonglongWrap(stats[i].val)); else if (stats[i].tag == VIR_DOMAIN_MEMORY_STAT_MINOR_FAULT) PyDict_SetItem(info, libvirt_constcharPtrWrap("minor_fault"), libvirt_ulonglongWrap(stats[i].val)); else if (stats[i].tag == VIR_DOMAIN_MEMORY_STAT_UNUSED) PyDict_SetItem(info, libvirt_constcharPtrWrap("unused"), libvirt_ulonglongWrap(stats[i].val)); else if (stats[i].tag == VIR_DOMAIN_MEMORY_STAT_AVAILABLE) PyDict_SetItem(info, libvirt_constcharPtrWrap("available"), libvirt_ulonglongWrap(stats[i].val)); else if (stats[i].tag == VIR_DOMAIN_MEMORY_STAT_ACTUAL_BALLOON) PyDict_SetItem(info, libvirt_constcharPtrWrap("actual"), libvirt_ulonglongWrap(stats[i].val)); else if (stats[i].tag == VIR_DOMAIN_MEMORY_STAT_RSS) PyDict_SetItem(info, libvirt_constcharPtrWrap("rss"), libvirt_ulonglongWrap(stats[i].val)); } return info; } static PyObject * libvirt_virDomainGetSchedulerType(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { virDomainPtr domain; PyObject *pyobj_domain, *info; char *c_retval; int nparams; if (!PyArg_ParseTuple(args, (char *)"O:virDomainGetScedulerType", &pyobj_domain)) return NULL; domain = (virDomainPtr) PyvirDomain_Get(pyobj_domain); LIBVIRT_BEGIN_ALLOW_THREADS; c_retval = virDomainGetSchedulerType(domain, &nparams); LIBVIRT_END_ALLOW_THREADS; if (c_retval == NULL) return VIR_PY_NONE; /* convert to a Python tuple of long objects */ if ((info = PyTuple_New(2)) == NULL) { VIR_FREE(c_retval); return VIR_PY_NONE; } PyTuple_SetItem(info, 0, libvirt_constcharPtrWrap(c_retval)); PyTuple_SetItem(info, 1, libvirt_intWrap((long)nparams)); VIR_FREE(c_retval); return info; } static PyObject * libvirt_virDomainGetSchedulerParameters(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { virDomainPtr domain; PyObject *pyobj_domain; PyObject *ret = NULL; char *c_retval; int i_retval; int nparams = 0; virTypedParameterPtr params; if (!PyArg_ParseTuple(args, (char *)"O:virDomainGetScedulerParameters", &pyobj_domain)) return NULL; domain = (virDomainPtr) PyvirDomain_Get(pyobj_domain); LIBVIRT_BEGIN_ALLOW_THREADS; c_retval = virDomainGetSchedulerType(domain, &nparams); LIBVIRT_END_ALLOW_THREADS; if (c_retval == NULL) return VIR_PY_NONE; VIR_FREE(c_retval); if (!nparams) return PyDict_New(); if (VIR_ALLOC_N(params, nparams) < 0) return PyErr_NoMemory(); LIBVIRT_BEGIN_ALLOW_THREADS; i_retval = virDomainGetSchedulerParameters(domain, params, &nparams); LIBVIRT_END_ALLOW_THREADS; if (i_retval < 0) { ret = VIR_PY_NONE; goto cleanup; } ret = getPyVirTypedParameter(params, nparams); cleanup: virTypedParamsFree(params, nparams); return ret; } static PyObject * libvirt_virDomainGetSchedulerParametersFlags(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { virDomainPtr domain; PyObject *pyobj_domain; PyObject *ret = NULL; char *c_retval; int i_retval; int nparams = 0; unsigned int flags; virTypedParameterPtr params; if (!PyArg_ParseTuple(args, (char *)"Oi:virDomainGetScedulerParametersFlags", &pyobj_domain, &flags)) return NULL; domain = (virDomainPtr) PyvirDomain_Get(pyobj_domain); LIBVIRT_BEGIN_ALLOW_THREADS; c_retval = virDomainGetSchedulerType(domain, &nparams); LIBVIRT_END_ALLOW_THREADS; if (c_retval == NULL) return VIR_PY_NONE; VIR_FREE(c_retval); if (!nparams) return PyDict_New(); if (VIR_ALLOC_N(params, nparams) < 0) return PyErr_NoMemory(); LIBVIRT_BEGIN_ALLOW_THREADS; i_retval = virDomainGetSchedulerParametersFlags(domain, params, &nparams, flags); LIBVIRT_END_ALLOW_THREADS; if (i_retval < 0) { ret = VIR_PY_NONE; goto cleanup; } ret = getPyVirTypedParameter(params, nparams); cleanup: virTypedParamsFree(params, nparams); return ret; } static PyObject * libvirt_virDomainSetSchedulerParameters(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { virDomainPtr domain; PyObject *pyobj_domain, *info; PyObject *ret = NULL; char *c_retval; int i_retval; int nparams = 0; Py_ssize_t size = 0; virTypedParameterPtr params, new_params = NULL; if (!PyArg_ParseTuple(args, (char *)"OO:virDomainSetScedulerParameters", &pyobj_domain, &info)) return NULL; domain = (virDomainPtr) PyvirDomain_Get(pyobj_domain); if ((size = PyDict_Size(info)) < 0) return NULL; if (size == 0) { PyErr_Format(PyExc_LookupError, "Need non-empty dictionary to set attributes"); return NULL; } LIBVIRT_BEGIN_ALLOW_THREADS; c_retval = virDomainGetSchedulerType(domain, &nparams); LIBVIRT_END_ALLOW_THREADS; if (c_retval == NULL) return VIR_PY_INT_FAIL; VIR_FREE(c_retval); if (nparams == 0) { PyErr_Format(PyExc_LookupError, "Domain has no settable attributes"); return NULL; } if (VIR_ALLOC_N(params, nparams) < 0) return PyErr_NoMemory(); LIBVIRT_BEGIN_ALLOW_THREADS; i_retval = virDomainGetSchedulerParameters(domain, params, &nparams); LIBVIRT_END_ALLOW_THREADS; if (i_retval < 0) { ret = VIR_PY_INT_FAIL; goto cleanup; } new_params = setPyVirTypedParameter(info, params, nparams); if (!new_params) goto cleanup; LIBVIRT_BEGIN_ALLOW_THREADS; i_retval = virDomainSetSchedulerParameters(domain, new_params, size); LIBVIRT_END_ALLOW_THREADS; if (i_retval < 0) { ret = VIR_PY_INT_FAIL; goto cleanup; } ret = VIR_PY_INT_SUCCESS; cleanup: virTypedParamsFree(params, nparams); virTypedParamsFree(new_params, nparams); return ret; } static PyObject * libvirt_virDomainSetSchedulerParametersFlags(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { virDomainPtr domain; PyObject *pyobj_domain, *info; PyObject *ret = NULL; char *c_retval; int i_retval; int nparams = 0; Py_ssize_t size = 0; unsigned int flags; virTypedParameterPtr params, new_params = NULL; if (!PyArg_ParseTuple(args, (char *)"OOi:virDomainSetScedulerParametersFlags", &pyobj_domain, &info, &flags)) return NULL; domain = (virDomainPtr) PyvirDomain_Get(pyobj_domain); if ((size = PyDict_Size(info)) < 0) return NULL; if (size == 0) { PyErr_Format(PyExc_LookupError, "Need non-empty dictionary to set attributes"); return NULL; } LIBVIRT_BEGIN_ALLOW_THREADS; c_retval = virDomainGetSchedulerType(domain, &nparams); LIBVIRT_END_ALLOW_THREADS; if (c_retval == NULL) return VIR_PY_INT_FAIL; VIR_FREE(c_retval); if (nparams == 0) { PyErr_Format(PyExc_LookupError, "Domain has no settable attributes"); return NULL; } if (VIR_ALLOC_N(params, nparams) < 0) return PyErr_NoMemory(); LIBVIRT_BEGIN_ALLOW_THREADS; i_retval = virDomainGetSchedulerParametersFlags(domain, params, &nparams, flags); LIBVIRT_END_ALLOW_THREADS; if (i_retval < 0) { ret = VIR_PY_INT_FAIL; goto cleanup; } new_params = setPyVirTypedParameter(info, params, nparams); if (!new_params) goto cleanup; LIBVIRT_BEGIN_ALLOW_THREADS; i_retval = virDomainSetSchedulerParametersFlags(domain, new_params, size, flags); LIBVIRT_END_ALLOW_THREADS; if (i_retval < 0) { ret = VIR_PY_INT_FAIL; goto cleanup; } ret = VIR_PY_INT_SUCCESS; cleanup: virTypedParamsFree(params, nparams); virTypedParamsFree(new_params, nparams); return ret; } static PyObject * libvirt_virDomainSetBlkioParameters(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { virDomainPtr domain; PyObject *pyobj_domain, *info; PyObject *ret = NULL; int i_retval; int nparams = 0; Py_ssize_t size = 0; unsigned int flags; virTypedParameterPtr params, new_params = NULL; if (!PyArg_ParseTuple(args, (char *)"OOi:virDomainSetBlkioParameters", &pyobj_domain, &info, &flags)) return NULL; domain = (virDomainPtr) PyvirDomain_Get(pyobj_domain); if ((size = PyDict_Size(info)) < 0) return NULL; if (size == 0) { PyErr_Format(PyExc_LookupError, "Need non-empty dictionary to set attributes"); return NULL; } LIBVIRT_BEGIN_ALLOW_THREADS; i_retval = virDomainGetBlkioParameters(domain, NULL, &nparams, flags); LIBVIRT_END_ALLOW_THREADS; if (i_retval < 0) return VIR_PY_INT_FAIL; if (nparams == 0) { PyErr_Format(PyExc_LookupError, "Domain has no settable attributes"); return NULL; } if (VIR_ALLOC_N(params, nparams) < 0) return PyErr_NoMemory(); LIBVIRT_BEGIN_ALLOW_THREADS; i_retval = virDomainGetBlkioParameters(domain, params, &nparams, flags); LIBVIRT_END_ALLOW_THREADS; if (i_retval < 0) { ret = VIR_PY_INT_FAIL; goto cleanup; } new_params = setPyVirTypedParameter(info, params, nparams); if (!new_params) goto cleanup; LIBVIRT_BEGIN_ALLOW_THREADS; i_retval = virDomainSetBlkioParameters(domain, new_params, size, flags); LIBVIRT_END_ALLOW_THREADS; if (i_retval < 0) { ret = VIR_PY_INT_FAIL; goto cleanup; } ret = VIR_PY_INT_SUCCESS; cleanup: virTypedParamsFree(params, nparams); virTypedParamsFree(new_params, nparams); return ret; } static PyObject * libvirt_virDomainGetBlkioParameters(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { virDomainPtr domain; PyObject *pyobj_domain; PyObject *ret = NULL; int i_retval; int nparams = 0; unsigned int flags; virTypedParameterPtr params; if (!PyArg_ParseTuple(args, (char *)"Oi:virDomainGetBlkioParameters", &pyobj_domain, &flags)) return NULL; domain = (virDomainPtr) PyvirDomain_Get(pyobj_domain); LIBVIRT_BEGIN_ALLOW_THREADS; i_retval = virDomainGetBlkioParameters(domain, NULL, &nparams, flags); LIBVIRT_END_ALLOW_THREADS; if (i_retval < 0) return VIR_PY_NONE; if (!nparams) return PyDict_New(); if (VIR_ALLOC_N(params, nparams) < 0) return PyErr_NoMemory(); LIBVIRT_BEGIN_ALLOW_THREADS; i_retval = virDomainGetBlkioParameters(domain, params, &nparams, flags); LIBVIRT_END_ALLOW_THREADS; if (i_retval < 0) { ret = VIR_PY_NONE; goto cleanup; } ret = getPyVirTypedParameter(params, nparams); cleanup: virTypedParamsFree(params, nparams); return ret; } static PyObject * libvirt_virDomainSetMemoryParameters(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { virDomainPtr domain; PyObject *pyobj_domain, *info; PyObject *ret = NULL; int i_retval; int nparams = 0; Py_ssize_t size = 0; unsigned int flags; virTypedParameterPtr params, new_params = NULL; if (!PyArg_ParseTuple(args, (char *)"OOi:virDomainSetMemoryParameters", &pyobj_domain, &info, &flags)) return NULL; domain = (virDomainPtr) PyvirDomain_Get(pyobj_domain); if ((size = PyDict_Size(info)) < 0) return NULL; if (size == 0) { PyErr_Format(PyExc_LookupError, "Need non-empty dictionary to set attributes"); return NULL; } LIBVIRT_BEGIN_ALLOW_THREADS; i_retval = virDomainGetMemoryParameters(domain, NULL, &nparams, flags); LIBVIRT_END_ALLOW_THREADS; if (i_retval < 0) return VIR_PY_INT_FAIL; if (nparams == 0) { PyErr_Format(PyExc_LookupError, "Domain has no settable attributes"); return NULL; } if (VIR_ALLOC_N(params, nparams) < 0) return PyErr_NoMemory(); LIBVIRT_BEGIN_ALLOW_THREADS; i_retval = virDomainGetMemoryParameters(domain, params, &nparams, flags); LIBVIRT_END_ALLOW_THREADS; if (i_retval < 0) { ret = VIR_PY_INT_FAIL; goto cleanup; } new_params = setPyVirTypedParameter(info, params, nparams); if (!new_params) goto cleanup; LIBVIRT_BEGIN_ALLOW_THREADS; i_retval = virDomainSetMemoryParameters(domain, new_params, size, flags); LIBVIRT_END_ALLOW_THREADS; if (i_retval < 0) { ret = VIR_PY_INT_FAIL; goto cleanup; } ret = VIR_PY_INT_SUCCESS; cleanup: virTypedParamsFree(params, nparams); virTypedParamsFree(new_params, nparams); return ret; } static PyObject * libvirt_virDomainGetMemoryParameters(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { virDomainPtr domain; PyObject *pyobj_domain; PyObject *ret = NULL; int i_retval; int nparams = 0; unsigned int flags; virTypedParameterPtr params; if (!PyArg_ParseTuple(args, (char *)"Oi:virDomainGetMemoryParameters", &pyobj_domain, &flags)) return NULL; domain = (virDomainPtr) PyvirDomain_Get(pyobj_domain); LIBVIRT_BEGIN_ALLOW_THREADS; i_retval = virDomainGetMemoryParameters(domain, NULL, &nparams, flags); LIBVIRT_END_ALLOW_THREADS; if (i_retval < 0) return VIR_PY_NONE; if (!nparams) return PyDict_New(); if (VIR_ALLOC_N(params, nparams) < 0) return PyErr_NoMemory(); LIBVIRT_BEGIN_ALLOW_THREADS; i_retval = virDomainGetMemoryParameters(domain, params, &nparams, flags); LIBVIRT_END_ALLOW_THREADS; if (i_retval < 0) { ret = VIR_PY_NONE; goto cleanup; } ret = getPyVirTypedParameter(params, nparams); cleanup: virTypedParamsFree(params, nparams); return ret; } static PyObject * libvirt_virDomainSetNumaParameters(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { virDomainPtr domain; PyObject *pyobj_domain, *info; PyObject *ret = NULL; int i_retval; int nparams = 0; Py_ssize_t size = 0; unsigned int flags; virTypedParameterPtr params, new_params = NULL; if (!PyArg_ParseTuple(args, (char *)"OOi:virDomainSetNumaParameters", &pyobj_domain, &info, &flags)) return NULL; domain = (virDomainPtr) PyvirDomain_Get(pyobj_domain); if ((size = PyDict_Size(info)) < 0) return NULL; if (size == 0) { PyErr_Format(PyExc_LookupError, "Need non-empty dictionary to set attributes"); return NULL; } LIBVIRT_BEGIN_ALLOW_THREADS; i_retval = virDomainGetNumaParameters(domain, NULL, &nparams, flags); LIBVIRT_END_ALLOW_THREADS; if (i_retval < 0) return VIR_PY_INT_FAIL; if (nparams == 0) { PyErr_Format(PyExc_LookupError, "Domain has no settable attributes"); return NULL; } if (VIR_ALLOC_N(params, nparams) < 0) return PyErr_NoMemory(); LIBVIRT_BEGIN_ALLOW_THREADS; i_retval = virDomainGetNumaParameters(domain, params, &nparams, flags); LIBVIRT_END_ALLOW_THREADS; if (i_retval < 0) { ret = VIR_PY_INT_FAIL; goto cleanup; } new_params = setPyVirTypedParameter(info, params, nparams); if (!new_params) goto cleanup; LIBVIRT_BEGIN_ALLOW_THREADS; i_retval = virDomainSetNumaParameters(domain, new_params, size, flags); LIBVIRT_END_ALLOW_THREADS; if (i_retval < 0) { ret = VIR_PY_INT_FAIL; goto cleanup; } ret = VIR_PY_INT_SUCCESS; cleanup: virTypedParamsFree(params, nparams); virTypedParamsFree(new_params, nparams); return ret; } static PyObject * libvirt_virDomainGetNumaParameters(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { virDomainPtr domain; PyObject *pyobj_domain; PyObject *ret = NULL; int i_retval; int nparams = 0; unsigned int flags; virTypedParameterPtr params; if (!PyArg_ParseTuple(args, (char *)"Oi:virDomainGetNumaParameters", &pyobj_domain, &flags)) return NULL; domain = (virDomainPtr) PyvirDomain_Get(pyobj_domain); LIBVIRT_BEGIN_ALLOW_THREADS; i_retval = virDomainGetNumaParameters(domain, NULL, &nparams, flags); LIBVIRT_END_ALLOW_THREADS; if (i_retval < 0) return VIR_PY_NONE; if (!nparams) return PyDict_New(); if (VIR_ALLOC_N(params, nparams) < 0) return PyErr_NoMemory(); LIBVIRT_BEGIN_ALLOW_THREADS; i_retval = virDomainGetNumaParameters(domain, params, &nparams, flags); LIBVIRT_END_ALLOW_THREADS; if (i_retval < 0) { ret = VIR_PY_NONE; goto cleanup; } ret = getPyVirTypedParameter(params, nparams); cleanup: virTypedParamsFree(params, nparams); return ret; } static PyObject * libvirt_virDomainSetInterfaceParameters(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { virDomainPtr domain; PyObject *pyobj_domain, *info; PyObject *ret = NULL; int i_retval; int nparams = 0; Py_ssize_t size = 0; unsigned int flags; const char *device = NULL; virTypedParameterPtr params, new_params = NULL; if (!PyArg_ParseTuple(args, (char *)"OzOi:virDomainSetInterfaceParameters", &pyobj_domain, &device, &info, &flags)) return NULL; domain = (virDomainPtr) PyvirDomain_Get(pyobj_domain); if ((size = PyDict_Size(info)) < 0) return NULL; if (size == 0) { PyErr_Format(PyExc_LookupError, "Need non-empty dictionary to set attributes"); return NULL; } LIBVIRT_BEGIN_ALLOW_THREADS; i_retval = virDomainGetInterfaceParameters(domain, device, NULL, &nparams, flags); LIBVIRT_END_ALLOW_THREADS; if (i_retval < 0) return VIR_PY_INT_FAIL; if (nparams == 0) { PyErr_Format(PyExc_LookupError, "Domain has no settable attributes"); return NULL; } if (VIR_ALLOC_N(params, nparams) < 0) return PyErr_NoMemory(); LIBVIRT_BEGIN_ALLOW_THREADS; i_retval = virDomainGetInterfaceParameters(domain, device, params, &nparams, flags); LIBVIRT_END_ALLOW_THREADS; if (i_retval < 0) { ret = VIR_PY_INT_FAIL; goto cleanup; } new_params = setPyVirTypedParameter(info, params, nparams); if (!new_params) goto cleanup; LIBVIRT_BEGIN_ALLOW_THREADS; i_retval = virDomainSetInterfaceParameters(domain, device, new_params, size, flags); LIBVIRT_END_ALLOW_THREADS; if (i_retval < 0) { ret = VIR_PY_INT_FAIL; goto cleanup; } ret = VIR_PY_INT_SUCCESS; cleanup: virTypedParamsFree(params, nparams); virTypedParamsFree(new_params, nparams); return ret; } static PyObject * libvirt_virDomainGetInterfaceParameters(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { virDomainPtr domain; PyObject *pyobj_domain; PyObject *ret = NULL; int i_retval; int nparams = 0; unsigned int flags; const char *device = NULL; virTypedParameterPtr params; if (!PyArg_ParseTuple(args, (char *)"Ozi:virDomainGetInterfaceParameters", &pyobj_domain, &device, &flags)) return NULL; domain = (virDomainPtr) PyvirDomain_Get(pyobj_domain); LIBVIRT_BEGIN_ALLOW_THREADS; i_retval = virDomainGetInterfaceParameters(domain, device, NULL, &nparams, flags); LIBVIRT_END_ALLOW_THREADS; if (i_retval < 0) return VIR_PY_NONE; if (!nparams) return PyDict_New(); if (VIR_ALLOC_N(params, nparams) < 0) return PyErr_NoMemory(); LIBVIRT_BEGIN_ALLOW_THREADS; i_retval = virDomainGetInterfaceParameters(domain, device, params, &nparams, flags); LIBVIRT_END_ALLOW_THREADS; if (i_retval < 0) { ret = VIR_PY_NONE; goto cleanup; } ret = getPyVirTypedParameter(params, nparams); cleanup: virTypedParamsFree(params, nparams); return ret; } static PyObject * libvirt_virDomainGetVcpus(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { virDomainPtr domain; PyObject *pyobj_domain, *pyretval = NULL, *pycpuinfo = NULL, *pycpumap = NULL; PyObject *error = NULL; virDomainInfo dominfo; virVcpuInfoPtr cpuinfo = NULL; unsigned char *cpumap = NULL; size_t cpumaplen, i; int i_retval, cpunum; if (!PyArg_ParseTuple(args, (char *)"O:virDomainGetVcpus", &pyobj_domain)) return NULL; domain = (virDomainPtr) PyvirDomain_Get(pyobj_domain); if ((cpunum = getPyNodeCPUCount(virDomainGetConnect(domain))) < 0) return VIR_PY_INT_FAIL; LIBVIRT_BEGIN_ALLOW_THREADS; i_retval = virDomainGetInfo(domain, &dominfo); LIBVIRT_END_ALLOW_THREADS; if (i_retval < 0) return VIR_PY_INT_FAIL; if (VIR_ALLOC_N(cpuinfo, dominfo.nrVirtCpu) < 0) return PyErr_NoMemory(); cpumaplen = VIR_CPU_MAPLEN(cpunum); if (xalloc_oversized(dominfo.nrVirtCpu, cpumaplen) || VIR_ALLOC_N(cpumap, dominfo.nrVirtCpu * cpumaplen) < 0) { error = PyErr_NoMemory(); goto cleanup; } LIBVIRT_BEGIN_ALLOW_THREADS; i_retval = virDomainGetVcpus(domain, cpuinfo, dominfo.nrVirtCpu, cpumap, cpumaplen); LIBVIRT_END_ALLOW_THREADS; if (i_retval < 0) { error = VIR_PY_INT_FAIL; goto cleanup; } /* convert to a Python tuple of long objects */ if ((pyretval = PyTuple_New(2)) == NULL) goto cleanup; if ((pycpuinfo = PyList_New(dominfo.nrVirtCpu)) == NULL) goto cleanup; if ((pycpumap = PyList_New(dominfo.nrVirtCpu)) == NULL) goto cleanup; for (i = 0; i < dominfo.nrVirtCpu; i++) { PyObject *info = PyTuple_New(4); PyObject *item = NULL; if (info == NULL) goto cleanup; if ((item = libvirt_intWrap((long)cpuinfo[i].number)) == NULL || PyTuple_SetItem(info, 0, item) < 0) goto itemError; if ((item = libvirt_intWrap((long)cpuinfo[i].state)) == NULL || PyTuple_SetItem(info, 1, item) < 0) goto itemError; if ((item = libvirt_longlongWrap((long long)cpuinfo[i].cpuTime)) == NULL || PyTuple_SetItem(info, 2, item) < 0) goto itemError; if ((item = libvirt_intWrap((long)cpuinfo[i].cpu)) == NULL || PyTuple_SetItem(info, 3, item) < 0) goto itemError; if (PyList_SetItem(pycpuinfo, i, info) < 0) goto itemError; continue; itemError: Py_DECREF(info); Py_XDECREF(item); goto cleanup; } for (i = 0; i < dominfo.nrVirtCpu; i++) { PyObject *info = PyTuple_New(cpunum); size_t j; if (info == NULL) goto cleanup; for (j = 0; j < cpunum; j++) { PyObject *item = NULL; if ((item = PyBool_FromLong(VIR_CPU_USABLE(cpumap, cpumaplen, i, j))) == NULL || PyTuple_SetItem(info, j, item) < 0) { Py_DECREF(info); Py_XDECREF(item); goto cleanup; } } if (PyList_SetItem(pycpumap, i, info) < 0) { Py_DECREF(info); goto cleanup; } } if (PyTuple_SetItem(pyretval, 0, pycpuinfo) < 0 || PyTuple_SetItem(pyretval, 1, pycpumap) < 0) goto cleanup; VIR_FREE(cpuinfo); VIR_FREE(cpumap); return pyretval; cleanup: VIR_FREE(cpuinfo); VIR_FREE(cpumap); Py_XDECREF(pyretval); Py_XDECREF(pycpuinfo); Py_XDECREF(pycpumap); return error; } static PyObject * libvirt_virDomainPinVcpu(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { virDomainPtr domain; PyObject *pyobj_domain, *pycpumap; PyObject *ret = NULL; unsigned char *cpumap; int cpumaplen, vcpu, tuple_size, cpunum; size_t i; int i_retval; if (!PyArg_ParseTuple(args, (char *)"OiO:virDomainPinVcpu", &pyobj_domain, &vcpu, &pycpumap)) return NULL; domain = (virDomainPtr) PyvirDomain_Get(pyobj_domain); if ((cpunum = getPyNodeCPUCount(virDomainGetConnect(domain))) < 0) return VIR_PY_INT_FAIL; if (PyTuple_Check(pycpumap)) { tuple_size = PyTuple_Size(pycpumap); if (tuple_size == -1) return ret; } else { PyErr_SetString(PyExc_TypeError, "Unexpected type, tuple is required"); return ret; } cpumaplen = VIR_CPU_MAPLEN(cpunum); if (VIR_ALLOC_N(cpumap, cpumaplen) < 0) return PyErr_NoMemory(); for (i = 0; i < tuple_size; i++) { PyObject *flag = PyTuple_GetItem(pycpumap, i); bool b; if (!flag || libvirt_boolUnwrap(flag, &b) < 0) goto cleanup; if (b) VIR_USE_CPU(cpumap, i); else VIR_UNUSE_CPU(cpumap, i); } for (; i < cpunum; i++) VIR_UNUSE_CPU(cpumap, i); LIBVIRT_BEGIN_ALLOW_THREADS; i_retval = virDomainPinVcpu(domain, vcpu, cpumap, cpumaplen); LIBVIRT_END_ALLOW_THREADS; if (i_retval < 0) { ret = VIR_PY_INT_FAIL; goto cleanup; } ret = VIR_PY_INT_SUCCESS; cleanup: VIR_FREE(cpumap); return ret; } static PyObject * libvirt_virDomainPinVcpuFlags(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { virDomainPtr domain; PyObject *pyobj_domain, *pycpumap; PyObject *ret = NULL; unsigned char *cpumap; int cpumaplen, vcpu, tuple_size, cpunum; size_t i; unsigned int flags; int i_retval; if (!PyArg_ParseTuple(args, (char *)"OiOi:virDomainPinVcpuFlags", &pyobj_domain, &vcpu, &pycpumap, &flags)) return NULL; domain = (virDomainPtr) PyvirDomain_Get(pyobj_domain); if ((cpunum = getPyNodeCPUCount(virDomainGetConnect(domain))) < 0) return VIR_PY_INT_FAIL; if (PyTuple_Check(pycpumap)) { tuple_size = PyTuple_Size(pycpumap); if (tuple_size == -1) return ret; } else { PyErr_SetString(PyExc_TypeError, "Unexpected type, tuple is required"); return ret; } cpumaplen = VIR_CPU_MAPLEN(cpunum); if (VIR_ALLOC_N(cpumap, cpumaplen) < 0) return PyErr_NoMemory(); for (i = 0; i < tuple_size; i++) { PyObject *flag = PyTuple_GetItem(pycpumap, i); bool b; if (!flag || libvirt_boolUnwrap(flag, &b) < 0) goto cleanup; if (b) VIR_USE_CPU(cpumap, i); else VIR_UNUSE_CPU(cpumap, i); } for (; i < cpunum; i++) VIR_UNUSE_CPU(cpumap, i); LIBVIRT_BEGIN_ALLOW_THREADS; i_retval = virDomainPinVcpuFlags(domain, vcpu, cpumap, cpumaplen, flags); LIBVIRT_END_ALLOW_THREADS; if (i_retval < 0) { ret = VIR_PY_INT_FAIL; goto cleanup; } ret = VIR_PY_INT_SUCCESS; cleanup: VIR_FREE(cpumap); return ret; } static PyObject * libvirt_virDomainGetVcpuPinInfo(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { virDomainPtr domain; PyObject *pyobj_domain, *pycpumaps = NULL; virDomainInfo dominfo; unsigned char *cpumaps = NULL; size_t cpumaplen, vcpu, pcpu; unsigned int flags; int i_retval, cpunum; if (!PyArg_ParseTuple(args, (char *)"Oi:virDomainGetVcpuPinInfo", &pyobj_domain, &flags)) return NULL; domain = (virDomainPtr) PyvirDomain_Get(pyobj_domain); if ((cpunum = getPyNodeCPUCount(virDomainGetConnect(domain))) < 0) return VIR_PY_INT_FAIL; LIBVIRT_BEGIN_ALLOW_THREADS; i_retval = virDomainGetInfo(domain, &dominfo); LIBVIRT_END_ALLOW_THREADS; if (i_retval < 0) return VIR_PY_NONE; cpumaplen = VIR_CPU_MAPLEN(cpunum); if (xalloc_oversized(dominfo.nrVirtCpu, cpumaplen) || VIR_ALLOC_N(cpumaps, dominfo.nrVirtCpu * cpumaplen) < 0) goto cleanup; LIBVIRT_BEGIN_ALLOW_THREADS; i_retval = virDomainGetVcpuPinInfo(domain, dominfo.nrVirtCpu, cpumaps, cpumaplen, flags); LIBVIRT_END_ALLOW_THREADS; if (i_retval < 0) goto cleanup; if ((pycpumaps = PyList_New(dominfo.nrVirtCpu)) == NULL) goto cleanup; for (vcpu = 0; vcpu < dominfo.nrVirtCpu; vcpu++) { PyObject *mapinfo = PyTuple_New(cpunum); if (mapinfo == NULL) goto cleanup; for (pcpu = 0; pcpu < cpunum; pcpu++) { PyTuple_SetItem(mapinfo, pcpu, PyBool_FromLong(VIR_CPU_USABLE(cpumaps, cpumaplen, vcpu, pcpu))); } PyList_SetItem(pycpumaps, vcpu, mapinfo); } VIR_FREE(cpumaps); return pycpumaps; cleanup: VIR_FREE(cpumaps); Py_XDECREF(pycpumaps); return VIR_PY_NONE; } #if LIBVIR_CHECK_VERSION(0, 10, 0) static PyObject * libvirt_virDomainPinEmulator(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { virDomainPtr domain; PyObject *pyobj_domain, *pycpumap; unsigned char *cpumap = NULL; int cpumaplen, tuple_size, cpunum; size_t i; int i_retval; unsigned int flags; if (!PyArg_ParseTuple(args, (char *)"OOi:virDomainPinVcpu", &pyobj_domain, &pycpumap, &flags)) return NULL; domain = (virDomainPtr) PyvirDomain_Get(pyobj_domain); if ((cpunum = getPyNodeCPUCount(virDomainGetConnect(domain))) < 0) return VIR_PY_INT_FAIL; cpumaplen = VIR_CPU_MAPLEN(cpunum); if (!PyTuple_Check(pycpumap)) { PyErr_SetString(PyExc_TypeError, "Unexpected type, tuple is required"); return NULL; } if ((tuple_size = PyTuple_Size(pycpumap)) == -1) return NULL; if (VIR_ALLOC_N(cpumap, cpumaplen) < 0) return PyErr_NoMemory(); for (i = 0; i < tuple_size; i++) { PyObject *flag = PyTuple_GetItem(pycpumap, i); bool b; if (!flag || libvirt_boolUnwrap(flag, &b) < 0) { VIR_FREE(cpumap); return VIR_PY_INT_FAIL; } if (b) VIR_USE_CPU(cpumap, i); else VIR_UNUSE_CPU(cpumap, i); } for (; i < cpunum; i++) VIR_UNUSE_CPU(cpumap, i); LIBVIRT_BEGIN_ALLOW_THREADS; i_retval = virDomainPinEmulator(domain, cpumap, cpumaplen, flags); LIBVIRT_END_ALLOW_THREADS; VIR_FREE(cpumap); if (i_retval < 0) return VIR_PY_INT_FAIL; return VIR_PY_INT_SUCCESS; } static PyObject * libvirt_virDomainGetEmulatorPinInfo(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { virDomainPtr domain; PyObject *pyobj_domain; PyObject *pycpumap; unsigned char *cpumap; size_t cpumaplen; size_t pcpu; unsigned int flags; int ret; int cpunum; if (!PyArg_ParseTuple(args, (char *)"Oi:virDomainEmulatorPinInfo", &pyobj_domain, &flags)) return NULL; domain = (virDomainPtr) PyvirDomain_Get(pyobj_domain); if ((cpunum = getPyNodeCPUCount(virDomainGetConnect(domain))) < 0) return VIR_PY_NONE; cpumaplen = VIR_CPU_MAPLEN(cpunum); if (VIR_ALLOC_N(cpumap, cpumaplen) < 0) return PyErr_NoMemory(); LIBVIRT_BEGIN_ALLOW_THREADS; ret = virDomainGetEmulatorPinInfo(domain, cpumap, cpumaplen, flags); LIBVIRT_END_ALLOW_THREADS; if (ret < 0) { VIR_FREE(cpumap); return VIR_PY_NONE; } if (!(pycpumap = PyTuple_New(cpunum))) { VIR_FREE(cpumap); return NULL; } for (pcpu = 0; pcpu < cpunum; pcpu++) PyTuple_SET_ITEM(pycpumap, pcpu, PyBool_FromLong(VIR_CPU_USABLE(cpumap, cpumaplen, 0, pcpu))); VIR_FREE(cpumap); return pycpumap; } #endif /* LIBVIR_CHECK_VERSION(0, 10, 0) */ /************************************************************************ * * * Global error handler at the Python level * * * ************************************************************************/ static PyObject *libvirt_virPythonErrorFuncHandler = NULL; static PyObject *libvirt_virPythonErrorFuncCtxt = NULL; static PyObject * libvirt_virGetLastError(PyObject *self ATTRIBUTE_UNUSED, PyObject *args ATTRIBUTE_UNUSED) { virError *err; PyObject *info; if ((err = virGetLastError()) == NULL) return VIR_PY_NONE; if ((info = PyTuple_New(9)) == NULL) return VIR_PY_NONE; PyTuple_SetItem(info, 0, libvirt_intWrap((long) err->code)); PyTuple_SetItem(info, 1, libvirt_intWrap((long) err->domain)); PyTuple_SetItem(info, 2, libvirt_constcharPtrWrap(err->message)); PyTuple_SetItem(info, 3, libvirt_intWrap((long) err->level)); PyTuple_SetItem(info, 4, libvirt_constcharPtrWrap(err->str1)); PyTuple_SetItem(info, 5, libvirt_constcharPtrWrap(err->str2)); PyTuple_SetItem(info, 6, libvirt_constcharPtrWrap(err->str3)); PyTuple_SetItem(info, 7, libvirt_intWrap((long) err->int1)); PyTuple_SetItem(info, 8, libvirt_intWrap((long) err->int2)); return info; } static PyObject * libvirt_virConnGetLastError(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { virError *err; PyObject *info; virConnectPtr conn; PyObject *pyobj_conn; if (!PyArg_ParseTuple(args, (char *)"O:virConGetLastError", &pyobj_conn)) return NULL; conn = (virConnectPtr) PyvirConnect_Get(pyobj_conn); LIBVIRT_BEGIN_ALLOW_THREADS; err = virConnGetLastError(conn); LIBVIRT_END_ALLOW_THREADS; if (err == NULL) return VIR_PY_NONE; if ((info = PyTuple_New(9)) == NULL) return VIR_PY_NONE; PyTuple_SetItem(info, 0, libvirt_intWrap((long) err->code)); PyTuple_SetItem(info, 1, libvirt_intWrap((long) err->domain)); PyTuple_SetItem(info, 2, libvirt_constcharPtrWrap(err->message)); PyTuple_SetItem(info, 3, libvirt_intWrap((long) err->level)); PyTuple_SetItem(info, 4, libvirt_constcharPtrWrap(err->str1)); PyTuple_SetItem(info, 5, libvirt_constcharPtrWrap(err->str2)); PyTuple_SetItem(info, 6, libvirt_constcharPtrWrap(err->str3)); PyTuple_SetItem(info, 7, libvirt_intWrap((long) err->int1)); PyTuple_SetItem(info, 8, libvirt_intWrap((long) err->int2)); return info; } static void libvirt_virErrorFuncHandler(ATTRIBUTE_UNUSED void *ctx, virErrorPtr err) { PyObject *list, *info; PyObject *result; DEBUG("libvirt_virErrorFuncHandler(%p, %s, ...) called\n", ctx, err->message); if ((err == NULL) || (err->code == VIR_ERR_OK)) return; LIBVIRT_ENSURE_THREAD_STATE; if ((libvirt_virPythonErrorFuncHandler == NULL) || (libvirt_virPythonErrorFuncHandler == Py_None)) { virDefaultErrorFunc(err); } else { list = PyTuple_New(2); info = PyTuple_New(9); PyTuple_SetItem(list, 0, libvirt_virPythonErrorFuncCtxt); PyTuple_SetItem(list, 1, info); Py_XINCREF(libvirt_virPythonErrorFuncCtxt); PyTuple_SetItem(info, 0, libvirt_intWrap((long) err->code)); PyTuple_SetItem(info, 1, libvirt_intWrap((long) err->domain)); PyTuple_SetItem(info, 2, libvirt_constcharPtrWrap(err->message)); PyTuple_SetItem(info, 3, libvirt_intWrap((long) err->level)); PyTuple_SetItem(info, 4, libvirt_constcharPtrWrap(err->str1)); PyTuple_SetItem(info, 5, libvirt_constcharPtrWrap(err->str2)); PyTuple_SetItem(info, 6, libvirt_constcharPtrWrap(err->str3)); PyTuple_SetItem(info, 7, libvirt_intWrap((long) err->int1)); PyTuple_SetItem(info, 8, libvirt_intWrap((long) err->int2)); /* TODO pass conn and dom if available */ result = PyEval_CallObject(libvirt_virPythonErrorFuncHandler, list); Py_XDECREF(list); Py_XDECREF(result); } LIBVIRT_RELEASE_THREAD_STATE; } static PyObject * libvirt_virRegisterErrorHandler(ATTRIBUTE_UNUSED PyObject * self, PyObject * args) { PyObject *py_retval; PyObject *pyobj_f; PyObject *pyobj_ctx; if (!PyArg_ParseTuple (args, (char *) "OO:xmlRegisterErrorHandler", &pyobj_f, &pyobj_ctx)) return NULL; DEBUG("libvirt_virRegisterErrorHandler(%p, %p) called\n", pyobj_ctx, pyobj_f); virSetErrorFunc(NULL, libvirt_virErrorFuncHandler); if (libvirt_virPythonErrorFuncHandler != NULL) { Py_XDECREF(libvirt_virPythonErrorFuncHandler); } if (libvirt_virPythonErrorFuncCtxt != NULL) { Py_XDECREF(libvirt_virPythonErrorFuncCtxt); } if ((pyobj_f == Py_None) && (pyobj_ctx == Py_None)) { libvirt_virPythonErrorFuncHandler = NULL; libvirt_virPythonErrorFuncCtxt = NULL; } else { Py_XINCREF(pyobj_ctx); Py_XINCREF(pyobj_f); /* TODO: check f is a function ! */ libvirt_virPythonErrorFuncHandler = pyobj_f; libvirt_virPythonErrorFuncCtxt = pyobj_ctx; } py_retval = libvirt_intWrap(1); return py_retval; } static int virConnectCredCallbackWrapper(virConnectCredentialPtr cred, unsigned int ncred, void *cbdata) { PyObject *list; PyObject *pycred; PyObject *pyauth = (PyObject *)cbdata; PyObject *pycbdata; PyObject *pycb; PyObject *pyret; int ret = -1; size_t i; LIBVIRT_ENSURE_THREAD_STATE; pycb = PyList_GetItem(pyauth, 1); pycbdata = PyList_GetItem(pyauth, 2); list = PyTuple_New(2); pycred = PyTuple_New(ncred); for (i = 0; i < ncred; i++) { PyObject *pycreditem; pycreditem = PyList_New(5); Py_INCREF(Py_None); PyTuple_SetItem(pycred, i, pycreditem); PyList_SetItem(pycreditem, 0, libvirt_intWrap((long) cred[i].type)); PyList_SetItem(pycreditem, 1, libvirt_constcharPtrWrap(cred[i].prompt)); if (cred[i].challenge) { PyList_SetItem(pycreditem, 2, libvirt_constcharPtrWrap(cred[i].challenge)); } else { Py_INCREF(Py_None); PyList_SetItem(pycreditem, 2, Py_None); } if (cred[i].defresult) { PyList_SetItem(pycreditem, 3, libvirt_constcharPtrWrap(cred[i].defresult)); } else { Py_INCREF(Py_None); PyList_SetItem(pycreditem, 3, Py_None); } PyList_SetItem(pycreditem, 4, Py_None); } PyTuple_SetItem(list, 0, pycred); Py_XINCREF(pycbdata); PyTuple_SetItem(list, 1, pycbdata); PyErr_Clear(); pyret = PyEval_CallObject(pycb, list); if (PyErr_Occurred()) { PyErr_Print(); goto cleanup; } ret = PyLong_AsLong(pyret); if (ret == 0) { for (i = 0; i < ncred; i++) { PyObject *pycreditem; PyObject *pyresult; char *result = NULL; pycreditem = PyTuple_GetItem(pycred, i); pyresult = PyList_GetItem(pycreditem, 4); if (pyresult != Py_None) libvirt_charPtrUnwrap(pyresult, &result); if (result != NULL) { cred[i].result = result; cred[i].resultlen = strlen(result); } else { cred[i].result = NULL; cred[i].resultlen = 0; } } } cleanup: Py_XDECREF(list); Py_XDECREF(pyret); LIBVIRT_RELEASE_THREAD_STATE; return ret; } static PyObject * libvirt_virConnectOpenAuth(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { PyObject *py_retval; virConnectPtr c_retval; char * name; unsigned int flags; PyObject *pyauth; PyObject *pycredcb; PyObject *pycredtype; virConnectAuth auth; memset(&auth, 0, sizeof(auth)); if (!PyArg_ParseTuple(args, (char *)"zOi:virConnectOpenAuth", &name, &pyauth, &flags)) return NULL; pycredtype = PyList_GetItem(pyauth, 0); pycredcb = PyList_GetItem(pyauth, 1); auth.ncredtype = PyList_Size(pycredtype); if (auth.ncredtype) { size_t i; if (VIR_ALLOC_N(auth.credtype, auth.ncredtype) < 0) return VIR_PY_NONE; for (i = 0; i < auth.ncredtype; i++) { PyObject *val; val = PyList_GetItem(pycredtype, i); auth.credtype[i] = (int)PyLong_AsLong(val); } } if (pycredcb && pycredcb != Py_None) auth.cb = virConnectCredCallbackWrapper; auth.cbdata = pyauth; LIBVIRT_BEGIN_ALLOW_THREADS; c_retval = virConnectOpenAuth(name, &auth, flags); LIBVIRT_END_ALLOW_THREADS; VIR_FREE(auth.credtype); py_retval = libvirt_virConnectPtrWrap((virConnectPtr) c_retval); return py_retval; } /************************************************************************ * * * Wrappers for functions where generator fails * * * ************************************************************************/ static PyObject * libvirt_virGetVersion(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { char *type = NULL; unsigned long libVer, typeVer = 0; int c_retval; if (!PyArg_ParseTuple(args, (char *) "|s", &type)) return NULL; LIBVIRT_BEGIN_ALLOW_THREADS; if (type == NULL) c_retval = virGetVersion(&libVer, NULL, NULL); else c_retval = virGetVersion(&libVer, type, &typeVer); LIBVIRT_END_ALLOW_THREADS; if (c_retval == -1) return VIR_PY_NONE; if (type == NULL) return libvirt_intWrap(libVer); else return Py_BuildValue((char *) "kk", libVer, typeVer); } static PyObject * libvirt_virConnectGetVersion(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { unsigned long hvVersion; int c_retval; virConnectPtr conn; PyObject *pyobj_conn; if (!PyArg_ParseTuple(args, (char *)"O:virConnectGetVersion", &pyobj_conn)) return NULL; conn = (virConnectPtr) PyvirConnect_Get(pyobj_conn); LIBVIRT_BEGIN_ALLOW_THREADS; c_retval = virConnectGetVersion(conn, &hvVersion); LIBVIRT_END_ALLOW_THREADS; if (c_retval == -1) return VIR_PY_INT_FAIL; return libvirt_intWrap(hvVersion); } #if LIBVIR_CHECK_VERSION(1, 1, 3) static PyObject * libvirt_virConnectGetCPUModelNames(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { int c_retval; virConnectPtr conn; PyObject *rv = NULL, *pyobj_conn; char **models = NULL; size_t i; int flags = 0; const char *arch = NULL; if (!PyArg_ParseTuple(args, (char *)"Osi:virConnectGetCPUModelNames", &pyobj_conn, &arch, &flags)) return NULL; conn = (virConnectPtr) PyvirConnect_Get(pyobj_conn); LIBVIRT_BEGIN_ALLOW_THREADS; c_retval = virConnectGetCPUModelNames(conn, arch, &models, flags); LIBVIRT_END_ALLOW_THREADS; if (c_retval == -1) return VIR_PY_INT_FAIL; if ((rv = PyList_New(c_retval)) == NULL) goto error; for (i = 0; i < c_retval; i++) { PyObject *str; if ((str = libvirt_constcharPtrWrap(models[i])) == NULL) goto error; PyList_SET_ITEM(rv, i, str); } done: if (models) { for (i = 0; i < c_retval; i++) VIR_FREE(models[i]); VIR_FREE(models); } return rv; error: Py_XDECREF(rv); rv = VIR_PY_INT_FAIL; goto done; } #endif /* LIBVIR_CHECK_VERSION(1, 1, 3) */ static PyObject * libvirt_virConnectGetLibVersion(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { unsigned long libVer; int c_retval; virConnectPtr conn; PyObject *pyobj_conn; if (!PyArg_ParseTuple(args, (char *)"O:virConnectGetLibVersion", &pyobj_conn)) return NULL; conn = (virConnectPtr) PyvirConnect_Get(pyobj_conn); LIBVIRT_BEGIN_ALLOW_THREADS; c_retval = virConnectGetLibVersion(conn, &libVer); LIBVIRT_END_ALLOW_THREADS; if (c_retval == -1) return VIR_PY_INT_FAIL; return libvirt_intWrap(libVer); } static PyObject * libvirt_virConnectListDomainsID(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { PyObject *py_retval; int *ids = NULL, c_retval; size_t i; virConnectPtr conn; PyObject *pyobj_conn; if (!PyArg_ParseTuple(args, (char *)"O:virConnectListDomains", &pyobj_conn)) return NULL; conn = (virConnectPtr) PyvirConnect_Get(pyobj_conn); LIBVIRT_BEGIN_ALLOW_THREADS; c_retval = virConnectNumOfDomains(conn); LIBVIRT_END_ALLOW_THREADS; if (c_retval < 0) return VIR_PY_NONE; if (c_retval) { if (VIR_ALLOC_N(ids, c_retval) < 0) return VIR_PY_NONE; LIBVIRT_BEGIN_ALLOW_THREADS; c_retval = virConnectListDomains(conn, ids, c_retval); LIBVIRT_END_ALLOW_THREADS; if (c_retval < 0) { VIR_FREE(ids); return VIR_PY_NONE; } } py_retval = PyList_New(c_retval); if (ids) { for (i = 0; i < c_retval; i++) { PyList_SetItem(py_retval, i, libvirt_intWrap(ids[i])); } VIR_FREE(ids); } return py_retval; } #if LIBVIR_CHECK_VERSION(0, 9, 13) static PyObject * libvirt_virConnectListAllDomains(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { PyObject *pyobj_conn; PyObject *py_retval = NULL; PyObject *tmp = NULL; virConnectPtr conn; virDomainPtr *doms = NULL; int c_retval = 0; size_t i; unsigned int flags; if (!PyArg_ParseTuple(args, (char *)"Oi:virConnectListAllDomains", &pyobj_conn, &flags)) return NULL; conn = (virConnectPtr) PyvirConnect_Get(pyobj_conn); LIBVIRT_BEGIN_ALLOW_THREADS; c_retval = virConnectListAllDomains(conn, &doms, flags); LIBVIRT_END_ALLOW_THREADS; if (c_retval < 0) return VIR_PY_NONE; if (!(py_retval = PyList_New(c_retval))) goto cleanup; for (i = 0; i < c_retval; i++) { if (!(tmp = libvirt_virDomainPtrWrap(doms[i])) || PyList_SetItem(py_retval, i, tmp) < 0) { Py_XDECREF(tmp); Py_DECREF(py_retval); py_retval = NULL; goto cleanup; } /* python steals the pointer */ doms[i] = NULL; } cleanup: for (i = 0; i < c_retval; i++) if (doms[i]) virDomainFree(doms[i]); VIR_FREE(doms); return py_retval; } #endif /* LIBVIR_CHECK_VERSION(0, 9, 13) */ static PyObject * libvirt_virConnectListDefinedDomains(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { PyObject *py_retval; char **names = NULL; int c_retval; size_t i; virConnectPtr conn; PyObject *pyobj_conn; if (!PyArg_ParseTuple(args, (char *)"O:virConnectListDefinedDomains", &pyobj_conn)) return NULL; conn = (virConnectPtr) PyvirConnect_Get(pyobj_conn); LIBVIRT_BEGIN_ALLOW_THREADS; c_retval = virConnectNumOfDefinedDomains(conn); LIBVIRT_END_ALLOW_THREADS; if (c_retval < 0) return VIR_PY_NONE; if (c_retval) { if (VIR_ALLOC_N(names, c_retval) < 0) return VIR_PY_NONE; LIBVIRT_BEGIN_ALLOW_THREADS; c_retval = virConnectListDefinedDomains(conn, names, c_retval); LIBVIRT_END_ALLOW_THREADS; if (c_retval < 0) { VIR_FREE(names); return VIR_PY_NONE; } } py_retval = PyList_New(c_retval); if (names) { for (i = 0; i < c_retval; i++) { PyList_SetItem(py_retval, i, libvirt_constcharPtrWrap(names[i])); VIR_FREE(names[i]); } VIR_FREE(names); } return py_retval; } static PyObject * libvirt_virDomainSnapshotListNames(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { PyObject *py_retval; char **names = NULL; int c_retval; size_t i; virDomainPtr dom; PyObject *pyobj_dom; PyObject *pyobj_snap; unsigned int flags; if (!PyArg_ParseTuple(args, (char *)"Oi:virDomainSnapshotListNames", &pyobj_dom, &flags)) return NULL; dom = (virDomainPtr) PyvirDomain_Get(pyobj_dom); LIBVIRT_BEGIN_ALLOW_THREADS; c_retval = virDomainSnapshotNum(dom, flags); LIBVIRT_END_ALLOW_THREADS; if (c_retval < 0) return VIR_PY_NONE; if (c_retval) { if (VIR_ALLOC_N(names, c_retval) < 0) return PyErr_NoMemory(); LIBVIRT_BEGIN_ALLOW_THREADS; c_retval = virDomainSnapshotListNames(dom, names, c_retval, flags); LIBVIRT_END_ALLOW_THREADS; if (c_retval < 0) { VIR_FREE(names); return VIR_PY_NONE; } } py_retval = PyList_New(c_retval); if (!py_retval) goto cleanup; for (i = 0; i < c_retval; i++) { if ((pyobj_snap = libvirt_constcharPtrWrap(names[i])) == NULL || PyList_SetItem(py_retval, i, pyobj_snap) < 0) { Py_XDECREF(pyobj_snap); Py_DECREF(py_retval); py_retval = NULL; goto cleanup; } VIR_FREE(names[i]); } cleanup: for (i = 0; i < c_retval; i++) VIR_FREE(names[i]); VIR_FREE(names); return py_retval; } #if LIBVIR_CHECK_VERSION(0, 9, 13) static PyObject * libvirt_virDomainListAllSnapshots(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { PyObject *py_retval = NULL; virDomainSnapshotPtr *snaps = NULL; int c_retval; size_t i; virDomainPtr dom; PyObject *pyobj_dom; unsigned int flags; PyObject *pyobj_snap; if (!PyArg_ParseTuple(args, (char *)"Oi:virDomainListAllSnapshots", &pyobj_dom, &flags)) return NULL; dom = (virDomainPtr) PyvirDomain_Get(pyobj_dom); LIBVIRT_BEGIN_ALLOW_THREADS; c_retval = virDomainListAllSnapshots(dom, &snaps, flags); LIBVIRT_END_ALLOW_THREADS; if (c_retval < 0) return VIR_PY_NONE; if (!(py_retval = PyList_New(c_retval))) goto cleanup; for (i = 0; i < c_retval; i++) { if ((pyobj_snap = libvirt_virDomainSnapshotPtrWrap(snaps[i])) == NULL || PyList_SetItem(py_retval, i, pyobj_snap) < 0) { Py_XDECREF(pyobj_snap); Py_DECREF(py_retval); py_retval = NULL; goto cleanup; } snaps[i] = NULL; } cleanup: for (i = 0; i < c_retval; i++) if (snaps[i]) virDomainSnapshotFree(snaps[i]); VIR_FREE(snaps); return py_retval; } #endif /* LIBVIR_CHECK_VERSION(0, 9, 13) */ static PyObject * libvirt_virDomainSnapshotListChildrenNames(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { PyObject *py_retval; char **names = NULL; int c_retval; size_t i; virDomainSnapshotPtr snap; PyObject *pyobj_snap; unsigned int flags; if (!PyArg_ParseTuple(args, (char *)"Oi:virDomainSnapshotListChildrenNames", &pyobj_snap, &flags)) return NULL; snap = (virDomainSnapshotPtr) PyvirDomainSnapshot_Get(pyobj_snap); LIBVIRT_BEGIN_ALLOW_THREADS; c_retval = virDomainSnapshotNumChildren(snap, flags); LIBVIRT_END_ALLOW_THREADS; if (c_retval < 0) return VIR_PY_NONE; if (c_retval) { if (VIR_ALLOC_N(names, c_retval) < 0) return PyErr_NoMemory(); LIBVIRT_BEGIN_ALLOW_THREADS; c_retval = virDomainSnapshotListChildrenNames(snap, names, c_retval, flags); LIBVIRT_END_ALLOW_THREADS; if (c_retval < 0) { VIR_FREE(names); return VIR_PY_NONE; } } py_retval = PyList_New(c_retval); for (i = 0; i < c_retval; i++) { if ((pyobj_snap = libvirt_constcharPtrWrap(names[i])) == NULL || PyList_SetItem(py_retval, i, pyobj_snap) < 0) { Py_XDECREF(pyobj_snap); Py_DECREF(py_retval); py_retval = NULL; goto cleanup; } VIR_FREE(names[i]); } cleanup: for (i = 0; i < c_retval; i++) VIR_FREE(names[i]); VIR_FREE(names); return py_retval; } #if LIBVIR_CHECK_VERSION(0, 9, 13) static PyObject * libvirt_virDomainSnapshotListAllChildren(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { PyObject *py_retval = NULL; virDomainSnapshotPtr *snaps = NULL; int c_retval; size_t i; virDomainSnapshotPtr parent; PyObject *pyobj_parent; unsigned int flags; PyObject *pyobj_snap; if (!PyArg_ParseTuple(args, (char *)"Oi:virDomainSnapshotListAllChildren", &pyobj_parent, &flags)) return NULL; parent = (virDomainSnapshotPtr) PyvirDomainSnapshot_Get(pyobj_parent); LIBVIRT_BEGIN_ALLOW_THREADS; c_retval = virDomainSnapshotListAllChildren(parent, &snaps, flags); LIBVIRT_END_ALLOW_THREADS; if (c_retval < 0) return VIR_PY_NONE; if (!(py_retval = PyList_New(c_retval))) goto cleanup; for (i = 0; i < c_retval; i++) { if ((pyobj_snap = libvirt_virDomainSnapshotPtrWrap(snaps[i])) == NULL || PyList_SetItem(py_retval, i, pyobj_snap) < 0) { Py_XDECREF(pyobj_snap); Py_DECREF(py_retval); py_retval = NULL; goto cleanup; } snaps[i] = NULL; } cleanup: for (i = 0; i < c_retval; i++) if (snaps[i]) virDomainSnapshotFree(snaps[i]); VIR_FREE(snaps); return py_retval; } #endif /* LIBVIR_CHECK_VERSION(0, 9, 13) */ static PyObject * libvirt_virDomainRevertToSnapshot(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { int c_retval; virDomainSnapshotPtr snap; PyObject *pyobj_snap; PyObject *pyobj_dom; unsigned int flags; if (!PyArg_ParseTuple(args, (char *)"OOi:virDomainRevertToSnapshot", &pyobj_dom, &pyobj_snap, &flags)) return NULL; snap = (virDomainSnapshotPtr) PyvirDomainSnapshot_Get(pyobj_snap); LIBVIRT_BEGIN_ALLOW_THREADS; c_retval = virDomainRevertToSnapshot(snap, flags); LIBVIRT_END_ALLOW_THREADS; if (c_retval < 0) return VIR_PY_INT_FAIL; return libvirt_intWrap(c_retval); } static PyObject * libvirt_virDomainGetInfo(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { PyObject *py_retval; int c_retval; virDomainPtr domain; PyObject *pyobj_domain; virDomainInfo info; if (!PyArg_ParseTuple(args, (char *)"O:virDomainGetInfo", &pyobj_domain)) return NULL; domain = (virDomainPtr) PyvirDomain_Get(pyobj_domain); LIBVIRT_BEGIN_ALLOW_THREADS; c_retval = virDomainGetInfo(domain, &info); LIBVIRT_END_ALLOW_THREADS; if (c_retval < 0) return VIR_PY_NONE; py_retval = PyList_New(5); PyList_SetItem(py_retval, 0, libvirt_intWrap((int) info.state)); PyList_SetItem(py_retval, 1, libvirt_ulongWrap(info.maxMem)); PyList_SetItem(py_retval, 2, libvirt_ulongWrap(info.memory)); PyList_SetItem(py_retval, 3, libvirt_intWrap((int) info.nrVirtCpu)); PyList_SetItem(py_retval, 4, libvirt_longlongWrap((unsigned long long) info.cpuTime)); return py_retval; } static PyObject * libvirt_virDomainGetState(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { PyObject *py_retval; int c_retval; virDomainPtr domain; PyObject *pyobj_domain; int state; int reason; unsigned int flags; if (!PyArg_ParseTuple(args, (char *)"Oi:virDomainGetState", &pyobj_domain, &flags)) return NULL; domain = (virDomainPtr) PyvirDomain_Get(pyobj_domain); LIBVIRT_BEGIN_ALLOW_THREADS; c_retval = virDomainGetState(domain, &state, &reason, flags); LIBVIRT_END_ALLOW_THREADS; if (c_retval < 0) return VIR_PY_NONE; py_retval = PyList_New(2); PyList_SetItem(py_retval, 0, libvirt_intWrap(state)); PyList_SetItem(py_retval, 1, libvirt_intWrap(reason)); return py_retval; } static PyObject * libvirt_virDomainGetControlInfo(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { PyObject *py_retval; int c_retval; virDomainPtr domain; PyObject *pyobj_domain; virDomainControlInfo info; unsigned int flags; if (!PyArg_ParseTuple(args, (char *)"Oi:virDomainGetControlInfo", &pyobj_domain, &flags)) return NULL; domain = (virDomainPtr) PyvirDomain_Get(pyobj_domain); LIBVIRT_BEGIN_ALLOW_THREADS; c_retval = virDomainGetControlInfo(domain, &info, flags); LIBVIRT_END_ALLOW_THREADS; if (c_retval < 0) return VIR_PY_NONE; py_retval = PyList_New(3); PyList_SetItem(py_retval, 0, libvirt_intWrap(info.state)); PyList_SetItem(py_retval, 1, libvirt_intWrap(info.details)); PyList_SetItem(py_retval, 2, libvirt_longlongWrap(info.stateTime)); return py_retval; } static PyObject * libvirt_virDomainGetBlockInfo(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { PyObject *py_retval; int c_retval; virDomainPtr domain; PyObject *pyobj_domain; virDomainBlockInfo info; const char *path; unsigned int flags; if (!PyArg_ParseTuple(args, (char *)"Ozi:virDomainGetInfo", &pyobj_domain, &path, &flags)) return NULL; domain = (virDomainPtr) PyvirDomain_Get(pyobj_domain); LIBVIRT_BEGIN_ALLOW_THREADS; c_retval = virDomainGetBlockInfo(domain, path, &info, flags); LIBVIRT_END_ALLOW_THREADS; if (c_retval < 0) return VIR_PY_NONE; py_retval = PyList_New(3); PyList_SetItem(py_retval, 0, libvirt_ulonglongWrap(info.capacity)); PyList_SetItem(py_retval, 1, libvirt_ulonglongWrap(info.allocation)); PyList_SetItem(py_retval, 2, libvirt_ulonglongWrap(info.physical)); return py_retval; } static PyObject * libvirt_virNodeGetInfo(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { PyObject *py_retval; int c_retval; virConnectPtr conn; PyObject *pyobj_conn; virNodeInfo info; if (!PyArg_ParseTuple(args, (char *)"O:virDomainGetInfo", &pyobj_conn)) return NULL; conn = (virConnectPtr) PyvirConnect_Get(pyobj_conn); LIBVIRT_BEGIN_ALLOW_THREADS; c_retval = virNodeGetInfo(conn, &info); LIBVIRT_END_ALLOW_THREADS; if (c_retval < 0) return VIR_PY_NONE; py_retval = PyList_New(8); PyList_SetItem(py_retval, 0, libvirt_constcharPtrWrap(&info.model[0])); PyList_SetItem(py_retval, 1, libvirt_longWrap((long) info.memory >> 10)); PyList_SetItem(py_retval, 2, libvirt_intWrap((int) info.cpus)); PyList_SetItem(py_retval, 3, libvirt_intWrap((int) info.mhz)); PyList_SetItem(py_retval, 4, libvirt_intWrap((int) info.nodes)); PyList_SetItem(py_retval, 5, libvirt_intWrap((int) info.sockets)); PyList_SetItem(py_retval, 6, libvirt_intWrap((int) info.cores)); PyList_SetItem(py_retval, 7, libvirt_intWrap((int) info.threads)); return py_retval; } static PyObject * libvirt_virNodeGetSecurityModel(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { PyObject *py_retval; int c_retval; virConnectPtr conn; PyObject *pyobj_conn; virSecurityModel model; if (!PyArg_ParseTuple(args, (char *)"O:virDomainGetSecurityModel", &pyobj_conn)) return NULL; conn = (virConnectPtr) PyvirConnect_Get(pyobj_conn); LIBVIRT_BEGIN_ALLOW_THREADS; c_retval = virNodeGetSecurityModel(conn, &model); LIBVIRT_END_ALLOW_THREADS; if (c_retval < 0) return VIR_PY_NONE; py_retval = PyList_New(2); PyList_SetItem(py_retval, 0, libvirt_constcharPtrWrap(&model.model[0])); PyList_SetItem(py_retval, 1, libvirt_constcharPtrWrap(&model.doi[0])); return py_retval; } static PyObject * libvirt_virDomainGetSecurityLabel(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { PyObject *py_retval; int c_retval; virDomainPtr dom; PyObject *pyobj_dom; virSecurityLabel label; if (!PyArg_ParseTuple(args, (char *)"O:virDomainGetSecurityLabel", &pyobj_dom)) return NULL; dom = (virDomainPtr) PyvirDomain_Get(pyobj_dom); LIBVIRT_BEGIN_ALLOW_THREADS; c_retval = virDomainGetSecurityLabel(dom, &label); LIBVIRT_END_ALLOW_THREADS; if (c_retval < 0) return VIR_PY_NONE; py_retval = PyList_New(2); PyList_SetItem(py_retval, 0, libvirt_constcharPtrWrap(&label.label[0])); PyList_SetItem(py_retval, 1, libvirt_boolWrap(label.enforcing)); return py_retval; } #if LIBVIR_CHECK_VERSION(0, 10, 0) static PyObject * libvirt_virDomainGetSecurityLabelList(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { PyObject *py_retval; int c_retval; virDomainPtr dom; PyObject *pyobj_dom; virSecurityLabel *labels; size_t i; if (!PyArg_ParseTuple(args, (char *)"O:virDomainGetSecurityLabel", &pyobj_dom)) return NULL; dom = (virDomainPtr) PyvirDomain_Get(pyobj_dom); LIBVIRT_BEGIN_ALLOW_THREADS; c_retval = virDomainGetSecurityLabelList(dom, &labels); LIBVIRT_END_ALLOW_THREADS; if (c_retval < 0) return VIR_PY_NONE; py_retval = PyList_New(0); for (i = 0 ; i < c_retval ; i++) { PyObject *entry = PyList_New(2); PyList_SetItem(entry, 0, libvirt_constcharPtrWrap(&labels[i].label[0])); PyList_SetItem(entry, 1, libvirt_boolWrap(labels[i].enforcing)); PyList_Append(py_retval, entry); } free(labels); return py_retval; } #endif /* LIBVIR_CHECK_VERSION(0, 10, 0) */ static PyObject * libvirt_virDomainGetUUID(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { PyObject *py_retval; unsigned char uuid[VIR_UUID_BUFLEN]; virDomainPtr domain; PyObject *pyobj_domain; int c_retval; if (!PyArg_ParseTuple(args, (char *)"O:virDomainGetUUID", &pyobj_domain)) return NULL; domain = (virDomainPtr) PyvirDomain_Get(pyobj_domain); if (domain == NULL) return VIR_PY_NONE; LIBVIRT_BEGIN_ALLOW_THREADS; c_retval = virDomainGetUUID(domain, &uuid[0]); LIBVIRT_END_ALLOW_THREADS; if (c_retval < 0) return VIR_PY_NONE; py_retval = libvirt_charPtrSizeWrap((char *) &uuid[0], VIR_UUID_BUFLEN); return py_retval; } static PyObject * libvirt_virDomainGetUUIDString(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { PyObject *py_retval; char uuidstr[VIR_UUID_STRING_BUFLEN]; virDomainPtr dom; PyObject *pyobj_dom; int c_retval; if (!PyArg_ParseTuple(args, (char *)"O:virDomainGetUUIDString", &pyobj_dom)) return NULL; dom = (virDomainPtr) PyvirDomain_Get(pyobj_dom); if (dom == NULL) return VIR_PY_NONE; LIBVIRT_BEGIN_ALLOW_THREADS; c_retval = virDomainGetUUIDString(dom, &uuidstr[0]); LIBVIRT_END_ALLOW_THREADS; if (c_retval < 0) return VIR_PY_NONE; py_retval = libvirt_constcharPtrWrap((char *) &uuidstr[0]); return py_retval; } static PyObject * libvirt_virDomainLookupByUUID(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { PyObject *py_retval; virDomainPtr c_retval; virConnectPtr conn; PyObject *pyobj_conn; unsigned char * uuid; int len; if (!PyArg_ParseTuple(args, (char *)"Oz#:virDomainLookupByUUID", &pyobj_conn, &uuid, &len)) return NULL; conn = (virConnectPtr) PyvirConnect_Get(pyobj_conn); if ((uuid == NULL) || (len != VIR_UUID_BUFLEN)) return VIR_PY_NONE; LIBVIRT_BEGIN_ALLOW_THREADS; c_retval = virDomainLookupByUUID(conn, uuid); LIBVIRT_END_ALLOW_THREADS; py_retval = libvirt_virDomainPtrWrap((virDomainPtr) c_retval); return py_retval; } static PyObject * libvirt_virConnectListNetworks(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { PyObject *py_retval; char **names = NULL; int c_retval; size_t i; virConnectPtr conn; PyObject *pyobj_conn; if (!PyArg_ParseTuple(args, (char *)"O:virConnectListNetworks", &pyobj_conn)) return NULL; conn = (virConnectPtr) PyvirConnect_Get(pyobj_conn); LIBVIRT_BEGIN_ALLOW_THREADS; c_retval = virConnectNumOfNetworks(conn); LIBVIRT_END_ALLOW_THREADS; if (c_retval < 0) return VIR_PY_NONE; if (c_retval) { if (VIR_ALLOC_N(names, c_retval) < 0) return VIR_PY_NONE; LIBVIRT_BEGIN_ALLOW_THREADS; c_retval = virConnectListNetworks(conn, names, c_retval); LIBVIRT_END_ALLOW_THREADS; if (c_retval < 0) { VIR_FREE(names); return VIR_PY_NONE; } } py_retval = PyList_New(c_retval); if (names) { for (i = 0; i < c_retval; i++) { PyList_SetItem(py_retval, i, libvirt_constcharPtrWrap(names[i])); VIR_FREE(names[i]); } VIR_FREE(names); } return py_retval; } static PyObject * libvirt_virConnectListDefinedNetworks(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { PyObject *py_retval; char **names = NULL; int c_retval; size_t i; virConnectPtr conn; PyObject *pyobj_conn; if (!PyArg_ParseTuple(args, (char *)"O:virConnectListDefinedNetworks", &pyobj_conn)) return NULL; conn = (virConnectPtr) PyvirConnect_Get(pyobj_conn); LIBVIRT_BEGIN_ALLOW_THREADS; c_retval = virConnectNumOfDefinedNetworks(conn); LIBVIRT_END_ALLOW_THREADS; if (c_retval < 0) return VIR_PY_NONE; if (c_retval) { if (VIR_ALLOC_N(names, c_retval) < 0) return VIR_PY_NONE; LIBVIRT_BEGIN_ALLOW_THREADS; c_retval = virConnectListDefinedNetworks(conn, names, c_retval); LIBVIRT_END_ALLOW_THREADS; if (c_retval < 0) { VIR_FREE(names); return VIR_PY_NONE; } } py_retval = PyList_New(c_retval); if (names) { for (i = 0; i < c_retval; i++) { PyList_SetItem(py_retval, i, libvirt_constcharPtrWrap(names[i])); VIR_FREE(names[i]); } VIR_FREE(names); } return py_retval; } #if LIBVIR_CHECK_VERSION(0, 10, 2) static PyObject * libvirt_virConnectListAllNetworks(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { PyObject *pyobj_conn; PyObject *py_retval = NULL; PyObject *tmp = NULL; virConnectPtr conn; virNetworkPtr *nets = NULL; int c_retval = 0; size_t i; unsigned int flags; if (!PyArg_ParseTuple(args, (char *)"Oi:virConnectListAllNetworks", &pyobj_conn, &flags)) return NULL; conn = (virConnectPtr) PyvirConnect_Get(pyobj_conn); LIBVIRT_BEGIN_ALLOW_THREADS; c_retval = virConnectListAllNetworks(conn, &nets, flags); LIBVIRT_END_ALLOW_THREADS; if (c_retval < 0) return VIR_PY_NONE; if (!(py_retval = PyList_New(c_retval))) goto cleanup; for (i = 0; i < c_retval; i++) { if (!(tmp = libvirt_virNetworkPtrWrap(nets[i])) || PyList_SetItem(py_retval, i, tmp) < 0) { Py_XDECREF(tmp); Py_DECREF(py_retval); py_retval = NULL; goto cleanup; } /* python steals the pointer */ nets[i] = NULL; } cleanup: for (i = 0; i < c_retval; i++) if (nets[i]) virNetworkFree(nets[i]); VIR_FREE(nets); return py_retval; } #endif /* LIBVIR_CHECK_VERSION(0, 10, 2) */ static PyObject * libvirt_virNetworkGetUUID(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { PyObject *py_retval; unsigned char uuid[VIR_UUID_BUFLEN]; virNetworkPtr domain; PyObject *pyobj_domain; int c_retval; if (!PyArg_ParseTuple(args, (char *)"O:virNetworkGetUUID", &pyobj_domain)) return NULL; domain = (virNetworkPtr) PyvirNetwork_Get(pyobj_domain); if (domain == NULL) return VIR_PY_NONE; LIBVIRT_BEGIN_ALLOW_THREADS; c_retval = virNetworkGetUUID(domain, &uuid[0]); LIBVIRT_END_ALLOW_THREADS; if (c_retval < 0) return VIR_PY_NONE; py_retval = libvirt_charPtrSizeWrap((char *) &uuid[0], VIR_UUID_BUFLEN); return py_retval; } static PyObject * libvirt_virNetworkGetUUIDString(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { PyObject *py_retval; char uuidstr[VIR_UUID_STRING_BUFLEN]; virNetworkPtr net; PyObject *pyobj_net; int c_retval; if (!PyArg_ParseTuple(args, (char *)"O:virNetworkGetUUIDString", &pyobj_net)) return NULL; net = (virNetworkPtr) PyvirNetwork_Get(pyobj_net); if (net == NULL) return VIR_PY_NONE; LIBVIRT_BEGIN_ALLOW_THREADS; c_retval = virNetworkGetUUIDString(net, &uuidstr[0]); LIBVIRT_END_ALLOW_THREADS; if (c_retval < 0) return VIR_PY_NONE; py_retval = libvirt_constcharPtrWrap((char *) &uuidstr[0]); return py_retval; } static PyObject * libvirt_virNetworkLookupByUUID(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { PyObject *py_retval; virNetworkPtr c_retval; virConnectPtr conn; PyObject *pyobj_conn; unsigned char * uuid; int len; if (!PyArg_ParseTuple(args, (char *)"Oz#:virNetworkLookupByUUID", &pyobj_conn, &uuid, &len)) return NULL; conn = (virConnectPtr) PyvirConnect_Get(pyobj_conn); if ((uuid == NULL) || (len != VIR_UUID_BUFLEN)) return VIR_PY_NONE; LIBVIRT_BEGIN_ALLOW_THREADS; c_retval = virNetworkLookupByUUID(conn, uuid); LIBVIRT_END_ALLOW_THREADS; py_retval = libvirt_virNetworkPtrWrap((virNetworkPtr) c_retval); return py_retval; } static PyObject * libvirt_virDomainGetAutostart(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { PyObject *py_retval; int c_retval, autostart; virDomainPtr domain; PyObject *pyobj_domain; if (!PyArg_ParseTuple(args, (char *)"O:virDomainGetAutostart", &pyobj_domain)) return NULL; domain = (virDomainPtr) PyvirDomain_Get(pyobj_domain); LIBVIRT_BEGIN_ALLOW_THREADS; c_retval = virDomainGetAutostart(domain, &autostart); LIBVIRT_END_ALLOW_THREADS; if (c_retval < 0) return VIR_PY_INT_FAIL; py_retval = libvirt_intWrap(autostart); return py_retval; } static PyObject * libvirt_virNetworkGetAutostart(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { PyObject *py_retval; int c_retval, autostart; virNetworkPtr network; PyObject *pyobj_network; if (!PyArg_ParseTuple(args, (char *)"O:virNetworkGetAutostart", &pyobj_network)) return NULL; network = (virNetworkPtr) PyvirNetwork_Get(pyobj_network); LIBVIRT_BEGIN_ALLOW_THREADS; c_retval = virNetworkGetAutostart(network, &autostart); LIBVIRT_END_ALLOW_THREADS; if (c_retval < 0) return VIR_PY_INT_FAIL; py_retval = libvirt_intWrap(autostart); return py_retval; } static PyObject * libvirt_virNodeGetCellsFreeMemory(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { PyObject *py_retval; PyObject *pyobj_conn; int startCell, maxCells, c_retval; size_t i; virConnectPtr conn; unsigned long long *freeMems; if (!PyArg_ParseTuple(args, (char *)"Oii:virNodeGetCellsFreeMemory", &pyobj_conn, &startCell, &maxCells)) return NULL; if ((startCell < 0) || (maxCells <= 0) || (startCell + maxCells > 10000)) return VIR_PY_NONE; conn = (virConnectPtr) PyvirConnect_Get(pyobj_conn); if (VIR_ALLOC_N(freeMems, maxCells) < 0) return VIR_PY_NONE; LIBVIRT_BEGIN_ALLOW_THREADS; c_retval = virNodeGetCellsFreeMemory(conn, freeMems, startCell, maxCells); LIBVIRT_END_ALLOW_THREADS; if (c_retval < 0) { VIR_FREE(freeMems); return VIR_PY_NONE; } py_retval = PyList_New(c_retval); for (i = 0; i < c_retval; i++) { PyList_SetItem(py_retval, i, libvirt_longlongWrap((long long) freeMems[i])); } VIR_FREE(freeMems); return py_retval; } static PyObject * libvirt_virNodeGetCPUStats(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { PyObject *ret = NULL; PyObject *key = NULL; PyObject *val = NULL; PyObject *pyobj_conn; virConnectPtr conn; unsigned int flags; int cpuNum, c_retval; size_t i; int nparams = 0; virNodeCPUStatsPtr stats = NULL; if (!PyArg_ParseTuple(args, (char *)"Oii:virNodeGetCPUStats", &pyobj_conn, &cpuNum, &flags)) return ret; conn = (virConnectPtr)(PyvirConnect_Get(pyobj_conn)); LIBVIRT_BEGIN_ALLOW_THREADS; c_retval = virNodeGetCPUStats(conn, cpuNum, NULL, &nparams, flags); LIBVIRT_END_ALLOW_THREADS; if (c_retval < 0) return VIR_PY_NONE; if (nparams) { if (VIR_ALLOC_N(stats, nparams) < 0) return PyErr_NoMemory(); LIBVIRT_BEGIN_ALLOW_THREADS; c_retval = virNodeGetCPUStats(conn, cpuNum, stats, &nparams, flags); LIBVIRT_END_ALLOW_THREADS; if (c_retval < 0) { VIR_FREE(stats); return VIR_PY_NONE; } } if (!(ret = PyDict_New())) goto error; for (i = 0; i < nparams; i++) { key = libvirt_constcharPtrWrap(stats[i].field); val = libvirt_ulonglongWrap(stats[i].value); if (!key || !val || PyDict_SetItem(ret, key, val) < 0) { Py_DECREF(ret); ret = NULL; goto error; } Py_DECREF(key); Py_DECREF(val); } VIR_FREE(stats); return ret; error: VIR_FREE(stats); Py_XDECREF(key); Py_XDECREF(val); return ret; } static PyObject * libvirt_virNodeGetMemoryStats(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { PyObject *ret = NULL; PyObject *key = NULL; PyObject *val = NULL; PyObject *pyobj_conn; virConnectPtr conn; unsigned int flags; int cellNum, c_retval; size_t i; int nparams = 0; virNodeMemoryStatsPtr stats = NULL; if (!PyArg_ParseTuple(args, (char *)"Oii:virNodeGetMemoryStats", &pyobj_conn, &cellNum, &flags)) return ret; conn = (virConnectPtr)(PyvirConnect_Get(pyobj_conn)); LIBVIRT_BEGIN_ALLOW_THREADS; c_retval = virNodeGetMemoryStats(conn, cellNum, NULL, &nparams, flags); LIBVIRT_END_ALLOW_THREADS; if (c_retval < 0) return VIR_PY_NONE; if (nparams) { if (VIR_ALLOC_N(stats, nparams) < 0) return PyErr_NoMemory(); LIBVIRT_BEGIN_ALLOW_THREADS; c_retval = virNodeGetMemoryStats(conn, cellNum, stats, &nparams, flags); LIBVIRT_END_ALLOW_THREADS; if (c_retval < 0) { VIR_FREE(stats); return VIR_PY_NONE; } } if (!(ret = PyDict_New())) goto error; for (i = 0; i < nparams; i++) { key = libvirt_constcharPtrWrap(stats[i].field); val = libvirt_ulonglongWrap(stats[i].value); if (!key || !val || PyDict_SetItem(ret, key, val) < 0) { Py_DECREF(ret); ret = NULL; goto error; } Py_DECREF(key); Py_DECREF(val); } VIR_FREE(stats); return ret; error: VIR_FREE(stats); Py_XDECREF(key); Py_XDECREF(val); return ret; } static PyObject * libvirt_virConnectListStoragePools(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { PyObject *py_retval; char **names = NULL; int c_retval; size_t i; virConnectPtr conn; PyObject *pyobj_conn; if (!PyArg_ParseTuple(args, (char *)"O:virConnectListStoragePools", &pyobj_conn)) return NULL; conn = (virConnectPtr) PyvirConnect_Get(pyobj_conn); LIBVIRT_BEGIN_ALLOW_THREADS; c_retval = virConnectNumOfStoragePools(conn); LIBVIRT_END_ALLOW_THREADS; if (c_retval < 0) return VIR_PY_NONE; if (c_retval) { if (VIR_ALLOC_N(names, c_retval) < 0) return VIR_PY_NONE; LIBVIRT_BEGIN_ALLOW_THREADS; c_retval = virConnectListStoragePools(conn, names, c_retval); LIBVIRT_END_ALLOW_THREADS; if (c_retval < 0) { VIR_FREE(names); return VIR_PY_NONE; } } py_retval = PyList_New(c_retval); if (py_retval == NULL) { if (names) { for (i = 0; i < c_retval; i++) VIR_FREE(names[i]); VIR_FREE(names); } return VIR_PY_NONE; } if (names) { for (i = 0; i < c_retval; i++) { PyList_SetItem(py_retval, i, libvirt_constcharPtrWrap(names[i])); VIR_FREE(names[i]); } VIR_FREE(names); } return py_retval; } static PyObject * libvirt_virConnectListDefinedStoragePools(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { PyObject *py_retval; char **names = NULL; int c_retval; size_t i; virConnectPtr conn; PyObject *pyobj_conn; if (!PyArg_ParseTuple(args, (char *)"O:virConnectListDefinedStoragePools", &pyobj_conn)) return NULL; conn = (virConnectPtr) PyvirConnect_Get(pyobj_conn); LIBVIRT_BEGIN_ALLOW_THREADS; c_retval = virConnectNumOfDefinedStoragePools(conn); LIBVIRT_END_ALLOW_THREADS; if (c_retval < 0) return VIR_PY_NONE; if (c_retval) { if (VIR_ALLOC_N(names, c_retval) < 0) return VIR_PY_NONE; LIBVIRT_BEGIN_ALLOW_THREADS; c_retval = virConnectListDefinedStoragePools(conn, names, c_retval); LIBVIRT_END_ALLOW_THREADS; if (c_retval < 0) { VIR_FREE(names); return VIR_PY_NONE; } } py_retval = PyList_New(c_retval); if (py_retval == NULL) { if (names) { for (i = 0; i < c_retval; i++) VIR_FREE(names[i]); VIR_FREE(names); } return VIR_PY_NONE; } if (names) { for (i = 0; i < c_retval; i++) { PyList_SetItem(py_retval, i, libvirt_constcharPtrWrap(names[i])); VIR_FREE(names[i]); } VIR_FREE(names); } return py_retval; } #if LIBVIR_CHECK_VERSION(0, 10, 2) static PyObject * libvirt_virConnectListAllStoragePools(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { PyObject *pyobj_conn; PyObject *py_retval = NULL; PyObject *tmp = NULL; virConnectPtr conn; virStoragePoolPtr *pools = NULL; int c_retval = 0; size_t i; unsigned int flags; if (!PyArg_ParseTuple(args, (char *)"Oi:virConnectListAllStoragePools", &pyobj_conn, &flags)) return NULL; conn = (virConnectPtr) PyvirConnect_Get(pyobj_conn); LIBVIRT_BEGIN_ALLOW_THREADS; c_retval = virConnectListAllStoragePools(conn, &pools, flags); LIBVIRT_END_ALLOW_THREADS; if (c_retval < 0) return VIR_PY_NONE; if (!(py_retval = PyList_New(c_retval))) goto cleanup; for (i = 0; i < c_retval; i++) { if (!(tmp = libvirt_virStoragePoolPtrWrap(pools[i])) || PyList_SetItem(py_retval, i, tmp) < 0) { Py_XDECREF(tmp); Py_DECREF(py_retval); py_retval = NULL; goto cleanup; } /* python steals the pointer */ pools[i] = NULL; } cleanup: for (i = 0; i < c_retval; i++) if (pools[i]) virStoragePoolFree(pools[i]); VIR_FREE(pools); return py_retval; } #endif /* LIBVIR_CHECK_VERSION(0, 10, 2) */ static PyObject * libvirt_virStoragePoolListVolumes(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { PyObject *py_retval; char **names = NULL; int c_retval; size_t i; virStoragePoolPtr pool; PyObject *pyobj_pool; if (!PyArg_ParseTuple(args, (char *)"O:virStoragePoolListVolumes", &pyobj_pool)) return NULL; pool = (virStoragePoolPtr) PyvirStoragePool_Get(pyobj_pool); LIBVIRT_BEGIN_ALLOW_THREADS; c_retval = virStoragePoolNumOfVolumes(pool); LIBVIRT_END_ALLOW_THREADS; if (c_retval < 0) return VIR_PY_NONE; if (c_retval) { if (VIR_ALLOC_N(names, c_retval) < 0) return VIR_PY_NONE; LIBVIRT_BEGIN_ALLOW_THREADS; c_retval = virStoragePoolListVolumes(pool, names, c_retval); LIBVIRT_END_ALLOW_THREADS; if (c_retval < 0) { VIR_FREE(names); return VIR_PY_NONE; } } py_retval = PyList_New(c_retval); if (py_retval == NULL) { if (names) { for (i = 0; i < c_retval; i++) VIR_FREE(names[i]); VIR_FREE(names); } return VIR_PY_NONE; } if (names) { for (i = 0; i < c_retval; i++) { PyList_SetItem(py_retval, i, libvirt_constcharPtrWrap(names[i])); VIR_FREE(names[i]); } VIR_FREE(names); } return py_retval; } #if LIBVIR_CHECK_VERSION(0, 10, 2) static PyObject * libvirt_virStoragePoolListAllVolumes(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { PyObject *py_retval = NULL; PyObject *tmp = NULL; virStoragePoolPtr pool; virStorageVolPtr *vols = NULL; int c_retval = 0; size_t i; unsigned int flags; PyObject *pyobj_pool; if (!PyArg_ParseTuple(args, (char *)"Oi:virStoragePoolListAllVolumes", &pyobj_pool, &flags)) return NULL; pool = (virStoragePoolPtr) PyvirStoragePool_Get(pyobj_pool); LIBVIRT_BEGIN_ALLOW_THREADS; c_retval = virStoragePoolListAllVolumes(pool, &vols, flags); LIBVIRT_END_ALLOW_THREADS; if (c_retval < 0) return VIR_PY_NONE; if (!(py_retval = PyList_New(c_retval))) goto cleanup; for (i = 0; i < c_retval; i++) { if (!(tmp = libvirt_virStorageVolPtrWrap(vols[i])) || PyList_SetItem(py_retval, i, tmp) < 0) { Py_XDECREF(tmp); Py_DECREF(py_retval); py_retval = NULL; goto cleanup; } /* python steals the pointer */ vols[i] = NULL; } cleanup: for (i = 0; i < c_retval; i++) if (vols[i]) virStorageVolFree(vols[i]); VIR_FREE(vols); return py_retval; } #endif /* LIBVIR_CHECK_VERSION(0, 10, 2) */ static PyObject * libvirt_virStoragePoolGetAutostart(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { PyObject *py_retval; int c_retval, autostart; virStoragePoolPtr pool; PyObject *pyobj_pool; if (!PyArg_ParseTuple(args, (char *)"O:virStoragePoolGetAutostart", &pyobj_pool)) return NULL; pool = (virStoragePoolPtr) PyvirStoragePool_Get(pyobj_pool); LIBVIRT_BEGIN_ALLOW_THREADS; c_retval = virStoragePoolGetAutostart(pool, &autostart); LIBVIRT_END_ALLOW_THREADS; if (c_retval < 0) return VIR_PY_NONE; py_retval = libvirt_intWrap(autostart); return py_retval; } static PyObject * libvirt_virStoragePoolGetInfo(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { PyObject *py_retval; int c_retval; virStoragePoolPtr pool; PyObject *pyobj_pool; virStoragePoolInfo info; if (!PyArg_ParseTuple(args, (char *)"O:virStoragePoolGetInfo", &pyobj_pool)) return NULL; pool = (virStoragePoolPtr) PyvirStoragePool_Get(pyobj_pool); LIBVIRT_BEGIN_ALLOW_THREADS; c_retval = virStoragePoolGetInfo(pool, &info); LIBVIRT_END_ALLOW_THREADS; if (c_retval < 0) return VIR_PY_NONE; if ((py_retval = PyList_New(4)) == NULL) return VIR_PY_NONE; PyList_SetItem(py_retval, 0, libvirt_intWrap((int) info.state)); PyList_SetItem(py_retval, 1, libvirt_longlongWrap((unsigned long long) info.capacity)); PyList_SetItem(py_retval, 2, libvirt_longlongWrap((unsigned long long) info.allocation)); PyList_SetItem(py_retval, 3, libvirt_longlongWrap((unsigned long long) info.available)); return py_retval; } static PyObject * libvirt_virStorageVolGetInfo(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { PyObject *py_retval; int c_retval; virStorageVolPtr pool; PyObject *pyobj_pool; virStorageVolInfo info; if (!PyArg_ParseTuple(args, (char *)"O:virStorageVolGetInfo", &pyobj_pool)) return NULL; pool = (virStorageVolPtr) PyvirStorageVol_Get(pyobj_pool); LIBVIRT_BEGIN_ALLOW_THREADS; c_retval = virStorageVolGetInfo(pool, &info); LIBVIRT_END_ALLOW_THREADS; if (c_retval < 0) return VIR_PY_NONE; if ((py_retval = PyList_New(3)) == NULL) return VIR_PY_NONE; PyList_SetItem(py_retval, 0, libvirt_intWrap((int) info.type)); PyList_SetItem(py_retval, 1, libvirt_longlongWrap((unsigned long long) info.capacity)); PyList_SetItem(py_retval, 2, libvirt_longlongWrap((unsigned long long) info.allocation)); return py_retval; } static PyObject * libvirt_virStoragePoolGetUUID(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { PyObject *py_retval; unsigned char uuid[VIR_UUID_BUFLEN]; virStoragePoolPtr pool; PyObject *pyobj_pool; int c_retval; if (!PyArg_ParseTuple(args, (char *)"O:virStoragePoolGetUUID", &pyobj_pool)) return NULL; pool = (virStoragePoolPtr) PyvirStoragePool_Get(pyobj_pool); if (pool == NULL) return VIR_PY_NONE; LIBVIRT_BEGIN_ALLOW_THREADS; c_retval = virStoragePoolGetUUID(pool, &uuid[0]); LIBVIRT_END_ALLOW_THREADS; if (c_retval < 0) return VIR_PY_NONE; py_retval = libvirt_charPtrSizeWrap((char *) &uuid[0], VIR_UUID_BUFLEN); return py_retval; } static PyObject * libvirt_virStoragePoolGetUUIDString(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { PyObject *py_retval; char uuidstr[VIR_UUID_STRING_BUFLEN]; virStoragePoolPtr pool; PyObject *pyobj_pool; int c_retval; if (!PyArg_ParseTuple(args, (char *)"O:virStoragePoolGetUUIDString", &pyobj_pool)) return NULL; pool = (virStoragePoolPtr) PyvirStoragePool_Get(pyobj_pool); if (pool == NULL) return VIR_PY_NONE; LIBVIRT_BEGIN_ALLOW_THREADS; c_retval = virStoragePoolGetUUIDString(pool, &uuidstr[0]); LIBVIRT_END_ALLOW_THREADS; if (c_retval < 0) return VIR_PY_NONE; py_retval = libvirt_constcharPtrWrap((char *) &uuidstr[0]); return py_retval; } static PyObject * libvirt_virStoragePoolLookupByUUID(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { PyObject *py_retval; virStoragePoolPtr c_retval; virConnectPtr conn; PyObject *pyobj_conn; unsigned char * uuid; int len; if (!PyArg_ParseTuple(args, (char *)"Oz#:virStoragePoolLookupByUUID", &pyobj_conn, &uuid, &len)) return NULL; conn = (virConnectPtr) PyvirConnect_Get(pyobj_conn); if ((uuid == NULL) || (len != VIR_UUID_BUFLEN)) return VIR_PY_NONE; LIBVIRT_BEGIN_ALLOW_THREADS; c_retval = virStoragePoolLookupByUUID(conn, uuid); LIBVIRT_END_ALLOW_THREADS; py_retval = libvirt_virStoragePoolPtrWrap((virStoragePoolPtr) c_retval); return py_retval; } static PyObject * libvirt_virNodeListDevices(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { PyObject *py_retval; char **names = NULL; int c_retval; size_t i; virConnectPtr conn; PyObject *pyobj_conn; char *cap; unsigned int flags; if (!PyArg_ParseTuple(args, (char *)"Ozi:virNodeListDevices", &pyobj_conn, &cap, &flags)) return NULL; conn = (virConnectPtr) PyvirConnect_Get(pyobj_conn); LIBVIRT_BEGIN_ALLOW_THREADS; c_retval = virNodeNumOfDevices(conn, cap, flags); LIBVIRT_END_ALLOW_THREADS; if (c_retval < 0) return VIR_PY_NONE; if (c_retval) { if (VIR_ALLOC_N(names, c_retval) < 0) return VIR_PY_NONE; LIBVIRT_BEGIN_ALLOW_THREADS; c_retval = virNodeListDevices(conn, cap, names, c_retval, flags); LIBVIRT_END_ALLOW_THREADS; if (c_retval < 0) { VIR_FREE(names); return VIR_PY_NONE; } } py_retval = PyList_New(c_retval); if (names) { for (i = 0; i < c_retval; i++) { PyList_SetItem(py_retval, i, libvirt_constcharPtrWrap(names[i])); VIR_FREE(names[i]); } VIR_FREE(names); } return py_retval; } #if LIBVIR_CHECK_VERSION(0, 10, 2) static PyObject * libvirt_virConnectListAllNodeDevices(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { PyObject *pyobj_conn; PyObject *py_retval = NULL; PyObject *tmp = NULL; virConnectPtr conn; virNodeDevicePtr *devices = NULL; int c_retval = 0; size_t i; unsigned int flags; if (!PyArg_ParseTuple(args, (char *)"Oi:virConnectListAllNodeDevices", &pyobj_conn, &flags)) return NULL; conn = (virConnectPtr) PyvirConnect_Get(pyobj_conn); LIBVIRT_BEGIN_ALLOW_THREADS; c_retval = virConnectListAllNodeDevices(conn, &devices, flags); LIBVIRT_END_ALLOW_THREADS; if (c_retval < 0) return VIR_PY_NONE; if (!(py_retval = PyList_New(c_retval))) goto cleanup; for (i = 0; i < c_retval; i++) { if (!(tmp = libvirt_virNodeDevicePtrWrap(devices[i])) || PyList_SetItem(py_retval, i, tmp) < 0) { Py_XDECREF(tmp); Py_DECREF(py_retval); py_retval = NULL; goto cleanup; } /* python steals the pointer */ devices[i] = NULL; } cleanup: for (i = 0; i < c_retval; i++) if (devices[i]) virNodeDeviceFree(devices[i]); VIR_FREE(devices); return py_retval; } #endif /* LIBVIR_CHECK_VERSION(0, 10, 2) */ static PyObject * libvirt_virNodeDeviceListCaps(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { PyObject *py_retval; char **names = NULL; int c_retval; size_t i; virNodeDevicePtr dev; PyObject *pyobj_dev; if (!PyArg_ParseTuple(args, (char *)"O:virNodeDeviceListCaps", &pyobj_dev)) return NULL; dev = (virNodeDevicePtr) PyvirNodeDevice_Get(pyobj_dev); LIBVIRT_BEGIN_ALLOW_THREADS; c_retval = virNodeDeviceNumOfCaps(dev); LIBVIRT_END_ALLOW_THREADS; if (c_retval < 0) return VIR_PY_NONE; if (c_retval) { if (VIR_ALLOC_N(names, c_retval) < 0) return VIR_PY_NONE; LIBVIRT_BEGIN_ALLOW_THREADS; c_retval = virNodeDeviceListCaps(dev, names, c_retval); LIBVIRT_END_ALLOW_THREADS; if (c_retval < 0) { VIR_FREE(names); return VIR_PY_NONE; } } py_retval = PyList_New(c_retval); if (names) { for (i = 0; i < c_retval; i++) { PyList_SetItem(py_retval, i, libvirt_constcharPtrWrap(names[i])); VIR_FREE(names[i]); } VIR_FREE(names); } return py_retval; } static PyObject * libvirt_virSecretGetUUID(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { PyObject *py_retval; unsigned char uuid[VIR_UUID_BUFLEN]; virSecretPtr secret; PyObject *pyobj_secret; int c_retval; if (!PyArg_ParseTuple(args, (char *)"O:virSecretGetUUID", &pyobj_secret)) return NULL; secret = (virSecretPtr) PyvirSecret_Get(pyobj_secret); if (secret == NULL) return VIR_PY_NONE; LIBVIRT_BEGIN_ALLOW_THREADS; c_retval = virSecretGetUUID(secret, &uuid[0]); LIBVIRT_END_ALLOW_THREADS; if (c_retval < 0) return VIR_PY_NONE; py_retval = libvirt_charPtrSizeWrap((char *) &uuid[0], VIR_UUID_BUFLEN); return py_retval; } static PyObject * libvirt_virSecretGetUUIDString(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { PyObject *py_retval; char uuidstr[VIR_UUID_STRING_BUFLEN]; virSecretPtr dom; PyObject *pyobj_dom; int c_retval; if (!PyArg_ParseTuple(args, (char *)"O:virSecretGetUUIDString", &pyobj_dom)) return NULL; dom = (virSecretPtr) PyvirSecret_Get(pyobj_dom); if (dom == NULL) return VIR_PY_NONE; LIBVIRT_BEGIN_ALLOW_THREADS; c_retval = virSecretGetUUIDString(dom, &uuidstr[0]); LIBVIRT_END_ALLOW_THREADS; if (c_retval < 0) return VIR_PY_NONE; py_retval = libvirt_constcharPtrWrap((char *) &uuidstr[0]); return py_retval; } static PyObject * libvirt_virSecretLookupByUUID(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { PyObject *py_retval; virSecretPtr c_retval; virConnectPtr conn; PyObject *pyobj_conn; unsigned char * uuid; int len; if (!PyArg_ParseTuple(args, (char *)"Oz#:virSecretLookupByUUID", &pyobj_conn, &uuid, &len)) return NULL; conn = (virConnectPtr) PyvirConnect_Get(pyobj_conn); if ((uuid == NULL) || (len != VIR_UUID_BUFLEN)) return VIR_PY_NONE; LIBVIRT_BEGIN_ALLOW_THREADS; c_retval = virSecretLookupByUUID(conn, uuid); LIBVIRT_END_ALLOW_THREADS; py_retval = libvirt_virSecretPtrWrap((virSecretPtr) c_retval); return py_retval; } static PyObject * libvirt_virConnectListSecrets(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { PyObject *py_retval; char **uuids = NULL; virConnectPtr conn; int c_retval; size_t i; PyObject *pyobj_conn; if (!PyArg_ParseTuple(args, (char *)"O:virConnectListSecrets", &pyobj_conn)) return NULL; conn = (virConnectPtr) PyvirConnect_Get(pyobj_conn); LIBVIRT_BEGIN_ALLOW_THREADS; c_retval = virConnectNumOfSecrets(conn); LIBVIRT_END_ALLOW_THREADS; if (c_retval < 0) return VIR_PY_NONE; if (c_retval) { if (VIR_ALLOC_N(uuids, c_retval) < 0) return VIR_PY_NONE; LIBVIRT_BEGIN_ALLOW_THREADS; c_retval = virConnectListSecrets(conn, uuids, c_retval); LIBVIRT_END_ALLOW_THREADS; if (c_retval < 0) { VIR_FREE(uuids); return VIR_PY_NONE; } } py_retval = PyList_New(c_retval); if (uuids) { for (i = 0; i < c_retval; i++) { PyList_SetItem(py_retval, i, libvirt_constcharPtrWrap(uuids[i])); VIR_FREE(uuids[i]); } VIR_FREE(uuids); } return py_retval; } #if LIBVIR_CHECK_VERSION(0, 10, 2) static PyObject * libvirt_virConnectListAllSecrets(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { PyObject *pyobj_conn; PyObject *py_retval = NULL; PyObject *tmp = NULL; virConnectPtr conn; virSecretPtr *secrets = NULL; int c_retval = 0; size_t i; unsigned int flags; if (!PyArg_ParseTuple(args, (char *)"Oi:virConnectListAllSecrets", &pyobj_conn, &flags)) return NULL; conn = (virConnectPtr) PyvirConnect_Get(pyobj_conn); LIBVIRT_BEGIN_ALLOW_THREADS; c_retval = virConnectListAllSecrets(conn, &secrets, flags); LIBVIRT_END_ALLOW_THREADS; if (c_retval < 0) return VIR_PY_NONE; if (!(py_retval = PyList_New(c_retval))) goto cleanup; for (i = 0; i < c_retval; i++) { if (!(tmp = libvirt_virSecretPtrWrap(secrets[i])) || PyList_SetItem(py_retval, i, tmp) < 0) { Py_XDECREF(tmp); Py_DECREF(py_retval); py_retval = NULL; goto cleanup; } /* python steals the pointer */ secrets[i] = NULL; } cleanup: for (i = 0; i < c_retval; i++) if (secrets[i]) virSecretFree(secrets[i]); VIR_FREE(secrets); return py_retval; } #endif /* LIBVIR_CHECK_VERSION(0, 10, 2) */ static PyObject * libvirt_virSecretGetValue(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { PyObject *py_retval; unsigned char *c_retval; size_t size; virSecretPtr secret; PyObject *pyobj_secret; unsigned int flags; if (!PyArg_ParseTuple(args, (char *)"Oi:virSecretGetValue", &pyobj_secret, &flags)) return NULL; secret = (virSecretPtr) PyvirSecret_Get(pyobj_secret); LIBVIRT_BEGIN_ALLOW_THREADS; c_retval = virSecretGetValue(secret, &size, flags); LIBVIRT_END_ALLOW_THREADS; if (c_retval == NULL) return VIR_PY_NONE; py_retval = libvirt_charPtrSizeWrap((char*)c_retval, size); VIR_FREE(c_retval); return py_retval; } static PyObject * libvirt_virSecretSetValue(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { PyObject *py_retval; int c_retval; virSecretPtr secret; PyObject *pyobj_secret; const char *value; int size; unsigned int flags; if (!PyArg_ParseTuple(args, (char *)"Oz#i:virSecretSetValue", &pyobj_secret, &value, &size, &flags)) return NULL; secret = (virSecretPtr) PyvirSecret_Get(pyobj_secret); LIBVIRT_BEGIN_ALLOW_THREADS; c_retval = virSecretSetValue(secret, (const unsigned char *)value, size, flags); LIBVIRT_END_ALLOW_THREADS; py_retval = libvirt_intWrap(c_retval); return py_retval; } static PyObject * libvirt_virNWFilterGetUUID(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { PyObject *py_retval; unsigned char uuid[VIR_UUID_BUFLEN]; virNWFilterPtr nwfilter; PyObject *pyobj_nwfilter; int c_retval; if (!PyArg_ParseTuple(args, (char *)"O:virNWFilterGetUUID", &pyobj_nwfilter)) return NULL; nwfilter = (virNWFilterPtr) PyvirNWFilter_Get(pyobj_nwfilter); if (nwfilter == NULL) return VIR_PY_NONE; LIBVIRT_BEGIN_ALLOW_THREADS; c_retval = virNWFilterGetUUID(nwfilter, &uuid[0]); LIBVIRT_END_ALLOW_THREADS; if (c_retval < 0) return VIR_PY_NONE; py_retval = libvirt_charPtrSizeWrap((char *) &uuid[0], VIR_UUID_BUFLEN); return py_retval; } static PyObject * libvirt_virNWFilterGetUUIDString(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { PyObject *py_retval; char uuidstr[VIR_UUID_STRING_BUFLEN]; virNWFilterPtr nwfilter; PyObject *pyobj_nwfilter; int c_retval; if (!PyArg_ParseTuple(args, (char *)"O:virNWFilterGetUUIDString", &pyobj_nwfilter)) return NULL; nwfilter = (virNWFilterPtr) PyvirNWFilter_Get(pyobj_nwfilter); if (nwfilter == NULL) return VIR_PY_NONE; LIBVIRT_BEGIN_ALLOW_THREADS; c_retval = virNWFilterGetUUIDString(nwfilter, &uuidstr[0]); LIBVIRT_END_ALLOW_THREADS; if (c_retval < 0) return VIR_PY_NONE; py_retval = libvirt_constcharPtrWrap((char *) &uuidstr[0]); return py_retval; } static PyObject * libvirt_virNWFilterLookupByUUID(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { PyObject *py_retval; virNWFilterPtr c_retval; virConnectPtr conn; PyObject *pyobj_conn; unsigned char * uuid; int len; if (!PyArg_ParseTuple(args, (char *)"Oz#:virNWFilterLookupByUUID", &pyobj_conn, &uuid, &len)) return NULL; conn = (virConnectPtr) PyvirConnect_Get(pyobj_conn); if ((uuid == NULL) || (len != VIR_UUID_BUFLEN)) return VIR_PY_NONE; LIBVIRT_BEGIN_ALLOW_THREADS; c_retval = virNWFilterLookupByUUID(conn, uuid); LIBVIRT_END_ALLOW_THREADS; py_retval = libvirt_virNWFilterPtrWrap((virNWFilterPtr) c_retval); return py_retval; } static PyObject * libvirt_virConnectListNWFilters(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { PyObject *py_retval; char **uuids = NULL; virConnectPtr conn; int c_retval; size_t i; PyObject *pyobj_conn; if (!PyArg_ParseTuple(args, (char *)"O:virConnectListNWFilters", &pyobj_conn)) return NULL; conn = (virConnectPtr) PyvirConnect_Get(pyobj_conn); LIBVIRT_BEGIN_ALLOW_THREADS; c_retval = virConnectNumOfNWFilters(conn); LIBVIRT_END_ALLOW_THREADS; if (c_retval < 0) return VIR_PY_NONE; if (c_retval) { if (VIR_ALLOC_N(uuids, c_retval) < 0) return VIR_PY_NONE; LIBVIRT_BEGIN_ALLOW_THREADS; c_retval = virConnectListNWFilters(conn, uuids, c_retval); LIBVIRT_END_ALLOW_THREADS; if (c_retval < 0) { VIR_FREE(uuids); return VIR_PY_NONE; } } py_retval = PyList_New(c_retval); if (uuids) { for (i = 0; i < c_retval; i++) { PyList_SetItem(py_retval, i, libvirt_constcharPtrWrap(uuids[i])); VIR_FREE(uuids[i]); } VIR_FREE(uuids); } return py_retval; } #if LIBVIR_CHECK_VERSION(0, 10, 2) static PyObject * libvirt_virConnectListAllNWFilters(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { PyObject *pyobj_conn; PyObject *py_retval = NULL; PyObject *tmp = NULL; virConnectPtr conn; virNWFilterPtr *filters = NULL; int c_retval = 0; size_t i; unsigned int flags; if (!PyArg_ParseTuple(args, (char *)"Oi:virConnectListAllNWFilters", &pyobj_conn, &flags)) return NULL; conn = (virConnectPtr) PyvirConnect_Get(pyobj_conn); LIBVIRT_BEGIN_ALLOW_THREADS; c_retval = virConnectListAllNWFilters(conn, &filters, flags); LIBVIRT_END_ALLOW_THREADS; if (c_retval < 0) return VIR_PY_NONE; if (!(py_retval = PyList_New(c_retval))) goto cleanup; for (i = 0; i < c_retval; i++) { if (!(tmp = libvirt_virNWFilterPtrWrap(filters[i])) || PyList_SetItem(py_retval, i, tmp) < 0) { Py_XDECREF(tmp); Py_DECREF(py_retval); py_retval = NULL; goto cleanup; } /* python steals the pointer */ filters[i] = NULL; } cleanup: for (i = 0; i < c_retval; i++) if (filters[i]) virNWFilterFree(filters[i]); VIR_FREE(filters); return py_retval; } #endif /* LIBVIR_CHECK_VERSION(0, 10, 2) */ static PyObject * libvirt_virConnectListInterfaces(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { PyObject *py_retval; char **names = NULL; int c_retval; size_t i; virConnectPtr conn; PyObject *pyobj_conn; if (!PyArg_ParseTuple(args, (char *)"O:virConnectListInterfaces", &pyobj_conn)) return NULL; conn = (virConnectPtr) PyvirConnect_Get(pyobj_conn); LIBVIRT_BEGIN_ALLOW_THREADS; c_retval = virConnectNumOfInterfaces(conn); LIBVIRT_END_ALLOW_THREADS; if (c_retval < 0) return VIR_PY_NONE; if (c_retval) { if (VIR_ALLOC_N(names, c_retval) < 0) return VIR_PY_NONE; LIBVIRT_BEGIN_ALLOW_THREADS; c_retval = virConnectListInterfaces(conn, names, c_retval); LIBVIRT_END_ALLOW_THREADS; if (c_retval < 0) { VIR_FREE(names); return VIR_PY_NONE; } } py_retval = PyList_New(c_retval); if (py_retval == NULL) { if (names) { for (i = 0; i < c_retval; i++) VIR_FREE(names[i]); VIR_FREE(names); } return VIR_PY_NONE; } if (names) { for (i = 0; i < c_retval; i++) { PyList_SetItem(py_retval, i, libvirt_constcharPtrWrap(names[i])); VIR_FREE(names[i]); } VIR_FREE(names); } return py_retval; } static PyObject * libvirt_virConnectListDefinedInterfaces(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { PyObject *py_retval; char **names = NULL; int c_retval; size_t i; virConnectPtr conn; PyObject *pyobj_conn; if (!PyArg_ParseTuple(args, (char *)"O:virConnectListDefinedInterfaces", &pyobj_conn)) return NULL; conn = (virConnectPtr) PyvirConnect_Get(pyobj_conn); LIBVIRT_BEGIN_ALLOW_THREADS; c_retval = virConnectNumOfDefinedInterfaces(conn); LIBVIRT_END_ALLOW_THREADS; if (c_retval < 0) return VIR_PY_NONE; if (c_retval) { if (VIR_ALLOC_N(names, c_retval) < 0) return VIR_PY_NONE; LIBVIRT_BEGIN_ALLOW_THREADS; c_retval = virConnectListDefinedInterfaces(conn, names, c_retval); LIBVIRT_END_ALLOW_THREADS; if (c_retval < 0) { VIR_FREE(names); return VIR_PY_NONE; } } py_retval = PyList_New(c_retval); if (py_retval == NULL) { if (names) { for (i = 0; i < c_retval; i++) VIR_FREE(names[i]); VIR_FREE(names); } return VIR_PY_NONE; } if (names) { for (i = 0; i < c_retval; i++) { PyList_SetItem(py_retval, i, libvirt_constcharPtrWrap(names[i])); VIR_FREE(names[i]); } VIR_FREE(names); } return py_retval; } #if LIBVIR_CHECK_VERSION(0, 10, 2) static PyObject * libvirt_virConnectListAllInterfaces(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { PyObject *pyobj_conn; PyObject *py_retval = NULL; PyObject *tmp = NULL; virConnectPtr conn; virInterfacePtr *ifaces = NULL; int c_retval = 0; size_t i; unsigned int flags; if (!PyArg_ParseTuple(args, (char *)"Oi:virConnectListAllInterfaces", &pyobj_conn, &flags)) return NULL; conn = (virConnectPtr) PyvirConnect_Get(pyobj_conn); LIBVIRT_BEGIN_ALLOW_THREADS; c_retval = virConnectListAllInterfaces(conn, &ifaces, flags); LIBVIRT_END_ALLOW_THREADS; if (c_retval < 0) return VIR_PY_NONE; if (!(py_retval = PyList_New(c_retval))) goto cleanup; for (i = 0; i < c_retval; i++) { if (!(tmp = libvirt_virInterfacePtrWrap(ifaces[i])) || PyList_SetItem(py_retval, i, tmp) < 0) { Py_XDECREF(tmp); Py_DECREF(py_retval); py_retval = NULL; goto cleanup; } /* python steals the pointer */ ifaces[i] = NULL; } cleanup: for (i = 0; i < c_retval; i++) if (ifaces[i]) virInterfaceFree(ifaces[i]); VIR_FREE(ifaces); return py_retval; } #endif /* LIBVIR_CHECK_VERSION(0, 10, 2) */ static PyObject * libvirt_virConnectBaselineCPU(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { PyObject *pyobj_conn; PyObject *list; virConnectPtr conn; unsigned int flags; char **xmlcpus = NULL; int ncpus = 0; char *base_cpu; PyObject *pybase_cpu; size_t i, j; if (!PyArg_ParseTuple(args, (char *)"OOi:virConnectBaselineCPU", &pyobj_conn, &list, &flags)) return NULL; conn = (virConnectPtr) PyvirConnect_Get(pyobj_conn); if (PyList_Check(list)) { ncpus = PyList_Size(list); if (VIR_ALLOC_N(xmlcpus, ncpus) < 0) return VIR_PY_NONE; for (i = 0; i < ncpus; i++) { if (libvirt_charPtrUnwrap(PyList_GetItem(list, i), &(xmlcpus[i])) < 0 || xmlcpus[i] == NULL) { for (j = 0 ; j < i ; j++) VIR_FREE(xmlcpus[j]); VIR_FREE(xmlcpus); return VIR_PY_NONE; } } } LIBVIRT_BEGIN_ALLOW_THREADS; base_cpu = virConnectBaselineCPU(conn, (const char **)xmlcpus, ncpus, flags); LIBVIRT_END_ALLOW_THREADS; for (i = 0 ; i < ncpus ; i++) VIR_FREE(xmlcpus[i]); VIR_FREE(xmlcpus); if (base_cpu == NULL) return VIR_PY_NONE; pybase_cpu = libvirt_constcharPtrWrap(base_cpu); VIR_FREE(base_cpu); if (pybase_cpu == NULL) return VIR_PY_NONE; return pybase_cpu; } static PyObject * libvirt_virDomainGetJobInfo(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { PyObject *py_retval; int c_retval; virDomainPtr domain; PyObject *pyobj_domain; virDomainJobInfo info; if (!PyArg_ParseTuple(args, (char *)"O:virDomainGetJobInfo", &pyobj_domain)) return NULL; domain = (virDomainPtr) PyvirDomain_Get(pyobj_domain); LIBVIRT_BEGIN_ALLOW_THREADS; c_retval = virDomainGetJobInfo(domain, &info); LIBVIRT_END_ALLOW_THREADS; if (c_retval < 0) return VIR_PY_NONE; py_retval = PyList_New(12); PyList_SetItem(py_retval, 0, libvirt_intWrap((int) info.type)); PyList_SetItem(py_retval, 1, libvirt_ulonglongWrap(info.timeElapsed)); PyList_SetItem(py_retval, 2, libvirt_ulonglongWrap(info.timeRemaining)); PyList_SetItem(py_retval, 3, libvirt_ulonglongWrap(info.dataTotal)); PyList_SetItem(py_retval, 4, libvirt_ulonglongWrap(info.dataProcessed)); PyList_SetItem(py_retval, 5, libvirt_ulonglongWrap(info.dataRemaining)); PyList_SetItem(py_retval, 6, libvirt_ulonglongWrap(info.memTotal)); PyList_SetItem(py_retval, 7, libvirt_ulonglongWrap(info.memProcessed)); PyList_SetItem(py_retval, 8, libvirt_ulonglongWrap(info.memRemaining)); PyList_SetItem(py_retval, 9, libvirt_ulonglongWrap(info.fileTotal)); PyList_SetItem(py_retval, 10, libvirt_ulonglongWrap(info.fileProcessed)); PyList_SetItem(py_retval, 11, libvirt_ulonglongWrap(info.fileRemaining)); return py_retval; } #if LIBVIR_CHECK_VERSION(1, 0, 3) static PyObject * libvirt_virDomainGetJobStats(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { PyObject *pyobj_domain; virDomainPtr domain; unsigned int flags; virTypedParameterPtr params = NULL; int nparams = 0; int type; PyObject *dict = NULL; int rc; if (!PyArg_ParseTuple(args, (char *) "Oi:virDomainGetJobStats", &pyobj_domain, &flags)) goto cleanup; domain = (virDomainPtr) PyvirDomain_Get(pyobj_domain); LIBVIRT_BEGIN_ALLOW_THREADS; rc = virDomainGetJobStats(domain, &type, ¶ms, &nparams, flags); LIBVIRT_END_ALLOW_THREADS; if (rc < 0) goto cleanup; if (!(dict = getPyVirTypedParameter(params, nparams))) goto cleanup; if (PyDict_SetItem(dict, libvirt_constcharPtrWrap("type"), libvirt_intWrap(type)) < 0) { Py_DECREF(dict); dict = NULL; goto cleanup; } cleanup: virTypedParamsFree(params, nparams); if (dict) return dict; else return VIR_PY_NONE; } #endif /* LIBVIR_CHECK_VERSION(1, 0, 3) */ static PyObject * libvirt_virDomainGetBlockJobInfo(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { virDomainPtr domain; PyObject *pyobj_domain; const char *path; unsigned int flags; virDomainBlockJobInfo info; int c_ret; PyObject *type = NULL, *bandwidth = NULL, *cur = NULL, *end = NULL; PyObject *dict; if (!PyArg_ParseTuple(args, (char *)"Ozi:virDomainGetBlockJobInfo", &pyobj_domain, &path, &flags)) return NULL; domain = (virDomainPtr) PyvirDomain_Get(pyobj_domain); if ((dict = PyDict_New()) == NULL) return NULL; LIBVIRT_BEGIN_ALLOW_THREADS; c_ret = virDomainGetBlockJobInfo(domain, path, &info, flags); LIBVIRT_END_ALLOW_THREADS; if (c_ret == 0) { return dict; } else if (c_ret < 0) { Py_DECREF(dict); return VIR_PY_NONE; } if ((type = libvirt_intWrap(info.type)) == NULL || PyDict_SetItemString(dict, "type", type) < 0) goto error; Py_DECREF(type); if ((bandwidth = libvirt_ulongWrap(info.bandwidth)) == NULL || PyDict_SetItemString(dict, "bandwidth", bandwidth) < 0) goto error; Py_DECREF(bandwidth); if ((cur = libvirt_ulonglongWrap(info.cur)) == NULL || PyDict_SetItemString(dict, "cur", cur) < 0) goto error; Py_DECREF(cur); if ((end = libvirt_ulonglongWrap(info.end)) == NULL || PyDict_SetItemString(dict, "end", end) < 0) goto error; Py_DECREF(end); return dict; error: Py_DECREF(dict); Py_XDECREF(type); Py_XDECREF(bandwidth); Py_XDECREF(cur); Py_XDECREF(end); return NULL; } static PyObject * libvirt_virDomainSetBlockIoTune(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { virDomainPtr domain; PyObject *pyobj_domain, *info; PyObject *ret = NULL; int i_retval; int nparams = 0; Py_ssize_t size = 0; const char *disk; unsigned int flags; virTypedParameterPtr params, new_params = NULL; if (!PyArg_ParseTuple(args, (char *)"OzOi:virDomainSetBlockIoTune", &pyobj_domain, &disk, &info, &flags)) return NULL; domain = (virDomainPtr) PyvirDomain_Get(pyobj_domain); if ((size = PyDict_Size(info)) < 0) return NULL; if (size == 0) { PyErr_Format(PyExc_LookupError, "Need non-empty dictionary to set attributes"); return NULL; } LIBVIRT_BEGIN_ALLOW_THREADS; i_retval = virDomainGetBlockIoTune(domain, disk, NULL, &nparams, flags); LIBVIRT_END_ALLOW_THREADS; if (i_retval < 0) return VIR_PY_INT_FAIL; if (nparams == 0) { PyErr_Format(PyExc_LookupError, "Domain has no settable attributes"); return NULL; } if (VIR_ALLOC_N(params, nparams) < 0) return PyErr_NoMemory(); LIBVIRT_BEGIN_ALLOW_THREADS; i_retval = virDomainGetBlockIoTune(domain, disk, params, &nparams, flags); LIBVIRT_END_ALLOW_THREADS; if (i_retval < 0) { ret = VIR_PY_INT_FAIL; goto cleanup; } new_params = setPyVirTypedParameter(info, params, nparams); if (!new_params) goto cleanup; LIBVIRT_BEGIN_ALLOW_THREADS; i_retval = virDomainSetBlockIoTune(domain, disk, new_params, size, flags); LIBVIRT_END_ALLOW_THREADS; if (i_retval < 0) { ret = VIR_PY_INT_FAIL; goto cleanup; } ret = VIR_PY_INT_SUCCESS; cleanup: virTypedParamsFree(params, nparams); virTypedParamsFree(new_params, nparams); return ret; } static PyObject * libvirt_virDomainGetBlockIoTune(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { virDomainPtr domain; PyObject *pyobj_domain; PyObject *ret = NULL; int i_retval; int nparams = 0; const char *disk; unsigned int flags; virTypedParameterPtr params; if (!PyArg_ParseTuple(args, (char *)"Ozi:virDomainGetBlockIoTune", &pyobj_domain, &disk, &flags)) return NULL; domain = (virDomainPtr) PyvirDomain_Get(pyobj_domain); LIBVIRT_BEGIN_ALLOW_THREADS; i_retval = virDomainGetBlockIoTune(domain, disk, NULL, &nparams, flags); LIBVIRT_END_ALLOW_THREADS; if (i_retval < 0) return VIR_PY_NONE; if (!nparams) return PyDict_New(); if (VIR_ALLOC_N(params, nparams) < 0) return PyErr_NoMemory(); LIBVIRT_BEGIN_ALLOW_THREADS; i_retval = virDomainGetBlockIoTune(domain, disk, params, &nparams, flags); LIBVIRT_END_ALLOW_THREADS; if (i_retval < 0) { ret = VIR_PY_NONE; goto cleanup; } ret = getPyVirTypedParameter(params, nparams); cleanup: virTypedParamsFree(params, nparams); return ret; } static PyObject * libvirt_virDomainGetDiskErrors(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { PyObject *py_retval = VIR_PY_NONE; virDomainPtr domain; PyObject *pyobj_domain; unsigned int flags; virDomainDiskErrorPtr disks = NULL; unsigned int ndisks; int count; size_t i; if (!PyArg_ParseTuple(args, (char *) "Oi:virDomainGetDiskErrors", &pyobj_domain, &flags)) return NULL; domain = (virDomainPtr) PyvirDomain_Get(pyobj_domain); if ((count = virDomainGetDiskErrors(domain, NULL, 0, 0)) < 0) return VIR_PY_NONE; ndisks = count; if (ndisks) { if (VIR_ALLOC_N(disks, ndisks) < 0) return VIR_PY_NONE; LIBVIRT_BEGIN_ALLOW_THREADS; count = virDomainGetDiskErrors(domain, disks, ndisks, 0); LIBVIRT_END_ALLOW_THREADS; if (count < 0) goto cleanup; } if (!(py_retval = PyDict_New())) goto cleanup; for (i = 0; i < count; i++) { PyDict_SetItem(py_retval, libvirt_constcharPtrWrap(disks[i].disk), libvirt_intWrap(disks[i].error)); } cleanup: if (disks) { for (i = 0; i < count; i++) VIR_FREE(disks[i].disk); VIR_FREE(disks); } return py_retval; } /******************************************* * Helper functions to avoid importing modules * for every callback *******************************************/ static PyObject *libvirt_module = NULL; static PyObject *libvirt_dict = NULL; static PyObject * getLibvirtModuleObject(void) { if (libvirt_module) return libvirt_module; // PyImport_ImportModule returns a new reference /* Bogus (char *) cast for RHEL-5 python API brokenness */ libvirt_module = PyImport_ImportModule((char *)"libvirt"); if (!libvirt_module) { DEBUG("%s Error importing libvirt module\n", __FUNCTION__); PyErr_Print(); return NULL; } return libvirt_module; } static PyObject * getLibvirtDictObject(void) { if (libvirt_dict) return libvirt_dict; // PyModule_GetDict returns a borrowed reference libvirt_dict = PyModule_GetDict(getLibvirtModuleObject()); if (!libvirt_dict) { DEBUG("%s Error importing libvirt dictionary\n", __FUNCTION__); PyErr_Print(); return NULL; } Py_INCREF(libvirt_dict); return libvirt_dict; } static PyObject * libvirt_lookupPythonFunc(const char *funcname) { PyObject *python_cb; /* Lookup the python callback */ python_cb = PyDict_GetItemString(getLibvirtDictObject(), funcname); if (!python_cb) { DEBUG("%s: Error finding %s\n", __FUNCTION__, funcname); PyErr_Print(); PyErr_Clear(); return NULL; } if (!PyCallable_Check(python_cb)) { DEBUG("%s: %s is not callable\n", __FUNCTION__, funcname); return NULL; } return python_cb; } /******************************************* * Domain Events *******************************************/ static int libvirt_virConnectDomainEventCallback(virConnectPtr conn ATTRIBUTE_UNUSED, virDomainPtr dom, int event, int detail, void *opaque) { PyObject *pyobj_ret; PyObject *pyobj_conn = (PyObject*)opaque; PyObject *pyobj_dom; int ret = -1; LIBVIRT_ENSURE_THREAD_STATE; /* Create a python instance of this virDomainPtr */ virDomainRef(dom); pyobj_dom = libvirt_virDomainPtrWrap(dom); /* Call the Callback Dispatcher */ pyobj_ret = PyObject_CallMethod(pyobj_conn, (char*)"_dispatchDomainEventCallbacks", (char*)"Oii", pyobj_dom, event, detail); Py_DECREF(pyobj_dom); if (!pyobj_ret) { DEBUG("%s - ret:%p\n", __FUNCTION__, pyobj_ret); PyErr_Print(); } else { Py_DECREF(pyobj_ret); ret = 0; } LIBVIRT_RELEASE_THREAD_STATE; return ret; } static PyObject * libvirt_virConnectDomainEventRegister(ATTRIBUTE_UNUSED PyObject * self, PyObject * args) { PyObject *py_retval; /* return value */ PyObject *pyobj_conn; /* virConnectPtr */ PyObject *pyobj_conn_inst; /* virConnect Python object */ virConnectPtr conn; int ret = 0; if (!PyArg_ParseTuple (args, (char *) "OO:virConnectDomainEventRegister", &pyobj_conn, &pyobj_conn_inst)) { DEBUG("%s failed parsing tuple\n", __FUNCTION__); return VIR_PY_INT_FAIL; } DEBUG("libvirt_virConnectDomainEventRegister(%p %p) called\n", pyobj_conn, pyobj_conn_inst); conn = (virConnectPtr) PyvirConnect_Get(pyobj_conn); Py_INCREF(pyobj_conn_inst); LIBVIRT_BEGIN_ALLOW_THREADS; ret = virConnectDomainEventRegister(conn, libvirt_virConnectDomainEventCallback, (void *)pyobj_conn_inst, NULL); LIBVIRT_END_ALLOW_THREADS; py_retval = libvirt_intWrap(ret); return py_retval; } static PyObject * libvirt_virConnectDomainEventDeregister(ATTRIBUTE_UNUSED PyObject * self, PyObject * args) { PyObject *py_retval; PyObject *pyobj_conn; PyObject *pyobj_conn_inst; virConnectPtr conn; int ret = 0; if (!PyArg_ParseTuple (args, (char *) "OO:virConnectDomainEventDeregister", &pyobj_conn, &pyobj_conn_inst)) return NULL; DEBUG("libvirt_virConnectDomainEventDeregister(%p) called\n", pyobj_conn); conn = (virConnectPtr) PyvirConnect_Get(pyobj_conn); LIBVIRT_BEGIN_ALLOW_THREADS; ret = virConnectDomainEventDeregister(conn, libvirt_virConnectDomainEventCallback); LIBVIRT_END_ALLOW_THREADS; Py_DECREF(pyobj_conn_inst); py_retval = libvirt_intWrap(ret); return py_retval; } /******************************************* * Event Impl *******************************************/ static PyObject *addHandleObj; static char *addHandleName; static PyObject *updateHandleObj; static char *updateHandleName; static PyObject *removeHandleObj; static char *removeHandleName; static PyObject *addTimeoutObj; static char *addTimeoutName; static PyObject *updateTimeoutObj; static char *updateTimeoutName; static PyObject *removeTimeoutObj; static char *removeTimeoutName; #define NAME(fn) ( fn ## Name ? fn ## Name : # fn ) static int libvirt_virEventAddHandleFunc (int fd, int event, virEventHandleCallback cb, void *opaque, virFreeCallback ff) { PyObject *result; PyObject *python_cb; PyObject *cb_obj; PyObject *ff_obj; PyObject *opaque_obj; PyObject *cb_args; PyObject *pyobj_args; int retval = -1; LIBVIRT_ENSURE_THREAD_STATE; /* Lookup the python callback */ python_cb = libvirt_lookupPythonFunc("_eventInvokeHandleCallback"); if (!python_cb) { goto cleanup; } Py_INCREF(python_cb); /* create tuple for cb */ cb_obj = libvirt_virEventHandleCallbackWrap(cb); ff_obj = libvirt_virFreeCallbackWrap(ff); opaque_obj = libvirt_virVoidPtrWrap(opaque); cb_args = PyTuple_New(3); PyTuple_SetItem(cb_args, 0, cb_obj); PyTuple_SetItem(cb_args, 1, opaque_obj); PyTuple_SetItem(cb_args, 2, ff_obj); pyobj_args = PyTuple_New(4); PyTuple_SetItem(pyobj_args, 0, libvirt_intWrap(fd)); PyTuple_SetItem(pyobj_args, 1, libvirt_intWrap(event)); PyTuple_SetItem(pyobj_args, 2, python_cb); PyTuple_SetItem(pyobj_args, 3, cb_args); result = PyEval_CallObject(addHandleObj, pyobj_args); if (!result) { PyErr_Print(); PyErr_Clear(); } else { libvirt_intUnwrap(result, &retval); } Py_XDECREF(result); Py_DECREF(pyobj_args); cleanup: LIBVIRT_RELEASE_THREAD_STATE; return retval; } static void libvirt_virEventUpdateHandleFunc(int watch, int event) { PyObject *result; PyObject *pyobj_args; LIBVIRT_ENSURE_THREAD_STATE; pyobj_args = PyTuple_New(2); PyTuple_SetItem(pyobj_args, 0, libvirt_intWrap(watch)); PyTuple_SetItem(pyobj_args, 1, libvirt_intWrap(event)); result = PyEval_CallObject(updateHandleObj, pyobj_args); if (!result) { PyErr_Print(); PyErr_Clear(); } Py_XDECREF(result); Py_DECREF(pyobj_args); LIBVIRT_RELEASE_THREAD_STATE; } static int libvirt_virEventRemoveHandleFunc(int watch) { PyObject *result; PyObject *pyobj_args; PyObject *opaque; PyObject *ff; int retval = -1; virFreeCallback cff; LIBVIRT_ENSURE_THREAD_STATE; pyobj_args = PyTuple_New(1); PyTuple_SetItem(pyobj_args, 0, libvirt_intWrap(watch)); result = PyEval_CallObject(removeHandleObj, pyobj_args); if (!result) { PyErr_Print(); PyErr_Clear(); } else if (!PyTuple_Check(result) || PyTuple_Size(result) != 3) { DEBUG("%s: %s must return opaque obj registered with %s" "to avoid leaking libvirt memory\n", __FUNCTION__, NAME(removeHandle), NAME(addHandle)); } else { opaque = PyTuple_GetItem(result, 1); ff = PyTuple_GetItem(result, 2); cff = PyvirFreeCallback_Get(ff); if (cff) (*cff)(PyvirVoidPtr_Get(opaque)); retval = 0; } Py_XDECREF(result); Py_DECREF(pyobj_args); LIBVIRT_RELEASE_THREAD_STATE; return retval; } static int libvirt_virEventAddTimeoutFunc(int timeout, virEventTimeoutCallback cb, void *opaque, virFreeCallback ff) { PyObject *result; PyObject *python_cb; PyObject *cb_obj; PyObject *ff_obj; PyObject *opaque_obj; PyObject *cb_args; PyObject *pyobj_args; int retval = -1; LIBVIRT_ENSURE_THREAD_STATE; /* Lookup the python callback */ python_cb = libvirt_lookupPythonFunc("_eventInvokeTimeoutCallback"); if (!python_cb) { goto cleanup; } Py_INCREF(python_cb); /* create tuple for cb */ cb_obj = libvirt_virEventTimeoutCallbackWrap(cb); ff_obj = libvirt_virFreeCallbackWrap(ff); opaque_obj = libvirt_virVoidPtrWrap(opaque); cb_args = PyTuple_New(3); PyTuple_SetItem(cb_args, 0, cb_obj); PyTuple_SetItem(cb_args, 1, opaque_obj); PyTuple_SetItem(cb_args, 2, ff_obj); pyobj_args = PyTuple_New(3); PyTuple_SetItem(pyobj_args, 0, libvirt_intWrap(timeout)); PyTuple_SetItem(pyobj_args, 1, python_cb); PyTuple_SetItem(pyobj_args, 2, cb_args); result = PyEval_CallObject(addTimeoutObj, pyobj_args); if (!result) { PyErr_Print(); PyErr_Clear(); } else { libvirt_intUnwrap(result, &retval); } Py_XDECREF(result); Py_DECREF(pyobj_args); cleanup: LIBVIRT_RELEASE_THREAD_STATE; return retval; } static void libvirt_virEventUpdateTimeoutFunc(int timer, int timeout) { PyObject *result = NULL; PyObject *pyobj_args; LIBVIRT_ENSURE_THREAD_STATE; pyobj_args = PyTuple_New(2); PyTuple_SetItem(pyobj_args, 0, libvirt_intWrap(timer)); PyTuple_SetItem(pyobj_args, 1, libvirt_intWrap(timeout)); result = PyEval_CallObject(updateTimeoutObj, pyobj_args); if (!result) { PyErr_Print(); PyErr_Clear(); } Py_XDECREF(result); Py_DECREF(pyobj_args); LIBVIRT_RELEASE_THREAD_STATE; } static int libvirt_virEventRemoveTimeoutFunc(int timer) { PyObject *result = NULL; PyObject *pyobj_args; PyObject *opaque; PyObject *ff; int retval = -1; virFreeCallback cff; LIBVIRT_ENSURE_THREAD_STATE; pyobj_args = PyTuple_New(1); PyTuple_SetItem(pyobj_args, 0, libvirt_intWrap(timer)); result = PyEval_CallObject(removeTimeoutObj, pyobj_args); if (!result) { PyErr_Print(); PyErr_Clear(); } else if (!PyTuple_Check(result) || PyTuple_Size(result) != 3) { DEBUG("%s: %s must return opaque obj registered with %s" "to avoid leaking libvirt memory\n", __FUNCTION__, NAME(removeTimeout), NAME(addTimeout)); } else { opaque = PyTuple_GetItem(result, 1); ff = PyTuple_GetItem(result, 2); cff = PyvirFreeCallback_Get(ff); if (cff) (*cff)(PyvirVoidPtr_Get(opaque)); retval = 0; } Py_XDECREF(result); Py_DECREF(pyobj_args); LIBVIRT_RELEASE_THREAD_STATE; return retval; } static PyObject * libvirt_virEventRegisterImpl(ATTRIBUTE_UNUSED PyObject * self, PyObject * args) { /* Unref the previously-registered impl (if any) */ Py_XDECREF(addHandleObj); Py_XDECREF(updateHandleObj); Py_XDECREF(removeHandleObj); Py_XDECREF(addTimeoutObj); Py_XDECREF(updateTimeoutObj); Py_XDECREF(removeTimeoutObj); VIR_FREE(addHandleName); VIR_FREE(updateHandleName); VIR_FREE(removeHandleName); VIR_FREE(addTimeoutName); VIR_FREE(updateTimeoutName); VIR_FREE(removeTimeoutName); /* Parse and check arguments */ if (!PyArg_ParseTuple(args, (char *) "OOOOOO:virEventRegisterImpl", &addHandleObj, &updateHandleObj, &removeHandleObj, &addTimeoutObj, &updateTimeoutObj, &removeTimeoutObj) || !PyCallable_Check(addHandleObj) || !PyCallable_Check(updateHandleObj) || !PyCallable_Check(removeHandleObj) || !PyCallable_Check(addTimeoutObj) || !PyCallable_Check(updateTimeoutObj) || !PyCallable_Check(removeTimeoutObj)) return VIR_PY_INT_FAIL; /* Get argument string representations (for error reporting) */ addHandleName = py_str(addHandleObj); updateHandleName = py_str(updateHandleObj); removeHandleName = py_str(removeHandleObj); addTimeoutName = py_str(addTimeoutObj); updateTimeoutName = py_str(updateTimeoutObj); removeTimeoutName = py_str(removeTimeoutObj); /* Inc refs since we're holding on to these objects until * the next call (if any) to this function. */ Py_INCREF(addHandleObj); Py_INCREF(updateHandleObj); Py_INCREF(removeHandleObj); Py_INCREF(addTimeoutObj); Py_INCREF(updateTimeoutObj); Py_INCREF(removeTimeoutObj); LIBVIRT_BEGIN_ALLOW_THREADS; /* Now register our C EventImpl, which will dispatch * to the Python callbacks passed in as args. */ virEventRegisterImpl(libvirt_virEventAddHandleFunc, libvirt_virEventUpdateHandleFunc, libvirt_virEventRemoveHandleFunc, libvirt_virEventAddTimeoutFunc, libvirt_virEventUpdateTimeoutFunc, libvirt_virEventRemoveTimeoutFunc); LIBVIRT_END_ALLOW_THREADS; return VIR_PY_INT_SUCCESS; } static PyObject * libvirt_virEventInvokeHandleCallback(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { int watch, fd, event; PyObject *py_f; PyObject *py_opaque; virEventHandleCallback cb; void *opaque; if (!PyArg_ParseTuple (args, (char *) "iiiOO:virEventInvokeHandleCallback", &watch, &fd, &event, &py_f, &py_opaque )) return VIR_PY_INT_FAIL; cb = (virEventHandleCallback) PyvirEventHandleCallback_Get(py_f); opaque = (void *) PyvirVoidPtr_Get(py_opaque); if (cb) { LIBVIRT_BEGIN_ALLOW_THREADS; cb(watch, fd, event, opaque); LIBVIRT_END_ALLOW_THREADS; } return VIR_PY_INT_SUCCESS; } static PyObject * libvirt_virEventInvokeTimeoutCallback(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { int timer; PyObject *py_f; PyObject *py_opaque; virEventTimeoutCallback cb; void *opaque; if (!PyArg_ParseTuple (args, (char *) "iOO:virEventInvokeTimeoutCallback", &timer, &py_f, &py_opaque )) return VIR_PY_INT_FAIL; cb = (virEventTimeoutCallback) PyvirEventTimeoutCallback_Get(py_f); opaque = (void *) PyvirVoidPtr_Get(py_opaque); if (cb) { LIBVIRT_BEGIN_ALLOW_THREADS; cb(timer, opaque); LIBVIRT_END_ALLOW_THREADS; } return VIR_PY_INT_SUCCESS; } static void libvirt_virEventHandleCallback(int watch, int fd, int events, void *opaque) { PyObject *pyobj_cbData = (PyObject *)opaque; PyObject *pyobj_ret; PyObject *python_cb; LIBVIRT_ENSURE_THREAD_STATE; /* Lookup the python callback */ python_cb = libvirt_lookupPythonFunc("_dispatchEventHandleCallback"); if (!python_cb) { goto cleanup; } Py_INCREF(pyobj_cbData); /* Call the pure python dispatcher */ pyobj_ret = PyObject_CallFunction(python_cb, (char *)"iiiO", watch, fd, events, pyobj_cbData); Py_DECREF(pyobj_cbData); if (!pyobj_ret) { DEBUG("%s - ret:%p\n", __FUNCTION__, pyobj_ret); PyErr_Print(); } else { Py_DECREF(pyobj_ret); } cleanup: LIBVIRT_RELEASE_THREAD_STATE; } static PyObject * libvirt_virEventAddHandle(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { PyObject *py_retval; PyObject *pyobj_cbData; virEventHandleCallback cb = libvirt_virEventHandleCallback; int events; int fd; int ret; if (!PyArg_ParseTuple(args, (char *) "iiO:virEventAddHandle", &fd, &events, &pyobj_cbData)) { DEBUG("%s failed to parse tuple\n", __FUNCTION__); return VIR_PY_INT_FAIL; } Py_INCREF(pyobj_cbData); LIBVIRT_BEGIN_ALLOW_THREADS; ret = virEventAddHandle(fd, events, cb, pyobj_cbData, NULL); LIBVIRT_END_ALLOW_THREADS; if (ret < 0) { Py_DECREF(pyobj_cbData); } py_retval = libvirt_intWrap(ret); return py_retval; } static void libvirt_virEventTimeoutCallback(int timer, void *opaque) { PyObject *pyobj_cbData = (PyObject *)opaque; PyObject *pyobj_ret; PyObject *python_cb; LIBVIRT_ENSURE_THREAD_STATE; /* Lookup the python callback */ python_cb = libvirt_lookupPythonFunc("_dispatchEventTimeoutCallback"); if (!python_cb) { goto cleanup; } Py_INCREF(pyobj_cbData); /* Call the pure python dispatcher */ pyobj_ret = PyObject_CallFunction(python_cb, (char *)"iO", timer, pyobj_cbData); Py_DECREF(pyobj_cbData); if (!pyobj_ret) { DEBUG("%s - ret:%p\n", __FUNCTION__, pyobj_ret); PyErr_Print(); } else { Py_DECREF(pyobj_ret); } cleanup: LIBVIRT_RELEASE_THREAD_STATE; } static PyObject * libvirt_virEventAddTimeout(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { PyObject *py_retval; PyObject *pyobj_cbData; virEventTimeoutCallback cb = libvirt_virEventTimeoutCallback; int timeout; int ret; if (!PyArg_ParseTuple(args, (char *) "iO:virEventAddTimeout", &timeout, &pyobj_cbData)) { DEBUG("%s failed to parse tuple\n", __FUNCTION__); return VIR_PY_INT_FAIL; } Py_INCREF(pyobj_cbData); LIBVIRT_BEGIN_ALLOW_THREADS; ret = virEventAddTimeout(timeout, cb, pyobj_cbData, NULL); LIBVIRT_END_ALLOW_THREADS; if (ret < 0) { Py_DECREF(pyobj_cbData); } py_retval = libvirt_intWrap(ret); return py_retval; } static void libvirt_virConnectDomainEventFreeFunc(void *opaque) { PyObject *pyobj_conn = (PyObject*)opaque; LIBVIRT_ENSURE_THREAD_STATE; Py_DECREF(pyobj_conn); LIBVIRT_RELEASE_THREAD_STATE; } static int libvirt_virConnectDomainEventLifecycleCallback(virConnectPtr conn ATTRIBUTE_UNUSED, virDomainPtr dom, int event, int detail, void *opaque) { PyObject *pyobj_cbData = (PyObject*)opaque; PyObject *pyobj_dom; PyObject *pyobj_ret; PyObject *pyobj_conn; PyObject *dictKey; int ret = -1; LIBVIRT_ENSURE_THREAD_STATE; /* Create a python instance of this virDomainPtr */ virDomainRef(dom); pyobj_dom = libvirt_virDomainPtrWrap(dom); Py_INCREF(pyobj_cbData); dictKey = libvirt_constcharPtrWrap("conn"); pyobj_conn = PyDict_GetItem(pyobj_cbData, dictKey); Py_DECREF(dictKey); /* Call the Callback Dispatcher */ pyobj_ret = PyObject_CallMethod(pyobj_conn, (char*)"_dispatchDomainEventLifecycleCallback", (char*)"OiiO", pyobj_dom, event, detail, pyobj_cbData); Py_DECREF(pyobj_cbData); Py_DECREF(pyobj_dom); if (!pyobj_ret) { DEBUG("%s - ret:%p\n", __FUNCTION__, pyobj_ret); PyErr_Print(); } else { Py_DECREF(pyobj_ret); ret = 0; } LIBVIRT_RELEASE_THREAD_STATE; return ret; } static int libvirt_virConnectDomainEventGenericCallback(virConnectPtr conn ATTRIBUTE_UNUSED, virDomainPtr dom, void *opaque) { PyObject *pyobj_cbData = (PyObject*)opaque; PyObject *pyobj_dom; PyObject *pyobj_ret; PyObject *pyobj_conn; PyObject *dictKey; int ret = -1; LIBVIRT_ENSURE_THREAD_STATE; /* Create a python instance of this virDomainPtr */ virDomainRef(dom); pyobj_dom = libvirt_virDomainPtrWrap(dom); Py_INCREF(pyobj_cbData); dictKey = libvirt_constcharPtrWrap("conn"); pyobj_conn = PyDict_GetItem(pyobj_cbData, dictKey); Py_DECREF(dictKey); /* Call the Callback Dispatcher */ pyobj_ret = PyObject_CallMethod(pyobj_conn, (char*)"_dispatchDomainEventGenericCallback", (char*)"OO", pyobj_dom, pyobj_cbData); Py_DECREF(pyobj_cbData); Py_DECREF(pyobj_dom); if (!pyobj_ret) { DEBUG("%s - ret:%p\n", __FUNCTION__, pyobj_ret); PyErr_Print(); } else { Py_DECREF(pyobj_ret); ret = 0; } LIBVIRT_RELEASE_THREAD_STATE; return ret; } static int libvirt_virConnectDomainEventRTCChangeCallback(virConnectPtr conn ATTRIBUTE_UNUSED, virDomainPtr dom, long long utcoffset, void *opaque) { PyObject *pyobj_cbData = (PyObject*)opaque; PyObject *pyobj_dom; PyObject *pyobj_ret; PyObject *pyobj_conn; PyObject *dictKey; int ret = -1; LIBVIRT_ENSURE_THREAD_STATE; /* Create a python instance of this virDomainPtr */ virDomainRef(dom); pyobj_dom = libvirt_virDomainPtrWrap(dom); Py_INCREF(pyobj_cbData); dictKey = libvirt_constcharPtrWrap("conn"); pyobj_conn = PyDict_GetItem(pyobj_cbData, dictKey); Py_DECREF(dictKey); /* Call the Callback Dispatcher */ pyobj_ret = PyObject_CallMethod(pyobj_conn, (char*)"_dispatchDomainEventRTCChangeCallback", (char*)"OLO", pyobj_dom, (PY_LONG_LONG)utcoffset, pyobj_cbData); Py_DECREF(pyobj_cbData); Py_DECREF(pyobj_dom); if (!pyobj_ret) { DEBUG("%s - ret:%p\n", __FUNCTION__, pyobj_ret); PyErr_Print(); } else { Py_DECREF(pyobj_ret); ret = 0; } LIBVIRT_RELEASE_THREAD_STATE; return ret; } static int libvirt_virConnectDomainEventWatchdogCallback(virConnectPtr conn ATTRIBUTE_UNUSED, virDomainPtr dom, int action, void *opaque) { PyObject *pyobj_cbData = (PyObject*)opaque; PyObject *pyobj_dom; PyObject *pyobj_ret; PyObject *pyobj_conn; PyObject *dictKey; int ret = -1; LIBVIRT_ENSURE_THREAD_STATE; /* Create a python instance of this virDomainPtr */ virDomainRef(dom); pyobj_dom = libvirt_virDomainPtrWrap(dom); Py_INCREF(pyobj_cbData); dictKey = libvirt_constcharPtrWrap("conn"); pyobj_conn = PyDict_GetItem(pyobj_cbData, dictKey); Py_DECREF(dictKey); /* Call the Callback Dispatcher */ pyobj_ret = PyObject_CallMethod(pyobj_conn, (char*)"_dispatchDomainEventWatchdogCallback", (char*)"OiO", pyobj_dom, action, pyobj_cbData); Py_DECREF(pyobj_cbData); Py_DECREF(pyobj_dom); if (!pyobj_ret) { DEBUG("%s - ret:%p\n", __FUNCTION__, pyobj_ret); PyErr_Print(); } else { Py_DECREF(pyobj_ret); ret = 0; } LIBVIRT_RELEASE_THREAD_STATE; return ret; } static int libvirt_virConnectDomainEventIOErrorCallback(virConnectPtr conn ATTRIBUTE_UNUSED, virDomainPtr dom, const char *srcPath, const char *devAlias, int action, void *opaque) { PyObject *pyobj_cbData = (PyObject*)opaque; PyObject *pyobj_dom; PyObject *pyobj_ret; PyObject *pyobj_conn; PyObject *dictKey; int ret = -1; LIBVIRT_ENSURE_THREAD_STATE; /* Create a python instance of this virDomainPtr */ virDomainRef(dom); pyobj_dom = libvirt_virDomainPtrWrap(dom); Py_INCREF(pyobj_cbData); dictKey = libvirt_constcharPtrWrap("conn"); pyobj_conn = PyDict_GetItem(pyobj_cbData, dictKey); Py_DECREF(dictKey); /* Call the Callback Dispatcher */ pyobj_ret = PyObject_CallMethod(pyobj_conn, (char*)"_dispatchDomainEventIOErrorCallback", (char*)"OssiO", pyobj_dom, srcPath, devAlias, action, pyobj_cbData); Py_DECREF(pyobj_cbData); Py_DECREF(pyobj_dom); if (!pyobj_ret) { DEBUG("%s - ret:%p\n", __FUNCTION__, pyobj_ret); PyErr_Print(); } else { Py_DECREF(pyobj_ret); ret = 0; } LIBVIRT_RELEASE_THREAD_STATE; return ret; } static int libvirt_virConnectDomainEventIOErrorReasonCallback(virConnectPtr conn ATTRIBUTE_UNUSED, virDomainPtr dom, const char *srcPath, const char *devAlias, int action, const char *reason, void *opaque) { PyObject *pyobj_cbData = (PyObject*)opaque; PyObject *pyobj_dom; PyObject *pyobj_ret; PyObject *pyobj_conn; PyObject *dictKey; int ret = -1; LIBVIRT_ENSURE_THREAD_STATE; /* Create a python instance of this virDomainPtr */ virDomainRef(dom); pyobj_dom = libvirt_virDomainPtrWrap(dom); Py_INCREF(pyobj_cbData); dictKey = libvirt_constcharPtrWrap("conn"); pyobj_conn = PyDict_GetItem(pyobj_cbData, dictKey); Py_DECREF(dictKey); /* Call the Callback Dispatcher */ pyobj_ret = PyObject_CallMethod(pyobj_conn, (char*)"_dispatchDomainEventIOErrorReasonCallback", (char*)"OssisO", pyobj_dom, srcPath, devAlias, action, reason, pyobj_cbData); Py_DECREF(pyobj_cbData); Py_DECREF(pyobj_dom); if (!pyobj_ret) { DEBUG("%s - ret:%p\n", __FUNCTION__, pyobj_ret); PyErr_Print(); } else { Py_DECREF(pyobj_ret); ret = 0; } LIBVIRT_RELEASE_THREAD_STATE; return ret; } static int libvirt_virConnectDomainEventGraphicsCallback(virConnectPtr conn ATTRIBUTE_UNUSED, virDomainPtr dom, int phase, virDomainEventGraphicsAddressPtr local, virDomainEventGraphicsAddressPtr remote, const char *authScheme, virDomainEventGraphicsSubjectPtr subject, void *opaque) { PyObject *pyobj_cbData = (PyObject*)opaque; PyObject *pyobj_dom; PyObject *pyobj_ret; PyObject *pyobj_conn; PyObject *dictKey; PyObject *pyobj_local; PyObject *pyobj_remote; PyObject *pyobj_subject; int ret = -1; size_t i; LIBVIRT_ENSURE_THREAD_STATE; /* Create a python instance of this virDomainPtr */ virDomainRef(dom); pyobj_dom = libvirt_virDomainPtrWrap(dom); Py_INCREF(pyobj_cbData); dictKey = libvirt_constcharPtrWrap("conn"); pyobj_conn = PyDict_GetItem(pyobj_cbData, dictKey); Py_DECREF(dictKey); pyobj_local = PyDict_New(); PyDict_SetItem(pyobj_local, libvirt_constcharPtrWrap("family"), libvirt_intWrap(local->family)); PyDict_SetItem(pyobj_local, libvirt_constcharPtrWrap("node"), libvirt_constcharPtrWrap(local->node)); PyDict_SetItem(pyobj_local, libvirt_constcharPtrWrap("service"), libvirt_constcharPtrWrap(local->service)); pyobj_remote = PyDict_New(); PyDict_SetItem(pyobj_remote, libvirt_constcharPtrWrap("family"), libvirt_intWrap(remote->family)); PyDict_SetItem(pyobj_remote, libvirt_constcharPtrWrap("node"), libvirt_constcharPtrWrap(remote->node)); PyDict_SetItem(pyobj_remote, libvirt_constcharPtrWrap("service"), libvirt_constcharPtrWrap(remote->service)); pyobj_subject = PyList_New(subject->nidentity); for (i = 0; i < subject->nidentity; i++) { PyObject *pair = PyTuple_New(2); PyTuple_SetItem(pair, 0, libvirt_constcharPtrWrap(subject->identities[i].type)); PyTuple_SetItem(pair, 1, libvirt_constcharPtrWrap(subject->identities[i].name)); PyList_SetItem(pyobj_subject, i, pair); } /* Call the Callback Dispatcher */ pyobj_ret = PyObject_CallMethod(pyobj_conn, (char*)"_dispatchDomainEventGraphicsCallback", (char*)"OiOOsOO", pyobj_dom, phase, pyobj_local, pyobj_remote, authScheme, pyobj_subject, pyobj_cbData); Py_DECREF(pyobj_cbData); Py_DECREF(pyobj_dom); if (!pyobj_ret) { DEBUG("%s - ret:%p\n", __FUNCTION__, pyobj_ret); PyErr_Print(); } else { Py_DECREF(pyobj_ret); ret = 0; } LIBVIRT_RELEASE_THREAD_STATE; return ret; } static int libvirt_virConnectDomainEventBlockJobCallback(virConnectPtr conn ATTRIBUTE_UNUSED, virDomainPtr dom, const char *path, int type, int status, void *opaque) { PyObject *pyobj_cbData = (PyObject*)opaque; PyObject *pyobj_dom; PyObject *pyobj_ret; PyObject *pyobj_conn; PyObject *dictKey; int ret = -1; LIBVIRT_ENSURE_THREAD_STATE; /* Create a python instance of this virDomainPtr */ virDomainRef(dom); pyobj_dom = libvirt_virDomainPtrWrap(dom); Py_INCREF(pyobj_cbData); dictKey = libvirt_constcharPtrWrap("conn"); pyobj_conn = PyDict_GetItem(pyobj_cbData, dictKey); Py_DECREF(dictKey); /* Call the Callback Dispatcher */ pyobj_ret = PyObject_CallMethod(pyobj_conn, (char*)"_dispatchDomainEventBlockPullCallback", (char*)"OsiiO", pyobj_dom, path, type, status, pyobj_cbData); Py_DECREF(pyobj_cbData); Py_DECREF(pyobj_dom); if (!pyobj_ret) { #if DEBUG_ERROR printf("%s - ret:%p\n", __FUNCTION__, pyobj_ret); #endif PyErr_Print(); } else { Py_DECREF(pyobj_ret); ret = 0; } LIBVIRT_RELEASE_THREAD_STATE; return ret; } static int libvirt_virConnectDomainEventDiskChangeCallback(virConnectPtr conn ATTRIBUTE_UNUSED, virDomainPtr dom, const char *oldSrcPath, const char *newSrcPath, const char *devAlias, int reason, void *opaque) { PyObject *pyobj_cbData = (PyObject*)opaque; PyObject *pyobj_dom; PyObject *pyobj_ret; PyObject *pyobj_conn; PyObject *dictKey; int ret = -1; LIBVIRT_ENSURE_THREAD_STATE; /* Create a python instance of this virDomainPtr */ virDomainRef(dom); pyobj_dom = libvirt_virDomainPtrWrap(dom); Py_INCREF(pyobj_cbData); dictKey = libvirt_constcharPtrWrap("conn"); pyobj_conn = PyDict_GetItem(pyobj_cbData, dictKey); Py_DECREF(dictKey); /* Call the Callback Dispatcher */ pyobj_ret = PyObject_CallMethod(pyobj_conn, (char*)"_dispatchDomainEventDiskChangeCallback", (char*)"OsssiO", pyobj_dom, oldSrcPath, newSrcPath, devAlias, reason, pyobj_cbData); Py_DECREF(pyobj_cbData); Py_DECREF(pyobj_dom); if (!pyobj_ret) { DEBUG("%s - ret:%p\n", __FUNCTION__, pyobj_ret); PyErr_Print(); } else { Py_DECREF(pyobj_ret); ret = 0; } LIBVIRT_RELEASE_THREAD_STATE; return ret; } static int libvirt_virConnectDomainEventTrayChangeCallback(virConnectPtr conn ATTRIBUTE_UNUSED, virDomainPtr dom, const char *devAlias, int reason, void *opaque) { PyObject *pyobj_cbData = (PyObject*)opaque; PyObject *pyobj_dom; PyObject *pyobj_ret; PyObject *pyobj_conn; PyObject *dictKey; int ret = -1; LIBVIRT_ENSURE_THREAD_STATE; /* Create a python instance of this virDomainPtr */ virDomainRef(dom); pyobj_dom = libvirt_virDomainPtrWrap(dom); Py_INCREF(pyobj_cbData); dictKey = libvirt_constcharPtrWrap("conn"); pyobj_conn = PyDict_GetItem(pyobj_cbData, dictKey); Py_DECREF(dictKey); /* Call the Callback Dispatcher */ pyobj_ret = PyObject_CallMethod(pyobj_conn, (char*)"_dispatchDomainEventTrayChangeCallback", (char*)"OsiO", pyobj_dom, devAlias, reason, pyobj_cbData); Py_DECREF(pyobj_cbData); Py_DECREF(pyobj_dom); if (!pyobj_ret) { DEBUG("%s - ret:%p\n", __FUNCTION__, pyobj_ret); PyErr_Print(); } else { Py_DECREF(pyobj_ret); ret = 0; } LIBVIRT_RELEASE_THREAD_STATE; return ret; } static int libvirt_virConnectDomainEventPMWakeupCallback(virConnectPtr conn ATTRIBUTE_UNUSED, virDomainPtr dom, int reason, void *opaque) { PyObject *pyobj_cbData = (PyObject*)opaque; PyObject *pyobj_dom; PyObject *pyobj_ret; PyObject *pyobj_conn; PyObject *dictKey; int ret = -1; LIBVIRT_ENSURE_THREAD_STATE; /* Create a python instance of this virDomainPtr */ virDomainRef(dom); pyobj_dom = libvirt_virDomainPtrWrap(dom); Py_INCREF(pyobj_cbData); dictKey = libvirt_constcharPtrWrap("conn"); pyobj_conn = PyDict_GetItem(pyobj_cbData, dictKey); Py_DECREF(dictKey); /* Call the Callback Dispatcher */ pyobj_ret = PyObject_CallMethod(pyobj_conn, (char*)"_dispatchDomainEventPMWakeupCallback", (char*)"OiO", pyobj_dom, reason, pyobj_cbData); Py_DECREF(pyobj_cbData); Py_DECREF(pyobj_dom); if (!pyobj_ret) { DEBUG("%s - ret:%p\n", __FUNCTION__, pyobj_ret); PyErr_Print(); } else { Py_DECREF(pyobj_ret); ret = 0; } LIBVIRT_RELEASE_THREAD_STATE; return ret; } static int libvirt_virConnectDomainEventPMSuspendCallback(virConnectPtr conn ATTRIBUTE_UNUSED, virDomainPtr dom, int reason, void *opaque) { PyObject *pyobj_cbData = (PyObject*)opaque; PyObject *pyobj_dom; PyObject *pyobj_ret; PyObject *pyobj_conn; PyObject *dictKey; int ret = -1; LIBVIRT_ENSURE_THREAD_STATE; /* Create a python instance of this virDomainPtr */ virDomainRef(dom); pyobj_dom = libvirt_virDomainPtrWrap(dom); Py_INCREF(pyobj_cbData); dictKey = libvirt_constcharPtrWrap("conn"); pyobj_conn = PyDict_GetItem(pyobj_cbData, dictKey); Py_DECREF(dictKey); /* Call the Callback Dispatcher */ pyobj_ret = PyObject_CallMethod(pyobj_conn, (char*)"_dispatchDomainEventPMSuspendCallback", (char*)"OiO", pyobj_dom, reason, pyobj_cbData); Py_DECREF(pyobj_cbData); Py_DECREF(pyobj_dom); if (!pyobj_ret) { DEBUG("%s - ret:%p\n", __FUNCTION__, pyobj_ret); PyErr_Print(); } else { Py_DECREF(pyobj_ret); ret = 0; } LIBVIRT_RELEASE_THREAD_STATE; return ret; } #if LIBVIR_CHECK_VERSION(0, 10, 0) static int libvirt_virConnectDomainEventBalloonChangeCallback(virConnectPtr conn ATTRIBUTE_UNUSED, virDomainPtr dom, unsigned long long actual, void *opaque) { PyObject *pyobj_cbData = (PyObject*)opaque; PyObject *pyobj_dom; PyObject *pyobj_ret; PyObject *pyobj_conn; PyObject *dictKey; int ret = -1; LIBVIRT_ENSURE_THREAD_STATE; /* Create a python instance of this virDomainPtr */ virDomainRef(dom); pyobj_dom = libvirt_virDomainPtrWrap(dom); Py_INCREF(pyobj_cbData); dictKey = libvirt_constcharPtrWrap("conn"); pyobj_conn = PyDict_GetItem(pyobj_cbData, dictKey); Py_DECREF(dictKey); /* Call the Callback Dispatcher */ pyobj_ret = PyObject_CallMethod(pyobj_conn, (char*)"_dispatchDomainEventBalloonChangeCallback", (char*)"OLO", pyobj_dom, (PY_LONG_LONG)actual, pyobj_cbData); Py_DECREF(pyobj_cbData); Py_DECREF(pyobj_dom); if (!pyobj_ret) { DEBUG("%s - ret:%p\n", __FUNCTION__, pyobj_ret); PyErr_Print(); } else { Py_DECREF(pyobj_ret); ret = 0; } LIBVIRT_RELEASE_THREAD_STATE; return ret; } #endif /* LIBVIR_CHECK_VERSION(0, 10, 0) */ #if LIBVIR_CHECK_VERSION(1, 0, 0) static int libvirt_virConnectDomainEventPMSuspendDiskCallback(virConnectPtr conn ATTRIBUTE_UNUSED, virDomainPtr dom, int reason, void *opaque) { PyObject *pyobj_cbData = (PyObject*)opaque; PyObject *pyobj_dom; PyObject *pyobj_ret; PyObject *pyobj_conn; PyObject *dictKey; int ret = -1; LIBVIRT_ENSURE_THREAD_STATE; /* Create a python instance of this virDomainPtr */ virDomainRef(dom); pyobj_dom = libvirt_virDomainPtrWrap(dom); Py_INCREF(pyobj_cbData); dictKey = libvirt_constcharPtrWrap("conn"); pyobj_conn = PyDict_GetItem(pyobj_cbData, dictKey); Py_DECREF(dictKey); /* Call the Callback Dispatcher */ pyobj_ret = PyObject_CallMethod(pyobj_conn, (char*)"_dispatchDomainEventPMSuspendDiskCallback", (char*)"OiO", pyobj_dom, reason, pyobj_cbData); Py_DECREF(pyobj_cbData); Py_DECREF(pyobj_dom); if (!pyobj_ret) { DEBUG("%s - ret:%p\n", __FUNCTION__, pyobj_ret); PyErr_Print(); } else { Py_DECREF(pyobj_ret); ret = 0; } LIBVIRT_RELEASE_THREAD_STATE; return ret; } #endif /* LIBVIR_CHECK_VERSION(1, 0, 0) */ #if LIBVIR_CHECK_VERSION(1, 1, 1) static int libvirt_virConnectDomainEventDeviceRemovedCallback(virConnectPtr conn ATTRIBUTE_UNUSED, virDomainPtr dom, const char *devAlias, void *opaque) { PyObject *pyobj_cbData = (PyObject*)opaque; PyObject *pyobj_dom; PyObject *pyobj_ret; PyObject *pyobj_conn; PyObject *dictKey; int ret = -1; LIBVIRT_ENSURE_THREAD_STATE; /* Create a python instance of this virDomainPtr */ virDomainRef(dom); pyobj_dom = libvirt_virDomainPtrWrap(dom); Py_INCREF(pyobj_cbData); dictKey = libvirt_constcharPtrWrap("conn"); pyobj_conn = PyDict_GetItem(pyobj_cbData, dictKey); Py_DECREF(dictKey); /* Call the Callback Dispatcher */ pyobj_ret = PyObject_CallMethod(pyobj_conn, (char*)"_dispatchDomainEventDeviceRemovedCallback", (char*)"OsO", pyobj_dom, devAlias, pyobj_cbData); Py_DECREF(pyobj_cbData); Py_DECREF(pyobj_dom); if (!pyobj_ret) { DEBUG("%s - ret:%p\n", __FUNCTION__, pyobj_ret); PyErr_Print(); } else { Py_DECREF(pyobj_ret); ret = 0; } LIBVIRT_RELEASE_THREAD_STATE; return ret; } #endif /* LIBVIR_CHECK_VERSION(1, 1, 1) */ static PyObject * libvirt_virConnectDomainEventRegisterAny(ATTRIBUTE_UNUSED PyObject * self, PyObject * args) { PyObject *py_retval; /* return value */ PyObject *pyobj_conn; /* virConnectPtr */ PyObject *pyobj_dom; PyObject *pyobj_cbData; /* hash of callback data */ int eventID; virConnectPtr conn; int ret = 0; virConnectDomainEventGenericCallback cb = NULL; virDomainPtr dom; if (!PyArg_ParseTuple (args, (char *) "OOiO:virConnectDomainEventRegisterAny", &pyobj_conn, &pyobj_dom, &eventID, &pyobj_cbData)) { DEBUG("%s failed parsing tuple\n", __FUNCTION__); return VIR_PY_INT_FAIL; } DEBUG("libvirt_virConnectDomainEventRegister(%p %p %d %p) called\n", pyobj_conn, pyobj_dom, eventID, pyobj_cbData); conn = PyvirConnect_Get(pyobj_conn); if (pyobj_dom == Py_None) dom = NULL; else dom = PyvirDomain_Get(pyobj_dom); switch ((virDomainEventID) eventID) { case VIR_DOMAIN_EVENT_ID_LIFECYCLE: cb = VIR_DOMAIN_EVENT_CALLBACK(libvirt_virConnectDomainEventLifecycleCallback); break; case VIR_DOMAIN_EVENT_ID_REBOOT: cb = VIR_DOMAIN_EVENT_CALLBACK(libvirt_virConnectDomainEventGenericCallback); break; case VIR_DOMAIN_EVENT_ID_RTC_CHANGE: cb = VIR_DOMAIN_EVENT_CALLBACK(libvirt_virConnectDomainEventRTCChangeCallback); break; case VIR_DOMAIN_EVENT_ID_WATCHDOG: cb = VIR_DOMAIN_EVENT_CALLBACK(libvirt_virConnectDomainEventWatchdogCallback); break; case VIR_DOMAIN_EVENT_ID_IO_ERROR: cb = VIR_DOMAIN_EVENT_CALLBACK(libvirt_virConnectDomainEventIOErrorCallback); break; case VIR_DOMAIN_EVENT_ID_IO_ERROR_REASON: cb = VIR_DOMAIN_EVENT_CALLBACK(libvirt_virConnectDomainEventIOErrorReasonCallback); break; case VIR_DOMAIN_EVENT_ID_GRAPHICS: cb = VIR_DOMAIN_EVENT_CALLBACK(libvirt_virConnectDomainEventGraphicsCallback); break; case VIR_DOMAIN_EVENT_ID_CONTROL_ERROR: cb = VIR_DOMAIN_EVENT_CALLBACK(libvirt_virConnectDomainEventGenericCallback); break; case VIR_DOMAIN_EVENT_ID_BLOCK_JOB: cb = VIR_DOMAIN_EVENT_CALLBACK(libvirt_virConnectDomainEventBlockJobCallback); break; case VIR_DOMAIN_EVENT_ID_DISK_CHANGE: cb = VIR_DOMAIN_EVENT_CALLBACK(libvirt_virConnectDomainEventDiskChangeCallback); break; case VIR_DOMAIN_EVENT_ID_TRAY_CHANGE: cb = VIR_DOMAIN_EVENT_CALLBACK(libvirt_virConnectDomainEventTrayChangeCallback); break; case VIR_DOMAIN_EVENT_ID_PMWAKEUP: cb = VIR_DOMAIN_EVENT_CALLBACK(libvirt_virConnectDomainEventPMWakeupCallback); break; case VIR_DOMAIN_EVENT_ID_PMSUSPEND: cb = VIR_DOMAIN_EVENT_CALLBACK(libvirt_virConnectDomainEventPMSuspendCallback); break; #if LIBVIR_CHECK_VERSION(0, 10, 0) case VIR_DOMAIN_EVENT_ID_BALLOON_CHANGE: cb = VIR_DOMAIN_EVENT_CALLBACK(libvirt_virConnectDomainEventBalloonChangeCallback); break; #endif /* LIBVIR_CHECK_VERSION(0, 10, 0) */ #if LIBVIR_CHECK_VERSION(1, 0, 0) case VIR_DOMAIN_EVENT_ID_PMSUSPEND_DISK: cb = VIR_DOMAIN_EVENT_CALLBACK(libvirt_virConnectDomainEventPMSuspendDiskCallback); break; #endif /* LIBVIR_CHECK_VERSION(1, 0, 0) */ #if LIBVIR_CHECK_VERSION(1, 1, 1) case VIR_DOMAIN_EVENT_ID_DEVICE_REMOVED: cb = VIR_DOMAIN_EVENT_CALLBACK(libvirt_virConnectDomainEventDeviceRemovedCallback); break; #endif /* LIBVIR_CHECK_VERSION(1, 1, 1) */ case VIR_DOMAIN_EVENT_ID_LAST: break; } if (!cb) { return VIR_PY_INT_FAIL; } Py_INCREF(pyobj_cbData); LIBVIRT_BEGIN_ALLOW_THREADS; ret = virConnectDomainEventRegisterAny(conn, dom, eventID, cb, pyobj_cbData, libvirt_virConnectDomainEventFreeFunc); LIBVIRT_END_ALLOW_THREADS; if (ret < 0) { Py_DECREF(pyobj_cbData); } py_retval = libvirt_intWrap(ret); return py_retval; } static PyObject * libvirt_virConnectDomainEventDeregisterAny(ATTRIBUTE_UNUSED PyObject * self, PyObject * args) { PyObject *py_retval; PyObject *pyobj_conn; int callbackID; virConnectPtr conn; int ret = 0; if (!PyArg_ParseTuple (args, (char *) "Oi:virConnectDomainEventDeregister", &pyobj_conn, &callbackID)) return NULL; DEBUG("libvirt_virConnectDomainEventDeregister(%p) called\n", pyobj_conn); conn = (virConnectPtr) PyvirConnect_Get(pyobj_conn); LIBVIRT_BEGIN_ALLOW_THREADS; ret = virConnectDomainEventDeregisterAny(conn, callbackID); LIBVIRT_END_ALLOW_THREADS; py_retval = libvirt_intWrap(ret); return py_retval; } #if LIBVIR_CHECK_VERSION(1, 2, 1) static void libvirt_virConnectNetworkEventFreeFunc(void *opaque) { PyObject *pyobj_conn = (PyObject*)opaque; LIBVIRT_ENSURE_THREAD_STATE; Py_DECREF(pyobj_conn); LIBVIRT_RELEASE_THREAD_STATE; } static int libvirt_virConnectNetworkEventLifecycleCallback(virConnectPtr conn ATTRIBUTE_UNUSED, virNetworkPtr net, int event, int detail, void *opaque) { PyObject *pyobj_cbData = (PyObject*)opaque; PyObject *pyobj_net; PyObject *pyobj_ret; PyObject *pyobj_conn; PyObject *dictKey; int ret = -1; LIBVIRT_ENSURE_THREAD_STATE; dictKey = libvirt_constcharPtrWrap("conn"); if (!dictKey) return ret; pyobj_conn = PyDict_GetItem(pyobj_cbData, dictKey); Py_DECREF(dictKey); /* Create a python instance of this virNetworkPtr */ virNetworkRef(net); pyobj_net = libvirt_virNetworkPtrWrap(net); Py_INCREF(pyobj_cbData); /* Call the Callback Dispatcher */ pyobj_ret = PyObject_CallMethod(pyobj_conn, (char*)"_dispatchNetworkEventLifecycleCallback", (char*)"OiiO", pyobj_net, event, detail, pyobj_cbData); Py_DECREF(pyobj_cbData); Py_DECREF(pyobj_net); if (!pyobj_ret) { DEBUG("%s - ret:%p\n", __FUNCTION__, pyobj_ret); PyErr_Print(); } else { Py_DECREF(pyobj_ret); ret = 0; } LIBVIRT_RELEASE_THREAD_STATE; return ret; } static PyObject * libvirt_virConnectNetworkEventRegisterAny(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { PyObject *py_retval; /* return value */ PyObject *pyobj_conn; /* virConnectPtr */ PyObject *pyobj_net; PyObject *pyobj_cbData; /* hash of callback data */ int eventID; virConnectPtr conn; int ret = 0; virConnectNetworkEventGenericCallback cb = NULL; virNetworkPtr net; if (!PyArg_ParseTuple (args, (char *) "OOiO:virConnectNetworkEventRegisterAny", &pyobj_conn, &pyobj_net, &eventID, &pyobj_cbData)) { DEBUG("%s failed parsing tuple\n", __FUNCTION__); return VIR_PY_INT_FAIL; } DEBUG("libvirt_virConnectNetworkEventRegister(%p %p %d %p) called\n", pyobj_conn, pyobj_net, eventID, pyobj_cbData); conn = PyvirConnect_Get(pyobj_conn); if (pyobj_net == Py_None) net = NULL; else net = PyvirNetwork_Get(pyobj_net); switch ((virNetworkEventID) eventID) { case VIR_NETWORK_EVENT_ID_LIFECYCLE: cb = VIR_NETWORK_EVENT_CALLBACK(libvirt_virConnectNetworkEventLifecycleCallback); break; case VIR_NETWORK_EVENT_ID_LAST: break; } if (!cb) { return VIR_PY_INT_FAIL; } Py_INCREF(pyobj_cbData); LIBVIRT_BEGIN_ALLOW_THREADS; ret = virConnectNetworkEventRegisterAny(conn, net, eventID, cb, pyobj_cbData, libvirt_virConnectNetworkEventFreeFunc); LIBVIRT_END_ALLOW_THREADS; if (ret < 0) { Py_DECREF(pyobj_cbData); } py_retval = libvirt_intWrap(ret); return py_retval; } static PyObject *libvirt_virConnectNetworkEventDeregisterAny(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { PyObject *py_retval; PyObject *pyobj_conn; int callbackID; virConnectPtr conn; int ret = 0; if (!PyArg_ParseTuple (args, (char *) "Oi:virConnectNetworkEventDeregister", &pyobj_conn, &callbackID)) return NULL; DEBUG("libvirt_virConnectNetworkEventDeregister(%p) called\n", pyobj_conn); conn = (virConnectPtr) PyvirConnect_Get(pyobj_conn); LIBVIRT_BEGIN_ALLOW_THREADS; ret = virConnectNetworkEventDeregisterAny(conn, callbackID); LIBVIRT_END_ALLOW_THREADS; py_retval = libvirt_intWrap(ret); return py_retval; } #endif /* LIBVIR_CHECK_VERSION(1, 2, 1)*/ #if LIBVIR_CHECK_VERSION(0, 10, 0) static void libvirt_virConnectCloseCallbackDispatch(virConnectPtr conn ATTRIBUTE_UNUSED, int reason, void *opaque) { PyObject *pyobj_cbData = (PyObject*)opaque; PyObject *pyobj_ret; PyObject *pyobj_conn; PyObject *dictKey; LIBVIRT_ENSURE_THREAD_STATE; Py_INCREF(pyobj_cbData); dictKey = libvirt_constcharPtrWrap("conn"); pyobj_conn = PyDict_GetItem(pyobj_cbData, dictKey); Py_DECREF(dictKey); /* Call the Callback Dispatcher */ pyobj_ret = PyObject_CallMethod(pyobj_conn, (char*)"_dispatchCloseCallback", (char*)"iO", reason, pyobj_cbData); Py_DECREF(pyobj_cbData); if (!pyobj_ret) { DEBUG("%s - ret:%p\n", __FUNCTION__, pyobj_ret); PyErr_Print(); } else { Py_DECREF(pyobj_ret); } LIBVIRT_RELEASE_THREAD_STATE; } static PyObject * libvirt_virConnectRegisterCloseCallback(ATTRIBUTE_UNUSED PyObject * self, PyObject * args) { PyObject *py_retval; /* return value */ PyObject *pyobj_conn; /* virConnectPtr */ PyObject *pyobj_cbData; /* hash of callback data */ virConnectPtr conn; int ret = 0; if (!PyArg_ParseTuple (args, (char *) "OO:virConnectRegisterCloseCallback", &pyobj_conn, &pyobj_cbData)) { DEBUG("%s failed parsing tuple\n", __FUNCTION__); return VIR_PY_INT_FAIL; } DEBUG("libvirt_virConnectRegisterCloseCallback(%p %p) called\n", pyobj_conn, pyobj_cbData); conn = PyvirConnect_Get(pyobj_conn); Py_INCREF(pyobj_cbData); LIBVIRT_BEGIN_ALLOW_THREADS; ret = virConnectRegisterCloseCallback(conn, libvirt_virConnectCloseCallbackDispatch, pyobj_cbData, libvirt_virConnectDomainEventFreeFunc); LIBVIRT_END_ALLOW_THREADS; if (ret < 0) { Py_DECREF(pyobj_cbData); } py_retval = libvirt_intWrap(ret); return py_retval; } static PyObject * libvirt_virConnectUnregisterCloseCallback(ATTRIBUTE_UNUSED PyObject * self, PyObject * args) { PyObject *py_retval; PyObject *pyobj_conn; virConnectPtr conn; int ret = 0; if (!PyArg_ParseTuple (args, (char *) "O:virConnectDomainEventUnregister", &pyobj_conn)) return NULL; DEBUG("libvirt_virConnectDomainEventUnregister(%p) called\n", pyobj_conn); conn = PyvirConnect_Get(pyobj_conn); LIBVIRT_BEGIN_ALLOW_THREADS; ret = virConnectUnregisterCloseCallback(conn, libvirt_virConnectCloseCallbackDispatch); LIBVIRT_END_ALLOW_THREADS; py_retval = libvirt_intWrap(ret); return py_retval; } #endif /* LIBVIR_CHECK_VERSION(0, 10, 0) */ static void libvirt_virStreamEventFreeFunc(void *opaque) { PyObject *pyobj_stream = (PyObject*)opaque; LIBVIRT_ENSURE_THREAD_STATE; Py_DECREF(pyobj_stream); LIBVIRT_RELEASE_THREAD_STATE; } static void libvirt_virStreamEventCallback(virStreamPtr st ATTRIBUTE_UNUSED, int events, void *opaque) { PyObject *pyobj_cbData = (PyObject *)opaque; PyObject *pyobj_stream; PyObject *pyobj_ret; PyObject *dictKey; LIBVIRT_ENSURE_THREAD_STATE; Py_INCREF(pyobj_cbData); dictKey = libvirt_constcharPtrWrap("stream"); pyobj_stream = PyDict_GetItem(pyobj_cbData, dictKey); Py_DECREF(dictKey); /* Call the pure python dispatcher */ pyobj_ret = PyObject_CallMethod(pyobj_stream, (char *)"_dispatchStreamEventCallback", (char *)"iO", events, pyobj_cbData); Py_DECREF(pyobj_cbData); if (!pyobj_ret) { DEBUG("%s - ret:%p\n", __FUNCTION__, pyobj_ret); PyErr_Print(); } else { Py_DECREF(pyobj_ret); } LIBVIRT_RELEASE_THREAD_STATE; } static PyObject * libvirt_virStreamEventAddCallback(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { PyObject *py_retval; PyObject *pyobj_stream; PyObject *pyobj_cbData; virStreamPtr stream; virStreamEventCallback cb = libvirt_virStreamEventCallback; int ret; int events; if (!PyArg_ParseTuple(args, (char *) "OiO:virStreamEventAddCallback", &pyobj_stream, &events, &pyobj_cbData)) { DEBUG("%s failed to parse tuple\n", __FUNCTION__); return VIR_PY_INT_FAIL; } DEBUG("libvirt_virStreamEventAddCallback(%p, %d, %p) called\n", pyobj_stream, events, pyobj_cbData); stream = PyvirStream_Get(pyobj_stream); Py_INCREF(pyobj_cbData); LIBVIRT_BEGIN_ALLOW_THREADS; ret = virStreamEventAddCallback(stream, events, cb, pyobj_cbData, libvirt_virStreamEventFreeFunc); LIBVIRT_END_ALLOW_THREADS; if (ret < 0) { Py_DECREF(pyobj_cbData); } py_retval = libvirt_intWrap(ret); return py_retval; } static PyObject * libvirt_virStreamRecv(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { PyObject *pyobj_stream; PyObject *rv; virStreamPtr stream; char *buf = NULL; int ret; int nbytes; if (!PyArg_ParseTuple(args, (char *) "Oi:virStreamRecv", &pyobj_stream, &nbytes)) { DEBUG("%s failed to parse tuple\n", __FUNCTION__); return VIR_PY_NONE; } stream = PyvirStream_Get(pyobj_stream); if (VIR_ALLOC_N(buf, nbytes+1 > 0 ? nbytes+1 : 1) < 0) return VIR_PY_NONE; LIBVIRT_BEGIN_ALLOW_THREADS; ret = virStreamRecv(stream, buf, nbytes); LIBVIRT_END_ALLOW_THREADS; buf[ret > -1 ? ret : 0] = '\0'; DEBUG("StreamRecv ret=%d strlen=%d\n", ret, (int) strlen(buf)); if (ret == -2) return libvirt_intWrap(ret); if (ret < 0) return VIR_PY_NONE; rv = libvirt_charPtrSizeWrap((char *) buf, (Py_ssize_t) ret); VIR_FREE(buf); return rv; } static PyObject * libvirt_virStreamSend(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { PyObject *py_retval; PyObject *pyobj_stream; PyObject *pyobj_data; virStreamPtr stream; char *data; Py_ssize_t datalen; int ret; if (!PyArg_ParseTuple(args, (char *) "OO:virStreamRecv", &pyobj_stream, &pyobj_data)) { DEBUG("%s failed to parse tuple\n", __FUNCTION__); return VIR_PY_INT_FAIL; } stream = PyvirStream_Get(pyobj_stream); libvirt_charPtrSizeUnwrap(pyobj_data, &data, &datalen); LIBVIRT_BEGIN_ALLOW_THREADS; ret = virStreamSend(stream, data, datalen); LIBVIRT_END_ALLOW_THREADS; DEBUG("StreamSend ret=%d\n", ret); py_retval = libvirt_intWrap(ret); return py_retval; } static PyObject * libvirt_virDomainSendKey(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { PyObject *py_retval; virDomainPtr domain; PyObject *pyobj_domain; PyObject *pyobj_list; int codeset; int holdtime; unsigned int flags; int ret; size_t i; unsigned int keycodes[VIR_DOMAIN_SEND_KEY_MAX_KEYS]; unsigned int nkeycodes; if (!PyArg_ParseTuple(args, (char *)"OiiOii:virDomainSendKey", &pyobj_domain, &codeset, &holdtime, &pyobj_list, &nkeycodes, &flags)) { DEBUG("%s failed to parse tuple\n", __FUNCTION__); return VIR_PY_INT_FAIL; } domain = (virDomainPtr) PyvirDomain_Get(pyobj_domain); if (!PyList_Check(pyobj_list)) { return VIR_PY_INT_FAIL; } if (nkeycodes != PyList_Size(pyobj_list) || nkeycodes > VIR_DOMAIN_SEND_KEY_MAX_KEYS) { return VIR_PY_INT_FAIL; } for (i = 0; i < nkeycodes; i++) { libvirt_uintUnwrap(PyList_GetItem(pyobj_list, i), &(keycodes[i])); } LIBVIRT_BEGIN_ALLOW_THREADS; ret = virDomainSendKey(domain, codeset, holdtime, keycodes, nkeycodes, flags); LIBVIRT_END_ALLOW_THREADS; DEBUG("virDomainSendKey ret=%d\n", ret); py_retval = libvirt_intWrap(ret); return py_retval; } #if LIBVIR_CHECK_VERSION(1, 0, 3) static PyObject * libvirt_virDomainMigrateGetCompressionCache(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { PyObject *pyobj_domain; virDomainPtr domain; unsigned int flags; unsigned long long cacheSize; int rc; if (!PyArg_ParseTuple(args, (char *) "Oi:virDomainMigrateGetCompressionCache", &pyobj_domain, &flags)) return VIR_PY_NONE; domain = (virDomainPtr) PyvirDomain_Get(pyobj_domain); LIBVIRT_BEGIN_ALLOW_THREADS; rc = virDomainMigrateGetCompressionCache(domain, &cacheSize, flags); LIBVIRT_END_ALLOW_THREADS; if (rc < 0) return VIR_PY_NONE; return libvirt_ulonglongWrap(cacheSize); } #endif /* LIBVIR_CHECK_VERSION(1, 0, 3) */ static PyObject * libvirt_virDomainMigrateGetMaxSpeed(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { PyObject *py_retval; int c_retval; unsigned long bandwidth; virDomainPtr domain; PyObject *pyobj_domain; unsigned int flags = 0; if (!PyArg_ParseTuple(args, (char *)"Oi:virDomainMigrateGetMaxSpeed", &pyobj_domain, &flags)) return NULL; domain = (virDomainPtr) PyvirDomain_Get(pyobj_domain); LIBVIRT_BEGIN_ALLOW_THREADS; c_retval = virDomainMigrateGetMaxSpeed(domain, &bandwidth, flags); LIBVIRT_END_ALLOW_THREADS; if (c_retval < 0) return VIR_PY_INT_FAIL; py_retval = libvirt_ulongWrap(bandwidth); return py_retval; } #if LIBVIR_CHECK_VERSION(1, 1, 0) static PyObject * libvirt_virDomainMigrate3(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { PyObject *pyobj_domain; virDomainPtr domain; PyObject *pyobj_dconn; virConnectPtr dconn; PyObject *dict; unsigned int flags; virTypedParameterPtr params; int nparams; virDomainPtr ddom = NULL; if (!PyArg_ParseTuple(args, (char *) "OOOi:virDomainMigrate3", &pyobj_domain, &pyobj_dconn, &dict, &flags)) return NULL; domain = (virDomainPtr) PyvirDomain_Get(pyobj_domain); dconn = (virConnectPtr) PyvirConnect_Get(pyobj_dconn); if (virPyDictToTypedParams(dict, ¶ms, &nparams, NULL, 0) < 0) return NULL; LIBVIRT_BEGIN_ALLOW_THREADS; ddom = virDomainMigrate3(domain, dconn, params, nparams, flags); LIBVIRT_END_ALLOW_THREADS; virTypedParamsFree(params, nparams); return libvirt_virDomainPtrWrap(ddom); } static PyObject * libvirt_virDomainMigrateToURI3(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { PyObject *pyobj_domain; virDomainPtr domain; char *dconnuri; PyObject *dict; unsigned int flags; virTypedParameterPtr params; int nparams; int ret = -1; if (!PyArg_ParseTuple(args, (char *) "OzOi:virDomainMigrate3", &pyobj_domain, &dconnuri, &dict, &flags)) return NULL; domain = (virDomainPtr) PyvirDomain_Get(pyobj_domain); if (virPyDictToTypedParams(dict, ¶ms, &nparams, NULL, 0) < 0) return NULL; LIBVIRT_BEGIN_ALLOW_THREADS; ret = virDomainMigrateToURI3(domain, dconnuri, params, nparams, flags); LIBVIRT_END_ALLOW_THREADS; virTypedParamsFree(params, nparams); return libvirt_intWrap(ret); } #endif /* LIBVIR_CHECK_VERSION(1, 1, 0) */ static PyObject * libvirt_virDomainBlockPeek(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { PyObject *py_retval = NULL; int c_retval; virDomainPtr domain; PyObject *pyobj_domain; const char *disk; unsigned long long offset; size_t size; char *buf; unsigned int flags; if (!PyArg_ParseTuple(args, (char *)"OzLni:virDomainBlockPeek", &pyobj_domain, &disk, &offset, &size, &flags)) return NULL; domain = (virDomainPtr) PyvirDomain_Get(pyobj_domain); if (VIR_ALLOC_N(buf, size) < 0) return VIR_PY_NONE; LIBVIRT_BEGIN_ALLOW_THREADS; c_retval = virDomainBlockPeek(domain, disk, offset, size, buf, flags); LIBVIRT_END_ALLOW_THREADS; if (c_retval < 0) { py_retval = VIR_PY_NONE; goto cleanup; } py_retval = libvirt_charPtrSizeWrap(buf, size); cleanup: VIR_FREE(buf); return py_retval; } static PyObject * libvirt_virDomainMemoryPeek(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { PyObject *py_retval = NULL; int c_retval; virDomainPtr domain; PyObject *pyobj_domain; unsigned long long start; size_t size; char *buf; unsigned int flags; if (!PyArg_ParseTuple(args, (char *)"OLni:virDomainMemoryPeek", &pyobj_domain, &start, &size, &flags)) return NULL; domain = (virDomainPtr) PyvirDomain_Get(pyobj_domain); if (VIR_ALLOC_N(buf, size) < 0) return VIR_PY_NONE; LIBVIRT_BEGIN_ALLOW_THREADS; c_retval = virDomainMemoryPeek(domain, start, size, buf, flags); LIBVIRT_END_ALLOW_THREADS; if (c_retval < 0) { py_retval = VIR_PY_NONE; goto cleanup; } py_retval = libvirt_charPtrSizeWrap(buf, size); cleanup: VIR_FREE(buf); return py_retval; } #if LIBVIR_CHECK_VERSION(0, 10, 2) static PyObject * libvirt_virNodeSetMemoryParameters(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { virConnectPtr conn; PyObject *pyobj_conn, *info; PyObject *ret = NULL; int i_retval; int nparams = 0; Py_ssize_t size = 0; unsigned int flags; virTypedParameterPtr params, new_params = NULL; if (!PyArg_ParseTuple(args, (char *)"OOi:virNodeSetMemoryParameters", &pyobj_conn, &info, &flags)) return NULL; conn = (virConnectPtr) PyvirConnect_Get(pyobj_conn); if ((size = PyDict_Size(info)) < 0) return NULL; if (size == 0) { PyErr_Format(PyExc_LookupError, "Need non-empty dictionary to set attributes"); return NULL; } LIBVIRT_BEGIN_ALLOW_THREADS; i_retval = virNodeGetMemoryParameters(conn, NULL, &nparams, flags); LIBVIRT_END_ALLOW_THREADS; if (i_retval < 0) return VIR_PY_INT_FAIL; if (nparams == 0) { PyErr_Format(PyExc_LookupError, "no settable attributes"); return NULL; } if (VIR_ALLOC_N(params, nparams) < 0) return PyErr_NoMemory(); LIBVIRT_BEGIN_ALLOW_THREADS; i_retval = virNodeGetMemoryParameters(conn, params, &nparams, flags); LIBVIRT_END_ALLOW_THREADS; if (i_retval < 0) { ret = VIR_PY_INT_FAIL; goto cleanup; } new_params = setPyVirTypedParameter(info, params, nparams); if (!new_params) goto cleanup; LIBVIRT_BEGIN_ALLOW_THREADS; i_retval = virNodeSetMemoryParameters(conn, new_params, size, flags); LIBVIRT_END_ALLOW_THREADS; if (i_retval < 0) { ret = VIR_PY_INT_FAIL; goto cleanup; } ret = VIR_PY_INT_SUCCESS; cleanup: virTypedParamsFree(params, nparams); virTypedParamsFree(new_params, nparams); return ret; } static PyObject * libvirt_virNodeGetMemoryParameters(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { virConnectPtr conn; PyObject *pyobj_conn; PyObject *ret = NULL; int i_retval; int nparams = 0; unsigned int flags; virTypedParameterPtr params; if (!PyArg_ParseTuple(args, (char *)"Oi:virNodeGetMemoryParameters", &pyobj_conn, &flags)) return NULL; conn = (virConnectPtr) PyvirConnect_Get(pyobj_conn); LIBVIRT_BEGIN_ALLOW_THREADS; i_retval = virNodeGetMemoryParameters(conn, NULL, &nparams, flags); LIBVIRT_END_ALLOW_THREADS; if (i_retval < 0) return VIR_PY_NONE; if (!nparams) return PyDict_New(); if (VIR_ALLOC_N(params, nparams) < 0) return PyErr_NoMemory(); LIBVIRT_BEGIN_ALLOW_THREADS; i_retval = virNodeGetMemoryParameters(conn, params, &nparams, flags); LIBVIRT_END_ALLOW_THREADS; if (i_retval < 0) { ret = VIR_PY_NONE; goto cleanup; } ret = getPyVirTypedParameter(params, nparams); cleanup: virTypedParamsFree(params, nparams); return ret; } #endif /* LIBVIR_CHECK_VERSION(0, 10, 2) */ #if LIBVIR_CHECK_VERSION(1, 0, 0) static PyObject * libvirt_virNodeGetCPUMap(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { virConnectPtr conn; PyObject *pyobj_conn; PyObject *ret = NULL; PyObject *pycpumap = NULL; PyObject *pyused = NULL; PyObject *pycpunum = NULL; PyObject *pyonline = NULL; int i_retval; unsigned char *cpumap = NULL; unsigned int online = 0; unsigned int flags; size_t i; if (!PyArg_ParseTuple(args, (char *)"Oi:virNodeGetCPUMap", &pyobj_conn, &flags)) return NULL; conn = (virConnectPtr) PyvirConnect_Get(pyobj_conn); LIBVIRT_BEGIN_ALLOW_THREADS; i_retval = virNodeGetCPUMap(conn, &cpumap, &online, flags); LIBVIRT_END_ALLOW_THREADS; if (i_retval < 0) return VIR_PY_NONE; if ((ret = PyTuple_New(3)) == NULL) goto error; /* 0: number of CPUs */ if ((pycpunum = libvirt_intWrap(i_retval)) == NULL || PyTuple_SetItem(ret, 0, pycpunum) < 0) goto error; /* 1: CPU map */ if ((pycpumap = PyList_New(i_retval)) == NULL) goto error; for (i = 0; i < i_retval; i++) { if ((pyused = PyBool_FromLong(VIR_CPU_USED(cpumap, i))) == NULL) goto error; if (PyList_SetItem(pycpumap, i, pyused) < 0) goto error; } if (PyTuple_SetItem(ret, 1, pycpumap) < 0) goto error; /* 2: number of online CPUs */ if ((pyonline = libvirt_uintWrap(online)) == NULL || PyTuple_SetItem(ret, 2, pyonline) < 0) goto error; cleanup: VIR_FREE(cpumap); return ret; error: Py_XDECREF(ret); Py_XDECREF(pycpumap); Py_XDECREF(pyused); Py_XDECREF(pycpunum); Py_XDECREF(pyonline); ret = NULL; goto cleanup; } #endif /* LIBVIR_CHECK_VERSION(1, 0, 0) */ #if LIBVIR_CHECK_VERSION(1, 1, 1) static PyObject * libvirt_virDomainCreateWithFiles(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { PyObject *py_retval = NULL; int c_retval; virDomainPtr domain; PyObject *pyobj_domain; PyObject *pyobj_files; unsigned int flags; unsigned int nfiles; int *files = NULL; size_t i; if (!PyArg_ParseTuple(args, (char *)"OOi:virDomainCreateWithFiles", &pyobj_domain, &pyobj_files, &flags)) return NULL; domain = (virDomainPtr) PyvirDomain_Get(pyobj_domain); nfiles = PyList_Size(pyobj_files); if (VIR_ALLOC_N(files, nfiles) < 0) return PyErr_NoMemory(); for (i = 0; i < nfiles; i++) { PyObject *pyfd; int fd; pyfd = PyList_GetItem(pyobj_files, i); if (libvirt_intUnwrap(pyfd, &fd) < 0) goto cleanup; files[i] = fd; } LIBVIRT_BEGIN_ALLOW_THREADS; c_retval = virDomainCreateWithFiles(domain, nfiles, files, flags); LIBVIRT_END_ALLOW_THREADS; py_retval = libvirt_intWrap((int) c_retval); cleanup: VIR_FREE(files); return py_retval; } static PyObject * libvirt_virDomainCreateXMLWithFiles(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { PyObject *py_retval = NULL; virDomainPtr c_retval; virConnectPtr conn; PyObject *pyobj_conn; char * xmlDesc; PyObject *pyobj_files; unsigned int flags; unsigned int nfiles; int *files = NULL; size_t i; if (!PyArg_ParseTuple(args, (char *)"OzOi:virDomainCreateXMLWithFiles", &pyobj_conn, &xmlDesc, &pyobj_files, &flags)) return NULL; conn = (virConnectPtr) PyvirConnect_Get(pyobj_conn); nfiles = PyList_Size(pyobj_files); if (VIR_ALLOC_N(files, nfiles) < 0) return PyErr_NoMemory(); for (i = 0; i < nfiles; i++) { PyObject *pyfd; int fd; pyfd = PyList_GetItem(pyobj_files, i); if (libvirt_intUnwrap(pyfd, &fd) < 0) goto cleanup; files[i] = fd; } LIBVIRT_BEGIN_ALLOW_THREADS; c_retval = virDomainCreateXMLWithFiles(conn, xmlDesc, nfiles, files, flags); LIBVIRT_END_ALLOW_THREADS; py_retval = libvirt_virDomainPtrWrap((virDomainPtr) c_retval); cleanup: VIR_FREE(files); return py_retval; } #endif /* LIBVIR_CHECK_VERSION(1, 1, 1) */ /************************************************************************ * * * The registration stuff * * * ************************************************************************/ static PyMethodDef libvirtMethods[] = { #include "build/libvirt-export.c" {(char *) "virGetVersion", libvirt_virGetVersion, METH_VARARGS, NULL}, {(char *) "virConnectGetVersion", libvirt_virConnectGetVersion, METH_VARARGS, NULL}, #if LIBVIR_CHECK_VERSION(1, 1, 3) {(char *) "virConnectGetCPUModelNames", libvirt_virConnectGetCPUModelNames, METH_VARARGS, NULL}, #endif /* LIBVIR_CHECK_VERSION(1, 1, 3) */ {(char *) "virConnectGetLibVersion", libvirt_virConnectGetLibVersion, METH_VARARGS, NULL}, {(char *) "virConnectOpenAuth", libvirt_virConnectOpenAuth, METH_VARARGS, NULL}, {(char *) "virConnectListDomainsID", libvirt_virConnectListDomainsID, METH_VARARGS, NULL}, {(char *) "virConnectListDefinedDomains", libvirt_virConnectListDefinedDomains, METH_VARARGS, NULL}, #if LIBVIR_CHECK_VERSION(0, 9, 13) {(char *) "virConnectListAllDomains", libvirt_virConnectListAllDomains, METH_VARARGS, NULL}, #endif /* LIBVIR_CHECK_VERSION(0, 9, 13) */ {(char *) "virConnectDomainEventRegister", libvirt_virConnectDomainEventRegister, METH_VARARGS, NULL}, {(char *) "virConnectDomainEventDeregister", libvirt_virConnectDomainEventDeregister, METH_VARARGS, NULL}, {(char *) "virConnectDomainEventRegisterAny", libvirt_virConnectDomainEventRegisterAny, METH_VARARGS, NULL}, {(char *) "virConnectDomainEventDeregisterAny", libvirt_virConnectDomainEventDeregisterAny, METH_VARARGS, NULL}, #if LIBVIR_CHECK_VERSION(1, 2, 1) {(char *) "virConnectNetworkEventRegisterAny", libvirt_virConnectNetworkEventRegisterAny, METH_VARARGS, NULL}, {(char *) "virConnectNetworkEventDeregisterAny", libvirt_virConnectNetworkEventDeregisterAny, METH_VARARGS, NULL}, #endif /* LIBVIR_CHECK_VERSION(1, 2, 1) */ #if LIBVIR_CHECK_VERSION(0, 10, 0) {(char *) "virConnectRegisterCloseCallback", libvirt_virConnectRegisterCloseCallback, METH_VARARGS, NULL}, {(char *) "virConnectUnregisterCloseCallback", libvirt_virConnectUnregisterCloseCallback, METH_VARARGS, NULL}, #endif /* LIBVIR_CHECK_VERSION(0, 10, 0) */ {(char *) "virStreamEventAddCallback", libvirt_virStreamEventAddCallback, METH_VARARGS, NULL}, {(char *) "virStreamRecv", libvirt_virStreamRecv, METH_VARARGS, NULL}, {(char *) "virStreamSend", libvirt_virStreamSend, METH_VARARGS, NULL}, {(char *) "virDomainGetInfo", libvirt_virDomainGetInfo, METH_VARARGS, NULL}, {(char *) "virDomainGetState", libvirt_virDomainGetState, METH_VARARGS, NULL}, {(char *) "virDomainGetControlInfo", libvirt_virDomainGetControlInfo, METH_VARARGS, NULL}, {(char *) "virDomainGetBlockInfo", libvirt_virDomainGetBlockInfo, METH_VARARGS, NULL}, {(char *) "virNodeGetInfo", libvirt_virNodeGetInfo, METH_VARARGS, NULL}, {(char *) "virNodeGetSecurityModel", libvirt_virNodeGetSecurityModel, METH_VARARGS, NULL}, {(char *) "virDomainGetSecurityLabel", libvirt_virDomainGetSecurityLabel, METH_VARARGS, NULL}, #if LIBVIR_CHECK_VERSION(0, 10, 0) {(char *) "virDomainGetSecurityLabelList", libvirt_virDomainGetSecurityLabelList, METH_VARARGS, NULL}, #endif /* LIBVIR_CHECK_VERSION(0, 10, 0) */ {(char *) "virNodeGetCPUStats", libvirt_virNodeGetCPUStats, METH_VARARGS, NULL}, {(char *) "virNodeGetMemoryStats", libvirt_virNodeGetMemoryStats, METH_VARARGS, NULL}, {(char *) "virDomainGetUUID", libvirt_virDomainGetUUID, METH_VARARGS, NULL}, {(char *) "virDomainGetUUIDString", libvirt_virDomainGetUUIDString, METH_VARARGS, NULL}, {(char *) "virDomainLookupByUUID", libvirt_virDomainLookupByUUID, METH_VARARGS, NULL}, {(char *) "virRegisterErrorHandler", libvirt_virRegisterErrorHandler, METH_VARARGS, NULL}, {(char *) "virGetLastError", libvirt_virGetLastError, METH_VARARGS, NULL}, {(char *) "virConnGetLastError", libvirt_virConnGetLastError, METH_VARARGS, NULL}, {(char *) "virConnectListNetworks", libvirt_virConnectListNetworks, METH_VARARGS, NULL}, {(char *) "virConnectListDefinedNetworks", libvirt_virConnectListDefinedNetworks, METH_VARARGS, NULL}, #if LIBVIR_CHECK_VERSION(0, 10, 2) {(char *) "virConnectListAllNetworks", libvirt_virConnectListAllNetworks, METH_VARARGS, NULL}, #endif /* LIBVIR_CHECK_VERSION(0, 10, 2) */ {(char *) "virNetworkGetUUID", libvirt_virNetworkGetUUID, METH_VARARGS, NULL}, {(char *) "virNetworkGetUUIDString", libvirt_virNetworkGetUUIDString, METH_VARARGS, NULL}, {(char *) "virNetworkLookupByUUID", libvirt_virNetworkLookupByUUID, METH_VARARGS, NULL}, {(char *) "virDomainGetAutostart", libvirt_virDomainGetAutostart, METH_VARARGS, NULL}, {(char *) "virNetworkGetAutostart", libvirt_virNetworkGetAutostart, METH_VARARGS, NULL}, {(char *) "virDomainBlockStats", libvirt_virDomainBlockStats, METH_VARARGS, NULL}, {(char *) "virDomainBlockStatsFlags", libvirt_virDomainBlockStatsFlags, METH_VARARGS, NULL}, {(char *) "virDomainGetCPUStats", libvirt_virDomainGetCPUStats, METH_VARARGS, NULL}, {(char *) "virDomainInterfaceStats", libvirt_virDomainInterfaceStats, METH_VARARGS, NULL}, {(char *) "virDomainMemoryStats", libvirt_virDomainMemoryStats, METH_VARARGS, NULL}, {(char *) "virNodeGetCellsFreeMemory", libvirt_virNodeGetCellsFreeMemory, METH_VARARGS, NULL}, {(char *) "virDomainGetSchedulerType", libvirt_virDomainGetSchedulerType, METH_VARARGS, NULL}, {(char *) "virDomainGetSchedulerParameters", libvirt_virDomainGetSchedulerParameters, METH_VARARGS, NULL}, {(char *) "virDomainGetSchedulerParametersFlags", libvirt_virDomainGetSchedulerParametersFlags, METH_VARARGS, NULL}, {(char *) "virDomainSetSchedulerParameters", libvirt_virDomainSetSchedulerParameters, METH_VARARGS, NULL}, {(char *) "virDomainSetSchedulerParametersFlags", libvirt_virDomainSetSchedulerParametersFlags, METH_VARARGS, NULL}, {(char *) "virDomainSetBlkioParameters", libvirt_virDomainSetBlkioParameters, METH_VARARGS, NULL}, {(char *) "virDomainGetBlkioParameters", libvirt_virDomainGetBlkioParameters, METH_VARARGS, NULL}, {(char *) "virDomainSetMemoryParameters", libvirt_virDomainSetMemoryParameters, METH_VARARGS, NULL}, {(char *) "virDomainGetMemoryParameters", libvirt_virDomainGetMemoryParameters, METH_VARARGS, NULL}, {(char *) "virDomainSetNumaParameters", libvirt_virDomainSetNumaParameters, METH_VARARGS, NULL}, {(char *) "virDomainGetNumaParameters", libvirt_virDomainGetNumaParameters, METH_VARARGS, NULL}, {(char *) "virDomainSetInterfaceParameters", libvirt_virDomainSetInterfaceParameters, METH_VARARGS, NULL}, {(char *) "virDomainGetInterfaceParameters", libvirt_virDomainGetInterfaceParameters, METH_VARARGS, NULL}, {(char *) "virDomainGetVcpus", libvirt_virDomainGetVcpus, METH_VARARGS, NULL}, {(char *) "virDomainPinVcpu", libvirt_virDomainPinVcpu, METH_VARARGS, NULL}, {(char *) "virDomainPinVcpuFlags", libvirt_virDomainPinVcpuFlags, METH_VARARGS, NULL}, {(char *) "virDomainGetVcpuPinInfo", libvirt_virDomainGetVcpuPinInfo, METH_VARARGS, NULL}, #if LIBVIR_CHECK_VERSION(0, 10, 0) {(char *) "virDomainGetEmulatorPinInfo", libvirt_virDomainGetEmulatorPinInfo, METH_VARARGS, NULL}, {(char *) "virDomainPinEmulator", libvirt_virDomainPinEmulator, METH_VARARGS, NULL}, #endif /* LIBVIR_CHECK_VERSION(0, 10, 0) */ {(char *) "virConnectListStoragePools", libvirt_virConnectListStoragePools, METH_VARARGS, NULL}, {(char *) "virConnectListDefinedStoragePools", libvirt_virConnectListDefinedStoragePools, METH_VARARGS, NULL}, #if LIBVIR_CHECK_VERSION(0, 10, 2) {(char *) "virConnectListAllStoragePools", libvirt_virConnectListAllStoragePools, METH_VARARGS, NULL}, #endif /* LIBVIR_CHECK_VERSION(0, 10, 2) */ {(char *) "virStoragePoolGetAutostart", libvirt_virStoragePoolGetAutostart, METH_VARARGS, NULL}, {(char *) "virStoragePoolListVolumes", libvirt_virStoragePoolListVolumes, METH_VARARGS, NULL}, #if LIBVIR_CHECK_VERSION(0, 10, 2) {(char *) "virStoragePoolListAllVolumes", libvirt_virStoragePoolListAllVolumes, METH_VARARGS, NULL}, #endif /* LIBVIR_CHECK_VERSION(0, 10, 2) */ {(char *) "virStoragePoolGetInfo", libvirt_virStoragePoolGetInfo, METH_VARARGS, NULL}, {(char *) "virStorageVolGetInfo", libvirt_virStorageVolGetInfo, METH_VARARGS, NULL}, {(char *) "virStoragePoolGetUUID", libvirt_virStoragePoolGetUUID, METH_VARARGS, NULL}, {(char *) "virStoragePoolGetUUIDString", libvirt_virStoragePoolGetUUIDString, METH_VARARGS, NULL}, {(char *) "virStoragePoolLookupByUUID", libvirt_virStoragePoolLookupByUUID, METH_VARARGS, NULL}, {(char *) "virEventRegisterImpl", libvirt_virEventRegisterImpl, METH_VARARGS, NULL}, {(char *) "virEventAddHandle", libvirt_virEventAddHandle, METH_VARARGS, NULL}, {(char *) "virEventAddTimeout", libvirt_virEventAddTimeout, METH_VARARGS, NULL}, {(char *) "virEventInvokeHandleCallback", libvirt_virEventInvokeHandleCallback, METH_VARARGS, NULL}, {(char *) "virEventInvokeTimeoutCallback", libvirt_virEventInvokeTimeoutCallback, METH_VARARGS, NULL}, {(char *) "virNodeListDevices", libvirt_virNodeListDevices, METH_VARARGS, NULL}, #if LIBVIR_CHECK_VERSION(0, 10, 2) {(char *) "virConnectListAllNodeDevices", libvirt_virConnectListAllNodeDevices, METH_VARARGS, NULL}, #endif /* LIBVIR_CHECK_VERSION(0, 10, 2) */ {(char *) "virNodeDeviceListCaps", libvirt_virNodeDeviceListCaps, METH_VARARGS, NULL}, {(char *) "virSecretGetUUID", libvirt_virSecretGetUUID, METH_VARARGS, NULL}, {(char *) "virSecretGetUUIDString", libvirt_virSecretGetUUIDString, METH_VARARGS, NULL}, {(char *) "virSecretLookupByUUID", libvirt_virSecretLookupByUUID, METH_VARARGS, NULL}, {(char *) "virConnectListSecrets", libvirt_virConnectListSecrets, METH_VARARGS, NULL}, #if LIBVIR_CHECK_VERSION(0, 10, 2) {(char *) "virConnectListAllSecrets", libvirt_virConnectListAllSecrets, METH_VARARGS, NULL}, #endif /* LIBVIR_CHECK_VERSION(0, 10, 2) */ {(char *) "virSecretGetValue", libvirt_virSecretGetValue, METH_VARARGS, NULL}, {(char *) "virSecretSetValue", libvirt_virSecretSetValue, METH_VARARGS, NULL}, {(char *) "virNWFilterGetUUID", libvirt_virNWFilterGetUUID, METH_VARARGS, NULL}, {(char *) "virNWFilterGetUUIDString", libvirt_virNWFilterGetUUIDString, METH_VARARGS, NULL}, {(char *) "virNWFilterLookupByUUID", libvirt_virNWFilterLookupByUUID, METH_VARARGS, NULL}, {(char *) "virConnectListNWFilters", libvirt_virConnectListNWFilters, METH_VARARGS, NULL}, #if LIBVIR_CHECK_VERSION(0, 10, 2) {(char *) "virConnectListAllNWFilters", libvirt_virConnectListAllNWFilters, METH_VARARGS, NULL}, #endif /* LIBVIR_CHECK_VERSION(0, 10, 2) */ {(char *) "virConnectListInterfaces", libvirt_virConnectListInterfaces, METH_VARARGS, NULL}, {(char *) "virConnectListDefinedInterfaces", libvirt_virConnectListDefinedInterfaces, METH_VARARGS, NULL}, #if LIBVIR_CHECK_VERSION(0, 10, 2) {(char *) "virConnectListAllInterfaces", libvirt_virConnectListAllInterfaces, METH_VARARGS, NULL}, #endif /* LIBVIR_CHECK_VERSION(0, 10, 2) */ {(char *) "virConnectBaselineCPU", libvirt_virConnectBaselineCPU, METH_VARARGS, NULL}, {(char *) "virDomainGetJobInfo", libvirt_virDomainGetJobInfo, METH_VARARGS, NULL}, #if LIBVIR_CHECK_VERSION(1, 0, 3) {(char *) "virDomainGetJobStats", libvirt_virDomainGetJobStats, METH_VARARGS, NULL}, #endif /* LIBVIR_CHECK_VERSION(1, 0, 3) */ {(char *) "virDomainSnapshotListNames", libvirt_virDomainSnapshotListNames, METH_VARARGS, NULL}, #if LIBVIR_CHECK_VERSION(0, 9, 13) {(char *) "virDomainListAllSnapshots", libvirt_virDomainListAllSnapshots, METH_VARARGS, NULL}, #endif /* LIBVIR_CHECK_VERSION(0, 9, 13) */ {(char *) "virDomainSnapshotListChildrenNames", libvirt_virDomainSnapshotListChildrenNames, METH_VARARGS, NULL}, #if LIBVIR_CHECK_VERSION(0, 9, 13) {(char *) "virDomainSnapshotListAllChildren", libvirt_virDomainSnapshotListAllChildren, METH_VARARGS, NULL}, #endif /* LIBVIR_CHECK_VERSION(0, 9, 13) */ {(char *) "virDomainRevertToSnapshot", libvirt_virDomainRevertToSnapshot, METH_VARARGS, NULL}, {(char *) "virDomainGetBlockJobInfo", libvirt_virDomainGetBlockJobInfo, METH_VARARGS, NULL}, {(char *) "virDomainSetBlockIoTune", libvirt_virDomainSetBlockIoTune, METH_VARARGS, NULL}, {(char *) "virDomainGetBlockIoTune", libvirt_virDomainGetBlockIoTune, METH_VARARGS, NULL}, {(char *) "virDomainSendKey", libvirt_virDomainSendKey, METH_VARARGS, NULL}, #if LIBVIR_CHECK_VERSION(1, 0, 3) {(char *) "virDomainMigrateGetCompressionCache", libvirt_virDomainMigrateGetCompressionCache, METH_VARARGS, NULL}, #endif /* LIBVIR_CHECK_VERSION(1, 0, 3) */ {(char *) "virDomainMigrateGetMaxSpeed", libvirt_virDomainMigrateGetMaxSpeed, METH_VARARGS, NULL}, #if LIBVIR_CHECK_VERSION(1, 1, 0) {(char *) "virDomainMigrate3", libvirt_virDomainMigrate3, METH_VARARGS, NULL}, {(char *) "virDomainMigrateToURI3", libvirt_virDomainMigrateToURI3, METH_VARARGS, NULL}, #endif /* LIBVIR_CHECK_VERSION(1, 1, 0) */ {(char *) "virDomainBlockPeek", libvirt_virDomainBlockPeek, METH_VARARGS, NULL}, {(char *) "virDomainMemoryPeek", libvirt_virDomainMemoryPeek, METH_VARARGS, NULL}, {(char *) "virDomainGetDiskErrors", libvirt_virDomainGetDiskErrors, METH_VARARGS, NULL}, #if LIBVIR_CHECK_VERSION(0, 10, 2) {(char *) "virNodeGetMemoryParameters", libvirt_virNodeGetMemoryParameters, METH_VARARGS, NULL}, {(char *) "virNodeSetMemoryParameters", libvirt_virNodeSetMemoryParameters, METH_VARARGS, NULL}, #endif /* LIBVIR_CHECK_VERSION(0, 10, 2) */ #if LIBVIR_CHECK_VERSION(1, 0, 0) {(char *) "virNodeGetCPUMap", libvirt_virNodeGetCPUMap, METH_VARARGS, NULL}, #endif /* LIBVIR_CHECK_VERSION(1, 0, 0) */ #if LIBVIR_CHECK_VERSION(1, 1, 1) {(char *) "virDomainCreateXMLWithFiles", libvirt_virDomainCreateXMLWithFiles, METH_VARARGS, NULL}, {(char *) "virDomainCreateWithFiles", libvirt_virDomainCreateWithFiles, METH_VARARGS, NULL}, #endif /* LIBVIR_CHECK_VERSION(1, 1, 1) */ {NULL, NULL, 0, NULL} }; #if PY_MAJOR_VERSION > 2 static struct PyModuleDef moduledef = { PyModuleDef_HEAD_INIT, # ifndef __CYGWIN__ "libvirtmod", # else "cygvirtmod", # endif NULL, -1, libvirtMethods, NULL, NULL, NULL, NULL }; PyObject * # ifndef __CYGWIN__ PyInit_libvirtmod # else PyInit_cygvirtmod # endif (void) { PyObject *module; if (virInitialize() < 0) return NULL; module = PyModule_Create(&moduledef); return module; } #else /* ! PY_MAJOR_VERSION > 2 */ void # ifndef __CYGWIN__ initlibvirtmod # else initcygvirtmod # endif (void) { if (virInitialize() < 0) return; /* initialize the python extension module */ Py_InitModule((char *) # ifndef __CYGWIN__ "libvirtmod", # else "cygvirtmod", # endif libvirtMethods); } #endif /* ! PY_MAJOR_VERSION > 2 */ libvirt-python-1.2.2/libvirt-override-virStream.py0000664000076400007640000001062012302554455023766 0ustar veillardveillard00000000000000 def __del__(self): try: if self.cb: libvirtmod.virStreamEventRemoveCallback(self._o) except AttributeError: pass if self._o is not None: libvirtmod.virStreamFree(self._o) self._o = None def _dispatchStreamEventCallback(self, events, cbData): """ Dispatches events to python user's stream event callbacks """ cb = cbData["cb"] opaque = cbData["opaque"] cb(self, events, opaque) return 0 def eventAddCallback(self, events, cb, opaque): self.cb = cb cbData = {"stream": self, "cb" : cb, "opaque" : opaque} ret = libvirtmod.virStreamEventAddCallback(self._o, events, cbData) if ret == -1: raise libvirtError ('virStreamEventAddCallback() failed') def recvAll(self, handler, opaque): """Receive the entire data stream, sending the data to the requested data sink. This is simply a convenient alternative to virStreamRecv, for apps that do blocking-I/O. A hypothetical handler function looks like: def handler(stream, # virStream instance buf, # string containing received data opaque): # extra data passed to recvAll as opaque fd = opaque return os.write(fd, buf) """ while True: got = self.recv(1024*64) if got == -2: raise libvirtError("cannot use recvAll with " "nonblocking stream") if len(got) == 0: break try: ret = handler(self, got, opaque) if type(ret) is int and ret < 0: raise RuntimeError("recvAll handler returned %d" % ret) except Exception: e = sys.exc_info()[1] try: self.abort() except: pass raise e def sendAll(self, handler, opaque): """ Send the entire data stream, reading the data from the requested data source. This is simply a convenient alternative to virStreamSend, for apps that do blocking-I/O. A hypothetical handler function looks like: def handler(stream, # virStream instance nbytes, # int amt of data to read opaque): # extra data passed to recvAll as opaque fd = opaque return os.read(fd, nbytes) """ while True: try: got = handler(self, 1024*64, opaque) except: e = sys.exc_info()[1] try: self.abort() except: pass raise e if got == "": break ret = self.send(got) if ret == -2: raise libvirtError("cannot use sendAll with " "nonblocking stream") def recv(self, nbytes): """Reads a series of bytes from the stream. This method may block the calling application for an arbitrary amount of time. Errors are not guaranteed to be reported synchronously with the call, but may instead be delayed until a subsequent call. On success, the received data is returned. On failure, an exception is raised. If the stream is a NONBLOCK stream and the request would block, integer -2 is returned. """ ret = libvirtmod.virStreamRecv(self._o, nbytes) if ret is None: raise libvirtError ('virStreamRecv() failed') return ret def send(self, data): """Write a series of bytes to the stream. This method may block the calling application for an arbitrary amount of time. Once an application has finished sending data it should call virStreamFinish to wait for successful confirmation from the driver, or detect any error This method may not be used if a stream source has been registered Errors are not guaranteed to be reported synchronously with the call, but may instead be delayed until a subsequent call. """ ret = libvirtmod.virStreamSend(self._o, data) if ret == -1: raise libvirtError ('virStreamSend() failed') return ret libvirt-python-1.2.2/setup.py0000775000076400007640000002045312303303267017666 0ustar veillardveillard00000000000000#!/usr/bin/python from distutils.core import setup, Extension, Command from distutils.command.build import build from distutils.command.clean import clean from distutils.command.sdist import sdist from distutils.dir_util import remove_tree from distutils.util import get_platform from distutils.spawn import spawn from distutils.errors import DistutilsExecError import distutils import sys import datetime import os import os.path import re import time MIN_LIBVIRT = "0.9.11" MIN_LIBVIRT_LXC = "1.0.2" # Hack to stop 'pip install' failing with error # about missing 'build' dir. if not os.path.exists("build"): os.mkdir("build") pkgcfg = distutils.spawn.find_executable("pkg-config") if pkgcfg is None: raise Exception("pkg-config binary is required to compile libvirt-python") spawn([pkgcfg, "--print-errors", "--atleast-version=%s" % MIN_LIBVIRT, "libvirt"]) have_libvirt_lxc=True try: spawn([pkgcfg, "--atleast-version=%s" % MIN_LIBVIRT_LXC, "libvirt"]) except DistutilsExecError: have_libvirt_lxc=False def get_pkgconfig_data(args, mod, required=True): """Run pkg-config to and return content associated with it""" f = os.popen("%s %s %s" % (pkgcfg, " ".join(args), mod)) line = f.readline() if line is not None: line = line.strip() if line is None or line == "": if required: raise Exception("Cannot determine '%s' from libvirt pkg-config file" % " ".join(args)) else: return "" return line def get_api_xml_files(): """Check with pkg-config that libvirt is present and extract the API XML file paths we need from it""" libvirt_api = get_pkgconfig_data(["--variable", "libvirt_api"], "libvirt") offset = libvirt_api.index("-api.xml") libvirt_qemu_api = libvirt_api[0:offset] + "-qemu-api.xml" offset = libvirt_api.index("-api.xml") libvirt_lxc_api = libvirt_api[0:offset] + "-lxc-api.xml" return (libvirt_api, libvirt_qemu_api, libvirt_lxc_api) ldflags = get_pkgconfig_data(["--libs-only-L"], "libvirt", False) cflags = get_pkgconfig_data(["--cflags"], "libvirt", False) c_modules = [] py_modules = [] module = Extension('libvirtmod', sources = ['libvirt-override.c', 'build/libvirt.c', 'typewrappers.c', 'libvirt-utils.c'], libraries = [ "virt" ], include_dirs = [ "." ]) if cflags != "": module.extra_compile_args.append(cflags) if ldflags != "": module.extra_link_args.append(ldflags) c_modules.append(module) py_modules.append("libvirt") moduleqemu = Extension('libvirtmod_qemu', sources = ['libvirt-qemu-override.c', 'build/libvirt-qemu.c', 'typewrappers.c', 'libvirt-utils.c'], libraries = [ "virt-qemu" ], include_dirs = [ "." ]) if cflags != "": moduleqemu.extra_compile_args.append(cflags) if ldflags != "": moduleqemu.extra_link_args.append(ldflags) c_modules.append(moduleqemu) py_modules.append("libvirt_qemu") if have_libvirt_lxc: modulelxc = Extension('libvirtmod_lxc', sources = ['libvirt-lxc-override.c', 'build/libvirt-lxc.c', 'typewrappers.c', 'libvirt-utils.c'], libraries = [ "virt-lxc" ], include_dirs = [ "." ]) if cflags != "": modulelxc.extra_compile_args.append(cflags) if ldflags != "": modulelxc.extra_link_args.append(ldflags) c_modules.append(modulelxc) py_modules.append("libvirt_lxc") class my_build(build): def run(self): apis = get_api_xml_files() self.spawn([sys.executable, "generator.py", "libvirt", apis[0]]) self.spawn([sys.executable, "generator.py", "libvirt-qemu", apis[1]]) if have_libvirt_lxc: self.spawn([sys.executable, "generator.py", "libvirt-lxc", apis[2]]) build.run(self) class my_sdist(sdist): user_options = sdist.user_options description = "Update libvirt-python.spec; build sdist-tarball." def initialize_options(self): self.snapshot = None sdist.initialize_options(self) def finalize_options(self): if self.snapshot is not None: self.snapshot = 1 sdist.finalize_options(self) def gen_rpm_spec(self): f1 = open('libvirt-python.spec.in', 'r') f2 = open('libvirt-python.spec', 'w') for line in f1: f2.write(line .replace('@PY_VERSION@', self.distribution.get_version()) .replace('@C_VERSION@', MIN_LIBVIRT)) f1.close() f2.close() def gen_authors(self): f = os.popen("git log --pretty=format:'%aN <%aE>'") authors = [] for line in f: authors.append(" " + line.strip()) authors.sort(key=str.lower) f1 = open('AUTHORS.in', 'r') f2 = open('AUTHORS', 'w') for line in f1: f2.write(line.replace('@AUTHORS@', "\n".join(authors))) f1.close() f2.close() def gen_changelog(self): f1 = os.popen("git log '--pretty=format:%H:%ct %an <%ae>%n%n%s%n%b%n'") f2 = open("ChangeLog", 'w') for line in f1: m = re.match(r'([a-f0-9]+):(\d+)\s(.*)', line) if m: t = time.gmtime(int(m.group(2))) f2.write("%04d-%02d-%02d %s\n" % (t.tm_year, t.tm_mon, t.tm_mday, m.group(3))) else: if re.match(r'Signed-off-by', line): continue f2.write(" " + line.strip() + "\n") f1.close() f2.close() def run(self): if not os.path.exists("build"): os.mkdir("build") if os.path.exists(".git"): try: self.gen_rpm_spec() self.gen_authors() self.gen_changelog() sdist.run(self) finally: files = ["libvirt-python.spec", "AUTHORS", "ChangeLog"] for f in files: if os.path.exists(f): os.unlink(f) else: sdist.run(self) class my_rpm(Command): user_options = [] description = "Build src and noarch rpms." def initialize_options(self): pass def finalize_options(self): pass def run(self): """ Run sdist, then 'rpmbuild' the tar.gz """ self.run_command('sdist') os.system('rpmbuild -ta --clean dist/libvirt-python-%s.tar.gz' % self.distribution.get_version()) class my_test(Command): user_options = [ ('build-base=', 'b', "base directory for build library"), ('build-platlib=', None, "build directory for platform-specific distributions"), ('plat-name=', 'p', "platform name to build for, if supported " "(default: %s)" % get_platform()), ] description = "Run test suite." def initialize_options(self): self.build_base = 'build' self.build_platlib = None self.plat_name = None def finalize_options(self): if self.plat_name is None: self.plat_name = get_platform() plat_specifier = ".%s-%s" % (self.plat_name, sys.version[0:3]) if hasattr(sys, 'gettotalrefcount'): plat_specifier += '-pydebug' if self.build_platlib is None: self.build_platlib = os.path.join(self.build_base, 'lib' + plat_specifier) def run(self): """ Run test suite """ apis = get_api_xml_files() self.spawn([sys.executable, "sanitytest.py", self.build_platlib, apis[0]]) class my_clean(clean): def run(self): clean.run(self) if os.path.exists("build"): remove_tree("build") setup(name = 'libvirt-python', version = '1.2.2', url = 'http://www.libvirt.org', maintainer = 'Libvirt Maintainers', maintainer_email = 'libvir-list@redhat.com', description = 'The libvirt virtualization API', ext_modules = c_modules, py_modules = py_modules, package_dir = { '': 'build' }, cmdclass = { 'build': my_build, 'clean': my_clean, 'sdist': my_sdist, 'rpm': my_rpm, 'test': my_test }) libvirt-python-1.2.2/COPYING.LESSER0000664000076400007640000006364212245535607020221 0ustar veillardveillard00000000000000 GNU LESSER GENERAL PUBLIC LICENSE Version 2.1, February 1999 Copyright (C) 1991, 1999 Free Software Foundation, Inc. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. [This is the first released version of the Lesser GPL. It also counts as the successor of the GNU Library Public License, version 2, hence the version number 2.1.] Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public Licenses are intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This license, the Lesser General Public License, applies to some specially designated software packages--typically libraries--of the Free Software Foundation and other authors who decide to use it. You can use it too, but we suggest you first think carefully about whether this license or the ordinary General Public License is the better strategy to use in any particular case, based on the explanations below. When we speak of free software, we are referring to freedom of use, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish); that you receive source code or can get it if you want it; that you can change the software and use pieces of it in new free programs; and that you are informed that you can do these things. To protect your rights, we need to make restrictions that forbid distributors to deny you these rights or to ask you to surrender these rights. These restrictions translate to certain responsibilities for you if you distribute copies of the library or if you modify it. For example, if you distribute copies of the library, whether gratis or for a fee, you must give the recipients all the rights that we gave you. You must make sure that they, too, receive or can get the source code. If you link other code with the library, you must provide complete object files to the recipients, so that they can relink them with the library after making changes to the library and recompiling it. And you must show them these terms so they know their rights. We protect your rights with a two-step method: (1) we copyright the library, and (2) we offer you this license, which gives you legal permission to copy, distribute and/or modify the library. To protect each distributor, we want to make it very clear that there is no warranty for the free library. Also, if the library is modified by someone else and passed on, the recipients should know that what they have is not the original version, so that the original author's reputation will not be affected by problems that might be introduced by others. Finally, software patents pose a constant threat to the existence of any free program. We wish to make sure that a company cannot effectively restrict the users of a free program by obtaining a restrictive license from a patent holder. Therefore, we insist that any patent license obtained for a version of the library must be consistent with the full freedom of use specified in this license. Most GNU software, including some libraries, is covered by the ordinary GNU General Public License. This license, the GNU Lesser General Public License, applies to certain designated libraries, and is quite different from the ordinary General Public License. We use this license for certain libraries in order to permit linking those libraries into non-free programs. When a program is linked with a library, whether statically or using a shared library, the combination of the two is legally speaking a combined work, a derivative of the original library. The ordinary General Public License therefore permits such linking only if the entire combination fits its criteria of freedom. The Lesser General Public License permits more lax criteria for linking other code with the library. We call this license the "Lesser" General Public License because it does Less to protect the user's freedom than the ordinary General Public License. It also provides other free software developers Less of an advantage over competing non-free programs. These disadvantages are the reason we use the ordinary General Public License for many libraries. However, the Lesser license provides advantages in certain special circumstances. For example, on rare occasions, there may be a special need to encourage the widest possible use of a certain library, so that it becomes a de-facto standard. To achieve this, non-free programs must be allowed to use the library. A more frequent case is that a free library does the same job as widely used non-free libraries. In this case, there is little to gain by limiting the free library to free software only, so we use the Lesser General Public License. In other cases, permission to use a particular library in non-free programs enables a greater number of people to use a large body of free software. For example, permission to use the GNU C Library in non-free programs enables many more people to use the whole GNU operating system, as well as its variant, the GNU/Linux operating system. Although the Lesser General Public License is Less protective of the users' freedom, it does ensure that the user of a program that is linked with the Library has the freedom and the wherewithal to run that program using a modified version of the Library. The precise terms and conditions for copying, distribution and modification follow. Pay close attention to the difference between a "work based on the library" and a "work that uses the library". The former contains code derived from the library, whereas the latter must be combined with the library in order to run. GNU LESSER GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License Agreement applies to any software library or other program which contains a notice placed by the copyright holder or other authorized party saying it may be distributed under the terms of this Lesser General Public License (also called "this License"). Each licensee is addressed as "you". A "library" means a collection of software functions and/or data prepared so as to be conveniently linked with application programs (which use some of those functions and data) to form executables. The "Library", below, refers to any such software library or work which has been distributed under these terms. A "work based on the Library" means either the Library or any derivative work under copyright law: that is to say, a work containing the Library or a portion of it, either verbatim or with modifications and/or translated straightforwardly into another language. (Hereinafter, translation is included without limitation in the term "modification".) "Source code" for a work means the preferred form of the work for making modifications to it. For a library, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the library. Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running a program using the Library is not restricted, and output from such a program is covered only if its contents constitute a work based on the Library (independent of the use of the Library in a tool for writing it). Whether that is true depends on what the Library does and what the program that uses the Library does. 1. You may copy and distribute verbatim copies of the Library's complete source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and distribute a copy of this License along with the Library. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Library or any portion of it, thus forming a work based on the Library, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) The modified work must itself be a software library. b) You must cause the files modified to carry prominent notices stating that you changed the files and the date of any change. c) You must cause the whole of the work to be licensed at no charge to all third parties under the terms of this License. d) If a facility in the modified Library refers to a function or a table of data to be supplied by an application program that uses the facility, other than as an argument passed when the facility is invoked, then you must make a good faith effort to ensure that, in the event an application does not supply such function or table, the facility still operates, and performs whatever part of its purpose remains meaningful. (For example, a function in a library to compute square roots has a purpose that is entirely well-defined independent of the application. Therefore, Subsection 2d requires that any application-supplied function or table used by this function must be optional: if the application does not supply it, the square root function must still compute square roots.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Library, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Library, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Library. In addition, mere aggregation of another work not based on the Library with the Library (or with a work based on the Library) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may opt to apply the terms of the ordinary GNU General Public License instead of this License to a given copy of the Library. To do this, you must alter all the notices that refer to this License, so that they refer to the ordinary GNU General Public License, version 2, instead of to this License. (If a newer version than version 2 of the ordinary GNU General Public License has appeared, then you can specify that version instead if you wish.) Do not make any other change in these notices. Once this change is made in a given copy, it is irreversible for that copy, so the ordinary GNU General Public License applies to all subsequent copies and derivative works made from that copy. This option is useful when you wish to copy part of the code of the Library into a program that is not a library. 4. You may copy and distribute the Library (or a portion or derivative of it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange. If distribution of object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place satisfies the requirement to distribute the source code, even though third parties are not compelled to copy the source along with the object code. 5. A program that contains no derivative of any portion of the Library, but is designed to work with the Library by being compiled or linked with it, is called a "work that uses the Library". Such a work, in isolation, is not a derivative work of the Library, and therefore falls outside the scope of this License. However, linking a "work that uses the Library" with the Library creates an executable that is a derivative of the Library (because it contains portions of the Library), rather than a "work that uses the library". The executable is therefore covered by this License. Section 6 states terms for distribution of such executables. When a "work that uses the Library" uses material from a header file that is part of the Library, the object code for the work may be a derivative work of the Library even though the source code is not. Whether this is true is especially significant if the work can be linked without the Library, or if the work is itself a library. The threshold for this to be true is not precisely defined by law. If such an object file uses only numerical parameters, data structure layouts and accessors, and small macros and small inline functions (ten lines or less in length), then the use of the object file is unrestricted, regardless of whether it is legally a derivative work. (Executables containing this object code plus portions of the Library will still fall under Section 6.) Otherwise, if the work is a derivative of the Library, you may distribute the object code for the work under the terms of Section 6. Any executables containing that work also fall under Section 6, whether or not they are linked directly with the Library itself. 6. As an exception to the Sections above, you may also combine or link a "work that uses the Library" with the Library to produce a work containing portions of the Library, and distribute that work under terms of your choice, provided that the terms permit modification of the work for the customer's own use and reverse engineering for debugging such modifications. You must give prominent notice with each copy of the work that the Library is used in it and that the Library and its use are covered by this License. You must supply a copy of this License. If the work during execution displays copyright notices, you must include the copyright notice for the Library among them, as well as a reference directing the user to the copy of this License. Also, you must do one of these things: a) Accompany the work with the complete corresponding machine-readable source code for the Library including whatever changes were used in the work (which must be distributed under Sections 1 and 2 above); and, if the work is an executable linked with the Library, with the complete machine-readable "work that uses the Library", as object code and/or source code, so that the user can modify the Library and then relink to produce a modified executable containing the modified Library. (It is understood that the user who changes the contents of definitions files in the Library will not necessarily be able to recompile the application to use the modified definitions.) b) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (1) uses at run time a copy of the library already present on the user's computer system, rather than copying library functions into the executable, and (2) will operate properly with a modified version of the library, if the user installs one, as long as the modified version is interface-compatible with the version that the work was made with. c) Accompany the work with a written offer, valid for at least three years, to give the same user the materials specified in Subsection 6a, above, for a charge no more than the cost of performing this distribution. d) If distribution of the work is made by offering access to copy from a designated place, offer equivalent access to copy the above specified materials from the same place. e) Verify that the user has already received a copy of these materials or that you have already sent this user a copy. For an executable, the required form of the "work that uses the Library" must include any data and utility programs needed for reproducing the executable from it. However, as a special exception, the materials to be distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. It may happen that this requirement contradicts the license restrictions of other proprietary libraries that do not normally accompany the operating system. Such a contradiction means you cannot use both them and the Library together in an executable that you distribute. 7. You may place library facilities that are a work based on the Library side-by-side in a single library together with other library facilities not covered by this License, and distribute such a combined library, provided that the separate distribution of the work based on the Library and of the other library facilities is otherwise permitted, and provided that you do these two things: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities. This must be distributed under the terms of the Sections above. b) Give prominent notice with the combined library of the fact that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 8. You may not copy, modify, sublicense, link with, or distribute the Library except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense, link with, or distribute the Library is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 9. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Library or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Library (or any work based on the Library), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Library or works based on it. 10. Each time you redistribute the Library (or any work based on the Library), the recipient automatically receives a license from the original licensor to copy, distribute, link with or modify the Library subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties with this License. 11. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Library at all. For example, if a patent license would not permit royalty-free redistribution of the Library by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Library. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply, and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 12. If the distribution and/or use of the Library is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Library under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 13. The Free Software Foundation may publish revised and/or new versions of the Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Library specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Library does not specify a license version number, you may choose any version ever published by the Free Software Foundation. 14. If you wish to incorporate parts of the Library into other free programs whose distribution conditions are incompatible with these, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Libraries If you develop a new library, and you want it to be of the greatest possible use to the public, we recommend making it free software that everyone can redistribute and change. You can do so by permitting redistribution under these terms (or, alternatively, under the terms of the ordinary General Public License). To apply these terms, attach the following notices to the library. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Also add information on how to contact you by electronic and paper mail. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the library, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the library `Frob' (a library for tweaking knobs) written by James Random Hacker. , 1 April 1990 Ty Coon, President of Vice That's all there is to it! libvirt-python-1.2.2/libvirt-override.py0000664000076400007640000001416412263141061022012 0ustar veillardveillard00000000000000# # Manually written part of python bindings for libvirt # # On cygwin, the DLL is called cygvirtmod.dll import sys try: import libvirtmod except ImportError: lib_e = sys.exc_info()[1] try: import cygvirtmod as libvirtmod except ImportError: cyg_e = sys.exc_info()[1] if str(cyg_e).count("No module named"): raise lib_e import types # The root of all libvirt errors. class libvirtError(Exception): def __init__(self, defmsg, conn=None, dom=None, net=None, pool=None, vol=None): # Never call virConnGetLastError(). # virGetLastError() is now thread local err = libvirtmod.virGetLastError() if err is None: msg = defmsg else: msg = err[2] Exception.__init__(self, msg) self.err = err def get_error_code(self): if self.err is None: return None return self.err[0] def get_error_domain(self): if self.err is None: return None return self.err[1] def get_error_message(self): if self.err is None: return None return self.err[2] def get_error_level(self): if self.err is None: return None return self.err[3] def get_str1(self): if self.err is None: return None return self.err[4] def get_str2(self): if self.err is None: return None return self.err[5] def get_str3(self): if self.err is None: return None return self.err[6] def get_int1(self): if self.err is None: return None return self.err[7] def get_int2(self): if self.err is None: return None return self.err[8] # # register the libvirt global error handler # def registerErrorHandler(f, ctx): """Register a Python function for error reporting. The function is called back as f(ctx, error), with error being a list of information about the error being raised. Returns 1 in case of success.""" return libvirtmod.virRegisterErrorHandler(f,ctx) def openAuth(uri, auth, flags=0): ret = libvirtmod.virConnectOpenAuth(uri, auth, flags) if ret is None:raise libvirtError('virConnectOpenAuth() failed') return virConnect(_obj=ret) # # Return library version. # def getVersion (name = None): """If no name parameter is passed (or name is None) then the version of the libvirt library is returned as an integer. If a name is passed and it refers to a driver linked to the libvirt library, then this returns a tuple of (library version, driver version). If the name passed refers to a non-existent driver, then you will get the exception 'no support for hypervisor'. Versions numbers are integers: 1000000*major + 1000*minor + release.""" if name is None: ret = libvirtmod.virGetVersion () else: ret = libvirtmod.virGetVersion (name) if ret is None: raise libvirtError ("virGetVersion() failed") return ret # # Invoke an EventHandle callback # def _eventInvokeHandleCallback(watch, fd, event, opaque, opaquecompat=None): """ Invoke the Event Impl Handle Callback in C """ # libvirt 0.9.2 and earlier required custom event loops to know # that opaque=(cb, original_opaque) and pass the values individually # to this wrapper. This should handle the back compat case, and make # future invocations match the virEventHandleCallback prototype if opaquecompat: callback = opaque opaque = opaquecompat else: callback = opaque[0] opaque = opaque[1] libvirtmod.virEventInvokeHandleCallback(watch, fd, event, callback, opaque) # # Invoke an EventTimeout callback # def _eventInvokeTimeoutCallback(timer, opaque, opaquecompat=None): """ Invoke the Event Impl Timeout Callback in C """ # libvirt 0.9.2 and earlier required custom event loops to know # that opaque=(cb, original_opaque) and pass the values individually # to this wrapper. This should handle the back compat case, and make # future invocations match the virEventTimeoutCallback prototype if opaquecompat: callback = opaque opaque = opaquecompat else: callback = opaque[0] opaque = opaque[1] libvirtmod.virEventInvokeTimeoutCallback(timer, callback, opaque) def _dispatchEventHandleCallback(watch, fd, events, cbData): cb = cbData["cb"] opaque = cbData["opaque"] cb(watch, fd, events, opaque) return 0 def _dispatchEventTimeoutCallback(timer, cbData): cb = cbData["cb"] opaque = cbData["opaque"] cb(timer, opaque) return 0 def virEventAddHandle(fd, events, cb, opaque): """ register a callback for monitoring file handle events @fd: file handle to monitor for events @events: bitset of events to watch from virEventHandleType constants @cb: callback to invoke when an event occurs @opaque: user data to pass to callback Example callback prototype is: def cb(watch, # int id of the handle fd, # int file descriptor the event occurred on events, # int bitmap of events that have occurred opaque): # opaque data passed to eventAddHandle """ cbData = {"cb" : cb, "opaque" : opaque} ret = libvirtmod.virEventAddHandle(fd, events, cbData) if ret == -1: raise libvirtError ('virEventAddHandle() failed') return ret def virEventAddTimeout(timeout, cb, opaque): """ register a callback for a timer event @timeout: time between events in milliseconds @cb: callback to invoke when an event occurs @opaque: user data to pass to callback Setting timeout to -1 will disable the timer. Setting the timeout to zero will cause it to fire on every event loop iteration. Example callback prototype is: def cb(timer, # int id of the timer opaque): # opaque data passed to eventAddTimeout """ cbData = {"cb" : cb, "opaque" : opaque} ret = libvirtmod.virEventAddTimeout(timeout, cbData) if ret == -1: raise libvirtError ('virEventAddTimeout() failed') return ret libvirt-python-1.2.2/libvirt-override-api.xml0000664000076400007640000012147712245535607022754 0ustar veillardveillard00000000000000 Returns the running hypervisor version of the connection host Returns the libvirt version of the connection host Returns the list of the ID of the domains on the hypervisor list the defined domains, stores the pointers to the names in @names returns list of all defined domains list the networks, stores the pointers to the names in @names list the defined networks, stores the pointers to the names in @names returns list of all networks Try to lookup a domain on the given hypervisor based on its UUID. Try to lookup a network on the given hypervisor based on its UUID. Extract information about a domain. Note that if the connection used to get the domain is limited only a partial set of the information can be extracted. Extract domain state. Extract details about current state of control interface to a domain. Extract information about a domain block device size Extract information about an active job being processed for a domain. Extract information about an active job being processed for a domain. Extract hardware information about the Node. Note that the memory size is reported in MiB instead of KiB. Extract information about the host security model Extract information about the domain security label. Only the first label will be returned. Extract information about the domain security label. A list of all labels will be returned. Extract node's CPU statistics. Extract node's memory statistics. Extract the UUID unique Identifier of a domain. Fetch globally unique ID of the domain as a string. Extract the UUID unique Identifier of a network. Fetch globally unique ID of the network as a string. Extract the UUID unique Identifier of a storage pool. Fetch globally unique ID of the storage pool as a string. Extract the autostart flag for a network. Extract the autostart flag for a domain Extract the autostart flag for a storage pool Extracts block device statistics for a domain Extracts block device statistics parameters of a running domain Extracts CPU statistics for a running domain. On success it will return a list of data of dictionary type. If boolean total is False or 0, the first element of the list refers to CPU0 on the host, second element is CPU1, and so on. The format of data struct is as follows: [{cpu_time:xxx}, {cpu_time:xxx}, ...] If it is True or 1, it returns total domain CPU statistics in the format of [{cpu_time:xxx, user_time:xxx, system_time:xxx}] Extracts interface device statistics for a domain Extracts memory statistics for a domain Returns the available memory for a list of cells Get the scheduler parameters, the @params array will be filled with the values. Get the scheduler parameters Get the scheduler type. Extract information about virtual CPUs of domain, store it in info array and also in cpumaps if this pointer is'nt NULL. Dynamically change the real CPUs which can be allocated to a virtual CPU. This function requires privileged access to the hypervisor. Dynamically change the real CPUs which can be allocated to a virtual CPU. This function requires privileged access to the hypervisor. Query the CPU affinity setting of all virtual CPUs of domain Query the CPU affinity setting of the emulator process of domain Dynamically change the real CPUs which can be allocated to the emulator process of a domain. This function requires privileged access to the hypervisor. Change the scheduler parameters Change the scheduler parameters Change the blkio tunables Get the blkio parameters Change the memory tunables Get the memory parameters Change the NUMA tunables Get the NUMA parameters Change the bandwidth tunables for a interface device Get the bandwidth tunables for a interface device list the storage pools, stores the pointers to the names in @names list the defined storage pool, stores the pointers to the names in @names returns list of all storage pools list the storage volumes, stores the pointers to the names in @names return list of storage volume objects Extract information about a storage pool. Note that if the connection used to get the domain is limited only a partial set of the information can be extracted. Extract information about a storage volume. Note that if the connection used to get the domain is limited only a partial set of the information can be extracted. list the node devices returns list of all host node devices list the node device's capabilities Fetches the value associated with a secret. List the defined secret IDs returns list of all interfaces Associates a value with a secret. Try to lookup a secret on the given hypervisor based on its UUID. Extract the UUID unique Identifier of a secret. Fetch globally unique ID of the secret as a string. List the defined network filters returns list of all network fitlers Try to lookup a network filter on the given hypervisor based on its UUID. Extract the UUID unique Identifier of a network filter. Fetch globally unique ID of the network filter as a string. list the running interfaces, stores the pointers to the names in @names list the defined interfaces, stores the pointers to the names in @names returns list of all interfaces Computes the most feature-rich CPU which is compatible with all given host CPUs. Get the list of supported CPU models. collect the list of snapshot names for the given domain returns the list of snapshots for the given domain collect the list of child snapshot names for the given snapshot returns the list of child snapshots for the given snapshot revert the domain to the given snapshot Get progress information for a block job Get current size of the cache (in bytes) used for compressing repeatedly transferred memory pages during live migration. Get currently configured maximum migration speed for a domain Migrate the domain object from its current host to the destination host given by dconn (a connection to the destination host). Migrate the domain object from its current host to the destination host given by URI. Change the I/O tunables for a block device Get the I/O tunables for a block device Read the contents of domain's disk device Read the contents of domain's memory Extract errors on disk devices. Change the node memory tunables Get the node memory parameters Get node CPU information libvirt-python-1.2.2/libvirt-override-virStoragePool.py0000664000076400007640000000066612245535607025006 0ustar veillardveillard00000000000000 def listAllVolumes(self, flags=0): """List all storage volumes and returns a list of storage volume objects""" ret = libvirtmod.virStoragePoolListAllVolumes(self._o, flags) if ret is None: raise libvirtError("virStoragePoolListAllVolumes() failed", conn=self) retlist = list() for volptr in ret: retlist.append(virStorageVol(self, _obj=volptr)) return retlist libvirt-python-1.2.2/libvirt-lxc-override.c0000664000076400007640000001033212263141061022361 0ustar veillardveillard00000000000000/* * libvir.c: this modules implements the main part of the glue of the * libvir library and the Python interpreter. It provides the * entry points where an automatically generated stub is * unpractical * * Copyright (C) 2012-2013 Red Hat, Inc. * * Daniel Veillard */ /* Horrible kludge to work around even more horrible name-space pollution via Python.h. That file includes /usr/include/python2.5/pyconfig*.h, which has over 180 autoconf-style HAVE_* definitions. Shame on them. */ #undef HAVE_PTHREAD_H #include #include #include #include "typewrappers.h" #include "libvirt-utils.h" #include "build/libvirt-lxc.h" #if PY_MAJOR_VERSION > 2 # ifndef __CYGWIN__ extern PyObject *PyInit_libvirtmod_lxc(void); # else extern PyObject *PyInit_cygvirtmod_lxc(void); # endif #else # ifndef __CYGWIN__ extern void initlibvirtmod_lxc(void); # else extern void initcygvirtmod_lxc(void); # endif #endif #if 0 # define DEBUG_ERROR 1 #endif #if DEBUG_ERROR # define DEBUG(fmt, ...) \ printf(fmt, __VA_ARGS__) #else # define DEBUG(fmt, ...) \ do {} while (0) #endif /* The two-statement sequence "Py_INCREF(Py_None); return Py_None;" is so common that we encapsulate it here. Now, each use is simply return VIR_PY_NONE; */ #define VIR_PY_NONE (Py_INCREF (Py_None), Py_None) #define VIR_PY_INT_FAIL (libvirt_intWrap(-1)) #define VIR_PY_INT_SUCCESS (libvirt_intWrap(0)) /************************************************************************ * * * Statistics * * * ************************************************************************/ static PyObject * libvirt_lxc_virDomainLxcOpenNamespace(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { PyObject *py_retval; virDomainPtr domain; PyObject *pyobj_domain; unsigned int flags; int c_retval; int *fdlist = NULL; size_t i; if (!PyArg_ParseTuple(args, (char *)"Oi:virDomainLxcOpenNamespace", &pyobj_domain, &flags)) return NULL; domain = (virDomainPtr) PyvirDomain_Get(pyobj_domain); if (domain == NULL) return VIR_PY_NONE; LIBVIRT_BEGIN_ALLOW_THREADS; c_retval = virDomainLxcOpenNamespace(domain, &fdlist, flags); LIBVIRT_END_ALLOW_THREADS; if (c_retval < 0) return VIR_PY_NONE; py_retval = PyList_New(0); for (i = 0; i < c_retval; i++) { PyObject *item = NULL; if ((item = libvirt_intWrap(fdlist[i])) == NULL) goto error; if (PyList_Append(py_retval, item) < 0) { Py_DECREF(item); goto error; } } VIR_FREE(fdlist); return py_retval; error: for (i = 0; i < c_retval; i++) { VIR_FORCE_CLOSE(fdlist[i]); } VIR_FREE(fdlist); return VIR_PY_NONE; } /************************************************************************ * * * The registration stuff * * * ************************************************************************/ static PyMethodDef libvirtLxcMethods[] = { #include "build/libvirt-lxc-export.c" {(char *) "virDomainLxcOpenNamespace", libvirt_lxc_virDomainLxcOpenNamespace, METH_VARARGS, NULL}, {NULL, NULL, 0, NULL} }; #if PY_MAJOR_VERSION > 2 static struct PyModuleDef moduledef = { PyModuleDef_HEAD_INIT, # ifndef __CYGWIN__ "libvirtmod_lxc", # else "cygvirtmod_lxc", # endif NULL, -1, libvirtLxcMethods, NULL, NULL, NULL, NULL }; PyObject * # ifndef __CYGWIN__ PyInit_libvirtmod_lxc # else PyInit_cygvirtmod_lxc # endif (void) { PyObject *module; if (virInitialize() < 0) return NULL; module = PyModule_Create(&moduledef); return module; } #else /* ! PY_MAJOR_VERSION > 2 */ void # ifndef __CYGWIN__ initlibvirtmod_lxc # else initcygvirtmod_lxc # endif (void) { if (virInitialize() < 0) return; /* initialize the python extension module */ Py_InitModule((char *) # ifndef __CYGWIN__ "libvirtmod_lxc", # else "cygvirtmod_lxc", # endif libvirtLxcMethods); } #endif /* ! PY_MAJOR_VERSION > 2 */ libvirt-python-1.2.2/AUTHORS0000664000076400007640000004727212304641433017232 0ustar veillardveillard00000000000000 Libvirt Python Binding Authors ============================== The libvirt python binding is maintained by the libvirt development team, who can be contacted at libvir-list@redhat.com The individual contributors are Adam Litke Adam Litke Adam Litke Adam Litke Adam Litke Adam Litke Adam Litke Adam Litke Alex Jia Alex Jia Alex Jia Alex Jia Alex Jia Alex Jia Chris Lalancette Chris Lalancette Claudio Bley Claudio Bley Cole Robinson Cole Robinson Cole Robinson Cole Robinson Cole Robinson Cole Robinson Cole Robinson Cole Robinson Cole Robinson Cole Robinson Cole Robinson Cole Robinson Cole Robinson Cole Robinson Cole Robinson Cole Robinson Cole Robinson Cole Robinson Cole Robinson Cole Robinson Cole Robinson Cole Robinson Cole Robinson Cole Robinson Cole Robinson Cole Robinson Cole Robinson Cole Robinson Cole Robinson Cole Robinson Cédric Bosdonnat Dan Kenigsberg Dan Kenigsberg Dan Kenigsberg Daniel P. Berrange Daniel P. Berrange Daniel P. Berrange Daniel P. Berrange Daniel P. Berrange Daniel P. Berrange Daniel P. Berrange Daniel P. Berrange Daniel P. Berrange Daniel P. Berrange Daniel P. Berrange Daniel P. Berrange Daniel P. Berrange Daniel P. Berrange Daniel P. Berrange Daniel P. Berrange Daniel P. Berrange Daniel P. Berrange Daniel P. Berrange Daniel P. Berrange Daniel P. Berrange Daniel P. Berrange Daniel P. Berrange Daniel P. Berrange Daniel P. Berrange Daniel P. Berrange Daniel P. Berrange Daniel P. Berrange Daniel P. Berrange Daniel P. Berrange Daniel P. Berrange Daniel P. Berrange Daniel P. Berrange Daniel P. Berrange Daniel P. Berrange Daniel P. Berrange Daniel P. Berrange Daniel P. Berrange Daniel P. Berrange Daniel P. Berrange Daniel P. Berrange Daniel P. Berrange Daniel P. Berrange Daniel P. Berrange Daniel P. Berrange Daniel P. Berrange Daniel P. Berrange Daniel P. Berrange Daniel P. Berrange Daniel P. Berrange Daniel P. Berrange Daniel P. Berrange Daniel P. Berrange Daniel P. Berrange Daniel P. Berrange Daniel P. Berrange Daniel P. Berrange Daniel P. Berrange Daniel P. Berrange Daniel P. Berrange Daniel P. Berrange Daniel P. Berrange Daniel P. Berrange Daniel P. Berrange Daniel P. Berrange Daniel P. Berrange Daniel P. Berrange Daniel P. Berrange Daniel P. Berrange Daniel P. Berrange Daniel P. Berrange Daniel P. Berrange Daniel P. Berrange Daniel P. Berrange Daniel P. Berrange Daniel P. Berrange Daniel P. Berrange Daniel P. Berrange Daniel P. Berrange Daniel P. Berrange Daniel P. Berrange Daniel P. Berrange Daniel P. Berrange Daniel P. Berrange Daniel P. Berrange Daniel P. Berrange Daniel P. Berrange Daniel P. Berrange Daniel P. Berrange Daniel P. Berrange Daniel P. Berrange Daniel P. Berrange Daniel P. Berrange Daniel P. Berrange Daniel P. Berrange Daniel P. Berrange Daniel P. Berrange Daniel P. Berrange Daniel P. Berrange Daniel P. Berrange Daniel P. Berrange Daniel P. Berrange Daniel P. Berrange Daniel P. Berrange Daniel P. Berrange Daniel P. Berrange Daniel P. Berrange Daniel P. Berrange Daniel P. Berrange Daniel P. Berrange Daniel P. Berrange Daniel P. Berrange Daniel P. Berrange Daniel P. Berrange Daniel P. Berrange Daniel P. Berrange Daniel P. Berrange Daniel P. Berrange Daniel P. Berrange Daniel P. Berrange Daniel P. Berrange Daniel P. Berrange Daniel P. Berrange Daniel P. Berrange Daniel P. Berrange Daniel P. Berrange Daniel P. Berrange Daniel P. Berrange Daniel P. Berrange Daniel P. Berrange Daniel P. Berrange Daniel P. Berrange Daniel P. Berrange Daniel P. Berrange Daniel P. Berrange Daniel P. Berrange Daniel P. Berrange Daniel P. Berrange Daniel P. Berrange Daniel P. Berrange Daniel Veillard Daniel Veillard Daniel Veillard Daniel Veillard Daniel Veillard Daniel Veillard Daniel Veillard Daniel Veillard Daniel Veillard Daniel Veillard Daniel Veillard Daniel Veillard Daniel Veillard Daniel Veillard Daniel Veillard Daniel Veillard Daniel Veillard Daniel Veillard Daniel Veillard Daniel Veillard Daniel Veillard Daniel Veillard Daniel Veillard Daniel Veillard Daniel Veillard Daniel Veillard Daniel Veillard Daniel Veillard Daniel Veillard Daniel Veillard Daniel Veillard Daniel Veillard Daniel Veillard Daniel Veillard Daniel Veillard Daniel Veillard Daniel Veillard Daniel Veillard Daniel Veillard Daniel Veillard Daniel Veillard Daniel Veillard Daniel Veillard Daniel Veillard Daniel Veillard Daniel Veillard Daniel Veillard Daniel Veillard Diego Elio Pettenò Don Dugger Doug Goldstein Doug Goldstein Doug Goldstein Doug Goldstein Doug Goldstein Doug Goldstein Doug Goldstein Doug Goldstein Doug Goldstein Doug Goldstein Doug Goldstein Doug Goldstein Doug Goldstein Doug Goldstein Doug Goldstein Doug Goldstein Doug Goldstein Doug Goldstein Doug Goldstein Doug Goldstein Doug Goldstein Doug Goldstein Doug Goldstein Doug Goldstein Doug Goldstein Doug Goldstein Doug Goldstein Doug Goldstein Doug Goldstein Doug Goldstein Doug Goldstein Doug Goldstein Doug Goldstein Eric Blake Eric Blake Eric Blake Eric Blake Eric Blake Eric Blake Eric Blake Eric Blake Eric Blake Eric Blake Eric Blake Eric Blake Eric Blake Eric Blake Eric Blake Eric Blake Eric Blake Eric Blake Eric Blake Eric Blake Eric Blake Eric Blake Eric Blake Eric Blake Eric Blake Eric Blake Eric Blake Eric Blake Eric Blake Eric Blake Eric Blake Eric Blake Eric Blake Eric Blake Eric Blake Eric Blake Eric Blake Eric Blake Eric Blake Eric Blake Eric Blake Eric Blake Eric Blake Eric Blake Eric Blake Federico Simoncelli Giuseppe Scrivano Giuseppe Scrivano Guan Qiang Guannan Ren Guannan Ren Guannan Ren Guannan Ren Guannan Ren Guannan Ren Guannan Ren Guannan Ren Guannan Ren Guannan Ren Guannan Ren Guannan Ren Guannan Ren Guannan Ren Guannan Ren Guannan Ren Gui Jianfeng Guido Günther Guido Günther Guido Günther Guido Günther Guido Günther Hu Tao Hu Tao Hu Tao Hu Tao Hu Tao Hu Tao Hu Tao Hu Tao Jim Fehlig Jim Meyering Jim Meyering Jim Meyering Jim Meyering Jim Meyering Jim Meyering Jim Meyering Jim Meyering Jim Meyering Jim Meyering Jim Meyering Jim Meyering Jim Meyering Jim Meyering Jim Meyering Jim Meyering Jim Meyering Jim Meyering Jim Meyering Jim Meyering Jiri Denemark Jiri Denemark Jiri Denemark Jiri Denemark Jiri Denemark Jiri Denemark Jiri Denemark Jiri Denemark Jiri Denemark Jiri Denemark Jiri Denemark Jiri Denemark Jiri Denemark Jiri Denemark Jiri Denemark Jiri Denemark Jiri Denemark Jiri Denemark Jiri Denemark Jiri Denemark Jiri Denemark Ján Tomko KAMEZAWA Hiroyuki Lai Jiangshan Lai Jiangshan Lei Li Lei Li Marcelo Cerri Marian Neagul Mark McLoughlin Mark McLoughlin Mark McLoughlin Martin Kletzander Martin Kletzander Martin Kletzander Martin Kletzander Martin Kletzander MATSUDA Daiki MATSUDA Daiki Matthias Bolte Matthias Bolte Matthias Bolte Matthias Bolte Matthias Bolte Matthias Bolte Matthias Bolte Matthias Bolte Matthias Bolte Michal Privoznik Michal Privoznik Michal Privoznik Michal Privoznik Michal Privoznik Michal Privoznik Michal Privoznik Michal Privoznik Miloslav Trmač Minoru Usui Minoru Usui Nikunj A. Dadhania Osier Yang Osier Yang Osier Yang Osier Yang Osier Yang Osier Yang Osier Yang Osier Yang Osier Yang Osier Yang Osier Yang Osier Yang Osier Yang Osier Yang Osier Yang Osier Yang Osier Yang Osier Yang Osier Yang Osier Yang Osier Yang Osier Yang Osier Yang Osier Yang Osier Yang Osier Yang Osier Yang Osier Yang Osier Yang Oskari Saarenmaa Peter Krempa Peter Krempa Peter Krempa Peter Krempa Peter Krempa Peter Krempa Peter Krempa Philip Hahn Philipp Hahn Philipp Hahn Philipp Hahn Philipp Hahn Philipp Hahn Richard W.M. Jones Richard W.M. Jones Richard W.M. Jones Richard W.M. Jones Richard W.M. Jones Richard W.M. Jones Richard W.M. Jones Richard W.M. Jones Richard W.M. Jones Richard W.M. Jones Robie Basak Serge Hallyn Stefan Berger Stefan Berger Stefan Berger Taizo ITO Taku Izumi Taku Izumi Taku Izumi Taku Izumi Viktor Mihajlovski Viktor Mihajlovski Viktor Mihajlovski Zeeshan Ali (Khattak) libvirt-python-1.2.2/PKG-INFO0000664000076400007640000000037512304641434017251 0ustar veillardveillard00000000000000Metadata-Version: 1.0 Name: libvirt-python Version: 1.2.2 Summary: The libvirt virtualization API Home-page: http://www.libvirt.org Author: Libvirt Maintainers Author-email: libvir-list@redhat.com License: UNKNOWN Description: UNKNOWN Platform: UNKNOWN libvirt-python-1.2.2/libvirt-utils.h0000664000076400007640000001640212263141061021127 0ustar veillardveillard00000000000000/* * libvirt-utils.h: misc helper APIs for python binding * * Copyright (C) 2013 Red Hat, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library. If not, see * . * */ #ifndef __LIBVIRT_UTILS_H__ # define __LIBVIRT_UTILS_H__ # define STREQ(a,b) (strcmp(a,b) == 0) # ifndef MIN # define MIN(a,b) (((a) < (b)) ? (a) : (b)) # endif /** * libvirt.h provides this as of version 1.2.0, but we want to be able * to support older versions of libvirt so copy and paste the macro from * libvirt.h */ # ifndef LIBVIR_CHECK_VERSION # define LIBVIR_CHECK_VERSION(major, minor, micro) \ ((major) * 1000000 + (minor) * 1000 + (micro) <= LIBVIR_VERSION_NUMBER) # endif /* Return 1 if an array of N objects, each of size S, cannot exist due to size arithmetic overflow. S must be positive and N must be nonnegative. This is a macro, not a function, so that it works correctly even when SIZE_MAX < N. By gnulib convention, SIZE_MAX represents overflow in size calculations, so the conservative dividend to use here is SIZE_MAX - 1, since SIZE_MAX might represent an overflowed value. However, malloc (SIZE_MAX) fails on all known hosts where sizeof (ptrdiff_t) <= sizeof (size_t), so do not bother to test for exactly-SIZE_MAX allocations on such hosts; this avoids a test and branch when S is known to be 1. */ # define xalloc_oversized(n, s) \ ((size_t) (sizeof (ptrdiff_t) <= sizeof (size_t) ? -1 : -2) / (s) < (n)) /* The __attribute__((__warn_unused_result__)) feature is available in gcc versions 3.4 and newer, while the typeof feature has been available since 2.7 at least. */ # if 3 < __GNUC__ + (4 <= __GNUC_MINOR__) # define ignore_value(x) \ (__extension__ ({ __typeof__ (x) __x = (x); (void) __x; })) # else # define ignore_value(x) ((void) (x)) # endif # ifdef __GNUC__ # ifndef __GNUC_PREREQ # if defined __GNUC__ && defined __GNUC_MINOR__ # define __GNUC_PREREQ(maj, min) \ ((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min)) # else # define __GNUC_PREREQ(maj, min) 0 # endif # endif /* __GNUC_PREREQ */ /** * ATTRIBUTE_UNUSED: * * Macro to flag consciously unused parameters to functions */ # ifndef ATTRIBUTE_UNUSED # define ATTRIBUTE_UNUSED __attribute__((__unused__)) # endif /* gcc's handling of attribute nonnull is less than stellar - it does * NOT improve diagnostics, and merely allows gcc to optimize away * null code checks even when the caller manages to pass null in spite * of the attribute, leading to weird crashes. Coverity, on the other * hand, knows how to do better static analysis based on knowing * whether a parameter is nonnull. Make this attribute conditional * based on whether we are compiling for real or for analysis, while * still requiring correct gcc syntax when it is turned off. See also * http://gcc.gnu.org/bugzilla/show_bug.cgi?id=17308 */ # ifndef ATTRIBUTE_NONNULL # if __GNUC_PREREQ (3, 3) # if STATIC_ANALYSIS # define ATTRIBUTE_NONNULL(m) __attribute__((__nonnull__(m))) # else # define ATTRIBUTE_NONNULL(m) __attribute__(()) # endif # else # define ATTRIBUTE_NONNULL(m) # endif # endif # ifndef ATTRIBUTE_RETURN_CHECK # if __GNUC_PREREQ (3, 4) # define ATTRIBUTE_RETURN_CHECK __attribute__((__warn_unused_result__)) # else # define ATTRIBUTE_RETURN_CHECK # endif # endif # else # ifndef ATTRIBUTE_UNUSED # define ATTRIBUTE_UNUSED # endif # ifndef ATTRIBUTE_NONNULL # define ATTRIBUTE_NONNULL(m) # endif # ifndef ATTRIBUTE_RETURN_CHECK # define ATTRIBUTE_RETURN_CHECK # endif # endif /* __GNUC__ */ /* Don't call these directly - use the macros below */ int virAlloc(void *ptrptr, size_t size) ATTRIBUTE_RETURN_CHECK ATTRIBUTE_NONNULL(1); int virAllocN(void *ptrptr, size_t size, size_t count) ATTRIBUTE_RETURN_CHECK ATTRIBUTE_NONNULL(1); int virReallocN(void *ptrptr, size_t size, size_t count) ATTRIBUTE_RETURN_CHECK ATTRIBUTE_NONNULL(1); void virFree(void *ptrptr) ATTRIBUTE_NONNULL(1); /** * VIR_ALLOC: * @ptr: pointer to hold address of allocated memory * * Allocate sizeof(*ptr) bytes of memory and store * the address of allocated memory in 'ptr'. Fill the * newly allocated memory with zeros. * * This macro is safe to use on arguments with side effects. * * Returns -1 on failure (with OOM error reported), 0 on success */ # define VIR_ALLOC(ptr) virAlloc(&(ptr), sizeof(*(ptr))) /** * VIR_ALLOC_N: * @ptr: pointer to hold address of allocated memory * @count: number of elements to allocate * * Allocate an array of 'count' elements, each sizeof(*ptr) * bytes long and store the address of allocated memory in * 'ptr'. Fill the newly allocated memory with zeros. * * This macro is safe to use on arguments with side effects. * * Returns -1 on failure (with OOM error reported), 0 on success */ # define VIR_ALLOC_N(ptr, count) virAllocN(&(ptr), sizeof(*(ptr)), (count)) /** * VIR_REALLOC_N: * @ptr: pointer to hold address of allocated memory * @count: number of elements to allocate * * Re-allocate an array of 'count' elements, each sizeof(*ptr) * bytes long and store the address of allocated memory in * 'ptr'. If 'ptr' grew, the added memory is uninitialized. * * This macro is safe to use on arguments with side effects. * * Returns -1 on failure (with OOM error reported), 0 on success */ # define VIR_REALLOC_N(ptr, count) virReallocN(&(ptr), sizeof(*(ptr)), (count)) /** * VIR_FREE: * @ptr: pointer holding address to be freed * * Free the memory stored in 'ptr' and update to point * to NULL. * * This macro is safe to use on arguments with side effects. */ # if !STATIC_ANALYSIS /* The ternary ensures that ptr is a pointer and not an integer type, * while evaluating ptr only once. This gives us extra compiler * safety when compiling under gcc. For now, we intentionally cast * away const, since a number of callers safely pass const char *. */ # define VIR_FREE(ptr) virFree((void *) (1 ? (const void *) &(ptr) : (ptr))) # else /* The Coverity static analyzer considers the else path of the "?:" and * flags the VIR_FREE() of the address of the address of memory as a * RESOURCE_LEAK resulting in numerous false positives (eg, VIR_FREE(&ptr)) */ # define VIR_FREE(ptr) virFree((void *) &(ptr)) # endif /* Don't call this directly - use the macro below */ int virFileClose(int *fdptr) ATTRIBUTE_RETURN_CHECK; # define VIR_FORCE_CLOSE(FD) \ ignore_value(virFileClose(&(FD))) # if ! LIBVIR_CHECK_VERSION(1, 0, 2) void virTypedParamsClear(virTypedParameterPtr params, int nparams); void virTypedParamsFree(virTypedParameterPtr params, int nparams); # endif /* ! LIBVIR_CHECK_VERSION(1, 0, 2) */ #endif /* __LIBVIRT_UTILS_H__ */ libvirt-python-1.2.2/ChangeLog0000664000076400007640000062670612304641433017741 0ustar veillardveillard000000000000002014-02-20 Martin Kletzander generator: Skip exporting only sentinels When enum type has '_LAST' in its name, but is not the last type in that enum, it's skipped even though it shouldn't be. Currently, this is the case for only VIR_NETWORK_UPDATE_COMMAND_ADD_LAST inside an enum virNetworkUpdateCommand. Also, since _LAST types can have other enums instead of values, that needs to be filtered out using a try-except when converting the value. 2014-02-13 Philipp Hahn Fix stream related spelling mistakes Consistent spelling of all-uppercase I/O. 2014-02-12 Eric Blake examples: demonstrate network events Commit 6ea5be0 added network event callback support, so we might as well demonstrate that it works by updating our example. * examples/event-test.py: Add network event, fix typos. 2014-02-04 Eric Blake maint: ignore editor files * .gitignore: Exclude emacs cruft. 2014-02-03 Eric Blake Merge tag 'v1.2.1' Release of libvirt-python-1.2.1 2014-01-23 Robie Basak Fix calling of virStreamSend method Change d40861 removed the 'len' argument from the virStreamSend C level wrapper, but forgot to remove it from the python level wrapper. Reported-by: Robie Basak 2014-01-16 Daniel Veillard Release of libvirt-python-1.2.1 2014-01-11 Doug Goldstein virStream.sendAll() fix raising an undeclared var The exception is raised from the variable 'e', which was undeclared in this context. Used code that is compatible with old and new Python versions. 2014-01-02 Doug Goldstein Add space after comma for consistency with code style 2013-12-30 Doug Goldstein define __GNUC_PREREQ macro before using it We brought over use of the __GNUC_PREREQ macro from libvirt but didn't bring over the definition of it. This brings over the macro from libvirt sources. 2013-12-12 Daniel P. Berrange Rewrite libvirt_charPtrUnwrap to work with Python 3.0->3.2 The PyUnicode_AsUTF8 method doesn't exist prior to Python 3.3. It is also somewhat inefficient, so rewrite it to use an intermediate PyBytes object. 2013-12-12 Daniel P. Berrange Add python3 to the automated build and RPM This updates autobuild.sh to test the python3 build process. The RPM specfile is changed to build a libvirt-python3 RPM on Fedora > 18 2013-12-11 Daniel P. Berrange Skip network event callbacks in sanity test 2013-12-11 Daniel P. Berrange Fix return type in override method for virStreamRecv The virStreamRecv override returns a PyObject not an int 2013-12-11 Daniel P. Berrange sanitytest: remove use of string.lower() Call lower() directly on the string object instance, not the class 2013-12-11 Daniel P. Berrange sanitytest: Fix broken comparison between int and string Python2 was forgiving of a comparison between an int and string but Python3 gets very upset. 2013-12-11 Daniel P. Berrange override: Switch virStreamSend wrapper to use libvirt_charPtrSizeUnwrap Instead of using a 'z#i' format string to receive byte array, use 'O' and then libvirt_charPtrSizeUnwrap. This lets us hide the Python 3 vs 2 differences in typewrappers.c 2013-12-11 Daniel P. Berrange override: Conditionalize use of PyString_Check and PyInt_Check The PyString and PyInt classes are gone in Python 3, so we must conditionalize their use to be Python 2 only. 2013-12-11 Daniel P. Berrange typewrappers: PyInt/PyLong merge for Python3 In Python3 the PyInt / PyLong types have merged into a single PyLong type. Conditionalize the use of PyInt to Python 2 only 2013-12-11 Daniel P. Berrange typewrappers: Replace use of PyString class Replace use of PyString with either PyBytes or PyUnicode. The former is used for buffers with explicit sizes, which are used by APIs processing raw bytes. 2013-12-11 Daniel P. Berrange override: Replace PyInt_AsLong with helper Replace use of the PyInt_AsLong libvirt_intUnwrap helper. This isolates the need for Python3 specific code in one place 2013-12-11 Daniel P. Berrange override: Replace Py{Int,Long}_FromLong with helpers Replace use of the PyInt_FromLong and PyLong_FromLongLong with libvirt_{int,uint,longlong,ulonglong}Wrap helpers. This isolates the need for Python3 specific code in one place. 2013-12-11 Daniel P. Berrange override: Replace PyString_AsString with libvirt_charPtrUnwrap Replace calls to PyString_AsString with the helper method libvirt_charPtrUnwrap. This isolates the code that will change in Python3. In making this change, all callers now have responsibility for free'ing the string. 2013-12-11 Daniel P. Berrange override: Replace PyString_FromString with libvirt_constcharPtrWrap Make use of libvirt_constcharPtrWrap in all override code, to match generated code. This will isolate Python3 specific changes in one place. 2013-12-11 Daniel P. Berrange sanitytest: Fix libvirtError class handling for Python 2.4 The Exception class hiearchy in Python 2.4 reports different data types than in later Python versions. As a result the type(libvirt.libvirtError) does not return 'type'. We just special case handling of this class. 2013-12-11 Daniel P. Berrange override: Fix native module registration to work with Python3 The way native modules are registered has completely changed, so the code must be #ifdef'd for Python2 & 3 2013-12-11 Daniel P. Berrange examples: Ensure we write bytes to the self-pipe Strings in python3 default to unicode, so when writing to the self-pipe we must be sure to use bytes by calling the encode() method. 2013-12-11 Daniel P. Berrange examples: Invoke print("...") instead of print "..." The 'print' method must be called as a function in python3, ie with brackets. 2013-12-11 Daniel P. Berrange Don't free passed in args in libvirt_charPtrWrap / libvirt_charPtrSizeWrap Functions should not make assumptions about the memory management callers use for parameters 2013-12-11 Cédric Bosdonnat Added python binding for the new network events API The new network events code requires manual binding code to be written. 2013-12-09 Doug Goldstein test: Invoke print("...") instead of print "..." The 'print' statement no longer exists in Python 3 and now must be called as a function. This is compatible down to Python 2.4 as we are not using any special syntax of the function. 2013-12-09 Doug Goldstein override: Fix exception handling syntax Python 3 no longer accepts 'except Exception, e:' as valid while Python 2.4 does not accept the new syntax 'except Exception as e:' so this uses a fall back method that is compatible with both. 2013-12-09 Daniel P. Berrange generator: Sort enums and functions when generating code To assist in diff comparisons between code generated with different versions of Python, do an explicit sort of all functions and enums. 2013-12-09 Daniel P. Berrange generator: Remove use of string.replace and string.find functions Call the 'replace' and 'find' functions directly on the string variables, instead of via the 'string' module. Python3 only accepts the latter syntax 2013-12-09 Daniel P. Berrange generator: Update to use sort() 'key' param The sort() method previously took either a comparator function or a key function. Only the latter is supported in Python3. 2013-12-09 Daniel P. Berrange generator: Remove use of 'has_key' function The code 'XXX.has_key(YYYY)' must be changed to be of the form 'YYY in XXXX' which works in Python2 and 3 As an added complication, if 'YYY in XXX' is used against an object overriding the '__getitem__' method it does not work in Python 2.4. Instead we must use 'YYY in XXX.keys()' 2013-12-05 Doug Goldstein Update exception catching in generated code Use a syntax for exception handling that works in both Python 2 and Python 3. The new syntax is 'except Exception as e:' but this does not work in older Pythons so we use the most compatible way by just catching the exception and getting the type and the exception value after the fact. 2013-12-05 Doug Goldstein generator: Support exceptions in Python 2 and 3 Use a syntax for exception handling that works in both Python 2 and Python 3 2013-12-05 Doug Goldstein setup: Drop unused exception variable Drop the unused exception variable in setup.py. This has the benefit of dropping syntax that is not valid with Python 3. 2013-12-04 Daniel P. Berrange generator: Cast iterators to a list() explicitly In python3 various methods list 'dict.keys()' do not return a list, so we must explicitly cast the result. 2013-12-04 Daniel P. Berrange Revert "Optimize callback lookup in event handlers" This reverts commit 084729e26905f574b8c057cc4c732b1b6ce852d3. The PyImport_ImportModuleNoBlock method does not exist in python 2.4 2013-12-04 Daniel P. Berrange Revert accidental change to exception handling syntax The previous commit changed the exception handling syntax to use 'as' instead of a ','. This doesn't work with python 2.4 2013-12-04 Daniel P. Berrange generator: Invoke print("...") instead of print "..." The 'print' method must be called as a function in python3, ie with brackets. 2013-12-04 Daniel P. Berrange generator: Remove string.lower(XXX) with XXX.lower() In python3 the string.lower() method doesn't exist, the lower() function can only be executed against a string variable directly. Python2 supported both approaches so this change is compatible 2013-12-04 Daniel P. Berrange generator: Don't use 'list' as a variable name In python3 if we use 'list' as a variable name it causes it to hide the corresponding 'list()' function from the entire function that holds the variable. 2013-12-04 Daniel P. Berrange Optimize callback lookup in event handlers The event handler code currently invokes PyImport_ImportModule which is very heavyweight. This is not in fact required, since we know the libvirt module has already been imported. We can thus use PyImport_ImportModuleNoBlock and do away with the global variables caching the imported module reference. 2013-12-04 Daniel P. Berrange Fix use of virDomainEventRegister in python bindings If an app used the virDomainEventRegister binding instead of the virDomainEventRegisterAny binding, it would never have its callback invoked. This is because the code for dispatching from the C libvirt_virConnectDomainEventCallback method was totally fubar. If DEBUG macro was set in the python build the error would become visible "libvirt_virConnectDomainEventCallback dom_class is not a class!" The code in libvirt_virConnectDomainEventCallback was inexplicably complex and has apparently never worked. The fix is to write it the same way as the other callback handlers. 2013-12-03 Doug Goldstein setup: Use user requested python binary When setup.py is kicked off with a python interpreter other than the system 'python', (e.g. python2.7 setup.py build) the build process would switch to 'python' and not use python2.7 as requested by the user. We should always respect the user requested python interpreter and use it. 2013-11-28 Daniel P. Berrange Improve quality of sanitytest check Validate that every public API method is mapped into the python and that every python method has a sane C API. 2013-11-28 Daniel P. Berrange Skip copying manually written python for C APIs which don't exist If the libvirt-override-virXXXX.py file has methods which call C APIs that don't exist in the version of libvirt built against we need to skip copying their code. eg for 0.9.13 libvirt we should not copy the 'listAllDomains' method. The way this works is that it breaks the override file into individual methods by looking for ' def '. It then collects the contents until the next method start, whereupon it looks for a libvirtmod.XXXXXX API call. It checks if the XXXXX part is present in the XML description we have, and if not, it discards the entire method. 2013-11-28 Daniel P. Berrange Fix misc RPM specfile flaws Fix the RPM summary line, add placeholder %changelog tag, make %setup quiet, add Url: tag and filter out bogus provides and add example programs as docs. 2013-11-28 Daniel P. Berrange Fix code for avoiding overrides of non-existant functions When reading/writing a global variable from inside a method it must be declared as a global, otherwise a local variable by the same name will be used. Special case the virConnectListDomainsID method which is bizarrely renamed for no obvious reason. 2013-11-28 Daniel P. Berrange Deal with old filenames for events/error functions Older libvirt has files named 'events' and 'virterror' rather than 'virevent' and 'virerror'. This is visible in the API XML files. We must look for both names to ensure we don't lose generation of methods with older versions of libvirt. 2013-11-27 Daniel P. Berrange Add missing binding of security model/label APIs The virNodeGetSecurityModel, virDomainGetSecurityLabel and virDomainGetSecurityLabelList methods were disabled in the python binding for inexplicable reasons. 2013-11-27 Daniel P. Berrange Avoid generating the methods in multiple classes The python code generator tries to figure out what class a method should be in by looking at the list of arguments for any which are object types. Unfortunately missing break statements meant that methods which have multiple object arguments (eg migrate as a virDomainPtr followed by a virConnectPtr) got added to multiple classes. The following incorrect methods are removed by this change virStream.download (dup of virStorageVol.download) virStream.screenshot (dup of virDomain.screenshot) virStream.upload (dup of virStorageVol.upload) virConnect.migrate (dup of virDomain.migrate) virConnect.migrate2 (dup of virDomain.migrate2) virConnect.migrate3 (dup of virDomain.migrate3) virConnect.migrateToURI3 (dup of virDomain.migrateToURI3) 2013-11-27 Daniel P. Berrange Make block pull event dispatcher private The method dispatchDomainEventBlockPullCallback which is used internally to dispatch block pull events to the python application code was missing the leading '_', to denote that it was private. All other event callback helpers have a leading '_'. No application should have been using this so it is justifiable to rename it. 2013-11-27 Daniel P. Berrange Don't include virDomainSnapshotRef in python API The reference counting API is for internal use only. Attempts to use it from python application code will cause havoc. 2013-11-26 Doug Goldstein Call virGetLastError from mod rather than py wrapper All other code always calls the methods from the mod rather than using the python wrapper so this matches the state of all other callers. 2013-11-26 Don Dugger Return right error code for baselineCPU This Python interface code is returning a -1 on errors for the `baselineCPU' API. Since this API is supposed to return a pointer the error return value should really be VIR_PY_NONE. 2013-11-26 Martin Kletzander Make setup.py executable 2013-11-26 Daniel P. Berrange Update README file contents and add HACKING file The previous README file from the python code is more like a HACKING file. Rename it and update the content. Then add a basic README file 2013-11-25 Eric Blake maint: next release is 1.2.0 No other hits for: git grep '1\.1\.5' * libvirt-utils.h: Fix comment. 2013-11-22 Daniel P. Berrange Ensure API overrides only used if API exists Entries in the -overrides.xml files should only be recorded if the API also exists in the main API XML file. 2013-11-22 Daniel P. Berrange Relax min required libvirt to version 0.9.11 2013-11-22 Doug Goldstein virConnectGetCPUModelNames API appeared in 1.1.3 2013-11-22 Daniel P. Berrange VIR_DOMAIN_EVENT_ID_DEVICE_REMOVED appeared in 1.1.1 2013-11-22 Doug Goldstein virDomainCreateXMLWithFiles and virDomainCreateWithFiles APIs appeared in 1.1.1 virDomainCreateXMLWithFiles() and virDomainCreateWithFiles() were not added to libvirt until 1.1.1 2013-11-22 Doug Goldstein virDomainMigrate3 and virDomainMigrateToURI3 appeared in 1.1.0 The functions virDomainMigrate3 and virDomainMigrateToURI3 were not added to libvirt until v1.1.0. 2013-11-22 Doug Goldstein virTypedParams* API appeared in 1.0.2 and used in 1.1.0 When building against versions of libvirt prior to 1.0.2, we can not provide wrappers for virTypedParams* APIs. In addition we don't need to have the helper APIs until 1.1.0 when the first API we wrap starts to use them. 2013-11-22 Doug Goldstein virDomainMigrateGetCompressionCache API appeared in 1.0.3 2013-11-22 Doug Goldstein virDomainGetJobStats API appeared in 1.0.3 2013-11-22 Doug Goldstein virNodeGetCPUMap API appeared in 1.0.0 2013-11-22 Daniel P. Berrange VIR_DOMAIN_EVENT_ID_PMSUSPEND_DISK appeared in 1.0.0 2013-11-22 Doug Goldstein virStoragePoolListAllVolumes API appeared in 0.10.2 2013-11-22 Doug Goldstein virNode{Get,Set}MemoryParameters API appeared in 0.10.2 2013-11-22 Doug Goldstein virConnectListAll* APIs appeared in 0.10.2 2013-11-22 Daniel P. Berrange virDomainQemuAgentCommand appeared in 0.10.0 2013-11-22 Doug Goldstein virDomainPinEmulator and virDomainGetEmulatorPinInfo APIs appeared in 0.10.0 2013-11-22 Daniel P. Berrange VIR_DOMAIN_EVENT_ID_BALLOON_CHANGED appeared in 0.10.0 2013-11-22 Doug Goldstein virConnect{Unr,R}egisterCloseCallback API appeared in 0.10.0 2013-11-22 Doug Goldstein virDomainSnapshotListAllChildren API appeared in 0.9.13 2013-11-22 Doug Goldstein virConnectListAllDomains API appeared in 0.9.13 2013-11-22 Doug Goldstein virDomainListAllSnapshots API appeared in 0.9.13 2013-11-22 Doug Goldstein Don't build LXC module when building less than 1.0.2 The functions that the LXC module wraps did not appear until 1.0.2 so we can't build the module unless we're building against 1.0.2 or newer. 2013-11-22 Doug Goldstein Create array of modules to be built Create an array of modules to be built to allow for flexibility to enable or disable some modules in the future and allow for additional modules to be added easily 2013-11-22 Doug Goldstein Break generator.py to be called per module Since we don't always want to build all the modules, and there might be more modules added in the future but we want to retain backwards compatibility with older libvirts, change generator.py to be called once per module instead of with all modules at once. 2013-11-22 Daniel P. Berrange Setup distutils build system Create a setup.py for building libvirt python code and add supporting files 2013-11-22 Daniel P. Berrange Add execute permission for sanitytest.py 2013-11-22 Daniel P. Berrange Add build/ to python module path for sanitytest.py The generated libvirt.py modules will be in the build/ directory, so santitytest.py must use that directory. 2013-11-22 Doug Goldstein Import some virTypedParams* APIs from libvirt virTypedParamsClear() and virTypedParamsFree() were introduced in libvirt 1.0.2. In an effort to keep the code clean bring these two functions to libvirt-python if we're building against a version of libvirt that's older than 1.0.2 2013-11-22 Doug Goldstein Import LIBVIR_CHECK_VERSION macro from libvirt Add LIBVIR_CHECK_VERSION from libvirt upstream so that we can check the version of the library we are compiling against and support a range of libvirt versions. The macro was added to libvirt in 1.2.0 so we must provide it if its not defined. 2013-11-22 Daniel P. Berrange Import VIR_FORCE_CLOSE macro from libvirt Import the macro for safely closing file descriptors 2013-11-22 Daniel P. Berrange Remove use of virStrcpyStatic 2013-11-22 Daniel P. Berrange Import VIR_ALLOC / VIR_ALLOC_N / VIR_REALLOC_N functions Import the libvirt memory allocation functions, stripping the OOM testing and error reporting pieces. 2013-11-22 Daniel P. Berrange Import code annotation macros from libvirt Import ATTRIBUTE_RETURN_CHECK, ATTRIBUTE_UNUSED & ATTRIBUTE_NONNULL macros 2013-11-22 Daniel P. Berrange Import gnulib's ignore_value macro 2013-11-22 Daniel P. Berrange Import gnulib's xalloc_oversized macro 2013-11-22 Daniel P. Berrange Add decl of MIN macro 2013-11-22 Daniel P. Berrange Import STREQ macro from libvirt 2013-11-22 Daniel P. Berrange Update header file includes We're no longer using automake, so files are not required. Also remove of all libvirt internal util header files. Reference generated header files in build/ subdir. 2013-11-22 Daniel P. Berrange Update generator for new code layout Change the generator.py to - Take XML API file names on command line - Generate data in build/ directory instead of cwd 2013-11-22 Daniel P. Berrange Remove obsolete Makefile.am We are no longer using automake, so Makefile.am is obsolete 2013-11-22 Daniel P. Berrange Move python example programs into python/examples/ subdirectory 2013-11-22 Daniel P. Berrange Mostly revert "python: remove virConnectGetCPUModelNames from globals" This reverts commit 6b90d7428d72e92db292a9228c44701bfd5003c9. The original problem was that libvirt_virConnectGetCPUModelNames was listed twice in the exports table, once automatically from the generator and once from the manual override. We merely needed to list it in the skip_impl list, and not delete the manually written code entirely. 2013-11-21 Doug Goldstein python: remove virConnectGetCPUModelNames from globals Commit de51dc9c9aed0e615c8b301cccb89f4859324eb0 primarily added virConnectGetCPUModelNames as libvirt.getCPUModelNames(conn, arch) instead of libvirt.virConnect.getCPUModelNames(arch) so revert the code that does the former while leaving the code that does the later. This is the rest of the patch that was ACK'd by Dan but I committed only the partial patch in 6a8b8ae. 2013-11-21 Doug Goldstein python: remove virConnectGetCPUModelNames from globals Commit de51dc9c9aed0e615c8b301cccb89f4859324eb0 primarily added virConnectGetCPUModelNames as libvirt.getCPUModelNames(conn, arch) instead of libvirt.virConnect.getCPUModelNames(arch) so revert the code that does the former while leaving the code that does the later. 2013-11-20 Eric Blake maint: fix comma style issues: python Most of our code base uses space after comma but not before; fix the remaining uses before adding a syntax check. * python/libvirt-override.c: Consistently use commas. 2013-11-19 Doug Goldstein Add missing break to switch-case block The case label for VIR_DOMAIN_EVENT_ID_DEVICE_REMOVED did not have its own break statement but relied on falling through which we probably don't want. 2013-10-22 Marian Neagul python: Fix Create*WithFiles filefd passing Commit d76227be added functions virDomainCreateWithFiles and virDomainCreateXMLWithFiles, but there was a little piece missing in python bindings. This patch fixes proper passing of file descriptors in the overwrites of these functions. 2013-10-21 Daniel P. Berrange Don't link virt-login-shell against libvirt.so (CVE-2013-4400) The libvirt.so library has far too many library deps to allow linking against it from setuid programs. Those libraries can do stuff in __attribute__((constructor) functions which is not setuid safe. The virt-login-shell needs to link directly against individual files that it uses, with all library deps turned off except for libxml2 and libselinux. Create a libvirt-setuid-rpc-client.la library which is linked to by virt-login-shell. A config-post.h file allows this library to disable all external deps except libselinux and libxml2. 2013-10-14 Eric Blake maint: avoid 'const fooPtr' in python bindings 'const fooPtr' is the same as 'foo * const' (the pointer won't change, but it's contents can). But in general, if an interface is trying to be const-correct, it should be using 'const foo *' (the pointer is to data that can't be changed). Fix up offenders in the python bindings. * python/generator.py (py_types): Drop useless conversions. * python/libvirt-override.c (getPyVirTypedParameter) (setPyVirTypedParameter): Use intended type. 2013-09-30 Michal Privoznik python: Document virNodeGetInfo bug The memory size in virNodeGetInfo python API binding is reported in MiB instead of KiB (like we have in C struct). However, there already might be applications out there relying on this inconsistence so we can't simply fix it. Document this sad fact as known bug. 2013-09-23 Giuseppe Scrivano python: add bindings for virConnectGetCPUModelNames 2013-09-23 Giuseppe Scrivano libvirt: add new public API virConnectGetCPUModelNames The new function virConnectGetCPUModelNames allows to retrieve the list of CPU models known by the hypervisor for a specific architecture. 2013-09-20 Daniel P. Berrange Fix potential use of uninitialized value in virDomainGetVcpuPinInfo The virDomainGetVcpuPinInfo python wrapper had a potential use of uninitialized values 2013-09-10 Oskari Saarenmaa docs, comments: minor typo fixes 2013-09-04 Eric Blake build: enforce makefile conditional style Automake has builtin support to prevent botched conditional nesting, but only if you use: if FOO else !FOO endif !FOO An example error message when using the wrong name: daemon/Makefile.am:378: error: else reminder (LIBVIRT_INIT_SCRIPT_SYSTEMD_TRUE) incompatible with current conditional: LIBVIRT_INIT_SCRIPT_SYSTEMD_FALSE daemon/Makefile.am:381: error: endif reminder (LIBVIRT_INIT_SCRIPT_SYSTEMD_TRUE) incompatible with current conditional: LIBVIRT_INIT_SCRIPT_SYSTEMD_FALSE As our makefiles tend to have quite a bit of nested conditionals, it's better to take advantage of the benefits of the build system double-checking that our conditionals are well-nested, but that requires a syntax check to enforce our usage style. Alas, unlike C preprocessor and spec files, we can't use indentation to make it easier to see how deeply nesting goes. * cfg.mk (sc_makefile_conditionals): New rule. * daemon/Makefile.am: Enforce the style. * gnulib/tests/Makefile.am: Likewise. * python/Makefile.am: Likewise. * src/Makefile.am: Likewise. * tests/Makefile.am: Likewise. * tools/Makefile.am: Likewise. 2013-09-03 Ján Tomko Fix leaks in python bindings https://bugzilla.redhat.com/show_bug.cgi?id=1003828 2013-08-29 Guan Qiang python: Fix a PyList usage mistake Fix PyList usage mistake in Function libvirt_lxc_virDomainLxcOpenNamespace. https://bugzilla.redhat.com/show_bug.cgi?id=1002383 2013-08-23 Claudio Bley python: simplify complicated conditional assignment 2013-08-23 Claudio Bley Test for object identity when checking for None in Python Consistently use "is" or "is not" to compare variables to None, because doing so is preferrable, as per PEP 8 (http://www.python.org/dev/peps/pep-0008/#programming-recommendations): > Comparisons to singletons like None should always be done with is or > is not, never the equality operators. 2013-08-22 Guido Günther python: Use RELRO_LDFLAGS and NO_INDIRECT_LDFLAGS A readonly GOT and detecting indirect linkage is useful here too. 2013-07-30 Daniel P. Berrange Delete obsolete / unused python test files The python/tests directory contains a number of so called "tests" for the python API. These are all hardcoded to look for Xen and cannot be run in any automated fashion, and no one is ever manually running them. Given that they don't meaningully contribute to the test coverage, delete them. For some reason these tests were also copied into the filesystem as part of 'make install'. The change to the RPM in commit 3347a4203278ec93d7b0ceb88b5ed10e4f14765c caused a build failure, since it removed the code which deleted these installed tests. 2013-07-29 Cole Robinson python: Drop TODO File hasn't been really touched for 7 years. And with recent rawhide changes it contributed to an RPM build failure. Let's drop it. This also removes installation of a libvirt-python doc dir, so drop handling of it from the RPM spec. 2013-07-19 Eric Blake maint: split long lines in Makefiles Makefiles are another easy file to enforce line limits. Mostly straightforward; interesting tricks worth noting: src/Makefile.am: $(confdir) was already defined, use it in more places tests/Makefile.am: path_add and VG required some interesting compression * cfg.mk (sc_prohibit_long_lines): Add another test. * Makefile.am: Fix offenders. * daemon/Makefile.am: Likewise. * docs/Makefile.am: Likewise. * python/Makefile.am: Likewise. * src/Makefile.am: Likewise. * tests/Makefile.am: Likewise. 2013-07-18 Jiri Denemark Add VIR_DOMAIN_EVENT_ID_DEVICE_REMOVED event 2013-07-18 Daniel P. Berrange Introduce new domain create APIs to pass pre-opened FDs to LXC With container based virt, it is useful to be able to pass pre-opened file descriptors to the container init process. This allows for containers to be auto-activated from incoming socket connections, passing the active socket into the container. To do this, introduce a pair of new APIs, virDomainCreateXMLWithFiles and virDomainCreateWithFiles, which accept an array of file descriptors. For the LXC driver, UNIX file descriptor passing will be used to send them to libvirtd, which will them pass them down to libvirt_lxc, which will then pass them to the container init process. This will only be implemented for LXC right now, but the design is generic enough it could work with other hypervisors, hence I suggest adding this to libvirt.so, rather than libvirt-lxc.so 2013-07-15 Guannan Ren python: return dictionary without value in case of no blockjob Currently, when there is no blockjob, dom.blockJobInfo('vda') still reports error because it doesn't distinguish return value 0 from -1. libvirt.libvirtError: virDomainGetBlockJobInfo() failed virDomainGetBlockJobInfo() API return value: -1 in case of failure, 0 when nothing found, 1 found. And use PyDict_SetItemString instead of PyDict_SetItem when key is of string type. PyDict_SetItemString increments key/value reference count, so call Py_DECREF() for value. For key, we don't need to do this, because PyDict_SetItemString will handle it internally. 2013-07-10 Daniel P. Berrange Convert 'int i' to 'size_t i' in python/ files Convert the type of loop iterators named 'i', 'j', k', 'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or 'unsigned int', also santizing 'ii', 'jj', 'kk' to use the normal 'i', 'j', 'k' naming 2013-07-10 Michal Privoznik viralloc: Report OOM error on failure Similarly to VIR_STRDUP, we want the OOM error to be reported in VIR_ALLOC and friends. 2013-06-24 Jiri Denemark python: Add bindings for extensible migration APIs The patch implements wrappers for virDomainMigrate3 and virDomainMigrateToURI3. 2013-06-24 Jiri Denemark Extensible migration APIs This patch introduces two new APIs virDomainMigrate3 and virDomainMigrateToURI3 that may be used in place of their older variants. These new APIs take optional migration parameters (such as bandwidth, domain XML, ...) in an array of virTypedParameters, which makes adding new parameters easier as there's no need to introduce new APIs whenever a new migration parameter needs to be added. Both APIs are backward compatible and will automatically use older migration calls in case the new calls are not supported as long as the typed parameters array does not contain any parameter which was not supported by the older calls. 2013-05-28 Eric Blake syntax: prefer space after semicolon in for loop I noticed several unusual spacings in for loops, and decided to fix them up. See the next commit for the syntax check that found all of these. * examples/domsuspend/suspend.c (main): Fix spacing. * python/libvirt-override.c: Likewise. * src/conf/interface_conf.c: Likewise. * src/security/virt-aa-helper.c: Likewise. * src/util/virconf.c: Likewise. * src/util/virhook.c: Likewise. * src/util/virlog.c: Likewise. * src/util/virsocketaddr.c: Likewise. * src/util/virsysinfo.c: Likewise. * src/util/viruuid.c: Likewise. * src/vbox/vbox_tmpl.c: Likewise. * src/xen/xen_hypervisor.c: Likewise. * tools/virsh-domain-monitor.c (vshDomainStateToString): Drop default case, to let compiler check us. * tools/virsh-domain.c (vshDomainVcpuStateToString): Likewise. 2013-05-21 Osier Yang python: Remove the whitespace before ";" 2013-05-20 Eric Blake maint: use LGPL correctly Several files called out COPYING or COPYING.LIB instead of using the normal boilerplate. It's especially important that we don't call out COPYING from an LGPL file, since COPYING is traditionally used for the GPL. A few files were lacking copyright altogether. * src/rpc/gendispatch.pl: Add missing copyright. * Makefile.nonreentrant: Likewise. * src/check-symfile.pl: Likewise. * src/check-symsorting.pl: Likewise. * src/driver.h: Likewise. * src/internal.h: Likewise. * tools/libvirt-guests.sh.in: Likewise. * tools/virt-pki-validate.in: Mention copyright in comment, not just code. * tools/virt-sanlock-cleanup.in: Likewise. * src/rpc/genprotocol.pl: Spell out license terms. * src/xen/xend_internal.h: Likewise. * src/xen/xend_internal.c: Likewise. * Makefile.am: Likewise. * daemon/Makefile.am: Likewise. * docs/Makefile.am: Likewise. * docs/schemas/Makefile.am: Likewise. * examples/apparmor/Makefile.am: Likewise. * examples/domain-events/events-c/Makefile.am: Likewise. * examples/dominfo/Makefile.am: Likewise. * examples/domsuspend/Makefile.am: Likewise. * examples/hellolibvirt/Makefile.am: Likewise. * examples/openauth/Makefile.am: Likewise. * examples/python/Makefile.am: Likewise. * examples/systemtap/Makefile.am: Likewise. * examples/xml/nwfilter/Makefile.am: Likewise. * gnulib/lib/Makefile.am: Likewise. * gnulib/tests/Makefile.am: Likewise. * include/Makefile.am: Likewise. * include/libvirt/Makefile.am: Likewise. * python/Makefile.am: Likewise. * python/tests/Makefile.am: Likewise. * src/Makefile.am: Likewise. * tests/Makefile.am: Likewise. * tools/Makefile.am: Likewise. * configure.ac: Likewise. 2013-05-09 Daniel P. Berrange Fix build of python bindings on Python 2.4 The PyDict_Next method on Python <= 2.4 used 'int' instead of "Py_ssize_t" for the 'pos' parameter 2013-05-06 Eric Blake build: clean up stray files found by 'make distcheck' 'make distcheck' complained: ERROR: files left in build directory after distclean: ./python/libvirt.pyc ./tests/commandhelper.log Problems introduced in commits f015495 and 25ea8e4 (both v1.0.3). * tests/commandtest.c (test21): Check (and clean) log file. * tests/commanddata/test21.log: New file. * python/Makefile.am (CLEANFILES): Clean up compiled python files. 2013-05-02 Eric Blake build: always include sanitytest in tarball The libvirt 1.0.5 tarball is missing a file which renders 'make check' broken; first reported on list by Guido Günther. * python/Makefile.am (EXTRA_DIST): Hoist sanitytest.py out of HAVE_PYTHON conditional. 2013-05-02 Michal Privoznik virutil: Move string related functions to virstring.c The source code base needs to be adapted as well. Some files include virutil.h just for the string related functions (here, the include is substituted to match the new file), some include virutil.h without any need (here, the include is removed), and some require both. 2013-04-19 Eric Blake docs: fix usage of 'onto' http://www.uhv.edu/ac/newsletters/writing/grammartip2009.07.01.htm (and several other sites) give hints that 'onto' is best used if you can also add 'up' just before it and still make sense. In many cases in the code base, we really want the two-word form, or even a simplification to just 'on' or 'to'. * docs/hacking.html.in: Use correct 'on to'. * python/libvirt-override.c: Likewise. * src/lxc/lxc_controller.c: Likewise. * src/util/virpci.c: Likewise. * daemon/THREADS.txt: Use simpler 'on'. * docs/formatdomain.html.in: Better usage. * docs/internals/rpc.html.in: Likewise. * src/conf/domain_event.c: Likewise. * src/rpc/virnetclient.c: Likewise. * tests/qemumonitortestutils.c: Likewise. * HACKING: Regenerate. 2013-04-18 Osier Yang syntax-check: Only allows to include public headers in external tools With this patch, include public headers in "" form is only allowed for "internal.h". And only the external tools (examples|tools|python |include/libvirt) can include the public headers in <> form. 2013-03-26 Guannan Ren python: set default value to optional arguments When prefixing with string (optional) or optional in the description of arguments to libvirt C APIs, in python, these arguments will be set as optional arugments, for example: * virDomainSaveFlags: * @domain: a domain object * @to: path for the output file * @dxml: (optional) XML config for adjusting guest xml used on restore * @flags: bitwise-OR of virDomainSaveRestoreFlags the corresponding python APIs is restoreFlags(self, frm, dxml=None, flags=0) The following python APIs are changed to: blockCommit(self, disk, base, top, bandwidth=0, flags=0) blockPull(self, disk, bandwidth=0, flags=0) blockRebase(self, disk, base, bandwidth=0, flags=0) migrate(self, dconn, flags=0, dname=None, uri=None, bandwidth=0) migrate2(self, dconn, dxml=None, flags=0, dname=None, uri=None, bandwidth=0) migrateToURI(self, duri, flags=0, dname=None, bandwidth=0) migrateToURI2(self, dconnuri=None, miguri=None, dxml=None, flags=0, \ dname=None, bandwidth=0) saveFlags(self, to, dxml=None, flags=0) migrate(self, domain, flags=0, dname=None, uri=None, bandwidth=0) migrate2(self, domain, dxml=None, flags=0, dname=None, uri=None, bandwidth=0) restoreFlags(self, frm, dxml=None, flags=0) 2013-03-22 Guannan Ren python:remove semicolon in python code This breaked "make syntax-check" testing Pushed under trivial rule 2013-03-22 Guannan Ren make: regenerate bindings when .py changes 2013-03-22 Guannan Ren python: treat flags as default argument with value 0 The following four functions have not changed because default arguments have to come after positional arguments. Changing them will break the the binding APIs. migrate(self, dconn, flags, dname, uri, bandwidth): migrate2(self, dconn, dxml, flags, dname, uri, bandwidth): migrateToURI(self, duri, flags, dname, bandwidth): migrateToURI2(self, dconnuri, miguri, dxml, flags, dname, bandwidth): 2013-03-21 Peter Krempa python: Fix emulatorpin API bindings The addition of emulator pinning APIs didn't think of doing the right job with python APIs for them. The default generator produced unusable code for this. This patch switches to proper code as in the case of domain Vcpu pining. This change can be classified as a python API-breaker but in the state the code was before I doubt anyone was able to use it successfully. 2013-03-21 Guannan Ren python: fix bindings that don't raise an exception For example: >>> dom.memoryStats() libvir: QEMU Driver error : Requested operation is not valid:\ domain is not running There are six such python API functions like so. The root reason is that generator.py script checks the type of return value of a python stub function defined in libvirt-api.xml or libvirt-override-api.xml to see whether to add the raise clause or not in python wrapper code in libvirt.py. The type of return value is supposed to be C types. For those stub functions which return python non-integer data type like string, list, tuple, dictionary, the existing type in functions varies from each other which leads problem like this. Currently, in generator.py, it maintains a buggy whitelist for stub functions returning a list type. I think it is easy to forget adding new function name in the whitelist. This patch makes the value of type consistent with C type "char *" in libvirt-override-api.xml. For python, any of types could be printed as string, so I choose "char *" in this case. And the comment in xml could explain it when adding new function definition. ... - + ... 2013-03-13 Daniel P. Berrange Apply security label when entering LXC namespaces Add a new virDomainLxcEnterSecurityLabel() function as a counterpart to virDomainLxcEnterNamespaces(), which can change the current calling process to have a new security context. This call runs client side, not in libvirtd so we can't use the security driver infrastructure. When entering a namespace, the process spawned from virsh will default to running with the security label of virsh. The actual desired behaviour is to run with the security label of the container most of the time. So this changes virsh lxc-enter-namespace command to invoke the virDomainLxcEnterSecurityLabel method. The current behaviour is: LABEL PID TTY TIME CMD system_u:system_r:svirt_lxc_net_t:s0:c0.c1023 1 pts/0 00:00:00 systemd system_u:system_r:svirt_lxc_net_t:s0:c0.c1023 3 pts/1 00:00:00 sh system_u:system_r:svirt_lxc_net_t:s0:c0.c1023 24 ? 00:00:00 systemd-journal system_u:system_r:svirt_lxc_net_t:s0:c0.c1023 29 ? 00:00:00 dhclient staff_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 47 ? 00:00:00 ps Note the ps command is running as unconfined_t, After this patch, The new behaviour is this: virsh -c lxc:/// lxc-enter-namespace dan -- /bin/ps -eZ LABEL PID TTY TIME CMD system_u:system_r:svirt_lxc_net_t:s0:c0.c1023 1 pts/0 00:00:00 systemd system_u:system_r:svirt_lxc_net_t:s0:c0.c1023 3 pts/1 00:00:00 sh system_u:system_r:svirt_lxc_net_t:s0:c0.c1023 24 ? 00:00:00 systemd-journal system_u:system_r:svirt_lxc_net_t:s0:c0.c1023 32 ? 00:00:00 dhclient system_u:system_r:svirt_lxc_net_t:s0:c0.c1023 38 ? 00:00:00 ps The '--noseclabel' flag can be used to skip security labelling. 2013-03-01 Guannan Ren python: fix fd leak in generator.py 2013-03-01 Guannan Ren python: fix typoes and repeated global vars references 2013-02-22 Jiri Denemark python: Implement virDomainMigrateGetCompressionCache wrapper 2013-02-22 Jiri Denemark Introduce virDomainMigrate*CompressionCache APIs Introduce virDomainMigrateGetCompressionCache and virDomainMigrateSetCompressionCache APIs. 2013-02-22 Jiri Denemark python: Implement virDomainGetJobStats wrapper 2013-02-22 Jiri Denemark Introduce virDomainGetJobStats API This is an extensible version of virDomainGetJobInfo. 2013-02-11 Guido Günther Check if classes are derived from object This makes sure we don't regress to old style classes 2013-02-07 Guido Günther Remove more trailing semicolons in Python files 2013-02-07 Guido Günther Cosmetics: Remove semicolons It's Python, not C 2013-02-05 Jiri Denemark sanitytest.py: Do not rely on system libvirt When running sanitytest.py we should not rely on libvirt library installed on the system. And since we generate a nice wrapper called "run" that sets both PYTHON_PATH and LD_LIBRARY_PATH, we should just use it rather than trying to duplicate it in the Makefile. 2013-02-05 Daniel P. Berrange Fix missing error constants in libvirt python module The previous change to the generator, changed too much - only the functions are in 'virerror.c', the constants remained in 'virerror.h' which could not be renamed for API compat reasons. Add a test case to sanity check the generated python bindings 2013-01-31 Serge Hallyn complete virterror->virerror name change Without these two string changes in generator.py, the virGetLastError wrapper does not get created in /usr/share/pyshared/libvirt.py. Noticed when running tests with virt-install. 2013-01-24 Jiri Denemark python: Fix bindings for virDomainSnapshotGet{Domain,Connect} https://bugzilla.redhat.com/show_bug.cgi?id=895882 virDomainSnapshot.getDomain() and virDomainSnapshot.getConnect() wrappers around virDomainSnapshotGet{Domain,Connect} were not supposed to be ever implemented. The class should contain proper domain() and connect() accessors that fetch python objects stored internally within the class. While domain() was already provided, connect() was missing. This patch adds connect() method to virDomainSnapshot class and reimplements getDomain() and getConnect() methods as aliases to domain() and connect() for backward compatibility. 2013-01-24 Daniel P. Berrange Make python objects inherit from 'object' base class As of python >= 2.2, it is recommended that all objects inherit from the 'object' base class. We already require python >= 2.3 for libvirt for thread macro support, so we should follow this best practice. See also http://stackoverflow.com/questions/4015417/python-class-inherits-object 2013-01-18 Jiri Denemark Introduce virTypedParamsClear public API The function is just a renamed public version of former virTypedParameterArrayClear. 2013-01-18 Jiri Denemark Add virTypedParams* APIs Working with virTypedParameters in clients written in C is ugly and requires all clients to duplicate the same code. This set of APIs makes this code for manipulating with virTypedParameters integral part of libvirt so that all clients may benefit from it. 2013-01-17 Jiri Denemark python: Avoid freeing uninitialized new_params pointer 2013-01-14 Daniel P. Berrange Fix build due to previous LXC patch Mark virDomainLxcEnterNamespace as skipped in python binding and remove reference to lxcDomainOpenNamespace which doesn't arrive until a later patch 2013-01-14 Daniel P. Berrange Introduce an LXC specific public API & library This patch introduces support for LXC specific public APIs. In common with what was done for QEMU, this creates a libvirt_lxc.so library and libvirt/libvirt-lxc.h header file. The actual APIs are int virDomainLxcOpenNamespace(virDomainPtr domain, int **fdlist, unsigned int flags); int virDomainLxcEnterNamespace(virDomainPtr domain, unsigned int nfdlist, int *fdlist, unsigned int *noldfdlist, int **oldfdlist, unsigned int flags); which provide a way to use the setns() system call to move the calling process into the container's namespace. It is not practical to write in a generically applicable manner. The nearest that we could get to such an API would be an API which allows to pass a command + argv to be executed inside a container. Even if we had such a generic API, this LXC specific API is still useful, because it allows the caller to maintain the current process context, in particular any I/O streams they have open. NB the virDomainLxcEnterNamespace() API is special in that it runs client side, so does not involve the internal driver API. 2012-12-28 Michal Privoznik python: Adapt to virevent rename With our recent renames under src/util/* we forgot to adapt python wrapper code generator. This results in some methods being not exposed: $ python examples/domain-events/events-python/event-test.py Using uri:qemu:///system Traceback (most recent call last): File "examples/domain-events/events-python/event-test.py", line 585, in main() File "examples/domain-events/events-python/event-test.py", line 543, in main virEventLoopPureStart() File "examples/domain-events/events-python/event-test.py", line 416, in virEventLoopPureStart virEventLoopPureRegister() File "examples/domain-events/events-python/event-test.py", line 397, in virEventLoopPureRegister libvirt.virEventRegisterImpl(virEventAddHandleImpl, AttributeError: 'module' object has no attribute 'virEventRegisterImpl' 2012-12-21 Daniel P. Berrange Rename util.{c,h} to virutil.{c,h} 2012-12-21 Daniel P. Berrange Rename memory.{c,h} to viralloc.{c,h} 2012-12-04 Osier Yang Fix the indention Introduced by commit 1465876a, pushed under build-breaker && trivial rule. 2012-12-04 Daniel P. Berrange Bind connection close callback APIs to python binding Add code in the python binding to cope with the new APIs virConnectRegisterCloseCallback and virConnectUnregisterCloseCallback. Also demonstrate their use in the python domain events demo 2012-11-15 Viktor Mihajlovski python: Use virNodeGetCPUMap where possible Modified the places where virNodeGetInfo was used for the purpose of obtaining the maximum node CPU number. Transparently falling back to virNodeGetInfo in case of failure. Wrote a utility function getPyNodeCPUCount for that purpose. 2012-11-02 Daniel P. Berrange Remove spurious whitespace between function name & open brackets The libvirt coding standard is to use 'function(...args...)' instead of 'function (...args...)'. A non-trivial number of places did not follow this rule and are fixed in this patch. 2012-10-25 Eric Blake maint: consistent whitespace after 'if' Noticed during the review of the previous patch. * python/libvirt-override.c: Use space between 'if ('. 2012-10-25 Viktor Mihajlovski virNodeGetCPUMap: Add python binding Added a method getCPUMap to virConnect. It can be used as follows: import libvirt import sys import os conn = libvirt.openReadOnly(None) if conn == None: print 'Failed to open connection to the hypervisor' sys.exit(1) try: (cpus, cpumap, online) = conn.getCPUMap(0) except: print 'Failed to extract the node cpu map information' sys.exit(1) print 'CPUs total %d, online %d' % (cpus, online) print 'CPU map %s' % str(cpumap) del conn print "OK" sys.exit(0) 2012-10-24 Viktor Mihajlovski virNodeGetCPUMap: Define public API. Adding a new API to obtain information about the host node's present, online and offline CPUs. int virNodeGetCPUMap(virConnectPtr conn, unsigned char **cpumap, unsigned int *online, unsigned int flags); The function will return the number of CPUs present on the host or -1 on failure; If cpumap is non-NULL virNodeGetCPUMap will allocate an array containing a bit map representation of the online CPUs. It's the callers responsibility to deallocate cpumap using free(). If online is non-NULL, the variable pointed to will contain the number of online host node CPUs. The variable flags has been added to support future extensions and must be set to 0. Extend the driver structure by nodeGetCPUMap entry in support of the new API virNodeGetCPUMap. Added implementation of virNodeGetCPUMap to libvirt.c 2012-10-15 Martin Kletzander Add support for SUSPEND_DISK event This patch adds support for SUSPEND_DISK event; both lifecycle and separated. The support is added for QEMU, machines are changed to PMSUSPENDED, but as QEMU sends SHUTDOWN afterwards, the state changes to shut-off. This and much more needs to be done in order for libvirt to work with transient devices, wake-ups etc. This patch is not aiming for that functionality. 2012-10-13 Guido Günther Properly parse (unsigned) long long This fixes problems on platforms where sizeof(long) != sizeof(long long) like ia32. 2012-10-08 Guannan Ren python: keep consistent handling of Python integer conversion libvirt_ulonglongUnwrap requires the integer type of python obj. But libvirt_longlongUnwrap still could handle python obj of Pyfloat_type which causes the float value to be rounded up to an integer. For example >>> dom.setSchedulerParameters({'vcpu_quota': 0.88}) 0 libvirt_longlongUnwrap treats 0.88 as a valid value 0 However >>> dom.setSchedulerParameters({'cpu_shares': 1000.22}) libvirt_ulonglongUnwrap will throw out an error "TypeError: an integer is required" The patch make this consistent. 2012-10-08 Guannan Ren python: cleanup vcpu related binding APIs libvirt_virDomainGetVcpus: add error handling, return -1 instead of None libvirt_virDomainPinVcpu and libvirt_virDomainPinVcpuFlags: check the type of argument make use of libvirt_boolUnwrap Set bitmap according to these values which are contained in given argument of vcpu tuple and turn off these bit corresponding to missing vcpus in argument tuple The original way ignored the error info from PyTuple_GetItem if index is out of range. "IndexError: tuple index out of range" The error message will only be raised on next command in interactive mode. 2012-09-28 Guannan Ren python: return error if PyObject obj is NULL for unwrapper helper functions The result is indeterminate for NULL argument to python functions as follows. It's better to return negative value in these situations. PyObject_IsTrue will segfault if the argument is NULL PyFloat_AsDouble(NULL) is -1.000000 PyLong_AsUnsignedLongLong(NULL) is 0.000000 2012-09-17 Osier Yang node_memory: Expose the APIs to Python bindings * python/libvirt-override-api.xml: (Add document to describe the APIs). * python/libvirt-override.c: (Implement the API wrappers manually) 2012-09-17 Osier Yang node_memory: Define the APIs to get/set memory parameters * include/libvirt/libvirt.h.in: (Add macros for the param fields, declare the APIs). * src/driver.h: (New methods for the driver struct) * src/libvirt.c: (Implement the public APIs) * src/libvirt_public.syms: (Export the public symbols) 2012-09-17 Osier Yang list: Expose virConnectListAllSecrets to Python binding The implementation is done manually as the generator does not support wrapping lists of C pointers into Python objects. python/libvirt-override-api.xml: Document python/libvirt-override-virConnect.py: Implementation for listAllSecrets. python/libvirt-override.c: Implementation for the wrapper. 2012-09-17 Osier Yang list: Define new API virConnectListAllSecrets This is to list the secret objects. Supports to filter the secrets by its storage location, and whether it's private or not. include/libvirt/libvirt.h.in: Declare enum virConnectListAllSecretFlags and virConnectListAllSecrets. python/generator.py: Skip auto-generating src/driver.h: (virDrvConnectListAllSecrets) src/libvirt.c: Implement the public API src/libvirt_public.syms: Export the symbol to public 2012-09-17 Osier Yang list: Expose virConnectListAllNWFilters to Python binding The implementation is done manually as the generator does not support wrapping lists of C pointers into Python objects. python/libvirt-override-api.xml: Document python/libvirt-override-virConnect.py: * Implementation for listAllNWFilters. python/libvirt-override.c: Implementation for the wrapper. 2012-09-17 Osier Yang list: Define new API virConnectListAllNWFilters This is to list the network filter objects. No flags are supported include/libvirt/libvirt.h.in: Declare enum virConnectListAllNWFilterFlags and virConnectListAllNWFilters. python/generator.py: Skip auto-generating src/driver.h: (virDrvConnectListAllNWFilters) src/libvirt.c: Implement the public API src/libvirt_public.syms: Export the symbol to public 2012-09-17 Osier Yang list: Expose virConnectListAllNodeDevices to Python binding The implementation is done manually as the generator does not support wrapping lists of C pointers into Python objects. python/libvirt-override-api.xml: Document python/libvirt-override-virConnect.py: * Implementation for listAllNodeDevices. python/libvirt-override.c: Implementation for the wrapper. 2012-09-17 Osier Yang list: Define new API virConnectListAllNodeDevices This is to list the node device objects, supports to filter the results by capability types. include/libvirt/libvirt.h.in: Declare enum virConnectListAllNodeDeviceFlags and virConnectListAllNodeDevices. python/generator.py: Skip auto-generating src/driver.h: (virDrvConnectListAllNodeDevices) src/libvirt.c: Implement the public API src/libvirt_public.syms: Export the symbol to public 2012-09-12 Osier Yang list: Expose virConnectListAllInterfaces to Python binding The implementation is done manually as the generator does not support wrapping lists of C pointers into Python objects. python/libvirt-override-api.xml: Document python/libvirt-override-virConnect.py: * New file, includes implementation of listAllInterfaces. python/libvirt-override.c: Implementation for the wrapper. 2012-09-12 Osier Yang list: Define new API virConnectListAllInterfaces This is to list the interface objects, supported filtering flags are: active|inactive. include/libvirt/libvirt.h.in: Declare enum virConnectListAllInterfaceFlags and virConnectListAllInterfaces. python/generator.py: Skip auto-generating src/driver.h: (virDrvConnectListAllInterfaces) src/libvirt.c: Implement the public API src/libvirt_public.syms: Export the symbol to public 2012-09-11 Federico Simoncelli python: Initialize new_params in virDomainSetSchedulerParameters The new_params variable must be initialized in case the virDomainGetSchedulerParameters call fails and we hit the cleanup section before actually allocating the new parameters. 2012-09-11 Daniel P. Berrange Check against python None type when filling in auth parameters When deciding whether to provide an auth function callback in openAuth(), credcb was checked against NULL, when it really needs to be checked against Py_None 2012-09-11 Daniel P. Berrange Print any exception that occurs in authentication callback If an exception occurs in the python callback for openAuth() the stack trace isn't seen by the apps, since this code is called from libvirt context. To aid diagnostics, print the error to stderr at least 2012-09-11 Daniel P. Berrange Fix crash passing an empty list to python openAuth() API If passing a 'credtype' parameter which was an empty list to the python openAuth() API, the 'credtype' field in the virConnectAuth struct would not be initialized. This lead to a crash when later trying to free that field. 2012-09-11 Osier Yang list: Expose virConnectListAllNetworks to Python binding The implementation is done manually as the generator does not support wrapping lists of C pointers into Python objects. python/libvirt-override-api.xml: Document python/libvirt-override-virConnect.py: Implement listAllNetworks. python/libvirt-override.c: Implementation for the wrapper. 2012-09-11 Osier Yang list: Define new API virConnectListAllNetworks This is to list the network objects, supported filtering flags are: active|inactive, persistent|transient, autostart|no-autostart. include/libvirt/libvirt.h.in: Declare enum virConnectListAllNetworkFlags and virConnectListAllNetworks. python/generator.py: Skip auto-generating src/driver.h: (virDrvConnectListAllNetworks) src/libvirt.c: Implement the public API src/libvirt_public.syms: Export the symbol to public 2012-09-10 Osier Yang list: Expose virStoragePoolListAllVolumes to Python binding The implementation is done manually as the generator does not support wrapping lists of C pointers into Python objects. python/libvirt-override-api.xml: Document python/libvirt-override-virStoragePool.py: * New file, includes implementation of listAllVolumes. python/libvirt-override.c: Implementation for the wrapper. 2012-09-10 Osier Yang list: Define new API virStoragePoolListAllVolumes Simply returns the storage volume objects. No supported filter flags. include/libvirt/libvirt.h.in: Declare the API python/generator.py: Skip the function for generating. virStoragePool.py will be added in later patch. src/driver.h: virDrvStoragePoolListVolumesFlags src/libvirt.c: Implementation for the API. src/libvirt_public.syms: Export the symbol to public 2012-09-07 Jiri Denemark Fix PMSuspend and PMWakeup events The unused reason parameter of PM{Suspend,Wakeup} event callbacks was completely ignored in lot of places and those events were not actually working at all. 2012-09-06 Osier Yang python: Expose virStorageListAllStoragePools to python binding The implementation is done manually as the generator does not support wrapping lists of C pointers into Python objects. python/libvirt-override-api.xml: Document python/libvirt-override-virConnect.py: Add listAllStoragePools python/libvirt-override.c: Implementation for the wrapper. 2012-09-06 Osier Yang list: Define new API virStorageListAllStoragePools This introduces a new API to list the storage pool objects, 4 groups of flags are provided to filter the returned pools: * Active or not * Autostarting or not * Persistent or not * And the pool type. include/libvirt/libvirt.h.in: New enum virConnectListAllStoragePoolFlags; Declare the API. python/generator.py: Skip the generating src/driver.h: (virDrvConnectListAllStoragePools) src/libvirt.c: Implementation for the API. src/libvirt_public.syms: Export the symbol. 2012-08-31 Eric Blake python: don't mask libvirt errors A user reported this crash when using python bindings: File "/home/nox/workspace/NOX/src/NOX/hooks.py", line 134, in trigger hook.trigger(event) File "/home/nox/workspace/NOX/src/NOX/hooks.py", line 33, in trigger self.handlers[event]() File "/home/nox/workspace/NOX/hooks/volatility.py", line 81, in memory_dump for block in Memory(self.ctx): File "/home/see/workspace/NOX/src/NOX/lib/libtools.py", line 179, in next libvirt.VIR_MEMORY_PHYSICAL) File "/usr/lib/python2.7/dist-packages/libvirt.py", line 1759, in memoryPeek ret = libvirtmod.virDomainMemoryPeek(self._o, start, size, flags) SystemError: error return without exception set In the python bindings, returning NULL makes python think an exception was thrown, while returning the None object lets the wrappers know that a libvirt error exists. Reported by Nox DaFox, fix suggested by Dan Berrange. * python/libvirt-override.c (libvirt_virDomainBlockPeek) (libvirt_virDomainMemoryPeek): Return python's None object, so wrapper knows to check libvirt error. 2012-08-23 MATSUDA Daiki agent: add python module support Add virDomainQemuAgentCommand() support function to python module. 2012-08-23 MATSUDA Daiki agent: add virDrvDomainQemuAgentCommand prototype for drivers. Add virDrvDomainQemuAgentCommand prototype for drivers. Add virDomainQemuAgentCommand() for virDrvDomainQemuAgentCommand. 2012-08-20 Marcelo Cerri Update the remote API This patch updates libvirt's API to allow applications to inspect the full list of security labels of a domain. 2012-07-30 Peter Krempa python: Don't generate bodies for close callback functions Commit 6ed5a1b9bd6240b8f2736790e48dd1c284c2e0e1 adds close callback functions to the public API but doesn't add python implementation. This patch sets the function to be written manually (to fix the build), but doesn't implement them yet. 2012-07-14 Daniel P. Berrange Define public API for receiving guest memory balloon events When the guest changes its memory balloon applications may want to know what the new value is, without having to periodically poll on XML / domain info. Introduce a "balloon change" event to let apps see this * include/libvirt/libvirt.h.in: Define the virConnectDomainEventBalloonChangeCallback callback and VIR_DOMAIN_EVENT_ID_BALLOON_CHANGE constant * python/libvirt-override-virConnect.py, python/libvirt-override.c: Wire up helpers for new event * daemon/remote.c: Helper for serializing balloon event * examples/domain-events/events-c/event-test.c, examples/domain-events/events-python/event-test.py: Add example of balloon event usage * src/conf/domain_event.c, src/conf/domain_event.h: Handling of balloon events * src/remote/remote_driver.c: Add handler of balloon events * src/remote/remote_protocol.x: Define wire protocol for balloon events * src/remote_protocol-structs: Likewise. 2012-06-19 Eric Blake list: provide python bindings for snapshots This adds support for the new virDomainListAllSnapshots (a domain function) and virDomainSnapshotListAllChildren (a snapshot function) to the libvirt-python bindings. The implementation is done manually as the generator does not support wrapping lists of C pointers into python objects. * python/libvirt-override.c (libvirt_virDomainListAllSnapshots) (libvirt_virDomainSnapshotListAllChildren): New functions. * python/libvirt-override-api.xml: Document them. * python/libvirt-override-virDomain.py (listAllSnapshots): New file. * python/libvirt-override-virDomainSnapshot.py (listAllChildren): Likewise. * python/Makefile.am (CLASSES_EXTRA): Ship them. 2012-06-19 Eric Blake list: add virDomainListAllSnapshots API There was an inherent race between virDomainSnapshotNum() and virDomainSnapshotListNames(), where an additional snapshot could be created in the meantime, or where a snapshot could be deleted before converting the name back to a virDomainSnapshotPtr. It was also an awkward name: the function operates on domains, not domain snapshots. virDomainSnapshotListChildrenNames() suffered from the same inherent race, although its naming was nicer. This patch makes things nicer by grabbing a snapshot list atomically, in the format most useful to the user. * include/libvirt/libvirt.h.in (virDomainListAllSnapshots) (virDomainSnapshotListAllChildren): New declarations. * src/libvirt.c (virDomainSnapshotListNames) (virDomainSnapshotListChildrenNames): Add cross-references. (virDomainListAllSnapshots, virDomainSnapshotListAllChildren): New functions. * src/libvirt_public.syms (LIBVIRT_0.9.13): Export them. * src/driver.h (virDrvDomainListAllSnapshots) (virDrvDomainSnapshotListAllChildren): New callbacks. * python/generator.py (skip_function): Prepare for later hand-written versions. 2012-06-18 Peter Krempa python: add API exports for virConnectListAllDomains() This patch adds export of the new API function virConnectListAllDomains() to the libvirt-python bindings. The virConnect object now has method "listAllDomains" that takes only the flags parameter and returns a python list of virDomain object corresponding to virDomainPtrs returned by the underlying api. The implementation is done manually as the generator does not support wrapping list of virDomainPtrs into virDomain objects. 2012-06-18 Peter Krempa lib: Add public api to enable atomic listing of guest This patch adds a new public api that lists domains. The new approach is different from those used before. There are key points to this: 1) The list is acquired atomically and contains both active and inactive domains (guests). This eliminates the need to call two different list APIs, where the state might change in between the calls. 2) The returned list consists of virDomainPtrs instead of names or ID's that have to be converted to virDomainPtrs anyways using separate calls for each one of them. This is more convenient and saves hypervisor calls. 3) The returned list is auto-allocated. This saves a lot of hassle for the users. 4) Built in support for filtering. The API call supports various filtering flags that modify the output list according to user needs. Available filter groups: Domain status: VIR_CONNECT_LIST_DOMAINS_ACTIVE, VIR_CONNECT_LIST_DOMAINS_INACTIVE Domain persistence: VIR_CONNECT_LIST_DOMAINS_PERSISTENT, VIR_CONNECT_LIST_DOMAINS_TRANSIENT Domain state: VIR_CONNECT_LIST_DOMAINS_RUNNING, VIR_CONNECT_LIST_DOMAINS_PAUSED, VIR_CONNECT_LIST_DOMAINS_SHUTOFF, VIR_CONNECT_LIST_DOMAINS_OTHER Existence of managed save image: VIR_CONNECT_LIST_DOMAINS_MANAGEDSAVE, VIR_CONNECT_LIST_DOMAINS_NO_MANAGEDSAVE Auto-start option: VIR_CONNECT_LIST_DOMAINS_AUTOSTART, VIR_CONNECT_LIST_DOMAINS_NO_AUTOSTART Existence of snapshot: VIR_CONNECT_LIST_DOMAINS_HAS_SNAPSHOT, VIR_CONNECT_LIST_DOMAINS_NO_SNAPSHOT 5) The python binding returns a list of domain objects that is very neat to work with. The only problem with this approach is no support from code generators so both RPC code and python bindings had to be written manually. *include/libvirt/libvirt.h.in: - add API prototype - clean up whitespace mistakes nearby *python/generator.py: - inhibit generation of the bindings for the new api *src/driver.h: - add driver prototype - clean up some whitespace mistakes nearby *src/libvirt.c: - add public implementation *src/libvirt_public.syms: - export the new symbol 2012-06-12 Eric Blake python: fix snapshot listing bugs Python exceptions are different than libvirt errors, and we had some corner case bugs on OOM situations. * python/libvirt-override.c (libvirt_virDomainSnapshotListNames) (libvirt_virDomainSnapshotListChildrenNames): Use correct error returns, avoid segv on OOM, and avoid memory leaks on error. 2012-06-12 Eric Blake python: use simpler methods * python/libvirt-override.c (libvirt_virDomainGetVcpus) (libvirt_virDomainGetVcpuPinInfo): Use Py_XDECREF instead of open-coding it. 2012-05-04 Osier Yang Coverity: Fix the forward_null error in Python binding codes Related coverity log: Error: FORWARD_NULL: /builddir/build/BUILD/libvirt-0.9.10/python/libvirt-override.c:355: assign_zero: Assigning: "params" = 0. /builddir/build/BUILD/libvirt-0.9.10/python/libvirt-override.c:458: var_deref_model: Passing null variable "params" to function "getPyVirTypedParameter", which dereferences it. (The dereference is assumed on the basis of the 'nonnull' parameter attribute.) 2012-04-27 Cole Robinson python: Fix doc directory name for stable releases We were using the libvirt release version (like 0.9.11) and not the configure version (which for stable releases is 0.9.11.X) Most other places got this right so hopefully that's all the fallout from the version format change :) 2012-04-10 Stefan Berger Fix compilation error on 32bit Below code failed to compile on a 32 bit machine with error typewrappers.c: In function 'libvirt_intUnwrap': typewrappers.c:135:5: error: logical 'and' of mutually exclusive tests is always false [-Werror=logical-op] cc1: all warnings being treated as errors The patch fixes this error. 2012-03-31 Eric Blake python: improve conversion validation Laszlo Ersek pointed out that in trying to convert a long to an unsigned int, we used: long long_val = ...; if ((unsigned int)long_val == long_val) According to C99 integer promotion rules, the if statement is equivalent to: (unsigned long)(unsigned int)long_val == (unsigned long)long_val since you get an unsigned comparison if at least one side is unsigned, using the largest rank of the two sides; but on 32-bit platforms, where unsigned long and unsigned int are the same size, this comparison is always true and ends up converting negative long_val into posigive unsigned int values, rather than rejecting the negative value as we had originally intended (python longs are unbounded size, and we don't want to do silent modulo arithmetic when converting to C code). Fix this by using direct comparisons, rather than casting. * python/typewrappers.c (libvirt_intUnwrap, libvirt_uintUnwrap) (libvirt_ulongUnwrap, libvirt_ulonglongUnwrap): Fix conversion checks. 2012-03-28 Guannan Ren python: make python APIs use these helper functions *setPyVirTypedParameter *libvirt_virDomainGetCPUStats 2012-03-28 Guannan Ren python: Add new helper functions for python to C integral conversion int libvirt_intUnwrap(PyObject *obj, int *val); int libvirt_uintUnwrap(PyObject *obj, unsigned int *val); int libvirt_longUnwrap(PyObject *obj, long *val); int libvirt_ulongUnwrap(PyObject *obj, unsigned long *val); int libvirt_longlongUnwrap(PyObject *obj, long long *val); int libvirt_ulonglongUnwrap(PyObject *obj, unsigned long long *val); int libvirt_doubleUnwrap(PyObject *obj, double *val); int libvirt_boolUnwrap(PyObject *obj, bool *val); 2012-03-26 Martin Kletzander Cleanup for a return statement in source files Return statements with parameter enclosed in parentheses were modified and parentheses were removed. The whole change was scripted, here is how: List of files was obtained using this command: git grep -l -e '\ Add support for the suspend event This patch introduces a new event type for the QMP event SUSPEND: VIR_DOMAIN_EVENT_ID_PMSUSPEND The event doesn't take any data, but considering there might be reason for wakeup in future, the callback definition is: typedef void (*virConnectDomainEventSuspendCallback)(virConnectPtr conn, virDomainPtr dom, int reason, void *opaque); "reason" is unused currently, always passes "0". 2012-03-23 Osier Yang Add support for the wakeup event This patch introduces a new event type for the QMP event WAKEUP: VIR_DOMAIN_EVENT_ID_PMWAKEUP The event doesn't take any data, but considering there might be reason for wakeup in future, the callback definition is: typedef void (*virConnectDomainEventWakeupCallback)(virConnectPtr conn, virDomainPtr dom, int reason, void *opaque); "reason" is unused currently, always passes "0". 2012-03-23 Osier Yang Add support for event tray moved of removable disks This patch introduces a new event type for the QMP event DEVICE_TRAY_MOVED, which occurs when the tray of a removable disk is moved (i.e opened or closed): VIR_DOMAIN_EVENT_ID_TRAY_CHANGE The event's data includes the device alias and the reason for tray status' changing, which indicates why the tray status was changed. Thus the callback definition for the event is: enum { VIR_DOMAIN_EVENT_TRAY_CHANGE_OPEN = 0, VIR_DOMAIN_EVENT_TRAY_CHANGE_CLOSE, \#ifdef VIR_ENUM_SENTINELS VIR_DOMAIN_EVENT_TRAY_CHANGE_LAST \#endif } virDomainEventTrayChangeReason; typedef void (*virConnectDomainEventTrayChangeCallback)(virConnectPtr conn, virDomainPtr dom, const char *devAlias, int reason, void *opaque); 2012-03-22 Guannan Ren python: add virDomainGetCPUStats python binding API dom.getCPUStats(True, 0) [{'cpu_time': 24699446159L, 'system_time': 10870000000L, 'user_time': 950000000L}] dom.getCPUStats(False, 0) [{'cpu_time': 8535292289L}, {'cpu_time': 1005395355L}, {'cpu_time': 9351766377L}, {'cpu_time': 5813545649L}] *generator.py Add a new naming rule *libvirt-override-api.xml The API function description *libvirt-override.c Implement it. 2012-03-22 Alex Jia python: Avoid memory leaks on libvirt_virNodeGetCPUStats Detected by valgrind. Leaks are introduced in commit 4955602. * python/libvirt-override.c (libvirt_virNodeGetCPUStats): fix memory leaks and improve codes return value. For details, please see the following link: RHBZ: https://bugzilla.redhat.com/show_bug.cgi?id=770943 2012-03-21 Alex Jia python: Avoid memory leaks on libvirt_virNodeGetMemoryStats Detected by valgrind. Leaks are introduced in commit 17c7795. * python/libvirt-override.c (libvirt_virNodeGetMemoryStats): fix memory leaks and improve codes return value. For details, please see the following link: RHBZ: https://bugzilla.redhat.com/show_bug.cgi?id=770944 2012-03-20 Eric Blake python: always include config.h first On RHEL 5.7, I got this compilation failure: In file included from /usr/include/python2.4/pyport.h:98, from /usr/include/python2.4/Python.h:55, from libvirt.c:3: ../gnulib/lib/time.h:468: error: expected ';', ',' or ')' before '__timer' Turns out that our '#define restrict __restrict' from config.h wasn't being picked up. Gnulib _requires_ that all .c files include first, otherwise the gnulib header overrides tend to misbehave. Problem introduced by patch c700613b8. * python/generator.py (buildStubs): Include first. 2012-02-16 Alex Jia python: Expose virDomain{G,S}etInterfaceParameters APIs in python binding The v4 patch corrects indentation issues. The v3 patch follows latest python binding codes and change 'size' type from int to Py_ssize_t. An simple example to show how to use it: #!/usr/bin/env python import libvirt conn = libvirt.open(None) dom = conn.lookupByName('foo') print dom.interfaceParameters('vnet0', 0) params = {'outbound.peak': 10, 'inbound.peak': 10, 'inbound.burst': 20, 'inbound.average': 20, 'outbound.average': 30, 'outbound.burst': 30} print dom.setInterfaceParameters('vnet0', params, 0) print dom.interfaceParameters('vnet0', 0) 2012-02-11 Guannan Ren python: make other APIs share common {get, set}PyVirTypedParameter *libvirt_virDomainBlockStatsFlags *libvirt_virDomainGetSchedulerParameters *libvirt_virDomainGetSchedulerParametersFlags *libvirt_virDomainSetSchedulerParameters *libvirt_virDomainSetSchedulerParametersFlags *libvirt_virDomainSetBlkioParameters *libvirt_virDomainGetBlkioParameters *libvirt_virDomainSetMemoryParameters *libvirt_virDomainGetMemoryParameters *libvirt_virDomainSetBlockIoTune *libvirt_virDomainGetBlockIoTune 2012-02-09 Guannan Ren python: refactoring virTypedParameter conversion for NUMA tuning APIs *getPyVirTypedParameter *setPyVirTypedParameter *virDomainSetNumaParameters *virDomainGetNumaParameters 2012-02-09 Osier Yang python: Correct arguments number for migrateSetMaxSpeed The API definition accepts "flags" argument, however, the implementation ignores it, though "flags" is unused currently, we should expose it instead of hard coding, the API implementation inside hypervisor driver is responsible to check if the passed "flags" is valid. 2012-02-08 Eric Blake python: drop unused function Gcc warned about an unused static function. * python/libvirt-qemu-override.c (py_str): Delete. 2012-02-07 Michal Privoznik pyhton: Don't link against libvirt_util.la As we already link with libvirt.la which contains libvirt_utils.la. Double linking causes global symbols to be presented twice and thus confusion. This partially reverts c700613b8d463212d142c97108b7a2352e23e559 2012-02-03 Eric Blake maint: consolidate several .gitignore files Unlike .cvsignore under CVS, git allows for ignoring nested names. We weren't very consistent where new tests were being ignored (some in .gitignore, some in tests/.gitignore), and I found it easier to just consolidate everything. * .gitignore: Subsume entries from subdirectories. * daemon/.gitignore: Delete. * docs/.gitignore: Likewise. * docs/devhelp/.gitignore: Likewise. * docs/html/.gitignore: Likewise. * examples/dominfo/.gitignore: Likewise. * examples/domsuspend/.gitignore: Likewise. * examples/hellolibvirt/.gitignore: Likewise. * examples/openauth/.gitignore: Likewise. * examples/domain-events/events-c/.gitignore: Likewise. * include/libvirt/.gitignore: Likewise. * src/.gitignore: Likewise. * src/esx/.gitignore: Likewise. * tests/.gitignore: Likewise. * tools/.gitignore: Likewise. 2012-02-03 Martin Kletzander Added missing memory reporting into python bindings Two types of memory stats were not reported by python bindings. This patch fixes both of them. 2012-02-03 Eric Blake python: use libvirt_util to avoid raw free This patch starts the process of elevating the python binding code to be on the same level as the rest of libvirt when it comes to requiring good coding styles. Statically linking against the libvirt_util library makes it much easier to write good code, rather than having to open-code and reinvent things locally. Done by global search and replace of s/free(/VIR_FREE(/, followed by hand-inspection of remaining malloc and redundant memset. * cfg.mk (exclude_file_name_regexp--sc_prohibit_raw_allocation): Remove python from exemption. * python/Makefile.am (INCLUDES): Add gnulib and src/util. Drop $(top_builddir)/$(subdir), as automake already guarantees that. (mylibs, myqemulibs): Pull in libvirt_util and gnulib. (libvirtmod_la_CFLAGS): Catch compiler warnings if configured to use -Werror. * python/typewrappers.c (libvirt_charPtrSizeWrap) (libvirt_charPtrWrap): Convert free to VIR_FREE. * python/generator.py (print_function_wrapper): Likewise. * python/libvirt-override.c: Likewise. 2012-02-03 Eric Blake python: drop redundant function I noticed some redundant code while preparing my next patch. * python/generator.py (py_types): Fix 'const char *' mapping. * python/typewrappers.h (libvirt_charPtrConstWrap): Drop. * python/typewrappers.c (libvirt_charPtrConstWrap): Delete, since it is identical to libvirt_constcharPtrWrap. 2012-02-03 Eric Blake build: clean up CPPFLAGS/INCLUDES usage Our syntax checker missed all-lower-case variables (this will be fixed by the next .gnulib update). Additionally, anywhere that we mix in-tree files with generated files, automake recommends listing builddir prior to srcdir for VPATH builds. * src/Makefile.am (*_la_CFLAGS): Favor $(top_srcdir). (INCLUDES): Likewise, and follow automake recommendations on builddir before srcdir. * python/Makefile.am (INCLUDES): Swap directory order. * tests/Makefile.am (INCLUDES): Likewise. * tools/Makefile.am (INCLUDES): Likewise. * daemon/Makefile.am (INCLUDES): Likewise. (libvirtd.init, libvirtd.service): Favor $(). * examples/hellolibvirt/Makefile.am (hellolibvirt_LDADD): Likewise. * examples/openauth/Makefile.am (openauth_LDADD): Likewise. * examples/dominfo/Makefile.am (INCLUDES): Drop dead include. * examples/domsuspend/Makefile.am (INCLUDES): Likewise. 2012-02-01 Jiri Denemark python: Add binding for virDomainGetDiskErrors 2012-02-01 Jiri Denemark virDomainGetDiskErrors public API We already provide ways to detect when a domain has been paused as a result of I/O error, but there was no way of getting the exact error or even the device that experienced it. This new API may be used for both. 2012-02-01 Alex Jia python: correct a copy-paste error * python/libvirt-override-virStream.py: fix a copy-paste error in sendAll(). 2012-01-28 KAMEZAWA Hiroyuki Add new public API virDomainGetCPUStats() add new API virDomainGetCPUStats() for getting cpu accounting information per real cpus which is used by a domain. The API is designed to allow future extensions for additional statistics. based on ideas by Lai Jiangshan and Eric Blake. * src/libvirt_public.syms: add API for LIBVIRT_0.9.10 * src/libvirt.c: define virDomainGetCPUStats() * include/libvirt/libvirt.h.in: add virDomainGetCPUStats() header * src/driver.h: add driver API * python/generator.py: add python API (as not implemented) 2012-01-28 Zeeshan Ali (Khattak) resize: add virStorageVolResize() API Add a new function to allow changing of capacity of storage volumes. Plan out several flags, even if not all of them will be implemented up front. Expose the new command via 'virsh vol-resize'. 2012-01-20 Eric Blake API: make declaration of _LAST enum values conditional Although this is a public API break, it only affects users that were compiling against *_LAST values, and can be trivially worked around without impacting compilation against older headers, by the user defining VIR_ENUM_SENTINELS before using libvirt.h. It is not an ABI break, since enum values do not appear as .so entry points. Meanwhile, it prevents users from using non-stable enum values without explicitly acknowledging the risk of doing so. See this list discussion: https://www.redhat.com/archives/libvir-list/2012-January/msg00804.html * include/libvirt/libvirt.h.in: Hide all sentinels behind LIBVIRT_ENUM_SENTINELS, and add missing sentinels. * src/internal.h (VIR_DEPRECATED): Allow inclusion after libvirt.h. (LIBVIRT_ENUM_SENTINELS): Expose sentinels internally. * daemon/libvirtd.h: Use the sentinels. * src/remote/remote_protocol.x (includes): Don't expose sentinels. * python/generator.py (enum): Likewise. * tests/cputest.c (cpuTestCompResStr): Silence compiler warning. * tools/virsh.c (vshDomainStateReasonToString) (vshDomainControlStateToString): Likewise. 2011-12-29 Hu Tao domiftune: Add API virDomain{S,G}etInterfaceParameters The APIs are used to set/get domain's network interface's parameters. Currently supported parameters are bandwidth settings. * include/libvirt/libvirt.h.in: new API and parameters definition * python/generator.py: skip the Python API generation * src/driver.h: add new entry to the driver structure * src/libvirt_public.syms: export symbols 2011-12-29 Daniel Veillard remove a static limit on max domains in python bindings * python/libvirt-override.c: remove the predefined array in the virConnectListDomainsID binding and call virConnectNumOfDomains to do a proper allocation 2011-12-29 Alex Jia python: Fix problems of virDomain{Set, Get}BlockIoTune bindings The parameter 'params' is useless for virDomainGetBlockIoTune API, and the return value type should be a virTypedParameterPtr but not integer. And "PyArg_ParseTuple" in functions libvirt_virDomain{Set,Get}BlockIoTune misses format unit for "format" argument. * libvirt-override-api.xml: Remove useless the parameter 'params' from virDomainGetBlockIoTune API, and change return value type from integer to virTypedParameterPtr. * python/libvirt-override.c: Add the missed format units. RHBZ: https://bugzilla.redhat.com/show_bug.cgi?id=770683 2011-12-20 Hu Tao add new API virDomain{G, S}etNumaParameters Set up the types for the numa functions and insert them into the virDriver structure definition. 2011-12-19 Alex Jia python: plug memory leak on libvirt_virConnectOpenAuth * Detected by valgrind. Leak introduced in commit 5ab109f. * python/libvirt-override.c: avoid memory leak on libvirt_virConnectOpenAuth. * How to reproduce? % valgrind -v --leak-check=full virt-clone --print-xml Note: it can hit the issue although options are incomplete. * Actual valgrind result: ==1801== 12 bytes in 1 blocks are definitely lost in loss record 25 of 3,270 ==1801== at 0x4A05FDE: malloc (vg_replace_malloc.c:236) ==1801== by 0xCF1F60E: libvirt_virConnectOpenAuth (libvirt-override.c:1507) ==1801== by 0x3AFEEDE7F3: PyEval_EvalFrameEx (ceval.c:3794) ==1801== by 0x3AFEEDF99E: PyEval_EvalFrameEx (ceval.c:3880) ==1801== by 0x3AFEEDF99E: PyEval_EvalFrameEx (ceval.c:3880) ==1801== by 0x3AFEEDF99E: PyEval_EvalFrameEx (ceval.c:3880) ==1801== by 0x3AFEEDF99E: PyEval_EvalFrameEx (ceval.c:3880) ==1801== by 0x3AFEEE0466: PyEval_EvalCodeEx (ceval.c:3044) ==1801== by 0x3AFEEE0541: PyEval_EvalCode (ceval.c:545) ==1801== by 0x3AFEEFB88B: run_mod (pythonrun.c:1351) ==1801== by 0x3AFEEFB95F: PyRun_FileExFlags (pythonrun.c:1337) ==1801== by 0x3AFEEFCE4B: PyRun_SimpleFileExFlags (pythonrun.c:941) 2011-12-15 Osier Yang python: Expose blockPeek and memoryPeek in Python binding A simple example to show how to use it: \#! /usr/bin/python import os import sys import libvirt disk = "/var/lib/libvirt/images/test.img" conn = libvirt.open(None) dom = conn.lookupByName('test') mem_contents = dom.memoryPeek(0, 32, libvirt.VIR_MEMORY_VIRTUAL); sys.stdout.write(mem_contents) % python test.py | hexdump 0000000 1660 0209 0000 0000 0000 0000 0000 0000 0000010 0000 0000 0000 0000 d3a0 01d0 0000 0000 0000020 2011-12-13 Peter Krempa python: Fix export of virDomainSnapshotListChildrenNames Commit f2013c9dd1ce468b8620ee35c232a93ef7026fb0 added implementation of virDomainSnapshotListChildrenNames override export, but registration of the newly exported function was not added. *python/libvirt-override.c: - register export of function 2011-12-05 Peter Krempa python: Expose binding for virNodeGetMemoryStats() This patch adds binding for virNodeGetMemoryStats method of libvirtd. Return value is represented as a python dictionary mapping field names to values. 2011-12-05 Peter Krempa python: Expose binding for virNodeGetCPUStats() This patch adds binding for virNodeGetCPUStats method of libvirtd. Return value is represented as a python dictionary mapping field names to values. 2011-11-30 Lei Li Support virDomain{Set, Get}BlockIoTune in the python API Python support for both setting and getting block I/O throttle. 2011-11-30 Lei Li Add new API virDomain{Set, Get}BlockIoTune This patch add new pulic API virDomainSetBlockIoTune and virDomainGetBlockIoTune. 2011-10-31 Matthias Bolte python: Fix documentation of virStream recv This was fixed in be757a3f7baf93b for libvirt.c. 2011-10-25 Michal Privoznik startupPolicy: Emit event on disk source dropping If a disk source gets dropped because it is not accessible, mgmt application might want to be informed about this. Therefore we need to emit an event. The event presented in this patch is however a bit superset of what written above. The reason is simple: an intention to be easily expanded, e.g. on 'user ejected disk in guest' events. Therefore, callback gets source string and disk alias (which should be unique among a domain) and reason (an integer); 2011-10-17 Philipp Hahn Fix two comments related to error handling 2011-10-10 Eric Blake snapshot: new virDomainSnapshotListChildrenNames API The previous API addition allowed traversal up the hierarchy; this one makes it easier to traverse down the hierarchy. In the python bindings, virDomainSnapshotNumChildren can be generated, but virDomainSnapshotListChildrenNames had to copy from the hand-written example of virDomainSnapshotListNames. * include/libvirt/libvirt.h.in (virDomainSnapshotNumChildren) (virDomainSnapshotListChildrenNames): New prototypes. (VIR_DOMAIN_SNAPSHOT_LIST_DESCENDANTS): New flag alias. * src/libvirt.c (virDomainSnapshotNumChildren) (virDomainSnapshotListChildrenNames): New functions. * src/libvirt_public.syms: Export them. * src/driver.h (virDrvDomainSnapshotNumChildren) (virDrvDomainSnapshotListChildrenNames): New callbacks. * python/generator.py (skip_impl, nameFixup): Update lists. * python/libvirt-override-api.xml: Likewise. * python/libvirt-override.c (libvirt_virDomainSnapshotListChildrenNames): New wrapper function. 2011-10-10 Eric Blake maint: typo fixes I noticed a couple typos in recent commits, and fixed the remaining instances of them. * docs/internals/command.html.in: Fix spelling errors. * include/libvirt/libvirt.h.in (virConnectDomainEventCallback): Likewise. * python/libvirt-override.py (virEventAddHandle): Likewise. * src/lxc/lxc_container.c (lxcContainerChild): Likewise. * src/util/hash.c (virHashCreateFull): Likewise. * src/storage/storage_backend_logical.c (virStorageBackendLogicalMakeVol): Likewise. * src/esx/esx_driver.c (esxFormatVMXFileName): Likewise. * src/vbox/vbox_tmpl.c (vboxIIDIsEqual_v3_x): Likewise. 2011-09-16 Jiri Denemark python: Fix bindings generated in VPATH build 2011-09-15 Cole Robinson python: Fix libvirt.py generation to include virterror info Recent generator refactoring broke libvirt.py. With this patch, libvirt.py is generated exactly the same as before offending commit 9eba0d25. 2011-09-14 Osier Yang qemu_api: Update Makefile to generate libvirtmod_qemu lib 2011-09-14 Osier Yang qemu_api: Update Py binding generator to generate files for QEMU APIs It will generate: libvirt-qemu.py libvirt-qemu.h libvirt-qemu.c libvirt-qemu-export.c 2011-09-14 Osier Yang qemu_api: Add override XML and C files for QEMU APIs There is only one function (virDomainQemuMonitorCommand) need to be hand-craft. 2011-09-06 Osier Yang latency: Expose the new API for Python binding 2011-09-01 Jim Fehlig Add public API for getting migration speed Includes impl of python binding since the generator was not able to cope. Note: Requires gendispatch.pl patch from Matthias Bolte https://www.redhat.com/archives/libvir-list/2011-August/msg01367.html 2011-08-02 Eric Blake python: avoid unlikely sign extension bug Detected by Coverity; same analysis as for commit f73198df. * python/libvirt-override.c (libvirt_virDomainGetVcpuPinInfo): Use correct type. 2011-07-29 Matthias Bolte freebsd: Fix build problem due to picking up the wrong libvirt.h Gettext annoyingly modifies CPPFLAGS in-place, putting -I/usr/local/include into the search patch if libintl headers must be used from that location. But since we must support automake 1.9.6 which lacks AM_CPPFLAGS, and since CPPFLAGS is used prior to INCLUDES, this means that the build picks up the _old_ installed libvirt.h in priority to the in-tree version, leading to all sorts of weird build failures on FreeBSD. Fix this by teaching configure to undo gettext's actions, but to keep any changes required by gettext at the end of INCLUDES after all in-tree locations are used first. Also requires adding a wrapper Makefile.am and making gnulib-tool create just gnulib.mk files during the bootstrap process. 2011-07-28 Eric Blake maint: add missing copyright notices I went with the shorter license notice used by src/libvirt.c, rather than spelling out the full LGPLv2+ clause into each of these files. * configure.ac: Declare copyright. * all Makefile.am: Likewise. 2011-07-28 Hu Tao python: add python binding for virDomainSetMemoryParameters 2011-07-28 Hu Tao python: add python binding for virDomainGetMemoryParameters 2011-07-28 Hu Tao python: add python binding for virDomainSetBlkioParameters 2011-07-28 Hu Tao python: add python binding for virDomainGetBlkioParameters 2011-07-27 Lai Jiangshan send-key: Implement Python API 2011-07-26 Cole Robinson python: Properly report errors if virStreamRecv fails We only want to raise the special value -2. -1 should return None which tells the bindings to throw an exception. 2011-07-25 Cole Robinson python: Handle embedded NUL in stream.send data Otherwise things like volume upload are only useful with text data. 2011-07-25 Taku Izumi python: add Python binding for virDomainGetVcpuPinInfo API This patch adds the Python bindings for virDomainGetVcpuPinInfo API. * python/generator.py: add it to generator skip list * python/libvirt-override-api.xml: provide an override description * python/libvirt-override.c: provide an override binding implementation 2011-07-25 Taku Izumi python: add Python binding for virDomainPinVcpusFlags API This patch adds the Python bindings for virDomainPinVcpuFlags API. * python/generator.py: add it to the generator skip list * python/libvirt-override-api.xml: provide override description * python/libvirt-override.c: provide override bindings implementation 2011-07-25 Taku Izumi python: add Python binding for virDomainGetSchedulerParametersFlags API This patch adds the Python bindings for virDomainGetSchedulerParametersFlags API. 2011-07-25 Taku Izumi python: add Python binding for virDomainGetSchedulerParametersFlags API This patch adds the Python bindings for virDomainGetSchedulerParametersFlags API. * python/libvirt-override-api.xml: provide and override description * python/libvirt-override.c: implement the bindings 2011-07-22 Adam Litke Asynchronous event for BlockJob completion When an operation started by virDomainBlockPull completes (either with success or with failure), raise an event to indicate the final status. This API allow users to avoid polling on virDomainGetBlockJobInfo if they would prefer to use an event mechanism. * daemon/remote.c: Dispatch events to client * include/libvirt/libvirt.h.in: Define event ID and callback signature * src/conf/domain_event.c, src/conf/domain_event.h, src/libvirt_private.syms: Extend API to handle the new event * src/qemu/qemu_driver.c: Connect to the QEMU monitor event for block_stream completion and emit a libvirt block pull event * src/remote/remote_driver.c: Receive and dispatch events to application * src/remote/remote_protocol.x: Wire protocol definition for the event * src/remote_protocol-structs: structure definitions for protocol verification * src/qemu/qemu_monitor.c, src/qemu/qemu_monitor.h, src/qemu/qemu_monitor_json.c: Watch for BLOCK_STREAM_COMPLETED event from QEMU monitor 2011-07-22 Adam Litke Enable virDomainBlockPull in the python API virDomainGetBlockJobInfo requires manual override since it returns a custom type. * python/generator.py: reenable bindings for this entry point * python/libvirt-override-api.xml python/libvirt-override.c: manual overrides 2011-07-22 Adam Litke Add new API virDomainBlockPull* to headers Set up the types for the block pull functions and insert them into the virDriver structure definition. Symbols are exported in this patch to prevent documentation compile failures. * include/libvirt/libvirt.h.in: new API * src/driver.h: add the new entry to the driver structure * python/generator.py: fix compiler errors, the actual python bindings * are implemented later * src/libvirt_public.syms: export symbols * docs/apibuild.py: Extend 'unsigned long' parameter exception to this * API 2011-07-21 Matthias Bolte python: Fix makefile rule for code generation Commit 8665f85523f0451c changed generated.stamp to $(GENERATE).stamp, but missed one instance in the CLEANFILES list. This can break the build in case the generated code is deleted but the .stamp file stays around and therefore the code isn't regenerated. 2011-07-19 Daniel P. Berrange Quieten build & ensure API build scripts exit with non-zero status The current API build scripts will continue and exit with a zero status even if they find problems. This has been the cause of many build problems, or hidden build errors, in the past. Change the scripts so they always exit with a non-zero status for any problems they do not understand. Also turn off all debug output by default so they respect $(AM_V_GEN) * docs/Makefile.am: Use $(AM_V_GEN) for API/HTML scripts * docs/apibuild.py, python/generator.py: Exit with non-zero status if problems are found. Also be silent, not outputting any debug messages. * src/Makefile.am: Use $(AM_V_GEN) for ESX generator * python/Makefile.am: Tweak rule 2011-07-13 Eric Blake python: prefer unsigned flags * python/libvirt-override.c (libvirt_virConnectOpenAuth) (libvirt_virDomainSnapshotListNames) (libvirt_virDomainRevertToSnapshot): Change flags type. 2011-07-07 Matthias Bolte python: Fix bogus label placement 2011-07-01 Eric Blake build: consistently use CFLAGS According to the automake manual, CPPFLAGS (aka INCLUDES, as spelled in automake 1.9.6) should only include -I, -D, and -U directives; more generic directives like -Wall belong in CFLAGS since they affect more phases of the build process. Therefore, we should be sticking CFLAGS additions into a CFLAGS container, not a CPPFLAGS container. * src/Makefile.am (libvirt_driver_vmware_la_CFLAGS): Use AM_CFLAGS. (INCLUDES): Move CFLAGS items... (AM_CFLAGS): ...to their proper location. * python/Makefile.am (INCLUDES, AM_CFLAGS): Likewise. * tests/Makefile.am (INCLUDES, AM_CFLAGS): Likewise. (commandtest_CFLAGS, commandhelper_CFLAGS) (virnetmessagetest_CFLAGS, virnetsockettest_CFLAGS): Use AM_CFLAGS. 2011-06-24 Matthias Bolte python: Don't declare Py_ssize_t for Python 2.6 Commit cd48c3f4e95597 added a Py_ssize_t typedef for Python < 2.7. But Py_ssize_t was added in Python 2.5. This makes the build fail for Python 2.6. Adjust the check to match Python < 2.5 to fix this. 2011-06-24 Eric Blake Revert "Add new API virDomainBlockPull* to headers" This reverts commit 7d56a16d036d9aa7292e10e884c129742036f8a7. Conflicts: python/generator.py src/libvirt_public.syms 2011-06-24 Eric Blake Revert "Enable virDomainBlockPull in the python API." This reverts commit d74b86f5d6ecae3d18a391f90a918fcac75914db. Conflicts: python/generator.py 2011-06-24 Eric Blake Revert "Asynchronous event for BlockPull completion" This reverts commit 12cd77a0c58a80179182f7d09e8e73f9f66b4677. Conflicts: python/libvirt-override-virConnect.py python/libvirt-override.c src/remote/remote_protocol.x 2011-06-24 Eric Blake build: avoid python 2.4 build failure I'm not sure when Py_ssize_t was introduced; but Fedora 14 Python 2.7 has it, while RHEL 5 Python 2.4 lacks it. It should be easy enough to adjust if someone runs into problems. * python/typewrappers.h (Py_ssize_t): Define for older python. 2011-06-24 Eric Blake build: avoid python 2.4 build failure On RHEL 5, I got: /usr/bin/python ./generator.py /usr/bin/python File "./generator.py", line 427 "virStreamFree", # Needed in custom virStream __del__, but free shouldn't ^ SyntaxError: invalid syntax * python/generator.py (function_skip_python_impl): Use same syntax as other skip lists. 2011-06-23 Cole Robinson python: Generate virStreamFree but don't expose in bindings Turns out I was right in removing this the first time :) This is needed in our custom __del__ function, but the C code wasn't being generated. Add new infrastructure to do what we want 2011-06-21 Cole Robinson python: Mark event callback wrappers as private These functions aren't intended to be called directly by users, so mark them as private. While we're at it, remove unneeded exception handling, and break some long lines. 2011-06-21 Cole Robinson python: events: Fix C->Python handle callback prototype If registering our own event loop implementation written in python, any handles or timeouts callbacks registered by libvirt C code must be wrapped in a python function. There is some argument trickery that makes this all work, by wrapping the user passed opaque value in a tuple, along with the callback function. Problem is, the current setup requires the user's event loop to know about this trickery, rather than just treating the opaque value as truly opaque. Fix this in a backwards compatible manner, and adjust the example python event loop to do things the proper way. 2011-06-21 Cole Robinson python: Add bindings for virEvent*Handle/Timeout 2011-06-21 Cole Robinson Promote virEvent*Handle/Timeout to public API Since we virEventRegisterDefaultImpl is now a public API, callers need a way to invoke the default registered Handle and Timeout functions. We already have general functions for these internally, so promote them to the public API. v2: Actually add APIs to libvirt.h 2011-06-21 Cole Robinson python: Implement virStreamSend/RecvAll helpers Pure python implementation. The handler callbacks have been altered a bit compared to the C API: RecvAll doesn't pass length of the data read since that can be trivially obtained from python string objects, and SendAll requires the handler to return the string data to send rather than store the data in a string pointer. 2011-06-21 Cole Robinson python: Implement virStreamSend/Recv The return values for the python version are different that the C version of virStreamSend: on success we return a string, an error raises an exception, and if the stream would block we return int(-2). We need to do this since strings aren't passed by reference in python. 2011-06-20 Cole Robinson python: Implement bindings for virStreamEventAddCallback v2: Don't generate virStreamFree 2011-06-20 Cole Robinson python: generator: Don't print warning if nothing to warn about 2011-06-20 Cole Robinson python: libvirt-override: use simpler debug In a couple instances we have to mark a debug variable as ATTRIBUTE_UNUSED to avoid warnings. v2: Use #if 0 to comment out debug define 2011-06-16 Jiri Denemark Introduce virDomainGetControlInfo API The API can be used to query current state of an interface to VMM used to control a domain. In QEMU world this translates into monitor connection. 2011-06-15 Adam Litke Asynchronous event for BlockPull completion When an operation started by virDomainBlockPullAll completes (either with success or with failure), raise an event to indicate the final status. This allows an API user to avoid polling on virDomainBlockPullInfo if they would prefer to use the event mechanism. * daemon/remote.c: Dispatch events to client * include/libvirt/libvirt.h.in: Define event ID and callback signature * src/conf/domain_event.c, src/conf/domain_event.h, src/libvirt_private.syms: Extend API to handle the new event * src/qemu/qemu_driver.c: Connect to the QEMU monitor event for block_stream completion and emit a libvirt block pull event * src/remote/remote_driver.c: Receive and dispatch events to application * src/remote/remote_protocol.x: Wire protocol definition for the event * src/qemu/qemu_monitor.c, src/qemu/qemu_monitor.h, src/qemu/qemu_monitor_json.c: Watch for BLOCK_STREAM_COMPLETED event from QEMU monitor 2011-06-15 Adam Litke Enable virDomainBlockPull in the python API. virDomainBlockPullAll and virDomainBlockPullAbort are handled automatically. virDomainBlockPull and virDomainBlockPullInfo require manual overrides since they return a custom type. * python/generator.py: reenable bindings for this entry point * python/libvirt-override-api.xml python/libvirt-override.c: manual overrides Acked-by: Daniel P. Berrange 2011-06-15 Adam Litke Add new API virDomainBlockPull* to headers Set up the types for the block pull functions and insert them into the virDriver structure definition. Symbols are exported in this patch to prevent documentation compile failures. * include/libvirt/libvirt.h.in: new API * src/driver.h: add the new entry to the driver structure * python/generator.py: fix compiler errors, the actual python bindings are implemented later * src/libvirt_public.syms: export symbols 2011-06-14 Minoru Usui virNodeGetMemoryStats: Expose new API 2011-06-14 Minoru Usui virNodeGetCPUStats: Expose new API 2011-06-14 Lai Jiangshan send-key: Defining the public API Add public virDomainSendKey() and enum libvirt_keycode_set for the @codeset. Python version of virDomainSendKey() has not been implemented yet, it will be done soon. 2011-06-13 Hu Tao Deprecate several CURRENT/LIVE/CONFIG enums This patch deprecates following enums: VIR_DOMAIN_MEM_CURRENT VIR_DOMAIN_MEM_LIVE VIR_DOMAIN_MEM_CONFIG VIR_DOMAIN_VCPU_LIVE VIR_DOMAIN_VCPU_CONFIG VIR_DOMAIN_DEVICE_MODIFY_CURRENT VIR_DOMAIN_DEVICE_MODIFY_LIVE VIR_DOMAIN_DEVICE_MODIFY_CONFIG And modify internal codes to use virDomainModificationImpact. 2011-06-08 Eric Blake python: avoid unlikely sign extension bug Detected by Coverity. cpumap was allocated with a value of (unsigned short)*(int), which is an int computation, and then promotes to size_t. On a 64-bit platform, this fails if bit 32 of the product is set (because of sign extension giving a HUGE value to malloc), even though a naive programmer would assume that since the first value is unsigned, the product is also unsigned and at most 4GB would be allocated. Won't bite in practice (the product should never be that large), but worth using the right types to begin with, so that we are now computing (unsigned short)*(size_t). * python/libvirt-override.c (libvirt_virDomainGetVcpus): Use correct type. 2011-05-29 Daniel P. Berrange Introduce a new event emitted when a virtualization failure occurs This introduces a new domain VIR_DOMAIN_EVENT_ID_CONTROL_ERROR Which uses the existing generic callback typedef void (*virConnectDomainEventGenericCallback)(virConnectPtr conn, virDomainPtr dom, void *opaque); This event is intended to be emitted when there is a failure in some part of the domain virtualization system. Whether the domain continues to run/exist after the failure is an implementation detail specific to the hypervisor. The idea is that with some types of failure, hypervisors may prefer to leave the domain running in a "degraded" mode of operation. For example, if something goes wrong with the QEMU monitor, it is possible to leave the guest OS running quite happily. The mgmt app will simply loose the ability todo various tasks. The mgmt app can then choose how/when to deal with the failure that occured. * daemon/remote.c: Dispatch of new event * examples/domain-events/events-c/event-test.c: Demo catch of event * include/libvirt/libvirt.h.in: Define event ID and callback * src/conf/domain_event.c, src/conf/domain_event.h: Internal event handling * src/remote/remote_driver.c: Receipt of new event from daemon * src/remote/remote_protocol.x: Wire protocol for new event * src/remote_protocol-structs: add new event for checks 2011-05-29 Eric Blake sched: introduce virDomainGetSchedulerParametersFlags If we can choose live or config when setting, then we need to be able to choose which one we are querying. Also, make the documentation clear that set must use a non-empty subset (some of the hypervisors fail if params is NULL). * include/libvirt/libvirt.h.in (virDomainGetSchedulerParametersFlags): New prototype. * src/libvirt.c (virDomainGetSchedulerParametersFlags): Implement it. * src/libvirt_public.syms: Export it. * python/generator.py (skip_impl): Don't auto-generate. * src/driver.h (virDrvDomainGetSchedulerParametersFlags): New callback. 2011-05-29 Eric Blake libvirt.h: avoid regression, and document preferred name Commit 824dcaff was a regression (thankfully unreleased) for any client code that used 'struct _virSchedParameter' directly rather than the preferred virSchedParameter typedef. Adding a #define avoids even that API change, while rearranging the file makes it clear what the old vs. new API is. * include/libvirt/libvirt.h.in: Rearrange older names to the bottom and improve documentation on preferred names. (virDomainGetSchedulerParameters, virDomainSetSchedulerParameters) (virDomainSetSchedulerParametersFlags) (virDomainSetBlkioParameters, virDomainGetBlkioParameters) (virDomainSetMemoryParameters, virDomainGetMemoryParameters): Use newer type names. * python/libvirt-override.c: Adjust code generation to cope. Suggested by Daniel P. Berrange. 2011-05-24 Michal Privoznik python: Don't free must-not-free variables py_str() function call PyString_AsString(). As written in documentation, the caller must not free the returned value, because it points to some internal structures. 2011-05-23 Michal Privoznik python: Fix typo in bindings This typo caused a bug in which we wanted to free() invalid pointer. 2011-05-18 Eric Blake libvirt.h: consolidate typed parameter handling The new type is identical to the three old types that it replaces, and by creating a common type, this allows future patches to share common code that manipulates typed parameters. This change is backwards-compatible in API (recompilation works without any edits) and ABI (an older client that has not been recompiled uses the same layout) for code using only public names; only code using private names (those beginning with _) will have to adapt. * include/libvirt/libvirt.h.in (virTypedParameterType) (VIR_TYPED_PARAM_FIELD_LENGTH, _virTypedParameter): New enum, macro, and type. (virSchedParameter, virBlkioParameter, virMemoryParameter): Rewrite in terms of a common type, while keeping all old public names for backwards compatibility. (struct _virSchedParameter, struct _virBlkioParameter) (struct _virMemoryParameter): Delete - these are private names. * python/generator.py (enum): Cope with the refactoring. 2011-05-17 Hu Tao introduce virDomainSetSchedulerParametersFlags This new function allows aditional flags to be passed into from the virsh command line. 2011-05-16 Jiri Denemark virDomainGetState public API This API is supposed to replace virDomainGetInfo when the only purpose of calling it is getting current domain status. 2011-03-14 Jiri Denemark python: Use hardcoded python path in libvirt.py This partially reverts (and fixes that part in a different way) commit e4384459c93e3e786aa483c7f077d1d22148f689, which replaced ``/usr/bin/python'' with ``/usr/bin/env python'' in all examples or scripts used during build to generate other files. However, python bindings module is compiled and linked against a specific python discovered or explicitly provided in configure phase. Thus libvirt.py, which is generated and installed into the system, should use the same python binary for which the module has been built. The hunk in Makefile.am replaces $(srcdir) with $(PYTHON), which might seem wrong but it is not. generator.py didn't use any of its command line arguments so passing $(srcdir) to it was redundant. 2011-03-11 Gui Jianfeng libvirt: add virDomain{Get,Set}BlkioParameters Add virDomainSetBlkioParameters virDomainGetBlkioParameters 2011-02-21 Eric Blake maint: fix grammar in error message * python/tests/create.py: Use correct wording. 2011-02-18 Jiri Denemark maint: Expand tabs in python code Also cfg.mk is tweaked to force this for all future changes to *.py files. 2011-01-10 Cole Robinson python: Use PyCapsule API if available On Fedore 14, virt-manager spews a bunch of warnings to the console: /usr/lib64/python2.7/site-packages/libvirt.py:1781: PendingDeprecationWarning: The CObject type is marked Pending Deprecation in Python 2.7. Please use capsule objects instead. Have libvirt use the capsule API if available. I've verified this compiles fine on older python (2.6 in RHEL6 which doesn't have capsules), and virt-manager seems to function fine. 2010-11-14 Matthias Bolte Use python discovered through env instead of hardcoding a path This is more flexible regarding the location of the python binary but doesn't allow to pass the -u flag. The -i flag can be passed from inside the script using the PYTHONINSPECT env variable. This fixes a problem with the esx_vi_generator.py on FreeBSD. 2010-10-12 Matthias Bolte Fix several minor problems introduced by the memtune series Add proper documentation to the new VIR_DOMAIN_MEMORY_* macros in libvirt.h.in to placate apibuild.py. Mark args as unused in for libvirt_virDomain{Get,Set}MemoryParameters in the Python bindings and add both to the libvirtMethods array. Update remote_protocol-structs to placate make syntax-check. Undo unintended modifications in vboxDomainGetInfo. Update the function table of the VirtualBox and XenAPI drivers. 2010-10-12 Nikunj A. Dadhania Adding structure and defines for virDomainSet/GetMemoryParameters This patch adds a structure virMemoryParameter, it contains the name of the parameter and the type of the parameter along with a union. dv: + rename enums to VIR_DOMAIN_MEMORY_PARAM_* + remove some extraneous tabs v4: + Add unsigned int flags to the public api for future extensions v3: + Protoype for virDomainGetMemoryParameters and dummy python binding. v2: + Includes dummy python bindings for the library to build cleanly. + Define string constants like "hard_limit", etc. + re-order this patch. 2010-09-27 Dan Kenigsberg python: drop unnecessary conn assignment Since 554d82a200289938d5639a782a9f12e3e2e968f0, conn is unused. Let's drop it - but keep the signature of the constructor for backward compatibility. 2010-07-23 Philipp Hahn Fix SEGV on exit after domainEventDeregister() When the last callback is removed using domainEventDeregister(), the events dispatcher is deregistered from the C-library, but domainEventsCallbacks is still an empty list. On shutdown __del__() deregisters the dispatacher again, which SEGVs # You need the event-loop implementation from the Python examples; # give the file a name which is importable by Python. ln examples/domain-events/events-python/event-test.py eloop.py python -c 'from eloop import * import sys def dump(*args): print " ".join(map(str, args)) virEventLoopPureStart() c = libvirt.open("xen:///") c.domainEventRegister(dump, None) c.domainEventDeregister(dump) sys.exit(0)' domainEventDeregister() needs to delete domainEventCallbacks so subsequent calls to __del__() and domainEventRegister() choose the right code paths. Setting it to None is not enough, since calling domainEventRegiser() again would trigger an TypeError. 2010-07-14 Cole Robinson python: Fix IOErrorReasonCallback bindings A copy and paste error was causing us to dispatch the incorrect routine. Spotted by Dan Kenigsberg. 2010-07-12 Daniel P. Berrange Ensure we return the callback ID in python events binding A missing return statement in the python binding meant that the callers could not get the callback ID, and thus not be able to unregister event callbacks * python/libvirt-override-virConnect.py: Add missing return statement 2010-06-25 Daniel P. Berrange Add missing parameter in python Disk IO error callback The IO error callback was forgetting to pass the action parameter, causing a stack trace when IO errors arrive * python/libvirt-override-virConnect.py: Add missing action parameter in IO error callback 2010-06-18 Philipp Hahn Fix description of virStorageVolGetInfo() Probably a copy-paste-bug in python/libvirt-override-api.xml: virStorageVolGetInfo() extracts information about a "storage volume", not the "storage pool" as virStoragePoolGetInfo() does. 2010-06-15 Eric Blake maint: simplify some ignore files * .hgignore: Delete, no longer used. * examples/python/.gitignore: Delete, covered globally. * include/.gitignore: Likewise. * python/tests/.gitignore: Likewise. * docs/schemas/.gitignore: Likewise. * tests/xml2sexprdata/.gitignore: Likewise. * tests/sexpr2xmldata/.gitignore: Likewise. * tests/confdata/.gitignore: Likewise. * tests/xencapsdata/.gitignore: Likewise. * tests/xmconfigdata/.gitignore: Likewise. * tests/xml2sexprdata/.gitignore: Likewise. 2010-05-20 Chris Lalancette Fix up the python bindings for snapshotting. This involved a few fixes. To start with, an virDomainSnapshot object is really tied to a domain, not a connection, so we have to generate a slightly different object so that we can get at self._dom for the object. Next, we had to "dummy" up an override piece of XML with a bogus argument that the function doesn't actually take. That's so that the generator places virDomainRevertToSnapshot underneath the correct class (namely, the virDomain class). Finally, we had to hand-implement the virDomainRevertToSnapshot implementation, ignoring the bogus pointer we are being passed. With all of this in place, I was able to successfully take a snapshot and revert to it using only the Python bindings. 2010-05-18 Jim Meyering python: don't ignore virInitialize failure in module initialization * python/libvirt-override.c (initlibvirtmod): Upon virInitialize failure, skip the Py_InitModule call. 2010-04-30 Daniel P. Berrange Add support for another explicit IO error event This introduces a new event type VIR_DOMAIN_EVENT_ID_IO_ERROR_REASON This event is the same as the previous VIR_DOMAIN_ID_IO_ERROR event, but also includes a string describing the cause of the event. Thus there is a new callback definition for this event type typedef void (*virConnectDomainEventIOErrorReasonCallback)(virConnectPtr conn, virDomainPtr dom, const char *srcPath, const char *devAlias, int action, const char *reason, void *opaque); This is currently wired up to the QEMU block IO error events * daemon/remote.c: Dispatch IO error events to client * examples/domain-events/events-c/event-test.c: Watch for IO error events * include/libvirt/libvirt.h.in: Define new IO error event ID and callback signature * src/conf/domain_event.c, src/conf/domain_event.h, src/libvirt_private.syms: Extend API to handle IO error events * src/qemu/qemu_driver.c: Connect to the QEMU monitor event for block IO errors and emit a libvirt IO error event * src/remote/remote_driver.c: Receive and dispatch IO error events to application * src/remote/remote_protocol.x: Wire protocol definition for IO error events * src/qemu/qemu_monitor.c, src/qemu/qemu_monitor.h, src/qemu/qemu_monitor_json.c: Watch for BLOCK_IO_ERROR event from QEMU monitor 2010-04-29 Daniel P. Berrange Implement python binding for virDomainGetBlockInfo This binds the virDomainGetBlockInfo API to python's blockInfo method on the domain object >>> c = libvirt.openReadOnly('qemu:///session') >>> d = c.lookupByName('demo') >>> f = d.blockInfo("/dev/loop0", 0) >>> print f [1048576000L, 104857600L, 104857600L] * python/libvirt-override-api.xml: Define override signature * python/generator.py: Skip C impl generator for virDomainGetBlockInfo * python/libvirt-override.c: Manual impl of virDomainGetBlockInfo 2010-04-29 Stefan Berger nwfilter: python bindings for nwfilter I have primarily followed the pattern of the 'secret' driver to provide support for the missing python bindings for the network filter API. 2010-04-20 Philipp Hahn Don't ship generated python/libvirt.? files. libvirt.c and libvirt.h are auto-generated files. Mentioning their names in *_SOURCES includes them in the distribution. During an out-of-tree build these shipped files are included instead of the auto-generated version, potentially breaking the build (as it happend in 0.8.0, because the shipped libvirt.h was missing the declaration for 'libvirt_virDomainUpdateDeviceFlags') Use the nodist_*_SOURCES automake variable instead. 2010-04-20 Daniel P. Berrange Fixup python binding for virDomainSnapshot APIs The generator code was totally wrong for the virDomainSnapshot APIs, not generating the wrapper class, and giving methods the wrong names * generator.py: Set metadata for virDomainSnapshot type & APIs * libvirt-override-api.xml, libvirt-override.c: Hand-code the virDomainSnapshotListNames glue layer 2010-04-09 Daniel P. Berrange More event callback fixes In a couple of cases typos meant we were firing the wrong type of event. In the python code my previous commit accidentally missed some chunks of the code. * python/libvirt-override-virConnect.py: Add missing python glue accidentally left out of previous commit * src/conf/domain_event.c, src/qemu/qemu_monitor_json.c: Fix typos in event name / method name to invoke 2010-04-08 Daniel P. Berrange Fix up python bindings for new event callbacks The generator was disabled for the new event callbacks, since they need to be hand written. This patch adds the C and python glue to expose the new APIs in the python binding. The python example program is extended to demonstrate of the code * python/libvirt-override.c: Registration and dispatch of events at the C layer * python/libvirt-override-virConnect.py: Python glue for events * examples/domain-events/events-python/event-test.py: Demo use of new event callbacks 2010-04-05 Chris Lalancette Snapshot API framework. 2010-03-26 Stefan Berger Core driver implementation with ebtables support This patch implements the core driver and provides - management functionality for managing the filter XMLs - compiling the internal filter representation into ebtables rules - applying ebtables rules on a network (tap,macvtap) interface - tearing down ebtables rules that were applied on behalf of an interface - updating of filters while VMs are running and causing the firewalls to be rebuilt - other bits and pieces 2010-03-26 Daniel P. Berrange Add domain events for graphics network clients This introduces a new event type VIR_DOMAIN_EVENT_ID_GRAPHICS The same event can be emitted in 3 scenarios typedef enum { VIR_DOMAIN_EVENT_GRAPHICS_CONNECT = 0, VIR_DOMAIN_EVENT_GRAPHICS_INITIALIZE, VIR_DOMAIN_EVENT_GRAPHICS_DISCONNECT, } virDomainEventGraphicsPhase; Connect/disconnect are triggered at socket accept/close. The initialize phase is immediately after the protocol setup and authentication has completed. ie when the client is authorized and about to start interacting with the graphical desktop This event comes with *a lot* of potential information - IP address, port & address family of client - IP address, port & address family of server - Authentication scheme (arbitrary string) - Authenticated subject identity. A subject may have multiple identities with some authentication schemes. For example, vencrypt+sasl results in a x509dname and saslUsername identities. This results in a very complicated callback :-( typedef enum { VIR_DOMAIN_EVENT_GRAPHICS_ADDRESS_IPV4, VIR_DOMAIN_EVENT_GRAPHICS_ADDRESS_IPV6, } virDomainEventGraphicsAddressType; struct _virDomainEventGraphicsAddress { int family; const char *node; const char *service; }; typedef struct _virDomainEventGraphicsAddress virDomainEventGraphicsAddress; typedef virDomainEventGraphicsAddress *virDomainEventGraphicsAddressPtr; struct _virDomainEventGraphicsSubject { int nidentity; struct { const char *type; const char *name; } *identities; }; typedef struct _virDomainEventGraphicsSubject virDomainEventGraphicsSubject; typedef virDomainEventGraphicsSubject *virDomainEventGraphicsSubjectPtr; typedef void (*virConnectDomainEventGraphicsCallback)(virConnectPtr conn, virDomainPtr dom, int phase, virDomainEventGraphicsAddressPtr local, virDomainEventGraphicsAddressPtr remote, const char *authScheme, virDomainEventGraphicsSubjectPtr subject, void *opaque); The wire protocol is similarly complex struct remote_domain_event_graphics_address { int family; remote_nonnull_string node; remote_nonnull_string service; }; const REMOTE_DOMAIN_EVENT_GRAPHICS_IDENTITY_MAX = 20; struct remote_domain_event_graphics_identity { remote_nonnull_string type; remote_nonnull_string name; }; struct remote_domain_event_graphics_msg { remote_nonnull_domain dom; int phase; remote_domain_event_graphics_address local; remote_domain_event_graphics_address remote; remote_nonnull_string authScheme; remote_domain_event_graphics_identity subject; }; This is currently implemented in QEMU for the VNC graphics protocol, but designed to be usable with SPICE graphics in the future too. * daemon/remote.c: Dispatch graphics events to client * examples/domain-events/events-c/event-test.c: Watch for graphics events * include/libvirt/libvirt.h.in: Define new graphics event ID and callback signature * src/conf/domain_event.c, src/conf/domain_event.h, src/libvirt_private.syms: Extend API to handle graphics events * src/qemu/qemu_driver.c: Connect to the QEMU monitor event for VNC events and emit a libvirt graphics event * src/remote/remote_driver.c: Receive and dispatch graphics events to application * src/remote/remote_protocol.x: Wire protocol definition for graphics events * src/qemu/qemu_monitor.c, src/qemu/qemu_monitor.h, src/qemu/qemu_monitor_json.c: Watch for VNC_CONNECTED, VNC_INITIALIZED & VNC_DISCONNETED events from QEMU monitor 2010-03-26 Daniel P. Berrange Add support for an explicit IO error event This introduces a new event type VIR_DOMAIN_EVENT_ID_IO_ERROR This event includes the action that is about to be taken as a result of the watchdog triggering typedef enum { VIR_DOMAIN_EVENT_IO_ERROR_NONE = 0, VIR_DOMAIN_EVENT_IO_ERROR_PAUSE, VIR_DOMAIN_EVENT_IO_ERROR_REPORT, } virDomainEventIOErrorAction; In addition it has the source path of the disk that had the error and its unique device alias. It does not include the target device name (/dev/sda), since this would preclude triggering IO errors from other file backed devices (eg serial ports connected to a file) Thus there is a new callback definition for this event type typedef void (*virConnectDomainEventIOErrorCallback)(virConnectPtr conn, virDomainPtr dom, const char *srcPath, const char *devAlias, int action, void *opaque); This is currently wired up to the QEMU block IO error events * daemon/remote.c: Dispatch IO error events to client * examples/domain-events/events-c/event-test.c: Watch for IO error events * include/libvirt/libvirt.h.in: Define new IO error event ID and callback signature * src/conf/domain_event.c, src/conf/domain_event.h, src/libvirt_private.syms: Extend API to handle IO error events * src/qemu/qemu_driver.c: Connect to the QEMU monitor event for block IO errors and emit a libvirt IO error event * src/remote/remote_driver.c: Receive and dispatch IO error events to application * src/remote/remote_protocol.x: Wire protocol definition for IO error events * src/qemu/qemu_monitor.c, src/qemu/qemu_monitor.h, src/qemu/qemu_monitor_json.c: Watch for BLOCK_IO_ERROR event from QEMU monitor 2010-03-26 Daniel P. Berrange Add support for an explicit watchdog event This introduces a new event type VIR_DOMAIN_EVENT_ID_WATCHDOG This event includes the action that is about to be taken as a result of the watchdog triggering typedef enum { VIR_DOMAIN_EVENT_WATCHDOG_NONE = 0, VIR_DOMAIN_EVENT_WATCHDOG_PAUSE, VIR_DOMAIN_EVENT_WATCHDOG_RESET, VIR_DOMAIN_EVENT_WATCHDOG_POWEROFF, VIR_DOMAIN_EVENT_WATCHDOG_SHUTDOWN, VIR_DOMAIN_EVENT_WATCHDOG_DEBUG, } virDomainEventWatchdogAction; Thus there is a new callback definition for this event type typedef void (*virConnectDomainEventWatchdogCallback)(virConnectPtr conn, virDomainPtr dom, int action, void *opaque); * daemon/remote.c: Dispatch watchdog events to client * examples/domain-events/events-c/event-test.c: Watch for watchdog events * include/libvirt/libvirt.h.in: Define new watchdg event ID and callback signature * src/conf/domain_event.c, src/conf/domain_event.h, src/libvirt_private.syms: Extend API to handle watchdog events * src/qemu/qemu_driver.c: Connect to the QEMU monitor event for watchdogs and emit a libvirt watchdog event * src/remote/remote_driver.c: Receive and dispatch watchdog events to application * src/remote/remote_protocol.x: Wire protocol definition for watchdog events * src/qemu/qemu_monitor.c, src/qemu/qemu_monitor.h, src/qemu/qemu_monitor_json.c: Watch for WATCHDOG event from QEMU monitor 2010-03-26 Daniel P. Berrange Add support for an explicit RTC change event This introduces a new event type VIR_DOMAIN_EVENT_ID_RTC_CHANGE This event includes the new UTC offset measured in seconds. Thus there is a new callback definition for this event type typedef void (*virConnectDomainEventRTCChangeCallback)(virConnectPtr conn, virDomainPtr dom, long long utcoffset, void *opaque); If the guest XML configuration for the is set to offset='variable', then the XML will automatically be updated with the new UTC offset value. This ensures that during migration/save/restore the new offset is preserved. * daemon/remote.c: Dispatch RTC change events to client * examples/domain-events/events-c/event-test.c: Watch for RTC change events * include/libvirt/libvirt.h.in: Define new RTC change event ID and callback signature * src/conf/domain_event.c, src/conf/domain_event.h, src/libvirt_private.syms: Extend API to handle RTC change events * src/qemu/qemu_driver.c: Connect to the QEMU monitor event for RTC changes and emit a libvirt RTC change event * src/remote/remote_driver.c: Receive and dispatch RTC change events to application * src/remote/remote_protocol.x: Wire protocol definition for RTC change events * src/qemu/qemu_monitor.c, src/qemu/qemu_monitor.h, src/qemu/qemu_monitor_json.c: Watch for RTC_CHANGE event from QEMU monitor 2010-03-26 Daniel P. Berrange Introduce a new public API for domain events The current API for domain events has a number of problems - Only allows for domain lifecycle change events - Does not allow the same callback to be registered multiple times - Does not allow filtering of events to a specific domain This introduces a new more general purpose domain events API typedef enum { VIR_DOMAIN_EVENT_ID_LIFECYCLE = 0, /* virConnectDomainEventCallback */ ...more events later.. } int virConnectDomainEventRegisterAny(virConnectPtr conn, virDomainPtr dom, /* Optional, to filter */ int eventID, virConnectDomainEventGenericCallback cb, void *opaque, virFreeCallback freecb); int virConnectDomainEventDeregisterAny(virConnectPtr conn, int callbackID); Since different event types can received different data in the callback, the API is defined with a generic callback. Specific events will each have a custom signature for their callback. Thus when registering an event it is neccessary to cast the callback to the generic signature eg int myDomainEventCallback(virConnectPtr conn, virDomainPtr dom, int event, int detail, void *opaque) { ... } virConnectDomainEventRegisterAny(conn, NULL, VIR_DOMAIN_EVENT_ID_LIFECYCLE, VIR_DOMAIN_EVENT_CALLBACK(myDomainEventCallback) NULL, NULL); The VIR_DOMAIN_EVENT_CALLBACK() macro simply does a "bad" cast to the generic signature * include/libvirt/libvirt.h.in: Define new APIs for registering domain events * src/driver.h: Internal driver entry points for new events APIs * src/libvirt.c: Wire up public API to driver API for events APIs * src/libvirt_public.syms: Export new APIs * src/esx/esx_driver.c, src/lxc/lxc_driver.c, src/opennebula/one_driver.c, src/openvz/openvz_driver.c, src/phyp/phyp_driver.c, src/qemu/qemu_driver.c, src/remote/remote_driver.c, src/test/test_driver.c, src/uml/uml_driver.c, src/vbox/vbox_tmpl.c, src/xen/xen_driver.c, src/xenapi/xenapi_driver.c: Stub out new API entries 2010-03-17 Philip Hahn python: Fix networkLookupByUUID According to: http://libvirt.org/html/libvirt-libvirt.html#virNetworkLookupByUUID virNetworkLookupByUUID() expects a virConnectPtr as its first argument, thus making it a method of the virConnect Python class. Currently it's a method of libvirt.virNetwork. @@ -805,13 +805,6 @@ class virNetwork: if ret == -1: raise libvirtError ('virNetworkGetAutostart() failed', net=self) return ret - def networkLookupByUUID(self, uuid): - """Try to lookup a network on the given hypervisor based on its UUID. """ - ret = libvirtmod.virNetworkLookupByUUID(self._o, uuid) - if ret is None:raise libvirtError('virNetworkLookupByUUID() failed', net=self) - __tmp = virNetwork(self, _obj=ret) - return __tmp - class virInterface: def __init__(self, conn, _obj=None): self._conn = conn @@ -1689,6 +1682,13 @@ class virConnect: __tmp = virDomain(self,_obj=ret) return __tmp + def networkLookupByUUID(self, uuid): + """Try to lookup a network on the given hypervisor based on its UUID. """ + ret = libvirtmod.virNetworkLookupByUUID(self._o, uuid) + if ret is None:raise libvirtError('virNetworkLookupByUUID() failed', conn=self) + __tmp = virNetwork(self, _obj=ret) + return __tmp + 2010-03-09 Eric Blake build: consistently indent preprocessor directives * global: patch created by running: for f in $(git ls-files '*.[ch]') ; do cppi $f > $f.t && mv $f.t $f done 2010-03-02 Daniel P. Berrange Introduce public API for domain async job handling Introduce a new public API that provides a way to get progress info on currently running jobs on a virDomainpPtr. APIs that are initially within scope of this idea are virDomainMigrate virDomainMigrateToURI virDomainSave virDomainRestore virDomainCoreDump These all take a potentially long time and benefit from monitoring. The virDomainJobInfo struct allows for various pieces of information to be reported - Percentage completion - Time - Overall data - Guest memory data - Guest disk/file data * include/libvirt/libvirt.h.in: Add virDomainGetJobInfo * python/generator.py, python/libvirt-override-api.xml, python/libvirt-override.c: Override for virDomainGetJobInfo API * python/typewrappers.c, python/typewrappers.h: Introduce wrapper for unsigned long long type 2010-02-17 Cole Robinson python: Actually add virConnectGetVersion to generated bindings The recent commit to implement a python version of this function didn't drop an explicit 'ignore' check in the generator, so this never ended up in the bindings. 2010-02-16 Jim Meyering libvirt-override.c: avoid a leak upon call with invalid argument * python/libvirt-override.c (libvirt_virConnectBaselineCPU): Don't leak the xmlcpus buffer upon encountering a non-string list element. 2010-02-12 Jiri Denemark virConnectBaselineCPU public API 2010-01-22 Taizo ITO Add virConnectGetVersion Python API adds a new python API call for retrieving the running hypervisor version used by a connection: virConnectGetVersion * python/generator.py: skip virConnectGetVersion from autogenerated * python/libvirt-override-api.xml python/libvirt-override.c: define direct native bindings 2010-01-18 Jim Meyering gnulib added a new syntax-check test: use $(VAR), not @VAR@ The latter is not officially "wrong", but *is* terribly anachronistic. I think automake documentation or comments call that syntax obsolescent. * cfg.mk (_makefile_at_at_check_exceptions): Exempt @SCHEMADIR@ and @SYSCONFDIR@ uses -- there are no Makefile variables for those. * docs/Makefile.am: Use $(INSTALL), not @INSTALL@. * examples/dominfo/Makefile.am: Similar. * examples/domsuspend/Makefile.am: Similar. * proxy/Makefile.am: Similar. * python/Makefile.am: Similar. * python/tests/Makefile.am: Similar. * src/Makefile.am: Similar. * tests/Makefile.am: Similar. 2010-01-06 Diego Elio Pettenò Disable building of static Python module * python/Makefile.am: python modules are loaded at runtime so the static version is not needed, avoid building it 2009-12-20 Adam Litke python: Add python bindings for virDomainMemoryStats Enable virDomainMemoryStats in the python API. dom.memoryStats() will return a dictionary containing the supported statistics. A dictionary is required because the meaining of each quantity cannot be inferred from its index in a list. * python/generator.py: reenable bindings for this entry point * python/libvirt-override-api.xml python/libvirt-override.c: the generator can't handle this new function, add the new binding, and the XML description 2009-12-20 Adam Litke Add new API virDomainMemoryStats to header and drivers Set up the types for the domainMemoryStats function and insert it into the virDriver structure definition. Because of static initializers, update every driver and set the new field to NULL. * include/libvirt/libvirt.h.in: new API * src/driver.h src/*/*_driver.c src/vbox/vbox_tmpl.c: add the new entry to the driver structure * python/generator.py: fix compiler errors, the actual python binding is implemented later 2009-12-14 Matthias Bolte Fix install location for Python bindings Commit 66137344feb488ea87b0d92f3c03844d9a7a7786 changed the Python detection mechanism in configure to use AM_PATH_PYTHON. This results in a changed install location for the Python bindings, at least on Fedora 12 64bit systems. Before this commit libvirt.py and libvirtmod.so were installed to /usr/lib64/python2.6/site-packages After this commit they are installed to /usr/lib/python2.6/site-packages Mixed Python packages (containing *.py and *.so files) should be installed to the pyexecdir directory detected by AM_PATH_PYTHON. This restores the install location from before the AM_PATH_PYTHON commit. * configure.in: remove unnecessary pythondir export * python/Makefile.am: switch from pythondir to pyexecdir 2009-12-08 Matthias Bolte Use AM_PATH_PYTHON and python-config to detect Python configuration Using AM_PATH_PYTHON solves the site-packages directory problem. At least in Ubuntu with Python 2.6 and later site-packages is renamed to dist-packages and site-packages is not part of sys.path anymore. So installing the libvirt Python bindings to site-packages renders them unusable, because they can be imported from there without manually including site-packages into sys.path. AM_PATH_PYTHON detects the correct site-packages/dist-packages directory. python-config --includes gives the correct include path for the Python header files. The old probing code stays there as fallback mechanism. * configure.in: use AM_PATH_PYTHON and python-config * python/Makefile.am: remove -I because PYTHON_INCLUDES contains it now 2009-11-26 Daniel P. Berrange Fix threading problems in python bindings * libvirt-override.c: Add many missing calls to allow threading when entering C code, otherwise python blocks & then deadlocks when we have an async event to dispatch back into python code. Fix return value check for virDomainPinVcpu binding. 2009-11-20 Cole Robinson python: Actually implement list*Interfaces bindings * python/generator.py python/libvirt-override-api.xml python/libvirt-override.c: implement the bindings for virConnectListInterfaces() and virConnectListDefinedInterfaces() 2009-11-12 Cole Robinson Add virConnectGetLibvirtVersion API There is currently no way to determine the libvirt version of a remote libvirtd we are connected to. This is a useful piece of data to enable feature detection. 2009-11-03 Dan Kenigsberg give up python interpreter lock before calling cb suggested by danpb on irc, patch by danken fixed for proper C syntax * python/libvirt-override.c: on event callback release the python interpreter lock and take it again when coming back so that the callback can reinvoke libvirt. 2009-10-05 Cole Robinson python: Add a newline after custom classes In the generated bindings, custom classes are squashed against the following class, which hurts readability. 2009-10-05 Cole Robinson python: Fix generated virInterface method names A mistake in the generator was causing virInterface methods to be generated with unpredicatable names ('ceUndefine', instead of just 'undefine'). This fixes the method names to match existing convention. Does anyone care if we are breaking API compat? My guess is that no one is using the python interface bindings yet. 2009-10-05 Cole Robinson python: Use a pure python implementation of 'vir*GetConnect' The API docs explictly warn that we shouldn't use the C vir*GetConnect calls in bindings: doing so can close the internal connection pointer and cause things to get screwy. Implement these calls in python. 2009-10-05 Cole Robinson python: Don't generate bindings for vir*Ref They are only for use in implementing the bindings, so shouldn't be exposed to regular API users. 2009-10-05 Cole Robinson python: Don't generate conflicting conn.createXML functions. A special case in the generator wasn't doing its job, and duplicate conn.createXML functions were being generated. The bindings diff is: @@ -1079,14 +1079,6 @@ class virConnect: return __tmp def createXML(self, xmlDesc, flags): - """Create a new device on the VM host machine, for example, - virtual HBAs created using vport_create. """ - ret = libvirtmod.virNodeDeviceCreateXML(self._o, xmlDesc, flags) - if ret is None:raise libvirtError('virNodeDeviceCreateXML() failed', conn=self) - __tmp = virNodeDevice(self, _obj=ret) - return __tmp - - def createXML(self, xmlDesc, flags): """Launch a new guest domain, based on an XML description similar to the one returned by virDomainGetXMLDesc() This function may requires privileged access to the hypervisor. @@ -1327,6 +1319,14 @@ class virConnect: __tmp = virNetwork(self, _obj=ret) return __tmp + def nodeDeviceCreateXML(self, xmlDesc, flags): + """Create a new device on the VM host machine, for example, + virtual HBAs created using vport_create. """ + ret = libvirtmod.virNodeDeviceCreateXML(self._o, xmlDesc, flags) + if ret is None:raise libvirtError('virNodeDeviceCreateXML() failed', conn=self) + __tmp = virNodeDevice(self, _obj=ret) + return __tmp + def nodeDeviceLookupByName(self, name): """Lookup a node device by its name. """ ret = libvirtmod.virNodeDeviceLookupByName(self._o, name) 2009-10-05 Cole Robinson python: Remove use of xmllib in generator.py xmllib has been deprecated since python 2.0, and running the generator throws a warning. Move to using xml.sax 2009-10-05 Cole Robinson python: Remove FastParser from generator. FastParser uses sgmlop, a non-standard python module meant as a replacement for xmllib (which is deprecated since python 2.0). Fedora doesn't even carry this module, and the generator doesn't have high performance requirements, so just rip the code out. 2009-09-29 Daniel P. Berrange Add public API definition for data stream handling * include/libvirt/libvirt.h.in: Public API contract for virStreamPtr object * src/libvirt_public.syms: Export data stream APIs * src/libvirt_private.syms: Export internal helper APIs * src/libvirt.c: Data stream API driver dispatch * src/datatypes.h, src/datatypes.c: Internal helpers for virStreamPtr object * src/driver.h: Define internal driver API for streams * .x-sc_avoid_write: Ignore src/libvirt.c because it trips up on comments including write() * python/Makefile.am: Add libvirt-override-virStream.py * python/generator.py: Add rules for virStreamPtr class * python/typewrappers.h, python/typewrappers.c: Wrapper for virStreamPtr * docs/libvirt-api.xml, docs/libvirt-refs.xml: Regenerate with new APIs 2009-09-28 Daniel P. Berrange Fix API doc extractor to stop munging comment formatting The python method help docs are copied across from the C funtion comments, but in the process all line breaks and indentation was being lost. This made the resulting text and code examples completely unreadable. Both the API doc extractor and the python generator were destroying whitespace & this fixes them to preserve it exactly. * docs/apibuild.py: Preserve all whitespace when extracting function comments. Print function comment inside a Misc syntax-check fixes 2009-09-21 Daniel P. Berrange Re-arrange python generator to make it clear what's auto-generated * README: New file describing what each file is used for * livvirt-override.c, libvirt-override.py, libvirt-override-api.xml, libvirt-override-virConnect.py: Manually written code overriding the generator * typewrappers.c, typewrappers.h: Data type wrappers * generator.py: Automatically pre-prend contents of libvirt-override.py to generated libvirt.py. Output into libvirt.py directly instead of libvirtclass.py. Don't generate libvirtclass.txt at all. Write C files into libvirt.c/.h directly * Makefile.am: Remove rule for creating libvirt.py from libvirt-override.py and libvirtclass.py, since generator.py does it directly 2009-09-14 Daniel P. Berrange Add usage type/id as a public API property of virSecret * include/libvirt/libvirt.h, include/libvirt/libvirt.h.in: Add virSecretGetUsageType, virSecretGetUsageID and virLookupSecretByUsage * python/generator.py: Mark virSecretGetUsageType, virSecretGetUsageID as not throwing exceptions * qemud/remote.c: Implement dispatch for virLookupSecretByUsage * qemud/remote_protocol.x: Add usage type & ID as attributes of remote_nonnull_secret. Add RPC calls for new public APIs * qemud/remote_dispatch_args.h, qemud/remote_dispatch_prototypes.h, qemud/remote_dispatch_ret.h, qemud/remote_dispatch_table.h, qemud/remote_protocol.c, qemud/remote_protocol.h: Re-generate * src/datatypes.c, src/datatypes.h: Add usageType and usageID as properties of virSecretPtr * src/driver.h: Add virLookupSecretByUsage driver entry point * src/libvirt.c: Implement virSecretGetUsageType, virSecretGetUsageID and virLookupSecretByUsage * src/libvirt_public.syms: Export virSecretGetUsageType, virSecretGetUsageID and virLookupSecretByUsage * src/remote_internal.c: Implement virLookupSecretByUsage entry * src/secret_conf.c, src/secret_conf.h: Remove the virSecretUsageType enum, now in public API. Make volume path mandatory when parsing XML * src/secret_driver.c: Enforce usage uniqueness when defining secrets. Implement virSecretLookupByUsage api method * src/virsh.c: Include usage for secret-list command 2009-09-14 Daniel P. Berrange Fix UUID handling in secrets/storage encryption APIs Convert all the secret/storage encryption APIs / wire format to handle UUIDs in raw format instead of non-canonical printable format. Guarentees data format correctness. * docs/schemas/storageencryption.rng: Make UUID mandatory for a secret and validate fully * docs/schemas/secret.rng: Fully validate UUID * include/libvirt/libvirt.h, include/libvirt/libvirt.h.in, Add virSecretLookupByUUID and virSecretGetUUID. Make virSecretGetUUIDString follow normal API design pattern * python/generator.py: Skip generation of virSecretGetUUID, virSecretGetUUIDString and virSecretLookupByUUID * python/libvir.c, python/libvirt-python-api.xml: Manual impl of virSecretGetUUID,virSecretGetUUIDString and virSecretLookupByUUID * qemud/remote.c: s/virSecretLookupByUUIDString/virSecretLookupByUUID/ Fix get_nonnull_secret/make_nonnull_secret to use unsigned char * qemud/remote_protocol.x: Fix remote_nonnull_secret to use a remote_uuid instead of remote_nonnull_string for UUID field. Rename REMOTE_PROC_SECRET_LOOKUP_BY_UUID_STRING to REMOTE_PROC_SECRET_LOOKUP_BY_UUID_STRING and make it take an remote_uuid value * qemud/remote_dispatch_args.h, qemud/remote_dispatch_prototypes.h, qemud/remote_dispatch_ret.h, qemud/remote_dispatch_table.h, qemud/remote_protocol.c, qemud/remote_protocol.h: Re-generate * src/datatypes.h, src/datatypes.c: Store UUID in raw format instead of printable. Change virGetSecret to use raw format UUID * src/driver.h: Rename virDrvSecretLookupByUUIDString to virDrvSecretLookupByUUID and use raw format UUID * src/libvirt.c: Add virSecretLookupByUUID and virSecretGetUUID and re-implement virSecretLookupByUUIDString and virSecretGetUUIDString in terms of those * src/libvirt_public.syms: Add virSecretLookupByUUID and virSecretGetUUID * src/remote_internal.c: Rename remoteSecretLookupByUUIDString to remoteSecretLookupByUUID. Fix typo in args for remoteSecretDefineXML impl. Use raw UUID format for get_nonnull_secret and make_nonnull_secret * src/storage_encryption_conf.c, src/storage_encryption_conf.h: Storage UUID in raw format, and require it to be present in XML. Use UUID parser to validate. * secret_conf.h, secret_conf.c: Generate a UUID if none is provided. Storage UUID in raw format. * src/secret_driver.c: Adjust to deal with raw UUIDs. Save secrets in a filed with printable UUID, instead of base64 UUID. * src/virsh.c: Adjust for changed public API contract of virSecretGetUUIDString. * src/storage_Backend.c: DOn't undefine secret we just generated upon successful volume creation. Fix to handle raw UUIDs. Generate a non-clashing UUID * src/qemu_driver.c: Change to use lookupByUUID instead of lookupByUUIDString 2009-09-03 Jim Meyering python: let libvirt_virConnectDomainEventCallback indicate success * python/libvir.c (libvirt_virConnectDomainEventCallback): Return 0 when successful, rather than always returning -1. clang flagged this function for its dead-store of "ret=0". Once "ret" was set to 0, it was never used, and the function would always return -1. 2009-09-01 Miloslav Trmač Secret manipulation API docs refresh & wire up python generator Sample session: >>> import libvirt >>> c = libvirt.open('qemu:///session') >>> c.listSecrets() ['12247729-47d2-a783-88ce-b329d4781cd3', 'reee', 'abc'] >>> s = c.secretDefineXML("\nSomething for use\n/foo/bar\n\n") >>> s.UUIDString() '340c2dfb-811b-eda8-da9e-25ccd7bfd650' >>> s.XMLDesc() "\n 340c2dfb-811b-eda8-da9e-25ccd7bfd650\n Something for use\n /foo/bar\n\n" >>> s.setValue('abc\0xx\xffx') 0 >>> s.value() 'abc\x00xx\xffx' >>> s.undefine() 0 * python/generator.py: Add rules for virSecret APIs * python/libvir.c, python/libvirt-python-api.xml: Manual impl of virSecretSetValue, virSecretGetValue$ and virConnectListSecrets APIs * python/libvirt_wrap.h, python/types.c: Wrapper for virSecret objects * docs/libvirt-api.xml, docs/libvirt-refs.xml, docs/html/libvirt-virterror.html, docs/html/libvirt-libvirt.html, docs/devhelp/libvirt-virterror.html, docs/devhelp/libvirt-libvirt.html: Re-generate with 'make api' 2009-07-26 Cole Robinson python: Raise exceptions if virDomain*Stats fail. The generator couldn't tell that the stats return values were pointers. Stick a white list in the function which tries to make this distinction. 2009-07-16 Jim Meyering remove all trailing blank lines by running this command: git ls-files -z | xargs -0 perl -pi -0777 -e 's/\n\n+$/\n/' This is in preparation for a more strict make syntax-check rule that will detect trailing blank lines. 2009-07-08 Jim Meyering remove all .cvsignore files 2009-07-06 Dan Kenigsberg Fix python examples to use read-write conn * docs/examples/python/domstart.py python/tests/create.py: The two example were broken as they needed full-access connection but only opened read-only connections 2009-05-28 Daniel P. Berrange Fix python domain events example & binding 2009-05-21 Daniel P. Berrange Add virInterface APIs to python code generator 2009-05-19 Cole Robinson Better error reporting if 'import libvirtmod' fails Don't squash a possibly legitimate libvirtmod error (e.g. some from clashing libvirt.so versions) with 'Cannot import cygvirtmod' 2009-04-01 Daniel P. Berrange Fix crash after calling virConnectClose 2009-04-01 Daniel P. Berrange Fix generation of networkCreateXML and storagePoolCreateXML 2009-03-03 Jim Meyering update .gitignore and .hgignore files 2009-03-03 Daniel P. Berrange Internal driver API for sVirt support (James Morris & Dan Walsh) 2009-03-02 Daniel P. Berrange Ignore some generated autotools files in example app 2009-02-26 Daniel Veillard * python/Makefile.am: avoid a parallel make issue #472702 provided by Michael Marineau Daniel 2009-02-16 Cole Robinson Fix building python bindings: Skip bindings for virSaveLastError and virFreeError 2009-01-20 Daniel P. Berrange Use global thread-local error for all python error reporting 2008-12-18 Daniel P. Berrange Replace __FUNCTION__ with __func__ for better portability (John Levon) 2008-12-18 Daniel P. Berrange Fix gcc-ism in python build (John Levon) 2008-12-15 Jim Meyering syntax-check: enforce the no-cvs-keywords prohibition * Makefile.maint (sc_prohibit_cvs_keyword): New rule. Suggested by Daniel Veillard. The new test exposed two uses of $Date$. * docs/Goals: Don't use $Date$. * python/TODO: Likewise. 2008-11-25 Daniel P. Berrange Support domain lifecycle events for Xen (Ben Guthro & Daniel Berrange) 2008-11-24 Daniel P. Berrange Fix python bindings events code (David Lively) 2008-11-21 Daniel P. Berrange Python binding for node device APIs (David Lively) 2008-11-19 Daniel P. Berrange Add a virFreeCallback to event loop APIs 2008-11-19 Daniel P. Berrange Change public API for virEventAddHandle to allow multiple registrations per FD 2008-11-19 Daniel P. Berrange Add a virFreeCallback to virDomainEventRegister (from David Lively) 2008-11-17 Daniel P. Berrange Add domain events detail information 2008-11-17 Daniel P. Berrange Fix domain events python thread safety & incorrect enum generation 2008-10-31 Daniel Veillard * python/virConnect.py: needed for events from the python bindings by Ben Guthro daniel 2008-10-31 Daniel Veillard * python/Makefile.am python/generator.py python/libvir.c python/libvir.py python/libvirt_wrap.h python/types.c: adds support for events from the python bindings, also improves the generator allowing to embbed per function definition files, patch by Ben Guthro * examples/domain-events/events-python/event-test.py: also adds a programming example Daniel 2008-10-23 Daniel Veillard Massive patch adding event APIs by Ben Guthro * include/libvirt/libvirt.h include/libvirt/libvirt.h.in src/libvirt.c src/libvirt_sym.version: new libvirt event entry points, big patch provided by Ben Guthro * Makefile.am configure.in src/driver.h src/event.c src/event.h src/internal.h src/libvirt.c src/libvirt_sym.version src/lxc_driver.c src/openvz_driver.c src/qemu_conf.h src/qemu_driver.c src/remote_internal.c src/storage_backend_fs.c src/test.c qemud/event.c qemud/event.h qemud/mdns.c qemud/qemud.c qemud/qemud.h qemud/remote.c qemud/remote_dispatch_localvars.h qemud/remote_dispatch_proc_switch.h qemud/remote_dispatch_prototypes.h qemud/remote_protocol.c qemud/remote_protocol.h qemud/remote_protocol.x proxy/Makefile.am python/generator.py: Not much is left untouched by the patch adding the events support * docs/libvirt-api.xml docs/libvirt-refs.xml docs/html/libvirt-libvirt.html: regenerated the docs * examples/domain-events/events-c/Makefile.am examples/domain-events/events-c/event-test.c: a test example * AUTHORS: added Ben Guthro daniel 2008-10-17 Jim Meyering generate .gitignore files from .cvsignore ones * Makefile.maint (sync-vcs-ignore-files): New target. Prompted by a patch from James Morris. http://thread.gmane.org/gmane.comp.emulators.libvirt/8619/focus=8773 Add all (now-generated) .gitignore files. * .gitignore: New file. * build-aux/.gitignore: New file. * docs/.gitignore: New file. * docs/devhelp/.gitignore: New file. * docs/examples/.gitignore: New file. * docs/examples/python/.gitignore: New file. * gnulib/lib/.gitignore: New file. * gnulib/lib/arpa/.gitignore: New file. * gnulib/lib/netinet/.gitignore: New file. * gnulib/lib/sys/.gitignore: New file. * gnulib/tests/.gitignore: New file. * include/.gitignore: New file. * include/libvirt/.gitignore: New file. * po/.gitignore: New file. * proxy/.gitignore: New file. * python/.gitignore: New file. * python/tests/.gitignore: New file. * qemud/.gitignore: New file. * src/.gitignore: New file. * tests/.gitignore: New file. * tests/confdata/.gitignore: New file. * tests/sexpr2xmldata/.gitignore: New file. * tests/virshdata/.gitignore: New file. * tests/xencapsdata/.gitignore: New file. * tests/xmconfigdata/.gitignore: New file. * tests/xml2sexprdata/.gitignore: New file. 2008-10-01 Daniel Veillard Xen interface order and fix python parallel build * src/xend_internal.c: fix ordering when parsing multiple Xen interfaces, patch by Jim Fehlig * python/Makefile.am: fix parallel build Daniel 2008-08-22 Daniel P. Berrange Use libvirt error message for python exceptions 2008-08-12 Daniel Veillard Fix connection lookup in python storage instances * python/generator.py: patch from Cole Robinson trying to fix problem of connection lookup when creating storage instances Daniel 2008-07-25 Daniel Veillard Skip python bindings for virDomainBlockPeek and virDomainMemoryPeek * python/generator.py: skip generation for virDomainBlockPeek and virDomainMemoryPeek as they break the build Daniel 2008-07-09 Daniel P. Berrange Ignore JIT'd python files 2008-06-25 Daniel Veillard * python/types.c: patch from Ryan Scott to remove misplaced verbosity when compiling in debug mode. Daniel 2008-06-11 Daniel Veillard * python/libvir.py python/libvirt-python-api.xml: more python cleanups by Cole Robinson Daniel 2008-06-10 Daniel Veillard * python/generator.py python/libvir.c python/libvirt-python-api.xml: Apply patch from Cole Robinson fixing UUIDString for python Daniel 2008-05-29 Daniel P. Berrange Fix python code generation for storage APIs 2008-05-21 Daniel P. Berrange Don't free C object after destroy method in python 2008-04-18 Daniel P. Berrange Python header workaround 2008-04-18 Jim Meyering Work around Python.h name-space pollution. * python/libvir.c (HAVE_PTHREAD_H): #undef. Without this, we'd get a redefinition warning. 2008-04-10 Jim Meyering convert TAB-based indentation in C sources to use only spaces Done using this command (also includes .c.in and .h.in files): for i in $(g ls-files|grep -E '\.[ch](\.in)?$'|grep -v gnulib); do expand -i $i > j && mv j $i;done 2008-04-10 Jim Meyering remove Vim and Emacs variable settings from C source files Done with these commands: git grep -l Local.variab|xargs \ perl -0x3b -pi -e 's,\n+/\*\n \* vim:(.|\n)*,\n,' git grep -l Local.variab|xargs \ perl -0x3b -pi -e 's,\n+/\*\n \* Local variables:\n(.|\n)*,\n,' 2008-04-08 Daniel Veillard Fix potential infinite loop in python generator * python/generator.py: fix an infinite loop bug Daniel 2008-03-14 Richard W.M. Jones Fix typo "informations" -> "information" (Atsushi SAKAI and Saori FUKUTA). 2008-02-29 Richard W.M. Jones Many typos fixed (Atsushi SAKAI). 2008-02-20 Daniel P. Berrange Added python binding for storage APIs 2008-02-07 Daniel Veillard Python bindings return values fixes * python/libvir.c: apply patch from Cole Robinson to provide return values for manulally written python bindings. Daniel 2008-02-05 Jim Meyering Remove all trailing blanks; turn on the rule to detect them. * Makefile.cfg (local-checks-to-skip): Remove sc_trailing_blank. * .x-sc_trailing_blank: New file, to exempt the few binary files. 2008-01-29 Jim Meyering Enable the -requiring test; fix violations Use , not "config.h", per autoconf documentation. * Makefile.cfg (local-checks-to-skip) [sc_require_config_h]: Enable. * .x-sc_require_config_h: New file, to list exempted files. * Makefile.am (EXTRA_DIST): Add .x-sc_require_config_h. 2008-01-29 Jim Meyering Given code like if (foo) free (foo); remove the useless "if (foo) " part. Likewise, given if (foo != NULL) free (foo); remove the useless "if" test. * proxy/libvirt_proxy.c: Remove unnecessary "if" test before free. * python/generator.py: Likewise. * qemud/qemud.c: Likewise. * src/buf.c: Likewise. * src/conf.c: Likewise. * src/hash.c: Likewise. * src/iptables.c: Likewise. * src/libvirt.c: Likewise. * src/openvz_conf.c: Likewise. * src/qemu_conf.c: Likewise. * src/qemu_driver.c: Likewise. * src/remote_internal.c: Likewise. * src/test.c: Likewise. * src/virsh.c: Likewise. * src/virterror.c: Likewise. * src/xen_internal.c: Likewise. * src/xen_unified.c: Likewise. * src/xend_internal.c: Likewise. * src/xm_internal.c: Likewise. * src/xml.c: Likewise. * src/xmlrpc.c: Likewise. * src/xs_internal.c: Likewise. * tests/testutils.c: Likewise. * tests/xencapstest.c: Likewise. * tests/xmconfigtest.c: Likewise. 2008-01-21 Daniel P. Berrange Make python generator fail build on any missing APIs 2008-01-21 Daniel P. Berrange Add missing vcpu/schedular APIs to python binding 2008-01-17 Jim Meyering Handle PyTuple_New's malloc failure. * python/libvir.c (libvirt_virDomainBlockStats): Handle a NULL return from PyTuple_New. (libvirt_virDomainInterfaceStats, libvirt_virGetLastError): Likewise. (libvirt_virConnGetLastError): Likewise. 2008-01-17 Jim Meyering Factor out some duplication. * python/libvir.c (VIR_PY_NONE): New macro, to encapsulate a common two-statement sequence. Replace all such 2-stmt sequences. 2007-12-11 Jim Meyering Use a variable name as sizeof argument, not a type name. Given code like: T *var = calloc (n, sizeof (T)); Convert to this: T *var = calloc (n, sizeof (*var)); This first-cut change adjusts all malloc, calloc, and realloc statements. The only binary differences are in remote_internal.c (due to the bug fix) and in xmlrpc.c (due to factorization). * python/libvir.c: As above. * qemud/event.c: Likewise. * qemud/mdns.c: Likewise. * qemud/qemud.c: Likewise. * qemud/remote.c: Likewise. * src/bridge.c: Likewise. * src/buf.c: Likewise. * src/conf.c: Likewise. * src/hash.c: Likewise. * src/iptables.c: Likewise. * src/openvz_conf.c: Likewise. * src/qemu_conf.c: Likewise. * src/qemu_driver.c: Likewise. * src/test.c: Likewise. * src/xen_internal.c: Likewise. * src/xen_unified.c: Likewise. * src/xm_internal.c: Likewise. * src/xml.c: Likewise. * tests/qemuxml2argvtest.c: Likewise. * src/xmlrpc.c (xmlRpcValuePtr): Likewise, and minor factorization. * src/remote_internal.c (remoteAuthMakeCredentials): Use the right type when allocating space for an array of cred _pointers_. 2007-12-07 Jim Meyering Include "config.h" in remaining non-generated files. * proxy/libvirt_proxy.c: Likewise. * python/libvir.c: Likewise. * python/types.c: Likewise. * src/event.c: Likewise. * src/xm_internal.c: Likewise. * tests/reconnect.c: Likewise. * tests/testutils.c: Likewise. 2007-12-07 Daniel Veillard * python/generator.py python/libvir.c python/libvirt-python-api.xml: add a python binding for virNodeGetCellsFreeMemory Daniel 2007-12-05 Daniel P. Berrange Add manual impl of virConnectOpenAuth python binding 2007-12-05 Richard W.M. Jones Wed Dec 5 13:48:00 UTC 2007 Richard W.M. Jones * python/libvir.c, python/libvirt_wrap.h, qemud/qemud.c, qemud/remote.c, src/internal.h, src/openvz_conf.c, src/openvz_driver.c, src/proxy_internal.h, src/qemu_conf.c, src/qemu_driver.c, src/remote_internal.h, src/test.h, src/util.c, src/xen_unified.c, src/xen_unified.h, tests/nodeinfotest.c, tests/qemuxml2argvtest.c, tests/qemuxml2xmltest.c, tests/reconnect.c, tests/sexpr2xmltest.c, tests/virshtest.c, tests/xencapstest.c, tests/xmconfigtest.c, tests/xml2sexprtest.c: Change #include <> to #include "" for local includes. Removed many includes from src/internal.h and put them in the C files which actually use them. Removed - unused. Added a comment around __func__. Removed a clashing redefinition of VERSION symbol. All limits (PATH_MAX etc) now done in src/internal.h, so we don't need to include those headers in other files. 2007-11-30 Richard W.M. Jones Fri Nov 30 11:04:00 GMT 2007 Richard W.M. Jones * python/libvir.c, python/libvir.py: Make Python aware that the C bindings module is called cygvirtmod.dll when compiled by CYGWIN. * python/Makefile.am: Remove symlink libvirtmod.dll -> cygvirtmod.dll no longer necessary because of the above. * configure.in: Remove AM_CONDITIONAL(CYGWIN). 2007-11-29 Richard W.M. Jones Thu Nov 29 17:40:00 GMT 2007 Richard W.M. Jones * configure.in: Added CYGWIN_EXTRA_LDFLAGS, CYGWIN_EXTRA_LIBADD, CYGWIN_EXTRA_PYTHON_LIBADD, CYGWIN automake conditional. * src/Makefile.am: Extra flags required to build DLL of libvirt for Cygwin. * python/Makefile.am: Extra flags and rule required to build Python module for Cygwin. 2007-11-15 Jim Meyering Make "make distcheck" work. * Makefile.am: Expand some "*" wildcards, and (for now) disable the relatively unimportant, distuninstallcheck target. Fix a few redirect-directly-to-target bugs. Add a few $(srcdir)/ prefixes and add an uninstall-local rule. * docs/Makefile.am: More of the same. Split some long lines. * python/Makefile.am: Likewise. * python/tests/Makefile.am: Likewise. * qemud/Makefile.am: Likewise. * tests/Makefile.am: Remove the directories already listed in SUBDIRS. * docs/examples/index.py: Adapt to produce the desired changes in docs/examples/Makefile.am. Also, sort *.c, so results are reproducible, and emit a comment telling emacs and vi that the file is read-only. * docs/examples/Makefile.am: Regenerate. Author: Jim Meyering 2007-09-30 Daniel Veillard * python/generator.py python/libvir.c python/libvirt-python-api.xml: provide bindings for block and interface statistics Daniel 2007-07-24 Daniel Veillard * libvirt.spec.in NEWS docs/* po/*: preparing release 0.3.1 * src/libvirt.c python/generator.py: some cleanup and warnings from Richard W.M. Jones Daniel 2007-06-26 Richard W.M. Jones Tue Jun 26 14:40:00 BST 2007 Richard W.M. Jones * src/remote_internal.c, python/Makefile.am: Python bindings fixed, and now building virConnect.getHostname and virConnect.getURI. Fixed a problem which stopped libvirt.py from being (re-)built. Rearranged python/Makefile.am to make it cleaner and clearer. 2007-06-25 Richard W.M. Jones Mon Jun 25 16:55:00 BST 2007 Richard W.M. Jones * include/libvirt/libvirt.h.in, src/libvirt.c, src/libvirt_sym.version, python/generator.py: Added virDomainGetConnect and virNetworkGetConnect to allow us to get the "hidden" connection associated with each domain or network. 2007-06-15 Richard W.M. Jones Fri Jun 15 08:53:00 BST 2007 Richard W.M. Jones * src/internal.h, src/virsh.c: Replace _N with N_ so that Solaris builds work (Mark Johnson). * src/virsh.c: Add a couple of missing error messages (Mark Johnson). * python/types.c: Fix NULL pointer deref on DEBUG build (Mark Johnson). * src/virsh.c: Spelling fix (Mark Johnson). 2007-05-29 Richard W.M. Jones +Tue May 29 15:56:00 BST 2007 Richard W.M. Jones + + * python/generator.py, python/libvir.c, python/libvir.py: + Wrap the virGetVersion call as Python libvirt.getVersion. + + * src/libvirt.c: Change virGetVersion so that the driver name + is case insensitive. + 2007-04-16 Daniel P. Berrange Fixed exception reporting for domain/network operations 2007-04-10 Daniel P. Berrange Added vir*GetAutostart APIs to python 2007-03-28 Richard W.M. Jones * python/generator.py: Python bindings now throw exceptions in almost all cases where an error is encountered in the underlying libvirt code. 2007-03-16 Daniel Veillard * python/generator.py: patch from Tatsuro Enokura to fix virNetworkDefine binding Daniel 2007-03-15 Daniel Veillard * python/generator.py: fix the python binding generation for virNetworkLookup...() functions, which were clashing with equivalent virConnLookup...() equivalents, as reported by Tatsuro Enokura Daniel 2007-03-09 Daniel P. Berrange Added python bindings for networking APIs 2007-03-06 Daniel P. Berrange Fixed up numerous compiler warnings 2007-03-01 Mark McLoughlin Thu Mar 01 16:17:48 EST 2007 Mark McLoughlin * acinclude.m4: add LIBVIRT_COMPILE_WARNINGS, copied from GNOME but with a few more flags we'd been using. * configure.in: use that instead of setting CFLAGS directly. * proxy/Makefile.am, python/Makefile.am, qemud/Makefile.am, src/Makefile.am, tests/Makefile.am: use $(WARN_CFLAGS) 2007-02-14 Daniel P. Berrange Blacklist vshRunConsole from python 2007-01-23 Mark McLoughlin Mon Jan 23 14:36:18 IST 2007 Mark McLoughlin * include/libvirt/libvirt.h.in: add VIR_UUID_BUFLEN and VIR_UUID_STRING_BUFLEN * libvirt/proxy/libvirt_proxy.c, libvirt/src/hash.c, libvirt/src/internal.h, libvirt/src/libvirt.c, libvirt/src/proxy_internal.c, libvirt/src/test.c, libvirt/src/virsh.c, libvirt/src/xend_internal.c, libvirt/src/xm_internal.c, libvirt/src/xml.c, libvirt/python/libvir.c: use them 2006-11-16 Daniel P. Berrange Added binding for virConnectListDefinedDomains api 2006-11-15 Daniel P. Berrange Fix unsigned long wraparound in python binding 2006-11-10 Daniel P. Berrange Fixed string concatenation in case where there is no lower level error 2006-11-09 Daniel Veillard * python/generator.py: changed the generator to generate a reference from Domain class instances to the Connect they were issued from should fix rhbz#204490 * docs//*: rebuilt Daniel 2006-11-07 Daniel P. Berrange Propagate libvirt errors back with python exceptions 2006-10-24 Daniel P. Berrange Make python bindings threaded, by dropping/acquiring Python GIL where needed 2006-08-29 Daniel Veillard * python/libvir.c: Pete Vetere pointed out a bug in string cast when handling errors in Python Daniel 2006-08-04 Daniel Veillard * python/generator.py: fix the generator when handling long integers Dan Berrange reported problems due to this when using virDomainSetMemory bindings Daniel 2006-07-05 Mark McLoughlin unleash the hush puppies 2006-06-26 Daniel Veillard * configure.in libvirt.spec.in docs/examples/* include/Makefile.am include/libvirt/virterror.h python/generator.py python/libvir.c python/libvirt_wrap.h src/driver.h src/internal.h src/test.h src/virsh.c src/virterror.c src/xend_internal.c src/xend_internal.h src/xml.c src/xml.h: moved the includes from include/ to include/libvirt to reflect the installed include tree. This avoid using "" in the includes themselves. Daniel 2006-03-29 Daniel Veillard * python/libvir.c: fixed a bug in the new wrapper * python/tests/Makefile.am python/tests/node.py: added a new test for the new API * python/tests/create.py: remove a debug Daniel 2006-03-29 Daniel Veillard * include/libvirt.h[.in] include/virterror.h src/driver.h src/internal.h src/libvirt_sym.version src/xen_internal.c src/xs_internal.c: added a new entry point to get node hardware informations virGetNodeInfo, and associated driver hook. * src/xend_internal.c: implemented the node and version information hooks for the Xen Daemon * python/libvir.c python/libvirt-python-api.xml python/generator.py: also added Python bindings for the new call Daniel 2006-03-28 Daniel Veillard * python/libvir.c: call the initialize entry point * src/libvirt_sym.version: add initialize entry point * src/libvirt.c: make sure we always initialize the lib * python/tests/*.py: start updating exemple for exception handling as pointed by Jim Meyering Daniel 2006-03-28 Daniel Veillard * doc/site.xsl doc/libvir.html doc/*: added informations about the Perl bindings, regenerated * python/libvirt_wrap.h: added a missing include. Daniel 2006-03-23 Daniel Veillard * src/xs_internal.c src/xs_internal.h include/virterror.h src/virterror.c: created a new module related to Xen Store accesses * src/libvirt.c src/xen_internal.[ch] src/xend_internal.[ch]: nearly completed the separation of the code from the different modules Daniel 2006-03-22 Daniel Veillard * python/tests/create.py: add one more image path * src/libvirt.c src/xend_internal.c src/xend_internal.h: more work on the xend refactoring Daniel 2006-03-22 Daniel Veillard * python/tests/create.py: adapt to new naming scheme in FC5 Daniel 2006-02-28 Daniel Veillard * NEWS configure.in libvirt.spec.in include/libvirt.h docs/*: preparing release 0.0.6 Daniel 2006-02-28 Daniel Veillard Fixed the test, daniel 2006-02-28 Daniel Veillard * TODO: updated * python/Makefile.am python/generator.py python/libvir.c python/libvir.py: improved python binding, raise exception when an instance creation or lookup fails, and add support for the global error handler, per conn handler still needed * python/tests/error.py python/tests/Makefile.am: adding a regression test Daniel 2006-02-24 Daniel Veillard * python/generator.py python/libvir.c python/libvirt-python-api.xml: UUID strings can contain zeroes, so the autogenerated conversion functions don't work. Daniel 2006-02-23 Daniel Veillard * src/libvirt.c: fixing a bug before the release of 0.0.5 * python/generator.py python/libvir.c python/libvirt-python-api.xml: also fixing the binding for getting a domain UUID * python/tests/Makefile.am python/tests/uuid.py: added a test for the new UUID API Daniel 2006-02-23 Daniel Veillard * python/tests/Makefile.am: added the create.py in the regression tests Daniel 2006-02-21 Daniel Veillard * TODO: updated * python/tests/Makefile.am: fix a small PYTHONPATH bug * docs//*: fixed the xsl a bit for toc names, added doc for the python bindings, regenerated Daniel 2006-02-20 Daniel Veillard * docs/examples/examples.xsl docs/examples/index.html docs/site.xsl: integates the examples page in the web site * docs//* : fixed generator and rebuilt the docs * python/tests/basic.py python/tests/create.py: couple cleanups Daniel 2006-02-17 Daniel Veillard * python/tests/create.py: trying to make test more generic, but it's difficult since it requires a system image * src/libvirt.c src/xend_internal.c: fixed the shutdown API which was broken due to a bad reason at the xend level. Daniel 2006-02-16 Daniel Veillard * configure.in src/Makefile.am: adding dependency to libxml2 * include/libvirt.h* src/libvirt.c src/xend_internal.[ch] src/xml.[ch]: added XML parsing for Xen domain descriptions needed for creates, plugged in a converter to s-exp and xend call. Modified the virDomainCreateLinux() to reflect that XML based description. Seems to work. * python/tests/create.py: added a test case which seems to work not tested much yet * docs/*: regenerated Daniel 2006-02-15 Daniel Veillard * configure.in libvirt.spec.in include/libvirt.h.in python/Makefile.am src/Makefile.am: fix rpm packaging problems whith head, more LIBVIR -> LIBVIRT changes. Daniel 2006-02-14 Daniel Veillard * Makefile.am configure.in python/Makefile.am python/tests/Makefile.am python/tests/basic.py: added first python test script and a 'make tests' target Daniel 2006-02-10 Daniel Veillard * python/libvir.c: fixed one more problem prior to 0.0.4 Daniel 2006-02-09 Daniel Veillard * //* : renamed the project libvirt , this affects all makefiles, the specs, the icons, the docs, etc ... * configure.in: prepare for 0.0.3 Daniel 2006-01-31 Daniel Veillard * python/*: update of the python bindings, fix names, add missing features like list of domains and domain info extraction Daniel 2006-01-28 Daniel Veillard * python/libvir.c: fix a stupid bug in python bindings (DomainDestroy is still mishandled though) Daniel 2006-01-26 Daniel Veillard * TODO: updated * docs/search.php: use the new web site design * python/generator.py: fix a generation bug on python keyword Daniel 2005-12-19 Daniel Veillard * Makefile.am configure.in libvir.spec.in python/*: added a first version for python bindings, heavilly based on libxml2/libxslt way of doing things, maybe this need to be revisited. Added packaging too. * src/hash.h: fixed the Copyright notice. Daniel libvirt-python-1.2.2/libvirt-qemu-override.c0000664000076400007640000001167512263141061022555 0ustar veillardveillard00000000000000/* * libvir.c: this modules implements the main part of the glue of the * libvir library and the Python interpreter. It provides the * entry points where an automatically generated stub is * unpractical * * Copyright (C) 2011-2012 Red Hat, Inc. * * Daniel Veillard */ /* Horrible kludge to work around even more horrible name-space pollution via Python.h. That file includes /usr/include/python2.5/pyconfig*.h, which has over 180 autoconf-style HAVE_* definitions. Shame on them. */ #undef HAVE_PTHREAD_H #include #include #include #include "typewrappers.h" #include "libvirt-utils.h" #include "build/libvirt-qemu.h" #if PY_MAJOR_VERSION > 2 # ifndef __CYGWIN__ extern PyObject *PyInit_libvirtmod_qemu(void); # else extern PyObject *PyInit_cygvirtmod_qemu(void); # endif #else # ifndef __CYGWIN__ extern void initlibvirtmod_qemu(void); # else extern void initcygvirtmod_qemu(void); # endif #endif #if 0 # define DEBUG_ERROR 1 #endif #if DEBUG_ERROR # define DEBUG(fmt, ...) \ printf(fmt, __VA_ARGS__) #else # define DEBUG(fmt, ...) \ do {} while (0) #endif /* The two-statement sequence "Py_INCREF(Py_None); return Py_None;" is so common that we encapsulate it here. Now, each use is simply return VIR_PY_NONE; */ #define VIR_PY_NONE (Py_INCREF (Py_None), Py_None) #define VIR_PY_INT_FAIL (libvirt_intWrap(-1)) #define VIR_PY_INT_SUCCESS (libvirt_intWrap(0)) /************************************************************************ * * * Statistics * * * ************************************************************************/ static PyObject * libvirt_qemu_virDomainQemuMonitorCommand(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { PyObject *py_retval; char *result = NULL; virDomainPtr domain; PyObject *pyobj_domain; unsigned int flags; char *cmd; int c_retval; if (!PyArg_ParseTuple(args, (char *)"Ozi:virDomainQemuMonitorCommand", &pyobj_domain, &cmd, &flags)) return NULL; domain = (virDomainPtr) PyvirDomain_Get(pyobj_domain); if (domain == NULL) return VIR_PY_NONE; LIBVIRT_BEGIN_ALLOW_THREADS; c_retval = virDomainQemuMonitorCommand(domain, cmd, &result, flags); LIBVIRT_END_ALLOW_THREADS; if (c_retval < 0) return VIR_PY_NONE; py_retval = libvirt_constcharPtrWrap(result); VIR_FREE(result); return py_retval; } #if LIBVIR_CHECK_VERSION(0, 10, 0) static PyObject * libvirt_qemu_virDomainQemuAgentCommand(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { PyObject *py_retval; char *result = NULL; virDomainPtr domain; PyObject *pyobj_domain; int timeout; unsigned int flags; char *cmd; if (!PyArg_ParseTuple(args, (char *)"Ozii:virDomainQemuAgentCommand", &pyobj_domain, &cmd, &timeout, &flags)) return NULL; domain = (virDomainPtr) PyvirDomain_Get(pyobj_domain); if (domain == NULL) return VIR_PY_NONE; LIBVIRT_BEGIN_ALLOW_THREADS; result = virDomainQemuAgentCommand(domain, cmd, timeout, flags); LIBVIRT_END_ALLOW_THREADS; if (!result) return VIR_PY_NONE; py_retval = libvirt_constcharPtrWrap(result); VIR_FREE(result); return py_retval; } #endif /* LIBVIR_CHECK_VERSION(0, 10, 0) */ /************************************************************************ * * * The registration stuff * * * ************************************************************************/ static PyMethodDef libvirtQemuMethods[] = { #include "build/libvirt-qemu-export.c" {(char *) "virDomainQemuMonitorCommand", libvirt_qemu_virDomainQemuMonitorCommand, METH_VARARGS, NULL}, #if LIBVIR_CHECK_VERSION(0, 10, 0) {(char *) "virDomainQemuAgentCommand", libvirt_qemu_virDomainQemuAgentCommand, METH_VARARGS, NULL}, #endif /* LIBVIR_CHECK_VERSION(0, 10, 0) */ {NULL, NULL, 0, NULL} }; #if PY_MAJOR_VERSION > 2 static struct PyModuleDef moduledef = { PyModuleDef_HEAD_INIT, # ifndef __CYGWIN__ "libvirtmod_qemu", # else "cygvirtmod_qemu", # endif NULL, -1, libvirtQemuMethods, NULL, NULL, NULL, NULL }; PyObject * # ifndef __CYGWIN__ PyInit_libvirtmod_qemu # else PyInit_cygvirtmod_qemu # endif (void) { PyObject *module; if (virInitialize() < 0) return NULL; module = PyModule_Create(&moduledef); return module; } #else /* ! PY_MAJOR_VERSION > 2 */ void # ifndef __CYGWIN__ initlibvirtmod_qemu # else initcygvirtmod_qemu # endif (void) { if (virInitialize() < 0) return; /* initialize the python extension module */ Py_InitModule((char *) # ifndef __CYGWIN__ "libvirtmod_qemu", # else "cygvirtmod_qemu", # endif libvirtQemuMethods); } #endif /* ! PY_MAJOR_VERSION > 2 */ libvirt-python-1.2.2/libvirt-python.spec0000664000076400007640000000504112304641433022014 0ustar veillardveillard00000000000000 %define with_python3 0 %if 0%{?fedora} > 18 %define with_python3 1 %endif Summary: The libvirt virtualization API python2 binding Name: libvirt-python Version: 1.2.2 Release: 1%{?dist}%{?extra_release} Source0: http://libvirt.org/sources/python/%{name}-%{version}.tar.gz Url: http://libvirt.org License: LGPLv2+ Group: Development/Libraries BuildRequires: libvirt-devel >= 0.9.11 BuildRequires: python-devel %if %{with_python3} BuildRequires: python3-devel %endif %if %{with_python3} %package -n libvirt-python3 Summary: The libvirt virtualization API python3 binding Url: http://libvirt.org License: LGPLv2+ Group: Development/Libraries %endif # Don't want provides for python shared objects %{?filter_provides_in: %filter_provides_in %{python_sitearch}/.*\.so} %{?filter_setup} %description The libvirt-python package contains a module that permits applications written in the Python programming language to use the interface supplied by the libvirt library to use the virtualization capabilities of recent versions of Linux (and other OSes). %if %{with_python3} %description -n libvirt-python3 The libvirt-python package contains a module that permits applications written in the Python programming language to use the interface supplied by the libvirt library to use the virtualization capabilities of recent versions of Linux (and other OSes). %endif %prep %setup -q %build CFLAGS="$RPM_OPT_FLAGS" %{__python} setup.py build %if %{with_python3} CFLAGS="$RPM_OPT_FLAGS" %{__python3} setup.py build %endif %install %{__python} setup.py install --skip-build --root=%{buildroot} %if %{with_python3} %{__python3} setup.py install --skip-build --root=%{buildroot} %endif rm -f %{buildroot}%{_libdir}/python*/site-packages/*egg-info %files %defattr(-,root,root) %doc ChangeLog AUTHORS NEWS README COPYING COPYING.LESSER examples/ %{_libdir}/python2*/site-packages/libvirt.py* %{_libdir}/python2*/site-packages/libvirt_qemu.py* %{_libdir}/python2*/site-packages/libvirt_lxc.py* %{_libdir}/python2*/site-packages/libvirtmod* %if %{with_python3} %files -n libvirt-python3 %defattr(-,root,root) %doc ChangeLog AUTHORS NEWS README COPYING COPYING.LESSER examples/ %{_libdir}/python3*/site-packages/libvirt.py* %{_libdir}/python3*/site-packages/libvirt_qemu.py* %{_libdir}/python3*/site-packages/libvirt_lxc.py* %{_libdir}/python3*/site-packages/__pycache__/libvirt.cpython-*.py* %{_libdir}/python3*/site-packages/__pycache__/libvirt_qemu.cpython-*.py* %{_libdir}/python3*/site-packages/__pycache__/libvirt_lxc.cpython-*.py* %{_libdir}/python3*/site-packages/libvirtmod* %endif %changelog libvirt-python-1.2.2/COPYING0000664000076400007640000004325412245535607017222 0ustar veillardveillard00000000000000 GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Lesser General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. libvirt-python-1.2.2/typewrappers.c0000664000076400007640000003013612263141061021056 0ustar veillardveillard00000000000000/* * types.c: converter functions between the internal representation * and the Python objects * * Copyright (C) 2005, 2007, 2012 Red Hat, Inc. * * Daniel Veillard */ /* Horrible kludge to work around even more horrible name-space pollution * via Python.h. That file includes /usr/include/python2.5/pyconfig*.h, * which has over 180 autoconf-style HAVE_* definitions. Shame on them. */ #undef HAVE_PTHREAD_H #include "typewrappers.h" #include "libvirt-utils.h" #ifndef Py_CAPSULE_H typedef void(*PyCapsule_Destructor)(void *, void *); #endif static PyObject * libvirt_buildPyObject(void *cobj, const char *name, PyCapsule_Destructor destr) { PyObject *ret; #ifdef Py_CAPSULE_H ret = PyCapsule_New(cobj, name, destr); #else ret = PyCObject_FromVoidPtrAndDesc(cobj, (void *) name, destr); #endif /* _TEST_CAPSULE */ return ret; } PyObject * libvirt_intWrap(int val) { PyObject *ret; #if PY_MAJOR_VERSION > 2 ret = PyLong_FromLong((long) val); #else ret = PyInt_FromLong((long) val); #endif return ret; } PyObject * libvirt_uintWrap(uint val) { PyObject *ret; #if PY_MAJOR_VERSION > 2 ret = PyLong_FromLong((long) val); #else ret = PyInt_FromLong((long) val); #endif return ret; } PyObject * libvirt_longWrap(long val) { PyObject *ret; ret = PyLong_FromLong(val); return ret; } PyObject * libvirt_ulongWrap(unsigned long val) { PyObject *ret; ret = PyLong_FromLong(val); return ret; } PyObject * libvirt_longlongWrap(long long val) { PyObject *ret; ret = PyLong_FromUnsignedLongLong((unsigned long long) val); return ret; } PyObject * libvirt_ulonglongWrap(unsigned long long val) { PyObject *ret; ret = PyLong_FromUnsignedLongLong(val); return ret; } PyObject * libvirt_charPtrSizeWrap(char *str, Py_ssize_t size) { PyObject *ret; if (str == NULL) { Py_INCREF(Py_None); return Py_None; } #if PY_MAJOR_VERSION > 2 ret = PyBytes_FromStringAndSize(str, size); #else ret = PyString_FromStringAndSize(str, size); #endif return ret; } PyObject * libvirt_charPtrWrap(char *str) { PyObject *ret; if (str == NULL) { Py_INCREF(Py_None); return Py_None; } #if PY_MAJOR_VERSION > 2 ret = PyUnicode_FromString(str); #else ret = PyString_FromString(str); #endif return ret; } PyObject * libvirt_constcharPtrWrap(const char *str) { PyObject *ret; if (str == NULL) { Py_INCREF(Py_None); return Py_None; } #if PY_MAJOR_VERSION > 2 ret = PyUnicode_FromString(str); #else ret = PyString_FromString(str); #endif return ret; } PyObject * libvirt_boolWrap(int val) { if (val) Py_RETURN_TRUE; else Py_RETURN_FALSE; } int libvirt_intUnwrap(PyObject *obj, int *val) { long long_val; if (!obj) { PyErr_SetString(PyExc_TypeError, "unexpected type"); return -1; } /* If obj is type of PyInt_Type, PyInt_AsLong converts it * to C long type directly. If it is of PyLong_Type, PyInt_AsLong * will call PyLong_AsLong() to deal with it automatically. */ #if PY_MAJOR_VERSION > 2 long_val = PyLong_AsLong(obj); #else long_val = PyInt_AsLong(obj); #endif if ((long_val == -1) && PyErr_Occurred()) return -1; #if LONG_MAX != INT_MAX if (long_val >= INT_MIN && long_val <= INT_MAX) { *val = long_val; } else { PyErr_SetString(PyExc_OverflowError, "Python int too large to convert to C int"); return -1; } #else *val = long_val; #endif return 0; } int libvirt_uintUnwrap(PyObject *obj, unsigned int *val) { long long_val; if (!obj) { PyErr_SetString(PyExc_TypeError, "unexpected type"); return -1; } #if PY_MAJOR_VERSION > 2 long_val = PyLong_AsLong(obj); #else long_val = PyInt_AsLong(obj); #endif if ((long_val == -1) && PyErr_Occurred()) return -1; if (long_val >= 0 && long_val <= UINT_MAX) { *val = long_val; } else { PyErr_SetString(PyExc_OverflowError, "Python int too large to convert to C unsigned int"); return -1; } return 0; } int libvirt_longUnwrap(PyObject *obj, long *val) { long long_val; if (!obj) { PyErr_SetString(PyExc_TypeError, "unexpected type"); return -1; } long_val = PyLong_AsLong(obj); if ((long_val == -1) && PyErr_Occurred()) return -1; *val = long_val; return 0; } int libvirt_ulongUnwrap(PyObject *obj, unsigned long *val) { long long_val; if (!obj) { PyErr_SetString(PyExc_TypeError, "unexpected type"); return -1; } long_val = PyLong_AsLong(obj); if ((long_val == -1) && PyErr_Occurred()) return -1; if (long_val >= 0) { *val = long_val; } else { PyErr_SetString(PyExc_OverflowError, "negative Python int cannot be converted to C unsigned long"); return -1; } return 0; } int libvirt_longlongUnwrap(PyObject *obj, long long *val) { long long llong_val = -1; if (!obj) { PyErr_SetString(PyExc_TypeError, "unexpected type"); return -1; } #if PY_MAJOR_VERSION == 2 /* If obj is of PyInt_Type, PyLong_AsLongLong * will call PyInt_AsLong() to handle it automatically. */ if (PyInt_Check(obj) || PyLong_Check(obj)) #else if (PyLong_Check(obj)) #endif llong_val = PyLong_AsLongLong(obj); else PyErr_SetString(PyExc_TypeError, "an integer is required"); if ((llong_val == -1) && PyErr_Occurred()) return -1; *val = llong_val; return 0; } int libvirt_ulonglongUnwrap(PyObject *obj, unsigned long long *val) { unsigned long long ullong_val = -1; if (!obj) { PyErr_SetString(PyExc_TypeError, "unexpected type"); return -1; } #if PY_MAJOR_VERSION == 2 /* The PyLong_AsUnsignedLongLong doesn't check the type of * obj, only accept argument of PyLong_Type, so we check it instead. */ if (PyInt_Check(obj)) { long long llong_val = PyInt_AsLong(obj); if (llong_val < 0) PyErr_SetString(PyExc_OverflowError, "negative Python int cannot be converted to C unsigned long long"); else ullong_val = llong_val; } else if (PyLong_Check(obj)) { #else if (PyLong_Check(obj)) { #endif ullong_val = PyLong_AsUnsignedLongLong(obj); } else { PyErr_SetString(PyExc_TypeError, "an integer is required"); } if ((ullong_val == -1) && PyErr_Occurred()) return -1; *val = ullong_val; return 0; } int libvirt_doubleUnwrap(PyObject *obj, double *val) { double double_val; if (!obj) { PyErr_SetString(PyExc_TypeError, "unexpected type"); return -1; } double_val = PyFloat_AsDouble(obj); if ((double_val == -1) && PyErr_Occurred()) return -1; *val = double_val; return 0; } int libvirt_boolUnwrap(PyObject *obj, bool *val) { int ret; if (!obj) { PyErr_SetString(PyExc_TypeError, "unexpected type"); return -1; } if ((ret = PyObject_IsTrue(obj)) < 0) return ret; *val = ret > 0; return 0; } int libvirt_charPtrUnwrap(PyObject *obj, char **str) { #if PY_MAJOR_VERSION > 2 PyObject *bytes; #endif const char *ret; *str = NULL; if (!obj) { PyErr_SetString(PyExc_TypeError, "unexpected type"); return -1; } #if PY_MAJOR_VERSION > 2 if (!(bytes = PyUnicode_AsUTF8String(obj))) return -1; ret = PyBytes_AsString(bytes); #else ret = PyString_AsString(obj); #endif if (ret) *str = strdup(ret); #if PY_MAJOR_VERSION > 2 Py_DECREF(bytes); #endif return ret && *str ? 0 : -1; } int libvirt_charPtrSizeUnwrap(PyObject *obj, char **str, Py_ssize_t *size) { int ret; #if PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION <= 4 int isize; #endif *str = NULL; *size = 0; if (!obj) { PyErr_SetString(PyExc_TypeError, "unexpected type"); return -1; } #if PY_MAJOR_VERSION > 2 ret = PyBytes_AsStringAndSize(obj, str, size); #else # if PY_MINOR_VERSION <= 4 ret = PyString_AsStringAndSize(obj, str, &isize); *size = isize; # else ret = PyString_AsStringAndSize(obj, str, size); # endif #endif return ret; } PyObject * libvirt_virDomainPtrWrap(virDomainPtr node) { PyObject *ret; if (node == NULL) { Py_INCREF(Py_None); return Py_None; } ret = libvirt_buildPyObject(node, "virDomainPtr", NULL); return ret; } PyObject * libvirt_virNetworkPtrWrap(virNetworkPtr node) { PyObject *ret; if (node == NULL) { Py_INCREF(Py_None); return Py_None; } ret = libvirt_buildPyObject(node, "virNetworkPtr", NULL); return ret; } PyObject * libvirt_virInterfacePtrWrap(virInterfacePtr node) { PyObject *ret; if (node == NULL) { Py_INCREF(Py_None); return Py_None; } ret = libvirt_buildPyObject(node, "virInterfacePtr", NULL); return ret; } PyObject * libvirt_virStoragePoolPtrWrap(virStoragePoolPtr node) { PyObject *ret; if (node == NULL) { Py_INCREF(Py_None); return Py_None; } ret = libvirt_buildPyObject(node, "virStoragePoolPtr", NULL); return ret; } PyObject * libvirt_virStorageVolPtrWrap(virStorageVolPtr node) { PyObject *ret; if (node == NULL) { Py_INCREF(Py_None); return Py_None; } ret = libvirt_buildPyObject(node, "virStorageVolPtr", NULL); return ret; } PyObject * libvirt_virConnectPtrWrap(virConnectPtr node) { PyObject *ret; if (node == NULL) { Py_INCREF(Py_None); return Py_None; } ret = libvirt_buildPyObject(node, "virConnectPtr", NULL); return ret; } PyObject * libvirt_virNodeDevicePtrWrap(virNodeDevicePtr node) { PyObject *ret; if (node == NULL) { Py_INCREF(Py_None); return Py_None; } ret = libvirt_buildPyObject(node, "virNodeDevicePtr", NULL); return ret; } PyObject * libvirt_virSecretPtrWrap(virSecretPtr node) { PyObject *ret; if (node == NULL) { Py_INCREF(Py_None); return Py_None; } ret = libvirt_buildPyObject(node, "virSecretPtr", NULL); return ret; } PyObject * libvirt_virNWFilterPtrWrap(virNWFilterPtr node) { PyObject *ret; if (node == NULL) { Py_INCREF(Py_None); return Py_None; } ret = libvirt_buildPyObject(node, "virNWFilterPtr", NULL); return ret; } PyObject * libvirt_virStreamPtrWrap(virStreamPtr node) { PyObject *ret; if (node == NULL) { Py_INCREF(Py_None); return Py_None; } ret = libvirt_buildPyObject(node, "virStreamPtr", NULL); return ret; } PyObject * libvirt_virDomainSnapshotPtrWrap(virDomainSnapshotPtr node) { PyObject *ret; if (node == NULL) { Py_INCREF(Py_None); return Py_None; } ret = libvirt_buildPyObject(node, "virDomainSnapshotPtr", NULL); return ret; } PyObject * libvirt_virEventHandleCallbackWrap(virEventHandleCallback node) { PyObject *ret; if (node == NULL) { Py_INCREF(Py_None); printf("%s: WARNING - Wrapping None\n", __func__); return Py_None; } ret = libvirt_buildPyObject(node, "virEventHandleCallback", NULL); return ret; } PyObject * libvirt_virEventTimeoutCallbackWrap(virEventTimeoutCallback node) { PyObject *ret; if (node == NULL) { printf("%s: WARNING - Wrapping None\n", __func__); Py_INCREF(Py_None); return Py_None; } ret = libvirt_buildPyObject(node, "virEventTimeoutCallback", NULL); return ret; } PyObject * libvirt_virFreeCallbackWrap(virFreeCallback node) { PyObject *ret; if (node == NULL) { Py_INCREF(Py_None); return Py_None; } ret = libvirt_buildPyObject(node, "virFreeCallback", NULL); return ret; } PyObject * libvirt_virVoidPtrWrap(void* node) { PyObject *ret; if (node == NULL) { Py_INCREF(Py_None); return Py_None; } ret = libvirt_buildPyObject(node, "void*", NULL); return ret; } libvirt-python-1.2.2/libvirt-override-virConnect.py0000664000076400007640000003562212263141061024124 0ustar veillardveillard00000000000000 def __del__(self): try: for cb,opaque in self.domainEventCallbacks.items(): del self.domainEventCallbacks[cb] del self.domainEventCallbacks libvirtmod.virConnectDomainEventDeregister(self._o, self) except AttributeError: pass if self._o is not None: libvirtmod.virConnectClose(self._o) self._o = None def domainEventDeregister(self, cb): """Removes a Domain Event Callback. De-registering for a domain callback will disable delivery of this event type """ try: del self.domainEventCallbacks[cb] if len(self.domainEventCallbacks) == 0: del self.domainEventCallbacks ret = libvirtmod.virConnectDomainEventDeregister(self._o, self) if ret == -1: raise libvirtError ('virConnectDomainEventDeregister() failed', conn=self) except AttributeError: pass def domainEventRegister(self, cb, opaque): """Adds a Domain Event Callback. Registering for a domain callback will enable delivery of the events """ try: self.domainEventCallbacks[cb] = opaque except AttributeError: self.domainEventCallbacks = {cb:opaque} ret = libvirtmod.virConnectDomainEventRegister(self._o, self) if ret == -1: raise libvirtError ('virConnectDomainEventRegister() failed', conn=self) def _dispatchDomainEventCallbacks(self, dom, event, detail): """Dispatches events to python user domain event callbacks """ try: for cb,opaque in self.domainEventCallbacks.items(): cb(self, virDomain(self, _obj=dom), event, detail, opaque) return 0 except AttributeError: pass def _dispatchDomainEventLifecycleCallback(self, dom, event, detail, cbData): """Dispatches events to python user domain lifecycle event callbacks """ cb = cbData["cb"] opaque = cbData["opaque"] cb(self, virDomain(self, _obj=dom), event, detail, opaque) return 0 def _dispatchDomainEventGenericCallback(self, dom, cbData): """Dispatches events to python user domain generic event callbacks """ cb = cbData["cb"] opaque = cbData["opaque"] cb(self, virDomain(self, _obj=dom), opaque) return 0 def _dispatchDomainEventRTCChangeCallback(self, dom, offset, cbData): """Dispatches events to python user domain RTC change event callbacks """ cb = cbData["cb"] opaque = cbData["opaque"] cb(self, virDomain(self, _obj=dom), offset ,opaque) return 0 def _dispatchDomainEventWatchdogCallback(self, dom, action, cbData): """Dispatches events to python user domain watchdog event callbacks """ cb = cbData["cb"] opaque = cbData["opaque"] cb(self, virDomain(self, _obj=dom), action, opaque) return 0 def _dispatchDomainEventIOErrorCallback(self, dom, srcPath, devAlias, action, cbData): """Dispatches events to python user domain IO error event callbacks """ cb = cbData["cb"] opaque = cbData["opaque"] cb(self, virDomain(self, _obj=dom), srcPath, devAlias, action, opaque) return 0 def _dispatchDomainEventIOErrorReasonCallback(self, dom, srcPath, devAlias, action, reason, cbData): """Dispatches events to python user domain IO error event callbacks """ cb = cbData["cb"] opaque = cbData["opaque"] cb(self, virDomain(self, _obj=dom), srcPath, devAlias, action, reason, opaque) return 0 def _dispatchDomainEventGraphicsCallback(self, dom, phase, localAddr, remoteAddr, authScheme, subject, cbData): """Dispatches events to python user domain graphics event callbacks """ cb = cbData["cb"] opaque = cbData["opaque"] cb(self, virDomain(self, _obj=dom), phase, localAddr, remoteAddr, authScheme, subject, opaque) return 0 def _dispatchDomainEventBlockPullCallback(self, dom, path, type, status, cbData): """Dispatches events to python user domain blockJob event callbacks """ try: cb = cbData["cb"] opaque = cbData["opaque"] cb(self, virDomain(self, _obj=dom), path, type, status, opaque) return 0 except AttributeError: pass def _dispatchDomainEventDiskChangeCallback(self, dom, oldSrcPath, newSrcPath, devAlias, reason, cbData): """Dispatches event to python user domain diskChange event callbacks """ cb = cbData["cb"] opaque = cbData["opaque"] cb(self, virDomain(self, _obj=dom), oldSrcPath, newSrcPath, devAlias, reason, opaque) return 0 def _dispatchDomainEventTrayChangeCallback(self, dom, devAlias, reason, cbData): """Dispatches event to python user domain trayChange event callbacks """ cb = cbData["cb"] opaque = cbData["opaque"] cb(self, virDomain(self, _obj=dom), devAlias, reason, opaque) return 0 def _dispatchDomainEventPMWakeupCallback(self, dom, reason, cbData): """Dispatches event to python user domain pmwakeup event callbacks """ cb = cbData["cb"] opaque = cbData["opaque"] cb(self, virDomain(self, _obj=dom), reason, opaque) return 0 def _dispatchDomainEventPMSuspendCallback(self, dom, reason, cbData): """Dispatches event to python user domain pmsuspend event callbacks """ cb = cbData["cb"] opaque = cbData["opaque"] cb(self, virDomain(self, _obj=dom), reason, opaque) return 0 def _dispatchDomainEventBalloonChangeCallback(self, dom, actual, cbData): """Dispatches events to python user domain balloon change event callbacks """ cb = cbData["cb"] opaque = cbData["opaque"] cb(self, virDomain(self, _obj=dom), actual, opaque) return 0 def _dispatchDomainEventPMSuspendDiskCallback(self, dom, reason, cbData): """Dispatches event to python user domain pmsuspend-disk event callbacks """ cb = cbData["cb"] opaque = cbData["opaque"] cb(self, virDomain(self, _obj=dom), reason, opaque) return 0 def _dispatchDomainEventDeviceRemovedCallback(self, dom, devAlias, cbData): """Dispatches event to python user domain device removed event callbacks """ cb = cbData["cb"] opaque = cbData["opaque"] cb(self, virDomain(self, _obj=dom), devAlias, opaque) return 0 def domainEventDeregisterAny(self, callbackID): """Removes a Domain Event Callback. De-registering for a domain callback will disable delivery of this event type """ try: ret = libvirtmod.virConnectDomainEventDeregisterAny(self._o, callbackID) if ret == -1: raise libvirtError ('virConnectDomainEventDeregisterAny() failed', conn=self) del self.domainEventCallbackID[callbackID] except AttributeError: pass def _dispatchNetworkEventLifecycleCallback(self, net, event, detail, cbData): """Dispatches events to python user network lifecycle event callbacks """ cb = cbData["cb"] opaque = cbData["opaque"] cb(self, virNetwork(self, _obj=net), event, detail, opaque) return 0 def networkEventDeregisterAny(self, callbackID): """Removes a Network Event Callback. De-registering for a network callback will disable delivery of this event type""" try: ret = libvirtmod.virConnectNetworkEventDeregisterAny(self._o, callbackID) if ret == -1: raise libvirtError ('virConnectNetworkEventDeregisterAny() failed', conn=self) del self.networkEventCallbackID[callbackID] except AttributeError: pass def networkEventRegisterAny(self, net, eventID, cb, opaque): """Adds a Network Event Callback. Registering for a network callback will enable delivery of the events""" if not hasattr(self, 'networkEventCallbackID'): self.networkEventCallbackID = {} cbData = { "cb": cb, "conn": self, "opaque": opaque } if net is None: ret = libvirtmod.virConnectNetworkEventRegisterAny(self._o, None, eventID, cbData) else: ret = libvirtmod.virConnectNetworkEventRegisterAny(self._o, net._o, eventID, cbData) if ret == -1: raise libvirtError ('virConnectNetworkEventRegisterAny() failed', conn=self) self.networkEventCallbackID[ret] = opaque return ret def domainEventRegisterAny(self, dom, eventID, cb, opaque): """Adds a Domain Event Callback. Registering for a domain callback will enable delivery of the events """ if not hasattr(self, 'domainEventCallbackID'): self.domainEventCallbackID = {} cbData = { "cb": cb, "conn": self, "opaque": opaque } if dom is None: ret = libvirtmod.virConnectDomainEventRegisterAny(self._o, None, eventID, cbData) else: ret = libvirtmod.virConnectDomainEventRegisterAny(self._o, dom._o, eventID, cbData) if ret == -1: raise libvirtError ('virConnectDomainEventRegisterAny() failed', conn=self) self.domainEventCallbackID[ret] = opaque return ret def listAllDomains(self, flags=0): """List all domains and returns a list of domain objects""" ret = libvirtmod.virConnectListAllDomains(self._o, flags) if ret is None: raise libvirtError("virConnectListAllDomains() failed", conn=self) retlist = list() for domptr in ret: retlist.append(virDomain(self, _obj=domptr)) return retlist def listAllStoragePools(self, flags=0): """Returns a list of storage pool objects""" ret = libvirtmod.virConnectListAllStoragePools(self._o, flags) if ret is None: raise libvirtError("virConnectListAllStoragePools() failed", conn=self) retlist = list() for poolptr in ret: retlist.append(virStoragePool(self, _obj=poolptr)) return retlist def listAllNetworks(self, flags=0): """Returns a list of network objects""" ret = libvirtmod.virConnectListAllNetworks(self._o, flags) if ret is None: raise libvirtError("virConnectListAllNetworks() failed", conn=self) retlist = list() for netptr in ret: retlist.append(virNetwork(self, _obj=netptr)) return retlist def listAllInterfaces(self, flags=0): """Returns a list of interface objects""" ret = libvirtmod.virConnectListAllInterfaces(self._o, flags) if ret is None: raise libvirtError("virConnectListAllInterfaces() failed", conn=self) retlist = list() for ifaceptr in ret: retlist.append(virInterface(self, _obj=ifaceptr)) return retlist def listAllDevices(self, flags=0): """Returns a list of host node device objects""" ret = libvirtmod.virConnectListAllNodeDevices(self._o, flags) if ret is None: raise libvirtError("virConnectListAllNodeDevices() failed", conn=self) retlist = list() for devptr in ret: retlist.append(virNodeDevice(self, _obj=devptr)) return retlist def listAllNWFilters(self, flags=0): """Returns a list of network filter objects""" ret = libvirtmod.virConnectListAllNWFilters(self._o, flags) if ret is None: raise libvirtError("virConnectListAllNWFilters() failed", conn=self) retlist = list() for filter_ptr in ret: retlist.append(virNWFilter(self, _obj=filter_ptr)) return retlist def listAllSecrets(self, flags=0): """Returns a list of secret objects""" ret = libvirtmod.virConnectListAllSecrets(self._o, flags) if ret is None: raise libvirtError("virConnectListAllSecrets() failed", conn=self) retlist = list() for secret_ptr in ret: retlist.append(virSecret(self, _obj=secret_ptr)) return retlist def _dispatchCloseCallback(self, reason, cbData): """Dispatches events to python user close callback""" cb = cbData["cb"] opaque = cbData["opaque"] cb(self, reason, opaque) return 0 def unregisterCloseCallback(self): """Removes a close event callback""" ret = libvirtmod.virConnectUnregisterCloseCallback(self._o) if ret == -1: raise libvirtError ('virConnectUnregisterCloseCallback() failed', conn=self) def registerCloseCallback(self, cb, opaque): """Adds a close event callback, providing a notification when a connection fails / closes""" cbData = { "cb": cb, "conn": self, "opaque": opaque } ret = libvirtmod.virConnectRegisterCloseCallback(self._o, cbData) if ret == -1: raise libvirtError ('virConnectRegisterCloseCallback() failed', conn=self) return ret def createXMLWithFiles(self, xmlDesc, files, flags=0): """Launch a new guest domain, based on an XML description similar to the one returned by virDomainGetXMLDesc() This function may require privileged access to the hypervisor. The domain is not persistent, so its definition will disappear when it is destroyed, or if the host is restarted (see virDomainDefineXML() to define persistent domains). @files provides an array of file descriptors which will be made available to the 'init' process of the guest. The file handles exposed to the guest will be renumbered to start from 3 (ie immediately following stderr). This is only supported for guests which use container based virtualization technology. If the VIR_DOMAIN_START_PAUSED flag is set, the guest domain will be started, but its CPUs will remain paused. The CPUs can later be manually started using virDomainResume. If the VIR_DOMAIN_START_AUTODESTROY flag is set, the guest domain will be automatically destroyed when the virConnectPtr object is finally released. This will also happen if the client application crashes / loses its connection to the libvirtd daemon. Any domains marked for auto destroy will block attempts at migration, save-to-file, or snapshots. """ ret = libvirtmod.virDomainCreateXMLWithFiles(self._o, xmlDesc, files, flags) if ret is None:raise libvirtError('virDomainCreateXMLWithFiles() failed', conn=self) __tmp = virDomain(self,_obj=ret) return __tmp libvirt-python-1.2.2/libvirt-utils.c0000664000076400007640000001077412245535607021145 0ustar veillardveillard00000000000000/* * libvirt-utils.c: misc helper APIs for python binding * * Copyright (C) 2013 Red Hat, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library. If not, see * . * */ #include #include #include #include #include #include "libvirt-utils.h" /** * virAlloc: * @ptrptr: pointer to pointer for address of allocated memory * @size: number of bytes to allocate * * Allocate 'size' bytes of memory. Return the address of the * allocated memory in 'ptrptr'. The newly allocated memory is * filled with zeros. * * Returns -1 on failure to allocate, zero on success */ int virAlloc(void *ptrptr, size_t size) { *(void **)ptrptr = calloc(1, size); if (*(void **)ptrptr == NULL) { return -1; } return 0; } /** * virAllocN: * @ptrptr: pointer to pointer for address of allocated memory * @size: number of bytes to allocate * @count: number of elements to allocate * * Allocate an array of memory 'count' elements long, * each with 'size' bytes. Return the address of the * allocated memory in 'ptrptr'. The newly allocated * memory is filled with zeros. * * Returns -1 on failure to allocate, zero on success */ int virAllocN(void *ptrptr, size_t size, size_t count) { *(void**)ptrptr = calloc(count, size); if (*(void**)ptrptr == NULL) { return -1; } return 0; } /** * virReallocN: * @ptrptr: pointer to pointer for address of allocated memory * @size: number of bytes to allocate * @count: number of elements in array * * Resize the block of memory in 'ptrptr' to be an array of * 'count' elements, each 'size' bytes in length. Update 'ptrptr' * with the address of the newly allocated memory. On failure, * 'ptrptr' is not changed and still points to the original memory * block. Any newly allocated memory in 'ptrptr' is uninitialized. * * Returns -1 on failure to allocate, zero on success */ int virReallocN(void *ptrptr, size_t size, size_t count) { void *tmp; if (xalloc_oversized(count, size)) { errno = ENOMEM; return -1; } tmp = realloc(*(void**)ptrptr, size * count); if (!tmp && (size * count)) { return -1; } *(void**)ptrptr = tmp; return 0; } /** * virFree: * @ptrptr: pointer to pointer for address of memory to be freed * * Release the chunk of memory in the pointer pointed to by * the 'ptrptr' variable. After release, 'ptrptr' will be * updated to point to NULL. */ void virFree(void *ptrptr) { int save_errno = errno; free(*(void**)ptrptr); *(void**)ptrptr = NULL; errno = save_errno; } int virFileClose(int *fdptr) { int saved_errno = 0; int rc = 0; saved_errno = errno; if (*fdptr < 0) return 0; rc = close(*fdptr); *fdptr = -1; errno = saved_errno; return rc; } #if ! LIBVIR_CHECK_VERSION(1, 0, 2) /** * virTypedParamsClear: * @params: the array of the typed parameters * @nparams: number of parameters in the @params array * * Frees all memory used by string parameters. The memory occupied by @params * is not free; use virTypedParamsFree if you want it to be freed too. * * Returns nothing. */ void virTypedParamsClear(virTypedParameterPtr params, int nparams) { size_t i; if (!params) return; for (i = 0; i < nparams; i++) { if (params[i].type == VIR_TYPED_PARAM_STRING) VIR_FREE(params[i].value.s); } } /** * virTypedParamsFree: * @params: the array of the typed parameters * @nparams: number of parameters in the @params array * * Frees all memory used by string parameters and the memory occuiped by * @params. * * Returns nothing. */ void virTypedParamsFree(virTypedParameterPtr params, int nparams) { virTypedParamsClear(params, nparams); VIR_FREE(params); } #endif /* ! LIBVIR_CHECK_VERSION(1, 0, 2) */ libvirt-python-1.2.2/NEWS0000664000076400007640000000025112245535607016654 0ustar veillardveillard00000000000000 Libvirt Python News =================== Release 1.2.0 ============= - Split off from main libvirt package - Allow to compile against multiple versions of libvirt libvirt-python-1.2.2/libvirt-override-virDomainSnapshot.py0000664000076400007640000000130212245535607025463 0ustar veillardveillard00000000000000 def getConnect(self): """Get the connection that owns the domain that a snapshot was created for""" return self.connect() def getDomain(self): """Get the domain that a snapshot was created for""" return self.domain() def listAllChildren(self, flags=0): """List all child snapshots and returns a list of snapshot objects""" ret = libvirtmod.virDomainSnapshotListAllChildren(self._o, flags) if ret is None: raise libvirtError("virDomainSnapshotListAllChildren() failed", conn=self) retlist = list() for snapptr in ret: retlist.append(virDomainSnapshot(self, _obj=snapptr)) return retlist libvirt-python-1.2.2/typewrappers.h0000664000076400007640000001661312263141061021067 0ustar veillardveillard00000000000000/* * libvirt_wrap.h: type wrappers for libvir python bindings * * Copyright (C) 2005, 2011-2012 Red Hat, Inc. * * Daniel Veillard */ #include #include #include #include #ifdef __GNUC__ # ifdef ATTRIBUTE_UNUSED # undef ATTRIBUTE_UNUSED # endif # ifndef ATTRIBUTE_UNUSED # define ATTRIBUTE_UNUSED __attribute__ ((__unused__)) # endif /* ATTRIBUTE_UNUSED */ #else # define ATTRIBUTE_UNUSED #endif /* Work around really old python. */ #if PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION < 5 typedef ssize_t Py_ssize_t; #endif #define PyvirConnect_Get(v) (((v) == Py_None) ? NULL : \ (((PyvirConnect_Object *)(v))->obj)) typedef struct { PyObject_HEAD virConnectPtr obj; } PyvirConnect_Object; #define PyvirDomain_Get(v) (((v) == Py_None) ? NULL : \ (((PyvirDomain_Object *)(v))->obj)) typedef struct { PyObject_HEAD virDomainPtr obj; } PyvirDomain_Object; #define PyvirNetwork_Get(v) (((v) == Py_None) ? NULL : \ (((PyvirNetwork_Object *)(v))->obj)) typedef struct { PyObject_HEAD virNetworkPtr obj; } PyvirNetwork_Object; #define PyvirInterface_Get(v) (((v) == Py_None) ? NULL : \ (((PyvirInterface_Object *)(v))->obj)) typedef struct { PyObject_HEAD virInterfacePtr obj; } PyvirInterface_Object; #define PyvirStoragePool_Get(v) (((v) == Py_None) ? NULL : \ (((PyvirStoragePool_Object *)(v))->obj)) typedef struct { PyObject_HEAD virStoragePoolPtr obj; } PyvirStoragePool_Object; #define PyvirStorageVol_Get(v) (((v) == Py_None) ? NULL : \ (((PyvirStorageVol_Object *)(v))->obj)) typedef struct { PyObject_HEAD virStorageVolPtr obj; } PyvirStorageVol_Object; #define PyvirNodeDevice_Get(v) (((v) == Py_None) ? NULL : \ (((PyvirNodeDevice_Object *)(v))->obj)) typedef struct { PyObject_HEAD virNodeDevicePtr obj; } PyvirNodeDevice_Object; #define PyvirSecret_Get(v) (((v) == Py_None) ? NULL : \ (((PyvirSecret_Object *)(v))->obj)) typedef struct { PyObject_HEAD virSecretPtr obj; } PyvirSecret_Object; #define PyvirNWFilter_Get(v) (((v) == Py_None) ? NULL : \ (((PyvirNWFilter_Object *)(v))->obj)) typedef struct { PyObject_HEAD virNWFilterPtr obj; } PyvirNWFilter_Object; #define PyvirStream_Get(v) (((v) == Py_None) ? NULL : \ (((PyvirStream_Object *)(v))->obj)) typedef struct { PyObject_HEAD virStreamPtr obj; } PyvirStream_Object; #define PyvirDomainSnapshot_Get(v) (((v) == Py_None) ? NULL : \ (((PyvirDomainSnapshot_Object *)(v))->obj)) typedef struct { PyObject_HEAD virDomainSnapshotPtr obj; } PyvirDomainSnapshot_Object; #define PyvirEventHandleCallback_Get(v) (((v) == Py_None) ? NULL : \ (((PyvirEventHandleCallback_Object *)(v))->obj)) typedef struct { PyObject_HEAD virEventHandleCallback obj; } PyvirEventHandleCallback_Object; #define PyvirEventTimeoutCallback_Get(v) (((v) == Py_None) ? NULL : \ (((PyvirEventTimeoutCallback_Object *)(v))->obj)) typedef struct { PyObject_HEAD virEventTimeoutCallback obj; } PyvirEventTimeoutCallback_Object; #define PyvirFreeCallback_Get(v) (((v) == Py_None) ? NULL : \ (((PyvirFreeCallback_Object *)(v))->obj)) typedef struct { PyObject_HEAD virFreeCallback obj; } PyvirFreeCallback_Object; #define PyvirVoidPtr_Get(v) (((v) == Py_None) ? NULL : \ (((PyvirVoidPtr_Object *)(v))->obj)) typedef struct { PyObject_HEAD void* obj; } PyvirVoidPtr_Object; PyObject * libvirt_intWrap(int val); PyObject * libvirt_uintWrap(uint val); PyObject * libvirt_longWrap(long val); PyObject * libvirt_ulongWrap(unsigned long val); PyObject * libvirt_longlongWrap(long long val); PyObject * libvirt_ulonglongWrap(unsigned long long val); PyObject * libvirt_charPtrWrap(char *str); PyObject * libvirt_charPtrSizeWrap(char *str, Py_ssize_t size); PyObject * libvirt_constcharPtrWrap(const char *str); PyObject * libvirt_boolWrap(int val); int libvirt_intUnwrap(PyObject *obj, int *val); int libvirt_uintUnwrap(PyObject *obj, unsigned int *val); int libvirt_longUnwrap(PyObject *obj, long *val); int libvirt_ulongUnwrap(PyObject *obj, unsigned long *val); int libvirt_longlongUnwrap(PyObject *obj, long long *val); int libvirt_ulonglongUnwrap(PyObject *obj, unsigned long long *val); int libvirt_doubleUnwrap(PyObject *obj, double *val); int libvirt_boolUnwrap(PyObject *obj, bool *val); int libvirt_charPtrUnwrap(PyObject *obj, char **str); int libvirt_charPtrSizeUnwrap(PyObject *obj, char **str, Py_ssize_t *size); PyObject * libvirt_virConnectPtrWrap(virConnectPtr node); PyObject * libvirt_virDomainPtrWrap(virDomainPtr node); PyObject * libvirt_virNetworkPtrWrap(virNetworkPtr node); PyObject * libvirt_virInterfacePtrWrap(virInterfacePtr node); PyObject * libvirt_virStoragePoolPtrWrap(virStoragePoolPtr node); PyObject * libvirt_virStorageVolPtrWrap(virStorageVolPtr node); PyObject * libvirt_virEventHandleCallbackWrap(virEventHandleCallback node); PyObject * libvirt_virEventTimeoutCallbackWrap(virEventTimeoutCallback node); PyObject * libvirt_virFreeCallbackWrap(virFreeCallback node); PyObject * libvirt_virVoidPtrWrap(void* node); PyObject * libvirt_virNodeDevicePtrWrap(virNodeDevicePtr node); PyObject * libvirt_virSecretPtrWrap(virSecretPtr node); PyObject * libvirt_virNWFilterPtrWrap(virNWFilterPtr node); PyObject * libvirt_virStreamPtrWrap(virStreamPtr node); PyObject * libvirt_virDomainSnapshotPtrWrap(virDomainSnapshotPtr node); /* Provide simple macro statement wrappers (adapted from GLib, in turn from Perl): * LIBVIRT_STMT_START { statements; } LIBVIRT_STMT_END; * can be used as a single statement, as in * if (x) LIBVIRT_STMT_START { ... } LIBVIRT_STMT_END; else ... * * When GCC is compiling C code in non-ANSI mode, it will use the * compiler __extension__ to wrap the statements within `({' and '})' braces. * When compiling on platforms where configure has defined * HAVE_DOWHILE_MACROS, statements will be wrapped with `do' and `while (0)'. * For any other platforms (SunOS4 is known to have this issue), wrap the * statements with `if (1)' and `else (void) 0'. */ #if !(defined (LIBVIRT_STMT_START) && defined (LIBVIRT_STMT_END)) # if defined (__GNUC__) && !defined (__STRICT_ANSI__) && !defined (__cplusplus) # define LIBVIRT_STMT_START (void) __extension__ ( # define LIBVIRT_STMT_END ) # else /* !(__GNUC__ && !__STRICT_ANSI__ && !__cplusplus) */ # if defined (HAVE_DOWHILE_MACROS) # define LIBVIRT_STMT_START do # define LIBVIRT_STMT_END while (0) # else /* !HAVE_DOWHILE_MACROS */ # define LIBVIRT_STMT_START if (1) # define LIBVIRT_STMT_END else (void) 0 # endif /* !HAVE_DOWHILE_MACROS */ # endif /* !(__GNUC__ && !__STRICT_ANSI__ && !__cplusplus) */ #endif #define LIBVIRT_BEGIN_ALLOW_THREADS \ LIBVIRT_STMT_START { \ PyThreadState *_save = NULL; \ if (PyEval_ThreadsInitialized()) \ _save = PyEval_SaveThread(); #define LIBVIRT_END_ALLOW_THREADS \ if (PyEval_ThreadsInitialized()) \ PyEval_RestoreThread(_save); \ } LIBVIRT_STMT_END #define LIBVIRT_ENSURE_THREAD_STATE \ LIBVIRT_STMT_START { \ PyGILState_STATE _save = PyGILState_UNLOCKED; \ if (PyEval_ThreadsInitialized()) \ _save = PyGILState_Ensure(); #define LIBVIRT_RELEASE_THREAD_STATE \ if (PyEval_ThreadsInitialized()) \ PyGILState_Release(_save); \ } LIBVIRT_STMT_END libvirt-python-1.2.2/README0000664000076400007640000000166712245535607017051 0ustar veillardveillard00000000000000 Libvirt Python Binding README ============================= This package provides a python binding to the libvirt.so, libvirt-qemu.so and libvirt-lxc.so library APIs. It is written to build against any version of libvirt that is 0.9.11 or newer. This code is distributed under the terms of the LGPL version 2 or later. The module can be built by following the normal python module build process python setup.py build sudo python setup.py install or to install as non-root python setup.py build python setup.py install --user Patches for this code should be sent to the main libvirt development mailing list http://libvirt.org/contact.html#email To send patches, it is strongly recommended to use the 'git send-email' command. Make sure the mails mention that the patch is for the python binding. This can be done by setting a config parameter in the local git checkout git config format.subjectprefix "PATCH python" libvirt-python-1.2.2/generator.py0000775000076400007640000023154712302554455020532 0ustar veillardveillard00000000000000#!/usr/bin/python -u # # generate python wrappers from the XML API description # functions = {} lxc_functions = {} qemu_functions = {} enums = {} # { enumType: { enumConstant: enumValue } } lxc_enums = {} # { enumType: { enumConstant: enumValue } } qemu_enums = {} # { enumType: { enumConstant: enumValue } } import os import sys import string import re quiet=True ####################################################################### # # That part if purely the API acquisition phase from the # libvirt API description # ####################################################################### import os import xml.sax debug = 0 onlyOverrides = False def getparser(): # Attach parser to an unmarshalling object. return both objects. target = docParser() parser = xml.sax.make_parser() parser.setContentHandler(target) return parser, target class docParser(xml.sax.handler.ContentHandler): def __init__(self): self._methodname = None self._data = [] self.in_function = 0 self.startElement = self.start self.endElement = self.end self.characters = self.data def close(self): if debug: print("close") def getmethodname(self): return self._methodname def data(self, text): if debug: print("data %s" % text) self._data.append(text) def cdata(self, text): if debug: print("data %s" % text) self._data.append(text) def start(self, tag, attrs): if debug: print("start %s, %s" % (tag, attrs)) if tag == 'function': self._data = [] self.in_function = 1 self.function = None self.function_cond = None self.function_args = [] self.function_descr = None self.function_return = None self.function_file = None self.function_module= None if 'name' in attrs.keys(): self.function = attrs['name'] if 'file' in attrs.keys(): self.function_file = attrs['file'] if 'module' in attrs.keys(): self.function_module= attrs['module'] elif tag == 'cond': self._data = [] elif tag == 'info': self._data = [] elif tag == 'arg': if self.in_function == 1: self.function_arg_name = None self.function_arg_type = None self.function_arg_info = None if 'name' in attrs.keys(): self.function_arg_name = attrs['name'] if self.function_arg_name == 'from': self.function_arg_name = 'frm' if 'type' in attrs.keys(): self.function_arg_type = attrs['type'] if 'info' in attrs.keys(): self.function_arg_info = attrs['info'] elif tag == 'return': if self.in_function == 1: self.function_return_type = None self.function_return_info = None self.function_return_field = None if 'type' in attrs.keys(): self.function_return_type = attrs['type'] if 'info' in attrs.keys(): self.function_return_info = attrs['info'] if 'field' in attrs.keys(): self.function_return_field = attrs['field'] elif tag == 'enum': # enums come from header files, hence virterror.h if (attrs['file'] == "libvirt" or attrs['file'] == "virterror" or attrs['file'] == "virerror"): enum(attrs['type'],attrs['name'],attrs['value']) elif attrs['file'] == "libvirt-lxc": lxc_enum(attrs['type'],attrs['name'],attrs['value']) elif attrs['file'] == "libvirt-qemu": qemu_enum(attrs['type'],attrs['name'],attrs['value']) def end(self, tag): if debug: print("end %s" % tag) if tag == 'function': # fuctions come from source files, hence 'virerror.c' if self.function is not None: if (self.function_module == "libvirt" or self.function_module == "event" or self.function_module == "virevent" or self.function_module == "virerror" or self.function_module == "virterror"): function(self.function, self.function_descr, self.function_return, self.function_args, self.function_file, self.function_module, self.function_cond) elif self.function_module == "libvirt-lxc": lxc_function(self.function, self.function_descr, self.function_return, self.function_args, self.function_file, self.function_module, self.function_cond) elif self.function_module == "libvirt-qemu": qemu_function(self.function, self.function_descr, self.function_return, self.function_args, self.function_file, self.function_module, self.function_cond) elif self.function_file == "python": function(self.function, self.function_descr, self.function_return, self.function_args, self.function_file, self.function_module, self.function_cond) elif self.function_file == "python-lxc": lxc_function(self.function, self.function_descr, self.function_return, self.function_args, self.function_file, self.function_module, self.function_cond) elif self.function_file == "python-qemu": qemu_function(self.function, self.function_descr, self.function_return, self.function_args, self.function_file, self.function_module, self.function_cond) self.in_function = 0 elif tag == 'arg': if self.in_function == 1: self.function_args.append([self.function_arg_name, self.function_arg_type, self.function_arg_info]) elif tag == 'return': if self.in_function == 1: self.function_return = [self.function_return_type, self.function_return_info, self.function_return_field] elif tag == 'info': str = '' for c in self._data: str = str + c if self.in_function == 1: self.function_descr = str elif tag == 'cond': str = '' for c in self._data: str = str + c if self.in_function == 1: self.function_cond = str def function(name, desc, ret, args, file, module, cond): global onlyOverrides if onlyOverrides and name not in functions: return if name == "virConnectListDomains": name = "virConnectListDomainsID" functions[name] = (desc, ret, args, file, module, cond) def qemu_function(name, desc, ret, args, file, module, cond): global onlyOverrides if onlyOverrides and name not in qemu_functions: return qemu_functions[name] = (desc, ret, args, file, module, cond) def lxc_function(name, desc, ret, args, file, module, cond): global onlyOverrides if onlyOverrides and name not in lxc_functions: return lxc_functions[name] = (desc, ret, args, file, module, cond) def enum(type, name, value): if type not in enums: enums[type] = {} if value == 'VIR_TYPED_PARAM_INT': value = 1 elif value == 'VIR_TYPED_PARAM_UINT': value = 2 elif value == 'VIR_TYPED_PARAM_LLONG': value = 3 elif value == 'VIR_TYPED_PARAM_ULLONG': value = 4 elif value == 'VIR_TYPED_PARAM_DOUBLE': value = 5 elif value == 'VIR_TYPED_PARAM_BOOLEAN': value = 6 elif value == 'VIR_DOMAIN_AFFECT_CURRENT': value = 0 elif value == 'VIR_DOMAIN_AFFECT_LIVE': value = 1 elif value == 'VIR_DOMAIN_AFFECT_CONFIG': value = 2 if onlyOverrides and name not in enums[type]: return enums[type][name] = value def lxc_enum(type, name, value): if type not in lxc_enums: lxc_enums[type] = {} if onlyOverrides and name not in lxc_enums[type]: return lxc_enums[type][name] = value def qemu_enum(type, name, value): if type not in qemu_enums: qemu_enums[type] = {} if onlyOverrides and name not in qemu_enums[type]: return qemu_enums[type][name] = value ####################################################################### # # Some filtering rukes to drop functions/types which should not # be exposed as-is on the Python interface # ####################################################################### functions_failed = [] lxc_functions_failed = [] qemu_functions_failed = [] functions_skipped = [ "virConnectListDomains", ] lxc_functions_skipped = [] qemu_functions_skipped = [] skipped_modules = { } skipped_types = { # 'int *': "usually a return type", 'virConnectDomainEventCallback': "No function types in python", 'virConnectDomainEventGenericCallback': "No function types in python", 'virConnectDomainEventRTCChangeCallback': "No function types in python", 'virConnectDomainEventWatchdogCallback': "No function types in python", 'virConnectDomainEventIOErrorCallback': "No function types in python", 'virConnectDomainEventGraphicsCallback': "No function types in python", 'virStreamEventCallback': "No function types in python", 'virEventHandleCallback': "No function types in python", 'virEventTimeoutCallback': "No function types in python", 'virDomainBlockJobInfoPtr': "Not implemented yet", } ####################################################################### # # Table of remapping to/from the python type or class to the C # counterpart. # ####################################################################### py_types = { 'void': (None, None, None, None), 'int': ('i', None, "int", "int"), 'long': ('l', None, "long", "long"), 'double': ('d', None, "double", "double"), 'unsigned int': ('i', None, "int", "int"), 'unsigned long': ('l', None, "long", "long"), 'long long': ('L', None, "longlong", "long long"), 'unsigned long long': ('L', None, "longlong", "long long"), 'unsigned char *': ('z', None, "charPtr", "char *"), 'char *': ('z', None, "charPtr", "char *"), 'const char *': ('z', None, "constcharPtr", "const char *"), 'size_t': ('n', None, "size_t", "size_t"), 'virDomainPtr': ('O', "virDomain", "virDomainPtr", "virDomainPtr"), 'virDomain *': ('O', "virDomain", "virDomainPtr", "virDomainPtr"), 'const virDomain *': ('O', "virDomain", "virDomainPtr", "virDomainPtr"), 'virNetworkPtr': ('O', "virNetwork", "virNetworkPtr", "virNetworkPtr"), 'virNetwork *': ('O', "virNetwork", "virNetworkPtr", "virNetworkPtr"), 'const virNetwork *': ('O', "virNetwork", "virNetworkPtr", "virNetworkPtr"), 'virInterfacePtr': ('O', "virInterface", "virInterfacePtr", "virInterfacePtr"), 'virInterface *': ('O', "virInterface", "virInterfacePtr", "virInterfacePtr"), 'const virInterface *': ('O', "virInterface", "virInterfacePtr", "virInterfacePtr"), 'virStoragePoolPtr': ('O', "virStoragePool", "virStoragePoolPtr", "virStoragePoolPtr"), 'virStoragePool *': ('O', "virStoragePool", "virStoragePoolPtr", "virStoragePoolPtr"), 'const virStoragePool *': ('O', "virStoragePool", "virStoragePoolPtr", "virStoragePoolPtr"), 'virStorageVolPtr': ('O', "virStorageVol", "virStorageVolPtr", "virStorageVolPtr"), 'virStorageVol *': ('O', "virStorageVol", "virStorageVolPtr", "virStorageVolPtr"), 'const virStorageVol *': ('O', "virStorageVol", "virStorageVolPtr", "virStorageVolPtr"), 'virConnectPtr': ('O', "virConnect", "virConnectPtr", "virConnectPtr"), 'virConnect *': ('O', "virConnect", "virConnectPtr", "virConnectPtr"), 'const virConnect *': ('O', "virConnect", "virConnectPtr", "virConnectPtr"), 'virNodeDevicePtr': ('O', "virNodeDevice", "virNodeDevicePtr", "virNodeDevicePtr"), 'virNodeDevice *': ('O', "virNodeDevice", "virNodeDevicePtr", "virNodeDevicePtr"), 'const virNodeDevice *': ('O', "virNodeDevice", "virNodeDevicePtr", "virNodeDevicePtr"), 'virSecretPtr': ('O', "virSecret", "virSecretPtr", "virSecretPtr"), 'virSecret *': ('O', "virSecret", "virSecretPtr", "virSecretPtr"), 'const virSecret *': ('O', "virSecret", "virSecretPtr", "virSecretPtr"), 'virNWFilterPtr': ('O', "virNWFilter", "virNWFilterPtr", "virNWFilterPtr"), 'virNWFilter *': ('O', "virNWFilter", "virNWFilterPtr", "virNWFilterPtr"), 'const virNWFilter *': ('O', "virNWFilter", "virNWFilterPtr", "virNWFilterPtr"), 'virStreamPtr': ('O', "virStream", "virStreamPtr", "virStreamPtr"), 'virStream *': ('O', "virStream", "virStreamPtr", "virStreamPtr"), 'const virStream *': ('O', "virStream", "virStreamPtr", "virStreamPtr"), 'virDomainSnapshotPtr': ('O', "virDomainSnapshot", "virDomainSnapshotPtr", "virDomainSnapshotPtr"), 'virDomainSnapshot *': ('O', "virDomainSnapshot", "virDomainSnapshotPtr", "virDomainSnapshotPtr"), 'const virDomainSnapshot *': ('O', "virDomainSnapshot", "virDomainSnapshotPtr", "virDomainSnapshotPtr"), } py_return_types = { } unknown_types = {} foreign_encoding_args = ( ) ####################################################################### # # This part writes the C <-> Python stubs libvirt.[ch] and # the table libvirt-export.c to add when registrering the Python module # ####################################################################### # Class methods which are written by hand in libvirt.c but the Python-level # code is still automatically generated (so they are not in skip_function()). skip_impl = ( 'virConnectGetVersion', 'virConnectGetLibVersion', 'virConnectListDomainsID', 'virConnectListDefinedDomains', 'virConnectListNetworks', 'virConnectListDefinedNetworks', 'virConnectListSecrets', 'virConnectListInterfaces', 'virConnectListStoragePools', 'virConnectListDefinedStoragePools', 'virConnectListStorageVols', 'virConnectListDefinedStorageVols', 'virConnectListDefinedInterfaces', 'virConnectListNWFilters', 'virDomainSnapshotListNames', 'virDomainSnapshotListChildrenNames', 'virConnGetLastError', 'virGetLastError', 'virDomainGetInfo', 'virDomainGetState', 'virDomainGetControlInfo', 'virDomainGetBlockInfo', 'virDomainGetJobInfo', 'virDomainGetJobStats', 'virNodeGetInfo', 'virNodeGetSecurityModel', 'virDomainGetSecurityLabel', 'virDomainGetSecurityLabelList', 'virDomainGetUUID', 'virDomainGetUUIDString', 'virDomainLookupByUUID', 'virNetworkGetUUID', 'virNetworkGetUUIDString', 'virNetworkLookupByUUID', 'virDomainGetAutostart', 'virNetworkGetAutostart', 'virDomainBlockStats', 'virDomainInterfaceStats', 'virDomainMemoryStats', 'virNodeGetCellsFreeMemory', 'virDomainGetSchedulerType', 'virDomainGetSchedulerParameters', 'virDomainGetSchedulerParametersFlags', 'virDomainSetSchedulerParameters', 'virDomainSetSchedulerParametersFlags', 'virDomainSetBlkioParameters', 'virDomainGetBlkioParameters', 'virDomainSetMemoryParameters', 'virDomainGetMemoryParameters', 'virDomainSetNumaParameters', 'virDomainGetNumaParameters', 'virDomainGetVcpus', 'virDomainPinVcpu', 'virDomainPinVcpuFlags', 'virDomainGetVcpuPinInfo', 'virDomainGetEmulatorPinInfo', 'virDomainPinEmulator', 'virSecretGetValue', 'virSecretSetValue', 'virSecretGetUUID', 'virSecretGetUUIDString', 'virSecretLookupByUUID', 'virNWFilterGetUUID', 'virNWFilterGetUUIDString', 'virNWFilterLookupByUUID', 'virStoragePoolGetUUID', 'virStoragePoolGetUUIDString', 'virStoragePoolLookupByUUID', 'virStoragePoolGetInfo', 'virStorageVolGetInfo', 'virStoragePoolGetAutostart', 'virStoragePoolListVolumes', 'virDomainBlockPeek', 'virDomainMemoryPeek', 'virEventRegisterImpl', 'virNodeListDevices', 'virNodeDeviceListCaps', 'virConnectBaselineCPU', 'virDomainRevertToSnapshot', 'virDomainSendKey', 'virNodeGetCPUStats', 'virNodeGetMemoryStats', 'virDomainGetBlockJobInfo', 'virDomainMigrateGetCompressionCache', 'virDomainMigrateGetMaxSpeed', 'virDomainBlockStatsFlags', 'virDomainSetBlockIoTune', 'virDomainGetBlockIoTune', 'virDomainSetInterfaceParameters', 'virDomainGetInterfaceParameters', 'virDomainGetCPUStats', 'virDomainGetDiskErrors', 'virNodeGetMemoryParameters', 'virNodeSetMemoryParameters', 'virNodeGetCPUMap', 'virDomainMigrate3', 'virDomainMigrateToURI3', 'virConnectGetCPUModelNames', ) lxc_skip_impl = ( 'virDomainLxcOpenNamespace', ) qemu_skip_impl = ( 'virDomainQemuMonitorCommand', 'virDomainQemuAgentCommand', ) # These are functions which the generator skips completly - no python # or C code is generated. Generally should not be used for any more # functions than those already listed skip_function = ( 'virConnectListDomains', # Python API is called virConectListDomainsID for unknown reasons 'virConnSetErrorFunc', # Not used in Python API XXX is this a bug ? 'virResetError', # Not used in Python API XXX is this a bug ? 'virGetVersion', # Python C code is manually written 'virSetErrorFunc', # Python API is called virRegisterErrorHandler for unknown reasons 'virConnCopyLastError', # Python API is called virConnGetLastError instead 'virCopyLastError', # Python API is called virGetLastError instead 'virConnectOpenAuth', # Python C code is manually written 'virDefaultErrorFunc', # Python virErrorFuncHandler impl calls this from C 'virConnectDomainEventRegister', # overridden in virConnect.py 'virConnectDomainEventDeregister', # overridden in virConnect.py 'virConnectDomainEventRegisterAny', # overridden in virConnect.py 'virConnectDomainEventDeregisterAny', # overridden in virConnect.py 'virConnectNetworkEventRegisterAny', # overridden in virConnect.py 'virConnectNetworkEventDeregisterAny', # overridden in virConnect.py 'virSaveLastError', # We have our own python error wrapper 'virFreeError', # Only needed if we use virSaveLastError 'virConnectListAllDomains', # overridden in virConnect.py 'virDomainListAllSnapshots', # overridden in virDomain.py 'virDomainSnapshotListAllChildren', # overridden in virDomainSnapshot.py 'virConnectListAllStoragePools', # overridden in virConnect.py 'virStoragePoolListAllVolumes', # overridden in virStoragePool.py 'virConnectListAllNetworks', # overridden in virConnect.py 'virConnectListAllInterfaces', # overridden in virConnect.py 'virConnectListAllNodeDevices', # overridden in virConnect.py 'virConnectListAllNWFilters', # overridden in virConnect.py 'virConnectListAllSecrets', # overridden in virConnect.py 'virStreamRecvAll', # Pure python libvirt-override-virStream.py 'virStreamSendAll', # Pure python libvirt-override-virStream.py 'virStreamRecv', # overridden in libvirt-override-virStream.py 'virStreamSend', # overridden in libvirt-override-virStream.py 'virConnectUnregisterCloseCallback', # overridden in virConnect.py 'virConnectRegisterCloseCallback', # overridden in virConnect.py 'virDomainCreateXMLWithFiles', # overridden in virConnect.py 'virDomainCreateWithFiles', # overridden in virDomain.py # 'Ref' functions have no use for bindings users. "virConnectRef", "virDomainRef", "virInterfaceRef", "virNetworkRef", "virNodeDeviceRef", "virSecretRef", "virNWFilterRef", "virStoragePoolRef", "virStorageVolRef", "virStreamRef", "virDomainSnapshotRef", # This functions shouldn't be called via the bindings (and even the docs # contain an explicit warning to that effect). The equivalent should be # implemented in pure python for each class "virDomainGetConnect", "virInterfaceGetConnect", "virNetworkGetConnect", "virSecretGetConnect", "virNWFilterGetConnect", "virStoragePoolGetConnect", "virStorageVolGetConnect", "virDomainSnapshotGetConnect", "virDomainSnapshotGetDomain", # only useful in C code, python code uses dict for typed parameters "virTypedParamsAddBoolean", "virTypedParamsAddDouble", "virTypedParamsAddFromString", "virTypedParamsAddInt", "virTypedParamsAddLLong", "virTypedParamsAddString", "virTypedParamsAddUInt", "virTypedParamsAddULLong", "virTypedParamsClear", "virTypedParamsFree", "virTypedParamsGet", "virTypedParamsGetBoolean", "virTypedParamsGetDouble", "virTypedParamsGetInt", "virTypedParamsGetLLong", "virTypedParamsGetString", "virTypedParamsGetUInt", "virTypedParamsGetULLong", ) lxc_skip_function = ( "virDomainLxcEnterNamespace", "virDomainLxcEnterSecurityLabel", ) qemu_skip_function = ( #"virDomainQemuAttach", ) # Generate C code, but skip python impl function_skip_python_impl = ( "virStreamFree", # Needed in custom virStream __del__, but free shouldn't # be exposed in bindings ) lxc_function_skip_python_impl = () qemu_function_skip_python_impl = () function_skip_index_one = ( "virDomainRevertToSnapshot", ) def print_function_wrapper(module, name, output, export, include): global py_types global unknown_types global functions global lxc_functions global qemu_functions global skipped_modules global function_skip_python_impl try: if module == "libvirt": (desc, ret, args, file, mod, cond) = functions[name] if module == "libvirt-lxc": (desc, ret, args, file, mod, cond) = lxc_functions[name] if module == "libvirt-qemu": (desc, ret, args, file, mod, cond) = qemu_functions[name] except: print("failed to get function %s infos" % name) return if module in skipped_modules: return 0 if module == "libvirt": if name in skip_function: return 0 if name in skip_impl: # Don't delete the function entry in the caller. return 1 elif module == "libvirt-lxc": if name in lxc_skip_function: return 0 if name in lxc_skip_impl: # Don't delete the function entry in the caller. return 1 elif module == "libvirt-qemu": if name in qemu_skip_function: return 0 if name in qemu_skip_impl: # Don't delete the function entry in the caller. return 1 c_call = "" format="" format_args="" c_args="" c_return="" c_convert="" num_bufs=0 for arg in args: # This should be correct if arg[1][0:6] == "const ": arg[1] = arg[1][6:] c_args = c_args + " %s %s;\n" % (arg[1], arg[0]) if arg[1] in py_types: (f, t, n, c) = py_types[arg[1]] if (f == 'z') and (name in foreign_encoding_args) and (num_bufs == 0): f = 't#' if f is not None: format = format + f if t is not None: format_args = format_args + ", &pyobj_%s" % (arg[0]) c_args = c_args + " PyObject *pyobj_%s;\n" % (arg[0]) c_convert = c_convert + \ " %s = (%s) Py%s_Get(pyobj_%s);\n" % (arg[0], arg[1], t, arg[0]) else: format_args = format_args + ", &%s" % (arg[0]) if f == 't#': format_args = format_args + ", &py_buffsize%d" % num_bufs c_args = c_args + " int py_buffsize%d;\n" % num_bufs num_bufs = num_bufs + 1 if c_call != "": c_call = c_call + ", " c_call = c_call + "%s" % (arg[0]) else: if arg[1] in skipped_types: return 0 if arg[1] in unknown_types: lst = unknown_types[arg[1]] lst.append(name) else: unknown_types[arg[1]] = [name] return -1 if format != "": format = format + ":%s" % (name) if ret[0] == 'void': if file == "python_accessor": if args[1][1] == "char *": c_call = "\n VIR_FREE(%s->%s);\n" % ( args[0][0], args[1][0], args[0][0], args[1][0]) c_call = c_call + " %s->%s = (%s)strdup((const xmlChar *)%s);\n" % (args[0][0], args[1][0], args[1][1], args[1][0]) else: c_call = "\n %s->%s = %s;\n" % (args[0][0], args[1][0], args[1][0]) else: c_call = "\n %s(%s);\n" % (name, c_call) ret_convert = " Py_INCREF(Py_None);\n return Py_None;\n" elif ret[0] in py_types: (f, t, n, c) = py_types[ret[0]] c_return = " %s c_retval;\n" % (ret[0]) if file == "python_accessor" and ret[2] is not None: c_call = "\n c_retval = %s->%s;\n" % (args[0][0], ret[2]) else: c_call = "\n c_retval = %s(%s);\n" % (name, c_call) ret_convert = " py_retval = libvirt_%sWrap((%s) c_retval);\n" % (n,c) ret_convert = ret_convert + " return py_retval;\n" elif ret[0] in py_return_types: (f, t, n, c) = py_return_types[ret[0]] c_return = " %s c_retval;\n" % (ret[0]) c_call = "\n c_retval = %s(%s);\n" % (name, c_call) ret_convert = " py_retval = libvirt_%sWrap((%s) c_retval);\n" % (n,c) ret_convert = ret_convert + " return py_retval;\n" else: if ret[0] in skipped_types: return 0 if ret[0] in unknown_types: lst = unknown_types[ret[0]] lst.append(name) else: unknown_types[ret[0]] = [name] return -1 if cond is not None and cond != "": include.write("#if %s\n" % cond) export.write("#if %s\n" % cond) output.write("#if %s\n" % cond) include.write("PyObject * ") if module == "libvirt": include.write("libvirt_%s(PyObject *self, PyObject *args);\n" % (name)) export.write(" { (char *)\"%s\", libvirt_%s, METH_VARARGS, NULL },\n" % (name, name)) elif module == "libvirt-lxc": include.write("libvirt_lxc_%s(PyObject *self, PyObject *args);\n" % (name)) export.write(" { (char *)\"%s\", libvirt_lxc_%s, METH_VARARGS, NULL },\n" % (name, name)) elif module == "libvirt-qemu": include.write("libvirt_qemu_%s(PyObject *self, PyObject *args);\n" % (name)) export.write(" { (char *)\"%s\", libvirt_qemu_%s, METH_VARARGS, NULL },\n" % (name, name)) if file == "python": # Those have been manually generated if cond is not None and cond != "": include.write("#endif\n") export.write("#endif\n") output.write("#endif\n") return 1 if file == "python_accessor" and ret[0] != "void" and ret[2] is None: # Those have been manually generated if cond is not None and cond != "": include.write("#endif\n") export.write("#endif\n") output.write("#endif\n") return 1 output.write("PyObject *\n") if module == "libvirt": output.write("libvirt_%s(PyObject *self ATTRIBUTE_UNUSED," % (name)) elif module == "libvirt-lxc": output.write("libvirt_lxc_%s(PyObject *self ATTRIBUTE_UNUSED," % (name)) elif module == "libvirt-qemu": output.write("libvirt_qemu_%s(PyObject *self ATTRIBUTE_UNUSED," % (name)) output.write(" PyObject *args") if format == "": output.write(" ATTRIBUTE_UNUSED") output.write(") {\n") if ret[0] != 'void': output.write(" PyObject *py_retval;\n") if c_return != "": output.write(c_return) if c_args != "": output.write(c_args) if format != "": output.write("\n if (!PyArg_ParseTuple(args, (char *)\"%s\"%s))\n" % (format, format_args)) output.write(" return NULL;\n") if c_convert != "": output.write(c_convert + "\n") output.write(" LIBVIRT_BEGIN_ALLOW_THREADS;") output.write(c_call) output.write(" LIBVIRT_END_ALLOW_THREADS;\n") output.write(ret_convert) output.write("}\n\n") if cond is not None and cond != "": include.write("#endif /* %s */\n" % cond) export.write("#endif /* %s */\n" % cond) output.write("#endif /* %s */\n" % cond) if module == "libvirt": if name in function_skip_python_impl: return 0 elif module == "libvirt-lxc": if name in lxc_function_skip_python_impl: return 0 elif module == "libvirt-qemu": if name in qemu_function_skip_python_impl: return 0 return 1 def buildStubs(module, api_xml): global py_types global py_return_types global unknown_types global onlyOverrides if module not in ["libvirt", "libvirt-qemu", "libvirt-lxc"]: print("ERROR: Unknown module type: %s" % module) return None if module == "libvirt": funcs = functions funcs_failed = functions_failed funcs_skipped = functions_skipped elif module == "libvirt-lxc": funcs = lxc_functions funcs_failed = lxc_functions_failed funcs_skipped = lxc_functions_skipped elif module == "libvirt-qemu": funcs = qemu_functions funcs_failed = qemu_functions_failed funcs_skipped = qemu_functions_skipped try: f = open(api_xml) data = f.read() f.close() onlyOverrides = False (parser, target) = getparser() parser.feed(data) parser.close() except IOError: msg = sys.exc_info()[1] print(file, ":", msg) sys.exit(1) n = len(list(funcs.keys())) if not quiet: print("Found %d functions in %s" % ((n), api_xml)) override_api_xml = "%s-override-api.xml" % module py_types['pythonObject'] = ('O', "pythonObject", "pythonObject", "pythonObject") try: f = open(override_api_xml) data = f.read() f.close() onlyOverrides = True (parser, target) = getparser() parser.feed(data) parser.close() except IOError: msg = sys.exc_info()[1] print(file, ":", msg) if not quiet: # XXX: This is not right, same function already in @functions # will be overwritten. print("Found %d functions in %s" % ((len(list(funcs.keys())) - n), override_api_xml)) nb_wrap = 0 failed = 0 skipped = 0 header_file = "build/%s.h" % module export_file = "build/%s-export.c" % module wrapper_file = "build/%s.c" % module include = open(header_file, "w") include.write("/* Generated */\n\n") export = open(export_file, "w") export.write("/* Generated */\n\n") wrapper = open(wrapper_file, "w") wrapper.write("/* Generated by generator.py */\n\n") wrapper.write("#include \n") wrapper.write("#include \n") wrapper.write("#include \"typewrappers.h\"\n") wrapper.write("#include \"build/" + module + ".h\"\n\n") funcnames = list(funcs.keys()) if funcnames is not None: funcnames.sort() for function in funcnames: # Skip the functions which are not for the module ret = print_function_wrapper(module, function, wrapper, export, include) if ret < 0: failed = failed + 1 funcs_failed.append(function) del funcs[function] if ret == 0: skipped = skipped + 1 funcs_skipped.append(function) del funcs[function] if ret == 1: nb_wrap = nb_wrap + 1 include.close() export.close() wrapper.close() if not quiet: print("Generated %d wrapper functions" % nb_wrap) if unknown_types: print("Missing type converters: ") for type in list(unknown_types.keys()): print("%s:%d " % (type, len(unknown_types[type]))) for f in funcs_failed: print("ERROR: failed %s" % f) if failed > 0: return -1 if len(unknown_types) > 0: return -1 return 0 ####################################################################### # # This part writes part of the Python front-end classes based on # mapping rules between types and classes and also based on function # renaming to get consistent function names at the Python level # ####################################################################### # # The type automatically remapped to generated classes # classes_type = { "virDomainPtr": ("._o", "virDomain(self,_obj=%s)", "virDomain"), "virDomain *": ("._o", "virDomain(self, _obj=%s)", "virDomain"), "virNetworkPtr": ("._o", "virNetwork(self, _obj=%s)", "virNetwork"), "virNetwork *": ("._o", "virNetwork(self, _obj=%s)", "virNetwork"), "virInterfacePtr": ("._o", "virInterface(self, _obj=%s)", "virInterface"), "virInterface *": ("._o", "virInterface(self, _obj=%s)", "virInterface"), "virStoragePoolPtr": ("._o", "virStoragePool(self, _obj=%s)", "virStoragePool"), "virStoragePool *": ("._o", "virStoragePool(self, _obj=%s)", "virStoragePool"), "virStorageVolPtr": ("._o", "virStorageVol(self, _obj=%s)", "virStorageVol"), "virStorageVol *": ("._o", "virStorageVol(self, _obj=%s)", "virStorageVol"), "virNodeDevicePtr": ("._o", "virNodeDevice(self, _obj=%s)", "virNodeDevice"), "virNodeDevice *": ("._o", "virNodeDevice(self, _obj=%s)", "virNodeDevice"), "virSecretPtr": ("._o", "virSecret(self, _obj=%s)", "virSecret"), "virSecret *": ("._o", "virSecret(self, _obj=%s)", "virSecret"), "virNWFilterPtr": ("._o", "virNWFilter(self, _obj=%s)", "virNWFilter"), "virNWFilter *": ("._o", "virNWFilter(self, _obj=%s)", "virNWFilter"), "virStreamPtr": ("._o", "virStream(self, _obj=%s)", "virStream"), "virStream *": ("._o", "virStream(self, _obj=%s)", "virStream"), "virConnectPtr": ("._o", "virConnect(_obj=%s)", "virConnect"), "virConnect *": ("._o", "virConnect(_obj=%s)", "virConnect"), "virDomainSnapshotPtr": ("._o", "virDomainSnapshot(self,_obj=%s)", "virDomainSnapshot"), "virDomainSnapshot *": ("._o", "virDomainSnapshot(self, _obj=%s)", "virDomainSnapshot"), } converter_type = { } primary_classes = ["virDomain", "virNetwork", "virInterface", "virStoragePool", "virStorageVol", "virConnect", "virNodeDevice", "virSecret", "virNWFilter", "virStream", "virDomainSnapshot"] classes_ancestor = { } classes_destructors = { "virDomain": "virDomainFree", "virNetwork": "virNetworkFree", "virInterface": "virInterfaceFree", "virStoragePool": "virStoragePoolFree", "virStorageVol": "virStorageVolFree", "virNodeDevice" : "virNodeDeviceFree", "virSecret": "virSecretFree", "virNWFilter": "virNWFilterFree", "virDomainSnapshot": "virDomainSnapshotFree", # We hand-craft __del__ for this one #"virStream": "virStreamFree", } class_skip_connect_impl = { "virConnect" : True, } class_domain_impl = { "virDomainSnapshot": True, } functions_noexcept = { 'virDomainGetID': True, 'virDomainGetName': True, 'virNetworkGetName': True, 'virInterfaceGetName': True, 'virStoragePoolGetName': True, 'virStorageVolGetName': True, 'virStorageVolGetkey': True, 'virNodeDeviceGetName': True, 'virNodeDeviceGetParent': True, 'virSecretGetUsageType': True, 'virSecretGetUsageID': True, 'virNWFilterGetName': True, } reference_keepers = { } function_classes = {} function_classes["None"] = [] function_post = {} # Functions returning an integral type which need special rules to # check for errors and raise exceptions. functions_int_exception_test = { 'virDomainGetMaxMemory': "%s == 0", } functions_int_default_test = "%s == -1" def is_integral_type (name): return not re.search ("^(unsigned)? ?(int|long)$", name) is None def is_optional_arg(info): return re.search("^\(?\optional\)?", info) is not None # Functions returning lists which need special rules to check for errors # and raise exceptions. functions_list_exception_test = { } functions_list_default_test = "%s is None" def is_python_noninteger_type (name): return name[-1:] == "*" def nameFixup(name, classe, type, file): # avoid a desastrous clash listname = classe + "List" ll = len(listname) l = len(classe) if name[0:l] == listname: func = name[l:] func = func[0:1].lower() + func[1:] elif name[0:16] == "virNetworkDefine": func = name[3:] func = func[0:1].lower() + func[1:] elif name[0:19] == "virNetworkCreateXML": func = name[3:] func = func[0:1].lower() + func[1:] elif name[0:16] == "virNetworkLookup": func = name[3:] func = func[0:1].lower() + func[1:] elif name[0:18] == "virInterfaceDefine": func = name[3:] func = func[0:1].lower() + func[1:] elif name[0:21] == "virInterfaceCreateXML": func = name[3:] func = func[0:1].lower() + func[1:] elif name[0:18] == "virInterfaceLookup": func = name[3:] func = func[0:1].lower() + func[1:] elif name[0:15] == "virSecretDefine": func = name[3:] func = func[0:1].lower() + func[1:] elif name[0:15] == "virSecretLookup": func = name[3:] func = func[0:1].lower() + func[1:] elif name[0:17] == "virNWFilterDefine": func = name[3:] func = func[0:3].lower() + func[3:] elif name[0:17] == "virNWFilterLookup": func = name[3:] func = func[0:3].lower() + func[3:] elif name[0:20] == "virStoragePoolDefine": func = name[3:] func = func[0:1].lower() + func[1:] elif name[0:23] == "virStoragePoolCreateXML": func = name[3:] func = func[0:1].lower() + func[1:] elif name[0:20] == "virStoragePoolLookup": func = name[3:] func = func[0:1].lower() + func[1:] elif name[0:19] == "virStorageVolDefine": func = name[3:] func = func[0:1].lower() + func[1:] elif name[0:19] == "virStorageVolLookup": func = name[3:] func = func[0:1].lower() + func[1:] elif name[0:20] == "virDomainGetCPUStats": func = name[9:] func = func[0:1].lower() + func[1:] elif name[0:12] == "virDomainGet": func = name[12:] func = func[0:1].lower() + func[1:] elif name[0:29] == "virDomainSnapshotLookupByName": func = name[9:] func = func[0:1].lower() + func[1:] elif name[0:26] == "virDomainSnapshotListNames": func = name[9:] func = func[0:1].lower() + func[1:] elif name[0:28] == "virDomainSnapshotNumChildren": func = name[17:] func = func[0:1].lower() + func[1:] elif name[0:20] == "virDomainSnapshotNum": func = name[9:] func = func[0:1].lower() + func[1:] elif name[0:26] == "virDomainSnapshotCreateXML": func = name[9:] func = func[0:1].lower() + func[1:] elif name[0:24] == "virDomainSnapshotCurrent": func = name[9:] func = func[0:1].lower() + func[1:] elif name[0:17] == "virDomainSnapshot": func = name[17:] func = func[0:1].lower() + func[1:] elif name[0:9] == "virDomain": func = name[9:] func = func[0:1].lower() + func[1:] elif name[0:13] == "virNetworkGet": func = name[13:] func = func[0:1].lower() + func[1:] elif name[0:10] == "virNetwork": func = name[10:] func = func[0:1].lower() + func[1:] elif name[0:15] == "virInterfaceGet": func = name[15:] func = func[0:1].lower() + func[1:] elif name[0:12] == "virInterface": func = name[12:] func = func[0:1].lower() + func[1:] elif name[0:12] == 'virSecretGet': func = name[12:] func = func[0:1].lower() + func[1:] elif name[0:9] == 'virSecret': func = name[9:] func = func[0:1].lower() + func[1:] elif name[0:14] == 'virNWFilterGet': func = name[14:] func = func[0:1].lower() + func[1:] elif name[0:11] == 'virNWFilter': func = name[11:] func = func[0:1].lower() + func[1:] elif name[0:12] == 'virStreamNew': func = "newStream" elif name[0:9] == 'virStream': func = name[9:] func = func[0:1].lower() + func[1:] elif name[0:17] == "virStoragePoolGet": func = name[17:] func = func[0:1].lower() + func[1:] elif name[0:14] == "virStoragePool": func = name[14:] func = func[0:1].lower() + func[1:] elif name[0:16] == "virStorageVolGet": func = name[16:] func = func[0:1].lower() + func[1:] elif name[0:13] == "virStorageVol": func = name[13:] func = func[0:1].lower() + func[1:] elif name[0:13] == "virNodeDevice": if name[13:16] == "Get": func = name[16].lower() + name[17:] elif name[13:19] == "Lookup" or name[13:19] == "Create": func = name[3].lower() + name[4:] else: func = name[13].lower() + name[14:] elif name[0:7] == "virNode": func = name[7:] func = func[0:1].lower() + func[1:] elif name[0:10] == "virConnect": func = name[10:] func = func[0:1].lower() + func[1:] elif name[0:3] == "xml": func = name[3:] func = func[0:1].lower() + func[1:] else: func = name if func == "iD": func = "ID" if func == "uUID": func = "UUID" if func == "uUIDString": func = "UUIDString" if func == "oSType": func = "OSType" if func == "xMLDesc": func = "XMLDesc" if func == "mACString": func = "MACString" return func def functionSortKey(info): (index, func, name, ret, args, filename, mod) = info return func, filename def writeDoc(module, name, args, indent, output): if module == "libvirt": funcs = functions elif module == "libvirt-lxc": funcs = lxc_functions elif module == "libvirt-qemu": funcs = qemu_functions if funcs[name][0] is None or funcs[name][0] == "": return val = funcs[name][0] val = val.replace("NULL", "None") output.write(indent) output.write('"""') i = val.find("\n") while i >= 0: str = val[0:i+1] val = val[i+1:] output.write(str) i = val.find("\n") output.write(indent) output.write(val) output.write(' """\n') def buildWrappers(module): global ctypes global py_types global py_return_types global unknown_types global functions global function_classes global classes_type global classes_list global primary_classes global classes_ancestor global converter_type global classes_destructors global functions_noexcept if not module == "libvirt": print("ERROR: Unknown module type: %s" % module) return None for type in list(classes_type.keys()): function_classes[classes_type[type][2]] = [] # # Build the list of C types to look for ordered to start # with primary classes # ctypes = [] classes_list = [] ctypes_processed = {} classes_processed = {} for classe in primary_classes: classes_list.append(classe) classes_processed[classe] = () for type in list(classes_type.keys()): tinfo = classes_type[type] if tinfo[2] == classe: ctypes.append(type) ctypes_processed[type] = () for type in list(classes_type.keys()): if type in ctypes_processed: continue tinfo = classes_type[type] if tinfo[2] not in classes_processed: classes_list.append(tinfo[2]) classes_processed[tinfo[2]] = () ctypes.append(type) ctypes_processed[type] = () for name in list(functions.keys()): found = 0 (desc, ret, args, file, mod, cond) = functions[name] for type in ctypes: classe = classes_type[type][2] if name[0:3] == "vir" and len(args) >= 1 and args[0][1] == type: found = 1 func = nameFixup(name, classe, type, file) info = (0, func, name, ret, args, file, mod) function_classes[classe].append(info) break elif name[0:3] == "vir" and len(args) >= 2 and args[1][1] == type \ and file != "python_accessor" and not name in function_skip_index_one: found = 1 func = nameFixup(name, classe, type, file) info = (1, func, name, ret, args, file, mod) function_classes[classe].append(info) break if found == 1: continue func = nameFixup(name, "None", file, file) info = (0, func, name, ret, args, file, mod) function_classes['None'].append(info) classes_file = "build/%s.py" % module extra_file = "%s-override.py" % module extra = None classes = open(classes_file, "w") if os.path.exists(extra_file): extra = open(extra_file, "r") classes.write("#\n") classes.write("# WARNING WARNING WARNING WARNING\n") classes.write("#\n") classes.write("# This file is automatically written by generator.py. Any changes\n") classes.write("# made here will be lost.\n") classes.write("#\n") classes.write("# To change the manually written methods edit " + module + "-override.py\n") classes.write("# To change the automatically written methods edit generator.py\n") classes.write("#\n") classes.write("# WARNING WARNING WARNING WARNING\n") classes.write("#\n") if extra is not None: classes.writelines(extra.readlines()) classes.write("#\n") classes.write("# WARNING WARNING WARNING WARNING\n") classes.write("#\n") classes.write("# Automatically written part of python bindings for libvirt\n") classes.write("#\n") classes.write("# WARNING WARNING WARNING WARNING\n") if extra is not None: extra.close() if "None" in function_classes: flist = function_classes["None"] flist.sort(key=functionSortKey) oldfile = "" for info in flist: (index, func, name, ret, args, file, mod) = info if file != oldfile: classes.write("#\n# Functions from module %s\n#\n\n" % file) oldfile = file classes.write("def %s(" % func) n = 0 for arg in args: if n != 0: classes.write(", ") classes.write("%s" % arg[0]) if arg[0] == "flags" or is_optional_arg(arg[2]): if is_integral_type(arg[1]): classes.write("=0") else: classes.write("=None") n = n + 1 classes.write("):\n") writeDoc(module, name, args, ' ', classes) for arg in args: if arg[1] in classes_type: classes.write(" if %s is None: %s__o = None\n" % (arg[0], arg[0])) classes.write(" else: %s__o = %s%s\n" % (arg[0], arg[0], classes_type[arg[1]][0])) if ret[0] != "void": classes.write(" ret = ") else: classes.write(" ") classes.write("libvirtmod.%s(" % name) n = 0 for arg in args: if n != 0: classes.write(", ") classes.write("%s" % arg[0]) if arg[1] in classes_type: classes.write("__o") n = n + 1 classes.write(")\n") if ret[0] != "void": if ret[0] in classes_type: # # Raise an exception # if name in functions_noexcept: classes.write(" if ret is None:return None\n") else: classes.write( " if ret is None:raise libvirtError('%s() failed')\n" % (name)) classes.write(" return ") classes.write(classes_type[ret[0]][1] % ("ret")) classes.write("\n") # For functions returning an integral type there are # several things that we can do, depending on the # contents of functions_int_*: elif is_integral_type (ret[0]): if name not in functions_noexcept: if name in functions_int_exception_test: test = functions_int_exception_test[name] else: test = functions_int_default_test classes.write ((" if " + test + ": raise libvirtError ('%s() failed')\n") % ("ret", name)) classes.write(" return ret\n") elif is_python_noninteger_type (ret[0]): if name not in functions_noexcept: if name in functions_list_exception_test: test = functions_list_exception_test[name] else: test = functions_list_default_test classes.write ((" if " + test + ": raise libvirtError ('%s() failed')\n") % ("ret", name)) classes.write(" return ret\n") else: classes.write(" return ret\n") classes.write("\n") for classname in classes_list: if classname == "None": pass else: if classname in classes_ancestor: classes.write("class %s(%s):\n" % (classname, classes_ancestor[classname])) classes.write(" def __init__(self, _obj=None):\n") if classname in reference_keepers: rlist = reference_keepers[classname] for ref in rlist: classes.write(" self.%s = None\n" % ref[1]) classes.write(" self._o = _obj\n") classes.write(" %s.__init__(self, _obj=_obj)\n\n" % ( classes_ancestor[classname])) else: classes.write("class %s(object):\n" % (classname)) if classname in [ "virDomain", "virNetwork", "virInterface", "virStoragePool", "virStorageVol", "virNodeDevice", "virSecret","virStream", "virNWFilter" ]: classes.write(" def __init__(self, conn, _obj=None):\n") elif classname in [ 'virDomainSnapshot' ]: classes.write(" def __init__(self, dom, _obj=None):\n") else: classes.write(" def __init__(self, _obj=None):\n") if classname in reference_keepers: rlist = reference_keepers[classname] for ref in rlist: classes.write(" self.%s = None\n" % ref[1]) if classname in [ "virDomain", "virNetwork", "virInterface", "virNodeDevice", "virSecret", "virStream", "virNWFilter" ]: classes.write(" self._conn = conn\n") elif classname in [ "virStorageVol", "virStoragePool" ]: classes.write(" self._conn = conn\n" + \ " if not isinstance(conn, virConnect):\n" + \ " self._conn = conn._conn\n") elif classname in [ "virDomainSnapshot" ]: classes.write(" self._dom = dom\n") classes.write(" self._conn = dom.connect()\n") classes.write(" self._o = _obj\n\n") destruct=None if classname in classes_destructors: classes.write(" def __del__(self):\n") classes.write(" if self._o is not None:\n") classes.write(" libvirtmod.%s(self._o)\n" % classes_destructors[classname]) classes.write(" self._o = None\n\n") destruct=classes_destructors[classname] if classname not in class_skip_connect_impl: # Build python safe 'connect' method classes.write(" def connect(self):\n") classes.write(" return self._conn\n\n") if classname in class_domain_impl: classes.write(" def domain(self):\n") classes.write(" return self._dom\n\n") flist = function_classes[classname] flist.sort(key=functionSortKey) oldfile = "" for info in flist: (index, func, name, ret, args, file, mod) = info # # Do not provide as method the destructors for the class # to avoid double free # if name == destruct: continue if file != oldfile: if file == "python_accessor": classes.write(" # accessors for %s\n" % (classname)) else: classes.write(" #\n") classes.write(" # %s functions from module %s\n" % ( classname, file)) classes.write(" #\n\n") oldfile = file classes.write(" def %s(self" % func) n = 0 for arg in args: if n != index: classes.write(", %s" % arg[0]) if arg[0] == "flags" or is_optional_arg(arg[2]): if is_integral_type(arg[1]): classes.write("=0") else: classes.write("=None") n = n + 1 classes.write("):\n") writeDoc(module, name, args, ' ', classes) n = 0 for arg in args: if arg[1] in classes_type: if n != index: classes.write(" if %s is None: %s__o = None\n" % (arg[0], arg[0])) classes.write(" else: %s__o = %s%s\n" % (arg[0], arg[0], classes_type[arg[1]][0])) n = n + 1 if ret[0] != "void": classes.write(" ret = ") else: classes.write(" ") n = 0 classes.write("libvirtmod.%s(" % name) for arg in args: if n != 0: classes.write(", ") if n != index: classes.write("%s" % arg[0]) if arg[1] in classes_type: classes.write("__o") else: classes.write("self") if arg[1] in classes_type: classes.write(classes_type[arg[1]][0]) n = n + 1 classes.write(")\n") if name == "virConnectClose": classes.write(" self._o = None\n") # For functions returning object types: if ret[0] != "void": if ret[0] in classes_type: # # Raise an exception # if name in functions_noexcept: classes.write( " if ret is None:return None\n") else: if classname == "virConnect": classes.write( " if ret is None:raise libvirtError('%s() failed', conn=self)\n" % (name)) elif classname == "virDomain": classes.write( " if ret is None:raise libvirtError('%s() failed', dom=self)\n" % (name)) elif classname == "virNetwork": classes.write( " if ret is None:raise libvirtError('%s() failed', net=self)\n" % (name)) elif classname == "virInterface": classes.write( " if ret is None:raise libvirtError('%s() failed', net=self)\n" % (name)) elif classname == "virStoragePool": classes.write( " if ret is None:raise libvirtError('%s() failed', pool=self)\n" % (name)) elif classname == "virStorageVol": classes.write( " if ret is None:raise libvirtError('%s() failed', vol=self)\n" % (name)) elif classname == "virDomainSnapshot": classes.write( " if ret is None:raise libvirtError('%s() failed', dom=self._dom)\n" % (name)) else: classes.write( " if ret is None:raise libvirtError('%s() failed')\n" % (name)) # # generate the returned class wrapper for the object # classes.write(" __tmp = ") classes.write(classes_type[ret[0]][1] % ("ret")) classes.write("\n") # # Sometime one need to keep references of the source # class in the returned class object. # See reference_keepers for the list # tclass = classes_type[ret[0]][2] if tclass in reference_keepers: rlist = reference_keepers[tclass] for pref in rlist: if pref[0] == classname: classes.write(" __tmp.%s = self\n" % pref[1]) # Post-processing - just before we return. if name in function_post: classes.write(" %s\n" % (function_post[name])) # # return the class # classes.write(" return __tmp\n") elif ret[0] in converter_type: # # Raise an exception # if name in functions_noexcept: classes.write( " if ret is None:return None") # Post-processing - just before we return. if name in function_post: classes.write(" %s\n" % (function_post[name])) classes.write(" return ") classes.write(converter_type[ret[0]] % ("ret")) classes.write("\n") # For functions returning an integral type there # are several things that we can do, depending on # the contents of functions_int_*: elif is_integral_type (ret[0]): if name not in functions_noexcept: if name in functions_int_exception_test: test = functions_int_exception_test[name] else: test = functions_int_default_test if classname == "virConnect": classes.write ((" if " + test + ": raise libvirtError ('%s() failed', conn=self)\n") % ("ret", name)) elif classname == "virDomain": classes.write ((" if " + test + ": raise libvirtError ('%s() failed', dom=self)\n") % ("ret", name)) elif classname == "virNetwork": classes.write ((" if " + test + ": raise libvirtError ('%s() failed', net=self)\n") % ("ret", name)) elif classname == "virInterface": classes.write ((" if " + test + ": raise libvirtError ('%s() failed', net=self)\n") % ("ret", name)) elif classname == "virStoragePool": classes.write ((" if " + test + ": raise libvirtError ('%s() failed', pool=self)\n") % ("ret", name)) elif classname == "virStorageVol": classes.write ((" if " + test + ": raise libvirtError ('%s() failed', vol=self)\n") % ("ret", name)) else: classes.write ((" if " + test + ": raise libvirtError ('%s() failed')\n") % ("ret", name)) # Post-processing - just before we return. if name in function_post: classes.write(" %s\n" % (function_post[name])) classes.write (" return ret\n") elif is_python_noninteger_type (ret[0]): if name not in functions_noexcept: if name in functions_list_exception_test: test = functions_list_exception_test[name] else: test = functions_list_default_test if classname == "virConnect": classes.write ((" if " + test + ": raise libvirtError ('%s() failed', conn=self)\n") % ("ret", name)) elif classname == "virDomain": classes.write ((" if " + test + ": raise libvirtError ('%s() failed', dom=self)\n") % ("ret", name)) elif classname == "virNetwork": classes.write ((" if " + test + ": raise libvirtError ('%s() failed', net=self)\n") % ("ret", name)) elif classname == "virInterface": classes.write ((" if " + test + ": raise libvirtError ('%s() failed', net=self)\n") % ("ret", name)) elif classname == "virStoragePool": classes.write ((" if " + test + ": raise libvirtError ('%s() failed', pool=self)\n") % ("ret", name)) elif classname == "virStorageVol": classes.write ((" if " + test + ": raise libvirtError ('%s() failed', vol=self)\n") % ("ret", name)) else: classes.write ((" if " + test + ": raise libvirtError ('%s() failed')\n") % ("ret", name)) # Post-processing - just before we return. if name in function_post: classes.write(" %s\n" % (function_post[name])) classes.write (" return ret\n") else: # Post-processing - just before we return. if name in function_post: classes.write(" %s\n" % (function_post[name])) classes.write(" return ret\n") classes.write("\n") # Append ".py" to class def, iff it exists try: wantfuncs = [] extra = open("libvirt-override-" + classname + ".py", "r") classes.write (" #\n") classes.write (" # %s methods from %s.py (hand coded)\n" % (classname,classname)) classes.write (" #\n") cached = None # Since we compile with older libvirt, we don't want to pull # in manually written python methods which call C methods # that don't exist. This code attempts to detect which # methods to skip by looking at the libvirtmod.XXXX calls def shouldSkip(lines): for line in lines: offset = line.find("libvirtmod.") if offset != -1: func = line[offset + 11:] offset = func.find("(") func = func[0:offset] if func not in functions_skipped: return True return False for line in extra.readlines(): offset = line.find(" def ") if offset != -1: name = line[offset+5:] offset = name.find("(") name = name[0:offset] if cached is not None: if not shouldSkip(cached): classes.writelines(cached) if name == "__del__": cached = None classes.write(line) else: cached = [line] else: if cached is not None: cached.append(line) else: classes.write(line) if not shouldSkip(cached): classes.writelines(cached) classes.write("\n") extra.close() except: pass # # Generate enum constants # def enumsSortKey(data): value = data[1] try: value = int(value) except ValueError: value = float('inf') return value enumvals = list(enums.items()) if enumvals is not None: enumvals.sort(key=lambda x: x[0]) for type,enum in enumvals: classes.write("# %s\n" % type) items = list(enum.items()) items.sort(key=enumsSortKey) if items[-1][0].endswith('_LAST'): del items[-1] for name,value in items: classes.write("%s = %s\n" % (name,value)) classes.write("\n") classes.close() def qemuBuildWrappers(module): global qemu_functions if not module == "libvirt-qemu": print("ERROR: only libvirt-qemu is supported") return None extra_file = "%s-override.py" % module extra = None fd = open("build/libvirt_qemu.py", "w") if os.path.exists(extra_file): extra = open(extra_file, "r") fd.write("#\n") fd.write("# WARNING WARNING WARNING WARNING\n") fd.write("#\n") fd.write("# This file is automatically written by generator.py. Any changes\n") fd.write("# made here will be lost.\n") fd.write("#\n") fd.write("# To change the manually written methods edit " + module + "-override.py\n") fd.write("# To change the automatically written methods edit generator.py\n") fd.write("#\n") fd.write("# WARNING WARNING WARNING WARNING\n") fd.write("#\n") if extra is not None: fd.writelines(extra.readlines()) fd.write("#\n") fd.write("# WARNING WARNING WARNING WARNING\n") fd.write("#\n") fd.write("# Automatically written part of python bindings for libvirt\n") fd.write("#\n") fd.write("# WARNING WARNING WARNING WARNING\n") if extra is not None: extra.close() fd.write("try:\n") fd.write(" import libvirtmod_qemu\n") fd.write("except ImportError:\n") fd.write(" lib_e = sys.exc_info()[1]\n") fd.write(" try:\n") fd.write(" import cygvirtmod_qemu as libvirtmod_qemu\n") fd.write(" except ImportError:\n") fd.write(" cyg_e = sys.exc_info()[1]\n") fd.write(" if str(cyg_e).count(\"No module named\"):\n") fd.write(" raise lib_e\n\n") fd.write("import libvirt\n\n") fd.write("#\n# Functions from module %s\n#\n\n" % module) # # Generate functions directly, no classes # for name in list(qemu_functions.keys()): func = nameFixup(name, 'None', None, None) (desc, ret, args, file, mod, cond) = qemu_functions[name] fd.write("def %s(" % func) n = 0 for arg in args: if n != 0: fd.write(", ") fd.write("%s" % arg[0]) n = n + 1 fd.write("):\n") writeDoc(module, name, args, ' ', fd) if ret[0] != "void": fd.write(" ret = ") else: fd.write(" ") fd.write("libvirtmod_qemu.%s(" % name) n = 0 conn = None for arg in args: if arg[1] == "virConnectPtr": conn = arg[0] if n != 0: fd.write(", ") if arg[1] in ["virDomainPtr", "virConnectPtr"]: # FIXME: This might have problem if the function # has multiple args which are objects. fd.write("%s.%s" % (arg[0], "_o")) else: fd.write("%s" % arg[0]) n = n + 1 fd.write(")\n") if ret[0] != "void": fd.write(" if ret is None: raise libvirt.libvirtError('" + name + "() failed')\n") if ret[0] == "virDomainPtr": fd.write(" __tmp = virDomain(" + conn + ",_obj=ret)\n") fd.write(" return __tmp\n") else: fd.write(" return ret\n") fd.write("\n") # # Generate enum constants # for type,enum in list(qemu_enums.items()): fd.write("# %s\n" % type) items = list(enum.items()) items.sort(key=lambda i: int(i[1])) for name,value in items: fd.write("%s = %s\n" % (name,value)) fd.write("\n") fd.close() def lxcBuildWrappers(module): global lxc_functions if not module == "libvirt-lxc": print("ERROR: only libvirt-lxc is supported") return None extra_file = "%s-override.py" % module extra = None fd = open("build/libvirt_lxc.py", "w") if os.path.exists(extra_file): extra = open(extra_file, "r") fd.write("#\n") fd.write("# WARNING WARNING WARNING WARNING\n") fd.write("#\n") fd.write("# This file is automatically written by generator.py. Any changes\n") fd.write("# made here will be lost.\n") fd.write("#\n") fd.write("# To change the manually written methods edit " + module + "-override.py\n") fd.write("# To change the automatically written methods edit generator.py\n") fd.write("#\n") fd.write("# WARNING WARNING WARNING WARNING\n") fd.write("#\n") if extra is not None: fd.writelines(extra.readlines()) fd.write("#\n") fd.write("# WARNING WARNING WARNING WARNING\n") fd.write("#\n") fd.write("# Automatically written part of python bindings for libvirt\n") fd.write("#\n") fd.write("# WARNING WARNING WARNING WARNING\n") if extra is not None: extra.close() fd.write("try:\n") fd.write(" import libvirtmod_lxc\n") fd.write("except ImportError:\n") fd.write(" lib_e = sys.exc_info()[1]\n") fd.write(" try:\n") fd.write(" import cygvirtmod_lxc as libvirtmod_lxc\n") fd.write(" except ImportError:\n") fd.write(" cyg_e = sys.exc_info()[1]\n") fd.write(" if str(cyg_e).count(\"No module named\"):\n") fd.write(" raise lib_e\n\n") fd.write("import libvirt\n\n") fd.write("#\n# Functions from module %s\n#\n\n" % module) # # Generate functions directly, no classes # for name in list(lxc_functions.keys()): func = nameFixup(name, 'None', None, None) (desc, ret, args, file, mod, cond) = lxc_functions[name] fd.write("def %s(" % func) n = 0 for arg in args: if n != 0: fd.write(", ") fd.write("%s" % arg[0]) n = n + 1 fd.write("):\n") writeDoc(module, name, args, ' ', fd) if ret[0] != "void": fd.write(" ret = ") else: fd.write(" ") fd.write("libvirtmod_lxc.%s(" % name) n = 0 conn = None for arg in args: if arg[1] == "virConnectPtr": conn = arg[0] if n != 0: fd.write(", ") if arg[1] in ["virDomainPtr", "virConnectPtr"]: # FIXME: This might have problem if the function # has multiple args which are objects. fd.write("%s.%s" % (arg[0], "_o")) else: fd.write("%s" % arg[0]) n = n + 1 fd.write(")\n") if ret[0] != "void": fd.write(" if ret is None: raise libvirt.libvirtError('" + name + "() failed')\n") if ret[0] == "virDomainPtr": fd.write(" __tmp = virDomain(" + conn + ",_obj=ret)\n") fd.write(" return __tmp\n") else: fd.write(" return ret\n") fd.write("\n") # # Generate enum constants # for type,enum in list(lxc_enums.items()): fd.write("# %s\n" % type) items = list(enum.items()) items.sort(key=lambda i: int(i[1])) for name,value in items: fd.write("%s = %s\n" % (name,value)) fd.write("\n") fd.close() quiet = 0 if not os.path.exists("build"): os.mkdir("build") if buildStubs(sys.argv[1], sys.argv[2]) < 0: sys.exit(1) if sys.argv[1] == "libvirt": buildWrappers(sys.argv[1]) elif sys.argv[1] == "libvirt-lxc": lxcBuildWrappers(sys.argv[1]) elif sys.argv[1] == "libvirt-qemu": qemuBuildWrappers(sys.argv[1]) else: print("ERROR: unknown module %s" % sys.argv[1]) sys.exit(1) sys.exit(0) libvirt-python-1.2.2/libvirt-override-virDomain.py0000664000076400007640000000466512245535607023762 0ustar veillardveillard00000000000000 def listAllSnapshots(self, flags=0): """List all snapshots and returns a list of snapshot objects""" ret = libvirtmod.virDomainListAllSnapshots(self._o, flags) if ret is None: raise libvirtError("virDomainListAllSnapshots() failed", conn=self) retlist = list() for snapptr in ret: retlist.append(virDomainSnapshot(self, _obj=snapptr)) return retlist def createWithFiles(self, files, flags=0): """Launch a defined domain. If the call succeeds the domain moves from the defined to the running domains pools. @files provides an array of file descriptors which will be made available to the 'init' process of the guest. The file handles exposed to the guest will be renumbered to start from 3 (ie immediately following stderr). This is only supported for guests which use container based virtualization technology. If the VIR_DOMAIN_START_PAUSED flag is set, or if the guest domain has a managed save image that requested paused state (see virDomainManagedSave()) the guest domain will be started, but its CPUs will remain paused. The CPUs can later be manually started using virDomainResume(). In all other cases, the guest domain will be running. If the VIR_DOMAIN_START_AUTODESTROY flag is set, the guest domain will be automatically destroyed when the virConnectPtr object is finally released. This will also happen if the client application crashes / loses its connection to the libvirtd daemon. Any domains marked for auto destroy will block attempts at migration, save-to-file, or snapshots. If the VIR_DOMAIN_START_BYPASS_CACHE flag is set, and there is a managed save file for this domain (created by virDomainManagedSave()), then libvirt will attempt to bypass the file system cache while restoring the file, or fail if it cannot do so for the given system; this can allow less pressure on file system cache, but also risks slowing loads from NFS. If the VIR_DOMAIN_START_FORCE_BOOT flag is set, then any managed save file for this domain is discarded, and the domain boots from scratch. """ ret = libvirtmod.virDomainCreateWithFiles(self._o, files, flags) if ret == -1: raise libvirtError ('virDomainCreateWithFiles() failed', dom=self) return ret libvirt-python-1.2.2/examples/0000775000076400007640000000000012304641434017765 5ustar veillardveillard00000000000000libvirt-python-1.2.2/examples/domstart.py0000775000076400007640000000243012263141061022171 0ustar veillardveillard00000000000000#!/usr/bin/env python # domstart - make sure a given domU is running, if not start it import libvirt import sys import os import libxml2 import pdb # Parse the XML description of domU from FNAME # and return a tuple (name, xmldesc) where NAME # is the name of the domain, and xmldesc is the contetn of FNAME def read_domain(fname): fp = open(fname, "r") xmldesc = fp.read() fp.close() doc = libxml2.parseDoc(xmldesc) name = doc.xpathNewContext().xpathEval("/domain/name")[0].content return (name, xmldesc) def usage(): print('Usage: %s domain.xml' % sys.argv[0]) print(' Check that the domain described by DOMAIN.XML is running') print(' If the domain is not running, create it') print(' DOMAIN.XML must be a XML description of the domain') print(' in libvirt\'s XML format') if len(sys.argv) != 2: usage() sys.exit(2) (name, xmldesc) = read_domain(sys.argv[1]) conn = libvirt.open(None) if conn is None: print('Failed to open connection to the hypervisor') sys.exit(1) try: dom = conn.lookupByName(name) except libvirt.libvirtError: print("Starting domain %s ... " % name) dom = conn.createLinux(xmldesc, 0) if dom is None: print("failed") sys.exit(1) else: print("done") libvirt-python-1.2.2/examples/consolecallback.py0000664000076400007640000000555012263141061023456 0ustar veillardveillard00000000000000#!/usr/bin/env python # consolecallback - provide a persistent console that survives guest reboots import sys, os, logging, libvirt, tty, termios, atexit def reset_term(): termios.tcsetattr(0, termios.TCSADRAIN, attrs) def error_handler(unused, error): # The console stream errors on VM shutdown; we don't care if (error[0] == libvirt.VIR_ERR_RPC and error[1] == libvirt.VIR_FROM_STREAMS): return logging.warn(error) class Console(object): def __init__(self, uri, uuid): self.uri = uri self.uuid = uuid self.connection = libvirt.open(uri) self.domain = self.connection.lookupByUUIDString(uuid) self.state = self.domain.state(0) self.connection.domainEventRegister(lifecycle_callback, self) self.stream = None self.run_console = True logging.info("%s initial state %d, reason %d", self.uuid, self.state[0], self.state[1]) def check_console(console): if (console.state[0] == libvirt.VIR_DOMAIN_RUNNING or console.state[0] == libvirt.VIR_DOMAIN_PAUSED): if console.stream is None: console.stream = console.connection.newStream(libvirt.VIR_STREAM_NONBLOCK) console.domain.openConsole(None, console.stream, 0) console.stream.eventAddCallback(libvirt.VIR_STREAM_EVENT_READABLE, stream_callback, console) else: if console.stream: console.stream.eventRemoveCallback() console.stream = None return console.run_console def stdin_callback(watch, fd, events, console): readbuf = os.read(fd, 1024) if readbuf.startswith(""): console.run_console = False return if console.stream: console.stream.send(readbuf) def stream_callback(stream, events, console): try: received_data = console.stream.recv(1024) except: return os.write(0, received_data) def lifecycle_callback (connection, domain, event, detail, console): console.state = console.domain.state(0) logging.info("%s transitioned to state %d, reason %d", console.uuid, console.state[0], console.state[1]) # main if len(sys.argv) != 3: print("Usage:", sys.argv[0], "URI UUID") print("for example:", sys.argv[0], "'qemu:///system' '32ad945f-7e78-c33a-e96d-39f25e025d81'") sys.exit(1) uri = sys.argv[1] uuid = sys.argv[2] print("Escape character is ^]") logging.basicConfig(filename='msg.log', level=logging.DEBUG) logging.info("URI: %s", uri) logging.info("UUID: %s", uuid) libvirt.virEventRegisterDefaultImpl() libvirt.registerErrorHandler(error_handler, None) atexit.register(reset_term) attrs = termios.tcgetattr(0) tty.setraw(0) console = Console(uri, uuid) console.stdin_watch = libvirt.virEventAddHandle(0, libvirt.VIR_EVENT_HANDLE_READABLE, stdin_callback, console) while check_console(console): libvirt.virEventRunDefaultImpl() libvirt-python-1.2.2/examples/dominfo.py0000775000076400007640000000402712263141061021773 0ustar veillardveillard00000000000000#!/usr/bin/env python # dominfo - print some information about a domain import libvirt import sys import os import libxml2 import pdb def usage(): print('Usage: %s DOMAIN' % sys.argv[0]) print(' Print information about the domain DOMAIN') def print_section(title): print("\n%s" % title) print("=" * 60) def print_entry(key, value): print("%-10s %-10s" % (key, value)) def print_xml(key, ctx, path): res = ctx.xpathEval(path) if res is None or len(res) == 0: value="Unknown" else: value = res[0].content print_entry(key, value) return value if len(sys.argv) != 2: usage() sys.exit(2) name = sys.argv[1] # Connect to libvirt conn = libvirt.openReadOnly(None) if conn is None: print('Failed to open connection to the hypervisor') sys.exit(1) try: dom = conn.lookupByName(name) # Annoyiingly, libvirt prints its own error message here except libvirt.libvirtError: print("Domain %s is not running" % name) sys.exit(0) info = dom.info() print_section("Domain info") print_entry("State:", info[0]) print_entry("MaxMem:", info[1]) print_entry("UsedMem:", info[2]) print_entry("VCPUs:", info[3]) # Read some info from the XML desc xmldesc = dom.XMLDesc(0) doc = libxml2.parseDoc(xmldesc) ctx = doc.xpathNewContext() print_section("Kernel") print_xml("Type:", ctx, "/domain/os/type") print_xml("Kernel:", ctx, "/domain/os/kernel") print_xml("initrd:", ctx, "/domain/os/initrd") print_xml("cmdline:", ctx, "/domain/os/cmdline") print_section("Devices") devs = ctx.xpathEval("/domain/devices/*") for d in devs: ctx.setContextNode(d) #pdb.set_trace() type = print_xml("Type:", ctx, "@type") if type == "file": print_xml("Source:", ctx, "source/@file") print_xml("Target:", ctx, "target/@dev") elif type == "block": print_xml("Source:", ctx, "source/@dev") print_xml("Target:", ctx, "target/@dev") elif type == "bridge": print_xml("Source:", ctx, "source/@bridge") print_xml("MAC Addr:", ctx, "mac/@address") libvirt-python-1.2.2/examples/domrestore.py0000775000076400007640000000143612263141061022524 0ustar veillardveillard00000000000000#!/usr/bin/env python # domstart - make sure a given domU is running, if not start it import libvirt import sys import os import libxml2 import pdb def usage(): print('Usage: %s DIR' % sys.argv[0]) print(' Restore all the domains contained in DIR') print(' It is assumed that all files in DIR are') print(' images of domU\'s previously created with save') if len(sys.argv) != 2: usage() sys.exit(2) dir = sys.argv[1] imgs = os.listdir(dir) conn = libvirt.open(None) if conn is None: print('Failed to open connection to the hypervisor') sys.exit(1) for img in imgs: file = os.path.join(dir, img) print("Restoring %s ... " % img) ret = conn.restore(file) if ret == 0: print("done") else: print("error %d" % ret) libvirt-python-1.2.2/examples/esxlist.py0000775000076400007640000001200712263141061022030 0ustar veillardveillard00000000000000#!/usr/bin/env python # esxlist - list active domains of an ESX host and print some info. # also demonstrates how to use the libvirt.openAuth() method import libvirt import sys import os import libxml2 import getpass def usage(): print("Usage: %s HOSTNAME" % sys.argv[0]) print(" List active domains of HOSTNAME and print some info") # This is the callback method passed to libvirt.openAuth() (see below). # # The credentials argument is a list of credentials that libvirt (actually # the ESX driver) would like to request. An element of this list is itself a # list containing 5 items (4 inputs, 1 output): # - the credential type, e.g. libvirt.VIR_CRED_AUTHNAME # - a prompt to be displayed to the user # - a challenge, the ESX driver sets this to the hostname to allow automatic # distinction between requests for ESX and vCenter credentials # - a default result for the request # - a place to store the actual result for the request # # The user_data argument is the user data item of the auth argument (see below) # passed to libvirt.openAuth(). def request_credentials(credentials, user_data): for credential in credentials: if credential[0] == libvirt.VIR_CRED_AUTHNAME: # prompt the user to input a authname. display the provided message credential[4] = raw_input(credential[1] + ": ") # if the user just hits enter raw_input() returns an empty string. # in this case return the default result through the last item of # the list if len(credential[4]) == 0: credential[4] = credential[3] elif credential[0] == libvirt.VIR_CRED_NOECHOPROMPT: # use the getpass module to prompt the user to input a password. # display the provided message and return the result through the # last item of the list credential[4] = getpass.getpass(credential[1] + ": ") else: return -1 return 0 def print_section(title): print("\n%s" % title) print("=" * 60) def print_entry(key, value): print("%-10s %-10s" % (key, value)) def print_xml(key, ctx, path): res = ctx.xpathEval(path) if res is None or len(res) == 0: value = "Unknown" else: value = res[0].content print_entry(key, value) return value if len(sys.argv) != 2: usage() sys.exit(2) hostname = sys.argv[1] # Connect to libvirt uri = "esx://%s/?no_verify=1" % hostname # The auth argument is a list that contains 3 items: # - a list of supported credential types # - a callable that takes 2 arguments # - user data that will be passed to the callable as second argument # # In this example the supported credential types are VIR_CRED_AUTHNAME and # VIR_CRED_NOECHOPROMPT, the callable is the unbound method request_credentials # (see above) and the user data is None. # # libvirt (actually the ESX driver) will call the callable to request # credentials in order to log into the ESX host. The callable would also be # called if the connection URI would reference a vCenter to request credentials # in order to log into the vCenter auth = [[libvirt.VIR_CRED_AUTHNAME, libvirt.VIR_CRED_NOECHOPROMPT], request_credentials, None] conn = libvirt.openAuth(uri, auth, 0) if conn is None: print("Failed to open connection to %s" % hostname) sys.exit(1) state_names = { libvirt.VIR_DOMAIN_RUNNING : "running", libvirt.VIR_DOMAIN_BLOCKED : "idle", libvirt.VIR_DOMAIN_PAUSED : "paused", libvirt.VIR_DOMAIN_SHUTDOWN : "in shutdown", libvirt.VIR_DOMAIN_SHUTOFF : "shut off", libvirt.VIR_DOMAIN_CRASHED : "crashed", libvirt.VIR_DOMAIN_NOSTATE : "no state" } for id in conn.listDomainsID(): domain = conn.lookupByID(id) info = domain.info() print_section("Domain " + domain.name()) print_entry("ID:", id) print_entry("UUID:", domain.UUIDString()) print_entry("State:", state_names[info[0]]) print_entry("MaxMem:", info[1]) print_entry("UsedMem:", info[2]) print_entry("VCPUs:", info[3]) # Read some info from the XML desc print_section("Devices of " + domain.name()) xmldesc = domain.XMLDesc(0) doc = libxml2.parseDoc(xmldesc) ctx = doc.xpathNewContext() devs = ctx.xpathEval("/domain/devices/*") first = True for d in devs: ctx.setContextNode(d) if not first: print("------------------------------------------------------------") else: first = False print_entry("Device", d.name) type = print_xml("Type:", ctx, "@type") if type == "file": print_xml("Source:", ctx, "source/@file") print_xml("Target:", ctx, "target/@dev") elif type == "block": print_xml("Source:", ctx, "source/@dev") print_xml("Target:", ctx, "target/@dev") elif type == "bridge": print_xml("Source:", ctx, "source/@bridge") print_xml("MAC Addr:", ctx, "mac/@address") libvirt-python-1.2.2/examples/domsave.py0000775000076400007640000000151412263141061021774 0ustar veillardveillard00000000000000#!/usr/bin/env python # domstart - make sure a given domU is running, if not start it import libvirt import sys import os import libxml2 import pdb def usage(): print('Usage: %s DIR' % sys.argv[0]) print(' Save all currently running domU\'s into DIR') print(' DIR must exist and be writable by this process') if len(sys.argv) != 2: usage() sys.exit(2) dir = sys.argv[1] conn = libvirt.open(None) if conn is None: print('Failed to open connection to the hypervisor') sys.exit(1) doms = conn.listDomainsID() for id in doms: if id == 0: continue dom = conn.lookupByID(id) print("Saving %s[%d] ... " % (dom.name(), id)) path = os.path.join(dir, dom.name()) ret = dom.save(path) if ret == 0: print("done") else: print("error %d" % ret) #pdb.set_trace() libvirt-python-1.2.2/examples/event-test.py0000664000076400007640000005630712302554455022454 0ustar veillardveillard00000000000000#!/usr/bin/python -u # # # ############################################################################## # Start off by implementing a general purpose event loop for anyone's use ############################################################################## import sys import getopt import os import libvirt import select import errno import time import threading # For the sake of demonstration, this example program includes # an implementation of a pure python event loop. Most applications # would be better off just using the default libvirt event loop # APIs, instead of implementing this in python. The exception is # where an application wants to integrate with an existing 3rd # party event loop impl # # Change this to 'False' to make the demo use the native # libvirt event loop impl use_pure_python_event_loop = True do_debug = False def debug(msg): global do_debug if do_debug: print(msg) # # This general purpose event loop will support waiting for file handle # I/O and errors events, as well as scheduling repeatable timers with # a fixed interval. # # It is a pure python implementation based around the poll() API # class virEventLoopPure: # This class contains the data we need to track for a # single file handle class virEventLoopPureHandle: def __init__(self, handle, fd, events, cb, opaque): self.handle = handle self.fd = fd self.events = events self.cb = cb self.opaque = opaque def get_id(self): return self.handle def get_fd(self): return self.fd def get_events(self): return self.events def set_events(self, events): self.events = events def dispatch(self, events): self.cb(self.handle, self.fd, events, self.opaque) # This class contains the data we need to track for a # single periodic timer class virEventLoopPureTimer: def __init__(self, timer, interval, cb, opaque): self.timer = timer self.interval = interval self.cb = cb self.opaque = opaque self.lastfired = 0 def get_id(self): return self.timer def get_interval(self): return self.interval def set_interval(self, interval): self.interval = interval def get_last_fired(self): return self.lastfired def set_last_fired(self, now): self.lastfired = now def dispatch(self): self.cb(self.timer, self.opaque) def __init__(self): self.poll = select.poll() self.pipetrick = os.pipe() self.pendingWakeup = False self.runningPoll = False self.nextHandleID = 1 self.nextTimerID = 1 self.handles = [] self.timers = [] self.quit = False # The event loop can be used from multiple threads at once. # Specifically while the main thread is sleeping in poll() # waiting for events to occur, another thread may come along # and add/update/remove a file handle, or timer. When this # happens we need to interrupt the poll() sleep in the other # thread, so that it'll see the file handle / timer changes. # # Using OS level signals for this is very unreliable and # hard to implement correctly. Thus we use the real classic # "self pipe" trick. A anonymous pipe, with one end registered # with the event loop for input events. When we need to force # the main thread out of a poll() sleep, we simple write a # single byte of data to the other end of the pipe. debug("Self pipe watch %d write %d" %(self.pipetrick[0], self.pipetrick[1])) self.poll.register(self.pipetrick[0], select.POLLIN) # Calculate when the next timeout is due to occur, returning # the absolute timestamp for the next timeout, or 0 if there is # no timeout due def next_timeout(self): next = 0 for t in self.timers: last = t.get_last_fired() interval = t.get_interval() if interval < 0: continue if next == 0 or (last + interval) < next: next = last + interval return next # Lookup a virEventLoopPureHandle object based on file descriptor def get_handle_by_fd(self, fd): for h in self.handles: if h.get_fd() == fd: return h return None # Lookup a virEventLoopPureHandle object based on its event loop ID def get_handle_by_id(self, handleID): for h in self.handles: if h.get_id() == handleID: return h return None # This is the heart of the event loop, performing one single # iteration. It asks when the next timeout is due, and then # calculates the maximum amount of time it is able to sleep # for in poll() pending file handle events. # # It then goes into the poll() sleep. # # When poll() returns, there will zero or more file handle # events which need to be dispatched to registered callbacks # It may also be time to fire some periodic timers. # # Due to the coarse granularity of scheduler timeslices, if # we ask for a sleep of 500ms in order to satisfy a timer, we # may return up to 1 scheduler timeslice early. So even though # our sleep timeout was reached, the registered timer may not # technically be at its expiry point. This leads to us going # back around the loop with a crazy 5ms sleep. So when checking # if timeouts are due, we allow a margin of 20ms, to avoid # these pointless repeated tiny sleeps. def run_once(self): sleep = -1 self.runningPoll = True try: next = self.next_timeout() debug("Next timeout due at %d" % next) if next > 0: now = int(time.time() * 1000) if now >= next: sleep = 0 else: sleep = (next - now) / 1000.0 debug("Poll with a sleep of %d" % sleep) events = self.poll.poll(sleep) # Dispatch any file handle events that occurred for (fd, revents) in events: # See if the events was from the self-pipe # telling us to wakup. if so, then discard # the data just continue if fd == self.pipetrick[0]: self.pendingWakeup = False data = os.read(fd, 1) continue h = self.get_handle_by_fd(fd) if h: debug("Dispatch fd %d handle %d events %d" % (fd, h.get_id(), revents)) h.dispatch(self.events_from_poll(revents)) now = int(time.time() * 1000) for t in self.timers: interval = t.get_interval() if interval < 0: continue want = t.get_last_fired() + interval # Deduct 20ms, since scheduler timeslice # means we could be ever so slightly early if now >= (want-20): debug("Dispatch timer %d now %s want %s" % (t.get_id(), str(now), str(want))) t.set_last_fired(now) t.dispatch() except (os.error, select.error), e: if e.args[0] != errno.EINTR: raise finally: self.runningPoll = False # Actually run the event loop forever def run_loop(self): self.quit = False while not self.quit: self.run_once() def interrupt(self): if self.runningPoll and not self.pendingWakeup: self.pendingWakeup = True os.write(self.pipetrick[1], 'c'.encode("UTF-8")) # Registers a new file handle 'fd', monitoring for 'events' (libvirt # event constants), firing the callback cb() when an event occurs. # Returns a unique integer identier for this handle, that should be # used to later update/remove it def add_handle(self, fd, events, cb, opaque): handleID = self.nextHandleID + 1 self.nextHandleID = self.nextHandleID + 1 h = self.virEventLoopPureHandle(handleID, fd, events, cb, opaque) self.handles.append(h) self.poll.register(fd, self.events_to_poll(events)) self.interrupt() debug("Add handle %d fd %d events %d" % (handleID, fd, events)) return handleID # Registers a new timer with periodic expiry at 'interval' ms, # firing cb() each time the timer expires. If 'interval' is -1, # then the timer is registered, but not enabled # Returns a unique integer identier for this handle, that should be # used to later update/remove it def add_timer(self, interval, cb, opaque): timerID = self.nextTimerID + 1 self.nextTimerID = self.nextTimerID + 1 h = self.virEventLoopPureTimer(timerID, interval, cb, opaque) self.timers.append(h) self.interrupt() debug("Add timer %d interval %d" % (timerID, interval)) return timerID # Change the set of events to be monitored on the file handle def update_handle(self, handleID, events): h = self.get_handle_by_id(handleID) if h: h.set_events(events) self.poll.unregister(h.get_fd()) self.poll.register(h.get_fd(), self.events_to_poll(events)) self.interrupt() debug("Update handle %d fd %d events %d" % (handleID, h.get_fd(), events)) # Change the periodic frequency of the timer def update_timer(self, timerID, interval): for h in self.timers: if h.get_id() == timerID: h.set_interval(interval) self.interrupt() debug("Update timer %d interval %d" % (timerID, interval)) break # Stop monitoring for events on the file handle def remove_handle(self, handleID): handles = [] for h in self.handles: if h.get_id() == handleID: self.poll.unregister(h.get_fd()) debug("Remove handle %d fd %d" % (handleID, h.get_fd())) else: handles.append(h) self.handles = handles self.interrupt() # Stop firing the periodic timer def remove_timer(self, timerID): timers = [] for h in self.timers: if h.get_id() != timerID: timers.append(h) debug("Remove timer %d" % timerID) self.timers = timers self.interrupt() # Convert from libvirt event constants, to poll() events constants def events_to_poll(self, events): ret = 0 if events & libvirt.VIR_EVENT_HANDLE_READABLE: ret |= select.POLLIN if events & libvirt.VIR_EVENT_HANDLE_WRITABLE: ret |= select.POLLOUT if events & libvirt.VIR_EVENT_HANDLE_ERROR: ret |= select.POLLERR if events & libvirt.VIR_EVENT_HANDLE_HANGUP: ret |= select.POLLHUP return ret # Convert from poll() event constants, to libvirt events constants def events_from_poll(self, events): ret = 0 if events & select.POLLIN: ret |= libvirt.VIR_EVENT_HANDLE_READABLE if events & select.POLLOUT: ret |= libvirt.VIR_EVENT_HANDLE_WRITABLE if events & select.POLLNVAL: ret |= libvirt.VIR_EVENT_HANDLE_ERROR if events & select.POLLERR: ret |= libvirt.VIR_EVENT_HANDLE_ERROR if events & select.POLLHUP: ret |= libvirt.VIR_EVENT_HANDLE_HANGUP return ret ########################################################################### # Now glue an instance of the general event loop into libvirt's event loop ########################################################################### # This single global instance of the event loop wil be used for # monitoring libvirt events eventLoop = virEventLoopPure() # This keeps track of what thread is running the event loop, # (if it is run in a background thread) eventLoopThread = None # These next set of 6 methods are the glue between the official # libvirt events API, and our particular impl of the event loop # # There is no reason why the 'virEventLoopPure' has to be used. # An application could easily may these 6 glue methods hook into # another event loop such as GLib's, or something like the python # Twisted event framework. def virEventAddHandleImpl(fd, events, cb, opaque): global eventLoop return eventLoop.add_handle(fd, events, cb, opaque) def virEventUpdateHandleImpl(handleID, events): global eventLoop return eventLoop.update_handle(handleID, events) def virEventRemoveHandleImpl(handleID): global eventLoop return eventLoop.remove_handle(handleID) def virEventAddTimerImpl(interval, cb, opaque): global eventLoop return eventLoop.add_timer(interval, cb, opaque) def virEventUpdateTimerImpl(timerID, interval): global eventLoop return eventLoop.update_timer(timerID, interval) def virEventRemoveTimerImpl(timerID): global eventLoop return eventLoop.remove_timer(timerID) # This tells libvirt what event loop implementation it # should use def virEventLoopPureRegister(): libvirt.virEventRegisterImpl(virEventAddHandleImpl, virEventUpdateHandleImpl, virEventRemoveHandleImpl, virEventAddTimerImpl, virEventUpdateTimerImpl, virEventRemoveTimerImpl) # Directly run the event loop in the current thread def virEventLoopPureRun(): global eventLoop eventLoop.run_loop() def virEventLoopNativeRun(): while True: libvirt.virEventRunDefaultImpl() # Spawn a background thread to run the event loop def virEventLoopPureStart(): global eventLoopThread virEventLoopPureRegister() eventLoopThread = threading.Thread(target=virEventLoopPureRun, name="libvirtEventLoop") eventLoopThread.setDaemon(True) eventLoopThread.start() def virEventLoopNativeStart(): global eventLoopThread libvirt.virEventRegisterDefaultImpl() eventLoopThread = threading.Thread(target=virEventLoopNativeRun, name="libvirtEventLoop") eventLoopThread.setDaemon(True) eventLoopThread.start() ########################################################################## # Everything that now follows is a simple demo of domain lifecycle events ########################################################################## def domEventToString(event): domEventStrings = ( "Defined", "Undefined", "Started", "Suspended", "Resumed", "Stopped", "Shutdown", "PMSuspended", "Crashed", ) return domEventStrings[event] def domDetailToString(event, detail): domEventStrings = ( ( "Added", "Updated" ), ( "Removed", ), ( "Booted", "Migrated", "Restored", "Snapshot", "Wakeup" ), ( "Paused", "Migrated", "IOError", "Watchdog", "Restored", "Snapshot", "API error" ), ( "Unpaused", "Migrated", "Snapshot" ), ( "Shutdown", "Destroyed", "Crashed", "Migrated", "Saved", "Failed", "Snapshot"), ( "Finished", ), ( "Memory", "Disk" ), ( "Panicked", ), ) return domEventStrings[event][detail] def myDomainEventCallback1 (conn, dom, event, detail, opaque): print("myDomainEventCallback1 EVENT: Domain %s(%s) %s %s" % (dom.name(), dom.ID(), domEventToString(event), domDetailToString(event, detail))) def myDomainEventCallback2 (conn, dom, event, detail, opaque): print("myDomainEventCallback2 EVENT: Domain %s(%s) %s %s" % (dom.name(), dom.ID(), domEventToString(event), domDetailToString(event, detail))) def myDomainEventRebootCallback(conn, dom, opaque): print("myDomainEventRebootCallback: Domain %s(%s)" % (dom.name(), dom.ID())) def myDomainEventRTCChangeCallback(conn, dom, utcoffset, opaque): print("myDomainEventRTCChangeCallback: Domain %s(%s) %d" % (dom.name(), dom.ID(), utcoffset)) def myDomainEventWatchdogCallback(conn, dom, action, opaque): print("myDomainEventWatchdogCallback: Domain %s(%s) %d" % (dom.name(), dom.ID(), action)) def myDomainEventIOErrorCallback(conn, dom, srcpath, devalias, action, opaque): print("myDomainEventIOErrorCallback: Domain %s(%s) %s %s %d" % (dom.name(), dom.ID(), srcpath, devalias, action)) def myDomainEventGraphicsCallback(conn, dom, phase, localAddr, remoteAddr, authScheme, subject, opaque): print("myDomainEventGraphicsCallback: Domain %s(%s) %d %s" % (dom.name(), dom.ID(), phase, authScheme)) def myDomainEventDiskChangeCallback(conn, dom, oldSrcPath, newSrcPath, devAlias, reason, opaque): print("myDomainEventDiskChangeCallback: Domain %s(%s) disk change oldSrcPath: %s newSrcPath: %s devAlias: %s reason: %s" % ( dom.name(), dom.ID(), oldSrcPath, newSrcPath, devAlias, reason)) def myDomainEventTrayChangeCallback(conn, dom, devAlias, reason, opaque): print("myDomainEventTrayChangeCallback: Domain %s(%s) tray change devAlias: %s reason: %s" % ( dom.name(), dom.ID(), devAlias, reason)) def myDomainEventPMWakeupCallback(conn, dom, reason, opaque): print("myDomainEventPMWakeupCallback: Domain %s(%s) system pmwakeup" % ( dom.name(), dom.ID())) def myDomainEventPMSuspendCallback(conn, dom, reason, opaque): print("myDomainEventPMSuspendCallback: Domain %s(%s) system pmsuspend" % ( dom.name(), dom.ID())) def myDomainEventBalloonChangeCallback(conn, dom, actual, opaque): print("myDomainEventBalloonChangeCallback: Domain %s(%s) %d" % (dom.name(), dom.ID(), actual)) def myDomainEventPMSuspendDiskCallback(conn, dom, reason, opaque): print("myDomainEventPMSuspendDiskCallback: Domain %s(%s) system pmsuspend_disk" % ( dom.name(), dom.ID())) def myDomainEventDeviceRemovedCallback(conn, dom, dev, opaque): print("myDomainEventDeviceRemovedCallback: Domain %s(%s) device removed: %s" % ( dom.name(), dom.ID(), dev)) ########################################################################## # Network events ########################################################################## def netEventToString(event): netEventStrings = ( "Defined", "Undefined", "Started", "Stopped", ) return netEventStrings[event] def netDetailToString(event, detail): netEventStrings = ( ( "Added", ), ( "Removed", ), ( "Started", ), ( "Stopped", ), ) return netEventStrings[event][detail] def myNetworkEventLifecycleCallback(conn, net, event, detail, opaque): print("myNetworkEventLifecycleCallback: Network %s %s %s" % (net.name(), netEventToString(event), netDetailToString(event, detail))) ########################################################################## # Set up and run the program ########################################################################## run = True def myConnectionCloseCallback(conn, reason, opaque): reasonStrings = ( "Error", "End-of-file", "Keepalive", "Client", ) print("myConnectionCloseCallback: %s: %s" % (conn.getURI(), reasonStrings[reason])) run = False def usage(): print("usage: "+os.path.basename(sys.argv[0])+" [-hdl] [uri]") print(" uri will default to qemu:///system") print(" --help, -h Print(this help message") print(" --debug, -d Print(debug output") print(" --loop, -l Toggle event-loop-implementation") def main(): try: opts, args = getopt.getopt(sys.argv[1:], "hdl", ["help", "debug", "loop"]) except getopt.GetoptError, err: # print help information and exit: print(str(err)) # will print something like "option -a not recognized" usage() sys.exit(2) for o, a in opts: if o in ("-h", "--help"): usage() sys.exit() if o in ("-d", "--debug"): global do_debug do_debug = True if o in ("-l", "--loop"): global use_pure_python_event_loop use_pure_python_event_loop ^= True if len(args) >= 1: uri = args[0] else: uri = "qemu:///system" print("Using uri:" + uri) # Run a background thread with the event loop if use_pure_python_event_loop: virEventLoopPureStart() else: virEventLoopNativeStart() vc = libvirt.openReadOnly(uri) # Close connection on exit (to test cleanup paths) old_exitfunc = getattr(sys, 'exitfunc', None) def exit(): print("Closing " + vc.getURI()) vc.close() if (old_exitfunc): old_exitfunc() sys.exitfunc = exit vc.registerCloseCallback(myConnectionCloseCallback, None) #Add 2 callbacks to prove this works with more than just one vc.domainEventRegister(myDomainEventCallback1,None) vc.domainEventRegisterAny(None, libvirt.VIR_DOMAIN_EVENT_ID_LIFECYCLE, myDomainEventCallback2, None) vc.domainEventRegisterAny(None, libvirt.VIR_DOMAIN_EVENT_ID_REBOOT, myDomainEventRebootCallback, None) vc.domainEventRegisterAny(None, libvirt.VIR_DOMAIN_EVENT_ID_RTC_CHANGE, myDomainEventRTCChangeCallback, None) vc.domainEventRegisterAny(None, libvirt.VIR_DOMAIN_EVENT_ID_IO_ERROR, myDomainEventIOErrorCallback, None) vc.domainEventRegisterAny(None, libvirt.VIR_DOMAIN_EVENT_ID_WATCHDOG, myDomainEventWatchdogCallback, None) vc.domainEventRegisterAny(None, libvirt.VIR_DOMAIN_EVENT_ID_GRAPHICS, myDomainEventGraphicsCallback, None) vc.domainEventRegisterAny(None, libvirt.VIR_DOMAIN_EVENT_ID_DISK_CHANGE, myDomainEventDiskChangeCallback, None) vc.domainEventRegisterAny(None, libvirt.VIR_DOMAIN_EVENT_ID_TRAY_CHANGE, myDomainEventTrayChangeCallback, None) vc.domainEventRegisterAny(None, libvirt.VIR_DOMAIN_EVENT_ID_PMWAKEUP, myDomainEventPMWakeupCallback, None) vc.domainEventRegisterAny(None, libvirt.VIR_DOMAIN_EVENT_ID_PMSUSPEND, myDomainEventPMSuspendCallback, None) vc.domainEventRegisterAny(None, libvirt.VIR_DOMAIN_EVENT_ID_BALLOON_CHANGE, myDomainEventBalloonChangeCallback, None) vc.domainEventRegisterAny(None, libvirt.VIR_DOMAIN_EVENT_ID_PMSUSPEND_DISK, myDomainEventPMSuspendDiskCallback, None) vc.domainEventRegisterAny(None, libvirt.VIR_DOMAIN_EVENT_ID_DEVICE_REMOVED, myDomainEventDeviceRemovedCallback, None) vc.networkEventRegisterAny(None, libvirt.VIR_NETWORK_EVENT_ID_LIFECYCLE, myNetworkEventLifecycleCallback, None) vc.setKeepAlive(5, 3) # The rest of your app would go here normally, but for sake # of demo we'll just go to sleep. The other option is to # run the event loop in your main thread if your app is # totally event based. while run: time.sleep(1) if __name__ == "__main__": main() libvirt-python-1.2.2/examples/topology.py0000775000076400007640000000241112263141061022207 0ustar veillardveillard00000000000000#!/usr/bin/env python # Parse topology information from the capabilities XML and use # them to calculate host topology # # Authors: # Amador Pahim # Peter Krempa import libvirt import sys from xml.dom import minidom try: conn = libvirt.openReadOnly(None) except libvirt.libvirtError: print('Failed to connect to the hypervisor') sys.exit(1) try: capsXML = conn.getCapabilities() except libvirt.libvirtError: print('Failed to request capabilities') sys.exit(1) caps = minidom.parseString(capsXML) host = caps.getElementsByTagName('host')[0] cells = host.getElementsByTagName('cells')[0] total_cpus = cells.getElementsByTagName('cpu').length socketIds = [] siblingsIds = [] socketIds = [ proc.getAttribute('socket_id') for proc in cells.getElementsByTagName('cpu') if proc.getAttribute('socket_id') not in socketIds ] siblingsIds = [ proc.getAttribute('siblings') for proc in cells.getElementsByTagName('cpu') if proc.getAttribute('siblings') not in siblingsIds ] print("Host topology") print("NUMA nodes:", cells.getAttribute('num')) print(" Sockets:", len(set(socketIds))) print(" Cores:", len(set(siblingsIds))) print(" Threads:", total_cpus) libvirt-python-1.2.2/libvirt-lxc-override-api.xml0000664000076400007640000000134112245535607023523 0ustar veillardveillard00000000000000