2005-12-20 00:34:11 +08:00
|
|
|
#!/usr/bin/python -u
|
|
|
|
#
|
|
|
|
# generate python wrappers from the XML API description
|
|
|
|
#
|
|
|
|
|
|
|
|
functions = {}
|
|
|
|
enums = {} # { enumType: { enumConstant: enumValue } }
|
|
|
|
|
|
|
|
import os
|
|
|
|
import sys
|
|
|
|
import string
|
2007-03-28 19:24:14 +08:00
|
|
|
import re
|
2005-12-20 00:34:11 +08:00
|
|
|
|
|
|
|
if __name__ == "__main__":
|
|
|
|
# launched as a script
|
|
|
|
srcPref = os.path.dirname(sys.argv[0])
|
2011-03-11 20:44:20 +08:00
|
|
|
if len(sys.argv) > 1:
|
|
|
|
python = sys.argv[1]
|
|
|
|
else:
|
|
|
|
print "Python binary not specified"
|
|
|
|
sys.exit(1)
|
2005-12-20 00:34:11 +08:00
|
|
|
else:
|
|
|
|
# imported
|
|
|
|
srcPref = os.path.dirname(__file__)
|
|
|
|
|
|
|
|
#######################################################################
|
|
|
|
#
|
|
|
|
# That part if purely the API acquisition phase from the
|
2006-02-10 01:45:11 +08:00
|
|
|
# libvirt API description
|
2005-12-20 00:34:11 +08:00
|
|
|
#
|
|
|
|
#######################################################################
|
|
|
|
import os
|
2009-10-02 23:20:47 +08:00
|
|
|
import xml.sax
|
2005-12-20 00:34:11 +08:00
|
|
|
|
|
|
|
debug = 0
|
|
|
|
|
2009-10-02 22:34:54 +08:00
|
|
|
def getparser():
|
|
|
|
# Attach parser to an unmarshalling object. return both objects.
|
|
|
|
target = docParser()
|
2009-10-02 23:20:47 +08:00
|
|
|
parser = xml.sax.make_parser()
|
|
|
|
parser.setContentHandler(target)
|
|
|
|
return parser, target
|
2005-12-20 00:34:11 +08:00
|
|
|
|
2009-10-02 23:20:47 +08:00
|
|
|
class docParser(xml.sax.handler.ContentHandler):
|
2005-12-20 00:34:11 +08:00
|
|
|
def __init__(self):
|
|
|
|
self._methodname = None
|
|
|
|
self._data = []
|
|
|
|
self.in_function = 0
|
|
|
|
|
2009-10-02 23:20:47 +08:00
|
|
|
self.startElement = self.start
|
|
|
|
self.endElement = self.end
|
|
|
|
self.characters = self.data
|
|
|
|
|
2005-12-20 00:34:11 +08:00
|
|
|
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)
|
|
|
|
|
2009-09-25 20:24:40 +08:00
|
|
|
def cdata(self, text):
|
|
|
|
if debug:
|
|
|
|
print "data %s" % text
|
|
|
|
self._data.append(text)
|
|
|
|
|
2005-12-20 00:34:11 +08:00
|
|
|
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
|
|
|
|
if attrs.has_key('name'):
|
|
|
|
self.function = attrs['name']
|
|
|
|
if attrs.has_key('file'):
|
|
|
|
self.function_file = attrs['file']
|
|
|
|
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 attrs.has_key('name'):
|
|
|
|
self.function_arg_name = attrs['name']
|
2011-02-16 23:57:50 +08:00
|
|
|
if self.function_arg_name == 'from':
|
|
|
|
self.function_arg_name = 'frm'
|
2005-12-20 00:34:11 +08:00
|
|
|
if attrs.has_key('type'):
|
|
|
|
self.function_arg_type = attrs['type']
|
|
|
|
if attrs.has_key('info'):
|
|
|
|
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 attrs.has_key('type'):
|
|
|
|
self.function_return_type = attrs['type']
|
|
|
|
if attrs.has_key('info'):
|
|
|
|
self.function_return_info = attrs['info']
|
|
|
|
if attrs.has_key('field'):
|
|
|
|
self.function_return_field = attrs['field']
|
|
|
|
elif tag == 'enum':
|
|
|
|
enum(attrs['type'],attrs['name'],attrs['value'])
|
|
|
|
|
|
|
|
def end(self, tag):
|
|
|
|
if debug:
|
|
|
|
print "end %s" % tag
|
|
|
|
if tag == 'function':
|
|
|
|
if self.function != None:
|
|
|
|
function(self.function, self.function_descr,
|
|
|
|
self.function_return, self.function_args,
|
|
|
|
self.function_file, 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
|
2008-02-06 03:27:37 +08:00
|
|
|
|
|
|
|
|
2005-12-20 00:34:11 +08:00
|
|
|
def function(name, desc, ret, args, file, cond):
|
|
|
|
functions[name] = (desc, ret, args, file, cond)
|
|
|
|
|
|
|
|
def enum(type, name, value):
|
|
|
|
if not enums.has_key(type):
|
|
|
|
enums[type] = {}
|
|
|
|
enums[type][name] = value
|
|
|
|
|
|
|
|
#######################################################################
|
|
|
|
#
|
|
|
|
# Some filtering rukes to drop functions/types which should not
|
|
|
|
# be exposed as-is on the Python interface
|
|
|
|
#
|
|
|
|
#######################################################################
|
|
|
|
|
2006-01-31 18:24:12 +08:00
|
|
|
functions_failed = []
|
2006-02-23 19:26:17 +08:00
|
|
|
functions_skipped = [
|
2009-12-20 20:28:42 +08:00
|
|
|
"virConnectListDomains",
|
2006-02-23 19:26:17 +08:00
|
|
|
]
|
2006-01-31 18:24:12 +08:00
|
|
|
|
2005-12-20 00:34:11 +08:00
|
|
|
skipped_modules = {
|
|
|
|
}
|
|
|
|
|
|
|
|
skipped_types = {
|
2008-01-21 23:55:53 +08:00
|
|
|
# 'int *': "usually a return type",
|
2008-10-31 18:13:45 +08:00
|
|
|
'virConnectDomainEventCallback': "No function types in python",
|
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-18 21:01:48 +08:00
|
|
|
'virConnectDomainEventGenericCallback': "No function types in python",
|
2010-03-19 02:28:15 +08:00
|
|
|
'virConnectDomainEventRTCChangeCallback': "No function types in python",
|
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-19 03:07:48 +08:00
|
|
|
'virConnectDomainEventWatchdogCallback': "No function types in python",
|
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-19 03:37:44 +08:00
|
|
|
'virConnectDomainEventIOErrorCallback': "No function types in python",
|
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<REMOTE_DOMAIN_EVENT_GRAPHICS_IDENTITY_MAX>;
};
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-19 21:27:45 +08:00
|
|
|
'virConnectDomainEventGraphicsCallback': "No function types in python",
|
2008-10-31 18:13:45 +08:00
|
|
|
'virEventAddHandleFunc': "No function types in python",
|
2005-12-20 00:34:11 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
#######################################################################
|
|
|
|
#
|
|
|
|
# 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"),
|
2006-08-04 21:36:07 +08:00
|
|
|
'long': ('l', None, "long", "long"),
|
2005-12-20 00:34:11 +08:00
|
|
|
'double': ('d', None, "double", "double"),
|
|
|
|
'unsigned int': ('i', None, "int", "int"),
|
2006-08-04 21:36:07 +08:00
|
|
|
'unsigned long': ('l', None, "long", "long"),
|
2008-01-21 23:41:15 +08:00
|
|
|
'unsigned long long': ('l', None, "longlong", "long long"),
|
2005-12-20 00:34:11 +08:00
|
|
|
'unsigned char *': ('z', None, "charPtr", "char *"),
|
|
|
|
'char *': ('z', None, "charPtr", "char *"),
|
|
|
|
'const char *': ('z', None, "charPtrConst", "const char *"),
|
2008-02-20 23:26:22 +08:00
|
|
|
|
2005-12-20 00:34:11 +08:00
|
|
|
'virDomainPtr': ('O', "virDomain", "virDomainPtr", "virDomainPtr"),
|
|
|
|
'const virDomainPtr': ('O', "virDomain", "virDomainPtr", "virDomainPtr"),
|
|
|
|
'virDomain *': ('O', "virDomain", "virDomainPtr", "virDomainPtr"),
|
|
|
|
'const virDomain *': ('O', "virDomain", "virDomainPtr", "virDomainPtr"),
|
2008-02-20 23:26:22 +08:00
|
|
|
|
2007-03-09 23:42:50 +08:00
|
|
|
'virNetworkPtr': ('O', "virNetwork", "virNetworkPtr", "virNetworkPtr"),
|
|
|
|
'const virNetworkPtr': ('O', "virNetwork", "virNetworkPtr", "virNetworkPtr"),
|
|
|
|
'virNetwork *': ('O', "virNetwork", "virNetworkPtr", "virNetworkPtr"),
|
|
|
|
'const virNetwork *': ('O', "virNetwork", "virNetworkPtr", "virNetworkPtr"),
|
2008-02-20 23:26:22 +08:00
|
|
|
|
2009-05-21 18:57:05 +08:00
|
|
|
'virInterfacePtr': ('O', "virInterface", "virInterfacePtr", "virInterfacePtr"),
|
|
|
|
'const virInterfacePtr': ('O', "virInterface", "virInterfacePtr", "virInterfacePtr"),
|
|
|
|
'virInterface *': ('O', "virInterface", "virInterfacePtr", "virInterfacePtr"),
|
|
|
|
'const virInterface *': ('O', "virInterface", "virInterfacePtr", "virInterfacePtr"),
|
|
|
|
|
2008-02-20 23:26:22 +08:00
|
|
|
'virStoragePoolPtr': ('O', "virStoragePool", "virStoragePoolPtr", "virStoragePoolPtr"),
|
|
|
|
'const virStoragePoolPtr': ('O', "virStoragePool", "virStoragePoolPtr", "virStoragePoolPtr"),
|
|
|
|
'virStoragePool *': ('O', "virStoragePool", "virStoragePoolPtr", "virStoragePoolPtr"),
|
|
|
|
'const virStoragePool *': ('O', "virStoragePool", "virStoragePoolPtr", "virStoragePoolPtr"),
|
|
|
|
|
|
|
|
'virStorageVolPtr': ('O', "virStorageVol", "virStorageVolPtr", "virStorageVolPtr"),
|
|
|
|
'const virStorageVolPtr': ('O', "virStorageVol", "virStorageVolPtr", "virStorageVolPtr"),
|
|
|
|
'virStorageVol *': ('O', "virStorageVol", "virStorageVolPtr", "virStorageVolPtr"),
|
|
|
|
'const virStorageVol *': ('O', "virStorageVol", "virStorageVolPtr", "virStorageVolPtr"),
|
|
|
|
|
2005-12-20 00:34:11 +08:00
|
|
|
'virConnectPtr': ('O', "virConnect", "virConnectPtr", "virConnectPtr"),
|
|
|
|
'const virConnectPtr': ('O', "virConnect", "virConnectPtr", "virConnectPtr"),
|
|
|
|
'virConnect *': ('O', "virConnect", "virConnectPtr", "virConnectPtr"),
|
|
|
|
'const virConnect *': ('O', "virConnect", "virConnectPtr", "virConnectPtr"),
|
2008-11-21 20:41:15 +08:00
|
|
|
|
|
|
|
'virNodeDevicePtr': ('O', "virNodeDevice", "virNodeDevicePtr", "virNodeDevicePtr"),
|
|
|
|
'const virNodeDevicePtr': ('O', "virNodeDevice", "virNodeDevicePtr", "virNodeDevicePtr"),
|
|
|
|
'virNodeDevice *': ('O', "virNodeDevice", "virNodeDevicePtr", "virNodeDevicePtr"),
|
|
|
|
'const virNodeDevice *': ('O', "virNodeDevice", "virNodeDevicePtr", "virNodeDevicePtr"),
|
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("<secret ephemeral='no' private='no'>\n<description>Something for use</description>\n<volume>/foo/bar</volume>\n</secret>\n")
>>> s.UUIDString()
'340c2dfb-811b-eda8-da9e-25ccd7bfd650'
>>> s.XMLDesc()
"<secret ephemeral='no' private='no'>\n <uuid>340c2dfb-811b-eda8-da9e-25ccd7bfd650</uuid>\n <description>Something for use</description>\n <volume>/foo/bar</volume>\n</secret>\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-08-05 02:38:21 +08:00
|
|
|
|
|
|
|
'virSecretPtr': ('O', "virSecret", "virSecretPtr", "virSecretPtr"),
|
|
|
|
'const virSecretPtr': ('O', "virSecret", "virSecretPtr", "virSecretPtr"),
|
|
|
|
'virSecret *': ('O', "virSecret", "virSecretPtr", "virSecretPtr"),
|
|
|
|
'const virSecret *': ('O', "virSecret", "virSecretPtr", "virSecretPtr"),
|
2009-07-10 19:18:12 +08:00
|
|
|
|
2010-04-29 18:46:01 +08:00
|
|
|
'virNWFilterPtr': ('O', "virNWFilter", "virNWFilterPtr", "virNWFilterPtr"),
|
|
|
|
'const virNWFilterPtr': ('O', "virNWFilter", "virNWFilterPtr", "virNWFilterPtr"),
|
|
|
|
'virNWFilter *': ('O', "virNWFilter", "virNWFilterPtr", "virNWFilterPtr"),
|
|
|
|
'const virNWFilter *': ('O', "virNWFilter", "virNWFilterPtr", "virNWFilterPtr"),
|
|
|
|
|
2009-07-10 19:18:12 +08:00
|
|
|
'virStreamPtr': ('O', "virStream", "virStreamPtr", "virStreamPtr"),
|
|
|
|
'const virStreamPtr': ('O', "virStream", "virStreamPtr", "virStreamPtr"),
|
|
|
|
'virStream *': ('O', "virStream", "virStreamPtr", "virStreamPtr"),
|
|
|
|
'const virStream *': ('O', "virStream", "virStreamPtr", "virStreamPtr"),
|
2010-04-01 04:33:13 +08:00
|
|
|
|
|
|
|
'virDomainSnapshotPtr': ('O', "virDomainSnapshot", "virDomainSnapshotPtr", "virDomainSnapshotPtr"),
|
2010-04-20 17:49:27 +08:00
|
|
|
'const virDomainSnapshotPtr': ('O', "virDomainSnapshot", "virDomainSnapshotPtr", "virDomainSnapshotPtr"),
|
|
|
|
'virDomainSnapshot *': ('O', "virDomainSnapshot", "virDomainSnapshotPtr", "virDomainSnapshotPtr"),
|
|
|
|
'const virDomainSnapshot *': ('O', "virDomainSnapshot", "virDomainSnapshotPtr", "virDomainSnapshotPtr"),
|
2005-12-20 00:34:11 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
py_return_types = {
|
|
|
|
}
|
|
|
|
|
|
|
|
unknown_types = {}
|
|
|
|
|
|
|
|
foreign_encoding_args = (
|
|
|
|
)
|
|
|
|
|
|
|
|
#######################################################################
|
|
|
|
#
|
2009-09-16 21:03:53 +08:00
|
|
|
# This part writes the C <-> Python stubs libvirt.[ch] and
|
|
|
|
# the table libvirt-export.c to add when registrering the Python module
|
2005-12-20 00:34:11 +08:00
|
|
|
#
|
|
|
|
#######################################################################
|
|
|
|
|
|
|
|
# Class methods which are written by hand in libvir.c but the Python-level
|
|
|
|
# code is still automatically generated (so they are not in skip_function()).
|
|
|
|
skip_impl = (
|
2010-01-22 18:01:09 +08:00
|
|
|
'virConnectGetVersion',
|
2009-11-12 23:53:26 +08:00
|
|
|
'virConnectGetLibVersion',
|
2006-01-31 18:24:12 +08:00
|
|
|
'virConnectListDomainsID',
|
2006-11-16 08:17:10 +08:00
|
|
|
'virConnectListDefinedDomains',
|
2007-03-09 23:42:50 +08:00
|
|
|
'virConnectListNetworks',
|
|
|
|
'virConnectListDefinedNetworks',
|
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("<secret ephemeral='no' private='no'>\n<description>Something for use</description>\n<volume>/foo/bar</volume>\n</secret>\n")
>>> s.UUIDString()
'340c2dfb-811b-eda8-da9e-25ccd7bfd650'
>>> s.XMLDesc()
"<secret ephemeral='no' private='no'>\n <uuid>340c2dfb-811b-eda8-da9e-25ccd7bfd650</uuid>\n <description>Something for use</description>\n <volume>/foo/bar</volume>\n</secret>\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-08-05 02:38:21 +08:00
|
|
|
'virConnectListSecrets',
|
2009-11-20 23:22:42 +08:00
|
|
|
'virConnectListInterfaces',
|
2008-02-20 23:26:22 +08:00
|
|
|
'virConnectListStoragePools',
|
|
|
|
'virConnectListDefinedStoragePools',
|
|
|
|
'virConnectListStorageVols',
|
|
|
|
'virConnectListDefinedStorageVols',
|
2009-11-20 23:22:42 +08:00
|
|
|
'virConnectListDefinedInterfaces',
|
2010-03-26 01:46:09 +08:00
|
|
|
'virConnectListNWFilters',
|
2010-04-20 17:49:27 +08:00
|
|
|
'virDomainSnapshotListNames',
|
2006-11-08 07:18:56 +08:00
|
|
|
'virConnGetLastError',
|
|
|
|
'virGetLastError',
|
2006-01-31 18:24:12 +08:00
|
|
|
'virDomainGetInfo',
|
2010-04-28 20:42:13 +08:00
|
|
|
'virDomainGetBlockInfo',
|
2010-02-03 19:31:45 +08:00
|
|
|
'virDomainGetJobInfo',
|
2006-03-29 20:46:03 +08:00
|
|
|
'virNodeGetInfo',
|
2006-02-23 19:26:17 +08:00
|
|
|
'virDomainGetUUID',
|
2008-06-10 23:20:25 +08:00
|
|
|
'virDomainGetUUIDString',
|
2006-02-24 20:26:56 +08:00
|
|
|
'virDomainLookupByUUID',
|
2007-03-09 23:42:50 +08:00
|
|
|
'virNetworkGetUUID',
|
2008-06-10 23:20:25 +08:00
|
|
|
'virNetworkGetUUIDString',
|
2007-03-09 23:42:50 +08:00
|
|
|
'virNetworkLookupByUUID',
|
2008-01-21 23:55:53 +08:00
|
|
|
'virDomainGetAutostart',
|
|
|
|
'virNetworkGetAutostart',
|
2007-10-01 04:52:13 +08:00
|
|
|
'virDomainBlockStats',
|
|
|
|
'virDomainInterfaceStats',
|
2009-12-20 20:48:37 +08:00
|
|
|
'virDomainMemoryStats',
|
2007-12-07 16:41:01 +08:00
|
|
|
'virNodeGetCellsFreeMemory',
|
2008-01-21 23:41:15 +08:00
|
|
|
'virDomainGetSchedulerType',
|
|
|
|
'virDomainGetSchedulerParameters',
|
|
|
|
'virDomainSetSchedulerParameters',
|
2011-02-22 13:30:33 +08:00
|
|
|
'virDomainSetBlkioParameters',
|
|
|
|
'virDomainGetBlkioParameters',
|
2010-10-12 21:43:27 +08:00
|
|
|
'virDomainSetMemoryParameters',
|
|
|
|
'virDomainGetMemoryParameters',
|
2008-01-21 23:41:15 +08:00
|
|
|
'virDomainGetVcpus',
|
|
|
|
'virDomainPinVcpu',
|
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("<secret ephemeral='no' private='no'>\n<description>Something for use</description>\n<volume>/foo/bar</volume>\n</secret>\n")
>>> s.UUIDString()
'340c2dfb-811b-eda8-da9e-25ccd7bfd650'
>>> s.XMLDesc()
"<secret ephemeral='no' private='no'>\n <uuid>340c2dfb-811b-eda8-da9e-25ccd7bfd650</uuid>\n <description>Something for use</description>\n <volume>/foo/bar</volume>\n</secret>\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-08-05 02:38:21 +08:00
|
|
|
'virSecretGetValue',
|
|
|
|
'virSecretSetValue',
|
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-11 00:44:12 +08:00
|
|
|
'virSecretGetUUID',
|
|
|
|
'virSecretGetUUIDString',
|
|
|
|
'virSecretLookupByUUID',
|
2010-04-29 18:46:01 +08:00
|
|
|
'virNWFilterGetUUID',
|
|
|
|
'virNWFilterGetUUIDString',
|
|
|
|
'virNWFilterLookupByUUID',
|
2009-07-10 19:18:12 +08:00
|
|
|
'virStreamRecv',
|
|
|
|
'virStreamSend',
|
2008-02-20 23:26:22 +08:00
|
|
|
'virStoragePoolGetUUID',
|
2008-06-10 23:20:25 +08:00
|
|
|
'virStoragePoolGetUUIDString',
|
2008-02-20 23:26:22 +08:00
|
|
|
'virStoragePoolLookupByUUID',
|
|
|
|
'virStoragePoolGetInfo',
|
|
|
|
'virStorageVolGetInfo',
|
|
|
|
'virStoragePoolGetAutostart',
|
|
|
|
'virStoragePoolListVolumes',
|
2008-07-25 20:37:06 +08:00
|
|
|
'virDomainBlockPeek',
|
|
|
|
'virDomainMemoryPeek',
|
2008-10-31 18:13:45 +08:00
|
|
|
'virEventRegisterImpl',
|
2008-11-21 20:41:15 +08:00
|
|
|
'virNodeListDevices',
|
|
|
|
'virNodeDeviceListCaps',
|
2010-01-22 21:52:41 +08:00
|
|
|
'virConnectBaselineCPU',
|
2010-05-19 21:02:30 +08:00
|
|
|
'virDomainRevertToSnapshot',
|
2005-12-20 00:34:11 +08:00
|
|
|
)
|
|
|
|
|
2008-01-21 23:55:53 +08:00
|
|
|
|
|
|
|
# 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
|
2009-03-03 17:14:28 +08:00
|
|
|
'virDomainGetSecurityLabel', # Needs investigation...
|
|
|
|
'virNodeGetSecurityModel', # Needs investigation...
|
2008-10-31 18:13:45 +08:00
|
|
|
'virConnectDomainEventRegister', # overridden in virConnect.py
|
|
|
|
'virConnectDomainEventDeregister', # overridden in virConnect.py
|
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-18 21:01:48 +08:00
|
|
|
'virConnectDomainEventRegisterAny', # overridden in virConnect.py
|
|
|
|
'virConnectDomainEventDeregisterAny', # overridden in virConnect.py
|
2009-02-17 06:44:49 +08:00
|
|
|
'virSaveLastError', # We have our own python error wrapper
|
|
|
|
'virFreeError', # Only needed if we use virSaveLastError
|
2009-07-10 19:18:12 +08:00
|
|
|
'virStreamEventAddCallback',
|
|
|
|
'virStreamRecvAll',
|
|
|
|
'virStreamSendAll',
|
|
|
|
'virStreamRef',
|
|
|
|
'virStreamFree',
|
2009-09-24 00:17:03 +08:00
|
|
|
|
|
|
|
# These have no use for bindings users.
|
|
|
|
"virConnectRef",
|
|
|
|
"virDomainRef",
|
|
|
|
"virInterfaceRef",
|
|
|
|
"virNetworkRef",
|
|
|
|
"virNodeDeviceRef",
|
|
|
|
"virSecretRef",
|
2010-04-29 18:46:01 +08:00
|
|
|
"virNWFilterRef",
|
2009-09-24 00:17:03 +08:00
|
|
|
"virStoragePoolRef",
|
|
|
|
"virStorageVolRef",
|
2009-09-24 00:38:47 +08:00
|
|
|
|
|
|
|
# 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",
|
2010-04-29 18:46:01 +08:00
|
|
|
"virNWFilterGetConnect",
|
2009-09-24 00:38:47 +08:00
|
|
|
"virStoragePoolGetConnect",
|
|
|
|
"virStorageVolGetConnect",
|
2008-01-21 23:55:53 +08:00
|
|
|
)
|
|
|
|
|
2010-05-19 21:02:30 +08:00
|
|
|
function_skip_index_one = (
|
|
|
|
"virDomainRevertToSnapshot",
|
|
|
|
)
|
|
|
|
|
2005-12-20 00:34:11 +08:00
|
|
|
|
|
|
|
def print_function_wrapper(name, output, export, include):
|
|
|
|
global py_types
|
|
|
|
global unknown_types
|
|
|
|
global functions
|
|
|
|
global skipped_modules
|
|
|
|
|
|
|
|
try:
|
|
|
|
(desc, ret, args, file, cond) = functions[name]
|
|
|
|
except:
|
|
|
|
print "failed to get function %s infos"
|
|
|
|
return
|
|
|
|
|
|
|
|
if skipped_modules.has_key(file):
|
|
|
|
return 0
|
2008-01-21 23:55:53 +08:00
|
|
|
if name in skip_function:
|
2005-12-20 00:34:11 +08:00
|
|
|
return 0
|
|
|
|
if name in skip_impl:
|
2011-02-16 23:57:50 +08:00
|
|
|
# Don't delete the function entry in the caller.
|
|
|
|
return 1
|
2005-12-20 00:34:11 +08:00
|
|
|
|
|
|
|
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 py_types.has_key(arg[1]):
|
|
|
|
(f, t, n, c) = py_types[arg[1]]
|
2011-02-16 23:57:50 +08:00
|
|
|
if (f == 'z') and (name in foreign_encoding_args) and (num_bufs == 0):
|
|
|
|
f = 't#'
|
2005-12-20 00:34:11 +08:00
|
|
|
if f != None:
|
|
|
|
format = format + f
|
|
|
|
if t != 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])
|
2011-02-16 23:57:50 +08:00
|
|
|
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
|
2005-12-20 00:34:11 +08:00
|
|
|
if c_call != "":
|
|
|
|
c_call = c_call + ", ";
|
|
|
|
c_call = c_call + "%s" % (arg[0])
|
|
|
|
else:
|
|
|
|
if skipped_types.has_key(arg[1]):
|
|
|
|
return 0
|
|
|
|
if unknown_types.has_key(arg[1]):
|
|
|
|
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":
|
2011-02-16 23:57:50 +08:00
|
|
|
if args[1][1] == "char *":
|
|
|
|
c_call = "\n 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])
|
2005-12-20 00:34:11 +08:00
|
|
|
else:
|
|
|
|
c_call = "\n %s(%s);\n" % (name, c_call);
|
|
|
|
ret_convert = " Py_INCREF(Py_None);\n return(Py_None);\n"
|
|
|
|
elif py_types.has_key(ret[0]):
|
|
|
|
(f, t, n, c) = py_types[ret[0]]
|
|
|
|
c_return = " %s c_retval;\n" % (ret[0])
|
|
|
|
if file == "python_accessor" and ret[2] != 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);
|
2006-02-10 01:45:11 +08:00
|
|
|
ret_convert = " py_retval = libvirt_%sWrap((%s) c_retval);\n" % (n,c)
|
2005-12-20 00:34:11 +08:00
|
|
|
ret_convert = ret_convert + " return(py_retval);\n"
|
|
|
|
elif py_return_types.has_key(ret[0]):
|
|
|
|
(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);
|
2006-02-10 01:45:11 +08:00
|
|
|
ret_convert = " py_retval = libvirt_%sWrap((%s) c_retval);\n" % (n,c)
|
2005-12-20 00:34:11 +08:00
|
|
|
ret_convert = ret_convert + " return(py_retval);\n"
|
|
|
|
else:
|
|
|
|
if skipped_types.has_key(ret[0]):
|
|
|
|
return 0
|
|
|
|
if unknown_types.has_key(ret[0]):
|
|
|
|
lst = unknown_types[ret[0]]
|
|
|
|
lst.append(name)
|
|
|
|
else:
|
|
|
|
unknown_types[ret[0]] = [name]
|
|
|
|
return -1
|
|
|
|
|
|
|
|
if cond != None and cond != "":
|
|
|
|
include.write("#if %s\n" % cond)
|
|
|
|
export.write("#if %s\n" % cond)
|
|
|
|
output.write("#if %s\n" % cond)
|
|
|
|
|
|
|
|
include.write("PyObject * ")
|
2006-02-10 01:45:11 +08:00
|
|
|
include.write("libvirt_%s(PyObject *self, PyObject *args);\n" % (name));
|
2005-12-20 00:34:11 +08:00
|
|
|
|
2006-02-10 01:45:11 +08:00
|
|
|
export.write(" { (char *)\"%s\", libvirt_%s, METH_VARARGS, NULL },\n" %
|
2005-12-20 00:34:11 +08:00
|
|
|
(name, name))
|
|
|
|
|
|
|
|
if file == "python":
|
|
|
|
# Those have been manually generated
|
2011-02-16 23:57:50 +08:00
|
|
|
if cond != None and cond != "":
|
|
|
|
include.write("#endif\n");
|
|
|
|
export.write("#endif\n");
|
|
|
|
output.write("#endif\n");
|
2005-12-20 00:34:11 +08:00
|
|
|
return 1
|
|
|
|
if file == "python_accessor" and ret[0] != "void" and ret[2] is None:
|
|
|
|
# Those have been manually generated
|
2011-02-16 23:57:50 +08:00
|
|
|
if cond != None and cond != "":
|
|
|
|
include.write("#endif\n");
|
|
|
|
export.write("#endif\n");
|
|
|
|
output.write("#endif\n");
|
2005-12-20 00:34:11 +08:00
|
|
|
return 1
|
|
|
|
|
|
|
|
output.write("PyObject *\n")
|
2006-02-10 01:45:11 +08:00
|
|
|
output.write("libvirt_%s(PyObject *self ATTRIBUTE_UNUSED," % (name))
|
2005-12-20 00:34:11 +08:00
|
|
|
output.write(" PyObject *args")
|
|
|
|
if format == "":
|
2011-02-16 23:57:50 +08:00
|
|
|
output.write(" ATTRIBUTE_UNUSED")
|
2005-12-20 00:34:11 +08:00
|
|
|
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)
|
2006-10-25 04:28:16 +08:00
|
|
|
|
|
|
|
output.write("LIBVIRT_BEGIN_ALLOW_THREADS;\n");
|
|
|
|
output.write(c_call);
|
|
|
|
output.write("LIBVIRT_END_ALLOW_THREADS;\n");
|
2005-12-20 00:34:11 +08:00
|
|
|
output.write(ret_convert)
|
|
|
|
output.write("}\n\n")
|
|
|
|
if cond != None and cond != "":
|
|
|
|
include.write("#endif /* %s */\n" % cond)
|
|
|
|
export.write("#endif /* %s */\n" % cond)
|
|
|
|
output.write("#endif /* %s */\n" % cond)
|
|
|
|
return 1
|
|
|
|
|
|
|
|
def buildStubs():
|
|
|
|
global py_types
|
|
|
|
global py_return_types
|
|
|
|
global unknown_types
|
|
|
|
|
|
|
|
try:
|
2011-02-16 23:57:50 +08:00
|
|
|
f = open(os.path.join(srcPref,"libvirt-api.xml"))
|
|
|
|
data = f.read()
|
|
|
|
(parser, target) = getparser()
|
|
|
|
parser.feed(data)
|
|
|
|
parser.close()
|
2005-12-20 00:34:11 +08:00
|
|
|
except IOError, msg:
|
2011-02-16 23:57:50 +08:00
|
|
|
try:
|
|
|
|
f = open(os.path.join(srcPref,"..","docs","libvirt-api.xml"))
|
|
|
|
data = f.read()
|
|
|
|
(parser, target) = getparser()
|
|
|
|
parser.feed(data)
|
|
|
|
parser.close()
|
|
|
|
except IOError, msg:
|
|
|
|
print file, ":", msg
|
|
|
|
sys.exit(1)
|
2005-12-20 00:34:11 +08:00
|
|
|
|
|
|
|
n = len(functions.keys())
|
2006-02-10 01:45:11 +08:00
|
|
|
print "Found %d functions in libvirt-api.xml" % (n)
|
2005-12-20 00:34:11 +08:00
|
|
|
|
|
|
|
py_types['pythonObject'] = ('O', "pythonObject", "pythonObject", "pythonObject")
|
|
|
|
try:
|
2011-02-16 23:57:50 +08:00
|
|
|
f = open(os.path.join(srcPref,"libvirt-override-api.xml"))
|
|
|
|
data = f.read()
|
|
|
|
(parser, target) = getparser()
|
|
|
|
parser.feed(data)
|
|
|
|
parser.close()
|
2005-12-20 00:34:11 +08:00
|
|
|
except IOError, msg:
|
2011-02-16 23:57:50 +08:00
|
|
|
print file, ":", msg
|
2005-12-20 00:34:11 +08:00
|
|
|
|
|
|
|
|
2009-09-16 21:03:53 +08:00
|
|
|
print "Found %d functions in libvirt-override-api.xml" % (
|
2011-02-16 23:57:50 +08:00
|
|
|
len(functions.keys()) - n)
|
2005-12-20 00:34:11 +08:00
|
|
|
nb_wrap = 0
|
|
|
|
failed = 0
|
|
|
|
skipped = 0
|
|
|
|
|
2009-09-16 21:03:53 +08:00
|
|
|
include = open("libvirt.h", "w")
|
2005-12-20 00:34:11 +08:00
|
|
|
include.write("/* Generated */\n\n")
|
2006-02-10 01:45:11 +08:00
|
|
|
export = open("libvirt-export.c", "w")
|
2005-12-20 00:34:11 +08:00
|
|
|
export.write("/* Generated */\n\n")
|
2009-09-16 21:03:53 +08:00
|
|
|
wrapper = open("libvirt.c", "w")
|
2005-12-20 00:34:11 +08:00
|
|
|
wrapper.write("/* Generated */\n\n")
|
|
|
|
wrapper.write("#include <Python.h>\n")
|
2006-06-26 23:02:18 +08:00
|
|
|
wrapper.write("#include <libvirt/libvirt.h>\n")
|
2009-09-16 21:03:53 +08:00
|
|
|
wrapper.write("#include \"typewrappers.h\"\n")
|
|
|
|
wrapper.write("#include \"libvirt.h\"\n\n")
|
2005-12-20 00:34:11 +08:00
|
|
|
for function in functions.keys():
|
2011-02-16 23:57:50 +08:00
|
|
|
ret = print_function_wrapper(function, wrapper, export, include)
|
|
|
|
if ret < 0:
|
|
|
|
failed = failed + 1
|
|
|
|
functions_failed.append(function)
|
|
|
|
del functions[function]
|
|
|
|
if ret == 0:
|
|
|
|
skipped = skipped + 1
|
|
|
|
functions_skipped.append(function)
|
|
|
|
del functions[function]
|
|
|
|
if ret == 1:
|
|
|
|
nb_wrap = nb_wrap + 1
|
2005-12-20 00:34:11 +08:00
|
|
|
include.close()
|
|
|
|
export.close()
|
|
|
|
wrapper.close()
|
|
|
|
|
2008-01-21 23:55:53 +08:00
|
|
|
print "Generated %d wrapper functions" % nb_wrap
|
|
|
|
|
2005-12-20 00:34:11 +08:00
|
|
|
print "Missing type converters: "
|
|
|
|
for type in unknown_types.keys():
|
2011-02-16 23:57:50 +08:00
|
|
|
print "%s:%d " % (type, len(unknown_types[type])),
|
2005-12-20 00:34:11 +08:00
|
|
|
print
|
|
|
|
|
2008-01-21 23:55:53 +08:00
|
|
|
for f in functions_failed:
|
|
|
|
print "ERROR: failed %s" % f
|
|
|
|
|
|
|
|
if failed > 0:
|
|
|
|
return -1
|
|
|
|
return 0
|
|
|
|
|
2005-12-20 00:34:11 +08:00
|
|
|
#######################################################################
|
|
|
|
#
|
|
|
|
# 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 = {
|
2007-04-16 20:37:59 +08:00
|
|
|
"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"),
|
2009-05-21 18:57:05 +08:00
|
|
|
"virInterfacePtr": ("._o", "virInterface(self, _obj=%s)", "virInterface"),
|
|
|
|
"virInterface *": ("._o", "virInterface(self, _obj=%s)", "virInterface"),
|
2008-02-20 23:26:22 +08:00
|
|
|
"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"),
|
2008-11-21 20:41:15 +08:00
|
|
|
"virNodeDevicePtr": ("._o", "virNodeDevice(self, _obj=%s)", "virNodeDevice"),
|
|
|
|
"virNodeDevice *": ("._o", "virNodeDevice(self, _obj=%s)", "virNodeDevice"),
|
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("<secret ephemeral='no' private='no'>\n<description>Something for use</description>\n<volume>/foo/bar</volume>\n</secret>\n")
>>> s.UUIDString()
'340c2dfb-811b-eda8-da9e-25ccd7bfd650'
>>> s.XMLDesc()
"<secret ephemeral='no' private='no'>\n <uuid>340c2dfb-811b-eda8-da9e-25ccd7bfd650</uuid>\n <description>Something for use</description>\n <volume>/foo/bar</volume>\n</secret>\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-08-05 02:38:21 +08:00
|
|
|
"virSecretPtr": ("._o", "virSecret(self, _obj=%s)", "virSecret"),
|
|
|
|
"virSecret *": ("._o", "virSecret(self, _obj=%s)", "virSecret"),
|
2010-04-29 18:46:01 +08:00
|
|
|
"virNWFilterPtr": ("._o", "virNWFilter(self, _obj=%s)", "virNWFilter"),
|
|
|
|
"virNWFilter *": ("._o", "virNWFilter(self, _obj=%s)", "virNWFilter"),
|
2009-07-10 19:18:12 +08:00
|
|
|
"virStreamPtr": ("._o", "virStream(self, _obj=%s)", "virStream"),
|
|
|
|
"virStream *": ("._o", "virStream(self, _obj=%s)", "virStream"),
|
2005-12-20 00:34:11 +08:00
|
|
|
"virConnectPtr": ("._o", "virConnect(_obj=%s)", "virConnect"),
|
|
|
|
"virConnect *": ("._o", "virConnect(_obj=%s)", "virConnect"),
|
2010-04-20 17:49:27 +08:00
|
|
|
"virDomainSnapshotPtr": ("._o", "virDomainSnapshot(self,_obj=%s)", "virDomainSnapshot"),
|
|
|
|
"virDomainSnapshot *": ("._o", "virDomainSnapshot(self, _obj=%s)", "virDomainSnapshot"),
|
2005-12-20 00:34:11 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
converter_type = {
|
|
|
|
}
|
|
|
|
|
2009-05-21 18:57:05 +08:00
|
|
|
primary_classes = ["virDomain", "virNetwork", "virInterface",
|
|
|
|
"virStoragePool", "virStorageVol",
|
2009-07-10 19:18:12 +08:00
|
|
|
"virConnect", "virNodeDevice", "virSecret",
|
2010-04-29 18:46:01 +08:00
|
|
|
"virNWFilter", "virStream", "virDomainSnapshot"]
|
2005-12-20 00:34:11 +08:00
|
|
|
|
|
|
|
classes_ancestor = {
|
|
|
|
}
|
|
|
|
classes_destructors = {
|
|
|
|
"virDomain": "virDomainFree",
|
2007-03-09 23:42:50 +08:00
|
|
|
"virNetwork": "virNetworkFree",
|
2009-05-21 18:57:05 +08:00
|
|
|
"virInterface": "virInterfaceFree",
|
2008-02-20 23:26:22 +08:00
|
|
|
"virStoragePool": "virStoragePoolFree",
|
|
|
|
"virStorageVol": "virStorageVolFree",
|
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("<secret ephemeral='no' private='no'>\n<description>Something for use</description>\n<volume>/foo/bar</volume>\n</secret>\n")
>>> s.UUIDString()
'340c2dfb-811b-eda8-da9e-25ccd7bfd650'
>>> s.XMLDesc()
"<secret ephemeral='no' private='no'>\n <uuid>340c2dfb-811b-eda8-da9e-25ccd7bfd650</uuid>\n <description>Something for use</description>\n <volume>/foo/bar</volume>\n</secret>\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-08-05 02:38:21 +08:00
|
|
|
"virNodeDevice" : "virNodeDeviceFree",
|
2009-07-10 19:18:12 +08:00
|
|
|
"virSecret": "virSecretFree",
|
2010-04-29 18:46:01 +08:00
|
|
|
"virNWFilter": "virNWFilterFree",
|
2010-04-20 17:49:27 +08:00
|
|
|
"virDomainSnapshot": "virDomainSnapshotFree",
|
2009-07-10 19:18:12 +08:00
|
|
|
# We hand-craft __del__ for this one
|
|
|
|
#"virStream": "virStreamFree",
|
2005-12-20 00:34:11 +08:00
|
|
|
}
|
|
|
|
|
2009-09-24 00:38:47 +08:00
|
|
|
class_skip_connect_impl = {
|
2010-05-19 21:02:30 +08:00
|
|
|
"virConnect" : True,
|
|
|
|
"virDomainSnapshot": True,
|
2009-09-24 00:38:47 +08:00
|
|
|
}
|
|
|
|
|
2010-05-19 21:02:30 +08:00
|
|
|
class_domain_impl = {
|
|
|
|
"virDomainSnapshot": True,
|
|
|
|
}
|
2009-09-24 00:38:47 +08:00
|
|
|
|
2005-12-20 00:34:11 +08:00
|
|
|
functions_noexcept = {
|
2007-03-28 19:24:14 +08:00
|
|
|
'virDomainGetID': True,
|
|
|
|
'virDomainGetName': True,
|
2008-02-20 23:26:22 +08:00
|
|
|
'virNetworkGetName': True,
|
2009-05-21 18:57:05 +08:00
|
|
|
'virInterfaceGetName': True,
|
2008-02-20 23:26:22 +08:00
|
|
|
'virStoragePoolGetName': True,
|
|
|
|
'virStorageVolGetName': True,
|
|
|
|
'virStorageVolGetkey': True,
|
2008-11-21 20:41:15 +08:00
|
|
|
'virNodeDeviceGetName': True,
|
|
|
|
'virNodeDeviceGetParent': True,
|
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-11 21:06:15 +08:00
|
|
|
'virSecretGetUsageType': True,
|
|
|
|
'virSecretGetUsageID': True,
|
2010-04-29 18:46:01 +08:00
|
|
|
'virNWFilterGetName': True,
|
2005-12-20 00:34:11 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
reference_keepers = {
|
|
|
|
}
|
|
|
|
|
|
|
|
function_classes = {}
|
|
|
|
|
|
|
|
function_classes["None"] = []
|
|
|
|
|
2008-05-22 04:18:20 +08:00
|
|
|
function_post = {}
|
2006-01-31 18:24:12 +08:00
|
|
|
|
2007-03-28 19:24:14 +08:00
|
|
|
# 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
|
|
|
|
|
|
|
|
# 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_list_type (name):
|
2009-07-24 23:05:27 +08:00
|
|
|
whitelist = [ "virDomainBlockStats",
|
|
|
|
"virDomainInterfaceStats" ]
|
|
|
|
|
|
|
|
return name[-1:] == "*" or name in whitelist
|
2007-03-28 19:24:14 +08:00
|
|
|
|
2005-12-20 00:34:11 +08:00
|
|
|
def nameFixup(name, classe, type, file):
|
2007-03-15 23:23:21 +08:00
|
|
|
# avoid a desastrous clash
|
2005-12-20 00:34:11 +08:00
|
|
|
listname = classe + "List"
|
|
|
|
ll = len(listname)
|
|
|
|
l = len(classe)
|
|
|
|
if name[0:l] == listname:
|
|
|
|
func = name[l:]
|
|
|
|
func = string.lower(func[0:1]) + func[1:]
|
2007-03-16 18:44:44 +08:00
|
|
|
elif name[0:16] == "virNetworkDefine":
|
|
|
|
func = name[3:]
|
|
|
|
func = string.lower(func[0:1]) + func[1:]
|
2009-04-01 18:37:57 +08:00
|
|
|
elif name[0:19] == "virNetworkCreateXML":
|
|
|
|
func = name[3:]
|
|
|
|
func = string.lower(func[0:1]) + func[1:]
|
2007-03-15 23:23:21 +08:00
|
|
|
elif name[0:16] == "virNetworkLookup":
|
2007-03-16 18:44:44 +08:00
|
|
|
func = name[3:]
|
|
|
|
func = string.lower(func[0:1]) + func[1:]
|
2009-05-21 18:57:05 +08:00
|
|
|
elif name[0:18] == "virInterfaceDefine":
|
|
|
|
func = name[3:]
|
|
|
|
func = string.lower(func[0:1]) + func[1:]
|
|
|
|
elif name[0:21] == "virInterfaceCreateXML":
|
|
|
|
func = name[3:]
|
|
|
|
func = string.lower(func[0:1]) + func[1:]
|
|
|
|
elif name[0:18] == "virInterfaceLookup":
|
|
|
|
func = name[3:]
|
|
|
|
func = string.lower(func[0:1]) + func[1:]
|
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("<secret ephemeral='no' private='no'>\n<description>Something for use</description>\n<volume>/foo/bar</volume>\n</secret>\n")
>>> s.UUIDString()
'340c2dfb-811b-eda8-da9e-25ccd7bfd650'
>>> s.XMLDesc()
"<secret ephemeral='no' private='no'>\n <uuid>340c2dfb-811b-eda8-da9e-25ccd7bfd650</uuid>\n <description>Something for use</description>\n <volume>/foo/bar</volume>\n</secret>\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-08-05 02:38:21 +08:00
|
|
|
elif name[0:15] == "virSecretDefine":
|
|
|
|
func = name[3:]
|
|
|
|
func = string.lower(func[0:1]) + func[1:]
|
|
|
|
elif name[0:15] == "virSecretLookup":
|
|
|
|
func = name[3:]
|
|
|
|
func = string.lower(func[0:1]) + func[1:]
|
2010-04-29 18:46:01 +08:00
|
|
|
elif name[0:17] == "virNWFilterDefine":
|
|
|
|
func = name[3:]
|
|
|
|
func = string.lower(func[0:3]) + func[3:]
|
|
|
|
elif name[0:17] == "virNWFilterLookup":
|
|
|
|
func = name[3:]
|
|
|
|
func = string.lower(func[0:3]) + func[3:]
|
2008-02-20 23:26:22 +08:00
|
|
|
elif name[0:20] == "virStoragePoolDefine":
|
|
|
|
func = name[3:]
|
|
|
|
func = string.lower(func[0:1]) + func[1:]
|
2009-04-01 18:37:57 +08:00
|
|
|
elif name[0:23] == "virStoragePoolCreateXML":
|
|
|
|
func = name[3:]
|
|
|
|
func = string.lower(func[0:1]) + func[1:]
|
2008-02-20 23:26:22 +08:00
|
|
|
elif name[0:20] == "virStoragePoolLookup":
|
|
|
|
func = name[3:]
|
|
|
|
func = string.lower(func[0:1]) + func[1:]
|
|
|
|
elif name[0:19] == "virStorageVolDefine":
|
|
|
|
func = name[3:]
|
|
|
|
func = string.lower(func[0:1]) + func[1:]
|
|
|
|
elif name[0:19] == "virStorageVolLookup":
|
|
|
|
func = name[3:]
|
|
|
|
func = string.lower(func[0:1]) + func[1:]
|
2005-12-20 00:34:11 +08:00
|
|
|
elif name[0:12] == "virDomainGet":
|
|
|
|
func = name[12:]
|
|
|
|
func = string.lower(func[0:1]) + func[1:]
|
2010-04-20 17:49:27 +08:00
|
|
|
elif name[0:29] == "virDomainSnapshotLookupByName":
|
|
|
|
func = name[9:]
|
|
|
|
func = string.lower(func[0:1]) + func[1:]
|
|
|
|
elif name[0:26] == "virDomainSnapshotListNames":
|
|
|
|
func = name[9:]
|
|
|
|
func = string.lower(func[0:1]) + func[1:]
|
|
|
|
elif name[0:20] == "virDomainSnapshotNum":
|
|
|
|
func = name[9:]
|
|
|
|
func = string.lower(func[0:1]) + func[1:]
|
|
|
|
elif name[0:26] == "virDomainSnapshotCreateXML":
|
|
|
|
func = name[9:]
|
|
|
|
func = string.lower(func[0:1]) + func[1:]
|
|
|
|
elif name[0:24] == "virDomainSnapshotCurrent":
|
|
|
|
func = name[9:]
|
|
|
|
func = string.lower(func[0:1]) + func[1:]
|
|
|
|
elif name[0:17] == "virDomainSnapshot":
|
|
|
|
func = name[17:]
|
|
|
|
func = string.lower(func[0:1]) + func[1:]
|
2005-12-20 00:34:11 +08:00
|
|
|
elif name[0:9] == "virDomain":
|
|
|
|
func = name[9:]
|
|
|
|
func = string.lower(func[0:1]) + func[1:]
|
2007-03-09 23:42:50 +08:00
|
|
|
elif name[0:13] == "virNetworkGet":
|
|
|
|
func = name[13:]
|
|
|
|
func = string.lower(func[0:1]) + func[1:]
|
|
|
|
elif name[0:10] == "virNetwork":
|
|
|
|
func = name[10:]
|
|
|
|
func = string.lower(func[0:1]) + func[1:]
|
2009-05-21 18:57:05 +08:00
|
|
|
elif name[0:15] == "virInterfaceGet":
|
2009-09-24 00:51:55 +08:00
|
|
|
func = name[15:]
|
2009-05-21 18:57:05 +08:00
|
|
|
func = string.lower(func[0:1]) + func[1:]
|
|
|
|
elif name[0:12] == "virInterface":
|
2009-09-24 00:51:55 +08:00
|
|
|
func = name[12:]
|
2009-05-21 18:57:05 +08:00
|
|
|
func = string.lower(func[0:1]) + func[1:]
|
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("<secret ephemeral='no' private='no'>\n<description>Something for use</description>\n<volume>/foo/bar</volume>\n</secret>\n")
>>> s.UUIDString()
'340c2dfb-811b-eda8-da9e-25ccd7bfd650'
>>> s.XMLDesc()
"<secret ephemeral='no' private='no'>\n <uuid>340c2dfb-811b-eda8-da9e-25ccd7bfd650</uuid>\n <description>Something for use</description>\n <volume>/foo/bar</volume>\n</secret>\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-08-05 02:38:21 +08:00
|
|
|
elif name[0:12] == 'virSecretGet':
|
|
|
|
func = name[12:]
|
|
|
|
func = string.lower(func[0:1]) + func[1:]
|
|
|
|
elif name[0:9] == 'virSecret':
|
|
|
|
func = name[9:]
|
|
|
|
func = string.lower(func[0:1]) + func[1:]
|
2010-04-29 18:46:01 +08:00
|
|
|
elif name[0:14] == 'virNWFilterGet':
|
|
|
|
func = name[14:]
|
|
|
|
func = string.lower(func[0:1]) + func[1:]
|
|
|
|
elif name[0:11] == 'virNWFilter':
|
|
|
|
func = name[11:]
|
|
|
|
func = string.lower(func[0:1]) + func[1:]
|
2009-07-10 19:18:12 +08:00
|
|
|
elif name[0:12] == 'virStreamNew':
|
|
|
|
func = "newStream"
|
|
|
|
elif name[0:9] == 'virStream':
|
|
|
|
func = name[9:]
|
|
|
|
func = string.lower(func[0:1]) + func[1:]
|
2008-02-20 23:26:22 +08:00
|
|
|
elif name[0:17] == "virStoragePoolGet":
|
|
|
|
func = name[17:]
|
|
|
|
func = string.lower(func[0:1]) + func[1:]
|
|
|
|
elif name[0:14] == "virStoragePool":
|
|
|
|
func = name[14:]
|
|
|
|
func = string.lower(func[0:1]) + func[1:]
|
|
|
|
elif name[0:16] == "virStorageVolGet":
|
|
|
|
func = name[16:]
|
|
|
|
func = string.lower(func[0:1]) + func[1:]
|
|
|
|
elif name[0:13] == "virStorageVol":
|
|
|
|
func = name[13:]
|
|
|
|
func = string.lower(func[0:1]) + func[1:]
|
2008-11-21 20:41:15 +08:00
|
|
|
elif name[0:13] == "virNodeDevice":
|
|
|
|
if name[13:16] == "Get":
|
|
|
|
func = string.lower(name[16]) + name[17:]
|
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)
Signed-off-by: Cole Robinson <crobinso@redhat.com>
2009-09-24 00:09:09 +08:00
|
|
|
elif name[13:19] == "Lookup" or name[13:19] == "Create":
|
2008-11-21 20:41:15 +08:00
|
|
|
func = string.lower(name[3]) + name[4:]
|
|
|
|
else:
|
|
|
|
func = string.lower(name[13]) + name[14:]
|
2006-03-29 20:46:03 +08:00
|
|
|
elif name[0:7] == "virNode":
|
|
|
|
func = name[7:]
|
|
|
|
func = string.lower(func[0:1]) + func[1:]
|
2005-12-20 00:34:11 +08:00
|
|
|
elif name[0:10] == "virConnect":
|
|
|
|
func = name[10:]
|
|
|
|
func = string.lower(func[0:1]) + func[1:]
|
|
|
|
elif name[0:3] == "xml":
|
|
|
|
func = name[3:]
|
|
|
|
func = string.lower(func[0:1]) + func[1:]
|
|
|
|
else:
|
|
|
|
func = name
|
2006-01-31 18:24:12 +08:00
|
|
|
if func == "iD":
|
|
|
|
func = "ID"
|
2006-02-23 19:26:17 +08:00
|
|
|
if func == "uUID":
|
|
|
|
func = "UUID"
|
2007-03-09 23:42:50 +08:00
|
|
|
if func == "uUIDString":
|
|
|
|
func = "UUIDString"
|
2006-01-31 18:24:12 +08:00
|
|
|
if func == "oSType":
|
|
|
|
func = "OSType"
|
|
|
|
if func == "xMLDesc":
|
|
|
|
func = "XMLDesc"
|
2009-09-24 00:51:55 +08:00
|
|
|
if func == "mACString":
|
|
|
|
func = "MACString"
|
|
|
|
|
2005-12-20 00:34:11 +08:00
|
|
|
return func
|
|
|
|
|
|
|
|
|
|
|
|
def functionCompare(info1, info2):
|
|
|
|
(index1, func1, name1, ret1, args1, file1) = info1
|
|
|
|
(index2, func2, name2, ret2, args2, file2) = info2
|
|
|
|
if file1 == file2:
|
|
|
|
if func1 < func2:
|
|
|
|
return -1
|
|
|
|
if func1 > func2:
|
|
|
|
return 1
|
|
|
|
if file1 == "python_accessor":
|
|
|
|
return -1
|
|
|
|
if file2 == "python_accessor":
|
|
|
|
return 1
|
|
|
|
if file1 < file2:
|
|
|
|
return -1
|
|
|
|
if file1 > file2:
|
|
|
|
return 1
|
|
|
|
return 0
|
|
|
|
|
|
|
|
def writeDoc(name, args, indent, output):
|
|
|
|
if functions[name][0] is None or functions[name][0] == "":
|
|
|
|
return
|
|
|
|
val = functions[name][0]
|
|
|
|
val = string.replace(val, "NULL", "None");
|
|
|
|
output.write(indent)
|
|
|
|
output.write('"""')
|
2009-09-25 20:24:40 +08:00
|
|
|
i = string.find(val, "\n")
|
|
|
|
while i >= 0:
|
|
|
|
str = val[0:i+1]
|
|
|
|
val = val[i+1:]
|
2005-12-20 00:34:11 +08:00
|
|
|
output.write(str)
|
2009-09-25 20:24:40 +08:00
|
|
|
i = string.find(val, "\n")
|
2005-12-20 00:34:11 +08:00
|
|
|
output.write(indent)
|
2009-09-25 20:24:40 +08:00
|
|
|
output.write(val)
|
2005-12-20 00:34:11 +08:00
|
|
|
output.write(' """\n')
|
|
|
|
|
|
|
|
def buildWrappers():
|
|
|
|
global ctypes
|
|
|
|
global py_types
|
|
|
|
global py_return_types
|
|
|
|
global unknown_types
|
|
|
|
global functions
|
|
|
|
global function_classes
|
|
|
|
global classes_type
|
|
|
|
global classes_list
|
|
|
|
global converter_type
|
|
|
|
global primary_classes
|
|
|
|
global converter_type
|
|
|
|
global classes_ancestor
|
|
|
|
global converter_type
|
|
|
|
global primary_classes
|
|
|
|
global classes_ancestor
|
|
|
|
global classes_destructors
|
|
|
|
global functions_noexcept
|
|
|
|
|
|
|
|
for type in classes_type.keys():
|
2011-02-16 23:57:50 +08:00
|
|
|
function_classes[classes_type[type][2]] = []
|
2005-12-20 00:34:11 +08:00
|
|
|
|
|
|
|
#
|
|
|
|
# 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:
|
2011-02-16 23:57:50 +08:00
|
|
|
classes_list.append(classe)
|
|
|
|
classes_processed[classe] = ()
|
|
|
|
for type in classes_type.keys():
|
|
|
|
tinfo = classes_type[type]
|
|
|
|
if tinfo[2] == classe:
|
|
|
|
ctypes.append(type)
|
|
|
|
ctypes_processed[type] = ()
|
2005-12-20 00:34:11 +08:00
|
|
|
for type in classes_type.keys():
|
2011-02-16 23:57:50 +08:00
|
|
|
if ctypes_processed.has_key(type):
|
|
|
|
continue
|
|
|
|
tinfo = classes_type[type]
|
|
|
|
if not classes_processed.has_key(tinfo[2]):
|
|
|
|
classes_list.append(tinfo[2])
|
|
|
|
classes_processed[tinfo[2]] = ()
|
2008-02-06 03:27:37 +08:00
|
|
|
|
2011-02-16 23:57:50 +08:00
|
|
|
ctypes.append(type)
|
|
|
|
ctypes_processed[type] = ()
|
2005-12-20 00:34:11 +08:00
|
|
|
|
|
|
|
for name in functions.keys():
|
2011-02-16 23:57:50 +08:00
|
|
|
found = 0;
|
|
|
|
(desc, ret, args, file, 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)
|
|
|
|
function_classes[classe].append(info)
|
|
|
|
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)
|
|
|
|
function_classes[classe].append(info)
|
|
|
|
if found == 1:
|
|
|
|
continue
|
|
|
|
func = nameFixup(name, "None", file, file)
|
|
|
|
info = (0, func, name, ret, args, file)
|
|
|
|
function_classes['None'].append(info)
|
2008-02-06 03:27:37 +08:00
|
|
|
|
2009-09-16 21:03:53 +08:00
|
|
|
classes = open("libvirt.py", "w")
|
|
|
|
|
|
|
|
extra = open(os.path.join(srcPref,"libvirt-override.py"), "r")
|
2011-03-11 20:44:20 +08:00
|
|
|
classes.write("#! " + python + " -i\n")
|
2009-09-16 21:03:53 +08:00
|
|
|
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 libvirt-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")
|
|
|
|
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")
|
|
|
|
extra.close()
|
2005-12-20 00:34:11 +08:00
|
|
|
|
|
|
|
if function_classes.has_key("None"):
|
2011-02-16 23:57:50 +08:00
|
|
|
flist = function_classes["None"]
|
|
|
|
flist.sort(functionCompare)
|
|
|
|
oldfile = ""
|
|
|
|
for info in flist:
|
|
|
|
(index, func, name, ret, args, file) = 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])
|
|
|
|
n = n + 1
|
|
|
|
classes.write("):\n")
|
|
|
|
writeDoc(name, args, ' ', classes);
|
|
|
|
|
|
|
|
for arg in args:
|
|
|
|
if classes_type.has_key(arg[1]):
|
|
|
|
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 classes_type.has_key(arg[1]):
|
|
|
|
classes.write("__o");
|
|
|
|
n = n + 1
|
|
|
|
classes.write(")\n");
|
2007-03-28 19:24:14 +08:00
|
|
|
|
|
|
|
if ret[0] != "void":
|
2011-02-16 23:57:50 +08:00
|
|
|
if classes_type.has_key(ret[0]):
|
|
|
|
#
|
|
|
|
# Raise an exception
|
|
|
|
#
|
|
|
|
if functions_noexcept.has_key(name):
|
|
|
|
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");
|
2007-03-28 19:24:14 +08:00
|
|
|
|
|
|
|
# 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 not functions_noexcept.has_key (name):
|
|
|
|
if functions_int_exception_test.has_key (name):
|
|
|
|
test = functions_int_exception_test[name]
|
|
|
|
else:
|
|
|
|
test = functions_int_default_test
|
|
|
|
classes.write ((" if " + test +
|
|
|
|
": raise libvirtError ('%s() failed')\n") %
|
|
|
|
("ret", name))
|
2011-02-16 23:57:50 +08:00
|
|
|
classes.write(" return ret\n")
|
2007-03-28 19:24:14 +08:00
|
|
|
|
|
|
|
elif is_list_type (ret[0]):
|
|
|
|
if not functions_noexcept.has_key (name):
|
|
|
|
if functions_list_exception_test.has_key (name):
|
|
|
|
test = functions_list_exception_test[name]
|
|
|
|
else:
|
|
|
|
test = functions_list_default_test
|
|
|
|
classes.write ((" if " + test +
|
|
|
|
": raise libvirtError ('%s() failed')\n") %
|
|
|
|
("ret", name))
|
2011-02-16 23:57:50 +08:00
|
|
|
classes.write(" return ret\n")
|
2007-03-28 19:24:14 +08:00
|
|
|
|
2011-02-16 23:57:50 +08:00
|
|
|
else:
|
|
|
|
classes.write(" return ret\n")
|
2007-03-28 19:24:14 +08:00
|
|
|
|
2011-02-16 23:57:50 +08:00
|
|
|
classes.write("\n");
|
2005-12-20 00:34:11 +08:00
|
|
|
|
|
|
|
for classname in classes_list:
|
2011-02-16 23:57:50 +08:00
|
|
|
if classname == "None":
|
|
|
|
pass
|
|
|
|
else:
|
|
|
|
if classes_ancestor.has_key(classname):
|
|
|
|
classes.write("class %s(%s):\n" % (classname,
|
|
|
|
classes_ancestor[classname]))
|
|
|
|
classes.write(" def __init__(self, _obj=None):\n")
|
|
|
|
if reference_keepers.has_key(classname):
|
|
|
|
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:\n" % (classname))
|
2009-07-10 19:18:12 +08:00
|
|
|
if classname in [ "virDomain", "virNetwork", "virInterface", "virStoragePool",
|
2010-04-29 18:46:01 +08:00
|
|
|
"virStorageVol", "virNodeDevice", "virSecret","virStream",
|
|
|
|
"virNWFilter" ]:
|
2007-04-16 20:37:59 +08:00
|
|
|
classes.write(" def __init__(self, conn, _obj=None):\n")
|
2010-05-19 21:02:30 +08:00
|
|
|
elif classname in [ 'virDomainSnapshot' ]:
|
|
|
|
classes.write(" def __init__(self, dom, _obj=None):\n")
|
2007-04-16 20:37:59 +08:00
|
|
|
else:
|
|
|
|
classes.write(" def __init__(self, _obj=None):\n")
|
2011-02-16 23:57:50 +08:00
|
|
|
if reference_keepers.has_key(classname):
|
|
|
|
list = reference_keepers[classname]
|
|
|
|
for ref in list:
|
|
|
|
classes.write(" self.%s = None\n" % ref[1])
|
2009-07-10 19:18:12 +08:00
|
|
|
if classname in [ "virDomain", "virNetwork", "virInterface",
|
2010-04-29 18:46:01 +08:00
|
|
|
"virNodeDevice", "virSecret", "virStream",
|
|
|
|
"virNWFilter" ]:
|
2007-04-16 20:37:59 +08:00
|
|
|
classes.write(" self._conn = conn\n")
|
2008-08-12 16:11:09 +08:00
|
|
|
elif classname in [ "virStorageVol", "virStoragePool" ]:
|
|
|
|
classes.write(" self._conn = conn\n" + \
|
|
|
|
" if not isinstance(conn, virConnect):\n" + \
|
|
|
|
" self._conn = conn._conn\n")
|
2010-05-19 21:02:30 +08:00
|
|
|
elif classname in [ "virDomainSnapshot" ]:
|
|
|
|
classes.write(" self._dom = dom\n")
|
2011-02-16 23:57:50 +08:00
|
|
|
classes.write(" if _obj != None:self._o = _obj;return\n")
|
|
|
|
classes.write(" self._o = None\n\n");
|
|
|
|
destruct=None
|
|
|
|
if classes_destructors.has_key(classname):
|
|
|
|
classes.write(" def __del__(self):\n")
|
|
|
|
classes.write(" if self._o != None:\n")
|
|
|
|
classes.write(" libvirtmod.%s(self._o)\n" %
|
|
|
|
classes_destructors[classname]);
|
|
|
|
classes.write(" self._o = None\n\n");
|
|
|
|
destruct=classes_destructors[classname]
|
2009-09-24 00:38:47 +08:00
|
|
|
|
|
|
|
if not class_skip_connect_impl.has_key(classname):
|
|
|
|
# Build python safe 'connect' method
|
|
|
|
classes.write(" def connect(self):\n")
|
|
|
|
classes.write(" return self._conn\n\n")
|
|
|
|
|
2010-05-19 21:02:30 +08:00
|
|
|
if class_domain_impl.has_key(classname):
|
|
|
|
classes.write(" def domain(self):\n")
|
|
|
|
classes.write(" return self._dom\n\n")
|
|
|
|
|
2011-02-16 23:57:50 +08:00
|
|
|
flist = function_classes[classname]
|
|
|
|
flist.sort(functionCompare)
|
|
|
|
oldfile = ""
|
|
|
|
for info in flist:
|
|
|
|
(index, func, name, ret, args, file) = 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])
|
|
|
|
n = n + 1
|
|
|
|
classes.write("):\n")
|
|
|
|
writeDoc(name, args, ' ', classes);
|
|
|
|
n = 0
|
|
|
|
for arg in args:
|
|
|
|
if classes_type.has_key(arg[1]):
|
|
|
|
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(" ");
|
|
|
|
classes.write("libvirtmod.%s(" % name)
|
|
|
|
n = 0
|
|
|
|
for arg in args:
|
|
|
|
if n != 0:
|
|
|
|
classes.write(", ");
|
|
|
|
if n != index:
|
|
|
|
classes.write("%s" % arg[0])
|
|
|
|
if classes_type.has_key(arg[1]):
|
|
|
|
classes.write("__o");
|
|
|
|
else:
|
|
|
|
classes.write("self");
|
|
|
|
if classes_type.has_key(arg[1]):
|
|
|
|
classes.write(classes_type[arg[1]][0])
|
|
|
|
n = n + 1
|
|
|
|
classes.write(")\n");
|
2007-03-28 19:24:14 +08:00
|
|
|
|
2009-04-01 18:39:12 +08:00
|
|
|
if name == "virConnectClose":
|
|
|
|
classes.write(" self._o = None\n")
|
|
|
|
|
2007-03-28 19:24:14 +08:00
|
|
|
# For functions returning object types:
|
|
|
|
if ret[0] != "void":
|
2011-02-16 23:57:50 +08:00
|
|
|
if classes_type.has_key(ret[0]):
|
|
|
|
#
|
|
|
|
# Raise an exception
|
|
|
|
#
|
|
|
|
if functions_noexcept.has_key(name):
|
|
|
|
classes.write(
|
|
|
|
" if ret is None:return None\n");
|
|
|
|
else:
|
2006-11-08 07:18:56 +08:00
|
|
|
if classname == "virConnect":
|
|
|
|
classes.write(
|
2011-02-16 23:57:50 +08:00
|
|
|
" if ret is None:raise libvirtError('%s() failed', conn=self)\n" %
|
2006-11-08 07:18:56 +08:00
|
|
|
(name))
|
2007-04-16 20:37:59 +08:00
|
|
|
elif classname == "virDomain":
|
|
|
|
classes.write(
|
2011-02-16 23:57:50 +08:00
|
|
|
" if ret is None:raise libvirtError('%s() failed', dom=self)\n" %
|
2007-04-16 20:37:59 +08:00
|
|
|
(name))
|
|
|
|
elif classname == "virNetwork":
|
|
|
|
classes.write(
|
2011-02-16 23:57:50 +08:00
|
|
|
" if ret is None:raise libvirtError('%s() failed', net=self)\n" %
|
2009-05-21 18:57:05 +08:00
|
|
|
(name))
|
|
|
|
elif classname == "virInterface":
|
|
|
|
classes.write(
|
2011-02-16 23:57:50 +08:00
|
|
|
" if ret is None:raise libvirtError('%s() failed', net=self)\n" %
|
2007-04-16 20:37:59 +08:00
|
|
|
(name))
|
2008-02-20 23:26:22 +08:00
|
|
|
elif classname == "virStoragePool":
|
|
|
|
classes.write(
|
2011-02-16 23:57:50 +08:00
|
|
|
" if ret is None:raise libvirtError('%s() failed', pool=self)\n" %
|
2008-02-20 23:26:22 +08:00
|
|
|
(name))
|
|
|
|
elif classname == "virStorageVol":
|
|
|
|
classes.write(
|
2011-02-16 23:57:50 +08:00
|
|
|
" if ret is None:raise libvirtError('%s() failed', vol=self)\n" %
|
2008-02-20 23:26:22 +08:00
|
|
|
(name))
|
2010-05-19 21:02:30 +08:00
|
|
|
elif classname == "virDomainSnapshot":
|
|
|
|
classes.write(
|
|
|
|
" if ret is None:raise libvirtError('%s() failed', dom=self._dom)\n" %
|
|
|
|
(name))
|
2006-11-08 07:18:56 +08:00
|
|
|
else:
|
|
|
|
classes.write(
|
2011-02-16 23:57:50 +08:00
|
|
|
" if ret is None:raise libvirtError('%s() failed')\n" %
|
2006-11-08 07:18:56 +08:00
|
|
|
(name))
|
2005-12-20 00:34:11 +08:00
|
|
|
|
2011-02-16 23:57:50 +08:00
|
|
|
#
|
|
|
|
# generate the returned class wrapper for the object
|
|
|
|
#
|
|
|
|
classes.write(" __tmp = ");
|
|
|
|
classes.write(classes_type[ret[0]][1] % ("ret"));
|
|
|
|
classes.write("\n");
|
2005-12-20 00:34:11 +08:00
|
|
|
|
|
|
|
#
|
2011-02-16 23:57:50 +08:00
|
|
|
# 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 reference_keepers.has_key(tclass):
|
|
|
|
list = reference_keepers[tclass]
|
|
|
|
for pref in list:
|
|
|
|
if pref[0] == classname:
|
|
|
|
classes.write(" __tmp.%s = self\n" %
|
|
|
|
pref[1])
|
2007-03-28 19:24:14 +08:00
|
|
|
|
|
|
|
# Post-processing - just before we return.
|
|
|
|
if function_post.has_key(name):
|
|
|
|
classes.write(" %s\n" %
|
|
|
|
(function_post[name]));
|
|
|
|
|
2011-02-16 23:57:50 +08:00
|
|
|
#
|
|
|
|
# return the class
|
|
|
|
#
|
|
|
|
classes.write(" return __tmp\n");
|
|
|
|
elif converter_type.has_key(ret[0]):
|
|
|
|
#
|
|
|
|
# Raise an exception
|
|
|
|
#
|
|
|
|
if functions_noexcept.has_key(name):
|
|
|
|
classes.write(
|
|
|
|
" if ret is None:return None");
|
2007-03-28 19:24:14 +08:00
|
|
|
|
|
|
|
# Post-processing - just before we return.
|
|
|
|
if function_post.has_key(name):
|
|
|
|
classes.write(" %s\n" %
|
|
|
|
(function_post[name]));
|
|
|
|
|
2011-02-16 23:57:50 +08:00
|
|
|
classes.write(" return ");
|
|
|
|
classes.write(converter_type[ret[0]] % ("ret"));
|
|
|
|
classes.write("\n");
|
2007-03-28 19:24:14 +08:00
|
|
|
|
|
|
|
# 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 not functions_noexcept.has_key (name):
|
|
|
|
if functions_int_exception_test.has_key (name):
|
|
|
|
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))
|
2007-04-16 20:37:59 +08:00
|
|
|
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))
|
2009-05-21 18:57:05 +08:00
|
|
|
elif classname == "virInterface":
|
|
|
|
classes.write ((" if " + test +
|
|
|
|
": raise libvirtError ('%s() failed', net=self)\n") %
|
|
|
|
("ret", name))
|
2008-02-20 23:26:22 +08:00
|
|
|
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))
|
2007-03-28 19:24:14 +08:00
|
|
|
else:
|
|
|
|
classes.write ((" if " + test +
|
|
|
|
": raise libvirtError ('%s() failed')\n") %
|
|
|
|
("ret", name))
|
|
|
|
|
|
|
|
# Post-processing - just before we return.
|
|
|
|
if function_post.has_key(name):
|
|
|
|
classes.write(" %s\n" %
|
|
|
|
(function_post[name]));
|
|
|
|
|
|
|
|
classes.write (" return ret\n")
|
|
|
|
|
|
|
|
elif is_list_type (ret[0]):
|
|
|
|
if not functions_noexcept.has_key (name):
|
|
|
|
if functions_list_exception_test.has_key (name):
|
|
|
|
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))
|
2007-04-16 20:37:59 +08:00
|
|
|
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))
|
2009-05-21 18:57:05 +08:00
|
|
|
elif classname == "virInterface":
|
|
|
|
classes.write ((" if " + test +
|
|
|
|
": raise libvirtError ('%s() failed', net=self)\n") %
|
|
|
|
("ret", name))
|
2008-02-20 23:26:22 +08:00
|
|
|
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))
|
2007-03-28 19:24:14 +08:00
|
|
|
else:
|
|
|
|
classes.write ((" if " + test +
|
|
|
|
": raise libvirtError ('%s() failed')\n") %
|
|
|
|
("ret", name))
|
|
|
|
|
|
|
|
# Post-processing - just before we return.
|
|
|
|
if function_post.has_key(name):
|
|
|
|
classes.write(" %s\n" %
|
|
|
|
(function_post[name]));
|
|
|
|
|
|
|
|
classes.write (" return ret\n")
|
|
|
|
|
2011-02-16 23:57:50 +08:00
|
|
|
else:
|
2007-03-28 19:24:14 +08:00
|
|
|
# Post-processing - just before we return.
|
|
|
|
if function_post.has_key(name):
|
|
|
|
classes.write(" %s\n" %
|
|
|
|
(function_post[name]));
|
|
|
|
|
2011-02-16 23:57:50 +08:00
|
|
|
classes.write(" return ret\n");
|
2007-03-28 19:24:14 +08:00
|
|
|
|
2011-02-16 23:57:50 +08:00
|
|
|
classes.write("\n");
|
2008-10-31 18:13:45 +08:00
|
|
|
# Append "<classname>.py" to class def, iff it exists
|
|
|
|
try:
|
2009-09-16 21:03:53 +08:00
|
|
|
extra = open(os.path.join(srcPref,"libvirt-override-" + classname + ".py"), "r")
|
2008-10-31 18:13:45 +08:00
|
|
|
classes.write (" #\n")
|
|
|
|
classes.write (" # %s methods from %s.py (hand coded)\n" % (classname,classname))
|
|
|
|
classes.write (" #\n")
|
|
|
|
classes.writelines(extra.readlines())
|
2009-10-03 01:05:03 +08:00
|
|
|
classes.write("\n")
|
2008-10-31 18:13:45 +08:00
|
|
|
extra.close()
|
|
|
|
except:
|
|
|
|
pass
|
2005-12-20 00:34:11 +08:00
|
|
|
|
|
|
|
#
|
|
|
|
# Generate enum constants
|
|
|
|
#
|
|
|
|
for type,enum in enums.items():
|
|
|
|
classes.write("# %s\n" % type)
|
|
|
|
items = enum.items()
|
|
|
|
items.sort(lambda i1,i2: cmp(long(i1[1]),long(i2[1])))
|
|
|
|
for name,value in items:
|
|
|
|
classes.write("%s = %s\n" % (name,value))
|
|
|
|
classes.write("\n");
|
|
|
|
|
|
|
|
classes.close()
|
|
|
|
|
2008-01-21 23:55:53 +08:00
|
|
|
if buildStubs() < 0:
|
|
|
|
sys.exit(1)
|
2005-12-20 00:34:11 +08:00
|
|
|
buildWrappers()
|
2008-01-21 23:55:53 +08:00
|
|
|
sys.exit(0)
|